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),
578 -- Start of processing for Expand_Dispatching_Call
581 if No_Run_Time_Mode then
582 Error_Msg_CRT ("tagged types", Call_Node);
586 -- Expand_Dispatching_Call is called directly from the semantics,
587 -- so we need a check to see whether expansion is active before
588 -- proceeding. In addition, there is no need to expand the call
589 -- if we are compiling under restriction No_Dispatching_Calls;
590 -- the semantic analyzer has previously notified the violation
591 -- of this restriction.
593 if not Expander_Active
594 or else Restriction_Active (No_Dispatching_Calls)
599 -- Set subprogram. If this is an inherited operation that was
600 -- overridden, the body that is being called is its alias.
602 Subp := Entity (Name (Call_Node));
604 if Present (Alias (Subp))
605 and then Is_Inherited_Operation (Subp)
606 and then No (DTC_Entity (Subp))
608 Subp := Alias (Subp);
611 -- Definition of the class-wide type and the tagged type
613 -- If the controlling argument is itself a tag rather than a tagged
614 -- object, then use the class-wide type associated with the subprogram's
615 -- controlling type. This case can occur when a call to an inherited
616 -- primitive has an actual that originated from a default parameter
617 -- given by a tag-indeterminate call and when there is no other
618 -- controlling argument providing the tag (AI-239 requires dispatching).
619 -- This capability of dispatching directly by tag is also needed by the
620 -- implementation of AI-260 (for the generic dispatching constructors).
622 if Ctrl_Typ = RTE (RE_Tag)
623 or else (RTE_Available (RE_Interface_Tag)
624 and then Ctrl_Typ = RTE (RE_Interface_Tag))
626 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
628 -- Class_Wide_Type is applied to the expressions used to initialize
629 -- CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
630 -- there are cases where the controlling type is resolved to a specific
631 -- type (such as for designated types of arguments such as CW'Access).
633 elsif Is_Access_Type (Ctrl_Typ) then
634 CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));
637 CW_Typ := Class_Wide_Type (Ctrl_Typ);
640 Typ := Root_Type (CW_Typ);
642 if Ekind (Typ) = E_Incomplete_Type then
643 Typ := Non_Limited_View (Typ);
646 if Generate_SCIL then
647 Insert_Action (Call_Node,
649 (Nkind => Dispatching_Call,
650 Related_Node => Call_Node,
652 Target_Prim => Subp));
655 if not Is_Limited_Type (Typ) then
656 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
659 -- Dispatching call to C++ primitive. Create a new parameter list
660 -- with no tag checks.
662 New_Params := New_List;
664 if Is_CPP_Class (Typ) then
665 Param := First_Actual (Call_Node);
666 while Present (Param) loop
667 Append_To (New_Params, Relocate_Node (Param));
671 -- Dispatching call to Ada primitive
673 elsif Present (Param_List) then
674 Apply_Tag_Checks (Call_Node);
676 Param := First_Actual (Call_Node);
677 while Present (Param) loop
678 -- Cases in which we may have generated runtime checks
681 or else Subp = Eq_Prim_Op
683 Append_To (New_Params,
684 Duplicate_Subexpr_Move_Checks (Param));
687 Append_To (New_Params, Relocate_Node (Param));
694 -- Generate the appropriate subprogram pointer type
696 if Etype (Subp) = Typ then
699 Res_Typ := Etype (Subp);
702 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
703 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
704 Set_Etype (Subp_Typ, Res_Typ);
705 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
707 -- Create a new list of parameters which is a copy of the old formal
708 -- list including the creation of a new set of matching entities.
711 Old_Formal : Entity_Id := First_Formal (Subp);
712 New_Formal : Entity_Id;
713 Extra : Entity_Id := Empty;
716 if Present (Old_Formal) then
717 New_Formal := New_Copy (Old_Formal);
718 Set_First_Entity (Subp_Typ, New_Formal);
719 Param := First_Actual (Call_Node);
722 Set_Scope (New_Formal, Subp_Typ);
724 -- Change all the controlling argument types to be class-wide
725 -- to avoid a recursion in dispatching.
727 if Is_Controlling_Formal (New_Formal) then
728 Set_Etype (New_Formal, Etype (Param));
731 -- If the type of the formal is an itype, there was code here
732 -- introduced in 1998 in revision 1.46, to create a new itype
733 -- by copy. This seems useless, and in fact leads to semantic
734 -- errors when the itype is the completion of a type derived
735 -- from a private type.
738 Next_Formal (Old_Formal);
739 exit when No (Old_Formal);
741 Set_Next_Entity (New_Formal, New_Copy (Old_Formal));
742 Next_Entity (New_Formal);
746 Set_Next_Entity (New_Formal, Empty);
747 Set_Last_Entity (Subp_Typ, Extra);
750 -- Now that the explicit formals have been duplicated, any extra
751 -- formals needed by the subprogram must be created.
753 if Present (Extra) then
754 Set_Extra_Formal (Extra, Empty);
757 Create_Extra_Formals (Subp_Typ);
760 -- Complete description of pointer type, including size information, as
761 -- must be done with itypes to prevent order-of-elaboration anomalies
764 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
765 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
766 Set_Convention (Subp_Ptr_Typ, Convention (Subp_Typ));
767 Layout_Type (Subp_Ptr_Typ);
769 -- If the controlling argument is a value of type Ada.Tag or an abstract
770 -- interface class-wide type then use it directly. Otherwise, the tag
771 -- must be extracted from the controlling object.
773 if Ctrl_Typ = RTE (RE_Tag)
774 or else (RTE_Available (RE_Interface_Tag)
775 and then Ctrl_Typ = RTE (RE_Interface_Tag))
777 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
779 -- Extract the tag from an unchecked type conversion. Done to avoid
780 -- the expansion of additional code just to obtain the value of such
781 -- tag because the current management of interface type conversions
782 -- generates in some cases this unchecked type conversion with the
783 -- tag of the object (see Expand_Interface_Conversion).
785 elsif Nkind (Ctrl_Arg) = N_Unchecked_Type_Conversion
787 (Etype (Expression (Ctrl_Arg)) = RTE (RE_Tag)
789 (RTE_Available (RE_Interface_Tag)
791 Etype (Expression (Ctrl_Arg)) = RTE (RE_Interface_Tag)))
793 Controlling_Tag := Duplicate_Subexpr (Expression (Ctrl_Arg));
795 -- Ada 2005 (AI-251): Abstract interface class-wide type
797 elsif Is_Interface (Ctrl_Typ)
798 and then Is_Class_Wide_Type (Ctrl_Typ)
800 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
804 Make_Selected_Component (Loc,
805 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
806 Selector_Name => New_Reference_To (DTC_Entity (Subp), Loc));
809 -- Handle dispatching calls to predefined primitives
811 if Is_Predefined_Dispatching_Operation (Subp)
812 or else Is_Predefined_Dispatching_Alias (Subp)
815 Unchecked_Convert_To (Subp_Ptr_Typ,
816 Build_Get_Predefined_Prim_Op_Address (Loc,
817 Tag_Node => Controlling_Tag,
818 Position => DT_Position (Subp)));
820 -- Handle dispatching calls to user-defined primitives
824 Unchecked_Convert_To (Subp_Ptr_Typ,
825 Build_Get_Prim_Op_Address (Loc,
826 Typ => Find_Dispatching_Type (Subp),
827 Tag_Node => Controlling_Tag,
828 Position => DT_Position (Subp)));
831 if Nkind (Call_Node) = N_Function_Call then
834 Make_Function_Call (Loc,
835 Name => New_Call_Name,
836 Parameter_Associations => New_Params);
838 -- If this is a dispatching "=", we must first compare the tags so
839 -- we generate: x.tag = y.tag and then x = y
841 if Subp = Eq_Prim_Op then
842 Param := First_Actual (Call_Node);
848 Make_Selected_Component (Loc,
849 Prefix => New_Value (Param),
851 New_Reference_To (First_Tag_Component (Typ),
855 Make_Selected_Component (Loc,
857 Unchecked_Convert_To (Typ,
858 New_Value (Next_Actual (Param))),
860 New_Reference_To (First_Tag_Component (Typ),
862 Right_Opnd => New_Call);
867 Make_Procedure_Call_Statement (Loc,
868 Name => New_Call_Name,
869 Parameter_Associations => New_Params);
872 Rewrite (Call_Node, New_Call);
874 -- Suppress all checks during the analysis of the expanded code
875 -- to avoid the generation of spurious warnings under ZFP run-time.
877 Analyze_And_Resolve (Call_Node, Call_Typ, Suppress => All_Checks);
878 end Expand_Dispatching_Call;
880 ---------------------------------
881 -- Expand_Interface_Conversion --
882 ---------------------------------
884 procedure Expand_Interface_Conversion
886 Is_Static : Boolean := True)
888 Loc : constant Source_Ptr := Sloc (N);
889 Etyp : constant Entity_Id := Etype (N);
890 Operand : constant Node_Id := Expression (N);
891 Operand_Typ : Entity_Id := Etype (Operand);
893 Iface_Typ : Entity_Id := Etype (N);
894 Iface_Tag : Entity_Id;
897 -- Ada 2005 (AI-345): Handle synchronized interface type derivations
899 if Is_Concurrent_Type (Operand_Typ) then
900 Operand_Typ := Base_Type (Corresponding_Record_Type (Operand_Typ));
903 -- Handle access to class-wide interface types
905 if Is_Access_Type (Iface_Typ) then
906 Iface_Typ := Etype (Directly_Designated_Type (Iface_Typ));
909 -- Handle class-wide interface types. This conversion can appear
910 -- explicitly in the source code. Example: I'Class (Obj)
912 if Is_Class_Wide_Type (Iface_Typ) then
913 Iface_Typ := Root_Type (Iface_Typ);
916 -- If the target type is a tagged synchronized type, the dispatch table
917 -- info is in the corresponding record type.
919 if Is_Concurrent_Type (Iface_Typ) then
920 Iface_Typ := Corresponding_Record_Type (Iface_Typ);
923 -- Freeze the entity associated with the target interface to have
924 -- available the attribute Access_Disp_Table.
926 Freeze_Before (N, Iface_Typ);
928 pragma Assert (not Is_Static
929 or else (not Is_Class_Wide_Type (Iface_Typ)
930 and then Is_Interface (Iface_Typ)));
932 if not Tagged_Type_Expansion then
934 -- For VM, just do a conversion ???
936 Rewrite (N, Unchecked_Convert_To (Etype (N), N));
941 if not Is_Static then
943 -- Give error if configurable run time and Displace not available
945 if not RTE_Available (RE_Displace) then
946 Error_Msg_CRT ("dynamic interface conversion", N);
950 -- Handle conversion of access-to-class-wide interface types. Target
951 -- can be an access to an object or an access to another class-wide
952 -- interface (see -1- and -2- in the following example):
954 -- type Iface1_Ref is access all Iface1'Class;
955 -- type Iface2_Ref is access all Iface1'Class;
957 -- Acc1 : Iface1_Ref := new ...
958 -- Obj : Obj_Ref := Obj_Ref (Acc); -- 1
959 -- Acc2 : Iface2_Ref := Iface2_Ref (Acc); -- 2
961 if Is_Access_Type (Operand_Typ) then
963 Unchecked_Convert_To (Etype (N),
964 Make_Function_Call (Loc,
965 Name => New_Reference_To (RTE (RE_Displace), Loc),
966 Parameter_Associations => New_List (
968 Unchecked_Convert_To (RTE (RE_Address),
969 Relocate_Node (Expression (N))),
972 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
980 Make_Function_Call (Loc,
981 Name => New_Reference_To (RTE (RE_Displace), Loc),
982 Parameter_Associations => New_List (
983 Make_Attribute_Reference (Loc,
984 Prefix => Relocate_Node (Expression (N)),
985 Attribute_Name => Name_Address),
988 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
993 -- If the target is a class-wide interface we change the type of the
994 -- data returned by IW_Convert to indicate that this is a dispatching
998 New_Itype : Entity_Id;
1001 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
1002 Set_Etype (New_Itype, New_Itype);
1003 Set_Directly_Designated_Type (New_Itype, Etyp);
1006 Make_Explicit_Dereference (Loc,
1008 Unchecked_Convert_To (New_Itype, Relocate_Node (N))));
1010 Freeze_Itype (New_Itype, N);
1016 Iface_Tag := Find_Interface_Tag (Operand_Typ, Iface_Typ);
1017 pragma Assert (Iface_Tag /= Empty);
1019 -- Keep separate access types to interfaces because one internal
1020 -- function is used to handle the null value (see following comment)
1022 if not Is_Access_Type (Etype (N)) then
1024 Unchecked_Convert_To (Etype (N),
1025 Make_Selected_Component (Loc,
1026 Prefix => Relocate_Node (Expression (N)),
1028 New_Occurrence_Of (Iface_Tag, Loc))));
1031 -- Build internal function to handle the case in which the
1032 -- actual is null. If the actual is null returns null because
1033 -- no displacement is required; otherwise performs a type
1034 -- conversion that will be expanded in the code that returns
1035 -- the value of the displaced actual. That is:
1037 -- function Func (O : Address) return Iface_Typ is
1038 -- type Op_Typ is access all Operand_Typ;
1039 -- Aux : Op_Typ := To_Op_Typ (O);
1041 -- if O = Null_Address then
1044 -- return Iface_Typ!(Aux.Iface_Tag'Address);
1049 Desig_Typ : Entity_Id;
1051 New_Typ_Decl : Node_Id;
1055 Desig_Typ := Etype (Expression (N));
1057 if Is_Access_Type (Desig_Typ) then
1059 Available_View (Directly_Designated_Type (Desig_Typ));
1062 if Is_Concurrent_Type (Desig_Typ) then
1063 Desig_Typ := Base_Type (Corresponding_Record_Type (Desig_Typ));
1067 Make_Full_Type_Declaration (Loc,
1068 Defining_Identifier =>
1069 Make_Defining_Identifier (Loc, New_Internal_Name ('T')),
1071 Make_Access_To_Object_Definition (Loc,
1072 All_Present => True,
1073 Null_Exclusion_Present => False,
1074 Constant_Present => False,
1075 Subtype_Indication =>
1076 New_Reference_To (Desig_Typ, Loc)));
1079 Make_Simple_Return_Statement (Loc,
1080 Unchecked_Convert_To (Etype (N),
1081 Make_Attribute_Reference (Loc,
1083 Make_Selected_Component (Loc,
1085 Unchecked_Convert_To
1086 (Defining_Identifier (New_Typ_Decl),
1087 Make_Identifier (Loc, Name_uO)),
1089 New_Occurrence_Of (Iface_Tag, Loc)),
1090 Attribute_Name => Name_Address))));
1092 -- If the type is null-excluding, no need for the null branch.
1093 -- Otherwise we need to check for it and return null.
1095 if not Can_Never_Be_Null (Etype (N)) then
1097 Make_If_Statement (Loc,
1100 Left_Opnd => Make_Identifier (Loc, Name_uO),
1101 Right_Opnd => New_Reference_To
1102 (RTE (RE_Null_Address), Loc)),
1104 Then_Statements => New_List (
1105 Make_Simple_Return_Statement (Loc,
1107 Else_Statements => Stats));
1111 Make_Defining_Identifier (Loc,
1112 New_Internal_Name ('F'));
1115 Make_Subprogram_Body (Loc,
1117 Make_Function_Specification (Loc,
1118 Defining_Unit_Name => Fent,
1120 Parameter_Specifications => New_List (
1121 Make_Parameter_Specification (Loc,
1122 Defining_Identifier =>
1123 Make_Defining_Identifier (Loc, Name_uO),
1125 New_Reference_To (RTE (RE_Address), Loc))),
1127 Result_Definition =>
1128 New_Reference_To (Etype (N), Loc)),
1130 Declarations => New_List (New_Typ_Decl),
1132 Handled_Statement_Sequence =>
1133 Make_Handled_Sequence_Of_Statements (Loc, Stats));
1135 -- Place function body before the expression containing the
1136 -- conversion. We suppress all checks because the body of the
1137 -- internally generated function already takes care of the case
1138 -- in which the actual is null; therefore there is no need to
1139 -- double check that the pointer is not null when the program
1140 -- executes the alternative that performs the type conversion).
1142 Insert_Action (N, Func, Suppress => All_Checks);
1144 if Is_Access_Type (Etype (Expression (N))) then
1146 -- Generate: Func (Address!(Expression))
1149 Make_Function_Call (Loc,
1150 Name => New_Reference_To (Fent, Loc),
1151 Parameter_Associations => New_List (
1152 Unchecked_Convert_To (RTE (RE_Address),
1153 Relocate_Node (Expression (N))))));
1156 -- Generate: Func (Operand_Typ!(Expression)'Address)
1159 Make_Function_Call (Loc,
1160 Name => New_Reference_To (Fent, Loc),
1161 Parameter_Associations => New_List (
1162 Make_Attribute_Reference (Loc,
1163 Prefix => Unchecked_Convert_To (Operand_Typ,
1164 Relocate_Node (Expression (N))),
1165 Attribute_Name => Name_Address))));
1171 end Expand_Interface_Conversion;
1173 ------------------------------
1174 -- Expand_Interface_Actuals --
1175 ------------------------------
1177 procedure Expand_Interface_Actuals (Call_Node : Node_Id) is
1179 Actual_Dup : Node_Id;
1180 Actual_Typ : Entity_Id;
1182 Conversion : Node_Id;
1184 Formal_Typ : Entity_Id;
1186 Formal_DDT : Entity_Id;
1187 Actual_DDT : Entity_Id;
1190 -- This subprogram is called directly from the semantics, so we need a
1191 -- check to see whether expansion is active before proceeding.
1193 if not Expander_Active then
1197 -- Call using access to subprogram with explicit dereference
1199 if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
1200 Subp := Etype (Name (Call_Node));
1202 -- Call using selected component
1204 elsif Nkind (Name (Call_Node)) = N_Selected_Component then
1205 Subp := Entity (Selector_Name (Name (Call_Node)));
1207 -- Call using direct name
1210 Subp := Entity (Name (Call_Node));
1213 -- Ada 2005 (AI-251): Look for interface type formals to force "this"
1216 Formal := First_Formal (Subp);
1217 Actual := First_Actual (Call_Node);
1218 while Present (Formal) loop
1219 Formal_Typ := Etype (Formal);
1221 if Ekind (Formal_Typ) = E_Record_Type_With_Private then
1222 Formal_Typ := Full_View (Formal_Typ);
1225 if Is_Access_Type (Formal_Typ) then
1226 Formal_DDT := Directly_Designated_Type (Formal_Typ);
1229 Actual_Typ := Etype (Actual);
1231 if Is_Access_Type (Actual_Typ) then
1232 Actual_DDT := Directly_Designated_Type (Actual_Typ);
1235 if Is_Interface (Formal_Typ)
1236 and then Is_Class_Wide_Type (Formal_Typ)
1238 -- No need to displace the pointer if the type of the actual
1239 -- coindices with the type of the formal.
1241 if Actual_Typ = Formal_Typ then
1244 -- No need to displace the pointer if the interface type is
1245 -- a parent of the type of the actual because in this case the
1246 -- interface primitives are located in the primary dispatch table.
1248 elsif Is_Ancestor (Formal_Typ, Actual_Typ) then
1251 -- Implicit conversion to the class-wide formal type to force
1252 -- the displacement of the pointer.
1255 Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
1256 Rewrite (Actual, Conversion);
1257 Analyze_And_Resolve (Actual, Formal_Typ);
1260 -- Access to class-wide interface type
1262 elsif Is_Access_Type (Formal_Typ)
1263 and then Is_Interface (Formal_DDT)
1264 and then Is_Class_Wide_Type (Formal_DDT)
1265 and then Interface_Present_In_Ancestor
1267 Iface => Etype (Formal_DDT))
1269 -- Handle attributes 'Access and 'Unchecked_Access
1271 if Nkind (Actual) = N_Attribute_Reference
1273 (Attribute_Name (Actual) = Name_Access
1274 or else Attribute_Name (Actual) = Name_Unchecked_Access)
1276 -- This case must have been handled by the analysis and
1277 -- expansion of 'Access. The only exception is when types
1278 -- match and no further expansion is required.
1280 pragma Assert (Base_Type (Etype (Prefix (Actual)))
1281 = Base_Type (Formal_DDT));
1284 -- No need to displace the pointer if the type of the actual
1285 -- coincides with the type of the formal.
1287 elsif Actual_DDT = Formal_DDT then
1290 -- No need to displace the pointer if the interface type is
1291 -- a parent of the type of the actual because in this case the
1292 -- interface primitives are located in the primary dispatch table.
1294 elsif Is_Ancestor (Formal_DDT, Actual_DDT) then
1298 Actual_Dup := Relocate_Node (Actual);
1300 if From_With_Type (Actual_Typ) then
1302 -- If the type of the actual parameter comes from a limited
1303 -- with-clause and the non-limited view is already available
1304 -- we replace the anonymous access type by a duplicate
1305 -- declaration whose designated type is the non-limited view
1307 if Ekind (Actual_DDT) = E_Incomplete_Type
1308 and then Present (Non_Limited_View (Actual_DDT))
1310 Anon := New_Copy (Actual_Typ);
1312 if Is_Itype (Anon) then
1313 Set_Scope (Anon, Current_Scope);
1316 Set_Directly_Designated_Type (Anon,
1317 Non_Limited_View (Actual_DDT));
1318 Set_Etype (Actual_Dup, Anon);
1320 elsif Is_Class_Wide_Type (Actual_DDT)
1321 and then Ekind (Etype (Actual_DDT)) = E_Incomplete_Type
1322 and then Present (Non_Limited_View (Etype (Actual_DDT)))
1324 Anon := New_Copy (Actual_Typ);
1326 if Is_Itype (Anon) then
1327 Set_Scope (Anon, Current_Scope);
1330 Set_Directly_Designated_Type (Anon,
1331 New_Copy (Actual_DDT));
1332 Set_Class_Wide_Type (Directly_Designated_Type (Anon),
1333 New_Copy (Class_Wide_Type (Actual_DDT)));
1334 Set_Etype (Directly_Designated_Type (Anon),
1335 Non_Limited_View (Etype (Actual_DDT)));
1337 Class_Wide_Type (Directly_Designated_Type (Anon)),
1338 Non_Limited_View (Etype (Actual_DDT)));
1339 Set_Etype (Actual_Dup, Anon);
1343 Conversion := Convert_To (Formal_Typ, Actual_Dup);
1344 Rewrite (Actual, Conversion);
1345 Analyze_And_Resolve (Actual, Formal_Typ);
1349 Next_Actual (Actual);
1350 Next_Formal (Formal);
1352 end Expand_Interface_Actuals;
1354 ----------------------------
1355 -- Expand_Interface_Thunk --
1356 ----------------------------
1358 procedure Expand_Interface_Thunk
1360 Thunk_Id : out Entity_Id;
1361 Thunk_Code : out Node_Id)
1363 Loc : constant Source_Ptr := Sloc (Prim);
1364 Actuals : constant List_Id := New_List;
1365 Decl : constant List_Id := New_List;
1366 Formals : constant List_Id := New_List;
1368 Controlling_Typ : Entity_Id;
1373 Offset_To_Top : Node_Id;
1375 Target_Formal : Entity_Id;
1379 Thunk_Code := Empty;
1381 -- Traverse the list of alias to find the final target
1384 while Present (Alias (Target)) loop
1385 Target := Alias (Target);
1388 -- In case of primitives that are functions without formals and
1389 -- a controlling result there is no need to build the thunk.
1391 if not Present (First_Formal (Target)) then
1392 pragma Assert (Ekind (Target) = E_Function
1393 and then Has_Controlling_Result (Target));
1397 -- Duplicate the formals
1399 Formal := First_Formal (Target);
1400 while Present (Formal) loop
1402 Make_Parameter_Specification (Loc,
1403 Defining_Identifier =>
1404 Make_Defining_Identifier (Sloc (Formal),
1405 Chars => Chars (Formal)),
1406 In_Present => In_Present (Parent (Formal)),
1407 Out_Present => Out_Present (Parent (Formal)),
1409 New_Reference_To (Etype (Formal), Loc),
1410 Expression => New_Copy_Tree (Expression (Parent (Formal)))));
1412 Next_Formal (Formal);
1415 Controlling_Typ := Find_Dispatching_Type (Target);
1417 Target_Formal := First_Formal (Target);
1418 Formal := First (Formals);
1419 while Present (Formal) loop
1420 if Ekind (Target_Formal) = E_In_Parameter
1421 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
1422 and then Directly_Designated_Type (Etype (Target_Formal))
1427 -- type T is access all <<type of the target formal>>
1428 -- S : Storage_Offset := Storage_Offset!(Formal)
1429 -- - Offset_To_Top (address!(Formal))
1432 Make_Full_Type_Declaration (Loc,
1433 Defining_Identifier =>
1434 Make_Defining_Identifier (Loc,
1435 New_Internal_Name ('T')),
1437 Make_Access_To_Object_Definition (Loc,
1438 All_Present => True,
1439 Null_Exclusion_Present => False,
1440 Constant_Present => False,
1441 Subtype_Indication =>
1443 (Directly_Designated_Type
1444 (Etype (Target_Formal)), Loc)));
1447 Unchecked_Convert_To (RTE (RE_Address),
1448 New_Reference_To (Defining_Identifier (Formal), Loc));
1450 if not RTE_Available (RE_Offset_To_Top) then
1452 Build_Offset_To_Top (Loc, New_Arg);
1455 Make_Function_Call (Loc,
1456 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1457 Parameter_Associations => New_List (New_Arg));
1461 Make_Object_Declaration (Loc,
1462 Defining_Identifier =>
1463 Make_Defining_Identifier (Loc,
1464 New_Internal_Name ('S')),
1465 Constant_Present => True,
1466 Object_Definition =>
1467 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1469 Make_Op_Subtract (Loc,
1471 Unchecked_Convert_To
1472 (RTE (RE_Storage_Offset),
1473 New_Reference_To (Defining_Identifier (Formal), Loc)),
1477 Append_To (Decl, Decl_2);
1478 Append_To (Decl, Decl_1);
1480 -- Reference the new actual. Generate:
1484 Unchecked_Convert_To
1485 (Defining_Identifier (Decl_2),
1486 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1488 elsif Etype (Target_Formal) = Controlling_Typ then
1491 -- S1 : Storage_Offset := Storage_Offset!(Formal'Address)
1492 -- - Offset_To_Top (Formal'Address)
1493 -- S2 : Addr_Ptr := Addr_Ptr!(S1)
1496 Make_Attribute_Reference (Loc,
1498 New_Reference_To (Defining_Identifier (Formal), Loc),
1502 if not RTE_Available (RE_Offset_To_Top) then
1504 Build_Offset_To_Top (Loc, New_Arg);
1507 Make_Function_Call (Loc,
1508 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1509 Parameter_Associations => New_List (New_Arg));
1513 Make_Object_Declaration (Loc,
1514 Defining_Identifier =>
1515 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1516 Constant_Present => True,
1517 Object_Definition =>
1518 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1520 Make_Op_Subtract (Loc,
1522 Unchecked_Convert_To
1523 (RTE (RE_Storage_Offset),
1524 Make_Attribute_Reference (Loc,
1527 (Defining_Identifier (Formal), Loc),
1528 Attribute_Name => Name_Address)),
1533 Make_Object_Declaration (Loc,
1534 Defining_Identifier =>
1535 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1536 Constant_Present => True,
1537 Object_Definition => New_Reference_To (RTE (RE_Addr_Ptr), Loc),
1539 Unchecked_Convert_To
1541 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1543 Append_To (Decl, Decl_1);
1544 Append_To (Decl, Decl_2);
1546 -- Reference the new actual. Generate:
1547 -- Target_Formal (S2.all)
1550 Unchecked_Convert_To
1551 (Etype (Target_Formal),
1552 Make_Explicit_Dereference (Loc,
1553 New_Reference_To (Defining_Identifier (Decl_2), Loc))));
1555 -- No special management required for this actual
1559 New_Reference_To (Defining_Identifier (Formal), Loc));
1562 Next_Formal (Target_Formal);
1567 Make_Defining_Identifier (Loc,
1568 Chars => New_Internal_Name ('T'));
1570 Set_Is_Thunk (Thunk_Id);
1572 if Ekind (Target) = E_Procedure then
1574 Make_Subprogram_Body (Loc,
1576 Make_Procedure_Specification (Loc,
1577 Defining_Unit_Name => Thunk_Id,
1578 Parameter_Specifications => Formals),
1579 Declarations => Decl,
1580 Handled_Statement_Sequence =>
1581 Make_Handled_Sequence_Of_Statements (Loc,
1582 Statements => New_List (
1583 Make_Procedure_Call_Statement (Loc,
1584 Name => New_Occurrence_Of (Target, Loc),
1585 Parameter_Associations => Actuals))));
1587 else pragma Assert (Ekind (Target) = E_Function);
1590 Make_Subprogram_Body (Loc,
1592 Make_Function_Specification (Loc,
1593 Defining_Unit_Name => Thunk_Id,
1594 Parameter_Specifications => Formals,
1595 Result_Definition =>
1596 New_Copy (Result_Definition (Parent (Target)))),
1597 Declarations => Decl,
1598 Handled_Statement_Sequence =>
1599 Make_Handled_Sequence_Of_Statements (Loc,
1600 Statements => New_List (
1601 Make_Simple_Return_Statement (Loc,
1602 Make_Function_Call (Loc,
1603 Name => New_Occurrence_Of (Target, Loc),
1604 Parameter_Associations => Actuals)))));
1606 end Expand_Interface_Thunk;
1608 ------------------------
1609 -- Get_Scil_Node_Kind --
1610 ------------------------
1612 function Get_Scil_Node_Kind (Node : Node_Id) return Scil_Node_Kind is
1614 pragma Assert (Nkind (Node) = N_Null_Statement
1615 and then Is_Scil_Node (Node));
1617 return Scil_Node_Kind'Val (UI_To_Int (Scil_Nkind (Node)));
1618 end Get_Scil_Node_Kind;
1624 function Has_DT (Typ : Entity_Id) return Boolean is
1626 return not Is_Interface (Typ)
1627 and then not Restriction_Active (No_Dispatching_Calls);
1630 -----------------------------------------
1631 -- Is_Predefined_Dispatching_Operation --
1632 -----------------------------------------
1634 function Is_Predefined_Dispatching_Operation
1635 (E : Entity_Id) return Boolean
1637 TSS_Name : TSS_Name_Type;
1640 if not Is_Dispatching_Operation (E) then
1644 Get_Name_String (Chars (E));
1646 -- Most predefined primitives have internally generated names. Equality
1647 -- must be treated differently; the predefined operation is recognized
1648 -- as a homogeneous binary operator that returns Boolean.
1650 if Name_Len > TSS_Name_Type'Last then
1651 TSS_Name := TSS_Name_Type (Name_Buffer (Name_Len - TSS_Name'Length + 1
1653 if Chars (E) = Name_uSize
1654 or else Chars (E) = Name_uAlignment
1655 or else TSS_Name = TSS_Stream_Read
1656 or else TSS_Name = TSS_Stream_Write
1657 or else TSS_Name = TSS_Stream_Input
1658 or else TSS_Name = TSS_Stream_Output
1660 (Chars (E) = Name_Op_Eq
1661 and then Etype (First_Entity (E)) = Etype (Last_Entity (E)))
1662 or else Chars (E) = Name_uAssign
1663 or else TSS_Name = TSS_Deep_Adjust
1664 or else TSS_Name = TSS_Deep_Finalize
1665 or else Is_Predefined_Interface_Primitive (E)
1672 end Is_Predefined_Dispatching_Operation;
1674 -------------------------------------
1675 -- Is_Predefined_Dispatching_Alias --
1676 -------------------------------------
1678 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
1683 if not Is_Predefined_Dispatching_Operation (Prim)
1684 and then Present (Alias (Prim))
1687 while Present (Alias (E)) loop
1691 if Is_Predefined_Dispatching_Operation (E) then
1697 end Is_Predefined_Dispatching_Alias;
1699 ---------------------------------------
1700 -- Is_Predefined_Interface_Primitive --
1701 ---------------------------------------
1703 function Is_Predefined_Interface_Primitive (E : Entity_Id) return Boolean is
1705 return Ada_Version >= Ada_05
1706 and then (Chars (E) = Name_uDisp_Asynchronous_Select or else
1707 Chars (E) = Name_uDisp_Conditional_Select or else
1708 Chars (E) = Name_uDisp_Get_Prim_Op_Kind or else
1709 Chars (E) = Name_uDisp_Get_Task_Id or else
1710 Chars (E) = Name_uDisp_Requeue or else
1711 Chars (E) = Name_uDisp_Timed_Select);
1712 end Is_Predefined_Interface_Primitive;
1714 ----------------------------------------
1715 -- Make_Disp_Asynchronous_Select_Body --
1716 ----------------------------------------
1718 -- For interface types, generate:
1720 -- procedure _Disp_Asynchronous_Select
1721 -- (T : in out <Typ>;
1723 -- P : System.Address;
1724 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1729 -- end _Disp_Asynchronous_Select;
1731 -- For protected types, generate:
1733 -- procedure _Disp_Asynchronous_Select
1734 -- (T : in out <Typ>;
1736 -- P : System.Address;
1737 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1741 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1742 -- Bnn : System.Tasking.Protected_Objects.Operations.
1743 -- Communication_Block;
1745 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
1746 -- (T._object'Access,
1747 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
1749 -- System.Tasking.Asynchronous_Call,
1751 -- B := System.Storage_Elements.Dummy_Communication_Block (Bnn);
1752 -- end _Disp_Asynchronous_Select;
1754 -- For task types, generate:
1756 -- procedure _Disp_Asynchronous_Select
1757 -- (T : in out <Typ>;
1759 -- P : System.Address;
1760 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1764 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1766 -- System.Tasking.Rendezvous.Task_Entry_Call
1768 -- System.Tasking.Task_Entry_Index (I),
1770 -- System.Tasking.Asynchronous_Call,
1772 -- end _Disp_Asynchronous_Select;
1774 function Make_Disp_Asynchronous_Select_Body
1775 (Typ : Entity_Id) return Node_Id
1777 Com_Block : Entity_Id;
1778 Conc_Typ : Entity_Id := Empty;
1779 Decls : constant List_Id := New_List;
1781 Loc : constant Source_Ptr := Sloc (Typ);
1783 Stmts : constant List_Id := New_List;
1786 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1788 -- Null body is generated for interface types
1790 if Is_Interface (Typ) then
1792 Make_Subprogram_Body (Loc,
1794 Make_Disp_Asynchronous_Select_Spec (Typ),
1797 Handled_Statement_Sequence =>
1798 Make_Handled_Sequence_Of_Statements (Loc,
1799 New_List (Make_Null_Statement (Loc))));
1802 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1804 if Is_Concurrent_Record_Type (Typ) then
1805 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1809 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
1811 -- where I will be used to capture the entry index of the primitive
1812 -- wrapper at position S.
1815 Make_Object_Declaration (Loc,
1816 Defining_Identifier =>
1817 Make_Defining_Identifier (Loc, Name_uI),
1818 Object_Definition =>
1819 New_Reference_To (Standard_Integer, Loc),
1821 Make_Function_Call (Loc,
1823 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
1824 Parameter_Associations =>
1826 Unchecked_Convert_To (RTE (RE_Tag),
1827 New_Reference_To (DT_Ptr, Loc)),
1828 Make_Identifier (Loc, Name_uS)))));
1830 if Ekind (Conc_Typ) = E_Protected_Type then
1833 -- Bnn : Communication_Block;
1836 Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1839 Make_Object_Declaration (Loc,
1840 Defining_Identifier =>
1842 Object_Definition =>
1843 New_Reference_To (RTE (RE_Communication_Block), Loc)));
1845 -- Build T._object'Access for calls below
1848 Make_Attribute_Reference (Loc,
1849 Attribute_Name => Name_Unchecked_Access,
1851 Make_Selected_Component (Loc,
1852 Prefix => Make_Identifier (Loc, Name_uT),
1853 Selector_Name => Make_Identifier (Loc, Name_uObject)));
1855 case Corresponding_Runtime_Package (Conc_Typ) is
1856 when System_Tasking_Protected_Objects_Entries =>
1859 -- Protected_Entry_Call
1860 -- (T._object'Access, -- Object
1861 -- Protected_Entry_Index! (I), -- E
1862 -- P, -- Uninterpreted_Data
1863 -- Asynchronous_Call, -- Mode
1864 -- Bnn); -- Communication_Block
1866 -- where T is the protected object, I is the entry index, P
1867 -- is the wrapped parameters and B is the name of the
1868 -- communication block.
1871 Make_Procedure_Call_Statement (Loc,
1873 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1874 Parameter_Associations =>
1878 Make_Unchecked_Type_Conversion (Loc, -- entry index
1881 (RTE (RE_Protected_Entry_Index), Loc),
1882 Expression => Make_Identifier (Loc, Name_uI)),
1884 Make_Identifier (Loc, Name_uP), -- parameter block
1885 New_Reference_To ( -- Asynchronous_Call
1886 RTE (RE_Asynchronous_Call), Loc),
1888 New_Reference_To (Com_Block, Loc)))); -- comm block
1890 when System_Tasking_Protected_Objects_Single_Entry =>
1893 -- procedure Protected_Single_Entry_Call
1894 -- (Object : Protection_Entry_Access;
1895 -- Uninterpreted_Data : System.Address;
1896 -- Mode : Call_Modes);
1899 Make_Procedure_Call_Statement (Loc,
1902 (RTE (RE_Protected_Single_Entry_Call), Loc),
1903 Parameter_Associations =>
1907 Make_Attribute_Reference (Loc,
1908 Prefix => Make_Identifier (Loc, Name_uP),
1909 Attribute_Name => Name_Address),
1912 (RTE (RE_Asynchronous_Call), Loc))));
1915 raise Program_Error;
1919 -- B := Dummy_Communication_Block (Bnn);
1922 Make_Assignment_Statement (Loc,
1924 Make_Identifier (Loc, Name_uB),
1926 Make_Unchecked_Type_Conversion (Loc,
1929 RTE (RE_Dummy_Communication_Block), Loc),
1931 New_Reference_To (Com_Block, Loc))));
1934 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
1938 -- (T._task_id, -- Acceptor
1939 -- Task_Entry_Index! (I), -- E
1940 -- P, -- Uninterpreted_Data
1941 -- Asynchronous_Call, -- Mode
1942 -- F); -- Rendezvous_Successful
1944 -- where T is the task object, I is the entry index, P is the
1945 -- wrapped parameters and F is the status flag.
1948 Make_Procedure_Call_Statement (Loc,
1950 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
1951 Parameter_Associations =>
1953 Make_Selected_Component (Loc, -- T._task_id
1955 Make_Identifier (Loc, Name_uT),
1957 Make_Identifier (Loc, Name_uTask_Id)),
1959 Make_Unchecked_Type_Conversion (Loc, -- entry index
1961 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
1963 Make_Identifier (Loc, Name_uI)),
1965 Make_Identifier (Loc, Name_uP), -- parameter block
1966 New_Reference_To ( -- Asynchronous_Call
1967 RTE (RE_Asynchronous_Call), Loc),
1968 Make_Identifier (Loc, Name_uF)))); -- status flag
1972 -- Ensure that the statements list is non-empty
1974 Append_To (Stmts, Make_Null_Statement (Loc));
1978 Make_Subprogram_Body (Loc,
1980 Make_Disp_Asynchronous_Select_Spec (Typ),
1983 Handled_Statement_Sequence =>
1984 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
1985 end Make_Disp_Asynchronous_Select_Body;
1987 ----------------------------------------
1988 -- Make_Disp_Asynchronous_Select_Spec --
1989 ----------------------------------------
1991 function Make_Disp_Asynchronous_Select_Spec
1992 (Typ : Entity_Id) return Node_Id
1994 Loc : constant Source_Ptr := Sloc (Typ);
1995 Def_Id : constant Node_Id :=
1996 Make_Defining_Identifier (Loc,
1997 Name_uDisp_Asynchronous_Select);
1998 Params : constant List_Id := New_List;
2001 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2003 -- T : in out Typ; -- Object parameter
2004 -- S : Integer; -- Primitive operation slot
2005 -- P : Address; -- Wrapped parameters
2006 -- B : out Dummy_Communication_Block; -- Communication block dummy
2007 -- F : out Boolean; -- Status flag
2009 Append_List_To (Params, New_List (
2011 Make_Parameter_Specification (Loc,
2012 Defining_Identifier =>
2013 Make_Defining_Identifier (Loc, Name_uT),
2015 New_Reference_To (Typ, Loc),
2017 Out_Present => True),
2019 Make_Parameter_Specification (Loc,
2020 Defining_Identifier =>
2021 Make_Defining_Identifier (Loc, Name_uS),
2023 New_Reference_To (Standard_Integer, Loc)),
2025 Make_Parameter_Specification (Loc,
2026 Defining_Identifier =>
2027 Make_Defining_Identifier (Loc, Name_uP),
2029 New_Reference_To (RTE (RE_Address), Loc)),
2031 Make_Parameter_Specification (Loc,
2032 Defining_Identifier =>
2033 Make_Defining_Identifier (Loc, Name_uB),
2035 New_Reference_To (RTE (RE_Dummy_Communication_Block), Loc),
2036 Out_Present => True),
2038 Make_Parameter_Specification (Loc,
2039 Defining_Identifier =>
2040 Make_Defining_Identifier (Loc, Name_uF),
2042 New_Reference_To (Standard_Boolean, Loc),
2043 Out_Present => True)));
2046 Make_Procedure_Specification (Loc,
2047 Defining_Unit_Name => Def_Id,
2048 Parameter_Specifications => Params);
2049 end Make_Disp_Asynchronous_Select_Spec;
2051 ---------------------------------------
2052 -- Make_Disp_Conditional_Select_Body --
2053 ---------------------------------------
2055 -- For interface types, generate:
2057 -- procedure _Disp_Conditional_Select
2058 -- (T : in out <Typ>;
2060 -- P : System.Address;
2061 -- C : out Ada.Tags.Prim_Op_Kind;
2066 -- end _Disp_Conditional_Select;
2068 -- For protected types, generate:
2070 -- procedure _Disp_Conditional_Select
2071 -- (T : in out <Typ>;
2073 -- P : System.Address;
2074 -- C : out Ada.Tags.Prim_Op_Kind;
2078 -- Bnn : System.Tasking.Protected_Objects.Operations.
2079 -- Communication_Block;
2082 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP, S));
2084 -- if C = Ada.Tags.POK_Procedure
2085 -- or else C = Ada.Tags.POK_Protected_Procedure
2086 -- or else C = Ada.Tags.POK_Task_Procedure
2092 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2093 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
2094 -- (T.object'Access,
2095 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
2097 -- System.Tasking.Conditional_Call,
2099 -- F := not Cancelled (Bnn);
2100 -- end _Disp_Conditional_Select;
2102 -- For task types, generate:
2104 -- procedure _Disp_Conditional_Select
2105 -- (T : in out <Typ>;
2107 -- P : System.Address;
2108 -- C : out Ada.Tags.Prim_Op_Kind;
2114 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2115 -- System.Tasking.Rendezvous.Task_Entry_Call
2117 -- System.Tasking.Task_Entry_Index (I),
2119 -- System.Tasking.Conditional_Call,
2121 -- end _Disp_Conditional_Select;
2123 function Make_Disp_Conditional_Select_Body
2124 (Typ : Entity_Id) return Node_Id
2126 Loc : constant Source_Ptr := Sloc (Typ);
2127 Blk_Nam : Entity_Id;
2128 Conc_Typ : Entity_Id := Empty;
2129 Decls : constant List_Id := New_List;
2132 Stmts : constant List_Id := New_List;
2135 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2137 -- Null body is generated for interface types
2139 if Is_Interface (Typ) then
2141 Make_Subprogram_Body (Loc,
2143 Make_Disp_Conditional_Select_Spec (Typ),
2146 Handled_Statement_Sequence =>
2147 Make_Handled_Sequence_Of_Statements (Loc,
2148 New_List (Make_Null_Statement (Loc))));
2151 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2153 if Is_Concurrent_Record_Type (Typ) then
2154 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2159 -- where I will be used to capture the entry index of the primitive
2160 -- wrapper at position S.
2163 Make_Object_Declaration (Loc,
2164 Defining_Identifier =>
2165 Make_Defining_Identifier (Loc, Name_uI),
2166 Object_Definition =>
2167 New_Reference_To (Standard_Integer, Loc)));
2170 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag! (<type>VP), S);
2172 -- if C = POK_Procedure
2173 -- or else C = POK_Protected_Procedure
2174 -- or else C = POK_Task_Procedure;
2180 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
2183 -- Bnn : Communication_Block;
2185 -- where Bnn is the name of the communication block used in the
2186 -- call to Protected_Entry_Call.
2188 Blk_Nam := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
2191 Make_Object_Declaration (Loc,
2192 Defining_Identifier =>
2194 Object_Definition =>
2195 New_Reference_To (RTE (RE_Communication_Block), Loc)));
2198 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
2200 -- I is the entry index and S is the dispatch table slot
2203 Make_Assignment_Statement (Loc,
2205 Make_Identifier (Loc, Name_uI),
2207 Make_Function_Call (Loc,
2209 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
2210 Parameter_Associations =>
2212 Unchecked_Convert_To (RTE (RE_Tag),
2213 New_Reference_To (DT_Ptr, Loc)),
2214 Make_Identifier (Loc, Name_uS)))));
2216 if Ekind (Conc_Typ) = E_Protected_Type then
2218 Obj_Ref := -- T._object'Access
2219 Make_Attribute_Reference (Loc,
2220 Attribute_Name => Name_Unchecked_Access,
2222 Make_Selected_Component (Loc,
2223 Prefix => Make_Identifier (Loc, Name_uT),
2224 Selector_Name => Make_Identifier (Loc, Name_uObject)));
2226 case Corresponding_Runtime_Package (Conc_Typ) is
2227 when System_Tasking_Protected_Objects_Entries =>
2230 -- Protected_Entry_Call
2231 -- (T._object'Access, -- Object
2232 -- Protected_Entry_Index! (I), -- E
2233 -- P, -- Uninterpreted_Data
2234 -- Conditional_Call, -- Mode
2237 -- where T is the protected object, I is the entry index, P
2238 -- are the wrapped parameters and Bnn is the name of the
2239 -- communication block.
2242 Make_Procedure_Call_Statement (Loc,
2244 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
2245 Parameter_Associations =>
2249 Make_Unchecked_Type_Conversion (Loc, -- entry index
2252 (RTE (RE_Protected_Entry_Index), Loc),
2253 Expression => Make_Identifier (Loc, Name_uI)),
2255 Make_Identifier (Loc, Name_uP), -- parameter block
2257 New_Reference_To ( -- Conditional_Call
2258 RTE (RE_Conditional_Call), Loc),
2259 New_Reference_To ( -- Bnn
2262 when System_Tasking_Protected_Objects_Single_Entry =>
2264 -- If we are compiling for a restricted run-time, the call
2265 -- uses the simpler form.
2268 Make_Procedure_Call_Statement (Loc,
2271 (RTE (RE_Protected_Single_Entry_Call), Loc),
2272 Parameter_Associations =>
2276 Make_Attribute_Reference (Loc,
2277 Prefix => Make_Identifier (Loc, Name_uP),
2278 Attribute_Name => Name_Address),
2281 (RTE (RE_Conditional_Call), Loc))));
2283 raise Program_Error;
2287 -- F := not Cancelled (Bnn);
2289 -- where F is the success flag. The status of Cancelled is negated
2290 -- in order to match the behaviour of the version for task types.
2293 Make_Assignment_Statement (Loc,
2295 Make_Identifier (Loc, Name_uF),
2299 Make_Function_Call (Loc,
2301 New_Reference_To (RTE (RE_Cancelled), Loc),
2302 Parameter_Associations =>
2304 New_Reference_To (Blk_Nam, Loc))))));
2306 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2310 -- (T._task_id, -- Acceptor
2311 -- Task_Entry_Index! (I), -- E
2312 -- P, -- Uninterpreted_Data
2313 -- Conditional_Call, -- Mode
2314 -- F); -- Rendezvous_Successful
2316 -- where T is the task object, I is the entry index, P are the
2317 -- wrapped parameters and F is the status flag.
2320 Make_Procedure_Call_Statement (Loc,
2322 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
2323 Parameter_Associations =>
2326 Make_Selected_Component (Loc, -- T._task_id
2328 Make_Identifier (Loc, Name_uT),
2330 Make_Identifier (Loc, Name_uTask_Id)),
2332 Make_Unchecked_Type_Conversion (Loc, -- entry index
2334 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2336 Make_Identifier (Loc, Name_uI)),
2338 Make_Identifier (Loc, Name_uP), -- parameter block
2339 New_Reference_To ( -- Conditional_Call
2340 RTE (RE_Conditional_Call), Loc),
2341 Make_Identifier (Loc, Name_uF)))); -- status flag
2345 -- Ensure that the statements list is non-empty
2347 Append_To (Stmts, Make_Null_Statement (Loc));
2351 Make_Subprogram_Body (Loc,
2353 Make_Disp_Conditional_Select_Spec (Typ),
2356 Handled_Statement_Sequence =>
2357 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2358 end Make_Disp_Conditional_Select_Body;
2360 ---------------------------------------
2361 -- Make_Disp_Conditional_Select_Spec --
2362 ---------------------------------------
2364 function Make_Disp_Conditional_Select_Spec
2365 (Typ : Entity_Id) return Node_Id
2367 Loc : constant Source_Ptr := Sloc (Typ);
2368 Def_Id : constant Node_Id :=
2369 Make_Defining_Identifier (Loc,
2370 Name_uDisp_Conditional_Select);
2371 Params : constant List_Id := New_List;
2374 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2376 -- T : in out Typ; -- Object parameter
2377 -- S : Integer; -- Primitive operation slot
2378 -- P : Address; -- Wrapped parameters
2379 -- C : out Prim_Op_Kind; -- Call kind
2380 -- F : out Boolean; -- Status flag
2382 Append_List_To (Params, New_List (
2384 Make_Parameter_Specification (Loc,
2385 Defining_Identifier =>
2386 Make_Defining_Identifier (Loc, Name_uT),
2388 New_Reference_To (Typ, Loc),
2390 Out_Present => True),
2392 Make_Parameter_Specification (Loc,
2393 Defining_Identifier =>
2394 Make_Defining_Identifier (Loc, Name_uS),
2396 New_Reference_To (Standard_Integer, Loc)),
2398 Make_Parameter_Specification (Loc,
2399 Defining_Identifier =>
2400 Make_Defining_Identifier (Loc, Name_uP),
2402 New_Reference_To (RTE (RE_Address), Loc)),
2404 Make_Parameter_Specification (Loc,
2405 Defining_Identifier =>
2406 Make_Defining_Identifier (Loc, Name_uC),
2408 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2409 Out_Present => True),
2411 Make_Parameter_Specification (Loc,
2412 Defining_Identifier =>
2413 Make_Defining_Identifier (Loc, Name_uF),
2415 New_Reference_To (Standard_Boolean, Loc),
2416 Out_Present => True)));
2419 Make_Procedure_Specification (Loc,
2420 Defining_Unit_Name => Def_Id,
2421 Parameter_Specifications => Params);
2422 end Make_Disp_Conditional_Select_Spec;
2424 -------------------------------------
2425 -- Make_Disp_Get_Prim_Op_Kind_Body --
2426 -------------------------------------
2428 function Make_Disp_Get_Prim_Op_Kind_Body
2429 (Typ : Entity_Id) return Node_Id
2431 Loc : constant Source_Ptr := Sloc (Typ);
2435 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2437 if Is_Interface (Typ) then
2439 Make_Subprogram_Body (Loc,
2441 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2444 Handled_Statement_Sequence =>
2445 Make_Handled_Sequence_Of_Statements (Loc,
2446 New_List (Make_Null_Statement (Loc))));
2449 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2452 -- C := get_prim_op_kind (tag! (<type>VP), S);
2454 -- where C is the out parameter capturing the call kind and S is the
2455 -- dispatch table slot number.
2458 Make_Subprogram_Body (Loc,
2460 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2463 Handled_Statement_Sequence =>
2464 Make_Handled_Sequence_Of_Statements (Loc,
2466 Make_Assignment_Statement (Loc,
2468 Make_Identifier (Loc, Name_uC),
2470 Make_Function_Call (Loc,
2472 New_Reference_To (RTE (RE_Get_Prim_Op_Kind), Loc),
2473 Parameter_Associations => New_List (
2474 Unchecked_Convert_To (RTE (RE_Tag),
2475 New_Reference_To (DT_Ptr, Loc)),
2476 Make_Identifier (Loc, Name_uS)))))));
2477 end Make_Disp_Get_Prim_Op_Kind_Body;
2479 -------------------------------------
2480 -- Make_Disp_Get_Prim_Op_Kind_Spec --
2481 -------------------------------------
2483 function Make_Disp_Get_Prim_Op_Kind_Spec
2484 (Typ : Entity_Id) return Node_Id
2486 Loc : constant Source_Ptr := Sloc (Typ);
2487 Def_Id : constant Node_Id :=
2488 Make_Defining_Identifier (Loc,
2489 Name_uDisp_Get_Prim_Op_Kind);
2490 Params : constant List_Id := New_List;
2493 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2495 -- T : in out Typ; -- Object parameter
2496 -- S : Integer; -- Primitive operation slot
2497 -- C : out Prim_Op_Kind; -- Call kind
2499 Append_List_To (Params, New_List (
2501 Make_Parameter_Specification (Loc,
2502 Defining_Identifier =>
2503 Make_Defining_Identifier (Loc, Name_uT),
2505 New_Reference_To (Typ, Loc),
2507 Out_Present => True),
2509 Make_Parameter_Specification (Loc,
2510 Defining_Identifier =>
2511 Make_Defining_Identifier (Loc, Name_uS),
2513 New_Reference_To (Standard_Integer, Loc)),
2515 Make_Parameter_Specification (Loc,
2516 Defining_Identifier =>
2517 Make_Defining_Identifier (Loc, Name_uC),
2519 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2520 Out_Present => True)));
2523 Make_Procedure_Specification (Loc,
2524 Defining_Unit_Name => Def_Id,
2525 Parameter_Specifications => Params);
2526 end Make_Disp_Get_Prim_Op_Kind_Spec;
2528 --------------------------------
2529 -- Make_Disp_Get_Task_Id_Body --
2530 --------------------------------
2532 function Make_Disp_Get_Task_Id_Body
2533 (Typ : Entity_Id) return Node_Id
2535 Loc : constant Source_Ptr := Sloc (Typ);
2539 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2541 if Is_Concurrent_Record_Type (Typ)
2542 and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
2545 -- return To_Address (_T._task_id);
2548 Make_Simple_Return_Statement (Loc,
2550 Make_Unchecked_Type_Conversion (Loc,
2552 New_Reference_To (RTE (RE_Address), Loc),
2554 Make_Selected_Component (Loc,
2556 Make_Identifier (Loc, Name_uT),
2558 Make_Identifier (Loc, Name_uTask_Id))));
2560 -- A null body is constructed for non-task types
2564 -- return Null_Address;
2567 Make_Simple_Return_Statement (Loc,
2569 New_Reference_To (RTE (RE_Null_Address), Loc));
2573 Make_Subprogram_Body (Loc,
2575 Make_Disp_Get_Task_Id_Spec (Typ),
2578 Handled_Statement_Sequence =>
2579 Make_Handled_Sequence_Of_Statements (Loc,
2581 end Make_Disp_Get_Task_Id_Body;
2583 --------------------------------
2584 -- Make_Disp_Get_Task_Id_Spec --
2585 --------------------------------
2587 function Make_Disp_Get_Task_Id_Spec
2588 (Typ : Entity_Id) return Node_Id
2590 Loc : constant Source_Ptr := Sloc (Typ);
2593 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2596 Make_Function_Specification (Loc,
2597 Defining_Unit_Name =>
2598 Make_Defining_Identifier (Loc, Name_uDisp_Get_Task_Id),
2599 Parameter_Specifications => New_List (
2600 Make_Parameter_Specification (Loc,
2601 Defining_Identifier =>
2602 Make_Defining_Identifier (Loc, Name_uT),
2604 New_Reference_To (Typ, Loc))),
2605 Result_Definition =>
2606 New_Reference_To (RTE (RE_Address), Loc));
2607 end Make_Disp_Get_Task_Id_Spec;
2609 ----------------------------
2610 -- Make_Disp_Requeue_Body --
2611 ----------------------------
2613 function Make_Disp_Requeue_Body
2614 (Typ : Entity_Id) return Node_Id
2616 Loc : constant Source_Ptr := Sloc (Typ);
2617 Conc_Typ : Entity_Id := Empty;
2618 Stmts : constant List_Id := New_List;
2621 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2623 -- Null body is generated for interface types and non-concurrent
2626 if Is_Interface (Typ)
2627 or else not Is_Concurrent_Record_Type (Typ)
2630 Make_Subprogram_Body (Loc,
2632 Make_Disp_Requeue_Spec (Typ),
2635 Handled_Statement_Sequence =>
2636 Make_Handled_Sequence_Of_Statements (Loc,
2637 New_List (Make_Null_Statement (Loc))));
2640 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2642 if Ekind (Conc_Typ) = E_Protected_Type then
2644 -- Generate statements:
2646 -- System.Tasking.Protected_Objects.Operations.
2647 -- Requeue_Protected_Entry
2648 -- (Protection_Entries_Access (P),
2649 -- O._object'Unchecked_Access,
2650 -- Protected_Entry_Index (I),
2653 -- System.Tasking.Protected_Objects.Operations.
2654 -- Requeue_Task_To_Protected_Entry
2655 -- (O._object'Unchecked_Access,
2656 -- Protected_Entry_Index (I),
2660 if Restriction_Active (No_Entry_Queue) then
2661 Append_To (Stmts, Make_Null_Statement (Loc));
2664 Make_If_Statement (Loc,
2666 Make_Identifier (Loc, Name_uF),
2671 -- Call to Requeue_Protected_Entry
2673 Make_Procedure_Call_Statement (Loc,
2676 RTE (RE_Requeue_Protected_Entry), Loc),
2677 Parameter_Associations =>
2680 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
2683 RTE (RE_Protection_Entries_Access), Loc),
2685 Make_Identifier (Loc, Name_uP)),
2687 Make_Attribute_Reference (Loc, -- O._object'Acc
2689 Name_Unchecked_Access,
2691 Make_Selected_Component (Loc,
2693 Make_Identifier (Loc, Name_uO),
2695 Make_Identifier (Loc, Name_uObject))),
2697 Make_Unchecked_Type_Conversion (Loc, -- entry index
2700 RTE (RE_Protected_Entry_Index), Loc),
2702 Make_Identifier (Loc, Name_uI)),
2704 Make_Identifier (Loc, Name_uA)))), -- abort status
2709 -- Call to Requeue_Task_To_Protected_Entry
2711 Make_Procedure_Call_Statement (Loc,
2714 RTE (RE_Requeue_Task_To_Protected_Entry), Loc),
2715 Parameter_Associations =>
2718 Make_Attribute_Reference (Loc, -- O._object'Acc
2720 Name_Unchecked_Access,
2722 Make_Selected_Component (Loc,
2724 Make_Identifier (Loc, Name_uO),
2726 Make_Identifier (Loc, Name_uObject))),
2728 Make_Unchecked_Type_Conversion (Loc, -- entry index
2731 RTE (RE_Protected_Entry_Index), Loc),
2733 Make_Identifier (Loc, Name_uI)),
2735 Make_Identifier (Loc, Name_uA)))))); -- abort status
2738 pragma Assert (Is_Task_Type (Conc_Typ));
2742 -- System.Tasking.Rendezvous.Requeue_Protected_To_Task_Entry
2743 -- (Protection_Entries_Access (P),
2745 -- Task_Entry_Index (I),
2748 -- System.Tasking.Rendezvous.Requeue_Task_Entry
2750 -- Task_Entry_Index (I),
2755 Make_If_Statement (Loc,
2757 Make_Identifier (Loc, Name_uF),
2762 -- Call to Requeue_Protected_To_Task_Entry
2764 Make_Procedure_Call_Statement (Loc,
2767 RTE (RE_Requeue_Protected_To_Task_Entry), Loc),
2769 Parameter_Associations =>
2772 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
2775 RTE (RE_Protection_Entries_Access), Loc),
2777 Make_Identifier (Loc, Name_uP)),
2779 Make_Selected_Component (Loc, -- O._task_id
2781 Make_Identifier (Loc, Name_uO),
2783 Make_Identifier (Loc, Name_uTask_Id)),
2785 Make_Unchecked_Type_Conversion (Loc, -- entry index
2788 RTE (RE_Task_Entry_Index), Loc),
2790 Make_Identifier (Loc, Name_uI)),
2792 Make_Identifier (Loc, Name_uA)))), -- abort status
2797 -- Call to Requeue_Task_Entry
2799 Make_Procedure_Call_Statement (Loc,
2801 New_Reference_To (RTE (RE_Requeue_Task_Entry), Loc),
2803 Parameter_Associations =>
2806 Make_Selected_Component (Loc, -- O._task_id
2808 Make_Identifier (Loc, Name_uO),
2810 Make_Identifier (Loc, Name_uTask_Id)),
2812 Make_Unchecked_Type_Conversion (Loc, -- entry index
2815 RTE (RE_Task_Entry_Index), Loc),
2817 Make_Identifier (Loc, Name_uI)),
2819 Make_Identifier (Loc, Name_uA)))))); -- abort status
2822 -- Even though no declarations are needed in both cases, we allocate
2823 -- a list for entities added by Freeze.
2826 Make_Subprogram_Body (Loc,
2828 Make_Disp_Requeue_Spec (Typ),
2831 Handled_Statement_Sequence =>
2832 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2833 end Make_Disp_Requeue_Body;
2835 ----------------------------
2836 -- Make_Disp_Requeue_Spec --
2837 ----------------------------
2839 function Make_Disp_Requeue_Spec
2840 (Typ : Entity_Id) return Node_Id
2842 Loc : constant Source_Ptr := Sloc (Typ);
2845 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2847 -- O : in out Typ; - Object parameter
2848 -- F : Boolean; - Protected (True) / task (False) flag
2849 -- P : Address; - Protection_Entries_Access value
2850 -- I : Entry_Index - Index of entry call
2851 -- A : Boolean - Abort flag
2853 -- Note that the Protection_Entries_Access value is represented as a
2854 -- System.Address in order to avoid dragging in the tasking runtime
2855 -- when compiling sources without tasking constructs.
2858 Make_Procedure_Specification (Loc,
2859 Defining_Unit_Name =>
2860 Make_Defining_Identifier (Loc, Name_uDisp_Requeue),
2862 Parameter_Specifications =>
2865 Make_Parameter_Specification (Loc, -- O
2866 Defining_Identifier =>
2867 Make_Defining_Identifier (Loc, Name_uO),
2869 New_Reference_To (Typ, Loc),
2871 Out_Present => True),
2873 Make_Parameter_Specification (Loc, -- F
2874 Defining_Identifier =>
2875 Make_Defining_Identifier (Loc, Name_uF),
2877 New_Reference_To (Standard_Boolean, Loc)),
2879 Make_Parameter_Specification (Loc, -- P
2880 Defining_Identifier =>
2881 Make_Defining_Identifier (Loc, Name_uP),
2883 New_Reference_To (RTE (RE_Address), Loc)),
2885 Make_Parameter_Specification (Loc, -- I
2886 Defining_Identifier =>
2887 Make_Defining_Identifier (Loc, Name_uI),
2889 New_Reference_To (Standard_Integer, Loc)),
2891 Make_Parameter_Specification (Loc, -- A
2892 Defining_Identifier =>
2893 Make_Defining_Identifier (Loc, Name_uA),
2895 New_Reference_To (Standard_Boolean, Loc))));
2896 end Make_Disp_Requeue_Spec;
2898 ---------------------------------
2899 -- Make_Disp_Timed_Select_Body --
2900 ---------------------------------
2902 -- For interface types, generate:
2904 -- procedure _Disp_Timed_Select
2905 -- (T : in out <Typ>;
2907 -- P : System.Address;
2910 -- C : out Ada.Tags.Prim_Op_Kind;
2915 -- end _Disp_Timed_Select;
2917 -- For protected types, generate:
2919 -- procedure _Disp_Timed_Select
2920 -- (T : in out <Typ>;
2922 -- P : System.Address;
2925 -- C : out Ada.Tags.Prim_Op_Kind;
2931 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP), S);
2933 -- if C = Ada.Tags.POK_Procedure
2934 -- or else C = Ada.Tags.POK_Protected_Procedure
2935 -- or else C = Ada.Tags.POK_Task_Procedure
2941 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
2942 -- System.Tasking.Protected_Objects.Operations.
2943 -- Timed_Protected_Entry_Call
2944 -- (T._object'Access,
2945 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
2950 -- end _Disp_Timed_Select;
2952 -- For task types, generate:
2954 -- procedure _Disp_Timed_Select
2955 -- (T : in out <Typ>;
2957 -- P : System.Address;
2960 -- C : out Ada.Tags.Prim_Op_Kind;
2966 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
2967 -- System.Tasking.Rendezvous.Timed_Task_Entry_Call
2969 -- System.Tasking.Task_Entry_Index (I),
2974 -- end _Disp_Time_Select;
2976 function Make_Disp_Timed_Select_Body
2977 (Typ : Entity_Id) return Node_Id
2979 Loc : constant Source_Ptr := Sloc (Typ);
2980 Conc_Typ : Entity_Id := Empty;
2981 Decls : constant List_Id := New_List;
2984 Stmts : constant List_Id := New_List;
2987 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2989 -- Null body is generated for interface types
2991 if Is_Interface (Typ) then
2993 Make_Subprogram_Body (Loc,
2995 Make_Disp_Timed_Select_Spec (Typ),
2998 Handled_Statement_Sequence =>
2999 Make_Handled_Sequence_Of_Statements (Loc,
3000 New_List (Make_Null_Statement (Loc))));
3003 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
3005 if Is_Concurrent_Record_Type (Typ) then
3006 Conc_Typ := Corresponding_Concurrent_Type (Typ);
3011 -- where I will be used to capture the entry index of the primitive
3012 -- wrapper at position S.
3015 Make_Object_Declaration (Loc,
3016 Defining_Identifier =>
3017 Make_Defining_Identifier (Loc, Name_uI),
3018 Object_Definition =>
3019 New_Reference_To (Standard_Integer, Loc)));
3022 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
3024 -- if C = POK_Procedure
3025 -- or else C = POK_Protected_Procedure
3026 -- or else C = POK_Task_Procedure;
3032 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
3035 -- I := Get_Entry_Index (tag! (<type>VP), S);
3037 -- I is the entry index and S is the dispatch table slot
3040 Make_Assignment_Statement (Loc,
3042 Make_Identifier (Loc, Name_uI),
3044 Make_Function_Call (Loc,
3046 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
3047 Parameter_Associations =>
3049 Unchecked_Convert_To (RTE (RE_Tag),
3050 New_Reference_To (DT_Ptr, Loc)),
3051 Make_Identifier (Loc, Name_uS)))));
3055 if Ekind (Conc_Typ) = E_Protected_Type then
3057 -- Build T._object'Access
3060 Make_Attribute_Reference (Loc,
3061 Attribute_Name => Name_Unchecked_Access,
3063 Make_Selected_Component (Loc,
3064 Prefix => Make_Identifier (Loc, Name_uT),
3065 Selector_Name => Make_Identifier (Loc, Name_uObject)));
3067 -- Normal case, No_Entry_Queue restriction not active. In this
3068 -- case we generate:
3070 -- Timed_Protected_Entry_Call
3071 -- (T._object'access,
3072 -- Protected_Entry_Index! (I),
3075 -- where T is the protected object, I is the entry index, P are
3076 -- the wrapped parameters, D is the delay amount, M is the delay
3077 -- mode and F is the status flag.
3079 case Corresponding_Runtime_Package (Conc_Typ) is
3080 when System_Tasking_Protected_Objects_Entries =>
3082 Make_Procedure_Call_Statement (Loc,
3085 (RTE (RE_Timed_Protected_Entry_Call), Loc),
3086 Parameter_Associations =>
3090 Make_Unchecked_Type_Conversion (Loc, -- entry index
3093 (RTE (RE_Protected_Entry_Index), Loc),
3095 Make_Identifier (Loc, Name_uI)),
3097 Make_Identifier (Loc, Name_uP), -- parameter block
3098 Make_Identifier (Loc, Name_uD), -- delay
3099 Make_Identifier (Loc, Name_uM), -- delay mode
3100 Make_Identifier (Loc, Name_uF)))); -- status flag
3102 when System_Tasking_Protected_Objects_Single_Entry =>
3105 -- Timed_Protected_Single_Entry_Call
3106 -- (T._object'access, P, D, M, F);
3108 -- where T is the protected object, P is the wrapped
3109 -- parameters, D is the delay amount, M is the delay mode, F
3110 -- is the status flag.
3113 Make_Procedure_Call_Statement (Loc,
3116 (RTE (RE_Timed_Protected_Single_Entry_Call), Loc),
3117 Parameter_Associations =>
3120 Make_Identifier (Loc, Name_uP), -- parameter block
3121 Make_Identifier (Loc, Name_uD), -- delay
3122 Make_Identifier (Loc, Name_uM), -- delay mode
3123 Make_Identifier (Loc, Name_uF)))); -- status flag
3126 raise Program_Error;
3132 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
3135 -- Timed_Task_Entry_Call (
3137 -- Task_Entry_Index! (I),
3143 -- where T is the task object, I is the entry index, P are the
3144 -- wrapped parameters, D is the delay amount, M is the delay
3145 -- mode and F is the status flag.
3148 Make_Procedure_Call_Statement (Loc,
3150 New_Reference_To (RTE (RE_Timed_Task_Entry_Call), Loc),
3151 Parameter_Associations =>
3154 Make_Selected_Component (Loc, -- T._task_id
3156 Make_Identifier (Loc, Name_uT),
3158 Make_Identifier (Loc, Name_uTask_Id)),
3160 Make_Unchecked_Type_Conversion (Loc, -- entry index
3162 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
3164 Make_Identifier (Loc, Name_uI)),
3166 Make_Identifier (Loc, Name_uP), -- parameter block
3167 Make_Identifier (Loc, Name_uD), -- delay
3168 Make_Identifier (Loc, Name_uM), -- delay mode
3169 Make_Identifier (Loc, Name_uF)))); -- status flag
3173 -- Ensure that the statements list is non-empty
3175 Append_To (Stmts, Make_Null_Statement (Loc));
3179 Make_Subprogram_Body (Loc,
3181 Make_Disp_Timed_Select_Spec (Typ),
3184 Handled_Statement_Sequence =>
3185 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
3186 end Make_Disp_Timed_Select_Body;
3188 ---------------------------------
3189 -- Make_Disp_Timed_Select_Spec --
3190 ---------------------------------
3192 function Make_Disp_Timed_Select_Spec
3193 (Typ : Entity_Id) return Node_Id
3195 Loc : constant Source_Ptr := Sloc (Typ);
3196 Def_Id : constant Node_Id :=
3197 Make_Defining_Identifier (Loc,
3198 Name_uDisp_Timed_Select);
3199 Params : constant List_Id := New_List;
3202 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3204 -- T : in out Typ; -- Object parameter
3205 -- S : Integer; -- Primitive operation slot
3206 -- P : Address; -- Wrapped parameters
3207 -- D : Duration; -- Delay
3208 -- M : Integer; -- Delay Mode
3209 -- C : out Prim_Op_Kind; -- Call kind
3210 -- F : out Boolean; -- Status flag
3212 Append_List_To (Params, New_List (
3214 Make_Parameter_Specification (Loc,
3215 Defining_Identifier =>
3216 Make_Defining_Identifier (Loc, Name_uT),
3218 New_Reference_To (Typ, Loc),
3220 Out_Present => True),
3222 Make_Parameter_Specification (Loc,
3223 Defining_Identifier =>
3224 Make_Defining_Identifier (Loc, Name_uS),
3226 New_Reference_To (Standard_Integer, Loc)),
3228 Make_Parameter_Specification (Loc,
3229 Defining_Identifier =>
3230 Make_Defining_Identifier (Loc, Name_uP),
3232 New_Reference_To (RTE (RE_Address), Loc)),
3234 Make_Parameter_Specification (Loc,
3235 Defining_Identifier =>
3236 Make_Defining_Identifier (Loc, Name_uD),
3238 New_Reference_To (Standard_Duration, Loc)),
3240 Make_Parameter_Specification (Loc,
3241 Defining_Identifier =>
3242 Make_Defining_Identifier (Loc, Name_uM),
3244 New_Reference_To (Standard_Integer, Loc)),
3246 Make_Parameter_Specification (Loc,
3247 Defining_Identifier =>
3248 Make_Defining_Identifier (Loc, Name_uC),
3250 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
3251 Out_Present => True)));
3254 Make_Parameter_Specification (Loc,
3255 Defining_Identifier =>
3256 Make_Defining_Identifier (Loc, Name_uF),
3258 New_Reference_To (Standard_Boolean, Loc),
3259 Out_Present => True));
3262 Make_Procedure_Specification (Loc,
3263 Defining_Unit_Name => Def_Id,
3264 Parameter_Specifications => Params);
3265 end Make_Disp_Timed_Select_Spec;
3271 -- The frontend supports two models for expanding dispatch tables
3272 -- associated with library-level defined tagged types: statically
3273 -- and non-statically allocated dispatch tables. In the former case
3274 -- the object containing the dispatch table is constant and it is
3275 -- initialized by means of a positional aggregate. In the latter case,
3276 -- the object containing the dispatch table is a variable which is
3277 -- initialized by means of assignments.
3279 -- In case of locally defined tagged types, the object containing the
3280 -- object containing the dispatch table is always a variable (instead
3281 -- of a constant). This is currently required to give support to late
3282 -- overriding of primitives. For example:
3284 -- procedure Example is
3286 -- type T1 is tagged null record;
3287 -- procedure Prim (O : T1);
3290 -- type T2 is new Pkg.T1 with null record;
3291 -- procedure Prim (X : T2) is -- late overriding
3297 function Make_DT (Typ : Entity_Id; N : Node_Id := Empty) return List_Id is
3298 Loc : constant Source_Ptr := Sloc (Typ);
3300 Max_Predef_Prims : constant Int :=
3304 (Parent (RTE (RE_Max_Predef_Prims)))));
3306 DT_Decl : constant Elist_Id := New_Elmt_List;
3307 DT_Aggr : constant Elist_Id := New_Elmt_List;
3308 -- Entities marked with attribute Is_Dispatch_Table_Entity
3310 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id);
3311 -- Verify that all non-tagged types in the profile of a subprogram
3312 -- are frozen at the point the subprogram is frozen. This enforces
3313 -- the rule on RM 13.14 (14) as modified by AI05-019. At the point a
3314 -- subprogram is frozen, enough must be known about it to build the
3315 -- activation record for it, which requires at least that the size of
3316 -- all parameters be known. Controlling arguments are by-reference,
3317 -- and therefore the rule only applies to non-tagged types.
3318 -- Typical violation of the rule involves an object declaration that
3319 -- freezes a tagged type, when one of its primitive operations has a
3320 -- type in its profile whose full view has not been analyzed yet.
3322 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0);
3323 -- Export the dispatch table DT of tagged type Typ. Required to generate
3324 -- forward references and statically allocate the table. For primary
3325 -- dispatch tables Index is 0; for secondary dispatch tables the value
3326 -- of index must match the Suffix_Index value assigned to the table by
3327 -- Make_Tags when generating its unique external name, and it is used to
3328 -- retrieve from the Dispatch_Table_Wrappers list associated with Typ
3329 -- the external name generated by Import_DT.
3331 procedure Make_Secondary_DT
3335 Num_Iface_Prims : Nat;
3336 Iface_DT_Ptr : Entity_Id;
3337 Predef_Prims_Ptr : Entity_Id;
3338 Build_Thunks : Boolean;
3340 -- Ada 2005 (AI-251): Expand the declarations for a Secondary Dispatch
3341 -- Table of Typ associated with Iface. Each abstract interface of Typ
3342 -- has two secondary dispatch tables: one containing pointers to thunks
3343 -- and another containing pointers to the primitives covering the
3344 -- interface primitives. The former secondary table is generated when
3345 -- Build_Thunks is True, and provides common support for dispatching
3346 -- calls through interface types; the latter secondary table is
3347 -- generated when Build_Thunks is False, and provides support for
3348 -- Generic Dispatching Constructors that dispatch calls through
3349 -- interface types. When constructing this latter table the value
3350 -- of Suffix_Index is -1 to indicate that there is no need to export
3351 -- such table when building statically allocated dispatch tables; a
3352 -- positive value of Suffix_Index must match the Suffix_Index value
3353 -- assigned to this secondary dispatch table by Make_Tags when its
3354 -- unique external name was generated.
3356 ------------------------------
3357 -- Check_Premature_Freezing --
3358 ------------------------------
3360 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id) is
3363 and then Is_Private_Type (Typ)
3364 and then No (Full_View (Typ))
3365 and then not Is_Generic_Type (Typ)
3366 and then not Is_Tagged_Type (Typ)
3367 and then not Is_Frozen (Typ)
3369 Error_Msg_Sloc := Sloc (Subp);
3371 ("declaration must appear after completion of type &", N, Typ);
3373 ("\which is an untagged type in the profile of"
3374 & " primitive operation & declared#",
3377 end Check_Premature_Freezing;
3383 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0)
3389 Set_Is_Statically_Allocated (DT);
3390 Set_Is_True_Constant (DT);
3391 Set_Is_Exported (DT);
3394 Elmt := First_Elmt (Dispatch_Table_Wrappers (Typ));
3395 while Count /= Index loop
3400 pragma Assert (Related_Type (Node (Elmt)) = Typ);
3403 (Entity => Node (Elmt),
3404 Has_Suffix => True);
3406 Set_Interface_Name (DT,
3407 Make_String_Literal (Loc,
3408 Strval => String_From_Name_Buffer));
3410 -- Ensure proper Sprint output of this implicit importation
3412 Set_Is_Internal (DT);
3416 -----------------------
3417 -- Make_Secondary_DT --
3418 -----------------------
3420 procedure Make_Secondary_DT
3424 Num_Iface_Prims : Nat;
3425 Iface_DT_Ptr : Entity_Id;
3426 Predef_Prims_Ptr : Entity_Id;
3427 Build_Thunks : Boolean;
3430 Loc : constant Source_Ptr := Sloc (Typ);
3431 Exporting_Table : constant Boolean :=
3432 Building_Static_DT (Typ)
3433 and then Suffix_Index > 0;
3434 Iface_DT : constant Entity_Id :=
3435 Make_Defining_Identifier (Loc,
3436 Chars => New_Internal_Name ('T'));
3437 Name_Predef_Prims : constant Name_Id := New_Internal_Name ('R');
3438 Predef_Prims : constant Entity_Id :=
3439 Make_Defining_Identifier (Loc,
3440 Chars => Name_Predef_Prims);
3441 DT_Constr_List : List_Id;
3442 DT_Aggr_List : List_Id;
3443 Empty_DT : Boolean := False;
3444 Nb_Predef_Prims : Nat := 0;
3448 OSD_Aggr_List : List_Id;
3451 Prim_Elmt : Elmt_Id;
3452 Prim_Ops_Aggr_List : List_Id;
3455 -- Handle cases in which we do not generate statically allocated
3458 if not Building_Static_DT (Typ) then
3459 Set_Ekind (Predef_Prims, E_Variable);
3460 Set_Ekind (Iface_DT, E_Variable);
3462 -- Statically allocated dispatch tables and related entities are
3466 Set_Ekind (Predef_Prims, E_Constant);
3467 Set_Is_Statically_Allocated (Predef_Prims);
3468 Set_Is_True_Constant (Predef_Prims);
3470 Set_Ekind (Iface_DT, E_Constant);
3471 Set_Is_Statically_Allocated (Iface_DT);
3472 Set_Is_True_Constant (Iface_DT);
3475 -- Calculate the number of slots of the dispatch table. If the number
3476 -- of primitives of Typ is 0 we reserve a dummy single entry for its
3477 -- DT because at run-time the pointer to this dummy entry will be
3480 if Num_Iface_Prims = 0 then
3484 Nb_Prim := Num_Iface_Prims;
3489 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
3490 -- (predef-prim-op-thunk-1'address,
3491 -- predef-prim-op-thunk-2'address,
3493 -- predef-prim-op-thunk-n'address);
3494 -- for Predef_Prims'Alignment use Address'Alignment
3496 -- Stage 1: Calculate the number of predefined primitives
3498 if not Building_Static_DT (Typ) then
3499 Nb_Predef_Prims := Max_Predef_Prims;
3501 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3502 while Present (Prim_Elmt) loop
3503 Prim := Node (Prim_Elmt);
3505 if Is_Predefined_Dispatching_Operation (Prim)
3506 and then not Is_Abstract_Subprogram (Prim)
3508 Pos := UI_To_Int (DT_Position (Prim));
3510 if Pos > Nb_Predef_Prims then
3511 Nb_Predef_Prims := Pos;
3515 Next_Elmt (Prim_Elmt);
3519 -- Stage 2: Create the thunks associated with the predefined
3520 -- primitives and save their entity to fill the aggregate.
3523 Prim_Table : array (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
3525 Thunk_Id : Entity_Id;
3526 Thunk_Code : Node_Id;
3529 Prim_Ops_Aggr_List := New_List;
3530 Prim_Table := (others => Empty);
3532 if Building_Static_DT (Typ) then
3533 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3534 while Present (Prim_Elmt) loop
3535 Prim := Node (Prim_Elmt);
3537 if Is_Predefined_Dispatching_Operation (Prim)
3538 and then not Is_Abstract_Subprogram (Prim)
3539 and then not Present (Prim_Table
3540 (UI_To_Int (DT_Position (Prim))))
3542 if not Build_Thunks then
3543 Prim_Table (UI_To_Int (DT_Position (Prim))) :=
3547 while Present (Alias (Prim)) loop
3548 Prim := Alias (Prim);
3551 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
3553 if Present (Thunk_Id) then
3554 Append_To (Result, Thunk_Code);
3555 Prim_Table (UI_To_Int (DT_Position (Prim)))
3561 Next_Elmt (Prim_Elmt);
3565 for J in Prim_Table'Range loop
3566 if Present (Prim_Table (J)) then
3568 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
3569 Make_Attribute_Reference (Loc,
3570 Prefix => New_Reference_To (Prim_Table (J), Loc),
3571 Attribute_Name => Name_Unrestricted_Access));
3573 New_Node := Make_Null (Loc);
3576 Append_To (Prim_Ops_Aggr_List, New_Node);
3580 Make_Aggregate (Loc,
3581 Expressions => Prim_Ops_Aggr_List);
3583 -- Remember aggregates initializing dispatch tables
3585 Append_Elmt (New_Node, DT_Aggr);
3588 Make_Subtype_Declaration (Loc,
3589 Defining_Identifier =>
3590 Make_Defining_Identifier (Loc,
3591 New_Internal_Name ('S')),
3592 Subtype_Indication =>
3593 New_Reference_To (RTE (RE_Address_Array), Loc));
3595 Append_To (Result, Decl);
3598 Make_Object_Declaration (Loc,
3599 Defining_Identifier => Predef_Prims,
3600 Constant_Present => Building_Static_DT (Typ),
3601 Aliased_Present => True,
3602 Object_Definition => New_Reference_To
3603 (Defining_Identifier (Decl), Loc),
3604 Expression => New_Node));
3607 Make_Attribute_Definition_Clause (Loc,
3608 Name => New_Reference_To (Predef_Prims, Loc),
3609 Chars => Name_Alignment,
3611 Make_Attribute_Reference (Loc,
3613 New_Reference_To (RTE (RE_Integer_Address), Loc),
3614 Attribute_Name => Name_Alignment)));
3619 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
3620 -- (OSD_Table => (1 => <value>,
3624 -- Iface_DT : Dispatch_Table (Nb_Prims) :=
3625 -- ([ Signature => <sig-value> ],
3626 -- Tag_Kind => <tag_kind-value>,
3627 -- Predef_Prims => Predef_Prims'Address,
3628 -- Offset_To_Top => 0,
3629 -- OSD => OSD'Address,
3630 -- Prims_Ptr => (prim-op-1'address,
3631 -- prim-op-2'address,
3633 -- prim-op-n'address));
3634 -- for Iface_DT'Alignment use Address'Alignment;
3636 -- Stage 3: Initialize the discriminant and the record components
3638 DT_Constr_List := New_List;
3639 DT_Aggr_List := New_List;
3641 -- Nb_Prim. If the tagged type has no primitives we add a dummy
3642 -- slot whose address will be the tag of this type.
3645 New_Node := Make_Integer_Literal (Loc, 1);
3647 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
3650 Append_To (DT_Constr_List, New_Node);
3651 Append_To (DT_Aggr_List, New_Copy (New_Node));
3655 if RTE_Record_Component_Available (RE_Signature) then
3656 Append_To (DT_Aggr_List,
3657 New_Reference_To (RTE (RE_Secondary_DT), Loc));
3662 if RTE_Record_Component_Available (RE_Tag_Kind) then
3663 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
3668 Append_To (DT_Aggr_List,
3669 Make_Attribute_Reference (Loc,
3670 Prefix => New_Reference_To (Predef_Prims, Loc),
3671 Attribute_Name => Name_Address));
3673 -- Note: The correct value of Offset_To_Top will be set by the init
3676 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
3678 -- Generate the Object Specific Data table required to dispatch calls
3679 -- through synchronized interfaces.
3682 or else Is_Abstract_Type (Typ)
3683 or else Is_Controlled (Typ)
3684 or else Restriction_Active (No_Dispatching_Calls)
3685 or else not Is_Limited_Type (Typ)
3686 or else not Has_Interfaces (Typ)
3687 or else not Build_Thunks
3688 or else not RTE_Record_Component_Available (RE_OSD_Table)
3690 -- No OSD table required
3692 Append_To (DT_Aggr_List,
3693 New_Reference_To (RTE (RE_Null_Address), Loc));
3696 OSD_Aggr_List := New_List;
3699 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
3701 Prim_Alias : Entity_Id;
3702 Prim_Elmt : Elmt_Id;
3708 Prim_Table := (others => Empty);
3709 Prim_Alias := Empty;
3711 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3712 while Present (Prim_Elmt) loop
3713 Prim := Node (Prim_Elmt);
3715 if Present (Interface_Alias (Prim))
3716 and then Find_Dispatching_Type
3717 (Interface_Alias (Prim)) = Iface
3719 Prim_Alias := Interface_Alias (Prim);
3722 while Present (Alias (E)) loop
3726 Pos := UI_To_Int (DT_Position (Prim_Alias));
3728 if Present (Prim_Table (Pos)) then
3729 pragma Assert (Prim_Table (Pos) = E);
3733 Prim_Table (Pos) := E;
3735 Append_To (OSD_Aggr_List,
3736 Make_Component_Association (Loc,
3737 Choices => New_List (
3738 Make_Integer_Literal (Loc,
3739 DT_Position (Prim_Alias))),
3741 Make_Integer_Literal (Loc,
3742 DT_Position (Alias (Prim)))));
3748 Next_Elmt (Prim_Elmt);
3750 pragma Assert (Count = Nb_Prim);
3753 OSD := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
3756 Make_Object_Declaration (Loc,
3757 Defining_Identifier => OSD,
3758 Object_Definition =>
3759 Make_Subtype_Indication (Loc,
3761 New_Reference_To (RTE (RE_Object_Specific_Data), Loc),
3763 Make_Index_Or_Discriminant_Constraint (Loc,
3764 Constraints => New_List (
3765 Make_Integer_Literal (Loc, Nb_Prim)))),
3766 Expression => Make_Aggregate (Loc,
3767 Component_Associations => New_List (
3768 Make_Component_Association (Loc,
3769 Choices => New_List (
3771 (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
3773 Make_Integer_Literal (Loc, Nb_Prim)),
3775 Make_Component_Association (Loc,
3776 Choices => New_List (
3778 (RTE_Record_Component (RE_OSD_Table), Loc)),
3779 Expression => Make_Aggregate (Loc,
3780 Component_Associations => OSD_Aggr_List))))));
3783 Make_Attribute_Definition_Clause (Loc,
3784 Name => New_Reference_To (OSD, Loc),
3785 Chars => Name_Alignment,
3787 Make_Attribute_Reference (Loc,
3789 New_Reference_To (RTE (RE_Integer_Address), Loc),
3790 Attribute_Name => Name_Alignment)));
3792 -- In secondary dispatch tables the Typeinfo component contains
3793 -- the address of the Object Specific Data (see a-tags.ads)
3795 Append_To (DT_Aggr_List,
3796 Make_Attribute_Reference (Loc,
3797 Prefix => New_Reference_To (OSD, Loc),
3798 Attribute_Name => Name_Address));
3801 -- Initialize the table of primitive operations
3803 Prim_Ops_Aggr_List := New_List;
3806 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
3808 elsif Is_Abstract_Type (Typ)
3809 or else not Building_Static_DT (Typ)
3811 for J in 1 .. Nb_Prim loop
3812 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
3817 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
3819 Thunk_Code : Node_Id;
3820 Thunk_Id : Entity_Id;
3823 Prim_Table := (others => Empty);
3825 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3826 while Present (Prim_Elmt) loop
3827 Prim := Node (Prim_Elmt);
3829 if not Is_Predefined_Dispatching_Operation (Prim)
3830 and then Present (Interface_Alias (Prim))
3831 and then not Is_Abstract_Subprogram (Alias (Prim))
3832 and then not Is_Imported (Alias (Prim))
3833 and then Find_Dispatching_Type
3834 (Interface_Alias (Prim)) = Iface
3836 -- Generate the code of the thunk only if the abstract
3837 -- interface type is not an immediate ancestor of
3838 -- Tagged_Type; otherwise the DT associated with the
3839 -- interface is the primary DT.
3841 and then not Is_Ancestor (Iface, Typ)
3843 if not Build_Thunks then
3845 UI_To_Int (DT_Position (Interface_Alias (Prim)));
3846 Prim_Table (Pos) := Alias (Prim);
3848 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
3850 if Present (Thunk_Id) then
3852 UI_To_Int (DT_Position (Interface_Alias (Prim)));
3854 Prim_Table (Pos) := Thunk_Id;
3855 Append_To (Result, Thunk_Code);
3860 Next_Elmt (Prim_Elmt);
3863 for J in Prim_Table'Range loop
3864 if Present (Prim_Table (J)) then
3866 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
3867 Make_Attribute_Reference (Loc,
3868 Prefix => New_Reference_To (Prim_Table (J), Loc),
3869 Attribute_Name => Name_Unrestricted_Access));
3871 New_Node := Make_Null (Loc);
3874 Append_To (Prim_Ops_Aggr_List, New_Node);
3880 Make_Aggregate (Loc,
3881 Expressions => Prim_Ops_Aggr_List);
3883 Append_To (DT_Aggr_List, New_Node);
3885 -- Remember aggregates initializing dispatch tables
3887 Append_Elmt (New_Node, DT_Aggr);
3889 -- Note: Secondary dispatch tables cannot be declared constant
3890 -- because the component Offset_To_Top is currently initialized
3891 -- by the IP routine.
3894 Make_Object_Declaration (Loc,
3895 Defining_Identifier => Iface_DT,
3896 Aliased_Present => True,
3897 Constant_Present => False,
3899 Object_Definition =>
3900 Make_Subtype_Indication (Loc,
3901 Subtype_Mark => New_Reference_To
3902 (RTE (RE_Dispatch_Table_Wrapper), Loc),
3903 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
3904 Constraints => DT_Constr_List)),
3907 Make_Aggregate (Loc,
3908 Expressions => DT_Aggr_List)));
3911 Make_Attribute_Definition_Clause (Loc,
3912 Name => New_Reference_To (Iface_DT, Loc),
3913 Chars => Name_Alignment,
3916 Make_Attribute_Reference (Loc,
3918 New_Reference_To (RTE (RE_Integer_Address), Loc),
3919 Attribute_Name => Name_Alignment)));
3921 if Exporting_Table then
3922 Export_DT (Typ, Iface_DT, Suffix_Index);
3924 -- Generate code to create the pointer to the dispatch table
3926 -- Iface_DT_Ptr : Tag := Tag!(DT.Prims_Ptr'Address);
3928 -- Note: This declaration is not added here if the table is exported
3929 -- because in such case Make_Tags has already added this declaration.
3933 Make_Object_Declaration (Loc,
3934 Defining_Identifier => Iface_DT_Ptr,
3935 Constant_Present => True,
3937 Object_Definition =>
3938 New_Reference_To (RTE (RE_Interface_Tag), Loc),
3941 Unchecked_Convert_To (RTE (RE_Interface_Tag),
3942 Make_Attribute_Reference (Loc,
3944 Make_Selected_Component (Loc,
3945 Prefix => New_Reference_To (Iface_DT, Loc),
3948 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
3949 Attribute_Name => Name_Address))));
3953 Make_Object_Declaration (Loc,
3954 Defining_Identifier => Predef_Prims_Ptr,
3955 Constant_Present => True,
3957 Object_Definition =>
3958 New_Reference_To (RTE (RE_Address), Loc),
3961 Make_Attribute_Reference (Loc,
3963 Make_Selected_Component (Loc,
3964 Prefix => New_Reference_To (Iface_DT, Loc),
3967 (RTE_Record_Component (RE_Predef_Prims), Loc)),
3968 Attribute_Name => Name_Address)));
3970 -- Remember entities containing dispatch tables
3972 Append_Elmt (Predef_Prims, DT_Decl);
3973 Append_Elmt (Iface_DT, DT_Decl);
3974 end Make_Secondary_DT;
3978 Elab_Code : constant List_Id := New_List;
3979 Result : constant List_Id := New_List;
3980 Tname : constant Name_Id := Chars (Typ);
3982 AI_Tag_Elmt : Elmt_Id;
3983 AI_Tag_Comp : Elmt_Id;
3984 DT_Aggr_List : List_Id;
3985 DT_Constr_List : List_Id;
3989 Iface_Table_Node : Node_Id;
3990 Name_ITable : Name_Id;
3991 Nb_Predef_Prims : Nat := 0;
3994 Num_Ifaces : Nat := 0;
3995 Parent_Typ : Entity_Id;
3997 Prim_Elmt : Elmt_Id;
3998 Prim_Ops_Aggr_List : List_Id;
4000 Typ_Comps : Elist_Id;
4001 Typ_Ifaces : Elist_Id;
4002 TSD_Aggr_List : List_Id;
4003 TSD_Tags_List : List_Id;
4005 -- The following name entries are used by Make_DT to generate a number
4006 -- of entities related to a tagged type. These entities may be generated
4007 -- in a scope other than that of the tagged type declaration, and if
4008 -- the entities for two tagged types with the same name happen to be
4009 -- generated in the same scope, we have to take care to use different
4010 -- names. This is achieved by means of a unique serial number appended
4011 -- to each generated entity name.
4013 Name_DT : constant Name_Id :=
4014 New_External_Name (Tname, 'T', Suffix_Index => -1);
4015 Name_Exname : constant Name_Id :=
4016 New_External_Name (Tname, 'E', Suffix_Index => -1);
4017 Name_HT_Link : constant Name_Id :=
4018 New_External_Name (Tname, 'H', Suffix_Index => -1);
4019 Name_Predef_Prims : constant Name_Id :=
4020 New_External_Name (Tname, 'R', Suffix_Index => -1);
4021 Name_SSD : constant Name_Id :=
4022 New_External_Name (Tname, 'S', Suffix_Index => -1);
4023 Name_TSD : constant Name_Id :=
4024 New_External_Name (Tname, 'B', Suffix_Index => -1);
4026 -- Entities built with above names
4028 DT : constant Entity_Id :=
4029 Make_Defining_Identifier (Loc, Name_DT);
4030 Exname : constant Entity_Id :=
4031 Make_Defining_Identifier (Loc, Name_Exname);
4032 HT_Link : constant Entity_Id :=
4033 Make_Defining_Identifier (Loc, Name_HT_Link);
4034 Predef_Prims : constant Entity_Id :=
4035 Make_Defining_Identifier (Loc, Name_Predef_Prims);
4036 SSD : constant Entity_Id :=
4037 Make_Defining_Identifier (Loc, Name_SSD);
4038 TSD : constant Entity_Id :=
4039 Make_Defining_Identifier (Loc, Name_TSD);
4041 -- Start of processing for Make_DT
4044 pragma Assert (Is_Frozen (Typ));
4046 -- Handle cases in which there is no need to build the dispatch table
4048 if Has_Dispatch_Table (Typ)
4049 or else No (Access_Disp_Table (Typ))
4050 or else Is_CPP_Class (Typ)
4054 elsif No_Run_Time_Mode then
4055 Error_Msg_CRT ("tagged types", Typ);
4058 elsif not RTE_Available (RE_Tag) then
4060 Make_Object_Declaration (Loc,
4061 Defining_Identifier => Node (First_Elmt
4062 (Access_Disp_Table (Typ))),
4063 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4064 Constant_Present => True,
4066 Unchecked_Convert_To (RTE (RE_Tag),
4067 New_Reference_To (RTE (RE_Null_Address), Loc))));
4069 Analyze_List (Result, Suppress => All_Checks);
4070 Error_Msg_CRT ("tagged types", Typ);
4074 -- Ensure that the value of Max_Predef_Prims defined in a-tags is
4075 -- correct. Valid values are 10 under configurable runtime or 16
4076 -- with full runtime.
4078 if RTE_Available (RE_Interface_Data) then
4079 if Max_Predef_Prims /= 16 then
4080 Error_Msg_N ("run-time library configuration error", Typ);
4084 if Max_Predef_Prims /= 10 then
4085 Error_Msg_N ("run-time library configuration error", Typ);
4086 Error_Msg_CRT ("tagged types", Typ);
4091 -- Initialize Parent_Typ handling private types
4093 Parent_Typ := Etype (Typ);
4095 if Present (Full_View (Parent_Typ)) then
4096 Parent_Typ := Full_View (Parent_Typ);
4099 -- Ensure that all the primitives are frozen. This is only required when
4100 -- building static dispatch tables --- the primitives must be frozen to
4101 -- be referenced (otherwise we have problems with the backend). It is
4102 -- not a requirement with nonstatic dispatch tables because in this case
4103 -- we generate now an empty dispatch table; the extra code required to
4104 -- register the primitives in the slots will be generated later --- when
4105 -- each primitive is frozen (see Freeze_Subprogram).
4107 if Building_Static_DT (Typ)
4108 and then not Is_CPP_Class (Typ)
4111 Save : constant Boolean := Freezing_Library_Level_Tagged_Type;
4113 Prim_Elmt : Elmt_Id;
4117 Freezing_Library_Level_Tagged_Type := True;
4119 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4120 while Present (Prim_Elmt) loop
4121 Prim := Node (Prim_Elmt);
4122 Frnodes := Freeze_Entity (Prim, Loc);
4128 F := First_Formal (Prim);
4129 while Present (F) loop
4130 Check_Premature_Freezing (Prim, Etype (F));
4134 Check_Premature_Freezing (Prim, Etype (Prim));
4137 if Present (Frnodes) then
4138 Append_List_To (Result, Frnodes);
4141 Next_Elmt (Prim_Elmt);
4144 Freezing_Library_Level_Tagged_Type := Save;
4148 -- Ada 2005 (AI-251): Build the secondary dispatch tables
4150 if Has_Interfaces (Typ) then
4151 Collect_Interface_Components (Typ, Typ_Comps);
4153 -- Each secondary dispatch table is assigned an unique positive
4154 -- suffix index; such value also corresponds with the location of
4155 -- its entity in the Dispatch_Table_Wrappers list (see Make_Tags).
4157 -- Note: This value must be kept sync with the Suffix_Index values
4158 -- generated by Make_Tags
4162 Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
4164 AI_Tag_Comp := First_Elmt (Typ_Comps);
4165 while Present (AI_Tag_Comp) loop
4167 -- Build the secondary table containing pointers to thunks
4171 Iface => Base_Type (Related_Type (Node (AI_Tag_Comp))),
4172 Suffix_Index => Suffix_Index,
4173 Num_Iface_Prims => UI_To_Int
4174 (DT_Entry_Count (Node (AI_Tag_Comp))),
4175 Iface_DT_Ptr => Node (AI_Tag_Elmt),
4176 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
4177 Build_Thunks => True,
4180 -- Skip secondary dispatch table and secondary dispatch table of
4181 -- predefined primitives
4183 Next_Elmt (AI_Tag_Elmt);
4184 Next_Elmt (AI_Tag_Elmt);
4186 -- Build the secondary table containing pointers to primitives
4187 -- (used to give support to Generic Dispatching Constructors).
4191 Iface => Base_Type (Related_Type (Node (AI_Tag_Comp))),
4193 Num_Iface_Prims => UI_To_Int
4194 (DT_Entry_Count (Node (AI_Tag_Comp))),
4195 Iface_DT_Ptr => Node (AI_Tag_Elmt),
4196 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
4197 Build_Thunks => False,
4200 -- Skip secondary dispatch table and secondary dispatch table of
4201 -- predefined primitives
4203 Next_Elmt (AI_Tag_Elmt);
4204 Next_Elmt (AI_Tag_Elmt);
4206 Suffix_Index := Suffix_Index + 1;
4207 Next_Elmt (AI_Tag_Comp);
4211 -- Get the _tag entity and the number of primitives of its dispatch
4214 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
4215 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
4217 Set_Is_Statically_Allocated (DT, Is_Library_Level_Tagged_Type (Typ));
4218 Set_Is_Statically_Allocated (SSD, Is_Library_Level_Tagged_Type (Typ));
4219 Set_Is_Statically_Allocated (TSD, Is_Library_Level_Tagged_Type (Typ));
4220 Set_Is_Statically_Allocated (Predef_Prims,
4221 Is_Library_Level_Tagged_Type (Typ));
4223 -- In case of locally defined tagged type we declare the object
4224 -- containing the dispatch table by means of a variable. Its
4225 -- initialization is done later by means of an assignment. This is
4226 -- required to generate its External_Tag.
4228 if not Building_Static_DT (Typ) then
4231 -- DT : No_Dispatch_Table_Wrapper;
4232 -- for DT'Alignment use Address'Alignment;
4233 -- DT_Ptr : Tag := !Tag (DT.NDT_Prims_Ptr'Address);
4235 if not Has_DT (Typ) then
4237 Make_Object_Declaration (Loc,
4238 Defining_Identifier => DT,
4239 Aliased_Present => True,
4240 Constant_Present => False,
4241 Object_Definition =>
4243 (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
4245 if Generate_SCIL then
4246 Insert_Before (Last (Result),
4248 (Nkind => Dispatch_Table_Object_Init,
4249 Related_Node => Last (Result),
4254 Make_Attribute_Definition_Clause (Loc,
4255 Name => New_Reference_To (DT, Loc),
4256 Chars => Name_Alignment,
4258 Make_Attribute_Reference (Loc,
4260 New_Reference_To (RTE (RE_Integer_Address), Loc),
4261 Attribute_Name => Name_Alignment)));
4264 Make_Object_Declaration (Loc,
4265 Defining_Identifier => DT_Ptr,
4266 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4267 Constant_Present => True,
4269 Unchecked_Convert_To (RTE (RE_Tag),
4270 Make_Attribute_Reference (Loc,
4272 Make_Selected_Component (Loc,
4273 Prefix => New_Reference_To (DT, Loc),
4276 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
4277 Attribute_Name => Name_Address))));
4279 if Generate_SCIL then
4280 Insert_Before (Last (Result),
4282 (Nkind => Dispatch_Table_Tag_Init,
4283 Related_Node => Last (Result),
4288 -- DT : Dispatch_Table_Wrapper (Nb_Prim);
4289 -- for DT'Alignment use Address'Alignment;
4290 -- DT_Ptr : Tag := !Tag (DT.Prims_Ptr'Address);
4293 -- If the tagged type has no primitives we add a dummy slot
4294 -- whose address will be the tag of this type.
4298 New_List (Make_Integer_Literal (Loc, 1));
4301 New_List (Make_Integer_Literal (Loc, Nb_Prim));
4305 Make_Object_Declaration (Loc,
4306 Defining_Identifier => DT,
4307 Aliased_Present => True,
4308 Constant_Present => False,
4309 Object_Definition =>
4310 Make_Subtype_Indication (Loc,
4312 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
4313 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4314 Constraints => DT_Constr_List))));
4316 if Generate_SCIL then
4317 Insert_Before (Last (Result),
4319 (Nkind => Dispatch_Table_Object_Init,
4320 Related_Node => Last (Result),
4325 Make_Attribute_Definition_Clause (Loc,
4326 Name => New_Reference_To (DT, Loc),
4327 Chars => Name_Alignment,
4329 Make_Attribute_Reference (Loc,
4331 New_Reference_To (RTE (RE_Integer_Address), Loc),
4332 Attribute_Name => Name_Alignment)));
4335 Make_Object_Declaration (Loc,
4336 Defining_Identifier => DT_Ptr,
4337 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4338 Constant_Present => True,
4340 Unchecked_Convert_To (RTE (RE_Tag),
4341 Make_Attribute_Reference (Loc,
4343 Make_Selected_Component (Loc,
4344 Prefix => New_Reference_To (DT, Loc),
4347 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
4348 Attribute_Name => Name_Address))));
4350 if Generate_SCIL then
4351 Insert_Before (Last (Result),
4353 (Nkind => Dispatch_Table_Tag_Init,
4354 Related_Node => Last (Result),
4359 Make_Object_Declaration (Loc,
4360 Defining_Identifier =>
4361 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Typ)))),
4362 Constant_Present => True,
4363 Object_Definition => New_Reference_To
4364 (RTE (RE_Address), Loc),
4366 Make_Attribute_Reference (Loc,
4368 Make_Selected_Component (Loc,
4369 Prefix => New_Reference_To (DT, Loc),
4372 (RTE_Record_Component (RE_Predef_Prims), Loc)),
4373 Attribute_Name => Name_Address)));
4377 -- Generate: Exname : constant String := full_qualified_name (typ);
4378 -- The type itself may be an anonymous parent type, so use the first
4379 -- subtype to have a user-recognizable name.
4382 Make_Object_Declaration (Loc,
4383 Defining_Identifier => Exname,
4384 Constant_Present => True,
4385 Object_Definition => New_Reference_To (Standard_String, Loc),
4387 Make_String_Literal (Loc,
4388 Full_Qualified_Name (First_Subtype (Typ)))));
4390 Set_Is_Statically_Allocated (Exname);
4391 Set_Is_True_Constant (Exname);
4393 -- Declare the object used by Ada.Tags.Register_Tag
4395 if RTE_Available (RE_Register_Tag) then
4397 Make_Object_Declaration (Loc,
4398 Defining_Identifier => HT_Link,
4399 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc)));
4402 -- Generate code to create the storage for the type specific data object
4403 -- with enough space to store the tags of the ancestors plus the tags
4404 -- of all the implemented interfaces (as described in a-tags.adb).
4406 -- TSD : Type_Specific_Data (I_Depth) :=
4407 -- (Idepth => I_Depth,
4408 -- Access_Level => Type_Access_Level (Typ),
4409 -- Expanded_Name => Cstring_Ptr!(Exname'Address))
4410 -- External_Tag => Cstring_Ptr!(Exname'Address))
4411 -- HT_Link => HT_Link'Address,
4412 -- Transportable => <<boolean-value>>,
4413 -- RC_Offset => <<integer-value>>,
4414 -- [ Size_Func => Size_Prim'Access ]
4415 -- [ Interfaces_Table => <<access-value>> ]
4416 -- [ SSD => SSD_Table'Address ]
4417 -- Tags_Table => (0 => null,
4420 -- for TSD'Alignment use Address'Alignment
4422 TSD_Aggr_List := New_List;
4424 -- Idepth: Count ancestors to compute the inheritance depth. For private
4425 -- extensions, always go to the full view in order to compute the real
4426 -- inheritance depth.
4429 Current_Typ : Entity_Id;
4430 Parent_Typ : Entity_Id;
4436 Parent_Typ := Etype (Current_Typ);
4438 if Is_Private_Type (Parent_Typ) then
4439 Parent_Typ := Full_View (Base_Type (Parent_Typ));
4442 exit when Parent_Typ = Current_Typ;
4444 I_Depth := I_Depth + 1;
4445 Current_Typ := Parent_Typ;
4449 Append_To (TSD_Aggr_List,
4450 Make_Integer_Literal (Loc, I_Depth));
4454 Append_To (TSD_Aggr_List,
4455 Make_Integer_Literal (Loc, Type_Access_Level (Typ)));
4459 Append_To (TSD_Aggr_List,
4460 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4461 Make_Attribute_Reference (Loc,
4462 Prefix => New_Reference_To (Exname, Loc),
4463 Attribute_Name => Name_Address)));
4465 -- External_Tag of a local tagged type
4467 -- <typ>A : constant String :=
4468 -- "Internal tag at 16#tag-addr#: <full-name-of-typ>";
4470 -- The reason we generate this strange name is that we do not want to
4471 -- enter local tagged types in the global hash table used to compute
4472 -- the Internal_Tag attribute for two reasons:
4474 -- 1. It is hard to avoid a tasking race condition for entering the
4475 -- entry into the hash table.
4477 -- 2. It would cause a storage leak, unless we rig up considerable
4478 -- mechanism to remove the entry from the hash table on exit.
4480 -- So what we do is to generate the above external tag name, where the
4481 -- hex address is the address of the local dispatch table (i.e. exactly
4482 -- the value we want if Internal_Tag is computed from this string).
4484 -- Of course this value will only be valid if the tagged type is still
4485 -- in scope, but it clearly must be erroneous to compute the internal
4486 -- tag of a tagged type that is out of scope!
4488 -- We don't do this processing if an explicit external tag has been
4489 -- specified. That's an odd case for which we have already issued a
4490 -- warning, where we will not be able to compute the internal tag.
4492 if not Is_Library_Level_Entity (Typ)
4493 and then not Has_External_Tag_Rep_Clause (Typ)
4496 Exname : constant Entity_Id :=
4497 Make_Defining_Identifier (Loc,
4498 New_External_Name (Tname, 'A'));
4500 Full_Name : constant String_Id :=
4501 Full_Qualified_Name (First_Subtype (Typ));
4502 Str1_Id : String_Id;
4503 Str2_Id : String_Id;
4507 -- Str1 = "Internal tag at 16#";
4510 Store_String_Chars ("Internal tag at 16#");
4511 Str1_Id := End_String;
4514 -- Str2 = "#: <type-full-name>";
4517 Store_String_Chars ("#: ");
4518 Store_String_Chars (Full_Name);
4519 Str2_Id := End_String;
4522 -- Exname : constant String :=
4523 -- Str1 & Address_Image (Tag) & Str2;
4525 if RTE_Available (RE_Address_Image) then
4527 Make_Object_Declaration (Loc,
4528 Defining_Identifier => Exname,
4529 Constant_Present => True,
4530 Object_Definition => New_Reference_To
4531 (Standard_String, Loc),
4533 Make_Op_Concat (Loc,
4535 Make_String_Literal (Loc, Str1_Id),
4537 Make_Op_Concat (Loc,
4539 Make_Function_Call (Loc,
4542 (RTE (RE_Address_Image), Loc),
4543 Parameter_Associations => New_List (
4544 Unchecked_Convert_To (RTE (RE_Address),
4545 New_Reference_To (DT_Ptr, Loc)))),
4547 Make_String_Literal (Loc, Str2_Id)))));
4551 Make_Object_Declaration (Loc,
4552 Defining_Identifier => Exname,
4553 Constant_Present => True,
4554 Object_Definition => New_Reference_To
4555 (Standard_String, Loc),
4557 Make_Op_Concat (Loc,
4559 Make_String_Literal (Loc, Str1_Id),
4561 Make_String_Literal (Loc, Str2_Id))));
4565 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4566 Make_Attribute_Reference (Loc,
4567 Prefix => New_Reference_To (Exname, Loc),
4568 Attribute_Name => Name_Address));
4571 -- External tag of a library-level tagged type: Check for a definition
4572 -- of External_Tag. The clause is considered only if it applies to this
4573 -- specific tagged type, as opposed to one of its ancestors.
4574 -- If the type is an unconstrained type extension, we are building the
4575 -- dispatch table of its anonymous base type, so the external tag, if
4576 -- any was specified, must be retrieved from the first subtype. Go to
4577 -- the full view in case the clause is in the private part.
4581 Def : constant Node_Id := Get_Attribute_Definition_Clause
4582 (Underlying_Type (First_Subtype (Typ)),
4583 Attribute_External_Tag);
4585 Old_Val : String_Id;
4586 New_Val : String_Id;
4590 if not Present (Def)
4591 or else Entity (Name (Def)) /= First_Subtype (Typ)
4594 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4595 Make_Attribute_Reference (Loc,
4596 Prefix => New_Reference_To (Exname, Loc),
4597 Attribute_Name => Name_Address));
4599 Old_Val := Strval (Expr_Value_S (Expression (Def)));
4601 -- For the rep clause "for <typ>'external_tag use y" generate:
4603 -- <typ>A : constant string := y;
4605 -- <typ>A'Address is used to set the External_Tag component
4608 -- Create a new nul terminated string if it is not already
4610 if String_Length (Old_Val) > 0
4612 Get_String_Char (Old_Val, String_Length (Old_Val)) = 0
4616 Start_String (Old_Val);
4617 Store_String_Char (Get_Char_Code (ASCII.NUL));
4618 New_Val := End_String;
4621 E := Make_Defining_Identifier (Loc,
4622 New_External_Name (Chars (Typ), 'A'));
4625 Make_Object_Declaration (Loc,
4626 Defining_Identifier => E,
4627 Constant_Present => True,
4628 Object_Definition =>
4629 New_Reference_To (Standard_String, Loc),
4631 Make_String_Literal (Loc, New_Val)));
4634 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4635 Make_Attribute_Reference (Loc,
4636 Prefix => New_Reference_To (E, Loc),
4637 Attribute_Name => Name_Address));
4642 Append_To (TSD_Aggr_List, New_Node);
4646 if RTE_Available (RE_Register_Tag) then
4647 Append_To (TSD_Aggr_List,
4648 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
4649 Make_Attribute_Reference (Loc,
4650 Prefix => New_Reference_To (HT_Link, Loc),
4651 Attribute_Name => Name_Address)));
4653 Append_To (TSD_Aggr_List,
4654 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
4655 New_Reference_To (RTE (RE_Null_Address), Loc)));
4658 -- Transportable: Set for types that can be used in remote calls
4659 -- with respect to E.4(18) legality rules.
4662 Transportable : Entity_Id;
4668 or else Is_Shared_Passive (Typ)
4670 ((Is_Remote_Types (Typ)
4671 or else Is_Remote_Call_Interface (Typ))
4672 and then Original_View_In_Visible_Part (Typ))
4673 or else not Comes_From_Source (Typ));
4675 Append_To (TSD_Aggr_List,
4676 New_Occurrence_Of (Transportable, Loc));
4679 -- RC_Offset: These are the valid values and their meaning:
4681 -- >0: For simple types with controlled components is
4682 -- type._record_controller'position
4684 -- 0: For types with no controlled components
4686 -- -1: For complex types with controlled components where the position
4687 -- of the record controller is not statically computable but there
4688 -- are controlled components at this level. The _Controller field
4689 -- is available right after the _parent.
4691 -- -2: There are no controlled components at this level. We need to
4692 -- get the position from the parent.
4695 RC_Offset_Node : Node_Id;
4698 if not Has_Controlled_Component (Typ) then
4699 RC_Offset_Node := Make_Integer_Literal (Loc, 0);
4701 elsif Etype (Typ) /= Typ
4702 and then Has_Discriminants (Parent_Typ)
4704 if Has_New_Controlled_Component (Typ) then
4705 RC_Offset_Node := Make_Integer_Literal (Loc, -1);
4707 RC_Offset_Node := Make_Integer_Literal (Loc, -2);
4711 Make_Attribute_Reference (Loc,
4713 Make_Selected_Component (Loc,
4714 Prefix => New_Reference_To (Typ, Loc),
4716 New_Reference_To (Controller_Component (Typ), Loc)),
4717 Attribute_Name => Name_Position);
4719 -- This is not proper Ada code to use the attribute 'Position
4720 -- on something else than an object but this is supported by
4721 -- the back end (see comment on the Bit_Component attribute in
4722 -- sem_attr). So we avoid semantic checking here.
4724 -- Is this documented in sinfo.ads??? it should be!
4726 Set_Analyzed (RC_Offset_Node);
4727 Set_Etype (Prefix (RC_Offset_Node), RTE (RE_Record_Controller));
4728 Set_Etype (Prefix (Prefix (RC_Offset_Node)), Typ);
4729 Set_Etype (Selector_Name (Prefix (RC_Offset_Node)),
4730 RTE (RE_Record_Controller));
4731 Set_Etype (RC_Offset_Node, RTE (RE_Storage_Offset));
4734 Append_To (TSD_Aggr_List, RC_Offset_Node);
4739 if RTE_Record_Component_Available (RE_Size_Func) then
4740 if not Building_Static_DT (Typ)
4741 or else Is_Interface (Typ)
4743 Append_To (TSD_Aggr_List,
4744 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4745 New_Reference_To (RTE (RE_Null_Address), Loc)));
4749 Prim_Elmt : Elmt_Id;
4753 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4754 while Present (Prim_Elmt) loop
4755 Prim := Node (Prim_Elmt);
4757 if Chars (Prim) = Name_uSize then
4758 while Present (Alias (Prim)) loop
4759 Prim := Alias (Prim);
4762 if Is_Abstract_Subprogram (Prim) then
4763 Append_To (TSD_Aggr_List,
4764 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4765 New_Reference_To (RTE (RE_Null_Address), Loc)));
4767 Append_To (TSD_Aggr_List,
4768 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4769 Make_Attribute_Reference (Loc,
4770 Prefix => New_Reference_To (Prim, Loc),
4771 Attribute_Name => Name_Unrestricted_Access)));
4777 Next_Elmt (Prim_Elmt);
4783 -- Interfaces_Table (required for AI-405)
4785 if RTE_Record_Component_Available (RE_Interfaces_Table) then
4787 -- Count the number of interface types implemented by Typ
4789 Collect_Interfaces (Typ, Typ_Ifaces);
4791 AI := First_Elmt (Typ_Ifaces);
4792 while Present (AI) loop
4793 Num_Ifaces := Num_Ifaces + 1;
4797 if Num_Ifaces = 0 then
4798 Iface_Table_Node := Make_Null (Loc);
4800 -- Generate the Interface_Table object
4804 TSD_Ifaces_List : constant List_Id := New_List;
4806 Sec_DT_Tag : Node_Id;
4809 AI := First_Elmt (Typ_Ifaces);
4810 while Present (AI) loop
4811 if Is_Ancestor (Node (AI), Typ) then
4813 New_Reference_To (DT_Ptr, Loc);
4817 (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
4818 pragma Assert (Has_Thunks (Node (Elmt)));
4820 while Ekind (Node (Elmt)) = E_Constant
4822 Is_Ancestor (Node (AI), Related_Type (Node (Elmt)))
4824 pragma Assert (Has_Thunks (Node (Elmt)));
4826 pragma Assert (Has_Thunks (Node (Elmt)));
4828 pragma Assert (not Has_Thunks (Node (Elmt)));
4830 pragma Assert (not Has_Thunks (Node (Elmt)));
4834 pragma Assert (Ekind (Node (Elmt)) = E_Constant
4836 Has_Thunks (Node (Next_Elmt (Next_Elmt (Elmt)))));
4838 New_Reference_To (Node (Next_Elmt (Next_Elmt (Elmt))),
4842 Append_To (TSD_Ifaces_List,
4843 Make_Aggregate (Loc,
4844 Expressions => New_List (
4848 Unchecked_Convert_To (RTE (RE_Tag),
4850 (Node (First_Elmt (Access_Disp_Table (Node (AI)))),
4853 -- Static_Offset_To_Top
4855 New_Reference_To (Standard_True, Loc),
4857 -- Offset_To_Top_Value
4859 Make_Integer_Literal (Loc, 0),
4861 -- Offset_To_Top_Func
4867 Unchecked_Convert_To (RTE (RE_Tag), Sec_DT_Tag)
4874 Name_ITable := New_External_Name (Tname, 'I');
4875 ITable := Make_Defining_Identifier (Loc, Name_ITable);
4876 Set_Is_Statically_Allocated (ITable,
4877 Is_Library_Level_Tagged_Type (Typ));
4879 -- The table of interfaces is not constant; its slots are
4880 -- filled at run-time by the IP routine using attribute
4881 -- 'Position to know the location of the tag components
4882 -- (and this attribute cannot be safely used before the
4883 -- object is initialized).
4886 Make_Object_Declaration (Loc,
4887 Defining_Identifier => ITable,
4888 Aliased_Present => True,
4889 Constant_Present => False,
4890 Object_Definition =>
4891 Make_Subtype_Indication (Loc,
4893 New_Reference_To (RTE (RE_Interface_Data), Loc),
4894 Constraint => Make_Index_Or_Discriminant_Constraint
4896 Constraints => New_List (
4897 Make_Integer_Literal (Loc, Num_Ifaces)))),
4899 Expression => Make_Aggregate (Loc,
4900 Expressions => New_List (
4901 Make_Integer_Literal (Loc, Num_Ifaces),
4902 Make_Aggregate (Loc,
4903 Expressions => TSD_Ifaces_List)))));
4906 Make_Attribute_Definition_Clause (Loc,
4907 Name => New_Reference_To (ITable, Loc),
4908 Chars => Name_Alignment,
4910 Make_Attribute_Reference (Loc,
4912 New_Reference_To (RTE (RE_Integer_Address), Loc),
4913 Attribute_Name => Name_Alignment)));
4916 Make_Attribute_Reference (Loc,
4917 Prefix => New_Reference_To (ITable, Loc),
4918 Attribute_Name => Name_Unchecked_Access);
4922 Append_To (TSD_Aggr_List, Iface_Table_Node);
4925 -- Generate the Select Specific Data table for synchronized types that
4926 -- implement synchronized interfaces. The size of the table is
4927 -- constrained by the number of non-predefined primitive operations.
4929 if RTE_Record_Component_Available (RE_SSD) then
4930 if Ada_Version >= Ada_05
4931 and then Has_DT (Typ)
4932 and then Is_Concurrent_Record_Type (Typ)
4933 and then Has_Interfaces (Typ)
4934 and then Nb_Prim > 0
4935 and then not Is_Abstract_Type (Typ)
4936 and then not Is_Controlled (Typ)
4937 and then not Restriction_Active (No_Dispatching_Calls)
4938 and then not Restriction_Active (No_Select_Statements)
4941 Make_Object_Declaration (Loc,
4942 Defining_Identifier => SSD,
4943 Aliased_Present => True,
4944 Object_Definition =>
4945 Make_Subtype_Indication (Loc,
4946 Subtype_Mark => New_Reference_To (
4947 RTE (RE_Select_Specific_Data), Loc),
4949 Make_Index_Or_Discriminant_Constraint (Loc,
4950 Constraints => New_List (
4951 Make_Integer_Literal (Loc, Nb_Prim))))));
4954 Make_Attribute_Definition_Clause (Loc,
4955 Name => New_Reference_To (SSD, Loc),
4956 Chars => Name_Alignment,
4958 Make_Attribute_Reference (Loc,
4960 New_Reference_To (RTE (RE_Integer_Address), Loc),
4961 Attribute_Name => Name_Alignment)));
4963 -- This table is initialized by Make_Select_Specific_Data_Table,
4964 -- which calls Set_Entry_Index and Set_Prim_Op_Kind.
4966 Append_To (TSD_Aggr_List,
4967 Make_Attribute_Reference (Loc,
4968 Prefix => New_Reference_To (SSD, Loc),
4969 Attribute_Name => Name_Unchecked_Access));
4971 Append_To (TSD_Aggr_List, Make_Null (Loc));
4975 -- Initialize the table of ancestor tags. In case of interface types
4976 -- this table is not needed.
4978 TSD_Tags_List := New_List;
4980 -- If we are not statically allocating the dispatch table then we must
4981 -- fill position 0 with null because we still have not generated the
4984 if not Building_Static_DT (Typ)
4985 or else Is_Interface (Typ)
4987 Append_To (TSD_Tags_List,
4988 Unchecked_Convert_To (RTE (RE_Tag),
4989 New_Reference_To (RTE (RE_Null_Address), Loc)));
4991 -- Otherwise we can safely reference the tag
4994 Append_To (TSD_Tags_List,
4995 New_Reference_To (DT_Ptr, Loc));
4998 -- Fill the rest of the table with the tags of the ancestors
5001 Current_Typ : Entity_Id;
5002 Parent_Typ : Entity_Id;
5010 Parent_Typ := Etype (Current_Typ);
5012 if Is_Private_Type (Parent_Typ) then
5013 Parent_Typ := Full_View (Base_Type (Parent_Typ));
5016 exit when Parent_Typ = Current_Typ;
5018 if Is_CPP_Class (Parent_Typ)
5019 or else Is_Interface (Typ)
5021 -- The tags defined in the C++ side will be inherited when
5022 -- the object is constructed (Exp_Ch3.Build_Init_Procedure)
5024 Append_To (TSD_Tags_List,
5025 Unchecked_Convert_To (RTE (RE_Tag),
5026 New_Reference_To (RTE (RE_Null_Address), Loc)));
5028 Append_To (TSD_Tags_List,
5030 (Node (First_Elmt (Access_Disp_Table (Parent_Typ))),
5035 Current_Typ := Parent_Typ;
5038 pragma Assert (Pos = I_Depth + 1);
5041 Append_To (TSD_Aggr_List,
5042 Make_Aggregate (Loc,
5043 Expressions => TSD_Tags_List));
5045 -- Build the TSD object
5048 Make_Object_Declaration (Loc,
5049 Defining_Identifier => TSD,
5050 Aliased_Present => True,
5051 Constant_Present => Building_Static_DT (Typ),
5052 Object_Definition =>
5053 Make_Subtype_Indication (Loc,
5054 Subtype_Mark => New_Reference_To (
5055 RTE (RE_Type_Specific_Data), Loc),
5057 Make_Index_Or_Discriminant_Constraint (Loc,
5058 Constraints => New_List (
5059 Make_Integer_Literal (Loc, I_Depth)))),
5061 Expression => Make_Aggregate (Loc,
5062 Expressions => TSD_Aggr_List)));
5064 Set_Is_True_Constant (TSD, Building_Static_DT (Typ));
5067 Make_Attribute_Definition_Clause (Loc,
5068 Name => New_Reference_To (TSD, Loc),
5069 Chars => Name_Alignment,
5071 Make_Attribute_Reference (Loc,
5072 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
5073 Attribute_Name => Name_Alignment)));
5075 -- Initialize or declare the dispatch table object
5077 if not Has_DT (Typ) then
5078 DT_Constr_List := New_List;
5079 DT_Aggr_List := New_List;
5084 Make_Attribute_Reference (Loc,
5085 Prefix => New_Reference_To (TSD, Loc),
5086 Attribute_Name => Name_Address);
5088 Append_To (DT_Constr_List, New_Node);
5089 Append_To (DT_Aggr_List, New_Copy (New_Node));
5090 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
5092 -- In case of locally defined tagged types we have already declared
5093 -- and uninitialized object for the dispatch table, which is now
5094 -- initialized by means of the following assignment:
5096 -- DT := (TSD'Address, 0);
5098 if not Building_Static_DT (Typ) then
5100 Make_Assignment_Statement (Loc,
5101 Name => New_Reference_To (DT, Loc),
5102 Expression => Make_Aggregate (Loc,
5103 Expressions => DT_Aggr_List)));
5105 -- In case of library level tagged types we declare and export now
5106 -- the constant object containing the dummy dispatch table. There
5107 -- is no need to declare the tag here because it has been previously
5108 -- declared by Make_Tags
5110 -- DT : aliased constant No_Dispatch_Table :=
5111 -- (NDT_TSD => TSD'Address;
5112 -- NDT_Prims_Ptr => 0);
5113 -- for DT'Alignment use Address'Alignment;
5117 Make_Object_Declaration (Loc,
5118 Defining_Identifier => DT,
5119 Aliased_Present => True,
5120 Constant_Present => True,
5121 Object_Definition =>
5122 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc),
5123 Expression => Make_Aggregate (Loc,
5124 Expressions => DT_Aggr_List)));
5126 if Generate_SCIL then
5127 Insert_Before (Last (Result),
5129 (Nkind => Dispatch_Table_Object_Init,
5130 Related_Node => Last (Result),
5135 Make_Attribute_Definition_Clause (Loc,
5136 Name => New_Reference_To (DT, Loc),
5137 Chars => Name_Alignment,
5139 Make_Attribute_Reference (Loc,
5141 New_Reference_To (RTE (RE_Integer_Address), Loc),
5142 Attribute_Name => Name_Alignment)));
5144 Export_DT (Typ, DT);
5147 -- Common case: Typ has a dispatch table
5151 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
5152 -- (predef-prim-op-1'address,
5153 -- predef-prim-op-2'address,
5155 -- predef-prim-op-n'address);
5156 -- for Predef_Prims'Alignment use Address'Alignment
5158 -- DT : Dispatch_Table (Nb_Prims) :=
5159 -- (Signature => <sig-value>,
5160 -- Tag_Kind => <tag_kind-value>,
5161 -- Predef_Prims => Predef_Prims'First'Address,
5162 -- Offset_To_Top => 0,
5163 -- TSD => TSD'Address;
5164 -- Prims_Ptr => (prim-op-1'address,
5165 -- prim-op-2'address,
5167 -- prim-op-n'address));
5168 -- for DT'Alignment use Address'Alignment
5175 if not Building_Static_DT (Typ) then
5176 Nb_Predef_Prims := Max_Predef_Prims;
5179 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5180 while Present (Prim_Elmt) loop
5181 Prim := Node (Prim_Elmt);
5183 if Is_Predefined_Dispatching_Operation (Prim)
5184 and then not Is_Abstract_Subprogram (Prim)
5186 Pos := UI_To_Int (DT_Position (Prim));
5188 if Pos > Nb_Predef_Prims then
5189 Nb_Predef_Prims := Pos;
5193 Next_Elmt (Prim_Elmt);
5199 (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
5204 Prim_Ops_Aggr_List := New_List;
5206 Prim_Table := (others => Empty);
5208 if Building_Static_DT (Typ) then
5209 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5210 while Present (Prim_Elmt) loop
5211 Prim := Node (Prim_Elmt);
5213 if Is_Predefined_Dispatching_Operation (Prim)
5214 and then not Is_Abstract_Subprogram (Prim)
5215 and then not Present (Prim_Table
5216 (UI_To_Int (DT_Position (Prim))))
5219 while Present (Alias (E)) loop
5223 pragma Assert (not Is_Abstract_Subprogram (E));
5224 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
5227 Next_Elmt (Prim_Elmt);
5231 for J in Prim_Table'Range loop
5232 if Present (Prim_Table (J)) then
5234 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
5235 Make_Attribute_Reference (Loc,
5236 Prefix => New_Reference_To (Prim_Table (J), Loc),
5237 Attribute_Name => Name_Unrestricted_Access));
5239 New_Node := Make_Null (Loc);
5242 Append_To (Prim_Ops_Aggr_List, New_Node);
5246 Make_Aggregate (Loc,
5247 Expressions => Prim_Ops_Aggr_List);
5250 Make_Subtype_Declaration (Loc,
5251 Defining_Identifier =>
5252 Make_Defining_Identifier (Loc,
5253 New_Internal_Name ('S')),
5254 Subtype_Indication =>
5255 New_Reference_To (RTE (RE_Address_Array), Loc));
5257 Append_To (Result, Decl);
5260 Make_Object_Declaration (Loc,
5261 Defining_Identifier => Predef_Prims,
5262 Aliased_Present => True,
5263 Constant_Present => Building_Static_DT (Typ),
5264 Object_Definition => New_Reference_To
5265 (Defining_Identifier (Decl), Loc),
5266 Expression => New_Node));
5268 -- Remember aggregates initializing dispatch tables
5270 Append_Elmt (New_Node, DT_Aggr);
5273 Make_Attribute_Definition_Clause (Loc,
5274 Name => New_Reference_To (Predef_Prims, Loc),
5275 Chars => Name_Alignment,
5277 Make_Attribute_Reference (Loc,
5279 New_Reference_To (RTE (RE_Integer_Address), Loc),
5280 Attribute_Name => Name_Alignment)));
5284 -- Stage 1: Initialize the discriminant and the record components
5286 DT_Constr_List := New_List;
5287 DT_Aggr_List := New_List;
5289 -- Num_Prims. If the tagged type has no primitives we add a dummy
5290 -- slot whose address will be the tag of this type.
5293 New_Node := Make_Integer_Literal (Loc, 1);
5295 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
5298 Append_To (DT_Constr_List, New_Node);
5299 Append_To (DT_Aggr_List, New_Copy (New_Node));
5303 if RTE_Record_Component_Available (RE_Signature) then
5304 Append_To (DT_Aggr_List,
5305 New_Reference_To (RTE (RE_Primary_DT), Loc));
5310 if RTE_Record_Component_Available (RE_Tag_Kind) then
5311 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
5316 Append_To (DT_Aggr_List,
5317 Make_Attribute_Reference (Loc,
5318 Prefix => New_Reference_To (Predef_Prims, Loc),
5319 Attribute_Name => Name_Address));
5323 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
5327 Append_To (DT_Aggr_List,
5328 Make_Attribute_Reference (Loc,
5329 Prefix => New_Reference_To (TSD, Loc),
5330 Attribute_Name => Name_Address));
5332 -- Stage 2: Initialize the table of primitive operations
5334 Prim_Ops_Aggr_List := New_List;
5337 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
5339 elsif not Building_Static_DT (Typ) then
5340 for J in 1 .. Nb_Prim loop
5341 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
5346 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
5349 Prim_Elmt : Elmt_Id;
5352 Prim_Table := (others => Empty);
5354 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5355 while Present (Prim_Elmt) loop
5356 Prim := Node (Prim_Elmt);
5358 -- Retrieve the ultimate alias of the primitive for proper
5359 -- handling of renamings and eliminated primitives.
5361 E := Ultimate_Alias (Prim);
5363 if Is_Imported (Prim)
5364 or else Present (Interface_Alias (Prim))
5365 or else Is_Predefined_Dispatching_Operation (Prim)
5366 or else Is_Eliminated (E)
5371 if not Is_Predefined_Dispatching_Operation (E)
5372 and then not Is_Abstract_Subprogram (E)
5373 and then not Present (Interface_Alias (E))
5376 (UI_To_Int (DT_Position (Prim)) <= Nb_Prim);
5378 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
5382 Next_Elmt (Prim_Elmt);
5385 for J in Prim_Table'Range loop
5386 if Present (Prim_Table (J)) then
5388 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
5389 Make_Attribute_Reference (Loc,
5390 Prefix => New_Reference_To (Prim_Table (J), Loc),
5391 Attribute_Name => Name_Unrestricted_Access));
5393 New_Node := Make_Null (Loc);
5396 Append_To (Prim_Ops_Aggr_List, New_Node);
5402 Make_Aggregate (Loc,
5403 Expressions => Prim_Ops_Aggr_List);
5405 Append_To (DT_Aggr_List, New_Node);
5407 -- Remember aggregates initializing dispatch tables
5409 Append_Elmt (New_Node, DT_Aggr);
5411 -- In case of locally defined tagged types we have already declared
5412 -- and uninitialized object for the dispatch table, which is now
5413 -- initialized by means of an assignment.
5415 if not Building_Static_DT (Typ) then
5417 Make_Assignment_Statement (Loc,
5418 Name => New_Reference_To (DT, Loc),
5419 Expression => Make_Aggregate (Loc,
5420 Expressions => DT_Aggr_List)));
5422 -- In case of library level tagged types we declare now and export
5423 -- the constant object containing the dispatch table.
5427 Make_Object_Declaration (Loc,
5428 Defining_Identifier => DT,
5429 Aliased_Present => True,
5430 Constant_Present => True,
5431 Object_Definition =>
5432 Make_Subtype_Indication (Loc,
5433 Subtype_Mark => New_Reference_To
5434 (RTE (RE_Dispatch_Table_Wrapper), Loc),
5435 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
5436 Constraints => DT_Constr_List)),
5437 Expression => Make_Aggregate (Loc,
5438 Expressions => DT_Aggr_List)));
5440 if Generate_SCIL then
5441 Insert_Before (Last (Result),
5443 (Nkind => Dispatch_Table_Object_Init,
5444 Related_Node => Last (Result),
5449 Make_Attribute_Definition_Clause (Loc,
5450 Name => New_Reference_To (DT, Loc),
5451 Chars => Name_Alignment,
5453 Make_Attribute_Reference (Loc,
5455 New_Reference_To (RTE (RE_Integer_Address), Loc),
5456 Attribute_Name => Name_Alignment)));
5458 Export_DT (Typ, DT);
5462 -- Initialize the table of ancestor tags if not building static
5465 if not Building_Static_DT (Typ)
5466 and then not Is_Interface (Typ)
5467 and then not Is_CPP_Class (Typ)
5470 Make_Assignment_Statement (Loc,
5472 Make_Indexed_Component (Loc,
5474 Make_Selected_Component (Loc,
5476 New_Reference_To (TSD, Loc),
5479 (RTE_Record_Component (RE_Tags_Table), Loc)),
5481 New_List (Make_Integer_Literal (Loc, 0))),
5485 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)));
5488 -- Inherit the dispatch tables of the parent. There is no need to
5489 -- inherit anything from the parent when building static dispatch tables
5490 -- because the whole dispatch table (including inherited primitives) has
5491 -- been already built.
5493 if Building_Static_DT (Typ) then
5496 -- If the ancestor is a CPP_Class type we inherit the dispatch tables
5497 -- in the init proc, and we don't need to fill them in here.
5499 elsif Is_CPP_Class (Parent_Typ) then
5502 -- Otherwise we fill in the dispatch tables here
5505 if Typ /= Parent_Typ
5506 and then not Is_Interface (Typ)
5507 and then not Restriction_Active (No_Dispatching_Calls)
5509 -- Inherit the dispatch table
5511 if not Is_Interface (Typ)
5512 and then not Is_Interface (Parent_Typ)
5513 and then not Is_CPP_Class (Parent_Typ)
5516 Nb_Prims : constant Int :=
5517 UI_To_Int (DT_Entry_Count
5518 (First_Tag_Component (Parent_Typ)));
5521 Append_To (Elab_Code,
5522 Build_Inherit_Predefined_Prims (Loc,
5528 (Access_Disp_Table (Parent_Typ)))), Loc),
5534 (Access_Disp_Table (Typ)))), Loc)));
5536 if Nb_Prims /= 0 then
5537 Append_To (Elab_Code,
5538 Build_Inherit_Prims (Loc,
5544 (Access_Disp_Table (Parent_Typ))), Loc),
5545 New_Tag_Node => New_Reference_To (DT_Ptr, Loc),
5546 Num_Prims => Nb_Prims));
5551 -- Inherit the secondary dispatch tables of the ancestor
5553 if not Is_CPP_Class (Parent_Typ) then
5555 Sec_DT_Ancestor : Elmt_Id :=
5559 (Access_Disp_Table (Parent_Typ))));
5560 Sec_DT_Typ : Elmt_Id :=
5564 (Access_Disp_Table (Typ))));
5566 procedure Copy_Secondary_DTs (Typ : Entity_Id);
5567 -- Local procedure required to climb through the ancestors
5568 -- and copy the contents of all their secondary dispatch
5571 ------------------------
5572 -- Copy_Secondary_DTs --
5573 ------------------------
5575 procedure Copy_Secondary_DTs (Typ : Entity_Id) is
5580 -- Climb to the ancestor (if any) handling private types
5582 if Present (Full_View (Etype (Typ))) then
5583 if Full_View (Etype (Typ)) /= Typ then
5584 Copy_Secondary_DTs (Full_View (Etype (Typ)));
5587 elsif Etype (Typ) /= Typ then
5588 Copy_Secondary_DTs (Etype (Typ));
5591 if Present (Interfaces (Typ))
5592 and then not Is_Empty_Elmt_List (Interfaces (Typ))
5594 Iface := First_Elmt (Interfaces (Typ));
5595 E := First_Entity (Typ);
5597 and then Present (Node (Sec_DT_Ancestor))
5598 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
5600 if Is_Tag (E) and then Chars (E) /= Name_uTag then
5602 Num_Prims : constant Int :=
5603 UI_To_Int (DT_Entry_Count (E));
5606 if not Is_Interface (Etype (Typ)) then
5608 -- Inherit first secondary dispatch table
5610 Append_To (Elab_Code,
5611 Build_Inherit_Predefined_Prims (Loc,
5613 Unchecked_Convert_To (RTE (RE_Tag),
5616 (Next_Elmt (Sec_DT_Ancestor)),
5619 Unchecked_Convert_To (RTE (RE_Tag),
5621 (Node (Next_Elmt (Sec_DT_Typ)),
5624 if Num_Prims /= 0 then
5625 Append_To (Elab_Code,
5626 Build_Inherit_Prims (Loc,
5627 Typ => Node (Iface),
5629 Unchecked_Convert_To
5632 (Node (Sec_DT_Ancestor),
5635 Unchecked_Convert_To
5638 (Node (Sec_DT_Typ), Loc)),
5639 Num_Prims => Num_Prims));
5643 Next_Elmt (Sec_DT_Ancestor);
5644 Next_Elmt (Sec_DT_Typ);
5646 -- Skip the secondary dispatch table of
5647 -- predefined primitives
5649 Next_Elmt (Sec_DT_Ancestor);
5650 Next_Elmt (Sec_DT_Typ);
5652 if not Is_Interface (Etype (Typ)) then
5654 -- Inherit second secondary dispatch table
5656 Append_To (Elab_Code,
5657 Build_Inherit_Predefined_Prims (Loc,
5659 Unchecked_Convert_To (RTE (RE_Tag),
5662 (Next_Elmt (Sec_DT_Ancestor)),
5665 Unchecked_Convert_To (RTE (RE_Tag),
5667 (Node (Next_Elmt (Sec_DT_Typ)),
5670 if Num_Prims /= 0 then
5671 Append_To (Elab_Code,
5672 Build_Inherit_Prims (Loc,
5673 Typ => Node (Iface),
5675 Unchecked_Convert_To
5678 (Node (Sec_DT_Ancestor),
5681 Unchecked_Convert_To
5684 (Node (Sec_DT_Typ), Loc)),
5685 Num_Prims => Num_Prims));
5690 Next_Elmt (Sec_DT_Ancestor);
5691 Next_Elmt (Sec_DT_Typ);
5693 -- Skip the secondary dispatch table of
5694 -- predefined primitives
5696 Next_Elmt (Sec_DT_Ancestor);
5697 Next_Elmt (Sec_DT_Typ);
5705 end Copy_Secondary_DTs;
5708 if Present (Node (Sec_DT_Ancestor))
5709 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
5711 -- Handle private types
5713 if Present (Full_View (Typ)) then
5714 Copy_Secondary_DTs (Full_View (Typ));
5716 Copy_Secondary_DTs (Typ);
5724 -- Generate code to register the Tag in the External_Tag hash table for
5725 -- the pure Ada type only.
5727 -- Register_Tag (Dt_Ptr);
5729 -- Skip this action in the following cases:
5730 -- 1) if Register_Tag is not available.
5731 -- 2) in No_Run_Time mode.
5732 -- 3) if Typ is not defined at the library level (this is required
5733 -- to avoid adding concurrency control to the hash table used
5734 -- by the run-time to register the tags).
5736 if not No_Run_Time_Mode
5737 and then Is_Library_Level_Entity (Typ)
5738 and then RTE_Available (RE_Register_Tag)
5740 Append_To (Elab_Code,
5741 Make_Procedure_Call_Statement (Loc,
5742 Name => New_Reference_To (RTE (RE_Register_Tag), Loc),
5743 Parameter_Associations =>
5744 New_List (New_Reference_To (DT_Ptr, Loc))));
5747 if not Is_Empty_List (Elab_Code) then
5748 Append_List_To (Result, Elab_Code);
5751 -- Populate the two auxiliary tables used for dispatching asynchronous,
5752 -- conditional and timed selects for synchronized types that implement
5753 -- a limited interface. Skip this step in Ravenscar profile or when
5754 -- general dispatching is forbidden.
5756 if Ada_Version >= Ada_05
5757 and then Is_Concurrent_Record_Type (Typ)
5758 and then Has_Interfaces (Typ)
5759 and then not Restriction_Active (No_Dispatching_Calls)
5760 and then not Restriction_Active (No_Select_Statements)
5762 Append_List_To (Result,
5763 Make_Select_Specific_Data_Table (Typ));
5766 -- Remember entities containing dispatch tables
5768 Append_Elmt (Predef_Prims, DT_Decl);
5769 Append_Elmt (DT, DT_Decl);
5771 Analyze_List (Result, Suppress => All_Checks);
5772 Set_Has_Dispatch_Table (Typ);
5774 -- Mark entities containing dispatch tables. Required by the backend to
5775 -- handle them properly.
5777 if not Is_Interface (Typ) then
5782 -- Ensure that entities Prim_Ptr and Predef_Prims_Table_Ptr have
5783 -- the decoration required by the backend
5785 Set_Is_Dispatch_Table_Entity (RTE (RE_Prim_Ptr));
5786 Set_Is_Dispatch_Table_Entity (RTE (RE_Predef_Prims_Table_Ptr));
5788 -- Object declarations
5790 Elmt := First_Elmt (DT_Decl);
5791 while Present (Elmt) loop
5792 Set_Is_Dispatch_Table_Entity (Node (Elmt));
5793 pragma Assert (Ekind (Etype (Node (Elmt))) = E_Array_Subtype
5794 or else Ekind (Etype (Node (Elmt))) = E_Record_Subtype);
5795 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
5799 -- Aggregates initializing dispatch tables
5801 Elmt := First_Elmt (DT_Aggr);
5802 while Present (Elmt) loop
5803 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
5812 -------------------------------------
5813 -- Make_Select_Specific_Data_Table --
5814 -------------------------------------
5816 function Make_Select_Specific_Data_Table
5817 (Typ : Entity_Id) return List_Id
5819 Assignments : constant List_Id := New_List;
5820 Loc : constant Source_Ptr := Sloc (Typ);
5822 Conc_Typ : Entity_Id;
5826 Prim_Als : Entity_Id;
5827 Prim_Elmt : Elmt_Id;
5831 type Examined_Array is array (Int range <>) of Boolean;
5833 function Find_Entry_Index (E : Entity_Id) return Uint;
5834 -- Given an entry, find its index in the visible declarations of the
5835 -- corresponding concurrent type of Typ.
5837 ----------------------
5838 -- Find_Entry_Index --
5839 ----------------------
5841 function Find_Entry_Index (E : Entity_Id) return Uint is
5842 Index : Uint := Uint_1;
5843 Subp_Decl : Entity_Id;
5847 and then not Is_Empty_List (Decls)
5849 Subp_Decl := First (Decls);
5850 while Present (Subp_Decl) loop
5851 if Nkind (Subp_Decl) = N_Entry_Declaration then
5852 if Defining_Identifier (Subp_Decl) = E then
5864 end Find_Entry_Index;
5866 -- Start of processing for Make_Select_Specific_Data_Table
5869 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
5871 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
5873 if Present (Corresponding_Concurrent_Type (Typ)) then
5874 Conc_Typ := Corresponding_Concurrent_Type (Typ);
5876 if Present (Full_View (Conc_Typ)) then
5877 Conc_Typ := Full_View (Conc_Typ);
5880 if Ekind (Conc_Typ) = E_Protected_Type then
5881 Decls := Visible_Declarations (Protected_Definition (
5882 Parent (Conc_Typ)));
5884 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
5885 Decls := Visible_Declarations (Task_Definition (
5886 Parent (Conc_Typ)));
5890 -- Count the non-predefined primitive operations
5892 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5893 while Present (Prim_Elmt) loop
5894 Prim := Node (Prim_Elmt);
5896 if not (Is_Predefined_Dispatching_Operation (Prim)
5897 or else Is_Predefined_Dispatching_Alias (Prim))
5899 Nb_Prim := Nb_Prim + 1;
5902 Next_Elmt (Prim_Elmt);
5906 Examined : Examined_Array (1 .. Nb_Prim) := (others => False);
5909 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5910 while Present (Prim_Elmt) loop
5911 Prim := Node (Prim_Elmt);
5913 -- Look for primitive overriding an abstract interface subprogram
5915 if Present (Interface_Alias (Prim))
5916 and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
5918 Prim_Pos := DT_Position (Alias (Prim));
5919 pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
5920 Examined (UI_To_Int (Prim_Pos)) := True;
5922 -- Set the primitive operation kind regardless of subprogram
5924 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
5926 Append_To (Assignments,
5927 Make_Procedure_Call_Statement (Loc,
5928 Name => New_Reference_To (RTE (RE_Set_Prim_Op_Kind), Loc),
5929 Parameter_Associations => New_List (
5930 New_Reference_To (DT_Ptr, Loc),
5931 Make_Integer_Literal (Loc, Prim_Pos),
5932 Prim_Op_Kind (Alias (Prim), Typ))));
5934 -- Retrieve the root of the alias chain
5937 while Present (Alias (Prim_Als)) loop
5938 Prim_Als := Alias (Prim_Als);
5941 -- In the case of an entry wrapper, set the entry index
5943 if Ekind (Prim) = E_Procedure
5944 and then Is_Primitive_Wrapper (Prim_Als)
5945 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
5948 -- Ada.Tags.Set_Entry_Index
5949 -- (DT_Ptr, <position>, <index>);
5951 Append_To (Assignments,
5952 Make_Procedure_Call_Statement (Loc,
5954 New_Reference_To (RTE (RE_Set_Entry_Index), Loc),
5955 Parameter_Associations => New_List (
5956 New_Reference_To (DT_Ptr, Loc),
5957 Make_Integer_Literal (Loc, Prim_Pos),
5958 Make_Integer_Literal (Loc,
5959 Find_Entry_Index (Wrapped_Entity (Prim_Als))))));
5963 Next_Elmt (Prim_Elmt);
5968 end Make_Select_Specific_Data_Table;
5974 function Make_Tags (Typ : Entity_Id) return List_Id is
5975 Loc : constant Source_Ptr := Sloc (Typ);
5976 Result : constant List_Id := New_List;
5979 (Tag_Typ : Entity_Id;
5981 Is_Secondary_DT : Boolean);
5982 -- Import the dispatch table DT of tagged type Tag_Typ. Required to
5983 -- generate forward references and statically allocate the table. For
5984 -- primary dispatch tables that require no dispatch table generate:
5985 -- DT : static aliased constant Non_Dispatch_Table_Wrapper;
5986 -- $pragma import (ada, DT);
5987 -- Otherwise generate:
5988 -- DT : static aliased constant Dispatch_Table_Wrapper (Nb_Prim);
5989 -- $pragma import (ada, DT);
5996 (Tag_Typ : Entity_Id;
5998 Is_Secondary_DT : Boolean)
6000 DT_Constr_List : List_Id;
6004 Set_Is_Imported (DT);
6005 Set_Ekind (DT, E_Constant);
6006 Set_Related_Type (DT, Typ);
6008 -- The scope must be set now to call Get_External_Name
6010 Set_Scope (DT, Current_Scope);
6012 Get_External_Name (DT, True);
6013 Set_Interface_Name (DT,
6014 Make_String_Literal (Loc,
6015 Strval => String_From_Name_Buffer));
6017 -- Ensure proper Sprint output of this implicit importation
6019 Set_Is_Internal (DT);
6021 -- Save this entity to allow Make_DT to generate its exportation
6023 Append_Elmt (DT, Dispatch_Table_Wrappers (Typ));
6025 -- No dispatch table required
6027 if not Is_Secondary_DT
6028 and then not Has_DT (Tag_Typ)
6031 Make_Object_Declaration (Loc,
6032 Defining_Identifier => DT,
6033 Aliased_Present => True,
6034 Constant_Present => True,
6035 Object_Definition =>
6036 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
6039 -- Calculate the number of primitives of the dispatch table and
6040 -- the size of the Type_Specific_Data record.
6043 UI_To_Int (DT_Entry_Count (First_Tag_Component (Tag_Typ)));
6045 -- If the tagged type has no primitives we add a dummy slot
6046 -- whose address will be the tag of this type.
6050 New_List (Make_Integer_Literal (Loc, 1));
6053 New_List (Make_Integer_Literal (Loc, Nb_Prim));
6057 Make_Object_Declaration (Loc,
6058 Defining_Identifier => DT,
6059 Aliased_Present => True,
6060 Constant_Present => True,
6061 Object_Definition =>
6062 Make_Subtype_Indication (Loc,
6064 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
6065 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
6066 Constraints => DT_Constr_List))));
6072 Tname : constant Name_Id := Chars (Typ);
6073 AI_Tag_Comp : Elmt_Id;
6076 Predef_Prims_Ptr : Node_Id;
6078 Iface_DT_Ptr : Node_Id;
6081 Typ_Comps : Elist_Id;
6083 -- Start of processing for Make_Tags
6086 -- 1) Generate the primary and secondary tag entities
6088 -- Collect the components associated with secondary dispatch tables
6090 if Has_Interfaces (Typ) then
6091 Collect_Interface_Components (Typ, Typ_Comps);
6094 -- 1) Generate the primary tag entities
6096 -- Primary dispatch table containing user-defined primitives
6098 DT_Ptr := Make_Defining_Identifier (Loc,
6099 New_External_Name (Tname, 'P'));
6100 Set_Etype (DT_Ptr, RTE (RE_Tag));
6102 -- Primary dispatch table containing predefined primitives
6105 Make_Defining_Identifier (Loc,
6106 Chars => New_External_Name (Tname, 'Y'));
6107 Set_Etype (Predef_Prims_Ptr, RTE (RE_Address));
6109 -- Import the forward declaration of the Dispatch Table wrapper record
6110 -- (Make_DT will take care of its exportation)
6112 if Building_Static_DT (Typ) then
6113 Set_Dispatch_Table_Wrappers (Typ, New_Elmt_List);
6116 Make_Defining_Identifier (Loc,
6117 Chars => New_External_Name (Tname, 'T'));
6119 Import_DT (Typ, DT, Is_Secondary_DT => False);
6121 if Has_DT (Typ) then
6123 Make_Object_Declaration (Loc,
6124 Defining_Identifier => DT_Ptr,
6125 Constant_Present => True,
6126 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
6128 Unchecked_Convert_To (RTE (RE_Tag),
6129 Make_Attribute_Reference (Loc,
6131 Make_Selected_Component (Loc,
6132 Prefix => New_Reference_To (DT, Loc),
6135 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
6136 Attribute_Name => Name_Address))));
6138 if Generate_SCIL then
6139 Insert_Before (Last (Result),
6141 (Nkind => Dispatch_Table_Tag_Init,
6142 Related_Node => Last (Result),
6147 Make_Object_Declaration (Loc,
6148 Defining_Identifier => Predef_Prims_Ptr,
6149 Constant_Present => True,
6150 Object_Definition => New_Reference_To
6151 (RTE (RE_Address), Loc),
6153 Make_Attribute_Reference (Loc,
6155 Make_Selected_Component (Loc,
6156 Prefix => New_Reference_To (DT, Loc),
6159 (RTE_Record_Component (RE_Predef_Prims), Loc)),
6160 Attribute_Name => Name_Address)));
6162 -- No dispatch table required
6166 Make_Object_Declaration (Loc,
6167 Defining_Identifier => DT_Ptr,
6168 Constant_Present => True,
6169 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
6171 Unchecked_Convert_To (RTE (RE_Tag),
6172 Make_Attribute_Reference (Loc,
6174 Make_Selected_Component (Loc,
6175 Prefix => New_Reference_To (DT, Loc),
6178 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
6179 Attribute_Name => Name_Address))));
6181 if Generate_SCIL then
6182 Insert_Before (Last (Result),
6184 (Nkind => Dispatch_Table_Tag_Init,
6185 Related_Node => Last (Result),
6190 Set_Is_True_Constant (DT_Ptr);
6191 Set_Is_Statically_Allocated (DT_Ptr);
6194 pragma Assert (No (Access_Disp_Table (Typ)));
6195 Set_Access_Disp_Table (Typ, New_Elmt_List);
6196 Append_Elmt (DT_Ptr, Access_Disp_Table (Typ));
6197 Append_Elmt (Predef_Prims_Ptr, Access_Disp_Table (Typ));
6199 -- 2) Generate the secondary tag entities
6201 if Has_Interfaces (Typ) then
6203 -- Note: The following value of Suffix_Index must be in sync with
6204 -- the Suffix_Index values of secondary dispatch tables generated
6209 -- For each interface type we build an unique external name
6210 -- associated with its corresponding secondary dispatch table.
6211 -- This external name will be used to declare an object that
6212 -- references this secondary dispatch table, value that will be
6213 -- used for the elaboration of Typ's objects and also for the
6214 -- elaboration of objects of derivations of Typ that do not
6215 -- override the primitive operation of this interface type.
6217 AI_Tag_Comp := First_Elmt (Typ_Comps);
6218 while Present (AI_Tag_Comp) loop
6219 Get_Secondary_DT_External_Name
6220 (Typ, Related_Type (Node (AI_Tag_Comp)), Suffix_Index);
6221 Typ_Name := Name_Find;
6223 if Building_Static_DT (Typ) then
6225 Make_Defining_Identifier (Loc,
6226 Chars => New_External_Name
6227 (Typ_Name, 'T', Suffix_Index => -1));
6229 (Tag_Typ => Related_Type (Node (AI_Tag_Comp)),
6231 Is_Secondary_DT => True);
6234 -- Secondary dispatch table referencing thunks to user-defined
6235 -- primitives covered by this interface.
6238 Make_Defining_Identifier (Loc,
6239 Chars => New_External_Name (Typ_Name, 'P'));
6240 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
6241 Set_Ekind (Iface_DT_Ptr, E_Constant);
6242 Set_Is_Tag (Iface_DT_Ptr);
6243 Set_Has_Thunks (Iface_DT_Ptr);
6244 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6245 Is_Library_Level_Tagged_Type (Typ));
6246 Set_Is_True_Constant (Iface_DT_Ptr);
6248 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6249 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6251 if Building_Static_DT (Typ) then
6253 Make_Object_Declaration (Loc,
6254 Defining_Identifier => Iface_DT_Ptr,
6255 Constant_Present => True,
6256 Object_Definition => New_Reference_To
6257 (RTE (RE_Interface_Tag), Loc),
6259 Unchecked_Convert_To (RTE (RE_Interface_Tag),
6260 Make_Attribute_Reference (Loc,
6262 Make_Selected_Component (Loc,
6263 Prefix => New_Reference_To (Iface_DT, Loc),
6266 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
6267 Attribute_Name => Name_Address))));
6270 -- Secondary dispatch table referencing thunks to predefined
6274 Make_Defining_Identifier (Loc,
6275 Chars => New_External_Name (Typ_Name, 'Y'));
6276 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
6277 Set_Ekind (Iface_DT_Ptr, E_Constant);
6278 Set_Is_Tag (Iface_DT_Ptr);
6279 Set_Has_Thunks (Iface_DT_Ptr);
6280 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6281 Is_Library_Level_Tagged_Type (Typ));
6282 Set_Is_True_Constant (Iface_DT_Ptr);
6284 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6285 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6287 -- Secondary dispatch table referencing user-defined primitives
6288 -- covered by this interface.
6291 Make_Defining_Identifier (Loc,
6292 Chars => New_External_Name (Typ_Name, 'D'));
6293 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
6294 Set_Ekind (Iface_DT_Ptr, E_Constant);
6295 Set_Is_Tag (Iface_DT_Ptr);
6296 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6297 Is_Library_Level_Tagged_Type (Typ));
6298 Set_Is_True_Constant (Iface_DT_Ptr);
6300 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6301 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6303 -- Secondary dispatch table referencing predefined primitives
6306 Make_Defining_Identifier (Loc,
6307 Chars => New_External_Name (Typ_Name, 'Z'));
6308 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
6309 Set_Ekind (Iface_DT_Ptr, E_Constant);
6310 Set_Is_Tag (Iface_DT_Ptr);
6311 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6312 Is_Library_Level_Tagged_Type (Typ));
6313 Set_Is_True_Constant (Iface_DT_Ptr);
6315 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6316 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6318 Next_Elmt (AI_Tag_Comp);
6322 -- 3) At the end of Access_Disp_Table, if the type has user-defined
6323 -- primitives, we add the entity of an access type declaration that
6324 -- is used by Build_Get_Prim_Op_Address to expand dispatching calls
6325 -- through the primary dispatch table.
6327 if UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ))) = 0 then
6328 Analyze_List (Result);
6331 -- type Typ_DT is array (1 .. Nb_Prims) of Prim_Ptr;
6332 -- type Typ_DT_Acc is access Typ_DT;
6336 Name_DT_Prims : constant Name_Id :=
6337 New_External_Name (Tname, 'G');
6338 Name_DT_Prims_Acc : constant Name_Id :=
6339 New_External_Name (Tname, 'H');
6340 DT_Prims : constant Entity_Id :=
6341 Make_Defining_Identifier (Loc,
6343 DT_Prims_Acc : constant Entity_Id :=
6344 Make_Defining_Identifier (Loc,
6348 Make_Full_Type_Declaration (Loc,
6349 Defining_Identifier => DT_Prims,
6351 Make_Constrained_Array_Definition (Loc,
6352 Discrete_Subtype_Definitions => New_List (
6354 Low_Bound => Make_Integer_Literal (Loc, 1),
6355 High_Bound => Make_Integer_Literal (Loc,
6357 (First_Tag_Component (Typ))))),
6358 Component_Definition =>
6359 Make_Component_Definition (Loc,
6360 Subtype_Indication =>
6361 New_Reference_To (RTE (RE_Prim_Ptr), Loc)))));
6364 Make_Full_Type_Declaration (Loc,
6365 Defining_Identifier => DT_Prims_Acc,
6367 Make_Access_To_Object_Definition (Loc,
6368 Subtype_Indication =>
6369 New_Occurrence_Of (DT_Prims, Loc))));
6371 Append_Elmt (DT_Prims_Acc, Access_Disp_Table (Typ));
6373 -- Analyze the resulting list and suppress the generation of the
6374 -- Init_Proc associated with the above array declaration because
6375 -- this type is never used in object declarations. It is only used
6376 -- to simplify the expansion associated with dispatching calls.
6378 Analyze_List (Result);
6379 Set_Suppress_Init_Proc (Base_Type (DT_Prims));
6381 -- Mark entity of dispatch table. Required by the back end to
6382 -- handle them properly.
6384 Set_Is_Dispatch_Table_Entity (DT_Prims);
6388 Set_Ekind (DT_Ptr, E_Constant);
6389 Set_Is_Tag (DT_Ptr);
6390 Set_Related_Type (DT_Ptr, Typ);
6399 function New_Value (From : Node_Id) return Node_Id is
6400 Res : constant Node_Id := Duplicate_Subexpr (From);
6402 if Is_Access_Type (Etype (From)) then
6403 return Make_Explicit_Dereference (Sloc (From),
6414 function New_Scil_Node
6415 (Nkind : Scil_Node_Kind;
6416 Related_Node : Node_Id;
6417 Entity : Entity_Id := Empty;
6418 Target_Prim : Entity_Id := Empty) return Node_Id
6423 New_N := New_Node (N_Null_Statement, Sloc (Related_Node));
6424 Set_Is_Scil_Node (New_N);
6425 Set_Scil_Nkind (New_N, UI_From_Int (Scil_Node_Kind'Pos (Nkind)));
6426 Set_Scil_Related_Node (New_N, Related_Node);
6427 Set_Entity (New_N, Entity);
6428 Set_Scil_Target_Prim (New_N, Target_Prim);
6433 -----------------------------------
6434 -- Original_View_In_Visible_Part --
6435 -----------------------------------
6437 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
6438 Scop : constant Entity_Id := Scope (Typ);
6441 -- The scope must be a package
6443 if not Is_Package_Or_Generic_Package (Scop) then
6447 -- A type with a private declaration has a private view declared in
6448 -- the visible part.
6450 if Has_Private_Declaration (Typ) then
6454 return List_Containing (Parent (Typ)) =
6455 Visible_Declarations (Specification (Unit_Declaration_Node (Scop)));
6456 end Original_View_In_Visible_Part;
6462 function Prim_Op_Kind
6464 Typ : Entity_Id) return Node_Id
6466 Full_Typ : Entity_Id := Typ;
6467 Loc : constant Source_Ptr := Sloc (Prim);
6468 Prim_Op : Entity_Id;
6471 -- Retrieve the original primitive operation
6474 while Present (Alias (Prim_Op)) loop
6475 Prim_Op := Alias (Prim_Op);
6478 if Ekind (Typ) = E_Record_Type
6479 and then Present (Corresponding_Concurrent_Type (Typ))
6481 Full_Typ := Corresponding_Concurrent_Type (Typ);
6484 -- When a private tagged type is completed by a concurrent type,
6485 -- retrieve the full view.
6487 if Is_Private_Type (Full_Typ) then
6488 Full_Typ := Full_View (Full_Typ);
6491 if Ekind (Prim_Op) = E_Function then
6493 -- Protected function
6495 if Ekind (Full_Typ) = E_Protected_Type then
6496 return New_Reference_To (RTE (RE_POK_Protected_Function), Loc);
6500 elsif Ekind (Full_Typ) = E_Task_Type then
6501 return New_Reference_To (RTE (RE_POK_Task_Function), Loc);
6506 return New_Reference_To (RTE (RE_POK_Function), Loc);
6510 pragma Assert (Ekind (Prim_Op) = E_Procedure);
6512 if Ekind (Full_Typ) = E_Protected_Type then
6516 if Is_Primitive_Wrapper (Prim_Op)
6517 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
6519 return New_Reference_To (RTE (RE_POK_Protected_Entry), Loc);
6521 -- Protected procedure
6524 return New_Reference_To (RTE (RE_POK_Protected_Procedure), Loc);
6527 elsif Ekind (Full_Typ) = E_Task_Type then
6531 if Is_Primitive_Wrapper (Prim_Op)
6532 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
6534 return New_Reference_To (RTE (RE_POK_Task_Entry), Loc);
6536 -- Task "procedure". These are the internally Expander-generated
6537 -- procedures (task body for instance).
6540 return New_Reference_To (RTE (RE_POK_Task_Procedure), Loc);
6543 -- Regular procedure
6546 return New_Reference_To (RTE (RE_POK_Procedure), Loc);
6551 ------------------------
6552 -- Register_Primitive --
6553 ------------------------
6555 function Register_Primitive
6557 Prim : Entity_Id) return List_Id
6560 Iface_Prim : Entity_Id;
6561 Iface_Typ : Entity_Id;
6562 Iface_DT_Ptr : Entity_Id;
6563 Iface_DT_Elmt : Elmt_Id;
6564 L : constant List_Id := New_List;
6567 Tag_Typ : Entity_Id;
6568 Thunk_Id : Entity_Id;
6569 Thunk_Code : Node_Id;
6572 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
6574 if not RTE_Available (RE_Tag) then
6578 if not Present (Interface_Alias (Prim)) then
6579 Tag_Typ := Scope (DTC_Entity (Prim));
6580 Pos := DT_Position (Prim);
6581 Tag := First_Tag_Component (Tag_Typ);
6583 if Is_Predefined_Dispatching_Operation (Prim)
6584 or else Is_Predefined_Dispatching_Alias (Prim)
6587 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Tag_Typ))));
6590 Build_Set_Predefined_Prim_Op_Address (Loc,
6591 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6594 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6595 Make_Attribute_Reference (Loc,
6596 Prefix => New_Reference_To (Prim, Loc),
6597 Attribute_Name => Name_Unrestricted_Access))));
6599 -- Register copy of the pointer to the 'size primitive in the TSD
6601 if Chars (Prim) = Name_uSize
6602 and then RTE_Record_Component_Available (RE_Size_Func)
6604 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
6606 Build_Set_Size_Function (Loc,
6607 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6608 Size_Func => Prim));
6612 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
6614 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
6616 Build_Set_Prim_Op_Address (Loc,
6618 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6621 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6622 Make_Attribute_Reference (Loc,
6623 Prefix => New_Reference_To (Prim, Loc),
6624 Attribute_Name => Name_Unrestricted_Access))));
6627 -- Ada 2005 (AI-251): Primitive associated with an interface type
6628 -- Generate the code of the thunk only if the interface type is not an
6629 -- immediate ancestor of Typ; otherwise the dispatch table associated
6630 -- with the interface is the primary dispatch table and we have nothing
6634 Tag_Typ := Find_Dispatching_Type (Alias (Prim));
6635 Iface_Typ := Find_Dispatching_Type (Interface_Alias (Prim));
6637 pragma Assert (Is_Interface (Iface_Typ));
6639 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
6641 if not Is_Ancestor (Iface_Typ, Tag_Typ)
6642 and then Present (Thunk_Code)
6644 -- Generate the code necessary to fill the appropriate entry of
6645 -- the secondary dispatch table of Prim's controlling type with
6646 -- Thunk_Id's address.
6648 Iface_DT_Elmt := Find_Interface_ADT (Tag_Typ, Iface_Typ);
6649 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6650 pragma Assert (Has_Thunks (Iface_DT_Ptr));
6652 Iface_Prim := Interface_Alias (Prim);
6653 Pos := DT_Position (Iface_Prim);
6654 Tag := First_Tag_Component (Iface_Typ);
6656 Prepend_To (L, Thunk_Code);
6658 if Is_Predefined_Dispatching_Operation (Prim)
6659 or else Is_Predefined_Dispatching_Alias (Prim)
6662 Build_Set_Predefined_Prim_Op_Address (Loc,
6664 New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
6667 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6668 Make_Attribute_Reference (Loc,
6669 Prefix => New_Reference_To (Thunk_Id, Loc),
6670 Attribute_Name => Name_Unrestricted_Access))));
6672 Next_Elmt (Iface_DT_Elmt);
6673 Next_Elmt (Iface_DT_Elmt);
6674 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6675 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
6678 Build_Set_Predefined_Prim_Op_Address (Loc,
6680 New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
6683 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6684 Make_Attribute_Reference (Loc,
6685 Prefix => New_Reference_To (Alias (Prim), Loc),
6686 Attribute_Name => Name_Unrestricted_Access))));
6689 pragma Assert (Pos /= Uint_0
6690 and then Pos <= DT_Entry_Count (Tag));
6693 Build_Set_Prim_Op_Address (Loc,
6695 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
6698 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6699 Make_Attribute_Reference (Loc,
6700 Prefix => New_Reference_To (Thunk_Id, Loc),
6701 Attribute_Name => Name_Unrestricted_Access))));
6703 Next_Elmt (Iface_DT_Elmt);
6704 Next_Elmt (Iface_DT_Elmt);
6705 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6706 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
6709 Build_Set_Prim_Op_Address (Loc,
6711 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
6714 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6715 Make_Attribute_Reference (Loc,
6716 Prefix => New_Reference_To (Alias (Prim), Loc),
6717 Attribute_Name => Name_Unrestricted_Access))));
6724 end Register_Primitive;
6726 -------------------------
6727 -- Set_All_DT_Position --
6728 -------------------------
6730 procedure Set_All_DT_Position (Typ : Entity_Id) is
6732 procedure Validate_Position (Prim : Entity_Id);
6733 -- Check that the position assigned to Prim is completely safe
6734 -- (it has not been assigned to a previously defined primitive
6735 -- operation of Typ)
6737 -----------------------
6738 -- Validate_Position --
6739 -----------------------
6741 procedure Validate_Position (Prim : Entity_Id) is
6746 -- Aliased primitives are safe
6748 if Present (Alias (Prim)) then
6752 Op_Elmt := First_Elmt (Primitive_Operations (Typ));
6753 while Present (Op_Elmt) loop
6754 Op := Node (Op_Elmt);
6756 -- No need to check against itself
6761 -- Primitive operations covering abstract interfaces are
6764 elsif Present (Interface_Alias (Op)) then
6767 -- Predefined dispatching operations are completely safe. They
6768 -- are allocated at fixed positions in a separate table.
6770 elsif Is_Predefined_Dispatching_Operation (Op)
6771 or else Is_Predefined_Dispatching_Alias (Op)
6775 -- Aliased subprograms are safe
6777 elsif Present (Alias (Op)) then
6780 elsif DT_Position (Op) = DT_Position (Prim)
6781 and then not Is_Predefined_Dispatching_Operation (Op)
6782 and then not Is_Predefined_Dispatching_Operation (Prim)
6783 and then not Is_Predefined_Dispatching_Alias (Op)
6784 and then not Is_Predefined_Dispatching_Alias (Prim)
6787 -- Handle aliased subprograms
6796 if Present (Overridden_Operation (Op_1)) then
6797 Op_1 := Overridden_Operation (Op_1);
6798 elsif Present (Alias (Op_1)) then
6799 Op_1 := Alias (Op_1);
6807 if Present (Overridden_Operation (Op_2)) then
6808 Op_2 := Overridden_Operation (Op_2);
6809 elsif Present (Alias (Op_2)) then
6810 Op_2 := Alias (Op_2);
6816 if Op_1 /= Op_2 then
6817 raise Program_Error;
6822 Next_Elmt (Op_Elmt);
6824 end Validate_Position;
6828 Parent_Typ : constant Entity_Id := Etype (Typ);
6829 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
6830 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
6832 Adjusted : Boolean := False;
6833 Finalized : Boolean := False;
6839 Prim_Elmt : Elmt_Id;
6841 -- Start of processing for Set_All_DT_Position
6844 pragma Assert (Present (First_Tag_Component (Typ)));
6846 -- Set the DT_Position for each primitive operation. Perform some
6847 -- sanity checks to avoid to build completely inconsistent dispatch
6850 -- First stage: Set the DTC entity of all the primitive operations
6851 -- This is required to properly read the DT_Position attribute in
6852 -- the latter stages.
6854 Prim_Elmt := First_Prim;
6856 while Present (Prim_Elmt) loop
6857 Prim := Node (Prim_Elmt);
6859 -- Predefined primitives have a separate dispatch table
6861 if not (Is_Predefined_Dispatching_Operation (Prim)
6862 or else Is_Predefined_Dispatching_Alias (Prim))
6864 Count_Prim := Count_Prim + 1;
6867 Set_DTC_Entity_Value (Typ, Prim);
6869 -- Clear any previous value of the DT_Position attribute. In this
6870 -- way we ensure that the final position of all the primitives is
6871 -- established by the following stages of this algorithm.
6873 Set_DT_Position (Prim, No_Uint);
6875 Next_Elmt (Prim_Elmt);
6879 Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean :=
6884 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id);
6885 -- Called if Typ is declared in a nested package or a public child
6886 -- package to handle inherited primitives that were inherited by Typ
6887 -- in the visible part, but whose declaration was deferred because
6888 -- the parent operation was private and not visible at that point.
6890 procedure Set_Fixed_Prim (Pos : Nat);
6891 -- Sets to true an element of the Fixed_Prim table to indicate
6892 -- that this entry of the dispatch table of Typ is occupied.
6894 ------------------------------------------
6895 -- Handle_Inherited_Private_Subprograms --
6896 ------------------------------------------
6898 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id) is
6901 Op_Elmt_2 : Elmt_Id;
6902 Prim_Op : Entity_Id;
6903 Parent_Subp : Entity_Id;
6906 Op_List := Primitive_Operations (Typ);
6908 Op_Elmt := First_Elmt (Op_List);
6909 while Present (Op_Elmt) loop
6910 Prim_Op := Node (Op_Elmt);
6912 -- Search primitives that are implicit operations with an
6913 -- internal name whose parent operation has a normal name.
6915 if Present (Alias (Prim_Op))
6916 and then Find_Dispatching_Type (Alias (Prim_Op)) /= Typ
6917 and then not Comes_From_Source (Prim_Op)
6918 and then Is_Internal_Name (Chars (Prim_Op))
6919 and then not Is_Internal_Name (Chars (Alias (Prim_Op)))
6921 Parent_Subp := Alias (Prim_Op);
6923 -- Check if the type has an explicit overriding for this
6926 Op_Elmt_2 := Next_Elmt (Op_Elmt);
6927 while Present (Op_Elmt_2) loop
6928 if Chars (Node (Op_Elmt_2)) = Chars (Parent_Subp)
6929 and then Type_Conformant (Prim_Op, Node (Op_Elmt_2))
6931 Set_DT_Position (Prim_Op, DT_Position (Parent_Subp));
6932 Set_DT_Position (Node (Op_Elmt_2),
6933 DT_Position (Parent_Subp));
6934 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim_Op)));
6936 goto Next_Primitive;
6939 Next_Elmt (Op_Elmt_2);
6944 Next_Elmt (Op_Elmt);
6946 end Handle_Inherited_Private_Subprograms;
6948 --------------------
6949 -- Set_Fixed_Prim --
6950 --------------------
6952 procedure Set_Fixed_Prim (Pos : Nat) is
6954 pragma Assert (Pos <= Count_Prim);
6955 Fixed_Prim (Pos) := True;
6957 when Constraint_Error =>
6958 raise Program_Error;
6962 -- In case of nested packages and public child package it may be
6963 -- necessary a special management on inherited subprograms so that
6964 -- the dispatch table is properly filled.
6966 if Ekind (Scope (Scope (Typ))) = E_Package
6967 and then Scope (Scope (Typ)) /= Standard_Standard
6968 and then ((Is_Derived_Type (Typ) and then not Is_Private_Type (Typ))
6970 (Nkind (Parent (Typ)) = N_Private_Extension_Declaration
6971 and then Is_Generic_Type (Typ)))
6972 and then In_Open_Scopes (Scope (Etype (Typ)))
6973 and then Typ = Base_Type (Typ)
6975 Handle_Inherited_Private_Subprograms (Typ);
6978 -- Second stage: Register fixed entries
6981 Prim_Elmt := First_Prim;
6982 while Present (Prim_Elmt) loop
6983 Prim := Node (Prim_Elmt);
6985 -- Predefined primitives have a separate table and all its
6986 -- entries are at predefined fixed positions.
6988 if Is_Predefined_Dispatching_Operation (Prim) then
6989 Set_DT_Position (Prim, Default_Prim_Op_Position (Prim));
6991 elsif Is_Predefined_Dispatching_Alias (Prim) then
6993 while Present (Alias (E)) loop
6997 Set_DT_Position (Prim, Default_Prim_Op_Position (E));
6999 -- Overriding primitives of ancestor abstract interfaces
7001 elsif Present (Interface_Alias (Prim))
7002 and then Is_Ancestor
7003 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ)
7005 pragma Assert (DT_Position (Prim) = No_Uint
7006 and then Present (DTC_Entity (Interface_Alias (Prim))));
7008 E := Interface_Alias (Prim);
7009 Set_DT_Position (Prim, DT_Position (E));
7012 (DT_Position (Alias (Prim)) = No_Uint
7013 or else DT_Position (Alias (Prim)) = DT_Position (E));
7014 Set_DT_Position (Alias (Prim), DT_Position (E));
7015 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));
7017 -- Overriding primitives must use the same entry as the
7018 -- overridden primitive.
7020 elsif not Present (Interface_Alias (Prim))
7021 and then Present (Alias (Prim))
7022 and then Chars (Prim) = Chars (Alias (Prim))
7023 and then Find_Dispatching_Type (Alias (Prim)) /= Typ
7024 and then Is_Ancestor
7025 (Find_Dispatching_Type (Alias (Prim)), Typ)
7026 and then Present (DTC_Entity (Alias (Prim)))
7029 Set_DT_Position (Prim, DT_Position (E));
7031 if not Is_Predefined_Dispatching_Alias (E) then
7032 Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
7036 Next_Elmt (Prim_Elmt);
7039 -- Third stage: Fix the position of all the new primitives
7040 -- Entries associated with primitives covering interfaces
7041 -- are handled in a latter round.
7043 Prim_Elmt := First_Prim;
7044 while Present (Prim_Elmt) loop
7045 Prim := Node (Prim_Elmt);
7047 -- Skip primitives previously set entries
7049 if DT_Position (Prim) /= No_Uint then
7052 -- Primitives covering interface primitives are handled later
7054 elsif Present (Interface_Alias (Prim)) then
7058 -- Take the next available position in the DT
7061 Nb_Prim := Nb_Prim + 1;
7062 pragma Assert (Nb_Prim <= Count_Prim);
7063 exit when not Fixed_Prim (Nb_Prim);
7066 Set_DT_Position (Prim, UI_From_Int (Nb_Prim));
7067 Set_Fixed_Prim (Nb_Prim);
7070 Next_Elmt (Prim_Elmt);
7074 -- Fourth stage: Complete the decoration of primitives covering
7075 -- interfaces (that is, propagate the DT_Position attribute
7076 -- from the aliased primitive)
7078 Prim_Elmt := First_Prim;
7079 while Present (Prim_Elmt) loop
7080 Prim := Node (Prim_Elmt);
7082 if DT_Position (Prim) = No_Uint
7083 and then Present (Interface_Alias (Prim))
7085 pragma Assert (Present (Alias (Prim))
7086 and then Find_Dispatching_Type (Alias (Prim)) = Typ);
7088 -- Check if this entry will be placed in the primary DT
7091 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ)
7093 pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
7094 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
7096 -- Otherwise it will be placed in the secondary DT
7100 (DT_Position (Interface_Alias (Prim)) /= No_Uint);
7101 Set_DT_Position (Prim,
7102 DT_Position (Interface_Alias (Prim)));
7106 Next_Elmt (Prim_Elmt);
7109 -- Generate listing showing the contents of the dispatch tables.
7110 -- This action is done before some further static checks because
7111 -- in case of critical errors caused by a wrong dispatch table
7112 -- we need to see the contents of such table.
7114 if Debug_Flag_ZZ then
7118 -- Final stage: Ensure that the table is correct plus some further
7119 -- verifications concerning the primitives.
7121 Prim_Elmt := First_Prim;
7123 while Present (Prim_Elmt) loop
7124 Prim := Node (Prim_Elmt);
7126 -- At this point all the primitives MUST have a position
7127 -- in the dispatch table.
7129 if DT_Position (Prim) = No_Uint then
7130 raise Program_Error;
7133 -- Calculate real size of the dispatch table
7135 if not (Is_Predefined_Dispatching_Operation (Prim)
7136 or else Is_Predefined_Dispatching_Alias (Prim))
7137 and then UI_To_Int (DT_Position (Prim)) > DT_Length
7139 DT_Length := UI_To_Int (DT_Position (Prim));
7142 -- Ensure that the assigned position to non-predefined
7143 -- dispatching operations in the dispatch table is correct.
7145 if not (Is_Predefined_Dispatching_Operation (Prim)
7146 or else Is_Predefined_Dispatching_Alias (Prim))
7148 Validate_Position (Prim);
7151 if Chars (Prim) = Name_Finalize then
7155 if Chars (Prim) = Name_Adjust then
7159 -- An abstract operation cannot be declared in the private part
7160 -- for a visible abstract type, because it could never be over-
7161 -- ridden. For explicit declarations this is checked at the
7162 -- point of declaration, but for inherited operations it must
7163 -- be done when building the dispatch table.
7165 -- Ada 2005 (AI-251): Primitives associated with interfaces are
7166 -- excluded from this check because interfaces must be visible in
7167 -- the public and private part (RM 7.3 (7.3/2))
7169 if Is_Abstract_Type (Typ)
7170 and then Is_Abstract_Subprogram (Prim)
7171 and then Present (Alias (Prim))
7172 and then not Is_Interface
7173 (Find_Dispatching_Type (Ultimate_Alias (Prim)))
7174 and then not Present (Interface_Alias (Prim))
7175 and then Is_Derived_Type (Typ)
7176 and then In_Private_Part (Current_Scope)
7178 List_Containing (Parent (Prim)) =
7179 Private_Declarations
7180 (Specification (Unit_Declaration_Node (Current_Scope)))
7181 and then Original_View_In_Visible_Part (Typ)
7183 -- We exclude Input and Output stream operations because
7184 -- Limited_Controlled inherits useless Input and Output
7185 -- stream operations from Root_Controlled, which can
7186 -- never be overridden.
7188 if not Is_TSS (Prim, TSS_Stream_Input)
7190 not Is_TSS (Prim, TSS_Stream_Output)
7193 ("abstract inherited private operation&" &
7194 " must be overridden (RM 3.9.3(10))",
7195 Parent (Typ), Prim);
7199 Next_Elmt (Prim_Elmt);
7204 if Is_Controlled (Typ) then
7205 if not Finalized then
7207 ("controlled type has no explicit Finalize method?", Typ);
7209 elsif not Adjusted then
7211 ("controlled type has no explicit Adjust method?", Typ);
7215 -- Set the final size of the Dispatch Table
7217 Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));
7219 -- The derived type must have at least as many components as its parent
7220 -- (for root types Etype points to itself and the test cannot fail).
7222 if DT_Entry_Count (The_Tag) <
7223 DT_Entry_Count (First_Tag_Component (Parent_Typ))
7225 raise Program_Error;
7227 end Set_All_DT_Position;
7229 --------------------------
7230 -- Set_CPP_Constructors --
7231 --------------------------
7233 procedure Set_CPP_Constructors (Typ : Entity_Id) is
7237 Found : Boolean := False;
7242 -- Look for the constructor entities
7244 E := Next_Entity (Typ);
7245 while Present (E) loop
7246 if Ekind (E) = E_Function
7247 and then Is_Constructor (E)
7249 -- Create the init procedure
7253 Init := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
7256 Make_Parameter_Specification (Loc,
7257 Defining_Identifier =>
7258 Make_Defining_Identifier (Loc, Name_X),
7260 New_Reference_To (Typ, Loc)));
7262 if Present (Parameter_Specifications (Parent (E))) then
7263 P := First (Parameter_Specifications (Parent (E)));
7264 while Present (P) loop
7266 Make_Parameter_Specification (Loc,
7267 Defining_Identifier =>
7268 Make_Defining_Identifier (Loc,
7269 Chars (Defining_Identifier (P))),
7270 Parameter_Type => New_Copy_Tree (Parameter_Type (P))));
7276 Make_Subprogram_Declaration (Loc,
7277 Make_Procedure_Specification (Loc,
7278 Defining_Unit_Name => Init,
7279 Parameter_Specifications => Parms)));
7281 Set_Init_Proc (Typ, Init);
7282 Set_Is_Imported (Init);
7283 Set_Interface_Name (Init, Interface_Name (E));
7284 Set_Convention (Init, Convention_C);
7285 Set_Is_Public (Init);
7286 Set_Has_Completion (Init);
7292 -- If there are no constructors, mark the type as abstract since we
7293 -- won't be able to declare objects of that type.
7296 Set_Is_Abstract_Type (Typ);
7298 end Set_CPP_Constructors;
7300 --------------------------
7301 -- Set_DTC_Entity_Value --
7302 --------------------------
7304 procedure Set_DTC_Entity_Value
7305 (Tagged_Type : Entity_Id;
7309 if Present (Interface_Alias (Prim))
7310 and then Is_Interface
7311 (Find_Dispatching_Type (Interface_Alias (Prim)))
7313 Set_DTC_Entity (Prim,
7316 Iface => Find_Dispatching_Type (Interface_Alias (Prim))));
7318 Set_DTC_Entity (Prim,
7319 First_Tag_Component (Tagged_Type));
7321 end Set_DTC_Entity_Value;
7327 function Tagged_Kind (T : Entity_Id) return Node_Id is
7328 Conc_Typ : Entity_Id;
7329 Loc : constant Source_Ptr := Sloc (T);
7333 (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));
7337 if Is_Abstract_Type (T) then
7338 if Is_Limited_Record (T) then
7339 return New_Reference_To (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
7341 return New_Reference_To (RTE (RE_TK_Abstract_Tagged), Loc);
7346 elsif Is_Concurrent_Record_Type (T) then
7347 Conc_Typ := Corresponding_Concurrent_Type (T);
7349 if Present (Full_View (Conc_Typ)) then
7350 Conc_Typ := Full_View (Conc_Typ);
7353 if Ekind (Conc_Typ) = E_Protected_Type then
7354 return New_Reference_To (RTE (RE_TK_Protected), Loc);
7356 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
7357 return New_Reference_To (RTE (RE_TK_Task), Loc);
7360 -- Regular tagged kinds
7363 if Is_Limited_Record (T) then
7364 return New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc);
7366 return New_Reference_To (RTE (RE_TK_Tagged), Loc);
7375 procedure Write_DT (Typ : Entity_Id) is
7380 -- Protect this procedure against wrong usage. Required because it will
7381 -- be used directly from GDB
7383 if not (Typ <= Last_Node_Id)
7384 or else not Is_Tagged_Type (Typ)
7386 Write_Str ("wrong usage: Write_DT must be used with tagged types");
7391 Write_Int (Int (Typ));
7393 Write_Name (Chars (Typ));
7395 if Is_Interface (Typ) then
7396 Write_Str (" is interface");
7401 Elmt := First_Elmt (Primitive_Operations (Typ));
7402 while Present (Elmt) loop
7403 Prim := Node (Elmt);
7406 -- Indicate if this primitive will be allocated in the primary
7407 -- dispatch table or in a secondary dispatch table associated
7408 -- with an abstract interface type
7410 if Present (DTC_Entity (Prim)) then
7411 if Etype (DTC_Entity (Prim)) = RTE (RE_Tag) then
7418 -- Output the node of this primitive operation and its name
7420 Write_Int (Int (Prim));
7423 if Is_Predefined_Dispatching_Operation (Prim) then
7424 Write_Str ("(predefined) ");
7427 Write_Name (Chars (Prim));
7429 -- Indicate if this primitive has an aliased primitive
7431 if Present (Alias (Prim)) then
7432 Write_Str (" (alias = ");
7433 Write_Int (Int (Alias (Prim)));
7435 -- If the DTC_Entity attribute is already set we can also output
7436 -- the name of the interface covered by this primitive (if any)
7438 if Present (DTC_Entity (Alias (Prim)))
7439 and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
7441 Write_Str (" from interface ");
7442 Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
7445 if Present (Interface_Alias (Prim)) then
7446 Write_Str (", AI_Alias of ");
7448 (Chars (Find_Dispatching_Type (Interface_Alias (Prim))));
7450 Write_Int (Int (Interface_Alias (Prim)));
7456 -- Display the final position of this primitive in its associated
7457 -- (primary or secondary) dispatch table
7459 if Present (DTC_Entity (Prim))
7460 and then DT_Position (Prim) /= No_Uint
7462 Write_Str (" at #");
7463 Write_Int (UI_To_Int (DT_Position (Prim)));
7466 if Is_Abstract_Subprogram (Prim) then
7467 Write_Str (" is abstract;");
7469 -- Check if this is a null primitive
7471 elsif Comes_From_Source (Prim)
7472 and then Ekind (Prim) = E_Procedure
7473 and then Null_Present (Parent (Prim))
7475 Write_Str (" is null;");
7478 if Is_Eliminated (Ultimate_Alias (Prim)) then
7479 Write_Str (" (eliminated)");