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_Ch7; use Exp_Ch7;
34 with Exp_Dbug; use Exp_Dbug;
35 with Exp_Tss; use Exp_Tss;
36 with Exp_Util; use Exp_Util;
37 with Freeze; use Freeze;
38 with Itypes; use Itypes;
39 with Nlists; use Nlists;
40 with Nmake; use Nmake;
41 with Namet; use Namet;
43 with Output; use Output;
44 with Restrict; use Restrict;
45 with Rident; use Rident;
46 with Rtsfind; use Rtsfind;
48 with Sem_Disp; use Sem_Disp;
49 with Sem_Res; use Sem_Res;
50 with Sem_Type; use Sem_Type;
51 with Sem_Util; use Sem_Util;
52 with Sinfo; use Sinfo;
53 with Snames; use Snames;
54 with Stand; use Stand;
55 with Tbuild; use Tbuild;
56 with Uintp; use Uintp;
58 package body Exp_Disp is
60 --------------------------------
61 -- Select_Expansion_Utilities --
62 --------------------------------
64 -- The following package contains helper routines used in the expansion of
65 -- dispatching asynchronous, conditional and timed selects.
67 package Select_Expansion_Utilities is
72 -- B : out Communication_Block
78 -- C : out Prim_Op_Kind
80 procedure Build_Common_Dispatching_Select_Statements
85 -- Ada 2005 (AI-345): Generate statements that are common between
86 -- asynchronous, conditional and timed select expansion.
112 end Select_Expansion_Utilities;
114 package body Select_Expansion_Utilities is
126 Make_Parameter_Specification (Loc,
127 Defining_Identifier =>
128 Make_Defining_Identifier (Loc, Name_uB),
130 New_Reference_To (RTE (RE_Communication_Block), Loc),
131 Out_Present => True));
144 Make_Parameter_Specification (Loc,
145 Defining_Identifier =>
146 Make_Defining_Identifier (Loc, Name_uC),
148 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
149 Out_Present => True));
152 ------------------------------------------------
153 -- Build_Common_Dispatching_Select_Statements --
154 ------------------------------------------------
156 procedure Build_Common_Dispatching_Select_Statements
164 -- C := get_prim_op_kind (tag! (<type>VP), S);
166 -- where C is the out parameter capturing the call kind and S is the
167 -- dispatch table slot number.
170 Make_Assignment_Statement (Loc,
172 Make_Identifier (Loc, Name_uC),
174 Make_DT_Access_Action (Typ,
179 Unchecked_Convert_To (RTE (RE_Tag),
180 New_Reference_To (DT_Ptr, Loc)),
181 Make_Identifier (Loc, Name_uS)))));
185 -- if C = POK_Procedure
186 -- or else C = POK_Protected_Procedure
187 -- or else C = POK_Task_Procedure;
192 -- where F is the out parameter capturing the status of a potential
196 Make_If_Statement (Loc,
203 Make_Identifier (Loc, Name_uC),
205 New_Reference_To (RTE (RE_POK_Procedure), Loc)),
211 Make_Identifier (Loc, Name_uC),
213 New_Reference_To (RTE (
214 RE_POK_Protected_Procedure), Loc)),
218 Make_Identifier (Loc, Name_uC),
220 New_Reference_To (RTE (
221 RE_POK_Task_Procedure), Loc)))),
225 Make_Assignment_Statement (Loc,
226 Name => Make_Identifier (Loc, Name_uF),
227 Expression => New_Reference_To (Standard_True, Loc)),
229 Make_Return_Statement (Loc))));
230 end Build_Common_Dispatching_Select_Statements;
242 Make_Parameter_Specification (Loc,
243 Defining_Identifier =>
244 Make_Defining_Identifier (Loc, Name_uF),
246 New_Reference_To (Standard_Boolean, Loc),
247 Out_Present => True));
260 Make_Parameter_Specification (Loc,
261 Defining_Identifier =>
262 Make_Defining_Identifier (Loc, Name_uP),
264 New_Reference_To (RTE (RE_Address), Loc)));
277 Make_Parameter_Specification (Loc,
278 Defining_Identifier =>
279 Make_Defining_Identifier (Loc, Name_uS),
281 New_Reference_To (Standard_Integer, Loc)));
295 Make_Parameter_Specification (Loc,
296 Defining_Identifier =>
297 Make_Defining_Identifier (Loc, Name_uT),
299 New_Reference_To (Typ, Loc),
301 Out_Present => True));
303 end Select_Expansion_Utilities;
305 package SEU renames Select_Expansion_Utilities;
307 Ada_Actions : constant array (DT_Access_Action) of RE_Id :=
308 (CW_Membership => RE_CW_Membership,
309 IW_Membership => RE_IW_Membership,
310 DT_Entry_Size => RE_DT_Entry_Size,
311 DT_Prologue_Size => RE_DT_Prologue_Size,
312 Get_Access_Level => RE_Get_Access_Level,
313 Get_Entry_Index => RE_Get_Entry_Index,
314 Get_External_Tag => RE_Get_External_Tag,
315 Get_Predefined_Prim_Op_Address => RE_Get_Predefined_Prim_Op_Address,
316 Get_Prim_Op_Address => RE_Get_Prim_Op_Address,
317 Get_Prim_Op_Kind => RE_Get_Prim_Op_Kind,
318 Get_RC_Offset => RE_Get_RC_Offset,
319 Get_Remotely_Callable => RE_Get_Remotely_Callable,
320 Get_Tagged_Kind => RE_Get_Tagged_Kind,
321 Inherit_DT => RE_Inherit_DT,
322 Inherit_TSD => RE_Inherit_TSD,
323 Register_Interface_Tag => RE_Register_Interface_Tag,
324 Register_Tag => RE_Register_Tag,
325 Set_Access_Level => RE_Set_Access_Level,
326 Set_Entry_Index => RE_Set_Entry_Index,
327 Set_Expanded_Name => RE_Set_Expanded_Name,
328 Set_External_Tag => RE_Set_External_Tag,
329 Set_Interface_Table => RE_Set_Interface_Table,
330 Set_Offset_Index => RE_Set_Offset_Index,
331 Set_OSD => RE_Set_OSD,
332 Set_Predefined_Prim_Op_Address => RE_Set_Predefined_Prim_Op_Address,
333 Set_Prim_Op_Address => RE_Set_Prim_Op_Address,
334 Set_Prim_Op_Kind => RE_Set_Prim_Op_Kind,
335 Set_RC_Offset => RE_Set_RC_Offset,
336 Set_Remotely_Callable => RE_Set_Remotely_Callable,
337 Set_Signature => RE_Set_Signature,
338 Set_SSD => RE_Set_SSD,
339 Set_TSD => RE_Set_TSD,
340 Set_Tagged_Kind => RE_Set_Tagged_Kind,
341 TSD_Entry_Size => RE_TSD_Entry_Size,
342 TSD_Prologue_Size => RE_TSD_Prologue_Size);
344 Action_Is_Proc : constant array (DT_Access_Action) of Boolean :=
345 (CW_Membership => False,
346 IW_Membership => False,
347 DT_Entry_Size => False,
348 DT_Prologue_Size => False,
349 Get_Access_Level => False,
350 Get_Entry_Index => False,
351 Get_External_Tag => False,
352 Get_Predefined_Prim_Op_Address => False,
353 Get_Prim_Op_Address => False,
354 Get_Prim_Op_Kind => False,
355 Get_RC_Offset => False,
356 Get_Remotely_Callable => False,
357 Get_Tagged_Kind => False,
360 Register_Interface_Tag => True,
361 Register_Tag => True,
362 Set_Access_Level => True,
363 Set_Entry_Index => True,
364 Set_Expanded_Name => True,
365 Set_External_Tag => True,
366 Set_Interface_Table => True,
367 Set_Offset_Index => True,
369 Set_Predefined_Prim_Op_Address => True,
370 Set_Prim_Op_Address => True,
371 Set_Prim_Op_Kind => True,
372 Set_RC_Offset => True,
373 Set_Remotely_Callable => True,
374 Set_Signature => True,
377 Set_Tagged_Kind => True,
378 TSD_Entry_Size => False,
379 TSD_Prologue_Size => False);
381 Action_Nb_Arg : constant array (DT_Access_Action) of Int :=
385 DT_Prologue_Size => 0,
386 Get_Access_Level => 1,
387 Get_Entry_Index => 2,
388 Get_External_Tag => 1,
389 Get_Predefined_Prim_Op_Address => 2,
390 Get_Prim_Op_Address => 2,
391 Get_Prim_Op_Kind => 2,
393 Get_Remotely_Callable => 1,
394 Get_Tagged_Kind => 1,
397 Register_Interface_Tag => 3,
399 Set_Access_Level => 2,
400 Set_Entry_Index => 3,
401 Set_Expanded_Name => 2,
402 Set_External_Tag => 2,
403 Set_Interface_Table => 2,
404 Set_Offset_Index => 3,
406 Set_Predefined_Prim_Op_Address => 3,
407 Set_Prim_Op_Address => 3,
408 Set_Prim_Op_Kind => 3,
410 Set_Remotely_Callable => 2,
414 Set_Tagged_Kind => 2,
416 TSD_Prologue_Size => 0);
418 function Default_Prim_Op_Position (E : Entity_Id) return Uint;
419 -- Ada 2005 (AI-251): Returns the fixed position in the dispatch table
420 -- of the default primitive operations.
422 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean;
423 -- Returns true if Prim is not a predefined dispatching primitive but it is
424 -- an alias of a predefined dispatching primitive (ie. through a renaming)
426 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean;
427 -- Check if the type has a private view or if the public view appears
428 -- in the visible part of a package spec.
430 function Prim_Op_Kind
432 Typ : Entity_Id) return Node_Id;
433 -- Ada 2005 (AI-345): Determine the primitive operation kind of Prim
434 -- according to its type Typ. Return a reference to an RE_Prim_Op_Kind
435 -- enumeration value.
437 function Tagged_Kind (T : Entity_Id) return Node_Id;
438 -- Ada 2005 (AI-345): Determine the tagged kind of T and return a reference
439 -- to an RE_Tagged_Kind enumeration value.
441 ------------------------------
442 -- Default_Prim_Op_Position --
443 ------------------------------
445 function Default_Prim_Op_Position (E : Entity_Id) return Uint is
446 TSS_Name : TSS_Name_Type;
449 Get_Name_String (Chars (E));
452 (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
454 if Chars (E) = Name_uSize then
457 elsif Chars (E) = Name_uAlignment then
460 elsif TSS_Name = TSS_Stream_Read then
463 elsif TSS_Name = TSS_Stream_Write then
466 elsif TSS_Name = TSS_Stream_Input then
469 elsif TSS_Name = TSS_Stream_Output then
472 elsif Chars (E) = Name_Op_Eq then
475 elsif Chars (E) = Name_uAssign then
478 elsif TSS_Name = TSS_Deep_Adjust then
481 elsif TSS_Name = TSS_Deep_Finalize then
484 elsif Ada_Version >= Ada_05 then
485 if Chars (E) = Name_uDisp_Asynchronous_Select then
488 elsif Chars (E) = Name_uDisp_Conditional_Select then
491 elsif Chars (E) = Name_uDisp_Get_Prim_Op_Kind then
494 elsif Chars (E) = Name_uDisp_Get_Task_Id then
497 elsif Chars (E) = Name_uDisp_Timed_Select then
503 end Default_Prim_Op_Position;
505 -----------------------------
506 -- Expand_Dispatching_Call --
507 -----------------------------
509 procedure Expand_Dispatching_Call (Call_Node : Node_Id) is
510 Loc : constant Source_Ptr := Sloc (Call_Node);
511 Call_Typ : constant Entity_Id := Etype (Call_Node);
513 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
514 Param_List : constant List_Id := Parameter_Associations (Call_Node);
519 New_Call_Name : Node_Id;
520 New_Params : List_Id := No_List;
523 Subp_Ptr_Typ : Entity_Id;
524 Subp_Typ : Entity_Id;
526 Eq_Prim_Op : Entity_Id := Empty;
527 Controlling_Tag : Node_Id;
529 function New_Value (From : Node_Id) return Node_Id;
530 -- From is the original Expression. New_Value is equivalent to a call
531 -- to Duplicate_Subexpr with an explicit dereference when From is an
538 function New_Value (From : Node_Id) return Node_Id is
539 Res : constant Node_Id := Duplicate_Subexpr (From);
541 if Is_Access_Type (Etype (From)) then
543 Make_Explicit_Dereference (Sloc (From),
550 -- Start of processing for Expand_Dispatching_Call
553 Check_Restriction (No_Dispatching_Calls, Call_Node);
555 -- Set subprogram. If this is an inherited operation that was
556 -- overridden, the body that is being called is its alias.
558 Subp := Entity (Name (Call_Node));
560 if Present (Alias (Subp))
561 and then Is_Inherited_Operation (Subp)
562 and then No (DTC_Entity (Subp))
564 Subp := Alias (Subp);
567 -- Expand_Dispatching_Call is called directly from the semantics,
568 -- so we need a check to see whether expansion is active before
571 if not Expander_Active then
575 -- Definition of the class-wide type and the tagged type
577 -- If the controlling argument is itself a tag rather than a tagged
578 -- object, then use the class-wide type associated with the subprogram's
579 -- controlling type. This case can occur when a call to an inherited
580 -- primitive has an actual that originated from a default parameter
581 -- given by a tag-indeterminate call and when there is no other
582 -- controlling argument providing the tag (AI-239 requires dispatching).
583 -- This capability of dispatching directly by tag is also needed by the
584 -- implementation of AI-260 (for the generic dispatching constructors).
586 if Etype (Ctrl_Arg) = RTE (RE_Tag)
587 or else (RTE_Available (RE_Interface_Tag)
588 and then Etype (Ctrl_Arg) = RTE (RE_Interface_Tag))
590 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
592 elsif Is_Access_Type (Etype (Ctrl_Arg)) then
593 CW_Typ := Designated_Type (Etype (Ctrl_Arg));
596 CW_Typ := Etype (Ctrl_Arg);
599 Typ := Root_Type (CW_Typ);
601 if Ekind (Typ) = E_Incomplete_Type then
602 Typ := Non_Limited_View (Typ);
605 if not Is_Limited_Type (Typ) then
606 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
609 -- Why do we check the Root_Type instead of Typ???
611 if Is_CPP_Class (Root_Type (Typ)) then
613 -- Create a new parameter list with the displaced 'this'
615 New_Params := New_List;
616 Param := First_Actual (Call_Node);
617 while Present (Param) loop
618 Append_To (New_Params, Relocate_Node (Param));
622 elsif Present (Param_List) then
624 -- Generate the Tag checks when appropriate
626 New_Params := New_List;
627 Param := First_Actual (Call_Node);
628 while Present (Param) loop
630 -- No tag check with itself
632 if Param = Ctrl_Arg then
633 Append_To (New_Params,
634 Duplicate_Subexpr_Move_Checks (Param));
636 -- No tag check for parameter whose type is neither tagged nor
637 -- access to tagged (for access parameters)
639 elsif No (Find_Controlling_Arg (Param)) then
640 Append_To (New_Params, Relocate_Node (Param));
642 -- No tag check for function dispatching on result if the
643 -- Tag given by the context is this one
645 elsif Find_Controlling_Arg (Param) = Ctrl_Arg then
646 Append_To (New_Params, Relocate_Node (Param));
648 -- "=" is the only dispatching operation allowed to get
649 -- operands with incompatible tags (it just returns false).
650 -- We use Duplicate_Subexpr_Move_Checks instead of calling
651 -- Relocate_Node because the value will be duplicated to
654 elsif Subp = Eq_Prim_Op then
655 Append_To (New_Params,
656 Duplicate_Subexpr_Move_Checks (Param));
658 -- No check in presence of suppress flags
660 elsif Tag_Checks_Suppressed (Etype (Param))
661 or else (Is_Access_Type (Etype (Param))
662 and then Tag_Checks_Suppressed
663 (Designated_Type (Etype (Param))))
665 Append_To (New_Params, Relocate_Node (Param));
667 -- Optimization: no tag checks if the parameters are identical
669 elsif Is_Entity_Name (Param)
670 and then Is_Entity_Name (Ctrl_Arg)
671 and then Entity (Param) = Entity (Ctrl_Arg)
673 Append_To (New_Params, Relocate_Node (Param));
675 -- Now we need to generate the Tag check
678 -- Generate code for tag equality check
679 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
681 Insert_Action (Ctrl_Arg,
682 Make_Implicit_If_Statement (Call_Node,
686 Make_Selected_Component (Loc,
687 Prefix => New_Value (Ctrl_Arg),
690 (First_Tag_Component (Typ), Loc)),
693 Make_Selected_Component (Loc,
695 Unchecked_Convert_To (Typ, New_Value (Param)),
698 (First_Tag_Component (Typ), Loc))),
701 New_List (New_Constraint_Error (Loc))));
703 Append_To (New_Params, Relocate_Node (Param));
710 -- Generate the appropriate subprogram pointer type
712 if Etype (Subp) = Typ then
715 Res_Typ := Etype (Subp);
718 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
719 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
720 Set_Etype (Subp_Typ, Res_Typ);
721 Init_Size_Align (Subp_Ptr_Typ);
722 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
724 -- Create a new list of parameters which is a copy of the old formal
725 -- list including the creation of a new set of matching entities.
728 Old_Formal : Entity_Id := First_Formal (Subp);
729 New_Formal : Entity_Id;
733 if Present (Old_Formal) then
734 New_Formal := New_Copy (Old_Formal);
735 Set_First_Entity (Subp_Typ, New_Formal);
736 Param := First_Actual (Call_Node);
739 Set_Scope (New_Formal, Subp_Typ);
741 -- Change all the controlling argument types to be class-wide
742 -- to avoid a recursion in dispatching.
744 if Is_Controlling_Formal (New_Formal) then
745 Set_Etype (New_Formal, Etype (Param));
748 if Is_Itype (Etype (New_Formal)) then
749 Extra := New_Copy (Etype (New_Formal));
751 if Ekind (Extra) = E_Record_Subtype
752 or else Ekind (Extra) = E_Class_Wide_Subtype
754 Set_Cloned_Subtype (Extra, Etype (New_Formal));
757 Set_Etype (New_Formal, Extra);
758 Set_Scope (Etype (New_Formal), Subp_Typ);
762 Next_Formal (Old_Formal);
763 exit when No (Old_Formal);
765 Set_Next_Entity (New_Formal, New_Copy (Old_Formal));
766 Next_Entity (New_Formal);
770 Set_Next_Entity (New_Formal, Empty);
771 Set_Last_Entity (Subp_Typ, Extra);
773 -- Copy extra formals
775 New_Formal := First_Entity (Subp_Typ);
776 while Present (New_Formal) loop
777 if Present (Extra_Constrained (New_Formal)) then
778 Set_Extra_Formal (Extra,
779 New_Copy (Extra_Constrained (New_Formal)));
780 Extra := Extra_Formal (Extra);
781 Set_Extra_Constrained (New_Formal, Extra);
783 elsif Present (Extra_Accessibility (New_Formal)) then
784 Set_Extra_Formal (Extra,
785 New_Copy (Extra_Accessibility (New_Formal)));
786 Extra := Extra_Formal (Extra);
787 Set_Extra_Accessibility (New_Formal, Extra);
790 Next_Formal (New_Formal);
795 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
796 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
798 -- If the controlling argument is a value of type Ada.Tag or an abstract
799 -- interface class-wide type then use it directly. Otherwise, the tag
800 -- must be extracted from the controlling object.
802 if Etype (Ctrl_Arg) = RTE (RE_Tag)
803 or else (RTE_Available (RE_Interface_Tag)
804 and then Etype (Ctrl_Arg) = RTE (RE_Interface_Tag))
806 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
808 -- Ada 2005 (AI-251): Abstract interface class-wide type
810 elsif Is_Interface (Etype (Ctrl_Arg))
811 and then Is_Class_Wide_Type (Etype (Ctrl_Arg))
813 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
817 Make_Selected_Component (Loc,
818 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
819 Selector_Name => New_Reference_To (DTC_Entity (Subp), Loc));
823 -- Subp_Ptr_Typ!(Get_Prim_Op_Address (Ctrl._Tag, pos));
825 if Is_Predefined_Dispatching_Operation (Subp)
826 or else Is_Predefined_Dispatching_Alias (Subp)
829 Unchecked_Convert_To (Subp_Ptr_Typ,
830 Make_DT_Access_Action (Typ,
831 Action => Get_Predefined_Prim_Op_Address,
836 Unchecked_Convert_To (RTE (RE_Tag),
841 Make_Integer_Literal (Loc, DT_Position (Subp)))));
845 Unchecked_Convert_To (Subp_Ptr_Typ,
846 Make_DT_Access_Action (Typ,
847 Action => Get_Prim_Op_Address,
852 Unchecked_Convert_To (RTE (RE_Tag),
857 Make_Integer_Literal (Loc, DT_Position (Subp)))));
860 if Nkind (Call_Node) = N_Function_Call then
862 -- Ada 2005 (AI-251): A dispatching "=" with an abstract interface
863 -- just requires the comparison of the tags.
865 if Ekind (Etype (Ctrl_Arg)) = E_Class_Wide_Type
866 and then Is_Interface (Etype (Ctrl_Arg))
867 and then Subp = Eq_Prim_Op
869 Param := First_Actual (Call_Node);
874 Make_Selected_Component (Loc,
875 Prefix => New_Value (Param),
877 New_Reference_To (First_Tag_Component (Typ), Loc)),
880 Make_Selected_Component (Loc,
882 Unchecked_Convert_To (Typ,
883 New_Value (Next_Actual (Param))),
885 New_Reference_To (First_Tag_Component (Typ), Loc)));
889 Make_Function_Call (Loc,
890 Name => New_Call_Name,
891 Parameter_Associations => New_Params);
893 -- If this is a dispatching "=", we must first compare the tags so
894 -- we generate: x.tag = y.tag and then x = y
896 if Subp = Eq_Prim_Op then
897 Param := First_Actual (Call_Node);
903 Make_Selected_Component (Loc,
904 Prefix => New_Value (Param),
906 New_Reference_To (First_Tag_Component (Typ),
910 Make_Selected_Component (Loc,
912 Unchecked_Convert_To (Typ,
913 New_Value (Next_Actual (Param))),
915 New_Reference_To (First_Tag_Component (Typ),
917 Right_Opnd => New_Call);
923 Make_Procedure_Call_Statement (Loc,
924 Name => New_Call_Name,
925 Parameter_Associations => New_Params);
928 Rewrite (Call_Node, New_Call);
929 Analyze_And_Resolve (Call_Node, Call_Typ);
930 end Expand_Dispatching_Call;
932 ---------------------------------
933 -- Expand_Interface_Conversion --
934 ---------------------------------
936 procedure Expand_Interface_Conversion
938 Is_Static : Boolean := True)
940 Loc : constant Source_Ptr := Sloc (N);
941 Etyp : constant Entity_Id := Etype (N);
942 Operand : constant Node_Id := Expression (N);
943 Operand_Typ : Entity_Id := Etype (Operand);
946 Iface_Typ : Entity_Id := Etype (N);
947 Iface_Tag : Entity_Id;
948 New_Itype : Entity_Id;
952 pragma Assert (Nkind (Operand) /= N_Attribute_Reference);
954 -- Ada 2005 (AI-345): Handle task interfaces
956 if Ekind (Operand_Typ) = E_Task_Type
957 or else Ekind (Operand_Typ) = E_Protected_Type
959 Operand_Typ := Corresponding_Record_Type (Operand_Typ);
962 -- Handle access types to interfaces
964 if Is_Access_Type (Iface_Typ) then
965 Iface_Typ := Etype (Directly_Designated_Type (Iface_Typ));
968 -- Handle class-wide interface types. This conversion can appear
969 -- explicitly in the source code. Example: I'Class (Obj)
971 if Is_Class_Wide_Type (Iface_Typ) then
972 Iface_Typ := Etype (Iface_Typ);
975 pragma Assert (not Is_Static
976 or else (not Is_Class_Wide_Type (Iface_Typ)
977 and then Is_Interface (Iface_Typ)));
979 if not Is_Static then
981 -- Give error if configurable run time and Displace not available
983 if not RTE_Available (RE_Displace) then
984 Error_Msg_CRT ("abstract interface types", N);
988 -- Handle conversion of access to class-wide interface types. The
989 -- target can be an access to object or an access to another class
990 -- wide interfac (see -1- and -2- in the following example):
992 -- type Iface1_Ref is access all Iface1'Class;
993 -- type Iface2_Ref is access all Iface1'Class;
995 -- Acc1 : Iface1_Ref := new ...
996 -- Obj : Obj_Ref := Obj_Ref (Acc); -- 1
997 -- Acc2 : Iface2_Ref := Iface2_Ref (Acc); -- 2
999 if Is_Access_Type (Operand_Typ) then
1001 (Is_Class_Wide_Type (Directly_Designated_Type (Operand_Typ))
1003 Is_Interface (Directly_Designated_Type (Operand_Typ)));
1006 Unchecked_Convert_To (Etype (N),
1007 Make_Function_Call (Loc,
1008 Name => New_Reference_To (RTE (RE_Displace), Loc),
1009 Parameter_Associations => New_List (
1011 Unchecked_Convert_To (RTE (RE_Address),
1012 Relocate_Node (Expression (N))),
1015 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
1023 Make_Function_Call (Loc,
1024 Name => New_Reference_To (RTE (RE_Displace), Loc),
1025 Parameter_Associations => New_List (
1026 Make_Attribute_Reference (Loc,
1027 Prefix => Relocate_Node (Expression (N)),
1028 Attribute_Name => Name_Address),
1031 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
1036 -- If the target is a class-wide interface we change the type of the
1037 -- data returned by IW_Convert to indicate that this is a dispatching
1040 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
1041 Set_Etype (New_Itype, New_Itype);
1042 Init_Esize (New_Itype);
1043 Init_Size_Align (New_Itype);
1044 Set_Directly_Designated_Type (New_Itype, Etyp);
1046 Rewrite (N, Make_Explicit_Dereference (Loc,
1047 Unchecked_Convert_To (New_Itype,
1048 Relocate_Node (N))));
1050 Freeze_Itype (New_Itype, N);
1055 Iface_Tag := Find_Interface_Tag (Operand_Typ, Iface_Typ);
1056 pragma Assert (Iface_Tag /= Empty);
1058 -- Keep separate access types to interfaces because one internal
1059 -- function is used to handle the null value (see following comment)
1061 if not Is_Access_Type (Etype (N)) then
1063 Unchecked_Convert_To (Etype (N),
1064 Make_Selected_Component (Loc,
1065 Prefix => Relocate_Node (Expression (N)),
1067 New_Occurrence_Of (Iface_Tag, Loc))));
1070 -- Build internal function to handle the case in which the
1071 -- actual is null. If the actual is null returns null because
1072 -- no displacement is required; otherwise performs a type
1073 -- conversion that will be expanded in the code that returns
1074 -- the value of the displaced actual. That is:
1076 -- function Func (O : Address) return Iface_Typ is
1078 -- if O = Null_Address then
1081 -- return Iface_Typ!(Operand_Typ!(O).Iface_Tag'Address);
1085 Fent := Make_Defining_Identifier (Loc, New_Internal_Name ('F'));
1086 Set_Is_Internal (Fent);
1089 Desig_Typ : Entity_Id;
1091 Desig_Typ := Etype (Expression (N));
1093 if Is_Access_Type (Desig_Typ) then
1094 Desig_Typ := Directly_Designated_Type (Desig_Typ);
1097 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
1098 Set_Etype (New_Itype, New_Itype);
1099 Set_Scope (New_Itype, Fent);
1100 Init_Size_Align (New_Itype);
1101 Set_Directly_Designated_Type (New_Itype, Desig_Typ);
1105 Make_Subprogram_Body (Loc,
1107 Make_Function_Specification (Loc,
1108 Defining_Unit_Name => Fent,
1110 Parameter_Specifications => New_List (
1111 Make_Parameter_Specification (Loc,
1112 Defining_Identifier =>
1113 Make_Defining_Identifier (Loc, Name_uO),
1115 New_Reference_To (RTE (RE_Address), Loc))),
1117 Result_Definition =>
1118 New_Reference_To (Etype (N), Loc)),
1120 Declarations => Empty_List,
1122 Handled_Statement_Sequence =>
1123 Make_Handled_Sequence_Of_Statements (Loc,
1124 Statements => New_List (
1125 Make_If_Statement (Loc,
1128 Left_Opnd => Make_Identifier (Loc, Name_uO),
1129 Right_Opnd => New_Reference_To
1130 (RTE (RE_Null_Address), Loc)),
1132 Then_Statements => New_List (
1133 Make_Return_Statement (Loc,
1136 Else_Statements => New_List (
1137 Make_Return_Statement (Loc,
1138 Unchecked_Convert_To (Etype (N),
1139 Make_Attribute_Reference (Loc,
1141 Make_Selected_Component (Loc,
1142 Prefix => Unchecked_Convert_To (New_Itype,
1143 Make_Identifier (Loc, Name_uO)),
1145 New_Occurrence_Of (Iface_Tag, Loc)),
1146 Attribute_Name => Name_Address))))))));
1148 -- Insert the new declaration in the nearest enclosing scope
1149 -- that has declarations.
1152 while not Has_Declarations (Parent (P)) loop
1156 if Is_List_Member (P) then
1157 Insert_Before (P, Func);
1159 elsif Nkind (Parent (P)) = N_Package_Specification then
1160 Append_To (Visible_Declarations (Parent (P)), Func);
1163 Append_To (Declarations (Parent (P)), Func);
1168 if Is_Access_Type (Etype (Expression (N))) then
1170 -- Generate: Operand_Typ!(Expression.all)'Address
1173 Make_Function_Call (Loc,
1174 Name => New_Reference_To (Fent, Loc),
1175 Parameter_Associations => New_List (
1176 Make_Attribute_Reference (Loc,
1177 Prefix => Unchecked_Convert_To (Operand_Typ,
1178 Make_Explicit_Dereference (Loc,
1179 Relocate_Node (Expression (N)))),
1180 Attribute_Name => Name_Address))));
1183 -- Generate: Operand_Typ!(Expression)'Address
1186 Make_Function_Call (Loc,
1187 Name => New_Reference_To (Fent, Loc),
1188 Parameter_Associations => New_List (
1189 Make_Attribute_Reference (Loc,
1190 Prefix => Unchecked_Convert_To (Operand_Typ,
1191 Relocate_Node (Expression (N))),
1192 Attribute_Name => Name_Address))));
1197 end Expand_Interface_Conversion;
1199 ------------------------------
1200 -- Expand_Interface_Actuals --
1201 ------------------------------
1203 procedure Expand_Interface_Actuals (Call_Node : Node_Id) is
1204 Loc : constant Source_Ptr := Sloc (Call_Node);
1206 Actual_Dup : Node_Id;
1207 Actual_Typ : Entity_Id;
1209 Conversion : Node_Id;
1211 Formal_Typ : Entity_Id;
1214 Formal_DDT : Entity_Id;
1215 Actual_DDT : Entity_Id;
1218 -- This subprogram is called directly from the semantics, so we need a
1219 -- check to see whether expansion is active before proceeding.
1221 if not Expander_Active then
1225 -- Call using access to subprogram with explicit dereference
1227 if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
1228 Subp := Etype (Name (Call_Node));
1233 Subp := Entity (Name (Call_Node));
1236 Formal := First_Formal (Subp);
1237 Actual := First_Actual (Call_Node);
1238 while Present (Formal) loop
1240 -- Ada 2005 (AI-251): Conversion to interface to force "this"
1243 Formal_Typ := Etype (Etype (Formal));
1245 if Ekind (Formal_Typ) = E_Record_Type_With_Private then
1246 Formal_Typ := Full_View (Formal_Typ);
1249 if Is_Access_Type (Formal_Typ) then
1250 Formal_DDT := Directly_Designated_Type (Formal_Typ);
1253 Actual_Typ := Etype (Actual);
1255 if Is_Access_Type (Actual_Typ) then
1256 Actual_DDT := Directly_Designated_Type (Actual_Typ);
1259 if Is_Interface (Formal_Typ) then
1261 -- No need to displace the pointer if the type of the actual
1262 -- is class-wide of the formal-type interface; in this case the
1263 -- displacement of the pointer was already done at the point of
1264 -- the call to the enclosing subprogram. This case corresponds
1265 -- with the call to P (Obj) in the following example:
1267 -- type I is interface;
1268 -- procedure P (X : I) is abstract;
1270 -- procedure General_Op (Obj : I'Class) is
1275 if Is_Class_Wide_Type (Actual_Typ)
1276 and then Etype (Actual_Typ) = Formal_Typ
1280 -- No need to displace the pointer if the type of the actual is a
1281 -- derivation of the formal-type interface because in this case
1282 -- the interface primitives are located in the primary dispatch
1285 elsif Is_Ancestor (Formal_Typ, Actual_Typ) then
1289 Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
1290 Rewrite (Actual, Conversion);
1291 Analyze_And_Resolve (Actual, Formal_Typ);
1294 -- Anonymous access type
1296 elsif Is_Access_Type (Formal_Typ)
1297 and then Is_Interface (Etype (Formal_DDT))
1298 and then Interface_Present_In_Ancestor
1300 Iface => Etype (Formal_DDT))
1302 if Nkind (Actual) = N_Attribute_Reference
1304 (Attribute_Name (Actual) = Name_Access
1305 or else Attribute_Name (Actual) = Name_Unchecked_Access)
1307 Nam := Attribute_Name (Actual);
1309 Conversion := Convert_To (Etype (Formal_DDT), Prefix (Actual));
1311 Rewrite (Actual, Conversion);
1312 Analyze_And_Resolve (Actual, Etype (Formal_DDT));
1315 Unchecked_Convert_To (Formal_Typ,
1316 Make_Attribute_Reference (Loc,
1317 Prefix => Relocate_Node (Actual),
1318 Attribute_Name => Nam)));
1320 Analyze_And_Resolve (Actual, Formal_Typ);
1322 -- No need to displace the pointer if the actual is a class-wide
1323 -- type of the formal-type interface because in this case the
1324 -- displacement of the pointer was already done at the point of
1325 -- the call to the enclosing subprogram (this case is similar
1326 -- to the example described above for the non access-type case)
1328 elsif Is_Class_Wide_Type (Actual_DDT)
1329 and then Etype (Actual_DDT) = Formal_DDT
1333 -- No need to displace the pointer if the type of the actual is a
1334 -- derivation of the interface (because in this case the interface
1335 -- primitives are located in the primary dispatch table)
1337 elsif Is_Ancestor (Formal_DDT, Actual_DDT) then
1341 Actual_Dup := Relocate_Node (Actual);
1343 if From_With_Type (Actual_Typ) then
1345 -- If the type of the actual parameter comes from a limited
1346 -- with-clause and the non-limited view is already available
1347 -- we replace the anonymous access type by a duplicate decla
1348 -- ration whose designated type is the non-limited view
1350 if Ekind (Actual_DDT) = E_Incomplete_Type
1351 and then Present (Non_Limited_View (Actual_DDT))
1353 Anon := New_Copy (Actual_Typ);
1355 if Is_Itype (Anon) then
1356 Set_Scope (Anon, Current_Scope);
1359 Set_Directly_Designated_Type (Anon,
1360 Non_Limited_View (Actual_DDT));
1361 Set_Etype (Actual_Dup, Anon);
1363 elsif Is_Class_Wide_Type (Actual_DDT)
1364 and then Ekind (Etype (Actual_DDT)) = E_Incomplete_Type
1365 and then Present (Non_Limited_View (Etype (Actual_DDT)))
1367 Anon := New_Copy (Actual_Typ);
1369 if Is_Itype (Anon) then
1370 Set_Scope (Anon, Current_Scope);
1373 Set_Directly_Designated_Type (Anon,
1374 New_Copy (Actual_DDT));
1375 Set_Class_Wide_Type (Directly_Designated_Type (Anon),
1376 New_Copy (Class_Wide_Type (Actual_DDT)));
1377 Set_Etype (Directly_Designated_Type (Anon),
1378 Non_Limited_View (Etype (Actual_DDT)));
1380 Class_Wide_Type (Directly_Designated_Type (Anon)),
1381 Non_Limited_View (Etype (Actual_DDT)));
1382 Set_Etype (Actual_Dup, Anon);
1386 Conversion := Convert_To (Formal_Typ, Actual_Dup);
1387 Rewrite (Actual, Conversion);
1388 Analyze_And_Resolve (Actual, Formal_Typ);
1392 Next_Actual (Actual);
1393 Next_Formal (Formal);
1395 end Expand_Interface_Actuals;
1397 ----------------------------
1398 -- Expand_Interface_Thunk --
1399 ----------------------------
1401 function Expand_Interface_Thunk
1403 Thunk_Alias : Entity_Id;
1404 Thunk_Id : Entity_Id) return Node_Id
1406 Loc : constant Source_Ptr := Sloc (N);
1407 Actuals : constant List_Id := New_List;
1408 Decl : constant List_Id := New_List;
1409 Formals : constant List_Id := New_List;
1413 New_Formal : Node_Id;
1419 -- Traverse the list of alias to find the final target
1421 Target := Thunk_Alias;
1422 while Present (Alias (Target)) loop
1423 Target := Alias (Target);
1426 -- Duplicate the formals
1428 Formal := First_Formal (Target);
1429 E := First_Formal (N);
1430 while Present (Formal) loop
1431 New_Formal := Copy_Separate_Tree (Parent (Formal));
1433 -- Propagate the parameter type to the copy. This is required to
1434 -- properly handle the case in which the subprogram covering the
1435 -- interface has been inherited:
1438 -- type I is interface;
1439 -- procedure P (X : I) is abstract;
1441 -- type T is tagged null record;
1442 -- procedure P (X : T);
1444 -- type DT is new T and I with ...
1446 Set_Parameter_Type (New_Formal, New_Reference_To (Etype (E), Loc));
1447 Append_To (Formals, New_Formal);
1449 Next_Formal (Formal);
1453 -- Give message if configurable run-time and Offset_To_Top unavailable
1455 if not RTE_Available (RE_Offset_To_Top) then
1456 Error_Msg_CRT ("abstract interface types", N);
1460 if Ekind (First_Formal (Target)) = E_In_Parameter
1461 and then Ekind (Etype (First_Formal (Target)))
1462 = E_Anonymous_Access_Type
1466 -- type T is access all <<type of the first formal>>
1467 -- S1 := Storage_Offset!(First_formal)
1468 -- - Offset_To_Top (First_Formal.Tag)
1470 -- ... and the first actual of the call is generated as T!(S1)
1473 Make_Full_Type_Declaration (Loc,
1474 Defining_Identifier =>
1475 Make_Defining_Identifier (Loc,
1476 New_Internal_Name ('T')),
1478 Make_Access_To_Object_Definition (Loc,
1479 All_Present => True,
1480 Null_Exclusion_Present => False,
1481 Constant_Present => False,
1482 Subtype_Indication =>
1484 (Directly_Designated_Type
1485 (Etype (First_Formal (Target))), Loc)));
1488 Make_Object_Declaration (Loc,
1489 Defining_Identifier =>
1490 Make_Defining_Identifier (Loc,
1491 New_Internal_Name ('S')),
1492 Constant_Present => True,
1493 Object_Definition =>
1494 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1496 Make_Op_Subtract (Loc,
1498 Unchecked_Convert_To
1499 (RTE (RE_Storage_Offset),
1501 (Defining_Identifier (First (Formals)), Loc)),
1503 Make_Function_Call (Loc,
1504 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1505 Parameter_Associations => New_List (
1506 Unchecked_Convert_To
1509 (Defining_Identifier (First (Formals)), Loc))))));
1511 Append_To (Decl, Decl_2);
1512 Append_To (Decl, Decl_1);
1514 -- Reference the new first actual
1517 Unchecked_Convert_To
1518 (Defining_Identifier (Decl_2),
1519 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1524 -- S1 := Storage_Offset!(First_formal'Address)
1525 -- - Offset_To_Top (First_Formal.Tag)
1526 -- S2 := Tag_Ptr!(S3)
1529 Make_Object_Declaration (Loc,
1530 Defining_Identifier =>
1531 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1532 Constant_Present => True,
1533 Object_Definition =>
1534 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1536 Make_Op_Subtract (Loc,
1538 Unchecked_Convert_To
1539 (RTE (RE_Storage_Offset),
1540 Make_Attribute_Reference (Loc,
1543 (Defining_Identifier (First (Formals)), Loc),
1544 Attribute_Name => Name_Address)),
1546 Make_Function_Call (Loc,
1547 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1548 Parameter_Associations => New_List (
1549 Make_Attribute_Reference (Loc,
1550 Prefix => New_Reference_To
1551 (Defining_Identifier (First (Formals)),
1553 Attribute_Name => Name_Address)))));
1556 Make_Object_Declaration (Loc,
1557 Defining_Identifier =>
1558 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1559 Constant_Present => True,
1560 Object_Definition => New_Reference_To (RTE (RE_Addr_Ptr), Loc),
1562 Unchecked_Convert_To
1564 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1566 Append_To (Decl, Decl_1);
1567 Append_To (Decl, Decl_2);
1569 -- Reference the new first actual
1572 Unchecked_Convert_To
1573 (Etype (First_Entity (Target)),
1574 Make_Explicit_Dereference (Loc,
1575 New_Reference_To (Defining_Identifier (Decl_2), Loc))));
1578 Formal := Next (First (Formals));
1579 while Present (Formal) loop
1581 New_Reference_To (Defining_Identifier (Formal), Loc));
1585 if Ekind (Target) = E_Procedure then
1587 Make_Subprogram_Body (Loc,
1589 Make_Procedure_Specification (Loc,
1590 Defining_Unit_Name => Thunk_Id,
1591 Parameter_Specifications => Formals),
1592 Declarations => Decl,
1593 Handled_Statement_Sequence =>
1594 Make_Handled_Sequence_Of_Statements (Loc,
1595 Statements => New_List (
1596 Make_Procedure_Call_Statement (Loc,
1597 Name => New_Occurrence_Of (Target, Loc),
1598 Parameter_Associations => Actuals))));
1600 else pragma Assert (Ekind (Target) = E_Function);
1603 Make_Subprogram_Body (Loc,
1605 Make_Function_Specification (Loc,
1606 Defining_Unit_Name => Thunk_Id,
1607 Parameter_Specifications => Formals,
1608 Result_Definition =>
1609 New_Copy (Result_Definition (Parent (Target)))),
1610 Declarations => Decl,
1611 Handled_Statement_Sequence =>
1612 Make_Handled_Sequence_Of_Statements (Loc,
1613 Statements => New_List (
1614 Make_Return_Statement (Loc,
1615 Make_Function_Call (Loc,
1616 Name => New_Occurrence_Of (Target, Loc),
1617 Parameter_Associations => Actuals)))));
1620 -- Analyze the code of the thunk with checks suppressed because we are
1621 -- in the middle of building the dispatch information itself and some
1622 -- characteristics of the type may not be fully available.
1624 Analyze (New_Code, Suppress => All_Checks);
1626 end Expand_Interface_Thunk;
1632 function Fill_DT_Entry
1634 Prim : Entity_Id) return Node_Id
1636 Typ : constant Entity_Id := Scope (DTC_Entity (Prim));
1637 DT_Ptr : constant Entity_Id :=
1638 Node (First_Elmt (Access_Disp_Table (Typ)));
1639 Pos : constant Uint := DT_Position (Prim);
1640 Tag : constant Entity_Id := First_Tag_Component (Typ);
1643 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1645 if Is_Predefined_Dispatching_Operation (Prim)
1646 or else Is_Predefined_Dispatching_Alias (Prim)
1649 Make_DT_Access_Action (Typ,
1650 Action => Set_Predefined_Prim_Op_Address,
1652 Unchecked_Convert_To (RTE (RE_Tag),
1653 New_Reference_To (DT_Ptr, Loc)), -- DTptr
1655 Make_Integer_Literal (Loc, Pos), -- Position
1657 Make_Attribute_Reference (Loc, -- Value
1658 Prefix => New_Reference_To (Prim, Loc),
1659 Attribute_Name => Name_Address)));
1661 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
1664 Make_DT_Access_Action (Typ,
1665 Action => Set_Prim_Op_Address,
1667 Unchecked_Convert_To (RTE (RE_Tag),
1668 New_Reference_To (DT_Ptr, Loc)), -- DTptr
1670 Make_Integer_Literal (Loc, Pos), -- Position
1672 Make_Attribute_Reference (Loc, -- Value
1673 Prefix => New_Reference_To (Prim, Loc),
1674 Attribute_Name => Name_Address)));
1678 -----------------------------
1679 -- Fill_Secondary_DT_Entry --
1680 -----------------------------
1682 function Fill_Secondary_DT_Entry
1685 Thunk_Id : Entity_Id;
1686 Iface_DT_Ptr : Entity_Id) return Node_Id
1688 Typ : constant Entity_Id := Scope (DTC_Entity (Alias (Prim)));
1689 Iface_Prim : constant Entity_Id := Abstract_Interface_Alias (Prim);
1690 Pos : constant Uint := DT_Position (Iface_Prim);
1691 Tag : constant Entity_Id :=
1692 First_Tag_Component (Scope (DTC_Entity (Iface_Prim)));
1695 if Is_Predefined_Dispatching_Operation (Prim)
1696 or else Is_Predefined_Dispatching_Alias (Prim)
1699 Make_DT_Access_Action (Typ,
1700 Action => Set_Predefined_Prim_Op_Address,
1702 Unchecked_Convert_To (RTE (RE_Tag),
1703 New_Reference_To (Iface_DT_Ptr, Loc)), -- DTptr
1705 Make_Integer_Literal (Loc, Pos), -- Position
1707 Make_Attribute_Reference (Loc, -- Value
1708 Prefix => New_Reference_To (Thunk_Id, Loc),
1709 Attribute_Name => Name_Address)));
1711 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
1714 Make_DT_Access_Action (Typ,
1715 Action => Set_Prim_Op_Address,
1717 Unchecked_Convert_To (RTE (RE_Tag),
1718 New_Reference_To (Iface_DT_Ptr, Loc)), -- DTptr
1720 Make_Integer_Literal (Loc, Pos), -- Position
1722 Make_Attribute_Reference (Loc, -- Value
1723 Prefix => New_Reference_To (Thunk_Id, Loc),
1724 Attribute_Name => Name_Address)));
1726 end Fill_Secondary_DT_Entry;
1728 ---------------------------
1729 -- Get_Remotely_Callable --
1730 ---------------------------
1732 function Get_Remotely_Callable (Obj : Node_Id) return Node_Id is
1733 Loc : constant Source_Ptr := Sloc (Obj);
1735 return Make_DT_Access_Action
1736 (Typ => Etype (Obj),
1737 Action => Get_Remotely_Callable,
1739 Make_Selected_Component (Loc,
1741 Selector_Name => Make_Identifier (Loc, Name_uTag))));
1742 end Get_Remotely_Callable;
1744 ------------------------------------------
1745 -- Init_Predefined_Interface_Primitives --
1746 ------------------------------------------
1748 function Init_Predefined_Interface_Primitives
1749 (Typ : Entity_Id) return List_Id
1751 Loc : constant Source_Ptr := Sloc (Typ);
1752 DT_Ptr : constant Node_Id :=
1753 Node (First_Elmt (Access_Disp_Table (Typ)));
1754 Result : constant List_Id := New_List;
1758 -- No need to inherit primitives if we have an abstract interface
1759 -- type or a concurrent type.
1761 if Is_Interface (Typ)
1762 or else Is_Concurrent_Record_Type (Typ)
1763 or else Restriction_Active (No_Dispatching_Calls)
1768 AI := Next_Elmt (First_Elmt (Access_Disp_Table (Typ)));
1769 while Present (AI) loop
1771 -- All the secondary tables inherit the dispatch table entries
1772 -- associated with predefined primitives.
1775 -- Inherit_DT (T'Tag, Iface'Tag, 0);
1778 Make_DT_Access_Action (Typ,
1779 Action => Inherit_DT,
1781 Node1 => New_Reference_To (DT_Ptr, Loc),
1782 Node2 => Unchecked_Convert_To (RTE (RE_Tag),
1783 New_Reference_To (Node (AI), Loc)),
1784 Node3 => Make_Integer_Literal (Loc, Uint_0))));
1790 end Init_Predefined_Interface_Primitives;
1792 -------------------------------------
1793 -- Is_Predefined_Dispatching_Alias --
1794 -------------------------------------
1796 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
1801 if not Is_Predefined_Dispatching_Operation (Prim)
1802 and then Present (Alias (Prim))
1805 while Present (Alias (E)) loop
1809 if Is_Predefined_Dispatching_Operation (E) then
1815 end Is_Predefined_Dispatching_Alias;
1817 ----------------------------------------
1818 -- Make_Disp_Asynchronous_Select_Body --
1819 ----------------------------------------
1821 function Make_Disp_Asynchronous_Select_Body
1822 (Typ : Entity_Id) return Node_Id
1824 Conc_Typ : Entity_Id := Empty;
1825 Decls : constant List_Id := New_List;
1827 Loc : constant Source_Ptr := Sloc (Typ);
1828 Stmts : constant List_Id := New_List;
1831 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1833 -- Null body is generated for interface types
1835 if Is_Interface (Typ) then
1837 Make_Subprogram_Body (Loc,
1839 Make_Disp_Asynchronous_Select_Spec (Typ),
1842 Handled_Statement_Sequence =>
1843 Make_Handled_Sequence_Of_Statements (Loc,
1844 New_List (Make_Null_Statement (Loc))));
1847 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1849 if Is_Concurrent_Record_Type (Typ) then
1850 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1853 -- I : Integer := Get_Entry_Index (tag! (<type>VP), S);
1855 -- where I will be used to capture the entry index of the primitive
1856 -- wrapper at position S.
1859 Make_Object_Declaration (Loc,
1860 Defining_Identifier =>
1861 Make_Defining_Identifier (Loc, Name_uI),
1862 Object_Definition =>
1863 New_Reference_To (Standard_Integer, Loc),
1865 Make_DT_Access_Action (Typ,
1870 Unchecked_Convert_To (RTE (RE_Tag),
1871 New_Reference_To (DT_Ptr, Loc)),
1872 Make_Identifier (Loc, Name_uS)))));
1874 if Ekind (Conc_Typ) = E_Protected_Type then
1877 -- Protected_Entry_Call (
1878 -- T._object'access,
1879 -- protected_entry_index! (I),
1881 -- Asynchronous_Call,
1884 -- where T is the protected object, I is the entry index, P are
1885 -- the wrapped parameters and B is the name of the communication
1889 Make_Procedure_Call_Statement (Loc,
1891 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1892 Parameter_Associations =>
1895 Make_Attribute_Reference (Loc, -- T._object'access
1897 Name_Unchecked_Access,
1899 Make_Selected_Component (Loc,
1901 Make_Identifier (Loc, Name_uT),
1903 Make_Identifier (Loc, Name_uObject))),
1905 Make_Unchecked_Type_Conversion (Loc, -- entry index
1907 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
1909 Make_Identifier (Loc, Name_uI)),
1911 Make_Identifier (Loc, Name_uP), -- parameter block
1912 New_Reference_To ( -- Asynchronous_Call
1913 RTE (RE_Asynchronous_Call), Loc),
1914 Make_Identifier (Loc, Name_uB)))); -- comm block
1916 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
1919 -- Protected_Entry_Call (
1921 -- task_entry_index! (I),
1923 -- Conditional_Call,
1926 -- where T is the task object, I is the entry index, P are the
1927 -- wrapped parameters and F is the status flag.
1930 Make_Procedure_Call_Statement (Loc,
1932 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
1933 Parameter_Associations =>
1936 Make_Selected_Component (Loc, -- T._task_id
1938 Make_Identifier (Loc, Name_uT),
1940 Make_Identifier (Loc, Name_uTask_Id)),
1942 Make_Unchecked_Type_Conversion (Loc, -- entry index
1944 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
1946 Make_Identifier (Loc, Name_uI)),
1948 Make_Identifier (Loc, Name_uP), -- parameter block
1949 New_Reference_To ( -- Asynchronous_Call
1950 RTE (RE_Asynchronous_Call), Loc),
1951 Make_Identifier (Loc, Name_uF)))); -- status flag
1956 Make_Subprogram_Body (Loc,
1958 Make_Disp_Asynchronous_Select_Spec (Typ),
1961 Handled_Statement_Sequence =>
1962 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
1963 end Make_Disp_Asynchronous_Select_Body;
1965 ----------------------------------------
1966 -- Make_Disp_Asynchronous_Select_Spec --
1967 ----------------------------------------
1969 function Make_Disp_Asynchronous_Select_Spec
1970 (Typ : Entity_Id) return Node_Id
1972 Loc : constant Source_Ptr := Sloc (Typ);
1973 Def_Id : constant Node_Id :=
1974 Make_Defining_Identifier (Loc,
1975 Name_uDisp_Asynchronous_Select);
1976 Params : constant List_Id := New_List;
1979 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1981 -- "T" - Object parameter
1982 -- "S" - Primitive operation slot
1983 -- "P" - Wrapped parameters
1984 -- "B" - Communication block
1985 -- "F" - Status flag
1987 SEU.Build_T (Loc, Typ, Params);
1988 SEU.Build_S (Loc, Params);
1989 SEU.Build_P (Loc, Params);
1990 SEU.Build_B (Loc, Params);
1991 SEU.Build_F (Loc, Params);
1993 Set_Is_Internal (Def_Id);
1996 Make_Procedure_Specification (Loc,
1997 Defining_Unit_Name => Def_Id,
1998 Parameter_Specifications => Params);
1999 end Make_Disp_Asynchronous_Select_Spec;
2001 ---------------------------------------
2002 -- Make_Disp_Conditional_Select_Body --
2003 ---------------------------------------
2005 function Make_Disp_Conditional_Select_Body
2006 (Typ : Entity_Id) return Node_Id
2008 Loc : constant Source_Ptr := Sloc (Typ);
2009 Blk_Nam : Entity_Id;
2010 Conc_Typ : Entity_Id := Empty;
2011 Decls : constant List_Id := New_List;
2013 Stmts : constant List_Id := New_List;
2016 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2018 -- Null body is generated for interface types
2020 if Is_Interface (Typ) then
2022 Make_Subprogram_Body (Loc,
2024 Make_Disp_Conditional_Select_Spec (Typ),
2027 Handled_Statement_Sequence =>
2028 Make_Handled_Sequence_Of_Statements (Loc,
2029 New_List (Make_Null_Statement (Loc))));
2032 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2034 if Is_Concurrent_Record_Type (Typ) then
2035 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2040 -- where I will be used to capture the entry index of the primitive
2041 -- wrapper at position S.
2044 Make_Object_Declaration (Loc,
2045 Defining_Identifier =>
2046 Make_Defining_Identifier (Loc, Name_uI),
2047 Object_Definition =>
2048 New_Reference_To (Standard_Integer, Loc)));
2051 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
2053 -- if C = POK_Procedure
2054 -- or else C = POK_Protected_Procedure
2055 -- or else C = POK_Task_Procedure;
2061 SEU.Build_Common_Dispatching_Select_Statements
2062 (Loc, Typ, DT_Ptr, Stmts);
2065 -- Bnn : Communication_Block;
2067 -- where Bnn is the name of the communication block used in
2068 -- the call to Protected_Entry_Call.
2070 Blk_Nam := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
2073 Make_Object_Declaration (Loc,
2074 Defining_Identifier =>
2076 Object_Definition =>
2077 New_Reference_To (RTE (RE_Communication_Block), Loc)));
2080 -- I := Get_Entry_Index (tag! (<type>VP), S);
2082 -- I is the entry index and S is the dispatch table slot
2085 Make_Assignment_Statement (Loc,
2087 Make_Identifier (Loc, Name_uI),
2089 Make_DT_Access_Action (Typ,
2094 Unchecked_Convert_To (RTE (RE_Tag),
2095 New_Reference_To (DT_Ptr, Loc)),
2096 Make_Identifier (Loc, Name_uS)))));
2098 if Ekind (Conc_Typ) = E_Protected_Type then
2101 -- Protected_Entry_Call (
2102 -- T._object'access,
2103 -- protected_entry_index! (I),
2105 -- Conditional_Call,
2108 -- where T is the protected object, I is the entry index, P are
2109 -- the wrapped parameters and Bnn is the name of the communication
2113 Make_Procedure_Call_Statement (Loc,
2115 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
2116 Parameter_Associations =>
2119 Make_Attribute_Reference (Loc, -- T._object'access
2121 Name_Unchecked_Access,
2123 Make_Selected_Component (Loc,
2125 Make_Identifier (Loc, Name_uT),
2127 Make_Identifier (Loc, Name_uObject))),
2129 Make_Unchecked_Type_Conversion (Loc, -- entry index
2131 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
2133 Make_Identifier (Loc, Name_uI)),
2135 Make_Identifier (Loc, Name_uP), -- parameter block
2136 New_Reference_To ( -- Conditional_Call
2137 RTE (RE_Conditional_Call), Loc),
2138 New_Reference_To ( -- Bnn
2142 -- F := not Cancelled (Bnn);
2144 -- where F is the success flag. The status of Cancelled is negated
2145 -- in order to match the behaviour of the version for task types.
2148 Make_Assignment_Statement (Loc,
2150 Make_Identifier (Loc, Name_uF),
2154 Make_Function_Call (Loc,
2156 New_Reference_To (RTE (RE_Cancelled), Loc),
2157 Parameter_Associations =>
2159 New_Reference_To (Blk_Nam, Loc))))));
2161 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2164 -- Protected_Entry_Call (
2166 -- task_entry_index! (I),
2168 -- Conditional_Call,
2171 -- where T is the task object, I is the entry index, P are the
2172 -- wrapped parameters and F is the status flag.
2175 Make_Procedure_Call_Statement (Loc,
2177 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
2178 Parameter_Associations =>
2181 Make_Selected_Component (Loc, -- T._task_id
2183 Make_Identifier (Loc, Name_uT),
2185 Make_Identifier (Loc, Name_uTask_Id)),
2187 Make_Unchecked_Type_Conversion (Loc, -- entry index
2189 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2191 Make_Identifier (Loc, Name_uI)),
2193 Make_Identifier (Loc, Name_uP), -- parameter block
2194 New_Reference_To ( -- Conditional_Call
2195 RTE (RE_Conditional_Call), Loc),
2196 Make_Identifier (Loc, Name_uF)))); -- status flag
2201 Make_Subprogram_Body (Loc,
2203 Make_Disp_Conditional_Select_Spec (Typ),
2206 Handled_Statement_Sequence =>
2207 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2208 end Make_Disp_Conditional_Select_Body;
2210 ---------------------------------------
2211 -- Make_Disp_Conditional_Select_Spec --
2212 ---------------------------------------
2214 function Make_Disp_Conditional_Select_Spec
2215 (Typ : Entity_Id) return Node_Id
2217 Loc : constant Source_Ptr := Sloc (Typ);
2218 Def_Id : constant Node_Id :=
2219 Make_Defining_Identifier (Loc,
2220 Name_uDisp_Conditional_Select);
2221 Params : constant List_Id := New_List;
2224 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2226 -- "T" - Object parameter
2227 -- "S" - Primitive operation slot
2228 -- "P" - Wrapped parameters
2230 -- "F" - Status flag
2232 SEU.Build_T (Loc, Typ, Params);
2233 SEU.Build_S (Loc, Params);
2234 SEU.Build_P (Loc, Params);
2235 SEU.Build_C (Loc, Params);
2236 SEU.Build_F (Loc, Params);
2238 Set_Is_Internal (Def_Id);
2241 Make_Procedure_Specification (Loc,
2242 Defining_Unit_Name => Def_Id,
2243 Parameter_Specifications => Params);
2244 end Make_Disp_Conditional_Select_Spec;
2246 -------------------------------------
2247 -- Make_Disp_Get_Prim_Op_Kind_Body --
2248 -------------------------------------
2250 function Make_Disp_Get_Prim_Op_Kind_Body
2251 (Typ : Entity_Id) return Node_Id
2253 Loc : constant Source_Ptr := Sloc (Typ);
2257 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2259 if Is_Interface (Typ) then
2261 Make_Subprogram_Body (Loc,
2263 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2266 Handled_Statement_Sequence =>
2267 Make_Handled_Sequence_Of_Statements (Loc,
2268 New_List (Make_Null_Statement (Loc))));
2271 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2274 -- C := get_prim_op_kind (tag! (<type>VP), S);
2276 -- where C is the out parameter capturing the call kind and S is the
2277 -- dispatch table slot number.
2280 Make_Subprogram_Body (Loc,
2282 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2285 Handled_Statement_Sequence =>
2286 Make_Handled_Sequence_Of_Statements (Loc,
2288 Make_Assignment_Statement (Loc,
2290 Make_Identifier (Loc, Name_uC),
2292 Make_DT_Access_Action (Typ,
2297 Unchecked_Convert_To (RTE (RE_Tag),
2298 New_Reference_To (DT_Ptr, Loc)),
2299 Make_Identifier (Loc, Name_uS)))))));
2300 end Make_Disp_Get_Prim_Op_Kind_Body;
2302 -------------------------------------
2303 -- Make_Disp_Get_Prim_Op_Kind_Spec --
2304 -------------------------------------
2306 function Make_Disp_Get_Prim_Op_Kind_Spec
2307 (Typ : Entity_Id) return Node_Id
2309 Loc : constant Source_Ptr := Sloc (Typ);
2310 Def_Id : constant Node_Id :=
2311 Make_Defining_Identifier (Loc,
2312 Name_uDisp_Get_Prim_Op_Kind);
2313 Params : constant List_Id := New_List;
2316 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2318 -- "T" - Object parameter
2319 -- "S" - Primitive operation slot
2322 SEU.Build_T (Loc, Typ, Params);
2323 SEU.Build_S (Loc, Params);
2324 SEU.Build_C (Loc, Params);
2326 Set_Is_Internal (Def_Id);
2329 Make_Procedure_Specification (Loc,
2330 Defining_Unit_Name => Def_Id,
2331 Parameter_Specifications => Params);
2332 end Make_Disp_Get_Prim_Op_Kind_Spec;
2334 --------------------------------
2335 -- Make_Disp_Get_Task_Id_Body --
2336 --------------------------------
2338 function Make_Disp_Get_Task_Id_Body
2339 (Typ : Entity_Id) return Node_Id
2341 Loc : constant Source_Ptr := Sloc (Typ);
2345 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2347 if Is_Concurrent_Record_Type (Typ)
2348 and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
2351 Make_Return_Statement (Loc,
2353 Make_Selected_Component (Loc,
2355 Make_Identifier (Loc, Name_uT),
2357 Make_Identifier (Loc, Name_uTask_Id)));
2359 -- A null body is constructed for non-task types
2363 Make_Return_Statement (Loc,
2365 New_Reference_To (RTE (RO_ST_Null_Task), Loc));
2369 Make_Subprogram_Body (Loc,
2371 Make_Disp_Get_Task_Id_Spec (Typ),
2374 Handled_Statement_Sequence =>
2375 Make_Handled_Sequence_Of_Statements (Loc,
2377 end Make_Disp_Get_Task_Id_Body;
2379 --------------------------------
2380 -- Make_Disp_Get_Task_Id_Spec --
2381 --------------------------------
2383 function Make_Disp_Get_Task_Id_Spec
2384 (Typ : Entity_Id) return Node_Id
2386 Loc : constant Source_Ptr := Sloc (Typ);
2387 Def_Id : constant Node_Id :=
2388 Make_Defining_Identifier (Loc,
2389 Name_uDisp_Get_Task_Id);
2392 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2394 Set_Is_Internal (Def_Id);
2397 Make_Function_Specification (Loc,
2398 Defining_Unit_Name => Def_Id,
2399 Parameter_Specifications => New_List (
2400 Make_Parameter_Specification (Loc,
2401 Defining_Identifier =>
2402 Make_Defining_Identifier (Loc, Name_uT),
2404 New_Reference_To (Typ, Loc))),
2405 Result_Definition =>
2406 New_Reference_To (RTE (RO_ST_Task_Id), Loc));
2407 end Make_Disp_Get_Task_Id_Spec;
2409 ---------------------------------
2410 -- Make_Disp_Timed_Select_Body --
2411 ---------------------------------
2413 function Make_Disp_Timed_Select_Body
2414 (Typ : Entity_Id) return Node_Id
2416 Loc : constant Source_Ptr := Sloc (Typ);
2417 Conc_Typ : Entity_Id := Empty;
2418 Decls : constant List_Id := New_List;
2420 Stmts : constant List_Id := New_List;
2423 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2425 -- Null body is generated for interface types
2427 if Is_Interface (Typ) then
2429 Make_Subprogram_Body (Loc,
2431 Make_Disp_Timed_Select_Spec (Typ),
2434 Handled_Statement_Sequence =>
2435 Make_Handled_Sequence_Of_Statements (Loc,
2436 New_List (Make_Null_Statement (Loc))));
2439 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2441 if Is_Concurrent_Record_Type (Typ) then
2442 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2447 -- where I will be used to capture the entry index of the primitive
2448 -- wrapper at position S.
2451 Make_Object_Declaration (Loc,
2452 Defining_Identifier =>
2453 Make_Defining_Identifier (Loc, Name_uI),
2454 Object_Definition =>
2455 New_Reference_To (Standard_Integer, Loc)));
2458 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
2460 -- if C = POK_Procedure
2461 -- or else C = POK_Protected_Procedure
2462 -- or else C = POK_Task_Procedure;
2468 SEU.Build_Common_Dispatching_Select_Statements
2469 (Loc, Typ, DT_Ptr, Stmts);
2472 -- I := Get_Entry_Index (tag! (<type>VP), S);
2474 -- I is the entry index and S is the dispatch table slot
2477 Make_Assignment_Statement (Loc,
2479 Make_Identifier (Loc, Name_uI),
2481 Make_DT_Access_Action (Typ,
2486 Unchecked_Convert_To (RTE (RE_Tag),
2487 New_Reference_To (DT_Ptr, Loc)),
2488 Make_Identifier (Loc, Name_uS)))));
2490 if Ekind (Conc_Typ) = E_Protected_Type then
2493 -- Timed_Protected_Entry_Call (
2494 -- T._object'access,
2495 -- protected_entry_index! (I),
2501 -- where T is the protected object, I is the entry index, P are
2502 -- the wrapped parameters, D is the delay amount, M is the delay
2503 -- mode and F is the status flag.
2506 Make_Procedure_Call_Statement (Loc,
2508 New_Reference_To (RTE (RE_Timed_Protected_Entry_Call), Loc),
2509 Parameter_Associations =>
2512 Make_Attribute_Reference (Loc, -- T._object'access
2514 Name_Unchecked_Access,
2516 Make_Selected_Component (Loc,
2518 Make_Identifier (Loc, Name_uT),
2520 Make_Identifier (Loc, Name_uObject))),
2522 Make_Unchecked_Type_Conversion (Loc, -- entry index
2524 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
2526 Make_Identifier (Loc, Name_uI)),
2528 Make_Identifier (Loc, Name_uP), -- parameter block
2529 Make_Identifier (Loc, Name_uD), -- delay
2530 Make_Identifier (Loc, Name_uM), -- delay mode
2531 Make_Identifier (Loc, Name_uF)))); -- status flag
2534 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2537 -- Timed_Task_Entry_Call (
2539 -- task_entry_index! (I),
2545 -- where T is the task object, I is the entry index, P are the
2546 -- wrapped parameters, D is the delay amount, M is the delay
2547 -- mode and F is the status flag.
2550 Make_Procedure_Call_Statement (Loc,
2552 New_Reference_To (RTE (RE_Timed_Task_Entry_Call), Loc),
2553 Parameter_Associations =>
2556 Make_Selected_Component (Loc, -- T._task_id
2558 Make_Identifier (Loc, Name_uT),
2560 Make_Identifier (Loc, Name_uTask_Id)),
2562 Make_Unchecked_Type_Conversion (Loc, -- entry index
2564 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2566 Make_Identifier (Loc, Name_uI)),
2568 Make_Identifier (Loc, Name_uP), -- parameter block
2569 Make_Identifier (Loc, Name_uD), -- delay
2570 Make_Identifier (Loc, Name_uM), -- delay mode
2571 Make_Identifier (Loc, Name_uF)))); -- status flag
2576 Make_Subprogram_Body (Loc,
2578 Make_Disp_Timed_Select_Spec (Typ),
2581 Handled_Statement_Sequence =>
2582 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2583 end Make_Disp_Timed_Select_Body;
2585 ---------------------------------
2586 -- Make_Disp_Timed_Select_Spec --
2587 ---------------------------------
2589 function Make_Disp_Timed_Select_Spec
2590 (Typ : Entity_Id) return Node_Id
2592 Loc : constant Source_Ptr := Sloc (Typ);
2593 Def_Id : constant Node_Id :=
2594 Make_Defining_Identifier (Loc,
2595 Name_uDisp_Timed_Select);
2596 Params : constant List_Id := New_List;
2599 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2601 -- "T" - Object parameter
2602 -- "S" - Primitive operation slot
2603 -- "P" - Wrapped parameters
2607 -- "F" - Status flag
2609 SEU.Build_T (Loc, Typ, Params);
2610 SEU.Build_S (Loc, Params);
2611 SEU.Build_P (Loc, Params);
2614 Make_Parameter_Specification (Loc,
2615 Defining_Identifier =>
2616 Make_Defining_Identifier (Loc, Name_uD),
2618 New_Reference_To (Standard_Duration, Loc)));
2621 Make_Parameter_Specification (Loc,
2622 Defining_Identifier =>
2623 Make_Defining_Identifier (Loc, Name_uM),
2625 New_Reference_To (Standard_Integer, Loc)));
2627 SEU.Build_C (Loc, Params);
2628 SEU.Build_F (Loc, Params);
2630 Set_Is_Internal (Def_Id);
2633 Make_Procedure_Specification (Loc,
2634 Defining_Unit_Name => Def_Id,
2635 Parameter_Specifications => Params);
2636 end Make_Disp_Timed_Select_Spec;
2642 function Make_DT (Typ : Entity_Id) return List_Id is
2643 Loc : constant Source_Ptr := Sloc (Typ);
2644 Result : constant List_Id := New_List;
2645 Elab_Code : constant List_Id := New_List;
2647 Tname : constant Name_Id := Chars (Typ);
2648 Name_DT : constant Name_Id := New_External_Name (Tname, 'T');
2649 Name_DT_Ptr : constant Name_Id := New_External_Name (Tname, 'P');
2650 Name_SSD : constant Name_Id := New_External_Name (Tname, 'S');
2651 Name_TSD : constant Name_Id := New_External_Name (Tname, 'B');
2652 Name_Exname : constant Name_Id := New_External_Name (Tname, 'E');
2653 Name_No_Reg : constant Name_Id := New_External_Name (Tname, 'F');
2654 Name_ITable : Name_Id;
2656 DT : constant Node_Id := Make_Defining_Identifier (Loc, Name_DT);
2657 DT_Ptr : constant Node_Id := Make_Defining_Identifier (Loc, Name_DT_Ptr);
2658 SSD : constant Node_Id := Make_Defining_Identifier (Loc, Name_SSD);
2659 TSD : constant Node_Id := Make_Defining_Identifier (Loc, Name_TSD);
2660 Exname : constant Node_Id := Make_Defining_Identifier (Loc, Name_Exname);
2661 No_Reg : constant Node_Id := Make_Defining_Identifier (Loc, Name_No_Reg);
2664 Generalized_Tag : constant Entity_Id := RTE (RE_Tag);
2671 Parent_Num_Ifaces : Int;
2672 Size_Expr_Node : Node_Id;
2673 TSD_Num_Entries : Int;
2675 Empty_DT : Boolean := False;
2677 Ancestor_Ifaces : Elist_Id;
2678 Typ_Ifaces : Elist_Id;
2681 if not RTE_Available (RE_Tag) then
2682 Error_Msg_CRT ("tagged types", Typ);
2686 -- Calculate the size of the DT and the TSD. First we count the number
2687 -- of interfaces implemented by the ancestors
2689 Parent_Num_Ifaces := 0;
2692 -- Count the abstract interfaces of the ancestors
2694 if Typ /= Etype (Typ) then
2695 Collect_Abstract_Interfaces (Etype (Typ), Ancestor_Ifaces);
2697 AI := First_Elmt (Ancestor_Ifaces);
2698 while Present (AI) loop
2699 Parent_Num_Ifaces := Parent_Num_Ifaces + 1;
2704 -- Count the number of additional interfaces implemented by Typ
2706 Collect_Abstract_Interfaces (Typ, Typ_Ifaces);
2708 AI := First_Elmt (Typ_Ifaces);
2709 while Present (AI) loop
2710 Num_Ifaces := Num_Ifaces + 1;
2714 -- Count ancestors to compute the inheritance depth. For private
2715 -- extensions, always go to the full view in order to compute the
2716 -- real inheritance depth.
2719 Parent_Type : Entity_Id := Typ;
2725 P := Etype (Parent_Type);
2727 if Is_Private_Type (P) then
2728 P := Full_View (Base_Type (P));
2731 exit when P = Parent_Type;
2733 I_Depth := I_Depth + 1;
2738 -- Abstract interfaces don't need the DT. We reserve a single entry
2739 -- for its DT because at run-time the pointer to this dummy DT will
2740 -- be used as the tag of this abstract interface type. The table of
2741 -- interfaces is required to give support to AI-405
2743 if Is_Interface (Typ) then
2746 TSD_Num_Entries := 0;
2749 TSD_Num_Entries := I_Depth + 1;
2750 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
2752 -- If the number of primitives of Typ is 0 (or we are compiling
2753 -- with the No_Dispatching_Calls restriction) we reserve a dummy
2754 -- single entry for its DT because at run-time the pointer to this
2755 -- dummy DT will be used as the tag of this tagged type.
2758 or else Restriction_Active (No_Dispatching_Calls)
2765 -- Dispatch table and related entities are allocated statically
2767 Set_Ekind (DT, E_Variable);
2768 Set_Is_Statically_Allocated (DT);
2770 Set_Ekind (DT_Ptr, E_Variable);
2771 Set_Is_Statically_Allocated (DT_Ptr);
2773 if Num_Ifaces > 0 then
2774 Name_ITable := New_External_Name (Tname, 'I');
2775 ITable := Make_Defining_Identifier (Loc, Name_ITable);
2777 Set_Ekind (ITable, E_Variable);
2778 Set_Is_Statically_Allocated (ITable);
2781 Set_Ekind (SSD, E_Variable);
2782 Set_Is_Statically_Allocated (SSD);
2784 Set_Ekind (TSD, E_Variable);
2785 Set_Is_Statically_Allocated (TSD);
2787 Set_Ekind (Exname, E_Variable);
2788 Set_Is_Statically_Allocated (Exname);
2790 Set_Ekind (No_Reg, E_Variable);
2791 Set_Is_Statically_Allocated (No_Reg);
2793 -- Generate code to create the storage for the Dispatch_Table object:
2795 -- DT : Storage_Array (1..DT_Prologue_Size+nb_prim*DT_Entry_Size);
2796 -- for DT'Alignment use Address'Alignment
2800 Left_Opnd => Make_DT_Access_Action (Typ, DT_Prologue_Size, No_List),
2802 Make_Op_Multiply (Loc,
2804 Make_DT_Access_Action (Typ, DT_Entry_Size, No_List),
2806 Make_Integer_Literal (Loc, Nb_Prim)));
2809 Make_Object_Declaration (Loc,
2810 Defining_Identifier => DT,
2811 Aliased_Present => True,
2812 Object_Definition =>
2813 Make_Subtype_Indication (Loc,
2814 Subtype_Mark => New_Reference_To
2815 (RTE (RE_Storage_Array), Loc),
2816 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
2817 Constraints => New_List (
2819 Low_Bound => Make_Integer_Literal (Loc, 1),
2820 High_Bound => Size_Expr_Node))))));
2823 Make_Attribute_Definition_Clause (Loc,
2824 Name => New_Reference_To (DT, Loc),
2825 Chars => Name_Alignment,
2827 Make_Attribute_Reference (Loc,
2828 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
2829 Attribute_Name => Name_Alignment)));
2831 -- Generate code to create the pointer to the dispatch table
2833 -- DT_Ptr : Tag := Tag!(DT'Address);
2835 -- According to the C++ ABI, the base of the vtable is located after a
2836 -- prologue containing Offset_To_Top, and Typeinfo_Ptr. Hence, we move
2837 -- down the pointer to the real base of the vtable
2840 Make_Object_Declaration (Loc,
2841 Defining_Identifier => DT_Ptr,
2842 Constant_Present => True,
2843 Object_Definition => New_Reference_To (Generalized_Tag, Loc),
2845 Unchecked_Convert_To (Generalized_Tag,
2848 Unchecked_Convert_To (RTE (RE_Storage_Offset),
2849 Make_Attribute_Reference (Loc,
2850 Prefix => New_Reference_To (DT, Loc),
2851 Attribute_Name => Name_Address)),
2853 Make_DT_Access_Action (Typ,
2854 DT_Prologue_Size, No_List)))));
2856 -- Generate code to define the boolean that controls registration, in
2857 -- order to avoid multiple registrations for tagged types defined in
2858 -- multiple-called scopes.
2861 Make_Object_Declaration (Loc,
2862 Defining_Identifier => No_Reg,
2863 Object_Definition => New_Reference_To (Standard_Boolean, Loc),
2864 Expression => New_Reference_To (Standard_True, Loc)));
2866 -- Set Access_Disp_Table field to be the dispatch table pointer
2868 if No (Access_Disp_Table (Typ)) then
2869 Set_Access_Disp_Table (Typ, New_Elmt_List);
2872 Prepend_Elmt (DT_Ptr, Access_Disp_Table (Typ));
2874 -- Generate code to create the storage for the type specific data object
2875 -- with enough space to store the tags of the ancestors plus the tags
2876 -- of all the implemented interfaces (as described in a-tags.adb).
2878 -- TSD: Storage_Array
2879 -- (1..TSD_Prologue_Size+TSD_Num_Entries*TSD_Entry_Size);
2880 -- for TSD'Alignment use Address'Alignment
2885 Make_DT_Access_Action (Typ, TSD_Prologue_Size, No_List),
2887 Make_Op_Multiply (Loc,
2889 Make_DT_Access_Action (Typ, TSD_Entry_Size, No_List),
2891 Make_Integer_Literal (Loc, TSD_Num_Entries)));
2894 Make_Object_Declaration (Loc,
2895 Defining_Identifier => TSD,
2896 Aliased_Present => True,
2897 Object_Definition =>
2898 Make_Subtype_Indication (Loc,
2899 Subtype_Mark => New_Reference_To (RTE (RE_Storage_Array), Loc),
2900 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
2901 Constraints => New_List (
2903 Low_Bound => Make_Integer_Literal (Loc, 1),
2904 High_Bound => Size_Expr_Node))))));
2907 Make_Attribute_Definition_Clause (Loc,
2908 Name => New_Reference_To (TSD, Loc),
2909 Chars => Name_Alignment,
2911 Make_Attribute_Reference (Loc,
2912 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
2913 Attribute_Name => Name_Alignment)));
2916 -- Set_Signature (DT_Ptr, Value);
2918 if RTE_Available (RE_Set_Signature) then
2919 if Is_Interface (Typ) then
2920 Append_To (Elab_Code,
2921 Make_DT_Access_Action (Typ,
2922 Action => Set_Signature,
2924 New_Reference_To (DT_Ptr, Loc), -- DTptr
2925 New_Reference_To (RTE (RE_Abstract_Interface), Loc))));
2928 Append_To (Elab_Code,
2929 Make_DT_Access_Action (Typ,
2930 Action => Set_Signature,
2932 New_Reference_To (DT_Ptr, Loc), -- DTptr
2933 New_Reference_To (RTE (RE_Primary_DT), Loc))));
2937 -- Generate code to put the Address of the TSD in the dispatch table
2938 -- Set_TSD (DT_Ptr, TSD);
2940 Append_To (Elab_Code,
2941 Make_DT_Access_Action (Typ,
2944 New_Reference_To (DT_Ptr, Loc), -- DTptr
2945 Make_Attribute_Reference (Loc, -- Value
2946 Prefix => New_Reference_To (TSD, Loc),
2947 Attribute_Name => Name_Address))));
2949 -- Set the pointer to the Interfaces_Table (if any). Otherwise the
2950 -- corresponding access component is set to null.
2952 if Num_Ifaces = 0 then
2953 if RTE_Available (RE_Set_Interface_Table) then
2954 Append_To (Elab_Code,
2955 Make_DT_Access_Action (Typ,
2956 Action => Set_Interface_Table,
2958 New_Reference_To (DT_Ptr, Loc), -- DTptr
2959 New_Reference_To (RTE (RE_Null_Address), Loc)))); -- null
2962 -- Generate the Interface_Table object and set the access
2963 -- component if the TSD to it.
2965 elsif RTE_Available (RE_Set_Interface_Table) then
2967 Make_Object_Declaration (Loc,
2968 Defining_Identifier => ITable,
2969 Aliased_Present => True,
2970 Object_Definition =>
2971 Make_Subtype_Indication (Loc,
2972 Subtype_Mark => New_Reference_To
2973 (RTE (RE_Interface_Data), Loc),
2974 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
2975 Constraints => New_List (
2976 Make_Integer_Literal (Loc,
2979 Append_To (Elab_Code,
2980 Make_DT_Access_Action (Typ,
2981 Action => Set_Interface_Table,
2983 New_Reference_To (DT_Ptr, Loc), -- DTptr
2984 Make_Attribute_Reference (Loc, -- Value
2985 Prefix => New_Reference_To (ITable, Loc),
2986 Attribute_Name => Name_Address))));
2990 -- Set_Num_Prim_Ops (T'Tag, Nb_Prim)
2992 if RTE_Available (RE_Set_Num_Prim_Ops) then
2993 if not Is_Interface (Typ) then
2995 Append_To (Elab_Code,
2996 Make_Procedure_Call_Statement (Loc,
2997 Name => New_Reference_To (RTE (RE_Set_Num_Prim_Ops), Loc),
2998 Parameter_Associations => New_List (
2999 New_Reference_To (DT_Ptr, Loc),
3000 Make_Integer_Literal (Loc, Uint_0))));
3002 Append_To (Elab_Code,
3003 Make_Procedure_Call_Statement (Loc,
3004 Name => New_Reference_To (RTE (RE_Set_Num_Prim_Ops), Loc),
3005 Parameter_Associations => New_List (
3006 New_Reference_To (DT_Ptr, Loc),
3007 Make_Integer_Literal (Loc, Nb_Prim))));
3011 if Ada_Version >= Ada_05
3012 and then not Is_Interface (Typ)
3013 and then not Is_Abstract (Typ)
3014 and then not Is_Controlled (Typ)
3015 and then not Restriction_Active (No_Dispatching_Calls)
3018 -- Set_Type_Kind (T'Tag, Type_Kind (Typ));
3020 Append_To (Elab_Code,
3021 Make_DT_Access_Action (Typ,
3022 Action => Set_Tagged_Kind,
3024 New_Reference_To (DT_Ptr, Loc), -- DTptr
3025 Tagged_Kind (Typ)))); -- Value
3027 -- Generate the Select Specific Data table for synchronized
3028 -- types that implement a synchronized interface. The size
3029 -- of the table is constrained by the number of non-predefined
3030 -- primitive operations.
3033 and then Is_Concurrent_Record_Type (Typ)
3034 and then Implements_Interface (
3036 Kind => Any_Limited_Interface,
3037 Check_Parent => True)
3040 Make_Object_Declaration (Loc,
3041 Defining_Identifier => SSD,
3042 Aliased_Present => True,
3043 Object_Definition =>
3044 Make_Subtype_Indication (Loc,
3045 Subtype_Mark => New_Reference_To (
3046 RTE (RE_Select_Specific_Data), Loc),
3048 Make_Index_Or_Discriminant_Constraint (Loc,
3049 Constraints => New_List (
3050 Make_Integer_Literal (Loc, Nb_Prim))))));
3052 -- Set the pointer to the Select Specific Data table in the TSD
3054 Append_To (Elab_Code,
3055 Make_DT_Access_Action (Typ,
3058 New_Reference_To (DT_Ptr, Loc), -- DTptr
3059 Make_Attribute_Reference (Loc, -- Value
3060 Prefix => New_Reference_To (SSD, Loc),
3061 Attribute_Name => Name_Address))));
3066 -- Generate: Exname : constant String := full_qualified_name (typ);
3067 -- The type itself may be an anonymous parent type, so use the first
3068 -- subtype to have a user-recognizable name.
3071 Make_Object_Declaration (Loc,
3072 Defining_Identifier => Exname,
3073 Constant_Present => True,
3074 Object_Definition => New_Reference_To (Standard_String, Loc),
3076 Make_String_Literal (Loc,
3077 Full_Qualified_Name (First_Subtype (Typ)))));
3079 -- Generate: Set_Expanded_Name (DT_Ptr, exname'Address);
3081 Append_To (Elab_Code,
3082 Make_DT_Access_Action (Typ,
3083 Action => Set_Expanded_Name,
3085 Node1 => New_Reference_To (DT_Ptr, Loc),
3087 Make_Attribute_Reference (Loc,
3088 Prefix => New_Reference_To (Exname, Loc),
3089 Attribute_Name => Name_Address))));
3091 if not Is_Interface (Typ) then
3092 -- Generate: Set_Access_Level (DT_Ptr, <type's accessibility level>);
3094 Append_To (Elab_Code,
3095 Make_DT_Access_Action (Typ,
3096 Action => Set_Access_Level,
3098 Node1 => New_Reference_To (DT_Ptr, Loc),
3099 Node2 => Make_Integer_Literal (Loc, Type_Access_Level (Typ)))));
3102 -- If the ancestor is a CPP_Class type we inherit the dispatch tables
3103 -- in the init proc, and we don't need to fill them in here.
3105 if Is_CPP_Class (Etype (Typ)) and then not Debug_Flag_QQ then
3108 -- Otherwise we fill in the dispatch tables here
3111 if Typ = Etype (Typ)
3112 or else Is_CPP_Class (Etype (Typ))
3113 or else Is_Interface (Typ)
3116 Unchecked_Convert_To (Generalized_Tag,
3117 Make_Integer_Literal (Loc, 0));
3119 Unchecked_Convert_To (Generalized_Tag,
3120 Make_Integer_Literal (Loc, 0));
3125 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc);
3128 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc);
3131 if Typ /= Etype (Typ)
3132 and then not Is_Interface (Typ)
3133 and then not Restriction_Active (No_Dispatching_Calls)
3135 -- Generate: Inherit_DT (parent'tag, DT_Ptr, nb_prim of parent);
3137 if not Is_Interface (Etype (Typ)) then
3138 if Restriction_Active (No_Dispatching_Calls) then
3139 Append_To (Elab_Code,
3140 Make_DT_Access_Action (Typ,
3141 Action => Inherit_DT,
3144 Node2 => New_Reference_To (DT_Ptr, Loc),
3145 Node3 => Make_Integer_Literal (Loc, Uint_0))));
3147 Append_To (Elab_Code,
3148 Make_DT_Access_Action (Typ,
3149 Action => Inherit_DT,
3152 Node2 => New_Reference_To (DT_Ptr, Loc),
3153 Node3 => Make_Integer_Literal (Loc,
3155 (First_Tag_Component (Etype (Typ)))))));
3159 -- Inherit the secondary dispatch tables of the ancestor
3161 if not Restriction_Active (No_Dispatching_Calls)
3162 and then not Is_CPP_Class (Etype (Typ))
3165 Sec_DT_Ancestor : Elmt_Id :=
3168 (Access_Disp_Table (Etype (Typ))));
3169 Sec_DT_Typ : Elmt_Id :=
3172 (Access_Disp_Table (Typ)));
3174 procedure Copy_Secondary_DTs (Typ : Entity_Id);
3175 -- Local procedure required to climb through the ancestors
3176 -- and copy the contents of all their secondary dispatch
3179 ------------------------
3180 -- Copy_Secondary_DTs --
3181 ------------------------
3183 procedure Copy_Secondary_DTs (Typ : Entity_Id) is
3188 -- Climb to the ancestor (if any) handling private types
3190 if Present (Full_View (Etype (Typ))) then
3191 if Full_View (Etype (Typ)) /= Typ then
3192 Copy_Secondary_DTs (Full_View (Etype (Typ)));
3195 elsif Etype (Typ) /= Typ then
3196 Copy_Secondary_DTs (Etype (Typ));
3199 if Present (Abstract_Interfaces (Typ))
3200 and then not Is_Empty_Elmt_List
3201 (Abstract_Interfaces (Typ))
3203 Iface := First_Elmt (Abstract_Interfaces (Typ));
3204 E := First_Entity (Typ);
3206 and then Present (Node (Sec_DT_Ancestor))
3208 if Is_Tag (E) and then Chars (E) /= Name_uTag then
3209 if not Is_Interface (Etype (Typ)) then
3210 Append_To (Elab_Code,
3211 Make_DT_Access_Action (Typ,
3212 Action => Inherit_DT,
3214 Node1 => Unchecked_Convert_To
3217 (Node (Sec_DT_Ancestor),
3219 Node2 => Unchecked_Convert_To
3222 (Node (Sec_DT_Typ), Loc)),
3223 Node3 => Make_Integer_Literal (Loc,
3224 DT_Entry_Count (E)))));
3227 Next_Elmt (Sec_DT_Ancestor);
3228 Next_Elmt (Sec_DT_Typ);
3235 end Copy_Secondary_DTs;
3238 if Present (Node (Sec_DT_Ancestor)) then
3240 -- Handle private types
3242 if Present (Full_View (Typ)) then
3243 Copy_Secondary_DTs (Full_View (Typ));
3245 Copy_Secondary_DTs (Typ);
3253 -- Inherit_TSD (parent'tag, DT_Ptr);
3255 if not Is_Interface (Typ) then
3256 Append_To (Elab_Code,
3257 Make_DT_Access_Action (Typ,
3258 Action => Inherit_TSD,
3261 Node2 => New_Reference_To (DT_Ptr, Loc))));
3265 if not Is_Interface (Typ) then
3267 -- For types with no controlled components, generate:
3268 -- Set_RC_Offset (DT_Ptr, 0);
3270 -- For simple types with controlled components, generate:
3271 -- Set_RC_Offset (DT_Ptr, type._record_controller'position);
3273 -- For complex types with controlled components where the position
3274 -- of the record controller is not statically computable, if there
3275 -- are controlled components at this level, generate:
3276 -- Set_RC_Offset (DT_Ptr, -1);
3277 -- to indicate that the _controller field is right after the _parent
3279 -- Or if there are no controlled components at this level, generate:
3280 -- Set_RC_Offset (DT_Ptr, -2);
3281 -- to indicate that we need to get the position from the parent.
3287 if not Has_Controlled_Component (Typ) then
3288 Position := Make_Integer_Literal (Loc, 0);
3290 elsif Etype (Typ) /= Typ
3291 and then Has_Discriminants (Etype (Typ))
3293 if Has_New_Controlled_Component (Typ) then
3294 Position := Make_Integer_Literal (Loc, -1);
3296 Position := Make_Integer_Literal (Loc, -2);
3300 Make_Attribute_Reference (Loc,
3302 Make_Selected_Component (Loc,
3303 Prefix => New_Reference_To (Typ, Loc),
3305 New_Reference_To (Controller_Component (Typ), Loc)),
3306 Attribute_Name => Name_Position);
3308 -- This is not proper Ada code to use the attribute 'Position
3309 -- on something else than an object but this is supported by
3310 -- the back end (see comment on the Bit_Component attribute in
3311 -- sem_attr). So we avoid semantic checking here.
3313 -- Is this documented in sinfo.ads??? it should be!
3315 Set_Analyzed (Position);
3316 Set_Etype (Prefix (Position), RTE (RE_Record_Controller));
3317 Set_Etype (Prefix (Prefix (Position)), Typ);
3318 Set_Etype (Selector_Name (Prefix (Position)),
3319 RTE (RE_Record_Controller));
3320 Set_Etype (Position, RTE (RE_Storage_Offset));
3323 Append_To (Elab_Code,
3324 Make_DT_Access_Action (Typ,
3325 Action => Set_RC_Offset,
3327 Node1 => New_Reference_To (DT_Ptr, Loc),
3328 Node2 => Position)));
3331 -- Generate: Set_Remotely_Callable (DT_Ptr, Status); where Status is
3332 -- described in E.4 (18)
3341 or else Is_Shared_Passive (Typ)
3343 ((Is_Remote_Types (Typ)
3344 or else Is_Remote_Call_Interface (Typ))
3345 and then Original_View_In_Visible_Part (Typ))
3346 or else not Comes_From_Source (Typ));
3348 Append_To (Elab_Code,
3349 Make_DT_Access_Action (Typ,
3350 Action => Set_Remotely_Callable,
3352 New_Occurrence_Of (DT_Ptr, Loc),
3353 New_Occurrence_Of (Status, Loc))));
3356 if RTE_Available (RE_Set_Offset_To_Top) then
3358 -- Set_Offset_To_Top (0, DT_Ptr, True, 0, null);
3360 Append_To (Elab_Code,
3361 Make_Procedure_Call_Statement (Loc,
3362 Name => New_Reference_To (RTE (RE_Set_Offset_To_Top), Loc),
3363 Parameter_Associations => New_List (
3364 New_Reference_To (RTE (RE_Null_Address), Loc),
3365 New_Reference_To (DT_Ptr, Loc),
3366 New_Occurrence_Of (Standard_True, Loc),
3367 Make_Integer_Literal (Loc, Uint_0),
3368 New_Reference_To (RTE (RE_Null_Address), Loc))));
3372 -- Generate: Set_External_Tag (DT_Ptr, exname'Address);
3373 -- Should be the external name not the qualified name???
3375 if not Has_External_Tag_Rep_Clause (Typ) then
3376 Append_To (Elab_Code,
3377 Make_DT_Access_Action (Typ,
3378 Action => Set_External_Tag,
3380 Node1 => New_Reference_To (DT_Ptr, Loc),
3382 Make_Attribute_Reference (Loc,
3383 Prefix => New_Reference_To (Exname, Loc),
3384 Attribute_Name => Name_Address))));
3386 -- Generate code to register the Tag in the External_Tag hash
3387 -- table for the pure Ada type only.
3389 -- Register_Tag (Dt_Ptr);
3391 -- Skip this if routine not available, or in No_Run_Time mode
3392 -- or Typ is an abstract interface type (because the table to
3393 -- register it is not available in the abstract type but in
3394 -- types implementing this interface)
3396 if not No_Run_Time_Mode
3397 and then RTE_Available (RE_Register_Tag)
3398 and then Is_RTE (Generalized_Tag, RE_Tag)
3399 and then not Is_Interface (Typ)
3401 Append_To (Elab_Code,
3402 Make_Procedure_Call_Statement (Loc,
3403 Name => New_Reference_To (RTE (RE_Register_Tag), Loc),
3404 Parameter_Associations =>
3405 New_List (New_Reference_To (DT_Ptr, Loc))));
3415 Append_To (Elab_Code,
3416 Make_Assignment_Statement (Loc,
3417 Name => New_Reference_To (No_Reg, Loc),
3418 Expression => New_Reference_To (Standard_False, Loc)));
3421 Make_Implicit_If_Statement (Typ,
3422 Condition => New_Reference_To (No_Reg, Loc),
3423 Then_Statements => Elab_Code));
3425 -- Ada 2005 (AI-251): Register the tag of the interfaces into
3426 -- the table of implemented interfaces.
3428 if Num_Ifaces > 0 then
3433 -- If the parent is an interface we must generate code to register
3434 -- all its interfaces; otherwise this code is not needed because
3435 -- Inherit_TSD has already inherited such interfaces.
3437 if Etype (Typ) /= Typ
3438 and then Is_Interface (Etype (Typ))
3442 AI := First_Elmt (Ancestor_Ifaces);
3443 while Present (AI) loop
3445 -- Register_Interface (DT_Ptr, Interface'Tag);
3448 Make_DT_Access_Action (Typ,
3449 Action => Register_Interface_Tag,
3451 Node1 => New_Reference_To (DT_Ptr, Loc),
3452 Node2 => New_Reference_To
3455 (Access_Disp_Table (Node (AI)))),
3457 Node3 => Make_Integer_Literal (Loc, Position))));
3459 Position := Position + 1;
3464 -- Register the interfaces that are not implemented by the
3467 AI := First_Elmt (Typ_Ifaces);
3469 -- Skip the interfaces implemented by the ancestor
3471 for Count in 1 .. Parent_Num_Ifaces loop
3475 -- Register the additional interfaces
3477 Position := Parent_Num_Ifaces + 1;
3478 while Present (AI) loop
3481 -- Register_Interface (DT_Ptr, Interface'Tag);
3483 if not Is_Interface (Typ)
3484 or else Typ /= Node (AI)
3487 Make_DT_Access_Action (Typ,
3488 Action => Register_Interface_Tag,
3490 Node1 => New_Reference_To (DT_Ptr, Loc),
3491 Node2 => New_Reference_To
3494 (Access_Disp_Table (Node (AI)))),
3496 Node3 => Make_Integer_Literal (Loc, Position))));
3498 Position := Position + 1;
3504 pragma Assert (Position = Num_Ifaces + 1);
3511 ---------------------------
3512 -- Make_DT_Access_Action --
3513 ---------------------------
3515 function Make_DT_Access_Action
3517 Action : DT_Access_Action;
3518 Args : List_Id) return Node_Id
3520 Action_Name : constant Entity_Id := RTE (Ada_Actions (Action));
3526 -- This is a constant
3528 return New_Reference_To (Action_Name, Sloc (Typ));
3531 pragma Assert (List_Length (Args) = Action_Nb_Arg (Action));
3533 Loc := Sloc (First (Args));
3535 if Action_Is_Proc (Action) then
3537 Make_Procedure_Call_Statement (Loc,
3538 Name => New_Reference_To (Action_Name, Loc),
3539 Parameter_Associations => Args);
3543 Make_Function_Call (Loc,
3544 Name => New_Reference_To (Action_Name, Loc),
3545 Parameter_Associations => Args);
3547 end Make_DT_Access_Action;
3549 -----------------------
3550 -- Make_Secondary_DT --
3551 -----------------------
3553 procedure Make_Secondary_DT
3555 Ancestor_Typ : Entity_Id;
3559 Acc_Disp_Tables : in out Elist_Id;
3560 Result : out List_Id)
3562 Loc : constant Source_Ptr := Sloc (AI_Tag);
3563 Generalized_Tag : constant Entity_Id := RTE (RE_Interface_Tag);
3564 Name_DT : constant Name_Id := New_Internal_Name ('T');
3565 Empty_DT : Boolean := False;
3567 Iface_DT_Ptr : Node_Id;
3568 Name_DT_Ptr : Name_Id;
3571 Size_Expr_Node : Node_Id;
3577 -- Generate a unique external name associated with the secondary
3578 -- dispatch table. This external name will be used to declare an
3579 -- access to this secondary dispatch table, value that will be used
3580 -- for the elaboration of Typ's objects and also for the elaboration
3581 -- of objects of any derivation of Typ that do not override any
3582 -- primitive operation of Typ.
3584 Get_Secondary_DT_External_Name (Typ, Ancestor_Typ, Suffix_Index);
3587 Name_DT_Ptr := New_External_Name (Tname, "P");
3588 Iface_DT := Make_Defining_Identifier (Loc, Name_DT);
3589 Iface_DT_Ptr := Make_Defining_Identifier (Loc, Name_DT_Ptr);
3591 -- Dispatch table and related entities are allocated statically
3593 Set_Ekind (Iface_DT, E_Variable);
3594 Set_Is_Statically_Allocated (Iface_DT);
3596 Set_Ekind (Iface_DT_Ptr, E_Variable);
3597 Set_Is_Statically_Allocated (Iface_DT_Ptr);
3599 -- Generate code to create the storage for the Dispatch_Table object.
3600 -- If the number of primitives of Typ is 0 we reserve a dummy single
3601 -- entry for its DT because at run-time the pointer to this dummy entry
3602 -- will be used as the tag.
3604 Nb_Prim := UI_To_Int (DT_Entry_Count (AI_Tag));
3611 -- DT : Storage_Array (1..DT_Prologue_Size+nb_prim*DT_Entry_Size);
3612 -- for DT'Alignment use Address'Alignment
3616 Left_Opnd => Make_DT_Access_Action (Etype (AI_Tag),
3620 Make_Op_Multiply (Loc,
3622 Make_DT_Access_Action (Etype (AI_Tag),
3626 Make_Integer_Literal (Loc, Nb_Prim)));
3629 Make_Object_Declaration (Loc,
3630 Defining_Identifier => Iface_DT,
3631 Aliased_Present => True,
3632 Object_Definition =>
3633 Make_Subtype_Indication (Loc,
3634 Subtype_Mark => New_Reference_To (RTE (RE_Storage_Array), Loc),
3635 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
3636 Constraints => New_List (
3638 Low_Bound => Make_Integer_Literal (Loc, 1),
3639 High_Bound => Size_Expr_Node))))));
3642 Make_Attribute_Definition_Clause (Loc,
3643 Name => New_Reference_To (Iface_DT, Loc),
3644 Chars => Name_Alignment,
3646 Make_Attribute_Reference (Loc,
3647 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
3648 Attribute_Name => Name_Alignment)));
3650 -- Generate code to create the pointer to the dispatch table
3652 -- Iface_DT_Ptr : Tag := Tag!(DT'Address);
3654 -- According to the C++ ABI, the base of the vtable is located
3655 -- after the following prologue: Offset_To_Top, and Typeinfo_Ptr.
3656 -- Hence, move the pointer down to the real base of the vtable.
3659 Make_Object_Declaration (Loc,
3660 Defining_Identifier => Iface_DT_Ptr,
3661 Constant_Present => True,
3662 Object_Definition => New_Reference_To (Generalized_Tag, Loc),
3664 Unchecked_Convert_To (Generalized_Tag,
3667 Unchecked_Convert_To (RTE (RE_Storage_Offset),
3668 Make_Attribute_Reference (Loc,
3669 Prefix => New_Reference_To (Iface_DT, Loc),
3670 Attribute_Name => Name_Address)),
3672 Make_DT_Access_Action (Etype (AI_Tag),
3673 DT_Prologue_Size, No_List)))));
3675 -- Note: Offset_To_Top will be initialized by the init subprogram
3677 -- Set Access_Disp_Table field to be the dispatch table pointer
3679 if not (Present (Acc_Disp_Tables)) then
3680 Acc_Disp_Tables := New_Elmt_List;
3683 Append_Elmt (Iface_DT_Ptr, Acc_Disp_Tables);
3685 -- Step 1: Generate an Object Specific Data (OSD) table
3687 OSD := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
3689 -- Nothing to do if configurable run time does not support the
3690 -- Object_Specific_Data entity.
3692 if not RTE_Available (RE_Object_Specific_Data) then
3693 Error_Msg_CRT ("abstract interface types", Typ);
3698 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims);
3699 -- where the constraint is used to allocate space for the
3700 -- non-predefined primitive operations only.
3703 Make_Object_Declaration (Loc,
3704 Defining_Identifier => OSD,
3705 Object_Definition =>
3706 Make_Subtype_Indication (Loc,
3707 Subtype_Mark => New_Reference_To (
3708 RTE (RE_Object_Specific_Data), Loc),
3710 Make_Index_Or_Discriminant_Constraint (Loc,
3711 Constraints => New_List (
3712 Make_Integer_Literal (Loc, Nb_Prim))))));
3715 Make_DT_Access_Action (Typ,
3716 Action => Set_Signature,
3718 Unchecked_Convert_To (RTE (RE_Tag),
3719 New_Reference_To (Iface_DT_Ptr, Loc)),
3720 New_Reference_To (RTE (RE_Secondary_DT), Loc))));
3723 -- Ada.Tags.Set_OSD (Iface_DT_Ptr, OSD);
3726 Make_DT_Access_Action (Typ,
3729 Unchecked_Convert_To (RTE (RE_Tag),
3730 New_Reference_To (Iface_DT_Ptr, Loc)),
3731 Make_Attribute_Reference (Loc,
3732 Prefix => New_Reference_To (OSD, Loc),
3733 Attribute_Name => Name_Address))));
3736 -- Set_Num_Prim_Ops (T'Tag, Nb_Prim)
3738 if RTE_Available (RE_Set_Num_Prim_Ops) then
3741 Make_Procedure_Call_Statement (Loc,
3742 Name => New_Reference_To (RTE (RE_Set_Num_Prim_Ops), Loc),
3743 Parameter_Associations => New_List (
3744 Unchecked_Convert_To (RTE (RE_Tag),
3745 New_Reference_To (Iface_DT_Ptr, Loc)),
3746 Make_Integer_Literal (Loc, Uint_0))));
3749 Make_Procedure_Call_Statement (Loc,
3750 Name => New_Reference_To (RTE (RE_Set_Num_Prim_Ops), Loc),
3751 Parameter_Associations => New_List (
3752 Unchecked_Convert_To (RTE (RE_Tag),
3753 New_Reference_To (Iface_DT_Ptr, Loc)),
3754 Make_Integer_Literal (Loc, Nb_Prim))));
3758 if Ada_Version >= Ada_05
3759 and then not Is_Interface (Typ)
3760 and then not Is_Abstract (Typ)
3761 and then not Is_Controlled (Typ)
3762 and then RTE_Available (RE_Set_Tagged_Kind)
3763 and then not Restriction_Active (No_Dispatching_Calls)
3766 -- Set_Tagged_Kind (Iface'Tag, Tagged_Kind (Iface));
3769 Make_DT_Access_Action (Typ,
3770 Action => Set_Tagged_Kind,
3772 Unchecked_Convert_To (RTE (RE_Tag), -- DTptr
3773 New_Reference_To (Iface_DT_Ptr, Loc)),
3774 Tagged_Kind (Typ)))); -- Value
3777 and then Is_Concurrent_Record_Type (Typ)
3778 and then Implements_Interface (
3780 Kind => Any_Limited_Interface,
3781 Check_Parent => True)
3785 Prim_Alias : Entity_Id;
3786 Prim_Elmt : Elmt_Id;
3789 -- Step 2: Populate the OSD table
3791 Prim_Alias := Empty;
3792 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3793 while Present (Prim_Elmt) loop
3794 Prim := Node (Prim_Elmt);
3796 if Present (Abstract_Interface_Alias (Prim))
3797 and then Find_Dispatching_Type
3798 (Abstract_Interface_Alias (Prim)) = Iface
3800 Prim_Alias := Abstract_Interface_Alias (Prim);
3803 -- Ada.Tags.Set_Offset_Index (Tag (Iface_DT_Ptr),
3804 -- Secondary_DT_Pos, Primary_DT_pos);
3807 Make_DT_Access_Action (Iface,
3808 Action => Set_Offset_Index,
3810 Unchecked_Convert_To (RTE (RE_Tag),
3811 New_Reference_To (Iface_DT_Ptr, Loc)),
3812 Make_Integer_Literal (Loc,
3813 DT_Position (Prim_Alias)),
3814 Make_Integer_Literal (Loc,
3815 DT_Position (Alias (Prim))))));
3818 Next_Elmt (Prim_Elmt);
3823 end Make_Secondary_DT;
3825 -------------------------------------
3826 -- Make_Select_Specific_Data_Table --
3827 -------------------------------------
3829 function Make_Select_Specific_Data_Table
3830 (Typ : Entity_Id) return List_Id
3832 Assignments : constant List_Id := New_List;
3833 Loc : constant Source_Ptr := Sloc (Typ);
3835 Conc_Typ : Entity_Id;
3839 Prim_Als : Entity_Id;
3840 Prim_Elmt : Elmt_Id;
3844 type Examined_Array is array (Int range <>) of Boolean;
3846 function Find_Entry_Index (E : Entity_Id) return Uint;
3847 -- Given an entry, find its index in the visible declarations of the
3848 -- corresponding concurrent type of Typ.
3850 ----------------------
3851 -- Find_Entry_Index --
3852 ----------------------
3854 function Find_Entry_Index (E : Entity_Id) return Uint is
3855 Index : Uint := Uint_1;
3856 Subp_Decl : Entity_Id;
3860 and then not Is_Empty_List (Decls)
3862 Subp_Decl := First (Decls);
3863 while Present (Subp_Decl) loop
3864 if Nkind (Subp_Decl) = N_Entry_Declaration then
3865 if Defining_Identifier (Subp_Decl) = E then
3877 end Find_Entry_Index;
3879 -- Start of processing for Make_Select_Specific_Data_Table
3882 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3884 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
3886 if Present (Corresponding_Concurrent_Type (Typ)) then
3887 Conc_Typ := Corresponding_Concurrent_Type (Typ);
3889 if Ekind (Conc_Typ) = E_Protected_Type then
3890 Decls := Visible_Declarations (Protected_Definition (
3891 Parent (Conc_Typ)));
3893 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
3894 Decls := Visible_Declarations (Task_Definition (
3895 Parent (Conc_Typ)));
3899 -- Count the non-predefined primitive operations
3901 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3902 while Present (Prim_Elmt) loop
3903 Prim := Node (Prim_Elmt);
3905 if not (Is_Predefined_Dispatching_Operation (Prim)
3906 or else Is_Predefined_Dispatching_Alias (Prim))
3908 Nb_Prim := Nb_Prim + 1;
3911 Next_Elmt (Prim_Elmt);
3915 Examined : Examined_Array (1 .. Nb_Prim) := (others => False);
3918 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3919 while Present (Prim_Elmt) loop
3920 Prim := Node (Prim_Elmt);
3922 -- Look for primitive overriding an abstract interface subprogram
3924 if Present (Abstract_Interface_Alias (Prim))
3925 and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
3927 Prim_Pos := DT_Position (Alias (Prim));
3928 pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
3929 Examined (UI_To_Int (Prim_Pos)) := True;
3931 -- Set the primitive operation kind regardless of subprogram
3933 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
3935 Append_To (Assignments,
3936 Make_DT_Access_Action (Typ,
3937 Action => Set_Prim_Op_Kind,
3939 New_Reference_To (DT_Ptr, Loc),
3940 Make_Integer_Literal (Loc, Prim_Pos),
3941 Prim_Op_Kind (Alias (Prim), Typ))));
3943 -- Retrieve the root of the alias chain
3946 while Present (Alias (Prim_Als)) loop
3947 Prim_Als := Alias (Prim_Als);
3950 -- In the case of an entry wrapper, set the entry index
3952 if Ekind (Prim) = E_Procedure
3953 and then Is_Primitive_Wrapper (Prim_Als)
3954 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
3957 -- Ada.Tags.Set_Entry_Index
3958 -- (DT_Ptr, <position>, <index>);
3960 Append_To (Assignments,
3961 Make_DT_Access_Action (Typ,
3962 Action => Set_Entry_Index,
3964 New_Reference_To (DT_Ptr, Loc),
3965 Make_Integer_Literal (Loc, Prim_Pos),
3966 Make_Integer_Literal (Loc,
3968 (Wrapped_Entity (Prim_Als))))));
3972 Next_Elmt (Prim_Elmt);
3977 end Make_Select_Specific_Data_Table;
3979 -----------------------------------
3980 -- Original_View_In_Visible_Part --
3981 -----------------------------------
3983 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
3984 Scop : constant Entity_Id := Scope (Typ);
3987 -- The scope must be a package
3989 if Ekind (Scop) /= E_Package
3990 and then Ekind (Scop) /= E_Generic_Package
3995 -- A type with a private declaration has a private view declared in
3996 -- the visible part.
3998 if Has_Private_Declaration (Typ) then
4002 return List_Containing (Parent (Typ)) =
4003 Visible_Declarations (Specification (Unit_Declaration_Node (Scop)));
4004 end Original_View_In_Visible_Part;
4010 function Prim_Op_Kind
4012 Typ : Entity_Id) return Node_Id
4014 Full_Typ : Entity_Id := Typ;
4015 Loc : constant Source_Ptr := Sloc (Prim);
4016 Prim_Op : Entity_Id;
4019 -- Retrieve the original primitive operation
4022 while Present (Alias (Prim_Op)) loop
4023 Prim_Op := Alias (Prim_Op);
4026 if Ekind (Typ) = E_Record_Type
4027 and then Present (Corresponding_Concurrent_Type (Typ))
4029 Full_Typ := Corresponding_Concurrent_Type (Typ);
4032 if Ekind (Prim_Op) = E_Function then
4034 -- Protected function
4036 if Ekind (Full_Typ) = E_Protected_Type then
4037 return New_Reference_To (RTE (RE_POK_Protected_Function), Loc);
4041 elsif Ekind (Full_Typ) = E_Task_Type then
4042 return New_Reference_To (RTE (RE_POK_Task_Function), Loc);
4047 return New_Reference_To (RTE (RE_POK_Function), Loc);
4051 pragma Assert (Ekind (Prim_Op) = E_Procedure);
4053 if Ekind (Full_Typ) = E_Protected_Type then
4057 if Is_Primitive_Wrapper (Prim_Op)
4058 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
4060 return New_Reference_To (RTE (RE_POK_Protected_Entry), Loc);
4062 -- Protected procedure
4065 return New_Reference_To (RTE (RE_POK_Protected_Procedure), Loc);
4068 elsif Ekind (Full_Typ) = E_Task_Type then
4072 if Is_Primitive_Wrapper (Prim_Op)
4073 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
4075 return New_Reference_To (RTE (RE_POK_Task_Entry), Loc);
4077 -- Task "procedure". These are the internally Expander-generated
4078 -- procedures (task body for instance).
4081 return New_Reference_To (RTE (RE_POK_Task_Procedure), Loc);
4084 -- Regular procedure
4087 return New_Reference_To (RTE (RE_POK_Procedure), Loc);
4092 -------------------------
4093 -- Set_All_DT_Position --
4094 -------------------------
4096 procedure Set_All_DT_Position (Typ : Entity_Id) is
4098 procedure Validate_Position (Prim : Entity_Id);
4099 -- Check that the position assignated to Prim is completely safe
4100 -- (it has not been assigned to a previously defined primitive
4101 -- operation of Typ)
4103 -----------------------
4104 -- Validate_Position --
4105 -----------------------
4107 procedure Validate_Position (Prim : Entity_Id) is
4112 -- Aliased primitives are safe
4114 if Present (Alias (Prim)) then
4118 Op_Elmt := First_Elmt (Primitive_Operations (Typ));
4119 while Present (Op_Elmt) loop
4120 Op := Node (Op_Elmt);
4122 -- No need to check against itself
4127 -- Primitive operations covering abstract interfaces are
4130 elsif Present (Abstract_Interface_Alias (Op)) then
4133 -- Predefined dispatching operations are completely safe. They
4134 -- are allocated at fixed positions in a separate table.
4136 elsif Is_Predefined_Dispatching_Operation (Op)
4137 or else Is_Predefined_Dispatching_Alias (Op)
4141 -- Aliased subprograms are safe
4143 elsif Present (Alias (Op)) then
4146 elsif DT_Position (Op) = DT_Position (Prim)
4147 and then not Is_Predefined_Dispatching_Operation (Op)
4148 and then not Is_Predefined_Dispatching_Operation (Prim)
4149 and then not Is_Predefined_Dispatching_Alias (Op)
4150 and then not Is_Predefined_Dispatching_Alias (Prim)
4153 -- Handle aliased subprograms
4162 if Present (Overridden_Operation (Op_1)) then
4163 Op_1 := Overridden_Operation (Op_1);
4164 elsif Present (Alias (Op_1)) then
4165 Op_1 := Alias (Op_1);
4173 if Present (Overridden_Operation (Op_2)) then
4174 Op_2 := Overridden_Operation (Op_2);
4175 elsif Present (Alias (Op_2)) then
4176 Op_2 := Alias (Op_2);
4182 if Op_1 /= Op_2 then
4183 raise Program_Error;
4188 Next_Elmt (Op_Elmt);
4190 end Validate_Position;
4194 Parent_Typ : constant Entity_Id := Etype (Typ);
4195 Root_Typ : constant Entity_Id := Root_Type (Typ);
4196 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
4197 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
4199 Adjusted : Boolean := False;
4200 Finalized : Boolean := False;
4207 Prim_Elmt : Elmt_Id;
4209 -- Start of processing for Set_All_DT_Position
4212 -- Get Entry_Count of the parent
4214 if Parent_Typ /= Typ
4215 and then DT_Entry_Count (First_Tag_Component (Parent_Typ)) /= No_Uint
4217 Parent_EC := UI_To_Int (DT_Entry_Count
4218 (First_Tag_Component (Parent_Typ)));
4223 -- C++ Case, check that pragma CPP_Class, CPP_Virtual and CPP_Vtable
4224 -- give a coherent set of information
4226 if Is_CPP_Class (Root_Typ) and then Debug_Flag_QQ then
4228 -- Compute the number of primitive operations in the main Vtable
4229 -- Set their position:
4230 -- - where it was set if overriden or inherited
4231 -- - after the end of the parent vtable otherwise
4233 Prim_Elmt := First_Prim;
4235 while Present (Prim_Elmt) loop
4236 Prim := Node (Prim_Elmt);
4238 if not Is_CPP_Class (Typ) then
4239 Set_DTC_Entity (Prim, The_Tag);
4241 elsif Present (Alias (Prim)) then
4242 Set_DTC_Entity (Prim, DTC_Entity (Alias (Prim)));
4243 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
4245 elsif No (DTC_Entity (Prim)) and then Is_CPP_Class (Typ) then
4246 Error_Msg_NE ("is a primitive operation of&," &
4247 " pragma Cpp_Virtual required", Prim, Typ);
4250 if DTC_Entity (Prim) = The_Tag then
4252 -- Get the slot from the parent subprogram if any
4258 H := Homonym (Prim);
4259 while Present (H) loop
4260 if Present (DTC_Entity (H))
4261 and then Root_Type (Scope (DTC_Entity (H))) = Root_Typ
4263 Set_DT_Position (Prim, DT_Position (H));
4271 -- Otherwise take the canonical slot after the end of the
4274 if DT_Position (Prim) = No_Uint then
4275 Nb_Prim := Nb_Prim + 1;
4276 Set_DT_Position (Prim, UI_From_Int (Parent_EC + Nb_Prim));
4278 elsif UI_To_Int (DT_Position (Prim)) > Parent_EC then
4279 Nb_Prim := Nb_Prim + 1;
4283 Next_Elmt (Prim_Elmt);
4286 -- Check that the declared size of the Vtable is bigger or equal
4287 -- than the number of primitive operations (if bigger it means that
4288 -- some of the c++ virtual functions were not imported, that is
4291 if DT_Entry_Count (The_Tag) = No_Uint
4292 or else not Is_CPP_Class (Typ)
4294 Set_DT_Entry_Count (The_Tag, UI_From_Int (Parent_EC + Nb_Prim));
4296 elsif UI_To_Int (DT_Entry_Count (The_Tag)) < Parent_EC + Nb_Prim then
4297 Error_Msg_N ("not enough room in the Vtable for all virtual"
4298 & " functions", The_Tag);
4301 -- Check that Positions are not duplicate nor outside the range of
4305 Size : constant Int := UI_To_Int (DT_Entry_Count (The_Tag));
4307 Prim_Pos_Table : array (1 .. Size) of Entity_Id :=
4311 Prim_Elmt := First_Prim;
4312 while Present (Prim_Elmt) loop
4313 Prim := Node (Prim_Elmt);
4315 if DTC_Entity (Prim) = The_Tag then
4316 Pos := UI_To_Int (DT_Position (Prim));
4318 if Pos not in Prim_Pos_Table'Range then
4320 ("position not in range of virtual table", Prim);
4322 elsif Present (Prim_Pos_Table (Pos)) then
4323 Error_Msg_NE ("cannot be at the same position in the"
4324 & " vtable than&", Prim, Prim_Pos_Table (Pos));
4327 Prim_Pos_Table (Pos) := Prim;
4331 Next_Elmt (Prim_Elmt);
4335 -- Generate listing showing the contents of the dispatch tables
4337 if Debug_Flag_ZZ then
4341 -- For regular Ada tagged types, just set the DT_Position for
4342 -- each primitive operation. Perform some sanity checks to avoid
4343 -- to build completely inconsistant dispatch tables.
4345 -- Note that the _Size primitive is always set at position 1 in order
4346 -- to comply with the needs of Ada.Tags.Parent_Size (see documentation
4350 -- First stage: Set the DTC entity of all the primitive operations
4351 -- This is required to properly read the DT_Position attribute in
4352 -- the latter stages.
4354 Prim_Elmt := First_Prim;
4356 while Present (Prim_Elmt) loop
4357 Prim := Node (Prim_Elmt);
4359 -- Predefined primitives have a separate dispatch table
4361 if not (Is_Predefined_Dispatching_Operation (Prim)
4362 or else Is_Predefined_Dispatching_Alias (Prim))
4364 Count_Prim := Count_Prim + 1;
4367 -- Ada 2005 (AI-251)
4369 if Present (Abstract_Interface_Alias (Prim))
4370 and then Is_Interface
4371 (Find_Dispatching_Type
4372 (Abstract_Interface_Alias (Prim)))
4374 Set_DTC_Entity (Prim,
4377 Iface => Find_Dispatching_Type
4378 (Abstract_Interface_Alias (Prim))));
4380 Set_DTC_Entity (Prim, The_Tag);
4383 -- Clear any previous value of the DT_Position attribute. In this
4384 -- way we ensure that the final position of all the primitives is
4385 -- stablished by the following stages of this algorithm.
4387 Set_DT_Position (Prim, No_Uint);
4389 Next_Elmt (Prim_Elmt);
4393 Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean
4394 := (others => False);
4397 procedure Set_Fixed_Prim (Pos : Int);
4398 -- Sets to true an element of the Fixed_Prim table to indicate
4399 -- that this entry of the dispatch table of Typ is occupied.
4401 --------------------
4402 -- Set_Fixed_Prim --
4403 --------------------
4405 procedure Set_Fixed_Prim (Pos : Int) is
4407 pragma Assert (Pos >= 0 and then Pos <= Count_Prim);
4408 Fixed_Prim (Pos) := True;
4410 when Constraint_Error =>
4411 raise Program_Error;
4415 -- Second stage: Register fixed entries
4418 Prim_Elmt := First_Prim;
4419 while Present (Prim_Elmt) loop
4420 Prim := Node (Prim_Elmt);
4422 -- Predefined primitives have a separate table and all its
4423 -- entries are at predefined fixed positions.
4425 if Is_Predefined_Dispatching_Operation (Prim) then
4426 Set_DT_Position (Prim, Default_Prim_Op_Position (Prim));
4428 elsif Is_Predefined_Dispatching_Alias (Prim) then
4430 while Present (Alias (E)) loop
4434 Set_DT_Position (Prim, Default_Prim_Op_Position (E));
4436 -- Overriding primitives of ancestor abstract interfaces
4438 elsif Present (Abstract_Interface_Alias (Prim))
4439 and then Is_Ancestor
4440 (Find_Dispatching_Type
4441 (Abstract_Interface_Alias (Prim)),
4444 pragma Assert (DT_Position (Prim) = No_Uint
4445 and then Present (DTC_Entity
4446 (Abstract_Interface_Alias (Prim))));
4448 E := Abstract_Interface_Alias (Prim);
4449 Set_DT_Position (Prim, DT_Position (E));
4452 (DT_Position (Alias (Prim)) = No_Uint
4453 or else DT_Position (Alias (Prim)) = DT_Position (E));
4454 Set_DT_Position (Alias (Prim), DT_Position (E));
4455 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));
4457 -- Overriding primitives must use the same entry as the
4458 -- overriden primitive
4460 elsif not Present (Abstract_Interface_Alias (Prim))
4461 and then Present (Alias (Prim))
4462 and then Find_Dispatching_Type (Alias (Prim)) /= Typ
4463 and then Is_Ancestor
4464 (Find_Dispatching_Type (Alias (Prim)), Typ)
4465 and then Present (DTC_Entity (Alias (Prim)))
4468 Set_DT_Position (Prim, DT_Position (E));
4470 if not Is_Predefined_Dispatching_Alias (E) then
4471 Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
4475 Next_Elmt (Prim_Elmt);
4478 -- Third stage: Fix the position of all the new primitives
4479 -- Entries associated with primitives covering interfaces
4480 -- are handled in a latter round.
4482 Prim_Elmt := First_Prim;
4483 while Present (Prim_Elmt) loop
4484 Prim := Node (Prim_Elmt);
4486 -- Skip primitives previously set entries
4488 if DT_Position (Prim) /= No_Uint then
4491 -- Primitives covering interface primitives are handled later
4493 elsif Present (Abstract_Interface_Alias (Prim)) then
4497 -- Take the next available position in the DT
4500 Nb_Prim := Nb_Prim + 1;
4501 pragma Assert (Nb_Prim <= Count_Prim);
4502 exit when not Fixed_Prim (Nb_Prim);
4505 Set_DT_Position (Prim, UI_From_Int (Nb_Prim));
4506 Set_Fixed_Prim (Nb_Prim);
4509 Next_Elmt (Prim_Elmt);
4513 -- Fourth stage: Complete the decoration of primitives covering
4514 -- interfaces (that is, propagate the DT_Position attribute
4515 -- from the aliased primitive)
4517 Prim_Elmt := First_Prim;
4518 while Present (Prim_Elmt) loop
4519 Prim := Node (Prim_Elmt);
4521 if DT_Position (Prim) = No_Uint
4522 and then Present (Abstract_Interface_Alias (Prim))
4524 pragma Assert (Present (Alias (Prim))
4525 and then Find_Dispatching_Type (Alias (Prim)) = Typ);
4527 -- Check if this entry will be placed in the primary DT
4529 if Is_Ancestor (Find_Dispatching_Type
4530 (Abstract_Interface_Alias (Prim)),
4533 pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
4534 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
4536 -- Otherwise it will be placed in the secondary DT
4540 (DT_Position (Abstract_Interface_Alias (Prim)) /= No_Uint);
4541 Set_DT_Position (Prim,
4542 DT_Position (Abstract_Interface_Alias (Prim)));
4546 Next_Elmt (Prim_Elmt);
4549 -- Generate listing showing the contents of the dispatch tables.
4550 -- This action is done before some further static checks because
4551 -- in case of critical errors caused by a wrong dispatch table
4552 -- we need to see the contents of such table.
4554 if Debug_Flag_ZZ then
4558 -- Final stage: Ensure that the table is correct plus some further
4559 -- verifications concerning the primitives.
4561 Prim_Elmt := First_Prim;
4563 while Present (Prim_Elmt) loop
4564 Prim := Node (Prim_Elmt);
4566 -- At this point all the primitives MUST have a position
4567 -- in the dispatch table
4569 if DT_Position (Prim) = No_Uint then
4570 raise Program_Error;
4573 -- Calculate real size of the dispatch table
4575 if not (Is_Predefined_Dispatching_Operation (Prim)
4576 or else Is_Predefined_Dispatching_Alias (Prim))
4577 and then UI_To_Int (DT_Position (Prim)) > DT_Length
4579 DT_Length := UI_To_Int (DT_Position (Prim));
4582 -- Ensure that the asignated position to non-predefined
4583 -- dispatching operations in the dispatch table is correct.
4585 if not (Is_Predefined_Dispatching_Operation (Prim)
4586 or else Is_Predefined_Dispatching_Alias (Prim))
4588 Validate_Position (Prim);
4591 if Chars (Prim) = Name_Finalize then
4595 if Chars (Prim) = Name_Adjust then
4599 -- An abstract operation cannot be declared in the private part
4600 -- for a visible abstract type, because it could never be over-
4601 -- ridden. For explicit declarations this is checked at the
4602 -- point of declaration, but for inherited operations it must
4603 -- be done when building the dispatch table.
4605 -- Ada 2005 (AI-251): Hidden entities associated with abstract
4606 -- interface primitives are not taken into account because the
4607 -- check is done with the aliased primitive.
4609 if Is_Abstract (Typ)
4610 and then Is_Abstract (Prim)
4611 and then Present (Alias (Prim))
4612 and then not Present (Abstract_Interface_Alias (Prim))
4613 and then Is_Derived_Type (Typ)
4614 and then In_Private_Part (Current_Scope)
4616 List_Containing (Parent (Prim)) =
4617 Private_Declarations
4618 (Specification (Unit_Declaration_Node (Current_Scope)))
4619 and then Original_View_In_Visible_Part (Typ)
4621 -- We exclude Input and Output stream operations because
4622 -- Limited_Controlled inherits useless Input and Output
4623 -- stream operations from Root_Controlled, which can
4624 -- never be overridden.
4626 if not Is_TSS (Prim, TSS_Stream_Input)
4628 not Is_TSS (Prim, TSS_Stream_Output)
4631 ("abstract inherited private operation&" &
4632 " must be overridden ('R'M 3.9.3(10))",
4633 Parent (Typ), Prim);
4637 Next_Elmt (Prim_Elmt);
4642 if Is_Controlled (Typ) then
4643 if not Finalized then
4645 ("controlled type has no explicit Finalize method?", Typ);
4647 elsif not Adjusted then
4649 ("controlled type has no explicit Adjust method?", Typ);
4653 -- Set the final size of the Dispatch Table
4655 Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));
4657 -- The derived type must have at least as many components as its
4658 -- parent (for root types, the Etype points back to itself
4659 -- and the test should not fail)
4661 -- This test fails compiling the partial view of a tagged type
4662 -- derived from an interface which defines the overriding subprogram
4663 -- in the private part. This needs further investigation???
4665 if not Has_Private_Declaration (Typ) then
4667 DT_Entry_Count (The_Tag) >=
4668 DT_Entry_Count (First_Tag_Component (Parent_Typ)));
4672 end Set_All_DT_Position;
4674 -----------------------------
4675 -- Set_Default_Constructor --
4676 -----------------------------
4678 procedure Set_Default_Constructor (Typ : Entity_Id) is
4685 -- Look for the default constructor entity. For now only the
4686 -- default constructor has the flag Is_Constructor.
4688 E := Next_Entity (Typ);
4690 and then (Ekind (E) /= E_Function or else not Is_Constructor (E))
4695 -- Create the init procedure
4699 Init := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
4700 Param := Make_Defining_Identifier (Loc, Name_X);
4703 Make_Subprogram_Declaration (Loc,
4704 Make_Procedure_Specification (Loc,
4705 Defining_Unit_Name => Init,
4706 Parameter_Specifications => New_List (
4707 Make_Parameter_Specification (Loc,
4708 Defining_Identifier => Param,
4709 Parameter_Type => New_Reference_To (Typ, Loc))))));
4711 Set_Init_Proc (Typ, Init);
4712 Set_Is_Imported (Init);
4713 Set_Interface_Name (Init, Interface_Name (E));
4714 Set_Convention (Init, Convention_C);
4715 Set_Is_Public (Init);
4716 Set_Has_Completion (Init);
4718 -- If there are no constructors, mark the type as abstract since we
4719 -- won't be able to declare objects of that type.
4722 Set_Is_Abstract (Typ);
4724 end Set_Default_Constructor;
4730 function Tagged_Kind (T : Entity_Id) return Node_Id is
4731 Conc_Typ : Entity_Id;
4732 Loc : constant Source_Ptr := Sloc (T);
4736 (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));
4740 if Is_Abstract (T) then
4741 if Is_Limited_Record (T) then
4742 return New_Reference_To (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
4744 return New_Reference_To (RTE (RE_TK_Abstract_Tagged), Loc);
4749 elsif Is_Concurrent_Record_Type (T) then
4750 Conc_Typ := Corresponding_Concurrent_Type (T);
4752 if Ekind (Conc_Typ) = E_Protected_Type then
4753 return New_Reference_To (RTE (RE_TK_Protected), Loc);
4755 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
4756 return New_Reference_To (RTE (RE_TK_Task), Loc);
4759 -- Regular tagged kinds
4762 if Is_Limited_Record (T) then
4763 return New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc);
4765 return New_Reference_To (RTE (RE_TK_Tagged), Loc);
4774 procedure Write_DT (Typ : Entity_Id) is
4779 -- Protect this procedure against wrong usage. Required because it will
4780 -- be used directly from GDB
4782 if not (Typ in First_Node_Id .. Last_Node_Id)
4783 or else not Is_Tagged_Type (Typ)
4785 Write_Str ("wrong usage: Write_DT must be used with tagged types");
4790 Write_Int (Int (Typ));
4792 Write_Name (Chars (Typ));
4794 if Is_Interface (Typ) then
4795 Write_Str (" is interface");
4800 Elmt := First_Elmt (Primitive_Operations (Typ));
4801 while Present (Elmt) loop
4802 Prim := Node (Elmt);
4805 -- Indicate if this primitive will be allocated in the primary
4806 -- dispatch table or in a secondary dispatch table associated
4807 -- with an abstract interface type
4809 if Present (DTC_Entity (Prim)) then
4810 if Etype (DTC_Entity (Prim)) = RTE (RE_Tag) then
4817 -- Output the node of this primitive operation and its name
4819 Write_Int (Int (Prim));
4822 if Is_Predefined_Dispatching_Operation (Prim) then
4823 Write_Str ("(predefined) ");
4826 Write_Name (Chars (Prim));
4828 -- Indicate if this primitive has an aliased primitive
4830 if Present (Alias (Prim)) then
4831 Write_Str (" (alias = ");
4832 Write_Int (Int (Alias (Prim)));
4834 -- If the DTC_Entity attribute is already set we can also output
4835 -- the name of the interface covered by this primitive (if any)
4837 if Present (DTC_Entity (Alias (Prim)))
4838 and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
4840 Write_Str (" from interface ");
4841 Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
4844 if Present (Abstract_Interface_Alias (Prim)) then
4845 Write_Str (", AI_Alias of ");
4846 Write_Name (Chars (Scope (DTC_Entity
4847 (Abstract_Interface_Alias (Prim)))));
4849 Write_Int (Int (Abstract_Interface_Alias (Prim)));
4855 -- Display the final position of this primitive in its associated
4856 -- (primary or secondary) dispatch table
4858 if Present (DTC_Entity (Prim))
4859 and then DT_Position (Prim) /= No_Uint
4861 Write_Str (" at #");
4862 Write_Int (UI_To_Int (DT_Position (Prim)));
4865 if Is_Abstract (Prim) then
4866 Write_Str (" is abstract;");
4868 -- Check if this is a null primitive
4870 elsif Comes_From_Source (Prim)
4871 and then Ekind (Prim) = E_Procedure
4872 and then Null_Present (Parent (Prim))
4874 Write_Str (" is null;");