]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ada/exp_disp.adb
Fix memory order description in atomic ops built-ins docs.
[thirdparty/gcc.git] / gcc / ada / exp_disp.adb
CommitLineData
ee6ba406 1------------------------------------------------------------------------------
2-- --
3-- GNAT COMPILER COMPONENTS --
4-- --
5-- E X P _ D I S P --
6-- --
7-- B o d y --
8-- --
ad274a73 9-- Copyright (C) 1992-2015, Free Software Foundation, Inc. --
ee6ba406 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- --
24971415 13-- ware Foundation; either version 3, or (at your option) any later ver- --
ee6ba406 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 --
24971415 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. --
ee6ba406 20-- --
21-- GNAT was originally developed by the GNAT team at New York University. --
e78e8c8e 22-- Extensive contributions were provided by Ada Core Technologies Inc. --
ee6ba406 23-- --
24------------------------------------------------------------------------------
25
26with Atree; use Atree;
27with Checks; use Checks;
aad6babd 28with Debug; use Debug;
ee6ba406 29with Einfo; use Einfo;
30with Elists; use Elists;
31with Errout; use Errout;
343d35dc 32with Exp_Atag; use Exp_Atag;
8a8d9086 33with Exp_Ch6; use Exp_Ch6;
e00e091c 34with Exp_CG; use Exp_CG;
76a1c25b 35with Exp_Dbug; use Exp_Dbug;
ee6ba406 36with Exp_Tss; use Exp_Tss;
37with Exp_Util; use Exp_Util;
af647dc7 38with Freeze; use Freeze;
360b005f 39with Ghost; use Ghost;
ee6ba406 40with Itypes; use Itypes;
b6b96867 41with Layout; use Layout;
ee6ba406 42with Nlists; use Nlists;
43with Nmake; use Nmake;
aad6babd 44with Namet; use Namet;
ee6ba406 45with Opt; use Opt;
aad6babd 46with Output; use Output;
68f95949 47with Restrict; use Restrict;
48with Rident; use Rident;
ee6ba406 49with Rtsfind; use Rtsfind;
aad6babd 50with Sem; use Sem;
d60c9ff7 51with Sem_Aux; use Sem_Aux;
725a69d2 52with Sem_Ch6; use Sem_Ch6;
acf97c11 53with Sem_Ch7; use Sem_Ch7;
725a69d2 54with Sem_Ch8; use Sem_Ch8;
ee6ba406 55with Sem_Disp; use Sem_Disp;
725a69d2 56with Sem_Eval; use Sem_Eval;
ee6ba406 57with Sem_Res; use Sem_Res;
aad6babd 58with Sem_Type; use Sem_Type;
ee6ba406 59with Sem_Util; use Sem_Util;
60with Sinfo; use Sinfo;
61with Snames; use Snames;
62with Stand; use Stand;
725a69d2 63with Stringt; use Stringt;
5a44b136 64with SCIL_LL; use SCIL_LL;
79500ea0 65with Targparm; use Targparm;
ee6ba406 66with Tbuild; use Tbuild;
ee6ba406 67
68package body Exp_Disp is
69
725a69d2 70 -----------------------
71 -- Local Subprograms --
72 -----------------------
ee6ba406 73
68f95949 74 function Default_Prim_Op_Position (E : Entity_Id) return Uint;
aad6babd 75 -- Ada 2005 (AI-251): Returns the fixed position in the dispatch table
76 -- of the default primitive operations.
77
24971415 78 function Has_DT (Typ : Entity_Id) return Boolean;
79 pragma Inline (Has_DT);
80 -- Returns true if we generate a dispatch table for tagged type Typ
81
af647dc7 82 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean;
83 -- Returns true if Prim is not a predefined dispatching primitive but it is
36b938a3 84 -- an alias of a predefined dispatching primitive (i.e. through a renaming)
af647dc7 85
cd534f03 86 function New_Value (From : Node_Id) return Node_Id;
02a2406d 87 -- From is the original Expression. New_Value is equivalent to a call to
88 -- Duplicate_Subexpr with an explicit dereference when From is an access
89 -- parameter.
cd534f03 90
ee6ba406 91 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean;
02a2406d 92 -- Check if the type has a private view or if the public view appears in
93 -- the visible part of a package spec.
ee6ba406 94
d62940bf 95 function Prim_Op_Kind
96 (Prim : Entity_Id;
97 Typ : Entity_Id) return Node_Id;
98 -- Ada 2005 (AI-345): Determine the primitive operation kind of Prim
952af0b9 99 -- according to its type Typ. Return a reference to an RE_Prim_Op_Kind
d62940bf 100 -- enumeration value.
aad6babd 101
952af0b9 102 function Tagged_Kind (T : Entity_Id) return Node_Id;
103 -- Ada 2005 (AI-345): Determine the tagged kind of T and return a reference
104 -- to an RE_Tagged_Kind enumeration value.
105
cd534f03 106 ----------------------
107 -- Apply_Tag_Checks --
108 ----------------------
109
110 procedure Apply_Tag_Checks (Call_Node : Node_Id) is
111 Loc : constant Source_Ptr := Sloc (Call_Node);
112 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
113 Ctrl_Typ : constant Entity_Id := Base_Type (Etype (Ctrl_Arg));
114 Param_List : constant List_Id := Parameter_Associations (Call_Node);
115
116 Subp : Entity_Id;
117 CW_Typ : Entity_Id;
118 Param : Node_Id;
119 Typ : Entity_Id;
120 Eq_Prim_Op : Entity_Id := Empty;
121
122 begin
123 if No_Run_Time_Mode then
124 Error_Msg_CRT ("tagged types", Call_Node);
125 return;
126 end if;
127
02a2406d 128 -- Apply_Tag_Checks is called directly from the semantics, so we
129 -- need a check to see whether expansion is active before proceeding.
130 -- In addition, there is no need to expand the call when compiling
131 -- under restriction No_Dispatching_Calls; the semantic analyzer has
cd534f03 132 -- previously notified the violation of this restriction.
133
134 if not Expander_Active
135 or else Restriction_Active (No_Dispatching_Calls)
136 then
137 return;
138 end if;
139
140 -- Set subprogram. If this is an inherited operation that was
141 -- overridden, the body that is being called is its alias.
142
143 Subp := Entity (Name (Call_Node));
144
145 if Present (Alias (Subp))
146 and then Is_Inherited_Operation (Subp)
147 and then No (DTC_Entity (Subp))
148 then
149 Subp := Alias (Subp);
150 end if;
151
152 -- Definition of the class-wide type and the tagged type
153
154 -- If the controlling argument is itself a tag rather than a tagged
155 -- object, then use the class-wide type associated with the subprogram's
156 -- controlling type. This case can occur when a call to an inherited
157 -- primitive has an actual that originated from a default parameter
158 -- given by a tag-indeterminate call and when there is no other
159 -- controlling argument providing the tag (AI-239 requires dispatching).
160 -- This capability of dispatching directly by tag is also needed by the
161 -- implementation of AI-260 (for the generic dispatching constructors).
162
163 if Ctrl_Typ = RTE (RE_Tag)
164 or else (RTE_Available (RE_Interface_Tag)
165 and then Ctrl_Typ = RTE (RE_Interface_Tag))
166 then
167 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
168
169 -- Class_Wide_Type is applied to the expressions used to initialize
170 -- CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
171 -- there are cases where the controlling type is resolved to a specific
172 -- type (such as for designated types of arguments such as CW'Access).
173
174 elsif Is_Access_Type (Ctrl_Typ) then
175 CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));
176
177 else
178 CW_Typ := Class_Wide_Type (Ctrl_Typ);
179 end if;
180
bb5dfacc 181 Typ := Find_Specific_Type (CW_Typ);
cd534f03 182
183 if not Is_Limited_Type (Typ) then
184 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
185 end if;
186
187 -- Dispatching call to C++ primitive
188
189 if Is_CPP_Class (Typ) then
190 null;
191
192 -- Dispatching call to Ada primitive
193
194 elsif Present (Param_List) then
195
196 -- Generate the Tag checks when appropriate
197
198 Param := First_Actual (Call_Node);
199 while Present (Param) loop
200
201 -- No tag check with itself
202
203 if Param = Ctrl_Arg then
204 null;
205
206 -- No tag check for parameter whose type is neither tagged nor
207 -- access to tagged (for access parameters)
208
209 elsif No (Find_Controlling_Arg (Param)) then
210 null;
211
212 -- No tag check for function dispatching on result if the
213 -- Tag given by the context is this one
214
215 elsif Find_Controlling_Arg (Param) = Ctrl_Arg then
216 null;
217
02a2406d 218 -- "=" is the only dispatching operation allowed to get operands
219 -- with incompatible tags (it just returns false). We use
220 -- Duplicate_Subexpr_Move_Checks instead of calling Relocate_Node
221 -- because the value will be duplicated to check the tags.
cd534f03 222
223 elsif Subp = Eq_Prim_Op then
224 null;
225
226 -- No check in presence of suppress flags
227
228 elsif Tag_Checks_Suppressed (Etype (Param))
229 or else (Is_Access_Type (Etype (Param))
230 and then Tag_Checks_Suppressed
231 (Designated_Type (Etype (Param))))
232 then
233 null;
234
235 -- Optimization: no tag checks if the parameters are identical
236
237 elsif Is_Entity_Name (Param)
238 and then Is_Entity_Name (Ctrl_Arg)
239 and then Entity (Param) = Entity (Ctrl_Arg)
240 then
241 null;
242
243 -- Now we need to generate the Tag check
244
245 else
246 -- Generate code for tag equality check
02a2406d 247
cd534f03 248 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
249
250 Insert_Action (Ctrl_Arg,
251 Make_Implicit_If_Statement (Call_Node,
252 Condition =>
253 Make_Op_Ne (Loc,
254 Left_Opnd =>
255 Make_Selected_Component (Loc,
256 Prefix => New_Value (Ctrl_Arg),
257 Selector_Name =>
83c6c069 258 New_Occurrence_Of
cd534f03 259 (First_Tag_Component (Typ), Loc)),
260
261 Right_Opnd =>
262 Make_Selected_Component (Loc,
263 Prefix =>
264 Unchecked_Convert_To (Typ, New_Value (Param)),
265 Selector_Name =>
83c6c069 266 New_Occurrence_Of
cd534f03 267 (First_Tag_Component (Typ), Loc))),
268
269 Then_Statements =>
270 New_List (New_Constraint_Error (Loc))));
271 end if;
272
273 Next_Actual (Param);
274 end loop;
275 end if;
276 end Apply_Tag_Checks;
277
24971415 278 ------------------------
279 -- Building_Static_DT --
280 ------------------------
281
282 function Building_Static_DT (Typ : Entity_Id) return Boolean is
cc60bd16 283 Root_Typ : Entity_Id := Root_Type (Typ);
284
24971415 285 begin
cc60bd16 286 -- Handle private types
287
288 if Present (Full_View (Root_Typ)) then
289 Root_Typ := Full_View (Root_Typ);
290 end if;
291
24971415 292 return Static_Dispatch_Tables
e7e688dd 293 and then Is_Library_Level_Tagged_Type (Typ)
79500ea0 294 and then VM_Target = No_VM
e7e688dd 295
296 -- If the type is derived from a CPP class we cannot statically
297 -- build the dispatch tables because we must inherit primitives
298 -- from the CPP side.
299
cc60bd16 300 and then not Is_CPP_Class (Root_Typ);
24971415 301 end Building_Static_DT;
302
17e14451 303 ----------------------------------
304 -- Build_Static_Dispatch_Tables --
305 ----------------------------------
306
307 procedure Build_Static_Dispatch_Tables (N : Entity_Id) is
308 Target_List : List_Id;
309
310 procedure Build_Dispatch_Tables (List : List_Id);
311 -- Build the static dispatch table of tagged types found in the list of
312 -- declarations. The generated nodes are added at the end of Target_List
313
314 procedure Build_Package_Dispatch_Tables (N : Node_Id);
315 -- Build static dispatch tables associated with package declaration N
316
317 ---------------------------
318 -- Build_Dispatch_Tables --
319 ---------------------------
320
321 procedure Build_Dispatch_Tables (List : List_Id) is
322 D : Node_Id;
323
324 begin
325 D := First (List);
326 while Present (D) loop
327
328 -- Handle nested packages and package bodies recursively. The
329 -- generated code is placed on the Target_List established for
330 -- the enclosing compilation unit.
331
332 if Nkind (D) = N_Package_Declaration then
333 Build_Package_Dispatch_Tables (D);
334
335 elsif Nkind (D) = N_Package_Body then
336 Build_Dispatch_Tables (Declarations (D));
337
338 elsif Nkind (D) = N_Package_Body_Stub
339 and then Present (Library_Unit (D))
340 then
341 Build_Dispatch_Tables
342 (Declarations (Proper_Body (Unit (Library_Unit (D)))));
343
02a2406d 344 -- Handle full type declarations and derivations of library level
345 -- tagged types
17e14451 346
3164ed99 347 elsif Nkind_In (D, N_Full_Type_Declaration,
348 N_Derived_Type_Definition)
17e14451 349 and then Is_Library_Level_Tagged_Type (Defining_Entity (D))
350 and then Ekind (Defining_Entity (D)) /= E_Record_Subtype
351 and then not Is_Private_Type (Defining_Entity (D))
352 then
442049cc 353 -- We do not generate dispatch tables for the internal types
d9fac90e 354 -- created for a type extension with unknown discriminants
355 -- The needed information is shared with the source type,
356 -- See Expand_N_Record_Extension.
357
442049cc 358 if Is_Underlying_Record_View (Defining_Entity (D))
359 or else
360 (not Comes_From_Source (Defining_Entity (D))
361 and then
2f29393f 362 Has_Unknown_Discriminants (Etype (Defining_Entity (D)))
442049cc 363 and then
2f29393f 364 not Comes_From_Source
365 (First_Subtype (Defining_Entity (D))))
d9fac90e 366 then
367 null;
d9fac90e 368 else
369 Insert_List_After_And_Analyze (Last (Target_List),
370 Make_DT (Defining_Entity (D)));
371 end if;
17e14451 372
373 -- Handle private types of library level tagged types. We must
374 -- exchange the private and full-view to ensure the correct
a735d663 375 -- expansion. If the full view is a synchronized type ignore
376 -- the type because the table will be built for the corresponding
377 -- record type, that has its own declaration.
17e14451 378
379 elsif (Nkind (D) = N_Private_Type_Declaration
380 or else Nkind (D) = N_Private_Extension_Declaration)
381 and then Present (Full_View (Defining_Entity (D)))
17e14451 382 then
383 declare
acf97c11 384 E1 : constant Entity_Id := Defining_Entity (D);
a735d663 385 E2 : constant Entity_Id := Full_View (E1);
acf97c11 386
17e14451 387 begin
a735d663 388 if Is_Library_Level_Tagged_Type (E2)
389 and then Ekind (E2) /= E_Record_Subtype
390 and then not Is_Concurrent_Type (E2)
391 then
392 Exchange_Declarations (E1);
393 Insert_List_After_And_Analyze (Last (Target_List),
394 Make_DT (E1));
395 Exchange_Declarations (E2);
396 end if;
17e14451 397 end;
398 end if;
399
400 Next (D);
401 end loop;
402 end Build_Dispatch_Tables;
403
404 -----------------------------------
405 -- Build_Package_Dispatch_Tables --
406 -----------------------------------
407
408 procedure Build_Package_Dispatch_Tables (N : Node_Id) is
409 Spec : constant Node_Id := Specification (N);
410 Id : constant Entity_Id := Defining_Entity (N);
411 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
412 Priv_Decls : constant List_Id := Private_Declarations (Spec);
413
414 begin
415 Push_Scope (Id);
416
417 if Present (Priv_Decls) then
418 Build_Dispatch_Tables (Vis_Decls);
419 Build_Dispatch_Tables (Priv_Decls);
420
421 elsif Present (Vis_Decls) then
422 Build_Dispatch_Tables (Vis_Decls);
423 end if;
424
425 Pop_Scope;
426 end Build_Package_Dispatch_Tables;
427
428 -- Start of processing for Build_Static_Dispatch_Tables
429
430 begin
431 if not Expander_Active
662256db 432 or else not Tagged_Type_Expansion
17e14451 433 then
434 return;
435 end if;
436
437 if Nkind (N) = N_Package_Declaration then
438 declare
439 Spec : constant Node_Id := Specification (N);
440 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
441 Priv_Decls : constant List_Id := Private_Declarations (Spec);
442
443 begin
444 if Present (Priv_Decls)
445 and then Is_Non_Empty_List (Priv_Decls)
446 then
447 Target_List := Priv_Decls;
448
449 elsif not Present (Vis_Decls) then
450 Target_List := New_List;
451 Set_Private_Declarations (Spec, Target_List);
452 else
453 Target_List := Vis_Decls;
454 end if;
455
456 Build_Package_Dispatch_Tables (N);
457 end;
458
459 else pragma Assert (Nkind (N) = N_Package_Body);
460 Target_List := Declarations (N);
461 Build_Dispatch_Tables (Target_List);
462 end if;
463 end Build_Static_Dispatch_Tables;
464
f235fede 465 ------------------------------
466 -- Convert_Tag_To_Interface --
467 ------------------------------
468
469 function Convert_Tag_To_Interface
470 (Typ : Entity_Id;
471 Expr : Node_Id) return Node_Id
472 is
473 Loc : constant Source_Ptr := Sloc (Expr);
474 Anon_Type : Entity_Id;
475 Result : Node_Id;
476
477 begin
478 pragma Assert (Is_Class_Wide_Type (Typ)
479 and then Is_Interface (Typ)
480 and then
481 ((Nkind (Expr) = N_Selected_Component
4c58ddd7 482 and then Is_Tag (Entity (Selector_Name (Expr))))
f235fede 483 or else
484 (Nkind (Expr) = N_Function_Call
4c58ddd7 485 and then RTE_Available (RE_Displace)
486 and then Entity (Name (Expr)) = RTE (RE_Displace))));
f235fede 487
488 Anon_Type := Create_Itype (E_Anonymous_Access_Type, Expr);
489 Set_Directly_Designated_Type (Anon_Type, Typ);
490 Set_Etype (Anon_Type, Anon_Type);
491 Set_Can_Never_Be_Null (Anon_Type);
492
493 -- Decorate the size and alignment attributes of the anonymous access
02a2406d 494 -- type, as required by the back end.
f235fede 495
496 Layout_Type (Anon_Type);
497
498 if Nkind (Expr) = N_Selected_Component
499 and then Is_Tag (Entity (Selector_Name (Expr)))
500 then
501 Result :=
502 Make_Explicit_Dereference (Loc,
503 Unchecked_Convert_To (Anon_Type,
504 Make_Attribute_Reference (Loc,
505 Prefix => Expr,
506 Attribute_Name => Name_Address)));
507 else
508 Result :=
509 Make_Explicit_Dereference (Loc,
510 Unchecked_Convert_To (Anon_Type, Expr));
511 end if;
512
513 return Result;
514 end Convert_Tag_To_Interface;
515
d00681a7 516 -------------------
517 -- CPP_Num_Prims --
518 -------------------
519
520 function CPP_Num_Prims (Typ : Entity_Id) return Nat is
521 CPP_Typ : Entity_Id;
522 Tag_Comp : Entity_Id;
523
524 begin
525 if not Is_Tagged_Type (Typ)
526 or else not Is_CPP_Class (Root_Type (Typ))
527 then
528 return 0;
529
530 else
531 CPP_Typ := Enclosing_CPP_Parent (Typ);
532 Tag_Comp := First_Tag_Component (CPP_Typ);
533
02a2406d 534 -- If number of primitives already set in the tag component, use it
d00681a7 535
536 if Present (Tag_Comp)
537 and then DT_Entry_Count (Tag_Comp) /= No_Uint
538 then
539 return UI_To_Int (DT_Entry_Count (Tag_Comp));
540
541 -- Otherwise, count the primitives of the enclosing CPP type
542
543 else
544 declare
545 Count : Nat := 0;
546 Elmt : Elmt_Id;
547
548 begin
549 Elmt := First_Elmt (Primitive_Operations (CPP_Typ));
550 while Present (Elmt) loop
551 Count := Count + 1;
552 Next_Elmt (Elmt);
553 end loop;
554
555 return Count;
556 end;
557 end if;
558 end if;
559 end CPP_Num_Prims;
560
aad6babd 561 ------------------------------
562 -- Default_Prim_Op_Position --
563 ------------------------------
564
68f95949 565 function Default_Prim_Op_Position (E : Entity_Id) return Uint is
aad6babd 566 TSS_Name : TSS_Name_Type;
aad6babd 567
568 begin
aad6babd 569 Get_Name_String (Chars (E));
570 TSS_Name :=
571 TSS_Name_Type
572 (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
573
574 if Chars (E) = Name_uSize then
575 return Uint_1;
576
aad6babd 577 elsif TSS_Name = TSS_Stream_Read then
208fd589 578 return Uint_2;
aad6babd 579
580 elsif TSS_Name = TSS_Stream_Write then
208fd589 581 return Uint_3;
aad6babd 582
583 elsif TSS_Name = TSS_Stream_Input then
208fd589 584 return Uint_4;
aad6babd 585
586 elsif TSS_Name = TSS_Stream_Output then
208fd589 587 return Uint_5;
aad6babd 588
589 elsif Chars (E) = Name_Op_Eq then
208fd589 590 return Uint_6;
aad6babd 591
592 elsif Chars (E) = Name_uAssign then
208fd589 593 return Uint_7;
aad6babd 594
595 elsif TSS_Name = TSS_Deep_Adjust then
208fd589 596 return Uint_8;
aad6babd 597
598 elsif TSS_Name = TSS_Deep_Finalize then
208fd589 599 return Uint_9;
aad6babd 600
6cb4b973 601 -- In VM targets unconditionally allow obtaining the position associated
602 -- with predefined interface primitives since in these platforms any
603 -- tagged type has these primitives.
604
605 elsif Ada_Version >= Ada_2005 or else not Tagged_Type_Expansion then
76a1c25b 606 if Chars (E) = Name_uDisp_Asynchronous_Select then
208fd589 607 return Uint_10;
d62940bf 608
76a1c25b 609 elsif Chars (E) = Name_uDisp_Conditional_Select then
208fd589 610 return Uint_11;
d62940bf 611
76a1c25b 612 elsif Chars (E) = Name_uDisp_Get_Prim_Op_Kind then
208fd589 613 return Uint_12;
d62940bf 614
76a1c25b 615 elsif Chars (E) = Name_uDisp_Get_Task_Id then
208fd589 616 return Uint_13;
d62940bf 617
cdb1c38f 618 elsif Chars (E) = Name_uDisp_Requeue then
208fd589 619 return Uint_14;
cdb1c38f 620
621 elsif Chars (E) = Name_uDisp_Timed_Select then
208fd589 622 return Uint_15;
76a1c25b 623 end if;
aad6babd 624 end if;
76a1c25b 625
626 raise Program_Error;
aad6babd 627 end Default_Prim_Op_Position;
628
7189d17f 629 -----------------------------
630 -- Expand_Dispatching_Call --
631 -----------------------------
ee6ba406 632
7189d17f 633 procedure Expand_Dispatching_Call (Call_Node : Node_Id) is
ee6ba406 634 Loc : constant Source_Ptr := Sloc (Call_Node);
635 Call_Typ : constant Entity_Id := Etype (Call_Node);
636
2ea346ac 637 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
638 Ctrl_Typ : constant Entity_Id := Base_Type (Etype (Ctrl_Arg));
639 Param_List : constant List_Id := Parameter_Associations (Call_Node);
ee6ba406 640
af647dc7 641 Subp : Entity_Id;
7189d17f 642 CW_Typ : Entity_Id;
643 New_Call : Node_Id;
644 New_Call_Name : Node_Id;
645 New_Params : List_Id := No_List;
646 Param : Node_Id;
647 Res_Typ : Entity_Id;
648 Subp_Ptr_Typ : Entity_Id;
649 Subp_Typ : Entity_Id;
650 Typ : Entity_Id;
651 Eq_Prim_Op : Entity_Id := Empty;
652 Controlling_Tag : Node_Id;
ee6ba406 653
654 function New_Value (From : Node_Id) return Node_Id;
9dfe12ae 655 -- From is the original Expression. New_Value is equivalent to a call
656 -- to Duplicate_Subexpr with an explicit dereference when From is an
7189d17f 657 -- access parameter.
658
9dfe12ae 659 ---------------
660 -- New_Value --
661 ---------------
662
ee6ba406 663 function New_Value (From : Node_Id) return Node_Id is
664 Res : constant Node_Id := Duplicate_Subexpr (From);
ee6ba406 665 begin
666 if Is_Access_Type (Etype (From)) then
af647dc7 667 return
668 Make_Explicit_Dereference (Sloc (From),
669 Prefix => Res);
ee6ba406 670 else
671 return Res;
672 end if;
673 end New_Value;
674
d215f619 675 -- Local variables
676
5a44b136 677 New_Node : Node_Id;
678 SCIL_Node : Node_Id;
679 SCIL_Related_Node : Node_Id := Call_Node;
d215f619 680
7189d17f 681 -- Start of processing for Expand_Dispatching_Call
ee6ba406 682
683 begin
725a69d2 684 if No_Run_Time_Mode then
685 Error_Msg_CRT ("tagged types", Call_Node);
686 return;
687 end if;
688
02a2406d 689 -- Expand_Dispatching_Call is called directly from the semantics, so we
690 -- only proceed if the expander is active.
343d35dc 691
a33565dd 692 if not Expander_Active
0f3b1f49 693
694 -- And there is no need to expand the call if we are compiling under
695 -- restriction No_Dispatching_Calls; the semantic analyzer has
696 -- previously notified the violation of this restriction.
697
343d35dc 698 or else Restriction_Active (No_Dispatching_Calls)
687b5687 699
700 -- No action needed if the dispatching call has been already expanded
701
702 or else Is_Expanded_Dispatching_Call (Name (Call_Node))
343d35dc 703 then
704 return;
705 end if;
68f95949 706
af647dc7 707 -- Set subprogram. If this is an inherited operation that was
708 -- overridden, the body that is being called is its alias.
709
710 Subp := Entity (Name (Call_Node));
ee6ba406 711
712 if Present (Alias (Subp))
713 and then Is_Inherited_Operation (Subp)
714 and then No (DTC_Entity (Subp))
715 then
716 Subp := Alias (Subp);
717 end if;
718
7189d17f 719 -- Definition of the class-wide type and the tagged type
ee6ba406 720
7189d17f 721 -- If the controlling argument is itself a tag rather than a tagged
722 -- object, then use the class-wide type associated with the subprogram's
723 -- controlling type. This case can occur when a call to an inherited
724 -- primitive has an actual that originated from a default parameter
725 -- given by a tag-indeterminate call and when there is no other
726 -- controlling argument providing the tag (AI-239 requires dispatching).
727 -- This capability of dispatching directly by tag is also needed by the
728 -- implementation of AI-260 (for the generic dispatching constructors).
729
2ea346ac 730 if Ctrl_Typ = RTE (RE_Tag)
68f95949 731 or else (RTE_Available (RE_Interface_Tag)
2ea346ac 732 and then Ctrl_Typ = RTE (RE_Interface_Tag))
aad6babd 733 then
af647dc7 734 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
7189d17f 735
725a69d2 736 -- Class_Wide_Type is applied to the expressions used to initialize
737 -- CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
738 -- there are cases where the controlling type is resolved to a specific
739 -- type (such as for designated types of arguments such as CW'Access).
740
2ea346ac 741 elsif Is_Access_Type (Ctrl_Typ) then
742 CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));
7189d17f 743
ee6ba406 744 else
2ea346ac 745 CW_Typ := Class_Wide_Type (Ctrl_Typ);
ee6ba406 746 end if;
747
bb5dfacc 748 Typ := Find_Specific_Type (CW_Typ);
d62940bf 749
ee6ba406 750 if not Is_Limited_Type (Typ) then
751 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
752 end if;
753
343d35dc 754 -- Dispatching call to C++ primitive. Create a new parameter list
755 -- with no tag checks.
ee6ba406 756
cd534f03 757 New_Params := New_List;
758
343d35dc 759 if Is_CPP_Class (Typ) then
ee6ba406 760 Param := First_Actual (Call_Node);
761 while Present (Param) loop
aad6babd 762 Append_To (New_Params, Relocate_Node (Param));
ee6ba406 763 Next_Actual (Param);
764 end loop;
765
343d35dc 766 -- Dispatching call to Ada primitive
767
ee6ba406 768 elsif Present (Param_List) then
cd534f03 769 Apply_Tag_Checks (Call_Node);
ee6ba406 770
ee6ba406 771 Param := First_Actual (Call_Node);
772 while Present (Param) loop
773
f365561f 774 -- Cases in which we may have generated run-time checks. Note that
775 -- we strip any qualification from Param before comparing with the
776 -- already-stripped controlling argument.
777
778 if Unqualify (Param) = Ctrl_Arg or else Subp = Eq_Prim_Op then
9dfe12ae 779 Append_To (New_Params,
780 Duplicate_Subexpr_Move_Checks (Param));
ee6ba406 781
0429d533 782 elsif Nkind (Parent (Param)) /= N_Parameter_Association
783 or else not Is_Accessibility_Actual (Parent (Param))
784 then
ee6ba406 785 Append_To (New_Params, Relocate_Node (Param));
786 end if;
787
788 Next_Actual (Param);
789 end loop;
790 end if;
791
792 -- Generate the appropriate subprogram pointer type
793
68f95949 794 if Etype (Subp) = Typ then
ee6ba406 795 Res_Typ := CW_Typ;
796 else
7189d17f 797 Res_Typ := Etype (Subp);
ee6ba406 798 end if;
799
b6b96867 800 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
ee6ba406 801 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
802 Set_Etype (Subp_Typ, Res_Typ);
ee6ba406 803 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
265200d0 804 Set_Convention (Subp_Typ, Convention (Subp));
805
806 -- Notify gigi that the designated type is a dispatching primitive
807
808 Set_Is_Dispatch_Table_Entity (Subp_Typ);
ee6ba406 809
810 -- Create a new list of parameters which is a copy of the old formal
811 -- list including the creation of a new set of matching entities.
812
813 declare
814 Old_Formal : Entity_Id := First_Formal (Subp);
815 New_Formal : Entity_Id;
725a69d2 816 Extra : Entity_Id := Empty;
ee6ba406 817
818 begin
819 if Present (Old_Formal) then
820 New_Formal := New_Copy (Old_Formal);
821 Set_First_Entity (Subp_Typ, New_Formal);
822 Param := First_Actual (Call_Node);
823
824 loop
825 Set_Scope (New_Formal, Subp_Typ);
826
827 -- Change all the controlling argument types to be class-wide
7189d17f 828 -- to avoid a recursion in dispatching.
ee6ba406 829
7189d17f 830 if Is_Controlling_Formal (New_Formal) then
ee6ba406 831 Set_Etype (New_Formal, Etype (Param));
832 end if;
833
cc60bd16 834 -- If the type of the formal is an itype, there was code here
835 -- introduced in 1998 in revision 1.46, to create a new itype
836 -- by copy. This seems useless, and in fact leads to semantic
837 -- errors when the itype is the completion of a type derived
838 -- from a private type.
ee6ba406 839
840 Extra := New_Formal;
841 Next_Formal (Old_Formal);
842 exit when No (Old_Formal);
843
844 Set_Next_Entity (New_Formal, New_Copy (Old_Formal));
845 Next_Entity (New_Formal);
846 Next_Actual (Param);
847 end loop;
af647dc7 848
849 Set_Next_Entity (New_Formal, Empty);
ee6ba406 850 Set_Last_Entity (Subp_Typ, Extra);
725a69d2 851 end if;
ee6ba406 852
725a69d2 853 -- Now that the explicit formals have been duplicated, any extra
854 -- formals needed by the subprogram must be created.
ee6ba406 855
725a69d2 856 if Present (Extra) then
857 Set_Extra_Formal (Extra, Empty);
ee6ba406 858 end if;
725a69d2 859
860 Create_Extra_Formals (Subp_Typ);
ee6ba406 861 end;
862
b6b96867 863 -- Complete description of pointer type, including size information, as
864 -- must be done with itypes to prevent order-of-elaboration anomalies
865 -- in gigi.
866
ee6ba406 867 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
868 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
acf97c11 869 Set_Convention (Subp_Ptr_Typ, Convention (Subp_Typ));
b6b96867 870 Layout_Type (Subp_Ptr_Typ);
ee6ba406 871
68f95949 872 -- If the controlling argument is a value of type Ada.Tag or an abstract
873 -- interface class-wide type then use it directly. Otherwise, the tag
874 -- must be extracted from the controlling object.
7189d17f 875
2ea346ac 876 if Ctrl_Typ = RTE (RE_Tag)
68f95949 877 or else (RTE_Available (RE_Interface_Tag)
2ea346ac 878 and then Ctrl_Typ = RTE (RE_Interface_Tag))
68f95949 879 then
880 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
881
343d35dc 882 -- Extract the tag from an unchecked type conversion. Done to avoid
883 -- the expansion of additional code just to obtain the value of such
884 -- tag because the current management of interface type conversions
885 -- generates in some cases this unchecked type conversion with the
886 -- tag of the object (see Expand_Interface_Conversion).
887
888 elsif Nkind (Ctrl_Arg) = N_Unchecked_Type_Conversion
889 and then
890 (Etype (Expression (Ctrl_Arg)) = RTE (RE_Tag)
891 or else
892 (RTE_Available (RE_Interface_Tag)
893 and then
894 Etype (Expression (Ctrl_Arg)) = RTE (RE_Interface_Tag)))
895 then
896 Controlling_Tag := Duplicate_Subexpr (Expression (Ctrl_Arg));
897
68f95949 898 -- Ada 2005 (AI-251): Abstract interface class-wide type
899
2ea346ac 900 elsif Is_Interface (Ctrl_Typ)
901 and then Is_Class_Wide_Type (Ctrl_Typ)
aad6babd 902 then
7189d17f 903 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
904
905 else
906 Controlling_Tag :=
907 Make_Selected_Component (Loc,
1ea4332a 908 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
83c6c069 909 Selector_Name => New_Occurrence_Of (DTC_Entity (Subp), Loc));
7189d17f 910 end if;
911
1ea4332a 912 -- Handle dispatching calls to predefined primitives
ee6ba406 913
af647dc7 914 if Is_Predefined_Dispatching_Operation (Subp)
915 or else Is_Predefined_Dispatching_Alias (Subp)
916 then
ef40be71 917 Build_Get_Predefined_Prim_Op_Address (Loc,
918 Tag_Node => Controlling_Tag,
919 Position => DT_Position (Subp),
920 New_Node => New_Node);
ee6ba406 921
343d35dc 922 -- Handle dispatching calls to user-defined primitives
68f95949 923
924 else
ef40be71 925 Build_Get_Prim_Op_Address (Loc,
23197014 926 Typ => Underlying_Type (Find_Dispatching_Type (Subp)),
ef40be71 927 Tag_Node => Controlling_Tag,
928 Position => DT_Position (Subp),
929 New_Node => New_Node);
68f95949 930 end if;
ee6ba406 931
ef40be71 932 New_Call_Name :=
933 Unchecked_Convert_To (Subp_Ptr_Typ, New_Node);
934
5a44b136 935 -- Generate the SCIL node for this dispatching call. Done now because
936 -- attribute SCIL_Controlling_Tag must be set after the new call name
937 -- is built to reference the nodes that will see the SCIL backend
938 -- (because Build_Get_Prim_Op_Address generates an unchecked type
939 -- conversion which relocates the controlling tag node).
ee6ba406 940
ef40be71 941 if Generate_SCIL then
5a44b136 942 SCIL_Node := Make_SCIL_Dispatching_Call (Sloc (Call_Node));
943 Set_SCIL_Entity (SCIL_Node, Typ);
944 Set_SCIL_Target_Prim (SCIL_Node, Subp);
ef40be71 945
946 -- Common case: the controlling tag is the tag of an object
947 -- (for example, obj.tag)
948
949 if Nkind (Controlling_Tag) = N_Selected_Component then
950 Set_SCIL_Controlling_Tag (SCIL_Node, Controlling_Tag);
951
952 -- Handle renaming of selected component
953
954 elsif Nkind (Controlling_Tag) = N_Identifier
1ea4332a 955 and then Nkind (Parent (Entity (Controlling_Tag))) =
956 N_Object_Renaming_Declaration
957 and then Nkind (Name (Parent (Entity (Controlling_Tag)))) =
958 N_Selected_Component
ef40be71 959 then
960 Set_SCIL_Controlling_Tag (SCIL_Node,
961 Name (Parent (Entity (Controlling_Tag))));
962
963 -- If the controlling tag is an identifier, the SCIL node references
964 -- the corresponding object or parameter declaration
965
966 elsif Nkind (Controlling_Tag) = N_Identifier
967 and then Nkind_In (Parent (Entity (Controlling_Tag)),
1ea4332a 968 N_Object_Declaration,
969 N_Parameter_Specification)
ef40be71 970 then
971 Set_SCIL_Controlling_Tag (SCIL_Node,
972 Parent (Entity (Controlling_Tag)));
973
974 -- If the controlling tag is a dereference, the SCIL node references
975 -- the corresponding object or parameter declaration
976
977 elsif Nkind (Controlling_Tag) = N_Explicit_Dereference
978 and then Nkind (Prefix (Controlling_Tag)) = N_Identifier
979 and then Nkind_In (Parent (Entity (Prefix (Controlling_Tag))),
1ea4332a 980 N_Object_Declaration,
981 N_Parameter_Specification)
ef40be71 982 then
983 Set_SCIL_Controlling_Tag (SCIL_Node,
984 Parent (Entity (Prefix (Controlling_Tag))));
985
986 -- For a direct reference of the tag of the type the SCIL node
6fb3c314 987 -- references the internal object declaration containing the tag
ef40be71 988 -- of the type.
989
990 elsif Nkind (Controlling_Tag) = N_Attribute_Reference
991 and then Attribute_Name (Controlling_Tag) = Name_Tag
992 then
993 Set_SCIL_Controlling_Tag (SCIL_Node,
994 Parent
1ea4332a 995 (Node
996 (First_Elmt
997 (Access_Disp_Table (Entity (Prefix (Controlling_Tag)))))));
ef40be71 998
999 -- Interfaces are not supported. For now we leave the SCIL node
1000 -- decorated with the Controlling_Tag. More work needed here???
1001
1002 elsif Is_Interface (Etype (Controlling_Tag)) then
1003 Set_SCIL_Controlling_Tag (SCIL_Node, Controlling_Tag);
1004
1005 else
1006 pragma Assert (False);
1007 null;
1008 end if;
1009 end if;
1010
1011 if Nkind (Call_Node) = N_Function_Call then
725a69d2 1012 New_Call :=
1013 Make_Function_Call (Loc,
1ea4332a 1014 Name => New_Call_Name,
725a69d2 1015 Parameter_Associations => New_Params);
ee6ba406 1016
725a69d2 1017 -- If this is a dispatching "=", we must first compare the tags so
1018 -- we generate: x.tag = y.tag and then x = y
ee6ba406 1019
725a69d2 1020 if Subp = Eq_Prim_Op then
1021 Param := First_Actual (Call_Node);
aad6babd 1022 New_Call :=
725a69d2 1023 Make_And_Then (Loc,
1024 Left_Opnd =>
1025 Make_Op_Eq (Loc,
1026 Left_Opnd =>
1027 Make_Selected_Component (Loc,
1ea4332a 1028 Prefix => New_Value (Param),
725a69d2 1029 Selector_Name =>
83c6c069 1030 New_Occurrence_Of (First_Tag_Component (Typ),
725a69d2 1031 Loc)),
ee6ba406 1032
725a69d2 1033 Right_Opnd =>
1034 Make_Selected_Component (Loc,
1ea4332a 1035 Prefix =>
725a69d2 1036 Unchecked_Convert_To (Typ,
1037 New_Value (Next_Actual (Param))),
1038 Selector_Name =>
83c6c069 1039 New_Occurrence_Of
1ea4332a 1040 (First_Tag_Component (Typ), Loc))),
725a69d2 1041 Right_Opnd => New_Call);
5a44b136 1042
1043 SCIL_Related_Node := Right_Opnd (New_Call);
ee6ba406 1044 end if;
1045
1046 else
1047 New_Call :=
1048 Make_Procedure_Call_Statement (Loc,
1ea4332a 1049 Name => New_Call_Name,
ee6ba406 1050 Parameter_Associations => New_Params);
1051 end if;
1052
e00e091c 1053 -- Register the dispatching call in the call graph nodes table
1054
1055 Register_CG_Node (Call_Node);
1056
ee6ba406 1057 Rewrite (Call_Node, New_Call);
725a69d2 1058
5a44b136 1059 -- Associate the SCIL node of this dispatching call
1060
1061 if Generate_SCIL then
1062 Set_SCIL_Node (SCIL_Related_Node, SCIL_Node);
1063 end if;
1064
02a2406d 1065 -- Suppress all checks during the analysis of the expanded code to avoid
1066 -- the generation of spurious warnings under ZFP run-time.
725a69d2 1067
1068 Analyze_And_Resolve (Call_Node, Call_Typ, Suppress => All_Checks);
7189d17f 1069 end Expand_Dispatching_Call;
ee6ba406 1070
aad6babd 1071 ---------------------------------
1072 -- Expand_Interface_Conversion --
1073 ---------------------------------
1074
61ce7f9f 1075 procedure Expand_Interface_Conversion (N : Node_Id) is
1076 function Underlying_Record_Type (Typ : Entity_Id) return Entity_Id;
1077 -- Return the underlying record type of Typ.
aad6babd 1078
61ce7f9f 1079 ----------------------------
1080 -- Underlying_Record_Type --
1081 ----------------------------
aad6babd 1082
61ce7f9f 1083 function Underlying_Record_Type (Typ : Entity_Id) return Entity_Id is
1084 E : Entity_Id := Typ;
aad6babd 1085
61ce7f9f 1086 begin
1087 -- Handle access to class-wide interface types
aad6babd 1088
61ce7f9f 1089 if Is_Access_Type (E) then
1090 E := Etype (Directly_Designated_Type (E));
1091 end if;
aad6babd 1092
61ce7f9f 1093 -- Handle class-wide types. This conversion can appear explicitly in
1094 -- the source code. Example: I'Class (Obj)
aad6babd 1095
61ce7f9f 1096 if Is_Class_Wide_Type (E) then
1097 E := Root_Type (E);
1098 end if;
d62940bf 1099
61ce7f9f 1100 -- If the target type is a tagged synchronized type, the dispatch
1101 -- table info is in the corresponding record type.
79a72728 1102
61ce7f9f 1103 if Is_Concurrent_Type (E) then
1104 E := Corresponding_Record_Type (E);
1105 end if;
79a72728 1106
61ce7f9f 1107 -- Handle private types
1108
1109 E := Underlying_Type (E);
23197014 1110
61ce7f9f 1111 -- Handle subtypes
23197014 1112
61ce7f9f 1113 return Base_Type (E);
1114 end Underlying_Record_Type;
1115
1116 -- Local variables
1117
1118 Loc : constant Source_Ptr := Sloc (N);
1119 Etyp : constant Entity_Id := Etype (N);
1120 Operand : constant Node_Id := Expression (N);
1121 Operand_Typ : Entity_Id := Etype (Operand);
1122 Func : Node_Id;
1123 Iface_Typ : constant Entity_Id := Underlying_Record_Type (Etype (N));
1124 Iface_Tag : Entity_Id;
1125 Is_Static : Boolean;
1126
1127 -- Start of processing for Expand_Interface_Conversion
1128
1129 begin
a17cc77d 1130 -- Freeze the entity associated with the target interface to have
1131 -- available the attribute Access_Disp_Table.
1132
1133 Freeze_Before (N, Iface_Typ);
1134
61ce7f9f 1135 -- Ada 2005 (AI-345): Handle synchronized interface type derivations
1136
1137 if Is_Concurrent_Type (Operand_Typ) then
1138 Operand_Typ := Base_Type (Corresponding_Record_Type (Operand_Typ));
1139 end if;
1140
7e0d01bf 1141 -- No displacement of the pointer to the object needed when the type of
1142 -- the operand is not an interface type and the interface is one of
1143 -- its parent types (since they share the primary dispatch table).
1144
1145 declare
1146 Opnd : Entity_Id := Operand_Typ;
1147
1148 begin
1149 if Is_Access_Type (Opnd) then
1150 Opnd := Designated_Type (Opnd);
1151 end if;
1152
1153 if not Is_Interface (Opnd)
1154 and then Is_Ancestor (Iface_Typ, Opnd, Use_Full_View => True)
1155 then
1156 return;
1157 end if;
1158 end;
1159
61ce7f9f 1160 -- Evaluate if we can statically displace the pointer to the object
1161
1162 declare
1163 Opnd_Typ : constant Node_Id := Underlying_Record_Type (Operand_Typ);
1164
1165 begin
1166 Is_Static :=
1167 not Is_Interface (Opnd_Typ)
1168 and then Interface_Present_In_Ancestor
1169 (Typ => Opnd_Typ,
1170 Iface => Iface_Typ)
1171 and then (Etype (Opnd_Typ) = Opnd_Typ
1172 or else not
1173 Is_Variable_Size_Record (Etype (Opnd_Typ)));
1174 end;
aad6babd 1175
662256db 1176 if not Tagged_Type_Expansion then
79500ea0 1177 if VM_Target /= No_VM then
1178 if Is_Access_Type (Operand_Typ) then
1179 Operand_Typ := Designated_Type (Operand_Typ);
1180 end if;
725a69d2 1181
79500ea0 1182 if Is_Class_Wide_Type (Operand_Typ) then
1183 Operand_Typ := Root_Type (Operand_Typ);
1184 end if;
1185
61ce7f9f 1186 if not Is_Static and then Operand_Typ /= Iface_Typ then
79500ea0 1187 Insert_Action (N,
1188 Make_Procedure_Call_Statement (Loc,
1189 Name => New_Occurrence_Of
1190 (RTE (RE_Check_Interface_Conversion), Loc),
1191 Parameter_Associations => New_List (
1192 Make_Attribute_Reference (Loc,
61ce7f9f 1193 Prefix => Duplicate_Subexpr (Expression (N)),
79500ea0 1194 Attribute_Name => Name_Tag),
1195 Make_Attribute_Reference (Loc,
83c6c069 1196 Prefix => New_Occurrence_Of (Iface_Typ, Loc),
79500ea0 1197 Attribute_Name => Name_Tag))));
1198 end if;
8408cef9 1199
1200 -- Just do a conversion ???
1201
1202 Rewrite (N, Unchecked_Convert_To (Etype (N), N));
1203 Analyze (N);
79500ea0 1204 end if;
725a69d2 1205
725a69d2 1206 return;
aa0a69ab 1207
1208 -- A static conversion to an interface type that is not classwide is
1209 -- curious but legal if the interface operation is a null procedure.
1210 -- If the operation is abstract it will be rejected later.
1211
1212 elsif Is_Static
1213 and then Is_Interface (Etype (N))
1214 and then not Is_Class_Wide_Type (Etype (N))
1215 and then Comes_From_Source (N)
1216 then
1217 Rewrite (N, Unchecked_Convert_To (Etype (N), N));
1218 Analyze (N);
1219 return;
725a69d2 1220 end if;
1221
952af0b9 1222 if not Is_Static then
68f95949 1223
1224 -- Give error if configurable run time and Displace not available
1225
1226 if not RTE_Available (RE_Displace) then
cc60bd16 1227 Error_Msg_CRT ("dynamic interface conversion", N);
68f95949 1228 return;
1229 end if;
1230
725a69d2 1231 -- Handle conversion of access-to-class-wide interface types. Target
1232 -- can be an access to an object or an access to another class-wide
1233 -- interface (see -1- and -2- in the following example):
af647dc7 1234
1235 -- type Iface1_Ref is access all Iface1'Class;
1236 -- type Iface2_Ref is access all Iface1'Class;
1237
1238 -- Acc1 : Iface1_Ref := new ...
1239 -- Obj : Obj_Ref := Obj_Ref (Acc); -- 1
1240 -- Acc2 : Iface2_Ref := Iface2_Ref (Acc); -- 2
1241
1242 if Is_Access_Type (Operand_Typ) then
af647dc7 1243 Rewrite (N,
1244 Unchecked_Convert_To (Etype (N),
1245 Make_Function_Call (Loc,
83c6c069 1246 Name => New_Occurrence_Of (RTE (RE_Displace), Loc),
af647dc7 1247 Parameter_Associations => New_List (
1248
1249 Unchecked_Convert_To (RTE (RE_Address),
1250 Relocate_Node (Expression (N))),
1251
1252 New_Occurrence_Of
1253 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
1254 Loc)))));
1255
1256 Analyze (N);
1257 return;
1258 end if;
1259
952af0b9 1260 Rewrite (N,
1261 Make_Function_Call (Loc,
83c6c069 1262 Name => New_Occurrence_Of (RTE (RE_Displace), Loc),
952af0b9 1263 Parameter_Associations => New_List (
1264 Make_Attribute_Reference (Loc,
1265 Prefix => Relocate_Node (Expression (N)),
1266 Attribute_Name => Name_Address),
af647dc7 1267
952af0b9 1268 New_Occurrence_Of
1269 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
1270 Loc))));
1271
1272 Analyze (N);
1273
02a2406d 1274 -- If target is a class-wide interface, change the type of the data
1275 -- returned by IW_Convert to indicate this is a dispatching call.
952af0b9 1276
17e14451 1277 declare
1278 New_Itype : Entity_Id;
952af0b9 1279
17e14451 1280 begin
1281 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
cc60bd16 1282 Set_Etype (New_Itype, New_Itype);
17e14451 1283 Set_Directly_Designated_Type (New_Itype, Etyp);
952af0b9 1284
17e14451 1285 Rewrite (N,
1286 Make_Explicit_Dereference (Loc,
1287 Prefix =>
1288 Unchecked_Convert_To (New_Itype, Relocate_Node (N))));
1289 Analyze (N);
1290 Freeze_Itype (New_Itype, N);
1291
1292 return;
1293 end;
952af0b9 1294 end if;
1295
d62940bf 1296 Iface_Tag := Find_Interface_Tag (Operand_Typ, Iface_Typ);
aad6babd 1297 pragma Assert (Iface_Tag /= Empty);
1298
d62940bf 1299 -- Keep separate access types to interfaces because one internal
f235fede 1300 -- function is used to handle the null value (see following comments)
d62940bf 1301
1302 if not Is_Access_Type (Etype (N)) then
f235fede 1303
02a2406d 1304 -- Statically displace the pointer to the object to reference the
1305 -- component containing the secondary dispatch table.
f235fede 1306
d62940bf 1307 Rewrite (N,
f235fede 1308 Convert_Tag_To_Interface (Class_Wide_Type (Iface_Typ),
d62940bf 1309 Make_Selected_Component (Loc,
1310 Prefix => Relocate_Node (Expression (N)),
f235fede 1311 Selector_Name => New_Occurrence_Of (Iface_Tag, Loc))));
d62940bf 1312
1313 else
39a0c1d3 1314 -- Build internal function to handle the case in which the actual is
1315 -- null. If the actual is null returns null because no displacement
1316 -- is required; otherwise performs a type conversion that will be
1317 -- expanded in the code that returns the value of the displaced
1318 -- actual. That is:
d62940bf 1319
af647dc7 1320 -- function Func (O : Address) return Iface_Typ is
17e14451 1321 -- type Op_Typ is access all Operand_Typ;
1322 -- Aux : Op_Typ := To_Op_Typ (O);
d62940bf 1323 -- begin
af647dc7 1324 -- if O = Null_Address then
d62940bf 1325 -- return null;
1326 -- else
17e14451 1327 -- return Iface_Typ!(Aux.Iface_Tag'Address);
d62940bf 1328 -- end if;
1329 -- end Func;
1330
af647dc7 1331 declare
17e14451 1332 Desig_Typ : Entity_Id;
1333 Fent : Entity_Id;
1334 New_Typ_Decl : Node_Id;
17e14451 1335 Stats : List_Id;
1336
af647dc7 1337 begin
1338 Desig_Typ := Etype (Expression (N));
d62940bf 1339
af647dc7 1340 if Is_Access_Type (Desig_Typ) then
865909d3 1341 Desig_Typ :=
1342 Available_View (Directly_Designated_Type (Desig_Typ));
af647dc7 1343 end if;
d62940bf 1344
e7e688dd 1345 if Is_Concurrent_Type (Desig_Typ) then
1346 Desig_Typ := Base_Type (Corresponding_Record_Type (Desig_Typ));
1347 end if;
1348
17e14451 1349 New_Typ_Decl :=
1350 Make_Full_Type_Declaration (Loc,
ec97ce79 1351 Defining_Identifier => Make_Temporary (Loc, 'T'),
17e14451 1352 Type_Definition =>
1353 Make_Access_To_Object_Definition (Loc,
1354 All_Present => True,
1355 Null_Exclusion_Present => False,
1356 Constant_Present => False,
1357 Subtype_Indication =>
83c6c069 1358 New_Occurrence_Of (Desig_Typ, Loc)));
d62940bf 1359
725a69d2 1360 Stats := New_List (
17e14451 1361 Make_Simple_Return_Statement (Loc,
1362 Unchecked_Convert_To (Etype (N),
1363 Make_Attribute_Reference (Loc,
02a2406d 1364 Prefix =>
17e14451 1365 Make_Selected_Component (Loc,
02a2406d 1366 Prefix =>
e7e688dd 1367 Unchecked_Convert_To
1368 (Defining_Identifier (New_Typ_Decl),
1369 Make_Identifier (Loc, Name_uO)),
17e14451 1370 Selector_Name =>
1371 New_Occurrence_Of (Iface_Tag, Loc)),
1372 Attribute_Name => Name_Address))));
725a69d2 1373
17e14451 1374 -- If the type is null-excluding, no need for the null branch.
1375 -- Otherwise we need to check for it and return null.
1376
1377 if not Can_Never_Be_Null (Etype (N)) then
1378 Stats := New_List (
1379 Make_If_Statement (Loc,
1380 Condition =>
1381 Make_Op_Eq (Loc,
1382 Left_Opnd => Make_Identifier (Loc, Name_uO),
83c6c069 1383 Right_Opnd => New_Occurrence_Of
17e14451 1384 (RTE (RE_Null_Address), Loc)),
1385
1386 Then_Statements => New_List (
02a2406d 1387 Make_Simple_Return_Statement (Loc, Make_Null (Loc))),
17e14451 1388 Else_Statements => Stats));
1389 end if;
d62940bf 1390
ec97ce79 1391 Fent := Make_Temporary (Loc, 'F');
17e14451 1392 Func :=
1393 Make_Subprogram_Body (Loc,
1394 Specification =>
1395 Make_Function_Specification (Loc,
1396 Defining_Unit_Name => Fent,
d62940bf 1397
17e14451 1398 Parameter_Specifications => New_List (
1399 Make_Parameter_Specification (Loc,
1400 Defining_Identifier =>
1401 Make_Defining_Identifier (Loc, Name_uO),
1402 Parameter_Type =>
83c6c069 1403 New_Occurrence_Of (RTE (RE_Address), Loc))),
d62940bf 1404
17e14451 1405 Result_Definition =>
83c6c069 1406 New_Occurrence_Of (Etype (N), Loc)),
d62940bf 1407
e7e688dd 1408 Declarations => New_List (New_Typ_Decl),
d62940bf 1409
17e14451 1410 Handled_Statement_Sequence =>
1411 Make_Handled_Sequence_Of_Statements (Loc, Stats));
d62940bf 1412
17e14451 1413 -- Place function body before the expression containing the
1414 -- conversion. We suppress all checks because the body of the
1415 -- internally generated function already takes care of the case
1416 -- in which the actual is null; therefore there is no need to
1417 -- double check that the pointer is not null when the program
1418 -- executes the alternative that performs the type conversion).
af647dc7 1419
17e14451 1420 Insert_Action (N, Func, Suppress => All_Checks);
af647dc7 1421
17e14451 1422 if Is_Access_Type (Etype (Expression (N))) then
af647dc7 1423
cbd025d6 1424 Apply_Accessibility_Check
b29768cb 1425 (N => Expression (N),
1426 Typ => Etype (N),
cbd025d6 1427 Insert_Node => N);
1428
e7e688dd 1429 -- Generate: Func (Address!(Expression))
af647dc7 1430
17e14451 1431 Rewrite (N,
1432 Make_Function_Call (Loc,
b29768cb 1433 Name => New_Occurrence_Of (Fent, Loc),
17e14451 1434 Parameter_Associations => New_List (
e7e688dd 1435 Unchecked_Convert_To (RTE (RE_Address),
1436 Relocate_Node (Expression (N))))));
17e14451 1437
1438 else
e7e688dd 1439 -- Generate: Func (Operand_Typ!(Expression)'Address)
17e14451 1440
1441 Rewrite (N,
1442 Make_Function_Call (Loc,
b29768cb 1443 Name => New_Occurrence_Of (Fent, Loc),
17e14451 1444 Parameter_Associations => New_List (
1445 Make_Attribute_Reference (Loc,
1446 Prefix => Unchecked_Convert_To (Operand_Typ,
1447 Relocate_Node (Expression (N))),
1448 Attribute_Name => Name_Address))));
1449 end if;
1450 end;
d62940bf 1451 end if;
aad6babd 1452
1453 Analyze (N);
1454 end Expand_Interface_Conversion;
1455
1456 ------------------------------
1457 -- Expand_Interface_Actuals --
1458 ------------------------------
1459
1460 procedure Expand_Interface_Actuals (Call_Node : Node_Id) is
aad6babd 1461 Actual : Node_Id;
d62940bf 1462 Actual_Dup : Node_Id;
aad6babd 1463 Actual_Typ : Entity_Id;
d62940bf 1464 Anon : Entity_Id;
aad6babd 1465 Conversion : Node_Id;
1466 Formal : Entity_Id;
1467 Formal_Typ : Entity_Id;
1468 Subp : Entity_Id;
d62940bf 1469 Formal_DDT : Entity_Id;
1470 Actual_DDT : Entity_Id;
aad6babd 1471
1472 begin
1473 -- This subprogram is called directly from the semantics, so we need a
1474 -- check to see whether expansion is active before proceeding.
1475
1476 if not Expander_Active then
1477 return;
1478 end if;
1479
1480 -- Call using access to subprogram with explicit dereference
1481
1482 if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
1483 Subp := Etype (Name (Call_Node));
1484
4e5db562 1485 -- Call using selected component
1486
1487 elsif Nkind (Name (Call_Node)) = N_Selected_Component then
1488 Subp := Entity (Selector_Name (Name (Call_Node)));
1489
1490 -- Call using direct name
aad6babd 1491
1492 else
1493 Subp := Entity (Name (Call_Node));
1494 end if;
1495
725a69d2 1496 -- Ada 2005 (AI-251): Look for interface type formals to force "this"
1497 -- displacement
1498
aad6babd 1499 Formal := First_Formal (Subp);
1500 Actual := First_Actual (Call_Node);
aad6babd 1501 while Present (Formal) loop
725a69d2 1502 Formal_Typ := Etype (Formal);
d62940bf 1503
1504 if Ekind (Formal_Typ) = E_Record_Type_With_Private then
1505 Formal_Typ := Full_View (Formal_Typ);
1506 end if;
1507
1508 if Is_Access_Type (Formal_Typ) then
1509 Formal_DDT := Directly_Designated_Type (Formal_Typ);
1510 end if;
1511
aad6babd 1512 Actual_Typ := Etype (Actual);
1513
d62940bf 1514 if Is_Access_Type (Actual_Typ) then
1515 Actual_DDT := Directly_Designated_Type (Actual_Typ);
1516 end if;
1517
725a69d2 1518 if Is_Interface (Formal_Typ)
1519 and then Is_Class_Wide_Type (Formal_Typ)
1520 then
d62940bf 1521 -- No need to displace the pointer if the type of the actual
1d00a8ce 1522 -- coincides with the type of the formal.
aad6babd 1523
725a69d2 1524 if Actual_Typ = Formal_Typ then
d62940bf 1525 null;
1526
02a2406d 1527 -- No need to displace the pointer if the interface type is a
1528 -- parent of the type of the actual because in this case the
725a69d2 1529 -- interface primitives are located in the primary dispatch table.
aad6babd 1530
cb4af01d 1531 elsif Is_Ancestor (Formal_Typ, Actual_Typ,
1532 Use_Full_View => True)
1533 then
d62940bf 1534 null;
1535
02a2406d 1536 -- Implicit conversion to the class-wide formal type to force the
1537 -- displacement of the pointer.
725a69d2 1538
d62940bf 1539 else
8a8d9086 1540 -- Normally, expansion of actuals for calls to build-in-place
1541 -- functions happens as part of Expand_Actuals, but in this
1542 -- case the call will be wrapped in a conversion and soon after
1543 -- expanded further to handle the displacement for a class-wide
1544 -- interface conversion, so if this is a BIP call then we need
1545 -- to handle it now.
1546
1547 if Ada_Version >= Ada_2005
1548 and then Is_Build_In_Place_Function_Call (Actual)
1549 then
1550 Make_Build_In_Place_Call_In_Anonymous_Context (Actual);
1551 end if;
1552
d62940bf 1553 Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
725a69d2 1554 Rewrite (Actual, Conversion);
d62940bf 1555 Analyze_And_Resolve (Actual, Formal_Typ);
1556 end if;
aad6babd 1557
725a69d2 1558 -- Access to class-wide interface type
aad6babd 1559
1560 elsif Is_Access_Type (Formal_Typ)
725a69d2 1561 and then Is_Interface (Formal_DDT)
1562 and then Is_Class_Wide_Type (Formal_DDT)
aad6babd 1563 and then Interface_Present_In_Ancestor
d62940bf 1564 (Typ => Actual_DDT,
1565 Iface => Etype (Formal_DDT))
aad6babd 1566 then
725a69d2 1567 -- Handle attributes 'Access and 'Unchecked_Access
1568
aad6babd 1569 if Nkind (Actual) = N_Attribute_Reference
1570 and then
1571 (Attribute_Name (Actual) = Name_Access
1572 or else Attribute_Name (Actual) = Name_Unchecked_Access)
1573 then
5e82d8fe 1574 -- This case must have been handled by the analysis and
1575 -- expansion of 'Access. The only exception is when types
1576 -- match and no further expansion is required.
aad6babd 1577
5e82d8fe 1578 pragma Assert (Base_Type (Etype (Prefix (Actual)))
1579 = Base_Type (Formal_DDT));
1580 null;
aad6babd 1581
725a69d2 1582 -- No need to displace the pointer if the type of the actual
1583 -- coincides with the type of the formal.
d62940bf 1584
725a69d2 1585 elsif Actual_DDT = Formal_DDT then
d62940bf 1586 null;
1587
725a69d2 1588 -- No need to displace the pointer if the interface type is
1589 -- a parent of the type of the actual because in this case the
1590 -- interface primitives are located in the primary dispatch table.
d62940bf 1591
cb4af01d 1592 elsif Is_Ancestor (Formal_DDT, Actual_DDT,
1593 Use_Full_View => True)
1594 then
d62940bf 1595 null;
1596
aad6babd 1597 else
d62940bf 1598 Actual_Dup := Relocate_Node (Actual);
1599
4aa270d8 1600 if From_Limited_With (Actual_Typ) then
d62940bf 1601
02a2406d 1602 -- If the type of the actual parameter comes from a
1603 -- limited with-clause and the non-limited view is already
1604 -- available, we replace the anonymous access type by
1605 -- a duplicate declaration whose designated type is the
1606 -- non-limited view.
d62940bf 1607
40993cdb 1608 if Has_Non_Limited_View (Actual_DDT) then
d62940bf 1609 Anon := New_Copy (Actual_Typ);
1610
1611 if Is_Itype (Anon) then
1612 Set_Scope (Anon, Current_Scope);
1613 end if;
1614
542823a9 1615 Set_Directly_Designated_Type
1616 (Anon, Non_Limited_View (Actual_DDT));
d62940bf 1617 Set_Etype (Actual_Dup, Anon);
d62940bf 1618 end if;
1619 end if;
1620
1621 Conversion := Convert_To (Formal_Typ, Actual_Dup);
1622 Rewrite (Actual, Conversion);
aad6babd 1623 Analyze_And_Resolve (Actual, Formal_Typ);
1624 end if;
1625 end if;
1626
1627 Next_Actual (Actual);
1628 Next_Formal (Formal);
1629 end loop;
1630 end Expand_Interface_Actuals;
1631
1632 ----------------------------
1633 -- Expand_Interface_Thunk --
1634 ----------------------------
1635
725a69d2 1636 procedure Expand_Interface_Thunk
17e14451 1637 (Prim : Node_Id;
1638 Thunk_Id : out Entity_Id;
1639 Thunk_Code : out Node_Id)
aad6babd 1640 is
e8376947 1641 Loc : constant Source_Ptr := Sloc (Prim);
1642 Actuals : constant List_Id := New_List;
1643 Decl : constant List_Id := New_List;
1644 Formals : constant List_Id := New_List;
1645 Target : constant Entity_Id := Ultimate_Alias (Prim);
725a69d2 1646
c6431a40 1647 Decl_1 : Node_Id;
1648 Decl_2 : Node_Id;
1649 Expr : Node_Id;
1650 Formal : Node_Id;
1651 Ftyp : Entity_Id;
1652 Iface_Formal : Node_Id;
1653 New_Arg : Node_Id;
1654 Offset_To_Top : Node_Id;
1655 Target_Formal : Entity_Id;
aad6babd 1656
1657 begin
725a69d2 1658 Thunk_Id := Empty;
1659 Thunk_Code := Empty;
1660
3f8cf2d2 1661 -- No thunk needed if the primitive has been eliminated
1662
1663 if Is_Eliminated (Ultimate_Alias (Prim)) then
1664 return;
1665
e8376947 1666 -- In case of primitives that are functions without formals and a
1667 -- controlling result there is no need to build the thunk.
725a69d2 1668
3f8cf2d2 1669 elsif not Present (First_Formal (Target)) then
725a69d2 1670 pragma Assert (Ekind (Target) = E_Function
1671 and then Has_Controlling_Result (Target));
1672 return;
1673 end if;
1674
04c6d723 1675 -- Duplicate the formals of the Target primitive. In the thunk, the type
1676 -- of the controlling formal is the covered interface type (instead of
1677 -- the target tagged type). Done to avoid problems with discriminated
1678 -- tagged types because, if the controlling type has discriminants with
e8376947 1679 -- default values, then the type conversions done inside the body of
1680 -- the thunk (after the displacement of the pointer to the base of the
04c6d723 1681 -- actual object) generate code that modify its contents.
1682
1683 -- Note: This special management is not done for predefined primitives
1684 -- because???
1685
1686 if not Is_Predefined_Dispatching_Operation (Prim) then
1687 Iface_Formal := First_Formal (Interface_Alias (Prim));
1688 end if;
aad6babd 1689
d62940bf 1690 Formal := First_Formal (Target);
aad6babd 1691 while Present (Formal) loop
04c6d723 1692 Ftyp := Etype (Formal);
1693
1694 -- Use the interface type as the type of the controlling formal (see
e8376947 1695 -- comment above).
04c6d723 1696
1697 if not Is_Controlling_Formal (Formal)
1698 or else Is_Predefined_Dispatching_Operation (Prim)
1699 then
1700 Ftyp := Etype (Formal);
1701 Expr := New_Copy_Tree (Expression (Parent (Formal)));
1702 else
1703 Ftyp := Etype (Iface_Formal);
1704 Expr := Empty;
1705 end if;
1706
725a69d2 1707 Append_To (Formals,
1708 Make_Parameter_Specification (Loc,
1709 Defining_Identifier =>
1710 Make_Defining_Identifier (Sloc (Formal),
1711 Chars => Chars (Formal)),
1712 In_Present => In_Present (Parent (Formal)),
1713 Out_Present => Out_Present (Parent (Formal)),
83c6c069 1714 Parameter_Type => New_Occurrence_Of (Ftyp, Loc),
04c6d723 1715 Expression => Expr));
1716
1717 if not Is_Predefined_Dispatching_Operation (Prim) then
1718 Next_Formal (Iface_Formal);
1719 end if;
d62940bf 1720
aad6babd 1721 Next_Formal (Formal);
1722 end loop;
1723
725a69d2 1724 Target_Formal := First_Formal (Target);
1725 Formal := First (Formals);
1726 while Present (Formal) loop
04c6d723 1727
6cd460aa 1728 -- If the parent is a constrained discriminated type, then the
1729 -- primitive operation will have been defined on a first subtype.
1730 -- For proper matching with controlling type, use base type.
04c6d723 1731
1732 if Ekind (Target_Formal) = E_In_Parameter
1733 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
1734 then
6cd460aa 1735 Ftyp :=
1736 Base_Type (Directly_Designated_Type (Etype (Target_Formal)));
04c6d723 1737 else
ca12fde2 1738 Ftyp := Base_Type (Etype (Target_Formal));
04c6d723 1739 end if;
1740
232a63ed 1741 -- For concurrent types, the relevant information is found in the
1742 -- Corresponding_Record_Type, rather than the type entity itself.
6cd460aa 1743
04c6d723 1744 if Is_Concurrent_Type (Ftyp) then
1745 Ftyp := Corresponding_Record_Type (Ftyp);
1746 end if;
1747
725a69d2 1748 if Ekind (Target_Formal) = E_In_Parameter
1749 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
40cdae8b 1750 and then Is_Controlling_Formal (Target_Formal)
725a69d2 1751 then
1752 -- Generate:
17e14451 1753 -- type T is access all <<type of the target formal>>
1754 -- S : Storage_Offset := Storage_Offset!(Formal)
1755 -- - Offset_To_Top (address!(Formal))
725a69d2 1756
1757 Decl_2 :=
1758 Make_Full_Type_Declaration (Loc,
ec97ce79 1759 Defining_Identifier => Make_Temporary (Loc, 'T'),
725a69d2 1760 Type_Definition =>
1761 Make_Access_To_Object_Definition (Loc,
1762 All_Present => True,
1763 Null_Exclusion_Present => False,
1764 Constant_Present => False,
1765 Subtype_Indication =>
83c6c069 1766 New_Occurrence_Of (Ftyp, Loc)));
725a69d2 1767
cc60bd16 1768 New_Arg :=
1769 Unchecked_Convert_To (RTE (RE_Address),
83c6c069 1770 New_Occurrence_Of (Defining_Identifier (Formal), Loc));
cc60bd16 1771
1772 if not RTE_Available (RE_Offset_To_Top) then
1773 Offset_To_Top :=
1774 Build_Offset_To_Top (Loc, New_Arg);
1775 else
1776 Offset_To_Top :=
1777 Make_Function_Call (Loc,
83c6c069 1778 Name => New_Occurrence_Of (RTE (RE_Offset_To_Top), Loc),
cc60bd16 1779 Parameter_Associations => New_List (New_Arg));
1780 end if;
1781
725a69d2 1782 Decl_1 :=
1783 Make_Object_Declaration (Loc,
ec97ce79 1784 Defining_Identifier => Make_Temporary (Loc, 'S'),
725a69d2 1785 Constant_Present => True,
1786 Object_Definition =>
83c6c069 1787 New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
725a69d2 1788 Expression =>
1789 Make_Op_Subtract (Loc,
1790 Left_Opnd =>
1791 Unchecked_Convert_To
1792 (RTE (RE_Storage_Offset),
83c6c069 1793 New_Occurrence_Of
1794 (Defining_Identifier (Formal), Loc)),
725a69d2 1795 Right_Opnd =>
cc60bd16 1796 Offset_To_Top));
725a69d2 1797
1798 Append_To (Decl, Decl_2);
1799 Append_To (Decl, Decl_1);
1800
17e14451 1801 -- Reference the new actual. Generate:
1802 -- T!(S)
725a69d2 1803
1804 Append_To (Actuals,
1805 Unchecked_Convert_To
1806 (Defining_Identifier (Decl_2),
83c6c069 1807 New_Occurrence_Of (Defining_Identifier (Decl_1), Loc)));
725a69d2 1808
40cdae8b 1809 elsif Is_Controlling_Formal (Target_Formal) then
aad6babd 1810
e8376947 1811 -- Generate:
17e14451 1812 -- S1 : Storage_Offset := Storage_Offset!(Formal'Address)
1813 -- - Offset_To_Top (Formal'Address)
1814 -- S2 : Addr_Ptr := Addr_Ptr!(S1)
aad6babd 1815
cc60bd16 1816 New_Arg :=
1817 Make_Attribute_Reference (Loc,
1818 Prefix =>
83c6c069 1819 New_Occurrence_Of (Defining_Identifier (Formal), Loc),
cc60bd16 1820 Attribute_Name =>
1821 Name_Address);
1822
1823 if not RTE_Available (RE_Offset_To_Top) then
1824 Offset_To_Top :=
1825 Build_Offset_To_Top (Loc, New_Arg);
1826 else
1827 Offset_To_Top :=
1828 Make_Function_Call (Loc,
83c6c069 1829 Name => New_Occurrence_Of (RTE (RE_Offset_To_Top), Loc),
cc60bd16 1830 Parameter_Associations => New_List (New_Arg));
1831 end if;
1832
725a69d2 1833 Decl_1 :=
1834 Make_Object_Declaration (Loc,
ec97ce79 1835 Defining_Identifier => Make_Temporary (Loc, 'S'),
725a69d2 1836 Constant_Present => True,
1837 Object_Definition =>
83c6c069 1838 New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
725a69d2 1839 Expression =>
1840 Make_Op_Subtract (Loc,
1841 Left_Opnd =>
1842 Unchecked_Convert_To
1843 (RTE (RE_Storage_Offset),
1844 Make_Attribute_Reference (Loc,
1845 Prefix =>
83c6c069 1846 New_Occurrence_Of
725a69d2 1847 (Defining_Identifier (Formal), Loc),
1848 Attribute_Name => Name_Address)),
1849 Right_Opnd =>
cc60bd16 1850 Offset_To_Top));
aad6babd 1851
725a69d2 1852 Decl_2 :=
1853 Make_Object_Declaration (Loc,
ec97ce79 1854 Defining_Identifier => Make_Temporary (Loc, 'S'),
1855 Constant_Present => True,
1856 Object_Definition =>
83c6c069 1857 New_Occurrence_Of (RTE (RE_Addr_Ptr), Loc),
ec97ce79 1858 Expression =>
725a69d2 1859 Unchecked_Convert_To
1860 (RTE (RE_Addr_Ptr),
83c6c069 1861 New_Occurrence_Of (Defining_Identifier (Decl_1), Loc)));
aad6babd 1862
725a69d2 1863 Append_To (Decl, Decl_1);
1864 Append_To (Decl, Decl_2);
952af0b9 1865
ec97ce79 1866 -- Reference the new actual, generate:
17e14451 1867 -- Target_Formal (S2.all)
aad6babd 1868
725a69d2 1869 Append_To (Actuals,
04c6d723 1870 Unchecked_Convert_To (Ftyp,
725a69d2 1871 Make_Explicit_Dereference (Loc,
83c6c069 1872 New_Occurrence_Of (Defining_Identifier (Decl_2), Loc))));
aad6babd 1873
984d005d 1874 -- Ensure proper matching of access types. Required to avoid
1875 -- reporting spurious errors.
1876
1877 elsif Is_Access_Type (Etype (Target_Formal)) then
1878 Append_To (Actuals,
1879 Unchecked_Convert_To (Base_Type (Etype (Target_Formal)),
83c6c069 1880 New_Occurrence_Of (Defining_Identifier (Formal), Loc)));
984d005d 1881
725a69d2 1882 -- No special management required for this actual
aad6babd 1883
725a69d2 1884 else
1885 Append_To (Actuals,
83c6c069 1886 New_Occurrence_Of (Defining_Identifier (Formal), Loc));
725a69d2 1887 end if;
1888
1889 Next_Formal (Target_Formal);
aad6babd 1890 Next (Formal);
1891 end loop;
1892
ec97ce79 1893 Thunk_Id := Make_Temporary (Loc, 'T');
b1961352 1894 Set_Ekind (Thunk_Id, Ekind (Prim));
e7e688dd 1895 Set_Is_Thunk (Thunk_Id);
265200d0 1896 Set_Convention (Thunk_Id, Convention (Prim));
cdc5a761 1897 Set_Thunk_Entity (Thunk_Id, Target);
e7e688dd 1898
e8376947 1899 -- Procedure case
1900
d62940bf 1901 if Ekind (Target) = E_Procedure then
725a69d2 1902 Thunk_Code :=
aad6babd 1903 Make_Subprogram_Body (Loc,
1904 Specification =>
1905 Make_Procedure_Specification (Loc,
1906 Defining_Unit_Name => Thunk_Id,
1907 Parameter_Specifications => Formals),
1908 Declarations => Decl,
1909 Handled_Statement_Sequence =>
1910 Make_Handled_Sequence_Of_Statements (Loc,
1911 Statements => New_List (
1912 Make_Procedure_Call_Statement (Loc,
725a69d2 1913 Name => New_Occurrence_Of (Target, Loc),
1914 Parameter_Associations => Actuals))));
aad6babd 1915
e8376947 1916 -- Function case
aad6babd 1917
e8376947 1918 else pragma Assert (Ekind (Target) = E_Function);
61ce7f9f 1919 declare
1920 Result_Def : Node_Id;
1921 Call_Node : Node_Id;
1922
1923 begin
1924 Call_Node :=
1925 Make_Function_Call (Loc,
1926 Name => New_Occurrence_Of (Target, Loc),
1927 Parameter_Associations => Actuals);
1928
1929 if not Is_Interface (Etype (Prim)) then
1930 Result_Def := New_Copy (Result_Definition (Parent (Target)));
1931
1932 -- Thunk of function returning a class-wide interface object. No
1933 -- extra displacement needed since the displacement is generated
1934 -- in the return statement of Prim. Example:
1935
1936 -- type Iface is interface ...
1937 -- function F (O : Iface) return Iface'Class;
1938
1939 -- type T is new ... and Iface with ...
1940 -- function F (O : T) return Iface'Class;
1941
1942 elsif Is_Class_Wide_Type (Etype (Prim)) then
1943 Result_Def := New_Occurrence_Of (Etype (Prim), Loc);
1944
1945 -- Thunk of function returning an interface object. Displacement
1946 -- needed. Example:
1947
1948 -- type Iface is interface ...
1949 -- function F (O : Iface) return Iface;
1950
1951 -- type T is new ... and Iface with ...
1952 -- function F (O : T) return T;
1953
1954 else
1955 Result_Def :=
1956 New_Occurrence_Of (Class_Wide_Type (Etype (Prim)), Loc);
1957
1958 -- Adding implicit conversion to force the displacement of
1959 -- the pointer to the object to reference the corresponding
1960 -- secondary dispatch table.
1961
1962 Call_Node :=
1963 Make_Type_Conversion (Loc,
1964 Subtype_Mark =>
1965 New_Occurrence_Of (Class_Wide_Type (Etype (Prim)), Loc),
1966 Expression => Relocate_Node (Call_Node));
1967 end if;
1968
1969 Thunk_Code :=
1970 Make_Subprogram_Body (Loc,
02a2406d 1971 Specification =>
61ce7f9f 1972 Make_Function_Specification (Loc,
1973 Defining_Unit_Name => Thunk_Id,
1974 Parameter_Specifications => Formals,
1975 Result_Definition => Result_Def),
02a2406d 1976 Declarations => Decl,
61ce7f9f 1977 Handled_Statement_Sequence =>
1978 Make_Handled_Sequence_Of_Statements (Loc,
1979 Statements => New_List (
1980 Make_Simple_Return_Statement (Loc, Call_Node))));
1981 end;
aad6babd 1982 end if;
aad6babd 1983 end Expand_Interface_Thunk;
1984
d00681a7 1985 --------------------------
1986 -- Has_CPP_Constructors --
1987 --------------------------
1988
1989 function Has_CPP_Constructors (Typ : Entity_Id) return Boolean is
1990 E : Entity_Id;
1991
1992 begin
1993 -- Look for the constructor entities
1994
1995 E := Next_Entity (Typ);
1996 while Present (E) loop
02a2406d 1997 if Ekind (E) = E_Function and then Is_Constructor (E) then
d00681a7 1998 return True;
1999 end if;
2000
2001 Next_Entity (E);
2002 end loop;
2003
2004 return False;
2005 end Has_CPP_Constructors;
2006
24971415 2007 ------------
2008 -- Has_DT --
2009 ------------
2010
2011 function Has_DT (Typ : Entity_Id) return Boolean is
2012 begin
2013 return not Is_Interface (Typ)
02a2406d 2014 and then not Restriction_Active (No_Dispatching_Calls);
24971415 2015 end Has_DT;
2016
687b5687 2017 ----------------------------------
2018 -- Is_Expanded_Dispatching_Call --
2019 ----------------------------------
2020
2021 function Is_Expanded_Dispatching_Call (N : Node_Id) return Boolean is
2022 begin
2023 return Nkind (N) in N_Subprogram_Call
2024 and then Nkind (Name (N)) = N_Explicit_Dereference
2025 and then Is_Dispatch_Table_Entity (Etype (Name (N)));
2026 end Is_Expanded_Dispatching_Call;
2027
a652dd51 2028 -----------------------------------------
2029 -- Is_Predefined_Dispatching_Operation --
2030 -----------------------------------------
2031
2032 function Is_Predefined_Dispatching_Operation
2033 (E : Entity_Id) return Boolean
2034 is
2035 TSS_Name : TSS_Name_Type;
2036
2037 begin
2038 if not Is_Dispatching_Operation (E) then
2039 return False;
2040 end if;
2041
2042 Get_Name_String (Chars (E));
2043
2044 -- Most predefined primitives have internally generated names. Equality
2045 -- must be treated differently; the predefined operation is recognized
2046 -- as a homogeneous binary operator that returns Boolean.
2047
2048 if Name_Len > TSS_Name_Type'Last then
2049 TSS_Name := TSS_Name_Type (Name_Buffer (Name_Len - TSS_Name'Length + 1
2050 .. Name_Len));
2051 if Chars (E) = Name_uSize
a652dd51 2052 or else TSS_Name = TSS_Stream_Read
2053 or else TSS_Name = TSS_Stream_Write
2054 or else TSS_Name = TSS_Stream_Input
2055 or else TSS_Name = TSS_Stream_Output
2056 or else
2057 (Chars (E) = Name_Op_Eq
30592778 2058 and then Etype (First_Formal (E)) = Etype (Last_Formal (E)))
a652dd51 2059 or else Chars (E) = Name_uAssign
2060 or else TSS_Name = TSS_Deep_Adjust
2061 or else TSS_Name = TSS_Deep_Finalize
2062 or else Is_Predefined_Interface_Primitive (E)
2063 then
2064 return True;
2065 end if;
2066 end if;
2067
2068 return False;
2069 end Is_Predefined_Dispatching_Operation;
2070
d1458a07 2071 ---------------------------------------
2072 -- Is_Predefined_Internal_Operation --
2073 ---------------------------------------
2074
2075 function Is_Predefined_Internal_Operation
2076 (E : Entity_Id) return Boolean
2077 is
2078 TSS_Name : TSS_Name_Type;
2079
2080 begin
2081 if not Is_Dispatching_Operation (E) then
2082 return False;
2083 end if;
2084
2085 Get_Name_String (Chars (E));
2086
2087 -- Most predefined primitives have internally generated names. Equality
2088 -- must be treated differently; the predefined operation is recognized
2089 -- as a homogeneous binary operator that returns Boolean.
2090
2091 if Name_Len > TSS_Name_Type'Last then
2092 TSS_Name :=
2093 TSS_Name_Type
2094 (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
2095
18393965 2096 if Nam_In (Chars (E), Name_uSize, Name_uAssign)
d1458a07 2097 or else
2098 (Chars (E) = Name_Op_Eq
18393965 2099 and then Etype (First_Formal (E)) = Etype (Last_Formal (E)))
d1458a07 2100 or else TSS_Name = TSS_Deep_Adjust
2101 or else TSS_Name = TSS_Deep_Finalize
2102 or else Is_Predefined_Interface_Primitive (E)
2103 then
2104 return True;
2105 end if;
2106 end if;
2107
2108 return False;
2109 end Is_Predefined_Internal_Operation;
2110
af647dc7 2111 -------------------------------------
2112 -- Is_Predefined_Dispatching_Alias --
2113 -------------------------------------
2114
2115 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
2116 is
af647dc7 2117 begin
fc2907f6 2118 return not Is_Predefined_Dispatching_Operation (Prim)
af647dc7 2119 and then Present (Alias (Prim))
fc2907f6 2120 and then Is_Predefined_Dispatching_Operation (Ultimate_Alias (Prim));
af647dc7 2121 end Is_Predefined_Dispatching_Alias;
2122
a652dd51 2123 ---------------------------------------
2124 -- Is_Predefined_Interface_Primitive --
2125 ---------------------------------------
2126
2127 function Is_Predefined_Interface_Primitive (E : Entity_Id) return Boolean is
2128 begin
6cb4b973 2129 -- In VM targets we don't restrict the functionality of this test to
2130 -- compiling in Ada 2005 mode since in VM targets any tagged type has
02a2406d 2131 -- these primitives.
6cb4b973 2132
2133 return (Ada_Version >= Ada_2005 or else not Tagged_Type_Expansion)
02a2406d 2134 and then Nam_In (Chars (E), Name_uDisp_Asynchronous_Select,
2135 Name_uDisp_Conditional_Select,
2136 Name_uDisp_Get_Prim_Op_Kind,
2137 Name_uDisp_Get_Task_Id,
2138 Name_uDisp_Requeue,
2139 Name_uDisp_Timed_Select);
a652dd51 2140 end Is_Predefined_Interface_Primitive;
2141
76a1c25b 2142 ----------------------------------------
2143 -- Make_Disp_Asynchronous_Select_Body --
2144 ----------------------------------------
ee6ba406 2145
cdb1c38f 2146 -- For interface types, generate:
2147
2148 -- procedure _Disp_Asynchronous_Select
2149 -- (T : in out <Typ>;
2150 -- S : Integer;
2151 -- P : System.Address;
2152 -- B : out System.Storage_Elements.Dummy_Communication_Block;
2153 -- F : out Boolean)
2154 -- is
2155 -- begin
a053db0d 2156 -- F := False;
2157 -- C := Ada.Tags.POK_Function;
cdb1c38f 2158 -- end _Disp_Asynchronous_Select;
2159
2160 -- For protected types, generate:
2161
2162 -- procedure _Disp_Asynchronous_Select
2163 -- (T : in out <Typ>;
2164 -- S : Integer;
2165 -- P : System.Address;
2166 -- B : out System.Storage_Elements.Dummy_Communication_Block;
2167 -- F : out Boolean)
2168 -- is
2169 -- I : Integer :=
2170 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2171 -- Bnn : System.Tasking.Protected_Objects.Operations.
2172 -- Communication_Block;
2173 -- begin
2174 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
2175 -- (T._object'Access,
2176 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
2177 -- P,
2178 -- System.Tasking.Asynchronous_Call,
2179 -- Bnn);
2180 -- B := System.Storage_Elements.Dummy_Communication_Block (Bnn);
2181 -- end _Disp_Asynchronous_Select;
2182
2183 -- For task types, generate:
2184
2185 -- procedure _Disp_Asynchronous_Select
2186 -- (T : in out <Typ>;
2187 -- S : Integer;
2188 -- P : System.Address;
2189 -- B : out System.Storage_Elements.Dummy_Communication_Block;
2190 -- F : out Boolean)
2191 -- is
2192 -- I : Integer :=
2193 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2194 -- begin
2195 -- System.Tasking.Rendezvous.Task_Entry_Call
2196 -- (T._task_id,
2197 -- System.Tasking.Task_Entry_Index (I),
2198 -- P,
2199 -- System.Tasking.Asynchronous_Call,
2200 -- F);
2201 -- end _Disp_Asynchronous_Select;
2202
76a1c25b 2203 function Make_Disp_Asynchronous_Select_Body
2204 (Typ : Entity_Id) return Node_Id
2205 is
725a69d2 2206 Com_Block : Entity_Id;
2207 Conc_Typ : Entity_Id := Empty;
2208 Decls : constant List_Id := New_List;
725a69d2 2209 Loc : constant Source_Ptr := Sloc (Typ);
acf97c11 2210 Obj_Ref : Node_Id;
725a69d2 2211 Stmts : constant List_Id := New_List;
bf7f5966 2212 Tag_Node : Node_Id;
ee6ba406 2213
2214 begin
68f95949 2215 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2216
952af0b9 2217 -- Null body is generated for interface types
2218
76a1c25b 2219 if Is_Interface (Typ) then
2220 return
2221 Make_Subprogram_Body (Loc,
02a2406d 2222 Specification =>
2223 Make_Disp_Asynchronous_Select_Spec (Typ),
2224 Declarations => New_List,
76a1c25b 2225 Handled_Statement_Sequence =>
2226 Make_Handled_Sequence_Of_Statements (Loc,
02a2406d 2227 New_List (
2228 Make_Assignment_Statement (Loc,
2229 Name => Make_Identifier (Loc, Name_uF),
2230 Expression => New_Occurrence_Of (Standard_False, Loc)))));
9dfe12ae 2231 end if;
2232
952af0b9 2233 if Is_Concurrent_Record_Type (Typ) then
2234 Conc_Typ := Corresponding_Concurrent_Type (Typ);
aad6babd 2235
76a1c25b 2236 -- Generate:
cdb1c38f 2237 -- I : Integer :=
2238 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
aad6babd 2239
76a1c25b 2240 -- where I will be used to capture the entry index of the primitive
2241 -- wrapper at position S.
aad6babd 2242
bf7f5966 2243 if Tagged_Type_Expansion then
2244 Tag_Node :=
2245 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 2246 New_Occurrence_Of
bf7f5966 2247 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));
2248 else
2249 Tag_Node :=
2250 Make_Attribute_Reference (Loc,
02a2406d 2251 Prefix => New_Occurrence_Of (Typ, Loc),
bf7f5966 2252 Attribute_Name => Name_Tag);
2253 end if;
2254
76a1c25b 2255 Append_To (Decls,
2256 Make_Object_Declaration (Loc,
2257 Defining_Identifier =>
2258 Make_Defining_Identifier (Loc, Name_uI),
02a2406d 2259 Object_Definition =>
83c6c069 2260 New_Occurrence_Of (Standard_Integer, Loc),
02a2406d 2261 Expression =>
725a69d2 2262 Make_Function_Call (Loc,
02a2406d 2263 Name =>
83c6c069 2264 New_Occurrence_Of (RTE (RE_Get_Entry_Index), Loc),
cdb1c38f 2265 Parameter_Associations =>
02a2406d 2266 New_List (Tag_Node, Make_Identifier (Loc, Name_uS)))));
aad6babd 2267
76a1c25b 2268 if Ekind (Conc_Typ) = E_Protected_Type then
aad6babd 2269
725a69d2 2270 -- Generate:
cdb1c38f 2271 -- Bnn : Communication_Block;
725a69d2 2272
ec97ce79 2273 Com_Block := Make_Temporary (Loc, 'B');
725a69d2 2274 Append_To (Decls,
2275 Make_Object_Declaration (Loc,
02a2406d 2276 Defining_Identifier => Com_Block,
2277 Object_Definition =>
83c6c069 2278 New_Occurrence_Of (RTE (RE_Communication_Block), Loc)));
725a69d2 2279
acf97c11 2280 -- Build T._object'Access for calls below
aad6babd 2281
acf97c11 2282 Obj_Ref :=
2283 Make_Attribute_Reference (Loc,
2284 Attribute_Name => Name_Unchecked_Access,
2285 Prefix =>
2286 Make_Selected_Component (Loc,
2287 Prefix => Make_Identifier (Loc, Name_uT),
2288 Selector_Name => Make_Identifier (Loc, Name_uObject)));
aad6babd 2289
acf97c11 2290 case Corresponding_Runtime_Package (Conc_Typ) is
2291 when System_Tasking_Protected_Objects_Entries =>
aad6babd 2292
acf97c11 2293 -- Generate:
2294 -- Protected_Entry_Call
2295 -- (T._object'Access, -- Object
2296 -- Protected_Entry_Index! (I), -- E
2297 -- P, -- Uninterpreted_Data
2298 -- Asynchronous_Call, -- Mode
2299 -- Bnn); -- Communication_Block
2300
2301 -- where T is the protected object, I is the entry index, P
2302 -- is the wrapped parameters and B is the name of the
2303 -- communication block.
2304
2305 Append_To (Stmts,
2306 Make_Procedure_Call_Statement (Loc,
02a2406d 2307 Name =>
83c6c069 2308 New_Occurrence_Of (RTE (RE_Protected_Entry_Call), Loc),
acf97c11 2309 Parameter_Associations =>
2310 New_List (
2311 Obj_Ref,
aad6babd 2312
acf97c11 2313 Make_Unchecked_Type_Conversion (Loc, -- entry index
2314 Subtype_Mark =>
83c6c069 2315 New_Occurrence_Of
55868293 2316 (RTE (RE_Protected_Entry_Index), Loc),
acf97c11 2317 Expression => Make_Identifier (Loc, Name_uI)),
d62940bf 2318
acf97c11 2319 Make_Identifier (Loc, Name_uP), -- parameter block
83c6c069 2320 New_Occurrence_Of -- Asynchronous_Call
55868293 2321 (RTE (RE_Asynchronous_Call), Loc),
83c6c069 2322 New_Occurrence_Of -- comm block
2323 (Com_Block, Loc))));
acf97c11 2324
acf97c11 2325 when others =>
2326 raise Program_Error;
2327 end case;
725a69d2 2328
2329 -- Generate:
cdb1c38f 2330 -- B := Dummy_Communication_Block (Bnn);
725a69d2 2331
2332 Append_To (Stmts,
2333 Make_Assignment_Statement (Loc,
55868293 2334 Name => Make_Identifier (Loc, Name_uB),
725a69d2 2335 Expression =>
2336 Make_Unchecked_Type_Conversion (Loc,
2337 Subtype_Mark =>
02a2406d 2338 New_Occurrence_Of
2339 (RTE (RE_Dummy_Communication_Block), Loc),
2340 Expression => New_Occurrence_Of (Com_Block, Loc))));
725a69d2 2341
a053db0d 2342 -- Generate:
2343 -- F := False;
2344
2345 Append_To (Stmts,
2346 Make_Assignment_Statement (Loc,
aabafdc2 2347 Name => Make_Identifier (Loc, Name_uF),
83c6c069 2348 Expression => New_Occurrence_Of (Standard_False, Loc)));
a053db0d 2349
76a1c25b 2350 else
2351 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
d62940bf 2352
76a1c25b 2353 -- Generate:
cdb1c38f 2354 -- Task_Entry_Call
2355 -- (T._task_id, -- Acceptor
2356 -- Task_Entry_Index! (I), -- E
2357 -- P, -- Uninterpreted_Data
2358 -- Asynchronous_Call, -- Mode
2359 -- F); -- Rendezvous_Successful
ee6ba406 2360
acf97c11 2361 -- where T is the task object, I is the entry index, P is the
76a1c25b 2362 -- wrapped parameters and F is the status flag.
ee6ba406 2363
76a1c25b 2364 Append_To (Stmts,
2365 Make_Procedure_Call_Statement (Loc,
02a2406d 2366 Name =>
83c6c069 2367 New_Occurrence_Of (RTE (RE_Task_Entry_Call), Loc),
76a1c25b 2368 Parameter_Associations =>
2369 New_List (
76a1c25b 2370 Make_Selected_Component (Loc, -- T._task_id
55868293 2371 Prefix => Make_Identifier (Loc, Name_uT),
2372 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
ee6ba406 2373
76a1c25b 2374 Make_Unchecked_Type_Conversion (Loc, -- entry index
2375 Subtype_Mark =>
83c6c069 2376 New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
02a2406d 2377 Expression => Make_Identifier (Loc, Name_uI)),
ee6ba406 2378
76a1c25b 2379 Make_Identifier (Loc, Name_uP), -- parameter block
83c6c069 2380 New_Occurrence_Of -- Asynchronous_Call
55868293 2381 (RTE (RE_Asynchronous_Call), Loc),
76a1c25b 2382 Make_Identifier (Loc, Name_uF)))); -- status flag
2383 end if;
7c949aad 2384
2385 else
2386 -- Ensure that the statements list is non-empty
2387
a053db0d 2388 Append_To (Stmts,
2389 Make_Assignment_Statement (Loc,
aabafdc2 2390 Name => Make_Identifier (Loc, Name_uF),
83c6c069 2391 Expression => New_Occurrence_Of (Standard_False, Loc)));
76a1c25b 2392 end if;
ee6ba406 2393
76a1c25b 2394 return
2395 Make_Subprogram_Body (Loc,
aabafdc2 2396 Specification =>
76a1c25b 2397 Make_Disp_Asynchronous_Select_Spec (Typ),
aabafdc2 2398 Declarations => Decls,
76a1c25b 2399 Handled_Statement_Sequence =>
2400 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2401 end Make_Disp_Asynchronous_Select_Body;
ee6ba406 2402
76a1c25b 2403 ----------------------------------------
2404 -- Make_Disp_Asynchronous_Select_Spec --
2405 ----------------------------------------
ee6ba406 2406
76a1c25b 2407 function Make_Disp_Asynchronous_Select_Spec
2408 (Typ : Entity_Id) return Node_Id
2409 is
2410 Loc : constant Source_Ptr := Sloc (Typ);
2411 Def_Id : constant Node_Id :=
2412 Make_Defining_Identifier (Loc,
2413 Name_uDisp_Asynchronous_Select);
2414 Params : constant List_Id := New_List;
ee6ba406 2415
76a1c25b 2416 begin
68f95949 2417 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2418
725a69d2 2419 -- T : in out Typ; -- Object parameter
2420 -- S : Integer; -- Primitive operation slot
2421 -- P : Address; -- Wrapped parameters
2422 -- B : out Dummy_Communication_Block; -- Communication block dummy
2423 -- F : out Boolean; -- Status flag
ee6ba406 2424
725a69d2 2425 Append_List_To (Params, New_List (
2426
2427 Make_Parameter_Specification (Loc,
02a2406d 2428 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
2429 Parameter_Type => New_Occurrence_Of (Typ, Loc),
2430 In_Present => True,
2431 Out_Present => True),
725a69d2 2432
2433 Make_Parameter_Specification (Loc,
02a2406d 2434 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uS),
2435 Parameter_Type => New_Occurrence_Of (Standard_Integer, Loc)),
725a69d2 2436
2437 Make_Parameter_Specification (Loc,
02a2406d 2438 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uP),
2439 Parameter_Type => New_Occurrence_Of (RTE (RE_Address), Loc)),
725a69d2 2440
2441 Make_Parameter_Specification (Loc,
02a2406d 2442 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uB),
2443 Parameter_Type =>
83c6c069 2444 New_Occurrence_Of (RTE (RE_Dummy_Communication_Block), Loc),
02a2406d 2445 Out_Present => True),
ee6ba406 2446
725a69d2 2447 Make_Parameter_Specification (Loc,
02a2406d 2448 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uF),
2449 Parameter_Type => New_Occurrence_Of (Standard_Boolean, Loc),
2450 Out_Present => True)));
7189d17f 2451
76a1c25b 2452 return
725a69d2 2453 Make_Procedure_Specification (Loc,
2454 Defining_Unit_Name => Def_Id,
2455 Parameter_Specifications => Params);
76a1c25b 2456 end Make_Disp_Asynchronous_Select_Spec;
ee6ba406 2457
76a1c25b 2458 ---------------------------------------
2459 -- Make_Disp_Conditional_Select_Body --
2460 ---------------------------------------
ee6ba406 2461
cdb1c38f 2462 -- For interface types, generate:
2463
2464 -- procedure _Disp_Conditional_Select
2465 -- (T : in out <Typ>;
2466 -- S : Integer;
2467 -- P : System.Address;
2468 -- C : out Ada.Tags.Prim_Op_Kind;
2469 -- F : out Boolean)
2470 -- is
2471 -- begin
a053db0d 2472 -- F := False;
2473 -- C := Ada.Tags.POK_Function;
cdb1c38f 2474 -- end _Disp_Conditional_Select;
2475
2476 -- For protected types, generate:
2477
2478 -- procedure _Disp_Conditional_Select
2479 -- (T : in out <Typ>;
2480 -- S : Integer;
2481 -- P : System.Address;
2482 -- C : out Ada.Tags.Prim_Op_Kind;
2483 -- F : out Boolean)
2484 -- is
2485 -- I : Integer;
2486 -- Bnn : System.Tasking.Protected_Objects.Operations.
2487 -- Communication_Block;
2488
2489 -- begin
2490 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP, S));
2491
2492 -- if C = Ada.Tags.POK_Procedure
2493 -- or else C = Ada.Tags.POK_Protected_Procedure
2494 -- or else C = Ada.Tags.POK_Task_Procedure
2495 -- then
2496 -- F := True;
2497 -- return;
2498 -- end if;
2499
2500 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2501 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
2502 -- (T.object'Access,
2503 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
2504 -- P,
2505 -- System.Tasking.Conditional_Call,
2506 -- Bnn);
2507 -- F := not Cancelled (Bnn);
2508 -- end _Disp_Conditional_Select;
2509
2510 -- For task types, generate:
2511
2512 -- procedure _Disp_Conditional_Select
2513 -- (T : in out <Typ>;
2514 -- S : Integer;
2515 -- P : System.Address;
2516 -- C : out Ada.Tags.Prim_Op_Kind;
2517 -- F : out Boolean)
2518 -- is
2519 -- I : Integer;
2520
2521 -- begin
2522 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2523 -- System.Tasking.Rendezvous.Task_Entry_Call
2524 -- (T._task_id,
2525 -- System.Tasking.Task_Entry_Index (I),
2526 -- P,
2527 -- System.Tasking.Conditional_Call,
2528 -- F);
2529 -- end _Disp_Conditional_Select;
2530
76a1c25b 2531 function Make_Disp_Conditional_Select_Body
2532 (Typ : Entity_Id) return Node_Id
2533 is
2534 Loc : constant Source_Ptr := Sloc (Typ);
2535 Blk_Nam : Entity_Id;
2536 Conc_Typ : Entity_Id := Empty;
2537 Decls : constant List_Id := New_List;
acf97c11 2538 Obj_Ref : Node_Id;
76a1c25b 2539 Stmts : constant List_Id := New_List;
bf7f5966 2540 Tag_Node : Node_Id;
ee6ba406 2541
76a1c25b 2542 begin
68f95949 2543 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2544
952af0b9 2545 -- Null body is generated for interface types
2546
76a1c25b 2547 if Is_Interface (Typ) then
2548 return
2549 Make_Subprogram_Body (Loc,
02a2406d 2550 Specification =>
76a1c25b 2551 Make_Disp_Conditional_Select_Spec (Typ),
02a2406d 2552 Declarations => No_List,
76a1c25b 2553 Handled_Statement_Sequence =>
2554 Make_Handled_Sequence_Of_Statements (Loc,
a053db0d 2555 New_List (Make_Assignment_Statement (Loc,
aabafdc2 2556 Name => Make_Identifier (Loc, Name_uF),
83c6c069 2557 Expression => New_Occurrence_Of (Standard_False, Loc)))));
76a1c25b 2558 end if;
ee6ba406 2559
952af0b9 2560 if Is_Concurrent_Record_Type (Typ) then
2561 Conc_Typ := Corresponding_Concurrent_Type (Typ);
ee6ba406 2562
76a1c25b 2563 -- Generate:
2564 -- I : Integer;
ee6ba406 2565
76a1c25b 2566 -- where I will be used to capture the entry index of the primitive
2567 -- wrapper at position S.
ee6ba406 2568
76a1c25b 2569 Append_To (Decls,
2570 Make_Object_Declaration (Loc,
02a2406d 2571 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uI),
2572 Object_Definition =>
83c6c069 2573 New_Occurrence_Of (Standard_Integer, Loc)));
ee6ba406 2574
952af0b9 2575 -- Generate:
cdb1c38f 2576 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag! (<type>VP), S);
ee6ba406 2577
952af0b9 2578 -- if C = POK_Procedure
2579 -- or else C = POK_Protected_Procedure
2580 -- or else C = POK_Task_Procedure;
2581 -- then
2582 -- F := True;
2583 -- return;
2584 -- end if;
aad6babd 2585
e58ae6f1 2586 Build_Common_Dispatching_Select_Statements (Typ, Stmts);
aad6babd 2587
76a1c25b 2588 -- Generate:
2589 -- Bnn : Communication_Block;
aad6babd 2590
cdb1c38f 2591 -- where Bnn is the name of the communication block used in the
2592 -- call to Protected_Entry_Call.
aad6babd 2593
ec97ce79 2594 Blk_Nam := Make_Temporary (Loc, 'B');
76a1c25b 2595 Append_To (Decls,
2596 Make_Object_Declaration (Loc,
02a2406d 2597 Defining_Identifier => Blk_Nam,
2598 Object_Definition =>
83c6c069 2599 New_Occurrence_Of (RTE (RE_Communication_Block), Loc)));
aad6babd 2600
76a1c25b 2601 -- Generate:
cdb1c38f 2602 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
aad6babd 2603
76a1c25b 2604 -- I is the entry index and S is the dispatch table slot
aad6babd 2605
bf7f5966 2606 if Tagged_Type_Expansion then
2607 Tag_Node :=
2608 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 2609 New_Occurrence_Of
bf7f5966 2610 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));
2611
2612 else
2613 Tag_Node :=
2614 Make_Attribute_Reference (Loc,
02a2406d 2615 Prefix => New_Occurrence_Of (Typ, Loc),
bf7f5966 2616 Attribute_Name => Name_Tag);
2617 end if;
2618
76a1c25b 2619 Append_To (Stmts,
2620 Make_Assignment_Statement (Loc,
02a2406d 2621 Name => Make_Identifier (Loc, Name_uI),
76a1c25b 2622 Expression =>
725a69d2 2623 Make_Function_Call (Loc,
02a2406d 2624 Name =>
83c6c069 2625 New_Occurrence_Of (RTE (RE_Get_Entry_Index), Loc),
02a2406d 2626 Parameter_Associations => New_List (
2627 Tag_Node,
2628 Make_Identifier (Loc, Name_uS)))));
ee6ba406 2629
76a1c25b 2630 if Ekind (Conc_Typ) = E_Protected_Type then
ee6ba406 2631
acf97c11 2632 Obj_Ref := -- T._object'Access
2633 Make_Attribute_Reference (Loc,
2634 Attribute_Name => Name_Unchecked_Access,
2635 Prefix =>
2636 Make_Selected_Component (Loc,
2637 Prefix => Make_Identifier (Loc, Name_uT),
2638 Selector_Name => Make_Identifier (Loc, Name_uObject)));
ee6ba406 2639
acf97c11 2640 case Corresponding_Runtime_Package (Conc_Typ) is
2641 when System_Tasking_Protected_Objects_Entries =>
2642 -- Generate:
e1c20931 2643
acf97c11 2644 -- Protected_Entry_Call
2645 -- (T._object'Access, -- Object
2646 -- Protected_Entry_Index! (I), -- E
2647 -- P, -- Uninterpreted_Data
2648 -- Conditional_Call, -- Mode
2649 -- Bnn); -- Block
e1c20931 2650
acf97c11 2651 -- where T is the protected object, I is the entry index, P
2652 -- are the wrapped parameters and Bnn is the name of the
2653 -- communication block.
d62940bf 2654
acf97c11 2655 Append_To (Stmts,
2656 Make_Procedure_Call_Statement (Loc,
02a2406d 2657 Name =>
83c6c069 2658 New_Occurrence_Of (RTE (RE_Protected_Entry_Call), Loc),
02a2406d 2659 Parameter_Associations => New_List (
acf97c11 2660 Obj_Ref,
d62940bf 2661
acf97c11 2662 Make_Unchecked_Type_Conversion (Loc, -- entry index
2663 Subtype_Mark =>
83c6c069 2664 New_Occurrence_Of
acf97c11 2665 (RTE (RE_Protected_Entry_Index), Loc),
2666 Expression => Make_Identifier (Loc, Name_uI)),
2667
2668 Make_Identifier (Loc, Name_uP), -- parameter block
2669
83c6c069 2670 New_Occurrence_Of -- Conditional_Call
2671 (RTE (RE_Conditional_Call), Loc),
2672 New_Occurrence_Of -- Bnn
2673 (Blk_Nam, Loc))));
acf97c11 2674
2675 when System_Tasking_Protected_Objects_Single_Entry =>
2676
2677 -- If we are compiling for a restricted run-time, the call
2678 -- uses the simpler form.
2679
2680 Append_To (Stmts,
2681 Make_Procedure_Call_Statement (Loc,
02a2406d 2682 Name =>
83c6c069 2683 New_Occurrence_Of
acf97c11 2684 (RTE (RE_Protected_Single_Entry_Call), Loc),
02a2406d 2685 Parameter_Associations => New_List (
acf97c11 2686 Obj_Ref,
2687
2688 Make_Attribute_Reference (Loc,
55868293 2689 Prefix => Make_Identifier (Loc, Name_uP),
acf97c11 2690 Attribute_Name => Name_Address),
2691
83c6c069 2692 New_Occurrence_Of
acf97c11 2693 (RTE (RE_Conditional_Call), Loc))));
2694 when others =>
2695 raise Program_Error;
2696 end case;
d62940bf 2697
76a1c25b 2698 -- Generate:
2699 -- F := not Cancelled (Bnn);
e1c20931 2700
76a1c25b 2701 -- where F is the success flag. The status of Cancelled is negated
2702 -- in order to match the behaviour of the version for task types.
e1c20931 2703
76a1c25b 2704 Append_To (Stmts,
2705 Make_Assignment_Statement (Loc,
55868293 2706 Name => Make_Identifier (Loc, Name_uF),
76a1c25b 2707 Expression =>
2708 Make_Op_Not (Loc,
2709 Right_Opnd =>
2710 Make_Function_Call (Loc,
02a2406d 2711 Name =>
83c6c069 2712 New_Occurrence_Of (RTE (RE_Cancelled), Loc),
02a2406d 2713 Parameter_Associations => New_List (
83c6c069 2714 New_Occurrence_Of (Blk_Nam, Loc))))));
76a1c25b 2715 else
2716 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
d62940bf 2717
76a1c25b 2718 -- Generate:
cdb1c38f 2719 -- Task_Entry_Call
2720 -- (T._task_id, -- Acceptor
2721 -- Task_Entry_Index! (I), -- E
2722 -- P, -- Uninterpreted_Data
2723 -- Conditional_Call, -- Mode
2724 -- F); -- Rendezvous_Successful
d62940bf 2725
76a1c25b 2726 -- where T is the task object, I is the entry index, P are the
2727 -- wrapped parameters and F is the status flag.
e1c20931 2728
76a1c25b 2729 Append_To (Stmts,
2730 Make_Procedure_Call_Statement (Loc,
02a2406d 2731 Name =>
83c6c069 2732 New_Occurrence_Of (RTE (RE_Task_Entry_Call), Loc),
02a2406d 2733 Parameter_Associations => New_List (
76a1c25b 2734
2735 Make_Selected_Component (Loc, -- T._task_id
55868293 2736 Prefix => Make_Identifier (Loc, Name_uT),
2737 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
76a1c25b 2738
2739 Make_Unchecked_Type_Conversion (Loc, -- entry index
2740 Subtype_Mark =>
83c6c069 2741 New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
55868293 2742 Expression => Make_Identifier (Loc, Name_uI)),
76a1c25b 2743
2744 Make_Identifier (Loc, Name_uP), -- parameter block
83c6c069 2745 New_Occurrence_Of -- Conditional_Call
55868293 2746 (RTE (RE_Conditional_Call), Loc),
76a1c25b 2747 Make_Identifier (Loc, Name_uF)))); -- status flag
d62940bf 2748 end if;
7c949aad 2749
2750 else
a053db0d 2751 -- Initialize out parameters
7c949aad 2752
a053db0d 2753 Append_To (Stmts,
2754 Make_Assignment_Statement (Loc,
aabafdc2 2755 Name => Make_Identifier (Loc, Name_uF),
83c6c069 2756 Expression => New_Occurrence_Of (Standard_False, Loc)));
a053db0d 2757 Append_To (Stmts,
2758 Make_Assignment_Statement (Loc,
aabafdc2 2759 Name => Make_Identifier (Loc, Name_uC),
83c6c069 2760 Expression => New_Occurrence_Of (RTE (RE_POK_Function), Loc)));
76a1c25b 2761 end if;
2762
2763 return
2764 Make_Subprogram_Body (Loc,
aabafdc2 2765 Specification =>
76a1c25b 2766 Make_Disp_Conditional_Select_Spec (Typ),
aabafdc2 2767 Declarations => Decls,
76a1c25b 2768 Handled_Statement_Sequence =>
2769 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2770 end Make_Disp_Conditional_Select_Body;
2771
2772 ---------------------------------------
2773 -- Make_Disp_Conditional_Select_Spec --
2774 ---------------------------------------
2775
2776 function Make_Disp_Conditional_Select_Spec
2777 (Typ : Entity_Id) return Node_Id
2778 is
2779 Loc : constant Source_Ptr := Sloc (Typ);
2780 Def_Id : constant Node_Id :=
2781 Make_Defining_Identifier (Loc,
2782 Name_uDisp_Conditional_Select);
2783 Params : constant List_Id := New_List;
2784
2785 begin
68f95949 2786 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2787
725a69d2 2788 -- T : in out Typ; -- Object parameter
2789 -- S : Integer; -- Primitive operation slot
2790 -- P : Address; -- Wrapped parameters
2791 -- C : out Prim_Op_Kind; -- Call kind
2792 -- F : out Boolean; -- Status flag
2793
2794 Append_List_To (Params, New_List (
2795
2796 Make_Parameter_Specification (Loc,
02a2406d 2797 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
2798 Parameter_Type => New_Occurrence_Of (Typ, Loc),
2799 In_Present => True,
2800 Out_Present => True),
725a69d2 2801
2802 Make_Parameter_Specification (Loc,
02a2406d 2803 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uS),
2804 Parameter_Type => New_Occurrence_Of (Standard_Integer, Loc)),
725a69d2 2805
2806 Make_Parameter_Specification (Loc,
02a2406d 2807 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uP),
2808 Parameter_Type => New_Occurrence_Of (RTE (RE_Address), Loc)),
76a1c25b 2809
725a69d2 2810 Make_Parameter_Specification (Loc,
02a2406d 2811 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uC),
2812 Parameter_Type =>
83c6c069 2813 New_Occurrence_Of (RTE (RE_Prim_Op_Kind), Loc),
02a2406d 2814 Out_Present => True),
76a1c25b 2815
725a69d2 2816 Make_Parameter_Specification (Loc,
02a2406d 2817 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uF),
2818 Parameter_Type => New_Occurrence_Of (Standard_Boolean, Loc),
2819 Out_Present => True)));
76a1c25b 2820
2821 return
2822 Make_Procedure_Specification (Loc,
2823 Defining_Unit_Name => Def_Id,
2824 Parameter_Specifications => Params);
2825 end Make_Disp_Conditional_Select_Spec;
2826
2827 -------------------------------------
2828 -- Make_Disp_Get_Prim_Op_Kind_Body --
2829 -------------------------------------
2830
02a2406d 2831 function Make_Disp_Get_Prim_Op_Kind_Body (Typ : Entity_Id) return Node_Id is
bf7f5966 2832 Loc : constant Source_Ptr := Sloc (Typ);
2833 Tag_Node : Node_Id;
76a1c25b 2834
2835 begin
68f95949 2836 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2837
76a1c25b 2838 if Is_Interface (Typ) then
2839 return
2840 Make_Subprogram_Body (Loc,
02a2406d 2841 Specification =>
76a1c25b 2842 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
02a2406d 2843 Declarations => New_List,
76a1c25b 2844 Handled_Statement_Sequence =>
2845 Make_Handled_Sequence_Of_Statements (Loc,
2846 New_List (Make_Null_Statement (Loc))));
e1c20931 2847 end if;
2848
d62940bf 2849 -- Generate:
76a1c25b 2850 -- C := get_prim_op_kind (tag! (<type>VP), S);
ee6ba406 2851
76a1c25b 2852 -- where C is the out parameter capturing the call kind and S is the
2853 -- dispatch table slot number.
ee6ba406 2854
bf7f5966 2855 if Tagged_Type_Expansion then
2856 Tag_Node :=
2857 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 2858 New_Occurrence_Of
bf7f5966 2859 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));
2860
2861 else
2862 Tag_Node :=
2863 Make_Attribute_Reference (Loc,
02a2406d 2864 Prefix => New_Occurrence_Of (Typ, Loc),
bf7f5966 2865 Attribute_Name => Name_Tag);
2866 end if;
2867
76a1c25b 2868 return
2869 Make_Subprogram_Body (Loc,
02a2406d 2870 Specification =>
76a1c25b 2871 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
02a2406d 2872 Declarations => New_List,
76a1c25b 2873 Handled_Statement_Sequence =>
2874 Make_Handled_Sequence_Of_Statements (Loc,
2875 New_List (
2876 Make_Assignment_Statement (Loc,
02a2406d 2877 Name => Make_Identifier (Loc, Name_uC),
76a1c25b 2878 Expression =>
725a69d2 2879 Make_Function_Call (Loc,
2880 Name =>
83c6c069 2881 New_Occurrence_Of (RTE (RE_Get_Prim_Op_Kind), Loc),
725a69d2 2882 Parameter_Associations => New_List (
bf7f5966 2883 Tag_Node,
2884 Make_Identifier (Loc, Name_uS)))))));
76a1c25b 2885 end Make_Disp_Get_Prim_Op_Kind_Body;
e1c20931 2886
76a1c25b 2887 -------------------------------------
2888 -- Make_Disp_Get_Prim_Op_Kind_Spec --
2889 -------------------------------------
e1c20931 2890
76a1c25b 2891 function Make_Disp_Get_Prim_Op_Kind_Spec
2892 (Typ : Entity_Id) return Node_Id
2893 is
2894 Loc : constant Source_Ptr := Sloc (Typ);
2895 Def_Id : constant Node_Id :=
02a2406d 2896 Make_Defining_Identifier (Loc, Name_uDisp_Get_Prim_Op_Kind);
76a1c25b 2897 Params : constant List_Id := New_List;
e1c20931 2898
76a1c25b 2899 begin
68f95949 2900 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2901
725a69d2 2902 -- T : in out Typ; -- Object parameter
2903 -- S : Integer; -- Primitive operation slot
2904 -- C : out Prim_Op_Kind; -- Call kind
2905
2906 Append_List_To (Params, New_List (
2907
2908 Make_Parameter_Specification (Loc,
02a2406d 2909 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
2910 Parameter_Type => New_Occurrence_Of (Typ, Loc),
2911 In_Present => True,
2912 Out_Present => True),
ee6ba406 2913
725a69d2 2914 Make_Parameter_Specification (Loc,
02a2406d 2915 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uS),
2916 Parameter_Type => New_Occurrence_Of (Standard_Integer, Loc)),
ee6ba406 2917
725a69d2 2918 Make_Parameter_Specification (Loc,
02a2406d 2919 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uC),
2920 Parameter_Type =>
83c6c069 2921 New_Occurrence_Of (RTE (RE_Prim_Op_Kind), Loc),
02a2406d 2922 Out_Present => True)));
76a1c25b 2923
2924 return
2925 Make_Procedure_Specification (Loc,
2926 Defining_Unit_Name => Def_Id,
2927 Parameter_Specifications => Params);
2928 end Make_Disp_Get_Prim_Op_Kind_Spec;
2929
2930 --------------------------------
2931 -- Make_Disp_Get_Task_Id_Body --
2932 --------------------------------
2933
2934 function Make_Disp_Get_Task_Id_Body
2935 (Typ : Entity_Id) return Node_Id
2936 is
2937 Loc : constant Source_Ptr := Sloc (Typ);
2938 Ret : Node_Id;
2939
2940 begin
68f95949 2941 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2942
76a1c25b 2943 if Is_Concurrent_Record_Type (Typ)
2944 and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
2945 then
725a69d2 2946 -- Generate:
2947 -- return To_Address (_T._task_id);
2948
76a1c25b 2949 Ret :=
17e14451 2950 Make_Simple_Return_Statement (Loc,
76a1c25b 2951 Expression =>
725a69d2 2952 Make_Unchecked_Type_Conversion (Loc,
02a2406d 2953 Subtype_Mark => New_Occurrence_Of (RTE (RE_Address), Loc),
2954 Expression =>
725a69d2 2955 Make_Selected_Component (Loc,
55868293 2956 Prefix => Make_Identifier (Loc, Name_uT),
2957 Selector_Name => Make_Identifier (Loc, Name_uTask_Id))));
76a1c25b 2958
2959 -- A null body is constructed for non-task types
2960
2961 else
725a69d2 2962 -- Generate:
2963 -- return Null_Address;
2964
76a1c25b 2965 Ret :=
17e14451 2966 Make_Simple_Return_Statement (Loc,
02a2406d 2967 Expression => New_Occurrence_Of (RTE (RE_Null_Address), Loc));
76a1c25b 2968 end if;
2969
2970 return
2971 Make_Subprogram_Body (Loc,
02a2406d 2972 Specification => Make_Disp_Get_Task_Id_Spec (Typ),
2973 Declarations => New_List,
76a1c25b 2974 Handled_Statement_Sequence =>
02a2406d 2975 Make_Handled_Sequence_Of_Statements (Loc, New_List (Ret)));
76a1c25b 2976 end Make_Disp_Get_Task_Id_Body;
2977
2978 --------------------------------
2979 -- Make_Disp_Get_Task_Id_Spec --
2980 --------------------------------
2981
2982 function Make_Disp_Get_Task_Id_Spec
2983 (Typ : Entity_Id) return Node_Id
2984 is
725a69d2 2985 Loc : constant Source_Ptr := Sloc (Typ);
76a1c25b 2986
2987 begin
68f95949 2988 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2989
76a1c25b 2990 return
2991 Make_Function_Specification (Loc,
02a2406d 2992 Defining_Unit_Name =>
725a69d2 2993 Make_Defining_Identifier (Loc, Name_uDisp_Get_Task_Id),
76a1c25b 2994 Parameter_Specifications => New_List (
2995 Make_Parameter_Specification (Loc,
02a2406d 2996 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
2997 Parameter_Type => New_Occurrence_Of (Typ, Loc))),
2998 Result_Definition =>
83c6c069 2999 New_Occurrence_Of (RTE (RE_Address), Loc));
76a1c25b 3000 end Make_Disp_Get_Task_Id_Spec;
3001
cdb1c38f 3002 ----------------------------
3003 -- Make_Disp_Requeue_Body --
3004 ----------------------------
3005
3006 function Make_Disp_Requeue_Body
3007 (Typ : Entity_Id) return Node_Id
3008 is
3009 Loc : constant Source_Ptr := Sloc (Typ);
3010 Conc_Typ : Entity_Id := Empty;
3011 Stmts : constant List_Id := New_List;
3012
3013 begin
3014 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3015
3016 -- Null body is generated for interface types and non-concurrent
3017 -- tagged types.
3018
3019 if Is_Interface (Typ)
3020 or else not Is_Concurrent_Record_Type (Typ)
3021 then
3022 return
3023 Make_Subprogram_Body (Loc,
02a2406d 3024 Specification => Make_Disp_Requeue_Spec (Typ),
3025 Declarations => No_List,
cdb1c38f 3026 Handled_Statement_Sequence =>
3027 Make_Handled_Sequence_Of_Statements (Loc,
3028 New_List (Make_Null_Statement (Loc))));
3029 end if;
3030
3031 Conc_Typ := Corresponding_Concurrent_Type (Typ);
3032
3033 if Ekind (Conc_Typ) = E_Protected_Type then
3034
3035 -- Generate statements:
3036 -- if F then
3037 -- System.Tasking.Protected_Objects.Operations.
3038 -- Requeue_Protected_Entry
3039 -- (Protection_Entries_Access (P),
3040 -- O._object'Unchecked_Access,
3041 -- Protected_Entry_Index (I),
3042 -- A);
3043 -- else
3044 -- System.Tasking.Protected_Objects.Operations.
3045 -- Requeue_Task_To_Protected_Entry
3046 -- (O._object'Unchecked_Access,
3047 -- Protected_Entry_Index (I),
3048 -- A);
3049 -- end if;
3050
acf97c11 3051 if Restriction_Active (No_Entry_Queue) then
3052 Append_To (Stmts, Make_Null_Statement (Loc));
3053 else
3054 Append_To (Stmts,
3055 Make_If_Statement (Loc,
55868293 3056 Condition => Make_Identifier (Loc, Name_uF),
cdb1c38f 3057
acf97c11 3058 Then_Statements =>
3059 New_List (
cdb1c38f 3060
acf97c11 3061 -- Call to Requeue_Protected_Entry
cdb1c38f 3062
acf97c11 3063 Make_Procedure_Call_Statement (Loc,
3064 Name =>
02a2406d 3065 New_Occurrence_Of
3066 (RTE (RE_Requeue_Protected_Entry), Loc),
acf97c11 3067 Parameter_Associations =>
3068 New_List (
3069
3070 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
3071 Subtype_Mark =>
83c6c069 3072 New_Occurrence_Of (
acf97c11 3073 RTE (RE_Protection_Entries_Access), Loc),
3074 Expression =>
3075 Make_Identifier (Loc, Name_uP)),
3076
3077 Make_Attribute_Reference (Loc, -- O._object'Acc
3078 Attribute_Name =>
3079 Name_Unchecked_Access,
02a2406d 3080 Prefix =>
acf97c11 3081 Make_Selected_Component (Loc,
55868293 3082 Prefix =>
acf97c11 3083 Make_Identifier (Loc, Name_uO),
3084 Selector_Name =>
3085 Make_Identifier (Loc, Name_uObject))),
3086
3087 Make_Unchecked_Type_Conversion (Loc, -- entry index
3088 Subtype_Mark =>
02a2406d 3089 New_Occurrence_Of
3090 (RTE (RE_Protected_Entry_Index), Loc),
55868293 3091 Expression => Make_Identifier (Loc, Name_uI)),
cdb1c38f 3092
acf97c11 3093 Make_Identifier (Loc, Name_uA)))), -- abort status
cdb1c38f 3094
acf97c11 3095 Else_Statements =>
3096 New_List (
cdb1c38f 3097
acf97c11 3098 -- Call to Requeue_Task_To_Protected_Entry
cdb1c38f 3099
acf97c11 3100 Make_Procedure_Call_Statement (Loc,
3101 Name =>
02a2406d 3102 New_Occurrence_Of
3103 (RTE (RE_Requeue_Task_To_Protected_Entry), Loc),
acf97c11 3104 Parameter_Associations =>
3105 New_List (
3106
3107 Make_Attribute_Reference (Loc, -- O._object'Acc
02a2406d 3108 Attribute_Name => Name_Unchecked_Access,
3109 Prefix =>
acf97c11 3110 Make_Selected_Component (Loc,
02a2406d 3111 Prefix =>
acf97c11 3112 Make_Identifier (Loc, Name_uO),
3113 Selector_Name =>
3114 Make_Identifier (Loc, Name_uObject))),
3115
3116 Make_Unchecked_Type_Conversion (Loc, -- entry index
3117 Subtype_Mark =>
02a2406d 3118 New_Occurrence_Of
3119 (RTE (RE_Protected_Entry_Index), Loc),
3120 Expression => Make_Identifier (Loc, Name_uI)),
cdb1c38f 3121
acf97c11 3122 Make_Identifier (Loc, Name_uA)))))); -- abort status
3123 end if;
02a2406d 3124
cdb1c38f 3125 else
3126 pragma Assert (Is_Task_Type (Conc_Typ));
3127
3128 -- Generate:
3129 -- if F then
3130 -- System.Tasking.Rendezvous.Requeue_Protected_To_Task_Entry
3131 -- (Protection_Entries_Access (P),
3132 -- O._task_id,
3133 -- Task_Entry_Index (I),
3134 -- A);
3135 -- else
3136 -- System.Tasking.Rendezvous.Requeue_Task_Entry
3137 -- (O._task_id,
3138 -- Task_Entry_Index (I),
3139 -- A);
3140 -- end if;
3141
3142 Append_To (Stmts,
3143 Make_If_Statement (Loc,
55868293 3144 Condition => Make_Identifier (Loc, Name_uF),
cdb1c38f 3145
55868293 3146 Then_Statements => New_List (
cdb1c38f 3147
55868293 3148 -- Call to Requeue_Protected_To_Task_Entry
cdb1c38f 3149
55868293 3150 Make_Procedure_Call_Statement (Loc,
3151 Name =>
83c6c069 3152 New_Occurrence_Of
55868293 3153 (RTE (RE_Requeue_Protected_To_Task_Entry), Loc),
cdb1c38f 3154
55868293 3155 Parameter_Associations => New_List (
cdb1c38f 3156
55868293 3157 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
3158 Subtype_Mark =>
83c6c069 3159 New_Occurrence_Of
55868293 3160 (RTE (RE_Protection_Entries_Access), Loc),
3161 Expression => Make_Identifier (Loc, Name_uP)),
cdb1c38f 3162
55868293 3163 Make_Selected_Component (Loc, -- O._task_id
3164 Prefix => Make_Identifier (Loc, Name_uO),
3165 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
cdb1c38f 3166
55868293 3167 Make_Unchecked_Type_Conversion (Loc, -- entry index
3168 Subtype_Mark =>
83c6c069 3169 New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
55868293 3170 Expression => Make_Identifier (Loc, Name_uI)),
cdb1c38f 3171
55868293 3172 Make_Identifier (Loc, Name_uA)))), -- abort status
cdb1c38f 3173
55868293 3174 Else_Statements => New_List (
cdb1c38f 3175
55868293 3176 -- Call to Requeue_Task_Entry
cdb1c38f 3177
55868293 3178 Make_Procedure_Call_Statement (Loc,
02a2406d 3179 Name =>
3180 New_Occurrence_Of (RTE (RE_Requeue_Task_Entry), Loc),
cdb1c38f 3181
55868293 3182 Parameter_Associations => New_List (
cdb1c38f 3183
55868293 3184 Make_Selected_Component (Loc, -- O._task_id
3185 Prefix => Make_Identifier (Loc, Name_uO),
3186 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
cdb1c38f 3187
55868293 3188 Make_Unchecked_Type_Conversion (Loc, -- entry index
3189 Subtype_Mark =>
83c6c069 3190 New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
55868293 3191 Expression => Make_Identifier (Loc, Name_uI)),
cdb1c38f 3192
55868293 3193 Make_Identifier (Loc, Name_uA)))))); -- abort status
cdb1c38f 3194 end if;
3195
3196 -- Even though no declarations are needed in both cases, we allocate
3197 -- a list for entities added by Freeze.
3198
3199 return
3200 Make_Subprogram_Body (Loc,
02a2406d 3201 Specification => Make_Disp_Requeue_Spec (Typ),
3202 Declarations => New_List,
cdb1c38f 3203 Handled_Statement_Sequence =>
3204 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
3205 end Make_Disp_Requeue_Body;
3206
3207 ----------------------------
3208 -- Make_Disp_Requeue_Spec --
3209 ----------------------------
3210
3211 function Make_Disp_Requeue_Spec
3212 (Typ : Entity_Id) return Node_Id
3213 is
3214 Loc : constant Source_Ptr := Sloc (Typ);
3215
3216 begin
3217 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3218
3219 -- O : in out Typ; - Object parameter
3220 -- F : Boolean; - Protected (True) / task (False) flag
3221 -- P : Address; - Protection_Entries_Access value
3222 -- I : Entry_Index - Index of entry call
3223 -- A : Boolean - Abort flag
3224
3225 -- Note that the Protection_Entries_Access value is represented as a
3226 -- System.Address in order to avoid dragging in the tasking runtime
3227 -- when compiling sources without tasking constructs.
3228
3229 return
3230 Make_Procedure_Specification (Loc,
3231 Defining_Unit_Name =>
3232 Make_Defining_Identifier (Loc, Name_uDisp_Requeue),
3233
02a2406d 3234 Parameter_Specifications => New_List (
cdb1c38f 3235
3236 Make_Parameter_Specification (Loc, -- O
3237 Defining_Identifier =>
3238 Make_Defining_Identifier (Loc, Name_uO),
02a2406d 3239 Parameter_Type =>
83c6c069 3240 New_Occurrence_Of (Typ, Loc),
02a2406d 3241 In_Present => True,
3242 Out_Present => True),
cdb1c38f 3243
3244 Make_Parameter_Specification (Loc, -- F
3245 Defining_Identifier =>
3246 Make_Defining_Identifier (Loc, Name_uF),
02a2406d 3247 Parameter_Type =>
83c6c069 3248 New_Occurrence_Of (Standard_Boolean, Loc)),
cdb1c38f 3249
3250 Make_Parameter_Specification (Loc, -- P
3251 Defining_Identifier =>
3252 Make_Defining_Identifier (Loc, Name_uP),
02a2406d 3253 Parameter_Type =>
83c6c069 3254 New_Occurrence_Of (RTE (RE_Address), Loc)),
cdb1c38f 3255
3256 Make_Parameter_Specification (Loc, -- I
3257 Defining_Identifier =>
3258 Make_Defining_Identifier (Loc, Name_uI),
02a2406d 3259 Parameter_Type =>
83c6c069 3260 New_Occurrence_Of (Standard_Integer, Loc)),
cdb1c38f 3261
3262 Make_Parameter_Specification (Loc, -- A
3263 Defining_Identifier =>
3264 Make_Defining_Identifier (Loc, Name_uA),
02a2406d 3265 Parameter_Type =>
83c6c069 3266 New_Occurrence_Of (Standard_Boolean, Loc))));
cdb1c38f 3267 end Make_Disp_Requeue_Spec;
3268
76a1c25b 3269 ---------------------------------
3270 -- Make_Disp_Timed_Select_Body --
3271 ---------------------------------
3272
cdb1c38f 3273 -- For interface types, generate:
3274
3275 -- procedure _Disp_Timed_Select
3276 -- (T : in out <Typ>;
3277 -- S : Integer;
3278 -- P : System.Address;
3279 -- D : Duration;
3280 -- M : Integer;
3281 -- C : out Ada.Tags.Prim_Op_Kind;
3282 -- F : out Boolean)
3283 -- is
3284 -- begin
a053db0d 3285 -- F := False;
3286 -- C := Ada.Tags.POK_Function;
cdb1c38f 3287 -- end _Disp_Timed_Select;
3288
3289 -- For protected types, generate:
3290
3291 -- procedure _Disp_Timed_Select
3292 -- (T : in out <Typ>;
3293 -- S : Integer;
3294 -- P : System.Address;
3295 -- D : Duration;
3296 -- M : Integer;
3297 -- C : out Ada.Tags.Prim_Op_Kind;
3298 -- F : out Boolean)
3299 -- is
3300 -- I : Integer;
3301
3302 -- begin
3303 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP), S);
3304
3305 -- if C = Ada.Tags.POK_Procedure
3306 -- or else C = Ada.Tags.POK_Protected_Procedure
3307 -- or else C = Ada.Tags.POK_Task_Procedure
3308 -- then
3309 -- F := True;
3310 -- return;
3311 -- end if;
3312
3313 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
3314 -- System.Tasking.Protected_Objects.Operations.
3315 -- Timed_Protected_Entry_Call
3316 -- (T._object'Access,
3317 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
3318 -- P,
3319 -- D,
3320 -- M,
3321 -- F);
3322 -- end _Disp_Timed_Select;
3323
3324 -- For task types, generate:
3325
3326 -- procedure _Disp_Timed_Select
3327 -- (T : in out <Typ>;
3328 -- S : Integer;
3329 -- P : System.Address;
3330 -- D : Duration;
3331 -- M : Integer;
3332 -- C : out Ada.Tags.Prim_Op_Kind;
3333 -- F : out Boolean)
3334 -- is
3335 -- I : Integer;
3336
3337 -- begin
3338 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
3339 -- System.Tasking.Rendezvous.Timed_Task_Entry_Call
3340 -- (T._task_id,
3341 -- System.Tasking.Task_Entry_Index (I),
3342 -- P,
3343 -- D,
3344 -- M,
a053db0d 3345 -- F);
cdb1c38f 3346 -- end _Disp_Time_Select;
3347
76a1c25b 3348 function Make_Disp_Timed_Select_Body
3349 (Typ : Entity_Id) return Node_Id
3350 is
3351 Loc : constant Source_Ptr := Sloc (Typ);
3352 Conc_Typ : Entity_Id := Empty;
3353 Decls : constant List_Id := New_List;
acf97c11 3354 Obj_Ref : Node_Id;
76a1c25b 3355 Stmts : constant List_Id := New_List;
bf7f5966 3356 Tag_Node : Node_Id;
76a1c25b 3357
3358 begin
68f95949 3359 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3360
952af0b9 3361 -- Null body is generated for interface types
3362
76a1c25b 3363 if Is_Interface (Typ) then
3364 return
3365 Make_Subprogram_Body (Loc,
02a2406d 3366 Specification => Make_Disp_Timed_Select_Spec (Typ),
3367 Declarations => New_List,
76a1c25b 3368 Handled_Statement_Sequence =>
3369 Make_Handled_Sequence_Of_Statements (Loc,
aabafdc2 3370 New_List (
3371 Make_Assignment_Statement (Loc,
3372 Name => Make_Identifier (Loc, Name_uF),
83c6c069 3373 Expression => New_Occurrence_Of (Standard_False, Loc)))));
76a1c25b 3374 end if;
3375
952af0b9 3376 if Is_Concurrent_Record_Type (Typ) then
3377 Conc_Typ := Corresponding_Concurrent_Type (Typ);
76a1c25b 3378
3379 -- Generate:
3380 -- I : Integer;
3381
3382 -- where I will be used to capture the entry index of the primitive
3383 -- wrapper at position S.
3384
3385 Append_To (Decls,
3386 Make_Object_Declaration (Loc,
aabafdc2 3387 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uI),
83c6c069 3388 Object_Definition =>
3389 New_Occurrence_Of (Standard_Integer, Loc)));
76a1c25b 3390
952af0b9 3391 -- Generate:
3392 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
76a1c25b 3393
952af0b9 3394 -- if C = POK_Procedure
3395 -- or else C = POK_Protected_Procedure
3396 -- or else C = POK_Task_Procedure;
3397 -- then
3398 -- F := True;
3399 -- return;
3400 -- end if;
76a1c25b 3401
e58ae6f1 3402 Build_Common_Dispatching_Select_Statements (Typ, Stmts);
76a1c25b 3403
3404 -- Generate:
952af0b9 3405 -- I := Get_Entry_Index (tag! (<type>VP), S);
76a1c25b 3406
3407 -- I is the entry index and S is the dispatch table slot
3408
bf7f5966 3409 if Tagged_Type_Expansion then
3410 Tag_Node :=
3411 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 3412 New_Occurrence_Of
bf7f5966 3413 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));
3414
3415 else
3416 Tag_Node :=
3417 Make_Attribute_Reference (Loc,
83c6c069 3418 Prefix => New_Occurrence_Of (Typ, Loc),
bf7f5966 3419 Attribute_Name => Name_Tag);
3420 end if;
3421
76a1c25b 3422 Append_To (Stmts,
3423 Make_Assignment_Statement (Loc,
55868293 3424 Name => Make_Identifier (Loc, Name_uI),
76a1c25b 3425 Expression =>
725a69d2 3426 Make_Function_Call (Loc,
83c6c069 3427 Name => New_Occurrence_Of (RTE (RE_Get_Entry_Index), Loc),
02a2406d 3428 Parameter_Associations => New_List (
3429 Tag_Node,
3430 Make_Identifier (Loc, Name_uS)))));
76a1c25b 3431
acf97c11 3432 -- Protected case
3433
76a1c25b 3434 if Ekind (Conc_Typ) = E_Protected_Type then
3435
acf97c11 3436 -- Build T._object'Access
3437
3438 Obj_Ref :=
3439 Make_Attribute_Reference (Loc,
3440 Attribute_Name => Name_Unchecked_Access,
3441 Prefix =>
3442 Make_Selected_Component (Loc,
3443 Prefix => Make_Identifier (Loc, Name_uT),
3444 Selector_Name => Make_Identifier (Loc, Name_uObject)));
3445
3446 -- Normal case, No_Entry_Queue restriction not active. In this
3447 -- case we generate:
3448
3449 -- Timed_Protected_Entry_Call
3450 -- (T._object'access,
cdb1c38f 3451 -- Protected_Entry_Index! (I),
acf97c11 3452 -- P, D, M, F);
76a1c25b 3453
3454 -- where T is the protected object, I is the entry index, P are
3455 -- the wrapped parameters, D is the delay amount, M is the delay
3456 -- mode and F is the status flag.
3457
10970cab 3458 -- Historically, there was also an implementation for single
3459 -- entry protected types (in s-tposen). However, it was removed
3460 -- by also testing for no No_Select_Statements restriction in
3461 -- Exp_Utils.Corresponding_Runtime_Package. This simplified the
8dfd0767 3462 -- implementation of s-tposen.adb and provided consistency between
3463 -- all versions of System.Tasking.Protected_Objects.Single_Entry
3464 -- (s-tposen*.adb).
10970cab 3465
acf97c11 3466 case Corresponding_Runtime_Package (Conc_Typ) is
3467 when System_Tasking_Protected_Objects_Entries =>
3468 Append_To (Stmts,
3469 Make_Procedure_Call_Statement (Loc,
3470 Name =>
83c6c069 3471 New_Occurrence_Of
acf97c11 3472 (RTE (RE_Timed_Protected_Entry_Call), Loc),
02a2406d 3473 Parameter_Associations => New_List (
3474 Obj_Ref,
acf97c11 3475
02a2406d 3476 Make_Unchecked_Type_Conversion (Loc, -- entry index
3477 Subtype_Mark =>
3478 New_Occurrence_Of
3479 (RTE (RE_Protected_Entry_Index), Loc),
3480 Expression => Make_Identifier (Loc, Name_uI)),
76a1c25b 3481
02a2406d 3482 Make_Identifier (Loc, Name_uP), -- parameter block
3483 Make_Identifier (Loc, Name_uD), -- delay
3484 Make_Identifier (Loc, Name_uM), -- delay mode
3485 Make_Identifier (Loc, Name_uF)))); -- status flag
76a1c25b 3486
acf97c11 3487 when others =>
3488 raise Program_Error;
3489 end case;
3490
3491 -- Task case
ee6ba406 3492
ee6ba406 3493 else
76a1c25b 3494 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
3495
3496 -- Generate:
3497 -- Timed_Task_Entry_Call (
3498 -- T._task_id,
cdb1c38f 3499 -- Task_Entry_Index! (I),
76a1c25b 3500 -- P,
3501 -- D,
3502 -- M,
3503 -- F);
3504
3505 -- where T is the task object, I is the entry index, P are the
3506 -- wrapped parameters, D is the delay amount, M is the delay
3507 -- mode and F is the status flag.
3508
3509 Append_To (Stmts,
3510 Make_Procedure_Call_Statement (Loc,
02a2406d 3511 Name =>
83c6c069 3512 New_Occurrence_Of (RTE (RE_Timed_Task_Entry_Call), Loc),
76a1c25b 3513
02a2406d 3514 Parameter_Associations => New_List (
3515 Make_Selected_Component (Loc, -- T._task_id
3516 Prefix => Make_Identifier (Loc, Name_uT),
3517 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
76a1c25b 3518
02a2406d 3519 Make_Unchecked_Type_Conversion (Loc, -- entry index
3520 Subtype_Mark =>
3521 New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
3522 Expression => Make_Identifier (Loc, Name_uI)),
76a1c25b 3523
02a2406d 3524 Make_Identifier (Loc, Name_uP), -- parameter block
3525 Make_Identifier (Loc, Name_uD), -- delay
3526 Make_Identifier (Loc, Name_uM), -- delay mode
3527 Make_Identifier (Loc, Name_uF)))); -- status flag
ee6ba406 3528 end if;
7c949aad 3529
3530 else
a053db0d 3531 -- Initialize out parameters
7c949aad 3532
a053db0d 3533 Append_To (Stmts,
3534 Make_Assignment_Statement (Loc,
aabafdc2 3535 Name => Make_Identifier (Loc, Name_uF),
83c6c069 3536 Expression => New_Occurrence_Of (Standard_False, Loc)));
a053db0d 3537 Append_To (Stmts,
3538 Make_Assignment_Statement (Loc,
aabafdc2 3539 Name => Make_Identifier (Loc, Name_uC),
83c6c069 3540 Expression => New_Occurrence_Of (RTE (RE_POK_Function), Loc)));
76a1c25b 3541 end if;
3542
3543 return
3544 Make_Subprogram_Body (Loc,
aabafdc2 3545 Specification => Make_Disp_Timed_Select_Spec (Typ),
3546 Declarations => Decls,
76a1c25b 3547 Handled_Statement_Sequence =>
3548 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
3549 end Make_Disp_Timed_Select_Body;
3550
3551 ---------------------------------
3552 -- Make_Disp_Timed_Select_Spec --
3553 ---------------------------------
3554
3555 function Make_Disp_Timed_Select_Spec
3556 (Typ : Entity_Id) return Node_Id
3557 is
3558 Loc : constant Source_Ptr := Sloc (Typ);
3559 Def_Id : constant Node_Id :=
3560 Make_Defining_Identifier (Loc,
3561 Name_uDisp_Timed_Select);
3562 Params : constant List_Id := New_List;
ee6ba406 3563
76a1c25b 3564 begin
68f95949 3565 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3566
725a69d2 3567 -- T : in out Typ; -- Object parameter
3568 -- S : Integer; -- Primitive operation slot
3569 -- P : Address; -- Wrapped parameters
3570 -- D : Duration; -- Delay
3571 -- M : Integer; -- Delay Mode
3572 -- C : out Prim_Op_Kind; -- Call kind
3573 -- F : out Boolean; -- Status flag
76a1c25b 3574
725a69d2 3575 Append_List_To (Params, New_List (
3576
3577 Make_Parameter_Specification (Loc,
02a2406d 3578 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
3579 Parameter_Type => New_Occurrence_Of (Typ, Loc),
3580 In_Present => True,
3581 Out_Present => True),
725a69d2 3582
3583 Make_Parameter_Specification (Loc,
02a2406d 3584 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uS),
3585 Parameter_Type => New_Occurrence_Of (Standard_Integer, Loc)),
725a69d2 3586
3587 Make_Parameter_Specification (Loc,
02a2406d 3588 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uP),
3589 Parameter_Type => New_Occurrence_Of (RTE (RE_Address), Loc)),
76a1c25b 3590
76a1c25b 3591 Make_Parameter_Specification (Loc,
02a2406d 3592 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uD),
3593 Parameter_Type => New_Occurrence_Of (Standard_Duration, Loc)),
76a1c25b 3594
76a1c25b 3595 Make_Parameter_Specification (Loc,
02a2406d 3596 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uM),
3597 Parameter_Type => New_Occurrence_Of (Standard_Integer, Loc)),
ee6ba406 3598
725a69d2 3599 Make_Parameter_Specification (Loc,
02a2406d 3600 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uC),
3601 Parameter_Type =>
83c6c069 3602 New_Occurrence_Of (RTE (RE_Prim_Op_Kind), Loc),
02a2406d 3603 Out_Present => True)));
ee6ba406 3604
725a69d2 3605 Append_To (Params,
3606 Make_Parameter_Specification (Loc,
02a2406d 3607 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uF),
3608 Parameter_Type => New_Occurrence_Of (Standard_Boolean, Loc),
3609 Out_Present => True));
ee6ba406 3610
76a1c25b 3611 return
3612 Make_Procedure_Specification (Loc,
3613 Defining_Unit_Name => Def_Id,
3614 Parameter_Specifications => Params);
3615 end Make_Disp_Timed_Select_Spec;
ee6ba406 3616
76a1c25b 3617 -------------
3618 -- Make_DT --
3619 -------------
ee6ba406 3620
725a69d2 3621 -- The frontend supports two models for expanding dispatch tables
02a2406d 3622 -- associated with library-level defined tagged types: statically and
3623 -- non-statically allocated dispatch tables. In the former case the object
3624 -- containing the dispatch table is constant and it is initialized by means
3625 -- of a positional aggregate. In the latter case, the object containing
3626 -- the dispatch table is a variable which is initialized by means of
3627 -- assignments.
725a69d2 3628
3629 -- In case of locally defined tagged types, the object containing the
02a2406d 3630 -- object containing the dispatch table is always a variable (instead of a
3631 -- constant). This is currently required to give support to late overriding
3632 -- of primitives. For example:
725a69d2 3633
3634 -- procedure Example is
3635 -- package Pkg is
3636 -- type T1 is tagged null record;
3637 -- procedure Prim (O : T1);
3638 -- end Pkg;
3639
3640 -- type T2 is new Pkg.T1 with null record;
3641 -- procedure Prim (X : T2) is -- late overriding
3642 -- begin
3643 -- ...
3644 -- ...
3645 -- end;
952af0b9 3646
17e14451 3647 function Make_DT (Typ : Entity_Id; N : Node_Id := Empty) return List_Id is
360b005f 3648 GM : constant Ghost_Mode_Type := Ghost_Mode;
3649 -- Save the current Ghost mode in effect in case the tagged type sets a
3650 -- different mode.
3651
17e14451 3652 Loc : constant Source_Ptr := Sloc (Typ);
3653
725a69d2 3654 Max_Predef_Prims : constant Int :=
3655 UI_To_Int
3656 (Intval
3657 (Expression
17e14451 3658 (Parent (RTE (RE_Max_Predef_Prims)))));
3659
cc60bd16 3660 DT_Decl : constant Elist_Id := New_Elmt_List;
3661 DT_Aggr : constant Elist_Id := New_Elmt_List;
3662 -- Entities marked with attribute Is_Dispatch_Table_Entity
3663
349db231 3664 procedure Check_Premature_Freezing
3665 (Subp : Entity_Id;
3666 Tagged_Type : Entity_Id;
3667 Typ : Entity_Id);
d1a2e31b 3668 -- Verify that all untagged types in the profile of a subprogram are
3669 -- frozen at the point the subprogram is frozen. This enforces the rule
3670 -- on RM 13.14 (14) as modified by AI05-019. At the point a subprogram
3671 -- is frozen, enough must be known about it to build the activation
3672 -- record for it, which requires at least that the size of all
3673 -- parameters be known. Controlling arguments are by-reference,
decd66e0 3674 -- and therefore the rule only applies to untagged types. Typical
d1a2e31b 3675 -- violation of the rule involves an object declaration that freezes a
3676 -- tagged type, when one of its primitive operations has a type in its
3677 -- profile whose full view has not been analyzed yet. More complex cases
3678 -- involve composite types that have one private unfrozen subcomponent.
725a69d2 3679
f301a57b 3680 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0);
3681 -- Export the dispatch table DT of tagged type Typ. Required to generate
3682 -- forward references and statically allocate the table. For primary
3683 -- dispatch tables Index is 0; for secondary dispatch tables the value
3684 -- of index must match the Suffix_Index value assigned to the table by
3685 -- Make_Tags when generating its unique external name, and it is used to
3686 -- retrieve from the Dispatch_Table_Wrappers list associated with Typ
3687 -- the external name generated by Import_DT.
24971415 3688
725a69d2 3689 procedure Make_Secondary_DT
acf97c11 3690 (Typ : Entity_Id;
3691 Iface : Entity_Id;
f301a57b 3692 Suffix_Index : Int;
acf97c11 3693 Num_Iface_Prims : Nat;
3694 Iface_DT_Ptr : Entity_Id;
3695 Predef_Prims_Ptr : Entity_Id;
3696 Build_Thunks : Boolean;
3697 Result : List_Id);
cdb1c38f 3698 -- Ada 2005 (AI-251): Expand the declarations for a Secondary Dispatch
3699 -- Table of Typ associated with Iface. Each abstract interface of Typ
3700 -- has two secondary dispatch tables: one containing pointers to thunks
3701 -- and another containing pointers to the primitives covering the
3702 -- interface primitives. The former secondary table is generated when
3703 -- Build_Thunks is True, and provides common support for dispatching
3704 -- calls through interface types; the latter secondary table is
3705 -- generated when Build_Thunks is False, and provides support for
3706 -- Generic Dispatching Constructors that dispatch calls through
278c67dc 3707 -- interface types. When constructing this latter table the value of
3708 -- Suffix_Index is -1 to indicate that there is no need to export such
3709 -- table when building statically allocated dispatch tables; a positive
3710 -- value of Suffix_Index must match the Suffix_Index value assigned to
3711 -- this secondary dispatch table by Make_Tags when its unique external
3712 -- name was generated.
9dfe12ae 3713
360b005f 3714 procedure Restore_Globals;
3715 -- Restore the values of all saved global variables
3716
17e14451 3717 ------------------------------
3718 -- Check_Premature_Freezing --
3719 ------------------------------
3720
349db231 3721 procedure Check_Premature_Freezing
3722 (Subp : Entity_Id;
3723 Tagged_Type : Entity_Id;
3724 Typ : Entity_Id)
3725 is
3726 Comp : Entity_Id;
aada9bb5 3727
3728 function Is_Actual_For_Formal_Incomplete_Type
3729 (T : Entity_Id) return Boolean;
65a805b2 3730 -- In Ada 2012, if a nested generic has an incomplete formal type,
3731 -- the actual may be (and usually is) a private type whose completion
5f8e1c78 3732 -- appears later. It is safe to build the dispatch table in this
3733 -- case, gigi will have full views available.
3734
3735 ------------------------------------------
3736 -- Is_Actual_For_Formal_Incomplete_Type --
3737 ------------------------------------------
3738
aada9bb5 3739 function Is_Actual_For_Formal_Incomplete_Type
3740 (T : Entity_Id) return Boolean
5f8e1c78 3741 is
3742 Gen_Par : Entity_Id;
3743 F : Node_Id;
aada9bb5 3744
5f8e1c78 3745 begin
3746 if not Is_Generic_Instance (Current_Scope)
3747 or else not Used_As_Generic_Actual (T)
3748 then
3749 return False;
5f8e1c78 3750 else
3751 Gen_Par := Generic_Parent (Parent (Current_Scope));
3752 end if;
3753
3754 F :=
3755 First
3756 (Generic_Formal_Declarations
02a2406d 3757 (Unit_Declaration_Node (Gen_Par)));
5f8e1c78 3758 while Present (F) loop
3759 if Ekind (Defining_Identifier (F)) = E_Incomplete_Type then
3760 return True;
3761 end if;
3762
3763 Next (F);
3764 end loop;
3765
3766 return False;
3767 end Is_Actual_For_Formal_Incomplete_Type;
278c67dc 3768
aada9bb5 3769 -- Start of processing for Check_Premature_Freezing
3770
17e14451 3771 begin
496b8337 3772 -- Note that if the type is a (subtype of) a generic actual, the
3773 -- actual will have been frozen by the instantiation.
3774
17e14451 3775 if Present (N)
349db231 3776 and then Is_Private_Type (Typ)
17e14451 3777 and then No (Full_View (Typ))
3778 and then not Is_Generic_Type (Typ)
3779 and then not Is_Tagged_Type (Typ)
3780 and then not Is_Frozen (Typ)
496b8337 3781 and then not Is_Generic_Actual_Type (Typ)
17e14451 3782 then
3783 Error_Msg_Sloc := Sloc (Subp);
503f7fd3 3784 Error_Msg_NE
17e14451 3785 ("declaration must appear after completion of type &", N, Typ);
3786 Error_Msg_NE
02a2406d 3787 ("\which is an untagged type in the profile of "
3788 & "primitive operation & declared#", N, Subp);
349db231 3789
3790 else
3791 Comp := Private_Component (Typ);
3792
3793 if not Is_Tagged_Type (Typ)
3794 and then Present (Comp)
3795 and then not Is_Frozen (Comp)
02a2406d 3796 and then not Is_Actual_For_Formal_Incomplete_Type (Comp)
349db231 3797 then
3798 Error_Msg_Sloc := Sloc (Subp);
3799 Error_Msg_Node_2 := Subp;
3800 Error_Msg_Name_1 := Chars (Tagged_Type);
3801 Error_Msg_NE
3802 ("declaration must appear after completion of type &",
02a2406d 3803 N, Comp);
349db231 3804 Error_Msg_NE
02a2406d 3805 ("\which is a component of untagged type& in the profile "
3806 & "of primitive & of type % that is frozen by the "
3807 & "declaration ", N, Typ);
349db231 3808 end if;
17e14451 3809 end if;
3810 end Check_Premature_Freezing;
3811
24971415 3812 ---------------
3813 -- Export_DT --
3814 ---------------
3815
f301a57b 3816 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0)
3817 is
3818 Count : Nat;
3819 Elmt : Elmt_Id;
3820
24971415 3821 begin
3822 Set_Is_Statically_Allocated (DT);
3823 Set_Is_True_Constant (DT);
3824 Set_Is_Exported (DT);
3825
f301a57b 3826 Count := 0;
3827 Elmt := First_Elmt (Dispatch_Table_Wrappers (Typ));
3828 while Count /= Index loop
3829 Next_Elmt (Elmt);
3830 Count := Count + 1;
3831 end loop;
3832
3833 pragma Assert (Related_Type (Node (Elmt)) = Typ);
3834
f92da234 3835 Get_External_Name (Node (Elmt));
24971415 3836 Set_Interface_Name (DT,
3837 Make_String_Literal (Loc,
3838 Strval => String_From_Name_Buffer));
3839
3840 -- Ensure proper Sprint output of this implicit importation
3841
3842 Set_Is_Internal (DT);
3843 Set_Is_Public (DT);
3844 end Export_DT;
3845
725a69d2 3846 -----------------------
3847 -- Make_Secondary_DT --
3848 -----------------------
ee6ba406 3849
725a69d2 3850 procedure Make_Secondary_DT
acf97c11 3851 (Typ : Entity_Id;
3852 Iface : Entity_Id;
f301a57b 3853 Suffix_Index : Int;
acf97c11 3854 Num_Iface_Prims : Nat;
3855 Iface_DT_Ptr : Entity_Id;
3856 Predef_Prims_Ptr : Entity_Id;
3857 Build_Thunks : Boolean;
3858 Result : List_Id)
725a69d2 3859 is
3860 Loc : constant Source_Ptr := Sloc (Typ);
f301a57b 3861 Exporting_Table : constant Boolean :=
3862 Building_Static_DT (Typ)
3863 and then Suffix_Index > 0;
ec97ce79 3864 Iface_DT : constant Entity_Id := Make_Temporary (Loc, 'T');
3865 Predef_Prims : constant Entity_Id := Make_Temporary (Loc, 'R');
725a69d2 3866 DT_Constr_List : List_Id;
3867 DT_Aggr_List : List_Id;
3868 Empty_DT : Boolean := False;
3869 Nb_Predef_Prims : Nat := 0;
3870 Nb_Prim : Nat;
3871 New_Node : Node_Id;
3872 OSD : Entity_Id;
3873 OSD_Aggr_List : List_Id;
3874 Pos : Nat;
3875 Prim : Entity_Id;
3876 Prim_Elmt : Elmt_Id;
3877 Prim_Ops_Aggr_List : List_Id;
343d35dc 3878
725a69d2 3879 begin
17e14451 3880 -- Handle cases in which we do not generate statically allocated
3881 -- dispatch tables.
343d35dc 3882
24971415 3883 if not Building_Static_DT (Typ) then
725a69d2 3884 Set_Ekind (Predef_Prims, E_Variable);
725a69d2 3885 Set_Ekind (Iface_DT, E_Variable);
343d35dc 3886
725a69d2 3887 -- Statically allocated dispatch tables and related entities are
3888 -- constants.
343d35dc 3889
725a69d2 3890 else
3891 Set_Ekind (Predef_Prims, E_Constant);
3892 Set_Is_Statically_Allocated (Predef_Prims);
3893 Set_Is_True_Constant (Predef_Prims);
343d35dc 3894
725a69d2 3895 Set_Ekind (Iface_DT, E_Constant);
3896 Set_Is_Statically_Allocated (Iface_DT);
3897 Set_Is_True_Constant (Iface_DT);
343d35dc 3898 end if;
3899
f301a57b 3900 -- Calculate the number of slots of the dispatch table. If the number
3901 -- of primitives of Typ is 0 we reserve a dummy single entry for its
0c826ed4 3902 -- DT because at run time the pointer to this dummy entry will be
f301a57b 3903 -- used as the tag.
68f95949 3904
cdb1c38f 3905 if Num_Iface_Prims = 0 then
725a69d2 3906 Empty_DT := True;
3907 Nb_Prim := 1;
cdb1c38f 3908 else
3909 Nb_Prim := Num_Iface_Prims;
725a69d2 3910 end if;
76a1c25b 3911
725a69d2 3912 -- Generate:
952af0b9 3913
725a69d2 3914 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
3915 -- (predef-prim-op-thunk-1'address,
3916 -- predef-prim-op-thunk-2'address,
3917 -- ...
3918 -- predef-prim-op-thunk-n'address);
3919 -- for Predef_Prims'Alignment use Address'Alignment
952af0b9 3920
725a69d2 3921 -- Stage 1: Calculate the number of predefined primitives
76a1c25b 3922
24971415 3923 if not Building_Static_DT (Typ) then
725a69d2 3924 Nb_Predef_Prims := Max_Predef_Prims;
3925 else
3926 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3927 while Present (Prim_Elmt) loop
3928 Prim := Node (Prim_Elmt);
aad6babd 3929
725a69d2 3930 if Is_Predefined_Dispatching_Operation (Prim)
3931 and then not Is_Abstract_Subprogram (Prim)
3932 then
3933 Pos := UI_To_Int (DT_Position (Prim));
aad6babd 3934
725a69d2 3935 if Pos > Nb_Predef_Prims then
3936 Nb_Predef_Prims := Pos;
3937 end if;
3938 end if;
aad6babd 3939
725a69d2 3940 Next_Elmt (Prim_Elmt);
3941 end loop;
3942 end if;
aad6babd 3943
725a69d2 3944 -- Stage 2: Create the thunks associated with the predefined
3945 -- primitives and save their entity to fill the aggregate.
ee6ba406 3946
725a69d2 3947 declare
3948 Prim_Table : array (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
cc60bd16 3949 Decl : Node_Id;
725a69d2 3950 Thunk_Id : Entity_Id;
3951 Thunk_Code : Node_Id;
aad6babd 3952
725a69d2 3953 begin
3954 Prim_Ops_Aggr_List := New_List;
3955 Prim_Table := (others => Empty);
aad6babd 3956
cdb1c38f 3957 if Building_Static_DT (Typ) then
3958 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3959 while Present (Prim_Elmt) loop
3960 Prim := Node (Prim_Elmt);
aad6babd 3961
cdb1c38f 3962 if Is_Predefined_Dispatching_Operation (Prim)
3963 and then not Is_Abstract_Subprogram (Prim)
3f8cf2d2 3964 and then not Is_Eliminated (Prim)
cdb1c38f 3965 and then not Present (Prim_Table
3966 (UI_To_Int (DT_Position (Prim))))
3967 then
3968 if not Build_Thunks then
3969 Prim_Table (UI_To_Int (DT_Position (Prim))) :=
3970 Alias (Prim);
aad6babd 3971
cdb1c38f 3972 else
fc2907f6 3973 Expand_Interface_Thunk
3974 (Ultimate_Alias (Prim), Thunk_Id, Thunk_Code);
aad6babd 3975
cdb1c38f 3976 if Present (Thunk_Id) then
3977 Append_To (Result, Thunk_Code);
3978 Prim_Table (UI_To_Int (DT_Position (Prim)))
3979 := Thunk_Id;
3980 end if;
3981 end if;
725a69d2 3982 end if;
aad6babd 3983
cdb1c38f 3984 Next_Elmt (Prim_Elmt);
3985 end loop;
3986 end if;
aad6babd 3987
725a69d2 3988 for J in Prim_Table'Range loop
3989 if Present (Prim_Table (J)) then
3990 New_Node :=
cc60bd16 3991 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
acf97c11 3992 Make_Attribute_Reference (Loc,
83c6c069 3993 Prefix => New_Occurrence_Of (Prim_Table (J), Loc),
acf97c11 3994 Attribute_Name => Name_Unrestricted_Access));
725a69d2 3995 else
cc60bd16 3996 New_Node := Make_Null (Loc);
725a69d2 3997 end if;
952af0b9 3998
725a69d2 3999 Append_To (Prim_Ops_Aggr_List, New_Node);
4000 end loop;
952af0b9 4001
cc60bd16 4002 New_Node :=
02a2406d 4003 Make_Aggregate (Loc, Expressions => Prim_Ops_Aggr_List);
cc60bd16 4004
4005 -- Remember aggregates initializing dispatch tables
4006
4007 Append_Elmt (New_Node, DT_Aggr);
4008
4009 Decl :=
4010 Make_Subtype_Declaration (Loc,
ec97ce79 4011 Defining_Identifier => Make_Temporary (Loc, 'S'),
4012 Subtype_Indication =>
83c6c069 4013 New_Occurrence_Of (RTE (RE_Address_Array), Loc));
cc60bd16 4014
4015 Append_To (Result, Decl);
4016
725a69d2 4017 Append_To (Result,
4018 Make_Object_Declaration (Loc,
4019 Defining_Identifier => Predef_Prims,
24971415 4020 Constant_Present => Building_Static_DT (Typ),
725a69d2 4021 Aliased_Present => True,
83c6c069 4022 Object_Definition => New_Occurrence_Of
cc60bd16 4023 (Defining_Identifier (Decl), Loc),
4024 Expression => New_Node));
aad6babd 4025
725a69d2 4026 Append_To (Result,
4027 Make_Attribute_Definition_Clause (Loc,
83c6c069 4028 Name => New_Occurrence_Of (Predef_Prims, Loc),
725a69d2 4029 Chars => Name_Alignment,
4030 Expression =>
4031 Make_Attribute_Reference (Loc,
4032 Prefix =>
83c6c069 4033 New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
725a69d2 4034 Attribute_Name => Name_Alignment)));
4035 end;
aad6babd 4036
725a69d2 4037 -- Generate
76a1c25b 4038
725a69d2 4039 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
4040 -- (OSD_Table => (1 => <value>,
4041 -- ...
4042 -- N => <value>));
76a1c25b 4043
725a69d2 4044 -- Iface_DT : Dispatch_Table (Nb_Prims) :=
4045 -- ([ Signature => <sig-value> ],
4046 -- Tag_Kind => <tag_kind-value>,
4047 -- Predef_Prims => Predef_Prims'Address,
4048 -- Offset_To_Top => 0,
4049 -- OSD => OSD'Address,
4050 -- Prims_Ptr => (prim-op-1'address,
4051 -- prim-op-2'address,
4052 -- ...
4053 -- prim-op-n'address));
f301a57b 4054 -- for Iface_DT'Alignment use Address'Alignment;
76a1c25b 4055
725a69d2 4056 -- Stage 3: Initialize the discriminant and the record components
aad6babd 4057
725a69d2 4058 DT_Constr_List := New_List;
4059 DT_Aggr_List := New_List;
343d35dc 4060
4c5d0f70 4061 -- Nb_Prim
343d35dc 4062
4c5d0f70 4063 Append_To (DT_Constr_List, Make_Integer_Literal (Loc, Nb_Prim));
4064 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, Nb_Prim));
343d35dc 4065
725a69d2 4066 -- Signature
343d35dc 4067
725a69d2 4068 if RTE_Record_Component_Available (RE_Signature) then
4069 Append_To (DT_Aggr_List,
83c6c069 4070 New_Occurrence_Of (RTE (RE_Secondary_DT), Loc));
725a69d2 4071 end if;
343d35dc 4072
725a69d2 4073 -- Tag_Kind
343d35dc 4074
725a69d2 4075 if RTE_Record_Component_Available (RE_Tag_Kind) then
4076 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
4077 end if;
aad6babd 4078
725a69d2 4079 -- Predef_Prims
aad6babd 4080
725a69d2 4081 Append_To (DT_Aggr_List,
4082 Make_Attribute_Reference (Loc,
02a2406d 4083 Prefix => New_Occurrence_Of (Predef_Prims, Loc),
725a69d2 4084 Attribute_Name => Name_Address));
aad6babd 4085
725a69d2 4086 -- Note: The correct value of Offset_To_Top will be set by the init
4087 -- subprogram
aad6babd 4088
725a69d2 4089 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
aad6babd 4090
725a69d2 4091 -- Generate the Object Specific Data table required to dispatch calls
4092 -- through synchronized interfaces.
aad6babd 4093
725a69d2 4094 if Empty_DT
4095 or else Is_Abstract_Type (Typ)
4096 or else Is_Controlled (Typ)
4097 or else Restriction_Active (No_Dispatching_Calls)
4098 or else not Is_Limited_Type (Typ)
a652dd51 4099 or else not Has_Interfaces (Typ)
cdb1c38f 4100 or else not Build_Thunks
38d2fa31 4101 or else not RTE_Record_Component_Available (RE_OSD_Table)
725a69d2 4102 then
4103 -- No OSD table required
ee6ba406 4104
725a69d2 4105 Append_To (DT_Aggr_List,
83c6c069 4106 New_Occurrence_Of (RTE (RE_Null_Address), Loc));
d62940bf 4107
725a69d2 4108 else
4109 OSD_Aggr_List := New_List;
d62940bf 4110
725a69d2 4111 declare
4112 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
4113 Prim : Entity_Id;
4114 Prim_Alias : Entity_Id;
4115 Prim_Elmt : Elmt_Id;
4116 E : Entity_Id;
4117 Count : Nat := 0;
4118 Pos : Nat;
d62940bf 4119
725a69d2 4120 begin
4121 Prim_Table := (others => Empty);
4122 Prim_Alias := Empty;
d62940bf 4123
725a69d2 4124 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4125 while Present (Prim_Elmt) loop
4126 Prim := Node (Prim_Elmt);
d62940bf 4127
a652dd51 4128 if Present (Interface_Alias (Prim))
725a69d2 4129 and then Find_Dispatching_Type
a652dd51 4130 (Interface_Alias (Prim)) = Iface
725a69d2 4131 then
a652dd51 4132 Prim_Alias := Interface_Alias (Prim);
fc2907f6 4133 E := Ultimate_Alias (Prim);
725a69d2 4134 Pos := UI_To_Int (DT_Position (Prim_Alias));
68f95949 4135
725a69d2 4136 if Present (Prim_Table (Pos)) then
4137 pragma Assert (Prim_Table (Pos) = E);
4138 null;
68f95949 4139
725a69d2 4140 else
4141 Prim_Table (Pos) := E;
4142
4143 Append_To (OSD_Aggr_List,
4144 Make_Component_Association (Loc,
02a2406d 4145 Choices => New_List (
725a69d2 4146 Make_Integer_Literal (Loc,
4147 DT_Position (Prim_Alias))),
4148 Expression =>
4149 Make_Integer_Literal (Loc,
4150 DT_Position (Alias (Prim)))));
4151
4152 Count := Count + 1;
4153 end if;
4154 end if;
4155
4156 Next_Elmt (Prim_Elmt);
4157 end loop;
4158 pragma Assert (Count = Nb_Prim);
4159 end;
4160
ec97ce79 4161 OSD := Make_Temporary (Loc, 'I');
725a69d2 4162
4163 Append_To (Result,
4164 Make_Object_Declaration (Loc,
4165 Defining_Identifier => OSD,
4166 Object_Definition =>
4167 Make_Subtype_Indication (Loc,
4168 Subtype_Mark =>
83c6c069 4169 New_Occurrence_Of (RTE (RE_Object_Specific_Data), Loc),
02a2406d 4170 Constraint =>
725a69d2 4171 Make_Index_Or_Discriminant_Constraint (Loc,
4172 Constraints => New_List (
4173 Make_Integer_Literal (Loc, Nb_Prim)))),
725a69d2 4174
ec97ce79 4175 Expression =>
4176 Make_Aggregate (Loc,
4177 Component_Associations => New_List (
4178 Make_Component_Association (Loc,
02a2406d 4179 Choices => New_List (
ec97ce79 4180 New_Occurrence_Of
4181 (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
4182 Expression =>
4183 Make_Integer_Literal (Loc, Nb_Prim)),
4184
4185 Make_Component_Association (Loc,
02a2406d 4186 Choices => New_List (
ec97ce79 4187 New_Occurrence_Of
4188 (RTE_Record_Component (RE_OSD_Table), Loc)),
4189 Expression => Make_Aggregate (Loc,
4190 Component_Associations => OSD_Aggr_List))))));
725a69d2 4191
17e14451 4192 Append_To (Result,
4193 Make_Attribute_Definition_Clause (Loc,
83c6c069 4194 Name => New_Occurrence_Of (OSD, Loc),
17e14451 4195 Chars => Name_Alignment,
4196 Expression =>
4197 Make_Attribute_Reference (Loc,
02a2406d 4198 Prefix =>
83c6c069 4199 New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
17e14451 4200 Attribute_Name => Name_Alignment)));
4201
725a69d2 4202 -- In secondary dispatch tables the Typeinfo component contains
4203 -- the address of the Object Specific Data (see a-tags.ads)
4204
4205 Append_To (DT_Aggr_List,
4206 Make_Attribute_Reference (Loc,
02a2406d 4207 Prefix => New_Occurrence_Of (OSD, Loc),
725a69d2 4208 Attribute_Name => Name_Address));
4209 end if;
4210
4211 -- Initialize the table of primitive operations
4212
4213 Prim_Ops_Aggr_List := New_List;
4214
4215 if Empty_DT then
cc60bd16 4216 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
725a69d2 4217
4218 elsif Is_Abstract_Type (Typ)
9a479e51 4219 or else not Building_Static_DT (Typ)
725a69d2 4220 then
4221 for J in 1 .. Nb_Prim loop
cc60bd16 4222 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
725a69d2 4223 end loop;
4224
4225 else
4226 declare
d00681a7 4227 CPP_Nb_Prims : constant Nat := CPP_Num_Prims (Typ);
4228 E : Entity_Id;
4229 Prim_Pos : Nat;
4230 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
4231 Thunk_Code : Node_Id;
4232 Thunk_Id : Entity_Id;
725a69d2 4233
4234 begin
4235 Prim_Table := (others => Empty);
4236
4237 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4238 while Present (Prim_Elmt) loop
d00681a7 4239 Prim := Node (Prim_Elmt);
4240 E := Ultimate_Alias (Prim);
4241 Prim_Pos := UI_To_Int (DT_Position (E));
725a69d2 4242
d00681a7 4243 -- Do not reference predefined primitives because they are
4244 -- located in a separate dispatch table; skip abstract and
4245 -- eliminated primitives; skip primitives located in the C++
4246 -- part of the dispatch table because their slot is set by
4247 -- the IC routine.
3f8cf2d2 4248
725a69d2 4249 if not Is_Predefined_Dispatching_Operation (Prim)
a652dd51 4250 and then Present (Interface_Alias (Prim))
725a69d2 4251 and then not Is_Abstract_Subprogram (Alias (Prim))
3f8cf2d2 4252 and then not Is_Eliminated (Alias (Prim))
d00681a7 4253 and then (not Is_CPP_Class (Root_Type (Typ))
4254 or else Prim_Pos > CPP_Nb_Prims)
725a69d2 4255 and then Find_Dispatching_Type
a652dd51 4256 (Interface_Alias (Prim)) = Iface
725a69d2 4257
4258 -- Generate the code of the thunk only if the abstract
4259 -- interface type is not an immediate ancestor of
d00681a7 4260 -- Tagged_Type. Otherwise the DT associated with the
725a69d2 4261 -- interface is the primary DT.
4262
cb4af01d 4263 and then not Is_Ancestor (Iface, Typ,
4264 Use_Full_View => True)
725a69d2 4265 then
cdb1c38f 4266 if not Build_Thunks then
d00681a7 4267 Prim_Pos :=
a652dd51 4268 UI_To_Int (DT_Position (Interface_Alias (Prim)));
d00681a7 4269 Prim_Table (Prim_Pos) := Alias (Prim);
4270
cdb1c38f 4271 else
4272 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
725a69d2 4273
cdb1c38f 4274 if Present (Thunk_Id) then
d00681a7 4275 Prim_Pos :=
a652dd51 4276 UI_To_Int (DT_Position (Interface_Alias (Prim)));
cdb1c38f 4277
d00681a7 4278 Prim_Table (Prim_Pos) := Thunk_Id;
cdb1c38f 4279 Append_To (Result, Thunk_Code);
4280 end if;
725a69d2 4281 end if;
4282 end if;
4283
4284 Next_Elmt (Prim_Elmt);
4285 end loop;
4286
4287 for J in Prim_Table'Range loop
4288 if Present (Prim_Table (J)) then
4289 New_Node :=
cc60bd16 4290 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
acf97c11 4291 Make_Attribute_Reference (Loc,
83c6c069 4292 Prefix => New_Occurrence_Of (Prim_Table (J), Loc),
acf97c11 4293 Attribute_Name => Name_Unrestricted_Access));
d00681a7 4294
725a69d2 4295 else
cc60bd16 4296 New_Node := Make_Null (Loc);
725a69d2 4297 end if;
4298
4299 Append_To (Prim_Ops_Aggr_List, New_Node);
4300 end loop;
4301 end;
4302 end if;
4303
cc60bd16 4304 New_Node :=
725a69d2 4305 Make_Aggregate (Loc,
cc60bd16 4306 Expressions => Prim_Ops_Aggr_List);
4307
4308 Append_To (DT_Aggr_List, New_Node);
4309
4310 -- Remember aggregates initializing dispatch tables
4311
4312 Append_Elmt (New_Node, DT_Aggr);
725a69d2 4313
f301a57b 4314 -- Note: Secondary dispatch tables cannot be declared constant
4315 -- because the component Offset_To_Top is currently initialized
4316 -- by the IP routine.
4317
725a69d2 4318 Append_To (Result,
4319 Make_Object_Declaration (Loc,
4320 Defining_Identifier => Iface_DT,
4321 Aliased_Present => True,
f301a57b 4322 Constant_Present => False,
4323
725a69d2 4324 Object_Definition =>
4325 Make_Subtype_Indication (Loc,
83c6c069 4326 Subtype_Mark => New_Occurrence_Of
725a69d2 4327 (RTE (RE_Dispatch_Table_Wrapper), Loc),
4328 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4329 Constraints => DT_Constr_List)),
4330
f301a57b 4331 Expression =>
4332 Make_Aggregate (Loc,
4333 Expressions => DT_Aggr_List)));
725a69d2 4334
17e14451 4335 Append_To (Result,
4336 Make_Attribute_Definition_Clause (Loc,
83c6c069 4337 Name => New_Occurrence_Of (Iface_DT, Loc),
17e14451 4338 Chars => Name_Alignment,
f301a57b 4339
17e14451 4340 Expression =>
4341 Make_Attribute_Reference (Loc,
f301a57b 4342 Prefix =>
83c6c069 4343 New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
17e14451 4344 Attribute_Name => Name_Alignment)));
4345
f301a57b 4346 if Exporting_Table then
4347 Export_DT (Typ, Iface_DT, Suffix_Index);
4348
725a69d2 4349 -- Generate code to create the pointer to the dispatch table
4350
f301a57b 4351 -- Iface_DT_Ptr : Tag := Tag!(DT.Prims_Ptr'Address);
725a69d2 4352
f301a57b 4353 -- Note: This declaration is not added here if the table is exported
4354 -- because in such case Make_Tags has already added this declaration.
4355
4356 else
4357 Append_To (Result,
4358 Make_Object_Declaration (Loc,
4359 Defining_Identifier => Iface_DT_Ptr,
4360 Constant_Present => True,
4361
4362 Object_Definition =>
83c6c069 4363 New_Occurrence_Of (RTE (RE_Interface_Tag), Loc),
f301a57b 4364
4365 Expression =>
4366 Unchecked_Convert_To (RTE (RE_Interface_Tag),
4367 Make_Attribute_Reference (Loc,
4368 Prefix =>
4369 Make_Selected_Component (Loc,
83c6c069 4370 Prefix => New_Occurrence_Of (Iface_DT, Loc),
f301a57b 4371 Selector_Name =>
4372 New_Occurrence_Of
4373 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
4374 Attribute_Name => Name_Address))));
4375 end if;
725a69d2 4376
acf97c11 4377 Append_To (Result,
4378 Make_Object_Declaration (Loc,
4379 Defining_Identifier => Predef_Prims_Ptr,
4380 Constant_Present => True,
f301a57b 4381
4382 Object_Definition =>
83c6c069 4383 New_Occurrence_Of (RTE (RE_Address), Loc),
f301a57b 4384
4385 Expression =>
acf97c11 4386 Make_Attribute_Reference (Loc,
f301a57b 4387 Prefix =>
acf97c11 4388 Make_Selected_Component (Loc,
83c6c069 4389 Prefix => New_Occurrence_Of (Iface_DT, Loc),
f301a57b 4390 Selector_Name =>
4391 New_Occurrence_Of
4392 (RTE_Record_Component (RE_Predef_Prims), Loc)),
acf97c11 4393 Attribute_Name => Name_Address)));
4394
cc60bd16 4395 -- Remember entities containing dispatch tables
acf97c11 4396
cc60bd16 4397 Append_Elmt (Predef_Prims, DT_Decl);
4398 Append_Elmt (Iface_DT, DT_Decl);
725a69d2 4399 end Make_Secondary_DT;
4400
360b005f 4401 ---------------------
4402 -- Restore_Globals --
4403 ---------------------
4404
4405 procedure Restore_Globals is
4406 begin
4407 Ghost_Mode := GM;
4408 end Restore_Globals;
4409
725a69d2 4410 -- Local variables
4411
2ea346ac 4412 Elab_Code : constant List_Id := New_List;
4413 Result : constant List_Id := New_List;
4414 Tname : constant Name_Id := Chars (Typ);
725a69d2 4415 AI : Elmt_Id;
cdb1c38f 4416 AI_Tag_Elmt : Elmt_Id;
24971415 4417 AI_Tag_Comp : Elmt_Id;
f9162257 4418 DT_Aggr_List : List_Id;
24971415 4419 DT_Constr_List : List_Id;
725a69d2 4420 DT_Ptr : Entity_Id;
725a69d2 4421 ITable : Node_Id;
4422 I_Depth : Nat := 0;
4423 Iface_Table_Node : Node_Id;
4424 Name_ITable : Name_Id;
725a69d2 4425 Nb_Predef_Prims : Nat := 0;
4426 Nb_Prim : Nat := 0;
4427 New_Node : Node_Id;
725a69d2 4428 Num_Ifaces : Nat := 0;
cc60bd16 4429 Parent_Typ : Entity_Id;
725a69d2 4430 Prim : Entity_Id;
4431 Prim_Elmt : Elmt_Id;
4432 Prim_Ops_Aggr_List : List_Id;
725a69d2 4433 Suffix_Index : Int;
4434 Typ_Comps : Elist_Id;
4435 Typ_Ifaces : Elist_Id;
4436 TSD_Aggr_List : List_Id;
4437 TSD_Tags_List : List_Id;
17e14451 4438
4439 -- The following name entries are used by Make_DT to generate a number
4440 -- of entities related to a tagged type. These entities may be generated
4441 -- in a scope other than that of the tagged type declaration, and if
4442 -- the entities for two tagged types with the same name happen to be
4443 -- generated in the same scope, we have to take care to use different
4444 -- names. This is achieved by means of a unique serial number appended
4445 -- to each generated entity name.
4446
4447 Name_DT : constant Name_Id :=
4448 New_External_Name (Tname, 'T', Suffix_Index => -1);
4449 Name_Exname : constant Name_Id :=
4450 New_External_Name (Tname, 'E', Suffix_Index => -1);
e7e688dd 4451 Name_HT_Link : constant Name_Id :=
4452 New_External_Name (Tname, 'H', Suffix_Index => -1);
17e14451 4453 Name_Predef_Prims : constant Name_Id :=
4454 New_External_Name (Tname, 'R', Suffix_Index => -1);
4455 Name_SSD : constant Name_Id :=
4456 New_External_Name (Tname, 'S', Suffix_Index => -1);
4457 Name_TSD : constant Name_Id :=
4458 New_External_Name (Tname, 'B', Suffix_Index => -1);
4459
4460 -- Entities built with above names
4461
4462 DT : constant Entity_Id :=
4463 Make_Defining_Identifier (Loc, Name_DT);
4464 Exname : constant Entity_Id :=
4465 Make_Defining_Identifier (Loc, Name_Exname);
e7e688dd 4466 HT_Link : constant Entity_Id :=
4467 Make_Defining_Identifier (Loc, Name_HT_Link);
17e14451 4468 Predef_Prims : constant Entity_Id :=
4469 Make_Defining_Identifier (Loc, Name_Predef_Prims);
4470 SSD : constant Entity_Id :=
4471 Make_Defining_Identifier (Loc, Name_SSD);
4472 TSD : constant Entity_Id :=
4473 Make_Defining_Identifier (Loc, Name_TSD);
725a69d2 4474
4475 -- Start of processing for Make_DT
4476
4477 begin
17e14451 4478 pragma Assert (Is_Frozen (Typ));
725a69d2 4479
360b005f 4480 -- The tagged type for which the dispatch table is being build may be
4481 -- subject to pragma Ghost with policy Ignore. Set the mode now to
4482 -- ensure that any nodes generated during freezing are properly flagged
4483 -- as ignored Ghost.
4484
4485 Set_Ghost_Mode_For_Freeze (Typ, Typ);
4486
17e14451 4487 -- Handle cases in which there is no need to build the dispatch table
725a69d2 4488
17e14451 4489 if Has_Dispatch_Table (Typ)
4490 or else No (Access_Disp_Table (Typ))
4491 or else Is_CPP_Class (Typ)
b46aca2b 4492 or else Convention (Typ) = Convention_CIL
4493 or else Convention (Typ) = Convention_Java
17e14451 4494 then
360b005f 4495 Restore_Globals;
725a69d2 4496 return Result;
725a69d2 4497
17e14451 4498 elsif No_Run_Time_Mode then
4499 Error_Msg_CRT ("tagged types", Typ);
360b005f 4500 Restore_Globals;
17e14451 4501 return Result;
725a69d2 4502
17e14451 4503 elsif not RTE_Available (RE_Tag) then
725a69d2 4504 Append_To (Result,
4505 Make_Object_Declaration (Loc,
17e14451 4506 Defining_Identifier => Node (First_Elmt
4507 (Access_Disp_Table (Typ))),
83c6c069 4508 Object_Definition => New_Occurrence_Of (RTE (RE_Tag), Loc),
725a69d2 4509 Constant_Present => True,
4510 Expression =>
24971415 4511 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 4512 New_Occurrence_Of (RTE (RE_Null_Address), Loc))));
725a69d2 4513
4514 Analyze_List (Result, Suppress => All_Checks);
4515 Error_Msg_CRT ("tagged types", Typ);
360b005f 4516 Restore_Globals;
725a69d2 4517 return Result;
4518 end if;
4519
17e14451 4520 -- Ensure that the value of Max_Predef_Prims defined in a-tags is
208fd589 4521 -- correct. Valid values are 9 under configurable runtime or 15
17e14451 4522 -- with full runtime.
4523
4524 if RTE_Available (RE_Interface_Data) then
208fd589 4525 if Max_Predef_Prims /= 15 then
17e14451 4526 Error_Msg_N ("run-time library configuration error", Typ);
360b005f 4527 Restore_Globals;
17e14451 4528 return Result;
4529 end if;
725a69d2 4530 else
208fd589 4531 if Max_Predef_Prims /= 9 then
17e14451 4532 Error_Msg_N ("run-time library configuration error", Typ);
4533 Error_Msg_CRT ("tagged types", Typ);
360b005f 4534 Restore_Globals;
17e14451 4535 return Result;
4536 end if;
725a69d2 4537 end if;
4538
cc60bd16 4539 -- Initialize Parent_Typ handling private types
4540
4541 Parent_Typ := Etype (Typ);
4542
4543 if Present (Full_View (Parent_Typ)) then
4544 Parent_Typ := Full_View (Parent_Typ);
4545 end if;
4546
17e14451 4547 -- Ensure that all the primitives are frozen. This is only required when
4548 -- building static dispatch tables --- the primitives must be frozen to
4549 -- be referenced (otherwise we have problems with the backend). It is
4550 -- not a requirement with nonstatic dispatch tables because in this case
4551 -- we generate now an empty dispatch table; the extra code required to
24971415 4552 -- register the primitives in the slots will be generated later --- when
17e14451 4553 -- each primitive is frozen (see Freeze_Subprogram).
725a69d2 4554
d00681a7 4555 if Building_Static_DT (Typ) then
17e14451 4556 declare
4557 Save : constant Boolean := Freezing_Library_Level_Tagged_Type;
555c63a6 4558 Prim : Entity_Id;
17e14451 4559 Prim_Elmt : Elmt_Id;
4560 Frnodes : List_Id;
725a69d2 4561
17e14451 4562 begin
4563 Freezing_Library_Level_Tagged_Type := True;
555c63a6 4564
17e14451 4565 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4566 while Present (Prim_Elmt) loop
555c63a6 4567 Prim := Node (Prim_Elmt);
d74fc39a 4568 Frnodes := Freeze_Entity (Prim, Typ);
725a69d2 4569
17e14451 4570 declare
17e14451 4571 F : Entity_Id;
725a69d2 4572
17e14451 4573 begin
555c63a6 4574 F := First_Formal (Prim);
17e14451 4575 while Present (F) loop
349db231 4576 Check_Premature_Freezing (Prim, Typ, Etype (F));
17e14451 4577 Next_Formal (F);
4578 end loop;
4579
349db231 4580 Check_Premature_Freezing (Prim, Typ, Etype (Prim));
17e14451 4581 end;
4582
4583 if Present (Frnodes) then
4584 Append_List_To (Result, Frnodes);
4585 end if;
4586
4587 Next_Elmt (Prim_Elmt);
4588 end loop;
555c63a6 4589
17e14451 4590 Freezing_Library_Level_Tagged_Type := Save;
4591 end;
4592 end if;
725a69d2 4593
17e14451 4594 -- Ada 2005 (AI-251): Build the secondary dispatch tables
4595
a652dd51 4596 if Has_Interfaces (Typ) then
17e14451 4597 Collect_Interface_Components (Typ, Typ_Comps);
4598
f301a57b 4599 -- Each secondary dispatch table is assigned an unique positive
4600 -- suffix index; such value also corresponds with the location of
4601 -- its entity in the Dispatch_Table_Wrappers list (see Make_Tags).
4602
4603 -- Note: This value must be kept sync with the Suffix_Index values
4604 -- generated by Make_Tags
4605
4606 Suffix_Index := 1;
acf97c11 4607 AI_Tag_Elmt :=
4608 Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
17e14451 4609
4610 AI_Tag_Comp := First_Elmt (Typ_Comps);
4611 while Present (AI_Tag_Comp) loop
d00681a7 4612 pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'P'));
cdb1c38f 4613
4614 -- Build the secondary table containing pointers to thunks
4615
17e14451 4616 Make_Secondary_DT
02a2406d 4617 (Typ => Typ,
4618 Iface => Base_Type
4619 (Related_Type (Node (AI_Tag_Comp))),
4620 Suffix_Index => Suffix_Index,
4621 Num_Iface_Prims => UI_To_Int
4622 (DT_Entry_Count (Node (AI_Tag_Comp))),
4623 Iface_DT_Ptr => Node (AI_Tag_Elmt),
acf97c11 4624 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
02a2406d 4625 Build_Thunks => True,
4626 Result => Result);
cdb1c38f 4627
d00681a7 4628 -- Skip secondary dispatch table referencing thunks to predefined
4629 -- primitives.
acf97c11 4630
f301a57b 4631 Next_Elmt (AI_Tag_Elmt);
d00681a7 4632 pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'Y'));
4633
4634 -- Secondary dispatch table referencing user-defined primitives
4635 -- covered by this interface.
4636
acf97c11 4637 Next_Elmt (AI_Tag_Elmt);
d00681a7 4638 pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'D'));
acf97c11 4639
36b938a3 4640 -- Build the secondary table containing pointers to primitives
cdb1c38f 4641 -- (used to give support to Generic Dispatching Constructors).
4642
4643 Make_Secondary_DT
d00681a7 4644 (Typ => Typ,
4645 Iface => Base_Type
4646 (Related_Type (Node (AI_Tag_Comp))),
4647 Suffix_Index => -1,
4648 Num_Iface_Prims => UI_To_Int
4649 (DT_Entry_Count (Node (AI_Tag_Comp))),
4650 Iface_DT_Ptr => Node (AI_Tag_Elmt),
4651 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
4652 Build_Thunks => False,
4653 Result => Result);
4654
4655 -- Skip secondary dispatch table referencing predefined primitives
acf97c11 4656
f301a57b 4657 Next_Elmt (AI_Tag_Elmt);
d00681a7 4658 pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'Z'));
acf97c11 4659
17e14451 4660 Suffix_Index := Suffix_Index + 1;
d00681a7 4661 Next_Elmt (AI_Tag_Elmt);
17e14451 4662 Next_Elmt (AI_Tag_Comp);
4663 end loop;
4664 end if;
725a69d2 4665
c6a30f24 4666 -- Get the _tag entity and number of primitives of its dispatch table
725a69d2 4667
24971415 4668 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
4669 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
725a69d2 4670
2ea346ac 4671 Set_Is_Statically_Allocated (DT, Is_Library_Level_Tagged_Type (Typ));
4672 Set_Is_Statically_Allocated (SSD, Is_Library_Level_Tagged_Type (Typ));
4673 Set_Is_Statically_Allocated (TSD, Is_Library_Level_Tagged_Type (Typ));
4674 Set_Is_Statically_Allocated (Predef_Prims,
4675 Is_Library_Level_Tagged_Type (Typ));
725a69d2 4676
4677 -- In case of locally defined tagged type we declare the object
36b938a3 4678 -- containing the dispatch table by means of a variable. Its
725a69d2 4679 -- initialization is done later by means of an assignment. This is
4680 -- required to generate its External_Tag.
4681
24971415 4682 if not Building_Static_DT (Typ) then
725a69d2 4683
4684 -- Generate:
4685 -- DT : No_Dispatch_Table_Wrapper;
17e14451 4686 -- for DT'Alignment use Address'Alignment;
725a69d2 4687 -- DT_Ptr : Tag := !Tag (DT.NDT_Prims_Ptr'Address);
4688
24971415 4689 if not Has_DT (Typ) then
725a69d2 4690 Append_To (Result,
4691 Make_Object_Declaration (Loc,
4692 Defining_Identifier => DT,
4693 Aliased_Present => True,
4694 Constant_Present => False,
4695 Object_Definition =>
83c6c069 4696 New_Occurrence_Of
725a69d2 4697 (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
4698
17e14451 4699 Append_To (Result,
4700 Make_Attribute_Definition_Clause (Loc,
83c6c069 4701 Name => New_Occurrence_Of (DT, Loc),
17e14451 4702 Chars => Name_Alignment,
4703 Expression =>
4704 Make_Attribute_Reference (Loc,
02a2406d 4705 Prefix =>
83c6c069 4706 New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
17e14451 4707 Attribute_Name => Name_Alignment)));
4708
725a69d2 4709 Append_To (Result,
4710 Make_Object_Declaration (Loc,
4711 Defining_Identifier => DT_Ptr,
83c6c069 4712 Object_Definition => New_Occurrence_Of (RTE (RE_Tag), Loc),
725a69d2 4713 Constant_Present => True,
4714 Expression =>
24971415 4715 Unchecked_Convert_To (RTE (RE_Tag),
725a69d2 4716 Make_Attribute_Reference (Loc,
02a2406d 4717 Prefix =>
725a69d2 4718 Make_Selected_Component (Loc,
02a2406d 4719 Prefix => New_Occurrence_Of (DT, Loc),
4720 Selector_Name =>
4721 New_Occurrence_Of
4722 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
725a69d2 4723 Attribute_Name => Name_Address))));
4724
ff6293ec 4725 Set_Is_Statically_Allocated (DT_Ptr,
4726 Is_Library_Level_Tagged_Type (Typ));
4727
98045ff0 4728 -- Generate the SCIL node for the previous object declaration
4729 -- because it has a tag initialization.
4730
3dbca0d5 4731 if Generate_SCIL then
d215f619 4732 New_Node :=
4733 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
d215f619 4734 Set_SCIL_Entity (New_Node, Typ);
5a44b136 4735 Set_SCIL_Node (Last (Result), New_Node);
3dbca0d5 4736 end if;
4737
725a69d2 4738 -- Generate:
4739 -- DT : Dispatch_Table_Wrapper (Nb_Prim);
4740 -- for DT'Alignment use Address'Alignment;
4741 -- DT_Ptr : Tag := !Tag (DT.Prims_Ptr'Address);
4742
4743 else
4744 -- If the tagged type has no primitives we add a dummy slot
4745 -- whose address will be the tag of this type.
4746
4747 if Nb_Prim = 0 then
4748 DT_Constr_List :=
4749 New_List (Make_Integer_Literal (Loc, 1));
4750 else
4751 DT_Constr_List :=
4752 New_List (Make_Integer_Literal (Loc, Nb_Prim));
4753 end if;
4754
4755 Append_To (Result,
4756 Make_Object_Declaration (Loc,
4757 Defining_Identifier => DT,
4758 Aliased_Present => True,
4759 Constant_Present => False,
4760 Object_Definition =>
4761 Make_Subtype_Indication (Loc,
4762 Subtype_Mark =>
83c6c069 4763 New_Occurrence_Of (RTE (RE_Dispatch_Table_Wrapper), Loc),
02a2406d 4764 Constraint =>
4765 Make_Index_Or_Discriminant_Constraint (Loc,
4766 Constraints => DT_Constr_List))));
725a69d2 4767
4768 Append_To (Result,
4769 Make_Attribute_Definition_Clause (Loc,
83c6c069 4770 Name => New_Occurrence_Of (DT, Loc),
725a69d2 4771 Chars => Name_Alignment,
4772 Expression =>
4773 Make_Attribute_Reference (Loc,
02a2406d 4774 Prefix =>
83c6c069 4775 New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
725a69d2 4776 Attribute_Name => Name_Alignment)));
4777
4778 Append_To (Result,
4779 Make_Object_Declaration (Loc,
4780 Defining_Identifier => DT_Ptr,
83c6c069 4781 Object_Definition => New_Occurrence_Of (RTE (RE_Tag), Loc),
725a69d2 4782 Constant_Present => True,
4783 Expression =>
24971415 4784 Unchecked_Convert_To (RTE (RE_Tag),
725a69d2 4785 Make_Attribute_Reference (Loc,
02a2406d 4786 Prefix =>
725a69d2 4787 Make_Selected_Component (Loc,
02a2406d 4788 Prefix => New_Occurrence_Of (DT, Loc),
4789 Selector_Name =>
4790 New_Occurrence_Of
4791 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
725a69d2 4792 Attribute_Name => Name_Address))));
acf97c11 4793
ff6293ec 4794 Set_Is_Statically_Allocated (DT_Ptr,
4795 Is_Library_Level_Tagged_Type (Typ));
4796
98045ff0 4797 -- Generate the SCIL node for the previous object declaration
4798 -- because it has a tag initialization.
9af28f61 4799
3dbca0d5 4800 if Generate_SCIL then
d215f619 4801 New_Node :=
4802 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
d215f619 4803 Set_SCIL_Entity (New_Node, Typ);
5a44b136 4804 Set_SCIL_Node (Last (Result), New_Node);
3dbca0d5 4805 end if;
4806
acf97c11 4807 Append_To (Result,
4808 Make_Object_Declaration (Loc,
4809 Defining_Identifier =>
4810 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Typ)))),
4811 Constant_Present => True,
02a2406d 4812 Object_Definition =>
4813 New_Occurrence_Of (RTE (RE_Address), Loc),
acf97c11 4814 Expression =>
4815 Make_Attribute_Reference (Loc,
02a2406d 4816 Prefix =>
acf97c11 4817 Make_Selected_Component (Loc,
02a2406d 4818 Prefix => New_Occurrence_Of (DT, Loc),
4819 Selector_Name =>
4820 New_Occurrence_Of
4821 (RTE_Record_Component (RE_Predef_Prims), Loc)),
acf97c11 4822 Attribute_Name => Name_Address)));
725a69d2 4823 end if;
4824 end if;
4825
4826 -- Generate: Exname : constant String := full_qualified_name (typ);
343d35dc 4827 -- The type itself may be an anonymous parent type, so use the first
4828 -- subtype to have a user-recognizable name.
d62940bf 4829
343d35dc 4830 Append_To (Result,
4831 Make_Object_Declaration (Loc,
4832 Defining_Identifier => Exname,
4833 Constant_Present => True,
83c6c069 4834 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
343d35dc 4835 Expression =>
4836 Make_String_Literal (Loc,
02a2406d 4837 Strval => Fully_Qualified_Name_String (First_Subtype (Typ)))));
24971415 4838 Set_Is_Statically_Allocated (Exname);
4839 Set_Is_True_Constant (Exname);
4840
e7e688dd 4841 -- Declare the object used by Ada.Tags.Register_Tag
4842
4843 if RTE_Available (RE_Register_Tag) then
4844 Append_To (Result,
4845 Make_Object_Declaration (Loc,
4846 Defining_Identifier => HT_Link,
83c6c069 4847 Object_Definition => New_Occurrence_Of (RTE (RE_Tag), Loc)));
e7e688dd 4848 end if;
4849
725a69d2 4850 -- Generate code to create the storage for the type specific data object
4851 -- with enough space to store the tags of the ancestors plus the tags
4852 -- of all the implemented interfaces (as described in a-tags.adb).
4853
4854 -- TSD : Type_Specific_Data (I_Depth) :=
4855 -- (Idepth => I_Depth,
4856 -- Access_Level => Type_Access_Level (Typ),
208fd589 4857 -- Alignment => Typ'Alignment,
725a69d2 4858 -- Expanded_Name => Cstring_Ptr!(Exname'Address))
4859 -- External_Tag => Cstring_Ptr!(Exname'Address))
e7e688dd 4860 -- HT_Link => HT_Link'Address,
725a69d2 4861 -- Transportable => <<boolean-value>>,
3568e554 4862 -- Type_Is_Abstract => <<boolean-value>>,
bb3b440a 4863 -- Needs_Finalization => <<boolean-value>>,
693b0822 4864 -- [ Size_Func => Size_Prim'Access, ]
4865 -- [ Interfaces_Table => <<access-value>>, ]
24971415 4866 -- [ SSD => SSD_Table'Address ]
725a69d2 4867 -- Tags_Table => (0 => null,
4868 -- 1 => Parent'Tag
4869 -- ...);
4870 -- for TSD'Alignment use Address'Alignment
4871
4872 TSD_Aggr_List := New_List;
4873
4874 -- Idepth: Count ancestors to compute the inheritance depth. For private
4875 -- extensions, always go to the full view in order to compute the real
4876 -- inheritance depth.
4877
4878 declare
4879 Current_Typ : Entity_Id;
4880 Parent_Typ : Entity_Id;
4881
4882 begin
4883 I_Depth := 0;
4884 Current_Typ := Typ;
4885 loop
4886 Parent_Typ := Etype (Current_Typ);
4887
4888 if Is_Private_Type (Parent_Typ) then
4889 Parent_Typ := Full_View (Base_Type (Parent_Typ));
4890 end if;
4891
4892 exit when Parent_Typ = Current_Typ;
4893
4894 I_Depth := I_Depth + 1;
4895 Current_Typ := Parent_Typ;
4896 end loop;
4897 end;
4898
4899 Append_To (TSD_Aggr_List,
17e14451 4900 Make_Integer_Literal (Loc, I_Depth));
725a69d2 4901
4902 -- Access_Level
4903
4904 Append_To (TSD_Aggr_List,
17e14451 4905 Make_Integer_Literal (Loc, Type_Access_Level (Typ)));
725a69d2 4906
208fd589 4907 -- Alignment
4908
4909 -- For CPP types we cannot rely on the value of 'Alignment provided
4910 -- by the backend to initialize this TSD field.
4911
4912 if Convention (Typ) = Convention_CPP
4913 or else Is_CPP_Class (Root_Type (Typ))
4914 then
4915 Append_To (TSD_Aggr_List,
4916 Make_Integer_Literal (Loc, 0));
4917 else
4918 Append_To (TSD_Aggr_List,
4919 Make_Attribute_Reference (Loc,
02a2406d 4920 Prefix => New_Occurrence_Of (Typ, Loc),
208fd589 4921 Attribute_Name => Name_Alignment));
4922 end if;
4923
725a69d2 4924 -- Expanded_Name
4925
4926 Append_To (TSD_Aggr_List,
17e14451 4927 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4928 Make_Attribute_Reference (Loc,
83c6c069 4929 Prefix => New_Occurrence_Of (Exname, Loc),
17e14451 4930 Attribute_Name => Name_Address)));
725a69d2 4931
4932 -- External_Tag of a local tagged type
4933
17e14451 4934 -- <typ>A : constant String :=
725a69d2 4935 -- "Internal tag at 16#tag-addr#: <full-name-of-typ>";
4936
4937 -- The reason we generate this strange name is that we do not want to
4938 -- enter local tagged types in the global hash table used to compute
4939 -- the Internal_Tag attribute for two reasons:
4940
4941 -- 1. It is hard to avoid a tasking race condition for entering the
4942 -- entry into the hash table.
4943
4944 -- 2. It would cause a storage leak, unless we rig up considerable
4945 -- mechanism to remove the entry from the hash table on exit.
4946
4947 -- So what we do is to generate the above external tag name, where the
4948 -- hex address is the address of the local dispatch table (i.e. exactly
4949 -- the value we want if Internal_Tag is computed from this string).
4950
4951 -- Of course this value will only be valid if the tagged type is still
4952 -- in scope, but it clearly must be erroneous to compute the internal
39a0c1d3 4953 -- tag of a tagged type that is out of scope.
725a69d2 4954
17e14451 4955 -- We don't do this processing if an explicit external tag has been
4956 -- specified. That's an odd case for which we have already issued a
4957 -- warning, where we will not be able to compute the internal tag.
4958
4959 if not Is_Library_Level_Entity (Typ)
4960 and then not Has_External_Tag_Rep_Clause (Typ)
4961 then
725a69d2 4962 declare
02a2406d 4963 Exname : constant Entity_Id :=
4964 Make_Defining_Identifier (Loc,
4965 Chars => New_External_Name (Tname, 'A'));
4966 Full_Name : constant String_Id :=
c6a30f24 4967 Fully_Qualified_Name_String (First_Subtype (Typ));
02a2406d 4968 Str1_Id : String_Id;
4969 Str2_Id : String_Id;
725a69d2 4970
4971 begin
4972 -- Generate:
17e14451 4973 -- Str1 = "Internal tag at 16#";
725a69d2 4974
4975 Start_String;
4976 Store_String_Chars ("Internal tag at 16#");
4977 Str1_Id := End_String;
4978
4979 -- Generate:
17e14451 4980 -- Str2 = "#: <type-full-name>";
725a69d2 4981
4982 Start_String;
4983 Store_String_Chars ("#: ");
725a69d2 4984 Store_String_Chars (Full_Name);
17e14451 4985 Str2_Id := End_String;
725a69d2 4986
4987 -- Generate:
4988 -- Exname : constant String :=
17e14451 4989 -- Str1 & Address_Image (Tag) & Str2;
725a69d2 4990
4991 if RTE_Available (RE_Address_Image) then
4992 Append_To (Result,
4993 Make_Object_Declaration (Loc,
4994 Defining_Identifier => Exname,
4995 Constant_Present => True,
83c6c069 4996 Object_Definition => New_Occurrence_Of
725a69d2 4997 (Standard_String, Loc),
4998 Expression =>
4999 Make_Op_Concat (Loc,
02a2406d 5000 Left_Opnd => Make_String_Literal (Loc, Str1_Id),
725a69d2 5001 Right_Opnd =>
5002 Make_Op_Concat (Loc,
02a2406d 5003 Left_Opnd =>
725a69d2 5004 Make_Function_Call (Loc,
5005 Name =>
83c6c069 5006 New_Occurrence_Of
725a69d2 5007 (RTE (RE_Address_Image), Loc),
5008 Parameter_Associations => New_List (
5009 Unchecked_Convert_To (RTE (RE_Address),
83c6c069 5010 New_Occurrence_Of (DT_Ptr, Loc)))),
725a69d2 5011 Right_Opnd =>
17e14451 5012 Make_String_Literal (Loc, Str2_Id)))));
5013
725a69d2 5014 else
5015 Append_To (Result,
5016 Make_Object_Declaration (Loc,
5017 Defining_Identifier => Exname,
5018 Constant_Present => True,
02a2406d 5019 Object_Definition =>
5020 New_Occurrence_Of (Standard_String, Loc),
5021 Expression =>
725a69d2 5022 Make_Op_Concat (Loc,
02a2406d 5023 Left_Opnd => Make_String_Literal (Loc, Str1_Id),
5024 Right_Opnd => Make_String_Literal (Loc, Str2_Id))));
725a69d2 5025 end if;
5026
5027 New_Node :=
5028 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
5029 Make_Attribute_Reference (Loc,
02a2406d 5030 Prefix => New_Occurrence_Of (Exname, Loc),
725a69d2 5031 Attribute_Name => Name_Address));
5032 end;
5033
5034 -- External tag of a library-level tagged type: Check for a definition
5035 -- of External_Tag. The clause is considered only if it applies to this
5036 -- specific tagged type, as opposed to one of its ancestors.
cc60bd16 5037 -- If the type is an unconstrained type extension, we are building the
5038 -- dispatch table of its anonymous base type, so the external tag, if
34fd8639 5039 -- any was specified, must be retrieved from the first subtype. Go to
5040 -- the full view in case the clause is in the private part.
725a69d2 5041
5042 else
5043 declare
cc60bd16 5044 Def : constant Node_Id := Get_Attribute_Definition_Clause
34fd8639 5045 (Underlying_Type (First_Subtype (Typ)),
cc60bd16 5046 Attribute_External_Tag);
5047
725a69d2 5048 Old_Val : String_Id;
5049 New_Val : String_Id;
5050 E : Entity_Id;
5051
5052 begin
5053 if not Present (Def)
cc60bd16 5054 or else Entity (Name (Def)) /= First_Subtype (Typ)
725a69d2 5055 then
5056 New_Node :=
5057 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
5058 Make_Attribute_Reference (Loc,
83c6c069 5059 Prefix => New_Occurrence_Of (Exname, Loc),
725a69d2 5060 Attribute_Name => Name_Address));
5061 else
5062 Old_Val := Strval (Expr_Value_S (Expression (Def)));
5063
17e14451 5064 -- For the rep clause "for <typ>'external_tag use y" generate:
725a69d2 5065
17e14451 5066 -- <typ>A : constant string := y;
5067 --
5068 -- <typ>A'Address is used to set the External_Tag component
5069 -- of the TSD
725a69d2 5070
5071 -- Create a new nul terminated string if it is not already
5072
5073 if String_Length (Old_Val) > 0
5074 and then
5075 Get_String_Char (Old_Val, String_Length (Old_Val)) = 0
5076 then
5077 New_Val := Old_Val;
5078 else
5079 Start_String (Old_Val);
5080 Store_String_Char (Get_Char_Code (ASCII.NUL));
5081 New_Val := End_String;
5082 end if;
5083
5084 E := Make_Defining_Identifier (Loc,
5085 New_External_Name (Chars (Typ), 'A'));
5086
5087 Append_To (Result,
5088 Make_Object_Declaration (Loc,
5089 Defining_Identifier => E,
5090 Constant_Present => True,
5091 Object_Definition =>
83c6c069 5092 New_Occurrence_Of (Standard_String, Loc),
725a69d2 5093 Expression =>
5094 Make_String_Literal (Loc, New_Val)));
5095
5096 New_Node :=
5097 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
5098 Make_Attribute_Reference (Loc,
02a2406d 5099 Prefix => New_Occurrence_Of (E, Loc),
725a69d2 5100 Attribute_Name => Name_Address));
5101 end if;
5102 end;
5103 end if;
5104
17e14451 5105 Append_To (TSD_Aggr_List, New_Node);
725a69d2 5106
5107 -- HT_Link
5108
e7e688dd 5109 if RTE_Available (RE_Register_Tag) then
5110 Append_To (TSD_Aggr_List,
5111 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
5112 Make_Attribute_Reference (Loc,
02a2406d 5113 Prefix => New_Occurrence_Of (HT_Link, Loc),
e7e688dd 5114 Attribute_Name => Name_Address)));
5115 else
5116 Append_To (TSD_Aggr_List,
5117 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
83c6c069 5118 New_Occurrence_Of (RTE (RE_Null_Address), Loc)));
e7e688dd 5119 end if;
725a69d2 5120
5121 -- Transportable: Set for types that can be used in remote calls
5122 -- with respect to E.4(18) legality rules.
5123
17e14451 5124 declare
5125 Transportable : Entity_Id;
725a69d2 5126
17e14451 5127 begin
5128 Transportable :=
5129 Boolean_Literals
5130 (Is_Pure (Typ)
5131 or else Is_Shared_Passive (Typ)
5132 or else
5133 ((Is_Remote_Types (Typ)
02a2406d 5134 or else Is_Remote_Call_Interface (Typ))
17e14451 5135 and then Original_View_In_Visible_Part (Typ))
5136 or else not Comes_From_Source (Typ));
5137
5138 Append_To (TSD_Aggr_List,
5139 New_Occurrence_Of (Transportable, Loc));
5140 end;
725a69d2 5141
3568e554 5142 -- Type_Is_Abstract (Ada 2012: AI05-0173). This functionality is
5143 -- not available in the HIE runtime.
5144
5145 if RTE_Record_Component_Available (RE_Type_Is_Abstract) then
5146 declare
5147 Type_Is_Abstract : Entity_Id;
3568e554 5148 begin
02a2406d 5149 Type_Is_Abstract := Boolean_Literals (Is_Abstract_Type (Typ));
3568e554 5150 Append_To (TSD_Aggr_List,
02a2406d 5151 New_Occurrence_Of (Type_Is_Abstract, Loc));
3568e554 5152 end;
5153 end if;
5154
bb3b440a 5155 -- Needs_Finalization: Set if the type is controlled or has controlled
5156 -- components.
952af0b9 5157
17e14451 5158 declare
bb3b440a 5159 Needs_Fin : Entity_Id;
17e14451 5160 begin
bb3b440a 5161 Needs_Fin := Boolean_Literals (Needs_Finalization (Typ));
5162 Append_To (TSD_Aggr_List, New_Occurrence_Of (Needs_Fin, Loc));
17e14451 5163 end;
725a69d2 5164
cc60bd16 5165 -- Size_Func
5166
5167 if RTE_Record_Component_Available (RE_Size_Func) then
925c2ba1 5168
5169 -- Initialize this field to Null_Address if we are not building
5170 -- static dispatch tables static or if the size function is not
5171 -- available. In the former case we cannot initialize this field
5172 -- until the function is frozen and registered in the dispatch
5173 -- table (see Register_Primitive).
5174
5175 if not Building_Static_DT (Typ) or else not Has_DT (Typ) then
cc60bd16 5176 Append_To (TSD_Aggr_List,
5177 Unchecked_Convert_To (RTE (RE_Size_Ptr),
83c6c069 5178 New_Occurrence_Of (RTE (RE_Null_Address), Loc)));
cc60bd16 5179
5180 else
5181 declare
5182 Prim_Elmt : Elmt_Id;
5183 Prim : Entity_Id;
fa6a6949 5184 Size_Comp : Node_Id;
cc60bd16 5185
5186 begin
5187 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5188 while Present (Prim_Elmt) loop
5189 Prim := Node (Prim_Elmt);
5190
5191 if Chars (Prim) = Name_uSize then
fc2907f6 5192 Prim := Ultimate_Alias (Prim);
cc60bd16 5193
5194 if Is_Abstract_Subprogram (Prim) then
fa6a6949 5195 Size_Comp :=
cc60bd16 5196 Unchecked_Convert_To (RTE (RE_Size_Ptr),
83c6c069 5197 New_Occurrence_Of (RTE (RE_Null_Address), Loc));
cc60bd16 5198 else
fa6a6949 5199 Size_Comp :=
cc60bd16 5200 Unchecked_Convert_To (RTE (RE_Size_Ptr),
5201 Make_Attribute_Reference (Loc,
02a2406d 5202 Prefix => New_Occurrence_Of (Prim, Loc),
fa6a6949 5203 Attribute_Name => Name_Unrestricted_Access));
cc60bd16 5204 end if;
5205
5206 exit;
5207 end if;
5208
5209 Next_Elmt (Prim_Elmt);
5210 end loop;
fa6a6949 5211
5212 pragma Assert (Present (Size_Comp));
5213 Append_To (TSD_Aggr_List, Size_Comp);
cc60bd16 5214 end;
5215 end if;
5216 end if;
5217
725a69d2 5218 -- Interfaces_Table (required for AI-405)
5219
5220 if RTE_Record_Component_Available (RE_Interfaces_Table) then
5221
5222 -- Count the number of interface types implemented by Typ
5223
a652dd51 5224 Collect_Interfaces (Typ, Typ_Ifaces);
725a69d2 5225
5226 AI := First_Elmt (Typ_Ifaces);
5227 while Present (AI) loop
5228 Num_Ifaces := Num_Ifaces + 1;
5229 Next_Elmt (AI);
5230 end loop;
952af0b9 5231
343d35dc 5232 if Num_Ifaces = 0 then
725a69d2 5233 Iface_Table_Node := Make_Null (Loc);
952af0b9 5234
725a69d2 5235 -- Generate the Interface_Table object
343d35dc 5236
5237 else
725a69d2 5238 declare
17e14451 5239 TSD_Ifaces_List : constant List_Id := New_List;
cdb1c38f 5240 Elmt : Elmt_Id;
5241 Sec_DT_Tag : Node_Id;
725a69d2 5242
5243 begin
5244 AI := First_Elmt (Typ_Ifaces);
5245 while Present (AI) loop
cb4af01d 5246 if Is_Ancestor (Node (AI), Typ, Use_Full_View => True) then
cdb1c38f 5247 Sec_DT_Tag :=
83c6c069 5248 New_Occurrence_Of (DT_Ptr, Loc);
cdb1c38f 5249 else
acf97c11 5250 Elmt :=
5251 Next_Elmt
5252 (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
cdb1c38f 5253 pragma Assert (Has_Thunks (Node (Elmt)));
5254
d00681a7 5255 while Is_Tag (Node (Elmt))
cdb1c38f 5256 and then not
cb4af01d 5257 Is_Ancestor (Node (AI), Related_Type (Node (Elmt)),
5258 Use_Full_View => True)
cdb1c38f 5259 loop
5260 pragma Assert (Has_Thunks (Node (Elmt)));
5261 Next_Elmt (Elmt);
acf97c11 5262 pragma Assert (Has_Thunks (Node (Elmt)));
5263 Next_Elmt (Elmt);
5264 pragma Assert (not Has_Thunks (Node (Elmt)));
5265 Next_Elmt (Elmt);
cdb1c38f 5266 pragma Assert (not Has_Thunks (Node (Elmt)));
5267 Next_Elmt (Elmt);
5268 end loop;
5269
5270 pragma Assert (Ekind (Node (Elmt)) = E_Constant
acf97c11 5271 and then not
5272 Has_Thunks (Node (Next_Elmt (Next_Elmt (Elmt)))));
cdb1c38f 5273 Sec_DT_Tag :=
83c6c069 5274 New_Occurrence_Of (Node (Next_Elmt (Next_Elmt (Elmt))),
acf97c11 5275 Loc);
cdb1c38f 5276 end if;
5277
17e14451 5278 Append_To (TSD_Ifaces_List,
5279 Make_Aggregate (Loc,
5280 Expressions => New_List (
5281
5282 -- Iface_Tag
5283
24971415 5284 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 5285 New_Occurrence_Of
725a69d2 5286 (Node (First_Elmt (Access_Disp_Table (Node (AI)))),
17e14451 5287 Loc)),
725a69d2 5288
17e14451 5289 -- Static_Offset_To_Top
725a69d2 5290
83c6c069 5291 New_Occurrence_Of (Standard_True, Loc),
725a69d2 5292
17e14451 5293 -- Offset_To_Top_Value
5294
5295 Make_Integer_Literal (Loc, 0),
5296
5297 -- Offset_To_Top_Func
5298
cdb1c38f 5299 Make_Null (Loc),
5300
5301 -- Secondary_DT
5302
5303 Unchecked_Convert_To (RTE (RE_Tag), Sec_DT_Tag)
5304
5305 )));
725a69d2 5306
725a69d2 5307 Next_Elmt (AI);
5308 end loop;
725a69d2 5309
17e14451 5310 Name_ITable := New_External_Name (Tname, 'I');
5311 ITable := Make_Defining_Identifier (Loc, Name_ITable);
2ea346ac 5312 Set_Is_Statically_Allocated (ITable,
5313 Is_Library_Level_Tagged_Type (Typ));
725a69d2 5314
17e14451 5315 -- The table of interfaces is not constant; its slots are
0c826ed4 5316 -- filled at run time by the IP routine using attribute
17e14451 5317 -- 'Position to know the location of the tag components
5318 -- (and this attribute cannot be safely used before the
5319 -- object is initialized).
725a69d2 5320
17e14451 5321 Append_To (Result,
5322 Make_Object_Declaration (Loc,
5323 Defining_Identifier => ITable,
5324 Aliased_Present => True,
5325 Constant_Present => False,
5326 Object_Definition =>
5327 Make_Subtype_Indication (Loc,
5328 Subtype_Mark =>
83c6c069 5329 New_Occurrence_Of (RTE (RE_Interface_Data), Loc),
02a2406d 5330 Constraint =>
5331 Make_Index_Or_Discriminant_Constraint (Loc,
5332 Constraints => New_List (
5333 Make_Integer_Literal (Loc, Num_Ifaces)))),
725a69d2 5334
02a2406d 5335 Expression => Make_Aggregate (Loc,
17e14451 5336 Expressions => New_List (
5337 Make_Integer_Literal (Loc, Num_Ifaces),
02a2406d 5338 Make_Aggregate (Loc, TSD_Ifaces_List)))));
725a69d2 5339
17e14451 5340 Append_To (Result,
5341 Make_Attribute_Definition_Clause (Loc,
83c6c069 5342 Name => New_Occurrence_Of (ITable, Loc),
17e14451 5343 Chars => Name_Alignment,
5344 Expression =>
5345 Make_Attribute_Reference (Loc,
02a2406d 5346 Prefix =>
83c6c069 5347 New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
17e14451 5348 Attribute_Name => Name_Alignment)));
725a69d2 5349
17e14451 5350 Iface_Table_Node :=
5351 Make_Attribute_Reference (Loc,
83c6c069 5352 Prefix => New_Occurrence_Of (ITable, Loc),
17e14451 5353 Attribute_Name => Name_Unchecked_Access);
5354 end;
725a69d2 5355 end if;
5356
17e14451 5357 Append_To (TSD_Aggr_List, Iface_Table_Node);
725a69d2 5358 end if;
5359
5360 -- Generate the Select Specific Data table for synchronized types that
5361 -- implement synchronized interfaces. The size of the table is
5362 -- constrained by the number of non-predefined primitive operations.
5363
5364 if RTE_Record_Component_Available (RE_SSD) then
de54c5ab 5365 if Ada_Version >= Ada_2005
24971415 5366 and then Has_DT (Typ)
725a69d2 5367 and then Is_Concurrent_Record_Type (Typ)
a652dd51 5368 and then Has_Interfaces (Typ)
725a69d2 5369 and then Nb_Prim > 0
5370 and then not Is_Abstract_Type (Typ)
5371 and then not Is_Controlled (Typ)
5372 and then not Restriction_Active (No_Dispatching_Calls)
f38c8084 5373 and then not Restriction_Active (No_Select_Statements)
725a69d2 5374 then
343d35dc 5375 Append_To (Result,
5376 Make_Object_Declaration (Loc,
725a69d2 5377 Defining_Identifier => SSD,
343d35dc 5378 Aliased_Present => True,
5379 Object_Definition =>
5380 Make_Subtype_Indication (Loc,
83c6c069 5381 Subtype_Mark => New_Occurrence_Of (
725a69d2 5382 RTE (RE_Select_Specific_Data), Loc),
5383 Constraint =>
5384 Make_Index_Or_Discriminant_Constraint (Loc,
5385 Constraints => New_List (
5386 Make_Integer_Literal (Loc, Nb_Prim))))));
5387
17e14451 5388 Append_To (Result,
5389 Make_Attribute_Definition_Clause (Loc,
83c6c069 5390 Name => New_Occurrence_Of (SSD, Loc),
17e14451 5391 Chars => Name_Alignment,
5392 Expression =>
5393 Make_Attribute_Reference (Loc,
02a2406d 5394 Prefix =>
83c6c069 5395 New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
17e14451 5396 Attribute_Name => Name_Alignment)));
5397
725a69d2 5398 -- This table is initialized by Make_Select_Specific_Data_Table,
5399 -- which calls Set_Entry_Index and Set_Prim_Op_Kind.
5400
5401 Append_To (TSD_Aggr_List,
17e14451 5402 Make_Attribute_Reference (Loc,
02a2406d 5403 Prefix => New_Occurrence_Of (SSD, Loc),
17e14451 5404 Attribute_Name => Name_Unchecked_Access));
725a69d2 5405 else
17e14451 5406 Append_To (TSD_Aggr_List, Make_Null (Loc));
343d35dc 5407 end if;
952af0b9 5408 end if;
5409
725a69d2 5410 -- Initialize the table of ancestor tags. In case of interface types
5411 -- this table is not needed.
d62940bf 5412
cc60bd16 5413 TSD_Tags_List := New_List;
952af0b9 5414
cc60bd16 5415 -- If we are not statically allocating the dispatch table then we must
5416 -- fill position 0 with null because we still have not generated the
5417 -- tag of Typ.
343d35dc 5418
cc60bd16 5419 if not Building_Static_DT (Typ)
5420 or else Is_Interface (Typ)
5421 then
5422 Append_To (TSD_Tags_List,
5423 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 5424 New_Occurrence_Of (RTE (RE_Null_Address), Loc)));
343d35dc 5425
cc60bd16 5426 -- Otherwise we can safely reference the tag
343d35dc 5427
cc60bd16 5428 else
5429 Append_To (TSD_Tags_List,
83c6c069 5430 New_Occurrence_Of (DT_Ptr, Loc));
cc60bd16 5431 end if;
343d35dc 5432
cc60bd16 5433 -- Fill the rest of the table with the tags of the ancestors
343d35dc 5434
cc60bd16 5435 declare
5436 Current_Typ : Entity_Id;
5437 Parent_Typ : Entity_Id;
5438 Pos : Nat;
725a69d2 5439
cc60bd16 5440 begin
17e14451 5441 Pos := 1;
5442 Current_Typ := Typ;
725a69d2 5443
17e14451 5444 loop
5445 Parent_Typ := Etype (Current_Typ);
343d35dc 5446
17e14451 5447 if Is_Private_Type (Parent_Typ) then
5448 Parent_Typ := Full_View (Base_Type (Parent_Typ));
5449 end if;
5450
5451 exit when Parent_Typ = Current_Typ;
5452
7ac0f4a5 5453 if Is_CPP_Class (Parent_Typ) then
5454
17e14451 5455 -- The tags defined in the C++ side will be inherited when
5456 -- the object is constructed (Exp_Ch3.Build_Init_Procedure)
5457
5458 Append_To (TSD_Tags_List,
5459 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 5460 New_Occurrence_Of (RTE (RE_Null_Address), Loc)));
17e14451 5461 else
5462 Append_To (TSD_Tags_List,
83c6c069 5463 New_Occurrence_Of
17e14451 5464 (Node (First_Elmt (Access_Disp_Table (Parent_Typ))),
5465 Loc));
5466 end if;
5467
5468 Pos := Pos + 1;
5469 Current_Typ := Parent_Typ;
5470 end loop;
5471
5472 pragma Assert (Pos = I_Depth + 1);
5473 end;
5474
5475 Append_To (TSD_Aggr_List,
5476 Make_Aggregate (Loc,
5477 Expressions => TSD_Tags_List));
343d35dc 5478
725a69d2 5479 -- Build the TSD object
343d35dc 5480
5481 Append_To (Result,
5482 Make_Object_Declaration (Loc,
5483 Defining_Identifier => TSD,
5484 Aliased_Present => True,
24971415 5485 Constant_Present => Building_Static_DT (Typ),
343d35dc 5486 Object_Definition =>
5487 Make_Subtype_Indication (Loc,
83c6c069 5488 Subtype_Mark => New_Occurrence_Of (
343d35dc 5489 RTE (RE_Type_Specific_Data), Loc),
5490 Constraint =>
5491 Make_Index_Or_Discriminant_Constraint (Loc,
5492 Constraints => New_List (
5493 Make_Integer_Literal (Loc, I_Depth)))),
725a69d2 5494
343d35dc 5495 Expression => Make_Aggregate (Loc,
17e14451 5496 Expressions => TSD_Aggr_List)));
343d35dc 5497
24971415 5498 Set_Is_True_Constant (TSD, Building_Static_DT (Typ));
5499
343d35dc 5500 Append_To (Result,
5501 Make_Attribute_Definition_Clause (Loc,
83c6c069 5502 Name => New_Occurrence_Of (TSD, Loc),
343d35dc 5503 Chars => Name_Alignment,
5504 Expression =>
5505 Make_Attribute_Reference (Loc,
02a2406d 5506 Prefix =>
5507 New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
343d35dc 5508 Attribute_Name => Name_Alignment)));
5509
24971415 5510 -- Initialize or declare the dispatch table object
343d35dc 5511
24971415 5512 if not Has_DT (Typ) then
725a69d2 5513 DT_Constr_List := New_List;
5514 DT_Aggr_List := New_List;
343d35dc 5515
725a69d2 5516 -- Typeinfo
952af0b9 5517
725a69d2 5518 New_Node :=
5519 Make_Attribute_Reference (Loc,
02a2406d 5520 Prefix => New_Occurrence_Of (TSD, Loc),
725a69d2 5521 Attribute_Name => Name_Address);
5522
5523 Append_To (DT_Constr_List, New_Node);
5524 Append_To (DT_Aggr_List, New_Copy (New_Node));
5525 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
5526
5527 -- In case of locally defined tagged types we have already declared
5528 -- and uninitialized object for the dispatch table, which is now
24971415 5529 -- initialized by means of the following assignment:
5530
5531 -- DT := (TSD'Address, 0);
725a69d2 5532
24971415 5533 if not Building_Static_DT (Typ) then
725a69d2 5534 Append_To (Result,
5535 Make_Assignment_Statement (Loc,
02a2406d 5536 Name => New_Occurrence_Of (DT, Loc),
5537 Expression => Make_Aggregate (Loc, DT_Aggr_List)));
725a69d2 5538
24971415 5539 -- In case of library level tagged types we declare and export now
5540 -- the constant object containing the dummy dispatch table. There
5541 -- is no need to declare the tag here because it has been previously
5542 -- declared by Make_Tags
5543
5544 -- DT : aliased constant No_Dispatch_Table :=
5545 -- (NDT_TSD => TSD'Address;
5546 -- NDT_Prims_Ptr => 0);
5547 -- for DT'Alignment use Address'Alignment;
725a69d2 5548
5549 else
5550 Append_To (Result,
5551 Make_Object_Declaration (Loc,
5552 Defining_Identifier => DT,
5553 Aliased_Present => True,
17e14451 5554 Constant_Present => True,
725a69d2 5555 Object_Definition =>
83c6c069 5556 New_Occurrence_Of (RTE (RE_No_Dispatch_Table_Wrapper), Loc),
02a2406d 5557 Expression => Make_Aggregate (Loc, DT_Aggr_List)));
725a69d2 5558
17e14451 5559 Append_To (Result,
5560 Make_Attribute_Definition_Clause (Loc,
83c6c069 5561 Name => New_Occurrence_Of (DT, Loc),
17e14451 5562 Chars => Name_Alignment,
5563 Expression =>
5564 Make_Attribute_Reference (Loc,
02a2406d 5565 Prefix =>
83c6c069 5566 New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
17e14451 5567 Attribute_Name => Name_Alignment)));
5568
24971415 5569 Export_DT (Typ, DT);
725a69d2 5570 end if;
5571
5572 -- Common case: Typ has a dispatch table
5573
5574 -- Generate:
5575
5576 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
5577 -- (predef-prim-op-1'address,
5578 -- predef-prim-op-2'address,
5579 -- ...
5580 -- predef-prim-op-n'address);
5581 -- for Predef_Prims'Alignment use Address'Alignment
5582
5583 -- DT : Dispatch_Table (Nb_Prims) :=
5584 -- (Signature => <sig-value>,
5585 -- Tag_Kind => <tag_kind-value>,
5586 -- Predef_Prims => Predef_Prims'First'Address,
5587 -- Offset_To_Top => 0,
5588 -- TSD => TSD'Address;
5589 -- Prims_Ptr => (prim-op-1'address,
5590 -- prim-op-2'address,
5591 -- ...
5592 -- prim-op-n'address));
17e14451 5593 -- for DT'Alignment use Address'Alignment
725a69d2 5594
5595 else
5596 declare
5597 Pos : Nat;
5598
5599 begin
24971415 5600 if not Building_Static_DT (Typ) then
725a69d2 5601 Nb_Predef_Prims := Max_Predef_Prims;
5602
5603 else
5604 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5605 while Present (Prim_Elmt) loop
5606 Prim := Node (Prim_Elmt);
5607
5608 if Is_Predefined_Dispatching_Operation (Prim)
5609 and then not Is_Abstract_Subprogram (Prim)
5610 then
5611 Pos := UI_To_Int (DT_Position (Prim));
5612
5613 if Pos > Nb_Predef_Prims then
5614 Nb_Predef_Prims := Pos;
5615 end if;
5616 end if;
5617
5618 Next_Elmt (Prim_Elmt);
5619 end loop;
5620 end if;
5621
5622 declare
5623 Prim_Table : array
5624 (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
cc60bd16 5625 Decl : Node_Id;
725a69d2 5626 E : Entity_Id;
5627
5628 begin
5629 Prim_Ops_Aggr_List := New_List;
5630
5631 Prim_Table := (others => Empty);
17e14451 5632
cdb1c38f 5633 if Building_Static_DT (Typ) then
5634 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5635 while Present (Prim_Elmt) loop
5636 Prim := Node (Prim_Elmt);
725a69d2 5637
cdb1c38f 5638 if Is_Predefined_Dispatching_Operation (Prim)
5639 and then not Is_Abstract_Subprogram (Prim)
3f8cf2d2 5640 and then not Is_Eliminated (Prim)
cdb1c38f 5641 and then not Present (Prim_Table
5642 (UI_To_Int (DT_Position (Prim))))
5643 then
fc2907f6 5644 E := Ultimate_Alias (Prim);
cdb1c38f 5645 pragma Assert (not Is_Abstract_Subprogram (E));
5646 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
5647 end if;
725a69d2 5648
cdb1c38f 5649 Next_Elmt (Prim_Elmt);
5650 end loop;
5651 end if;
725a69d2 5652
5653 for J in Prim_Table'Range loop
5654 if Present (Prim_Table (J)) then
5655 New_Node :=
cc60bd16 5656 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
acf97c11 5657 Make_Attribute_Reference (Loc,
02a2406d 5658 Prefix =>
5659 New_Occurrence_Of (Prim_Table (J), Loc),
acf97c11 5660 Attribute_Name => Name_Unrestricted_Access));
725a69d2 5661 else
cc60bd16 5662 New_Node := Make_Null (Loc);
725a69d2 5663 end if;
5664
5665 Append_To (Prim_Ops_Aggr_List, New_Node);
5666 end loop;
343d35dc 5667
cc60bd16 5668 New_Node :=
5669 Make_Aggregate (Loc,
5670 Expressions => Prim_Ops_Aggr_List);
5671
5672 Decl :=
5673 Make_Subtype_Declaration (Loc,
ec97ce79 5674 Defining_Identifier => Make_Temporary (Loc, 'S'),
5675 Subtype_Indication =>
83c6c069 5676 New_Occurrence_Of (RTE (RE_Address_Array), Loc));
cc60bd16 5677
5678 Append_To (Result, Decl);
5679
68f95949 5680 Append_To (Result,
5681 Make_Object_Declaration (Loc,
725a69d2 5682 Defining_Identifier => Predef_Prims,
68f95949 5683 Aliased_Present => True,
24971415 5684 Constant_Present => Building_Static_DT (Typ),
02a2406d 5685 Object_Definition =>
5686 New_Occurrence_Of (Defining_Identifier (Decl), Loc),
cc60bd16 5687 Expression => New_Node));
5688
5689 -- Remember aggregates initializing dispatch tables
5690
5691 Append_Elmt (New_Node, DT_Aggr);
725a69d2 5692
5693 Append_To (Result,
5694 Make_Attribute_Definition_Clause (Loc,
83c6c069 5695 Name => New_Occurrence_Of (Predef_Prims, Loc),
725a69d2 5696 Chars => Name_Alignment,
5697 Expression =>
5698 Make_Attribute_Reference (Loc,
02a2406d 5699 Prefix =>
83c6c069 5700 New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
725a69d2 5701 Attribute_Name => Name_Alignment)));
5702 end;
5703 end;
5704
5705 -- Stage 1: Initialize the discriminant and the record components
5706
5707 DT_Constr_List := New_List;
5708 DT_Aggr_List := New_List;
5709
5710 -- Num_Prims. If the tagged type has no primitives we add a dummy
5711 -- slot whose address will be the tag of this type.
5712
5713 if Nb_Prim = 0 then
5714 New_Node := Make_Integer_Literal (Loc, 1);
5715 else
5716 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
5717 end if;
5718
5719 Append_To (DT_Constr_List, New_Node);
5720 Append_To (DT_Aggr_List, New_Copy (New_Node));
5721
5722 -- Signature
5723
5724 if RTE_Record_Component_Available (RE_Signature) then
5725 Append_To (DT_Aggr_List,
83c6c069 5726 New_Occurrence_Of (RTE (RE_Primary_DT), Loc));
725a69d2 5727 end if;
5728
5729 -- Tag_Kind
5730
5731 if RTE_Record_Component_Available (RE_Tag_Kind) then
5732 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
5733 end if;
5734
5735 -- Predef_Prims
5736
5737 Append_To (DT_Aggr_List,
5738 Make_Attribute_Reference (Loc,
02a2406d 5739 Prefix => New_Occurrence_Of (Predef_Prims, Loc),
725a69d2 5740 Attribute_Name => Name_Address));
5741
5742 -- Offset_To_Top
5743
cc60bd16 5744 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
725a69d2 5745
5746 -- Typeinfo
5747
5748 Append_To (DT_Aggr_List,
5749 Make_Attribute_Reference (Loc,
02a2406d 5750 Prefix => New_Occurrence_Of (TSD, Loc),
725a69d2 5751 Attribute_Name => Name_Address));
5752
f117057b 5753 -- Stage 2: Initialize the table of user-defined primitive operations
725a69d2 5754
5755 Prim_Ops_Aggr_List := New_List;
5756
5757 if Nb_Prim = 0 then
cc60bd16 5758 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
725a69d2 5759
9a479e51 5760 elsif not Building_Static_DT (Typ) then
725a69d2 5761 for J in 1 .. Nb_Prim loop
cc60bd16 5762 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
725a69d2 5763 end loop;
5764
5765 else
5766 declare
d00681a7 5767 CPP_Nb_Prims : constant Nat := CPP_Num_Prims (Typ);
5768 E : Entity_Id;
5769 Prim : Entity_Id;
5770 Prim_Elmt : Elmt_Id;
5771 Prim_Pos : Nat;
5772 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
725a69d2 5773
5774 begin
5775 Prim_Table := (others => Empty);
cdb1c38f 5776
5777 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
725a69d2 5778 while Present (Prim_Elmt) loop
5779 Prim := Node (Prim_Elmt);
5780
9429b6e9 5781 -- Retrieve the ultimate alias of the primitive for proper
5782 -- handling of renamings and eliminated primitives.
5783
d00681a7 5784 E := Ultimate_Alias (Prim);
5785 Prim_Pos := UI_To_Int (DT_Position (E));
9429b6e9 5786
3f8cf2d2 5787 -- Do not reference predefined primitives because they are
5788 -- located in a separate dispatch table; skip entities with
5789 -- attribute Interface_Alias because they are only required
d00681a7 5790 -- to build secondary dispatch tables; skip abstract and
5791 -- eliminated primitives; for derivations of CPP types skip
5792 -- primitives located in the C++ part of the dispatch table
5793 -- because their slot is initialized by the IC routine.
725a69d2 5794
3f8cf2d2 5795 if not Is_Predefined_Dispatching_Operation (Prim)
5796 and then not Is_Predefined_Dispatching_Operation (E)
5797 and then not Present (Interface_Alias (Prim))
5798 and then not Is_Abstract_Subprogram (E)
3f8cf2d2 5799 and then not Is_Eliminated (E)
d00681a7 5800 and then (not Is_CPP_Class (Root_Type (Typ))
5801 or else Prim_Pos > CPP_Nb_Prims)
3f8cf2d2 5802 then
5803 pragma Assert
5804 (UI_To_Int (DT_Position (Prim)) <= Nb_Prim);
5805
5806 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
725a69d2 5807 end if;
5808
5809 Next_Elmt (Prim_Elmt);
5810 end loop;
5811
5812 for J in Prim_Table'Range loop
5813 if Present (Prim_Table (J)) then
5814 New_Node :=
cc60bd16 5815 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
acf97c11 5816 Make_Attribute_Reference (Loc,
02a2406d 5817 Prefix =>
5818 New_Occurrence_Of (Prim_Table (J), Loc),
acf97c11 5819 Attribute_Name => Name_Unrestricted_Access));
725a69d2 5820 else
cc60bd16 5821 New_Node := Make_Null (Loc);
725a69d2 5822 end if;
5823
5824 Append_To (Prim_Ops_Aggr_List, New_Node);
5825 end loop;
5826 end;
5827 end if;
5828
cc60bd16 5829 New_Node :=
725a69d2 5830 Make_Aggregate (Loc,
cc60bd16 5831 Expressions => Prim_Ops_Aggr_List);
5832
5833 Append_To (DT_Aggr_List, New_Node);
5834
5835 -- Remember aggregates initializing dispatch tables
5836
5837 Append_Elmt (New_Node, DT_Aggr);
725a69d2 5838
5839 -- In case of locally defined tagged types we have already declared
5840 -- and uninitialized object for the dispatch table, which is now
5841 -- initialized by means of an assignment.
5842
24971415 5843 if not Building_Static_DT (Typ) then
725a69d2 5844 Append_To (Result,
5845 Make_Assignment_Statement (Loc,
02a2406d 5846 Name => New_Occurrence_Of (DT, Loc),
5847 Expression => Make_Aggregate (Loc, DT_Aggr_List)));
725a69d2 5848
24971415 5849 -- In case of library level tagged types we declare now and export
5850 -- the constant object containing the dispatch table.
725a69d2 5851
5852 else
5853 Append_To (Result,
5854 Make_Object_Declaration (Loc,
5855 Defining_Identifier => DT,
5856 Aliased_Present => True,
17e14451 5857 Constant_Present => True,
725a69d2 5858 Object_Definition =>
5859 Make_Subtype_Indication (Loc,
83c6c069 5860 Subtype_Mark => New_Occurrence_Of
725a69d2 5861 (RTE (RE_Dispatch_Table_Wrapper), Loc),
5862 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
5863 Constraints => DT_Constr_List)),
02a2406d 5864 Expression => Make_Aggregate (Loc, DT_Aggr_List)));
725a69d2 5865
5866 Append_To (Result,
5867 Make_Attribute_Definition_Clause (Loc,
83c6c069 5868 Name => New_Occurrence_Of (DT, Loc),
725a69d2 5869 Chars => Name_Alignment,
5870 Expression =>
5871 Make_Attribute_Reference (Loc,
02a2406d 5872 Prefix =>
83c6c069 5873 New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
725a69d2 5874 Attribute_Name => Name_Alignment)));
5875
24971415 5876 Export_DT (Typ, DT);
952af0b9 5877 end if;
76a1c25b 5878 end if;
d62940bf 5879
f301a57b 5880 -- Initialize the table of ancestor tags if not building static
5881 -- dispatch table
725a69d2 5882
24971415 5883 if not Building_Static_DT (Typ)
17e14451 5884 and then not Is_Interface (Typ)
725a69d2 5885 and then not Is_CPP_Class (Typ)
5886 then
5887 Append_To (Result,
5888 Make_Assignment_Statement (Loc,
02a2406d 5889 Name =>
725a69d2 5890 Make_Indexed_Component (Loc,
02a2406d 5891 Prefix =>
725a69d2 5892 Make_Selected_Component (Loc,
02a2406d 5893 Prefix => New_Occurrence_Of (TSD, Loc),
725a69d2 5894 Selector_Name =>
83c6c069 5895 New_Occurrence_Of
725a69d2 5896 (RTE_Record_Component (RE_Tags_Table), Loc)),
5897 Expressions =>
5898 New_List (Make_Integer_Literal (Loc, 0))),
5899
5900 Expression =>
83c6c069 5901 New_Occurrence_Of
725a69d2 5902 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)));
5903 end if;
5904
f301a57b 5905 -- Inherit the dispatch tables of the parent. There is no need to
5906 -- inherit anything from the parent when building static dispatch tables
5907 -- because the whole dispatch table (including inherited primitives) has
5908 -- been already built.
acf97c11 5909
9a479e51 5910 if Building_Static_DT (Typ) then
725a69d2 5911 null;
5912
af647dc7 5913 -- If the ancestor is a CPP_Class type we inherit the dispatch tables
5914 -- in the init proc, and we don't need to fill them in here.
d62940bf 5915
cc60bd16 5916 elsif Is_CPP_Class (Parent_Typ) then
af647dc7 5917 null;
d62940bf 5918
acf97c11 5919 -- Otherwise we fill in the dispatch tables here
d62940bf 5920
af647dc7 5921 else
cc60bd16 5922 if Typ /= Parent_Typ
af647dc7 5923 and then not Is_Interface (Typ)
5924 and then not Restriction_Active (No_Dispatching_Calls)
68f95949 5925 then
343d35dc 5926 -- Inherit the dispatch table
d62940bf 5927
acf97c11 5928 if not Is_Interface (Typ)
cc60bd16 5929 and then not Is_Interface (Parent_Typ)
5930 and then not Is_CPP_Class (Parent_Typ)
acf97c11 5931 then
5932 declare
5933 Nb_Prims : constant Int :=
5934 UI_To_Int (DT_Entry_Count
cc60bd16 5935 (First_Tag_Component (Parent_Typ)));
5936
acf97c11 5937 begin
5938 Append_To (Elab_Code,
5939 Build_Inherit_Predefined_Prims (Loc,
5940 Old_Tag_Node =>
83c6c069 5941 New_Occurrence_Of
acf97c11 5942 (Node
02a2406d 5943 (Next_Elmt
5944 (First_Elmt
5945 (Access_Disp_Table (Parent_Typ)))), Loc),
acf97c11 5946 New_Tag_Node =>
83c6c069 5947 New_Occurrence_Of
acf97c11 5948 (Node
02a2406d 5949 (Next_Elmt
5950 (First_Elmt
5951 (Access_Disp_Table (Typ)))), Loc)));
acf97c11 5952
5953 if Nb_Prims /= 0 then
725a69d2 5954 Append_To (Elab_Code,
acf97c11 5955 Build_Inherit_Prims (Loc,
5956 Typ => Typ,
5957 Old_Tag_Node =>
83c6c069 5958 New_Occurrence_Of
acf97c11 5959 (Node
02a2406d 5960 (First_Elmt
5961 (Access_Disp_Table (Parent_Typ))), Loc),
83c6c069 5962 New_Tag_Node => New_Occurrence_Of (DT_Ptr, Loc),
acf97c11 5963 Num_Prims => Nb_Prims));
5964 end if;
5965 end;
af647dc7 5966 end if;
d62940bf 5967
af647dc7 5968 -- Inherit the secondary dispatch tables of the ancestor
d62940bf 5969
cc60bd16 5970 if not Is_CPP_Class (Parent_Typ) then
af647dc7 5971 declare
5972 Sec_DT_Ancestor : Elmt_Id :=
5973 Next_Elmt
02a2406d 5974 (Next_Elmt
5975 (First_Elmt
5976 (Access_Disp_Table
5977 (Parent_Typ))));
af647dc7 5978 Sec_DT_Typ : Elmt_Id :=
5979 Next_Elmt
02a2406d 5980 (Next_Elmt
5981 (First_Elmt
5982 (Access_Disp_Table (Typ))));
af647dc7 5983
5984 procedure Copy_Secondary_DTs (Typ : Entity_Id);
5985 -- Local procedure required to climb through the ancestors
5986 -- and copy the contents of all their secondary dispatch
5987 -- tables.
5988
5989 ------------------------
5990 -- Copy_Secondary_DTs --
5991 ------------------------
5992
5993 procedure Copy_Secondary_DTs (Typ : Entity_Id) is
5994 E : Entity_Id;
5995 Iface : Elmt_Id;
5996
5997 begin
5998 -- Climb to the ancestor (if any) handling private types
5999
6000 if Present (Full_View (Etype (Typ))) then
6001 if Full_View (Etype (Typ)) /= Typ then
6002 Copy_Secondary_DTs (Full_View (Etype (Typ)));
6003 end if;
d62940bf 6004
af647dc7 6005 elsif Etype (Typ) /= Typ then
6006 Copy_Secondary_DTs (Etype (Typ));
6007 end if;
d62940bf 6008
a652dd51 6009 if Present (Interfaces (Typ))
6010 and then not Is_Empty_Elmt_List (Interfaces (Typ))
af647dc7 6011 then
a652dd51 6012 Iface := First_Elmt (Interfaces (Typ));
af647dc7 6013 E := First_Entity (Typ);
6014 while Present (E)
6015 and then Present (Node (Sec_DT_Ancestor))
725a69d2 6016 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
af647dc7 6017 loop
6018 if Is_Tag (E) and then Chars (E) /= Name_uTag then
cdb1c38f 6019 declare
6020 Num_Prims : constant Int :=
6021 UI_To_Int (DT_Entry_Count (E));
6022
6023 begin
6024 if not Is_Interface (Etype (Typ)) then
6025
6026 -- Inherit first secondary dispatch table
6027
6028 Append_To (Elab_Code,
6029 Build_Inherit_Predefined_Prims (Loc,
6030 Old_Tag_Node =>
6031 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 6032 New_Occurrence_Of
acf97c11 6033 (Node
6034 (Next_Elmt (Sec_DT_Ancestor)),
6035 Loc)),
cdb1c38f 6036 New_Tag_Node =>
6037 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 6038 New_Occurrence_Of
acf97c11 6039 (Node (Next_Elmt (Sec_DT_Typ)),
6040 Loc))));
cdb1c38f 6041
6042 if Num_Prims /= 0 then
6043 Append_To (Elab_Code,
6044 Build_Inherit_Prims (Loc,
6045 Typ => Node (Iface),
6046 Old_Tag_Node =>
6047 Unchecked_Convert_To
6048 (RTE (RE_Tag),
83c6c069 6049 New_Occurrence_Of
cdb1c38f 6050 (Node (Sec_DT_Ancestor),
6051 Loc)),
6052 New_Tag_Node =>
6053 Unchecked_Convert_To
6054 (RTE (RE_Tag),
83c6c069 6055 New_Occurrence_Of
cdb1c38f 6056 (Node (Sec_DT_Typ), Loc)),
6057 Num_Prims => Num_Prims));
6058 end if;
6059 end if;
6060
6061 Next_Elmt (Sec_DT_Ancestor);
6062 Next_Elmt (Sec_DT_Typ);
343d35dc 6063
acf97c11 6064 -- Skip the secondary dispatch table of
6065 -- predefined primitives
6066
6067 Next_Elmt (Sec_DT_Ancestor);
6068 Next_Elmt (Sec_DT_Typ);
6069
cdb1c38f 6070 if not Is_Interface (Etype (Typ)) then
6071
6072 -- Inherit second secondary dispatch table
343d35dc 6073
343d35dc 6074 Append_To (Elab_Code,
6075 Build_Inherit_Predefined_Prims (Loc,
6076 Old_Tag_Node =>
6077 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 6078 New_Occurrence_Of
acf97c11 6079 (Node
6080 (Next_Elmt (Sec_DT_Ancestor)),
6081 Loc)),
343d35dc 6082 New_Tag_Node =>
6083 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 6084 New_Occurrence_Of
acf97c11 6085 (Node (Next_Elmt (Sec_DT_Typ)),
6086 Loc))));
343d35dc 6087
6088 if Num_Prims /= 0 then
6089 Append_To (Elab_Code,
6090 Build_Inherit_Prims (Loc,
17e14451 6091 Typ => Node (Iface),
343d35dc 6092 Old_Tag_Node =>
6093 Unchecked_Convert_To
6094 (RTE (RE_Tag),
83c6c069 6095 New_Occurrence_Of
343d35dc 6096 (Node (Sec_DT_Ancestor),
6097 Loc)),
6098 New_Tag_Node =>
6099 Unchecked_Convert_To
6100 (RTE (RE_Tag),
83c6c069 6101 New_Occurrence_Of
343d35dc 6102 (Node (Sec_DT_Typ), Loc)),
17e14451 6103 Num_Prims => Num_Prims));
343d35dc 6104 end if;
cdb1c38f 6105 end if;
6106 end;
af647dc7 6107
6108 Next_Elmt (Sec_DT_Ancestor);
6109 Next_Elmt (Sec_DT_Typ);
acf97c11 6110
6111 -- Skip the secondary dispatch table of
6112 -- predefined primitives
6113
6114 Next_Elmt (Sec_DT_Ancestor);
6115 Next_Elmt (Sec_DT_Typ);
6116
af647dc7 6117 Next_Elmt (Iface);
6118 end if;
d62940bf 6119
af647dc7 6120 Next_Entity (E);
6121 end loop;
6122 end if;
6123 end Copy_Secondary_DTs;
d62940bf 6124
af647dc7 6125 begin
725a69d2 6126 if Present (Node (Sec_DT_Ancestor))
6127 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
6128 then
af647dc7 6129 -- Handle private types
76a1c25b 6130
af647dc7 6131 if Present (Full_View (Typ)) then
6132 Copy_Secondary_DTs (Full_View (Typ));
6133 else
6134 Copy_Secondary_DTs (Typ);
6135 end if;
76a1c25b 6136 end if;
af647dc7 6137 end;
6138 end if;
76a1c25b 6139 end if;
343d35dc 6140 end if;
d62940bf 6141
15a67a0a 6142 -- Generate code to check if the external tag of this type is the same
6143 -- as the external tag of some other declaration.
354540f3 6144
6145 -- Check_TSD (TSD'Unrestricted_Access);
6146
4a473cb9 6147 -- This check is a consequence of AI05-0113-1/06, so it officially
6148 -- applies to Ada 2005 (and Ada 2012). It might be argued that it is
6149 -- a desirable check to add in Ada 95 mode, but we hesitate to make
6150 -- this change, as it would be incompatible, and could conceivably
6151 -- cause a problem in existing Aa 95 code.
6152
6153 -- We check for No_Run_Time_Mode here, because we do not want to pick
6154 -- up the RE_Check_TSD entity and call it in No_Run_Time mode.
52b9debb 6155
354540f3 6156 if not No_Run_Time_Mode
4a473cb9 6157 and then Ada_Version >= Ada_2005
354540f3 6158 and then RTE_Available (RE_Check_TSD)
fa771c05 6159 and then not Duplicated_Tag_Checks_Suppressed (Typ)
354540f3 6160 then
6161 Append_To (Elab_Code,
6162 Make_Procedure_Call_Statement (Loc,
15a67a0a 6163 Name =>
6164 New_Occurrence_Of (RTE (RE_Check_TSD), Loc),
354540f3 6165 Parameter_Associations => New_List (
6166 Make_Attribute_Reference (Loc,
15a67a0a 6167 Prefix => New_Occurrence_Of (TSD, Loc),
354540f3 6168 Attribute_Name => Name_Unchecked_Access))));
6169 end if;
6170
343d35dc 6171 -- Generate code to register the Tag in the External_Tag hash table for
6172 -- the pure Ada type only.
d62940bf 6173
343d35dc 6174 -- Register_Tag (Dt_Ptr);
d62940bf 6175
725a69d2 6176 -- Skip this action in the following cases:
6177 -- 1) if Register_Tag is not available.
6178 -- 2) in No_Run_Time mode.
2ea346ac 6179 -- 3) if Typ is not defined at the library level (this is required
725a69d2 6180 -- to avoid adding concurrency control to the hash table used
6181 -- by the run-time to register the tags).
d62940bf 6182
cdb1c38f 6183 if not No_Run_Time_Mode
6184 and then Is_Library_Level_Entity (Typ)
6185 and then RTE_Available (RE_Register_Tag)
6186 then
725a69d2 6187 Append_To (Elab_Code,
cdb1c38f 6188 Make_Procedure_Call_Statement (Loc,
02a2406d 6189 Name =>
6190 New_Occurrence_Of (RTE (RE_Register_Tag), Loc),
cdb1c38f 6191 Parameter_Associations =>
83c6c069 6192 New_List (New_Occurrence_Of (DT_Ptr, Loc))));
d62940bf 6193 end if;
6194
2ea346ac 6195 if not Is_Empty_List (Elab_Code) then
6196 Append_List_To (Result, Elab_Code);
6197 end if;
cdb1c38f 6198
f38c8084 6199 -- Populate the two auxiliary tables used for dispatching asynchronous,
6200 -- conditional and timed selects for synchronized types that implement
6201 -- a limited interface. Skip this step in Ravenscar profile or when
6202 -- general dispatching is forbidden.
17e14451 6203
de54c5ab 6204 if Ada_Version >= Ada_2005
17e14451 6205 and then Is_Concurrent_Record_Type (Typ)
a652dd51 6206 and then Has_Interfaces (Typ)
f38c8084 6207 and then not Restriction_Active (No_Dispatching_Calls)
6208 and then not Restriction_Active (No_Select_Statements)
17e14451 6209 then
6210 Append_List_To (Result,
6211 Make_Select_Specific_Data_Table (Typ));
6212 end if;
6213
cc60bd16 6214 -- Remember entities containing dispatch tables
acf97c11 6215
cc60bd16 6216 Append_Elmt (Predef_Prims, DT_Decl);
6217 Append_Elmt (DT, DT_Decl);
acf97c11 6218
725a69d2 6219 Analyze_List (Result, Suppress => All_Checks);
17e14451 6220 Set_Has_Dispatch_Table (Typ);
6221
f301a57b 6222 -- Mark entities containing dispatch tables. Required by the backend to
6223 -- handle them properly.
cc60bd16 6224
925c2ba1 6225 if Has_DT (Typ) then
cc60bd16 6226 declare
6227 Elmt : Elmt_Id;
6228
6229 begin
cc60bd16 6230 -- Object declarations
6231
6232 Elmt := First_Elmt (DT_Decl);
6233 while Present (Elmt) loop
6234 Set_Is_Dispatch_Table_Entity (Node (Elmt));
6235 pragma Assert (Ekind (Etype (Node (Elmt))) = E_Array_Subtype
6236 or else Ekind (Etype (Node (Elmt))) = E_Record_Subtype);
6237 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
6238 Next_Elmt (Elmt);
6239 end loop;
6240
6241 -- Aggregates initializing dispatch tables
6242
6243 Elmt := First_Elmt (DT_Aggr);
6244 while Present (Elmt) loop
6245 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
6246 Next_Elmt (Elmt);
6247 end loop;
6248 end;
6249 end if;
6250
e00e091c 6251 -- Register the tagged type in the call graph nodes table
6252
6253 Register_CG_Node (Typ);
6254
360b005f 6255 Restore_Globals;
76a1c25b 6256 return Result;
6257 end Make_DT;
d62940bf 6258
87d6f1a4 6259 -----------------
6260 -- Make_VM_TSD --
6261 -----------------
6262
6263 function Make_VM_TSD (Typ : Entity_Id) return List_Id is
6cb4b973 6264 Loc : constant Source_Ptr := Sloc (Typ);
6265 Result : constant List_Id := New_List;
6266
6267 function Count_Primitives (Typ : Entity_Id) return Nat;
6268 -- Count the non-predefined primitive operations of Typ
6269
6270 ----------------------
6271 -- Count_Primitives --
6272 ----------------------
6273
6274 function Count_Primitives (Typ : Entity_Id) return Nat is
6275 Nb_Prim : Nat;
6276 Prim_Elmt : Elmt_Id;
6277 Prim : Entity_Id;
6278
6279 begin
6280 Nb_Prim := 0;
6281
6282 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6283 while Present (Prim_Elmt) loop
6284 Prim := Node (Prim_Elmt);
6285
6286 if Is_Predefined_Dispatching_Operation (Prim)
6287 or else Is_Predefined_Dispatching_Alias (Prim)
6288 then
6289 null;
6290
6291 elsif Present (Interface_Alias (Prim)) then
6292 null;
6293
6294 else
6295 Nb_Prim := Nb_Prim + 1;
6296 end if;
6297
6298 Next_Elmt (Prim_Elmt);
6299 end loop;
6300
6301 return Nb_Prim;
6302 end Count_Primitives;
6303
6304 --------------
6305 -- Make_OSD --
6306 --------------
6307
6308 function Make_OSD (Iface : Entity_Id) return Node_Id;
6309 -- Generate the Object Specific Data table required to dispatch calls
6310 -- through synchronized interfaces. Returns a node that references the
6311 -- generated OSD object.
6312
6313 function Make_OSD (Iface : Entity_Id) return Node_Id is
6314 Nb_Prim : constant Nat := Count_Primitives (Iface);
6315 OSD : Entity_Id;
6316 OSD_Aggr_List : List_Id;
6317
6318 begin
6319 -- Generate
6320 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
6321 -- (OSD_Table => (1 => <value>,
6322 -- ...
6323 -- N => <value>));
6324
6325 if Nb_Prim = 0
6326 or else Is_Abstract_Type (Typ)
6327 or else Is_Controlled (Typ)
6328 or else Restriction_Active (No_Dispatching_Calls)
6329 or else not Is_Limited_Type (Typ)
6330 or else not Has_Interfaces (Typ)
6331 or else not RTE_Record_Component_Available (RE_OSD_Table)
6332 then
6333 -- No OSD table required
6334
6335 return Make_Null (Loc);
6336
6337 else
6338 OSD_Aggr_List := New_List;
6339
6340 declare
6341 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
6342 Prim : Entity_Id;
6343 Prim_Alias : Entity_Id;
6344 Prim_Elmt : Elmt_Id;
6345 E : Entity_Id;
6346 Count : Nat := 0;
6347 Pos : Nat;
6348
6349 begin
6350 Prim_Table := (others => Empty);
6351 Prim_Alias := Empty;
6352
6353 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6354 while Present (Prim_Elmt) loop
6355 Prim := Node (Prim_Elmt);
6356
6357 if Present (Interface_Alias (Prim))
6358 and then Find_Dispatching_Type
6359 (Interface_Alias (Prim)) = Iface
6360 then
6361 Prim_Alias := Interface_Alias (Prim);
6362 E := Ultimate_Alias (Prim);
6363 Pos := UI_To_Int (DT_Position (Prim_Alias));
6364
6365 if Present (Prim_Table (Pos)) then
6366 pragma Assert (Prim_Table (Pos) = E);
6367 null;
6368
6369 else
6370 Prim_Table (Pos) := E;
6371
6372 Append_To (OSD_Aggr_List,
6373 Make_Component_Association (Loc,
02a2406d 6374 Choices => New_List (
6cb4b973 6375 Make_Integer_Literal (Loc,
6376 DT_Position (Prim_Alias))),
6377 Expression =>
6378 Make_Integer_Literal (Loc,
6379 DT_Position (Alias (Prim)))));
6380
6381 Count := Count + 1;
6382 end if;
6383 end if;
6384
6385 Next_Elmt (Prim_Elmt);
6386 end loop;
02a2406d 6387
6cb4b973 6388 pragma Assert (Count = Nb_Prim);
6389 end;
6390
6391 OSD := Make_Temporary (Loc, 'I');
6392
6393 Append_To (Result,
6394 Make_Object_Declaration (Loc,
6395 Defining_Identifier => OSD,
6396 Aliased_Present => True,
6397 Constant_Present => True,
6398 Object_Definition =>
6399 Make_Subtype_Indication (Loc,
6400 Subtype_Mark =>
83c6c069 6401 New_Occurrence_Of (RTE (RE_Object_Specific_Data), Loc),
02a2406d 6402 Constraint =>
6cb4b973 6403 Make_Index_Or_Discriminant_Constraint (Loc,
6404 Constraints => New_List (
6405 Make_Integer_Literal (Loc, Nb_Prim)))),
6406
6407 Expression =>
6408 Make_Aggregate (Loc,
6409 Component_Associations => New_List (
6410 Make_Component_Association (Loc,
02a2406d 6411 Choices => New_List (
6cb4b973 6412 New_Occurrence_Of
6413 (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
6414 Expression =>
6415 Make_Integer_Literal (Loc, Nb_Prim)),
6416
6417 Make_Component_Association (Loc,
02a2406d 6418 Choices => New_List (
6cb4b973 6419 New_Occurrence_Of
6420 (RTE_Record_Component (RE_OSD_Table), Loc)),
6421 Expression => Make_Aggregate (Loc,
6422 Component_Associations => OSD_Aggr_List))))));
6423
6424 return
6425 Make_Attribute_Reference (Loc,
83c6c069 6426 Prefix => New_Occurrence_Of (OSD, Loc),
6cb4b973 6427 Attribute_Name => Name_Unchecked_Access);
6428 end if;
6429 end Make_OSD;
6430
6431 -- Local variables
6432
6433 Nb_Prim : constant Nat := Count_Primitives (Typ);
87d6f1a4 6434 AI : Elmt_Id;
bf7f5966 6435 I_Depth : Nat;
87d6f1a4 6436 Iface_Table_Node : Node_Id;
bf7f5966 6437 Num_Ifaces : Nat;
87d6f1a4 6438 TSD_Aggr_List : List_Id;
6439 Typ_Ifaces : Elist_Id;
6440 TSD_Tags_List : List_Id;
6441
6442 Tname : constant Name_Id := Chars (Typ);
bf7f5966 6443 Name_SSD : constant Name_Id :=
6444 New_External_Name (Tname, 'S', Suffix_Index => -1);
87d6f1a4 6445 Name_TSD : constant Name_Id :=
6446 New_External_Name (Tname, 'B', Suffix_Index => -1);
bf7f5966 6447 SSD : constant Entity_Id :=
6448 Make_Defining_Identifier (Loc, Name_SSD);
87d6f1a4 6449 TSD : constant Entity_Id :=
6450 Make_Defining_Identifier (Loc, Name_TSD);
6451 begin
6452 -- Generate code to create the storage for the type specific data object
6453 -- with enough space to store the tags of the ancestors plus the tags
6454 -- of all the implemented interfaces (as described in a-tags.ads).
6455
6456 -- TSD : Type_Specific_Data (I_Depth) :=
6457 -- (Idepth => I_Depth,
6cb4b973 6458 -- Tag_Kind => <tag_kind-value>,
87d6f1a4 6459 -- Access_Level => Type_Access_Level (Typ),
d67a83fe 6460 -- Alignment => Typ'Alignment,
87d6f1a4 6461 -- HT_Link => null,
6462 -- Type_Is_Abstract => <<boolean-value>>,
6463 -- Type_Is_Library_Level => <<boolean-value>>,
6464 -- Interfaces_Table => <<access-value>>
6cb4b973 6465 -- SSD => SSD_Table'Address
87d6f1a4 6466 -- Tags_Table => (0 => Typ'Tag,
6467 -- 1 => Parent'Tag
6468 -- ...));
6469
6470 TSD_Aggr_List := New_List;
6471
6472 -- Idepth: Count ancestors to compute the inheritance depth. For private
6473 -- extensions, always go to the full view in order to compute the real
6474 -- inheritance depth.
6475
6476 declare
6477 Current_Typ : Entity_Id;
6478 Parent_Typ : Entity_Id;
6479
6480 begin
6481 I_Depth := 0;
6482 Current_Typ := Typ;
6483 loop
6484 Parent_Typ := Etype (Current_Typ);
6485
6486 if Is_Private_Type (Parent_Typ) then
6487 Parent_Typ := Full_View (Base_Type (Parent_Typ));
6488 end if;
6489
6490 exit when Parent_Typ = Current_Typ;
6491
6492 I_Depth := I_Depth + 1;
6493 Current_Typ := Parent_Typ;
6494 end loop;
6495 end;
6496
6cb4b973 6497 -- I_Depth
6498
87d6f1a4 6499 Append_To (TSD_Aggr_List,
6500 Make_Integer_Literal (Loc, I_Depth));
6501
6cb4b973 6502 -- Tag_Kind
6503
6504 Append_To (TSD_Aggr_List, Tagged_Kind (Typ));
6505
87d6f1a4 6506 -- Access_Level
6507
6508 Append_To (TSD_Aggr_List,
6509 Make_Integer_Literal (Loc, Type_Access_Level (Typ)));
6510
d67a83fe 6511 -- Alignment
6512
6fc3e7ad 6513 -- For CPP types we cannot rely on the value of 'Alignment provided
44705307 6514 -- by the backend to initialize this TSD field. Why not???
6fc3e7ad 6515
6516 if Convention (Typ) = Convention_CPP
6517 or else Is_CPP_Class (Root_Type (Typ))
6518 then
6519 Append_To (TSD_Aggr_List,
6520 Make_Integer_Literal (Loc, 0));
6521 else
6522 Append_To (TSD_Aggr_List,
6523 Make_Attribute_Reference (Loc,
83c6c069 6524 Prefix => New_Occurrence_Of (Typ, Loc),
6fc3e7ad 6525 Attribute_Name => Name_Alignment));
6526 end if;
d67a83fe 6527
87d6f1a4 6528 -- HT_Link
6529
6530 Append_To (TSD_Aggr_List,
6531 Make_Null (Loc));
6532
6533 -- Type_Is_Abstract (Ada 2012: AI05-0173)
6534
6535 declare
6536 Type_Is_Abstract : Entity_Id;
6537
6538 begin
6539 Type_Is_Abstract :=
6540 Boolean_Literals (Is_Abstract_Type (Typ));
6541
6542 Append_To (TSD_Aggr_List,
6543 New_Occurrence_Of (Type_Is_Abstract, Loc));
6544 end;
6545
6546 -- Type_Is_Library_Level
6547
6548 declare
6549 Type_Is_Library_Level : Entity_Id;
87d6f1a4 6550 begin
6551 Type_Is_Library_Level :=
6552 Boolean_Literals (Is_Library_Level_Entity (Typ));
87d6f1a4 6553 Append_To (TSD_Aggr_List,
6554 New_Occurrence_Of (Type_Is_Library_Level, Loc));
6555 end;
6556
6557 -- Interfaces_Table (required for AI-405)
6558
6559 if RTE_Record_Component_Available (RE_Interfaces_Table) then
6560
6561 -- Count the number of interface types implemented by Typ
6562
6563 Collect_Interfaces (Typ, Typ_Ifaces);
6564
bf7f5966 6565 Num_Ifaces := 0;
87d6f1a4 6566 AI := First_Elmt (Typ_Ifaces);
6567 while Present (AI) loop
6568 Num_Ifaces := Num_Ifaces + 1;
6569 Next_Elmt (AI);
6570 end loop;
6571
6572 if Num_Ifaces = 0 then
6573 Iface_Table_Node := Make_Null (Loc);
6574
6575 -- Generate the Interface_Table object
6576
6577 else
6578 declare
6579 TSD_Ifaces_List : constant List_Id := New_List;
6cb4b973 6580 Iface : Entity_Id;
87d6f1a4 6581 ITable : Node_Id;
6582
6583 begin
6584 AI := First_Elmt (Typ_Ifaces);
6585 while Present (AI) loop
6cb4b973 6586 Iface := Node (AI);
6587
87d6f1a4 6588 Append_To (TSD_Ifaces_List,
6589 Make_Aggregate (Loc,
6590 Expressions => New_List (
6cb4b973 6591
4055a532 6592 -- Iface_Tag
6cb4b973 6593
87d6f1a4 6594 Make_Attribute_Reference (Loc,
83c6c069 6595 Prefix => New_Occurrence_Of (Iface, Loc),
6cb4b973 6596 Attribute_Name => Name_Tag),
6597
4055a532 6598 -- OSD
6cb4b973 6599
6600 Make_OSD (Iface))));
87d6f1a4 6601
6602 Next_Elmt (AI);
6603 end loop;
6604
6605 ITable := Make_Temporary (Loc, 'I');
6606
6607 Append_To (Result,
6608 Make_Object_Declaration (Loc,
6609 Defining_Identifier => ITable,
6610 Aliased_Present => True,
6611 Constant_Present => True,
6612 Object_Definition =>
6613 Make_Subtype_Indication (Loc,
6614 Subtype_Mark =>
83c6c069 6615 New_Occurrence_Of (RTE (RE_Interface_Data), Loc),
b860aaec 6616 Constraint => Make_Index_Or_Discriminant_Constraint
87d6f1a4 6617 (Loc,
6618 Constraints => New_List (
6619 Make_Integer_Literal (Loc, Num_Ifaces)))),
6620
6621 Expression => Make_Aggregate (Loc,
6622 Expressions => New_List (
6623 Make_Integer_Literal (Loc, Num_Ifaces),
6624 Make_Aggregate (Loc,
6625 Expressions => TSD_Ifaces_List)))));
6626
6627 Iface_Table_Node :=
6628 Make_Attribute_Reference (Loc,
83c6c069 6629 Prefix => New_Occurrence_Of (ITable, Loc),
87d6f1a4 6630 Attribute_Name => Name_Unchecked_Access);
6631 end;
6632 end if;
6633
6634 Append_To (TSD_Aggr_List, Iface_Table_Node);
6635 end if;
6636
bf7f5966 6637 -- Generate the Select Specific Data table for synchronized types that
6638 -- implement synchronized interfaces. The size of the table is
6639 -- constrained by the number of non-predefined primitive operations.
6640
bf7f5966 6641 if RTE_Record_Component_Available (RE_SSD) then
6642 if Ada_Version >= Ada_2005
6643 and then Has_DT (Typ)
6644 and then Is_Concurrent_Record_Type (Typ)
6645 and then Has_Interfaces (Typ)
6646 and then Nb_Prim > 0
6647 and then not Is_Abstract_Type (Typ)
6648 and then not Is_Controlled (Typ)
6649 and then not Restriction_Active (No_Dispatching_Calls)
6650 and then not Restriction_Active (No_Select_Statements)
6651 then
6652 Append_To (Result,
6653 Make_Object_Declaration (Loc,
6654 Defining_Identifier => SSD,
6655 Aliased_Present => True,
6656 Object_Definition =>
6657 Make_Subtype_Indication (Loc,
83c6c069 6658 Subtype_Mark => New_Occurrence_Of (
bf7f5966 6659 RTE (RE_Select_Specific_Data), Loc),
6660 Constraint =>
6661 Make_Index_Or_Discriminant_Constraint (Loc,
6662 Constraints => New_List (
6663 Make_Integer_Literal (Loc, Nb_Prim))))));
6664
6665 -- This table is initialized by Make_Select_Specific_Data_Table,
6666 -- which calls Set_Entry_Index and Set_Prim_Op_Kind.
6667
6668 Append_To (TSD_Aggr_List,
6669 Make_Attribute_Reference (Loc,
83c6c069 6670 Prefix => New_Occurrence_Of (SSD, Loc),
bf7f5966 6671 Attribute_Name => Name_Unchecked_Access));
6672 else
6673 Append_To (TSD_Aggr_List, Make_Null (Loc));
6674 end if;
6675 end if;
6676
87d6f1a4 6677 -- Initialize the table of ancestor tags. In case of interface types
6678 -- this table is not needed.
6679
6680 TSD_Tags_List := New_List;
6681
6682 -- Fill position 0 with Typ'Tag
6683
6684 Append_To (TSD_Tags_List,
6685 Make_Attribute_Reference (Loc,
83c6c069 6686 Prefix => New_Occurrence_Of (Typ, Loc),
87d6f1a4 6687 Attribute_Name => Name_Tag));
6688
6689 -- Fill the rest of the table with the tags of the ancestors
6690
6691 declare
6692 Current_Typ : Entity_Id;
6693 Parent_Typ : Entity_Id;
6694 Pos : Nat;
6695
6696 begin
6697 Pos := 1;
6698 Current_Typ := Typ;
6699
6700 loop
6701 Parent_Typ := Etype (Current_Typ);
6702
6703 if Is_Private_Type (Parent_Typ) then
6704 Parent_Typ := Full_View (Base_Type (Parent_Typ));
6705 end if;
6706
6707 exit when Parent_Typ = Current_Typ;
6708
6709 Append_To (TSD_Tags_List,
6710 Make_Attribute_Reference (Loc,
83c6c069 6711 Prefix => New_Occurrence_Of (Parent_Typ, Loc),
87d6f1a4 6712 Attribute_Name => Name_Tag));
6713
6714 Pos := Pos + 1;
6715 Current_Typ := Parent_Typ;
6716 end loop;
6717
6718 pragma Assert (Pos = I_Depth + 1);
6719 end;
6720
6721 Append_To (TSD_Aggr_List,
6722 Make_Aggregate (Loc,
6723 Expressions => TSD_Tags_List));
6724
6725 -- Build the TSD object
6726
6727 Append_To (Result,
6728 Make_Object_Declaration (Loc,
6729 Defining_Identifier => TSD,
6730 Aliased_Present => True,
6731 Constant_Present => True,
6732 Object_Definition =>
6733 Make_Subtype_Indication (Loc,
83c6c069 6734 Subtype_Mark => New_Occurrence_Of (
87d6f1a4 6735 RTE (RE_Type_Specific_Data), Loc),
6736 Constraint =>
6737 Make_Index_Or_Discriminant_Constraint (Loc,
6738 Constraints => New_List (
6739 Make_Integer_Literal (Loc, I_Depth)))),
6740
6741 Expression => Make_Aggregate (Loc,
6742 Expressions => TSD_Aggr_List)));
6743
6744 -- Generate:
15a67a0a 6745 -- Check_TSD (TSD => TSD'Unrestricted_Access);
87d6f1a4 6746
79500ea0 6747 if Ada_Version >= Ada_2005
6748 and then Is_Library_Level_Entity (Typ)
79500ea0 6749 and then RTE_Available (RE_Check_TSD)
fa771c05 6750 and then not Duplicated_Tag_Checks_Suppressed (Typ)
79500ea0 6751 then
6752 Append_To (Result,
6753 Make_Procedure_Call_Statement (Loc,
83c6c069 6754 Name => New_Occurrence_Of (RTE (RE_Check_TSD), Loc),
79500ea0 6755 Parameter_Associations => New_List (
6756 Make_Attribute_Reference (Loc,
83c6c069 6757 Prefix => New_Occurrence_Of (TSD, Loc),
79500ea0 6758 Attribute_Name => Name_Unrestricted_Access))));
6759 end if;
87d6f1a4 6760
6761 -- Generate:
6762 -- Register_TSD (TSD'Unrestricted_Access);
6763
6764 Append_To (Result,
6765 Make_Procedure_Call_Statement (Loc,
83c6c069 6766 Name => New_Occurrence_Of (RTE (RE_Register_TSD), Loc),
87d6f1a4 6767 Parameter_Associations => New_List (
6768 Make_Attribute_Reference (Loc,
83c6c069 6769 Prefix => New_Occurrence_Of (TSD, Loc),
87d6f1a4 6770 Attribute_Name => Name_Unrestricted_Access))));
6771
bf7f5966 6772 -- Populate the two auxiliary tables used for dispatching asynchronous,
6773 -- conditional and timed selects for synchronized types that implement
6774 -- a limited interface. Skip this step in Ravenscar profile or when
6775 -- general dispatching is forbidden.
6776
6777 if Ada_Version >= Ada_2005
6778 and then Is_Concurrent_Record_Type (Typ)
6779 and then Has_Interfaces (Typ)
6780 and then not Restriction_Active (No_Dispatching_Calls)
6781 and then not Restriction_Active (No_Select_Statements)
6782 then
6783 Append_List_To (Result,
6784 Make_Select_Specific_Data_Table (Typ));
6785 end if;
6786
87d6f1a4 6787 return Result;
6788 end Make_VM_TSD;
6789
76a1c25b 6790 -------------------------------------
6791 -- Make_Select_Specific_Data_Table --
6792 -------------------------------------
d62940bf 6793
76a1c25b 6794 function Make_Select_Specific_Data_Table
6795 (Typ : Entity_Id) return List_Id
6796 is
6797 Assignments : constant List_Id := New_List;
6798 Loc : constant Source_Ptr := Sloc (Typ);
d62940bf 6799
68f95949 6800 Conc_Typ : Entity_Id;
6801 Decls : List_Id;
68f95949 6802 Prim : Entity_Id;
6803 Prim_Als : Entity_Id;
6804 Prim_Elmt : Elmt_Id;
6805 Prim_Pos : Uint;
343d35dc 6806 Nb_Prim : Nat := 0;
d62940bf 6807
76a1c25b 6808 type Examined_Array is array (Int range <>) of Boolean;
d62940bf 6809
76a1c25b 6810 function Find_Entry_Index (E : Entity_Id) return Uint;
6811 -- Given an entry, find its index in the visible declarations of the
6812 -- corresponding concurrent type of Typ.
d62940bf 6813
76a1c25b 6814 ----------------------
6815 -- Find_Entry_Index --
6816 ----------------------
d62940bf 6817
76a1c25b 6818 function Find_Entry_Index (E : Entity_Id) return Uint is
6819 Index : Uint := Uint_1;
6820 Subp_Decl : Entity_Id;
d62940bf 6821
76a1c25b 6822 begin
6823 if Present (Decls)
6824 and then not Is_Empty_List (Decls)
6825 then
6826 Subp_Decl := First (Decls);
6827 while Present (Subp_Decl) loop
6828 if Nkind (Subp_Decl) = N_Entry_Declaration then
6829 if Defining_Identifier (Subp_Decl) = E then
6830 return Index;
6831 end if;
d62940bf 6832
76a1c25b 6833 Index := Index + 1;
6834 end if;
d62940bf 6835
76a1c25b 6836 Next (Subp_Decl);
6837 end loop;
6838 end if;
d62940bf 6839
76a1c25b 6840 return Uint_0;
6841 end Find_Entry_Index;
6842
bf7f5966 6843 -- Local variables
6844
6845 Tag_Node : Node_Id;
6846
76a1c25b 6847 -- Start of processing for Make_Select_Specific_Data_Table
6848
6849 begin
68f95949 6850 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
6851
76a1c25b 6852 if Present (Corresponding_Concurrent_Type (Typ)) then
6853 Conc_Typ := Corresponding_Concurrent_Type (Typ);
6854
17e14451 6855 if Present (Full_View (Conc_Typ)) then
6856 Conc_Typ := Full_View (Conc_Typ);
6857 end if;
6858
76a1c25b 6859 if Ekind (Conc_Typ) = E_Protected_Type then
6860 Decls := Visible_Declarations (Protected_Definition (
6861 Parent (Conc_Typ)));
d62940bf 6862 else
6863 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
76a1c25b 6864 Decls := Visible_Declarations (Task_Definition (
6865 Parent (Conc_Typ)));
6866 end if;
6867 end if;
d62940bf 6868
76a1c25b 6869 -- Count the non-predefined primitive operations
d62940bf 6870
76a1c25b 6871 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6872 while Present (Prim_Elmt) loop
af647dc7 6873 Prim := Node (Prim_Elmt);
6874
6875 if not (Is_Predefined_Dispatching_Operation (Prim)
6876 or else Is_Predefined_Dispatching_Alias (Prim))
6877 then
76a1c25b 6878 Nb_Prim := Nb_Prim + 1;
6879 end if;
d62940bf 6880
76a1c25b 6881 Next_Elmt (Prim_Elmt);
6882 end loop;
d62940bf 6883
76a1c25b 6884 declare
68f95949 6885 Examined : Examined_Array (1 .. Nb_Prim) := (others => False);
d62940bf 6886
76a1c25b 6887 begin
6888 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6889 while Present (Prim_Elmt) loop
6890 Prim := Node (Prim_Elmt);
d62940bf 6891
af647dc7 6892 -- Look for primitive overriding an abstract interface subprogram
d62940bf 6893
a652dd51 6894 if Present (Interface_Alias (Prim))
c8da6114 6895 and then not
6896 Is_Ancestor
cb4af01d 6897 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ,
6898 Use_Full_View => True)
af647dc7 6899 and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
6900 then
6901 Prim_Pos := DT_Position (Alias (Prim));
6902 pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
6903 Examined (UI_To_Int (Prim_Pos)) := True;
d62940bf 6904
af647dc7 6905 -- Set the primitive operation kind regardless of subprogram
6906 -- type. Generate:
6907 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
d62940bf 6908
bf7f5966 6909 if Tagged_Type_Expansion then
6910 Tag_Node :=
83c6c069 6911 New_Occurrence_Of
bf7f5966 6912 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc);
6913
6914 else
6915 Tag_Node :=
6916 Make_Attribute_Reference (Loc,
83c6c069 6917 Prefix => New_Occurrence_Of (Typ, Loc),
bf7f5966 6918 Attribute_Name => Name_Tag);
6919 end if;
6920
af647dc7 6921 Append_To (Assignments,
725a69d2 6922 Make_Procedure_Call_Statement (Loc,
83c6c069 6923 Name => New_Occurrence_Of (RTE (RE_Set_Prim_Op_Kind), Loc),
725a69d2 6924 Parameter_Associations => New_List (
bf7f5966 6925 Tag_Node,
725a69d2 6926 Make_Integer_Literal (Loc, Prim_Pos),
6927 Prim_Op_Kind (Alias (Prim), Typ))));
68f95949 6928
af647dc7 6929 -- Retrieve the root of the alias chain
68f95949 6930
fc2907f6 6931 Prim_Als := Ultimate_Alias (Prim);
68f95949 6932
af647dc7 6933 -- In the case of an entry wrapper, set the entry index
68f95949 6934
af647dc7 6935 if Ekind (Prim) = E_Procedure
6936 and then Is_Primitive_Wrapper (Prim_Als)
6937 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
6938 then
6939 -- Generate:
6940 -- Ada.Tags.Set_Entry_Index
6941 -- (DT_Ptr, <position>, <index>);
68f95949 6942
bf7f5966 6943 if Tagged_Type_Expansion then
6944 Tag_Node :=
83c6c069 6945 New_Occurrence_Of
96dc081d 6946 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc);
bf7f5966 6947 else
6948 Tag_Node :=
6949 Make_Attribute_Reference (Loc,
83c6c069 6950 Prefix => New_Occurrence_Of (Typ, Loc),
bf7f5966 6951 Attribute_Name => Name_Tag);
6952 end if;
6953
af647dc7 6954 Append_To (Assignments,
725a69d2 6955 Make_Procedure_Call_Statement (Loc,
6956 Name =>
83c6c069 6957 New_Occurrence_Of (RTE (RE_Set_Entry_Index), Loc),
725a69d2 6958 Parameter_Associations => New_List (
bf7f5966 6959 Tag_Node,
725a69d2 6960 Make_Integer_Literal (Loc, Prim_Pos),
6961 Make_Integer_Literal (Loc,
6962 Find_Entry_Index (Wrapped_Entity (Prim_Als))))));
76a1c25b 6963 end if;
6964 end if;
6965
76a1c25b 6966 Next_Elmt (Prim_Elmt);
6967 end loop;
6968 end;
6969
6970 return Assignments;
6971 end Make_Select_Specific_Data_Table;
d62940bf 6972
17e14451 6973 ---------------
6974 -- Make_Tags --
6975 ---------------
6976
6977 function Make_Tags (Typ : Entity_Id) return List_Id is
f301a57b 6978 Loc : constant Source_Ptr := Sloc (Typ);
6979 Result : constant List_Id := New_List;
6980
6981 procedure Import_DT
6982 (Tag_Typ : Entity_Id;
6983 DT : Entity_Id;
6984 Is_Secondary_DT : Boolean);
6985 -- Import the dispatch table DT of tagged type Tag_Typ. Required to
6986 -- generate forward references and statically allocate the table. For
6987 -- primary dispatch tables that require no dispatch table generate:
d03ada96 6988
f301a57b 6989 -- DT : static aliased constant Non_Dispatch_Table_Wrapper;
d03ada96 6990 -- pragma Import (Ada, DT);
6991
f301a57b 6992 -- Otherwise generate:
d03ada96 6993
f301a57b 6994 -- DT : static aliased constant Dispatch_Table_Wrapper (Nb_Prim);
d03ada96 6995 -- pragma Import (Ada, DT);
7854e190 6996
f301a57b 6997 ---------------
6998 -- Import_DT --
6999 ---------------
24971415 7000
f301a57b 7001 procedure Import_DT
7002 (Tag_Typ : Entity_Id;
7003 DT : Entity_Id;
7004 Is_Secondary_DT : Boolean)
7005 is
7006 DT_Constr_List : List_Id;
7007 Nb_Prim : Nat;
24971415 7008
f301a57b 7009 begin
7010 Set_Is_Imported (DT);
7011 Set_Ekind (DT, E_Constant);
7012 Set_Related_Type (DT, Typ);
24971415 7013
24971415 7014 -- The scope must be set now to call Get_External_Name
7015
7016 Set_Scope (DT, Current_Scope);
7017
f92da234 7018 Get_External_Name (DT);
24971415 7019 Set_Interface_Name (DT,
d03ada96 7020 Make_String_Literal (Loc, Strval => String_From_Name_Buffer));
17e14451 7021
24971415 7022 -- Ensure proper Sprint output of this implicit importation
17e14451 7023
24971415 7024 Set_Is_Internal (DT);
17e14451 7025
24971415 7026 -- Save this entity to allow Make_DT to generate its exportation
7027
f301a57b 7028 Append_Elmt (DT, Dispatch_Table_Wrappers (Typ));
24971415 7029
f301a57b 7030 -- No dispatch table required
acf97c11 7031
d03ada96 7032 if not Is_Secondary_DT and then not Has_DT (Tag_Typ) then
f301a57b 7033 Append_To (Result,
7034 Make_Object_Declaration (Loc,
7035 Defining_Identifier => DT,
7036 Aliased_Present => True,
7037 Constant_Present => True,
7038 Object_Definition =>
83c6c069 7039 New_Occurrence_Of
7040 (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
f301a57b 7041
7042 else
24971415 7043 -- Calculate the number of primitives of the dispatch table and
7044 -- the size of the Type_Specific_Data record.
7045
f301a57b 7046 Nb_Prim :=
7047 UI_To_Int (DT_Entry_Count (First_Tag_Component (Tag_Typ)));
24971415 7048
d03ada96 7049 -- If the tagged type has no primitives we add a dummy slot whose
7050 -- address will be the tag of this type.
24971415 7051
7052 if Nb_Prim = 0 then
7053 DT_Constr_List :=
7054 New_List (Make_Integer_Literal (Loc, 1));
7055 else
7056 DT_Constr_List :=
7057 New_List (Make_Integer_Literal (Loc, Nb_Prim));
7058 end if;
7059
7060 Append_To (Result,
7061 Make_Object_Declaration (Loc,
7062 Defining_Identifier => DT,
7063 Aliased_Present => True,
7064 Constant_Present => True,
7065 Object_Definition =>
7066 Make_Subtype_Indication (Loc,
7067 Subtype_Mark =>
83c6c069 7068 New_Occurrence_Of (RTE (RE_Dispatch_Table_Wrapper), Loc),
24971415 7069 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
7070 Constraints => DT_Constr_List))));
f301a57b 7071 end if;
7072 end Import_DT;
7073
7074 -- Local variables
7075
7076 Tname : constant Name_Id := Chars (Typ);
7077 AI_Tag_Comp : Elmt_Id;
7640ed3d 7078 DT : Node_Id := Empty;
f301a57b 7079 DT_Ptr : Node_Id;
7080 Predef_Prims_Ptr : Node_Id;
d04be62f 7081 Iface_DT : Node_Id := Empty;
f301a57b 7082 Iface_DT_Ptr : Node_Id;
d215f619 7083 New_Node : Node_Id;
f301a57b 7084 Suffix_Index : Int;
7085 Typ_Name : Name_Id;
7086 Typ_Comps : Elist_Id;
7087
7088 -- Start of processing for Make_Tags
7089
7090 begin
d00681a7 7091 pragma Assert (No (Access_Disp_Table (Typ)));
7092 Set_Access_Disp_Table (Typ, New_Elmt_List);
f301a57b 7093
7094 -- 1) Generate the primary tag entities
7095
7096 -- Primary dispatch table containing user-defined primitives
7097
d00681a7 7098 DT_Ptr := Make_Defining_Identifier (Loc, New_External_Name (Tname, 'P'));
7099 Set_Etype (DT_Ptr, RTE (RE_Tag));
7100 Append_Elmt (DT_Ptr, Access_Disp_Table (Typ));
f301a57b 7101
d00681a7 7102 -- Minimum decoration
f301a57b 7103
d00681a7 7104 Set_Ekind (DT_Ptr, E_Variable);
7105 Set_Related_Type (DT_Ptr, Typ);
f301a57b 7106
02a2406d 7107 -- Notify back end that the types are associated with a dispatch table
2ff0322d 7108
7109 Set_Is_Dispatch_Table_Entity (RTE (RE_Prim_Ptr));
7110 Set_Is_Dispatch_Table_Entity (RTE (RE_Predef_Prims_Table_Ptr));
7111
d00681a7 7112 -- For CPP types there is no need to build the dispatch tables since
5682f43c 7113 -- they are imported from the C++ side. If the CPP type has an IP then
7114 -- we declare now the variable that will store the copy of the C++ tag.
d03ada96 7115 -- If the CPP type is an interface, we need the variable as well because
7116 -- it becomes the pointer to the corresponding secondary table.
f301a57b 7117
d00681a7 7118 if Is_CPP_Class (Typ) then
5682f43c 7119 if Has_CPP_Constructors (Typ) or else Is_Interface (Typ) then
24971415 7120 Append_To (Result,
7121 Make_Object_Declaration (Loc,
7122 Defining_Identifier => DT_Ptr,
83c6c069 7123 Object_Definition => New_Occurrence_Of (RTE (RE_Tag), Loc),
24971415 7124 Expression =>
7125 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 7126 New_Occurrence_Of (RTE (RE_Null_Address), Loc))));
24971415 7127
d00681a7 7128 Set_Is_Statically_Allocated (DT_Ptr,
7129 Is_Library_Level_Tagged_Type (Typ));
7130 end if;
9af28f61 7131
d00681a7 7132 -- Ada types
3dbca0d5 7133
d00681a7 7134 else
7135 -- Primary dispatch table containing predefined primitives
acf97c11 7136
d00681a7 7137 Predef_Prims_Ptr :=
7138 Make_Defining_Identifier (Loc,
7139 Chars => New_External_Name (Tname, 'Y'));
7140 Set_Etype (Predef_Prims_Ptr, RTE (RE_Address));
7141 Append_Elmt (Predef_Prims_Ptr, Access_Disp_Table (Typ));
24971415 7142
d00681a7 7143 -- Import the forward declaration of the Dispatch Table wrapper
d03ada96 7144 -- record (Make_DT will take care of exporting it).
24971415 7145
d00681a7 7146 if Building_Static_DT (Typ) then
7147 Set_Dispatch_Table_Wrappers (Typ, New_Elmt_List);
17e14451 7148
d00681a7 7149 DT :=
7150 Make_Defining_Identifier (Loc,
7151 Chars => New_External_Name (Tname, 'T'));
7152
7153 Import_DT (Typ, DT, Is_Secondary_DT => False);
7154
7155 if Has_DT (Typ) then
7156 Append_To (Result,
7157 Make_Object_Declaration (Loc,
7158 Defining_Identifier => DT_Ptr,
7159 Constant_Present => True,
83c6c069 7160 Object_Definition =>
7161 New_Occurrence_Of (RTE (RE_Tag), Loc),
4055a532 7162 Expression =>
d00681a7 7163 Unchecked_Convert_To (RTE (RE_Tag),
7164 Make_Attribute_Reference (Loc,
4055a532 7165 Prefix =>
d00681a7 7166 Make_Selected_Component (Loc,
83c6c069 7167 Prefix => New_Occurrence_Of (DT, Loc),
4055a532 7168 Selector_Name =>
7169 New_Occurrence_Of
7170 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
d00681a7 7171 Attribute_Name => Name_Address))));
7172
7173 -- Generate the SCIL node for the previous object declaration
7174 -- because it has a tag initialization.
7175
7176 if Generate_SCIL then
7177 New_Node :=
7178 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
7179 Set_SCIL_Entity (New_Node, Typ);
7180 Set_SCIL_Node (Last (Result), New_Node);
7181 end if;
7182
7183 Append_To (Result,
7184 Make_Object_Declaration (Loc,
7185 Defining_Identifier => Predef_Prims_Ptr,
7186 Constant_Present => True,
4055a532 7187 Object_Definition =>
83c6c069 7188 New_Occurrence_Of (RTE (RE_Address), Loc),
4055a532 7189 Expression =>
d00681a7 7190 Make_Attribute_Reference (Loc,
4055a532 7191 Prefix =>
d00681a7 7192 Make_Selected_Component (Loc,
83c6c069 7193 Prefix => New_Occurrence_Of (DT, Loc),
4055a532 7194 Selector_Name =>
7195 New_Occurrence_Of
7196 (RTE_Record_Component (RE_Predef_Prims), Loc)),
d00681a7 7197 Attribute_Name => Name_Address)));
7198
7199 -- No dispatch table required
7200
7201 else
7202 Append_To (Result,
7203 Make_Object_Declaration (Loc,
7204 Defining_Identifier => DT_Ptr,
7205 Constant_Present => True,
83c6c069 7206 Object_Definition =>
7207 New_Occurrence_Of (RTE (RE_Tag), Loc),
4055a532 7208 Expression =>
d00681a7 7209 Unchecked_Convert_To (RTE (RE_Tag),
7210 Make_Attribute_Reference (Loc,
4055a532 7211 Prefix =>
d00681a7 7212 Make_Selected_Component (Loc,
83c6c069 7213 Prefix => New_Occurrence_Of (DT, Loc),
4055a532 7214 Selector_Name =>
7215 New_Occurrence_Of
7216 (RTE_Record_Component (RE_NDT_Prims_Ptr),
7217 Loc)),
d00681a7 7218 Attribute_Name => Name_Address))));
7219 end if;
7220
7221 Set_Is_True_Constant (DT_Ptr);
7222 Set_Is_Statically_Allocated (DT_Ptr);
7223 end if;
7224 end if;
17e14451 7225
7226 -- 2) Generate the secondary tag entities
7227
d00681a7 7228 -- Collect the components associated with secondary dispatch tables
7229
a652dd51 7230 if Has_Interfaces (Typ) then
d00681a7 7231 Collect_Interface_Components (Typ, Typ_Comps);
f301a57b 7232
d03ada96 7233 -- For each interface type we build a unique external name associated
7234 -- with its secondary dispatch table. This name is used to declare an
7235 -- object that references this secondary dispatch table, whose value
7236 -- will be used for the elaboration of Typ objects, and also for the
7237 -- elaboration of objects of types derived from Typ that do not
7238 -- override the primitives of this interface type.
f301a57b 7239
7240 Suffix_Index := 1;
17e14451 7241
02a2406d 7242 -- Note: The value of Suffix_Index must be in sync with the values of
7243 -- Suffix_Index in secondary dispatch tables generated by Make_DT.
17e14451 7244
d00681a7 7245 if Is_CPP_Class (Typ) then
7246 AI_Tag_Comp := First_Elmt (Typ_Comps);
7247 while Present (AI_Tag_Comp) loop
7248 Get_Secondary_DT_External_Name
7249 (Typ, Related_Type (Node (AI_Tag_Comp)), Suffix_Index);
7250 Typ_Name := Name_Find;
17e14451 7251
02a2406d 7252 -- Declare variables to store copy of the C++ secondary tags
f301a57b 7253
d00681a7 7254 Iface_DT_Ptr :=
7255 Make_Defining_Identifier (Loc,
7256 Chars => New_External_Name (Typ_Name, 'P'));
7257 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
7258 Set_Ekind (Iface_DT_Ptr, E_Variable);
7259 Set_Is_Tag (Iface_DT_Ptr);
acf97c11 7260
d00681a7 7261 Set_Has_Thunks (Iface_DT_Ptr);
7262 Set_Related_Type
7263 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7264 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
cdb1c38f 7265
f301a57b 7266 Append_To (Result,
7267 Make_Object_Declaration (Loc,
7268 Defining_Identifier => Iface_DT_Ptr,
83c6c069 7269 Object_Definition => New_Occurrence_Of
f301a57b 7270 (RTE (RE_Interface_Tag), Loc),
7271 Expression =>
7272 Unchecked_Convert_To (RTE (RE_Interface_Tag),
83c6c069 7273 New_Occurrence_Of (RTE (RE_Null_Address), Loc))));
f301a57b 7274
d00681a7 7275 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7276 Is_Library_Level_Tagged_Type (Typ));
acf97c11 7277
d00681a7 7278 Next_Elmt (AI_Tag_Comp);
7279 end loop;
acf97c11 7280
d00681a7 7281 -- This is not a CPP_Class type
acf97c11 7282
d00681a7 7283 else
7284 AI_Tag_Comp := First_Elmt (Typ_Comps);
7285 while Present (AI_Tag_Comp) loop
7286 Get_Secondary_DT_External_Name
7287 (Typ, Related_Type (Node (AI_Tag_Comp)), Suffix_Index);
7288 Typ_Name := Name_Find;
17e14451 7289
d00681a7 7290 if Building_Static_DT (Typ) then
7291 Iface_DT :=
7292 Make_Defining_Identifier (Loc,
7293 Chars => New_External_Name
7294 (Typ_Name, 'T', Suffix_Index => -1));
7295 Import_DT
7296 (Tag_Typ => Related_Type (Node (AI_Tag_Comp)),
7297 DT => Iface_DT,
7298 Is_Secondary_DT => True);
7299 end if;
acf97c11 7300
d00681a7 7301 -- Secondary dispatch table referencing thunks to user-defined
7302 -- primitives covered by this interface.
acf97c11 7303
d00681a7 7304 Iface_DT_Ptr :=
7305 Make_Defining_Identifier (Loc,
7306 Chars => New_External_Name (Typ_Name, 'P'));
7307 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
7308 Set_Ekind (Iface_DT_Ptr, E_Constant);
7309 Set_Is_Tag (Iface_DT_Ptr);
7310 Set_Has_Thunks (Iface_DT_Ptr);
7311 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7312 Is_Library_Level_Tagged_Type (Typ));
7313 Set_Is_True_Constant (Iface_DT_Ptr);
7314 Set_Related_Type
7315 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7316 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
7317
7318 if Building_Static_DT (Typ) then
7319 Append_To (Result,
7320 Make_Object_Declaration (Loc,
7321 Defining_Identifier => Iface_DT_Ptr,
7322 Constant_Present => True,
83c6c069 7323 Object_Definition => New_Occurrence_Of
d00681a7 7324 (RTE (RE_Interface_Tag), Loc),
4055a532 7325 Expression =>
d00681a7 7326 Unchecked_Convert_To (RTE (RE_Interface_Tag),
7327 Make_Attribute_Reference (Loc,
4055a532 7328 Prefix =>
d00681a7 7329 Make_Selected_Component (Loc,
4055a532 7330 Prefix =>
83c6c069 7331 New_Occurrence_Of (Iface_DT, Loc),
4055a532 7332 Selector_Name =>
7333 New_Occurrence_Of
7334 (RTE_Record_Component (RE_Prims_Ptr),
7335 Loc)),
d00681a7 7336 Attribute_Name => Name_Address))));
7337 end if;
7338
7339 -- Secondary dispatch table referencing thunks to predefined
7340 -- primitives.
7341
7342 Iface_DT_Ptr :=
7343 Make_Defining_Identifier (Loc,
7344 Chars => New_External_Name (Typ_Name, 'Y'));
7345 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
7346 Set_Ekind (Iface_DT_Ptr, E_Constant);
7347 Set_Is_Tag (Iface_DT_Ptr);
7348 Set_Has_Thunks (Iface_DT_Ptr);
7349 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7350 Is_Library_Level_Tagged_Type (Typ));
7351 Set_Is_True_Constant (Iface_DT_Ptr);
7352 Set_Related_Type
7353 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7354 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
7355
7356 -- Secondary dispatch table referencing user-defined primitives
7357 -- covered by this interface.
7358
7359 Iface_DT_Ptr :=
7360 Make_Defining_Identifier (Loc,
7361 Chars => New_External_Name (Typ_Name, 'D'));
7362 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
7363 Set_Ekind (Iface_DT_Ptr, E_Constant);
7364 Set_Is_Tag (Iface_DT_Ptr);
7365 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7366 Is_Library_Level_Tagged_Type (Typ));
7367 Set_Is_True_Constant (Iface_DT_Ptr);
7368 Set_Related_Type
7369 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7370 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
7371
7372 -- Secondary dispatch table referencing predefined primitives
7373
7374 Iface_DT_Ptr :=
7375 Make_Defining_Identifier (Loc,
7376 Chars => New_External_Name (Typ_Name, 'Z'));
7377 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
7378 Set_Ekind (Iface_DT_Ptr, E_Constant);
7379 Set_Is_Tag (Iface_DT_Ptr);
7380 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7381 Is_Library_Level_Tagged_Type (Typ));
7382 Set_Is_True_Constant (Iface_DT_Ptr);
7383 Set_Related_Type
7384 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7385 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
7386
7387 Next_Elmt (AI_Tag_Comp);
7388 end loop;
7389 end if;
17e14451 7390 end if;
7391
dffd0a90 7392 -- 3) At the end of Access_Disp_Table, if the type has user-defined
7393 -- primitives, we add the entity of an access type declaration that
7394 -- is used by Build_Get_Prim_Op_Address to expand dispatching calls
7395 -- through the primary dispatch table.
7396
7397 if UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ))) = 0 then
7398 Analyze_List (Result);
17e14451 7399
7400 -- Generate:
cc60bd16 7401 -- type Typ_DT is array (1 .. Nb_Prims) of Prim_Ptr;
17e14451 7402 -- type Typ_DT_Acc is access Typ_DT;
7403
dffd0a90 7404 else
7405 declare
7406 Name_DT_Prims : constant Name_Id :=
7407 New_External_Name (Tname, 'G');
7408 Name_DT_Prims_Acc : constant Name_Id :=
7409 New_External_Name (Tname, 'H');
7410 DT_Prims : constant Entity_Id :=
7411 Make_Defining_Identifier (Loc,
7412 Name_DT_Prims);
7413 DT_Prims_Acc : constant Entity_Id :=
7414 Make_Defining_Identifier (Loc,
7415 Name_DT_Prims_Acc);
7416 begin
7417 Append_To (Result,
7418 Make_Full_Type_Declaration (Loc,
7419 Defining_Identifier => DT_Prims,
7420 Type_Definition =>
7421 Make_Constrained_Array_Definition (Loc,
7422 Discrete_Subtype_Definitions => New_List (
7423 Make_Range (Loc,
7424 Low_Bound => Make_Integer_Literal (Loc, 1),
7425 High_Bound => Make_Integer_Literal (Loc,
7426 DT_Entry_Count
7427 (First_Tag_Component (Typ))))),
7428 Component_Definition =>
7429 Make_Component_Definition (Loc,
7430 Subtype_Indication =>
83c6c069 7431 New_Occurrence_Of (RTE (RE_Prim_Ptr), Loc)))));
17e14451 7432
dffd0a90 7433 Append_To (Result,
7434 Make_Full_Type_Declaration (Loc,
7435 Defining_Identifier => DT_Prims_Acc,
7436 Type_Definition =>
7437 Make_Access_To_Object_Definition (Loc,
7438 Subtype_Indication =>
7439 New_Occurrence_Of (DT_Prims, Loc))));
17e14451 7440
dffd0a90 7441 Append_Elmt (DT_Prims_Acc, Access_Disp_Table (Typ));
17e14451 7442
dffd0a90 7443 -- Analyze the resulting list and suppress the generation of the
7444 -- Init_Proc associated with the above array declaration because
7445 -- this type is never used in object declarations. It is only used
7446 -- to simplify the expansion associated with dispatching calls.
17e14451 7447
dffd0a90 7448 Analyze_List (Result);
649455a4 7449 Set_Suppress_Initialization (Base_Type (DT_Prims));
cc60bd16 7450
ff6293ec 7451 -- Disable backend optimizations based on assumptions about the
7452 -- aliasing status of objects designated by the access to the
7453 -- dispatch table. Required to handle dispatch tables imported
7454 -- from C++.
7455
7456 Set_No_Strict_Aliasing (Base_Type (DT_Prims_Acc));
7457
d00681a7 7458 -- Add the freezing nodes of these declarations; required to avoid
7459 -- generating these freezing nodes in wrong scopes (for example in
7460 -- the IC routine of a derivation of Typ).
02a2406d 7461
d03ada96 7462 -- What is an "IC routine"? Is "init_proc" meant here???
d00681a7 7463
d74fc39a 7464 Append_List_To (Result, Freeze_Entity (DT_Prims, Typ));
7465 Append_List_To (Result, Freeze_Entity (DT_Prims_Acc, Typ));
d00681a7 7466
dffd0a90 7467 -- Mark entity of dispatch table. Required by the back end to
7468 -- handle them properly.
cc60bd16 7469
dffd0a90 7470 Set_Is_Dispatch_Table_Entity (DT_Prims);
7471 end;
7472 end if;
17e14451 7473
11bd2f46 7474 -- Mark entities of dispatch table. Required by the back end to handle
7475 -- them properly.
7640ed3d 7476
7477 if Present (DT) then
7478 Set_Is_Dispatch_Table_Entity (DT);
7479 Set_Is_Dispatch_Table_Entity (Etype (DT));
7480 end if;
7481
d04be62f 7482 if Present (Iface_DT) then
7483 Set_Is_Dispatch_Table_Entity (Iface_DT);
7484 Set_Is_Dispatch_Table_Entity (Etype (Iface_DT));
7485 end if;
7486
d00681a7 7487 if Is_CPP_Class (Root_Type (Typ)) then
7488 Set_Ekind (DT_Ptr, E_Variable);
7489 else
7490 Set_Ekind (DT_Ptr, E_Constant);
7491 end if;
7492
cdb1c38f 7493 Set_Is_Tag (DT_Ptr);
7494 Set_Related_Type (DT_Ptr, Typ);
7495
17e14451 7496 return Result;
7497 end Make_Tags;
7498
cd534f03 7499 ---------------
7500 -- New_Value --
7501 ---------------
7502
7503 function New_Value (From : Node_Id) return Node_Id is
7504 Res : constant Node_Id := Duplicate_Subexpr (From);
7505 begin
7506 if Is_Access_Type (Etype (From)) then
02a2406d 7507 return Make_Explicit_Dereference (Sloc (From), Prefix => Res);
cd534f03 7508 else
7509 return Res;
7510 end if;
7511 end New_Value;
7512
ee6ba406 7513 -----------------------------------
7514 -- Original_View_In_Visible_Part --
7515 -----------------------------------
7516
7517 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
7518 Scop : constant Entity_Id := Scope (Typ);
7519
7520 begin
7521 -- The scope must be a package
7522
65149aa0 7523 if not Is_Package_Or_Generic_Package (Scop) then
ee6ba406 7524 return False;
7525 end if;
7526
7527 -- A type with a private declaration has a private view declared in
7528 -- the visible part.
7529
7530 if Has_Private_Declaration (Typ) then
7531 return True;
7532 end if;
7533
7534 return List_Containing (Parent (Typ)) =
e8b4793a 7535 Visible_Declarations (Package_Specification (Scop));
ee6ba406 7536 end Original_View_In_Visible_Part;
7537
d62940bf 7538 ------------------
7539 -- Prim_Op_Kind --
7540 ------------------
7541
7542 function Prim_Op_Kind
7543 (Prim : Entity_Id;
7544 Typ : Entity_Id) return Node_Id
7545 is
7546 Full_Typ : Entity_Id := Typ;
7547 Loc : constant Source_Ptr := Sloc (Prim);
68f95949 7548 Prim_Op : Entity_Id;
d62940bf 7549
7550 begin
7551 -- Retrieve the original primitive operation
7552
fc2907f6 7553 Prim_Op := Ultimate_Alias (Prim);
d62940bf 7554
7555 if Ekind (Typ) = E_Record_Type
7556 and then Present (Corresponding_Concurrent_Type (Typ))
7557 then
7558 Full_Typ := Corresponding_Concurrent_Type (Typ);
7559 end if;
7560
d77e048b 7561 -- When a private tagged type is completed by a concurrent type,
7562 -- retrieve the full view.
7563
7564 if Is_Private_Type (Full_Typ) then
7565 Full_Typ := Full_View (Full_Typ);
7566 end if;
7567
d62940bf 7568 if Ekind (Prim_Op) = E_Function then
7569
7570 -- Protected function
7571
7572 if Ekind (Full_Typ) = E_Protected_Type then
83c6c069 7573 return New_Occurrence_Of (RTE (RE_POK_Protected_Function), Loc);
d62940bf 7574
76a1c25b 7575 -- Task function
7576
7577 elsif Ekind (Full_Typ) = E_Task_Type then
83c6c069 7578 return New_Occurrence_Of (RTE (RE_POK_Task_Function), Loc);
76a1c25b 7579
d62940bf 7580 -- Regular function
7581
7582 else
83c6c069 7583 return New_Occurrence_Of (RTE (RE_POK_Function), Loc);
d62940bf 7584 end if;
7585
7586 else
7587 pragma Assert (Ekind (Prim_Op) = E_Procedure);
7588
7589 if Ekind (Full_Typ) = E_Protected_Type then
7590
7591 -- Protected entry
7592
7593 if Is_Primitive_Wrapper (Prim_Op)
7594 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
7595 then
83c6c069 7596 return New_Occurrence_Of (RTE (RE_POK_Protected_Entry), Loc);
d62940bf 7597
7598 -- Protected procedure
7599
7600 else
83c6c069 7601 return
7602 New_Occurrence_Of (RTE (RE_POK_Protected_Procedure), Loc);
d62940bf 7603 end if;
7604
7605 elsif Ekind (Full_Typ) = E_Task_Type then
7606
7607 -- Task entry
7608
7609 if Is_Primitive_Wrapper (Prim_Op)
7610 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
7611 then
83c6c069 7612 return New_Occurrence_Of (RTE (RE_POK_Task_Entry), Loc);
d62940bf 7613
7614 -- Task "procedure". These are the internally Expander-generated
7615 -- procedures (task body for instance).
7616
7617 else
83c6c069 7618 return New_Occurrence_Of (RTE (RE_POK_Task_Procedure), Loc);
d62940bf 7619 end if;
7620
7621 -- Regular procedure
7622
7623 else
83c6c069 7624 return New_Occurrence_Of (RTE (RE_POK_Procedure), Loc);
d62940bf 7625 end if;
7626 end if;
7627 end Prim_Op_Kind;
7628
725a69d2 7629 ------------------------
7630 -- Register_Primitive --
7631 ------------------------
7632
49260fa5 7633 function Register_Primitive
725a69d2 7634 (Loc : Source_Ptr;
49260fa5 7635 Prim : Entity_Id) return List_Id
725a69d2 7636 is
cdb1c38f 7637 DT_Ptr : Entity_Id;
7638 Iface_Prim : Entity_Id;
7639 Iface_Typ : Entity_Id;
7640 Iface_DT_Ptr : Entity_Id;
7641 Iface_DT_Elmt : Elmt_Id;
49260fa5 7642 L : constant List_Id := New_List;
cdb1c38f 7643 Pos : Uint;
7644 Tag : Entity_Id;
cc60bd16 7645 Tag_Typ : Entity_Id;
cdb1c38f 7646 Thunk_Id : Entity_Id;
7647 Thunk_Code : Node_Id;
725a69d2 7648
7649 begin
7650 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
79500ea0 7651 pragma Assert (VM_Target = No_VM);
725a69d2 7652
3f8cf2d2 7653 -- Do not register in the dispatch table eliminated primitives
7654
7655 if not RTE_Available (RE_Tag)
7656 or else Is_Eliminated (Ultimate_Alias (Prim))
7657 then
49260fa5 7658 return L;
725a69d2 7659 end if;
7660
a652dd51 7661 if not Present (Interface_Alias (Prim)) then
cc60bd16 7662 Tag_Typ := Scope (DTC_Entity (Prim));
acf97c11 7663 Pos := DT_Position (Prim);
cc60bd16 7664 Tag := First_Tag_Component (Tag_Typ);
725a69d2 7665
7666 if Is_Predefined_Dispatching_Operation (Prim)
7667 or else Is_Predefined_Dispatching_Alias (Prim)
7668 then
cc60bd16 7669 DT_Ptr :=
7670 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Tag_Typ))));
7671
49260fa5 7672 Append_To (L,
725a69d2 7673 Build_Set_Predefined_Prim_Op_Address (Loc,
83c6c069 7674 Tag_Node => New_Occurrence_Of (DT_Ptr, Loc),
725a69d2 7675 Position => Pos,
acf97c11 7676 Address_Node =>
cc60bd16 7677 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
acf97c11 7678 Make_Attribute_Reference (Loc,
83c6c069 7679 Prefix => New_Occurrence_Of (Prim, Loc),
acf97c11 7680 Attribute_Name => Name_Unrestricted_Access))));
725a69d2 7681
9e7de1e1 7682 -- Register copy of the pointer to the 'size primitive in the TSD
cc60bd16 7683
7684 if Chars (Prim) = Name_uSize
7685 and then RTE_Record_Component_Available (RE_Size_Func)
7686 then
7687 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
49260fa5 7688 Append_To (L,
cc60bd16 7689 Build_Set_Size_Function (Loc,
83c6c069 7690 Tag_Node => New_Occurrence_Of (DT_Ptr, Loc),
cc60bd16 7691 Size_Func => Prim));
7692 end if;
7693
725a69d2 7694 else
7695 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
7696
d00681a7 7697 -- Skip registration of primitives located in the C++ part of the
7698 -- dispatch table. Their slot is set by the IC routine.
7699
7700 if not Is_CPP_Class (Root_Type (Tag_Typ))
7701 or else Pos > CPP_Num_Prims (Tag_Typ)
7702 then
7703 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
7704 Append_To (L,
7705 Build_Set_Prim_Op_Address (Loc,
7706 Typ => Tag_Typ,
83c6c069 7707 Tag_Node => New_Occurrence_Of (DT_Ptr, Loc),
d00681a7 7708 Position => Pos,
7709 Address_Node =>
7710 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
7711 Make_Attribute_Reference (Loc,
83c6c069 7712 Prefix => New_Occurrence_Of (Prim, Loc),
d00681a7 7713 Attribute_Name => Name_Unrestricted_Access))));
7714 end if;
725a69d2 7715 end if;
7716
7717 -- Ada 2005 (AI-251): Primitive associated with an interface type
02a2406d 7718
725a69d2 7719 -- Generate the code of the thunk only if the interface type is not an
7720 -- immediate ancestor of Typ; otherwise the dispatch table associated
7721 -- with the interface is the primary dispatch table and we have nothing
7722 -- else to do here.
7723
7724 else
cc60bd16 7725 Tag_Typ := Find_Dispatching_Type (Alias (Prim));
a652dd51 7726 Iface_Typ := Find_Dispatching_Type (Interface_Alias (Prim));
725a69d2 7727
7728 pragma Assert (Is_Interface (Iface_Typ));
7729
c8da6114 7730 -- No action needed for interfaces that are ancestors of Typ because
7731 -- their primitives are located in the primary dispatch table.
7732
cb4af01d 7733 if Is_Ancestor (Iface_Typ, Tag_Typ, Use_Full_View => True) then
c8da6114 7734 return L;
d00681a7 7735
7736 -- No action needed for primitives located in the C++ part of the
7737 -- dispatch table. Their slot is set by the IC routine.
7738
7739 elsif Is_CPP_Class (Root_Type (Tag_Typ))
7740 and then DT_Position (Alias (Prim)) <= CPP_Num_Prims (Tag_Typ)
7741 and then not Is_Predefined_Dispatching_Operation (Prim)
7742 and then not Is_Predefined_Dispatching_Alias (Prim)
7743 then
7744 return L;
c8da6114 7745 end if;
7746
17e14451 7747 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
725a69d2 7748
cb4af01d 7749 if not Is_Ancestor (Iface_Typ, Tag_Typ, Use_Full_View => True)
725a69d2 7750 and then Present (Thunk_Code)
7751 then
725a69d2 7752 -- Generate the code necessary to fill the appropriate entry of
7753 -- the secondary dispatch table of Prim's controlling type with
7754 -- Thunk_Id's address.
7755
cc60bd16 7756 Iface_DT_Elmt := Find_Interface_ADT (Tag_Typ, Iface_Typ);
cdb1c38f 7757 Iface_DT_Ptr := Node (Iface_DT_Elmt);
7758 pragma Assert (Has_Thunks (Iface_DT_Ptr));
7759
a652dd51 7760 Iface_Prim := Interface_Alias (Prim);
acf97c11 7761 Pos := DT_Position (Iface_Prim);
7762 Tag := First_Tag_Component (Iface_Typ);
49260fa5 7763
7764 Prepend_To (L, Thunk_Code);
725a69d2 7765
7766 if Is_Predefined_Dispatching_Operation (Prim)
7767 or else Is_Predefined_Dispatching_Alias (Prim)
7768 then
cdb1c38f 7769 Append_To (L,
725a69d2 7770 Build_Set_Predefined_Prim_Op_Address (Loc,
acf97c11 7771 Tag_Node =>
83c6c069 7772 New_Occurrence_Of (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
725a69d2 7773 Position => Pos,
7774 Address_Node =>
cc60bd16 7775 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
acf97c11 7776 Make_Attribute_Reference (Loc,
83c6c069 7777 Prefix => New_Occurrence_Of (Thunk_Id, Loc),
acf97c11 7778 Attribute_Name => Name_Unrestricted_Access))));
cdb1c38f 7779
acf97c11 7780 Next_Elmt (Iface_DT_Elmt);
cdb1c38f 7781 Next_Elmt (Iface_DT_Elmt);
7782 Iface_DT_Ptr := Node (Iface_DT_Elmt);
7783 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
7784
7785 Append_To (L,
7786 Build_Set_Predefined_Prim_Op_Address (Loc,
acf97c11 7787 Tag_Node =>
83c6c069 7788 New_Occurrence_Of (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
cdb1c38f 7789 Position => Pos,
7790 Address_Node =>
cc60bd16 7791 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
acf97c11 7792 Make_Attribute_Reference (Loc,
4055a532 7793 Prefix =>
83c6c069 7794 New_Occurrence_Of (Alias (Prim), Loc),
acf97c11 7795 Attribute_Name => Name_Unrestricted_Access))));
cdb1c38f 7796
725a69d2 7797 else
7798 pragma Assert (Pos /= Uint_0
7799 and then Pos <= DT_Entry_Count (Tag));
7800
cdb1c38f 7801 Append_To (L,
7802 Build_Set_Prim_Op_Address (Loc,
7803 Typ => Iface_Typ,
83c6c069 7804 Tag_Node => New_Occurrence_Of (Iface_DT_Ptr, Loc),
cdb1c38f 7805 Position => Pos,
acf97c11 7806 Address_Node =>
cc60bd16 7807 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
acf97c11 7808 Make_Attribute_Reference (Loc,
83c6c069 7809 Prefix => New_Occurrence_Of (Thunk_Id, Loc),
acf97c11 7810 Attribute_Name => Name_Unrestricted_Access))));
cdb1c38f 7811
acf97c11 7812 Next_Elmt (Iface_DT_Elmt);
cdb1c38f 7813 Next_Elmt (Iface_DT_Elmt);
7814 Iface_DT_Ptr := Node (Iface_DT_Elmt);
7815 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
7816
7817 Append_To (L,
725a69d2 7818 Build_Set_Prim_Op_Address (Loc,
7819 Typ => Iface_Typ,
83c6c069 7820 Tag_Node => New_Occurrence_Of (Iface_DT_Ptr, Loc),
725a69d2 7821 Position => Pos,
acf97c11 7822 Address_Node =>
cc60bd16 7823 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
acf97c11 7824 Make_Attribute_Reference (Loc,
4055a532 7825 Prefix =>
83c6c069 7826 New_Occurrence_Of (Alias (Prim), Loc),
acf97c11 7827 Attribute_Name => Name_Unrestricted_Access))));
cdb1c38f 7828
725a69d2 7829 end if;
7830 end if;
7831 end if;
49260fa5 7832
7833 return L;
725a69d2 7834 end Register_Primitive;
7835
ee6ba406 7836 -------------------------
7837 -- Set_All_DT_Position --
7838 -------------------------
7839
7840 procedure Set_All_DT_Position (Typ : Entity_Id) is
ee6ba406 7841
cf365b48 7842 function In_Predef_Prims_DT (Prim : Entity_Id) return Boolean;
7843 -- Returns True if Prim is located in the dispatch table of
7844 -- predefined primitives
7845
aad6babd 7846 procedure Validate_Position (Prim : Entity_Id);
02a2406d 7847 -- Check that position assigned to Prim is completely safe (it has not
7848 -- been assigned to a previously defined primitive operation of Typ).
aad6babd 7849
cf365b48 7850 ------------------------
7851 -- In_Predef_Prims_DT --
7852 ------------------------
7853
7854 function In_Predef_Prims_DT (Prim : Entity_Id) return Boolean is
7855 E : Entity_Id;
7856
7857 begin
7858 -- Predefined primitives
7859
7860 if Is_Predefined_Dispatching_Operation (Prim) then
7861 return True;
7862
7863 -- Renamings of predefined primitives
7864
7865 elsif Present (Alias (Prim))
7866 and then Is_Predefined_Dispatching_Operation (Ultimate_Alias (Prim))
7867 then
7868 if Chars (Ultimate_Alias (Prim)) /= Name_Op_Eq then
7869 return True;
7870
7871 -- User-defined renamings of predefined equality have their own
7872 -- slot in the primary dispatch table
7873
7874 else
7875 E := Prim;
7876 while Present (Alias (E)) loop
7877 if Comes_From_Source (E) then
7878 return False;
7879 end if;
7880
7881 E := Alias (E);
7882 end loop;
7883
7884 return not Comes_From_Source (E);
7885 end if;
7886
7887 -- User-defined primitives
7888
7889 else
7890 return False;
7891 end if;
7892 end In_Predef_Prims_DT;
7893
aad6babd 7894 -----------------------
7895 -- Validate_Position --
7896 -----------------------
7897
7898 procedure Validate_Position (Prim : Entity_Id) is
af647dc7 7899 Op_Elmt : Elmt_Id;
7900 Op : Entity_Id;
d62940bf 7901
aad6babd 7902 begin
af647dc7 7903 -- Aliased primitives are safe
7904
7905 if Present (Alias (Prim)) then
7906 return;
7907 end if;
7908
7909 Op_Elmt := First_Elmt (Primitive_Operations (Typ));
7910 while Present (Op_Elmt) loop
7911 Op := Node (Op_Elmt);
7912
7913 -- No need to check against itself
7914
7915 if Op = Prim then
7916 null;
7917
aad6babd 7918 -- Primitive operations covering abstract interfaces are
7919 -- allocated later
7920
a652dd51 7921 elsif Present (Interface_Alias (Op)) then
aad6babd 7922 null;
7923
68f95949 7924 -- Predefined dispatching operations are completely safe. They
7925 -- are allocated at fixed positions in a separate table.
aad6babd 7926
af647dc7 7927 elsif Is_Predefined_Dispatching_Operation (Op)
7928 or else Is_Predefined_Dispatching_Alias (Op)
7929 then
aad6babd 7930 null;
ee6ba406 7931
aad6babd 7932 -- Aliased subprograms are safe
7933
af647dc7 7934 elsif Present (Alias (Op)) then
aad6babd 7935 null;
7936
af647dc7 7937 elsif DT_Position (Op) = DT_Position (Prim)
7938 and then not Is_Predefined_Dispatching_Operation (Op)
7939 and then not Is_Predefined_Dispatching_Operation (Prim)
7940 and then not Is_Predefined_Dispatching_Alias (Op)
7941 and then not Is_Predefined_Dispatching_Alias (Prim)
7942 then
d62940bf 7943 -- Handle aliased subprograms
7944
7945 declare
7946 Op_1 : Entity_Id;
7947 Op_2 : Entity_Id;
7948
7949 begin
af647dc7 7950 Op_1 := Op;
d62940bf 7951 loop
7952 if Present (Overridden_Operation (Op_1)) then
7953 Op_1 := Overridden_Operation (Op_1);
7954 elsif Present (Alias (Op_1)) then
7955 Op_1 := Alias (Op_1);
7956 else
7957 exit;
7958 end if;
7959 end loop;
7960
7961 Op_2 := Prim;
7962 loop
7963 if Present (Overridden_Operation (Op_2)) then
7964 Op_2 := Overridden_Operation (Op_2);
7965 elsif Present (Alias (Op_2)) then
7966 Op_2 := Alias (Op_2);
7967 else
7968 exit;
7969 end if;
7970 end loop;
7971
7972 if Op_1 /= Op_2 then
7973 raise Program_Error;
7974 end if;
7975 end;
aad6babd 7976 end if;
7977
af647dc7 7978 Next_Elmt (Op_Elmt);
aad6babd 7979 end loop;
7980 end Validate_Position;
7981
af647dc7 7982 -- Local variables
7983
7984 Parent_Typ : constant Entity_Id := Etype (Typ);
af647dc7 7985 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
7986 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
7987
651a38ec 7988 Adjusted : Boolean := False;
7989 Finalized : Boolean := False;
af647dc7 7990
343d35dc 7991 Count_Prim : Nat;
7992 DT_Length : Nat;
7993 Nb_Prim : Nat;
af647dc7 7994 Prim : Entity_Id;
7995 Prim_Elmt : Elmt_Id;
7996
aad6babd 7997 -- Start of processing for Set_All_DT_Position
7998
7999 begin
a652dd51 8000 pragma Assert (Present (First_Tag_Component (Typ)));
8001
b3dd22b3 8002 -- Set the DT_Position for each primitive operation. Perform some sanity
8003 -- checks to avoid building inconsistent dispatch tables.
ee6ba406 8004
02a2406d 8005 -- First stage: Set DTC entity of all the primitive operations. This is
8006 -- required to properly read the DT_Position attribute in latter stages.
ee6ba406 8007
343d35dc 8008 Prim_Elmt := First_Prim;
8009 Count_Prim := 0;
8010 while Present (Prim_Elmt) loop
8011 Prim := Node (Prim_Elmt);
ee6ba406 8012
343d35dc 8013 -- Predefined primitives have a separate dispatch table
ee6ba406 8014
cf365b48 8015 if not In_Predef_Prims_DT (Prim) then
343d35dc 8016 Count_Prim := Count_Prim + 1;
8017 end if;
ee6ba406 8018
725a69d2 8019 Set_DTC_Entity_Value (Typ, Prim);
ee6ba406 8020
343d35dc 8021 -- Clear any previous value of the DT_Position attribute. In this
8022 -- way we ensure that the final position of all the primitives is
36b938a3 8023 -- established by the following stages of this algorithm.
ee6ba406 8024
ad274a73 8025 Set_DT_Position_Value (Prim, No_Uint);
ee6ba406 8026
343d35dc 8027 Next_Elmt (Prim_Elmt);
8028 end loop;
ee6ba406 8029
343d35dc 8030 declare
acf97c11 8031 Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean :=
8032 (others => False);
8033
343d35dc 8034 E : Entity_Id;
ee6ba406 8035
725a69d2 8036 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id);
8037 -- Called if Typ is declared in a nested package or a public child
8038 -- package to handle inherited primitives that were inherited by Typ
509f74d3 8039 -- in the visible part, but whose declaration was deferred because
725a69d2 8040 -- the parent operation was private and not visible at that point.
8041
343d35dc 8042 procedure Set_Fixed_Prim (Pos : Nat);
8043 -- Sets to true an element of the Fixed_Prim table to indicate
8044 -- that this entry of the dispatch table of Typ is occupied.
ee6ba406 8045
725a69d2 8046 ------------------------------------------
8047 -- Handle_Inherited_Private_Subprograms --
8048 ------------------------------------------
8049
8050 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id) is
8051 Op_List : Elist_Id;
8052 Op_Elmt : Elmt_Id;
8053 Op_Elmt_2 : Elmt_Id;
8054 Prim_Op : Entity_Id;
8055 Parent_Subp : Entity_Id;
8056
8057 begin
8058 Op_List := Primitive_Operations (Typ);
8059
8060 Op_Elmt := First_Elmt (Op_List);
8061 while Present (Op_Elmt) loop
8062 Prim_Op := Node (Op_Elmt);
8063
8064 -- Search primitives that are implicit operations with an
8065 -- internal name whose parent operation has a normal name.
8066
8067 if Present (Alias (Prim_Op))
8068 and then Find_Dispatching_Type (Alias (Prim_Op)) /= Typ
8069 and then not Comes_From_Source (Prim_Op)
8070 and then Is_Internal_Name (Chars (Prim_Op))
8071 and then not Is_Internal_Name (Chars (Alias (Prim_Op)))
8072 then
8073 Parent_Subp := Alias (Prim_Op);
8074
8075 -- Check if the type has an explicit overriding for this
8076 -- primitive.
8077
8078 Op_Elmt_2 := Next_Elmt (Op_Elmt);
8079 while Present (Op_Elmt_2) loop
8080 if Chars (Node (Op_Elmt_2)) = Chars (Parent_Subp)
8081 and then Type_Conformant (Prim_Op, Node (Op_Elmt_2))
8082 then
ad274a73 8083 Set_DT_Position_Value (Prim_Op,
8084 DT_Position (Parent_Subp));
8085 Set_DT_Position_Value (Node (Op_Elmt_2),
725a69d2 8086 DT_Position (Parent_Subp));
8087 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim_Op)));
8088
8089 goto Next_Primitive;
8090 end if;
8091
8092 Next_Elmt (Op_Elmt_2);
8093 end loop;
8094 end if;
8095
8096 <<Next_Primitive>>
8097 Next_Elmt (Op_Elmt);
8098 end loop;
8099 end Handle_Inherited_Private_Subprograms;
8100
343d35dc 8101 --------------------
8102 -- Set_Fixed_Prim --
8103 --------------------
ee6ba406 8104
343d35dc 8105 procedure Set_Fixed_Prim (Pos : Nat) is
ee6ba406 8106 begin
9e7de1e1 8107 pragma Assert (Pos <= Count_Prim);
343d35dc 8108 Fixed_Prim (Pos) := True;
8109 exception
8110 when Constraint_Error =>
8111 raise Program_Error;
8112 end Set_Fixed_Prim;
ee6ba406 8113
343d35dc 8114 begin
725a69d2 8115 -- In case of nested packages and public child package it may be
8116 -- necessary a special management on inherited subprograms so that
8117 -- the dispatch table is properly filled.
8118
8119 if Ekind (Scope (Scope (Typ))) = E_Package
8120 and then Scope (Scope (Typ)) /= Standard_Standard
8121 and then ((Is_Derived_Type (Typ) and then not Is_Private_Type (Typ))
8122 or else
8123 (Nkind (Parent (Typ)) = N_Private_Extension_Declaration
8124 and then Is_Generic_Type (Typ)))
8125 and then In_Open_Scopes (Scope (Etype (Typ)))
5b990e08 8126 and then Is_Base_Type (Typ)
725a69d2 8127 then
8128 Handle_Inherited_Private_Subprograms (Typ);
8129 end if;
8130
343d35dc 8131 -- Second stage: Register fixed entries
ee6ba406 8132
343d35dc 8133 Nb_Prim := 0;
8134 Prim_Elmt := First_Prim;
8135 while Present (Prim_Elmt) loop
8136 Prim := Node (Prim_Elmt);
ee6ba406 8137
343d35dc 8138 -- Predefined primitives have a separate table and all its
8139 -- entries are at predefined fixed positions.
ee6ba406 8140
cf365b48 8141 if In_Predef_Prims_DT (Prim) then
8142 if Is_Predefined_Dispatching_Operation (Prim) then
ad274a73 8143 Set_DT_Position_Value (Prim,
8144 Default_Prim_Op_Position (Prim));
ee6ba406 8145
cf365b48 8146 else pragma Assert (Present (Alias (Prim)));
ad274a73 8147 Set_DT_Position_Value (Prim,
cf365b48 8148 Default_Prim_Op_Position (Ultimate_Alias (Prim)));
8149 end if;
d62940bf 8150
343d35dc 8151 -- Overriding primitives of ancestor abstract interfaces
ee6ba406 8152
a652dd51 8153 elsif Present (Interface_Alias (Prim))
8154 and then Is_Ancestor
cb4af01d 8155 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ,
8156 Use_Full_View => True)
343d35dc 8157 then
8158 pragma Assert (DT_Position (Prim) = No_Uint
a652dd51 8159 and then Present (DTC_Entity (Interface_Alias (Prim))));
ee6ba406 8160
a652dd51 8161 E := Interface_Alias (Prim);
ad274a73 8162 Set_DT_Position_Value (Prim, DT_Position (E));
aad6babd 8163
343d35dc 8164 pragma Assert
8165 (DT_Position (Alias (Prim)) = No_Uint
8166 or else DT_Position (Alias (Prim)) = DT_Position (E));
ad274a73 8167 Set_DT_Position_Value (Alias (Prim), DT_Position (E));
343d35dc 8168 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));
af647dc7 8169
343d35dc 8170 -- Overriding primitives must use the same entry as the
36b938a3 8171 -- overridden primitive.
af647dc7 8172
a652dd51 8173 elsif not Present (Interface_Alias (Prim))
343d35dc 8174 and then Present (Alias (Prim))
17e14451 8175 and then Chars (Prim) = Chars (Alias (Prim))
343d35dc 8176 and then Find_Dispatching_Type (Alias (Prim)) /= Typ
a652dd51 8177 and then Is_Ancestor
cb4af01d 8178 (Find_Dispatching_Type (Alias (Prim)), Typ,
8179 Use_Full_View => True)
343d35dc 8180 and then Present (DTC_Entity (Alias (Prim)))
af647dc7 8181 then
343d35dc 8182 E := Alias (Prim);
ad274a73 8183 Set_DT_Position_Value (Prim, DT_Position (E));
aad6babd 8184
343d35dc 8185 if not Is_Predefined_Dispatching_Alias (E) then
8186 Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
8187 end if;
9dfe12ae 8188 end if;
ee6ba406 8189
aad6babd 8190 Next_Elmt (Prim_Elmt);
8191 end loop;
8192
02a2406d 8193 -- Third stage: Fix the position of all the new primitives. Entries
8194 -- associated with primitives covering interfaces are handled in a
8195 -- latter round.
aad6babd 8196
343d35dc 8197 Prim_Elmt := First_Prim;
8198 while Present (Prim_Elmt) loop
8199 Prim := Node (Prim_Elmt);
aad6babd 8200
343d35dc 8201 -- Skip primitives previously set entries
aad6babd 8202
343d35dc 8203 if DT_Position (Prim) /= No_Uint then
8204 null;
aad6babd 8205
343d35dc 8206 -- Primitives covering interface primitives are handled later
aad6babd 8207
a652dd51 8208 elsif Present (Interface_Alias (Prim)) then
343d35dc 8209 null;
aad6babd 8210
343d35dc 8211 else
8212 -- Take the next available position in the DT
aad6babd 8213
343d35dc 8214 loop
8215 Nb_Prim := Nb_Prim + 1;
8216 pragma Assert (Nb_Prim <= Count_Prim);
8217 exit when not Fixed_Prim (Nb_Prim);
8218 end loop;
aad6babd 8219
ad274a73 8220 Set_DT_Position_Value (Prim, UI_From_Int (Nb_Prim));
343d35dc 8221 Set_Fixed_Prim (Nb_Prim);
8222 end if;
aad6babd 8223
343d35dc 8224 Next_Elmt (Prim_Elmt);
8225 end loop;
8226 end;
aad6babd 8227
343d35dc 8228 -- Fourth stage: Complete the decoration of primitives covering
02a2406d 8229 -- interfaces (that is, propagate the DT_Position attribute from
8230 -- the aliased primitive)
aad6babd 8231
343d35dc 8232 Prim_Elmt := First_Prim;
8233 while Present (Prim_Elmt) loop
8234 Prim := Node (Prim_Elmt);
aad6babd 8235
343d35dc 8236 if DT_Position (Prim) = No_Uint
a652dd51 8237 and then Present (Interface_Alias (Prim))
343d35dc 8238 then
8239 pragma Assert (Present (Alias (Prim))
8240 and then Find_Dispatching_Type (Alias (Prim)) = Typ);
aad6babd 8241
343d35dc 8242 -- Check if this entry will be placed in the primary DT
aad6babd 8243
a652dd51 8244 if Is_Ancestor
cb4af01d 8245 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ,
8246 Use_Full_View => True)
ee6ba406 8247 then
343d35dc 8248 pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
ad274a73 8249 Set_DT_Position_Value (Prim, DT_Position (Alias (Prim)));
aad6babd 8250
343d35dc 8251 -- Otherwise it will be placed in the secondary DT
aad6babd 8252
343d35dc 8253 else
8254 pragma Assert
a652dd51 8255 (DT_Position (Interface_Alias (Prim)) /= No_Uint);
ad274a73 8256 Set_DT_Position_Value (Prim,
a652dd51 8257 DT_Position (Interface_Alias (Prim)));
aad6babd 8258 end if;
343d35dc 8259 end if;
aad6babd 8260
343d35dc 8261 Next_Elmt (Prim_Elmt);
8262 end loop;
d62940bf 8263
02a2406d 8264 -- Generate listing showing the contents of the dispatch tables. This
8265 -- action is done before some further static checks because in case of
8266 -- critical errors caused by a wrong dispatch table we need to see the
8267 -- contents of such table.
d62940bf 8268
343d35dc 8269 if Debug_Flag_ZZ then
8270 Write_DT (Typ);
8271 end if;
aad6babd 8272
343d35dc 8273 -- Final stage: Ensure that the table is correct plus some further
8274 -- verifications concerning the primitives.
aad6babd 8275
343d35dc 8276 Prim_Elmt := First_Prim;
8277 DT_Length := 0;
8278 while Present (Prim_Elmt) loop
8279 Prim := Node (Prim_Elmt);
aad6babd 8280
02a2406d 8281 -- At this point all the primitives MUST have a position in the
8282 -- dispatch table.
aad6babd 8283
343d35dc 8284 if DT_Position (Prim) = No_Uint then
8285 raise Program_Error;
8286 end if;
aad6babd 8287
343d35dc 8288 -- Calculate real size of the dispatch table
aad6babd 8289
cf365b48 8290 if not In_Predef_Prims_DT (Prim)
343d35dc 8291 and then UI_To_Int (DT_Position (Prim)) > DT_Length
8292 then
8293 DT_Length := UI_To_Int (DT_Position (Prim));
8294 end if;
aad6babd 8295
02a2406d 8296 -- Ensure that the assigned position to non-predefined dispatching
8297 -- operations in the dispatch table is correct.
aad6babd 8298
cf365b48 8299 if not Is_Predefined_Dispatching_Operation (Prim)
8300 and then not Is_Predefined_Dispatching_Alias (Prim)
343d35dc 8301 then
8302 Validate_Position (Prim);
8303 end if;
ee6ba406 8304
343d35dc 8305 if Chars (Prim) = Name_Finalize then
8306 Finalized := True;
8307 end if;
ee6ba406 8308
343d35dc 8309 if Chars (Prim) = Name_Adjust then
8310 Adjusted := True;
8311 end if;
af647dc7 8312
503f7fd3 8313 -- An abstract operation cannot be declared in the private part for a
8314 -- visible abstract type, because it can't be overridden outside this
8315 -- package hierarchy. For explicit declarations this is checked at
8316 -- the point of declaration, but for inherited operations it must be
8317 -- done when building the dispatch table.
343d35dc 8318
a652dd51 8319 -- Ada 2005 (AI-251): Primitives associated with interfaces are
8320 -- excluded from this check because interfaces must be visible in
8321 -- the public and private part (RM 7.3 (7.3/2))
343d35dc 8322
02a2406d 8323 -- We disable this check in Relaxed_RM_Semantics mode, to accommodate
8324 -- legacy Ada code.
6da4d289 8325
a9cd517c 8326 if not Relaxed_RM_Semantics
6da4d289 8327 and then Is_Abstract_Type (Typ)
343d35dc 8328 and then Is_Abstract_Subprogram (Prim)
8329 and then Present (Alias (Prim))
a652dd51 8330 and then not Is_Interface
8331 (Find_Dispatching_Type (Ultimate_Alias (Prim)))
8332 and then not Present (Interface_Alias (Prim))
343d35dc 8333 and then Is_Derived_Type (Typ)
8334 and then In_Private_Part (Current_Scope)
8335 and then
8336 List_Containing (Parent (Prim)) =
e8b4793a 8337 Private_Declarations (Package_Specification (Current_Scope))
343d35dc 8338 and then Original_View_In_Visible_Part (Typ)
8339 then
8340 -- We exclude Input and Output stream operations because
02a2406d 8341 -- Limited_Controlled inherits useless Input and Output stream
8342 -- operations from Root_Controlled, which can never be overridden.
ee6ba406 8343
343d35dc 8344 if not Is_TSS (Prim, TSS_Stream_Input)
8345 and then
8346 not Is_TSS (Prim, TSS_Stream_Output)
ee6ba406 8347 then
503f7fd3 8348 Error_Msg_NE
343d35dc 8349 ("abstract inherited private operation&" &
17e14451 8350 " must be overridden (RM 3.9.3(10))",
343d35dc 8351 Parent (Typ), Prim);
ee6ba406 8352 end if;
343d35dc 8353 end if;
aad6babd 8354
343d35dc 8355 Next_Elmt (Prim_Elmt);
8356 end loop;
ee6ba406 8357
343d35dc 8358 -- Additional check
aad6babd 8359
343d35dc 8360 if Is_Controlled (Typ) then
8361 if not Finalized then
503f7fd3 8362 Error_Msg_N
cb97ae5c 8363 ("controlled type has no explicit Finalize method??", Typ);
ee6ba406 8364
343d35dc 8365 elsif not Adjusted then
503f7fd3 8366 Error_Msg_N
cb97ae5c 8367 ("controlled type has no explicit Adjust method??", Typ);
ee6ba406 8368 end if;
343d35dc 8369 end if;
ee6ba406 8370
343d35dc 8371 -- Set the final size of the Dispatch Table
aad6babd 8372
343d35dc 8373 Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));
ee6ba406 8374
725a69d2 8375 -- The derived type must have at least as many components as its parent
acf97c11 8376 -- (for root types Etype points to itself and the test cannot fail).
aad6babd 8377
725a69d2 8378 if DT_Entry_Count (The_Tag) <
8379 DT_Entry_Count (First_Tag_Component (Parent_Typ))
8380 then
8381 raise Program_Error;
aad6babd 8382 end if;
ee6ba406 8383 end Set_All_DT_Position;
8384
294b942d 8385 --------------------------
8386 -- Set_CPP_Constructors --
8387 --------------------------
ee6ba406 8388
294b942d 8389 procedure Set_CPP_Constructors (Typ : Entity_Id) is
d00681a7 8390
95773554 8391 function Gen_Parameters_Profile (E : Entity_Id) return List_Id;
8392 -- Duplicate the parameters profile of the imported C++ constructor
8393 -- adding an access to the object as an additional parameter.
d00681a7 8394
02a2406d 8395 ----------------------------
8396 -- Gen_Parameters_Profile --
8397 ----------------------------
8398
95773554 8399 function Gen_Parameters_Profile (E : Entity_Id) return List_Id is
8400 Loc : constant Source_Ptr := Sloc (E);
8401 Parms : List_Id;
8402 P : Node_Id;
b8a17a21 8403
d00681a7 8404 begin
95773554 8405 Parms :=
8406 New_List (
8407 Make_Parameter_Specification (Loc,
8408 Defining_Identifier =>
8409 Make_Defining_Identifier (Loc, Name_uInit),
83c6c069 8410 Parameter_Type => New_Occurrence_Of (Typ, Loc)));
95773554 8411
8412 if Present (Parameter_Specifications (Parent (E))) then
8413 P := First (Parameter_Specifications (Parent (E)));
8414 while Present (P) loop
8415 Append_To (Parms,
8416 Make_Parameter_Specification (Loc,
8417 Defining_Identifier =>
8418 Make_Defining_Identifier (Loc,
8419 Chars => Chars (Defining_Identifier (P))),
8420 Parameter_Type => New_Copy_Tree (Parameter_Type (P)),
8421 Expression => New_Copy_Tree (Expression (P))));
8422 Next (P);
8423 end loop;
d00681a7 8424 end if;
b8a17a21 8425
95773554 8426 return Parms;
8427 end Gen_Parameters_Profile;
d00681a7 8428
8429 -- Local variables
8430
95773554 8431 Loc : Source_Ptr;
8432 E : Entity_Id;
8433 Found : Boolean := False;
8434 IP : Entity_Id;
8435 IP_Body : Node_Id;
8436 P : Node_Id;
8437 Parms : List_Id;
d00681a7 8438
c1b63034 8439 Covers_Default_Constructor : Entity_Id := Empty;
8440
8441 -- Start of processing for Set_CPP_Constructor
8442
ee6ba406 8443 begin
d00681a7 8444 pragma Assert (Is_CPP_Class (Typ));
8445
294b942d 8446 -- Look for the constructor entities
ee6ba406 8447
8448 E := Next_Entity (Typ);
294b942d 8449 while Present (E) loop
8450 if Ekind (E) = E_Function
8451 and then Is_Constructor (E)
8452 then
294b942d 8453 Found := True;
8454 Loc := Sloc (E);
95773554 8455 Parms := Gen_Parameters_Profile (E);
8456 IP :=
8457 Make_Defining_Identifier (Loc,
8458 Chars => Make_Init_Proc_Name (Typ));
8459
d1a2e31b 8460 -- Case 1: Constructor of untagged type
95773554 8461
8462 -- If the C++ class has no virtual methods then the matching Ada
d1a2e31b 8463 -- type is an untagged record type. In such case there is no need
95773554 8464 -- to generate a wrapper of the C++ constructor because the _tag
8465 -- component is not available.
8466
8467 if not Is_Tagged_Type (Typ) then
8468 Discard_Node
8469 (Make_Subprogram_Declaration (Loc,
8470 Specification =>
8471 Make_Procedure_Specification (Loc,
8472 Defining_Unit_Name => IP,
8473 Parameter_Specifications => Parms)));
8474
8475 Set_Init_Proc (Typ, IP);
8476 Set_Is_Imported (IP);
8477 Set_Is_Constructor (IP);
8478 Set_Interface_Name (IP, Interface_Name (E));
8479 Set_Convention (IP, Convention_CPP);
8480 Set_Is_Public (IP);
8481 Set_Has_Completion (IP);
8482
8483 -- Case 2: Constructor of a tagged type
8484
8485 -- In this case we generate the IP as a wrapper of the the
8486 -- C++ constructor because IP must also save copy of the _tag
8487 -- generated in the C++ side. The copy of the _tag is used by
8488 -- Build_CPP_Init_Procedure to elaborate derivations of C++ types.
d00681a7 8489
95773554 8490 -- Generate:
8491 -- procedure IP (_init : Typ; ...) is
8492 -- procedure ConstructorP (_init : Typ; ...);
8493 -- pragma Import (ConstructorP);
8494 -- begin
8495 -- ConstructorP (_init, ...);
8496 -- if Typ._tag = null then
8497 -- Typ._tag := _init._tag;
8498 -- end if;
8499 -- end IP;
d00681a7 8500
95773554 8501 else
8502 declare
8503 Body_Stmts : constant List_Id := New_List;
8504 Constructor_Id : Entity_Id;
8505 Constructor_Decl_Node : Node_Id;
8506 Init_Tags_List : List_Id;
d00681a7 8507
95773554 8508 begin
8509 Constructor_Id := Make_Temporary (Loc, 'P');
d00681a7 8510
95773554 8511 Constructor_Decl_Node :=
8512 Make_Subprogram_Declaration (Loc,
8513 Make_Procedure_Specification (Loc,
8514 Defining_Unit_Name => Constructor_Id,
8515 Parameter_Specifications => Parms));
d00681a7 8516
95773554 8517 Set_Is_Imported (Constructor_Id);
8518 Set_Is_Constructor (Constructor_Id);
8519 Set_Interface_Name (Constructor_Id, Interface_Name (E));
8520 Set_Convention (Constructor_Id, Convention_CPP);
8521 Set_Is_Public (Constructor_Id);
8522 Set_Has_Completion (Constructor_Id);
d00681a7 8523
95773554 8524 -- Build the init procedure as a wrapper of this constructor
d00681a7 8525
95773554 8526 Parms := Gen_Parameters_Profile (E);
d00681a7 8527
95773554 8528 -- Invoke the C++ constructor
d00681a7 8529
95773554 8530 declare
8531 Actuals : constant List_Id := New_List;
d00681a7 8532
95773554 8533 begin
8534 P := First (Parms);
8535 while Present (P) loop
8536 Append_To (Actuals,
83c6c069 8537 New_Occurrence_Of (Defining_Identifier (P), Loc));
95773554 8538 Next (P);
8539 end loop;
d00681a7 8540
95773554 8541 Append_To (Body_Stmts,
8542 Make_Procedure_Call_Statement (Loc,
83c6c069 8543 Name => New_Occurrence_Of (Constructor_Id, Loc),
95773554 8544 Parameter_Associations => Actuals));
8545 end;
d00681a7 8546
95773554 8547 -- Initialize copies of C++ primary and secondary tags
d00681a7 8548
95773554 8549 Init_Tags_List := New_List;
d00681a7 8550
95773554 8551 declare
8552 Tag_Elmt : Elmt_Id;
8553 Tag_Comp : Node_Id;
d00681a7 8554
95773554 8555 begin
8556 Tag_Elmt := First_Elmt (Access_Disp_Table (Typ));
8557 Tag_Comp := First_Tag_Component (Typ);
d00681a7 8558
95773554 8559 while Present (Tag_Elmt)
8560 and then Is_Tag (Node (Tag_Elmt))
8561 loop
8562 -- Skip the following assertion with primary tags
8563 -- because Related_Type is not set on primary tag
8564 -- components
8565
8566 pragma Assert
8567 (Tag_Comp = First_Tag_Component (Typ)
8568 or else Related_Type (Node (Tag_Elmt))
8569 = Related_Type (Tag_Comp));
8570
8571 Append_To (Init_Tags_List,
8572 Make_Assignment_Statement (Loc,
8573 Name =>
83c6c069 8574 New_Occurrence_Of (Node (Tag_Elmt), Loc),
95773554 8575 Expression =>
8576 Make_Selected_Component (Loc,
8577 Prefix =>
8578 Make_Identifier (Loc, Name_uInit),
8579 Selector_Name =>
83c6c069 8580 New_Occurrence_Of (Tag_Comp, Loc))));
d00681a7 8581
95773554 8582 Tag_Comp := Next_Tag_Component (Tag_Comp);
8583 Next_Elmt (Tag_Elmt);
8584 end loop;
8585 end;
d00681a7 8586
95773554 8587 Append_To (Body_Stmts,
8588 Make_If_Statement (Loc,
8589 Condition =>
8590 Make_Op_Eq (Loc,
8591 Left_Opnd =>
83c6c069 8592 New_Occurrence_Of
95773554 8593 (Node (First_Elmt (Access_Disp_Table (Typ))),
8594 Loc),
8595 Right_Opnd =>
8596 Unchecked_Convert_To (RTE (RE_Tag),
83c6c069 8597 New_Occurrence_Of (RTE (RE_Null_Address), Loc))),
95773554 8598 Then_Statements => Init_Tags_List));
8599
8600 IP_Body :=
8601 Make_Subprogram_Body (Loc,
8602 Specification =>
8603 Make_Procedure_Specification (Loc,
8604 Defining_Unit_Name => IP,
8605 Parameter_Specifications => Parms),
8606 Declarations => New_List (Constructor_Decl_Node),
8607 Handled_Statement_Sequence =>
8608 Make_Handled_Sequence_Of_Statements (Loc,
8609 Statements => Body_Stmts,
8610 Exception_Handlers => No_List));
8611
8612 Discard_Node (IP_Body);
8613 Set_Init_Proc (Typ, IP);
8614 end;
8615 end if;
c1b63034 8616
02a2406d 8617 -- If this constructor has parameters and all its parameters have
8618 -- defaults then it covers the default constructor. The semantic
8619 -- analyzer ensures that only one constructor with defaults covers
8620 -- the default constructor.
c1b63034 8621
8622 if Present (Parameter_Specifications (Parent (E)))
8623 and then Needs_No_Actuals (E)
8624 then
95773554 8625 Covers_Default_Constructor := IP;
c1b63034 8626 end if;
294b942d 8627 end if;
8628
ee6ba406 8629 Next_Entity (E);
8630 end loop;
8631
9dfe12ae 8632 -- If there are no constructors, mark the type as abstract since we
ee6ba406 8633 -- won't be able to declare objects of that type.
8634
294b942d 8635 if not Found then
343d35dc 8636 Set_Is_Abstract_Type (Typ);
ee6ba406 8637 end if;
d00681a7 8638
c1b63034 8639 -- Handle constructor that has all its parameters with defaults and
8640 -- hence it covers the default constructor. We generate a wrapper IP
8641 -- which calls the covering constructor.
8642
8643 if Present (Covers_Default_Constructor) then
95773554 8644 declare
8645 Body_Stmts : List_Id;
c1b63034 8646
95773554 8647 begin
8648 Loc := Sloc (Covers_Default_Constructor);
c1b63034 8649
95773554 8650 Body_Stmts := New_List (
8651 Make_Procedure_Call_Statement (Loc,
8652 Name =>
83c6c069 8653 New_Occurrence_Of (Covers_Default_Constructor, Loc),
95773554 8654 Parameter_Associations => New_List (
8655 Make_Identifier (Loc, Name_uInit))));
c1b63034 8656
95773554 8657 IP := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
c1b63034 8658
95773554 8659 IP_Body :=
8660 Make_Subprogram_Body (Loc,
8661 Specification =>
8662 Make_Procedure_Specification (Loc,
8663 Defining_Unit_Name => IP,
8664 Parameter_Specifications => New_List (
8665 Make_Parameter_Specification (Loc,
8666 Defining_Identifier =>
8667 Make_Defining_Identifier (Loc, Name_uInit),
83c6c069 8668 Parameter_Type => New_Occurrence_Of (Typ, Loc)))),
c1b63034 8669
95773554 8670 Declarations => No_List,
8671
8672 Handled_Statement_Sequence =>
8673 Make_Handled_Sequence_Of_Statements (Loc,
8674 Statements => Body_Stmts,
8675 Exception_Handlers => No_List));
8676
8677 Discard_Node (IP_Body);
8678 Set_Init_Proc (Typ, IP);
8679 end;
c1b63034 8680 end if;
8681
d00681a7 8682 -- If the CPP type has constructors then it must import also the default
8683 -- C++ constructor. It is required for default initialization of objects
8684 -- of the type. It is also required to elaborate objects of Ada types
8685 -- that are defined as derivations of this CPP type.
8686
8687 if Has_CPP_Constructors (Typ)
8688 and then No (Init_Proc (Typ))
8689 then
cb97ae5c 8690 Error_Msg_N ("??default constructor must be imported from C++", Typ);
d00681a7 8691 end if;
294b942d 8692 end Set_CPP_Constructors;
ee6ba406 8693
ad274a73 8694 ---------------------------
8695 -- Set_DT_Position_Value --
8696 ---------------------------
8697
8698 procedure Set_DT_Position_Value (Prim : Entity_Id; Value : Uint) is
8699 begin
8700 Set_DT_Position (Prim, Value);
8701
8702 -- Propagate the value to the wrapped subprogram (if one is present)
8703
8704 if Ekind_In (Prim, E_Function, E_Procedure)
8705 and then Is_Primitive_Wrapper (Prim)
8706 and then Present (Wrapped_Entity (Prim))
8707 and then Is_Dispatching_Operation (Wrapped_Entity (Prim))
8708 then
8709 Set_DT_Position (Wrapped_Entity (Prim), Value);
8710 end if;
8711 end Set_DT_Position_Value;
8712
725a69d2 8713 --------------------------
8714 -- Set_DTC_Entity_Value --
8715 --------------------------
8716
8717 procedure Set_DTC_Entity_Value
8718 (Tagged_Type : Entity_Id;
8719 Prim : Entity_Id)
8720 is
8721 begin
a652dd51 8722 if Present (Interface_Alias (Prim))
725a69d2 8723 and then Is_Interface
a652dd51 8724 (Find_Dispatching_Type (Interface_Alias (Prim)))
725a69d2 8725 then
8726 Set_DTC_Entity (Prim,
8727 Find_Interface_Tag
8728 (T => Tagged_Type,
a652dd51 8729 Iface => Find_Dispatching_Type (Interface_Alias (Prim))));
725a69d2 8730 else
8731 Set_DTC_Entity (Prim,
8732 First_Tag_Component (Tagged_Type));
8733 end if;
ad274a73 8734
8735 -- Propagate the value to the wrapped subprogram (if one is present)
8736
8737 if Ekind_In (Prim, E_Function, E_Procedure)
8738 and then Is_Primitive_Wrapper (Prim)
8739 and then Present (Wrapped_Entity (Prim))
8740 and then Is_Dispatching_Operation (Wrapped_Entity (Prim))
8741 then
8742 Set_DTC_Entity (Wrapped_Entity (Prim), DTC_Entity (Prim));
8743 end if;
725a69d2 8744 end Set_DTC_Entity_Value;
8745
952af0b9 8746 -----------------
8747 -- Tagged_Kind --
8748 -----------------
8749
8750 function Tagged_Kind (T : Entity_Id) return Node_Id is
8751 Conc_Typ : Entity_Id;
8752 Loc : constant Source_Ptr := Sloc (T);
8753
8754 begin
68f95949 8755 pragma Assert
8756 (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));
952af0b9 8757
8758 -- Abstract kinds
8759
343d35dc 8760 if Is_Abstract_Type (T) then
952af0b9 8761 if Is_Limited_Record (T) then
83c6c069 8762 return New_Occurrence_Of
8763 (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
952af0b9 8764 else
83c6c069 8765 return New_Occurrence_Of
8766 (RTE (RE_TK_Abstract_Tagged), Loc);
952af0b9 8767 end if;
8768
8769 -- Concurrent kinds
8770
8771 elsif Is_Concurrent_Record_Type (T) then
8772 Conc_Typ := Corresponding_Concurrent_Type (T);
8773
17e14451 8774 if Present (Full_View (Conc_Typ)) then
8775 Conc_Typ := Full_View (Conc_Typ);
8776 end if;
8777
952af0b9 8778 if Ekind (Conc_Typ) = E_Protected_Type then
83c6c069 8779 return New_Occurrence_Of (RTE (RE_TK_Protected), Loc);
952af0b9 8780 else
8781 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
83c6c069 8782 return New_Occurrence_Of (RTE (RE_TK_Task), Loc);
952af0b9 8783 end if;
8784
8785 -- Regular tagged kinds
8786
8787 else
8788 if Is_Limited_Record (T) then
83c6c069 8789 return New_Occurrence_Of (RTE (RE_TK_Limited_Tagged), Loc);
952af0b9 8790 else
83c6c069 8791 return New_Occurrence_Of (RTE (RE_TK_Tagged), Loc);
952af0b9 8792 end if;
8793 end if;
8794 end Tagged_Kind;
8795
aad6babd 8796 --------------
8797 -- Write_DT --
8798 --------------
8799
8800 procedure Write_DT (Typ : Entity_Id) is
8801 Elmt : Elmt_Id;
8802 Prim : Node_Id;
8803
8804 begin
8805 -- Protect this procedure against wrong usage. Required because it will
8806 -- be used directly from GDB
8807
17e14451 8808 if not (Typ <= Last_Node_Id)
aad6babd 8809 or else not Is_Tagged_Type (Typ)
8810 then
d62940bf 8811 Write_Str ("wrong usage: Write_DT must be used with tagged types");
aad6babd 8812 Write_Eol;
8813 return;
8814 end if;
8815
8816 Write_Int (Int (Typ));
8817 Write_Str (": ");
8818 Write_Name (Chars (Typ));
8819
8820 if Is_Interface (Typ) then
8821 Write_Str (" is interface");
8822 end if;
8823
8824 Write_Eol;
8825
8826 Elmt := First_Elmt (Primitive_Operations (Typ));
8827 while Present (Elmt) loop
8828 Prim := Node (Elmt);
8829 Write_Str (" - ");
8830
8831 -- Indicate if this primitive will be allocated in the primary
8832 -- dispatch table or in a secondary dispatch table associated
8833 -- with an abstract interface type
8834
8835 if Present (DTC_Entity (Prim)) then
8836 if Etype (DTC_Entity (Prim)) = RTE (RE_Tag) then
8837 Write_Str ("[P] ");
8838 else
8839 Write_Str ("[s] ");
8840 end if;
8841 end if;
8842
8843 -- Output the node of this primitive operation and its name
8844
8845 Write_Int (Int (Prim));
8846 Write_Str (": ");
68f95949 8847
8848 if Is_Predefined_Dispatching_Operation (Prim) then
8849 Write_Str ("(predefined) ");
8850 end if;
8851
b381b314 8852 -- Prefix the name of the primitive with its corresponding tagged
8853 -- type to facilitate seeing inherited primitives.
8854
8855 if Present (Alias (Prim)) then
8856 Write_Name
8857 (Chars (Find_Dispatching_Type (Ultimate_Alias (Prim))));
8858 else
8859 Write_Name (Chars (Typ));
8860 end if;
8861
8862 Write_Str (".");
aad6babd 8863 Write_Name (Chars (Prim));
8864
8865 -- Indicate if this primitive has an aliased primitive
8866
8867 if Present (Alias (Prim)) then
8868 Write_Str (" (alias = ");
8869 Write_Int (Int (Alias (Prim)));
8870
8871 -- If the DTC_Entity attribute is already set we can also output
4c58ddd7 8872 -- the name of the interface covered by this primitive (if any).
aad6babd 8873
f117057b 8874 if Ekind_In (Alias (Prim), E_Function, E_Procedure)
8875 and then Present (DTC_Entity (Alias (Prim)))
aad6babd 8876 and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
8877 then
8878 Write_Str (" from interface ");
8879 Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
8880 end if;
8881
a652dd51 8882 if Present (Interface_Alias (Prim)) then
aad6babd 8883 Write_Str (", AI_Alias of ");
f235fede 8884
8885 if Is_Null_Interface_Primitive (Interface_Alias (Prim)) then
8886 Write_Str ("null primitive ");
8887 end if;
8888
a652dd51 8889 Write_Name
8890 (Chars (Find_Dispatching_Type (Interface_Alias (Prim))));
aad6babd 8891 Write_Char (':');
a652dd51 8892 Write_Int (Int (Interface_Alias (Prim)));
aad6babd 8893 end if;
8894
8895 Write_Str (")");
8896 end if;
8897
8898 -- Display the final position of this primitive in its associated
02a2406d 8899 -- (primary or secondary) dispatch table.
aad6babd 8900
8901 if Present (DTC_Entity (Prim))
8902 and then DT_Position (Prim) /= No_Uint
8903 then
8904 Write_Str (" at #");
8905 Write_Int (UI_To_Int (DT_Position (Prim)));
8906 end if;
8907
343d35dc 8908 if Is_Abstract_Subprogram (Prim) then
aad6babd 8909 Write_Str (" is abstract;");
af647dc7 8910
8911 -- Check if this is a null primitive
8912
8913 elsif Comes_From_Source (Prim)
8914 and then Ekind (Prim) = E_Procedure
8915 and then Null_Present (Parent (Prim))
8916 then
8917 Write_Str (" is null;");
aad6babd 8918 end if;
8919
555c63a6 8920 if Is_Eliminated (Ultimate_Alias (Prim)) then
8921 Write_Str (" (eliminated)");
8922 end if;
8923
d00681a7 8924 if Is_Imported (Prim)
8925 and then Convention (Prim) = Convention_CPP
8926 then
8927 Write_Str (" (C++)");
8928 end if;
8929
aad6babd 8930 Write_Eol;
8931
8932 Next_Elmt (Elmt);
8933 end loop;
8934 end Write_DT;
8935
ee6ba406 8936end Exp_Disp;