1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2009, 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_Ch7; use Exp_Ch7;
34 with Exp_Dbug; use Exp_Dbug;
35 with Exp_Tss; use Exp_Tss;
36 with Exp_Util; use Exp_Util;
37 with Freeze; use Freeze;
38 with Itypes; use Itypes;
39 with Layout; use Layout;
40 with Nlists; use Nlists;
41 with Nmake; use Nmake;
42 with Namet; use Namet;
44 with Output; use Output;
45 with Restrict; use Restrict;
46 with Rident; use Rident;
47 with Rtsfind; use Rtsfind;
49 with Sem_Aux; use Sem_Aux;
50 with Sem_Ch6; use Sem_Ch6;
51 with Sem_Ch7; use Sem_Ch7;
52 with Sem_Ch8; use Sem_Ch8;
53 with Sem_Disp; use Sem_Disp;
54 with Sem_Eval; use Sem_Eval;
55 with Sem_Res; use Sem_Res;
56 with Sem_Type; use Sem_Type;
57 with Sem_Util; use Sem_Util;
58 with Sinfo; use Sinfo;
59 with Snames; use Snames;
60 with Stand; use Stand;
61 with Stringt; use Stringt;
62 with Tbuild; use Tbuild;
63 with Uintp; use Uintp;
65 package body Exp_Disp is
67 -----------------------
68 -- Local Subprograms --
69 -----------------------
71 function Default_Prim_Op_Position (E : Entity_Id) return Uint;
72 -- Ada 2005 (AI-251): Returns the fixed position in the dispatch table
73 -- of the default primitive operations.
75 function Has_DT (Typ : Entity_Id) return Boolean;
76 pragma Inline (Has_DT);
77 -- Returns true if we generate a dispatch table for tagged type Typ
79 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean;
80 -- Returns true if Prim is not a predefined dispatching primitive but it is
81 -- an alias of a predefined dispatching primitive (i.e. through a renaming)
83 function New_Value (From : Node_Id) return Node_Id;
84 -- From is the original Expression. New_Value is equivalent to a call
85 -- to Duplicate_Subexpr with an explicit dereference when From is an
88 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean;
89 -- Check if the type has a private view or if the public view appears
90 -- in the visible part of a package spec.
94 Typ : Entity_Id) return Node_Id;
95 -- Ada 2005 (AI-345): Determine the primitive operation kind of Prim
96 -- according to its type Typ. Return a reference to an RE_Prim_Op_Kind
99 function Tagged_Kind (T : Entity_Id) return Node_Id;
100 -- Ada 2005 (AI-345): Determine the tagged kind of T and return a reference
101 -- to an RE_Tagged_Kind enumeration value.
103 ----------------------
104 -- Apply_Tag_Checks --
105 ----------------------
107 procedure Apply_Tag_Checks (Call_Node : Node_Id) is
108 Loc : constant Source_Ptr := Sloc (Call_Node);
109 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
110 Ctrl_Typ : constant Entity_Id := Base_Type (Etype (Ctrl_Arg));
111 Param_List : constant List_Id := Parameter_Associations (Call_Node);
117 Eq_Prim_Op : Entity_Id := Empty;
120 if No_Run_Time_Mode then
121 Error_Msg_CRT ("tagged types", Call_Node);
125 -- Apply_Tag_Checks is called directly from the semantics, so we need
126 -- a check to see whether expansion is active before proceeding. In
127 -- addition, there is no need to expand the call when compiling under
128 -- restriction No_Dispatching_Calls; the semantic analyzer has
129 -- previously notified the violation of this restriction.
131 if not Expander_Active
132 or else Restriction_Active (No_Dispatching_Calls)
137 -- Set subprogram. If this is an inherited operation that was
138 -- overridden, the body that is being called is its alias.
140 Subp := Entity (Name (Call_Node));
142 if Present (Alias (Subp))
143 and then Is_Inherited_Operation (Subp)
144 and then No (DTC_Entity (Subp))
146 Subp := Alias (Subp);
149 -- Definition of the class-wide type and the tagged type
151 -- If the controlling argument is itself a tag rather than a tagged
152 -- object, then use the class-wide type associated with the subprogram's
153 -- controlling type. This case can occur when a call to an inherited
154 -- primitive has an actual that originated from a default parameter
155 -- given by a tag-indeterminate call and when there is no other
156 -- controlling argument providing the tag (AI-239 requires dispatching).
157 -- This capability of dispatching directly by tag is also needed by the
158 -- implementation of AI-260 (for the generic dispatching constructors).
160 if Ctrl_Typ = RTE (RE_Tag)
161 or else (RTE_Available (RE_Interface_Tag)
162 and then Ctrl_Typ = RTE (RE_Interface_Tag))
164 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
166 -- Class_Wide_Type is applied to the expressions used to initialize
167 -- CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
168 -- there are cases where the controlling type is resolved to a specific
169 -- type (such as for designated types of arguments such as CW'Access).
171 elsif Is_Access_Type (Ctrl_Typ) then
172 CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));
175 CW_Typ := Class_Wide_Type (Ctrl_Typ);
178 Typ := Root_Type (CW_Typ);
180 if Ekind (Typ) = E_Incomplete_Type then
181 Typ := Non_Limited_View (Typ);
184 if not Is_Limited_Type (Typ) then
185 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
188 -- Dispatching call to C++ primitive
190 if Is_CPP_Class (Typ) then
193 -- Dispatching call to Ada primitive
195 elsif Present (Param_List) then
197 -- Generate the Tag checks when appropriate
199 Param := First_Actual (Call_Node);
200 while Present (Param) loop
202 -- No tag check with itself
204 if Param = Ctrl_Arg then
207 -- No tag check for parameter whose type is neither tagged nor
208 -- access to tagged (for access parameters)
210 elsif No (Find_Controlling_Arg (Param)) then
213 -- No tag check for function dispatching on result if the
214 -- Tag given by the context is this one
216 elsif Find_Controlling_Arg (Param) = Ctrl_Arg then
219 -- "=" is the only dispatching operation allowed to get
220 -- operands with incompatible tags (it just returns false).
221 -- We use Duplicate_Subexpr_Move_Checks instead of calling
222 -- Relocate_Node because the value will be duplicated to
225 elsif Subp = Eq_Prim_Op then
228 -- No check in presence of suppress flags
230 elsif Tag_Checks_Suppressed (Etype (Param))
231 or else (Is_Access_Type (Etype (Param))
232 and then Tag_Checks_Suppressed
233 (Designated_Type (Etype (Param))))
237 -- Optimization: no tag checks if the parameters are identical
239 elsif Is_Entity_Name (Param)
240 and then Is_Entity_Name (Ctrl_Arg)
241 and then Entity (Param) = Entity (Ctrl_Arg)
245 -- Now we need to generate the Tag check
248 -- Generate code for tag equality check
249 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
251 Insert_Action (Ctrl_Arg,
252 Make_Implicit_If_Statement (Call_Node,
256 Make_Selected_Component (Loc,
257 Prefix => New_Value (Ctrl_Arg),
260 (First_Tag_Component (Typ), Loc)),
263 Make_Selected_Component (Loc,
265 Unchecked_Convert_To (Typ, New_Value (Param)),
268 (First_Tag_Component (Typ), Loc))),
271 New_List (New_Constraint_Error (Loc))));
277 end Apply_Tag_Checks;
279 ------------------------
280 -- Building_Static_DT --
281 ------------------------
283 function Building_Static_DT (Typ : Entity_Id) return Boolean is
284 Root_Typ : Entity_Id := Root_Type (Typ);
287 -- Handle private types
289 if Present (Full_View (Root_Typ)) then
290 Root_Typ := Full_View (Root_Typ);
293 return Static_Dispatch_Tables
294 and then Is_Library_Level_Tagged_Type (Typ)
296 -- If the type is derived from a CPP class we cannot statically
297 -- build the dispatch tables because we must inherit primitives
298 -- from the CPP side.
300 and then not Is_CPP_Class (Root_Typ);
301 end Building_Static_DT;
303 ----------------------------------
304 -- Build_Static_Dispatch_Tables --
305 ----------------------------------
307 procedure Build_Static_Dispatch_Tables (N : Entity_Id) is
308 Target_List : List_Id;
310 procedure Build_Dispatch_Tables (List : List_Id);
311 -- Build the static dispatch table of tagged types found in the list of
312 -- declarations. The generated nodes are added at the end of Target_List
314 procedure Build_Package_Dispatch_Tables (N : Node_Id);
315 -- Build static dispatch tables associated with package declaration N
317 ---------------------------
318 -- Build_Dispatch_Tables --
319 ---------------------------
321 procedure Build_Dispatch_Tables (List : List_Id) is
326 while Present (D) loop
328 -- Handle nested packages and package bodies recursively. The
329 -- generated code is placed on the Target_List established for
330 -- the enclosing compilation unit.
332 if Nkind (D) = N_Package_Declaration then
333 Build_Package_Dispatch_Tables (D);
335 elsif Nkind (D) = N_Package_Body then
336 Build_Dispatch_Tables (Declarations (D));
338 elsif Nkind (D) = N_Package_Body_Stub
339 and then Present (Library_Unit (D))
341 Build_Dispatch_Tables
342 (Declarations (Proper_Body (Unit (Library_Unit (D)))));
344 -- Handle full type declarations and derivations of library
345 -- level tagged types
347 elsif Nkind_In (D, N_Full_Type_Declaration,
348 N_Derived_Type_Definition)
349 and then Is_Library_Level_Tagged_Type (Defining_Entity (D))
350 and then Ekind (Defining_Entity (D)) /= E_Record_Subtype
351 and then not Is_Private_Type (Defining_Entity (D))
353 -- We do not generate dispatch tables for the internal types
354 -- created for a type extension with unknown discriminants
355 -- The needed information is shared with the source type,
356 -- See Expand_N_Record_Extension.
358 if Is_Underlying_Record_View (Defining_Entity (D))
360 (not Comes_From_Source (Defining_Entity (D))
362 Has_Unknown_Discriminants (Etype (Defining_Entity (D)))
364 not Comes_From_Source
365 (First_Subtype (Defining_Entity (D))))
369 Insert_List_After_And_Analyze (Last (Target_List),
370 Make_DT (Defining_Entity (D)));
373 -- Handle private types of library level tagged types. We must
374 -- exchange the private and full-view to ensure the correct
375 -- expansion. If the full view is a synchronized type ignore
376 -- the type because the table will be built for the corresponding
377 -- record type, that has its own declaration.
379 elsif (Nkind (D) = N_Private_Type_Declaration
380 or else Nkind (D) = N_Private_Extension_Declaration)
381 and then Present (Full_View (Defining_Entity (D)))
384 E1 : constant Entity_Id := Defining_Entity (D);
385 E2 : constant Entity_Id := Full_View (E1);
388 if Is_Library_Level_Tagged_Type (E2)
389 and then Ekind (E2) /= E_Record_Subtype
390 and then not Is_Concurrent_Type (E2)
392 Exchange_Declarations (E1);
393 Insert_List_After_And_Analyze (Last (Target_List),
395 Exchange_Declarations (E2);
402 end Build_Dispatch_Tables;
404 -----------------------------------
405 -- Build_Package_Dispatch_Tables --
406 -----------------------------------
408 procedure Build_Package_Dispatch_Tables (N : Node_Id) is
409 Spec : constant Node_Id := Specification (N);
410 Id : constant Entity_Id := Defining_Entity (N);
411 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
412 Priv_Decls : constant List_Id := Private_Declarations (Spec);
417 if Present (Priv_Decls) then
418 Build_Dispatch_Tables (Vis_Decls);
419 Build_Dispatch_Tables (Priv_Decls);
421 elsif Present (Vis_Decls) then
422 Build_Dispatch_Tables (Vis_Decls);
426 end Build_Package_Dispatch_Tables;
428 -- Start of processing for Build_Static_Dispatch_Tables
431 if not Expander_Active
432 or else not Tagged_Type_Expansion
437 if Nkind (N) = N_Package_Declaration then
439 Spec : constant Node_Id := Specification (N);
440 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
441 Priv_Decls : constant List_Id := Private_Declarations (Spec);
444 if Present (Priv_Decls)
445 and then Is_Non_Empty_List (Priv_Decls)
447 Target_List := Priv_Decls;
449 elsif not Present (Vis_Decls) then
450 Target_List := New_List;
451 Set_Private_Declarations (Spec, Target_List);
453 Target_List := Vis_Decls;
456 Build_Package_Dispatch_Tables (N);
459 else pragma Assert (Nkind (N) = N_Package_Body);
460 Target_List := Declarations (N);
461 Build_Dispatch_Tables (Target_List);
463 end Build_Static_Dispatch_Tables;
465 ------------------------------
466 -- Default_Prim_Op_Position --
467 ------------------------------
469 function Default_Prim_Op_Position (E : Entity_Id) return Uint is
470 TSS_Name : TSS_Name_Type;
473 Get_Name_String (Chars (E));
476 (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
478 if Chars (E) = Name_uSize then
481 elsif Chars (E) = Name_uAlignment then
484 elsif TSS_Name = TSS_Stream_Read then
487 elsif TSS_Name = TSS_Stream_Write then
490 elsif TSS_Name = TSS_Stream_Input then
493 elsif TSS_Name = TSS_Stream_Output then
496 elsif Chars (E) = Name_Op_Eq then
499 elsif Chars (E) = Name_uAssign then
502 elsif TSS_Name = TSS_Deep_Adjust then
505 elsif TSS_Name = TSS_Deep_Finalize then
508 elsif Ada_Version >= Ada_05 then
509 if Chars (E) = Name_uDisp_Asynchronous_Select then
512 elsif Chars (E) = Name_uDisp_Conditional_Select then
515 elsif Chars (E) = Name_uDisp_Get_Prim_Op_Kind then
518 elsif Chars (E) = Name_uDisp_Get_Task_Id then
521 elsif Chars (E) = Name_uDisp_Requeue then
524 elsif Chars (E) = Name_uDisp_Timed_Select then
530 end Default_Prim_Op_Position;
532 -----------------------------
533 -- Expand_Dispatching_Call --
534 -----------------------------
536 procedure Expand_Dispatching_Call (Call_Node : Node_Id) is
537 Loc : constant Source_Ptr := Sloc (Call_Node);
538 Call_Typ : constant Entity_Id := Etype (Call_Node);
540 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
541 Ctrl_Typ : constant Entity_Id := Base_Type (Etype (Ctrl_Arg));
542 Param_List : constant List_Id := Parameter_Associations (Call_Node);
547 New_Call_Name : Node_Id;
548 New_Params : List_Id := No_List;
551 Subp_Ptr_Typ : Entity_Id;
552 Subp_Typ : Entity_Id;
554 Eq_Prim_Op : Entity_Id := Empty;
555 Controlling_Tag : Node_Id;
557 function New_Value (From : Node_Id) return Node_Id;
558 -- From is the original Expression. New_Value is equivalent to a call
559 -- to Duplicate_Subexpr with an explicit dereference when From is an
566 function New_Value (From : Node_Id) return Node_Id is
567 Res : constant Node_Id := Duplicate_Subexpr (From);
569 if Is_Access_Type (Etype (From)) then
571 Make_Explicit_Dereference (Sloc (From),
583 -- Start of processing for Expand_Dispatching_Call
586 if No_Run_Time_Mode then
587 Error_Msg_CRT ("tagged types", Call_Node);
591 -- Expand_Dispatching_Call is called directly from the semantics,
592 -- so we need a check to see whether expansion is active before
593 -- proceeding. In addition, there is no need to expand the call
594 -- if we are compiling under restriction No_Dispatching_Calls;
595 -- the semantic analyzer has previously notified the violation
596 -- of this restriction.
598 if not Expander_Active
599 or else Restriction_Active (No_Dispatching_Calls)
604 -- Set subprogram. If this is an inherited operation that was
605 -- overridden, the body that is being called is its alias.
607 Subp := Entity (Name (Call_Node));
609 if Present (Alias (Subp))
610 and then Is_Inherited_Operation (Subp)
611 and then No (DTC_Entity (Subp))
613 Subp := Alias (Subp);
616 -- Definition of the class-wide type and the tagged type
618 -- If the controlling argument is itself a tag rather than a tagged
619 -- object, then use the class-wide type associated with the subprogram's
620 -- controlling type. This case can occur when a call to an inherited
621 -- primitive has an actual that originated from a default parameter
622 -- given by a tag-indeterminate call and when there is no other
623 -- controlling argument providing the tag (AI-239 requires dispatching).
624 -- This capability of dispatching directly by tag is also needed by the
625 -- implementation of AI-260 (for the generic dispatching constructors).
627 if Ctrl_Typ = RTE (RE_Tag)
628 or else (RTE_Available (RE_Interface_Tag)
629 and then Ctrl_Typ = RTE (RE_Interface_Tag))
631 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
633 -- Class_Wide_Type is applied to the expressions used to initialize
634 -- CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
635 -- there are cases where the controlling type is resolved to a specific
636 -- type (such as for designated types of arguments such as CW'Access).
638 elsif Is_Access_Type (Ctrl_Typ) then
639 CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));
642 CW_Typ := Class_Wide_Type (Ctrl_Typ);
645 Typ := Root_Type (CW_Typ);
647 if Ekind (Typ) = E_Incomplete_Type then
648 Typ := Non_Limited_View (Typ);
651 -- Generate the SCIL node for this dispatching call. The SCIL node for a
652 -- dispatching call is inserted in the tree before the call is rewriten
653 -- and expanded because the SCIL node must be found by the SCIL backend
654 -- BEFORE the expanded nodes associated with the call node are found.
656 if Generate_SCIL then
657 SCIL_Node := Make_SCIL_Dispatching_Call (Sloc (Call_Node));
658 Set_SCIL_Related_Node (SCIL_Node, Call_Node);
659 Set_SCIL_Entity (SCIL_Node, Typ);
660 Set_SCIL_Target_Prim (SCIL_Node, Subp);
661 Insert_Action (Call_Node, SCIL_Node);
664 if not Is_Limited_Type (Typ) then
665 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
668 -- Dispatching call to C++ primitive. Create a new parameter list
669 -- with no tag checks.
671 New_Params := New_List;
673 if Is_CPP_Class (Typ) then
674 Param := First_Actual (Call_Node);
675 while Present (Param) loop
676 Append_To (New_Params, Relocate_Node (Param));
680 -- Dispatching call to Ada primitive
682 elsif Present (Param_List) then
683 Apply_Tag_Checks (Call_Node);
685 Param := First_Actual (Call_Node);
686 while Present (Param) loop
687 -- Cases in which we may have generated runtime checks
690 or else Subp = Eq_Prim_Op
692 Append_To (New_Params,
693 Duplicate_Subexpr_Move_Checks (Param));
695 elsif Nkind (Parent (Param)) /= N_Parameter_Association
696 or else not Is_Accessibility_Actual (Parent (Param))
698 Append_To (New_Params, Relocate_Node (Param));
705 -- Generate the appropriate subprogram pointer type
707 if Etype (Subp) = Typ then
710 Res_Typ := Etype (Subp);
713 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
714 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
715 Set_Etype (Subp_Typ, Res_Typ);
716 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
718 -- Create a new list of parameters which is a copy of the old formal
719 -- list including the creation of a new set of matching entities.
722 Old_Formal : Entity_Id := First_Formal (Subp);
723 New_Formal : Entity_Id;
724 Extra : Entity_Id := Empty;
727 if Present (Old_Formal) then
728 New_Formal := New_Copy (Old_Formal);
729 Set_First_Entity (Subp_Typ, New_Formal);
730 Param := First_Actual (Call_Node);
733 Set_Scope (New_Formal, Subp_Typ);
735 -- Change all the controlling argument types to be class-wide
736 -- to avoid a recursion in dispatching.
738 if Is_Controlling_Formal (New_Formal) then
739 Set_Etype (New_Formal, Etype (Param));
742 -- If the type of the formal is an itype, there was code here
743 -- introduced in 1998 in revision 1.46, to create a new itype
744 -- by copy. This seems useless, and in fact leads to semantic
745 -- errors when the itype is the completion of a type derived
746 -- from a private type.
749 Next_Formal (Old_Formal);
750 exit when No (Old_Formal);
752 Set_Next_Entity (New_Formal, New_Copy (Old_Formal));
753 Next_Entity (New_Formal);
757 Set_Next_Entity (New_Formal, Empty);
758 Set_Last_Entity (Subp_Typ, Extra);
761 -- Now that the explicit formals have been duplicated, any extra
762 -- formals needed by the subprogram must be created.
764 if Present (Extra) then
765 Set_Extra_Formal (Extra, Empty);
768 Create_Extra_Formals (Subp_Typ);
771 -- Complete description of pointer type, including size information, as
772 -- must be done with itypes to prevent order-of-elaboration anomalies
775 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
776 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
777 Set_Convention (Subp_Ptr_Typ, Convention (Subp_Typ));
778 Layout_Type (Subp_Ptr_Typ);
780 -- If the controlling argument is a value of type Ada.Tag or an abstract
781 -- interface class-wide type then use it directly. Otherwise, the tag
782 -- must be extracted from the controlling object.
784 if Ctrl_Typ = RTE (RE_Tag)
785 or else (RTE_Available (RE_Interface_Tag)
786 and then Ctrl_Typ = RTE (RE_Interface_Tag))
788 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
790 -- Extract the tag from an unchecked type conversion. Done to avoid
791 -- the expansion of additional code just to obtain the value of such
792 -- tag because the current management of interface type conversions
793 -- generates in some cases this unchecked type conversion with the
794 -- tag of the object (see Expand_Interface_Conversion).
796 elsif Nkind (Ctrl_Arg) = N_Unchecked_Type_Conversion
798 (Etype (Expression (Ctrl_Arg)) = RTE (RE_Tag)
800 (RTE_Available (RE_Interface_Tag)
802 Etype (Expression (Ctrl_Arg)) = RTE (RE_Interface_Tag)))
804 Controlling_Tag := Duplicate_Subexpr (Expression (Ctrl_Arg));
806 -- Ada 2005 (AI-251): Abstract interface class-wide type
808 elsif Is_Interface (Ctrl_Typ)
809 and then Is_Class_Wide_Type (Ctrl_Typ)
811 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
815 Make_Selected_Component (Loc,
816 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
817 Selector_Name => New_Reference_To (DTC_Entity (Subp), Loc));
820 -- Handle dispatching calls to predefined primitives
822 if Is_Predefined_Dispatching_Operation (Subp)
823 or else Is_Predefined_Dispatching_Alias (Subp)
825 Build_Get_Predefined_Prim_Op_Address (Loc,
826 Tag_Node => Controlling_Tag,
827 Position => DT_Position (Subp),
828 New_Node => New_Node);
830 -- Handle dispatching calls to user-defined primitives
833 Build_Get_Prim_Op_Address (Loc,
834 Typ => Find_Dispatching_Type (Subp),
835 Tag_Node => Controlling_Tag,
836 Position => DT_Position (Subp),
837 New_Node => New_Node);
841 Unchecked_Convert_To (Subp_Ptr_Typ, New_Node);
843 -- Complete decoration of SCIL dispatching node. It must be done after
844 -- the new call name is built to reference the nodes that will see the
845 -- SCIL backend (because Build_Get_Prim_Op_Address generates an
846 -- unchecked type conversion which relocates the controlling tag node).
848 if Generate_SCIL then
850 -- Common case: the controlling tag is the tag of an object
851 -- (for example, obj.tag)
853 if Nkind (Controlling_Tag) = N_Selected_Component then
854 Set_SCIL_Controlling_Tag (SCIL_Node, Controlling_Tag);
856 -- Handle renaming of selected component
858 elsif Nkind (Controlling_Tag) = N_Identifier
859 and then Nkind (Parent (Entity (Controlling_Tag))) =
860 N_Object_Renaming_Declaration
861 and then Nkind (Name (Parent (Entity (Controlling_Tag)))) =
864 Set_SCIL_Controlling_Tag (SCIL_Node,
865 Name (Parent (Entity (Controlling_Tag))));
867 -- If the controlling tag is an identifier, the SCIL node references
868 -- the corresponding object or parameter declaration
870 elsif Nkind (Controlling_Tag) = N_Identifier
871 and then Nkind_In (Parent (Entity (Controlling_Tag)),
872 N_Object_Declaration,
873 N_Parameter_Specification)
875 Set_SCIL_Controlling_Tag (SCIL_Node,
876 Parent (Entity (Controlling_Tag)));
878 -- If the controlling tag is a dereference, the SCIL node references
879 -- the corresponding object or parameter declaration
881 elsif Nkind (Controlling_Tag) = N_Explicit_Dereference
882 and then Nkind (Prefix (Controlling_Tag)) = N_Identifier
883 and then Nkind_In (Parent (Entity (Prefix (Controlling_Tag))),
884 N_Object_Declaration,
885 N_Parameter_Specification)
887 Set_SCIL_Controlling_Tag (SCIL_Node,
888 Parent (Entity (Prefix (Controlling_Tag))));
890 -- For a direct reference of the tag of the type the SCIL node
891 -- references the the internal object declaration containing the tag
894 elsif Nkind (Controlling_Tag) = N_Attribute_Reference
895 and then Attribute_Name (Controlling_Tag) = Name_Tag
897 Set_SCIL_Controlling_Tag (SCIL_Node,
901 (Access_Disp_Table (Entity (Prefix (Controlling_Tag)))))));
903 -- Interfaces are not supported. For now we leave the SCIL node
904 -- decorated with the Controlling_Tag. More work needed here???
906 elsif Is_Interface (Etype (Controlling_Tag)) then
907 Set_SCIL_Controlling_Tag (SCIL_Node, Controlling_Tag);
910 pragma Assert (False);
915 if Nkind (Call_Node) = N_Function_Call then
917 Make_Function_Call (Loc,
918 Name => New_Call_Name,
919 Parameter_Associations => New_Params);
921 -- If this is a dispatching "=", we must first compare the tags so
922 -- we generate: x.tag = y.tag and then x = y
924 if Subp = Eq_Prim_Op then
925 Param := First_Actual (Call_Node);
931 Make_Selected_Component (Loc,
932 Prefix => New_Value (Param),
934 New_Reference_To (First_Tag_Component (Typ),
938 Make_Selected_Component (Loc,
940 Unchecked_Convert_To (Typ,
941 New_Value (Next_Actual (Param))),
944 (First_Tag_Component (Typ), Loc))),
945 Right_Opnd => New_Call);
950 Make_Procedure_Call_Statement (Loc,
951 Name => New_Call_Name,
952 Parameter_Associations => New_Params);
955 Rewrite (Call_Node, New_Call);
957 -- Suppress all checks during the analysis of the expanded code
958 -- to avoid the generation of spurious warnings under ZFP run-time.
960 Analyze_And_Resolve (Call_Node, Call_Typ, Suppress => All_Checks);
961 end Expand_Dispatching_Call;
963 ---------------------------------
964 -- Expand_Interface_Conversion --
965 ---------------------------------
967 procedure Expand_Interface_Conversion
969 Is_Static : Boolean := True)
971 Loc : constant Source_Ptr := Sloc (N);
972 Etyp : constant Entity_Id := Etype (N);
973 Operand : constant Node_Id := Expression (N);
974 Operand_Typ : Entity_Id := Etype (Operand);
976 Iface_Typ : Entity_Id := Etype (N);
977 Iface_Tag : Entity_Id;
980 -- Ada 2005 (AI-345): Handle synchronized interface type derivations
982 if Is_Concurrent_Type (Operand_Typ) then
983 Operand_Typ := Base_Type (Corresponding_Record_Type (Operand_Typ));
986 -- Handle access to class-wide interface types
988 if Is_Access_Type (Iface_Typ) then
989 Iface_Typ := Etype (Directly_Designated_Type (Iface_Typ));
992 -- Handle class-wide interface types. This conversion can appear
993 -- explicitly in the source code. Example: I'Class (Obj)
995 if Is_Class_Wide_Type (Iface_Typ) then
996 Iface_Typ := Root_Type (Iface_Typ);
999 -- If the target type is a tagged synchronized type, the dispatch table
1000 -- info is in the corresponding record type.
1002 if Is_Concurrent_Type (Iface_Typ) then
1003 Iface_Typ := Corresponding_Record_Type (Iface_Typ);
1006 -- Freeze the entity associated with the target interface to have
1007 -- available the attribute Access_Disp_Table.
1009 Freeze_Before (N, Iface_Typ);
1011 pragma Assert (not Is_Static
1012 or else (not Is_Class_Wide_Type (Iface_Typ)
1013 and then Is_Interface (Iface_Typ)));
1015 if not Tagged_Type_Expansion then
1017 -- For VM, just do a conversion ???
1019 Rewrite (N, Unchecked_Convert_To (Etype (N), N));
1024 if not Is_Static then
1026 -- Give error if configurable run time and Displace not available
1028 if not RTE_Available (RE_Displace) then
1029 Error_Msg_CRT ("dynamic interface conversion", N);
1033 -- Handle conversion of access-to-class-wide interface types. Target
1034 -- can be an access to an object or an access to another class-wide
1035 -- interface (see -1- and -2- in the following example):
1037 -- type Iface1_Ref is access all Iface1'Class;
1038 -- type Iface2_Ref is access all Iface1'Class;
1040 -- Acc1 : Iface1_Ref := new ...
1041 -- Obj : Obj_Ref := Obj_Ref (Acc); -- 1
1042 -- Acc2 : Iface2_Ref := Iface2_Ref (Acc); -- 2
1044 if Is_Access_Type (Operand_Typ) then
1046 Unchecked_Convert_To (Etype (N),
1047 Make_Function_Call (Loc,
1048 Name => New_Reference_To (RTE (RE_Displace), Loc),
1049 Parameter_Associations => New_List (
1051 Unchecked_Convert_To (RTE (RE_Address),
1052 Relocate_Node (Expression (N))),
1055 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
1063 Make_Function_Call (Loc,
1064 Name => New_Reference_To (RTE (RE_Displace), Loc),
1065 Parameter_Associations => New_List (
1066 Make_Attribute_Reference (Loc,
1067 Prefix => Relocate_Node (Expression (N)),
1068 Attribute_Name => Name_Address),
1071 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
1076 -- If the target is a class-wide interface we change the type of the
1077 -- data returned by IW_Convert to indicate that this is a dispatching
1081 New_Itype : Entity_Id;
1084 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
1085 Set_Etype (New_Itype, New_Itype);
1086 Set_Directly_Designated_Type (New_Itype, Etyp);
1089 Make_Explicit_Dereference (Loc,
1091 Unchecked_Convert_To (New_Itype, Relocate_Node (N))));
1093 Freeze_Itype (New_Itype, N);
1099 Iface_Tag := Find_Interface_Tag (Operand_Typ, Iface_Typ);
1100 pragma Assert (Iface_Tag /= Empty);
1102 -- Keep separate access types to interfaces because one internal
1103 -- function is used to handle the null value (see following comment)
1105 if not Is_Access_Type (Etype (N)) then
1107 Unchecked_Convert_To (Etype (N),
1108 Make_Selected_Component (Loc,
1109 Prefix => Relocate_Node (Expression (N)),
1111 New_Occurrence_Of (Iface_Tag, Loc))));
1114 -- Build internal function to handle the case in which the
1115 -- actual is null. If the actual is null returns null because
1116 -- no displacement is required; otherwise performs a type
1117 -- conversion that will be expanded in the code that returns
1118 -- the value of the displaced actual. That is:
1120 -- function Func (O : Address) return Iface_Typ is
1121 -- type Op_Typ is access all Operand_Typ;
1122 -- Aux : Op_Typ := To_Op_Typ (O);
1124 -- if O = Null_Address then
1127 -- return Iface_Typ!(Aux.Iface_Tag'Address);
1132 Desig_Typ : Entity_Id;
1134 New_Typ_Decl : Node_Id;
1138 Desig_Typ := Etype (Expression (N));
1140 if Is_Access_Type (Desig_Typ) then
1142 Available_View (Directly_Designated_Type (Desig_Typ));
1145 if Is_Concurrent_Type (Desig_Typ) then
1146 Desig_Typ := Base_Type (Corresponding_Record_Type (Desig_Typ));
1150 Make_Full_Type_Declaration (Loc,
1151 Defining_Identifier =>
1152 Make_Defining_Identifier (Loc, New_Internal_Name ('T')),
1154 Make_Access_To_Object_Definition (Loc,
1155 All_Present => True,
1156 Null_Exclusion_Present => False,
1157 Constant_Present => False,
1158 Subtype_Indication =>
1159 New_Reference_To (Desig_Typ, Loc)));
1162 Make_Simple_Return_Statement (Loc,
1163 Unchecked_Convert_To (Etype (N),
1164 Make_Attribute_Reference (Loc,
1166 Make_Selected_Component (Loc,
1168 Unchecked_Convert_To
1169 (Defining_Identifier (New_Typ_Decl),
1170 Make_Identifier (Loc, Name_uO)),
1172 New_Occurrence_Of (Iface_Tag, Loc)),
1173 Attribute_Name => Name_Address))));
1175 -- If the type is null-excluding, no need for the null branch.
1176 -- Otherwise we need to check for it and return null.
1178 if not Can_Never_Be_Null (Etype (N)) then
1180 Make_If_Statement (Loc,
1183 Left_Opnd => Make_Identifier (Loc, Name_uO),
1184 Right_Opnd => New_Reference_To
1185 (RTE (RE_Null_Address), Loc)),
1187 Then_Statements => New_List (
1188 Make_Simple_Return_Statement (Loc,
1190 Else_Statements => Stats));
1194 Make_Defining_Identifier (Loc,
1195 New_Internal_Name ('F'));
1198 Make_Subprogram_Body (Loc,
1200 Make_Function_Specification (Loc,
1201 Defining_Unit_Name => Fent,
1203 Parameter_Specifications => New_List (
1204 Make_Parameter_Specification (Loc,
1205 Defining_Identifier =>
1206 Make_Defining_Identifier (Loc, Name_uO),
1208 New_Reference_To (RTE (RE_Address), Loc))),
1210 Result_Definition =>
1211 New_Reference_To (Etype (N), Loc)),
1213 Declarations => New_List (New_Typ_Decl),
1215 Handled_Statement_Sequence =>
1216 Make_Handled_Sequence_Of_Statements (Loc, Stats));
1218 -- Place function body before the expression containing the
1219 -- conversion. We suppress all checks because the body of the
1220 -- internally generated function already takes care of the case
1221 -- in which the actual is null; therefore there is no need to
1222 -- double check that the pointer is not null when the program
1223 -- executes the alternative that performs the type conversion).
1225 Insert_Action (N, Func, Suppress => All_Checks);
1227 if Is_Access_Type (Etype (Expression (N))) then
1229 -- Generate: Func (Address!(Expression))
1232 Make_Function_Call (Loc,
1233 Name => New_Reference_To (Fent, Loc),
1234 Parameter_Associations => New_List (
1235 Unchecked_Convert_To (RTE (RE_Address),
1236 Relocate_Node (Expression (N))))));
1239 -- Generate: Func (Operand_Typ!(Expression)'Address)
1242 Make_Function_Call (Loc,
1243 Name => New_Reference_To (Fent, Loc),
1244 Parameter_Associations => New_List (
1245 Make_Attribute_Reference (Loc,
1246 Prefix => Unchecked_Convert_To (Operand_Typ,
1247 Relocate_Node (Expression (N))),
1248 Attribute_Name => Name_Address))));
1254 end Expand_Interface_Conversion;
1256 ------------------------------
1257 -- Expand_Interface_Actuals --
1258 ------------------------------
1260 procedure Expand_Interface_Actuals (Call_Node : Node_Id) is
1262 Actual_Dup : Node_Id;
1263 Actual_Typ : Entity_Id;
1265 Conversion : Node_Id;
1267 Formal_Typ : Entity_Id;
1269 Formal_DDT : Entity_Id;
1270 Actual_DDT : Entity_Id;
1273 -- This subprogram is called directly from the semantics, so we need a
1274 -- check to see whether expansion is active before proceeding.
1276 if not Expander_Active then
1280 -- Call using access to subprogram with explicit dereference
1282 if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
1283 Subp := Etype (Name (Call_Node));
1285 -- Call using selected component
1287 elsif Nkind (Name (Call_Node)) = N_Selected_Component then
1288 Subp := Entity (Selector_Name (Name (Call_Node)));
1290 -- Call using direct name
1293 Subp := Entity (Name (Call_Node));
1296 -- Ada 2005 (AI-251): Look for interface type formals to force "this"
1299 Formal := First_Formal (Subp);
1300 Actual := First_Actual (Call_Node);
1301 while Present (Formal) loop
1302 Formal_Typ := Etype (Formal);
1304 if Ekind (Formal_Typ) = E_Record_Type_With_Private then
1305 Formal_Typ := Full_View (Formal_Typ);
1308 if Is_Access_Type (Formal_Typ) then
1309 Formal_DDT := Directly_Designated_Type (Formal_Typ);
1312 Actual_Typ := Etype (Actual);
1314 if Is_Access_Type (Actual_Typ) then
1315 Actual_DDT := Directly_Designated_Type (Actual_Typ);
1318 if Is_Interface (Formal_Typ)
1319 and then Is_Class_Wide_Type (Formal_Typ)
1321 -- No need to displace the pointer if the type of the actual
1322 -- coindices with the type of the formal.
1324 if Actual_Typ = Formal_Typ then
1327 -- No need to displace the pointer if the interface type is
1328 -- a parent of the type of the actual because in this case the
1329 -- interface primitives are located in the primary dispatch table.
1331 elsif Is_Ancestor (Formal_Typ, Actual_Typ) then
1334 -- Implicit conversion to the class-wide formal type to force
1335 -- the displacement of the pointer.
1338 Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
1339 Rewrite (Actual, Conversion);
1340 Analyze_And_Resolve (Actual, Formal_Typ);
1343 -- Access to class-wide interface type
1345 elsif Is_Access_Type (Formal_Typ)
1346 and then Is_Interface (Formal_DDT)
1347 and then Is_Class_Wide_Type (Formal_DDT)
1348 and then Interface_Present_In_Ancestor
1350 Iface => Etype (Formal_DDT))
1352 -- Handle attributes 'Access and 'Unchecked_Access
1354 if Nkind (Actual) = N_Attribute_Reference
1356 (Attribute_Name (Actual) = Name_Access
1357 or else Attribute_Name (Actual) = Name_Unchecked_Access)
1359 -- This case must have been handled by the analysis and
1360 -- expansion of 'Access. The only exception is when types
1361 -- match and no further expansion is required.
1363 pragma Assert (Base_Type (Etype (Prefix (Actual)))
1364 = Base_Type (Formal_DDT));
1367 -- No need to displace the pointer if the type of the actual
1368 -- coincides with the type of the formal.
1370 elsif Actual_DDT = Formal_DDT then
1373 -- No need to displace the pointer if the interface type is
1374 -- a parent of the type of the actual because in this case the
1375 -- interface primitives are located in the primary dispatch table.
1377 elsif Is_Ancestor (Formal_DDT, Actual_DDT) then
1381 Actual_Dup := Relocate_Node (Actual);
1383 if From_With_Type (Actual_Typ) then
1385 -- If the type of the actual parameter comes from a limited
1386 -- with-clause and the non-limited view is already available
1387 -- we replace the anonymous access type by a duplicate
1388 -- declaration whose designated type is the non-limited view
1390 if Ekind (Actual_DDT) = E_Incomplete_Type
1391 and then Present (Non_Limited_View (Actual_DDT))
1393 Anon := New_Copy (Actual_Typ);
1395 if Is_Itype (Anon) then
1396 Set_Scope (Anon, Current_Scope);
1399 Set_Directly_Designated_Type (Anon,
1400 Non_Limited_View (Actual_DDT));
1401 Set_Etype (Actual_Dup, Anon);
1403 elsif Is_Class_Wide_Type (Actual_DDT)
1404 and then Ekind (Etype (Actual_DDT)) = E_Incomplete_Type
1405 and then Present (Non_Limited_View (Etype (Actual_DDT)))
1407 Anon := New_Copy (Actual_Typ);
1409 if Is_Itype (Anon) then
1410 Set_Scope (Anon, Current_Scope);
1413 Set_Directly_Designated_Type (Anon,
1414 New_Copy (Actual_DDT));
1415 Set_Class_Wide_Type (Directly_Designated_Type (Anon),
1416 New_Copy (Class_Wide_Type (Actual_DDT)));
1417 Set_Etype (Directly_Designated_Type (Anon),
1418 Non_Limited_View (Etype (Actual_DDT)));
1420 Class_Wide_Type (Directly_Designated_Type (Anon)),
1421 Non_Limited_View (Etype (Actual_DDT)));
1422 Set_Etype (Actual_Dup, Anon);
1426 Conversion := Convert_To (Formal_Typ, Actual_Dup);
1427 Rewrite (Actual, Conversion);
1428 Analyze_And_Resolve (Actual, Formal_Typ);
1432 Next_Actual (Actual);
1433 Next_Formal (Formal);
1435 end Expand_Interface_Actuals;
1437 ----------------------------
1438 -- Expand_Interface_Thunk --
1439 ----------------------------
1441 procedure Expand_Interface_Thunk
1443 Thunk_Id : out Entity_Id;
1444 Thunk_Code : out Node_Id)
1446 Loc : constant Source_Ptr := Sloc (Prim);
1447 Actuals : constant List_Id := New_List;
1448 Decl : constant List_Id := New_List;
1449 Formals : constant List_Id := New_List;
1451 Controlling_Typ : Entity_Id;
1456 Offset_To_Top : Node_Id;
1458 Target_Formal : Entity_Id;
1462 Thunk_Code := Empty;
1464 -- Traverse the list of alias to find the final target
1467 while Present (Alias (Target)) loop
1468 Target := Alias (Target);
1471 -- In case of primitives that are functions without formals and
1472 -- a controlling result there is no need to build the thunk.
1474 if not Present (First_Formal (Target)) then
1475 pragma Assert (Ekind (Target) = E_Function
1476 and then Has_Controlling_Result (Target));
1480 -- Duplicate the formals
1482 Formal := First_Formal (Target);
1483 while Present (Formal) loop
1485 Make_Parameter_Specification (Loc,
1486 Defining_Identifier =>
1487 Make_Defining_Identifier (Sloc (Formal),
1488 Chars => Chars (Formal)),
1489 In_Present => In_Present (Parent (Formal)),
1490 Out_Present => Out_Present (Parent (Formal)),
1492 New_Reference_To (Etype (Formal), Loc),
1493 Expression => New_Copy_Tree (Expression (Parent (Formal)))));
1495 Next_Formal (Formal);
1498 Controlling_Typ := Find_Dispatching_Type (Target);
1500 Target_Formal := First_Formal (Target);
1501 Formal := First (Formals);
1502 while Present (Formal) loop
1503 if Ekind (Target_Formal) = E_In_Parameter
1504 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
1505 and then Directly_Designated_Type (Etype (Target_Formal))
1510 -- type T is access all <<type of the target formal>>
1511 -- S : Storage_Offset := Storage_Offset!(Formal)
1512 -- - Offset_To_Top (address!(Formal))
1515 Make_Full_Type_Declaration (Loc,
1516 Defining_Identifier =>
1517 Make_Defining_Identifier (Loc,
1518 New_Internal_Name ('T')),
1520 Make_Access_To_Object_Definition (Loc,
1521 All_Present => True,
1522 Null_Exclusion_Present => False,
1523 Constant_Present => False,
1524 Subtype_Indication =>
1526 (Directly_Designated_Type
1527 (Etype (Target_Formal)), Loc)));
1530 Unchecked_Convert_To (RTE (RE_Address),
1531 New_Reference_To (Defining_Identifier (Formal), Loc));
1533 if not RTE_Available (RE_Offset_To_Top) then
1535 Build_Offset_To_Top (Loc, New_Arg);
1538 Make_Function_Call (Loc,
1539 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1540 Parameter_Associations => New_List (New_Arg));
1544 Make_Object_Declaration (Loc,
1545 Defining_Identifier =>
1546 Make_Defining_Identifier (Loc,
1547 New_Internal_Name ('S')),
1548 Constant_Present => True,
1549 Object_Definition =>
1550 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1552 Make_Op_Subtract (Loc,
1554 Unchecked_Convert_To
1555 (RTE (RE_Storage_Offset),
1556 New_Reference_To (Defining_Identifier (Formal), Loc)),
1560 Append_To (Decl, Decl_2);
1561 Append_To (Decl, Decl_1);
1563 -- Reference the new actual. Generate:
1567 Unchecked_Convert_To
1568 (Defining_Identifier (Decl_2),
1569 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1571 elsif Etype (Target_Formal) = Controlling_Typ then
1574 -- S1 : Storage_Offset := Storage_Offset!(Formal'Address)
1575 -- - Offset_To_Top (Formal'Address)
1576 -- S2 : Addr_Ptr := Addr_Ptr!(S1)
1579 Make_Attribute_Reference (Loc,
1581 New_Reference_To (Defining_Identifier (Formal), Loc),
1585 if not RTE_Available (RE_Offset_To_Top) then
1587 Build_Offset_To_Top (Loc, New_Arg);
1590 Make_Function_Call (Loc,
1591 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1592 Parameter_Associations => New_List (New_Arg));
1596 Make_Object_Declaration (Loc,
1597 Defining_Identifier =>
1598 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1599 Constant_Present => True,
1600 Object_Definition =>
1601 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1603 Make_Op_Subtract (Loc,
1605 Unchecked_Convert_To
1606 (RTE (RE_Storage_Offset),
1607 Make_Attribute_Reference (Loc,
1610 (Defining_Identifier (Formal), Loc),
1611 Attribute_Name => Name_Address)),
1616 Make_Object_Declaration (Loc,
1617 Defining_Identifier =>
1618 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1619 Constant_Present => True,
1620 Object_Definition => New_Reference_To (RTE (RE_Addr_Ptr), Loc),
1622 Unchecked_Convert_To
1624 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1626 Append_To (Decl, Decl_1);
1627 Append_To (Decl, Decl_2);
1629 -- Reference the new actual. Generate:
1630 -- Target_Formal (S2.all)
1633 Unchecked_Convert_To
1634 (Etype (Target_Formal),
1635 Make_Explicit_Dereference (Loc,
1636 New_Reference_To (Defining_Identifier (Decl_2), Loc))));
1638 -- No special management required for this actual
1642 New_Reference_To (Defining_Identifier (Formal), Loc));
1645 Next_Formal (Target_Formal);
1650 Make_Defining_Identifier (Loc,
1651 Chars => New_Internal_Name ('T'));
1653 Set_Is_Thunk (Thunk_Id);
1655 if Ekind (Target) = E_Procedure then
1657 Make_Subprogram_Body (Loc,
1659 Make_Procedure_Specification (Loc,
1660 Defining_Unit_Name => Thunk_Id,
1661 Parameter_Specifications => Formals),
1662 Declarations => Decl,
1663 Handled_Statement_Sequence =>
1664 Make_Handled_Sequence_Of_Statements (Loc,
1665 Statements => New_List (
1666 Make_Procedure_Call_Statement (Loc,
1667 Name => New_Occurrence_Of (Target, Loc),
1668 Parameter_Associations => Actuals))));
1670 else pragma Assert (Ekind (Target) = E_Function);
1673 Make_Subprogram_Body (Loc,
1675 Make_Function_Specification (Loc,
1676 Defining_Unit_Name => Thunk_Id,
1677 Parameter_Specifications => Formals,
1678 Result_Definition =>
1679 New_Copy (Result_Definition (Parent (Target)))),
1680 Declarations => Decl,
1681 Handled_Statement_Sequence =>
1682 Make_Handled_Sequence_Of_Statements (Loc,
1683 Statements => New_List (
1684 Make_Simple_Return_Statement (Loc,
1685 Make_Function_Call (Loc,
1686 Name => New_Occurrence_Of (Target, Loc),
1687 Parameter_Associations => Actuals)))));
1689 end Expand_Interface_Thunk;
1695 function Has_DT (Typ : Entity_Id) return Boolean is
1697 return not Is_Interface (Typ)
1698 and then not Restriction_Active (No_Dispatching_Calls);
1701 -----------------------------------------
1702 -- Is_Predefined_Dispatching_Operation --
1703 -----------------------------------------
1705 function Is_Predefined_Dispatching_Operation
1706 (E : Entity_Id) return Boolean
1708 TSS_Name : TSS_Name_Type;
1711 if not Is_Dispatching_Operation (E) then
1715 Get_Name_String (Chars (E));
1717 -- Most predefined primitives have internally generated names. Equality
1718 -- must be treated differently; the predefined operation is recognized
1719 -- as a homogeneous binary operator that returns Boolean.
1721 if Name_Len > TSS_Name_Type'Last then
1722 TSS_Name := TSS_Name_Type (Name_Buffer (Name_Len - TSS_Name'Length + 1
1724 if Chars (E) = Name_uSize
1725 or else Chars (E) = Name_uAlignment
1726 or else TSS_Name = TSS_Stream_Read
1727 or else TSS_Name = TSS_Stream_Write
1728 or else TSS_Name = TSS_Stream_Input
1729 or else TSS_Name = TSS_Stream_Output
1731 (Chars (E) = Name_Op_Eq
1732 and then Etype (First_Entity (E)) = Etype (Last_Entity (E)))
1733 or else Chars (E) = Name_uAssign
1734 or else TSS_Name = TSS_Deep_Adjust
1735 or else TSS_Name = TSS_Deep_Finalize
1736 or else Is_Predefined_Interface_Primitive (E)
1743 end Is_Predefined_Dispatching_Operation;
1745 ---------------------------------------
1746 -- Is_Predefined_Internal_Operation --
1747 ---------------------------------------
1749 function Is_Predefined_Internal_Operation
1750 (E : Entity_Id) return Boolean
1752 TSS_Name : TSS_Name_Type;
1755 if not Is_Dispatching_Operation (E) then
1759 Get_Name_String (Chars (E));
1761 -- Most predefined primitives have internally generated names. Equality
1762 -- must be treated differently; the predefined operation is recognized
1763 -- as a homogeneous binary operator that returns Boolean.
1765 if Name_Len > TSS_Name_Type'Last then
1768 (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
1770 if Chars (E) = Name_uSize
1771 or else Chars (E) = Name_uAlignment
1773 (Chars (E) = Name_Op_Eq
1774 and then Etype (First_Entity (E)) = Etype (Last_Entity (E)))
1775 or else Chars (E) = Name_uAssign
1776 or else TSS_Name = TSS_Deep_Adjust
1777 or else TSS_Name = TSS_Deep_Finalize
1778 or else Is_Predefined_Interface_Primitive (E)
1785 end Is_Predefined_Internal_Operation;
1787 -------------------------------------
1788 -- Is_Predefined_Dispatching_Alias --
1789 -------------------------------------
1791 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
1796 if not Is_Predefined_Dispatching_Operation (Prim)
1797 and then Present (Alias (Prim))
1800 while Present (Alias (E)) loop
1804 if Is_Predefined_Dispatching_Operation (E) then
1810 end Is_Predefined_Dispatching_Alias;
1812 ---------------------------------------
1813 -- Is_Predefined_Interface_Primitive --
1814 ---------------------------------------
1816 function Is_Predefined_Interface_Primitive (E : Entity_Id) return Boolean is
1818 return Ada_Version >= Ada_05
1819 and then (Chars (E) = Name_uDisp_Asynchronous_Select or else
1820 Chars (E) = Name_uDisp_Conditional_Select or else
1821 Chars (E) = Name_uDisp_Get_Prim_Op_Kind or else
1822 Chars (E) = Name_uDisp_Get_Task_Id or else
1823 Chars (E) = Name_uDisp_Requeue or else
1824 Chars (E) = Name_uDisp_Timed_Select);
1825 end Is_Predefined_Interface_Primitive;
1827 ----------------------------------------
1828 -- Make_Disp_Asynchronous_Select_Body --
1829 ----------------------------------------
1831 -- For interface types, generate:
1833 -- procedure _Disp_Asynchronous_Select
1834 -- (T : in out <Typ>;
1836 -- P : System.Address;
1837 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1842 -- end _Disp_Asynchronous_Select;
1844 -- For protected types, generate:
1846 -- procedure _Disp_Asynchronous_Select
1847 -- (T : in out <Typ>;
1849 -- P : System.Address;
1850 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1854 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1855 -- Bnn : System.Tasking.Protected_Objects.Operations.
1856 -- Communication_Block;
1858 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
1859 -- (T._object'Access,
1860 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
1862 -- System.Tasking.Asynchronous_Call,
1864 -- B := System.Storage_Elements.Dummy_Communication_Block (Bnn);
1865 -- end _Disp_Asynchronous_Select;
1867 -- For task types, generate:
1869 -- procedure _Disp_Asynchronous_Select
1870 -- (T : in out <Typ>;
1872 -- P : System.Address;
1873 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1877 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1879 -- System.Tasking.Rendezvous.Task_Entry_Call
1881 -- System.Tasking.Task_Entry_Index (I),
1883 -- System.Tasking.Asynchronous_Call,
1885 -- end _Disp_Asynchronous_Select;
1887 function Make_Disp_Asynchronous_Select_Body
1888 (Typ : Entity_Id) return Node_Id
1890 Com_Block : Entity_Id;
1891 Conc_Typ : Entity_Id := Empty;
1892 Decls : constant List_Id := New_List;
1894 Loc : constant Source_Ptr := Sloc (Typ);
1896 Stmts : constant List_Id := New_List;
1899 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1901 -- Null body is generated for interface types
1903 if Is_Interface (Typ) then
1905 Make_Subprogram_Body (Loc,
1907 Make_Disp_Asynchronous_Select_Spec (Typ),
1910 Handled_Statement_Sequence =>
1911 Make_Handled_Sequence_Of_Statements (Loc,
1912 New_List (Make_Null_Statement (Loc))));
1915 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1917 if Is_Concurrent_Record_Type (Typ) then
1918 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1922 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
1924 -- where I will be used to capture the entry index of the primitive
1925 -- wrapper at position S.
1928 Make_Object_Declaration (Loc,
1929 Defining_Identifier =>
1930 Make_Defining_Identifier (Loc, Name_uI),
1931 Object_Definition =>
1932 New_Reference_To (Standard_Integer, Loc),
1934 Make_Function_Call (Loc,
1936 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
1937 Parameter_Associations =>
1939 Unchecked_Convert_To (RTE (RE_Tag),
1940 New_Reference_To (DT_Ptr, Loc)),
1941 Make_Identifier (Loc, Name_uS)))));
1943 if Ekind (Conc_Typ) = E_Protected_Type then
1946 -- Bnn : Communication_Block;
1949 Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1952 Make_Object_Declaration (Loc,
1953 Defining_Identifier =>
1955 Object_Definition =>
1956 New_Reference_To (RTE (RE_Communication_Block), Loc)));
1958 -- Build T._object'Access for calls below
1961 Make_Attribute_Reference (Loc,
1962 Attribute_Name => Name_Unchecked_Access,
1964 Make_Selected_Component (Loc,
1965 Prefix => Make_Identifier (Loc, Name_uT),
1966 Selector_Name => Make_Identifier (Loc, Name_uObject)));
1968 case Corresponding_Runtime_Package (Conc_Typ) is
1969 when System_Tasking_Protected_Objects_Entries =>
1972 -- Protected_Entry_Call
1973 -- (T._object'Access, -- Object
1974 -- Protected_Entry_Index! (I), -- E
1975 -- P, -- Uninterpreted_Data
1976 -- Asynchronous_Call, -- Mode
1977 -- Bnn); -- Communication_Block
1979 -- where T is the protected object, I is the entry index, P
1980 -- is the wrapped parameters and B is the name of the
1981 -- communication block.
1984 Make_Procedure_Call_Statement (Loc,
1986 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1987 Parameter_Associations =>
1991 Make_Unchecked_Type_Conversion (Loc, -- entry index
1994 (RTE (RE_Protected_Entry_Index), Loc),
1995 Expression => Make_Identifier (Loc, Name_uI)),
1997 Make_Identifier (Loc, Name_uP), -- parameter block
1998 New_Reference_To ( -- Asynchronous_Call
1999 RTE (RE_Asynchronous_Call), Loc),
2001 New_Reference_To (Com_Block, Loc)))); -- comm block
2003 when System_Tasking_Protected_Objects_Single_Entry =>
2006 -- procedure Protected_Single_Entry_Call
2007 -- (Object : Protection_Entry_Access;
2008 -- Uninterpreted_Data : System.Address;
2009 -- Mode : Call_Modes);
2012 Make_Procedure_Call_Statement (Loc,
2015 (RTE (RE_Protected_Single_Entry_Call), Loc),
2016 Parameter_Associations =>
2020 Make_Attribute_Reference (Loc,
2021 Prefix => Make_Identifier (Loc, Name_uP),
2022 Attribute_Name => Name_Address),
2025 (RTE (RE_Asynchronous_Call), Loc))));
2028 raise Program_Error;
2032 -- B := Dummy_Communication_Block (Bnn);
2035 Make_Assignment_Statement (Loc,
2037 Make_Identifier (Loc, Name_uB),
2039 Make_Unchecked_Type_Conversion (Loc,
2042 RTE (RE_Dummy_Communication_Block), Loc),
2044 New_Reference_To (Com_Block, Loc))));
2047 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2051 -- (T._task_id, -- Acceptor
2052 -- Task_Entry_Index! (I), -- E
2053 -- P, -- Uninterpreted_Data
2054 -- Asynchronous_Call, -- Mode
2055 -- F); -- Rendezvous_Successful
2057 -- where T is the task object, I is the entry index, P is the
2058 -- wrapped parameters and F is the status flag.
2061 Make_Procedure_Call_Statement (Loc,
2063 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
2064 Parameter_Associations =>
2066 Make_Selected_Component (Loc, -- T._task_id
2068 Make_Identifier (Loc, Name_uT),
2070 Make_Identifier (Loc, Name_uTask_Id)),
2072 Make_Unchecked_Type_Conversion (Loc, -- entry index
2074 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2076 Make_Identifier (Loc, Name_uI)),
2078 Make_Identifier (Loc, Name_uP), -- parameter block
2079 New_Reference_To ( -- Asynchronous_Call
2080 RTE (RE_Asynchronous_Call), Loc),
2081 Make_Identifier (Loc, Name_uF)))); -- status flag
2085 -- Ensure that the statements list is non-empty
2087 Append_To (Stmts, Make_Null_Statement (Loc));
2091 Make_Subprogram_Body (Loc,
2093 Make_Disp_Asynchronous_Select_Spec (Typ),
2096 Handled_Statement_Sequence =>
2097 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2098 end Make_Disp_Asynchronous_Select_Body;
2100 ----------------------------------------
2101 -- Make_Disp_Asynchronous_Select_Spec --
2102 ----------------------------------------
2104 function Make_Disp_Asynchronous_Select_Spec
2105 (Typ : Entity_Id) return Node_Id
2107 Loc : constant Source_Ptr := Sloc (Typ);
2108 Def_Id : constant Node_Id :=
2109 Make_Defining_Identifier (Loc,
2110 Name_uDisp_Asynchronous_Select);
2111 Params : constant List_Id := New_List;
2114 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2116 -- T : in out Typ; -- Object parameter
2117 -- S : Integer; -- Primitive operation slot
2118 -- P : Address; -- Wrapped parameters
2119 -- B : out Dummy_Communication_Block; -- Communication block dummy
2120 -- F : out Boolean; -- Status flag
2122 Append_List_To (Params, New_List (
2124 Make_Parameter_Specification (Loc,
2125 Defining_Identifier =>
2126 Make_Defining_Identifier (Loc, Name_uT),
2128 New_Reference_To (Typ, Loc),
2130 Out_Present => True),
2132 Make_Parameter_Specification (Loc,
2133 Defining_Identifier =>
2134 Make_Defining_Identifier (Loc, Name_uS),
2136 New_Reference_To (Standard_Integer, Loc)),
2138 Make_Parameter_Specification (Loc,
2139 Defining_Identifier =>
2140 Make_Defining_Identifier (Loc, Name_uP),
2142 New_Reference_To (RTE (RE_Address), Loc)),
2144 Make_Parameter_Specification (Loc,
2145 Defining_Identifier =>
2146 Make_Defining_Identifier (Loc, Name_uB),
2148 New_Reference_To (RTE (RE_Dummy_Communication_Block), Loc),
2149 Out_Present => True),
2151 Make_Parameter_Specification (Loc,
2152 Defining_Identifier =>
2153 Make_Defining_Identifier (Loc, Name_uF),
2155 New_Reference_To (Standard_Boolean, Loc),
2156 Out_Present => True)));
2159 Make_Procedure_Specification (Loc,
2160 Defining_Unit_Name => Def_Id,
2161 Parameter_Specifications => Params);
2162 end Make_Disp_Asynchronous_Select_Spec;
2164 ---------------------------------------
2165 -- Make_Disp_Conditional_Select_Body --
2166 ---------------------------------------
2168 -- For interface types, generate:
2170 -- procedure _Disp_Conditional_Select
2171 -- (T : in out <Typ>;
2173 -- P : System.Address;
2174 -- C : out Ada.Tags.Prim_Op_Kind;
2179 -- end _Disp_Conditional_Select;
2181 -- For protected types, generate:
2183 -- procedure _Disp_Conditional_Select
2184 -- (T : in out <Typ>;
2186 -- P : System.Address;
2187 -- C : out Ada.Tags.Prim_Op_Kind;
2191 -- Bnn : System.Tasking.Protected_Objects.Operations.
2192 -- Communication_Block;
2195 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP, S));
2197 -- if C = Ada.Tags.POK_Procedure
2198 -- or else C = Ada.Tags.POK_Protected_Procedure
2199 -- or else C = Ada.Tags.POK_Task_Procedure
2205 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2206 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
2207 -- (T.object'Access,
2208 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
2210 -- System.Tasking.Conditional_Call,
2212 -- F := not Cancelled (Bnn);
2213 -- end _Disp_Conditional_Select;
2215 -- For task types, generate:
2217 -- procedure _Disp_Conditional_Select
2218 -- (T : in out <Typ>;
2220 -- P : System.Address;
2221 -- C : out Ada.Tags.Prim_Op_Kind;
2227 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2228 -- System.Tasking.Rendezvous.Task_Entry_Call
2230 -- System.Tasking.Task_Entry_Index (I),
2232 -- System.Tasking.Conditional_Call,
2234 -- end _Disp_Conditional_Select;
2236 function Make_Disp_Conditional_Select_Body
2237 (Typ : Entity_Id) return Node_Id
2239 Loc : constant Source_Ptr := Sloc (Typ);
2240 Blk_Nam : Entity_Id;
2241 Conc_Typ : Entity_Id := Empty;
2242 Decls : constant List_Id := New_List;
2245 Stmts : constant List_Id := New_List;
2248 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2250 -- Null body is generated for interface types
2252 if Is_Interface (Typ) then
2254 Make_Subprogram_Body (Loc,
2256 Make_Disp_Conditional_Select_Spec (Typ),
2259 Handled_Statement_Sequence =>
2260 Make_Handled_Sequence_Of_Statements (Loc,
2261 New_List (Make_Null_Statement (Loc))));
2264 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2266 if Is_Concurrent_Record_Type (Typ) then
2267 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2272 -- where I will be used to capture the entry index of the primitive
2273 -- wrapper at position S.
2276 Make_Object_Declaration (Loc,
2277 Defining_Identifier =>
2278 Make_Defining_Identifier (Loc, Name_uI),
2279 Object_Definition =>
2280 New_Reference_To (Standard_Integer, Loc)));
2283 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag! (<type>VP), S);
2285 -- if C = POK_Procedure
2286 -- or else C = POK_Protected_Procedure
2287 -- or else C = POK_Task_Procedure;
2293 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
2296 -- Bnn : Communication_Block;
2298 -- where Bnn is the name of the communication block used in the
2299 -- call to Protected_Entry_Call.
2301 Blk_Nam := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
2304 Make_Object_Declaration (Loc,
2305 Defining_Identifier =>
2307 Object_Definition =>
2308 New_Reference_To (RTE (RE_Communication_Block), Loc)));
2311 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
2313 -- I is the entry index and S is the dispatch table slot
2316 Make_Assignment_Statement (Loc,
2318 Make_Identifier (Loc, Name_uI),
2320 Make_Function_Call (Loc,
2322 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
2323 Parameter_Associations =>
2325 Unchecked_Convert_To (RTE (RE_Tag),
2326 New_Reference_To (DT_Ptr, Loc)),
2327 Make_Identifier (Loc, Name_uS)))));
2329 if Ekind (Conc_Typ) = E_Protected_Type then
2331 Obj_Ref := -- T._object'Access
2332 Make_Attribute_Reference (Loc,
2333 Attribute_Name => Name_Unchecked_Access,
2335 Make_Selected_Component (Loc,
2336 Prefix => Make_Identifier (Loc, Name_uT),
2337 Selector_Name => Make_Identifier (Loc, Name_uObject)));
2339 case Corresponding_Runtime_Package (Conc_Typ) is
2340 when System_Tasking_Protected_Objects_Entries =>
2343 -- Protected_Entry_Call
2344 -- (T._object'Access, -- Object
2345 -- Protected_Entry_Index! (I), -- E
2346 -- P, -- Uninterpreted_Data
2347 -- Conditional_Call, -- Mode
2350 -- where T is the protected object, I is the entry index, P
2351 -- are the wrapped parameters and Bnn is the name of the
2352 -- communication block.
2355 Make_Procedure_Call_Statement (Loc,
2357 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
2358 Parameter_Associations =>
2362 Make_Unchecked_Type_Conversion (Loc, -- entry index
2365 (RTE (RE_Protected_Entry_Index), Loc),
2366 Expression => Make_Identifier (Loc, Name_uI)),
2368 Make_Identifier (Loc, Name_uP), -- parameter block
2370 New_Reference_To ( -- Conditional_Call
2371 RTE (RE_Conditional_Call), Loc),
2372 New_Reference_To ( -- Bnn
2375 when System_Tasking_Protected_Objects_Single_Entry =>
2377 -- If we are compiling for a restricted run-time, the call
2378 -- uses the simpler form.
2381 Make_Procedure_Call_Statement (Loc,
2384 (RTE (RE_Protected_Single_Entry_Call), Loc),
2385 Parameter_Associations =>
2389 Make_Attribute_Reference (Loc,
2390 Prefix => Make_Identifier (Loc, Name_uP),
2391 Attribute_Name => Name_Address),
2394 (RTE (RE_Conditional_Call), Loc))));
2396 raise Program_Error;
2400 -- F := not Cancelled (Bnn);
2402 -- where F is the success flag. The status of Cancelled is negated
2403 -- in order to match the behaviour of the version for task types.
2406 Make_Assignment_Statement (Loc,
2408 Make_Identifier (Loc, Name_uF),
2412 Make_Function_Call (Loc,
2414 New_Reference_To (RTE (RE_Cancelled), Loc),
2415 Parameter_Associations =>
2417 New_Reference_To (Blk_Nam, Loc))))));
2419 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2423 -- (T._task_id, -- Acceptor
2424 -- Task_Entry_Index! (I), -- E
2425 -- P, -- Uninterpreted_Data
2426 -- Conditional_Call, -- Mode
2427 -- F); -- Rendezvous_Successful
2429 -- where T is the task object, I is the entry index, P are the
2430 -- wrapped parameters and F is the status flag.
2433 Make_Procedure_Call_Statement (Loc,
2435 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
2436 Parameter_Associations =>
2439 Make_Selected_Component (Loc, -- T._task_id
2441 Make_Identifier (Loc, Name_uT),
2443 Make_Identifier (Loc, Name_uTask_Id)),
2445 Make_Unchecked_Type_Conversion (Loc, -- entry index
2447 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2449 Make_Identifier (Loc, Name_uI)),
2451 Make_Identifier (Loc, Name_uP), -- parameter block
2452 New_Reference_To ( -- Conditional_Call
2453 RTE (RE_Conditional_Call), Loc),
2454 Make_Identifier (Loc, Name_uF)))); -- status flag
2458 -- Ensure that the statements list is non-empty
2460 Append_To (Stmts, Make_Null_Statement (Loc));
2464 Make_Subprogram_Body (Loc,
2466 Make_Disp_Conditional_Select_Spec (Typ),
2469 Handled_Statement_Sequence =>
2470 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2471 end Make_Disp_Conditional_Select_Body;
2473 ---------------------------------------
2474 -- Make_Disp_Conditional_Select_Spec --
2475 ---------------------------------------
2477 function Make_Disp_Conditional_Select_Spec
2478 (Typ : Entity_Id) return Node_Id
2480 Loc : constant Source_Ptr := Sloc (Typ);
2481 Def_Id : constant Node_Id :=
2482 Make_Defining_Identifier (Loc,
2483 Name_uDisp_Conditional_Select);
2484 Params : constant List_Id := New_List;
2487 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2489 -- T : in out Typ; -- Object parameter
2490 -- S : Integer; -- Primitive operation slot
2491 -- P : Address; -- Wrapped parameters
2492 -- C : out Prim_Op_Kind; -- Call kind
2493 -- F : out Boolean; -- Status flag
2495 Append_List_To (Params, New_List (
2497 Make_Parameter_Specification (Loc,
2498 Defining_Identifier =>
2499 Make_Defining_Identifier (Loc, Name_uT),
2501 New_Reference_To (Typ, Loc),
2503 Out_Present => True),
2505 Make_Parameter_Specification (Loc,
2506 Defining_Identifier =>
2507 Make_Defining_Identifier (Loc, Name_uS),
2509 New_Reference_To (Standard_Integer, Loc)),
2511 Make_Parameter_Specification (Loc,
2512 Defining_Identifier =>
2513 Make_Defining_Identifier (Loc, Name_uP),
2515 New_Reference_To (RTE (RE_Address), Loc)),
2517 Make_Parameter_Specification (Loc,
2518 Defining_Identifier =>
2519 Make_Defining_Identifier (Loc, Name_uC),
2521 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2522 Out_Present => True),
2524 Make_Parameter_Specification (Loc,
2525 Defining_Identifier =>
2526 Make_Defining_Identifier (Loc, Name_uF),
2528 New_Reference_To (Standard_Boolean, Loc),
2529 Out_Present => True)));
2532 Make_Procedure_Specification (Loc,
2533 Defining_Unit_Name => Def_Id,
2534 Parameter_Specifications => Params);
2535 end Make_Disp_Conditional_Select_Spec;
2537 -------------------------------------
2538 -- Make_Disp_Get_Prim_Op_Kind_Body --
2539 -------------------------------------
2541 function Make_Disp_Get_Prim_Op_Kind_Body
2542 (Typ : Entity_Id) return Node_Id
2544 Loc : constant Source_Ptr := Sloc (Typ);
2548 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2550 if Is_Interface (Typ) then
2552 Make_Subprogram_Body (Loc,
2554 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2557 Handled_Statement_Sequence =>
2558 Make_Handled_Sequence_Of_Statements (Loc,
2559 New_List (Make_Null_Statement (Loc))));
2562 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2565 -- C := get_prim_op_kind (tag! (<type>VP), S);
2567 -- where C is the out parameter capturing the call kind and S is the
2568 -- dispatch table slot number.
2571 Make_Subprogram_Body (Loc,
2573 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2576 Handled_Statement_Sequence =>
2577 Make_Handled_Sequence_Of_Statements (Loc,
2579 Make_Assignment_Statement (Loc,
2581 Make_Identifier (Loc, Name_uC),
2583 Make_Function_Call (Loc,
2585 New_Reference_To (RTE (RE_Get_Prim_Op_Kind), Loc),
2586 Parameter_Associations => New_List (
2587 Unchecked_Convert_To (RTE (RE_Tag),
2588 New_Reference_To (DT_Ptr, Loc)),
2589 Make_Identifier (Loc, Name_uS)))))));
2590 end Make_Disp_Get_Prim_Op_Kind_Body;
2592 -------------------------------------
2593 -- Make_Disp_Get_Prim_Op_Kind_Spec --
2594 -------------------------------------
2596 function Make_Disp_Get_Prim_Op_Kind_Spec
2597 (Typ : Entity_Id) return Node_Id
2599 Loc : constant Source_Ptr := Sloc (Typ);
2600 Def_Id : constant Node_Id :=
2601 Make_Defining_Identifier (Loc,
2602 Name_uDisp_Get_Prim_Op_Kind);
2603 Params : constant List_Id := New_List;
2606 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2608 -- T : in out Typ; -- Object parameter
2609 -- S : Integer; -- Primitive operation slot
2610 -- C : out Prim_Op_Kind; -- Call kind
2612 Append_List_To (Params, New_List (
2614 Make_Parameter_Specification (Loc,
2615 Defining_Identifier =>
2616 Make_Defining_Identifier (Loc, Name_uT),
2618 New_Reference_To (Typ, Loc),
2620 Out_Present => True),
2622 Make_Parameter_Specification (Loc,
2623 Defining_Identifier =>
2624 Make_Defining_Identifier (Loc, Name_uS),
2626 New_Reference_To (Standard_Integer, Loc)),
2628 Make_Parameter_Specification (Loc,
2629 Defining_Identifier =>
2630 Make_Defining_Identifier (Loc, Name_uC),
2632 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2633 Out_Present => True)));
2636 Make_Procedure_Specification (Loc,
2637 Defining_Unit_Name => Def_Id,
2638 Parameter_Specifications => Params);
2639 end Make_Disp_Get_Prim_Op_Kind_Spec;
2641 --------------------------------
2642 -- Make_Disp_Get_Task_Id_Body --
2643 --------------------------------
2645 function Make_Disp_Get_Task_Id_Body
2646 (Typ : Entity_Id) return Node_Id
2648 Loc : constant Source_Ptr := Sloc (Typ);
2652 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2654 if Is_Concurrent_Record_Type (Typ)
2655 and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
2658 -- return To_Address (_T._task_id);
2661 Make_Simple_Return_Statement (Loc,
2663 Make_Unchecked_Type_Conversion (Loc,
2665 New_Reference_To (RTE (RE_Address), Loc),
2667 Make_Selected_Component (Loc,
2669 Make_Identifier (Loc, Name_uT),
2671 Make_Identifier (Loc, Name_uTask_Id))));
2673 -- A null body is constructed for non-task types
2677 -- return Null_Address;
2680 Make_Simple_Return_Statement (Loc,
2682 New_Reference_To (RTE (RE_Null_Address), Loc));
2686 Make_Subprogram_Body (Loc,
2688 Make_Disp_Get_Task_Id_Spec (Typ),
2691 Handled_Statement_Sequence =>
2692 Make_Handled_Sequence_Of_Statements (Loc,
2694 end Make_Disp_Get_Task_Id_Body;
2696 --------------------------------
2697 -- Make_Disp_Get_Task_Id_Spec --
2698 --------------------------------
2700 function Make_Disp_Get_Task_Id_Spec
2701 (Typ : Entity_Id) return Node_Id
2703 Loc : constant Source_Ptr := Sloc (Typ);
2706 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2709 Make_Function_Specification (Loc,
2710 Defining_Unit_Name =>
2711 Make_Defining_Identifier (Loc, Name_uDisp_Get_Task_Id),
2712 Parameter_Specifications => New_List (
2713 Make_Parameter_Specification (Loc,
2714 Defining_Identifier =>
2715 Make_Defining_Identifier (Loc, Name_uT),
2717 New_Reference_To (Typ, Loc))),
2718 Result_Definition =>
2719 New_Reference_To (RTE (RE_Address), Loc));
2720 end Make_Disp_Get_Task_Id_Spec;
2722 ----------------------------
2723 -- Make_Disp_Requeue_Body --
2724 ----------------------------
2726 function Make_Disp_Requeue_Body
2727 (Typ : Entity_Id) return Node_Id
2729 Loc : constant Source_Ptr := Sloc (Typ);
2730 Conc_Typ : Entity_Id := Empty;
2731 Stmts : constant List_Id := New_List;
2734 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2736 -- Null body is generated for interface types and non-concurrent
2739 if Is_Interface (Typ)
2740 or else not Is_Concurrent_Record_Type (Typ)
2743 Make_Subprogram_Body (Loc,
2745 Make_Disp_Requeue_Spec (Typ),
2748 Handled_Statement_Sequence =>
2749 Make_Handled_Sequence_Of_Statements (Loc,
2750 New_List (Make_Null_Statement (Loc))));
2753 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2755 if Ekind (Conc_Typ) = E_Protected_Type then
2757 -- Generate statements:
2759 -- System.Tasking.Protected_Objects.Operations.
2760 -- Requeue_Protected_Entry
2761 -- (Protection_Entries_Access (P),
2762 -- O._object'Unchecked_Access,
2763 -- Protected_Entry_Index (I),
2766 -- System.Tasking.Protected_Objects.Operations.
2767 -- Requeue_Task_To_Protected_Entry
2768 -- (O._object'Unchecked_Access,
2769 -- Protected_Entry_Index (I),
2773 if Restriction_Active (No_Entry_Queue) then
2774 Append_To (Stmts, Make_Null_Statement (Loc));
2777 Make_If_Statement (Loc,
2779 Make_Identifier (Loc, Name_uF),
2784 -- Call to Requeue_Protected_Entry
2786 Make_Procedure_Call_Statement (Loc,
2789 RTE (RE_Requeue_Protected_Entry), Loc),
2790 Parameter_Associations =>
2793 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
2796 RTE (RE_Protection_Entries_Access), Loc),
2798 Make_Identifier (Loc, Name_uP)),
2800 Make_Attribute_Reference (Loc, -- O._object'Acc
2802 Name_Unchecked_Access,
2804 Make_Selected_Component (Loc,
2806 Make_Identifier (Loc, Name_uO),
2808 Make_Identifier (Loc, Name_uObject))),
2810 Make_Unchecked_Type_Conversion (Loc, -- entry index
2813 RTE (RE_Protected_Entry_Index), Loc),
2815 Make_Identifier (Loc, Name_uI)),
2817 Make_Identifier (Loc, Name_uA)))), -- abort status
2822 -- Call to Requeue_Task_To_Protected_Entry
2824 Make_Procedure_Call_Statement (Loc,
2827 RTE (RE_Requeue_Task_To_Protected_Entry), Loc),
2828 Parameter_Associations =>
2831 Make_Attribute_Reference (Loc, -- O._object'Acc
2833 Name_Unchecked_Access,
2835 Make_Selected_Component (Loc,
2837 Make_Identifier (Loc, Name_uO),
2839 Make_Identifier (Loc, Name_uObject))),
2841 Make_Unchecked_Type_Conversion (Loc, -- entry index
2844 RTE (RE_Protected_Entry_Index), Loc),
2846 Make_Identifier (Loc, Name_uI)),
2848 Make_Identifier (Loc, Name_uA)))))); -- abort status
2851 pragma Assert (Is_Task_Type (Conc_Typ));
2855 -- System.Tasking.Rendezvous.Requeue_Protected_To_Task_Entry
2856 -- (Protection_Entries_Access (P),
2858 -- Task_Entry_Index (I),
2861 -- System.Tasking.Rendezvous.Requeue_Task_Entry
2863 -- Task_Entry_Index (I),
2868 Make_If_Statement (Loc,
2870 Make_Identifier (Loc, Name_uF),
2875 -- Call to Requeue_Protected_To_Task_Entry
2877 Make_Procedure_Call_Statement (Loc,
2880 RTE (RE_Requeue_Protected_To_Task_Entry), Loc),
2882 Parameter_Associations =>
2885 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
2888 RTE (RE_Protection_Entries_Access), Loc),
2890 Make_Identifier (Loc, Name_uP)),
2892 Make_Selected_Component (Loc, -- O._task_id
2894 Make_Identifier (Loc, Name_uO),
2896 Make_Identifier (Loc, Name_uTask_Id)),
2898 Make_Unchecked_Type_Conversion (Loc, -- entry index
2901 RTE (RE_Task_Entry_Index), Loc),
2903 Make_Identifier (Loc, Name_uI)),
2905 Make_Identifier (Loc, Name_uA)))), -- abort status
2910 -- Call to Requeue_Task_Entry
2912 Make_Procedure_Call_Statement (Loc,
2914 New_Reference_To (RTE (RE_Requeue_Task_Entry), Loc),
2916 Parameter_Associations =>
2919 Make_Selected_Component (Loc, -- O._task_id
2921 Make_Identifier (Loc, Name_uO),
2923 Make_Identifier (Loc, Name_uTask_Id)),
2925 Make_Unchecked_Type_Conversion (Loc, -- entry index
2928 RTE (RE_Task_Entry_Index), Loc),
2930 Make_Identifier (Loc, Name_uI)),
2932 Make_Identifier (Loc, Name_uA)))))); -- abort status
2935 -- Even though no declarations are needed in both cases, we allocate
2936 -- a list for entities added by Freeze.
2939 Make_Subprogram_Body (Loc,
2941 Make_Disp_Requeue_Spec (Typ),
2944 Handled_Statement_Sequence =>
2945 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2946 end Make_Disp_Requeue_Body;
2948 ----------------------------
2949 -- Make_Disp_Requeue_Spec --
2950 ----------------------------
2952 function Make_Disp_Requeue_Spec
2953 (Typ : Entity_Id) return Node_Id
2955 Loc : constant Source_Ptr := Sloc (Typ);
2958 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2960 -- O : in out Typ; - Object parameter
2961 -- F : Boolean; - Protected (True) / task (False) flag
2962 -- P : Address; - Protection_Entries_Access value
2963 -- I : Entry_Index - Index of entry call
2964 -- A : Boolean - Abort flag
2966 -- Note that the Protection_Entries_Access value is represented as a
2967 -- System.Address in order to avoid dragging in the tasking runtime
2968 -- when compiling sources without tasking constructs.
2971 Make_Procedure_Specification (Loc,
2972 Defining_Unit_Name =>
2973 Make_Defining_Identifier (Loc, Name_uDisp_Requeue),
2975 Parameter_Specifications =>
2978 Make_Parameter_Specification (Loc, -- O
2979 Defining_Identifier =>
2980 Make_Defining_Identifier (Loc, Name_uO),
2982 New_Reference_To (Typ, Loc),
2984 Out_Present => True),
2986 Make_Parameter_Specification (Loc, -- F
2987 Defining_Identifier =>
2988 Make_Defining_Identifier (Loc, Name_uF),
2990 New_Reference_To (Standard_Boolean, Loc)),
2992 Make_Parameter_Specification (Loc, -- P
2993 Defining_Identifier =>
2994 Make_Defining_Identifier (Loc, Name_uP),
2996 New_Reference_To (RTE (RE_Address), Loc)),
2998 Make_Parameter_Specification (Loc, -- I
2999 Defining_Identifier =>
3000 Make_Defining_Identifier (Loc, Name_uI),
3002 New_Reference_To (Standard_Integer, Loc)),
3004 Make_Parameter_Specification (Loc, -- A
3005 Defining_Identifier =>
3006 Make_Defining_Identifier (Loc, Name_uA),
3008 New_Reference_To (Standard_Boolean, Loc))));
3009 end Make_Disp_Requeue_Spec;
3011 ---------------------------------
3012 -- Make_Disp_Timed_Select_Body --
3013 ---------------------------------
3015 -- For interface types, generate:
3017 -- procedure _Disp_Timed_Select
3018 -- (T : in out <Typ>;
3020 -- P : System.Address;
3023 -- C : out Ada.Tags.Prim_Op_Kind;
3028 -- end _Disp_Timed_Select;
3030 -- For protected types, generate:
3032 -- procedure _Disp_Timed_Select
3033 -- (T : in out <Typ>;
3035 -- P : System.Address;
3038 -- C : out Ada.Tags.Prim_Op_Kind;
3044 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP), S);
3046 -- if C = Ada.Tags.POK_Procedure
3047 -- or else C = Ada.Tags.POK_Protected_Procedure
3048 -- or else C = Ada.Tags.POK_Task_Procedure
3054 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
3055 -- System.Tasking.Protected_Objects.Operations.
3056 -- Timed_Protected_Entry_Call
3057 -- (T._object'Access,
3058 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
3063 -- end _Disp_Timed_Select;
3065 -- For task types, generate:
3067 -- procedure _Disp_Timed_Select
3068 -- (T : in out <Typ>;
3070 -- P : System.Address;
3073 -- C : out Ada.Tags.Prim_Op_Kind;
3079 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
3080 -- System.Tasking.Rendezvous.Timed_Task_Entry_Call
3082 -- System.Tasking.Task_Entry_Index (I),
3087 -- end _Disp_Time_Select;
3089 function Make_Disp_Timed_Select_Body
3090 (Typ : Entity_Id) return Node_Id
3092 Loc : constant Source_Ptr := Sloc (Typ);
3093 Conc_Typ : Entity_Id := Empty;
3094 Decls : constant List_Id := New_List;
3097 Stmts : constant List_Id := New_List;
3100 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3102 -- Null body is generated for interface types
3104 if Is_Interface (Typ) then
3106 Make_Subprogram_Body (Loc,
3108 Make_Disp_Timed_Select_Spec (Typ),
3111 Handled_Statement_Sequence =>
3112 Make_Handled_Sequence_Of_Statements (Loc,
3113 New_List (Make_Null_Statement (Loc))));
3116 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
3118 if Is_Concurrent_Record_Type (Typ) then
3119 Conc_Typ := Corresponding_Concurrent_Type (Typ);
3124 -- where I will be used to capture the entry index of the primitive
3125 -- wrapper at position S.
3128 Make_Object_Declaration (Loc,
3129 Defining_Identifier =>
3130 Make_Defining_Identifier (Loc, Name_uI),
3131 Object_Definition =>
3132 New_Reference_To (Standard_Integer, Loc)));
3135 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
3137 -- if C = POK_Procedure
3138 -- or else C = POK_Protected_Procedure
3139 -- or else C = POK_Task_Procedure;
3145 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
3148 -- I := Get_Entry_Index (tag! (<type>VP), S);
3150 -- I is the entry index and S is the dispatch table slot
3153 Make_Assignment_Statement (Loc,
3155 Make_Identifier (Loc, Name_uI),
3157 Make_Function_Call (Loc,
3159 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
3160 Parameter_Associations =>
3162 Unchecked_Convert_To (RTE (RE_Tag),
3163 New_Reference_To (DT_Ptr, Loc)),
3164 Make_Identifier (Loc, Name_uS)))));
3168 if Ekind (Conc_Typ) = E_Protected_Type then
3170 -- Build T._object'Access
3173 Make_Attribute_Reference (Loc,
3174 Attribute_Name => Name_Unchecked_Access,
3176 Make_Selected_Component (Loc,
3177 Prefix => Make_Identifier (Loc, Name_uT),
3178 Selector_Name => Make_Identifier (Loc, Name_uObject)));
3180 -- Normal case, No_Entry_Queue restriction not active. In this
3181 -- case we generate:
3183 -- Timed_Protected_Entry_Call
3184 -- (T._object'access,
3185 -- Protected_Entry_Index! (I),
3188 -- where T is the protected object, I is the entry index, P are
3189 -- the wrapped parameters, D is the delay amount, M is the delay
3190 -- mode and F is the status flag.
3192 case Corresponding_Runtime_Package (Conc_Typ) is
3193 when System_Tasking_Protected_Objects_Entries =>
3195 Make_Procedure_Call_Statement (Loc,
3198 (RTE (RE_Timed_Protected_Entry_Call), Loc),
3199 Parameter_Associations =>
3203 Make_Unchecked_Type_Conversion (Loc, -- entry index
3206 (RTE (RE_Protected_Entry_Index), Loc),
3208 Make_Identifier (Loc, Name_uI)),
3210 Make_Identifier (Loc, Name_uP), -- parameter block
3211 Make_Identifier (Loc, Name_uD), -- delay
3212 Make_Identifier (Loc, Name_uM), -- delay mode
3213 Make_Identifier (Loc, Name_uF)))); -- status flag
3215 when System_Tasking_Protected_Objects_Single_Entry =>
3218 -- Timed_Protected_Single_Entry_Call
3219 -- (T._object'access, P, D, M, F);
3221 -- where T is the protected object, P is the wrapped
3222 -- parameters, D is the delay amount, M is the delay mode, F
3223 -- is the status flag.
3226 Make_Procedure_Call_Statement (Loc,
3229 (RTE (RE_Timed_Protected_Single_Entry_Call), Loc),
3230 Parameter_Associations =>
3233 Make_Identifier (Loc, Name_uP), -- parameter block
3234 Make_Identifier (Loc, Name_uD), -- delay
3235 Make_Identifier (Loc, Name_uM), -- delay mode
3236 Make_Identifier (Loc, Name_uF)))); -- status flag
3239 raise Program_Error;
3245 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
3248 -- Timed_Task_Entry_Call (
3250 -- Task_Entry_Index! (I),
3256 -- where T is the task object, I is the entry index, P are the
3257 -- wrapped parameters, D is the delay amount, M is the delay
3258 -- mode and F is the status flag.
3261 Make_Procedure_Call_Statement (Loc,
3263 New_Reference_To (RTE (RE_Timed_Task_Entry_Call), Loc),
3264 Parameter_Associations =>
3267 Make_Selected_Component (Loc, -- T._task_id
3269 Make_Identifier (Loc, Name_uT),
3271 Make_Identifier (Loc, Name_uTask_Id)),
3273 Make_Unchecked_Type_Conversion (Loc, -- entry index
3275 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
3277 Make_Identifier (Loc, Name_uI)),
3279 Make_Identifier (Loc, Name_uP), -- parameter block
3280 Make_Identifier (Loc, Name_uD), -- delay
3281 Make_Identifier (Loc, Name_uM), -- delay mode
3282 Make_Identifier (Loc, Name_uF)))); -- status flag
3286 -- Ensure that the statements list is non-empty
3288 Append_To (Stmts, Make_Null_Statement (Loc));
3292 Make_Subprogram_Body (Loc,
3294 Make_Disp_Timed_Select_Spec (Typ),
3297 Handled_Statement_Sequence =>
3298 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
3299 end Make_Disp_Timed_Select_Body;
3301 ---------------------------------
3302 -- Make_Disp_Timed_Select_Spec --
3303 ---------------------------------
3305 function Make_Disp_Timed_Select_Spec
3306 (Typ : Entity_Id) return Node_Id
3308 Loc : constant Source_Ptr := Sloc (Typ);
3309 Def_Id : constant Node_Id :=
3310 Make_Defining_Identifier (Loc,
3311 Name_uDisp_Timed_Select);
3312 Params : constant List_Id := New_List;
3315 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3317 -- T : in out Typ; -- Object parameter
3318 -- S : Integer; -- Primitive operation slot
3319 -- P : Address; -- Wrapped parameters
3320 -- D : Duration; -- Delay
3321 -- M : Integer; -- Delay Mode
3322 -- C : out Prim_Op_Kind; -- Call kind
3323 -- F : out Boolean; -- Status flag
3325 Append_List_To (Params, New_List (
3327 Make_Parameter_Specification (Loc,
3328 Defining_Identifier =>
3329 Make_Defining_Identifier (Loc, Name_uT),
3331 New_Reference_To (Typ, Loc),
3333 Out_Present => True),
3335 Make_Parameter_Specification (Loc,
3336 Defining_Identifier =>
3337 Make_Defining_Identifier (Loc, Name_uS),
3339 New_Reference_To (Standard_Integer, Loc)),
3341 Make_Parameter_Specification (Loc,
3342 Defining_Identifier =>
3343 Make_Defining_Identifier (Loc, Name_uP),
3345 New_Reference_To (RTE (RE_Address), Loc)),
3347 Make_Parameter_Specification (Loc,
3348 Defining_Identifier =>
3349 Make_Defining_Identifier (Loc, Name_uD),
3351 New_Reference_To (Standard_Duration, Loc)),
3353 Make_Parameter_Specification (Loc,
3354 Defining_Identifier =>
3355 Make_Defining_Identifier (Loc, Name_uM),
3357 New_Reference_To (Standard_Integer, Loc)),
3359 Make_Parameter_Specification (Loc,
3360 Defining_Identifier =>
3361 Make_Defining_Identifier (Loc, Name_uC),
3363 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
3364 Out_Present => True)));
3367 Make_Parameter_Specification (Loc,
3368 Defining_Identifier =>
3369 Make_Defining_Identifier (Loc, Name_uF),
3371 New_Reference_To (Standard_Boolean, Loc),
3372 Out_Present => True));
3375 Make_Procedure_Specification (Loc,
3376 Defining_Unit_Name => Def_Id,
3377 Parameter_Specifications => Params);
3378 end Make_Disp_Timed_Select_Spec;
3384 -- The frontend supports two models for expanding dispatch tables
3385 -- associated with library-level defined tagged types: statically
3386 -- and non-statically allocated dispatch tables. In the former case
3387 -- the object containing the dispatch table is constant and it is
3388 -- initialized by means of a positional aggregate. In the latter case,
3389 -- the object containing the dispatch table is a variable which is
3390 -- initialized by means of assignments.
3392 -- In case of locally defined tagged types, the object containing the
3393 -- object containing the dispatch table is always a variable (instead
3394 -- of a constant). This is currently required to give support to late
3395 -- overriding of primitives. For example:
3397 -- procedure Example is
3399 -- type T1 is tagged null record;
3400 -- procedure Prim (O : T1);
3403 -- type T2 is new Pkg.T1 with null record;
3404 -- procedure Prim (X : T2) is -- late overriding
3410 function Make_DT (Typ : Entity_Id; N : Node_Id := Empty) return List_Id is
3411 Loc : constant Source_Ptr := Sloc (Typ);
3413 Max_Predef_Prims : constant Int :=
3417 (Parent (RTE (RE_Max_Predef_Prims)))));
3419 DT_Decl : constant Elist_Id := New_Elmt_List;
3420 DT_Aggr : constant Elist_Id := New_Elmt_List;
3421 -- Entities marked with attribute Is_Dispatch_Table_Entity
3423 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id);
3424 -- Verify that all non-tagged types in the profile of a subprogram
3425 -- are frozen at the point the subprogram is frozen. This enforces
3426 -- the rule on RM 13.14 (14) as modified by AI05-019. At the point a
3427 -- subprogram is frozen, enough must be known about it to build the
3428 -- activation record for it, which requires at least that the size of
3429 -- all parameters be known. Controlling arguments are by-reference,
3430 -- and therefore the rule only applies to non-tagged types.
3431 -- Typical violation of the rule involves an object declaration that
3432 -- freezes a tagged type, when one of its primitive operations has a
3433 -- type in its profile whose full view has not been analyzed yet.
3435 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0);
3436 -- Export the dispatch table DT of tagged type Typ. Required to generate
3437 -- forward references and statically allocate the table. For primary
3438 -- dispatch tables Index is 0; for secondary dispatch tables the value
3439 -- of index must match the Suffix_Index value assigned to the table by
3440 -- Make_Tags when generating its unique external name, and it is used to
3441 -- retrieve from the Dispatch_Table_Wrappers list associated with Typ
3442 -- the external name generated by Import_DT.
3444 procedure Make_Secondary_DT
3448 Num_Iface_Prims : Nat;
3449 Iface_DT_Ptr : Entity_Id;
3450 Predef_Prims_Ptr : Entity_Id;
3451 Build_Thunks : Boolean;
3453 -- Ada 2005 (AI-251): Expand the declarations for a Secondary Dispatch
3454 -- Table of Typ associated with Iface. Each abstract interface of Typ
3455 -- has two secondary dispatch tables: one containing pointers to thunks
3456 -- and another containing pointers to the primitives covering the
3457 -- interface primitives. The former secondary table is generated when
3458 -- Build_Thunks is True, and provides common support for dispatching
3459 -- calls through interface types; the latter secondary table is
3460 -- generated when Build_Thunks is False, and provides support for
3461 -- Generic Dispatching Constructors that dispatch calls through
3462 -- interface types. When constructing this latter table the value
3463 -- of Suffix_Index is -1 to indicate that there is no need to export
3464 -- such table when building statically allocated dispatch tables; a
3465 -- positive value of Suffix_Index must match the Suffix_Index value
3466 -- assigned to this secondary dispatch table by Make_Tags when its
3467 -- unique external name was generated.
3469 ------------------------------
3470 -- Check_Premature_Freezing --
3471 ------------------------------
3473 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id) is
3476 and then Is_Private_Type (Typ)
3477 and then No (Full_View (Typ))
3478 and then not Is_Generic_Type (Typ)
3479 and then not Is_Tagged_Type (Typ)
3480 and then not Is_Frozen (Typ)
3482 Error_Msg_Sloc := Sloc (Subp);
3484 ("declaration must appear after completion of type &", N, Typ);
3486 ("\which is an untagged type in the profile of"
3487 & " primitive operation & declared#",
3490 end Check_Premature_Freezing;
3496 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0)
3502 Set_Is_Statically_Allocated (DT);
3503 Set_Is_True_Constant (DT);
3504 Set_Is_Exported (DT);
3507 Elmt := First_Elmt (Dispatch_Table_Wrappers (Typ));
3508 while Count /= Index loop
3513 pragma Assert (Related_Type (Node (Elmt)) = Typ);
3516 (Entity => Node (Elmt),
3517 Has_Suffix => True);
3519 Set_Interface_Name (DT,
3520 Make_String_Literal (Loc,
3521 Strval => String_From_Name_Buffer));
3523 -- Ensure proper Sprint output of this implicit importation
3525 Set_Is_Internal (DT);
3529 -----------------------
3530 -- Make_Secondary_DT --
3531 -----------------------
3533 procedure Make_Secondary_DT
3537 Num_Iface_Prims : Nat;
3538 Iface_DT_Ptr : Entity_Id;
3539 Predef_Prims_Ptr : Entity_Id;
3540 Build_Thunks : Boolean;
3543 Loc : constant Source_Ptr := Sloc (Typ);
3544 Exporting_Table : constant Boolean :=
3545 Building_Static_DT (Typ)
3546 and then Suffix_Index > 0;
3547 Iface_DT : constant Entity_Id :=
3548 Make_Defining_Identifier (Loc,
3549 Chars => New_Internal_Name ('T'));
3550 Name_Predef_Prims : constant Name_Id := New_Internal_Name ('R');
3551 Predef_Prims : constant Entity_Id :=
3552 Make_Defining_Identifier (Loc,
3553 Chars => Name_Predef_Prims);
3554 DT_Constr_List : List_Id;
3555 DT_Aggr_List : List_Id;
3556 Empty_DT : Boolean := False;
3557 Nb_Predef_Prims : Nat := 0;
3561 OSD_Aggr_List : List_Id;
3564 Prim_Elmt : Elmt_Id;
3565 Prim_Ops_Aggr_List : List_Id;
3568 -- Handle cases in which we do not generate statically allocated
3571 if not Building_Static_DT (Typ) then
3572 Set_Ekind (Predef_Prims, E_Variable);
3573 Set_Ekind (Iface_DT, E_Variable);
3575 -- Statically allocated dispatch tables and related entities are
3579 Set_Ekind (Predef_Prims, E_Constant);
3580 Set_Is_Statically_Allocated (Predef_Prims);
3581 Set_Is_True_Constant (Predef_Prims);
3583 Set_Ekind (Iface_DT, E_Constant);
3584 Set_Is_Statically_Allocated (Iface_DT);
3585 Set_Is_True_Constant (Iface_DT);
3588 -- Calculate the number of slots of the dispatch table. If the number
3589 -- of primitives of Typ is 0 we reserve a dummy single entry for its
3590 -- DT because at run-time the pointer to this dummy entry will be
3593 if Num_Iface_Prims = 0 then
3597 Nb_Prim := Num_Iface_Prims;
3602 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
3603 -- (predef-prim-op-thunk-1'address,
3604 -- predef-prim-op-thunk-2'address,
3606 -- predef-prim-op-thunk-n'address);
3607 -- for Predef_Prims'Alignment use Address'Alignment
3609 -- Stage 1: Calculate the number of predefined primitives
3611 if not Building_Static_DT (Typ) then
3612 Nb_Predef_Prims := Max_Predef_Prims;
3614 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3615 while Present (Prim_Elmt) loop
3616 Prim := Node (Prim_Elmt);
3618 if Is_Predefined_Dispatching_Operation (Prim)
3619 and then not Is_Abstract_Subprogram (Prim)
3621 Pos := UI_To_Int (DT_Position (Prim));
3623 if Pos > Nb_Predef_Prims then
3624 Nb_Predef_Prims := Pos;
3628 Next_Elmt (Prim_Elmt);
3632 -- Stage 2: Create the thunks associated with the predefined
3633 -- primitives and save their entity to fill the aggregate.
3636 Prim_Table : array (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
3638 Thunk_Id : Entity_Id;
3639 Thunk_Code : Node_Id;
3642 Prim_Ops_Aggr_List := New_List;
3643 Prim_Table := (others => Empty);
3645 if Building_Static_DT (Typ) then
3646 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3647 while Present (Prim_Elmt) loop
3648 Prim := Node (Prim_Elmt);
3650 if Is_Predefined_Dispatching_Operation (Prim)
3651 and then not Is_Abstract_Subprogram (Prim)
3652 and then not Present (Prim_Table
3653 (UI_To_Int (DT_Position (Prim))))
3655 if not Build_Thunks then
3656 Prim_Table (UI_To_Int (DT_Position (Prim))) :=
3660 while Present (Alias (Prim)) loop
3661 Prim := Alias (Prim);
3664 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
3666 if Present (Thunk_Id) then
3667 Append_To (Result, Thunk_Code);
3668 Prim_Table (UI_To_Int (DT_Position (Prim)))
3674 Next_Elmt (Prim_Elmt);
3678 for J in Prim_Table'Range loop
3679 if Present (Prim_Table (J)) then
3681 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
3682 Make_Attribute_Reference (Loc,
3683 Prefix => New_Reference_To (Prim_Table (J), Loc),
3684 Attribute_Name => Name_Unrestricted_Access));
3686 New_Node := Make_Null (Loc);
3689 Append_To (Prim_Ops_Aggr_List, New_Node);
3693 Make_Aggregate (Loc,
3694 Expressions => Prim_Ops_Aggr_List);
3696 -- Remember aggregates initializing dispatch tables
3698 Append_Elmt (New_Node, DT_Aggr);
3701 Make_Subtype_Declaration (Loc,
3702 Defining_Identifier =>
3703 Make_Defining_Identifier (Loc,
3704 New_Internal_Name ('S')),
3705 Subtype_Indication =>
3706 New_Reference_To (RTE (RE_Address_Array), Loc));
3708 Append_To (Result, Decl);
3711 Make_Object_Declaration (Loc,
3712 Defining_Identifier => Predef_Prims,
3713 Constant_Present => Building_Static_DT (Typ),
3714 Aliased_Present => True,
3715 Object_Definition => New_Reference_To
3716 (Defining_Identifier (Decl), Loc),
3717 Expression => New_Node));
3720 Make_Attribute_Definition_Clause (Loc,
3721 Name => New_Reference_To (Predef_Prims, Loc),
3722 Chars => Name_Alignment,
3724 Make_Attribute_Reference (Loc,
3726 New_Reference_To (RTE (RE_Integer_Address), Loc),
3727 Attribute_Name => Name_Alignment)));
3732 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
3733 -- (OSD_Table => (1 => <value>,
3737 -- Iface_DT : Dispatch_Table (Nb_Prims) :=
3738 -- ([ Signature => <sig-value> ],
3739 -- Tag_Kind => <tag_kind-value>,
3740 -- Predef_Prims => Predef_Prims'Address,
3741 -- Offset_To_Top => 0,
3742 -- OSD => OSD'Address,
3743 -- Prims_Ptr => (prim-op-1'address,
3744 -- prim-op-2'address,
3746 -- prim-op-n'address));
3747 -- for Iface_DT'Alignment use Address'Alignment;
3749 -- Stage 3: Initialize the discriminant and the record components
3751 DT_Constr_List := New_List;
3752 DT_Aggr_List := New_List;
3754 -- Nb_Prim. If the tagged type has no primitives we add a dummy
3755 -- slot whose address will be the tag of this type.
3758 New_Node := Make_Integer_Literal (Loc, 1);
3760 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
3763 Append_To (DT_Constr_List, New_Node);
3764 Append_To (DT_Aggr_List, New_Copy (New_Node));
3768 if RTE_Record_Component_Available (RE_Signature) then
3769 Append_To (DT_Aggr_List,
3770 New_Reference_To (RTE (RE_Secondary_DT), Loc));
3775 if RTE_Record_Component_Available (RE_Tag_Kind) then
3776 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
3781 Append_To (DT_Aggr_List,
3782 Make_Attribute_Reference (Loc,
3783 Prefix => New_Reference_To (Predef_Prims, Loc),
3784 Attribute_Name => Name_Address));
3786 -- Note: The correct value of Offset_To_Top will be set by the init
3789 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
3791 -- Generate the Object Specific Data table required to dispatch calls
3792 -- through synchronized interfaces.
3795 or else Is_Abstract_Type (Typ)
3796 or else Is_Controlled (Typ)
3797 or else Restriction_Active (No_Dispatching_Calls)
3798 or else not Is_Limited_Type (Typ)
3799 or else not Has_Interfaces (Typ)
3800 or else not Build_Thunks
3801 or else not RTE_Record_Component_Available (RE_OSD_Table)
3803 -- No OSD table required
3805 Append_To (DT_Aggr_List,
3806 New_Reference_To (RTE (RE_Null_Address), Loc));
3809 OSD_Aggr_List := New_List;
3812 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
3814 Prim_Alias : Entity_Id;
3815 Prim_Elmt : Elmt_Id;
3821 Prim_Table := (others => Empty);
3822 Prim_Alias := Empty;
3824 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3825 while Present (Prim_Elmt) loop
3826 Prim := Node (Prim_Elmt);
3828 if Present (Interface_Alias (Prim))
3829 and then Find_Dispatching_Type
3830 (Interface_Alias (Prim)) = Iface
3832 Prim_Alias := Interface_Alias (Prim);
3835 while Present (Alias (E)) loop
3839 Pos := UI_To_Int (DT_Position (Prim_Alias));
3841 if Present (Prim_Table (Pos)) then
3842 pragma Assert (Prim_Table (Pos) = E);
3846 Prim_Table (Pos) := E;
3848 Append_To (OSD_Aggr_List,
3849 Make_Component_Association (Loc,
3850 Choices => New_List (
3851 Make_Integer_Literal (Loc,
3852 DT_Position (Prim_Alias))),
3854 Make_Integer_Literal (Loc,
3855 DT_Position (Alias (Prim)))));
3861 Next_Elmt (Prim_Elmt);
3863 pragma Assert (Count = Nb_Prim);
3866 OSD := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
3869 Make_Object_Declaration (Loc,
3870 Defining_Identifier => OSD,
3871 Object_Definition =>
3872 Make_Subtype_Indication (Loc,
3874 New_Reference_To (RTE (RE_Object_Specific_Data), Loc),
3876 Make_Index_Or_Discriminant_Constraint (Loc,
3877 Constraints => New_List (
3878 Make_Integer_Literal (Loc, Nb_Prim)))),
3879 Expression => Make_Aggregate (Loc,
3880 Component_Associations => New_List (
3881 Make_Component_Association (Loc,
3882 Choices => New_List (
3884 (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
3886 Make_Integer_Literal (Loc, Nb_Prim)),
3888 Make_Component_Association (Loc,
3889 Choices => New_List (
3891 (RTE_Record_Component (RE_OSD_Table), Loc)),
3892 Expression => Make_Aggregate (Loc,
3893 Component_Associations => OSD_Aggr_List))))));
3896 Make_Attribute_Definition_Clause (Loc,
3897 Name => New_Reference_To (OSD, Loc),
3898 Chars => Name_Alignment,
3900 Make_Attribute_Reference (Loc,
3902 New_Reference_To (RTE (RE_Integer_Address), Loc),
3903 Attribute_Name => Name_Alignment)));
3905 -- In secondary dispatch tables the Typeinfo component contains
3906 -- the address of the Object Specific Data (see a-tags.ads)
3908 Append_To (DT_Aggr_List,
3909 Make_Attribute_Reference (Loc,
3910 Prefix => New_Reference_To (OSD, Loc),
3911 Attribute_Name => Name_Address));
3914 -- Initialize the table of primitive operations
3916 Prim_Ops_Aggr_List := New_List;
3919 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
3921 elsif Is_Abstract_Type (Typ)
3922 or else not Building_Static_DT (Typ)
3924 for J in 1 .. Nb_Prim loop
3925 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
3930 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
3932 Thunk_Code : Node_Id;
3933 Thunk_Id : Entity_Id;
3936 Prim_Table := (others => Empty);
3938 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3939 while Present (Prim_Elmt) loop
3940 Prim := Node (Prim_Elmt);
3942 if not Is_Predefined_Dispatching_Operation (Prim)
3943 and then Present (Interface_Alias (Prim))
3944 and then not Is_Abstract_Subprogram (Alias (Prim))
3945 and then not Is_Imported (Alias (Prim))
3946 and then Find_Dispatching_Type
3947 (Interface_Alias (Prim)) = Iface
3949 -- Generate the code of the thunk only if the abstract
3950 -- interface type is not an immediate ancestor of
3951 -- Tagged_Type; otherwise the DT associated with the
3952 -- interface is the primary DT.
3954 and then not Is_Ancestor (Iface, Typ)
3956 if not Build_Thunks then
3958 UI_To_Int (DT_Position (Interface_Alias (Prim)));
3959 Prim_Table (Pos) := Alias (Prim);
3961 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
3963 if Present (Thunk_Id) then
3965 UI_To_Int (DT_Position (Interface_Alias (Prim)));
3967 Prim_Table (Pos) := Thunk_Id;
3968 Append_To (Result, Thunk_Code);
3973 Next_Elmt (Prim_Elmt);
3976 for J in Prim_Table'Range loop
3977 if Present (Prim_Table (J)) then
3979 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
3980 Make_Attribute_Reference (Loc,
3981 Prefix => New_Reference_To (Prim_Table (J), Loc),
3982 Attribute_Name => Name_Unrestricted_Access));
3984 New_Node := Make_Null (Loc);
3987 Append_To (Prim_Ops_Aggr_List, New_Node);
3993 Make_Aggregate (Loc,
3994 Expressions => Prim_Ops_Aggr_List);
3996 Append_To (DT_Aggr_List, New_Node);
3998 -- Remember aggregates initializing dispatch tables
4000 Append_Elmt (New_Node, DT_Aggr);
4002 -- Note: Secondary dispatch tables cannot be declared constant
4003 -- because the component Offset_To_Top is currently initialized
4004 -- by the IP routine.
4007 Make_Object_Declaration (Loc,
4008 Defining_Identifier => Iface_DT,
4009 Aliased_Present => True,
4010 Constant_Present => False,
4012 Object_Definition =>
4013 Make_Subtype_Indication (Loc,
4014 Subtype_Mark => New_Reference_To
4015 (RTE (RE_Dispatch_Table_Wrapper), Loc),
4016 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4017 Constraints => DT_Constr_List)),
4020 Make_Aggregate (Loc,
4021 Expressions => DT_Aggr_List)));
4024 Make_Attribute_Definition_Clause (Loc,
4025 Name => New_Reference_To (Iface_DT, Loc),
4026 Chars => Name_Alignment,
4029 Make_Attribute_Reference (Loc,
4031 New_Reference_To (RTE (RE_Integer_Address), Loc),
4032 Attribute_Name => Name_Alignment)));
4034 if Exporting_Table then
4035 Export_DT (Typ, Iface_DT, Suffix_Index);
4037 -- Generate code to create the pointer to the dispatch table
4039 -- Iface_DT_Ptr : Tag := Tag!(DT.Prims_Ptr'Address);
4041 -- Note: This declaration is not added here if the table is exported
4042 -- because in such case Make_Tags has already added this declaration.
4046 Make_Object_Declaration (Loc,
4047 Defining_Identifier => Iface_DT_Ptr,
4048 Constant_Present => True,
4050 Object_Definition =>
4051 New_Reference_To (RTE (RE_Interface_Tag), Loc),
4054 Unchecked_Convert_To (RTE (RE_Interface_Tag),
4055 Make_Attribute_Reference (Loc,
4057 Make_Selected_Component (Loc,
4058 Prefix => New_Reference_To (Iface_DT, Loc),
4061 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
4062 Attribute_Name => Name_Address))));
4066 Make_Object_Declaration (Loc,
4067 Defining_Identifier => Predef_Prims_Ptr,
4068 Constant_Present => True,
4070 Object_Definition =>
4071 New_Reference_To (RTE (RE_Address), Loc),
4074 Make_Attribute_Reference (Loc,
4076 Make_Selected_Component (Loc,
4077 Prefix => New_Reference_To (Iface_DT, Loc),
4080 (RTE_Record_Component (RE_Predef_Prims), Loc)),
4081 Attribute_Name => Name_Address)));
4083 -- Remember entities containing dispatch tables
4085 Append_Elmt (Predef_Prims, DT_Decl);
4086 Append_Elmt (Iface_DT, DT_Decl);
4087 end Make_Secondary_DT;
4091 Elab_Code : constant List_Id := New_List;
4092 Result : constant List_Id := New_List;
4093 Tname : constant Name_Id := Chars (Typ);
4095 AI_Tag_Elmt : Elmt_Id;
4096 AI_Tag_Comp : Elmt_Id;
4097 DT_Aggr_List : List_Id;
4098 DT_Constr_List : List_Id;
4102 Iface_Table_Node : Node_Id;
4103 Name_ITable : Name_Id;
4104 Nb_Predef_Prims : Nat := 0;
4107 Num_Ifaces : Nat := 0;
4108 Parent_Typ : Entity_Id;
4110 Prim_Elmt : Elmt_Id;
4111 Prim_Ops_Aggr_List : List_Id;
4113 Typ_Comps : Elist_Id;
4114 Typ_Ifaces : Elist_Id;
4115 TSD_Aggr_List : List_Id;
4116 TSD_Tags_List : List_Id;
4118 -- The following name entries are used by Make_DT to generate a number
4119 -- of entities related to a tagged type. These entities may be generated
4120 -- in a scope other than that of the tagged type declaration, and if
4121 -- the entities for two tagged types with the same name happen to be
4122 -- generated in the same scope, we have to take care to use different
4123 -- names. This is achieved by means of a unique serial number appended
4124 -- to each generated entity name.
4126 Name_DT : constant Name_Id :=
4127 New_External_Name (Tname, 'T', Suffix_Index => -1);
4128 Name_Exname : constant Name_Id :=
4129 New_External_Name (Tname, 'E', Suffix_Index => -1);
4130 Name_HT_Link : constant Name_Id :=
4131 New_External_Name (Tname, 'H', Suffix_Index => -1);
4132 Name_Predef_Prims : constant Name_Id :=
4133 New_External_Name (Tname, 'R', Suffix_Index => -1);
4134 Name_SSD : constant Name_Id :=
4135 New_External_Name (Tname, 'S', Suffix_Index => -1);
4136 Name_TSD : constant Name_Id :=
4137 New_External_Name (Tname, 'B', Suffix_Index => -1);
4139 -- Entities built with above names
4141 DT : constant Entity_Id :=
4142 Make_Defining_Identifier (Loc, Name_DT);
4143 Exname : constant Entity_Id :=
4144 Make_Defining_Identifier (Loc, Name_Exname);
4145 HT_Link : constant Entity_Id :=
4146 Make_Defining_Identifier (Loc, Name_HT_Link);
4147 Predef_Prims : constant Entity_Id :=
4148 Make_Defining_Identifier (Loc, Name_Predef_Prims);
4149 SSD : constant Entity_Id :=
4150 Make_Defining_Identifier (Loc, Name_SSD);
4151 TSD : constant Entity_Id :=
4152 Make_Defining_Identifier (Loc, Name_TSD);
4154 -- Start of processing for Make_DT
4157 pragma Assert (Is_Frozen (Typ));
4159 -- Handle cases in which there is no need to build the dispatch table
4161 if Has_Dispatch_Table (Typ)
4162 or else No (Access_Disp_Table (Typ))
4163 or else Is_CPP_Class (Typ)
4167 elsif No_Run_Time_Mode then
4168 Error_Msg_CRT ("tagged types", Typ);
4171 elsif not RTE_Available (RE_Tag) then
4173 Make_Object_Declaration (Loc,
4174 Defining_Identifier => Node (First_Elmt
4175 (Access_Disp_Table (Typ))),
4176 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4177 Constant_Present => True,
4179 Unchecked_Convert_To (RTE (RE_Tag),
4180 New_Reference_To (RTE (RE_Null_Address), Loc))));
4182 Analyze_List (Result, Suppress => All_Checks);
4183 Error_Msg_CRT ("tagged types", Typ);
4187 -- Ensure that the value of Max_Predef_Prims defined in a-tags is
4188 -- correct. Valid values are 10 under configurable runtime or 16
4189 -- with full runtime.
4191 if RTE_Available (RE_Interface_Data) then
4192 if Max_Predef_Prims /= 16 then
4193 Error_Msg_N ("run-time library configuration error", Typ);
4197 if Max_Predef_Prims /= 10 then
4198 Error_Msg_N ("run-time library configuration error", Typ);
4199 Error_Msg_CRT ("tagged types", Typ);
4204 -- Initialize Parent_Typ handling private types
4206 Parent_Typ := Etype (Typ);
4208 if Present (Full_View (Parent_Typ)) then
4209 Parent_Typ := Full_View (Parent_Typ);
4212 -- Ensure that all the primitives are frozen. This is only required when
4213 -- building static dispatch tables --- the primitives must be frozen to
4214 -- be referenced (otherwise we have problems with the backend). It is
4215 -- not a requirement with nonstatic dispatch tables because in this case
4216 -- we generate now an empty dispatch table; the extra code required to
4217 -- register the primitives in the slots will be generated later --- when
4218 -- each primitive is frozen (see Freeze_Subprogram).
4220 if Building_Static_DT (Typ)
4221 and then not Is_CPP_Class (Typ)
4224 Save : constant Boolean := Freezing_Library_Level_Tagged_Type;
4226 Prim_Elmt : Elmt_Id;
4230 Freezing_Library_Level_Tagged_Type := True;
4232 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4233 while Present (Prim_Elmt) loop
4234 Prim := Node (Prim_Elmt);
4235 Frnodes := Freeze_Entity (Prim, Loc);
4241 F := First_Formal (Prim);
4242 while Present (F) loop
4243 Check_Premature_Freezing (Prim, Etype (F));
4247 Check_Premature_Freezing (Prim, Etype (Prim));
4250 if Present (Frnodes) then
4251 Append_List_To (Result, Frnodes);
4254 Next_Elmt (Prim_Elmt);
4257 Freezing_Library_Level_Tagged_Type := Save;
4261 -- Ada 2005 (AI-251): Build the secondary dispatch tables
4263 if Has_Interfaces (Typ) then
4264 Collect_Interface_Components (Typ, Typ_Comps);
4266 -- Each secondary dispatch table is assigned an unique positive
4267 -- suffix index; such value also corresponds with the location of
4268 -- its entity in the Dispatch_Table_Wrappers list (see Make_Tags).
4270 -- Note: This value must be kept sync with the Suffix_Index values
4271 -- generated by Make_Tags
4275 Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
4277 AI_Tag_Comp := First_Elmt (Typ_Comps);
4278 while Present (AI_Tag_Comp) loop
4280 -- Build the secondary table containing pointers to thunks
4284 Iface => Base_Type (Related_Type (Node (AI_Tag_Comp))),
4285 Suffix_Index => Suffix_Index,
4286 Num_Iface_Prims => UI_To_Int
4287 (DT_Entry_Count (Node (AI_Tag_Comp))),
4288 Iface_DT_Ptr => Node (AI_Tag_Elmt),
4289 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
4290 Build_Thunks => True,
4293 -- Skip secondary dispatch table and secondary dispatch table of
4294 -- predefined primitives
4296 Next_Elmt (AI_Tag_Elmt);
4297 Next_Elmt (AI_Tag_Elmt);
4299 -- Build the secondary table containing pointers to primitives
4300 -- (used to give support to Generic Dispatching Constructors).
4304 Iface => Base_Type (Related_Type (Node (AI_Tag_Comp))),
4306 Num_Iface_Prims => UI_To_Int
4307 (DT_Entry_Count (Node (AI_Tag_Comp))),
4308 Iface_DT_Ptr => Node (AI_Tag_Elmt),
4309 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
4310 Build_Thunks => False,
4313 -- Skip secondary dispatch table and secondary dispatch table of
4314 -- predefined primitives
4316 Next_Elmt (AI_Tag_Elmt);
4317 Next_Elmt (AI_Tag_Elmt);
4319 Suffix_Index := Suffix_Index + 1;
4320 Next_Elmt (AI_Tag_Comp);
4324 -- Get the _tag entity and the number of primitives of its dispatch
4327 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
4328 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
4330 Set_Is_Statically_Allocated (DT, Is_Library_Level_Tagged_Type (Typ));
4331 Set_Is_Statically_Allocated (SSD, Is_Library_Level_Tagged_Type (Typ));
4332 Set_Is_Statically_Allocated (TSD, Is_Library_Level_Tagged_Type (Typ));
4333 Set_Is_Statically_Allocated (Predef_Prims,
4334 Is_Library_Level_Tagged_Type (Typ));
4336 -- In case of locally defined tagged type we declare the object
4337 -- containing the dispatch table by means of a variable. Its
4338 -- initialization is done later by means of an assignment. This is
4339 -- required to generate its External_Tag.
4341 if not Building_Static_DT (Typ) then
4344 -- DT : No_Dispatch_Table_Wrapper;
4345 -- for DT'Alignment use Address'Alignment;
4346 -- DT_Ptr : Tag := !Tag (DT.NDT_Prims_Ptr'Address);
4348 if not Has_DT (Typ) then
4350 Make_Object_Declaration (Loc,
4351 Defining_Identifier => DT,
4352 Aliased_Present => True,
4353 Constant_Present => False,
4354 Object_Definition =>
4356 (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
4358 -- Generate a SCIL node for the previous object declaration
4359 -- because it has a null dispatch table.
4361 if Generate_SCIL then
4363 Make_SCIL_Dispatch_Table_Object_Init (Sloc (Last (Result)));
4364 Set_SCIL_Related_Node (New_Node, Last (Result));
4365 Set_SCIL_Entity (New_Node, Typ);
4366 Insert_Before (Last (Result), New_Node);
4370 Make_Attribute_Definition_Clause (Loc,
4371 Name => New_Reference_To (DT, Loc),
4372 Chars => Name_Alignment,
4374 Make_Attribute_Reference (Loc,
4376 New_Reference_To (RTE (RE_Integer_Address), Loc),
4377 Attribute_Name => Name_Alignment)));
4380 Make_Object_Declaration (Loc,
4381 Defining_Identifier => DT_Ptr,
4382 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4383 Constant_Present => True,
4385 Unchecked_Convert_To (RTE (RE_Tag),
4386 Make_Attribute_Reference (Loc,
4388 Make_Selected_Component (Loc,
4389 Prefix => New_Reference_To (DT, Loc),
4392 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
4393 Attribute_Name => Name_Address))));
4395 -- Generate the SCIL node for the previous object declaration
4396 -- because it has a tag initialization.
4398 if Generate_SCIL then
4400 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
4401 Set_SCIL_Related_Node (New_Node, Last (Result));
4402 Set_SCIL_Entity (New_Node, Typ);
4403 Insert_Before (Last (Result), New_Node);
4407 -- DT : Dispatch_Table_Wrapper (Nb_Prim);
4408 -- for DT'Alignment use Address'Alignment;
4409 -- DT_Ptr : Tag := !Tag (DT.Prims_Ptr'Address);
4412 -- If the tagged type has no primitives we add a dummy slot
4413 -- whose address will be the tag of this type.
4417 New_List (Make_Integer_Literal (Loc, 1));
4420 New_List (Make_Integer_Literal (Loc, Nb_Prim));
4424 Make_Object_Declaration (Loc,
4425 Defining_Identifier => DT,
4426 Aliased_Present => True,
4427 Constant_Present => False,
4428 Object_Definition =>
4429 Make_Subtype_Indication (Loc,
4431 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
4432 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4433 Constraints => DT_Constr_List))));
4435 -- Generate the SCIL node for the previous object declaration
4436 -- because it contains a dispatch table.
4438 if Generate_SCIL then
4440 Make_SCIL_Dispatch_Table_Object_Init (Sloc (Last (Result)));
4441 Set_SCIL_Related_Node (New_Node, Last (Result));
4442 Set_SCIL_Entity (New_Node, Typ);
4443 Insert_Before (Last (Result), New_Node);
4447 Make_Attribute_Definition_Clause (Loc,
4448 Name => New_Reference_To (DT, Loc),
4449 Chars => Name_Alignment,
4451 Make_Attribute_Reference (Loc,
4453 New_Reference_To (RTE (RE_Integer_Address), Loc),
4454 Attribute_Name => Name_Alignment)));
4457 Make_Object_Declaration (Loc,
4458 Defining_Identifier => DT_Ptr,
4459 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4460 Constant_Present => True,
4462 Unchecked_Convert_To (RTE (RE_Tag),
4463 Make_Attribute_Reference (Loc,
4465 Make_Selected_Component (Loc,
4466 Prefix => New_Reference_To (DT, Loc),
4469 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
4470 Attribute_Name => Name_Address))));
4472 -- Generate the SCIL node for the previous object declaration
4473 -- because it has a tag initialization.
4475 if Generate_SCIL then
4477 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
4478 Set_SCIL_Related_Node (New_Node, Last (Result));
4479 Set_SCIL_Entity (New_Node, Typ);
4480 Insert_Before (Last (Result), New_Node);
4484 Make_Object_Declaration (Loc,
4485 Defining_Identifier =>
4486 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Typ)))),
4487 Constant_Present => True,
4488 Object_Definition => New_Reference_To
4489 (RTE (RE_Address), Loc),
4491 Make_Attribute_Reference (Loc,
4493 Make_Selected_Component (Loc,
4494 Prefix => New_Reference_To (DT, Loc),
4497 (RTE_Record_Component (RE_Predef_Prims), Loc)),
4498 Attribute_Name => Name_Address)));
4502 -- Generate: Exname : constant String := full_qualified_name (typ);
4503 -- The type itself may be an anonymous parent type, so use the first
4504 -- subtype to have a user-recognizable name.
4507 Make_Object_Declaration (Loc,
4508 Defining_Identifier => Exname,
4509 Constant_Present => True,
4510 Object_Definition => New_Reference_To (Standard_String, Loc),
4512 Make_String_Literal (Loc,
4513 Full_Qualified_Name (First_Subtype (Typ)))));
4515 Set_Is_Statically_Allocated (Exname);
4516 Set_Is_True_Constant (Exname);
4518 -- Declare the object used by Ada.Tags.Register_Tag
4520 if RTE_Available (RE_Register_Tag) then
4522 Make_Object_Declaration (Loc,
4523 Defining_Identifier => HT_Link,
4524 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc)));
4527 -- Generate code to create the storage for the type specific data object
4528 -- with enough space to store the tags of the ancestors plus the tags
4529 -- of all the implemented interfaces (as described in a-tags.adb).
4531 -- TSD : Type_Specific_Data (I_Depth) :=
4532 -- (Idepth => I_Depth,
4533 -- Access_Level => Type_Access_Level (Typ),
4534 -- Expanded_Name => Cstring_Ptr!(Exname'Address))
4535 -- External_Tag => Cstring_Ptr!(Exname'Address))
4536 -- HT_Link => HT_Link'Address,
4537 -- Transportable => <<boolean-value>>,
4538 -- RC_Offset => <<integer-value>>,
4539 -- [ Size_Func => Size_Prim'Access ]
4540 -- [ Interfaces_Table => <<access-value>> ]
4541 -- [ SSD => SSD_Table'Address ]
4542 -- Tags_Table => (0 => null,
4545 -- for TSD'Alignment use Address'Alignment
4547 TSD_Aggr_List := New_List;
4549 -- Idepth: Count ancestors to compute the inheritance depth. For private
4550 -- extensions, always go to the full view in order to compute the real
4551 -- inheritance depth.
4554 Current_Typ : Entity_Id;
4555 Parent_Typ : Entity_Id;
4561 Parent_Typ := Etype (Current_Typ);
4563 if Is_Private_Type (Parent_Typ) then
4564 Parent_Typ := Full_View (Base_Type (Parent_Typ));
4567 exit when Parent_Typ = Current_Typ;
4569 I_Depth := I_Depth + 1;
4570 Current_Typ := Parent_Typ;
4574 Append_To (TSD_Aggr_List,
4575 Make_Integer_Literal (Loc, I_Depth));
4579 Append_To (TSD_Aggr_List,
4580 Make_Integer_Literal (Loc, Type_Access_Level (Typ)));
4584 Append_To (TSD_Aggr_List,
4585 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4586 Make_Attribute_Reference (Loc,
4587 Prefix => New_Reference_To (Exname, Loc),
4588 Attribute_Name => Name_Address)));
4590 -- External_Tag of a local tagged type
4592 -- <typ>A : constant String :=
4593 -- "Internal tag at 16#tag-addr#: <full-name-of-typ>";
4595 -- The reason we generate this strange name is that we do not want to
4596 -- enter local tagged types in the global hash table used to compute
4597 -- the Internal_Tag attribute for two reasons:
4599 -- 1. It is hard to avoid a tasking race condition for entering the
4600 -- entry into the hash table.
4602 -- 2. It would cause a storage leak, unless we rig up considerable
4603 -- mechanism to remove the entry from the hash table on exit.
4605 -- So what we do is to generate the above external tag name, where the
4606 -- hex address is the address of the local dispatch table (i.e. exactly
4607 -- the value we want if Internal_Tag is computed from this string).
4609 -- Of course this value will only be valid if the tagged type is still
4610 -- in scope, but it clearly must be erroneous to compute the internal
4611 -- tag of a tagged type that is out of scope!
4613 -- We don't do this processing if an explicit external tag has been
4614 -- specified. That's an odd case for which we have already issued a
4615 -- warning, where we will not be able to compute the internal tag.
4617 if not Is_Library_Level_Entity (Typ)
4618 and then not Has_External_Tag_Rep_Clause (Typ)
4621 Exname : constant Entity_Id :=
4622 Make_Defining_Identifier (Loc,
4623 New_External_Name (Tname, 'A'));
4625 Full_Name : constant String_Id :=
4626 Full_Qualified_Name (First_Subtype (Typ));
4627 Str1_Id : String_Id;
4628 Str2_Id : String_Id;
4632 -- Str1 = "Internal tag at 16#";
4635 Store_String_Chars ("Internal tag at 16#");
4636 Str1_Id := End_String;
4639 -- Str2 = "#: <type-full-name>";
4642 Store_String_Chars ("#: ");
4643 Store_String_Chars (Full_Name);
4644 Str2_Id := End_String;
4647 -- Exname : constant String :=
4648 -- Str1 & Address_Image (Tag) & Str2;
4650 if RTE_Available (RE_Address_Image) then
4652 Make_Object_Declaration (Loc,
4653 Defining_Identifier => Exname,
4654 Constant_Present => True,
4655 Object_Definition => New_Reference_To
4656 (Standard_String, Loc),
4658 Make_Op_Concat (Loc,
4660 Make_String_Literal (Loc, Str1_Id),
4662 Make_Op_Concat (Loc,
4664 Make_Function_Call (Loc,
4667 (RTE (RE_Address_Image), Loc),
4668 Parameter_Associations => New_List (
4669 Unchecked_Convert_To (RTE (RE_Address),
4670 New_Reference_To (DT_Ptr, Loc)))),
4672 Make_String_Literal (Loc, Str2_Id)))));
4676 Make_Object_Declaration (Loc,
4677 Defining_Identifier => Exname,
4678 Constant_Present => True,
4679 Object_Definition => New_Reference_To
4680 (Standard_String, Loc),
4682 Make_Op_Concat (Loc,
4684 Make_String_Literal (Loc, Str1_Id),
4686 Make_String_Literal (Loc, Str2_Id))));
4690 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4691 Make_Attribute_Reference (Loc,
4692 Prefix => New_Reference_To (Exname, Loc),
4693 Attribute_Name => Name_Address));
4696 -- External tag of a library-level tagged type: Check for a definition
4697 -- of External_Tag. The clause is considered only if it applies to this
4698 -- specific tagged type, as opposed to one of its ancestors.
4699 -- If the type is an unconstrained type extension, we are building the
4700 -- dispatch table of its anonymous base type, so the external tag, if
4701 -- any was specified, must be retrieved from the first subtype. Go to
4702 -- the full view in case the clause is in the private part.
4706 Def : constant Node_Id := Get_Attribute_Definition_Clause
4707 (Underlying_Type (First_Subtype (Typ)),
4708 Attribute_External_Tag);
4710 Old_Val : String_Id;
4711 New_Val : String_Id;
4715 if not Present (Def)
4716 or else Entity (Name (Def)) /= First_Subtype (Typ)
4719 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4720 Make_Attribute_Reference (Loc,
4721 Prefix => New_Reference_To (Exname, Loc),
4722 Attribute_Name => Name_Address));
4724 Old_Val := Strval (Expr_Value_S (Expression (Def)));
4726 -- For the rep clause "for <typ>'external_tag use y" generate:
4728 -- <typ>A : constant string := y;
4730 -- <typ>A'Address is used to set the External_Tag component
4733 -- Create a new nul terminated string if it is not already
4735 if String_Length (Old_Val) > 0
4737 Get_String_Char (Old_Val, String_Length (Old_Val)) = 0
4741 Start_String (Old_Val);
4742 Store_String_Char (Get_Char_Code (ASCII.NUL));
4743 New_Val := End_String;
4746 E := Make_Defining_Identifier (Loc,
4747 New_External_Name (Chars (Typ), 'A'));
4750 Make_Object_Declaration (Loc,
4751 Defining_Identifier => E,
4752 Constant_Present => True,
4753 Object_Definition =>
4754 New_Reference_To (Standard_String, Loc),
4756 Make_String_Literal (Loc, New_Val)));
4759 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4760 Make_Attribute_Reference (Loc,
4761 Prefix => New_Reference_To (E, Loc),
4762 Attribute_Name => Name_Address));
4767 Append_To (TSD_Aggr_List, New_Node);
4771 if RTE_Available (RE_Register_Tag) then
4772 Append_To (TSD_Aggr_List,
4773 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
4774 Make_Attribute_Reference (Loc,
4775 Prefix => New_Reference_To (HT_Link, Loc),
4776 Attribute_Name => Name_Address)));
4778 Append_To (TSD_Aggr_List,
4779 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
4780 New_Reference_To (RTE (RE_Null_Address), Loc)));
4783 -- Transportable: Set for types that can be used in remote calls
4784 -- with respect to E.4(18) legality rules.
4787 Transportable : Entity_Id;
4793 or else Is_Shared_Passive (Typ)
4795 ((Is_Remote_Types (Typ)
4796 or else Is_Remote_Call_Interface (Typ))
4797 and then Original_View_In_Visible_Part (Typ))
4798 or else not Comes_From_Source (Typ));
4800 Append_To (TSD_Aggr_List,
4801 New_Occurrence_Of (Transportable, Loc));
4804 -- RC_Offset: These are the valid values and their meaning:
4806 -- >0: For simple types with controlled components is
4807 -- type._record_controller'position
4809 -- 0: For types with no controlled components
4811 -- -1: For complex types with controlled components where the position
4812 -- of the record controller is not statically computable but there
4813 -- are controlled components at this level. The _Controller field
4814 -- is available right after the _parent.
4816 -- -2: There are no controlled components at this level. We need to
4817 -- get the position from the parent.
4820 RC_Offset_Node : Node_Id;
4823 if not Has_Controlled_Component (Typ) then
4824 RC_Offset_Node := Make_Integer_Literal (Loc, 0);
4826 elsif Etype (Typ) /= Typ
4827 and then Has_Discriminants (Parent_Typ)
4829 if Has_New_Controlled_Component (Typ) then
4830 RC_Offset_Node := Make_Integer_Literal (Loc, -1);
4832 RC_Offset_Node := Make_Integer_Literal (Loc, -2);
4836 Make_Attribute_Reference (Loc,
4838 Make_Selected_Component (Loc,
4839 Prefix => New_Reference_To (Typ, Loc),
4841 New_Reference_To (Controller_Component (Typ), Loc)),
4842 Attribute_Name => Name_Position);
4844 -- This is not proper Ada code to use the attribute 'Position
4845 -- on something else than an object but this is supported by
4846 -- the back end (see comment on the Bit_Component attribute in
4847 -- sem_attr). So we avoid semantic checking here.
4849 -- Is this documented in sinfo.ads??? it should be!
4851 Set_Analyzed (RC_Offset_Node);
4852 Set_Etype (Prefix (RC_Offset_Node), RTE (RE_Record_Controller));
4853 Set_Etype (Prefix (Prefix (RC_Offset_Node)), Typ);
4854 Set_Etype (Selector_Name (Prefix (RC_Offset_Node)),
4855 RTE (RE_Record_Controller));
4856 Set_Etype (RC_Offset_Node, RTE (RE_Storage_Offset));
4859 Append_To (TSD_Aggr_List, RC_Offset_Node);
4864 if RTE_Record_Component_Available (RE_Size_Func) then
4865 if not Building_Static_DT (Typ)
4866 or else Is_Interface (Typ)
4868 Append_To (TSD_Aggr_List,
4869 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4870 New_Reference_To (RTE (RE_Null_Address), Loc)));
4874 Prim_Elmt : Elmt_Id;
4878 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4879 while Present (Prim_Elmt) loop
4880 Prim := Node (Prim_Elmt);
4882 if Chars (Prim) = Name_uSize then
4883 while Present (Alias (Prim)) loop
4884 Prim := Alias (Prim);
4887 if Is_Abstract_Subprogram (Prim) then
4888 Append_To (TSD_Aggr_List,
4889 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4890 New_Reference_To (RTE (RE_Null_Address), Loc)));
4892 Append_To (TSD_Aggr_List,
4893 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4894 Make_Attribute_Reference (Loc,
4895 Prefix => New_Reference_To (Prim, Loc),
4896 Attribute_Name => Name_Unrestricted_Access)));
4902 Next_Elmt (Prim_Elmt);
4908 -- Interfaces_Table (required for AI-405)
4910 if RTE_Record_Component_Available (RE_Interfaces_Table) then
4912 -- Count the number of interface types implemented by Typ
4914 Collect_Interfaces (Typ, Typ_Ifaces);
4916 AI := First_Elmt (Typ_Ifaces);
4917 while Present (AI) loop
4918 Num_Ifaces := Num_Ifaces + 1;
4922 if Num_Ifaces = 0 then
4923 Iface_Table_Node := Make_Null (Loc);
4925 -- Generate the Interface_Table object
4929 TSD_Ifaces_List : constant List_Id := New_List;
4931 Sec_DT_Tag : Node_Id;
4934 AI := First_Elmt (Typ_Ifaces);
4935 while Present (AI) loop
4936 if Is_Ancestor (Node (AI), Typ) then
4938 New_Reference_To (DT_Ptr, Loc);
4942 (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
4943 pragma Assert (Has_Thunks (Node (Elmt)));
4945 while Ekind (Node (Elmt)) = E_Constant
4947 Is_Ancestor (Node (AI), Related_Type (Node (Elmt)))
4949 pragma Assert (Has_Thunks (Node (Elmt)));
4951 pragma Assert (Has_Thunks (Node (Elmt)));
4953 pragma Assert (not Has_Thunks (Node (Elmt)));
4955 pragma Assert (not Has_Thunks (Node (Elmt)));
4959 pragma Assert (Ekind (Node (Elmt)) = E_Constant
4961 Has_Thunks (Node (Next_Elmt (Next_Elmt (Elmt)))));
4963 New_Reference_To (Node (Next_Elmt (Next_Elmt (Elmt))),
4967 Append_To (TSD_Ifaces_List,
4968 Make_Aggregate (Loc,
4969 Expressions => New_List (
4973 Unchecked_Convert_To (RTE (RE_Tag),
4975 (Node (First_Elmt (Access_Disp_Table (Node (AI)))),
4978 -- Static_Offset_To_Top
4980 New_Reference_To (Standard_True, Loc),
4982 -- Offset_To_Top_Value
4984 Make_Integer_Literal (Loc, 0),
4986 -- Offset_To_Top_Func
4992 Unchecked_Convert_To (RTE (RE_Tag), Sec_DT_Tag)
4999 Name_ITable := New_External_Name (Tname, 'I');
5000 ITable := Make_Defining_Identifier (Loc, Name_ITable);
5001 Set_Is_Statically_Allocated (ITable,
5002 Is_Library_Level_Tagged_Type (Typ));
5004 -- The table of interfaces is not constant; its slots are
5005 -- filled at run-time by the IP routine using attribute
5006 -- 'Position to know the location of the tag components
5007 -- (and this attribute cannot be safely used before the
5008 -- object is initialized).
5011 Make_Object_Declaration (Loc,
5012 Defining_Identifier => ITable,
5013 Aliased_Present => True,
5014 Constant_Present => False,
5015 Object_Definition =>
5016 Make_Subtype_Indication (Loc,
5018 New_Reference_To (RTE (RE_Interface_Data), Loc),
5019 Constraint => Make_Index_Or_Discriminant_Constraint
5021 Constraints => New_List (
5022 Make_Integer_Literal (Loc, Num_Ifaces)))),
5024 Expression => Make_Aggregate (Loc,
5025 Expressions => New_List (
5026 Make_Integer_Literal (Loc, Num_Ifaces),
5027 Make_Aggregate (Loc,
5028 Expressions => TSD_Ifaces_List)))));
5031 Make_Attribute_Definition_Clause (Loc,
5032 Name => New_Reference_To (ITable, Loc),
5033 Chars => Name_Alignment,
5035 Make_Attribute_Reference (Loc,
5037 New_Reference_To (RTE (RE_Integer_Address), Loc),
5038 Attribute_Name => Name_Alignment)));
5041 Make_Attribute_Reference (Loc,
5042 Prefix => New_Reference_To (ITable, Loc),
5043 Attribute_Name => Name_Unchecked_Access);
5047 Append_To (TSD_Aggr_List, Iface_Table_Node);
5050 -- Generate the Select Specific Data table for synchronized types that
5051 -- implement synchronized interfaces. The size of the table is
5052 -- constrained by the number of non-predefined primitive operations.
5054 if RTE_Record_Component_Available (RE_SSD) then
5055 if Ada_Version >= Ada_05
5056 and then Has_DT (Typ)
5057 and then Is_Concurrent_Record_Type (Typ)
5058 and then Has_Interfaces (Typ)
5059 and then Nb_Prim > 0
5060 and then not Is_Abstract_Type (Typ)
5061 and then not Is_Controlled (Typ)
5062 and then not Restriction_Active (No_Dispatching_Calls)
5063 and then not Restriction_Active (No_Select_Statements)
5066 Make_Object_Declaration (Loc,
5067 Defining_Identifier => SSD,
5068 Aliased_Present => True,
5069 Object_Definition =>
5070 Make_Subtype_Indication (Loc,
5071 Subtype_Mark => New_Reference_To (
5072 RTE (RE_Select_Specific_Data), Loc),
5074 Make_Index_Or_Discriminant_Constraint (Loc,
5075 Constraints => New_List (
5076 Make_Integer_Literal (Loc, Nb_Prim))))));
5079 Make_Attribute_Definition_Clause (Loc,
5080 Name => New_Reference_To (SSD, Loc),
5081 Chars => Name_Alignment,
5083 Make_Attribute_Reference (Loc,
5085 New_Reference_To (RTE (RE_Integer_Address), Loc),
5086 Attribute_Name => Name_Alignment)));
5088 -- This table is initialized by Make_Select_Specific_Data_Table,
5089 -- which calls Set_Entry_Index and Set_Prim_Op_Kind.
5091 Append_To (TSD_Aggr_List,
5092 Make_Attribute_Reference (Loc,
5093 Prefix => New_Reference_To (SSD, Loc),
5094 Attribute_Name => Name_Unchecked_Access));
5096 Append_To (TSD_Aggr_List, Make_Null (Loc));
5100 -- Initialize the table of ancestor tags. In case of interface types
5101 -- this table is not needed.
5103 TSD_Tags_List := New_List;
5105 -- If we are not statically allocating the dispatch table then we must
5106 -- fill position 0 with null because we still have not generated the
5109 if not Building_Static_DT (Typ)
5110 or else Is_Interface (Typ)
5112 Append_To (TSD_Tags_List,
5113 Unchecked_Convert_To (RTE (RE_Tag),
5114 New_Reference_To (RTE (RE_Null_Address), Loc)));
5116 -- Otherwise we can safely reference the tag
5119 Append_To (TSD_Tags_List,
5120 New_Reference_To (DT_Ptr, Loc));
5123 -- Fill the rest of the table with the tags of the ancestors
5126 Current_Typ : Entity_Id;
5127 Parent_Typ : Entity_Id;
5135 Parent_Typ := Etype (Current_Typ);
5137 if Is_Private_Type (Parent_Typ) then
5138 Parent_Typ := Full_View (Base_Type (Parent_Typ));
5141 exit when Parent_Typ = Current_Typ;
5143 if Is_CPP_Class (Parent_Typ)
5144 or else Is_Interface (Typ)
5146 -- The tags defined in the C++ side will be inherited when
5147 -- the object is constructed (Exp_Ch3.Build_Init_Procedure)
5149 Append_To (TSD_Tags_List,
5150 Unchecked_Convert_To (RTE (RE_Tag),
5151 New_Reference_To (RTE (RE_Null_Address), Loc)));
5153 Append_To (TSD_Tags_List,
5155 (Node (First_Elmt (Access_Disp_Table (Parent_Typ))),
5160 Current_Typ := Parent_Typ;
5163 pragma Assert (Pos = I_Depth + 1);
5166 Append_To (TSD_Aggr_List,
5167 Make_Aggregate (Loc,
5168 Expressions => TSD_Tags_List));
5170 -- Build the TSD object
5173 Make_Object_Declaration (Loc,
5174 Defining_Identifier => TSD,
5175 Aliased_Present => True,
5176 Constant_Present => Building_Static_DT (Typ),
5177 Object_Definition =>
5178 Make_Subtype_Indication (Loc,
5179 Subtype_Mark => New_Reference_To (
5180 RTE (RE_Type_Specific_Data), Loc),
5182 Make_Index_Or_Discriminant_Constraint (Loc,
5183 Constraints => New_List (
5184 Make_Integer_Literal (Loc, I_Depth)))),
5186 Expression => Make_Aggregate (Loc,
5187 Expressions => TSD_Aggr_List)));
5189 Set_Is_True_Constant (TSD, Building_Static_DT (Typ));
5192 Make_Attribute_Definition_Clause (Loc,
5193 Name => New_Reference_To (TSD, Loc),
5194 Chars => Name_Alignment,
5196 Make_Attribute_Reference (Loc,
5197 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
5198 Attribute_Name => Name_Alignment)));
5200 -- Initialize or declare the dispatch table object
5202 if not Has_DT (Typ) then
5203 DT_Constr_List := New_List;
5204 DT_Aggr_List := New_List;
5209 Make_Attribute_Reference (Loc,
5210 Prefix => New_Reference_To (TSD, Loc),
5211 Attribute_Name => Name_Address);
5213 Append_To (DT_Constr_List, New_Node);
5214 Append_To (DT_Aggr_List, New_Copy (New_Node));
5215 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
5217 -- In case of locally defined tagged types we have already declared
5218 -- and uninitialized object for the dispatch table, which is now
5219 -- initialized by means of the following assignment:
5221 -- DT := (TSD'Address, 0);
5223 if not Building_Static_DT (Typ) then
5225 Make_Assignment_Statement (Loc,
5226 Name => New_Reference_To (DT, Loc),
5227 Expression => Make_Aggregate (Loc,
5228 Expressions => DT_Aggr_List)));
5230 -- In case of library level tagged types we declare and export now
5231 -- the constant object containing the dummy dispatch table. There
5232 -- is no need to declare the tag here because it has been previously
5233 -- declared by Make_Tags
5235 -- DT : aliased constant No_Dispatch_Table :=
5236 -- (NDT_TSD => TSD'Address;
5237 -- NDT_Prims_Ptr => 0);
5238 -- for DT'Alignment use Address'Alignment;
5242 Make_Object_Declaration (Loc,
5243 Defining_Identifier => DT,
5244 Aliased_Present => True,
5245 Constant_Present => True,
5246 Object_Definition =>
5247 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc),
5248 Expression => Make_Aggregate (Loc,
5249 Expressions => DT_Aggr_List)));
5251 -- Generate the SCIL node for the previous object declaration
5252 -- because it has a null dispatch table.
5254 if Generate_SCIL then
5256 Make_SCIL_Dispatch_Table_Object_Init (Sloc (Last (Result)));
5257 Set_SCIL_Related_Node (New_Node, Last (Result));
5258 Set_SCIL_Entity (New_Node, Typ);
5259 Insert_Before (Last (Result), New_Node);
5263 Make_Attribute_Definition_Clause (Loc,
5264 Name => New_Reference_To (DT, Loc),
5265 Chars => Name_Alignment,
5267 Make_Attribute_Reference (Loc,
5269 New_Reference_To (RTE (RE_Integer_Address), Loc),
5270 Attribute_Name => Name_Alignment)));
5272 Export_DT (Typ, DT);
5275 -- Common case: Typ has a dispatch table
5279 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
5280 -- (predef-prim-op-1'address,
5281 -- predef-prim-op-2'address,
5283 -- predef-prim-op-n'address);
5284 -- for Predef_Prims'Alignment use Address'Alignment
5286 -- DT : Dispatch_Table (Nb_Prims) :=
5287 -- (Signature => <sig-value>,
5288 -- Tag_Kind => <tag_kind-value>,
5289 -- Predef_Prims => Predef_Prims'First'Address,
5290 -- Offset_To_Top => 0,
5291 -- TSD => TSD'Address;
5292 -- Prims_Ptr => (prim-op-1'address,
5293 -- prim-op-2'address,
5295 -- prim-op-n'address));
5296 -- for DT'Alignment use Address'Alignment
5303 if not Building_Static_DT (Typ) then
5304 Nb_Predef_Prims := Max_Predef_Prims;
5307 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5308 while Present (Prim_Elmt) loop
5309 Prim := Node (Prim_Elmt);
5311 if Is_Predefined_Dispatching_Operation (Prim)
5312 and then not Is_Abstract_Subprogram (Prim)
5314 Pos := UI_To_Int (DT_Position (Prim));
5316 if Pos > Nb_Predef_Prims then
5317 Nb_Predef_Prims := Pos;
5321 Next_Elmt (Prim_Elmt);
5327 (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
5332 Prim_Ops_Aggr_List := New_List;
5334 Prim_Table := (others => Empty);
5336 if Building_Static_DT (Typ) then
5337 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5338 while Present (Prim_Elmt) loop
5339 Prim := Node (Prim_Elmt);
5341 if Is_Predefined_Dispatching_Operation (Prim)
5342 and then not Is_Abstract_Subprogram (Prim)
5343 and then not Present (Prim_Table
5344 (UI_To_Int (DT_Position (Prim))))
5347 while Present (Alias (E)) loop
5351 pragma Assert (not Is_Abstract_Subprogram (E));
5352 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
5355 Next_Elmt (Prim_Elmt);
5359 for J in Prim_Table'Range loop
5360 if Present (Prim_Table (J)) then
5362 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
5363 Make_Attribute_Reference (Loc,
5364 Prefix => New_Reference_To (Prim_Table (J), Loc),
5365 Attribute_Name => Name_Unrestricted_Access));
5367 New_Node := Make_Null (Loc);
5370 Append_To (Prim_Ops_Aggr_List, New_Node);
5374 Make_Aggregate (Loc,
5375 Expressions => Prim_Ops_Aggr_List);
5378 Make_Subtype_Declaration (Loc,
5379 Defining_Identifier =>
5380 Make_Defining_Identifier (Loc,
5381 New_Internal_Name ('S')),
5382 Subtype_Indication =>
5383 New_Reference_To (RTE (RE_Address_Array), Loc));
5385 Append_To (Result, Decl);
5388 Make_Object_Declaration (Loc,
5389 Defining_Identifier => Predef_Prims,
5390 Aliased_Present => True,
5391 Constant_Present => Building_Static_DT (Typ),
5392 Object_Definition => New_Reference_To
5393 (Defining_Identifier (Decl), Loc),
5394 Expression => New_Node));
5396 -- Remember aggregates initializing dispatch tables
5398 Append_Elmt (New_Node, DT_Aggr);
5401 Make_Attribute_Definition_Clause (Loc,
5402 Name => New_Reference_To (Predef_Prims, Loc),
5403 Chars => Name_Alignment,
5405 Make_Attribute_Reference (Loc,
5407 New_Reference_To (RTE (RE_Integer_Address), Loc),
5408 Attribute_Name => Name_Alignment)));
5412 -- Stage 1: Initialize the discriminant and the record components
5414 DT_Constr_List := New_List;
5415 DT_Aggr_List := New_List;
5417 -- Num_Prims. If the tagged type has no primitives we add a dummy
5418 -- slot whose address will be the tag of this type.
5421 New_Node := Make_Integer_Literal (Loc, 1);
5423 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
5426 Append_To (DT_Constr_List, New_Node);
5427 Append_To (DT_Aggr_List, New_Copy (New_Node));
5431 if RTE_Record_Component_Available (RE_Signature) then
5432 Append_To (DT_Aggr_List,
5433 New_Reference_To (RTE (RE_Primary_DT), Loc));
5438 if RTE_Record_Component_Available (RE_Tag_Kind) then
5439 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
5444 Append_To (DT_Aggr_List,
5445 Make_Attribute_Reference (Loc,
5446 Prefix => New_Reference_To (Predef_Prims, Loc),
5447 Attribute_Name => Name_Address));
5451 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
5455 Append_To (DT_Aggr_List,
5456 Make_Attribute_Reference (Loc,
5457 Prefix => New_Reference_To (TSD, Loc),
5458 Attribute_Name => Name_Address));
5460 -- Stage 2: Initialize the table of primitive operations
5462 Prim_Ops_Aggr_List := New_List;
5465 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
5467 elsif not Building_Static_DT (Typ) then
5468 for J in 1 .. Nb_Prim loop
5469 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
5474 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
5477 Prim_Elmt : Elmt_Id;
5480 Prim_Table := (others => Empty);
5482 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5483 while Present (Prim_Elmt) loop
5484 Prim := Node (Prim_Elmt);
5486 -- Retrieve the ultimate alias of the primitive for proper
5487 -- handling of renamings and eliminated primitives.
5489 E := Ultimate_Alias (Prim);
5491 if Is_Imported (Prim)
5492 or else Present (Interface_Alias (Prim))
5493 or else Is_Predefined_Dispatching_Operation (Prim)
5494 or else Is_Eliminated (E)
5499 if not Is_Predefined_Dispatching_Operation (E)
5500 and then not Is_Abstract_Subprogram (E)
5501 and then not Present (Interface_Alias (E))
5504 (UI_To_Int (DT_Position (Prim)) <= Nb_Prim);
5506 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
5510 Next_Elmt (Prim_Elmt);
5513 for J in Prim_Table'Range loop
5514 if Present (Prim_Table (J)) then
5516 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
5517 Make_Attribute_Reference (Loc,
5518 Prefix => New_Reference_To (Prim_Table (J), Loc),
5519 Attribute_Name => Name_Unrestricted_Access));
5521 New_Node := Make_Null (Loc);
5524 Append_To (Prim_Ops_Aggr_List, New_Node);
5530 Make_Aggregate (Loc,
5531 Expressions => Prim_Ops_Aggr_List);
5533 Append_To (DT_Aggr_List, New_Node);
5535 -- Remember aggregates initializing dispatch tables
5537 Append_Elmt (New_Node, DT_Aggr);
5539 -- In case of locally defined tagged types we have already declared
5540 -- and uninitialized object for the dispatch table, which is now
5541 -- initialized by means of an assignment.
5543 if not Building_Static_DT (Typ) then
5545 Make_Assignment_Statement (Loc,
5546 Name => New_Reference_To (DT, Loc),
5547 Expression => Make_Aggregate (Loc,
5548 Expressions => DT_Aggr_List)));
5550 -- In case of library level tagged types we declare now and export
5551 -- the constant object containing the dispatch table.
5555 Make_Object_Declaration (Loc,
5556 Defining_Identifier => DT,
5557 Aliased_Present => True,
5558 Constant_Present => True,
5559 Object_Definition =>
5560 Make_Subtype_Indication (Loc,
5561 Subtype_Mark => New_Reference_To
5562 (RTE (RE_Dispatch_Table_Wrapper), Loc),
5563 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
5564 Constraints => DT_Constr_List)),
5565 Expression => Make_Aggregate (Loc,
5566 Expressions => DT_Aggr_List)));
5568 -- Generate the SCIL node for the previous object declaration
5569 -- because it contains a dispatch table.
5571 if Generate_SCIL then
5573 Make_SCIL_Dispatch_Table_Object_Init (Sloc (Last (Result)));
5574 Set_SCIL_Related_Node (New_Node, Last (Result));
5575 Set_SCIL_Entity (New_Node, Typ);
5576 Insert_Before (Last (Result), New_Node);
5580 Make_Attribute_Definition_Clause (Loc,
5581 Name => New_Reference_To (DT, Loc),
5582 Chars => Name_Alignment,
5584 Make_Attribute_Reference (Loc,
5586 New_Reference_To (RTE (RE_Integer_Address), Loc),
5587 Attribute_Name => Name_Alignment)));
5589 Export_DT (Typ, DT);
5593 -- Initialize the table of ancestor tags if not building static
5596 if not Building_Static_DT (Typ)
5597 and then not Is_Interface (Typ)
5598 and then not Is_CPP_Class (Typ)
5601 Make_Assignment_Statement (Loc,
5603 Make_Indexed_Component (Loc,
5605 Make_Selected_Component (Loc,
5607 New_Reference_To (TSD, Loc),
5610 (RTE_Record_Component (RE_Tags_Table), Loc)),
5612 New_List (Make_Integer_Literal (Loc, 0))),
5616 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)));
5619 -- Inherit the dispatch tables of the parent. There is no need to
5620 -- inherit anything from the parent when building static dispatch tables
5621 -- because the whole dispatch table (including inherited primitives) has
5622 -- been already built.
5624 if Building_Static_DT (Typ) then
5627 -- If the ancestor is a CPP_Class type we inherit the dispatch tables
5628 -- in the init proc, and we don't need to fill them in here.
5630 elsif Is_CPP_Class (Parent_Typ) then
5633 -- Otherwise we fill in the dispatch tables here
5636 if Typ /= Parent_Typ
5637 and then not Is_Interface (Typ)
5638 and then not Restriction_Active (No_Dispatching_Calls)
5640 -- Inherit the dispatch table
5642 if not Is_Interface (Typ)
5643 and then not Is_Interface (Parent_Typ)
5644 and then not Is_CPP_Class (Parent_Typ)
5647 Nb_Prims : constant Int :=
5648 UI_To_Int (DT_Entry_Count
5649 (First_Tag_Component (Parent_Typ)));
5652 Append_To (Elab_Code,
5653 Build_Inherit_Predefined_Prims (Loc,
5659 (Access_Disp_Table (Parent_Typ)))), Loc),
5665 (Access_Disp_Table (Typ)))), Loc)));
5667 if Nb_Prims /= 0 then
5668 Append_To (Elab_Code,
5669 Build_Inherit_Prims (Loc,
5675 (Access_Disp_Table (Parent_Typ))), Loc),
5676 New_Tag_Node => New_Reference_To (DT_Ptr, Loc),
5677 Num_Prims => Nb_Prims));
5682 -- Inherit the secondary dispatch tables of the ancestor
5684 if not Is_CPP_Class (Parent_Typ) then
5686 Sec_DT_Ancestor : Elmt_Id :=
5690 (Access_Disp_Table (Parent_Typ))));
5691 Sec_DT_Typ : Elmt_Id :=
5695 (Access_Disp_Table (Typ))));
5697 procedure Copy_Secondary_DTs (Typ : Entity_Id);
5698 -- Local procedure required to climb through the ancestors
5699 -- and copy the contents of all their secondary dispatch
5702 ------------------------
5703 -- Copy_Secondary_DTs --
5704 ------------------------
5706 procedure Copy_Secondary_DTs (Typ : Entity_Id) is
5711 -- Climb to the ancestor (if any) handling private types
5713 if Present (Full_View (Etype (Typ))) then
5714 if Full_View (Etype (Typ)) /= Typ then
5715 Copy_Secondary_DTs (Full_View (Etype (Typ)));
5718 elsif Etype (Typ) /= Typ then
5719 Copy_Secondary_DTs (Etype (Typ));
5722 if Present (Interfaces (Typ))
5723 and then not Is_Empty_Elmt_List (Interfaces (Typ))
5725 Iface := First_Elmt (Interfaces (Typ));
5726 E := First_Entity (Typ);
5728 and then Present (Node (Sec_DT_Ancestor))
5729 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
5731 if Is_Tag (E) and then Chars (E) /= Name_uTag then
5733 Num_Prims : constant Int :=
5734 UI_To_Int (DT_Entry_Count (E));
5737 if not Is_Interface (Etype (Typ)) then
5739 -- Inherit first secondary dispatch table
5741 Append_To (Elab_Code,
5742 Build_Inherit_Predefined_Prims (Loc,
5744 Unchecked_Convert_To (RTE (RE_Tag),
5747 (Next_Elmt (Sec_DT_Ancestor)),
5750 Unchecked_Convert_To (RTE (RE_Tag),
5752 (Node (Next_Elmt (Sec_DT_Typ)),
5755 if Num_Prims /= 0 then
5756 Append_To (Elab_Code,
5757 Build_Inherit_Prims (Loc,
5758 Typ => Node (Iface),
5760 Unchecked_Convert_To
5763 (Node (Sec_DT_Ancestor),
5766 Unchecked_Convert_To
5769 (Node (Sec_DT_Typ), Loc)),
5770 Num_Prims => Num_Prims));
5774 Next_Elmt (Sec_DT_Ancestor);
5775 Next_Elmt (Sec_DT_Typ);
5777 -- Skip the secondary dispatch table of
5778 -- predefined primitives
5780 Next_Elmt (Sec_DT_Ancestor);
5781 Next_Elmt (Sec_DT_Typ);
5783 if not Is_Interface (Etype (Typ)) then
5785 -- Inherit second secondary dispatch table
5787 Append_To (Elab_Code,
5788 Build_Inherit_Predefined_Prims (Loc,
5790 Unchecked_Convert_To (RTE (RE_Tag),
5793 (Next_Elmt (Sec_DT_Ancestor)),
5796 Unchecked_Convert_To (RTE (RE_Tag),
5798 (Node (Next_Elmt (Sec_DT_Typ)),
5801 if Num_Prims /= 0 then
5802 Append_To (Elab_Code,
5803 Build_Inherit_Prims (Loc,
5804 Typ => Node (Iface),
5806 Unchecked_Convert_To
5809 (Node (Sec_DT_Ancestor),
5812 Unchecked_Convert_To
5815 (Node (Sec_DT_Typ), Loc)),
5816 Num_Prims => Num_Prims));
5821 Next_Elmt (Sec_DT_Ancestor);
5822 Next_Elmt (Sec_DT_Typ);
5824 -- Skip the secondary dispatch table of
5825 -- predefined primitives
5827 Next_Elmt (Sec_DT_Ancestor);
5828 Next_Elmt (Sec_DT_Typ);
5836 end Copy_Secondary_DTs;
5839 if Present (Node (Sec_DT_Ancestor))
5840 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
5842 -- Handle private types
5844 if Present (Full_View (Typ)) then
5845 Copy_Secondary_DTs (Full_View (Typ));
5847 Copy_Secondary_DTs (Typ);
5855 -- Generate code to register the Tag in the External_Tag hash table for
5856 -- the pure Ada type only.
5858 -- Register_Tag (Dt_Ptr);
5860 -- Skip this action in the following cases:
5861 -- 1) if Register_Tag is not available.
5862 -- 2) in No_Run_Time mode.
5863 -- 3) if Typ is not defined at the library level (this is required
5864 -- to avoid adding concurrency control to the hash table used
5865 -- by the run-time to register the tags).
5867 if not No_Run_Time_Mode
5868 and then Is_Library_Level_Entity (Typ)
5869 and then RTE_Available (RE_Register_Tag)
5871 Append_To (Elab_Code,
5872 Make_Procedure_Call_Statement (Loc,
5873 Name => New_Reference_To (RTE (RE_Register_Tag), Loc),
5874 Parameter_Associations =>
5875 New_List (New_Reference_To (DT_Ptr, Loc))));
5878 if not Is_Empty_List (Elab_Code) then
5879 Append_List_To (Result, Elab_Code);
5882 -- Populate the two auxiliary tables used for dispatching asynchronous,
5883 -- conditional and timed selects for synchronized types that implement
5884 -- a limited interface. Skip this step in Ravenscar profile or when
5885 -- general dispatching is forbidden.
5887 if Ada_Version >= Ada_05
5888 and then Is_Concurrent_Record_Type (Typ)
5889 and then Has_Interfaces (Typ)
5890 and then not Restriction_Active (No_Dispatching_Calls)
5891 and then not Restriction_Active (No_Select_Statements)
5893 Append_List_To (Result,
5894 Make_Select_Specific_Data_Table (Typ));
5897 -- Remember entities containing dispatch tables
5899 Append_Elmt (Predef_Prims, DT_Decl);
5900 Append_Elmt (DT, DT_Decl);
5902 Analyze_List (Result, Suppress => All_Checks);
5903 Set_Has_Dispatch_Table (Typ);
5905 -- Mark entities containing dispatch tables. Required by the backend to
5906 -- handle them properly.
5908 if not Is_Interface (Typ) then
5913 -- Ensure that entities Prim_Ptr and Predef_Prims_Table_Ptr have
5914 -- the decoration required by the backend
5916 Set_Is_Dispatch_Table_Entity (RTE (RE_Prim_Ptr));
5917 Set_Is_Dispatch_Table_Entity (RTE (RE_Predef_Prims_Table_Ptr));
5919 -- Object declarations
5921 Elmt := First_Elmt (DT_Decl);
5922 while Present (Elmt) loop
5923 Set_Is_Dispatch_Table_Entity (Node (Elmt));
5924 pragma Assert (Ekind (Etype (Node (Elmt))) = E_Array_Subtype
5925 or else Ekind (Etype (Node (Elmt))) = E_Record_Subtype);
5926 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
5930 -- Aggregates initializing dispatch tables
5932 Elmt := First_Elmt (DT_Aggr);
5933 while Present (Elmt) loop
5934 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
5943 -------------------------------------
5944 -- Make_Select_Specific_Data_Table --
5945 -------------------------------------
5947 function Make_Select_Specific_Data_Table
5948 (Typ : Entity_Id) return List_Id
5950 Assignments : constant List_Id := New_List;
5951 Loc : constant Source_Ptr := Sloc (Typ);
5953 Conc_Typ : Entity_Id;
5957 Prim_Als : Entity_Id;
5958 Prim_Elmt : Elmt_Id;
5962 type Examined_Array is array (Int range <>) of Boolean;
5964 function Find_Entry_Index (E : Entity_Id) return Uint;
5965 -- Given an entry, find its index in the visible declarations of the
5966 -- corresponding concurrent type of Typ.
5968 ----------------------
5969 -- Find_Entry_Index --
5970 ----------------------
5972 function Find_Entry_Index (E : Entity_Id) return Uint is
5973 Index : Uint := Uint_1;
5974 Subp_Decl : Entity_Id;
5978 and then not Is_Empty_List (Decls)
5980 Subp_Decl := First (Decls);
5981 while Present (Subp_Decl) loop
5982 if Nkind (Subp_Decl) = N_Entry_Declaration then
5983 if Defining_Identifier (Subp_Decl) = E then
5995 end Find_Entry_Index;
5997 -- Start of processing for Make_Select_Specific_Data_Table
6000 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
6002 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
6004 if Present (Corresponding_Concurrent_Type (Typ)) then
6005 Conc_Typ := Corresponding_Concurrent_Type (Typ);
6007 if Present (Full_View (Conc_Typ)) then
6008 Conc_Typ := Full_View (Conc_Typ);
6011 if Ekind (Conc_Typ) = E_Protected_Type then
6012 Decls := Visible_Declarations (Protected_Definition (
6013 Parent (Conc_Typ)));
6015 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
6016 Decls := Visible_Declarations (Task_Definition (
6017 Parent (Conc_Typ)));
6021 -- Count the non-predefined primitive operations
6023 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6024 while Present (Prim_Elmt) loop
6025 Prim := Node (Prim_Elmt);
6027 if not (Is_Predefined_Dispatching_Operation (Prim)
6028 or else Is_Predefined_Dispatching_Alias (Prim))
6030 Nb_Prim := Nb_Prim + 1;
6033 Next_Elmt (Prim_Elmt);
6037 Examined : Examined_Array (1 .. Nb_Prim) := (others => False);
6040 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6041 while Present (Prim_Elmt) loop
6042 Prim := Node (Prim_Elmt);
6044 -- Look for primitive overriding an abstract interface subprogram
6046 if Present (Interface_Alias (Prim))
6047 and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
6049 Prim_Pos := DT_Position (Alias (Prim));
6050 pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
6051 Examined (UI_To_Int (Prim_Pos)) := True;
6053 -- Set the primitive operation kind regardless of subprogram
6055 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
6057 Append_To (Assignments,
6058 Make_Procedure_Call_Statement (Loc,
6059 Name => New_Reference_To (RTE (RE_Set_Prim_Op_Kind), Loc),
6060 Parameter_Associations => New_List (
6061 New_Reference_To (DT_Ptr, Loc),
6062 Make_Integer_Literal (Loc, Prim_Pos),
6063 Prim_Op_Kind (Alias (Prim), Typ))));
6065 -- Retrieve the root of the alias chain
6068 while Present (Alias (Prim_Als)) loop
6069 Prim_Als := Alias (Prim_Als);
6072 -- In the case of an entry wrapper, set the entry index
6074 if Ekind (Prim) = E_Procedure
6075 and then Is_Primitive_Wrapper (Prim_Als)
6076 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
6079 -- Ada.Tags.Set_Entry_Index
6080 -- (DT_Ptr, <position>, <index>);
6082 Append_To (Assignments,
6083 Make_Procedure_Call_Statement (Loc,
6085 New_Reference_To (RTE (RE_Set_Entry_Index), Loc),
6086 Parameter_Associations => New_List (
6087 New_Reference_To (DT_Ptr, Loc),
6088 Make_Integer_Literal (Loc, Prim_Pos),
6089 Make_Integer_Literal (Loc,
6090 Find_Entry_Index (Wrapped_Entity (Prim_Als))))));
6094 Next_Elmt (Prim_Elmt);
6099 end Make_Select_Specific_Data_Table;
6105 function Make_Tags (Typ : Entity_Id) return List_Id is
6106 Loc : constant Source_Ptr := Sloc (Typ);
6107 Result : constant List_Id := New_List;
6110 (Tag_Typ : Entity_Id;
6112 Is_Secondary_DT : Boolean);
6113 -- Import the dispatch table DT of tagged type Tag_Typ. Required to
6114 -- generate forward references and statically allocate the table. For
6115 -- primary dispatch tables that require no dispatch table generate:
6116 -- DT : static aliased constant Non_Dispatch_Table_Wrapper;
6117 -- $pragma import (ada, DT);
6118 -- Otherwise generate:
6119 -- DT : static aliased constant Dispatch_Table_Wrapper (Nb_Prim);
6120 -- $pragma import (ada, DT);
6127 (Tag_Typ : Entity_Id;
6129 Is_Secondary_DT : Boolean)
6131 DT_Constr_List : List_Id;
6135 Set_Is_Imported (DT);
6136 Set_Ekind (DT, E_Constant);
6137 Set_Related_Type (DT, Typ);
6139 -- The scope must be set now to call Get_External_Name
6141 Set_Scope (DT, Current_Scope);
6143 Get_External_Name (DT, True);
6144 Set_Interface_Name (DT,
6145 Make_String_Literal (Loc,
6146 Strval => String_From_Name_Buffer));
6148 -- Ensure proper Sprint output of this implicit importation
6150 Set_Is_Internal (DT);
6152 -- Save this entity to allow Make_DT to generate its exportation
6154 Append_Elmt (DT, Dispatch_Table_Wrappers (Typ));
6156 -- No dispatch table required
6158 if not Is_Secondary_DT
6159 and then not Has_DT (Tag_Typ)
6162 Make_Object_Declaration (Loc,
6163 Defining_Identifier => DT,
6164 Aliased_Present => True,
6165 Constant_Present => True,
6166 Object_Definition =>
6167 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
6170 -- Calculate the number of primitives of the dispatch table and
6171 -- the size of the Type_Specific_Data record.
6174 UI_To_Int (DT_Entry_Count (First_Tag_Component (Tag_Typ)));
6176 -- If the tagged type has no primitives we add a dummy slot
6177 -- whose address will be the tag of this type.
6181 New_List (Make_Integer_Literal (Loc, 1));
6184 New_List (Make_Integer_Literal (Loc, Nb_Prim));
6188 Make_Object_Declaration (Loc,
6189 Defining_Identifier => DT,
6190 Aliased_Present => True,
6191 Constant_Present => True,
6192 Object_Definition =>
6193 Make_Subtype_Indication (Loc,
6195 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
6196 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
6197 Constraints => DT_Constr_List))));
6203 Tname : constant Name_Id := Chars (Typ);
6204 AI_Tag_Comp : Elmt_Id;
6207 Predef_Prims_Ptr : Node_Id;
6209 Iface_DT_Ptr : Node_Id;
6213 Typ_Comps : Elist_Id;
6215 -- Start of processing for Make_Tags
6218 -- 1) Generate the primary and secondary tag entities
6220 -- Collect the components associated with secondary dispatch tables
6222 if Has_Interfaces (Typ) then
6223 Collect_Interface_Components (Typ, Typ_Comps);
6226 -- 1) Generate the primary tag entities
6228 -- Primary dispatch table containing user-defined primitives
6230 DT_Ptr := Make_Defining_Identifier (Loc,
6231 New_External_Name (Tname, 'P'));
6232 Set_Etype (DT_Ptr, RTE (RE_Tag));
6234 -- Primary dispatch table containing predefined primitives
6237 Make_Defining_Identifier (Loc,
6238 Chars => New_External_Name (Tname, 'Y'));
6239 Set_Etype (Predef_Prims_Ptr, RTE (RE_Address));
6241 -- Import the forward declaration of the Dispatch Table wrapper record
6242 -- (Make_DT will take care of its exportation)
6244 if Building_Static_DT (Typ) then
6245 Set_Dispatch_Table_Wrappers (Typ, New_Elmt_List);
6248 Make_Defining_Identifier (Loc,
6249 Chars => New_External_Name (Tname, 'T'));
6251 Import_DT (Typ, DT, Is_Secondary_DT => False);
6253 if Has_DT (Typ) then
6255 Make_Object_Declaration (Loc,
6256 Defining_Identifier => DT_Ptr,
6257 Constant_Present => True,
6258 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
6260 Unchecked_Convert_To (RTE (RE_Tag),
6261 Make_Attribute_Reference (Loc,
6263 Make_Selected_Component (Loc,
6264 Prefix => New_Reference_To (DT, Loc),
6267 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
6268 Attribute_Name => Name_Address))));
6270 -- Generate the SCIL node for the previous object declaration
6271 -- because it has a tag initialization.
6273 if Generate_SCIL then
6275 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
6276 Set_SCIL_Related_Node (New_Node, Last (Result));
6277 Set_SCIL_Entity (New_Node, Typ);
6278 Insert_Before (Last (Result), New_Node);
6282 Make_Object_Declaration (Loc,
6283 Defining_Identifier => Predef_Prims_Ptr,
6284 Constant_Present => True,
6285 Object_Definition => New_Reference_To
6286 (RTE (RE_Address), Loc),
6288 Make_Attribute_Reference (Loc,
6290 Make_Selected_Component (Loc,
6291 Prefix => New_Reference_To (DT, Loc),
6294 (RTE_Record_Component (RE_Predef_Prims), Loc)),
6295 Attribute_Name => Name_Address)));
6297 -- No dispatch table required
6301 Make_Object_Declaration (Loc,
6302 Defining_Identifier => DT_Ptr,
6303 Constant_Present => True,
6304 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
6306 Unchecked_Convert_To (RTE (RE_Tag),
6307 Make_Attribute_Reference (Loc,
6309 Make_Selected_Component (Loc,
6310 Prefix => New_Reference_To (DT, Loc),
6313 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
6314 Attribute_Name => Name_Address))));
6316 -- Generate the SCIL node for the previous object declaration
6317 -- because it has a tag initialization.
6319 if Generate_SCIL then
6321 Make_SCIL_Dispatch_Table_Object_Init (Sloc (Last (Result)));
6322 Set_SCIL_Related_Node (New_Node, Last (Result));
6323 Set_SCIL_Entity (New_Node, Typ);
6324 Insert_Before (Last (Result), New_Node);
6328 Set_Is_True_Constant (DT_Ptr);
6329 Set_Is_Statically_Allocated (DT_Ptr);
6332 pragma Assert (No (Access_Disp_Table (Typ)));
6333 Set_Access_Disp_Table (Typ, New_Elmt_List);
6334 Append_Elmt (DT_Ptr, Access_Disp_Table (Typ));
6335 Append_Elmt (Predef_Prims_Ptr, Access_Disp_Table (Typ));
6337 -- 2) Generate the secondary tag entities
6339 if Has_Interfaces (Typ) then
6341 -- Note: The following value of Suffix_Index must be in sync with
6342 -- the Suffix_Index values of secondary dispatch tables generated
6347 -- For each interface type we build an unique external name
6348 -- associated with its corresponding secondary dispatch table.
6349 -- This external name will be used to declare an object that
6350 -- references this secondary dispatch table, value that will be
6351 -- used for the elaboration of Typ's objects and also for the
6352 -- elaboration of objects of derivations of Typ that do not
6353 -- override the primitive operation of this interface type.
6355 AI_Tag_Comp := First_Elmt (Typ_Comps);
6356 while Present (AI_Tag_Comp) loop
6357 Get_Secondary_DT_External_Name
6358 (Typ, Related_Type (Node (AI_Tag_Comp)), Suffix_Index);
6359 Typ_Name := Name_Find;
6361 if Building_Static_DT (Typ) then
6363 Make_Defining_Identifier (Loc,
6364 Chars => New_External_Name
6365 (Typ_Name, 'T', Suffix_Index => -1));
6367 (Tag_Typ => Related_Type (Node (AI_Tag_Comp)),
6369 Is_Secondary_DT => True);
6372 -- Secondary dispatch table referencing thunks to user-defined
6373 -- primitives covered by this interface.
6376 Make_Defining_Identifier (Loc,
6377 Chars => New_External_Name (Typ_Name, 'P'));
6378 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
6379 Set_Ekind (Iface_DT_Ptr, E_Constant);
6380 Set_Is_Tag (Iface_DT_Ptr);
6381 Set_Has_Thunks (Iface_DT_Ptr);
6382 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6383 Is_Library_Level_Tagged_Type (Typ));
6384 Set_Is_True_Constant (Iface_DT_Ptr);
6386 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6387 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6389 if Building_Static_DT (Typ) then
6391 Make_Object_Declaration (Loc,
6392 Defining_Identifier => Iface_DT_Ptr,
6393 Constant_Present => True,
6394 Object_Definition => New_Reference_To
6395 (RTE (RE_Interface_Tag), Loc),
6397 Unchecked_Convert_To (RTE (RE_Interface_Tag),
6398 Make_Attribute_Reference (Loc,
6400 Make_Selected_Component (Loc,
6401 Prefix => New_Reference_To (Iface_DT, Loc),
6404 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
6405 Attribute_Name => Name_Address))));
6408 -- Secondary dispatch table referencing thunks to predefined
6412 Make_Defining_Identifier (Loc,
6413 Chars => New_External_Name (Typ_Name, 'Y'));
6414 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
6415 Set_Ekind (Iface_DT_Ptr, E_Constant);
6416 Set_Is_Tag (Iface_DT_Ptr);
6417 Set_Has_Thunks (Iface_DT_Ptr);
6418 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6419 Is_Library_Level_Tagged_Type (Typ));
6420 Set_Is_True_Constant (Iface_DT_Ptr);
6422 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6423 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6425 -- Secondary dispatch table referencing user-defined primitives
6426 -- covered by this interface.
6429 Make_Defining_Identifier (Loc,
6430 Chars => New_External_Name (Typ_Name, 'D'));
6431 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
6432 Set_Ekind (Iface_DT_Ptr, E_Constant);
6433 Set_Is_Tag (Iface_DT_Ptr);
6434 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6435 Is_Library_Level_Tagged_Type (Typ));
6436 Set_Is_True_Constant (Iface_DT_Ptr);
6438 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6439 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6441 -- Secondary dispatch table referencing predefined primitives
6444 Make_Defining_Identifier (Loc,
6445 Chars => New_External_Name (Typ_Name, 'Z'));
6446 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
6447 Set_Ekind (Iface_DT_Ptr, E_Constant);
6448 Set_Is_Tag (Iface_DT_Ptr);
6449 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6450 Is_Library_Level_Tagged_Type (Typ));
6451 Set_Is_True_Constant (Iface_DT_Ptr);
6453 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6454 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6456 Next_Elmt (AI_Tag_Comp);
6460 -- 3) At the end of Access_Disp_Table, if the type has user-defined
6461 -- primitives, we add the entity of an access type declaration that
6462 -- is used by Build_Get_Prim_Op_Address to expand dispatching calls
6463 -- through the primary dispatch table.
6465 if UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ))) = 0 then
6466 Analyze_List (Result);
6469 -- type Typ_DT is array (1 .. Nb_Prims) of Prim_Ptr;
6470 -- type Typ_DT_Acc is access Typ_DT;
6474 Name_DT_Prims : constant Name_Id :=
6475 New_External_Name (Tname, 'G');
6476 Name_DT_Prims_Acc : constant Name_Id :=
6477 New_External_Name (Tname, 'H');
6478 DT_Prims : constant Entity_Id :=
6479 Make_Defining_Identifier (Loc,
6481 DT_Prims_Acc : constant Entity_Id :=
6482 Make_Defining_Identifier (Loc,
6486 Make_Full_Type_Declaration (Loc,
6487 Defining_Identifier => DT_Prims,
6489 Make_Constrained_Array_Definition (Loc,
6490 Discrete_Subtype_Definitions => New_List (
6492 Low_Bound => Make_Integer_Literal (Loc, 1),
6493 High_Bound => Make_Integer_Literal (Loc,
6495 (First_Tag_Component (Typ))))),
6496 Component_Definition =>
6497 Make_Component_Definition (Loc,
6498 Subtype_Indication =>
6499 New_Reference_To (RTE (RE_Prim_Ptr), Loc)))));
6502 Make_Full_Type_Declaration (Loc,
6503 Defining_Identifier => DT_Prims_Acc,
6505 Make_Access_To_Object_Definition (Loc,
6506 Subtype_Indication =>
6507 New_Occurrence_Of (DT_Prims, Loc))));
6509 Append_Elmt (DT_Prims_Acc, Access_Disp_Table (Typ));
6511 -- Analyze the resulting list and suppress the generation of the
6512 -- Init_Proc associated with the above array declaration because
6513 -- this type is never used in object declarations. It is only used
6514 -- to simplify the expansion associated with dispatching calls.
6516 Analyze_List (Result);
6517 Set_Suppress_Init_Proc (Base_Type (DT_Prims));
6519 -- Mark entity of dispatch table. Required by the back end to
6520 -- handle them properly.
6522 Set_Is_Dispatch_Table_Entity (DT_Prims);
6526 Set_Ekind (DT_Ptr, E_Constant);
6527 Set_Is_Tag (DT_Ptr);
6528 Set_Related_Type (DT_Ptr, Typ);
6537 function New_Value (From : Node_Id) return Node_Id is
6538 Res : constant Node_Id := Duplicate_Subexpr (From);
6540 if Is_Access_Type (Etype (From)) then
6542 Make_Explicit_Dereference (Sloc (From),
6549 -----------------------------------
6550 -- Original_View_In_Visible_Part --
6551 -----------------------------------
6553 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
6554 Scop : constant Entity_Id := Scope (Typ);
6557 -- The scope must be a package
6559 if not Is_Package_Or_Generic_Package (Scop) then
6563 -- A type with a private declaration has a private view declared in
6564 -- the visible part.
6566 if Has_Private_Declaration (Typ) then
6570 return List_Containing (Parent (Typ)) =
6571 Visible_Declarations (Specification (Unit_Declaration_Node (Scop)));
6572 end Original_View_In_Visible_Part;
6578 function Prim_Op_Kind
6580 Typ : Entity_Id) return Node_Id
6582 Full_Typ : Entity_Id := Typ;
6583 Loc : constant Source_Ptr := Sloc (Prim);
6584 Prim_Op : Entity_Id;
6587 -- Retrieve the original primitive operation
6590 while Present (Alias (Prim_Op)) loop
6591 Prim_Op := Alias (Prim_Op);
6594 if Ekind (Typ) = E_Record_Type
6595 and then Present (Corresponding_Concurrent_Type (Typ))
6597 Full_Typ := Corresponding_Concurrent_Type (Typ);
6600 -- When a private tagged type is completed by a concurrent type,
6601 -- retrieve the full view.
6603 if Is_Private_Type (Full_Typ) then
6604 Full_Typ := Full_View (Full_Typ);
6607 if Ekind (Prim_Op) = E_Function then
6609 -- Protected function
6611 if Ekind (Full_Typ) = E_Protected_Type then
6612 return New_Reference_To (RTE (RE_POK_Protected_Function), Loc);
6616 elsif Ekind (Full_Typ) = E_Task_Type then
6617 return New_Reference_To (RTE (RE_POK_Task_Function), Loc);
6622 return New_Reference_To (RTE (RE_POK_Function), Loc);
6626 pragma Assert (Ekind (Prim_Op) = E_Procedure);
6628 if Ekind (Full_Typ) = E_Protected_Type then
6632 if Is_Primitive_Wrapper (Prim_Op)
6633 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
6635 return New_Reference_To (RTE (RE_POK_Protected_Entry), Loc);
6637 -- Protected procedure
6640 return New_Reference_To (RTE (RE_POK_Protected_Procedure), Loc);
6643 elsif Ekind (Full_Typ) = E_Task_Type then
6647 if Is_Primitive_Wrapper (Prim_Op)
6648 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
6650 return New_Reference_To (RTE (RE_POK_Task_Entry), Loc);
6652 -- Task "procedure". These are the internally Expander-generated
6653 -- procedures (task body for instance).
6656 return New_Reference_To (RTE (RE_POK_Task_Procedure), Loc);
6659 -- Regular procedure
6662 return New_Reference_To (RTE (RE_POK_Procedure), Loc);
6667 ------------------------
6668 -- Register_Primitive --
6669 ------------------------
6671 function Register_Primitive
6673 Prim : Entity_Id) return List_Id
6676 Iface_Prim : Entity_Id;
6677 Iface_Typ : Entity_Id;
6678 Iface_DT_Ptr : Entity_Id;
6679 Iface_DT_Elmt : Elmt_Id;
6680 L : constant List_Id := New_List;
6683 Tag_Typ : Entity_Id;
6684 Thunk_Id : Entity_Id;
6685 Thunk_Code : Node_Id;
6688 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
6690 if not RTE_Available (RE_Tag) then
6694 if not Present (Interface_Alias (Prim)) then
6695 Tag_Typ := Scope (DTC_Entity (Prim));
6696 Pos := DT_Position (Prim);
6697 Tag := First_Tag_Component (Tag_Typ);
6699 if Is_Predefined_Dispatching_Operation (Prim)
6700 or else Is_Predefined_Dispatching_Alias (Prim)
6703 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Tag_Typ))));
6706 Build_Set_Predefined_Prim_Op_Address (Loc,
6707 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6710 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6711 Make_Attribute_Reference (Loc,
6712 Prefix => New_Reference_To (Prim, Loc),
6713 Attribute_Name => Name_Unrestricted_Access))));
6715 -- Register copy of the pointer to the 'size primitive in the TSD
6717 if Chars (Prim) = Name_uSize
6718 and then RTE_Record_Component_Available (RE_Size_Func)
6720 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
6722 Build_Set_Size_Function (Loc,
6723 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6724 Size_Func => Prim));
6728 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
6730 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
6732 Build_Set_Prim_Op_Address (Loc,
6734 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6737 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6738 Make_Attribute_Reference (Loc,
6739 Prefix => New_Reference_To (Prim, Loc),
6740 Attribute_Name => Name_Unrestricted_Access))));
6743 -- Ada 2005 (AI-251): Primitive associated with an interface type
6744 -- Generate the code of the thunk only if the interface type is not an
6745 -- immediate ancestor of Typ; otherwise the dispatch table associated
6746 -- with the interface is the primary dispatch table and we have nothing
6750 Tag_Typ := Find_Dispatching_Type (Alias (Prim));
6751 Iface_Typ := Find_Dispatching_Type (Interface_Alias (Prim));
6753 pragma Assert (Is_Interface (Iface_Typ));
6755 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
6757 if not Is_Ancestor (Iface_Typ, Tag_Typ)
6758 and then Present (Thunk_Code)
6760 -- Generate the code necessary to fill the appropriate entry of
6761 -- the secondary dispatch table of Prim's controlling type with
6762 -- Thunk_Id's address.
6764 Iface_DT_Elmt := Find_Interface_ADT (Tag_Typ, Iface_Typ);
6765 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6766 pragma Assert (Has_Thunks (Iface_DT_Ptr));
6768 Iface_Prim := Interface_Alias (Prim);
6769 Pos := DT_Position (Iface_Prim);
6770 Tag := First_Tag_Component (Iface_Typ);
6772 Prepend_To (L, Thunk_Code);
6774 if Is_Predefined_Dispatching_Operation (Prim)
6775 or else Is_Predefined_Dispatching_Alias (Prim)
6778 Build_Set_Predefined_Prim_Op_Address (Loc,
6780 New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
6783 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6784 Make_Attribute_Reference (Loc,
6785 Prefix => New_Reference_To (Thunk_Id, Loc),
6786 Attribute_Name => Name_Unrestricted_Access))));
6788 Next_Elmt (Iface_DT_Elmt);
6789 Next_Elmt (Iface_DT_Elmt);
6790 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6791 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
6794 Build_Set_Predefined_Prim_Op_Address (Loc,
6796 New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
6799 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6800 Make_Attribute_Reference (Loc,
6801 Prefix => New_Reference_To (Alias (Prim), Loc),
6802 Attribute_Name => Name_Unrestricted_Access))));
6805 pragma Assert (Pos /= Uint_0
6806 and then Pos <= DT_Entry_Count (Tag));
6809 Build_Set_Prim_Op_Address (Loc,
6811 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
6814 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6815 Make_Attribute_Reference (Loc,
6816 Prefix => New_Reference_To (Thunk_Id, Loc),
6817 Attribute_Name => Name_Unrestricted_Access))));
6819 Next_Elmt (Iface_DT_Elmt);
6820 Next_Elmt (Iface_DT_Elmt);
6821 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6822 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
6825 Build_Set_Prim_Op_Address (Loc,
6827 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
6830 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6831 Make_Attribute_Reference (Loc,
6832 Prefix => New_Reference_To (Alias (Prim), Loc),
6833 Attribute_Name => Name_Unrestricted_Access))));
6840 end Register_Primitive;
6842 -------------------------
6843 -- Set_All_DT_Position --
6844 -------------------------
6846 procedure Set_All_DT_Position (Typ : Entity_Id) is
6848 procedure Validate_Position (Prim : Entity_Id);
6849 -- Check that the position assigned to Prim is completely safe
6850 -- (it has not been assigned to a previously defined primitive
6851 -- operation of Typ)
6853 -----------------------
6854 -- Validate_Position --
6855 -----------------------
6857 procedure Validate_Position (Prim : Entity_Id) is
6862 -- Aliased primitives are safe
6864 if Present (Alias (Prim)) then
6868 Op_Elmt := First_Elmt (Primitive_Operations (Typ));
6869 while Present (Op_Elmt) loop
6870 Op := Node (Op_Elmt);
6872 -- No need to check against itself
6877 -- Primitive operations covering abstract interfaces are
6880 elsif Present (Interface_Alias (Op)) then
6883 -- Predefined dispatching operations are completely safe. They
6884 -- are allocated at fixed positions in a separate table.
6886 elsif Is_Predefined_Dispatching_Operation (Op)
6887 or else Is_Predefined_Dispatching_Alias (Op)
6891 -- Aliased subprograms are safe
6893 elsif Present (Alias (Op)) then
6896 elsif DT_Position (Op) = DT_Position (Prim)
6897 and then not Is_Predefined_Dispatching_Operation (Op)
6898 and then not Is_Predefined_Dispatching_Operation (Prim)
6899 and then not Is_Predefined_Dispatching_Alias (Op)
6900 and then not Is_Predefined_Dispatching_Alias (Prim)
6903 -- Handle aliased subprograms
6912 if Present (Overridden_Operation (Op_1)) then
6913 Op_1 := Overridden_Operation (Op_1);
6914 elsif Present (Alias (Op_1)) then
6915 Op_1 := Alias (Op_1);
6923 if Present (Overridden_Operation (Op_2)) then
6924 Op_2 := Overridden_Operation (Op_2);
6925 elsif Present (Alias (Op_2)) then
6926 Op_2 := Alias (Op_2);
6932 if Op_1 /= Op_2 then
6933 raise Program_Error;
6938 Next_Elmt (Op_Elmt);
6940 end Validate_Position;
6944 Parent_Typ : constant Entity_Id := Etype (Typ);
6945 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
6946 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
6948 Adjusted : Boolean := False;
6949 Finalized : Boolean := False;
6955 Prim_Elmt : Elmt_Id;
6957 -- Start of processing for Set_All_DT_Position
6960 pragma Assert (Present (First_Tag_Component (Typ)));
6962 -- Set the DT_Position for each primitive operation. Perform some sanity
6963 -- checks to avoid building inconsistent dispatch tables.
6965 -- First stage: Set the DTC entity of all the primitive operations. This
6966 -- is required to properly read the DT_Position attribute in the latter
6969 Prim_Elmt := First_Prim;
6971 while Present (Prim_Elmt) loop
6972 Prim := Node (Prim_Elmt);
6974 -- Predefined primitives have a separate dispatch table
6976 if not (Is_Predefined_Dispatching_Operation (Prim)
6978 Is_Predefined_Dispatching_Alias (Prim))
6980 Count_Prim := Count_Prim + 1;
6983 Set_DTC_Entity_Value (Typ, Prim);
6985 -- Clear any previous value of the DT_Position attribute. In this
6986 -- way we ensure that the final position of all the primitives is
6987 -- established by the following stages of this algorithm.
6989 Set_DT_Position (Prim, No_Uint);
6991 Next_Elmt (Prim_Elmt);
6995 Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean :=
7000 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id);
7001 -- Called if Typ is declared in a nested package or a public child
7002 -- package to handle inherited primitives that were inherited by Typ
7003 -- in the visible part, but whose declaration was deferred because
7004 -- the parent operation was private and not visible at that point.
7006 procedure Set_Fixed_Prim (Pos : Nat);
7007 -- Sets to true an element of the Fixed_Prim table to indicate
7008 -- that this entry of the dispatch table of Typ is occupied.
7010 ------------------------------------------
7011 -- Handle_Inherited_Private_Subprograms --
7012 ------------------------------------------
7014 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id) is
7017 Op_Elmt_2 : Elmt_Id;
7018 Prim_Op : Entity_Id;
7019 Parent_Subp : Entity_Id;
7022 Op_List := Primitive_Operations (Typ);
7024 Op_Elmt := First_Elmt (Op_List);
7025 while Present (Op_Elmt) loop
7026 Prim_Op := Node (Op_Elmt);
7028 -- Search primitives that are implicit operations with an
7029 -- internal name whose parent operation has a normal name.
7031 if Present (Alias (Prim_Op))
7032 and then Find_Dispatching_Type (Alias (Prim_Op)) /= Typ
7033 and then not Comes_From_Source (Prim_Op)
7034 and then Is_Internal_Name (Chars (Prim_Op))
7035 and then not Is_Internal_Name (Chars (Alias (Prim_Op)))
7037 Parent_Subp := Alias (Prim_Op);
7039 -- Check if the type has an explicit overriding for this
7042 Op_Elmt_2 := Next_Elmt (Op_Elmt);
7043 while Present (Op_Elmt_2) loop
7044 if Chars (Node (Op_Elmt_2)) = Chars (Parent_Subp)
7045 and then Type_Conformant (Prim_Op, Node (Op_Elmt_2))
7047 Set_DT_Position (Prim_Op, DT_Position (Parent_Subp));
7048 Set_DT_Position (Node (Op_Elmt_2),
7049 DT_Position (Parent_Subp));
7050 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim_Op)));
7052 goto Next_Primitive;
7055 Next_Elmt (Op_Elmt_2);
7060 Next_Elmt (Op_Elmt);
7062 end Handle_Inherited_Private_Subprograms;
7064 --------------------
7065 -- Set_Fixed_Prim --
7066 --------------------
7068 procedure Set_Fixed_Prim (Pos : Nat) is
7070 pragma Assert (Pos <= Count_Prim);
7071 Fixed_Prim (Pos) := True;
7073 when Constraint_Error =>
7074 raise Program_Error;
7078 -- In case of nested packages and public child package it may be
7079 -- necessary a special management on inherited subprograms so that
7080 -- the dispatch table is properly filled.
7082 if Ekind (Scope (Scope (Typ))) = E_Package
7083 and then Scope (Scope (Typ)) /= Standard_Standard
7084 and then ((Is_Derived_Type (Typ) and then not Is_Private_Type (Typ))
7086 (Nkind (Parent (Typ)) = N_Private_Extension_Declaration
7087 and then Is_Generic_Type (Typ)))
7088 and then In_Open_Scopes (Scope (Etype (Typ)))
7089 and then Typ = Base_Type (Typ)
7091 Handle_Inherited_Private_Subprograms (Typ);
7094 -- Second stage: Register fixed entries
7097 Prim_Elmt := First_Prim;
7098 while Present (Prim_Elmt) loop
7099 Prim := Node (Prim_Elmt);
7101 -- Predefined primitives have a separate table and all its
7102 -- entries are at predefined fixed positions.
7104 if Is_Predefined_Dispatching_Operation (Prim) then
7105 Set_DT_Position (Prim, Default_Prim_Op_Position (Prim));
7107 elsif Is_Predefined_Dispatching_Alias (Prim) then
7109 while Present (Alias (E)) loop
7113 Set_DT_Position (Prim, Default_Prim_Op_Position (E));
7115 -- Overriding primitives of ancestor abstract interfaces
7117 elsif Present (Interface_Alias (Prim))
7118 and then Is_Ancestor
7119 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ)
7121 pragma Assert (DT_Position (Prim) = No_Uint
7122 and then Present (DTC_Entity (Interface_Alias (Prim))));
7124 E := Interface_Alias (Prim);
7125 Set_DT_Position (Prim, DT_Position (E));
7128 (DT_Position (Alias (Prim)) = No_Uint
7129 or else DT_Position (Alias (Prim)) = DT_Position (E));
7130 Set_DT_Position (Alias (Prim), DT_Position (E));
7131 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));
7133 -- Overriding primitives must use the same entry as the
7134 -- overridden primitive.
7136 elsif not Present (Interface_Alias (Prim))
7137 and then Present (Alias (Prim))
7138 and then Chars (Prim) = Chars (Alias (Prim))
7139 and then Find_Dispatching_Type (Alias (Prim)) /= Typ
7140 and then Is_Ancestor
7141 (Find_Dispatching_Type (Alias (Prim)), Typ)
7142 and then Present (DTC_Entity (Alias (Prim)))
7145 Set_DT_Position (Prim, DT_Position (E));
7147 if not Is_Predefined_Dispatching_Alias (E) then
7148 Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
7152 Next_Elmt (Prim_Elmt);
7155 -- Third stage: Fix the position of all the new primitives
7156 -- Entries associated with primitives covering interfaces
7157 -- are handled in a latter round.
7159 Prim_Elmt := First_Prim;
7160 while Present (Prim_Elmt) loop
7161 Prim := Node (Prim_Elmt);
7163 -- Skip primitives previously set entries
7165 if DT_Position (Prim) /= No_Uint then
7168 -- Primitives covering interface primitives are handled later
7170 elsif Present (Interface_Alias (Prim)) then
7174 -- Take the next available position in the DT
7177 Nb_Prim := Nb_Prim + 1;
7178 pragma Assert (Nb_Prim <= Count_Prim);
7179 exit when not Fixed_Prim (Nb_Prim);
7182 Set_DT_Position (Prim, UI_From_Int (Nb_Prim));
7183 Set_Fixed_Prim (Nb_Prim);
7186 Next_Elmt (Prim_Elmt);
7190 -- Fourth stage: Complete the decoration of primitives covering
7191 -- interfaces (that is, propagate the DT_Position attribute
7192 -- from the aliased primitive)
7194 Prim_Elmt := First_Prim;
7195 while Present (Prim_Elmt) loop
7196 Prim := Node (Prim_Elmt);
7198 if DT_Position (Prim) = No_Uint
7199 and then Present (Interface_Alias (Prim))
7201 pragma Assert (Present (Alias (Prim))
7202 and then Find_Dispatching_Type (Alias (Prim)) = Typ);
7204 -- Check if this entry will be placed in the primary DT
7207 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ)
7209 pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
7210 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
7212 -- Otherwise it will be placed in the secondary DT
7216 (DT_Position (Interface_Alias (Prim)) /= No_Uint);
7217 Set_DT_Position (Prim,
7218 DT_Position (Interface_Alias (Prim)));
7222 Next_Elmt (Prim_Elmt);
7225 -- Generate listing showing the contents of the dispatch tables.
7226 -- This action is done before some further static checks because
7227 -- in case of critical errors caused by a wrong dispatch table
7228 -- we need to see the contents of such table.
7230 if Debug_Flag_ZZ then
7234 -- Final stage: Ensure that the table is correct plus some further
7235 -- verifications concerning the primitives.
7237 Prim_Elmt := First_Prim;
7239 while Present (Prim_Elmt) loop
7240 Prim := Node (Prim_Elmt);
7242 -- At this point all the primitives MUST have a position
7243 -- in the dispatch table.
7245 if DT_Position (Prim) = No_Uint then
7246 raise Program_Error;
7249 -- Calculate real size of the dispatch table
7251 if not (Is_Predefined_Dispatching_Operation (Prim)
7252 or else Is_Predefined_Dispatching_Alias (Prim))
7253 and then UI_To_Int (DT_Position (Prim)) > DT_Length
7255 DT_Length := UI_To_Int (DT_Position (Prim));
7258 -- Ensure that the assigned position to non-predefined
7259 -- dispatching operations in the dispatch table is correct.
7261 if not (Is_Predefined_Dispatching_Operation (Prim)
7262 or else Is_Predefined_Dispatching_Alias (Prim))
7264 Validate_Position (Prim);
7267 if Chars (Prim) = Name_Finalize then
7271 if Chars (Prim) = Name_Adjust then
7275 -- An abstract operation cannot be declared in the private part
7276 -- for a visible abstract type, because it could never be over-
7277 -- ridden. For explicit declarations this is checked at the
7278 -- point of declaration, but for inherited operations it must
7279 -- be done when building the dispatch table.
7281 -- Ada 2005 (AI-251): Primitives associated with interfaces are
7282 -- excluded from this check because interfaces must be visible in
7283 -- the public and private part (RM 7.3 (7.3/2))
7285 if Is_Abstract_Type (Typ)
7286 and then Is_Abstract_Subprogram (Prim)
7287 and then Present (Alias (Prim))
7288 and then not Is_Interface
7289 (Find_Dispatching_Type (Ultimate_Alias (Prim)))
7290 and then not Present (Interface_Alias (Prim))
7291 and then Is_Derived_Type (Typ)
7292 and then In_Private_Part (Current_Scope)
7294 List_Containing (Parent (Prim)) =
7295 Private_Declarations
7296 (Specification (Unit_Declaration_Node (Current_Scope)))
7297 and then Original_View_In_Visible_Part (Typ)
7299 -- We exclude Input and Output stream operations because
7300 -- Limited_Controlled inherits useless Input and Output
7301 -- stream operations from Root_Controlled, which can
7302 -- never be overridden.
7304 if not Is_TSS (Prim, TSS_Stream_Input)
7306 not Is_TSS (Prim, TSS_Stream_Output)
7309 ("abstract inherited private operation&" &
7310 " must be overridden (RM 3.9.3(10))",
7311 Parent (Typ), Prim);
7315 Next_Elmt (Prim_Elmt);
7320 if Is_Controlled (Typ) then
7321 if not Finalized then
7323 ("controlled type has no explicit Finalize method?", Typ);
7325 elsif not Adjusted then
7327 ("controlled type has no explicit Adjust method?", Typ);
7331 -- Set the final size of the Dispatch Table
7333 Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));
7335 -- The derived type must have at least as many components as its parent
7336 -- (for root types Etype points to itself and the test cannot fail).
7338 if DT_Entry_Count (The_Tag) <
7339 DT_Entry_Count (First_Tag_Component (Parent_Typ))
7341 raise Program_Error;
7343 end Set_All_DT_Position;
7345 --------------------------
7346 -- Set_CPP_Constructors --
7347 --------------------------
7349 procedure Set_CPP_Constructors (Typ : Entity_Id) is
7353 Found : Boolean := False;
7358 -- Look for the constructor entities
7360 E := Next_Entity (Typ);
7361 while Present (E) loop
7362 if Ekind (E) = E_Function
7363 and then Is_Constructor (E)
7365 -- Create the init procedure
7369 Init := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
7372 Make_Parameter_Specification (Loc,
7373 Defining_Identifier =>
7374 Make_Defining_Identifier (Loc, Name_X),
7376 New_Reference_To (Typ, Loc)));
7378 if Present (Parameter_Specifications (Parent (E))) then
7379 P := First (Parameter_Specifications (Parent (E)));
7380 while Present (P) loop
7382 Make_Parameter_Specification (Loc,
7383 Defining_Identifier =>
7384 Make_Defining_Identifier (Loc,
7385 Chars (Defining_Identifier (P))),
7386 Parameter_Type => New_Copy_Tree (Parameter_Type (P))));
7392 Make_Subprogram_Declaration (Loc,
7393 Make_Procedure_Specification (Loc,
7394 Defining_Unit_Name => Init,
7395 Parameter_Specifications => Parms)));
7397 Set_Init_Proc (Typ, Init);
7398 Set_Is_Imported (Init);
7399 Set_Interface_Name (Init, Interface_Name (E));
7400 Set_Convention (Init, Convention_C);
7401 Set_Is_Public (Init);
7402 Set_Has_Completion (Init);
7408 -- If there are no constructors, mark the type as abstract since we
7409 -- won't be able to declare objects of that type.
7412 Set_Is_Abstract_Type (Typ);
7414 end Set_CPP_Constructors;
7416 --------------------------
7417 -- Set_DTC_Entity_Value --
7418 --------------------------
7420 procedure Set_DTC_Entity_Value
7421 (Tagged_Type : Entity_Id;
7425 if Present (Interface_Alias (Prim))
7426 and then Is_Interface
7427 (Find_Dispatching_Type (Interface_Alias (Prim)))
7429 Set_DTC_Entity (Prim,
7432 Iface => Find_Dispatching_Type (Interface_Alias (Prim))));
7434 Set_DTC_Entity (Prim,
7435 First_Tag_Component (Tagged_Type));
7437 end Set_DTC_Entity_Value;
7443 function Tagged_Kind (T : Entity_Id) return Node_Id is
7444 Conc_Typ : Entity_Id;
7445 Loc : constant Source_Ptr := Sloc (T);
7449 (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));
7453 if Is_Abstract_Type (T) then
7454 if Is_Limited_Record (T) then
7455 return New_Reference_To (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
7457 return New_Reference_To (RTE (RE_TK_Abstract_Tagged), Loc);
7462 elsif Is_Concurrent_Record_Type (T) then
7463 Conc_Typ := Corresponding_Concurrent_Type (T);
7465 if Present (Full_View (Conc_Typ)) then
7466 Conc_Typ := Full_View (Conc_Typ);
7469 if Ekind (Conc_Typ) = E_Protected_Type then
7470 return New_Reference_To (RTE (RE_TK_Protected), Loc);
7472 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
7473 return New_Reference_To (RTE (RE_TK_Task), Loc);
7476 -- Regular tagged kinds
7479 if Is_Limited_Record (T) then
7480 return New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc);
7482 return New_Reference_To (RTE (RE_TK_Tagged), Loc);
7491 procedure Write_DT (Typ : Entity_Id) is
7496 -- Protect this procedure against wrong usage. Required because it will
7497 -- be used directly from GDB
7499 if not (Typ <= Last_Node_Id)
7500 or else not Is_Tagged_Type (Typ)
7502 Write_Str ("wrong usage: Write_DT must be used with tagged types");
7507 Write_Int (Int (Typ));
7509 Write_Name (Chars (Typ));
7511 if Is_Interface (Typ) then
7512 Write_Str (" is interface");
7517 Elmt := First_Elmt (Primitive_Operations (Typ));
7518 while Present (Elmt) loop
7519 Prim := Node (Elmt);
7522 -- Indicate if this primitive will be allocated in the primary
7523 -- dispatch table or in a secondary dispatch table associated
7524 -- with an abstract interface type
7526 if Present (DTC_Entity (Prim)) then
7527 if Etype (DTC_Entity (Prim)) = RTE (RE_Tag) then
7534 -- Output the node of this primitive operation and its name
7536 Write_Int (Int (Prim));
7539 if Is_Predefined_Dispatching_Operation (Prim) then
7540 Write_Str ("(predefined) ");
7543 Write_Name (Chars (Prim));
7545 -- Indicate if this primitive has an aliased primitive
7547 if Present (Alias (Prim)) then
7548 Write_Str (" (alias = ");
7549 Write_Int (Int (Alias (Prim)));
7551 -- If the DTC_Entity attribute is already set we can also output
7552 -- the name of the interface covered by this primitive (if any)
7554 if Present (DTC_Entity (Alias (Prim)))
7555 and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
7557 Write_Str (" from interface ");
7558 Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
7561 if Present (Interface_Alias (Prim)) then
7562 Write_Str (", AI_Alias of ");
7564 (Chars (Find_Dispatching_Type (Interface_Alias (Prim))));
7566 Write_Int (Int (Interface_Alias (Prim)));
7572 -- Display the final position of this primitive in its associated
7573 -- (primary or secondary) dispatch table
7575 if Present (DTC_Entity (Prim))
7576 and then DT_Position (Prim) /= No_Uint
7578 Write_Str (" at #");
7579 Write_Int (UI_To_Int (DT_Position (Prim)));
7582 if Is_Abstract_Subprogram (Prim) then
7583 Write_Str (" is abstract;");
7585 -- Check if this is a null primitive
7587 elsif Comes_From_Source (Prim)
7588 and then Ekind (Prim) = E_Procedure
7589 and then Null_Present (Parent (Prim))
7591 Write_Str (" is null;");
7594 if Is_Eliminated (Ultimate_Alias (Prim)) then
7595 Write_Str (" (eliminated)");