1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2008, 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 Targparm; use Targparm;
63 with Tbuild; use Tbuild;
64 with Uintp; use Uintp;
66 package body Exp_Disp is
68 -----------------------
69 -- Local Subprograms --
70 -----------------------
72 function Default_Prim_Op_Position (E : Entity_Id) return Uint;
73 -- Ada 2005 (AI-251): Returns the fixed position in the dispatch table
74 -- of the default primitive operations.
76 function Has_DT (Typ : Entity_Id) return Boolean;
77 pragma Inline (Has_DT);
78 -- Returns true if we generate a dispatch table for tagged type Typ
80 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean;
81 -- Returns true if Prim is not a predefined dispatching primitive but it is
82 -- an alias of a predefined dispatching primitive (i.e. through a renaming)
84 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean;
85 -- Check if the type has a private view or if the public view appears
86 -- in the visible part of a package spec.
90 Typ : Entity_Id) return Node_Id;
91 -- Ada 2005 (AI-345): Determine the primitive operation kind of Prim
92 -- according to its type Typ. Return a reference to an RE_Prim_Op_Kind
95 function Tagged_Kind (T : Entity_Id) return Node_Id;
96 -- Ada 2005 (AI-345): Determine the tagged kind of T and return a reference
97 -- to an RE_Tagged_Kind enumeration value.
99 ------------------------
100 -- Building_Static_DT --
101 ------------------------
103 function Building_Static_DT (Typ : Entity_Id) return Boolean is
104 Root_Typ : Entity_Id := Root_Type (Typ);
107 -- Handle private types
109 if Present (Full_View (Root_Typ)) then
110 Root_Typ := Full_View (Root_Typ);
113 return Static_Dispatch_Tables
114 and then Is_Library_Level_Tagged_Type (Typ)
116 -- If the type is derived from a CPP class we cannot statically
117 -- build the dispatch tables because we must inherit primitives
118 -- from the CPP side.
120 and then not Is_CPP_Class (Root_Typ);
121 end Building_Static_DT;
123 ----------------------------------
124 -- Build_Static_Dispatch_Tables --
125 ----------------------------------
127 procedure Build_Static_Dispatch_Tables (N : Entity_Id) is
128 Target_List : List_Id;
130 procedure Build_Dispatch_Tables (List : List_Id);
131 -- Build the static dispatch table of tagged types found in the list of
132 -- declarations. The generated nodes are added at the end of Target_List
134 procedure Build_Package_Dispatch_Tables (N : Node_Id);
135 -- Build static dispatch tables associated with package declaration N
137 ---------------------------
138 -- Build_Dispatch_Tables --
139 ---------------------------
141 procedure Build_Dispatch_Tables (List : List_Id) is
146 while Present (D) loop
148 -- Handle nested packages and package bodies recursively. The
149 -- generated code is placed on the Target_List established for
150 -- the enclosing compilation unit.
152 if Nkind (D) = N_Package_Declaration then
153 Build_Package_Dispatch_Tables (D);
155 elsif Nkind (D) = N_Package_Body then
156 Build_Dispatch_Tables (Declarations (D));
158 elsif Nkind (D) = N_Package_Body_Stub
159 and then Present (Library_Unit (D))
161 Build_Dispatch_Tables
162 (Declarations (Proper_Body (Unit (Library_Unit (D)))));
164 -- Handle full type declarations and derivations of library
165 -- level tagged types
167 elsif (Nkind (D) = N_Full_Type_Declaration
168 or else Nkind (D) = N_Derived_Type_Definition)
169 and then Is_Library_Level_Tagged_Type (Defining_Entity (D))
170 and then Ekind (Defining_Entity (D)) /= E_Record_Subtype
171 and then not Is_Private_Type (Defining_Entity (D))
173 Insert_List_After_And_Analyze (Last (Target_List),
174 Make_DT (Defining_Entity (D)));
176 -- Handle private types of library level tagged types. We must
177 -- exchange the private and full-view to ensure the correct
178 -- expansion. If the full view is a synchronized type ignore
179 -- the type because the table will be built for the corresponding
180 -- record type, that has its own declaration.
182 elsif (Nkind (D) = N_Private_Type_Declaration
183 or else Nkind (D) = N_Private_Extension_Declaration)
184 and then Present (Full_View (Defining_Entity (D)))
187 E1 : constant Entity_Id := Defining_Entity (D);
188 E2 : constant Entity_Id := Full_View (E1);
191 if Is_Library_Level_Tagged_Type (E2)
192 and then Ekind (E2) /= E_Record_Subtype
193 and then not Is_Concurrent_Type (E2)
195 Exchange_Declarations (E1);
196 Insert_List_After_And_Analyze (Last (Target_List),
198 Exchange_Declarations (E2);
205 end Build_Dispatch_Tables;
207 -----------------------------------
208 -- Build_Package_Dispatch_Tables --
209 -----------------------------------
211 procedure Build_Package_Dispatch_Tables (N : Node_Id) is
212 Spec : constant Node_Id := Specification (N);
213 Id : constant Entity_Id := Defining_Entity (N);
214 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
215 Priv_Decls : constant List_Id := Private_Declarations (Spec);
220 if Present (Priv_Decls) then
221 Build_Dispatch_Tables (Vis_Decls);
222 Build_Dispatch_Tables (Priv_Decls);
224 elsif Present (Vis_Decls) then
225 Build_Dispatch_Tables (Vis_Decls);
229 end Build_Package_Dispatch_Tables;
231 -- Start of processing for Build_Static_Dispatch_Tables
234 if not Expander_Active
235 or else VM_Target /= No_VM
240 if Nkind (N) = N_Package_Declaration then
242 Spec : constant Node_Id := Specification (N);
243 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
244 Priv_Decls : constant List_Id := Private_Declarations (Spec);
247 if Present (Priv_Decls)
248 and then Is_Non_Empty_List (Priv_Decls)
250 Target_List := Priv_Decls;
252 elsif not Present (Vis_Decls) then
253 Target_List := New_List;
254 Set_Private_Declarations (Spec, Target_List);
256 Target_List := Vis_Decls;
259 Build_Package_Dispatch_Tables (N);
262 else pragma Assert (Nkind (N) = N_Package_Body);
263 Target_List := Declarations (N);
264 Build_Dispatch_Tables (Target_List);
266 end Build_Static_Dispatch_Tables;
268 ------------------------------
269 -- Default_Prim_Op_Position --
270 ------------------------------
272 function Default_Prim_Op_Position (E : Entity_Id) return Uint is
273 TSS_Name : TSS_Name_Type;
276 Get_Name_String (Chars (E));
279 (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
281 if Chars (E) = Name_uSize then
284 elsif Chars (E) = Name_uAlignment then
287 elsif TSS_Name = TSS_Stream_Read then
290 elsif TSS_Name = TSS_Stream_Write then
293 elsif TSS_Name = TSS_Stream_Input then
296 elsif TSS_Name = TSS_Stream_Output then
299 elsif Chars (E) = Name_Op_Eq then
302 elsif Chars (E) = Name_uAssign then
305 elsif TSS_Name = TSS_Deep_Adjust then
308 elsif TSS_Name = TSS_Deep_Finalize then
311 elsif Ada_Version >= Ada_05 then
312 if Chars (E) = Name_uDisp_Asynchronous_Select then
315 elsif Chars (E) = Name_uDisp_Conditional_Select then
318 elsif Chars (E) = Name_uDisp_Get_Prim_Op_Kind then
321 elsif Chars (E) = Name_uDisp_Get_Task_Id then
324 elsif Chars (E) = Name_uDisp_Requeue then
327 elsif Chars (E) = Name_uDisp_Timed_Select then
333 end Default_Prim_Op_Position;
335 -----------------------------
336 -- Expand_Dispatching_Call --
337 -----------------------------
339 procedure Expand_Dispatching_Call (Call_Node : Node_Id) is
340 Loc : constant Source_Ptr := Sloc (Call_Node);
341 Call_Typ : constant Entity_Id := Etype (Call_Node);
343 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
344 Ctrl_Typ : constant Entity_Id := Base_Type (Etype (Ctrl_Arg));
345 Param_List : constant List_Id := Parameter_Associations (Call_Node);
350 New_Call_Name : Node_Id;
351 New_Params : List_Id := No_List;
354 Subp_Ptr_Typ : Entity_Id;
355 Subp_Typ : Entity_Id;
357 Eq_Prim_Op : Entity_Id := Empty;
358 Controlling_Tag : Node_Id;
360 function New_Value (From : Node_Id) return Node_Id;
361 -- From is the original Expression. New_Value is equivalent to a call
362 -- to Duplicate_Subexpr with an explicit dereference when From is an
369 function New_Value (From : Node_Id) return Node_Id is
370 Res : constant Node_Id := Duplicate_Subexpr (From);
372 if Is_Access_Type (Etype (From)) then
374 Make_Explicit_Dereference (Sloc (From),
381 -- Start of processing for Expand_Dispatching_Call
384 if No_Run_Time_Mode then
385 Error_Msg_CRT ("tagged types", Call_Node);
389 -- Expand_Dispatching_Call is called directly from the semantics,
390 -- so we need a check to see whether expansion is active before
391 -- proceeding. In addition, there is no need to expand the call
392 -- if we are compiling under restriction No_Dispatching_Calls;
393 -- the semantic analyzer has previously notified the violation
394 -- of this restriction.
396 if not Expander_Active
397 or else Restriction_Active (No_Dispatching_Calls)
402 -- Set subprogram. If this is an inherited operation that was
403 -- overridden, the body that is being called is its alias.
405 Subp := Entity (Name (Call_Node));
407 if Present (Alias (Subp))
408 and then Is_Inherited_Operation (Subp)
409 and then No (DTC_Entity (Subp))
411 Subp := Alias (Subp);
414 -- Definition of the class-wide type and the tagged type
416 -- If the controlling argument is itself a tag rather than a tagged
417 -- object, then use the class-wide type associated with the subprogram's
418 -- controlling type. This case can occur when a call to an inherited
419 -- primitive has an actual that originated from a default parameter
420 -- given by a tag-indeterminate call and when there is no other
421 -- controlling argument providing the tag (AI-239 requires dispatching).
422 -- This capability of dispatching directly by tag is also needed by the
423 -- implementation of AI-260 (for the generic dispatching constructors).
425 if Ctrl_Typ = RTE (RE_Tag)
426 or else (RTE_Available (RE_Interface_Tag)
427 and then Ctrl_Typ = RTE (RE_Interface_Tag))
429 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
431 -- Class_Wide_Type is applied to the expressions used to initialize
432 -- CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
433 -- there are cases where the controlling type is resolved to a specific
434 -- type (such as for designated types of arguments such as CW'Access).
436 elsif Is_Access_Type (Ctrl_Typ) then
437 CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));
440 CW_Typ := Class_Wide_Type (Ctrl_Typ);
443 Typ := Root_Type (CW_Typ);
445 if Ekind (Typ) = E_Incomplete_Type then
446 Typ := Non_Limited_View (Typ);
449 if not Is_Limited_Type (Typ) then
450 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
453 -- Dispatching call to C++ primitive. Create a new parameter list
454 -- with no tag checks.
456 if Is_CPP_Class (Typ) then
457 New_Params := New_List;
458 Param := First_Actual (Call_Node);
459 while Present (Param) loop
460 Append_To (New_Params, Relocate_Node (Param));
464 -- Dispatching call to Ada primitive
466 elsif Present (Param_List) then
468 -- Generate the Tag checks when appropriate
470 New_Params := New_List;
471 Param := First_Actual (Call_Node);
472 while Present (Param) loop
474 -- No tag check with itself
476 if Param = Ctrl_Arg then
477 Append_To (New_Params,
478 Duplicate_Subexpr_Move_Checks (Param));
480 -- No tag check for parameter whose type is neither tagged nor
481 -- access to tagged (for access parameters)
483 elsif No (Find_Controlling_Arg (Param)) then
484 Append_To (New_Params, Relocate_Node (Param));
486 -- No tag check for function dispatching on result if the
487 -- Tag given by the context is this one
489 elsif Find_Controlling_Arg (Param) = Ctrl_Arg then
490 Append_To (New_Params, Relocate_Node (Param));
492 -- "=" is the only dispatching operation allowed to get
493 -- operands with incompatible tags (it just returns false).
494 -- We use Duplicate_Subexpr_Move_Checks instead of calling
495 -- Relocate_Node because the value will be duplicated to
498 elsif Subp = Eq_Prim_Op then
499 Append_To (New_Params,
500 Duplicate_Subexpr_Move_Checks (Param));
502 -- No check in presence of suppress flags
504 elsif Tag_Checks_Suppressed (Etype (Param))
505 or else (Is_Access_Type (Etype (Param))
506 and then Tag_Checks_Suppressed
507 (Designated_Type (Etype (Param))))
509 Append_To (New_Params, Relocate_Node (Param));
511 -- Optimization: no tag checks if the parameters are identical
513 elsif Is_Entity_Name (Param)
514 and then Is_Entity_Name (Ctrl_Arg)
515 and then Entity (Param) = Entity (Ctrl_Arg)
517 Append_To (New_Params, Relocate_Node (Param));
519 -- Now we need to generate the Tag check
522 -- Generate code for tag equality check
523 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
525 Insert_Action (Ctrl_Arg,
526 Make_Implicit_If_Statement (Call_Node,
530 Make_Selected_Component (Loc,
531 Prefix => New_Value (Ctrl_Arg),
534 (First_Tag_Component (Typ), Loc)),
537 Make_Selected_Component (Loc,
539 Unchecked_Convert_To (Typ, New_Value (Param)),
542 (First_Tag_Component (Typ), Loc))),
545 New_List (New_Constraint_Error (Loc))));
547 Append_To (New_Params, Relocate_Node (Param));
554 -- Generate the appropriate subprogram pointer type
556 if Etype (Subp) = Typ then
559 Res_Typ := Etype (Subp);
562 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
563 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
564 Set_Etype (Subp_Typ, Res_Typ);
565 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
567 -- Create a new list of parameters which is a copy of the old formal
568 -- list including the creation of a new set of matching entities.
571 Old_Formal : Entity_Id := First_Formal (Subp);
572 New_Formal : Entity_Id;
573 Extra : Entity_Id := Empty;
576 if Present (Old_Formal) then
577 New_Formal := New_Copy (Old_Formal);
578 Set_First_Entity (Subp_Typ, New_Formal);
579 Param := First_Actual (Call_Node);
582 Set_Scope (New_Formal, Subp_Typ);
584 -- Change all the controlling argument types to be class-wide
585 -- to avoid a recursion in dispatching.
587 if Is_Controlling_Formal (New_Formal) then
588 Set_Etype (New_Formal, Etype (Param));
591 -- If the type of the formal is an itype, there was code here
592 -- introduced in 1998 in revision 1.46, to create a new itype
593 -- by copy. This seems useless, and in fact leads to semantic
594 -- errors when the itype is the completion of a type derived
595 -- from a private type.
598 Next_Formal (Old_Formal);
599 exit when No (Old_Formal);
601 Set_Next_Entity (New_Formal, New_Copy (Old_Formal));
602 Next_Entity (New_Formal);
606 Set_Next_Entity (New_Formal, Empty);
607 Set_Last_Entity (Subp_Typ, Extra);
610 -- Now that the explicit formals have been duplicated, any extra
611 -- formals needed by the subprogram must be created.
613 if Present (Extra) then
614 Set_Extra_Formal (Extra, Empty);
617 Create_Extra_Formals (Subp_Typ);
620 -- Complete description of pointer type, including size information, as
621 -- must be done with itypes to prevent order-of-elaboration anomalies
624 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
625 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
626 Set_Convention (Subp_Ptr_Typ, Convention (Subp_Typ));
627 Layout_Type (Subp_Ptr_Typ);
629 -- If the controlling argument is a value of type Ada.Tag or an abstract
630 -- interface class-wide type then use it directly. Otherwise, the tag
631 -- must be extracted from the controlling object.
633 if Ctrl_Typ = RTE (RE_Tag)
634 or else (RTE_Available (RE_Interface_Tag)
635 and then Ctrl_Typ = RTE (RE_Interface_Tag))
637 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
639 -- Extract the tag from an unchecked type conversion. Done to avoid
640 -- the expansion of additional code just to obtain the value of such
641 -- tag because the current management of interface type conversions
642 -- generates in some cases this unchecked type conversion with the
643 -- tag of the object (see Expand_Interface_Conversion).
645 elsif Nkind (Ctrl_Arg) = N_Unchecked_Type_Conversion
647 (Etype (Expression (Ctrl_Arg)) = RTE (RE_Tag)
649 (RTE_Available (RE_Interface_Tag)
651 Etype (Expression (Ctrl_Arg)) = RTE (RE_Interface_Tag)))
653 Controlling_Tag := Duplicate_Subexpr (Expression (Ctrl_Arg));
655 -- Ada 2005 (AI-251): Abstract interface class-wide type
657 elsif Is_Interface (Ctrl_Typ)
658 and then Is_Class_Wide_Type (Ctrl_Typ)
660 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
664 Make_Selected_Component (Loc,
665 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
666 Selector_Name => New_Reference_To (DTC_Entity (Subp), Loc));
669 -- Handle dispatching calls to predefined primitives
671 if Is_Predefined_Dispatching_Operation (Subp)
672 or else Is_Predefined_Dispatching_Alias (Subp)
675 Unchecked_Convert_To (Subp_Ptr_Typ,
676 Build_Get_Predefined_Prim_Op_Address (Loc,
677 Tag_Node => Controlling_Tag,
678 Position => DT_Position (Subp)));
680 -- Handle dispatching calls to user-defined primitives
684 Unchecked_Convert_To (Subp_Ptr_Typ,
685 Build_Get_Prim_Op_Address (Loc,
686 Typ => Find_Dispatching_Type (Subp),
687 Tag_Node => Controlling_Tag,
688 Position => DT_Position (Subp)));
691 if Nkind (Call_Node) = N_Function_Call then
694 Make_Function_Call (Loc,
695 Name => New_Call_Name,
696 Parameter_Associations => New_Params);
698 -- If this is a dispatching "=", we must first compare the tags so
699 -- we generate: x.tag = y.tag and then x = y
701 if Subp = Eq_Prim_Op then
702 Param := First_Actual (Call_Node);
708 Make_Selected_Component (Loc,
709 Prefix => New_Value (Param),
711 New_Reference_To (First_Tag_Component (Typ),
715 Make_Selected_Component (Loc,
717 Unchecked_Convert_To (Typ,
718 New_Value (Next_Actual (Param))),
720 New_Reference_To (First_Tag_Component (Typ),
722 Right_Opnd => New_Call);
727 Make_Procedure_Call_Statement (Loc,
728 Name => New_Call_Name,
729 Parameter_Associations => New_Params);
732 Rewrite (Call_Node, New_Call);
734 -- Suppress all checks during the analysis of the expanded code
735 -- to avoid the generation of spurious warnings under ZFP run-time.
737 Analyze_And_Resolve (Call_Node, Call_Typ, Suppress => All_Checks);
738 end Expand_Dispatching_Call;
740 ---------------------------------
741 -- Expand_Interface_Conversion --
742 ---------------------------------
744 procedure Expand_Interface_Conversion
746 Is_Static : Boolean := True)
748 Loc : constant Source_Ptr := Sloc (N);
749 Etyp : constant Entity_Id := Etype (N);
750 Operand : constant Node_Id := Expression (N);
751 Operand_Typ : Entity_Id := Etype (Operand);
753 Iface_Typ : Entity_Id := Etype (N);
754 Iface_Tag : Entity_Id;
757 -- Ada 2005 (AI-345): Handle synchronized interface type derivations
759 if Is_Concurrent_Type (Operand_Typ) then
760 Operand_Typ := Base_Type (Corresponding_Record_Type (Operand_Typ));
763 -- Handle access to class-wide interface types
765 if Is_Access_Type (Iface_Typ) then
766 Iface_Typ := Etype (Directly_Designated_Type (Iface_Typ));
769 -- Handle class-wide interface types. This conversion can appear
770 -- explicitly in the source code. Example: I'Class (Obj)
772 if Is_Class_Wide_Type (Iface_Typ) then
773 Iface_Typ := Root_Type (Iface_Typ);
776 -- If the target type is a tagged synchronized type, the dispatch table
777 -- info is in the corresponding record type.
779 if Is_Concurrent_Type (Iface_Typ) then
780 Iface_Typ := Corresponding_Record_Type (Iface_Typ);
783 -- Freeze the entity associated with the target interface to have
784 -- available the attribute Access_Disp_Table.
786 Freeze_Before (N, Iface_Typ);
788 pragma Assert (not Is_Static
789 or else (not Is_Class_Wide_Type (Iface_Typ)
790 and then Is_Interface (Iface_Typ)));
792 if VM_Target /= No_VM then
794 -- For VM, just do a conversion ???
796 Rewrite (N, Unchecked_Convert_To (Etype (N), N));
801 if not Is_Static then
803 -- Give error if configurable run time and Displace not available
805 if not RTE_Available (RE_Displace) then
806 Error_Msg_CRT ("dynamic interface conversion", N);
810 -- Handle conversion of access-to-class-wide interface types. Target
811 -- can be an access to an object or an access to another class-wide
812 -- interface (see -1- and -2- in the following example):
814 -- type Iface1_Ref is access all Iface1'Class;
815 -- type Iface2_Ref is access all Iface1'Class;
817 -- Acc1 : Iface1_Ref := new ...
818 -- Obj : Obj_Ref := Obj_Ref (Acc); -- 1
819 -- Acc2 : Iface2_Ref := Iface2_Ref (Acc); -- 2
821 if Is_Access_Type (Operand_Typ) then
823 Unchecked_Convert_To (Etype (N),
824 Make_Function_Call (Loc,
825 Name => New_Reference_To (RTE (RE_Displace), Loc),
826 Parameter_Associations => New_List (
828 Unchecked_Convert_To (RTE (RE_Address),
829 Relocate_Node (Expression (N))),
832 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
840 Make_Function_Call (Loc,
841 Name => New_Reference_To (RTE (RE_Displace), Loc),
842 Parameter_Associations => New_List (
843 Make_Attribute_Reference (Loc,
844 Prefix => Relocate_Node (Expression (N)),
845 Attribute_Name => Name_Address),
848 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
853 -- If the target is a class-wide interface we change the type of the
854 -- data returned by IW_Convert to indicate that this is a dispatching
858 New_Itype : Entity_Id;
861 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
862 Set_Etype (New_Itype, New_Itype);
863 Set_Directly_Designated_Type (New_Itype, Etyp);
866 Make_Explicit_Dereference (Loc,
868 Unchecked_Convert_To (New_Itype, Relocate_Node (N))));
870 Freeze_Itype (New_Itype, N);
876 Iface_Tag := Find_Interface_Tag (Operand_Typ, Iface_Typ);
877 pragma Assert (Iface_Tag /= Empty);
879 -- Keep separate access types to interfaces because one internal
880 -- function is used to handle the null value (see following comment)
882 if not Is_Access_Type (Etype (N)) then
884 Unchecked_Convert_To (Etype (N),
885 Make_Selected_Component (Loc,
886 Prefix => Relocate_Node (Expression (N)),
888 New_Occurrence_Of (Iface_Tag, Loc))));
891 -- Build internal function to handle the case in which the
892 -- actual is null. If the actual is null returns null because
893 -- no displacement is required; otherwise performs a type
894 -- conversion that will be expanded in the code that returns
895 -- the value of the displaced actual. That is:
897 -- function Func (O : Address) return Iface_Typ is
898 -- type Op_Typ is access all Operand_Typ;
899 -- Aux : Op_Typ := To_Op_Typ (O);
901 -- if O = Null_Address then
904 -- return Iface_Typ!(Aux.Iface_Tag'Address);
909 Desig_Typ : Entity_Id;
911 New_Typ_Decl : Node_Id;
915 Desig_Typ := Etype (Expression (N));
917 if Is_Access_Type (Desig_Typ) then
918 Desig_Typ := Directly_Designated_Type (Desig_Typ);
921 if Is_Concurrent_Type (Desig_Typ) then
922 Desig_Typ := Base_Type (Corresponding_Record_Type (Desig_Typ));
926 Make_Full_Type_Declaration (Loc,
927 Defining_Identifier =>
928 Make_Defining_Identifier (Loc, New_Internal_Name ('T')),
930 Make_Access_To_Object_Definition (Loc,
932 Null_Exclusion_Present => False,
933 Constant_Present => False,
934 Subtype_Indication =>
935 New_Reference_To (Desig_Typ, Loc)));
938 Make_Simple_Return_Statement (Loc,
939 Unchecked_Convert_To (Etype (N),
940 Make_Attribute_Reference (Loc,
942 Make_Selected_Component (Loc,
945 (Defining_Identifier (New_Typ_Decl),
946 Make_Identifier (Loc, Name_uO)),
948 New_Occurrence_Of (Iface_Tag, Loc)),
949 Attribute_Name => Name_Address))));
951 -- If the type is null-excluding, no need for the null branch.
952 -- Otherwise we need to check for it and return null.
954 if not Can_Never_Be_Null (Etype (N)) then
956 Make_If_Statement (Loc,
959 Left_Opnd => Make_Identifier (Loc, Name_uO),
960 Right_Opnd => New_Reference_To
961 (RTE (RE_Null_Address), Loc)),
963 Then_Statements => New_List (
964 Make_Simple_Return_Statement (Loc,
966 Else_Statements => Stats));
970 Make_Defining_Identifier (Loc,
971 New_Internal_Name ('F'));
974 Make_Subprogram_Body (Loc,
976 Make_Function_Specification (Loc,
977 Defining_Unit_Name => Fent,
979 Parameter_Specifications => New_List (
980 Make_Parameter_Specification (Loc,
981 Defining_Identifier =>
982 Make_Defining_Identifier (Loc, Name_uO),
984 New_Reference_To (RTE (RE_Address), Loc))),
987 New_Reference_To (Etype (N), Loc)),
989 Declarations => New_List (New_Typ_Decl),
991 Handled_Statement_Sequence =>
992 Make_Handled_Sequence_Of_Statements (Loc, Stats));
994 -- Place function body before the expression containing the
995 -- conversion. We suppress all checks because the body of the
996 -- internally generated function already takes care of the case
997 -- in which the actual is null; therefore there is no need to
998 -- double check that the pointer is not null when the program
999 -- executes the alternative that performs the type conversion).
1001 Insert_Action (N, Func, Suppress => All_Checks);
1003 if Is_Access_Type (Etype (Expression (N))) then
1005 -- Generate: Func (Address!(Expression))
1008 Make_Function_Call (Loc,
1009 Name => New_Reference_To (Fent, Loc),
1010 Parameter_Associations => New_List (
1011 Unchecked_Convert_To (RTE (RE_Address),
1012 Relocate_Node (Expression (N))))));
1015 -- Generate: Func (Operand_Typ!(Expression)'Address)
1018 Make_Function_Call (Loc,
1019 Name => New_Reference_To (Fent, Loc),
1020 Parameter_Associations => New_List (
1021 Make_Attribute_Reference (Loc,
1022 Prefix => Unchecked_Convert_To (Operand_Typ,
1023 Relocate_Node (Expression (N))),
1024 Attribute_Name => Name_Address))));
1030 end Expand_Interface_Conversion;
1032 ------------------------------
1033 -- Expand_Interface_Actuals --
1034 ------------------------------
1036 procedure Expand_Interface_Actuals (Call_Node : Node_Id) is
1038 Actual_Dup : Node_Id;
1039 Actual_Typ : Entity_Id;
1041 Conversion : Node_Id;
1043 Formal_Typ : Entity_Id;
1045 Formal_DDT : Entity_Id;
1046 Actual_DDT : Entity_Id;
1049 -- This subprogram is called directly from the semantics, so we need a
1050 -- check to see whether expansion is active before proceeding.
1052 if not Expander_Active then
1056 -- Call using access to subprogram with explicit dereference
1058 if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
1059 Subp := Etype (Name (Call_Node));
1061 -- Call using selected component
1063 elsif Nkind (Name (Call_Node)) = N_Selected_Component then
1064 Subp := Entity (Selector_Name (Name (Call_Node)));
1066 -- Call using direct name
1069 Subp := Entity (Name (Call_Node));
1072 -- Ada 2005 (AI-251): Look for interface type formals to force "this"
1075 Formal := First_Formal (Subp);
1076 Actual := First_Actual (Call_Node);
1077 while Present (Formal) loop
1078 Formal_Typ := Etype (Formal);
1080 if Ekind (Formal_Typ) = E_Record_Type_With_Private then
1081 Formal_Typ := Full_View (Formal_Typ);
1084 if Is_Access_Type (Formal_Typ) then
1085 Formal_DDT := Directly_Designated_Type (Formal_Typ);
1088 Actual_Typ := Etype (Actual);
1090 if Is_Access_Type (Actual_Typ) then
1091 Actual_DDT := Directly_Designated_Type (Actual_Typ);
1094 if Is_Interface (Formal_Typ)
1095 and then Is_Class_Wide_Type (Formal_Typ)
1097 -- No need to displace the pointer if the type of the actual
1098 -- coindices with the type of the formal.
1100 if Actual_Typ = Formal_Typ then
1103 -- No need to displace the pointer if the interface type is
1104 -- a parent of the type of the actual because in this case the
1105 -- interface primitives are located in the primary dispatch table.
1107 elsif Is_Ancestor (Formal_Typ, Actual_Typ) then
1110 -- Implicit conversion to the class-wide formal type to force
1111 -- the displacement of the pointer.
1114 Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
1115 Rewrite (Actual, Conversion);
1116 Analyze_And_Resolve (Actual, Formal_Typ);
1119 -- Access to class-wide interface type
1121 elsif Is_Access_Type (Formal_Typ)
1122 and then Is_Interface (Formal_DDT)
1123 and then Is_Class_Wide_Type (Formal_DDT)
1124 and then Interface_Present_In_Ancestor
1126 Iface => Etype (Formal_DDT))
1128 -- Handle attributes 'Access and 'Unchecked_Access
1130 if Nkind (Actual) = N_Attribute_Reference
1132 (Attribute_Name (Actual) = Name_Access
1133 or else Attribute_Name (Actual) = Name_Unchecked_Access)
1135 -- This case must have been handled by the analysis and
1136 -- expansion of 'Access. The only exception is when types
1137 -- match and no further expansion is required.
1139 pragma Assert (Base_Type (Etype (Prefix (Actual)))
1140 = Base_Type (Formal_DDT));
1143 -- No need to displace the pointer if the type of the actual
1144 -- coincides with the type of the formal.
1146 elsif Actual_DDT = Formal_DDT then
1149 -- No need to displace the pointer if the interface type is
1150 -- a parent of the type of the actual because in this case the
1151 -- interface primitives are located in the primary dispatch table.
1153 elsif Is_Ancestor (Formal_DDT, Actual_DDT) then
1157 Actual_Dup := Relocate_Node (Actual);
1159 if From_With_Type (Actual_Typ) then
1161 -- If the type of the actual parameter comes from a limited
1162 -- with-clause and the non-limited view is already available
1163 -- we replace the anonymous access type by a duplicate
1164 -- declaration whose designated type is the non-limited view
1166 if Ekind (Actual_DDT) = E_Incomplete_Type
1167 and then Present (Non_Limited_View (Actual_DDT))
1169 Anon := New_Copy (Actual_Typ);
1171 if Is_Itype (Anon) then
1172 Set_Scope (Anon, Current_Scope);
1175 Set_Directly_Designated_Type (Anon,
1176 Non_Limited_View (Actual_DDT));
1177 Set_Etype (Actual_Dup, Anon);
1179 elsif Is_Class_Wide_Type (Actual_DDT)
1180 and then Ekind (Etype (Actual_DDT)) = E_Incomplete_Type
1181 and then Present (Non_Limited_View (Etype (Actual_DDT)))
1183 Anon := New_Copy (Actual_Typ);
1185 if Is_Itype (Anon) then
1186 Set_Scope (Anon, Current_Scope);
1189 Set_Directly_Designated_Type (Anon,
1190 New_Copy (Actual_DDT));
1191 Set_Class_Wide_Type (Directly_Designated_Type (Anon),
1192 New_Copy (Class_Wide_Type (Actual_DDT)));
1193 Set_Etype (Directly_Designated_Type (Anon),
1194 Non_Limited_View (Etype (Actual_DDT)));
1196 Class_Wide_Type (Directly_Designated_Type (Anon)),
1197 Non_Limited_View (Etype (Actual_DDT)));
1198 Set_Etype (Actual_Dup, Anon);
1202 Conversion := Convert_To (Formal_Typ, Actual_Dup);
1203 Rewrite (Actual, Conversion);
1204 Analyze_And_Resolve (Actual, Formal_Typ);
1208 Next_Actual (Actual);
1209 Next_Formal (Formal);
1211 end Expand_Interface_Actuals;
1213 ----------------------------
1214 -- Expand_Interface_Thunk --
1215 ----------------------------
1217 procedure Expand_Interface_Thunk
1219 Thunk_Id : out Entity_Id;
1220 Thunk_Code : out Node_Id)
1222 Loc : constant Source_Ptr := Sloc (Prim);
1223 Actuals : constant List_Id := New_List;
1224 Decl : constant List_Id := New_List;
1225 Formals : constant List_Id := New_List;
1227 Controlling_Typ : Entity_Id;
1232 Offset_To_Top : Node_Id;
1234 Target_Formal : Entity_Id;
1238 Thunk_Code := Empty;
1240 -- Traverse the list of alias to find the final target
1243 while Present (Alias (Target)) loop
1244 Target := Alias (Target);
1247 -- In case of primitives that are functions without formals and
1248 -- a controlling result there is no need to build the thunk.
1250 if not Present (First_Formal (Target)) then
1251 pragma Assert (Ekind (Target) = E_Function
1252 and then Has_Controlling_Result (Target));
1256 -- Duplicate the formals
1258 Formal := First_Formal (Target);
1259 while Present (Formal) loop
1261 Make_Parameter_Specification (Loc,
1262 Defining_Identifier =>
1263 Make_Defining_Identifier (Sloc (Formal),
1264 Chars => Chars (Formal)),
1265 In_Present => In_Present (Parent (Formal)),
1266 Out_Present => Out_Present (Parent (Formal)),
1268 New_Reference_To (Etype (Formal), Loc),
1269 Expression => New_Copy_Tree (Expression (Parent (Formal)))));
1271 Next_Formal (Formal);
1274 Controlling_Typ := Find_Dispatching_Type (Target);
1276 Target_Formal := First_Formal (Target);
1277 Formal := First (Formals);
1278 while Present (Formal) loop
1279 if Ekind (Target_Formal) = E_In_Parameter
1280 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
1281 and then Directly_Designated_Type (Etype (Target_Formal))
1286 -- type T is access all <<type of the target formal>>
1287 -- S : Storage_Offset := Storage_Offset!(Formal)
1288 -- - Offset_To_Top (address!(Formal))
1291 Make_Full_Type_Declaration (Loc,
1292 Defining_Identifier =>
1293 Make_Defining_Identifier (Loc,
1294 New_Internal_Name ('T')),
1296 Make_Access_To_Object_Definition (Loc,
1297 All_Present => True,
1298 Null_Exclusion_Present => False,
1299 Constant_Present => False,
1300 Subtype_Indication =>
1302 (Directly_Designated_Type
1303 (Etype (Target_Formal)), Loc)));
1306 Unchecked_Convert_To (RTE (RE_Address),
1307 New_Reference_To (Defining_Identifier (Formal), Loc));
1309 if not RTE_Available (RE_Offset_To_Top) then
1311 Build_Offset_To_Top (Loc, New_Arg);
1314 Make_Function_Call (Loc,
1315 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1316 Parameter_Associations => New_List (New_Arg));
1320 Make_Object_Declaration (Loc,
1321 Defining_Identifier =>
1322 Make_Defining_Identifier (Loc,
1323 New_Internal_Name ('S')),
1324 Constant_Present => True,
1325 Object_Definition =>
1326 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1328 Make_Op_Subtract (Loc,
1330 Unchecked_Convert_To
1331 (RTE (RE_Storage_Offset),
1332 New_Reference_To (Defining_Identifier (Formal), Loc)),
1336 Append_To (Decl, Decl_2);
1337 Append_To (Decl, Decl_1);
1339 -- Reference the new actual. Generate:
1343 Unchecked_Convert_To
1344 (Defining_Identifier (Decl_2),
1345 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1347 elsif Etype (Target_Formal) = Controlling_Typ then
1350 -- S1 : Storage_Offset := Storage_Offset!(Formal'Address)
1351 -- - Offset_To_Top (Formal'Address)
1352 -- S2 : Addr_Ptr := Addr_Ptr!(S1)
1355 Make_Attribute_Reference (Loc,
1357 New_Reference_To (Defining_Identifier (Formal), Loc),
1361 if not RTE_Available (RE_Offset_To_Top) then
1363 Build_Offset_To_Top (Loc, New_Arg);
1366 Make_Function_Call (Loc,
1367 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1368 Parameter_Associations => New_List (New_Arg));
1372 Make_Object_Declaration (Loc,
1373 Defining_Identifier =>
1374 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1375 Constant_Present => True,
1376 Object_Definition =>
1377 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1379 Make_Op_Subtract (Loc,
1381 Unchecked_Convert_To
1382 (RTE (RE_Storage_Offset),
1383 Make_Attribute_Reference (Loc,
1386 (Defining_Identifier (Formal), Loc),
1387 Attribute_Name => Name_Address)),
1392 Make_Object_Declaration (Loc,
1393 Defining_Identifier =>
1394 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1395 Constant_Present => True,
1396 Object_Definition => New_Reference_To (RTE (RE_Addr_Ptr), Loc),
1398 Unchecked_Convert_To
1400 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1402 Append_To (Decl, Decl_1);
1403 Append_To (Decl, Decl_2);
1405 -- Reference the new actual. Generate:
1406 -- Target_Formal (S2.all)
1409 Unchecked_Convert_To
1410 (Etype (Target_Formal),
1411 Make_Explicit_Dereference (Loc,
1412 New_Reference_To (Defining_Identifier (Decl_2), Loc))));
1414 -- No special management required for this actual
1418 New_Reference_To (Defining_Identifier (Formal), Loc));
1421 Next_Formal (Target_Formal);
1426 Make_Defining_Identifier (Loc,
1427 Chars => New_Internal_Name ('T'));
1429 Set_Is_Thunk (Thunk_Id);
1431 if Ekind (Target) = E_Procedure then
1433 Make_Subprogram_Body (Loc,
1435 Make_Procedure_Specification (Loc,
1436 Defining_Unit_Name => Thunk_Id,
1437 Parameter_Specifications => Formals),
1438 Declarations => Decl,
1439 Handled_Statement_Sequence =>
1440 Make_Handled_Sequence_Of_Statements (Loc,
1441 Statements => New_List (
1442 Make_Procedure_Call_Statement (Loc,
1443 Name => New_Occurrence_Of (Target, Loc),
1444 Parameter_Associations => Actuals))));
1446 else pragma Assert (Ekind (Target) = E_Function);
1449 Make_Subprogram_Body (Loc,
1451 Make_Function_Specification (Loc,
1452 Defining_Unit_Name => Thunk_Id,
1453 Parameter_Specifications => Formals,
1454 Result_Definition =>
1455 New_Copy (Result_Definition (Parent (Target)))),
1456 Declarations => Decl,
1457 Handled_Statement_Sequence =>
1458 Make_Handled_Sequence_Of_Statements (Loc,
1459 Statements => New_List (
1460 Make_Simple_Return_Statement (Loc,
1461 Make_Function_Call (Loc,
1462 Name => New_Occurrence_Of (Target, Loc),
1463 Parameter_Associations => Actuals)))));
1465 end Expand_Interface_Thunk;
1471 function Has_DT (Typ : Entity_Id) return Boolean is
1473 return not Is_Interface (Typ)
1474 and then not Restriction_Active (No_Dispatching_Calls);
1477 -----------------------------------------
1478 -- Is_Predefined_Dispatching_Operation --
1479 -----------------------------------------
1481 function Is_Predefined_Dispatching_Operation
1482 (E : Entity_Id) return Boolean
1484 TSS_Name : TSS_Name_Type;
1487 if not Is_Dispatching_Operation (E) then
1491 Get_Name_String (Chars (E));
1493 -- Most predefined primitives have internally generated names. Equality
1494 -- must be treated differently; the predefined operation is recognized
1495 -- as a homogeneous binary operator that returns Boolean.
1497 if Name_Len > TSS_Name_Type'Last then
1498 TSS_Name := TSS_Name_Type (Name_Buffer (Name_Len - TSS_Name'Length + 1
1500 if Chars (E) = Name_uSize
1501 or else Chars (E) = Name_uAlignment
1502 or else TSS_Name = TSS_Stream_Read
1503 or else TSS_Name = TSS_Stream_Write
1504 or else TSS_Name = TSS_Stream_Input
1505 or else TSS_Name = TSS_Stream_Output
1507 (Chars (E) = Name_Op_Eq
1508 and then Etype (First_Entity (E)) = Etype (Last_Entity (E)))
1509 or else Chars (E) = Name_uAssign
1510 or else TSS_Name = TSS_Deep_Adjust
1511 or else TSS_Name = TSS_Deep_Finalize
1512 or else Is_Predefined_Interface_Primitive (E)
1519 end Is_Predefined_Dispatching_Operation;
1521 -------------------------------------
1522 -- Is_Predefined_Dispatching_Alias --
1523 -------------------------------------
1525 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
1530 if not Is_Predefined_Dispatching_Operation (Prim)
1531 and then Present (Alias (Prim))
1534 while Present (Alias (E)) loop
1538 if Is_Predefined_Dispatching_Operation (E) then
1544 end Is_Predefined_Dispatching_Alias;
1546 ---------------------------------------
1547 -- Is_Predefined_Interface_Primitive --
1548 ---------------------------------------
1550 function Is_Predefined_Interface_Primitive (E : Entity_Id) return Boolean is
1552 return Ada_Version >= Ada_05
1553 and then (Chars (E) = Name_uDisp_Asynchronous_Select or else
1554 Chars (E) = Name_uDisp_Conditional_Select or else
1555 Chars (E) = Name_uDisp_Get_Prim_Op_Kind or else
1556 Chars (E) = Name_uDisp_Get_Task_Id or else
1557 Chars (E) = Name_uDisp_Requeue or else
1558 Chars (E) = Name_uDisp_Timed_Select);
1559 end Is_Predefined_Interface_Primitive;
1561 ----------------------------------------
1562 -- Make_Disp_Asynchronous_Select_Body --
1563 ----------------------------------------
1565 -- For interface types, generate:
1567 -- procedure _Disp_Asynchronous_Select
1568 -- (T : in out <Typ>;
1570 -- P : System.Address;
1571 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1576 -- end _Disp_Asynchronous_Select;
1578 -- For protected types, generate:
1580 -- procedure _Disp_Asynchronous_Select
1581 -- (T : in out <Typ>;
1583 -- P : System.Address;
1584 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1588 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1589 -- Bnn : System.Tasking.Protected_Objects.Operations.
1590 -- Communication_Block;
1592 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
1593 -- (T._object'Access,
1594 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
1596 -- System.Tasking.Asynchronous_Call,
1598 -- B := System.Storage_Elements.Dummy_Communication_Block (Bnn);
1599 -- end _Disp_Asynchronous_Select;
1601 -- For task types, generate:
1603 -- procedure _Disp_Asynchronous_Select
1604 -- (T : in out <Typ>;
1606 -- P : System.Address;
1607 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1611 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1613 -- System.Tasking.Rendezvous.Task_Entry_Call
1615 -- System.Tasking.Task_Entry_Index (I),
1617 -- System.Tasking.Asynchronous_Call,
1619 -- end _Disp_Asynchronous_Select;
1621 function Make_Disp_Asynchronous_Select_Body
1622 (Typ : Entity_Id) return Node_Id
1624 Com_Block : Entity_Id;
1625 Conc_Typ : Entity_Id := Empty;
1626 Decls : constant List_Id := New_List;
1628 Loc : constant Source_Ptr := Sloc (Typ);
1630 Stmts : constant List_Id := New_List;
1633 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1635 -- Null body is generated for interface types
1637 if Is_Interface (Typ) then
1639 Make_Subprogram_Body (Loc,
1641 Make_Disp_Asynchronous_Select_Spec (Typ),
1644 Handled_Statement_Sequence =>
1645 Make_Handled_Sequence_Of_Statements (Loc,
1646 New_List (Make_Null_Statement (Loc))));
1649 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1651 if Is_Concurrent_Record_Type (Typ) then
1652 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1656 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
1658 -- where I will be used to capture the entry index of the primitive
1659 -- wrapper at position S.
1662 Make_Object_Declaration (Loc,
1663 Defining_Identifier =>
1664 Make_Defining_Identifier (Loc, Name_uI),
1665 Object_Definition =>
1666 New_Reference_To (Standard_Integer, Loc),
1668 Make_Function_Call (Loc,
1670 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
1671 Parameter_Associations =>
1673 Unchecked_Convert_To (RTE (RE_Tag),
1674 New_Reference_To (DT_Ptr, Loc)),
1675 Make_Identifier (Loc, Name_uS)))));
1677 if Ekind (Conc_Typ) = E_Protected_Type then
1680 -- Bnn : Communication_Block;
1683 Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1686 Make_Object_Declaration (Loc,
1687 Defining_Identifier =>
1689 Object_Definition =>
1690 New_Reference_To (RTE (RE_Communication_Block), Loc)));
1692 -- Build T._object'Access for calls below
1695 Make_Attribute_Reference (Loc,
1696 Attribute_Name => Name_Unchecked_Access,
1698 Make_Selected_Component (Loc,
1699 Prefix => Make_Identifier (Loc, Name_uT),
1700 Selector_Name => Make_Identifier (Loc, Name_uObject)));
1702 case Corresponding_Runtime_Package (Conc_Typ) is
1703 when System_Tasking_Protected_Objects_Entries =>
1706 -- Protected_Entry_Call
1707 -- (T._object'Access, -- Object
1708 -- Protected_Entry_Index! (I), -- E
1709 -- P, -- Uninterpreted_Data
1710 -- Asynchronous_Call, -- Mode
1711 -- Bnn); -- Communication_Block
1713 -- where T is the protected object, I is the entry index, P
1714 -- is the wrapped parameters and B is the name of the
1715 -- communication block.
1718 Make_Procedure_Call_Statement (Loc,
1720 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1721 Parameter_Associations =>
1725 Make_Unchecked_Type_Conversion (Loc, -- entry index
1728 (RTE (RE_Protected_Entry_Index), Loc),
1729 Expression => Make_Identifier (Loc, Name_uI)),
1731 Make_Identifier (Loc, Name_uP), -- parameter block
1732 New_Reference_To ( -- Asynchronous_Call
1733 RTE (RE_Asynchronous_Call), Loc),
1735 New_Reference_To (Com_Block, Loc)))); -- comm block
1737 when System_Tasking_Protected_Objects_Single_Entry =>
1740 -- procedure Protected_Single_Entry_Call
1741 -- (Object : Protection_Entry_Access;
1742 -- Uninterpreted_Data : System.Address;
1743 -- Mode : Call_Modes);
1746 Make_Procedure_Call_Statement (Loc,
1749 (RTE (RE_Protected_Single_Entry_Call), Loc),
1750 Parameter_Associations =>
1754 Make_Attribute_Reference (Loc,
1755 Prefix => Make_Identifier (Loc, Name_uP),
1756 Attribute_Name => Name_Address),
1759 (RTE (RE_Asynchronous_Call), Loc))));
1762 raise Program_Error;
1766 -- B := Dummy_Communication_Block (Bnn);
1769 Make_Assignment_Statement (Loc,
1771 Make_Identifier (Loc, Name_uB),
1773 Make_Unchecked_Type_Conversion (Loc,
1776 RTE (RE_Dummy_Communication_Block), Loc),
1778 New_Reference_To (Com_Block, Loc))));
1781 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
1785 -- (T._task_id, -- Acceptor
1786 -- Task_Entry_Index! (I), -- E
1787 -- P, -- Uninterpreted_Data
1788 -- Asynchronous_Call, -- Mode
1789 -- F); -- Rendezvous_Successful
1791 -- where T is the task object, I is the entry index, P is the
1792 -- wrapped parameters and F is the status flag.
1795 Make_Procedure_Call_Statement (Loc,
1797 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
1798 Parameter_Associations =>
1800 Make_Selected_Component (Loc, -- T._task_id
1802 Make_Identifier (Loc, Name_uT),
1804 Make_Identifier (Loc, Name_uTask_Id)),
1806 Make_Unchecked_Type_Conversion (Loc, -- entry index
1808 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
1810 Make_Identifier (Loc, Name_uI)),
1812 Make_Identifier (Loc, Name_uP), -- parameter block
1813 New_Reference_To ( -- Asynchronous_Call
1814 RTE (RE_Asynchronous_Call), Loc),
1815 Make_Identifier (Loc, Name_uF)))); -- status flag
1820 Make_Subprogram_Body (Loc,
1822 Make_Disp_Asynchronous_Select_Spec (Typ),
1825 Handled_Statement_Sequence =>
1826 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
1827 end Make_Disp_Asynchronous_Select_Body;
1829 ----------------------------------------
1830 -- Make_Disp_Asynchronous_Select_Spec --
1831 ----------------------------------------
1833 function Make_Disp_Asynchronous_Select_Spec
1834 (Typ : Entity_Id) return Node_Id
1836 Loc : constant Source_Ptr := Sloc (Typ);
1837 Def_Id : constant Node_Id :=
1838 Make_Defining_Identifier (Loc,
1839 Name_uDisp_Asynchronous_Select);
1840 Params : constant List_Id := New_List;
1843 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1845 -- T : in out Typ; -- Object parameter
1846 -- S : Integer; -- Primitive operation slot
1847 -- P : Address; -- Wrapped parameters
1848 -- B : out Dummy_Communication_Block; -- Communication block dummy
1849 -- F : out Boolean; -- Status flag
1851 Append_List_To (Params, New_List (
1853 Make_Parameter_Specification (Loc,
1854 Defining_Identifier =>
1855 Make_Defining_Identifier (Loc, Name_uT),
1857 New_Reference_To (Typ, Loc),
1859 Out_Present => True),
1861 Make_Parameter_Specification (Loc,
1862 Defining_Identifier =>
1863 Make_Defining_Identifier (Loc, Name_uS),
1865 New_Reference_To (Standard_Integer, Loc)),
1867 Make_Parameter_Specification (Loc,
1868 Defining_Identifier =>
1869 Make_Defining_Identifier (Loc, Name_uP),
1871 New_Reference_To (RTE (RE_Address), Loc)),
1873 Make_Parameter_Specification (Loc,
1874 Defining_Identifier =>
1875 Make_Defining_Identifier (Loc, Name_uB),
1877 New_Reference_To (RTE (RE_Dummy_Communication_Block), Loc),
1878 Out_Present => True),
1880 Make_Parameter_Specification (Loc,
1881 Defining_Identifier =>
1882 Make_Defining_Identifier (Loc, Name_uF),
1884 New_Reference_To (Standard_Boolean, Loc),
1885 Out_Present => True)));
1888 Make_Procedure_Specification (Loc,
1889 Defining_Unit_Name => Def_Id,
1890 Parameter_Specifications => Params);
1891 end Make_Disp_Asynchronous_Select_Spec;
1893 ---------------------------------------
1894 -- Make_Disp_Conditional_Select_Body --
1895 ---------------------------------------
1897 -- For interface types, generate:
1899 -- procedure _Disp_Conditional_Select
1900 -- (T : in out <Typ>;
1902 -- P : System.Address;
1903 -- C : out Ada.Tags.Prim_Op_Kind;
1908 -- end _Disp_Conditional_Select;
1910 -- For protected types, generate:
1912 -- procedure _Disp_Conditional_Select
1913 -- (T : in out <Typ>;
1915 -- P : System.Address;
1916 -- C : out Ada.Tags.Prim_Op_Kind;
1920 -- Bnn : System.Tasking.Protected_Objects.Operations.
1921 -- Communication_Block;
1924 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP, S));
1926 -- if C = Ada.Tags.POK_Procedure
1927 -- or else C = Ada.Tags.POK_Protected_Procedure
1928 -- or else C = Ada.Tags.POK_Task_Procedure
1934 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1935 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
1936 -- (T.object'Access,
1937 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
1939 -- System.Tasking.Conditional_Call,
1941 -- F := not Cancelled (Bnn);
1942 -- end _Disp_Conditional_Select;
1944 -- For task types, generate:
1946 -- procedure _Disp_Conditional_Select
1947 -- (T : in out <Typ>;
1949 -- P : System.Address;
1950 -- C : out Ada.Tags.Prim_Op_Kind;
1956 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1957 -- System.Tasking.Rendezvous.Task_Entry_Call
1959 -- System.Tasking.Task_Entry_Index (I),
1961 -- System.Tasking.Conditional_Call,
1963 -- end _Disp_Conditional_Select;
1965 function Make_Disp_Conditional_Select_Body
1966 (Typ : Entity_Id) return Node_Id
1968 Loc : constant Source_Ptr := Sloc (Typ);
1969 Blk_Nam : Entity_Id;
1970 Conc_Typ : Entity_Id := Empty;
1971 Decls : constant List_Id := New_List;
1974 Stmts : constant List_Id := New_List;
1977 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1979 -- Null body is generated for interface types
1981 if Is_Interface (Typ) then
1983 Make_Subprogram_Body (Loc,
1985 Make_Disp_Conditional_Select_Spec (Typ),
1988 Handled_Statement_Sequence =>
1989 Make_Handled_Sequence_Of_Statements (Loc,
1990 New_List (Make_Null_Statement (Loc))));
1993 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1995 if Is_Concurrent_Record_Type (Typ) then
1996 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2001 -- where I will be used to capture the entry index of the primitive
2002 -- wrapper at position S.
2005 Make_Object_Declaration (Loc,
2006 Defining_Identifier =>
2007 Make_Defining_Identifier (Loc, Name_uI),
2008 Object_Definition =>
2009 New_Reference_To (Standard_Integer, Loc)));
2012 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag! (<type>VP), S);
2014 -- if C = POK_Procedure
2015 -- or else C = POK_Protected_Procedure
2016 -- or else C = POK_Task_Procedure;
2022 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
2025 -- Bnn : Communication_Block;
2027 -- where Bnn is the name of the communication block used in the
2028 -- call to Protected_Entry_Call.
2030 Blk_Nam := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
2033 Make_Object_Declaration (Loc,
2034 Defining_Identifier =>
2036 Object_Definition =>
2037 New_Reference_To (RTE (RE_Communication_Block), Loc)));
2040 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
2042 -- I is the entry index and S is the dispatch table slot
2045 Make_Assignment_Statement (Loc,
2047 Make_Identifier (Loc, Name_uI),
2049 Make_Function_Call (Loc,
2051 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
2052 Parameter_Associations =>
2054 Unchecked_Convert_To (RTE (RE_Tag),
2055 New_Reference_To (DT_Ptr, Loc)),
2056 Make_Identifier (Loc, Name_uS)))));
2058 if Ekind (Conc_Typ) = E_Protected_Type then
2060 Obj_Ref := -- T._object'Access
2061 Make_Attribute_Reference (Loc,
2062 Attribute_Name => Name_Unchecked_Access,
2064 Make_Selected_Component (Loc,
2065 Prefix => Make_Identifier (Loc, Name_uT),
2066 Selector_Name => Make_Identifier (Loc, Name_uObject)));
2068 case Corresponding_Runtime_Package (Conc_Typ) is
2069 when System_Tasking_Protected_Objects_Entries =>
2072 -- Protected_Entry_Call
2073 -- (T._object'Access, -- Object
2074 -- Protected_Entry_Index! (I), -- E
2075 -- P, -- Uninterpreted_Data
2076 -- Conditional_Call, -- Mode
2079 -- where T is the protected object, I is the entry index, P
2080 -- are the wrapped parameters and Bnn is the name of the
2081 -- communication block.
2084 Make_Procedure_Call_Statement (Loc,
2086 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
2087 Parameter_Associations =>
2091 Make_Unchecked_Type_Conversion (Loc, -- entry index
2094 (RTE (RE_Protected_Entry_Index), Loc),
2095 Expression => Make_Identifier (Loc, Name_uI)),
2097 Make_Identifier (Loc, Name_uP), -- parameter block
2099 New_Reference_To ( -- Conditional_Call
2100 RTE (RE_Conditional_Call), Loc),
2101 New_Reference_To ( -- Bnn
2104 when System_Tasking_Protected_Objects_Single_Entry =>
2106 -- If we are compiling for a restricted run-time, the call
2107 -- uses the simpler form.
2110 Make_Procedure_Call_Statement (Loc,
2113 (RTE (RE_Protected_Single_Entry_Call), Loc),
2114 Parameter_Associations =>
2118 Make_Attribute_Reference (Loc,
2119 Prefix => Make_Identifier (Loc, Name_uP),
2120 Attribute_Name => Name_Address),
2123 (RTE (RE_Conditional_Call), Loc))));
2125 raise Program_Error;
2129 -- F := not Cancelled (Bnn);
2131 -- where F is the success flag. The status of Cancelled is negated
2132 -- in order to match the behaviour of the version for task types.
2135 Make_Assignment_Statement (Loc,
2137 Make_Identifier (Loc, Name_uF),
2141 Make_Function_Call (Loc,
2143 New_Reference_To (RTE (RE_Cancelled), Loc),
2144 Parameter_Associations =>
2146 New_Reference_To (Blk_Nam, Loc))))));
2148 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2152 -- (T._task_id, -- Acceptor
2153 -- Task_Entry_Index! (I), -- E
2154 -- P, -- Uninterpreted_Data
2155 -- Conditional_Call, -- Mode
2156 -- F); -- Rendezvous_Successful
2158 -- where T is the task object, I is the entry index, P are the
2159 -- wrapped parameters and F is the status flag.
2162 Make_Procedure_Call_Statement (Loc,
2164 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
2165 Parameter_Associations =>
2168 Make_Selected_Component (Loc, -- T._task_id
2170 Make_Identifier (Loc, Name_uT),
2172 Make_Identifier (Loc, Name_uTask_Id)),
2174 Make_Unchecked_Type_Conversion (Loc, -- entry index
2176 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2178 Make_Identifier (Loc, Name_uI)),
2180 Make_Identifier (Loc, Name_uP), -- parameter block
2181 New_Reference_To ( -- Conditional_Call
2182 RTE (RE_Conditional_Call), Loc),
2183 Make_Identifier (Loc, Name_uF)))); -- status flag
2188 Make_Subprogram_Body (Loc,
2190 Make_Disp_Conditional_Select_Spec (Typ),
2193 Handled_Statement_Sequence =>
2194 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2195 end Make_Disp_Conditional_Select_Body;
2197 ---------------------------------------
2198 -- Make_Disp_Conditional_Select_Spec --
2199 ---------------------------------------
2201 function Make_Disp_Conditional_Select_Spec
2202 (Typ : Entity_Id) return Node_Id
2204 Loc : constant Source_Ptr := Sloc (Typ);
2205 Def_Id : constant Node_Id :=
2206 Make_Defining_Identifier (Loc,
2207 Name_uDisp_Conditional_Select);
2208 Params : constant List_Id := New_List;
2211 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2213 -- T : in out Typ; -- Object parameter
2214 -- S : Integer; -- Primitive operation slot
2215 -- P : Address; -- Wrapped parameters
2216 -- C : out Prim_Op_Kind; -- Call kind
2217 -- F : out Boolean; -- Status flag
2219 Append_List_To (Params, New_List (
2221 Make_Parameter_Specification (Loc,
2222 Defining_Identifier =>
2223 Make_Defining_Identifier (Loc, Name_uT),
2225 New_Reference_To (Typ, Loc),
2227 Out_Present => True),
2229 Make_Parameter_Specification (Loc,
2230 Defining_Identifier =>
2231 Make_Defining_Identifier (Loc, Name_uS),
2233 New_Reference_To (Standard_Integer, Loc)),
2235 Make_Parameter_Specification (Loc,
2236 Defining_Identifier =>
2237 Make_Defining_Identifier (Loc, Name_uP),
2239 New_Reference_To (RTE (RE_Address), Loc)),
2241 Make_Parameter_Specification (Loc,
2242 Defining_Identifier =>
2243 Make_Defining_Identifier (Loc, Name_uC),
2245 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2246 Out_Present => True),
2248 Make_Parameter_Specification (Loc,
2249 Defining_Identifier =>
2250 Make_Defining_Identifier (Loc, Name_uF),
2252 New_Reference_To (Standard_Boolean, Loc),
2253 Out_Present => True)));
2256 Make_Procedure_Specification (Loc,
2257 Defining_Unit_Name => Def_Id,
2258 Parameter_Specifications => Params);
2259 end Make_Disp_Conditional_Select_Spec;
2261 -------------------------------------
2262 -- Make_Disp_Get_Prim_Op_Kind_Body --
2263 -------------------------------------
2265 function Make_Disp_Get_Prim_Op_Kind_Body
2266 (Typ : Entity_Id) return Node_Id
2268 Loc : constant Source_Ptr := Sloc (Typ);
2272 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2274 if Is_Interface (Typ) then
2276 Make_Subprogram_Body (Loc,
2278 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2281 Handled_Statement_Sequence =>
2282 Make_Handled_Sequence_Of_Statements (Loc,
2283 New_List (Make_Null_Statement (Loc))));
2286 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2289 -- C := get_prim_op_kind (tag! (<type>VP), S);
2291 -- where C is the out parameter capturing the call kind and S is the
2292 -- dispatch table slot number.
2295 Make_Subprogram_Body (Loc,
2297 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2300 Handled_Statement_Sequence =>
2301 Make_Handled_Sequence_Of_Statements (Loc,
2303 Make_Assignment_Statement (Loc,
2305 Make_Identifier (Loc, Name_uC),
2307 Make_Function_Call (Loc,
2309 New_Reference_To (RTE (RE_Get_Prim_Op_Kind), Loc),
2310 Parameter_Associations => New_List (
2311 Unchecked_Convert_To (RTE (RE_Tag),
2312 New_Reference_To (DT_Ptr, Loc)),
2313 Make_Identifier (Loc, Name_uS)))))));
2314 end Make_Disp_Get_Prim_Op_Kind_Body;
2316 -------------------------------------
2317 -- Make_Disp_Get_Prim_Op_Kind_Spec --
2318 -------------------------------------
2320 function Make_Disp_Get_Prim_Op_Kind_Spec
2321 (Typ : Entity_Id) return Node_Id
2323 Loc : constant Source_Ptr := Sloc (Typ);
2324 Def_Id : constant Node_Id :=
2325 Make_Defining_Identifier (Loc,
2326 Name_uDisp_Get_Prim_Op_Kind);
2327 Params : constant List_Id := New_List;
2330 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2332 -- T : in out Typ; -- Object parameter
2333 -- S : Integer; -- Primitive operation slot
2334 -- C : out Prim_Op_Kind; -- Call kind
2336 Append_List_To (Params, New_List (
2338 Make_Parameter_Specification (Loc,
2339 Defining_Identifier =>
2340 Make_Defining_Identifier (Loc, Name_uT),
2342 New_Reference_To (Typ, Loc),
2344 Out_Present => True),
2346 Make_Parameter_Specification (Loc,
2347 Defining_Identifier =>
2348 Make_Defining_Identifier (Loc, Name_uS),
2350 New_Reference_To (Standard_Integer, Loc)),
2352 Make_Parameter_Specification (Loc,
2353 Defining_Identifier =>
2354 Make_Defining_Identifier (Loc, Name_uC),
2356 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2357 Out_Present => True)));
2360 Make_Procedure_Specification (Loc,
2361 Defining_Unit_Name => Def_Id,
2362 Parameter_Specifications => Params);
2363 end Make_Disp_Get_Prim_Op_Kind_Spec;
2365 --------------------------------
2366 -- Make_Disp_Get_Task_Id_Body --
2367 --------------------------------
2369 function Make_Disp_Get_Task_Id_Body
2370 (Typ : Entity_Id) return Node_Id
2372 Loc : constant Source_Ptr := Sloc (Typ);
2376 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2378 if Is_Concurrent_Record_Type (Typ)
2379 and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
2382 -- return To_Address (_T._task_id);
2385 Make_Simple_Return_Statement (Loc,
2387 Make_Unchecked_Type_Conversion (Loc,
2389 New_Reference_To (RTE (RE_Address), Loc),
2391 Make_Selected_Component (Loc,
2393 Make_Identifier (Loc, Name_uT),
2395 Make_Identifier (Loc, Name_uTask_Id))));
2397 -- A null body is constructed for non-task types
2401 -- return Null_Address;
2404 Make_Simple_Return_Statement (Loc,
2406 New_Reference_To (RTE (RE_Null_Address), Loc));
2410 Make_Subprogram_Body (Loc,
2412 Make_Disp_Get_Task_Id_Spec (Typ),
2415 Handled_Statement_Sequence =>
2416 Make_Handled_Sequence_Of_Statements (Loc,
2418 end Make_Disp_Get_Task_Id_Body;
2420 --------------------------------
2421 -- Make_Disp_Get_Task_Id_Spec --
2422 --------------------------------
2424 function Make_Disp_Get_Task_Id_Spec
2425 (Typ : Entity_Id) return Node_Id
2427 Loc : constant Source_Ptr := Sloc (Typ);
2430 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2433 Make_Function_Specification (Loc,
2434 Defining_Unit_Name =>
2435 Make_Defining_Identifier (Loc, Name_uDisp_Get_Task_Id),
2436 Parameter_Specifications => New_List (
2437 Make_Parameter_Specification (Loc,
2438 Defining_Identifier =>
2439 Make_Defining_Identifier (Loc, Name_uT),
2441 New_Reference_To (Typ, Loc))),
2442 Result_Definition =>
2443 New_Reference_To (RTE (RE_Address), Loc));
2444 end Make_Disp_Get_Task_Id_Spec;
2446 ----------------------------
2447 -- Make_Disp_Requeue_Body --
2448 ----------------------------
2450 function Make_Disp_Requeue_Body
2451 (Typ : Entity_Id) return Node_Id
2453 Loc : constant Source_Ptr := Sloc (Typ);
2454 Conc_Typ : Entity_Id := Empty;
2455 Stmts : constant List_Id := New_List;
2458 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2460 -- Null body is generated for interface types and non-concurrent
2463 if Is_Interface (Typ)
2464 or else not Is_Concurrent_Record_Type (Typ)
2467 Make_Subprogram_Body (Loc,
2469 Make_Disp_Requeue_Spec (Typ),
2472 Handled_Statement_Sequence =>
2473 Make_Handled_Sequence_Of_Statements (Loc,
2474 New_List (Make_Null_Statement (Loc))));
2477 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2479 if Ekind (Conc_Typ) = E_Protected_Type then
2481 -- Generate statements:
2483 -- System.Tasking.Protected_Objects.Operations.
2484 -- Requeue_Protected_Entry
2485 -- (Protection_Entries_Access (P),
2486 -- O._object'Unchecked_Access,
2487 -- Protected_Entry_Index (I),
2490 -- System.Tasking.Protected_Objects.Operations.
2491 -- Requeue_Task_To_Protected_Entry
2492 -- (O._object'Unchecked_Access,
2493 -- Protected_Entry_Index (I),
2497 if Restriction_Active (No_Entry_Queue) then
2498 Append_To (Stmts, Make_Null_Statement (Loc));
2501 Make_If_Statement (Loc,
2503 Make_Identifier (Loc, Name_uF),
2508 -- Call to Requeue_Protected_Entry
2510 Make_Procedure_Call_Statement (Loc,
2513 RTE (RE_Requeue_Protected_Entry), Loc),
2514 Parameter_Associations =>
2517 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
2520 RTE (RE_Protection_Entries_Access), Loc),
2522 Make_Identifier (Loc, Name_uP)),
2524 Make_Attribute_Reference (Loc, -- O._object'Acc
2526 Name_Unchecked_Access,
2528 Make_Selected_Component (Loc,
2530 Make_Identifier (Loc, Name_uO),
2532 Make_Identifier (Loc, Name_uObject))),
2534 Make_Unchecked_Type_Conversion (Loc, -- entry index
2537 RTE (RE_Protected_Entry_Index), Loc),
2539 Make_Identifier (Loc, Name_uI)),
2541 Make_Identifier (Loc, Name_uA)))), -- abort status
2546 -- Call to Requeue_Task_To_Protected_Entry
2548 Make_Procedure_Call_Statement (Loc,
2551 RTE (RE_Requeue_Task_To_Protected_Entry), Loc),
2552 Parameter_Associations =>
2555 Make_Attribute_Reference (Loc, -- O._object'Acc
2557 Name_Unchecked_Access,
2559 Make_Selected_Component (Loc,
2561 Make_Identifier (Loc, Name_uO),
2563 Make_Identifier (Loc, Name_uObject))),
2565 Make_Unchecked_Type_Conversion (Loc, -- entry index
2568 RTE (RE_Protected_Entry_Index), Loc),
2570 Make_Identifier (Loc, Name_uI)),
2572 Make_Identifier (Loc, Name_uA)))))); -- abort status
2575 pragma Assert (Is_Task_Type (Conc_Typ));
2579 -- System.Tasking.Rendezvous.Requeue_Protected_To_Task_Entry
2580 -- (Protection_Entries_Access (P),
2582 -- Task_Entry_Index (I),
2585 -- System.Tasking.Rendezvous.Requeue_Task_Entry
2587 -- Task_Entry_Index (I),
2592 Make_If_Statement (Loc,
2594 Make_Identifier (Loc, Name_uF),
2599 -- Call to Requeue_Protected_To_Task_Entry
2601 Make_Procedure_Call_Statement (Loc,
2604 RTE (RE_Requeue_Protected_To_Task_Entry), Loc),
2606 Parameter_Associations =>
2609 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
2612 RTE (RE_Protection_Entries_Access), Loc),
2614 Make_Identifier (Loc, Name_uP)),
2616 Make_Selected_Component (Loc, -- O._task_id
2618 Make_Identifier (Loc, Name_uO),
2620 Make_Identifier (Loc, Name_uTask_Id)),
2622 Make_Unchecked_Type_Conversion (Loc, -- entry index
2625 RTE (RE_Task_Entry_Index), Loc),
2627 Make_Identifier (Loc, Name_uI)),
2629 Make_Identifier (Loc, Name_uA)))), -- abort status
2634 -- Call to Requeue_Task_Entry
2636 Make_Procedure_Call_Statement (Loc,
2638 New_Reference_To (RTE (RE_Requeue_Task_Entry), Loc),
2640 Parameter_Associations =>
2643 Make_Selected_Component (Loc, -- O._task_id
2645 Make_Identifier (Loc, Name_uO),
2647 Make_Identifier (Loc, Name_uTask_Id)),
2649 Make_Unchecked_Type_Conversion (Loc, -- entry index
2652 RTE (RE_Task_Entry_Index), Loc),
2654 Make_Identifier (Loc, Name_uI)),
2656 Make_Identifier (Loc, Name_uA)))))); -- abort status
2659 -- Even though no declarations are needed in both cases, we allocate
2660 -- a list for entities added by Freeze.
2663 Make_Subprogram_Body (Loc,
2665 Make_Disp_Requeue_Spec (Typ),
2668 Handled_Statement_Sequence =>
2669 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2670 end Make_Disp_Requeue_Body;
2672 ----------------------------
2673 -- Make_Disp_Requeue_Spec --
2674 ----------------------------
2676 function Make_Disp_Requeue_Spec
2677 (Typ : Entity_Id) return Node_Id
2679 Loc : constant Source_Ptr := Sloc (Typ);
2682 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2684 -- O : in out Typ; - Object parameter
2685 -- F : Boolean; - Protected (True) / task (False) flag
2686 -- P : Address; - Protection_Entries_Access value
2687 -- I : Entry_Index - Index of entry call
2688 -- A : Boolean - Abort flag
2690 -- Note that the Protection_Entries_Access value is represented as a
2691 -- System.Address in order to avoid dragging in the tasking runtime
2692 -- when compiling sources without tasking constructs.
2695 Make_Procedure_Specification (Loc,
2696 Defining_Unit_Name =>
2697 Make_Defining_Identifier (Loc, Name_uDisp_Requeue),
2699 Parameter_Specifications =>
2702 Make_Parameter_Specification (Loc, -- O
2703 Defining_Identifier =>
2704 Make_Defining_Identifier (Loc, Name_uO),
2706 New_Reference_To (Typ, Loc),
2708 Out_Present => True),
2710 Make_Parameter_Specification (Loc, -- F
2711 Defining_Identifier =>
2712 Make_Defining_Identifier (Loc, Name_uF),
2714 New_Reference_To (Standard_Boolean, Loc)),
2716 Make_Parameter_Specification (Loc, -- P
2717 Defining_Identifier =>
2718 Make_Defining_Identifier (Loc, Name_uP),
2720 New_Reference_To (RTE (RE_Address), Loc)),
2722 Make_Parameter_Specification (Loc, -- I
2723 Defining_Identifier =>
2724 Make_Defining_Identifier (Loc, Name_uI),
2726 New_Reference_To (Standard_Integer, Loc)),
2728 Make_Parameter_Specification (Loc, -- A
2729 Defining_Identifier =>
2730 Make_Defining_Identifier (Loc, Name_uA),
2732 New_Reference_To (Standard_Boolean, Loc))));
2733 end Make_Disp_Requeue_Spec;
2735 ---------------------------------
2736 -- Make_Disp_Timed_Select_Body --
2737 ---------------------------------
2739 -- For interface types, generate:
2741 -- procedure _Disp_Timed_Select
2742 -- (T : in out <Typ>;
2744 -- P : System.Address;
2747 -- C : out Ada.Tags.Prim_Op_Kind;
2752 -- end _Disp_Timed_Select;
2754 -- For protected types, generate:
2756 -- procedure _Disp_Timed_Select
2757 -- (T : in out <Typ>;
2759 -- P : System.Address;
2762 -- C : out Ada.Tags.Prim_Op_Kind;
2768 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP), S);
2770 -- if C = Ada.Tags.POK_Procedure
2771 -- or else C = Ada.Tags.POK_Protected_Procedure
2772 -- or else C = Ada.Tags.POK_Task_Procedure
2778 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
2779 -- System.Tasking.Protected_Objects.Operations.
2780 -- Timed_Protected_Entry_Call
2781 -- (T._object'Access,
2782 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
2787 -- end _Disp_Timed_Select;
2789 -- For task types, generate:
2791 -- procedure _Disp_Timed_Select
2792 -- (T : in out <Typ>;
2794 -- P : System.Address;
2797 -- C : out Ada.Tags.Prim_Op_Kind;
2803 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
2804 -- System.Tasking.Rendezvous.Timed_Task_Entry_Call
2806 -- System.Tasking.Task_Entry_Index (I),
2811 -- end _Disp_Time_Select;
2813 function Make_Disp_Timed_Select_Body
2814 (Typ : Entity_Id) return Node_Id
2816 Loc : constant Source_Ptr := Sloc (Typ);
2817 Conc_Typ : Entity_Id := Empty;
2818 Decls : constant List_Id := New_List;
2821 Stmts : constant List_Id := New_List;
2824 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2826 -- Null body is generated for interface types
2828 if Is_Interface (Typ) then
2830 Make_Subprogram_Body (Loc,
2832 Make_Disp_Timed_Select_Spec (Typ),
2835 Handled_Statement_Sequence =>
2836 Make_Handled_Sequence_Of_Statements (Loc,
2837 New_List (Make_Null_Statement (Loc))));
2840 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2842 if Is_Concurrent_Record_Type (Typ) then
2843 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2848 -- where I will be used to capture the entry index of the primitive
2849 -- wrapper at position S.
2852 Make_Object_Declaration (Loc,
2853 Defining_Identifier =>
2854 Make_Defining_Identifier (Loc, Name_uI),
2855 Object_Definition =>
2856 New_Reference_To (Standard_Integer, Loc)));
2859 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
2861 -- if C = POK_Procedure
2862 -- or else C = POK_Protected_Procedure
2863 -- or else C = POK_Task_Procedure;
2869 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
2872 -- I := Get_Entry_Index (tag! (<type>VP), S);
2874 -- I is the entry index and S is the dispatch table slot
2877 Make_Assignment_Statement (Loc,
2879 Make_Identifier (Loc, Name_uI),
2881 Make_Function_Call (Loc,
2883 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
2884 Parameter_Associations =>
2886 Unchecked_Convert_To (RTE (RE_Tag),
2887 New_Reference_To (DT_Ptr, Loc)),
2888 Make_Identifier (Loc, Name_uS)))));
2892 if Ekind (Conc_Typ) = E_Protected_Type then
2894 -- Build T._object'Access
2897 Make_Attribute_Reference (Loc,
2898 Attribute_Name => Name_Unchecked_Access,
2900 Make_Selected_Component (Loc,
2901 Prefix => Make_Identifier (Loc, Name_uT),
2902 Selector_Name => Make_Identifier (Loc, Name_uObject)));
2904 -- Normal case, No_Entry_Queue restriction not active. In this
2905 -- case we generate:
2907 -- Timed_Protected_Entry_Call
2908 -- (T._object'access,
2909 -- Protected_Entry_Index! (I),
2912 -- where T is the protected object, I is the entry index, P are
2913 -- the wrapped parameters, D is the delay amount, M is the delay
2914 -- mode and F is the status flag.
2916 case Corresponding_Runtime_Package (Conc_Typ) is
2917 when System_Tasking_Protected_Objects_Entries =>
2919 Make_Procedure_Call_Statement (Loc,
2922 (RTE (RE_Timed_Protected_Entry_Call), Loc),
2923 Parameter_Associations =>
2927 Make_Unchecked_Type_Conversion (Loc, -- entry index
2930 (RTE (RE_Protected_Entry_Index), Loc),
2932 Make_Identifier (Loc, Name_uI)),
2934 Make_Identifier (Loc, Name_uP), -- parameter block
2935 Make_Identifier (Loc, Name_uD), -- delay
2936 Make_Identifier (Loc, Name_uM), -- delay mode
2937 Make_Identifier (Loc, Name_uF)))); -- status flag
2939 when System_Tasking_Protected_Objects_Single_Entry =>
2942 -- Timed_Protected_Single_Entry_Call
2943 -- (T._object'access, P, D, M, F);
2945 -- where T is the protected object, P is the wrapped
2946 -- parameters, D is the delay amount, M is the delay mode, F
2947 -- is the status flag.
2950 Make_Procedure_Call_Statement (Loc,
2953 (RTE (RE_Timed_Protected_Single_Entry_Call), Loc),
2954 Parameter_Associations =>
2957 Make_Identifier (Loc, Name_uP), -- parameter block
2958 Make_Identifier (Loc, Name_uD), -- delay
2959 Make_Identifier (Loc, Name_uM), -- delay mode
2960 Make_Identifier (Loc, Name_uF)))); -- status flag
2963 raise Program_Error;
2969 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2972 -- Timed_Task_Entry_Call (
2974 -- Task_Entry_Index! (I),
2980 -- where T is the task object, I is the entry index, P are the
2981 -- wrapped parameters, D is the delay amount, M is the delay
2982 -- mode and F is the status flag.
2985 Make_Procedure_Call_Statement (Loc,
2987 New_Reference_To (RTE (RE_Timed_Task_Entry_Call), Loc),
2988 Parameter_Associations =>
2991 Make_Selected_Component (Loc, -- T._task_id
2993 Make_Identifier (Loc, Name_uT),
2995 Make_Identifier (Loc, Name_uTask_Id)),
2997 Make_Unchecked_Type_Conversion (Loc, -- entry index
2999 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
3001 Make_Identifier (Loc, Name_uI)),
3003 Make_Identifier (Loc, Name_uP), -- parameter block
3004 Make_Identifier (Loc, Name_uD), -- delay
3005 Make_Identifier (Loc, Name_uM), -- delay mode
3006 Make_Identifier (Loc, Name_uF)))); -- status flag
3011 Make_Subprogram_Body (Loc,
3013 Make_Disp_Timed_Select_Spec (Typ),
3016 Handled_Statement_Sequence =>
3017 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
3018 end Make_Disp_Timed_Select_Body;
3020 ---------------------------------
3021 -- Make_Disp_Timed_Select_Spec --
3022 ---------------------------------
3024 function Make_Disp_Timed_Select_Spec
3025 (Typ : Entity_Id) return Node_Id
3027 Loc : constant Source_Ptr := Sloc (Typ);
3028 Def_Id : constant Node_Id :=
3029 Make_Defining_Identifier (Loc,
3030 Name_uDisp_Timed_Select);
3031 Params : constant List_Id := New_List;
3034 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3036 -- T : in out Typ; -- Object parameter
3037 -- S : Integer; -- Primitive operation slot
3038 -- P : Address; -- Wrapped parameters
3039 -- D : Duration; -- Delay
3040 -- M : Integer; -- Delay Mode
3041 -- C : out Prim_Op_Kind; -- Call kind
3042 -- F : out Boolean; -- Status flag
3044 Append_List_To (Params, New_List (
3046 Make_Parameter_Specification (Loc,
3047 Defining_Identifier =>
3048 Make_Defining_Identifier (Loc, Name_uT),
3050 New_Reference_To (Typ, Loc),
3052 Out_Present => True),
3054 Make_Parameter_Specification (Loc,
3055 Defining_Identifier =>
3056 Make_Defining_Identifier (Loc, Name_uS),
3058 New_Reference_To (Standard_Integer, Loc)),
3060 Make_Parameter_Specification (Loc,
3061 Defining_Identifier =>
3062 Make_Defining_Identifier (Loc, Name_uP),
3064 New_Reference_To (RTE (RE_Address), Loc)),
3066 Make_Parameter_Specification (Loc,
3067 Defining_Identifier =>
3068 Make_Defining_Identifier (Loc, Name_uD),
3070 New_Reference_To (Standard_Duration, Loc)),
3072 Make_Parameter_Specification (Loc,
3073 Defining_Identifier =>
3074 Make_Defining_Identifier (Loc, Name_uM),
3076 New_Reference_To (Standard_Integer, Loc)),
3078 Make_Parameter_Specification (Loc,
3079 Defining_Identifier =>
3080 Make_Defining_Identifier (Loc, Name_uC),
3082 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
3083 Out_Present => True)));
3086 Make_Parameter_Specification (Loc,
3087 Defining_Identifier =>
3088 Make_Defining_Identifier (Loc, Name_uF),
3090 New_Reference_To (Standard_Boolean, Loc),
3091 Out_Present => True));
3094 Make_Procedure_Specification (Loc,
3095 Defining_Unit_Name => Def_Id,
3096 Parameter_Specifications => Params);
3097 end Make_Disp_Timed_Select_Spec;
3103 -- The frontend supports two models for expanding dispatch tables
3104 -- associated with library-level defined tagged types: statically
3105 -- and non-statically allocated dispatch tables. In the former case
3106 -- the object containing the dispatch table is constant and it is
3107 -- initialized by means of a positional aggregate. In the latter case,
3108 -- the object containing the dispatch table is a variable which is
3109 -- initialized by means of assignments.
3111 -- In case of locally defined tagged types, the object containing the
3112 -- object containing the dispatch table is always a variable (instead
3113 -- of a constant). This is currently required to give support to late
3114 -- overriding of primitives. For example:
3116 -- procedure Example is
3118 -- type T1 is tagged null record;
3119 -- procedure Prim (O : T1);
3122 -- type T2 is new Pkg.T1 with null record;
3123 -- procedure Prim (X : T2) is -- late overriding
3129 function Make_DT (Typ : Entity_Id; N : Node_Id := Empty) return List_Id is
3130 Loc : constant Source_Ptr := Sloc (Typ);
3132 Max_Predef_Prims : constant Int :=
3136 (Parent (RTE (RE_Max_Predef_Prims)))));
3138 DT_Decl : constant Elist_Id := New_Elmt_List;
3139 DT_Aggr : constant Elist_Id := New_Elmt_List;
3140 -- Entities marked with attribute Is_Dispatch_Table_Entity
3142 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id);
3143 -- Verify that all non-tagged types in the profile of a subprogram
3144 -- are frozen at the point the subprogram is frozen. This enforces
3145 -- the rule on RM 13.14 (14) as modified by AI05-019. At the point a
3146 -- subprogram is frozen, enough must be known about it to build the
3147 -- activation record for it, which requires at least that the size of
3148 -- all parameters be known. Controlling arguments are by-reference,
3149 -- and therefore the rule only applies to non-tagged types.
3150 -- Typical violation of the rule involves an object declaration that
3151 -- freezes a tagged type, when one of its primitive operations has a
3152 -- type in its profile whose full view has not been analyzed yet.
3154 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0);
3155 -- Export the dispatch table DT of tagged type Typ. Required to generate
3156 -- forward references and statically allocate the table. For primary
3157 -- dispatch tables Index is 0; for secondary dispatch tables the value
3158 -- of index must match the Suffix_Index value assigned to the table by
3159 -- Make_Tags when generating its unique external name, and it is used to
3160 -- retrieve from the Dispatch_Table_Wrappers list associated with Typ
3161 -- the external name generated by Import_DT.
3163 procedure Make_Secondary_DT
3167 Num_Iface_Prims : Nat;
3168 Iface_DT_Ptr : Entity_Id;
3169 Predef_Prims_Ptr : Entity_Id;
3170 Build_Thunks : Boolean;
3172 -- Ada 2005 (AI-251): Expand the declarations for a Secondary Dispatch
3173 -- Table of Typ associated with Iface. Each abstract interface of Typ
3174 -- has two secondary dispatch tables: one containing pointers to thunks
3175 -- and another containing pointers to the primitives covering the
3176 -- interface primitives. The former secondary table is generated when
3177 -- Build_Thunks is True, and provides common support for dispatching
3178 -- calls through interface types; the latter secondary table is
3179 -- generated when Build_Thunks is False, and provides support for
3180 -- Generic Dispatching Constructors that dispatch calls through
3181 -- interface types. When constructing this latter table the value
3182 -- of Suffix_Index is -1 to indicate that there is no need to export
3183 -- such table when building statically allocated dispatch tables; a
3184 -- positive value of Suffix_Index must match the Suffix_Index value
3185 -- assigned to this secondary dispatch table by Make_Tags when its
3186 -- unique external name was generated.
3188 ------------------------------
3189 -- Check_Premature_Freezing --
3190 ------------------------------
3192 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id) is
3195 and then Is_Private_Type (Typ)
3196 and then No (Full_View (Typ))
3197 and then not Is_Generic_Type (Typ)
3198 and then not Is_Tagged_Type (Typ)
3199 and then not Is_Frozen (Typ)
3201 Error_Msg_Sloc := Sloc (Subp);
3203 ("declaration must appear after completion of type &", N, Typ);
3205 ("\which is an untagged type in the profile of"
3206 & " primitive operation & declared#",
3209 end Check_Premature_Freezing;
3215 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0)
3221 Set_Is_Statically_Allocated (DT);
3222 Set_Is_True_Constant (DT);
3223 Set_Is_Exported (DT);
3226 Elmt := First_Elmt (Dispatch_Table_Wrappers (Typ));
3227 while Count /= Index loop
3232 pragma Assert (Related_Type (Node (Elmt)) = Typ);
3235 (Entity => Node (Elmt),
3236 Has_Suffix => True);
3238 Set_Interface_Name (DT,
3239 Make_String_Literal (Loc,
3240 Strval => String_From_Name_Buffer));
3242 -- Ensure proper Sprint output of this implicit importation
3244 Set_Is_Internal (DT);
3248 -----------------------
3249 -- Make_Secondary_DT --
3250 -----------------------
3252 procedure Make_Secondary_DT
3256 Num_Iface_Prims : Nat;
3257 Iface_DT_Ptr : Entity_Id;
3258 Predef_Prims_Ptr : Entity_Id;
3259 Build_Thunks : Boolean;
3262 Loc : constant Source_Ptr := Sloc (Typ);
3263 Exporting_Table : constant Boolean :=
3264 Building_Static_DT (Typ)
3265 and then Suffix_Index > 0;
3266 Iface_DT : constant Entity_Id :=
3267 Make_Defining_Identifier (Loc,
3268 Chars => New_Internal_Name ('T'));
3269 Name_Predef_Prims : constant Name_Id := New_Internal_Name ('R');
3270 Predef_Prims : constant Entity_Id :=
3271 Make_Defining_Identifier (Loc,
3272 Chars => Name_Predef_Prims);
3273 DT_Constr_List : List_Id;
3274 DT_Aggr_List : List_Id;
3275 Empty_DT : Boolean := False;
3276 Nb_Predef_Prims : Nat := 0;
3280 OSD_Aggr_List : List_Id;
3283 Prim_Elmt : Elmt_Id;
3284 Prim_Ops_Aggr_List : List_Id;
3287 -- Handle cases in which we do not generate statically allocated
3290 if not Building_Static_DT (Typ) then
3291 Set_Ekind (Predef_Prims, E_Variable);
3292 Set_Ekind (Iface_DT, E_Variable);
3294 -- Statically allocated dispatch tables and related entities are
3298 Set_Ekind (Predef_Prims, E_Constant);
3299 Set_Is_Statically_Allocated (Predef_Prims);
3300 Set_Is_True_Constant (Predef_Prims);
3302 Set_Ekind (Iface_DT, E_Constant);
3303 Set_Is_Statically_Allocated (Iface_DT);
3304 Set_Is_True_Constant (Iface_DT);
3307 -- Calculate the number of slots of the dispatch table. If the number
3308 -- of primitives of Typ is 0 we reserve a dummy single entry for its
3309 -- DT because at run-time the pointer to this dummy entry will be
3312 if Num_Iface_Prims = 0 then
3316 Nb_Prim := Num_Iface_Prims;
3321 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
3322 -- (predef-prim-op-thunk-1'address,
3323 -- predef-prim-op-thunk-2'address,
3325 -- predef-prim-op-thunk-n'address);
3326 -- for Predef_Prims'Alignment use Address'Alignment
3328 -- Stage 1: Calculate the number of predefined primitives
3330 if not Building_Static_DT (Typ) then
3331 Nb_Predef_Prims := Max_Predef_Prims;
3333 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3334 while Present (Prim_Elmt) loop
3335 Prim := Node (Prim_Elmt);
3337 if Is_Predefined_Dispatching_Operation (Prim)
3338 and then not Is_Abstract_Subprogram (Prim)
3340 Pos := UI_To_Int (DT_Position (Prim));
3342 if Pos > Nb_Predef_Prims then
3343 Nb_Predef_Prims := Pos;
3347 Next_Elmt (Prim_Elmt);
3351 -- Stage 2: Create the thunks associated with the predefined
3352 -- primitives and save their entity to fill the aggregate.
3355 Prim_Table : array (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
3357 Thunk_Id : Entity_Id;
3358 Thunk_Code : Node_Id;
3361 Prim_Ops_Aggr_List := New_List;
3362 Prim_Table := (others => Empty);
3364 if Building_Static_DT (Typ) then
3365 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3366 while Present (Prim_Elmt) loop
3367 Prim := Node (Prim_Elmt);
3369 if Is_Predefined_Dispatching_Operation (Prim)
3370 and then not Is_Abstract_Subprogram (Prim)
3371 and then not Present (Prim_Table
3372 (UI_To_Int (DT_Position (Prim))))
3374 if not Build_Thunks then
3375 Prim_Table (UI_To_Int (DT_Position (Prim))) :=
3379 while Present (Alias (Prim)) loop
3380 Prim := Alias (Prim);
3383 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
3385 if Present (Thunk_Id) then
3386 Append_To (Result, Thunk_Code);
3387 Prim_Table (UI_To_Int (DT_Position (Prim)))
3393 Next_Elmt (Prim_Elmt);
3397 for J in Prim_Table'Range loop
3398 if Present (Prim_Table (J)) then
3400 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
3401 Make_Attribute_Reference (Loc,
3402 Prefix => New_Reference_To (Prim_Table (J), Loc),
3403 Attribute_Name => Name_Unrestricted_Access));
3405 New_Node := Make_Null (Loc);
3408 Append_To (Prim_Ops_Aggr_List, New_Node);
3412 Make_Aggregate (Loc,
3413 Expressions => Prim_Ops_Aggr_List);
3415 -- Remember aggregates initializing dispatch tables
3417 Append_Elmt (New_Node, DT_Aggr);
3420 Make_Subtype_Declaration (Loc,
3421 Defining_Identifier =>
3422 Make_Defining_Identifier (Loc,
3423 New_Internal_Name ('S')),
3424 Subtype_Indication =>
3425 New_Reference_To (RTE (RE_Address_Array), Loc));
3427 Append_To (Result, Decl);
3430 Make_Object_Declaration (Loc,
3431 Defining_Identifier => Predef_Prims,
3432 Constant_Present => Building_Static_DT (Typ),
3433 Aliased_Present => True,
3434 Object_Definition => New_Reference_To
3435 (Defining_Identifier (Decl), Loc),
3436 Expression => New_Node));
3439 Make_Attribute_Definition_Clause (Loc,
3440 Name => New_Reference_To (Predef_Prims, Loc),
3441 Chars => Name_Alignment,
3443 Make_Attribute_Reference (Loc,
3445 New_Reference_To (RTE (RE_Integer_Address), Loc),
3446 Attribute_Name => Name_Alignment)));
3451 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
3452 -- (OSD_Table => (1 => <value>,
3456 -- Iface_DT : Dispatch_Table (Nb_Prims) :=
3457 -- ([ Signature => <sig-value> ],
3458 -- Tag_Kind => <tag_kind-value>,
3459 -- Predef_Prims => Predef_Prims'Address,
3460 -- Offset_To_Top => 0,
3461 -- OSD => OSD'Address,
3462 -- Prims_Ptr => (prim-op-1'address,
3463 -- prim-op-2'address,
3465 -- prim-op-n'address));
3466 -- for Iface_DT'Alignment use Address'Alignment;
3468 -- Stage 3: Initialize the discriminant and the record components
3470 DT_Constr_List := New_List;
3471 DT_Aggr_List := New_List;
3473 -- Nb_Prim. If the tagged type has no primitives we add a dummy
3474 -- slot whose address will be the tag of this type.
3477 New_Node := Make_Integer_Literal (Loc, 1);
3479 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
3482 Append_To (DT_Constr_List, New_Node);
3483 Append_To (DT_Aggr_List, New_Copy (New_Node));
3487 if RTE_Record_Component_Available (RE_Signature) then
3488 Append_To (DT_Aggr_List,
3489 New_Reference_To (RTE (RE_Secondary_DT), Loc));
3494 if RTE_Record_Component_Available (RE_Tag_Kind) then
3495 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
3500 Append_To (DT_Aggr_List,
3501 Make_Attribute_Reference (Loc,
3502 Prefix => New_Reference_To (Predef_Prims, Loc),
3503 Attribute_Name => Name_Address));
3505 -- Note: The correct value of Offset_To_Top will be set by the init
3508 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
3510 -- Generate the Object Specific Data table required to dispatch calls
3511 -- through synchronized interfaces.
3514 or else Is_Abstract_Type (Typ)
3515 or else Is_Controlled (Typ)
3516 or else Restriction_Active (No_Dispatching_Calls)
3517 or else not Is_Limited_Type (Typ)
3518 or else not Has_Interfaces (Typ)
3519 or else not Build_Thunks
3520 or else not RTE_Record_Component_Available (RE_OSD_Table)
3522 -- No OSD table required
3524 Append_To (DT_Aggr_List,
3525 New_Reference_To (RTE (RE_Null_Address), Loc));
3528 OSD_Aggr_List := New_List;
3531 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
3533 Prim_Alias : Entity_Id;
3534 Prim_Elmt : Elmt_Id;
3540 Prim_Table := (others => Empty);
3541 Prim_Alias := Empty;
3543 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3544 while Present (Prim_Elmt) loop
3545 Prim := Node (Prim_Elmt);
3547 if Present (Interface_Alias (Prim))
3548 and then Find_Dispatching_Type
3549 (Interface_Alias (Prim)) = Iface
3551 Prim_Alias := Interface_Alias (Prim);
3554 while Present (Alias (E)) loop
3558 Pos := UI_To_Int (DT_Position (Prim_Alias));
3560 if Present (Prim_Table (Pos)) then
3561 pragma Assert (Prim_Table (Pos) = E);
3565 Prim_Table (Pos) := E;
3567 Append_To (OSD_Aggr_List,
3568 Make_Component_Association (Loc,
3569 Choices => New_List (
3570 Make_Integer_Literal (Loc,
3571 DT_Position (Prim_Alias))),
3573 Make_Integer_Literal (Loc,
3574 DT_Position (Alias (Prim)))));
3580 Next_Elmt (Prim_Elmt);
3582 pragma Assert (Count = Nb_Prim);
3585 OSD := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
3588 Make_Object_Declaration (Loc,
3589 Defining_Identifier => OSD,
3590 Object_Definition =>
3591 Make_Subtype_Indication (Loc,
3593 New_Reference_To (RTE (RE_Object_Specific_Data), Loc),
3595 Make_Index_Or_Discriminant_Constraint (Loc,
3596 Constraints => New_List (
3597 Make_Integer_Literal (Loc, Nb_Prim)))),
3598 Expression => Make_Aggregate (Loc,
3599 Component_Associations => New_List (
3600 Make_Component_Association (Loc,
3601 Choices => New_List (
3603 (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
3605 Make_Integer_Literal (Loc, Nb_Prim)),
3607 Make_Component_Association (Loc,
3608 Choices => New_List (
3610 (RTE_Record_Component (RE_OSD_Table), Loc)),
3611 Expression => Make_Aggregate (Loc,
3612 Component_Associations => OSD_Aggr_List))))));
3615 Make_Attribute_Definition_Clause (Loc,
3616 Name => New_Reference_To (OSD, Loc),
3617 Chars => Name_Alignment,
3619 Make_Attribute_Reference (Loc,
3621 New_Reference_To (RTE (RE_Integer_Address), Loc),
3622 Attribute_Name => Name_Alignment)));
3624 -- In secondary dispatch tables the Typeinfo component contains
3625 -- the address of the Object Specific Data (see a-tags.ads)
3627 Append_To (DT_Aggr_List,
3628 Make_Attribute_Reference (Loc,
3629 Prefix => New_Reference_To (OSD, Loc),
3630 Attribute_Name => Name_Address));
3633 -- Initialize the table of primitive operations
3635 Prim_Ops_Aggr_List := New_List;
3638 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
3640 elsif Is_Abstract_Type (Typ)
3641 or else not Building_Static_DT (Typ)
3643 for J in 1 .. Nb_Prim loop
3644 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
3649 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
3651 Thunk_Code : Node_Id;
3652 Thunk_Id : Entity_Id;
3655 Prim_Table := (others => Empty);
3657 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3658 while Present (Prim_Elmt) loop
3659 Prim := Node (Prim_Elmt);
3661 if not Is_Predefined_Dispatching_Operation (Prim)
3662 and then Present (Interface_Alias (Prim))
3663 and then not Is_Abstract_Subprogram (Alias (Prim))
3664 and then not Is_Imported (Alias (Prim))
3665 and then Find_Dispatching_Type
3666 (Interface_Alias (Prim)) = Iface
3668 -- Generate the code of the thunk only if the abstract
3669 -- interface type is not an immediate ancestor of
3670 -- Tagged_Type; otherwise the DT associated with the
3671 -- interface is the primary DT.
3673 and then not Is_Ancestor (Iface, Typ)
3675 if not Build_Thunks then
3677 UI_To_Int (DT_Position (Interface_Alias (Prim)));
3678 Prim_Table (Pos) := Alias (Prim);
3680 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
3682 if Present (Thunk_Id) then
3684 UI_To_Int (DT_Position (Interface_Alias (Prim)));
3686 Prim_Table (Pos) := Thunk_Id;
3687 Append_To (Result, Thunk_Code);
3692 Next_Elmt (Prim_Elmt);
3695 for J in Prim_Table'Range loop
3696 if Present (Prim_Table (J)) then
3698 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
3699 Make_Attribute_Reference (Loc,
3700 Prefix => New_Reference_To (Prim_Table (J), Loc),
3701 Attribute_Name => Name_Unrestricted_Access));
3703 New_Node := Make_Null (Loc);
3706 Append_To (Prim_Ops_Aggr_List, New_Node);
3712 Make_Aggregate (Loc,
3713 Expressions => Prim_Ops_Aggr_List);
3715 Append_To (DT_Aggr_List, New_Node);
3717 -- Remember aggregates initializing dispatch tables
3719 Append_Elmt (New_Node, DT_Aggr);
3721 -- Note: Secondary dispatch tables cannot be declared constant
3722 -- because the component Offset_To_Top is currently initialized
3723 -- by the IP routine.
3726 Make_Object_Declaration (Loc,
3727 Defining_Identifier => Iface_DT,
3728 Aliased_Present => True,
3729 Constant_Present => False,
3731 Object_Definition =>
3732 Make_Subtype_Indication (Loc,
3733 Subtype_Mark => New_Reference_To
3734 (RTE (RE_Dispatch_Table_Wrapper), Loc),
3735 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
3736 Constraints => DT_Constr_List)),
3739 Make_Aggregate (Loc,
3740 Expressions => DT_Aggr_List)));
3743 Make_Attribute_Definition_Clause (Loc,
3744 Name => New_Reference_To (Iface_DT, Loc),
3745 Chars => Name_Alignment,
3748 Make_Attribute_Reference (Loc,
3750 New_Reference_To (RTE (RE_Integer_Address), Loc),
3751 Attribute_Name => Name_Alignment)));
3753 if Exporting_Table then
3754 Export_DT (Typ, Iface_DT, Suffix_Index);
3756 -- Generate code to create the pointer to the dispatch table
3758 -- Iface_DT_Ptr : Tag := Tag!(DT.Prims_Ptr'Address);
3760 -- Note: This declaration is not added here if the table is exported
3761 -- because in such case Make_Tags has already added this declaration.
3765 Make_Object_Declaration (Loc,
3766 Defining_Identifier => Iface_DT_Ptr,
3767 Constant_Present => True,
3769 Object_Definition =>
3770 New_Reference_To (RTE (RE_Interface_Tag), Loc),
3773 Unchecked_Convert_To (RTE (RE_Interface_Tag),
3774 Make_Attribute_Reference (Loc,
3776 Make_Selected_Component (Loc,
3777 Prefix => New_Reference_To (Iface_DT, Loc),
3780 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
3781 Attribute_Name => Name_Address))));
3785 Make_Object_Declaration (Loc,
3786 Defining_Identifier => Predef_Prims_Ptr,
3787 Constant_Present => True,
3789 Object_Definition =>
3790 New_Reference_To (RTE (RE_Address), Loc),
3793 Make_Attribute_Reference (Loc,
3795 Make_Selected_Component (Loc,
3796 Prefix => New_Reference_To (Iface_DT, Loc),
3799 (RTE_Record_Component (RE_Predef_Prims), Loc)),
3800 Attribute_Name => Name_Address)));
3802 -- Remember entities containing dispatch tables
3804 Append_Elmt (Predef_Prims, DT_Decl);
3805 Append_Elmt (Iface_DT, DT_Decl);
3806 end Make_Secondary_DT;
3810 Elab_Code : constant List_Id := New_List;
3811 Result : constant List_Id := New_List;
3812 Tname : constant Name_Id := Chars (Typ);
3814 AI_Tag_Elmt : Elmt_Id;
3815 AI_Tag_Comp : Elmt_Id;
3816 DT_Aggr_List : List_Id;
3817 DT_Constr_List : List_Id;
3821 Iface_Table_Node : Node_Id;
3822 Name_ITable : Name_Id;
3823 Nb_Predef_Prims : Nat := 0;
3826 Num_Ifaces : Nat := 0;
3827 Parent_Typ : Entity_Id;
3829 Prim_Elmt : Elmt_Id;
3830 Prim_Ops_Aggr_List : List_Id;
3832 Typ_Comps : Elist_Id;
3833 Typ_Ifaces : Elist_Id;
3834 TSD_Aggr_List : List_Id;
3835 TSD_Tags_List : List_Id;
3837 -- The following name entries are used by Make_DT to generate a number
3838 -- of entities related to a tagged type. These entities may be generated
3839 -- in a scope other than that of the tagged type declaration, and if
3840 -- the entities for two tagged types with the same name happen to be
3841 -- generated in the same scope, we have to take care to use different
3842 -- names. This is achieved by means of a unique serial number appended
3843 -- to each generated entity name.
3845 Name_DT : constant Name_Id :=
3846 New_External_Name (Tname, 'T', Suffix_Index => -1);
3847 Name_Exname : constant Name_Id :=
3848 New_External_Name (Tname, 'E', Suffix_Index => -1);
3849 Name_HT_Link : constant Name_Id :=
3850 New_External_Name (Tname, 'H', Suffix_Index => -1);
3851 Name_Predef_Prims : constant Name_Id :=
3852 New_External_Name (Tname, 'R', Suffix_Index => -1);
3853 Name_SSD : constant Name_Id :=
3854 New_External_Name (Tname, 'S', Suffix_Index => -1);
3855 Name_TSD : constant Name_Id :=
3856 New_External_Name (Tname, 'B', Suffix_Index => -1);
3858 -- Entities built with above names
3860 DT : constant Entity_Id :=
3861 Make_Defining_Identifier (Loc, Name_DT);
3862 Exname : constant Entity_Id :=
3863 Make_Defining_Identifier (Loc, Name_Exname);
3864 HT_Link : constant Entity_Id :=
3865 Make_Defining_Identifier (Loc, Name_HT_Link);
3866 Predef_Prims : constant Entity_Id :=
3867 Make_Defining_Identifier (Loc, Name_Predef_Prims);
3868 SSD : constant Entity_Id :=
3869 Make_Defining_Identifier (Loc, Name_SSD);
3870 TSD : constant Entity_Id :=
3871 Make_Defining_Identifier (Loc, Name_TSD);
3873 -- Start of processing for Make_DT
3876 pragma Assert (Is_Frozen (Typ));
3878 -- Handle cases in which there is no need to build the dispatch table
3880 if Has_Dispatch_Table (Typ)
3881 or else No (Access_Disp_Table (Typ))
3882 or else Is_CPP_Class (Typ)
3886 elsif No_Run_Time_Mode then
3887 Error_Msg_CRT ("tagged types", Typ);
3890 elsif not RTE_Available (RE_Tag) then
3892 Make_Object_Declaration (Loc,
3893 Defining_Identifier => Node (First_Elmt
3894 (Access_Disp_Table (Typ))),
3895 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
3896 Constant_Present => True,
3898 Unchecked_Convert_To (RTE (RE_Tag),
3899 New_Reference_To (RTE (RE_Null_Address), Loc))));
3901 Analyze_List (Result, Suppress => All_Checks);
3902 Error_Msg_CRT ("tagged types", Typ);
3906 -- Ensure that the value of Max_Predef_Prims defined in a-tags is
3907 -- correct. Valid values are 10 under configurable runtime or 16
3908 -- with full runtime.
3910 if RTE_Available (RE_Interface_Data) then
3911 if Max_Predef_Prims /= 16 then
3912 Error_Msg_N ("run-time library configuration error", Typ);
3916 if Max_Predef_Prims /= 10 then
3917 Error_Msg_N ("run-time library configuration error", Typ);
3918 Error_Msg_CRT ("tagged types", Typ);
3923 -- Initialize Parent_Typ handling private types
3925 Parent_Typ := Etype (Typ);
3927 if Present (Full_View (Parent_Typ)) then
3928 Parent_Typ := Full_View (Parent_Typ);
3931 -- Ensure that all the primitives are frozen. This is only required when
3932 -- building static dispatch tables --- the primitives must be frozen to
3933 -- be referenced (otherwise we have problems with the backend). It is
3934 -- not a requirement with nonstatic dispatch tables because in this case
3935 -- we generate now an empty dispatch table; the extra code required to
3936 -- register the primitives in the slots will be generated later --- when
3937 -- each primitive is frozen (see Freeze_Subprogram).
3939 if Building_Static_DT (Typ)
3940 and then not Is_CPP_Class (Typ)
3943 Save : constant Boolean := Freezing_Library_Level_Tagged_Type;
3944 Prim_Elmt : Elmt_Id;
3948 Freezing_Library_Level_Tagged_Type := True;
3949 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3950 while Present (Prim_Elmt) loop
3951 Frnodes := Freeze_Entity (Node (Prim_Elmt), Loc);
3954 Subp : constant Entity_Id := Node (Prim_Elmt);
3958 F := First_Formal (Subp);
3959 while Present (F) loop
3960 Check_Premature_Freezing (Subp, Etype (F));
3964 Check_Premature_Freezing (Subp, Etype (Subp));
3967 if Present (Frnodes) then
3968 Append_List_To (Result, Frnodes);
3971 Next_Elmt (Prim_Elmt);
3973 Freezing_Library_Level_Tagged_Type := Save;
3977 -- Ada 2005 (AI-251): Build the secondary dispatch tables
3979 if Has_Interfaces (Typ) then
3980 Collect_Interface_Components (Typ, Typ_Comps);
3982 -- Each secondary dispatch table is assigned an unique positive
3983 -- suffix index; such value also corresponds with the location of
3984 -- its entity in the Dispatch_Table_Wrappers list (see Make_Tags).
3986 -- Note: This value must be kept sync with the Suffix_Index values
3987 -- generated by Make_Tags
3991 Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
3993 AI_Tag_Comp := First_Elmt (Typ_Comps);
3994 while Present (AI_Tag_Comp) loop
3996 -- Build the secondary table containing pointers to thunks
4000 Iface => Base_Type (Related_Type (Node (AI_Tag_Comp))),
4001 Suffix_Index => Suffix_Index,
4002 Num_Iface_Prims => UI_To_Int
4003 (DT_Entry_Count (Node (AI_Tag_Comp))),
4004 Iface_DT_Ptr => Node (AI_Tag_Elmt),
4005 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
4006 Build_Thunks => True,
4009 -- Skip secondary dispatch table and secondary dispatch table of
4010 -- predefined primitives
4012 Next_Elmt (AI_Tag_Elmt);
4013 Next_Elmt (AI_Tag_Elmt);
4015 -- Build the secondary table containing pointers to primitives
4016 -- (used to give support to Generic Dispatching Constructors).
4020 Iface => Base_Type (Related_Type (Node (AI_Tag_Comp))),
4022 Num_Iface_Prims => UI_To_Int
4023 (DT_Entry_Count (Node (AI_Tag_Comp))),
4024 Iface_DT_Ptr => Node (AI_Tag_Elmt),
4025 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
4026 Build_Thunks => False,
4029 -- Skip secondary dispatch table and secondary dispatch table of
4030 -- predefined primitives
4032 Next_Elmt (AI_Tag_Elmt);
4033 Next_Elmt (AI_Tag_Elmt);
4035 Suffix_Index := Suffix_Index + 1;
4036 Next_Elmt (AI_Tag_Comp);
4040 -- Get the _tag entity and the number of primitives of its dispatch
4043 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
4044 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
4046 Set_Is_Statically_Allocated (DT, Is_Library_Level_Tagged_Type (Typ));
4047 Set_Is_Statically_Allocated (SSD, Is_Library_Level_Tagged_Type (Typ));
4048 Set_Is_Statically_Allocated (TSD, Is_Library_Level_Tagged_Type (Typ));
4049 Set_Is_Statically_Allocated (Predef_Prims,
4050 Is_Library_Level_Tagged_Type (Typ));
4052 -- In case of locally defined tagged type we declare the object
4053 -- containing the dispatch table by means of a variable. Its
4054 -- initialization is done later by means of an assignment. This is
4055 -- required to generate its External_Tag.
4057 if not Building_Static_DT (Typ) then
4060 -- DT : No_Dispatch_Table_Wrapper;
4061 -- for DT'Alignment use Address'Alignment;
4062 -- DT_Ptr : Tag := !Tag (DT.NDT_Prims_Ptr'Address);
4064 if not Has_DT (Typ) then
4066 Make_Object_Declaration (Loc,
4067 Defining_Identifier => DT,
4068 Aliased_Present => True,
4069 Constant_Present => False,
4070 Object_Definition =>
4072 (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
4075 Make_Attribute_Definition_Clause (Loc,
4076 Name => New_Reference_To (DT, Loc),
4077 Chars => Name_Alignment,
4079 Make_Attribute_Reference (Loc,
4081 New_Reference_To (RTE (RE_Integer_Address), Loc),
4082 Attribute_Name => Name_Alignment)));
4085 Make_Object_Declaration (Loc,
4086 Defining_Identifier => DT_Ptr,
4087 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4088 Constant_Present => True,
4090 Unchecked_Convert_To (RTE (RE_Tag),
4091 Make_Attribute_Reference (Loc,
4093 Make_Selected_Component (Loc,
4094 Prefix => New_Reference_To (DT, Loc),
4097 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
4098 Attribute_Name => Name_Address))));
4101 -- DT : Dispatch_Table_Wrapper (Nb_Prim);
4102 -- for DT'Alignment use Address'Alignment;
4103 -- DT_Ptr : Tag := !Tag (DT.Prims_Ptr'Address);
4106 -- If the tagged type has no primitives we add a dummy slot
4107 -- whose address will be the tag of this type.
4111 New_List (Make_Integer_Literal (Loc, 1));
4114 New_List (Make_Integer_Literal (Loc, Nb_Prim));
4118 Make_Object_Declaration (Loc,
4119 Defining_Identifier => DT,
4120 Aliased_Present => True,
4121 Constant_Present => False,
4122 Object_Definition =>
4123 Make_Subtype_Indication (Loc,
4125 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
4126 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4127 Constraints => DT_Constr_List))));
4130 Make_Attribute_Definition_Clause (Loc,
4131 Name => New_Reference_To (DT, Loc),
4132 Chars => Name_Alignment,
4134 Make_Attribute_Reference (Loc,
4136 New_Reference_To (RTE (RE_Integer_Address), Loc),
4137 Attribute_Name => Name_Alignment)));
4140 Make_Object_Declaration (Loc,
4141 Defining_Identifier => DT_Ptr,
4142 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4143 Constant_Present => True,
4145 Unchecked_Convert_To (RTE (RE_Tag),
4146 Make_Attribute_Reference (Loc,
4148 Make_Selected_Component (Loc,
4149 Prefix => New_Reference_To (DT, Loc),
4152 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
4153 Attribute_Name => Name_Address))));
4156 Make_Object_Declaration (Loc,
4157 Defining_Identifier =>
4158 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Typ)))),
4159 Constant_Present => True,
4160 Object_Definition => New_Reference_To
4161 (RTE (RE_Address), Loc),
4163 Make_Attribute_Reference (Loc,
4165 Make_Selected_Component (Loc,
4166 Prefix => New_Reference_To (DT, Loc),
4169 (RTE_Record_Component (RE_Predef_Prims), Loc)),
4170 Attribute_Name => Name_Address)));
4174 -- Generate: Exname : constant String := full_qualified_name (typ);
4175 -- The type itself may be an anonymous parent type, so use the first
4176 -- subtype to have a user-recognizable name.
4179 Make_Object_Declaration (Loc,
4180 Defining_Identifier => Exname,
4181 Constant_Present => True,
4182 Object_Definition => New_Reference_To (Standard_String, Loc),
4184 Make_String_Literal (Loc,
4185 Full_Qualified_Name (First_Subtype (Typ)))));
4187 Set_Is_Statically_Allocated (Exname);
4188 Set_Is_True_Constant (Exname);
4190 -- Declare the object used by Ada.Tags.Register_Tag
4192 if RTE_Available (RE_Register_Tag) then
4194 Make_Object_Declaration (Loc,
4195 Defining_Identifier => HT_Link,
4196 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc)));
4199 -- Generate code to create the storage for the type specific data object
4200 -- with enough space to store the tags of the ancestors plus the tags
4201 -- of all the implemented interfaces (as described in a-tags.adb).
4203 -- TSD : Type_Specific_Data (I_Depth) :=
4204 -- (Idepth => I_Depth,
4205 -- Access_Level => Type_Access_Level (Typ),
4206 -- Expanded_Name => Cstring_Ptr!(Exname'Address))
4207 -- External_Tag => Cstring_Ptr!(Exname'Address))
4208 -- HT_Link => HT_Link'Address,
4209 -- Transportable => <<boolean-value>>,
4210 -- RC_Offset => <<integer-value>>,
4211 -- [ Size_Func => Size_Prim'Access ]
4212 -- [ Interfaces_Table => <<access-value>> ]
4213 -- [ SSD => SSD_Table'Address ]
4214 -- Tags_Table => (0 => null,
4217 -- for TSD'Alignment use Address'Alignment
4219 TSD_Aggr_List := New_List;
4221 -- Idepth: Count ancestors to compute the inheritance depth. For private
4222 -- extensions, always go to the full view in order to compute the real
4223 -- inheritance depth.
4226 Current_Typ : Entity_Id;
4227 Parent_Typ : Entity_Id;
4233 Parent_Typ := Etype (Current_Typ);
4235 if Is_Private_Type (Parent_Typ) then
4236 Parent_Typ := Full_View (Base_Type (Parent_Typ));
4239 exit when Parent_Typ = Current_Typ;
4241 I_Depth := I_Depth + 1;
4242 Current_Typ := Parent_Typ;
4246 Append_To (TSD_Aggr_List,
4247 Make_Integer_Literal (Loc, I_Depth));
4251 Append_To (TSD_Aggr_List,
4252 Make_Integer_Literal (Loc, Type_Access_Level (Typ)));
4256 Append_To (TSD_Aggr_List,
4257 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4258 Make_Attribute_Reference (Loc,
4259 Prefix => New_Reference_To (Exname, Loc),
4260 Attribute_Name => Name_Address)));
4262 -- External_Tag of a local tagged type
4264 -- <typ>A : constant String :=
4265 -- "Internal tag at 16#tag-addr#: <full-name-of-typ>";
4267 -- The reason we generate this strange name is that we do not want to
4268 -- enter local tagged types in the global hash table used to compute
4269 -- the Internal_Tag attribute for two reasons:
4271 -- 1. It is hard to avoid a tasking race condition for entering the
4272 -- entry into the hash table.
4274 -- 2. It would cause a storage leak, unless we rig up considerable
4275 -- mechanism to remove the entry from the hash table on exit.
4277 -- So what we do is to generate the above external tag name, where the
4278 -- hex address is the address of the local dispatch table (i.e. exactly
4279 -- the value we want if Internal_Tag is computed from this string).
4281 -- Of course this value will only be valid if the tagged type is still
4282 -- in scope, but it clearly must be erroneous to compute the internal
4283 -- tag of a tagged type that is out of scope!
4285 -- We don't do this processing if an explicit external tag has been
4286 -- specified. That's an odd case for which we have already issued a
4287 -- warning, where we will not be able to compute the internal tag.
4289 if not Is_Library_Level_Entity (Typ)
4290 and then not Has_External_Tag_Rep_Clause (Typ)
4293 Exname : constant Entity_Id :=
4294 Make_Defining_Identifier (Loc,
4295 New_External_Name (Tname, 'A'));
4297 Full_Name : constant String_Id :=
4298 Full_Qualified_Name (First_Subtype (Typ));
4299 Str1_Id : String_Id;
4300 Str2_Id : String_Id;
4304 -- Str1 = "Internal tag at 16#";
4307 Store_String_Chars ("Internal tag at 16#");
4308 Str1_Id := End_String;
4311 -- Str2 = "#: <type-full-name>";
4314 Store_String_Chars ("#: ");
4315 Store_String_Chars (Full_Name);
4316 Str2_Id := End_String;
4319 -- Exname : constant String :=
4320 -- Str1 & Address_Image (Tag) & Str2;
4322 if RTE_Available (RE_Address_Image) then
4324 Make_Object_Declaration (Loc,
4325 Defining_Identifier => Exname,
4326 Constant_Present => True,
4327 Object_Definition => New_Reference_To
4328 (Standard_String, Loc),
4330 Make_Op_Concat (Loc,
4332 Make_String_Literal (Loc, Str1_Id),
4334 Make_Op_Concat (Loc,
4336 Make_Function_Call (Loc,
4339 (RTE (RE_Address_Image), Loc),
4340 Parameter_Associations => New_List (
4341 Unchecked_Convert_To (RTE (RE_Address),
4342 New_Reference_To (DT_Ptr, Loc)))),
4344 Make_String_Literal (Loc, Str2_Id)))));
4348 Make_Object_Declaration (Loc,
4349 Defining_Identifier => Exname,
4350 Constant_Present => True,
4351 Object_Definition => New_Reference_To
4352 (Standard_String, Loc),
4354 Make_Op_Concat (Loc,
4356 Make_String_Literal (Loc, Str1_Id),
4358 Make_String_Literal (Loc, Str2_Id))));
4362 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4363 Make_Attribute_Reference (Loc,
4364 Prefix => New_Reference_To (Exname, Loc),
4365 Attribute_Name => Name_Address));
4368 -- External tag of a library-level tagged type: Check for a definition
4369 -- of External_Tag. The clause is considered only if it applies to this
4370 -- specific tagged type, as opposed to one of its ancestors.
4371 -- If the type is an unconstrained type extension, we are building the
4372 -- dispatch table of its anonymous base type, so the external tag, if
4373 -- any was specified, must be retrieved from the first subtype.
4377 Def : constant Node_Id := Get_Attribute_Definition_Clause
4378 (First_Subtype (Typ),
4379 Attribute_External_Tag);
4381 Old_Val : String_Id;
4382 New_Val : String_Id;
4386 if not Present (Def)
4387 or else Entity (Name (Def)) /= First_Subtype (Typ)
4390 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4391 Make_Attribute_Reference (Loc,
4392 Prefix => New_Reference_To (Exname, Loc),
4393 Attribute_Name => Name_Address));
4395 Old_Val := Strval (Expr_Value_S (Expression (Def)));
4397 -- For the rep clause "for <typ>'external_tag use y" generate:
4399 -- <typ>A : constant string := y;
4401 -- <typ>A'Address is used to set the External_Tag component
4404 -- Create a new nul terminated string if it is not already
4406 if String_Length (Old_Val) > 0
4408 Get_String_Char (Old_Val, String_Length (Old_Val)) = 0
4412 Start_String (Old_Val);
4413 Store_String_Char (Get_Char_Code (ASCII.NUL));
4414 New_Val := End_String;
4417 E := Make_Defining_Identifier (Loc,
4418 New_External_Name (Chars (Typ), 'A'));
4421 Make_Object_Declaration (Loc,
4422 Defining_Identifier => E,
4423 Constant_Present => True,
4424 Object_Definition =>
4425 New_Reference_To (Standard_String, Loc),
4427 Make_String_Literal (Loc, New_Val)));
4430 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4431 Make_Attribute_Reference (Loc,
4432 Prefix => New_Reference_To (E, Loc),
4433 Attribute_Name => Name_Address));
4438 Append_To (TSD_Aggr_List, New_Node);
4442 if RTE_Available (RE_Register_Tag) then
4443 Append_To (TSD_Aggr_List,
4444 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
4445 Make_Attribute_Reference (Loc,
4446 Prefix => New_Reference_To (HT_Link, Loc),
4447 Attribute_Name => Name_Address)));
4449 Append_To (TSD_Aggr_List,
4450 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
4451 New_Reference_To (RTE (RE_Null_Address), Loc)));
4454 -- Transportable: Set for types that can be used in remote calls
4455 -- with respect to E.4(18) legality rules.
4458 Transportable : Entity_Id;
4464 or else Is_Shared_Passive (Typ)
4466 ((Is_Remote_Types (Typ)
4467 or else Is_Remote_Call_Interface (Typ))
4468 and then Original_View_In_Visible_Part (Typ))
4469 or else not Comes_From_Source (Typ));
4471 Append_To (TSD_Aggr_List,
4472 New_Occurrence_Of (Transportable, Loc));
4475 -- RC_Offset: These are the valid values and their meaning:
4477 -- >0: For simple types with controlled components is
4478 -- type._record_controller'position
4480 -- 0: For types with no controlled components
4482 -- -1: For complex types with controlled components where the position
4483 -- of the record controller is not statically computable but there
4484 -- are controlled components at this level. The _Controller field
4485 -- is available right after the _parent.
4487 -- -2: There are no controlled components at this level. We need to
4488 -- get the position from the parent.
4491 RC_Offset_Node : Node_Id;
4494 if not Has_Controlled_Component (Typ) then
4495 RC_Offset_Node := Make_Integer_Literal (Loc, 0);
4497 elsif Etype (Typ) /= Typ
4498 and then Has_Discriminants (Parent_Typ)
4500 if Has_New_Controlled_Component (Typ) then
4501 RC_Offset_Node := Make_Integer_Literal (Loc, -1);
4503 RC_Offset_Node := Make_Integer_Literal (Loc, -2);
4507 Make_Attribute_Reference (Loc,
4509 Make_Selected_Component (Loc,
4510 Prefix => New_Reference_To (Typ, Loc),
4512 New_Reference_To (Controller_Component (Typ), Loc)),
4513 Attribute_Name => Name_Position);
4515 -- This is not proper Ada code to use the attribute 'Position
4516 -- on something else than an object but this is supported by
4517 -- the back end (see comment on the Bit_Component attribute in
4518 -- sem_attr). So we avoid semantic checking here.
4520 -- Is this documented in sinfo.ads??? it should be!
4522 Set_Analyzed (RC_Offset_Node);
4523 Set_Etype (Prefix (RC_Offset_Node), RTE (RE_Record_Controller));
4524 Set_Etype (Prefix (Prefix (RC_Offset_Node)), Typ);
4525 Set_Etype (Selector_Name (Prefix (RC_Offset_Node)),
4526 RTE (RE_Record_Controller));
4527 Set_Etype (RC_Offset_Node, RTE (RE_Storage_Offset));
4530 Append_To (TSD_Aggr_List, RC_Offset_Node);
4535 if RTE_Record_Component_Available (RE_Size_Func) then
4536 if not Building_Static_DT (Typ)
4537 or else Is_Interface (Typ)
4539 Append_To (TSD_Aggr_List,
4540 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4541 New_Reference_To (RTE (RE_Null_Address), Loc)));
4545 Prim_Elmt : Elmt_Id;
4549 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4550 while Present (Prim_Elmt) loop
4551 Prim := Node (Prim_Elmt);
4553 if Chars (Prim) = Name_uSize then
4554 while Present (Alias (Prim)) loop
4555 Prim := Alias (Prim);
4558 if Is_Abstract_Subprogram (Prim) then
4559 Append_To (TSD_Aggr_List,
4560 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4561 New_Reference_To (RTE (RE_Null_Address), Loc)));
4563 Append_To (TSD_Aggr_List,
4564 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4565 Make_Attribute_Reference (Loc,
4566 Prefix => New_Reference_To (Prim, Loc),
4567 Attribute_Name => Name_Unrestricted_Access)));
4573 Next_Elmt (Prim_Elmt);
4579 -- Interfaces_Table (required for AI-405)
4581 if RTE_Record_Component_Available (RE_Interfaces_Table) then
4583 -- Count the number of interface types implemented by Typ
4585 Collect_Interfaces (Typ, Typ_Ifaces);
4587 AI := First_Elmt (Typ_Ifaces);
4588 while Present (AI) loop
4589 Num_Ifaces := Num_Ifaces + 1;
4593 if Num_Ifaces = 0 then
4594 Iface_Table_Node := Make_Null (Loc);
4596 -- Generate the Interface_Table object
4600 TSD_Ifaces_List : constant List_Id := New_List;
4602 Sec_DT_Tag : Node_Id;
4605 AI := First_Elmt (Typ_Ifaces);
4606 while Present (AI) loop
4607 if Is_Ancestor (Node (AI), Typ) then
4609 New_Reference_To (DT_Ptr, Loc);
4613 (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
4614 pragma Assert (Has_Thunks (Node (Elmt)));
4616 while Ekind (Node (Elmt)) = E_Constant
4618 Is_Ancestor (Node (AI), Related_Type (Node (Elmt)))
4620 pragma Assert (Has_Thunks (Node (Elmt)));
4622 pragma Assert (Has_Thunks (Node (Elmt)));
4624 pragma Assert (not Has_Thunks (Node (Elmt)));
4626 pragma Assert (not Has_Thunks (Node (Elmt)));
4630 pragma Assert (Ekind (Node (Elmt)) = E_Constant
4632 Has_Thunks (Node (Next_Elmt (Next_Elmt (Elmt)))));
4634 New_Reference_To (Node (Next_Elmt (Next_Elmt (Elmt))),
4638 Append_To (TSD_Ifaces_List,
4639 Make_Aggregate (Loc,
4640 Expressions => New_List (
4644 Unchecked_Convert_To (RTE (RE_Tag),
4646 (Node (First_Elmt (Access_Disp_Table (Node (AI)))),
4649 -- Static_Offset_To_Top
4651 New_Reference_To (Standard_True, Loc),
4653 -- Offset_To_Top_Value
4655 Make_Integer_Literal (Loc, 0),
4657 -- Offset_To_Top_Func
4663 Unchecked_Convert_To (RTE (RE_Tag), Sec_DT_Tag)
4670 Name_ITable := New_External_Name (Tname, 'I');
4671 ITable := Make_Defining_Identifier (Loc, Name_ITable);
4672 Set_Is_Statically_Allocated (ITable,
4673 Is_Library_Level_Tagged_Type (Typ));
4675 -- The table of interfaces is not constant; its slots are
4676 -- filled at run-time by the IP routine using attribute
4677 -- 'Position to know the location of the tag components
4678 -- (and this attribute cannot be safely used before the
4679 -- object is initialized).
4682 Make_Object_Declaration (Loc,
4683 Defining_Identifier => ITable,
4684 Aliased_Present => True,
4685 Constant_Present => False,
4686 Object_Definition =>
4687 Make_Subtype_Indication (Loc,
4689 New_Reference_To (RTE (RE_Interface_Data), Loc),
4690 Constraint => Make_Index_Or_Discriminant_Constraint
4692 Constraints => New_List (
4693 Make_Integer_Literal (Loc, Num_Ifaces)))),
4695 Expression => Make_Aggregate (Loc,
4696 Expressions => New_List (
4697 Make_Integer_Literal (Loc, Num_Ifaces),
4698 Make_Aggregate (Loc,
4699 Expressions => TSD_Ifaces_List)))));
4702 Make_Attribute_Definition_Clause (Loc,
4703 Name => New_Reference_To (ITable, Loc),
4704 Chars => Name_Alignment,
4706 Make_Attribute_Reference (Loc,
4708 New_Reference_To (RTE (RE_Integer_Address), Loc),
4709 Attribute_Name => Name_Alignment)));
4712 Make_Attribute_Reference (Loc,
4713 Prefix => New_Reference_To (ITable, Loc),
4714 Attribute_Name => Name_Unchecked_Access);
4718 Append_To (TSD_Aggr_List, Iface_Table_Node);
4721 -- Generate the Select Specific Data table for synchronized types that
4722 -- implement synchronized interfaces. The size of the table is
4723 -- constrained by the number of non-predefined primitive operations.
4725 if RTE_Record_Component_Available (RE_SSD) then
4726 if Ada_Version >= Ada_05
4727 and then Has_DT (Typ)
4728 and then Is_Concurrent_Record_Type (Typ)
4729 and then Has_Interfaces (Typ)
4730 and then Nb_Prim > 0
4731 and then not Is_Abstract_Type (Typ)
4732 and then not Is_Controlled (Typ)
4733 and then not Restriction_Active (No_Dispatching_Calls)
4736 Make_Object_Declaration (Loc,
4737 Defining_Identifier => SSD,
4738 Aliased_Present => True,
4739 Object_Definition =>
4740 Make_Subtype_Indication (Loc,
4741 Subtype_Mark => New_Reference_To (
4742 RTE (RE_Select_Specific_Data), Loc),
4744 Make_Index_Or_Discriminant_Constraint (Loc,
4745 Constraints => New_List (
4746 Make_Integer_Literal (Loc, Nb_Prim))))));
4749 Make_Attribute_Definition_Clause (Loc,
4750 Name => New_Reference_To (SSD, Loc),
4751 Chars => Name_Alignment,
4753 Make_Attribute_Reference (Loc,
4755 New_Reference_To (RTE (RE_Integer_Address), Loc),
4756 Attribute_Name => Name_Alignment)));
4758 -- This table is initialized by Make_Select_Specific_Data_Table,
4759 -- which calls Set_Entry_Index and Set_Prim_Op_Kind.
4761 Append_To (TSD_Aggr_List,
4762 Make_Attribute_Reference (Loc,
4763 Prefix => New_Reference_To (SSD, Loc),
4764 Attribute_Name => Name_Unchecked_Access));
4766 Append_To (TSD_Aggr_List, Make_Null (Loc));
4770 -- Initialize the table of ancestor tags. In case of interface types
4771 -- this table is not needed.
4773 TSD_Tags_List := New_List;
4775 -- If we are not statically allocating the dispatch table then we must
4776 -- fill position 0 with null because we still have not generated the
4779 if not Building_Static_DT (Typ)
4780 or else Is_Interface (Typ)
4782 Append_To (TSD_Tags_List,
4783 Unchecked_Convert_To (RTE (RE_Tag),
4784 New_Reference_To (RTE (RE_Null_Address), Loc)));
4786 -- Otherwise we can safely reference the tag
4789 Append_To (TSD_Tags_List,
4790 New_Reference_To (DT_Ptr, Loc));
4793 -- Fill the rest of the table with the tags of the ancestors
4796 Current_Typ : Entity_Id;
4797 Parent_Typ : Entity_Id;
4805 Parent_Typ := Etype (Current_Typ);
4807 if Is_Private_Type (Parent_Typ) then
4808 Parent_Typ := Full_View (Base_Type (Parent_Typ));
4811 exit when Parent_Typ = Current_Typ;
4813 if Is_CPP_Class (Parent_Typ)
4814 or else Is_Interface (Typ)
4816 -- The tags defined in the C++ side will be inherited when
4817 -- the object is constructed (Exp_Ch3.Build_Init_Procedure)
4819 Append_To (TSD_Tags_List,
4820 Unchecked_Convert_To (RTE (RE_Tag),
4821 New_Reference_To (RTE (RE_Null_Address), Loc)));
4823 Append_To (TSD_Tags_List,
4825 (Node (First_Elmt (Access_Disp_Table (Parent_Typ))),
4830 Current_Typ := Parent_Typ;
4833 pragma Assert (Pos = I_Depth + 1);
4836 Append_To (TSD_Aggr_List,
4837 Make_Aggregate (Loc,
4838 Expressions => TSD_Tags_List));
4840 -- Build the TSD object
4843 Make_Object_Declaration (Loc,
4844 Defining_Identifier => TSD,
4845 Aliased_Present => True,
4846 Constant_Present => Building_Static_DT (Typ),
4847 Object_Definition =>
4848 Make_Subtype_Indication (Loc,
4849 Subtype_Mark => New_Reference_To (
4850 RTE (RE_Type_Specific_Data), Loc),
4852 Make_Index_Or_Discriminant_Constraint (Loc,
4853 Constraints => New_List (
4854 Make_Integer_Literal (Loc, I_Depth)))),
4856 Expression => Make_Aggregate (Loc,
4857 Expressions => TSD_Aggr_List)));
4859 Set_Is_True_Constant (TSD, Building_Static_DT (Typ));
4862 Make_Attribute_Definition_Clause (Loc,
4863 Name => New_Reference_To (TSD, Loc),
4864 Chars => Name_Alignment,
4866 Make_Attribute_Reference (Loc,
4867 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
4868 Attribute_Name => Name_Alignment)));
4870 -- Initialize or declare the dispatch table object
4872 if not Has_DT (Typ) then
4873 DT_Constr_List := New_List;
4874 DT_Aggr_List := New_List;
4879 Make_Attribute_Reference (Loc,
4880 Prefix => New_Reference_To (TSD, Loc),
4881 Attribute_Name => Name_Address);
4883 Append_To (DT_Constr_List, New_Node);
4884 Append_To (DT_Aggr_List, New_Copy (New_Node));
4885 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
4887 -- In case of locally defined tagged types we have already declared
4888 -- and uninitialized object for the dispatch table, which is now
4889 -- initialized by means of the following assignment:
4891 -- DT := (TSD'Address, 0);
4893 if not Building_Static_DT (Typ) then
4895 Make_Assignment_Statement (Loc,
4896 Name => New_Reference_To (DT, Loc),
4897 Expression => Make_Aggregate (Loc,
4898 Expressions => DT_Aggr_List)));
4900 -- In case of library level tagged types we declare and export now
4901 -- the constant object containing the dummy dispatch table. There
4902 -- is no need to declare the tag here because it has been previously
4903 -- declared by Make_Tags
4905 -- DT : aliased constant No_Dispatch_Table :=
4906 -- (NDT_TSD => TSD'Address;
4907 -- NDT_Prims_Ptr => 0);
4908 -- for DT'Alignment use Address'Alignment;
4912 Make_Object_Declaration (Loc,
4913 Defining_Identifier => DT,
4914 Aliased_Present => True,
4915 Constant_Present => True,
4916 Object_Definition =>
4917 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc),
4918 Expression => Make_Aggregate (Loc,
4919 Expressions => DT_Aggr_List)));
4922 Make_Attribute_Definition_Clause (Loc,
4923 Name => New_Reference_To (DT, Loc),
4924 Chars => Name_Alignment,
4926 Make_Attribute_Reference (Loc,
4928 New_Reference_To (RTE (RE_Integer_Address), Loc),
4929 Attribute_Name => Name_Alignment)));
4931 Export_DT (Typ, DT);
4934 -- Common case: Typ has a dispatch table
4938 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
4939 -- (predef-prim-op-1'address,
4940 -- predef-prim-op-2'address,
4942 -- predef-prim-op-n'address);
4943 -- for Predef_Prims'Alignment use Address'Alignment
4945 -- DT : Dispatch_Table (Nb_Prims) :=
4946 -- (Signature => <sig-value>,
4947 -- Tag_Kind => <tag_kind-value>,
4948 -- Predef_Prims => Predef_Prims'First'Address,
4949 -- Offset_To_Top => 0,
4950 -- TSD => TSD'Address;
4951 -- Prims_Ptr => (prim-op-1'address,
4952 -- prim-op-2'address,
4954 -- prim-op-n'address));
4955 -- for DT'Alignment use Address'Alignment
4962 if not Building_Static_DT (Typ) then
4963 Nb_Predef_Prims := Max_Predef_Prims;
4966 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4967 while Present (Prim_Elmt) loop
4968 Prim := Node (Prim_Elmt);
4970 if Is_Predefined_Dispatching_Operation (Prim)
4971 and then not Is_Abstract_Subprogram (Prim)
4973 Pos := UI_To_Int (DT_Position (Prim));
4975 if Pos > Nb_Predef_Prims then
4976 Nb_Predef_Prims := Pos;
4980 Next_Elmt (Prim_Elmt);
4986 (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
4991 Prim_Ops_Aggr_List := New_List;
4993 Prim_Table := (others => Empty);
4995 if Building_Static_DT (Typ) then
4996 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4997 while Present (Prim_Elmt) loop
4998 Prim := Node (Prim_Elmt);
5000 if Is_Predefined_Dispatching_Operation (Prim)
5001 and then not Is_Abstract_Subprogram (Prim)
5002 and then not Present (Prim_Table
5003 (UI_To_Int (DT_Position (Prim))))
5006 while Present (Alias (E)) loop
5010 pragma Assert (not Is_Abstract_Subprogram (E));
5011 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
5014 Next_Elmt (Prim_Elmt);
5018 for J in Prim_Table'Range loop
5019 if Present (Prim_Table (J)) then
5021 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
5022 Make_Attribute_Reference (Loc,
5023 Prefix => New_Reference_To (Prim_Table (J), Loc),
5024 Attribute_Name => Name_Unrestricted_Access));
5026 New_Node := Make_Null (Loc);
5029 Append_To (Prim_Ops_Aggr_List, New_Node);
5033 Make_Aggregate (Loc,
5034 Expressions => Prim_Ops_Aggr_List);
5037 Make_Subtype_Declaration (Loc,
5038 Defining_Identifier =>
5039 Make_Defining_Identifier (Loc,
5040 New_Internal_Name ('S')),
5041 Subtype_Indication =>
5042 New_Reference_To (RTE (RE_Address_Array), Loc));
5044 Append_To (Result, Decl);
5047 Make_Object_Declaration (Loc,
5048 Defining_Identifier => Predef_Prims,
5049 Aliased_Present => True,
5050 Constant_Present => Building_Static_DT (Typ),
5051 Object_Definition => New_Reference_To
5052 (Defining_Identifier (Decl), Loc),
5053 Expression => New_Node));
5055 -- Remember aggregates initializing dispatch tables
5057 Append_Elmt (New_Node, DT_Aggr);
5060 Make_Attribute_Definition_Clause (Loc,
5061 Name => New_Reference_To (Predef_Prims, Loc),
5062 Chars => Name_Alignment,
5064 Make_Attribute_Reference (Loc,
5066 New_Reference_To (RTE (RE_Integer_Address), Loc),
5067 Attribute_Name => Name_Alignment)));
5071 -- Stage 1: Initialize the discriminant and the record components
5073 DT_Constr_List := New_List;
5074 DT_Aggr_List := New_List;
5076 -- Num_Prims. If the tagged type has no primitives we add a dummy
5077 -- slot whose address will be the tag of this type.
5080 New_Node := Make_Integer_Literal (Loc, 1);
5082 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
5085 Append_To (DT_Constr_List, New_Node);
5086 Append_To (DT_Aggr_List, New_Copy (New_Node));
5090 if RTE_Record_Component_Available (RE_Signature) then
5091 Append_To (DT_Aggr_List,
5092 New_Reference_To (RTE (RE_Primary_DT), Loc));
5097 if RTE_Record_Component_Available (RE_Tag_Kind) then
5098 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
5103 Append_To (DT_Aggr_List,
5104 Make_Attribute_Reference (Loc,
5105 Prefix => New_Reference_To (Predef_Prims, Loc),
5106 Attribute_Name => Name_Address));
5110 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
5114 Append_To (DT_Aggr_List,
5115 Make_Attribute_Reference (Loc,
5116 Prefix => New_Reference_To (TSD, Loc),
5117 Attribute_Name => Name_Address));
5119 -- Stage 2: Initialize the table of primitive operations
5121 Prim_Ops_Aggr_List := New_List;
5124 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
5126 elsif not Building_Static_DT (Typ) then
5127 for J in 1 .. Nb_Prim loop
5128 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
5133 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
5136 Prim_Elmt : Elmt_Id;
5139 Prim_Table := (others => Empty);
5141 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5142 while Present (Prim_Elmt) loop
5143 Prim := Node (Prim_Elmt);
5145 if Is_Imported (Prim)
5146 or else Present (Interface_Alias (Prim))
5147 or else Is_Predefined_Dispatching_Operation (Prim)
5152 -- Traverse the list of aliased entities to handle
5153 -- renamings of predefined primitives.
5156 while Present (Alias (E)) loop
5160 if not Is_Predefined_Dispatching_Operation (E)
5161 and then not Is_Abstract_Subprogram (E)
5162 and then not Present (Interface_Alias (E))
5165 (UI_To_Int (DT_Position (Prim)) <= Nb_Prim);
5167 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
5171 Next_Elmt (Prim_Elmt);
5174 for J in Prim_Table'Range loop
5175 if Present (Prim_Table (J)) then
5177 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
5178 Make_Attribute_Reference (Loc,
5179 Prefix => New_Reference_To (Prim_Table (J), Loc),
5180 Attribute_Name => Name_Unrestricted_Access));
5182 New_Node := Make_Null (Loc);
5185 Append_To (Prim_Ops_Aggr_List, New_Node);
5191 Make_Aggregate (Loc,
5192 Expressions => Prim_Ops_Aggr_List);
5194 Append_To (DT_Aggr_List, New_Node);
5196 -- Remember aggregates initializing dispatch tables
5198 Append_Elmt (New_Node, DT_Aggr);
5200 -- In case of locally defined tagged types we have already declared
5201 -- and uninitialized object for the dispatch table, which is now
5202 -- initialized by means of an assignment.
5204 if not Building_Static_DT (Typ) then
5206 Make_Assignment_Statement (Loc,
5207 Name => New_Reference_To (DT, Loc),
5208 Expression => Make_Aggregate (Loc,
5209 Expressions => DT_Aggr_List)));
5211 -- In case of library level tagged types we declare now and export
5212 -- the constant object containing the dispatch table.
5216 Make_Object_Declaration (Loc,
5217 Defining_Identifier => DT,
5218 Aliased_Present => True,
5219 Constant_Present => True,
5220 Object_Definition =>
5221 Make_Subtype_Indication (Loc,
5222 Subtype_Mark => New_Reference_To
5223 (RTE (RE_Dispatch_Table_Wrapper), Loc),
5224 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
5225 Constraints => DT_Constr_List)),
5226 Expression => Make_Aggregate (Loc,
5227 Expressions => DT_Aggr_List)));
5230 Make_Attribute_Definition_Clause (Loc,
5231 Name => New_Reference_To (DT, Loc),
5232 Chars => Name_Alignment,
5234 Make_Attribute_Reference (Loc,
5236 New_Reference_To (RTE (RE_Integer_Address), Loc),
5237 Attribute_Name => Name_Alignment)));
5239 Export_DT (Typ, DT);
5243 -- Initialize the table of ancestor tags if not building static
5246 if not Building_Static_DT (Typ)
5247 and then not Is_Interface (Typ)
5248 and then not Is_CPP_Class (Typ)
5251 Make_Assignment_Statement (Loc,
5253 Make_Indexed_Component (Loc,
5255 Make_Selected_Component (Loc,
5257 New_Reference_To (TSD, Loc),
5260 (RTE_Record_Component (RE_Tags_Table), Loc)),
5262 New_List (Make_Integer_Literal (Loc, 0))),
5266 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)));
5269 -- Inherit the dispatch tables of the parent. There is no need to
5270 -- inherit anything from the parent when building static dispatch tables
5271 -- because the whole dispatch table (including inherited primitives) has
5272 -- been already built.
5274 if Building_Static_DT (Typ) then
5277 -- If the ancestor is a CPP_Class type we inherit the dispatch tables
5278 -- in the init proc, and we don't need to fill them in here.
5280 elsif Is_CPP_Class (Parent_Typ) then
5283 -- Otherwise we fill in the dispatch tables here
5286 if Typ /= Parent_Typ
5287 and then not Is_Interface (Typ)
5288 and then not Restriction_Active (No_Dispatching_Calls)
5290 -- Inherit the dispatch table
5292 if not Is_Interface (Typ)
5293 and then not Is_Interface (Parent_Typ)
5294 and then not Is_CPP_Class (Parent_Typ)
5297 Nb_Prims : constant Int :=
5298 UI_To_Int (DT_Entry_Count
5299 (First_Tag_Component (Parent_Typ)));
5302 Append_To (Elab_Code,
5303 Build_Inherit_Predefined_Prims (Loc,
5309 (Access_Disp_Table (Parent_Typ)))), Loc),
5315 (Access_Disp_Table (Typ)))), Loc)));
5317 if Nb_Prims /= 0 then
5318 Append_To (Elab_Code,
5319 Build_Inherit_Prims (Loc,
5325 (Access_Disp_Table (Parent_Typ))), Loc),
5326 New_Tag_Node => New_Reference_To (DT_Ptr, Loc),
5327 Num_Prims => Nb_Prims));
5332 -- Inherit the secondary dispatch tables of the ancestor
5334 if not Is_CPP_Class (Parent_Typ) then
5336 Sec_DT_Ancestor : Elmt_Id :=
5340 (Access_Disp_Table (Parent_Typ))));
5341 Sec_DT_Typ : Elmt_Id :=
5345 (Access_Disp_Table (Typ))));
5347 procedure Copy_Secondary_DTs (Typ : Entity_Id);
5348 -- Local procedure required to climb through the ancestors
5349 -- and copy the contents of all their secondary dispatch
5352 ------------------------
5353 -- Copy_Secondary_DTs --
5354 ------------------------
5356 procedure Copy_Secondary_DTs (Typ : Entity_Id) is
5361 -- Climb to the ancestor (if any) handling private types
5363 if Present (Full_View (Etype (Typ))) then
5364 if Full_View (Etype (Typ)) /= Typ then
5365 Copy_Secondary_DTs (Full_View (Etype (Typ)));
5368 elsif Etype (Typ) /= Typ then
5369 Copy_Secondary_DTs (Etype (Typ));
5372 if Present (Interfaces (Typ))
5373 and then not Is_Empty_Elmt_List (Interfaces (Typ))
5375 Iface := First_Elmt (Interfaces (Typ));
5376 E := First_Entity (Typ);
5378 and then Present (Node (Sec_DT_Ancestor))
5379 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
5381 if Is_Tag (E) and then Chars (E) /= Name_uTag then
5383 Num_Prims : constant Int :=
5384 UI_To_Int (DT_Entry_Count (E));
5387 if not Is_Interface (Etype (Typ)) then
5389 -- Inherit first secondary dispatch table
5391 Append_To (Elab_Code,
5392 Build_Inherit_Predefined_Prims (Loc,
5394 Unchecked_Convert_To (RTE (RE_Tag),
5397 (Next_Elmt (Sec_DT_Ancestor)),
5400 Unchecked_Convert_To (RTE (RE_Tag),
5402 (Node (Next_Elmt (Sec_DT_Typ)),
5405 if Num_Prims /= 0 then
5406 Append_To (Elab_Code,
5407 Build_Inherit_Prims (Loc,
5408 Typ => Node (Iface),
5410 Unchecked_Convert_To
5413 (Node (Sec_DT_Ancestor),
5416 Unchecked_Convert_To
5419 (Node (Sec_DT_Typ), Loc)),
5420 Num_Prims => Num_Prims));
5424 Next_Elmt (Sec_DT_Ancestor);
5425 Next_Elmt (Sec_DT_Typ);
5427 -- Skip the secondary dispatch table of
5428 -- predefined primitives
5430 Next_Elmt (Sec_DT_Ancestor);
5431 Next_Elmt (Sec_DT_Typ);
5433 if not Is_Interface (Etype (Typ)) then
5435 -- Inherit second secondary dispatch table
5437 Append_To (Elab_Code,
5438 Build_Inherit_Predefined_Prims (Loc,
5440 Unchecked_Convert_To (RTE (RE_Tag),
5443 (Next_Elmt (Sec_DT_Ancestor)),
5446 Unchecked_Convert_To (RTE (RE_Tag),
5448 (Node (Next_Elmt (Sec_DT_Typ)),
5451 if Num_Prims /= 0 then
5452 Append_To (Elab_Code,
5453 Build_Inherit_Prims (Loc,
5454 Typ => Node (Iface),
5456 Unchecked_Convert_To
5459 (Node (Sec_DT_Ancestor),
5462 Unchecked_Convert_To
5465 (Node (Sec_DT_Typ), Loc)),
5466 Num_Prims => Num_Prims));
5471 Next_Elmt (Sec_DT_Ancestor);
5472 Next_Elmt (Sec_DT_Typ);
5474 -- Skip the secondary dispatch table of
5475 -- predefined primitives
5477 Next_Elmt (Sec_DT_Ancestor);
5478 Next_Elmt (Sec_DT_Typ);
5486 end Copy_Secondary_DTs;
5489 if Present (Node (Sec_DT_Ancestor))
5490 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
5492 -- Handle private types
5494 if Present (Full_View (Typ)) then
5495 Copy_Secondary_DTs (Full_View (Typ));
5497 Copy_Secondary_DTs (Typ);
5505 -- Generate code to register the Tag in the External_Tag hash table for
5506 -- the pure Ada type only.
5508 -- Register_Tag (Dt_Ptr);
5510 -- Skip this action in the following cases:
5511 -- 1) if Register_Tag is not available.
5512 -- 2) in No_Run_Time mode.
5513 -- 3) if Typ is not defined at the library level (this is required
5514 -- to avoid adding concurrency control to the hash table used
5515 -- by the run-time to register the tags).
5517 if not No_Run_Time_Mode
5518 and then Is_Library_Level_Entity (Typ)
5519 and then RTE_Available (RE_Register_Tag)
5521 Append_To (Elab_Code,
5522 Make_Procedure_Call_Statement (Loc,
5523 Name => New_Reference_To (RTE (RE_Register_Tag), Loc),
5524 Parameter_Associations =>
5525 New_List (New_Reference_To (DT_Ptr, Loc))));
5528 if not Is_Empty_List (Elab_Code) then
5529 Append_List_To (Result, Elab_Code);
5532 -- Populate the two auxiliary tables used for dispatching
5533 -- asynchronous, conditional and timed selects for synchronized
5534 -- types that implement a limited interface.
5536 if Ada_Version >= Ada_05
5537 and then Is_Concurrent_Record_Type (Typ)
5538 and then Has_Interfaces (Typ)
5540 Append_List_To (Result,
5541 Make_Select_Specific_Data_Table (Typ));
5544 -- Remember entities containing dispatch tables
5546 Append_Elmt (Predef_Prims, DT_Decl);
5547 Append_Elmt (DT, DT_Decl);
5549 Analyze_List (Result, Suppress => All_Checks);
5550 Set_Has_Dispatch_Table (Typ);
5552 -- Mark entities containing dispatch tables. Required by the backend to
5553 -- handle them properly.
5555 if not Is_Interface (Typ) then
5560 -- Ensure that entities Prim_Ptr and Predef_Prims_Table_Ptr have
5561 -- the decoration required by the backend
5563 Set_Is_Dispatch_Table_Entity (RTE (RE_Prim_Ptr));
5564 Set_Is_Dispatch_Table_Entity (RTE (RE_Predef_Prims_Table_Ptr));
5566 -- Object declarations
5568 Elmt := First_Elmt (DT_Decl);
5569 while Present (Elmt) loop
5570 Set_Is_Dispatch_Table_Entity (Node (Elmt));
5571 pragma Assert (Ekind (Etype (Node (Elmt))) = E_Array_Subtype
5572 or else Ekind (Etype (Node (Elmt))) = E_Record_Subtype);
5573 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
5577 -- Aggregates initializing dispatch tables
5579 Elmt := First_Elmt (DT_Aggr);
5580 while Present (Elmt) loop
5581 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
5590 -------------------------------------
5591 -- Make_Select_Specific_Data_Table --
5592 -------------------------------------
5594 function Make_Select_Specific_Data_Table
5595 (Typ : Entity_Id) return List_Id
5597 Assignments : constant List_Id := New_List;
5598 Loc : constant Source_Ptr := Sloc (Typ);
5600 Conc_Typ : Entity_Id;
5604 Prim_Als : Entity_Id;
5605 Prim_Elmt : Elmt_Id;
5609 type Examined_Array is array (Int range <>) of Boolean;
5611 function Find_Entry_Index (E : Entity_Id) return Uint;
5612 -- Given an entry, find its index in the visible declarations of the
5613 -- corresponding concurrent type of Typ.
5615 ----------------------
5616 -- Find_Entry_Index --
5617 ----------------------
5619 function Find_Entry_Index (E : Entity_Id) return Uint is
5620 Index : Uint := Uint_1;
5621 Subp_Decl : Entity_Id;
5625 and then not Is_Empty_List (Decls)
5627 Subp_Decl := First (Decls);
5628 while Present (Subp_Decl) loop
5629 if Nkind (Subp_Decl) = N_Entry_Declaration then
5630 if Defining_Identifier (Subp_Decl) = E then
5642 end Find_Entry_Index;
5644 -- Start of processing for Make_Select_Specific_Data_Table
5647 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
5649 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
5651 if Present (Corresponding_Concurrent_Type (Typ)) then
5652 Conc_Typ := Corresponding_Concurrent_Type (Typ);
5654 if Present (Full_View (Conc_Typ)) then
5655 Conc_Typ := Full_View (Conc_Typ);
5658 if Ekind (Conc_Typ) = E_Protected_Type then
5659 Decls := Visible_Declarations (Protected_Definition (
5660 Parent (Conc_Typ)));
5662 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
5663 Decls := Visible_Declarations (Task_Definition (
5664 Parent (Conc_Typ)));
5668 -- Count the non-predefined primitive operations
5670 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5671 while Present (Prim_Elmt) loop
5672 Prim := Node (Prim_Elmt);
5674 if not (Is_Predefined_Dispatching_Operation (Prim)
5675 or else Is_Predefined_Dispatching_Alias (Prim))
5677 Nb_Prim := Nb_Prim + 1;
5680 Next_Elmt (Prim_Elmt);
5684 Examined : Examined_Array (1 .. Nb_Prim) := (others => False);
5687 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5688 while Present (Prim_Elmt) loop
5689 Prim := Node (Prim_Elmt);
5691 -- Look for primitive overriding an abstract interface subprogram
5693 if Present (Interface_Alias (Prim))
5694 and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
5696 Prim_Pos := DT_Position (Alias (Prim));
5697 pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
5698 Examined (UI_To_Int (Prim_Pos)) := True;
5700 -- Set the primitive operation kind regardless of subprogram
5702 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
5704 Append_To (Assignments,
5705 Make_Procedure_Call_Statement (Loc,
5706 Name => New_Reference_To (RTE (RE_Set_Prim_Op_Kind), Loc),
5707 Parameter_Associations => New_List (
5708 New_Reference_To (DT_Ptr, Loc),
5709 Make_Integer_Literal (Loc, Prim_Pos),
5710 Prim_Op_Kind (Alias (Prim), Typ))));
5712 -- Retrieve the root of the alias chain
5715 while Present (Alias (Prim_Als)) loop
5716 Prim_Als := Alias (Prim_Als);
5719 -- In the case of an entry wrapper, set the entry index
5721 if Ekind (Prim) = E_Procedure
5722 and then Is_Primitive_Wrapper (Prim_Als)
5723 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
5726 -- Ada.Tags.Set_Entry_Index
5727 -- (DT_Ptr, <position>, <index>);
5729 Append_To (Assignments,
5730 Make_Procedure_Call_Statement (Loc,
5732 New_Reference_To (RTE (RE_Set_Entry_Index), Loc),
5733 Parameter_Associations => New_List (
5734 New_Reference_To (DT_Ptr, Loc),
5735 Make_Integer_Literal (Loc, Prim_Pos),
5736 Make_Integer_Literal (Loc,
5737 Find_Entry_Index (Wrapped_Entity (Prim_Als))))));
5741 Next_Elmt (Prim_Elmt);
5746 end Make_Select_Specific_Data_Table;
5752 function Make_Tags (Typ : Entity_Id) return List_Id is
5753 Loc : constant Source_Ptr := Sloc (Typ);
5754 Result : constant List_Id := New_List;
5757 (Tag_Typ : Entity_Id;
5759 Is_Secondary_DT : Boolean);
5760 -- Import the dispatch table DT of tagged type Tag_Typ. Required to
5761 -- generate forward references and statically allocate the table. For
5762 -- primary dispatch tables that require no dispatch table generate:
5763 -- DT : static aliased constant Non_Dispatch_Table_Wrapper;
5764 -- $pragma import (ada, DT);
5765 -- Otherwise generate:
5766 -- DT : static aliased constant Dispatch_Table_Wrapper (Nb_Prim);
5767 -- $pragma import (ada, DT);
5774 (Tag_Typ : Entity_Id;
5776 Is_Secondary_DT : Boolean)
5778 DT_Constr_List : List_Id;
5782 Set_Is_Imported (DT);
5783 Set_Ekind (DT, E_Constant);
5784 Set_Related_Type (DT, Typ);
5786 -- The scope must be set now to call Get_External_Name
5788 Set_Scope (DT, Current_Scope);
5790 Get_External_Name (DT, True);
5791 Set_Interface_Name (DT,
5792 Make_String_Literal (Loc,
5793 Strval => String_From_Name_Buffer));
5795 -- Ensure proper Sprint output of this implicit importation
5797 Set_Is_Internal (DT);
5799 -- Save this entity to allow Make_DT to generate its exportation
5801 Append_Elmt (DT, Dispatch_Table_Wrappers (Typ));
5803 -- No dispatch table required
5805 if not Is_Secondary_DT
5806 and then not Has_DT (Tag_Typ)
5809 Make_Object_Declaration (Loc,
5810 Defining_Identifier => DT,
5811 Aliased_Present => True,
5812 Constant_Present => True,
5813 Object_Definition =>
5814 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
5817 -- Calculate the number of primitives of the dispatch table and
5818 -- the size of the Type_Specific_Data record.
5821 UI_To_Int (DT_Entry_Count (First_Tag_Component (Tag_Typ)));
5823 -- If the tagged type has no primitives we add a dummy slot
5824 -- whose address will be the tag of this type.
5828 New_List (Make_Integer_Literal (Loc, 1));
5831 New_List (Make_Integer_Literal (Loc, Nb_Prim));
5835 Make_Object_Declaration (Loc,
5836 Defining_Identifier => DT,
5837 Aliased_Present => True,
5838 Constant_Present => True,
5839 Object_Definition =>
5840 Make_Subtype_Indication (Loc,
5842 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
5843 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
5844 Constraints => DT_Constr_List))));
5850 Tname : constant Name_Id := Chars (Typ);
5851 AI_Tag_Comp : Elmt_Id;
5854 Predef_Prims_Ptr : Node_Id;
5856 Iface_DT_Ptr : Node_Id;
5859 Typ_Comps : Elist_Id;
5861 -- Start of processing for Make_Tags
5864 -- 1) Generate the primary and secondary tag entities
5866 -- Collect the components associated with secondary dispatch tables
5868 if Has_Interfaces (Typ) then
5869 Collect_Interface_Components (Typ, Typ_Comps);
5872 -- 1) Generate the primary tag entities
5874 -- Primary dispatch table containing user-defined primitives
5876 DT_Ptr := Make_Defining_Identifier (Loc,
5877 New_External_Name (Tname, 'P'));
5878 Set_Etype (DT_Ptr, RTE (RE_Tag));
5880 -- Primary dispatch table containing predefined primitives
5883 Make_Defining_Identifier (Loc,
5884 Chars => New_External_Name (Tname, 'Y'));
5885 Set_Etype (Predef_Prims_Ptr, RTE (RE_Address));
5887 -- Import the forward declaration of the Dispatch Table wrapper record
5888 -- (Make_DT will take care of its exportation)
5890 if Building_Static_DT (Typ) then
5891 Set_Dispatch_Table_Wrappers (Typ, New_Elmt_List);
5894 Make_Defining_Identifier (Loc,
5895 Chars => New_External_Name (Tname, 'T'));
5897 Import_DT (Typ, DT, Is_Secondary_DT => False);
5899 if Has_DT (Typ) then
5901 Make_Object_Declaration (Loc,
5902 Defining_Identifier => DT_Ptr,
5903 Constant_Present => True,
5904 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
5906 Unchecked_Convert_To (RTE (RE_Tag),
5907 Make_Attribute_Reference (Loc,
5909 Make_Selected_Component (Loc,
5910 Prefix => New_Reference_To (DT, Loc),
5913 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
5914 Attribute_Name => Name_Address))));
5917 Make_Object_Declaration (Loc,
5918 Defining_Identifier => Predef_Prims_Ptr,
5919 Constant_Present => True,
5920 Object_Definition => New_Reference_To
5921 (RTE (RE_Address), Loc),
5923 Make_Attribute_Reference (Loc,
5925 Make_Selected_Component (Loc,
5926 Prefix => New_Reference_To (DT, Loc),
5929 (RTE_Record_Component (RE_Predef_Prims), Loc)),
5930 Attribute_Name => Name_Address)));
5932 -- No dispatch table required
5936 Make_Object_Declaration (Loc,
5937 Defining_Identifier => DT_Ptr,
5938 Constant_Present => True,
5939 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
5941 Unchecked_Convert_To (RTE (RE_Tag),
5942 Make_Attribute_Reference (Loc,
5944 Make_Selected_Component (Loc,
5945 Prefix => New_Reference_To (DT, Loc),
5948 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
5949 Attribute_Name => Name_Address))));
5952 Set_Is_True_Constant (DT_Ptr);
5953 Set_Is_Statically_Allocated (DT_Ptr);
5956 pragma Assert (No (Access_Disp_Table (Typ)));
5957 Set_Access_Disp_Table (Typ, New_Elmt_List);
5958 Append_Elmt (DT_Ptr, Access_Disp_Table (Typ));
5959 Append_Elmt (Predef_Prims_Ptr, Access_Disp_Table (Typ));
5961 -- 2) Generate the secondary tag entities
5963 if Has_Interfaces (Typ) then
5965 -- Note: The following value of Suffix_Index must be in sync with
5966 -- the Suffix_Index values of secondary dispatch tables generated
5971 -- For each interface type we build an unique external name
5972 -- associated with its corresponding secondary dispatch table.
5973 -- This external name will be used to declare an object that
5974 -- references this secondary dispatch table, value that will be
5975 -- used for the elaboration of Typ's objects and also for the
5976 -- elaboration of objects of derivations of Typ that do not
5977 -- override the primitive operation of this interface type.
5979 AI_Tag_Comp := First_Elmt (Typ_Comps);
5980 while Present (AI_Tag_Comp) loop
5981 Get_Secondary_DT_External_Name
5982 (Typ, Related_Type (Node (AI_Tag_Comp)), Suffix_Index);
5983 Typ_Name := Name_Find;
5985 if Building_Static_DT (Typ) then
5987 Make_Defining_Identifier (Loc,
5988 Chars => New_External_Name
5989 (Typ_Name, 'T', Suffix_Index => -1));
5991 (Tag_Typ => Related_Type (Node (AI_Tag_Comp)),
5993 Is_Secondary_DT => True);
5996 -- Secondary dispatch table referencing thunks to user-defined
5997 -- primitives covered by this interface.
6000 Make_Defining_Identifier (Loc,
6001 Chars => New_External_Name (Typ_Name, 'P'));
6002 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
6003 Set_Ekind (Iface_DT_Ptr, E_Constant);
6004 Set_Is_Tag (Iface_DT_Ptr);
6005 Set_Has_Thunks (Iface_DT_Ptr);
6006 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6007 Is_Library_Level_Tagged_Type (Typ));
6008 Set_Is_True_Constant (Iface_DT_Ptr);
6010 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6011 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6013 if Building_Static_DT (Typ) then
6015 Make_Object_Declaration (Loc,
6016 Defining_Identifier => Iface_DT_Ptr,
6017 Constant_Present => True,
6018 Object_Definition => New_Reference_To
6019 (RTE (RE_Interface_Tag), Loc),
6021 Unchecked_Convert_To (RTE (RE_Interface_Tag),
6022 Make_Attribute_Reference (Loc,
6024 Make_Selected_Component (Loc,
6025 Prefix => New_Reference_To (Iface_DT, Loc),
6028 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
6029 Attribute_Name => Name_Address))));
6032 -- Secondary dispatch table referencing thunks to predefined
6036 Make_Defining_Identifier (Loc,
6037 Chars => New_External_Name (Typ_Name, 'Y'));
6038 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
6039 Set_Ekind (Iface_DT_Ptr, E_Constant);
6040 Set_Is_Tag (Iface_DT_Ptr);
6041 Set_Has_Thunks (Iface_DT_Ptr);
6042 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6043 Is_Library_Level_Tagged_Type (Typ));
6044 Set_Is_True_Constant (Iface_DT_Ptr);
6046 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6047 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6049 -- Secondary dispatch table referencing user-defined primitives
6050 -- covered by this interface.
6053 Make_Defining_Identifier (Loc,
6054 Chars => New_External_Name (Typ_Name, 'D'));
6055 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
6056 Set_Ekind (Iface_DT_Ptr, E_Constant);
6057 Set_Is_Tag (Iface_DT_Ptr);
6058 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6059 Is_Library_Level_Tagged_Type (Typ));
6060 Set_Is_True_Constant (Iface_DT_Ptr);
6062 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6063 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6065 -- Secondary dispatch table referencing predefined primitives
6068 Make_Defining_Identifier (Loc,
6069 Chars => New_External_Name (Typ_Name, 'Z'));
6070 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
6071 Set_Ekind (Iface_DT_Ptr, E_Constant);
6072 Set_Is_Tag (Iface_DT_Ptr);
6073 Set_Is_Statically_Allocated (Iface_DT_Ptr,
6074 Is_Library_Level_Tagged_Type (Typ));
6075 Set_Is_True_Constant (Iface_DT_Ptr);
6077 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
6078 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
6080 Next_Elmt (AI_Tag_Comp);
6084 -- 3) At the end of Access_Disp_Table we add the entity of an access
6085 -- type declaration. It is used by Build_Get_Prim_Op_Address to
6086 -- expand dispatching calls through the primary dispatch table.
6089 -- type Typ_DT is array (1 .. Nb_Prims) of Prim_Ptr;
6090 -- type Typ_DT_Acc is access Typ_DT;
6093 Name_DT_Prims : constant Name_Id :=
6094 New_External_Name (Tname, 'G');
6095 Name_DT_Prims_Acc : constant Name_Id :=
6096 New_External_Name (Tname, 'H');
6097 DT_Prims : constant Entity_Id :=
6098 Make_Defining_Identifier (Loc, Name_DT_Prims);
6099 DT_Prims_Acc : constant Entity_Id :=
6100 Make_Defining_Identifier (Loc,
6104 Make_Full_Type_Declaration (Loc,
6105 Defining_Identifier => DT_Prims,
6107 Make_Constrained_Array_Definition (Loc,
6108 Discrete_Subtype_Definitions => New_List (
6110 Low_Bound => Make_Integer_Literal (Loc, 1),
6111 High_Bound => Make_Integer_Literal (Loc,
6113 (First_Tag_Component (Typ))))),
6114 Component_Definition =>
6115 Make_Component_Definition (Loc,
6116 Subtype_Indication =>
6117 New_Reference_To (RTE (RE_Prim_Ptr), Loc)))));
6120 Make_Full_Type_Declaration (Loc,
6121 Defining_Identifier => DT_Prims_Acc,
6123 Make_Access_To_Object_Definition (Loc,
6124 Subtype_Indication =>
6125 New_Occurrence_Of (DT_Prims, Loc))));
6127 Append_Elmt (DT_Prims_Acc, Access_Disp_Table (Typ));
6129 -- Analyze the resulting list and suppress the generation of the
6130 -- Init_Proc associated with the above array declaration because
6131 -- we never use such type in object declarations; this type is only
6132 -- used to simplify the expansion associated with dispatching calls.
6134 Analyze_List (Result);
6135 Set_Suppress_Init_Proc (Base_Type (DT_Prims));
6137 -- Mark entity of dispatch table. Required by the backend to handle
6140 Set_Is_Dispatch_Table_Entity (DT_Prims);
6143 Set_Ekind (DT_Ptr, E_Constant);
6144 Set_Is_Tag (DT_Ptr);
6145 Set_Related_Type (DT_Ptr, Typ);
6150 -----------------------------------
6151 -- Original_View_In_Visible_Part --
6152 -----------------------------------
6154 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
6155 Scop : constant Entity_Id := Scope (Typ);
6158 -- The scope must be a package
6160 if not Is_Package_Or_Generic_Package (Scop) then
6164 -- A type with a private declaration has a private view declared in
6165 -- the visible part.
6167 if Has_Private_Declaration (Typ) then
6171 return List_Containing (Parent (Typ)) =
6172 Visible_Declarations (Specification (Unit_Declaration_Node (Scop)));
6173 end Original_View_In_Visible_Part;
6179 function Prim_Op_Kind
6181 Typ : Entity_Id) return Node_Id
6183 Full_Typ : Entity_Id := Typ;
6184 Loc : constant Source_Ptr := Sloc (Prim);
6185 Prim_Op : Entity_Id;
6188 -- Retrieve the original primitive operation
6191 while Present (Alias (Prim_Op)) loop
6192 Prim_Op := Alias (Prim_Op);
6195 if Ekind (Typ) = E_Record_Type
6196 and then Present (Corresponding_Concurrent_Type (Typ))
6198 Full_Typ := Corresponding_Concurrent_Type (Typ);
6201 -- When a private tagged type is completed by a concurrent type,
6202 -- retrieve the full view.
6204 if Is_Private_Type (Full_Typ) then
6205 Full_Typ := Full_View (Full_Typ);
6208 if Ekind (Prim_Op) = E_Function then
6210 -- Protected function
6212 if Ekind (Full_Typ) = E_Protected_Type then
6213 return New_Reference_To (RTE (RE_POK_Protected_Function), Loc);
6217 elsif Ekind (Full_Typ) = E_Task_Type then
6218 return New_Reference_To (RTE (RE_POK_Task_Function), Loc);
6223 return New_Reference_To (RTE (RE_POK_Function), Loc);
6227 pragma Assert (Ekind (Prim_Op) = E_Procedure);
6229 if Ekind (Full_Typ) = E_Protected_Type then
6233 if Is_Primitive_Wrapper (Prim_Op)
6234 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
6236 return New_Reference_To (RTE (RE_POK_Protected_Entry), Loc);
6238 -- Protected procedure
6241 return New_Reference_To (RTE (RE_POK_Protected_Procedure), Loc);
6244 elsif Ekind (Full_Typ) = E_Task_Type then
6248 if Is_Primitive_Wrapper (Prim_Op)
6249 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
6251 return New_Reference_To (RTE (RE_POK_Task_Entry), Loc);
6253 -- Task "procedure". These are the internally Expander-generated
6254 -- procedures (task body for instance).
6257 return New_Reference_To (RTE (RE_POK_Task_Procedure), Loc);
6260 -- Regular procedure
6263 return New_Reference_To (RTE (RE_POK_Procedure), Loc);
6268 ------------------------
6269 -- Register_Primitive --
6270 ------------------------
6272 procedure Register_Primitive
6278 Iface_Prim : Entity_Id;
6279 Iface_Typ : Entity_Id;
6280 Iface_DT_Ptr : Entity_Id;
6281 Iface_DT_Elmt : Elmt_Id;
6285 Tag_Typ : Entity_Id;
6286 Thunk_Id : Entity_Id;
6287 Thunk_Code : Node_Id;
6290 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
6292 if not RTE_Available (RE_Tag) then
6296 if not Present (Interface_Alias (Prim)) then
6297 Tag_Typ := Scope (DTC_Entity (Prim));
6298 Pos := DT_Position (Prim);
6299 Tag := First_Tag_Component (Tag_Typ);
6301 if Is_Predefined_Dispatching_Operation (Prim)
6302 or else Is_Predefined_Dispatching_Alias (Prim)
6305 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Tag_Typ))));
6307 Insert_After (Ins_Nod,
6308 Build_Set_Predefined_Prim_Op_Address (Loc,
6309 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6312 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6313 Make_Attribute_Reference (Loc,
6314 Prefix => New_Reference_To (Prim, Loc),
6315 Attribute_Name => Name_Unrestricted_Access))));
6317 -- Register copy of the pointer to the 'size primitive in the TSD
6319 if Chars (Prim) = Name_uSize
6320 and then RTE_Record_Component_Available (RE_Size_Func)
6322 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
6323 Insert_After (Ins_Nod,
6324 Build_Set_Size_Function (Loc,
6325 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6326 Size_Func => Prim));
6330 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
6332 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
6333 Insert_After (Ins_Nod,
6334 Build_Set_Prim_Op_Address (Loc,
6336 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6339 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6340 Make_Attribute_Reference (Loc,
6341 Prefix => New_Reference_To (Prim, Loc),
6342 Attribute_Name => Name_Unrestricted_Access))));
6345 -- Ada 2005 (AI-251): Primitive associated with an interface type
6346 -- Generate the code of the thunk only if the interface type is not an
6347 -- immediate ancestor of Typ; otherwise the dispatch table associated
6348 -- with the interface is the primary dispatch table and we have nothing
6352 Tag_Typ := Find_Dispatching_Type (Alias (Prim));
6353 Iface_Typ := Find_Dispatching_Type (Interface_Alias (Prim));
6355 pragma Assert (Is_Interface (Iface_Typ));
6357 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
6359 if not Is_Ancestor (Iface_Typ, Tag_Typ)
6360 and then Present (Thunk_Code)
6362 -- Comment needed on why checks are suppressed. This is not just
6363 -- efficiency, but fundamental functionality (see 1.295 RH, which
6364 -- still does not answer this question) ???
6366 Insert_Action (Ins_Nod, Thunk_Code, Suppress => All_Checks);
6368 -- Generate the code necessary to fill the appropriate entry of
6369 -- the secondary dispatch table of Prim's controlling type with
6370 -- Thunk_Id's address.
6372 Iface_DT_Elmt := Find_Interface_ADT (Tag_Typ, Iface_Typ);
6373 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6374 pragma Assert (Has_Thunks (Iface_DT_Ptr));
6376 Iface_Prim := Interface_Alias (Prim);
6377 Pos := DT_Position (Iface_Prim);
6378 Tag := First_Tag_Component (Iface_Typ);
6381 if Is_Predefined_Dispatching_Operation (Prim)
6382 or else Is_Predefined_Dispatching_Alias (Prim)
6385 Build_Set_Predefined_Prim_Op_Address (Loc,
6387 New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
6390 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6391 Make_Attribute_Reference (Loc,
6392 Prefix => New_Reference_To (Thunk_Id, Loc),
6393 Attribute_Name => Name_Unrestricted_Access))));
6395 Next_Elmt (Iface_DT_Elmt);
6396 Next_Elmt (Iface_DT_Elmt);
6397 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6398 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
6401 Build_Set_Predefined_Prim_Op_Address (Loc,
6403 New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
6406 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6407 Make_Attribute_Reference (Loc,
6408 Prefix => New_Reference_To (Alias (Prim), Loc),
6409 Attribute_Name => Name_Unrestricted_Access))));
6411 Insert_Actions_After (Ins_Nod, L);
6414 pragma Assert (Pos /= Uint_0
6415 and then Pos <= DT_Entry_Count (Tag));
6418 Build_Set_Prim_Op_Address (Loc,
6420 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
6423 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6424 Make_Attribute_Reference (Loc,
6425 Prefix => New_Reference_To (Thunk_Id, Loc),
6426 Attribute_Name => Name_Unrestricted_Access))));
6428 Next_Elmt (Iface_DT_Elmt);
6429 Next_Elmt (Iface_DT_Elmt);
6430 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6431 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
6434 Build_Set_Prim_Op_Address (Loc,
6436 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
6439 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6440 Make_Attribute_Reference (Loc,
6441 Prefix => New_Reference_To (Alias (Prim), Loc),
6442 Attribute_Name => Name_Unrestricted_Access))));
6444 Insert_Actions_After (Ins_Nod, L);
6448 end Register_Primitive;
6450 -------------------------
6451 -- Set_All_DT_Position --
6452 -------------------------
6454 procedure Set_All_DT_Position (Typ : Entity_Id) is
6456 procedure Validate_Position (Prim : Entity_Id);
6457 -- Check that the position assigned to Prim is completely safe
6458 -- (it has not been assigned to a previously defined primitive
6459 -- operation of Typ)
6461 -----------------------
6462 -- Validate_Position --
6463 -----------------------
6465 procedure Validate_Position (Prim : Entity_Id) is
6470 -- Aliased primitives are safe
6472 if Present (Alias (Prim)) then
6476 Op_Elmt := First_Elmt (Primitive_Operations (Typ));
6477 while Present (Op_Elmt) loop
6478 Op := Node (Op_Elmt);
6480 -- No need to check against itself
6485 -- Primitive operations covering abstract interfaces are
6488 elsif Present (Interface_Alias (Op)) then
6491 -- Predefined dispatching operations are completely safe. They
6492 -- are allocated at fixed positions in a separate table.
6494 elsif Is_Predefined_Dispatching_Operation (Op)
6495 or else Is_Predefined_Dispatching_Alias (Op)
6499 -- Aliased subprograms are safe
6501 elsif Present (Alias (Op)) then
6504 elsif DT_Position (Op) = DT_Position (Prim)
6505 and then not Is_Predefined_Dispatching_Operation (Op)
6506 and then not Is_Predefined_Dispatching_Operation (Prim)
6507 and then not Is_Predefined_Dispatching_Alias (Op)
6508 and then not Is_Predefined_Dispatching_Alias (Prim)
6511 -- Handle aliased subprograms
6520 if Present (Overridden_Operation (Op_1)) then
6521 Op_1 := Overridden_Operation (Op_1);
6522 elsif Present (Alias (Op_1)) then
6523 Op_1 := Alias (Op_1);
6531 if Present (Overridden_Operation (Op_2)) then
6532 Op_2 := Overridden_Operation (Op_2);
6533 elsif Present (Alias (Op_2)) then
6534 Op_2 := Alias (Op_2);
6540 if Op_1 /= Op_2 then
6541 raise Program_Error;
6546 Next_Elmt (Op_Elmt);
6548 end Validate_Position;
6552 Parent_Typ : constant Entity_Id := Etype (Typ);
6553 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
6554 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
6556 Adjusted : Boolean := False;
6557 Finalized : Boolean := False;
6563 Prim_Elmt : Elmt_Id;
6565 -- Start of processing for Set_All_DT_Position
6568 pragma Assert (Present (First_Tag_Component (Typ)));
6570 -- Set the DT_Position for each primitive operation. Perform some
6571 -- sanity checks to avoid to build completely inconsistent dispatch
6574 -- First stage: Set the DTC entity of all the primitive operations
6575 -- This is required to properly read the DT_Position attribute in
6576 -- the latter stages.
6578 Prim_Elmt := First_Prim;
6580 while Present (Prim_Elmt) loop
6581 Prim := Node (Prim_Elmt);
6583 -- Predefined primitives have a separate dispatch table
6585 if not (Is_Predefined_Dispatching_Operation (Prim)
6586 or else Is_Predefined_Dispatching_Alias (Prim))
6588 Count_Prim := Count_Prim + 1;
6591 Set_DTC_Entity_Value (Typ, Prim);
6593 -- Clear any previous value of the DT_Position attribute. In this
6594 -- way we ensure that the final position of all the primitives is
6595 -- established by the following stages of this algorithm.
6597 Set_DT_Position (Prim, No_Uint);
6599 Next_Elmt (Prim_Elmt);
6603 Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean :=
6608 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id);
6609 -- Called if Typ is declared in a nested package or a public child
6610 -- package to handle inherited primitives that were inherited by Typ
6611 -- in the visible part, but whose declaration was deferred because
6612 -- the parent operation was private and not visible at that point.
6614 procedure Set_Fixed_Prim (Pos : Nat);
6615 -- Sets to true an element of the Fixed_Prim table to indicate
6616 -- that this entry of the dispatch table of Typ is occupied.
6618 ------------------------------------------
6619 -- Handle_Inherited_Private_Subprograms --
6620 ------------------------------------------
6622 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id) is
6625 Op_Elmt_2 : Elmt_Id;
6626 Prim_Op : Entity_Id;
6627 Parent_Subp : Entity_Id;
6630 Op_List := Primitive_Operations (Typ);
6632 Op_Elmt := First_Elmt (Op_List);
6633 while Present (Op_Elmt) loop
6634 Prim_Op := Node (Op_Elmt);
6636 -- Search primitives that are implicit operations with an
6637 -- internal name whose parent operation has a normal name.
6639 if Present (Alias (Prim_Op))
6640 and then Find_Dispatching_Type (Alias (Prim_Op)) /= Typ
6641 and then not Comes_From_Source (Prim_Op)
6642 and then Is_Internal_Name (Chars (Prim_Op))
6643 and then not Is_Internal_Name (Chars (Alias (Prim_Op)))
6645 Parent_Subp := Alias (Prim_Op);
6647 -- Check if the type has an explicit overriding for this
6650 Op_Elmt_2 := Next_Elmt (Op_Elmt);
6651 while Present (Op_Elmt_2) loop
6652 if Chars (Node (Op_Elmt_2)) = Chars (Parent_Subp)
6653 and then Type_Conformant (Prim_Op, Node (Op_Elmt_2))
6655 Set_DT_Position (Prim_Op, DT_Position (Parent_Subp));
6656 Set_DT_Position (Node (Op_Elmt_2),
6657 DT_Position (Parent_Subp));
6658 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim_Op)));
6660 goto Next_Primitive;
6663 Next_Elmt (Op_Elmt_2);
6668 Next_Elmt (Op_Elmt);
6670 end Handle_Inherited_Private_Subprograms;
6672 --------------------
6673 -- Set_Fixed_Prim --
6674 --------------------
6676 procedure Set_Fixed_Prim (Pos : Nat) is
6678 pragma Assert (Pos <= Count_Prim);
6679 Fixed_Prim (Pos) := True;
6681 when Constraint_Error =>
6682 raise Program_Error;
6686 -- In case of nested packages and public child package it may be
6687 -- necessary a special management on inherited subprograms so that
6688 -- the dispatch table is properly filled.
6690 if Ekind (Scope (Scope (Typ))) = E_Package
6691 and then Scope (Scope (Typ)) /= Standard_Standard
6692 and then ((Is_Derived_Type (Typ) and then not Is_Private_Type (Typ))
6694 (Nkind (Parent (Typ)) = N_Private_Extension_Declaration
6695 and then Is_Generic_Type (Typ)))
6696 and then In_Open_Scopes (Scope (Etype (Typ)))
6697 and then Typ = Base_Type (Typ)
6699 Handle_Inherited_Private_Subprograms (Typ);
6702 -- Second stage: Register fixed entries
6705 Prim_Elmt := First_Prim;
6706 while Present (Prim_Elmt) loop
6707 Prim := Node (Prim_Elmt);
6709 -- Predefined primitives have a separate table and all its
6710 -- entries are at predefined fixed positions.
6712 if Is_Predefined_Dispatching_Operation (Prim) then
6713 Set_DT_Position (Prim, Default_Prim_Op_Position (Prim));
6715 elsif Is_Predefined_Dispatching_Alias (Prim) then
6717 while Present (Alias (E)) loop
6721 Set_DT_Position (Prim, Default_Prim_Op_Position (E));
6723 -- Overriding primitives of ancestor abstract interfaces
6725 elsif Present (Interface_Alias (Prim))
6726 and then Is_Ancestor
6727 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ)
6729 pragma Assert (DT_Position (Prim) = No_Uint
6730 and then Present (DTC_Entity (Interface_Alias (Prim))));
6732 E := Interface_Alias (Prim);
6733 Set_DT_Position (Prim, DT_Position (E));
6736 (DT_Position (Alias (Prim)) = No_Uint
6737 or else DT_Position (Alias (Prim)) = DT_Position (E));
6738 Set_DT_Position (Alias (Prim), DT_Position (E));
6739 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));
6741 -- Overriding primitives must use the same entry as the
6742 -- overridden primitive.
6744 elsif not Present (Interface_Alias (Prim))
6745 and then Present (Alias (Prim))
6746 and then Chars (Prim) = Chars (Alias (Prim))
6747 and then Find_Dispatching_Type (Alias (Prim)) /= Typ
6748 and then Is_Ancestor
6749 (Find_Dispatching_Type (Alias (Prim)), Typ)
6750 and then Present (DTC_Entity (Alias (Prim)))
6753 Set_DT_Position (Prim, DT_Position (E));
6755 if not Is_Predefined_Dispatching_Alias (E) then
6756 Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
6760 Next_Elmt (Prim_Elmt);
6763 -- Third stage: Fix the position of all the new primitives
6764 -- Entries associated with primitives covering interfaces
6765 -- are handled in a latter round.
6767 Prim_Elmt := First_Prim;
6768 while Present (Prim_Elmt) loop
6769 Prim := Node (Prim_Elmt);
6771 -- Skip primitives previously set entries
6773 if DT_Position (Prim) /= No_Uint then
6776 -- Primitives covering interface primitives are handled later
6778 elsif Present (Interface_Alias (Prim)) then
6782 -- Take the next available position in the DT
6785 Nb_Prim := Nb_Prim + 1;
6786 pragma Assert (Nb_Prim <= Count_Prim);
6787 exit when not Fixed_Prim (Nb_Prim);
6790 Set_DT_Position (Prim, UI_From_Int (Nb_Prim));
6791 Set_Fixed_Prim (Nb_Prim);
6794 Next_Elmt (Prim_Elmt);
6798 -- Fourth stage: Complete the decoration of primitives covering
6799 -- interfaces (that is, propagate the DT_Position attribute
6800 -- from the aliased primitive)
6802 Prim_Elmt := First_Prim;
6803 while Present (Prim_Elmt) loop
6804 Prim := Node (Prim_Elmt);
6806 if DT_Position (Prim) = No_Uint
6807 and then Present (Interface_Alias (Prim))
6809 pragma Assert (Present (Alias (Prim))
6810 and then Find_Dispatching_Type (Alias (Prim)) = Typ);
6812 -- Check if this entry will be placed in the primary DT
6815 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ)
6817 pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
6818 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
6820 -- Otherwise it will be placed in the secondary DT
6824 (DT_Position (Interface_Alias (Prim)) /= No_Uint);
6825 Set_DT_Position (Prim,
6826 DT_Position (Interface_Alias (Prim)));
6830 Next_Elmt (Prim_Elmt);
6833 -- Generate listing showing the contents of the dispatch tables.
6834 -- This action is done before some further static checks because
6835 -- in case of critical errors caused by a wrong dispatch table
6836 -- we need to see the contents of such table.
6838 if Debug_Flag_ZZ then
6842 -- Final stage: Ensure that the table is correct plus some further
6843 -- verifications concerning the primitives.
6845 Prim_Elmt := First_Prim;
6847 while Present (Prim_Elmt) loop
6848 Prim := Node (Prim_Elmt);
6850 -- At this point all the primitives MUST have a position
6851 -- in the dispatch table.
6853 if DT_Position (Prim) = No_Uint then
6854 raise Program_Error;
6857 -- Calculate real size of the dispatch table
6859 if not (Is_Predefined_Dispatching_Operation (Prim)
6860 or else Is_Predefined_Dispatching_Alias (Prim))
6861 and then UI_To_Int (DT_Position (Prim)) > DT_Length
6863 DT_Length := UI_To_Int (DT_Position (Prim));
6866 -- Ensure that the assigned position to non-predefined
6867 -- dispatching operations in the dispatch table is correct.
6869 if not (Is_Predefined_Dispatching_Operation (Prim)
6870 or else Is_Predefined_Dispatching_Alias (Prim))
6872 Validate_Position (Prim);
6875 if Chars (Prim) = Name_Finalize then
6879 if Chars (Prim) = Name_Adjust then
6883 -- An abstract operation cannot be declared in the private part
6884 -- for a visible abstract type, because it could never be over-
6885 -- ridden. For explicit declarations this is checked at the
6886 -- point of declaration, but for inherited operations it must
6887 -- be done when building the dispatch table.
6889 -- Ada 2005 (AI-251): Primitives associated with interfaces are
6890 -- excluded from this check because interfaces must be visible in
6891 -- the public and private part (RM 7.3 (7.3/2))
6893 if Is_Abstract_Type (Typ)
6894 and then Is_Abstract_Subprogram (Prim)
6895 and then Present (Alias (Prim))
6896 and then not Is_Interface
6897 (Find_Dispatching_Type (Ultimate_Alias (Prim)))
6898 and then not Present (Interface_Alias (Prim))
6899 and then Is_Derived_Type (Typ)
6900 and then In_Private_Part (Current_Scope)
6902 List_Containing (Parent (Prim)) =
6903 Private_Declarations
6904 (Specification (Unit_Declaration_Node (Current_Scope)))
6905 and then Original_View_In_Visible_Part (Typ)
6907 -- We exclude Input and Output stream operations because
6908 -- Limited_Controlled inherits useless Input and Output
6909 -- stream operations from Root_Controlled, which can
6910 -- never be overridden.
6912 if not Is_TSS (Prim, TSS_Stream_Input)
6914 not Is_TSS (Prim, TSS_Stream_Output)
6917 ("abstract inherited private operation&" &
6918 " must be overridden (RM 3.9.3(10))",
6919 Parent (Typ), Prim);
6923 Next_Elmt (Prim_Elmt);
6928 if Is_Controlled (Typ) then
6929 if not Finalized then
6931 ("controlled type has no explicit Finalize method?", Typ);
6933 elsif not Adjusted then
6935 ("controlled type has no explicit Adjust method?", Typ);
6939 -- Set the final size of the Dispatch Table
6941 Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));
6943 -- The derived type must have at least as many components as its parent
6944 -- (for root types Etype points to itself and the test cannot fail).
6946 if DT_Entry_Count (The_Tag) <
6947 DT_Entry_Count (First_Tag_Component (Parent_Typ))
6949 raise Program_Error;
6951 end Set_All_DT_Position;
6953 -----------------------------
6954 -- Set_Default_Constructor --
6955 -----------------------------
6957 procedure Set_Default_Constructor (Typ : Entity_Id) is
6964 -- Look for the default constructor entity. For now only the
6965 -- default constructor has the flag Is_Constructor.
6967 E := Next_Entity (Typ);
6969 and then (Ekind (E) /= E_Function or else not Is_Constructor (E))
6974 -- Create the init procedure
6978 Init := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
6979 Param := Make_Defining_Identifier (Loc, Name_X);
6982 Make_Subprogram_Declaration (Loc,
6983 Make_Procedure_Specification (Loc,
6984 Defining_Unit_Name => Init,
6985 Parameter_Specifications => New_List (
6986 Make_Parameter_Specification (Loc,
6987 Defining_Identifier => Param,
6988 Parameter_Type => New_Reference_To (Typ, Loc))))));
6990 Set_Init_Proc (Typ, Init);
6991 Set_Is_Imported (Init);
6992 Set_Interface_Name (Init, Interface_Name (E));
6993 Set_Convention (Init, Convention_C);
6994 Set_Is_Public (Init);
6995 Set_Has_Completion (Init);
6997 -- If there are no constructors, mark the type as abstract since we
6998 -- won't be able to declare objects of that type.
7001 Set_Is_Abstract_Type (Typ);
7003 end Set_Default_Constructor;
7005 --------------------------
7006 -- Set_DTC_Entity_Value --
7007 --------------------------
7009 procedure Set_DTC_Entity_Value
7010 (Tagged_Type : Entity_Id;
7014 if Present (Interface_Alias (Prim))
7015 and then Is_Interface
7016 (Find_Dispatching_Type (Interface_Alias (Prim)))
7018 Set_DTC_Entity (Prim,
7021 Iface => Find_Dispatching_Type (Interface_Alias (Prim))));
7023 Set_DTC_Entity (Prim,
7024 First_Tag_Component (Tagged_Type));
7026 end Set_DTC_Entity_Value;
7032 function Tagged_Kind (T : Entity_Id) return Node_Id is
7033 Conc_Typ : Entity_Id;
7034 Loc : constant Source_Ptr := Sloc (T);
7038 (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));
7042 if Is_Abstract_Type (T) then
7043 if Is_Limited_Record (T) then
7044 return New_Reference_To (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
7046 return New_Reference_To (RTE (RE_TK_Abstract_Tagged), Loc);
7051 elsif Is_Concurrent_Record_Type (T) then
7052 Conc_Typ := Corresponding_Concurrent_Type (T);
7054 if Present (Full_View (Conc_Typ)) then
7055 Conc_Typ := Full_View (Conc_Typ);
7058 if Ekind (Conc_Typ) = E_Protected_Type then
7059 return New_Reference_To (RTE (RE_TK_Protected), Loc);
7061 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
7062 return New_Reference_To (RTE (RE_TK_Task), Loc);
7065 -- Regular tagged kinds
7068 if Is_Limited_Record (T) then
7069 return New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc);
7071 return New_Reference_To (RTE (RE_TK_Tagged), Loc);
7080 procedure Write_DT (Typ : Entity_Id) is
7085 -- Protect this procedure against wrong usage. Required because it will
7086 -- be used directly from GDB
7088 if not (Typ <= Last_Node_Id)
7089 or else not Is_Tagged_Type (Typ)
7091 Write_Str ("wrong usage: Write_DT must be used with tagged types");
7096 Write_Int (Int (Typ));
7098 Write_Name (Chars (Typ));
7100 if Is_Interface (Typ) then
7101 Write_Str (" is interface");
7106 Elmt := First_Elmt (Primitive_Operations (Typ));
7107 while Present (Elmt) loop
7108 Prim := Node (Elmt);
7111 -- Indicate if this primitive will be allocated in the primary
7112 -- dispatch table or in a secondary dispatch table associated
7113 -- with an abstract interface type
7115 if Present (DTC_Entity (Prim)) then
7116 if Etype (DTC_Entity (Prim)) = RTE (RE_Tag) then
7123 -- Output the node of this primitive operation and its name
7125 Write_Int (Int (Prim));
7128 if Is_Predefined_Dispatching_Operation (Prim) then
7129 Write_Str ("(predefined) ");
7132 Write_Name (Chars (Prim));
7134 -- Indicate if this primitive has an aliased primitive
7136 if Present (Alias (Prim)) then
7137 Write_Str (" (alias = ");
7138 Write_Int (Int (Alias (Prim)));
7140 -- If the DTC_Entity attribute is already set we can also output
7141 -- the name of the interface covered by this primitive (if any)
7143 if Present (DTC_Entity (Alias (Prim)))
7144 and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
7146 Write_Str (" from interface ");
7147 Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
7150 if Present (Interface_Alias (Prim)) then
7151 Write_Str (", AI_Alias of ");
7153 (Chars (Find_Dispatching_Type (Interface_Alias (Prim))));
7155 Write_Int (Int (Interface_Alias (Prim)));
7161 -- Display the final position of this primitive in its associated
7162 -- (primary or secondary) dispatch table
7164 if Present (DTC_Entity (Prim))
7165 and then DT_Position (Prim) /= No_Uint
7167 Write_Str (" at #");
7168 Write_Int (UI_To_Int (DT_Position (Prim)));
7171 if Is_Abstract_Subprogram (Prim) then
7172 Write_Str (" is abstract;");
7174 -- Check if this is a null primitive
7176 elsif Comes_From_Source (Prim)
7177 and then Ekind (Prim) = E_Procedure
7178 and then Null_Present (Parent (Prim))
7180 Write_Str (" is null;");