1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
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. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
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 Exp_Atag; use Exp_Atag;
33 with Exp_Ch6; use Exp_Ch6;
34 with Exp_CG; use Exp_CG;
35 with Exp_Dbug; use Exp_Dbug;
36 with Exp_Tss; use Exp_Tss;
37 with Exp_Util; use Exp_Util;
38 with Freeze; use Freeze;
39 with Itypes; use Itypes;
40 with Layout; use Layout;
41 with Nlists; use Nlists;
42 with Nmake; use Nmake;
43 with Namet; use Namet;
45 with Output; use Output;
46 with Restrict; use Restrict;
47 with Rident; use Rident;
48 with Rtsfind; use Rtsfind;
50 with Sem_Aux; use Sem_Aux;
51 with Sem_Ch6; use Sem_Ch6;
52 with Sem_Ch7; use Sem_Ch7;
53 with Sem_Ch8; use Sem_Ch8;
54 with Sem_Disp; use Sem_Disp;
55 with Sem_Eval; use Sem_Eval;
56 with Sem_Res; use Sem_Res;
57 with Sem_Type; use Sem_Type;
58 with Sem_Util; use Sem_Util;
59 with Sinfo; use Sinfo;
60 with Snames; use Snames;
61 with Stand; use Stand;
62 with Stringt; use Stringt;
63 with SCIL_LL; use SCIL_LL;
64 with Targparm; use Targparm;
65 with Tbuild; use Tbuild;
66 with Uintp; use Uintp;
68 package body Exp_Disp is
70 -----------------------
71 -- Local Subprograms --
72 -----------------------
74 function Default_Prim_Op_Position (E : Entity_Id) return Uint;
75 -- Ada 2005 (AI-251): Returns the fixed position in the dispatch table
76 -- of the default primitive operations.
78 function Has_DT (Typ : Entity_Id) return Boolean;
79 pragma Inline (Has_DT);
80 -- Returns true if we generate a dispatch table for tagged type Typ
82 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean;
83 -- Returns true if Prim is not a predefined dispatching primitive but it is
84 -- an alias of a predefined dispatching primitive (i.e. through a renaming)
86 function New_Value (From : Node_Id) return Node_Id;
87 -- From is the original Expression. New_Value is equivalent to a call
88 -- to Duplicate_Subexpr with an explicit dereference when From is an
91 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean;
92 -- Check if the type has a private view or if the public view appears
93 -- in the visible part of a package spec.
97 Typ : Entity_Id) return Node_Id;
98 -- Ada 2005 (AI-345): Determine the primitive operation kind of Prim
99 -- according to its type Typ. Return a reference to an RE_Prim_Op_Kind
100 -- enumeration value.
102 function Tagged_Kind (T : Entity_Id) return Node_Id;
103 -- Ada 2005 (AI-345): Determine the tagged kind of T and return a reference
104 -- to an RE_Tagged_Kind enumeration value.
106 ----------------------
107 -- Apply_Tag_Checks --
108 ----------------------
110 procedure Apply_Tag_Checks (Call_Node : Node_Id) is
111 Loc : constant Source_Ptr := Sloc (Call_Node);
112 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
113 Ctrl_Typ : constant Entity_Id := Base_Type (Etype (Ctrl_Arg));
114 Param_List : constant List_Id := Parameter_Associations (Call_Node);
120 Eq_Prim_Op : Entity_Id := Empty;
123 if No_Run_Time_Mode then
124 Error_Msg_CRT ("tagged types", Call_Node);
128 -- Apply_Tag_Checks is called directly from the semantics, so we need
129 -- a check to see whether expansion is active before proceeding. In
130 -- addition, there is no need to expand the call when compiling under
131 -- restriction No_Dispatching_Calls; the semantic analyzer has
132 -- previously notified the violation of this restriction.
134 if not Expander_Active
135 or else Restriction_Active (No_Dispatching_Calls)
140 -- Set subprogram. If this is an inherited operation that was
141 -- overridden, the body that is being called is its alias.
143 Subp := Entity (Name (Call_Node));
145 if Present (Alias (Subp))
146 and then Is_Inherited_Operation (Subp)
147 and then No (DTC_Entity (Subp))
149 Subp := Alias (Subp);
152 -- Definition of the class-wide type and the tagged type
154 -- If the controlling argument is itself a tag rather than a tagged
155 -- object, then use the class-wide type associated with the subprogram's
156 -- controlling type. This case can occur when a call to an inherited
157 -- primitive has an actual that originated from a default parameter
158 -- given by a tag-indeterminate call and when there is no other
159 -- controlling argument providing the tag (AI-239 requires dispatching).
160 -- This capability of dispatching directly by tag is also needed by the
161 -- implementation of AI-260 (for the generic dispatching constructors).
163 if Ctrl_Typ = RTE (RE_Tag)
164 or else (RTE_Available (RE_Interface_Tag)
165 and then Ctrl_Typ = RTE (RE_Interface_Tag))
167 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
169 -- Class_Wide_Type is applied to the expressions used to initialize
170 -- CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
171 -- there are cases where the controlling type is resolved to a specific
172 -- type (such as for designated types of arguments such as CW'Access).
174 elsif Is_Access_Type (Ctrl_Typ) then
175 CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));
178 CW_Typ := Class_Wide_Type (Ctrl_Typ);
181 Typ := Root_Type (CW_Typ);
183 if Ekind (Typ) = E_Incomplete_Type then
184 Typ := Non_Limited_View (Typ);
187 if not Is_Limited_Type (Typ) then
188 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
191 -- Dispatching call to C++ primitive
193 if Is_CPP_Class (Typ) then
196 -- Dispatching call to Ada primitive
198 elsif Present (Param_List) then
200 -- Generate the Tag checks when appropriate
202 Param := First_Actual (Call_Node);
203 while Present (Param) loop
205 -- No tag check with itself
207 if Param = Ctrl_Arg then
210 -- No tag check for parameter whose type is neither tagged nor
211 -- access to tagged (for access parameters)
213 elsif No (Find_Controlling_Arg (Param)) then
216 -- No tag check for function dispatching on result if the
217 -- Tag given by the context is this one
219 elsif Find_Controlling_Arg (Param) = Ctrl_Arg then
222 -- "=" is the only dispatching operation allowed to get
223 -- operands with incompatible tags (it just returns false).
224 -- We use Duplicate_Subexpr_Move_Checks instead of calling
225 -- Relocate_Node because the value will be duplicated to
228 elsif Subp = Eq_Prim_Op then
231 -- No check in presence of suppress flags
233 elsif Tag_Checks_Suppressed (Etype (Param))
234 or else (Is_Access_Type (Etype (Param))
235 and then Tag_Checks_Suppressed
236 (Designated_Type (Etype (Param))))
240 -- Optimization: no tag checks if the parameters are identical
242 elsif Is_Entity_Name (Param)
243 and then Is_Entity_Name (Ctrl_Arg)
244 and then Entity (Param) = Entity (Ctrl_Arg)
248 -- Now we need to generate the Tag check
251 -- Generate code for tag equality check
252 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
254 Insert_Action (Ctrl_Arg,
255 Make_Implicit_If_Statement (Call_Node,
259 Make_Selected_Component (Loc,
260 Prefix => New_Value (Ctrl_Arg),
263 (First_Tag_Component (Typ), Loc)),
266 Make_Selected_Component (Loc,
268 Unchecked_Convert_To (Typ, New_Value (Param)),
271 (First_Tag_Component (Typ), Loc))),
274 New_List (New_Constraint_Error (Loc))));
280 end Apply_Tag_Checks;
282 ------------------------
283 -- Building_Static_DT --
284 ------------------------
286 function Building_Static_DT (Typ : Entity_Id) return Boolean is
287 Root_Typ : Entity_Id := Root_Type (Typ);
290 -- Handle private types
292 if Present (Full_View (Root_Typ)) then
293 Root_Typ := Full_View (Root_Typ);
296 return Static_Dispatch_Tables
297 and then Is_Library_Level_Tagged_Type (Typ)
298 and then VM_Target = No_VM
300 -- If the type is derived from a CPP class we cannot statically
301 -- build the dispatch tables because we must inherit primitives
302 -- from the CPP side.
304 and then not Is_CPP_Class (Root_Typ);
305 end Building_Static_DT;
307 ----------------------------------
308 -- Build_Static_Dispatch_Tables --
309 ----------------------------------
311 procedure Build_Static_Dispatch_Tables (N : Entity_Id) is
312 Target_List : List_Id;
314 procedure Build_Dispatch_Tables (List : List_Id);
315 -- Build the static dispatch table of tagged types found in the list of
316 -- declarations. The generated nodes are added at the end of Target_List
318 procedure Build_Package_Dispatch_Tables (N : Node_Id);
319 -- Build static dispatch tables associated with package declaration N
321 ---------------------------
322 -- Build_Dispatch_Tables --
323 ---------------------------
325 procedure Build_Dispatch_Tables (List : List_Id) is
330 while Present (D) loop
332 -- Handle nested packages and package bodies recursively. The
333 -- generated code is placed on the Target_List established for
334 -- the enclosing compilation unit.
336 if Nkind (D) = N_Package_Declaration then
337 Build_Package_Dispatch_Tables (D);
339 elsif Nkind (D) = N_Package_Body then
340 Build_Dispatch_Tables (Declarations (D));
342 elsif Nkind (D) = N_Package_Body_Stub
343 and then Present (Library_Unit (D))
345 Build_Dispatch_Tables
346 (Declarations (Proper_Body (Unit (Library_Unit (D)))));
348 -- Handle full type declarations and derivations of library
349 -- level tagged types
351 elsif Nkind_In (D, N_Full_Type_Declaration,
352 N_Derived_Type_Definition)
353 and then Is_Library_Level_Tagged_Type (Defining_Entity (D))
354 and then Ekind (Defining_Entity (D)) /= E_Record_Subtype
355 and then not Is_Private_Type (Defining_Entity (D))
357 -- We do not generate dispatch tables for the internal types
358 -- created for a type extension with unknown discriminants
359 -- The needed information is shared with the source type,
360 -- See Expand_N_Record_Extension.
362 if Is_Underlying_Record_View (Defining_Entity (D))
364 (not Comes_From_Source (Defining_Entity (D))
366 Has_Unknown_Discriminants (Etype (Defining_Entity (D)))
368 not Comes_From_Source
369 (First_Subtype (Defining_Entity (D))))
373 Insert_List_After_And_Analyze (Last (Target_List),
374 Make_DT (Defining_Entity (D)));
377 -- Handle private types of library level tagged types. We must
378 -- exchange the private and full-view to ensure the correct
379 -- expansion. If the full view is a synchronized type ignore
380 -- the type because the table will be built for the corresponding
381 -- record type, that has its own declaration.
383 elsif (Nkind (D) = N_Private_Type_Declaration
384 or else Nkind (D) = N_Private_Extension_Declaration)
385 and then Present (Full_View (Defining_Entity (D)))
388 E1 : constant Entity_Id := Defining_Entity (D);
389 E2 : constant Entity_Id := Full_View (E1);
392 if Is_Library_Level_Tagged_Type (E2)
393 and then Ekind (E2) /= E_Record_Subtype
394 and then not Is_Concurrent_Type (E2)
396 Exchange_Declarations (E1);
397 Insert_List_After_And_Analyze (Last (Target_List),
399 Exchange_Declarations (E2);
406 end Build_Dispatch_Tables;
408 -----------------------------------
409 -- Build_Package_Dispatch_Tables --
410 -----------------------------------
412 procedure Build_Package_Dispatch_Tables (N : Node_Id) is
413 Spec : constant Node_Id := Specification (N);
414 Id : constant Entity_Id := Defining_Entity (N);
415 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
416 Priv_Decls : constant List_Id := Private_Declarations (Spec);
421 if Present (Priv_Decls) then
422 Build_Dispatch_Tables (Vis_Decls);
423 Build_Dispatch_Tables (Priv_Decls);
425 elsif Present (Vis_Decls) then
426 Build_Dispatch_Tables (Vis_Decls);
430 end Build_Package_Dispatch_Tables;
432 -- Start of processing for Build_Static_Dispatch_Tables
435 if not Expander_Active
436 or else not Tagged_Type_Expansion
441 if Nkind (N) = N_Package_Declaration then
443 Spec : constant Node_Id := Specification (N);
444 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
445 Priv_Decls : constant List_Id := Private_Declarations (Spec);
448 if Present (Priv_Decls)
449 and then Is_Non_Empty_List (Priv_Decls)
451 Target_List := Priv_Decls;
453 elsif not Present (Vis_Decls) then
454 Target_List := New_List;
455 Set_Private_Declarations (Spec, Target_List);
457 Target_List := Vis_Decls;
460 Build_Package_Dispatch_Tables (N);
463 else pragma Assert (Nkind (N) = N_Package_Body);
464 Target_List := Declarations (N);
465 Build_Dispatch_Tables (Target_List);
467 end Build_Static_Dispatch_Tables;
469 ------------------------------
470 -- Convert_Tag_To_Interface --
471 ------------------------------
473 function Convert_Tag_To_Interface
475 Expr : Node_Id) return Node_Id
477 Loc : constant Source_Ptr := Sloc (Expr);
478 Anon_Type : Entity_Id;
482 pragma Assert (Is_Class_Wide_Type (Typ)
483 and then Is_Interface (Typ)
485 ((Nkind (Expr) = N_Selected_Component
486 and then Is_Tag (Entity (Selector_Name (Expr))))
488 (Nkind (Expr) = N_Function_Call
489 and then RTE_Available (RE_Displace)
490 and then Entity (Name (Expr)) = RTE (RE_Displace))));
492 Anon_Type := Create_Itype (E_Anonymous_Access_Type, Expr);
493 Set_Directly_Designated_Type (Anon_Type, Typ);
494 Set_Etype (Anon_Type, Anon_Type);
495 Set_Can_Never_Be_Null (Anon_Type);
497 -- Decorate the size and alignment attributes of the anonymous access
498 -- type, as required by gigi.
500 Layout_Type (Anon_Type);
502 if Nkind (Expr) = N_Selected_Component
503 and then Is_Tag (Entity (Selector_Name (Expr)))
506 Make_Explicit_Dereference (Loc,
507 Unchecked_Convert_To (Anon_Type,
508 Make_Attribute_Reference (Loc,
510 Attribute_Name => Name_Address)));
513 Make_Explicit_Dereference (Loc,
514 Unchecked_Convert_To (Anon_Type, Expr));
518 end Convert_Tag_To_Interface;
524 function CPP_Num_Prims (Typ : Entity_Id) return Nat is
526 Tag_Comp : Entity_Id;
529 if not Is_Tagged_Type (Typ)
530 or else not Is_CPP_Class (Root_Type (Typ))
535 CPP_Typ := Enclosing_CPP_Parent (Typ);
536 Tag_Comp := First_Tag_Component (CPP_Typ);
538 -- If the number of primitives is already set in the tag component
541 if Present (Tag_Comp)
542 and then DT_Entry_Count (Tag_Comp) /= No_Uint
544 return UI_To_Int (DT_Entry_Count (Tag_Comp));
546 -- Otherwise, count the primitives of the enclosing CPP type
554 Elmt := First_Elmt (Primitive_Operations (CPP_Typ));
555 while Present (Elmt) loop
566 ------------------------------
567 -- Default_Prim_Op_Position --
568 ------------------------------
570 function Default_Prim_Op_Position (E : Entity_Id) return Uint is
571 TSS_Name : TSS_Name_Type;
574 Get_Name_String (Chars (E));
577 (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
579 if Chars (E) = Name_uSize then
582 elsif Chars (E) = Name_uAlignment then
585 elsif TSS_Name = TSS_Stream_Read then
588 elsif TSS_Name = TSS_Stream_Write then
591 elsif TSS_Name = TSS_Stream_Input then
594 elsif TSS_Name = TSS_Stream_Output then
597 elsif Chars (E) = Name_Op_Eq then
600 elsif Chars (E) = Name_uAssign then
603 elsif TSS_Name = TSS_Deep_Adjust then
606 elsif TSS_Name = TSS_Deep_Finalize then
609 -- In VM targets unconditionally allow obtaining the position associated
610 -- with predefined interface primitives since in these platforms any
611 -- tagged type has these primitives.
613 elsif Ada_Version >= Ada_2005 or else not Tagged_Type_Expansion then
614 if Chars (E) = Name_uDisp_Asynchronous_Select then
617 elsif Chars (E) = Name_uDisp_Conditional_Select then
620 elsif Chars (E) = Name_uDisp_Get_Prim_Op_Kind then
623 elsif Chars (E) = Name_uDisp_Get_Task_Id then
626 elsif Chars (E) = Name_uDisp_Requeue then
629 elsif Chars (E) = Name_uDisp_Timed_Select then
635 end Default_Prim_Op_Position;
637 -----------------------------
638 -- Expand_Dispatching_Call --
639 -----------------------------
641 procedure Expand_Dispatching_Call (Call_Node : Node_Id) is
642 Loc : constant Source_Ptr := Sloc (Call_Node);
643 Call_Typ : constant Entity_Id := Etype (Call_Node);
645 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
646 Ctrl_Typ : constant Entity_Id := Base_Type (Etype (Ctrl_Arg));
647 Param_List : constant List_Id := Parameter_Associations (Call_Node);
652 New_Call_Name : Node_Id;
653 New_Params : List_Id := No_List;
656 Subp_Ptr_Typ : Entity_Id;
657 Subp_Typ : Entity_Id;
659 Eq_Prim_Op : Entity_Id := Empty;
660 Controlling_Tag : Node_Id;
662 function New_Value (From : Node_Id) return Node_Id;
663 -- From is the original Expression. New_Value is equivalent to a call
664 -- to Duplicate_Subexpr with an explicit dereference when From is an
671 function New_Value (From : Node_Id) return Node_Id is
672 Res : constant Node_Id := Duplicate_Subexpr (From);
674 if Is_Access_Type (Etype (From)) then
676 Make_Explicit_Dereference (Sloc (From),
687 SCIL_Related_Node : Node_Id := Call_Node;
689 -- Start of processing for Expand_Dispatching_Call
692 if No_Run_Time_Mode then
693 Error_Msg_CRT ("tagged types", Call_Node);
697 -- Expand_Dispatching_Call is called directly from the semantics,
698 -- so we need a check to see whether expansion is active before
699 -- proceeding. In addition, there is no need to expand the call
700 -- if we are compiling under restriction No_Dispatching_Calls;
701 -- the semantic analyzer has previously notified the violation
702 -- of this restriction.
704 if not Expander_Active
705 or else Restriction_Active (No_Dispatching_Calls)
710 -- Set subprogram. If this is an inherited operation that was
711 -- overridden, the body that is being called is its alias.
713 Subp := Entity (Name (Call_Node));
715 if Present (Alias (Subp))
716 and then Is_Inherited_Operation (Subp)
717 and then No (DTC_Entity (Subp))
719 Subp := Alias (Subp);
722 -- Definition of the class-wide type and the tagged type
724 -- If the controlling argument is itself a tag rather than a tagged
725 -- object, then use the class-wide type associated with the subprogram's
726 -- controlling type. This case can occur when a call to an inherited
727 -- primitive has an actual that originated from a default parameter
728 -- given by a tag-indeterminate call and when there is no other
729 -- controlling argument providing the tag (AI-239 requires dispatching).
730 -- This capability of dispatching directly by tag is also needed by the
731 -- implementation of AI-260 (for the generic dispatching constructors).
733 if Ctrl_Typ = RTE (RE_Tag)
734 or else (RTE_Available (RE_Interface_Tag)
735 and then Ctrl_Typ = RTE (RE_Interface_Tag))
737 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
739 -- Class_Wide_Type is applied to the expressions used to initialize
740 -- CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
741 -- there are cases where the controlling type is resolved to a specific
742 -- type (such as for designated types of arguments such as CW'Access).
744 elsif Is_Access_Type (Ctrl_Typ) then
745 CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));
748 CW_Typ := Class_Wide_Type (Ctrl_Typ);
751 Typ := Root_Type (CW_Typ);
753 if Ekind (Typ) = E_Incomplete_Type then
754 Typ := Non_Limited_View (Typ);
757 if not Is_Limited_Type (Typ) then
758 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
761 -- Dispatching call to C++ primitive. Create a new parameter list
762 -- with no tag checks.
764 New_Params := New_List;
766 if Is_CPP_Class (Typ) then
767 Param := First_Actual (Call_Node);
768 while Present (Param) loop
769 Append_To (New_Params, Relocate_Node (Param));
773 -- Dispatching call to Ada primitive
775 elsif Present (Param_List) then
776 Apply_Tag_Checks (Call_Node);
778 Param := First_Actual (Call_Node);
779 while Present (Param) loop
780 -- Cases in which we may have generated runtime checks
783 or else Subp = Eq_Prim_Op
785 Append_To (New_Params,
786 Duplicate_Subexpr_Move_Checks (Param));
788 elsif Nkind (Parent (Param)) /= N_Parameter_Association
789 or else not Is_Accessibility_Actual (Parent (Param))
791 Append_To (New_Params, Relocate_Node (Param));
798 -- Generate the appropriate subprogram pointer type
800 if Etype (Subp) = Typ then
803 Res_Typ := Etype (Subp);
806 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
807 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
808 Set_Etype (Subp_Typ, Res_Typ);
809 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
811 -- Create a new list of parameters which is a copy of the old formal
812 -- list including the creation of a new set of matching entities.
815 Old_Formal : Entity_Id := First_Formal (Subp);
816 New_Formal : Entity_Id;
817 Extra : Entity_Id := Empty;
820 if Present (Old_Formal) then
821 New_Formal := New_Copy (Old_Formal);
822 Set_First_Entity (Subp_Typ, New_Formal);
823 Param := First_Actual (Call_Node);
826 Set_Scope (New_Formal, Subp_Typ);
828 -- Change all the controlling argument types to be class-wide
829 -- to avoid a recursion in dispatching.
831 if Is_Controlling_Formal (New_Formal) then
832 Set_Etype (New_Formal, Etype (Param));
835 -- If the type of the formal is an itype, there was code here
836 -- introduced in 1998 in revision 1.46, to create a new itype
837 -- by copy. This seems useless, and in fact leads to semantic
838 -- errors when the itype is the completion of a type derived
839 -- from a private type.
842 Next_Formal (Old_Formal);
843 exit when No (Old_Formal);
845 Set_Next_Entity (New_Formal, New_Copy (Old_Formal));
846 Next_Entity (New_Formal);
850 Set_Next_Entity (New_Formal, Empty);
851 Set_Last_Entity (Subp_Typ, Extra);
854 -- Now that the explicit formals have been duplicated, any extra
855 -- formals needed by the subprogram must be created.
857 if Present (Extra) then
858 Set_Extra_Formal (Extra, Empty);
861 Create_Extra_Formals (Subp_Typ);
864 -- Complete description of pointer type, including size information, as
865 -- must be done with itypes to prevent order-of-elaboration anomalies
868 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
869 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
870 Set_Convention (Subp_Ptr_Typ, Convention (Subp_Typ));
871 Layout_Type (Subp_Ptr_Typ);
873 -- If the controlling argument is a value of type Ada.Tag or an abstract
874 -- interface class-wide type then use it directly. Otherwise, the tag
875 -- must be extracted from the controlling object.
877 if Ctrl_Typ = RTE (RE_Tag)
878 or else (RTE_Available (RE_Interface_Tag)
879 and then Ctrl_Typ = RTE (RE_Interface_Tag))
881 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
883 -- Extract the tag from an unchecked type conversion. Done to avoid
884 -- the expansion of additional code just to obtain the value of such
885 -- tag because the current management of interface type conversions
886 -- generates in some cases this unchecked type conversion with the
887 -- tag of the object (see Expand_Interface_Conversion).
889 elsif Nkind (Ctrl_Arg) = N_Unchecked_Type_Conversion
891 (Etype (Expression (Ctrl_Arg)) = RTE (RE_Tag)
893 (RTE_Available (RE_Interface_Tag)
895 Etype (Expression (Ctrl_Arg)) = RTE (RE_Interface_Tag)))
897 Controlling_Tag := Duplicate_Subexpr (Expression (Ctrl_Arg));
899 -- Ada 2005 (AI-251): Abstract interface class-wide type
901 elsif Is_Interface (Ctrl_Typ)
902 and then Is_Class_Wide_Type (Ctrl_Typ)
904 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
908 Make_Selected_Component (Loc,
909 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
910 Selector_Name => New_Reference_To (DTC_Entity (Subp), Loc));
913 -- Handle dispatching calls to predefined primitives
915 if Is_Predefined_Dispatching_Operation (Subp)
916 or else Is_Predefined_Dispatching_Alias (Subp)
918 Build_Get_Predefined_Prim_Op_Address (Loc,
919 Tag_Node => Controlling_Tag,
920 Position => DT_Position (Subp),
921 New_Node => New_Node);
923 -- Handle dispatching calls to user-defined primitives
926 Build_Get_Prim_Op_Address (Loc,
927 Typ => Underlying_Type (Find_Dispatching_Type (Subp)),
928 Tag_Node => Controlling_Tag,
929 Position => DT_Position (Subp),
930 New_Node => New_Node);
934 Unchecked_Convert_To (Subp_Ptr_Typ, New_Node);
936 -- Generate the SCIL node for this dispatching call. Done now because
937 -- attribute SCIL_Controlling_Tag must be set after the new call name
938 -- is built to reference the nodes that will see the SCIL backend
939 -- (because Build_Get_Prim_Op_Address generates an unchecked type
940 -- conversion which relocates the controlling tag node).
942 if Generate_SCIL then
943 SCIL_Node := Make_SCIL_Dispatching_Call (Sloc (Call_Node));
944 Set_SCIL_Entity (SCIL_Node, Typ);
945 Set_SCIL_Target_Prim (SCIL_Node, Subp);
947 -- Common case: the controlling tag is the tag of an object
948 -- (for example, obj.tag)
950 if Nkind (Controlling_Tag) = N_Selected_Component then
951 Set_SCIL_Controlling_Tag (SCIL_Node, Controlling_Tag);
953 -- Handle renaming of selected component
955 elsif Nkind (Controlling_Tag) = N_Identifier
956 and then Nkind (Parent (Entity (Controlling_Tag))) =
957 N_Object_Renaming_Declaration
958 and then Nkind (Name (Parent (Entity (Controlling_Tag)))) =
961 Set_SCIL_Controlling_Tag (SCIL_Node,
962 Name (Parent (Entity (Controlling_Tag))));
964 -- If the controlling tag is an identifier, the SCIL node references
965 -- the corresponding object or parameter declaration
967 elsif Nkind (Controlling_Tag) = N_Identifier
968 and then Nkind_In (Parent (Entity (Controlling_Tag)),
969 N_Object_Declaration,
970 N_Parameter_Specification)
972 Set_SCIL_Controlling_Tag (SCIL_Node,
973 Parent (Entity (Controlling_Tag)));
975 -- If the controlling tag is a dereference, the SCIL node references
976 -- the corresponding object or parameter declaration
978 elsif Nkind (Controlling_Tag) = N_Explicit_Dereference
979 and then Nkind (Prefix (Controlling_Tag)) = N_Identifier
980 and then Nkind_In (Parent (Entity (Prefix (Controlling_Tag))),
981 N_Object_Declaration,
982 N_Parameter_Specification)
984 Set_SCIL_Controlling_Tag (SCIL_Node,
985 Parent (Entity (Prefix (Controlling_Tag))));
987 -- For a direct reference of the tag of the type the SCIL node
988 -- references the internal object declaration containing the tag
991 elsif Nkind (Controlling_Tag) = N_Attribute_Reference
992 and then Attribute_Name (Controlling_Tag) = Name_Tag
994 Set_SCIL_Controlling_Tag (SCIL_Node,
998 (Access_Disp_Table (Entity (Prefix (Controlling_Tag)))))));
1000 -- Interfaces are not supported. For now we leave the SCIL node
1001 -- decorated with the Controlling_Tag. More work needed here???
1003 elsif Is_Interface (Etype (Controlling_Tag)) then
1004 Set_SCIL_Controlling_Tag (SCIL_Node, Controlling_Tag);
1007 pragma Assert (False);
1012 if Nkind (Call_Node) = N_Function_Call then
1014 Make_Function_Call (Loc,
1015 Name => New_Call_Name,
1016 Parameter_Associations => New_Params);
1018 -- If this is a dispatching "=", we must first compare the tags so
1019 -- we generate: x.tag = y.tag and then x = y
1021 if Subp = Eq_Prim_Op then
1022 Param := First_Actual (Call_Node);
1028 Make_Selected_Component (Loc,
1029 Prefix => New_Value (Param),
1031 New_Reference_To (First_Tag_Component (Typ),
1035 Make_Selected_Component (Loc,
1037 Unchecked_Convert_To (Typ,
1038 New_Value (Next_Actual (Param))),
1041 (First_Tag_Component (Typ), Loc))),
1042 Right_Opnd => New_Call);
1044 SCIL_Related_Node := Right_Opnd (New_Call);
1049 Make_Procedure_Call_Statement (Loc,
1050 Name => New_Call_Name,
1051 Parameter_Associations => New_Params);
1054 -- Register the dispatching call in the call graph nodes table
1056 Register_CG_Node (Call_Node);
1058 Rewrite (Call_Node, New_Call);
1060 -- Associate the SCIL node of this dispatching call
1062 if Generate_SCIL then
1063 Set_SCIL_Node (SCIL_Related_Node, SCIL_Node);
1066 -- Suppress all checks during the analysis of the expanded code
1067 -- to avoid the generation of spurious warnings under ZFP run-time.
1069 Analyze_And_Resolve (Call_Node, Call_Typ, Suppress => All_Checks);
1070 end Expand_Dispatching_Call;
1072 ---------------------------------
1073 -- Expand_Interface_Conversion --
1074 ---------------------------------
1076 procedure Expand_Interface_Conversion
1078 Is_Static : Boolean := True)
1080 Loc : constant Source_Ptr := Sloc (N);
1081 Etyp : constant Entity_Id := Etype (N);
1082 Operand : constant Node_Id := Expression (N);
1083 Operand_Typ : Entity_Id := Etype (Operand);
1085 Iface_Typ : Entity_Id := Etype (N);
1086 Iface_Tag : Entity_Id;
1089 -- Ada 2005 (AI-345): Handle synchronized interface type derivations
1091 if Is_Concurrent_Type (Operand_Typ) then
1092 Operand_Typ := Base_Type (Corresponding_Record_Type (Operand_Typ));
1095 -- Handle access to class-wide interface types
1097 if Is_Access_Type (Iface_Typ) then
1098 Iface_Typ := Etype (Directly_Designated_Type (Iface_Typ));
1101 -- Handle class-wide interface types. This conversion can appear
1102 -- explicitly in the source code. Example: I'Class (Obj)
1104 if Is_Class_Wide_Type (Iface_Typ) then
1105 Iface_Typ := Root_Type (Iface_Typ);
1108 -- If the target type is a tagged synchronized type, the dispatch table
1109 -- info is in the corresponding record type.
1111 if Is_Concurrent_Type (Iface_Typ) then
1112 Iface_Typ := Corresponding_Record_Type (Iface_Typ);
1115 -- Handle private types
1117 Iface_Typ := Underlying_Type (Iface_Typ);
1119 -- Freeze the entity associated with the target interface to have
1120 -- available the attribute Access_Disp_Table.
1122 Freeze_Before (N, Iface_Typ);
1124 pragma Assert (not Is_Static
1125 or else (not Is_Class_Wide_Type (Iface_Typ)
1126 and then Is_Interface (Iface_Typ)));
1128 if not Tagged_Type_Expansion then
1129 if VM_Target /= No_VM then
1130 if Is_Access_Type (Operand_Typ) then
1131 Operand_Typ := Designated_Type (Operand_Typ);
1134 if Is_Class_Wide_Type (Operand_Typ) then
1135 Operand_Typ := Root_Type (Operand_Typ);
1139 and then Operand_Typ /= Iface_Typ
1142 Make_Procedure_Call_Statement (Loc,
1143 Name => New_Occurrence_Of
1144 (RTE (RE_Check_Interface_Conversion), Loc),
1145 Parameter_Associations => New_List (
1146 Make_Attribute_Reference (Loc,
1147 Prefix => Duplicate_Subexpr (Expression (N)),
1148 Attribute_Name => Name_Tag),
1149 Make_Attribute_Reference (Loc,
1150 Prefix => New_Reference_To (Iface_Typ, Loc),
1151 Attribute_Name => Name_Tag))));
1154 -- Just do a conversion ???
1156 Rewrite (N, Unchecked_Convert_To (Etype (N), N));
1163 if not Is_Static then
1165 -- Give error if configurable run time and Displace not available
1167 if not RTE_Available (RE_Displace) then
1168 Error_Msg_CRT ("dynamic interface conversion", N);
1172 -- Handle conversion of access-to-class-wide interface types. Target
1173 -- can be an access to an object or an access to another class-wide
1174 -- interface (see -1- and -2- in the following example):
1176 -- type Iface1_Ref is access all Iface1'Class;
1177 -- type Iface2_Ref is access all Iface1'Class;
1179 -- Acc1 : Iface1_Ref := new ...
1180 -- Obj : Obj_Ref := Obj_Ref (Acc); -- 1
1181 -- Acc2 : Iface2_Ref := Iface2_Ref (Acc); -- 2
1183 if Is_Access_Type (Operand_Typ) then
1185 Unchecked_Convert_To (Etype (N),
1186 Make_Function_Call (Loc,
1187 Name => New_Reference_To (RTE (RE_Displace), Loc),
1188 Parameter_Associations => New_List (
1190 Unchecked_Convert_To (RTE (RE_Address),
1191 Relocate_Node (Expression (N))),
1194 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
1202 Make_Function_Call (Loc,
1203 Name => New_Reference_To (RTE (RE_Displace), Loc),
1204 Parameter_Associations => New_List (
1205 Make_Attribute_Reference (Loc,
1206 Prefix => Relocate_Node (Expression (N)),
1207 Attribute_Name => Name_Address),
1210 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
1215 -- If the target is a class-wide interface we change the type of the
1216 -- data returned by IW_Convert to indicate that this is a dispatching
1220 New_Itype : Entity_Id;
1223 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
1224 Set_Etype (New_Itype, New_Itype);
1225 Set_Directly_Designated_Type (New_Itype, Etyp);
1228 Make_Explicit_Dereference (Loc,
1230 Unchecked_Convert_To (New_Itype, Relocate_Node (N))));
1232 Freeze_Itype (New_Itype, N);
1238 Iface_Tag := Find_Interface_Tag (Operand_Typ, Iface_Typ);
1239 pragma Assert (Iface_Tag /= Empty);
1241 -- Keep separate access types to interfaces because one internal
1242 -- function is used to handle the null value (see following comments)
1244 if not Is_Access_Type (Etype (N)) then
1246 -- Statically displace the pointer to the object to reference
1247 -- the component containing the secondary dispatch table.
1250 Convert_Tag_To_Interface (Class_Wide_Type (Iface_Typ),
1251 Make_Selected_Component (Loc,
1252 Prefix => Relocate_Node (Expression (N)),
1253 Selector_Name => New_Occurrence_Of (Iface_Tag, Loc))));
1256 -- Build internal function to handle the case in which the
1257 -- actual is null. If the actual is null returns null because
1258 -- no displacement is required; otherwise performs a type
1259 -- conversion that will be expanded in the code that returns
1260 -- the value of the displaced actual. That is:
1262 -- function Func (O : Address) return Iface_Typ is
1263 -- type Op_Typ is access all Operand_Typ;
1264 -- Aux : Op_Typ := To_Op_Typ (O);
1266 -- if O = Null_Address then
1269 -- return Iface_Typ!(Aux.Iface_Tag'Address);
1274 Desig_Typ : Entity_Id;
1276 New_Typ_Decl : Node_Id;
1280 Desig_Typ := Etype (Expression (N));
1282 if Is_Access_Type (Desig_Typ) then
1284 Available_View (Directly_Designated_Type (Desig_Typ));
1287 if Is_Concurrent_Type (Desig_Typ) then
1288 Desig_Typ := Base_Type (Corresponding_Record_Type (Desig_Typ));
1292 Make_Full_Type_Declaration (Loc,
1293 Defining_Identifier => Make_Temporary (Loc, 'T'),
1295 Make_Access_To_Object_Definition (Loc,
1296 All_Present => True,
1297 Null_Exclusion_Present => False,
1298 Constant_Present => False,
1299 Subtype_Indication =>
1300 New_Reference_To (Desig_Typ, Loc)));
1303 Make_Simple_Return_Statement (Loc,
1304 Unchecked_Convert_To (Etype (N),
1305 Make_Attribute_Reference (Loc,
1307 Make_Selected_Component (Loc,
1309 Unchecked_Convert_To
1310 (Defining_Identifier (New_Typ_Decl),
1311 Make_Identifier (Loc, Name_uO)),
1313 New_Occurrence_Of (Iface_Tag, Loc)),
1314 Attribute_Name => Name_Address))));
1316 -- If the type is null-excluding, no need for the null branch.
1317 -- Otherwise we need to check for it and return null.
1319 if not Can_Never_Be_Null (Etype (N)) then
1321 Make_If_Statement (Loc,
1324 Left_Opnd => Make_Identifier (Loc, Name_uO),
1325 Right_Opnd => New_Reference_To
1326 (RTE (RE_Null_Address), Loc)),
1328 Then_Statements => New_List (
1329 Make_Simple_Return_Statement (Loc,
1331 Else_Statements => Stats));
1334 Fent := Make_Temporary (Loc, 'F');
1336 Make_Subprogram_Body (Loc,
1338 Make_Function_Specification (Loc,
1339 Defining_Unit_Name => Fent,
1341 Parameter_Specifications => New_List (
1342 Make_Parameter_Specification (Loc,
1343 Defining_Identifier =>
1344 Make_Defining_Identifier (Loc, Name_uO),
1346 New_Reference_To (RTE (RE_Address), Loc))),
1348 Result_Definition =>
1349 New_Reference_To (Etype (N), Loc)),
1351 Declarations => New_List (New_Typ_Decl),
1353 Handled_Statement_Sequence =>
1354 Make_Handled_Sequence_Of_Statements (Loc, Stats));
1356 -- Place function body before the expression containing the
1357 -- conversion. We suppress all checks because the body of the
1358 -- internally generated function already takes care of the case
1359 -- in which the actual is null; therefore there is no need to
1360 -- double check that the pointer is not null when the program
1361 -- executes the alternative that performs the type conversion).
1363 Insert_Action (N, Func, Suppress => All_Checks);
1365 if Is_Access_Type (Etype (Expression (N))) then
1367 -- Generate: Func (Address!(Expression))
1370 Make_Function_Call (Loc,
1371 Name => New_Reference_To (Fent, Loc),
1372 Parameter_Associations => New_List (
1373 Unchecked_Convert_To (RTE (RE_Address),
1374 Relocate_Node (Expression (N))))));
1377 -- Generate: Func (Operand_Typ!(Expression)'Address)
1380 Make_Function_Call (Loc,
1381 Name => New_Reference_To (Fent, Loc),
1382 Parameter_Associations => New_List (
1383 Make_Attribute_Reference (Loc,
1384 Prefix => Unchecked_Convert_To (Operand_Typ,
1385 Relocate_Node (Expression (N))),
1386 Attribute_Name => Name_Address))));
1392 end Expand_Interface_Conversion;
1394 ------------------------------
1395 -- Expand_Interface_Actuals --
1396 ------------------------------
1398 procedure Expand_Interface_Actuals (Call_Node : Node_Id) is
1400 Actual_Dup : Node_Id;
1401 Actual_Typ : Entity_Id;
1403 Conversion : Node_Id;
1405 Formal_Typ : Entity_Id;
1407 Formal_DDT : Entity_Id;
1408 Actual_DDT : Entity_Id;
1411 -- This subprogram is called directly from the semantics, so we need a
1412 -- check to see whether expansion is active before proceeding.
1414 if not Expander_Active then
1418 -- Call using access to subprogram with explicit dereference
1420 if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
1421 Subp := Etype (Name (Call_Node));
1423 -- Call using selected component
1425 elsif Nkind (Name (Call_Node)) = N_Selected_Component then
1426 Subp := Entity (Selector_Name (Name (Call_Node)));
1428 -- Call using direct name
1431 Subp := Entity (Name (Call_Node));
1434 -- Ada 2005 (AI-251): Look for interface type formals to force "this"
1437 Formal := First_Formal (Subp);
1438 Actual := First_Actual (Call_Node);
1439 while Present (Formal) loop
1440 Formal_Typ := Etype (Formal);
1442 if Ekind (Formal_Typ) = E_Record_Type_With_Private then
1443 Formal_Typ := Full_View (Formal_Typ);
1446 if Is_Access_Type (Formal_Typ) then
1447 Formal_DDT := Directly_Designated_Type (Formal_Typ);
1450 Actual_Typ := Etype (Actual);
1452 if Is_Access_Type (Actual_Typ) then
1453 Actual_DDT := Directly_Designated_Type (Actual_Typ);
1456 if Is_Interface (Formal_Typ)
1457 and then Is_Class_Wide_Type (Formal_Typ)
1459 -- No need to displace the pointer if the type of the actual
1460 -- coincides with the type of the formal.
1462 if Actual_Typ = Formal_Typ then
1465 -- No need to displace the pointer if the interface type is
1466 -- a parent of the type of the actual because in this case the
1467 -- interface primitives are located in the primary dispatch table.
1469 elsif Is_Ancestor (Formal_Typ, Actual_Typ,
1470 Use_Full_View => True)
1474 -- Implicit conversion to the class-wide formal type to force
1475 -- the displacement of the pointer.
1478 -- Normally, expansion of actuals for calls to build-in-place
1479 -- functions happens as part of Expand_Actuals, but in this
1480 -- case the call will be wrapped in a conversion and soon after
1481 -- expanded further to handle the displacement for a class-wide
1482 -- interface conversion, so if this is a BIP call then we need
1483 -- to handle it now.
1485 if Ada_Version >= Ada_2005
1486 and then Is_Build_In_Place_Function_Call (Actual)
1488 Make_Build_In_Place_Call_In_Anonymous_Context (Actual);
1491 Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
1492 Rewrite (Actual, Conversion);
1493 Analyze_And_Resolve (Actual, Formal_Typ);
1496 -- Access to class-wide interface type
1498 elsif Is_Access_Type (Formal_Typ)
1499 and then Is_Interface (Formal_DDT)
1500 and then Is_Class_Wide_Type (Formal_DDT)
1501 and then Interface_Present_In_Ancestor
1503 Iface => Etype (Formal_DDT))
1505 -- Handle attributes 'Access and 'Unchecked_Access
1507 if Nkind (Actual) = N_Attribute_Reference
1509 (Attribute_Name (Actual) = Name_Access
1510 or else Attribute_Name (Actual) = Name_Unchecked_Access)
1512 -- This case must have been handled by the analysis and
1513 -- expansion of 'Access. The only exception is when types
1514 -- match and no further expansion is required.
1516 pragma Assert (Base_Type (Etype (Prefix (Actual)))
1517 = Base_Type (Formal_DDT));
1520 -- No need to displace the pointer if the type of the actual
1521 -- coincides with the type of the formal.
1523 elsif Actual_DDT = Formal_DDT then
1526 -- No need to displace the pointer if the interface type is
1527 -- a parent of the type of the actual because in this case the
1528 -- interface primitives are located in the primary dispatch table.
1530 elsif Is_Ancestor (Formal_DDT, Actual_DDT,
1531 Use_Full_View => True)
1536 Actual_Dup := Relocate_Node (Actual);
1538 if From_With_Type (Actual_Typ) then
1540 -- If the type of the actual parameter comes from a limited
1541 -- with-clause and the non-limited view is already available
1542 -- we replace the anonymous access type by a duplicate
1543 -- declaration whose designated type is the non-limited view
1545 if Ekind (Actual_DDT) = E_Incomplete_Type
1546 and then Present (Non_Limited_View (Actual_DDT))
1548 Anon := New_Copy (Actual_Typ);
1550 if Is_Itype (Anon) then
1551 Set_Scope (Anon, Current_Scope);
1554 Set_Directly_Designated_Type (Anon,
1555 Non_Limited_View (Actual_DDT));
1556 Set_Etype (Actual_Dup, Anon);
1558 elsif Is_Class_Wide_Type (Actual_DDT)
1559 and then Ekind (Etype (Actual_DDT)) = E_Incomplete_Type
1560 and then Present (Non_Limited_View (Etype (Actual_DDT)))
1562 Anon := New_Copy (Actual_Typ);
1564 if Is_Itype (Anon) then
1565 Set_Scope (Anon, Current_Scope);
1568 Set_Directly_Designated_Type (Anon,
1569 New_Copy (Actual_DDT));
1570 Set_Class_Wide_Type (Directly_Designated_Type (Anon),
1571 New_Copy (Class_Wide_Type (Actual_DDT)));
1572 Set_Etype (Directly_Designated_Type (Anon),
1573 Non_Limited_View (Etype (Actual_DDT)));
1575 Class_Wide_Type (Directly_Designated_Type (Anon)),
1576 Non_Limited_View (Etype (Actual_DDT)));
1577 Set_Etype (Actual_Dup, Anon);
1581 Conversion := Convert_To (Formal_Typ, Actual_Dup);
1582 Rewrite (Actual, Conversion);
1583 Analyze_And_Resolve (Actual, Formal_Typ);
1587 Next_Actual (Actual);
1588 Next_Formal (Formal);
1590 end Expand_Interface_Actuals;
1592 ----------------------------
1593 -- Expand_Interface_Thunk --
1594 ----------------------------
1596 procedure Expand_Interface_Thunk
1598 Thunk_Id : out Entity_Id;
1599 Thunk_Code : out Node_Id)
1601 Loc : constant Source_Ptr := Sloc (Prim);
1602 Actuals : constant List_Id := New_List;
1603 Decl : constant List_Id := New_List;
1604 Formals : constant List_Id := New_List;
1605 Target : constant Entity_Id := Ultimate_Alias (Prim);
1607 Controlling_Typ : Entity_Id;
1613 Iface_Formal : Node_Id;
1615 Offset_To_Top : Node_Id;
1616 Target_Formal : Entity_Id;
1620 Thunk_Code := Empty;
1622 -- No thunk needed if the primitive has been eliminated
1624 if Is_Eliminated (Ultimate_Alias (Prim)) then
1627 -- In case of primitives that are functions without formals and a
1628 -- controlling result there is no need to build the thunk.
1630 elsif not Present (First_Formal (Target)) then
1631 pragma Assert (Ekind (Target) = E_Function
1632 and then Has_Controlling_Result (Target));
1636 -- Duplicate the formals of the Target primitive. In the thunk, the type
1637 -- of the controlling formal is the covered interface type (instead of
1638 -- the target tagged type). Done to avoid problems with discriminated
1639 -- tagged types because, if the controlling type has discriminants with
1640 -- default values, then the type conversions done inside the body of
1641 -- the thunk (after the displacement of the pointer to the base of the
1642 -- actual object) generate code that modify its contents.
1644 -- Note: This special management is not done for predefined primitives
1647 if not Is_Predefined_Dispatching_Operation (Prim) then
1648 Iface_Formal := First_Formal (Interface_Alias (Prim));
1651 Formal := First_Formal (Target);
1652 while Present (Formal) loop
1653 Ftyp := Etype (Formal);
1655 -- Use the interface type as the type of the controlling formal (see
1658 if not Is_Controlling_Formal (Formal)
1659 or else Is_Predefined_Dispatching_Operation (Prim)
1661 Ftyp := Etype (Formal);
1662 Expr := New_Copy_Tree (Expression (Parent (Formal)));
1664 Ftyp := Etype (Iface_Formal);
1669 Make_Parameter_Specification (Loc,
1670 Defining_Identifier =>
1671 Make_Defining_Identifier (Sloc (Formal),
1672 Chars => Chars (Formal)),
1673 In_Present => In_Present (Parent (Formal)),
1674 Out_Present => Out_Present (Parent (Formal)),
1675 Parameter_Type => New_Reference_To (Ftyp, Loc),
1676 Expression => Expr));
1678 if not Is_Predefined_Dispatching_Operation (Prim) then
1679 Next_Formal (Iface_Formal);
1682 Next_Formal (Formal);
1685 Controlling_Typ := Find_Dispatching_Type (Target);
1687 Target_Formal := First_Formal (Target);
1688 Formal := First (Formals);
1689 while Present (Formal) loop
1691 -- If the parent is a constrained discriminated type, then the
1692 -- primitive operation will have been defined on a first subtype.
1693 -- For proper matching with controlling type, use base type.
1695 if Ekind (Target_Formal) = E_In_Parameter
1696 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
1699 Base_Type (Directly_Designated_Type (Etype (Target_Formal)));
1701 Ftyp := Base_Type (Etype (Target_Formal));
1704 -- For concurrent types, the relevant information is found in the
1705 -- Corresponding_Record_Type, rather than the type entity itself.
1707 if Is_Concurrent_Type (Ftyp) then
1708 Ftyp := Corresponding_Record_Type (Ftyp);
1711 if Ekind (Target_Formal) = E_In_Parameter
1712 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
1713 and then Ftyp = Controlling_Typ
1716 -- type T is access all <<type of the target formal>>
1717 -- S : Storage_Offset := Storage_Offset!(Formal)
1718 -- - Offset_To_Top (address!(Formal))
1721 Make_Full_Type_Declaration (Loc,
1722 Defining_Identifier => Make_Temporary (Loc, 'T'),
1724 Make_Access_To_Object_Definition (Loc,
1725 All_Present => True,
1726 Null_Exclusion_Present => False,
1727 Constant_Present => False,
1728 Subtype_Indication =>
1729 New_Reference_To (Ftyp, Loc)));
1732 Unchecked_Convert_To (RTE (RE_Address),
1733 New_Reference_To (Defining_Identifier (Formal), Loc));
1735 if not RTE_Available (RE_Offset_To_Top) then
1737 Build_Offset_To_Top (Loc, New_Arg);
1740 Make_Function_Call (Loc,
1741 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1742 Parameter_Associations => New_List (New_Arg));
1746 Make_Object_Declaration (Loc,
1747 Defining_Identifier => Make_Temporary (Loc, 'S'),
1748 Constant_Present => True,
1749 Object_Definition =>
1750 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1752 Make_Op_Subtract (Loc,
1754 Unchecked_Convert_To
1755 (RTE (RE_Storage_Offset),
1756 New_Reference_To (Defining_Identifier (Formal), Loc)),
1760 Append_To (Decl, Decl_2);
1761 Append_To (Decl, Decl_1);
1763 -- Reference the new actual. Generate:
1767 Unchecked_Convert_To
1768 (Defining_Identifier (Decl_2),
1769 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1771 elsif Ftyp = Controlling_Typ then
1774 -- S1 : Storage_Offset := Storage_Offset!(Formal'Address)
1775 -- - Offset_To_Top (Formal'Address)
1776 -- S2 : Addr_Ptr := Addr_Ptr!(S1)
1779 Make_Attribute_Reference (Loc,
1781 New_Reference_To (Defining_Identifier (Formal), Loc),
1785 if not RTE_Available (RE_Offset_To_Top) then
1787 Build_Offset_To_Top (Loc, New_Arg);
1790 Make_Function_Call (Loc,
1791 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1792 Parameter_Associations => New_List (New_Arg));
1796 Make_Object_Declaration (Loc,
1797 Defining_Identifier => Make_Temporary (Loc, 'S'),
1798 Constant_Present => True,
1799 Object_Definition =>
1800 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1802 Make_Op_Subtract (Loc,
1804 Unchecked_Convert_To
1805 (RTE (RE_Storage_Offset),
1806 Make_Attribute_Reference (Loc,
1809 (Defining_Identifier (Formal), Loc),
1810 Attribute_Name => Name_Address)),
1815 Make_Object_Declaration (Loc,
1816 Defining_Identifier => Make_Temporary (Loc, 'S'),
1817 Constant_Present => True,
1818 Object_Definition =>
1819 New_Reference_To (RTE (RE_Addr_Ptr), Loc),
1821 Unchecked_Convert_To
1823 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1825 Append_To (Decl, Decl_1);
1826 Append_To (Decl, Decl_2);
1828 -- Reference the new actual, generate:
1829 -- Target_Formal (S2.all)
1832 Unchecked_Convert_To (Ftyp,
1833 Make_Explicit_Dereference (Loc,
1834 New_Reference_To (Defining_Identifier (Decl_2), Loc))));
1836 -- No special management required for this actual
1840 New_Reference_To (Defining_Identifier (Formal), Loc));
1843 Next_Formal (Target_Formal);
1847 Thunk_Id := Make_Temporary (Loc, 'T');
1848 Set_Is_Thunk (Thunk_Id);
1852 if Ekind (Target) = E_Procedure then
1854 Make_Subprogram_Body (Loc,
1856 Make_Procedure_Specification (Loc,
1857 Defining_Unit_Name => Thunk_Id,
1858 Parameter_Specifications => Formals),
1859 Declarations => Decl,
1860 Handled_Statement_Sequence =>
1861 Make_Handled_Sequence_Of_Statements (Loc,
1862 Statements => New_List (
1863 Make_Procedure_Call_Statement (Loc,
1864 Name => New_Occurrence_Of (Target, Loc),
1865 Parameter_Associations => Actuals))));
1869 else pragma Assert (Ekind (Target) = E_Function);
1871 Make_Subprogram_Body (Loc,
1873 Make_Function_Specification (Loc,
1874 Defining_Unit_Name => Thunk_Id,
1875 Parameter_Specifications => Formals,
1876 Result_Definition =>
1877 New_Copy (Result_Definition (Parent (Target)))),
1878 Declarations => Decl,
1879 Handled_Statement_Sequence =>
1880 Make_Handled_Sequence_Of_Statements (Loc,
1881 Statements => New_List (
1882 Make_Simple_Return_Statement (Loc,
1883 Make_Function_Call (Loc,
1884 Name => New_Occurrence_Of (Target, Loc),
1885 Parameter_Associations => Actuals)))));
1887 end Expand_Interface_Thunk;
1889 --------------------------
1890 -- Has_CPP_Constructors --
1891 --------------------------
1893 function Has_CPP_Constructors (Typ : Entity_Id) return Boolean is
1897 -- Look for the constructor entities
1899 E := Next_Entity (Typ);
1900 while Present (E) loop
1901 if Ekind (E) = E_Function
1902 and then Is_Constructor (E)
1911 end Has_CPP_Constructors;
1917 function Has_DT (Typ : Entity_Id) return Boolean is
1919 return not Is_Interface (Typ)
1920 and then not Restriction_Active (No_Dispatching_Calls);
1923 -----------------------------------------
1924 -- Is_Predefined_Dispatching_Operation --
1925 -----------------------------------------
1927 function Is_Predefined_Dispatching_Operation
1928 (E : Entity_Id) return Boolean
1930 TSS_Name : TSS_Name_Type;
1933 if not Is_Dispatching_Operation (E) then
1937 Get_Name_String (Chars (E));
1939 -- Most predefined primitives have internally generated names. Equality
1940 -- must be treated differently; the predefined operation is recognized
1941 -- as a homogeneous binary operator that returns Boolean.
1943 if Name_Len > TSS_Name_Type'Last then
1944 TSS_Name := TSS_Name_Type (Name_Buffer (Name_Len - TSS_Name'Length + 1
1946 if Chars (E) = Name_uSize
1947 or else Chars (E) = Name_uAlignment
1948 or else TSS_Name = TSS_Stream_Read
1949 or else TSS_Name = TSS_Stream_Write
1950 or else TSS_Name = TSS_Stream_Input
1951 or else TSS_Name = TSS_Stream_Output
1953 (Chars (E) = Name_Op_Eq
1954 and then Etype (First_Formal (E)) = Etype (Last_Formal (E)))
1955 or else Chars (E) = Name_uAssign
1956 or else TSS_Name = TSS_Deep_Adjust
1957 or else TSS_Name = TSS_Deep_Finalize
1958 or else Is_Predefined_Interface_Primitive (E)
1965 end Is_Predefined_Dispatching_Operation;
1967 ---------------------------------------
1968 -- Is_Predefined_Internal_Operation --
1969 ---------------------------------------
1971 function Is_Predefined_Internal_Operation
1972 (E : Entity_Id) return Boolean
1974 TSS_Name : TSS_Name_Type;
1977 if not Is_Dispatching_Operation (E) then
1981 Get_Name_String (Chars (E));
1983 -- Most predefined primitives have internally generated names. Equality
1984 -- must be treated differently; the predefined operation is recognized
1985 -- as a homogeneous binary operator that returns Boolean.
1987 if Name_Len > TSS_Name_Type'Last then
1990 (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
1992 if Chars (E) = Name_uSize
1993 or else Chars (E) = Name_uAlignment
1995 (Chars (E) = Name_Op_Eq
1996 and then Etype (First_Formal (E)) = Etype (Last_Formal (E)))
1997 or else Chars (E) = Name_uAssign
1998 or else TSS_Name = TSS_Deep_Adjust
1999 or else TSS_Name = TSS_Deep_Finalize
2000 or else Is_Predefined_Interface_Primitive (E)
2007 end Is_Predefined_Internal_Operation;
2009 -------------------------------------
2010 -- Is_Predefined_Dispatching_Alias --
2011 -------------------------------------
2013 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
2016 return not Is_Predefined_Dispatching_Operation (Prim)
2017 and then Present (Alias (Prim))
2018 and then Is_Predefined_Dispatching_Operation (Ultimate_Alias (Prim));
2019 end Is_Predefined_Dispatching_Alias;
2021 ---------------------------------------
2022 -- Is_Predefined_Interface_Primitive --
2023 ---------------------------------------
2025 function Is_Predefined_Interface_Primitive (E : Entity_Id) return Boolean is
2027 -- In VM targets we don't restrict the functionality of this test to
2028 -- compiling in Ada 2005 mode since in VM targets any tagged type has
2031 return (Ada_Version >= Ada_2005 or else not Tagged_Type_Expansion)
2032 and then (Chars (E) = Name_uDisp_Asynchronous_Select or else
2033 Chars (E) = Name_uDisp_Conditional_Select or else
2034 Chars (E) = Name_uDisp_Get_Prim_Op_Kind or else
2035 Chars (E) = Name_uDisp_Get_Task_Id or else
2036 Chars (E) = Name_uDisp_Requeue or else
2037 Chars (E) = Name_uDisp_Timed_Select);
2038 end Is_Predefined_Interface_Primitive;
2040 ----------------------------------------
2041 -- Make_Disp_Asynchronous_Select_Body --
2042 ----------------------------------------
2044 -- For interface types, generate:
2046 -- procedure _Disp_Asynchronous_Select
2047 -- (T : in out <Typ>;
2049 -- P : System.Address;
2050 -- B : out System.Storage_Elements.Dummy_Communication_Block;
2055 -- end _Disp_Asynchronous_Select;
2057 -- For protected types, generate:
2059 -- procedure _Disp_Asynchronous_Select
2060 -- (T : in out <Typ>;
2062 -- P : System.Address;
2063 -- B : out System.Storage_Elements.Dummy_Communication_Block;
2067 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2068 -- Bnn : System.Tasking.Protected_Objects.Operations.
2069 -- Communication_Block;
2071 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
2072 -- (T._object'Access,
2073 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
2075 -- System.Tasking.Asynchronous_Call,
2077 -- B := System.Storage_Elements.Dummy_Communication_Block (Bnn);
2078 -- end _Disp_Asynchronous_Select;
2080 -- For task types, generate:
2082 -- procedure _Disp_Asynchronous_Select
2083 -- (T : in out <Typ>;
2085 -- P : System.Address;
2086 -- B : out System.Storage_Elements.Dummy_Communication_Block;
2090 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2092 -- System.Tasking.Rendezvous.Task_Entry_Call
2094 -- System.Tasking.Task_Entry_Index (I),
2096 -- System.Tasking.Asynchronous_Call,
2098 -- end _Disp_Asynchronous_Select;
2100 function Make_Disp_Asynchronous_Select_Body
2101 (Typ : Entity_Id) return Node_Id
2103 Com_Block : Entity_Id;
2104 Conc_Typ : Entity_Id := Empty;
2105 Decls : constant List_Id := New_List;
2106 Loc : constant Source_Ptr := Sloc (Typ);
2108 Stmts : constant List_Id := New_List;
2112 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2114 -- Null body is generated for interface types
2116 if Is_Interface (Typ) then
2118 Make_Subprogram_Body (Loc,
2120 Make_Disp_Asynchronous_Select_Spec (Typ),
2123 Handled_Statement_Sequence =>
2124 Make_Handled_Sequence_Of_Statements (Loc,
2125 New_List (Make_Null_Statement (Loc))));
2128 if Is_Concurrent_Record_Type (Typ) then
2129 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2133 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
2135 -- where I will be used to capture the entry index of the primitive
2136 -- wrapper at position S.
2138 if Tagged_Type_Expansion then
2140 Unchecked_Convert_To (RTE (RE_Tag),
2142 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));
2145 Make_Attribute_Reference (Loc,
2146 Prefix => New_Reference_To (Typ, Loc),
2147 Attribute_Name => Name_Tag);
2151 Make_Object_Declaration (Loc,
2152 Defining_Identifier =>
2153 Make_Defining_Identifier (Loc, Name_uI),
2154 Object_Definition =>
2155 New_Reference_To (Standard_Integer, Loc),
2157 Make_Function_Call (Loc,
2159 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
2160 Parameter_Associations =>
2163 Make_Identifier (Loc, Name_uS)))));
2165 if Ekind (Conc_Typ) = E_Protected_Type then
2168 -- Bnn : Communication_Block;
2170 Com_Block := Make_Temporary (Loc, 'B');
2172 Make_Object_Declaration (Loc,
2173 Defining_Identifier =>
2175 Object_Definition =>
2176 New_Reference_To (RTE (RE_Communication_Block), Loc)));
2178 -- Build T._object'Access for calls below
2181 Make_Attribute_Reference (Loc,
2182 Attribute_Name => Name_Unchecked_Access,
2184 Make_Selected_Component (Loc,
2185 Prefix => Make_Identifier (Loc, Name_uT),
2186 Selector_Name => Make_Identifier (Loc, Name_uObject)));
2188 case Corresponding_Runtime_Package (Conc_Typ) is
2189 when System_Tasking_Protected_Objects_Entries =>
2192 -- Protected_Entry_Call
2193 -- (T._object'Access, -- Object
2194 -- Protected_Entry_Index! (I), -- E
2195 -- P, -- Uninterpreted_Data
2196 -- Asynchronous_Call, -- Mode
2197 -- Bnn); -- Communication_Block
2199 -- where T is the protected object, I is the entry index, P
2200 -- is the wrapped parameters and B is the name of the
2201 -- communication block.
2204 Make_Procedure_Call_Statement (Loc,
2206 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
2207 Parameter_Associations =>
2211 Make_Unchecked_Type_Conversion (Loc, -- entry index
2214 (RTE (RE_Protected_Entry_Index), Loc),
2215 Expression => Make_Identifier (Loc, Name_uI)),
2217 Make_Identifier (Loc, Name_uP), -- parameter block
2218 New_Reference_To -- Asynchronous_Call
2219 (RTE (RE_Asynchronous_Call), Loc),
2221 New_Reference_To (Com_Block, Loc)))); -- comm block
2223 when System_Tasking_Protected_Objects_Single_Entry =>
2226 -- procedure Protected_Single_Entry_Call
2227 -- (Object : Protection_Entry_Access;
2228 -- Uninterpreted_Data : System.Address;
2229 -- Mode : Call_Modes);
2232 Make_Procedure_Call_Statement (Loc,
2235 (RTE (RE_Protected_Single_Entry_Call), Loc),
2236 Parameter_Associations =>
2240 Make_Attribute_Reference (Loc,
2241 Prefix => Make_Identifier (Loc, Name_uP),
2242 Attribute_Name => Name_Address),
2245 (RTE (RE_Asynchronous_Call), Loc))));
2248 raise Program_Error;
2252 -- B := Dummy_Communication_Block (Bnn);
2255 Make_Assignment_Statement (Loc,
2256 Name => Make_Identifier (Loc, Name_uB),
2258 Make_Unchecked_Type_Conversion (Loc,
2261 RTE (RE_Dummy_Communication_Block), Loc),
2263 New_Reference_To (Com_Block, Loc))));
2266 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2270 -- (T._task_id, -- Acceptor
2271 -- Task_Entry_Index! (I), -- E
2272 -- P, -- Uninterpreted_Data
2273 -- Asynchronous_Call, -- Mode
2274 -- F); -- Rendezvous_Successful
2276 -- where T is the task object, I is the entry index, P is the
2277 -- wrapped parameters and F is the status flag.
2280 Make_Procedure_Call_Statement (Loc,
2282 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
2283 Parameter_Associations =>
2285 Make_Selected_Component (Loc, -- T._task_id
2286 Prefix => Make_Identifier (Loc, Name_uT),
2287 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
2289 Make_Unchecked_Type_Conversion (Loc, -- entry index
2291 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2292 Expression => Make_Identifier (Loc, Name_uI)),
2294 Make_Identifier (Loc, Name_uP), -- parameter block
2295 New_Reference_To -- Asynchronous_Call
2296 (RTE (RE_Asynchronous_Call), Loc),
2297 Make_Identifier (Loc, Name_uF)))); -- status flag
2301 -- Ensure that the statements list is non-empty
2303 Append_To (Stmts, Make_Null_Statement (Loc));
2307 Make_Subprogram_Body (Loc,
2309 Make_Disp_Asynchronous_Select_Spec (Typ),
2312 Handled_Statement_Sequence =>
2313 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2314 end Make_Disp_Asynchronous_Select_Body;
2316 ----------------------------------------
2317 -- Make_Disp_Asynchronous_Select_Spec --
2318 ----------------------------------------
2320 function Make_Disp_Asynchronous_Select_Spec
2321 (Typ : Entity_Id) return Node_Id
2323 Loc : constant Source_Ptr := Sloc (Typ);
2324 Def_Id : constant Node_Id :=
2325 Make_Defining_Identifier (Loc,
2326 Name_uDisp_Asynchronous_Select);
2327 Params : constant List_Id := New_List;
2330 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2332 -- T : in out Typ; -- Object parameter
2333 -- S : Integer; -- Primitive operation slot
2334 -- P : Address; -- Wrapped parameters
2335 -- B : out Dummy_Communication_Block; -- Communication block dummy
2336 -- F : out Boolean; -- Status flag
2338 Append_List_To (Params, New_List (
2340 Make_Parameter_Specification (Loc,
2341 Defining_Identifier =>
2342 Make_Defining_Identifier (Loc, Name_uT),
2344 New_Reference_To (Typ, Loc),
2346 Out_Present => True),
2348 Make_Parameter_Specification (Loc,
2349 Defining_Identifier =>
2350 Make_Defining_Identifier (Loc, Name_uS),
2352 New_Reference_To (Standard_Integer, Loc)),
2354 Make_Parameter_Specification (Loc,
2355 Defining_Identifier =>
2356 Make_Defining_Identifier (Loc, Name_uP),
2358 New_Reference_To (RTE (RE_Address), Loc)),
2360 Make_Parameter_Specification (Loc,
2361 Defining_Identifier =>
2362 Make_Defining_Identifier (Loc, Name_uB),
2364 New_Reference_To (RTE (RE_Dummy_Communication_Block), Loc),
2365 Out_Present => True),
2367 Make_Parameter_Specification (Loc,
2368 Defining_Identifier =>
2369 Make_Defining_Identifier (Loc, Name_uF),
2371 New_Reference_To (Standard_Boolean, Loc),
2372 Out_Present => True)));
2375 Make_Procedure_Specification (Loc,
2376 Defining_Unit_Name => Def_Id,
2377 Parameter_Specifications => Params);
2378 end Make_Disp_Asynchronous_Select_Spec;
2380 ---------------------------------------
2381 -- Make_Disp_Conditional_Select_Body --
2382 ---------------------------------------
2384 -- For interface types, generate:
2386 -- procedure _Disp_Conditional_Select
2387 -- (T : in out <Typ>;
2389 -- P : System.Address;
2390 -- C : out Ada.Tags.Prim_Op_Kind;
2395 -- end _Disp_Conditional_Select;
2397 -- For protected types, generate:
2399 -- procedure _Disp_Conditional_Select
2400 -- (T : in out <Typ>;
2402 -- P : System.Address;
2403 -- C : out Ada.Tags.Prim_Op_Kind;
2407 -- Bnn : System.Tasking.Protected_Objects.Operations.
2408 -- Communication_Block;
2411 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP, S));
2413 -- if C = Ada.Tags.POK_Procedure
2414 -- or else C = Ada.Tags.POK_Protected_Procedure
2415 -- or else C = Ada.Tags.POK_Task_Procedure
2421 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2422 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
2423 -- (T.object'Access,
2424 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
2426 -- System.Tasking.Conditional_Call,
2428 -- F := not Cancelled (Bnn);
2429 -- end _Disp_Conditional_Select;
2431 -- For task types, generate:
2433 -- procedure _Disp_Conditional_Select
2434 -- (T : in out <Typ>;
2436 -- P : System.Address;
2437 -- C : out Ada.Tags.Prim_Op_Kind;
2443 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2444 -- System.Tasking.Rendezvous.Task_Entry_Call
2446 -- System.Tasking.Task_Entry_Index (I),
2448 -- System.Tasking.Conditional_Call,
2450 -- end _Disp_Conditional_Select;
2452 function Make_Disp_Conditional_Select_Body
2453 (Typ : Entity_Id) return Node_Id
2455 Loc : constant Source_Ptr := Sloc (Typ);
2456 Blk_Nam : Entity_Id;
2457 Conc_Typ : Entity_Id := Empty;
2458 Decls : constant List_Id := New_List;
2460 Stmts : constant List_Id := New_List;
2464 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2466 -- Null body is generated for interface types
2468 if Is_Interface (Typ) then
2470 Make_Subprogram_Body (Loc,
2472 Make_Disp_Conditional_Select_Spec (Typ),
2475 Handled_Statement_Sequence =>
2476 Make_Handled_Sequence_Of_Statements (Loc,
2477 New_List (Make_Null_Statement (Loc))));
2480 if Is_Concurrent_Record_Type (Typ) then
2481 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2486 -- where I will be used to capture the entry index of the primitive
2487 -- wrapper at position S.
2490 Make_Object_Declaration (Loc,
2491 Defining_Identifier =>
2492 Make_Defining_Identifier (Loc, Name_uI),
2493 Object_Definition =>
2494 New_Reference_To (Standard_Integer, Loc)));
2497 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag! (<type>VP), S);
2499 -- if C = POK_Procedure
2500 -- or else C = POK_Protected_Procedure
2501 -- or else C = POK_Task_Procedure;
2507 Build_Common_Dispatching_Select_Statements (Typ, Stmts);
2510 -- Bnn : Communication_Block;
2512 -- where Bnn is the name of the communication block used in the
2513 -- call to Protected_Entry_Call.
2515 Blk_Nam := Make_Temporary (Loc, 'B');
2517 Make_Object_Declaration (Loc,
2518 Defining_Identifier =>
2520 Object_Definition =>
2521 New_Reference_To (RTE (RE_Communication_Block), Loc)));
2524 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
2526 -- I is the entry index and S is the dispatch table slot
2528 if Tagged_Type_Expansion then
2530 Unchecked_Convert_To (RTE (RE_Tag),
2532 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));
2536 Make_Attribute_Reference (Loc,
2537 Prefix => New_Reference_To (Typ, Loc),
2538 Attribute_Name => Name_Tag);
2542 Make_Assignment_Statement (Loc,
2543 Name => Make_Identifier (Loc, Name_uI),
2545 Make_Function_Call (Loc,
2547 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
2548 Parameter_Associations =>
2551 Make_Identifier (Loc, Name_uS)))));
2553 if Ekind (Conc_Typ) = E_Protected_Type then
2555 Obj_Ref := -- T._object'Access
2556 Make_Attribute_Reference (Loc,
2557 Attribute_Name => Name_Unchecked_Access,
2559 Make_Selected_Component (Loc,
2560 Prefix => Make_Identifier (Loc, Name_uT),
2561 Selector_Name => Make_Identifier (Loc, Name_uObject)));
2563 case Corresponding_Runtime_Package (Conc_Typ) is
2564 when System_Tasking_Protected_Objects_Entries =>
2567 -- Protected_Entry_Call
2568 -- (T._object'Access, -- Object
2569 -- Protected_Entry_Index! (I), -- E
2570 -- P, -- Uninterpreted_Data
2571 -- Conditional_Call, -- Mode
2574 -- where T is the protected object, I is the entry index, P
2575 -- are the wrapped parameters and Bnn is the name of the
2576 -- communication block.
2579 Make_Procedure_Call_Statement (Loc,
2581 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
2582 Parameter_Associations =>
2586 Make_Unchecked_Type_Conversion (Loc, -- entry index
2589 (RTE (RE_Protected_Entry_Index), Loc),
2590 Expression => Make_Identifier (Loc, Name_uI)),
2592 Make_Identifier (Loc, Name_uP), -- parameter block
2594 New_Reference_To ( -- Conditional_Call
2595 RTE (RE_Conditional_Call), Loc),
2596 New_Reference_To ( -- Bnn
2599 when System_Tasking_Protected_Objects_Single_Entry =>
2601 -- If we are compiling for a restricted run-time, the call
2602 -- uses the simpler form.
2605 Make_Procedure_Call_Statement (Loc,
2608 (RTE (RE_Protected_Single_Entry_Call), Loc),
2609 Parameter_Associations =>
2613 Make_Attribute_Reference (Loc,
2614 Prefix => Make_Identifier (Loc, Name_uP),
2615 Attribute_Name => Name_Address),
2618 (RTE (RE_Conditional_Call), Loc))));
2620 raise Program_Error;
2624 -- F := not Cancelled (Bnn);
2626 -- where F is the success flag. The status of Cancelled is negated
2627 -- in order to match the behaviour of the version for task types.
2630 Make_Assignment_Statement (Loc,
2631 Name => Make_Identifier (Loc, Name_uF),
2635 Make_Function_Call (Loc,
2637 New_Reference_To (RTE (RE_Cancelled), Loc),
2638 Parameter_Associations =>
2640 New_Reference_To (Blk_Nam, Loc))))));
2642 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2646 -- (T._task_id, -- Acceptor
2647 -- Task_Entry_Index! (I), -- E
2648 -- P, -- Uninterpreted_Data
2649 -- Conditional_Call, -- Mode
2650 -- F); -- Rendezvous_Successful
2652 -- where T is the task object, I is the entry index, P are the
2653 -- wrapped parameters and F is the status flag.
2656 Make_Procedure_Call_Statement (Loc,
2658 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
2659 Parameter_Associations =>
2662 Make_Selected_Component (Loc, -- T._task_id
2663 Prefix => Make_Identifier (Loc, Name_uT),
2664 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
2666 Make_Unchecked_Type_Conversion (Loc, -- entry index
2668 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2669 Expression => Make_Identifier (Loc, Name_uI)),
2671 Make_Identifier (Loc, Name_uP), -- parameter block
2672 New_Reference_To -- Conditional_Call
2673 (RTE (RE_Conditional_Call), Loc),
2674 Make_Identifier (Loc, Name_uF)))); -- status flag
2678 -- Ensure that the statements list is non-empty
2680 Append_To (Stmts, Make_Null_Statement (Loc));
2684 Make_Subprogram_Body (Loc,
2686 Make_Disp_Conditional_Select_Spec (Typ),
2689 Handled_Statement_Sequence =>
2690 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2691 end Make_Disp_Conditional_Select_Body;
2693 ---------------------------------------
2694 -- Make_Disp_Conditional_Select_Spec --
2695 ---------------------------------------
2697 function Make_Disp_Conditional_Select_Spec
2698 (Typ : Entity_Id) return Node_Id
2700 Loc : constant Source_Ptr := Sloc (Typ);
2701 Def_Id : constant Node_Id :=
2702 Make_Defining_Identifier (Loc,
2703 Name_uDisp_Conditional_Select);
2704 Params : constant List_Id := New_List;
2707 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2709 -- T : in out Typ; -- Object parameter
2710 -- S : Integer; -- Primitive operation slot
2711 -- P : Address; -- Wrapped parameters
2712 -- C : out Prim_Op_Kind; -- Call kind
2713 -- F : out Boolean; -- Status flag
2715 Append_List_To (Params, New_List (
2717 Make_Parameter_Specification (Loc,
2718 Defining_Identifier =>
2719 Make_Defining_Identifier (Loc, Name_uT),
2721 New_Reference_To (Typ, Loc),
2723 Out_Present => True),
2725 Make_Parameter_Specification (Loc,
2726 Defining_Identifier =>
2727 Make_Defining_Identifier (Loc, Name_uS),
2729 New_Reference_To (Standard_Integer, Loc)),
2731 Make_Parameter_Specification (Loc,
2732 Defining_Identifier =>
2733 Make_Defining_Identifier (Loc, Name_uP),
2735 New_Reference_To (RTE (RE_Address), Loc)),
2737 Make_Parameter_Specification (Loc,
2738 Defining_Identifier =>
2739 Make_Defining_Identifier (Loc, Name_uC),
2741 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2742 Out_Present => True),
2744 Make_Parameter_Specification (Loc,
2745 Defining_Identifier =>
2746 Make_Defining_Identifier (Loc, Name_uF),
2748 New_Reference_To (Standard_Boolean, Loc),
2749 Out_Present => True)));
2752 Make_Procedure_Specification (Loc,
2753 Defining_Unit_Name => Def_Id,
2754 Parameter_Specifications => Params);
2755 end Make_Disp_Conditional_Select_Spec;
2757 -------------------------------------
2758 -- Make_Disp_Get_Prim_Op_Kind_Body --
2759 -------------------------------------
2761 function Make_Disp_Get_Prim_Op_Kind_Body
2762 (Typ : Entity_Id) return Node_Id
2764 Loc : constant Source_Ptr := Sloc (Typ);
2768 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2770 if Is_Interface (Typ) then
2772 Make_Subprogram_Body (Loc,
2774 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2777 Handled_Statement_Sequence =>
2778 Make_Handled_Sequence_Of_Statements (Loc,
2779 New_List (Make_Null_Statement (Loc))));
2783 -- C := get_prim_op_kind (tag! (<type>VP), S);
2785 -- where C is the out parameter capturing the call kind and S is the
2786 -- dispatch table slot number.
2788 if Tagged_Type_Expansion then
2790 Unchecked_Convert_To (RTE (RE_Tag),
2792 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));
2796 Make_Attribute_Reference (Loc,
2797 Prefix => New_Reference_To (Typ, Loc),
2798 Attribute_Name => Name_Tag);
2802 Make_Subprogram_Body (Loc,
2804 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2807 Handled_Statement_Sequence =>
2808 Make_Handled_Sequence_Of_Statements (Loc,
2810 Make_Assignment_Statement (Loc,
2812 Make_Identifier (Loc, Name_uC),
2814 Make_Function_Call (Loc,
2816 New_Reference_To (RTE (RE_Get_Prim_Op_Kind), Loc),
2817 Parameter_Associations => New_List (
2819 Make_Identifier (Loc, Name_uS)))))));
2820 end Make_Disp_Get_Prim_Op_Kind_Body;
2822 -------------------------------------
2823 -- Make_Disp_Get_Prim_Op_Kind_Spec --
2824 -------------------------------------
2826 function Make_Disp_Get_Prim_Op_Kind_Spec
2827 (Typ : Entity_Id) return Node_Id
2829 Loc : constant Source_Ptr := Sloc (Typ);
2830 Def_Id : constant Node_Id :=
2831 Make_Defining_Identifier (Loc,
2832 Name_uDisp_Get_Prim_Op_Kind);
2833 Params : constant List_Id := New_List;
2836 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2838 -- T : in out Typ; -- Object parameter
2839 -- S : Integer; -- Primitive operation slot
2840 -- C : out Prim_Op_Kind; -- Call kind
2842 Append_List_To (Params, New_List (
2844 Make_Parameter_Specification (Loc,
2845 Defining_Identifier =>
2846 Make_Defining_Identifier (Loc, Name_uT),
2848 New_Reference_To (Typ, Loc),
2850 Out_Present => True),
2852 Make_Parameter_Specification (Loc,
2853 Defining_Identifier =>
2854 Make_Defining_Identifier (Loc, Name_uS),
2856 New_Reference_To (Standard_Integer, Loc)),
2858 Make_Parameter_Specification (Loc,
2859 Defining_Identifier =>
2860 Make_Defining_Identifier (Loc, Name_uC),
2862 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2863 Out_Present => True)));
2866 Make_Procedure_Specification (Loc,
2867 Defining_Unit_Name => Def_Id,
2868 Parameter_Specifications => Params);
2869 end Make_Disp_Get_Prim_Op_Kind_Spec;
2871 --------------------------------
2872 -- Make_Disp_Get_Task_Id_Body --
2873 --------------------------------
2875 function Make_Disp_Get_Task_Id_Body
2876 (Typ : Entity_Id) return Node_Id
2878 Loc : constant Source_Ptr := Sloc (Typ);
2882 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2884 if Is_Concurrent_Record_Type (Typ)
2885 and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
2888 -- return To_Address (_T._task_id);
2891 Make_Simple_Return_Statement (Loc,
2893 Make_Unchecked_Type_Conversion (Loc,
2895 New_Reference_To (RTE (RE_Address), Loc),
2897 Make_Selected_Component (Loc,
2898 Prefix => Make_Identifier (Loc, Name_uT),
2899 Selector_Name => Make_Identifier (Loc, Name_uTask_Id))));
2901 -- A null body is constructed for non-task types
2905 -- return Null_Address;
2908 Make_Simple_Return_Statement (Loc,
2910 New_Reference_To (RTE (RE_Null_Address), Loc));
2914 Make_Subprogram_Body (Loc,
2916 Make_Disp_Get_Task_Id_Spec (Typ),
2919 Handled_Statement_Sequence =>
2920 Make_Handled_Sequence_Of_Statements (Loc,
2922 end Make_Disp_Get_Task_Id_Body;
2924 --------------------------------
2925 -- Make_Disp_Get_Task_Id_Spec --
2926 --------------------------------
2928 function Make_Disp_Get_Task_Id_Spec
2929 (Typ : Entity_Id) return Node_Id
2931 Loc : constant Source_Ptr := Sloc (Typ);
2934 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2937 Make_Function_Specification (Loc,
2938 Defining_Unit_Name =>
2939 Make_Defining_Identifier (Loc, Name_uDisp_Get_Task_Id),
2940 Parameter_Specifications => New_List (
2941 Make_Parameter_Specification (Loc,
2942 Defining_Identifier =>
2943 Make_Defining_Identifier (Loc, Name_uT),
2945 New_Reference_To (Typ, Loc))),
2946 Result_Definition =>
2947 New_Reference_To (RTE (RE_Address), Loc));
2948 end Make_Disp_Get_Task_Id_Spec;
2950 ----------------------------
2951 -- Make_Disp_Requeue_Body --
2952 ----------------------------
2954 function Make_Disp_Requeue_Body
2955 (Typ : Entity_Id) return Node_Id
2957 Loc : constant Source_Ptr := Sloc (Typ);
2958 Conc_Typ : Entity_Id := Empty;
2959 Stmts : constant List_Id := New_List;
2962 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2964 -- Null body is generated for interface types and non-concurrent
2967 if Is_Interface (Typ)
2968 or else not Is_Concurrent_Record_Type (Typ)
2971 Make_Subprogram_Body (Loc,
2973 Make_Disp_Requeue_Spec (Typ),
2976 Handled_Statement_Sequence =>
2977 Make_Handled_Sequence_Of_Statements (Loc,
2978 New_List (Make_Null_Statement (Loc))));
2981 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2983 if Ekind (Conc_Typ) = E_Protected_Type then
2985 -- Generate statements:
2987 -- System.Tasking.Protected_Objects.Operations.
2988 -- Requeue_Protected_Entry
2989 -- (Protection_Entries_Access (P),
2990 -- O._object'Unchecked_Access,
2991 -- Protected_Entry_Index (I),
2994 -- System.Tasking.Protected_Objects.Operations.
2995 -- Requeue_Task_To_Protected_Entry
2996 -- (O._object'Unchecked_Access,
2997 -- Protected_Entry_Index (I),
3001 if Restriction_Active (No_Entry_Queue) then
3002 Append_To (Stmts, Make_Null_Statement (Loc));
3005 Make_If_Statement (Loc,
3006 Condition => Make_Identifier (Loc, Name_uF),
3011 -- Call to Requeue_Protected_Entry
3013 Make_Procedure_Call_Statement (Loc,
3016 RTE (RE_Requeue_Protected_Entry), Loc),
3017 Parameter_Associations =>
3020 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
3023 RTE (RE_Protection_Entries_Access), Loc),
3025 Make_Identifier (Loc, Name_uP)),
3027 Make_Attribute_Reference (Loc, -- O._object'Acc
3029 Name_Unchecked_Access,
3031 Make_Selected_Component (Loc,
3033 Make_Identifier (Loc, Name_uO),
3035 Make_Identifier (Loc, Name_uObject))),
3037 Make_Unchecked_Type_Conversion (Loc, -- entry index
3040 RTE (RE_Protected_Entry_Index), Loc),
3041 Expression => Make_Identifier (Loc, Name_uI)),
3043 Make_Identifier (Loc, Name_uA)))), -- abort status
3048 -- Call to Requeue_Task_To_Protected_Entry
3050 Make_Procedure_Call_Statement (Loc,
3053 RTE (RE_Requeue_Task_To_Protected_Entry), Loc),
3054 Parameter_Associations =>
3057 Make_Attribute_Reference (Loc, -- O._object'Acc
3059 Name_Unchecked_Access,
3061 Make_Selected_Component (Loc,
3063 Make_Identifier (Loc, Name_uO),
3065 Make_Identifier (Loc, Name_uObject))),
3067 Make_Unchecked_Type_Conversion (Loc, -- entry index
3070 RTE (RE_Protected_Entry_Index), Loc),
3072 Make_Identifier (Loc, Name_uI)),
3074 Make_Identifier (Loc, Name_uA)))))); -- abort status
3077 pragma Assert (Is_Task_Type (Conc_Typ));
3081 -- System.Tasking.Rendezvous.Requeue_Protected_To_Task_Entry
3082 -- (Protection_Entries_Access (P),
3084 -- Task_Entry_Index (I),
3087 -- System.Tasking.Rendezvous.Requeue_Task_Entry
3089 -- Task_Entry_Index (I),
3094 Make_If_Statement (Loc,
3095 Condition => Make_Identifier (Loc, Name_uF),
3097 Then_Statements => New_List (
3099 -- Call to Requeue_Protected_To_Task_Entry
3101 Make_Procedure_Call_Statement (Loc,
3104 (RTE (RE_Requeue_Protected_To_Task_Entry), Loc),
3106 Parameter_Associations => New_List (
3108 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
3111 (RTE (RE_Protection_Entries_Access), Loc),
3112 Expression => Make_Identifier (Loc, Name_uP)),
3114 Make_Selected_Component (Loc, -- O._task_id
3115 Prefix => Make_Identifier (Loc, Name_uO),
3116 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
3118 Make_Unchecked_Type_Conversion (Loc, -- entry index
3120 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
3121 Expression => Make_Identifier (Loc, Name_uI)),
3123 Make_Identifier (Loc, Name_uA)))), -- abort status
3125 Else_Statements => New_List (
3127 -- Call to Requeue_Task_Entry
3129 Make_Procedure_Call_Statement (Loc,
3130 Name => New_Reference_To (RTE (RE_Requeue_Task_Entry), Loc),
3132 Parameter_Associations => New_List (
3134 Make_Selected_Component (Loc, -- O._task_id
3135 Prefix => Make_Identifier (Loc, Name_uO),
3136 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
3138 Make_Unchecked_Type_Conversion (Loc, -- entry index
3140 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
3141 Expression => Make_Identifier (Loc, Name_uI)),
3143 Make_Identifier (Loc, Name_uA)))))); -- abort status
3146 -- Even though no declarations are needed in both cases, we allocate
3147 -- a list for entities added by Freeze.
3150 Make_Subprogram_Body (Loc,
3152 Make_Disp_Requeue_Spec (Typ),
3155 Handled_Statement_Sequence =>
3156 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
3157 end Make_Disp_Requeue_Body;
3159 ----------------------------
3160 -- Make_Disp_Requeue_Spec --
3161 ----------------------------
3163 function Make_Disp_Requeue_Spec
3164 (Typ : Entity_Id) return Node_Id
3166 Loc : constant Source_Ptr := Sloc (Typ);
3169 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3171 -- O : in out Typ; - Object parameter
3172 -- F : Boolean; - Protected (True) / task (False) flag
3173 -- P : Address; - Protection_Entries_Access value
3174 -- I : Entry_Index - Index of entry call
3175 -- A : Boolean - Abort flag
3177 -- Note that the Protection_Entries_Access value is represented as a
3178 -- System.Address in order to avoid dragging in the tasking runtime
3179 -- when compiling sources without tasking constructs.
3182 Make_Procedure_Specification (Loc,
3183 Defining_Unit_Name =>
3184 Make_Defining_Identifier (Loc, Name_uDisp_Requeue),
3186 Parameter_Specifications =>
3189 Make_Parameter_Specification (Loc, -- O
3190 Defining_Identifier =>
3191 Make_Defining_Identifier (Loc, Name_uO),
3193 New_Reference_To (Typ, Loc),
3195 Out_Present => True),
3197 Make_Parameter_Specification (Loc, -- F
3198 Defining_Identifier =>
3199 Make_Defining_Identifier (Loc, Name_uF),
3201 New_Reference_To (Standard_Boolean, Loc)),
3203 Make_Parameter_Specification (Loc, -- P
3204 Defining_Identifier =>
3205 Make_Defining_Identifier (Loc, Name_uP),
3207 New_Reference_To (RTE (RE_Address), Loc)),
3209 Make_Parameter_Specification (Loc, -- I
3210 Defining_Identifier =>
3211 Make_Defining_Identifier (Loc, Name_uI),
3213 New_Reference_To (Standard_Integer, Loc)),
3215 Make_Parameter_Specification (Loc, -- A
3216 Defining_Identifier =>
3217 Make_Defining_Identifier (Loc, Name_uA),
3219 New_Reference_To (Standard_Boolean, Loc))));
3220 end Make_Disp_Requeue_Spec;
3222 ---------------------------------
3223 -- Make_Disp_Timed_Select_Body --
3224 ---------------------------------
3226 -- For interface types, generate:
3228 -- procedure _Disp_Timed_Select
3229 -- (T : in out <Typ>;
3231 -- P : System.Address;
3234 -- C : out Ada.Tags.Prim_Op_Kind;
3239 -- end _Disp_Timed_Select;
3241 -- For protected types, generate:
3243 -- procedure _Disp_Timed_Select
3244 -- (T : in out <Typ>;
3246 -- P : System.Address;
3249 -- C : out Ada.Tags.Prim_Op_Kind;
3255 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP), S);
3257 -- if C = Ada.Tags.POK_Procedure
3258 -- or else C = Ada.Tags.POK_Protected_Procedure
3259 -- or else C = Ada.Tags.POK_Task_Procedure
3265 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
3266 -- System.Tasking.Protected_Objects.Operations.
3267 -- Timed_Protected_Entry_Call
3268 -- (T._object'Access,
3269 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
3274 -- end _Disp_Timed_Select;
3276 -- For task types, generate:
3278 -- procedure _Disp_Timed_Select
3279 -- (T : in out <Typ>;
3281 -- P : System.Address;
3284 -- C : out Ada.Tags.Prim_Op_Kind;
3290 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
3291 -- System.Tasking.Rendezvous.Timed_Task_Entry_Call
3293 -- System.Tasking.Task_Entry_Index (I),
3298 -- end _Disp_Time_Select;
3300 function Make_Disp_Timed_Select_Body
3301 (Typ : Entity_Id) return Node_Id
3303 Loc : constant Source_Ptr := Sloc (Typ);
3304 Conc_Typ : Entity_Id := Empty;
3305 Decls : constant List_Id := New_List;
3307 Stmts : constant List_Id := New_List;
3311 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3313 -- Null body is generated for interface types
3315 if Is_Interface (Typ) then
3317 Make_Subprogram_Body (Loc,
3319 Make_Disp_Timed_Select_Spec (Typ),
3322 Handled_Statement_Sequence =>
3323 Make_Handled_Sequence_Of_Statements (Loc,
3324 New_List (Make_Null_Statement (Loc))));
3327 if Is_Concurrent_Record_Type (Typ) then
3328 Conc_Typ := Corresponding_Concurrent_Type (Typ);
3333 -- where I will be used to capture the entry index of the primitive
3334 -- wrapper at position S.
3337 Make_Object_Declaration (Loc,
3338 Defining_Identifier =>
3339 Make_Defining_Identifier (Loc, Name_uI),
3340 Object_Definition =>
3341 New_Reference_To (Standard_Integer, Loc)));
3344 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
3346 -- if C = POK_Procedure
3347 -- or else C = POK_Protected_Procedure
3348 -- or else C = POK_Task_Procedure;
3354 Build_Common_Dispatching_Select_Statements (Typ, Stmts);
3357 -- I := Get_Entry_Index (tag! (<type>VP), S);
3359 -- I is the entry index and S is the dispatch table slot
3361 if Tagged_Type_Expansion then
3363 Unchecked_Convert_To (RTE (RE_Tag),
3365 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));
3369 Make_Attribute_Reference (Loc,
3370 Prefix => New_Reference_To (Typ, Loc),
3371 Attribute_Name => Name_Tag);
3375 Make_Assignment_Statement (Loc,
3376 Name => Make_Identifier (Loc, Name_uI),
3378 Make_Function_Call (Loc,
3380 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
3381 Parameter_Associations =>
3384 Make_Identifier (Loc, Name_uS)))));
3388 if Ekind (Conc_Typ) = E_Protected_Type then
3390 -- Build T._object'Access
3393 Make_Attribute_Reference (Loc,
3394 Attribute_Name => Name_Unchecked_Access,
3396 Make_Selected_Component (Loc,
3397 Prefix => Make_Identifier (Loc, Name_uT),
3398 Selector_Name => Make_Identifier (Loc, Name_uObject)));
3400 -- Normal case, No_Entry_Queue restriction not active. In this
3401 -- case we generate:
3403 -- Timed_Protected_Entry_Call
3404 -- (T._object'access,
3405 -- Protected_Entry_Index! (I),
3408 -- where T is the protected object, I is the entry index, P are
3409 -- the wrapped parameters, D is the delay amount, M is the delay
3410 -- mode and F is the status flag.
3412 case Corresponding_Runtime_Package (Conc_Typ) is
3413 when System_Tasking_Protected_Objects_Entries =>
3415 Make_Procedure_Call_Statement (Loc,
3418 (RTE (RE_Timed_Protected_Entry_Call), Loc),
3419 Parameter_Associations =>
3423 Make_Unchecked_Type_Conversion (Loc, -- entry index
3426 (RTE (RE_Protected_Entry_Index), Loc),
3428 Make_Identifier (Loc, Name_uI)),
3430 Make_Identifier (Loc, Name_uP), -- parameter block
3431 Make_Identifier (Loc, Name_uD), -- delay
3432 Make_Identifier (Loc, Name_uM), -- delay mode
3433 Make_Identifier (Loc, Name_uF)))); -- status flag
3435 when System_Tasking_Protected_Objects_Single_Entry =>
3438 -- Timed_Protected_Single_Entry_Call
3439 -- (T._object'access, P, D, M, F);
3441 -- where T is the protected object, P is the wrapped
3442 -- parameters, D is the delay amount, M is the delay mode, F
3443 -- is the status flag.
3446 Make_Procedure_Call_Statement (Loc,
3449 (RTE (RE_Timed_Protected_Single_Entry_Call), Loc),
3450 Parameter_Associations =>
3453 Make_Identifier (Loc, Name_uP), -- parameter block
3454 Make_Identifier (Loc, Name_uD), -- delay
3455 Make_Identifier (Loc, Name_uM), -- delay mode
3456 Make_Identifier (Loc, Name_uF)))); -- status flag
3459 raise Program_Error;
3465 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
3468 -- Timed_Task_Entry_Call (
3470 -- Task_Entry_Index! (I),
3476 -- where T is the task object, I is the entry index, P are the
3477 -- wrapped parameters, D is the delay amount, M is the delay
3478 -- mode and F is the status flag.
3481 Make_Procedure_Call_Statement (Loc,
3483 New_Reference_To (RTE (RE_Timed_Task_Entry_Call), Loc),
3484 Parameter_Associations =>
3487 Make_Selected_Component (Loc, -- T._task_id
3488 Prefix => Make_Identifier (Loc, Name_uT),
3489 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
3491 Make_Unchecked_Type_Conversion (Loc, -- entry index
3493 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
3494 Expression => Make_Identifier (Loc, Name_uI)),
3496 Make_Identifier (Loc, Name_uP), -- parameter block
3497 Make_Identifier (Loc, Name_uD), -- delay
3498 Make_Identifier (Loc, Name_uM), -- delay mode
3499 Make_Identifier (Loc, Name_uF)))); -- status flag
3503 -- Ensure that the statements list is non-empty
3505 Append_To (Stmts, Make_Null_Statement (Loc));
3509 Make_Subprogram_Body (Loc,
3511 Make_Disp_Timed_Select_Spec (Typ),
3514 Handled_Statement_Sequence =>
3515 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
3516 end Make_Disp_Timed_Select_Body;
3518 ---------------------------------
3519 -- Make_Disp_Timed_Select_Spec --
3520 ---------------------------------
3522 function Make_Disp_Timed_Select_Spec
3523 (Typ : Entity_Id) return Node_Id
3525 Loc : constant Source_Ptr := Sloc (Typ);
3526 Def_Id : constant Node_Id :=
3527 Make_Defining_Identifier (Loc,
3528 Name_uDisp_Timed_Select);
3529 Params : constant List_Id := New_List;
3532 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3534 -- T : in out Typ; -- Object parameter
3535 -- S : Integer; -- Primitive operation slot
3536 -- P : Address; -- Wrapped parameters
3537 -- D : Duration; -- Delay
3538 -- M : Integer; -- Delay Mode
3539 -- C : out Prim_Op_Kind; -- Call kind
3540 -- F : out Boolean; -- Status flag
3542 Append_List_To (Params, New_List (
3544 Make_Parameter_Specification (Loc,
3545 Defining_Identifier =>
3546 Make_Defining_Identifier (Loc, Name_uT),
3548 New_Reference_To (Typ, Loc),
3550 Out_Present => True),
3552 Make_Parameter_Specification (Loc,
3553 Defining_Identifier =>
3554 Make_Defining_Identifier (Loc, Name_uS),
3556 New_Reference_To (Standard_Integer, Loc)),
3558 Make_Parameter_Specification (Loc,
3559 Defining_Identifier =>
3560 Make_Defining_Identifier (Loc, Name_uP),
3562 New_Reference_To (RTE (RE_Address), Loc)),
3564 Make_Parameter_Specification (Loc,
3565 Defining_Identifier =>
3566 Make_Defining_Identifier (Loc, Name_uD),
3568 New_Reference_To (Standard_Duration, Loc)),
3570 Make_Parameter_Specification (Loc,
3571 Defining_Identifier =>
3572 Make_Defining_Identifier (Loc, Name_uM),
3574 New_Reference_To (Standard_Integer, Loc)),
3576 Make_Parameter_Specification (Loc,
3577 Defining_Identifier =>
3578 Make_Defining_Identifier (Loc, Name_uC),
3580 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
3581 Out_Present => True)));
3584 Make_Parameter_Specification (Loc,
3585 Defining_Identifier =>
3586 Make_Defining_Identifier (Loc, Name_uF),
3588 New_Reference_To (Standard_Boolean, Loc),
3589 Out_Present => True));
3592 Make_Procedure_Specification (Loc,
3593 Defining_Unit_Name => Def_Id,
3594 Parameter_Specifications => Params);
3595 end Make_Disp_Timed_Select_Spec;
3601 -- The frontend supports two models for expanding dispatch tables
3602 -- associated with library-level defined tagged types: statically
3603 -- and non-statically allocated dispatch tables. In the former case
3604 -- the object containing the dispatch table is constant and it is
3605 -- initialized by means of a positional aggregate. In the latter case,
3606 -- the object containing the dispatch table is a variable which is
3607 -- initialized by means of assignments.
3609 -- In case of locally defined tagged types, the object containing the
3610 -- object containing the dispatch table is always a variable (instead
3611 -- of a constant). This is currently required to give support to late
3612 -- overriding of primitives. For example:
3614 -- procedure Example is
3616 -- type T1 is tagged null record;
3617 -- procedure Prim (O : T1);
3620 -- type T2 is new Pkg.T1 with null record;
3621 -- procedure Prim (X : T2) is -- late overriding
3627 function Make_DT (Typ : Entity_Id; N : Node_Id := Empty) return List_Id is
3628 Loc : constant Source_Ptr := Sloc (Typ);
3630 Max_Predef_Prims : constant Int :=
3634 (Parent (RTE (RE_Max_Predef_Prims)))));
3636 DT_Decl : constant Elist_Id := New_Elmt_List;
3637 DT_Aggr : constant Elist_Id := New_Elmt_List;
3638 -- Entities marked with attribute Is_Dispatch_Table_Entity
3640 procedure Check_Premature_Freezing
3642 Tagged_Type : Entity_Id;
3644 -- Verify that all non-tagged types in the profile of a subprogram
3645 -- are frozen at the point the subprogram is frozen. This enforces
3646 -- the rule on RM 13.14 (14) as modified by AI05-019. At the point a
3647 -- subprogram is frozen, enough must be known about it to build the
3648 -- activation record for it, which requires at least that the size of
3649 -- all parameters be known. Controlling arguments are by-reference,
3650 -- and therefore the rule only applies to non-tagged types.
3651 -- Typical violation of the rule involves an object declaration that
3652 -- freezes a tagged type, when one of its primitive operations has a
3653 -- type in its profile whose full view has not been analyzed yet.
3654 -- More complex cases involve composite types that have one private
3655 -- unfrozen subcomponent.
3657 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0);
3658 -- Export the dispatch table DT of tagged type Typ. Required to generate
3659 -- forward references and statically allocate the table. For primary
3660 -- dispatch tables Index is 0; for secondary dispatch tables the value
3661 -- of index must match the Suffix_Index value assigned to the table by
3662 -- Make_Tags when generating its unique external name, and it is used to
3663 -- retrieve from the Dispatch_Table_Wrappers list associated with Typ
3664 -- the external name generated by Import_DT.
3666 procedure Make_Secondary_DT
3670 Num_Iface_Prims : Nat;
3671 Iface_DT_Ptr : Entity_Id;
3672 Predef_Prims_Ptr : Entity_Id;
3673 Build_Thunks : Boolean;
3675 -- Ada 2005 (AI-251): Expand the declarations for a Secondary Dispatch
3676 -- Table of Typ associated with Iface. Each abstract interface of Typ
3677 -- has two secondary dispatch tables: one containing pointers to thunks
3678 -- and another containing pointers to the primitives covering the
3679 -- interface primitives. The former secondary table is generated when
3680 -- Build_Thunks is True, and provides common support for dispatching
3681 -- calls through interface types; the latter secondary table is
3682 -- generated when Build_Thunks is False, and provides support for
3683 -- Generic Dispatching Constructors that dispatch calls through
3684 -- interface types. When constructing this latter table the value of
3685 -- Suffix_Index is -1 to indicate that there is no need to export such
3686 -- table when building statically allocated dispatch tables; a positive
3687 -- value of Suffix_Index must match the Suffix_Index value assigned to
3688 -- this secondary dispatch table by Make_Tags when its unique external
3689 -- name was generated.
3691 ------------------------------
3692 -- Check_Premature_Freezing --
3693 ------------------------------
3695 procedure Check_Premature_Freezing
3697 Tagged_Type : Entity_Id;
3704 and then Is_Private_Type (Typ)
3705 and then No (Full_View (Typ))
3706 and then not Is_Generic_Type (Typ)
3707 and then not Is_Tagged_Type (Typ)
3708 and then not Is_Frozen (Typ)
3710 Error_Msg_Sloc := Sloc (Subp);
3712 ("declaration must appear after completion of type &", N, Typ);
3714 ("\which is an untagged type in the profile of"
3715 & " primitive operation & declared#", N, Subp);
3718 Comp := Private_Component (Typ);
3720 if not Is_Tagged_Type (Typ)
3721 and then Present (Comp)
3722 and then not Is_Frozen (Comp)
3724 Error_Msg_Sloc := Sloc (Subp);
3725 Error_Msg_Node_2 := Subp;
3726 Error_Msg_Name_1 := Chars (Tagged_Type);
3728 ("declaration must appear after completion of type &",
3731 ("\which is a component of untagged type& in the profile of"
3732 & " primitive & of type % that is frozen by the declaration ",
3736 end Check_Premature_Freezing;
3742 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0)
3748 Set_Is_Statically_Allocated (DT);
3749 Set_Is_True_Constant (DT);
3750 Set_Is_Exported (DT);
3753 Elmt := First_Elmt (Dispatch_Table_Wrappers (Typ));
3754 while Count /= Index loop
3759 pragma Assert (Related_Type (Node (Elmt)) = Typ);
3762 (Entity => Node (Elmt),
3763 Has_Suffix => True);
3765 Set_Interface_Name (DT,
3766 Make_String_Literal (Loc,
3767 Strval => String_From_Name_Buffer));
3769 -- Ensure proper Sprint output of this implicit importation
3771 Set_Is_Internal (DT);
3775 -----------------------
3776 -- Make_Secondary_DT --
3777 -----------------------
3779 procedure Make_Secondary_DT
3783 Num_Iface_Prims : Nat;
3784 Iface_DT_Ptr : Entity_Id;
3785 Predef_Prims_Ptr : Entity_Id;
3786 Build_Thunks : Boolean;
3789 Loc : constant Source_Ptr := Sloc (Typ);
3790 Exporting_Table : constant Boolean :=
3791 Building_Static_DT (Typ)
3792 and then Suffix_Index > 0;
3793 Iface_DT : constant Entity_Id := Make_Temporary (Loc, 'T');
3794 Predef_Prims : constant Entity_Id := Make_Temporary (Loc, 'R');
3795 DT_Constr_List : List_Id;
3796 DT_Aggr_List : List_Id;
3797 Empty_DT : Boolean := False;
3798 Nb_Predef_Prims : Nat := 0;
3802 OSD_Aggr_List : List_Id;
3805 Prim_Elmt : Elmt_Id;
3806 Prim_Ops_Aggr_List : List_Id;
3809 -- Handle cases in which we do not generate statically allocated
3812 if not Building_Static_DT (Typ) then
3813 Set_Ekind (Predef_Prims, E_Variable);
3814 Set_Ekind (Iface_DT, E_Variable);
3816 -- Statically allocated dispatch tables and related entities are
3820 Set_Ekind (Predef_Prims, E_Constant);
3821 Set_Is_Statically_Allocated (Predef_Prims);
3822 Set_Is_True_Constant (Predef_Prims);
3824 Set_Ekind (Iface_DT, E_Constant);
3825 Set_Is_Statically_Allocated (Iface_DT);
3826 Set_Is_True_Constant (Iface_DT);
3829 -- Calculate the number of slots of the dispatch table. If the number
3830 -- of primitives of Typ is 0 we reserve a dummy single entry for its
3831 -- DT because at run time the pointer to this dummy entry will be
3834 if Num_Iface_Prims = 0 then
3838 Nb_Prim := Num_Iface_Prims;
3843 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
3844 -- (predef-prim-op-thunk-1'address,
3845 -- predef-prim-op-thunk-2'address,
3847 -- predef-prim-op-thunk-n'address);
3848 -- for Predef_Prims'Alignment use Address'Alignment
3850 -- Stage 1: Calculate the number of predefined primitives
3852 if not Building_Static_DT (Typ) then
3853 Nb_Predef_Prims := Max_Predef_Prims;
3855 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3856 while Present (Prim_Elmt) loop
3857 Prim := Node (Prim_Elmt);
3859 if Is_Predefined_Dispatching_Operation (Prim)
3860 and then not Is_Abstract_Subprogram (Prim)
3862 Pos := UI_To_Int (DT_Position (Prim));
3864 if Pos > Nb_Predef_Prims then
3865 Nb_Predef_Prims := Pos;
3869 Next_Elmt (Prim_Elmt);
3873 -- Stage 2: Create the thunks associated with the predefined
3874 -- primitives and save their entity to fill the aggregate.
3877 Prim_Table : array (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
3879 Thunk_Id : Entity_Id;
3880 Thunk_Code : Node_Id;
3883 Prim_Ops_Aggr_List := New_List;
3884 Prim_Table := (others => Empty);
3886 if Building_Static_DT (Typ) then
3887 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3888 while Present (Prim_Elmt) loop
3889 Prim := Node (Prim_Elmt);
3891 if Is_Predefined_Dispatching_Operation (Prim)
3892 and then not Is_Abstract_Subprogram (Prim)
3893 and then not Is_Eliminated (Prim)
3894 and then not Present (Prim_Table
3895 (UI_To_Int (DT_Position (Prim))))
3897 if not Build_Thunks then
3898 Prim_Table (UI_To_Int (DT_Position (Prim))) :=
3902 Expand_Interface_Thunk
3903 (Ultimate_Alias (Prim), Thunk_Id, Thunk_Code);
3905 if Present (Thunk_Id) then
3906 Append_To (Result, Thunk_Code);
3907 Prim_Table (UI_To_Int (DT_Position (Prim)))
3913 Next_Elmt (Prim_Elmt);
3917 for J in Prim_Table'Range loop
3918 if Present (Prim_Table (J)) then
3920 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
3921 Make_Attribute_Reference (Loc,
3922 Prefix => New_Reference_To (Prim_Table (J), Loc),
3923 Attribute_Name => Name_Unrestricted_Access));
3925 New_Node := Make_Null (Loc);
3928 Append_To (Prim_Ops_Aggr_List, New_Node);
3932 Make_Aggregate (Loc,
3933 Expressions => Prim_Ops_Aggr_List);
3935 -- Remember aggregates initializing dispatch tables
3937 Append_Elmt (New_Node, DT_Aggr);
3940 Make_Subtype_Declaration (Loc,
3941 Defining_Identifier => Make_Temporary (Loc, 'S'),
3942 Subtype_Indication =>
3943 New_Reference_To (RTE (RE_Address_Array), Loc));
3945 Append_To (Result, Decl);
3948 Make_Object_Declaration (Loc,
3949 Defining_Identifier => Predef_Prims,
3950 Constant_Present => Building_Static_DT (Typ),
3951 Aliased_Present => True,
3952 Object_Definition => New_Reference_To
3953 (Defining_Identifier (Decl), Loc),
3954 Expression => New_Node));
3957 Make_Attribute_Definition_Clause (Loc,
3958 Name => New_Reference_To (Predef_Prims, Loc),
3959 Chars => Name_Alignment,
3961 Make_Attribute_Reference (Loc,
3963 New_Reference_To (RTE (RE_Integer_Address), Loc),
3964 Attribute_Name => Name_Alignment)));
3969 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
3970 -- (OSD_Table => (1 => <value>,
3974 -- Iface_DT : Dispatch_Table (Nb_Prims) :=
3975 -- ([ Signature => <sig-value> ],
3976 -- Tag_Kind => <tag_kind-value>,
3977 -- Predef_Prims => Predef_Prims'Address,
3978 -- Offset_To_Top => 0,
3979 -- OSD => OSD'Address,
3980 -- Prims_Ptr => (prim-op-1'address,
3981 -- prim-op-2'address,
3983 -- prim-op-n'address));
3984 -- for Iface_DT'Alignment use Address'Alignment;
3986 -- Stage 3: Initialize the discriminant and the record components
3988 DT_Constr_List := New_List;
3989 DT_Aggr_List := New_List;
3991 -- Nb_Prim. If the tagged type has no primitives we add a dummy
3992 -- slot whose address will be the tag of this type.
3995 New_Node := Make_Integer_Literal (Loc, 1);
3997 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
4000 Append_To (DT_Constr_List, New_Node);
4001 Append_To (DT_Aggr_List, New_Copy (New_Node));
4005 if RTE_Record_Component_Available (RE_Signature) then
4006 Append_To (DT_Aggr_List,
4007 New_Reference_To (RTE (RE_Secondary_DT), Loc));
4012 if RTE_Record_Component_Available (RE_Tag_Kind) then
4013 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
4018 Append_To (DT_Aggr_List,
4019 Make_Attribute_Reference (Loc,
4020 Prefix => New_Reference_To (Predef_Prims, Loc),
4021 Attribute_Name => Name_Address));
4023 -- Note: The correct value of Offset_To_Top will be set by the init
4026 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
4028 -- Generate the Object Specific Data table required to dispatch calls
4029 -- through synchronized interfaces.
4032 or else Is_Abstract_Type (Typ)
4033 or else Is_Controlled (Typ)
4034 or else Restriction_Active (No_Dispatching_Calls)
4035 or else not Is_Limited_Type (Typ)
4036 or else not Has_Interfaces (Typ)
4037 or else not Build_Thunks
4038 or else not RTE_Record_Component_Available (RE_OSD_Table)
4040 -- No OSD table required
4042 Append_To (DT_Aggr_List,
4043 New_Reference_To (RTE (RE_Null_Address), Loc));
4046 OSD_Aggr_List := New_List;
4049 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
4051 Prim_Alias : Entity_Id;
4052 Prim_Elmt : Elmt_Id;
4058 Prim_Table := (others => Empty);
4059 Prim_Alias := Empty;
4061 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4062 while Present (Prim_Elmt) loop
4063 Prim := Node (Prim_Elmt);
4065 if Present (Interface_Alias (Prim))
4066 and then Find_Dispatching_Type
4067 (Interface_Alias (Prim)) = Iface
4069 Prim_Alias := Interface_Alias (Prim);
4070 E := Ultimate_Alias (Prim);
4071 Pos := UI_To_Int (DT_Position (Prim_Alias));
4073 if Present (Prim_Table (Pos)) then
4074 pragma Assert (Prim_Table (Pos) = E);
4078 Prim_Table (Pos) := E;
4080 Append_To (OSD_Aggr_List,
4081 Make_Component_Association (Loc,
4082 Choices => New_List (
4083 Make_Integer_Literal (Loc,
4084 DT_Position (Prim_Alias))),
4086 Make_Integer_Literal (Loc,
4087 DT_Position (Alias (Prim)))));
4093 Next_Elmt (Prim_Elmt);
4095 pragma Assert (Count = Nb_Prim);
4098 OSD := Make_Temporary (Loc, 'I');
4101 Make_Object_Declaration (Loc,
4102 Defining_Identifier => OSD,
4103 Object_Definition =>
4104 Make_Subtype_Indication (Loc,
4106 New_Reference_To (RTE (RE_Object_Specific_Data), Loc),
4108 Make_Index_Or_Discriminant_Constraint (Loc,
4109 Constraints => New_List (
4110 Make_Integer_Literal (Loc, Nb_Prim)))),
4113 Make_Aggregate (Loc,
4114 Component_Associations => New_List (
4115 Make_Component_Association (Loc,
4116 Choices => New_List (
4118 (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
4120 Make_Integer_Literal (Loc, Nb_Prim)),
4122 Make_Component_Association (Loc,
4123 Choices => New_List (
4125 (RTE_Record_Component (RE_OSD_Table), Loc)),
4126 Expression => Make_Aggregate (Loc,
4127 Component_Associations => OSD_Aggr_List))))));
4130 Make_Attribute_Definition_Clause (Loc,
4131 Name => New_Reference_To (OSD, Loc),
4132 Chars => Name_Alignment,
4134 Make_Attribute_Reference (Loc,
4136 New_Reference_To (RTE (RE_Integer_Address), Loc),
4137 Attribute_Name => Name_Alignment)));
4139 -- In secondary dispatch tables the Typeinfo component contains
4140 -- the address of the Object Specific Data (see a-tags.ads)
4142 Append_To (DT_Aggr_List,
4143 Make_Attribute_Reference (Loc,
4144 Prefix => New_Reference_To (OSD, Loc),
4145 Attribute_Name => Name_Address));
4148 -- Initialize the table of primitive operations
4150 Prim_Ops_Aggr_List := New_List;
4153 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
4155 elsif Is_Abstract_Type (Typ)
4156 or else not Building_Static_DT (Typ)
4158 for J in 1 .. Nb_Prim loop
4159 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
4164 CPP_Nb_Prims : constant Nat := CPP_Num_Prims (Typ);
4167 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
4168 Thunk_Code : Node_Id;
4169 Thunk_Id : Entity_Id;
4172 Prim_Table := (others => Empty);
4174 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4175 while Present (Prim_Elmt) loop
4176 Prim := Node (Prim_Elmt);
4177 E := Ultimate_Alias (Prim);
4178 Prim_Pos := UI_To_Int (DT_Position (E));
4180 -- Do not reference predefined primitives because they are
4181 -- located in a separate dispatch table; skip abstract and
4182 -- eliminated primitives; skip primitives located in the C++
4183 -- part of the dispatch table because their slot is set by
4186 if not Is_Predefined_Dispatching_Operation (Prim)
4187 and then Present (Interface_Alias (Prim))
4188 and then not Is_Abstract_Subprogram (Alias (Prim))
4189 and then not Is_Eliminated (Alias (Prim))
4190 and then (not Is_CPP_Class (Root_Type (Typ))
4191 or else Prim_Pos > CPP_Nb_Prims)
4192 and then Find_Dispatching_Type
4193 (Interface_Alias (Prim)) = Iface
4195 -- Generate the code of the thunk only if the abstract
4196 -- interface type is not an immediate ancestor of
4197 -- Tagged_Type. Otherwise the DT associated with the
4198 -- interface is the primary DT.
4200 and then not Is_Ancestor (Iface, Typ,
4201 Use_Full_View => True)
4203 if not Build_Thunks then
4205 UI_To_Int (DT_Position (Interface_Alias (Prim)));
4206 Prim_Table (Prim_Pos) := Alias (Prim);
4209 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
4211 if Present (Thunk_Id) then
4213 UI_To_Int (DT_Position (Interface_Alias (Prim)));
4215 Prim_Table (Prim_Pos) := Thunk_Id;
4216 Append_To (Result, Thunk_Code);
4221 Next_Elmt (Prim_Elmt);
4224 for J in Prim_Table'Range loop
4225 if Present (Prim_Table (J)) then
4227 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
4228 Make_Attribute_Reference (Loc,
4229 Prefix => New_Reference_To (Prim_Table (J), Loc),
4230 Attribute_Name => Name_Unrestricted_Access));
4233 New_Node := Make_Null (Loc);
4236 Append_To (Prim_Ops_Aggr_List, New_Node);
4242 Make_Aggregate (Loc,
4243 Expressions => Prim_Ops_Aggr_List);
4245 Append_To (DT_Aggr_List, New_Node);
4247 -- Remember aggregates initializing dispatch tables
4249 Append_Elmt (New_Node, DT_Aggr);
4251 -- Note: Secondary dispatch tables cannot be declared constant
4252 -- because the component Offset_To_Top is currently initialized
4253 -- by the IP routine.
4256 Make_Object_Declaration (Loc,
4257 Defining_Identifier => Iface_DT,
4258 Aliased_Present => True,
4259 Constant_Present => False,
4261 Object_Definition =>
4262 Make_Subtype_Indication (Loc,
4263 Subtype_Mark => New_Reference_To
4264 (RTE (RE_Dispatch_Table_Wrapper), Loc),
4265 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4266 Constraints => DT_Constr_List)),
4269 Make_Aggregate (Loc,
4270 Expressions => DT_Aggr_List)));
4273 Make_Attribute_Definition_Clause (Loc,
4274 Name => New_Reference_To (Iface_DT, Loc),
4275 Chars => Name_Alignment,
4278 Make_Attribute_Reference (Loc,
4280 New_Reference_To (RTE (RE_Integer_Address), Loc),
4281 Attribute_Name => Name_Alignment)));
4283 if Exporting_Table then
4284 Export_DT (Typ, Iface_DT, Suffix_Index);
4286 -- Generate code to create the pointer to the dispatch table
4288 -- Iface_DT_Ptr : Tag := Tag!(DT.Prims_Ptr'Address);
4290 -- Note: This declaration is not added here if the table is exported
4291 -- because in such case Make_Tags has already added this declaration.
4295 Make_Object_Declaration (Loc,
4296 Defining_Identifier => Iface_DT_Ptr,
4297 Constant_Present => True,
4299 Object_Definition =>
4300 New_Reference_To (RTE (RE_Interface_Tag), Loc),
4303 Unchecked_Convert_To (RTE (RE_Interface_Tag),
4304 Make_Attribute_Reference (Loc,
4306 Make_Selected_Component (Loc,
4307 Prefix => New_Reference_To (Iface_DT, Loc),
4310 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
4311 Attribute_Name => Name_Address))));
4315 Make_Object_Declaration (Loc,
4316 Defining_Identifier => Predef_Prims_Ptr,
4317 Constant_Present => True,
4319 Object_Definition =>
4320 New_Reference_To (RTE (RE_Address), Loc),
4323 Make_Attribute_Reference (Loc,
4325 Make_Selected_Component (Loc,
4326 Prefix => New_Reference_To (Iface_DT, Loc),
4329 (RTE_Record_Component (RE_Predef_Prims), Loc)),
4330 Attribute_Name => Name_Address)));
4332 -- Remember entities containing dispatch tables
4334 Append_Elmt (Predef_Prims, DT_Decl);
4335 Append_Elmt (Iface_DT, DT_Decl);
4336 end Make_Secondary_DT;
4340 Elab_Code : constant List_Id := New_List;
4341 Result : constant List_Id := New_List;
4342 Tname : constant Name_Id := Chars (Typ);
4344 AI_Tag_Elmt : Elmt_Id;
4345 AI_Tag_Comp : Elmt_Id;
4346 DT_Aggr_List : List_Id;
4347 DT_Constr_List : List_Id;
4351 Iface_Table_Node : Node_Id;
4352 Name_ITable : Name_Id;
4353 Nb_Predef_Prims : Nat := 0;
4356 Num_Ifaces : Nat := 0;
4357 Parent_Typ : Entity_Id;
4359 Prim_Elmt : Elmt_Id;
4360 Prim_Ops_Aggr_List : List_Id;
4362 Typ_Comps : Elist_Id;
4363 Typ_Ifaces : Elist_Id;
4364 TSD_Aggr_List : List_Id;
4365 TSD_Tags_List : List_Id;
4367 -- The following name entries are used by Make_DT to generate a number
4368 -- of entities related to a tagged type. These entities may be generated
4369 -- in a scope other than that of the tagged type declaration, and if
4370 -- the entities for two tagged types with the same name happen to be
4371 -- generated in the same scope, we have to take care to use different
4372 -- names. This is achieved by means of a unique serial number appended
4373 -- to each generated entity name.
4375 Name_DT : constant Name_Id :=
4376 New_External_Name (Tname, 'T', Suffix_Index => -1);
4377 Name_Exname : constant Name_Id :=
4378 New_External_Name (Tname, 'E', Suffix_Index => -1);
4379 Name_HT_Link : constant Name_Id :=
4380 New_External_Name (Tname, 'H', Suffix_Index => -1);
4381 Name_Predef_Prims : constant Name_Id :=
4382 New_External_Name (Tname, 'R', Suffix_Index => -1);
4383 Name_SSD : constant Name_Id :=
4384 New_External_Name (Tname, 'S', Suffix_Index => -1);
4385 Name_TSD : constant Name_Id :=
4386 New_External_Name (Tname, 'B', Suffix_Index => -1);
4388 -- Entities built with above names
4390 DT : constant Entity_Id :=
4391 Make_Defining_Identifier (Loc, Name_DT);
4392 Exname : constant Entity_Id :=
4393 Make_Defining_Identifier (Loc, Name_Exname);
4394 HT_Link : constant Entity_Id :=
4395 Make_Defining_Identifier (Loc, Name_HT_Link);
4396 Predef_Prims : constant Entity_Id :=
4397 Make_Defining_Identifier (Loc, Name_Predef_Prims);
4398 SSD : constant Entity_Id :=
4399 Make_Defining_Identifier (Loc, Name_SSD);
4400 TSD : constant Entity_Id :=
4401 Make_Defining_Identifier (Loc, Name_TSD);
4403 -- Start of processing for Make_DT
4406 pragma Assert (Is_Frozen (Typ));
4408 -- Handle cases in which there is no need to build the dispatch table
4410 if Has_Dispatch_Table (Typ)
4411 or else No (Access_Disp_Table (Typ))
4412 or else Is_CPP_Class (Typ)
4413 or else Convention (Typ) = Convention_CIL
4414 or else Convention (Typ) = Convention_Java
4418 elsif No_Run_Time_Mode then
4419 Error_Msg_CRT ("tagged types", Typ);
4422 elsif not RTE_Available (RE_Tag) then
4424 Make_Object_Declaration (Loc,
4425 Defining_Identifier => Node (First_Elmt
4426 (Access_Disp_Table (Typ))),
4427 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4428 Constant_Present => True,
4430 Unchecked_Convert_To (RTE (RE_Tag),
4431 New_Reference_To (RTE (RE_Null_Address), Loc))));
4433 Analyze_List (Result, Suppress => All_Checks);
4434 Error_Msg_CRT ("tagged types", Typ);
4438 -- Ensure that the value of Max_Predef_Prims defined in a-tags is
4439 -- correct. Valid values are 10 under configurable runtime or 16
4440 -- with full runtime.
4442 if RTE_Available (RE_Interface_Data) then
4443 if Max_Predef_Prims /= 16 then
4444 Error_Msg_N ("run-time library configuration error", Typ);
4448 if Max_Predef_Prims /= 10 then
4449 Error_Msg_N ("run-time library configuration error", Typ);
4450 Error_Msg_CRT ("tagged types", Typ);
4455 -- Initialize Parent_Typ handling private types
4457 Parent_Typ := Etype (Typ);
4459 if Present (Full_View (Parent_Typ)) then
4460 Parent_Typ := Full_View (Parent_Typ);
4463 -- Ensure that all the primitives are frozen. This is only required when
4464 -- building static dispatch tables --- the primitives must be frozen to
4465 -- be referenced (otherwise we have problems with the backend). It is
4466 -- not a requirement with nonstatic dispatch tables because in this case
4467 -- we generate now an empty dispatch table; the extra code required to
4468 -- register the primitives in the slots will be generated later --- when
4469 -- each primitive is frozen (see Freeze_Subprogram).
4471 if Building_Static_DT (Typ) then
4473 Save : constant Boolean := Freezing_Library_Level_Tagged_Type;
4475 Prim_Elmt : Elmt_Id;
4479 Freezing_Library_Level_Tagged_Type := True;
4481 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4482 while Present (Prim_Elmt) loop
4483 Prim := Node (Prim_Elmt);
4484 Frnodes := Freeze_Entity (Prim, Typ);
4490 F := First_Formal (Prim);
4491 while Present (F) loop
4492 Check_Premature_Freezing (Prim, Typ, Etype (F));
4496 Check_Premature_Freezing (Prim, Typ, Etype (Prim));
4499 if Present (Frnodes) then
4500 Append_List_To (Result, Frnodes);
4503 Next_Elmt (Prim_Elmt);
4506 Freezing_Library_Level_Tagged_Type := Save;
4510 -- Ada 2005 (AI-251): Build the secondary dispatch tables
4512 if Has_Interfaces (Typ) then
4513 Collect_Interface_Components (Typ, Typ_Comps);
4515 -- Each secondary dispatch table is assigned an unique positive
4516 -- suffix index; such value also corresponds with the location of
4517 -- its entity in the Dispatch_Table_Wrappers list (see Make_Tags).
4519 -- Note: This value must be kept sync with the Suffix_Index values
4520 -- generated by Make_Tags
4524 Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
4526 AI_Tag_Comp := First_Elmt (Typ_Comps);
4527 while Present (AI_Tag_Comp) loop
4528 pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'P'));
4530 -- Build the secondary table containing pointers to thunks
4534 Iface => Base_Type (Related_Type (Node (AI_Tag_Comp))),
4535 Suffix_Index => Suffix_Index,
4536 Num_Iface_Prims => UI_To_Int
4537 (DT_Entry_Count (Node (AI_Tag_Comp))),
4538 Iface_DT_Ptr => Node (AI_Tag_Elmt),
4539 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
4540 Build_Thunks => True,
4543 -- Skip secondary dispatch table referencing thunks to predefined
4546 Next_Elmt (AI_Tag_Elmt);
4547 pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'Y'));
4549 -- Secondary dispatch table referencing user-defined primitives
4550 -- covered by this interface.
4552 Next_Elmt (AI_Tag_Elmt);
4553 pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'D'));
4555 -- Build the secondary table containing pointers to primitives
4556 -- (used to give support to Generic Dispatching Constructors).
4561 (Related_Type (Node (AI_Tag_Comp))),
4563 Num_Iface_Prims => UI_To_Int
4564 (DT_Entry_Count (Node (AI_Tag_Comp))),
4565 Iface_DT_Ptr => Node (AI_Tag_Elmt),
4566 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
4567 Build_Thunks => False,
4570 -- Skip secondary dispatch table referencing predefined primitives
4572 Next_Elmt (AI_Tag_Elmt);
4573 pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'Z'));
4575 Suffix_Index := Suffix_Index + 1;
4576 Next_Elmt (AI_Tag_Elmt);
4577 Next_Elmt (AI_Tag_Comp);
4581 -- Get the _tag entity and number of primitives of its dispatch table
4583 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
4584 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
4586 Set_Is_Statically_Allocated (DT, Is_Library_Level_Tagged_Type (Typ));
4587 Set_Is_Statically_Allocated (SSD, Is_Library_Level_Tagged_Type (Typ));
4588 Set_Is_Statically_Allocated (TSD, Is_Library_Level_Tagged_Type (Typ));
4589 Set_Is_Statically_Allocated (Predef_Prims,
4590 Is_Library_Level_Tagged_Type (Typ));
4592 -- In case of locally defined tagged type we declare the object
4593 -- containing the dispatch table by means of a variable. Its
4594 -- initialization is done later by means of an assignment. This is
4595 -- required to generate its External_Tag.
4597 if not Building_Static_DT (Typ) then
4600 -- DT : No_Dispatch_Table_Wrapper;
4601 -- for DT'Alignment use Address'Alignment;
4602 -- DT_Ptr : Tag := !Tag (DT.NDT_Prims_Ptr'Address);
4604 if not Has_DT (Typ) then
4606 Make_Object_Declaration (Loc,
4607 Defining_Identifier => DT,
4608 Aliased_Present => True,
4609 Constant_Present => False,
4610 Object_Definition =>
4612 (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
4615 Make_Attribute_Definition_Clause (Loc,
4616 Name => New_Reference_To (DT, Loc),
4617 Chars => Name_Alignment,
4619 Make_Attribute_Reference (Loc,
4621 New_Reference_To (RTE (RE_Integer_Address), Loc),
4622 Attribute_Name => Name_Alignment)));
4625 Make_Object_Declaration (Loc,
4626 Defining_Identifier => DT_Ptr,
4627 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4628 Constant_Present => True,
4630 Unchecked_Convert_To (RTE (RE_Tag),
4631 Make_Attribute_Reference (Loc,
4633 Make_Selected_Component (Loc,
4634 Prefix => New_Reference_To (DT, Loc),
4637 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
4638 Attribute_Name => Name_Address))));
4640 Set_Is_Statically_Allocated (DT_Ptr,
4641 Is_Library_Level_Tagged_Type (Typ));
4643 -- Generate the SCIL node for the previous object declaration
4644 -- because it has a tag initialization.
4646 if Generate_SCIL then
4648 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
4649 Set_SCIL_Entity (New_Node, Typ);
4650 Set_SCIL_Node (Last (Result), New_Node);
4654 -- DT : Dispatch_Table_Wrapper (Nb_Prim);
4655 -- for DT'Alignment use Address'Alignment;
4656 -- DT_Ptr : Tag := !Tag (DT.Prims_Ptr'Address);
4659 -- If the tagged type has no primitives we add a dummy slot
4660 -- whose address will be the tag of this type.
4664 New_List (Make_Integer_Literal (Loc, 1));
4667 New_List (Make_Integer_Literal (Loc, Nb_Prim));
4671 Make_Object_Declaration (Loc,
4672 Defining_Identifier => DT,
4673 Aliased_Present => True,
4674 Constant_Present => False,
4675 Object_Definition =>
4676 Make_Subtype_Indication (Loc,
4678 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
4679 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4680 Constraints => DT_Constr_List))));
4683 Make_Attribute_Definition_Clause (Loc,
4684 Name => New_Reference_To (DT, Loc),
4685 Chars => Name_Alignment,
4687 Make_Attribute_Reference (Loc,
4689 New_Reference_To (RTE (RE_Integer_Address), Loc),
4690 Attribute_Name => Name_Alignment)));
4693 Make_Object_Declaration (Loc,
4694 Defining_Identifier => DT_Ptr,
4695 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4696 Constant_Present => True,
4698 Unchecked_Convert_To (RTE (RE_Tag),
4699 Make_Attribute_Reference (Loc,
4701 Make_Selected_Component (Loc,
4702 Prefix => New_Reference_To (DT, Loc),
4705 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
4706 Attribute_Name => Name_Address))));
4708 Set_Is_Statically_Allocated (DT_Ptr,
4709 Is_Library_Level_Tagged_Type (Typ));
4711 -- Generate the SCIL node for the previous object declaration
4712 -- because it has a tag initialization.
4714 if Generate_SCIL then
4716 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
4717 Set_SCIL_Entity (New_Node, Typ);
4718 Set_SCIL_Node (Last (Result), New_Node);
4722 Make_Object_Declaration (Loc,
4723 Defining_Identifier =>
4724 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Typ)))),
4725 Constant_Present => True,
4726 Object_Definition => New_Reference_To
4727 (RTE (RE_Address), Loc),
4729 Make_Attribute_Reference (Loc,
4731 Make_Selected_Component (Loc,
4732 Prefix => New_Reference_To (DT, Loc),
4735 (RTE_Record_Component (RE_Predef_Prims), Loc)),
4736 Attribute_Name => Name_Address)));
4740 -- Generate: Exname : constant String := full_qualified_name (typ);
4741 -- The type itself may be an anonymous parent type, so use the first
4742 -- subtype to have a user-recognizable name.
4745 Make_Object_Declaration (Loc,
4746 Defining_Identifier => Exname,
4747 Constant_Present => True,
4748 Object_Definition => New_Reference_To (Standard_String, Loc),
4750 Make_String_Literal (Loc,
4751 Fully_Qualified_Name_String (First_Subtype (Typ)))));
4753 Set_Is_Statically_Allocated (Exname);
4754 Set_Is_True_Constant (Exname);
4756 -- Declare the object used by Ada.Tags.Register_Tag
4758 if RTE_Available (RE_Register_Tag) then
4760 Make_Object_Declaration (Loc,
4761 Defining_Identifier => HT_Link,
4762 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc)));
4765 -- Generate code to create the storage for the type specific data object
4766 -- with enough space to store the tags of the ancestors plus the tags
4767 -- of all the implemented interfaces (as described in a-tags.adb).
4769 -- TSD : Type_Specific_Data (I_Depth) :=
4770 -- (Idepth => I_Depth,
4771 -- Access_Level => Type_Access_Level (Typ),
4772 -- Expanded_Name => Cstring_Ptr!(Exname'Address))
4773 -- External_Tag => Cstring_Ptr!(Exname'Address))
4774 -- HT_Link => HT_Link'Address,
4775 -- Transportable => <<boolean-value>>,
4776 -- Type_Is_Abstract => <<boolean-value>>,
4777 -- Needs_Finalization => <<boolean-value>>,
4778 -- [ Size_Func => Size_Prim'Access ]
4779 -- [ Interfaces_Table => <<access-value>> ]
4780 -- [ SSD => SSD_Table'Address ]
4781 -- Tags_Table => (0 => null,
4784 -- for TSD'Alignment use Address'Alignment
4786 TSD_Aggr_List := New_List;
4788 -- Idepth: Count ancestors to compute the inheritance depth. For private
4789 -- extensions, always go to the full view in order to compute the real
4790 -- inheritance depth.
4793 Current_Typ : Entity_Id;
4794 Parent_Typ : Entity_Id;
4800 Parent_Typ := Etype (Current_Typ);
4802 if Is_Private_Type (Parent_Typ) then
4803 Parent_Typ := Full_View (Base_Type (Parent_Typ));
4806 exit when Parent_Typ = Current_Typ;
4808 I_Depth := I_Depth + 1;
4809 Current_Typ := Parent_Typ;
4813 Append_To (TSD_Aggr_List,
4814 Make_Integer_Literal (Loc, I_Depth));
4818 Append_To (TSD_Aggr_List,
4819 Make_Integer_Literal (Loc, Type_Access_Level (Typ)));
4823 Append_To (TSD_Aggr_List,
4824 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4825 Make_Attribute_Reference (Loc,
4826 Prefix => New_Reference_To (Exname, Loc),
4827 Attribute_Name => Name_Address)));
4829 -- External_Tag of a local tagged type
4831 -- <typ>A : constant String :=
4832 -- "Internal tag at 16#tag-addr#: <full-name-of-typ>";
4834 -- The reason we generate this strange name is that we do not want to
4835 -- enter local tagged types in the global hash table used to compute
4836 -- the Internal_Tag attribute for two reasons:
4838 -- 1. It is hard to avoid a tasking race condition for entering the
4839 -- entry into the hash table.
4841 -- 2. It would cause a storage leak, unless we rig up considerable
4842 -- mechanism to remove the entry from the hash table on exit.
4844 -- So what we do is to generate the above external tag name, where the
4845 -- hex address is the address of the local dispatch table (i.e. exactly
4846 -- the value we want if Internal_Tag is computed from this string).
4848 -- Of course this value will only be valid if the tagged type is still
4849 -- in scope, but it clearly must be erroneous to compute the internal
4850 -- tag of a tagged type that is out of scope!
4852 -- We don't do this processing if an explicit external tag has been
4853 -- specified. That's an odd case for which we have already issued a
4854 -- warning, where we will not be able to compute the internal tag.
4856 if not Is_Library_Level_Entity (Typ)
4857 and then not Has_External_Tag_Rep_Clause (Typ)
4860 Exname : constant Entity_Id :=
4861 Make_Defining_Identifier (Loc,
4862 New_External_Name (Tname, 'A'));
4864 Full_Name : constant String_Id :=
4865 Fully_Qualified_Name_String (First_Subtype (Typ));
4866 Str1_Id : String_Id;
4867 Str2_Id : String_Id;
4871 -- Str1 = "Internal tag at 16#";
4874 Store_String_Chars ("Internal tag at 16#");
4875 Str1_Id := End_String;
4878 -- Str2 = "#: <type-full-name>";
4881 Store_String_Chars ("#: ");
4882 Store_String_Chars (Full_Name);
4883 Str2_Id := End_String;
4886 -- Exname : constant String :=
4887 -- Str1 & Address_Image (Tag) & Str2;
4889 if RTE_Available (RE_Address_Image) then
4891 Make_Object_Declaration (Loc,
4892 Defining_Identifier => Exname,
4893 Constant_Present => True,
4894 Object_Definition => New_Reference_To
4895 (Standard_String, Loc),
4897 Make_Op_Concat (Loc,
4899 Make_String_Literal (Loc, Str1_Id),
4901 Make_Op_Concat (Loc,
4903 Make_Function_Call (Loc,
4906 (RTE (RE_Address_Image), Loc),
4907 Parameter_Associations => New_List (
4908 Unchecked_Convert_To (RTE (RE_Address),
4909 New_Reference_To (DT_Ptr, Loc)))),
4911 Make_String_Literal (Loc, Str2_Id)))));
4915 Make_Object_Declaration (Loc,
4916 Defining_Identifier => Exname,
4917 Constant_Present => True,
4918 Object_Definition => New_Reference_To
4919 (Standard_String, Loc),
4921 Make_Op_Concat (Loc,
4923 Make_String_Literal (Loc, Str1_Id),
4925 Make_String_Literal (Loc, Str2_Id))));
4929 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4930 Make_Attribute_Reference (Loc,
4931 Prefix => New_Reference_To (Exname, Loc),
4932 Attribute_Name => Name_Address));
4935 -- External tag of a library-level tagged type: Check for a definition
4936 -- of External_Tag. The clause is considered only if it applies to this
4937 -- specific tagged type, as opposed to one of its ancestors.
4938 -- If the type is an unconstrained type extension, we are building the
4939 -- dispatch table of its anonymous base type, so the external tag, if
4940 -- any was specified, must be retrieved from the first subtype. Go to
4941 -- the full view in case the clause is in the private part.
4945 Def : constant Node_Id := Get_Attribute_Definition_Clause
4946 (Underlying_Type (First_Subtype (Typ)),
4947 Attribute_External_Tag);
4949 Old_Val : String_Id;
4950 New_Val : String_Id;
4954 if not Present (Def)
4955 or else Entity (Name (Def)) /= First_Subtype (Typ)
4958 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4959 Make_Attribute_Reference (Loc,
4960 Prefix => New_Reference_To (Exname, Loc),
4961 Attribute_Name => Name_Address));
4963 Old_Val := Strval (Expr_Value_S (Expression (Def)));
4965 -- For the rep clause "for <typ>'external_tag use y" generate:
4967 -- <typ>A : constant string := y;
4969 -- <typ>A'Address is used to set the External_Tag component
4972 -- Create a new nul terminated string if it is not already
4974 if String_Length (Old_Val) > 0
4976 Get_String_Char (Old_Val, String_Length (Old_Val)) = 0
4980 Start_String (Old_Val);
4981 Store_String_Char (Get_Char_Code (ASCII.NUL));
4982 New_Val := End_String;
4985 E := Make_Defining_Identifier (Loc,
4986 New_External_Name (Chars (Typ), 'A'));
4989 Make_Object_Declaration (Loc,
4990 Defining_Identifier => E,
4991 Constant_Present => True,
4992 Object_Definition =>
4993 New_Reference_To (Standard_String, Loc),
4995 Make_String_Literal (Loc, New_Val)));
4998 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4999 Make_Attribute_Reference (Loc,
5000 Prefix => New_Reference_To (E, Loc),
5001 Attribute_Name => Name_Address));
5006 Append_To (TSD_Aggr_List, New_Node);
5010 if RTE_Available (RE_Register_Tag) then
5011 Append_To (TSD_Aggr_List,
5012 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
5013 Make_Attribute_Reference (Loc,
5014 Prefix => New_Reference_To (HT_Link, Loc),
5015 Attribute_Name => Name_Address)));
5017 Append_To (TSD_Aggr_List,
5018 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
5019 New_Reference_To (RTE (RE_Null_Address), Loc)));
5022 -- Transportable: Set for types that can be used in remote calls
5023 -- with respect to E.4(18) legality rules.
5026 Transportable : Entity_Id;
5032 or else Is_Shared_Passive (Typ)
5034 ((Is_Remote_Types (Typ)
5035 or else Is_Remote_Call_Interface (Typ))
5036 and then Original_View_In_Visible_Part (Typ))
5037 or else not Comes_From_Source (Typ));
5039 Append_To (TSD_Aggr_List,
5040 New_Occurrence_Of (Transportable, Loc));
5043 -- Type_Is_Abstract (Ada 2012: AI05-0173). This functionality is
5044 -- not available in the HIE runtime.
5046 if RTE_Record_Component_Available (RE_Type_Is_Abstract) then
5048 Type_Is_Abstract : Entity_Id;
5052 Boolean_Literals (Is_Abstract_Type (Typ));
5054 Append_To (TSD_Aggr_List,
5055 New_Occurrence_Of (Type_Is_Abstract, Loc));
5059 -- Needs_Finalization: Set if the type is controlled or has controlled
5063 Needs_Fin : Entity_Id;
5066 Needs_Fin := Boolean_Literals (Needs_Finalization (Typ));
5067 Append_To (TSD_Aggr_List, New_Occurrence_Of (Needs_Fin, Loc));
5072 if RTE_Record_Component_Available (RE_Size_Func) then
5074 -- Initialize this field to Null_Address if we are not building
5075 -- static dispatch tables static or if the size function is not
5076 -- available. In the former case we cannot initialize this field
5077 -- until the function is frozen and registered in the dispatch
5078 -- table (see Register_Primitive).
5080 if not Building_Static_DT (Typ) or else not Has_DT (Typ) then
5081 Append_To (TSD_Aggr_List,
5082 Unchecked_Convert_To (RTE (RE_Size_Ptr),
5083 New_Reference_To (RTE (RE_Null_Address), Loc)));
5087 Prim_Elmt : Elmt_Id;
5089 Size_Comp : Node_Id;
5092 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5093 while Present (Prim_Elmt) loop
5094 Prim := Node (Prim_Elmt);
5096 if Chars (Prim) = Name_uSize then
5097 Prim := Ultimate_Alias (Prim);
5099 if Is_Abstract_Subprogram (Prim) then
5101 Unchecked_Convert_To (RTE (RE_Size_Ptr),
5102 New_Reference_To (RTE (RE_Null_Address), Loc));
5105 Unchecked_Convert_To (RTE (RE_Size_Ptr),
5106 Make_Attribute_Reference (Loc,
5107 Prefix => New_Reference_To (Prim, Loc),
5108 Attribute_Name => Name_Unrestricted_Access));
5114 Next_Elmt (Prim_Elmt);
5117 pragma Assert (Present (Size_Comp));
5118 Append_To (TSD_Aggr_List, Size_Comp);
5123 -- Interfaces_Table (required for AI-405)
5125 if RTE_Record_Component_Available (RE_Interfaces_Table) then
5127 -- Count the number of interface types implemented by Typ
5129 Collect_Interfaces (Typ, Typ_Ifaces);
5131 AI := First_Elmt (Typ_Ifaces);
5132 while Present (AI) loop
5133 Num_Ifaces := Num_Ifaces + 1;
5137 if Num_Ifaces = 0 then
5138 Iface_Table_Node := Make_Null (Loc);
5140 -- Generate the Interface_Table object
5144 TSD_Ifaces_List : constant List_Id := New_List;
5146 Sec_DT_Tag : Node_Id;
5149 AI := First_Elmt (Typ_Ifaces);
5150 while Present (AI) loop
5151 if Is_Ancestor (Node (AI), Typ, Use_Full_View => True) then
5153 New_Reference_To (DT_Ptr, Loc);
5157 (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
5158 pragma Assert (Has_Thunks (Node (Elmt)));
5160 while Is_Tag (Node (Elmt))
5162 Is_Ancestor (Node (AI), Related_Type (Node (Elmt)),
5163 Use_Full_View => True)
5165 pragma Assert (Has_Thunks (Node (Elmt)));
5167 pragma Assert (Has_Thunks (Node (Elmt)));
5169 pragma Assert (not Has_Thunks (Node (Elmt)));
5171 pragma Assert (not Has_Thunks (Node (Elmt)));
5175 pragma Assert (Ekind (Node (Elmt)) = E_Constant
5177 Has_Thunks (Node (Next_Elmt (Next_Elmt (Elmt)))));
5179 New_Reference_To (Node (Next_Elmt (Next_Elmt (Elmt))),
5183 Append_To (TSD_Ifaces_List,
5184 Make_Aggregate (Loc,
5185 Expressions => New_List (
5189 Unchecked_Convert_To (RTE (RE_Tag),
5191 (Node (First_Elmt (Access_Disp_Table (Node (AI)))),
5194 -- Static_Offset_To_Top
5196 New_Reference_To (Standard_True, Loc),
5198 -- Offset_To_Top_Value
5200 Make_Integer_Literal (Loc, 0),
5202 -- Offset_To_Top_Func
5208 Unchecked_Convert_To (RTE (RE_Tag), Sec_DT_Tag)
5215 Name_ITable := New_External_Name (Tname, 'I');
5216 ITable := Make_Defining_Identifier (Loc, Name_ITable);
5217 Set_Is_Statically_Allocated (ITable,
5218 Is_Library_Level_Tagged_Type (Typ));
5220 -- The table of interfaces is not constant; its slots are
5221 -- filled at run time by the IP routine using attribute
5222 -- 'Position to know the location of the tag components
5223 -- (and this attribute cannot be safely used before the
5224 -- object is initialized).
5227 Make_Object_Declaration (Loc,
5228 Defining_Identifier => ITable,
5229 Aliased_Present => True,
5230 Constant_Present => False,
5231 Object_Definition =>
5232 Make_Subtype_Indication (Loc,
5234 New_Reference_To (RTE (RE_Interface_Data), Loc),
5235 Constraint => Make_Index_Or_Discriminant_Constraint
5237 Constraints => New_List (
5238 Make_Integer_Literal (Loc, Num_Ifaces)))),
5240 Expression => Make_Aggregate (Loc,
5241 Expressions => New_List (
5242 Make_Integer_Literal (Loc, Num_Ifaces),
5243 Make_Aggregate (Loc,
5244 Expressions => TSD_Ifaces_List)))));
5247 Make_Attribute_Definition_Clause (Loc,
5248 Name => New_Reference_To (ITable, Loc),
5249 Chars => Name_Alignment,
5251 Make_Attribute_Reference (Loc,
5253 New_Reference_To (RTE (RE_Integer_Address), Loc),
5254 Attribute_Name => Name_Alignment)));
5257 Make_Attribute_Reference (Loc,
5258 Prefix => New_Reference_To (ITable, Loc),
5259 Attribute_Name => Name_Unchecked_Access);
5263 Append_To (TSD_Aggr_List, Iface_Table_Node);
5266 -- Generate the Select Specific Data table for synchronized types that
5267 -- implement synchronized interfaces. The size of the table is
5268 -- constrained by the number of non-predefined primitive operations.
5270 if RTE_Record_Component_Available (RE_SSD) then
5271 if Ada_Version >= Ada_2005
5272 and then Has_DT (Typ)
5273 and then Is_Concurrent_Record_Type (Typ)
5274 and then Has_Interfaces (Typ)
5275 and then Nb_Prim > 0
5276 and then not Is_Abstract_Type (Typ)
5277 and then not Is_Controlled (Typ)
5278 and then not Restriction_Active (No_Dispatching_Calls)
5279 and then not Restriction_Active (No_Select_Statements)
5282 Make_Object_Declaration (Loc,
5283 Defining_Identifier => SSD,
5284 Aliased_Present => True,
5285 Object_Definition =>
5286 Make_Subtype_Indication (Loc,
5287 Subtype_Mark => New_Reference_To (
5288 RTE (RE_Select_Specific_Data), Loc),
5290 Make_Index_Or_Discriminant_Constraint (Loc,
5291 Constraints => New_List (
5292 Make_Integer_Literal (Loc, Nb_Prim))))));
5295 Make_Attribute_Definition_Clause (Loc,
5296 Name => New_Reference_To (SSD, Loc),
5297 Chars => Name_Alignment,
5299 Make_Attribute_Reference (Loc,
5301 New_Reference_To (RTE (RE_Integer_Address), Loc),
5302 Attribute_Name => Name_Alignment)));
5304 -- This table is initialized by Make_Select_Specific_Data_Table,
5305 -- which calls Set_Entry_Index and Set_Prim_Op_Kind.
5307 Append_To (TSD_Aggr_List,
5308 Make_Attribute_Reference (Loc,
5309 Prefix => New_Reference_To (SSD, Loc),
5310 Attribute_Name => Name_Unchecked_Access));
5312 Append_To (TSD_Aggr_List, Make_Null (Loc));
5316 -- Initialize the table of ancestor tags. In case of interface types
5317 -- this table is not needed.
5319 TSD_Tags_List := New_List;
5321 -- If we are not statically allocating the dispatch table then we must
5322 -- fill position 0 with null because we still have not generated the
5325 if not Building_Static_DT (Typ)
5326 or else Is_Interface (Typ)
5328 Append_To (TSD_Tags_List,
5329 Unchecked_Convert_To (RTE (RE_Tag),
5330 New_Reference_To (RTE (RE_Null_Address), Loc)));
5332 -- Otherwise we can safely reference the tag
5335 Append_To (TSD_Tags_List,
5336 New_Reference_To (DT_Ptr, Loc));
5339 -- Fill the rest of the table with the tags of the ancestors
5342 Current_Typ : Entity_Id;
5343 Parent_Typ : Entity_Id;
5351 Parent_Typ := Etype (Current_Typ);
5353 if Is_Private_Type (Parent_Typ) then
5354 Parent_Typ := Full_View (Base_Type (Parent_Typ));
5357 exit when Parent_Typ = Current_Typ;
5359 if Is_CPP_Class (Parent_Typ) then
5361 -- The tags defined in the C++ side will be inherited when
5362 -- the object is constructed (Exp_Ch3.Build_Init_Procedure)
5364 Append_To (TSD_Tags_List,
5365 Unchecked_Convert_To (RTE (RE_Tag),
5366 New_Reference_To (RTE (RE_Null_Address), Loc)));
5368 Append_To (TSD_Tags_List,
5370 (Node (First_Elmt (Access_Disp_Table (Parent_Typ))),
5375 Current_Typ := Parent_Typ;
5378 pragma Assert (Pos = I_Depth + 1);
5381 Append_To (TSD_Aggr_List,
5382 Make_Aggregate (Loc,
5383 Expressions => TSD_Tags_List));
5385 -- Build the TSD object
5388 Make_Object_Declaration (Loc,
5389 Defining_Identifier => TSD,
5390 Aliased_Present => True,
5391 Constant_Present => Building_Static_DT (Typ),
5392 Object_Definition =>
5393 Make_Subtype_Indication (Loc,
5394 Subtype_Mark => New_Reference_To (
5395 RTE (RE_Type_Specific_Data), Loc),
5397 Make_Index_Or_Discriminant_Constraint (Loc,
5398 Constraints => New_List (
5399 Make_Integer_Literal (Loc, I_Depth)))),
5401 Expression => Make_Aggregate (Loc,
5402 Expressions => TSD_Aggr_List)));
5404 Set_Is_True_Constant (TSD, Building_Static_DT (Typ));
5407 Make_Attribute_Definition_Clause (Loc,
5408 Name => New_Reference_To (TSD, Loc),
5409 Chars => Name_Alignment,
5411 Make_Attribute_Reference (Loc,
5412 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
5413 Attribute_Name => Name_Alignment)));
5415 -- Initialize or declare the dispatch table object
5417 if not Has_DT (Typ) then
5418 DT_Constr_List := New_List;
5419 DT_Aggr_List := New_List;
5424 Make_Attribute_Reference (Loc,
5425 Prefix => New_Reference_To (TSD, Loc),
5426 Attribute_Name => Name_Address);
5428 Append_To (DT_Constr_List, New_Node);
5429 Append_To (DT_Aggr_List, New_Copy (New_Node));
5430 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
5432 -- In case of locally defined tagged types we have already declared
5433 -- and uninitialized object for the dispatch table, which is now
5434 -- initialized by means of the following assignment:
5436 -- DT := (TSD'Address, 0);
5438 if not Building_Static_DT (Typ) then
5440 Make_Assignment_Statement (Loc,
5441 Name => New_Reference_To (DT, Loc),
5442 Expression => Make_Aggregate (Loc,
5443 Expressions => DT_Aggr_List)));
5445 -- In case of library level tagged types we declare and export now
5446 -- the constant object containing the dummy dispatch table. There
5447 -- is no need to declare the tag here because it has been previously
5448 -- declared by Make_Tags
5450 -- DT : aliased constant No_Dispatch_Table :=
5451 -- (NDT_TSD => TSD'Address;
5452 -- NDT_Prims_Ptr => 0);
5453 -- for DT'Alignment use Address'Alignment;
5457 Make_Object_Declaration (Loc,
5458 Defining_Identifier => DT,
5459 Aliased_Present => True,
5460 Constant_Present => True,
5461 Object_Definition =>
5462 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc),
5463 Expression => Make_Aggregate (Loc,
5464 Expressions => DT_Aggr_List)));
5467 Make_Attribute_Definition_Clause (Loc,
5468 Name => New_Reference_To (DT, Loc),
5469 Chars => Name_Alignment,
5471 Make_Attribute_Reference (Loc,
5473 New_Reference_To (RTE (RE_Integer_Address), Loc),
5474 Attribute_Name => Name_Alignment)));
5476 Export_DT (Typ, DT);
5479 -- Common case: Typ has a dispatch table
5483 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
5484 -- (predef-prim-op-1'address,
5485 -- predef-prim-op-2'address,
5487 -- predef-prim-op-n'address);
5488 -- for Predef_Prims'Alignment use Address'Alignment
5490 -- DT : Dispatch_Table (Nb_Prims) :=
5491 -- (Signature => <sig-value>,
5492 -- Tag_Kind => <tag_kind-value>,
5493 -- Predef_Prims => Predef_Prims'First'Address,
5494 -- Offset_To_Top => 0,
5495 -- TSD => TSD'Address;
5496 -- Prims_Ptr => (prim-op-1'address,
5497 -- prim-op-2'address,
5499 -- prim-op-n'address));
5500 -- for DT'Alignment use Address'Alignment
5507 if not Building_Static_DT (Typ) then
5508 Nb_Predef_Prims := Max_Predef_Prims;
5511 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5512 while Present (Prim_Elmt) loop
5513 Prim := Node (Prim_Elmt);
5515 if Is_Predefined_Dispatching_Operation (Prim)
5516 and then not Is_Abstract_Subprogram (Prim)
5518 Pos := UI_To_Int (DT_Position (Prim));
5520 if Pos > Nb_Predef_Prims then
5521 Nb_Predef_Prims := Pos;
5525 Next_Elmt (Prim_Elmt);
5531 (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
5536 Prim_Ops_Aggr_List := New_List;
5538 Prim_Table := (others => Empty);
5540 if Building_Static_DT (Typ) then
5541 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5542 while Present (Prim_Elmt) loop
5543 Prim := Node (Prim_Elmt);
5545 if Is_Predefined_Dispatching_Operation (Prim)
5546 and then not Is_Abstract_Subprogram (Prim)
5547 and then not Is_Eliminated (Prim)
5548 and then not Present (Prim_Table
5549 (UI_To_Int (DT_Position (Prim))))
5551 E := Ultimate_Alias (Prim);
5552 pragma Assert (not Is_Abstract_Subprogram (E));
5553 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
5556 Next_Elmt (Prim_Elmt);
5560 for J in Prim_Table'Range loop
5561 if Present (Prim_Table (J)) then
5563 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
5564 Make_Attribute_Reference (Loc,
5565 Prefix => New_Reference_To (Prim_Table (J), Loc),
5566 Attribute_Name => Name_Unrestricted_Access));
5568 New_Node := Make_Null (Loc);
5571 Append_To (Prim_Ops_Aggr_List, New_Node);
5575 Make_Aggregate (Loc,
5576 Expressions => Prim_Ops_Aggr_List);
5579 Make_Subtype_Declaration (Loc,
5580 Defining_Identifier => Make_Temporary (Loc, 'S'),
5581 Subtype_Indication =>
5582 New_Reference_To (RTE (RE_Address_Array), Loc));
5584 Append_To (Result, Decl);
5587 Make_Object_Declaration (Loc,
5588 Defining_Identifier => Predef_Prims,
5589 Aliased_Present => True,
5590 Constant_Present => Building_Static_DT (Typ),
5591 Object_Definition => New_Reference_To
5592 (Defining_Identifier (Decl), Loc),
5593 Expression => New_Node));
5595 -- Remember aggregates initializing dispatch tables
5597 Append_Elmt (New_Node, DT_Aggr);
5600 Make_Attribute_Definition_Clause (Loc,
5601 Name => New_Reference_To (Predef_Prims, Loc),
5602 Chars => Name_Alignment,
5604 Make_Attribute_Reference (Loc,
5606 New_Reference_To (RTE (RE_Integer_Address), Loc),
5607 Attribute_Name => Name_Alignment)));
5611 -- Stage 1: Initialize the discriminant and the record components
5613 DT_Constr_List := New_List;
5614 DT_Aggr_List := New_List;
5616 -- Num_Prims. If the tagged type has no primitives we add a dummy
5617 -- slot whose address will be the tag of this type.
5620 New_Node := Make_Integer_Literal (Loc, 1);
5622 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
5625 Append_To (DT_Constr_List, New_Node);
5626 Append_To (DT_Aggr_List, New_Copy (New_Node));
5630 if RTE_Record_Component_Available (RE_Signature) then
5631 Append_To (DT_Aggr_List,
5632 New_Reference_To (RTE (RE_Primary_DT), Loc));
5637 if RTE_Record_Component_Available (RE_Tag_Kind) then
5638 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
5643 Append_To (DT_Aggr_List,
5644 Make_Attribute_Reference (Loc,
5645 Prefix => New_Reference_To (Predef_Prims, Loc),
5646 Attribute_Name => Name_Address));
5650 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
5654 Append_To (DT_Aggr_List,
5655 Make_Attribute_Reference (Loc,
5656 Prefix => New_Reference_To (TSD, Loc),
5657 Attribute_Name => Name_Address));
5659 -- Stage 2: Initialize the table of primitive operations
5661 Prim_Ops_Aggr_List := New_List;
5664 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
5666 elsif not Building_Static_DT (Typ) then
5667 for J in 1 .. Nb_Prim loop
5668 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
5673 CPP_Nb_Prims : constant Nat := CPP_Num_Prims (Typ);
5676 Prim_Elmt : Elmt_Id;
5678 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
5681 Prim_Table := (others => Empty);
5683 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5684 while Present (Prim_Elmt) loop
5685 Prim := Node (Prim_Elmt);
5687 -- Retrieve the ultimate alias of the primitive for proper
5688 -- handling of renamings and eliminated primitives.
5690 E := Ultimate_Alias (Prim);
5691 Prim_Pos := UI_To_Int (DT_Position (E));
5693 -- Do not reference predefined primitives because they are
5694 -- located in a separate dispatch table; skip entities with
5695 -- attribute Interface_Alias because they are only required
5696 -- to build secondary dispatch tables; skip abstract and
5697 -- eliminated primitives; for derivations of CPP types skip
5698 -- primitives located in the C++ part of the dispatch table
5699 -- because their slot is initialized by the IC routine.
5701 if not Is_Predefined_Dispatching_Operation (Prim)
5702 and then not Is_Predefined_Dispatching_Operation (E)
5703 and then not Present (Interface_Alias (Prim))
5704 and then not Is_Abstract_Subprogram (E)
5705 and then not Is_Eliminated (E)
5706 and then (not Is_CPP_Class (Root_Type (Typ))
5707 or else Prim_Pos > CPP_Nb_Prims)
5710 (UI_To_Int (DT_Position (Prim)) <= Nb_Prim);
5712 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
5715 Next_Elmt (Prim_Elmt);
5718 for J in Prim_Table'Range loop
5719 if Present (Prim_Table (J)) then
5721 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
5722 Make_Attribute_Reference (Loc,
5723 Prefix => New_Reference_To (Prim_Table (J), Loc),
5724 Attribute_Name => Name_Unrestricted_Access));
5726 New_Node := Make_Null (Loc);
5729 Append_To (Prim_Ops_Aggr_List, New_Node);
5735 Make_Aggregate (Loc,
5736 Expressions => Prim_Ops_Aggr_List);
5738 Append_To (DT_Aggr_List, New_Node);
5740 -- Remember aggregates initializing dispatch tables
5742 Append_Elmt (New_Node, DT_Aggr);
5744 -- In case of locally defined tagged types we have already declared
5745 -- and uninitialized object for the dispatch table, which is now
5746 -- initialized by means of an assignment.
5748 if not Building_Static_DT (Typ) then
5750 Make_Assignment_Statement (Loc,
5751 Name => New_Reference_To (DT, Loc),
5752 Expression => Make_Aggregate (Loc,
5753 Expressions => DT_Aggr_List)));
5755 -- In case of library level tagged types we declare now and export
5756 -- the constant object containing the dispatch table.
5760 Make_Object_Declaration (Loc,
5761 Defining_Identifier => DT,
5762 Aliased_Present => True,
5763 Constant_Present => True,
5764 Object_Definition =>
5765 Make_Subtype_Indication (Loc,
5766 Subtype_Mark => New_Reference_To
5767 (RTE (RE_Dispatch_Table_Wrapper), Loc),
5768 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
5769 Constraints => DT_Constr_List)),
5770 Expression => Make_Aggregate (Loc,
5771 Expressions => DT_Aggr_List)));
5774 Make_Attribute_Definition_Clause (Loc,
5775 Name => New_Reference_To (DT, Loc),
5776 Chars => Name_Alignment,
5778 Make_Attribute_Reference (Loc,
5780 New_Reference_To (RTE (RE_Integer_Address), Loc),
5781 Attribute_Name => Name_Alignment)));
5783 Export_DT (Typ, DT);
5787 -- Initialize the table of ancestor tags if not building static
5790 if not Building_Static_DT (Typ)
5791 and then not Is_Interface (Typ)
5792 and then not Is_CPP_Class (Typ)
5795 Make_Assignment_Statement (Loc,
5797 Make_Indexed_Component (Loc,
5799 Make_Selected_Component (Loc,
5801 New_Reference_To (TSD, Loc),
5804 (RTE_Record_Component (RE_Tags_Table), Loc)),
5806 New_List (Make_Integer_Literal (Loc, 0))),
5810 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)));
5813 -- Inherit the dispatch tables of the parent. There is no need to
5814 -- inherit anything from the parent when building static dispatch tables
5815 -- because the whole dispatch table (including inherited primitives) has
5816 -- been already built.
5818 if Building_Static_DT (Typ) then
5821 -- If the ancestor is a CPP_Class type we inherit the dispatch tables
5822 -- in the init proc, and we don't need to fill them in here.
5824 elsif Is_CPP_Class (Parent_Typ) then
5827 -- Otherwise we fill in the dispatch tables here
5830 if Typ /= Parent_Typ
5831 and then not Is_Interface (Typ)
5832 and then not Restriction_Active (No_Dispatching_Calls)
5834 -- Inherit the dispatch table
5836 if not Is_Interface (Typ)
5837 and then not Is_Interface (Parent_Typ)
5838 and then not Is_CPP_Class (Parent_Typ)
5841 Nb_Prims : constant Int :=
5842 UI_To_Int (DT_Entry_Count
5843 (First_Tag_Component (Parent_Typ)));
5846 Append_To (Elab_Code,
5847 Build_Inherit_Predefined_Prims (Loc,
5853 (Access_Disp_Table (Parent_Typ)))), Loc),
5859 (Access_Disp_Table (Typ)))), Loc)));
5861 if Nb_Prims /= 0 then
5862 Append_To (Elab_Code,
5863 Build_Inherit_Prims (Loc,
5869 (Access_Disp_Table (Parent_Typ))), Loc),
5870 New_Tag_Node => New_Reference_To (DT_Ptr, Loc),
5871 Num_Prims => Nb_Prims));
5876 -- Inherit the secondary dispatch tables of the ancestor
5878 if not Is_CPP_Class (Parent_Typ) then
5880 Sec_DT_Ancestor : Elmt_Id :=
5884 (Access_Disp_Table (Parent_Typ))));
5885 Sec_DT_Typ : Elmt_Id :=
5889 (Access_Disp_Table (Typ))));
5891 procedure Copy_Secondary_DTs (Typ : Entity_Id);
5892 -- Local procedure required to climb through the ancestors
5893 -- and copy the contents of all their secondary dispatch
5896 ------------------------
5897 -- Copy_Secondary_DTs --
5898 ------------------------
5900 procedure Copy_Secondary_DTs (Typ : Entity_Id) is
5905 -- Climb to the ancestor (if any) handling private types
5907 if Present (Full_View (Etype (Typ))) then
5908 if Full_View (Etype (Typ)) /= Typ then
5909 Copy_Secondary_DTs (Full_View (Etype (Typ)));
5912 elsif Etype (Typ) /= Typ then
5913 Copy_Secondary_DTs (Etype (Typ));
5916 if Present (Interfaces (Typ))
5917 and then not Is_Empty_Elmt_List (Interfaces (Typ))
5919 Iface := First_Elmt (Interfaces (Typ));
5920 E := First_Entity (Typ);
5922 and then Present (Node (Sec_DT_Ancestor))
5923 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
5925 if Is_Tag (E) and then Chars (E) /= Name_uTag then
5927 Num_Prims : constant Int :=
5928 UI_To_Int (DT_Entry_Count (E));
5931 if not Is_Interface (Etype (Typ)) then
5933 -- Inherit first secondary dispatch table
5935 Append_To (Elab_Code,
5936 Build_Inherit_Predefined_Prims (Loc,
5938 Unchecked_Convert_To (RTE (RE_Tag),
5941 (Next_Elmt (Sec_DT_Ancestor)),
5944 Unchecked_Convert_To (RTE (RE_Tag),
5946 (Node (Next_Elmt (Sec_DT_Typ)),
5949 if Num_Prims /= 0 then
5950 Append_To (Elab_Code,
5951 Build_Inherit_Prims (Loc,
5952 Typ => Node (Iface),
5954 Unchecked_Convert_To
5957 (Node (Sec_DT_Ancestor),
5960 Unchecked_Convert_To
5963 (Node (Sec_DT_Typ), Loc)),
5964 Num_Prims => Num_Prims));
5968 Next_Elmt (Sec_DT_Ancestor);
5969 Next_Elmt (Sec_DT_Typ);
5971 -- Skip the secondary dispatch table of
5972 -- predefined primitives
5974 Next_Elmt (Sec_DT_Ancestor);
5975 Next_Elmt (Sec_DT_Typ);
5977 if not Is_Interface (Etype (Typ)) then
5979 -- Inherit second secondary dispatch table
5981 Append_To (Elab_Code,
5982 Build_Inherit_Predefined_Prims (Loc,
5984 Unchecked_Convert_To (RTE (RE_Tag),
5987 (Next_Elmt (Sec_DT_Ancestor)),
5990 Unchecked_Convert_To (RTE (RE_Tag),
5992 (Node (Next_Elmt (Sec_DT_Typ)),
5995 if Num_Prims /= 0 then
5996 Append_To (Elab_Code,
5997 Build_Inherit_Prims (Loc,
5998 Typ => Node (Iface),
6000 Unchecked_Convert_To
6003 (Node (Sec_DT_Ancestor),
6006 Unchecked_Convert_To
6009 (Node (Sec_DT_Typ), Loc)),
6010 Num_Prims => Num_Prims));
6015 Next_Elmt (Sec_DT_Ancestor);
6016 Next_Elmt (Sec_DT_Typ);
6018 -- Skip the secondary dispatch table of
6019 -- predefined primitives
6021 Next_Elmt (Sec_DT_Ancestor);
6022 Next_Elmt (Sec_DT_Typ);
6030 end Copy_Secondary_DTs;
6033 if Present (Node (Sec_DT_Ancestor))
6034 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
6036 -- Handle private types
6038 if Present (Full_View (Typ)) then
6039 Copy_Secondary_DTs (Full_View (Typ));
6041 Copy_Secondary_DTs (Typ);
6049 -- If the type has a representation clause which specifies its external
6050 -- tag then generate code to check if the external tag of this type is
6051 -- the same as the external tag of some other declaration.
6053 -- Check_TSD (TSD'Unrestricted_Access);
6055 -- This check is a consequence of AI05-0113-1/06, so it officially
6056 -- applies to Ada 2005 (and Ada 2012). It might be argued that it is
6057 -- a desirable check to add in Ada 95 mode, but we hesitate to make
6058 -- this change, as it would be incompatible, and could conceivably
6059 -- cause a problem in existing Aa 95 code.
6061 -- We check for No_Run_Time_Mode here, because we do not want to pick
6062 -- up the RE_Check_TSD entity and call it in No_Run_Time mode.
6064 if not No_Run_Time_Mode
6065 and then Ada_Version >= Ada_2005
6066 and then Has_External_Tag_Rep_Clause (Typ)
6067 and then RTE_Available (RE_Check_TSD)
6068 and then not Debug_Flag_QQ
6070 Append_To (Elab_Code,
6071 Make_Procedure_Call_Statement (Loc,
6072 Name => New_Reference_To (RTE (RE_Check_TSD), Loc),
6073 Parameter_Associations => New_List (
6074 Make_Attribute_Reference (Loc,
6075 Prefix => New_Reference_To (TSD, Loc),
6076 Attribute_Name => Name_Unchecked_Access))));
6079 -- Generate code to register the Tag in the External_Tag hash table for
6080 -- the pure Ada type only.
6082 -- Register_Tag (Dt_Ptr);
6084 -- Skip this action in the following cases:
6085 -- 1) if Register_Tag is not available.
6086 -- 2) in No_Run_Time mode.
6087 -- 3) if Typ is not defined at the library level (this is required
6088 -- to avoid adding concurrency control to the hash table used
6089 -- by the run-time to register the tags).
6091 if not No_Run_Time_Mode
6092 and then Is_Library_Level_Entity (Typ)
6093 and then RTE_Available (RE_Register_Tag)
6095 Append_To (Elab_Code,
6096 Make_Procedure_Call_Statement (Loc,
6097 Name => New_Reference_To (RTE (RE_Register_Tag), Loc),
6098 Parameter_Associations =>
6099 New_List (New_Reference_To (DT_Ptr, Loc))));
6102 if not Is_Empty_List (Elab_Code) then
6103 Append_List_To (Result, Elab_Code);
6106 -- Populate the two auxiliary tables used for dispatching asynchronous,
6107 -- conditional and timed selects for synchronized types that implement
6108 -- a limited interface. Skip this step in Ravenscar profile or when
6109 -- general dispatching is forbidden.
6111 if Ada_Version >= Ada_2005
6112 and then Is_Concurrent_Record_Type (Typ)
6113 and then Has_Interfaces (Typ)
6114 and then not Restriction_Active (No_Dispatching_Calls)
6115 and then not Restriction_Active (No_Select_Statements)
6117 Append_List_To (Result,
6118 Make_Select_Specific_Data_Table (Typ));
6121 -- Remember entities containing dispatch tables
6123 Append_Elmt (Predef_Prims, DT_Decl);
6124 Append_Elmt (DT, DT_Decl);
6126 Analyze_List (Result, Suppress => All_Checks);
6127 Set_Has_Dispatch_Table (Typ);
6129 -- Mark entities containing dispatch tables. Required by the backend to
6130 -- handle them properly.
6132 if Has_DT (Typ) then
6137 -- Ensure that entities Prim_Ptr and Predef_Prims_Table_Ptr have
6138 -- the decoration required by the backend
6140 Set_Is_Dispatch_Table_Entity (RTE (RE_Prim_Ptr));
6141 Set_Is_Dispatch_Table_Entity (RTE (RE_Predef_Prims_Table_Ptr));
6143 -- Object declarations
6145 Elmt := First_Elmt (DT_Decl);
6146 while Present (Elmt) loop
6147 Set_Is_Dispatch_Table_Entity (Node (Elmt));
6148 pragma Assert (Ekind (Etype (Node (Elmt))) = E_Array_Subtype
6149 or else Ekind (Etype (Node (Elmt))) = E_Record_Subtype);
6150 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
6154 -- Aggregates initializing dispatch tables
6156 Elmt := First_Elmt (DT_Aggr);
6157 while Present (Elmt) loop
6158 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
6164 -- Register the tagged type in the call graph nodes table
6166 Register_CG_Node (Typ);
6175 function Make_VM_TSD (Typ : Entity_Id) return List_Id is
6176 Loc : constant Source_Ptr := Sloc (Typ);
6177 Result : constant List_Id := New_List;
6179 function Count_Primitives (Typ : Entity_Id) return Nat;
6180 -- Count the non-predefined primitive operations of Typ
6182 ----------------------
6183 -- Count_Primitives --
6184 ----------------------
6186 function Count_Primitives (Typ : Entity_Id) return Nat is
6188 Prim_Elmt : Elmt_Id;
6194 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6195 while Present (Prim_Elmt) loop
6196 Prim := Node (Prim_Elmt);
6198 if Is_Predefined_Dispatching_Operation (Prim)
6199 or else Is_Predefined_Dispatching_Alias (Prim)
6203 elsif Present (Interface_Alias (Prim)) then
6207 Nb_Prim := Nb_Prim + 1;
6210 Next_Elmt (Prim_Elmt);
6214 end Count_Primitives;
6220 function Make_OSD (Iface : Entity_Id) return Node_Id;
6221 -- Generate the Object Specific Data table required to dispatch calls
6222 -- through synchronized interfaces. Returns a node that references the
6223 -- generated OSD object.
6225 function Make_OSD (Iface : Entity_Id) return Node_Id is
6226 Nb_Prim : constant Nat := Count_Primitives (Iface);
6228 OSD_Aggr_List : List_Id;
6232 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
6233 -- (OSD_Table => (1 => <value>,
6238 or else Is_Abstract_Type (Typ)
6239 or else Is_Controlled (Typ)
6240 or else Restriction_Active (No_Dispatching_Calls)
6241 or else not Is_Limited_Type (Typ)
6242 or else not Has_Interfaces (Typ)
6243 or else not RTE_Record_Component_Available (RE_OSD_Table)
6245 -- No OSD table required
6247 return Make_Null (Loc);
6250 OSD_Aggr_List := New_List;
6253 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
6255 Prim_Alias : Entity_Id;
6256 Prim_Elmt : Elmt_Id;
6262 Prim_Table := (others => Empty);
6263 Prim_Alias := Empty;
6265 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6266 while Present (Prim_Elmt) loop
6267 Prim := Node (Prim_Elmt);
6269 if Present (Interface_Alias (Prim))
6270 and then Find_Dispatching_Type
6271 (Interface_Alias (Prim)) = Iface
6273 Prim_Alias := Interface_Alias (Prim);
6274 E := Ultimate_Alias (Prim);
6275 Pos := UI_To_Int (DT_Position (Prim_Alias));
6277 if Present (Prim_Table (Pos)) then
6278 pragma Assert (Prim_Table (Pos) = E);
6282 Prim_Table (Pos) := E;
6284 Append_To (OSD_Aggr_List,
6285 Make_Component_Association (Loc,
6286 Choices => New_List (
6287 Make_Integer_Literal (Loc,
6288 DT_Position (Prim_Alias))),
6290 Make_Integer_Literal (Loc,
6291 DT_Position (Alias (Prim)))));
6297 Next_Elmt (Prim_Elmt);
6299 pragma Assert (Count = Nb_Prim);
6302 OSD := Make_Temporary (Loc, 'I');
6305 Make_Object_Declaration (Loc,
6306 Defining_Identifier => OSD,
6307 Aliased_Present => True,
6308 Constant_Present => True,
6309 Object_Definition =>
6310 Make_Subtype_Indication (Loc,
6312 New_Reference_To (RTE (RE_Object_Specific_Data), Loc),
6314 Make_Index_Or_Discriminant_Constraint (Loc,
6315 Constraints => New_List (
6316 Make_Integer_Literal (Loc, Nb_Prim)))),
6319 Make_Aggregate (Loc,
6320 Component_Associations => New_List (
6321 Make_Component_Association (Loc,
6322 Choices => New_List (
6324 (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
6326 Make_Integer_Literal (Loc, Nb_Prim)),
6328 Make_Component_Association (Loc,
6329 Choices => New_List (
6331 (RTE_Record_Component (RE_OSD_Table), Loc)),
6332 Expression => Make_Aggregate (Loc,
6333 Component_Associations => OSD_Aggr_List))))));
6336 Make_Attribute_Reference (Loc,
6337 Prefix => New_Reference_To (OSD, Loc),
6338 Attribute_Name => Name_Unchecked_Access);
6344 Nb_Prim : constant Nat := Count_Primitives (Typ);
6347 Iface_Table_Node : Node_Id;
6349 TSD_Aggr_List : List_Id;
6350 Typ_Ifaces : Elist_Id;
6351 TSD_Tags_List : List_Id;
6353 Tname : constant Name_Id := Chars (Typ);
6354 Name_SSD : constant Name_Id :=
6355 New_External_Name (Tname, 'S', Suffix_Index => -1);
6356 Name_TSD : constant Name_Id :=
6357 New_External_Name (Tname, 'B', Suffix_Index => -1);
6358 SSD : constant Entity_Id :=
6359 Make_Defining_Identifier (Loc, Name_SSD);
6360 TSD : constant Entity_Id :=
6361 Make_Defining_Identifier (Loc, Name_TSD);
6363 -- Generate code to create the storage for the type specific data object
6364 -- with enough space to store the tags of the ancestors plus the tags
6365 -- of all the implemented interfaces (as described in a-tags.ads).
6367 -- TSD : Type_Specific_Data (I_Depth) :=
6368 -- (Idepth => I_Depth,
6369 -- Tag_Kind => <tag_kind-value>,
6370 -- Access_Level => Type_Access_Level (Typ),
6372 -- Type_Is_Abstract => <<boolean-value>>,
6373 -- Type_Is_Library_Level => <<boolean-value>>,
6374 -- Interfaces_Table => <<access-value>>
6375 -- SSD => SSD_Table'Address
6376 -- Tags_Table => (0 => Typ'Tag,
6380 TSD_Aggr_List := New_List;
6382 -- Idepth: Count ancestors to compute the inheritance depth. For private
6383 -- extensions, always go to the full view in order to compute the real
6384 -- inheritance depth.
6387 Current_Typ : Entity_Id;
6388 Parent_Typ : Entity_Id;
6394 Parent_Typ := Etype (Current_Typ);
6396 if Is_Private_Type (Parent_Typ) then
6397 Parent_Typ := Full_View (Base_Type (Parent_Typ));
6400 exit when Parent_Typ = Current_Typ;
6402 I_Depth := I_Depth + 1;
6403 Current_Typ := Parent_Typ;
6409 Append_To (TSD_Aggr_List,
6410 Make_Integer_Literal (Loc, I_Depth));
6414 Append_To (TSD_Aggr_List, Tagged_Kind (Typ));
6418 Append_To (TSD_Aggr_List,
6419 Make_Integer_Literal (Loc, Type_Access_Level (Typ)));
6423 Append_To (TSD_Aggr_List,
6426 -- Type_Is_Abstract (Ada 2012: AI05-0173)
6429 Type_Is_Abstract : Entity_Id;
6433 Boolean_Literals (Is_Abstract_Type (Typ));
6435 Append_To (TSD_Aggr_List,
6436 New_Occurrence_Of (Type_Is_Abstract, Loc));
6439 -- Type_Is_Library_Level
6442 Type_Is_Library_Level : Entity_Id;
6444 Type_Is_Library_Level :=
6445 Boolean_Literals (Is_Library_Level_Entity (Typ));
6446 Append_To (TSD_Aggr_List,
6447 New_Occurrence_Of (Type_Is_Library_Level, Loc));
6450 -- Interfaces_Table (required for AI-405)
6452 if RTE_Record_Component_Available (RE_Interfaces_Table) then
6454 -- Count the number of interface types implemented by Typ
6456 Collect_Interfaces (Typ, Typ_Ifaces);
6459 AI := First_Elmt (Typ_Ifaces);
6460 while Present (AI) loop
6461 Num_Ifaces := Num_Ifaces + 1;
6465 if Num_Ifaces = 0 then
6466 Iface_Table_Node := Make_Null (Loc);
6468 -- Generate the Interface_Table object
6472 TSD_Ifaces_List : constant List_Id := New_List;
6477 AI := First_Elmt (Typ_Ifaces);
6478 while Present (AI) loop
6481 Append_To (TSD_Ifaces_List,
6482 Make_Aggregate (Loc,
6483 Expressions => New_List (
6487 Make_Attribute_Reference (Loc,
6488 Prefix => New_Reference_To (Iface, Loc),
6489 Attribute_Name => Name_Tag),
6493 Make_OSD (Iface))));
6498 ITable := Make_Temporary (Loc, 'I');
6501 Make_Object_Declaration (Loc,
6502 Defining_Identifier => ITable,
6503 Aliased_Present => True,
6504 Constant_Present => True,
6505 Object_Definition =>
6506 Make_Subtype_Indication (Loc,
6508 New_Reference_To (RTE (RE_Interface_Data), Loc),
6509 Constraint => Make_Index_Or_Discriminant_Constraint
6511 Constraints => New_List (
6512 Make_Integer_Literal (Loc, Num_Ifaces)))),
6514 Expression => Make_Aggregate (Loc,
6515 Expressions => New_List (
6516 Make_Integer_Literal (Loc, Num_Ifaces),
6517 Make_Aggregate (Loc,
6518 Expressions => TSD_Ifaces_List)))));
6521 Make_Attribute_Reference (Loc,
6522 Prefix => New_Reference_To (ITable, Loc),
6523 Attribute_Name => Name_Unchecked_Access);
6527 Append_To (TSD_Aggr_List, Iface_Table_Node);
6530 -- Generate the Select Specific Data table for synchronized types that
6531 -- implement synchronized interfaces. The size of the table is
6532 -- constrained by the number of non-predefined primitive operations.
6534 if RTE_Record_Component_Available (RE_SSD) then
6535 if Ada_Version >= Ada_2005
6536 and then Has_DT (Typ)
6537 and then Is_Concurrent_Record_Type (Typ)
6538 and then Has_Interfaces (Typ)
6539 and then Nb_Prim > 0
6540 and then not Is_Abstract_Type (Typ)
6541 and then not Is_Controlled (Typ)
6542 and then not Restriction_Active (No_Dispatching_Calls)
6543 and then not Restriction_Active (No_Select_Statements)
6546 Make_Object_Declaration (Loc,
6547 Defining_Identifier => SSD,
6548 Aliased_Present => True,
6549 Object_Definition =>
6550 Make_Subtype_Indication (Loc,
6551 Subtype_Mark => New_Reference_To (
6552 RTE (RE_Select_Specific_Data), Loc),
6554 Make_Index_Or_Discriminant_Constraint (Loc,
6555 Constraints => New_List (
6556 Make_Integer_Literal (Loc, Nb_Prim))))));
6558 -- This table is initialized by Make_Select_Specific_Data_Table,
6559 -- which calls Set_Entry_Index and Set_Prim_Op_Kind.
6561 Append_To (TSD_Aggr_List,
6562 Make_Attribute_Reference (Loc,
6563 Prefix => New_Reference_To (SSD, Loc),
6564 Attribute_Name => Name_Unchecked_Access));
6566 Append_To (TSD_Aggr_List, Make_Null (Loc));
6570 -- Initialize the table of ancestor tags. In case of interface types
6571 -- this table is not needed.
6573 TSD_Tags_List := New_List;
6575 -- Fill position 0 with Typ'Tag
6577 Append_To (TSD_Tags_List,
6578 Make_Attribute_Reference (Loc,
6579 Prefix => New_Reference_To (Typ, Loc),
6580 Attribute_Name => Name_Tag));
6582 -- Fill the rest of the table with the tags of the ancestors
6585 Current_Typ : Entity_Id;
6586 Parent_Typ : Entity_Id;
6594 Parent_Typ := Etype (Current_Typ);
6596 if Is_Private_Type (Parent_Typ) then
6597 Parent_Typ := Full_View (Base_Type (Parent_Typ));
6600 exit when Parent_Typ = Current_Typ;
6602 Append_To (TSD_Tags_List,
6603 Make_Attribute_Reference (Loc,
6604 Prefix => New_Reference_To (Parent_Typ, Loc),
6605 Attribute_Name => Name_Tag));
6608 Current_Typ := Parent_Typ;
6611 pragma Assert (Pos = I_Depth + 1);
6614 Append_To (TSD_Aggr_List,
6615 Make_Aggregate (Loc,
6616 Expressions => TSD_Tags_List));
6618 -- Build the TSD object
6621 Make_Object_Declaration (Loc,
6622 Defining_Identifier => TSD,
6623 Aliased_Present => True,
6624 Constant_Present => True,
6625 Object_Definition =>
6626 Make_Subtype_Indication (Loc,
6627 Subtype_Mark => New_Reference_To (
6628 RTE (RE_Type_Specific_Data), Loc),
6630 Make_Index_Or_Discriminant_Constraint (Loc,
6631 Constraints => New_List (
6632 Make_Integer_Literal (Loc, I_Depth)))),
6634 Expression => Make_Aggregate (Loc,
6635 Expressions => TSD_Aggr_List)));
6639 -- (TSD => TSD'Unrestricted_Access);
6641 if Ada_Version >= Ada_2005
6642 and then Is_Library_Level_Entity (Typ)
6643 and then Has_External_Tag_Rep_Clause (Typ)
6644 and then RTE_Available (RE_Check_TSD)
6645 and then not Debug_Flag_QQ
6648 Make_Procedure_Call_Statement (Loc,
6649 Name => New_Reference_To (RTE (RE_Check_TSD), Loc),
6650 Parameter_Associations => New_List (
6651 Make_Attribute_Reference (Loc,
6652 Prefix => New_Reference_To (TSD, Loc),
6653 Attribute_Name => Name_Unrestricted_Access))));
6657 -- Register_TSD (TSD'Unrestricted_Access);
6660 Make_Procedure_Call_Statement (Loc,
6661 Name => New_Reference_To (RTE (RE_Register_TSD), Loc),
6662 Parameter_Associations => New_List (
6663 Make_Attribute_Reference (Loc,
6664 Prefix => New_Reference_To (TSD, Loc),
6665 Attribute_Name => Name_Unrestricted_Access))));
6667 -- Populate the two auxiliary tables used for dispatching asynchronous,
6668 -- conditional and timed selects for synchronized types that implement
6669 -- a limited interface. Skip this step in Ravenscar profile or when
6670 -- general dispatching is forbidden.
6672 if Ada_Version >= Ada_2005
6673 and then Is_Concurrent_Record_Type (Typ)
6674 and then Has_Interfaces (Typ)
6675 and then not Restriction_Active (No_Dispatching_Calls)
6676 and then not Restriction_Active (No_Select_Statements)
6678 Append_List_To (Result,
6679 Make_Select_Specific_Data_Table (Typ));
6685 -------------------------------------
6686 -- Make_Select_Specific_Data_Table --
6687 -------------------------------------
6689 function Make_Select_Specific_Data_Table
6690 (Typ : Entity_Id) return List_Id
6692 Assignments : constant List_Id := New_List;
6693 Loc : constant Source_Ptr := Sloc (Typ);
6695 Conc_Typ : Entity_Id;
6698 Prim_Als : Entity_Id;
6699 Prim_Elmt : Elmt_Id;
6703 type Examined_Array is array (Int range <>) of Boolean;
6705 function Find_Entry_Index (E : Entity_Id) return Uint;
6706 -- Given an entry, find its index in the visible declarations of the
6707 -- corresponding concurrent type of Typ.
6709 ----------------------
6710 -- Find_Entry_Index --
6711 ----------------------
6713 function Find_Entry_Index (E : Entity_Id) return Uint is
6714 Index : Uint := Uint_1;
6715 Subp_Decl : Entity_Id;
6719 and then not Is_Empty_List (Decls)
6721 Subp_Decl := First (Decls);
6722 while Present (Subp_Decl) loop
6723 if Nkind (Subp_Decl) = N_Entry_Declaration then
6724 if Defining_Identifier (Subp_Decl) = E then
6736 end Find_Entry_Index;
6742 -- Start of processing for Make_Select_Specific_Data_Table
6745 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
6747 if Present (Corresponding_Concurrent_Type (Typ)) then
6748 Conc_Typ := Corresponding_Concurrent_Type (Typ);
6750 if Present (Full_View (Conc_Typ)) then
6751 Conc_Typ := Full_View (Conc_Typ);
6754 if Ekind (Conc_Typ) = E_Protected_Type then
6755 Decls := Visible_Declarations (Protected_Definition (
6756 Parent (Conc_Typ)));
6758 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
6759 Decls := Visible_Declarations (Task_Definition (
6760 Parent (Conc_Typ)));
6764 -- Count the non-predefined primitive operations
6766 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6767 while Present (Prim_Elmt) loop
6768 Prim := Node (Prim_Elmt);
6770 if not (Is_Predefined_Dispatching_Operation (Prim)
6771 or else Is_Predefined_Dispatching_Alias (Prim))
6773 Nb_Prim := Nb_Prim + 1;
6776 Next_Elmt (Prim_Elmt);
6780 Examined : Examined_Array (1 .. Nb_Prim) := (others => False);
6783 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6784 while Present (Prim_Elmt) loop
6785 Prim := Node (Prim_Elmt);
6787 -- Look for primitive overriding an abstract interface subprogram
6789 if Present (Interface_Alias (Prim))
6792 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ,
6793 Use_Full_View => True)
6794 and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
6796 Prim_Pos := DT_Position (Alias (Prim));
6797 pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
6798 Examined (UI_To_Int (Prim_Pos)) := True;
6800 -- Set the primitive operation kind regardless of subprogram
6802 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
6804 if Tagged_Type_Expansion then
6807 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc);
6811 Make_Attribute_Reference (Loc,
6812 Prefix => New_Reference_To (Typ, Loc),
6813 Attribute_Name => Name_Tag);
6816 Append_To (Assignments,
6817 Make_Procedure_Call_Statement (Loc,
6818 Name => New_Reference_To (RTE (RE_Set_Prim_Op_Kind), Loc),
6819 Parameter_Associations => New_List (
6821 Make_Integer_Literal (Loc, Prim_Pos),
6822 Prim_Op_Kind (Alias (Prim), Typ))));
6824 -- Retrieve the root of the alias chain
6826 Prim_Als := Ultimate_Alias (Prim);
6828 -- In the case of an entry wrapper, set the entry index
6830 if Ekind (Prim) = E_Procedure
6831 and then Is_Primitive_Wrapper (Prim_Als)
6832 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
6835 -- Ada.Tags.Set_Entry_Index
6836 -- (DT_Ptr, <position>, <index>);
6838 if Tagged_Type_Expansion then
6841 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc);
6844 Make_Attribute_Reference (Loc,
6845 Prefix => New_Reference_To (Typ, Loc),
6846 Attribute_Name => Name_Tag);
6849 Append_To (Assignments,
6850 Make_Procedure_Call_Statement (Loc,
6852 New_Reference_To (RTE (RE_Set_Entry_Index), Loc),
6853 Parameter_Associations => New_List (
6855 Make_Integer_Literal (Loc, Prim_Pos),
6856 Make_Integer_Literal (Loc,
6857 Find_Entry_Index (Wrapped_Entity (Prim_Als))))));
6861 Next_Elmt (Prim_Elmt);
6866 end Make_Select_Specific_Data_Table;
6872 function Make_Tags (Typ : Entity_Id) return List_Id is
6873 Loc : constant Source_Ptr := Sloc (Typ);
6874 Result : constant List_Id := New_List;
6877 (Tag_Typ : Entity_Id;
6879 Is_Secondary_DT : Boolean);
6880 -- Import the dispatch table DT of tagged type Tag_Typ. Required to
6881 -- generate forward references and statically allocate the table. For
6882 -- primary dispatch tables that require no dispatch table generate:
6884 -- DT : static aliased constant Non_Dispatch_Table_Wrapper;
6885 -- pragma Import (Ada, DT);
6887 -- Otherwise generate:
6889 -- DT : static aliased constant Dispatch_Table_Wrapper (Nb_Prim);
6890 -- pragma Import (Ada, DT);
6897 (Tag_Typ : Entity_Id;
6899 Is_Secondary_DT : Boolean)
6901 DT_Constr_List : List_Id;
6905 Set_Is_Imported (DT);
6906 Set_Ekind (DT, E_Constant);
6907 Set_Related_Type (DT, Typ);
6909 -- The scope must be set now to call Get_External_Name
6911 Set_Scope (DT, Current_Scope);
6913 Get_External_Name (DT, True);
6914 Set_Interface_Name (DT,
6915 Make_String_Literal (Loc, Strval => String_From_Name_Buffer));
6917 -- Ensure proper Sprint output of this implicit importation
6919 Set_Is_Internal (DT);
6921 -- Save this entity to allow Make_DT to generate its exportation
6923 Append_Elmt (DT, Dispatch_Table_Wrappers (Typ));
6925 -- No dispatch table required
6927 if not Is_Secondary_DT and then not Has_DT (Tag_Typ) then
6929 Make_Object_Declaration (Loc,
6930 Defining_Identifier => DT,
6931 Aliased_Present => True,
6932 Constant_Present => True,
6933 Object_Definition =>
6934 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
6937 -- Calculate the number of primitives of the dispatch table and
6938 -- the size of the Type_Specific_Data record.
6941 UI_To_Int (DT_Entry_Count (First_Tag_Component (Tag_Typ)));
6943 -- If the tagged type has no primitives we add a dummy slot whose
6944 -- address will be the tag of this type.
6948 New_List (Make_Integer_Literal (Loc, 1));
6951 New_List (Make_Integer_Literal (Loc, Nb_Prim));
6955 Make_Object_Declaration (Loc,
6956 Defining_Identifier => DT,
6957 Aliased_Present => True,
6958 Constant_Present => True,
6959 Object_Definition =>
6960 Make_Subtype_Indication (Loc,
6962 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
6963 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
6964 Constraints => DT_Constr_List))));
6970 Tname : constant Name_Id := Chars (Typ);
6971 AI_Tag_Comp : Elmt_Id;
6972 DT : Node_Id := Empty;
6974 Predef_Prims_Ptr : Node_Id;
6975 Iface_DT : Node_Id := Empty;
6976 Iface_DT_Ptr : Node_Id;
6980 Typ_Comps : Elist_Id;
6982 -- Start of processing for Make_Tags
6985 pragma Assert (No (Access_Disp_Table (Typ)));
6986 Set_Access_Disp_Table (Typ, New_Elmt_List);
6988 -- 1) Generate the primary tag entities
6990 -- Primary dispatch table containing user-defined primitives
6992 DT_Ptr := Make_Defining_Identifier (Loc, New_External_Name (Tname, 'P'));
6993 Set_Etype (DT_Ptr, RTE (RE_Tag));
6994 Append_Elmt (DT_Ptr, Access_Disp_Table (Typ));
6996 -- Minimum decoration
6998 Set_Ekind (DT_Ptr, E_Variable);
6999 Set_Related_Type (DT_Ptr, Typ);
7001 -- For CPP types there is no need to build the dispatch tables since
7002 -- they are imported from the C++ side. If the CPP type has an IP then
7003 -- we declare now the variable that will store the copy of the C++ tag.
7004 -- If the CPP type is an interface, we need the variable as well because
7005 -- it becomes the pointer to the corresponding secondary table.
7007 if Is_CPP_Class (Typ) then
7008 if Has_CPP_Constructors (Typ) or else Is_Interface (Typ) then
7010 Make_Object_Declaration (Loc,
7011 Defining_Identifier => DT_Ptr,
7012 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
7014 Unchecked_Convert_To (RTE (RE_Tag),
7015 New_Reference_To (RTE (RE_Null_Address), Loc))));
7017 Set_Is_Statically_Allocated (DT_Ptr,
7018 Is_Library_Level_Tagged_Type (Typ));
7024 -- Primary dispatch table containing predefined primitives
7027 Make_Defining_Identifier (Loc,
7028 Chars => New_External_Name (Tname, 'Y'));
7029 Set_Etype (Predef_Prims_Ptr, RTE (RE_Address));
7030 Append_Elmt (Predef_Prims_Ptr, Access_Disp_Table (Typ));
7032 -- Import the forward declaration of the Dispatch Table wrapper
7033 -- record (Make_DT will take care of exporting it).
7035 if Building_Static_DT (Typ) then
7036 Set_Dispatch_Table_Wrappers (Typ, New_Elmt_List);
7039 Make_Defining_Identifier (Loc,
7040 Chars => New_External_Name (Tname, 'T'));
7042 Import_DT (Typ, DT, Is_Secondary_DT => False);
7044 if Has_DT (Typ) then
7046 Make_Object_Declaration (Loc,
7047 Defining_Identifier => DT_Ptr,
7048 Constant_Present => True,
7049 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
7051 Unchecked_Convert_To (RTE (RE_Tag),
7052 Make_Attribute_Reference (Loc,
7054 Make_Selected_Component (Loc,
7055 Prefix => New_Reference_To (DT, Loc),
7058 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
7059 Attribute_Name => Name_Address))));
7061 -- Generate the SCIL node for the previous object declaration
7062 -- because it has a tag initialization.
7064 if Generate_SCIL then
7066 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
7067 Set_SCIL_Entity (New_Node, Typ);
7068 Set_SCIL_Node (Last (Result), New_Node);
7072 Make_Object_Declaration (Loc,
7073 Defining_Identifier => Predef_Prims_Ptr,
7074 Constant_Present => True,
7075 Object_Definition => New_Reference_To
7076 (RTE (RE_Address), Loc),
7078 Make_Attribute_Reference (Loc,
7080 Make_Selected_Component (Loc,
7081 Prefix => New_Reference_To (DT, Loc),
7084 (RTE_Record_Component (RE_Predef_Prims), Loc)),
7085 Attribute_Name => Name_Address)));
7087 -- No dispatch table required
7091 Make_Object_Declaration (Loc,
7092 Defining_Identifier => DT_Ptr,
7093 Constant_Present => True,
7094 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
7096 Unchecked_Convert_To (RTE (RE_Tag),
7097 Make_Attribute_Reference (Loc,
7099 Make_Selected_Component (Loc,
7100 Prefix => New_Reference_To (DT, Loc),
7103 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
7104 Attribute_Name => Name_Address))));
7107 Set_Is_True_Constant (DT_Ptr);
7108 Set_Is_Statically_Allocated (DT_Ptr);
7112 -- 2) Generate the secondary tag entities
7114 -- Collect the components associated with secondary dispatch tables
7116 if Has_Interfaces (Typ) then
7117 Collect_Interface_Components (Typ, Typ_Comps);
7119 -- For each interface type we build a unique external name associated
7120 -- with its secondary dispatch table. This name is used to declare an
7121 -- object that references this secondary dispatch table, whose value
7122 -- will be used for the elaboration of Typ objects, and also for the
7123 -- elaboration of objects of types derived from Typ that do not
7124 -- override the primitives of this interface type.
7128 -- Note: The value of Suffix_Index must be in sync with the
7129 -- Suffix_Index values of secondary dispatch tables generated
7132 if Is_CPP_Class (Typ) then
7133 AI_Tag_Comp := First_Elmt (Typ_Comps);
7134 while Present (AI_Tag_Comp) loop
7135 Get_Secondary_DT_External_Name
7136 (Typ, Related_Type (Node (AI_Tag_Comp)), Suffix_Index);
7137 Typ_Name := Name_Find;
7139 -- Declare variables that will store the copy of the C++
7143 Make_Defining_Identifier (Loc,
7144 Chars => New_External_Name (Typ_Name, 'P'));
7145 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
7146 Set_Ekind (Iface_DT_Ptr, E_Variable);
7147 Set_Is_Tag (Iface_DT_Ptr);
7149 Set_Has_Thunks (Iface_DT_Ptr);
7151 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7152 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
7155 Make_Object_Declaration (Loc,
7156 Defining_Identifier => Iface_DT_Ptr,
7157 Object_Definition => New_Reference_To
7158 (RTE (RE_Interface_Tag), Loc),
7160 Unchecked_Convert_To (RTE (RE_Interface_Tag),
7161 New_Reference_To (RTE (RE_Null_Address), Loc))));
7163 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7164 Is_Library_Level_Tagged_Type (Typ));
7166 Next_Elmt (AI_Tag_Comp);
7169 -- This is not a CPP_Class type
7172 AI_Tag_Comp := First_Elmt (Typ_Comps);
7173 while Present (AI_Tag_Comp) loop
7174 Get_Secondary_DT_External_Name
7175 (Typ, Related_Type (Node (AI_Tag_Comp)), Suffix_Index);
7176 Typ_Name := Name_Find;
7178 if Building_Static_DT (Typ) then
7180 Make_Defining_Identifier (Loc,
7181 Chars => New_External_Name
7182 (Typ_Name, 'T', Suffix_Index => -1));
7184 (Tag_Typ => Related_Type (Node (AI_Tag_Comp)),
7186 Is_Secondary_DT => True);
7189 -- Secondary dispatch table referencing thunks to user-defined
7190 -- primitives covered by this interface.
7193 Make_Defining_Identifier (Loc,
7194 Chars => New_External_Name (Typ_Name, 'P'));
7195 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
7196 Set_Ekind (Iface_DT_Ptr, E_Constant);
7197 Set_Is_Tag (Iface_DT_Ptr);
7198 Set_Has_Thunks (Iface_DT_Ptr);
7199 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7200 Is_Library_Level_Tagged_Type (Typ));
7201 Set_Is_True_Constant (Iface_DT_Ptr);
7203 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7204 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
7206 if Building_Static_DT (Typ) then
7208 Make_Object_Declaration (Loc,
7209 Defining_Identifier => Iface_DT_Ptr,
7210 Constant_Present => True,
7211 Object_Definition => New_Reference_To
7212 (RTE (RE_Interface_Tag), Loc),
7214 Unchecked_Convert_To (RTE (RE_Interface_Tag),
7215 Make_Attribute_Reference (Loc,
7217 Make_Selected_Component (Loc,
7218 Prefix => New_Reference_To (Iface_DT, Loc),
7221 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
7222 Attribute_Name => Name_Address))));
7225 -- Secondary dispatch table referencing thunks to predefined
7229 Make_Defining_Identifier (Loc,
7230 Chars => New_External_Name (Typ_Name, 'Y'));
7231 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
7232 Set_Ekind (Iface_DT_Ptr, E_Constant);
7233 Set_Is_Tag (Iface_DT_Ptr);
7234 Set_Has_Thunks (Iface_DT_Ptr);
7235 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7236 Is_Library_Level_Tagged_Type (Typ));
7237 Set_Is_True_Constant (Iface_DT_Ptr);
7239 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7240 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
7242 -- Secondary dispatch table referencing user-defined primitives
7243 -- covered by this interface.
7246 Make_Defining_Identifier (Loc,
7247 Chars => New_External_Name (Typ_Name, 'D'));
7248 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
7249 Set_Ekind (Iface_DT_Ptr, E_Constant);
7250 Set_Is_Tag (Iface_DT_Ptr);
7251 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7252 Is_Library_Level_Tagged_Type (Typ));
7253 Set_Is_True_Constant (Iface_DT_Ptr);
7255 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7256 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
7258 -- Secondary dispatch table referencing predefined primitives
7261 Make_Defining_Identifier (Loc,
7262 Chars => New_External_Name (Typ_Name, 'Z'));
7263 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
7264 Set_Ekind (Iface_DT_Ptr, E_Constant);
7265 Set_Is_Tag (Iface_DT_Ptr);
7266 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7267 Is_Library_Level_Tagged_Type (Typ));
7268 Set_Is_True_Constant (Iface_DT_Ptr);
7270 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7271 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
7273 Next_Elmt (AI_Tag_Comp);
7278 -- 3) At the end of Access_Disp_Table, if the type has user-defined
7279 -- primitives, we add the entity of an access type declaration that
7280 -- is used by Build_Get_Prim_Op_Address to expand dispatching calls
7281 -- through the primary dispatch table.
7283 if UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ))) = 0 then
7284 Analyze_List (Result);
7287 -- type Typ_DT is array (1 .. Nb_Prims) of Prim_Ptr;
7288 -- type Typ_DT_Acc is access Typ_DT;
7292 Name_DT_Prims : constant Name_Id :=
7293 New_External_Name (Tname, 'G');
7294 Name_DT_Prims_Acc : constant Name_Id :=
7295 New_External_Name (Tname, 'H');
7296 DT_Prims : constant Entity_Id :=
7297 Make_Defining_Identifier (Loc,
7299 DT_Prims_Acc : constant Entity_Id :=
7300 Make_Defining_Identifier (Loc,
7304 Make_Full_Type_Declaration (Loc,
7305 Defining_Identifier => DT_Prims,
7307 Make_Constrained_Array_Definition (Loc,
7308 Discrete_Subtype_Definitions => New_List (
7310 Low_Bound => Make_Integer_Literal (Loc, 1),
7311 High_Bound => Make_Integer_Literal (Loc,
7313 (First_Tag_Component (Typ))))),
7314 Component_Definition =>
7315 Make_Component_Definition (Loc,
7316 Subtype_Indication =>
7317 New_Reference_To (RTE (RE_Prim_Ptr), Loc)))));
7320 Make_Full_Type_Declaration (Loc,
7321 Defining_Identifier => DT_Prims_Acc,
7323 Make_Access_To_Object_Definition (Loc,
7324 Subtype_Indication =>
7325 New_Occurrence_Of (DT_Prims, Loc))));
7327 Append_Elmt (DT_Prims_Acc, Access_Disp_Table (Typ));
7329 -- Analyze the resulting list and suppress the generation of the
7330 -- Init_Proc associated with the above array declaration because
7331 -- this type is never used in object declarations. It is only used
7332 -- to simplify the expansion associated with dispatching calls.
7334 Analyze_List (Result);
7335 Set_Suppress_Initialization (Base_Type (DT_Prims));
7337 -- Disable backend optimizations based on assumptions about the
7338 -- aliasing status of objects designated by the access to the
7339 -- dispatch table. Required to handle dispatch tables imported
7342 Set_No_Strict_Aliasing (Base_Type (DT_Prims_Acc));
7344 -- Add the freezing nodes of these declarations; required to avoid
7345 -- generating these freezing nodes in wrong scopes (for example in
7346 -- the IC routine of a derivation of Typ).
7347 -- What is an "IC routine"? Is "init_proc" meant here???
7349 Append_List_To (Result, Freeze_Entity (DT_Prims, Typ));
7350 Append_List_To (Result, Freeze_Entity (DT_Prims_Acc, Typ));
7352 -- Mark entity of dispatch table. Required by the back end to
7353 -- handle them properly.
7355 Set_Is_Dispatch_Table_Entity (DT_Prims);
7359 -- Mark entities of dispatch table. Required by the back end to handle
7362 if Present (DT) then
7363 Set_Is_Dispatch_Table_Entity (DT);
7364 Set_Is_Dispatch_Table_Entity (Etype (DT));
7367 if Present (Iface_DT) then
7368 Set_Is_Dispatch_Table_Entity (Iface_DT);
7369 Set_Is_Dispatch_Table_Entity (Etype (Iface_DT));
7372 if Is_CPP_Class (Root_Type (Typ)) then
7373 Set_Ekind (DT_Ptr, E_Variable);
7375 Set_Ekind (DT_Ptr, E_Constant);
7378 Set_Is_Tag (DT_Ptr);
7379 Set_Related_Type (DT_Ptr, Typ);
7388 function New_Value (From : Node_Id) return Node_Id is
7389 Res : constant Node_Id := Duplicate_Subexpr (From);
7391 if Is_Access_Type (Etype (From)) then
7393 Make_Explicit_Dereference (Sloc (From),
7400 -----------------------------------
7401 -- Original_View_In_Visible_Part --
7402 -----------------------------------
7404 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
7405 Scop : constant Entity_Id := Scope (Typ);
7408 -- The scope must be a package
7410 if not Is_Package_Or_Generic_Package (Scop) then
7414 -- A type with a private declaration has a private view declared in
7415 -- the visible part.
7417 if Has_Private_Declaration (Typ) then
7421 return List_Containing (Parent (Typ)) =
7422 Visible_Declarations (Specification (Unit_Declaration_Node (Scop)));
7423 end Original_View_In_Visible_Part;
7429 function Prim_Op_Kind
7431 Typ : Entity_Id) return Node_Id
7433 Full_Typ : Entity_Id := Typ;
7434 Loc : constant Source_Ptr := Sloc (Prim);
7435 Prim_Op : Entity_Id;
7438 -- Retrieve the original primitive operation
7440 Prim_Op := Ultimate_Alias (Prim);
7442 if Ekind (Typ) = E_Record_Type
7443 and then Present (Corresponding_Concurrent_Type (Typ))
7445 Full_Typ := Corresponding_Concurrent_Type (Typ);
7448 -- When a private tagged type is completed by a concurrent type,
7449 -- retrieve the full view.
7451 if Is_Private_Type (Full_Typ) then
7452 Full_Typ := Full_View (Full_Typ);
7455 if Ekind (Prim_Op) = E_Function then
7457 -- Protected function
7459 if Ekind (Full_Typ) = E_Protected_Type then
7460 return New_Reference_To (RTE (RE_POK_Protected_Function), Loc);
7464 elsif Ekind (Full_Typ) = E_Task_Type then
7465 return New_Reference_To (RTE (RE_POK_Task_Function), Loc);
7470 return New_Reference_To (RTE (RE_POK_Function), Loc);
7474 pragma Assert (Ekind (Prim_Op) = E_Procedure);
7476 if Ekind (Full_Typ) = E_Protected_Type then
7480 if Is_Primitive_Wrapper (Prim_Op)
7481 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
7483 return New_Reference_To (RTE (RE_POK_Protected_Entry), Loc);
7485 -- Protected procedure
7488 return New_Reference_To (RTE (RE_POK_Protected_Procedure), Loc);
7491 elsif Ekind (Full_Typ) = E_Task_Type then
7495 if Is_Primitive_Wrapper (Prim_Op)
7496 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
7498 return New_Reference_To (RTE (RE_POK_Task_Entry), Loc);
7500 -- Task "procedure". These are the internally Expander-generated
7501 -- procedures (task body for instance).
7504 return New_Reference_To (RTE (RE_POK_Task_Procedure), Loc);
7507 -- Regular procedure
7510 return New_Reference_To (RTE (RE_POK_Procedure), Loc);
7515 ------------------------
7516 -- Register_Primitive --
7517 ------------------------
7519 function Register_Primitive
7521 Prim : Entity_Id) return List_Id
7524 Iface_Prim : Entity_Id;
7525 Iface_Typ : Entity_Id;
7526 Iface_DT_Ptr : Entity_Id;
7527 Iface_DT_Elmt : Elmt_Id;
7528 L : constant List_Id := New_List;
7531 Tag_Typ : Entity_Id;
7532 Thunk_Id : Entity_Id;
7533 Thunk_Code : Node_Id;
7536 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
7537 pragma Assert (VM_Target = No_VM);
7539 -- Do not register in the dispatch table eliminated primitives
7541 if not RTE_Available (RE_Tag)
7542 or else Is_Eliminated (Ultimate_Alias (Prim))
7547 if not Present (Interface_Alias (Prim)) then
7548 Tag_Typ := Scope (DTC_Entity (Prim));
7549 Pos := DT_Position (Prim);
7550 Tag := First_Tag_Component (Tag_Typ);
7552 if Is_Predefined_Dispatching_Operation (Prim)
7553 or else Is_Predefined_Dispatching_Alias (Prim)
7556 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Tag_Typ))));
7559 Build_Set_Predefined_Prim_Op_Address (Loc,
7560 Tag_Node => New_Reference_To (DT_Ptr, Loc),
7563 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
7564 Make_Attribute_Reference (Loc,
7565 Prefix => New_Reference_To (Prim, Loc),
7566 Attribute_Name => Name_Unrestricted_Access))));
7568 -- Register copy of the pointer to the 'size primitive in the TSD
7570 if Chars (Prim) = Name_uSize
7571 and then RTE_Record_Component_Available (RE_Size_Func)
7573 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
7575 Build_Set_Size_Function (Loc,
7576 Tag_Node => New_Reference_To (DT_Ptr, Loc),
7577 Size_Func => Prim));
7581 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
7583 -- Skip registration of primitives located in the C++ part of the
7584 -- dispatch table. Their slot is set by the IC routine.
7586 if not Is_CPP_Class (Root_Type (Tag_Typ))
7587 or else Pos > CPP_Num_Prims (Tag_Typ)
7589 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
7591 Build_Set_Prim_Op_Address (Loc,
7593 Tag_Node => New_Reference_To (DT_Ptr, Loc),
7596 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
7597 Make_Attribute_Reference (Loc,
7598 Prefix => New_Reference_To (Prim, Loc),
7599 Attribute_Name => Name_Unrestricted_Access))));
7603 -- Ada 2005 (AI-251): Primitive associated with an interface type
7604 -- Generate the code of the thunk only if the interface type is not an
7605 -- immediate ancestor of Typ; otherwise the dispatch table associated
7606 -- with the interface is the primary dispatch table and we have nothing
7610 Tag_Typ := Find_Dispatching_Type (Alias (Prim));
7611 Iface_Typ := Find_Dispatching_Type (Interface_Alias (Prim));
7613 pragma Assert (Is_Interface (Iface_Typ));
7615 -- No action needed for interfaces that are ancestors of Typ because
7616 -- their primitives are located in the primary dispatch table.
7618 if Is_Ancestor (Iface_Typ, Tag_Typ, Use_Full_View => True) then
7621 -- No action needed for primitives located in the C++ part of the
7622 -- dispatch table. Their slot is set by the IC routine.
7624 elsif Is_CPP_Class (Root_Type (Tag_Typ))
7625 and then DT_Position (Alias (Prim)) <= CPP_Num_Prims (Tag_Typ)
7626 and then not Is_Predefined_Dispatching_Operation (Prim)
7627 and then not Is_Predefined_Dispatching_Alias (Prim)
7632 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
7634 if not Is_Ancestor (Iface_Typ, Tag_Typ, Use_Full_View => True)
7635 and then Present (Thunk_Code)
7637 -- Generate the code necessary to fill the appropriate entry of
7638 -- the secondary dispatch table of Prim's controlling type with
7639 -- Thunk_Id's address.
7641 Iface_DT_Elmt := Find_Interface_ADT (Tag_Typ, Iface_Typ);
7642 Iface_DT_Ptr := Node (Iface_DT_Elmt);
7643 pragma Assert (Has_Thunks (Iface_DT_Ptr));
7645 Iface_Prim := Interface_Alias (Prim);
7646 Pos := DT_Position (Iface_Prim);
7647 Tag := First_Tag_Component (Iface_Typ);
7649 Prepend_To (L, Thunk_Code);
7651 if Is_Predefined_Dispatching_Operation (Prim)
7652 or else Is_Predefined_Dispatching_Alias (Prim)
7655 Build_Set_Predefined_Prim_Op_Address (Loc,
7657 New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
7660 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
7661 Make_Attribute_Reference (Loc,
7662 Prefix => New_Reference_To (Thunk_Id, Loc),
7663 Attribute_Name => Name_Unrestricted_Access))));
7665 Next_Elmt (Iface_DT_Elmt);
7666 Next_Elmt (Iface_DT_Elmt);
7667 Iface_DT_Ptr := Node (Iface_DT_Elmt);
7668 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
7671 Build_Set_Predefined_Prim_Op_Address (Loc,
7673 New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
7676 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
7677 Make_Attribute_Reference (Loc,
7678 Prefix => New_Reference_To (Alias (Prim), Loc),
7679 Attribute_Name => Name_Unrestricted_Access))));
7682 pragma Assert (Pos /= Uint_0
7683 and then Pos <= DT_Entry_Count (Tag));
7686 Build_Set_Prim_Op_Address (Loc,
7688 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
7691 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
7692 Make_Attribute_Reference (Loc,
7693 Prefix => New_Reference_To (Thunk_Id, Loc),
7694 Attribute_Name => Name_Unrestricted_Access))));
7696 Next_Elmt (Iface_DT_Elmt);
7697 Next_Elmt (Iface_DT_Elmt);
7698 Iface_DT_Ptr := Node (Iface_DT_Elmt);
7699 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
7702 Build_Set_Prim_Op_Address (Loc,
7704 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
7707 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
7708 Make_Attribute_Reference (Loc,
7709 Prefix => New_Reference_To (Alias (Prim), Loc),
7710 Attribute_Name => Name_Unrestricted_Access))));
7717 end Register_Primitive;
7719 -------------------------
7720 -- Set_All_DT_Position --
7721 -------------------------
7723 procedure Set_All_DT_Position (Typ : Entity_Id) is
7725 function In_Predef_Prims_DT (Prim : Entity_Id) return Boolean;
7726 -- Returns True if Prim is located in the dispatch table of
7727 -- predefined primitives
7729 procedure Validate_Position (Prim : Entity_Id);
7730 -- Check that the position assigned to Prim is completely safe
7731 -- (it has not been assigned to a previously defined primitive
7732 -- operation of Typ)
7734 ------------------------
7735 -- In_Predef_Prims_DT --
7736 ------------------------
7738 function In_Predef_Prims_DT (Prim : Entity_Id) return Boolean is
7742 -- Predefined primitives
7744 if Is_Predefined_Dispatching_Operation (Prim) then
7747 -- Renamings of predefined primitives
7749 elsif Present (Alias (Prim))
7750 and then Is_Predefined_Dispatching_Operation (Ultimate_Alias (Prim))
7752 if Chars (Ultimate_Alias (Prim)) /= Name_Op_Eq then
7755 -- User-defined renamings of predefined equality have their own
7756 -- slot in the primary dispatch table
7760 while Present (Alias (E)) loop
7761 if Comes_From_Source (E) then
7768 return not Comes_From_Source (E);
7771 -- User-defined primitives
7776 end In_Predef_Prims_DT;
7778 -----------------------
7779 -- Validate_Position --
7780 -----------------------
7782 procedure Validate_Position (Prim : Entity_Id) is
7787 -- Aliased primitives are safe
7789 if Present (Alias (Prim)) then
7793 Op_Elmt := First_Elmt (Primitive_Operations (Typ));
7794 while Present (Op_Elmt) loop
7795 Op := Node (Op_Elmt);
7797 -- No need to check against itself
7802 -- Primitive operations covering abstract interfaces are
7805 elsif Present (Interface_Alias (Op)) then
7808 -- Predefined dispatching operations are completely safe. They
7809 -- are allocated at fixed positions in a separate table.
7811 elsif Is_Predefined_Dispatching_Operation (Op)
7812 or else Is_Predefined_Dispatching_Alias (Op)
7816 -- Aliased subprograms are safe
7818 elsif Present (Alias (Op)) then
7821 elsif DT_Position (Op) = DT_Position (Prim)
7822 and then not Is_Predefined_Dispatching_Operation (Op)
7823 and then not Is_Predefined_Dispatching_Operation (Prim)
7824 and then not Is_Predefined_Dispatching_Alias (Op)
7825 and then not Is_Predefined_Dispatching_Alias (Prim)
7828 -- Handle aliased subprograms
7837 if Present (Overridden_Operation (Op_1)) then
7838 Op_1 := Overridden_Operation (Op_1);
7839 elsif Present (Alias (Op_1)) then
7840 Op_1 := Alias (Op_1);
7848 if Present (Overridden_Operation (Op_2)) then
7849 Op_2 := Overridden_Operation (Op_2);
7850 elsif Present (Alias (Op_2)) then
7851 Op_2 := Alias (Op_2);
7857 if Op_1 /= Op_2 then
7858 raise Program_Error;
7863 Next_Elmt (Op_Elmt);
7865 end Validate_Position;
7869 Parent_Typ : constant Entity_Id := Etype (Typ);
7870 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
7871 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
7873 Adjusted : Boolean := False;
7874 Finalized : Boolean := False;
7880 Prim_Elmt : Elmt_Id;
7882 -- Start of processing for Set_All_DT_Position
7885 pragma Assert (Present (First_Tag_Component (Typ)));
7887 -- Set the DT_Position for each primitive operation. Perform some sanity
7888 -- checks to avoid building inconsistent dispatch tables.
7890 -- First stage: Set the DTC entity of all the primitive operations. This
7891 -- is required to properly read the DT_Position attribute in the latter
7894 Prim_Elmt := First_Prim;
7896 while Present (Prim_Elmt) loop
7897 Prim := Node (Prim_Elmt);
7899 -- Predefined primitives have a separate dispatch table
7901 if not In_Predef_Prims_DT (Prim) then
7902 Count_Prim := Count_Prim + 1;
7905 Set_DTC_Entity_Value (Typ, Prim);
7907 -- Clear any previous value of the DT_Position attribute. In this
7908 -- way we ensure that the final position of all the primitives is
7909 -- established by the following stages of this algorithm.
7911 Set_DT_Position (Prim, No_Uint);
7913 Next_Elmt (Prim_Elmt);
7917 Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean :=
7922 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id);
7923 -- Called if Typ is declared in a nested package or a public child
7924 -- package to handle inherited primitives that were inherited by Typ
7925 -- in the visible part, but whose declaration was deferred because
7926 -- the parent operation was private and not visible at that point.
7928 procedure Set_Fixed_Prim (Pos : Nat);
7929 -- Sets to true an element of the Fixed_Prim table to indicate
7930 -- that this entry of the dispatch table of Typ is occupied.
7932 ------------------------------------------
7933 -- Handle_Inherited_Private_Subprograms --
7934 ------------------------------------------
7936 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id) is
7939 Op_Elmt_2 : Elmt_Id;
7940 Prim_Op : Entity_Id;
7941 Parent_Subp : Entity_Id;
7944 Op_List := Primitive_Operations (Typ);
7946 Op_Elmt := First_Elmt (Op_List);
7947 while Present (Op_Elmt) loop
7948 Prim_Op := Node (Op_Elmt);
7950 -- Search primitives that are implicit operations with an
7951 -- internal name whose parent operation has a normal name.
7953 if Present (Alias (Prim_Op))
7954 and then Find_Dispatching_Type (Alias (Prim_Op)) /= Typ
7955 and then not Comes_From_Source (Prim_Op)
7956 and then Is_Internal_Name (Chars (Prim_Op))
7957 and then not Is_Internal_Name (Chars (Alias (Prim_Op)))
7959 Parent_Subp := Alias (Prim_Op);
7961 -- Check if the type has an explicit overriding for this
7964 Op_Elmt_2 := Next_Elmt (Op_Elmt);
7965 while Present (Op_Elmt_2) loop
7966 if Chars (Node (Op_Elmt_2)) = Chars (Parent_Subp)
7967 and then Type_Conformant (Prim_Op, Node (Op_Elmt_2))
7969 Set_DT_Position (Prim_Op, DT_Position (Parent_Subp));
7970 Set_DT_Position (Node (Op_Elmt_2),
7971 DT_Position (Parent_Subp));
7972 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim_Op)));
7974 goto Next_Primitive;
7977 Next_Elmt (Op_Elmt_2);
7982 Next_Elmt (Op_Elmt);
7984 end Handle_Inherited_Private_Subprograms;
7986 --------------------
7987 -- Set_Fixed_Prim --
7988 --------------------
7990 procedure Set_Fixed_Prim (Pos : Nat) is
7992 pragma Assert (Pos <= Count_Prim);
7993 Fixed_Prim (Pos) := True;
7995 when Constraint_Error =>
7996 raise Program_Error;
8000 -- In case of nested packages and public child package it may be
8001 -- necessary a special management on inherited subprograms so that
8002 -- the dispatch table is properly filled.
8004 if Ekind (Scope (Scope (Typ))) = E_Package
8005 and then Scope (Scope (Typ)) /= Standard_Standard
8006 and then ((Is_Derived_Type (Typ) and then not Is_Private_Type (Typ))
8008 (Nkind (Parent (Typ)) = N_Private_Extension_Declaration
8009 and then Is_Generic_Type (Typ)))
8010 and then In_Open_Scopes (Scope (Etype (Typ)))
8011 and then Is_Base_Type (Typ)
8013 Handle_Inherited_Private_Subprograms (Typ);
8016 -- Second stage: Register fixed entries
8019 Prim_Elmt := First_Prim;
8020 while Present (Prim_Elmt) loop
8021 Prim := Node (Prim_Elmt);
8023 -- Predefined primitives have a separate table and all its
8024 -- entries are at predefined fixed positions.
8026 if In_Predef_Prims_DT (Prim) then
8027 if Is_Predefined_Dispatching_Operation (Prim) then
8028 Set_DT_Position (Prim, Default_Prim_Op_Position (Prim));
8030 else pragma Assert (Present (Alias (Prim)));
8031 Set_DT_Position (Prim,
8032 Default_Prim_Op_Position (Ultimate_Alias (Prim)));
8035 -- Overriding primitives of ancestor abstract interfaces
8037 elsif Present (Interface_Alias (Prim))
8038 and then Is_Ancestor
8039 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ,
8040 Use_Full_View => True)
8042 pragma Assert (DT_Position (Prim) = No_Uint
8043 and then Present (DTC_Entity (Interface_Alias (Prim))));
8045 E := Interface_Alias (Prim);
8046 Set_DT_Position (Prim, DT_Position (E));
8049 (DT_Position (Alias (Prim)) = No_Uint
8050 or else DT_Position (Alias (Prim)) = DT_Position (E));
8051 Set_DT_Position (Alias (Prim), DT_Position (E));
8052 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));
8054 -- Overriding primitives must use the same entry as the
8055 -- overridden primitive.
8057 elsif not Present (Interface_Alias (Prim))
8058 and then Present (Alias (Prim))
8059 and then Chars (Prim) = Chars (Alias (Prim))
8060 and then Find_Dispatching_Type (Alias (Prim)) /= Typ
8061 and then Is_Ancestor
8062 (Find_Dispatching_Type (Alias (Prim)), Typ,
8063 Use_Full_View => True)
8064 and then Present (DTC_Entity (Alias (Prim)))
8067 Set_DT_Position (Prim, DT_Position (E));
8069 if not Is_Predefined_Dispatching_Alias (E) then
8070 Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
8074 Next_Elmt (Prim_Elmt);
8077 -- Third stage: Fix the position of all the new primitives.
8078 -- Entries associated with primitives covering interfaces
8079 -- are handled in a latter round.
8081 Prim_Elmt := First_Prim;
8082 while Present (Prim_Elmt) loop
8083 Prim := Node (Prim_Elmt);
8085 -- Skip primitives previously set entries
8087 if DT_Position (Prim) /= No_Uint then
8090 -- Primitives covering interface primitives are handled later
8092 elsif Present (Interface_Alias (Prim)) then
8096 -- Take the next available position in the DT
8099 Nb_Prim := Nb_Prim + 1;
8100 pragma Assert (Nb_Prim <= Count_Prim);
8101 exit when not Fixed_Prim (Nb_Prim);
8104 Set_DT_Position (Prim, UI_From_Int (Nb_Prim));
8105 Set_Fixed_Prim (Nb_Prim);
8108 Next_Elmt (Prim_Elmt);
8112 -- Fourth stage: Complete the decoration of primitives covering
8113 -- interfaces (that is, propagate the DT_Position attribute
8114 -- from the aliased primitive)
8116 Prim_Elmt := First_Prim;
8117 while Present (Prim_Elmt) loop
8118 Prim := Node (Prim_Elmt);
8120 if DT_Position (Prim) = No_Uint
8121 and then Present (Interface_Alias (Prim))
8123 pragma Assert (Present (Alias (Prim))
8124 and then Find_Dispatching_Type (Alias (Prim)) = Typ);
8126 -- Check if this entry will be placed in the primary DT
8129 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ,
8130 Use_Full_View => True)
8132 pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
8133 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
8135 -- Otherwise it will be placed in the secondary DT
8139 (DT_Position (Interface_Alias (Prim)) /= No_Uint);
8140 Set_DT_Position (Prim,
8141 DT_Position (Interface_Alias (Prim)));
8145 Next_Elmt (Prim_Elmt);
8148 -- Generate listing showing the contents of the dispatch tables.
8149 -- This action is done before some further static checks because
8150 -- in case of critical errors caused by a wrong dispatch table
8151 -- we need to see the contents of such table.
8153 if Debug_Flag_ZZ then
8157 -- Final stage: Ensure that the table is correct plus some further
8158 -- verifications concerning the primitives.
8160 Prim_Elmt := First_Prim;
8162 while Present (Prim_Elmt) loop
8163 Prim := Node (Prim_Elmt);
8165 -- At this point all the primitives MUST have a position
8166 -- in the dispatch table.
8168 if DT_Position (Prim) = No_Uint then
8169 raise Program_Error;
8172 -- Calculate real size of the dispatch table
8174 if not In_Predef_Prims_DT (Prim)
8175 and then UI_To_Int (DT_Position (Prim)) > DT_Length
8177 DT_Length := UI_To_Int (DT_Position (Prim));
8180 -- Ensure that the assigned position to non-predefined
8181 -- dispatching operations in the dispatch table is correct.
8183 if not Is_Predefined_Dispatching_Operation (Prim)
8184 and then not Is_Predefined_Dispatching_Alias (Prim)
8186 Validate_Position (Prim);
8189 if Chars (Prim) = Name_Finalize then
8193 if Chars (Prim) = Name_Adjust then
8197 -- An abstract operation cannot be declared in the private part for a
8198 -- visible abstract type, because it can't be overridden outside this
8199 -- package hierarchy. For explicit declarations this is checked at
8200 -- the point of declaration, but for inherited operations it must be
8201 -- done when building the dispatch table.
8203 -- Ada 2005 (AI-251): Primitives associated with interfaces are
8204 -- excluded from this check because interfaces must be visible in
8205 -- the public and private part (RM 7.3 (7.3/2))
8207 -- We disable this check in CodePeer mode, to accommodate legacy
8210 if not CodePeer_Mode
8211 and then Is_Abstract_Type (Typ)
8212 and then Is_Abstract_Subprogram (Prim)
8213 and then Present (Alias (Prim))
8214 and then not Is_Interface
8215 (Find_Dispatching_Type (Ultimate_Alias (Prim)))
8216 and then not Present (Interface_Alias (Prim))
8217 and then Is_Derived_Type (Typ)
8218 and then In_Private_Part (Current_Scope)
8220 List_Containing (Parent (Prim)) =
8221 Private_Declarations
8222 (Specification (Unit_Declaration_Node (Current_Scope)))
8223 and then Original_View_In_Visible_Part (Typ)
8225 -- We exclude Input and Output stream operations because
8226 -- Limited_Controlled inherits useless Input and Output
8227 -- stream operations from Root_Controlled, which can
8228 -- never be overridden.
8230 if not Is_TSS (Prim, TSS_Stream_Input)
8232 not Is_TSS (Prim, TSS_Stream_Output)
8235 ("abstract inherited private operation&" &
8236 " must be overridden (RM 3.9.3(10))",
8237 Parent (Typ), Prim);
8241 Next_Elmt (Prim_Elmt);
8246 if Is_Controlled (Typ) then
8247 if not Finalized then
8249 ("controlled type has no explicit Finalize method?", Typ);
8251 elsif not Adjusted then
8253 ("controlled type has no explicit Adjust method?", Typ);
8257 -- Set the final size of the Dispatch Table
8259 Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));
8261 -- The derived type must have at least as many components as its parent
8262 -- (for root types Etype points to itself and the test cannot fail).
8264 if DT_Entry_Count (The_Tag) <
8265 DT_Entry_Count (First_Tag_Component (Parent_Typ))
8267 raise Program_Error;
8269 end Set_All_DT_Position;
8271 --------------------------
8272 -- Set_CPP_Constructors --
8273 --------------------------
8275 procedure Set_CPP_Constructors (Typ : Entity_Id) is
8277 procedure Set_CPP_Constructors_Old (Typ : Entity_Id);
8278 -- For backward compatibility this routine handles CPP constructors
8279 -- of non-tagged types.
8281 procedure Set_CPP_Constructors_Old (Typ : Entity_Id) is
8285 Found : Boolean := False;
8290 -- Look for the constructor entities
8292 E := Next_Entity (Typ);
8293 while Present (E) loop
8294 if Ekind (E) = E_Function
8295 and then Is_Constructor (E)
8297 -- Create the init procedure
8301 Init := Make_Defining_Identifier (Loc,
8302 Make_Init_Proc_Name (Typ));
8305 Make_Parameter_Specification (Loc,
8306 Defining_Identifier =>
8307 Make_Defining_Identifier (Loc, Name_X),
8309 New_Reference_To (Typ, Loc)));
8311 if Present (Parameter_Specifications (Parent (E))) then
8312 P := First (Parameter_Specifications (Parent (E)));
8313 while Present (P) loop
8315 Make_Parameter_Specification (Loc,
8316 Defining_Identifier =>
8317 Make_Defining_Identifier (Loc,
8318 Chars (Defining_Identifier (P))),
8320 New_Copy_Tree (Parameter_Type (P))));
8326 Make_Subprogram_Declaration (Loc,
8327 Make_Procedure_Specification (Loc,
8328 Defining_Unit_Name => Init,
8329 Parameter_Specifications => Parms)));
8331 Set_Init_Proc (Typ, Init);
8332 Set_Is_Imported (Init);
8333 Set_Interface_Name (Init, Interface_Name (E));
8334 Set_Convention (Init, Convention_C);
8335 Set_Is_Public (Init);
8336 Set_Has_Completion (Init);
8342 -- If there are no constructors, mark the type as abstract since we
8343 -- won't be able to declare objects of that type.
8346 Set_Is_Abstract_Type (Typ);
8348 end Set_CPP_Constructors_Old;
8354 Found : Boolean := False;
8358 Constructor_Decl_Node : Node_Id;
8359 Constructor_Id : Entity_Id;
8360 Wrapper_Id : Entity_Id;
8361 Wrapper_Body_Node : Node_Id;
8363 Body_Stmts : List_Id;
8364 Init_Tags_List : List_Id;
8367 pragma Assert (Is_CPP_Class (Typ));
8369 -- For backward compatibility the compiler accepts C++ classes
8370 -- imported through non-tagged record types. In such case the
8371 -- wrapper of the C++ constructor is useless because the _tag
8372 -- component is not available.
8375 -- type Root is limited record ...
8376 -- pragma Import (CPP, Root);
8377 -- function New_Root return Root;
8378 -- pragma CPP_Constructor (New_Root, ... );
8380 if not Is_Tagged_Type (Typ) then
8381 Set_CPP_Constructors_Old (Typ);
8385 -- Look for the constructor entities
8387 E := Next_Entity (Typ);
8388 while Present (E) loop
8389 if Ekind (E) = E_Function
8390 and then Is_Constructor (E)
8395 -- Generate the declaration of the imported C++ constructor
8399 Make_Parameter_Specification (Loc,
8400 Defining_Identifier =>
8401 Make_Defining_Identifier (Loc, Name_uInit),
8403 New_Reference_To (Typ, Loc)));
8405 if Present (Parameter_Specifications (Parent (E))) then
8406 P := First (Parameter_Specifications (Parent (E)));
8407 while Present (P) loop
8409 Make_Parameter_Specification (Loc,
8410 Defining_Identifier =>
8411 Make_Defining_Identifier (Loc,
8412 Chars (Defining_Identifier (P))),
8413 Parameter_Type => New_Copy_Tree (Parameter_Type (P))));
8418 Constructor_Id := Make_Temporary (Loc, 'P');
8420 Constructor_Decl_Node :=
8421 Make_Subprogram_Declaration (Loc,
8422 Make_Procedure_Specification (Loc,
8423 Defining_Unit_Name => Constructor_Id,
8424 Parameter_Specifications => Parms));
8426 Set_Is_Imported (Constructor_Id);
8427 Set_Interface_Name (Constructor_Id, Interface_Name (E));
8428 Set_Convention (Constructor_Id, Convention_C);
8429 Set_Is_Public (Constructor_Id);
8430 Set_Has_Completion (Constructor_Id);
8432 -- Build the wrapper of this constructor
8436 Make_Parameter_Specification (Loc,
8437 Defining_Identifier =>
8438 Make_Defining_Identifier (Loc, Name_uInit),
8440 New_Reference_To (Typ, Loc)));
8442 if Present (Parameter_Specifications (Parent (E))) then
8443 P := First (Parameter_Specifications (Parent (E)));
8444 while Present (P) loop
8446 Make_Parameter_Specification (Loc,
8447 Defining_Identifier =>
8448 Make_Defining_Identifier (Loc,
8449 Chars (Defining_Identifier (P))),
8450 Parameter_Type => New_Copy_Tree (Parameter_Type (P))));
8455 Body_Stmts := New_List;
8457 -- Invoke the C++ constructor
8459 Actuals := New_List;
8462 while Present (P) loop
8464 New_Reference_To (Defining_Identifier (P), Loc));
8468 Append_To (Body_Stmts,
8469 Make_Procedure_Call_Statement (Loc,
8470 Name => New_Reference_To (Constructor_Id, Loc),
8471 Parameter_Associations => Actuals));
8473 -- Initialize copies of C++ primary and secondary tags
8475 Init_Tags_List := New_List;
8482 Tag_Elmt := First_Elmt (Access_Disp_Table (Typ));
8483 Tag_Comp := First_Tag_Component (Typ);
8485 while Present (Tag_Elmt)
8486 and then Is_Tag (Node (Tag_Elmt))
8488 -- Skip the following assertion with primary tags because
8489 -- Related_Type is not set on primary tag components
8491 pragma Assert (Tag_Comp = First_Tag_Component (Typ)
8492 or else Related_Type (Node (Tag_Elmt))
8493 = Related_Type (Tag_Comp));
8495 Append_To (Init_Tags_List,
8496 Make_Assignment_Statement (Loc,
8498 New_Reference_To (Node (Tag_Elmt), Loc),
8500 Make_Selected_Component (Loc,
8502 Make_Identifier (Loc, Name_uInit),
8504 New_Reference_To (Tag_Comp, Loc))));
8506 Tag_Comp := Next_Tag_Component (Tag_Comp);
8507 Next_Elmt (Tag_Elmt);
8511 Append_To (Body_Stmts,
8512 Make_If_Statement (Loc,
8517 (Node (First_Elmt (Access_Disp_Table (Typ))),
8520 Unchecked_Convert_To (RTE (RE_Tag),
8521 New_Reference_To (RTE (RE_Null_Address), Loc))),
8522 Then_Statements => Init_Tags_List));
8524 Wrapper_Id := Make_Defining_Identifier (Loc,
8525 Make_Init_Proc_Name (Typ));
8527 Wrapper_Body_Node :=
8528 Make_Subprogram_Body (Loc,
8530 Make_Procedure_Specification (Loc,
8531 Defining_Unit_Name => Wrapper_Id,
8532 Parameter_Specifications => Parms),
8533 Declarations => New_List (Constructor_Decl_Node),
8534 Handled_Statement_Sequence =>
8535 Make_Handled_Sequence_Of_Statements (Loc,
8536 Statements => Body_Stmts,
8537 Exception_Handlers => No_List));
8539 Discard_Node (Wrapper_Body_Node);
8540 Set_Init_Proc (Typ, Wrapper_Id);
8546 -- If there are no constructors, mark the type as abstract since we
8547 -- won't be able to declare objects of that type.
8550 Set_Is_Abstract_Type (Typ);
8553 -- If the CPP type has constructors then it must import also the default
8554 -- C++ constructor. It is required for default initialization of objects
8555 -- of the type. It is also required to elaborate objects of Ada types
8556 -- that are defined as derivations of this CPP type.
8558 if Has_CPP_Constructors (Typ)
8559 and then No (Init_Proc (Typ))
8561 Error_Msg_N ("?default constructor must be imported from C++", Typ);
8563 end Set_CPP_Constructors;
8565 --------------------------
8566 -- Set_DTC_Entity_Value --
8567 --------------------------
8569 procedure Set_DTC_Entity_Value
8570 (Tagged_Type : Entity_Id;
8574 if Present (Interface_Alias (Prim))
8575 and then Is_Interface
8576 (Find_Dispatching_Type (Interface_Alias (Prim)))
8578 Set_DTC_Entity (Prim,
8581 Iface => Find_Dispatching_Type (Interface_Alias (Prim))));
8583 Set_DTC_Entity (Prim,
8584 First_Tag_Component (Tagged_Type));
8586 end Set_DTC_Entity_Value;
8592 function Tagged_Kind (T : Entity_Id) return Node_Id is
8593 Conc_Typ : Entity_Id;
8594 Loc : constant Source_Ptr := Sloc (T);
8598 (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));
8602 if Is_Abstract_Type (T) then
8603 if Is_Limited_Record (T) then
8604 return New_Reference_To (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
8606 return New_Reference_To (RTE (RE_TK_Abstract_Tagged), Loc);
8611 elsif Is_Concurrent_Record_Type (T) then
8612 Conc_Typ := Corresponding_Concurrent_Type (T);
8614 if Present (Full_View (Conc_Typ)) then
8615 Conc_Typ := Full_View (Conc_Typ);
8618 if Ekind (Conc_Typ) = E_Protected_Type then
8619 return New_Reference_To (RTE (RE_TK_Protected), Loc);
8621 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
8622 return New_Reference_To (RTE (RE_TK_Task), Loc);
8625 -- Regular tagged kinds
8628 if Is_Limited_Record (T) then
8629 return New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc);
8631 return New_Reference_To (RTE (RE_TK_Tagged), Loc);
8640 procedure Write_DT (Typ : Entity_Id) is
8645 -- Protect this procedure against wrong usage. Required because it will
8646 -- be used directly from GDB
8648 if not (Typ <= Last_Node_Id)
8649 or else not Is_Tagged_Type (Typ)
8651 Write_Str ("wrong usage: Write_DT must be used with tagged types");
8656 Write_Int (Int (Typ));
8658 Write_Name (Chars (Typ));
8660 if Is_Interface (Typ) then
8661 Write_Str (" is interface");
8666 Elmt := First_Elmt (Primitive_Operations (Typ));
8667 while Present (Elmt) loop
8668 Prim := Node (Elmt);
8671 -- Indicate if this primitive will be allocated in the primary
8672 -- dispatch table or in a secondary dispatch table associated
8673 -- with an abstract interface type
8675 if Present (DTC_Entity (Prim)) then
8676 if Etype (DTC_Entity (Prim)) = RTE (RE_Tag) then
8683 -- Output the node of this primitive operation and its name
8685 Write_Int (Int (Prim));
8688 if Is_Predefined_Dispatching_Operation (Prim) then
8689 Write_Str ("(predefined) ");
8692 -- Prefix the name of the primitive with its corresponding tagged
8693 -- type to facilitate seeing inherited primitives.
8695 if Present (Alias (Prim)) then
8697 (Chars (Find_Dispatching_Type (Ultimate_Alias (Prim))));
8699 Write_Name (Chars (Typ));
8703 Write_Name (Chars (Prim));
8705 -- Indicate if this primitive has an aliased primitive
8707 if Present (Alias (Prim)) then
8708 Write_Str (" (alias = ");
8709 Write_Int (Int (Alias (Prim)));
8711 -- If the DTC_Entity attribute is already set we can also output
8712 -- the name of the interface covered by this primitive (if any).
8714 if Present (DTC_Entity (Alias (Prim)))
8715 and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
8717 Write_Str (" from interface ");
8718 Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
8721 if Present (Interface_Alias (Prim)) then
8722 Write_Str (", AI_Alias of ");
8724 if Is_Null_Interface_Primitive (Interface_Alias (Prim)) then
8725 Write_Str ("null primitive ");
8729 (Chars (Find_Dispatching_Type (Interface_Alias (Prim))));
8731 Write_Int (Int (Interface_Alias (Prim)));
8737 -- Display the final position of this primitive in its associated
8738 -- (primary or secondary) dispatch table
8740 if Present (DTC_Entity (Prim))
8741 and then DT_Position (Prim) /= No_Uint
8743 Write_Str (" at #");
8744 Write_Int (UI_To_Int (DT_Position (Prim)));
8747 if Is_Abstract_Subprogram (Prim) then
8748 Write_Str (" is abstract;");
8750 -- Check if this is a null primitive
8752 elsif Comes_From_Source (Prim)
8753 and then Ekind (Prim) = E_Procedure
8754 and then Null_Present (Parent (Prim))
8756 Write_Str (" is null;");
8759 if Is_Eliminated (Ultimate_Alias (Prim)) then
8760 Write_Str (" (eliminated)");
8763 if Is_Imported (Prim)
8764 and then Convention (Prim) = Convention_CPP
8766 Write_Str (" (C++)");