1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2006, 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;
40 with Nlists; use Nlists;
41 with Nmake; use Nmake;
42 with Namet; use Namet;
44 with Output; use Output;
45 with Restrict; use Restrict;
46 with Rident; use Rident;
47 with Rtsfind; use Rtsfind;
49 with Sem_Disp; use Sem_Disp;
50 with Sem_Res; use Sem_Res;
51 with Sem_Type; use Sem_Type;
52 with Sem_Util; use Sem_Util;
53 with Sinfo; use Sinfo;
54 with Snames; use Snames;
55 with Stand; use Stand;
56 with Tbuild; use Tbuild;
57 with Uintp; use Uintp;
59 package body Exp_Disp is
61 --------------------------------
62 -- Select_Expansion_Utilities --
63 --------------------------------
65 -- The following package contains helper routines used in the expansion of
66 -- dispatching asynchronous, conditional and timed selects.
68 package Select_Expansion_Utilities is
73 -- B : out Communication_Block
79 -- C : out Prim_Op_Kind
81 procedure Build_Common_Dispatching_Select_Statements
86 -- Ada 2005 (AI-345): Generate statements that are common between
87 -- asynchronous, conditional and timed select expansion.
113 end Select_Expansion_Utilities;
115 package body Select_Expansion_Utilities is
127 Make_Parameter_Specification (Loc,
128 Defining_Identifier =>
129 Make_Defining_Identifier (Loc, Name_uB),
131 New_Reference_To (RTE (RE_Communication_Block), Loc),
132 Out_Present => True));
145 Make_Parameter_Specification (Loc,
146 Defining_Identifier =>
147 Make_Defining_Identifier (Loc, Name_uC),
149 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
150 Out_Present => True));
153 ------------------------------------------------
154 -- Build_Common_Dispatching_Select_Statements --
155 ------------------------------------------------
157 procedure Build_Common_Dispatching_Select_Statements
165 -- C := get_prim_op_kind (tag! (<type>VP), S);
167 -- where C is the out parameter capturing the call kind and S is the
168 -- dispatch table slot number.
171 Make_Assignment_Statement (Loc,
173 Make_Identifier (Loc, Name_uC),
175 Make_DT_Access_Action (Typ,
180 Unchecked_Convert_To (RTE (RE_Tag),
181 New_Reference_To (DT_Ptr, Loc)),
182 Make_Identifier (Loc, Name_uS)))));
186 -- if C = POK_Procedure
187 -- or else C = POK_Protected_Procedure
188 -- or else C = POK_Task_Procedure;
193 -- where F is the out parameter capturing the status of a potential
197 Make_If_Statement (Loc,
204 Make_Identifier (Loc, Name_uC),
206 New_Reference_To (RTE (RE_POK_Procedure), Loc)),
212 Make_Identifier (Loc, Name_uC),
214 New_Reference_To (RTE (
215 RE_POK_Protected_Procedure), Loc)),
219 Make_Identifier (Loc, Name_uC),
221 New_Reference_To (RTE (
222 RE_POK_Task_Procedure), Loc)))),
226 Make_Assignment_Statement (Loc,
227 Name => Make_Identifier (Loc, Name_uF),
228 Expression => New_Reference_To (Standard_True, Loc)),
230 Make_Return_Statement (Loc))));
231 end Build_Common_Dispatching_Select_Statements;
243 Make_Parameter_Specification (Loc,
244 Defining_Identifier =>
245 Make_Defining_Identifier (Loc, Name_uF),
247 New_Reference_To (Standard_Boolean, Loc),
248 Out_Present => True));
261 Make_Parameter_Specification (Loc,
262 Defining_Identifier =>
263 Make_Defining_Identifier (Loc, Name_uP),
265 New_Reference_To (RTE (RE_Address), Loc)));
278 Make_Parameter_Specification (Loc,
279 Defining_Identifier =>
280 Make_Defining_Identifier (Loc, Name_uS),
282 New_Reference_To (Standard_Integer, Loc)));
296 Make_Parameter_Specification (Loc,
297 Defining_Identifier =>
298 Make_Defining_Identifier (Loc, Name_uT),
300 New_Reference_To (Typ, Loc),
302 Out_Present => True));
304 end Select_Expansion_Utilities;
306 package SEU renames Select_Expansion_Utilities;
308 Ada_Actions : constant array (DT_Access_Action) of RE_Id :=
309 (IW_Membership => RE_IW_Membership,
310 Get_Entry_Index => RE_Get_Entry_Index,
311 Get_Prim_Op_Kind => RE_Get_Prim_Op_Kind,
312 Get_Tagged_Kind => RE_Get_Tagged_Kind,
313 Register_Interface_Tag => RE_Register_Interface_Tag,
314 Register_Tag => RE_Register_Tag,
315 Set_Entry_Index => RE_Set_Entry_Index,
316 Set_Offset_Index => RE_Set_Offset_Index,
317 Set_OSD => RE_Set_OSD,
318 Set_Prim_Op_Kind => RE_Set_Prim_Op_Kind,
319 Set_Signature => RE_Set_Signature,
320 Set_SSD => RE_Set_SSD,
321 Set_Tagged_Kind => RE_Set_Tagged_Kind);
323 Action_Is_Proc : constant array (DT_Access_Action) of Boolean :=
324 (IW_Membership => False,
325 Get_Entry_Index => False,
326 Get_Prim_Op_Kind => False,
327 Get_Tagged_Kind => False,
328 Register_Interface_Tag => True,
329 Register_Tag => True,
330 Set_Entry_Index => True,
331 Set_Offset_Index => True,
333 Set_Prim_Op_Kind => True,
334 Set_Signature => True,
336 Set_Tagged_Kind => True);
338 Action_Nb_Arg : constant array (DT_Access_Action) of Int :=
340 Get_Entry_Index => 2,
341 Get_Prim_Op_Kind => 2,
342 Get_Tagged_Kind => 1,
343 Register_Interface_Tag => 3,
345 Set_Entry_Index => 3,
346 Set_Offset_Index => 3,
348 Set_Prim_Op_Kind => 3,
351 Set_Tagged_Kind => 2);
353 function Default_Prim_Op_Position (E : Entity_Id) return Uint;
354 -- Ada 2005 (AI-251): Returns the fixed position in the dispatch table
355 -- of the default primitive operations.
357 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean;
358 -- Returns true if Prim is not a predefined dispatching primitive but it is
359 -- an alias of a predefined dispatching primitive (ie. through a renaming)
361 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean;
362 -- Check if the type has a private view or if the public view appears
363 -- in the visible part of a package spec.
365 function Prim_Op_Kind
367 Typ : Entity_Id) return Node_Id;
368 -- Ada 2005 (AI-345): Determine the primitive operation kind of Prim
369 -- according to its type Typ. Return a reference to an RE_Prim_Op_Kind
370 -- enumeration value.
372 function Tagged_Kind (T : Entity_Id) return Node_Id;
373 -- Ada 2005 (AI-345): Determine the tagged kind of T and return a reference
374 -- to an RE_Tagged_Kind enumeration value.
376 ------------------------------
377 -- Default_Prim_Op_Position --
378 ------------------------------
380 function Default_Prim_Op_Position (E : Entity_Id) return Uint is
381 TSS_Name : TSS_Name_Type;
384 Get_Name_String (Chars (E));
387 (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
389 if Chars (E) = Name_uSize then
392 elsif Chars (E) = Name_uAlignment then
395 elsif TSS_Name = TSS_Stream_Read then
398 elsif TSS_Name = TSS_Stream_Write then
401 elsif TSS_Name = TSS_Stream_Input then
404 elsif TSS_Name = TSS_Stream_Output then
407 elsif Chars (E) = Name_Op_Eq then
410 elsif Chars (E) = Name_uAssign then
413 elsif TSS_Name = TSS_Deep_Adjust then
416 elsif TSS_Name = TSS_Deep_Finalize then
419 elsif Ada_Version >= Ada_05 then
420 if Chars (E) = Name_uDisp_Asynchronous_Select then
423 elsif Chars (E) = Name_uDisp_Conditional_Select then
426 elsif Chars (E) = Name_uDisp_Get_Prim_Op_Kind then
429 elsif Chars (E) = Name_uDisp_Get_Task_Id then
432 elsif Chars (E) = Name_uDisp_Timed_Select then
438 end Default_Prim_Op_Position;
440 -----------------------------
441 -- Expand_Dispatching_Call --
442 -----------------------------
444 procedure Expand_Dispatching_Call (Call_Node : Node_Id) is
445 Loc : constant Source_Ptr := Sloc (Call_Node);
446 Call_Typ : constant Entity_Id := Etype (Call_Node);
448 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
449 Param_List : constant List_Id := Parameter_Associations (Call_Node);
454 New_Call_Name : Node_Id;
455 New_Params : List_Id := No_List;
458 Subp_Ptr_Typ : Entity_Id;
459 Subp_Typ : Entity_Id;
461 Eq_Prim_Op : Entity_Id := Empty;
462 Controlling_Tag : Node_Id;
464 function New_Value (From : Node_Id) return Node_Id;
465 -- From is the original Expression. New_Value is equivalent to a call
466 -- to Duplicate_Subexpr with an explicit dereference when From is an
473 function New_Value (From : Node_Id) return Node_Id is
474 Res : constant Node_Id := Duplicate_Subexpr (From);
476 if Is_Access_Type (Etype (From)) then
478 Make_Explicit_Dereference (Sloc (From),
485 -- Start of processing for Expand_Dispatching_Call
488 -- Expand_Dispatching_Call is called directly from the semantics,
489 -- so we need a check to see whether expansion is active before
490 -- proceeding. In addition, there is no need to expand the call
491 -- if we are compiling under restriction No_Dispatching_Calls;
492 -- the semantic analyzer has previously notified the violation
493 -- of this restriction.
495 if not Expander_Active
496 or else Restriction_Active (No_Dispatching_Calls)
501 -- Set subprogram. If this is an inherited operation that was
502 -- overridden, the body that is being called is its alias.
504 Subp := Entity (Name (Call_Node));
506 if Present (Alias (Subp))
507 and then Is_Inherited_Operation (Subp)
508 and then No (DTC_Entity (Subp))
510 Subp := Alias (Subp);
513 -- Definition of the class-wide type and the tagged type
515 -- If the controlling argument is itself a tag rather than a tagged
516 -- object, then use the class-wide type associated with the subprogram's
517 -- controlling type. This case can occur when a call to an inherited
518 -- primitive has an actual that originated from a default parameter
519 -- given by a tag-indeterminate call and when there is no other
520 -- controlling argument providing the tag (AI-239 requires dispatching).
521 -- This capability of dispatching directly by tag is also needed by the
522 -- implementation of AI-260 (for the generic dispatching constructors).
524 if Etype (Ctrl_Arg) = RTE (RE_Tag)
525 or else (RTE_Available (RE_Interface_Tag)
526 and then Etype (Ctrl_Arg) = RTE (RE_Interface_Tag))
528 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
530 elsif Is_Access_Type (Etype (Ctrl_Arg)) then
531 CW_Typ := Designated_Type (Etype (Ctrl_Arg));
534 CW_Typ := Etype (Ctrl_Arg);
537 Typ := Root_Type (CW_Typ);
539 if Ekind (Typ) = E_Incomplete_Type then
540 Typ := Non_Limited_View (Typ);
543 if not Is_Limited_Type (Typ) then
544 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
547 -- Dispatching call to C++ primitive. Create a new parameter list
548 -- with no tag checks.
550 if Is_CPP_Class (Typ) then
551 New_Params := New_List;
552 Param := First_Actual (Call_Node);
553 while Present (Param) loop
554 Append_To (New_Params, Relocate_Node (Param));
558 -- Dispatching call to Ada primitive
560 elsif Present (Param_List) then
562 -- Generate the Tag checks when appropriate
564 New_Params := New_List;
565 Param := First_Actual (Call_Node);
566 while Present (Param) loop
568 -- No tag check with itself
570 if Param = Ctrl_Arg then
571 Append_To (New_Params,
572 Duplicate_Subexpr_Move_Checks (Param));
574 -- No tag check for parameter whose type is neither tagged nor
575 -- access to tagged (for access parameters)
577 elsif No (Find_Controlling_Arg (Param)) then
578 Append_To (New_Params, Relocate_Node (Param));
580 -- No tag check for function dispatching on result if the
581 -- Tag given by the context is this one
583 elsif Find_Controlling_Arg (Param) = Ctrl_Arg then
584 Append_To (New_Params, Relocate_Node (Param));
586 -- "=" is the only dispatching operation allowed to get
587 -- operands with incompatible tags (it just returns false).
588 -- We use Duplicate_Subexpr_Move_Checks instead of calling
589 -- Relocate_Node because the value will be duplicated to
592 elsif Subp = Eq_Prim_Op then
593 Append_To (New_Params,
594 Duplicate_Subexpr_Move_Checks (Param));
596 -- No check in presence of suppress flags
598 elsif Tag_Checks_Suppressed (Etype (Param))
599 or else (Is_Access_Type (Etype (Param))
600 and then Tag_Checks_Suppressed
601 (Designated_Type (Etype (Param))))
603 Append_To (New_Params, Relocate_Node (Param));
605 -- Optimization: no tag checks if the parameters are identical
607 elsif Is_Entity_Name (Param)
608 and then Is_Entity_Name (Ctrl_Arg)
609 and then Entity (Param) = Entity (Ctrl_Arg)
611 Append_To (New_Params, Relocate_Node (Param));
613 -- Now we need to generate the Tag check
616 -- Generate code for tag equality check
617 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
619 Insert_Action (Ctrl_Arg,
620 Make_Implicit_If_Statement (Call_Node,
624 Make_Selected_Component (Loc,
625 Prefix => New_Value (Ctrl_Arg),
628 (First_Tag_Component (Typ), Loc)),
631 Make_Selected_Component (Loc,
633 Unchecked_Convert_To (Typ, New_Value (Param)),
636 (First_Tag_Component (Typ), Loc))),
639 New_List (New_Constraint_Error (Loc))));
641 Append_To (New_Params, Relocate_Node (Param));
648 -- Generate the appropriate subprogram pointer type
650 if Etype (Subp) = Typ then
653 Res_Typ := Etype (Subp);
656 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
657 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
658 Set_Etype (Subp_Typ, Res_Typ);
659 Init_Size_Align (Subp_Ptr_Typ);
660 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
662 -- Create a new list of parameters which is a copy of the old formal
663 -- list including the creation of a new set of matching entities.
666 Old_Formal : Entity_Id := First_Formal (Subp);
667 New_Formal : Entity_Id;
671 if Present (Old_Formal) then
672 New_Formal := New_Copy (Old_Formal);
673 Set_First_Entity (Subp_Typ, New_Formal);
674 Param := First_Actual (Call_Node);
677 Set_Scope (New_Formal, Subp_Typ);
679 -- Change all the controlling argument types to be class-wide
680 -- to avoid a recursion in dispatching.
682 if Is_Controlling_Formal (New_Formal) then
683 Set_Etype (New_Formal, Etype (Param));
686 if Is_Itype (Etype (New_Formal)) then
687 Extra := New_Copy (Etype (New_Formal));
689 if Ekind (Extra) = E_Record_Subtype
690 or else Ekind (Extra) = E_Class_Wide_Subtype
692 Set_Cloned_Subtype (Extra, Etype (New_Formal));
695 Set_Etype (New_Formal, Extra);
696 Set_Scope (Etype (New_Formal), Subp_Typ);
700 Next_Formal (Old_Formal);
701 exit when No (Old_Formal);
703 Set_Next_Entity (New_Formal, New_Copy (Old_Formal));
704 Next_Entity (New_Formal);
708 Set_Next_Entity (New_Formal, Empty);
709 Set_Last_Entity (Subp_Typ, Extra);
711 -- Copy extra formals
713 New_Formal := First_Entity (Subp_Typ);
714 while Present (New_Formal) loop
715 if Present (Extra_Constrained (New_Formal)) then
716 Set_Extra_Formal (Extra,
717 New_Copy (Extra_Constrained (New_Formal)));
718 Extra := Extra_Formal (Extra);
719 Set_Extra_Constrained (New_Formal, Extra);
721 elsif Present (Extra_Accessibility (New_Formal)) then
722 Set_Extra_Formal (Extra,
723 New_Copy (Extra_Accessibility (New_Formal)));
724 Extra := Extra_Formal (Extra);
725 Set_Extra_Accessibility (New_Formal, Extra);
728 Next_Formal (New_Formal);
733 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
734 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
736 -- If the controlling argument is a value of type Ada.Tag or an abstract
737 -- interface class-wide type then use it directly. Otherwise, the tag
738 -- must be extracted from the controlling object.
740 if Etype (Ctrl_Arg) = RTE (RE_Tag)
741 or else (RTE_Available (RE_Interface_Tag)
742 and then Etype (Ctrl_Arg) = RTE (RE_Interface_Tag))
744 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
746 -- Extract the tag from an unchecked type conversion. Done to avoid
747 -- the expansion of additional code just to obtain the value of such
748 -- tag because the current management of interface type conversions
749 -- generates in some cases this unchecked type conversion with the
750 -- tag of the object (see Expand_Interface_Conversion).
752 elsif Nkind (Ctrl_Arg) = N_Unchecked_Type_Conversion
754 (Etype (Expression (Ctrl_Arg)) = RTE (RE_Tag)
756 (RTE_Available (RE_Interface_Tag)
758 Etype (Expression (Ctrl_Arg)) = RTE (RE_Interface_Tag)))
760 Controlling_Tag := Duplicate_Subexpr (Expression (Ctrl_Arg));
762 -- Ada 2005 (AI-251): Abstract interface class-wide type
764 elsif Is_Interface (Etype (Ctrl_Arg))
765 and then Is_Class_Wide_Type (Etype (Ctrl_Arg))
767 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
771 Make_Selected_Component (Loc,
772 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
773 Selector_Name => New_Reference_To (DTC_Entity (Subp), Loc));
776 -- Handle dispatching calls to predefined primitives
778 if Is_Predefined_Dispatching_Operation (Subp)
779 or else Is_Predefined_Dispatching_Alias (Subp)
782 Unchecked_Convert_To (Subp_Ptr_Typ,
783 Build_Get_Predefined_Prim_Op_Address (Loc,
784 Tag_Node => Controlling_Tag,
785 Position_Node => Make_Integer_Literal (Loc,
786 DT_Position (Subp))));
788 -- Handle dispatching calls to user-defined primitives
792 Unchecked_Convert_To (Subp_Ptr_Typ,
793 Build_Get_Prim_Op_Address (Loc,
794 Tag_Node => Controlling_Tag,
795 Position_Node => Make_Integer_Literal (Loc,
796 DT_Position (Subp))));
799 if Nkind (Call_Node) = N_Function_Call then
801 -- Ada 2005 (AI-251): A dispatching "=" with an abstract interface
802 -- just requires the comparison of the tags.
804 if Ekind (Etype (Ctrl_Arg)) = E_Class_Wide_Type
805 and then Is_Interface (Etype (Ctrl_Arg))
806 and then Subp = Eq_Prim_Op
808 Param := First_Actual (Call_Node);
813 Make_Selected_Component (Loc,
814 Prefix => New_Value (Param),
816 New_Reference_To (First_Tag_Component (Typ), Loc)),
819 Make_Selected_Component (Loc,
821 Unchecked_Convert_To (Typ,
822 New_Value (Next_Actual (Param))),
824 New_Reference_To (First_Tag_Component (Typ), Loc)));
828 Make_Function_Call (Loc,
829 Name => New_Call_Name,
830 Parameter_Associations => New_Params);
832 -- If this is a dispatching "=", we must first compare the tags so
833 -- we generate: x.tag = y.tag and then x = y
835 if Subp = Eq_Prim_Op then
836 Param := First_Actual (Call_Node);
842 Make_Selected_Component (Loc,
843 Prefix => New_Value (Param),
845 New_Reference_To (First_Tag_Component (Typ),
849 Make_Selected_Component (Loc,
851 Unchecked_Convert_To (Typ,
852 New_Value (Next_Actual (Param))),
854 New_Reference_To (First_Tag_Component (Typ),
856 Right_Opnd => New_Call);
862 Make_Procedure_Call_Statement (Loc,
863 Name => New_Call_Name,
864 Parameter_Associations => New_Params);
867 Rewrite (Call_Node, New_Call);
868 Analyze_And_Resolve (Call_Node, Call_Typ);
869 end Expand_Dispatching_Call;
871 ---------------------------------
872 -- Expand_Interface_Conversion --
873 ---------------------------------
875 procedure Expand_Interface_Conversion
877 Is_Static : Boolean := True)
879 Loc : constant Source_Ptr := Sloc (N);
880 Etyp : constant Entity_Id := Etype (N);
881 Operand : constant Node_Id := Expression (N);
882 Operand_Typ : Entity_Id := Etype (Operand);
885 Iface_Typ : Entity_Id := Etype (N);
886 Iface_Tag : Entity_Id;
887 New_Itype : Entity_Id;
890 pragma Assert (Nkind (Operand) /= N_Attribute_Reference);
892 -- Ada 2005 (AI-345): Handle synchronized interface type derivations
894 if Is_Concurrent_Type (Operand_Typ) then
895 Operand_Typ := Base_Type (Corresponding_Record_Type (Operand_Typ));
898 -- Handle access types to interfaces
900 if Is_Access_Type (Iface_Typ) then
901 Iface_Typ := Etype (Directly_Designated_Type (Iface_Typ));
904 -- Handle class-wide interface types. This conversion can appear
905 -- explicitly in the source code. Example: I'Class (Obj)
907 if Is_Class_Wide_Type (Iface_Typ) then
908 Iface_Typ := Etype (Iface_Typ);
911 pragma Assert (not Is_Static
912 or else (not Is_Class_Wide_Type (Iface_Typ)
913 and then Is_Interface (Iface_Typ)));
915 if not Is_Static then
917 -- Give error if configurable run time and Displace not available
919 if not RTE_Available (RE_Displace) then
920 Error_Msg_CRT ("abstract interface types", N);
924 -- Handle conversion of access to class-wide interface types. The
925 -- target can be an access to object or an access to another class
926 -- wide interfac (see -1- and -2- in the following example):
928 -- type Iface1_Ref is access all Iface1'Class;
929 -- type Iface2_Ref is access all Iface1'Class;
931 -- Acc1 : Iface1_Ref := new ...
932 -- Obj : Obj_Ref := Obj_Ref (Acc); -- 1
933 -- Acc2 : Iface2_Ref := Iface2_Ref (Acc); -- 2
935 if Is_Access_Type (Operand_Typ) then
937 (Is_Class_Wide_Type (Directly_Designated_Type (Operand_Typ))
939 Is_Interface (Directly_Designated_Type (Operand_Typ)));
942 Unchecked_Convert_To (Etype (N),
943 Make_Function_Call (Loc,
944 Name => New_Reference_To (RTE (RE_Displace), Loc),
945 Parameter_Associations => New_List (
947 Unchecked_Convert_To (RTE (RE_Address),
948 Relocate_Node (Expression (N))),
951 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
959 Make_Function_Call (Loc,
960 Name => New_Reference_To (RTE (RE_Displace), Loc),
961 Parameter_Associations => New_List (
962 Make_Attribute_Reference (Loc,
963 Prefix => Relocate_Node (Expression (N)),
964 Attribute_Name => Name_Address),
967 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
972 -- If the target is a class-wide interface we change the type of the
973 -- data returned by IW_Convert to indicate that this is a dispatching
976 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
977 Set_Etype (New_Itype, New_Itype);
978 Init_Esize (New_Itype);
979 Init_Size_Align (New_Itype);
980 Set_Directly_Designated_Type (New_Itype, Etyp);
982 Rewrite (N, Make_Explicit_Dereference (Loc,
983 Unchecked_Convert_To (New_Itype,
984 Relocate_Node (N))));
986 Freeze_Itype (New_Itype, N);
991 Iface_Tag := Find_Interface_Tag (Operand_Typ, Iface_Typ);
992 pragma Assert (Iface_Tag /= Empty);
994 -- Keep separate access types to interfaces because one internal
995 -- function is used to handle the null value (see following comment)
997 if not Is_Access_Type (Etype (N)) then
999 Unchecked_Convert_To (Etype (N),
1000 Make_Selected_Component (Loc,
1001 Prefix => Relocate_Node (Expression (N)),
1003 New_Occurrence_Of (Iface_Tag, Loc))));
1006 -- Build internal function to handle the case in which the
1007 -- actual is null. If the actual is null returns null because
1008 -- no displacement is required; otherwise performs a type
1009 -- conversion that will be expanded in the code that returns
1010 -- the value of the displaced actual. That is:
1012 -- function Func (O : Address) return Iface_Typ is
1014 -- if O = Null_Address then
1017 -- return Iface_Typ!(Operand_Typ!(O).Iface_Tag'Address);
1021 Fent := Make_Defining_Identifier (Loc, New_Internal_Name ('F'));
1022 Set_Is_Internal (Fent);
1025 Desig_Typ : Entity_Id;
1027 Desig_Typ := Etype (Expression (N));
1029 if Is_Access_Type (Desig_Typ) then
1030 Desig_Typ := Directly_Designated_Type (Desig_Typ);
1033 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
1034 Set_Etype (New_Itype, New_Itype);
1035 Set_Scope (New_Itype, Fent);
1036 Init_Size_Align (New_Itype);
1037 Set_Directly_Designated_Type (New_Itype, Desig_Typ);
1041 Make_Subprogram_Body (Loc,
1043 Make_Function_Specification (Loc,
1044 Defining_Unit_Name => Fent,
1046 Parameter_Specifications => New_List (
1047 Make_Parameter_Specification (Loc,
1048 Defining_Identifier =>
1049 Make_Defining_Identifier (Loc, Name_uO),
1051 New_Reference_To (RTE (RE_Address), Loc))),
1053 Result_Definition =>
1054 New_Reference_To (Etype (N), Loc)),
1056 Declarations => Empty_List,
1058 Handled_Statement_Sequence =>
1059 Make_Handled_Sequence_Of_Statements (Loc,
1060 Statements => New_List (
1061 Make_If_Statement (Loc,
1064 Left_Opnd => Make_Identifier (Loc, Name_uO),
1065 Right_Opnd => New_Reference_To
1066 (RTE (RE_Null_Address), Loc)),
1068 Then_Statements => New_List (
1069 Make_Return_Statement (Loc,
1072 Else_Statements => New_List (
1073 Make_Return_Statement (Loc,
1074 Unchecked_Convert_To (Etype (N),
1075 Make_Attribute_Reference (Loc,
1077 Make_Selected_Component (Loc,
1078 Prefix => Unchecked_Convert_To (New_Itype,
1079 Make_Identifier (Loc, Name_uO)),
1081 New_Occurrence_Of (Iface_Tag, Loc)),
1082 Attribute_Name => Name_Address))))))));
1084 -- Place function body before the expression containing
1087 Insert_Action (N, Func);
1090 if Is_Access_Type (Etype (Expression (N))) then
1092 -- Generate: Operand_Typ!(Expression.all)'Address
1095 Make_Function_Call (Loc,
1096 Name => New_Reference_To (Fent, Loc),
1097 Parameter_Associations => New_List (
1098 Make_Attribute_Reference (Loc,
1099 Prefix => Unchecked_Convert_To (Operand_Typ,
1100 Make_Explicit_Dereference (Loc,
1101 Relocate_Node (Expression (N)))),
1102 Attribute_Name => Name_Address))));
1105 -- Generate: Operand_Typ!(Expression)'Address
1108 Make_Function_Call (Loc,
1109 Name => New_Reference_To (Fent, Loc),
1110 Parameter_Associations => New_List (
1111 Make_Attribute_Reference (Loc,
1112 Prefix => Unchecked_Convert_To (Operand_Typ,
1113 Relocate_Node (Expression (N))),
1114 Attribute_Name => Name_Address))));
1119 end Expand_Interface_Conversion;
1121 ------------------------------
1122 -- Expand_Interface_Actuals --
1123 ------------------------------
1125 procedure Expand_Interface_Actuals (Call_Node : Node_Id) is
1126 Loc : constant Source_Ptr := Sloc (Call_Node);
1128 Actual_Dup : Node_Id;
1129 Actual_Typ : Entity_Id;
1131 Conversion : Node_Id;
1133 Formal_Typ : Entity_Id;
1136 Formal_DDT : Entity_Id;
1137 Actual_DDT : Entity_Id;
1140 -- This subprogram is called directly from the semantics, so we need a
1141 -- check to see whether expansion is active before proceeding.
1143 if not Expander_Active then
1147 -- Call using access to subprogram with explicit dereference
1149 if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
1150 Subp := Etype (Name (Call_Node));
1155 Subp := Entity (Name (Call_Node));
1158 Formal := First_Formal (Subp);
1159 Actual := First_Actual (Call_Node);
1160 while Present (Formal) loop
1162 -- Ada 2005 (AI-251): Conversion to interface to force "this"
1165 Formal_Typ := Etype (Etype (Formal));
1167 if Ekind (Formal_Typ) = E_Record_Type_With_Private then
1168 Formal_Typ := Full_View (Formal_Typ);
1171 if Is_Access_Type (Formal_Typ) then
1172 Formal_DDT := Directly_Designated_Type (Formal_Typ);
1175 Actual_Typ := Etype (Actual);
1177 if Is_Access_Type (Actual_Typ) then
1178 Actual_DDT := Directly_Designated_Type (Actual_Typ);
1181 if Is_Interface (Formal_Typ) then
1183 -- No need to displace the pointer if the type of the actual
1184 -- is class-wide of the formal-type interface; in this case the
1185 -- displacement of the pointer was already done at the point of
1186 -- the call to the enclosing subprogram. This case corresponds
1187 -- with the call to P (Obj) in the following example:
1189 -- type I is interface;
1190 -- procedure P (X : I) is abstract;
1192 -- procedure General_Op (Obj : I'Class) is
1197 if Is_Class_Wide_Type (Actual_Typ)
1198 and then Etype (Actual_Typ) = Formal_Typ
1202 -- No need to displace the pointer if the type of the actual is a
1203 -- derivation of the formal-type interface because in this case
1204 -- the interface primitives are located in the primary dispatch
1207 elsif Is_Parent (Formal_Typ, Actual_Typ) then
1211 Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
1212 Rewrite (Actual, Conversion);
1213 Analyze_And_Resolve (Actual, Formal_Typ);
1216 -- Anonymous access type
1218 elsif Is_Access_Type (Formal_Typ)
1219 and then Is_Interface (Etype (Formal_DDT))
1220 and then Interface_Present_In_Ancestor
1222 Iface => Etype (Formal_DDT))
1224 if Nkind (Actual) = N_Attribute_Reference
1226 (Attribute_Name (Actual) = Name_Access
1227 or else Attribute_Name (Actual) = Name_Unchecked_Access)
1229 Nam := Attribute_Name (Actual);
1231 Conversion := Convert_To (Etype (Formal_DDT), Prefix (Actual));
1233 Rewrite (Actual, Conversion);
1234 Analyze_And_Resolve (Actual, Etype (Formal_DDT));
1237 Unchecked_Convert_To (Formal_Typ,
1238 Make_Attribute_Reference (Loc,
1239 Prefix => Relocate_Node (Actual),
1240 Attribute_Name => Nam)));
1242 Analyze_And_Resolve (Actual, Formal_Typ);
1244 -- No need to displace the pointer if the actual is a class-wide
1245 -- type of the formal-type interface because in this case the
1246 -- displacement of the pointer was already done at the point of
1247 -- the call to the enclosing subprogram (this case is similar
1248 -- to the example described above for the non access-type case)
1250 elsif Is_Class_Wide_Type (Actual_DDT)
1251 and then Etype (Actual_DDT) = Formal_DDT
1255 -- No need to displace the pointer if the type of the actual is a
1256 -- derivation of the interface (because in this case the interface
1257 -- primitives are located in the primary dispatch table)
1259 elsif Is_Parent (Formal_DDT, Actual_DDT) then
1263 Actual_Dup := Relocate_Node (Actual);
1265 if From_With_Type (Actual_Typ) then
1267 -- If the type of the actual parameter comes from a limited
1268 -- with-clause and the non-limited view is already available
1269 -- we replace the anonymous access type by a duplicate decla
1270 -- ration whose designated type is the non-limited view
1272 if Ekind (Actual_DDT) = E_Incomplete_Type
1273 and then Present (Non_Limited_View (Actual_DDT))
1275 Anon := New_Copy (Actual_Typ);
1277 if Is_Itype (Anon) then
1278 Set_Scope (Anon, Current_Scope);
1281 Set_Directly_Designated_Type (Anon,
1282 Non_Limited_View (Actual_DDT));
1283 Set_Etype (Actual_Dup, Anon);
1285 elsif Is_Class_Wide_Type (Actual_DDT)
1286 and then Ekind (Etype (Actual_DDT)) = E_Incomplete_Type
1287 and then Present (Non_Limited_View (Etype (Actual_DDT)))
1289 Anon := New_Copy (Actual_Typ);
1291 if Is_Itype (Anon) then
1292 Set_Scope (Anon, Current_Scope);
1295 Set_Directly_Designated_Type (Anon,
1296 New_Copy (Actual_DDT));
1297 Set_Class_Wide_Type (Directly_Designated_Type (Anon),
1298 New_Copy (Class_Wide_Type (Actual_DDT)));
1299 Set_Etype (Directly_Designated_Type (Anon),
1300 Non_Limited_View (Etype (Actual_DDT)));
1302 Class_Wide_Type (Directly_Designated_Type (Anon)),
1303 Non_Limited_View (Etype (Actual_DDT)));
1304 Set_Etype (Actual_Dup, Anon);
1308 Conversion := Convert_To (Formal_Typ, Actual_Dup);
1309 Rewrite (Actual, Conversion);
1310 Analyze_And_Resolve (Actual, Formal_Typ);
1314 Next_Actual (Actual);
1315 Next_Formal (Formal);
1317 end Expand_Interface_Actuals;
1319 ----------------------------
1320 -- Expand_Interface_Thunk --
1321 ----------------------------
1323 function Expand_Interface_Thunk
1325 Thunk_Alias : Entity_Id;
1326 Thunk_Id : Entity_Id) return Node_Id
1328 Loc : constant Source_Ptr := Sloc (N);
1329 Actuals : constant List_Id := New_List;
1330 Decl : constant List_Id := New_List;
1331 Formals : constant List_Id := New_List;
1335 New_Formal : Node_Id;
1341 -- Traverse the list of alias to find the final target
1343 Target := Thunk_Alias;
1344 while Present (Alias (Target)) loop
1345 Target := Alias (Target);
1348 -- Duplicate the formals
1350 Formal := First_Formal (Target);
1351 E := First_Formal (N);
1352 while Present (Formal) loop
1353 New_Formal := Copy_Separate_Tree (Parent (Formal));
1355 -- Propagate the parameter type to the copy. This is required to
1356 -- properly handle the case in which the subprogram covering the
1357 -- interface has been inherited:
1360 -- type I is interface;
1361 -- procedure P (X : I) is abstract;
1363 -- type T is tagged null record;
1364 -- procedure P (X : T);
1366 -- type DT is new T and I with ...
1368 Set_Parameter_Type (New_Formal, New_Reference_To (Etype (E), Loc));
1369 Append_To (Formals, New_Formal);
1371 Next_Formal (Formal);
1375 -- Give message if configurable run-time and Offset_To_Top unavailable
1377 if not RTE_Available (RE_Offset_To_Top) then
1378 Error_Msg_CRT ("abstract interface types", N);
1382 if Ekind (First_Formal (Target)) = E_In_Parameter
1383 and then Ekind (Etype (First_Formal (Target)))
1384 = E_Anonymous_Access_Type
1388 -- type T is access all <<type of the first formal>>
1389 -- S1 := Storage_Offset!(First_formal)
1390 -- - Offset_To_Top (First_Formal.Tag)
1392 -- ... and the first actual of the call is generated as T!(S1)
1395 Make_Full_Type_Declaration (Loc,
1396 Defining_Identifier =>
1397 Make_Defining_Identifier (Loc,
1398 New_Internal_Name ('T')),
1400 Make_Access_To_Object_Definition (Loc,
1401 All_Present => True,
1402 Null_Exclusion_Present => False,
1403 Constant_Present => False,
1404 Subtype_Indication =>
1406 (Directly_Designated_Type
1407 (Etype (First_Formal (Target))), Loc)));
1410 Make_Object_Declaration (Loc,
1411 Defining_Identifier =>
1412 Make_Defining_Identifier (Loc,
1413 New_Internal_Name ('S')),
1414 Constant_Present => True,
1415 Object_Definition =>
1416 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1418 Make_Op_Subtract (Loc,
1420 Unchecked_Convert_To
1421 (RTE (RE_Storage_Offset),
1423 (Defining_Identifier (First (Formals)), Loc)),
1425 Make_Function_Call (Loc,
1426 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1427 Parameter_Associations => New_List (
1428 Unchecked_Convert_To
1431 (Defining_Identifier (First (Formals)), Loc))))));
1433 Append_To (Decl, Decl_2);
1434 Append_To (Decl, Decl_1);
1436 -- Reference the new first actual
1439 Unchecked_Convert_To
1440 (Defining_Identifier (Decl_2),
1441 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1446 -- S1 := Storage_Offset!(First_formal'Address)
1447 -- - Offset_To_Top (First_Formal.Tag)
1448 -- S2 := Tag_Ptr!(S3)
1451 Make_Object_Declaration (Loc,
1452 Defining_Identifier =>
1453 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1454 Constant_Present => True,
1455 Object_Definition =>
1456 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1458 Make_Op_Subtract (Loc,
1460 Unchecked_Convert_To
1461 (RTE (RE_Storage_Offset),
1462 Make_Attribute_Reference (Loc,
1465 (Defining_Identifier (First (Formals)), Loc),
1466 Attribute_Name => Name_Address)),
1468 Make_Function_Call (Loc,
1469 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1470 Parameter_Associations => New_List (
1471 Make_Attribute_Reference (Loc,
1472 Prefix => New_Reference_To
1473 (Defining_Identifier (First (Formals)),
1475 Attribute_Name => Name_Address)))));
1478 Make_Object_Declaration (Loc,
1479 Defining_Identifier =>
1480 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1481 Constant_Present => True,
1482 Object_Definition => New_Reference_To (RTE (RE_Addr_Ptr), Loc),
1484 Unchecked_Convert_To
1486 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1488 Append_To (Decl, Decl_1);
1489 Append_To (Decl, Decl_2);
1491 -- Reference the new first actual
1494 Unchecked_Convert_To
1495 (Etype (First_Entity (Target)),
1496 Make_Explicit_Dereference (Loc,
1497 New_Reference_To (Defining_Identifier (Decl_2), Loc))));
1500 Formal := Next (First (Formals));
1501 while Present (Formal) loop
1503 New_Reference_To (Defining_Identifier (Formal), Loc));
1507 if Ekind (Target) = E_Procedure then
1509 Make_Subprogram_Body (Loc,
1511 Make_Procedure_Specification (Loc,
1512 Defining_Unit_Name => Thunk_Id,
1513 Parameter_Specifications => Formals),
1514 Declarations => Decl,
1515 Handled_Statement_Sequence =>
1516 Make_Handled_Sequence_Of_Statements (Loc,
1517 Statements => New_List (
1518 Make_Procedure_Call_Statement (Loc,
1519 Name => New_Occurrence_Of (Target, Loc),
1520 Parameter_Associations => Actuals))));
1522 else pragma Assert (Ekind (Target) = E_Function);
1525 Make_Subprogram_Body (Loc,
1527 Make_Function_Specification (Loc,
1528 Defining_Unit_Name => Thunk_Id,
1529 Parameter_Specifications => Formals,
1530 Result_Definition =>
1531 New_Copy (Result_Definition (Parent (Target)))),
1532 Declarations => Decl,
1533 Handled_Statement_Sequence =>
1534 Make_Handled_Sequence_Of_Statements (Loc,
1535 Statements => New_List (
1536 Make_Return_Statement (Loc,
1537 Make_Function_Call (Loc,
1538 Name => New_Occurrence_Of (Target, Loc),
1539 Parameter_Associations => Actuals)))));
1542 -- Analyze the code of the thunk with checks suppressed because we are
1543 -- in the middle of building the dispatch information itself and some
1544 -- characteristics of the type may not be fully available.
1546 Analyze (New_Code, Suppress => All_Checks);
1548 end Expand_Interface_Thunk;
1554 function Fill_DT_Entry
1556 Prim : Entity_Id) return Node_Id
1558 Typ : constant Entity_Id := Scope (DTC_Entity (Prim));
1559 DT_Ptr : constant Entity_Id :=
1560 Node (First_Elmt (Access_Disp_Table (Typ)));
1561 Pos : constant Uint := DT_Position (Prim);
1562 Tag : constant Entity_Id := First_Tag_Component (Typ);
1565 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1567 if Is_Predefined_Dispatching_Operation (Prim)
1568 or else Is_Predefined_Dispatching_Alias (Prim)
1571 Build_Set_Predefined_Prim_Op_Address (Loc,
1572 Tag_Node => New_Reference_To (DT_Ptr, Loc),
1573 Position_Node => Make_Integer_Literal (Loc, Pos),
1574 Address_Node => Make_Attribute_Reference (Loc,
1575 Prefix => New_Reference_To (Prim, Loc),
1576 Attribute_Name => Name_Address));
1579 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
1582 Build_Set_Prim_Op_Address (Loc,
1583 Tag_Node => New_Reference_To (DT_Ptr, Loc),
1584 Position_Node => Make_Integer_Literal (Loc, Pos),
1585 Address_Node => Make_Attribute_Reference (Loc,
1586 Prefix => New_Reference_To (Prim, Loc),
1587 Attribute_Name => Name_Address));
1591 -----------------------------
1592 -- Fill_Secondary_DT_Entry --
1593 -----------------------------
1595 function Fill_Secondary_DT_Entry
1598 Thunk_Id : Entity_Id;
1599 Iface_DT_Ptr : Entity_Id) return Node_Id
1601 Iface_Prim : constant Entity_Id := Abstract_Interface_Alias (Prim);
1602 Pos : constant Uint := DT_Position (Iface_Prim);
1603 Tag : constant Entity_Id :=
1604 First_Tag_Component (Scope (DTC_Entity (Iface_Prim)));
1607 if Is_Predefined_Dispatching_Operation (Prim)
1608 or else Is_Predefined_Dispatching_Alias (Prim)
1611 Build_Set_Predefined_Prim_Op_Address (Loc,
1613 New_Reference_To (Iface_DT_Ptr, Loc),
1615 Make_Integer_Literal (Loc, Pos),
1617 Make_Attribute_Reference (Loc,
1618 Prefix => New_Reference_To (Thunk_Id, Loc),
1619 Attribute_Name => Name_Address));
1621 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
1624 Build_Set_Prim_Op_Address (Loc,
1625 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
1626 Position_Node => Make_Integer_Literal (Loc, Pos),
1627 Address_Node => Make_Attribute_Reference (Loc,
1628 Prefix => New_Reference_To (Thunk_Id, Loc),
1629 Attribute_Name => Name_Address));
1631 end Fill_Secondary_DT_Entry;
1633 -------------------------------------
1634 -- Is_Predefined_Dispatching_Alias --
1635 -------------------------------------
1637 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
1642 if not Is_Predefined_Dispatching_Operation (Prim)
1643 and then Present (Alias (Prim))
1646 while Present (Alias (E)) loop
1650 if Is_Predefined_Dispatching_Operation (E) then
1656 end Is_Predefined_Dispatching_Alias;
1658 ----------------------------------------
1659 -- Make_Disp_Asynchronous_Select_Body --
1660 ----------------------------------------
1662 function Make_Disp_Asynchronous_Select_Body
1663 (Typ : Entity_Id) return Node_Id
1665 Conc_Typ : Entity_Id := Empty;
1666 Decls : constant List_Id := New_List;
1668 Loc : constant Source_Ptr := Sloc (Typ);
1669 Stmts : constant List_Id := New_List;
1672 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1674 -- Null body is generated for interface types
1676 if Is_Interface (Typ) then
1678 Make_Subprogram_Body (Loc,
1680 Make_Disp_Asynchronous_Select_Spec (Typ),
1683 Handled_Statement_Sequence =>
1684 Make_Handled_Sequence_Of_Statements (Loc,
1685 New_List (Make_Null_Statement (Loc))));
1688 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1690 if Is_Concurrent_Record_Type (Typ) then
1691 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1694 -- I : Integer := Get_Entry_Index (tag! (<type>VP), S);
1696 -- where I will be used to capture the entry index of the primitive
1697 -- wrapper at position S.
1700 Make_Object_Declaration (Loc,
1701 Defining_Identifier =>
1702 Make_Defining_Identifier (Loc, Name_uI),
1703 Object_Definition =>
1704 New_Reference_To (Standard_Integer, Loc),
1706 Make_DT_Access_Action (Typ,
1711 Unchecked_Convert_To (RTE (RE_Tag),
1712 New_Reference_To (DT_Ptr, Loc)),
1713 Make_Identifier (Loc, Name_uS)))));
1715 if Ekind (Conc_Typ) = E_Protected_Type then
1718 -- Protected_Entry_Call (
1719 -- T._object'access,
1720 -- protected_entry_index! (I),
1722 -- Asynchronous_Call,
1725 -- where T is the protected object, I is the entry index, P are
1726 -- the wrapped parameters and B is the name of the communication
1730 Make_Procedure_Call_Statement (Loc,
1732 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1733 Parameter_Associations =>
1736 Make_Attribute_Reference (Loc, -- T._object'access
1738 Name_Unchecked_Access,
1740 Make_Selected_Component (Loc,
1742 Make_Identifier (Loc, Name_uT),
1744 Make_Identifier (Loc, Name_uObject))),
1746 Make_Unchecked_Type_Conversion (Loc, -- entry index
1748 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
1750 Make_Identifier (Loc, Name_uI)),
1752 Make_Identifier (Loc, Name_uP), -- parameter block
1753 New_Reference_To ( -- Asynchronous_Call
1754 RTE (RE_Asynchronous_Call), Loc),
1755 Make_Identifier (Loc, Name_uB)))); -- comm block
1757 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
1760 -- Protected_Entry_Call (
1762 -- task_entry_index! (I),
1764 -- Conditional_Call,
1767 -- where T is the task object, I is the entry index, P are the
1768 -- wrapped parameters and F is the status flag.
1771 Make_Procedure_Call_Statement (Loc,
1773 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
1774 Parameter_Associations =>
1777 Make_Selected_Component (Loc, -- T._task_id
1779 Make_Identifier (Loc, Name_uT),
1781 Make_Identifier (Loc, Name_uTask_Id)),
1783 Make_Unchecked_Type_Conversion (Loc, -- entry index
1785 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
1787 Make_Identifier (Loc, Name_uI)),
1789 Make_Identifier (Loc, Name_uP), -- parameter block
1790 New_Reference_To ( -- Asynchronous_Call
1791 RTE (RE_Asynchronous_Call), Loc),
1792 Make_Identifier (Loc, Name_uF)))); -- status flag
1797 Make_Subprogram_Body (Loc,
1799 Make_Disp_Asynchronous_Select_Spec (Typ),
1802 Handled_Statement_Sequence =>
1803 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
1804 end Make_Disp_Asynchronous_Select_Body;
1806 ----------------------------------------
1807 -- Make_Disp_Asynchronous_Select_Spec --
1808 ----------------------------------------
1810 function Make_Disp_Asynchronous_Select_Spec
1811 (Typ : Entity_Id) return Node_Id
1813 Loc : constant Source_Ptr := Sloc (Typ);
1814 Def_Id : constant Node_Id :=
1815 Make_Defining_Identifier (Loc,
1816 Name_uDisp_Asynchronous_Select);
1817 Params : constant List_Id := New_List;
1820 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1822 -- "T" - Object parameter
1823 -- "S" - Primitive operation slot
1824 -- "P" - Wrapped parameters
1825 -- "B" - Communication block
1826 -- "F" - Status flag
1828 SEU.Build_T (Loc, Typ, Params);
1829 SEU.Build_S (Loc, Params);
1830 SEU.Build_P (Loc, Params);
1831 SEU.Build_B (Loc, Params);
1832 SEU.Build_F (Loc, Params);
1834 Set_Is_Internal (Def_Id);
1837 Make_Procedure_Specification (Loc,
1838 Defining_Unit_Name => Def_Id,
1839 Parameter_Specifications => Params);
1840 end Make_Disp_Asynchronous_Select_Spec;
1842 ---------------------------------------
1843 -- Make_Disp_Conditional_Select_Body --
1844 ---------------------------------------
1846 function Make_Disp_Conditional_Select_Body
1847 (Typ : Entity_Id) return Node_Id
1849 Loc : constant Source_Ptr := Sloc (Typ);
1850 Blk_Nam : Entity_Id;
1851 Conc_Typ : Entity_Id := Empty;
1852 Decls : constant List_Id := New_List;
1854 Stmts : constant List_Id := New_List;
1857 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1859 -- Null body is generated for interface types
1861 if Is_Interface (Typ) then
1863 Make_Subprogram_Body (Loc,
1865 Make_Disp_Conditional_Select_Spec (Typ),
1868 Handled_Statement_Sequence =>
1869 Make_Handled_Sequence_Of_Statements (Loc,
1870 New_List (Make_Null_Statement (Loc))));
1873 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1875 if Is_Concurrent_Record_Type (Typ) then
1876 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1881 -- where I will be used to capture the entry index of the primitive
1882 -- wrapper at position S.
1885 Make_Object_Declaration (Loc,
1886 Defining_Identifier =>
1887 Make_Defining_Identifier (Loc, Name_uI),
1888 Object_Definition =>
1889 New_Reference_To (Standard_Integer, Loc)));
1892 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
1894 -- if C = POK_Procedure
1895 -- or else C = POK_Protected_Procedure
1896 -- or else C = POK_Task_Procedure;
1902 SEU.Build_Common_Dispatching_Select_Statements
1903 (Loc, Typ, DT_Ptr, Stmts);
1906 -- Bnn : Communication_Block;
1908 -- where Bnn is the name of the communication block used in
1909 -- the call to Protected_Entry_Call.
1911 Blk_Nam := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1914 Make_Object_Declaration (Loc,
1915 Defining_Identifier =>
1917 Object_Definition =>
1918 New_Reference_To (RTE (RE_Communication_Block), Loc)));
1921 -- I := Get_Entry_Index (tag! (<type>VP), S);
1923 -- I is the entry index and S is the dispatch table slot
1926 Make_Assignment_Statement (Loc,
1928 Make_Identifier (Loc, Name_uI),
1930 Make_DT_Access_Action (Typ,
1935 Unchecked_Convert_To (RTE (RE_Tag),
1936 New_Reference_To (DT_Ptr, Loc)),
1937 Make_Identifier (Loc, Name_uS)))));
1939 if Ekind (Conc_Typ) = E_Protected_Type then
1942 -- Protected_Entry_Call (
1943 -- T._object'access,
1944 -- protected_entry_index! (I),
1946 -- Conditional_Call,
1949 -- where T is the protected object, I is the entry index, P are
1950 -- the wrapped parameters and Bnn is the name of the communication
1954 Make_Procedure_Call_Statement (Loc,
1956 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1957 Parameter_Associations =>
1960 Make_Attribute_Reference (Loc, -- T._object'access
1962 Name_Unchecked_Access,
1964 Make_Selected_Component (Loc,
1966 Make_Identifier (Loc, Name_uT),
1968 Make_Identifier (Loc, Name_uObject))),
1970 Make_Unchecked_Type_Conversion (Loc, -- entry index
1972 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
1974 Make_Identifier (Loc, Name_uI)),
1976 Make_Identifier (Loc, Name_uP), -- parameter block
1977 New_Reference_To ( -- Conditional_Call
1978 RTE (RE_Conditional_Call), Loc),
1979 New_Reference_To ( -- Bnn
1983 -- F := not Cancelled (Bnn);
1985 -- where F is the success flag. The status of Cancelled is negated
1986 -- in order to match the behaviour of the version for task types.
1989 Make_Assignment_Statement (Loc,
1991 Make_Identifier (Loc, Name_uF),
1995 Make_Function_Call (Loc,
1997 New_Reference_To (RTE (RE_Cancelled), Loc),
1998 Parameter_Associations =>
2000 New_Reference_To (Blk_Nam, Loc))))));
2002 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2005 -- Protected_Entry_Call (
2007 -- task_entry_index! (I),
2009 -- Conditional_Call,
2012 -- where T is the task object, I is the entry index, P are the
2013 -- wrapped parameters and F is the status flag.
2016 Make_Procedure_Call_Statement (Loc,
2018 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
2019 Parameter_Associations =>
2022 Make_Selected_Component (Loc, -- T._task_id
2024 Make_Identifier (Loc, Name_uT),
2026 Make_Identifier (Loc, Name_uTask_Id)),
2028 Make_Unchecked_Type_Conversion (Loc, -- entry index
2030 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2032 Make_Identifier (Loc, Name_uI)),
2034 Make_Identifier (Loc, Name_uP), -- parameter block
2035 New_Reference_To ( -- Conditional_Call
2036 RTE (RE_Conditional_Call), Loc),
2037 Make_Identifier (Loc, Name_uF)))); -- status flag
2042 Make_Subprogram_Body (Loc,
2044 Make_Disp_Conditional_Select_Spec (Typ),
2047 Handled_Statement_Sequence =>
2048 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2049 end Make_Disp_Conditional_Select_Body;
2051 ---------------------------------------
2052 -- Make_Disp_Conditional_Select_Spec --
2053 ---------------------------------------
2055 function Make_Disp_Conditional_Select_Spec
2056 (Typ : Entity_Id) return Node_Id
2058 Loc : constant Source_Ptr := Sloc (Typ);
2059 Def_Id : constant Node_Id :=
2060 Make_Defining_Identifier (Loc,
2061 Name_uDisp_Conditional_Select);
2062 Params : constant List_Id := New_List;
2065 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2067 -- "T" - Object parameter
2068 -- "S" - Primitive operation slot
2069 -- "P" - Wrapped parameters
2071 -- "F" - Status flag
2073 SEU.Build_T (Loc, Typ, Params);
2074 SEU.Build_S (Loc, Params);
2075 SEU.Build_P (Loc, Params);
2076 SEU.Build_C (Loc, Params);
2077 SEU.Build_F (Loc, Params);
2079 Set_Is_Internal (Def_Id);
2082 Make_Procedure_Specification (Loc,
2083 Defining_Unit_Name => Def_Id,
2084 Parameter_Specifications => Params);
2085 end Make_Disp_Conditional_Select_Spec;
2087 -------------------------------------
2088 -- Make_Disp_Get_Prim_Op_Kind_Body --
2089 -------------------------------------
2091 function Make_Disp_Get_Prim_Op_Kind_Body
2092 (Typ : Entity_Id) return Node_Id
2094 Loc : constant Source_Ptr := Sloc (Typ);
2098 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2100 if Is_Interface (Typ) then
2102 Make_Subprogram_Body (Loc,
2104 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2107 Handled_Statement_Sequence =>
2108 Make_Handled_Sequence_Of_Statements (Loc,
2109 New_List (Make_Null_Statement (Loc))));
2112 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2115 -- C := get_prim_op_kind (tag! (<type>VP), S);
2117 -- where C is the out parameter capturing the call kind and S is the
2118 -- dispatch table slot number.
2121 Make_Subprogram_Body (Loc,
2123 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2126 Handled_Statement_Sequence =>
2127 Make_Handled_Sequence_Of_Statements (Loc,
2129 Make_Assignment_Statement (Loc,
2131 Make_Identifier (Loc, Name_uC),
2133 Make_DT_Access_Action (Typ,
2138 Unchecked_Convert_To (RTE (RE_Tag),
2139 New_Reference_To (DT_Ptr, Loc)),
2140 Make_Identifier (Loc, Name_uS)))))));
2141 end Make_Disp_Get_Prim_Op_Kind_Body;
2143 -------------------------------------
2144 -- Make_Disp_Get_Prim_Op_Kind_Spec --
2145 -------------------------------------
2147 function Make_Disp_Get_Prim_Op_Kind_Spec
2148 (Typ : Entity_Id) return Node_Id
2150 Loc : constant Source_Ptr := Sloc (Typ);
2151 Def_Id : constant Node_Id :=
2152 Make_Defining_Identifier (Loc,
2153 Name_uDisp_Get_Prim_Op_Kind);
2154 Params : constant List_Id := New_List;
2157 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2159 -- "T" - Object parameter
2160 -- "S" - Primitive operation slot
2163 SEU.Build_T (Loc, Typ, Params);
2164 SEU.Build_S (Loc, Params);
2165 SEU.Build_C (Loc, Params);
2167 Set_Is_Internal (Def_Id);
2170 Make_Procedure_Specification (Loc,
2171 Defining_Unit_Name => Def_Id,
2172 Parameter_Specifications => Params);
2173 end Make_Disp_Get_Prim_Op_Kind_Spec;
2175 --------------------------------
2176 -- Make_Disp_Get_Task_Id_Body --
2177 --------------------------------
2179 function Make_Disp_Get_Task_Id_Body
2180 (Typ : Entity_Id) return Node_Id
2182 Loc : constant Source_Ptr := Sloc (Typ);
2186 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2188 if Is_Concurrent_Record_Type (Typ)
2189 and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
2192 Make_Return_Statement (Loc,
2194 Make_Selected_Component (Loc,
2196 Make_Identifier (Loc, Name_uT),
2198 Make_Identifier (Loc, Name_uTask_Id)));
2200 -- A null body is constructed for non-task types
2204 Make_Return_Statement (Loc,
2206 New_Reference_To (RTE (RO_ST_Null_Task), Loc));
2210 Make_Subprogram_Body (Loc,
2212 Make_Disp_Get_Task_Id_Spec (Typ),
2215 Handled_Statement_Sequence =>
2216 Make_Handled_Sequence_Of_Statements (Loc,
2218 end Make_Disp_Get_Task_Id_Body;
2220 --------------------------------
2221 -- Make_Disp_Get_Task_Id_Spec --
2222 --------------------------------
2224 function Make_Disp_Get_Task_Id_Spec
2225 (Typ : Entity_Id) return Node_Id
2227 Loc : constant Source_Ptr := Sloc (Typ);
2228 Def_Id : constant Node_Id :=
2229 Make_Defining_Identifier (Loc,
2230 Name_uDisp_Get_Task_Id);
2233 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2235 Set_Is_Internal (Def_Id);
2238 Make_Function_Specification (Loc,
2239 Defining_Unit_Name => Def_Id,
2240 Parameter_Specifications => New_List (
2241 Make_Parameter_Specification (Loc,
2242 Defining_Identifier =>
2243 Make_Defining_Identifier (Loc, Name_uT),
2245 New_Reference_To (Typ, Loc))),
2246 Result_Definition =>
2247 New_Reference_To (RTE (RO_ST_Task_Id), Loc));
2248 end Make_Disp_Get_Task_Id_Spec;
2250 ---------------------------------
2251 -- Make_Disp_Timed_Select_Body --
2252 ---------------------------------
2254 function Make_Disp_Timed_Select_Body
2255 (Typ : Entity_Id) return Node_Id
2257 Loc : constant Source_Ptr := Sloc (Typ);
2258 Conc_Typ : Entity_Id := Empty;
2259 Decls : constant List_Id := New_List;
2261 Stmts : constant List_Id := New_List;
2264 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2266 -- Null body is generated for interface types
2268 if Is_Interface (Typ) then
2270 Make_Subprogram_Body (Loc,
2272 Make_Disp_Timed_Select_Spec (Typ),
2275 Handled_Statement_Sequence =>
2276 Make_Handled_Sequence_Of_Statements (Loc,
2277 New_List (Make_Null_Statement (Loc))));
2280 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2282 if Is_Concurrent_Record_Type (Typ) then
2283 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2288 -- where I will be used to capture the entry index of the primitive
2289 -- wrapper at position S.
2292 Make_Object_Declaration (Loc,
2293 Defining_Identifier =>
2294 Make_Defining_Identifier (Loc, Name_uI),
2295 Object_Definition =>
2296 New_Reference_To (Standard_Integer, Loc)));
2299 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
2301 -- if C = POK_Procedure
2302 -- or else C = POK_Protected_Procedure
2303 -- or else C = POK_Task_Procedure;
2309 SEU.Build_Common_Dispatching_Select_Statements
2310 (Loc, Typ, DT_Ptr, Stmts);
2313 -- I := Get_Entry_Index (tag! (<type>VP), S);
2315 -- I is the entry index and S is the dispatch table slot
2318 Make_Assignment_Statement (Loc,
2320 Make_Identifier (Loc, Name_uI),
2322 Make_DT_Access_Action (Typ,
2327 Unchecked_Convert_To (RTE (RE_Tag),
2328 New_Reference_To (DT_Ptr, Loc)),
2329 Make_Identifier (Loc, Name_uS)))));
2331 if Ekind (Conc_Typ) = E_Protected_Type then
2334 -- Timed_Protected_Entry_Call (
2335 -- T._object'access,
2336 -- protected_entry_index! (I),
2342 -- where T is the protected object, I is the entry index, P are
2343 -- the wrapped parameters, D is the delay amount, M is the delay
2344 -- mode and F is the status flag.
2347 Make_Procedure_Call_Statement (Loc,
2349 New_Reference_To (RTE (RE_Timed_Protected_Entry_Call), Loc),
2350 Parameter_Associations =>
2353 Make_Attribute_Reference (Loc, -- T._object'access
2355 Name_Unchecked_Access,
2357 Make_Selected_Component (Loc,
2359 Make_Identifier (Loc, Name_uT),
2361 Make_Identifier (Loc, Name_uObject))),
2363 Make_Unchecked_Type_Conversion (Loc, -- entry index
2365 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
2367 Make_Identifier (Loc, Name_uI)),
2369 Make_Identifier (Loc, Name_uP), -- parameter block
2370 Make_Identifier (Loc, Name_uD), -- delay
2371 Make_Identifier (Loc, Name_uM), -- delay mode
2372 Make_Identifier (Loc, Name_uF)))); -- status flag
2375 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2378 -- Timed_Task_Entry_Call (
2380 -- task_entry_index! (I),
2386 -- where T is the task object, I is the entry index, P are the
2387 -- wrapped parameters, D is the delay amount, M is the delay
2388 -- mode and F is the status flag.
2391 Make_Procedure_Call_Statement (Loc,
2393 New_Reference_To (RTE (RE_Timed_Task_Entry_Call), Loc),
2394 Parameter_Associations =>
2397 Make_Selected_Component (Loc, -- T._task_id
2399 Make_Identifier (Loc, Name_uT),
2401 Make_Identifier (Loc, Name_uTask_Id)),
2403 Make_Unchecked_Type_Conversion (Loc, -- entry index
2405 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2407 Make_Identifier (Loc, Name_uI)),
2409 Make_Identifier (Loc, Name_uP), -- parameter block
2410 Make_Identifier (Loc, Name_uD), -- delay
2411 Make_Identifier (Loc, Name_uM), -- delay mode
2412 Make_Identifier (Loc, Name_uF)))); -- status flag
2417 Make_Subprogram_Body (Loc,
2419 Make_Disp_Timed_Select_Spec (Typ),
2422 Handled_Statement_Sequence =>
2423 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2424 end Make_Disp_Timed_Select_Body;
2426 ---------------------------------
2427 -- Make_Disp_Timed_Select_Spec --
2428 ---------------------------------
2430 function Make_Disp_Timed_Select_Spec
2431 (Typ : Entity_Id) return Node_Id
2433 Loc : constant Source_Ptr := Sloc (Typ);
2434 Def_Id : constant Node_Id :=
2435 Make_Defining_Identifier (Loc,
2436 Name_uDisp_Timed_Select);
2437 Params : constant List_Id := New_List;
2440 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2442 -- "T" - Object parameter
2443 -- "S" - Primitive operation slot
2444 -- "P" - Wrapped parameters
2448 -- "F" - Status flag
2450 SEU.Build_T (Loc, Typ, Params);
2451 SEU.Build_S (Loc, Params);
2452 SEU.Build_P (Loc, Params);
2455 Make_Parameter_Specification (Loc,
2456 Defining_Identifier =>
2457 Make_Defining_Identifier (Loc, Name_uD),
2459 New_Reference_To (Standard_Duration, Loc)));
2462 Make_Parameter_Specification (Loc,
2463 Defining_Identifier =>
2464 Make_Defining_Identifier (Loc, Name_uM),
2466 New_Reference_To (Standard_Integer, Loc)));
2468 SEU.Build_C (Loc, Params);
2469 SEU.Build_F (Loc, Params);
2471 Set_Is_Internal (Def_Id);
2474 Make_Procedure_Specification (Loc,
2475 Defining_Unit_Name => Def_Id,
2476 Parameter_Specifications => Params);
2477 end Make_Disp_Timed_Select_Spec;
2483 function Make_DT (Typ : Entity_Id) return List_Id is
2484 Loc : constant Source_Ptr := Sloc (Typ);
2485 Result : constant List_Id := New_List;
2486 Elab_Code : constant List_Id := New_List;
2488 Tname : constant Name_Id := Chars (Typ);
2489 Name_DT : constant Name_Id := New_External_Name (Tname, 'T');
2490 Name_DT_Ptr : constant Name_Id := New_External_Name (Tname, 'P');
2491 Name_SSD : constant Name_Id := New_External_Name (Tname, 'S');
2492 Name_TSD : constant Name_Id := New_External_Name (Tname, 'B');
2493 Name_Exname : constant Name_Id := New_External_Name (Tname, 'E');
2494 Name_No_Reg : constant Name_Id := New_External_Name (Tname, 'F');
2496 -- The following external name is only generated if Typ has interfaces
2497 Name_ITable : Name_Id;
2499 DT : constant Node_Id := Make_Defining_Identifier (Loc, Name_DT);
2500 DT_Ptr : constant Node_Id := Make_Defining_Identifier (Loc, Name_DT_Ptr);
2501 SSD : constant Node_Id := Make_Defining_Identifier (Loc, Name_SSD);
2502 TSD : constant Node_Id := Make_Defining_Identifier (Loc, Name_TSD);
2503 Exname : constant Node_Id := Make_Defining_Identifier (Loc, Name_Exname);
2504 No_Reg : constant Node_Id := Make_Defining_Identifier (Loc, Name_No_Reg);
2506 Generalized_Tag : constant Entity_Id := RTE (RE_Tag);
2507 Ancestor_Ifaces : Elist_Id;
2509 Has_Dispatch_Table : Boolean := True;
2512 Iface_Table_Node : Node_Id;
2514 Null_Parent_Tag : Boolean := False;
2515 Num_Ifaces : Nat := 0;
2519 Parent_Num_Ifaces : Nat := 0;
2520 Remotely_Callable : Entity_Id;
2521 RC_Offset_Node : Node_Id;
2522 Size_Expr_Node : Node_Id;
2523 Typ_Ifaces : Elist_Id;
2524 TSD_Aggr_List : List_Id;
2527 if not RTE_Available (RE_Tag) then
2528 Error_Msg_CRT ("tagged types", Typ);
2532 -- Ensure that the unit System_Storage_Elements is loaded. This is
2533 -- required to properly expand the routines of Ada.Tags
2535 if not RTU_Loaded (System_Storage_Elements)
2536 and then not Present (RTE (RE_Storage_Offset))
2538 raise Program_Error;
2541 if Ada_Version >= Ada_05 then
2543 -- Count the interface types of the parents
2547 if Typ /= Etype (Typ) then
2548 Parent := Etype (Typ);
2550 elsif Is_Concurrent_Record_Type (Typ) then
2551 Parent := Etype (First (Abstract_Interface_List (Typ)));
2554 if Present (Parent) then
2555 Collect_Abstract_Interfaces (Parent, Ancestor_Ifaces);
2557 AI := First_Elmt (Ancestor_Ifaces);
2558 while Present (AI) loop
2559 Parent_Num_Ifaces := Parent_Num_Ifaces + 1;
2564 -- Count the additional interfaces implemented by Typ
2566 Collect_Abstract_Interfaces (Typ, Typ_Ifaces);
2568 AI := First_Elmt (Typ_Ifaces);
2569 while Present (AI) loop
2570 Num_Ifaces := Num_Ifaces + 1;
2575 -- Count ancestors to compute the inheritance depth. For private
2576 -- extensions, always go to the full view in order to compute the
2577 -- real inheritance depth.
2580 Parent_Type : Entity_Id := Typ;
2586 P := Etype (Parent_Type);
2588 if Is_Private_Type (P) then
2589 P := Full_View (Base_Type (P));
2592 exit when P = Parent_Type;
2594 I_Depth := I_Depth + 1;
2599 -- Calculate the number of primitives of the dispatch table and the
2600 -- size of the Type_Specific_Data record.
2602 -- Abstract interfaces don't need the dispatch table. In addition,
2603 -- compiling with restriction No_Dispatching_Calls we do not generate
2604 -- the dispatch table.
2606 Has_Dispatch_Table :=
2607 not Is_Interface (Typ)
2608 and then not Restriction_Active (No_Dispatching_Calls);
2610 if Has_Dispatch_Table then
2611 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
2614 -- Dispatch table and related entities are allocated statically
2616 Set_Ekind (DT, E_Variable);
2617 Set_Is_Statically_Allocated (DT);
2619 Set_Ekind (DT_Ptr, E_Variable);
2620 Set_Is_Statically_Allocated (DT_Ptr);
2622 if Num_Ifaces > 0 then
2623 Name_ITable := New_External_Name (Tname, 'I');
2624 ITable := Make_Defining_Identifier (Loc, Name_ITable);
2626 Set_Ekind (ITable, E_Variable);
2627 Set_Is_Statically_Allocated (ITable);
2630 Set_Ekind (SSD, E_Variable);
2631 Set_Is_Statically_Allocated (SSD);
2633 Set_Ekind (TSD, E_Variable);
2634 Set_Is_Statically_Allocated (TSD);
2636 Set_Ekind (Exname, E_Variable);
2637 Set_Is_Statically_Allocated (Exname);
2639 Set_Ekind (No_Reg, E_Variable);
2640 Set_Is_Statically_Allocated (No_Reg);
2642 -- Generate code to create the storage for the Dispatch_Table object:
2644 -- DT : Storage_Array (1 .. Size_Expr);
2645 -- for DT'Alignment use Address'Alignment
2647 -- Under No_Dispatching_Calls the size of the table is small just
2649 -- 1) the pointer to the TSD
2650 -- 2) a dummy entry used as the Tag of the type (see a-tags.ads).
2652 if not Has_Dispatch_Table then
2654 New_Reference_To (RTE (RE_DT_Min_Prologue_Size), Loc);
2656 -- If the object has no primitives we ensure that the table will
2657 -- have at least a dummy entry which will be used as the Tag.
2659 -- Size_Expr := DT_Prologue_Size + DT_Entry_Size
2661 elsif Nb_Prim = 0 then
2665 New_Reference_To (RTE (RE_DT_Prologue_Size), Loc),
2667 New_Reference_To (RTE (RE_DT_Entry_Size), Loc));
2669 -- Common case. The dispatch table has space to save the pointers to
2670 -- all the predefined primitives, the C++ ABI header of the DT, and
2671 -- the pointers to the primitives of Typ. That is,
2673 -- Size_Expr := DT_Prologue_Size + nb_prim * DT_Entry_Size
2679 New_Reference_To (RTE (RE_DT_Prologue_Size), Loc),
2681 Make_Op_Multiply (Loc,
2683 New_Reference_To (RTE (RE_DT_Entry_Size), Loc),
2685 Make_Integer_Literal (Loc, Nb_Prim)));
2689 Make_Object_Declaration (Loc,
2690 Defining_Identifier => DT,
2691 Aliased_Present => True,
2692 Object_Definition =>
2693 Make_Subtype_Indication (Loc,
2694 Subtype_Mark => New_Reference_To
2695 (RTE (RE_Storage_Array), Loc),
2696 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
2697 Constraints => New_List (
2699 Low_Bound => Make_Integer_Literal (Loc, 1),
2700 High_Bound => Size_Expr_Node))))));
2703 Make_Attribute_Definition_Clause (Loc,
2704 Name => New_Reference_To (DT, Loc),
2705 Chars => Name_Alignment,
2707 Make_Attribute_Reference (Loc,
2708 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
2709 Attribute_Name => Name_Alignment)));
2711 -- Generate code to create the pointer to the dispatch table
2713 -- DT_Ptr : Tag := Tag!(DT'Address);
2715 -- According to the C++ ABI, the base of the vtable is located after a
2716 -- prologue containing Offset_To_Top, and Typeinfo_Ptr. Hence, we move
2717 -- down the pointer to the real base of the vtable
2719 if not Has_Dispatch_Table then
2721 Make_Object_Declaration (Loc,
2722 Defining_Identifier => DT_Ptr,
2723 Constant_Present => True,
2724 Object_Definition => New_Reference_To (Generalized_Tag, Loc),
2726 Unchecked_Convert_To (Generalized_Tag,
2729 Unchecked_Convert_To (RTE (RE_Storage_Offset),
2730 Make_Attribute_Reference (Loc,
2731 Prefix => New_Reference_To (DT, Loc),
2732 Attribute_Name => Name_Address)),
2734 New_Reference_To (RTE (RE_DT_Typeinfo_Ptr_Size), Loc)))));
2738 Make_Object_Declaration (Loc,
2739 Defining_Identifier => DT_Ptr,
2740 Constant_Present => True,
2741 Object_Definition => New_Reference_To (Generalized_Tag, Loc),
2743 Unchecked_Convert_To (Generalized_Tag,
2746 Unchecked_Convert_To (RTE (RE_Storage_Offset),
2747 Make_Attribute_Reference (Loc,
2748 Prefix => New_Reference_To (DT, Loc),
2749 Attribute_Name => Name_Address)),
2751 New_Reference_To (RTE (RE_DT_Prologue_Size), Loc)))));
2754 -- Save the tag in the Access_Disp_Table attribute
2756 if No (Access_Disp_Table (Typ)) then
2757 Set_Access_Disp_Table (Typ, New_Elmt_List);
2760 Prepend_Elmt (DT_Ptr, Access_Disp_Table (Typ));
2762 -- Generate code to define the boolean that controls registration, in
2763 -- order to avoid multiple registrations for tagged types defined in
2764 -- multiple-called scopes.
2767 Make_Object_Declaration (Loc,
2768 Defining_Identifier => No_Reg,
2769 Object_Definition => New_Reference_To (Standard_Boolean, Loc),
2770 Expression => New_Reference_To (Standard_True, Loc)));
2773 -- Set_Signature (DT_Ptr, Value);
2775 if Has_Dispatch_Table
2776 and then RTE_Available (RE_Set_Signature)
2778 if Is_Interface (Typ) then
2779 Append_To (Elab_Code,
2780 Make_DT_Access_Action (Typ,
2781 Action => Set_Signature,
2783 New_Reference_To (DT_Ptr, Loc),
2784 New_Reference_To (RTE (RE_Abstract_Interface), Loc))));
2787 Append_To (Elab_Code,
2788 Make_DT_Access_Action (Typ,
2789 Action => Set_Signature,
2791 New_Reference_To (DT_Ptr, Loc),
2792 New_Reference_To (RTE (RE_Primary_DT), Loc))));
2796 -- Generate: Exname : constant String := full_qualified_name (typ);
2797 -- The type itself may be an anonymous parent type, so use the first
2798 -- subtype to have a user-recognizable name.
2801 Make_Object_Declaration (Loc,
2802 Defining_Identifier => Exname,
2803 Constant_Present => True,
2804 Object_Definition => New_Reference_To (Standard_String, Loc),
2806 Make_String_Literal (Loc,
2807 Full_Qualified_Name (First_Subtype (Typ)))));
2809 -- Calculate the value of the RC_Offset component. These are the
2810 -- valid valiues and their meaning:
2811 -- >0: For simple types with controlled components is
2812 -- type._record_controller'position
2813 -- 0: For types with no controlled components
2814 -- -1: For complex types with controlled components where the position
2815 -- of the record controller is not statically computable but there
2816 -- are controlled components at this level. The _Controller field
2817 -- is available right after the _parent.
2818 -- -2: There are no controlled components at this level. We need to
2819 -- get the position from the parent.
2821 if Is_Interface (Typ)
2822 or else not Has_Controlled_Component (Typ)
2824 RC_Offset_Node := Make_Integer_Literal (Loc, 0);
2826 elsif Etype (Typ) /= Typ
2827 and then Has_Discriminants (Etype (Typ))
2829 if Has_New_Controlled_Component (Typ) then
2830 RC_Offset_Node := Make_Integer_Literal (Loc, -1);
2832 RC_Offset_Node := Make_Integer_Literal (Loc, -2);
2836 Make_Attribute_Reference (Loc,
2838 Make_Selected_Component (Loc,
2839 Prefix => New_Reference_To (Typ, Loc),
2841 New_Reference_To (Controller_Component (Typ), Loc)),
2842 Attribute_Name => Name_Position);
2844 -- This is not proper Ada code to use the attribute 'Position
2845 -- on something else than an object but this is supported by
2846 -- the back end (see comment on the Bit_Component attribute in
2847 -- sem_attr). So we avoid semantic checking here.
2849 -- Is this documented in sinfo.ads??? it should be!
2851 Set_Analyzed (RC_Offset_Node);
2852 Set_Etype (Prefix (RC_Offset_Node), RTE (RE_Record_Controller));
2853 Set_Etype (Prefix (Prefix (RC_Offset_Node)), Typ);
2854 Set_Etype (Selector_Name (Prefix (RC_Offset_Node)),
2855 RTE (RE_Record_Controller));
2856 Set_Etype (RC_Offset_Node, RTE (RE_Storage_Offset));
2859 -- Set the pointer to the Interfaces_Table (if any). Otherwise the
2860 -- corresponding access component is set to null. The table of
2861 -- interfaces is required for AI-405
2863 if RTE_Record_Component_Available (RE_Ifaces_Table_Ptr) then
2864 if Num_Ifaces = 0 then
2866 New_Reference_To (RTE (RE_Null_Address), Loc);
2868 -- Generate the Interface_Table object.
2872 Make_Object_Declaration (Loc,
2873 Defining_Identifier => ITable,
2874 Aliased_Present => True,
2875 Object_Definition =>
2876 Make_Subtype_Indication (Loc,
2877 Subtype_Mark => New_Reference_To
2878 (RTE (RE_Interface_Data), Loc),
2879 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
2880 Constraints => New_List (
2881 Make_Integer_Literal (Loc,
2885 Make_Attribute_Reference (Loc,
2886 Prefix => New_Reference_To (ITable, Loc),
2887 Attribute_Name => Name_Address);
2891 -- Generate: Set_Remotely_Callable (DT_Ptr, Status); where Status is
2892 -- described in E.4 (18)
2894 Remotely_Callable :=
2897 or else Is_Shared_Passive (Typ)
2899 ((Is_Remote_Types (Typ)
2900 or else Is_Remote_Call_Interface (Typ))
2901 and then Original_View_In_Visible_Part (Typ))
2902 or else not Comes_From_Source (Typ));
2904 -- Generate code to create the storage for the type specific data object
2905 -- with enough space to store the tags of the ancestors plus the tags
2906 -- of all the implemented interfaces (as described in a-tags.adb).
2908 -- TSD : Type_Specific_Data (I_Depth) :=
2909 -- (Idepth => I_Depth,
2910 -- Access_Level => Type_Access_Level (Typ),
2911 -- Expanded_Name => Cstring_Ptr!(Exname'Address))
2912 -- [ External_Tag => Cstring_Ptr!(Exname'Address)) ]
2913 -- RC_Offset => <<integer-value>>,
2914 -- Remotely_Callable => <<boolean-value>>
2915 -- [ Ifaces_Table_Ptr => <<access-value>> ]
2917 -- for TSD'Alignment use Address'Alignment
2919 TSD_Aggr_List := New_List (
2920 Make_Component_Association (Loc,
2921 Choices => New_List (
2922 New_Occurrence_Of (RTE_Record_Component (RE_Idepth), Loc)),
2923 Expression => Make_Integer_Literal (Loc, I_Depth)),
2925 Make_Component_Association (Loc,
2926 Choices => New_List (
2927 New_Occurrence_Of (RTE_Record_Component (RE_Access_Level), Loc)),
2928 Expression => Make_Integer_Literal (Loc, Type_Access_Level (Typ))),
2930 Make_Component_Association (Loc,
2931 Choices => New_List (
2933 (RTE_Record_Component (RE_Expanded_Name), Loc)),
2935 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
2936 Make_Attribute_Reference (Loc,
2937 Prefix => New_Reference_To (Exname, Loc),
2938 Attribute_Name => Name_Address))));
2940 if not Has_External_Tag_Rep_Clause (Typ) then
2942 -- Should be the external name not the qualified name???
2944 Append_To (TSD_Aggr_List,
2945 Make_Component_Association (Loc,
2946 Choices => New_List (
2948 (RTE_Record_Component (RE_External_Tag), Loc)),
2950 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
2951 Make_Attribute_Reference (Loc,
2952 Prefix => New_Reference_To (Exname, Loc),
2953 Attribute_Name => Name_Address))));
2956 Append_List_To (TSD_Aggr_List, New_List (
2957 Make_Component_Association (Loc,
2958 Choices => New_List (
2959 New_Occurrence_Of (RTE_Record_Component (RE_RC_Offset), Loc)),
2960 Expression => RC_Offset_Node),
2962 Make_Component_Association (Loc,
2963 Choices => New_List (
2965 (RTE_Record_Component (RE_Remotely_Callable), Loc)),
2966 Expression => New_Occurrence_Of (Remotely_Callable, Loc))));
2968 if RTE_Record_Component_Available (RE_Ifaces_Table_Ptr) then
2969 Append_To (TSD_Aggr_List,
2970 Make_Component_Association (Loc,
2971 Choices => New_List (
2973 (RTE_Record_Component (RE_Ifaces_Table_Ptr), Loc)),
2974 Expression => Iface_Table_Node));
2977 Append_To (TSD_Aggr_List,
2978 Make_Component_Association (Loc,
2979 Choices => New_List (Make_Others_Choice (Loc)),
2980 Expression => Empty,
2981 Box_Present => True));
2983 -- Save the expanded name in the dispatch table
2986 Make_Object_Declaration (Loc,
2987 Defining_Identifier => TSD,
2988 Aliased_Present => True,
2989 Object_Definition =>
2990 Make_Subtype_Indication (Loc,
2991 Subtype_Mark => New_Reference_To (
2992 RTE (RE_Type_Specific_Data), Loc),
2994 Make_Index_Or_Discriminant_Constraint (Loc,
2995 Constraints => New_List (
2996 Make_Integer_Literal (Loc, I_Depth)))),
2997 Expression => Make_Aggregate (Loc,
2998 Component_Associations => TSD_Aggr_List)));
3001 Make_Attribute_Definition_Clause (Loc,
3002 Name => New_Reference_To (TSD, Loc),
3003 Chars => Name_Alignment,
3005 Make_Attribute_Reference (Loc,
3006 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
3007 Attribute_Name => Name_Alignment)));
3009 -- Generate code to put the Address of the TSD in the dispatch table
3011 Append_To (Elab_Code,
3013 Tag_Node => New_Reference_To (DT_Ptr, Loc),
3015 Make_Attribute_Reference (Loc,
3016 Prefix => New_Reference_To (TSD, Loc),
3017 Attribute_Name => Name_Address)));
3019 -- Generate extra code required for synchronized interfaces
3021 if RTE_Available (RE_Set_Tagged_Kind) then
3022 if Ada_Version >= Ada_05
3023 and then not Is_Interface (Typ)
3024 and then not Is_Abstract_Type (Typ)
3025 and then not Is_Controlled (Typ)
3026 and then not Restriction_Active (No_Dispatching_Calls)
3029 -- Set_Type_Kind (T'Tag, Type_Kind (Typ));
3031 Append_To (Elab_Code,
3032 Make_DT_Access_Action (Typ,
3033 Action => Set_Tagged_Kind,
3035 New_Reference_To (DT_Ptr, Loc), -- DTptr
3036 Tagged_Kind (Typ)))); -- Value
3038 -- Generate the Select Specific Data table for synchronized
3039 -- types that implement a synchronized interface. The size
3040 -- of the table is constrained by the number of non-predefined
3041 -- primitive operations.
3043 if Has_Dispatch_Table
3044 and then Is_Concurrent_Record_Type (Typ)
3045 and then Has_Abstract_Interfaces (Typ)
3047 -- No need to generate this code if Nb_Prim = 0 ???
3050 Make_Object_Declaration (Loc,
3051 Defining_Identifier => SSD,
3052 Aliased_Present => True,
3053 Object_Definition =>
3054 Make_Subtype_Indication (Loc,
3055 Subtype_Mark => New_Reference_To (
3056 RTE (RE_Select_Specific_Data), Loc),
3058 Make_Index_Or_Discriminant_Constraint (Loc,
3059 Constraints => New_List (
3060 Make_Integer_Literal (Loc, Nb_Prim))))));
3062 -- Set the pointer to the Select Specific Data table in the TSD
3064 Append_To (Elab_Code,
3065 Make_DT_Access_Action (Typ,
3068 New_Reference_To (DT_Ptr, Loc), -- DTptr
3069 Make_Attribute_Reference (Loc, -- Value
3070 Prefix => New_Reference_To (SSD, Loc),
3071 Attribute_Name => Name_Address))));
3076 -- If the ancestor is a CPP_Class type we inherit the dispatch tables
3077 -- in the init proc, and we don't need to fill them in here.
3079 if Is_CPP_Class (Etype (Typ)) then
3082 -- Otherwise we fill in the dispatch tables here
3085 if Typ = Etype (Typ)
3086 or else Is_CPP_Class (Etype (Typ))
3087 or else Is_Interface (Typ)
3089 Null_Parent_Tag := True;
3092 Unchecked_Convert_To (Generalized_Tag,
3093 Make_Integer_Literal (Loc, 0));
3095 Unchecked_Convert_To (Generalized_Tag,
3096 Make_Integer_Literal (Loc, 0));
3101 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc);
3104 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc);
3107 if Typ /= Etype (Typ)
3108 and then not Is_Interface (Typ)
3109 and then not Restriction_Active (No_Dispatching_Calls)
3111 -- Inherit the dispatch table
3113 if not Is_Interface (Etype (Typ)) then
3114 if Restriction_Active (No_Dispatching_Calls) then
3118 if not Null_Parent_Tag then
3120 Nb_Prims : constant Int :=
3121 UI_To_Int (DT_Entry_Count
3122 (First_Tag_Component (Etype (Typ))));
3124 Append_To (Elab_Code,
3125 Build_Inherit_Predefined_Prims (Loc,
3126 Old_Tag_Node => Old_Tag1,
3128 New_Reference_To (DT_Ptr, Loc)));
3130 if Nb_Prims /= 0 then
3131 Append_To (Elab_Code,
3132 Build_Inherit_Prims (Loc,
3133 Old_Tag_Node => Old_Tag2,
3134 New_Tag_Node => New_Reference_To (DT_Ptr, Loc),
3135 Num_Prims => Nb_Prims));
3142 -- Inherit the secondary dispatch tables of the ancestor
3144 if not Restriction_Active (No_Dispatching_Calls)
3145 and then not Is_CPP_Class (Etype (Typ))
3148 Sec_DT_Ancestor : Elmt_Id :=
3151 (Access_Disp_Table (Etype (Typ))));
3152 Sec_DT_Typ : Elmt_Id :=
3155 (Access_Disp_Table (Typ)));
3157 procedure Copy_Secondary_DTs (Typ : Entity_Id);
3158 -- Local procedure required to climb through the ancestors
3159 -- and copy the contents of all their secondary dispatch
3162 ------------------------
3163 -- Copy_Secondary_DTs --
3164 ------------------------
3166 procedure Copy_Secondary_DTs (Typ : Entity_Id) is
3171 -- Climb to the ancestor (if any) handling private types
3173 if Present (Full_View (Etype (Typ))) then
3174 if Full_View (Etype (Typ)) /= Typ then
3175 Copy_Secondary_DTs (Full_View (Etype (Typ)));
3178 elsif Etype (Typ) /= Typ then
3179 Copy_Secondary_DTs (Etype (Typ));
3182 if Present (Abstract_Interfaces (Typ))
3183 and then not Is_Empty_Elmt_List
3184 (Abstract_Interfaces (Typ))
3186 Iface := First_Elmt (Abstract_Interfaces (Typ));
3187 E := First_Entity (Typ);
3189 and then Present (Node (Sec_DT_Ancestor))
3191 if Is_Tag (E) and then Chars (E) /= Name_uTag then
3192 if not Is_Interface (Etype (Typ)) then
3194 -- Inherit the dispatch table
3197 Num_Prims : constant Int :=
3198 UI_To_Int (DT_Entry_Count (E));
3200 Append_To (Elab_Code,
3201 Build_Inherit_Predefined_Prims (Loc,
3203 Unchecked_Convert_To (RTE (RE_Tag),
3205 (Node (Sec_DT_Ancestor), Loc)),
3207 Unchecked_Convert_To (RTE (RE_Tag),
3209 (Node (Sec_DT_Typ), Loc))));
3211 if Num_Prims /= 0 then
3212 Append_To (Elab_Code,
3213 Build_Inherit_Prims (Loc,
3215 Unchecked_Convert_To
3218 (Node (Sec_DT_Ancestor),
3221 Unchecked_Convert_To
3224 (Node (Sec_DT_Typ), Loc)),
3225 Num_Prims => Num_Prims));
3230 Next_Elmt (Sec_DT_Ancestor);
3231 Next_Elmt (Sec_DT_Typ);
3238 end Copy_Secondary_DTs;
3241 if Present (Node (Sec_DT_Ancestor)) then
3243 -- Handle private types
3245 if Present (Full_View (Typ)) then
3246 Copy_Secondary_DTs (Full_View (Typ));
3248 Copy_Secondary_DTs (Typ);
3256 -- Inherit_TSD (parent'tag, DT_Ptr);
3258 if not Is_Interface (Typ) then
3259 if Typ = Etype (Typ)
3260 or else Is_CPP_Class (Etype (Typ))
3262 -- New_TSD (DT_Ptr);
3264 Append_List_To (Elab_Code,
3266 New_Tag_Node => New_Reference_To (DT_Ptr, Loc)));
3268 -- Inherit_TSD (parent'tag, DT_Ptr);
3270 Append_To (Elab_Code,
3271 Build_Inherit_TSD (Loc,
3274 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))),
3276 New_Tag_Node => New_Reference_To (DT_Ptr, Loc),
3278 Parent_Num_Ifaces => Parent_Num_Ifaces));
3283 if not Is_Interface (Typ)
3284 and then RTE_Available (RE_Set_Offset_To_Top)
3287 -- Set_Offset_To_Top (0, DT_Ptr, True, 0, null);
3289 Append_To (Elab_Code,
3290 Make_Procedure_Call_Statement (Loc,
3291 Name => New_Reference_To (RTE (RE_Set_Offset_To_Top), Loc),
3292 Parameter_Associations => New_List (
3293 New_Reference_To (RTE (RE_Null_Address), Loc),
3294 New_Reference_To (DT_Ptr, Loc),
3295 New_Occurrence_Of (Standard_True, Loc),
3296 Make_Integer_Literal (Loc, Uint_0),
3297 New_Reference_To (RTE (RE_Null_Address), Loc))));
3300 -- Generate code to register the Tag in the External_Tag hash table for
3301 -- the pure Ada type only.
3303 -- Register_Tag (Dt_Ptr);
3305 -- Skip this if routine not available, or in No_Run_Time mode or Typ is
3306 -- an abstract interface type (because the table to register it is not
3307 -- available in the abstract type but in types implementing this
3310 if not Has_External_Tag_Rep_Clause (Typ)
3311 and then not No_Run_Time_Mode
3312 and then RTE_Available (RE_Register_Tag)
3313 and then Is_RTE (RTE (RE_Tag), RE_Tag)
3314 and then not Is_Interface (Typ)
3316 Append_To (Elab_Code,
3317 Make_Procedure_Call_Statement (Loc,
3318 Name => New_Reference_To (RTE (RE_Register_Tag), Loc),
3319 Parameter_Associations =>
3320 New_List (New_Reference_To (DT_Ptr, Loc))));
3329 Append_To (Elab_Code,
3330 Make_Assignment_Statement (Loc,
3331 Name => New_Reference_To (No_Reg, Loc),
3332 Expression => New_Reference_To (Standard_False, Loc)));
3335 Make_Implicit_If_Statement (Typ,
3336 Condition => New_Reference_To (No_Reg, Loc),
3337 Then_Statements => Elab_Code));
3339 -- Ada 2005 (AI-251): Register the tag of the interfaces into the table
3342 if Num_Ifaces > 0 then
3347 -- If the parent is an interface we must generate code to register
3348 -- all its interfaces; otherwise this code is not needed because
3349 -- Inherit_TSD has already inherited such interfaces.
3351 if Is_Concurrent_Record_Type (Typ)
3352 or else (Etype (Typ) /= Typ and then Is_Interface (Etype (Typ)))
3356 AI := First_Elmt (Ancestor_Ifaces);
3357 while Present (AI) loop
3359 -- Register_Interface (DT_Ptr, Interface'Tag);
3362 Make_DT_Access_Action (Typ,
3363 Action => Register_Interface_Tag,
3365 Node1 => New_Reference_To (DT_Ptr, Loc),
3366 Node2 => New_Reference_To
3369 (Access_Disp_Table (Node (AI)))),
3371 Node3 => Make_Integer_Literal (Loc, Position))));
3373 Position := Position + 1;
3378 -- Register the interfaces that are not implemented by the
3381 AI := First_Elmt (Typ_Ifaces);
3383 -- Skip the interfaces implemented by the ancestor
3385 for Count in 1 .. Parent_Num_Ifaces loop
3389 -- Register the additional interfaces
3391 Position := Parent_Num_Ifaces + 1;
3392 while Present (AI) loop
3395 -- Register_Interface (DT_Ptr, Interface'Tag);
3397 if not Is_Interface (Typ)
3398 or else Typ /= Node (AI)
3401 Make_DT_Access_Action (Typ,
3402 Action => Register_Interface_Tag,
3404 Node1 => New_Reference_To (DT_Ptr, Loc),
3405 Node2 => New_Reference_To
3408 (Access_Disp_Table (Node (AI)))),
3410 Node3 => Make_Integer_Literal (Loc, Position))));
3412 Position := Position + 1;
3418 pragma Assert (Position = Num_Ifaces + 1);
3425 ---------------------------
3426 -- Make_DT_Access_Action --
3427 ---------------------------
3429 function Make_DT_Access_Action
3431 Action : DT_Access_Action;
3432 Args : List_Id) return Node_Id
3434 Action_Name : constant Entity_Id := RTE (Ada_Actions (Action));
3440 -- This is a constant
3442 return New_Reference_To (Action_Name, Sloc (Typ));
3445 pragma Assert (List_Length (Args) = Action_Nb_Arg (Action));
3447 Loc := Sloc (First (Args));
3449 if Action_Is_Proc (Action) then
3451 Make_Procedure_Call_Statement (Loc,
3452 Name => New_Reference_To (Action_Name, Loc),
3453 Parameter_Associations => Args);
3457 Make_Function_Call (Loc,
3458 Name => New_Reference_To (Action_Name, Loc),
3459 Parameter_Associations => Args);
3461 end Make_DT_Access_Action;
3463 -----------------------
3464 -- Make_Secondary_DT --
3465 -----------------------
3467 procedure Make_Secondary_DT
3469 Ancestor_Typ : Entity_Id;
3473 Acc_Disp_Tables : in out Elist_Id;
3474 Result : out List_Id)
3476 Loc : constant Source_Ptr := Sloc (AI_Tag);
3477 Generalized_Tag : constant Entity_Id := RTE (RE_Interface_Tag);
3478 Name_DT : constant Name_Id := New_Internal_Name ('T');
3479 Empty_DT : Boolean := False;
3481 Iface_DT_Ptr : Node_Id;
3482 Name_DT_Ptr : Name_Id;
3485 Size_Expr_Node : Node_Id;
3491 -- Generate a unique external name associated with the secondary
3492 -- dispatch table. This external name will be used to declare an
3493 -- access to this secondary dispatch table, value that will be used
3494 -- for the elaboration of Typ's objects and also for the elaboration
3495 -- of objects of any derivation of Typ that do not override any
3496 -- primitive operation of Typ.
3498 Get_Secondary_DT_External_Name (Typ, Ancestor_Typ, Suffix_Index);
3501 Name_DT_Ptr := New_External_Name (Tname, "P");
3502 Iface_DT := Make_Defining_Identifier (Loc, Name_DT);
3503 Iface_DT_Ptr := Make_Defining_Identifier (Loc, Name_DT_Ptr);
3505 -- Dispatch table and related entities are allocated statically
3507 Set_Ekind (Iface_DT, E_Variable);
3508 Set_Is_Statically_Allocated (Iface_DT);
3510 Set_Ekind (Iface_DT_Ptr, E_Variable);
3511 Set_Is_Statically_Allocated (Iface_DT_Ptr);
3513 -- Generate code to create the storage for the Dispatch_Table object.
3514 -- If the number of primitives of Typ is 0 we reserve a dummy single
3515 -- entry for its DT because at run-time the pointer to this dummy entry
3516 -- will be used as the tag.
3518 Nb_Prim := UI_To_Int (DT_Entry_Count (AI_Tag));
3525 -- DT : Storage_Array (1..DT_Prologue_Size+nb_prim*DT_Entry_Size);
3526 -- for DT'Alignment use Address'Alignment
3531 New_Reference_To (RTE (RE_DT_Prologue_Size), Loc),
3533 Make_Op_Multiply (Loc,
3535 New_Reference_To (RTE (RE_DT_Entry_Size), Loc),
3537 Make_Integer_Literal (Loc, Nb_Prim)));
3540 Make_Object_Declaration (Loc,
3541 Defining_Identifier => Iface_DT,
3542 Aliased_Present => True,
3543 Object_Definition =>
3544 Make_Subtype_Indication (Loc,
3545 Subtype_Mark => New_Reference_To (RTE (RE_Storage_Array), Loc),
3546 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
3547 Constraints => New_List (
3549 Low_Bound => Make_Integer_Literal (Loc, 1),
3550 High_Bound => Size_Expr_Node))))));
3553 Make_Attribute_Definition_Clause (Loc,
3554 Name => New_Reference_To (Iface_DT, Loc),
3555 Chars => Name_Alignment,
3557 Make_Attribute_Reference (Loc,
3558 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
3559 Attribute_Name => Name_Alignment)));
3561 -- Generate code to create the pointer to the dispatch table
3563 -- Iface_DT_Ptr : Tag := Tag!(DT'Address);
3565 -- According to the C++ ABI, the base of the vtable is located
3566 -- after the following prologue: Offset_To_Top, and Typeinfo_Ptr.
3567 -- Hence, move the pointer down to the real base of the vtable.
3570 Make_Object_Declaration (Loc,
3571 Defining_Identifier => Iface_DT_Ptr,
3572 Constant_Present => True,
3573 Object_Definition => New_Reference_To (Generalized_Tag, Loc),
3575 Unchecked_Convert_To (Generalized_Tag,
3578 Unchecked_Convert_To (RTE (RE_Storage_Offset),
3579 Make_Attribute_Reference (Loc,
3580 Prefix => New_Reference_To (Iface_DT, Loc),
3581 Attribute_Name => Name_Address)),
3583 New_Reference_To (RTE (RE_DT_Prologue_Size), Loc)))));
3585 -- Note: Offset_To_Top will be initialized by the init subprogram
3587 -- Set Access_Disp_Table field to be the dispatch table pointer
3589 if not (Present (Acc_Disp_Tables)) then
3590 Acc_Disp_Tables := New_Elmt_List;
3593 Append_Elmt (Iface_DT_Ptr, Acc_Disp_Tables);
3595 -- Step 1: Generate an Object Specific Data (OSD) table
3597 OSD := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
3599 -- Nothing to do if configurable run time does not support the
3600 -- Object_Specific_Data entity.
3602 if not RTE_Available (RE_Object_Specific_Data) then
3603 Error_Msg_CRT ("abstract interface types", Typ);
3608 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims);
3609 -- where the constraint is used to allocate space for the
3610 -- non-predefined primitive operations only.
3613 Make_Object_Declaration (Loc,
3614 Defining_Identifier => OSD,
3615 Object_Definition =>
3616 Make_Subtype_Indication (Loc,
3617 Subtype_Mark => New_Reference_To (
3618 RTE (RE_Object_Specific_Data), Loc),
3620 Make_Index_Or_Discriminant_Constraint (Loc,
3621 Constraints => New_List (
3622 Make_Integer_Literal (Loc, Nb_Prim))))));
3625 Make_DT_Access_Action (Typ,
3626 Action => Set_Signature,
3628 Unchecked_Convert_To (RTE (RE_Tag),
3629 New_Reference_To (Iface_DT_Ptr, Loc)),
3630 New_Reference_To (RTE (RE_Secondary_DT), Loc))));
3633 -- Ada.Tags.Set_OSD (Iface_DT_Ptr, OSD);
3636 Make_DT_Access_Action (Typ,
3639 Unchecked_Convert_To (RTE (RE_Tag),
3640 New_Reference_To (Iface_DT_Ptr, Loc)),
3641 Make_Attribute_Reference (Loc,
3642 Prefix => New_Reference_To (OSD, Loc),
3643 Attribute_Name => Name_Address))));
3645 if Ada_Version >= Ada_05
3646 and then not Is_Interface (Typ)
3647 and then not Is_Abstract_Type (Typ)
3648 and then not Is_Controlled (Typ)
3649 and then RTE_Available (RE_Set_Tagged_Kind)
3650 and then not Restriction_Active (No_Dispatching_Calls)
3653 -- Set_Tagged_Kind (Iface'Tag, Tagged_Kind (Iface));
3656 Make_DT_Access_Action (Typ,
3657 Action => Set_Tagged_Kind,
3659 Unchecked_Convert_To (RTE (RE_Tag), -- DTptr
3660 New_Reference_To (Iface_DT_Ptr, Loc)),
3661 Tagged_Kind (Typ)))); -- Value
3664 and then Is_Concurrent_Record_Type (Typ)
3665 and then Has_Abstract_Interfaces (Typ)
3669 Prim_Alias : Entity_Id;
3670 Prim_Elmt : Elmt_Id;
3673 -- Step 2: Populate the OSD table
3675 Prim_Alias := Empty;
3676 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3677 while Present (Prim_Elmt) loop
3678 Prim := Node (Prim_Elmt);
3680 if Present (Abstract_Interface_Alias (Prim))
3681 and then Find_Dispatching_Type
3682 (Abstract_Interface_Alias (Prim)) = Iface
3684 Prim_Alias := Abstract_Interface_Alias (Prim);
3687 -- Ada.Tags.Set_Offset_Index (Tag (Iface_DT_Ptr),
3688 -- Secondary_DT_Pos, Primary_DT_pos);
3691 Make_DT_Access_Action (Iface,
3692 Action => Set_Offset_Index,
3694 Unchecked_Convert_To (RTE (RE_Tag),
3695 New_Reference_To (Iface_DT_Ptr, Loc)),
3696 Make_Integer_Literal (Loc,
3697 DT_Position (Prim_Alias)),
3698 Make_Integer_Literal (Loc,
3699 DT_Position (Alias (Prim))))));
3702 Next_Elmt (Prim_Elmt);
3707 end Make_Secondary_DT;
3709 -------------------------------------
3710 -- Make_Select_Specific_Data_Table --
3711 -------------------------------------
3713 function Make_Select_Specific_Data_Table
3714 (Typ : Entity_Id) return List_Id
3716 Assignments : constant List_Id := New_List;
3717 Loc : constant Source_Ptr := Sloc (Typ);
3719 Conc_Typ : Entity_Id;
3723 Prim_Als : Entity_Id;
3724 Prim_Elmt : Elmt_Id;
3728 type Examined_Array is array (Int range <>) of Boolean;
3730 function Find_Entry_Index (E : Entity_Id) return Uint;
3731 -- Given an entry, find its index in the visible declarations of the
3732 -- corresponding concurrent type of Typ.
3734 ----------------------
3735 -- Find_Entry_Index --
3736 ----------------------
3738 function Find_Entry_Index (E : Entity_Id) return Uint is
3739 Index : Uint := Uint_1;
3740 Subp_Decl : Entity_Id;
3744 and then not Is_Empty_List (Decls)
3746 Subp_Decl := First (Decls);
3747 while Present (Subp_Decl) loop
3748 if Nkind (Subp_Decl) = N_Entry_Declaration then
3749 if Defining_Identifier (Subp_Decl) = E then
3761 end Find_Entry_Index;
3763 -- Start of processing for Make_Select_Specific_Data_Table
3766 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3768 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
3770 if Present (Corresponding_Concurrent_Type (Typ)) then
3771 Conc_Typ := Corresponding_Concurrent_Type (Typ);
3773 if Ekind (Conc_Typ) = E_Protected_Type then
3774 Decls := Visible_Declarations (Protected_Definition (
3775 Parent (Conc_Typ)));
3777 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
3778 Decls := Visible_Declarations (Task_Definition (
3779 Parent (Conc_Typ)));
3783 -- Count the non-predefined primitive operations
3785 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3786 while Present (Prim_Elmt) loop
3787 Prim := Node (Prim_Elmt);
3789 if not (Is_Predefined_Dispatching_Operation (Prim)
3790 or else Is_Predefined_Dispatching_Alias (Prim))
3792 Nb_Prim := Nb_Prim + 1;
3795 Next_Elmt (Prim_Elmt);
3799 Examined : Examined_Array (1 .. Nb_Prim) := (others => False);
3802 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3803 while Present (Prim_Elmt) loop
3804 Prim := Node (Prim_Elmt);
3806 -- Look for primitive overriding an abstract interface subprogram
3808 if Present (Abstract_Interface_Alias (Prim))
3809 and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
3811 Prim_Pos := DT_Position (Alias (Prim));
3812 pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
3813 Examined (UI_To_Int (Prim_Pos)) := True;
3815 -- Set the primitive operation kind regardless of subprogram
3817 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
3819 Append_To (Assignments,
3820 Make_DT_Access_Action (Typ,
3821 Action => Set_Prim_Op_Kind,
3823 New_Reference_To (DT_Ptr, Loc),
3824 Make_Integer_Literal (Loc, Prim_Pos),
3825 Prim_Op_Kind (Alias (Prim), Typ))));
3827 -- Retrieve the root of the alias chain
3830 while Present (Alias (Prim_Als)) loop
3831 Prim_Als := Alias (Prim_Als);
3834 -- In the case of an entry wrapper, set the entry index
3836 if Ekind (Prim) = E_Procedure
3837 and then Is_Primitive_Wrapper (Prim_Als)
3838 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
3841 -- Ada.Tags.Set_Entry_Index
3842 -- (DT_Ptr, <position>, <index>);
3844 Append_To (Assignments,
3845 Make_DT_Access_Action (Typ,
3846 Action => Set_Entry_Index,
3848 New_Reference_To (DT_Ptr, Loc),
3849 Make_Integer_Literal (Loc, Prim_Pos),
3850 Make_Integer_Literal (Loc,
3852 (Wrapped_Entity (Prim_Als))))));
3856 Next_Elmt (Prim_Elmt);
3861 end Make_Select_Specific_Data_Table;
3863 -----------------------------------
3864 -- Original_View_In_Visible_Part --
3865 -----------------------------------
3867 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
3868 Scop : constant Entity_Id := Scope (Typ);
3871 -- The scope must be a package
3873 if Ekind (Scop) /= E_Package
3874 and then Ekind (Scop) /= E_Generic_Package
3879 -- A type with a private declaration has a private view declared in
3880 -- the visible part.
3882 if Has_Private_Declaration (Typ) then
3886 return List_Containing (Parent (Typ)) =
3887 Visible_Declarations (Specification (Unit_Declaration_Node (Scop)));
3888 end Original_View_In_Visible_Part;
3894 function Prim_Op_Kind
3896 Typ : Entity_Id) return Node_Id
3898 Full_Typ : Entity_Id := Typ;
3899 Loc : constant Source_Ptr := Sloc (Prim);
3900 Prim_Op : Entity_Id;
3903 -- Retrieve the original primitive operation
3906 while Present (Alias (Prim_Op)) loop
3907 Prim_Op := Alias (Prim_Op);
3910 if Ekind (Typ) = E_Record_Type
3911 and then Present (Corresponding_Concurrent_Type (Typ))
3913 Full_Typ := Corresponding_Concurrent_Type (Typ);
3916 if Ekind (Prim_Op) = E_Function then
3918 -- Protected function
3920 if Ekind (Full_Typ) = E_Protected_Type then
3921 return New_Reference_To (RTE (RE_POK_Protected_Function), Loc);
3925 elsif Ekind (Full_Typ) = E_Task_Type then
3926 return New_Reference_To (RTE (RE_POK_Task_Function), Loc);
3931 return New_Reference_To (RTE (RE_POK_Function), Loc);
3935 pragma Assert (Ekind (Prim_Op) = E_Procedure);
3937 if Ekind (Full_Typ) = E_Protected_Type then
3941 if Is_Primitive_Wrapper (Prim_Op)
3942 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
3944 return New_Reference_To (RTE (RE_POK_Protected_Entry), Loc);
3946 -- Protected procedure
3949 return New_Reference_To (RTE (RE_POK_Protected_Procedure), Loc);
3952 elsif Ekind (Full_Typ) = E_Task_Type then
3956 if Is_Primitive_Wrapper (Prim_Op)
3957 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
3959 return New_Reference_To (RTE (RE_POK_Task_Entry), Loc);
3961 -- Task "procedure". These are the internally Expander-generated
3962 -- procedures (task body for instance).
3965 return New_Reference_To (RTE (RE_POK_Task_Procedure), Loc);
3968 -- Regular procedure
3971 return New_Reference_To (RTE (RE_POK_Procedure), Loc);
3976 -------------------------
3977 -- Set_All_DT_Position --
3978 -------------------------
3980 procedure Set_All_DT_Position (Typ : Entity_Id) is
3982 procedure Validate_Position (Prim : Entity_Id);
3983 -- Check that the position assignated to Prim is completely safe
3984 -- (it has not been assigned to a previously defined primitive
3985 -- operation of Typ)
3987 -----------------------
3988 -- Validate_Position --
3989 -----------------------
3991 procedure Validate_Position (Prim : Entity_Id) is
3996 -- Aliased primitives are safe
3998 if Present (Alias (Prim)) then
4002 Op_Elmt := First_Elmt (Primitive_Operations (Typ));
4003 while Present (Op_Elmt) loop
4004 Op := Node (Op_Elmt);
4006 -- No need to check against itself
4011 -- Primitive operations covering abstract interfaces are
4014 elsif Present (Abstract_Interface_Alias (Op)) then
4017 -- Predefined dispatching operations are completely safe. They
4018 -- are allocated at fixed positions in a separate table.
4020 elsif Is_Predefined_Dispatching_Operation (Op)
4021 or else Is_Predefined_Dispatching_Alias (Op)
4025 -- Aliased subprograms are safe
4027 elsif Present (Alias (Op)) then
4030 elsif DT_Position (Op) = DT_Position (Prim)
4031 and then not Is_Predefined_Dispatching_Operation (Op)
4032 and then not Is_Predefined_Dispatching_Operation (Prim)
4033 and then not Is_Predefined_Dispatching_Alias (Op)
4034 and then not Is_Predefined_Dispatching_Alias (Prim)
4037 -- Handle aliased subprograms
4046 if Present (Overridden_Operation (Op_1)) then
4047 Op_1 := Overridden_Operation (Op_1);
4048 elsif Present (Alias (Op_1)) then
4049 Op_1 := Alias (Op_1);
4057 if Present (Overridden_Operation (Op_2)) then
4058 Op_2 := Overridden_Operation (Op_2);
4059 elsif Present (Alias (Op_2)) then
4060 Op_2 := Alias (Op_2);
4066 if Op_1 /= Op_2 then
4067 raise Program_Error;
4072 Next_Elmt (Op_Elmt);
4074 end Validate_Position;
4078 Parent_Typ : constant Entity_Id := Etype (Typ);
4079 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
4080 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
4082 Adjusted : Boolean := False;
4083 Finalized : Boolean := False;
4089 Prim_Elmt : Elmt_Id;
4091 -- Start of processing for Set_All_DT_Position
4094 -- Set the DT_Position for each primitive operation. Perform some
4095 -- sanity checks to avoid to build completely inconsistant dispatch
4098 -- First stage: Set the DTC entity of all the primitive operations
4099 -- This is required to properly read the DT_Position attribute in
4100 -- the latter stages.
4102 Prim_Elmt := First_Prim;
4104 while Present (Prim_Elmt) loop
4105 Prim := Node (Prim_Elmt);
4107 -- Predefined primitives have a separate dispatch table
4109 if not (Is_Predefined_Dispatching_Operation (Prim)
4110 or else Is_Predefined_Dispatching_Alias (Prim))
4112 Count_Prim := Count_Prim + 1;
4115 -- Ada 2005 (AI-251)
4117 if Present (Abstract_Interface_Alias (Prim))
4118 and then Is_Interface
4119 (Find_Dispatching_Type
4120 (Abstract_Interface_Alias (Prim)))
4122 Set_DTC_Entity (Prim,
4125 Iface => Find_Dispatching_Type
4126 (Abstract_Interface_Alias (Prim))));
4128 Set_DTC_Entity (Prim, The_Tag);
4131 -- Clear any previous value of the DT_Position attribute. In this
4132 -- way we ensure that the final position of all the primitives is
4133 -- stablished by the following stages of this algorithm.
4135 Set_DT_Position (Prim, No_Uint);
4137 Next_Elmt (Prim_Elmt);
4141 Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean
4142 := (others => False);
4145 procedure Set_Fixed_Prim (Pos : Nat);
4146 -- Sets to true an element of the Fixed_Prim table to indicate
4147 -- that this entry of the dispatch table of Typ is occupied.
4149 --------------------
4150 -- Set_Fixed_Prim --
4151 --------------------
4153 procedure Set_Fixed_Prim (Pos : Nat) is
4155 pragma Assert (Pos >= 0 and then Pos <= Count_Prim);
4156 Fixed_Prim (Pos) := True;
4158 when Constraint_Error =>
4159 raise Program_Error;
4163 -- Second stage: Register fixed entries
4166 Prim_Elmt := First_Prim;
4167 while Present (Prim_Elmt) loop
4168 Prim := Node (Prim_Elmt);
4170 -- Predefined primitives have a separate table and all its
4171 -- entries are at predefined fixed positions.
4173 if Is_Predefined_Dispatching_Operation (Prim) then
4174 Set_DT_Position (Prim, Default_Prim_Op_Position (Prim));
4176 elsif Is_Predefined_Dispatching_Alias (Prim) then
4178 while Present (Alias (E)) loop
4182 Set_DT_Position (Prim, Default_Prim_Op_Position (E));
4184 -- Overriding primitives of ancestor abstract interfaces
4186 elsif Present (Abstract_Interface_Alias (Prim))
4188 (Find_Dispatching_Type
4189 (Abstract_Interface_Alias (Prim)),
4192 pragma Assert (DT_Position (Prim) = No_Uint
4193 and then Present (DTC_Entity
4194 (Abstract_Interface_Alias (Prim))));
4196 E := Abstract_Interface_Alias (Prim);
4197 Set_DT_Position (Prim, DT_Position (E));
4200 (DT_Position (Alias (Prim)) = No_Uint
4201 or else DT_Position (Alias (Prim)) = DT_Position (E));
4202 Set_DT_Position (Alias (Prim), DT_Position (E));
4203 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));
4205 -- Overriding primitives must use the same entry as the
4206 -- overriden primitive
4208 elsif not Present (Abstract_Interface_Alias (Prim))
4209 and then Present (Alias (Prim))
4210 and then Find_Dispatching_Type (Alias (Prim)) /= Typ
4212 (Find_Dispatching_Type (Alias (Prim)), Typ)
4213 and then Present (DTC_Entity (Alias (Prim)))
4216 Set_DT_Position (Prim, DT_Position (E));
4218 if not Is_Predefined_Dispatching_Alias (E) then
4219 Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
4223 Next_Elmt (Prim_Elmt);
4226 -- Third stage: Fix the position of all the new primitives
4227 -- Entries associated with primitives covering interfaces
4228 -- are handled in a latter round.
4230 Prim_Elmt := First_Prim;
4231 while Present (Prim_Elmt) loop
4232 Prim := Node (Prim_Elmt);
4234 -- Skip primitives previously set entries
4236 if DT_Position (Prim) /= No_Uint then
4239 -- Primitives covering interface primitives are handled later
4241 elsif Present (Abstract_Interface_Alias (Prim)) then
4245 -- Take the next available position in the DT
4248 Nb_Prim := Nb_Prim + 1;
4249 pragma Assert (Nb_Prim <= Count_Prim);
4250 exit when not Fixed_Prim (Nb_Prim);
4253 Set_DT_Position (Prim, UI_From_Int (Nb_Prim));
4254 Set_Fixed_Prim (Nb_Prim);
4257 Next_Elmt (Prim_Elmt);
4261 -- Fourth stage: Complete the decoration of primitives covering
4262 -- interfaces (that is, propagate the DT_Position attribute
4263 -- from the aliased primitive)
4265 Prim_Elmt := First_Prim;
4266 while Present (Prim_Elmt) loop
4267 Prim := Node (Prim_Elmt);
4269 if DT_Position (Prim) = No_Uint
4270 and then Present (Abstract_Interface_Alias (Prim))
4272 pragma Assert (Present (Alias (Prim))
4273 and then Find_Dispatching_Type (Alias (Prim)) = Typ);
4275 -- Check if this entry will be placed in the primary DT
4277 if Is_Parent (Find_Dispatching_Type
4278 (Abstract_Interface_Alias (Prim)),
4281 pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
4282 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
4284 -- Otherwise it will be placed in the secondary DT
4288 (DT_Position (Abstract_Interface_Alias (Prim)) /= No_Uint);
4289 Set_DT_Position (Prim,
4290 DT_Position (Abstract_Interface_Alias (Prim)));
4294 Next_Elmt (Prim_Elmt);
4297 -- Generate listing showing the contents of the dispatch tables.
4298 -- This action is done before some further static checks because
4299 -- in case of critical errors caused by a wrong dispatch table
4300 -- we need to see the contents of such table.
4302 if Debug_Flag_ZZ then
4306 -- Final stage: Ensure that the table is correct plus some further
4307 -- verifications concerning the primitives.
4309 Prim_Elmt := First_Prim;
4311 while Present (Prim_Elmt) loop
4312 Prim := Node (Prim_Elmt);
4314 -- At this point all the primitives MUST have a position
4315 -- in the dispatch table
4317 if DT_Position (Prim) = No_Uint then
4318 raise Program_Error;
4321 -- Calculate real size of the dispatch table
4323 if not (Is_Predefined_Dispatching_Operation (Prim)
4324 or else Is_Predefined_Dispatching_Alias (Prim))
4325 and then UI_To_Int (DT_Position (Prim)) > DT_Length
4327 DT_Length := UI_To_Int (DT_Position (Prim));
4330 -- Ensure that the asignated position to non-predefined
4331 -- dispatching operations in the dispatch table is correct.
4333 if not (Is_Predefined_Dispatching_Operation (Prim)
4334 or else Is_Predefined_Dispatching_Alias (Prim))
4336 Validate_Position (Prim);
4339 if Chars (Prim) = Name_Finalize then
4343 if Chars (Prim) = Name_Adjust then
4347 -- An abstract operation cannot be declared in the private part
4348 -- for a visible abstract type, because it could never be over-
4349 -- ridden. For explicit declarations this is checked at the
4350 -- point of declaration, but for inherited operations it must
4351 -- be done when building the dispatch table.
4353 -- Ada 2005 (AI-251): Hidden entities associated with abstract
4354 -- interface primitives are not taken into account because the
4355 -- check is done with the aliased primitive.
4357 if Is_Abstract_Type (Typ)
4358 and then Is_Abstract_Subprogram (Prim)
4359 and then Present (Alias (Prim))
4360 and then not Present (Abstract_Interface_Alias (Prim))
4361 and then Is_Derived_Type (Typ)
4362 and then In_Private_Part (Current_Scope)
4364 List_Containing (Parent (Prim)) =
4365 Private_Declarations
4366 (Specification (Unit_Declaration_Node (Current_Scope)))
4367 and then Original_View_In_Visible_Part (Typ)
4369 -- We exclude Input and Output stream operations because
4370 -- Limited_Controlled inherits useless Input and Output
4371 -- stream operations from Root_Controlled, which can
4372 -- never be overridden.
4374 if not Is_TSS (Prim, TSS_Stream_Input)
4376 not Is_TSS (Prim, TSS_Stream_Output)
4379 ("abstract inherited private operation&" &
4380 " must be overridden ('R'M 3.9.3(10))",
4381 Parent (Typ), Prim);
4385 Next_Elmt (Prim_Elmt);
4390 if Is_Controlled (Typ) then
4391 if not Finalized then
4393 ("controlled type has no explicit Finalize method?", Typ);
4395 elsif not Adjusted then
4397 ("controlled type has no explicit Adjust method?", Typ);
4401 -- Set the final size of the Dispatch Table
4403 Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));
4405 -- The derived type must have at least as many components as its
4406 -- parent (for root types, the Etype points back to itself
4407 -- and the test should not fail)
4409 -- This test fails compiling the partial view of a tagged type
4410 -- derived from an interface which defines the overriding subprogram
4411 -- in the private part. This needs further investigation???
4413 if not Has_Private_Declaration (Typ) then
4415 DT_Entry_Count (The_Tag) >=
4416 DT_Entry_Count (First_Tag_Component (Parent_Typ)));
4419 end Set_All_DT_Position;
4421 -----------------------------
4422 -- Set_Default_Constructor --
4423 -----------------------------
4425 procedure Set_Default_Constructor (Typ : Entity_Id) is
4432 -- Look for the default constructor entity. For now only the
4433 -- default constructor has the flag Is_Constructor.
4435 E := Next_Entity (Typ);
4437 and then (Ekind (E) /= E_Function or else not Is_Constructor (E))
4442 -- Create the init procedure
4446 Init := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
4447 Param := Make_Defining_Identifier (Loc, Name_X);
4450 Make_Subprogram_Declaration (Loc,
4451 Make_Procedure_Specification (Loc,
4452 Defining_Unit_Name => Init,
4453 Parameter_Specifications => New_List (
4454 Make_Parameter_Specification (Loc,
4455 Defining_Identifier => Param,
4456 Parameter_Type => New_Reference_To (Typ, Loc))))));
4458 Set_Init_Proc (Typ, Init);
4459 Set_Is_Imported (Init);
4460 Set_Interface_Name (Init, Interface_Name (E));
4461 Set_Convention (Init, Convention_C);
4462 Set_Is_Public (Init);
4463 Set_Has_Completion (Init);
4465 -- If there are no constructors, mark the type as abstract since we
4466 -- won't be able to declare objects of that type.
4469 Set_Is_Abstract_Type (Typ);
4471 end Set_Default_Constructor;
4477 function Tagged_Kind (T : Entity_Id) return Node_Id is
4478 Conc_Typ : Entity_Id;
4479 Loc : constant Source_Ptr := Sloc (T);
4483 (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));
4487 if Is_Abstract_Type (T) then
4488 if Is_Limited_Record (T) then
4489 return New_Reference_To (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
4491 return New_Reference_To (RTE (RE_TK_Abstract_Tagged), Loc);
4496 elsif Is_Concurrent_Record_Type (T) then
4497 Conc_Typ := Corresponding_Concurrent_Type (T);
4499 if Ekind (Conc_Typ) = E_Protected_Type then
4500 return New_Reference_To (RTE (RE_TK_Protected), Loc);
4502 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
4503 return New_Reference_To (RTE (RE_TK_Task), Loc);
4506 -- Regular tagged kinds
4509 if Is_Limited_Record (T) then
4510 return New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc);
4512 return New_Reference_To (RTE (RE_TK_Tagged), Loc);
4521 procedure Write_DT (Typ : Entity_Id) is
4526 -- Protect this procedure against wrong usage. Required because it will
4527 -- be used directly from GDB
4529 if not (Typ in First_Node_Id .. Last_Node_Id)
4530 or else not Is_Tagged_Type (Typ)
4532 Write_Str ("wrong usage: Write_DT must be used with tagged types");
4537 Write_Int (Int (Typ));
4539 Write_Name (Chars (Typ));
4541 if Is_Interface (Typ) then
4542 Write_Str (" is interface");
4547 Elmt := First_Elmt (Primitive_Operations (Typ));
4548 while Present (Elmt) loop
4549 Prim := Node (Elmt);
4552 -- Indicate if this primitive will be allocated in the primary
4553 -- dispatch table or in a secondary dispatch table associated
4554 -- with an abstract interface type
4556 if Present (DTC_Entity (Prim)) then
4557 if Etype (DTC_Entity (Prim)) = RTE (RE_Tag) then
4564 -- Output the node of this primitive operation and its name
4566 Write_Int (Int (Prim));
4569 if Is_Predefined_Dispatching_Operation (Prim) then
4570 Write_Str ("(predefined) ");
4573 Write_Name (Chars (Prim));
4575 -- Indicate if this primitive has an aliased primitive
4577 if Present (Alias (Prim)) then
4578 Write_Str (" (alias = ");
4579 Write_Int (Int (Alias (Prim)));
4581 -- If the DTC_Entity attribute is already set we can also output
4582 -- the name of the interface covered by this primitive (if any)
4584 if Present (DTC_Entity (Alias (Prim)))
4585 and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
4587 Write_Str (" from interface ");
4588 Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
4591 if Present (Abstract_Interface_Alias (Prim)) then
4592 Write_Str (", AI_Alias of ");
4593 Write_Name (Chars (Scope (DTC_Entity
4594 (Abstract_Interface_Alias (Prim)))));
4596 Write_Int (Int (Abstract_Interface_Alias (Prim)));
4602 -- Display the final position of this primitive in its associated
4603 -- (primary or secondary) dispatch table
4605 if Present (DTC_Entity (Prim))
4606 and then DT_Position (Prim) /= No_Uint
4608 Write_Str (" at #");
4609 Write_Int (UI_To_Int (DT_Position (Prim)));
4612 if Is_Abstract_Subprogram (Prim) then
4613 Write_Str (" is abstract;");
4615 -- Check if this is a null primitive
4617 elsif Comes_From_Source (Prim)
4618 and then Ekind (Prim) = E_Procedure
4619 and then Null_Present (Parent (Prim))
4621 Write_Str (" is null;");