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