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