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 -- Generate the SCIL node for this dispatching call. The SCIL node for a
647 -- dispatching call is inserted in the tree before the call is rewriten
648 -- and expanded because the SCIL node must be found by the SCIL backend
649 -- BEFORE the expanded nodes associated with the call node are found.
651 if Generate_SCIL then
652 Insert_Action (Call_Node,
654 (SN_Kind => Dispatching_Call,
655 Related_Node => Call_Node,
657 Target_Prim => Subp));
660 if not Is_Limited_Type (Typ) then
661 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
664 -- Dispatching call to C++ primitive. Create a new parameter list
665 -- with no tag checks.
667 New_Params := New_List;
669 if Is_CPP_Class (Typ) then
670 Param := First_Actual (Call_Node);
671 while Present (Param) loop
672 Append_To (New_Params, Relocate_Node (Param));
676 -- Dispatching call to Ada primitive
678 elsif Present (Param_List) then
679 Apply_Tag_Checks (Call_Node);
681 Param := First_Actual (Call_Node);
682 while Present (Param) loop
683 -- Cases in which we may have generated runtime checks
686 or else Subp = Eq_Prim_Op
688 Append_To (New_Params,
689 Duplicate_Subexpr_Move_Checks (Param));
692 Append_To (New_Params, Relocate_Node (Param));
699 -- Generate the appropriate subprogram pointer type
701 if Etype (Subp) = Typ then
704 Res_Typ := Etype (Subp);
707 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
708 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
709 Set_Etype (Subp_Typ, Res_Typ);
710 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
712 -- Create a new list of parameters which is a copy of the old formal
713 -- list including the creation of a new set of matching entities.
716 Old_Formal : Entity_Id := First_Formal (Subp);
717 New_Formal : Entity_Id;
718 Extra : Entity_Id := Empty;
721 if Present (Old_Formal) then
722 New_Formal := New_Copy (Old_Formal);
723 Set_First_Entity (Subp_Typ, New_Formal);
724 Param := First_Actual (Call_Node);
727 Set_Scope (New_Formal, Subp_Typ);
729 -- Change all the controlling argument types to be class-wide
730 -- to avoid a recursion in dispatching.
732 if Is_Controlling_Formal (New_Formal) then
733 Set_Etype (New_Formal, Etype (Param));
736 -- If the type of the formal is an itype, there was code here
737 -- introduced in 1998 in revision 1.46, to create a new itype
738 -- by copy. This seems useless, and in fact leads to semantic
739 -- errors when the itype is the completion of a type derived
740 -- from a private type.
743 Next_Formal (Old_Formal);
744 exit when No (Old_Formal);
746 Set_Next_Entity (New_Formal, New_Copy (Old_Formal));
747 Next_Entity (New_Formal);
751 Set_Next_Entity (New_Formal, Empty);
752 Set_Last_Entity (Subp_Typ, Extra);
755 -- Now that the explicit formals have been duplicated, any extra
756 -- formals needed by the subprogram must be created.
758 if Present (Extra) then
759 Set_Extra_Formal (Extra, Empty);
762 Create_Extra_Formals (Subp_Typ);
765 -- Complete description of pointer type, including size information, as
766 -- must be done with itypes to prevent order-of-elaboration anomalies
769 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
770 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
771 Set_Convention (Subp_Ptr_Typ, Convention (Subp_Typ));
772 Layout_Type (Subp_Ptr_Typ);
774 -- If the controlling argument is a value of type Ada.Tag or an abstract
775 -- interface class-wide type then use it directly. Otherwise, the tag
776 -- must be extracted from the controlling object.
778 if Ctrl_Typ = RTE (RE_Tag)
779 or else (RTE_Available (RE_Interface_Tag)
780 and then Ctrl_Typ = RTE (RE_Interface_Tag))
782 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
784 -- Extract the tag from an unchecked type conversion. Done to avoid
785 -- the expansion of additional code just to obtain the value of such
786 -- tag because the current management of interface type conversions
787 -- generates in some cases this unchecked type conversion with the
788 -- tag of the object (see Expand_Interface_Conversion).
790 elsif Nkind (Ctrl_Arg) = N_Unchecked_Type_Conversion
792 (Etype (Expression (Ctrl_Arg)) = RTE (RE_Tag)
794 (RTE_Available (RE_Interface_Tag)
796 Etype (Expression (Ctrl_Arg)) = RTE (RE_Interface_Tag)))
798 Controlling_Tag := Duplicate_Subexpr (Expression (Ctrl_Arg));
800 -- Ada 2005 (AI-251): Abstract interface class-wide type
802 elsif Is_Interface (Ctrl_Typ)
803 and then Is_Class_Wide_Type (Ctrl_Typ)
805 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
809 Make_Selected_Component (Loc,
810 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
811 Selector_Name => New_Reference_To (DTC_Entity (Subp), Loc));
814 -- Handle dispatching calls to predefined primitives
816 if Is_Predefined_Dispatching_Operation (Subp)
817 or else Is_Predefined_Dispatching_Alias (Subp)
820 Unchecked_Convert_To (Subp_Ptr_Typ,
821 Build_Get_Predefined_Prim_Op_Address (Loc,
822 Tag_Node => Controlling_Tag,
823 Position => DT_Position (Subp)));
825 -- Handle dispatching calls to user-defined primitives
829 Unchecked_Convert_To (Subp_Ptr_Typ,
830 Build_Get_Prim_Op_Address (Loc,
831 Typ => Find_Dispatching_Type (Subp),
832 Tag_Node => Controlling_Tag,
833 Position => DT_Position (Subp)));
836 if Nkind (Call_Node) = N_Function_Call then
839 Make_Function_Call (Loc,
840 Name => New_Call_Name,
841 Parameter_Associations => New_Params);
843 -- If this is a dispatching "=", we must first compare the tags so
844 -- we generate: x.tag = y.tag and then x = y
846 if Subp = Eq_Prim_Op then
847 Param := First_Actual (Call_Node);
853 Make_Selected_Component (Loc,
854 Prefix => New_Value (Param),
856 New_Reference_To (First_Tag_Component (Typ),
860 Make_Selected_Component (Loc,
862 Unchecked_Convert_To (Typ,
863 New_Value (Next_Actual (Param))),
865 New_Reference_To (First_Tag_Component (Typ),
867 Right_Opnd => New_Call);
872 Make_Procedure_Call_Statement (Loc,
873 Name => New_Call_Name,
874 Parameter_Associations => New_Params);
877 Rewrite (Call_Node, New_Call);
879 -- Suppress all checks during the analysis of the expanded code
880 -- to avoid the generation of spurious warnings under ZFP run-time.
882 Analyze_And_Resolve (Call_Node, Call_Typ, Suppress => All_Checks);
883 end Expand_Dispatching_Call;
885 ---------------------------------
886 -- Expand_Interface_Conversion --
887 ---------------------------------
889 procedure Expand_Interface_Conversion
891 Is_Static : Boolean := True)
893 Loc : constant Source_Ptr := Sloc (N);
894 Etyp : constant Entity_Id := Etype (N);
895 Operand : constant Node_Id := Expression (N);
896 Operand_Typ : Entity_Id := Etype (Operand);
898 Iface_Typ : Entity_Id := Etype (N);
899 Iface_Tag : Entity_Id;
902 -- Ada 2005 (AI-345): Handle synchronized interface type derivations
904 if Is_Concurrent_Type (Operand_Typ) then
905 Operand_Typ := Base_Type (Corresponding_Record_Type (Operand_Typ));
908 -- Handle access to class-wide interface types
910 if Is_Access_Type (Iface_Typ) then
911 Iface_Typ := Etype (Directly_Designated_Type (Iface_Typ));
914 -- Handle class-wide interface types. This conversion can appear
915 -- explicitly in the source code. Example: I'Class (Obj)
917 if Is_Class_Wide_Type (Iface_Typ) then
918 Iface_Typ := Root_Type (Iface_Typ);
921 -- If the target type is a tagged synchronized type, the dispatch table
922 -- info is in the corresponding record type.
924 if Is_Concurrent_Type (Iface_Typ) then
925 Iface_Typ := Corresponding_Record_Type (Iface_Typ);
928 -- Freeze the entity associated with the target interface to have
929 -- available the attribute Access_Disp_Table.
931 Freeze_Before (N, Iface_Typ);
933 pragma Assert (not Is_Static
934 or else (not Is_Class_Wide_Type (Iface_Typ)
935 and then Is_Interface (Iface_Typ)));
937 if not Tagged_Type_Expansion then
939 -- For VM, just do a conversion ???
941 Rewrite (N, Unchecked_Convert_To (Etype (N), N));
946 if not Is_Static then
948 -- Give error if configurable run time and Displace not available
950 if not RTE_Available (RE_Displace) then
951 Error_Msg_CRT ("dynamic interface conversion", N);
955 -- Handle conversion of access-to-class-wide interface types. Target
956 -- can be an access to an object or an access to another class-wide
957 -- interface (see -1- and -2- in the following example):
959 -- type Iface1_Ref is access all Iface1'Class;
960 -- type Iface2_Ref is access all Iface1'Class;
962 -- Acc1 : Iface1_Ref := new ...
963 -- Obj : Obj_Ref := Obj_Ref (Acc); -- 1
964 -- Acc2 : Iface2_Ref := Iface2_Ref (Acc); -- 2
966 if Is_Access_Type (Operand_Typ) then
968 Unchecked_Convert_To (Etype (N),
969 Make_Function_Call (Loc,
970 Name => New_Reference_To (RTE (RE_Displace), Loc),
971 Parameter_Associations => New_List (
973 Unchecked_Convert_To (RTE (RE_Address),
974 Relocate_Node (Expression (N))),
977 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
985 Make_Function_Call (Loc,
986 Name => New_Reference_To (RTE (RE_Displace), Loc),
987 Parameter_Associations => New_List (
988 Make_Attribute_Reference (Loc,
989 Prefix => Relocate_Node (Expression (N)),
990 Attribute_Name => Name_Address),
993 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
998 -- If the target is a class-wide interface we change the type of the
999 -- data returned by IW_Convert to indicate that this is a dispatching
1003 New_Itype : Entity_Id;
1006 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
1007 Set_Etype (New_Itype, New_Itype);
1008 Set_Directly_Designated_Type (New_Itype, Etyp);
1011 Make_Explicit_Dereference (Loc,
1013 Unchecked_Convert_To (New_Itype, Relocate_Node (N))));
1015 Freeze_Itype (New_Itype, N);
1021 Iface_Tag := Find_Interface_Tag (Operand_Typ, Iface_Typ);
1022 pragma Assert (Iface_Tag /= Empty);
1024 -- Keep separate access types to interfaces because one internal
1025 -- function is used to handle the null value (see following comment)
1027 if not Is_Access_Type (Etype (N)) then
1029 Unchecked_Convert_To (Etype (N),
1030 Make_Selected_Component (Loc,
1031 Prefix => Relocate_Node (Expression (N)),
1033 New_Occurrence_Of (Iface_Tag, Loc))));
1036 -- Build internal function to handle the case in which the
1037 -- actual is null. If the actual is null returns null because
1038 -- no displacement is required; otherwise performs a type
1039 -- conversion that will be expanded in the code that returns
1040 -- the value of the displaced actual. That is:
1042 -- function Func (O : Address) return Iface_Typ is
1043 -- type Op_Typ is access all Operand_Typ;
1044 -- Aux : Op_Typ := To_Op_Typ (O);
1046 -- if O = Null_Address then
1049 -- return Iface_Typ!(Aux.Iface_Tag'Address);
1054 Desig_Typ : Entity_Id;
1056 New_Typ_Decl : Node_Id;
1060 Desig_Typ := Etype (Expression (N));
1062 if Is_Access_Type (Desig_Typ) then
1064 Available_View (Directly_Designated_Type (Desig_Typ));
1067 if Is_Concurrent_Type (Desig_Typ) then
1068 Desig_Typ := Base_Type (Corresponding_Record_Type (Desig_Typ));
1072 Make_Full_Type_Declaration (Loc,
1073 Defining_Identifier =>
1074 Make_Defining_Identifier (Loc, New_Internal_Name ('T')),
1076 Make_Access_To_Object_Definition (Loc,
1077 All_Present => True,
1078 Null_Exclusion_Present => False,
1079 Constant_Present => False,
1080 Subtype_Indication =>
1081 New_Reference_To (Desig_Typ, Loc)));
1084 Make_Simple_Return_Statement (Loc,
1085 Unchecked_Convert_To (Etype (N),
1086 Make_Attribute_Reference (Loc,
1088 Make_Selected_Component (Loc,
1090 Unchecked_Convert_To
1091 (Defining_Identifier (New_Typ_Decl),
1092 Make_Identifier (Loc, Name_uO)),
1094 New_Occurrence_Of (Iface_Tag, Loc)),
1095 Attribute_Name => Name_Address))));
1097 -- If the type is null-excluding, no need for the null branch.
1098 -- Otherwise we need to check for it and return null.
1100 if not Can_Never_Be_Null (Etype (N)) then
1102 Make_If_Statement (Loc,
1105 Left_Opnd => Make_Identifier (Loc, Name_uO),
1106 Right_Opnd => New_Reference_To
1107 (RTE (RE_Null_Address), Loc)),
1109 Then_Statements => New_List (
1110 Make_Simple_Return_Statement (Loc,
1112 Else_Statements => Stats));
1116 Make_Defining_Identifier (Loc,
1117 New_Internal_Name ('F'));
1120 Make_Subprogram_Body (Loc,
1122 Make_Function_Specification (Loc,
1123 Defining_Unit_Name => Fent,
1125 Parameter_Specifications => New_List (
1126 Make_Parameter_Specification (Loc,
1127 Defining_Identifier =>
1128 Make_Defining_Identifier (Loc, Name_uO),
1130 New_Reference_To (RTE (RE_Address), Loc))),
1132 Result_Definition =>
1133 New_Reference_To (Etype (N), Loc)),
1135 Declarations => New_List (New_Typ_Decl),
1137 Handled_Statement_Sequence =>
1138 Make_Handled_Sequence_Of_Statements (Loc, Stats));
1140 -- Place function body before the expression containing the
1141 -- conversion. We suppress all checks because the body of the
1142 -- internally generated function already takes care of the case
1143 -- in which the actual is null; therefore there is no need to
1144 -- double check that the pointer is not null when the program
1145 -- executes the alternative that performs the type conversion).
1147 Insert_Action (N, Func, Suppress => All_Checks);
1149 if Is_Access_Type (Etype (Expression (N))) then
1151 -- Generate: Func (Address!(Expression))
1154 Make_Function_Call (Loc,
1155 Name => New_Reference_To (Fent, Loc),
1156 Parameter_Associations => New_List (
1157 Unchecked_Convert_To (RTE (RE_Address),
1158 Relocate_Node (Expression (N))))));
1161 -- Generate: Func (Operand_Typ!(Expression)'Address)
1164 Make_Function_Call (Loc,
1165 Name => New_Reference_To (Fent, Loc),
1166 Parameter_Associations => New_List (
1167 Make_Attribute_Reference (Loc,
1168 Prefix => Unchecked_Convert_To (Operand_Typ,
1169 Relocate_Node (Expression (N))),
1170 Attribute_Name => Name_Address))));
1176 end Expand_Interface_Conversion;
1178 ------------------------------
1179 -- Expand_Interface_Actuals --
1180 ------------------------------
1182 procedure Expand_Interface_Actuals (Call_Node : Node_Id) is
1184 Actual_Dup : Node_Id;
1185 Actual_Typ : Entity_Id;
1187 Conversion : Node_Id;
1189 Formal_Typ : Entity_Id;
1191 Formal_DDT : Entity_Id;
1192 Actual_DDT : Entity_Id;
1195 -- This subprogram is called directly from the semantics, so we need a
1196 -- check to see whether expansion is active before proceeding.
1198 if not Expander_Active then
1202 -- Call using access to subprogram with explicit dereference
1204 if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
1205 Subp := Etype (Name (Call_Node));
1207 -- Call using selected component
1209 elsif Nkind (Name (Call_Node)) = N_Selected_Component then
1210 Subp := Entity (Selector_Name (Name (Call_Node)));
1212 -- Call using direct name
1215 Subp := Entity (Name (Call_Node));
1218 -- Ada 2005 (AI-251): Look for interface type formals to force "this"
1221 Formal := First_Formal (Subp);
1222 Actual := First_Actual (Call_Node);
1223 while Present (Formal) loop
1224 Formal_Typ := Etype (Formal);
1226 if Ekind (Formal_Typ) = E_Record_Type_With_Private then
1227 Formal_Typ := Full_View (Formal_Typ);
1230 if Is_Access_Type (Formal_Typ) then
1231 Formal_DDT := Directly_Designated_Type (Formal_Typ);
1234 Actual_Typ := Etype (Actual);
1236 if Is_Access_Type (Actual_Typ) then
1237 Actual_DDT := Directly_Designated_Type (Actual_Typ);
1240 if Is_Interface (Formal_Typ)
1241 and then Is_Class_Wide_Type (Formal_Typ)
1243 -- No need to displace the pointer if the type of the actual
1244 -- coindices with the type of the formal.
1246 if Actual_Typ = Formal_Typ then
1249 -- No need to displace the pointer if the interface type is
1250 -- a parent of the type of the actual because in this case the
1251 -- interface primitives are located in the primary dispatch table.
1253 elsif Is_Ancestor (Formal_Typ, Actual_Typ) then
1256 -- Implicit conversion to the class-wide formal type to force
1257 -- the displacement of the pointer.
1260 Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
1261 Rewrite (Actual, Conversion);
1262 Analyze_And_Resolve (Actual, Formal_Typ);
1265 -- Access to class-wide interface type
1267 elsif Is_Access_Type (Formal_Typ)
1268 and then Is_Interface (Formal_DDT)
1269 and then Is_Class_Wide_Type (Formal_DDT)
1270 and then Interface_Present_In_Ancestor
1272 Iface => Etype (Formal_DDT))
1274 -- Handle attributes 'Access and 'Unchecked_Access
1276 if Nkind (Actual) = N_Attribute_Reference
1278 (Attribute_Name (Actual) = Name_Access
1279 or else Attribute_Name (Actual) = Name_Unchecked_Access)
1281 -- This case must have been handled by the analysis and
1282 -- expansion of 'Access. The only exception is when types
1283 -- match and no further expansion is required.
1285 pragma Assert (Base_Type (Etype (Prefix (Actual)))
1286 = Base_Type (Formal_DDT));
1289 -- No need to displace the pointer if the type of the actual
1290 -- coincides with the type of the formal.
1292 elsif Actual_DDT = Formal_DDT then
1295 -- No need to displace the pointer if the interface type is
1296 -- a parent of the type of the actual because in this case the
1297 -- interface primitives are located in the primary dispatch table.
1299 elsif Is_Ancestor (Formal_DDT, Actual_DDT) then
1303 Actual_Dup := Relocate_Node (Actual);
1305 if From_With_Type (Actual_Typ) then
1307 -- If the type of the actual parameter comes from a limited
1308 -- with-clause and the non-limited view is already available
1309 -- we replace the anonymous access type by a duplicate
1310 -- declaration whose designated type is the non-limited view
1312 if Ekind (Actual_DDT) = E_Incomplete_Type
1313 and then Present (Non_Limited_View (Actual_DDT))
1315 Anon := New_Copy (Actual_Typ);
1317 if Is_Itype (Anon) then
1318 Set_Scope (Anon, Current_Scope);
1321 Set_Directly_Designated_Type (Anon,
1322 Non_Limited_View (Actual_DDT));
1323 Set_Etype (Actual_Dup, Anon);
1325 elsif Is_Class_Wide_Type (Actual_DDT)
1326 and then Ekind (Etype (Actual_DDT)) = E_Incomplete_Type
1327 and then Present (Non_Limited_View (Etype (Actual_DDT)))
1329 Anon := New_Copy (Actual_Typ);
1331 if Is_Itype (Anon) then
1332 Set_Scope (Anon, Current_Scope);
1335 Set_Directly_Designated_Type (Anon,
1336 New_Copy (Actual_DDT));
1337 Set_Class_Wide_Type (Directly_Designated_Type (Anon),
1338 New_Copy (Class_Wide_Type (Actual_DDT)));
1339 Set_Etype (Directly_Designated_Type (Anon),
1340 Non_Limited_View (Etype (Actual_DDT)));
1342 Class_Wide_Type (Directly_Designated_Type (Anon)),
1343 Non_Limited_View (Etype (Actual_DDT)));
1344 Set_Etype (Actual_Dup, Anon);
1348 Conversion := Convert_To (Formal_Typ, Actual_Dup);
1349 Rewrite (Actual, Conversion);
1350 Analyze_And_Resolve (Actual, Formal_Typ);
1354 Next_Actual (Actual);
1355 Next_Formal (Formal);
1357 end Expand_Interface_Actuals;
1359 ----------------------------
1360 -- Expand_Interface_Thunk --
1361 ----------------------------
1363 procedure Expand_Interface_Thunk
1365 Thunk_Id : out Entity_Id;
1366 Thunk_Code : out Node_Id)
1368 Loc : constant Source_Ptr := Sloc (Prim);
1369 Actuals : constant List_Id := New_List;
1370 Decl : constant List_Id := New_List;
1371 Formals : constant List_Id := New_List;
1373 Controlling_Typ : Entity_Id;
1378 Offset_To_Top : Node_Id;
1380 Target_Formal : Entity_Id;
1384 Thunk_Code := Empty;
1386 -- Traverse the list of alias to find the final target
1389 while Present (Alias (Target)) loop
1390 Target := Alias (Target);
1393 -- In case of primitives that are functions without formals and
1394 -- a controlling result there is no need to build the thunk.
1396 if not Present (First_Formal (Target)) then
1397 pragma Assert (Ekind (Target) = E_Function
1398 and then Has_Controlling_Result (Target));
1402 -- Duplicate the formals
1404 Formal := First_Formal (Target);
1405 while Present (Formal) loop
1407 Make_Parameter_Specification (Loc,
1408 Defining_Identifier =>
1409 Make_Defining_Identifier (Sloc (Formal),
1410 Chars => Chars (Formal)),
1411 In_Present => In_Present (Parent (Formal)),
1412 Out_Present => Out_Present (Parent (Formal)),
1414 New_Reference_To (Etype (Formal), Loc),
1415 Expression => New_Copy_Tree (Expression (Parent (Formal)))));
1417 Next_Formal (Formal);
1420 Controlling_Typ := Find_Dispatching_Type (Target);
1422 Target_Formal := First_Formal (Target);
1423 Formal := First (Formals);
1424 while Present (Formal) loop
1425 if Ekind (Target_Formal) = E_In_Parameter
1426 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
1427 and then Directly_Designated_Type (Etype (Target_Formal))
1432 -- type T is access all <<type of the target formal>>
1433 -- S : Storage_Offset := Storage_Offset!(Formal)
1434 -- - Offset_To_Top (address!(Formal))
1437 Make_Full_Type_Declaration (Loc,
1438 Defining_Identifier =>
1439 Make_Defining_Identifier (Loc,
1440 New_Internal_Name ('T')),
1442 Make_Access_To_Object_Definition (Loc,
1443 All_Present => True,
1444 Null_Exclusion_Present => False,
1445 Constant_Present => False,
1446 Subtype_Indication =>
1448 (Directly_Designated_Type
1449 (Etype (Target_Formal)), Loc)));
1452 Unchecked_Convert_To (RTE (RE_Address),
1453 New_Reference_To (Defining_Identifier (Formal), Loc));
1455 if not RTE_Available (RE_Offset_To_Top) then
1457 Build_Offset_To_Top (Loc, New_Arg);
1460 Make_Function_Call (Loc,
1461 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1462 Parameter_Associations => New_List (New_Arg));
1466 Make_Object_Declaration (Loc,
1467 Defining_Identifier =>
1468 Make_Defining_Identifier (Loc,
1469 New_Internal_Name ('S')),
1470 Constant_Present => True,
1471 Object_Definition =>
1472 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1474 Make_Op_Subtract (Loc,
1476 Unchecked_Convert_To
1477 (RTE (RE_Storage_Offset),
1478 New_Reference_To (Defining_Identifier (Formal), Loc)),
1482 Append_To (Decl, Decl_2);
1483 Append_To (Decl, Decl_1);
1485 -- Reference the new actual. Generate:
1489 Unchecked_Convert_To
1490 (Defining_Identifier (Decl_2),
1491 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1493 elsif Etype (Target_Formal) = Controlling_Typ then
1496 -- S1 : Storage_Offset := Storage_Offset!(Formal'Address)
1497 -- - Offset_To_Top (Formal'Address)
1498 -- S2 : Addr_Ptr := Addr_Ptr!(S1)
1501 Make_Attribute_Reference (Loc,
1503 New_Reference_To (Defining_Identifier (Formal), Loc),
1507 if not RTE_Available (RE_Offset_To_Top) then
1509 Build_Offset_To_Top (Loc, New_Arg);
1512 Make_Function_Call (Loc,
1513 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1514 Parameter_Associations => New_List (New_Arg));
1518 Make_Object_Declaration (Loc,
1519 Defining_Identifier =>
1520 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1521 Constant_Present => True,
1522 Object_Definition =>
1523 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1525 Make_Op_Subtract (Loc,
1527 Unchecked_Convert_To
1528 (RTE (RE_Storage_Offset),
1529 Make_Attribute_Reference (Loc,
1532 (Defining_Identifier (Formal), Loc),
1533 Attribute_Name => Name_Address)),
1538 Make_Object_Declaration (Loc,
1539 Defining_Identifier =>
1540 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1541 Constant_Present => True,
1542 Object_Definition => New_Reference_To (RTE (RE_Addr_Ptr), Loc),
1544 Unchecked_Convert_To
1546 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1548 Append_To (Decl, Decl_1);
1549 Append_To (Decl, Decl_2);
1551 -- Reference the new actual. Generate:
1552 -- Target_Formal (S2.all)
1555 Unchecked_Convert_To
1556 (Etype (Target_Formal),
1557 Make_Explicit_Dereference (Loc,
1558 New_Reference_To (Defining_Identifier (Decl_2), Loc))));
1560 -- No special management required for this actual
1564 New_Reference_To (Defining_Identifier (Formal), Loc));
1567 Next_Formal (Target_Formal);
1572 Make_Defining_Identifier (Loc,
1573 Chars => New_Internal_Name ('T'));
1575 Set_Is_Thunk (Thunk_Id);
1577 if Ekind (Target) = E_Procedure then
1579 Make_Subprogram_Body (Loc,
1581 Make_Procedure_Specification (Loc,
1582 Defining_Unit_Name => Thunk_Id,
1583 Parameter_Specifications => Formals),
1584 Declarations => Decl,
1585 Handled_Statement_Sequence =>
1586 Make_Handled_Sequence_Of_Statements (Loc,
1587 Statements => New_List (
1588 Make_Procedure_Call_Statement (Loc,
1589 Name => New_Occurrence_Of (Target, Loc),
1590 Parameter_Associations => Actuals))));
1592 else pragma Assert (Ekind (Target) = E_Function);
1595 Make_Subprogram_Body (Loc,
1597 Make_Function_Specification (Loc,
1598 Defining_Unit_Name => Thunk_Id,
1599 Parameter_Specifications => Formals,
1600 Result_Definition =>
1601 New_Copy (Result_Definition (Parent (Target)))),
1602 Declarations => Decl,
1603 Handled_Statement_Sequence =>
1604 Make_Handled_Sequence_Of_Statements (Loc,
1605 Statements => New_List (
1606 Make_Simple_Return_Statement (Loc,
1607 Make_Function_Call (Loc,
1608 Name => New_Occurrence_Of (Target, Loc),
1609 Parameter_Associations => Actuals)))));
1611 end Expand_Interface_Thunk;
1613 ------------------------
1614 -- Get_SCIL_Node_Kind --
1615 ------------------------
1617 function Get_SCIL_Node_Kind (Node : Node_Id) return SCIL_Node_Kind is
1620 (Nkind (Node) = N_Null_Statement and then Is_SCIL_Node (Node));
1621 return SCIL_Node_Kind'Val (UI_To_Int (SCIL_Nkind (Node)));
1622 end Get_SCIL_Node_Kind;
1628 function Has_DT (Typ : Entity_Id) return Boolean is
1630 return not Is_Interface (Typ)
1631 and then not Restriction_Active (No_Dispatching_Calls);
1634 -----------------------------------------
1635 -- Is_Predefined_Dispatching_Operation --
1636 -----------------------------------------
1638 function Is_Predefined_Dispatching_Operation
1639 (E : Entity_Id) return Boolean
1641 TSS_Name : TSS_Name_Type;
1644 if not Is_Dispatching_Operation (E) then
1648 Get_Name_String (Chars (E));
1650 -- Most predefined primitives have internally generated names. Equality
1651 -- must be treated differently; the predefined operation is recognized
1652 -- as a homogeneous binary operator that returns Boolean.
1654 if Name_Len > TSS_Name_Type'Last then
1655 TSS_Name := TSS_Name_Type (Name_Buffer (Name_Len - TSS_Name'Length + 1
1657 if Chars (E) = Name_uSize
1658 or else Chars (E) = Name_uAlignment
1659 or else TSS_Name = TSS_Stream_Read
1660 or else TSS_Name = TSS_Stream_Write
1661 or else TSS_Name = TSS_Stream_Input
1662 or else TSS_Name = TSS_Stream_Output
1664 (Chars (E) = Name_Op_Eq
1665 and then Etype (First_Entity (E)) = Etype (Last_Entity (E)))
1666 or else Chars (E) = Name_uAssign
1667 or else TSS_Name = TSS_Deep_Adjust
1668 or else TSS_Name = TSS_Deep_Finalize
1669 or else Is_Predefined_Interface_Primitive (E)
1676 end Is_Predefined_Dispatching_Operation;
1678 -------------------------------------
1679 -- Is_Predefined_Dispatching_Alias --
1680 -------------------------------------
1682 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
1687 if not Is_Predefined_Dispatching_Operation (Prim)
1688 and then Present (Alias (Prim))
1691 while Present (Alias (E)) loop
1695 if Is_Predefined_Dispatching_Operation (E) then
1701 end Is_Predefined_Dispatching_Alias;
1703 ---------------------------------------
1704 -- Is_Predefined_Interface_Primitive --
1705 ---------------------------------------
1707 function Is_Predefined_Interface_Primitive (E : Entity_Id) return Boolean is
1709 return Ada_Version >= Ada_05
1710 and then (Chars (E) = Name_uDisp_Asynchronous_Select or else
1711 Chars (E) = Name_uDisp_Conditional_Select or else
1712 Chars (E) = Name_uDisp_Get_Prim_Op_Kind or else
1713 Chars (E) = Name_uDisp_Get_Task_Id or else
1714 Chars (E) = Name_uDisp_Requeue or else
1715 Chars (E) = Name_uDisp_Timed_Select);
1716 end Is_Predefined_Interface_Primitive;
1718 ----------------------------------------
1719 -- Make_Disp_Asynchronous_Select_Body --
1720 ----------------------------------------
1722 -- For interface types, generate:
1724 -- procedure _Disp_Asynchronous_Select
1725 -- (T : in out <Typ>;
1727 -- P : System.Address;
1728 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1733 -- end _Disp_Asynchronous_Select;
1735 -- For protected types, generate:
1737 -- procedure _Disp_Asynchronous_Select
1738 -- (T : in out <Typ>;
1740 -- P : System.Address;
1741 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1745 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1746 -- Bnn : System.Tasking.Protected_Objects.Operations.
1747 -- Communication_Block;
1749 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
1750 -- (T._object'Access,
1751 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
1753 -- System.Tasking.Asynchronous_Call,
1755 -- B := System.Storage_Elements.Dummy_Communication_Block (Bnn);
1756 -- end _Disp_Asynchronous_Select;
1758 -- For task types, generate:
1760 -- procedure _Disp_Asynchronous_Select
1761 -- (T : in out <Typ>;
1763 -- P : System.Address;
1764 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1768 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1770 -- System.Tasking.Rendezvous.Task_Entry_Call
1772 -- System.Tasking.Task_Entry_Index (I),
1774 -- System.Tasking.Asynchronous_Call,
1776 -- end _Disp_Asynchronous_Select;
1778 function Make_Disp_Asynchronous_Select_Body
1779 (Typ : Entity_Id) return Node_Id
1781 Com_Block : Entity_Id;
1782 Conc_Typ : Entity_Id := Empty;
1783 Decls : constant List_Id := New_List;
1785 Loc : constant Source_Ptr := Sloc (Typ);
1787 Stmts : constant List_Id := New_List;
1790 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1792 -- Null body is generated for interface types
1794 if Is_Interface (Typ) then
1796 Make_Subprogram_Body (Loc,
1798 Make_Disp_Asynchronous_Select_Spec (Typ),
1801 Handled_Statement_Sequence =>
1802 Make_Handled_Sequence_Of_Statements (Loc,
1803 New_List (Make_Null_Statement (Loc))));
1806 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1808 if Is_Concurrent_Record_Type (Typ) then
1809 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1813 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
1815 -- where I will be used to capture the entry index of the primitive
1816 -- wrapper at position S.
1819 Make_Object_Declaration (Loc,
1820 Defining_Identifier =>
1821 Make_Defining_Identifier (Loc, Name_uI),
1822 Object_Definition =>
1823 New_Reference_To (Standard_Integer, Loc),
1825 Make_Function_Call (Loc,
1827 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
1828 Parameter_Associations =>
1830 Unchecked_Convert_To (RTE (RE_Tag),
1831 New_Reference_To (DT_Ptr, Loc)),
1832 Make_Identifier (Loc, Name_uS)))));
1834 if Ekind (Conc_Typ) = E_Protected_Type then
1837 -- Bnn : Communication_Block;
1840 Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1843 Make_Object_Declaration (Loc,
1844 Defining_Identifier =>
1846 Object_Definition =>
1847 New_Reference_To (RTE (RE_Communication_Block), Loc)));
1849 -- Build T._object'Access for calls below
1852 Make_Attribute_Reference (Loc,
1853 Attribute_Name => Name_Unchecked_Access,
1855 Make_Selected_Component (Loc,
1856 Prefix => Make_Identifier (Loc, Name_uT),
1857 Selector_Name => Make_Identifier (Loc, Name_uObject)));
1859 case Corresponding_Runtime_Package (Conc_Typ) is
1860 when System_Tasking_Protected_Objects_Entries =>
1863 -- Protected_Entry_Call
1864 -- (T._object'Access, -- Object
1865 -- Protected_Entry_Index! (I), -- E
1866 -- P, -- Uninterpreted_Data
1867 -- Asynchronous_Call, -- Mode
1868 -- Bnn); -- Communication_Block
1870 -- where T is the protected object, I is the entry index, P
1871 -- is the wrapped parameters and B is the name of the
1872 -- communication block.
1875 Make_Procedure_Call_Statement (Loc,
1877 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1878 Parameter_Associations =>
1882 Make_Unchecked_Type_Conversion (Loc, -- entry index
1885 (RTE (RE_Protected_Entry_Index), Loc),
1886 Expression => Make_Identifier (Loc, Name_uI)),
1888 Make_Identifier (Loc, Name_uP), -- parameter block
1889 New_Reference_To ( -- Asynchronous_Call
1890 RTE (RE_Asynchronous_Call), Loc),
1892 New_Reference_To (Com_Block, Loc)))); -- comm block
1894 when System_Tasking_Protected_Objects_Single_Entry =>
1897 -- procedure Protected_Single_Entry_Call
1898 -- (Object : Protection_Entry_Access;
1899 -- Uninterpreted_Data : System.Address;
1900 -- Mode : Call_Modes);
1903 Make_Procedure_Call_Statement (Loc,
1906 (RTE (RE_Protected_Single_Entry_Call), Loc),
1907 Parameter_Associations =>
1911 Make_Attribute_Reference (Loc,
1912 Prefix => Make_Identifier (Loc, Name_uP),
1913 Attribute_Name => Name_Address),
1916 (RTE (RE_Asynchronous_Call), Loc))));
1919 raise Program_Error;
1923 -- B := Dummy_Communication_Block (Bnn);
1926 Make_Assignment_Statement (Loc,
1928 Make_Identifier (Loc, Name_uB),
1930 Make_Unchecked_Type_Conversion (Loc,
1933 RTE (RE_Dummy_Communication_Block), Loc),
1935 New_Reference_To (Com_Block, Loc))));
1938 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
1942 -- (T._task_id, -- Acceptor
1943 -- Task_Entry_Index! (I), -- E
1944 -- P, -- Uninterpreted_Data
1945 -- Asynchronous_Call, -- Mode
1946 -- F); -- Rendezvous_Successful
1948 -- where T is the task object, I is the entry index, P is the
1949 -- wrapped parameters and F is the status flag.
1952 Make_Procedure_Call_Statement (Loc,
1954 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
1955 Parameter_Associations =>
1957 Make_Selected_Component (Loc, -- T._task_id
1959 Make_Identifier (Loc, Name_uT),
1961 Make_Identifier (Loc, Name_uTask_Id)),
1963 Make_Unchecked_Type_Conversion (Loc, -- entry index
1965 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
1967 Make_Identifier (Loc, Name_uI)),
1969 Make_Identifier (Loc, Name_uP), -- parameter block
1970 New_Reference_To ( -- Asynchronous_Call
1971 RTE (RE_Asynchronous_Call), Loc),
1972 Make_Identifier (Loc, Name_uF)))); -- status flag
1976 -- Ensure that the statements list is non-empty
1978 Append_To (Stmts, Make_Null_Statement (Loc));
1982 Make_Subprogram_Body (Loc,
1984 Make_Disp_Asynchronous_Select_Spec (Typ),
1987 Handled_Statement_Sequence =>
1988 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
1989 end Make_Disp_Asynchronous_Select_Body;
1991 ----------------------------------------
1992 -- Make_Disp_Asynchronous_Select_Spec --
1993 ----------------------------------------
1995 function Make_Disp_Asynchronous_Select_Spec
1996 (Typ : Entity_Id) return Node_Id
1998 Loc : constant Source_Ptr := Sloc (Typ);
1999 Def_Id : constant Node_Id :=
2000 Make_Defining_Identifier (Loc,
2001 Name_uDisp_Asynchronous_Select);
2002 Params : constant List_Id := New_List;
2005 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2007 -- T : in out Typ; -- Object parameter
2008 -- S : Integer; -- Primitive operation slot
2009 -- P : Address; -- Wrapped parameters
2010 -- B : out Dummy_Communication_Block; -- Communication block dummy
2011 -- F : out Boolean; -- Status flag
2013 Append_List_To (Params, New_List (
2015 Make_Parameter_Specification (Loc,
2016 Defining_Identifier =>
2017 Make_Defining_Identifier (Loc, Name_uT),
2019 New_Reference_To (Typ, Loc),
2021 Out_Present => True),
2023 Make_Parameter_Specification (Loc,
2024 Defining_Identifier =>
2025 Make_Defining_Identifier (Loc, Name_uS),
2027 New_Reference_To (Standard_Integer, Loc)),
2029 Make_Parameter_Specification (Loc,
2030 Defining_Identifier =>
2031 Make_Defining_Identifier (Loc, Name_uP),
2033 New_Reference_To (RTE (RE_Address), Loc)),
2035 Make_Parameter_Specification (Loc,
2036 Defining_Identifier =>
2037 Make_Defining_Identifier (Loc, Name_uB),
2039 New_Reference_To (RTE (RE_Dummy_Communication_Block), Loc),
2040 Out_Present => True),
2042 Make_Parameter_Specification (Loc,
2043 Defining_Identifier =>
2044 Make_Defining_Identifier (Loc, Name_uF),
2046 New_Reference_To (Standard_Boolean, Loc),
2047 Out_Present => True)));
2050 Make_Procedure_Specification (Loc,
2051 Defining_Unit_Name => Def_Id,
2052 Parameter_Specifications => Params);
2053 end Make_Disp_Asynchronous_Select_Spec;
2055 ---------------------------------------
2056 -- Make_Disp_Conditional_Select_Body --
2057 ---------------------------------------
2059 -- For interface types, generate:
2061 -- procedure _Disp_Conditional_Select
2062 -- (T : in out <Typ>;
2064 -- P : System.Address;
2065 -- C : out Ada.Tags.Prim_Op_Kind;
2070 -- end _Disp_Conditional_Select;
2072 -- For protected types, generate:
2074 -- procedure _Disp_Conditional_Select
2075 -- (T : in out <Typ>;
2077 -- P : System.Address;
2078 -- C : out Ada.Tags.Prim_Op_Kind;
2082 -- Bnn : System.Tasking.Protected_Objects.Operations.
2083 -- Communication_Block;
2086 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP, S));
2088 -- if C = Ada.Tags.POK_Procedure
2089 -- or else C = Ada.Tags.POK_Protected_Procedure
2090 -- or else C = Ada.Tags.POK_Task_Procedure
2096 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2097 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
2098 -- (T.object'Access,
2099 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
2101 -- System.Tasking.Conditional_Call,
2103 -- F := not Cancelled (Bnn);
2104 -- end _Disp_Conditional_Select;
2106 -- For task types, generate:
2108 -- procedure _Disp_Conditional_Select
2109 -- (T : in out <Typ>;
2111 -- P : System.Address;
2112 -- C : out Ada.Tags.Prim_Op_Kind;
2118 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2119 -- System.Tasking.Rendezvous.Task_Entry_Call
2121 -- System.Tasking.Task_Entry_Index (I),
2123 -- System.Tasking.Conditional_Call,
2125 -- end _Disp_Conditional_Select;
2127 function Make_Disp_Conditional_Select_Body
2128 (Typ : Entity_Id) return Node_Id
2130 Loc : constant Source_Ptr := Sloc (Typ);
2131 Blk_Nam : Entity_Id;
2132 Conc_Typ : Entity_Id := Empty;
2133 Decls : constant List_Id := New_List;
2136 Stmts : constant List_Id := New_List;
2139 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2141 -- Null body is generated for interface types
2143 if Is_Interface (Typ) then
2145 Make_Subprogram_Body (Loc,
2147 Make_Disp_Conditional_Select_Spec (Typ),
2150 Handled_Statement_Sequence =>
2151 Make_Handled_Sequence_Of_Statements (Loc,
2152 New_List (Make_Null_Statement (Loc))));
2155 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2157 if Is_Concurrent_Record_Type (Typ) then
2158 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2163 -- where I will be used to capture the entry index of the primitive
2164 -- wrapper at position S.
2167 Make_Object_Declaration (Loc,
2168 Defining_Identifier =>
2169 Make_Defining_Identifier (Loc, Name_uI),
2170 Object_Definition =>
2171 New_Reference_To (Standard_Integer, Loc)));
2174 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag! (<type>VP), S);
2176 -- if C = POK_Procedure
2177 -- or else C = POK_Protected_Procedure
2178 -- or else C = POK_Task_Procedure;
2184 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
2187 -- Bnn : Communication_Block;
2189 -- where Bnn is the name of the communication block used in the
2190 -- call to Protected_Entry_Call.
2192 Blk_Nam := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
2195 Make_Object_Declaration (Loc,
2196 Defining_Identifier =>
2198 Object_Definition =>
2199 New_Reference_To (RTE (RE_Communication_Block), Loc)));
2202 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
2204 -- I is the entry index and S is the dispatch table slot
2207 Make_Assignment_Statement (Loc,
2209 Make_Identifier (Loc, Name_uI),
2211 Make_Function_Call (Loc,
2213 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
2214 Parameter_Associations =>
2216 Unchecked_Convert_To (RTE (RE_Tag),
2217 New_Reference_To (DT_Ptr, Loc)),
2218 Make_Identifier (Loc, Name_uS)))));
2220 if Ekind (Conc_Typ) = E_Protected_Type then
2222 Obj_Ref := -- T._object'Access
2223 Make_Attribute_Reference (Loc,
2224 Attribute_Name => Name_Unchecked_Access,
2226 Make_Selected_Component (Loc,
2227 Prefix => Make_Identifier (Loc, Name_uT),
2228 Selector_Name => Make_Identifier (Loc, Name_uObject)));
2230 case Corresponding_Runtime_Package (Conc_Typ) is
2231 when System_Tasking_Protected_Objects_Entries =>
2234 -- Protected_Entry_Call
2235 -- (T._object'Access, -- Object
2236 -- Protected_Entry_Index! (I), -- E
2237 -- P, -- Uninterpreted_Data
2238 -- Conditional_Call, -- Mode
2241 -- where T is the protected object, I is the entry index, P
2242 -- are the wrapped parameters and Bnn is the name of the
2243 -- communication block.
2246 Make_Procedure_Call_Statement (Loc,
2248 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
2249 Parameter_Associations =>
2253 Make_Unchecked_Type_Conversion (Loc, -- entry index
2256 (RTE (RE_Protected_Entry_Index), Loc),
2257 Expression => Make_Identifier (Loc, Name_uI)),
2259 Make_Identifier (Loc, Name_uP), -- parameter block
2261 New_Reference_To ( -- Conditional_Call
2262 RTE (RE_Conditional_Call), Loc),
2263 New_Reference_To ( -- Bnn
2266 when System_Tasking_Protected_Objects_Single_Entry =>
2268 -- If we are compiling for a restricted run-time, the call
2269 -- uses the simpler form.
2272 Make_Procedure_Call_Statement (Loc,
2275 (RTE (RE_Protected_Single_Entry_Call), Loc),
2276 Parameter_Associations =>
2280 Make_Attribute_Reference (Loc,
2281 Prefix => Make_Identifier (Loc, Name_uP),
2282 Attribute_Name => Name_Address),
2285 (RTE (RE_Conditional_Call), Loc))));
2287 raise Program_Error;
2291 -- F := not Cancelled (Bnn);
2293 -- where F is the success flag. The status of Cancelled is negated
2294 -- in order to match the behaviour of the version for task types.
2297 Make_Assignment_Statement (Loc,
2299 Make_Identifier (Loc, Name_uF),
2303 Make_Function_Call (Loc,
2305 New_Reference_To (RTE (RE_Cancelled), Loc),
2306 Parameter_Associations =>
2308 New_Reference_To (Blk_Nam, Loc))))));
2310 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2314 -- (T._task_id, -- Acceptor
2315 -- Task_Entry_Index! (I), -- E
2316 -- P, -- Uninterpreted_Data
2317 -- Conditional_Call, -- Mode
2318 -- F); -- Rendezvous_Successful
2320 -- where T is the task object, I is the entry index, P are the
2321 -- wrapped parameters and F is the status flag.
2324 Make_Procedure_Call_Statement (Loc,
2326 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
2327 Parameter_Associations =>
2330 Make_Selected_Component (Loc, -- T._task_id
2332 Make_Identifier (Loc, Name_uT),
2334 Make_Identifier (Loc, Name_uTask_Id)),
2336 Make_Unchecked_Type_Conversion (Loc, -- entry index
2338 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2340 Make_Identifier (Loc, Name_uI)),
2342 Make_Identifier (Loc, Name_uP), -- parameter block
2343 New_Reference_To ( -- Conditional_Call
2344 RTE (RE_Conditional_Call), Loc),
2345 Make_Identifier (Loc, Name_uF)))); -- status flag
2349 -- Ensure that the statements list is non-empty
2351 Append_To (Stmts, Make_Null_Statement (Loc));
2355 Make_Subprogram_Body (Loc,
2357 Make_Disp_Conditional_Select_Spec (Typ),
2360 Handled_Statement_Sequence =>
2361 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2362 end Make_Disp_Conditional_Select_Body;
2364 ---------------------------------------
2365 -- Make_Disp_Conditional_Select_Spec --
2366 ---------------------------------------
2368 function Make_Disp_Conditional_Select_Spec
2369 (Typ : Entity_Id) return Node_Id
2371 Loc : constant Source_Ptr := Sloc (Typ);
2372 Def_Id : constant Node_Id :=
2373 Make_Defining_Identifier (Loc,
2374 Name_uDisp_Conditional_Select);
2375 Params : constant List_Id := New_List;
2378 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2380 -- T : in out Typ; -- Object parameter
2381 -- S : Integer; -- Primitive operation slot
2382 -- P : Address; -- Wrapped parameters
2383 -- C : out Prim_Op_Kind; -- Call kind
2384 -- F : out Boolean; -- Status flag
2386 Append_List_To (Params, New_List (
2388 Make_Parameter_Specification (Loc,
2389 Defining_Identifier =>
2390 Make_Defining_Identifier (Loc, Name_uT),
2392 New_Reference_To (Typ, Loc),
2394 Out_Present => True),
2396 Make_Parameter_Specification (Loc,
2397 Defining_Identifier =>
2398 Make_Defining_Identifier (Loc, Name_uS),
2400 New_Reference_To (Standard_Integer, Loc)),
2402 Make_Parameter_Specification (Loc,
2403 Defining_Identifier =>
2404 Make_Defining_Identifier (Loc, Name_uP),
2406 New_Reference_To (RTE (RE_Address), Loc)),
2408 Make_Parameter_Specification (Loc,
2409 Defining_Identifier =>
2410 Make_Defining_Identifier (Loc, Name_uC),
2412 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2413 Out_Present => True),
2415 Make_Parameter_Specification (Loc,
2416 Defining_Identifier =>
2417 Make_Defining_Identifier (Loc, Name_uF),
2419 New_Reference_To (Standard_Boolean, Loc),
2420 Out_Present => True)));
2423 Make_Procedure_Specification (Loc,
2424 Defining_Unit_Name => Def_Id,
2425 Parameter_Specifications => Params);
2426 end Make_Disp_Conditional_Select_Spec;
2428 -------------------------------------
2429 -- Make_Disp_Get_Prim_Op_Kind_Body --
2430 -------------------------------------
2432 function Make_Disp_Get_Prim_Op_Kind_Body
2433 (Typ : Entity_Id) return Node_Id
2435 Loc : constant Source_Ptr := Sloc (Typ);
2439 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2441 if Is_Interface (Typ) then
2443 Make_Subprogram_Body (Loc,
2445 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2448 Handled_Statement_Sequence =>
2449 Make_Handled_Sequence_Of_Statements (Loc,
2450 New_List (Make_Null_Statement (Loc))));
2453 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2456 -- C := get_prim_op_kind (tag! (<type>VP), S);
2458 -- where C is the out parameter capturing the call kind and S is the
2459 -- dispatch table slot number.
2462 Make_Subprogram_Body (Loc,
2464 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2467 Handled_Statement_Sequence =>
2468 Make_Handled_Sequence_Of_Statements (Loc,
2470 Make_Assignment_Statement (Loc,
2472 Make_Identifier (Loc, Name_uC),
2474 Make_Function_Call (Loc,
2476 New_Reference_To (RTE (RE_Get_Prim_Op_Kind), Loc),
2477 Parameter_Associations => New_List (
2478 Unchecked_Convert_To (RTE (RE_Tag),
2479 New_Reference_To (DT_Ptr, Loc)),
2480 Make_Identifier (Loc, Name_uS)))))));
2481 end Make_Disp_Get_Prim_Op_Kind_Body;
2483 -------------------------------------
2484 -- Make_Disp_Get_Prim_Op_Kind_Spec --
2485 -------------------------------------
2487 function Make_Disp_Get_Prim_Op_Kind_Spec
2488 (Typ : Entity_Id) return Node_Id
2490 Loc : constant Source_Ptr := Sloc (Typ);
2491 Def_Id : constant Node_Id :=
2492 Make_Defining_Identifier (Loc,
2493 Name_uDisp_Get_Prim_Op_Kind);
2494 Params : constant List_Id := New_List;
2497 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2499 -- T : in out Typ; -- Object parameter
2500 -- S : Integer; -- Primitive operation slot
2501 -- C : out Prim_Op_Kind; -- Call kind
2503 Append_List_To (Params, New_List (
2505 Make_Parameter_Specification (Loc,
2506 Defining_Identifier =>
2507 Make_Defining_Identifier (Loc, Name_uT),
2509 New_Reference_To (Typ, Loc),
2511 Out_Present => True),
2513 Make_Parameter_Specification (Loc,
2514 Defining_Identifier =>
2515 Make_Defining_Identifier (Loc, Name_uS),
2517 New_Reference_To (Standard_Integer, Loc)),
2519 Make_Parameter_Specification (Loc,
2520 Defining_Identifier =>
2521 Make_Defining_Identifier (Loc, Name_uC),
2523 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2524 Out_Present => True)));
2527 Make_Procedure_Specification (Loc,
2528 Defining_Unit_Name => Def_Id,
2529 Parameter_Specifications => Params);
2530 end Make_Disp_Get_Prim_Op_Kind_Spec;
2532 --------------------------------
2533 -- Make_Disp_Get_Task_Id_Body --
2534 --------------------------------
2536 function Make_Disp_Get_Task_Id_Body
2537 (Typ : Entity_Id) return Node_Id
2539 Loc : constant Source_Ptr := Sloc (Typ);
2543 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2545 if Is_Concurrent_Record_Type (Typ)
2546 and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
2549 -- return To_Address (_T._task_id);
2552 Make_Simple_Return_Statement (Loc,
2554 Make_Unchecked_Type_Conversion (Loc,
2556 New_Reference_To (RTE (RE_Address), Loc),
2558 Make_Selected_Component (Loc,
2560 Make_Identifier (Loc, Name_uT),
2562 Make_Identifier (Loc, Name_uTask_Id))));
2564 -- A null body is constructed for non-task types
2568 -- return Null_Address;
2571 Make_Simple_Return_Statement (Loc,
2573 New_Reference_To (RTE (RE_Null_Address), Loc));
2577 Make_Subprogram_Body (Loc,
2579 Make_Disp_Get_Task_Id_Spec (Typ),
2582 Handled_Statement_Sequence =>
2583 Make_Handled_Sequence_Of_Statements (Loc,
2585 end Make_Disp_Get_Task_Id_Body;
2587 --------------------------------
2588 -- Make_Disp_Get_Task_Id_Spec --
2589 --------------------------------
2591 function Make_Disp_Get_Task_Id_Spec
2592 (Typ : Entity_Id) return Node_Id
2594 Loc : constant Source_Ptr := Sloc (Typ);
2597 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2600 Make_Function_Specification (Loc,
2601 Defining_Unit_Name =>
2602 Make_Defining_Identifier (Loc, Name_uDisp_Get_Task_Id),
2603 Parameter_Specifications => New_List (
2604 Make_Parameter_Specification (Loc,
2605 Defining_Identifier =>
2606 Make_Defining_Identifier (Loc, Name_uT),
2608 New_Reference_To (Typ, Loc))),
2609 Result_Definition =>
2610 New_Reference_To (RTE (RE_Address), Loc));
2611 end Make_Disp_Get_Task_Id_Spec;
2613 ----------------------------
2614 -- Make_Disp_Requeue_Body --
2615 ----------------------------
2617 function Make_Disp_Requeue_Body
2618 (Typ : Entity_Id) return Node_Id
2620 Loc : constant Source_Ptr := Sloc (Typ);
2621 Conc_Typ : Entity_Id := Empty;
2622 Stmts : constant List_Id := New_List;
2625 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2627 -- Null body is generated for interface types and non-concurrent
2630 if Is_Interface (Typ)
2631 or else not Is_Concurrent_Record_Type (Typ)
2634 Make_Subprogram_Body (Loc,
2636 Make_Disp_Requeue_Spec (Typ),
2639 Handled_Statement_Sequence =>
2640 Make_Handled_Sequence_Of_Statements (Loc,
2641 New_List (Make_Null_Statement (Loc))));
2644 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2646 if Ekind (Conc_Typ) = E_Protected_Type then
2648 -- Generate statements:
2650 -- System.Tasking.Protected_Objects.Operations.
2651 -- Requeue_Protected_Entry
2652 -- (Protection_Entries_Access (P),
2653 -- O._object'Unchecked_Access,
2654 -- Protected_Entry_Index (I),
2657 -- System.Tasking.Protected_Objects.Operations.
2658 -- Requeue_Task_To_Protected_Entry
2659 -- (O._object'Unchecked_Access,
2660 -- Protected_Entry_Index (I),
2664 if Restriction_Active (No_Entry_Queue) then
2665 Append_To (Stmts, Make_Null_Statement (Loc));
2668 Make_If_Statement (Loc,
2670 Make_Identifier (Loc, Name_uF),
2675 -- Call to Requeue_Protected_Entry
2677 Make_Procedure_Call_Statement (Loc,
2680 RTE (RE_Requeue_Protected_Entry), Loc),
2681 Parameter_Associations =>
2684 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
2687 RTE (RE_Protection_Entries_Access), Loc),
2689 Make_Identifier (Loc, Name_uP)),
2691 Make_Attribute_Reference (Loc, -- O._object'Acc
2693 Name_Unchecked_Access,
2695 Make_Selected_Component (Loc,
2697 Make_Identifier (Loc, Name_uO),
2699 Make_Identifier (Loc, Name_uObject))),
2701 Make_Unchecked_Type_Conversion (Loc, -- entry index
2704 RTE (RE_Protected_Entry_Index), Loc),
2706 Make_Identifier (Loc, Name_uI)),
2708 Make_Identifier (Loc, Name_uA)))), -- abort status
2713 -- Call to Requeue_Task_To_Protected_Entry
2715 Make_Procedure_Call_Statement (Loc,
2718 RTE (RE_Requeue_Task_To_Protected_Entry), Loc),
2719 Parameter_Associations =>
2722 Make_Attribute_Reference (Loc, -- O._object'Acc
2724 Name_Unchecked_Access,
2726 Make_Selected_Component (Loc,
2728 Make_Identifier (Loc, Name_uO),
2730 Make_Identifier (Loc, Name_uObject))),
2732 Make_Unchecked_Type_Conversion (Loc, -- entry index
2735 RTE (RE_Protected_Entry_Index), Loc),
2737 Make_Identifier (Loc, Name_uI)),
2739 Make_Identifier (Loc, Name_uA)))))); -- abort status
2742 pragma Assert (Is_Task_Type (Conc_Typ));
2746 -- System.Tasking.Rendezvous.Requeue_Protected_To_Task_Entry
2747 -- (Protection_Entries_Access (P),
2749 -- Task_Entry_Index (I),
2752 -- System.Tasking.Rendezvous.Requeue_Task_Entry
2754 -- Task_Entry_Index (I),
2759 Make_If_Statement (Loc,
2761 Make_Identifier (Loc, Name_uF),
2766 -- Call to Requeue_Protected_To_Task_Entry
2768 Make_Procedure_Call_Statement (Loc,
2771 RTE (RE_Requeue_Protected_To_Task_Entry), Loc),
2773 Parameter_Associations =>
2776 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
2779 RTE (RE_Protection_Entries_Access), Loc),
2781 Make_Identifier (Loc, Name_uP)),
2783 Make_Selected_Component (Loc, -- O._task_id
2785 Make_Identifier (Loc, Name_uO),
2787 Make_Identifier (Loc, Name_uTask_Id)),
2789 Make_Unchecked_Type_Conversion (Loc, -- entry index
2792 RTE (RE_Task_Entry_Index), Loc),
2794 Make_Identifier (Loc, Name_uI)),
2796 Make_Identifier (Loc, Name_uA)))), -- abort status
2801 -- Call to Requeue_Task_Entry
2803 Make_Procedure_Call_Statement (Loc,
2805 New_Reference_To (RTE (RE_Requeue_Task_Entry), Loc),
2807 Parameter_Associations =>
2810 Make_Selected_Component (Loc, -- O._task_id
2812 Make_Identifier (Loc, Name_uO),
2814 Make_Identifier (Loc, Name_uTask_Id)),
2816 Make_Unchecked_Type_Conversion (Loc, -- entry index
2819 RTE (RE_Task_Entry_Index), Loc),
2821 Make_Identifier (Loc, Name_uI)),
2823 Make_Identifier (Loc, Name_uA)))))); -- abort status
2826 -- Even though no declarations are needed in both cases, we allocate
2827 -- a list for entities added by Freeze.
2830 Make_Subprogram_Body (Loc,
2832 Make_Disp_Requeue_Spec (Typ),
2835 Handled_Statement_Sequence =>
2836 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2837 end Make_Disp_Requeue_Body;
2839 ----------------------------
2840 -- Make_Disp_Requeue_Spec --
2841 ----------------------------
2843 function Make_Disp_Requeue_Spec
2844 (Typ : Entity_Id) return Node_Id
2846 Loc : constant Source_Ptr := Sloc (Typ);
2849 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2851 -- O : in out Typ; - Object parameter
2852 -- F : Boolean; - Protected (True) / task (False) flag
2853 -- P : Address; - Protection_Entries_Access value
2854 -- I : Entry_Index - Index of entry call
2855 -- A : Boolean - Abort flag
2857 -- Note that the Protection_Entries_Access value is represented as a
2858 -- System.Address in order to avoid dragging in the tasking runtime
2859 -- when compiling sources without tasking constructs.
2862 Make_Procedure_Specification (Loc,
2863 Defining_Unit_Name =>
2864 Make_Defining_Identifier (Loc, Name_uDisp_Requeue),
2866 Parameter_Specifications =>
2869 Make_Parameter_Specification (Loc, -- O
2870 Defining_Identifier =>
2871 Make_Defining_Identifier (Loc, Name_uO),
2873 New_Reference_To (Typ, Loc),
2875 Out_Present => True),
2877 Make_Parameter_Specification (Loc, -- F
2878 Defining_Identifier =>
2879 Make_Defining_Identifier (Loc, Name_uF),
2881 New_Reference_To (Standard_Boolean, Loc)),
2883 Make_Parameter_Specification (Loc, -- P
2884 Defining_Identifier =>
2885 Make_Defining_Identifier (Loc, Name_uP),
2887 New_Reference_To (RTE (RE_Address), Loc)),
2889 Make_Parameter_Specification (Loc, -- I
2890 Defining_Identifier =>
2891 Make_Defining_Identifier (Loc, Name_uI),
2893 New_Reference_To (Standard_Integer, Loc)),
2895 Make_Parameter_Specification (Loc, -- A
2896 Defining_Identifier =>
2897 Make_Defining_Identifier (Loc, Name_uA),
2899 New_Reference_To (Standard_Boolean, Loc))));
2900 end Make_Disp_Requeue_Spec;
2902 ---------------------------------
2903 -- Make_Disp_Timed_Select_Body --
2904 ---------------------------------
2906 -- For interface types, generate:
2908 -- procedure _Disp_Timed_Select
2909 -- (T : in out <Typ>;
2911 -- P : System.Address;
2914 -- C : out Ada.Tags.Prim_Op_Kind;
2919 -- end _Disp_Timed_Select;
2921 -- For protected types, generate:
2923 -- procedure _Disp_Timed_Select
2924 -- (T : in out <Typ>;
2926 -- P : System.Address;
2929 -- C : out Ada.Tags.Prim_Op_Kind;
2935 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP), S);
2937 -- if C = Ada.Tags.POK_Procedure
2938 -- or else C = Ada.Tags.POK_Protected_Procedure
2939 -- or else C = Ada.Tags.POK_Task_Procedure
2945 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
2946 -- System.Tasking.Protected_Objects.Operations.
2947 -- Timed_Protected_Entry_Call
2948 -- (T._object'Access,
2949 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
2954 -- end _Disp_Timed_Select;
2956 -- For task types, generate:
2958 -- procedure _Disp_Timed_Select
2959 -- (T : in out <Typ>;
2961 -- P : System.Address;
2964 -- C : out Ada.Tags.Prim_Op_Kind;
2970 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
2971 -- System.Tasking.Rendezvous.Timed_Task_Entry_Call
2973 -- System.Tasking.Task_Entry_Index (I),
2978 -- end _Disp_Time_Select;
2980 function Make_Disp_Timed_Select_Body
2981 (Typ : Entity_Id) return Node_Id
2983 Loc : constant Source_Ptr := Sloc (Typ);
2984 Conc_Typ : Entity_Id := Empty;
2985 Decls : constant List_Id := New_List;
2988 Stmts : constant List_Id := New_List;
2991 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2993 -- Null body is generated for interface types
2995 if Is_Interface (Typ) then
2997 Make_Subprogram_Body (Loc,
2999 Make_Disp_Timed_Select_Spec (Typ),
3002 Handled_Statement_Sequence =>
3003 Make_Handled_Sequence_Of_Statements (Loc,
3004 New_List (Make_Null_Statement (Loc))));
3007 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
3009 if Is_Concurrent_Record_Type (Typ) then
3010 Conc_Typ := Corresponding_Concurrent_Type (Typ);
3015 -- where I will be used to capture the entry index of the primitive
3016 -- wrapper at position S.
3019 Make_Object_Declaration (Loc,
3020 Defining_Identifier =>
3021 Make_Defining_Identifier (Loc, Name_uI),
3022 Object_Definition =>
3023 New_Reference_To (Standard_Integer, Loc)));
3026 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
3028 -- if C = POK_Procedure
3029 -- or else C = POK_Protected_Procedure
3030 -- or else C = POK_Task_Procedure;
3036 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
3039 -- I := Get_Entry_Index (tag! (<type>VP), S);
3041 -- I is the entry index and S is the dispatch table slot
3044 Make_Assignment_Statement (Loc,
3046 Make_Identifier (Loc, Name_uI),
3048 Make_Function_Call (Loc,
3050 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
3051 Parameter_Associations =>
3053 Unchecked_Convert_To (RTE (RE_Tag),
3054 New_Reference_To (DT_Ptr, Loc)),
3055 Make_Identifier (Loc, Name_uS)))));
3059 if Ekind (Conc_Typ) = E_Protected_Type then
3061 -- Build T._object'Access
3064 Make_Attribute_Reference (Loc,
3065 Attribute_Name => Name_Unchecked_Access,
3067 Make_Selected_Component (Loc,
3068 Prefix => Make_Identifier (Loc, Name_uT),
3069 Selector_Name => Make_Identifier (Loc, Name_uObject)));
3071 -- Normal case, No_Entry_Queue restriction not active. In this
3072 -- case we generate:
3074 -- Timed_Protected_Entry_Call
3075 -- (T._object'access,
3076 -- Protected_Entry_Index! (I),
3079 -- where T is the protected object, I is the entry index, P are
3080 -- the wrapped parameters, D is the delay amount, M is the delay
3081 -- mode and F is the status flag.
3083 case Corresponding_Runtime_Package (Conc_Typ) is
3084 when System_Tasking_Protected_Objects_Entries =>
3086 Make_Procedure_Call_Statement (Loc,
3089 (RTE (RE_Timed_Protected_Entry_Call), Loc),
3090 Parameter_Associations =>
3094 Make_Unchecked_Type_Conversion (Loc, -- entry index
3097 (RTE (RE_Protected_Entry_Index), Loc),
3099 Make_Identifier (Loc, Name_uI)),
3101 Make_Identifier (Loc, Name_uP), -- parameter block
3102 Make_Identifier (Loc, Name_uD), -- delay
3103 Make_Identifier (Loc, Name_uM), -- delay mode
3104 Make_Identifier (Loc, Name_uF)))); -- status flag
3106 when System_Tasking_Protected_Objects_Single_Entry =>
3109 -- Timed_Protected_Single_Entry_Call
3110 -- (T._object'access, P, D, M, F);
3112 -- where T is the protected object, P is the wrapped
3113 -- parameters, D is the delay amount, M is the delay mode, F
3114 -- is the status flag.
3117 Make_Procedure_Call_Statement (Loc,
3120 (RTE (RE_Timed_Protected_Single_Entry_Call), Loc),
3121 Parameter_Associations =>
3124 Make_Identifier (Loc, Name_uP), -- parameter block
3125 Make_Identifier (Loc, Name_uD), -- delay
3126 Make_Identifier (Loc, Name_uM), -- delay mode
3127 Make_Identifier (Loc, Name_uF)))); -- status flag
3130 raise Program_Error;
3136 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
3139 -- Timed_Task_Entry_Call (
3141 -- Task_Entry_Index! (I),
3147 -- where T is the task object, I is the entry index, P are the
3148 -- wrapped parameters, D is the delay amount, M is the delay
3149 -- mode and F is the status flag.
3152 Make_Procedure_Call_Statement (Loc,
3154 New_Reference_To (RTE (RE_Timed_Task_Entry_Call), Loc),
3155 Parameter_Associations =>
3158 Make_Selected_Component (Loc, -- T._task_id
3160 Make_Identifier (Loc, Name_uT),
3162 Make_Identifier (Loc, Name_uTask_Id)),
3164 Make_Unchecked_Type_Conversion (Loc, -- entry index
3166 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
3168 Make_Identifier (Loc, Name_uI)),
3170 Make_Identifier (Loc, Name_uP), -- parameter block
3171 Make_Identifier (Loc, Name_uD), -- delay
3172 Make_Identifier (Loc, Name_uM), -- delay mode
3173 Make_Identifier (Loc, Name_uF)))); -- status flag
3177 -- Ensure that the statements list is non-empty
3179 Append_To (Stmts, Make_Null_Statement (Loc));
3183 Make_Subprogram_Body (Loc,
3185 Make_Disp_Timed_Select_Spec (Typ),
3188 Handled_Statement_Sequence =>
3189 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
3190 end Make_Disp_Timed_Select_Body;
3192 ---------------------------------
3193 -- Make_Disp_Timed_Select_Spec --
3194 ---------------------------------
3196 function Make_Disp_Timed_Select_Spec
3197 (Typ : Entity_Id) return Node_Id
3199 Loc : constant Source_Ptr := Sloc (Typ);
3200 Def_Id : constant Node_Id :=
3201 Make_Defining_Identifier (Loc,
3202 Name_uDisp_Timed_Select);
3203 Params : constant List_Id := New_List;
3206 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3208 -- T : in out Typ; -- Object parameter
3209 -- S : Integer; -- Primitive operation slot
3210 -- P : Address; -- Wrapped parameters
3211 -- D : Duration; -- Delay
3212 -- M : Integer; -- Delay Mode
3213 -- C : out Prim_Op_Kind; -- Call kind
3214 -- F : out Boolean; -- Status flag
3216 Append_List_To (Params, New_List (
3218 Make_Parameter_Specification (Loc,
3219 Defining_Identifier =>
3220 Make_Defining_Identifier (Loc, Name_uT),
3222 New_Reference_To (Typ, Loc),
3224 Out_Present => True),
3226 Make_Parameter_Specification (Loc,
3227 Defining_Identifier =>
3228 Make_Defining_Identifier (Loc, Name_uS),
3230 New_Reference_To (Standard_Integer, Loc)),
3232 Make_Parameter_Specification (Loc,
3233 Defining_Identifier =>
3234 Make_Defining_Identifier (Loc, Name_uP),
3236 New_Reference_To (RTE (RE_Address), Loc)),
3238 Make_Parameter_Specification (Loc,
3239 Defining_Identifier =>
3240 Make_Defining_Identifier (Loc, Name_uD),
3242 New_Reference_To (Standard_Duration, Loc)),
3244 Make_Parameter_Specification (Loc,
3245 Defining_Identifier =>
3246 Make_Defining_Identifier (Loc, Name_uM),
3248 New_Reference_To (Standard_Integer, Loc)),
3250 Make_Parameter_Specification (Loc,
3251 Defining_Identifier =>
3252 Make_Defining_Identifier (Loc, Name_uC),
3254 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
3255 Out_Present => True)));
3258 Make_Parameter_Specification (Loc,
3259 Defining_Identifier =>
3260 Make_Defining_Identifier (Loc, Name_uF),
3262 New_Reference_To (Standard_Boolean, Loc),
3263 Out_Present => True));
3266 Make_Procedure_Specification (Loc,
3267 Defining_Unit_Name => Def_Id,
3268 Parameter_Specifications => Params);
3269 end Make_Disp_Timed_Select_Spec;
3275 -- The frontend supports two models for expanding dispatch tables
3276 -- associated with library-level defined tagged types: statically
3277 -- and non-statically allocated dispatch tables. In the former case
3278 -- the object containing the dispatch table is constant and it is
3279 -- initialized by means of a positional aggregate. In the latter case,
3280 -- the object containing the dispatch table is a variable which is
3281 -- initialized by means of assignments.
3283 -- In case of locally defined tagged types, the object containing the
3284 -- object containing the dispatch table is always a variable (instead
3285 -- of a constant). This is currently required to give support to late
3286 -- overriding of primitives. For example:
3288 -- procedure Example is
3290 -- type T1 is tagged null record;
3291 -- procedure Prim (O : T1);
3294 -- type T2 is new Pkg.T1 with null record;
3295 -- procedure Prim (X : T2) is -- late overriding
3301 function Make_DT (Typ : Entity_Id; N : Node_Id := Empty) return List_Id is
3302 Loc : constant Source_Ptr := Sloc (Typ);
3304 Max_Predef_Prims : constant Int :=
3308 (Parent (RTE (RE_Max_Predef_Prims)))));
3310 DT_Decl : constant Elist_Id := New_Elmt_List;
3311 DT_Aggr : constant Elist_Id := New_Elmt_List;
3312 -- Entities marked with attribute Is_Dispatch_Table_Entity
3314 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id);
3315 -- Verify that all non-tagged types in the profile of a subprogram
3316 -- are frozen at the point the subprogram is frozen. This enforces
3317 -- the rule on RM 13.14 (14) as modified by AI05-019. At the point a
3318 -- subprogram is frozen, enough must be known about it to build the
3319 -- activation record for it, which requires at least that the size of
3320 -- all parameters be known. Controlling arguments are by-reference,
3321 -- and therefore the rule only applies to non-tagged types.
3322 -- Typical violation of the rule involves an object declaration that
3323 -- freezes a tagged type, when one of its primitive operations has a
3324 -- type in its profile whose full view has not been analyzed yet.
3326 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0);
3327 -- Export the dispatch table DT of tagged type Typ. Required to generate
3328 -- forward references and statically allocate the table. For primary
3329 -- dispatch tables Index is 0; for secondary dispatch tables the value
3330 -- of index must match the Suffix_Index value assigned to the table by
3331 -- Make_Tags when generating its unique external name, and it is used to
3332 -- retrieve from the Dispatch_Table_Wrappers list associated with Typ
3333 -- the external name generated by Import_DT.
3335 procedure Make_Secondary_DT
3339 Num_Iface_Prims : Nat;
3340 Iface_DT_Ptr : Entity_Id;
3341 Predef_Prims_Ptr : Entity_Id;
3342 Build_Thunks : Boolean;
3344 -- Ada 2005 (AI-251): Expand the declarations for a Secondary Dispatch
3345 -- Table of Typ associated with Iface. Each abstract interface of Typ
3346 -- has two secondary dispatch tables: one containing pointers to thunks
3347 -- and another containing pointers to the primitives covering the
3348 -- interface primitives. The former secondary table is generated when
3349 -- Build_Thunks is True, and provides common support for dispatching
3350 -- calls through interface types; the latter secondary table is
3351 -- generated when Build_Thunks is False, and provides support for
3352 -- Generic Dispatching Constructors that dispatch calls through
3353 -- interface types. When constructing this latter table the value
3354 -- of Suffix_Index is -1 to indicate that there is no need to export
3355 -- such table when building statically allocated dispatch tables; a
3356 -- positive value of Suffix_Index must match the Suffix_Index value
3357 -- assigned to this secondary dispatch table by Make_Tags when its
3358 -- unique external name was generated.
3360 ------------------------------
3361 -- Check_Premature_Freezing --
3362 ------------------------------
3364 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id) is
3367 and then Is_Private_Type (Typ)
3368 and then No (Full_View (Typ))
3369 and then not Is_Generic_Type (Typ)
3370 and then not Is_Tagged_Type (Typ)
3371 and then not Is_Frozen (Typ)
3373 Error_Msg_Sloc := Sloc (Subp);
3375 ("declaration must appear after completion of type &", N, Typ);
3377 ("\which is an untagged type in the profile of"
3378 & " primitive operation & declared#",
3381 end Check_Premature_Freezing;
3387 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0)
3393 Set_Is_Statically_Allocated (DT);
3394 Set_Is_True_Constant (DT);
3395 Set_Is_Exported (DT);
3398 Elmt := First_Elmt (Dispatch_Table_Wrappers (Typ));
3399 while Count /= Index loop
3404 pragma Assert (Related_Type (Node (Elmt)) = Typ);
3407 (Entity => Node (Elmt),
3408 Has_Suffix => True);
3410 Set_Interface_Name (DT,
3411 Make_String_Literal (Loc,
3412 Strval => String_From_Name_Buffer));
3414 -- Ensure proper Sprint output of this implicit importation
3416 Set_Is_Internal (DT);
3420 -----------------------
3421 -- Make_Secondary_DT --
3422 -----------------------
3424 procedure Make_Secondary_DT
3428 Num_Iface_Prims : Nat;
3429 Iface_DT_Ptr : Entity_Id;
3430 Predef_Prims_Ptr : Entity_Id;
3431 Build_Thunks : Boolean;
3434 Loc : constant Source_Ptr := Sloc (Typ);
3435 Exporting_Table : constant Boolean :=
3436 Building_Static_DT (Typ)
3437 and then Suffix_Index > 0;
3438 Iface_DT : constant Entity_Id :=
3439 Make_Defining_Identifier (Loc,
3440 Chars => New_Internal_Name ('T'));
3441 Name_Predef_Prims : constant Name_Id := New_Internal_Name ('R');
3442 Predef_Prims : constant Entity_Id :=
3443 Make_Defining_Identifier (Loc,
3444 Chars => Name_Predef_Prims);
3445 DT_Constr_List : List_Id;
3446 DT_Aggr_List : List_Id;
3447 Empty_DT : Boolean := False;
3448 Nb_Predef_Prims : Nat := 0;
3452 OSD_Aggr_List : List_Id;
3455 Prim_Elmt : Elmt_Id;
3456 Prim_Ops_Aggr_List : List_Id;
3459 -- Handle cases in which we do not generate statically allocated
3462 if not Building_Static_DT (Typ) then
3463 Set_Ekind (Predef_Prims, E_Variable);
3464 Set_Ekind (Iface_DT, E_Variable);
3466 -- Statically allocated dispatch tables and related entities are
3470 Set_Ekind (Predef_Prims, E_Constant);
3471 Set_Is_Statically_Allocated (Predef_Prims);
3472 Set_Is_True_Constant (Predef_Prims);
3474 Set_Ekind (Iface_DT, E_Constant);
3475 Set_Is_Statically_Allocated (Iface_DT);
3476 Set_Is_True_Constant (Iface_DT);
3479 -- Calculate the number of slots of the dispatch table. If the number
3480 -- of primitives of Typ is 0 we reserve a dummy single entry for its
3481 -- DT because at run-time the pointer to this dummy entry will be
3484 if Num_Iface_Prims = 0 then
3488 Nb_Prim := Num_Iface_Prims;
3493 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
3494 -- (predef-prim-op-thunk-1'address,
3495 -- predef-prim-op-thunk-2'address,
3497 -- predef-prim-op-thunk-n'address);
3498 -- for Predef_Prims'Alignment use Address'Alignment
3500 -- Stage 1: Calculate the number of predefined primitives
3502 if not Building_Static_DT (Typ) then
3503 Nb_Predef_Prims := Max_Predef_Prims;
3505 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3506 while Present (Prim_Elmt) loop
3507 Prim := Node (Prim_Elmt);
3509 if Is_Predefined_Dispatching_Operation (Prim)
3510 and then not Is_Abstract_Subprogram (Prim)
3512 Pos := UI_To_Int (DT_Position (Prim));
3514 if Pos > Nb_Predef_Prims then
3515 Nb_Predef_Prims := Pos;
3519 Next_Elmt (Prim_Elmt);
3523 -- Stage 2: Create the thunks associated with the predefined
3524 -- primitives and save their entity to fill the aggregate.
3527 Prim_Table : array (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
3529 Thunk_Id : Entity_Id;
3530 Thunk_Code : Node_Id;
3533 Prim_Ops_Aggr_List := New_List;
3534 Prim_Table := (others => Empty);
3536 if Building_Static_DT (Typ) then
3537 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3538 while Present (Prim_Elmt) loop
3539 Prim := Node (Prim_Elmt);
3541 if Is_Predefined_Dispatching_Operation (Prim)
3542 and then not Is_Abstract_Subprogram (Prim)
3543 and then not Present (Prim_Table
3544 (UI_To_Int (DT_Position (Prim))))
3546 if not Build_Thunks then
3547 Prim_Table (UI_To_Int (DT_Position (Prim))) :=
3551 while Present (Alias (Prim)) loop
3552 Prim := Alias (Prim);
3555 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
3557 if Present (Thunk_Id) then
3558 Append_To (Result, Thunk_Code);
3559 Prim_Table (UI_To_Int (DT_Position (Prim)))
3565 Next_Elmt (Prim_Elmt);
3569 for J in Prim_Table'Range loop
3570 if Present (Prim_Table (J)) then
3572 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
3573 Make_Attribute_Reference (Loc,
3574 Prefix => New_Reference_To (Prim_Table (J), Loc),
3575 Attribute_Name => Name_Unrestricted_Access));
3577 New_Node := Make_Null (Loc);
3580 Append_To (Prim_Ops_Aggr_List, New_Node);
3584 Make_Aggregate (Loc,
3585 Expressions => Prim_Ops_Aggr_List);
3587 -- Remember aggregates initializing dispatch tables
3589 Append_Elmt (New_Node, DT_Aggr);
3592 Make_Subtype_Declaration (Loc,
3593 Defining_Identifier =>
3594 Make_Defining_Identifier (Loc,
3595 New_Internal_Name ('S')),
3596 Subtype_Indication =>
3597 New_Reference_To (RTE (RE_Address_Array), Loc));
3599 Append_To (Result, Decl);
3602 Make_Object_Declaration (Loc,
3603 Defining_Identifier => Predef_Prims,
3604 Constant_Present => Building_Static_DT (Typ),
3605 Aliased_Present => True,
3606 Object_Definition => New_Reference_To
3607 (Defining_Identifier (Decl), Loc),
3608 Expression => New_Node));
3611 Make_Attribute_Definition_Clause (Loc,
3612 Name => New_Reference_To (Predef_Prims, Loc),
3613 Chars => Name_Alignment,
3615 Make_Attribute_Reference (Loc,
3617 New_Reference_To (RTE (RE_Integer_Address), Loc),
3618 Attribute_Name => Name_Alignment)));
3623 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
3624 -- (OSD_Table => (1 => <value>,
3628 -- Iface_DT : Dispatch_Table (Nb_Prims) :=
3629 -- ([ Signature => <sig-value> ],
3630 -- Tag_Kind => <tag_kind-value>,
3631 -- Predef_Prims => Predef_Prims'Address,
3632 -- Offset_To_Top => 0,
3633 -- OSD => OSD'Address,
3634 -- Prims_Ptr => (prim-op-1'address,
3635 -- prim-op-2'address,
3637 -- prim-op-n'address));
3638 -- for Iface_DT'Alignment use Address'Alignment;
3640 -- Stage 3: Initialize the discriminant and the record components
3642 DT_Constr_List := New_List;
3643 DT_Aggr_List := New_List;
3645 -- Nb_Prim. If the tagged type has no primitives we add a dummy
3646 -- slot whose address will be the tag of this type.
3649 New_Node := Make_Integer_Literal (Loc, 1);
3651 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
3654 Append_To (DT_Constr_List, New_Node);
3655 Append_To (DT_Aggr_List, New_Copy (New_Node));
3659 if RTE_Record_Component_Available (RE_Signature) then
3660 Append_To (DT_Aggr_List,
3661 New_Reference_To (RTE (RE_Secondary_DT), Loc));
3666 if RTE_Record_Component_Available (RE_Tag_Kind) then
3667 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
3672 Append_To (DT_Aggr_List,
3673 Make_Attribute_Reference (Loc,
3674 Prefix => New_Reference_To (Predef_Prims, Loc),
3675 Attribute_Name => Name_Address));
3677 -- Note: The correct value of Offset_To_Top will be set by the init
3680 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
3682 -- Generate the Object Specific Data table required to dispatch calls
3683 -- through synchronized interfaces.
3686 or else Is_Abstract_Type (Typ)
3687 or else Is_Controlled (Typ)
3688 or else Restriction_Active (No_Dispatching_Calls)
3689 or else not Is_Limited_Type (Typ)
3690 or else not Has_Interfaces (Typ)
3691 or else not Build_Thunks
3692 or else not RTE_Record_Component_Available (RE_OSD_Table)
3694 -- No OSD table required
3696 Append_To (DT_Aggr_List,
3697 New_Reference_To (RTE (RE_Null_Address), Loc));
3700 OSD_Aggr_List := New_List;
3703 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
3705 Prim_Alias : Entity_Id;
3706 Prim_Elmt : Elmt_Id;
3712 Prim_Table := (others => Empty);
3713 Prim_Alias := Empty;
3715 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3716 while Present (Prim_Elmt) loop
3717 Prim := Node (Prim_Elmt);
3719 if Present (Interface_Alias (Prim))
3720 and then Find_Dispatching_Type
3721 (Interface_Alias (Prim)) = Iface
3723 Prim_Alias := Interface_Alias (Prim);
3726 while Present (Alias (E)) loop
3730 Pos := UI_To_Int (DT_Position (Prim_Alias));
3732 if Present (Prim_Table (Pos)) then
3733 pragma Assert (Prim_Table (Pos) = E);
3737 Prim_Table (Pos) := E;
3739 Append_To (OSD_Aggr_List,
3740 Make_Component_Association (Loc,
3741 Choices => New_List (
3742 Make_Integer_Literal (Loc,
3743 DT_Position (Prim_Alias))),
3745 Make_Integer_Literal (Loc,
3746 DT_Position (Alias (Prim)))));
3752 Next_Elmt (Prim_Elmt);
3754 pragma Assert (Count = Nb_Prim);
3757 OSD := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
3760 Make_Object_Declaration (Loc,
3761 Defining_Identifier => OSD,
3762 Object_Definition =>
3763 Make_Subtype_Indication (Loc,
3765 New_Reference_To (RTE (RE_Object_Specific_Data), Loc),
3767 Make_Index_Or_Discriminant_Constraint (Loc,
3768 Constraints => New_List (
3769 Make_Integer_Literal (Loc, Nb_Prim)))),
3770 Expression => Make_Aggregate (Loc,
3771 Component_Associations => New_List (
3772 Make_Component_Association (Loc,
3773 Choices => New_List (
3775 (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
3777 Make_Integer_Literal (Loc, Nb_Prim)),
3779 Make_Component_Association (Loc,
3780 Choices => New_List (
3782 (RTE_Record_Component (RE_OSD_Table), Loc)),
3783 Expression => Make_Aggregate (Loc,
3784 Component_Associations => OSD_Aggr_List))))));
3787 Make_Attribute_Definition_Clause (Loc,
3788 Name => New_Reference_To (OSD, Loc),
3789 Chars => Name_Alignment,
3791 Make_Attribute_Reference (Loc,
3793 New_Reference_To (RTE (RE_Integer_Address), Loc),
3794 Attribute_Name => Name_Alignment)));
3796 -- In secondary dispatch tables the Typeinfo component contains
3797 -- the address of the Object Specific Data (see a-tags.ads)
3799 Append_To (DT_Aggr_List,
3800 Make_Attribute_Reference (Loc,
3801 Prefix => New_Reference_To (OSD, Loc),
3802 Attribute_Name => Name_Address));
3805 -- Initialize the table of primitive operations
3807 Prim_Ops_Aggr_List := New_List;
3810 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
3812 elsif Is_Abstract_Type (Typ)
3813 or else not Building_Static_DT (Typ)
3815 for J in 1 .. Nb_Prim loop
3816 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
3821 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
3823 Thunk_Code : Node_Id;
3824 Thunk_Id : Entity_Id;
3827 Prim_Table := (others => Empty);
3829 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3830 while Present (Prim_Elmt) loop
3831 Prim := Node (Prim_Elmt);
3833 if not Is_Predefined_Dispatching_Operation (Prim)
3834 and then Present (Interface_Alias (Prim))
3835 and then not Is_Abstract_Subprogram (Alias (Prim))
3836 and then not Is_Imported (Alias (Prim))
3837 and then Find_Dispatching_Type
3838 (Interface_Alias (Prim)) = Iface
3840 -- Generate the code of the thunk only if the abstract
3841 -- interface type is not an immediate ancestor of
3842 -- Tagged_Type; otherwise the DT associated with the
3843 -- interface is the primary DT.
3845 and then not Is_Ancestor (Iface, Typ)
3847 if not Build_Thunks then
3849 UI_To_Int (DT_Position (Interface_Alias (Prim)));
3850 Prim_Table (Pos) := Alias (Prim);
3852 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
3854 if Present (Thunk_Id) then
3856 UI_To_Int (DT_Position (Interface_Alias (Prim)));
3858 Prim_Table (Pos) := Thunk_Id;
3859 Append_To (Result, Thunk_Code);
3864 Next_Elmt (Prim_Elmt);
3867 for J in Prim_Table'Range loop
3868 if Present (Prim_Table (J)) then
3870 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
3871 Make_Attribute_Reference (Loc,
3872 Prefix => New_Reference_To (Prim_Table (J), Loc),
3873 Attribute_Name => Name_Unrestricted_Access));
3875 New_Node := Make_Null (Loc);
3878 Append_To (Prim_Ops_Aggr_List, New_Node);
3884 Make_Aggregate (Loc,
3885 Expressions => Prim_Ops_Aggr_List);
3887 Append_To (DT_Aggr_List, New_Node);
3889 -- Remember aggregates initializing dispatch tables
3891 Append_Elmt (New_Node, DT_Aggr);
3893 -- Note: Secondary dispatch tables cannot be declared constant
3894 -- because the component Offset_To_Top is currently initialized
3895 -- by the IP routine.
3898 Make_Object_Declaration (Loc,
3899 Defining_Identifier => Iface_DT,
3900 Aliased_Present => True,
3901 Constant_Present => False,
3903 Object_Definition =>
3904 Make_Subtype_Indication (Loc,
3905 Subtype_Mark => New_Reference_To
3906 (RTE (RE_Dispatch_Table_Wrapper), Loc),
3907 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
3908 Constraints => DT_Constr_List)),
3911 Make_Aggregate (Loc,
3912 Expressions => DT_Aggr_List)));
3915 Make_Attribute_Definition_Clause (Loc,
3916 Name => New_Reference_To (Iface_DT, Loc),
3917 Chars => Name_Alignment,
3920 Make_Attribute_Reference (Loc,
3922 New_Reference_To (RTE (RE_Integer_Address), Loc),
3923 Attribute_Name => Name_Alignment)));
3925 if Exporting_Table then
3926 Export_DT (Typ, Iface_DT, Suffix_Index);
3928 -- Generate code to create the pointer to the dispatch table
3930 -- Iface_DT_Ptr : Tag := Tag!(DT.Prims_Ptr'Address);
3932 -- Note: This declaration is not added here if the table is exported
3933 -- because in such case Make_Tags has already added this declaration.
3937 Make_Object_Declaration (Loc,
3938 Defining_Identifier => Iface_DT_Ptr,
3939 Constant_Present => True,
3941 Object_Definition =>
3942 New_Reference_To (RTE (RE_Interface_Tag), Loc),
3945 Unchecked_Convert_To (RTE (RE_Interface_Tag),
3946 Make_Attribute_Reference (Loc,
3948 Make_Selected_Component (Loc,
3949 Prefix => New_Reference_To (Iface_DT, Loc),
3952 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
3953 Attribute_Name => Name_Address))));
3957 Make_Object_Declaration (Loc,
3958 Defining_Identifier => Predef_Prims_Ptr,
3959 Constant_Present => True,
3961 Object_Definition =>
3962 New_Reference_To (RTE (RE_Address), Loc),
3965 Make_Attribute_Reference (Loc,
3967 Make_Selected_Component (Loc,
3968 Prefix => New_Reference_To (Iface_DT, Loc),
3971 (RTE_Record_Component (RE_Predef_Prims), Loc)),
3972 Attribute_Name => Name_Address)));
3974 -- Remember entities containing dispatch tables
3976 Append_Elmt (Predef_Prims, DT_Decl);
3977 Append_Elmt (Iface_DT, DT_Decl);
3978 end Make_Secondary_DT;
3982 Elab_Code : constant List_Id := New_List;
3983 Result : constant List_Id := New_List;
3984 Tname : constant Name_Id := Chars (Typ);
3986 AI_Tag_Elmt : Elmt_Id;
3987 AI_Tag_Comp : Elmt_Id;
3988 DT_Aggr_List : List_Id;
3989 DT_Constr_List : List_Id;
3993 Iface_Table_Node : Node_Id;
3994 Name_ITable : Name_Id;
3995 Nb_Predef_Prims : Nat := 0;
3998 Num_Ifaces : Nat := 0;
3999 Parent_Typ : Entity_Id;
4001 Prim_Elmt : Elmt_Id;
4002 Prim_Ops_Aggr_List : List_Id;
4004 Typ_Comps : Elist_Id;
4005 Typ_Ifaces : Elist_Id;
4006 TSD_Aggr_List : List_Id;
4007 TSD_Tags_List : List_Id;
4009 -- The following name entries are used by Make_DT to generate a number
4010 -- of entities related to a tagged type. These entities may be generated
4011 -- in a scope other than that of the tagged type declaration, and if
4012 -- the entities for two tagged types with the same name happen to be
4013 -- generated in the same scope, we have to take care to use different
4014 -- names. This is achieved by means of a unique serial number appended
4015 -- to each generated entity name.
4017 Name_DT : constant Name_Id :=
4018 New_External_Name (Tname, 'T', Suffix_Index => -1);
4019 Name_Exname : constant Name_Id :=
4020 New_External_Name (Tname, 'E', Suffix_Index => -1);
4021 Name_HT_Link : constant Name_Id :=
4022 New_External_Name (Tname, 'H', Suffix_Index => -1);
4023 Name_Predef_Prims : constant Name_Id :=
4024 New_External_Name (Tname, 'R', Suffix_Index => -1);
4025 Name_SSD : constant Name_Id :=
4026 New_External_Name (Tname, 'S', Suffix_Index => -1);
4027 Name_TSD : constant Name_Id :=
4028 New_External_Name (Tname, 'B', Suffix_Index => -1);
4030 -- Entities built with above names
4032 DT : constant Entity_Id :=
4033 Make_Defining_Identifier (Loc, Name_DT);
4034 Exname : constant Entity_Id :=
4035 Make_Defining_Identifier (Loc, Name_Exname);
4036 HT_Link : constant Entity_Id :=
4037 Make_Defining_Identifier (Loc, Name_HT_Link);
4038 Predef_Prims : constant Entity_Id :=
4039 Make_Defining_Identifier (Loc, Name_Predef_Prims);
4040 SSD : constant Entity_Id :=
4041 Make_Defining_Identifier (Loc, Name_SSD);
4042 TSD : constant Entity_Id :=
4043 Make_Defining_Identifier (Loc, Name_TSD);
4045 -- Start of processing for Make_DT
4048 pragma Assert (Is_Frozen (Typ));
4050 -- Handle cases in which there is no need to build the dispatch table
4052 if Has_Dispatch_Table (Typ)
4053 or else No (Access_Disp_Table (Typ))
4054 or else Is_CPP_Class (Typ)
4058 elsif No_Run_Time_Mode then
4059 Error_Msg_CRT ("tagged types", Typ);
4062 elsif not RTE_Available (RE_Tag) then
4064 Make_Object_Declaration (Loc,
4065 Defining_Identifier => Node (First_Elmt
4066 (Access_Disp_Table (Typ))),
4067 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4068 Constant_Present => True,
4070 Unchecked_Convert_To (RTE (RE_Tag),
4071 New_Reference_To (RTE (RE_Null_Address), Loc))));
4073 Analyze_List (Result, Suppress => All_Checks);
4074 Error_Msg_CRT ("tagged types", Typ);
4078 -- Ensure that the value of Max_Predef_Prims defined in a-tags is
4079 -- correct. Valid values are 10 under configurable runtime or 16
4080 -- with full runtime.
4082 if RTE_Available (RE_Interface_Data) then
4083 if Max_Predef_Prims /= 16 then
4084 Error_Msg_N ("run-time library configuration error", Typ);
4088 if Max_Predef_Prims /= 10 then
4089 Error_Msg_N ("run-time library configuration error", Typ);
4090 Error_Msg_CRT ("tagged types", Typ);
4095 -- Initialize Parent_Typ handling private types
4097 Parent_Typ := Etype (Typ);
4099 if Present (Full_View (Parent_Typ)) then
4100 Parent_Typ := Full_View (Parent_Typ);
4103 -- Ensure that all the primitives are frozen. This is only required when
4104 -- building static dispatch tables --- the primitives must be frozen to
4105 -- be referenced (otherwise we have problems with the backend). It is
4106 -- not a requirement with nonstatic dispatch tables because in this case
4107 -- we generate now an empty dispatch table; the extra code required to
4108 -- register the primitives in the slots will be generated later --- when
4109 -- each primitive is frozen (see Freeze_Subprogram).
4111 if Building_Static_DT (Typ)
4112 and then not Is_CPP_Class (Typ)
4115 Save : constant Boolean := Freezing_Library_Level_Tagged_Type;
4117 Prim_Elmt : Elmt_Id;
4121 Freezing_Library_Level_Tagged_Type := True;
4123 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4124 while Present (Prim_Elmt) loop
4125 Prim := Node (Prim_Elmt);
4126 Frnodes := Freeze_Entity (Prim, Loc);
4132 F := First_Formal (Prim);
4133 while Present (F) loop
4134 Check_Premature_Freezing (Prim, Etype (F));
4138 Check_Premature_Freezing (Prim, Etype (Prim));
4141 if Present (Frnodes) then
4142 Append_List_To (Result, Frnodes);
4145 Next_Elmt (Prim_Elmt);
4148 Freezing_Library_Level_Tagged_Type := Save;
4152 -- Ada 2005 (AI-251): Build the secondary dispatch tables
4154 if Has_Interfaces (Typ) then
4155 Collect_Interface_Components (Typ, Typ_Comps);
4157 -- Each secondary dispatch table is assigned an unique positive
4158 -- suffix index; such value also corresponds with the location of
4159 -- its entity in the Dispatch_Table_Wrappers list (see Make_Tags).
4161 -- Note: This value must be kept sync with the Suffix_Index values
4162 -- generated by Make_Tags
4166 Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
4168 AI_Tag_Comp := First_Elmt (Typ_Comps);
4169 while Present (AI_Tag_Comp) loop
4171 -- Build the secondary table containing pointers to thunks
4175 Iface => Base_Type (Related_Type (Node (AI_Tag_Comp))),
4176 Suffix_Index => Suffix_Index,
4177 Num_Iface_Prims => UI_To_Int
4178 (DT_Entry_Count (Node (AI_Tag_Comp))),
4179 Iface_DT_Ptr => Node (AI_Tag_Elmt),
4180 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
4181 Build_Thunks => True,
4184 -- Skip secondary dispatch table and secondary dispatch table of
4185 -- predefined primitives
4187 Next_Elmt (AI_Tag_Elmt);
4188 Next_Elmt (AI_Tag_Elmt);
4190 -- Build the secondary table containing pointers to primitives
4191 -- (used to give support to Generic Dispatching Constructors).
4195 Iface => Base_Type (Related_Type (Node (AI_Tag_Comp))),
4197 Num_Iface_Prims => UI_To_Int
4198 (DT_Entry_Count (Node (AI_Tag_Comp))),
4199 Iface_DT_Ptr => Node (AI_Tag_Elmt),
4200 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
4201 Build_Thunks => False,
4204 -- Skip secondary dispatch table and secondary dispatch table of
4205 -- predefined primitives
4207 Next_Elmt (AI_Tag_Elmt);
4208 Next_Elmt (AI_Tag_Elmt);
4210 Suffix_Index := Suffix_Index + 1;
4211 Next_Elmt (AI_Tag_Comp);
4215 -- Get the _tag entity and the number of primitives of its dispatch
4218 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
4219 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
4221 Set_Is_Statically_Allocated (DT, Is_Library_Level_Tagged_Type (Typ));
4222 Set_Is_Statically_Allocated (SSD, Is_Library_Level_Tagged_Type (Typ));
4223 Set_Is_Statically_Allocated (TSD, Is_Library_Level_Tagged_Type (Typ));
4224 Set_Is_Statically_Allocated (Predef_Prims,
4225 Is_Library_Level_Tagged_Type (Typ));
4227 -- In case of locally defined tagged type we declare the object
4228 -- containing the dispatch table by means of a variable. Its
4229 -- initialization is done later by means of an assignment. This is
4230 -- required to generate its External_Tag.
4232 if not Building_Static_DT (Typ) then
4235 -- DT : No_Dispatch_Table_Wrapper;
4236 -- for DT'Alignment use Address'Alignment;
4237 -- DT_Ptr : Tag := !Tag (DT.NDT_Prims_Ptr'Address);
4239 if not Has_DT (Typ) then
4241 Make_Object_Declaration (Loc,
4242 Defining_Identifier => DT,
4243 Aliased_Present => True,
4244 Constant_Present => False,
4245 Object_Definition =>
4247 (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
4249 -- Generate a SCIL node for the previous object declaration
4250 -- because it has a null dispatch table.
4252 if Generate_SCIL then
4253 Insert_Before (Last (Result),
4255 (SN_Kind => Dispatch_Table_Object_Init,
4256 Related_Node => Last (Result),
4261 Make_Attribute_Definition_Clause (Loc,
4262 Name => New_Reference_To (DT, Loc),
4263 Chars => Name_Alignment,
4265 Make_Attribute_Reference (Loc,
4267 New_Reference_To (RTE (RE_Integer_Address), Loc),
4268 Attribute_Name => Name_Alignment)));
4271 Make_Object_Declaration (Loc,
4272 Defining_Identifier => DT_Ptr,
4273 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4274 Constant_Present => True,
4276 Unchecked_Convert_To (RTE (RE_Tag),
4277 Make_Attribute_Reference (Loc,
4279 Make_Selected_Component (Loc,
4280 Prefix => New_Reference_To (DT, Loc),
4283 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
4284 Attribute_Name => Name_Address))));
4286 -- Generate the SCIL node for the previous object declaration
4287 -- because it has a tag initialization.
4289 if Generate_SCIL then
4290 Insert_Before (Last (Result),
4292 (SN_Kind => Dispatch_Table_Tag_Init,
4293 Related_Node => Last (Result),
4298 -- DT : Dispatch_Table_Wrapper (Nb_Prim);
4299 -- for DT'Alignment use Address'Alignment;
4300 -- DT_Ptr : Tag := !Tag (DT.Prims_Ptr'Address);
4303 -- If the tagged type has no primitives we add a dummy slot
4304 -- whose address will be the tag of this type.
4308 New_List (Make_Integer_Literal (Loc, 1));
4311 New_List (Make_Integer_Literal (Loc, Nb_Prim));
4315 Make_Object_Declaration (Loc,
4316 Defining_Identifier => DT,
4317 Aliased_Present => True,
4318 Constant_Present => False,
4319 Object_Definition =>
4320 Make_Subtype_Indication (Loc,
4322 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
4323 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4324 Constraints => DT_Constr_List))));
4326 -- Generate the SCIL node for the previous object declaration
4327 -- because it contains a dispatch table.
4329 if Generate_SCIL then
4330 Insert_Before (Last (Result),
4332 (SN_Kind => Dispatch_Table_Object_Init,
4333 Related_Node => Last (Result),
4338 Make_Attribute_Definition_Clause (Loc,
4339 Name => New_Reference_To (DT, Loc),
4340 Chars => Name_Alignment,
4342 Make_Attribute_Reference (Loc,
4344 New_Reference_To (RTE (RE_Integer_Address), Loc),
4345 Attribute_Name => Name_Alignment)));
4348 Make_Object_Declaration (Loc,
4349 Defining_Identifier => DT_Ptr,
4350 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4351 Constant_Present => True,
4353 Unchecked_Convert_To (RTE (RE_Tag),
4354 Make_Attribute_Reference (Loc,
4356 Make_Selected_Component (Loc,
4357 Prefix => New_Reference_To (DT, Loc),
4360 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
4361 Attribute_Name => Name_Address))));
4363 -- Generate the SCIL node for the previous object declaration
4364 -- because it has a tag initialization.
4366 if Generate_SCIL then
4367 Insert_Before (Last (Result),
4369 (SN_Kind => Dispatch_Table_Tag_Init,
4370 Related_Node => Last (Result),
4375 Make_Object_Declaration (Loc,
4376 Defining_Identifier =>
4377 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Typ)))),
4378 Constant_Present => True,
4379 Object_Definition => New_Reference_To
4380 (RTE (RE_Address), Loc),
4382 Make_Attribute_Reference (Loc,
4384 Make_Selected_Component (Loc,
4385 Prefix => New_Reference_To (DT, Loc),
4388 (RTE_Record_Component (RE_Predef_Prims), Loc)),
4389 Attribute_Name => Name_Address)));
4393 -- Generate: Exname : constant String := full_qualified_name (typ);
4394 -- The type itself may be an anonymous parent type, so use the first
4395 -- subtype to have a user-recognizable name.
4398 Make_Object_Declaration (Loc,
4399 Defining_Identifier => Exname,
4400 Constant_Present => True,
4401 Object_Definition => New_Reference_To (Standard_String, Loc),
4403 Make_String_Literal (Loc,
4404 Full_Qualified_Name (First_Subtype (Typ)))));
4406 Set_Is_Statically_Allocated (Exname);
4407 Set_Is_True_Constant (Exname);
4409 -- Declare the object used by Ada.Tags.Register_Tag
4411 if RTE_Available (RE_Register_Tag) then
4413 Make_Object_Declaration (Loc,
4414 Defining_Identifier => HT_Link,
4415 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc)));
4418 -- Generate code to create the storage for the type specific data object
4419 -- with enough space to store the tags of the ancestors plus the tags
4420 -- of all the implemented interfaces (as described in a-tags.adb).
4422 -- TSD : Type_Specific_Data (I_Depth) :=
4423 -- (Idepth => I_Depth,
4424 -- Access_Level => Type_Access_Level (Typ),
4425 -- Expanded_Name => Cstring_Ptr!(Exname'Address))
4426 -- External_Tag => Cstring_Ptr!(Exname'Address))
4427 -- HT_Link => HT_Link'Address,
4428 -- Transportable => <<boolean-value>>,
4429 -- RC_Offset => <<integer-value>>,
4430 -- [ Size_Func => Size_Prim'Access ]
4431 -- [ Interfaces_Table => <<access-value>> ]
4432 -- [ SSD => SSD_Table'Address ]
4433 -- Tags_Table => (0 => null,
4436 -- for TSD'Alignment use Address'Alignment
4438 TSD_Aggr_List := New_List;
4440 -- Idepth: Count ancestors to compute the inheritance depth. For private
4441 -- extensions, always go to the full view in order to compute the real
4442 -- inheritance depth.
4445 Current_Typ : Entity_Id;
4446 Parent_Typ : Entity_Id;
4452 Parent_Typ := Etype (Current_Typ);
4454 if Is_Private_Type (Parent_Typ) then
4455 Parent_Typ := Full_View (Base_Type (Parent_Typ));
4458 exit when Parent_Typ = Current_Typ;
4460 I_Depth := I_Depth + 1;
4461 Current_Typ := Parent_Typ;
4465 Append_To (TSD_Aggr_List,
4466 Make_Integer_Literal (Loc, I_Depth));
4470 Append_To (TSD_Aggr_List,
4471 Make_Integer_Literal (Loc, Type_Access_Level (Typ)));
4475 Append_To (TSD_Aggr_List,
4476 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4477 Make_Attribute_Reference (Loc,
4478 Prefix => New_Reference_To (Exname, Loc),
4479 Attribute_Name => Name_Address)));
4481 -- External_Tag of a local tagged type
4483 -- <typ>A : constant String :=
4484 -- "Internal tag at 16#tag-addr#: <full-name-of-typ>";
4486 -- The reason we generate this strange name is that we do not want to
4487 -- enter local tagged types in the global hash table used to compute
4488 -- the Internal_Tag attribute for two reasons:
4490 -- 1. It is hard to avoid a tasking race condition for entering the
4491 -- entry into the hash table.
4493 -- 2. It would cause a storage leak, unless we rig up considerable
4494 -- mechanism to remove the entry from the hash table on exit.
4496 -- So what we do is to generate the above external tag name, where the
4497 -- hex address is the address of the local dispatch table (i.e. exactly
4498 -- the value we want if Internal_Tag is computed from this string).
4500 -- Of course this value will only be valid if the tagged type is still
4501 -- in scope, but it clearly must be erroneous to compute the internal
4502 -- tag of a tagged type that is out of scope!
4504 -- We don't do this processing if an explicit external tag has been
4505 -- specified. That's an odd case for which we have already issued a
4506 -- warning, where we will not be able to compute the internal tag.
4508 if not Is_Library_Level_Entity (Typ)
4509 and then not Has_External_Tag_Rep_Clause (Typ)
4512 Exname : constant Entity_Id :=
4513 Make_Defining_Identifier (Loc,
4514 New_External_Name (Tname, 'A'));
4516 Full_Name : constant String_Id :=
4517 Full_Qualified_Name (First_Subtype (Typ));
4518 Str1_Id : String_Id;
4519 Str2_Id : String_Id;
4523 -- Str1 = "Internal tag at 16#";
4526 Store_String_Chars ("Internal tag at 16#");
4527 Str1_Id := End_String;
4530 -- Str2 = "#: <type-full-name>";
4533 Store_String_Chars ("#: ");
4534 Store_String_Chars (Full_Name);
4535 Str2_Id := End_String;
4538 -- Exname : constant String :=
4539 -- Str1 & Address_Image (Tag) & Str2;
4541 if RTE_Available (RE_Address_Image) then
4543 Make_Object_Declaration (Loc,
4544 Defining_Identifier => Exname,
4545 Constant_Present => True,
4546 Object_Definition => New_Reference_To
4547 (Standard_String, Loc),
4549 Make_Op_Concat (Loc,
4551 Make_String_Literal (Loc, Str1_Id),
4553 Make_Op_Concat (Loc,
4555 Make_Function_Call (Loc,
4558 (RTE (RE_Address_Image), Loc),
4559 Parameter_Associations => New_List (
4560 Unchecked_Convert_To (RTE (RE_Address),
4561 New_Reference_To (DT_Ptr, Loc)))),
4563 Make_String_Literal (Loc, Str2_Id)))));
4567 Make_Object_Declaration (Loc,
4568 Defining_Identifier => Exname,
4569 Constant_Present => True,
4570 Object_Definition => New_Reference_To
4571 (Standard_String, Loc),
4573 Make_Op_Concat (Loc,
4575 Make_String_Literal (Loc, Str1_Id),
4577 Make_String_Literal (Loc, Str2_Id))));
4581 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4582 Make_Attribute_Reference (Loc,
4583 Prefix => New_Reference_To (Exname, Loc),
4584 Attribute_Name => Name_Address));
4587 -- External tag of a library-level tagged type: Check for a definition
4588 -- of External_Tag. The clause is considered only if it applies to this
4589 -- specific tagged type, as opposed to one of its ancestors.
4590 -- If the type is an unconstrained type extension, we are building the
4591 -- dispatch table of its anonymous base type, so the external tag, if
4592 -- any was specified, must be retrieved from the first subtype. Go to
4593 -- the full view in case the clause is in the private part.
4597 Def : constant Node_Id := Get_Attribute_Definition_Clause
4598 (Underlying_Type (First_Subtype (Typ)),
4599 Attribute_External_Tag);
4601 Old_Val : String_Id;
4602 New_Val : String_Id;
4606 if not Present (Def)
4607 or else Entity (Name (Def)) /= First_Subtype (Typ)
4610 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4611 Make_Attribute_Reference (Loc,
4612 Prefix => New_Reference_To (Exname, Loc),
4613 Attribute_Name => Name_Address));
4615 Old_Val := Strval (Expr_Value_S (Expression (Def)));
4617 -- For the rep clause "for <typ>'external_tag use y" generate:
4619 -- <typ>A : constant string := y;
4621 -- <typ>A'Address is used to set the External_Tag component
4624 -- Create a new nul terminated string if it is not already
4626 if String_Length (Old_Val) > 0
4628 Get_String_Char (Old_Val, String_Length (Old_Val)) = 0
4632 Start_String (Old_Val);
4633 Store_String_Char (Get_Char_Code (ASCII.NUL));
4634 New_Val := End_String;
4637 E := Make_Defining_Identifier (Loc,
4638 New_External_Name (Chars (Typ), 'A'));
4641 Make_Object_Declaration (Loc,
4642 Defining_Identifier => E,
4643 Constant_Present => True,
4644 Object_Definition =>
4645 New_Reference_To (Standard_String, Loc),
4647 Make_String_Literal (Loc, New_Val)));
4650 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4651 Make_Attribute_Reference (Loc,
4652 Prefix => New_Reference_To (E, Loc),
4653 Attribute_Name => Name_Address));
4658 Append_To (TSD_Aggr_List, New_Node);
4662 if RTE_Available (RE_Register_Tag) then
4663 Append_To (TSD_Aggr_List,
4664 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
4665 Make_Attribute_Reference (Loc,
4666 Prefix => New_Reference_To (HT_Link, Loc),
4667 Attribute_Name => Name_Address)));
4669 Append_To (TSD_Aggr_List,
4670 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
4671 New_Reference_To (RTE (RE_Null_Address), Loc)));
4674 -- Transportable: Set for types that can be used in remote calls
4675 -- with respect to E.4(18) legality rules.
4678 Transportable : Entity_Id;
4684 or else Is_Shared_Passive (Typ)
4686 ((Is_Remote_Types (Typ)
4687 or else Is_Remote_Call_Interface (Typ))
4688 and then Original_View_In_Visible_Part (Typ))
4689 or else not Comes_From_Source (Typ));
4691 Append_To (TSD_Aggr_List,
4692 New_Occurrence_Of (Transportable, Loc));
4695 -- RC_Offset: These are the valid values and their meaning:
4697 -- >0: For simple types with controlled components is
4698 -- type._record_controller'position
4700 -- 0: For types with no controlled components
4702 -- -1: For complex types with controlled components where the position
4703 -- of the record controller is not statically computable but there
4704 -- are controlled components at this level. The _Controller field
4705 -- is available right after the _parent.
4707 -- -2: There are no controlled components at this level. We need to
4708 -- get the position from the parent.
4711 RC_Offset_Node : Node_Id;
4714 if not Has_Controlled_Component (Typ) then
4715 RC_Offset_Node := Make_Integer_Literal (Loc, 0);
4717 elsif Etype (Typ) /= Typ
4718 and then Has_Discriminants (Parent_Typ)
4720 if Has_New_Controlled_Component (Typ) then
4721 RC_Offset_Node := Make_Integer_Literal (Loc, -1);
4723 RC_Offset_Node := Make_Integer_Literal (Loc, -2);
4727 Make_Attribute_Reference (Loc,
4729 Make_Selected_Component (Loc,
4730 Prefix => New_Reference_To (Typ, Loc),
4732 New_Reference_To (Controller_Component (Typ), Loc)),
4733 Attribute_Name => Name_Position);
4735 -- This is not proper Ada code to use the attribute 'Position
4736 -- on something else than an object but this is supported by
4737 -- the back end (see comment on the Bit_Component attribute in
4738 -- sem_attr). So we avoid semantic checking here.
4740 -- Is this documented in sinfo.ads??? it should be!
4742 Set_Analyzed (RC_Offset_Node);
4743 Set_Etype (Prefix (RC_Offset_Node), RTE (RE_Record_Controller));
4744 Set_Etype (Prefix (Prefix (RC_Offset_Node)), Typ);
4745 Set_Etype (Selector_Name (Prefix (RC_Offset_Node)),
4746 RTE (RE_Record_Controller));
4747 Set_Etype (RC_Offset_Node, RTE (RE_Storage_Offset));
4750 Append_To (TSD_Aggr_List, RC_Offset_Node);
4755 if RTE_Record_Component_Available (RE_Size_Func) then
4756 if not Building_Static_DT (Typ)
4757 or else Is_Interface (Typ)
4759 Append_To (TSD_Aggr_List,
4760 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4761 New_Reference_To (RTE (RE_Null_Address), Loc)));
4765 Prim_Elmt : Elmt_Id;
4769 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4770 while Present (Prim_Elmt) loop
4771 Prim := Node (Prim_Elmt);
4773 if Chars (Prim) = Name_uSize then
4774 while Present (Alias (Prim)) loop
4775 Prim := Alias (Prim);
4778 if Is_Abstract_Subprogram (Prim) then
4779 Append_To (TSD_Aggr_List,
4780 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4781 New_Reference_To (RTE (RE_Null_Address), Loc)));
4783 Append_To (TSD_Aggr_List,
4784 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4785 Make_Attribute_Reference (Loc,
4786 Prefix => New_Reference_To (Prim, Loc),
4787 Attribute_Name => Name_Unrestricted_Access)));
4793 Next_Elmt (Prim_Elmt);
4799 -- Interfaces_Table (required for AI-405)
4801 if RTE_Record_Component_Available (RE_Interfaces_Table) then
4803 -- Count the number of interface types implemented by Typ
4805 Collect_Interfaces (Typ, Typ_Ifaces);
4807 AI := First_Elmt (Typ_Ifaces);
4808 while Present (AI) loop
4809 Num_Ifaces := Num_Ifaces + 1;
4813 if Num_Ifaces = 0 then
4814 Iface_Table_Node := Make_Null (Loc);
4816 -- Generate the Interface_Table object
4820 TSD_Ifaces_List : constant List_Id := New_List;
4822 Sec_DT_Tag : Node_Id;
4825 AI := First_Elmt (Typ_Ifaces);
4826 while Present (AI) loop
4827 if Is_Ancestor (Node (AI), Typ) then
4829 New_Reference_To (DT_Ptr, Loc);
4833 (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
4834 pragma Assert (Has_Thunks (Node (Elmt)));
4836 while Ekind (Node (Elmt)) = E_Constant
4838 Is_Ancestor (Node (AI), Related_Type (Node (Elmt)))
4840 pragma Assert (Has_Thunks (Node (Elmt)));
4842 pragma Assert (Has_Thunks (Node (Elmt)));
4844 pragma Assert (not Has_Thunks (Node (Elmt)));
4846 pragma Assert (not Has_Thunks (Node (Elmt)));
4850 pragma Assert (Ekind (Node (Elmt)) = E_Constant
4852 Has_Thunks (Node (Next_Elmt (Next_Elmt (Elmt)))));
4854 New_Reference_To (Node (Next_Elmt (Next_Elmt (Elmt))),
4858 Append_To (TSD_Ifaces_List,
4859 Make_Aggregate (Loc,
4860 Expressions => New_List (
4864 Unchecked_Convert_To (RTE (RE_Tag),
4866 (Node (First_Elmt (Access_Disp_Table (Node (AI)))),
4869 -- Static_Offset_To_Top
4871 New_Reference_To (Standard_True, Loc),
4873 -- Offset_To_Top_Value
4875 Make_Integer_Literal (Loc, 0),
4877 -- Offset_To_Top_Func
4883 Unchecked_Convert_To (RTE (RE_Tag), Sec_DT_Tag)
4890 Name_ITable := New_External_Name (Tname, 'I');
4891 ITable := Make_Defining_Identifier (Loc, Name_ITable);
4892 Set_Is_Statically_Allocated (ITable,
4893 Is_Library_Level_Tagged_Type (Typ));
4895 -- The table of interfaces is not constant; its slots are
4896 -- filled at run-time by the IP routine using attribute
4897 -- 'Position to know the location of the tag components
4898 -- (and this attribute cannot be safely used before the
4899 -- object is initialized).
4902 Make_Object_Declaration (Loc,
4903 Defining_Identifier => ITable,
4904 Aliased_Present => True,
4905 Constant_Present => False,
4906 Object_Definition =>
4907 Make_Subtype_Indication (Loc,
4909 New_Reference_To (RTE (RE_Interface_Data), Loc),
4910 Constraint => Make_Index_Or_Discriminant_Constraint
4912 Constraints => New_List (
4913 Make_Integer_Literal (Loc, Num_Ifaces)))),
4915 Expression => Make_Aggregate (Loc,
4916 Expressions => New_List (
4917 Make_Integer_Literal (Loc, Num_Ifaces),
4918 Make_Aggregate (Loc,
4919 Expressions => TSD_Ifaces_List)))));
4922 Make_Attribute_Definition_Clause (Loc,
4923 Name => New_Reference_To (ITable, Loc),
4924 Chars => Name_Alignment,
4926 Make_Attribute_Reference (Loc,
4928 New_Reference_To (RTE (RE_Integer_Address), Loc),
4929 Attribute_Name => Name_Alignment)));
4932 Make_Attribute_Reference (Loc,
4933 Prefix => New_Reference_To (ITable, Loc),
4934 Attribute_Name => Name_Unchecked_Access);
4938 Append_To (TSD_Aggr_List, Iface_Table_Node);
4941 -- Generate the Select Specific Data table for synchronized types that
4942 -- implement synchronized interfaces. The size of the table is
4943 -- constrained by the number of non-predefined primitive operations.
4945 if RTE_Record_Component_Available (RE_SSD) then
4946 if Ada_Version >= Ada_05
4947 and then Has_DT (Typ)
4948 and then Is_Concurrent_Record_Type (Typ)
4949 and then Has_Interfaces (Typ)
4950 and then Nb_Prim > 0
4951 and then not Is_Abstract_Type (Typ)
4952 and then not Is_Controlled (Typ)
4953 and then not Restriction_Active (No_Dispatching_Calls)
4954 and then not Restriction_Active (No_Select_Statements)
4957 Make_Object_Declaration (Loc,
4958 Defining_Identifier => SSD,
4959 Aliased_Present => True,
4960 Object_Definition =>
4961 Make_Subtype_Indication (Loc,
4962 Subtype_Mark => New_Reference_To (
4963 RTE (RE_Select_Specific_Data), Loc),
4965 Make_Index_Or_Discriminant_Constraint (Loc,
4966 Constraints => New_List (
4967 Make_Integer_Literal (Loc, Nb_Prim))))));
4970 Make_Attribute_Definition_Clause (Loc,
4971 Name => New_Reference_To (SSD, Loc),
4972 Chars => Name_Alignment,
4974 Make_Attribute_Reference (Loc,
4976 New_Reference_To (RTE (RE_Integer_Address), Loc),
4977 Attribute_Name => Name_Alignment)));
4979 -- This table is initialized by Make_Select_Specific_Data_Table,
4980 -- which calls Set_Entry_Index and Set_Prim_Op_Kind.
4982 Append_To (TSD_Aggr_List,
4983 Make_Attribute_Reference (Loc,
4984 Prefix => New_Reference_To (SSD, Loc),
4985 Attribute_Name => Name_Unchecked_Access));
4987 Append_To (TSD_Aggr_List, Make_Null (Loc));
4991 -- Initialize the table of ancestor tags. In case of interface types
4992 -- this table is not needed.
4994 TSD_Tags_List := New_List;
4996 -- If we are not statically allocating the dispatch table then we must
4997 -- fill position 0 with null because we still have not generated the
5000 if not Building_Static_DT (Typ)
5001 or else Is_Interface (Typ)
5003 Append_To (TSD_Tags_List,
5004 Unchecked_Convert_To (RTE (RE_Tag),
5005 New_Reference_To (RTE (RE_Null_Address), Loc)));
5007 -- Otherwise we can safely reference the tag
5010 Append_To (TSD_Tags_List,
5011 New_Reference_To (DT_Ptr, Loc));
5014 -- Fill the rest of the table with the tags of the ancestors
5017 Current_Typ : Entity_Id;
5018 Parent_Typ : Entity_Id;
5026 Parent_Typ := Etype (Current_Typ);
5028 if Is_Private_Type (Parent_Typ) then
5029 Parent_Typ := Full_View (Base_Type (Parent_Typ));
5032 exit when Parent_Typ = Current_Typ;
5034 if Is_CPP_Class (Parent_Typ)
5035 or else Is_Interface (Typ)
5037 -- The tags defined in the C++ side will be inherited when
5038 -- the object is constructed (Exp_Ch3.Build_Init_Procedure)
5040 Append_To (TSD_Tags_List,
5041 Unchecked_Convert_To (RTE (RE_Tag),
5042 New_Reference_To (RTE (RE_Null_Address), Loc)));
5044 Append_To (TSD_Tags_List,
5046 (Node (First_Elmt (Access_Disp_Table (Parent_Typ))),
5051 Current_Typ := Parent_Typ;
5054 pragma Assert (Pos = I_Depth + 1);
5057 Append_To (TSD_Aggr_List,
5058 Make_Aggregate (Loc,
5059 Expressions => TSD_Tags_List));
5061 -- Build the TSD object
5064 Make_Object_Declaration (Loc,
5065 Defining_Identifier => TSD,
5066 Aliased_Present => True,
5067 Constant_Present => Building_Static_DT (Typ),
5068 Object_Definition =>
5069 Make_Subtype_Indication (Loc,
5070 Subtype_Mark => New_Reference_To (
5071 RTE (RE_Type_Specific_Data), Loc),
5073 Make_Index_Or_Discriminant_Constraint (Loc,
5074 Constraints => New_List (
5075 Make_Integer_Literal (Loc, I_Depth)))),
5077 Expression => Make_Aggregate (Loc,
5078 Expressions => TSD_Aggr_List)));
5080 Set_Is_True_Constant (TSD, Building_Static_DT (Typ));
5083 Make_Attribute_Definition_Clause (Loc,
5084 Name => New_Reference_To (TSD, Loc),
5085 Chars => Name_Alignment,
5087 Make_Attribute_Reference (Loc,
5088 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
5089 Attribute_Name => Name_Alignment)));
5091 -- Initialize or declare the dispatch table object
5093 if not Has_DT (Typ) then
5094 DT_Constr_List := New_List;
5095 DT_Aggr_List := New_List;
5100 Make_Attribute_Reference (Loc,
5101 Prefix => New_Reference_To (TSD, Loc),
5102 Attribute_Name => Name_Address);
5104 Append_To (DT_Constr_List, New_Node);
5105 Append_To (DT_Aggr_List, New_Copy (New_Node));
5106 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
5108 -- In case of locally defined tagged types we have already declared
5109 -- and uninitialized object for the dispatch table, which is now
5110 -- initialized by means of the following assignment:
5112 -- DT := (TSD'Address, 0);
5114 if not Building_Static_DT (Typ) then
5116 Make_Assignment_Statement (Loc,
5117 Name => New_Reference_To (DT, Loc),
5118 Expression => Make_Aggregate (Loc,
5119 Expressions => DT_Aggr_List)));
5121 -- In case of library level tagged types we declare and export now
5122 -- the constant object containing the dummy dispatch table. There
5123 -- is no need to declare the tag here because it has been previously
5124 -- declared by Make_Tags
5126 -- DT : aliased constant No_Dispatch_Table :=
5127 -- (NDT_TSD => TSD'Address;
5128 -- NDT_Prims_Ptr => 0);
5129 -- for DT'Alignment use Address'Alignment;
5133 Make_Object_Declaration (Loc,
5134 Defining_Identifier => DT,
5135 Aliased_Present => True,
5136 Constant_Present => True,
5137 Object_Definition =>
5138 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc),
5139 Expression => Make_Aggregate (Loc,
5140 Expressions => DT_Aggr_List)));
5142 -- Generate the SCIL node for the previous object declaration
5143 -- because it has a null dispatch table.
5145 if Generate_SCIL then
5146 Insert_Before (Last (Result),
5148 (SN_Kind => Dispatch_Table_Object_Init,
5149 Related_Node => Last (Result),
5154 Make_Attribute_Definition_Clause (Loc,
5155 Name => New_Reference_To (DT, Loc),
5156 Chars => Name_Alignment,
5158 Make_Attribute_Reference (Loc,
5160 New_Reference_To (RTE (RE_Integer_Address), Loc),
5161 Attribute_Name => Name_Alignment)));
5163 Export_DT (Typ, DT);
5166 -- Common case: Typ has a dispatch table
5170 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
5171 -- (predef-prim-op-1'address,
5172 -- predef-prim-op-2'address,
5174 -- predef-prim-op-n'address);
5175 -- for Predef_Prims'Alignment use Address'Alignment
5177 -- DT : Dispatch_Table (Nb_Prims) :=
5178 -- (Signature => <sig-value>,
5179 -- Tag_Kind => <tag_kind-value>,
5180 -- Predef_Prims => Predef_Prims'First'Address,
5181 -- Offset_To_Top => 0,
5182 -- TSD => TSD'Address;
5183 -- Prims_Ptr => (prim-op-1'address,
5184 -- prim-op-2'address,
5186 -- prim-op-n'address));
5187 -- for DT'Alignment use Address'Alignment
5194 if not Building_Static_DT (Typ) then
5195 Nb_Predef_Prims := Max_Predef_Prims;
5198 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5199 while Present (Prim_Elmt) loop
5200 Prim := Node (Prim_Elmt);
5202 if Is_Predefined_Dispatching_Operation (Prim)
5203 and then not Is_Abstract_Subprogram (Prim)
5205 Pos := UI_To_Int (DT_Position (Prim));
5207 if Pos > Nb_Predef_Prims then
5208 Nb_Predef_Prims := Pos;
5212 Next_Elmt (Prim_Elmt);
5218 (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
5223 Prim_Ops_Aggr_List := New_List;
5225 Prim_Table := (others => Empty);
5227 if Building_Static_DT (Typ) then
5228 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5229 while Present (Prim_Elmt) loop
5230 Prim := Node (Prim_Elmt);
5232 if Is_Predefined_Dispatching_Operation (Prim)
5233 and then not Is_Abstract_Subprogram (Prim)
5234 and then not Present (Prim_Table
5235 (UI_To_Int (DT_Position (Prim))))
5238 while Present (Alias (E)) loop
5242 pragma Assert (not Is_Abstract_Subprogram (E));
5243 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
5246 Next_Elmt (Prim_Elmt);
5250 for J in Prim_Table'Range loop
5251 if Present (Prim_Table (J)) then
5253 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
5254 Make_Attribute_Reference (Loc,
5255 Prefix => New_Reference_To (Prim_Table (J), Loc),
5256 Attribute_Name => Name_Unrestricted_Access));
5258 New_Node := Make_Null (Loc);
5261 Append_To (Prim_Ops_Aggr_List, New_Node);
5265 Make_Aggregate (Loc,
5266 Expressions => Prim_Ops_Aggr_List);
5269 Make_Subtype_Declaration (Loc,
5270 Defining_Identifier =>
5271 Make_Defining_Identifier (Loc,
5272 New_Internal_Name ('S')),
5273 Subtype_Indication =>
5274 New_Reference_To (RTE (RE_Address_Array), Loc));
5276 Append_To (Result, Decl);
5279 Make_Object_Declaration (Loc,
5280 Defining_Identifier => Predef_Prims,
5281 Aliased_Present => True,
5282 Constant_Present => Building_Static_DT (Typ),
5283 Object_Definition => New_Reference_To
5284 (Defining_Identifier (Decl), Loc),
5285 Expression => New_Node));
5287 -- Remember aggregates initializing dispatch tables
5289 Append_Elmt (New_Node, DT_Aggr);
5292 Make_Attribute_Definition_Clause (Loc,
5293 Name => New_Reference_To (Predef_Prims, Loc),
5294 Chars => Name_Alignment,
5296 Make_Attribute_Reference (Loc,
5298 New_Reference_To (RTE (RE_Integer_Address), Loc),
5299 Attribute_Name => Name_Alignment)));
5303 -- Stage 1: Initialize the discriminant and the record components
5305 DT_Constr_List := New_List;
5306 DT_Aggr_List := New_List;
5308 -- Num_Prims. If the tagged type has no primitives we add a dummy
5309 -- slot whose address will be the tag of this type.
5312 New_Node := Make_Integer_Literal (Loc, 1);
5314 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
5317 Append_To (DT_Constr_List, New_Node);
5318 Append_To (DT_Aggr_List, New_Copy (New_Node));
5322 if RTE_Record_Component_Available (RE_Signature) then
5323 Append_To (DT_Aggr_List,
5324 New_Reference_To (RTE (RE_Primary_DT), Loc));
5329 if RTE_Record_Component_Available (RE_Tag_Kind) then
5330 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
5335 Append_To (DT_Aggr_List,
5336 Make_Attribute_Reference (Loc,
5337 Prefix => New_Reference_To (Predef_Prims, Loc),
5338 Attribute_Name => Name_Address));
5342 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
5346 Append_To (DT_Aggr_List,
5347 Make_Attribute_Reference (Loc,
5348 Prefix => New_Reference_To (TSD, Loc),
5349 Attribute_Name => Name_Address));
5351 -- Stage 2: Initialize the table of primitive operations
5353 Prim_Ops_Aggr_List := New_List;
5356 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
5358 elsif not Building_Static_DT (Typ) then
5359 for J in 1 .. Nb_Prim loop
5360 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
5365 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
5368 Prim_Elmt : Elmt_Id;
5371 Prim_Table := (others => Empty);
5373 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5374 while Present (Prim_Elmt) loop
5375 Prim := Node (Prim_Elmt);
5377 -- Retrieve the ultimate alias of the primitive for proper
5378 -- handling of renamings and eliminated primitives.
5380 E := Ultimate_Alias (Prim);
5382 if Is_Imported (Prim)
5383 or else Present (Interface_Alias (Prim))
5384 or else Is_Predefined_Dispatching_Operation (Prim)
5385 or else Is_Eliminated (E)
5390 if not Is_Predefined_Dispatching_Operation (E)
5391 and then not Is_Abstract_Subprogram (E)
5392 and then not Present (Interface_Alias (E))
5395 (UI_To_Int (DT_Position (Prim)) <= Nb_Prim);
5397 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
5401 Next_Elmt (Prim_Elmt);
5404 for J in Prim_Table'Range loop
5405 if Present (Prim_Table (J)) then
5407 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
5408 Make_Attribute_Reference (Loc,
5409 Prefix => New_Reference_To (Prim_Table (J), Loc),
5410 Attribute_Name => Name_Unrestricted_Access));
5412 New_Node := Make_Null (Loc);
5415 Append_To (Prim_Ops_Aggr_List, New_Node);
5421 Make_Aggregate (Loc,
5422 Expressions => Prim_Ops_Aggr_List);
5424 Append_To (DT_Aggr_List, New_Node);
5426 -- Remember aggregates initializing dispatch tables
5428 Append_Elmt (New_Node, DT_Aggr);
5430 -- In case of locally defined tagged types we have already declared
5431 -- and uninitialized object for the dispatch table, which is now
5432 -- initialized by means of an assignment.
5434 if not Building_Static_DT (Typ) then
5436 Make_Assignment_Statement (Loc,
5437 Name => New_Reference_To (DT, Loc),
5438 Expression => Make_Aggregate (Loc,
5439 Expressions => DT_Aggr_List)));
5441 -- In case of library level tagged types we declare now and export
5442 -- the constant object containing the dispatch table.
5446 Make_Object_Declaration (Loc,
5447 Defining_Identifier => DT,
5448 Aliased_Present => True,
5449 Constant_Present => True,
5450 Object_Definition =>
5451 Make_Subtype_Indication (Loc,
5452 Subtype_Mark => New_Reference_To
5453 (RTE (RE_Dispatch_Table_Wrapper), Loc),
5454 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
5455 Constraints => DT_Constr_List)),
5456 Expression => Make_Aggregate (Loc,
5457 Expressions => DT_Aggr_List)));
5459 -- Generate the SCIL node for the previous object declaration
5460 -- because it contains a dispatch table.
5462 if Generate_SCIL then
5463 Insert_Before (Last (Result),
5465 (SN_Kind => Dispatch_Table_Object_Init,
5466 Related_Node => Last (Result),
5471 Make_Attribute_Definition_Clause (Loc,
5472 Name => New_Reference_To (DT, Loc),
5473 Chars => Name_Alignment,
5475 Make_Attribute_Reference (Loc,
5477 New_Reference_To (RTE (RE_Integer_Address), Loc),
5478 Attribute_Name => Name_Alignment)));
5480 Export_DT (Typ, DT);
5484 -- Initialize the table of ancestor tags if not building static
5487 if not Building_Static_DT (Typ)
5488 and then not Is_Interface (Typ)
5489 and then not Is_CPP_Class (Typ)
5492 Make_Assignment_Statement (Loc,
5494 Make_Indexed_Component (Loc,
5496 Make_Selected_Component (Loc,
5498 New_Reference_To (TSD, Loc),
5501 (RTE_Record_Component (RE_Tags_Table), Loc)),
5503 New_List (Make_Integer_Literal (Loc, 0))),
5507 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)));
5510 -- Inherit the dispatch tables of the parent. There is no need to
5511 -- inherit anything from the parent when building static dispatch tables
5512 -- because the whole dispatch table (including inherited primitives) has
5513 -- been already built.
5515 if Building_Static_DT (Typ) then
5518 -- If the ancestor is a CPP_Class type we inherit the dispatch tables
5519 -- in the init proc, and we don't need to fill them in here.
5521 elsif Is_CPP_Class (Parent_Typ) then
5524 -- Otherwise we fill in the dispatch tables here
5527 if Typ /= Parent_Typ
5528 and then not Is_Interface (Typ)
5529 and then not Restriction_Active (No_Dispatching_Calls)
5531 -- Inherit the dispatch table
5533 if not Is_Interface (Typ)
5534 and then not Is_Interface (Parent_Typ)
5535 and then not Is_CPP_Class (Parent_Typ)
5538 Nb_Prims : constant Int :=
5539 UI_To_Int (DT_Entry_Count
5540 (First_Tag_Component (Parent_Typ)));
5543 Append_To (Elab_Code,
5544 Build_Inherit_Predefined_Prims (Loc,
5550 (Access_Disp_Table (Parent_Typ)))), Loc),
5556 (Access_Disp_Table (Typ)))), Loc)));
5558 if Nb_Prims /= 0 then
5559 Append_To (Elab_Code,
5560 Build_Inherit_Prims (Loc,
5566 (Access_Disp_Table (Parent_Typ))), Loc),
5567 New_Tag_Node => New_Reference_To (DT_Ptr, Loc),
5568 Num_Prims => Nb_Prims));
5573 -- Inherit the secondary dispatch tables of the ancestor
5575 if not Is_CPP_Class (Parent_Typ) then
5577 Sec_DT_Ancestor : Elmt_Id :=
5581 (Access_Disp_Table (Parent_Typ))));
5582 Sec_DT_Typ : Elmt_Id :=
5586 (Access_Disp_Table (Typ))));
5588 procedure Copy_Secondary_DTs (Typ : Entity_Id);
5589 -- Local procedure required to climb through the ancestors
5590 -- and copy the contents of all their secondary dispatch
5593 ------------------------
5594 -- Copy_Secondary_DTs --
5595 ------------------------
5597 procedure Copy_Secondary_DTs (Typ : Entity_Id) is
5602 -- Climb to the ancestor (if any) handling private types
5604 if Present (Full_View (Etype (Typ))) then
5605 if Full_View (Etype (Typ)) /= Typ then
5606 Copy_Secondary_DTs (Full_View (Etype (Typ)));
5609 elsif Etype (Typ) /= Typ then
5610 Copy_Secondary_DTs (Etype (Typ));
5613 if Present (Interfaces (Typ))
5614 and then not Is_Empty_Elmt_List (Interfaces (Typ))
5616 Iface := First_Elmt (Interfaces (Typ));
5617 E := First_Entity (Typ);
5619 and then Present (Node (Sec_DT_Ancestor))
5620 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
5622 if Is_Tag (E) and then Chars (E) /= Name_uTag then
5624 Num_Prims : constant Int :=
5625 UI_To_Int (DT_Entry_Count (E));
5628 if not Is_Interface (Etype (Typ)) then
5630 -- Inherit first secondary dispatch table
5632 Append_To (Elab_Code,
5633 Build_Inherit_Predefined_Prims (Loc,
5635 Unchecked_Convert_To (RTE (RE_Tag),
5638 (Next_Elmt (Sec_DT_Ancestor)),
5641 Unchecked_Convert_To (RTE (RE_Tag),
5643 (Node (Next_Elmt (Sec_DT_Typ)),
5646 if Num_Prims /= 0 then
5647 Append_To (Elab_Code,
5648 Build_Inherit_Prims (Loc,
5649 Typ => Node (Iface),
5651 Unchecked_Convert_To
5654 (Node (Sec_DT_Ancestor),
5657 Unchecked_Convert_To
5660 (Node (Sec_DT_Typ), Loc)),
5661 Num_Prims => Num_Prims));
5665 Next_Elmt (Sec_DT_Ancestor);
5666 Next_Elmt (Sec_DT_Typ);
5668 -- Skip the secondary dispatch table of
5669 -- predefined primitives
5671 Next_Elmt (Sec_DT_Ancestor);
5672 Next_Elmt (Sec_DT_Typ);
5674 if not Is_Interface (Etype (Typ)) then
5676 -- Inherit second secondary dispatch table
5678 Append_To (Elab_Code,
5679 Build_Inherit_Predefined_Prims (Loc,
5681 Unchecked_Convert_To (RTE (RE_Tag),
5684 (Next_Elmt (Sec_DT_Ancestor)),
5687 Unchecked_Convert_To (RTE (RE_Tag),
5689 (Node (Next_Elmt (Sec_DT_Typ)),
5692 if Num_Prims /= 0 then
5693 Append_To (Elab_Code,
5694 Build_Inherit_Prims (Loc,
5695 Typ => Node (Iface),
5697 Unchecked_Convert_To
5700 (Node (Sec_DT_Ancestor),
5703 Unchecked_Convert_To
5706 (Node (Sec_DT_Typ), Loc)),
5707 Num_Prims => Num_Prims));
5712 Next_Elmt (Sec_DT_Ancestor);
5713 Next_Elmt (Sec_DT_Typ);
5715 -- Skip the secondary dispatch table of
5716 -- predefined primitives
5718 Next_Elmt (Sec_DT_Ancestor);
5719 Next_Elmt (Sec_DT_Typ);
5727 end Copy_Secondary_DTs;
5730 if Present (Node (Sec_DT_Ancestor))
5731 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
5733 -- Handle private types
5735 if Present (Full_View (Typ)) then
5736 Copy_Secondary_DTs (Full_View (Typ));
5738 Copy_Secondary_DTs (Typ);
5746 -- Generate code to register the Tag in the External_Tag hash table for
5747 -- the pure Ada type only.
5749 -- Register_Tag (Dt_Ptr);
5751 -- Skip this action in the following cases:
5752 -- 1) if Register_Tag is not available.
5753 -- 2) in No_Run_Time mode.
5754 -- 3) if Typ is not defined at the library level (this is required
5755 -- to avoid adding concurrency control to the hash table used
5756 -- by the run-time to register the tags).
5758 if not No_Run_Time_Mode
5759 and then Is_Library_Level_Entity (Typ)
5760 and then RTE_Available (RE_Register_Tag)
5762 Append_To (Elab_Code,
5763 Make_Procedure_Call_Statement (Loc,
5764 Name => New_Reference_To (RTE (RE_Register_Tag), Loc),
5765 Parameter_Associations =>
5766 New_List (New_Reference_To (DT_Ptr, Loc))));
5769 if not Is_Empty_List (Elab_Code) then
5770 Append_List_To (Result, Elab_Code);
5773 -- Populate the two auxiliary tables used for dispatching asynchronous,
5774 -- conditional and timed selects for synchronized types that implement
5775 -- a limited interface. Skip this step in Ravenscar profile or when
5776 -- general dispatching is forbidden.
5778 if Ada_Version >= Ada_05
5779 and then Is_Concurrent_Record_Type (Typ)
5780 and then Has_Interfaces (Typ)
5781 and then not Restriction_Active (No_Dispatching_Calls)
5782 and then not Restriction_Active (No_Select_Statements)
5784 Append_List_To (Result,
5785 Make_Select_Specific_Data_Table (Typ));
5788 -- Remember entities containing dispatch tables
5790 Append_Elmt (Predef_Prims, DT_Decl);
5791 Append_Elmt (DT, DT_Decl);
5793 Analyze_List (Result, Suppress => All_Checks);
5794 Set_Has_Dispatch_Table (Typ);
5796 -- Mark entities containing dispatch tables. Required by the backend to
5797 -- handle them properly.
5799 if not Is_Interface (Typ) then
5804 -- Ensure that entities Prim_Ptr and Predef_Prims_Table_Ptr have
5805 -- the decoration required by the backend
5807 Set_Is_Dispatch_Table_Entity (RTE (RE_Prim_Ptr));
5808 Set_Is_Dispatch_Table_Entity (RTE (RE_Predef_Prims_Table_Ptr));
5810 -- Object declarations
5812 Elmt := First_Elmt (DT_Decl);
5813 while Present (Elmt) loop
5814 Set_Is_Dispatch_Table_Entity (Node (Elmt));
5815 pragma Assert (Ekind (Etype (Node (Elmt))) = E_Array_Subtype
5816 or else Ekind (Etype (Node (Elmt))) = E_Record_Subtype);
5817 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
5821 -- Aggregates initializing dispatch tables
5823 Elmt := First_Elmt (DT_Aggr);
5824 while Present (Elmt) loop
5825 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
5834 -------------------------------------
5835 -- Make_Select_Specific_Data_Table --
5836 -------------------------------------
5838 function Make_Select_Specific_Data_Table
5839 (Typ : Entity_Id) return List_Id
5841 Assignments : constant List_Id := New_List;
5842 Loc : constant Source_Ptr := Sloc (Typ);
5844 Conc_Typ : Entity_Id;
5848 Prim_Als : Entity_Id;
5849 Prim_Elmt : Elmt_Id;
5853 type Examined_Array is array (Int range <>) of Boolean;
5855 function Find_Entry_Index (E : Entity_Id) return Uint;
5856 -- Given an entry, find its index in the visible declarations of the
5857 -- corresponding concurrent type of Typ.
5859 ----------------------
5860 -- Find_Entry_Index --
5861 ----------------------
5863 function Find_Entry_Index (E : Entity_Id) return Uint is
5864 Index : Uint := Uint_1;
5865 Subp_Decl : Entity_Id;
5869 and then not Is_Empty_List (Decls)
5871 Subp_Decl := First (Decls);
5872 while Present (Subp_Decl) loop
5873 if Nkind (Subp_Decl) = N_Entry_Declaration then
5874 if Defining_Identifier (Subp_Decl) = E then
5886 end Find_Entry_Index;
5888 -- Start of processing for Make_Select_Specific_Data_Table
5891 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
5893 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
5895 if Present (Corresponding_Concurrent_Type (Typ)) then
5896 Conc_Typ := Corresponding_Concurrent_Type (Typ);
5898 if Present (Full_View (Conc_Typ)) then
5899 Conc_Typ := Full_View (Conc_Typ);
5902 if Ekind (Conc_Typ) = E_Protected_Type then
5903 Decls := Visible_Declarations (Protected_Definition (
5904 Parent (Conc_Typ)));
5906 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
5907 Decls := Visible_Declarations (Task_Definition (
5908 Parent (Conc_Typ)));
5912 -- Count the non-predefined primitive operations
5914 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5915 while Present (Prim_Elmt) loop
5916 Prim := Node (Prim_Elmt);
5918 if not (Is_Predefined_Dispatching_Operation (Prim)
5919 or else Is_Predefined_Dispatching_Alias (Prim))
5921 Nb_Prim := Nb_Prim + 1;
5924 Next_Elmt (Prim_Elmt);
5928 Examined : Examined_Array (1 .. Nb_Prim) := (others => False);
5931 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5932 while Present (Prim_Elmt) loop
5933 Prim := Node (Prim_Elmt);
5935 -- Look for primitive overriding an abstract interface subprogram
5937 if Present (Interface_Alias (Prim))
5938 and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
5940 Prim_Pos := DT_Position (Alias (Prim));
5941 pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
5942 Examined (UI_To_Int (Prim_Pos)) := True;
5944 -- Set the primitive operation kind regardless of subprogram
5946 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
5948 Append_To (Assignments,
5949 Make_Procedure_Call_Statement (Loc,
5950 Name => New_Reference_To (RTE (RE_Set_Prim_Op_Kind), Loc),
5951 Parameter_Associations => New_List (
5952 New_Reference_To (DT_Ptr, Loc),
5953 Make_Integer_Literal (Loc, Prim_Pos),
5954 Prim_Op_Kind (Alias (Prim), Typ))));
5956 -- Retrieve the root of the alias chain
5959 while Present (Alias (Prim_Als)) loop
5960 Prim_Als := Alias (Prim_Als);
5963 -- In the case of an entry wrapper, set the entry index
5965 if Ekind (Prim) = E_Procedure
5966 and then Is_Primitive_Wrapper (Prim_Als)
5967 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
5970 -- Ada.Tags.Set_Entry_Index
5971 -- (DT_Ptr, <position>, <index>);
5973 Append_To (Assignments,
5974 Make_Procedure_Call_Statement (Loc,
5976 New_Reference_To (RTE (RE_Set_Entry_Index), Loc),
5977 Parameter_Associations => New_List (
5978 New_Reference_To (DT_Ptr, Loc),
5979 Make_Integer_Literal (Loc, Prim_Pos),
5980 Make_Integer_Literal (Loc,
5981 Find_Entry_Index (Wrapped_Entity (Prim_Als))))));
5985 Next_Elmt (Prim_Elmt);
5990 end Make_Select_Specific_Data_Table;
5996 function Make_Tags (Typ : Entity_Id) return List_Id is
5997 Loc : constant Source_Ptr := Sloc (Typ);
5998 Result : constant List_Id := New_List;
6001 (Tag_Typ : Entity_Id;
6003 Is_Secondary_DT : Boolean);
6004 -- Import the dispatch table DT of tagged type Tag_Typ. Required to
6005 -- generate forward references and statically allocate the table. For
6006 -- primary dispatch tables that require no dispatch table generate:
6007 -- DT : static aliased constant Non_Dispatch_Table_Wrapper;
6008 -- $pragma import (ada, DT);
6009 -- Otherwise generate:
6010 -- DT : static aliased constant Dispatch_Table_Wrapper (Nb_Prim);
6011 -- $pragma import (ada, DT);
6018 (Tag_Typ : Entity_Id;
6020 Is_Secondary_DT : Boolean)
6022 DT_Constr_List : List_Id;
6026 Set_Is_Imported (DT);
6027 Set_Ekind (DT, E_Constant);
6028 Set_Related_Type (DT, Typ);
6030 -- The scope must be set now to call Get_External_Name
6032 Set_Scope (DT, Current_Scope);
6034 Get_External_Name (DT, True);
6035 Set_Interface_Name (DT,
6036 Make_String_Literal (Loc,
6037 Strval => String_From_Name_Buffer));
6039 -- Ensure proper Sprint output of this implicit importation
6041 Set_Is_Internal (DT);
6043 -- Save this entity to allow Make_DT to generate its exportation
6045 Append_Elmt (DT, Dispatch_Table_Wrappers (Typ));
6047 -- No dispatch table required
6049 if not Is_Secondary_DT
6050 and then not Has_DT (Tag_Typ)
6053 Make_Object_Declaration (Loc,
6054 Defining_Identifier => DT,
6055 Aliased_Present => True,
6056 Constant_Present => True,
6057 Object_Definition =>
6058 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
6061 -- Calculate the number of primitives of the dispatch table and
6062 -- the size of the Type_Specific_Data record.
6065 UI_To_Int (DT_Entry_Count (First_Tag_Component (Tag_Typ)));
6067 -- If the tagged type has no primitives we add a dummy slot
6068 -- whose address will be the tag of this type.
6072 New_List (Make_Integer_Literal (Loc, 1));
6075 New_List (Make_Integer_Literal (Loc, Nb_Prim));
6079 Make_Object_Declaration (Loc,
6080 Defining_Identifier => DT,
6081 Aliased_Present => True,
6082 Constant_Present => True,
6083 Object_Definition =>
6084 Make_Subtype_Indication (Loc,
6086 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
6087 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
6088 Constraints => DT_Constr_List))));
6094 Tname : constant Name_Id := Chars (Typ);
6095 AI_Tag_Comp : Elmt_Id;
6098 Predef_Prims_Ptr : Node_Id;
6100 Iface_DT_Ptr : Node_Id;
6103 Typ_Comps : Elist_Id;
6105 -- Start of processing for Make_Tags
6108 -- 1) Generate the primary and secondary tag entities
6110 -- Collect the components associated with secondary dispatch tables
6112 if Has_Interfaces (Typ) then
6113 Collect_Interface_Components (Typ, Typ_Comps);
6116 -- 1) Generate the primary tag entities
6118 -- Primary dispatch table containing user-defined primitives
6120 DT_Ptr := Make_Defining_Identifier (Loc,
6121 New_External_Name (Tname, 'P'));
6122 Set_Etype (DT_Ptr, RTE (RE_Tag));
6124 -- Primary dispatch table containing predefined primitives
6127 Make_Defining_Identifier (Loc,
6128 Chars => New_External_Name (Tname, 'Y'));
6129 Set_Etype (Predef_Prims_Ptr, RTE (RE_Address));
6131 -- Import the forward declaration of the Dispatch Table wrapper record
6132 -- (Make_DT will take care of its exportation)
6134 if Building_Static_DT (Typ) then
6135 Set_Dispatch_Table_Wrappers (Typ, New_Elmt_List);
6138 Make_Defining_Identifier (Loc,
6139 Chars => New_External_Name (Tname, 'T'));
6141 Import_DT (Typ, DT, Is_Secondary_DT => False);
6143 if Has_DT (Typ) then
6145 Make_Object_Declaration (Loc,
6146 Defining_Identifier => DT_Ptr,
6147 Constant_Present => True,
6148 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
6150 Unchecked_Convert_To (RTE (RE_Tag),
6151 Make_Attribute_Reference (Loc,
6153 Make_Selected_Component (Loc,
6154 Prefix => New_Reference_To (DT, Loc),
6157 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
6158 Attribute_Name => Name_Address))));
6160 -- Generate the SCIL node for the previous object declaration
6161 -- because it has a tag initialization.
6163 if Generate_SCIL then
6164 Insert_Before (Last (Result),
6166 (SN_Kind => Dispatch_Table_Tag_Init,
6167 Related_Node => Last (Result),
6172 Make_Object_Declaration (Loc,
6173 Defining_Identifier => Predef_Prims_Ptr,
6174 Constant_Present => True,
6175 Object_Definition => New_Reference_To
6176 (RTE (RE_Address), Loc),
6178 Make_Attribute_Reference (Loc,
6180 Make_Selected_Component (Loc,
6181 Prefix => New_Reference_To (DT, Loc),
6184 (RTE_Record_Component (RE_Predef_Prims), Loc)),
6185 Attribute_Name => Name_Address)));
6187 -- No dispatch table required
6191 Make_Object_Declaration (Loc,
6192 Defining_Identifier => DT_Ptr,
6193 Constant_Present => True,
6194 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
6196 Unchecked_Convert_To (RTE (RE_Tag),
6197 Make_Attribute_Reference (Loc,
6199 Make_Selected_Component (Loc,
6200 Prefix => New_Reference_To (DT, Loc),
6203 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
6204 Attribute_Name => Name_Address))));
6206 -- Generate the SCIL node for the previous object declaration
6207 -- because it has a tag initialization.
6209 if Generate_SCIL then
6210 Insert_Before (Last (Result),
6212 (SN_Kind => Dispatch_Table_Tag_Init,
6213 Related_Node => Last (Result),
6218 Set_Is_True_Constant (DT_Ptr);
6219 Set_Is_Statically_Allocated (DT_Ptr);
6222 pragma Assert (No (Access_Disp_Table (Typ)));
6223 Set_Access_Disp_Table (Typ, New_Elmt_List);
6224 Append_Elmt (DT_Ptr, Access_Disp_Table (Typ));
6225 Append_Elmt (Predef_Prims_Ptr, Access_Disp_Table (Typ));
6227 -- 2) Generate the secondary tag entities
6229 if Has_Interfaces (Typ) then
6231 -- Note: The following value of Suffix_Index must be in sync with
6232 -- the Suffix_Index values of secondary dispatch tables generated
6237 -- For each interface type we build an unique external name
6238 -- associated with its corresponding secondary dispatch table.
6239 -- This external name will be used to declare an object that
6240 -- references this secondary dispatch table, value that will be
6241 -- used for the elaboration of Typ's objects and also for the
6242 -- elaboration of objects of derivations of Typ that do not
6243 -- override the primitive operation of this interface type.
6245 AI_Tag_Comp := First_Elmt (Typ_Comps);
6246 while Present (AI_Tag_Comp) loop
6247 Get_Secondary_DT_External_Name
6248 (Typ, Related_Type (Node (AI_Tag_Comp)), Suffix_Index);
6249 Typ_Name := Name_Find;
6251 if Building_Static_DT (Typ) then
6253 Make_Defining_Identifier (Loc,
6254 Chars => New_External_Name
6255 (Typ_Name, 'T', Suffix_Index => -1));
6257 (Tag_Typ => Related_Type (Node (AI_Tag_Comp)),
6259 Is_Secondary_DT => True);
6262 -- Secondary dispatch table referencing thunks to user-defined
6263 -- primitives covered by this interface.
6266 Make_Defining_Identifier (Loc,
6267 Chars => New_External_Name (Typ_Name, 'P'));
6268 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
6269 Set_Ekind (Iface_DT_Ptr, E_Constant);
6270 Set_Is_Tag (Iface_DT_Ptr);
6271 Set_Has_Thunks (Iface_DT_Ptr);
6272 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6273 Is_Library_Level_Tagged_Type (Typ));
6274 Set_Is_True_Constant (Iface_DT_Ptr);
6276 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6277 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6279 if Building_Static_DT (Typ) then
6281 Make_Object_Declaration (Loc,
6282 Defining_Identifier => Iface_DT_Ptr,
6283 Constant_Present => True,
6284 Object_Definition => New_Reference_To
6285 (RTE (RE_Interface_Tag), Loc),
6287 Unchecked_Convert_To (RTE (RE_Interface_Tag),
6288 Make_Attribute_Reference (Loc,
6290 Make_Selected_Component (Loc,
6291 Prefix => New_Reference_To (Iface_DT, Loc),
6294 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
6295 Attribute_Name => Name_Address))));
6298 -- Secondary dispatch table referencing thunks to predefined
6302 Make_Defining_Identifier (Loc,
6303 Chars => New_External_Name (Typ_Name, 'Y'));
6304 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
6305 Set_Ekind (Iface_DT_Ptr, E_Constant);
6306 Set_Is_Tag (Iface_DT_Ptr);
6307 Set_Has_Thunks (Iface_DT_Ptr);
6308 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6309 Is_Library_Level_Tagged_Type (Typ));
6310 Set_Is_True_Constant (Iface_DT_Ptr);
6312 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6313 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6315 -- Secondary dispatch table referencing user-defined primitives
6316 -- covered by this interface.
6319 Make_Defining_Identifier (Loc,
6320 Chars => New_External_Name (Typ_Name, 'D'));
6321 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
6322 Set_Ekind (Iface_DT_Ptr, E_Constant);
6323 Set_Is_Tag (Iface_DT_Ptr);
6324 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6325 Is_Library_Level_Tagged_Type (Typ));
6326 Set_Is_True_Constant (Iface_DT_Ptr);
6328 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6329 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6331 -- Secondary dispatch table referencing predefined primitives
6334 Make_Defining_Identifier (Loc,
6335 Chars => New_External_Name (Typ_Name, 'Z'));
6336 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
6337 Set_Ekind (Iface_DT_Ptr, E_Constant);
6338 Set_Is_Tag (Iface_DT_Ptr);
6339 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6340 Is_Library_Level_Tagged_Type (Typ));
6341 Set_Is_True_Constant (Iface_DT_Ptr);
6343 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6344 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6346 Next_Elmt (AI_Tag_Comp);
6350 -- 3) At the end of Access_Disp_Table, if the type has user-defined
6351 -- primitives, we add the entity of an access type declaration that
6352 -- is used by Build_Get_Prim_Op_Address to expand dispatching calls
6353 -- through the primary dispatch table.
6355 if UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ))) = 0 then
6356 Analyze_List (Result);
6359 -- type Typ_DT is array (1 .. Nb_Prims) of Prim_Ptr;
6360 -- type Typ_DT_Acc is access Typ_DT;
6364 Name_DT_Prims : constant Name_Id :=
6365 New_External_Name (Tname, 'G');
6366 Name_DT_Prims_Acc : constant Name_Id :=
6367 New_External_Name (Tname, 'H');
6368 DT_Prims : constant Entity_Id :=
6369 Make_Defining_Identifier (Loc,
6371 DT_Prims_Acc : constant Entity_Id :=
6372 Make_Defining_Identifier (Loc,
6376 Make_Full_Type_Declaration (Loc,
6377 Defining_Identifier => DT_Prims,
6379 Make_Constrained_Array_Definition (Loc,
6380 Discrete_Subtype_Definitions => New_List (
6382 Low_Bound => Make_Integer_Literal (Loc, 1),
6383 High_Bound => Make_Integer_Literal (Loc,
6385 (First_Tag_Component (Typ))))),
6386 Component_Definition =>
6387 Make_Component_Definition (Loc,
6388 Subtype_Indication =>
6389 New_Reference_To (RTE (RE_Prim_Ptr), Loc)))));
6392 Make_Full_Type_Declaration (Loc,
6393 Defining_Identifier => DT_Prims_Acc,
6395 Make_Access_To_Object_Definition (Loc,
6396 Subtype_Indication =>
6397 New_Occurrence_Of (DT_Prims, Loc))));
6399 Append_Elmt (DT_Prims_Acc, Access_Disp_Table (Typ));
6401 -- Analyze the resulting list and suppress the generation of the
6402 -- Init_Proc associated with the above array declaration because
6403 -- this type is never used in object declarations. It is only used
6404 -- to simplify the expansion associated with dispatching calls.
6406 Analyze_List (Result);
6407 Set_Suppress_Init_Proc (Base_Type (DT_Prims));
6409 -- Mark entity of dispatch table. Required by the back end to
6410 -- handle them properly.
6412 Set_Is_Dispatch_Table_Entity (DT_Prims);
6416 Set_Ekind (DT_Ptr, E_Constant);
6417 Set_Is_Tag (DT_Ptr);
6418 Set_Related_Type (DT_Ptr, Typ);
6427 function New_Value (From : Node_Id) return Node_Id is
6428 Res : constant Node_Id := Duplicate_Subexpr (From);
6430 if Is_Access_Type (Etype (From)) then
6432 Make_Explicit_Dereference (Sloc (From),
6443 function New_SCIL_Node
6444 (SN_Kind : SCIL_Node_Kind;
6445 Related_Node : Node_Id;
6446 Entity : Entity_Id := Empty;
6447 Target_Prim : Entity_Id := Empty) return Node_Id
6449 New_N : constant Node_Id :=
6450 New_Node (N_Null_Statement, Sloc (Related_Node));
6452 Set_Is_SCIL_Node (New_N);
6454 Set_SCIL_Nkind (New_N, UI_From_Int (SCIL_Node_Kind'Pos (SN_Kind)));
6455 Set_SCIL_Related_Node (New_N, Related_Node);
6456 Set_SCIL_Entity (New_N, Entity);
6457 Set_SCIL_Target_Prim (New_N, Target_Prim);
6462 -----------------------------------
6463 -- Original_View_In_Visible_Part --
6464 -----------------------------------
6466 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
6467 Scop : constant Entity_Id := Scope (Typ);
6470 -- The scope must be a package
6472 if not Is_Package_Or_Generic_Package (Scop) then
6476 -- A type with a private declaration has a private view declared in
6477 -- the visible part.
6479 if Has_Private_Declaration (Typ) then
6483 return List_Containing (Parent (Typ)) =
6484 Visible_Declarations (Specification (Unit_Declaration_Node (Scop)));
6485 end Original_View_In_Visible_Part;
6491 function Prim_Op_Kind
6493 Typ : Entity_Id) return Node_Id
6495 Full_Typ : Entity_Id := Typ;
6496 Loc : constant Source_Ptr := Sloc (Prim);
6497 Prim_Op : Entity_Id;
6500 -- Retrieve the original primitive operation
6503 while Present (Alias (Prim_Op)) loop
6504 Prim_Op := Alias (Prim_Op);
6507 if Ekind (Typ) = E_Record_Type
6508 and then Present (Corresponding_Concurrent_Type (Typ))
6510 Full_Typ := Corresponding_Concurrent_Type (Typ);
6513 -- When a private tagged type is completed by a concurrent type,
6514 -- retrieve the full view.
6516 if Is_Private_Type (Full_Typ) then
6517 Full_Typ := Full_View (Full_Typ);
6520 if Ekind (Prim_Op) = E_Function then
6522 -- Protected function
6524 if Ekind (Full_Typ) = E_Protected_Type then
6525 return New_Reference_To (RTE (RE_POK_Protected_Function), Loc);
6529 elsif Ekind (Full_Typ) = E_Task_Type then
6530 return New_Reference_To (RTE (RE_POK_Task_Function), Loc);
6535 return New_Reference_To (RTE (RE_POK_Function), Loc);
6539 pragma Assert (Ekind (Prim_Op) = E_Procedure);
6541 if Ekind (Full_Typ) = E_Protected_Type then
6545 if Is_Primitive_Wrapper (Prim_Op)
6546 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
6548 return New_Reference_To (RTE (RE_POK_Protected_Entry), Loc);
6550 -- Protected procedure
6553 return New_Reference_To (RTE (RE_POK_Protected_Procedure), Loc);
6556 elsif Ekind (Full_Typ) = E_Task_Type then
6560 if Is_Primitive_Wrapper (Prim_Op)
6561 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
6563 return New_Reference_To (RTE (RE_POK_Task_Entry), Loc);
6565 -- Task "procedure". These are the internally Expander-generated
6566 -- procedures (task body for instance).
6569 return New_Reference_To (RTE (RE_POK_Task_Procedure), Loc);
6572 -- Regular procedure
6575 return New_Reference_To (RTE (RE_POK_Procedure), Loc);
6580 ------------------------
6581 -- Register_Primitive --
6582 ------------------------
6584 function Register_Primitive
6586 Prim : Entity_Id) return List_Id
6589 Iface_Prim : Entity_Id;
6590 Iface_Typ : Entity_Id;
6591 Iface_DT_Ptr : Entity_Id;
6592 Iface_DT_Elmt : Elmt_Id;
6593 L : constant List_Id := New_List;
6596 Tag_Typ : Entity_Id;
6597 Thunk_Id : Entity_Id;
6598 Thunk_Code : Node_Id;
6601 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
6603 if not RTE_Available (RE_Tag) then
6607 if not Present (Interface_Alias (Prim)) then
6608 Tag_Typ := Scope (DTC_Entity (Prim));
6609 Pos := DT_Position (Prim);
6610 Tag := First_Tag_Component (Tag_Typ);
6612 if Is_Predefined_Dispatching_Operation (Prim)
6613 or else Is_Predefined_Dispatching_Alias (Prim)
6616 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Tag_Typ))));
6619 Build_Set_Predefined_Prim_Op_Address (Loc,
6620 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6623 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6624 Make_Attribute_Reference (Loc,
6625 Prefix => New_Reference_To (Prim, Loc),
6626 Attribute_Name => Name_Unrestricted_Access))));
6628 -- Register copy of the pointer to the 'size primitive in the TSD
6630 if Chars (Prim) = Name_uSize
6631 and then RTE_Record_Component_Available (RE_Size_Func)
6633 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
6635 Build_Set_Size_Function (Loc,
6636 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6637 Size_Func => Prim));
6641 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
6643 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
6645 Build_Set_Prim_Op_Address (Loc,
6647 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6650 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6651 Make_Attribute_Reference (Loc,
6652 Prefix => New_Reference_To (Prim, Loc),
6653 Attribute_Name => Name_Unrestricted_Access))));
6656 -- Ada 2005 (AI-251): Primitive associated with an interface type
6657 -- Generate the code of the thunk only if the interface type is not an
6658 -- immediate ancestor of Typ; otherwise the dispatch table associated
6659 -- with the interface is the primary dispatch table and we have nothing
6663 Tag_Typ := Find_Dispatching_Type (Alias (Prim));
6664 Iface_Typ := Find_Dispatching_Type (Interface_Alias (Prim));
6666 pragma Assert (Is_Interface (Iface_Typ));
6668 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
6670 if not Is_Ancestor (Iface_Typ, Tag_Typ)
6671 and then Present (Thunk_Code)
6673 -- Generate the code necessary to fill the appropriate entry of
6674 -- the secondary dispatch table of Prim's controlling type with
6675 -- Thunk_Id's address.
6677 Iface_DT_Elmt := Find_Interface_ADT (Tag_Typ, Iface_Typ);
6678 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6679 pragma Assert (Has_Thunks (Iface_DT_Ptr));
6681 Iface_Prim := Interface_Alias (Prim);
6682 Pos := DT_Position (Iface_Prim);
6683 Tag := First_Tag_Component (Iface_Typ);
6685 Prepend_To (L, Thunk_Code);
6687 if Is_Predefined_Dispatching_Operation (Prim)
6688 or else Is_Predefined_Dispatching_Alias (Prim)
6691 Build_Set_Predefined_Prim_Op_Address (Loc,
6693 New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
6696 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6697 Make_Attribute_Reference (Loc,
6698 Prefix => New_Reference_To (Thunk_Id, Loc),
6699 Attribute_Name => Name_Unrestricted_Access))));
6701 Next_Elmt (Iface_DT_Elmt);
6702 Next_Elmt (Iface_DT_Elmt);
6703 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6704 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
6707 Build_Set_Predefined_Prim_Op_Address (Loc,
6709 New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
6712 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6713 Make_Attribute_Reference (Loc,
6714 Prefix => New_Reference_To (Alias (Prim), Loc),
6715 Attribute_Name => Name_Unrestricted_Access))));
6718 pragma Assert (Pos /= Uint_0
6719 and then Pos <= DT_Entry_Count (Tag));
6722 Build_Set_Prim_Op_Address (Loc,
6724 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
6727 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6728 Make_Attribute_Reference (Loc,
6729 Prefix => New_Reference_To (Thunk_Id, Loc),
6730 Attribute_Name => Name_Unrestricted_Access))));
6732 Next_Elmt (Iface_DT_Elmt);
6733 Next_Elmt (Iface_DT_Elmt);
6734 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6735 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
6738 Build_Set_Prim_Op_Address (Loc,
6740 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
6743 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6744 Make_Attribute_Reference (Loc,
6745 Prefix => New_Reference_To (Alias (Prim), Loc),
6746 Attribute_Name => Name_Unrestricted_Access))));
6753 end Register_Primitive;
6755 -------------------------
6756 -- Set_All_DT_Position --
6757 -------------------------
6759 procedure Set_All_DT_Position (Typ : Entity_Id) is
6761 procedure Validate_Position (Prim : Entity_Id);
6762 -- Check that the position assigned to Prim is completely safe
6763 -- (it has not been assigned to a previously defined primitive
6764 -- operation of Typ)
6766 -----------------------
6767 -- Validate_Position --
6768 -----------------------
6770 procedure Validate_Position (Prim : Entity_Id) is
6775 -- Aliased primitives are safe
6777 if Present (Alias (Prim)) then
6781 Op_Elmt := First_Elmt (Primitive_Operations (Typ));
6782 while Present (Op_Elmt) loop
6783 Op := Node (Op_Elmt);
6785 -- No need to check against itself
6790 -- Primitive operations covering abstract interfaces are
6793 elsif Present (Interface_Alias (Op)) then
6796 -- Predefined dispatching operations are completely safe. They
6797 -- are allocated at fixed positions in a separate table.
6799 elsif Is_Predefined_Dispatching_Operation (Op)
6800 or else Is_Predefined_Dispatching_Alias (Op)
6804 -- Aliased subprograms are safe
6806 elsif Present (Alias (Op)) then
6809 elsif DT_Position (Op) = DT_Position (Prim)
6810 and then not Is_Predefined_Dispatching_Operation (Op)
6811 and then not Is_Predefined_Dispatching_Operation (Prim)
6812 and then not Is_Predefined_Dispatching_Alias (Op)
6813 and then not Is_Predefined_Dispatching_Alias (Prim)
6816 -- Handle aliased subprograms
6825 if Present (Overridden_Operation (Op_1)) then
6826 Op_1 := Overridden_Operation (Op_1);
6827 elsif Present (Alias (Op_1)) then
6828 Op_1 := Alias (Op_1);
6836 if Present (Overridden_Operation (Op_2)) then
6837 Op_2 := Overridden_Operation (Op_2);
6838 elsif Present (Alias (Op_2)) then
6839 Op_2 := Alias (Op_2);
6845 if Op_1 /= Op_2 then
6846 raise Program_Error;
6851 Next_Elmt (Op_Elmt);
6853 end Validate_Position;
6857 Parent_Typ : constant Entity_Id := Etype (Typ);
6858 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
6859 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
6861 Adjusted : Boolean := False;
6862 Finalized : Boolean := False;
6868 Prim_Elmt : Elmt_Id;
6870 -- Start of processing for Set_All_DT_Position
6873 pragma Assert (Present (First_Tag_Component (Typ)));
6875 -- Set the DT_Position for each primitive operation. Perform some
6876 -- sanity checks to avoid to build completely inconsistent dispatch
6879 -- First stage: Set the DTC entity of all the primitive operations
6880 -- This is required to properly read the DT_Position attribute in
6881 -- the latter stages.
6883 Prim_Elmt := First_Prim;
6885 while Present (Prim_Elmt) loop
6886 Prim := Node (Prim_Elmt);
6888 -- Predefined primitives have a separate dispatch table
6890 if not (Is_Predefined_Dispatching_Operation (Prim)
6891 or else Is_Predefined_Dispatching_Alias (Prim))
6893 Count_Prim := Count_Prim + 1;
6896 Set_DTC_Entity_Value (Typ, Prim);
6898 -- Clear any previous value of the DT_Position attribute. In this
6899 -- way we ensure that the final position of all the primitives is
6900 -- established by the following stages of this algorithm.
6902 Set_DT_Position (Prim, No_Uint);
6904 Next_Elmt (Prim_Elmt);
6908 Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean :=
6913 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id);
6914 -- Called if Typ is declared in a nested package or a public child
6915 -- package to handle inherited primitives that were inherited by Typ
6916 -- in the visible part, but whose declaration was deferred because
6917 -- the parent operation was private and not visible at that point.
6919 procedure Set_Fixed_Prim (Pos : Nat);
6920 -- Sets to true an element of the Fixed_Prim table to indicate
6921 -- that this entry of the dispatch table of Typ is occupied.
6923 ------------------------------------------
6924 -- Handle_Inherited_Private_Subprograms --
6925 ------------------------------------------
6927 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id) is
6930 Op_Elmt_2 : Elmt_Id;
6931 Prim_Op : Entity_Id;
6932 Parent_Subp : Entity_Id;
6935 Op_List := Primitive_Operations (Typ);
6937 Op_Elmt := First_Elmt (Op_List);
6938 while Present (Op_Elmt) loop
6939 Prim_Op := Node (Op_Elmt);
6941 -- Search primitives that are implicit operations with an
6942 -- internal name whose parent operation has a normal name.
6944 if Present (Alias (Prim_Op))
6945 and then Find_Dispatching_Type (Alias (Prim_Op)) /= Typ
6946 and then not Comes_From_Source (Prim_Op)
6947 and then Is_Internal_Name (Chars (Prim_Op))
6948 and then not Is_Internal_Name (Chars (Alias (Prim_Op)))
6950 Parent_Subp := Alias (Prim_Op);
6952 -- Check if the type has an explicit overriding for this
6955 Op_Elmt_2 := Next_Elmt (Op_Elmt);
6956 while Present (Op_Elmt_2) loop
6957 if Chars (Node (Op_Elmt_2)) = Chars (Parent_Subp)
6958 and then Type_Conformant (Prim_Op, Node (Op_Elmt_2))
6960 Set_DT_Position (Prim_Op, DT_Position (Parent_Subp));
6961 Set_DT_Position (Node (Op_Elmt_2),
6962 DT_Position (Parent_Subp));
6963 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim_Op)));
6965 goto Next_Primitive;
6968 Next_Elmt (Op_Elmt_2);
6973 Next_Elmt (Op_Elmt);
6975 end Handle_Inherited_Private_Subprograms;
6977 --------------------
6978 -- Set_Fixed_Prim --
6979 --------------------
6981 procedure Set_Fixed_Prim (Pos : Nat) is
6983 pragma Assert (Pos <= Count_Prim);
6984 Fixed_Prim (Pos) := True;
6986 when Constraint_Error =>
6987 raise Program_Error;
6991 -- In case of nested packages and public child package it may be
6992 -- necessary a special management on inherited subprograms so that
6993 -- the dispatch table is properly filled.
6995 if Ekind (Scope (Scope (Typ))) = E_Package
6996 and then Scope (Scope (Typ)) /= Standard_Standard
6997 and then ((Is_Derived_Type (Typ) and then not Is_Private_Type (Typ))
6999 (Nkind (Parent (Typ)) = N_Private_Extension_Declaration
7000 and then Is_Generic_Type (Typ)))
7001 and then In_Open_Scopes (Scope (Etype (Typ)))
7002 and then Typ = Base_Type (Typ)
7004 Handle_Inherited_Private_Subprograms (Typ);
7007 -- Second stage: Register fixed entries
7010 Prim_Elmt := First_Prim;
7011 while Present (Prim_Elmt) loop
7012 Prim := Node (Prim_Elmt);
7014 -- Predefined primitives have a separate table and all its
7015 -- entries are at predefined fixed positions.
7017 if Is_Predefined_Dispatching_Operation (Prim) then
7018 Set_DT_Position (Prim, Default_Prim_Op_Position (Prim));
7020 elsif Is_Predefined_Dispatching_Alias (Prim) then
7022 while Present (Alias (E)) loop
7026 Set_DT_Position (Prim, Default_Prim_Op_Position (E));
7028 -- Overriding primitives of ancestor abstract interfaces
7030 elsif Present (Interface_Alias (Prim))
7031 and then Is_Ancestor
7032 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ)
7034 pragma Assert (DT_Position (Prim) = No_Uint
7035 and then Present (DTC_Entity (Interface_Alias (Prim))));
7037 E := Interface_Alias (Prim);
7038 Set_DT_Position (Prim, DT_Position (E));
7041 (DT_Position (Alias (Prim)) = No_Uint
7042 or else DT_Position (Alias (Prim)) = DT_Position (E));
7043 Set_DT_Position (Alias (Prim), DT_Position (E));
7044 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));
7046 -- Overriding primitives must use the same entry as the
7047 -- overridden primitive.
7049 elsif not Present (Interface_Alias (Prim))
7050 and then Present (Alias (Prim))
7051 and then Chars (Prim) = Chars (Alias (Prim))
7052 and then Find_Dispatching_Type (Alias (Prim)) /= Typ
7053 and then Is_Ancestor
7054 (Find_Dispatching_Type (Alias (Prim)), Typ)
7055 and then Present (DTC_Entity (Alias (Prim)))
7058 Set_DT_Position (Prim, DT_Position (E));
7060 if not Is_Predefined_Dispatching_Alias (E) then
7061 Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
7065 Next_Elmt (Prim_Elmt);
7068 -- Third stage: Fix the position of all the new primitives
7069 -- Entries associated with primitives covering interfaces
7070 -- are handled in a latter round.
7072 Prim_Elmt := First_Prim;
7073 while Present (Prim_Elmt) loop
7074 Prim := Node (Prim_Elmt);
7076 -- Skip primitives previously set entries
7078 if DT_Position (Prim) /= No_Uint then
7081 -- Primitives covering interface primitives are handled later
7083 elsif Present (Interface_Alias (Prim)) then
7087 -- Take the next available position in the DT
7090 Nb_Prim := Nb_Prim + 1;
7091 pragma Assert (Nb_Prim <= Count_Prim);
7092 exit when not Fixed_Prim (Nb_Prim);
7095 Set_DT_Position (Prim, UI_From_Int (Nb_Prim));
7096 Set_Fixed_Prim (Nb_Prim);
7099 Next_Elmt (Prim_Elmt);
7103 -- Fourth stage: Complete the decoration of primitives covering
7104 -- interfaces (that is, propagate the DT_Position attribute
7105 -- from the aliased primitive)
7107 Prim_Elmt := First_Prim;
7108 while Present (Prim_Elmt) loop
7109 Prim := Node (Prim_Elmt);
7111 if DT_Position (Prim) = No_Uint
7112 and then Present (Interface_Alias (Prim))
7114 pragma Assert (Present (Alias (Prim))
7115 and then Find_Dispatching_Type (Alias (Prim)) = Typ);
7117 -- Check if this entry will be placed in the primary DT
7120 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ)
7122 pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
7123 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
7125 -- Otherwise it will be placed in the secondary DT
7129 (DT_Position (Interface_Alias (Prim)) /= No_Uint);
7130 Set_DT_Position (Prim,
7131 DT_Position (Interface_Alias (Prim)));
7135 Next_Elmt (Prim_Elmt);
7138 -- Generate listing showing the contents of the dispatch tables.
7139 -- This action is done before some further static checks because
7140 -- in case of critical errors caused by a wrong dispatch table
7141 -- we need to see the contents of such table.
7143 if Debug_Flag_ZZ then
7147 -- Final stage: Ensure that the table is correct plus some further
7148 -- verifications concerning the primitives.
7150 Prim_Elmt := First_Prim;
7152 while Present (Prim_Elmt) loop
7153 Prim := Node (Prim_Elmt);
7155 -- At this point all the primitives MUST have a position
7156 -- in the dispatch table.
7158 if DT_Position (Prim) = No_Uint then
7159 raise Program_Error;
7162 -- Calculate real size of the dispatch table
7164 if not (Is_Predefined_Dispatching_Operation (Prim)
7165 or else Is_Predefined_Dispatching_Alias (Prim))
7166 and then UI_To_Int (DT_Position (Prim)) > DT_Length
7168 DT_Length := UI_To_Int (DT_Position (Prim));
7171 -- Ensure that the assigned position to non-predefined
7172 -- dispatching operations in the dispatch table is correct.
7174 if not (Is_Predefined_Dispatching_Operation (Prim)
7175 or else Is_Predefined_Dispatching_Alias (Prim))
7177 Validate_Position (Prim);
7180 if Chars (Prim) = Name_Finalize then
7184 if Chars (Prim) = Name_Adjust then
7188 -- An abstract operation cannot be declared in the private part
7189 -- for a visible abstract type, because it could never be over-
7190 -- ridden. For explicit declarations this is checked at the
7191 -- point of declaration, but for inherited operations it must
7192 -- be done when building the dispatch table.
7194 -- Ada 2005 (AI-251): Primitives associated with interfaces are
7195 -- excluded from this check because interfaces must be visible in
7196 -- the public and private part (RM 7.3 (7.3/2))
7198 if Is_Abstract_Type (Typ)
7199 and then Is_Abstract_Subprogram (Prim)
7200 and then Present (Alias (Prim))
7201 and then not Is_Interface
7202 (Find_Dispatching_Type (Ultimate_Alias (Prim)))
7203 and then not Present (Interface_Alias (Prim))
7204 and then Is_Derived_Type (Typ)
7205 and then In_Private_Part (Current_Scope)
7207 List_Containing (Parent (Prim)) =
7208 Private_Declarations
7209 (Specification (Unit_Declaration_Node (Current_Scope)))
7210 and then Original_View_In_Visible_Part (Typ)
7212 -- We exclude Input and Output stream operations because
7213 -- Limited_Controlled inherits useless Input and Output
7214 -- stream operations from Root_Controlled, which can
7215 -- never be overridden.
7217 if not Is_TSS (Prim, TSS_Stream_Input)
7219 not Is_TSS (Prim, TSS_Stream_Output)
7222 ("abstract inherited private operation&" &
7223 " must be overridden (RM 3.9.3(10))",
7224 Parent (Typ), Prim);
7228 Next_Elmt (Prim_Elmt);
7233 if Is_Controlled (Typ) then
7234 if not Finalized then
7236 ("controlled type has no explicit Finalize method?", Typ);
7238 elsif not Adjusted then
7240 ("controlled type has no explicit Adjust method?", Typ);
7244 -- Set the final size of the Dispatch Table
7246 Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));
7248 -- The derived type must have at least as many components as its parent
7249 -- (for root types Etype points to itself and the test cannot fail).
7251 if DT_Entry_Count (The_Tag) <
7252 DT_Entry_Count (First_Tag_Component (Parent_Typ))
7254 raise Program_Error;
7256 end Set_All_DT_Position;
7258 --------------------------
7259 -- Set_CPP_Constructors --
7260 --------------------------
7262 procedure Set_CPP_Constructors (Typ : Entity_Id) is
7266 Found : Boolean := False;
7271 -- Look for the constructor entities
7273 E := Next_Entity (Typ);
7274 while Present (E) loop
7275 if Ekind (E) = E_Function
7276 and then Is_Constructor (E)
7278 -- Create the init procedure
7282 Init := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
7285 Make_Parameter_Specification (Loc,
7286 Defining_Identifier =>
7287 Make_Defining_Identifier (Loc, Name_X),
7289 New_Reference_To (Typ, Loc)));
7291 if Present (Parameter_Specifications (Parent (E))) then
7292 P := First (Parameter_Specifications (Parent (E)));
7293 while Present (P) loop
7295 Make_Parameter_Specification (Loc,
7296 Defining_Identifier =>
7297 Make_Defining_Identifier (Loc,
7298 Chars (Defining_Identifier (P))),
7299 Parameter_Type => New_Copy_Tree (Parameter_Type (P))));
7305 Make_Subprogram_Declaration (Loc,
7306 Make_Procedure_Specification (Loc,
7307 Defining_Unit_Name => Init,
7308 Parameter_Specifications => Parms)));
7310 Set_Init_Proc (Typ, Init);
7311 Set_Is_Imported (Init);
7312 Set_Interface_Name (Init, Interface_Name (E));
7313 Set_Convention (Init, Convention_C);
7314 Set_Is_Public (Init);
7315 Set_Has_Completion (Init);
7321 -- If there are no constructors, mark the type as abstract since we
7322 -- won't be able to declare objects of that type.
7325 Set_Is_Abstract_Type (Typ);
7327 end Set_CPP_Constructors;
7329 --------------------------
7330 -- Set_DTC_Entity_Value --
7331 --------------------------
7333 procedure Set_DTC_Entity_Value
7334 (Tagged_Type : Entity_Id;
7338 if Present (Interface_Alias (Prim))
7339 and then Is_Interface
7340 (Find_Dispatching_Type (Interface_Alias (Prim)))
7342 Set_DTC_Entity (Prim,
7345 Iface => Find_Dispatching_Type (Interface_Alias (Prim))));
7347 Set_DTC_Entity (Prim,
7348 First_Tag_Component (Tagged_Type));
7350 end Set_DTC_Entity_Value;
7356 function Tagged_Kind (T : Entity_Id) return Node_Id is
7357 Conc_Typ : Entity_Id;
7358 Loc : constant Source_Ptr := Sloc (T);
7362 (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));
7366 if Is_Abstract_Type (T) then
7367 if Is_Limited_Record (T) then
7368 return New_Reference_To (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
7370 return New_Reference_To (RTE (RE_TK_Abstract_Tagged), Loc);
7375 elsif Is_Concurrent_Record_Type (T) then
7376 Conc_Typ := Corresponding_Concurrent_Type (T);
7378 if Present (Full_View (Conc_Typ)) then
7379 Conc_Typ := Full_View (Conc_Typ);
7382 if Ekind (Conc_Typ) = E_Protected_Type then
7383 return New_Reference_To (RTE (RE_TK_Protected), Loc);
7385 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
7386 return New_Reference_To (RTE (RE_TK_Task), Loc);
7389 -- Regular tagged kinds
7392 if Is_Limited_Record (T) then
7393 return New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc);
7395 return New_Reference_To (RTE (RE_TK_Tagged), Loc);
7404 procedure Write_DT (Typ : Entity_Id) is
7409 -- Protect this procedure against wrong usage. Required because it will
7410 -- be used directly from GDB
7412 if not (Typ <= Last_Node_Id)
7413 or else not Is_Tagged_Type (Typ)
7415 Write_Str ("wrong usage: Write_DT must be used with tagged types");
7420 Write_Int (Int (Typ));
7422 Write_Name (Chars (Typ));
7424 if Is_Interface (Typ) then
7425 Write_Str (" is interface");
7430 Elmt := First_Elmt (Primitive_Operations (Typ));
7431 while Present (Elmt) loop
7432 Prim := Node (Elmt);
7435 -- Indicate if this primitive will be allocated in the primary
7436 -- dispatch table or in a secondary dispatch table associated
7437 -- with an abstract interface type
7439 if Present (DTC_Entity (Prim)) then
7440 if Etype (DTC_Entity (Prim)) = RTE (RE_Tag) then
7447 -- Output the node of this primitive operation and its name
7449 Write_Int (Int (Prim));
7452 if Is_Predefined_Dispatching_Operation (Prim) then
7453 Write_Str ("(predefined) ");
7456 Write_Name (Chars (Prim));
7458 -- Indicate if this primitive has an aliased primitive
7460 if Present (Alias (Prim)) then
7461 Write_Str (" (alias = ");
7462 Write_Int (Int (Alias (Prim)));
7464 -- If the DTC_Entity attribute is already set we can also output
7465 -- the name of the interface covered by this primitive (if any)
7467 if Present (DTC_Entity (Alias (Prim)))
7468 and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
7470 Write_Str (" from interface ");
7471 Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
7474 if Present (Interface_Alias (Prim)) then
7475 Write_Str (", AI_Alias of ");
7477 (Chars (Find_Dispatching_Type (Interface_Alias (Prim))));
7479 Write_Int (Int (Interface_Alias (Prim)));
7485 -- Display the final position of this primitive in its associated
7486 -- (primary or secondary) dispatch table
7488 if Present (DTC_Entity (Prim))
7489 and then DT_Position (Prim) /= No_Uint
7491 Write_Str (" at #");
7492 Write_Int (UI_To_Int (DT_Position (Prim)));
7495 if Is_Abstract_Subprogram (Prim) then
7496 Write_Str (" is abstract;");
7498 -- Check if this is a null primitive
7500 elsif Comes_From_Source (Prim)
7501 and then Ekind (Prim) = E_Procedure
7502 and then Null_Present (Parent (Prim))
7504 Write_Str (" is null;");
7507 if Is_Eliminated (Ultimate_Alias (Prim)) then
7508 Write_Str (" (eliminated)");