1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2007, 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 2, 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 COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 ------------------------------------------------------------------------------
27 with Atree; use Atree;
28 with Checks; use Checks;
29 with Debug; use Debug;
30 with Einfo; use Einfo;
31 with Elists; use Elists;
32 with Errout; use Errout;
33 with Exp_Atag; use Exp_Atag;
34 with Exp_Ch7; use Exp_Ch7;
35 with Exp_Dbug; use Exp_Dbug;
36 with Exp_Tss; use Exp_Tss;
37 with Exp_Util; use Exp_Util;
38 with Freeze; use Freeze;
39 with Itypes; use Itypes;
41 with Nlists; use Nlists;
42 with Nmake; use Nmake;
43 with Namet; use Namet;
45 with Output; use Output;
46 with Restrict; use Restrict;
47 with Rident; use Rident;
48 with Rtsfind; use Rtsfind;
50 with Sem_Ch6; use Sem_Ch6;
51 with Sem_Ch8; use Sem_Ch8;
52 with Sem_Disp; use Sem_Disp;
53 with Sem_Eval; use Sem_Eval;
54 with Sem_Res; use Sem_Res;
55 with Sem_Type; use Sem_Type;
56 with Sem_Util; use Sem_Util;
57 with Sinfo; use Sinfo;
58 with Snames; use Snames;
59 with Stand; use Stand;
60 with Stringt; use Stringt;
61 with Targparm; use Targparm;
62 with Tbuild; use Tbuild;
63 with Uintp; use Uintp;
65 package body Exp_Disp is
67 -----------------------
68 -- Local Subprograms --
69 -----------------------
71 function Default_Prim_Op_Position (E : Entity_Id) return Uint;
72 -- Ada 2005 (AI-251): Returns the fixed position in the dispatch table
73 -- of the default primitive operations.
75 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean;
76 -- Returns true if Prim is not a predefined dispatching primitive but it is
77 -- an alias of a predefined dispatching primitive (ie. through a renaming)
79 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean;
80 -- Check if the type has a private view or if the public view appears
81 -- in the visible part of a package spec.
85 Typ : Entity_Id) return Node_Id;
86 -- Ada 2005 (AI-345): Determine the primitive operation kind of Prim
87 -- according to its type Typ. Return a reference to an RE_Prim_Op_Kind
90 function Tagged_Kind (T : Entity_Id) return Node_Id;
91 -- Ada 2005 (AI-345): Determine the tagged kind of T and return a reference
92 -- to an RE_Tagged_Kind enumeration value.
94 ------------------------------
95 -- Default_Prim_Op_Position --
96 ------------------------------
98 function Default_Prim_Op_Position (E : Entity_Id) return Uint is
99 TSS_Name : TSS_Name_Type;
102 Get_Name_String (Chars (E));
105 (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
107 if Chars (E) = Name_uSize then
110 elsif Chars (E) = Name_uAlignment then
113 elsif TSS_Name = TSS_Stream_Read then
116 elsif TSS_Name = TSS_Stream_Write then
119 elsif TSS_Name = TSS_Stream_Input then
122 elsif TSS_Name = TSS_Stream_Output then
125 elsif Chars (E) = Name_Op_Eq then
128 elsif Chars (E) = Name_uAssign then
131 elsif TSS_Name = TSS_Deep_Adjust then
134 elsif TSS_Name = TSS_Deep_Finalize then
137 elsif Ada_Version >= Ada_05 then
138 if Chars (E) = Name_uDisp_Asynchronous_Select then
141 elsif Chars (E) = Name_uDisp_Conditional_Select then
144 elsif Chars (E) = Name_uDisp_Get_Prim_Op_Kind then
147 elsif Chars (E) = Name_uDisp_Get_Task_Id then
150 elsif Chars (E) = Name_uDisp_Timed_Select then
156 end Default_Prim_Op_Position;
158 -----------------------------
159 -- Expand_Dispatching_Call --
160 -----------------------------
162 procedure Expand_Dispatching_Call (Call_Node : Node_Id) is
163 Loc : constant Source_Ptr := Sloc (Call_Node);
164 Call_Typ : constant Entity_Id := Etype (Call_Node);
166 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
167 Param_List : constant List_Id := Parameter_Associations (Call_Node);
172 New_Call_Name : Node_Id;
173 New_Params : List_Id := No_List;
176 Subp_Ptr_Typ : Entity_Id;
177 Subp_Typ : Entity_Id;
179 Eq_Prim_Op : Entity_Id := Empty;
180 Controlling_Tag : Node_Id;
182 function New_Value (From : Node_Id) return Node_Id;
183 -- From is the original Expression. New_Value is equivalent to a call
184 -- to Duplicate_Subexpr with an explicit dereference when From is an
191 function New_Value (From : Node_Id) return Node_Id is
192 Res : constant Node_Id := Duplicate_Subexpr (From);
194 if Is_Access_Type (Etype (From)) then
196 Make_Explicit_Dereference (Sloc (From),
203 -- Start of processing for Expand_Dispatching_Call
206 if No_Run_Time_Mode then
207 Error_Msg_CRT ("tagged types", Call_Node);
211 -- Expand_Dispatching_Call is called directly from the semantics,
212 -- so we need a check to see whether expansion is active before
213 -- proceeding. In addition, there is no need to expand the call
214 -- if we are compiling under restriction No_Dispatching_Calls;
215 -- the semantic analyzer has previously notified the violation
216 -- of this restriction.
218 if not Expander_Active
219 or else Restriction_Active (No_Dispatching_Calls)
224 -- Set subprogram. If this is an inherited operation that was
225 -- overridden, the body that is being called is its alias.
227 Subp := Entity (Name (Call_Node));
229 if Present (Alias (Subp))
230 and then Is_Inherited_Operation (Subp)
231 and then No (DTC_Entity (Subp))
233 Subp := Alias (Subp);
236 -- Definition of the class-wide type and the tagged type
238 -- If the controlling argument is itself a tag rather than a tagged
239 -- object, then use the class-wide type associated with the subprogram's
240 -- controlling type. This case can occur when a call to an inherited
241 -- primitive has an actual that originated from a default parameter
242 -- given by a tag-indeterminate call and when there is no other
243 -- controlling argument providing the tag (AI-239 requires dispatching).
244 -- This capability of dispatching directly by tag is also needed by the
245 -- implementation of AI-260 (for the generic dispatching constructors).
247 if Etype (Ctrl_Arg) = RTE (RE_Tag)
248 or else (RTE_Available (RE_Interface_Tag)
249 and then Etype (Ctrl_Arg) = RTE (RE_Interface_Tag))
251 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
253 -- Class_Wide_Type is applied to the expressions used to initialize
254 -- CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
255 -- there are cases where the controlling type is resolved to a specific
256 -- type (such as for designated types of arguments such as CW'Access).
258 elsif Is_Access_Type (Etype (Ctrl_Arg)) then
259 CW_Typ := Class_Wide_Type (Designated_Type (Etype (Ctrl_Arg)));
262 CW_Typ := Class_Wide_Type (Etype (Ctrl_Arg));
265 Typ := Root_Type (CW_Typ);
267 if Ekind (Typ) = E_Incomplete_Type then
268 Typ := Non_Limited_View (Typ);
271 if not Is_Limited_Type (Typ) then
272 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
275 -- Dispatching call to C++ primitive. Create a new parameter list
276 -- with no tag checks.
278 if Is_CPP_Class (Typ) then
279 New_Params := New_List;
280 Param := First_Actual (Call_Node);
281 while Present (Param) loop
282 Append_To (New_Params, Relocate_Node (Param));
286 -- Dispatching call to Ada primitive
288 elsif Present (Param_List) then
290 -- Generate the Tag checks when appropriate
292 New_Params := New_List;
293 Param := First_Actual (Call_Node);
294 while Present (Param) loop
296 -- No tag check with itself
298 if Param = Ctrl_Arg then
299 Append_To (New_Params,
300 Duplicate_Subexpr_Move_Checks (Param));
302 -- No tag check for parameter whose type is neither tagged nor
303 -- access to tagged (for access parameters)
305 elsif No (Find_Controlling_Arg (Param)) then
306 Append_To (New_Params, Relocate_Node (Param));
308 -- No tag check for function dispatching on result if the
309 -- Tag given by the context is this one
311 elsif Find_Controlling_Arg (Param) = Ctrl_Arg then
312 Append_To (New_Params, Relocate_Node (Param));
314 -- "=" is the only dispatching operation allowed to get
315 -- operands with incompatible tags (it just returns false).
316 -- We use Duplicate_Subexpr_Move_Checks instead of calling
317 -- Relocate_Node because the value will be duplicated to
320 elsif Subp = Eq_Prim_Op then
321 Append_To (New_Params,
322 Duplicate_Subexpr_Move_Checks (Param));
324 -- No check in presence of suppress flags
326 elsif Tag_Checks_Suppressed (Etype (Param))
327 or else (Is_Access_Type (Etype (Param))
328 and then Tag_Checks_Suppressed
329 (Designated_Type (Etype (Param))))
331 Append_To (New_Params, Relocate_Node (Param));
333 -- Optimization: no tag checks if the parameters are identical
335 elsif Is_Entity_Name (Param)
336 and then Is_Entity_Name (Ctrl_Arg)
337 and then Entity (Param) = Entity (Ctrl_Arg)
339 Append_To (New_Params, Relocate_Node (Param));
341 -- Now we need to generate the Tag check
344 -- Generate code for tag equality check
345 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
347 Insert_Action (Ctrl_Arg,
348 Make_Implicit_If_Statement (Call_Node,
352 Make_Selected_Component (Loc,
353 Prefix => New_Value (Ctrl_Arg),
356 (First_Tag_Component (Typ), Loc)),
359 Make_Selected_Component (Loc,
361 Unchecked_Convert_To (Typ, New_Value (Param)),
364 (First_Tag_Component (Typ), Loc))),
367 New_List (New_Constraint_Error (Loc))));
369 Append_To (New_Params, Relocate_Node (Param));
376 -- Generate the appropriate subprogram pointer type
378 if Etype (Subp) = Typ then
381 Res_Typ := Etype (Subp);
384 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
385 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
386 Set_Etype (Subp_Typ, Res_Typ);
387 Init_Size_Align (Subp_Ptr_Typ);
388 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
390 -- Create a new list of parameters which is a copy of the old formal
391 -- list including the creation of a new set of matching entities.
394 Old_Formal : Entity_Id := First_Formal (Subp);
395 New_Formal : Entity_Id;
396 Extra : Entity_Id := Empty;
399 if Present (Old_Formal) then
400 New_Formal := New_Copy (Old_Formal);
401 Set_First_Entity (Subp_Typ, New_Formal);
402 Param := First_Actual (Call_Node);
405 Set_Scope (New_Formal, Subp_Typ);
407 -- Change all the controlling argument types to be class-wide
408 -- to avoid a recursion in dispatching.
410 if Is_Controlling_Formal (New_Formal) then
411 Set_Etype (New_Formal, Etype (Param));
414 if Is_Itype (Etype (New_Formal)) then
415 Extra := New_Copy (Etype (New_Formal));
417 if Ekind (Extra) = E_Record_Subtype
418 or else Ekind (Extra) = E_Class_Wide_Subtype
420 Set_Cloned_Subtype (Extra, Etype (New_Formal));
423 Set_Etype (New_Formal, Extra);
424 Set_Scope (Etype (New_Formal), Subp_Typ);
428 Next_Formal (Old_Formal);
429 exit when No (Old_Formal);
431 Set_Next_Entity (New_Formal, New_Copy (Old_Formal));
432 Next_Entity (New_Formal);
436 Set_Next_Entity (New_Formal, Empty);
437 Set_Last_Entity (Subp_Typ, Extra);
440 -- Now that the explicit formals have been duplicated, any extra
441 -- formals needed by the subprogram must be created.
443 if Present (Extra) then
444 Set_Extra_Formal (Extra, Empty);
447 Create_Extra_Formals (Subp_Typ);
450 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
451 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
453 -- If the controlling argument is a value of type Ada.Tag or an abstract
454 -- interface class-wide type then use it directly. Otherwise, the tag
455 -- must be extracted from the controlling object.
457 if Etype (Ctrl_Arg) = RTE (RE_Tag)
458 or else (RTE_Available (RE_Interface_Tag)
459 and then Etype (Ctrl_Arg) = RTE (RE_Interface_Tag))
461 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
463 -- Extract the tag from an unchecked type conversion. Done to avoid
464 -- the expansion of additional code just to obtain the value of such
465 -- tag because the current management of interface type conversions
466 -- generates in some cases this unchecked type conversion with the
467 -- tag of the object (see Expand_Interface_Conversion).
469 elsif Nkind (Ctrl_Arg) = N_Unchecked_Type_Conversion
471 (Etype (Expression (Ctrl_Arg)) = RTE (RE_Tag)
473 (RTE_Available (RE_Interface_Tag)
475 Etype (Expression (Ctrl_Arg)) = RTE (RE_Interface_Tag)))
477 Controlling_Tag := Duplicate_Subexpr (Expression (Ctrl_Arg));
479 -- Ada 2005 (AI-251): Abstract interface class-wide type
481 elsif Is_Interface (Etype (Ctrl_Arg))
482 and then Is_Class_Wide_Type (Etype (Ctrl_Arg))
484 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
488 Make_Selected_Component (Loc,
489 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
490 Selector_Name => New_Reference_To (DTC_Entity (Subp), Loc));
493 -- Handle dispatching calls to predefined primitives
495 if Is_Predefined_Dispatching_Operation (Subp)
496 or else Is_Predefined_Dispatching_Alias (Subp)
499 Unchecked_Convert_To (Subp_Ptr_Typ,
500 Build_Get_Predefined_Prim_Op_Address (Loc,
501 Tag_Node => Controlling_Tag,
502 Position => DT_Position (Subp)));
504 -- Handle dispatching calls to user-defined primitives
508 Unchecked_Convert_To (Subp_Ptr_Typ,
509 Build_Get_Prim_Op_Address (Loc,
510 Typ => Find_Dispatching_Type (Subp),
511 Tag_Node => Controlling_Tag,
512 Position => DT_Position (Subp)));
515 if Nkind (Call_Node) = N_Function_Call then
518 Make_Function_Call (Loc,
519 Name => New_Call_Name,
520 Parameter_Associations => New_Params);
522 -- If this is a dispatching "=", we must first compare the tags so
523 -- we generate: x.tag = y.tag and then x = y
525 if Subp = Eq_Prim_Op then
526 Param := First_Actual (Call_Node);
532 Make_Selected_Component (Loc,
533 Prefix => New_Value (Param),
535 New_Reference_To (First_Tag_Component (Typ),
539 Make_Selected_Component (Loc,
541 Unchecked_Convert_To (Typ,
542 New_Value (Next_Actual (Param))),
544 New_Reference_To (First_Tag_Component (Typ),
546 Right_Opnd => New_Call);
551 Make_Procedure_Call_Statement (Loc,
552 Name => New_Call_Name,
553 Parameter_Associations => New_Params);
556 Rewrite (Call_Node, New_Call);
558 -- Suppress all checks during the analysis of the expanded code
559 -- to avoid the generation of spureous warnings under ZFP run-time.
561 Analyze_And_Resolve (Call_Node, Call_Typ, Suppress => All_Checks);
562 end Expand_Dispatching_Call;
564 ---------------------------------
565 -- Expand_Interface_Conversion --
566 ---------------------------------
568 procedure Expand_Interface_Conversion
570 Is_Static : Boolean := True)
572 Loc : constant Source_Ptr := Sloc (N);
573 Etyp : constant Entity_Id := Etype (N);
574 Operand : constant Node_Id := Expression (N);
575 Operand_Typ : Entity_Id := Etype (Operand);
578 Iface_Typ : Entity_Id := Etype (N);
579 Iface_Tag : Entity_Id;
580 New_Itype : Entity_Id;
584 -- Ada 2005 (AI-345): Handle synchronized interface type derivations
586 if Is_Concurrent_Type (Operand_Typ) then
587 Operand_Typ := Base_Type (Corresponding_Record_Type (Operand_Typ));
590 -- Handle access types to interfaces
592 if Is_Access_Type (Iface_Typ) then
593 Iface_Typ := Etype (Directly_Designated_Type (Iface_Typ));
596 -- Handle class-wide interface types. This conversion can appear
597 -- explicitly in the source code. Example: I'Class (Obj)
599 if Is_Class_Wide_Type (Iface_Typ) then
600 Iface_Typ := Root_Type (Iface_Typ);
603 pragma Assert (not Is_Static
604 or else (not Is_Class_Wide_Type (Iface_Typ)
605 and then Is_Interface (Iface_Typ)));
607 if VM_Target /= No_VM then
609 -- For VM, just do a conversion ???
611 Rewrite (N, Unchecked_Convert_To (Etype (N), N));
616 if not Is_Static then
618 -- Give error if configurable run time and Displace not available
620 if not RTE_Available (RE_Displace) then
621 Error_Msg_CRT ("abstract interface types", N);
625 -- Handle conversion of access-to-class-wide interface types. Target
626 -- can be an access to an object or an access to another class-wide
627 -- interface (see -1- and -2- in the following example):
629 -- type Iface1_Ref is access all Iface1'Class;
630 -- type Iface2_Ref is access all Iface1'Class;
632 -- Acc1 : Iface1_Ref := new ...
633 -- Obj : Obj_Ref := Obj_Ref (Acc); -- 1
634 -- Acc2 : Iface2_Ref := Iface2_Ref (Acc); -- 2
636 if Is_Access_Type (Operand_Typ) then
638 (Is_Interface (Directly_Designated_Type (Operand_Typ)));
641 Unchecked_Convert_To (Etype (N),
642 Make_Function_Call (Loc,
643 Name => New_Reference_To (RTE (RE_Displace), Loc),
644 Parameter_Associations => New_List (
646 Unchecked_Convert_To (RTE (RE_Address),
647 Relocate_Node (Expression (N))),
650 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
658 Make_Function_Call (Loc,
659 Name => New_Reference_To (RTE (RE_Displace), Loc),
660 Parameter_Associations => New_List (
661 Make_Attribute_Reference (Loc,
662 Prefix => Relocate_Node (Expression (N)),
663 Attribute_Name => Name_Address),
666 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
671 -- If the target is a class-wide interface we change the type of the
672 -- data returned by IW_Convert to indicate that this is a dispatching
675 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
676 Set_Etype (New_Itype, New_Itype);
677 Init_Esize (New_Itype);
678 Init_Size_Align (New_Itype);
679 Set_Directly_Designated_Type (New_Itype, Etyp);
681 Rewrite (N, Make_Explicit_Dereference (Loc,
682 Unchecked_Convert_To (New_Itype,
683 Relocate_Node (N))));
685 Freeze_Itype (New_Itype, N);
690 Iface_Tag := Find_Interface_Tag (Operand_Typ, Iface_Typ);
691 pragma Assert (Iface_Tag /= Empty);
693 -- Keep separate access types to interfaces because one internal
694 -- function is used to handle the null value (see following comment)
696 if not Is_Access_Type (Etype (N)) then
698 Unchecked_Convert_To (Etype (N),
699 Make_Selected_Component (Loc,
700 Prefix => Relocate_Node (Expression (N)),
702 New_Occurrence_Of (Iface_Tag, Loc))));
705 -- Build internal function to handle the case in which the
706 -- actual is null. If the actual is null returns null because
707 -- no displacement is required; otherwise performs a type
708 -- conversion that will be expanded in the code that returns
709 -- the value of the displaced actual. That is:
711 -- function Func (O : Address) return Iface_Typ is
713 -- if O = Null_Address then
716 -- return Iface_Typ!(Operand_Typ!(O).Iface_Tag'Address);
720 Fent := Make_Defining_Identifier (Loc, New_Internal_Name ('F'));
723 Desig_Typ : Entity_Id;
725 Desig_Typ := Etype (Expression (N));
727 if Is_Access_Type (Desig_Typ) then
728 Desig_Typ := Directly_Designated_Type (Desig_Typ);
731 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
732 Set_Etype (New_Itype, New_Itype);
733 Set_Scope (New_Itype, Fent);
734 Init_Size_Align (New_Itype);
735 Set_Directly_Designated_Type (New_Itype, Desig_Typ);
739 Make_Return_Statement (Loc,
740 Unchecked_Convert_To (Etype (N),
741 Make_Attribute_Reference (Loc,
743 Make_Selected_Component (Loc,
744 Prefix => Unchecked_Convert_To (New_Itype,
745 Make_Identifier (Loc, Name_uO)),
747 New_Occurrence_Of (Iface_Tag, Loc)),
748 Attribute_Name => Name_Address))));
750 -- If the type is null-excluding, no need for the null branch.
751 -- Otherwise we need to check for it and return null.
753 if not Can_Never_Be_Null (Etype (N)) then
755 Make_If_Statement (Loc,
758 Left_Opnd => Make_Identifier (Loc, Name_uO),
759 Right_Opnd => New_Reference_To
760 (RTE (RE_Null_Address), Loc)),
762 Then_Statements => New_List (
763 Make_Return_Statement (Loc,
765 Else_Statements => Stats));
769 Make_Subprogram_Body (Loc,
771 Make_Function_Specification (Loc,
772 Defining_Unit_Name => Fent,
774 Parameter_Specifications => New_List (
775 Make_Parameter_Specification (Loc,
776 Defining_Identifier =>
777 Make_Defining_Identifier (Loc, Name_uO),
779 New_Reference_To (RTE (RE_Address), Loc))),
782 New_Reference_To (Etype (N), Loc)),
784 Declarations => Empty_List,
786 Handled_Statement_Sequence =>
787 Make_Handled_Sequence_Of_Statements (Loc, Stats));
789 -- Place function body before the expression containing the
790 -- conversion. We suppress all checks because the body of the
791 -- internally generated function already takes care of the case
792 -- in which the actual is null; therefore there is no need to
793 -- double check that the pointer is not null when the program
794 -- executes the alternative that performs the type conversion).
796 Insert_Action (N, Func, Suppress => All_Checks);
798 if Is_Access_Type (Etype (Expression (N))) then
800 -- Generate: Operand_Typ!(Expression.all)'Address
803 Make_Function_Call (Loc,
804 Name => New_Reference_To (Fent, Loc),
805 Parameter_Associations => New_List (
806 Make_Attribute_Reference (Loc,
807 Prefix => Unchecked_Convert_To (Operand_Typ,
808 Make_Explicit_Dereference (Loc,
809 Relocate_Node (Expression (N)))),
810 Attribute_Name => Name_Address))));
813 -- Generate: Operand_Typ!(Expression)'Address
816 Make_Function_Call (Loc,
817 Name => New_Reference_To (Fent, Loc),
818 Parameter_Associations => New_List (
819 Make_Attribute_Reference (Loc,
820 Prefix => Unchecked_Convert_To (Operand_Typ,
821 Relocate_Node (Expression (N))),
822 Attribute_Name => Name_Address))));
827 end Expand_Interface_Conversion;
829 ------------------------------
830 -- Expand_Interface_Actuals --
831 ------------------------------
833 procedure Expand_Interface_Actuals (Call_Node : Node_Id) is
834 Loc : constant Source_Ptr := Sloc (Call_Node);
836 Actual_Dup : Node_Id;
837 Actual_Typ : Entity_Id;
839 Conversion : Node_Id;
841 Formal_Typ : Entity_Id;
844 Formal_DDT : Entity_Id;
845 Actual_DDT : Entity_Id;
848 -- This subprogram is called directly from the semantics, so we need a
849 -- check to see whether expansion is active before proceeding.
851 if not Expander_Active then
855 -- Call using access to subprogram with explicit dereference
857 if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
858 Subp := Etype (Name (Call_Node));
863 Subp := Entity (Name (Call_Node));
866 -- Ada 2005 (AI-251): Look for interface type formals to force "this"
869 Formal := First_Formal (Subp);
870 Actual := First_Actual (Call_Node);
871 while Present (Formal) loop
872 Formal_Typ := Etype (Formal);
874 if Ekind (Formal_Typ) = E_Record_Type_With_Private then
875 Formal_Typ := Full_View (Formal_Typ);
878 if Is_Access_Type (Formal_Typ) then
879 Formal_DDT := Directly_Designated_Type (Formal_Typ);
882 Actual_Typ := Etype (Actual);
884 if Is_Access_Type (Actual_Typ) then
885 Actual_DDT := Directly_Designated_Type (Actual_Typ);
888 if Is_Interface (Formal_Typ)
889 and then Is_Class_Wide_Type (Formal_Typ)
891 -- No need to displace the pointer if the type of the actual
892 -- coindices with the type of the formal.
894 if Actual_Typ = Formal_Typ then
897 -- No need to displace the pointer if the interface type is
898 -- a parent of the type of the actual because in this case the
899 -- interface primitives are located in the primary dispatch table.
901 elsif Is_Parent (Formal_Typ, Actual_Typ) then
904 -- Implicit conversion to the class-wide formal type to force
905 -- the displacement of the pointer.
908 Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
909 Rewrite (Actual, Conversion);
910 Analyze_And_Resolve (Actual, Formal_Typ);
913 -- Access to class-wide interface type
915 elsif Is_Access_Type (Formal_Typ)
916 and then Is_Interface (Formal_DDT)
917 and then Is_Class_Wide_Type (Formal_DDT)
918 and then Interface_Present_In_Ancestor
920 Iface => Etype (Formal_DDT))
922 -- Handle attributes 'Access and 'Unchecked_Access
924 if Nkind (Actual) = N_Attribute_Reference
926 (Attribute_Name (Actual) = Name_Access
927 or else Attribute_Name (Actual) = Name_Unchecked_Access)
929 Nam := Attribute_Name (Actual);
931 Conversion := Convert_To (Formal_DDT, Prefix (Actual));
932 Rewrite (Actual, Conversion);
933 Analyze_And_Resolve (Actual, Formal_DDT);
936 Unchecked_Convert_To (Formal_Typ,
937 Make_Attribute_Reference (Loc,
938 Prefix => Relocate_Node (Actual),
939 Attribute_Name => Nam)));
940 Analyze_And_Resolve (Actual, Formal_Typ);
942 -- No need to displace the pointer if the type of the actual
943 -- coincides with the type of the formal.
945 elsif Actual_DDT = Formal_DDT then
948 -- No need to displace the pointer if the interface type is
949 -- a parent of the type of the actual because in this case the
950 -- interface primitives are located in the primary dispatch table.
952 elsif Is_Parent (Formal_DDT, Actual_DDT) then
956 Actual_Dup := Relocate_Node (Actual);
958 if From_With_Type (Actual_Typ) then
960 -- If the type of the actual parameter comes from a limited
961 -- with-clause and the non-limited view is already available
962 -- we replace the anonymous access type by a duplicate decla
963 -- ration whose designated type is the non-limited view
965 if Ekind (Actual_DDT) = E_Incomplete_Type
966 and then Present (Non_Limited_View (Actual_DDT))
968 Anon := New_Copy (Actual_Typ);
970 if Is_Itype (Anon) then
971 Set_Scope (Anon, Current_Scope);
974 Set_Directly_Designated_Type (Anon,
975 Non_Limited_View (Actual_DDT));
976 Set_Etype (Actual_Dup, Anon);
978 elsif Is_Class_Wide_Type (Actual_DDT)
979 and then Ekind (Etype (Actual_DDT)) = E_Incomplete_Type
980 and then Present (Non_Limited_View (Etype (Actual_DDT)))
982 Anon := New_Copy (Actual_Typ);
984 if Is_Itype (Anon) then
985 Set_Scope (Anon, Current_Scope);
988 Set_Directly_Designated_Type (Anon,
989 New_Copy (Actual_DDT));
990 Set_Class_Wide_Type (Directly_Designated_Type (Anon),
991 New_Copy (Class_Wide_Type (Actual_DDT)));
992 Set_Etype (Directly_Designated_Type (Anon),
993 Non_Limited_View (Etype (Actual_DDT)));
995 Class_Wide_Type (Directly_Designated_Type (Anon)),
996 Non_Limited_View (Etype (Actual_DDT)));
997 Set_Etype (Actual_Dup, Anon);
1001 Conversion := Convert_To (Formal_Typ, Actual_Dup);
1002 Rewrite (Actual, Conversion);
1003 Analyze_And_Resolve (Actual, Formal_Typ);
1007 Next_Actual (Actual);
1008 Next_Formal (Formal);
1010 end Expand_Interface_Actuals;
1012 ----------------------------
1013 -- Expand_Interface_Thunk --
1014 ----------------------------
1016 procedure Expand_Interface_Thunk
1018 Thunk_Alias : Entity_Id;
1019 Thunk_Id : out Entity_Id;
1020 Thunk_Code : out Node_Id)
1022 Loc : constant Source_Ptr := Sloc (N);
1023 Actuals : constant List_Id := New_List;
1024 Decl : constant List_Id := New_List;
1025 Formals : constant List_Id := New_List;
1027 Controlling_Typ : Entity_Id;
1032 Target_Formal : Entity_Id;
1036 Thunk_Code := Empty;
1038 -- Give message if configurable run-time and Offset_To_Top unavailable
1040 if not RTE_Available (RE_Offset_To_Top) then
1041 Error_Msg_CRT ("abstract interface types", N);
1045 -- Traverse the list of alias to find the final target
1047 Target := Thunk_Alias;
1048 while Present (Alias (Target)) loop
1049 Target := Alias (Target);
1052 -- In case of primitives that are functions without formals and
1053 -- a controlling result there is no need to build the thunk.
1055 if not Present (First_Formal (Target)) then
1056 pragma Assert (Ekind (Target) = E_Function
1057 and then Has_Controlling_Result (Target));
1061 -- Duplicate the formals
1063 Formal := First_Formal (Target);
1064 while Present (Formal) loop
1066 Make_Parameter_Specification (Loc,
1067 Defining_Identifier =>
1068 Make_Defining_Identifier (Sloc (Formal),
1069 Chars => Chars (Formal)),
1070 In_Present => In_Present (Parent (Formal)),
1071 Out_Present => Out_Present (Parent (Formal)),
1073 New_Reference_To (Etype (Formal), Loc),
1074 Expression => New_Copy_Tree (Expression (Parent (Formal)))));
1076 Next_Formal (Formal);
1079 if Ekind (First_Formal (Target)) = E_In_Parameter
1080 and then Ekind (Etype (First_Formal (Target)))
1081 = E_Anonymous_Access_Type
1084 Directly_Designated_Type (Etype (First_Formal (Target)));
1086 Controlling_Typ := Etype (First_Formal (Target));
1089 Target_Formal := First_Formal (Target);
1090 Formal := First (Formals);
1091 while Present (Formal) loop
1092 if Ekind (Target_Formal) = E_In_Parameter
1093 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
1094 and then Directly_Designated_Type (Etype (Target_Formal))
1099 -- type T is access all <<type of the first formal>>
1100 -- S1 := Storage_Offset!(formal)
1101 -- - Offset_To_Top (Formal.Tag)
1103 -- ... and the first actual of the call is generated as T!(S1)
1106 Make_Full_Type_Declaration (Loc,
1107 Defining_Identifier =>
1108 Make_Defining_Identifier (Loc,
1109 New_Internal_Name ('T')),
1111 Make_Access_To_Object_Definition (Loc,
1112 All_Present => True,
1113 Null_Exclusion_Present => False,
1114 Constant_Present => False,
1115 Subtype_Indication =>
1117 (Directly_Designated_Type
1118 (Etype (Target_Formal)), Loc)));
1121 Make_Object_Declaration (Loc,
1122 Defining_Identifier =>
1123 Make_Defining_Identifier (Loc,
1124 New_Internal_Name ('S')),
1125 Constant_Present => True,
1126 Object_Definition =>
1127 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1129 Make_Op_Subtract (Loc,
1131 Unchecked_Convert_To
1132 (RTE (RE_Storage_Offset),
1133 New_Reference_To (Defining_Identifier (Formal), Loc)),
1135 Make_Function_Call (Loc,
1137 New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1138 Parameter_Associations => New_List (
1139 Unchecked_Convert_To
1142 (Defining_Identifier (Formal), Loc))))));
1144 Append_To (Decl, Decl_2);
1145 Append_To (Decl, Decl_1);
1147 -- Reference the new first actual
1150 Unchecked_Convert_To
1151 (Defining_Identifier (Decl_2),
1152 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1154 elsif Etype (Target_Formal) = Controlling_Typ then
1157 -- S1 := Storage_Offset!(Formal'Address)
1158 -- - Offset_To_Top (Formal.Tag)
1159 -- S2 := Tag_Ptr!(S3)
1162 Make_Object_Declaration (Loc,
1163 Defining_Identifier =>
1164 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1165 Constant_Present => True,
1166 Object_Definition =>
1167 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1169 Make_Op_Subtract (Loc,
1171 Unchecked_Convert_To
1172 (RTE (RE_Storage_Offset),
1173 Make_Attribute_Reference (Loc,
1176 (Defining_Identifier (Formal), Loc),
1177 Attribute_Name => Name_Address)),
1179 Make_Function_Call (Loc,
1181 New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1182 Parameter_Associations => New_List (
1183 Make_Attribute_Reference (Loc,
1186 (Defining_Identifier (Formal), Loc),
1187 Attribute_Name => Name_Address)))));
1190 Make_Object_Declaration (Loc,
1191 Defining_Identifier =>
1192 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1193 Constant_Present => True,
1194 Object_Definition => New_Reference_To (RTE (RE_Addr_Ptr), Loc),
1196 Unchecked_Convert_To
1198 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1200 Append_To (Decl, Decl_1);
1201 Append_To (Decl, Decl_2);
1203 -- Reference the new first actual
1206 Unchecked_Convert_To
1207 (Etype (First_Entity (Target)),
1208 Make_Explicit_Dereference (Loc,
1209 New_Reference_To (Defining_Identifier (Decl_2), Loc))));
1211 -- No special management required for this actual
1215 New_Reference_To (Defining_Identifier (Formal), Loc));
1218 Next_Formal (Target_Formal);
1223 Make_Defining_Identifier (Loc,
1224 Chars => New_Internal_Name ('T'));
1226 if Ekind (Target) = E_Procedure then
1228 Make_Subprogram_Body (Loc,
1230 Make_Procedure_Specification (Loc,
1231 Defining_Unit_Name => Thunk_Id,
1232 Parameter_Specifications => Formals),
1233 Declarations => Decl,
1234 Handled_Statement_Sequence =>
1235 Make_Handled_Sequence_Of_Statements (Loc,
1236 Statements => New_List (
1237 Make_Procedure_Call_Statement (Loc,
1238 Name => New_Occurrence_Of (Target, Loc),
1239 Parameter_Associations => Actuals))));
1241 else pragma Assert (Ekind (Target) = E_Function);
1244 Make_Subprogram_Body (Loc,
1246 Make_Function_Specification (Loc,
1247 Defining_Unit_Name => Thunk_Id,
1248 Parameter_Specifications => Formals,
1249 Result_Definition =>
1250 New_Copy (Result_Definition (Parent (Target)))),
1251 Declarations => Decl,
1252 Handled_Statement_Sequence =>
1253 Make_Handled_Sequence_Of_Statements (Loc,
1254 Statements => New_List (
1255 Make_Return_Statement (Loc,
1256 Make_Function_Call (Loc,
1257 Name => New_Occurrence_Of (Target, Loc),
1258 Parameter_Associations => Actuals)))));
1260 end Expand_Interface_Thunk;
1262 -------------------------------------
1263 -- Is_Predefined_Dispatching_Alias --
1264 -------------------------------------
1266 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
1271 if not Is_Predefined_Dispatching_Operation (Prim)
1272 and then Present (Alias (Prim))
1275 while Present (Alias (E)) loop
1279 if Is_Predefined_Dispatching_Operation (E) then
1285 end Is_Predefined_Dispatching_Alias;
1287 ----------------------------------------
1288 -- Make_Disp_Asynchronous_Select_Body --
1289 ----------------------------------------
1291 function Make_Disp_Asynchronous_Select_Body
1292 (Typ : Entity_Id) return Node_Id
1294 Com_Block : Entity_Id;
1295 Conc_Typ : Entity_Id := Empty;
1296 Decls : constant List_Id := New_List;
1298 Loc : constant Source_Ptr := Sloc (Typ);
1299 Stmts : constant List_Id := New_List;
1302 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1304 -- Null body is generated for interface types
1306 if Is_Interface (Typ) then
1308 Make_Subprogram_Body (Loc,
1310 Make_Disp_Asynchronous_Select_Spec (Typ),
1313 Handled_Statement_Sequence =>
1314 Make_Handled_Sequence_Of_Statements (Loc,
1315 New_List (Make_Null_Statement (Loc))));
1318 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1320 if Is_Concurrent_Record_Type (Typ) then
1321 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1324 -- I : Integer := Get_Entry_Index (tag! (<type>VP), S);
1326 -- where I will be used to capture the entry index of the primitive
1327 -- wrapper at position S.
1330 Make_Object_Declaration (Loc,
1331 Defining_Identifier =>
1332 Make_Defining_Identifier (Loc, Name_uI),
1333 Object_Definition =>
1334 New_Reference_To (Standard_Integer, Loc),
1336 Make_Function_Call (Loc,
1337 Name => New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
1338 Parameter_Associations => New_List (
1339 Unchecked_Convert_To (RTE (RE_Tag),
1340 New_Reference_To (DT_Ptr, Loc)),
1341 Make_Identifier (Loc, Name_uS)))));
1343 if Ekind (Conc_Typ) = E_Protected_Type then
1346 -- Com_Block : Communication_Block;
1349 Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1352 Make_Object_Declaration (Loc,
1353 Defining_Identifier =>
1355 Object_Definition =>
1356 New_Reference_To (RTE (RE_Communication_Block), Loc)));
1359 -- Protected_Entry_Call (
1360 -- T._object'access,
1361 -- protected_entry_index! (I),
1363 -- Asynchronous_Call,
1366 -- where T is the protected object, I is the entry index, P are
1367 -- the wrapped parameters and B is the name of the communication
1371 Make_Procedure_Call_Statement (Loc,
1373 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1374 Parameter_Associations =>
1377 Make_Attribute_Reference (Loc, -- T._object'access
1379 Name_Unchecked_Access,
1381 Make_Selected_Component (Loc,
1383 Make_Identifier (Loc, Name_uT),
1385 Make_Identifier (Loc, Name_uObject))),
1387 Make_Unchecked_Type_Conversion (Loc, -- entry index
1389 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
1391 Make_Identifier (Loc, Name_uI)),
1393 Make_Identifier (Loc, Name_uP), -- parameter block
1394 New_Reference_To ( -- Asynchronous_Call
1395 RTE (RE_Asynchronous_Call), Loc),
1397 New_Reference_To (Com_Block, Loc)))); -- comm block
1400 -- B := Dummy_Communication_Bloc (Com_Block);
1403 Make_Assignment_Statement (Loc,
1405 Make_Identifier (Loc, Name_uB),
1407 Make_Unchecked_Type_Conversion (Loc,
1410 RTE (RE_Dummy_Communication_Block), Loc),
1412 New_Reference_To (Com_Block, Loc))));
1415 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
1418 -- Protected_Entry_Call (
1420 -- task_entry_index! (I),
1422 -- Conditional_Call,
1425 -- where T is the task object, I is the entry index, P are the
1426 -- wrapped parameters and F is the status flag.
1429 Make_Procedure_Call_Statement (Loc,
1431 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
1432 Parameter_Associations =>
1435 Make_Selected_Component (Loc, -- T._task_id
1437 Make_Identifier (Loc, Name_uT),
1439 Make_Identifier (Loc, Name_uTask_Id)),
1441 Make_Unchecked_Type_Conversion (Loc, -- entry index
1443 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
1445 Make_Identifier (Loc, Name_uI)),
1447 Make_Identifier (Loc, Name_uP), -- parameter block
1448 New_Reference_To ( -- Asynchronous_Call
1449 RTE (RE_Asynchronous_Call), Loc),
1450 Make_Identifier (Loc, Name_uF)))); -- status flag
1455 Make_Subprogram_Body (Loc,
1457 Make_Disp_Asynchronous_Select_Spec (Typ),
1460 Handled_Statement_Sequence =>
1461 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
1462 end Make_Disp_Asynchronous_Select_Body;
1464 ----------------------------------------
1465 -- Make_Disp_Asynchronous_Select_Spec --
1466 ----------------------------------------
1468 function Make_Disp_Asynchronous_Select_Spec
1469 (Typ : Entity_Id) return Node_Id
1471 Loc : constant Source_Ptr := Sloc (Typ);
1472 Def_Id : constant Node_Id :=
1473 Make_Defining_Identifier (Loc,
1474 Name_uDisp_Asynchronous_Select);
1475 Params : constant List_Id := New_List;
1478 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1480 -- T : in out Typ; -- Object parameter
1481 -- S : Integer; -- Primitive operation slot
1482 -- P : Address; -- Wrapped parameters
1483 -- B : out Dummy_Communication_Block; -- Communication block dummy
1484 -- F : out Boolean; -- Status flag
1486 Append_List_To (Params, New_List (
1488 Make_Parameter_Specification (Loc,
1489 Defining_Identifier =>
1490 Make_Defining_Identifier (Loc, Name_uT),
1492 New_Reference_To (Typ, Loc),
1494 Out_Present => True),
1496 Make_Parameter_Specification (Loc,
1497 Defining_Identifier =>
1498 Make_Defining_Identifier (Loc, Name_uS),
1500 New_Reference_To (Standard_Integer, Loc)),
1502 Make_Parameter_Specification (Loc,
1503 Defining_Identifier =>
1504 Make_Defining_Identifier (Loc, Name_uP),
1506 New_Reference_To (RTE (RE_Address), Loc)),
1508 Make_Parameter_Specification (Loc,
1509 Defining_Identifier =>
1510 Make_Defining_Identifier (Loc, Name_uB),
1512 New_Reference_To (RTE (RE_Dummy_Communication_Block), Loc),
1513 Out_Present => True),
1515 Make_Parameter_Specification (Loc,
1516 Defining_Identifier =>
1517 Make_Defining_Identifier (Loc, Name_uF),
1519 New_Reference_To (Standard_Boolean, Loc),
1520 Out_Present => True)));
1523 Make_Procedure_Specification (Loc,
1524 Defining_Unit_Name => Def_Id,
1525 Parameter_Specifications => Params);
1526 end Make_Disp_Asynchronous_Select_Spec;
1528 ---------------------------------------
1529 -- Make_Disp_Conditional_Select_Body --
1530 ---------------------------------------
1532 function Make_Disp_Conditional_Select_Body
1533 (Typ : Entity_Id) return Node_Id
1535 Loc : constant Source_Ptr := Sloc (Typ);
1536 Blk_Nam : Entity_Id;
1537 Conc_Typ : Entity_Id := Empty;
1538 Decls : constant List_Id := New_List;
1540 Stmts : constant List_Id := New_List;
1543 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1545 -- Null body is generated for interface types
1547 if Is_Interface (Typ) then
1549 Make_Subprogram_Body (Loc,
1551 Make_Disp_Conditional_Select_Spec (Typ),
1554 Handled_Statement_Sequence =>
1555 Make_Handled_Sequence_Of_Statements (Loc,
1556 New_List (Make_Null_Statement (Loc))));
1559 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1561 if Is_Concurrent_Record_Type (Typ) then
1562 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1567 -- where I will be used to capture the entry index of the primitive
1568 -- wrapper at position S.
1571 Make_Object_Declaration (Loc,
1572 Defining_Identifier =>
1573 Make_Defining_Identifier (Loc, Name_uI),
1574 Object_Definition =>
1575 New_Reference_To (Standard_Integer, Loc)));
1578 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
1580 -- if C = POK_Procedure
1581 -- or else C = POK_Protected_Procedure
1582 -- or else C = POK_Task_Procedure;
1588 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
1591 -- Bnn : Communication_Block;
1593 -- where Bnn is the name of the communication block used in
1594 -- the call to Protected_Entry_Call.
1596 Blk_Nam := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1599 Make_Object_Declaration (Loc,
1600 Defining_Identifier =>
1602 Object_Definition =>
1603 New_Reference_To (RTE (RE_Communication_Block), Loc)));
1606 -- I := Get_Entry_Index (tag! (<type>VP), S);
1608 -- I is the entry index and S is the dispatch table slot
1611 Make_Assignment_Statement (Loc,
1613 Make_Identifier (Loc, Name_uI),
1615 Make_Function_Call (Loc,
1616 Name => New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
1617 Parameter_Associations => New_List (
1618 Unchecked_Convert_To (RTE (RE_Tag),
1619 New_Reference_To (DT_Ptr, Loc)),
1620 Make_Identifier (Loc, Name_uS)))));
1622 if Ekind (Conc_Typ) = E_Protected_Type then
1625 -- Protected_Entry_Call (
1626 -- T._object'access,
1627 -- protected_entry_index! (I),
1629 -- Conditional_Call,
1632 -- where T is the protected object, I is the entry index, P are
1633 -- the wrapped parameters and Bnn is the name of the communication
1637 Make_Procedure_Call_Statement (Loc,
1639 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1640 Parameter_Associations =>
1643 Make_Attribute_Reference (Loc, -- T._object'access
1645 Name_Unchecked_Access,
1647 Make_Selected_Component (Loc,
1649 Make_Identifier (Loc, Name_uT),
1651 Make_Identifier (Loc, Name_uObject))),
1653 Make_Unchecked_Type_Conversion (Loc, -- entry index
1655 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
1657 Make_Identifier (Loc, Name_uI)),
1659 Make_Identifier (Loc, Name_uP), -- parameter block
1660 New_Reference_To ( -- Conditional_Call
1661 RTE (RE_Conditional_Call), Loc),
1662 New_Reference_To ( -- Bnn
1666 -- F := not Cancelled (Bnn);
1668 -- where F is the success flag. The status of Cancelled is negated
1669 -- in order to match the behaviour of the version for task types.
1672 Make_Assignment_Statement (Loc,
1674 Make_Identifier (Loc, Name_uF),
1678 Make_Function_Call (Loc,
1680 New_Reference_To (RTE (RE_Cancelled), Loc),
1681 Parameter_Associations =>
1683 New_Reference_To (Blk_Nam, Loc))))));
1685 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
1688 -- Protected_Entry_Call (
1690 -- task_entry_index! (I),
1692 -- Conditional_Call,
1695 -- where T is the task object, I is the entry index, P are the
1696 -- wrapped parameters and F is the status flag.
1699 Make_Procedure_Call_Statement (Loc,
1701 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
1702 Parameter_Associations =>
1705 Make_Selected_Component (Loc, -- T._task_id
1707 Make_Identifier (Loc, Name_uT),
1709 Make_Identifier (Loc, Name_uTask_Id)),
1711 Make_Unchecked_Type_Conversion (Loc, -- entry index
1713 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
1715 Make_Identifier (Loc, Name_uI)),
1717 Make_Identifier (Loc, Name_uP), -- parameter block
1718 New_Reference_To ( -- Conditional_Call
1719 RTE (RE_Conditional_Call), Loc),
1720 Make_Identifier (Loc, Name_uF)))); -- status flag
1725 Make_Subprogram_Body (Loc,
1727 Make_Disp_Conditional_Select_Spec (Typ),
1730 Handled_Statement_Sequence =>
1731 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
1732 end Make_Disp_Conditional_Select_Body;
1734 ---------------------------------------
1735 -- Make_Disp_Conditional_Select_Spec --
1736 ---------------------------------------
1738 function Make_Disp_Conditional_Select_Spec
1739 (Typ : Entity_Id) return Node_Id
1741 Loc : constant Source_Ptr := Sloc (Typ);
1742 Def_Id : constant Node_Id :=
1743 Make_Defining_Identifier (Loc,
1744 Name_uDisp_Conditional_Select);
1745 Params : constant List_Id := New_List;
1748 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1750 -- T : in out Typ; -- Object parameter
1751 -- S : Integer; -- Primitive operation slot
1752 -- P : Address; -- Wrapped parameters
1753 -- C : out Prim_Op_Kind; -- Call kind
1754 -- F : out Boolean; -- Status flag
1756 Append_List_To (Params, New_List (
1758 Make_Parameter_Specification (Loc,
1759 Defining_Identifier =>
1760 Make_Defining_Identifier (Loc, Name_uT),
1762 New_Reference_To (Typ, Loc),
1764 Out_Present => True),
1766 Make_Parameter_Specification (Loc,
1767 Defining_Identifier =>
1768 Make_Defining_Identifier (Loc, Name_uS),
1770 New_Reference_To (Standard_Integer, Loc)),
1772 Make_Parameter_Specification (Loc,
1773 Defining_Identifier =>
1774 Make_Defining_Identifier (Loc, Name_uP),
1776 New_Reference_To (RTE (RE_Address), Loc)),
1778 Make_Parameter_Specification (Loc,
1779 Defining_Identifier =>
1780 Make_Defining_Identifier (Loc, Name_uC),
1782 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
1783 Out_Present => True),
1785 Make_Parameter_Specification (Loc,
1786 Defining_Identifier =>
1787 Make_Defining_Identifier (Loc, Name_uF),
1789 New_Reference_To (Standard_Boolean, Loc),
1790 Out_Present => True)));
1793 Make_Procedure_Specification (Loc,
1794 Defining_Unit_Name => Def_Id,
1795 Parameter_Specifications => Params);
1796 end Make_Disp_Conditional_Select_Spec;
1798 -------------------------------------
1799 -- Make_Disp_Get_Prim_Op_Kind_Body --
1800 -------------------------------------
1802 function Make_Disp_Get_Prim_Op_Kind_Body
1803 (Typ : Entity_Id) return Node_Id
1805 Loc : constant Source_Ptr := Sloc (Typ);
1809 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1811 if Is_Interface (Typ) then
1813 Make_Subprogram_Body (Loc,
1815 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
1818 Handled_Statement_Sequence =>
1819 Make_Handled_Sequence_Of_Statements (Loc,
1820 New_List (Make_Null_Statement (Loc))));
1823 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1826 -- C := get_prim_op_kind (tag! (<type>VP), S);
1828 -- where C is the out parameter capturing the call kind and S is the
1829 -- dispatch table slot number.
1832 Make_Subprogram_Body (Loc,
1834 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
1837 Handled_Statement_Sequence =>
1838 Make_Handled_Sequence_Of_Statements (Loc,
1840 Make_Assignment_Statement (Loc,
1842 Make_Identifier (Loc, Name_uC),
1844 Make_Function_Call (Loc,
1846 New_Reference_To (RTE (RE_Get_Prim_Op_Kind), Loc),
1847 Parameter_Associations => New_List (
1848 Unchecked_Convert_To (RTE (RE_Tag),
1849 New_Reference_To (DT_Ptr, Loc)),
1850 Make_Identifier (Loc, Name_uS)))))));
1851 end Make_Disp_Get_Prim_Op_Kind_Body;
1853 -------------------------------------
1854 -- Make_Disp_Get_Prim_Op_Kind_Spec --
1855 -------------------------------------
1857 function Make_Disp_Get_Prim_Op_Kind_Spec
1858 (Typ : Entity_Id) return Node_Id
1860 Loc : constant Source_Ptr := Sloc (Typ);
1861 Def_Id : constant Node_Id :=
1862 Make_Defining_Identifier (Loc,
1863 Name_uDisp_Get_Prim_Op_Kind);
1864 Params : constant List_Id := New_List;
1867 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1869 -- T : in out Typ; -- Object parameter
1870 -- S : Integer; -- Primitive operation slot
1871 -- C : out Prim_Op_Kind; -- Call kind
1873 Append_List_To (Params, New_List (
1875 Make_Parameter_Specification (Loc,
1876 Defining_Identifier =>
1877 Make_Defining_Identifier (Loc, Name_uT),
1879 New_Reference_To (Typ, Loc),
1881 Out_Present => True),
1883 Make_Parameter_Specification (Loc,
1884 Defining_Identifier =>
1885 Make_Defining_Identifier (Loc, Name_uS),
1887 New_Reference_To (Standard_Integer, Loc)),
1889 Make_Parameter_Specification (Loc,
1890 Defining_Identifier =>
1891 Make_Defining_Identifier (Loc, Name_uC),
1893 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
1894 Out_Present => True)));
1897 Make_Procedure_Specification (Loc,
1898 Defining_Unit_Name => Def_Id,
1899 Parameter_Specifications => Params);
1900 end Make_Disp_Get_Prim_Op_Kind_Spec;
1902 --------------------------------
1903 -- Make_Disp_Get_Task_Id_Body --
1904 --------------------------------
1906 function Make_Disp_Get_Task_Id_Body
1907 (Typ : Entity_Id) return Node_Id
1909 Loc : constant Source_Ptr := Sloc (Typ);
1913 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1915 if Is_Concurrent_Record_Type (Typ)
1916 and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
1919 -- return To_Address (_T._task_id);
1922 Make_Return_Statement (Loc,
1924 Make_Unchecked_Type_Conversion (Loc,
1926 New_Reference_To (RTE (RE_Address), Loc),
1928 Make_Selected_Component (Loc,
1930 Make_Identifier (Loc, Name_uT),
1932 Make_Identifier (Loc, Name_uTask_Id))));
1934 -- A null body is constructed for non-task types
1938 -- return Null_Address;
1941 Make_Return_Statement (Loc,
1943 New_Reference_To (RTE (RE_Null_Address), Loc));
1947 Make_Subprogram_Body (Loc,
1949 Make_Disp_Get_Task_Id_Spec (Typ),
1952 Handled_Statement_Sequence =>
1953 Make_Handled_Sequence_Of_Statements (Loc,
1955 end Make_Disp_Get_Task_Id_Body;
1957 --------------------------------
1958 -- Make_Disp_Get_Task_Id_Spec --
1959 --------------------------------
1961 function Make_Disp_Get_Task_Id_Spec
1962 (Typ : Entity_Id) return Node_Id
1964 Loc : constant Source_Ptr := Sloc (Typ);
1967 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1970 Make_Function_Specification (Loc,
1971 Defining_Unit_Name =>
1972 Make_Defining_Identifier (Loc, Name_uDisp_Get_Task_Id),
1973 Parameter_Specifications => New_List (
1974 Make_Parameter_Specification (Loc,
1975 Defining_Identifier =>
1976 Make_Defining_Identifier (Loc, Name_uT),
1978 New_Reference_To (Typ, Loc))),
1979 Result_Definition =>
1980 New_Reference_To (RTE (RE_Address), Loc));
1981 end Make_Disp_Get_Task_Id_Spec;
1983 ---------------------------------
1984 -- Make_Disp_Timed_Select_Body --
1985 ---------------------------------
1987 function Make_Disp_Timed_Select_Body
1988 (Typ : Entity_Id) return Node_Id
1990 Loc : constant Source_Ptr := Sloc (Typ);
1991 Conc_Typ : Entity_Id := Empty;
1992 Decls : constant List_Id := New_List;
1994 Stmts : constant List_Id := New_List;
1997 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1999 -- Null body is generated for interface types
2001 if Is_Interface (Typ) then
2003 Make_Subprogram_Body (Loc,
2005 Make_Disp_Timed_Select_Spec (Typ),
2008 Handled_Statement_Sequence =>
2009 Make_Handled_Sequence_Of_Statements (Loc,
2010 New_List (Make_Null_Statement (Loc))));
2013 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2015 if Is_Concurrent_Record_Type (Typ) then
2016 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2021 -- where I will be used to capture the entry index of the primitive
2022 -- wrapper at position S.
2025 Make_Object_Declaration (Loc,
2026 Defining_Identifier =>
2027 Make_Defining_Identifier (Loc, Name_uI),
2028 Object_Definition =>
2029 New_Reference_To (Standard_Integer, Loc)));
2032 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
2034 -- if C = POK_Procedure
2035 -- or else C = POK_Protected_Procedure
2036 -- or else C = POK_Task_Procedure;
2042 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
2045 -- I := Get_Entry_Index (tag! (<type>VP), S);
2047 -- I is the entry index and S is the dispatch table slot
2050 Make_Assignment_Statement (Loc,
2052 Make_Identifier (Loc, Name_uI),
2054 Make_Function_Call (Loc,
2055 Name => New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
2056 Parameter_Associations => New_List (
2057 Unchecked_Convert_To (RTE (RE_Tag),
2058 New_Reference_To (DT_Ptr, Loc)),
2059 Make_Identifier (Loc, Name_uS)))));
2061 if Ekind (Conc_Typ) = E_Protected_Type then
2064 -- Timed_Protected_Entry_Call (
2065 -- T._object'access,
2066 -- protected_entry_index! (I),
2072 -- where T is the protected object, I is the entry index, P are
2073 -- the wrapped parameters, D is the delay amount, M is the delay
2074 -- mode and F is the status flag.
2077 Make_Procedure_Call_Statement (Loc,
2079 New_Reference_To (RTE (RE_Timed_Protected_Entry_Call), Loc),
2080 Parameter_Associations =>
2083 Make_Attribute_Reference (Loc, -- T._object'access
2085 Name_Unchecked_Access,
2087 Make_Selected_Component (Loc,
2089 Make_Identifier (Loc, Name_uT),
2091 Make_Identifier (Loc, Name_uObject))),
2093 Make_Unchecked_Type_Conversion (Loc, -- entry index
2095 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
2097 Make_Identifier (Loc, Name_uI)),
2099 Make_Identifier (Loc, Name_uP), -- parameter block
2100 Make_Identifier (Loc, Name_uD), -- delay
2101 Make_Identifier (Loc, Name_uM), -- delay mode
2102 Make_Identifier (Loc, Name_uF)))); -- status flag
2105 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2108 -- Timed_Task_Entry_Call (
2110 -- task_entry_index! (I),
2116 -- where T is the task object, I is the entry index, P are the
2117 -- wrapped parameters, D is the delay amount, M is the delay
2118 -- mode and F is the status flag.
2121 Make_Procedure_Call_Statement (Loc,
2123 New_Reference_To (RTE (RE_Timed_Task_Entry_Call), Loc),
2124 Parameter_Associations =>
2127 Make_Selected_Component (Loc, -- T._task_id
2129 Make_Identifier (Loc, Name_uT),
2131 Make_Identifier (Loc, Name_uTask_Id)),
2133 Make_Unchecked_Type_Conversion (Loc, -- entry index
2135 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2137 Make_Identifier (Loc, Name_uI)),
2139 Make_Identifier (Loc, Name_uP), -- parameter block
2140 Make_Identifier (Loc, Name_uD), -- delay
2141 Make_Identifier (Loc, Name_uM), -- delay mode
2142 Make_Identifier (Loc, Name_uF)))); -- status flag
2147 Make_Subprogram_Body (Loc,
2149 Make_Disp_Timed_Select_Spec (Typ),
2152 Handled_Statement_Sequence =>
2153 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2154 end Make_Disp_Timed_Select_Body;
2156 ---------------------------------
2157 -- Make_Disp_Timed_Select_Spec --
2158 ---------------------------------
2160 function Make_Disp_Timed_Select_Spec
2161 (Typ : Entity_Id) return Node_Id
2163 Loc : constant Source_Ptr := Sloc (Typ);
2164 Def_Id : constant Node_Id :=
2165 Make_Defining_Identifier (Loc,
2166 Name_uDisp_Timed_Select);
2167 Params : constant List_Id := New_List;
2170 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2172 -- T : in out Typ; -- Object parameter
2173 -- S : Integer; -- Primitive operation slot
2174 -- P : Address; -- Wrapped parameters
2175 -- D : Duration; -- Delay
2176 -- M : Integer; -- Delay Mode
2177 -- C : out Prim_Op_Kind; -- Call kind
2178 -- F : out Boolean; -- Status flag
2180 Append_List_To (Params, New_List (
2182 Make_Parameter_Specification (Loc,
2183 Defining_Identifier =>
2184 Make_Defining_Identifier (Loc, Name_uT),
2186 New_Reference_To (Typ, Loc),
2188 Out_Present => True),
2190 Make_Parameter_Specification (Loc,
2191 Defining_Identifier =>
2192 Make_Defining_Identifier (Loc, Name_uS),
2194 New_Reference_To (Standard_Integer, Loc)),
2196 Make_Parameter_Specification (Loc,
2197 Defining_Identifier =>
2198 Make_Defining_Identifier (Loc, Name_uP),
2200 New_Reference_To (RTE (RE_Address), Loc)),
2202 Make_Parameter_Specification (Loc,
2203 Defining_Identifier =>
2204 Make_Defining_Identifier (Loc, Name_uD),
2206 New_Reference_To (Standard_Duration, Loc)),
2208 Make_Parameter_Specification (Loc,
2209 Defining_Identifier =>
2210 Make_Defining_Identifier (Loc, Name_uM),
2212 New_Reference_To (Standard_Integer, Loc)),
2214 Make_Parameter_Specification (Loc,
2215 Defining_Identifier =>
2216 Make_Defining_Identifier (Loc, Name_uC),
2218 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2219 Out_Present => True)));
2222 Make_Parameter_Specification (Loc,
2223 Defining_Identifier =>
2224 Make_Defining_Identifier (Loc, Name_uF),
2226 New_Reference_To (Standard_Boolean, Loc),
2227 Out_Present => True));
2230 Make_Procedure_Specification (Loc,
2231 Defining_Unit_Name => Def_Id,
2232 Parameter_Specifications => Params);
2233 end Make_Disp_Timed_Select_Spec;
2239 -- The frontend supports two models for expanding dispatch tables
2240 -- associated with library-level defined tagged types: statically
2241 -- and non-statically allocated dispatch tables. In the former case
2242 -- the object containing the dispatch table is constant and it is
2243 -- initialized by means of a positional aggregate. In the latter case,
2244 -- the object containing the dispatch table is a variable which is
2245 -- initialized by means of assignments.
2247 -- In case of locally defined tagged types, the object containing the
2248 -- object containing the dispatch table is always a variable (instead
2249 -- of a constant). This is currently required to give support to late
2250 -- overriding of primitives. For example:
2252 -- procedure Example is
2254 -- type T1 is tagged null record;
2255 -- procedure Prim (O : T1);
2258 -- type T2 is new Pkg.T1 with null record;
2259 -- procedure Prim (X : T2) is -- late overriding
2265 function Make_DT (Typ : Entity_Id) return List_Id is
2266 Loc : constant Source_Ptr := Sloc (Typ);
2267 Is_Local_DT : constant Boolean :=
2268 Ekind (Cunit_Entity (Get_Source_Unit (Typ)))
2270 Max_Predef_Prims : constant Int :=
2274 (Parent (RTE (RE_Default_Prim_Op_Count)))));
2276 procedure Make_Secondary_DT
2280 Iface_DT_Ptr : Entity_Id;
2282 -- Ada 2005 (AI-251): Expand the declarations for the Secondary Dispatch
2283 -- Table of Typ associated with Iface (each abstract interface of Typ
2284 -- has a secondary dispatch table). The arguments Typ, Ancestor_Typ
2285 -- and Suffix_Index are used to generate an unique external name which
2286 -- is added at the end of Acc_Disp_Tables; this external name will be
2287 -- used later by the subprogram Exp_Ch3.Build_Init_Procedure.
2289 -----------------------
2290 -- Make_Secondary_DT --
2291 -----------------------
2293 procedure Make_Secondary_DT
2297 Iface_DT_Ptr : Entity_Id;
2300 Loc : constant Source_Ptr := Sloc (Typ);
2301 Generalized_Tag : constant Entity_Id := RTE (RE_Interface_Tag);
2303 Name_DT : constant Name_Id := New_Internal_Name ('T');
2304 Iface_DT : constant Entity_Id :=
2305 Make_Defining_Identifier (Loc, Name_DT);
2306 Name_Predef_Prims : constant Name_Id := New_Internal_Name ('R');
2307 Predef_Prims : constant Entity_Id :=
2308 Make_Defining_Identifier (Loc,
2310 DT_Constr_List : List_Id;
2311 DT_Aggr_List : List_Id;
2312 Empty_DT : Boolean := False;
2313 Nb_Predef_Prims : Nat := 0;
2317 OSD_Aggr_List : List_Id;
2320 Prim_Elmt : Elmt_Id;
2321 Prim_Ops_Aggr_List : List_Id;
2324 -- Handle the case where the backend does not support statically
2325 -- allocated dispatch tables.
2327 if not Static_Dispatch_Tables
2330 Set_Ekind (Predef_Prims, E_Variable);
2331 Set_Is_Statically_Allocated (Predef_Prims);
2333 Set_Ekind (Iface_DT, E_Variable);
2334 Set_Is_Statically_Allocated (Iface_DT);
2336 -- Statically allocated dispatch tables and related entities are
2340 Set_Ekind (Predef_Prims, E_Constant);
2341 Set_Is_Statically_Allocated (Predef_Prims);
2342 Set_Is_True_Constant (Predef_Prims);
2344 Set_Ekind (Iface_DT, E_Constant);
2345 Set_Is_Statically_Allocated (Iface_DT);
2346 Set_Is_True_Constant (Iface_DT);
2349 -- Generate code to create the storage for the Dispatch_Table object.
2350 -- If the number of primitives of Typ is 0 we reserve a dummy single
2351 -- entry for its DT because at run-time the pointer to this dummy
2352 -- entry will be used as the tag.
2354 Nb_Prim := UI_To_Int (DT_Entry_Count (AI_Tag));
2363 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
2364 -- (predef-prim-op-thunk-1'address,
2365 -- predef-prim-op-thunk-2'address,
2367 -- predef-prim-op-thunk-n'address);
2368 -- for Predef_Prims'Alignment use Address'Alignment
2370 -- Stage 1: Calculate the number of predefined primitives
2372 if not Static_Dispatch_Tables then
2373 Nb_Predef_Prims := Max_Predef_Prims;
2375 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2376 while Present (Prim_Elmt) loop
2377 Prim := Node (Prim_Elmt);
2379 if Is_Predefined_Dispatching_Operation (Prim)
2380 and then not Is_Abstract_Subprogram (Prim)
2382 Pos := UI_To_Int (DT_Position (Prim));
2384 if Pos > Nb_Predef_Prims then
2385 Nb_Predef_Prims := Pos;
2389 Next_Elmt (Prim_Elmt);
2393 -- Stage 2: Create the thunks associated with the predefined
2394 -- primitives and save their entity to fill the aggregate.
2397 Prim_Table : array (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
2398 Thunk_Id : Entity_Id;
2399 Thunk_Code : Node_Id;
2402 Prim_Ops_Aggr_List := New_List;
2403 Prim_Table := (others => Empty);
2405 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2406 while Present (Prim_Elmt) loop
2407 Prim := Node (Prim_Elmt);
2409 if Is_Predefined_Dispatching_Operation (Prim)
2410 and then not Is_Abstract_Subprogram (Prim)
2411 and then not Present (Prim_Table
2412 (UI_To_Int (DT_Position (Prim))))
2414 while Present (Alias (Prim)) loop
2415 Prim := Alias (Prim);
2418 Expand_Interface_Thunk
2420 Thunk_Alias => Prim,
2421 Thunk_Id => Thunk_Id,
2422 Thunk_Code => Thunk_Code);
2424 if Present (Thunk_Id) then
2425 Append_To (Result, Thunk_Code);
2426 Prim_Table (UI_To_Int (DT_Position (Prim))) := Thunk_Id;
2430 Next_Elmt (Prim_Elmt);
2433 for J in Prim_Table'Range loop
2434 if Present (Prim_Table (J)) then
2436 Make_Attribute_Reference (Loc,
2437 Prefix => New_Reference_To (Prim_Table (J), Loc),
2438 Attribute_Name => Name_Address);
2441 New_Reference_To (RTE (RE_Null_Address), Loc);
2444 Append_To (Prim_Ops_Aggr_List, New_Node);
2448 Make_Object_Declaration (Loc,
2449 Defining_Identifier => Predef_Prims,
2450 Constant_Present => Static_Dispatch_Tables,
2451 Aliased_Present => True,
2452 Object_Definition =>
2453 New_Reference_To (RTE (RE_Address_Array), Loc),
2454 Expression => Make_Aggregate (Loc,
2455 Expressions => Prim_Ops_Aggr_List)));
2458 Make_Attribute_Definition_Clause (Loc,
2459 Name => New_Reference_To (Predef_Prims, Loc),
2460 Chars => Name_Alignment,
2462 Make_Attribute_Reference (Loc,
2464 New_Reference_To (RTE (RE_Integer_Address), Loc),
2465 Attribute_Name => Name_Alignment)));
2470 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
2471 -- (OSD_Table => (1 => <value>,
2475 -- Iface_DT : Dispatch_Table (Nb_Prims) :=
2476 -- ([ Signature => <sig-value> ],
2477 -- Tag_Kind => <tag_kind-value>,
2478 -- Predef_Prims => Predef_Prims'Address,
2479 -- Offset_To_Top => 0,
2480 -- OSD => OSD'Address,
2481 -- Prims_Ptr => (prim-op-1'address,
2482 -- prim-op-2'address,
2484 -- prim-op-n'address));
2486 -- Stage 3: Initialize the discriminant and the record components
2488 DT_Constr_List := New_List;
2489 DT_Aggr_List := New_List;
2491 -- Nb_Prim. If the tagged type has no primitives we add a dummy
2492 -- slot whose address will be the tag of this type.
2495 New_Node := Make_Integer_Literal (Loc, 1);
2497 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
2500 Append_To (DT_Constr_List, New_Node);
2501 Append_To (DT_Aggr_List, New_Copy (New_Node));
2505 if RTE_Record_Component_Available (RE_Signature) then
2506 Append_To (DT_Aggr_List,
2507 New_Reference_To (RTE (RE_Secondary_DT), Loc));
2512 if RTE_Record_Component_Available (RE_Tag_Kind) then
2513 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
2518 Append_To (DT_Aggr_List,
2519 Make_Attribute_Reference (Loc,
2520 Prefix => New_Reference_To (Predef_Prims, Loc),
2521 Attribute_Name => Name_Address));
2523 -- Note: The correct value of Offset_To_Top will be set by the init
2526 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
2528 -- Generate the Object Specific Data table required to dispatch calls
2529 -- through synchronized interfaces.
2532 or else Is_Abstract_Type (Typ)
2533 or else Is_Controlled (Typ)
2534 or else Restriction_Active (No_Dispatching_Calls)
2535 or else not Is_Limited_Type (Typ)
2536 or else not Has_Abstract_Interfaces (Typ)
2538 -- No OSD table required
2540 Append_To (DT_Aggr_List,
2541 New_Reference_To (RTE (RE_Null_Address), Loc));
2544 OSD_Aggr_List := New_List;
2547 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
2549 Prim_Alias : Entity_Id;
2550 Prim_Elmt : Elmt_Id;
2556 Prim_Table := (others => Empty);
2557 Prim_Alias := Empty;
2559 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2560 while Present (Prim_Elmt) loop
2561 Prim := Node (Prim_Elmt);
2563 if Present (Abstract_Interface_Alias (Prim))
2564 and then Find_Dispatching_Type
2565 (Abstract_Interface_Alias (Prim)) = Iface
2567 Prim_Alias := Abstract_Interface_Alias (Prim);
2570 while Present (Alias (E)) loop
2574 Pos := UI_To_Int (DT_Position (Prim_Alias));
2576 if Present (Prim_Table (Pos)) then
2577 pragma Assert (Prim_Table (Pos) = E);
2581 Prim_Table (Pos) := E;
2583 Append_To (OSD_Aggr_List,
2584 Make_Component_Association (Loc,
2585 Choices => New_List (
2586 Make_Integer_Literal (Loc,
2587 DT_Position (Prim_Alias))),
2589 Make_Integer_Literal (Loc,
2590 DT_Position (Alias (Prim)))));
2596 Next_Elmt (Prim_Elmt);
2598 pragma Assert (Count = Nb_Prim);
2601 OSD := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
2604 Make_Object_Declaration (Loc,
2605 Defining_Identifier => OSD,
2606 Object_Definition =>
2607 Make_Subtype_Indication (Loc,
2609 New_Reference_To (RTE (RE_Object_Specific_Data), Loc),
2611 Make_Index_Or_Discriminant_Constraint (Loc,
2612 Constraints => New_List (
2613 Make_Integer_Literal (Loc, Nb_Prim)))),
2614 Expression => Make_Aggregate (Loc,
2615 Component_Associations => New_List (
2616 Make_Component_Association (Loc,
2617 Choices => New_List (
2619 (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
2621 Make_Integer_Literal (Loc, Nb_Prim)),
2623 Make_Component_Association (Loc,
2624 Choices => New_List (
2626 (RTE_Record_Component (RE_OSD_Table), Loc)),
2627 Expression => Make_Aggregate (Loc,
2628 Component_Associations => OSD_Aggr_List))))));
2630 -- In secondary dispatch tables the Typeinfo component contains
2631 -- the address of the Object Specific Data (see a-tags.ads)
2633 Append_To (DT_Aggr_List,
2634 Make_Attribute_Reference (Loc,
2635 Prefix => New_Reference_To (OSD, Loc),
2636 Attribute_Name => Name_Address));
2639 -- Initialize the table of primitive operations
2641 Prim_Ops_Aggr_List := New_List;
2644 Append_To (Prim_Ops_Aggr_List,
2645 New_Reference_To (RTE (RE_Null_Address), Loc));
2647 elsif Is_Abstract_Type (Typ)
2648 or else not Static_Dispatch_Tables
2650 for J in 1 .. Nb_Prim loop
2651 Append_To (Prim_Ops_Aggr_List,
2652 New_Reference_To (RTE (RE_Null_Address), Loc));
2657 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
2659 Thunk_Code : Node_Id;
2660 Thunk_Id : Entity_Id;
2663 Prim_Table := (others => Empty);
2665 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2666 while Present (Prim_Elmt) loop
2667 Prim := Node (Prim_Elmt);
2669 if not Is_Predefined_Dispatching_Operation (Prim)
2670 and then Present (Abstract_Interface_Alias (Prim))
2671 and then not Is_Abstract_Subprogram (Alias (Prim))
2672 and then not Is_Imported (Alias (Prim))
2673 and then Find_Dispatching_Type
2674 (Abstract_Interface_Alias (Prim)) = Iface
2676 -- Generate the code of the thunk only if the abstract
2677 -- interface type is not an immediate ancestor of
2678 -- Tagged_Type; otherwise the DT associated with the
2679 -- interface is the primary DT.
2681 and then not Is_Parent (Iface, Typ)
2683 Expand_Interface_Thunk
2685 Thunk_Alias => Alias (Prim),
2686 Thunk_Id => Thunk_Id,
2687 Thunk_Code => Thunk_Code);
2689 if Present (Thunk_Id) then
2692 (DT_Position (Abstract_Interface_Alias (Prim)));
2694 Prim_Table (Pos) := Thunk_Id;
2695 Append_To (Result, Thunk_Code);
2699 Next_Elmt (Prim_Elmt);
2702 for J in Prim_Table'Range loop
2703 if Present (Prim_Table (J)) then
2705 Make_Attribute_Reference (Loc,
2706 Prefix => New_Reference_To (Prim_Table (J), Loc),
2707 Attribute_Name => Name_Address);
2710 New_Reference_To (RTE (RE_Null_Address), Loc);
2713 Append_To (Prim_Ops_Aggr_List, New_Node);
2718 Append_To (DT_Aggr_List,
2719 Make_Aggregate (Loc,
2720 Expressions => Prim_Ops_Aggr_List));
2723 Make_Object_Declaration (Loc,
2724 Defining_Identifier => Iface_DT,
2725 Aliased_Present => True,
2726 Object_Definition =>
2727 Make_Subtype_Indication (Loc,
2728 Subtype_Mark => New_Reference_To
2729 (RTE (RE_Dispatch_Table_Wrapper), Loc),
2730 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
2731 Constraints => DT_Constr_List)),
2733 Expression => Make_Aggregate (Loc,
2734 Expressions => DT_Aggr_List)));
2736 -- Generate code to create the pointer to the dispatch table
2738 -- Iface_DT_Ptr : Tag := Tag!(DT'Address);
2741 Make_Object_Declaration (Loc,
2742 Defining_Identifier => Iface_DT_Ptr,
2743 Constant_Present => True,
2744 Object_Definition =>
2745 New_Reference_To (RTE (RE_Interface_Tag), Loc),
2747 Unchecked_Convert_To (Generalized_Tag,
2748 Make_Attribute_Reference (Loc,
2750 Make_Selected_Component (Loc,
2751 Prefix => New_Reference_To (Iface_DT, Loc),
2754 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
2755 Attribute_Name => Name_Address))));
2757 end Make_Secondary_DT;
2761 -- Seems a huge list, shouldn't some of these be commented???
2762 -- Seems like we are counting too much on guessing from names here???
2764 Elab_Code : constant List_Id := New_List;
2765 Generalized_Tag : constant Entity_Id := RTE (RE_Tag);
2766 Result : constant List_Id := New_List;
2767 Tname : constant Name_Id := Chars (Typ);
2768 Name_DT : constant Name_Id := New_External_Name (Tname, 'T');
2769 Name_Exname : constant Name_Id := New_External_Name (Tname, 'E');
2770 Name_Predef_Prims : constant Name_Id := New_External_Name (Tname, 'R');
2771 Name_SSD : constant Name_Id := New_External_Name (Tname, 'S');
2772 Name_TSD : constant Name_Id := New_External_Name (Tname, 'B');
2773 DT : constant Entity_Id :=
2774 Make_Defining_Identifier (Loc, Name_DT);
2775 Exname : constant Entity_Id :=
2776 Make_Defining_Identifier (Loc, Name_Exname);
2777 Predef_Prims : constant Entity_Id :=
2778 Make_Defining_Identifier (Loc, Name_Predef_Prims);
2779 SSD : constant Entity_Id :=
2780 Make_Defining_Identifier (Loc, Name_SSD);
2781 TSD : constant Entity_Id :=
2782 Make_Defining_Identifier (Loc, Name_TSD);
2784 AI_Tag_Comp : Elmt_Id;
2785 AI_Ptr_Elmt : Elmt_Id;
2786 DT_Constr_List : List_Id;
2787 DT_Aggr_List : List_Id;
2789 Has_Dispatch_Table : Boolean := True;
2792 Iface_Table_Node : Node_Id;
2793 Name_ITable : Name_Id;
2794 Name_No_Reg : Name_Id;
2795 Nb_Predef_Prims : Nat := 0;
2799 Null_Parent_Tag : Boolean := False;
2800 Num_Ifaces : Nat := 0;
2804 Prim_Elmt : Elmt_Id;
2805 Prim_Ops_Aggr_List : List_Id;
2806 Transportable : Entity_Id;
2807 RC_Offset_Node : Node_Id;
2809 Typ_Comps : Elist_Id;
2810 Typ_Ifaces : Elist_Id;
2811 TSD_Aggr_List : List_Id;
2812 TSD_Tags_List : List_Id;
2813 TSD_Ifaces_List : List_Id;
2815 -- Start of processing for Make_DT
2818 -- Fill the contents of Access_Disp_Table
2820 -- 1) Generate the primary and secondary tag entities
2824 Name_DT_Ptr : Name_Id;
2826 Iface_DT_Ptr : Node_Id;
2828 AI_Tag_Comp : Elmt_Id;
2831 -- Collect the components associated with secondary dispatch tables
2833 if Has_Abstract_Interfaces (Typ) then
2834 Collect_Interface_Components (Typ, Typ_Comps);
2837 -- Generate the primary tag entity
2839 Name_DT_Ptr := New_External_Name (Tname, 'P');
2840 DT_Ptr := Make_Defining_Identifier (Loc, Name_DT_Ptr);
2841 Set_Ekind (DT_Ptr, E_Constant);
2842 Set_Is_Statically_Allocated (DT_Ptr);
2843 Set_Is_True_Constant (DT_Ptr);
2845 pragma Assert (No (Access_Disp_Table (Typ)));
2846 Set_Access_Disp_Table (Typ, New_Elmt_List);
2847 Append_Elmt (DT_Ptr, Access_Disp_Table (Typ));
2849 -- Generate the secondary tag entities
2851 if Has_Abstract_Interfaces (Typ) then
2854 -- For each interface type we build an unique external name
2855 -- associated with its corresponding secondary dispatch table.
2856 -- This external name will be used to declare an object that
2857 -- references this secondary dispatch table, value that will be
2858 -- used for the elaboration of Typ's objects and also for the
2859 -- elaboration of objects of derivations of Typ that do not
2860 -- override the primitive operation of this interface type.
2862 AI_Tag_Comp := First_Elmt (Typ_Comps);
2863 while Present (AI_Tag_Comp) loop
2864 Get_Secondary_DT_External_Name
2865 (Typ, Related_Interface (Node (AI_Tag_Comp)), Suffix_Index);
2867 Typ_Name := Name_Find;
2868 Name_DT_Ptr := New_External_Name (Typ_Name, "P");
2869 Iface_DT_Ptr := Make_Defining_Identifier (Loc, Name_DT_Ptr);
2871 Set_Ekind (Iface_DT_Ptr, E_Constant);
2872 Set_Is_Statically_Allocated (Iface_DT_Ptr);
2873 Set_Is_True_Constant (Iface_DT_Ptr);
2874 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
2876 Next_Elmt (AI_Tag_Comp);
2881 -- 2) At the end of Access_Disp_Table we add the entity of an access
2882 -- type declaration. It is used by Build_Get_Prim_Op_Address to
2883 -- expand dispatching calls through the primary dispatch table.
2886 -- type Typ_DT is array (1 .. Nb_Prims) of Address;
2887 -- type Typ_DT_Acc is access Typ_DT;
2890 Name_DT_Prims : constant Name_Id :=
2891 New_External_Name (Tname, 'G');
2892 Name_DT_Prims_Acc : constant Name_Id :=
2893 New_External_Name (Tname, 'H');
2894 DT_Prims : constant Entity_Id :=
2895 Make_Defining_Identifier (Loc, Name_DT_Prims);
2896 DT_Prims_Acc : constant Entity_Id :=
2897 Make_Defining_Identifier (Loc,
2901 Make_Full_Type_Declaration (Loc,
2902 Defining_Identifier => DT_Prims,
2904 Make_Constrained_Array_Definition (Loc,
2905 Discrete_Subtype_Definitions => New_List (
2907 Low_Bound => Make_Integer_Literal (Loc, 1),
2908 High_Bound => Make_Integer_Literal (Loc,
2910 (First_Tag_Component (Typ))))),
2911 Component_Definition =>
2912 Make_Component_Definition (Loc,
2913 Subtype_Indication =>
2914 New_Reference_To (RTE (RE_Address), Loc)))));
2917 Make_Full_Type_Declaration (Loc,
2918 Defining_Identifier => DT_Prims_Acc,
2920 Make_Access_To_Object_Definition (Loc,
2921 Subtype_Indication =>
2922 New_Occurrence_Of (DT_Prims, Loc))));
2924 Append_Elmt (DT_Prims_Acc, Access_Disp_Table (Typ));
2927 if Is_CPP_Class (Typ) then
2931 if No_Run_Time_Mode or else not RTE_Available (RE_Tag) then
2932 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2935 Make_Object_Declaration (Loc,
2936 Defining_Identifier => DT_Ptr,
2937 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
2938 Constant_Present => True,
2940 Unchecked_Convert_To (Generalized_Tag,
2941 New_Reference_To (RTE (RE_Null_Address), Loc))));
2943 Analyze_List (Result, Suppress => All_Checks);
2944 Error_Msg_CRT ("tagged types", Typ);
2948 if not Static_Dispatch_Tables
2951 Set_Ekind (DT, E_Variable);
2952 Set_Is_Statically_Allocated (DT);
2954 Set_Ekind (DT, E_Constant);
2955 Set_Is_Statically_Allocated (DT);
2956 Set_Is_True_Constant (DT);
2959 pragma Assert (Present (Access_Disp_Table (Typ)));
2960 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2962 -- Ada 2005 (AI-251): Build the secondary dispatch tables
2964 if Has_Abstract_Interfaces (Typ) then
2966 AI_Ptr_Elmt := Next_Elmt (First_Elmt (Access_Disp_Table (Typ)));
2968 AI_Tag_Comp := First_Elmt (Typ_Comps);
2969 while Present (AI_Tag_Comp) loop
2973 (Related_Interface (Node (AI_Tag_Comp))),
2974 AI_Tag => Node (AI_Tag_Comp),
2975 Iface_DT_Ptr => Node (AI_Ptr_Elmt),
2978 Suffix_Index := Suffix_Index + 1;
2979 Next_Elmt (AI_Ptr_Elmt);
2980 Next_Elmt (AI_Tag_Comp);
2984 -- Evaluate if we generate the dispatch table
2986 Has_Dispatch_Table :=
2987 not Is_Interface (Typ)
2988 and then not Restriction_Active (No_Dispatching_Calls);
2990 -- Calculate the number of primitives of the dispatch table and the
2991 -- size of the Type_Specific_Data record.
2993 if Has_Dispatch_Table then
2994 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
2997 if not Static_Dispatch_Tables then
2998 Set_Ekind (Predef_Prims, E_Variable);
2999 Set_Is_Statically_Allocated (Predef_Prims);
3001 Set_Ekind (Predef_Prims, E_Constant);
3002 Set_Is_Statically_Allocated (Predef_Prims);
3003 Set_Is_True_Constant (Predef_Prims);
3006 Set_Ekind (SSD, E_Constant);
3007 Set_Is_Statically_Allocated (SSD);
3008 Set_Is_True_Constant (SSD);
3010 Set_Ekind (TSD, E_Constant);
3011 Set_Is_Statically_Allocated (TSD);
3012 Set_Is_True_Constant (TSD);
3014 Set_Ekind (Exname, E_Constant);
3015 Set_Is_Statically_Allocated (Exname);
3016 Set_Is_True_Constant (Exname);
3018 -- Generate code to define the boolean that controls registration, in
3019 -- order to avoid multiple registrations for tagged types defined in
3020 -- multiple-called scopes.
3022 if not Is_Interface (Typ) then
3023 Name_No_Reg := New_External_Name (Tname, 'F');
3024 No_Reg := Make_Defining_Identifier (Loc, Name_No_Reg);
3026 Set_Ekind (No_Reg, E_Variable);
3027 Set_Is_Statically_Allocated (No_Reg);
3030 Make_Object_Declaration (Loc,
3031 Defining_Identifier => No_Reg,
3032 Object_Definition => New_Reference_To (Standard_Boolean, Loc),
3033 Expression => New_Reference_To (Standard_True, Loc)));
3036 -- In case of locally defined tagged type we declare the object
3037 -- contanining the dispatch table by means of a variable. Its
3038 -- initialization is done later by means of an assignment. This is
3039 -- required to generate its External_Tag.
3044 -- DT : No_Dispatch_Table_Wrapper;
3045 -- DT_Ptr : Tag := !Tag (DT.NDT_Prims_Ptr'Address);
3047 if not Has_Dispatch_Table then
3049 Make_Object_Declaration (Loc,
3050 Defining_Identifier => DT,
3051 Aliased_Present => True,
3052 Constant_Present => False,
3053 Object_Definition =>
3055 (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
3058 Make_Object_Declaration (Loc,
3059 Defining_Identifier => DT_Ptr,
3060 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
3061 Constant_Present => True,
3063 Unchecked_Convert_To (Generalized_Tag,
3064 Make_Attribute_Reference (Loc,
3066 Make_Selected_Component (Loc,
3067 Prefix => New_Reference_To (DT, Loc),
3070 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
3071 Attribute_Name => Name_Address))));
3074 -- DT : Dispatch_Table_Wrapper (Nb_Prim);
3075 -- for DT'Alignment use Address'Alignment;
3076 -- DT_Ptr : Tag := !Tag (DT.Prims_Ptr'Address);
3079 -- If the tagged type has no primitives we add a dummy slot
3080 -- whose address will be the tag of this type.
3084 New_List (Make_Integer_Literal (Loc, 1));
3087 New_List (Make_Integer_Literal (Loc, Nb_Prim));
3091 Make_Object_Declaration (Loc,
3092 Defining_Identifier => DT,
3093 Aliased_Present => True,
3094 Constant_Present => False,
3095 Object_Definition =>
3096 Make_Subtype_Indication (Loc,
3098 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
3099 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
3100 Constraints => DT_Constr_List))));
3103 Make_Attribute_Definition_Clause (Loc,
3104 Name => New_Reference_To (DT, Loc),
3105 Chars => Name_Alignment,
3107 Make_Attribute_Reference (Loc,
3109 New_Reference_To (RTE (RE_Integer_Address), Loc),
3110 Attribute_Name => Name_Alignment)));
3113 Make_Object_Declaration (Loc,
3114 Defining_Identifier => DT_Ptr,
3115 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
3116 Constant_Present => True,
3118 Unchecked_Convert_To (Generalized_Tag,
3119 Make_Attribute_Reference (Loc,
3121 Make_Selected_Component (Loc,
3122 Prefix => New_Reference_To (DT, Loc),
3125 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
3126 Attribute_Name => Name_Address))));
3130 -- Generate: Exname : constant String := full_qualified_name (typ);
3131 -- The type itself may be an anonymous parent type, so use the first
3132 -- subtype to have a user-recognizable name.
3135 Make_Object_Declaration (Loc,
3136 Defining_Identifier => Exname,
3137 Constant_Present => True,
3138 Object_Definition => New_Reference_To (Standard_String, Loc),
3140 Make_String_Literal (Loc,
3141 Full_Qualified_Name (First_Subtype (Typ)))));
3143 -- Generate code to create the storage for the type specific data object
3144 -- with enough space to store the tags of the ancestors plus the tags
3145 -- of all the implemented interfaces (as described in a-tags.adb).
3147 -- TSD : Type_Specific_Data (I_Depth) :=
3148 -- (Idepth => I_Depth,
3149 -- Access_Level => Type_Access_Level (Typ),
3150 -- Expanded_Name => Cstring_Ptr!(Exname'Address))
3151 -- External_Tag => Cstring_Ptr!(Exname'Address))
3153 -- Transportable => <<boolean-value>>,
3154 -- RC_Offset => <<integer-value>>,
3155 -- [ Interfaces_Table => <<access-value>> ]
3156 -- [ SSD => SSD_Table'Address ]
3157 -- Tags_Table => (0 => null,
3160 -- for TSD'Alignment use Address'Alignment
3162 TSD_Aggr_List := New_List;
3164 -- Idepth: Count ancestors to compute the inheritance depth. For private
3165 -- extensions, always go to the full view in order to compute the real
3166 -- inheritance depth.
3169 Current_Typ : Entity_Id;
3170 Parent_Typ : Entity_Id;
3176 Parent_Typ := Etype (Current_Typ);
3178 if Is_Private_Type (Parent_Typ) then
3179 Parent_Typ := Full_View (Base_Type (Parent_Typ));
3182 exit when Parent_Typ = Current_Typ;
3184 I_Depth := I_Depth + 1;
3185 Current_Typ := Parent_Typ;
3189 Append_To (TSD_Aggr_List,
3190 Make_Component_Association (Loc,
3191 Choices => New_List (
3192 New_Occurrence_Of (RTE_Record_Component (RE_Idepth), Loc)),
3194 Make_Integer_Literal (Loc, I_Depth)));
3198 Append_To (TSD_Aggr_List,
3199 Make_Component_Association (Loc,
3200 Choices => New_List (
3201 New_Occurrence_Of (RTE_Record_Component (RE_Access_Level), Loc)),
3203 Make_Integer_Literal (Loc, Type_Access_Level (Typ))));
3207 Append_To (TSD_Aggr_List,
3208 Make_Component_Association (Loc,
3209 Choices => New_List (
3210 New_Occurrence_Of (RTE_Record_Component (RE_Expanded_Name), Loc)),
3212 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
3213 Make_Attribute_Reference (Loc,
3214 Prefix => New_Reference_To (Exname, Loc),
3215 Attribute_Name => Name_Address))));
3217 -- External_Tag of a local tagged type
3219 -- Exname : constant String :=
3220 -- "Internal tag at 16#tag-addr#: <full-name-of-typ>";
3222 -- The reason we generate this strange name is that we do not want to
3223 -- enter local tagged types in the global hash table used to compute
3224 -- the Internal_Tag attribute for two reasons:
3226 -- 1. It is hard to avoid a tasking race condition for entering the
3227 -- entry into the hash table.
3229 -- 2. It would cause a storage leak, unless we rig up considerable
3230 -- mechanism to remove the entry from the hash table on exit.
3232 -- So what we do is to generate the above external tag name, where the
3233 -- hex address is the address of the local dispatch table (i.e. exactly
3234 -- the value we want if Internal_Tag is computed from this string).
3236 -- Of course this value will only be valid if the tagged type is still
3237 -- in scope, but it clearly must be erroneous to compute the internal
3238 -- tag of a tagged type that is out of scope!
3242 Name_Exname : constant Name_Id := New_External_Name (Tname, 'L');
3243 Name_Str1 : constant Name_Id := New_Internal_Name ('I');
3244 Name_Str2 : constant Name_Id := New_Internal_Name ('I');
3245 Name_Str3 : constant Name_Id := New_Internal_Name ('I');
3246 Exname : constant Entity_Id :=
3247 Make_Defining_Identifier (Loc, Name_Exname);
3248 Str1 : constant Entity_Id :=
3249 Make_Defining_Identifier (Loc, Name_Str1);
3250 Str2 : constant Entity_Id :=
3251 Make_Defining_Identifier (Loc, Name_Str2);
3252 Str3 : constant Entity_Id :=
3253 Make_Defining_Identifier (Loc, Name_Str3);
3254 Full_Name : constant String_Id :=
3255 Full_Qualified_Name (First_Subtype (Typ));
3256 Str1_Id : String_Id;
3257 Str2_Id : String_Id;
3258 Str3_Id : String_Id;
3262 -- Str1 : constant String := "Internal tag at 16#";
3264 Set_Ekind (Str1, E_Constant);
3265 Set_Is_Statically_Allocated (Str1);
3266 Set_Is_True_Constant (Str1);
3269 Store_String_Chars ("Internal tag at 16#");
3270 Str1_Id := End_String;
3273 -- Str2 : constant String := "#: ";
3275 Set_Ekind (Str2, E_Constant);
3276 Set_Is_Statically_Allocated (Str2);
3277 Set_Is_True_Constant (Str2);
3280 Store_String_Chars ("#: ");
3281 Str2_Id := End_String;
3284 -- Str3 : constant String := <full-name-of-typ>;
3286 Set_Ekind (Str3, E_Constant);
3287 Set_Is_Statically_Allocated (Str3);
3288 Set_Is_True_Constant (Str3);
3291 Store_String_Chars (Full_Name);
3292 Str3_Id := End_String;
3295 -- Exname : constant String :=
3296 -- Str1 & Address_Image (Tag) & Str2 & Str3;
3298 if RTE_Available (RE_Address_Image) then
3300 Make_Object_Declaration (Loc,
3301 Defining_Identifier => Exname,
3302 Constant_Present => True,
3303 Object_Definition => New_Reference_To
3304 (Standard_String, Loc),
3306 Make_Op_Concat (Loc,
3308 Make_String_Literal (Loc, Str1_Id),
3310 Make_Op_Concat (Loc,
3312 Make_Function_Call (Loc,
3315 (RTE (RE_Address_Image), Loc),
3316 Parameter_Associations => New_List (
3317 Unchecked_Convert_To (RTE (RE_Address),
3318 New_Reference_To (DT_Ptr, Loc)))),
3320 Make_Op_Concat (Loc,
3322 Make_String_Literal (Loc, Str2_Id),
3324 Make_String_Literal (Loc, Str3_Id))))));
3327 Make_Object_Declaration (Loc,
3328 Defining_Identifier => Exname,
3329 Constant_Present => True,
3330 Object_Definition => New_Reference_To
3331 (Standard_String, Loc),
3333 Make_Op_Concat (Loc,
3335 Make_String_Literal (Loc, Str1_Id),
3337 Make_Op_Concat (Loc,
3339 Make_String_Literal (Loc, Str2_Id),
3341 Make_String_Literal (Loc, Str3_Id)))));
3345 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
3346 Make_Attribute_Reference (Loc,
3347 Prefix => New_Reference_To (Exname, Loc),
3348 Attribute_Name => Name_Address));
3351 -- External tag of a library-level tagged type: Check for a definition
3352 -- of External_Tag. The clause is considered only if it applies to this
3353 -- specific tagged type, as opposed to one of its ancestors.
3357 Def : constant Node_Id := Get_Attribute_Definition_Clause (Typ,
3358 Attribute_External_Tag);
3359 Old_Val : String_Id;
3360 New_Val : String_Id;
3364 if not Present (Def)
3365 or else Entity (Name (Def)) /= Typ
3368 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
3369 Make_Attribute_Reference (Loc,
3370 Prefix => New_Reference_To (Exname, Loc),
3371 Attribute_Name => Name_Address));
3373 Old_Val := Strval (Expr_Value_S (Expression (Def)));
3375 -- For the rep clause "for x'external_tag use y" generate:
3377 -- xV : constant string := y;
3378 -- Set_External_Tag (x'tag, xV'Address);
3379 -- Register_Tag (x'tag);
3381 -- Create a new nul terminated string if it is not already
3383 if String_Length (Old_Val) > 0
3385 Get_String_Char (Old_Val, String_Length (Old_Val)) = 0
3389 Start_String (Old_Val);
3390 Store_String_Char (Get_Char_Code (ASCII.NUL));
3391 New_Val := End_String;
3394 E := Make_Defining_Identifier (Loc,
3395 New_External_Name (Chars (Typ), 'A'));
3398 Make_Object_Declaration (Loc,
3399 Defining_Identifier => E,
3400 Constant_Present => True,
3401 Object_Definition =>
3402 New_Reference_To (Standard_String, Loc),
3404 Make_String_Literal (Loc, New_Val)));
3407 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
3408 Make_Attribute_Reference (Loc,
3409 Prefix => New_Reference_To (E, Loc),
3410 Attribute_Name => Name_Address));
3415 Append_To (TSD_Aggr_List,
3416 Make_Component_Association (Loc,
3417 Choices => New_List (
3419 (RTE_Record_Component (RE_External_Tag), Loc)),
3420 Expression => New_Node));
3424 Append_To (TSD_Aggr_List,
3425 Make_Component_Association (Loc,
3426 Choices => New_List (
3428 (RTE_Record_Component (RE_HT_Link), Loc)),
3430 Unchecked_Convert_To (RTE (RE_Tag),
3431 New_Reference_To (RTE (RE_Null_Address), Loc))));
3433 -- Transportable: Set for types that can be used in remote calls
3434 -- with respect to E.4(18) legality rules.
3439 or else Is_Shared_Passive (Typ)
3441 ((Is_Remote_Types (Typ)
3442 or else Is_Remote_Call_Interface (Typ))
3443 and then Original_View_In_Visible_Part (Typ))
3444 or else not Comes_From_Source (Typ));
3446 Append_To (TSD_Aggr_List,
3447 Make_Component_Association (Loc,
3448 Choices => New_List (
3450 (RTE_Record_Component (RE_Transportable), Loc)),
3451 Expression => New_Occurrence_Of (Transportable, Loc)));
3453 -- RC_Offset: These are the valid values and their meaning:
3455 -- >0: For simple types with controlled components is
3456 -- type._record_controller'position
3458 -- 0: For types with no controlled components
3460 -- -1: For complex types with controlled components where the position
3461 -- of the record controller is not statically computable but there
3462 -- are controlled components at this level. The _Controller field
3463 -- is available right after the _parent.
3465 -- -2: There are no controlled components at this level. We need to
3466 -- get the position from the parent.
3468 if not Has_Controlled_Component (Typ) then
3469 RC_Offset_Node := Make_Integer_Literal (Loc, 0);
3471 elsif Etype (Typ) /= Typ
3472 and then Has_Discriminants (Etype (Typ))
3474 if Has_New_Controlled_Component (Typ) then
3475 RC_Offset_Node := Make_Integer_Literal (Loc, -1);
3477 RC_Offset_Node := Make_Integer_Literal (Loc, -2);
3481 Make_Attribute_Reference (Loc,
3483 Make_Selected_Component (Loc,
3484 Prefix => New_Reference_To (Typ, Loc),
3486 New_Reference_To (Controller_Component (Typ), Loc)),
3487 Attribute_Name => Name_Position);
3489 -- This is not proper Ada code to use the attribute 'Position
3490 -- on something else than an object but this is supported by
3491 -- the back end (see comment on the Bit_Component attribute in
3492 -- sem_attr). So we avoid semantic checking here.
3494 -- Is this documented in sinfo.ads??? it should be!
3496 Set_Analyzed (RC_Offset_Node);
3497 Set_Etype (Prefix (RC_Offset_Node), RTE (RE_Record_Controller));
3498 Set_Etype (Prefix (Prefix (RC_Offset_Node)), Typ);
3499 Set_Etype (Selector_Name (Prefix (RC_Offset_Node)),
3500 RTE (RE_Record_Controller));
3501 Set_Etype (RC_Offset_Node, RTE (RE_Storage_Offset));
3504 Append_To (TSD_Aggr_List,
3505 Make_Component_Association (Loc,
3506 Choices => New_List (
3507 New_Occurrence_Of (RTE_Record_Component (RE_RC_Offset), Loc)),
3508 Expression => RC_Offset_Node));
3510 -- Interfaces_Table (required for AI-405)
3512 if RTE_Record_Component_Available (RE_Interfaces_Table) then
3514 -- Count the number of interface types implemented by Typ
3516 Collect_Abstract_Interfaces (Typ, Typ_Ifaces);
3518 AI := First_Elmt (Typ_Ifaces);
3519 while Present (AI) loop
3520 Num_Ifaces := Num_Ifaces + 1;
3524 if Num_Ifaces = 0 then
3525 Iface_Table_Node := Make_Null (Loc);
3527 -- Generate the Interface_Table object
3530 TSD_Ifaces_List := New_List;
3534 Aggr_List : List_Id;
3537 AI := First_Elmt (Typ_Ifaces);
3538 while Present (AI) loop
3539 Aggr_List := New_List (
3540 Make_Component_Association (Loc,
3541 Choices => New_List (
3543 (RTE_Record_Component (RE_Iface_Tag), Loc)),
3545 Unchecked_Convert_To (Generalized_Tag,
3547 (Node (First_Elmt (Access_Disp_Table (Node (AI)))),
3550 Make_Component_Association (Loc,
3551 Choices => New_List (
3553 (RTE_Record_Component (RE_Static_Offset_To_Top),
3556 New_Reference_To (Standard_True, Loc)),
3558 Make_Component_Association (Loc,
3559 Choices => New_List (Make_Others_Choice (Loc)),
3560 Expression => Empty,
3561 Box_Present => True));
3563 Append_To (TSD_Ifaces_List,
3564 Make_Component_Association (Loc,
3565 Choices => New_List (
3566 Make_Integer_Literal (Loc, Pos)),
3567 Expression => Make_Aggregate (Loc,
3568 Component_Associations => Aggr_List)));
3575 Name_ITable := New_External_Name (Tname, 'I');
3576 ITable := Make_Defining_Identifier (Loc, Name_ITable);
3578 Set_Ekind (ITable, E_Constant);
3579 Set_Is_Statically_Allocated (ITable);
3580 Set_Is_True_Constant (ITable);
3583 Make_Object_Declaration (Loc,
3584 Defining_Identifier => ITable,
3585 Aliased_Present => True,
3586 Object_Definition =>
3587 Make_Subtype_Indication (Loc,
3589 New_Reference_To (RTE (RE_Interface_Data), Loc),
3590 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
3591 Constraints => New_List (
3592 Make_Integer_Literal (Loc, Num_Ifaces)))),
3594 Expression => Make_Aggregate (Loc,
3595 Component_Associations => New_List (
3596 Make_Component_Association (Loc,
3597 Choices => New_List (
3599 (RTE_Record_Component (RE_Nb_Ifaces), Loc)),
3601 Make_Integer_Literal (Loc, Num_Ifaces)),
3603 Make_Component_Association (Loc,
3604 Choices => New_List (
3606 (RTE_Record_Component (RE_Ifaces_Table), Loc)),
3607 Expression => Make_Aggregate (Loc,
3608 Component_Associations => TSD_Ifaces_List))))));
3611 Make_Attribute_Reference (Loc,
3612 Prefix => New_Reference_To (ITable, Loc),
3613 Attribute_Name => Name_Unchecked_Access);
3616 Append_To (TSD_Aggr_List,
3617 Make_Component_Association (Loc,
3618 Choices => New_List (
3620 (RTE_Record_Component (RE_Interfaces_Table), Loc)),
3621 Expression => Iface_Table_Node));
3624 -- Generate the Select Specific Data table for synchronized types that
3625 -- implement synchronized interfaces. The size of the table is
3626 -- constrained by the number of non-predefined primitive operations.
3628 if RTE_Record_Component_Available (RE_SSD) then
3629 if Ada_Version >= Ada_05
3630 and then Has_Dispatch_Table
3631 and then Is_Concurrent_Record_Type (Typ)
3632 and then Has_Abstract_Interfaces (Typ)
3633 and then Nb_Prim > 0
3634 and then not Is_Abstract_Type (Typ)
3635 and then not Is_Controlled (Typ)
3636 and then not Restriction_Active (No_Dispatching_Calls)
3639 Make_Object_Declaration (Loc,
3640 Defining_Identifier => SSD,
3641 Aliased_Present => True,
3642 Object_Definition =>
3643 Make_Subtype_Indication (Loc,
3644 Subtype_Mark => New_Reference_To (
3645 RTE (RE_Select_Specific_Data), Loc),
3647 Make_Index_Or_Discriminant_Constraint (Loc,
3648 Constraints => New_List (
3649 Make_Integer_Literal (Loc, Nb_Prim))))));
3651 -- This table is initialized by Make_Select_Specific_Data_Table,
3652 -- which calls Set_Entry_Index and Set_Prim_Op_Kind.
3654 Append_To (TSD_Aggr_List,
3655 Make_Component_Association (Loc,
3656 Choices => New_List (
3658 (RTE_Record_Component (RE_SSD), Loc)),
3660 Make_Attribute_Reference (Loc,
3661 Prefix => New_Reference_To (SSD, Loc),
3662 Attribute_Name => Name_Unchecked_Access)));
3664 Append_To (TSD_Aggr_List,
3665 Make_Component_Association (Loc,
3666 Choices => New_List (
3668 (RTE_Record_Component (RE_SSD), Loc)),
3669 Expression => Make_Null (Loc)));
3673 -- Initialize the table of ancestor tags. In case of interface types
3674 -- this table is not needed.
3676 if Is_Interface (Typ) then
3677 Append_To (TSD_Aggr_List,
3678 Make_Component_Association (Loc,
3679 Choices => New_List (Make_Others_Choice (Loc)),
3680 Expression => Empty,
3681 Box_Present => True));
3684 Current_Typ : Entity_Id;
3685 Parent_Typ : Entity_Id;
3689 TSD_Tags_List := New_List;
3691 -- Fill position 0 with null because we still have not generated
3694 Append_To (TSD_Tags_List,
3695 Make_Component_Association (Loc,
3696 Choices => New_List (
3697 Make_Integer_Literal (Loc, 0)),
3699 Unchecked_Convert_To (RTE (RE_Tag),
3700 New_Reference_To (RTE (RE_Null_Address), Loc))));
3702 -- Fill the rest of the table with the tags of the ancestors
3708 Parent_Typ := Etype (Current_Typ);
3710 if Is_Private_Type (Parent_Typ) then
3711 Parent_Typ := Full_View (Base_Type (Parent_Typ));
3714 exit when Parent_Typ = Current_Typ;
3716 if Is_CPP_Class (Parent_Typ) then
3718 -- The tags defined in the C++ side will be inherited when
3719 -- the object is constructed.
3720 -- (see Exp_Ch3.Build_Init_Procedure)
3722 Append_To (TSD_Tags_List,
3723 Make_Component_Association (Loc,
3724 Choices => New_List (
3725 Make_Integer_Literal (Loc, Pos)),
3727 Unchecked_Convert_To (RTE (RE_Tag),
3728 New_Reference_To (RTE (RE_Null_Address), Loc))));
3730 Append_To (TSD_Tags_List,
3731 Make_Component_Association (Loc,
3732 Choices => New_List (
3733 Make_Integer_Literal (Loc, Pos)),
3736 (Node (First_Elmt (Access_Disp_Table (Parent_Typ))),
3741 Current_Typ := Parent_Typ;
3744 pragma Assert (Pos = I_Depth + 1);
3747 Append_To (TSD_Aggr_List,
3748 Make_Component_Association (Loc,
3749 Choices => New_List (
3751 (RTE_Record_Component (RE_Tags_Table), Loc)),
3752 Expression => Make_Aggregate (Loc,
3753 Component_Associations => TSD_Tags_List)));
3756 -- Build the TSD object
3759 Make_Object_Declaration (Loc,
3760 Defining_Identifier => TSD,
3761 Aliased_Present => True,
3762 Object_Definition =>
3763 Make_Subtype_Indication (Loc,
3764 Subtype_Mark => New_Reference_To (
3765 RTE (RE_Type_Specific_Data), Loc),
3767 Make_Index_Or_Discriminant_Constraint (Loc,
3768 Constraints => New_List (
3769 Make_Integer_Literal (Loc, I_Depth)))),
3771 Expression => Make_Aggregate (Loc,
3772 Component_Associations => TSD_Aggr_List)));
3775 Make_Attribute_Definition_Clause (Loc,
3776 Name => New_Reference_To (TSD, Loc),
3777 Chars => Name_Alignment,
3779 Make_Attribute_Reference (Loc,
3780 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
3781 Attribute_Name => Name_Alignment)));
3783 -- Generate the dummy Dispatch_Table object associated with tagged
3784 -- types that have no dispatch table.
3786 -- DT : No_Dispatch_Table :=
3787 -- (NDT_TSD => TSD'Address;
3788 -- NDT_Prims_Ptr => 0);
3790 if not Has_Dispatch_Table then
3791 DT_Constr_List := New_List;
3792 DT_Aggr_List := New_List;
3797 Make_Attribute_Reference (Loc,
3798 Prefix => New_Reference_To (TSD, Loc),
3799 Attribute_Name => Name_Address);
3801 Append_To (DT_Constr_List, New_Node);
3802 Append_To (DT_Aggr_List, New_Copy (New_Node));
3803 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
3805 -- In case of locally defined tagged types we have already declared
3806 -- and uninitialized object for the dispatch table, which is now
3807 -- initialized by means of an assignment.
3811 Make_Assignment_Statement (Loc,
3812 Name => New_Reference_To (DT, Loc),
3813 Expression => Make_Aggregate (Loc,
3814 Expressions => DT_Aggr_List)));
3816 -- In case of library level tagged types we declare now the constant
3817 -- object containing the dispatch table.
3821 Make_Object_Declaration (Loc,
3822 Defining_Identifier => DT,
3823 Aliased_Present => True,
3824 Constant_Present => Static_Dispatch_Tables,
3825 Object_Definition =>
3826 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc),
3827 Expression => Make_Aggregate (Loc,
3828 Expressions => DT_Aggr_List)));
3831 Make_Object_Declaration (Loc,
3832 Defining_Identifier => DT_Ptr,
3833 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
3834 Constant_Present => True,
3836 Unchecked_Convert_To (Generalized_Tag,
3837 Make_Attribute_Reference (Loc,
3839 Make_Selected_Component (Loc,
3840 Prefix => New_Reference_To (DT, Loc),
3843 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
3844 Attribute_Name => Name_Address))));
3847 -- Common case: Typ has a dispatch table
3851 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
3852 -- (predef-prim-op-1'address,
3853 -- predef-prim-op-2'address,
3855 -- predef-prim-op-n'address);
3856 -- for Predef_Prims'Alignment use Address'Alignment
3858 -- DT : Dispatch_Table (Nb_Prims) :=
3859 -- (Signature => <sig-value>,
3860 -- Tag_Kind => <tag_kind-value>,
3861 -- Predef_Prims => Predef_Prims'First'Address,
3862 -- Offset_To_Top => 0,
3863 -- TSD => TSD'Address;
3864 -- Prims_Ptr => (prim-op-1'address,
3865 -- prim-op-2'address,
3867 -- prim-op-n'address));
3874 if not Static_Dispatch_Tables then
3875 Nb_Predef_Prims := Max_Predef_Prims;
3878 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3879 while Present (Prim_Elmt) loop
3880 Prim := Node (Prim_Elmt);
3882 if Is_Predefined_Dispatching_Operation (Prim)
3883 and then not Is_Abstract_Subprogram (Prim)
3885 Pos := UI_To_Int (DT_Position (Prim));
3887 if Pos > Nb_Predef_Prims then
3888 Nb_Predef_Prims := Pos;
3892 Next_Elmt (Prim_Elmt);
3898 (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
3902 Prim_Ops_Aggr_List := New_List;
3904 Prim_Table := (others => Empty);
3905 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3906 while Present (Prim_Elmt) loop
3907 Prim := Node (Prim_Elmt);
3909 if Static_Dispatch_Tables
3910 and then Is_Predefined_Dispatching_Operation (Prim)
3911 and then not Is_Abstract_Subprogram (Prim)
3912 and then not Present (Prim_Table
3913 (UI_To_Int (DT_Position (Prim))))
3916 while Present (Alias (E)) loop
3920 pragma Assert (not Is_Abstract_Subprogram (E));
3921 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
3924 Next_Elmt (Prim_Elmt);
3927 for J in Prim_Table'Range loop
3928 if Present (Prim_Table (J)) then
3930 Make_Attribute_Reference (Loc,
3931 Prefix => New_Reference_To (Prim_Table (J), Loc),
3932 Attribute_Name => Name_Address);
3934 New_Node := New_Reference_To (RTE (RE_Null_Address), Loc);
3937 Append_To (Prim_Ops_Aggr_List, New_Node);
3941 Make_Object_Declaration (Loc,
3942 Defining_Identifier => Predef_Prims,
3943 Aliased_Present => True,
3944 Constant_Present => Static_Dispatch_Tables,
3945 Object_Definition =>
3946 New_Reference_To (RTE (RE_Address_Array), Loc),
3947 Expression => Make_Aggregate (Loc,
3948 Expressions => Prim_Ops_Aggr_List)));
3951 Make_Attribute_Definition_Clause (Loc,
3952 Name => New_Reference_To (Predef_Prims, Loc),
3953 Chars => Name_Alignment,
3955 Make_Attribute_Reference (Loc,
3957 New_Reference_To (RTE (RE_Integer_Address), Loc),
3958 Attribute_Name => Name_Alignment)));
3962 -- Stage 1: Initialize the discriminant and the record components
3964 DT_Constr_List := New_List;
3965 DT_Aggr_List := New_List;
3967 -- Num_Prims. If the tagged type has no primitives we add a dummy
3968 -- slot whose address will be the tag of this type.
3971 New_Node := Make_Integer_Literal (Loc, 1);
3973 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
3976 Append_To (DT_Constr_List, New_Node);
3977 Append_To (DT_Aggr_List, New_Copy (New_Node));
3981 if RTE_Record_Component_Available (RE_Signature) then
3982 Append_To (DT_Aggr_List,
3983 New_Reference_To (RTE (RE_Primary_DT), Loc));
3988 if RTE_Record_Component_Available (RE_Tag_Kind) then
3989 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
3994 Append_To (DT_Aggr_List,
3995 Make_Attribute_Reference (Loc,
3996 Prefix => New_Reference_To (Predef_Prims, Loc),
3997 Attribute_Name => Name_Address));
4001 if RTE_Record_Component_Available (RE_Offset_To_Top) then
4002 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
4007 Append_To (DT_Aggr_List,
4008 Make_Attribute_Reference (Loc,
4009 Prefix => New_Reference_To (TSD, Loc),
4010 Attribute_Name => Name_Address));
4012 -- Stage 2: Initialize the table of primitive operations
4014 Prim_Ops_Aggr_List := New_List;
4017 Append_To (Prim_Ops_Aggr_List,
4018 New_Reference_To (RTE (RE_Null_Address), Loc));
4020 elsif not Static_Dispatch_Tables then
4021 for J in 1 .. Nb_Prim loop
4022 Append_To (Prim_Ops_Aggr_List,
4023 New_Reference_To (RTE (RE_Null_Address), Loc));
4028 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
4031 Prim_Elmt : Elmt_Id;
4034 Prim_Table := (others => Empty);
4035 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4036 while Present (Prim_Elmt) loop
4037 Prim := Node (Prim_Elmt);
4039 if Is_Imported (Prim)
4040 or else Present (Abstract_Interface_Alias (Prim))
4041 or else Is_Predefined_Dispatching_Operation (Prim)
4046 -- Traverse the list of aliased entities to handle
4047 -- renamings of predefined primitives.
4050 while Present (Alias (E)) loop
4054 if not Is_Predefined_Dispatching_Operation (E)
4055 and then not Is_Abstract_Subprogram (E)
4056 and then not Present (Abstract_Interface_Alias (E))
4059 (UI_To_Int (DT_Position (Prim)) <= Nb_Prim);
4061 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
4063 -- There is no need to set Has_Delayed_Freeze here
4064 -- because the analysis of 'Address and 'Code_Address
4065 -- takes care of it.
4069 Next_Elmt (Prim_Elmt);
4072 for J in Prim_Table'Range loop
4073 if Present (Prim_Table (J)) then
4075 Make_Attribute_Reference (Loc,
4076 Prefix => New_Reference_To (Prim_Table (J), Loc),
4077 Attribute_Name => Name_Address);
4079 New_Node := New_Reference_To (RTE (RE_Null_Address), Loc);
4082 Append_To (Prim_Ops_Aggr_List, New_Node);
4087 Append_To (DT_Aggr_List,
4088 Make_Aggregate (Loc,
4089 Expressions => Prim_Ops_Aggr_List));
4091 -- In case of locally defined tagged types we have already declared
4092 -- and uninitialized object for the dispatch table, which is now
4093 -- initialized by means of an assignment.
4097 Make_Assignment_Statement (Loc,
4098 Name => New_Reference_To (DT, Loc),
4099 Expression => Make_Aggregate (Loc,
4100 Expressions => DT_Aggr_List)));
4102 -- In case of library level tagged types we declare now the constant
4103 -- object containing the dispatch table.
4107 Make_Object_Declaration (Loc,
4108 Defining_Identifier => DT,
4109 Aliased_Present => True,
4110 Constant_Present => Static_Dispatch_Tables,
4111 Object_Definition =>
4112 Make_Subtype_Indication (Loc,
4113 Subtype_Mark => New_Reference_To
4114 (RTE (RE_Dispatch_Table_Wrapper), Loc),
4115 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4116 Constraints => DT_Constr_List)),
4117 Expression => Make_Aggregate (Loc,
4118 Expressions => DT_Aggr_List)));
4121 Make_Attribute_Definition_Clause (Loc,
4122 Name => New_Reference_To (DT, Loc),
4123 Chars => Name_Alignment,
4125 Make_Attribute_Reference (Loc,
4127 New_Reference_To (RTE (RE_Integer_Address), Loc),
4128 Attribute_Name => Name_Alignment)));
4131 Make_Object_Declaration (Loc,
4132 Defining_Identifier => DT_Ptr,
4133 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4134 Constant_Present => True,
4136 Unchecked_Convert_To (Generalized_Tag,
4137 Make_Attribute_Reference (Loc,
4139 Make_Selected_Component (Loc,
4140 Prefix => New_Reference_To (DT, Loc),
4143 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
4144 Attribute_Name => Name_Address))));
4148 -- Initialize the table of ancestor tags
4150 if not Is_Interface (Typ)
4151 and then not Is_CPP_Class (Typ)
4154 Make_Assignment_Statement (Loc,
4156 Make_Indexed_Component (Loc,
4158 Make_Selected_Component (Loc,
4160 New_Reference_To (TSD, Loc),
4163 (RTE_Record_Component (RE_Tags_Table), Loc)),
4165 New_List (Make_Integer_Literal (Loc, 0))),
4169 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)));
4172 if Static_Dispatch_Tables then
4175 -- If the ancestor is a CPP_Class type we inherit the dispatch tables
4176 -- in the init proc, and we don't need to fill them in here.
4178 elsif Is_CPP_Class (Etype (Typ)) then
4181 -- Otherwise we fill in the dispatch tables here
4184 if Typ = Etype (Typ)
4185 or else Is_CPP_Class (Etype (Typ))
4186 or else Is_Interface (Typ)
4188 Null_Parent_Tag := True;
4191 Unchecked_Convert_To (Generalized_Tag,
4192 Make_Integer_Literal (Loc, 0));
4194 Unchecked_Convert_To (Generalized_Tag,
4195 Make_Integer_Literal (Loc, 0));
4200 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc);
4203 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc);
4206 if Typ /= Etype (Typ)
4207 and then not Is_Interface (Typ)
4208 and then not Restriction_Active (No_Dispatching_Calls)
4210 -- Inherit the dispatch table
4212 if not Is_Interface (Etype (Typ)) then
4213 if not Null_Parent_Tag then
4215 Nb_Prims : constant Int :=
4216 UI_To_Int (DT_Entry_Count
4217 (First_Tag_Component (Etype (Typ))));
4219 Append_To (Elab_Code,
4220 Build_Inherit_Predefined_Prims (Loc,
4221 Old_Tag_Node => Old_Tag1,
4223 New_Reference_To (DT_Ptr, Loc)));
4225 if Nb_Prims /= 0 then
4226 Append_To (Elab_Code,
4227 Build_Inherit_Prims (Loc,
4228 Old_Tag_Node => Old_Tag2,
4229 New_Tag_Node => New_Reference_To (DT_Ptr, Loc),
4230 Num_Prims => Nb_Prims));
4236 -- Inherit the secondary dispatch tables of the ancestor
4238 if not Is_CPP_Class (Etype (Typ)) then
4240 Sec_DT_Ancestor : Elmt_Id :=
4243 (Access_Disp_Table (Etype (Typ))));
4244 Sec_DT_Typ : Elmt_Id :=
4247 (Access_Disp_Table (Typ)));
4249 procedure Copy_Secondary_DTs (Typ : Entity_Id);
4250 -- Local procedure required to climb through the ancestors
4251 -- and copy the contents of all their secondary dispatch
4254 ------------------------
4255 -- Copy_Secondary_DTs --
4256 ------------------------
4258 procedure Copy_Secondary_DTs (Typ : Entity_Id) is
4263 -- Climb to the ancestor (if any) handling private types
4265 if Present (Full_View (Etype (Typ))) then
4266 if Full_View (Etype (Typ)) /= Typ then
4267 Copy_Secondary_DTs (Full_View (Etype (Typ)));
4270 elsif Etype (Typ) /= Typ then
4271 Copy_Secondary_DTs (Etype (Typ));
4274 if Present (Abstract_Interfaces (Typ))
4275 and then not Is_Empty_Elmt_List
4276 (Abstract_Interfaces (Typ))
4278 Iface := First_Elmt (Abstract_Interfaces (Typ));
4279 E := First_Entity (Typ);
4281 and then Present (Node (Sec_DT_Ancestor))
4282 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
4284 if Is_Tag (E) and then Chars (E) /= Name_uTag then
4285 if not Is_Interface (Etype (Typ)) then
4287 -- Inherit the dispatch table
4290 Num_Prims : constant Int :=
4291 UI_To_Int (DT_Entry_Count (E));
4293 Append_To (Elab_Code,
4294 Build_Inherit_Predefined_Prims (Loc,
4296 Unchecked_Convert_To (RTE (RE_Tag),
4298 (Node (Sec_DT_Ancestor), Loc)),
4300 Unchecked_Convert_To (RTE (RE_Tag),
4302 (Node (Sec_DT_Typ), Loc))));
4304 if Num_Prims /= 0 then
4305 Append_To (Elab_Code,
4306 Build_Inherit_Prims (Loc,
4308 Unchecked_Convert_To
4311 (Node (Sec_DT_Ancestor),
4314 Unchecked_Convert_To
4317 (Node (Sec_DT_Typ), Loc)),
4318 Num_Prims => Num_Prims));
4323 Next_Elmt (Sec_DT_Ancestor);
4324 Next_Elmt (Sec_DT_Typ);
4331 end Copy_Secondary_DTs;
4334 if Present (Node (Sec_DT_Ancestor))
4335 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
4337 -- Handle private types
4339 if Present (Full_View (Typ)) then
4340 Copy_Secondary_DTs (Full_View (Typ));
4342 Copy_Secondary_DTs (Typ);
4350 -- Generate code to register the Tag in the External_Tag hash table for
4351 -- the pure Ada type only.
4353 -- Register_Tag (Dt_Ptr);
4355 -- Skip this action in the following cases:
4356 -- 1) if Register_Tag is not available.
4357 -- 2) in No_Run_Time mode.
4358 -- 3) if Typ is an abstract interface type (the secondary tags will
4359 -- be registered later in types implementing this interface type).
4360 -- 4) if Typ is not defined at the library level (this is required
4361 -- to avoid adding concurrency control to the hash table used
4362 -- by the run-time to register the tags).
4367 -- [ Register_Tag (Dt_Ptr); ]
4371 if not Is_Interface (Typ) then
4372 if not No_Run_Time_Mode
4373 and then not Is_Local_DT
4374 and then RTE_Available (RE_Register_Tag)
4376 Append_To (Elab_Code,
4377 Make_Procedure_Call_Statement (Loc,
4378 Name => New_Reference_To (RTE (RE_Register_Tag), Loc),
4379 Parameter_Associations =>
4380 New_List (New_Reference_To (DT_Ptr, Loc))));
4383 Append_To (Elab_Code,
4384 Make_Assignment_Statement (Loc,
4385 Name => New_Reference_To (No_Reg, Loc),
4386 Expression => New_Reference_To (Standard_False, Loc)));
4389 Make_Implicit_If_Statement (Typ,
4390 Condition => New_Reference_To (No_Reg, Loc),
4391 Then_Statements => Elab_Code));
4394 Analyze_List (Result, Suppress => All_Checks);
4398 -------------------------------------
4399 -- Make_Select_Specific_Data_Table --
4400 -------------------------------------
4402 function Make_Select_Specific_Data_Table
4403 (Typ : Entity_Id) return List_Id
4405 Assignments : constant List_Id := New_List;
4406 Loc : constant Source_Ptr := Sloc (Typ);
4408 Conc_Typ : Entity_Id;
4412 Prim_Als : Entity_Id;
4413 Prim_Elmt : Elmt_Id;
4417 type Examined_Array is array (Int range <>) of Boolean;
4419 function Find_Entry_Index (E : Entity_Id) return Uint;
4420 -- Given an entry, find its index in the visible declarations of the
4421 -- corresponding concurrent type of Typ.
4423 ----------------------
4424 -- Find_Entry_Index --
4425 ----------------------
4427 function Find_Entry_Index (E : Entity_Id) return Uint is
4428 Index : Uint := Uint_1;
4429 Subp_Decl : Entity_Id;
4433 and then not Is_Empty_List (Decls)
4435 Subp_Decl := First (Decls);
4436 while Present (Subp_Decl) loop
4437 if Nkind (Subp_Decl) = N_Entry_Declaration then
4438 if Defining_Identifier (Subp_Decl) = E then
4450 end Find_Entry_Index;
4452 -- Start of processing for Make_Select_Specific_Data_Table
4455 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
4457 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
4459 if Present (Corresponding_Concurrent_Type (Typ)) then
4460 Conc_Typ := Corresponding_Concurrent_Type (Typ);
4462 if Ekind (Conc_Typ) = E_Protected_Type then
4463 Decls := Visible_Declarations (Protected_Definition (
4464 Parent (Conc_Typ)));
4466 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
4467 Decls := Visible_Declarations (Task_Definition (
4468 Parent (Conc_Typ)));
4472 -- Count the non-predefined primitive operations
4474 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4475 while Present (Prim_Elmt) loop
4476 Prim := Node (Prim_Elmt);
4478 if not (Is_Predefined_Dispatching_Operation (Prim)
4479 or else Is_Predefined_Dispatching_Alias (Prim))
4481 Nb_Prim := Nb_Prim + 1;
4484 Next_Elmt (Prim_Elmt);
4488 Examined : Examined_Array (1 .. Nb_Prim) := (others => False);
4491 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4492 while Present (Prim_Elmt) loop
4493 Prim := Node (Prim_Elmt);
4495 -- Look for primitive overriding an abstract interface subprogram
4497 if Present (Abstract_Interface_Alias (Prim))
4498 and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
4500 Prim_Pos := DT_Position (Alias (Prim));
4501 pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
4502 Examined (UI_To_Int (Prim_Pos)) := True;
4504 -- Set the primitive operation kind regardless of subprogram
4506 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
4508 Append_To (Assignments,
4509 Make_Procedure_Call_Statement (Loc,
4510 Name => New_Reference_To (RTE (RE_Set_Prim_Op_Kind), Loc),
4511 Parameter_Associations => New_List (
4512 New_Reference_To (DT_Ptr, Loc),
4513 Make_Integer_Literal (Loc, Prim_Pos),
4514 Prim_Op_Kind (Alias (Prim), Typ))));
4516 -- Retrieve the root of the alias chain
4519 while Present (Alias (Prim_Als)) loop
4520 Prim_Als := Alias (Prim_Als);
4523 -- In the case of an entry wrapper, set the entry index
4525 if Ekind (Prim) = E_Procedure
4526 and then Is_Primitive_Wrapper (Prim_Als)
4527 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
4530 -- Ada.Tags.Set_Entry_Index
4531 -- (DT_Ptr, <position>, <index>);
4533 Append_To (Assignments,
4534 Make_Procedure_Call_Statement (Loc,
4536 New_Reference_To (RTE (RE_Set_Entry_Index), Loc),
4537 Parameter_Associations => New_List (
4538 New_Reference_To (DT_Ptr, Loc),
4539 Make_Integer_Literal (Loc, Prim_Pos),
4540 Make_Integer_Literal (Loc,
4541 Find_Entry_Index (Wrapped_Entity (Prim_Als))))));
4545 Next_Elmt (Prim_Elmt);
4550 end Make_Select_Specific_Data_Table;
4552 -----------------------------------
4553 -- Original_View_In_Visible_Part --
4554 -----------------------------------
4556 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
4557 Scop : constant Entity_Id := Scope (Typ);
4560 -- The scope must be a package
4562 if Ekind (Scop) /= E_Package
4563 and then Ekind (Scop) /= E_Generic_Package
4568 -- A type with a private declaration has a private view declared in
4569 -- the visible part.
4571 if Has_Private_Declaration (Typ) then
4575 return List_Containing (Parent (Typ)) =
4576 Visible_Declarations (Specification (Unit_Declaration_Node (Scop)));
4577 end Original_View_In_Visible_Part;
4583 function Prim_Op_Kind
4585 Typ : Entity_Id) return Node_Id
4587 Full_Typ : Entity_Id := Typ;
4588 Loc : constant Source_Ptr := Sloc (Prim);
4589 Prim_Op : Entity_Id;
4592 -- Retrieve the original primitive operation
4595 while Present (Alias (Prim_Op)) loop
4596 Prim_Op := Alias (Prim_Op);
4599 if Ekind (Typ) = E_Record_Type
4600 and then Present (Corresponding_Concurrent_Type (Typ))
4602 Full_Typ := Corresponding_Concurrent_Type (Typ);
4605 if Ekind (Prim_Op) = E_Function then
4607 -- Protected function
4609 if Ekind (Full_Typ) = E_Protected_Type then
4610 return New_Reference_To (RTE (RE_POK_Protected_Function), Loc);
4614 elsif Ekind (Full_Typ) = E_Task_Type then
4615 return New_Reference_To (RTE (RE_POK_Task_Function), Loc);
4620 return New_Reference_To (RTE (RE_POK_Function), Loc);
4624 pragma Assert (Ekind (Prim_Op) = E_Procedure);
4626 if Ekind (Full_Typ) = E_Protected_Type then
4630 if Is_Primitive_Wrapper (Prim_Op)
4631 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
4633 return New_Reference_To (RTE (RE_POK_Protected_Entry), Loc);
4635 -- Protected procedure
4638 return New_Reference_To (RTE (RE_POK_Protected_Procedure), Loc);
4641 elsif Ekind (Full_Typ) = E_Task_Type then
4645 if Is_Primitive_Wrapper (Prim_Op)
4646 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
4648 return New_Reference_To (RTE (RE_POK_Task_Entry), Loc);
4650 -- Task "procedure". These are the internally Expander-generated
4651 -- procedures (task body for instance).
4654 return New_Reference_To (RTE (RE_POK_Task_Procedure), Loc);
4657 -- Regular procedure
4660 return New_Reference_To (RTE (RE_POK_Procedure), Loc);
4665 ------------------------
4666 -- Register_Primitive --
4667 ------------------------
4669 procedure Register_Primitive
4675 Iface_Prim : Entity_Id;
4676 Iface_Typ : Entity_Id;
4677 Iface_DT_Ptr : Entity_Id;
4680 Thunk_Id : Entity_Id;
4681 Thunk_Code : Node_Id;
4685 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
4687 if not RTE_Available (RE_Tag) then
4691 if not Present (Abstract_Interface_Alias (Prim)) then
4692 Typ := Scope (DTC_Entity (Prim));
4693 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
4694 Pos := DT_Position (Prim);
4695 Tag := First_Tag_Component (Typ);
4697 if Is_Predefined_Dispatching_Operation (Prim)
4698 or else Is_Predefined_Dispatching_Alias (Prim)
4700 Insert_After (Ins_Nod,
4701 Build_Set_Predefined_Prim_Op_Address (Loc,
4702 Tag_Node => New_Reference_To (DT_Ptr, Loc),
4704 Address_Node => Make_Attribute_Reference (Loc,
4705 Prefix => New_Reference_To (Prim, Loc),
4706 Attribute_Name => Name_Address)));
4709 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
4711 Insert_After (Ins_Nod,
4712 Build_Set_Prim_Op_Address (Loc,
4714 Tag_Node => New_Reference_To (DT_Ptr, Loc),
4716 Address_Node => Make_Attribute_Reference (Loc,
4717 Prefix => New_Reference_To (Prim, Loc),
4718 Attribute_Name => Name_Address)));
4721 -- Ada 2005 (AI-251): Primitive associated with an interface type
4722 -- Generate the code of the thunk only if the interface type is not an
4723 -- immediate ancestor of Typ; otherwise the dispatch table associated
4724 -- with the interface is the primary dispatch table and we have nothing
4728 Typ := Find_Dispatching_Type (Alias (Prim));
4729 Iface_Typ := Find_Dispatching_Type (Abstract_Interface_Alias (Prim));
4731 pragma Assert (Is_Interface (Iface_Typ));
4733 Expand_Interface_Thunk
4735 Thunk_Alias => Alias (Prim),
4736 Thunk_Id => Thunk_Id,
4737 Thunk_Code => Thunk_Code);
4739 if not Is_Parent (Iface_Typ, Typ)
4740 and then Present (Thunk_Code)
4742 Insert_Action (Ins_Nod, Thunk_Code, Suppress => All_Checks);
4744 -- Generate the code necessary to fill the appropriate entry of
4745 -- the secondary dispatch table of Prim's controlling type with
4746 -- Thunk_Id's address.
4748 Iface_DT_Ptr := Find_Interface_ADT (Typ, Iface_Typ);
4749 Iface_Prim := Abstract_Interface_Alias (Prim);
4750 Pos := DT_Position (Iface_Prim);
4751 Tag := First_Tag_Component (Iface_Typ);
4753 if Is_Predefined_Dispatching_Operation (Prim)
4754 or else Is_Predefined_Dispatching_Alias (Prim)
4756 Insert_Action (Ins_Nod,
4757 Build_Set_Predefined_Prim_Op_Address (Loc,
4758 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
4761 Make_Attribute_Reference (Loc,
4762 Prefix => New_Reference_To (Thunk_Id, Loc),
4763 Attribute_Name => Name_Address)));
4765 pragma Assert (Pos /= Uint_0
4766 and then Pos <= DT_Entry_Count (Tag));
4768 Insert_Action (Ins_Nod,
4769 Build_Set_Prim_Op_Address (Loc,
4771 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
4773 Address_Node => Make_Attribute_Reference (Loc,
4775 New_Reference_To (Thunk_Id, Loc),
4776 Attribute_Name => Name_Address)));
4780 end Register_Primitive;
4782 -------------------------
4783 -- Set_All_DT_Position --
4784 -------------------------
4786 procedure Set_All_DT_Position (Typ : Entity_Id) is
4788 procedure Validate_Position (Prim : Entity_Id);
4789 -- Check that the position assignated to Prim is completely safe
4790 -- (it has not been assigned to a previously defined primitive
4791 -- operation of Typ)
4793 -----------------------
4794 -- Validate_Position --
4795 -----------------------
4797 procedure Validate_Position (Prim : Entity_Id) is
4802 -- Aliased primitives are safe
4804 if Present (Alias (Prim)) then
4808 Op_Elmt := First_Elmt (Primitive_Operations (Typ));
4809 while Present (Op_Elmt) loop
4810 Op := Node (Op_Elmt);
4812 -- No need to check against itself
4817 -- Primitive operations covering abstract interfaces are
4820 elsif Present (Abstract_Interface_Alias (Op)) then
4823 -- Predefined dispatching operations are completely safe. They
4824 -- are allocated at fixed positions in a separate table.
4826 elsif Is_Predefined_Dispatching_Operation (Op)
4827 or else Is_Predefined_Dispatching_Alias (Op)
4831 -- Aliased subprograms are safe
4833 elsif Present (Alias (Op)) then
4836 elsif DT_Position (Op) = DT_Position (Prim)
4837 and then not Is_Predefined_Dispatching_Operation (Op)
4838 and then not Is_Predefined_Dispatching_Operation (Prim)
4839 and then not Is_Predefined_Dispatching_Alias (Op)
4840 and then not Is_Predefined_Dispatching_Alias (Prim)
4843 -- Handle aliased subprograms
4852 if Present (Overridden_Operation (Op_1)) then
4853 Op_1 := Overridden_Operation (Op_1);
4854 elsif Present (Alias (Op_1)) then
4855 Op_1 := Alias (Op_1);
4863 if Present (Overridden_Operation (Op_2)) then
4864 Op_2 := Overridden_Operation (Op_2);
4865 elsif Present (Alias (Op_2)) then
4866 Op_2 := Alias (Op_2);
4872 if Op_1 /= Op_2 then
4873 raise Program_Error;
4878 Next_Elmt (Op_Elmt);
4880 end Validate_Position;
4884 Parent_Typ : constant Entity_Id := Etype (Typ);
4885 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
4886 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
4888 Adjusted : Boolean := False;
4889 Finalized : Boolean := False;
4895 Prim_Elmt : Elmt_Id;
4897 -- Start of processing for Set_All_DT_Position
4900 -- Set the DT_Position for each primitive operation. Perform some
4901 -- sanity checks to avoid to build completely inconsistant dispatch
4904 -- First stage: Set the DTC entity of all the primitive operations
4905 -- This is required to properly read the DT_Position attribute in
4906 -- the latter stages.
4908 Prim_Elmt := First_Prim;
4910 while Present (Prim_Elmt) loop
4911 Prim := Node (Prim_Elmt);
4913 -- Predefined primitives have a separate dispatch table
4915 if not (Is_Predefined_Dispatching_Operation (Prim)
4916 or else Is_Predefined_Dispatching_Alias (Prim))
4918 Count_Prim := Count_Prim + 1;
4921 Set_DTC_Entity_Value (Typ, Prim);
4923 -- Clear any previous value of the DT_Position attribute. In this
4924 -- way we ensure that the final position of all the primitives is
4925 -- stablished by the following stages of this algorithm.
4927 Set_DT_Position (Prim, No_Uint);
4929 Next_Elmt (Prim_Elmt);
4933 Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean
4934 := (others => False);
4937 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id);
4938 -- Called if Typ is declared in a nested package or a public child
4939 -- package to handle inherited primitives that were inherited by Typ
4940 -- in the visible part, but whose declaration was deferred because
4941 -- the parent operation was private and not visible at that point.
4943 procedure Set_Fixed_Prim (Pos : Nat);
4944 -- Sets to true an element of the Fixed_Prim table to indicate
4945 -- that this entry of the dispatch table of Typ is occupied.
4947 ------------------------------------------
4948 -- Handle_Inherited_Private_Subprograms --
4949 ------------------------------------------
4951 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id) is
4954 Op_Elmt_2 : Elmt_Id;
4955 Prim_Op : Entity_Id;
4956 Parent_Subp : Entity_Id;
4959 Op_List := Primitive_Operations (Typ);
4961 Op_Elmt := First_Elmt (Op_List);
4962 while Present (Op_Elmt) loop
4963 Prim_Op := Node (Op_Elmt);
4965 -- Search primitives that are implicit operations with an
4966 -- internal name whose parent operation has a normal name.
4968 if Present (Alias (Prim_Op))
4969 and then Find_Dispatching_Type (Alias (Prim_Op)) /= Typ
4970 and then not Comes_From_Source (Prim_Op)
4971 and then Is_Internal_Name (Chars (Prim_Op))
4972 and then not Is_Internal_Name (Chars (Alias (Prim_Op)))
4974 Parent_Subp := Alias (Prim_Op);
4976 -- Check if the type has an explicit overriding for this
4979 Op_Elmt_2 := Next_Elmt (Op_Elmt);
4980 while Present (Op_Elmt_2) loop
4981 if Chars (Node (Op_Elmt_2)) = Chars (Parent_Subp)
4982 and then Type_Conformant (Prim_Op, Node (Op_Elmt_2))
4984 Set_DT_Position (Prim_Op, DT_Position (Parent_Subp));
4985 Set_DT_Position (Node (Op_Elmt_2),
4986 DT_Position (Parent_Subp));
4987 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim_Op)));
4989 goto Next_Primitive;
4992 Next_Elmt (Op_Elmt_2);
4997 Next_Elmt (Op_Elmt);
4999 end Handle_Inherited_Private_Subprograms;
5001 --------------------
5002 -- Set_Fixed_Prim --
5003 --------------------
5005 procedure Set_Fixed_Prim (Pos : Nat) is
5007 pragma Assert (Pos >= 0 and then Pos <= Count_Prim);
5008 Fixed_Prim (Pos) := True;
5010 when Constraint_Error =>
5011 raise Program_Error;
5015 -- In case of nested packages and public child package it may be
5016 -- necessary a special management on inherited subprograms so that
5017 -- the dispatch table is properly filled.
5019 if Ekind (Scope (Scope (Typ))) = E_Package
5020 and then Scope (Scope (Typ)) /= Standard_Standard
5021 and then ((Is_Derived_Type (Typ) and then not Is_Private_Type (Typ))
5023 (Nkind (Parent (Typ)) = N_Private_Extension_Declaration
5024 and then Is_Generic_Type (Typ)))
5025 and then In_Open_Scopes (Scope (Etype (Typ)))
5026 and then Typ = Base_Type (Typ)
5028 Handle_Inherited_Private_Subprograms (Typ);
5031 -- Second stage: Register fixed entries
5034 Prim_Elmt := First_Prim;
5035 while Present (Prim_Elmt) loop
5036 Prim := Node (Prim_Elmt);
5038 -- Predefined primitives have a separate table and all its
5039 -- entries are at predefined fixed positions.
5041 if Is_Predefined_Dispatching_Operation (Prim) then
5042 Set_DT_Position (Prim, Default_Prim_Op_Position (Prim));
5044 elsif Is_Predefined_Dispatching_Alias (Prim) then
5046 while Present (Alias (E)) loop
5050 Set_DT_Position (Prim, Default_Prim_Op_Position (E));
5052 -- Overriding primitives of ancestor abstract interfaces
5054 elsif Present (Abstract_Interface_Alias (Prim))
5056 (Find_Dispatching_Type
5057 (Abstract_Interface_Alias (Prim)),
5060 pragma Assert (DT_Position (Prim) = No_Uint
5061 and then Present (DTC_Entity
5062 (Abstract_Interface_Alias (Prim))));
5064 E := Abstract_Interface_Alias (Prim);
5065 Set_DT_Position (Prim, DT_Position (E));
5068 (DT_Position (Alias (Prim)) = No_Uint
5069 or else DT_Position (Alias (Prim)) = DT_Position (E));
5070 Set_DT_Position (Alias (Prim), DT_Position (E));
5071 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));
5073 -- Overriding primitives must use the same entry as the
5074 -- overriden primitive.
5076 elsif not Present (Abstract_Interface_Alias (Prim))
5077 and then Present (Alias (Prim))
5078 and then Find_Dispatching_Type (Alias (Prim)) /= Typ
5080 (Find_Dispatching_Type (Alias (Prim)), Typ)
5081 and then Present (DTC_Entity (Alias (Prim)))
5084 Set_DT_Position (Prim, DT_Position (E));
5086 if not Is_Predefined_Dispatching_Alias (E) then
5087 Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
5091 Next_Elmt (Prim_Elmt);
5094 -- Third stage: Fix the position of all the new primitives
5095 -- Entries associated with primitives covering interfaces
5096 -- are handled in a latter round.
5098 Prim_Elmt := First_Prim;
5099 while Present (Prim_Elmt) loop
5100 Prim := Node (Prim_Elmt);
5102 -- Skip primitives previously set entries
5104 if DT_Position (Prim) /= No_Uint then
5107 -- Primitives covering interface primitives are handled later
5109 elsif Present (Abstract_Interface_Alias (Prim)) then
5113 -- Take the next available position in the DT
5116 Nb_Prim := Nb_Prim + 1;
5117 pragma Assert (Nb_Prim <= Count_Prim);
5118 exit when not Fixed_Prim (Nb_Prim);
5121 Set_DT_Position (Prim, UI_From_Int (Nb_Prim));
5122 Set_Fixed_Prim (Nb_Prim);
5125 Next_Elmt (Prim_Elmt);
5129 -- Fourth stage: Complete the decoration of primitives covering
5130 -- interfaces (that is, propagate the DT_Position attribute
5131 -- from the aliased primitive)
5133 Prim_Elmt := First_Prim;
5134 while Present (Prim_Elmt) loop
5135 Prim := Node (Prim_Elmt);
5137 if DT_Position (Prim) = No_Uint
5138 and then Present (Abstract_Interface_Alias (Prim))
5140 pragma Assert (Present (Alias (Prim))
5141 and then Find_Dispatching_Type (Alias (Prim)) = Typ);
5143 -- Check if this entry will be placed in the primary DT
5145 if Is_Parent (Find_Dispatching_Type
5146 (Abstract_Interface_Alias (Prim)),
5149 pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
5150 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
5152 -- Otherwise it will be placed in the secondary DT
5156 (DT_Position (Abstract_Interface_Alias (Prim)) /= No_Uint);
5157 Set_DT_Position (Prim,
5158 DT_Position (Abstract_Interface_Alias (Prim)));
5162 Next_Elmt (Prim_Elmt);
5165 -- Generate listing showing the contents of the dispatch tables.
5166 -- This action is done before some further static checks because
5167 -- in case of critical errors caused by a wrong dispatch table
5168 -- we need to see the contents of such table.
5170 if Debug_Flag_ZZ then
5174 -- Final stage: Ensure that the table is correct plus some further
5175 -- verifications concerning the primitives.
5177 Prim_Elmt := First_Prim;
5179 while Present (Prim_Elmt) loop
5180 Prim := Node (Prim_Elmt);
5182 -- At this point all the primitives MUST have a position
5183 -- in the dispatch table
5185 if DT_Position (Prim) = No_Uint then
5186 raise Program_Error;
5189 -- Calculate real size of the dispatch table
5191 if not (Is_Predefined_Dispatching_Operation (Prim)
5192 or else Is_Predefined_Dispatching_Alias (Prim))
5193 and then UI_To_Int (DT_Position (Prim)) > DT_Length
5195 DT_Length := UI_To_Int (DT_Position (Prim));
5198 -- Ensure that the asignated position to non-predefined
5199 -- dispatching operations in the dispatch table is correct.
5201 if not (Is_Predefined_Dispatching_Operation (Prim)
5202 or else Is_Predefined_Dispatching_Alias (Prim))
5204 Validate_Position (Prim);
5207 if Chars (Prim) = Name_Finalize then
5211 if Chars (Prim) = Name_Adjust then
5215 -- An abstract operation cannot be declared in the private part
5216 -- for a visible abstract type, because it could never be over-
5217 -- ridden. For explicit declarations this is checked at the
5218 -- point of declaration, but for inherited operations it must
5219 -- be done when building the dispatch table.
5221 -- Ada 2005 (AI-251): Hidden entities associated with abstract
5222 -- interface primitives are not taken into account because the
5223 -- check is done with the aliased primitive.
5225 if Is_Abstract_Type (Typ)
5226 and then Is_Abstract_Subprogram (Prim)
5227 and then Present (Alias (Prim))
5228 and then not Present (Abstract_Interface_Alias (Prim))
5229 and then Is_Derived_Type (Typ)
5230 and then In_Private_Part (Current_Scope)
5232 List_Containing (Parent (Prim)) =
5233 Private_Declarations
5234 (Specification (Unit_Declaration_Node (Current_Scope)))
5235 and then Original_View_In_Visible_Part (Typ)
5237 -- We exclude Input and Output stream operations because
5238 -- Limited_Controlled inherits useless Input and Output
5239 -- stream operations from Root_Controlled, which can
5240 -- never be overridden.
5242 if not Is_TSS (Prim, TSS_Stream_Input)
5244 not Is_TSS (Prim, TSS_Stream_Output)
5247 ("abstract inherited private operation&" &
5248 " must be overridden ('R'M 3.9.3(10))",
5249 Parent (Typ), Prim);
5253 Next_Elmt (Prim_Elmt);
5258 if Is_Controlled (Typ) then
5259 if not Finalized then
5261 ("controlled type has no explicit Finalize method?", Typ);
5263 elsif not Adjusted then
5265 ("controlled type has no explicit Adjust method?", Typ);
5269 -- Set the final size of the Dispatch Table
5271 Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));
5273 -- The derived type must have at least as many components as its parent
5274 -- (for root types, the Etype points back to itself and the test cannot
5277 if DT_Entry_Count (The_Tag) <
5278 DT_Entry_Count (First_Tag_Component (Parent_Typ))
5280 raise Program_Error;
5282 end Set_All_DT_Position;
5284 -----------------------------
5285 -- Set_Default_Constructor --
5286 -----------------------------
5288 procedure Set_Default_Constructor (Typ : Entity_Id) is
5295 -- Look for the default constructor entity. For now only the
5296 -- default constructor has the flag Is_Constructor.
5298 E := Next_Entity (Typ);
5300 and then (Ekind (E) /= E_Function or else not Is_Constructor (E))
5305 -- Create the init procedure
5309 Init := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
5310 Param := Make_Defining_Identifier (Loc, Name_X);
5313 Make_Subprogram_Declaration (Loc,
5314 Make_Procedure_Specification (Loc,
5315 Defining_Unit_Name => Init,
5316 Parameter_Specifications => New_List (
5317 Make_Parameter_Specification (Loc,
5318 Defining_Identifier => Param,
5319 Parameter_Type => New_Reference_To (Typ, Loc))))));
5321 Set_Init_Proc (Typ, Init);
5322 Set_Is_Imported (Init);
5323 Set_Interface_Name (Init, Interface_Name (E));
5324 Set_Convention (Init, Convention_C);
5325 Set_Is_Public (Init);
5326 Set_Has_Completion (Init);
5328 -- If there are no constructors, mark the type as abstract since we
5329 -- won't be able to declare objects of that type.
5332 Set_Is_Abstract_Type (Typ);
5334 end Set_Default_Constructor;
5336 --------------------------
5337 -- Set_DTC_Entity_Value --
5338 --------------------------
5340 procedure Set_DTC_Entity_Value
5341 (Tagged_Type : Entity_Id;
5345 if Present (Abstract_Interface_Alias (Prim))
5346 and then Is_Interface
5347 (Find_Dispatching_Type
5348 (Abstract_Interface_Alias (Prim)))
5350 Set_DTC_Entity (Prim,
5353 Iface => Find_Dispatching_Type
5354 (Abstract_Interface_Alias (Prim))));
5356 Set_DTC_Entity (Prim,
5357 First_Tag_Component (Tagged_Type));
5359 end Set_DTC_Entity_Value;
5365 function Tagged_Kind (T : Entity_Id) return Node_Id is
5366 Conc_Typ : Entity_Id;
5367 Loc : constant Source_Ptr := Sloc (T);
5371 (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));
5375 if Is_Abstract_Type (T) then
5376 if Is_Limited_Record (T) then
5377 return New_Reference_To (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
5379 return New_Reference_To (RTE (RE_TK_Abstract_Tagged), Loc);
5384 elsif Is_Concurrent_Record_Type (T) then
5385 Conc_Typ := Corresponding_Concurrent_Type (T);
5387 if Ekind (Conc_Typ) = E_Protected_Type then
5388 return New_Reference_To (RTE (RE_TK_Protected), Loc);
5390 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
5391 return New_Reference_To (RTE (RE_TK_Task), Loc);
5394 -- Regular tagged kinds
5397 if Is_Limited_Record (T) then
5398 return New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc);
5400 return New_Reference_To (RTE (RE_TK_Tagged), Loc);
5409 procedure Write_DT (Typ : Entity_Id) is
5414 -- Protect this procedure against wrong usage. Required because it will
5415 -- be used directly from GDB
5417 if not (Typ in First_Node_Id .. Last_Node_Id)
5418 or else not Is_Tagged_Type (Typ)
5420 Write_Str ("wrong usage: Write_DT must be used with tagged types");
5425 Write_Int (Int (Typ));
5427 Write_Name (Chars (Typ));
5429 if Is_Interface (Typ) then
5430 Write_Str (" is interface");
5435 Elmt := First_Elmt (Primitive_Operations (Typ));
5436 while Present (Elmt) loop
5437 Prim := Node (Elmt);
5440 -- Indicate if this primitive will be allocated in the primary
5441 -- dispatch table or in a secondary dispatch table associated
5442 -- with an abstract interface type
5444 if Present (DTC_Entity (Prim)) then
5445 if Etype (DTC_Entity (Prim)) = RTE (RE_Tag) then
5452 -- Output the node of this primitive operation and its name
5454 Write_Int (Int (Prim));
5457 if Is_Predefined_Dispatching_Operation (Prim) then
5458 Write_Str ("(predefined) ");
5461 Write_Name (Chars (Prim));
5463 -- Indicate if this primitive has an aliased primitive
5465 if Present (Alias (Prim)) then
5466 Write_Str (" (alias = ");
5467 Write_Int (Int (Alias (Prim)));
5469 -- If the DTC_Entity attribute is already set we can also output
5470 -- the name of the interface covered by this primitive (if any)
5472 if Present (DTC_Entity (Alias (Prim)))
5473 and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
5475 Write_Str (" from interface ");
5476 Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
5479 if Present (Abstract_Interface_Alias (Prim)) then
5480 Write_Str (", AI_Alias of ");
5481 Write_Name (Chars (Scope (DTC_Entity
5482 (Abstract_Interface_Alias (Prim)))));
5484 Write_Int (Int (Abstract_Interface_Alias (Prim)));
5490 -- Display the final position of this primitive in its associated
5491 -- (primary or secondary) dispatch table
5493 if Present (DTC_Entity (Prim))
5494 and then DT_Position (Prim) /= No_Uint
5496 Write_Str (" at #");
5497 Write_Int (UI_To_Int (DT_Position (Prim)));
5500 if Is_Abstract_Subprogram (Prim) then
5501 Write_Str (" is abstract;");
5503 -- Check if this is a null primitive
5505 elsif Comes_From_Source (Prim)
5506 and then Ekind (Prim) = E_Procedure
5507 and then Null_Present (Parent (Prim))
5509 Write_Str (" is null;");