1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2005, 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 Itypes
; use Itypes
;
38 with Nlists
; use Nlists
;
39 with Nmake
; use Nmake
;
40 with Namet
; use Namet
;
42 with Output
; use Output
;
43 with Rtsfind
; use Rtsfind
;
45 with Sem_Disp
; use Sem_Disp
;
46 with Sem_Res
; use Sem_Res
;
47 with Sem_Type
; use Sem_Type
;
48 with Sem_Util
; use Sem_Util
;
49 with Sinfo
; use Sinfo
;
50 with Snames
; use Snames
;
51 with Stand
; use Stand
;
52 with Tbuild
; use Tbuild
;
53 with Uintp
; use Uintp
;
55 package body Exp_Disp
is
57 --------------------------------
58 -- Select_Expansion_Utilities --
59 --------------------------------
61 -- The following package contains helper routines used in the expansion of
62 -- dispatching asynchronous, conditional and timed selects.
64 package Select_Expansion_Utilities
is
69 -- B : out Communication_Block
75 -- C : out Prim_Op_Kind
77 procedure Build_Common_Dispatching_Select_Statements
82 -- Ada 2005 (AI-345): Generate statements that are common between
83 -- asynchronous, conditional and timed select expansion.
109 end Select_Expansion_Utilities
;
111 package body Select_Expansion_Utilities
is
123 Make_Parameter_Specification
(Loc
,
124 Defining_Identifier
=>
125 Make_Defining_Identifier
(Loc
, Name_uB
),
127 New_Reference_To
(RTE
(RE_Communication_Block
), Loc
),
128 Out_Present
=> True));
141 Make_Parameter_Specification
(Loc
,
142 Defining_Identifier
=>
143 Make_Defining_Identifier
(Loc
, Name_uC
),
145 New_Reference_To
(RTE
(RE_Prim_Op_Kind
), Loc
),
146 Out_Present
=> True));
149 ------------------------------------------------
150 -- Build_Common_Dispatching_Select_Statements --
151 ------------------------------------------------
153 procedure Build_Common_Dispatching_Select_Statements
161 -- C := get_prim_op_kind (tag! (<type>VP), S);
163 -- where C is the out parameter capturing the call kind and S is the
164 -- dispatch table slot number.
167 Make_Assignment_Statement
(Loc
,
169 Make_Identifier
(Loc
, Name_uC
),
171 Make_DT_Access_Action
(Typ
,
176 Unchecked_Convert_To
(RTE
(RE_Tag
),
177 New_Reference_To
(DT_Ptr
, Loc
)),
178 Make_Identifier
(Loc
, Name_uS
)))));
182 -- if C = POK_Procedure
183 -- or else C = POK_Protected_Procedure
184 -- or else C = POK_Task_Procedure;
189 -- where F is the out parameter capturing the status of a potential
193 Make_If_Statement
(Loc
,
200 Make_Identifier
(Loc
, Name_uC
),
202 New_Reference_To
(RTE
(RE_POK_Procedure
), Loc
)),
208 Make_Identifier
(Loc
, Name_uC
),
210 New_Reference_To
(RTE
(
211 RE_POK_Protected_Procedure
), Loc
)),
215 Make_Identifier
(Loc
, Name_uC
),
217 New_Reference_To
(RTE
(
218 RE_POK_Task_Procedure
), Loc
)))),
222 Make_Assignment_Statement
(Loc
,
223 Name
=> Make_Identifier
(Loc
, Name_uF
),
224 Expression
=> New_Reference_To
(Standard_True
, Loc
)),
226 Make_Return_Statement
(Loc
))));
227 end Build_Common_Dispatching_Select_Statements
;
239 Make_Parameter_Specification
(Loc
,
240 Defining_Identifier
=>
241 Make_Defining_Identifier
(Loc
, Name_uF
),
243 New_Reference_To
(Standard_Boolean
, Loc
),
244 Out_Present
=> True));
257 Make_Parameter_Specification
(Loc
,
258 Defining_Identifier
=>
259 Make_Defining_Identifier
(Loc
, Name_uP
),
261 New_Reference_To
(RTE
(RE_Address
), Loc
)));
274 Make_Parameter_Specification
(Loc
,
275 Defining_Identifier
=>
276 Make_Defining_Identifier
(Loc
, Name_uS
),
278 New_Reference_To
(Standard_Integer
, Loc
)));
292 Make_Parameter_Specification
(Loc
,
293 Defining_Identifier
=>
294 Make_Defining_Identifier
(Loc
, Name_uT
),
296 New_Reference_To
(Typ
, Loc
),
298 Out_Present
=> True));
300 end Select_Expansion_Utilities
;
302 package SEU
renames Select_Expansion_Utilities
;
304 Ada_Actions
: constant array (DT_Access_Action
) of RE_Id
:=
305 (CW_Membership
=> RE_CW_Membership
,
306 IW_Membership
=> RE_IW_Membership
,
307 DT_Entry_Size
=> RE_DT_Entry_Size
,
308 DT_Prologue_Size
=> RE_DT_Prologue_Size
,
309 Get_Access_Level
=> RE_Get_Access_Level
,
310 Get_Entry_Index
=> RE_Get_Entry_Index
,
311 Get_External_Tag
=> RE_Get_External_Tag
,
312 Get_Prim_Op_Address
=> RE_Get_Prim_Op_Address
,
313 Get_Prim_Op_Kind
=> RE_Get_Prim_Op_Kind
,
314 Get_RC_Offset
=> RE_Get_RC_Offset
,
315 Get_Remotely_Callable
=> RE_Get_Remotely_Callable
,
316 Get_Tagged_Kind
=> RE_Get_Tagged_Kind
,
317 Inherit_DT
=> RE_Inherit_DT
,
318 Inherit_TSD
=> RE_Inherit_TSD
,
319 Register_Interface_Tag
=> RE_Register_Interface_Tag
,
320 Register_Tag
=> RE_Register_Tag
,
321 Set_Access_Level
=> RE_Set_Access_Level
,
322 Set_Entry_Index
=> RE_Set_Entry_Index
,
323 Set_Expanded_Name
=> RE_Set_Expanded_Name
,
324 Set_External_Tag
=> RE_Set_External_Tag
,
325 Set_Interface_Table
=> RE_Set_Interface_Table
,
326 Set_Offset_Index
=> RE_Set_Offset_Index
,
327 Set_OSD
=> RE_Set_OSD
,
328 Set_Prim_Op_Address
=> RE_Set_Prim_Op_Address
,
329 Set_Prim_Op_Kind
=> RE_Set_Prim_Op_Kind
,
330 Set_RC_Offset
=> RE_Set_RC_Offset
,
331 Set_Remotely_Callable
=> RE_Set_Remotely_Callable
,
332 Set_SSD
=> RE_Set_SSD
,
333 Set_TSD
=> RE_Set_TSD
,
334 Set_Tagged_Kind
=> RE_Set_Tagged_Kind
,
335 TSD_Entry_Size
=> RE_TSD_Entry_Size
,
336 TSD_Prologue_Size
=> RE_TSD_Prologue_Size
);
338 Action_Is_Proc
: constant array (DT_Access_Action
) of Boolean :=
339 (CW_Membership
=> False,
340 IW_Membership
=> False,
341 DT_Entry_Size
=> False,
342 DT_Prologue_Size
=> False,
343 Get_Access_Level
=> False,
344 Get_Entry_Index
=> False,
345 Get_External_Tag
=> False,
346 Get_Prim_Op_Address
=> False,
347 Get_Prim_Op_Kind
=> False,
348 Get_RC_Offset
=> False,
349 Get_Remotely_Callable
=> False,
350 Get_Tagged_Kind
=> False,
353 Register_Interface_Tag
=> True,
354 Register_Tag
=> True,
355 Set_Access_Level
=> True,
356 Set_Entry_Index
=> True,
357 Set_Expanded_Name
=> True,
358 Set_External_Tag
=> True,
359 Set_Interface_Table
=> True,
360 Set_Offset_Index
=> True,
362 Set_Prim_Op_Address
=> True,
363 Set_Prim_Op_Kind
=> True,
364 Set_RC_Offset
=> True,
365 Set_Remotely_Callable
=> True,
368 Set_Tagged_Kind
=> True,
369 TSD_Entry_Size
=> False,
370 TSD_Prologue_Size
=> False);
372 Action_Nb_Arg
: constant array (DT_Access_Action
) of Int
:=
376 DT_Prologue_Size
=> 0,
377 Get_Access_Level
=> 1,
378 Get_Entry_Index
=> 2,
379 Get_External_Tag
=> 1,
380 Get_Prim_Op_Address
=> 2,
381 Get_Prim_Op_Kind
=> 2,
383 Get_Remotely_Callable
=> 1,
384 Get_Tagged_Kind
=> 1,
387 Register_Interface_Tag
=> 3,
389 Set_Access_Level
=> 2,
390 Set_Entry_Index
=> 3,
391 Set_Expanded_Name
=> 2,
392 Set_External_Tag
=> 2,
393 Set_Interface_Table
=> 2,
394 Set_Offset_Index
=> 3,
396 Set_Prim_Op_Address
=> 3,
397 Set_Prim_Op_Kind
=> 3,
399 Set_Remotely_Callable
=> 2,
402 Set_Tagged_Kind
=> 2,
404 TSD_Prologue_Size
=> 0);
406 procedure Collect_All_Interfaces
(T
: Entity_Id
);
407 -- Ada 2005 (AI-251): Collect the whole list of interfaces that are
408 -- directly or indirectly implemented by T. Used to compute the size
409 -- of the table of interfaces.
411 function Default_Prim_Op_Position
(Subp
: Entity_Id
) return Uint
;
412 -- Ada 2005 (AI-251): Returns the fixed position in the dispatch table
413 -- of the default primitive operations.
415 function Original_View_In_Visible_Part
(Typ
: Entity_Id
) return Boolean;
416 -- Check if the type has a private view or if the public view appears
417 -- in the visible part of a package spec.
419 function Prim_Op_Kind
421 Typ
: Entity_Id
) return Node_Id
;
422 -- Ada 2005 (AI-345): Determine the primitive operation kind of Prim
423 -- according to its type Typ. Return a reference to an RE_Prim_Op_Kind
424 -- enumeration value.
426 function Tagged_Kind
(T
: Entity_Id
) return Node_Id
;
427 -- Ada 2005 (AI-345): Determine the tagged kind of T and return a reference
428 -- to an RE_Tagged_Kind enumeration value.
430 ----------------------------
431 -- Collect_All_Interfaces --
432 ----------------------------
434 procedure Collect_All_Interfaces
(T
: Entity_Id
) is
436 procedure Add_Interface
(Iface
: Entity_Id
);
437 -- Add the interface it if is not already in the list
439 procedure Collect
(Typ
: Entity_Id
);
440 -- Subsidiary subprogram used to traverse the whole list
441 -- of directly and indirectly implemented interfaces
447 procedure Add_Interface
(Iface
: Entity_Id
) is
451 Elmt
:= First_Elmt
(Abstract_Interfaces
(T
));
452 while Present
(Elmt
) and then Node
(Elmt
) /= Iface
loop
456 if not Present
(Elmt
) then
457 Append_Elmt
(Iface
, Abstract_Interfaces
(T
));
465 procedure Collect
(Typ
: Entity_Id
) is
466 Ancestor
: Entity_Id
;
472 if Ekind
(Typ
) = E_Record_Type_With_Private
then
473 Nod
:= Type_Definition
(Parent
(Full_View
(Typ
)));
475 Nod
:= Type_Definition
(Parent
(Typ
));
479 or else Nkind
(Nod
) = N_Derived_Type_Definition
480 or else Nkind
(Nod
) = N_Record_Definition
);
482 -- Include the ancestor if we are generating the whole list
483 -- of interfaces. This is used to know the size of the table
484 -- that stores the tag of all the ancestor interfaces.
486 Ancestor
:= Etype
(Typ
);
488 if Ancestor
/= Typ
then
492 if Is_Interface
(Ancestor
) then
493 Add_Interface
(Ancestor
);
496 -- Traverse the graph of ancestor interfaces
498 if Is_Non_Empty_List
(Interface_List
(Nod
)) then
499 Id
:= First
(Interface_List
(Nod
));
500 while Present
(Id
) loop
503 if Is_Interface
(Iface
) then
504 Add_Interface
(Iface
);
513 -- Start of processing for Collect_All_Interfaces
517 end Collect_All_Interfaces
;
519 ------------------------------
520 -- Default_Prim_Op_Position --
521 ------------------------------
523 function Default_Prim_Op_Position
(Subp
: Entity_Id
) return Uint
is
524 TSS_Name
: TSS_Name_Type
;
525 E
: Entity_Id
:= Subp
;
528 -- Handle overriden subprograms
530 while Present
(Alias
(E
)) loop
534 Get_Name_String
(Chars
(E
));
537 (Name_Buffer
(Name_Len
- TSS_Name
'Length + 1 .. Name_Len
));
539 if Chars
(E
) = Name_uSize
then
542 elsif Chars
(E
) = Name_uAlignment
then
545 elsif TSS_Name
= TSS_Stream_Read
then
548 elsif TSS_Name
= TSS_Stream_Write
then
551 elsif TSS_Name
= TSS_Stream_Input
then
554 elsif TSS_Name
= TSS_Stream_Output
then
557 elsif Chars
(E
) = Name_Op_Eq
then
560 elsif Chars
(E
) = Name_uAssign
then
563 elsif TSS_Name
= TSS_Deep_Adjust
then
566 elsif TSS_Name
= TSS_Deep_Finalize
then
569 elsif Ada_Version
>= Ada_05
then
570 if Chars
(E
) = Name_uDisp_Asynchronous_Select
then
573 elsif Chars
(E
) = Name_uDisp_Conditional_Select
then
576 elsif Chars
(E
) = Name_uDisp_Get_Prim_Op_Kind
then
579 elsif Chars
(E
) = Name_uDisp_Get_Task_Id
then
582 elsif Chars
(E
) = Name_uDisp_Timed_Select
then
588 end Default_Prim_Op_Position
;
590 -----------------------------
591 -- Expand_Dispatching_Call --
592 -----------------------------
594 procedure Expand_Dispatching_Call
(Call_Node
: Node_Id
) is
595 Loc
: constant Source_Ptr
:= Sloc
(Call_Node
);
596 Call_Typ
: constant Entity_Id
:= Etype
(Call_Node
);
598 Ctrl_Arg
: constant Node_Id
:= Controlling_Argument
(Call_Node
);
599 Param_List
: constant List_Id
:= Parameter_Associations
(Call_Node
);
600 Subp
: Entity_Id
:= Entity
(Name
(Call_Node
));
604 New_Call_Name
: Node_Id
;
605 New_Params
: List_Id
:= No_List
;
608 Subp_Ptr_Typ
: Entity_Id
;
609 Subp_Typ
: Entity_Id
;
611 Eq_Prim_Op
: Entity_Id
:= Empty
;
612 Controlling_Tag
: Node_Id
;
614 function New_Value
(From
: Node_Id
) return Node_Id
;
615 -- From is the original Expression. New_Value is equivalent to a call
616 -- to Duplicate_Subexpr with an explicit dereference when From is an
619 function Controlling_Type
(Subp
: Entity_Id
) return Entity_Id
;
620 -- Returns the tagged type for which Subp is a primitive subprogram
626 function New_Value
(From
: Node_Id
) return Node_Id
is
627 Res
: constant Node_Id
:= Duplicate_Subexpr
(From
);
629 if Is_Access_Type
(Etype
(From
)) then
630 return Make_Explicit_Dereference
(Sloc
(From
), Res
);
636 ----------------------
637 -- Controlling_Type --
638 ----------------------
640 function Controlling_Type
(Subp
: Entity_Id
) return Entity_Id
is
642 if Ekind
(Subp
) = E_Function
643 and then Has_Controlling_Result
(Subp
)
645 return Base_Type
(Etype
(Subp
));
652 Formal
:= First_Formal
(Subp
);
653 while Present
(Formal
) loop
654 if Is_Controlling_Formal
(Formal
) then
655 if Is_Access_Type
(Etype
(Formal
)) then
656 return Base_Type
(Designated_Type
(Etype
(Formal
)));
658 return Base_Type
(Etype
(Formal
));
662 Next_Formal
(Formal
);
667 -- Controlling type not found (should never happen)
670 end Controlling_Type
;
672 -- Start of processing for Expand_Dispatching_Call
675 -- If this is an inherited operation that was overridden, the body
676 -- that is being called is its alias.
678 if Present
(Alias
(Subp
))
679 and then Is_Inherited_Operation
(Subp
)
680 and then No
(DTC_Entity
(Subp
))
682 Subp
:= Alias
(Subp
);
685 -- Expand_Dispatching_Call is called directly from the semantics,
686 -- so we need a check to see whether expansion is active before
689 if not Expander_Active
then
693 -- Definition of the class-wide type and the tagged type
695 -- If the controlling argument is itself a tag rather than a tagged
696 -- object, then use the class-wide type associated with the subprogram's
697 -- controlling type. This case can occur when a call to an inherited
698 -- primitive has an actual that originated from a default parameter
699 -- given by a tag-indeterminate call and when there is no other
700 -- controlling argument providing the tag (AI-239 requires dispatching).
701 -- This capability of dispatching directly by tag is also needed by the
702 -- implementation of AI-260 (for the generic dispatching constructors).
704 if Etype
(Ctrl_Arg
) = RTE
(RE_Tag
)
705 or else Etype
(Ctrl_Arg
) = RTE
(RE_Interface_Tag
)
707 CW_Typ
:= Class_Wide_Type
(Controlling_Type
(Subp
));
709 elsif Is_Access_Type
(Etype
(Ctrl_Arg
)) then
710 CW_Typ
:= Designated_Type
(Etype
(Ctrl_Arg
));
713 CW_Typ
:= Etype
(Ctrl_Arg
);
716 Typ
:= Root_Type
(CW_Typ
);
718 if Ekind
(Typ
) = E_Incomplete_Type
then
719 Typ
:= Non_Limited_View
(Typ
);
722 if not Is_Limited_Type
(Typ
) then
723 Eq_Prim_Op
:= Find_Prim_Op
(Typ
, Name_Op_Eq
);
726 if Is_CPP_Class
(Root_Type
(Typ
)) then
728 -- Create a new parameter list with the displaced 'this'
730 New_Params
:= New_List
;
731 Param
:= First_Actual
(Call_Node
);
732 while Present
(Param
) loop
733 Append_To
(New_Params
, Relocate_Node
(Param
));
737 elsif Present
(Param_List
) then
739 -- Generate the Tag checks when appropriate
741 New_Params
:= New_List
;
743 Param
:= First_Actual
(Call_Node
);
744 while Present
(Param
) loop
746 -- No tag check with itself
748 if Param
= Ctrl_Arg
then
749 Append_To
(New_Params
,
750 Duplicate_Subexpr_Move_Checks
(Param
));
752 -- No tag check for parameter whose type is neither tagged nor
753 -- access to tagged (for access parameters)
755 elsif No
(Find_Controlling_Arg
(Param
)) then
756 Append_To
(New_Params
, Relocate_Node
(Param
));
758 -- No tag check for function dispatching on result if the
759 -- Tag given by the context is this one
761 elsif Find_Controlling_Arg
(Param
) = Ctrl_Arg
then
762 Append_To
(New_Params
, Relocate_Node
(Param
));
764 -- "=" is the only dispatching operation allowed to get
765 -- operands with incompatible tags (it just returns false).
766 -- We use Duplicate_Subexpr_Move_Checks instead of calling
767 -- Relocate_Node because the value will be duplicated to
770 elsif Subp
= Eq_Prim_Op
then
771 Append_To
(New_Params
,
772 Duplicate_Subexpr_Move_Checks
(Param
));
774 -- No check in presence of suppress flags
776 elsif Tag_Checks_Suppressed
(Etype
(Param
))
777 or else (Is_Access_Type
(Etype
(Param
))
778 and then Tag_Checks_Suppressed
779 (Designated_Type
(Etype
(Param
))))
781 Append_To
(New_Params
, Relocate_Node
(Param
));
783 -- Optimization: no tag checks if the parameters are identical
785 elsif Is_Entity_Name
(Param
)
786 and then Is_Entity_Name
(Ctrl_Arg
)
787 and then Entity
(Param
) = Entity
(Ctrl_Arg
)
789 Append_To
(New_Params
, Relocate_Node
(Param
));
791 -- Now we need to generate the Tag check
794 -- Generate code for tag equality check
795 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
797 Insert_Action
(Ctrl_Arg
,
798 Make_Implicit_If_Statement
(Call_Node
,
802 Make_Selected_Component
(Loc
,
803 Prefix
=> New_Value
(Ctrl_Arg
),
806 (First_Tag_Component
(Typ
), Loc
)),
809 Make_Selected_Component
(Loc
,
811 Unchecked_Convert_To
(Typ
, New_Value
(Param
)),
814 (First_Tag_Component
(Typ
), Loc
))),
817 New_List
(New_Constraint_Error
(Loc
))));
819 Append_To
(New_Params
, Relocate_Node
(Param
));
826 -- Generate the appropriate subprogram pointer type
828 if Etype
(Subp
) = Typ
then
831 Res_Typ
:= Etype
(Subp
);
834 Subp_Typ
:= Create_Itype
(E_Subprogram_Type
, Call_Node
);
835 Subp_Ptr_Typ
:= Create_Itype
(E_Access_Subprogram_Type
, Call_Node
);
836 Set_Etype
(Subp_Typ
, Res_Typ
);
837 Init_Size_Align
(Subp_Ptr_Typ
);
838 Set_Returns_By_Ref
(Subp_Typ
, Returns_By_Ref
(Subp
));
840 -- Create a new list of parameters which is a copy of the old formal
841 -- list including the creation of a new set of matching entities.
844 Old_Formal
: Entity_Id
:= First_Formal
(Subp
);
845 New_Formal
: Entity_Id
;
849 if Present
(Old_Formal
) then
850 New_Formal
:= New_Copy
(Old_Formal
);
851 Set_First_Entity
(Subp_Typ
, New_Formal
);
852 Param
:= First_Actual
(Call_Node
);
855 Set_Scope
(New_Formal
, Subp_Typ
);
857 -- Change all the controlling argument types to be class-wide
858 -- to avoid a recursion in dispatching.
860 if Is_Controlling_Formal
(New_Formal
) then
861 Set_Etype
(New_Formal
, Etype
(Param
));
864 if Is_Itype
(Etype
(New_Formal
)) then
865 Extra
:= New_Copy
(Etype
(New_Formal
));
867 if Ekind
(Extra
) = E_Record_Subtype
868 or else Ekind
(Extra
) = E_Class_Wide_Subtype
870 Set_Cloned_Subtype
(Extra
, Etype
(New_Formal
));
873 Set_Etype
(New_Formal
, Extra
);
874 Set_Scope
(Etype
(New_Formal
), Subp_Typ
);
878 Next_Formal
(Old_Formal
);
879 exit when No
(Old_Formal
);
881 Set_Next_Entity
(New_Formal
, New_Copy
(Old_Formal
));
882 Next_Entity
(New_Formal
);
885 Set_Last_Entity
(Subp_Typ
, Extra
);
887 -- Copy extra formals
889 New_Formal
:= First_Entity
(Subp_Typ
);
890 while Present
(New_Formal
) loop
891 if Present
(Extra_Constrained
(New_Formal
)) then
892 Set_Extra_Formal
(Extra
,
893 New_Copy
(Extra_Constrained
(New_Formal
)));
894 Extra
:= Extra_Formal
(Extra
);
895 Set_Extra_Constrained
(New_Formal
, Extra
);
897 elsif Present
(Extra_Accessibility
(New_Formal
)) then
898 Set_Extra_Formal
(Extra
,
899 New_Copy
(Extra_Accessibility
(New_Formal
)));
900 Extra
:= Extra_Formal
(Extra
);
901 Set_Extra_Accessibility
(New_Formal
, Extra
);
904 Next_Formal
(New_Formal
);
909 Set_Etype
(Subp_Ptr_Typ
, Subp_Ptr_Typ
);
910 Set_Directly_Designated_Type
(Subp_Ptr_Typ
, Subp_Typ
);
912 -- If the controlling argument is a value of type Ada.Tag then
913 -- use it directly. Otherwise, the tag must be extracted from
914 -- the controlling object.
916 if Etype
(Ctrl_Arg
) = RTE
(RE_Tag
)
917 or else Etype
(Ctrl_Arg
) = RTE
(RE_Interface_Tag
)
919 Controlling_Tag
:= Duplicate_Subexpr
(Ctrl_Arg
);
923 Make_Selected_Component
(Loc
,
924 Prefix
=> Duplicate_Subexpr_Move_Checks
(Ctrl_Arg
),
925 Selector_Name
=> New_Reference_To
(DTC_Entity
(Subp
), Loc
));
929 -- Subp_Ptr_Typ!(Get_Prim_Op_Address (Ctrl._Tag, pos));
932 Unchecked_Convert_To
(Subp_Ptr_Typ
,
933 Make_DT_Access_Action
(Typ
,
934 Action
=> Get_Prim_Op_Address
,
943 Make_Integer_Literal
(Loc
, DT_Position
(Subp
)))));
945 if Nkind
(Call_Node
) = N_Function_Call
then
947 -- Ada 2005 (AI-251): A dispatching "=" with an abstract interface
948 -- just requires the comparison of the tags.
950 if Ekind
(Etype
(Ctrl_Arg
)) = E_Class_Wide_Type
951 and then Is_Interface
(Etype
(Ctrl_Arg
))
952 and then Subp
= Eq_Prim_Op
954 Param
:= First_Actual
(Call_Node
);
959 Make_Selected_Component
(Loc
,
960 Prefix
=> New_Value
(Param
),
962 New_Reference_To
(First_Tag_Component
(Typ
), Loc
)),
965 Make_Selected_Component
(Loc
,
967 Unchecked_Convert_To
(Typ
,
968 New_Value
(Next_Actual
(Param
))),
970 New_Reference_To
(First_Tag_Component
(Typ
), Loc
)));
974 Make_Function_Call
(Loc
,
975 Name
=> New_Call_Name
,
976 Parameter_Associations
=> New_Params
);
978 -- If this is a dispatching "=", we must first compare the tags so
979 -- we generate: x.tag = y.tag and then x = y
981 if Subp
= Eq_Prim_Op
then
982 Param
:= First_Actual
(Call_Node
);
988 Make_Selected_Component
(Loc
,
989 Prefix
=> New_Value
(Param
),
991 New_Reference_To
(First_Tag_Component
(Typ
),
995 Make_Selected_Component
(Loc
,
997 Unchecked_Convert_To
(Typ
,
998 New_Value
(Next_Actual
(Param
))),
1000 New_Reference_To
(First_Tag_Component
(Typ
),
1002 Right_Opnd
=> New_Call
);
1008 Make_Procedure_Call_Statement
(Loc
,
1009 Name
=> New_Call_Name
,
1010 Parameter_Associations
=> New_Params
);
1013 Rewrite
(Call_Node
, New_Call
);
1014 Analyze_And_Resolve
(Call_Node
, Call_Typ
);
1015 end Expand_Dispatching_Call
;
1017 ---------------------------------
1018 -- Expand_Interface_Conversion --
1019 ---------------------------------
1021 procedure Expand_Interface_Conversion
1023 Is_Static
: Boolean := True)
1025 Loc
: constant Source_Ptr
:= Sloc
(N
);
1026 Operand
: constant Node_Id
:= Expression
(N
);
1027 Operand_Typ
: Entity_Id
:= Etype
(Operand
);
1028 Iface_Typ
: Entity_Id
:= Etype
(N
);
1029 Iface_Tag
: Entity_Id
;
1033 Null_Op_Nod
: Node_Id
;
1036 pragma Assert
(Nkind
(Operand
) /= N_Attribute_Reference
);
1038 -- Ada 2005 (AI-345): Handle task interfaces
1040 if Ekind
(Operand_Typ
) = E_Task_Type
1041 or else Ekind
(Operand_Typ
) = E_Protected_Type
1043 Operand_Typ
:= Corresponding_Record_Type
(Operand_Typ
);
1046 -- Handle access types to interfaces
1048 if Is_Access_Type
(Iface_Typ
) then
1049 Iface_Typ
:= Etype
(Directly_Designated_Type
(Iface_Typ
));
1052 -- Handle class-wide interface types. This conversion can appear
1053 -- explicitly in the source code. Example: I'Class (Obj)
1055 if Is_Class_Wide_Type
(Iface_Typ
) then
1056 Iface_Typ
:= Etype
(Iface_Typ
);
1059 pragma Assert
(not Is_Class_Wide_Type
(Iface_Typ
)
1060 and then Is_Interface
(Iface_Typ
));
1062 if not Is_Static
then
1064 Make_Function_Call
(Loc
,
1065 Name
=> New_Reference_To
(RTE
(RE_Displace
), Loc
),
1066 Parameter_Associations
=> New_List
(
1067 Make_Attribute_Reference
(Loc
,
1068 Prefix
=> Relocate_Node
(Expression
(N
)),
1069 Attribute_Name
=> Name_Address
),
1071 (Node
(First_Elmt
(Access_Disp_Table
(Iface_Typ
))),
1076 -- Change the type of the data returned by IW_Convert to
1077 -- indicate that this is a dispatching call.
1080 New_Itype
: Entity_Id
;
1083 New_Itype
:= Create_Itype
(E_Anonymous_Access_Type
, N
);
1084 Set_Etype
(New_Itype
, New_Itype
);
1085 Init_Size_Align
(New_Itype
);
1086 Set_Directly_Designated_Type
(New_Itype
,
1087 Class_Wide_Type
(Iface_Typ
));
1089 Rewrite
(N
, Unchecked_Convert_To
(New_Itype
,
1090 Relocate_Node
(N
)));
1096 Iface_Tag
:= Find_Interface_Tag
(Operand_Typ
, Iface_Typ
);
1097 pragma Assert
(Iface_Tag
/= Empty
);
1099 -- Keep separate access types to interfaces because one internal
1100 -- function is used to handle the null value (see following comment)
1102 if not Is_Access_Type
(Etype
(N
)) then
1104 Unchecked_Convert_To
(Etype
(N
),
1105 Make_Selected_Component
(Loc
,
1106 Prefix
=> Relocate_Node
(Expression
(N
)),
1108 New_Occurrence_Of
(Iface_Tag
, Loc
))));
1111 -- Build internal function to handle the case in which the
1112 -- actual is null. If the actual is null returns null because
1113 -- no displacement is required; otherwise performs a type
1114 -- conversion that will be expanded in the code that returns
1115 -- the value of the displaced actual. That is:
1117 -- function Func (O : Operand_Typ) return Iface_Typ is
1122 -- return Iface_Typ!(O);
1127 Make_Defining_Identifier
(Loc
, New_Internal_Name
('F'));
1129 -- Decorate the "null" in the if-statement condition
1131 Null_Op_Nod
:= Make_Null
(Loc
);
1132 Set_Etype
(Null_Op_Nod
, Etype
(Operand
));
1133 Set_Analyzed
(Null_Op_Nod
);
1136 Make_Subprogram_Body
(Loc
,
1138 Make_Function_Specification
(Loc
,
1139 Defining_Unit_Name
=> Fent
,
1141 Parameter_Specifications
=> New_List
(
1142 Make_Parameter_Specification
(Loc
,
1143 Defining_Identifier
=>
1144 Make_Defining_Identifier
(Loc
, Name_uO
),
1146 New_Reference_To
(Etype
(Operand
), Loc
))),
1147 Result_Definition
=>
1148 New_Reference_To
(Etype
(N
), Loc
)),
1150 Declarations
=> Empty_List
,
1152 Handled_Statement_Sequence
=>
1153 Make_Handled_Sequence_Of_Statements
(Loc
,
1154 Statements
=> New_List
(
1155 Make_If_Statement
(Loc
,
1158 Left_Opnd
=> Make_Identifier
(Loc
, Name_uO
),
1159 Right_Opnd
=> Null_Op_Nod
),
1160 Then_Statements
=> New_List
(
1161 Make_Return_Statement
(Loc
,
1163 Else_Statements
=> New_List
(
1164 Make_Return_Statement
(Loc
,
1165 Unchecked_Convert_To
(Etype
(N
),
1166 Make_Attribute_Reference
(Loc
,
1168 Make_Selected_Component
(Loc
,
1169 Prefix
=> Relocate_Node
(Expression
(N
)),
1171 New_Occurrence_Of
(Iface_Tag
, Loc
)),
1172 Attribute_Name
=> Name_Address
))))))));
1174 -- Insert the new declaration in the nearest enclosing scope
1175 -- that has declarations.
1178 while not Has_Declarations
(Parent
(P
)) loop
1182 if Is_List_Member
(P
) then
1183 Insert_Before
(P
, Func
);
1185 elsif Nkind
(Parent
(P
)) = N_Package_Specification
then
1186 Append_To
(Visible_Declarations
(Parent
(P
)), Func
);
1189 Append_To
(Declarations
(Parent
(P
)), Func
);
1195 Make_Function_Call
(Loc
,
1196 Name
=> New_Reference_To
(Fent
, Loc
),
1197 Parameter_Associations
=> New_List
(
1198 Relocate_Node
(Expression
(N
)))));
1202 end Expand_Interface_Conversion
;
1204 ------------------------------
1205 -- Expand_Interface_Actuals --
1206 ------------------------------
1208 procedure Expand_Interface_Actuals
(Call_Node
: Node_Id
) is
1209 Loc
: constant Source_Ptr
:= Sloc
(Call_Node
);
1211 Actual_Dup
: Node_Id
;
1212 Actual_Typ
: Entity_Id
;
1214 Conversion
: Node_Id
;
1216 Formal_Typ
: Entity_Id
;
1219 Formal_DDT
: Entity_Id
;
1220 Actual_DDT
: Entity_Id
;
1223 -- This subprogram is called directly from the semantics, so we need a
1224 -- check to see whether expansion is active before proceeding.
1226 if not Expander_Active
then
1230 -- Call using access to subprogram with explicit dereference
1232 if Nkind
(Name
(Call_Node
)) = N_Explicit_Dereference
then
1233 Subp
:= Etype
(Name
(Call_Node
));
1238 Subp
:= Entity
(Name
(Call_Node
));
1241 Formal
:= First_Formal
(Subp
);
1242 Actual
:= First_Actual
(Call_Node
);
1243 while Present
(Formal
) loop
1245 -- Ada 2005 (AI-251): Conversion to interface to force "this"
1248 Formal_Typ
:= Etype
(Etype
(Formal
));
1250 if Ekind
(Formal_Typ
) = E_Record_Type_With_Private
then
1251 Formal_Typ
:= Full_View
(Formal_Typ
);
1254 if Is_Access_Type
(Formal_Typ
) then
1255 Formal_DDT
:= Directly_Designated_Type
(Formal_Typ
);
1258 Actual_Typ
:= Etype
(Actual
);
1260 if Is_Access_Type
(Actual_Typ
) then
1261 Actual_DDT
:= Directly_Designated_Type
(Actual_Typ
);
1264 if Is_Interface
(Formal_Typ
) then
1266 -- No need to displace the pointer if the type of the actual
1267 -- is class-wide of the formal-type interface; in this case the
1268 -- displacement of the pointer was already done at the point of
1269 -- the call to the enclosing subprogram. This case corresponds
1270 -- with the call to P (Obj) in the following example:
1272 -- type I is interface;
1273 -- procedure P (X : I) is abstract;
1275 -- procedure General_Op (Obj : I'Class) is
1280 if Is_Class_Wide_Type
(Actual_Typ
)
1281 and then Etype
(Actual_Typ
) = Formal_Typ
1285 -- No need to displace the pointer if the type of the actual is a
1286 -- derivation of the formal-type interface because in this case
1287 -- the interface primitives are located in the primary dispatch
1290 elsif Is_Ancestor
(Formal_Typ
, Actual_Typ
) then
1294 Conversion
:= Convert_To
(Formal_Typ
, Relocate_Node
(Actual
));
1295 Rewrite
(Actual
, Conversion
);
1296 Analyze_And_Resolve
(Actual
, Formal_Typ
);
1299 -- Anonymous access type
1301 elsif Is_Access_Type
(Formal_Typ
)
1302 and then Is_Interface
(Etype
(Formal_DDT
))
1303 and then Interface_Present_In_Ancestor
1305 Iface
=> Etype
(Formal_DDT
))
1307 if Nkind
(Actual
) = N_Attribute_Reference
1309 (Attribute_Name
(Actual
) = Name_Access
1310 or else Attribute_Name
(Actual
) = Name_Unchecked_Access
)
1312 Nam
:= Attribute_Name
(Actual
);
1314 Conversion
:= Convert_To
(Etype
(Formal_DDT
), Prefix
(Actual
));
1316 Rewrite
(Actual
, Conversion
);
1317 Analyze_And_Resolve
(Actual
, Etype
(Formal_DDT
));
1320 Unchecked_Convert_To
(Formal_Typ
,
1321 Make_Attribute_Reference
(Loc
,
1322 Prefix
=> Relocate_Node
(Actual
),
1323 Attribute_Name
=> Nam
)));
1325 Analyze_And_Resolve
(Actual
, Formal_Typ
);
1327 -- No need to displace the pointer if the actual is a class-wide
1328 -- type of the formal-type interface because in this case the
1329 -- displacement of the pointer was already done at the point of
1330 -- the call to the enclosing subprogram (this case is similar
1331 -- to the example described above for the non access-type case)
1333 elsif Is_Class_Wide_Type
(Actual_DDT
)
1334 and then Etype
(Actual_DDT
) = Formal_DDT
1338 -- No need to displace the pointer if the type of the actual is a
1339 -- derivation of the interface (because in this case the interface
1340 -- primitives are located in the primary dispatch table)
1342 elsif Is_Ancestor
(Formal_DDT
, Actual_DDT
) then
1346 Actual_Dup
:= Relocate_Node
(Actual
);
1348 if From_With_Type
(Actual_Typ
) then
1350 -- If the type of the actual parameter comes from a limited
1351 -- with-clause and the non-limited view is already available
1352 -- we replace the anonymous access type by a duplicate decla
1353 -- ration whose designated type is the non-limited view
1355 if Ekind
(Actual_DDT
) = E_Incomplete_Type
1356 and then Present
(Non_Limited_View
(Actual_DDT
))
1358 Anon
:= New_Copy
(Actual_Typ
);
1360 if Is_Itype
(Anon
) then
1361 Set_Scope
(Anon
, Current_Scope
);
1364 Set_Directly_Designated_Type
(Anon
,
1365 Non_Limited_View
(Actual_DDT
));
1366 Set_Etype
(Actual_Dup
, Anon
);
1368 elsif Is_Class_Wide_Type
(Actual_DDT
)
1369 and then Ekind
(Etype
(Actual_DDT
)) = E_Incomplete_Type
1370 and then Present
(Non_Limited_View
(Etype
(Actual_DDT
)))
1372 Anon
:= New_Copy
(Actual_Typ
);
1374 if Is_Itype
(Anon
) then
1375 Set_Scope
(Anon
, Current_Scope
);
1378 Set_Directly_Designated_Type
(Anon
,
1379 New_Copy
(Actual_DDT
));
1380 Set_Class_Wide_Type
(Directly_Designated_Type
(Anon
),
1381 New_Copy
(Class_Wide_Type
(Actual_DDT
)));
1382 Set_Etype
(Directly_Designated_Type
(Anon
),
1383 Non_Limited_View
(Etype
(Actual_DDT
)));
1385 Class_Wide_Type
(Directly_Designated_Type
(Anon
)),
1386 Non_Limited_View
(Etype
(Actual_DDT
)));
1387 Set_Etype
(Actual_Dup
, Anon
);
1391 Conversion
:= Convert_To
(Formal_Typ
, Actual_Dup
);
1392 Rewrite
(Actual
, Conversion
);
1393 Analyze_And_Resolve
(Actual
, Formal_Typ
);
1397 Next_Actual
(Actual
);
1398 Next_Formal
(Formal
);
1400 end Expand_Interface_Actuals
;
1402 ----------------------------
1403 -- Expand_Interface_Thunk --
1404 ----------------------------
1406 function Expand_Interface_Thunk
1408 Thunk_Alias
: Entity_Id
;
1409 Thunk_Id
: Entity_Id
) return Node_Id
1411 Loc
: constant Source_Ptr
:= Sloc
(N
);
1412 Actuals
: constant List_Id
:= New_List
;
1413 Decl
: constant List_Id
:= New_List
;
1414 Formals
: constant List_Id
:= New_List
;
1418 New_Formal
: Node_Id
;
1424 -- Traverse the list of alias to find the final target
1426 Target
:= Thunk_Alias
;
1427 while Present
(Alias
(Target
)) loop
1428 Target
:= Alias
(Target
);
1431 -- Duplicate the formals
1433 Formal
:= First_Formal
(Target
);
1434 E
:= First_Formal
(N
);
1435 while Present
(Formal
) loop
1436 New_Formal
:= Copy_Separate_Tree
(Parent
(Formal
));
1438 -- Propagate the parameter type to the copy. This is required to
1439 -- properly handle the case in which the subprogram covering the
1440 -- interface has been inherited:
1443 -- type I is interface;
1444 -- procedure P (X : in I) is abstract;
1446 -- type T is tagged null record;
1447 -- procedure P (X : T);
1449 -- type DT is new T and I with ...
1451 Set_Parameter_Type
(New_Formal
, New_Reference_To
(Etype
(E
), Loc
));
1452 Append_To
(Formals
, New_Formal
);
1454 Next_Formal
(Formal
);
1458 if Ekind
(First_Formal
(Target
)) = E_In_Parameter
1459 and then Ekind
(Etype
(First_Formal
(Target
)))
1460 = E_Anonymous_Access_Type
1464 -- type T is access all <<type of the first formal>>
1465 -- S1 := Storage_Offset!(First_formal)
1466 -- - Offset_To_Top (First_Formal.Tag)
1468 -- ... and the first actual of the call is generated as T!(S1)
1471 Make_Full_Type_Declaration
(Loc
,
1472 Defining_Identifier
=>
1473 Make_Defining_Identifier
(Loc
,
1474 New_Internal_Name
('T')),
1476 Make_Access_To_Object_Definition
(Loc
,
1477 All_Present
=> True,
1478 Null_Exclusion_Present
=> False,
1479 Constant_Present
=> False,
1480 Subtype_Indication
=>
1482 (Directly_Designated_Type
1483 (Etype
(First_Formal
(Target
))), Loc
)));
1486 Make_Object_Declaration
(Loc
,
1487 Defining_Identifier
=>
1488 Make_Defining_Identifier
(Loc
,
1489 New_Internal_Name
('S')),
1490 Constant_Present
=> True,
1491 Object_Definition
=>
1492 New_Reference_To
(RTE
(RE_Storage_Offset
), Loc
),
1494 Make_Op_Subtract
(Loc
,
1496 Unchecked_Convert_To
1497 (RTE
(RE_Storage_Offset
),
1499 (Defining_Identifier
(First
(Formals
)), Loc
)),
1501 Make_Function_Call
(Loc
,
1502 Name
=> New_Reference_To
(RTE
(RE_Offset_To_Top
), Loc
),
1503 Parameter_Associations
=> New_List
(
1504 Make_Selected_Component
(Loc
,
1505 Prefix
=> New_Reference_To
1506 (Defining_Identifier
(First
(Formals
)),
1508 Selector_Name
=> Make_Identifier
(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_Selected_Component
(Loc
,
1550 Prefix
=> New_Reference_To
1551 (Defining_Identifier
(First
(Formals
)),
1553 Selector_Name
=> Make_Identifier
(Loc
,
1557 Make_Object_Declaration
(Loc
,
1558 Defining_Identifier
=>
1559 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S')),
1560 Constant_Present
=> True,
1561 Object_Definition
=> New_Reference_To
(RTE
(RE_Addr_Ptr
), Loc
),
1563 Unchecked_Convert_To
1565 New_Reference_To
(Defining_Identifier
(Decl_1
), Loc
)));
1567 Append_To
(Decl
, Decl_1
);
1568 Append_To
(Decl
, Decl_2
);
1570 -- Reference the new first actual
1573 Unchecked_Convert_To
1574 (Etype
(First_Entity
(Target
)),
1575 Make_Explicit_Dereference
(Loc
,
1576 New_Reference_To
(Defining_Identifier
(Decl_2
), Loc
))));
1579 Formal
:= Next
(First
(Formals
));
1580 while Present
(Formal
) loop
1582 New_Reference_To
(Defining_Identifier
(Formal
), Loc
));
1586 if Ekind
(Target
) = E_Procedure
then
1588 Make_Subprogram_Body
(Loc
,
1590 Make_Procedure_Specification
(Loc
,
1591 Defining_Unit_Name
=> Thunk_Id
,
1592 Parameter_Specifications
=> Formals
),
1593 Declarations
=> Decl
,
1594 Handled_Statement_Sequence
=>
1595 Make_Handled_Sequence_Of_Statements
(Loc
,
1596 Statements
=> New_List
(
1597 Make_Procedure_Call_Statement
(Loc
,
1598 Name
=> New_Occurrence_Of
(Target
, Loc
),
1599 Parameter_Associations
=> Actuals
))));
1601 else pragma Assert
(Ekind
(Target
) = E_Function
);
1604 Make_Subprogram_Body
(Loc
,
1606 Make_Function_Specification
(Loc
,
1607 Defining_Unit_Name
=> Thunk_Id
,
1608 Parameter_Specifications
=> Formals
,
1609 Result_Definition
=>
1610 New_Copy
(Result_Definition
(Parent
(Target
)))),
1611 Declarations
=> Decl
,
1612 Handled_Statement_Sequence
=>
1613 Make_Handled_Sequence_Of_Statements
(Loc
,
1614 Statements
=> New_List
(
1615 Make_Return_Statement
(Loc
,
1616 Make_Function_Call
(Loc
,
1617 Name
=> New_Occurrence_Of
(Target
, Loc
),
1618 Parameter_Associations
=> Actuals
)))));
1623 end Expand_Interface_Thunk
;
1629 function Fill_DT_Entry
1631 Prim
: Entity_Id
) return Node_Id
1633 Typ
: constant Entity_Id
:= Scope
(DTC_Entity
(Prim
));
1634 DT_Ptr
: constant Entity_Id
:=
1635 Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
1636 Pos
: constant Uint
:= DT_Position
(Prim
);
1637 Tag
: constant Entity_Id
:= First_Tag_Component
(Typ
);
1640 if Pos
= Uint_0
or else Pos
> DT_Entry_Count
(Tag
) then
1641 raise Program_Error
;
1645 Make_DT_Access_Action
(Typ
,
1646 Action
=> Set_Prim_Op_Address
,
1648 Unchecked_Convert_To
(RTE
(RE_Tag
),
1649 New_Reference_To
(DT_Ptr
, Loc
)), -- DTptr
1651 Make_Integer_Literal
(Loc
, Pos
), -- Position
1653 Make_Attribute_Reference
(Loc
, -- Value
1654 Prefix
=> New_Reference_To
(Prim
, Loc
),
1655 Attribute_Name
=> Name_Address
)));
1658 -----------------------------
1659 -- Fill_Secondary_DT_Entry --
1660 -----------------------------
1662 function Fill_Secondary_DT_Entry
1665 Thunk_Id
: Entity_Id
;
1666 Iface_DT_Ptr
: Entity_Id
) return Node_Id
1668 Typ
: constant Entity_Id
:= Scope
(DTC_Entity
(Alias
(Prim
)));
1669 Iface_Prim
: constant Entity_Id
:= Abstract_Interface_Alias
(Prim
);
1670 Pos
: constant Uint
:= DT_Position
(Iface_Prim
);
1671 Tag
: constant Entity_Id
:=
1672 First_Tag_Component
(Scope
(DTC_Entity
(Iface_Prim
)));
1675 if Pos
= Uint_0
or else Pos
> DT_Entry_Count
(Tag
) then
1676 raise Program_Error
;
1680 Make_DT_Access_Action
(Typ
,
1681 Action
=> Set_Prim_Op_Address
,
1683 Unchecked_Convert_To
(RTE
(RE_Tag
),
1684 New_Reference_To
(Iface_DT_Ptr
, Loc
)), -- DTptr
1686 Make_Integer_Literal
(Loc
, Pos
), -- Position
1688 Make_Attribute_Reference
(Loc
, -- Value
1689 Prefix
=> New_Reference_To
(Thunk_Id
, Loc
),
1690 Attribute_Name
=> Name_Address
)));
1691 end Fill_Secondary_DT_Entry
;
1693 ---------------------------
1694 -- Get_Remotely_Callable --
1695 ---------------------------
1697 function Get_Remotely_Callable
(Obj
: Node_Id
) return Node_Id
is
1698 Loc
: constant Source_Ptr
:= Sloc
(Obj
);
1700 return Make_DT_Access_Action
1701 (Typ
=> Etype
(Obj
),
1702 Action
=> Get_Remotely_Callable
,
1704 Make_Selected_Component
(Loc
,
1706 Selector_Name
=> Make_Identifier
(Loc
, Name_uTag
))));
1707 end Get_Remotely_Callable
;
1709 ------------------------------------------
1710 -- Init_Predefined_Interface_Primitives --
1711 ------------------------------------------
1713 function Init_Predefined_Interface_Primitives
1714 (Typ
: Entity_Id
) return List_Id
1716 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
1717 DT_Ptr
: constant Node_Id
:=
1718 Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
1719 Result
: constant List_Id
:= New_List
;
1723 -- No need to inherit primitives if we have an abstract interface
1724 -- type or a concurrent type.
1726 if Is_Interface
(Typ
) or else Is_Concurrent_Record_Type
(Typ
) then
1730 AI
:= Next_Elmt
(First_Elmt
(Access_Disp_Table
(Typ
)));
1731 while Present
(AI
) loop
1733 -- All the secondary tables inherit the dispatch table entries
1734 -- associated with predefined primitives.
1737 -- Inherit_DT (T'Tag, Iface'Tag, Default_Prim_Op_Count);
1740 Make_DT_Access_Action
(Typ
,
1741 Action
=> Inherit_DT
,
1743 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
1744 Node2
=> Unchecked_Convert_To
(RTE
(RE_Tag
),
1745 New_Reference_To
(Node
(AI
), Loc
)),
1746 Node3
=> Make_Integer_Literal
(Loc
, Default_Prim_Op_Count
))));
1752 end Init_Predefined_Interface_Primitives
;
1754 ----------------------------------------
1755 -- Make_Disp_Asynchronous_Select_Body --
1756 ----------------------------------------
1758 function Make_Disp_Asynchronous_Select_Body
1759 (Typ
: Entity_Id
) return Node_Id
1761 Conc_Typ
: Entity_Id
:= Empty
;
1762 Decls
: constant List_Id
:= New_List
;
1764 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
1765 Stmts
: constant List_Id
:= New_List
;
1768 -- Null body is generated for interface types
1770 if Is_Interface
(Typ
) then
1772 Make_Subprogram_Body
(Loc
,
1774 Make_Disp_Asynchronous_Select_Spec
(Typ
),
1777 Handled_Statement_Sequence
=>
1778 Make_Handled_Sequence_Of_Statements
(Loc
,
1779 New_List
(Make_Null_Statement
(Loc
))));
1782 DT_Ptr
:= Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
1784 if Is_Concurrent_Record_Type
(Typ
) then
1785 Conc_Typ
:= Corresponding_Concurrent_Type
(Typ
);
1788 -- I : Integer := Get_Entry_Index (tag! (<type>VP), S);
1790 -- where I will be used to capture the entry index of the primitive
1791 -- wrapper at position S.
1794 Make_Object_Declaration
(Loc
,
1795 Defining_Identifier
=>
1796 Make_Defining_Identifier
(Loc
, Name_uI
),
1797 Object_Definition
=>
1798 New_Reference_To
(Standard_Integer
, Loc
),
1800 Make_DT_Access_Action
(Typ
,
1805 Unchecked_Convert_To
(RTE
(RE_Tag
),
1806 New_Reference_To
(DT_Ptr
, Loc
)),
1807 Make_Identifier
(Loc
, Name_uS
)))));
1809 if Ekind
(Conc_Typ
) = E_Protected_Type
then
1812 -- Protected_Entry_Call (
1813 -- T._object'access,
1814 -- protected_entry_index! (I),
1816 -- Asynchronous_Call,
1819 -- where T is the protected object, I is the entry index, P are
1820 -- the wrapped parameters and B is the name of the communication
1824 Make_Procedure_Call_Statement
(Loc
,
1826 New_Reference_To
(RTE
(RE_Protected_Entry_Call
), Loc
),
1827 Parameter_Associations
=>
1830 Make_Attribute_Reference
(Loc
, -- T._object'access
1832 Name_Unchecked_Access
,
1834 Make_Selected_Component
(Loc
,
1836 Make_Identifier
(Loc
, Name_uT
),
1838 Make_Identifier
(Loc
, Name_uObject
))),
1840 Make_Unchecked_Type_Conversion
(Loc
, -- entry index
1842 New_Reference_To
(RTE
(RE_Protected_Entry_Index
), Loc
),
1844 Make_Identifier
(Loc
, Name_uI
)),
1846 Make_Identifier
(Loc
, Name_uP
), -- parameter block
1847 New_Reference_To
( -- Asynchronous_Call
1848 RTE
(RE_Asynchronous_Call
), Loc
),
1849 Make_Identifier
(Loc
, Name_uB
)))); -- comm block
1851 pragma Assert
(Ekind
(Conc_Typ
) = E_Task_Type
);
1854 -- Protected_Entry_Call (
1856 -- task_entry_index! (I),
1858 -- Conditional_Call,
1861 -- where T is the task object, I is the entry index, P are the
1862 -- wrapped parameters and F is the status flag.
1865 Make_Procedure_Call_Statement
(Loc
,
1867 New_Reference_To
(RTE
(RE_Task_Entry_Call
), Loc
),
1868 Parameter_Associations
=>
1871 Make_Selected_Component
(Loc
, -- T._task_id
1873 Make_Identifier
(Loc
, Name_uT
),
1875 Make_Identifier
(Loc
, Name_uTask_Id
)),
1877 Make_Unchecked_Type_Conversion
(Loc
, -- entry index
1879 New_Reference_To
(RTE
(RE_Task_Entry_Index
), Loc
),
1881 Make_Identifier
(Loc
, Name_uI
)),
1883 Make_Identifier
(Loc
, Name_uP
), -- parameter block
1884 New_Reference_To
( -- Asynchronous_Call
1885 RTE
(RE_Asynchronous_Call
), Loc
),
1886 Make_Identifier
(Loc
, Name_uF
)))); -- status flag
1891 Make_Subprogram_Body
(Loc
,
1893 Make_Disp_Asynchronous_Select_Spec
(Typ
),
1896 Handled_Statement_Sequence
=>
1897 Make_Handled_Sequence_Of_Statements
(Loc
, Stmts
));
1898 end Make_Disp_Asynchronous_Select_Body
;
1900 ----------------------------------------
1901 -- Make_Disp_Asynchronous_Select_Spec --
1902 ----------------------------------------
1904 function Make_Disp_Asynchronous_Select_Spec
1905 (Typ
: Entity_Id
) return Node_Id
1907 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
1908 Def_Id
: constant Node_Id
:=
1909 Make_Defining_Identifier
(Loc
,
1910 Name_uDisp_Asynchronous_Select
);
1911 Params
: constant List_Id
:= New_List
;
1914 -- "T" - Object parameter
1915 -- "S" - Primitive operation slot
1916 -- "P" - Wrapped parameters
1917 -- "B" - Communication block
1918 -- "F" - Status flag
1920 SEU
.Build_T
(Loc
, Typ
, Params
);
1921 SEU
.Build_S
(Loc
, Params
);
1922 SEU
.Build_P
(Loc
, Params
);
1923 SEU
.Build_B
(Loc
, Params
);
1924 SEU
.Build_F
(Loc
, Params
);
1926 Set_Is_Internal
(Def_Id
);
1929 Make_Procedure_Specification
(Loc
,
1930 Defining_Unit_Name
=> Def_Id
,
1931 Parameter_Specifications
=> Params
);
1932 end Make_Disp_Asynchronous_Select_Spec
;
1934 ---------------------------------------
1935 -- Make_Disp_Conditional_Select_Body --
1936 ---------------------------------------
1938 function Make_Disp_Conditional_Select_Body
1939 (Typ
: Entity_Id
) return Node_Id
1941 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
1942 Blk_Nam
: Entity_Id
;
1943 Conc_Typ
: Entity_Id
:= Empty
;
1944 Decls
: constant List_Id
:= New_List
;
1946 Stmts
: constant List_Id
:= New_List
;
1949 -- Null body is generated for interface types
1951 if Is_Interface
(Typ
) then
1953 Make_Subprogram_Body
(Loc
,
1955 Make_Disp_Conditional_Select_Spec
(Typ
),
1958 Handled_Statement_Sequence
=>
1959 Make_Handled_Sequence_Of_Statements
(Loc
,
1960 New_List
(Make_Null_Statement
(Loc
))));
1963 DT_Ptr
:= Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
1965 if Is_Concurrent_Record_Type
(Typ
) then
1966 Conc_Typ
:= Corresponding_Concurrent_Type
(Typ
);
1971 -- where I will be used to capture the entry index of the primitive
1972 -- wrapper at position S.
1975 Make_Object_Declaration
(Loc
,
1976 Defining_Identifier
=>
1977 Make_Defining_Identifier
(Loc
, Name_uI
),
1978 Object_Definition
=>
1979 New_Reference_To
(Standard_Integer
, Loc
)));
1982 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
1984 -- if C = POK_Procedure
1985 -- or else C = POK_Protected_Procedure
1986 -- or else C = POK_Task_Procedure;
1992 SEU
.Build_Common_Dispatching_Select_Statements
1993 (Loc
, Typ
, DT_Ptr
, Stmts
);
1996 -- Bnn : Communication_Block;
1998 -- where Bnn is the name of the communication block used in
1999 -- the call to Protected_Entry_Call.
2001 Blk_Nam
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('B'));
2004 Make_Object_Declaration
(Loc
,
2005 Defining_Identifier
=>
2007 Object_Definition
=>
2008 New_Reference_To
(RTE
(RE_Communication_Block
), Loc
)));
2011 -- I := Get_Entry_Index (tag! (<type>VP), S);
2013 -- I is the entry index and S is the dispatch table slot
2016 Make_Assignment_Statement
(Loc
,
2018 Make_Identifier
(Loc
, Name_uI
),
2020 Make_DT_Access_Action
(Typ
,
2025 Unchecked_Convert_To
(RTE
(RE_Tag
),
2026 New_Reference_To
(DT_Ptr
, Loc
)),
2027 Make_Identifier
(Loc
, Name_uS
)))));
2029 if Ekind
(Conc_Typ
) = E_Protected_Type
then
2032 -- Protected_Entry_Call (
2033 -- T._object'access,
2034 -- protected_entry_index! (I),
2036 -- Conditional_Call,
2039 -- where T is the protected object, I is the entry index, P are
2040 -- the wrapped parameters and Bnn is the name of the communication
2044 Make_Procedure_Call_Statement
(Loc
,
2046 New_Reference_To
(RTE
(RE_Protected_Entry_Call
), Loc
),
2047 Parameter_Associations
=>
2050 Make_Attribute_Reference
(Loc
, -- T._object'access
2052 Name_Unchecked_Access
,
2054 Make_Selected_Component
(Loc
,
2056 Make_Identifier
(Loc
, Name_uT
),
2058 Make_Identifier
(Loc
, Name_uObject
))),
2060 Make_Unchecked_Type_Conversion
(Loc
, -- entry index
2062 New_Reference_To
(RTE
(RE_Protected_Entry_Index
), Loc
),
2064 Make_Identifier
(Loc
, Name_uI
)),
2066 Make_Identifier
(Loc
, Name_uP
), -- parameter block
2067 New_Reference_To
( -- Conditional_Call
2068 RTE
(RE_Conditional_Call
), Loc
),
2069 New_Reference_To
( -- Bnn
2073 -- F := not Cancelled (Bnn);
2075 -- where F is the success flag. The status of Cancelled is negated
2076 -- in order to match the behaviour of the version for task types.
2079 Make_Assignment_Statement
(Loc
,
2081 Make_Identifier
(Loc
, Name_uF
),
2085 Make_Function_Call
(Loc
,
2087 New_Reference_To
(RTE
(RE_Cancelled
), Loc
),
2088 Parameter_Associations
=>
2090 New_Reference_To
(Blk_Nam
, Loc
))))));
2092 pragma Assert
(Ekind
(Conc_Typ
) = E_Task_Type
);
2095 -- Protected_Entry_Call (
2097 -- task_entry_index! (I),
2099 -- Conditional_Call,
2102 -- where T is the task object, I is the entry index, P are the
2103 -- wrapped parameters and F is the status flag.
2106 Make_Procedure_Call_Statement
(Loc
,
2108 New_Reference_To
(RTE
(RE_Task_Entry_Call
), Loc
),
2109 Parameter_Associations
=>
2112 Make_Selected_Component
(Loc
, -- T._task_id
2114 Make_Identifier
(Loc
, Name_uT
),
2116 Make_Identifier
(Loc
, Name_uTask_Id
)),
2118 Make_Unchecked_Type_Conversion
(Loc
, -- entry index
2120 New_Reference_To
(RTE
(RE_Task_Entry_Index
), Loc
),
2122 Make_Identifier
(Loc
, Name_uI
)),
2124 Make_Identifier
(Loc
, Name_uP
), -- parameter block
2125 New_Reference_To
( -- Conditional_Call
2126 RTE
(RE_Conditional_Call
), Loc
),
2127 Make_Identifier
(Loc
, Name_uF
)))); -- status flag
2132 Make_Subprogram_Body
(Loc
,
2134 Make_Disp_Conditional_Select_Spec
(Typ
),
2137 Handled_Statement_Sequence
=>
2138 Make_Handled_Sequence_Of_Statements
(Loc
, Stmts
));
2139 end Make_Disp_Conditional_Select_Body
;
2141 ---------------------------------------
2142 -- Make_Disp_Conditional_Select_Spec --
2143 ---------------------------------------
2145 function Make_Disp_Conditional_Select_Spec
2146 (Typ
: Entity_Id
) return Node_Id
2148 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2149 Def_Id
: constant Node_Id
:=
2150 Make_Defining_Identifier
(Loc
,
2151 Name_uDisp_Conditional_Select
);
2152 Params
: constant List_Id
:= New_List
;
2155 -- "T" - Object parameter
2156 -- "S" - Primitive operation slot
2157 -- "P" - Wrapped parameters
2159 -- "F" - Status flag
2161 SEU
.Build_T
(Loc
, Typ
, Params
);
2162 SEU
.Build_S
(Loc
, Params
);
2163 SEU
.Build_P
(Loc
, Params
);
2164 SEU
.Build_C
(Loc
, Params
);
2165 SEU
.Build_F
(Loc
, Params
);
2167 Set_Is_Internal
(Def_Id
);
2170 Make_Procedure_Specification
(Loc
,
2171 Defining_Unit_Name
=> Def_Id
,
2172 Parameter_Specifications
=> Params
);
2173 end Make_Disp_Conditional_Select_Spec
;
2175 -------------------------------------
2176 -- Make_Disp_Get_Prim_Op_Kind_Body --
2177 -------------------------------------
2179 function Make_Disp_Get_Prim_Op_Kind_Body
2180 (Typ
: Entity_Id
) return Node_Id
2182 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2186 if Is_Interface
(Typ
) then
2188 Make_Subprogram_Body
(Loc
,
2190 Make_Disp_Get_Prim_Op_Kind_Spec
(Typ
),
2193 Handled_Statement_Sequence
=>
2194 Make_Handled_Sequence_Of_Statements
(Loc
,
2195 New_List
(Make_Null_Statement
(Loc
))));
2198 DT_Ptr
:= Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
2201 -- C := get_prim_op_kind (tag! (<type>VP), S);
2203 -- where C is the out parameter capturing the call kind and S is the
2204 -- dispatch table slot number.
2207 Make_Subprogram_Body
(Loc
,
2209 Make_Disp_Get_Prim_Op_Kind_Spec
(Typ
),
2212 Handled_Statement_Sequence
=>
2213 Make_Handled_Sequence_Of_Statements
(Loc
,
2215 Make_Assignment_Statement
(Loc
,
2217 Make_Identifier
(Loc
, Name_uC
),
2219 Make_DT_Access_Action
(Typ
,
2224 Unchecked_Convert_To
(RTE
(RE_Tag
),
2225 New_Reference_To
(DT_Ptr
, Loc
)),
2226 Make_Identifier
(Loc
, Name_uS
)))))));
2227 end Make_Disp_Get_Prim_Op_Kind_Body
;
2229 -------------------------------------
2230 -- Make_Disp_Get_Prim_Op_Kind_Spec --
2231 -------------------------------------
2233 function Make_Disp_Get_Prim_Op_Kind_Spec
2234 (Typ
: Entity_Id
) return Node_Id
2236 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2237 Def_Id
: constant Node_Id
:=
2238 Make_Defining_Identifier
(Loc
,
2239 Name_uDisp_Get_Prim_Op_Kind
);
2240 Params
: constant List_Id
:= New_List
;
2243 -- "T" - Object parameter
2244 -- "S" - Primitive operation slot
2247 SEU
.Build_T
(Loc
, Typ
, Params
);
2248 SEU
.Build_S
(Loc
, Params
);
2249 SEU
.Build_C
(Loc
, Params
);
2251 Set_Is_Internal
(Def_Id
);
2254 Make_Procedure_Specification
(Loc
,
2255 Defining_Unit_Name
=> Def_Id
,
2256 Parameter_Specifications
=> Params
);
2257 end Make_Disp_Get_Prim_Op_Kind_Spec
;
2259 --------------------------------
2260 -- Make_Disp_Get_Task_Id_Body --
2261 --------------------------------
2263 function Make_Disp_Get_Task_Id_Body
2264 (Typ
: Entity_Id
) return Node_Id
2266 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2270 if Is_Concurrent_Record_Type
(Typ
)
2271 and then Ekind
(Corresponding_Concurrent_Type
(Typ
)) = E_Task_Type
2274 Make_Return_Statement
(Loc
,
2276 Make_Selected_Component
(Loc
,
2278 Make_Identifier
(Loc
, Name_uT
),
2280 Make_Identifier
(Loc
, Name_uTask_Id
)));
2282 -- A null body is constructed for non-task types
2286 Make_Return_Statement
(Loc
,
2288 New_Reference_To
(RTE
(RO_ST_Null_Task
), Loc
));
2292 Make_Subprogram_Body
(Loc
,
2294 Make_Disp_Get_Task_Id_Spec
(Typ
),
2297 Handled_Statement_Sequence
=>
2298 Make_Handled_Sequence_Of_Statements
(Loc
,
2300 end Make_Disp_Get_Task_Id_Body
;
2302 --------------------------------
2303 -- Make_Disp_Get_Task_Id_Spec --
2304 --------------------------------
2306 function Make_Disp_Get_Task_Id_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_Task_Id
);
2315 Set_Is_Internal
(Def_Id
);
2318 Make_Function_Specification
(Loc
,
2319 Defining_Unit_Name
=> Def_Id
,
2320 Parameter_Specifications
=> New_List
(
2321 Make_Parameter_Specification
(Loc
,
2322 Defining_Identifier
=>
2323 Make_Defining_Identifier
(Loc
, Name_uT
),
2325 New_Reference_To
(Typ
, Loc
))),
2326 Result_Definition
=>
2327 New_Reference_To
(RTE
(RO_ST_Task_Id
), Loc
));
2328 end Make_Disp_Get_Task_Id_Spec
;
2330 ---------------------------------
2331 -- Make_Disp_Timed_Select_Body --
2332 ---------------------------------
2334 function Make_Disp_Timed_Select_Body
2335 (Typ
: Entity_Id
) return Node_Id
2337 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2338 Conc_Typ
: Entity_Id
:= Empty
;
2339 Decls
: constant List_Id
:= New_List
;
2341 Stmts
: constant List_Id
:= New_List
;
2344 -- Null body is generated for interface types
2346 if Is_Interface
(Typ
) then
2348 Make_Subprogram_Body
(Loc
,
2350 Make_Disp_Timed_Select_Spec
(Typ
),
2353 Handled_Statement_Sequence
=>
2354 Make_Handled_Sequence_Of_Statements
(Loc
,
2355 New_List
(Make_Null_Statement
(Loc
))));
2358 DT_Ptr
:= Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
2360 if Is_Concurrent_Record_Type
(Typ
) then
2361 Conc_Typ
:= Corresponding_Concurrent_Type
(Typ
);
2366 -- where I will be used to capture the entry index of the primitive
2367 -- wrapper at position S.
2370 Make_Object_Declaration
(Loc
,
2371 Defining_Identifier
=>
2372 Make_Defining_Identifier
(Loc
, Name_uI
),
2373 Object_Definition
=>
2374 New_Reference_To
(Standard_Integer
, Loc
)));
2377 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
2379 -- if C = POK_Procedure
2380 -- or else C = POK_Protected_Procedure
2381 -- or else C = POK_Task_Procedure;
2387 SEU
.Build_Common_Dispatching_Select_Statements
2388 (Loc
, Typ
, DT_Ptr
, Stmts
);
2391 -- I := Get_Entry_Index (tag! (<type>VP), S);
2393 -- I is the entry index and S is the dispatch table slot
2396 Make_Assignment_Statement
(Loc
,
2398 Make_Identifier
(Loc
, Name_uI
),
2400 Make_DT_Access_Action
(Typ
,
2405 Unchecked_Convert_To
(RTE
(RE_Tag
),
2406 New_Reference_To
(DT_Ptr
, Loc
)),
2407 Make_Identifier
(Loc
, Name_uS
)))));
2409 if Ekind
(Conc_Typ
) = E_Protected_Type
then
2412 -- Timed_Protected_Entry_Call (
2413 -- T._object'access,
2414 -- protected_entry_index! (I),
2420 -- where T is the protected object, I is the entry index, P are
2421 -- the wrapped parameters, D is the delay amount, M is the delay
2422 -- mode and F is the status flag.
2425 Make_Procedure_Call_Statement
(Loc
,
2427 New_Reference_To
(RTE
(RE_Timed_Protected_Entry_Call
), Loc
),
2428 Parameter_Associations
=>
2431 Make_Attribute_Reference
(Loc
, -- T._object'access
2433 Name_Unchecked_Access
,
2435 Make_Selected_Component
(Loc
,
2437 Make_Identifier
(Loc
, Name_uT
),
2439 Make_Identifier
(Loc
, Name_uObject
))),
2441 Make_Unchecked_Type_Conversion
(Loc
, -- entry index
2443 New_Reference_To
(RTE
(RE_Protected_Entry_Index
), Loc
),
2445 Make_Identifier
(Loc
, Name_uI
)),
2447 Make_Identifier
(Loc
, Name_uP
), -- parameter block
2448 Make_Identifier
(Loc
, Name_uD
), -- delay
2449 Make_Identifier
(Loc
, Name_uM
), -- delay mode
2450 Make_Identifier
(Loc
, Name_uF
)))); -- status flag
2453 pragma Assert
(Ekind
(Conc_Typ
) = E_Task_Type
);
2456 -- Timed_Task_Entry_Call (
2458 -- task_entry_index! (I),
2464 -- where T is the task object, I is the entry index, P are the
2465 -- wrapped parameters, D is the delay amount, M is the delay
2466 -- mode and F is the status flag.
2469 Make_Procedure_Call_Statement
(Loc
,
2471 New_Reference_To
(RTE
(RE_Timed_Task_Entry_Call
), Loc
),
2472 Parameter_Associations
=>
2475 Make_Selected_Component
(Loc
, -- T._task_id
2477 Make_Identifier
(Loc
, Name_uT
),
2479 Make_Identifier
(Loc
, Name_uTask_Id
)),
2481 Make_Unchecked_Type_Conversion
(Loc
, -- entry index
2483 New_Reference_To
(RTE
(RE_Task_Entry_Index
), Loc
),
2485 Make_Identifier
(Loc
, Name_uI
)),
2487 Make_Identifier
(Loc
, Name_uP
), -- parameter block
2488 Make_Identifier
(Loc
, Name_uD
), -- delay
2489 Make_Identifier
(Loc
, Name_uM
), -- delay mode
2490 Make_Identifier
(Loc
, Name_uF
)))); -- status flag
2495 Make_Subprogram_Body
(Loc
,
2497 Make_Disp_Timed_Select_Spec
(Typ
),
2500 Handled_Statement_Sequence
=>
2501 Make_Handled_Sequence_Of_Statements
(Loc
, Stmts
));
2502 end Make_Disp_Timed_Select_Body
;
2504 ---------------------------------
2505 -- Make_Disp_Timed_Select_Spec --
2506 ---------------------------------
2508 function Make_Disp_Timed_Select_Spec
2509 (Typ
: Entity_Id
) return Node_Id
2511 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2512 Def_Id
: constant Node_Id
:=
2513 Make_Defining_Identifier
(Loc
,
2514 Name_uDisp_Timed_Select
);
2515 Params
: constant List_Id
:= New_List
;
2518 -- "T" - Object parameter
2519 -- "S" - Primitive operation slot
2520 -- "P" - Wrapped parameters
2524 -- "F" - Status flag
2526 SEU
.Build_T
(Loc
, Typ
, Params
);
2527 SEU
.Build_S
(Loc
, Params
);
2528 SEU
.Build_P
(Loc
, Params
);
2531 Make_Parameter_Specification
(Loc
,
2532 Defining_Identifier
=>
2533 Make_Defining_Identifier
(Loc
, Name_uD
),
2535 New_Reference_To
(Standard_Duration
, Loc
)));
2538 Make_Parameter_Specification
(Loc
,
2539 Defining_Identifier
=>
2540 Make_Defining_Identifier
(Loc
, Name_uM
),
2542 New_Reference_To
(Standard_Integer
, Loc
)));
2544 SEU
.Build_C
(Loc
, Params
);
2545 SEU
.Build_F
(Loc
, Params
);
2547 Set_Is_Internal
(Def_Id
);
2550 Make_Procedure_Specification
(Loc
,
2551 Defining_Unit_Name
=> Def_Id
,
2552 Parameter_Specifications
=> Params
);
2553 end Make_Disp_Timed_Select_Spec
;
2559 function Make_DT
(Typ
: Entity_Id
) return List_Id
is
2560 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2561 Result
: constant List_Id
:= New_List
;
2562 Elab_Code
: constant List_Id
:= New_List
;
2564 Tname
: constant Name_Id
:= Chars
(Typ
);
2565 Name_DT
: constant Name_Id
:= New_External_Name
(Tname
, 'T');
2566 Name_DT_Ptr
: constant Name_Id
:= New_External_Name
(Tname
, 'P');
2567 Name_SSD
: constant Name_Id
:= New_External_Name
(Tname
, 'S');
2568 Name_TSD
: constant Name_Id
:= New_External_Name
(Tname
, 'B');
2569 Name_Exname
: constant Name_Id
:= New_External_Name
(Tname
, 'E');
2570 Name_No_Reg
: constant Name_Id
:= New_External_Name
(Tname
, 'F');
2571 Name_ITable
: Name_Id
;
2573 DT
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_DT
);
2574 DT_Ptr
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_DT_Ptr
);
2575 SSD
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_SSD
);
2576 TSD
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_TSD
);
2577 Exname
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_Exname
);
2578 No_Reg
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_No_Reg
);
2581 Generalized_Tag
: constant Entity_Id
:= RTE
(RE_Tag
);
2588 Parent_Num_Ifaces
: Int
;
2589 Size_Expr_Node
: Node_Id
;
2590 TSD_Num_Entries
: Int
;
2592 Ancestor_Copy
: Entity_Id
;
2593 Typ_Copy
: Entity_Id
;
2596 if not RTE_Available
(RE_Tag
) then
2597 Error_Msg_CRT
("tagged types", Typ
);
2601 -- Calculate the size of the DT and the TSD
2603 if Is_Interface
(Typ
) then
2604 -- Abstract interfaces need neither the DT nor the ancestors table.
2605 -- We reserve a single entry for its DT because at run-time the
2606 -- pointer to this dummy DT will be used as the tag of this abstract
2610 TSD_Num_Entries
:= 0;
2614 -- Count the number of interfaces implemented by the ancestors
2616 Parent_Num_Ifaces
:= 0;
2619 if Typ
/= Etype
(Typ
) then
2620 Ancestor_Copy
:= New_Copy
(Etype
(Typ
));
2621 Set_Parent
(Ancestor_Copy
, Parent
(Etype
(Typ
)));
2622 Set_Abstract_Interfaces
(Ancestor_Copy
, New_Elmt_List
);
2623 Collect_All_Interfaces
(Ancestor_Copy
);
2625 AI
:= First_Elmt
(Abstract_Interfaces
(Ancestor_Copy
));
2626 while Present
(AI
) loop
2627 Parent_Num_Ifaces
:= Parent_Num_Ifaces
+ 1;
2632 -- Count the number of additional interfaces implemented by Typ
2634 Typ_Copy
:= New_Copy
(Typ
);
2635 Set_Parent
(Typ_Copy
, Parent
(Typ
));
2636 Set_Abstract_Interfaces
(Typ_Copy
, New_Elmt_List
);
2637 Collect_All_Interfaces
(Typ_Copy
);
2639 AI
:= First_Elmt
(Abstract_Interfaces
(Typ_Copy
));
2640 while Present
(AI
) loop
2641 Num_Ifaces
:= Num_Ifaces
+ 1;
2645 -- Count ancestors to compute the inheritance depth. For private
2646 -- extensions, always go to the full view in order to compute the
2647 -- real inheritance depth.
2650 Parent_Type
: Entity_Id
:= Typ
;
2656 P
:= Etype
(Parent_Type
);
2658 if Is_Private_Type
(P
) then
2659 P
:= Full_View
(Base_Type
(P
));
2662 exit when P
= Parent_Type
;
2664 I_Depth
:= I_Depth
+ 1;
2669 TSD_Num_Entries
:= I_Depth
+ 1;
2670 Nb_Prim
:= UI_To_Int
(DT_Entry_Count
(First_Tag_Component
(Typ
)));
2672 -- If the number of primitives of Typ is less that the number of
2673 -- predefined primitives, we must reserve at least enough space
2674 -- for the predefined primitives.
2676 if Nb_Prim
< Default_Prim_Op_Count
then
2677 Nb_Prim
:= Default_Prim_Op_Count
;
2681 -- Dispatch table and related entities are allocated statically
2683 Set_Ekind
(DT
, E_Variable
);
2684 Set_Is_Statically_Allocated
(DT
);
2686 Set_Ekind
(DT_Ptr
, E_Variable
);
2687 Set_Is_Statically_Allocated
(DT_Ptr
);
2689 if not Is_Interface
(Typ
)
2690 and then Num_Ifaces
> 0
2692 Name_ITable
:= New_External_Name
(Tname
, 'I');
2693 ITable
:= Make_Defining_Identifier
(Loc
, Name_ITable
);
2695 Set_Ekind
(ITable
, E_Variable
);
2696 Set_Is_Statically_Allocated
(ITable
);
2699 Set_Ekind
(SSD
, E_Variable
);
2700 Set_Is_Statically_Allocated
(SSD
);
2702 Set_Ekind
(TSD
, E_Variable
);
2703 Set_Is_Statically_Allocated
(TSD
);
2705 Set_Ekind
(Exname
, E_Variable
);
2706 Set_Is_Statically_Allocated
(Exname
);
2708 Set_Ekind
(No_Reg
, E_Variable
);
2709 Set_Is_Statically_Allocated
(No_Reg
);
2711 -- Generate code to create the storage for the Dispatch_Table object:
2713 -- DT : Storage_Array (1..DT_Prologue_Size+nb_prim*DT_Entry_Size);
2714 -- for DT'Alignment use Address'Alignment
2718 Left_Opnd
=> Make_DT_Access_Action
(Typ
, DT_Prologue_Size
, No_List
),
2720 Make_Op_Multiply
(Loc
,
2722 Make_DT_Access_Action
(Typ
, DT_Entry_Size
, No_List
),
2724 Make_Integer_Literal
(Loc
, Nb_Prim
)));
2727 Make_Object_Declaration
(Loc
,
2728 Defining_Identifier
=> DT
,
2729 Aliased_Present
=> True,
2730 Object_Definition
=>
2731 Make_Subtype_Indication
(Loc
,
2732 Subtype_Mark
=> New_Reference_To
2733 (RTE
(RE_Storage_Array
), Loc
),
2734 Constraint
=> Make_Index_Or_Discriminant_Constraint
(Loc
,
2735 Constraints
=> New_List
(
2737 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
2738 High_Bound
=> Size_Expr_Node
))))));
2741 Make_Attribute_Definition_Clause
(Loc
,
2742 Name
=> New_Reference_To
(DT
, Loc
),
2743 Chars
=> Name_Alignment
,
2745 Make_Attribute_Reference
(Loc
,
2746 Prefix
=> New_Reference_To
(RTE
(RE_Integer_Address
), Loc
),
2747 Attribute_Name
=> Name_Alignment
)));
2749 -- Initialize the signature of the interface tag. It is a sequence
2750 -- two bytes located in the header of the dispatch table.
2753 Make_Assignment_Statement
(Loc
,
2755 Make_Indexed_Component
(Loc
,
2756 Prefix
=> New_Occurrence_Of
(DT
, Loc
),
2757 Expressions
=> New_List
(
2758 Make_Integer_Literal
(Loc
, Uint_1
))),
2760 Unchecked_Convert_To
(RTE
(RE_Storage_Element
),
2761 New_Reference_To
(RTE
(RE_Valid_Signature
), Loc
))));
2763 if not Is_Interface
(Typ
) then
2765 -- The signature of a Primary Dispatch table is:
2766 -- (Valid_Signature, Primary_DT)
2769 Make_Assignment_Statement
(Loc
,
2771 Make_Indexed_Component
(Loc
,
2772 Prefix
=> New_Occurrence_Of
(DT
, Loc
),
2773 Expressions
=> New_List
(
2774 Make_Integer_Literal
(Loc
, Uint_2
))),
2776 Unchecked_Convert_To
(RTE
(RE_Storage_Element
),
2777 New_Reference_To
(RTE
(RE_Primary_DT
), Loc
))));
2780 -- The signature of an abstract interface is:
2781 -- (Valid_Signature, Abstract_Interface)
2784 Make_Assignment_Statement
(Loc
,
2786 Make_Indexed_Component
(Loc
,
2787 Prefix
=> New_Occurrence_Of
(DT
, Loc
),
2788 Expressions
=> New_List
(
2789 Make_Integer_Literal
(Loc
, Uint_2
))),
2791 Unchecked_Convert_To
(RTE
(RE_Storage_Element
),
2792 New_Reference_To
(RTE
(RE_Abstract_Interface
), Loc
))));
2795 -- Generate code to create the pointer to the dispatch table
2797 -- DT_Ptr : Tag := Tag!(DT'Address);
2799 -- According to the C++ ABI, the base of the vtable is located after a
2800 -- prologue containing Offset_To_Top, and Typeinfo_Ptr. Hence, we move
2801 -- down the pointer to the real base of the vtable
2804 Make_Object_Declaration
(Loc
,
2805 Defining_Identifier
=> DT_Ptr
,
2806 Constant_Present
=> True,
2807 Object_Definition
=> New_Reference_To
(Generalized_Tag
, Loc
),
2809 Unchecked_Convert_To
(Generalized_Tag
,
2812 Unchecked_Convert_To
(RTE
(RE_Storage_Offset
),
2813 Make_Attribute_Reference
(Loc
,
2814 Prefix
=> New_Reference_To
(DT
, Loc
),
2815 Attribute_Name
=> Name_Address
)),
2817 Make_DT_Access_Action
(Typ
,
2818 DT_Prologue_Size
, No_List
)))));
2820 -- Generate code to define the boolean that controls registration, in
2821 -- order to avoid multiple registrations for tagged types defined in
2822 -- multiple-called scopes.
2825 Make_Object_Declaration
(Loc
,
2826 Defining_Identifier
=> No_Reg
,
2827 Object_Definition
=> New_Reference_To
(Standard_Boolean
, Loc
),
2828 Expression
=> New_Reference_To
(Standard_True
, Loc
)));
2830 -- Set Access_Disp_Table field to be the dispatch table pointer
2832 if not Present
(Access_Disp_Table
(Typ
)) then
2833 Set_Access_Disp_Table
(Typ
, New_Elmt_List
);
2836 Prepend_Elmt
(DT_Ptr
, Access_Disp_Table
(Typ
));
2838 -- Generate code to create the storage for the type specific data object
2839 -- with enough space to store the tags of the ancestors plus the tags
2840 -- of all the implemented interfaces (as described in a-tags.adb).
2842 -- TSD: Storage_Array
2843 -- (1..TSD_Prologue_Size+TSD_Num_Entries*TSD_Entry_Size);
2844 -- for TSD'Alignment use Address'Alignment
2849 Make_DT_Access_Action
(Typ
, TSD_Prologue_Size
, No_List
),
2851 Make_Op_Multiply
(Loc
,
2853 Make_DT_Access_Action
(Typ
, TSD_Entry_Size
, No_List
),
2855 Make_Integer_Literal
(Loc
, TSD_Num_Entries
)));
2858 Make_Object_Declaration
(Loc
,
2859 Defining_Identifier
=> TSD
,
2860 Aliased_Present
=> True,
2861 Object_Definition
=>
2862 Make_Subtype_Indication
(Loc
,
2863 Subtype_Mark
=> New_Reference_To
(RTE
(RE_Storage_Array
), Loc
),
2864 Constraint
=> Make_Index_Or_Discriminant_Constraint
(Loc
,
2865 Constraints
=> New_List
(
2867 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
2868 High_Bound
=> Size_Expr_Node
))))));
2871 Make_Attribute_Definition_Clause
(Loc
,
2872 Name
=> New_Reference_To
(TSD
, Loc
),
2873 Chars
=> Name_Alignment
,
2875 Make_Attribute_Reference
(Loc
,
2876 Prefix
=> New_Reference_To
(RTE
(RE_Integer_Address
), Loc
),
2877 Attribute_Name
=> Name_Alignment
)));
2879 -- Generate code to put the Address of the TSD in the dispatch table
2880 -- Set_TSD (DT_Ptr, TSD);
2882 Append_To
(Elab_Code
,
2883 Make_DT_Access_Action
(Typ
,
2886 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
2887 Make_Attribute_Reference
(Loc
, -- Value
2888 Prefix
=> New_Reference_To
(TSD
, Loc
),
2889 Attribute_Name
=> Name_Address
))));
2891 -- Set the pointer to the Interfaces_Table (if any). Otherwise the
2892 -- corresponding access component is set to null.
2894 if Is_Interface
(Typ
) then
2897 elsif Num_Ifaces
= 0 then
2898 Append_To
(Elab_Code
,
2899 Make_DT_Access_Action
(Typ
,
2900 Action
=> Set_Interface_Table
,
2902 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
2903 New_Reference_To
(RTE
(RE_Null_Address
), Loc
)))); -- null
2905 -- Generate the Interface_Table object and set the access
2906 -- component if the TSD to it.
2910 Make_Object_Declaration
(Loc
,
2911 Defining_Identifier
=> ITable
,
2912 Aliased_Present
=> True,
2913 Object_Definition
=>
2914 Make_Subtype_Indication
(Loc
,
2915 Subtype_Mark
=> New_Reference_To
2916 (RTE
(RE_Interface_Data
), Loc
),
2917 Constraint
=> Make_Index_Or_Discriminant_Constraint
(Loc
,
2918 Constraints
=> New_List
(
2919 Make_Integer_Literal
(Loc
,
2922 Append_To
(Elab_Code
,
2923 Make_DT_Access_Action
(Typ
,
2924 Action
=> Set_Interface_Table
,
2926 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
2927 Make_Attribute_Reference
(Loc
, -- Value
2928 Prefix
=> New_Reference_To
(ITable
, Loc
),
2929 Attribute_Name
=> Name_Address
))));
2933 -- Set_Num_Prim_Ops (T'Tag, Nb_Prim)
2935 if not Is_Interface
(Typ
) then
2936 Append_To
(Elab_Code
,
2937 Make_Procedure_Call_Statement
(Loc
,
2938 Name
=> New_Reference_To
(RTE
(RE_Set_Num_Prim_Ops
), Loc
),
2939 Parameter_Associations
=> New_List
(
2940 New_Reference_To
(DT_Ptr
, Loc
),
2941 Make_Integer_Literal
(Loc
, Nb_Prim
))));
2944 if Ada_Version
>= Ada_05
2945 and then not Is_Interface
(Typ
)
2946 and then not Is_Abstract
(Typ
)
2947 and then not Is_Controlled
(Typ
)
2950 -- Set_Type_Kind (T'Tag, Type_Kind (Typ));
2952 Append_To
(Elab_Code
,
2953 Make_DT_Access_Action
(Typ
,
2954 Action
=> Set_Tagged_Kind
,
2956 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
2957 Tagged_Kind
(Typ
)))); -- Value
2959 -- Generate the Select Specific Data table for synchronized
2960 -- types that implement a synchronized interface. The size
2961 -- of the table is constrained by the number of non-predefined
2962 -- primitive operations.
2964 if Is_Concurrent_Record_Type
(Typ
)
2965 and then Implements_Interface
(
2967 Kind
=> Any_Limited_Interface
,
2968 Check_Parent
=> True)
2969 and then (Nb_Prim
- Default_Prim_Op_Count
) > 0
2972 Make_Object_Declaration
(Loc
,
2973 Defining_Identifier
=> SSD
,
2974 Aliased_Present
=> True,
2975 Object_Definition
=>
2976 Make_Subtype_Indication
(Loc
,
2977 Subtype_Mark
=> New_Reference_To
(
2978 RTE
(RE_Select_Specific_Data
), Loc
),
2979 Constraint
=> Make_Index_Or_Discriminant_Constraint
(Loc
,
2980 Constraints
=> New_List
(
2981 Make_Integer_Literal
(Loc
,
2982 Nb_Prim
- Default_Prim_Op_Count
))))));
2984 -- Set the pointer to the Select Specific Data table in the TSD
2986 Append_To
(Elab_Code
,
2987 Make_DT_Access_Action
(Typ
,
2990 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
2991 Make_Attribute_Reference
(Loc
, -- Value
2992 Prefix
=> New_Reference_To
(SSD
, Loc
),
2993 Attribute_Name
=> Name_Address
))));
2997 -- Generate: Exname : constant String := full_qualified_name (typ);
2998 -- The type itself may be an anonymous parent type, so use the first
2999 -- subtype to have a user-recognizable name.
3002 Make_Object_Declaration
(Loc
,
3003 Defining_Identifier
=> Exname
,
3004 Constant_Present
=> True,
3005 Object_Definition
=> New_Reference_To
(Standard_String
, Loc
),
3007 Make_String_Literal
(Loc
,
3008 Full_Qualified_Name
(First_Subtype
(Typ
)))));
3010 -- Generate: Set_Expanded_Name (DT_Ptr, exname'Address);
3012 Append_To
(Elab_Code
,
3013 Make_DT_Access_Action
(Typ
,
3014 Action
=> Set_Expanded_Name
,
3016 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
3018 Make_Attribute_Reference
(Loc
,
3019 Prefix
=> New_Reference_To
(Exname
, Loc
),
3020 Attribute_Name
=> Name_Address
))));
3022 if not Is_Interface
(Typ
) then
3023 -- Generate: Set_Access_Level (DT_Ptr, <type's accessibility level>);
3025 Append_To
(Elab_Code
,
3026 Make_DT_Access_Action
(Typ
,
3027 Action
=> Set_Access_Level
,
3029 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
3030 Node2
=> Make_Integer_Literal
(Loc
, Type_Access_Level
(Typ
)))));
3033 if Typ
= Etype
(Typ
)
3034 or else Is_CPP_Class
(Etype
(Typ
))
3035 or else Is_Interface
(Typ
)
3038 Unchecked_Convert_To
(Generalized_Tag
,
3039 Make_Integer_Literal
(Loc
, 0));
3041 Unchecked_Convert_To
(Generalized_Tag
,
3042 Make_Integer_Literal
(Loc
, 0));
3047 (Node
(First_Elmt
(Access_Disp_Table
(Etype
(Typ
)))), Loc
);
3050 (Node
(First_Elmt
(Access_Disp_Table
(Etype
(Typ
)))), Loc
);
3053 if Typ
/= Etype
(Typ
)
3054 and then not Is_Interface
(Typ
)
3056 -- Generate: Inherit_DT (parent'tag, DT_Ptr, nb_prim of parent);
3058 if not Is_Interface
(Etype
(Typ
)) then
3059 Append_To
(Elab_Code
,
3060 Make_DT_Access_Action
(Typ
,
3061 Action
=> Inherit_DT
,
3064 Node2
=> New_Reference_To
(DT_Ptr
, Loc
),
3066 Make_Integer_Literal
(Loc
,
3067 DT_Entry_Count
(First_Tag_Component
(Etype
(Typ
)))))));
3070 -- Inherit the secondary dispatch tables of the ancestor
3072 if not Is_CPP_Class
(Etype
(Typ
)) then
3074 Sec_DT_Ancestor
: Elmt_Id
:=
3077 (Access_Disp_Table
(Etype
(Typ
))));
3078 Sec_DT_Typ
: Elmt_Id
:=
3081 (Access_Disp_Table
(Typ
)));
3083 procedure Copy_Secondary_DTs
(Typ
: Entity_Id
);
3084 -- Local procedure required to climb through the ancestors and
3085 -- copy the contents of all their secondary dispatch tables.
3087 ------------------------
3088 -- Copy_Secondary_DTs --
3089 ------------------------
3091 procedure Copy_Secondary_DTs
(Typ
: Entity_Id
) is
3096 -- Climb to the ancestor (if any) handling private types
3098 if Present
(Full_View
(Etype
(Typ
))) then
3099 if Full_View
(Etype
(Typ
)) /= Typ
then
3100 Copy_Secondary_DTs
(Full_View
(Etype
(Typ
)));
3103 elsif Etype
(Typ
) /= Typ
then
3104 Copy_Secondary_DTs
(Etype
(Typ
));
3107 if Present
(Abstract_Interfaces
(Typ
))
3108 and then not Is_Empty_Elmt_List
3109 (Abstract_Interfaces
(Typ
))
3111 Iface
:= First_Elmt
(Abstract_Interfaces
(Typ
));
3112 E
:= First_Entity
(Typ
);
3115 and then Present
(Node
(Sec_DT_Ancestor
))
3117 if Is_Tag
(E
) and then Chars
(E
) /= Name_uTag
then
3118 if not Is_Interface
(Etype
(Typ
)) then
3119 Append_To
(Elab_Code
,
3120 Make_DT_Access_Action
(Typ
,
3121 Action
=> Inherit_DT
,
3123 Node1
=> Unchecked_Convert_To
3126 (Node
(Sec_DT_Ancestor
),
3128 Node2
=> Unchecked_Convert_To
3131 (Node
(Sec_DT_Typ
), Loc
)),
3132 Node3
=> Make_Integer_Literal
(Loc
,
3133 DT_Entry_Count
(E
)))));
3136 Next_Elmt
(Sec_DT_Ancestor
);
3137 Next_Elmt
(Sec_DT_Typ
);
3144 end Copy_Secondary_DTs
;
3147 if Present
(Node
(Sec_DT_Ancestor
)) then
3149 -- Handle private types
3151 if Present
(Full_View
(Typ
)) then
3152 Copy_Secondary_DTs
(Full_View
(Typ
));
3154 Copy_Secondary_DTs
(Typ
);
3162 -- Inherit_TSD (parent'tag, DT_Ptr);
3164 Append_To
(Elab_Code
,
3165 Make_DT_Access_Action
(Typ
,
3166 Action
=> Inherit_TSD
,
3169 Node2
=> New_Reference_To
(DT_Ptr
, Loc
))));
3171 -- For types with no controlled components, generate:
3172 -- Set_RC_Offset (DT_Ptr, 0);
3174 -- For simple types with controlled components, generate:
3175 -- Set_RC_Offset (DT_Ptr, type._record_controller'position);
3177 -- For complex types with controlled components where the position
3178 -- of the record controller is not statically computable, if there are
3179 -- controlled components at this level, generate:
3180 -- Set_RC_Offset (DT_Ptr, -1);
3181 -- to indicate that the _controller field is right after the _parent
3183 -- Or if there are no controlled components at this level, generate:
3184 -- Set_RC_Offset (DT_Ptr, -2);
3185 -- to indicate that we need to get the position from the parent.
3187 if not Is_Interface
(Typ
) then
3192 if not Has_Controlled_Component
(Typ
) then
3193 Position
:= Make_Integer_Literal
(Loc
, 0);
3195 elsif Etype
(Typ
) /= Typ
3196 and then Has_Discriminants
(Etype
(Typ
))
3198 if Has_New_Controlled_Component
(Typ
) then
3199 Position
:= Make_Integer_Literal
(Loc
, -1);
3201 Position
:= Make_Integer_Literal
(Loc
, -2);
3205 Make_Attribute_Reference
(Loc
,
3207 Make_Selected_Component
(Loc
,
3208 Prefix
=> New_Reference_To
(Typ
, Loc
),
3210 New_Reference_To
(Controller_Component
(Typ
), Loc
)),
3211 Attribute_Name
=> Name_Position
);
3213 -- This is not proper Ada code to use the attribute 'Position
3214 -- on something else than an object but this is supported by
3215 -- the back end (see comment on the Bit_Component attribute in
3216 -- sem_attr). So we avoid semantic checking here.
3218 -- Is this documented in sinfo.ads??? it should be!
3220 Set_Analyzed
(Position
);
3221 Set_Etype
(Prefix
(Position
), RTE
(RE_Record_Controller
));
3222 Set_Etype
(Prefix
(Prefix
(Position
)), Typ
);
3223 Set_Etype
(Selector_Name
(Prefix
(Position
)),
3224 RTE
(RE_Record_Controller
));
3225 Set_Etype
(Position
, RTE
(RE_Storage_Offset
));
3228 Append_To
(Elab_Code
,
3229 Make_DT_Access_Action
(Typ
,
3230 Action
=> Set_RC_Offset
,
3232 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
3233 Node2
=> Position
)));
3236 -- Generate: Set_Remotely_Callable (DT_Ptr, Status); where Status is
3237 -- described in E.4 (18)
3246 or else Is_Shared_Passive
(Typ
)
3248 ((Is_Remote_Types
(Typ
)
3249 or else Is_Remote_Call_Interface
(Typ
))
3250 and then Original_View_In_Visible_Part
(Typ
))
3251 or else not Comes_From_Source
(Typ
));
3253 Append_To
(Elab_Code
,
3254 Make_DT_Access_Action
(Typ
,
3255 Action
=> Set_Remotely_Callable
,
3257 New_Occurrence_Of
(DT_Ptr
, Loc
),
3258 New_Occurrence_Of
(Status
, Loc
))));
3262 -- Set_Offset_To_Top (0, DT_Ptr, 0);
3264 Append_To
(Elab_Code
,
3265 Make_Procedure_Call_Statement
(Loc
,
3266 Name
=> New_Reference_To
(RTE
(RE_Set_Offset_To_Top
), Loc
),
3267 Parameter_Associations
=> New_List
(
3268 New_Reference_To
(RTE
(RE_Null_Address
), Loc
),
3269 New_Reference_To
(DT_Ptr
, Loc
),
3270 Make_Integer_Literal
(Loc
, Uint_0
))));
3273 -- Generate: Set_External_Tag (DT_Ptr, exname'Address);
3274 -- Should be the external name not the qualified name???
3276 if not Has_External_Tag_Rep_Clause
(Typ
) then
3277 Append_To
(Elab_Code
,
3278 Make_DT_Access_Action
(Typ
,
3279 Action
=> Set_External_Tag
,
3281 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
3283 Make_Attribute_Reference
(Loc
,
3284 Prefix
=> New_Reference_To
(Exname
, Loc
),
3285 Attribute_Name
=> Name_Address
))));
3287 -- Generate code to register the Tag in the External_Tag hash
3288 -- table for the pure Ada type only.
3290 -- Register_Tag (Dt_Ptr);
3292 -- Skip this if routine not available, or in No_Run_Time mode
3293 -- or Typ is an abstract interface type (because the table to
3294 -- register it is not available in the abstract type but in
3295 -- types implementing this interface)
3297 if not No_Run_Time_Mode
3298 and then RTE_Available
(RE_Register_Tag
)
3299 and then Is_RTE
(Generalized_Tag
, RE_Tag
)
3300 and then not Is_Interface
(Typ
)
3302 Append_To
(Elab_Code
,
3303 Make_Procedure_Call_Statement
(Loc
,
3304 Name
=> New_Reference_To
(RTE
(RE_Register_Tag
), Loc
),
3305 Parameter_Associations
=>
3306 New_List
(New_Reference_To
(DT_Ptr
, Loc
))));
3316 Append_To
(Elab_Code
,
3317 Make_Assignment_Statement
(Loc
,
3318 Name
=> New_Reference_To
(No_Reg
, Loc
),
3319 Expression
=> New_Reference_To
(Standard_False
, Loc
)));
3322 Make_Implicit_If_Statement
(Typ
,
3323 Condition
=> New_Reference_To
(No_Reg
, Loc
),
3324 Then_Statements
=> Elab_Code
));
3326 -- Ada 2005 (AI-251): Register the tag of the interfaces into
3327 -- the table of implemented interfaces.
3329 if not Is_Interface
(Typ
)
3330 and then Num_Ifaces
> 0
3336 -- If the parent is an interface we must generate code to register
3337 -- all its interfaces; otherwise this code is not needed because
3338 -- Inherit_TSD has already inherited such interfaces.
3340 if Is_Interface
(Etype
(Typ
)) then
3343 AI
:= First_Elmt
(Abstract_Interfaces
(Ancestor_Copy
));
3344 while Present
(AI
) loop
3346 -- Register_Interface (DT_Ptr, Interface'Tag);
3349 Make_DT_Access_Action
(Typ
,
3350 Action
=> Register_Interface_Tag
,
3352 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
3353 Node2
=> New_Reference_To
3356 (Access_Disp_Table
(Node
(AI
)))),
3358 Node3
=> Make_Integer_Literal
(Loc
, Position
))));
3360 Position
:= Position
+ 1;
3365 -- Register the interfaces that are not implemented by the
3368 if Present
(Abstract_Interfaces
(Typ_Copy
)) then
3369 AI
:= First_Elmt
(Abstract_Interfaces
(Typ_Copy
));
3371 -- Skip the interfaces implemented by the ancestor
3373 for Count
in 1 .. Parent_Num_Ifaces
loop
3377 -- Register the additional interfaces
3379 Position
:= Parent_Num_Ifaces
+ 1;
3380 while Present
(AI
) loop
3382 -- Register_Interface (DT_Ptr, Interface'Tag);
3385 Make_DT_Access_Action
(Typ
,
3386 Action
=> Register_Interface_Tag
,
3388 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
3389 Node2
=> New_Reference_To
3392 (Access_Disp_Table
(Node
(AI
)))),
3394 Node3
=> Make_Integer_Literal
(Loc
, Position
))));
3396 Position
:= Position
+ 1;
3401 pragma Assert
(Position
= Num_Ifaces
+ 1);
3408 ---------------------------
3409 -- Make_DT_Access_Action --
3410 ---------------------------
3412 function Make_DT_Access_Action
3414 Action
: DT_Access_Action
;
3415 Args
: List_Id
) return Node_Id
3417 Action_Name
: constant Entity_Id
:= RTE
(Ada_Actions
(Action
));
3423 -- This is a constant
3425 return New_Reference_To
(Action_Name
, Sloc
(Typ
));
3428 pragma Assert
(List_Length
(Args
) = Action_Nb_Arg
(Action
));
3430 Loc
:= Sloc
(First
(Args
));
3432 if Action_Is_Proc
(Action
) then
3434 Make_Procedure_Call_Statement
(Loc
,
3435 Name
=> New_Reference_To
(Action_Name
, Loc
),
3436 Parameter_Associations
=> Args
);
3440 Make_Function_Call
(Loc
,
3441 Name
=> New_Reference_To
(Action_Name
, Loc
),
3442 Parameter_Associations
=> Args
);
3444 end Make_DT_Access_Action
;
3446 -----------------------
3447 -- Make_Secondary_DT --
3448 -----------------------
3450 procedure Make_Secondary_DT
3452 Ancestor_Typ
: Entity_Id
;
3456 Acc_Disp_Tables
: in out Elist_Id
;
3457 Result
: out List_Id
)
3459 Loc
: constant Source_Ptr
:= Sloc
(AI_Tag
);
3460 Generalized_Tag
: constant Entity_Id
:= RTE
(RE_Interface_Tag
);
3461 Name_DT
: constant Name_Id
:= New_Internal_Name
('T');
3463 Iface_DT_Ptr
: Node_Id
;
3464 Name_DT_Ptr
: Name_Id
;
3467 Size_Expr_Node
: Node_Id
;
3473 -- Generate a unique external name associated with the secondary
3474 -- dispatch table. This external name will be used to declare an
3475 -- access to this secondary dispatch table, value that will be used
3476 -- for the elaboration of Typ's objects and also for the elaboration
3477 -- of objects of any derivation of Typ that do not override any
3478 -- primitive operation of Typ.
3480 Get_Secondary_DT_External_Name
(Typ
, Ancestor_Typ
, Suffix_Index
);
3483 Name_DT_Ptr
:= New_External_Name
(Tname
, "P");
3484 Iface_DT
:= Make_Defining_Identifier
(Loc
, Name_DT
);
3485 Iface_DT_Ptr
:= Make_Defining_Identifier
(Loc
, Name_DT_Ptr
);
3487 -- Dispatch table and related entities are allocated statically
3489 Set_Ekind
(Iface_DT
, E_Variable
);
3490 Set_Is_Statically_Allocated
(Iface_DT
);
3492 Set_Ekind
(Iface_DT_Ptr
, E_Variable
);
3493 Set_Is_Statically_Allocated
(Iface_DT_Ptr
);
3495 -- Generate code to create the storage for the Dispatch_Table object.
3496 -- If the number of primitives of Typ is less that the number of
3497 -- predefined primitives, we must reserve at least enough space
3498 -- for the predefined primitives.
3500 Nb_Prim
:= UI_To_Int
(DT_Entry_Count
(AI_Tag
));
3502 if Nb_Prim
< Default_Prim_Op_Count
then
3503 Nb_Prim
:= Default_Prim_Op_Count
;
3506 -- DT : Storage_Array (1..DT_Prologue_Size+nb_prim*DT_Entry_Size);
3507 -- for DT'Alignment use Address'Alignment
3511 Left_Opnd
=> Make_DT_Access_Action
(Etype
(AI_Tag
),
3515 Make_Op_Multiply
(Loc
,
3517 Make_DT_Access_Action
(Etype
(AI_Tag
),
3521 Make_Integer_Literal
(Loc
, Nb_Prim
)));
3524 Make_Object_Declaration
(Loc
,
3525 Defining_Identifier
=> Iface_DT
,
3526 Aliased_Present
=> True,
3527 Object_Definition
=>
3528 Make_Subtype_Indication
(Loc
,
3529 Subtype_Mark
=> New_Reference_To
(RTE
(RE_Storage_Array
), Loc
),
3530 Constraint
=> Make_Index_Or_Discriminant_Constraint
(Loc
,
3531 Constraints
=> New_List
(
3533 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
3534 High_Bound
=> Size_Expr_Node
))))));
3537 Make_Attribute_Definition_Clause
(Loc
,
3538 Name
=> New_Reference_To
(Iface_DT
, Loc
),
3539 Chars
=> Name_Alignment
,
3541 Make_Attribute_Reference
(Loc
,
3542 Prefix
=> New_Reference_To
(RTE
(RE_Integer_Address
), Loc
),
3543 Attribute_Name
=> Name_Alignment
)));
3545 -- Initialize the signature of the interface tag. It is a sequence of
3546 -- two bytes located in the header of the dispatch table. The signature
3547 -- of a Secondary Dispatch Table is (Valid_Signature, Secondary_DT).
3550 Make_Assignment_Statement
(Loc
,
3552 Make_Indexed_Component
(Loc
,
3553 Prefix
=> New_Occurrence_Of
(Iface_DT
, Loc
),
3554 Expressions
=> New_List
(
3555 Make_Integer_Literal
(Loc
, Uint_1
))),
3557 Unchecked_Convert_To
(RTE
(RE_Storage_Element
),
3558 New_Reference_To
(RTE
(RE_Valid_Signature
), Loc
))));
3561 Make_Assignment_Statement
(Loc
,
3563 Make_Indexed_Component
(Loc
,
3564 Prefix
=> New_Occurrence_Of
(Iface_DT
, Loc
),
3565 Expressions
=> New_List
(
3566 Make_Integer_Literal
(Loc
, Uint_2
))),
3568 Unchecked_Convert_To
(RTE
(RE_Storage_Element
),
3569 New_Reference_To
(RTE
(RE_Secondary_DT
), Loc
))));
3571 -- Generate code to create the pointer to the dispatch table
3573 -- Iface_DT_Ptr : Tag := Tag!(DT'Address);
3575 -- According to the C++ ABI, the base of the vtable is located
3576 -- after the following prologue: Offset_To_Top, and Typeinfo_Ptr.
3577 -- Hence, move the pointer down to the real base of the vtable.
3580 Make_Object_Declaration
(Loc
,
3581 Defining_Identifier
=> Iface_DT_Ptr
,
3582 Constant_Present
=> True,
3583 Object_Definition
=> New_Reference_To
(Generalized_Tag
, Loc
),
3585 Unchecked_Convert_To
(Generalized_Tag
,
3588 Unchecked_Convert_To
(RTE
(RE_Storage_Offset
),
3589 Make_Attribute_Reference
(Loc
,
3590 Prefix
=> New_Reference_To
(Iface_DT
, Loc
),
3591 Attribute_Name
=> Name_Address
)),
3593 Make_DT_Access_Action
(Etype
(AI_Tag
),
3594 DT_Prologue_Size
, No_List
)))));
3596 -- Note: Offset_To_Top will be initialized by the init subprogram
3598 -- Set Access_Disp_Table field to be the dispatch table pointer
3600 if not (Present
(Acc_Disp_Tables
)) then
3601 Acc_Disp_Tables
:= New_Elmt_List
;
3604 Append_Elmt
(Iface_DT_Ptr
, Acc_Disp_Tables
);
3606 -- Step 1: Generate an Object Specific Data (OSD) table
3608 OSD
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('I'));
3611 -- OSD : Ada.Tags.Object_Specific_Data
3612 -- (Nb_Prims - Default_Prim_Op_Count);
3613 -- where the constraint is used to allocate space for the
3614 -- non-predefined primitive operations only.
3617 Make_Object_Declaration
(Loc
,
3618 Defining_Identifier
=> OSD
,
3619 Object_Definition
=>
3620 Make_Subtype_Indication
(Loc
,
3621 Subtype_Mark
=> New_Reference_To
(
3622 RTE
(RE_Object_Specific_Data
), Loc
),
3624 Make_Index_Or_Discriminant_Constraint
(Loc
,
3625 Constraints
=> New_List
(
3626 Make_Integer_Literal
(Loc
,
3627 Nb_Prim
- Default_Prim_Op_Count
+ 1))))));
3630 -- Ada.Tags.Set_OSD (Iface_DT_Ptr, OSD);
3633 Make_DT_Access_Action
(Typ
,
3636 Unchecked_Convert_To
(RTE
(RE_Tag
),
3637 New_Reference_To
(Iface_DT_Ptr
, Loc
)),
3638 Make_Attribute_Reference
(Loc
,
3639 Prefix
=> New_Reference_To
(OSD
, Loc
),
3640 Attribute_Name
=> Name_Address
))));
3643 -- Set_Num_Prim_Ops (T'Tag, Nb_Prim)
3646 Make_Procedure_Call_Statement
(Loc
,
3647 Name
=> New_Reference_To
(RTE
(RE_Set_Num_Prim_Ops
), Loc
),
3648 Parameter_Associations
=> New_List
(
3649 Unchecked_Convert_To
(RTE
(RE_Tag
),
3650 New_Reference_To
(Iface_DT_Ptr
, Loc
)),
3651 Make_Integer_Literal
(Loc
, Nb_Prim
))));
3653 if Ada_Version
>= Ada_05
3654 and then not Is_Interface
(Typ
)
3655 and then not Is_Abstract
(Typ
)
3656 and then not Is_Controlled
(Typ
)
3659 -- Set_Tagged_Kind (Iface'Tag, Tagged_Kind (Iface));
3662 Make_DT_Access_Action
(Typ
,
3663 Action
=> Set_Tagged_Kind
,
3665 Unchecked_Convert_To
(RTE
(RE_Tag
), -- DTptr
3666 New_Reference_To
(Iface_DT_Ptr
, Loc
)),
3667 Tagged_Kind
(Typ
)))); -- Value
3669 if Is_Concurrent_Record_Type
(Typ
)
3670 and then Implements_Interface
(
3672 Kind
=> Any_Limited_Interface
,
3673 Check_Parent
=> True)
3674 and then (Nb_Prim
- Default_Prim_Op_Count
) > 0
3678 Prim_Alias
: Entity_Id
;
3679 Prim_Elmt
: Elmt_Id
;
3682 -- Step 2: Populate the OSD table
3684 Prim_Alias
:= Empty
;
3685 Prim_Elmt
:= First_Elmt
(Primitive_Operations
(Typ
));
3686 while Present
(Prim_Elmt
) loop
3687 Prim
:= Node
(Prim_Elmt
);
3689 if Present
(Abstract_Interface_Alias
(Prim
)) then
3690 Prim_Alias
:= Abstract_Interface_Alias
(Prim
);
3693 if Present
(Prim_Alias
)
3694 and then Present
(First_Entity
(Prim_Alias
))
3695 and then Etype
(First_Entity
(Prim_Alias
)) = Iface
3698 -- Ada.Tags.Set_Offset_Index (Tag (Iface_DT_Ptr),
3699 -- Secondary_DT_Pos, Primary_DT_pos);
3702 Make_DT_Access_Action
(Iface
,
3703 Action
=> Set_Offset_Index
,
3705 Unchecked_Convert_To
(RTE
(RE_Tag
),
3706 New_Reference_To
(Iface_DT_Ptr
, Loc
)),
3707 Make_Integer_Literal
(Loc
,
3708 DT_Position
(Prim_Alias
)),
3709 Make_Integer_Literal
(Loc
,
3710 DT_Position
(Prim
)))));
3712 Prim_Alias
:= Empty
;
3715 Next_Elmt
(Prim_Elmt
);
3720 end Make_Secondary_DT
;
3722 -------------------------------------
3723 -- Make_Select_Specific_Data_Table --
3724 -------------------------------------
3726 function Make_Select_Specific_Data_Table
3727 (Typ
: Entity_Id
) return List_Id
3729 Assignments
: constant List_Id
:= New_List
;
3730 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
3732 Conc_Typ
: Entity_Id
;
3736 Prim_Als
: Entity_Id
;
3737 Prim_Elmt
: Elmt_Id
;
3741 type Examined_Array
is array (Int
range <>) of Boolean;
3743 function Find_Entry_Index
(E
: Entity_Id
) return Uint
;
3744 -- Given an entry, find its index in the visible declarations of the
3745 -- corresponding concurrent type of Typ.
3747 ----------------------
3748 -- Find_Entry_Index --
3749 ----------------------
3751 function Find_Entry_Index
(E
: Entity_Id
) return Uint
is
3752 Index
: Uint
:= Uint_1
;
3753 Subp_Decl
: Entity_Id
;
3757 and then not Is_Empty_List
(Decls
)
3759 Subp_Decl
:= First
(Decls
);
3760 while Present
(Subp_Decl
) loop
3761 if Nkind
(Subp_Decl
) = N_Entry_Declaration
then
3762 if Defining_Identifier
(Subp_Decl
) = E
then
3774 end Find_Entry_Index
;
3776 -- Start of processing for Make_Select_Specific_Data_Table
3779 DT_Ptr
:= Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
3781 if Present
(Corresponding_Concurrent_Type
(Typ
)) then
3782 Conc_Typ
:= Corresponding_Concurrent_Type
(Typ
);
3784 if Ekind
(Conc_Typ
) = E_Protected_Type
then
3785 Decls
:= Visible_Declarations
(Protected_Definition
(
3786 Parent
(Conc_Typ
)));
3788 pragma Assert
(Ekind
(Conc_Typ
) = E_Task_Type
);
3789 Decls
:= Visible_Declarations
(Task_Definition
(
3790 Parent
(Conc_Typ
)));
3794 -- Count the non-predefined primitive operations
3796 Prim_Elmt
:= First_Elmt
(Primitive_Operations
(Typ
));
3797 while Present
(Prim_Elmt
) loop
3798 if not Is_Predefined_Dispatching_Operation
(Node
(Prim_Elmt
)) then
3799 Nb_Prim
:= Nb_Prim
+ 1;
3802 Next_Elmt
(Prim_Elmt
);
3806 Examined_Size
: constant Int
:= Nb_Prim
+ Default_Prim_Op_Count
;
3807 Examined
: Examined_Array
(1 .. Examined_Size
) := (others => False);
3810 Prim_Elmt
:= First_Elmt
(Primitive_Operations
(Typ
));
3811 while Present
(Prim_Elmt
) loop
3812 Prim
:= Node
(Prim_Elmt
);
3813 Prim_Pos
:= DT_Position
(Prim
);
3815 pragma Assert
(UI_To_Int
(Prim_Pos
) <= Examined_Size
);
3817 if Examined
(UI_To_Int
(Prim_Pos
)) then
3820 Examined
(UI_To_Int
(Prim_Pos
)) := True;
3823 -- The current primitive overrides an interface-level subprogram
3825 if Present
(Abstract_Interface_Alias
(Prim
)) then
3827 -- Set the primitive operation kind regardless of subprogram
3829 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
3831 Append_To
(Assignments
,
3832 Make_DT_Access_Action
(Typ
,
3837 New_Reference_To
(DT_Ptr
, Loc
),
3838 Make_Integer_Literal
(Loc
, Prim_Pos
),
3839 Prim_Op_Kind
(Prim
, Typ
))));
3841 -- Retrieve the root of the alias chain if one is present
3843 if Present
(Alias
(Prim
)) then
3845 while Present
(Alias
(Prim_Als
)) loop
3846 Prim_Als
:= Alias
(Prim_Als
);
3852 -- In the case of an entry wrapper, set the entry index
3854 if Ekind
(Prim
) = E_Procedure
3855 and then Present
(Prim_Als
)
3856 and then Is_Primitive_Wrapper
(Prim_Als
)
3857 and then Ekind
(Wrapped_Entity
(Prim_Als
)) = E_Entry
3861 -- Ada.Tags.Set_Entry_Index (DT_Ptr, <position>, <index>);
3863 Append_To
(Assignments
,
3864 Make_DT_Access_Action
(Typ
,
3869 New_Reference_To
(DT_Ptr
, Loc
),
3870 Make_Integer_Literal
(Loc
, Prim_Pos
),
3871 Make_Integer_Literal
(Loc
,
3872 Find_Entry_Index
(Wrapped_Entity
(Prim_Als
))))));
3878 Next_Elmt
(Prim_Elmt
);
3883 end Make_Select_Specific_Data_Table
;
3885 -----------------------------------
3886 -- Original_View_In_Visible_Part --
3887 -----------------------------------
3889 function Original_View_In_Visible_Part
(Typ
: Entity_Id
) return Boolean is
3890 Scop
: constant Entity_Id
:= Scope
(Typ
);
3893 -- The scope must be a package
3895 if Ekind
(Scop
) /= E_Package
3896 and then Ekind
(Scop
) /= E_Generic_Package
3901 -- A type with a private declaration has a private view declared in
3902 -- the visible part.
3904 if Has_Private_Declaration
(Typ
) then
3908 return List_Containing
(Parent
(Typ
)) =
3909 Visible_Declarations
(Specification
(Unit_Declaration_Node
(Scop
)));
3910 end Original_View_In_Visible_Part
;
3916 function Prim_Op_Kind
3918 Typ
: Entity_Id
) return Node_Id
3920 Full_Typ
: Entity_Id
:= Typ
;
3921 Loc
: constant Source_Ptr
:= Sloc
(Prim
);
3922 Prim_Op
: Entity_Id
:= Prim
;
3925 -- Retrieve the original primitive operation
3927 while Present
(Alias
(Prim_Op
)) loop
3928 Prim_Op
:= Alias
(Prim_Op
);
3931 if Ekind
(Typ
) = E_Record_Type
3932 and then Present
(Corresponding_Concurrent_Type
(Typ
))
3934 Full_Typ
:= Corresponding_Concurrent_Type
(Typ
);
3937 if Ekind
(Prim_Op
) = E_Function
then
3939 -- Protected function
3941 if Ekind
(Full_Typ
) = E_Protected_Type
then
3942 return New_Reference_To
(RTE
(RE_POK_Protected_Function
), Loc
);
3946 elsif Ekind
(Full_Typ
) = E_Task_Type
then
3947 return New_Reference_To
(RTE
(RE_POK_Task_Function
), Loc
);
3952 return New_Reference_To
(RTE
(RE_POK_Function
), Loc
);
3956 pragma Assert
(Ekind
(Prim_Op
) = E_Procedure
);
3958 if Ekind
(Full_Typ
) = E_Protected_Type
then
3962 if Is_Primitive_Wrapper
(Prim_Op
)
3963 and then Ekind
(Wrapped_Entity
(Prim_Op
)) = E_Entry
3965 return New_Reference_To
(RTE
(RE_POK_Protected_Entry
), Loc
);
3967 -- Protected procedure
3970 return New_Reference_To
(RTE
(RE_POK_Protected_Procedure
), Loc
);
3973 elsif Ekind
(Full_Typ
) = E_Task_Type
then
3977 if Is_Primitive_Wrapper
(Prim_Op
)
3978 and then Ekind
(Wrapped_Entity
(Prim_Op
)) = E_Entry
3980 return New_Reference_To
(RTE
(RE_POK_Task_Entry
), Loc
);
3982 -- Task "procedure". These are the internally Expander-generated
3983 -- procedures (task body for instance).
3986 return New_Reference_To
(RTE
(RE_POK_Task_Procedure
), Loc
);
3989 -- Regular procedure
3992 return New_Reference_To
(RTE
(RE_POK_Procedure
), Loc
);
3997 -------------------------
3998 -- Set_All_DT_Position --
3999 -------------------------
4001 procedure Set_All_DT_Position
(Typ
: Entity_Id
) is
4002 Parent_Typ
: constant Entity_Id
:= Etype
(Typ
);
4003 Root_Typ
: constant Entity_Id
:= Root_Type
(Typ
);
4004 First_Prim
: constant Elmt_Id
:= First_Elmt
(Primitive_Operations
(Typ
));
4005 The_Tag
: constant Entity_Id
:= First_Tag_Component
(Typ
);
4007 Adjusted
: Boolean := False;
4008 Finalized
: Boolean := False;
4015 Prim_Elmt
: Elmt_Id
;
4017 procedure Validate_Position
(Prim
: Entity_Id
);
4018 -- Check that the position assignated to Prim is completely safe
4019 -- (it has not been assigned to a previously defined primitive
4020 -- operation of Typ)
4022 -----------------------
4023 -- Validate_Position --
4024 -----------------------
4026 procedure Validate_Position
(Prim
: Entity_Id
) is
4027 Prim_Elmt
: Elmt_Id
;
4030 Prim_Elmt
:= First_Elmt
(Primitive_Operations
(Typ
));
4031 while Present
(Prim_Elmt
)
4032 and then Node
(Prim_Elmt
) /= Prim
4034 -- Primitive operations covering abstract interfaces are
4037 if Present
(Abstract_Interface_Alias
(Node
(Prim_Elmt
))) then
4040 -- Predefined dispatching operations are completely safe.
4041 -- They are allocated at fixed positions.
4043 elsif Is_Predefined_Dispatching_Operation
(Node
(Prim_Elmt
)) then
4046 -- Aliased subprograms are safe
4048 elsif Present
(Alias
(Prim
)) then
4051 elsif DT_Position
(Node
(Prim_Elmt
)) = DT_Position
(Prim
) then
4053 -- Handle aliased subprograms
4060 Op_1
:= Node
(Prim_Elmt
);
4062 if Present
(Overridden_Operation
(Op_1
)) then
4063 Op_1
:= Overridden_Operation
(Op_1
);
4064 elsif Present
(Alias
(Op_1
)) then
4065 Op_1
:= Alias
(Op_1
);
4073 if Present
(Overridden_Operation
(Op_2
)) then
4074 Op_2
:= Overridden_Operation
(Op_2
);
4075 elsif Present
(Alias
(Op_2
)) then
4076 Op_2
:= Alias
(Op_2
);
4082 if Op_1
/= Op_2
then
4083 raise Program_Error
;
4088 Next_Elmt
(Prim_Elmt
);
4090 end Validate_Position
;
4092 -- Start of processing for Set_All_DT_Position
4095 -- Get Entry_Count of the parent
4097 if Parent_Typ
/= Typ
4098 and then DT_Entry_Count
(First_Tag_Component
(Parent_Typ
)) /= No_Uint
4100 Parent_EC
:= UI_To_Int
(DT_Entry_Count
4101 (First_Tag_Component
(Parent_Typ
)));
4106 -- C++ Case, check that pragma CPP_Class, CPP_Virtual and CPP_Vtable
4107 -- give a coherent set of information
4109 if Is_CPP_Class
(Root_Typ
) then
4111 -- Compute the number of primitive operations in the main Vtable
4112 -- Set their position:
4113 -- - where it was set if overriden or inherited
4114 -- - after the end of the parent vtable otherwise
4116 Prim_Elmt
:= First_Prim
;
4118 while Present
(Prim_Elmt
) loop
4119 Prim
:= Node
(Prim_Elmt
);
4121 if not Is_CPP_Class
(Typ
) then
4122 Set_DTC_Entity
(Prim
, The_Tag
);
4124 elsif Present
(Alias
(Prim
)) then
4125 Set_DTC_Entity
(Prim
, DTC_Entity
(Alias
(Prim
)));
4126 Set_DT_Position
(Prim
, DT_Position
(Alias
(Prim
)));
4128 elsif No
(DTC_Entity
(Prim
)) and then Is_CPP_Class
(Typ
) then
4129 Error_Msg_NE
("is a primitive operation of&," &
4130 " pragma Cpp_Virtual required", Prim
, Typ
);
4133 if DTC_Entity
(Prim
) = The_Tag
then
4135 -- Get the slot from the parent subprogram if any
4141 H
:= Homonym
(Prim
);
4142 while Present
(H
) loop
4143 if Present
(DTC_Entity
(H
))
4144 and then Root_Type
(Scope
(DTC_Entity
(H
))) = Root_Typ
4146 Set_DT_Position
(Prim
, DT_Position
(H
));
4154 -- Otherwise take the canonical slot after the end of the
4157 if DT_Position
(Prim
) = No_Uint
then
4158 Nb_Prim
:= Nb_Prim
+ 1;
4159 Set_DT_Position
(Prim
, UI_From_Int
(Parent_EC
+ Nb_Prim
));
4161 elsif UI_To_Int
(DT_Position
(Prim
)) > Parent_EC
then
4162 Nb_Prim
:= Nb_Prim
+ 1;
4166 Next_Elmt
(Prim_Elmt
);
4169 -- Check that the declared size of the Vtable is bigger or equal
4170 -- than the number of primitive operations (if bigger it means that
4171 -- some of the c++ virtual functions were not imported, that is
4174 if DT_Entry_Count
(The_Tag
) = No_Uint
4175 or else not Is_CPP_Class
(Typ
)
4177 Set_DT_Entry_Count
(The_Tag
, UI_From_Int
(Parent_EC
+ Nb_Prim
));
4179 elsif UI_To_Int
(DT_Entry_Count
(The_Tag
)) < Parent_EC
+ Nb_Prim
then
4180 Error_Msg_N
("not enough room in the Vtable for all virtual"
4181 & " functions", The_Tag
);
4184 -- Check that Positions are not duplicate nor outside the range of
4188 Size
: constant Int
:= UI_To_Int
(DT_Entry_Count
(The_Tag
));
4190 Prim_Pos_Table
: array (1 .. Size
) of Entity_Id
:=
4194 Prim_Elmt
:= First_Prim
;
4195 while Present
(Prim_Elmt
) loop
4196 Prim
:= Node
(Prim_Elmt
);
4198 if DTC_Entity
(Prim
) = The_Tag
then
4199 Pos
:= UI_To_Int
(DT_Position
(Prim
));
4201 if Pos
not in Prim_Pos_Table
'Range then
4203 ("position not in range of virtual table", Prim
);
4205 elsif Present
(Prim_Pos_Table
(Pos
)) then
4206 Error_Msg_NE
("cannot be at the same position in the"
4207 & " vtable than&", Prim
, Prim_Pos_Table
(Pos
));
4210 Prim_Pos_Table
(Pos
) := Prim
;
4214 Next_Elmt
(Prim_Elmt
);
4218 -- Generate listing showing the contents of the dispatch tables
4220 if Debug_Flag_ZZ
then
4224 -- For regular Ada tagged types, just set the DT_Position for
4225 -- each primitive operation. Perform some sanity checks to avoid
4226 -- to build completely inconsistant dispatch tables.
4228 -- Note that the _Size primitive is always set at position 1 in order
4229 -- to comply with the needs of Ada.Tags.Parent_Size (see documentation
4233 -- First stage: Set the DTC entity of all the primitive operations
4234 -- This is required to properly read the DT_Position attribute in
4235 -- the latter stages.
4237 Prim_Elmt
:= First_Prim
;
4239 while Present
(Prim_Elmt
) loop
4240 Count_Prim
:= Count_Prim
+ 1;
4241 Prim
:= Node
(Prim_Elmt
);
4243 -- Ada 2005 (AI-251)
4245 if Present
(Abstract_Interface_Alias
(Prim
))
4246 and then Is_Interface
(Scope
(DTC_Entity
4247 (Abstract_Interface_Alias
(Prim
))))
4249 Set_DTC_Entity
(Prim
,
4252 Iface
=> Scope
(DTC_Entity
4253 (Abstract_Interface_Alias
(Prim
)))));
4256 Set_DTC_Entity
(Prim
, The_Tag
);
4259 -- Clear any previous value of the DT_Position attribute. In this
4260 -- way we ensure that the final position of all the primitives is
4261 -- stablished by the following stages of this algorithm.
4263 Set_DT_Position
(Prim
, No_Uint
);
4265 Next_Elmt
(Prim_Elmt
);
4269 Fixed_Prim
: array (Int
range 0 .. Default_Prim_Op_Count
+
4270 Parent_EC
+ Count_Prim
)
4271 of Boolean := (others => False);
4276 -- Second stage: Register fixed entries
4278 Nb_Prim
:= Default_Prim_Op_Count
;
4279 Prim_Elmt
:= First_Prim
;
4280 while Present
(Prim_Elmt
) loop
4281 Prim
:= Node
(Prim_Elmt
);
4283 -- Predefined primitives have a fixed position in all the
4286 if Is_Predefined_Dispatching_Operation
(Prim
) then
4287 Set_DT_Position
(Prim
, Default_Prim_Op_Position
(Prim
));
4288 Fixed_Prim
(UI_To_Int
(DT_Position
(Prim
))) := True;
4290 -- Overriding interface primitives of an ancestor
4292 elsif DT_Position
(Prim
) = No_Uint
4293 and then Present
(Abstract_Interface_Alias
(Prim
))
4294 and then Present
(DTC_Entity
4295 (Abstract_Interface_Alias
(Prim
)))
4296 and then DT_Position
(Abstract_Interface_Alias
(Prim
))
4298 and then Is_Inherited_Operation
(Prim
)
4299 and then Is_Ancestor
(Scope
4301 (Abstract_Interface_Alias
(Prim
))),
4304 Set_DT_Position
(Prim
,
4305 DT_Position
(Abstract_Interface_Alias
(Prim
)));
4306 Set_DT_Position
(Alias
(Prim
),
4307 DT_Position
(Abstract_Interface_Alias
(Prim
)));
4308 Fixed_Prim
(UI_To_Int
(DT_Position
(Prim
))) := True;
4310 -- Overriding primitives must use the same entry as the
4311 -- overriden primitive
4313 elsif DT_Position
(Prim
) = No_Uint
4314 and then Present
(Alias
(Prim
))
4315 and then Present
(DTC_Entity
(Alias
(Prim
)))
4316 and then DT_Position
(Alias
(Prim
)) /= No_Uint
4317 and then Is_Inherited_Operation
(Prim
)
4318 and then Is_Ancestor
(Scope
(DTC_Entity
(Alias
(Prim
))), Typ
)
4321 while not (Present
(DTC_Entity
(E
))
4322 or else DT_Position
(E
) = No_Uint
)
4323 and then Present
(Alias
(E
))
4328 pragma Assert
(Present
(DTC_Entity
(E
))
4330 DT_Position
(E
) /= No_Uint
);
4332 Set_DT_Position
(Prim
, DT_Position
(E
));
4333 Fixed_Prim
(UI_To_Int
(DT_Position
(E
))) := True;
4335 -- If this is not the last element in the chain continue
4336 -- traversing the chain. This is required to properly
4337 -- handling renamed primitives
4339 while Present
(Alias
(E
)) loop
4341 Fixed_Prim
(UI_To_Int
(DT_Position
(E
))) := True;
4345 Next_Elmt
(Prim_Elmt
);
4348 -- Third stage: Fix the position of all the new primitives
4349 -- Entries associated with primitives covering interfaces
4350 -- are handled in a latter round.
4352 Prim_Elmt
:= First_Prim
;
4353 while Present
(Prim_Elmt
) loop
4354 Prim
:= Node
(Prim_Elmt
);
4356 -- Skip primitives previously set entries
4358 if DT_Position
(Prim
) /= No_Uint
then
4361 elsif Etype
(DTC_Entity
(Prim
)) /= RTE
(RE_Tag
) then
4364 -- Primitives covering interface primitives are
4367 elsif Present
(Abstract_Interface_Alias
(Prim
)) then
4371 -- Take the next available position in the DT
4374 Nb_Prim
:= Nb_Prim
+ 1;
4375 exit when not Fixed_Prim
(Nb_Prim
);
4378 Set_DT_Position
(Prim
, UI_From_Int
(Nb_Prim
));
4379 Fixed_Prim
(Nb_Prim
) := True;
4382 Next_Elmt
(Prim_Elmt
);
4386 -- Fourth stage: Complete the decoration of primitives covering
4387 -- interfaces (that is, propagate the DT_Position attribute
4388 -- from the aliased primitive)
4390 Prim_Elmt
:= First_Prim
;
4391 while Present
(Prim_Elmt
) loop
4392 Prim
:= Node
(Prim_Elmt
);
4394 if DT_Position
(Prim
) = No_Uint
4395 and then Present
(Abstract_Interface_Alias
(Prim
))
4397 -- Check if this entry will be placed in the primary DT
4399 if Etype
(DTC_Entity
(Abstract_Interface_Alias
(Prim
)))
4402 pragma Assert
(DT_Position
(Alias
(Prim
)) /= No_Uint
);
4403 Set_DT_Position
(Prim
, DT_Position
(Alias
(Prim
)));
4405 -- Otherwise it will be placed in the secondary DT
4409 (DT_Position
(Abstract_Interface_Alias
(Prim
)) /= No_Uint
);
4411 Set_DT_Position
(Prim
,
4412 DT_Position
(Abstract_Interface_Alias
(Prim
)));
4416 Next_Elmt
(Prim_Elmt
);
4419 -- Generate listing showing the contents of the dispatch tables.
4420 -- This action is done before some further static checks because
4421 -- in case of critical errors caused by a wrong dispatch table
4422 -- we need to see the contents of such table.
4424 if Debug_Flag_ZZ
then
4428 -- Final stage: Ensure that the table is correct plus some further
4429 -- verifications concerning the primitives.
4431 Prim_Elmt
:= First_Prim
;
4433 while Present
(Prim_Elmt
) loop
4434 Prim
:= Node
(Prim_Elmt
);
4436 -- At this point all the primitives MUST have a position
4437 -- in the dispatch table
4439 if DT_Position
(Prim
) = No_Uint
then
4440 raise Program_Error
;
4443 -- Calculate real size of the dispatch table
4445 if UI_To_Int
(DT_Position
(Prim
)) > DT_Length
then
4446 DT_Length
:= UI_To_Int
(DT_Position
(Prim
));
4449 -- Ensure that the asignated position in the dispatch
4452 Validate_Position
(Prim
);
4454 if Chars
(Prim
) = Name_Finalize
then
4458 if Chars
(Prim
) = Name_Adjust
then
4462 -- An abstract operation cannot be declared in the private part
4463 -- for a visible abstract type, because it could never be over-
4464 -- ridden. For explicit declarations this is checked at the
4465 -- point of declaration, but for inherited operations it must
4466 -- be done when building the dispatch table. Input is excluded
4469 if Is_Abstract
(Typ
)
4470 and then Is_Abstract
(Prim
)
4471 and then Present
(Alias
(Prim
))
4472 and then Is_Derived_Type
(Typ
)
4473 and then In_Private_Part
(Current_Scope
)
4475 List_Containing
(Parent
(Prim
)) =
4476 Private_Declarations
4477 (Specification
(Unit_Declaration_Node
(Current_Scope
)))
4478 and then Original_View_In_Visible_Part
(Typ
)
4480 -- We exclude Input and Output stream operations because
4481 -- Limited_Controlled inherits useless Input and Output
4482 -- stream operations from Root_Controlled, which can
4483 -- never be overridden.
4485 if not Is_TSS
(Prim
, TSS_Stream_Input
)
4487 not Is_TSS
(Prim
, TSS_Stream_Output
)
4490 ("abstract inherited private operation&" &
4491 " must be overridden ('R'M 3.9.3(10))",
4492 Parent
(Typ
), Prim
);
4496 Next_Elmt
(Prim_Elmt
);
4501 if Is_Controlled
(Typ
) then
4502 if not Finalized
then
4504 ("controlled type has no explicit Finalize method?", Typ
);
4506 elsif not Adjusted
then
4508 ("controlled type has no explicit Adjust method?", Typ
);
4512 -- Set the final size of the Dispatch Table
4514 Set_DT_Entry_Count
(The_Tag
, UI_From_Int
(DT_Length
));
4516 -- The derived type must have at least as many components as its
4517 -- parent (for root types, the Etype points back to itself
4518 -- and the test should not fail)
4520 -- This test fails compiling the partial view of a tagged type
4521 -- derived from an interface which defines the overriding subprogram
4522 -- in the private part. This needs further investigation???
4524 if not Has_Private_Declaration
(Typ
) then
4526 DT_Entry_Count
(The_Tag
) >=
4527 DT_Entry_Count
(First_Tag_Component
(Parent_Typ
)));
4531 end Set_All_DT_Position
;
4533 -----------------------------
4534 -- Set_Default_Constructor --
4535 -----------------------------
4537 procedure Set_Default_Constructor
(Typ
: Entity_Id
) is
4544 -- Look for the default constructor entity. For now only the
4545 -- default constructor has the flag Is_Constructor.
4547 E
:= Next_Entity
(Typ
);
4549 and then (Ekind
(E
) /= E_Function
or else not Is_Constructor
(E
))
4554 -- Create the init procedure
4558 Init
:= Make_Defining_Identifier
(Loc
, Make_Init_Proc_Name
(Typ
));
4559 Param
:= Make_Defining_Identifier
(Loc
, Name_X
);
4562 Make_Subprogram_Declaration
(Loc
,
4563 Make_Procedure_Specification
(Loc
,
4564 Defining_Unit_Name
=> Init
,
4565 Parameter_Specifications
=> New_List
(
4566 Make_Parameter_Specification
(Loc
,
4567 Defining_Identifier
=> Param
,
4568 Parameter_Type
=> New_Reference_To
(Typ
, Loc
))))));
4570 Set_Init_Proc
(Typ
, Init
);
4571 Set_Is_Imported
(Init
);
4572 Set_Interface_Name
(Init
, Interface_Name
(E
));
4573 Set_Convention
(Init
, Convention_C
);
4574 Set_Is_Public
(Init
);
4575 Set_Has_Completion
(Init
);
4577 -- If there are no constructors, mark the type as abstract since we
4578 -- won't be able to declare objects of that type.
4581 Set_Is_Abstract
(Typ
);
4583 end Set_Default_Constructor
;
4589 function Tagged_Kind
(T
: Entity_Id
) return Node_Id
is
4590 Conc_Typ
: Entity_Id
;
4591 Loc
: constant Source_Ptr
:= Sloc
(T
);
4594 pragma Assert
(Is_Tagged_Type
(T
));
4598 if Is_Abstract
(T
) then
4599 if Is_Limited_Record
(T
) then
4600 return New_Reference_To
(RTE
(RE_TK_Abstract_Limited_Tagged
), Loc
);
4602 return New_Reference_To
(RTE
(RE_TK_Abstract_Tagged
), Loc
);
4607 elsif Is_Concurrent_Record_Type
(T
) then
4608 Conc_Typ
:= Corresponding_Concurrent_Type
(T
);
4610 if Ekind
(Conc_Typ
) = E_Protected_Type
then
4611 return New_Reference_To
(RTE
(RE_TK_Protected
), Loc
);
4613 pragma Assert
(Ekind
(Conc_Typ
) = E_Task_Type
);
4614 return New_Reference_To
(RTE
(RE_TK_Task
), Loc
);
4617 -- Regular tagged kinds
4620 if Is_Limited_Record
(T
) then
4621 return New_Reference_To
(RTE
(RE_TK_Limited_Tagged
), Loc
);
4623 return New_Reference_To
(RTE
(RE_TK_Tagged
), Loc
);
4632 procedure Write_DT
(Typ
: Entity_Id
) is
4637 -- Protect this procedure against wrong usage. Required because it will
4638 -- be used directly from GDB
4640 if not (Typ
in First_Node_Id
.. Last_Node_Id
)
4641 or else not Is_Tagged_Type
(Typ
)
4643 Write_Str
("wrong usage: Write_DT must be used with tagged types");
4648 Write_Int
(Int
(Typ
));
4650 Write_Name
(Chars
(Typ
));
4652 if Is_Interface
(Typ
) then
4653 Write_Str
(" is interface");
4658 Elmt
:= First_Elmt
(Primitive_Operations
(Typ
));
4659 while Present
(Elmt
) loop
4660 Prim
:= Node
(Elmt
);
4663 -- Indicate if this primitive will be allocated in the primary
4664 -- dispatch table or in a secondary dispatch table associated
4665 -- with an abstract interface type
4667 if Present
(DTC_Entity
(Prim
)) then
4668 if Etype
(DTC_Entity
(Prim
)) = RTE
(RE_Tag
) then
4675 -- Output the node of this primitive operation and its name
4677 Write_Int
(Int
(Prim
));
4679 Write_Name
(Chars
(Prim
));
4681 -- Indicate if this primitive has an aliased primitive
4683 if Present
(Alias
(Prim
)) then
4684 Write_Str
(" (alias = ");
4685 Write_Int
(Int
(Alias
(Prim
)));
4687 -- If the DTC_Entity attribute is already set we can also output
4688 -- the name of the interface covered by this primitive (if any)
4690 if Present
(DTC_Entity
(Alias
(Prim
)))
4691 and then Is_Interface
(Scope
(DTC_Entity
(Alias
(Prim
))))
4693 Write_Str
(" from interface ");
4694 Write_Name
(Chars
(Scope
(DTC_Entity
(Alias
(Prim
)))));
4697 if Present
(Abstract_Interface_Alias
(Prim
)) then
4698 Write_Str
(", AI_Alias of ");
4699 Write_Name
(Chars
(Scope
(DTC_Entity
4700 (Abstract_Interface_Alias
(Prim
)))));
4702 Write_Int
(Int
(Abstract_Interface_Alias
(Prim
)));
4708 -- Display the final position of this primitive in its associated
4709 -- (primary or secondary) dispatch table
4711 if Present
(DTC_Entity
(Prim
))
4712 and then DT_Position
(Prim
) /= No_Uint
4714 Write_Str
(" at #");
4715 Write_Int
(UI_To_Int
(DT_Position
(Prim
)));
4718 if Is_Abstract
(Prim
) then
4719 Write_Str
(" is abstract;");