PR27116, Spelling errors found by Debian style checker
[official-gcc.git] / gcc / ada / exp_dist.adb
blobf025b5656c6c60aac0bd9fa0d8fa1f9b03379062
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-2023, 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 3, 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 COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
26 with Atree; use Atree;
27 with Einfo; use Einfo;
28 with Einfo.Entities; use Einfo.Entities;
29 with Einfo.Utils; use Einfo.Utils;
30 with Elists; use Elists;
31 with Exp_Atag; use Exp_Atag;
32 with Exp_Strm; use Exp_Strm;
33 with Exp_Tss; use Exp_Tss;
34 with Exp_Util; use Exp_Util;
35 with Lib; use Lib;
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_Aux; use Sem_Aux;
42 with Sem_Cat; use Sem_Cat;
43 with Sem_Ch3; use Sem_Ch3;
44 with Sem_Ch8; use Sem_Ch8;
45 with Sem_Ch12; use Sem_Ch12;
46 with Sem_Dist; use Sem_Dist;
47 with Sem_Eval; use Sem_Eval;
48 with Sem_Util; use Sem_Util;
49 with Sinfo; use Sinfo;
50 with Sinfo.Nodes; use Sinfo.Nodes;
51 with Sinfo.Utils; use Sinfo.Utils;
52 with Stand; use Stand;
53 with Stringt; use Stringt;
54 with Tbuild; use Tbuild;
55 with Ttypes; use Ttypes;
56 with Uintp; use Uintp;
58 with GNAT.HTable; use GNAT.HTable;
60 package body Exp_Dist is
62 -- The following model has been used to implement distributed objects:
63 -- given a designated type D and a RACW type R, then a record of the form:
65 -- type Stub is tagged record
66 -- [...declaration similar to s-parint.ads RACW_Stub_Type...]
67 -- end record;
69 -- is built. This type has two properties:
71 -- 1) Since it has the same structure as RACW_Stub_Type, it can
72 -- be converted to and from this type to make it suitable for
73 -- System.Partition_Interface.Get_Unique_Remote_Pointer in order
74 -- to avoid memory leaks when the same remote object arrives on the
75 -- same partition through several paths;
77 -- 2) It also has the same dispatching table as the designated type D,
78 -- and thus can be used as an object designated by a value of type
79 -- R on any partition other than the one on which the object has
80 -- been created, since only dispatching calls will be performed and
81 -- the fields themselves will not be used. We call Derive_Subprograms
82 -- to fake half a derivation to ensure that the subprograms do have
83 -- the same dispatching table.
85 First_RCI_Subprogram_Id : constant := 2;
86 -- RCI subprograms are numbered starting at 2. The RCI receiver for
87 -- an RCI package can thus identify calls received through remote
88 -- access-to-subprogram dereferences by the fact that they have a
89 -- (primitive) subprogram id of 0, and 1 is used for the internal RAS
90 -- information lookup operation. (This is for the Garlic code generation,
91 -- where subprograms are identified by numbers; in the PolyORB version,
92 -- they are identified by name, with a numeric suffix for homonyms.)
94 type Hash_Index is range 0 .. 50;
96 -----------------------
97 -- Local subprograms --
98 -----------------------
100 function Hash (F : Entity_Id) return Hash_Index;
101 -- DSA expansion associates stubs to distributed object types using a hash
102 -- table on entity ids.
104 function Hash (F : Name_Id) return Hash_Index;
105 -- The generation of subprogram identifiers requires an overload counter
106 -- to be associated with each remote subprogram name. These counters are
107 -- maintained in a hash table on name ids.
109 type Subprogram_Identifiers is record
110 Str_Identifier : String_Id;
111 Int_Identifier : Int;
112 end record;
114 package Subprogram_Identifier_Table is
115 new Simple_HTable (Header_Num => Hash_Index,
116 Element => Subprogram_Identifiers,
117 No_Element => (No_String, 0),
118 Key => Entity_Id,
119 Hash => Hash,
120 Equal => "=");
121 -- Mapping between a remote subprogram and the corresponding subprogram
122 -- identifiers.
124 package Overload_Counter_Table is
125 new Simple_HTable (Header_Num => Hash_Index,
126 Element => Int,
127 No_Element => 0,
128 Key => Name_Id,
129 Hash => Hash,
130 Equal => "=");
131 -- Mapping between a subprogram name and an integer that counts the number
132 -- of defining subprogram names with that Name_Id encountered so far in a
133 -- given context (an interface).
135 function Get_Subprogram_Ids (Def : Entity_Id) return Subprogram_Identifiers;
136 function Get_Subprogram_Id (Def : Entity_Id) return String_Id;
137 function Get_Subprogram_Id (Def : Entity_Id) return Int;
138 -- Given a subprogram defined in a RCI package, get its distribution
139 -- subprogram identifiers (the distribution identifiers are a unique
140 -- subprogram number, and the non-qualified subprogram name, in the
141 -- casing used for the subprogram declaration; if the name is overloaded,
142 -- a double underscore and a serial number are appended.
144 -- The integer identifier is used to perform remote calls with GARLIC;
145 -- the string identifier is used in the case of PolyORB.
147 -- Although the PolyORB DSA receiving stubs will make a caseless comparison
148 -- when receiving a call, the calling stubs will create requests with the
149 -- exact casing of the defining unit name of the called subprogram, so as
150 -- to allow calls to subprograms on distributed nodes that do distinguish
151 -- between casings.
153 -- NOTE: Another design would be to allow a representation clause on
154 -- subprogram specs: for Subp'Distribution_Identifier use "fooBar";
156 pragma Warnings (Off, Get_Subprogram_Id);
157 -- One homonym only is unreferenced (specific to the GARLIC version)
159 procedure Add_RAS_Dereference_TSS (N : Node_Id);
160 -- Add a subprogram body for RAS Dereference TSS
162 procedure Add_RAS_Proxy_And_Analyze
163 (Decls : List_Id;
164 Vis_Decl : Node_Id;
165 All_Calls_Remote_E : Entity_Id;
166 Proxy_Object_Addr : out Entity_Id);
167 -- Add the proxy type required, on the receiving (server) side, to handle
168 -- calls to the subprogram declared by Vis_Decl through a remote access
169 -- to subprogram type. All_Calls_Remote_E must be Standard_True if a pragma
170 -- All_Calls_Remote applies, Standard_False otherwise. The new proxy type
171 -- is appended to Decls. Proxy_Object_Addr is a constant of type
172 -- System.Address that designates an instance of the proxy object.
174 function Build_Remote_Subprogram_Proxy_Type
175 (Loc : Source_Ptr;
176 ACR_Expression : Node_Id) return Node_Id;
177 -- Build and return a tagged record type definition for an RCI subprogram
178 -- proxy type. ACR_Expression is used as the initialization value for the
179 -- All_Calls_Remote component.
181 function Build_Get_Unique_RP_Call
182 (Loc : Source_Ptr;
183 Pointer : Entity_Id;
184 Stub_Type : Entity_Id) return List_Id;
185 -- Build a call to Get_Unique_Remote_Pointer (Pointer), followed by a
186 -- tag fixup (Get_Unique_Remote_Pointer may have changed Pointer'Tag to
187 -- RACW_Stub_Type'Tag, while the desired tag is that of Stub_Type).
189 function Build_Stub_Tag
190 (Loc : Source_Ptr;
191 RACW_Type : Entity_Id) return Node_Id;
192 -- Return an expression denoting the tag of the stub type associated with
193 -- RACW_Type.
195 function Build_Subprogram_Calling_Stubs
196 (Vis_Decl : Node_Id;
197 Subp_Id : Node_Id;
198 Asynchronous : Boolean;
199 Dynamically_Asynchronous : Boolean := False;
200 Stub_Type : Entity_Id := Empty;
201 RACW_Type : Entity_Id := Empty;
202 Locator : Entity_Id := Empty;
203 New_Name : Name_Id := No_Name) return Node_Id;
204 -- Build the calling stub for a given subprogram with the subprogram ID
205 -- being Subp_Id. If Stub_Type is given, then the "addr" field of
206 -- parameters of this type will be marshalled instead of the object itself.
207 -- It will then be converted into Stub_Type before performing the real
208 -- call. If Dynamically_Asynchronous is True, then it will be computed at
209 -- run time whether the call is asynchronous or not. Otherwise, the value
210 -- of the formal Asynchronous will be used. If Locator is not Empty, it
211 -- will be used instead of RCI_Cache. If New_Name is given, then it will
212 -- be used instead of the original name.
214 function Build_RPC_Receiver_Specification
215 (RPC_Receiver : Entity_Id;
216 Request_Parameter : Entity_Id) return Node_Id;
217 -- Make a subprogram specification for an RPC receiver, with the given
218 -- defining unit name and formal parameter.
220 function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id;
221 -- Return an ordered parameter list: unconstrained parameters are put
222 -- at the beginning of the list and constrained ones are put after. If
223 -- there are no parameters, an empty list is returned. Special case:
224 -- the controlling formal of the equivalent RACW operation for a RAS
225 -- type is always left in first position.
227 function Transmit_As_Unconstrained (Typ : Entity_Id) return Boolean;
228 -- True when Typ is an unconstrained type, or a null-excluding access type.
229 -- In either case, this means stubs cannot contain a default-initialized
230 -- object declaration of such type.
232 procedure Add_Calling_Stubs_To_Declarations (Pkg_Spec : Node_Id);
233 -- Add calling stubs to the declarative part
235 function Could_Be_Asynchronous (Spec : Node_Id) return Boolean;
236 -- Return True if nothing prevents the program whose specification is
237 -- given to be asynchronous (i.e. no [IN] OUT parameters).
239 function Pack_Entity_Into_Stream_Access
240 (Loc : Source_Ptr;
241 Stream : Node_Id;
242 Object : Entity_Id;
243 Etyp : Entity_Id := Empty) return Node_Id;
244 -- Pack Object (of type Etyp) into Stream. If Etyp is not given,
245 -- then Etype (Object) will be used if present. If the type is
246 -- constrained, then 'Write will be used to output the object,
247 -- If the type is unconstrained, 'Output will be used.
249 function Pack_Node_Into_Stream
250 (Loc : Source_Ptr;
251 Stream : Entity_Id;
252 Object : Node_Id;
253 Etyp : Entity_Id) return Node_Id;
254 -- Similar to above, with an arbitrary node instead of an entity
256 function Pack_Node_Into_Stream_Access
257 (Loc : Source_Ptr;
258 Stream : Node_Id;
259 Object : Node_Id;
260 Etyp : Entity_Id) return Node_Id;
261 -- Similar to above, with Stream instead of Stream'Access
263 function Make_Selected_Component
264 (Loc : Source_Ptr;
265 Prefix : Entity_Id;
266 Selector_Name : Name_Id) return Node_Id;
267 -- Return a selected_component whose prefix denotes the given entity, and
268 -- with the given Selector_Name.
270 function Scope_Of_Spec (Spec : Node_Id) return Entity_Id;
271 -- Return the scope represented by a given spec
273 procedure Set_Renaming_TSS
274 (Typ : Entity_Id;
275 Nam : Entity_Id;
276 TSS_Nam : TSS_Name_Type);
277 -- Create a renaming declaration of subprogram Nam, and register it as a
278 -- TSS for Typ with name TSS_Nam.
280 function Need_Extra_Constrained (Parameter : Node_Id) return Boolean;
281 -- Return True if the current parameter needs an extra formal to reflect
282 -- its constrained status.
284 function Is_RACW_Controlling_Formal
285 (Parameter : Node_Id;
286 Stub_Type : Entity_Id) return Boolean;
287 -- Return True if the current parameter is a controlling formal argument
288 -- of type Stub_Type or access to Stub_Type.
290 procedure Declare_Create_NVList
291 (Loc : Source_Ptr;
292 NVList : Entity_Id;
293 Decls : List_Id;
294 Stmts : List_Id);
295 -- Append the declaration of NVList to Decls, and its
296 -- initialization to Stmts.
298 function Add_Parameter_To_NVList
299 (Loc : Source_Ptr;
300 NVList : Entity_Id;
301 Parameter : Entity_Id;
302 Constrained : Boolean;
303 Any : Entity_Id) return Node_Id;
304 -- Return a call to Add_Item to add the Any corresponding to the designated
305 -- formal Parameter (with the indicated Constrained status) to NVList.
307 --------------------
308 -- Stub_Structure --
309 --------------------
311 -- This record describes various tree fragments associated with the
312 -- generation of RACW calling stubs. One such record exists for every
313 -- distributed object type, i.e. each tagged type that is the designated
314 -- type of one or more RACW type.
316 type Stub_Structure is record
317 Stub_Type : Entity_Id;
318 -- Stub type: this type has the same primitive operations as the
319 -- designated types, but the provided bodies for these operations
320 -- a remote call to an actual target object potentially located on
321 -- another partition; each value of the stub type encapsulates a
322 -- reference to a remote object.
324 Stub_Type_Access : Entity_Id;
325 -- A local access type designating the stub type (this is not an RACW
326 -- type).
328 RPC_Receiver_Decl : Node_Id;
329 -- Declaration for the RPC receiver entity associated with the
330 -- designated type. As an exception, in the case of GARLIC, for an RACW
331 -- that implements a RAS, no object RPC receiver is generated. Instead,
332 -- RPC_Receiver_Decl is the declaration after which the RPC receiver
333 -- would have been inserted.
335 Body_Decls : List_Id;
336 -- List of subprogram bodies to be included in generated code: bodies
337 -- for the RACW's stream attributes, and for the primitive operations
338 -- of the stub type.
340 RACW_Type : Entity_Id;
341 -- One of the RACW types designating this distributed object type
342 -- (they are all interchangeable; we use any one of them in order to
343 -- avoid having to create various anonymous access types).
345 end record;
347 Empty_Stub_Structure : constant Stub_Structure :=
348 (Empty, Empty, Empty, No_List, Empty);
350 package Stubs_Table is
351 new Simple_HTable (Header_Num => Hash_Index,
352 Element => Stub_Structure,
353 No_Element => Empty_Stub_Structure,
354 Key => Entity_Id,
355 Hash => Hash,
356 Equal => "=");
357 -- Mapping between a RACW designated type and its stub type
359 package Asynchronous_Flags_Table is
360 new Simple_HTable (Header_Num => Hash_Index,
361 Element => Entity_Id,
362 No_Element => Empty,
363 Key => Entity_Id,
364 Hash => Hash,
365 Equal => "=");
366 -- Mapping between a RACW type and a constant having the value True
367 -- if the RACW is asynchronous and False otherwise.
369 package RCI_Locator_Table is
370 new Simple_HTable (Header_Num => Hash_Index,
371 Element => Entity_Id,
372 No_Element => Empty,
373 Key => Entity_Id,
374 Hash => Hash,
375 Equal => "=");
376 -- Mapping between a RCI package on which All_Calls_Remote applies and
377 -- the generic instantiation of RCI_Locator for this package.
379 package RCI_Calling_Stubs_Table is
380 new Simple_HTable (Header_Num => Hash_Index,
381 Element => Entity_Id,
382 No_Element => Empty,
383 Key => Entity_Id,
384 Hash => Hash,
385 Equal => "=");
386 -- Mapping between a RCI subprogram and the corresponding calling stubs
388 function Get_Stub_Elements (RACW_Type : Entity_Id) return Stub_Structure;
389 -- Return the stub information associated with the given RACW type
391 procedure Add_Stub_Type
392 (Designated_Type : Entity_Id;
393 RACW_Type : Entity_Id;
394 Decls : List_Id;
395 Stub_Type : out Entity_Id;
396 Stub_Type_Access : out Entity_Id;
397 RPC_Receiver_Decl : out Node_Id;
398 Body_Decls : out List_Id;
399 Existing : out Boolean);
400 -- Add the declaration of the stub type, the access to stub type and the
401 -- object RPC receiver at the end of Decls. If these already exist,
402 -- then nothing is added in the tree but the right values are returned
403 -- anyhow and Existing is set to True.
405 function Get_And_Reset_RACW_Bodies (RACW_Type : Entity_Id) return List_Id;
406 -- Retrieve the Body_Decls list associated to RACW_Type in the stub
407 -- structure table, reset it to No_List, and return the previous value.
409 procedure Add_RACW_Asynchronous_Flag
410 (Declarations : List_Id;
411 RACW_Type : Entity_Id);
412 -- Declare a boolean constant associated with RACW_Type whose value
413 -- indicates at run time whether a pragma Asynchronous applies to it.
415 procedure Assign_Subprogram_Identifier
416 (Def : Entity_Id;
417 Spn : Int;
418 Id : out String_Id);
419 -- Determine the distribution subprogram identifier to
420 -- be used for remote subprogram Def, return it in Id and
421 -- store it in a hash table for later retrieval by
422 -- Get_Subprogram_Id. Spn is the subprogram number.
424 function RCI_Package_Locator
425 (Loc : Source_Ptr;
426 Package_Spec : Node_Id) return Node_Id;
427 -- Instantiate the generic package RCI_Locator in order to locate the
428 -- RCI package whose spec is given as argument.
430 function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id;
431 -- Surround a node N by a tag check, as in:
432 -- begin
433 -- <N>;
434 -- exception
435 -- when E : Ada.Tags.Tag_Error =>
436 -- Raise_Exception (Program_Error'Identity,
437 -- Exception_Message (E));
438 -- end;
440 function Input_With_Tag_Check
441 (Loc : Source_Ptr;
442 Var_Type : Entity_Id;
443 Stream : Node_Id) return Node_Id;
444 -- Return a function with the following form:
445 -- function R return Var_Type is
446 -- begin
447 -- return Var_Type'Input (S);
448 -- exception
449 -- when E : Ada.Tags.Tag_Error =>
450 -- Raise_Exception (Program_Error'Identity,
451 -- Exception_Message (E));
452 -- end R;
454 procedure Build_Actual_Object_Declaration
455 (Object : Entity_Id;
456 Etyp : Entity_Id;
457 Variable : Boolean;
458 Expr : Node_Id;
459 Decls : List_Id);
460 -- Build the declaration of an object with the given defining identifier,
461 -- initialized with Expr if provided, to serve as actual parameter in a
462 -- server stub. If Variable is true, the declared object will be a variable
463 -- (case of an out or in out formal), else it will be a constant. Object's
464 -- Ekind is set accordingly. The declaration, as well as any other
465 -- declarations it requires, are appended to Decls.
467 --------------------------------------------
468 -- Hooks for PCS-specific code generation --
469 --------------------------------------------
471 -- Part of the code generation circuitry for distribution needs to be
472 -- tailored for each implementation of the PCS. For each routine that
473 -- needs to be specialized, a Specific_<routine> wrapper is created,
474 -- which calls the corresponding <routine> in package
475 -- <pcs_implementation>_Support.
477 procedure Specific_Add_RACW_Features
478 (RACW_Type : Entity_Id;
479 Desig : Entity_Id;
480 Stub_Type : Entity_Id;
481 Stub_Type_Access : Entity_Id;
482 RPC_Receiver_Decl : Node_Id;
483 Body_Decls : List_Id);
484 -- Add declaration for TSSs for a given RACW type. The declarations are
485 -- added just after the declaration of the RACW type itself. If the RACW
486 -- appears in the main unit, Body_Decls is a list of declarations to which
487 -- the bodies are appended. Else Body_Decls is No_List.
488 -- PCS-specific ancillary subprogram for Add_RACW_Features.
490 procedure Specific_Add_RAST_Features
491 (Vis_Decl : Node_Id;
492 RAS_Type : Entity_Id);
493 -- Add declaration for TSSs for a given RAS type. PCS-specific ancillary
494 -- subprogram for Add_RAST_Features.
496 -- An RPC_Target record is used during construction of calling stubs
497 -- to pass PCS-specific tree fragments corresponding to the information
498 -- necessary to locate the target of a remote subprogram call.
500 type RPC_Target (PCS_Kind : PCS_Names) is record
501 case PCS_Kind is
502 when Name_PolyORB_DSA =>
503 Object : Node_Id;
504 -- An expression whose value is a PolyORB reference to the target
505 -- object.
507 when others =>
508 Partition : Entity_Id;
509 -- A variable containing the Partition_ID of the target partition
511 RPC_Receiver : Node_Id;
512 -- An expression whose value is the address of the target RPC
513 -- receiver.
514 end case;
515 end record;
517 procedure Specific_Build_General_Calling_Stubs
518 (Decls : List_Id;
519 Statements : List_Id;
520 Target : RPC_Target;
521 Subprogram_Id : Node_Id;
522 Asynchronous : Node_Id := Empty;
523 Is_Known_Asynchronous : Boolean := False;
524 Is_Known_Non_Asynchronous : Boolean := False;
525 Is_Function : Boolean;
526 Spec : Node_Id;
527 Stub_Type : Entity_Id := Empty;
528 RACW_Type : Entity_Id := Empty;
529 Nod : Node_Id);
530 -- Build calling stubs for general purpose. The parameters are:
531 -- Decls : A place to put declarations
532 -- Statements : A place to put statements
533 -- Target : PCS-specific target information (see details in
534 -- RPC_Target declaration).
535 -- Subprogram_Id : A node containing the subprogram ID
536 -- Asynchronous : True if an APC must be made instead of an RPC.
537 -- The value needs not be supplied if one of the
538 -- Is_Known_... is True.
539 -- Is_Known_Async... : True if we know that this is asynchronous
540 -- Is_Known_Non_A... : True if we know that this is not asynchronous
541 -- Spec : Node with a Parameter_Specifications and a
542 -- Result_Definition if applicable
543 -- Stub_Type : For case of RACW stubs, parameters of type access
544 -- to Stub_Type will be marshalled using the address
545 -- address of the object (the addr field) rather
546 -- than using the 'Write on the stub itself
547 -- Nod : Used to provide sloc for generated code
549 function Specific_Build_Stub_Target
550 (Loc : Source_Ptr;
551 Decls : List_Id;
552 RCI_Locator : Entity_Id;
553 Controlling_Parameter : Entity_Id) return RPC_Target;
554 -- Build call target information nodes for use within calling stubs. In the
555 -- RCI case, RCI_Locator is the entity for the instance of RCI_Locator. If
556 -- for an RACW, Controlling_Parameter is the entity for the controlling
557 -- formal parameter used to determine the location of the target of the
558 -- call. Decls provides a location where variable declarations can be
559 -- appended to construct the necessary values.
561 function Specific_RPC_Receiver_Decl
562 (RACW_Type : Entity_Id) return Node_Id;
563 -- Build the RPC receiver, for RACW, if applicable, else return Empty
565 procedure Specific_Build_RPC_Receiver_Body
566 (RPC_Receiver : Entity_Id;
567 Request : out Entity_Id;
568 Subp_Id : out Entity_Id;
569 Subp_Index : out Entity_Id;
570 Stmts : out List_Id;
571 Decl : out Node_Id);
572 -- Make a subprogram body for an RPC receiver, with the given
573 -- defining unit name. On return:
574 -- - Subp_Id is the subprogram identifier from the PCS.
575 -- - Subp_Index is the index in the list of subprograms
576 -- used for dispatching (a variable of type Subprogram_Id).
577 -- - Stmts is the place where the request dispatching
578 -- statements can occur,
579 -- - Decl is the subprogram body declaration.
581 function Specific_Build_Subprogram_Receiving_Stubs
582 (Vis_Decl : Node_Id;
583 Asynchronous : Boolean;
584 Dynamically_Asynchronous : Boolean := False;
585 Stub_Type : Entity_Id := Empty;
586 RACW_Type : Entity_Id := Empty;
587 Parent_Primitive : Entity_Id := Empty) return Node_Id;
588 -- Build the receiving stub for a given subprogram. The subprogram
589 -- declaration is also built by this procedure, and the value returned
590 -- is a N_Subprogram_Body. If a parameter of type access to Stub_Type is
591 -- found in the specification, then its address is read from the stream
592 -- instead of the object itself and converted into an access to
593 -- class-wide type before doing the real call using any of the RACW type
594 -- pointing on the designated type.
596 procedure Specific_Add_Obj_RPC_Receiver_Completion
597 (Loc : Source_Ptr;
598 Decls : List_Id;
599 RPC_Receiver : Entity_Id;
600 Stub_Elements : Stub_Structure);
601 -- Add the necessary code to Decls after the completion of generation
602 -- of the RACW RPC receiver described by Stub_Elements.
604 procedure Specific_Add_Receiving_Stubs_To_Declarations
605 (Pkg_Spec : Node_Id;
606 Decls : List_Id;
607 Stmts : List_Id);
608 -- Add receiving stubs to the declarative part of an RCI unit
610 --------------------
611 -- GARLIC_Support --
612 --------------------
614 package GARLIC_Support is
616 -- Support for generating DSA code that uses the GARLIC PCS
618 -- The subprograms below provide the GARLIC versions of the
619 -- corresponding Specific_<subprogram> routine declared above.
621 procedure Add_RACW_Features
622 (RACW_Type : Entity_Id;
623 Stub_Type : Entity_Id;
624 Stub_Type_Access : Entity_Id;
625 RPC_Receiver_Decl : Node_Id;
626 Body_Decls : List_Id);
628 procedure Add_RAST_Features
629 (Vis_Decl : Node_Id;
630 RAS_Type : Entity_Id);
632 procedure Build_General_Calling_Stubs
633 (Decls : List_Id;
634 Statements : List_Id;
635 Target_Partition : Entity_Id; -- From RPC_Target
636 Target_RPC_Receiver : Node_Id; -- From RPC_Target
637 Subprogram_Id : Node_Id;
638 Asynchronous : Node_Id := Empty;
639 Is_Known_Asynchronous : Boolean := False;
640 Is_Known_Non_Asynchronous : Boolean := False;
641 Is_Function : Boolean;
642 Spec : Node_Id;
643 Stub_Type : Entity_Id := Empty;
644 RACW_Type : Entity_Id := Empty;
645 Nod : Node_Id);
647 function Build_Stub_Target
648 (Loc : Source_Ptr;
649 Decls : List_Id;
650 RCI_Locator : Entity_Id;
651 Controlling_Parameter : Entity_Id) return RPC_Target;
653 function RPC_Receiver_Decl (RACW_Type : Entity_Id) return Node_Id;
655 function Build_Subprogram_Receiving_Stubs
656 (Vis_Decl : Node_Id;
657 Asynchronous : Boolean;
658 Dynamically_Asynchronous : Boolean := False;
659 Stub_Type : Entity_Id := Empty;
660 RACW_Type : Entity_Id := Empty;
661 Parent_Primitive : Entity_Id := Empty) return Node_Id;
663 procedure Add_Obj_RPC_Receiver_Completion
664 (Loc : Source_Ptr;
665 Decls : List_Id;
666 RPC_Receiver : Entity_Id;
667 Stub_Elements : Stub_Structure);
669 procedure Add_Receiving_Stubs_To_Declarations
670 (Pkg_Spec : Node_Id;
671 Decls : List_Id;
672 Stmts : List_Id);
674 procedure Build_RPC_Receiver_Body
675 (RPC_Receiver : Entity_Id;
676 Request : out Entity_Id;
677 Subp_Id : out Entity_Id;
678 Subp_Index : out Entity_Id;
679 Stmts : out List_Id;
680 Decl : out Node_Id);
682 end GARLIC_Support;
684 ---------------------
685 -- PolyORB_Support --
686 ---------------------
688 package PolyORB_Support is
690 -- Support for generating DSA code that uses the PolyORB PCS
692 -- The subprograms below provide the PolyORB versions of the
693 -- corresponding Specific_<subprogram> routine declared above.
695 procedure Add_RACW_Features
696 (RACW_Type : Entity_Id;
697 Desig : Entity_Id;
698 Stub_Type : Entity_Id;
699 Stub_Type_Access : Entity_Id;
700 RPC_Receiver_Decl : Node_Id;
701 Body_Decls : List_Id);
703 procedure Add_RAST_Features
704 (Vis_Decl : Node_Id;
705 RAS_Type : Entity_Id);
707 procedure Build_General_Calling_Stubs
708 (Decls : List_Id;
709 Statements : List_Id;
710 Target_Object : Node_Id; -- From RPC_Target
711 Subprogram_Id : Node_Id;
712 Asynchronous : Node_Id := Empty;
713 Is_Known_Asynchronous : Boolean := False;
714 Is_Known_Non_Asynchronous : Boolean := False;
715 Is_Function : Boolean;
716 Spec : Node_Id;
717 Stub_Type : Entity_Id := Empty;
718 RACW_Type : Entity_Id := Empty;
719 Nod : Node_Id);
721 function Build_Stub_Target
722 (Loc : Source_Ptr;
723 Decls : List_Id;
724 RCI_Locator : Entity_Id;
725 Controlling_Parameter : Entity_Id) return RPC_Target;
727 function RPC_Receiver_Decl (RACW_Type : Entity_Id) return Node_Id;
729 function Build_Subprogram_Receiving_Stubs
730 (Vis_Decl : Node_Id;
731 Asynchronous : Boolean;
732 Dynamically_Asynchronous : Boolean := False;
733 Stub_Type : Entity_Id := Empty;
734 RACW_Type : Entity_Id := Empty;
735 Parent_Primitive : Entity_Id := Empty) return Node_Id;
737 procedure Add_Obj_RPC_Receiver_Completion
738 (Loc : Source_Ptr;
739 Decls : List_Id;
740 RPC_Receiver : Entity_Id;
741 Stub_Elements : Stub_Structure);
743 procedure Add_Receiving_Stubs_To_Declarations
744 (Pkg_Spec : Node_Id;
745 Decls : List_Id;
746 Stmts : List_Id);
748 procedure Build_RPC_Receiver_Body
749 (RPC_Receiver : Entity_Id;
750 Request : out Entity_Id;
751 Subp_Id : out Entity_Id;
752 Subp_Index : out Entity_Id;
753 Stmts : out List_Id;
754 Decl : out Node_Id);
756 procedure Reserve_NamingContext_Methods;
757 -- Mark the method names for interface NamingContext as already used in
758 -- the overload table, so no clashes occur with user code (with the
759 -- PolyORB PCS, RCIs Implement The NamingContext interface to allow
760 -- their methods to be accessed as objects, for the implementation of
761 -- remote access-to-subprogram types).
763 -------------
764 -- Helpers --
765 -------------
767 package Helpers is
769 -- Routines to build distribution helper subprograms for user-defined
770 -- types. For implementation of the Distributed systems annex (DSA)
771 -- over the PolyORB generic middleware components, it is necessary to
772 -- generate several supporting subprograms for each application data
773 -- type used in inter-partition communication. These subprograms are:
775 -- A Typecode function returning a high-level description of the
776 -- type's structure;
778 -- Two conversion functions allowing conversion of values of the
779 -- type from and to the generic data containers used by PolyORB.
780 -- These generic containers are called 'Any' type values after the
781 -- CORBA terminology, and hence the conversion subprograms are
782 -- named To_Any and From_Any.
784 function Build_From_Any_Call
785 (Typ : Entity_Id;
786 N : Node_Id;
787 Decls : List_Id) return Node_Id;
788 -- Build call to From_Any attribute function of type Typ with
789 -- expression N as actual parameter. Decls is the declarations list
790 -- for an appropriate enclosing scope of the point where the call
791 -- will be inserted; if the From_Any attribute for Typ needs to be
792 -- generated at this point, its declaration is appended to Decls.
794 procedure Build_From_Any_Function
795 (Loc : Source_Ptr;
796 Typ : Entity_Id;
797 Decl : out Node_Id;
798 Fnam : out Entity_Id);
799 -- Build From_Any attribute function for Typ. Loc is the reference
800 -- location for generated nodes, Typ is the type for which the
801 -- conversion function is generated. On return, Decl and Fnam contain
802 -- the declaration and entity for the newly-created function.
804 function Build_To_Any_Call
805 (Loc : Source_Ptr;
806 N : Node_Id;
807 Decls : List_Id;
808 Constrained : Boolean := False) return Node_Id;
809 -- Build call to To_Any attribute function with expression as actual
810 -- parameter. Loc is the reference location of generated nodes,
811 -- Decls is the declarations list for an appropriate enclosing scope
812 -- of the point where the call will be inserted; if the To_Any
813 -- attribute for the type of N needs to be generated at this point,
814 -- its declaration is appended to Decls. For the case of a limited
815 -- type, there is an additional parameter Constrained indicating
816 -- whether 'Write (when True) or 'Output (when False) is used.
818 procedure Build_To_Any_Function
819 (Loc : Source_Ptr;
820 Typ : Entity_Id;
821 Decl : out Node_Id;
822 Fnam : out Entity_Id);
823 -- Build To_Any attribute function for Typ. Loc is the reference
824 -- location for generated nodes, Typ is the type for which the
825 -- conversion function is generated. On return, Decl and Fnam contain
826 -- the declaration and entity for the newly-created function.
828 function Build_TypeCode_Call
829 (Loc : Source_Ptr;
830 Typ : Entity_Id;
831 Decls : List_Id) return Node_Id;
832 -- Build call to TypeCode attribute function for Typ. Decls is the
833 -- declarations list for an appropriate enclosing scope of the point
834 -- where the call will be inserted; if the To_Any attribute for Typ
835 -- needs to be generated at this point, its declaration is appended
836 -- to Decls.
838 procedure Build_TypeCode_Function
839 (Loc : Source_Ptr;
840 Typ : Entity_Id;
841 Decl : out Node_Id;
842 Fnam : out Entity_Id);
843 -- Build TypeCode attribute function for Typ. Loc is the reference
844 -- location for generated nodes, Typ is the type for which the
845 -- typecode function is generated. On return, Decl and Fnam contain
846 -- the declaration and entity for the newly-created function.
848 procedure Build_Name_And_Repository_Id
849 (E : Entity_Id;
850 Name_Str : out String_Id;
851 Repo_Id_Str : out String_Id);
852 -- In the PolyORB distribution model, each distributed object type
853 -- and each distributed operation has a globally unique identifier,
854 -- its Repository Id. This subprogram builds and returns two strings
855 -- for entity E (a distributed object type or operation): one
856 -- containing the name of E, the second containing its repository id.
858 procedure Assign_Opaque_From_Any
859 (Loc : Source_Ptr;
860 Stms : List_Id;
861 Typ : Entity_Id;
862 N : Node_Id;
863 Target : Entity_Id;
864 Constrained : Boolean := False);
865 -- For a Target object of type Typ, which has opaque representation
866 -- as a sequence of octets determined by stream attributes (which
867 -- includes all limited types), append code to Stmts performing the
868 -- equivalent of:
869 -- Target := Typ'From_Any (N)
871 -- or, if Target is Empty:
872 -- return Typ'From_Any (N)
874 -- Constrained determines whether 'Input (when False) or 'Read
875 -- (when True) is used.
877 end Helpers;
879 end PolyORB_Support;
881 -- The following PolyORB-specific subprograms are made visible to Exp_Attr:
883 function Build_From_Any_Call
884 (Typ : Entity_Id;
885 N : Node_Id;
886 Decls : List_Id) return Node_Id
887 renames PolyORB_Support.Helpers.Build_From_Any_Call;
889 function Build_To_Any_Call
890 (Loc : Source_Ptr;
891 N : Node_Id;
892 Decls : List_Id;
893 Constrained : Boolean := False) return Node_Id
894 renames PolyORB_Support.Helpers.Build_To_Any_Call;
896 function Build_TypeCode_Call
897 (Loc : Source_Ptr;
898 Typ : Entity_Id;
899 Decls : List_Id) return Node_Id
900 renames PolyORB_Support.Helpers.Build_TypeCode_Call;
902 ------------------------------------
903 -- Local variables and structures --
904 ------------------------------------
906 RCI_Cache : Node_Id := Empty;
907 -- Needs comments ???
909 Output_From_Constrained : constant array (Boolean) of Name_Id :=
910 (False => Name_Output,
911 True => Name_Write);
912 -- The attribute to choose depending on the fact that the parameter
913 -- is constrained or not. There is no such thing as Input_From_Constrained
914 -- since this require separate mechanisms ('Input is a function while
915 -- 'Read is a procedure).
917 generic
918 with procedure Process_Subprogram_Declaration (Decl : Node_Id);
919 -- Generate calling or receiving stub for this subprogram declaration
921 procedure Build_Package_Stubs (Pkg_Spec : Node_Id);
922 -- Recursively visit the given RCI Package_Specification, calling
923 -- Process_Subprogram_Declaration for each remote subprogram.
925 -------------------------
926 -- Build_Package_Stubs --
927 -------------------------
929 procedure Build_Package_Stubs (Pkg_Spec : Node_Id) is
930 Decls : constant List_Id := Visible_Declarations (Pkg_Spec);
931 Decl : Node_Id;
933 procedure Visit_Nested_Pkg (Nested_Pkg_Decl : Node_Id);
934 -- Recurse for the given nested package declaration
936 ----------------------
937 -- Visit_Nested_Pkg --
938 ----------------------
940 procedure Visit_Nested_Pkg (Nested_Pkg_Decl : Node_Id) is
941 Nested_Pkg_Spec : constant Node_Id := Specification (Nested_Pkg_Decl);
942 begin
943 Push_Scope (Scope_Of_Spec (Nested_Pkg_Spec));
944 Build_Package_Stubs (Nested_Pkg_Spec);
945 Pop_Scope;
946 end Visit_Nested_Pkg;
948 -- Start of processing for Build_Package_Stubs
950 begin
951 Decl := First (Decls);
952 while Present (Decl) loop
953 case Nkind (Decl) is
954 when N_Subprogram_Declaration =>
956 -- Note: we test Comes_From_Source on Spec, not Decl, because
957 -- in the case of a subprogram instance, only the specification
958 -- (not the declaration) is marked as coming from source.
960 if Comes_From_Source (Specification (Decl)) then
961 Process_Subprogram_Declaration (Decl);
962 end if;
964 when N_Package_Declaration =>
966 -- Case of a nested package or package instantiation coming
967 -- from source, including the wrapper package for an instance
968 -- of a generic subprogram.
970 declare
971 Pkg_Ent : constant Entity_Id :=
972 Defining_Unit_Name (Specification (Decl));
973 begin
974 if Comes_From_Source (Decl)
975 or else
976 (Is_Generic_Instance (Pkg_Ent)
977 and then Comes_From_Source
978 (Get_Unit_Instantiation_Node (Pkg_Ent)))
979 then
980 Visit_Nested_Pkg (Decl);
981 end if;
982 end;
984 when others =>
985 null;
986 end case;
988 Next (Decl);
989 end loop;
990 end Build_Package_Stubs;
992 ---------------------------------------
993 -- Add_Calling_Stubs_To_Declarations --
994 ---------------------------------------
996 procedure Add_Calling_Stubs_To_Declarations (Pkg_Spec : Node_Id) is
997 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
999 Current_Subprogram_Number : Int := First_RCI_Subprogram_Id;
1000 -- Subprogram id 0 is reserved for calls received from
1001 -- remote access-to-subprogram dereferences.
1003 RCI_Instantiation : Node_Id;
1005 procedure Visit_Subprogram (Decl : Node_Id);
1006 -- Generate calling stub for one remote subprogram
1008 ----------------------
1009 -- Visit_Subprogram --
1010 ----------------------
1012 procedure Visit_Subprogram (Decl : Node_Id) is
1013 Loc : constant Source_Ptr := Sloc (Decl);
1014 Spec : constant Node_Id := Specification (Decl);
1015 Subp_Stubs : Node_Id;
1017 Subp_Str : String_Id;
1018 pragma Warnings (Off, Subp_Str);
1020 begin
1021 -- Disable expansion of stubs if serious errors have been diagnosed,
1022 -- because otherwise some illegal remote subprogram declarations
1023 -- could cause cascaded errors in stubs.
1025 if Serious_Errors_Detected /= 0 then
1026 return;
1027 end if;
1029 Assign_Subprogram_Identifier
1030 (Defining_Unit_Name (Spec), Current_Subprogram_Number, Subp_Str);
1032 Subp_Stubs :=
1033 Build_Subprogram_Calling_Stubs
1034 (Vis_Decl => Decl,
1035 Subp_Id =>
1036 Build_Subprogram_Id (Loc, Defining_Unit_Name (Spec)),
1037 Asynchronous =>
1038 Nkind (Spec) = N_Procedure_Specification
1039 and then Is_Asynchronous (Defining_Unit_Name (Spec)));
1041 Append_To (List_Containing (Decl), Subp_Stubs);
1042 Analyze (Subp_Stubs);
1044 Current_Subprogram_Number := Current_Subprogram_Number + 1;
1045 end Visit_Subprogram;
1047 procedure Visit_Spec is new Build_Package_Stubs (Visit_Subprogram);
1049 -- Start of processing for Add_Calling_Stubs_To_Declarations
1051 begin
1052 Push_Scope (Scope_Of_Spec (Pkg_Spec));
1054 -- The first thing added is an instantiation of the generic package
1055 -- System.Partition_Interface.RCI_Locator with the name of this remote
1056 -- package. This will act as an interface with the name server to
1057 -- determine the Partition_ID and the RPC_Receiver for the receiver
1058 -- of this package.
1060 RCI_Instantiation := RCI_Package_Locator (Loc, Pkg_Spec);
1061 RCI_Cache := Defining_Unit_Name (RCI_Instantiation);
1063 Append_To (Visible_Declarations (Pkg_Spec), RCI_Instantiation);
1064 Analyze (RCI_Instantiation);
1066 -- For each subprogram declaration visible in the spec, we do build a
1067 -- body. We also increment a counter to assign a different Subprogram_Id
1068 -- to each subprogram. The receiving stubs processing uses the same
1069 -- mechanism and will thus assign the same Id and do the correct
1070 -- dispatching.
1072 Overload_Counter_Table.Reset;
1073 PolyORB_Support.Reserve_NamingContext_Methods;
1075 Visit_Spec (Pkg_Spec);
1077 Pop_Scope;
1078 end Add_Calling_Stubs_To_Declarations;
1080 -----------------------------
1081 -- Add_Parameter_To_NVList --
1082 -----------------------------
1084 function Add_Parameter_To_NVList
1085 (Loc : Source_Ptr;
1086 NVList : Entity_Id;
1087 Parameter : Entity_Id;
1088 Constrained : Boolean;
1089 Any : Entity_Id) return Node_Id
1091 Parameter_Name_String : String_Id;
1092 Parameter_Mode : Node_Id;
1094 function Parameter_Passing_Mode
1095 (Loc : Source_Ptr;
1096 Parameter : Entity_Id;
1097 Constrained : Boolean) return Node_Id;
1098 -- Return an expression that denotes the parameter passing mode to be
1099 -- used for Parameter in distribution stubs, where Constrained is
1100 -- Parameter's constrained status.
1102 ----------------------------
1103 -- Parameter_Passing_Mode --
1104 ----------------------------
1106 function Parameter_Passing_Mode
1107 (Loc : Source_Ptr;
1108 Parameter : Entity_Id;
1109 Constrained : Boolean) return Node_Id
1111 Lib_RE : RE_Id;
1113 begin
1114 if Out_Present (Parameter) then
1115 if In_Present (Parameter)
1116 or else not Constrained
1117 then
1118 -- Unconstrained formals must be translated
1119 -- to 'in' or 'inout', not 'out', because
1120 -- they need to be constrained by the actual.
1122 Lib_RE := RE_Mode_Inout;
1123 else
1124 Lib_RE := RE_Mode_Out;
1125 end if;
1127 else
1128 Lib_RE := RE_Mode_In;
1129 end if;
1131 return New_Occurrence_Of (RTE (Lib_RE), Loc);
1132 end Parameter_Passing_Mode;
1134 -- Start of processing for Add_Parameter_To_NVList
1136 begin
1137 if Nkind (Parameter) = N_Defining_Identifier then
1138 Get_Name_String (Chars (Parameter));
1139 else
1140 Get_Name_String (Chars (Defining_Identifier (Parameter)));
1141 end if;
1143 Parameter_Name_String := String_From_Name_Buffer;
1145 if Nkind (Parameter) = N_Defining_Identifier then
1147 -- When the parameter passed to Add_Parameter_To_NVList is an
1148 -- Extra_Constrained parameter, Parameter is an N_Defining_
1149 -- Identifier, instead of a complete N_Parameter_Specification.
1150 -- Thus, we explicitly set 'in' mode in this case.
1152 Parameter_Mode := New_Occurrence_Of (RTE (RE_Mode_In), Loc);
1154 else
1155 Parameter_Mode :=
1156 Parameter_Passing_Mode (Loc, Parameter, Constrained);
1157 end if;
1159 return
1160 Make_Procedure_Call_Statement (Loc,
1161 Name =>
1162 New_Occurrence_Of (RTE (RE_NVList_Add_Item), Loc),
1163 Parameter_Associations => New_List (
1164 New_Occurrence_Of (NVList, Loc),
1165 Make_Function_Call (Loc,
1166 Name =>
1167 New_Occurrence_Of (RTE (RE_To_PolyORB_String), Loc),
1168 Parameter_Associations => New_List (
1169 Make_String_Literal (Loc, Strval => Parameter_Name_String))),
1170 New_Occurrence_Of (Any, Loc),
1171 Parameter_Mode));
1172 end Add_Parameter_To_NVList;
1174 --------------------------------
1175 -- Add_RACW_Asynchronous_Flag --
1176 --------------------------------
1178 procedure Add_RACW_Asynchronous_Flag
1179 (Declarations : List_Id;
1180 RACW_Type : Entity_Id)
1182 Loc : constant Source_Ptr := Sloc (RACW_Type);
1184 Asynchronous_Flag : constant Entity_Id :=
1185 Make_Defining_Identifier (Loc,
1186 New_External_Name (Chars (RACW_Type), 'A'));
1188 begin
1189 -- Declare the asynchronous flag. This flag will be changed to True
1190 -- whenever it is known that the RACW type is asynchronous.
1192 Append_To (Declarations,
1193 Make_Object_Declaration (Loc,
1194 Defining_Identifier => Asynchronous_Flag,
1195 Constant_Present => True,
1196 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
1197 Expression => New_Occurrence_Of (Standard_False, Loc)));
1199 Asynchronous_Flags_Table.Set (RACW_Type, Asynchronous_Flag);
1200 end Add_RACW_Asynchronous_Flag;
1202 -----------------------
1203 -- Add_RACW_Features --
1204 -----------------------
1206 procedure Add_RACW_Features (RACW_Type : Entity_Id) is
1207 Desig : constant Entity_Id := Etype (Designated_Type (RACW_Type));
1208 Same_Scope : constant Boolean := Scope (Desig) = Scope (RACW_Type);
1210 Pkg_Spec : Node_Id;
1211 Decls : List_Id;
1212 Body_Decls : List_Id;
1214 Stub_Type : Entity_Id;
1215 Stub_Type_Access : Entity_Id;
1216 RPC_Receiver_Decl : Node_Id;
1218 Existing : Boolean;
1219 -- True when appropriate stubs have already been generated (this is the
1220 -- case when another RACW with the same designated type has already been
1221 -- encountered), in which case we reuse the previous stubs rather than
1222 -- generating new ones.
1224 begin
1225 if not Expander_Active then
1226 return;
1227 end if;
1229 -- Mark the current package declaration as containing an RACW, so that
1230 -- the bodies for the calling stubs and the RACW stream subprograms
1231 -- are attached to the tree when the corresponding body is encountered.
1233 Set_Has_RACW (Current_Scope);
1235 -- Look for place to declare the RACW stub type and RACW operations
1237 Pkg_Spec := Empty;
1239 if Same_Scope then
1241 -- Case of declaring the RACW in the same package as its designated
1242 -- type: we know that the designated type is a private type, so we
1243 -- use the private declarations list.
1245 Pkg_Spec := Package_Specification_Of_Scope (Current_Scope);
1247 if Present (Private_Declarations (Pkg_Spec)) then
1248 Decls := Private_Declarations (Pkg_Spec);
1249 else
1250 Decls := Visible_Declarations (Pkg_Spec);
1251 end if;
1253 else
1254 -- Case of declaring the RACW in another package than its designated
1255 -- type: use the private declarations list if present; otherwise
1256 -- use the visible declarations.
1258 Decls := List_Containing (Declaration_Node (RACW_Type));
1260 end if;
1262 -- If we were unable to find the declarations, that means that the
1263 -- completion of the type was missing. We can safely return and let the
1264 -- error be caught by the semantic analysis.
1266 if No (Decls) then
1267 return;
1268 end if;
1270 Add_Stub_Type
1271 (Designated_Type => Desig,
1272 RACW_Type => RACW_Type,
1273 Decls => Decls,
1274 Stub_Type => Stub_Type,
1275 Stub_Type_Access => Stub_Type_Access,
1276 RPC_Receiver_Decl => RPC_Receiver_Decl,
1277 Body_Decls => Body_Decls,
1278 Existing => Existing);
1280 -- If this RACW is not in the main unit, do not generate primitive or
1281 -- TSS bodies.
1283 if not Entity_Is_In_Main_Unit (RACW_Type) then
1284 Body_Decls := No_List;
1285 end if;
1287 Add_RACW_Asynchronous_Flag
1288 (Declarations => Decls,
1289 RACW_Type => RACW_Type);
1291 Specific_Add_RACW_Features
1292 (RACW_Type => RACW_Type,
1293 Desig => Desig,
1294 Stub_Type => Stub_Type,
1295 Stub_Type_Access => Stub_Type_Access,
1296 RPC_Receiver_Decl => RPC_Receiver_Decl,
1297 Body_Decls => Body_Decls);
1299 -- If we already have stubs for this designated type, nothing to do
1301 if Existing then
1302 return;
1303 end if;
1305 if Is_Frozen (Desig) then
1306 Validate_RACW_Primitives (RACW_Type);
1307 Add_RACW_Primitive_Declarations_And_Bodies
1308 (Designated_Type => Desig,
1309 Insertion_Node => RPC_Receiver_Decl,
1310 Body_Decls => Body_Decls);
1312 else
1313 -- Validate_RACW_Primitives requires the list of all primitives of
1314 -- the designated type, so defer processing until Desig is frozen.
1315 -- See Exp_Ch3.Freeze_Type.
1317 Add_Access_Type_To_Process (E => Desig, A => RACW_Type);
1318 end if;
1319 end Add_RACW_Features;
1321 ------------------------------------------------
1322 -- Add_RACW_Primitive_Declarations_And_Bodies --
1323 ------------------------------------------------
1325 procedure Add_RACW_Primitive_Declarations_And_Bodies
1326 (Designated_Type : Entity_Id;
1327 Insertion_Node : Node_Id;
1328 Body_Decls : List_Id)
1330 Loc : constant Source_Ptr := Sloc (Insertion_Node);
1331 -- Set Sloc of generated declaration copy of insertion node Sloc, so
1332 -- the declarations are recognized as belonging to the current package.
1334 Stub_Elements : constant Stub_Structure :=
1335 Stubs_Table.Get (Designated_Type);
1337 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
1339 Is_RAS : constant Boolean :=
1340 not Comes_From_Source (Stub_Elements.RACW_Type);
1341 -- Case of the RACW generated to implement a remote access-to-
1342 -- subprogram type.
1344 Build_Bodies : constant Boolean :=
1345 In_Extended_Main_Code_Unit (Stub_Elements.Stub_Type);
1346 -- True when bodies must be prepared in Body_Decls. Bodies are generated
1347 -- only when the main unit is the unit that contains the stub type.
1349 Current_Insertion_Node : Node_Id := Insertion_Node;
1351 RPC_Receiver : Entity_Id;
1352 RPC_Receiver_Statements : List_Id;
1353 RPC_Receiver_Case_Alternatives : constant List_Id := New_List;
1354 RPC_Receiver_Elsif_Parts : List_Id := No_List;
1355 RPC_Receiver_Request : Entity_Id := Empty;
1356 RPC_Receiver_Subp_Id : Entity_Id := Empty;
1357 RPC_Receiver_Subp_Index : Entity_Id := Empty;
1359 Subp_Str : String_Id;
1361 Current_Primitive_Elmt : Elmt_Id;
1362 Current_Primitive : Entity_Id;
1363 Current_Primitive_Body : Node_Id;
1364 Current_Primitive_Spec : Node_Id;
1365 Current_Primitive_Decl : Node_Id;
1366 Current_Primitive_Number : Int := 0;
1367 Current_Primitive_Alias : Node_Id;
1368 Current_Receiver : Entity_Id;
1369 Current_Receiver_Body : Node_Id;
1370 RPC_Receiver_Decl : Node_Id;
1371 Possibly_Asynchronous : Boolean;
1373 begin
1374 if not Expander_Active then
1375 return;
1376 end if;
1378 if not Is_RAS then
1379 RPC_Receiver := Make_Temporary (Loc, 'P');
1381 Specific_Build_RPC_Receiver_Body
1382 (RPC_Receiver => RPC_Receiver,
1383 Request => RPC_Receiver_Request,
1384 Subp_Id => RPC_Receiver_Subp_Id,
1385 Subp_Index => RPC_Receiver_Subp_Index,
1386 Stmts => RPC_Receiver_Statements,
1387 Decl => RPC_Receiver_Decl);
1389 if Get_PCS_Name = Name_PolyORB_DSA then
1391 -- For the case of PolyORB, we need to map a textual operation
1392 -- name into a primitive index. Currently we do so using a simple
1393 -- sequence of string comparisons.
1395 RPC_Receiver_Elsif_Parts := New_List;
1396 end if;
1397 end if;
1399 -- Build callers, receivers for every primitive operations and a RPC
1400 -- receiver for this type. Note that we use Direct_Primitive_Operations,
1401 -- not Primitive_Operations, because we really want just the primitives
1402 -- of the tagged type itself, and in the case of a tagged synchronized
1403 -- type we do not want to get the primitives of the corresponding
1404 -- record type).
1406 if Present (Direct_Primitive_Operations (Designated_Type)) then
1407 Overload_Counter_Table.Reset;
1409 Current_Primitive_Elmt :=
1410 First_Elmt (Direct_Primitive_Operations (Designated_Type));
1411 while Current_Primitive_Elmt /= No_Elmt loop
1412 Current_Primitive := Node (Current_Primitive_Elmt);
1414 -- Copy the primitive of all the parents, except predefined ones
1415 -- that are not remotely dispatching. Also omit hidden primitives
1416 -- (occurs in the case of primitives of interface progenitors
1417 -- other than immediate ancestors of the Designated_Type).
1419 if Chars (Current_Primitive) /= Name_uSize
1420 and then Chars (Current_Primitive) /= Name_uAlignment
1421 and then not
1422 (Is_TSS (Current_Primitive, TSS_Deep_Finalize) or else
1423 Is_TSS (Current_Primitive, TSS_Put_Image) or else
1424 Is_TSS (Current_Primitive, TSS_Stream_Input) or else
1425 Is_TSS (Current_Primitive, TSS_Stream_Output) or else
1426 Is_TSS (Current_Primitive, TSS_Stream_Read) or else
1427 Is_TSS (Current_Primitive, TSS_Stream_Write)
1428 or else
1429 Is_Predefined_Interface_Primitive (Current_Primitive))
1430 and then not Is_Hidden (Current_Primitive)
1431 then
1432 -- The first thing to do is build an up-to-date copy of the
1433 -- spec with all the formals referencing Controlling_Type
1434 -- transformed into formals referencing Stub_Type. Since this
1435 -- primitive may have been inherited, go back the alias chain
1436 -- until the real primitive has been found.
1438 Current_Primitive_Alias := Ultimate_Alias (Current_Primitive);
1440 -- Copy the spec from the original declaration for the purpose
1441 -- of declaring an overriding subprogram: we need to replace
1442 -- the type of each controlling formal with Stub_Type. The
1443 -- primitive may have been declared for Controlling_Type or
1444 -- inherited from some ancestor type for which we do not have
1445 -- an easily determined Entity_Id. We have no systematic way
1446 -- of knowing which type to substitute Stub_Type for. Instead,
1447 -- Copy_Specification relies on the flag Is_Controlling_Formal
1448 -- to determine which formals to change.
1450 Current_Primitive_Spec :=
1451 Copy_Specification (Loc,
1452 Spec => Parent (Current_Primitive_Alias),
1453 Ctrl_Type => Stub_Elements.Stub_Type);
1455 Current_Primitive_Decl :=
1456 Make_Subprogram_Declaration (Loc,
1457 Specification => Current_Primitive_Spec);
1459 Insert_After_And_Analyze (Current_Insertion_Node,
1460 Current_Primitive_Decl);
1461 Current_Insertion_Node := Current_Primitive_Decl;
1463 Possibly_Asynchronous :=
1464 Nkind (Current_Primitive_Spec) = N_Procedure_Specification
1465 and then Could_Be_Asynchronous (Current_Primitive_Spec);
1467 Assign_Subprogram_Identifier (
1468 Defining_Unit_Name (Current_Primitive_Spec),
1469 Current_Primitive_Number,
1470 Subp_Str);
1472 if Build_Bodies then
1473 Current_Primitive_Body :=
1474 Build_Subprogram_Calling_Stubs
1475 (Vis_Decl => Current_Primitive_Decl,
1476 Subp_Id =>
1477 Build_Subprogram_Id (Loc,
1478 Defining_Unit_Name (Current_Primitive_Spec)),
1479 Asynchronous => Possibly_Asynchronous,
1480 Dynamically_Asynchronous => Possibly_Asynchronous,
1481 Stub_Type => Stub_Elements.Stub_Type,
1482 RACW_Type => Stub_Elements.RACW_Type);
1483 Append_To (Body_Decls, Current_Primitive_Body);
1485 -- Analyzing the body here would cause the Stub type to
1486 -- be frozen, thus preventing subsequent primitive
1487 -- declarations. For this reason, it will be analyzed
1488 -- later in the regular flow (and in the context of the
1489 -- appropriate unit body, see Append_RACW_Bodies).
1491 end if;
1493 -- Build the receiver stubs
1495 if Build_Bodies and then not Is_RAS then
1496 Current_Receiver_Body :=
1497 Specific_Build_Subprogram_Receiving_Stubs
1498 (Vis_Decl => Current_Primitive_Decl,
1499 Asynchronous => Possibly_Asynchronous,
1500 Dynamically_Asynchronous => Possibly_Asynchronous,
1501 Stub_Type => Stub_Elements.Stub_Type,
1502 RACW_Type => Stub_Elements.RACW_Type,
1503 Parent_Primitive => Current_Primitive);
1505 Current_Receiver :=
1506 Defining_Unit_Name (Specification (Current_Receiver_Body));
1508 Append_To (Body_Decls, Current_Receiver_Body);
1510 -- Add a case alternative to the receiver
1512 if Get_PCS_Name = Name_PolyORB_DSA then
1513 Append_To (RPC_Receiver_Elsif_Parts,
1514 Make_Elsif_Part (Loc,
1515 Condition =>
1516 Make_Function_Call (Loc,
1517 Name =>
1518 New_Occurrence_Of (
1519 RTE (RE_Caseless_String_Eq), Loc),
1520 Parameter_Associations => New_List (
1521 New_Occurrence_Of (RPC_Receiver_Subp_Id, Loc),
1522 Make_String_Literal (Loc, Subp_Str))),
1524 Then_Statements => New_List (
1525 Make_Assignment_Statement (Loc,
1526 Name => New_Occurrence_Of (
1527 RPC_Receiver_Subp_Index, Loc),
1528 Expression =>
1529 Make_Integer_Literal (Loc,
1530 Intval => Current_Primitive_Number)))));
1531 end if;
1533 Append_To (RPC_Receiver_Case_Alternatives,
1534 Make_Case_Statement_Alternative (Loc,
1535 Discrete_Choices => New_List (
1536 Make_Integer_Literal (Loc, Current_Primitive_Number)),
1538 Statements => New_List (
1539 Make_Procedure_Call_Statement (Loc,
1540 Name =>
1541 New_Occurrence_Of (Current_Receiver, Loc),
1542 Parameter_Associations => New_List (
1543 New_Occurrence_Of (RPC_Receiver_Request, Loc))))));
1544 end if;
1546 -- Increment the index of current primitive
1548 Current_Primitive_Number := Current_Primitive_Number + 1;
1549 end if;
1551 Next_Elmt (Current_Primitive_Elmt);
1552 end loop;
1553 end if;
1555 -- Build the case statement and the heart of the subprogram
1557 if Build_Bodies and then not Is_RAS then
1558 if Get_PCS_Name = Name_PolyORB_DSA
1559 and then Present (First (RPC_Receiver_Elsif_Parts))
1560 then
1561 Append_To (RPC_Receiver_Statements,
1562 Make_Implicit_If_Statement (Designated_Type,
1563 Condition => New_Occurrence_Of (Standard_False, Loc),
1564 Then_Statements => New_List,
1565 Elsif_Parts => RPC_Receiver_Elsif_Parts));
1566 end if;
1568 Append_To (RPC_Receiver_Case_Alternatives,
1569 Make_Case_Statement_Alternative (Loc,
1570 Discrete_Choices => New_List (Make_Others_Choice (Loc)),
1571 Statements => New_List (Make_Null_Statement (Loc))));
1573 Append_To (RPC_Receiver_Statements,
1574 Make_Case_Statement (Loc,
1575 Expression =>
1576 New_Occurrence_Of (RPC_Receiver_Subp_Index, Loc),
1577 Alternatives => RPC_Receiver_Case_Alternatives));
1579 Append_To (Body_Decls, RPC_Receiver_Decl);
1580 Specific_Add_Obj_RPC_Receiver_Completion (Loc,
1581 Body_Decls, RPC_Receiver, Stub_Elements);
1583 -- Do not analyze RPC receiver body at this stage since it references
1584 -- subprograms that have not been analyzed yet. It will be analyzed in
1585 -- the regular flow (see Append_RACW_Bodies).
1587 end if;
1588 end Add_RACW_Primitive_Declarations_And_Bodies;
1590 -----------------------------
1591 -- Add_RAS_Dereference_TSS --
1592 -----------------------------
1594 procedure Add_RAS_Dereference_TSS (N : Node_Id) is
1595 Loc : constant Source_Ptr := Sloc (N);
1597 Type_Def : constant Node_Id := Type_Definition (N);
1598 RAS_Type : constant Entity_Id := Defining_Identifier (N);
1599 Fat_Type : constant Entity_Id := Equivalent_Type (RAS_Type);
1600 RACW_Type : constant Entity_Id := Underlying_RACW_Type (RAS_Type);
1602 RACW_Primitive_Name : Node_Id;
1604 Proc : constant Entity_Id :=
1605 Make_Defining_Identifier (Loc,
1606 Chars => Make_TSS_Name (RAS_Type, TSS_RAS_Dereference));
1608 Proc_Spec : Node_Id;
1609 Param_Specs : List_Id;
1610 Param_Assoc : constant List_Id := New_List;
1611 Stmts : constant List_Id := New_List;
1613 RAS_Parameter : constant Entity_Id := Make_Temporary (Loc, 'P');
1615 Is_Function : constant Boolean :=
1616 Nkind (Type_Def) = N_Access_Function_Definition;
1618 Is_Degenerate : Boolean;
1619 -- Set to True if the subprogram_specification for this RAS has an
1620 -- anonymous access parameter (see Process_Remote_AST_Declaration).
1622 Spec : constant Node_Id := Type_Def;
1624 Current_Parameter : Node_Id;
1626 -- Start of processing for Add_RAS_Dereference_TSS
1628 begin
1629 -- The Dereference TSS for a remote access-to-subprogram type has the
1630 -- form:
1632 -- [function|procedure] ras_typeRD (RAS_Value, <RAS_Parameters>)
1633 -- [return <>]
1635 -- This is called whenever a value of a RAS type is dereferenced
1637 -- First construct a list of parameter specifications:
1639 -- The first formal is the RAS values
1641 Param_Specs := New_List (
1642 Make_Parameter_Specification (Loc,
1643 Defining_Identifier => RAS_Parameter,
1644 In_Present => True,
1645 Parameter_Type =>
1646 New_Occurrence_Of (Fat_Type, Loc)));
1648 -- The following formals are copied from the type declaration
1650 Is_Degenerate := False;
1651 Current_Parameter := First (Parameter_Specifications (Type_Def));
1652 Parameters : while Present (Current_Parameter) loop
1653 if Nkind (Parameter_Type (Current_Parameter)) =
1654 N_Access_Definition
1655 then
1656 Is_Degenerate := True;
1657 end if;
1659 Append_To (Param_Specs,
1660 Make_Parameter_Specification (Loc,
1661 Defining_Identifier =>
1662 Make_Defining_Identifier (Loc,
1663 Chars => Chars (Defining_Identifier (Current_Parameter))),
1664 In_Present => In_Present (Current_Parameter),
1665 Out_Present => Out_Present (Current_Parameter),
1666 Parameter_Type =>
1667 New_Copy_Tree (Parameter_Type (Current_Parameter)),
1668 Expression =>
1669 New_Copy_Tree (Expression (Current_Parameter))));
1671 Append_To (Param_Assoc,
1672 Make_Identifier (Loc,
1673 Chars => Chars (Defining_Identifier (Current_Parameter))));
1675 Next (Current_Parameter);
1676 end loop Parameters;
1678 if Is_Degenerate then
1679 Prepend_To (Param_Assoc, New_Occurrence_Of (RAS_Parameter, Loc));
1681 -- Generate a dummy body. This code will never actually be executed,
1682 -- because null is the only legal value for a degenerate RAS type.
1683 -- For legality's sake (in order to avoid generating a function that
1684 -- does not contain a return statement), we include a dummy recursive
1685 -- call on the TSS itself.
1687 Append_To (Stmts,
1688 Make_Raise_Program_Error (Loc, Reason => PE_Explicit_Raise));
1689 RACW_Primitive_Name := New_Occurrence_Of (Proc, Loc);
1691 else
1692 -- For a normal RAS type, we cast the RAS formal to the corresponding
1693 -- tagged type, and perform a dispatching call to its Call primitive
1694 -- operation.
1696 Prepend_To (Param_Assoc,
1697 Unchecked_Convert_To (RACW_Type,
1698 New_Occurrence_Of (RAS_Parameter, Loc)));
1700 RACW_Primitive_Name :=
1701 Make_Selected_Component (Loc,
1702 Prefix => Scope (RACW_Type),
1703 Selector_Name => Name_uCall);
1704 end if;
1706 if Is_Function then
1707 Append_To (Stmts,
1708 Make_Simple_Return_Statement (Loc,
1709 Expression =>
1710 Make_Function_Call (Loc,
1711 Name => RACW_Primitive_Name,
1712 Parameter_Associations => Param_Assoc)));
1714 else
1715 Append_To (Stmts,
1716 Make_Procedure_Call_Statement (Loc,
1717 Name => RACW_Primitive_Name,
1718 Parameter_Associations => Param_Assoc));
1719 end if;
1721 -- Build the complete subprogram
1723 if Is_Function then
1724 Proc_Spec :=
1725 Make_Function_Specification (Loc,
1726 Defining_Unit_Name => Proc,
1727 Parameter_Specifications => Param_Specs,
1728 Result_Definition =>
1729 New_Occurrence_Of (
1730 Entity (Result_Definition (Spec)), Loc));
1732 Mutate_Ekind (Proc, E_Function);
1733 Set_Etype (Proc,
1734 New_Occurrence_Of (Entity (Result_Definition (Spec)), Loc));
1736 else
1737 Proc_Spec :=
1738 Make_Procedure_Specification (Loc,
1739 Defining_Unit_Name => Proc,
1740 Parameter_Specifications => Param_Specs);
1742 Mutate_Ekind (Proc, E_Procedure);
1743 Set_Etype (Proc, Standard_Void_Type);
1744 end if;
1746 Discard_Node (
1747 Make_Subprogram_Body (Loc,
1748 Specification => Proc_Spec,
1749 Declarations => New_List,
1750 Handled_Statement_Sequence =>
1751 Make_Handled_Sequence_Of_Statements (Loc,
1752 Statements => Stmts)));
1754 Set_TSS (Fat_Type, Proc);
1755 end Add_RAS_Dereference_TSS;
1757 -------------------------------
1758 -- Add_RAS_Proxy_And_Analyze --
1759 -------------------------------
1761 procedure Add_RAS_Proxy_And_Analyze
1762 (Decls : List_Id;
1763 Vis_Decl : Node_Id;
1764 All_Calls_Remote_E : Entity_Id;
1765 Proxy_Object_Addr : out Entity_Id)
1767 Loc : constant Source_Ptr := Sloc (Vis_Decl);
1769 Subp_Name : constant Entity_Id :=
1770 Defining_Unit_Name (Specification (Vis_Decl));
1772 Pkg_Name : constant Entity_Id :=
1773 Make_Defining_Identifier (Loc,
1774 Chars => New_External_Name (Chars (Subp_Name), 'P', -1));
1776 Proxy_Type : constant Entity_Id :=
1777 Make_Defining_Identifier (Loc,
1778 Chars =>
1779 New_External_Name
1780 (Related_Id => Chars (Subp_Name),
1781 Suffix => 'P'));
1783 Proxy_Type_Full_View : constant Entity_Id :=
1784 Make_Defining_Identifier (Loc,
1785 Chars (Proxy_Type));
1787 Subp_Decl_Spec : constant Node_Id :=
1788 Build_RAS_Primitive_Specification
1789 (Subp_Spec => Specification (Vis_Decl),
1790 Remote_Object_Type => Proxy_Type);
1792 Subp_Body_Spec : constant Node_Id :=
1793 Build_RAS_Primitive_Specification
1794 (Subp_Spec => Specification (Vis_Decl),
1795 Remote_Object_Type => Proxy_Type);
1797 Vis_Decls : constant List_Id := New_List;
1798 Pvt_Decls : constant List_Id := New_List;
1799 Actuals : constant List_Id := New_List;
1800 Formal : Node_Id;
1801 Perform_Call : Node_Id;
1803 begin
1804 -- type subpP is tagged limited private;
1806 Append_To (Vis_Decls,
1807 Make_Private_Type_Declaration (Loc,
1808 Defining_Identifier => Proxy_Type,
1809 Tagged_Present => True,
1810 Limited_Present => True));
1812 -- [subprogram] Call
1813 -- (Self : access subpP;
1814 -- ...other-formals...)
1815 -- [return T];
1817 Append_To (Vis_Decls,
1818 Make_Subprogram_Declaration (Loc,
1819 Specification => Subp_Decl_Spec));
1821 -- A : constant System.Address;
1823 Proxy_Object_Addr := Make_Defining_Identifier (Loc, Name_uA);
1825 Append_To (Vis_Decls,
1826 Make_Object_Declaration (Loc,
1827 Defining_Identifier => Proxy_Object_Addr,
1828 Constant_Present => True,
1829 Object_Definition => New_Occurrence_Of (RTE (RE_Address), Loc)));
1831 -- private
1833 -- type subpP is tagged limited record
1834 -- All_Calls_Remote : Boolean := [All_Calls_Remote?];
1835 -- ...
1836 -- end record;
1838 Append_To (Pvt_Decls,
1839 Make_Full_Type_Declaration (Loc,
1840 Defining_Identifier => Proxy_Type_Full_View,
1841 Type_Definition =>
1842 Build_Remote_Subprogram_Proxy_Type (Loc,
1843 New_Occurrence_Of (All_Calls_Remote_E, Loc))));
1845 -- Trick semantic analysis into swapping the public and full view when
1846 -- freezing the public view.
1848 Set_Comes_From_Source (Proxy_Type_Full_View, True);
1850 -- procedure Call
1851 -- (Self : access O;
1852 -- ...other-formals...) is
1853 -- begin
1854 -- P (...other-formals...);
1855 -- end Call;
1857 -- function Call
1858 -- (Self : access O;
1859 -- ...other-formals...)
1860 -- return T is
1861 -- begin
1862 -- return F (...other-formals...);
1863 -- end Call;
1865 if Nkind (Subp_Decl_Spec) = N_Procedure_Specification then
1866 Perform_Call :=
1867 Make_Procedure_Call_Statement (Loc,
1868 Name => New_Occurrence_Of (Subp_Name, Loc),
1869 Parameter_Associations => Actuals);
1870 else
1871 Perform_Call :=
1872 Make_Simple_Return_Statement (Loc,
1873 Expression =>
1874 Make_Function_Call (Loc,
1875 Name => New_Occurrence_Of (Subp_Name, Loc),
1876 Parameter_Associations => Actuals));
1877 end if;
1879 Formal := First (Parameter_Specifications (Subp_Decl_Spec));
1880 pragma Assert (Present (Formal));
1881 loop
1882 Next (Formal);
1883 exit when No (Formal);
1884 Append_To (Actuals,
1885 New_Occurrence_Of (Defining_Identifier (Formal), Loc));
1886 end loop;
1888 -- O : aliased subpP;
1890 Append_To (Pvt_Decls,
1891 Make_Object_Declaration (Loc,
1892 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uO),
1893 Aliased_Present => True,
1894 Object_Definition => New_Occurrence_Of (Proxy_Type, Loc)));
1896 -- A : constant System.Address := O'Address;
1898 Append_To (Pvt_Decls,
1899 Make_Object_Declaration (Loc,
1900 Defining_Identifier =>
1901 Make_Defining_Identifier (Loc, Chars (Proxy_Object_Addr)),
1902 Constant_Present => True,
1903 Object_Definition => New_Occurrence_Of (RTE (RE_Address), Loc),
1904 Expression =>
1905 Make_Attribute_Reference (Loc,
1906 Prefix => New_Occurrence_Of (
1907 Defining_Identifier (Last (Pvt_Decls)), Loc),
1908 Attribute_Name => Name_Address)));
1910 Append_To (Decls,
1911 Make_Package_Declaration (Loc,
1912 Specification => Make_Package_Specification (Loc,
1913 Defining_Unit_Name => Pkg_Name,
1914 Visible_Declarations => Vis_Decls,
1915 Private_Declarations => Pvt_Decls,
1916 End_Label => Empty)));
1917 Analyze (Last (Decls));
1919 Append_To (Decls,
1920 Make_Package_Body (Loc,
1921 Defining_Unit_Name =>
1922 Make_Defining_Identifier (Loc, Chars (Pkg_Name)),
1923 Declarations => New_List (
1924 Make_Subprogram_Body (Loc,
1925 Specification => Subp_Body_Spec,
1926 Declarations => New_List,
1927 Handled_Statement_Sequence =>
1928 Make_Handled_Sequence_Of_Statements (Loc,
1929 Statements => New_List (Perform_Call))))));
1930 Analyze (Last (Decls));
1931 end Add_RAS_Proxy_And_Analyze;
1933 -----------------------
1934 -- Add_RAST_Features --
1935 -----------------------
1937 procedure Add_RAST_Features (Vis_Decl : Node_Id) is
1938 RAS_Type : constant Entity_Id :=
1939 Equivalent_Type (Defining_Identifier (Vis_Decl));
1940 begin
1941 pragma Assert (No (TSS (RAS_Type, TSS_RAS_Access)));
1942 Add_RAS_Dereference_TSS (Vis_Decl);
1943 Specific_Add_RAST_Features (Vis_Decl, RAS_Type);
1944 end Add_RAST_Features;
1946 -------------------
1947 -- Add_Stub_Type --
1948 -------------------
1950 procedure Add_Stub_Type
1951 (Designated_Type : Entity_Id;
1952 RACW_Type : Entity_Id;
1953 Decls : List_Id;
1954 Stub_Type : out Entity_Id;
1955 Stub_Type_Access : out Entity_Id;
1956 RPC_Receiver_Decl : out Node_Id;
1957 Body_Decls : out List_Id;
1958 Existing : out Boolean)
1960 Loc : constant Source_Ptr := Sloc (RACW_Type);
1962 Stub_Elements : constant Stub_Structure :=
1963 Stubs_Table.Get (Designated_Type);
1964 Stub_Type_Decl : Node_Id;
1965 Stub_Type_Access_Decl : Node_Id;
1967 begin
1968 if Stub_Elements /= Empty_Stub_Structure then
1969 Stub_Type := Stub_Elements.Stub_Type;
1970 Stub_Type_Access := Stub_Elements.Stub_Type_Access;
1971 RPC_Receiver_Decl := Stub_Elements.RPC_Receiver_Decl;
1972 Body_Decls := Stub_Elements.Body_Decls;
1973 Existing := True;
1974 return;
1975 end if;
1977 Existing := False;
1978 Stub_Type := Make_Temporary (Loc, 'S');
1979 Mutate_Ekind (Stub_Type, E_Record_Type);
1980 Set_Is_RACW_Stub_Type (Stub_Type);
1981 Stub_Type_Access :=
1982 Make_Defining_Identifier (Loc,
1983 Chars => New_External_Name
1984 (Related_Id => Chars (Stub_Type), Suffix => 'A'));
1986 RPC_Receiver_Decl := Specific_RPC_Receiver_Decl (RACW_Type);
1988 -- Create new stub type, copying components from generic RACW_Stub_Type
1990 Stub_Type_Decl :=
1991 Make_Full_Type_Declaration (Loc,
1992 Defining_Identifier => Stub_Type,
1993 Type_Definition =>
1994 Make_Record_Definition (Loc,
1995 Tagged_Present => True,
1996 Limited_Present => True,
1997 Component_List =>
1998 Make_Component_List (Loc,
1999 Component_Items =>
2000 Copy_Component_List (RTE (RE_RACW_Stub_Type), Loc))));
2002 -- Does the stub type need to explicitly implement interfaces from the
2003 -- designated type???
2005 -- In particular are there issues in the case where the designated type
2006 -- is a synchronized interface???
2008 Stub_Type_Access_Decl :=
2009 Make_Full_Type_Declaration (Loc,
2010 Defining_Identifier => Stub_Type_Access,
2011 Type_Definition =>
2012 Make_Access_To_Object_Definition (Loc,
2013 All_Present => True,
2014 Subtype_Indication => New_Occurrence_Of (Stub_Type, Loc)));
2016 Append_To (Decls, Stub_Type_Decl);
2017 Analyze (Last (Decls));
2018 Append_To (Decls, Stub_Type_Access_Decl);
2019 Analyze (Last (Decls));
2021 -- We can't directly derive the stub type from the designated type,
2022 -- because we don't want any components or discriminants from the real
2023 -- type, so instead we manually fake a derivation to get an appropriate
2024 -- dispatch table.
2026 Derive_Subprograms (Parent_Type => Designated_Type,
2027 Derived_Type => Stub_Type);
2029 if Present (RPC_Receiver_Decl) then
2030 Append_To (Decls, RPC_Receiver_Decl);
2032 else
2033 -- Case of RACW implementing a RAS with the GARLIC PCS: there is
2034 -- no RPC receiver in that case, this is just an indication of
2035 -- where to insert code in the tree (see comment in declaration of
2036 -- type Stub_Structure).
2038 RPC_Receiver_Decl := Last (Decls);
2039 end if;
2041 Body_Decls := New_List;
2043 Stubs_Table.Set (Designated_Type,
2044 (Stub_Type => Stub_Type,
2045 Stub_Type_Access => Stub_Type_Access,
2046 RPC_Receiver_Decl => RPC_Receiver_Decl,
2047 Body_Decls => Body_Decls,
2048 RACW_Type => RACW_Type));
2049 end Add_Stub_Type;
2051 ------------------------
2052 -- Append_RACW_Bodies --
2053 ------------------------
2055 procedure Append_RACW_Bodies (Decls : List_Id; Spec_Id : Entity_Id) is
2056 E : Entity_Id;
2058 begin
2059 E := First_Entity (Spec_Id);
2060 while Present (E) loop
2061 if Is_Remote_Access_To_Class_Wide_Type (E) then
2062 Append_List_To (Decls, Get_And_Reset_RACW_Bodies (E));
2063 end if;
2065 Next_Entity (E);
2066 end loop;
2067 end Append_RACW_Bodies;
2069 ----------------------------------
2070 -- Assign_Subprogram_Identifier --
2071 ----------------------------------
2073 procedure Assign_Subprogram_Identifier
2074 (Def : Entity_Id;
2075 Spn : Int;
2076 Id : out String_Id)
2078 N : constant Name_Id := Chars (Def);
2080 Overload_Order : constant Int := Overload_Counter_Table.Get (N) + 1;
2082 begin
2083 Overload_Counter_Table.Set (N, Overload_Order);
2085 Get_Name_String (N);
2087 -- Homonym handling: as in Exp_Dbug, but much simpler, because the only
2088 -- entities for which we have to generate names here need only to be
2089 -- disambiguated within their own scope.
2091 if Overload_Order > 1 then
2092 Name_Buffer (Name_Len + 1 .. Name_Len + 2) := "__";
2093 Name_Len := Name_Len + 2;
2094 Add_Nat_To_Name_Buffer (Overload_Order);
2095 end if;
2097 Id := String_From_Name_Buffer;
2098 Subprogram_Identifier_Table.Set
2099 (Def,
2100 Subprogram_Identifiers'(Str_Identifier => Id, Int_Identifier => Spn));
2101 end Assign_Subprogram_Identifier;
2103 -------------------------------------
2104 -- Build_Actual_Object_Declaration --
2105 -------------------------------------
2107 procedure Build_Actual_Object_Declaration
2108 (Object : Entity_Id;
2109 Etyp : Entity_Id;
2110 Variable : Boolean;
2111 Expr : Node_Id;
2112 Decls : List_Id)
2114 Loc : constant Source_Ptr := Sloc (Object);
2116 begin
2117 -- Declare a temporary object for the actual, possibly initialized with
2118 -- a 'Input/From_Any call.
2120 -- Complication arises in the case of limited types, for which such a
2121 -- declaration is illegal in Ada 95. In that case, we first generate a
2122 -- renaming declaration of the 'Input call, and then if needed we
2123 -- generate an overlaid non-constant view.
2125 if Ada_Version <= Ada_95
2126 and then Is_Limited_Type (Etyp)
2127 and then Present (Expr)
2128 then
2130 -- Object : Etyp renames <func-call>
2132 Append_To (Decls,
2133 Make_Object_Renaming_Declaration (Loc,
2134 Defining_Identifier => Object,
2135 Subtype_Mark => New_Occurrence_Of (Etyp, Loc),
2136 Name => Expr));
2138 if Variable then
2140 -- The name defined by the renaming declaration denotes a
2141 -- constant view; create a non-constant object at the same address
2142 -- to be used as the actual.
2144 declare
2145 Constant_Object : constant Entity_Id :=
2146 Make_Temporary (Loc, 'P');
2148 begin
2149 Set_Defining_Identifier
2150 (Last (Decls), Constant_Object);
2152 -- We have an unconstrained Etyp: build the actual constrained
2153 -- subtype for the value we just read from the stream.
2155 -- subtype S is <actual subtype of Constant_Object>;
2157 Append_To (Decls,
2158 Build_Actual_Subtype (Etyp,
2159 New_Occurrence_Of (Constant_Object, Loc)));
2161 -- Object : S;
2163 Append_To (Decls,
2164 Make_Object_Declaration (Loc,
2165 Defining_Identifier => Object,
2166 Object_Definition =>
2167 New_Occurrence_Of
2168 (Defining_Identifier (Last (Decls)), Loc)));
2169 Mutate_Ekind (Object, E_Variable);
2171 -- Suppress default initialization:
2172 -- pragma Import (Ada, Object);
2174 Append_To (Decls,
2175 Make_Pragma (Loc,
2176 Chars => Name_Import,
2177 Pragma_Argument_Associations => New_List (
2178 Make_Pragma_Argument_Association (Loc,
2179 Chars => Name_Convention,
2180 Expression => Make_Identifier (Loc, Name_Ada)),
2181 Make_Pragma_Argument_Association (Loc,
2182 Chars => Name_Entity,
2183 Expression => New_Occurrence_Of (Object, Loc)))));
2185 -- for Object'Address use Constant_Object'Address;
2187 Append_To (Decls,
2188 Make_Attribute_Definition_Clause (Loc,
2189 Name => New_Occurrence_Of (Object, Loc),
2190 Chars => Name_Address,
2191 Expression =>
2192 Make_Attribute_Reference (Loc,
2193 Prefix => New_Occurrence_Of (Constant_Object, Loc),
2194 Attribute_Name => Name_Address)));
2195 end;
2196 end if;
2198 else
2199 -- General case of a regular object declaration. Object is flagged
2200 -- constant unless it has mode out or in out, to allow the backend
2201 -- to optimize where possible.
2203 -- Object : [constant] Etyp [:= <expr>];
2205 Append_To (Decls,
2206 Make_Object_Declaration (Loc,
2207 Defining_Identifier => Object,
2208 Constant_Present => Present (Expr) and then not Variable,
2209 Object_Definition => New_Occurrence_Of (Etyp, Loc),
2210 Expression => Expr));
2212 if Constant_Present (Last (Decls)) then
2213 Mutate_Ekind (Object, E_Constant);
2214 else
2215 Mutate_Ekind (Object, E_Variable);
2216 end if;
2217 end if;
2218 end Build_Actual_Object_Declaration;
2220 ------------------------------
2221 -- Build_Get_Unique_RP_Call --
2222 ------------------------------
2224 function Build_Get_Unique_RP_Call
2225 (Loc : Source_Ptr;
2226 Pointer : Entity_Id;
2227 Stub_Type : Entity_Id) return List_Id
2229 begin
2230 return New_List (
2231 Make_Procedure_Call_Statement (Loc,
2232 Name =>
2233 New_Occurrence_Of (RTE (RE_Get_Unique_Remote_Pointer), Loc),
2234 Parameter_Associations => New_List (
2235 Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
2236 New_Occurrence_Of (Pointer, Loc)))),
2238 Make_Assignment_Statement (Loc,
2239 Name =>
2240 Make_Selected_Component (Loc,
2241 Prefix => New_Occurrence_Of (Pointer, Loc),
2242 Selector_Name =>
2243 New_Occurrence_Of (First_Tag_Component
2244 (Designated_Type (Etype (Pointer))), Loc)),
2245 Expression =>
2246 Make_Attribute_Reference (Loc,
2247 Prefix => New_Occurrence_Of (Stub_Type, Loc),
2248 Attribute_Name => Name_Tag)));
2250 -- Note: The assignment to Pointer._Tag is safe here because
2251 -- we carefully ensured that Stub_Type has exactly the same layout
2252 -- as System.Partition_Interface.RACW_Stub_Type.
2254 end Build_Get_Unique_RP_Call;
2256 -----------------------------------
2257 -- Build_Ordered_Parameters_List --
2258 -----------------------------------
2260 function Build_Ordered_Parameters_List (Spec : Node_Id) return List_Id is
2261 Constrained_List : List_Id;
2262 Unconstrained_List : List_Id;
2263 Current_Parameter : Node_Id;
2264 Ptyp : Node_Id;
2266 First_Parameter : Node_Id;
2267 For_RAS : Boolean := False;
2269 begin
2270 if No (Parameter_Specifications (Spec)) then
2271 return New_List;
2272 end if;
2274 Constrained_List := New_List;
2275 Unconstrained_List := New_List;
2276 First_Parameter := First (Parameter_Specifications (Spec));
2278 if Nkind (Parameter_Type (First_Parameter)) = N_Access_Definition
2279 and then Chars (Defining_Identifier (First_Parameter)) = Name_uS
2280 then
2281 For_RAS := True;
2282 end if;
2284 -- Loop through the parameters and add them to the right list. Note that
2285 -- we treat a parameter of a null-excluding access type as unconstrained
2286 -- because we can't declare an object of such a type with default
2287 -- initialization.
2289 Current_Parameter := First_Parameter;
2290 while Present (Current_Parameter) loop
2291 Ptyp := Parameter_Type (Current_Parameter);
2293 if (Nkind (Ptyp) = N_Access_Definition
2294 or else not Transmit_As_Unconstrained (Etype (Ptyp)))
2295 and then not (For_RAS and then Current_Parameter = First_Parameter)
2296 then
2297 Append_To (Constrained_List, New_Copy (Current_Parameter));
2298 else
2299 Append_To (Unconstrained_List, New_Copy (Current_Parameter));
2300 end if;
2302 Next (Current_Parameter);
2303 end loop;
2305 -- Unconstrained parameters are returned first
2307 Append_List_To (Unconstrained_List, Constrained_List);
2309 return Unconstrained_List;
2310 end Build_Ordered_Parameters_List;
2312 ----------------------------------
2313 -- Build_Passive_Partition_Stub --
2314 ----------------------------------
2316 procedure Build_Passive_Partition_Stub (U : Node_Id) is
2317 Pkg_Spec : Node_Id;
2318 Pkg_Ent : Entity_Id;
2319 L : List_Id;
2320 Reg : Node_Id;
2321 Loc : constant Source_Ptr := Sloc (U);
2323 begin
2324 -- Verify that the implementation supports distribution, by accessing
2325 -- a type defined in the proper version of system.rpc
2327 declare
2328 Dist_OK : Entity_Id;
2329 pragma Warnings (Off, Dist_OK);
2330 begin
2331 Dist_OK := RTE (RE_Params_Stream_Type);
2332 end;
2334 -- Use body if present, spec otherwise
2336 if Nkind (U) = N_Package_Declaration then
2337 Pkg_Spec := Specification (U);
2338 L := Visible_Declarations (Pkg_Spec);
2339 else
2340 Pkg_Spec := Parent (Corresponding_Spec (U));
2341 L := Declarations (U);
2342 end if;
2343 Pkg_Ent := Defining_Entity (Pkg_Spec);
2345 Reg :=
2346 Make_Procedure_Call_Statement (Loc,
2347 Name =>
2348 New_Occurrence_Of (RTE (RE_Register_Passive_Package), Loc),
2349 Parameter_Associations => New_List (
2350 Make_String_Literal (Loc,
2351 Fully_Qualified_Name_String (Pkg_Ent, Append_NUL => False)),
2352 Make_Attribute_Reference (Loc,
2353 Prefix => New_Occurrence_Of (Pkg_Ent, Loc),
2354 Attribute_Name => Name_Version)));
2355 Append_To (L, Reg);
2356 Analyze (Reg);
2357 end Build_Passive_Partition_Stub;
2359 --------------------------------------
2360 -- Build_RPC_Receiver_Specification --
2361 --------------------------------------
2363 function Build_RPC_Receiver_Specification
2364 (RPC_Receiver : Entity_Id;
2365 Request_Parameter : Entity_Id) return Node_Id
2367 Loc : constant Source_Ptr := Sloc (RPC_Receiver);
2368 begin
2369 return
2370 Make_Procedure_Specification (Loc,
2371 Defining_Unit_Name => RPC_Receiver,
2372 Parameter_Specifications => New_List (
2373 Make_Parameter_Specification (Loc,
2374 Defining_Identifier => Request_Parameter,
2375 Parameter_Type =>
2376 New_Occurrence_Of (RTE (RE_Request_Access), Loc))));
2377 end Build_RPC_Receiver_Specification;
2379 ----------------------------------------
2380 -- Build_Remote_Subprogram_Proxy_Type --
2381 ----------------------------------------
2383 function Build_Remote_Subprogram_Proxy_Type
2384 (Loc : Source_Ptr;
2385 ACR_Expression : Node_Id) return Node_Id
2387 begin
2388 return
2389 Make_Record_Definition (Loc,
2390 Tagged_Present => True,
2391 Limited_Present => True,
2392 Component_List =>
2393 Make_Component_List (Loc,
2394 Component_Items => New_List (
2395 Make_Component_Declaration (Loc,
2396 Defining_Identifier =>
2397 Make_Defining_Identifier (Loc,
2398 Name_All_Calls_Remote),
2399 Component_Definition =>
2400 Make_Component_Definition (Loc,
2401 Subtype_Indication =>
2402 New_Occurrence_Of (Standard_Boolean, Loc)),
2403 Expression =>
2404 ACR_Expression),
2406 Make_Component_Declaration (Loc,
2407 Defining_Identifier =>
2408 Make_Defining_Identifier (Loc,
2409 Name_Receiver),
2410 Component_Definition =>
2411 Make_Component_Definition (Loc,
2412 Subtype_Indication =>
2413 New_Occurrence_Of (RTE (RE_Address), Loc)),
2414 Expression =>
2415 New_Occurrence_Of (RTE (RE_Null_Address), Loc)),
2417 Make_Component_Declaration (Loc,
2418 Defining_Identifier =>
2419 Make_Defining_Identifier (Loc,
2420 Name_Subp_Id),
2421 Component_Definition =>
2422 Make_Component_Definition (Loc,
2423 Subtype_Indication =>
2424 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))))));
2425 end Build_Remote_Subprogram_Proxy_Type;
2427 --------------------
2428 -- Build_Stub_Tag --
2429 --------------------
2431 function Build_Stub_Tag
2432 (Loc : Source_Ptr;
2433 RACW_Type : Entity_Id) return Node_Id
2435 Stub_Type : constant Entity_Id := Corresponding_Stub_Type (RACW_Type);
2436 begin
2437 return
2438 Make_Attribute_Reference (Loc,
2439 Prefix => New_Occurrence_Of (Stub_Type, Loc),
2440 Attribute_Name => Name_Tag);
2441 end Build_Stub_Tag;
2443 ------------------------------------
2444 -- Build_Subprogram_Calling_Stubs --
2445 ------------------------------------
2447 function Build_Subprogram_Calling_Stubs
2448 (Vis_Decl : Node_Id;
2449 Subp_Id : Node_Id;
2450 Asynchronous : Boolean;
2451 Dynamically_Asynchronous : Boolean := False;
2452 Stub_Type : Entity_Id := Empty;
2453 RACW_Type : Entity_Id := Empty;
2454 Locator : Entity_Id := Empty;
2455 New_Name : Name_Id := No_Name) return Node_Id
2457 Loc : constant Source_Ptr := Sloc (Vis_Decl);
2459 Decls : constant List_Id := New_List;
2460 Statements : constant List_Id := New_List;
2462 Subp_Spec : Node_Id;
2463 -- The specification of the body
2465 Controlling_Parameter : Entity_Id := Empty;
2467 Asynchronous_Expr : Node_Id := Empty;
2469 RCI_Locator : Entity_Id;
2471 Spec_To_Use : Node_Id;
2473 procedure Insert_Partition_Check (Parameter : Node_Id);
2474 -- Check that the parameter has been elaborated on the same partition
2475 -- than the controlling parameter (E.4(19)).
2477 ----------------------------
2478 -- Insert_Partition_Check --
2479 ----------------------------
2481 procedure Insert_Partition_Check (Parameter : Node_Id) is
2482 Parameter_Entity : constant Entity_Id :=
2483 Defining_Identifier (Parameter);
2484 begin
2485 -- The expression that will be built is of the form:
2487 -- if not Same_Partition (Parameter, Controlling_Parameter) then
2488 -- raise Constraint_Error;
2489 -- end if;
2491 -- We do not check that Parameter is in Stub_Type since such a check
2492 -- has been inserted at the point of call already (a tag check since
2493 -- we have multiple controlling operands).
2495 Append_To (Decls,
2496 Make_Raise_Constraint_Error (Loc,
2497 Condition =>
2498 Make_Op_Not (Loc,
2499 Right_Opnd =>
2500 Make_Function_Call (Loc,
2501 Name =>
2502 New_Occurrence_Of (RTE (RE_Same_Partition), Loc),
2503 Parameter_Associations =>
2504 New_List (
2505 Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
2506 New_Occurrence_Of (Parameter_Entity, Loc)),
2507 Unchecked_Convert_To (RTE (RE_RACW_Stub_Type_Access),
2508 New_Occurrence_Of (Controlling_Parameter, Loc))))),
2509 Reason => CE_Partition_Check_Failed));
2510 end Insert_Partition_Check;
2512 -- Start of processing for Build_Subprogram_Calling_Stubs
2514 begin
2515 Subp_Spec :=
2516 Copy_Specification (Loc,
2517 Spec => Specification (Vis_Decl),
2518 New_Name => New_Name);
2520 if Locator = Empty then
2521 RCI_Locator := RCI_Cache;
2522 Spec_To_Use := Specification (Vis_Decl);
2523 else
2524 RCI_Locator := Locator;
2525 Spec_To_Use := Subp_Spec;
2526 end if;
2528 -- Find a controlling argument if we have a stub type. Also check
2529 -- if this subprogram can be made asynchronous.
2531 if Present (Stub_Type)
2532 and then Present (Parameter_Specifications (Spec_To_Use))
2533 then
2534 declare
2535 Current_Parameter : Node_Id :=
2536 First (Parameter_Specifications
2537 (Spec_To_Use));
2538 begin
2539 while Present (Current_Parameter) loop
2541 Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type)
2542 then
2543 if Controlling_Parameter = Empty then
2544 Controlling_Parameter :=
2545 Defining_Identifier (Current_Parameter);
2546 else
2547 Insert_Partition_Check (Current_Parameter);
2548 end if;
2549 end if;
2551 Next (Current_Parameter);
2552 end loop;
2553 end;
2554 end if;
2556 pragma Assert (No (Stub_Type) or else Present (Controlling_Parameter));
2558 if Dynamically_Asynchronous then
2559 Asynchronous_Expr := Make_Selected_Component (Loc,
2560 Prefix => Controlling_Parameter,
2561 Selector_Name => Name_Asynchronous);
2562 end if;
2564 Specific_Build_General_Calling_Stubs
2565 (Decls => Decls,
2566 Statements => Statements,
2567 Target => Specific_Build_Stub_Target (Loc,
2568 Decls, RCI_Locator, Controlling_Parameter),
2569 Subprogram_Id => Subp_Id,
2570 Asynchronous => Asynchronous_Expr,
2571 Is_Known_Asynchronous => Asynchronous
2572 and then not Dynamically_Asynchronous,
2573 Is_Known_Non_Asynchronous
2574 => not Asynchronous
2575 and then not Dynamically_Asynchronous,
2576 Is_Function => Nkind (Spec_To_Use) =
2577 N_Function_Specification,
2578 Spec => Spec_To_Use,
2579 Stub_Type => Stub_Type,
2580 RACW_Type => RACW_Type,
2581 Nod => Vis_Decl);
2583 RCI_Calling_Stubs_Table.Set
2584 (Defining_Unit_Name (Specification (Vis_Decl)),
2585 Defining_Unit_Name (Spec_To_Use));
2587 return
2588 Make_Subprogram_Body (Loc,
2589 Specification => Subp_Spec,
2590 Declarations => Decls,
2591 Handled_Statement_Sequence =>
2592 Make_Handled_Sequence_Of_Statements (Loc, Statements));
2593 end Build_Subprogram_Calling_Stubs;
2595 -------------------------
2596 -- Build_Subprogram_Id --
2597 -------------------------
2599 function Build_Subprogram_Id
2600 (Loc : Source_Ptr;
2601 E : Entity_Id) return Node_Id
2603 begin
2604 if Get_Subprogram_Ids (E).Str_Identifier = No_String then
2605 declare
2606 Current_Declaration : Node_Id;
2607 Current_Subp : Entity_Id;
2608 Current_Subp_Str : String_Id;
2609 Current_Subp_Number : Int := First_RCI_Subprogram_Id;
2611 pragma Warnings (Off, Current_Subp_Str);
2613 begin
2614 -- Build_Subprogram_Id is called outside of the context of
2615 -- generating calling or receiving stubs. Hence we are processing
2616 -- an 'Access attribute_reference for an RCI subprogram, for the
2617 -- purpose of obtaining a RAS value.
2619 pragma Assert
2620 (Is_Remote_Call_Interface (Scope (E))
2621 and then
2622 (Nkind (Parent (E)) = N_Procedure_Specification
2623 or else
2624 Nkind (Parent (E)) = N_Function_Specification));
2626 Current_Declaration :=
2627 First (Visible_Declarations
2628 (Package_Specification_Of_Scope (Scope (E))));
2629 while Present (Current_Declaration) loop
2630 if Nkind (Current_Declaration) = N_Subprogram_Declaration
2631 and then Comes_From_Source (Current_Declaration)
2632 then
2633 Current_Subp := Defining_Unit_Name (Specification (
2634 Current_Declaration));
2636 Assign_Subprogram_Identifier
2637 (Current_Subp, Current_Subp_Number, Current_Subp_Str);
2639 Current_Subp_Number := Current_Subp_Number + 1;
2640 end if;
2642 Next (Current_Declaration);
2643 end loop;
2644 end;
2645 end if;
2647 case Get_PCS_Name is
2648 when Name_PolyORB_DSA =>
2649 return Make_String_Literal (Loc, Get_Subprogram_Id (E));
2651 when others =>
2652 return Make_Integer_Literal (Loc, Get_Subprogram_Id (E));
2653 end case;
2654 end Build_Subprogram_Id;
2656 ------------------------
2657 -- Copy_Specification --
2658 ------------------------
2660 function Copy_Specification
2661 (Loc : Source_Ptr;
2662 Spec : Node_Id;
2663 Ctrl_Type : Entity_Id := Empty;
2664 New_Name : Name_Id := No_Name) return Node_Id
2666 Parameters : List_Id := No_List;
2668 Current_Parameter : Node_Id;
2669 Current_Identifier : Entity_Id;
2670 Current_Type : Node_Id;
2672 Name_For_New_Spec : Name_Id;
2674 New_Identifier : Entity_Id;
2676 -- Comments needed in body below ???
2678 begin
2679 if New_Name = No_Name then
2680 pragma Assert (Nkind (Spec) = N_Function_Specification
2681 or else Nkind (Spec) = N_Procedure_Specification);
2683 Name_For_New_Spec := Chars (Defining_Unit_Name (Spec));
2684 else
2685 Name_For_New_Spec := New_Name;
2686 end if;
2688 if Present (Parameter_Specifications (Spec)) then
2689 Parameters := New_List;
2690 Current_Parameter := First (Parameter_Specifications (Spec));
2691 while Present (Current_Parameter) loop
2692 Current_Identifier := Defining_Identifier (Current_Parameter);
2693 Current_Type := Parameter_Type (Current_Parameter);
2695 if Nkind (Current_Type) = N_Access_Definition then
2696 if Present (Ctrl_Type) then
2697 pragma Assert (Is_Controlling_Formal (Current_Identifier));
2698 Current_Type :=
2699 Make_Access_Definition (Loc,
2700 Subtype_Mark => New_Occurrence_Of (Ctrl_Type, Loc),
2701 Null_Exclusion_Present =>
2702 Null_Exclusion_Present (Current_Type));
2704 else
2705 Current_Type :=
2706 Make_Access_Definition (Loc,
2707 Subtype_Mark =>
2708 New_Copy_Tree (Subtype_Mark (Current_Type)),
2709 Null_Exclusion_Present =>
2710 Null_Exclusion_Present (Current_Type));
2711 end if;
2713 else
2714 if Present (Ctrl_Type)
2715 and then Is_Controlling_Formal (Current_Identifier)
2716 then
2717 Current_Type := New_Occurrence_Of (Ctrl_Type, Loc);
2718 else
2719 Current_Type := New_Copy_Tree (Current_Type);
2720 end if;
2721 end if;
2723 New_Identifier := Make_Defining_Identifier (Loc,
2724 Chars (Current_Identifier));
2726 Append_To (Parameters,
2727 Make_Parameter_Specification (Loc,
2728 Defining_Identifier => New_Identifier,
2729 Parameter_Type => Current_Type,
2730 In_Present => In_Present (Current_Parameter),
2731 Out_Present => Out_Present (Current_Parameter),
2732 Expression =>
2733 New_Copy_Tree (Expression (Current_Parameter))));
2735 -- For a regular formal parameter (that needs to be marshalled
2736 -- in the context of remote calls), set the Etype now, because
2737 -- marshalling processing might need it.
2739 if Is_Entity_Name (Current_Type) then
2740 Set_Etype (New_Identifier, Entity (Current_Type));
2742 -- Current_Type is an access definition, special processing
2743 -- (not requiring etype) will occur for marshalling.
2745 else
2746 null;
2747 end if;
2749 Next (Current_Parameter);
2750 end loop;
2751 end if;
2753 case Nkind (Spec) is
2754 when N_Access_Function_Definition
2755 | N_Function_Specification
2757 return
2758 Make_Function_Specification (Loc,
2759 Defining_Unit_Name =>
2760 Make_Defining_Identifier (Loc,
2761 Chars => Name_For_New_Spec),
2762 Parameter_Specifications => Parameters,
2763 Result_Definition =>
2764 New_Occurrence_Of (Entity (Result_Definition (Spec)), Loc));
2766 when N_Access_Procedure_Definition
2767 | N_Procedure_Specification
2769 return
2770 Make_Procedure_Specification (Loc,
2771 Defining_Unit_Name =>
2772 Make_Defining_Identifier (Loc,
2773 Chars => Name_For_New_Spec),
2774 Parameter_Specifications => Parameters);
2776 when others =>
2777 raise Program_Error;
2778 end case;
2779 end Copy_Specification;
2781 -----------------------------
2782 -- Corresponding_Stub_Type --
2783 -----------------------------
2785 function Corresponding_Stub_Type (RACW_Type : Entity_Id) return Entity_Id is
2786 Desig : constant Entity_Id :=
2787 Etype (Designated_Type (RACW_Type));
2788 Stub_Elements : constant Stub_Structure := Stubs_Table.Get (Desig);
2789 begin
2790 return Stub_Elements.Stub_Type;
2791 end Corresponding_Stub_Type;
2793 ---------------------------
2794 -- Could_Be_Asynchronous --
2795 ---------------------------
2797 function Could_Be_Asynchronous (Spec : Node_Id) return Boolean is
2798 Current_Parameter : Node_Id;
2800 begin
2801 if Present (Parameter_Specifications (Spec)) then
2802 Current_Parameter := First (Parameter_Specifications (Spec));
2803 while Present (Current_Parameter) loop
2804 if Out_Present (Current_Parameter) then
2805 return False;
2806 end if;
2808 Next (Current_Parameter);
2809 end loop;
2810 end if;
2812 return True;
2813 end Could_Be_Asynchronous;
2815 ---------------------------
2816 -- Declare_Create_NVList --
2817 ---------------------------
2819 procedure Declare_Create_NVList
2820 (Loc : Source_Ptr;
2821 NVList : Entity_Id;
2822 Decls : List_Id;
2823 Stmts : List_Id)
2825 begin
2826 Append_To (Decls,
2827 Make_Object_Declaration (Loc,
2828 Defining_Identifier => NVList,
2829 Aliased_Present => False,
2830 Object_Definition =>
2831 New_Occurrence_Of (RTE (RE_NVList_Ref), Loc)));
2833 Append_To (Stmts,
2834 Make_Procedure_Call_Statement (Loc,
2835 Name => New_Occurrence_Of (RTE (RE_NVList_Create), Loc),
2836 Parameter_Associations => New_List (
2837 New_Occurrence_Of (NVList, Loc))));
2838 end Declare_Create_NVList;
2840 ---------------------------------------------
2841 -- Expand_All_Calls_Remote_Subprogram_Call --
2842 ---------------------------------------------
2844 procedure Expand_All_Calls_Remote_Subprogram_Call (N : Node_Id) is
2845 Loc : constant Source_Ptr := Sloc (N);
2846 Called_Subprogram : constant Entity_Id := Entity (Name (N));
2847 RCI_Package : constant Entity_Id := Scope (Called_Subprogram);
2848 RCI_Locator_Decl : Node_Id;
2849 RCI_Locator : Entity_Id;
2850 Calling_Stubs : Node_Id;
2851 E_Calling_Stubs : Entity_Id;
2853 begin
2854 E_Calling_Stubs := RCI_Calling_Stubs_Table.Get (Called_Subprogram);
2856 if E_Calling_Stubs = Empty then
2857 RCI_Locator := RCI_Locator_Table.Get (RCI_Package);
2859 -- The RCI_Locator package and calling stub are inserted at the top
2860 -- level in the current unit, and must appear in the proper scope so
2861 -- that it is not prematurely removed by the GCC back end.
2863 declare
2864 Scop : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
2865 begin
2866 if Ekind (Scop) = E_Package_Body then
2867 Push_Scope (Spec_Entity (Scop));
2868 elsif Ekind (Scop) = E_Subprogram_Body then
2869 Push_Scope
2870 (Corresponding_Spec (Unit_Declaration_Node (Scop)));
2871 else
2872 Push_Scope (Scop);
2873 end if;
2874 end;
2876 if RCI_Locator = Empty then
2877 RCI_Locator_Decl :=
2878 RCI_Package_Locator (Loc, Package_Specification (RCI_Package));
2879 Prepend_To (Current_Sem_Unit_Declarations, RCI_Locator_Decl);
2880 Analyze (RCI_Locator_Decl);
2881 RCI_Locator := Defining_Unit_Name (RCI_Locator_Decl);
2883 else
2884 RCI_Locator_Decl := Parent (RCI_Locator);
2885 end if;
2887 Calling_Stubs := Build_Subprogram_Calling_Stubs
2888 (Vis_Decl => Parent (Parent (Called_Subprogram)),
2889 Subp_Id =>
2890 Build_Subprogram_Id (Loc, Called_Subprogram),
2891 Asynchronous => Nkind (N) = N_Procedure_Call_Statement
2892 and then
2893 Is_Asynchronous (Called_Subprogram),
2894 Locator => RCI_Locator,
2895 New_Name => New_Internal_Name ('S'));
2896 Insert_After (RCI_Locator_Decl, Calling_Stubs);
2897 Analyze (Calling_Stubs);
2898 Pop_Scope;
2900 E_Calling_Stubs := Defining_Unit_Name (Specification (Calling_Stubs));
2901 end if;
2903 Rewrite (Name (N), New_Occurrence_Of (E_Calling_Stubs, Loc));
2904 end Expand_All_Calls_Remote_Subprogram_Call;
2906 ---------------------------------
2907 -- Expand_Calling_Stubs_Bodies --
2908 ---------------------------------
2910 procedure Expand_Calling_Stubs_Bodies (Unit_Node : Node_Id) is
2911 Spec : constant Node_Id := Specification (Unit_Node);
2912 begin
2913 Add_Calling_Stubs_To_Declarations (Spec);
2914 end Expand_Calling_Stubs_Bodies;
2916 -----------------------------------
2917 -- Expand_Receiving_Stubs_Bodies --
2918 -----------------------------------
2920 procedure Expand_Receiving_Stubs_Bodies (Unit_Node : Node_Id) is
2921 Spec : Node_Id;
2922 Decls : List_Id;
2923 Stubs_Decls : List_Id;
2924 Stubs_Stmts : List_Id;
2926 begin
2927 if Nkind (Unit_Node) = N_Package_Declaration then
2928 Spec := Specification (Unit_Node);
2929 Decls := Private_Declarations (Spec);
2931 if No (Decls) then
2932 Decls := Visible_Declarations (Spec);
2933 end if;
2935 Push_Scope (Scope_Of_Spec (Spec));
2936 Specific_Add_Receiving_Stubs_To_Declarations (Spec, Decls, Decls);
2938 else
2939 Spec :=
2940 Package_Specification_Of_Scope (Corresponding_Spec (Unit_Node));
2941 Decls := Declarations (Unit_Node);
2943 Push_Scope (Scope_Of_Spec (Unit_Node));
2944 Stubs_Decls := New_List;
2945 Stubs_Stmts := New_List;
2946 Specific_Add_Receiving_Stubs_To_Declarations
2947 (Spec, Stubs_Decls, Stubs_Stmts);
2949 Insert_List_Before (First (Decls), Stubs_Decls);
2951 declare
2952 HSS_Stmts : constant List_Id :=
2953 Statements (Handled_Statement_Sequence (Unit_Node));
2955 First_HSS_Stmt : constant Node_Id := First (HSS_Stmts);
2957 begin
2958 if No (First_HSS_Stmt) then
2959 Append_List_To (HSS_Stmts, Stubs_Stmts);
2960 else
2961 Insert_List_Before (First_HSS_Stmt, Stubs_Stmts);
2962 end if;
2963 end;
2964 end if;
2966 Pop_Scope;
2967 end Expand_Receiving_Stubs_Bodies;
2969 --------------------
2970 -- GARLIC_Support --
2971 --------------------
2973 package body GARLIC_Support is
2975 -- Local subprograms
2977 procedure Add_RACW_Read_Attribute
2978 (RACW_Type : Entity_Id;
2979 Stub_Type : Entity_Id;
2980 Stub_Type_Access : Entity_Id;
2981 Body_Decls : List_Id);
2982 -- Add Read attribute for the RACW type. The declaration and attribute
2983 -- definition clauses are inserted right after the declaration of
2984 -- RACW_Type. If Body_Decls is not No_List, the subprogram body is
2985 -- appended to it (case where the RACW declaration is in the main unit).
2987 procedure Add_RACW_Write_Attribute
2988 (RACW_Type : Entity_Id;
2989 Stub_Type : Entity_Id;
2990 Stub_Type_Access : Entity_Id;
2991 RPC_Receiver : Node_Id;
2992 Body_Decls : List_Id);
2993 -- Same as above for the Write attribute
2995 function Stream_Parameter return Node_Id;
2996 function Result return Node_Id;
2997 function Object return Node_Id renames Result;
2998 -- Functions to create occurrences of the formal parameter names of the
2999 -- 'Read and 'Write attributes.
3001 Loc : Source_Ptr;
3002 -- Shared source location used by Add_{Read,Write}_Read_Attribute and
3003 -- their ancillary subroutines (set on entry by Add_RACW_Features).
3005 procedure Add_RAS_Access_TSS (N : Node_Id);
3006 -- Add a subprogram body for RAS Access TSS
3008 -------------------------------------
3009 -- Add_Obj_RPC_Receiver_Completion --
3010 -------------------------------------
3012 procedure Add_Obj_RPC_Receiver_Completion
3013 (Loc : Source_Ptr;
3014 Decls : List_Id;
3015 RPC_Receiver : Entity_Id;
3016 Stub_Elements : Stub_Structure)
3018 begin
3019 -- The RPC receiver body should not be the completion of the
3020 -- declaration recorded in the stub structure, because then the
3021 -- occurrences of the formal parameters within the body should refer
3022 -- to the entities from the declaration, not from the completion, to
3023 -- which we do not have easy access. Instead, the RPC receiver body
3024 -- acts as its own declaration, and the RPC receiver declaration is
3025 -- completed by a renaming-as-body.
3027 Append_To (Decls,
3028 Make_Subprogram_Renaming_Declaration (Loc,
3029 Specification =>
3030 Copy_Specification (Loc,
3031 Specification (Stub_Elements.RPC_Receiver_Decl)),
3032 Name => New_Occurrence_Of (RPC_Receiver, Loc)));
3033 end Add_Obj_RPC_Receiver_Completion;
3035 -----------------------
3036 -- Add_RACW_Features --
3037 -----------------------
3039 procedure Add_RACW_Features
3040 (RACW_Type : Entity_Id;
3041 Stub_Type : Entity_Id;
3042 Stub_Type_Access : Entity_Id;
3043 RPC_Receiver_Decl : Node_Id;
3044 Body_Decls : List_Id)
3046 RPC_Receiver : Node_Id;
3047 Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
3049 begin
3050 Loc := Sloc (RACW_Type);
3052 if Is_RAS then
3054 -- For a RAS, the RPC receiver is that of the RCI unit, not that
3055 -- of the corresponding distributed object type. We retrieve its
3056 -- address from the local proxy object.
3058 RPC_Receiver := Make_Selected_Component (Loc,
3059 Prefix =>
3060 Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access), Object),
3061 Selector_Name => Make_Identifier (Loc, Name_Receiver));
3063 else
3064 RPC_Receiver := Make_Attribute_Reference (Loc,
3065 Prefix => New_Occurrence_Of (
3066 Defining_Unit_Name (Specification (RPC_Receiver_Decl)), Loc),
3067 Attribute_Name => Name_Address);
3068 end if;
3070 Add_RACW_Write_Attribute
3071 (RACW_Type,
3072 Stub_Type,
3073 Stub_Type_Access,
3074 RPC_Receiver,
3075 Body_Decls);
3077 Add_RACW_Read_Attribute
3078 (RACW_Type,
3079 Stub_Type,
3080 Stub_Type_Access,
3081 Body_Decls);
3082 end Add_RACW_Features;
3084 -----------------------------
3085 -- Add_RACW_Read_Attribute --
3086 -----------------------------
3088 procedure Add_RACW_Read_Attribute
3089 (RACW_Type : Entity_Id;
3090 Stub_Type : Entity_Id;
3091 Stub_Type_Access : Entity_Id;
3092 Body_Decls : List_Id)
3094 Proc_Decl : Node_Id;
3095 Attr_Decl : Node_Id;
3097 Body_Node : Node_Id;
3099 Statements : constant List_Id := New_List;
3100 Decls : List_Id;
3101 Local_Statements : List_Id;
3102 Remote_Statements : List_Id;
3103 -- Various parts of the procedure
3105 Pnam : constant Entity_Id := Make_Temporary (Loc, 'R');
3106 Asynchronous_Flag : constant Entity_Id :=
3107 Asynchronous_Flags_Table.Get (RACW_Type);
3108 pragma Assert (Present (Asynchronous_Flag));
3110 -- Prepare local identifiers
3112 Source_Partition : Entity_Id;
3113 Source_Receiver : Entity_Id;
3114 Source_Address : Entity_Id;
3115 Local_Stub : Entity_Id;
3116 Stubbed_Result : Entity_Id;
3118 -- Start of processing for Add_RACW_Read_Attribute
3120 begin
3121 Build_Stream_Procedure
3122 (RACW_Type, Body_Node, Pnam, Statements, Outp => True);
3123 Proc_Decl := Make_Subprogram_Declaration (Loc,
3124 Copy_Specification (Loc, Specification (Body_Node)));
3126 Attr_Decl :=
3127 Make_Attribute_Definition_Clause (Loc,
3128 Name => New_Occurrence_Of (RACW_Type, Loc),
3129 Chars => Name_Read,
3130 Expression =>
3131 New_Occurrence_Of (
3132 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
3134 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
3135 Insert_After (Proc_Decl, Attr_Decl);
3137 if No (Body_Decls) then
3139 -- Case of processing an RACW type from another unit than the
3140 -- main one: do not generate a body.
3142 return;
3143 end if;
3145 -- Prepare local identifiers
3147 Source_Partition := Make_Temporary (Loc, 'P');
3148 Source_Receiver := Make_Temporary (Loc, 'S');
3149 Source_Address := Make_Temporary (Loc, 'P');
3150 Local_Stub := Make_Temporary (Loc, 'L');
3151 Stubbed_Result := Make_Temporary (Loc, 'S');
3153 -- Generate object declarations
3155 Decls := New_List (
3156 Make_Object_Declaration (Loc,
3157 Defining_Identifier => Source_Partition,
3158 Object_Definition =>
3159 New_Occurrence_Of (RTE (RE_Partition_ID), Loc)),
3161 Make_Object_Declaration (Loc,
3162 Defining_Identifier => Source_Receiver,
3163 Object_Definition =>
3164 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
3166 Make_Object_Declaration (Loc,
3167 Defining_Identifier => Source_Address,
3168 Object_Definition =>
3169 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
3171 Make_Object_Declaration (Loc,
3172 Defining_Identifier => Local_Stub,
3173 Aliased_Present => True,
3174 Object_Definition => New_Occurrence_Of (Stub_Type, Loc)),
3176 Make_Object_Declaration (Loc,
3177 Defining_Identifier => Stubbed_Result,
3178 Object_Definition =>
3179 New_Occurrence_Of (Stub_Type_Access, Loc),
3180 Expression =>
3181 Make_Attribute_Reference (Loc,
3182 Prefix =>
3183 New_Occurrence_Of (Local_Stub, Loc),
3184 Attribute_Name =>
3185 Name_Unchecked_Access)));
3187 -- Read the source Partition_ID and RPC_Receiver from incoming stream
3189 Append_List_To (Statements, New_List (
3190 Make_Attribute_Reference (Loc,
3191 Prefix =>
3192 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
3193 Attribute_Name => Name_Read,
3194 Expressions => New_List (
3195 Stream_Parameter,
3196 New_Occurrence_Of (Source_Partition, Loc))),
3198 Make_Attribute_Reference (Loc,
3199 Prefix =>
3200 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
3201 Attribute_Name =>
3202 Name_Read,
3203 Expressions => New_List (
3204 Stream_Parameter,
3205 New_Occurrence_Of (Source_Receiver, Loc))),
3207 Make_Attribute_Reference (Loc,
3208 Prefix =>
3209 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
3210 Attribute_Name =>
3211 Name_Read,
3212 Expressions => New_List (
3213 Stream_Parameter,
3214 New_Occurrence_Of (Source_Address, Loc)))));
3216 -- Build_Get_Unique_RP_Call needs the type of Stubbed_Result
3218 Set_Etype (Stubbed_Result, Stub_Type_Access);
3220 -- If the Address is Null_Address, then return a null object, unless
3221 -- RACW_Type is null-excluding, in which case unconditionally raise
3222 -- CONSTRAINT_ERROR instead.
3224 declare
3225 Zero_Statements : List_Id;
3226 -- Statements executed when a zero value is received
3228 begin
3229 if Can_Never_Be_Null (RACW_Type) then
3230 Zero_Statements := New_List (
3231 Make_Raise_Constraint_Error (Loc,
3232 Reason => CE_Null_Not_Allowed));
3233 else
3234 Zero_Statements := New_List (
3235 Make_Assignment_Statement (Loc,
3236 Name => Result,
3237 Expression => Make_Null (Loc)),
3238 Make_Simple_Return_Statement (Loc));
3239 end if;
3241 Append_To (Statements,
3242 Make_Implicit_If_Statement (RACW_Type,
3243 Condition =>
3244 Make_Op_Eq (Loc,
3245 Left_Opnd => New_Occurrence_Of (Source_Address, Loc),
3246 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
3247 Then_Statements => Zero_Statements));
3248 end;
3250 -- If the RACW denotes an object created on the current partition,
3251 -- Local_Statements will be executed. The real object will be used.
3253 Local_Statements := New_List (
3254 Make_Assignment_Statement (Loc,
3255 Name => Result,
3256 Expression =>
3257 Unchecked_Convert_To (RACW_Type,
3258 OK_Convert_To (RTE (RE_Address),
3259 New_Occurrence_Of (Source_Address, Loc)))));
3261 -- If the object is located on another partition, then a stub object
3262 -- will be created with all the information needed to rebuild the
3263 -- real object at the other end.
3265 Remote_Statements := New_List (
3267 Make_Assignment_Statement (Loc,
3268 Name => Make_Selected_Component (Loc,
3269 Prefix => Stubbed_Result,
3270 Selector_Name => Name_Origin),
3271 Expression =>
3272 New_Occurrence_Of (Source_Partition, Loc)),
3274 Make_Assignment_Statement (Loc,
3275 Name => Make_Selected_Component (Loc,
3276 Prefix => Stubbed_Result,
3277 Selector_Name => Name_Receiver),
3278 Expression =>
3279 New_Occurrence_Of (Source_Receiver, Loc)),
3281 Make_Assignment_Statement (Loc,
3282 Name => Make_Selected_Component (Loc,
3283 Prefix => Stubbed_Result,
3284 Selector_Name => Name_Addr),
3285 Expression =>
3286 New_Occurrence_Of (Source_Address, Loc)));
3288 Append_To (Remote_Statements,
3289 Make_Assignment_Statement (Loc,
3290 Name => Make_Selected_Component (Loc,
3291 Prefix => Stubbed_Result,
3292 Selector_Name => Name_Asynchronous),
3293 Expression =>
3294 New_Occurrence_Of (Asynchronous_Flag, Loc)));
3296 Append_List_To (Remote_Statements,
3297 Build_Get_Unique_RP_Call (Loc, Stubbed_Result, Stub_Type));
3298 -- ??? Issue with asynchronous calls here: the Asynchronous flag is
3299 -- set on the stub type if, and only if, the RACW type has a pragma
3300 -- Asynchronous. This is incorrect for RACWs that implement RAS
3301 -- types, because in that case the /designated subprogram/ (not the
3302 -- type) might be asynchronous, and that causes the stub to need to
3303 -- be asynchronous too. A solution is to transport a RAS as a struct
3304 -- containing a RACW and an asynchronous flag, and to properly alter
3305 -- the Asynchronous component in the stub type in the RAS's Input
3306 -- TSS.
3308 Append_To (Remote_Statements,
3309 Make_Assignment_Statement (Loc,
3310 Name => Result,
3311 Expression => Unchecked_Convert_To (RACW_Type,
3312 New_Occurrence_Of (Stubbed_Result, Loc))));
3314 -- Distinguish between the local and remote cases, and execute the
3315 -- appropriate piece of code.
3317 Append_To (Statements,
3318 Make_Implicit_If_Statement (RACW_Type,
3319 Condition =>
3320 Make_Op_Eq (Loc,
3321 Left_Opnd =>
3322 Make_Function_Call (Loc,
3323 Name => New_Occurrence_Of (
3324 RTE (RE_Get_Local_Partition_Id), Loc)),
3325 Right_Opnd => New_Occurrence_Of (Source_Partition, Loc)),
3326 Then_Statements => Local_Statements,
3327 Else_Statements => Remote_Statements));
3329 Set_Declarations (Body_Node, Decls);
3330 Append_To (Body_Decls, Body_Node);
3331 end Add_RACW_Read_Attribute;
3333 ------------------------------
3334 -- Add_RACW_Write_Attribute --
3335 ------------------------------
3337 procedure Add_RACW_Write_Attribute
3338 (RACW_Type : Entity_Id;
3339 Stub_Type : Entity_Id;
3340 Stub_Type_Access : Entity_Id;
3341 RPC_Receiver : Node_Id;
3342 Body_Decls : List_Id)
3344 Body_Node : Node_Id;
3345 Proc_Decl : Node_Id;
3346 Attr_Decl : Node_Id;
3348 Statements : constant List_Id := New_List;
3349 Local_Statements : List_Id;
3350 Remote_Statements : List_Id;
3351 Null_Statements : List_Id;
3353 Pnam : constant Entity_Id := Make_Temporary (Loc, 'R');
3355 begin
3356 Build_Stream_Procedure
3357 (RACW_Type, Body_Node, Pnam, Statements, Outp => False);
3359 Proc_Decl := Make_Subprogram_Declaration (Loc,
3360 Copy_Specification (Loc, Specification (Body_Node)));
3362 Attr_Decl :=
3363 Make_Attribute_Definition_Clause (Loc,
3364 Name => New_Occurrence_Of (RACW_Type, Loc),
3365 Chars => Name_Write,
3366 Expression =>
3367 New_Occurrence_Of (
3368 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
3370 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
3371 Insert_After (Proc_Decl, Attr_Decl);
3373 if No (Body_Decls) then
3374 return;
3375 end if;
3377 -- Build the code fragment corresponding to the marshalling of a
3378 -- local object.
3380 Local_Statements := New_List (
3382 Pack_Entity_Into_Stream_Access (Loc,
3383 Stream => Stream_Parameter,
3384 Object => RTE (RE_Get_Local_Partition_Id)),
3386 Pack_Node_Into_Stream_Access (Loc,
3387 Stream => Stream_Parameter,
3388 Object => OK_Convert_To (RTE (RE_Unsigned_64), RPC_Receiver),
3389 Etyp => RTE (RE_Unsigned_64)),
3391 Pack_Node_Into_Stream_Access (Loc,
3392 Stream => Stream_Parameter,
3393 Object => OK_Convert_To (RTE (RE_Unsigned_64),
3394 Make_Attribute_Reference (Loc,
3395 Prefix =>
3396 Make_Explicit_Dereference (Loc,
3397 Prefix => Object),
3398 Attribute_Name => Name_Address)),
3399 Etyp => RTE (RE_Unsigned_64)));
3401 -- Build the code fragment corresponding to the marshalling of
3402 -- a remote object.
3404 Remote_Statements := New_List (
3405 Pack_Node_Into_Stream_Access (Loc,
3406 Stream => Stream_Parameter,
3407 Object =>
3408 Make_Selected_Component (Loc,
3409 Prefix =>
3410 Unchecked_Convert_To (Stub_Type_Access, Object),
3411 Selector_Name => Make_Identifier (Loc, Name_Origin)),
3412 Etyp => RTE (RE_Partition_ID)),
3414 Pack_Node_Into_Stream_Access (Loc,
3415 Stream => Stream_Parameter,
3416 Object =>
3417 Make_Selected_Component (Loc,
3418 Prefix =>
3419 Unchecked_Convert_To (Stub_Type_Access, Object),
3420 Selector_Name => Make_Identifier (Loc, Name_Receiver)),
3421 Etyp => RTE (RE_Unsigned_64)),
3423 Pack_Node_Into_Stream_Access (Loc,
3424 Stream => Stream_Parameter,
3425 Object =>
3426 Make_Selected_Component (Loc,
3427 Prefix =>
3428 Unchecked_Convert_To (Stub_Type_Access, Object),
3429 Selector_Name => Make_Identifier (Loc, Name_Addr)),
3430 Etyp => RTE (RE_Unsigned_64)));
3432 -- Build code fragment corresponding to marshalling of a null object
3434 Null_Statements := New_List (
3436 Pack_Entity_Into_Stream_Access (Loc,
3437 Stream => Stream_Parameter,
3438 Object => RTE (RE_Get_Local_Partition_Id)),
3440 Pack_Node_Into_Stream_Access (Loc,
3441 Stream => Stream_Parameter,
3442 Object => OK_Convert_To (RTE (RE_Unsigned_64), RPC_Receiver),
3443 Etyp => RTE (RE_Unsigned_64)),
3445 Pack_Node_Into_Stream_Access (Loc,
3446 Stream => Stream_Parameter,
3447 Object => Make_Integer_Literal (Loc, Uint_0),
3448 Etyp => RTE (RE_Unsigned_64)));
3450 Append_To (Statements,
3451 Make_Implicit_If_Statement (RACW_Type,
3452 Condition =>
3453 Make_Op_Eq (Loc,
3454 Left_Opnd => Object,
3455 Right_Opnd => Make_Null (Loc)),
3457 Then_Statements => Null_Statements,
3459 Elsif_Parts => New_List (
3460 Make_Elsif_Part (Loc,
3461 Condition =>
3462 Make_Op_Eq (Loc,
3463 Left_Opnd =>
3464 Make_Attribute_Reference (Loc,
3465 Prefix => Object,
3466 Attribute_Name => Name_Tag),
3468 Right_Opnd =>
3469 Make_Attribute_Reference (Loc,
3470 Prefix => New_Occurrence_Of (Stub_Type, Loc),
3471 Attribute_Name => Name_Tag)),
3472 Then_Statements => Remote_Statements)),
3473 Else_Statements => Local_Statements));
3475 Append_To (Body_Decls, Body_Node);
3476 end Add_RACW_Write_Attribute;
3478 ------------------------
3479 -- Add_RAS_Access_TSS --
3480 ------------------------
3482 procedure Add_RAS_Access_TSS (N : Node_Id) is
3483 Loc : constant Source_Ptr := Sloc (N);
3485 Ras_Type : constant Entity_Id := Defining_Identifier (N);
3486 Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
3487 -- Ras_Type is the access to subprogram type while Fat_Type is the
3488 -- corresponding record type.
3490 RACW_Type : constant Entity_Id :=
3491 Underlying_RACW_Type (Ras_Type);
3492 Desig : constant Entity_Id :=
3493 Etype (Designated_Type (RACW_Type));
3495 Stub_Elements : constant Stub_Structure :=
3496 Stubs_Table.Get (Desig);
3497 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
3499 Proc : constant Entity_Id :=
3500 Make_Defining_Identifier (Loc,
3501 Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access));
3503 Proc_Spec : Node_Id;
3505 -- Formal parameters
3507 Package_Name : constant Entity_Id :=
3508 Make_Defining_Identifier (Loc,
3509 Chars => Name_P);
3510 -- Target package
3512 Subp_Id : constant Entity_Id :=
3513 Make_Defining_Identifier (Loc,
3514 Chars => Name_S);
3515 -- Target subprogram
3517 Asynch_P : constant Entity_Id :=
3518 Make_Defining_Identifier (Loc,
3519 Chars => Name_Asynchronous);
3520 -- Is the procedure to which the 'Access applies asynchronous?
3522 All_Calls_Remote : constant Entity_Id :=
3523 Make_Defining_Identifier (Loc,
3524 Chars => Name_All_Calls_Remote);
3525 -- True if an All_Calls_Remote pragma applies to the RCI unit
3526 -- that contains the subprogram.
3528 -- Common local variables
3530 Proc_Decls : List_Id;
3531 Proc_Statements : List_Id;
3533 Origin : constant Entity_Id := Make_Temporary (Loc, 'P');
3535 -- Additional local variables for the local case
3537 Proxy_Addr : constant Entity_Id := Make_Temporary (Loc, 'P');
3539 -- Additional local variables for the remote case
3541 Local_Stub : constant Entity_Id := Make_Temporary (Loc, 'L');
3542 Stub_Ptr : constant Entity_Id := Make_Temporary (Loc, 'S');
3544 function Set_Field
3545 (Field_Name : Name_Id;
3546 Value : Node_Id) return Node_Id;
3547 -- Construct an assignment that sets the named component in the
3548 -- returned record
3550 ---------------
3551 -- Set_Field --
3552 ---------------
3554 function Set_Field
3555 (Field_Name : Name_Id;
3556 Value : Node_Id) return Node_Id
3558 begin
3559 return
3560 Make_Assignment_Statement (Loc,
3561 Name =>
3562 Make_Selected_Component (Loc,
3563 Prefix => Stub_Ptr,
3564 Selector_Name => Field_Name),
3565 Expression => Value);
3566 end Set_Field;
3568 -- Start of processing for Add_RAS_Access_TSS
3570 begin
3571 Proc_Decls := New_List (
3573 -- Common declarations
3575 Make_Object_Declaration (Loc,
3576 Defining_Identifier => Origin,
3577 Constant_Present => True,
3578 Object_Definition =>
3579 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
3580 Expression =>
3581 Make_Function_Call (Loc,
3582 Name =>
3583 New_Occurrence_Of (RTE (RE_Get_Active_Partition_Id), Loc),
3584 Parameter_Associations => New_List (
3585 New_Occurrence_Of (Package_Name, Loc)))),
3587 -- Declaration use only in the local case: proxy address
3589 Make_Object_Declaration (Loc,
3590 Defining_Identifier => Proxy_Addr,
3591 Object_Definition =>
3592 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)),
3594 -- Declarations used only in the remote case: stub object and
3595 -- stub pointer.
3597 Make_Object_Declaration (Loc,
3598 Defining_Identifier => Local_Stub,
3599 Aliased_Present => True,
3600 Object_Definition =>
3601 New_Occurrence_Of (Stub_Elements.Stub_Type, Loc)),
3603 Make_Object_Declaration (Loc,
3604 Defining_Identifier =>
3605 Stub_Ptr,
3606 Object_Definition =>
3607 New_Occurrence_Of (Stub_Elements.Stub_Type_Access, Loc),
3608 Expression =>
3609 Make_Attribute_Reference (Loc,
3610 Prefix => New_Occurrence_Of (Local_Stub, Loc),
3611 Attribute_Name => Name_Unchecked_Access)));
3613 Set_Etype (Stub_Ptr, Stub_Elements.Stub_Type_Access);
3615 -- Build_Get_Unique_RP_Call needs above information
3617 -- Note: Here we assume that the Fat_Type is a record
3618 -- containing just a pointer to a proxy or stub object.
3620 Proc_Statements := New_List (
3622 -- Generate:
3624 -- Get_RAS_Info (Pkg, Subp, PA);
3625 -- if Origin = Local_Partition_Id
3626 -- and then not All_Calls_Remote
3627 -- then
3628 -- return Fat_Type!(PA);
3629 -- end if;
3631 Make_Procedure_Call_Statement (Loc,
3632 Name => New_Occurrence_Of (RTE (RE_Get_RAS_Info), Loc),
3633 Parameter_Associations => New_List (
3634 New_Occurrence_Of (Package_Name, Loc),
3635 New_Occurrence_Of (Subp_Id, Loc),
3636 New_Occurrence_Of (Proxy_Addr, Loc))),
3638 Make_Implicit_If_Statement (N,
3639 Condition =>
3640 Make_And_Then (Loc,
3641 Left_Opnd =>
3642 Make_Op_Eq (Loc,
3643 Left_Opnd =>
3644 New_Occurrence_Of (Origin, Loc),
3645 Right_Opnd =>
3646 Make_Function_Call (Loc,
3647 New_Occurrence_Of (
3648 RTE (RE_Get_Local_Partition_Id), Loc))),
3650 Right_Opnd =>
3651 Make_Op_Not (Loc,
3652 New_Occurrence_Of (All_Calls_Remote, Loc))),
3654 Then_Statements => New_List (
3655 Make_Simple_Return_Statement (Loc,
3656 Unchecked_Convert_To (Fat_Type,
3657 OK_Convert_To (RTE (RE_Address),
3658 New_Occurrence_Of (Proxy_Addr, Loc)))))),
3660 Set_Field (Name_Origin,
3661 New_Occurrence_Of (Origin, Loc)),
3663 Set_Field (Name_Receiver,
3664 Make_Function_Call (Loc,
3665 Name =>
3666 New_Occurrence_Of (RTE (RE_Get_RCI_Package_Receiver), Loc),
3667 Parameter_Associations => New_List (
3668 New_Occurrence_Of (Package_Name, Loc)))),
3670 Set_Field (Name_Addr, New_Occurrence_Of (Proxy_Addr, Loc)),
3672 -- E.4.1(9) A remote call is asynchronous if it is a call to
3673 -- a procedure or a call through a value of an access-to-procedure
3674 -- type to which a pragma Asynchronous applies.
3676 -- Asynch_P is true when the procedure is asynchronous;
3677 -- Asynch_T is true when the type is asynchronous.
3679 Set_Field (Name_Asynchronous,
3680 Make_Or_Else (Loc,
3681 New_Occurrence_Of (Asynch_P, Loc),
3682 New_Occurrence_Of (Boolean_Literals (
3683 Is_Asynchronous (Ras_Type)), Loc))));
3685 Append_List_To (Proc_Statements,
3686 Build_Get_Unique_RP_Call
3687 (Loc, Stub_Ptr, Stub_Elements.Stub_Type));
3689 -- Return the newly created value
3691 Append_To (Proc_Statements,
3692 Make_Simple_Return_Statement (Loc,
3693 Expression =>
3694 Unchecked_Convert_To (Fat_Type,
3695 New_Occurrence_Of (Stub_Ptr, Loc))));
3697 Proc_Spec :=
3698 Make_Function_Specification (Loc,
3699 Defining_Unit_Name => Proc,
3700 Parameter_Specifications => New_List (
3701 Make_Parameter_Specification (Loc,
3702 Defining_Identifier => Package_Name,
3703 Parameter_Type =>
3704 New_Occurrence_Of (Standard_String, Loc)),
3706 Make_Parameter_Specification (Loc,
3707 Defining_Identifier => Subp_Id,
3708 Parameter_Type =>
3709 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc)),
3711 Make_Parameter_Specification (Loc,
3712 Defining_Identifier => Asynch_P,
3713 Parameter_Type =>
3714 New_Occurrence_Of (Standard_Boolean, Loc)),
3716 Make_Parameter_Specification (Loc,
3717 Defining_Identifier => All_Calls_Remote,
3718 Parameter_Type =>
3719 New_Occurrence_Of (Standard_Boolean, Loc))),
3721 Result_Definition =>
3722 New_Occurrence_Of (Fat_Type, Loc));
3724 -- Set the kind and return type of the function to prevent
3725 -- ambiguities between Ras_Type and Fat_Type in subsequent analysis.
3727 Mutate_Ekind (Proc, E_Function);
3728 Set_Etype (Proc, Fat_Type);
3730 Discard_Node (
3731 Make_Subprogram_Body (Loc,
3732 Specification => Proc_Spec,
3733 Declarations => Proc_Decls,
3734 Handled_Statement_Sequence =>
3735 Make_Handled_Sequence_Of_Statements (Loc,
3736 Statements => Proc_Statements)));
3738 Set_TSS (Fat_Type, Proc);
3739 end Add_RAS_Access_TSS;
3741 -----------------------
3742 -- Add_RAST_Features --
3743 -----------------------
3745 procedure Add_RAST_Features
3746 (Vis_Decl : Node_Id;
3747 RAS_Type : Entity_Id)
3749 pragma Unreferenced (RAS_Type);
3750 begin
3751 Add_RAS_Access_TSS (Vis_Decl);
3752 end Add_RAST_Features;
3754 -----------------------------------------
3755 -- Add_Receiving_Stubs_To_Declarations --
3756 -----------------------------------------
3758 procedure Add_Receiving_Stubs_To_Declarations
3759 (Pkg_Spec : Node_Id;
3760 Decls : List_Id;
3761 Stmts : List_Id)
3763 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
3765 Request_Parameter : Node_Id;
3767 Pkg_RPC_Receiver : constant Entity_Id :=
3768 Make_Temporary (Loc, 'H');
3769 Pkg_RPC_Receiver_Statements : List_Id;
3770 Pkg_RPC_Receiver_Cases : constant List_Id := New_List;
3771 Pkg_RPC_Receiver_Body : Node_Id;
3772 -- A Pkg_RPC_Receiver is built to decode the request
3774 Lookup_RAS : Node_Id;
3775 Lookup_RAS_Info : constant Entity_Id := Make_Temporary (Loc, 'R');
3776 -- A remote subprogram is created to allow peers to look up RAS
3777 -- information using subprogram ids.
3779 Subp_Id : Entity_Id;
3780 Subp_Index : Entity_Id;
3781 -- Subprogram_Id as read from the incoming stream
3783 Current_Subp_Number : Int := First_RCI_Subprogram_Id;
3784 Current_Stubs : Node_Id;
3786 Subp_Info_Array : constant Entity_Id := Make_Temporary (Loc, 'I');
3787 Subp_Info_List : constant List_Id := New_List;
3789 Register_Pkg_Actuals : constant List_Id := New_List;
3791 All_Calls_Remote_E : Entity_Id;
3792 Proxy_Object_Addr : Entity_Id;
3794 procedure Append_Stubs_To
3795 (RPC_Receiver_Cases : List_Id;
3796 Stubs : Node_Id;
3797 Subprogram_Number : Int);
3798 -- Add one case to the specified RPC receiver case list
3799 -- associating Subprogram_Number with the subprogram declared
3800 -- by Declaration, for which we have receiving stubs in Stubs.
3802 procedure Visit_Subprogram (Decl : Node_Id);
3803 -- Generate receiving stub for one remote subprogram
3805 ---------------------
3806 -- Append_Stubs_To --
3807 ---------------------
3809 procedure Append_Stubs_To
3810 (RPC_Receiver_Cases : List_Id;
3811 Stubs : Node_Id;
3812 Subprogram_Number : Int)
3814 begin
3815 Append_To (RPC_Receiver_Cases,
3816 Make_Case_Statement_Alternative (Loc,
3817 Discrete_Choices =>
3818 New_List (Make_Integer_Literal (Loc, Subprogram_Number)),
3819 Statements =>
3820 New_List (
3821 Make_Procedure_Call_Statement (Loc,
3822 Name =>
3823 New_Occurrence_Of (Defining_Entity (Stubs), Loc),
3824 Parameter_Associations => New_List (
3825 New_Occurrence_Of (Request_Parameter, Loc))))));
3826 end Append_Stubs_To;
3828 ----------------------
3829 -- Visit_Subprogram --
3830 ----------------------
3832 procedure Visit_Subprogram (Decl : Node_Id) is
3833 Loc : constant Source_Ptr := Sloc (Decl);
3834 Spec : constant Node_Id := Specification (Decl);
3835 Subp_Def : constant Entity_Id := Defining_Unit_Name (Spec);
3837 Subp_Val : String_Id;
3838 pragma Warnings (Off, Subp_Val);
3840 begin
3841 -- Disable expansion of stubs if serious errors have been
3842 -- diagnosed, because otherwise some illegal remote subprogram
3843 -- declarations could cause cascaded errors in stubs.
3845 if Serious_Errors_Detected /= 0 then
3846 return;
3847 end if;
3849 -- Build receiving stub
3851 Current_Stubs :=
3852 Build_Subprogram_Receiving_Stubs
3853 (Vis_Decl => Decl,
3854 Asynchronous =>
3855 Nkind (Spec) = N_Procedure_Specification
3856 and then Is_Asynchronous (Subp_Def));
3858 Append_To (Decls, Current_Stubs);
3859 Analyze (Current_Stubs);
3861 -- Build RAS proxy
3863 Add_RAS_Proxy_And_Analyze (Decls,
3864 Vis_Decl => Decl,
3865 All_Calls_Remote_E => All_Calls_Remote_E,
3866 Proxy_Object_Addr => Proxy_Object_Addr);
3868 -- Compute distribution identifier
3870 Assign_Subprogram_Identifier
3871 (Subp_Def, Current_Subp_Number, Subp_Val);
3873 pragma Assert (Current_Subp_Number = Get_Subprogram_Id (Subp_Def));
3875 -- Add subprogram descriptor (RCI_Subp_Info) to the subprograms
3876 -- table for this receiver. This aggregate must be kept consistent
3877 -- with the declaration of RCI_Subp_Info in
3878 -- System.Partition_Interface.
3880 Append_To (Subp_Info_List,
3881 Make_Component_Association (Loc,
3882 Choices => New_List (
3883 Make_Integer_Literal (Loc, Current_Subp_Number)),
3885 Expression =>
3886 Make_Aggregate (Loc,
3887 Component_Associations => New_List (
3889 -- Addr =>
3891 Make_Component_Association (Loc,
3892 Choices =>
3893 New_List (Make_Identifier (Loc, Name_Addr)),
3894 Expression =>
3895 New_Occurrence_Of (Proxy_Object_Addr, Loc))))));
3897 Append_Stubs_To (Pkg_RPC_Receiver_Cases,
3898 Stubs => Current_Stubs,
3899 Subprogram_Number => Current_Subp_Number);
3901 Current_Subp_Number := Current_Subp_Number + 1;
3902 end Visit_Subprogram;
3904 procedure Visit_Spec is new Build_Package_Stubs (Visit_Subprogram);
3906 -- Start of processing for Add_Receiving_Stubs_To_Declarations
3908 begin
3909 -- Building receiving stubs consist in several operations:
3911 -- - a package RPC receiver must be built. This subprogram
3912 -- will get a Subprogram_Id from the incoming stream
3913 -- and will dispatch the call to the right subprogram;
3915 -- - a receiving stub for each subprogram visible in the package
3916 -- spec. This stub will read all the parameters from the stream,
3917 -- and put the result as well as the exception occurrence in the
3918 -- output stream;
3920 -- - a dummy package with an empty spec and a body made of an
3921 -- elaboration part, whose job is to register the receiving
3922 -- part of this RCI package on the name server. This is done
3923 -- by calling System.Partition_Interface.Register_Receiving_Stub.
3925 Build_RPC_Receiver_Body (
3926 RPC_Receiver => Pkg_RPC_Receiver,
3927 Request => Request_Parameter,
3928 Subp_Id => Subp_Id,
3929 Subp_Index => Subp_Index,
3930 Stmts => Pkg_RPC_Receiver_Statements,
3931 Decl => Pkg_RPC_Receiver_Body);
3932 pragma Assert (Subp_Id = Subp_Index);
3934 -- A null subp_id denotes a call through a RAS, in which case the
3935 -- next Uint_64 element in the stream is the address of the local
3936 -- proxy object, from which we can retrieve the actual subprogram id.
3938 Append_To (Pkg_RPC_Receiver_Statements,
3939 Make_Implicit_If_Statement (Pkg_Spec,
3940 Condition =>
3941 Make_Op_Eq (Loc,
3942 New_Occurrence_Of (Subp_Id, Loc),
3943 Make_Integer_Literal (Loc, 0)),
3945 Then_Statements => New_List (
3946 Make_Assignment_Statement (Loc,
3947 Name =>
3948 New_Occurrence_Of (Subp_Id, Loc),
3950 Expression =>
3951 Make_Selected_Component (Loc,
3952 Prefix =>
3953 Unchecked_Convert_To (RTE (RE_RAS_Proxy_Type_Access),
3954 OK_Convert_To (RTE (RE_Address),
3955 Make_Attribute_Reference (Loc,
3956 Prefix =>
3957 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
3958 Attribute_Name =>
3959 Name_Input,
3960 Expressions => New_List (
3961 Make_Selected_Component (Loc,
3962 Prefix => Request_Parameter,
3963 Selector_Name => Name_Params))))),
3965 Selector_Name => Make_Identifier (Loc, Name_Subp_Id))))));
3967 -- Build a subprogram for RAS information lookups
3969 Lookup_RAS :=
3970 Make_Subprogram_Declaration (Loc,
3971 Specification =>
3972 Make_Function_Specification (Loc,
3973 Defining_Unit_Name =>
3974 Lookup_RAS_Info,
3975 Parameter_Specifications => New_List (
3976 Make_Parameter_Specification (Loc,
3977 Defining_Identifier =>
3978 Make_Defining_Identifier (Loc, Name_Subp_Id),
3979 In_Present =>
3980 True,
3981 Parameter_Type =>
3982 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc))),
3983 Result_Definition =>
3984 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc)));
3985 Append_To (Decls, Lookup_RAS);
3986 Analyze (Lookup_RAS);
3988 Current_Stubs := Build_Subprogram_Receiving_Stubs
3989 (Vis_Decl => Lookup_RAS,
3990 Asynchronous => False);
3991 Append_To (Decls, Current_Stubs);
3992 Analyze (Current_Stubs);
3994 Append_Stubs_To (Pkg_RPC_Receiver_Cases,
3995 Stubs => Current_Stubs,
3996 Subprogram_Number => 1);
3998 -- For each subprogram, the receiving stub will be built and a
3999 -- case statement will be made on the Subprogram_Id to dispatch
4000 -- to the right subprogram.
4002 All_Calls_Remote_E :=
4003 Boolean_Literals
4004 (Has_All_Calls_Remote (Defining_Entity (Pkg_Spec)));
4006 Overload_Counter_Table.Reset;
4008 Visit_Spec (Pkg_Spec);
4010 -- If we receive an invalid Subprogram_Id, it is best to do nothing
4011 -- rather than raising an exception since we do not want someone
4012 -- to crash a remote partition by sending invalid subprogram ids.
4013 -- This is consistent with the other parts of the case statement
4014 -- since even in presence of incorrect parameters in the stream,
4015 -- every exception will be caught and (if the subprogram is not an
4016 -- APC) put into the result stream and sent away.
4018 Append_To (Pkg_RPC_Receiver_Cases,
4019 Make_Case_Statement_Alternative (Loc,
4020 Discrete_Choices => New_List (Make_Others_Choice (Loc)),
4021 Statements => New_List (Make_Null_Statement (Loc))));
4023 Append_To (Pkg_RPC_Receiver_Statements,
4024 Make_Case_Statement (Loc,
4025 Expression => New_Occurrence_Of (Subp_Id, Loc),
4026 Alternatives => Pkg_RPC_Receiver_Cases));
4028 Append_To (Decls,
4029 Make_Object_Declaration (Loc,
4030 Defining_Identifier => Subp_Info_Array,
4031 Constant_Present => True,
4032 Aliased_Present => True,
4033 Object_Definition =>
4034 Make_Subtype_Indication (Loc,
4035 Subtype_Mark =>
4036 New_Occurrence_Of (RTE (RE_RCI_Subp_Info_Array), Loc),
4037 Constraint =>
4038 Make_Index_Or_Discriminant_Constraint (Loc,
4039 New_List (
4040 Make_Range (Loc,
4041 Low_Bound => Make_Integer_Literal (Loc,
4042 First_RCI_Subprogram_Id),
4043 High_Bound =>
4044 Make_Integer_Literal (Loc,
4045 Intval =>
4046 First_RCI_Subprogram_Id
4047 + List_Length (Subp_Info_List) - 1)))))));
4049 -- For a degenerate RCI with no visible subprograms, Subp_Info_List
4050 -- has zero length, and the declaration is for an empty array, in
4051 -- which case no initialization aggregate must be generated.
4053 if Present (First (Subp_Info_List)) then
4054 Set_Expression (Last (Decls),
4055 Make_Aggregate (Loc,
4056 Component_Associations => Subp_Info_List));
4058 -- No initialization provided: remove CONSTANT so that the
4059 -- declaration is not an incomplete deferred constant.
4061 else
4062 Set_Constant_Present (Last (Decls), False);
4063 end if;
4065 Analyze (Last (Decls));
4067 declare
4068 Subp_Info_Addr : Node_Id;
4069 -- Return statement for Lookup_RAS_Info: address of the subprogram
4070 -- information record for the requested subprogram id.
4072 begin
4073 if Present (First (Subp_Info_List)) then
4074 Subp_Info_Addr :=
4075 Make_Selected_Component (Loc,
4076 Prefix =>
4077 Make_Indexed_Component (Loc,
4078 Prefix => New_Occurrence_Of (Subp_Info_Array, Loc),
4079 Expressions => New_List (
4080 Convert_To (Standard_Integer,
4081 Make_Identifier (Loc, Name_Subp_Id)))),
4082 Selector_Name => Make_Identifier (Loc, Name_Addr));
4084 -- Case of no visible subprogram: just raise Constraint_Error, we
4085 -- know for sure we got junk from a remote partition.
4087 else
4088 Subp_Info_Addr :=
4089 Make_Raise_Constraint_Error (Loc,
4090 Reason => CE_Range_Check_Failed);
4091 Set_Etype (Subp_Info_Addr, RTE (RE_Unsigned_64));
4092 end if;
4094 Append_To (Decls,
4095 Make_Subprogram_Body (Loc,
4096 Specification =>
4097 Copy_Specification (Loc, Parent (Lookup_RAS_Info)),
4098 Declarations => No_List,
4099 Handled_Statement_Sequence =>
4100 Make_Handled_Sequence_Of_Statements (Loc,
4101 Statements => New_List (
4102 Make_Simple_Return_Statement (Loc,
4103 Expression =>
4104 OK_Convert_To
4105 (RTE (RE_Unsigned_64), Subp_Info_Addr))))));
4106 end;
4108 Analyze (Last (Decls));
4110 Append_To (Decls, Pkg_RPC_Receiver_Body);
4111 Analyze (Last (Decls));
4113 -- Name
4115 Append_To (Register_Pkg_Actuals,
4116 Make_String_Literal (Loc,
4117 Strval =>
4118 Fully_Qualified_Name_String
4119 (Defining_Entity (Pkg_Spec), Append_NUL => False)));
4121 -- Receiver
4123 Append_To (Register_Pkg_Actuals,
4124 Make_Attribute_Reference (Loc,
4125 Prefix => New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
4126 Attribute_Name => Name_Unrestricted_Access));
4128 -- Version
4130 Append_To (Register_Pkg_Actuals,
4131 Make_Attribute_Reference (Loc,
4132 Prefix =>
4133 New_Occurrence_Of (Defining_Entity (Pkg_Spec), Loc),
4134 Attribute_Name => Name_Version));
4136 -- Subp_Info
4138 Append_To (Register_Pkg_Actuals,
4139 Make_Attribute_Reference (Loc,
4140 Prefix => New_Occurrence_Of (Subp_Info_Array, Loc),
4141 Attribute_Name => Name_Address));
4143 -- Subp_Info_Len
4145 Append_To (Register_Pkg_Actuals,
4146 Make_Attribute_Reference (Loc,
4147 Prefix => New_Occurrence_Of (Subp_Info_Array, Loc),
4148 Attribute_Name => Name_Length));
4150 -- Generate the call
4152 Append_To (Stmts,
4153 Make_Procedure_Call_Statement (Loc,
4154 Name =>
4155 New_Occurrence_Of (RTE (RE_Register_Receiving_Stub), Loc),
4156 Parameter_Associations => Register_Pkg_Actuals));
4157 Analyze (Last (Stmts));
4158 end Add_Receiving_Stubs_To_Declarations;
4160 ---------------------------------
4161 -- Build_General_Calling_Stubs --
4162 ---------------------------------
4164 procedure Build_General_Calling_Stubs
4165 (Decls : List_Id;
4166 Statements : List_Id;
4167 Target_Partition : Entity_Id;
4168 Target_RPC_Receiver : Node_Id;
4169 Subprogram_Id : Node_Id;
4170 Asynchronous : Node_Id := Empty;
4171 Is_Known_Asynchronous : Boolean := False;
4172 Is_Known_Non_Asynchronous : Boolean := False;
4173 Is_Function : Boolean;
4174 Spec : Node_Id;
4175 Stub_Type : Entity_Id := Empty;
4176 RACW_Type : Entity_Id := Empty;
4177 Nod : Node_Id)
4179 Loc : constant Source_Ptr := Sloc (Nod);
4181 Stream_Parameter : Node_Id;
4182 -- Name of the stream used to transmit parameters to the remote
4183 -- package.
4185 Result_Parameter : Node_Id;
4186 -- Name of the result parameter (in non-APC cases) which get the
4187 -- result of the remote subprogram.
4189 Exception_Return_Parameter : Node_Id;
4190 -- Name of the parameter which will hold the exception sent by the
4191 -- remote subprogram.
4193 Current_Parameter : Node_Id;
4194 -- Current parameter being handled
4196 Ordered_Parameters_List : constant List_Id :=
4197 Build_Ordered_Parameters_List (Spec);
4199 Asynchronous_Statements : List_Id := No_List;
4200 Non_Asynchronous_Statements : List_Id := No_List;
4201 -- Statements specifics to the Asynchronous/Non-Asynchronous cases
4203 Extra_Formal_Statements : constant List_Id := New_List;
4204 -- List of statements for extra formal parameters. It will appear
4205 -- after the regular statements for writing out parameters.
4207 pragma Unreferenced (RACW_Type);
4208 -- Used only for the PolyORB case
4210 begin
4211 -- The general form of a calling stub for a given subprogram is:
4213 -- procedure X (...) is P : constant Partition_ID :=
4214 -- RCI_Cache.Get_Active_Partition_ID; Stream, Result : aliased
4215 -- System.RPC.Params_Stream_Type (0); begin
4216 -- Put_Package_RPC_Receiver_In_Stream; (the package RPC receiver
4217 -- comes from RCI_Cache.Get_RCI_Package_Receiver)
4218 -- Put_Subprogram_Id_In_Stream; Put_Parameters_In_Stream; Do_RPC
4219 -- (Stream, Result); Read_Exception_Occurrence_From_Result;
4220 -- Raise_It;
4221 -- Read_Out_Parameters_And_Function_Return_From_Stream; end X;
4223 -- There are some variations: Do_APC is called for an asynchronous
4224 -- procedure and the part after the call is completely ommitted as
4225 -- well as the declaration of Result. For a function call, 'Input is
4226 -- always used to read the result even if it is constrained.
4228 Stream_Parameter := Make_Temporary (Loc, 'S');
4230 Append_To (Decls,
4231 Make_Object_Declaration (Loc,
4232 Defining_Identifier => Stream_Parameter,
4233 Aliased_Present => True,
4234 Object_Definition =>
4235 Make_Subtype_Indication (Loc,
4236 Subtype_Mark =>
4237 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
4238 Constraint =>
4239 Make_Index_Or_Discriminant_Constraint (Loc,
4240 Constraints =>
4241 New_List (Make_Integer_Literal (Loc, 0))))));
4243 if not Is_Known_Asynchronous then
4244 Result_Parameter := Make_Temporary (Loc, 'R');
4246 Append_To (Decls,
4247 Make_Object_Declaration (Loc,
4248 Defining_Identifier => Result_Parameter,
4249 Aliased_Present => True,
4250 Object_Definition =>
4251 Make_Subtype_Indication (Loc,
4252 Subtype_Mark =>
4253 New_Occurrence_Of (RTE (RE_Params_Stream_Type), Loc),
4254 Constraint =>
4255 Make_Index_Or_Discriminant_Constraint (Loc,
4256 Constraints =>
4257 New_List (Make_Integer_Literal (Loc, 0))))));
4259 Exception_Return_Parameter := Make_Temporary (Loc, 'E');
4261 Append_To (Decls,
4262 Make_Object_Declaration (Loc,
4263 Defining_Identifier => Exception_Return_Parameter,
4264 Object_Definition =>
4265 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc)));
4267 else
4268 Result_Parameter := Empty;
4269 Exception_Return_Parameter := Empty;
4270 end if;
4272 -- Put first the RPC receiver corresponding to the remote package
4274 Append_To (Statements,
4275 Make_Attribute_Reference (Loc,
4276 Prefix =>
4277 New_Occurrence_Of (RTE (RE_Unsigned_64), Loc),
4278 Attribute_Name => Name_Write,
4279 Expressions => New_List (
4280 Make_Attribute_Reference (Loc,
4281 Prefix => New_Occurrence_Of (Stream_Parameter, Loc),
4282 Attribute_Name => Name_Access),
4283 Target_RPC_Receiver)));
4285 -- Then put the Subprogram_Id of the subprogram we want to call in
4286 -- the stream.
4288 Append_To (Statements,
4289 Make_Attribute_Reference (Loc,
4290 Prefix => New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
4291 Attribute_Name => Name_Write,
4292 Expressions => New_List (
4293 Make_Attribute_Reference (Loc,
4294 Prefix => New_Occurrence_Of (Stream_Parameter, Loc),
4295 Attribute_Name => Name_Access),
4296 Subprogram_Id)));
4298 Current_Parameter := First (Ordered_Parameters_List);
4299 while Present (Current_Parameter) loop
4300 declare
4301 Typ : constant Node_Id :=
4302 Parameter_Type (Current_Parameter);
4303 Etyp : Entity_Id;
4304 Constrained : Boolean;
4305 Value : Node_Id;
4306 Extra_Parameter : Entity_Id;
4308 begin
4309 if Is_RACW_Controlling_Formal
4310 (Current_Parameter, Stub_Type)
4311 then
4312 -- In the case of a controlling formal argument, we marshall
4313 -- its addr field rather than the local stub.
4315 Append_To (Statements,
4316 Pack_Node_Into_Stream (Loc,
4317 Stream => Stream_Parameter,
4318 Object =>
4319 Make_Selected_Component (Loc,
4320 Prefix =>
4321 Defining_Identifier (Current_Parameter),
4322 Selector_Name => Name_Addr),
4323 Etyp => RTE (RE_Unsigned_64)));
4325 else
4326 Value :=
4327 New_Occurrence_Of
4328 (Defining_Identifier (Current_Parameter), Loc);
4330 -- Access type parameters are transmitted as in out
4331 -- parameters. However, a dereference is needed so that
4332 -- we marshall the designated object.
4334 if Nkind (Typ) = N_Access_Definition then
4335 Value := Make_Explicit_Dereference (Loc, Value);
4336 Etyp := Etype (Subtype_Mark (Typ));
4337 else
4338 Etyp := Etype (Typ);
4339 end if;
4341 Constrained := not Transmit_As_Unconstrained (Etyp);
4343 -- Any parameter but unconstrained out parameters are
4344 -- transmitted to the peer.
4346 if In_Present (Current_Parameter)
4347 or else not Out_Present (Current_Parameter)
4348 or else not Constrained
4349 then
4350 Append_To (Statements,
4351 Make_Attribute_Reference (Loc,
4352 Prefix => New_Occurrence_Of (Etyp, Loc),
4353 Attribute_Name =>
4354 Output_From_Constrained (Constrained),
4355 Expressions => New_List (
4356 Make_Attribute_Reference (Loc,
4357 Prefix =>
4358 New_Occurrence_Of (Stream_Parameter, Loc),
4359 Attribute_Name => Name_Access),
4360 Value)));
4361 end if;
4362 end if;
4364 -- If the current parameter has a dynamic constrained status,
4365 -- then this status is transmitted as well.
4366 -- This should be done for accessibility as well ???
4368 if Nkind (Typ) /= N_Access_Definition
4369 and then Need_Extra_Constrained (Current_Parameter)
4370 then
4371 -- In this block, we do not use the extra formal that has
4372 -- been created because it does not exist at the time of
4373 -- expansion when building calling stubs for remote access
4374 -- to subprogram types. We create an extra variable of this
4375 -- type and push it in the stream after the regular
4376 -- parameters.
4378 Extra_Parameter := Make_Temporary (Loc, 'P');
4380 Append_To (Decls,
4381 Make_Object_Declaration (Loc,
4382 Defining_Identifier => Extra_Parameter,
4383 Constant_Present => True,
4384 Object_Definition =>
4385 New_Occurrence_Of (Standard_Boolean, Loc),
4386 Expression =>
4387 Make_Attribute_Reference (Loc,
4388 Prefix =>
4389 New_Occurrence_Of (
4390 Defining_Identifier (Current_Parameter), Loc),
4391 Attribute_Name => Name_Constrained)));
4393 Append_To (Extra_Formal_Statements,
4394 Make_Attribute_Reference (Loc,
4395 Prefix =>
4396 New_Occurrence_Of (Standard_Boolean, Loc),
4397 Attribute_Name => Name_Write,
4398 Expressions => New_List (
4399 Make_Attribute_Reference (Loc,
4400 Prefix =>
4401 New_Occurrence_Of
4402 (Stream_Parameter, Loc), Attribute_Name =>
4403 Name_Access),
4404 New_Occurrence_Of (Extra_Parameter, Loc))));
4405 end if;
4407 Next (Current_Parameter);
4408 end;
4409 end loop;
4411 -- Append the formal statements list to the statements
4413 Append_List_To (Statements, Extra_Formal_Statements);
4415 if not Is_Known_Non_Asynchronous then
4417 -- Build the call to System.RPC.Do_APC
4419 Asynchronous_Statements := New_List (
4420 Make_Procedure_Call_Statement (Loc,
4421 Name =>
4422 New_Occurrence_Of (RTE (RE_Do_Apc), Loc),
4423 Parameter_Associations => New_List (
4424 New_Occurrence_Of (Target_Partition, Loc),
4425 Make_Attribute_Reference (Loc,
4426 Prefix =>
4427 New_Occurrence_Of (Stream_Parameter, Loc),
4428 Attribute_Name => Name_Access))));
4429 else
4430 Asynchronous_Statements := No_List;
4431 end if;
4433 if not Is_Known_Asynchronous then
4435 -- Build the call to System.RPC.Do_RPC
4437 Non_Asynchronous_Statements := New_List (
4438 Make_Procedure_Call_Statement (Loc,
4439 Name =>
4440 New_Occurrence_Of (RTE (RE_Do_Rpc), Loc),
4441 Parameter_Associations => New_List (
4442 New_Occurrence_Of (Target_Partition, Loc),
4444 Make_Attribute_Reference (Loc,
4445 Prefix =>
4446 New_Occurrence_Of (Stream_Parameter, Loc),
4447 Attribute_Name => Name_Access),
4449 Make_Attribute_Reference (Loc,
4450 Prefix =>
4451 New_Occurrence_Of (Result_Parameter, Loc),
4452 Attribute_Name => Name_Access))));
4454 -- Read the exception occurrence from the result stream and
4455 -- reraise it. It does no harm if this is a Null_Occurrence since
4456 -- this does nothing.
4458 Append_To (Non_Asynchronous_Statements,
4459 Make_Attribute_Reference (Loc,
4460 Prefix =>
4461 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
4463 Attribute_Name => Name_Read,
4465 Expressions => New_List (
4466 Make_Attribute_Reference (Loc,
4467 Prefix =>
4468 New_Occurrence_Of (Result_Parameter, Loc),
4469 Attribute_Name => Name_Access),
4470 New_Occurrence_Of (Exception_Return_Parameter, Loc))));
4472 Append_To (Non_Asynchronous_Statements,
4473 Make_Procedure_Call_Statement (Loc,
4474 Name =>
4475 New_Occurrence_Of (RTE (RE_Reraise_Occurrence), Loc),
4476 Parameter_Associations => New_List (
4477 New_Occurrence_Of (Exception_Return_Parameter, Loc))));
4479 if Is_Function then
4481 -- If this is a function call, then read the value and return
4482 -- it. The return value is written/read using 'Output/'Input.
4484 Append_To (Non_Asynchronous_Statements,
4485 Make_Tag_Check (Loc,
4486 Make_Simple_Return_Statement (Loc,
4487 Expression =>
4488 Make_Attribute_Reference (Loc,
4489 Prefix =>
4490 New_Occurrence_Of (
4491 Etype (Result_Definition (Spec)), Loc),
4493 Attribute_Name => Name_Input,
4495 Expressions => New_List (
4496 Make_Attribute_Reference (Loc,
4497 Prefix =>
4498 New_Occurrence_Of (Result_Parameter, Loc),
4499 Attribute_Name => Name_Access))))));
4501 else
4502 -- Loop around parameters and assign out (or in out)
4503 -- parameters. In the case of RACW, controlling arguments
4504 -- cannot possibly have changed since they are remote, so
4505 -- we do not read them from the stream.
4507 Current_Parameter := First (Ordered_Parameters_List);
4508 while Present (Current_Parameter) loop
4509 declare
4510 Typ : constant Node_Id :=
4511 Parameter_Type (Current_Parameter);
4512 Etyp : Entity_Id;
4513 Value : Node_Id;
4515 begin
4516 Value :=
4517 New_Occurrence_Of
4518 (Defining_Identifier (Current_Parameter), Loc);
4520 if Nkind (Typ) = N_Access_Definition then
4521 Value := Make_Explicit_Dereference (Loc, Value);
4522 Etyp := Etype (Subtype_Mark (Typ));
4523 else
4524 Etyp := Etype (Typ);
4525 end if;
4527 if (Out_Present (Current_Parameter)
4528 or else Nkind (Typ) = N_Access_Definition)
4529 and then Etyp /= Stub_Type
4530 then
4531 Append_To (Non_Asynchronous_Statements,
4532 Make_Attribute_Reference (Loc,
4533 Prefix =>
4534 New_Occurrence_Of (Etyp, Loc),
4536 Attribute_Name => Name_Read,
4538 Expressions => New_List (
4539 Make_Attribute_Reference (Loc,
4540 Prefix =>
4541 New_Occurrence_Of (Result_Parameter, Loc),
4542 Attribute_Name => Name_Access),
4543 Value)));
4544 end if;
4545 end;
4547 Next (Current_Parameter);
4548 end loop;
4549 end if;
4550 end if;
4552 if Is_Known_Asynchronous then
4553 Append_List_To (Statements, Asynchronous_Statements);
4555 elsif Is_Known_Non_Asynchronous then
4556 Append_List_To (Statements, Non_Asynchronous_Statements);
4558 else
4559 pragma Assert (Present (Asynchronous));
4560 Prepend_To (Asynchronous_Statements,
4561 Make_Attribute_Reference (Loc,
4562 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
4563 Attribute_Name => Name_Write,
4564 Expressions => New_List (
4565 Make_Attribute_Reference (Loc,
4566 Prefix =>
4567 New_Occurrence_Of (Stream_Parameter, Loc),
4568 Attribute_Name => Name_Access),
4569 New_Occurrence_Of (Standard_True, Loc))));
4571 Prepend_To (Non_Asynchronous_Statements,
4572 Make_Attribute_Reference (Loc,
4573 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
4574 Attribute_Name => Name_Write,
4575 Expressions => New_List (
4576 Make_Attribute_Reference (Loc,
4577 Prefix =>
4578 New_Occurrence_Of (Stream_Parameter, Loc),
4579 Attribute_Name => Name_Access),
4580 New_Occurrence_Of (Standard_False, Loc))));
4582 Append_To (Statements,
4583 Make_Implicit_If_Statement (Nod,
4584 Condition => Asynchronous,
4585 Then_Statements => Asynchronous_Statements,
4586 Else_Statements => Non_Asynchronous_Statements));
4587 end if;
4588 end Build_General_Calling_Stubs;
4590 -----------------------------
4591 -- Build_RPC_Receiver_Body --
4592 -----------------------------
4594 procedure Build_RPC_Receiver_Body
4595 (RPC_Receiver : Entity_Id;
4596 Request : out Entity_Id;
4597 Subp_Id : out Entity_Id;
4598 Subp_Index : out Entity_Id;
4599 Stmts : out List_Id;
4600 Decl : out Node_Id)
4602 Loc : constant Source_Ptr := Sloc (RPC_Receiver);
4604 RPC_Receiver_Spec : Node_Id;
4605 RPC_Receiver_Decls : List_Id;
4607 begin
4608 Request := Make_Defining_Identifier (Loc, Name_R);
4610 RPC_Receiver_Spec :=
4611 Build_RPC_Receiver_Specification
4612 (RPC_Receiver => RPC_Receiver,
4613 Request_Parameter => Request);
4615 Subp_Id := Make_Temporary (Loc, 'P');
4616 Subp_Index := Subp_Id;
4618 -- Subp_Id may not be a constant, because in the case of the RPC
4619 -- receiver for an RCI package, when a call is received from a RAS
4620 -- dereference, it will be assigned during subsequent processing.
4622 RPC_Receiver_Decls := New_List (
4623 Make_Object_Declaration (Loc,
4624 Defining_Identifier => Subp_Id,
4625 Object_Definition =>
4626 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
4627 Expression =>
4628 Make_Attribute_Reference (Loc,
4629 Prefix =>
4630 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
4631 Attribute_Name => Name_Input,
4632 Expressions => New_List (
4633 Make_Selected_Component (Loc,
4634 Prefix => Request,
4635 Selector_Name => Name_Params)))));
4637 Stmts := New_List;
4639 Decl :=
4640 Make_Subprogram_Body (Loc,
4641 Specification => RPC_Receiver_Spec,
4642 Declarations => RPC_Receiver_Decls,
4643 Handled_Statement_Sequence =>
4644 Make_Handled_Sequence_Of_Statements (Loc,
4645 Statements => Stmts));
4646 end Build_RPC_Receiver_Body;
4648 -----------------------
4649 -- Build_Stub_Target --
4650 -----------------------
4652 function Build_Stub_Target
4653 (Loc : Source_Ptr;
4654 Decls : List_Id;
4655 RCI_Locator : Entity_Id;
4656 Controlling_Parameter : Entity_Id) return RPC_Target
4658 Target_Info : RPC_Target (PCS_Kind => Name_GARLIC_DSA);
4660 begin
4661 Target_Info.Partition := Make_Temporary (Loc, 'P');
4663 if Present (Controlling_Parameter) then
4664 Append_To (Decls,
4665 Make_Object_Declaration (Loc,
4666 Defining_Identifier => Target_Info.Partition,
4667 Constant_Present => True,
4668 Object_Definition =>
4669 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
4671 Expression =>
4672 Make_Selected_Component (Loc,
4673 Prefix => Controlling_Parameter,
4674 Selector_Name => Name_Origin)));
4676 Target_Info.RPC_Receiver :=
4677 Make_Selected_Component (Loc,
4678 Prefix => Controlling_Parameter,
4679 Selector_Name => Name_Receiver);
4681 else
4682 Append_To (Decls,
4683 Make_Object_Declaration (Loc,
4684 Defining_Identifier => Target_Info.Partition,
4685 Constant_Present => True,
4686 Object_Definition =>
4687 New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
4689 Expression =>
4690 Make_Function_Call (Loc,
4691 Name => Make_Selected_Component (Loc,
4692 Prefix =>
4693 Make_Identifier (Loc, Chars (RCI_Locator)),
4694 Selector_Name =>
4695 Make_Identifier (Loc,
4696 Name_Get_Active_Partition_ID)))));
4698 Target_Info.RPC_Receiver :=
4699 Make_Selected_Component (Loc,
4700 Prefix =>
4701 Make_Identifier (Loc, Chars (RCI_Locator)),
4702 Selector_Name =>
4703 Make_Identifier (Loc, Name_Get_RCI_Package_Receiver));
4704 end if;
4705 return Target_Info;
4706 end Build_Stub_Target;
4708 --------------------------------------
4709 -- Build_Subprogram_Receiving_Stubs --
4710 --------------------------------------
4712 function Build_Subprogram_Receiving_Stubs
4713 (Vis_Decl : Node_Id;
4714 Asynchronous : Boolean;
4715 Dynamically_Asynchronous : Boolean := False;
4716 Stub_Type : Entity_Id := Empty;
4717 RACW_Type : Entity_Id := Empty;
4718 Parent_Primitive : Entity_Id := Empty) return Node_Id
4720 Loc : constant Source_Ptr := Sloc (Vis_Decl);
4722 Request_Parameter : constant Entity_Id := Make_Temporary (Loc, 'R');
4723 -- Formal parameter for receiving stubs: a descriptor for an incoming
4724 -- request.
4726 Decls : constant List_Id := New_List;
4727 -- All the parameters will get declared before calling the real
4728 -- subprograms. Also the out parameters will be declared.
4730 Statements : constant List_Id := New_List;
4732 Extra_Formal_Statements : constant List_Id := New_List;
4733 -- Statements concerning extra formal parameters
4735 After_Statements : constant List_Id := New_List;
4736 -- Statements to be executed after the subprogram call
4738 Inner_Decls : List_Id := No_List;
4739 -- In case of a function, the inner declarations are needed since
4740 -- the result may be unconstrained.
4742 Excep_Handlers : List_Id := No_List;
4743 Excep_Choice : Entity_Id;
4744 Excep_Code : List_Id;
4746 Parameter_List : constant List_Id := New_List;
4747 -- List of parameters to be passed to the subprogram
4749 Current_Parameter : Node_Id;
4751 Ordered_Parameters_List : constant List_Id :=
4752 Build_Ordered_Parameters_List
4753 (Specification (Vis_Decl));
4755 Subp_Spec : Node_Id;
4756 -- Subprogram specification
4758 Called_Subprogram : Node_Id;
4759 -- The subprogram to call
4761 Null_Raise_Statement : Node_Id;
4763 Dynamic_Async : Entity_Id;
4765 begin
4766 if Present (RACW_Type) then
4767 Called_Subprogram := New_Occurrence_Of (Parent_Primitive, Loc);
4768 else
4769 Called_Subprogram :=
4770 New_Occurrence_Of
4771 (Defining_Unit_Name (Specification (Vis_Decl)), Loc);
4772 end if;
4774 if Dynamically_Asynchronous then
4775 Dynamic_Async := Make_Temporary (Loc, 'S');
4776 else
4777 Dynamic_Async := Empty;
4778 end if;
4780 if not Asynchronous or Dynamically_Asynchronous then
4782 -- The first statement after the subprogram call is a statement to
4783 -- write a Null_Occurrence into the result stream.
4785 Null_Raise_Statement :=
4786 Make_Attribute_Reference (Loc,
4787 Prefix =>
4788 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
4789 Attribute_Name => Name_Write,
4790 Expressions => New_List (
4791 Make_Selected_Component (Loc,
4792 Prefix => Request_Parameter,
4793 Selector_Name => Name_Result),
4794 New_Occurrence_Of (RTE (RE_Null_Occurrence), Loc)));
4796 if Dynamically_Asynchronous then
4797 Null_Raise_Statement :=
4798 Make_Implicit_If_Statement (Vis_Decl,
4799 Condition =>
4800 Make_Op_Not (Loc, New_Occurrence_Of (Dynamic_Async, Loc)),
4801 Then_Statements => New_List (Null_Raise_Statement));
4802 end if;
4804 Append_To (After_Statements, Null_Raise_Statement);
4805 end if;
4807 -- Loop through every parameter and get its value from the stream. If
4808 -- the parameter is unconstrained, then the parameter is read using
4809 -- 'Input at the point of declaration.
4811 Current_Parameter := First (Ordered_Parameters_List);
4812 while Present (Current_Parameter) loop
4813 declare
4814 Etyp : Entity_Id;
4815 Constrained : Boolean;
4817 Need_Extra_Constrained : Boolean;
4818 -- True when an Extra_Constrained actual is required
4820 Object : constant Entity_Id := Make_Temporary (Loc, 'P');
4822 Expr : Node_Id := Empty;
4824 Is_Controlling_Formal : constant Boolean :=
4825 Is_RACW_Controlling_Formal
4826 (Current_Parameter, Stub_Type);
4828 begin
4829 if Is_Controlling_Formal then
4831 -- We have a controlling formal parameter. Read its address
4832 -- rather than a real object. The address is in Unsigned_64
4833 -- form.
4835 Etyp := RTE (RE_Unsigned_64);
4836 else
4837 Etyp := Etype (Parameter_Type (Current_Parameter));
4838 end if;
4840 Constrained := not Transmit_As_Unconstrained (Etyp);
4842 if In_Present (Current_Parameter)
4843 or else not Out_Present (Current_Parameter)
4844 or else not Constrained
4845 or else Is_Controlling_Formal
4846 then
4847 -- If an input parameter is constrained, then the read of
4848 -- the parameter is deferred until the beginning of the
4849 -- subprogram body. If it is unconstrained, then an
4850 -- expression is built for the object declaration and the
4851 -- variable is set using 'Input instead of 'Read. Note that
4852 -- this deferral does not change the order in which the
4853 -- actuals are read because Build_Ordered_Parameter_List
4854 -- puts them unconstrained first.
4856 if Constrained then
4857 Append_To (Statements,
4858 Make_Attribute_Reference (Loc,
4859 Prefix => New_Occurrence_Of (Etyp, Loc),
4860 Attribute_Name => Name_Read,
4861 Expressions => New_List (
4862 Make_Selected_Component (Loc,
4863 Prefix => Request_Parameter,
4864 Selector_Name => Name_Params),
4865 New_Occurrence_Of (Object, Loc))));
4867 else
4869 -- Build and append Input_With_Tag_Check function
4871 Append_To (Decls,
4872 Input_With_Tag_Check (Loc,
4873 Var_Type => Etyp,
4874 Stream =>
4875 Make_Selected_Component (Loc,
4876 Prefix => Request_Parameter,
4877 Selector_Name => Name_Params)));
4879 -- Prepare function call expression
4881 Expr :=
4882 Make_Function_Call (Loc,
4883 Name =>
4884 New_Occurrence_Of
4885 (Defining_Unit_Name
4886 (Specification (Last (Decls))), Loc));
4887 end if;
4888 end if;
4890 Need_Extra_Constrained :=
4891 Nkind (Parameter_Type (Current_Parameter)) /=
4892 N_Access_Definition
4893 and then
4894 Ekind (Defining_Identifier (Current_Parameter)) /= E_Void
4895 and then
4896 Present (Extra_Constrained
4897 (Defining_Identifier (Current_Parameter)));
4899 -- We may not associate an extra constrained actual to a
4900 -- constant object, so if one is needed, declare the actual
4901 -- as a variable even if it won't be modified.
4903 Build_Actual_Object_Declaration
4904 (Object => Object,
4905 Etyp => Etyp,
4906 Variable => Need_Extra_Constrained
4907 or else Out_Present (Current_Parameter),
4908 Expr => Expr,
4909 Decls => Decls);
4911 -- An out parameter may be written back using a 'Write
4912 -- attribute instead of a 'Output because it has been
4913 -- constrained by the parameter given to the caller. Note that
4914 -- out controlling arguments in the case of a RACW are not put
4915 -- back in the stream because the pointer on them has not
4916 -- changed.
4918 if Out_Present (Current_Parameter)
4919 and then
4920 Etype (Parameter_Type (Current_Parameter)) /= Stub_Type
4921 then
4922 Append_To (After_Statements,
4923 Make_Attribute_Reference (Loc,
4924 Prefix => New_Occurrence_Of (Etyp, Loc),
4925 Attribute_Name => Name_Write,
4926 Expressions => New_List (
4927 Make_Selected_Component (Loc,
4928 Prefix => Request_Parameter,
4929 Selector_Name => Name_Result),
4930 New_Occurrence_Of (Object, Loc))));
4931 end if;
4933 -- For RACW controlling formals, the Etyp of Object is always
4934 -- an RACW, even if the parameter is not of an anonymous access
4935 -- type. In such case, we need to dereference it at call time.
4937 if Is_Controlling_Formal then
4938 if Nkind (Parameter_Type (Current_Parameter)) /=
4939 N_Access_Definition
4940 then
4941 Append_To (Parameter_List,
4942 Make_Parameter_Association (Loc,
4943 Selector_Name =>
4944 New_Occurrence_Of (
4945 Defining_Identifier (Current_Parameter), Loc),
4946 Explicit_Actual_Parameter =>
4947 Make_Explicit_Dereference (Loc,
4948 Unchecked_Convert_To (RACW_Type,
4949 OK_Convert_To (RTE (RE_Address),
4950 New_Occurrence_Of (Object, Loc))))));
4952 else
4953 Append_To (Parameter_List,
4954 Make_Parameter_Association (Loc,
4955 Selector_Name =>
4956 New_Occurrence_Of (
4957 Defining_Identifier (Current_Parameter), Loc),
4958 Explicit_Actual_Parameter =>
4959 Unchecked_Convert_To (RACW_Type,
4960 OK_Convert_To (RTE (RE_Address),
4961 New_Occurrence_Of (Object, Loc)))));
4962 end if;
4964 else
4965 Append_To (Parameter_List,
4966 Make_Parameter_Association (Loc,
4967 Selector_Name =>
4968 New_Occurrence_Of (
4969 Defining_Identifier (Current_Parameter), Loc),
4970 Explicit_Actual_Parameter =>
4971 New_Occurrence_Of (Object, Loc)));
4972 end if;
4974 -- If the current parameter needs an extra formal, then read it
4975 -- from the stream and set the corresponding semantic field in
4976 -- the variable. If the kind of the parameter identifier is
4977 -- E_Void, then this is a compiler generated parameter that
4978 -- doesn't need an extra constrained status.
4980 -- The case of Extra_Accessibility should also be handled ???
4982 if Need_Extra_Constrained then
4983 declare
4984 Extra_Parameter : constant Entity_Id :=
4985 Extra_Constrained
4986 (Defining_Identifier
4987 (Current_Parameter));
4989 Formal_Entity : constant Entity_Id :=
4990 Make_Defining_Identifier
4991 (Loc, Chars (Extra_Parameter));
4993 Formal_Type : constant Entity_Id :=
4994 Etype (Extra_Parameter);
4996 begin
4997 Append_To (Decls,
4998 Make_Object_Declaration (Loc,
4999 Defining_Identifier => Formal_Entity,
5000 Object_Definition =>
5001 New_Occurrence_Of (Formal_Type, Loc)));
5003 Append_To (Extra_Formal_Statements,
5004 Make_Attribute_Reference (Loc,
5005 Prefix => New_Occurrence_Of (
5006 Formal_Type, Loc),
5007 Attribute_Name => Name_Read,
5008 Expressions => New_List (
5009 Make_Selected_Component (Loc,
5010 Prefix => Request_Parameter,
5011 Selector_Name => Name_Params),
5012 New_Occurrence_Of (Formal_Entity, Loc))));
5014 -- Note: the call to Set_Extra_Constrained below relies
5015 -- on the fact that Object's Ekind has been set by
5016 -- Build_Actual_Object_Declaration.
5018 Set_Extra_Constrained (Object, Formal_Entity);
5019 end;
5020 end if;
5021 end;
5023 Next (Current_Parameter);
5024 end loop;
5026 -- Append the formal statements list at the end of regular statements
5028 Append_List_To (Statements, Extra_Formal_Statements);
5030 if Nkind (Specification (Vis_Decl)) = N_Function_Specification then
5032 -- The remote subprogram is a function. We build an inner block to
5033 -- be able to hold a potentially unconstrained result in a
5034 -- variable.
5036 declare
5037 Etyp : constant Entity_Id :=
5038 Etype (Result_Definition (Specification (Vis_Decl)));
5039 Result : constant Node_Id := Make_Temporary (Loc, 'R');
5041 begin
5042 Inner_Decls := New_List (
5043 Make_Object_Declaration (Loc,
5044 Defining_Identifier => Result,
5045 Constant_Present => True,
5046 Object_Definition => New_Occurrence_Of (Etyp, Loc),
5047 Expression =>
5048 Make_Function_Call (Loc,
5049 Name => Called_Subprogram,
5050 Parameter_Associations => Parameter_List)));
5052 if Is_Class_Wide_Type (Etyp) then
5054 -- For a remote call to a function with a class-wide type,
5055 -- check that the returned value satisfies the requirements
5056 -- of E.4(18).
5058 Append_To (Inner_Decls,
5059 Make_Transportable_Check (Loc,
5060 New_Occurrence_Of (Result, Loc)));
5062 end if;
5064 Append_To (After_Statements,
5065 Make_Attribute_Reference (Loc,
5066 Prefix => New_Occurrence_Of (Etyp, Loc),
5067 Attribute_Name => Name_Output,
5068 Expressions => New_List (
5069 Make_Selected_Component (Loc,
5070 Prefix => Request_Parameter,
5071 Selector_Name => Name_Result),
5072 New_Occurrence_Of (Result, Loc))));
5073 end;
5075 Append_To (Statements,
5076 Make_Block_Statement (Loc,
5077 Declarations => Inner_Decls,
5078 Handled_Statement_Sequence =>
5079 Make_Handled_Sequence_Of_Statements (Loc,
5080 Statements => After_Statements)));
5082 else
5083 -- The remote subprogram is a procedure. We do not need any inner
5084 -- block in this case.
5086 if Dynamically_Asynchronous then
5087 Append_To (Decls,
5088 Make_Object_Declaration (Loc,
5089 Defining_Identifier => Dynamic_Async,
5090 Object_Definition =>
5091 New_Occurrence_Of (Standard_Boolean, Loc)));
5093 Append_To (Statements,
5094 Make_Attribute_Reference (Loc,
5095 Prefix => New_Occurrence_Of (Standard_Boolean, Loc),
5096 Attribute_Name => Name_Read,
5097 Expressions => New_List (
5098 Make_Selected_Component (Loc,
5099 Prefix => Request_Parameter,
5100 Selector_Name => Name_Params),
5101 New_Occurrence_Of (Dynamic_Async, Loc))));
5102 end if;
5104 Append_To (Statements,
5105 Make_Procedure_Call_Statement (Loc,
5106 Name => Called_Subprogram,
5107 Parameter_Associations => Parameter_List));
5109 Append_List_To (Statements, After_Statements);
5110 end if;
5112 if Asynchronous and then not Dynamically_Asynchronous then
5114 -- For an asynchronous procedure, add a null exception handler
5116 Excep_Handlers := New_List (
5117 Make_Implicit_Exception_Handler (Loc,
5118 Exception_Choices => New_List (Make_Others_Choice (Loc)),
5119 Statements => New_List (Make_Null_Statement (Loc))));
5121 else
5122 -- In the other cases, if an exception is raised, then the
5123 -- exception occurrence is copied into the output stream and
5124 -- no other output parameter is written.
5126 Excep_Choice := Make_Temporary (Loc, 'E');
5128 Excep_Code := New_List (
5129 Make_Attribute_Reference (Loc,
5130 Prefix =>
5131 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc),
5132 Attribute_Name => Name_Write,
5133 Expressions => New_List (
5134 Make_Selected_Component (Loc,
5135 Prefix => Request_Parameter,
5136 Selector_Name => Name_Result),
5137 New_Occurrence_Of (Excep_Choice, Loc))));
5139 if Dynamically_Asynchronous then
5140 Excep_Code := New_List (
5141 Make_Implicit_If_Statement (Vis_Decl,
5142 Condition => Make_Op_Not (Loc,
5143 New_Occurrence_Of (Dynamic_Async, Loc)),
5144 Then_Statements => Excep_Code));
5145 end if;
5147 Excep_Handlers := New_List (
5148 Make_Implicit_Exception_Handler (Loc,
5149 Choice_Parameter => Excep_Choice,
5150 Exception_Choices => New_List (Make_Others_Choice (Loc)),
5151 Statements => Excep_Code));
5153 end if;
5155 Subp_Spec :=
5156 Make_Procedure_Specification (Loc,
5157 Defining_Unit_Name => Make_Temporary (Loc, 'F'),
5159 Parameter_Specifications => New_List (
5160 Make_Parameter_Specification (Loc,
5161 Defining_Identifier => Request_Parameter,
5162 Parameter_Type =>
5163 New_Occurrence_Of (RTE (RE_Request_Access), Loc))));
5165 return
5166 Make_Subprogram_Body (Loc,
5167 Specification => Subp_Spec,
5168 Declarations => Decls,
5169 Handled_Statement_Sequence =>
5170 Make_Handled_Sequence_Of_Statements (Loc,
5171 Statements => Statements,
5172 Exception_Handlers => Excep_Handlers));
5173 end Build_Subprogram_Receiving_Stubs;
5175 ------------
5176 -- Result --
5177 ------------
5179 function Result return Node_Id is
5180 begin
5181 return Make_Identifier (Loc, Name_V);
5182 end Result;
5184 -----------------------
5185 -- RPC_Receiver_Decl --
5186 -----------------------
5188 function RPC_Receiver_Decl (RACW_Type : Entity_Id) return Node_Id is
5189 Loc : constant Source_Ptr := Sloc (RACW_Type);
5190 Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
5192 begin
5193 -- No RPC receiver for remote access-to-subprogram
5195 if Is_RAS then
5196 return Empty;
5197 end if;
5199 return
5200 Make_Subprogram_Declaration (Loc,
5201 Build_RPC_Receiver_Specification
5202 (RPC_Receiver => Make_Temporary (Loc, 'R'),
5203 Request_Parameter => Make_Defining_Identifier (Loc, Name_R)));
5204 end RPC_Receiver_Decl;
5206 ----------------------
5207 -- Stream_Parameter --
5208 ----------------------
5210 function Stream_Parameter return Node_Id is
5211 begin
5212 return Make_Identifier (Loc, Name_S);
5213 end Stream_Parameter;
5215 end GARLIC_Support;
5217 -------------------------------
5218 -- Get_And_Reset_RACW_Bodies --
5219 -------------------------------
5221 function Get_And_Reset_RACW_Bodies (RACW_Type : Entity_Id) return List_Id is
5222 Desig : constant Entity_Id :=
5223 Etype (Designated_Type (RACW_Type));
5225 Stub_Elements : Stub_Structure := Stubs_Table.Get (Desig);
5227 Body_Decls : List_Id;
5228 -- Returned list of declarations
5230 begin
5231 if Stub_Elements = Empty_Stub_Structure then
5233 -- Stub elements may be missing as a consequence of a previously
5234 -- detected error.
5236 return No_List;
5237 end if;
5239 Body_Decls := Stub_Elements.Body_Decls;
5240 Stub_Elements.Body_Decls := No_List;
5241 Stubs_Table.Set (Desig, Stub_Elements);
5242 return Body_Decls;
5243 end Get_And_Reset_RACW_Bodies;
5245 -----------------------
5246 -- Get_Stub_Elements --
5247 -----------------------
5249 function Get_Stub_Elements (RACW_Type : Entity_Id) return Stub_Structure is
5250 Desig : constant Entity_Id :=
5251 Etype (Designated_Type (RACW_Type));
5252 Stub_Elements : constant Stub_Structure := Stubs_Table.Get (Desig);
5253 begin
5254 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
5255 return Stub_Elements;
5256 end Get_Stub_Elements;
5258 -----------------------
5259 -- Get_Subprogram_Id --
5260 -----------------------
5262 function Get_Subprogram_Id (Def : Entity_Id) return String_Id is
5263 Result : constant String_Id := Get_Subprogram_Ids (Def).Str_Identifier;
5264 begin
5265 pragma Assert (Result /= No_String);
5266 return Result;
5267 end Get_Subprogram_Id;
5269 -----------------------
5270 -- Get_Subprogram_Id --
5271 -----------------------
5273 function Get_Subprogram_Id (Def : Entity_Id) return Int is
5274 begin
5275 return Get_Subprogram_Ids (Def).Int_Identifier;
5276 end Get_Subprogram_Id;
5278 ------------------------
5279 -- Get_Subprogram_Ids --
5280 ------------------------
5282 function Get_Subprogram_Ids
5283 (Def : Entity_Id) return Subprogram_Identifiers
5285 begin
5286 return Subprogram_Identifier_Table.Get (Def);
5287 end Get_Subprogram_Ids;
5289 ----------
5290 -- Hash --
5291 ----------
5293 function Hash (F : Entity_Id) return Hash_Index is
5294 begin
5295 return Hash_Index (Natural (F) mod Positive (Hash_Index'Last + 1));
5296 end Hash;
5298 function Hash (F : Name_Id) return Hash_Index is
5299 begin
5300 return Hash_Index (Integer (F) mod Positive (Hash_Index'Last + 1));
5301 end Hash;
5303 --------------------------
5304 -- Input_With_Tag_Check --
5305 --------------------------
5307 function Input_With_Tag_Check
5308 (Loc : Source_Ptr;
5309 Var_Type : Entity_Id;
5310 Stream : Node_Id) return Node_Id
5312 begin
5313 return
5314 Make_Subprogram_Body (Loc,
5315 Specification =>
5316 Make_Function_Specification (Loc,
5317 Defining_Unit_Name => Make_Temporary (Loc, 'S'),
5318 Result_Definition => New_Occurrence_Of (Var_Type, Loc)),
5319 Declarations => No_List,
5320 Handled_Statement_Sequence =>
5321 Make_Handled_Sequence_Of_Statements (Loc, New_List (
5322 Make_Tag_Check (Loc,
5323 Make_Simple_Return_Statement (Loc,
5324 Make_Attribute_Reference (Loc,
5325 Prefix => New_Occurrence_Of (Var_Type, Loc),
5326 Attribute_Name => Name_Input,
5327 Expressions =>
5328 New_List (Stream)))))));
5329 end Input_With_Tag_Check;
5331 --------------------------------
5332 -- Is_RACW_Controlling_Formal --
5333 --------------------------------
5335 function Is_RACW_Controlling_Formal
5336 (Parameter : Node_Id;
5337 Stub_Type : Entity_Id) return Boolean
5339 Typ : Entity_Id;
5341 begin
5342 -- If the kind of the parameter is E_Void, then it is not a controlling
5343 -- formal (this can happen in the context of RAS).
5345 if Ekind (Defining_Identifier (Parameter)) = E_Void then
5346 return False;
5347 end if;
5349 -- If the parameter is not a controlling formal, then it cannot be
5350 -- possibly a RACW_Controlling_Formal.
5352 if not Is_Controlling_Formal (Defining_Identifier (Parameter)) then
5353 return False;
5354 end if;
5356 Typ := Parameter_Type (Parameter);
5357 return (Nkind (Typ) = N_Access_Definition
5358 and then Etype (Subtype_Mark (Typ)) = Stub_Type)
5359 or else Etype (Typ) = Stub_Type;
5360 end Is_RACW_Controlling_Formal;
5362 ------------------------------
5363 -- Make_Transportable_Check --
5364 ------------------------------
5366 function Make_Transportable_Check
5367 (Loc : Source_Ptr;
5368 Expr : Node_Id) return Node_Id is
5369 begin
5370 return
5371 Make_Raise_Program_Error (Loc,
5372 Condition =>
5373 Make_Op_Not (Loc,
5374 Build_Get_Transportable (Loc,
5375 Make_Selected_Component (Loc,
5376 Prefix => Expr,
5377 Selector_Name => Make_Identifier (Loc, Name_uTag)))),
5378 Reason => PE_Non_Transportable_Actual);
5379 end Make_Transportable_Check;
5381 -----------------------------
5382 -- Make_Selected_Component --
5383 -----------------------------
5385 function Make_Selected_Component
5386 (Loc : Source_Ptr;
5387 Prefix : Entity_Id;
5388 Selector_Name : Name_Id) return Node_Id
5390 begin
5391 return Make_Selected_Component (Loc,
5392 Prefix => New_Occurrence_Of (Prefix, Loc),
5393 Selector_Name => Make_Identifier (Loc, Selector_Name));
5394 end Make_Selected_Component;
5396 --------------------
5397 -- Make_Tag_Check --
5398 --------------------
5400 function Make_Tag_Check (Loc : Source_Ptr; N : Node_Id) return Node_Id is
5401 Occ : constant Entity_Id := Make_Temporary (Loc, 'E');
5403 begin
5404 return Make_Block_Statement (Loc,
5405 Handled_Statement_Sequence =>
5406 Make_Handled_Sequence_Of_Statements (Loc,
5407 Statements => New_List (N),
5409 Exception_Handlers => New_List (
5410 Make_Implicit_Exception_Handler (Loc,
5411 Choice_Parameter => Occ,
5413 Exception_Choices =>
5414 New_List (New_Occurrence_Of (RTE (RE_Tag_Error), Loc)),
5416 Statements =>
5417 New_List (Make_Procedure_Call_Statement (Loc,
5418 New_Occurrence_Of
5419 (RTE (RE_Raise_Program_Error_Unknown_Tag), Loc),
5420 New_List (New_Occurrence_Of (Occ, Loc))))))));
5421 end Make_Tag_Check;
5423 ----------------------------
5424 -- Need_Extra_Constrained --
5425 ----------------------------
5427 function Need_Extra_Constrained (Parameter : Node_Id) return Boolean is
5428 Etyp : constant Entity_Id := Etype (Parameter_Type (Parameter));
5429 begin
5430 return Out_Present (Parameter)
5431 and then Has_Discriminants (Etyp)
5432 and then not Is_Constrained (Etyp)
5433 and then Is_Definite_Subtype (Etyp);
5434 end Need_Extra_Constrained;
5436 ------------------------------------
5437 -- Pack_Entity_Into_Stream_Access --
5438 ------------------------------------
5440 function Pack_Entity_Into_Stream_Access
5441 (Loc : Source_Ptr;
5442 Stream : Node_Id;
5443 Object : Entity_Id;
5444 Etyp : Entity_Id := Empty) return Node_Id
5446 Typ : Entity_Id;
5448 begin
5449 if Present (Etyp) then
5450 Typ := Etyp;
5451 else
5452 Typ := Etype (Object);
5453 end if;
5455 return
5456 Pack_Node_Into_Stream_Access (Loc,
5457 Stream => Stream,
5458 Object => New_Occurrence_Of (Object, Loc),
5459 Etyp => Typ);
5460 end Pack_Entity_Into_Stream_Access;
5462 ---------------------------
5463 -- Pack_Node_Into_Stream --
5464 ---------------------------
5466 function Pack_Node_Into_Stream
5467 (Loc : Source_Ptr;
5468 Stream : Entity_Id;
5469 Object : Node_Id;
5470 Etyp : Entity_Id) return Node_Id
5472 Write_Attribute : Name_Id := Name_Write;
5474 begin
5475 if not Is_Constrained (Etyp) then
5476 Write_Attribute := Name_Output;
5477 end if;
5479 return
5480 Make_Attribute_Reference (Loc,
5481 Prefix => New_Occurrence_Of (Etyp, Loc),
5482 Attribute_Name => Write_Attribute,
5483 Expressions => New_List (
5484 Make_Attribute_Reference (Loc,
5485 Prefix => New_Occurrence_Of (Stream, Loc),
5486 Attribute_Name => Name_Access),
5487 Object));
5488 end Pack_Node_Into_Stream;
5490 ----------------------------------
5491 -- Pack_Node_Into_Stream_Access --
5492 ----------------------------------
5494 function Pack_Node_Into_Stream_Access
5495 (Loc : Source_Ptr;
5496 Stream : Node_Id;
5497 Object : Node_Id;
5498 Etyp : Entity_Id) return Node_Id
5500 Write_Attribute : Name_Id := Name_Write;
5502 begin
5503 if not Is_Constrained (Etyp) then
5504 Write_Attribute := Name_Output;
5505 end if;
5507 return
5508 Make_Attribute_Reference (Loc,
5509 Prefix => New_Occurrence_Of (Etyp, Loc),
5510 Attribute_Name => Write_Attribute,
5511 Expressions => New_List (
5512 Stream,
5513 Object));
5514 end Pack_Node_Into_Stream_Access;
5516 ---------------------
5517 -- PolyORB_Support --
5518 ---------------------
5520 package body PolyORB_Support is
5522 -- Local subprograms
5524 procedure Add_RACW_Read_Attribute
5525 (RACW_Type : Entity_Id;
5526 Stub_Type : Entity_Id;
5527 Stub_Type_Access : Entity_Id;
5528 Body_Decls : List_Id);
5529 -- Add Read attribute for the RACW type. The declaration and attribute
5530 -- definition clauses are inserted right after the declaration of
5531 -- RACW_Type. If Body_Decls is not No_List, the subprogram body is
5532 -- appended to it (case where the RACW declaration is in the main unit).
5534 procedure Add_RACW_Write_Attribute
5535 (RACW_Type : Entity_Id;
5536 Stub_Type : Entity_Id;
5537 Stub_Type_Access : Entity_Id;
5538 Body_Decls : List_Id);
5539 -- Same as above for the Write attribute
5541 procedure Add_RACW_From_Any
5542 (RACW_Type : Entity_Id;
5543 Body_Decls : List_Id);
5544 -- Add the From_Any TSS for this RACW type
5546 procedure Add_RACW_To_Any
5547 (RACW_Type : Entity_Id;
5548 Body_Decls : List_Id);
5549 -- Add the To_Any TSS for this RACW type
5551 procedure Add_RACW_TypeCode
5552 (Designated_Type : Entity_Id;
5553 RACW_Type : Entity_Id;
5554 Body_Decls : List_Id);
5555 -- Add the TypeCode TSS for this RACW type
5557 procedure Add_RAS_From_Any (RAS_Type : Entity_Id);
5558 -- Add the From_Any TSS for this RAS type
5560 procedure Add_RAS_To_Any (RAS_Type : Entity_Id);
5561 -- Add the To_Any TSS for this RAS type
5563 procedure Add_RAS_TypeCode (RAS_Type : Entity_Id);
5564 -- Add the TypeCode TSS for this RAS type
5566 procedure Add_RAS_Access_TSS (N : Node_Id);
5567 -- Add a subprogram body for RAS Access TSS
5569 -------------------------------------
5570 -- Add_Obj_RPC_Receiver_Completion --
5571 -------------------------------------
5573 procedure Add_Obj_RPC_Receiver_Completion
5574 (Loc : Source_Ptr;
5575 Decls : List_Id;
5576 RPC_Receiver : Entity_Id;
5577 Stub_Elements : Stub_Structure)
5579 Desig : constant Entity_Id :=
5580 Etype (Designated_Type (Stub_Elements.RACW_Type));
5581 begin
5582 Append_To (Decls,
5583 Make_Procedure_Call_Statement (Loc,
5584 Name =>
5585 New_Occurrence_Of (
5586 RTE (RE_Register_Obj_Receiving_Stub), Loc),
5588 Parameter_Associations => New_List (
5590 -- Name
5592 Make_String_Literal (Loc,
5593 Fully_Qualified_Name_String (Desig, Append_NUL => False)),
5595 -- Handler
5597 Make_Attribute_Reference (Loc,
5598 Prefix =>
5599 New_Occurrence_Of (
5600 Defining_Unit_Name (Parent (RPC_Receiver)), Loc),
5601 Attribute_Name =>
5602 Name_Access),
5604 -- Receiver
5606 Make_Attribute_Reference (Loc,
5607 Prefix =>
5608 New_Occurrence_Of (
5609 Defining_Identifier (
5610 Stub_Elements.RPC_Receiver_Decl), Loc),
5611 Attribute_Name =>
5612 Name_Access))));
5613 end Add_Obj_RPC_Receiver_Completion;
5615 -----------------------
5616 -- Add_RACW_Features --
5617 -----------------------
5619 procedure Add_RACW_Features
5620 (RACW_Type : Entity_Id;
5621 Desig : Entity_Id;
5622 Stub_Type : Entity_Id;
5623 Stub_Type_Access : Entity_Id;
5624 RPC_Receiver_Decl : Node_Id;
5625 Body_Decls : List_Id)
5627 pragma Unreferenced (RPC_Receiver_Decl);
5629 begin
5630 Add_RACW_From_Any
5631 (RACW_Type => RACW_Type,
5632 Body_Decls => Body_Decls);
5634 Add_RACW_To_Any
5635 (RACW_Type => RACW_Type,
5636 Body_Decls => Body_Decls);
5638 Add_RACW_Write_Attribute
5639 (RACW_Type => RACW_Type,
5640 Stub_Type => Stub_Type,
5641 Stub_Type_Access => Stub_Type_Access,
5642 Body_Decls => Body_Decls);
5644 Add_RACW_Read_Attribute
5645 (RACW_Type => RACW_Type,
5646 Stub_Type => Stub_Type,
5647 Stub_Type_Access => Stub_Type_Access,
5648 Body_Decls => Body_Decls);
5650 Add_RACW_TypeCode
5651 (Designated_Type => Desig,
5652 RACW_Type => RACW_Type,
5653 Body_Decls => Body_Decls);
5654 end Add_RACW_Features;
5656 -----------------------
5657 -- Add_RACW_From_Any --
5658 -----------------------
5660 procedure Add_RACW_From_Any
5661 (RACW_Type : Entity_Id;
5662 Body_Decls : List_Id)
5664 Loc : constant Source_Ptr := Sloc (RACW_Type);
5665 Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
5666 Fnam : constant Entity_Id :=
5667 Make_Defining_Identifier (Loc,
5668 Chars => New_External_Name (Chars (RACW_Type), 'F'));
5670 Func_Spec : Node_Id;
5671 Func_Decl : Node_Id;
5672 Func_Body : Node_Id;
5674 Statements : List_Id;
5675 -- Various parts of the subprogram
5677 Any_Parameter : constant Entity_Id :=
5678 Make_Defining_Identifier (Loc, Name_A);
5680 Asynchronous_Flag : constant Entity_Id :=
5681 Asynchronous_Flags_Table.Get (RACW_Type);
5682 -- The flag object declared in Add_RACW_Asynchronous_Flag
5684 begin
5685 Func_Spec :=
5686 Make_Function_Specification (Loc,
5687 Defining_Unit_Name =>
5688 Fnam,
5689 Parameter_Specifications => New_List (
5690 Make_Parameter_Specification (Loc,
5691 Defining_Identifier =>
5692 Any_Parameter,
5693 Parameter_Type =>
5694 New_Occurrence_Of (RTE (RE_Any), Loc))),
5695 Result_Definition => New_Occurrence_Of (RACW_Type, Loc));
5697 -- NOTE: The usage occurrences of RACW_Parameter must refer to the
5698 -- entity in the declaration spec, not those of the body spec.
5700 Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
5701 Insert_After (Declaration_Node (RACW_Type), Func_Decl);
5702 Set_Renaming_TSS (RACW_Type, Fnam, TSS_From_Any);
5704 if No (Body_Decls) then
5705 return;
5706 end if;
5708 -- ??? Issue with asynchronous calls here: the Asynchronous flag is
5709 -- set on the stub type if, and only if, the RACW type has a pragma
5710 -- Asynchronous. This is incorrect for RACWs that implement RAS
5711 -- types, because in that case the /designated subprogram/ (not the
5712 -- type) might be asynchronous, and that causes the stub to need to
5713 -- be asynchronous too. A solution is to transport a RAS as a struct
5714 -- containing a RACW and an asynchronous flag, and to properly alter
5715 -- the Asynchronous component in the stub type in the RAS's _From_Any
5716 -- TSS.
5718 Statements := New_List (
5719 Make_Simple_Return_Statement (Loc,
5720 Expression => Unchecked_Convert_To (RACW_Type,
5721 Make_Function_Call (Loc,
5722 Name => New_Occurrence_Of (RTE (RE_Get_RACW), Loc),
5723 Parameter_Associations => New_List (
5724 Make_Function_Call (Loc,
5725 Name => New_Occurrence_Of (RTE (RE_FA_ObjRef), Loc),
5726 Parameter_Associations => New_List (
5727 New_Occurrence_Of (Any_Parameter, Loc))),
5728 Build_Stub_Tag (Loc, RACW_Type),
5729 New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc),
5730 New_Occurrence_Of (Asynchronous_Flag, Loc))))));
5732 Func_Body :=
5733 Make_Subprogram_Body (Loc,
5734 Specification => Copy_Specification (Loc, Func_Spec),
5735 Declarations => No_List,
5736 Handled_Statement_Sequence =>
5737 Make_Handled_Sequence_Of_Statements (Loc,
5738 Statements => Statements));
5740 Append_To (Body_Decls, Func_Body);
5741 end Add_RACW_From_Any;
5743 -----------------------------
5744 -- Add_RACW_Read_Attribute --
5745 -----------------------------
5747 procedure Add_RACW_Read_Attribute
5748 (RACW_Type : Entity_Id;
5749 Stub_Type : Entity_Id;
5750 Stub_Type_Access : Entity_Id;
5751 Body_Decls : List_Id)
5753 pragma Unreferenced (Stub_Type, Stub_Type_Access);
5755 Loc : constant Source_Ptr := Sloc (RACW_Type);
5757 Proc_Decl : Node_Id;
5758 Attr_Decl : Node_Id;
5760 Body_Node : Node_Id;
5762 Decls : constant List_Id := New_List;
5763 Statements : constant List_Id := New_List;
5764 Reference : constant Entity_Id :=
5765 Make_Defining_Identifier (Loc, Name_R);
5766 -- Various parts of the procedure
5768 Pnam : constant Entity_Id := Make_Temporary (Loc, 'R');
5770 Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
5772 Asynchronous_Flag : constant Entity_Id :=
5773 Asynchronous_Flags_Table.Get (RACW_Type);
5774 pragma Assert (Present (Asynchronous_Flag));
5776 function Stream_Parameter return Node_Id;
5777 function Result return Node_Id;
5779 -- Functions to create occurrences of the formal parameter names
5781 ------------
5782 -- Result --
5783 ------------
5785 function Result return Node_Id is
5786 begin
5787 return Make_Identifier (Loc, Name_V);
5788 end Result;
5790 ----------------------
5791 -- Stream_Parameter --
5792 ----------------------
5794 function Stream_Parameter return Node_Id is
5795 begin
5796 return Make_Identifier (Loc, Name_S);
5797 end Stream_Parameter;
5799 -- Start of processing for Add_RACW_Read_Attribute
5801 begin
5802 Build_Stream_Procedure
5803 (RACW_Type, Body_Node, Pnam, Statements, Outp => True);
5805 Proc_Decl := Make_Subprogram_Declaration (Loc,
5806 Copy_Specification (Loc, Specification (Body_Node)));
5808 Attr_Decl :=
5809 Make_Attribute_Definition_Clause (Loc,
5810 Name => New_Occurrence_Of (RACW_Type, Loc),
5811 Chars => Name_Read,
5812 Expression =>
5813 New_Occurrence_Of (
5814 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
5816 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
5817 Insert_After (Proc_Decl, Attr_Decl);
5819 if No (Body_Decls) then
5820 return;
5821 end if;
5823 Append_To (Decls,
5824 Make_Object_Declaration (Loc,
5825 Defining_Identifier =>
5826 Reference,
5827 Object_Definition =>
5828 New_Occurrence_Of (RTE (RE_Object_Ref), Loc)));
5830 Append_List_To (Statements, New_List (
5831 Make_Attribute_Reference (Loc,
5832 Prefix =>
5833 New_Occurrence_Of (RTE (RE_Object_Ref), Loc),
5834 Attribute_Name => Name_Read,
5835 Expressions => New_List (
5836 Stream_Parameter,
5837 New_Occurrence_Of (Reference, Loc))),
5839 Make_Assignment_Statement (Loc,
5840 Name =>
5841 Result,
5842 Expression =>
5843 Unchecked_Convert_To (RACW_Type,
5844 Make_Function_Call (Loc,
5845 Name =>
5846 New_Occurrence_Of (RTE (RE_Get_RACW), Loc),
5847 Parameter_Associations => New_List (
5848 New_Occurrence_Of (Reference, Loc),
5849 Build_Stub_Tag (Loc, RACW_Type),
5850 New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc),
5851 New_Occurrence_Of (Asynchronous_Flag, Loc)))))));
5853 Set_Declarations (Body_Node, Decls);
5854 Append_To (Body_Decls, Body_Node);
5855 end Add_RACW_Read_Attribute;
5857 ---------------------
5858 -- Add_RACW_To_Any --
5859 ---------------------
5861 procedure Add_RACW_To_Any
5862 (RACW_Type : Entity_Id;
5863 Body_Decls : List_Id)
5865 Loc : constant Source_Ptr := Sloc (RACW_Type);
5867 Fnam : constant Entity_Id :=
5868 Make_Defining_Identifier (Loc,
5869 Chars => New_External_Name (Chars (RACW_Type), 'T'));
5871 Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
5873 Stub_Elements : constant Stub_Structure :=
5874 Get_Stub_Elements (RACW_Type);
5876 Func_Spec : Node_Id;
5877 Func_Decl : Node_Id;
5878 Func_Body : Node_Id;
5880 Decls : List_Id;
5881 Statements : List_Id;
5882 -- Various parts of the subprogram
5884 RACW_Parameter : constant Entity_Id :=
5885 Make_Defining_Identifier (Loc, Name_R);
5887 Reference : constant Entity_Id := Make_Temporary (Loc, 'R');
5888 Any : constant Entity_Id := Make_Temporary (Loc, 'A');
5890 begin
5891 Func_Spec :=
5892 Make_Function_Specification (Loc,
5893 Defining_Unit_Name =>
5894 Fnam,
5895 Parameter_Specifications => New_List (
5896 Make_Parameter_Specification (Loc,
5897 Defining_Identifier =>
5898 RACW_Parameter,
5899 Parameter_Type =>
5900 New_Occurrence_Of (RACW_Type, Loc))),
5901 Result_Definition => New_Occurrence_Of (RTE (RE_Any), Loc));
5903 -- NOTE: The usage occurrences of RACW_Parameter must refer to the
5904 -- entity in the declaration spec, not in the body spec.
5906 Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
5908 Insert_After (Declaration_Node (RACW_Type), Func_Decl);
5909 Set_Renaming_TSS (RACW_Type, Fnam, TSS_To_Any);
5911 if No (Body_Decls) then
5912 return;
5913 end if;
5915 -- Generate:
5917 -- R : constant Object_Ref :=
5918 -- Get_Reference
5919 -- (Address!(RACW),
5920 -- "typ",
5921 -- Stub_Type'Tag,
5922 -- Is_RAS,
5923 -- RPC_Receiver'Access);
5924 -- A : Any;
5926 Decls := New_List (
5927 Make_Object_Declaration (Loc,
5928 Defining_Identifier => Reference,
5929 Constant_Present => True,
5930 Object_Definition =>
5931 New_Occurrence_Of (RTE (RE_Object_Ref), Loc),
5932 Expression =>
5933 Make_Function_Call (Loc,
5934 Name => New_Occurrence_Of (RTE (RE_Get_Reference), Loc),
5935 Parameter_Associations => New_List (
5936 Unchecked_Convert_To (RTE (RE_Address),
5937 New_Occurrence_Of (RACW_Parameter, Loc)),
5938 Make_String_Literal (Loc,
5939 Strval => Fully_Qualified_Name_String
5940 (Etype (Designated_Type (RACW_Type)),
5941 Append_NUL => False)),
5942 Build_Stub_Tag (Loc, RACW_Type),
5943 New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc),
5944 Make_Attribute_Reference (Loc,
5945 Prefix =>
5946 New_Occurrence_Of
5947 (Defining_Identifier
5948 (Stub_Elements.RPC_Receiver_Decl), Loc),
5949 Attribute_Name => Name_Access)))),
5951 Make_Object_Declaration (Loc,
5952 Defining_Identifier => Any,
5953 Object_Definition => New_Occurrence_Of (RTE (RE_Any), Loc)));
5955 -- Generate:
5957 -- Any := TA_ObjRef (Reference);
5958 -- Set_TC (Any, RPC_Receiver.Obj_TypeCode);
5959 -- return Any;
5961 Statements := New_List (
5962 Make_Assignment_Statement (Loc,
5963 Name => New_Occurrence_Of (Any, Loc),
5964 Expression =>
5965 Make_Function_Call (Loc,
5966 Name => New_Occurrence_Of (RTE (RE_TA_ObjRef), Loc),
5967 Parameter_Associations => New_List (
5968 New_Occurrence_Of (Reference, Loc)))),
5970 Make_Procedure_Call_Statement (Loc,
5971 Name => New_Occurrence_Of (RTE (RE_Set_TC), Loc),
5972 Parameter_Associations => New_List (
5973 New_Occurrence_Of (Any, Loc),
5974 Make_Selected_Component (Loc,
5975 Prefix =>
5976 Defining_Identifier (
5977 Stub_Elements.RPC_Receiver_Decl),
5978 Selector_Name => Name_Obj_TypeCode))),
5980 Make_Simple_Return_Statement (Loc,
5981 Expression => New_Occurrence_Of (Any, Loc)));
5983 Func_Body :=
5984 Make_Subprogram_Body (Loc,
5985 Specification => Copy_Specification (Loc, Func_Spec),
5986 Declarations => Decls,
5987 Handled_Statement_Sequence =>
5988 Make_Handled_Sequence_Of_Statements (Loc,
5989 Statements => Statements));
5990 Append_To (Body_Decls, Func_Body);
5991 end Add_RACW_To_Any;
5993 -----------------------
5994 -- Add_RACW_TypeCode --
5995 -----------------------
5997 procedure Add_RACW_TypeCode
5998 (Designated_Type : Entity_Id;
5999 RACW_Type : Entity_Id;
6000 Body_Decls : List_Id)
6002 Loc : constant Source_Ptr := Sloc (RACW_Type);
6004 Fnam : constant Entity_Id :=
6005 Make_Defining_Identifier (Loc,
6006 Chars => New_External_Name (Chars (RACW_Type), 'Y'));
6008 Stub_Elements : constant Stub_Structure :=
6009 Stubs_Table.Get (Designated_Type);
6010 pragma Assert (Stub_Elements /= Empty_Stub_Structure);
6012 Func_Spec : Node_Id;
6013 Func_Decl : Node_Id;
6014 Func_Body : Node_Id;
6016 begin
6017 -- The spec for this subprogram has a dummy 'access RACW' argument,
6018 -- which serves only for overloading purposes.
6020 Func_Spec :=
6021 Make_Function_Specification (Loc,
6022 Defining_Unit_Name => Fnam,
6023 Result_Definition => New_Occurrence_Of (RTE (RE_TypeCode), Loc));
6025 -- NOTE: The usage occurrences of RACW_Parameter must refer to the
6026 -- entity in the declaration spec, not those of the body spec.
6028 Func_Decl := Make_Subprogram_Declaration (Loc, Func_Spec);
6029 Insert_After (Declaration_Node (RACW_Type), Func_Decl);
6030 Set_Renaming_TSS (RACW_Type, Fnam, TSS_TypeCode);
6032 if No (Body_Decls) then
6033 return;
6034 end if;
6036 Func_Body :=
6037 Make_Subprogram_Body (Loc,
6038 Specification => Copy_Specification (Loc, Func_Spec),
6039 Declarations => Empty_List,
6040 Handled_Statement_Sequence =>
6041 Make_Handled_Sequence_Of_Statements (Loc,
6042 Statements => New_List (
6043 Make_Simple_Return_Statement (Loc,
6044 Expression =>
6045 Make_Selected_Component (Loc,
6046 Prefix =>
6047 Defining_Identifier
6048 (Stub_Elements.RPC_Receiver_Decl),
6049 Selector_Name => Name_Obj_TypeCode)))));
6051 Append_To (Body_Decls, Func_Body);
6052 end Add_RACW_TypeCode;
6054 ------------------------------
6055 -- Add_RACW_Write_Attribute --
6056 ------------------------------
6058 procedure Add_RACW_Write_Attribute
6059 (RACW_Type : Entity_Id;
6060 Stub_Type : Entity_Id;
6061 Stub_Type_Access : Entity_Id;
6062 Body_Decls : List_Id)
6064 pragma Unreferenced (Stub_Type, Stub_Type_Access);
6066 Loc : constant Source_Ptr := Sloc (RACW_Type);
6068 Is_RAS : constant Boolean := not Comes_From_Source (RACW_Type);
6070 Stub_Elements : constant Stub_Structure :=
6071 Get_Stub_Elements (RACW_Type);
6073 Body_Node : Node_Id;
6074 Proc_Decl : Node_Id;
6075 Attr_Decl : Node_Id;
6077 Statements : constant List_Id := New_List;
6078 Pnam : constant Entity_Id := Make_Temporary (Loc, 'R');
6080 function Stream_Parameter return Node_Id;
6081 function Object return Node_Id;
6082 -- Functions to create occurrences of the formal parameter names
6084 ------------
6085 -- Object --
6086 ------------
6088 function Object return Node_Id is
6089 begin
6090 return Make_Identifier (Loc, Name_V);
6091 end Object;
6093 ----------------------
6094 -- Stream_Parameter --
6095 ----------------------
6097 function Stream_Parameter return Node_Id is
6098 begin
6099 return Make_Identifier (Loc, Name_S);
6100 end Stream_Parameter;
6102 -- Start of processing for Add_RACW_Write_Attribute
6104 begin
6105 Build_Stream_Procedure
6106 (RACW_Type, Body_Node, Pnam, Statements, Outp => False);
6108 Proc_Decl :=
6109 Make_Subprogram_Declaration (Loc,
6110 Copy_Specification (Loc, Specification (Body_Node)));
6112 Attr_Decl :=
6113 Make_Attribute_Definition_Clause (Loc,
6114 Name => New_Occurrence_Of (RACW_Type, Loc),
6115 Chars => Name_Write,
6116 Expression =>
6117 New_Occurrence_Of (
6118 Defining_Unit_Name (Specification (Proc_Decl)), Loc));
6120 Insert_After (Declaration_Node (RACW_Type), Proc_Decl);
6121 Insert_After (Proc_Decl, Attr_Decl);
6123 if No (Body_Decls) then
6124 return;
6125 end if;
6127 Append_To (Statements,
6128 Pack_Node_Into_Stream_Access (Loc,
6129 Stream => Stream_Parameter,
6130 Object =>
6131 Make_Function_Call (Loc,
6132 Name => New_Occurrence_Of (RTE (RE_Get_Reference), Loc),
6133 Parameter_Associations => New_List (
6134 Unchecked_Convert_To (RTE (RE_Address), Object),
6135 Make_String_Literal (Loc,
6136 Strval => Fully_Qualified_Name_String
6137 (Etype (Designated_Type (RACW_Type)),
6138 Append_NUL => False)),
6139 Build_Stub_Tag (Loc, RACW_Type),
6140 New_Occurrence_Of (Boolean_Literals (Is_RAS), Loc),
6141 Make_Attribute_Reference (Loc,
6142 Prefix =>
6143 New_Occurrence_Of
6144 (Defining_Identifier
6145 (Stub_Elements.RPC_Receiver_Decl), Loc),
6146 Attribute_Name => Name_Access))),
6148 Etyp => RTE (RE_Object_Ref)));
6150 Append_To (Body_Decls, Body_Node);
6151 end Add_RACW_Write_Attribute;
6153 -----------------------
6154 -- Add_RAST_Features --
6155 -----------------------
6157 procedure Add_RAST_Features
6158 (Vis_Decl : Node_Id;
6159 RAS_Type : Entity_Id)
6161 begin
6162 Add_RAS_Access_TSS (Vis_Decl);
6164 Add_RAS_From_Any (RAS_Type);
6165 Add_RAS_TypeCode (RAS_Type);
6167 -- To_Any uses TypeCode, and therefore needs to be generated last
6169 Add_RAS_To_Any (RAS_Type);
6170 end Add_RAST_Features;
6172 ------------------------
6173 -- Add_RAS_Access_TSS --
6174 ------------------------
6176 procedure Add_RAS_Access_TSS (N : Node_Id) is
6177 Loc : constant Source_Ptr := Sloc (N);
6179 Ras_Type : constant Entity_Id := Defining_Identifier (N);
6180 Fat_Type : constant Entity_Id := Equivalent_Type (Ras_Type);
6181 -- Ras_Type is the access to subprogram type; Fat_Type is the
6182 -- corresponding record type.
6184 RACW_Type : constant Entity_Id :=
6185 Underlying_RACW_Type (Ras_Type);
6187 Stub_Elements : constant Stub_Structure :=
6188 Get_Stub_Elements (RACW_Type);
6190 Proc : constant Entity_Id :=
6191 Make_Defining_Identifier (Loc,
6192 Chars => Make_TSS_Name (Ras_Type, TSS_RAS_Access));
6194 Proc_Spec : Node_Id;
6196 -- Formal parameters
6198 Package_Name : constant Entity_Id :=
6199 Make_Defining_Identifier (Loc,
6200 Chars => Name_P);
6202 -- Target package
6204 Subp_Id : constant Entity_Id :=
6205 Make_Defining_Identifier (Loc,
6206 Chars => Name_S);
6208 -- Target subprogram
6210 Asynch_P : constant Entity_Id :=
6211 Make_Defining_Identifier (Loc,
6212 Chars => Name_Asynchronous);
6213 -- Is the procedure to which the 'Access applies asynchronous?
6215 All_Calls_Remote : constant Entity_Id :=
6216 Make_Defining_Identifier (Loc,
6217 Chars => Name_All_Calls_Remote);
6218 -- True if an All_Calls_Remote pragma applies to the RCI unit
6219 -- that contains the subprogram.
6221 -- Common local variables
6223 Proc_Decls : List_Id;
6224 Proc_Statements : List_Id;
6226 Subp_Ref : constant Entity_Id :=
6227 Make_Defining_Identifier (Loc, Name_R);
6228 -- Reference that designates the target subprogram (returned
6229 -- by Get_RAS_Info).
6231 Is_Local : constant Entity_Id :=
6232 Make_Defining_Identifier (Loc, Name_L);
6233 Local_Addr : constant Entity_Id :=
6234 Make_Defining_Identifier (Loc, Name_A);
6235 -- For the call to Get_Local_Address
6237 Local_Stub : constant Entity_Id := Make_Temporary (Loc, 'L');
6238 Stub_Ptr : constant Entity_Id := Make_Temporary (Loc, 'S');
6239 -- Additional local variables for the remote case
6241 function Set_Field
6242 (Field_Name : Name_Id;
6243 Value : Node_Id) return Node_Id;
6244 -- Construct an assignment that sets the named component in the
6245 -- returned record
6247 ---------------
6248 -- Set_Field --
6249 ---------------
6251 function Set_Field
6252 (Field_Name : Name_Id;
6253 Value : Node_Id) return Node_Id
6255 begin
6256 return
6257 Make_Assignment_Statement (Loc,
6258 Name =>
6259 Make_Selected_Component (Loc,
6260 Prefix => Stub_Ptr,
6261 Selector_Name => Field_Name),
6262 Expression => Value);
6263 end Set_Field;
6265 -- Start of processing for Add_RAS_Access_TSS
6267 begin
6268 Proc_Decls := New_List (
6270 -- Common declarations
6272 Make_Object_Declaration (Loc,
6273 Defining_Identifier => Subp_Ref,
6274 Object_Definition =>
6275 New_Occurrence_Of (RTE (RE_Object_Ref), Loc)),
6277 Make_Object_Declaration (Loc,
6278 Defining_Identifier => Is_Local,
6279 Object_Definition =>
6280 New_Occurrence_Of (Standard_Boolean, Loc)),
6282 Make_Object_Declaration (Loc,
6283 Defining_Identifier => Local_Addr,
6284 Object_Definition =>
6285 New_Occurrence_Of (RTE (RE_Address), Loc)),
6287 Make_Object_Declaration (Loc,
6288 Defining_Identifier => Local_Stub,
6289 Aliased_Present => True,
6290 Object_Definition =>
6291 New_Occurrence_Of (Stub_Elements.Stub_Type, Loc)),
6293 Make_Object_Declaration (Loc,
6294 Defining_Identifier => Stub_Ptr,
6295 Object_Definition =>
6296 New_Occurrence_Of (Stub_Elements.Stub_Type_Access, Loc),
6297 Expression =>
6298 Make_Attribute_Reference (Loc,
6299 Prefix => New_Occurrence_Of (Local_Stub, Loc),
6300 Attribute_Name => Name_Unchecked_Access)));
6302 Set_Etype (Stub_Ptr, Stub_Elements.Stub_Type_Access);
6303 -- Build_Get_Unique_RP_Call needs this information
6305 -- Get_RAS_Info (Pkg, Subp, R);
6306 -- Obtain a reference to the target subprogram
6308 Proc_Statements := New_List (
6309 Make_Procedure_Call_Statement (Loc,
6310 Name => New_Occurrence_Of (RTE (RE_Get_RAS_Info), Loc),
6311 Parameter_Associations => New_List (
6312 New_Occurrence_Of (Package_Name, Loc),
6313 New_Occurrence_Of (Subp_Id, Loc),
6314 New_Occurrence_Of (Subp_Ref, Loc))),
6316 -- Get_Local_Address (R, L, A);
6317 -- Determine whether the subprogram is local (L), and if so
6318 -- obtain the local address of its proxy (A).
6320 Make_Procedure_Call_Statement (Loc,
6321 Name => New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
6322 Parameter_Associations => New_List (
6323 New_Occurrence_Of (Subp_Ref, Loc),
6324 New_Occurrence_Of (Is_Local, Loc),
6325 New_Occurrence_Of (Local_Addr, Loc))));
6327 -- Note: Here we assume that the Fat_Type is a record containing just
6328 -- an access to a proxy or stub object.
6330 Append_To (Proc_Statements,
6332 -- if L then
6334 Make_Implicit_If_Statement (N,
6335 Condition => New_Occurrence_Of (Is_Local, Loc),
6337 Then_Statements => New_List (
6339 -- if A.Target = null then
6341 Make_Implicit_If_Statement (N,
6342 Condition =>
6343 Make_Op_Eq (Loc,
6344 Make_Selected_Component (Loc,
6345 Prefix =>
6346 Unchecked_Convert_To
6347 (RTE (RE_RAS_Proxy_Type_Access),
6348 New_Occurrence_Of (Local_Addr, Loc)),
6349 Selector_Name => Make_Identifier (Loc, Name_Target)),
6350 Make_Null (Loc)),
6352 Then_Statements => New_List (
6354 -- A.Target := Entity_Of (Ref);
6356 Make_Assignment_Statement (Loc,
6357 Name =>
6358 Make_Selected_Component (Loc,
6359 Prefix =>
6360 Unchecked_Convert_To
6361 (RTE (RE_RAS_Proxy_Type_Access),
6362 New_Occurrence_Of (Local_Addr, Loc)),
6363 Selector_Name => Make_Identifier (Loc, Name_Target)),
6364 Expression =>
6365 Make_Function_Call (Loc,
6366 Name => New_Occurrence_Of (RTE (RE_Entity_Of), Loc),
6367 Parameter_Associations => New_List (
6368 New_Occurrence_Of (Subp_Ref, Loc)))),
6370 -- Inc_Usage (A.Target);
6371 -- end if;
6373 Make_Procedure_Call_Statement (Loc,
6374 Name => New_Occurrence_Of (RTE (RE_Inc_Usage), Loc),
6375 Parameter_Associations => New_List (
6376 Make_Selected_Component (Loc,
6377 Prefix =>
6378 Unchecked_Convert_To
6379 (RTE (RE_RAS_Proxy_Type_Access),
6380 New_Occurrence_Of (Local_Addr, Loc)),
6381 Selector_Name =>
6382 Make_Identifier (Loc, Name_Target)))))),
6384 -- if not All_Calls_Remote then
6385 -- return Fat_Type!(A);
6386 -- end if;
6388 Make_Implicit_If_Statement (N,
6389 Condition =>
6390 Make_Op_Not (Loc,
6391 Right_Opnd =>
6392 New_Occurrence_Of (All_Calls_Remote, Loc)),
6394 Then_Statements => New_List (
6395 Make_Simple_Return_Statement (Loc,
6396 Expression =>
6397 Unchecked_Convert_To
6398 (Fat_Type, New_Occurrence_Of (Local_Addr, Loc))))))));
6400 Append_List_To (Proc_Statements, New_List (
6402 -- Stub.Target := Entity_Of (Ref);
6404 Set_Field (Name_Target,
6405 Make_Function_Call (Loc,
6406 Name => New_Occurrence_Of (RTE (RE_Entity_Of), Loc),
6407 Parameter_Associations => New_List (
6408 New_Occurrence_Of (Subp_Ref, Loc)))),
6410 -- Inc_Usage (Stub.Target);
6412 Make_Procedure_Call_Statement (Loc,
6413 Name => New_Occurrence_Of (RTE (RE_Inc_Usage), Loc),
6414 Parameter_Associations => New_List (
6415 Make_Selected_Component (Loc,
6416 Prefix => Stub_Ptr,
6417 Selector_Name => Name_Target))),
6419 -- E.4.1(9) A remote call is asynchronous if it is a call to
6420 -- a procedure, or a call through a value of an access-to-procedure
6421 -- type, to which a pragma Asynchronous applies.
6423 -- Parameter Asynch_P is true when the procedure is asynchronous;
6424 -- Expression Asynch_T is true when the type is asynchronous.
6426 Set_Field (Name_Asynchronous,
6427 Make_Or_Else (Loc,
6428 Left_Opnd => New_Occurrence_Of (Asynch_P, Loc),
6429 Right_Opnd =>
6430 New_Occurrence_Of
6431 (Boolean_Literals (Is_Asynchronous (Ras_Type)), Loc)))));
6433 Append_List_To (Proc_Statements,
6434 Build_Get_Unique_RP_Call (Loc, Stub_Ptr, Stub_Elements.Stub_Type));
6436 Append_To (Proc_Statements,
6437 Make_Simple_Return_Statement (Loc,
6438 Expression =>
6439 Unchecked_Convert_To (Fat_Type,
6440 New_Occurrence_Of (Stub_Ptr, Loc))));
6442 Proc_Spec :=
6443 Make_Function_Specification (Loc,
6444 Defining_Unit_Name => Proc,
6445 Parameter_Specifications => New_List (
6446 Make_Parameter_Specification (Loc,
6447 Defining_Identifier => Package_Name,
6448 Parameter_Type =>
6449 New_Occurrence_Of (Standard_String, Loc)),
6451 Make_Parameter_Specification (Loc,
6452 Defining_Identifier => Subp_Id,
6453 Parameter_Type =>
6454 New_Occurrence_Of (Standard_String, Loc)),
6456 Make_Parameter_Specification (Loc,
6457 Defining_Identifier => Asynch_P,
6458 Parameter_Type =>
6459 New_Occurrence_Of (Standard_Boolean, Loc)),
6461 Make_Parameter_Specification (Loc,
6462 Defining_Identifier => All_Calls_Remote,
6463 Parameter_Type =>
6464 New_Occurrence_Of (Standard_Boolean, Loc))),
6466 Result_Definition =>
6467 New_Occurrence_Of (Fat_Type, Loc));
6469 -- Set the kind and return type of the function to prevent
6470 -- ambiguities between Ras_Type and Fat_Type in subsequent analysis.
6472 Mutate_Ekind (Proc, E_Function);
6473 Set_Etype (Proc, Fat_Type);
6475 Discard_Node (
6476 Make_Subprogram_Body (Loc,
6477 Specification => Proc_Spec,
6478 Declarations => Proc_Decls,
6479 Handled_Statement_Sequence =>
6480 Make_Handled_Sequence_Of_Statements (Loc,
6481 Statements => Proc_Statements)));
6483 Set_TSS (Fat_Type, Proc);
6484 end Add_RAS_Access_TSS;
6486 ----------------------
6487 -- Add_RAS_From_Any --
6488 ----------------------
6490 procedure Add_RAS_From_Any (RAS_Type : Entity_Id) is
6491 Loc : constant Source_Ptr := Sloc (RAS_Type);
6493 Fnam : constant Entity_Id := Make_Defining_Identifier (Loc,
6494 Make_TSS_Name (RAS_Type, TSS_From_Any));
6496 Func_Spec : Node_Id;
6498 Statements : List_Id;
6500 Any_Parameter : constant Entity_Id :=
6501 Make_Defining_Identifier (Loc, Name_A);
6503 begin
6504 Statements := New_List (
6505 Make_Simple_Return_Statement (Loc,
6506 Expression =>
6507 Make_Aggregate (Loc,
6508 Component_Associations => New_List (
6509 Make_Component_Association (Loc,
6510 Choices => New_List (Make_Identifier (Loc, Name_Ras)),
6511 Expression =>
6512 PolyORB_Support.Helpers.Build_From_Any_Call
6513 (Underlying_RACW_Type (RAS_Type),
6514 New_Occurrence_Of (Any_Parameter, Loc),
6515 No_List))))));
6517 Func_Spec :=
6518 Make_Function_Specification (Loc,
6519 Defining_Unit_Name => Fnam,
6520 Parameter_Specifications => New_List (
6521 Make_Parameter_Specification (Loc,
6522 Defining_Identifier => Any_Parameter,
6523 Parameter_Type => New_Occurrence_Of (RTE (RE_Any), Loc))),
6524 Result_Definition => New_Occurrence_Of (RAS_Type, Loc));
6526 Discard_Node (
6527 Make_Subprogram_Body (Loc,
6528 Specification => Func_Spec,
6529 Declarations => No_List,
6530 Handled_Statement_Sequence =>
6531 Make_Handled_Sequence_Of_Statements (Loc,
6532 Statements => Statements)));
6533 Set_TSS (RAS_Type, Fnam);
6534 end Add_RAS_From_Any;
6536 --------------------
6537 -- Add_RAS_To_Any --
6538 --------------------
6540 procedure Add_RAS_To_Any (RAS_Type : Entity_Id) is
6541 Loc : constant Source_Ptr := Sloc (RAS_Type);
6543 Fnam : constant Entity_Id := Make_Defining_Identifier (Loc,
6544 Make_TSS_Name (RAS_Type, TSS_To_Any));
6546 Decls : List_Id;
6547 Statements : List_Id;
6549 Func_Spec : Node_Id;
6551 Any : constant Entity_Id := Make_Temporary (Loc, 'A');
6552 RAS_Parameter : constant Entity_Id := Make_Temporary (Loc, 'R');
6553 RACW_Parameter : constant Node_Id :=
6554 Make_Selected_Component (Loc,
6555 Prefix => RAS_Parameter,
6556 Selector_Name => Name_Ras);
6558 begin
6559 -- Object declarations
6561 Set_Etype (RACW_Parameter, Underlying_RACW_Type (RAS_Type));
6562 Decls := New_List (
6563 Make_Object_Declaration (Loc,
6564 Defining_Identifier => Any,
6565 Object_Definition => New_Occurrence_Of (RTE (RE_Any), Loc),
6566 Expression =>
6567 PolyORB_Support.Helpers.Build_To_Any_Call
6568 (Loc, RACW_Parameter, No_List)));
6570 Statements := New_List (
6571 Make_Procedure_Call_Statement (Loc,
6572 Name => New_Occurrence_Of (RTE (RE_Set_TC), Loc),
6573 Parameter_Associations => New_List (
6574 New_Occurrence_Of (Any, Loc),
6575 PolyORB_Support.Helpers.Build_TypeCode_Call (Loc,
6576 RAS_Type, Decls))),
6578 Make_Simple_Return_Statement (Loc,
6579 Expression => New_Occurrence_Of (Any, Loc)));
6581 Func_Spec :=
6582 Make_Function_Specification (Loc,
6583 Defining_Unit_Name => Fnam,
6584 Parameter_Specifications => New_List (
6585 Make_Parameter_Specification (Loc,
6586 Defining_Identifier => RAS_Parameter,
6587 Parameter_Type => New_Occurrence_Of (RAS_Type, Loc))),
6588 Result_Definition => New_Occurrence_Of (RTE (RE_Any), Loc));
6590 Discard_Node (
6591 Make_Subprogram_Body (Loc,
6592 Specification => Func_Spec,
6593 Declarations => Decls,
6594 Handled_Statement_Sequence =>
6595 Make_Handled_Sequence_Of_Statements (Loc,
6596 Statements => Statements)));
6597 Set_TSS (RAS_Type, Fnam);
6598 end Add_RAS_To_Any;
6600 ----------------------
6601 -- Add_RAS_TypeCode --
6602 ----------------------
6604 procedure Add_RAS_TypeCode (RAS_Type : Entity_Id) is
6605 Loc : constant Source_Ptr := Sloc (RAS_Type);
6607 Fnam : constant Entity_Id := Make_Defining_Identifier (Loc,
6608 Make_TSS_Name (RAS_Type, TSS_TypeCode));
6610 Func_Spec : Node_Id;
6611 Decls : constant List_Id := New_List;
6612 Name_String : String_Id;
6613 Repo_Id_String : String_Id;
6615 begin
6616 Func_Spec :=
6617 Make_Function_Specification (Loc,
6618 Defining_Unit_Name => Fnam,
6619 Result_Definition => New_Occurrence_Of (RTE (RE_TypeCode), Loc));
6621 PolyORB_Support.Helpers.Build_Name_And_Repository_Id
6622 (RAS_Type, Name_Str => Name_String, Repo_Id_Str => Repo_Id_String);
6624 Discard_Node (
6625 Make_Subprogram_Body (Loc,
6626 Specification => Func_Spec,
6627 Declarations => Decls,
6628 Handled_Statement_Sequence =>
6629 Make_Handled_Sequence_Of_Statements (Loc,
6630 Statements => New_List (
6631 Make_Simple_Return_Statement (Loc,
6632 Expression =>
6633 Make_Function_Call (Loc,
6634 Name =>
6635 New_Occurrence_Of (RTE (RE_Build_Complex_TC), Loc),
6636 Parameter_Associations => New_List (
6637 New_Occurrence_Of (RTE (RE_Tk_Objref), Loc),
6638 Make_Aggregate (Loc,
6639 Expressions =>
6640 New_List (
6641 Make_Function_Call (Loc,
6642 Name =>
6643 New_Occurrence_Of
6644 (RTE (RE_TA_Std_String), Loc),
6645 Parameter_Associations => New_List (
6646 Make_String_Literal (Loc, Name_String))),
6647 Make_Function_Call (Loc,
6648 Name =>
6649 New_Occurrence_Of
6650 (RTE (RE_TA_Std_String), Loc),
6651 Parameter_Associations => New_List (
6652 Make_String_Literal (Loc,
6653 Strval => Repo_Id_String))))))))))));
6654 Set_TSS (RAS_Type, Fnam);
6655 end Add_RAS_TypeCode;
6657 -----------------------------------------
6658 -- Add_Receiving_Stubs_To_Declarations --
6659 -----------------------------------------
6661 procedure Add_Receiving_Stubs_To_Declarations
6662 (Pkg_Spec : Node_Id;
6663 Decls : List_Id;
6664 Stmts : List_Id)
6666 Loc : constant Source_Ptr := Sloc (Pkg_Spec);
6668 Pkg_RPC_Receiver : constant Entity_Id :=
6669 Make_Temporary (Loc, 'H');
6670 Pkg_RPC_Receiver_Object : Node_Id;
6671 Pkg_RPC_Receiver_Body : Node_Id;
6672 Pkg_RPC_Receiver_Decls : List_Id;
6673 Pkg_RPC_Receiver_Statements : List_Id;
6675 Pkg_RPC_Receiver_Cases : constant List_Id := New_List;
6676 -- A Pkg_RPC_Receiver is built to decode the request
6678 Request : Node_Id;
6679 -- Request object received from neutral layer
6681 Subp_Id : Entity_Id;
6682 -- Subprogram identifier as received from the neutral distribution
6683 -- core.
6685 Subp_Index : Entity_Id;
6686 -- Internal index as determined by matching either the method name
6687 -- from the request structure, or the local subprogram address (in
6688 -- case of a RAS).
6690 Is_Local : constant Entity_Id := Make_Temporary (Loc, 'L');
6692 Local_Address : constant Entity_Id := Make_Temporary (Loc, 'A');
6693 -- Address of a local subprogram designated by a reference
6694 -- corresponding to a RAS.
6696 Dispatch_On_Address : constant List_Id := New_List;
6697 Dispatch_On_Name : constant List_Id := New_List;
6699 Current_Subp_Number : Int := First_RCI_Subprogram_Id;
6701 Subp_Info_Array : constant Entity_Id := Make_Temporary (Loc, 'I');
6702 Subp_Info_List : constant List_Id := New_List;
6704 Register_Pkg_Actuals : constant List_Id := New_List;
6706 All_Calls_Remote_E : Entity_Id;
6708 procedure Append_Stubs_To
6709 (RPC_Receiver_Cases : List_Id;
6710 Declaration : Node_Id;
6711 Stubs : Node_Id;
6712 Subp_Number : Int;
6713 Subp_Dist_Name : Entity_Id;
6714 Subp_Proxy_Addr : Entity_Id);
6715 -- Add one case to the specified RPC receiver case list associating
6716 -- Subprogram_Number with the subprogram declared by Declaration, for
6717 -- which we have receiving stubs in Stubs. Subp_Number is an internal
6718 -- subprogram index. Subp_Dist_Name is the string used to call the
6719 -- subprogram by name, and Subp_Dist_Addr is the address of the proxy
6720 -- object, used in the context of calls through remote
6721 -- access-to-subprogram types.
6723 procedure Visit_Subprogram (Decl : Node_Id);
6724 -- Generate receiving stub for one remote subprogram
6726 ---------------------
6727 -- Append_Stubs_To --
6728 ---------------------
6730 procedure Append_Stubs_To
6731 (RPC_Receiver_Cases : List_Id;
6732 Declaration : Node_Id;
6733 Stubs : Node_Id;
6734 Subp_Number : Int;
6735 Subp_Dist_Name : Entity_Id;
6736 Subp_Proxy_Addr : Entity_Id)
6738 Case_Stmts : List_Id;
6739 begin
6740 Case_Stmts := New_List (
6741 Make_Procedure_Call_Statement (Loc,
6742 Name =>
6743 New_Occurrence_Of (
6744 Defining_Entity (Stubs), Loc),
6745 Parameter_Associations =>
6746 New_List (New_Occurrence_Of (Request, Loc))));
6748 if Nkind (Specification (Declaration)) = N_Function_Specification
6749 or else not
6750 Is_Asynchronous (Defining_Entity (Specification (Declaration)))
6751 then
6752 Append_To (Case_Stmts, Make_Simple_Return_Statement (Loc));
6753 end if;
6755 Append_To (RPC_Receiver_Cases,
6756 Make_Case_Statement_Alternative (Loc,
6757 Discrete_Choices =>
6758 New_List (Make_Integer_Literal (Loc, Subp_Number)),
6759 Statements => Case_Stmts));
6761 Append_To (Dispatch_On_Name,
6762 Make_Elsif_Part (Loc,
6763 Condition =>
6764 Make_Function_Call (Loc,
6765 Name =>
6766 New_Occurrence_Of (RTE (RE_Caseless_String_Eq), Loc),
6767 Parameter_Associations => New_List (
6768 New_Occurrence_Of (Subp_Id, Loc),
6769 New_Occurrence_Of (Subp_Dist_Name, Loc))),
6771 Then_Statements => New_List (
6772 Make_Assignment_Statement (Loc,
6773 New_Occurrence_Of (Subp_Index, Loc),
6774 Make_Integer_Literal (Loc, Subp_Number)))));
6776 Append_To (Dispatch_On_Address,
6777 Make_Elsif_Part (Loc,
6778 Condition =>
6779 Make_Op_Eq (Loc,
6780 Left_Opnd => New_Occurrence_Of (Local_Address, Loc),
6781 Right_Opnd => New_Occurrence_Of (Subp_Proxy_Addr, Loc)),
6783 Then_Statements => New_List (
6784 Make_Assignment_Statement (Loc,
6785 New_Occurrence_Of (Subp_Index, Loc),
6786 Make_Integer_Literal (Loc, Subp_Number)))));
6787 end Append_Stubs_To;
6789 ----------------------
6790 -- Visit_Subprogram --
6791 ----------------------
6793 procedure Visit_Subprogram (Decl : Node_Id) is
6794 Loc : constant Source_Ptr := Sloc (Decl);
6795 Spec : constant Node_Id := Specification (Decl);
6796 Subp_Def : constant Entity_Id := Defining_Unit_Name (Spec);
6798 Subp_Val : String_Id;
6800 Subp_Dist_Name : constant Entity_Id :=
6801 Make_Defining_Identifier (Loc,
6802 Chars =>
6803 New_External_Name
6804 (Related_Id => Chars (Subp_Def),
6805 Suffix => 'D',
6806 Suffix_Index => -1));
6808 Current_Stubs : Node_Id;
6809 Proxy_Obj_Addr : Entity_Id;
6811 begin
6812 -- Disable expansion of stubs if serious errors have been
6813 -- diagnosed, because otherwise some illegal remote subprogram
6814 -- declarations could cause cascaded errors in stubs.
6816 if Serious_Errors_Detected /= 0 then
6817 return;
6818 end if;
6820 -- Build receiving stub
6822 Current_Stubs :=
6823 Build_Subprogram_Receiving_Stubs
6824 (Vis_Decl => Decl,
6825 Asynchronous => Nkind (Spec) = N_Procedure_Specification
6826 and then Is_Asynchronous (Subp_Def));
6828 Append_To (Decls, Current_Stubs);
6829 Analyze (Current_Stubs);
6831 -- Build RAS proxy
6833 Add_RAS_Proxy_And_Analyze (Decls,
6834 Vis_Decl => Decl,
6835 All_Calls_Remote_E => All_Calls_Remote_E,
6836 Proxy_Object_Addr => Proxy_Obj_Addr);
6838 -- Compute distribution identifier
6840 Assign_Subprogram_Identifier
6841 (Subp_Def, Current_Subp_Number, Subp_Val);
6843 pragma Assert
6844 (Current_Subp_Number = Get_Subprogram_Id (Subp_Def));
6846 Append_To (Decls,
6847 Make_Object_Declaration (Loc,
6848 Defining_Identifier => Subp_Dist_Name,
6849 Constant_Present => True,
6850 Object_Definition =>
6851 New_Occurrence_Of (Standard_String, Loc),
6852 Expression =>
6853 Make_String_Literal (Loc, Subp_Val)));
6854 Analyze (Last (Decls));
6856 -- Add subprogram descriptor (RCI_Subp_Info) to the subprograms
6857 -- table for this receiver. The aggregate below must be kept
6858 -- consistent with the declaration of RCI_Subp_Info in
6859 -- System.Partition_Interface.
6861 Append_To (Subp_Info_List,
6862 Make_Component_Association (Loc,
6863 Choices =>
6864 New_List (Make_Integer_Literal (Loc, Current_Subp_Number)),
6866 Expression =>
6867 Make_Aggregate (Loc,
6868 Expressions => New_List (
6870 -- Name =>
6872 Make_Attribute_Reference (Loc,
6873 Prefix =>
6874 New_Occurrence_Of (Subp_Dist_Name, Loc),
6875 Attribute_Name => Name_Address),
6877 -- Name_Length =>
6879 Make_Attribute_Reference (Loc,
6880 Prefix =>
6881 New_Occurrence_Of (Subp_Dist_Name, Loc),
6882 Attribute_Name => Name_Length),
6884 -- Addr =>
6886 New_Occurrence_Of (Proxy_Obj_Addr, Loc)))));
6888 Append_Stubs_To (Pkg_RPC_Receiver_Cases,
6889 Declaration => Decl,
6890 Stubs => Current_Stubs,
6891 Subp_Number => Current_Subp_Number,
6892 Subp_Dist_Name => Subp_Dist_Name,
6893 Subp_Proxy_Addr => Proxy_Obj_Addr);
6895 Current_Subp_Number := Current_Subp_Number + 1;
6896 end Visit_Subprogram;
6898 procedure Visit_Spec is new Build_Package_Stubs (Visit_Subprogram);
6900 -- Start of processing for Add_Receiving_Stubs_To_Declarations
6902 begin
6903 -- Building receiving stubs consist in several operations:
6905 -- - a package RPC receiver must be built. This subprogram will get
6906 -- a Subprogram_Id from the incoming stream and will dispatch the
6907 -- call to the right subprogram;
6909 -- - a receiving stub for each subprogram visible in the package
6910 -- spec. This stub will read all the parameters from the stream,
6911 -- and put the result as well as the exception occurrence in the
6912 -- output stream;
6914 Build_RPC_Receiver_Body (
6915 RPC_Receiver => Pkg_RPC_Receiver,
6916 Request => Request,
6917 Subp_Id => Subp_Id,
6918 Subp_Index => Subp_Index,
6919 Stmts => Pkg_RPC_Receiver_Statements,
6920 Decl => Pkg_RPC_Receiver_Body);
6921 Pkg_RPC_Receiver_Decls := Declarations (Pkg_RPC_Receiver_Body);
6923 -- Extract local address information from the target reference:
6924 -- if non-null, that means that this is a reference that denotes
6925 -- one particular operation, and hence that the operation name
6926 -- must not be taken into account for dispatching.
6928 Append_To (Pkg_RPC_Receiver_Decls,
6929 Make_Object_Declaration (Loc,
6930 Defining_Identifier => Is_Local,
6931 Object_Definition =>
6932 New_Occurrence_Of (Standard_Boolean, Loc)));
6934 Append_To (Pkg_RPC_Receiver_Decls,
6935 Make_Object_Declaration (Loc,
6936 Defining_Identifier => Local_Address,
6937 Object_Definition =>
6938 New_Occurrence_Of (RTE (RE_Address), Loc)));
6940 Append_To (Pkg_RPC_Receiver_Statements,
6941 Make_Procedure_Call_Statement (Loc,
6942 Name => New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
6943 Parameter_Associations => New_List (
6944 Make_Selected_Component (Loc,
6945 Prefix => Request,
6946 Selector_Name => Name_Target),
6947 New_Occurrence_Of (Is_Local, Loc),
6948 New_Occurrence_Of (Local_Address, Loc))));
6950 -- For each subprogram, the receiving stub will be built and a case
6951 -- statement will be made on the Subprogram_Id to dispatch to the
6952 -- right subprogram.
6954 All_Calls_Remote_E := Boolean_Literals (
6955 Has_All_Calls_Remote (Defining_Entity (Pkg_Spec)));
6957 Overload_Counter_Table.Reset;
6958 Reserve_NamingContext_Methods;
6960 Visit_Spec (Pkg_Spec);
6962 Append_To (Decls,
6963 Make_Object_Declaration (Loc,
6964 Defining_Identifier => Subp_Info_Array,
6965 Constant_Present => True,
6966 Aliased_Present => True,
6967 Object_Definition =>
6968 Make_Subtype_Indication (Loc,
6969 Subtype_Mark =>
6970 New_Occurrence_Of (RTE (RE_RCI_Subp_Info_Array), Loc),
6971 Constraint =>
6972 Make_Index_Or_Discriminant_Constraint (Loc,
6973 New_List (
6974 Make_Range (Loc,
6975 Low_Bound =>
6976 Make_Integer_Literal (Loc,
6977 Intval => First_RCI_Subprogram_Id),
6978 High_Bound =>
6979 Make_Integer_Literal (Loc,
6980 Intval =>
6981 First_RCI_Subprogram_Id
6982 + List_Length (Subp_Info_List) - 1)))))));
6984 if Present (First (Subp_Info_List)) then
6985 Set_Expression (Last (Decls),
6986 Make_Aggregate (Loc,
6987 Component_Associations => Subp_Info_List));
6989 -- Generate the dispatch statement to determine the subprogram id
6990 -- of the called subprogram.
6992 -- We first test whether the reference that was used to make the
6993 -- call was the base RCI reference (in which case Local_Address is
6994 -- zero, and the method identifier from the request must be used
6995 -- to determine which subprogram is called) or a reference
6996 -- identifying one particular subprogram (in which case
6997 -- Local_Address is the address of that subprogram, and the
6998 -- method name from the request is ignored). The latter occurs
6999 -- for the case of a call through a remote access-to-subprogram.
7001 -- In each case, cascaded elsifs are used to determine the proper
7002 -- subprogram index. Using hash tables might be more efficient.
7004 Append_To (Pkg_RPC_Receiver_Statements,
7005 Make_Implicit_If_Statement (Pkg_Spec,
7006 Condition =>
7007 Make_Op_Ne (Loc,
7008 Left_Opnd => New_Occurrence_Of (Local_Address, Loc),
7009 Right_Opnd => New_Occurrence_Of
7010 (RTE (RE_Null_Address), Loc)),
7012 Then_Statements => New_List (
7013 Make_Implicit_If_Statement (Pkg_Spec,
7014 Condition => New_Occurrence_Of (Standard_False, Loc),
7015 Then_Statements => New_List (
7016 Make_Null_Statement (Loc)),
7017 Elsif_Parts => Dispatch_On_Address)),
7019 Else_Statements => New_List (
7020 Make_Implicit_If_Statement (Pkg_Spec,
7021 Condition => New_Occurrence_Of (Standard_False, Loc),
7022 Then_Statements => New_List (Make_Null_Statement (Loc)),
7023 Elsif_Parts => Dispatch_On_Name))));
7025 else
7026 -- For a degenerate RCI with no visible subprograms,
7027 -- Subp_Info_List has zero length, and the declaration is for an
7028 -- empty array, in which case no initialization aggregate must be
7029 -- generated. We do not generate a Dispatch_Statement either.
7031 -- No initialization provided: remove CONSTANT so that the
7032 -- declaration is not an incomplete deferred constant.
7034 Set_Constant_Present (Last (Decls), False);
7035 end if;
7037 -- Analyze Subp_Info_Array declaration
7039 Analyze (Last (Decls));
7041 -- If we receive an invalid Subprogram_Id, it is best to do nothing
7042 -- rather than raising an exception since we do not want someone
7043 -- to crash a remote partition by sending invalid subprogram ids.
7044 -- This is consistent with the other parts of the case statement
7045 -- since even in presence of incorrect parameters in the stream,
7046 -- every exception will be caught and (if the subprogram is not an
7047 -- APC) put into the result stream and sent away.
7049 Append_To (Pkg_RPC_Receiver_Cases,
7050 Make_Case_Statement_Alternative (Loc,
7051 Discrete_Choices => New_List (Make_Others_Choice (Loc)),
7052 Statements => New_List (Make_Null_Statement (Loc))));
7054 Append_To (Pkg_RPC_Receiver_Statements,
7055 Make_Case_Statement (Loc,
7056 Expression => New_Occurrence_Of (Subp_Index, Loc),
7057 Alternatives => Pkg_RPC_Receiver_Cases));
7059 -- Pkg_RPC_Receiver body is now complete: insert it into the tree and
7060 -- analyze it.
7062 Append_To (Decls, Pkg_RPC_Receiver_Body);
7063 Analyze (Last (Decls));
7065 Pkg_RPC_Receiver_Object :=
7066 Make_Object_Declaration (Loc,
7067 Defining_Identifier => Make_Temporary (Loc, 'R'),
7068 Aliased_Present => True,
7069 Object_Definition => New_Occurrence_Of (RTE (RE_Servant), Loc));
7070 Append_To (Decls, Pkg_RPC_Receiver_Object);
7071 Analyze (Last (Decls));
7073 -- Name
7075 Append_To (Register_Pkg_Actuals,
7076 Make_String_Literal (Loc,
7077 Strval =>
7078 Fully_Qualified_Name_String
7079 (Defining_Entity (Pkg_Spec), Append_NUL => False)));
7081 -- Version
7083 Append_To (Register_Pkg_Actuals,
7084 Make_Attribute_Reference (Loc,
7085 Prefix =>
7086 New_Occurrence_Of
7087 (Defining_Entity (Pkg_Spec), Loc),
7088 Attribute_Name => Name_Version));
7090 -- Handler
7092 Append_To (Register_Pkg_Actuals,
7093 Make_Attribute_Reference (Loc,
7094 Prefix =>
7095 New_Occurrence_Of (Pkg_RPC_Receiver, Loc),
7096 Attribute_Name => Name_Access));
7098 -- Receiver
7100 Append_To (Register_Pkg_Actuals,
7101 Make_Attribute_Reference (Loc,
7102 Prefix =>
7103 New_Occurrence_Of (
7104 Defining_Identifier (Pkg_RPC_Receiver_Object), Loc),
7105 Attribute_Name => Name_Access));
7107 -- Subp_Info
7109 Append_To (Register_Pkg_Actuals,
7110 Make_Attribute_Reference (Loc,
7111 Prefix => New_Occurrence_Of (Subp_Info_Array, Loc),
7112 Attribute_Name => Name_Address));
7114 -- Subp_Info_Len
7116 Append_To (Register_Pkg_Actuals,
7117 Make_Attribute_Reference (Loc,
7118 Prefix => New_Occurrence_Of (Subp_Info_Array, Loc),
7119 Attribute_Name => Name_Length));
7121 -- Is_All_Calls_Remote
7123 Append_To (Register_Pkg_Actuals,
7124 New_Occurrence_Of (All_Calls_Remote_E, Loc));
7126 -- Finally call Register_Pkg_Receiving_Stub with the above parameters
7128 Append_To (Stmts,
7129 Make_Procedure_Call_Statement (Loc,
7130 Name =>
7131 New_Occurrence_Of (RTE (RE_Register_Pkg_Receiving_Stub), Loc),
7132 Parameter_Associations => Register_Pkg_Actuals));
7133 Analyze (Last (Stmts));
7134 end Add_Receiving_Stubs_To_Declarations;
7136 ---------------------------------
7137 -- Build_General_Calling_Stubs --
7138 ---------------------------------
7140 procedure Build_General_Calling_Stubs
7141 (Decls : List_Id;
7142 Statements : List_Id;
7143 Target_Object : Node_Id;
7144 Subprogram_Id : Node_Id;
7145 Asynchronous : Node_Id := Empty;
7146 Is_Known_Asynchronous : Boolean := False;
7147 Is_Known_Non_Asynchronous : Boolean := False;
7148 Is_Function : Boolean;
7149 Spec : Node_Id;
7150 Stub_Type : Entity_Id := Empty;
7151 RACW_Type : Entity_Id := Empty;
7152 Nod : Node_Id)
7154 Loc : constant Source_Ptr := Sloc (Nod);
7156 Request : constant Entity_Id := Make_Temporary (Loc, 'R');
7157 -- The request object constructed by these stubs
7158 -- Could we use Name_R instead??? (see GLADE client stubs)
7160 function Make_Request_RTE_Call
7161 (RE : RE_Id;
7162 Actuals : List_Id := New_List) return Node_Id;
7163 -- Generate a procedure call statement calling RE with the given
7164 -- actuals. Request'Access is appended to the list.
7166 ---------------------------
7167 -- Make_Request_RTE_Call --
7168 ---------------------------
7170 function Make_Request_RTE_Call
7171 (RE : RE_Id;
7172 Actuals : List_Id := New_List) return Node_Id
7174 begin
7175 Append_To (Actuals,
7176 Make_Attribute_Reference (Loc,
7177 Prefix => New_Occurrence_Of (Request, Loc),
7178 Attribute_Name => Name_Access));
7179 return Make_Procedure_Call_Statement (Loc,
7180 Name =>
7181 New_Occurrence_Of (RTE (RE), Loc),
7182 Parameter_Associations => Actuals);
7183 end Make_Request_RTE_Call;
7185 Arguments : Node_Id;
7186 -- Name of the named values list used to transmit parameters
7187 -- to the remote package
7189 Result : Node_Id;
7190 -- Name of the result named value (in non-APC cases) which get the
7191 -- result of the remote subprogram.
7193 Result_TC : Node_Id;
7194 -- Typecode expression for the result of the request (void
7195 -- typecode for procedures).
7197 Exception_Return_Parameter : Node_Id;
7198 -- Name of the parameter which will hold the exception sent by the
7199 -- remote subprogram.
7201 Current_Parameter : Node_Id;
7202 -- Current parameter being handled
7204 Ordered_Parameters_List : constant List_Id :=
7205 Build_Ordered_Parameters_List (Spec);
7207 Asynchronous_P : Node_Id;
7208 -- A Boolean expression indicating whether this call is asynchronous
7210 Asynchronous_Statements : List_Id := No_List;
7211 Non_Asynchronous_Statements : List_Id := No_List;
7212 -- Statements specifics to the Asynchronous/Non-Asynchronous cases
7214 Extra_Formal_Statements : constant List_Id := New_List;
7215 -- List of statements for extra formal parameters. It will appear
7216 -- after the regular statements for writing out parameters.
7218 After_Statements : constant List_Id := New_List;
7219 -- Statements to be executed after call returns (to assign IN OUT or
7220 -- OUT parameter values).
7222 Etyp : Entity_Id;
7223 -- The type of the formal parameter being processed
7225 Is_Controlling_Formal : Boolean;
7226 Is_First_Controlling_Formal : Boolean;
7227 First_Controlling_Formal_Seen : Boolean := False;
7228 -- Controlling formal parameters of distributed object primitives
7229 -- require special handling, and the first such parameter needs even
7230 -- more special handling.
7232 begin
7233 -- ??? document general form of stub subprograms for the PolyORB case
7235 Append_To (Decls,
7236 Make_Object_Declaration (Loc,
7237 Defining_Identifier => Request,
7238 Aliased_Present => True,
7239 Object_Definition =>
7240 New_Occurrence_Of (RTE (RE_Request), Loc)));
7242 Result := Make_Temporary (Loc, 'R');
7244 if Is_Function then
7245 Result_TC :=
7246 PolyORB_Support.Helpers.Build_TypeCode_Call
7247 (Loc, Etype (Result_Definition (Spec)), Decls);
7248 else
7249 Result_TC := New_Occurrence_Of (RTE (RE_TC_Void), Loc);
7250 end if;
7252 Append_To (Decls,
7253 Make_Object_Declaration (Loc,
7254 Defining_Identifier => Result,
7255 Aliased_Present => False,
7256 Object_Definition =>
7257 New_Occurrence_Of (RTE (RE_NamedValue), Loc),
7258 Expression =>
7259 Make_Aggregate (Loc,
7260 Component_Associations => New_List (
7261 Make_Component_Association (Loc,
7262 Choices => New_List (Make_Identifier (Loc, Name_Name)),
7263 Expression =>
7264 New_Occurrence_Of (RTE (RE_Result_Name), Loc)),
7265 Make_Component_Association (Loc,
7266 Choices => New_List (
7267 Make_Identifier (Loc, Name_Argument)),
7268 Expression =>
7269 Make_Function_Call (Loc,
7270 Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc),
7271 Parameter_Associations => New_List (Result_TC))),
7272 Make_Component_Association (Loc,
7273 Choices => New_List (
7274 Make_Identifier (Loc, Name_Arg_Modes)),
7275 Expression => Make_Integer_Literal (Loc, 0))))));
7277 if not Is_Known_Asynchronous then
7278 Exception_Return_Parameter := Make_Temporary (Loc, 'E');
7280 Append_To (Decls,
7281 Make_Object_Declaration (Loc,
7282 Defining_Identifier => Exception_Return_Parameter,
7283 Object_Definition =>
7284 New_Occurrence_Of (RTE (RE_Exception_Occurrence), Loc)));
7286 else
7287 Exception_Return_Parameter := Empty;
7288 end if;
7290 -- Initialize and fill in arguments list
7292 Arguments := Make_Temporary (Loc, 'A');
7293 Declare_Create_NVList (Loc, Arguments, Decls, Statements);
7295 Current_Parameter := First (Ordered_Parameters_List);
7296 while Present (Current_Parameter) loop
7297 if Is_RACW_Controlling_Formal (Current_Parameter, Stub_Type) then
7298 Is_Controlling_Formal := True;
7299 Is_First_Controlling_Formal :=
7300 not First_Controlling_Formal_Seen;
7301 First_Controlling_Formal_Seen := True;
7303 else
7304 Is_Controlling_Formal := False;
7305 Is_First_Controlling_Formal := False;
7306 end if;
7308 if Is_Controlling_Formal then
7310 -- For a controlling formal argument, we send its reference
7312 Etyp := RACW_Type;
7314 else
7315 Etyp := Etype (Parameter_Type (Current_Parameter));
7316 end if;
7318 -- The first controlling formal parameter is treated specially:
7319 -- it is used to set the target object of the call.
7321 if not Is_First_Controlling_Formal then
7322 declare
7323 Constrained : constant Boolean :=
7324 Is_Constrained (Etyp)
7325 or else Is_Elementary_Type (Etyp);
7327 Any : constant Entity_Id := Make_Temporary (Loc, 'A');
7329 Actual_Parameter : Node_Id :=
7330 New_Occurrence_Of (
7331 Defining_Identifier (
7332 Current_Parameter), Loc);
7334 Expr : Node_Id;
7336 begin
7337 if Is_Controlling_Formal then
7339 -- For a controlling formal parameter (other than the
7340 -- first one), use the corresponding RACW. If the
7341 -- parameter is not an anonymous access parameter, that
7342 -- involves taking its 'Unrestricted_Access.
7344 if Nkind (Parameter_Type (Current_Parameter))
7345 = N_Access_Definition
7346 then
7347 Actual_Parameter := OK_Convert_To
7348 (Etyp, Actual_Parameter);
7349 else
7350 Actual_Parameter := OK_Convert_To (Etyp,
7351 Make_Attribute_Reference (Loc,
7352 Prefix => Actual_Parameter,
7353 Attribute_Name => Name_Unrestricted_Access));
7354 end if;
7356 end if;
7358 if In_Present (Current_Parameter)
7359 or else not Out_Present (Current_Parameter)
7360 or else not Constrained
7361 or else Is_Controlling_Formal
7362 then
7363 -- The parameter has an input value, is constrained at
7364 -- runtime by an input value, or is a controlling formal
7365 -- parameter (always passed as a reference) other than
7366 -- the first one.
7368 Expr := PolyORB_Support.Helpers.Build_To_Any_Call
7369 (Loc, Actual_Parameter, Decls);
7371 else
7372 Expr := Make_Function_Call (Loc,
7373 Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc),
7374 Parameter_Associations => New_List (
7375 PolyORB_Support.Helpers.Build_TypeCode_Call
7376 (Loc, Etyp, Decls)));
7377 end if;
7379 Append_To (Decls,
7380 Make_Object_Declaration (Loc,
7381 Defining_Identifier => Any,
7382 Aliased_Present => False,
7383 Object_Definition =>
7384 New_Occurrence_Of (RTE (RE_Any), Loc),
7385 Expression => Expr));
7387 Append_To (Statements,
7388 Add_Parameter_To_NVList (Loc,
7389 Parameter => Current_Parameter,
7390 NVList => Arguments,
7391 Constrained => Constrained,
7392 Any => Any));
7394 if Out_Present (Current_Parameter)
7395 and then not Is_Controlling_Formal
7396 then
7397 if Is_Limited_Type (Etyp) then
7398 Helpers.Assign_Opaque_From_Any (Loc,
7399 Stms => After_Statements,
7400 Typ => Etyp,
7401 N => New_Occurrence_Of (Any, Loc),
7402 Target =>
7403 Defining_Identifier (Current_Parameter),
7404 Constrained => True);
7406 else
7407 Append_To (After_Statements,
7408 Make_Assignment_Statement (Loc,
7409 Name =>
7410 New_Occurrence_Of (
7411 Defining_Identifier (Current_Parameter), Loc),
7412 Expression =>
7413 PolyORB_Support.Helpers.Build_From_Any_Call
7414 (Etyp,
7415 New_Occurrence_Of (Any, Loc),
7416 Decls)));
7417 end if;
7418 end if;
7419 end;
7420 end if;
7422 -- If the current parameter has a dynamic constrained status, then
7423 -- this status is transmitted as well.
7425 -- This should be done for accessibility as well ???
7427 if Nkind (Parameter_Type (Current_Parameter)) /=
7428 N_Access_Definition
7429 and then Need_Extra_Constrained (Current_Parameter)
7430 then
7431 -- In this block, we do not use the extra formal that has been
7432 -- created because it does not exist at the time of expansion
7433 -- when building calling stubs for remote access to subprogram
7434 -- types. We create an extra variable of this type and push it
7435 -- in the stream after the regular parameters.
7437 declare
7438 Extra_Any_Parameter : constant Entity_Id :=
7439 Make_Temporary (Loc, 'P');
7441 Parameter_Exp : constant Node_Id :=
7442 Make_Attribute_Reference (Loc,
7443 Prefix => New_Occurrence_Of (
7444 Defining_Identifier (Current_Parameter), Loc),
7445 Attribute_Name => Name_Constrained);
7447 begin
7448 Set_Etype (Parameter_Exp, Etype (Standard_Boolean));
7450 Append_To (Decls,
7451 Make_Object_Declaration (Loc,
7452 Defining_Identifier => Extra_Any_Parameter,
7453 Aliased_Present => False,
7454 Object_Definition =>
7455 New_Occurrence_Of (RTE (RE_Any), Loc),
7456 Expression =>
7457 PolyORB_Support.Helpers.Build_To_Any_Call
7458 (Loc, Parameter_Exp, Decls)));
7460 Append_To (Extra_Formal_Statements,
7461 Add_Parameter_To_NVList (Loc,
7462 Parameter => Extra_Any_Parameter,
7463 NVList => Arguments,
7464 Constrained => True,
7465 Any => Extra_Any_Parameter));
7466 end;
7467 end if;
7469 Next (Current_Parameter);
7470 end loop;
7472 -- Append the formal statements list to the statements
7474 Append_List_To (Statements, Extra_Formal_Statements);
7476 Append_To (Statements,
7477 Make_Procedure_Call_Statement (Loc,
7478 Name =>
7479 New_Occurrence_Of (RTE (RE_Request_Setup), Loc),
7480 Parameter_Associations => New_List (
7481 New_Occurrence_Of (Request, Loc),
7482 Target_Object,
7483 Subprogram_Id,
7484 New_Occurrence_Of (Arguments, Loc),
7485 New_Occurrence_Of (Result, Loc),
7486 New_Occurrence_Of (RTE (RE_Nil_Exc_List), Loc))));
7488 pragma Assert
7489 (not (Is_Known_Non_Asynchronous and Is_Known_Asynchronous));
7491 if Is_Known_Non_Asynchronous or Is_Known_Asynchronous then
7492 Asynchronous_P :=
7493 New_Occurrence_Of
7494 (Boolean_Literals (Is_Known_Asynchronous), Loc);
7496 else
7497 pragma Assert (Present (Asynchronous));
7498 Asynchronous_P := New_Copy_Tree (Asynchronous);
7500 -- The expression node Asynchronous will be used to build an 'if'
7501 -- statement at the end of Build_General_Calling_Stubs: we need to
7502 -- make a copy here.
7503 end if;
7505 Append_To (Parameter_Associations (Last (Statements)),
7506 Make_Indexed_Component (Loc,
7507 Prefix =>
7508 New_Occurrence_Of (
7509 RTE (RE_Asynchronous_P_To_Sync_Scope), Loc),
7510 Expressions => New_List (Asynchronous_P)));
7512 Append_To (Statements, Make_Request_RTE_Call (RE_Request_Invoke));
7514 -- Asynchronous case
7516 if not Is_Known_Non_Asynchronous then
7517 Asynchronous_Statements := New_List (Make_Null_Statement (Loc));
7518 end if;
7520 -- Non-asynchronous case
7522 if not Is_Known_Asynchronous then
7523 -- Reraise an exception occurrence from the completed request.
7524 -- If the exception occurrence is empty, this is a no-op.
7526 Non_Asynchronous_Statements := New_List (
7527 Make_Procedure_Call_Statement (Loc,
7528 Name =>
7529 New_Occurrence_Of (RTE (RE_Request_Raise_Occurrence), Loc),
7530 Parameter_Associations => New_List (
7531 New_Occurrence_Of (Request, Loc))));
7533 if Is_Function then
7534 -- If this is a function call, read the value and return it
7536 Append_To (Non_Asynchronous_Statements,
7537 Make_Tag_Check (Loc,
7538 Make_Simple_Return_Statement (Loc,
7539 PolyORB_Support.Helpers.Build_From_Any_Call
7540 (Etype (Result_Definition (Spec)),
7541 Make_Selected_Component (Loc,
7542 Prefix => Result,
7543 Selector_Name => Name_Argument),
7544 Decls))));
7546 else
7548 -- Case of a procedure: deal with IN OUT and OUT formals
7550 Append_List_To (Non_Asynchronous_Statements, After_Statements);
7551 end if;
7552 end if;
7554 if Is_Known_Asynchronous then
7555 Append_List_To (Statements, Asynchronous_Statements);
7557 elsif Is_Known_Non_Asynchronous then
7558 Append_List_To (Statements, Non_Asynchronous_Statements);
7560 else
7561 pragma Assert (Present (Asynchronous));
7562 Append_To (Statements,
7563 Make_Implicit_If_Statement (Nod,
7564 Condition => Asynchronous,
7565 Then_Statements => Asynchronous_Statements,
7566 Else_Statements => Non_Asynchronous_Statements));
7567 end if;
7568 end Build_General_Calling_Stubs;
7570 -----------------------
7571 -- Build_Stub_Target --
7572 -----------------------
7574 function Build_Stub_Target
7575 (Loc : Source_Ptr;
7576 Decls : List_Id;
7577 RCI_Locator : Entity_Id;
7578 Controlling_Parameter : Entity_Id) return RPC_Target
7580 Target_Info : RPC_Target (PCS_Kind => Name_PolyORB_DSA);
7581 Target_Reference : constant Entity_Id := Make_Temporary (Loc, 'T');
7583 begin
7584 if Present (Controlling_Parameter) then
7585 Append_To (Decls,
7586 Make_Object_Declaration (Loc,
7587 Defining_Identifier => Target_Reference,
7589 Object_Definition =>
7590 New_Occurrence_Of (RTE (RE_Object_Ref), Loc),
7592 Expression =>
7593 Make_Function_Call (Loc,
7594 Name =>
7595 New_Occurrence_Of (RTE (RE_Make_Ref), Loc),
7596 Parameter_Associations => New_List (
7597 Make_Selected_Component (Loc,
7598 Prefix => Controlling_Parameter,
7599 Selector_Name => Name_Target)))));
7601 -- Note: Controlling_Parameter has the same components as
7602 -- System.Partition_Interface.RACW_Stub_Type.
7604 Target_Info.Object := New_Occurrence_Of (Target_Reference, Loc);
7606 else
7607 Target_Info.Object :=
7608 Make_Selected_Component (Loc,
7609 Prefix =>
7610 Make_Identifier (Loc, Chars (RCI_Locator)),
7611 Selector_Name =>
7612 Make_Identifier (Loc, Name_Get_RCI_Package_Ref));
7613 end if;
7615 return Target_Info;
7616 end Build_Stub_Target;
7618 -----------------------------
7619 -- Build_RPC_Receiver_Body --
7620 -----------------------------
7622 procedure Build_RPC_Receiver_Body
7623 (RPC_Receiver : Entity_Id;
7624 Request : out Entity_Id;
7625 Subp_Id : out Entity_Id;
7626 Subp_Index : out Entity_Id;
7627 Stmts : out List_Id;
7628 Decl : out Node_Id)
7630 Loc : constant Source_Ptr := Sloc (RPC_Receiver);
7632 RPC_Receiver_Spec : Node_Id;
7633 RPC_Receiver_Decls : List_Id;
7635 begin
7636 Request := Make_Defining_Identifier (Loc, Name_R);
7638 RPC_Receiver_Spec :=
7639 Build_RPC_Receiver_Specification
7640 (RPC_Receiver => RPC_Receiver,
7641 Request_Parameter => Request);
7643 Subp_Id := Make_Defining_Identifier (Loc, Name_P);
7644 Subp_Index := Make_Defining_Identifier (Loc, Name_I);
7646 RPC_Receiver_Decls := New_List (
7647 Make_Object_Renaming_Declaration (Loc,
7648 Defining_Identifier => Subp_Id,
7649 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
7650 Name =>
7651 Make_Explicit_Dereference (Loc,
7652 Prefix =>
7653 Make_Selected_Component (Loc,
7654 Prefix => Request,
7655 Selector_Name => Name_Operation))),
7657 Make_Object_Declaration (Loc,
7658 Defining_Identifier => Subp_Index,
7659 Object_Definition =>
7660 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
7661 Expression =>
7662 Make_Attribute_Reference (Loc,
7663 Prefix =>
7664 New_Occurrence_Of (RTE (RE_Subprogram_Id), Loc),
7665 Attribute_Name => Name_Last)));
7667 Stmts := New_List;
7669 Decl :=
7670 Make_Subprogram_Body (Loc,
7671 Specification => RPC_Receiver_Spec,
7672 Declarations => RPC_Receiver_Decls,
7673 Handled_Statement_Sequence =>
7674 Make_Handled_Sequence_Of_Statements (Loc,
7675 Statements => Stmts));
7676 end Build_RPC_Receiver_Body;
7678 --------------------------------------
7679 -- Build_Subprogram_Receiving_Stubs --
7680 --------------------------------------
7682 function Build_Subprogram_Receiving_Stubs
7683 (Vis_Decl : Node_Id;
7684 Asynchronous : Boolean;
7685 Dynamically_Asynchronous : Boolean := False;
7686 Stub_Type : Entity_Id := Empty;
7687 RACW_Type : Entity_Id := Empty;
7688 Parent_Primitive : Entity_Id := Empty) return Node_Id
7690 Loc : constant Source_Ptr := Sloc (Vis_Decl);
7692 Request_Parameter : constant Entity_Id := Make_Temporary (Loc, 'R');
7693 -- Formal parameter for receiving stubs: a descriptor for an incoming
7694 -- request.
7696 Outer_Decls : constant List_Id := New_List;
7697 -- At the outermost level, an NVList and Any's are declared for all
7698 -- parameters. The Dynamic_Async flag also needs to be declared there
7699 -- to be visible from the exception handling code.
7701 Outer_Statements : constant List_Id := New_List;
7702 -- Statements that occur prior to the declaration of the actual
7703 -- parameter variables.
7705 Outer_Extra_Formal_Statements : constant List_Id := New_List;
7706 -- Statements concerning extra formal parameters, prior to the
7707 -- declaration of the actual parameter variables.
7709 Decls : constant List_Id := New_List;
7710 -- All the parameters will get declared before calling the real
7711 -- subprograms. Also the out parameters will be declared. At this
7712 -- level, parameters may be unconstrained.
7714 Statements : constant List_Id := New_List;
7716 After_Statements : constant List_Id := New_List;
7717 -- Statements to be executed after the subprogram call
7719 Inner_Decls : List_Id := No_List;
7720 -- In case of a function, the inner declarations are needed since
7721 -- the result may be unconstrained.
7723 Excep_Handlers : List_Id := No_List;
7725 Parameter_List : constant List_Id := New_List;
7726 -- List of parameters to be passed to the subprogram
7728 First_Controlling_Formal_Seen : Boolean := False;
7730 Current_Parameter : Node_Id;
7732 Ordered_Parameters_List : constant List_Id :=
7733 Build_Ordered_Parameters_List
7734 (Specification (Vis_Decl));
7736 Arguments : constant Entity_Id := Make_Temporary (Loc, 'A');
7737 -- Name of the named values list used to retrieve parameters
7739 Subp_Spec : Node_Id;
7740 -- Subprogram specification
7742 Called_Subprogram : Node_Id;
7743 -- The subprogram to call
7745 begin
7746 if Present (RACW_Type) then
7747 Called_Subprogram :=
7748 New_Occurrence_Of (Parent_Primitive, Loc);
7749 else
7750 Called_Subprogram :=
7751 New_Occurrence_Of
7752 (Defining_Unit_Name (Specification (Vis_Decl)), Loc);
7753 end if;
7755 Declare_Create_NVList (Loc, Arguments, Outer_Decls, Outer_Statements);
7757 -- Loop through every parameter and get its value from the stream. If
7758 -- the parameter is unconstrained, then the parameter is read using
7759 -- 'Input at the point of declaration.
7761 Current_Parameter := First (Ordered_Parameters_List);
7762 while Present (Current_Parameter) loop
7763 declare
7764 Etyp : Entity_Id;
7765 Constrained : Boolean;
7766 Any : Entity_Id := Empty;
7767 Object : constant Entity_Id := Make_Temporary (Loc, 'P');
7768 Expr : Node_Id := Empty;
7770 Is_Controlling_Formal : constant Boolean :=
7771 Is_RACW_Controlling_Formal
7772 (Current_Parameter, Stub_Type);
7774 Is_First_Controlling_Formal : Boolean := False;
7776 Need_Extra_Constrained : Boolean;
7777 -- True when an extra constrained actual is required
7779 begin
7780 if Is_Controlling_Formal then
7782 -- Controlling formals in distributed object primitive
7783 -- operations are handled specially:
7785 -- - the first controlling formal is used as the
7786 -- target of the call;
7788 -- - the remaining controlling formals are transmitted
7789 -- as RACWs.
7791 Etyp := RACW_Type;
7792 Is_First_Controlling_Formal :=
7793 not First_Controlling_Formal_Seen;
7794 First_Controlling_Formal_Seen := True;
7796 else
7797 Etyp := Etype (Parameter_Type (Current_Parameter));
7798 end if;
7800 Constrained :=
7801 Is_Constrained (Etyp) or else Is_Elementary_Type (Etyp);
7803 if not Is_First_Controlling_Formal then
7804 Any := Make_Temporary (Loc, 'A');
7806 Append_To (Outer_Decls,
7807 Make_Object_Declaration (Loc,
7808 Defining_Identifier => Any,
7809 Object_Definition =>
7810 New_Occurrence_Of (RTE (RE_Any), Loc),
7811 Expression =>
7812 Make_Function_Call (Loc,
7813 Name => New_Occurrence_Of (RTE (RE_Create_Any), Loc),
7814 Parameter_Associations => New_List (
7815 PolyORB_Support.Helpers.Build_TypeCode_Call
7816 (Loc, Etyp, Outer_Decls)))));
7818 Append_To (Outer_Statements,
7819 Add_Parameter_To_NVList (Loc,
7820 Parameter => Current_Parameter,
7821 NVList => Arguments,
7822 Constrained => Constrained,
7823 Any => Any));
7824 end if;
7826 if Is_First_Controlling_Formal then
7827 declare
7828 Addr : constant Entity_Id := Make_Temporary (Loc, 'A');
7830 Is_Local : constant Entity_Id :=
7831 Make_Temporary (Loc, 'L');
7833 begin
7834 -- Special case: obtain the first controlling formal
7835 -- from the target of the remote call, instead of the
7836 -- argument list.
7838 Append_To (Outer_Decls,
7839 Make_Object_Declaration (Loc,
7840 Defining_Identifier => Addr,
7841 Object_Definition =>
7842 New_Occurrence_Of (RTE (RE_Address), Loc)));
7844 Append_To (Outer_Decls,
7845 Make_Object_Declaration (Loc,
7846 Defining_Identifier => Is_Local,
7847 Object_Definition =>
7848 New_Occurrence_Of (Standard_Boolean, Loc)));
7850 Append_To (Outer_Statements,
7851 Make_Procedure_Call_Statement (Loc,
7852 Name =>
7853 New_Occurrence_Of (RTE (RE_Get_Local_Address), Loc),
7854 Parameter_Associations => New_List (
7855 Make_Selected_Component (Loc,
7856 Prefix =>
7857 New_Occurrence_Of (
7858 Request_Parameter, Loc),
7859 Selector_Name =>
7860 Make_Identifier (Loc, Name_Target)),
7861 New_Occurrence_Of (Is_Local, Loc),
7862 New_Occurrence_Of (Addr, Loc))));
7864 Expr := Unchecked_Convert_To (RACW_Type,
7865 New_Occurrence_Of (Addr, Loc));
7866 end;
7868 elsif In_Present (Current_Parameter)
7869 or else not Out_Present (Current_Parameter)
7870 or else not Constrained
7871 then
7872 -- If an input parameter is constrained, then its reading is
7873 -- deferred until the beginning of the subprogram body. If
7874 -- it is unconstrained, then an expression is built for
7875 -- the object declaration and the variable is set using
7876 -- 'Input instead of 'Read.
7878 if Constrained and then Is_Limited_Type (Etyp) then
7879 Helpers.Assign_Opaque_From_Any (Loc,
7880 Stms => Statements,
7881 Typ => Etyp,
7882 N => New_Occurrence_Of (Any, Loc),
7883 Target => Object);
7885 else
7886 Expr := Helpers.Build_From_Any_Call
7887 (Etyp, New_Occurrence_Of (Any, Loc), Decls);
7889 if Constrained then
7890 Append_To (Statements,
7891 Make_Assignment_Statement (Loc,
7892 Name => New_Occurrence_Of (Object, Loc),
7893 Expression => Expr));
7894 Expr := Empty;
7896 else
7897 -- Expr will be used to initialize (and constrain) the
7898 -- parameter when it is declared.
7899 null;
7900 end if;
7902 null;
7903 end if;
7904 end if;
7906 Need_Extra_Constrained :=
7907 Nkind (Parameter_Type (Current_Parameter)) /=
7908 N_Access_Definition
7909 and then
7910 Ekind (Defining_Identifier (Current_Parameter)) /= E_Void
7911 and then
7912 Present (Extra_Constrained
7913 (Defining_Identifier (Current_Parameter)));
7915 -- We may not associate an extra constrained actual to a
7916 -- constant object, so if one is needed, declare the actual
7917 -- as a variable even if it won't be modified.
7919 Build_Actual_Object_Declaration
7920 (Object => Object,
7921 Etyp => Etyp,
7922 Variable => Need_Extra_Constrained
7923 or else Out_Present (Current_Parameter),
7924 Expr => Expr,
7925 Decls => Decls);
7926 Set_Etype (Object, Etyp);
7928 -- An out parameter may be written back using a 'Write
7929 -- attribute instead of a 'Output because it has been
7930 -- constrained by the parameter given to the caller. Note that
7931 -- OUT controlling arguments in the case of a RACW are not put
7932 -- back in the stream because the pointer on them has not
7933 -- changed.
7935 if Out_Present (Current_Parameter)
7936 and then not Is_Controlling_Formal
7937 then
7938 Append_To (After_Statements,
7939 Make_Procedure_Call_Statement (Loc,
7940 Name => New_Occurrence_Of (RTE (RE_Move_Any_Value), Loc),
7941 Parameter_Associations => New_List (
7942 New_Occurrence_Of (Any, Loc),
7943 PolyORB_Support.Helpers.Build_To_Any_Call
7944 (Loc,
7945 New_Occurrence_Of (Object, Loc),
7946 Decls,
7947 Constrained => True))));
7948 end if;
7950 -- For RACW controlling formals, the Etyp of Object is always
7951 -- an RACW, even if the parameter is not of an anonymous access
7952 -- type. In such case, we need to dereference it at call time.
7954 if Is_Controlling_Formal then
7955 if Nkind (Parameter_Type (Current_Parameter)) /=
7956 N_Access_Definition
7957 then
7958 Append_To (Parameter_List,
7959 Make_Parameter_Association (Loc,
7960 Selector_Name =>
7961 New_Occurrence_Of
7962 (Defining_Identifier (Current_Parameter), Loc),
7963 Explicit_Actual_Parameter =>
7964 Make_Explicit_Dereference (Loc,
7965 Prefix => New_Occurrence_Of (Object, Loc))));
7967 else
7968 Append_To (Parameter_List,
7969 Make_Parameter_Association (Loc,
7970 Selector_Name =>
7971 New_Occurrence_Of
7972 (Defining_Identifier (Current_Parameter), Loc),
7974 Explicit_Actual_Parameter =>
7975 New_Occurrence_Of (Object, Loc)));
7976 end if;
7978 else
7979 Append_To (Parameter_List,
7980 Make_Parameter_Association (Loc,
7981 Selector_Name =>
7982 New_Occurrence_Of (
7983 Defining_Identifier (Current_Parameter), Loc),
7984 Explicit_Actual_Parameter =>
7985 New_Occurrence_Of (Object, Loc)));
7986 end if;
7988 -- If the current parameter needs an extra formal, then read it
7989 -- from the stream and set the corresponding semantic field in
7990 -- the variable. If the kind of the parameter identifier is
7991 -- E_Void, then this is a compiler generated parameter that
7992 -- doesn't need an extra constrained status.
7994 -- The case of Extra_Accessibility should also be handled ???
7996 if Need_Extra_Constrained then
7997 declare
7998 Extra_Parameter : constant Entity_Id :=
7999 Extra_Constrained
8000 (Defining_Identifier
8001 (Current_Parameter));
8003 Extra_Any : constant Entity_Id :=
8004 Make_Temporary (Loc, 'A');
8006 Formal_Entity : constant Entity_Id :=
8007 Make_Defining_Identifier (Loc,
8008 Chars => Chars (Extra_Parameter));
8010 Formal_Type : constant Entity_Id :=
8011 Etype (Extra_Parameter);
8013 begin
8014 Append_To (Outer_Decls,
8015 Make_Object_Declaration (Loc,
8016 Defining_Identifier => Extra_Any,
8017 Object_Definition =>
8018 New_Occurrence_Of (RTE (RE_Any), Loc),
8019 Expression =>
8020 Make_Function_Call (Loc,
8021 Name =>
8022 New_Occurrence_Of (RTE (RE_Create_Any), Loc),
8023 Parameter_Associations => New_List (
8024 PolyORB_Support.Helpers.Build_TypeCode_Call
8025 (Loc, Formal_Type, Outer_Decls)))));
8027 Append_To (Outer_Extra_Formal_Statements,
8028 Add_Parameter_To_NVList (Loc,
8029 Parameter => Extra_Parameter,
8030 NVList => Arguments,
8031 Constrained => True,
8032 Any => Extra_Any));
8034 Append_To (Decls,
8035 Make_Object_Declaration (Loc,
8036 Defining_Identifier => Formal_Entity,
8037 Object_Definition =>
8038 New_Occurrence_Of (Formal_Type, Loc)));
8040 Append_To (Statements,
8041 Make_Assignment_Statement (Loc,
8042 Name => New_Occurrence_Of (Formal_Entity, Loc),
8043 Expression =>
8044 PolyORB_Support.Helpers.Build_From_Any_Call
8045 (Formal_Type,
8046 New_Occurrence_Of (Extra_Any, Loc),
8047 Decls)));
8048 Set_Extra_Constrained (Object, Formal_Entity);
8049 end;
8050 end if;
8051 end;
8053 Next (Current_Parameter);
8054 end loop;
8056 -- Extra Formals should go after all the other parameters
8058 Append_List_To (Outer_Statements, Outer_Extra_Formal_Statements);
8060 Append_To (Outer_Statements,
8061 Make_Procedure_Call_Statement (Loc,
8062 Name => New_Occurrence_Of (RTE (RE_Request_Arguments), Loc),
8063 Parameter_Associations => New_List (
8064 New_Occurrence_Of (Request_Parameter, Loc),
8065 New_Occurrence_Of (Arguments, Loc))));
8067 if Nkind (Specification (Vis_Decl)) = N_Function_Specification then
8069 -- The remote subprogram is a function: Build an inner block to be
8070 -- able to hold a potentially unconstrained result in a variable.
8072 declare
8073 Etyp : constant Entity_Id :=
8074 Etype (Result_Definition (Specification (Vis_Decl)));
8075 Result : constant Node_Id := Make_Temporary (Loc, 'R');
8077 begin
8078 Inner_Decls := New_List (
8079 Make_Object_Declaration (Loc,
8080 Defining_Identifier => Result,
8081 Constant_Present => True,
8082 Object_Definition => New_Occurrence_Of (Etyp, Loc),
8083 Expression =>
8084 Make_Function_Call (Loc,
8085 Name => Called_Subprogram,
8086 Parameter_Associations => Parameter_List)));
8088 if Is_Class_Wide_Type (Etyp) then
8090 -- For a remote call to a function with a class-wide type,
8091 -- check that the returned value satisfies the requirements
8092 -- of (RM E.4(18)).
8094 Append_To (Inner_Decls,
8095 Make_Transportable_Check (Loc,
8096 New_Occurrence_Of (Result, Loc)));
8098 end if;
8100 Set_Etype (Result, Etyp);
8101 Append_To (After_Statements,
8102 Make_Procedure_Call_Statement (Loc,
8103 Name => New_Occurrence_Of (RTE (RE_Set_Result), Loc),
8104 Parameter_Associations => New_List (
8105 New_Occurrence_Of (Request_Parameter, Loc),
8106 PolyORB_Support.Helpers.Build_To_Any_Call
8107 (Loc, New_Occurrence_Of (Result, Loc), Decls))));
8109 -- A DSA function does not have out or inout arguments
8110 end;
8112 Append_To (Statements,
8113 Make_Block_Statement (Loc,
8114 Declarations => Inner_Decls,
8115 Handled_Statement_Sequence =>
8116 Make_Handled_Sequence_Of_Statements (Loc,
8117 Statements => After_Statements)));
8119 else
8120 -- The remote subprogram is a procedure. We do not need any inner
8121 -- block in this case. No specific processing is required here for
8122 -- the dynamically asynchronous case: the indication of whether
8123 -- call is asynchronous or not is managed by the Sync_Scope
8124 -- attibute of the request, and is handled entirely in the
8125 -- protocol layer.
8127 Append_To (After_Statements,
8128 Make_Procedure_Call_Statement (Loc,
8129 Name => New_Occurrence_Of (RTE (RE_Request_Set_Out), Loc),
8130 Parameter_Associations => New_List (
8131 New_Occurrence_Of (Request_Parameter, Loc))));
8133 Append_To (Statements,
8134 Make_Procedure_Call_Statement (Loc,
8135 Name => Called_Subprogram,
8136 Parameter_Associations => Parameter_List));
8138 Append_List_To (Statements, After_Statements);
8139 end if;
8141 Subp_Spec :=
8142 Make_Procedure_Specification (Loc,
8143 Defining_Unit_Name => Make_Temporary (Loc, 'F'),
8145 Parameter_Specifications => New_List (
8146 Make_Parameter_Specification (Loc,
8147 Defining_Identifier => Request_Parameter,
8148 Parameter_Type =>
8149 New_Occurrence_Of (RTE (RE_Request_Access), Loc))));
8151 -- An exception raised during the execution of an incoming remote
8152 -- subprogram call and that needs to be sent back to the caller is
8153 -- propagated by the receiving stubs, and will be handled by the
8154 -- caller (the distribution runtime).
8156 if Asynchronous and then not Dynamically_Asynchronous then
8158 -- For an asynchronous procedure, add a null exception handler
8160 Excep_Handlers := New_List (
8161 Make_Implicit_Exception_Handler (Loc,
8162 Exception_Choices => New_List (Make_Others_Choice (Loc)),
8163 Statements => New_List (Make_Null_Statement (Loc))));
8165 else
8166 -- In the other cases, if an exception is raised, then the
8167 -- exception occurrence is propagated.
8169 null;
8170 end if;
8172 Append_To (Outer_Statements,
8173 Make_Block_Statement (Loc,
8174 Declarations => Decls,
8175 Handled_Statement_Sequence =>
8176 Make_Handled_Sequence_Of_Statements (Loc,
8177 Statements => Statements)));
8179 return
8180 Make_Subprogram_Body (Loc,
8181 Specification => Subp_Spec,
8182 Declarations => Outer_Decls,
8183 Handled_Statement_Sequence =>
8184 Make_Handled_Sequence_Of_Statements (Loc,
8185 Statements => Outer_Statements,
8186 Exception_Handlers => Excep_Handlers));
8187 end Build_Subprogram_Receiving_Stubs;
8189 -------------
8190 -- Helpers --
8191 -------------
8193 package body Helpers is
8195 -----------------------
8196 -- Local Subprograms --
8197 -----------------------
8199 function Find_Numeric_Representation
8200 (Typ : Entity_Id) return Entity_Id;
8201 -- Given a numeric type Typ, return the smallest integer or modular
8202 -- type from Interfaces, or the smallest floating point type from
8203 -- Standard whose range encompasses that of Typ.
8205 function Is_Generic_Actual_Subtype (Typ : Entity_Id) return Boolean;
8206 -- Return true if Typ is a subtype representing a generic formal type
8207 -- as a subtype of the actual type in an instance. This is needed to
8208 -- recognize these subtypes because the Is_Generic_Actual_Type flag
8209 -- can only be relied upon within the instance.
8211 function Make_Helper_Function_Name
8212 (Loc : Source_Ptr;
8213 Typ : Entity_Id;
8214 Nam : Name_Id) return Entity_Id;
8215 -- Return the name to be assigned for helper subprogram Nam of Typ
8217 ------------------------------------------------------------
8218 -- Common subprograms for building various tree fragments --
8219 ------------------------------------------------------------
8221 function Build_Get_Aggregate_Element
8222 (Loc : Source_Ptr;
8223 Any : Entity_Id;
8224 TC : Node_Id;
8225 Idx : Node_Id) return Node_Id;
8226 -- Build a call to Get_Aggregate_Element on Any for typecode TC,
8227 -- returning the Idx'th element.
8229 generic
8230 Subprogram : Entity_Id;
8231 -- Reference location for constructed nodes
8233 Arry : Entity_Id;
8234 -- For 'Range and Etype
8236 Indexes : List_Id;
8237 -- For the construction of the innermost element expression
8239 with procedure Add_Process_Element
8240 (Stmts : List_Id;
8241 Any : Entity_Id;
8242 Counter : Entity_Id;
8243 Datum : Node_Id);
8245 procedure Append_Array_Traversal
8246 (Stmts : List_Id;
8247 Any : Entity_Id;
8248 Counter : Entity_Id := Empty;
8249 Depth : Pos := 1);
8250 -- Build nested loop statements that iterate over the elements of an
8251 -- array Arry. The statement(s) built by Add_Process_Element are
8252 -- executed for each element; Indexes is the list of indexes to be
8253 -- used in the construction of the indexed component that denotes the
8254 -- current element. Subprogram is the entity for the subprogram for
8255 -- which this iterator is generated. The generated statements are
8256 -- appended to Stmts.
8258 generic
8259 Rec : Entity_Id;
8260 -- The record entity being dealt with
8262 with procedure Add_Process_Element
8263 (Stmts : List_Id;
8264 Container : Node_Or_Entity_Id;
8265 Counter : in out Nat;
8266 Rec : Entity_Id;
8267 Field : Node_Id);
8268 -- Rec is the instance of the record type, or Empty.
8269 -- Field is either the N_Defining_Identifier for a component,
8270 -- or an N_Variant_Part.
8272 procedure Append_Record_Traversal
8273 (Stmts : List_Id;
8274 Clist : Node_Id;
8275 Container : Node_Or_Entity_Id;
8276 Counter : in out Nat);
8277 -- Process component list Clist. Individual fields are passed
8278 -- to Field_Processing. Each variant part is also processed.
8279 -- Container is the outer Any (for From_Any/To_Any),
8280 -- the outer typecode (for TC) to which the operation applies.
8282 -----------------------------
8283 -- Append_Record_Traversal --
8284 -----------------------------
8286 procedure Append_Record_Traversal
8287 (Stmts : List_Id;
8288 Clist : Node_Id;
8289 Container : Node_Or_Entity_Id;
8290 Counter : in out Nat)
8292 CI : List_Id;
8293 VP : Node_Id;
8294 -- Clist's Component_Items and Variant_Part
8296 Item : Node_Id;
8297 Def : Entity_Id;
8299 begin
8300 if No (Clist) then
8301 return;
8302 end if;
8304 CI := Component_Items (Clist);
8305 VP := Variant_Part (Clist);
8307 Item := First_Non_Pragma (CI);
8308 while Present (Item) loop
8309 Def := Defining_Identifier (Item);
8311 if not Is_Internal_Name (Chars (Def)) then
8312 Add_Process_Element
8313 (Stmts, Container, Counter, Rec, Def);
8314 end if;
8316 Next_Non_Pragma (Item);
8317 end loop;
8319 if Present (VP) then
8320 Add_Process_Element (Stmts, Container, Counter, Rec, VP);
8321 end if;
8322 end Append_Record_Traversal;
8324 -----------------------------
8325 -- Assign_Opaque_From_Any --
8326 -----------------------------
8328 procedure Assign_Opaque_From_Any
8329 (Loc : Source_Ptr;
8330 Stms : List_Id;
8331 Typ : Entity_Id;
8332 N : Node_Id;
8333 Target : Entity_Id;
8334 Constrained : Boolean := False)
8336 Strm : constant Entity_Id := Make_Temporary (Loc, 'S');
8337 Expr : Node_Id;
8339 Read_Call_List : List_Id;
8340 -- List on which to place the 'Read attribute reference
8342 begin
8343 -- Strm : Buffer_Stream_Type;
8345 Append_To (Stms,
8346 Make_Object_Declaration (Loc,
8347 Defining_Identifier => Strm,
8348 Aliased_Present => True,
8349 Object_Definition =>
8350 New_Occurrence_Of (RTE (RE_Buffer_Stream_Type), Loc)));
8352 -- Any_To_BS (Strm, A);
8354 Append_To (Stms,
8355 Make_Procedure_Call_Statement (Loc,
8356 Name => New_Occurrence_Of (RTE (RE_Any_To_BS), Loc),
8357 Parameter_Associations => New_List (
8359 New_Occurrence_Of (Strm, Loc))));
8361 if Transmit_As_Unconstrained (Typ) and then not Constrained then
8362 Expr :=
8363 Make_Attribute_Reference (Loc,
8364 Prefix => New_Occurrence_Of (Typ, Loc),
8365 Attribute_Name => Name_Input,
8366 Expressions => New_List (
8367 Make_Attribute_Reference (Loc,
8368 Prefix => New_Occurrence_Of (Strm, Loc),
8369 Attribute_Name => Name_Access)));
8371 -- Target := Typ'Input (Strm'Access)
8373 if Present (Target) then
8374 Append_To (Stms,
8375 Make_Assignment_Statement (Loc,
8376 Name => New_Occurrence_Of (Target, Loc),
8377 Expression => Expr));
8379 -- return Typ'Input (Strm'Access);
8381 else
8382 Append_To (Stms,
8383 Make_Simple_Return_Statement (Loc,
8384 Expression => Expr));
8385 end if;
8387 else
8388 if Present (Target) then
8389 Read_Call_List := Stms;
8390 Expr := New_Occurrence_Of (Target, Loc);
8392 else
8393 declare
8394 Temp : constant Entity_Id := Make_Temporary (Loc, 'R');
8396 begin
8397 Read_Call_List := New_List;
8398 Expr := New_Occurrence_Of (Temp, Loc);
8400 Append_To (Stms, Make_Block_Statement (Loc,
8401 Declarations => New_List (
8402 Make_Object_Declaration (Loc,
8403 Defining_Identifier =>
8404 Temp,
8405 Object_Definition =>
8406 New_Occurrence_Of (Typ, Loc))),
8408 Handled_Statement_Sequence =>
8409 Make_Handled_Sequence_Of_Statements (Loc,
8410 Statements => Read_Call_List)));
8411 end;
8412 end if;
8414 -- Typ'Read (Strm'Access, [Target|Temp])
8416 Append_To (Read_Call_List,
8417 Make_Attribute_Reference (Loc,
8418 Prefix => New_Occurrence_Of (Typ, Loc),
8419 Attribute_Name => Name_Read,
8420 Expressions => New_List (
8421 Make_Attribute_Reference (Loc,
8422 Prefix => New_Occurrence_Of (Strm, Loc),
8423 Attribute_Name => Name_Access),
8424 Expr)));
8426 if No (Target) then
8428 -- return Temp
8430 Append_To (Read_Call_List,
8431 Make_Simple_Return_Statement (Loc,
8432 Expression => New_Copy (Expr)));
8433 end if;
8434 end if;
8435 end Assign_Opaque_From_Any;
8437 -------------------------
8438 -- Build_From_Any_Call --
8439 -------------------------
8441 function Build_From_Any_Call
8442 (Typ : Entity_Id;
8443 N : Node_Id;
8444 Decls : List_Id) return Node_Id
8446 Loc : constant Source_Ptr := Sloc (N);
8448 U_Type : Entity_Id := Underlying_Type (Typ);
8450 Fnam : Entity_Id;
8451 Lib_RE : RE_Id := RE_Null;
8452 Result : Node_Id;
8454 begin
8455 -- First simple case where the From_Any function is present
8456 -- in the type's TSS.
8458 Fnam := Find_Inherited_TSS (U_Type, TSS_From_Any);
8460 -- For the subtype representing a generic actual type, go to the
8461 -- actual type.
8463 if Is_Generic_Actual_Subtype (U_Type) then
8464 U_Type := Underlying_Type (Base_Type (U_Type));
8465 end if;
8467 -- For a standard subtype, go to the base type
8469 if Sloc (U_Type) <= Standard_Location then
8470 U_Type := Base_Type (U_Type);
8472 -- For a user subtype, go to first subtype
8474 elsif Comes_From_Source (U_Type)
8475 and then Nkind (Declaration_Node (U_Type))
8476 = N_Subtype_Declaration
8477 then
8478 U_Type := First_Subtype (U_Type);
8479 end if;
8481 -- Check first for Boolean and Character. These are enumeration
8482 -- types, but we treat them specially, since they may require
8483 -- special handling in the transfer protocol. However, this
8484 -- special handling only applies if they have standard
8485 -- representation, otherwise they are treated like any other
8486 -- enumeration type.
8488 if Present (Fnam) then
8489 null;
8491 elsif U_Type = Standard_Boolean then
8492 Lib_RE := RE_FA_B;
8494 elsif U_Type = Standard_Character then
8495 Lib_RE := RE_FA_C;
8497 elsif U_Type = Standard_Wide_Character then
8498 Lib_RE := RE_FA_WC;
8500 elsif U_Type = Standard_Wide_Wide_Character then
8501 Lib_RE := RE_FA_WWC;
8503 -- Floating point types
8505 elsif U_Type = Standard_Short_Float then
8506 Lib_RE := RE_FA_SF;
8508 elsif U_Type = Standard_Float then
8509 Lib_RE := RE_FA_F;
8511 elsif U_Type = Standard_Long_Float then
8512 Lib_RE := RE_FA_LF;
8514 elsif U_Type = Standard_Long_Long_Float then
8515 Lib_RE := RE_FA_LLF;
8517 -- Integer types
8519 elsif U_Type = RTE (RE_Integer_8) then
8520 Lib_RE := RE_FA_I8;
8522 elsif U_Type = RTE (RE_Integer_16) then
8523 Lib_RE := RE_FA_I16;
8525 elsif U_Type = RTE (RE_Integer_32) then
8526 Lib_RE := RE_FA_I32;
8528 elsif U_Type = RTE (RE_Integer_64) then
8529 Lib_RE := RE_FA_I64;
8531 -- Unsigned integer types
8533 elsif U_Type = RTE (RE_Unsigned_8) then
8534 Lib_RE := RE_FA_U8;
8536 elsif U_Type = RTE (RE_Unsigned_16) then
8537 Lib_RE := RE_FA_U16;
8539 elsif U_Type = RTE (RE_Unsigned_32) then
8540 Lib_RE := RE_FA_U32;
8542 elsif U_Type = RTE (RE_Unsigned_64) then
8543 Lib_RE := RE_FA_U64;
8545 elsif Is_RTE (U_Type, RE_Unbounded_String) then
8546 Lib_RE := RE_FA_String;
8548 -- Special DSA types
8550 elsif Is_RTE (U_Type, RE_Any_Container_Ptr) then
8551 Lib_RE := RE_FA_A;
8553 -- Other (non-primitive) types
8555 else
8556 declare
8557 Decl : Entity_Id;
8559 begin
8560 Build_From_Any_Function (Loc, U_Type, Decl, Fnam);
8561 Append_To (Decls, Decl);
8562 end;
8563 end if;
8565 -- Call the function
8567 if Lib_RE /= RE_Null then
8568 pragma Assert (No (Fnam));
8569 Fnam := RTE (Lib_RE);
8570 end if;
8572 Result :=
8573 Make_Function_Call (Loc,
8574 Name => New_Occurrence_Of (Fnam, Loc),
8575 Parameter_Associations => New_List (N));
8577 -- We must set the type of Result, so the unchecked conversion
8578 -- from the underlying type to the base type is properly done.
8580 Set_Etype (Result, U_Type);
8582 return Unchecked_Convert_To (Typ, Result);
8583 end Build_From_Any_Call;
8585 -----------------------------
8586 -- Build_From_Any_Function --
8587 -----------------------------
8589 procedure Build_From_Any_Function
8590 (Loc : Source_Ptr;
8591 Typ : Entity_Id;
8592 Decl : out Node_Id;
8593 Fnam : out Entity_Id)
8595 Spec : Node_Id;
8596 Decls : constant List_Id := New_List;
8597 Stms : constant List_Id := New_List;
8599 Any_Parameter : constant Entity_Id := Make_Temporary (Loc, 'A');
8601 Use_Opaque_Representation : Boolean;
8603 Real_Rep : Node_Id;
8605 begin
8606 -- For a derived type, we can't go past the base type (to the
8607 -- parent type) here, because that would cause the attribute's
8608 -- formal parameter to have the wrong type; hence the Base_Type
8609 -- check here.
8611 if Is_Itype (Typ) and then Typ /= Base_Type (Typ) then
8612 Build_From_Any_Function
8613 (Loc => Loc,
8614 Typ => Etype (Typ),
8615 Decl => Decl,
8616 Fnam => Fnam);
8617 return;
8618 end if;
8620 Fnam := Make_Helper_Function_Name (Loc, Typ, Name_From_Any);
8622 Spec :=
8623 Make_Function_Specification (Loc,
8624 Defining_Unit_Name => Fnam,
8625 Parameter_Specifications => New_List (
8626 Make_Parameter_Specification (Loc,
8627 Defining_Identifier => Any_Parameter,
8628 Parameter_Type => New_Occurrence_Of (RTE (RE_Any), Loc))),
8629 Result_Definition => New_Occurrence_Of (Typ, Loc));
8631 -- The RACW case is taken care of by Exp_Dist.Add_RACW_From_Any
8633 pragma Assert
8634 (not (Is_Remote_Access_To_Class_Wide_Type (Typ)));
8636 Use_Opaque_Representation := False;
8638 if Has_Stream_Attribute_Definition
8639 (Typ, TSS_Stream_Output, Real_Rep, At_Any_Place => True)
8640 or else
8641 Has_Stream_Attribute_Definition
8642 (Typ, TSS_Stream_Write, Real_Rep, At_Any_Place => True)
8643 then
8644 -- If user-defined stream attributes are specified for this
8645 -- type, use them and transmit data as an opaque sequence of
8646 -- stream elements.
8648 Use_Opaque_Representation := True;
8650 elsif Is_Derived_Type (Typ) and then not Is_Tagged_Type (Typ) then
8651 Append_To (Stms,
8652 Make_Simple_Return_Statement (Loc,
8653 Expression =>
8654 OK_Convert_To (Typ,
8655 Build_From_Any_Call
8656 (Root_Type (Typ),
8657 New_Occurrence_Of (Any_Parameter, Loc),
8658 Decls))));
8660 elsif Is_Record_Type (Typ)
8661 and then not Is_Derived_Type (Typ)
8662 and then not Is_Tagged_Type (Typ)
8663 then
8664 if Nkind (Declaration_Node (Typ)) = N_Subtype_Declaration then
8665 Append_To (Stms,
8666 Make_Simple_Return_Statement (Loc,
8667 Expression =>
8668 Build_From_Any_Call
8669 (Etype (Typ),
8670 New_Occurrence_Of (Any_Parameter, Loc),
8671 Decls)));
8673 else
8674 declare
8675 Disc : Entity_Id := Empty;
8676 Discriminant_Associations : List_Id;
8677 Rdef : constant Node_Id :=
8678 Type_Definition
8679 (Declaration_Node (Typ));
8680 Component_Counter : Nat := 0;
8682 -- The returned object
8684 Res : constant Entity_Id := Make_Temporary (Loc, 'R');
8686 Res_Definition : Node_Id := New_Occurrence_Of (Typ, Loc);
8688 procedure FA_Rec_Add_Process_Element
8689 (Stmts : List_Id;
8690 Any : Entity_Id;
8691 Counter : in out Nat;
8692 Rec : Entity_Id;
8693 Field : Node_Id);
8695 procedure FA_Append_Record_Traversal is
8696 new Append_Record_Traversal
8697 (Rec => Res,
8698 Add_Process_Element => FA_Rec_Add_Process_Element);
8700 --------------------------------
8701 -- FA_Rec_Add_Process_Element --
8702 --------------------------------
8704 procedure FA_Rec_Add_Process_Element
8705 (Stmts : List_Id;
8706 Any : Entity_Id;
8707 Counter : in out Nat;
8708 Rec : Entity_Id;
8709 Field : Node_Id)
8711 Ctyp : Entity_Id;
8712 begin
8713 if Nkind (Field) = N_Defining_Identifier then
8714 -- A regular component
8716 Ctyp := Etype (Field);
8718 Append_To (Stmts,
8719 Make_Assignment_Statement (Loc,
8720 Name => Make_Selected_Component (Loc,
8721 Prefix =>
8722 New_Occurrence_Of (Rec, Loc),
8723 Selector_Name =>
8724 New_Occurrence_Of (Field, Loc)),
8726 Expression =>
8727 Build_From_Any_Call (Ctyp,
8728 Build_Get_Aggregate_Element (Loc,
8729 Any => Any,
8730 TC =>
8731 Build_TypeCode_Call (Loc, Ctyp, Decls),
8732 Idx =>
8733 Make_Integer_Literal (Loc, Counter)),
8734 Decls)));
8736 else
8737 -- A variant part
8739 declare
8740 Variant : Node_Id;
8741 Struct_Counter : Nat := 0;
8743 Block_Decls : constant List_Id := New_List;
8744 Block_Stmts : constant List_Id := New_List;
8745 VP_Stmts : List_Id;
8747 Alt_List : constant List_Id := New_List;
8748 Choice_List : List_Id;
8750 Struct_Any : constant Entity_Id :=
8751 Make_Temporary (Loc, 'S');
8753 begin
8754 Append_To (Decls,
8755 Make_Object_Declaration (Loc,
8756 Defining_Identifier => Struct_Any,
8757 Constant_Present => True,
8758 Object_Definition =>
8759 New_Occurrence_Of (RTE (RE_Any), Loc),
8760 Expression =>
8761 Make_Function_Call (Loc,
8762 Name =>
8763 New_Occurrence_Of
8764 (RTE (RE_Extract_Union_Value), Loc),
8766 Parameter_Associations => New_List (
8767 Build_Get_Aggregate_Element (Loc,
8768 Any => Any,
8769 TC =>
8770 Make_Function_Call (Loc,
8771 Name => New_Occurrence_Of (
8772 RTE (RE_Any_Member_Type), Loc),
8773 Parameter_Associations =>
8774 New_List (
8775 New_Occurrence_Of (Any, Loc),
8776 Make_Integer_Literal (Loc,
8777 Intval => Counter))),
8778 Idx =>
8779 Make_Integer_Literal (Loc,
8780 Intval => Counter))))));
8782 Append_To (Stmts,
8783 Make_Block_Statement (Loc,
8784 Declarations => Block_Decls,
8785 Handled_Statement_Sequence =>
8786 Make_Handled_Sequence_Of_Statements (Loc,
8787 Statements => Block_Stmts)));
8789 Append_To (Block_Stmts,
8790 Make_Case_Statement (Loc,
8791 Expression =>
8792 Make_Selected_Component (Loc,
8793 Prefix => Rec,
8794 Selector_Name => Chars (Name (Field))),
8795 Alternatives => Alt_List));
8797 Variant := First_Non_Pragma (Variants (Field));
8798 while Present (Variant) loop
8799 Choice_List :=
8800 New_Copy_List_Tree
8801 (Discrete_Choices (Variant));
8803 VP_Stmts := New_List;
8805 -- Struct_Counter should be reset before
8806 -- handling a variant part. Indeed only one
8807 -- of the case statement alternatives will be
8808 -- executed at run time, so the counter must
8809 -- start at 0 for every case statement.
8811 Struct_Counter := 0;
8813 FA_Append_Record_Traversal (
8814 Stmts => VP_Stmts,
8815 Clist => Component_List (Variant),
8816 Container => Struct_Any,
8817 Counter => Struct_Counter);
8819 Append_To (Alt_List,
8820 Make_Case_Statement_Alternative (Loc,
8821 Discrete_Choices => Choice_List,
8822 Statements => VP_Stmts));
8823 Next_Non_Pragma (Variant);
8824 end loop;
8825 end;
8826 end if;
8828 Counter := Counter + 1;
8829 end FA_Rec_Add_Process_Element;
8831 begin
8832 -- First all discriminants
8834 if Has_Discriminants (Typ) then
8835 Discriminant_Associations := New_List;
8837 Disc := First_Discriminant (Typ);
8838 while Present (Disc) loop
8839 declare
8840 Disc_Var_Name : constant Entity_Id :=
8841 Make_Defining_Identifier (Loc,
8842 Chars => Chars (Disc));
8843 Disc_Type : constant Entity_Id :=
8844 Etype (Disc);
8846 begin
8847 Append_To (Decls,
8848 Make_Object_Declaration (Loc,
8849 Defining_Identifier => Disc_Var_Name,
8850 Constant_Present => True,
8851 Object_Definition =>
8852 New_Occurrence_Of (Disc_Type, Loc),
8854 Expression =>
8855 Build_From_Any_Call (Disc_Type,
8856 Build_Get_Aggregate_Element (Loc,
8857 Any => Any_Parameter,
8858 TC => Build_TypeCode_Call
8859 (Loc, Disc_Type, Decls),
8860 Idx => Make_Integer_Literal (Loc,
8861 Intval => Component_Counter)),
8862 Decls)));
8864 Component_Counter := Component_Counter + 1;
8866 Append_To (Discriminant_Associations,
8867 Make_Discriminant_Association (Loc,
8868 Selector_Names => New_List (
8869 New_Occurrence_Of (Disc, Loc)),
8870 Expression =>
8871 New_Occurrence_Of (Disc_Var_Name, Loc)));
8872 end;
8873 Next_Discriminant (Disc);
8874 end loop;
8876 Res_Definition :=
8877 Make_Subtype_Indication (Loc,
8878 Subtype_Mark => Res_Definition,
8879 Constraint =>
8880 Make_Index_Or_Discriminant_Constraint (Loc,
8881 Discriminant_Associations));
8882 end if;
8884 -- Now we have all the discriminants in variables, we can
8885 -- declared a constrained object. Note that we are not
8886 -- initializing (non-discriminant) components directly in
8887 -- the object declarations, because which fields to
8888 -- initialize depends (at run time) on the discriminant
8889 -- values.
8891 Append_To (Decls,
8892 Make_Object_Declaration (Loc,
8893 Defining_Identifier => Res,
8894 Object_Definition => Res_Definition));
8896 -- ... then all components
8898 FA_Append_Record_Traversal (Stms,
8899 Clist => Component_List (Rdef),
8900 Container => Any_Parameter,
8901 Counter => Component_Counter);
8903 Append_To (Stms,
8904 Make_Simple_Return_Statement (Loc,
8905 Expression => New_Occurrence_Of (Res, Loc)));
8906 end;
8907 end if;
8909 elsif Is_Array_Type (Typ) then
8910 declare
8911 Constrained : constant Boolean := Is_Constrained (Typ);
8913 procedure FA_Ary_Add_Process_Element
8914 (Stmts : List_Id;
8915 Any : Entity_Id;
8916 Counter : Entity_Id;
8917 Datum : Node_Id);
8918 -- Assign the current element (as identified by Counter) of
8919 -- Any to the variable denoted by name Datum, and advance
8920 -- Counter by 1. If Datum is not an Any, a call to From_Any
8921 -- for its type is inserted.
8923 --------------------------------
8924 -- FA_Ary_Add_Process_Element --
8925 --------------------------------
8927 procedure FA_Ary_Add_Process_Element
8928 (Stmts : List_Id;
8929 Any : Entity_Id;
8930 Counter : Entity_Id;
8931 Datum : Node_Id)
8933 Assignment : constant Node_Id :=
8934 Make_Assignment_Statement (Loc,
8935 Name => Datum,
8936 Expression => Empty);
8938 Element_Any : Node_Id;
8940 begin
8941 declare
8942 Element_TC : Node_Id;
8944 begin
8945 if Etype (Datum) = RTE (RE_Any) then
8947 -- When Datum is an Any the Etype field is not
8948 -- sufficient to determine the typecode of Datum
8949 -- (which can be a TC_SEQUENCE or TC_ARRAY
8950 -- depending on the value of Constrained).
8952 -- Therefore we retrieve the typecode which has
8953 -- been constructed in Append_Array_Traversal with
8954 -- a call to Get_Any_Type.
8956 Element_TC :=
8957 Make_Function_Call (Loc,
8958 Name => New_Occurrence_Of (
8959 RTE (RE_Get_Any_Type), Loc),
8960 Parameter_Associations => New_List (
8961 New_Occurrence_Of (Entity (Datum), Loc)));
8962 else
8963 -- For non Any Datum we simply construct a typecode
8964 -- matching the Etype of the Datum.
8966 Element_TC := Build_TypeCode_Call
8967 (Loc, Etype (Datum), Decls);
8968 end if;
8970 Element_Any :=
8971 Build_Get_Aggregate_Element (Loc,
8972 Any => Any,
8973 TC => Element_TC,
8974 Idx => New_Occurrence_Of (Counter, Loc));
8975 end;
8977 -- Note: here we *prepend* statements to Stmts, so
8978 -- we must do it in reverse order.
8980 Prepend_To (Stmts,
8981 Make_Assignment_Statement (Loc,
8982 Name =>
8983 New_Occurrence_Of (Counter, Loc),
8984 Expression =>
8985 Make_Op_Add (Loc,
8986 Left_Opnd => New_Occurrence_Of (Counter, Loc),
8987 Right_Opnd => Make_Integer_Literal (Loc, 1))));
8989 if Nkind (Datum) /= N_Attribute_Reference then
8991 -- We ignore the value of the length of each
8992 -- dimension, since the target array has already been
8993 -- constrained anyway.
8995 if Etype (Datum) /= RTE (RE_Any) then
8996 Set_Expression (Assignment,
8997 Build_From_Any_Call
8998 (Component_Type (Typ), Element_Any, Decls));
8999 else
9000 Set_Expression (Assignment, Element_Any);
9001 end if;
9003 Prepend_To (Stmts, Assignment);
9004 end if;
9005 end FA_Ary_Add_Process_Element;
9007 ------------------------
9008 -- Local Declarations --
9009 ------------------------
9011 Counter : constant Entity_Id :=
9012 Make_Defining_Identifier (Loc, Name_J);
9014 Initial_Counter_Value : Int := 0;
9016 Component_TC : constant Entity_Id :=
9017 Make_Defining_Identifier (Loc, Name_T);
9019 Res : constant Entity_Id :=
9020 Make_Defining_Identifier (Loc, Name_R);
9022 procedure Append_From_Any_Array_Iterator is
9023 new Append_Array_Traversal (
9024 Subprogram => Fnam,
9025 Arry => Res,
9026 Indexes => New_List,
9027 Add_Process_Element => FA_Ary_Add_Process_Element);
9029 Res_Subtype_Indication : Node_Id :=
9030 New_Occurrence_Of (Typ, Loc);
9032 begin
9033 if not Constrained then
9034 declare
9035 Ndim : constant Int := Number_Dimensions (Typ);
9036 Lnam : Name_Id;
9037 Hnam : Name_Id;
9038 Indx : Node_Id := First_Index (Typ);
9039 Indt : Entity_Id;
9041 Ranges : constant List_Id := New_List;
9043 begin
9044 for J in 1 .. Ndim loop
9045 Lnam := New_External_Name ('L', J);
9046 Hnam := New_External_Name ('H', J);
9048 -- Note, for empty arrays bounds may be out of
9049 -- the range of Etype (Indx).
9051 Indt := Base_Type (Etype (Indx));
9053 Append_To (Decls,
9054 Make_Object_Declaration (Loc,
9055 Defining_Identifier =>
9056 Make_Defining_Identifier (Loc, Lnam),
9057 Constant_Present => True,
9058 Object_Definition =>
9059 New_Occurrence_Of (Indt, Loc),
9060 Expression =>
9061 Build_From_Any_Call
9062 (Indt,
9063 Build_Get_Aggregate_Element (Loc,
9064 Any => Any_Parameter,
9065 TC => Build_TypeCode_Call
9066 (Loc, Indt, Decls),
9067 Idx =>
9068 Make_Integer_Literal (Loc, J - 1)),
9069 Decls)));
9071 Append_To (Decls,
9072 Make_Object_Declaration (Loc,
9073 Defining_Identifier =>
9074 Make_Defining_Identifier (Loc, Hnam),
9076 Constant_Present => True,
9078 Object_Definition =>
9079 New_Occurrence_Of (Indt, Loc),
9081 Expression => Make_Attribute_Reference (Loc,
9082 Prefix =>
9083 New_Occurrence_Of (Indt, Loc),
9085 Attribute_Name => Name_Val,
9087 Expressions => New_List (
9088 Make_Op_Subtract (Loc,
9089 Left_Opnd =>
9090 Make_Op_Add (Loc,
9091 Left_Opnd =>
9092 OK_Convert_To
9093 (Standard_Long_Integer,
9094 Make_Identifier (Loc, Lnam)),
9096 Right_Opnd =>
9097 OK_Convert_To
9098 (Standard_Long_Integer,
9099 Make_Function_Call (Loc,
9100 Name =>
9101 New_Occurrence_Of (RTE (
9102 RE_Get_Nested_Sequence_Length
9103 ), Loc),
9104 Parameter_Associations =>
9105 New_List (
9106 New_Occurrence_Of (
9107 Any_Parameter, Loc),
9108 Make_Integer_Literal (Loc,
9109 Intval => J))))),
9111 Right_Opnd =>
9112 Make_Integer_Literal (Loc, 1))))));
9114 Append_To (Ranges,
9115 Make_Range (Loc,
9116 Low_Bound => Make_Identifier (Loc, Lnam),
9117 High_Bound => Make_Identifier (Loc, Hnam)));
9119 Next_Index (Indx);
9120 end loop;
9122 -- Now we have all the necessary bound information:
9123 -- apply the set of range constraints to the
9124 -- (unconstrained) nominal subtype of Res.
9126 Initial_Counter_Value := Ndim;
9127 Res_Subtype_Indication := Make_Subtype_Indication (Loc,
9128 Subtype_Mark => Res_Subtype_Indication,
9129 Constraint =>
9130 Make_Index_Or_Discriminant_Constraint (Loc,
9131 Constraints => Ranges));
9132 end;
9133 end if;
9135 Append_To (Decls,
9136 Make_Object_Declaration (Loc,
9137 Defining_Identifier => Res,
9138 Object_Definition => Res_Subtype_Indication));
9139 Set_Etype (Res, Typ);
9141 Append_To (Decls,
9142 Make_Object_Declaration (Loc,
9143 Defining_Identifier => Counter,
9144 Object_Definition =>
9145 New_Occurrence_Of (RTE (RE_Unsigned_32), Loc),
9146 Expression =>
9147 Make_Integer_Literal (Loc, Initial_Counter_Value)));
9149 Append_To (Decls,
9150 Make_Object_Declaration (Loc,
9151 Defining_Identifier => Component_TC,
9152 Constant_Present => True,
9153 Object_Definition =>
9154 New_Occurrence_Of (RTE (RE_TypeCode), Loc),
9155 Expression =>
9156 Build_TypeCode_Call (Loc,
9157 Component_Type (Typ), Decls)));
9159 Append_From_Any_Array_Iterator
9160 (Stms, Any_Parameter, Counter);
9162 Append_To (Stms,
9163 Make_Simple_Return_Statement (Loc,
9164 Expression => New_Occurrence_Of (Res, Loc)));
9165 end;
9167 elsif Is_Integer_Type (Typ) or else Is_Unsigned_Type (Typ) then
9168 Append_To (Stms,
9169 Make_Simple_Return_Statement (Loc,
9170 Expression =>
9171 Unchecked_Convert_To (Typ,
9172 Build_From_Any_Call
9173 (Find_Numeric_Representation (Typ),
9174 New_Occurrence_Of (Any_Parameter, Loc),
9175 Decls))));
9177 else
9178 Use_Opaque_Representation := True;
9179 end if;
9181 if Use_Opaque_Representation then
9182 Assign_Opaque_From_Any (Loc,
9183 Stms => Stms,
9184 Typ => Typ,
9185 N => New_Occurrence_Of (Any_Parameter, Loc),
9186 Target => Empty);
9187 end if;
9189 Decl :=
9190 Make_Subprogram_Body (Loc,
9191 Specification => Spec,
9192 Declarations => Decls,
9193 Handled_Statement_Sequence =>
9194 Make_Handled_Sequence_Of_Statements (Loc,
9195 Statements => Stms));
9196 end Build_From_Any_Function;
9198 ---------------------------------
9199 -- Build_Get_Aggregate_Element --
9200 ---------------------------------
9202 function Build_Get_Aggregate_Element
9203 (Loc : Source_Ptr;
9204 Any : Entity_Id;
9205 TC : Node_Id;
9206 Idx : Node_Id) return Node_Id
9208 begin
9209 return Make_Function_Call (Loc,
9210 Name =>
9211 New_Occurrence_Of (RTE (RE_Get_Aggregate_Element), Loc),
9212 Parameter_Associations => New_List (
9213 New_Occurrence_Of (Any, Loc),
9215 Idx));
9216 end Build_Get_Aggregate_Element;
9218 ----------------------------------
9219 -- Build_Name_And_Repository_Id --
9220 ----------------------------------
9222 procedure Build_Name_And_Repository_Id
9223 (E : Entity_Id;
9224 Name_Str : out String_Id;
9225 Repo_Id_Str : out String_Id)
9227 begin
9228 Name_Str := Fully_Qualified_Name_String (E, Append_NUL => False);
9229 Start_String;
9230 Store_String_Chars ("DSA:");
9231 Store_String_Chars (Name_Str);
9232 Store_String_Chars (":1.0");
9233 Repo_Id_Str := End_String;
9234 end Build_Name_And_Repository_Id;
9236 -----------------------
9237 -- Build_To_Any_Call --
9238 -----------------------
9240 function Build_To_Any_Call
9241 (Loc : Source_Ptr;
9242 N : Node_Id;
9243 Decls : List_Id;
9244 Constrained : Boolean := False) return Node_Id
9246 Typ : Entity_Id := Etype (N);
9247 U_Type : Entity_Id;
9248 C_Type : Entity_Id;
9249 Fnam : Entity_Id;
9250 Lib_RE : RE_Id := RE_Null;
9252 begin
9253 -- If N is a selected component, then maybe its Etype has not been
9254 -- set yet: try to use Etype of the selector_name in that case.
9256 if No (Typ) and then Nkind (N) = N_Selected_Component then
9257 Typ := Etype (Selector_Name (N));
9258 end if;
9260 pragma Assert (Present (Typ));
9262 -- Get full view for private type, completion for incomplete type
9264 U_Type := Underlying_Type (Typ);
9266 -- First simple case where the To_Any function is present in the
9267 -- type's TSS.
9269 Fnam := Find_Inherited_TSS (U_Type, TSS_To_Any);
9271 -- For the subtype representing a generic actual type, go to the
9272 -- actual type.
9274 if Is_Generic_Actual_Subtype (U_Type) then
9275 U_Type := Underlying_Type (Base_Type (U_Type));
9276 end if;
9278 -- For a standard subtype, go to the base type
9280 if Sloc (U_Type) <= Standard_Location then
9281 U_Type := Base_Type (U_Type);
9283 -- For a user subtype, go to first subtype
9285 elsif Comes_From_Source (U_Type)
9286 and then Nkind (Declaration_Node (U_Type))
9287 = N_Subtype_Declaration
9288 then
9289 U_Type := First_Subtype (U_Type);
9290 end if;
9292 if Present (Fnam) then
9293 null;
9295 -- Check first for Boolean and Character. These are enumeration
9296 -- types, but we treat them specially, since they may require
9297 -- special handling in the transfer protocol. However, this
9298 -- special handling only applies if they have standard
9299 -- representation, otherwise they are treated like any other
9300 -- enumeration type.
9302 elsif U_Type = Standard_Boolean then
9303 Lib_RE := RE_TA_B;
9305 elsif U_Type = Standard_Character then
9306 Lib_RE := RE_TA_C;
9308 elsif U_Type = Standard_Wide_Character then
9309 Lib_RE := RE_TA_WC;
9311 elsif U_Type = Standard_Wide_Wide_Character then
9312 Lib_RE := RE_TA_WWC;
9314 -- Floating point types
9316 elsif U_Type = Standard_Short_Float then
9317 Lib_RE := RE_TA_SF;
9319 elsif U_Type = Standard_Float then
9320 Lib_RE := RE_TA_F;
9322 elsif U_Type = Standard_Long_Float then
9323 Lib_RE := RE_TA_LF;
9325 elsif U_Type = Standard_Long_Long_Float then
9326 Lib_RE := RE_TA_LLF;
9328 -- Integer types
9330 elsif U_Type = RTE (RE_Integer_8) then
9331 Lib_RE := RE_TA_I8;
9333 elsif U_Type = RTE (RE_Integer_16) then
9334 Lib_RE := RE_TA_I16;
9336 elsif U_Type = RTE (RE_Integer_32) then
9337 Lib_RE := RE_TA_I32;
9339 elsif U_Type = RTE (RE_Integer_64) then
9340 Lib_RE := RE_TA_I64;
9342 -- Unsigned integer types
9344 elsif U_Type = RTE (RE_Unsigned_8) then
9345 Lib_RE := RE_TA_U8;
9347 elsif U_Type = RTE (RE_Unsigned_16) then
9348 Lib_RE := RE_TA_U16;
9350 elsif U_Type = RTE (RE_Unsigned_32) then
9351 Lib_RE := RE_TA_U32;
9353 elsif U_Type = RTE (RE_Unsigned_64) then
9354 Lib_RE := RE_TA_U64;
9356 elsif Is_RTE (U_Type, RE_Unbounded_String) then
9357 Lib_RE := RE_TA_String;
9359 -- Special DSA types
9361 elsif Is_RTE (U_Type, RE_Any_Container_Ptr) then
9362 Lib_RE := RE_TA_A;
9363 U_Type := Typ;
9365 elsif U_Type = Underlying_Type (RTE (RE_TypeCode)) then
9367 -- No corresponding FA_TC ???
9369 Lib_RE := RE_TA_TC;
9371 -- Other (non-primitive) types
9373 else
9374 declare
9375 Decl : Entity_Id;
9376 begin
9377 Build_To_Any_Function (Loc, U_Type, Decl, Fnam);
9378 Append_To (Decls, Decl);
9379 end;
9380 end if;
9382 -- Call the function
9384 if Lib_RE /= RE_Null then
9385 pragma Assert (No (Fnam));
9386 Fnam := RTE (Lib_RE);
9387 end if;
9389 -- If Fnam is already analyzed, find the proper expected type,
9390 -- else we have a newly constructed To_Any function and we know
9391 -- that the expected type of its parameter is U_Type.
9393 if Ekind (Fnam) = E_Function
9394 and then Present (First_Formal (Fnam))
9395 then
9396 C_Type := Etype (First_Formal (Fnam));
9397 else
9398 C_Type := U_Type;
9399 end if;
9401 declare
9402 Params : constant List_Id :=
9403 New_List (OK_Convert_To (C_Type, N));
9404 begin
9405 if Is_Limited_Type (C_Type) then
9406 Append_To (Params,
9407 New_Occurrence_Of (Boolean_Literals (Constrained), Loc));
9408 end if;
9410 return
9411 Make_Function_Call (Loc,
9412 Name => New_Occurrence_Of (Fnam, Loc),
9413 Parameter_Associations => Params);
9414 end;
9415 end Build_To_Any_Call;
9417 ---------------------------
9418 -- Build_To_Any_Function --
9419 ---------------------------
9421 procedure Build_To_Any_Function
9422 (Loc : Source_Ptr;
9423 Typ : Entity_Id;
9424 Decl : out Node_Id;
9425 Fnam : out Entity_Id)
9427 Spec : Node_Id;
9428 Params : List_Id;
9429 Decls : List_Id;
9430 Stms : List_Id;
9432 Expr_Formal : Entity_Id;
9433 Cstr_Formal : Entity_Id := Empty; -- initialize to prevent warning
9434 Any : Entity_Id;
9435 Result_TC : Node_Id;
9437 Any_Decl : Node_Id;
9439 Use_Opaque_Representation : Boolean;
9440 -- When True, use stream attributes and represent type as an
9441 -- opaque sequence of bytes.
9443 Real_Rep : Node_Id;
9445 begin
9446 -- For a derived type, we can't go past the base type (to the
9447 -- parent type) here, because that would cause the attribute's
9448 -- formal parameter to have the wrong type; hence the Base_Type
9449 -- check here.
9451 if Is_Itype (Typ) and then Typ /= Base_Type (Typ) then
9452 Build_To_Any_Function
9453 (Loc => Loc,
9454 Typ => Etype (Typ),
9455 Decl => Decl,
9456 Fnam => Fnam);
9457 return;
9458 end if;
9460 Decls := New_List;
9461 Stms := New_List;
9463 Any := Make_Defining_Identifier (Loc, Name_A);
9464 Result_TC := Build_TypeCode_Call (Loc, Typ, Decls);
9466 Fnam := Make_Helper_Function_Name (Loc, Typ, Name_To_Any);
9468 Expr_Formal := Make_Defining_Identifier (Loc, Name_E);
9469 Params := New_List (
9470 Make_Parameter_Specification (Loc,
9471 Defining_Identifier => Expr_Formal,
9472 Parameter_Type => New_Occurrence_Of (Typ, Loc)));
9473 Set_Etype (Expr_Formal, Typ);
9475 if Is_Limited_Type (Typ) then
9476 Cstr_Formal := Make_Defining_Identifier (Loc, Name_C);
9477 Append_To (Params,
9478 Make_Parameter_Specification (Loc,
9479 Defining_Identifier => Cstr_Formal,
9480 Parameter_Type =>
9481 New_Occurrence_Of (Standard_Boolean, Loc)));
9482 end if;
9484 Spec :=
9485 Make_Function_Specification (Loc,
9486 Defining_Unit_Name => Fnam,
9487 Parameter_Specifications => Params,
9488 Result_Definition =>
9489 New_Occurrence_Of (RTE (RE_Any), Loc));
9491 Any_Decl :=
9492 Make_Object_Declaration (Loc,
9493 Defining_Identifier => Any,
9494 Object_Definition => New_Occurrence_Of (RTE (RE_Any), Loc));
9496 Use_Opaque_Representation := False;
9498 if Has_Stream_Attribute_Definition
9499 (Typ, TSS_Stream_Output, Real_Rep, At_Any_Place => True)
9500 or else
9501 Has_Stream_Attribute_Definition
9502 (Typ, TSS_Stream_Write, Real_Rep, At_Any_Place => True)
9503 then
9504 -- If user-defined stream attributes are specified for this
9505 -- type, use them and transmit data as an opaque sequence of
9506 -- stream elements.
9508 Use_Opaque_Representation := True;
9510 elsif Is_Derived_Type (Typ) and then not Is_Tagged_Type (Typ) then
9512 -- Untagged derived type: convert to root type
9514 declare
9515 Rt_Type : constant Entity_Id := Root_Type (Typ);
9516 Expr : constant Node_Id :=
9517 OK_Convert_To
9518 (Rt_Type,
9519 New_Occurrence_Of (Expr_Formal, Loc));
9520 begin
9521 Set_Expression (Any_Decl,
9522 Build_To_Any_Call (Loc, Expr, Decls));
9523 end;
9525 elsif Is_Record_Type (Typ) and then not Is_Tagged_Type (Typ) then
9527 -- Untagged record type
9529 if Nkind (Declaration_Node (Typ)) = N_Subtype_Declaration then
9530 declare
9531 Rt_Type : constant Entity_Id := Etype (Typ);
9532 Expr : constant Node_Id :=
9533 OK_Convert_To (Rt_Type,
9534 New_Occurrence_Of (Expr_Formal, Loc));
9536 begin
9537 Set_Expression
9538 (Any_Decl, Build_To_Any_Call (Loc, Expr, Decls));
9539 end;
9541 -- Comment needed here (and label on declare block ???)
9543 else
9544 declare
9545 Disc : Entity_Id := Empty;
9546 Rdef : constant Node_Id :=
9547 Type_Definition (Declaration_Node (Typ));
9548 Counter : Nat := 0;
9549 Elements : constant List_Id := New_List;
9551 procedure TA_Rec_Add_Process_Element
9552 (Stmts : List_Id;
9553 Container : Node_Or_Entity_Id;
9554 Counter : in out Nat;
9555 Rec : Entity_Id;
9556 Field : Node_Id);
9557 -- Processing routine for traversal below
9559 procedure TA_Append_Record_Traversal is
9560 new Append_Record_Traversal
9561 (Rec => Expr_Formal,
9562 Add_Process_Element => TA_Rec_Add_Process_Element);
9564 --------------------------------
9565 -- TA_Rec_Add_Process_Element --
9566 --------------------------------
9568 procedure TA_Rec_Add_Process_Element
9569 (Stmts : List_Id;
9570 Container : Node_Or_Entity_Id;
9571 Counter : in out Nat;
9572 Rec : Entity_Id;
9573 Field : Node_Id)
9575 Field_Ref : Node_Id;
9577 begin
9578 if Nkind (Field) = N_Defining_Identifier then
9580 -- A regular component
9582 Field_Ref := Make_Selected_Component (Loc,
9583 Prefix => New_Occurrence_Of (Rec, Loc),
9584 Selector_Name => New_Occurrence_Of (Field, Loc));
9585 Set_Etype (Field_Ref, Etype (Field));
9587 Append_To (Stmts,
9588 Make_Procedure_Call_Statement (Loc,
9589 Name =>
9590 New_Occurrence_Of (
9591 RTE (RE_Add_Aggregate_Element), Loc),
9592 Parameter_Associations => New_List (
9593 New_Occurrence_Of (Container, Loc),
9594 Build_To_Any_Call (Loc, Field_Ref, Decls))));
9596 else
9597 -- A variant part
9599 Variant_Part : declare
9600 Variant : Node_Id;
9601 Struct_Counter : Nat := 0;
9603 Block_Decls : constant List_Id := New_List;
9604 Block_Stmts : constant List_Id := New_List;
9605 VP_Stmts : List_Id;
9607 Alt_List : constant List_Id := New_List;
9608 Choice_List : List_Id;
9610 Union_Any : constant Entity_Id :=
9611 Make_Temporary (Loc, 'V');
9613 Struct_Any : constant Entity_Id :=
9614 Make_Temporary (Loc, 'S');
9616 function Make_Discriminant_Reference
9617 return Node_Id;
9618 -- Build reference to the discriminant for this
9619 -- variant part.
9621 ---------------------------------
9622 -- Make_Discriminant_Reference --
9623 ---------------------------------
9625 function Make_Discriminant_Reference
9626 return Node_Id
9628 Nod : constant Node_Id :=
9629 Make_Selected_Component (Loc,
9630 Prefix => Rec,
9631 Selector_Name =>
9632 Chars (Name (Field)));
9633 begin
9634 Set_Etype (Nod, Etype (Name (Field)));
9635 return Nod;
9636 end Make_Discriminant_Reference;
9638 -- Start of processing for Variant_Part
9640 begin
9641 Append_To (Stmts,
9642 Make_Block_Statement (Loc,
9643 Declarations =>
9644 Block_Decls,
9645 Handled_Statement_Sequence =>
9646 Make_Handled_Sequence_Of_Statements (Loc,
9647 Statements => Block_Stmts)));
9649 -- Declare variant part aggregate (Union_Any).
9650 -- Knowing the position of this VP in the
9651 -- variant record, we can fetch the VP typecode
9652 -- from Container.
9654 Append_To (Block_Decls,
9655 Make_Object_Declaration (Loc,
9656 Defining_Identifier => Union_Any,
9657 Object_Definition =>
9658 New_Occurrence_Of (RTE (RE_Any), Loc),
9659 Expression =>
9660 Make_Function_Call (Loc,
9661 Name => New_Occurrence_Of (
9662 RTE (RE_Create_Any), Loc),
9663 Parameter_Associations => New_List (
9664 Make_Function_Call (Loc,
9665 Name =>
9666 New_Occurrence_Of (
9667 RTE (RE_Any_Member_Type), Loc),
9668 Parameter_Associations => New_List (
9669 New_Occurrence_Of (Container, Loc),
9670 Make_Integer_Literal (Loc,
9671 Counter)))))));
9673 -- Declare inner struct aggregate (which
9674 -- contains the components of this VP).
9676 Append_To (Block_Decls,
9677 Make_Object_Declaration (Loc,
9678 Defining_Identifier => Struct_Any,
9679 Object_Definition =>
9680 New_Occurrence_Of (RTE (RE_Any), Loc),
9681 Expression =>
9682 Make_Function_Call (Loc,
9683 Name => New_Occurrence_Of (
9684 RTE (RE_Create_Any), Loc),
9685 Parameter_Associations => New_List (
9686 Make_Function_Call (Loc,
9687 Name =>
9688 New_Occurrence_Of (
9689 RTE (RE_Any_Member_Type), Loc),
9690 Parameter_Associations => New_List (
9691 New_Occurrence_Of (Union_Any, Loc),
9692 Make_Integer_Literal (Loc,
9693 Uint_1)))))));
9695 -- Build case statement
9697 Append_To (Block_Stmts,
9698 Make_Case_Statement (Loc,
9699 Expression => Make_Discriminant_Reference,
9700 Alternatives => Alt_List));
9702 Variant := First_Non_Pragma (Variants (Field));
9703 while Present (Variant) loop
9704 Choice_List := New_Copy_List_Tree
9705 (Discrete_Choices (Variant));
9707 VP_Stmts := New_List;
9709 -- Append discriminant val to union aggregate
9711 Append_To (VP_Stmts,
9712 Make_Procedure_Call_Statement (Loc,
9713 Name =>
9714 New_Occurrence_Of (
9715 RTE (RE_Add_Aggregate_Element), Loc),
9716 Parameter_Associations => New_List (
9717 New_Occurrence_Of (Union_Any, Loc),
9718 Build_To_Any_Call
9719 (Loc,
9720 Make_Discriminant_Reference,
9721 Block_Decls))));
9723 -- Populate inner struct aggregate
9725 -- Struct_Counter should be reset before
9726 -- handling a variant part. Indeed only one
9727 -- of the case statement alternatives will be
9728 -- executed at run time, so the counter must
9729 -- start at 0 for every case statement.
9731 Struct_Counter := 0;
9733 TA_Append_Record_Traversal
9734 (Stmts => VP_Stmts,
9735 Clist => Component_List (Variant),
9736 Container => Struct_Any,
9737 Counter => Struct_Counter);
9739 -- Append inner struct to union aggregate
9741 Append_To (VP_Stmts,
9742 Make_Procedure_Call_Statement (Loc,
9743 Name =>
9744 New_Occurrence_Of
9745 (RTE (RE_Add_Aggregate_Element), Loc),
9746 Parameter_Associations => New_List (
9747 New_Occurrence_Of (Union_Any, Loc),
9748 New_Occurrence_Of (Struct_Any, Loc))));
9750 -- Append union to outer aggregate
9752 Append_To (VP_Stmts,
9753 Make_Procedure_Call_Statement (Loc,
9754 Name =>
9755 New_Occurrence_Of
9756 (RTE (RE_Add_Aggregate_Element), Loc),
9757 Parameter_Associations => New_List (
9758 New_Occurrence_Of (Container, Loc),
9759 New_Occurrence_Of
9760 (Union_Any, Loc))));
9762 Append_To (Alt_List,
9763 Make_Case_Statement_Alternative (Loc,
9764 Discrete_Choices => Choice_List,
9765 Statements => VP_Stmts));
9767 Next_Non_Pragma (Variant);
9768 end loop;
9769 end Variant_Part;
9770 end if;
9772 Counter := Counter + 1;
9773 end TA_Rec_Add_Process_Element;
9775 begin
9776 -- Records are encoded in a TC_STRUCT aggregate:
9778 -- -- Outer aggregate (TC_STRUCT)
9779 -- | [discriminant1]
9780 -- | [discriminant2]
9781 -- | ...
9782 -- |
9783 -- | [component1]
9784 -- | [component2]
9785 -- | ...
9787 -- A component can be a common component or variant part
9789 -- A variant part is encoded as a TC_UNION aggregate:
9791 -- -- Variant Part Aggregate (TC_UNION)
9792 -- | [discriminant choice for this Variant Part]
9793 -- |
9794 -- | -- Inner struct (TC_STRUCT)
9795 -- | | [component1]
9796 -- | | [component2]
9797 -- | | ...
9799 -- Let's start by building the outer aggregate. First we
9800 -- construct Elements array containing all discriminants.
9802 if Has_Discriminants (Typ) then
9803 Disc := First_Discriminant (Typ);
9804 while Present (Disc) loop
9805 declare
9806 Discriminant : constant Entity_Id :=
9807 Make_Selected_Component (Loc,
9808 Prefix => Expr_Formal,
9809 Selector_Name => Chars (Disc));
9810 begin
9811 Set_Etype (Discriminant, Etype (Disc));
9812 Append_To (Elements,
9813 Make_Component_Association (Loc,
9814 Choices => New_List (
9815 Make_Integer_Literal (Loc, Counter)),
9816 Expression =>
9817 Build_To_Any_Call (Loc,
9818 Discriminant, Decls)));
9819 end;
9821 Counter := Counter + 1;
9822 Next_Discriminant (Disc);
9823 end loop;
9825 else
9826 -- If there are no discriminants, we declare an empty
9827 -- Elements array.
9829 declare
9830 Dummy_Any : constant Entity_Id :=
9831 Make_Temporary (Loc, 'A');
9833 begin
9834 Append_To (Decls,
9835 Make_Object_Declaration (Loc,
9836 Defining_Identifier => Dummy_Any,
9837 Object_Definition =>
9838 New_Occurrence_Of (RTE (RE_Any), Loc)));
9840 Append_To (Elements,
9841 Make_Component_Association (Loc,
9842 Choices => New_List (
9843 Make_Range (Loc,
9844 Low_Bound =>
9845 Make_Integer_Literal (Loc, 1),
9846 High_Bound =>
9847 Make_Integer_Literal (Loc, 0))),
9848 Expression =>
9849 New_Occurrence_Of (Dummy_Any, Loc)));
9850 end;
9851 end if;
9853 -- We build the result aggregate with discriminants
9854 -- as the first elements.
9856 Set_Expression (Any_Decl,
9857 Make_Function_Call (Loc,
9858 Name => New_Occurrence_Of
9859 (RTE (RE_Any_Aggregate_Build), Loc),
9860 Parameter_Associations => New_List (
9861 Result_TC,
9862 Make_Aggregate (Loc,
9863 Component_Associations => Elements))));
9864 Result_TC := Empty;
9866 -- Then we append all the components to the result
9867 -- aggregate.
9869 TA_Append_Record_Traversal (Stms,
9870 Clist => Component_List (Rdef),
9871 Container => Any,
9872 Counter => Counter);
9873 end;
9874 end if;
9876 elsif Is_Array_Type (Typ) then
9878 -- Constrained and unconstrained array types
9880 declare
9881 Constrained : constant Boolean :=
9882 not Transmit_As_Unconstrained (Typ);
9884 procedure TA_Ary_Add_Process_Element
9885 (Stmts : List_Id;
9886 Any : Entity_Id;
9887 Counter : Entity_Id;
9888 Datum : Node_Id);
9890 --------------------------------
9891 -- TA_Ary_Add_Process_Element --
9892 --------------------------------
9894 procedure TA_Ary_Add_Process_Element
9895 (Stmts : List_Id;
9896 Any : Entity_Id;
9897 Counter : Entity_Id;
9898 Datum : Node_Id)
9900 pragma Unreferenced (Counter);
9902 Element_Any : Node_Id;
9904 begin
9905 if Etype (Datum) = RTE (RE_Any) then
9906 Element_Any := Datum;
9907 else
9908 Element_Any := Build_To_Any_Call (Loc, Datum, Decls);
9909 end if;
9911 Append_To (Stmts,
9912 Make_Procedure_Call_Statement (Loc,
9913 Name => New_Occurrence_Of (
9914 RTE (RE_Add_Aggregate_Element), Loc),
9915 Parameter_Associations => New_List (
9916 New_Occurrence_Of (Any, Loc),
9917 Element_Any)));
9918 end TA_Ary_Add_Process_Element;
9920 procedure Append_To_Any_Array_Iterator is
9921 new Append_Array_Traversal (
9922 Subprogram => Fnam,
9923 Arry => Expr_Formal,
9924 Indexes => New_List,
9925 Add_Process_Element => TA_Ary_Add_Process_Element);
9927 Index : Node_Id;
9929 begin
9930 Set_Expression (Any_Decl,
9931 Make_Function_Call (Loc,
9932 Name =>
9933 New_Occurrence_Of (RTE (RE_Create_Any), Loc),
9934 Parameter_Associations => New_List (Result_TC)));
9935 Result_TC := Empty;
9937 if not Constrained then
9938 Index := First_Index (Typ);
9939 for J in 1 .. Number_Dimensions (Typ) loop
9940 Append_To (Stms,
9941 Make_Procedure_Call_Statement (Loc,
9942 Name =>
9943 New_Occurrence_Of
9944 (RTE (RE_Add_Aggregate_Element), Loc),
9945 Parameter_Associations => New_List (
9946 New_Occurrence_Of (Any, Loc),
9947 Build_To_Any_Call (Loc,
9948 OK_Convert_To (Etype (Index),
9949 Make_Attribute_Reference (Loc,
9950 Prefix =>
9951 New_Occurrence_Of (Expr_Formal, Loc),
9952 Attribute_Name => Name_First,
9953 Expressions => New_List (
9954 Make_Integer_Literal (Loc, J)))),
9955 Decls))));
9956 Next_Index (Index);
9957 end loop;
9958 end if;
9960 Append_To_Any_Array_Iterator (Stms, Any);
9961 end;
9963 elsif Is_Integer_Type (Typ) or else Is_Unsigned_Type (Typ) then
9965 -- Integer types
9967 Set_Expression (Any_Decl,
9968 Build_To_Any_Call (Loc,
9969 OK_Convert_To (
9970 Find_Numeric_Representation (Typ),
9971 New_Occurrence_Of (Expr_Formal, Loc)),
9972 Decls));
9974 else
9975 -- Default case, including tagged types: opaque representation
9977 Use_Opaque_Representation := True;
9978 end if;
9980 if Use_Opaque_Representation then
9981 declare
9982 Strm : constant Entity_Id := Make_Temporary (Loc, 'S');
9983 -- Stream used to store data representation produced by
9984 -- stream attribute.
9986 begin
9987 -- Generate:
9988 -- Strm : aliased Buffer_Stream_Type;
9990 Append_To (Decls,
9991 Make_Object_Declaration (Loc,
9992 Defining_Identifier => Strm,
9993 Aliased_Present => True,
9994 Object_Definition =>
9995 New_Occurrence_Of (RTE (RE_Buffer_Stream_Type), Loc)));
9997 -- Generate:
9998 -- T'Output (Strm'Access, E);
9999 -- or
10000 -- T'Write (Strm'Access, E);
10001 -- depending on whether to transmit as unconstrained.
10003 -- For limited types, select at run time depending on
10004 -- Constrained parameter.
10006 declare
10007 function Stream_Call (Attr : Name_Id) return Node_Id;
10008 -- Return a call to the named attribute
10010 -----------------
10011 -- Stream_Call --
10012 -----------------
10014 function Stream_Call (Attr : Name_Id) return Node_Id is
10015 begin
10016 return Make_Attribute_Reference (Loc,
10017 Prefix =>
10018 New_Occurrence_Of (Typ, Loc),
10019 Attribute_Name => Attr,
10020 Expressions => New_List (
10021 Make_Attribute_Reference (Loc,
10022 Prefix =>
10023 New_Occurrence_Of (Strm, Loc),
10024 Attribute_Name => Name_Access),
10025 New_Occurrence_Of (Expr_Formal, Loc)));
10027 end Stream_Call;
10029 begin
10030 if Is_Limited_Type (Typ) then
10031 Append_To (Stms,
10032 Make_Implicit_If_Statement (Typ,
10033 Condition =>
10034 New_Occurrence_Of (Cstr_Formal, Loc),
10035 Then_Statements => New_List (
10036 Stream_Call (Name_Write)),
10037 Else_Statements => New_List (
10038 Stream_Call (Name_Output))));
10040 elsif Transmit_As_Unconstrained (Typ) then
10041 Append_To (Stms, Stream_Call (Name_Output));
10043 else
10044 Append_To (Stms, Stream_Call (Name_Write));
10045 end if;
10046 end;
10048 -- Generate:
10049 -- BS_To_Any (Strm, A);
10051 Append_To (Stms,
10052 Make_Procedure_Call_Statement (Loc,
10053 Name =>
10054 New_Occurrence_Of (RTE (RE_BS_To_Any), Loc),
10055 Parameter_Associations => New_List (
10056 New_Occurrence_Of (Strm, Loc),
10057 New_Occurrence_Of (Any, Loc))));
10059 -- Generate:
10060 -- Release_Buffer (Strm);
10062 Append_To (Stms,
10063 Make_Procedure_Call_Statement (Loc,
10064 Name =>
10065 New_Occurrence_Of (RTE (RE_Release_Buffer), Loc),
10066 Parameter_Associations => New_List (
10067 New_Occurrence_Of (Strm, Loc))));
10068 end;
10069 end if;
10071 Append_To (Decls, Any_Decl);
10073 if Present (Result_TC) then
10074 Append_To (Stms,
10075 Make_Procedure_Call_Statement (Loc,
10076 Name =>
10077 New_Occurrence_Of (RTE (RE_Set_TC), Loc),
10078 Parameter_Associations => New_List (
10079 New_Occurrence_Of (Any, Loc),
10080 Result_TC)));
10081 end if;
10083 Append_To (Stms,
10084 Make_Simple_Return_Statement (Loc,
10085 Expression => New_Occurrence_Of (Any, Loc)));
10087 Decl :=
10088 Make_Subprogram_Body (Loc,
10089 Specification => Spec,
10090 Declarations => Decls,
10091 Handled_Statement_Sequence =>
10092 Make_Handled_Sequence_Of_Statements (Loc,
10093 Statements => Stms));
10094 end Build_To_Any_Function;
10096 -------------------------
10097 -- Build_TypeCode_Call --
10098 -------------------------
10100 function Build_TypeCode_Call
10101 (Loc : Source_Ptr;
10102 Typ : Entity_Id;
10103 Decls : List_Id) return Node_Id
10105 U_Type : Entity_Id := Underlying_Type (Typ);
10106 -- The full view, if Typ is private; the completion,
10107 -- if Typ is incomplete.
10109 Fnam : Entity_Id;
10110 Lib_RE : RE_Id := RE_Null;
10111 Expr : Node_Id;
10113 begin
10114 -- Special case System.PolyORB.Interface.Any: its primitives have
10115 -- not been set yet, so can't call Find_Inherited_TSS.
10117 if Typ = RTE (RE_Any) then
10118 Fnam := RTE (RE_TC_A);
10120 else
10121 -- First simple case where the TypeCode is present
10122 -- in the type's TSS.
10124 Fnam := Find_Inherited_TSS (U_Type, TSS_TypeCode);
10125 end if;
10127 -- For the subtype representing a generic actual type, go to the
10128 -- actual type.
10130 if Is_Generic_Actual_Subtype (U_Type) then
10131 U_Type := Underlying_Type (Base_Type (U_Type));
10132 end if;
10134 -- For a standard subtype, go to the base type
10136 if Sloc (U_Type) <= Standard_Location then
10137 U_Type := Base_Type (U_Type);
10139 -- For a user subtype, go to first subtype
10141 elsif Comes_From_Source (U_Type)
10142 and then Nkind (Declaration_Node (U_Type))
10143 = N_Subtype_Declaration
10144 then
10145 U_Type := First_Subtype (U_Type);
10146 end if;
10148 if No (Fnam) then
10149 if U_Type = Standard_Boolean then
10150 Lib_RE := RE_TC_B;
10152 elsif U_Type = Standard_Character then
10153 Lib_RE := RE_TC_C;
10155 elsif U_Type = Standard_Wide_Character then
10156 Lib_RE := RE_TC_WC;
10158 elsif U_Type = Standard_Wide_Wide_Character then
10159 Lib_RE := RE_TC_WWC;
10161 -- Floating point types
10163 elsif U_Type = Standard_Short_Float then
10164 Lib_RE := RE_TC_SF;
10166 elsif U_Type = Standard_Float then
10167 Lib_RE := RE_TC_F;
10169 elsif U_Type = Standard_Long_Float then
10170 Lib_RE := RE_TC_LF;
10172 elsif U_Type = Standard_Long_Long_Float then
10173 Lib_RE := RE_TC_LLF;
10175 -- Integer types (walk back to the base type)
10177 elsif U_Type = RTE (RE_Integer_8) then
10178 Lib_RE := RE_TC_I8;
10180 elsif U_Type = RTE (RE_Integer_16) then
10181 Lib_RE := RE_TC_I16;
10183 elsif U_Type = RTE (RE_Integer_32) then
10184 Lib_RE := RE_TC_I32;
10186 elsif U_Type = RTE (RE_Integer_64) then
10187 Lib_RE := RE_TC_I64;
10189 -- Unsigned integer types
10191 elsif U_Type = RTE (RE_Unsigned_8) then
10192 Lib_RE := RE_TC_U8;
10194 elsif U_Type = RTE (RE_Unsigned_16) then
10195 Lib_RE := RE_TC_U16;
10197 elsif U_Type = RTE (RE_Unsigned_32) then
10198 Lib_RE := RE_TC_U32;
10200 elsif U_Type = RTE (RE_Unsigned_64) then
10201 Lib_RE := RE_TC_U64;
10203 elsif Is_RTE (U_Type, RE_Unbounded_String) then
10204 Lib_RE := RE_TC_String;
10206 -- Special DSA types
10208 elsif Is_RTE (U_Type, RE_Any_Container_Ptr) then
10209 Lib_RE := RE_TC_A;
10211 -- Other (non-primitive) types
10213 else
10214 declare
10215 Decl : Entity_Id;
10216 begin
10217 Build_TypeCode_Function (Loc, U_Type, Decl, Fnam);
10218 Append_To (Decls, Decl);
10219 end;
10220 end if;
10222 if Lib_RE /= RE_Null then
10223 Fnam := RTE (Lib_RE);
10224 end if;
10225 end if;
10227 -- Call the function
10229 Expr :=
10230 Make_Function_Call (Loc, Name => New_Occurrence_Of (Fnam, Loc));
10232 -- Allow Expr to be used as arg to Build_To_Any_Call immediately
10234 Set_Etype (Expr, RTE (RE_TypeCode));
10236 return Expr;
10237 end Build_TypeCode_Call;
10239 -----------------------------
10240 -- Build_TypeCode_Function --
10241 -----------------------------
10243 procedure Build_TypeCode_Function
10244 (Loc : Source_Ptr;
10245 Typ : Entity_Id;
10246 Decl : out Node_Id;
10247 Fnam : out Entity_Id)
10249 Spec : Node_Id;
10250 Decls : constant List_Id := New_List;
10251 Stms : constant List_Id := New_List;
10253 TCNam : constant Entity_Id :=
10254 Make_Helper_Function_Name (Loc, Typ, Name_TypeCode);
10256 Parameters : List_Id;
10258 procedure Add_String_Parameter
10259 (S : String_Id;
10260 Parameter_List : List_Id);
10261 -- Add a literal for S to Parameters
10263 procedure Add_TypeCode_Parameter
10264 (TC_Node : Node_Id;
10265 Parameter_List : List_Id);
10266 -- Add the typecode for Typ to Parameters
10268 procedure Add_Long_Parameter
10269 (Expr_Node : Node_Id;
10270 Parameter_List : List_Id);
10271 -- Add a signed long integer expression to Parameters
10273 procedure Initialize_Parameter_List
10274 (Name_String : String_Id;
10275 Repo_Id_String : String_Id;
10276 Parameter_List : out List_Id);
10277 -- Return a list that contains the first two parameters
10278 -- for a parameterized typecode: name and repository id.
10280 function Make_Constructed_TypeCode
10281 (Kind : Entity_Id;
10282 Parameters : List_Id) return Node_Id;
10283 -- Call Build_Complex_TC with the given kind and parameters
10285 procedure Return_Constructed_TypeCode (Kind : Entity_Id);
10286 -- Make a return statement that calls Build_Complex_TC with the
10287 -- given typecode kind, and the constructed parameters list.
10289 procedure Return_Alias_TypeCode (Base_TypeCode : Node_Id);
10290 -- Return a typecode that is a TC_Alias for the given typecode
10292 --------------------------
10293 -- Add_String_Parameter --
10294 --------------------------
10296 procedure Add_String_Parameter
10297 (S : String_Id;
10298 Parameter_List : List_Id)
10300 begin
10301 Append_To (Parameter_List,
10302 Make_Function_Call (Loc,
10303 Name => New_Occurrence_Of (RTE (RE_TA_Std_String), Loc),
10304 Parameter_Associations => New_List (
10305 Make_String_Literal (Loc, S))));
10306 end Add_String_Parameter;
10308 ----------------------------
10309 -- Add_TypeCode_Parameter --
10310 ----------------------------
10312 procedure Add_TypeCode_Parameter
10313 (TC_Node : Node_Id;
10314 Parameter_List : List_Id)
10316 begin
10317 Append_To (Parameter_List,
10318 Make_Function_Call (Loc,
10319 Name => New_Occurrence_Of (RTE (RE_TA_TC), Loc),
10320 Parameter_Associations => New_List (TC_Node)));
10321 end Add_TypeCode_Parameter;
10323 ------------------------
10324 -- Add_Long_Parameter --
10325 ------------------------
10327 procedure Add_Long_Parameter
10328 (Expr_Node : Node_Id;
10329 Parameter_List : List_Id)
10331 begin
10332 Append_To (Parameter_List,
10333 Make_Function_Call (Loc,
10334 Name =>
10335 New_Occurrence_Of (RTE (RE_TA_I32), Loc),
10336 Parameter_Associations => New_List (Expr_Node)));
10337 end Add_Long_Parameter;
10339 -------------------------------
10340 -- Initialize_Parameter_List --
10341 -------------------------------
10343 procedure Initialize_Parameter_List
10344 (Name_String : String_Id;
10345 Repo_Id_String : String_Id;
10346 Parameter_List : out List_Id)
10348 begin
10349 Parameter_List := New_List;
10350 Add_String_Parameter (Name_String, Parameter_List);
10351 Add_String_Parameter (Repo_Id_String, Parameter_List);
10352 end Initialize_Parameter_List;
10354 ---------------------------
10355 -- Return_Alias_TypeCode --
10356 ---------------------------
10358 procedure Return_Alias_TypeCode (Base_TypeCode : Node_Id) is
10359 begin
10360 Add_TypeCode_Parameter (Base_TypeCode, Parameters);
10361 Return_Constructed_TypeCode (RTE (RE_Tk_Alias));
10362 end Return_Alias_TypeCode;
10364 -------------------------------
10365 -- Make_Constructed_TypeCode --
10366 -------------------------------
10368 function Make_Constructed_TypeCode
10369 (Kind : Entity_Id;
10370 Parameters : List_Id) return Node_Id
10372 Constructed_TC : constant Node_Id :=
10373 Make_Function_Call (Loc,
10374 Name =>
10375 New_Occurrence_Of (RTE (RE_Build_Complex_TC), Loc),
10376 Parameter_Associations => New_List (
10377 New_Occurrence_Of (Kind, Loc),
10378 Make_Aggregate (Loc,
10379 Expressions => Parameters)));
10380 begin
10381 Set_Etype (Constructed_TC, RTE (RE_TypeCode));
10382 return Constructed_TC;
10383 end Make_Constructed_TypeCode;
10385 ---------------------------------
10386 -- Return_Constructed_TypeCode --
10387 ---------------------------------
10389 procedure Return_Constructed_TypeCode (Kind : Entity_Id) is
10390 begin
10391 Append_To (Stms,
10392 Make_Simple_Return_Statement (Loc,
10393 Expression =>
10394 Make_Constructed_TypeCode (Kind, Parameters)));
10395 end Return_Constructed_TypeCode;
10397 ------------------
10398 -- Record types --
10399 ------------------
10401 procedure TC_Rec_Add_Process_Element
10402 (Params : List_Id;
10403 Any : Entity_Id;
10404 Counter : in out Nat;
10405 Rec : Entity_Id;
10406 Field : Node_Id);
10408 procedure TC_Append_Record_Traversal is
10409 new Append_Record_Traversal (
10410 Rec => Empty,
10411 Add_Process_Element => TC_Rec_Add_Process_Element);
10413 --------------------------------
10414 -- TC_Rec_Add_Process_Element --
10415 --------------------------------
10417 procedure TC_Rec_Add_Process_Element
10418 (Params : List_Id;
10419 Any : Entity_Id;
10420 Counter : in out Nat;
10421 Rec : Entity_Id;
10422 Field : Node_Id)
10424 pragma Unreferenced (Any, Counter, Rec);
10426 begin
10427 if Nkind (Field) = N_Defining_Identifier then
10429 -- A regular component
10431 Add_TypeCode_Parameter
10432 (Build_TypeCode_Call (Loc, Etype (Field), Decls), Params);
10433 Get_Name_String (Chars (Field));
10434 Add_String_Parameter (String_From_Name_Buffer, Params);
10436 else
10438 -- A variant part
10440 Variant_Part : declare
10441 Disc_Type : constant Entity_Id := Etype (Name (Field));
10443 Is_Enum : constant Boolean :=
10444 Is_Enumeration_Type (Disc_Type);
10446 Union_TC_Params : List_Id;
10448 U_Name : constant Name_Id :=
10449 New_External_Name (Chars (Typ), 'V', -1);
10451 Name_Str : String_Id;
10452 Struct_TC_Params : List_Id;
10454 Variant : Node_Id;
10455 Choice : Node_Id;
10456 Default : constant Node_Id :=
10457 Make_Integer_Literal (Loc, -1);
10459 Dummy_Counter : Nat := 0;
10461 Choice_Index : Int := 0;
10462 -- Index of current choice in TypeCode, used to identify
10463 -- it as the default choice if it is a "when others".
10465 procedure Add_Params_For_Variant_Components;
10466 -- Add a struct TypeCode and a corresponding member name
10467 -- to the union parameter list.
10469 -- Ordering of declarations is a complete mess in this
10470 -- area, it is supposed to be types/variables, then
10471 -- subprogram specs, then subprogram bodies ???
10473 ---------------------------------------
10474 -- Add_Params_For_Variant_Components --
10475 ---------------------------------------
10477 procedure Add_Params_For_Variant_Components is
10478 S_Name : constant Name_Id :=
10479 New_External_Name (U_Name, 'S', -1);
10481 begin
10482 Get_Name_String (S_Name);
10483 Name_Str := String_From_Name_Buffer;
10484 Initialize_Parameter_List
10485 (Name_Str, Name_Str, Struct_TC_Params);
10487 -- Build struct parameters
10489 TC_Append_Record_Traversal (Struct_TC_Params,
10490 Component_List (Variant),
10491 Empty,
10492 Dummy_Counter);
10494 Add_TypeCode_Parameter
10495 (Make_Constructed_TypeCode
10496 (RTE (RE_Tk_Struct), Struct_TC_Params),
10497 Union_TC_Params);
10499 Add_String_Parameter (Name_Str, Union_TC_Params);
10500 end Add_Params_For_Variant_Components;
10502 -- Start of processing for Variant_Part
10504 begin
10505 Get_Name_String (U_Name);
10506 Name_Str := String_From_Name_Buffer;
10508 Initialize_Parameter_List
10509 (Name_Str, Name_Str, Union_TC_Params);
10511 -- Add union in enclosing parameter list
10513 Add_TypeCode_Parameter
10514 (Make_Constructed_TypeCode
10515 (RTE (RE_Tk_Union), Union_TC_Params),
10516 Params);
10518 Add_String_Parameter (Name_Str, Params);
10520 -- Build union parameters
10522 Add_TypeCode_Parameter
10523 (Build_TypeCode_Call (Loc, Disc_Type, Decls),
10524 Union_TC_Params);
10526 Add_Long_Parameter (Default, Union_TC_Params);
10528 Variant := First_Non_Pragma (Variants (Field));
10529 while Present (Variant) loop
10530 Choice := First (Discrete_Choices (Variant));
10531 while Present (Choice) loop
10532 case Nkind (Choice) is
10533 when N_Range =>
10534 declare
10535 L : constant Uint :=
10536 Expr_Value (Low_Bound (Choice));
10537 H : constant Uint :=
10538 Expr_Value (High_Bound (Choice));
10539 J : Uint := L;
10540 -- 3.8.1(8) guarantees that the bounds of
10541 -- this range are static.
10543 Expr : Node_Id;
10545 begin
10546 while J <= H loop
10547 if Is_Enum then
10548 Expr := Get_Enum_Lit_From_Pos
10549 (Disc_Type, J, Loc);
10550 else
10551 Expr :=
10552 Make_Integer_Literal (Loc, J);
10553 end if;
10555 Set_Etype (Expr, Disc_Type);
10556 Append_To (Union_TC_Params,
10557 Build_To_Any_Call (Loc, Expr, Decls));
10559 Add_Params_For_Variant_Components;
10560 J := J + Uint_1;
10561 end loop;
10563 Choice_Index :=
10564 Choice_Index + UI_To_Int (H - L) + 1;
10565 end;
10567 when N_Others_Choice =>
10569 -- This variant has a default choice. We must
10570 -- therefore set the default parameter to the
10571 -- current choice index. This parameter is by
10572 -- construction the 4th in Union_TC_Params.
10574 Replace
10575 (Pick (Union_TC_Params, 4),
10576 Make_Function_Call (Loc,
10577 Name =>
10578 New_Occurrence_Of
10579 (RTE (RE_TA_I32), Loc),
10580 Parameter_Associations =>
10581 New_List (
10582 Make_Integer_Literal (Loc,
10583 Intval => Choice_Index))));
10585 -- Add a placeholder member label for the
10586 -- default case, which must have the
10587 -- discriminant type.
10589 declare
10590 Exp : constant Node_Id :=
10591 Make_Attribute_Reference (Loc,
10592 Prefix => New_Occurrence_Of
10593 (Disc_Type, Loc),
10594 Attribute_Name => Name_First);
10595 begin
10596 Set_Etype (Exp, Disc_Type);
10597 Append_To (Union_TC_Params,
10598 Build_To_Any_Call (Loc, Exp, Decls));
10599 end;
10601 Add_Params_For_Variant_Components;
10602 Choice_Index := Choice_Index + 1;
10604 -- Case of an explicit choice
10606 when others =>
10607 declare
10608 Exp : constant Node_Id :=
10609 New_Copy_Tree (Choice);
10610 begin
10611 Append_To (Union_TC_Params,
10612 Build_To_Any_Call (Loc, Exp, Decls));
10613 end;
10615 Add_Params_For_Variant_Components;
10616 Choice_Index := Choice_Index + 1;
10617 end case;
10619 Next (Choice);
10620 end loop;
10622 Next_Non_Pragma (Variant);
10623 end loop;
10624 end Variant_Part;
10625 end if;
10626 end TC_Rec_Add_Process_Element;
10628 Type_Name_Str : String_Id;
10629 Type_Repo_Id_Str : String_Id;
10631 Real_Rep : Node_Id;
10633 -- Start of processing for Build_TypeCode_Function
10635 begin
10636 -- For a derived type, we can't go past the base type (to the
10637 -- parent type) here, because that would cause the attribute's
10638 -- formal parameter to have the wrong type; hence the Base_Type
10639 -- check here.
10641 if Is_Itype (Typ) and then Typ /= Base_Type (Typ) then
10642 Build_TypeCode_Function
10643 (Loc => Loc,
10644 Typ => Etype (Typ),
10645 Decl => Decl,
10646 Fnam => Fnam);
10647 return;
10648 end if;
10650 Fnam := TCNam;
10652 Spec :=
10653 Make_Function_Specification (Loc,
10654 Defining_Unit_Name => Fnam,
10655 Parameter_Specifications => Empty_List,
10656 Result_Definition =>
10657 New_Occurrence_Of (RTE (RE_TypeCode), Loc));
10659 Build_Name_And_Repository_Id (Typ,
10660 Name_Str => Type_Name_Str, Repo_Id_Str => Type_Repo_Id_Str);
10662 Initialize_Parameter_List
10663 (Type_Name_Str, Type_Repo_Id_Str, Parameters);
10665 if Has_Stream_Attribute_Definition
10666 (Typ, TSS_Stream_Output, Real_Rep, At_Any_Place => True)
10667 or else
10668 Has_Stream_Attribute_Definition
10669 (Typ, TSS_Stream_Write, Real_Rep, At_Any_Place => True)
10670 then
10671 -- If user-defined stream attributes are specified for this
10672 -- type, use them and transmit data as an opaque sequence of
10673 -- stream elements.
10675 Return_Alias_TypeCode
10676 (New_Occurrence_Of (RTE (RE_TC_Opaque), Loc));
10678 elsif Is_Derived_Type (Typ) and then not Is_Tagged_Type (Typ) then
10679 Return_Alias_TypeCode (
10680 Build_TypeCode_Call (Loc, Etype (Typ), Decls));
10682 elsif Is_Integer_Type (Typ) or else Is_Unsigned_Type (Typ) then
10683 Return_Alias_TypeCode (
10684 Build_TypeCode_Call (Loc,
10685 Find_Numeric_Representation (Typ), Decls));
10687 elsif Is_Record_Type (Typ) and then not Is_Tagged_Type (Typ) then
10689 -- Record typecodes are encoded as follows:
10690 -- -- TC_STRUCT
10691 -- |
10692 -- | [Name]
10693 -- | [Repository Id]
10695 -- Then for each discriminant:
10697 -- | [Discriminant Type Code]
10698 -- | [Discriminant Name]
10699 -- | ...
10701 -- Then for each component:
10703 -- | [Component Type Code]
10704 -- | [Component Name]
10705 -- | ...
10707 -- Variants components type codes are encoded as follows:
10708 -- -- TC_UNION
10709 -- |
10710 -- | [Name]
10711 -- | [Repository Id]
10712 -- | [Discriminant Type Code]
10713 -- | [Index of Default Variant Part or -1 for no default]
10715 -- Then for each Variant Part :
10717 -- | [VP Label]
10718 -- |
10719 -- | -- TC_STRUCT
10720 -- | | [Variant Part Name]
10721 -- | | [Variant Part Repository Id]
10722 -- | |
10723 -- | Then for each VP component:
10724 -- | | [VP component Typecode]
10725 -- | | [VP component Name]
10726 -- | | ...
10727 -- | --
10728 -- |
10729 -- | [VP Name]
10731 if Nkind (Declaration_Node (Typ)) = N_Subtype_Declaration then
10732 Return_Alias_TypeCode
10733 (Build_TypeCode_Call (Loc, Etype (Typ), Decls));
10735 else
10736 declare
10737 Disc : Entity_Id := Empty;
10738 Rdef : constant Node_Id :=
10739 Type_Definition (Declaration_Node (Typ));
10740 Dummy_Counter : Int := 0;
10742 begin
10743 -- Construct the discriminants typecodes
10745 if Has_Discriminants (Typ) then
10746 Disc := First_Discriminant (Typ);
10747 end if;
10749 while Present (Disc) loop
10750 Add_TypeCode_Parameter (
10751 Build_TypeCode_Call (Loc, Etype (Disc), Decls),
10752 Parameters);
10753 Get_Name_String (Chars (Disc));
10754 Add_String_Parameter (
10755 String_From_Name_Buffer,
10756 Parameters);
10757 Next_Discriminant (Disc);
10758 end loop;
10760 -- then the components typecodes
10762 TC_Append_Record_Traversal
10763 (Parameters, Component_List (Rdef),
10764 Empty, Dummy_Counter);
10765 Return_Constructed_TypeCode (RTE (RE_Tk_Struct));
10766 end;
10767 end if;
10769 elsif Is_Array_Type (Typ) then
10770 declare
10771 Ndim : constant Pos := Number_Dimensions (Typ);
10772 Inner_TypeCode : Node_Id;
10773 Constrained : constant Boolean := Is_Constrained (Typ);
10774 Indx : Node_Id := First_Index (Typ);
10776 begin
10777 Inner_TypeCode :=
10778 Build_TypeCode_Call (Loc, Component_Type (Typ), Decls);
10780 for J in 1 .. Ndim loop
10781 if Constrained then
10782 Inner_TypeCode := Make_Constructed_TypeCode
10783 (RTE (RE_Tk_Array), New_List (
10784 Build_To_Any_Call (Loc,
10785 OK_Convert_To (RTE (RE_Unsigned_32),
10786 Make_Attribute_Reference (Loc,
10787 Prefix => New_Occurrence_Of (Typ, Loc),
10788 Attribute_Name => Name_Length,
10789 Expressions => New_List (
10790 Make_Integer_Literal (Loc,
10791 Intval => Ndim - J + 1)))),
10792 Decls),
10793 Build_To_Any_Call (Loc, Inner_TypeCode, Decls)));
10795 else
10796 -- Unconstrained case: add low bound for each
10797 -- dimension.
10799 Add_TypeCode_Parameter
10800 (Build_TypeCode_Call (Loc, Etype (Indx), Decls),
10801 Parameters);
10802 Get_Name_String (New_External_Name ('L', J));
10803 Add_String_Parameter (
10804 String_From_Name_Buffer,
10805 Parameters);
10806 Next_Index (Indx);
10808 Inner_TypeCode := Make_Constructed_TypeCode
10809 (RTE (RE_Tk_Sequence), New_List (
10810 Build_To_Any_Call (Loc,
10811 OK_Convert_To (RTE (RE_Unsigned_32),
10812 Make_Integer_Literal (Loc, 0)),
10813 Decls),
10814 Build_To_Any_Call (Loc, Inner_TypeCode, Decls)));
10815 end if;
10816 end loop;
10818 if Constrained then
10819 Return_Alias_TypeCode (Inner_TypeCode);
10820 else
10821 Add_TypeCode_Parameter (Inner_TypeCode, Parameters);
10822 Start_String;
10823 Store_String_Char ('V');
10824 Add_String_Parameter (End_String, Parameters);
10825 Return_Constructed_TypeCode (RTE (RE_Tk_Struct));
10826 end if;
10827 end;
10829 else
10830 -- Default: type is represented as an opaque sequence of bytes
10832 Return_Alias_TypeCode
10833 (New_Occurrence_Of (RTE (RE_TC_Opaque), Loc));
10834 end if;
10836 Decl :=
10837 Make_Subprogram_Body (Loc,
10838 Specification => Spec,
10839 Declarations => Decls,
10840 Handled_Statement_Sequence =>
10841 Make_Handled_Sequence_Of_Statements (Loc,
10842 Statements => Stms));
10843 end Build_TypeCode_Function;
10845 ---------------------------------
10846 -- Find_Numeric_Representation --
10847 ---------------------------------
10849 function Find_Numeric_Representation
10850 (Typ : Entity_Id) return Entity_Id
10852 FST : constant Entity_Id := First_Subtype (Typ);
10853 P_Size : constant Uint := Esize (FST);
10855 begin
10856 -- Special case: for Stream_Element_Offset and Storage_Offset,
10857 -- always force transmission as a 64-bit value.
10859 if Is_RTE (FST, RE_Stream_Element_Offset)
10860 or else
10861 Is_RTE (FST, RE_Storage_Offset)
10862 then
10863 return RTE (RE_Unsigned_64);
10864 end if;
10866 if Is_Unsigned_Type (Typ) then
10867 if P_Size <= 8 then
10868 return RTE (RE_Unsigned_8);
10870 elsif P_Size <= 16 then
10871 return RTE (RE_Unsigned_16);
10873 elsif P_Size <= 32 then
10874 return RTE (RE_Unsigned_32);
10876 else
10877 return RTE (RE_Unsigned_64);
10878 end if;
10880 elsif Is_Integer_Type (Typ) then
10881 if P_Size <= 8 then
10882 return RTE (RE_Integer_8);
10884 elsif P_Size <= Standard_Short_Integer_Size then
10885 return RTE (RE_Integer_16);
10887 elsif P_Size <= Standard_Integer_Size then
10888 return RTE (RE_Integer_32);
10890 else
10891 return RTE (RE_Integer_64);
10892 end if;
10894 elsif Is_Floating_Point_Type (Typ) then
10895 if P_Size <= Standard_Short_Float_Size then
10896 return Standard_Short_Float;
10898 elsif P_Size <= Standard_Float_Size then
10899 return Standard_Float;
10901 elsif P_Size <= Standard_Long_Float_Size then
10902 return Standard_Long_Float;
10904 else
10905 return Standard_Long_Long_Float;
10906 end if;
10908 else
10909 raise Program_Error;
10910 end if;
10912 -- What about fixed point types and numeric types with a biased
10913 -- representation???
10915 end Find_Numeric_Representation;
10917 ---------------------------------
10918 -- Is_Generic_Actual_Subtype --
10919 ---------------------------------
10921 function Is_Generic_Actual_Subtype (Typ : Entity_Id) return Boolean is
10922 begin
10923 if Is_Itype (Typ)
10924 and then Present (Associated_Node_For_Itype (Typ))
10925 then
10926 declare
10927 N : constant Node_Id := Associated_Node_For_Itype (Typ);
10928 begin
10929 if Nkind (N) = N_Subtype_Declaration
10930 and then Nkind (Parent (N)) = N_Package_Specification
10931 and then Is_Generic_Instance (Scope_Of_Spec (Parent (N)))
10932 then
10933 return True;
10934 end if;
10935 end;
10936 end if;
10938 return False;
10939 end Is_Generic_Actual_Subtype;
10941 ---------------------------
10942 -- Append_Array_Traversal --
10943 ---------------------------
10945 procedure Append_Array_Traversal
10946 (Stmts : List_Id;
10947 Any : Entity_Id;
10948 Counter : Entity_Id := Empty;
10949 Depth : Pos := 1)
10951 Loc : constant Source_Ptr := Sloc (Subprogram);
10952 Typ : constant Entity_Id := Etype (Arry);
10953 Constrained : constant Boolean := Is_Constrained (Typ);
10954 Ndim : constant Pos := Number_Dimensions (Typ);
10956 Inner_Any, Inner_Counter : Entity_Id;
10958 Loop_Stm : Node_Id;
10959 Inner_Stmts : constant List_Id := New_List;
10961 begin
10962 if Depth > Ndim then
10964 -- Processing for one element of an array
10966 declare
10967 Element_Expr : constant Node_Id :=
10968 Make_Indexed_Component (Loc,
10969 New_Occurrence_Of (Arry, Loc),
10970 Indexes);
10971 begin
10972 Set_Etype (Element_Expr, Component_Type (Typ));
10973 Add_Process_Element (Stmts,
10974 Any => Any,
10975 Counter => Counter,
10976 Datum => Element_Expr);
10977 end;
10979 return;
10980 end if;
10982 Append_To (Indexes,
10983 Make_Identifier (Loc, New_External_Name ('L', Depth)));
10985 if not Constrained or else Depth > 1 then
10986 Inner_Any := Make_Defining_Identifier (Loc,
10987 New_External_Name ('A', Depth));
10988 Set_Etype (Inner_Any, RTE (RE_Any));
10989 else
10990 Inner_Any := Empty;
10991 end if;
10993 if Present (Counter) then
10994 Inner_Counter := Make_Defining_Identifier (Loc,
10995 New_External_Name ('J', Depth));
10996 else
10997 Inner_Counter := Empty;
10998 end if;
11000 declare
11001 Loop_Any : Node_Id := Inner_Any;
11003 begin
11004 -- For the first dimension of a constrained array, we add
11005 -- elements directly in the corresponding Any; there is no
11006 -- intervening inner Any.
11008 if No (Loop_Any) then
11009 Loop_Any := Any;
11010 end if;
11012 Append_Array_Traversal (Inner_Stmts,
11013 Any => Loop_Any,
11014 Counter => Inner_Counter,
11015 Depth => Depth + 1);
11016 end;
11018 Loop_Stm :=
11019 Make_Implicit_Loop_Statement (Subprogram,
11020 Iteration_Scheme =>
11021 Make_Iteration_Scheme (Loc,
11022 Loop_Parameter_Specification =>
11023 Make_Loop_Parameter_Specification (Loc,
11024 Defining_Identifier =>
11025 Make_Defining_Identifier (Loc,
11026 Chars => New_External_Name ('L', Depth)),
11028 Discrete_Subtype_Definition =>
11029 Make_Attribute_Reference (Loc,
11030 Prefix => New_Occurrence_Of (Arry, Loc),
11031 Attribute_Name => Name_Range,
11033 Expressions => New_List (
11034 Make_Integer_Literal (Loc, Depth))))),
11035 Statements => Inner_Stmts);
11037 declare
11038 Decls : constant List_Id := New_List;
11039 Dimen_Stmts : constant List_Id := New_List;
11040 Length_Node : Node_Id;
11042 Inner_Any_TypeCode : constant Entity_Id :=
11043 Make_Defining_Identifier (Loc,
11044 New_External_Name ('T', Depth));
11046 Inner_Any_TypeCode_Expr : Node_Id;
11048 begin
11049 if Depth = 1 then
11050 if Constrained then
11051 Inner_Any_TypeCode_Expr :=
11052 Make_Function_Call (Loc,
11053 Name => New_Occurrence_Of (RTE (RE_Get_TC), Loc),
11054 Parameter_Associations => New_List (
11055 New_Occurrence_Of (Any, Loc)));
11057 else
11058 Inner_Any_TypeCode_Expr :=
11059 Make_Function_Call (Loc,
11060 Name =>
11061 New_Occurrence_Of (RTE (RE_Any_Member_Type), Loc),
11062 Parameter_Associations => New_List (
11063 New_Occurrence_Of (Any, Loc),
11064 Make_Integer_Literal (Loc, Ndim)));
11065 end if;
11067 else
11068 Inner_Any_TypeCode_Expr :=
11069 Make_Function_Call (Loc,
11070 Name => New_Occurrence_Of (RTE (RE_Content_Type), Loc),
11071 Parameter_Associations => New_List (
11072 Make_Identifier (Loc,
11073 Chars => New_External_Name ('T', Depth - 1))));
11074 end if;
11076 Append_To (Decls,
11077 Make_Object_Declaration (Loc,
11078 Defining_Identifier => Inner_Any_TypeCode,
11079 Constant_Present => True,
11080 Object_Definition => New_Occurrence_Of (
11081 RTE (RE_TypeCode), Loc),
11082 Expression => Inner_Any_TypeCode_Expr));
11084 if Present (Inner_Any) then
11085 Append_To (Decls,
11086 Make_Object_Declaration (Loc,
11087 Defining_Identifier => Inner_Any,
11088 Object_Definition =>
11089 New_Occurrence_Of (RTE (RE_Any), Loc),
11090 Expression =>
11091 Make_Function_Call (Loc,
11092 Name =>
11093 New_Occurrence_Of (
11094 RTE (RE_Create_Any), Loc),
11095 Parameter_Associations => New_List (
11096 New_Occurrence_Of (Inner_Any_TypeCode, Loc)))));
11097 end if;
11099 if Present (Inner_Counter) then
11100 Append_To (Decls,
11101 Make_Object_Declaration (Loc,
11102 Defining_Identifier => Inner_Counter,
11103 Object_Definition =>
11104 New_Occurrence_Of (RTE (RE_Unsigned_32), Loc),
11105 Expression =>
11106 Make_Integer_Literal (Loc, 0)));
11107 end if;
11109 if not Constrained then
11110 Length_Node := Make_Attribute_Reference (Loc,
11111 Prefix => New_Occurrence_Of (Arry, Loc),
11112 Attribute_Name => Name_Length,
11113 Expressions =>
11114 New_List (Make_Integer_Literal (Loc, Depth)));
11115 Set_Etype (Length_Node, RTE (RE_Unsigned_32));
11117 Add_Process_Element (Dimen_Stmts,
11118 Datum => Length_Node,
11119 Any => Inner_Any,
11120 Counter => Inner_Counter);
11121 end if;
11123 -- Loop_Stm does appropriate processing for each element
11124 -- of Inner_Any.
11126 Append_To (Dimen_Stmts, Loop_Stm);
11128 -- Link outer and inner any
11130 if Present (Inner_Any) then
11131 Add_Process_Element (Dimen_Stmts,
11132 Any => Any,
11133 Counter => Counter,
11134 Datum => New_Occurrence_Of (Inner_Any, Loc));
11135 end if;
11137 Append_To (Stmts,
11138 Make_Block_Statement (Loc,
11139 Declarations =>
11140 Decls,
11141 Handled_Statement_Sequence =>
11142 Make_Handled_Sequence_Of_Statements (Loc,
11143 Statements => Dimen_Stmts)));
11144 end;
11145 end Append_Array_Traversal;
11147 -------------------------------
11148 -- Make_Helper_Function_Name --
11149 -------------------------------
11151 function Make_Helper_Function_Name
11152 (Loc : Source_Ptr;
11153 Typ : Entity_Id;
11154 Nam : Name_Id) return Entity_Id
11156 begin
11157 declare
11158 Serial : Nat := 0;
11159 -- For tagged types that aren't frozen yet, generate the helper
11160 -- under its canonical name so that it matches the primitive
11161 -- spec. For all other cases, we use a serialized name so that
11162 -- multiple generations of the same procedure do not clash.
11164 begin
11165 if Is_Tagged_Type (Typ) and then not Is_Frozen (Typ) then
11166 null;
11167 else
11168 Serial := Increment_Serial_Number;
11169 end if;
11171 -- Use prefixed underscore to avoid potential clash with user
11172 -- identifier (we use attribute names for Nam).
11174 return
11175 Make_Defining_Identifier (Loc,
11176 Chars =>
11177 New_External_Name
11178 (Related_Id => Nam,
11179 Suffix => ' ',
11180 Suffix_Index => Serial,
11181 Prefix => '_'));
11182 end;
11183 end Make_Helper_Function_Name;
11184 end Helpers;
11186 -----------------------------------
11187 -- Reserve_NamingContext_Methods --
11188 -----------------------------------
11190 procedure Reserve_NamingContext_Methods is
11191 Str_Resolve : constant String := "resolve";
11192 begin
11193 Name_Buffer (1 .. Str_Resolve'Length) := Str_Resolve;
11194 Name_Len := Str_Resolve'Length;
11195 Overload_Counter_Table.Set (Name_Find, 1);
11196 end Reserve_NamingContext_Methods;
11198 -----------------------
11199 -- RPC_Receiver_Decl --
11200 -----------------------
11202 function RPC_Receiver_Decl (RACW_Type : Entity_Id) return Node_Id is
11203 Loc : constant Source_Ptr := Sloc (RACW_Type);
11204 begin
11205 return
11206 Make_Object_Declaration (Loc,
11207 Defining_Identifier => Make_Temporary (Loc, 'R'),
11208 Aliased_Present => True,
11209 Object_Definition => New_Occurrence_Of (RTE (RE_Servant), Loc));
11210 end RPC_Receiver_Decl;
11212 end PolyORB_Support;
11214 -------------------------------
11215 -- RACW_Type_Is_Asynchronous --
11216 -------------------------------
11218 procedure RACW_Type_Is_Asynchronous (RACW_Type : Entity_Id) is
11219 Asynchronous_Flag : constant Entity_Id :=
11220 Asynchronous_Flags_Table.Get (RACW_Type);
11221 begin
11222 Replace (Expression (Parent (Asynchronous_Flag)),
11223 New_Occurrence_Of (Standard_True, Sloc (Asynchronous_Flag)));
11224 end RACW_Type_Is_Asynchronous;
11226 -------------------------
11227 -- RCI_Package_Locator --
11228 -------------------------
11230 function RCI_Package_Locator
11231 (Loc : Source_Ptr;
11232 Package_Spec : Node_Id) return Node_Id
11234 Inst : Node_Id;
11235 Pkg_Name : constant String_Id :=
11236 Fully_Qualified_Name_String
11237 (Defining_Entity (Package_Spec), Append_NUL => False);
11239 begin
11240 Inst :=
11241 Make_Package_Instantiation (Loc,
11242 Defining_Unit_Name => Make_Temporary (Loc, 'R'),
11244 Name =>
11245 New_Occurrence_Of (RTE (RE_RCI_Locator), Loc),
11247 Generic_Associations => New_List (
11248 Make_Generic_Association (Loc,
11249 Selector_Name =>
11250 Make_Identifier (Loc, Name_RCI_Name),
11251 Explicit_Generic_Actual_Parameter =>
11252 Make_String_Literal (Loc,
11253 Strval => Pkg_Name)),
11255 Make_Generic_Association (Loc,
11256 Selector_Name =>
11257 Make_Identifier (Loc, Name_Version),
11258 Explicit_Generic_Actual_Parameter =>
11259 Make_Attribute_Reference (Loc,
11260 Prefix =>
11261 New_Occurrence_Of (Defining_Entity (Package_Spec), Loc),
11262 Attribute_Name =>
11263 Name_Version))));
11265 RCI_Locator_Table.Set
11266 (Defining_Unit_Name (Package_Spec),
11267 Defining_Unit_Name (Inst));
11268 return Inst;
11269 end RCI_Package_Locator;
11271 -----------------------------------------------
11272 -- Remote_Types_Tagged_Full_View_Encountered --
11273 -----------------------------------------------
11275 procedure Remote_Types_Tagged_Full_View_Encountered
11276 (Full_View : Entity_Id)
11278 Stub_Elements : constant Stub_Structure :=
11279 Stubs_Table.Get (Full_View);
11281 begin
11282 -- For an RACW encountered before the freeze point of its designated
11283 -- type, the stub type is generated at the point of the RACW declaration
11284 -- but the primitives are generated only once the designated type is
11285 -- frozen. That freeze can occur in another scope, for example when the
11286 -- RACW is declared in a nested package. In that case we need to
11287 -- reestablish the stub type's scope prior to generating its primitive
11288 -- operations.
11290 if Stub_Elements /= Empty_Stub_Structure then
11291 declare
11292 Saved_Scope : constant Entity_Id := Current_Scope;
11293 Stubs_Scope : constant Entity_Id :=
11294 Scope (Stub_Elements.Stub_Type);
11296 begin
11297 if Current_Scope /= Stubs_Scope then
11298 Push_Scope (Stubs_Scope);
11299 end if;
11301 Add_RACW_Primitive_Declarations_And_Bodies
11302 (Full_View,
11303 Stub_Elements.RPC_Receiver_Decl,
11304 Stub_Elements.Body_Decls);
11306 if Current_Scope /= Saved_Scope then
11307 Pop_Scope;
11308 end if;
11309 end;
11310 end if;
11311 end Remote_Types_Tagged_Full_View_Encountered;
11313 -------------------
11314 -- Scope_Of_Spec --
11315 -------------------
11317 function Scope_Of_Spec (Spec : Node_Id) return Entity_Id is
11318 Unit_Name : Node_Id;
11320 begin
11321 Unit_Name := Defining_Unit_Name (Spec);
11322 while Nkind (Unit_Name) /= N_Defining_Identifier loop
11323 Unit_Name := Defining_Identifier (Unit_Name);
11324 end loop;
11326 return Unit_Name;
11327 end Scope_Of_Spec;
11329 ----------------------
11330 -- Set_Renaming_TSS --
11331 ----------------------
11333 procedure Set_Renaming_TSS
11334 (Typ : Entity_Id;
11335 Nam : Entity_Id;
11336 TSS_Nam : TSS_Name_Type)
11338 Loc : constant Source_Ptr := Sloc (Nam);
11339 Spec : constant Node_Id := Parent (Nam);
11341 TSS_Node : constant Node_Id :=
11342 Make_Subprogram_Renaming_Declaration (Loc,
11343 Specification =>
11344 Copy_Specification (Loc,
11345 Spec => Spec,
11346 New_Name => Make_TSS_Name (Typ, TSS_Nam)),
11347 Name => New_Occurrence_Of (Nam, Loc));
11349 Snam : constant Entity_Id :=
11350 Defining_Unit_Name (Specification (TSS_Node));
11352 begin
11353 if Nkind (Spec) = N_Function_Specification then
11354 Mutate_Ekind (Snam, E_Function);
11355 Set_Etype (Snam, Entity (Result_Definition (Spec)));
11356 else
11357 Mutate_Ekind (Snam, E_Procedure);
11358 Set_Etype (Snam, Standard_Void_Type);
11359 end if;
11361 Set_TSS (Typ, Snam);
11362 end Set_Renaming_TSS;
11364 ----------------------------------------------
11365 -- Specific_Add_Obj_RPC_Receiver_Completion --
11366 ----------------------------------------------
11368 procedure Specific_Add_Obj_RPC_Receiver_Completion
11369 (Loc : Source_Ptr;
11370 Decls : List_Id;
11371 RPC_Receiver : Entity_Id;
11372 Stub_Elements : Stub_Structure)
11374 begin
11375 case Get_PCS_Name is
11376 when Name_PolyORB_DSA =>
11377 PolyORB_Support.Add_Obj_RPC_Receiver_Completion
11378 (Loc, Decls, RPC_Receiver, Stub_Elements);
11380 when others =>
11381 GARLIC_Support.Add_Obj_RPC_Receiver_Completion
11382 (Loc, Decls, RPC_Receiver, Stub_Elements);
11383 end case;
11384 end Specific_Add_Obj_RPC_Receiver_Completion;
11386 --------------------------------
11387 -- Specific_Add_RACW_Features --
11388 --------------------------------
11390 procedure Specific_Add_RACW_Features
11391 (RACW_Type : Entity_Id;
11392 Desig : Entity_Id;
11393 Stub_Type : Entity_Id;
11394 Stub_Type_Access : Entity_Id;
11395 RPC_Receiver_Decl : Node_Id;
11396 Body_Decls : List_Id)
11398 begin
11399 case Get_PCS_Name is
11400 when Name_PolyORB_DSA =>
11401 PolyORB_Support.Add_RACW_Features
11402 (RACW_Type,
11403 Desig,
11404 Stub_Type,
11405 Stub_Type_Access,
11406 RPC_Receiver_Decl,
11407 Body_Decls);
11409 when others =>
11410 GARLIC_Support.Add_RACW_Features
11411 (RACW_Type,
11412 Stub_Type,
11413 Stub_Type_Access,
11414 RPC_Receiver_Decl,
11415 Body_Decls);
11416 end case;
11417 end Specific_Add_RACW_Features;
11419 --------------------------------
11420 -- Specific_Add_RAST_Features --
11421 --------------------------------
11423 procedure Specific_Add_RAST_Features
11424 (Vis_Decl : Node_Id;
11425 RAS_Type : Entity_Id)
11427 begin
11428 case Get_PCS_Name is
11429 when Name_PolyORB_DSA =>
11430 PolyORB_Support.Add_RAST_Features (Vis_Decl, RAS_Type);
11432 when others =>
11433 GARLIC_Support.Add_RAST_Features (Vis_Decl, RAS_Type);
11434 end case;
11435 end Specific_Add_RAST_Features;
11437 --------------------------------------------------
11438 -- Specific_Add_Receiving_Stubs_To_Declarations --
11439 --------------------------------------------------
11441 procedure Specific_Add_Receiving_Stubs_To_Declarations
11442 (Pkg_Spec : Node_Id;
11443 Decls : List_Id;
11444 Stmts : List_Id)
11446 begin
11447 case Get_PCS_Name is
11448 when Name_PolyORB_DSA =>
11449 PolyORB_Support.Add_Receiving_Stubs_To_Declarations
11450 (Pkg_Spec, Decls, Stmts);
11452 when others =>
11453 GARLIC_Support.Add_Receiving_Stubs_To_Declarations
11454 (Pkg_Spec, Decls, Stmts);
11455 end case;
11456 end Specific_Add_Receiving_Stubs_To_Declarations;
11458 ------------------------------------------
11459 -- Specific_Build_General_Calling_Stubs --
11460 ------------------------------------------
11462 procedure Specific_Build_General_Calling_Stubs
11463 (Decls : List_Id;
11464 Statements : List_Id;
11465 Target : RPC_Target;
11466 Subprogram_Id : Node_Id;
11467 Asynchronous : Node_Id := Empty;
11468 Is_Known_Asynchronous : Boolean := False;
11469 Is_Known_Non_Asynchronous : Boolean := False;
11470 Is_Function : Boolean;
11471 Spec : Node_Id;
11472 Stub_Type : Entity_Id := Empty;
11473 RACW_Type : Entity_Id := Empty;
11474 Nod : Node_Id)
11476 begin
11477 case Get_PCS_Name is
11478 when Name_PolyORB_DSA =>
11479 PolyORB_Support.Build_General_Calling_Stubs
11480 (Decls,
11481 Statements,
11482 Target.Object,
11483 Subprogram_Id,
11484 Asynchronous,
11485 Is_Known_Asynchronous,
11486 Is_Known_Non_Asynchronous,
11487 Is_Function,
11488 Spec,
11489 Stub_Type,
11490 RACW_Type,
11491 Nod);
11493 when others =>
11494 GARLIC_Support.Build_General_Calling_Stubs
11495 (Decls,
11496 Statements,
11497 Target.Partition,
11498 Target.RPC_Receiver,
11499 Subprogram_Id,
11500 Asynchronous,
11501 Is_Known_Asynchronous,
11502 Is_Known_Non_Asynchronous,
11503 Is_Function,
11504 Spec,
11505 Stub_Type,
11506 RACW_Type,
11507 Nod);
11508 end case;
11509 end Specific_Build_General_Calling_Stubs;
11511 --------------------------------------
11512 -- Specific_Build_RPC_Receiver_Body --
11513 --------------------------------------
11515 procedure Specific_Build_RPC_Receiver_Body
11516 (RPC_Receiver : Entity_Id;
11517 Request : out Entity_Id;
11518 Subp_Id : out Entity_Id;
11519 Subp_Index : out Entity_Id;
11520 Stmts : out List_Id;
11521 Decl : out Node_Id)
11523 begin
11524 case Get_PCS_Name is
11525 when Name_PolyORB_DSA =>
11526 PolyORB_Support.Build_RPC_Receiver_Body
11527 (RPC_Receiver,
11528 Request,
11529 Subp_Id,
11530 Subp_Index,
11531 Stmts,
11532 Decl);
11534 when others =>
11535 GARLIC_Support.Build_RPC_Receiver_Body
11536 (RPC_Receiver,
11537 Request,
11538 Subp_Id,
11539 Subp_Index,
11540 Stmts,
11541 Decl);
11542 end case;
11543 end Specific_Build_RPC_Receiver_Body;
11545 --------------------------------
11546 -- Specific_Build_Stub_Target --
11547 --------------------------------
11549 function Specific_Build_Stub_Target
11550 (Loc : Source_Ptr;
11551 Decls : List_Id;
11552 RCI_Locator : Entity_Id;
11553 Controlling_Parameter : Entity_Id) return RPC_Target
11555 begin
11556 case Get_PCS_Name is
11557 when Name_PolyORB_DSA =>
11558 return
11559 PolyORB_Support.Build_Stub_Target
11560 (Loc, Decls, RCI_Locator, Controlling_Parameter);
11562 when others =>
11563 return
11564 GARLIC_Support.Build_Stub_Target
11565 (Loc, Decls, RCI_Locator, Controlling_Parameter);
11566 end case;
11567 end Specific_Build_Stub_Target;
11569 --------------------------------
11570 -- Specific_RPC_Receiver_Decl --
11571 --------------------------------
11573 function Specific_RPC_Receiver_Decl
11574 (RACW_Type : Entity_Id) return Node_Id
11576 begin
11577 case Get_PCS_Name is
11578 when Name_PolyORB_DSA =>
11579 return PolyORB_Support.RPC_Receiver_Decl (RACW_Type);
11581 when others =>
11582 return GARLIC_Support.RPC_Receiver_Decl (RACW_Type);
11583 end case;
11584 end Specific_RPC_Receiver_Decl;
11586 -----------------------------------------------
11587 -- Specific_Build_Subprogram_Receiving_Stubs --
11588 -----------------------------------------------
11590 function Specific_Build_Subprogram_Receiving_Stubs
11591 (Vis_Decl : Node_Id;
11592 Asynchronous : Boolean;
11593 Dynamically_Asynchronous : Boolean := False;
11594 Stub_Type : Entity_Id := Empty;
11595 RACW_Type : Entity_Id := Empty;
11596 Parent_Primitive : Entity_Id := Empty) return Node_Id
11598 begin
11599 case Get_PCS_Name is
11600 when Name_PolyORB_DSA =>
11601 return
11602 PolyORB_Support.Build_Subprogram_Receiving_Stubs
11603 (Vis_Decl,
11604 Asynchronous,
11605 Dynamically_Asynchronous,
11606 Stub_Type,
11607 RACW_Type,
11608 Parent_Primitive);
11610 when others =>
11611 return
11612 GARLIC_Support.Build_Subprogram_Receiving_Stubs
11613 (Vis_Decl,
11614 Asynchronous,
11615 Dynamically_Asynchronous,
11616 Stub_Type,
11617 RACW_Type,
11618 Parent_Primitive);
11619 end case;
11620 end Specific_Build_Subprogram_Receiving_Stubs;
11622 -------------------------------
11623 -- Transmit_As_Unconstrained --
11624 -------------------------------
11626 function Transmit_As_Unconstrained (Typ : Entity_Id) return Boolean is
11627 begin
11628 return
11629 not (Is_Elementary_Type (Typ) or else Is_Constrained (Typ))
11630 or else (Is_Access_Type (Typ) and then Can_Never_Be_Null (Typ));
11631 end Transmit_As_Unconstrained;
11633 --------------------------
11634 -- Underlying_RACW_Type --
11635 --------------------------
11637 function Underlying_RACW_Type (RAS_Typ : Entity_Id) return Entity_Id is
11638 Record_Type : Entity_Id;
11640 begin
11641 if Ekind (RAS_Typ) = E_Record_Type then
11642 Record_Type := RAS_Typ;
11643 else
11644 pragma Assert (Present (Equivalent_Type (RAS_Typ)));
11645 Record_Type := Equivalent_Type (RAS_Typ);
11646 end if;
11648 return
11649 Etype (Subtype_Indication
11650 (Component_Definition
11651 (First (Component_Items
11652 (Component_List
11653 (Type_Definition
11654 (Declaration_Node (Record_Type))))))));
11655 end Underlying_RACW_Type;
11657 end Exp_Dist;