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