1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2006, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 ------------------------------------------------------------------------------
27 with Atree
; use Atree
;
28 with Checks
; use Checks
;
29 with Debug
; use Debug
;
30 with Einfo
; use Einfo
;
31 with Elists
; use Elists
;
32 with Errout
; use Errout
;
33 with Exp_Ch7
; use Exp_Ch7
;
34 with Exp_Dbug
; use Exp_Dbug
;
35 with Exp_Tss
; use Exp_Tss
;
36 with Exp_Util
; use Exp_Util
;
37 with 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 Restrict
; use Restrict
;
44 with Rident
; use Rident
;
45 with Rtsfind
; use Rtsfind
;
47 with Sem_Disp
; use Sem_Disp
;
48 with Sem_Res
; use Sem_Res
;
49 with Sem_Type
; use Sem_Type
;
50 with Sem_Util
; use Sem_Util
;
51 with Sinfo
; use Sinfo
;
52 with Snames
; use Snames
;
53 with Stand
; use Stand
;
54 with Tbuild
; use Tbuild
;
55 with Uintp
; use Uintp
;
57 package body Exp_Disp
is
59 --------------------------------
60 -- Select_Expansion_Utilities --
61 --------------------------------
63 -- The following package contains helper routines used in the expansion of
64 -- dispatching asynchronous, conditional and timed selects.
66 package Select_Expansion_Utilities
is
71 -- B : out Communication_Block
77 -- C : out Prim_Op_Kind
79 procedure Build_Common_Dispatching_Select_Statements
84 -- Ada 2005 (AI-345): Generate statements that are common between
85 -- asynchronous, conditional and timed select expansion.
111 end Select_Expansion_Utilities
;
113 package body Select_Expansion_Utilities
is
125 Make_Parameter_Specification
(Loc
,
126 Defining_Identifier
=>
127 Make_Defining_Identifier
(Loc
, Name_uB
),
129 New_Reference_To
(RTE
(RE_Communication_Block
), Loc
),
130 Out_Present
=> True));
143 Make_Parameter_Specification
(Loc
,
144 Defining_Identifier
=>
145 Make_Defining_Identifier
(Loc
, Name_uC
),
147 New_Reference_To
(RTE
(RE_Prim_Op_Kind
), Loc
),
148 Out_Present
=> True));
151 ------------------------------------------------
152 -- Build_Common_Dispatching_Select_Statements --
153 ------------------------------------------------
155 procedure Build_Common_Dispatching_Select_Statements
163 -- C := get_prim_op_kind (tag! (<type>VP), S);
165 -- where C is the out parameter capturing the call kind and S is the
166 -- dispatch table slot number.
169 Make_Assignment_Statement
(Loc
,
171 Make_Identifier
(Loc
, Name_uC
),
173 Make_DT_Access_Action
(Typ
,
178 Unchecked_Convert_To
(RTE
(RE_Tag
),
179 New_Reference_To
(DT_Ptr
, Loc
)),
180 Make_Identifier
(Loc
, Name_uS
)))));
184 -- if C = POK_Procedure
185 -- or else C = POK_Protected_Procedure
186 -- or else C = POK_Task_Procedure;
191 -- where F is the out parameter capturing the status of a potential
195 Make_If_Statement
(Loc
,
202 Make_Identifier
(Loc
, Name_uC
),
204 New_Reference_To
(RTE
(RE_POK_Procedure
), Loc
)),
210 Make_Identifier
(Loc
, Name_uC
),
212 New_Reference_To
(RTE
(
213 RE_POK_Protected_Procedure
), Loc
)),
217 Make_Identifier
(Loc
, Name_uC
),
219 New_Reference_To
(RTE
(
220 RE_POK_Task_Procedure
), Loc
)))),
224 Make_Assignment_Statement
(Loc
,
225 Name
=> Make_Identifier
(Loc
, Name_uF
),
226 Expression
=> New_Reference_To
(Standard_True
, Loc
)),
228 Make_Return_Statement
(Loc
))));
229 end Build_Common_Dispatching_Select_Statements
;
241 Make_Parameter_Specification
(Loc
,
242 Defining_Identifier
=>
243 Make_Defining_Identifier
(Loc
, Name_uF
),
245 New_Reference_To
(Standard_Boolean
, Loc
),
246 Out_Present
=> True));
259 Make_Parameter_Specification
(Loc
,
260 Defining_Identifier
=>
261 Make_Defining_Identifier
(Loc
, Name_uP
),
263 New_Reference_To
(RTE
(RE_Address
), Loc
)));
276 Make_Parameter_Specification
(Loc
,
277 Defining_Identifier
=>
278 Make_Defining_Identifier
(Loc
, Name_uS
),
280 New_Reference_To
(Standard_Integer
, Loc
)));
294 Make_Parameter_Specification
(Loc
,
295 Defining_Identifier
=>
296 Make_Defining_Identifier
(Loc
, Name_uT
),
298 New_Reference_To
(Typ
, Loc
),
300 Out_Present
=> True));
302 end Select_Expansion_Utilities
;
304 package SEU
renames Select_Expansion_Utilities
;
306 Ada_Actions
: constant array (DT_Access_Action
) of RE_Id
:=
307 (CW_Membership
=> RE_CW_Membership
,
308 IW_Membership
=> RE_IW_Membership
,
309 DT_Entry_Size
=> RE_DT_Entry_Size
,
310 DT_Prologue_Size
=> RE_DT_Prologue_Size
,
311 Get_Access_Level
=> RE_Get_Access_Level
,
312 Get_Entry_Index
=> RE_Get_Entry_Index
,
313 Get_External_Tag
=> RE_Get_External_Tag
,
314 Get_Predefined_Prim_Op_Address
=> RE_Get_Predefined_Prim_Op_Address
,
315 Get_Prim_Op_Address
=> RE_Get_Prim_Op_Address
,
316 Get_Prim_Op_Kind
=> RE_Get_Prim_Op_Kind
,
317 Get_RC_Offset
=> RE_Get_RC_Offset
,
318 Get_Remotely_Callable
=> RE_Get_Remotely_Callable
,
319 Get_Tagged_Kind
=> RE_Get_Tagged_Kind
,
320 Inherit_DT
=> RE_Inherit_DT
,
321 Inherit_TSD
=> RE_Inherit_TSD
,
322 Register_Interface_Tag
=> RE_Register_Interface_Tag
,
323 Register_Tag
=> RE_Register_Tag
,
324 Set_Access_Level
=> RE_Set_Access_Level
,
325 Set_Entry_Index
=> RE_Set_Entry_Index
,
326 Set_Expanded_Name
=> RE_Set_Expanded_Name
,
327 Set_External_Tag
=> RE_Set_External_Tag
,
328 Set_Interface_Table
=> RE_Set_Interface_Table
,
329 Set_Offset_Index
=> RE_Set_Offset_Index
,
330 Set_OSD
=> RE_Set_OSD
,
331 Set_Predefined_Prim_Op_Address
=> RE_Set_Predefined_Prim_Op_Address
,
332 Set_Prim_Op_Address
=> RE_Set_Prim_Op_Address
,
333 Set_Prim_Op_Kind
=> RE_Set_Prim_Op_Kind
,
334 Set_RC_Offset
=> RE_Set_RC_Offset
,
335 Set_Remotely_Callable
=> RE_Set_Remotely_Callable
,
336 Set_Signature
=> RE_Set_Signature
,
337 Set_SSD
=> RE_Set_SSD
,
338 Set_TSD
=> RE_Set_TSD
,
339 Set_Tagged_Kind
=> RE_Set_Tagged_Kind
,
340 TSD_Entry_Size
=> RE_TSD_Entry_Size
,
341 TSD_Prologue_Size
=> RE_TSD_Prologue_Size
);
343 Action_Is_Proc
: constant array (DT_Access_Action
) of Boolean :=
344 (CW_Membership
=> False,
345 IW_Membership
=> False,
346 DT_Entry_Size
=> False,
347 DT_Prologue_Size
=> False,
348 Get_Access_Level
=> False,
349 Get_Entry_Index
=> False,
350 Get_External_Tag
=> False,
351 Get_Predefined_Prim_Op_Address
=> False,
352 Get_Prim_Op_Address
=> False,
353 Get_Prim_Op_Kind
=> False,
354 Get_RC_Offset
=> False,
355 Get_Remotely_Callable
=> False,
356 Get_Tagged_Kind
=> False,
359 Register_Interface_Tag
=> True,
360 Register_Tag
=> True,
361 Set_Access_Level
=> True,
362 Set_Entry_Index
=> True,
363 Set_Expanded_Name
=> True,
364 Set_External_Tag
=> True,
365 Set_Interface_Table
=> True,
366 Set_Offset_Index
=> True,
368 Set_Predefined_Prim_Op_Address
=> True,
369 Set_Prim_Op_Address
=> True,
370 Set_Prim_Op_Kind
=> True,
371 Set_RC_Offset
=> True,
372 Set_Remotely_Callable
=> True,
373 Set_Signature
=> True,
376 Set_Tagged_Kind
=> True,
377 TSD_Entry_Size
=> False,
378 TSD_Prologue_Size
=> False);
380 Action_Nb_Arg
: constant array (DT_Access_Action
) of Int
:=
384 DT_Prologue_Size
=> 0,
385 Get_Access_Level
=> 1,
386 Get_Entry_Index
=> 2,
387 Get_External_Tag
=> 1,
388 Get_Predefined_Prim_Op_Address
=> 2,
389 Get_Prim_Op_Address
=> 2,
390 Get_Prim_Op_Kind
=> 2,
392 Get_Remotely_Callable
=> 1,
393 Get_Tagged_Kind
=> 1,
396 Register_Interface_Tag
=> 3,
398 Set_Access_Level
=> 2,
399 Set_Entry_Index
=> 3,
400 Set_Expanded_Name
=> 2,
401 Set_External_Tag
=> 2,
402 Set_Interface_Table
=> 2,
403 Set_Offset_Index
=> 3,
405 Set_Predefined_Prim_Op_Address
=> 3,
406 Set_Prim_Op_Address
=> 3,
407 Set_Prim_Op_Kind
=> 3,
409 Set_Remotely_Callable
=> 2,
413 Set_Tagged_Kind
=> 2,
415 TSD_Prologue_Size
=> 0);
417 procedure Collect_All_Interfaces
(T
: Entity_Id
);
418 -- Ada 2005 (AI-251): Collect the whole list of interfaces that are
419 -- directly or indirectly implemented by T. Used to compute the size
420 -- of the table of interfaces.
422 function Default_Prim_Op_Position
(E
: Entity_Id
) return Uint
;
423 -- Ada 2005 (AI-251): Returns the fixed position in the dispatch table
424 -- of the default primitive operations.
426 function Original_View_In_Visible_Part
(Typ
: Entity_Id
) return Boolean;
427 -- Check if the type has a private view or if the public view appears
428 -- in the visible part of a package spec.
430 function Prim_Op_Kind
432 Typ
: Entity_Id
) return Node_Id
;
433 -- Ada 2005 (AI-345): Determine the primitive operation kind of Prim
434 -- according to its type Typ. Return a reference to an RE_Prim_Op_Kind
435 -- enumeration value.
437 function Tagged_Kind
(T
: Entity_Id
) return Node_Id
;
438 -- Ada 2005 (AI-345): Determine the tagged kind of T and return a reference
439 -- to an RE_Tagged_Kind enumeration value.
441 ----------------------------
442 -- Collect_All_Interfaces --
443 ----------------------------
445 procedure Collect_All_Interfaces
(T
: Entity_Id
) is
447 procedure Add_Interface
(Iface
: Entity_Id
);
448 -- Add the interface it if is not already in the list
450 procedure Collect
(Typ
: Entity_Id
);
451 -- Subsidiary subprogram used to traverse the whole list
452 -- of directly and indirectly implemented interfaces
458 procedure Add_Interface
(Iface
: Entity_Id
) is
462 Elmt
:= First_Elmt
(Abstract_Interfaces
(T
));
463 while Present
(Elmt
) and then Node
(Elmt
) /= Iface
loop
468 Append_Elmt
(Iface
, Abstract_Interfaces
(T
));
476 procedure Collect
(Typ
: Entity_Id
) is
477 Ancestor
: Entity_Id
;
483 if Ekind
(Typ
) = E_Record_Type_With_Private
then
484 Nod
:= Type_Definition
(Parent
(Full_View
(Typ
)));
486 Nod
:= Type_Definition
(Parent
(Typ
));
490 or else Nkind
(Nod
) = N_Derived_Type_Definition
491 or else Nkind
(Nod
) = N_Record_Definition
);
493 -- Include the ancestor if we are generating the whole list
494 -- of interfaces. This is used to know the size of the table
495 -- that stores the tag of all the ancestor interfaces.
497 Ancestor
:= Etype
(Typ
);
499 if Ancestor
/= Typ
then
503 if Is_Interface
(Ancestor
) then
504 Add_Interface
(Ancestor
);
507 -- Traverse the graph of ancestor interfaces
509 if Is_Non_Empty_List
(Interface_List
(Nod
)) then
510 Id
:= First
(Interface_List
(Nod
));
511 while Present
(Id
) loop
514 if Is_Interface
(Iface
) then
515 Add_Interface
(Iface
);
524 -- Start of processing for Collect_All_Interfaces
528 end Collect_All_Interfaces
;
530 ------------------------------
531 -- Default_Prim_Op_Position --
532 ------------------------------
534 function Default_Prim_Op_Position
(E
: Entity_Id
) return Uint
is
535 TSS_Name
: TSS_Name_Type
;
538 Get_Name_String
(Chars
(E
));
541 (Name_Buffer
(Name_Len
- TSS_Name
'Length + 1 .. Name_Len
));
543 if Chars
(E
) = Name_uSize
then
546 elsif Chars
(E
) = Name_uAlignment
then
549 elsif TSS_Name
= TSS_Stream_Read
then
552 elsif TSS_Name
= TSS_Stream_Write
then
555 elsif TSS_Name
= TSS_Stream_Input
then
558 elsif TSS_Name
= TSS_Stream_Output
then
561 elsif Chars
(E
) = Name_Op_Eq
then
564 elsif Chars
(E
) = Name_uAssign
then
567 elsif TSS_Name
= TSS_Deep_Adjust
then
570 elsif TSS_Name
= TSS_Deep_Finalize
then
573 elsif Ada_Version
>= Ada_05
then
574 if Chars
(E
) = Name_uDisp_Asynchronous_Select
then
577 elsif Chars
(E
) = Name_uDisp_Conditional_Select
then
580 elsif Chars
(E
) = Name_uDisp_Get_Prim_Op_Kind
then
583 elsif Chars
(E
) = Name_uDisp_Get_Task_Id
then
586 elsif Chars
(E
) = Name_uDisp_Timed_Select
then
592 end Default_Prim_Op_Position
;
594 -----------------------------
595 -- Expand_Dispatching_Call --
596 -----------------------------
598 procedure Expand_Dispatching_Call
(Call_Node
: Node_Id
) is
599 Loc
: constant Source_Ptr
:= Sloc
(Call_Node
);
600 Call_Typ
: constant Entity_Id
:= Etype
(Call_Node
);
602 Ctrl_Arg
: constant Node_Id
:= Controlling_Argument
(Call_Node
);
603 Param_List
: constant List_Id
:= Parameter_Associations
(Call_Node
);
604 Subp
: Entity_Id
:= Entity
(Name
(Call_Node
));
608 New_Call_Name
: Node_Id
;
609 New_Params
: List_Id
:= No_List
;
612 Subp_Ptr_Typ
: Entity_Id
;
613 Subp_Typ
: Entity_Id
;
615 Eq_Prim_Op
: Entity_Id
:= Empty
;
616 Controlling_Tag
: Node_Id
;
618 function New_Value
(From
: Node_Id
) return Node_Id
;
619 -- From is the original Expression. New_Value is equivalent to a call
620 -- to Duplicate_Subexpr with an explicit dereference when From is an
623 function Controlling_Type
(Subp
: Entity_Id
) return Entity_Id
;
624 -- Returns the tagged type for which Subp is a primitive subprogram
630 function New_Value
(From
: Node_Id
) return Node_Id
is
631 Res
: constant Node_Id
:= Duplicate_Subexpr
(From
);
633 if Is_Access_Type
(Etype
(From
)) then
634 return Make_Explicit_Dereference
(Sloc
(From
), Res
);
640 ----------------------
641 -- Controlling_Type --
642 ----------------------
644 function Controlling_Type
(Subp
: Entity_Id
) return Entity_Id
is
646 if Ekind
(Subp
) = E_Function
647 and then Has_Controlling_Result
(Subp
)
649 return Base_Type
(Etype
(Subp
));
656 Formal
:= First_Formal
(Subp
);
657 while Present
(Formal
) loop
658 if Is_Controlling_Formal
(Formal
) then
659 if Is_Access_Type
(Etype
(Formal
)) then
660 return Base_Type
(Designated_Type
(Etype
(Formal
)));
662 return Base_Type
(Etype
(Formal
));
666 Next_Formal
(Formal
);
671 -- Controlling type not found (should never happen)
674 end Controlling_Type
;
676 -- Start of processing for Expand_Dispatching_Call
679 Check_Restriction
(No_Dispatching_Calls
, Call_Node
);
681 -- If this is an inherited operation that was overridden, the body
682 -- that is being called is its alias.
684 if Present
(Alias
(Subp
))
685 and then Is_Inherited_Operation
(Subp
)
686 and then No
(DTC_Entity
(Subp
))
688 Subp
:= Alias
(Subp
);
691 -- Expand_Dispatching_Call is called directly from the semantics,
692 -- so we need a check to see whether expansion is active before
695 if not Expander_Active
then
699 -- Definition of the class-wide type and the tagged type
701 -- If the controlling argument is itself a tag rather than a tagged
702 -- object, then use the class-wide type associated with the subprogram's
703 -- controlling type. This case can occur when a call to an inherited
704 -- primitive has an actual that originated from a default parameter
705 -- given by a tag-indeterminate call and when there is no other
706 -- controlling argument providing the tag (AI-239 requires dispatching).
707 -- This capability of dispatching directly by tag is also needed by the
708 -- implementation of AI-260 (for the generic dispatching constructors).
710 if Etype
(Ctrl_Arg
) = RTE
(RE_Tag
)
711 or else (RTE_Available
(RE_Interface_Tag
)
712 and then Etype
(Ctrl_Arg
) = RTE
(RE_Interface_Tag
))
714 CW_Typ
:= Class_Wide_Type
(Controlling_Type
(Subp
));
716 elsif Is_Access_Type
(Etype
(Ctrl_Arg
)) then
717 CW_Typ
:= Designated_Type
(Etype
(Ctrl_Arg
));
720 CW_Typ
:= Etype
(Ctrl_Arg
);
723 Typ
:= Root_Type
(CW_Typ
);
725 if Ekind
(Typ
) = E_Incomplete_Type
then
726 Typ
:= Non_Limited_View
(Typ
);
729 if not Is_Limited_Type
(Typ
) then
730 Eq_Prim_Op
:= Find_Prim_Op
(Typ
, Name_Op_Eq
);
733 if Is_CPP_Class
(Root_Type
(Typ
)) then
735 -- Create a new parameter list with the displaced 'this'
737 New_Params
:= New_List
;
738 Param
:= First_Actual
(Call_Node
);
739 while Present
(Param
) loop
740 Append_To
(New_Params
, Relocate_Node
(Param
));
744 elsif Present
(Param_List
) then
746 -- Generate the Tag checks when appropriate
748 New_Params
:= New_List
;
749 Param
:= First_Actual
(Call_Node
);
750 while Present
(Param
) loop
752 -- No tag check with itself
754 if Param
= Ctrl_Arg
then
755 Append_To
(New_Params
,
756 Duplicate_Subexpr_Move_Checks
(Param
));
758 -- No tag check for parameter whose type is neither tagged nor
759 -- access to tagged (for access parameters)
761 elsif No
(Find_Controlling_Arg
(Param
)) then
762 Append_To
(New_Params
, Relocate_Node
(Param
));
764 -- No tag check for function dispatching on result if the
765 -- Tag given by the context is this one
767 elsif Find_Controlling_Arg
(Param
) = Ctrl_Arg
then
768 Append_To
(New_Params
, Relocate_Node
(Param
));
770 -- "=" is the only dispatching operation allowed to get
771 -- operands with incompatible tags (it just returns false).
772 -- We use Duplicate_Subexpr_Move_Checks instead of calling
773 -- Relocate_Node because the value will be duplicated to
776 elsif Subp
= Eq_Prim_Op
then
777 Append_To
(New_Params
,
778 Duplicate_Subexpr_Move_Checks
(Param
));
780 -- No check in presence of suppress flags
782 elsif Tag_Checks_Suppressed
(Etype
(Param
))
783 or else (Is_Access_Type
(Etype
(Param
))
784 and then Tag_Checks_Suppressed
785 (Designated_Type
(Etype
(Param
))))
787 Append_To
(New_Params
, Relocate_Node
(Param
));
789 -- Optimization: no tag checks if the parameters are identical
791 elsif Is_Entity_Name
(Param
)
792 and then Is_Entity_Name
(Ctrl_Arg
)
793 and then Entity
(Param
) = Entity
(Ctrl_Arg
)
795 Append_To
(New_Params
, Relocate_Node
(Param
));
797 -- Now we need to generate the Tag check
800 -- Generate code for tag equality check
801 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
803 Insert_Action
(Ctrl_Arg
,
804 Make_Implicit_If_Statement
(Call_Node
,
808 Make_Selected_Component
(Loc
,
809 Prefix
=> New_Value
(Ctrl_Arg
),
812 (First_Tag_Component
(Typ
), Loc
)),
815 Make_Selected_Component
(Loc
,
817 Unchecked_Convert_To
(Typ
, New_Value
(Param
)),
820 (First_Tag_Component
(Typ
), Loc
))),
823 New_List
(New_Constraint_Error
(Loc
))));
825 Append_To
(New_Params
, Relocate_Node
(Param
));
832 -- Generate the appropriate subprogram pointer type
834 if Etype
(Subp
) = Typ
then
837 Res_Typ
:= Etype
(Subp
);
840 Subp_Typ
:= Create_Itype
(E_Subprogram_Type
, Call_Node
);
841 Subp_Ptr_Typ
:= Create_Itype
(E_Access_Subprogram_Type
, Call_Node
);
842 Set_Etype
(Subp_Typ
, Res_Typ
);
843 Init_Size_Align
(Subp_Ptr_Typ
);
844 Set_Returns_By_Ref
(Subp_Typ
, Returns_By_Ref
(Subp
));
846 -- Create a new list of parameters which is a copy of the old formal
847 -- list including the creation of a new set of matching entities.
850 Old_Formal
: Entity_Id
:= First_Formal
(Subp
);
851 New_Formal
: Entity_Id
;
855 if Present
(Old_Formal
) then
856 New_Formal
:= New_Copy
(Old_Formal
);
857 Set_First_Entity
(Subp_Typ
, New_Formal
);
858 Param
:= First_Actual
(Call_Node
);
861 Set_Scope
(New_Formal
, Subp_Typ
);
863 -- Change all the controlling argument types to be class-wide
864 -- to avoid a recursion in dispatching.
866 if Is_Controlling_Formal
(New_Formal
) then
867 Set_Etype
(New_Formal
, Etype
(Param
));
870 if Is_Itype
(Etype
(New_Formal
)) then
871 Extra
:= New_Copy
(Etype
(New_Formal
));
873 if Ekind
(Extra
) = E_Record_Subtype
874 or else Ekind
(Extra
) = E_Class_Wide_Subtype
876 Set_Cloned_Subtype
(Extra
, Etype
(New_Formal
));
879 Set_Etype
(New_Formal
, Extra
);
880 Set_Scope
(Etype
(New_Formal
), Subp_Typ
);
884 Next_Formal
(Old_Formal
);
885 exit when No
(Old_Formal
);
887 Set_Next_Entity
(New_Formal
, New_Copy
(Old_Formal
));
888 Next_Entity
(New_Formal
);
891 Set_Last_Entity
(Subp_Typ
, Extra
);
893 -- Copy extra formals
895 New_Formal
:= First_Entity
(Subp_Typ
);
896 while Present
(New_Formal
) loop
897 if Present
(Extra_Constrained
(New_Formal
)) then
898 Set_Extra_Formal
(Extra
,
899 New_Copy
(Extra_Constrained
(New_Formal
)));
900 Extra
:= Extra_Formal
(Extra
);
901 Set_Extra_Constrained
(New_Formal
, Extra
);
903 elsif Present
(Extra_Accessibility
(New_Formal
)) then
904 Set_Extra_Formal
(Extra
,
905 New_Copy
(Extra_Accessibility
(New_Formal
)));
906 Extra
:= Extra_Formal
(Extra
);
907 Set_Extra_Accessibility
(New_Formal
, Extra
);
910 Next_Formal
(New_Formal
);
915 Set_Etype
(Subp_Ptr_Typ
, Subp_Ptr_Typ
);
916 Set_Directly_Designated_Type
(Subp_Ptr_Typ
, Subp_Typ
);
918 -- If the controlling argument is a value of type Ada.Tag or an abstract
919 -- interface class-wide type then use it directly. Otherwise, the tag
920 -- must be extracted from the controlling object.
922 if Etype
(Ctrl_Arg
) = RTE
(RE_Tag
)
923 or else (RTE_Available
(RE_Interface_Tag
)
924 and then Etype
(Ctrl_Arg
) = RTE
(RE_Interface_Tag
))
926 Controlling_Tag
:= Duplicate_Subexpr
(Ctrl_Arg
);
928 -- Ada 2005 (AI-251): Abstract interface class-wide type
930 elsif Is_Interface
(Etype
(Ctrl_Arg
))
931 and then Is_Class_Wide_Type
(Etype
(Ctrl_Arg
))
933 Controlling_Tag
:= Duplicate_Subexpr
(Ctrl_Arg
);
937 Make_Selected_Component
(Loc
,
938 Prefix
=> Duplicate_Subexpr_Move_Checks
(Ctrl_Arg
),
939 Selector_Name
=> New_Reference_To
(DTC_Entity
(Subp
), Loc
));
943 -- Subp_Ptr_Typ!(Get_Prim_Op_Address (Ctrl._Tag, pos));
945 if Is_Predefined_Dispatching_Operation
(Subp
) then
947 Unchecked_Convert_To
(Subp_Ptr_Typ
,
948 Make_DT_Access_Action
(Typ
,
949 Action
=> Get_Predefined_Prim_Op_Address
,
954 Unchecked_Convert_To
(RTE
(RE_Tag
),
959 Make_Integer_Literal
(Loc
, DT_Position
(Subp
)))));
963 Unchecked_Convert_To
(Subp_Ptr_Typ
,
964 Make_DT_Access_Action
(Typ
,
965 Action
=> Get_Prim_Op_Address
,
970 Unchecked_Convert_To
(RTE
(RE_Tag
),
975 Make_Integer_Literal
(Loc
, DT_Position
(Subp
)))));
978 if Nkind
(Call_Node
) = N_Function_Call
then
980 -- Ada 2005 (AI-251): A dispatching "=" with an abstract interface
981 -- just requires the comparison of the tags.
983 if Ekind
(Etype
(Ctrl_Arg
)) = E_Class_Wide_Type
984 and then Is_Interface
(Etype
(Ctrl_Arg
))
985 and then Subp
= Eq_Prim_Op
987 Param
:= First_Actual
(Call_Node
);
992 Make_Selected_Component
(Loc
,
993 Prefix
=> New_Value
(Param
),
995 New_Reference_To
(First_Tag_Component
(Typ
), Loc
)),
998 Make_Selected_Component
(Loc
,
1000 Unchecked_Convert_To
(Typ
,
1001 New_Value
(Next_Actual
(Param
))),
1003 New_Reference_To
(First_Tag_Component
(Typ
), Loc
)));
1007 Make_Function_Call
(Loc
,
1008 Name
=> New_Call_Name
,
1009 Parameter_Associations
=> New_Params
);
1011 -- If this is a dispatching "=", we must first compare the tags so
1012 -- we generate: x.tag = y.tag and then x = y
1014 if Subp
= Eq_Prim_Op
then
1015 Param
:= First_Actual
(Call_Node
);
1021 Make_Selected_Component
(Loc
,
1022 Prefix
=> New_Value
(Param
),
1024 New_Reference_To
(First_Tag_Component
(Typ
),
1028 Make_Selected_Component
(Loc
,
1030 Unchecked_Convert_To
(Typ
,
1031 New_Value
(Next_Actual
(Param
))),
1033 New_Reference_To
(First_Tag_Component
(Typ
),
1035 Right_Opnd
=> New_Call
);
1041 Make_Procedure_Call_Statement
(Loc
,
1042 Name
=> New_Call_Name
,
1043 Parameter_Associations
=> New_Params
);
1046 Rewrite
(Call_Node
, New_Call
);
1047 Analyze_And_Resolve
(Call_Node
, Call_Typ
);
1048 end Expand_Dispatching_Call
;
1050 ---------------------------------
1051 -- Expand_Interface_Conversion --
1052 ---------------------------------
1054 procedure Expand_Interface_Conversion
1056 Is_Static
: Boolean := True)
1058 Loc
: constant Source_Ptr
:= Sloc
(N
);
1059 Operand
: constant Node_Id
:= Expression
(N
);
1060 Operand_Typ
: Entity_Id
:= Etype
(Operand
);
1061 Iface_Typ
: Entity_Id
:= Etype
(N
);
1062 Iface_Tag
: Entity_Id
;
1066 Null_Op_Nod
: Node_Id
;
1069 pragma Assert
(Nkind
(Operand
) /= N_Attribute_Reference
);
1071 -- Ada 2005 (AI-345): Handle task interfaces
1073 if Ekind
(Operand_Typ
) = E_Task_Type
1074 or else Ekind
(Operand_Typ
) = E_Protected_Type
1076 Operand_Typ
:= Corresponding_Record_Type
(Operand_Typ
);
1079 -- Handle access types to interfaces
1081 if Is_Access_Type
(Iface_Typ
) then
1082 Iface_Typ
:= Etype
(Directly_Designated_Type
(Iface_Typ
));
1085 -- Handle class-wide interface types. This conversion can appear
1086 -- explicitly in the source code. Example: I'Class (Obj)
1088 if Is_Class_Wide_Type
(Iface_Typ
) then
1089 Iface_Typ
:= Etype
(Iface_Typ
);
1092 pragma Assert
(not Is_Class_Wide_Type
(Iface_Typ
)
1093 and then Is_Interface
(Iface_Typ
));
1095 if not Is_Static
then
1097 -- Give error if configurable run time and Displace not available
1099 if not RTE_Available
(RE_Displace
) then
1100 Error_Msg_CRT
("abstract interface types", N
);
1105 Make_Function_Call
(Loc
,
1106 Name
=> New_Reference_To
(RTE
(RE_Displace
), Loc
),
1107 Parameter_Associations
=> New_List
(
1108 Make_Attribute_Reference
(Loc
,
1109 Prefix
=> Relocate_Node
(Expression
(N
)),
1110 Attribute_Name
=> Name_Address
),
1112 (Node
(First_Elmt
(Access_Disp_Table
(Iface_Typ
))),
1117 -- Change the type of the data returned by IW_Convert to
1118 -- indicate that this is a dispatching call.
1121 New_Itype
: Entity_Id
;
1124 New_Itype
:= Create_Itype
(E_Anonymous_Access_Type
, N
);
1125 Set_Etype
(New_Itype
, New_Itype
);
1126 Init_Size_Align
(New_Itype
);
1127 Set_Directly_Designated_Type
(New_Itype
,
1128 Class_Wide_Type
(Iface_Typ
));
1130 Rewrite
(N
, Make_Explicit_Dereference
(Loc
,
1131 Unchecked_Convert_To
(New_Itype
,
1132 Relocate_Node
(N
))));
1139 Iface_Tag
:= Find_Interface_Tag
(Operand_Typ
, Iface_Typ
);
1140 pragma Assert
(Iface_Tag
/= Empty
);
1142 -- Keep separate access types to interfaces because one internal
1143 -- function is used to handle the null value (see following comment)
1145 if not Is_Access_Type
(Etype
(N
)) then
1147 Unchecked_Convert_To
(Etype
(N
),
1148 Make_Selected_Component
(Loc
,
1149 Prefix
=> Relocate_Node
(Expression
(N
)),
1151 New_Occurrence_Of
(Iface_Tag
, Loc
))));
1154 -- Build internal function to handle the case in which the
1155 -- actual is null. If the actual is null returns null because
1156 -- no displacement is required; otherwise performs a type
1157 -- conversion that will be expanded in the code that returns
1158 -- the value of the displaced actual. That is:
1160 -- function Func (O : Operand_Typ) return Iface_Typ is
1165 -- return Iface_Typ!(O);
1170 Make_Defining_Identifier
(Loc
, New_Internal_Name
('F'));
1172 -- Decorate the "null" in the if-statement condition
1174 Null_Op_Nod
:= Make_Null
(Loc
);
1175 Set_Etype
(Null_Op_Nod
, Etype
(Operand
));
1176 Set_Analyzed
(Null_Op_Nod
);
1179 Make_Subprogram_Body
(Loc
,
1181 Make_Function_Specification
(Loc
,
1182 Defining_Unit_Name
=> Fent
,
1184 Parameter_Specifications
=> New_List
(
1185 Make_Parameter_Specification
(Loc
,
1186 Defining_Identifier
=>
1187 Make_Defining_Identifier
(Loc
, Name_uO
),
1189 New_Reference_To
(Etype
(Operand
), Loc
))),
1190 Result_Definition
=>
1191 New_Reference_To
(Etype
(N
), Loc
)),
1193 Declarations
=> Empty_List
,
1195 Handled_Statement_Sequence
=>
1196 Make_Handled_Sequence_Of_Statements
(Loc
,
1197 Statements
=> New_List
(
1198 Make_If_Statement
(Loc
,
1201 Left_Opnd
=> Make_Identifier
(Loc
, Name_uO
),
1202 Right_Opnd
=> Null_Op_Nod
),
1203 Then_Statements
=> New_List
(
1204 Make_Return_Statement
(Loc
,
1206 Else_Statements
=> New_List
(
1207 Make_Return_Statement
(Loc
,
1208 Unchecked_Convert_To
(Etype
(N
),
1209 Make_Attribute_Reference
(Loc
,
1211 Make_Selected_Component
(Loc
,
1212 Prefix
=> Make_Identifier
(Loc
, Name_uO
),
1214 New_Occurrence_Of
(Iface_Tag
, Loc
)),
1215 Attribute_Name
=> Name_Address
))))))));
1217 -- Insert the new declaration in the nearest enclosing scope
1218 -- that has declarations.
1221 while not Has_Declarations
(Parent
(P
)) loop
1225 if Is_List_Member
(P
) then
1226 Insert_Before
(P
, Func
);
1228 elsif Nkind
(Parent
(P
)) = N_Package_Specification
then
1229 Append_To
(Visible_Declarations
(Parent
(P
)), Func
);
1232 Append_To
(Declarations
(Parent
(P
)), Func
);
1238 Make_Function_Call
(Loc
,
1239 Name
=> New_Reference_To
(Fent
, Loc
),
1240 Parameter_Associations
=> New_List
(
1241 Relocate_Node
(Expression
(N
)))));
1245 end Expand_Interface_Conversion
;
1247 ------------------------------
1248 -- Expand_Interface_Actuals --
1249 ------------------------------
1251 procedure Expand_Interface_Actuals
(Call_Node
: Node_Id
) is
1252 Loc
: constant Source_Ptr
:= Sloc
(Call_Node
);
1254 Actual_Dup
: Node_Id
;
1255 Actual_Typ
: Entity_Id
;
1257 Conversion
: Node_Id
;
1259 Formal_Typ
: Entity_Id
;
1262 Formal_DDT
: Entity_Id
;
1263 Actual_DDT
: Entity_Id
;
1266 -- This subprogram is called directly from the semantics, so we need a
1267 -- check to see whether expansion is active before proceeding.
1269 if not Expander_Active
then
1273 -- Call using access to subprogram with explicit dereference
1275 if Nkind
(Name
(Call_Node
)) = N_Explicit_Dereference
then
1276 Subp
:= Etype
(Name
(Call_Node
));
1281 Subp
:= Entity
(Name
(Call_Node
));
1284 Formal
:= First_Formal
(Subp
);
1285 Actual
:= First_Actual
(Call_Node
);
1286 while Present
(Formal
) loop
1288 -- Ada 2005 (AI-251): Conversion to interface to force "this"
1291 Formal_Typ
:= Etype
(Etype
(Formal
));
1293 if Ekind
(Formal_Typ
) = E_Record_Type_With_Private
then
1294 Formal_Typ
:= Full_View
(Formal_Typ
);
1297 if Is_Access_Type
(Formal_Typ
) then
1298 Formal_DDT
:= Directly_Designated_Type
(Formal_Typ
);
1301 Actual_Typ
:= Etype
(Actual
);
1303 if Is_Access_Type
(Actual_Typ
) then
1304 Actual_DDT
:= Directly_Designated_Type
(Actual_Typ
);
1307 if Is_Interface
(Formal_Typ
) then
1309 -- No need to displace the pointer if the type of the actual
1310 -- is class-wide of the formal-type interface; in this case the
1311 -- displacement of the pointer was already done at the point of
1312 -- the call to the enclosing subprogram. This case corresponds
1313 -- with the call to P (Obj) in the following example:
1315 -- type I is interface;
1316 -- procedure P (X : I) is abstract;
1318 -- procedure General_Op (Obj : I'Class) is
1323 if Is_Class_Wide_Type
(Actual_Typ
)
1324 and then Etype
(Actual_Typ
) = Formal_Typ
1328 -- No need to displace the pointer if the type of the actual is a
1329 -- derivation of the formal-type interface because in this case
1330 -- the interface primitives are located in the primary dispatch
1333 elsif Is_Ancestor
(Formal_Typ
, Actual_Typ
) then
1337 Conversion
:= Convert_To
(Formal_Typ
, Relocate_Node
(Actual
));
1338 Rewrite
(Actual
, Conversion
);
1339 Analyze_And_Resolve
(Actual
, Formal_Typ
);
1342 -- Anonymous access type
1344 elsif Is_Access_Type
(Formal_Typ
)
1345 and then Is_Interface
(Etype
(Formal_DDT
))
1346 and then Interface_Present_In_Ancestor
1348 Iface
=> Etype
(Formal_DDT
))
1350 if Nkind
(Actual
) = N_Attribute_Reference
1352 (Attribute_Name
(Actual
) = Name_Access
1353 or else Attribute_Name
(Actual
) = Name_Unchecked_Access
)
1355 Nam
:= Attribute_Name
(Actual
);
1357 Conversion
:= Convert_To
(Etype
(Formal_DDT
), Prefix
(Actual
));
1359 Rewrite
(Actual
, Conversion
);
1360 Analyze_And_Resolve
(Actual
, Etype
(Formal_DDT
));
1363 Unchecked_Convert_To
(Formal_Typ
,
1364 Make_Attribute_Reference
(Loc
,
1365 Prefix
=> Relocate_Node
(Actual
),
1366 Attribute_Name
=> Nam
)));
1368 Analyze_And_Resolve
(Actual
, Formal_Typ
);
1370 -- No need to displace the pointer if the actual is a class-wide
1371 -- type of the formal-type interface because in this case the
1372 -- displacement of the pointer was already done at the point of
1373 -- the call to the enclosing subprogram (this case is similar
1374 -- to the example described above for the non access-type case)
1376 elsif Is_Class_Wide_Type
(Actual_DDT
)
1377 and then Etype
(Actual_DDT
) = Formal_DDT
1381 -- No need to displace the pointer if the type of the actual is a
1382 -- derivation of the interface (because in this case the interface
1383 -- primitives are located in the primary dispatch table)
1385 elsif Is_Ancestor
(Formal_DDT
, Actual_DDT
) then
1389 Actual_Dup
:= Relocate_Node
(Actual
);
1391 if From_With_Type
(Actual_Typ
) then
1393 -- If the type of the actual parameter comes from a limited
1394 -- with-clause and the non-limited view is already available
1395 -- we replace the anonymous access type by a duplicate decla
1396 -- ration whose designated type is the non-limited view
1398 if Ekind
(Actual_DDT
) = E_Incomplete_Type
1399 and then Present
(Non_Limited_View
(Actual_DDT
))
1401 Anon
:= New_Copy
(Actual_Typ
);
1403 if Is_Itype
(Anon
) then
1404 Set_Scope
(Anon
, Current_Scope
);
1407 Set_Directly_Designated_Type
(Anon
,
1408 Non_Limited_View
(Actual_DDT
));
1409 Set_Etype
(Actual_Dup
, Anon
);
1411 elsif Is_Class_Wide_Type
(Actual_DDT
)
1412 and then Ekind
(Etype
(Actual_DDT
)) = E_Incomplete_Type
1413 and then Present
(Non_Limited_View
(Etype
(Actual_DDT
)))
1415 Anon
:= New_Copy
(Actual_Typ
);
1417 if Is_Itype
(Anon
) then
1418 Set_Scope
(Anon
, Current_Scope
);
1421 Set_Directly_Designated_Type
(Anon
,
1422 New_Copy
(Actual_DDT
));
1423 Set_Class_Wide_Type
(Directly_Designated_Type
(Anon
),
1424 New_Copy
(Class_Wide_Type
(Actual_DDT
)));
1425 Set_Etype
(Directly_Designated_Type
(Anon
),
1426 Non_Limited_View
(Etype
(Actual_DDT
)));
1428 Class_Wide_Type
(Directly_Designated_Type
(Anon
)),
1429 Non_Limited_View
(Etype
(Actual_DDT
)));
1430 Set_Etype
(Actual_Dup
, Anon
);
1434 Conversion
:= Convert_To
(Formal_Typ
, Actual_Dup
);
1435 Rewrite
(Actual
, Conversion
);
1436 Analyze_And_Resolve
(Actual
, Formal_Typ
);
1440 Next_Actual
(Actual
);
1441 Next_Formal
(Formal
);
1443 end Expand_Interface_Actuals
;
1445 ----------------------------
1446 -- Expand_Interface_Thunk --
1447 ----------------------------
1449 function Expand_Interface_Thunk
1451 Thunk_Alias
: Entity_Id
;
1452 Thunk_Id
: Entity_Id
) return Node_Id
1454 Loc
: constant Source_Ptr
:= Sloc
(N
);
1455 Actuals
: constant List_Id
:= New_List
;
1456 Decl
: constant List_Id
:= New_List
;
1457 Formals
: constant List_Id
:= New_List
;
1461 New_Formal
: Node_Id
;
1467 -- Traverse the list of alias to find the final target
1469 Target
:= Thunk_Alias
;
1470 while Present
(Alias
(Target
)) loop
1471 Target
:= Alias
(Target
);
1474 -- Duplicate the formals
1476 Formal
:= First_Formal
(Target
);
1477 E
:= First_Formal
(N
);
1478 while Present
(Formal
) loop
1479 New_Formal
:= Copy_Separate_Tree
(Parent
(Formal
));
1481 -- Propagate the parameter type to the copy. This is required to
1482 -- properly handle the case in which the subprogram covering the
1483 -- interface has been inherited:
1486 -- type I is interface;
1487 -- procedure P (X : in I) is abstract;
1489 -- type T is tagged null record;
1490 -- procedure P (X : T);
1492 -- type DT is new T and I with ...
1494 Set_Parameter_Type
(New_Formal
, New_Reference_To
(Etype
(E
), Loc
));
1495 Append_To
(Formals
, New_Formal
);
1497 Next_Formal
(Formal
);
1501 -- Give message if configurable run-time and Offset_To_Top unavailable
1503 if not RTE_Available
(RE_Offset_To_Top
) then
1504 Error_Msg_CRT
("abstract interface types", N
);
1508 if Ekind
(First_Formal
(Target
)) = E_In_Parameter
1509 and then Ekind
(Etype
(First_Formal
(Target
)))
1510 = E_Anonymous_Access_Type
1514 -- type T is access all <<type of the first formal>>
1515 -- S1 := Storage_Offset!(First_formal)
1516 -- - Offset_To_Top (First_Formal.Tag)
1518 -- ... and the first actual of the call is generated as T!(S1)
1521 Make_Full_Type_Declaration
(Loc
,
1522 Defining_Identifier
=>
1523 Make_Defining_Identifier
(Loc
,
1524 New_Internal_Name
('T')),
1526 Make_Access_To_Object_Definition
(Loc
,
1527 All_Present
=> True,
1528 Null_Exclusion_Present
=> False,
1529 Constant_Present
=> False,
1530 Subtype_Indication
=>
1532 (Directly_Designated_Type
1533 (Etype
(First_Formal
(Target
))), Loc
)));
1536 Make_Object_Declaration
(Loc
,
1537 Defining_Identifier
=>
1538 Make_Defining_Identifier
(Loc
,
1539 New_Internal_Name
('S')),
1540 Constant_Present
=> True,
1541 Object_Definition
=>
1542 New_Reference_To
(RTE
(RE_Storage_Offset
), Loc
),
1544 Make_Op_Subtract
(Loc
,
1546 Unchecked_Convert_To
1547 (RTE
(RE_Storage_Offset
),
1549 (Defining_Identifier
(First
(Formals
)), Loc
)),
1551 Make_Function_Call
(Loc
,
1552 Name
=> New_Reference_To
(RTE
(RE_Offset_To_Top
), Loc
),
1553 Parameter_Associations
=> New_List
(
1554 Unchecked_Convert_To
1557 (Defining_Identifier
(First
(Formals
)), Loc
))))));
1559 Append_To
(Decl
, Decl_2
);
1560 Append_To
(Decl
, Decl_1
);
1562 -- Reference the new first actual
1565 Unchecked_Convert_To
1566 (Defining_Identifier
(Decl_2
),
1567 New_Reference_To
(Defining_Identifier
(Decl_1
), Loc
)));
1572 -- S1 := Storage_Offset!(First_formal'Address)
1573 -- - Offset_To_Top (First_Formal.Tag)
1574 -- S2 := Tag_Ptr!(S3)
1577 Make_Object_Declaration
(Loc
,
1578 Defining_Identifier
=>
1579 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S')),
1580 Constant_Present
=> True,
1581 Object_Definition
=>
1582 New_Reference_To
(RTE
(RE_Storage_Offset
), Loc
),
1584 Make_Op_Subtract
(Loc
,
1586 Unchecked_Convert_To
1587 (RTE
(RE_Storage_Offset
),
1588 Make_Attribute_Reference
(Loc
,
1591 (Defining_Identifier
(First
(Formals
)), Loc
),
1592 Attribute_Name
=> Name_Address
)),
1594 Make_Function_Call
(Loc
,
1595 Name
=> New_Reference_To
(RTE
(RE_Offset_To_Top
), Loc
),
1596 Parameter_Associations
=> New_List
(
1597 Make_Attribute_Reference
(Loc
,
1598 Prefix
=> New_Reference_To
1599 (Defining_Identifier
(First
(Formals
)),
1601 Attribute_Name
=> Name_Address
)))));
1604 Make_Object_Declaration
(Loc
,
1605 Defining_Identifier
=>
1606 Make_Defining_Identifier
(Loc
, New_Internal_Name
('S')),
1607 Constant_Present
=> True,
1608 Object_Definition
=> New_Reference_To
(RTE
(RE_Addr_Ptr
), Loc
),
1610 Unchecked_Convert_To
1612 New_Reference_To
(Defining_Identifier
(Decl_1
), Loc
)));
1614 Append_To
(Decl
, Decl_1
);
1615 Append_To
(Decl
, Decl_2
);
1617 -- Reference the new first actual
1620 Unchecked_Convert_To
1621 (Etype
(First_Entity
(Target
)),
1622 Make_Explicit_Dereference
(Loc
,
1623 New_Reference_To
(Defining_Identifier
(Decl_2
), Loc
))));
1626 Formal
:= Next
(First
(Formals
));
1627 while Present
(Formal
) loop
1629 New_Reference_To
(Defining_Identifier
(Formal
), Loc
));
1633 if Ekind
(Target
) = E_Procedure
then
1635 Make_Subprogram_Body
(Loc
,
1637 Make_Procedure_Specification
(Loc
,
1638 Defining_Unit_Name
=> Thunk_Id
,
1639 Parameter_Specifications
=> Formals
),
1640 Declarations
=> Decl
,
1641 Handled_Statement_Sequence
=>
1642 Make_Handled_Sequence_Of_Statements
(Loc
,
1643 Statements
=> New_List
(
1644 Make_Procedure_Call_Statement
(Loc
,
1645 Name
=> New_Occurrence_Of
(Target
, Loc
),
1646 Parameter_Associations
=> Actuals
))));
1648 else pragma Assert
(Ekind
(Target
) = E_Function
);
1651 Make_Subprogram_Body
(Loc
,
1653 Make_Function_Specification
(Loc
,
1654 Defining_Unit_Name
=> Thunk_Id
,
1655 Parameter_Specifications
=> Formals
,
1656 Result_Definition
=>
1657 New_Copy
(Result_Definition
(Parent
(Target
)))),
1658 Declarations
=> Decl
,
1659 Handled_Statement_Sequence
=>
1660 Make_Handled_Sequence_Of_Statements
(Loc
,
1661 Statements
=> New_List
(
1662 Make_Return_Statement
(Loc
,
1663 Make_Function_Call
(Loc
,
1664 Name
=> New_Occurrence_Of
(Target
, Loc
),
1665 Parameter_Associations
=> Actuals
)))));
1670 end Expand_Interface_Thunk
;
1676 function Fill_DT_Entry
1678 Prim
: Entity_Id
) return Node_Id
1680 Typ
: constant Entity_Id
:= Scope
(DTC_Entity
(Prim
));
1681 DT_Ptr
: constant Entity_Id
:=
1682 Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
1683 Pos
: constant Uint
:= DT_Position
(Prim
);
1684 Tag
: constant Entity_Id
:= First_Tag_Component
(Typ
);
1687 pragma Assert
(not Restriction_Active
(No_Dispatching_Calls
));
1689 if Is_Predefined_Dispatching_Operation
(Prim
) then
1691 Make_DT_Access_Action
(Typ
,
1692 Action
=> Set_Predefined_Prim_Op_Address
,
1694 Unchecked_Convert_To
(RTE
(RE_Tag
),
1695 New_Reference_To
(DT_Ptr
, Loc
)), -- DTptr
1697 Make_Integer_Literal
(Loc
, Pos
), -- Position
1699 Make_Attribute_Reference
(Loc
, -- Value
1700 Prefix
=> New_Reference_To
(Prim
, Loc
),
1701 Attribute_Name
=> Name_Address
)));
1703 pragma Assert
(Pos
/= Uint_0
and then Pos
<= DT_Entry_Count
(Tag
));
1706 Make_DT_Access_Action
(Typ
,
1707 Action
=> Set_Prim_Op_Address
,
1709 Unchecked_Convert_To
(RTE
(RE_Tag
),
1710 New_Reference_To
(DT_Ptr
, Loc
)), -- DTptr
1712 Make_Integer_Literal
(Loc
, Pos
), -- Position
1714 Make_Attribute_Reference
(Loc
, -- Value
1715 Prefix
=> New_Reference_To
(Prim
, Loc
),
1716 Attribute_Name
=> Name_Address
)));
1720 -----------------------------
1721 -- Fill_Secondary_DT_Entry --
1722 -----------------------------
1724 function Fill_Secondary_DT_Entry
1727 Thunk_Id
: Entity_Id
;
1728 Iface_DT_Ptr
: Entity_Id
) return Node_Id
1730 Typ
: constant Entity_Id
:= Scope
(DTC_Entity
(Alias
(Prim
)));
1731 Iface_Prim
: constant Entity_Id
:= Abstract_Interface_Alias
(Prim
);
1732 Pos
: constant Uint
:= DT_Position
(Iface_Prim
);
1733 Tag
: constant Entity_Id
:=
1734 First_Tag_Component
(Scope
(DTC_Entity
(Iface_Prim
)));
1737 if Is_Predefined_Dispatching_Operation
(Prim
) then
1739 Make_DT_Access_Action
(Typ
,
1740 Action
=> Set_Predefined_Prim_Op_Address
,
1742 Unchecked_Convert_To
(RTE
(RE_Tag
),
1743 New_Reference_To
(Iface_DT_Ptr
, Loc
)), -- DTptr
1745 Make_Integer_Literal
(Loc
, Pos
), -- Position
1747 Make_Attribute_Reference
(Loc
, -- Value
1748 Prefix
=> New_Reference_To
(Thunk_Id
, Loc
),
1749 Attribute_Name
=> Name_Address
)));
1751 pragma Assert
(Pos
/= Uint_0
and then Pos
<= DT_Entry_Count
(Tag
));
1754 Make_DT_Access_Action
(Typ
,
1755 Action
=> Set_Prim_Op_Address
,
1757 Unchecked_Convert_To
(RTE
(RE_Tag
),
1758 New_Reference_To
(Iface_DT_Ptr
, Loc
)), -- DTptr
1760 Make_Integer_Literal
(Loc
, Pos
), -- Position
1762 Make_Attribute_Reference
(Loc
, -- Value
1763 Prefix
=> New_Reference_To
(Thunk_Id
, Loc
),
1764 Attribute_Name
=> Name_Address
)));
1766 end Fill_Secondary_DT_Entry
;
1768 ---------------------------
1769 -- Get_Remotely_Callable --
1770 ---------------------------
1772 function Get_Remotely_Callable
(Obj
: Node_Id
) return Node_Id
is
1773 Loc
: constant Source_Ptr
:= Sloc
(Obj
);
1775 return Make_DT_Access_Action
1776 (Typ
=> Etype
(Obj
),
1777 Action
=> Get_Remotely_Callable
,
1779 Make_Selected_Component
(Loc
,
1781 Selector_Name
=> Make_Identifier
(Loc
, Name_uTag
))));
1782 end Get_Remotely_Callable
;
1784 ------------------------------------------
1785 -- Init_Predefined_Interface_Primitives --
1786 ------------------------------------------
1788 function Init_Predefined_Interface_Primitives
1789 (Typ
: Entity_Id
) return List_Id
1791 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
1792 DT_Ptr
: constant Node_Id
:=
1793 Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
1794 Result
: constant List_Id
:= New_List
;
1798 -- No need to inherit primitives if we have an abstract interface
1799 -- type or a concurrent type.
1801 if Is_Interface
(Typ
)
1802 or else Is_Concurrent_Record_Type
(Typ
)
1803 or else Restriction_Active
(No_Dispatching_Calls
)
1808 AI
:= Next_Elmt
(First_Elmt
(Access_Disp_Table
(Typ
)));
1809 while Present
(AI
) loop
1811 -- All the secondary tables inherit the dispatch table entries
1812 -- associated with predefined primitives.
1815 -- Inherit_DT (T'Tag, Iface'Tag, 0);
1818 Make_DT_Access_Action
(Typ
,
1819 Action
=> Inherit_DT
,
1821 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
1822 Node2
=> Unchecked_Convert_To
(RTE
(RE_Tag
),
1823 New_Reference_To
(Node
(AI
), Loc
)),
1824 Node3
=> Make_Integer_Literal
(Loc
, Uint_0
))));
1830 end Init_Predefined_Interface_Primitives
;
1832 ----------------------------------------
1833 -- Make_Disp_Asynchronous_Select_Body --
1834 ----------------------------------------
1836 function Make_Disp_Asynchronous_Select_Body
1837 (Typ
: Entity_Id
) return Node_Id
1839 Conc_Typ
: Entity_Id
:= Empty
;
1840 Decls
: constant List_Id
:= New_List
;
1842 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
1843 Stmts
: constant List_Id
:= New_List
;
1846 pragma Assert
(not Restriction_Active
(No_Dispatching_Calls
));
1848 -- Null body is generated for interface types
1850 if Is_Interface
(Typ
) then
1852 Make_Subprogram_Body
(Loc
,
1854 Make_Disp_Asynchronous_Select_Spec
(Typ
),
1857 Handled_Statement_Sequence
=>
1858 Make_Handled_Sequence_Of_Statements
(Loc
,
1859 New_List
(Make_Null_Statement
(Loc
))));
1862 DT_Ptr
:= Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
1864 if Is_Concurrent_Record_Type
(Typ
) then
1865 Conc_Typ
:= Corresponding_Concurrent_Type
(Typ
);
1868 -- I : Integer := Get_Entry_Index (tag! (<type>VP), S);
1870 -- where I will be used to capture the entry index of the primitive
1871 -- wrapper at position S.
1874 Make_Object_Declaration
(Loc
,
1875 Defining_Identifier
=>
1876 Make_Defining_Identifier
(Loc
, Name_uI
),
1877 Object_Definition
=>
1878 New_Reference_To
(Standard_Integer
, Loc
),
1880 Make_DT_Access_Action
(Typ
,
1885 Unchecked_Convert_To
(RTE
(RE_Tag
),
1886 New_Reference_To
(DT_Ptr
, Loc
)),
1887 Make_Identifier
(Loc
, Name_uS
)))));
1889 if Ekind
(Conc_Typ
) = E_Protected_Type
then
1892 -- Protected_Entry_Call (
1893 -- T._object'access,
1894 -- protected_entry_index! (I),
1896 -- Asynchronous_Call,
1899 -- where T is the protected object, I is the entry index, P are
1900 -- the wrapped parameters and B is the name of the communication
1904 Make_Procedure_Call_Statement
(Loc
,
1906 New_Reference_To
(RTE
(RE_Protected_Entry_Call
), Loc
),
1907 Parameter_Associations
=>
1910 Make_Attribute_Reference
(Loc
, -- T._object'access
1912 Name_Unchecked_Access
,
1914 Make_Selected_Component
(Loc
,
1916 Make_Identifier
(Loc
, Name_uT
),
1918 Make_Identifier
(Loc
, Name_uObject
))),
1920 Make_Unchecked_Type_Conversion
(Loc
, -- entry index
1922 New_Reference_To
(RTE
(RE_Protected_Entry_Index
), Loc
),
1924 Make_Identifier
(Loc
, Name_uI
)),
1926 Make_Identifier
(Loc
, Name_uP
), -- parameter block
1927 New_Reference_To
( -- Asynchronous_Call
1928 RTE
(RE_Asynchronous_Call
), Loc
),
1929 Make_Identifier
(Loc
, Name_uB
)))); -- comm block
1931 pragma Assert
(Ekind
(Conc_Typ
) = E_Task_Type
);
1934 -- Protected_Entry_Call (
1936 -- task_entry_index! (I),
1938 -- Conditional_Call,
1941 -- where T is the task object, I is the entry index, P are the
1942 -- wrapped parameters and F is the status flag.
1945 Make_Procedure_Call_Statement
(Loc
,
1947 New_Reference_To
(RTE
(RE_Task_Entry_Call
), Loc
),
1948 Parameter_Associations
=>
1951 Make_Selected_Component
(Loc
, -- T._task_id
1953 Make_Identifier
(Loc
, Name_uT
),
1955 Make_Identifier
(Loc
, Name_uTask_Id
)),
1957 Make_Unchecked_Type_Conversion
(Loc
, -- entry index
1959 New_Reference_To
(RTE
(RE_Task_Entry_Index
), Loc
),
1961 Make_Identifier
(Loc
, Name_uI
)),
1963 Make_Identifier
(Loc
, Name_uP
), -- parameter block
1964 New_Reference_To
( -- Asynchronous_Call
1965 RTE
(RE_Asynchronous_Call
), Loc
),
1966 Make_Identifier
(Loc
, Name_uF
)))); -- status flag
1971 Make_Subprogram_Body
(Loc
,
1973 Make_Disp_Asynchronous_Select_Spec
(Typ
),
1976 Handled_Statement_Sequence
=>
1977 Make_Handled_Sequence_Of_Statements
(Loc
, Stmts
));
1978 end Make_Disp_Asynchronous_Select_Body
;
1980 ----------------------------------------
1981 -- Make_Disp_Asynchronous_Select_Spec --
1982 ----------------------------------------
1984 function Make_Disp_Asynchronous_Select_Spec
1985 (Typ
: Entity_Id
) return Node_Id
1987 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
1988 Def_Id
: constant Node_Id
:=
1989 Make_Defining_Identifier
(Loc
,
1990 Name_uDisp_Asynchronous_Select
);
1991 Params
: constant List_Id
:= New_List
;
1994 pragma Assert
(not Restriction_Active
(No_Dispatching_Calls
));
1996 -- "T" - Object parameter
1997 -- "S" - Primitive operation slot
1998 -- "P" - Wrapped parameters
1999 -- "B" - Communication block
2000 -- "F" - Status flag
2002 SEU
.Build_T
(Loc
, Typ
, Params
);
2003 SEU
.Build_S
(Loc
, Params
);
2004 SEU
.Build_P
(Loc
, Params
);
2005 SEU
.Build_B
(Loc
, Params
);
2006 SEU
.Build_F
(Loc
, Params
);
2008 Set_Is_Internal
(Def_Id
);
2011 Make_Procedure_Specification
(Loc
,
2012 Defining_Unit_Name
=> Def_Id
,
2013 Parameter_Specifications
=> Params
);
2014 end Make_Disp_Asynchronous_Select_Spec
;
2016 ---------------------------------------
2017 -- Make_Disp_Conditional_Select_Body --
2018 ---------------------------------------
2020 function Make_Disp_Conditional_Select_Body
2021 (Typ
: Entity_Id
) return Node_Id
2023 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2024 Blk_Nam
: Entity_Id
;
2025 Conc_Typ
: Entity_Id
:= Empty
;
2026 Decls
: constant List_Id
:= New_List
;
2028 Stmts
: constant List_Id
:= New_List
;
2031 pragma Assert
(not Restriction_Active
(No_Dispatching_Calls
));
2033 -- Null body is generated for interface types
2035 if Is_Interface
(Typ
) then
2037 Make_Subprogram_Body
(Loc
,
2039 Make_Disp_Conditional_Select_Spec
(Typ
),
2042 Handled_Statement_Sequence
=>
2043 Make_Handled_Sequence_Of_Statements
(Loc
,
2044 New_List
(Make_Null_Statement
(Loc
))));
2047 DT_Ptr
:= Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
2049 if Is_Concurrent_Record_Type
(Typ
) then
2050 Conc_Typ
:= Corresponding_Concurrent_Type
(Typ
);
2055 -- where I will be used to capture the entry index of the primitive
2056 -- wrapper at position S.
2059 Make_Object_Declaration
(Loc
,
2060 Defining_Identifier
=>
2061 Make_Defining_Identifier
(Loc
, Name_uI
),
2062 Object_Definition
=>
2063 New_Reference_To
(Standard_Integer
, Loc
)));
2066 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
2068 -- if C = POK_Procedure
2069 -- or else C = POK_Protected_Procedure
2070 -- or else C = POK_Task_Procedure;
2076 SEU
.Build_Common_Dispatching_Select_Statements
2077 (Loc
, Typ
, DT_Ptr
, Stmts
);
2080 -- Bnn : Communication_Block;
2082 -- where Bnn is the name of the communication block used in
2083 -- the call to Protected_Entry_Call.
2085 Blk_Nam
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('B'));
2088 Make_Object_Declaration
(Loc
,
2089 Defining_Identifier
=>
2091 Object_Definition
=>
2092 New_Reference_To
(RTE
(RE_Communication_Block
), Loc
)));
2095 -- I := Get_Entry_Index (tag! (<type>VP), S);
2097 -- I is the entry index and S is the dispatch table slot
2100 Make_Assignment_Statement
(Loc
,
2102 Make_Identifier
(Loc
, Name_uI
),
2104 Make_DT_Access_Action
(Typ
,
2109 Unchecked_Convert_To
(RTE
(RE_Tag
),
2110 New_Reference_To
(DT_Ptr
, Loc
)),
2111 Make_Identifier
(Loc
, Name_uS
)))));
2113 if Ekind
(Conc_Typ
) = E_Protected_Type
then
2116 -- Protected_Entry_Call (
2117 -- T._object'access,
2118 -- protected_entry_index! (I),
2120 -- Conditional_Call,
2123 -- where T is the protected object, I is the entry index, P are
2124 -- the wrapped parameters and Bnn is the name of the communication
2128 Make_Procedure_Call_Statement
(Loc
,
2130 New_Reference_To
(RTE
(RE_Protected_Entry_Call
), Loc
),
2131 Parameter_Associations
=>
2134 Make_Attribute_Reference
(Loc
, -- T._object'access
2136 Name_Unchecked_Access
,
2138 Make_Selected_Component
(Loc
,
2140 Make_Identifier
(Loc
, Name_uT
),
2142 Make_Identifier
(Loc
, Name_uObject
))),
2144 Make_Unchecked_Type_Conversion
(Loc
, -- entry index
2146 New_Reference_To
(RTE
(RE_Protected_Entry_Index
), Loc
),
2148 Make_Identifier
(Loc
, Name_uI
)),
2150 Make_Identifier
(Loc
, Name_uP
), -- parameter block
2151 New_Reference_To
( -- Conditional_Call
2152 RTE
(RE_Conditional_Call
), Loc
),
2153 New_Reference_To
( -- Bnn
2157 -- F := not Cancelled (Bnn);
2159 -- where F is the success flag. The status of Cancelled is negated
2160 -- in order to match the behaviour of the version for task types.
2163 Make_Assignment_Statement
(Loc
,
2165 Make_Identifier
(Loc
, Name_uF
),
2169 Make_Function_Call
(Loc
,
2171 New_Reference_To
(RTE
(RE_Cancelled
), Loc
),
2172 Parameter_Associations
=>
2174 New_Reference_To
(Blk_Nam
, Loc
))))));
2176 pragma Assert
(Ekind
(Conc_Typ
) = E_Task_Type
);
2179 -- Protected_Entry_Call (
2181 -- task_entry_index! (I),
2183 -- Conditional_Call,
2186 -- where T is the task object, I is the entry index, P are the
2187 -- wrapped parameters and F is the status flag.
2190 Make_Procedure_Call_Statement
(Loc
,
2192 New_Reference_To
(RTE
(RE_Task_Entry_Call
), Loc
),
2193 Parameter_Associations
=>
2196 Make_Selected_Component
(Loc
, -- T._task_id
2198 Make_Identifier
(Loc
, Name_uT
),
2200 Make_Identifier
(Loc
, Name_uTask_Id
)),
2202 Make_Unchecked_Type_Conversion
(Loc
, -- entry index
2204 New_Reference_To
(RTE
(RE_Task_Entry_Index
), Loc
),
2206 Make_Identifier
(Loc
, Name_uI
)),
2208 Make_Identifier
(Loc
, Name_uP
), -- parameter block
2209 New_Reference_To
( -- Conditional_Call
2210 RTE
(RE_Conditional_Call
), Loc
),
2211 Make_Identifier
(Loc
, Name_uF
)))); -- status flag
2216 Make_Subprogram_Body
(Loc
,
2218 Make_Disp_Conditional_Select_Spec
(Typ
),
2221 Handled_Statement_Sequence
=>
2222 Make_Handled_Sequence_Of_Statements
(Loc
, Stmts
));
2223 end Make_Disp_Conditional_Select_Body
;
2225 ---------------------------------------
2226 -- Make_Disp_Conditional_Select_Spec --
2227 ---------------------------------------
2229 function Make_Disp_Conditional_Select_Spec
2230 (Typ
: Entity_Id
) return Node_Id
2232 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2233 Def_Id
: constant Node_Id
:=
2234 Make_Defining_Identifier
(Loc
,
2235 Name_uDisp_Conditional_Select
);
2236 Params
: constant List_Id
:= New_List
;
2239 pragma Assert
(not Restriction_Active
(No_Dispatching_Calls
));
2241 -- "T" - Object parameter
2242 -- "S" - Primitive operation slot
2243 -- "P" - Wrapped parameters
2245 -- "F" - Status flag
2247 SEU
.Build_T
(Loc
, Typ
, Params
);
2248 SEU
.Build_S
(Loc
, Params
);
2249 SEU
.Build_P
(Loc
, Params
);
2250 SEU
.Build_C
(Loc
, Params
);
2251 SEU
.Build_F
(Loc
, Params
);
2253 Set_Is_Internal
(Def_Id
);
2256 Make_Procedure_Specification
(Loc
,
2257 Defining_Unit_Name
=> Def_Id
,
2258 Parameter_Specifications
=> Params
);
2259 end Make_Disp_Conditional_Select_Spec
;
2261 -------------------------------------
2262 -- Make_Disp_Get_Prim_Op_Kind_Body --
2263 -------------------------------------
2265 function Make_Disp_Get_Prim_Op_Kind_Body
2266 (Typ
: Entity_Id
) return Node_Id
2268 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2272 pragma Assert
(not Restriction_Active
(No_Dispatching_Calls
));
2274 if Is_Interface
(Typ
) then
2276 Make_Subprogram_Body
(Loc
,
2278 Make_Disp_Get_Prim_Op_Kind_Spec
(Typ
),
2281 Handled_Statement_Sequence
=>
2282 Make_Handled_Sequence_Of_Statements
(Loc
,
2283 New_List
(Make_Null_Statement
(Loc
))));
2286 DT_Ptr
:= Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
2289 -- C := get_prim_op_kind (tag! (<type>VP), S);
2291 -- where C is the out parameter capturing the call kind and S is the
2292 -- dispatch table slot number.
2295 Make_Subprogram_Body
(Loc
,
2297 Make_Disp_Get_Prim_Op_Kind_Spec
(Typ
),
2300 Handled_Statement_Sequence
=>
2301 Make_Handled_Sequence_Of_Statements
(Loc
,
2303 Make_Assignment_Statement
(Loc
,
2305 Make_Identifier
(Loc
, Name_uC
),
2307 Make_DT_Access_Action
(Typ
,
2312 Unchecked_Convert_To
(RTE
(RE_Tag
),
2313 New_Reference_To
(DT_Ptr
, Loc
)),
2314 Make_Identifier
(Loc
, Name_uS
)))))));
2315 end Make_Disp_Get_Prim_Op_Kind_Body
;
2317 -------------------------------------
2318 -- Make_Disp_Get_Prim_Op_Kind_Spec --
2319 -------------------------------------
2321 function Make_Disp_Get_Prim_Op_Kind_Spec
2322 (Typ
: Entity_Id
) return Node_Id
2324 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2325 Def_Id
: constant Node_Id
:=
2326 Make_Defining_Identifier
(Loc
,
2327 Name_uDisp_Get_Prim_Op_Kind
);
2328 Params
: constant List_Id
:= New_List
;
2331 pragma Assert
(not Restriction_Active
(No_Dispatching_Calls
));
2333 -- "T" - Object parameter
2334 -- "S" - Primitive operation slot
2337 SEU
.Build_T
(Loc
, Typ
, Params
);
2338 SEU
.Build_S
(Loc
, Params
);
2339 SEU
.Build_C
(Loc
, Params
);
2341 Set_Is_Internal
(Def_Id
);
2344 Make_Procedure_Specification
(Loc
,
2345 Defining_Unit_Name
=> Def_Id
,
2346 Parameter_Specifications
=> Params
);
2347 end Make_Disp_Get_Prim_Op_Kind_Spec
;
2349 --------------------------------
2350 -- Make_Disp_Get_Task_Id_Body --
2351 --------------------------------
2353 function Make_Disp_Get_Task_Id_Body
2354 (Typ
: Entity_Id
) return Node_Id
2356 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2360 pragma Assert
(not Restriction_Active
(No_Dispatching_Calls
));
2362 if Is_Concurrent_Record_Type
(Typ
)
2363 and then Ekind
(Corresponding_Concurrent_Type
(Typ
)) = E_Task_Type
2366 Make_Return_Statement
(Loc
,
2368 Make_Selected_Component
(Loc
,
2370 Make_Identifier
(Loc
, Name_uT
),
2372 Make_Identifier
(Loc
, Name_uTask_Id
)));
2374 -- A null body is constructed for non-task types
2378 Make_Return_Statement
(Loc
,
2380 New_Reference_To
(RTE
(RO_ST_Null_Task
), Loc
));
2384 Make_Subprogram_Body
(Loc
,
2386 Make_Disp_Get_Task_Id_Spec
(Typ
),
2389 Handled_Statement_Sequence
=>
2390 Make_Handled_Sequence_Of_Statements
(Loc
,
2392 end Make_Disp_Get_Task_Id_Body
;
2394 --------------------------------
2395 -- Make_Disp_Get_Task_Id_Spec --
2396 --------------------------------
2398 function Make_Disp_Get_Task_Id_Spec
2399 (Typ
: Entity_Id
) return Node_Id
2401 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2402 Def_Id
: constant Node_Id
:=
2403 Make_Defining_Identifier
(Loc
,
2404 Name_uDisp_Get_Task_Id
);
2407 pragma Assert
(not Restriction_Active
(No_Dispatching_Calls
));
2409 Set_Is_Internal
(Def_Id
);
2412 Make_Function_Specification
(Loc
,
2413 Defining_Unit_Name
=> Def_Id
,
2414 Parameter_Specifications
=> New_List
(
2415 Make_Parameter_Specification
(Loc
,
2416 Defining_Identifier
=>
2417 Make_Defining_Identifier
(Loc
, Name_uT
),
2419 New_Reference_To
(Typ
, Loc
))),
2420 Result_Definition
=>
2421 New_Reference_To
(RTE
(RO_ST_Task_Id
), Loc
));
2422 end Make_Disp_Get_Task_Id_Spec
;
2424 ---------------------------------
2425 -- Make_Disp_Timed_Select_Body --
2426 ---------------------------------
2428 function Make_Disp_Timed_Select_Body
2429 (Typ
: Entity_Id
) return Node_Id
2431 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2432 Conc_Typ
: Entity_Id
:= Empty
;
2433 Decls
: constant List_Id
:= New_List
;
2435 Stmts
: constant List_Id
:= New_List
;
2438 pragma Assert
(not Restriction_Active
(No_Dispatching_Calls
));
2440 -- Null body is generated for interface types
2442 if Is_Interface
(Typ
) then
2444 Make_Subprogram_Body
(Loc
,
2446 Make_Disp_Timed_Select_Spec
(Typ
),
2449 Handled_Statement_Sequence
=>
2450 Make_Handled_Sequence_Of_Statements
(Loc
,
2451 New_List
(Make_Null_Statement
(Loc
))));
2454 DT_Ptr
:= Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
2456 if Is_Concurrent_Record_Type
(Typ
) then
2457 Conc_Typ
:= Corresponding_Concurrent_Type
(Typ
);
2462 -- where I will be used to capture the entry index of the primitive
2463 -- wrapper at position S.
2466 Make_Object_Declaration
(Loc
,
2467 Defining_Identifier
=>
2468 Make_Defining_Identifier
(Loc
, Name_uI
),
2469 Object_Definition
=>
2470 New_Reference_To
(Standard_Integer
, Loc
)));
2473 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
2475 -- if C = POK_Procedure
2476 -- or else C = POK_Protected_Procedure
2477 -- or else C = POK_Task_Procedure;
2483 SEU
.Build_Common_Dispatching_Select_Statements
2484 (Loc
, Typ
, DT_Ptr
, Stmts
);
2487 -- I := Get_Entry_Index (tag! (<type>VP), S);
2489 -- I is the entry index and S is the dispatch table slot
2492 Make_Assignment_Statement
(Loc
,
2494 Make_Identifier
(Loc
, Name_uI
),
2496 Make_DT_Access_Action
(Typ
,
2501 Unchecked_Convert_To
(RTE
(RE_Tag
),
2502 New_Reference_To
(DT_Ptr
, Loc
)),
2503 Make_Identifier
(Loc
, Name_uS
)))));
2505 if Ekind
(Conc_Typ
) = E_Protected_Type
then
2508 -- Timed_Protected_Entry_Call (
2509 -- T._object'access,
2510 -- protected_entry_index! (I),
2516 -- where T is the protected object, I is the entry index, P are
2517 -- the wrapped parameters, D is the delay amount, M is the delay
2518 -- mode and F is the status flag.
2521 Make_Procedure_Call_Statement
(Loc
,
2523 New_Reference_To
(RTE
(RE_Timed_Protected_Entry_Call
), Loc
),
2524 Parameter_Associations
=>
2527 Make_Attribute_Reference
(Loc
, -- T._object'access
2529 Name_Unchecked_Access
,
2531 Make_Selected_Component
(Loc
,
2533 Make_Identifier
(Loc
, Name_uT
),
2535 Make_Identifier
(Loc
, Name_uObject
))),
2537 Make_Unchecked_Type_Conversion
(Loc
, -- entry index
2539 New_Reference_To
(RTE
(RE_Protected_Entry_Index
), Loc
),
2541 Make_Identifier
(Loc
, Name_uI
)),
2543 Make_Identifier
(Loc
, Name_uP
), -- parameter block
2544 Make_Identifier
(Loc
, Name_uD
), -- delay
2545 Make_Identifier
(Loc
, Name_uM
), -- delay mode
2546 Make_Identifier
(Loc
, Name_uF
)))); -- status flag
2549 pragma Assert
(Ekind
(Conc_Typ
) = E_Task_Type
);
2552 -- Timed_Task_Entry_Call (
2554 -- task_entry_index! (I),
2560 -- where T is the task object, I is the entry index, P are the
2561 -- wrapped parameters, D is the delay amount, M is the delay
2562 -- mode and F is the status flag.
2565 Make_Procedure_Call_Statement
(Loc
,
2567 New_Reference_To
(RTE
(RE_Timed_Task_Entry_Call
), Loc
),
2568 Parameter_Associations
=>
2571 Make_Selected_Component
(Loc
, -- T._task_id
2573 Make_Identifier
(Loc
, Name_uT
),
2575 Make_Identifier
(Loc
, Name_uTask_Id
)),
2577 Make_Unchecked_Type_Conversion
(Loc
, -- entry index
2579 New_Reference_To
(RTE
(RE_Task_Entry_Index
), Loc
),
2581 Make_Identifier
(Loc
, Name_uI
)),
2583 Make_Identifier
(Loc
, Name_uP
), -- parameter block
2584 Make_Identifier
(Loc
, Name_uD
), -- delay
2585 Make_Identifier
(Loc
, Name_uM
), -- delay mode
2586 Make_Identifier
(Loc
, Name_uF
)))); -- status flag
2591 Make_Subprogram_Body
(Loc
,
2593 Make_Disp_Timed_Select_Spec
(Typ
),
2596 Handled_Statement_Sequence
=>
2597 Make_Handled_Sequence_Of_Statements
(Loc
, Stmts
));
2598 end Make_Disp_Timed_Select_Body
;
2600 ---------------------------------
2601 -- Make_Disp_Timed_Select_Spec --
2602 ---------------------------------
2604 function Make_Disp_Timed_Select_Spec
2605 (Typ
: Entity_Id
) return Node_Id
2607 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2608 Def_Id
: constant Node_Id
:=
2609 Make_Defining_Identifier
(Loc
,
2610 Name_uDisp_Timed_Select
);
2611 Params
: constant List_Id
:= New_List
;
2614 pragma Assert
(not Restriction_Active
(No_Dispatching_Calls
));
2616 -- "T" - Object parameter
2617 -- "S" - Primitive operation slot
2618 -- "P" - Wrapped parameters
2622 -- "F" - Status flag
2624 SEU
.Build_T
(Loc
, Typ
, Params
);
2625 SEU
.Build_S
(Loc
, Params
);
2626 SEU
.Build_P
(Loc
, Params
);
2629 Make_Parameter_Specification
(Loc
,
2630 Defining_Identifier
=>
2631 Make_Defining_Identifier
(Loc
, Name_uD
),
2633 New_Reference_To
(Standard_Duration
, Loc
)));
2636 Make_Parameter_Specification
(Loc
,
2637 Defining_Identifier
=>
2638 Make_Defining_Identifier
(Loc
, Name_uM
),
2640 New_Reference_To
(Standard_Integer
, Loc
)));
2642 SEU
.Build_C
(Loc
, Params
);
2643 SEU
.Build_F
(Loc
, Params
);
2645 Set_Is_Internal
(Def_Id
);
2648 Make_Procedure_Specification
(Loc
,
2649 Defining_Unit_Name
=> Def_Id
,
2650 Parameter_Specifications
=> Params
);
2651 end Make_Disp_Timed_Select_Spec
;
2657 function Make_DT
(Typ
: Entity_Id
) return List_Id
is
2658 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
2659 Result
: constant List_Id
:= New_List
;
2660 Elab_Code
: constant List_Id
:= New_List
;
2662 Tname
: constant Name_Id
:= Chars
(Typ
);
2663 Name_DT
: constant Name_Id
:= New_External_Name
(Tname
, 'T');
2664 Name_DT_Ptr
: constant Name_Id
:= New_External_Name
(Tname
, 'P');
2665 Name_SSD
: constant Name_Id
:= New_External_Name
(Tname
, 'S');
2666 Name_TSD
: constant Name_Id
:= New_External_Name
(Tname
, 'B');
2667 Name_Exname
: constant Name_Id
:= New_External_Name
(Tname
, 'E');
2668 Name_No_Reg
: constant Name_Id
:= New_External_Name
(Tname
, 'F');
2669 Name_ITable
: Name_Id
;
2671 DT
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_DT
);
2672 DT_Ptr
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_DT_Ptr
);
2673 SSD
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_SSD
);
2674 TSD
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_TSD
);
2675 Exname
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_Exname
);
2676 No_Reg
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_No_Reg
);
2679 Generalized_Tag
: constant Entity_Id
:= RTE
(RE_Tag
);
2686 Parent_Num_Ifaces
: Int
;
2687 Size_Expr_Node
: Node_Id
;
2688 TSD_Num_Entries
: Int
;
2690 Ancestor_Copy
: Entity_Id
;
2691 Empty_DT
: Boolean := False;
2692 Typ_Copy
: Entity_Id
;
2695 if not RTE_Available
(RE_Tag
) then
2696 Error_Msg_CRT
("tagged types", Typ
);
2700 -- Calculate the size of the DT and the TSD
2702 if Is_Interface
(Typ
) then
2704 -- Abstract interfaces need neither the DT nor the ancestors table.
2705 -- We reserve a single entry for its DT because at run-time the
2706 -- pointer to this dummy DT will be used as the tag of this abstract
2711 TSD_Num_Entries
:= 0;
2715 -- Count the number of interfaces implemented by the ancestors
2717 Parent_Num_Ifaces
:= 0;
2720 if Typ
/= Etype
(Typ
) then
2721 Ancestor_Copy
:= New_Copy
(Etype
(Typ
));
2722 Set_Parent
(Ancestor_Copy
, Parent
(Etype
(Typ
)));
2723 Set_Abstract_Interfaces
(Ancestor_Copy
, New_Elmt_List
);
2724 Collect_All_Interfaces
(Ancestor_Copy
);
2726 AI
:= First_Elmt
(Abstract_Interfaces
(Ancestor_Copy
));
2727 while Present
(AI
) loop
2728 Parent_Num_Ifaces
:= Parent_Num_Ifaces
+ 1;
2733 -- Count the number of additional interfaces implemented by Typ
2735 Typ_Copy
:= New_Copy
(Typ
);
2736 Set_Parent
(Typ_Copy
, Parent
(Typ
));
2737 Set_Abstract_Interfaces
(Typ_Copy
, New_Elmt_List
);
2738 Collect_All_Interfaces
(Typ_Copy
);
2740 AI
:= First_Elmt
(Abstract_Interfaces
(Typ_Copy
));
2741 while Present
(AI
) loop
2742 Num_Ifaces
:= Num_Ifaces
+ 1;
2746 -- Count ancestors to compute the inheritance depth. For private
2747 -- extensions, always go to the full view in order to compute the
2748 -- real inheritance depth.
2751 Parent_Type
: Entity_Id
:= Typ
;
2757 P
:= Etype
(Parent_Type
);
2759 if Is_Private_Type
(P
) then
2760 P
:= Full_View
(Base_Type
(P
));
2763 exit when P
= Parent_Type
;
2765 I_Depth
:= I_Depth
+ 1;
2770 TSD_Num_Entries
:= I_Depth
+ 1;
2771 Nb_Prim
:= UI_To_Int
(DT_Entry_Count
(First_Tag_Component
(Typ
)));
2773 -- If the number of primitives of Typ is 0 (or we are compiling with
2774 -- the No_Dispatching_Calls restriction) we reserve a dummy single
2775 -- entry for its DT because at run-time the pointer to this dummy DT
2776 -- will be used as the tag of this tagged type.
2778 if Nb_Prim
= 0 or else Restriction_Active
(No_Dispatching_Calls
) then
2784 -- Dispatch table and related entities are allocated statically
2786 Set_Ekind
(DT
, E_Variable
);
2787 Set_Is_Statically_Allocated
(DT
);
2789 Set_Ekind
(DT_Ptr
, E_Variable
);
2790 Set_Is_Statically_Allocated
(DT_Ptr
);
2792 if not Is_Interface
(Typ
)
2793 and then Num_Ifaces
> 0
2795 Name_ITable
:= New_External_Name
(Tname
, 'I');
2796 ITable
:= Make_Defining_Identifier
(Loc
, Name_ITable
);
2798 Set_Ekind
(ITable
, E_Variable
);
2799 Set_Is_Statically_Allocated
(ITable
);
2802 Set_Ekind
(SSD
, E_Variable
);
2803 Set_Is_Statically_Allocated
(SSD
);
2805 Set_Ekind
(TSD
, E_Variable
);
2806 Set_Is_Statically_Allocated
(TSD
);
2808 Set_Ekind
(Exname
, E_Variable
);
2809 Set_Is_Statically_Allocated
(Exname
);
2811 Set_Ekind
(No_Reg
, E_Variable
);
2812 Set_Is_Statically_Allocated
(No_Reg
);
2814 -- Generate code to create the storage for the Dispatch_Table object:
2816 -- DT : Storage_Array (1..DT_Prologue_Size+nb_prim*DT_Entry_Size);
2817 -- for DT'Alignment use Address'Alignment
2821 Left_Opnd
=> Make_DT_Access_Action
(Typ
, DT_Prologue_Size
, No_List
),
2823 Make_Op_Multiply
(Loc
,
2825 Make_DT_Access_Action
(Typ
, DT_Entry_Size
, No_List
),
2827 Make_Integer_Literal
(Loc
, Nb_Prim
)));
2830 Make_Object_Declaration
(Loc
,
2831 Defining_Identifier
=> DT
,
2832 Aliased_Present
=> True,
2833 Object_Definition
=>
2834 Make_Subtype_Indication
(Loc
,
2835 Subtype_Mark
=> New_Reference_To
2836 (RTE
(RE_Storage_Array
), Loc
),
2837 Constraint
=> Make_Index_Or_Discriminant_Constraint
(Loc
,
2838 Constraints
=> New_List
(
2840 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
2841 High_Bound
=> Size_Expr_Node
))))));
2844 Make_Attribute_Definition_Clause
(Loc
,
2845 Name
=> New_Reference_To
(DT
, Loc
),
2846 Chars
=> Name_Alignment
,
2848 Make_Attribute_Reference
(Loc
,
2849 Prefix
=> New_Reference_To
(RTE
(RE_Integer_Address
), Loc
),
2850 Attribute_Name
=> Name_Alignment
)));
2852 -- Generate code to create the pointer to the dispatch table
2854 -- DT_Ptr : Tag := Tag!(DT'Address);
2856 -- According to the C++ ABI, the base of the vtable is located after a
2857 -- prologue containing Offset_To_Top, and Typeinfo_Ptr. Hence, we move
2858 -- down the pointer to the real base of the vtable
2861 Make_Object_Declaration
(Loc
,
2862 Defining_Identifier
=> DT_Ptr
,
2863 Constant_Present
=> True,
2864 Object_Definition
=> New_Reference_To
(Generalized_Tag
, Loc
),
2866 Unchecked_Convert_To
(Generalized_Tag
,
2869 Unchecked_Convert_To
(RTE
(RE_Storage_Offset
),
2870 Make_Attribute_Reference
(Loc
,
2871 Prefix
=> New_Reference_To
(DT
, Loc
),
2872 Attribute_Name
=> Name_Address
)),
2874 Make_DT_Access_Action
(Typ
,
2875 DT_Prologue_Size
, No_List
)))));
2877 -- Generate code to define the boolean that controls registration, in
2878 -- order to avoid multiple registrations for tagged types defined in
2879 -- multiple-called scopes.
2882 Make_Object_Declaration
(Loc
,
2883 Defining_Identifier
=> No_Reg
,
2884 Object_Definition
=> New_Reference_To
(Standard_Boolean
, Loc
),
2885 Expression
=> New_Reference_To
(Standard_True
, Loc
)));
2887 -- Set Access_Disp_Table field to be the dispatch table pointer
2889 if No
(Access_Disp_Table
(Typ
)) then
2890 Set_Access_Disp_Table
(Typ
, New_Elmt_List
);
2893 Prepend_Elmt
(DT_Ptr
, Access_Disp_Table
(Typ
));
2895 -- Generate code to create the storage for the type specific data object
2896 -- with enough space to store the tags of the ancestors plus the tags
2897 -- of all the implemented interfaces (as described in a-tags.adb).
2899 -- TSD: Storage_Array
2900 -- (1..TSD_Prologue_Size+TSD_Num_Entries*TSD_Entry_Size);
2901 -- for TSD'Alignment use Address'Alignment
2906 Make_DT_Access_Action
(Typ
, TSD_Prologue_Size
, No_List
),
2908 Make_Op_Multiply
(Loc
,
2910 Make_DT_Access_Action
(Typ
, TSD_Entry_Size
, No_List
),
2912 Make_Integer_Literal
(Loc
, TSD_Num_Entries
)));
2915 Make_Object_Declaration
(Loc
,
2916 Defining_Identifier
=> TSD
,
2917 Aliased_Present
=> True,
2918 Object_Definition
=>
2919 Make_Subtype_Indication
(Loc
,
2920 Subtype_Mark
=> New_Reference_To
(RTE
(RE_Storage_Array
), Loc
),
2921 Constraint
=> Make_Index_Or_Discriminant_Constraint
(Loc
,
2922 Constraints
=> New_List
(
2924 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
2925 High_Bound
=> Size_Expr_Node
))))));
2928 Make_Attribute_Definition_Clause
(Loc
,
2929 Name
=> New_Reference_To
(TSD
, Loc
),
2930 Chars
=> Name_Alignment
,
2932 Make_Attribute_Reference
(Loc
,
2933 Prefix
=> New_Reference_To
(RTE
(RE_Integer_Address
), Loc
),
2934 Attribute_Name
=> Name_Alignment
)));
2937 -- Set_Signature (DT_Ptr, Value);
2939 if Is_Interface
(Typ
) then
2940 Append_To
(Elab_Code
,
2941 Make_DT_Access_Action
(Typ
,
2942 Action
=> Set_Signature
,
2944 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
2945 New_Reference_To
(RTE
(RE_Abstract_Interface
), Loc
))));
2947 elsif RTE_Available
(RE_Set_Signature
) then
2948 Append_To
(Elab_Code
,
2949 Make_DT_Access_Action
(Typ
,
2950 Action
=> Set_Signature
,
2952 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
2953 New_Reference_To
(RTE
(RE_Primary_DT
), Loc
))));
2956 -- Generate code to put the Address of the TSD in the dispatch table
2957 -- Set_TSD (DT_Ptr, TSD);
2959 Append_To
(Elab_Code
,
2960 Make_DT_Access_Action
(Typ
,
2963 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
2964 Make_Attribute_Reference
(Loc
, -- Value
2965 Prefix
=> New_Reference_To
(TSD
, Loc
),
2966 Attribute_Name
=> Name_Address
))));
2968 -- Set the pointer to the Interfaces_Table (if any). Otherwise the
2969 -- corresponding access component is set to null.
2971 if Is_Interface
(Typ
) then
2974 elsif Num_Ifaces
= 0 then
2975 if RTE_Available
(RE_Set_Interface_Table
) then
2976 Append_To
(Elab_Code
,
2977 Make_DT_Access_Action
(Typ
,
2978 Action
=> Set_Interface_Table
,
2980 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
2981 New_Reference_To
(RTE
(RE_Null_Address
), Loc
)))); -- null
2984 -- Generate the Interface_Table object and set the access
2985 -- component if the TSD to it.
2987 elsif RTE_Available
(RE_Set_Interface_Table
) then
2989 Make_Object_Declaration
(Loc
,
2990 Defining_Identifier
=> ITable
,
2991 Aliased_Present
=> True,
2992 Object_Definition
=>
2993 Make_Subtype_Indication
(Loc
,
2994 Subtype_Mark
=> New_Reference_To
2995 (RTE
(RE_Interface_Data
), Loc
),
2996 Constraint
=> Make_Index_Or_Discriminant_Constraint
(Loc
,
2997 Constraints
=> New_List
(
2998 Make_Integer_Literal
(Loc
,
3001 Append_To
(Elab_Code
,
3002 Make_DT_Access_Action
(Typ
,
3003 Action
=> Set_Interface_Table
,
3005 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
3006 Make_Attribute_Reference
(Loc
, -- Value
3007 Prefix
=> New_Reference_To
(ITable
, Loc
),
3008 Attribute_Name
=> Name_Address
))));
3012 -- Set_Num_Prim_Ops (T'Tag, Nb_Prim)
3014 if RTE_Available
(RE_Set_Num_Prim_Ops
) then
3015 if not Is_Interface
(Typ
) then
3017 Append_To
(Elab_Code
,
3018 Make_Procedure_Call_Statement
(Loc
,
3019 Name
=> New_Reference_To
(RTE
(RE_Set_Num_Prim_Ops
), Loc
),
3020 Parameter_Associations
=> New_List
(
3021 New_Reference_To
(DT_Ptr
, Loc
),
3022 Make_Integer_Literal
(Loc
, Uint_0
))));
3024 Append_To
(Elab_Code
,
3025 Make_Procedure_Call_Statement
(Loc
,
3026 Name
=> New_Reference_To
(RTE
(RE_Set_Num_Prim_Ops
), Loc
),
3027 Parameter_Associations
=> New_List
(
3028 New_Reference_To
(DT_Ptr
, Loc
),
3029 Make_Integer_Literal
(Loc
, Nb_Prim
))));
3033 if Ada_Version
>= Ada_05
3034 and then not Is_Interface
(Typ
)
3035 and then not Is_Abstract
(Typ
)
3036 and then not Is_Controlled
(Typ
)
3037 and then not Restriction_Active
(No_Dispatching_Calls
)
3040 -- Set_Type_Kind (T'Tag, Type_Kind (Typ));
3042 Append_To
(Elab_Code
,
3043 Make_DT_Access_Action
(Typ
,
3044 Action
=> Set_Tagged_Kind
,
3046 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
3047 Tagged_Kind
(Typ
)))); -- Value
3049 -- Generate the Select Specific Data table for synchronized
3050 -- types that implement a synchronized interface. The size
3051 -- of the table is constrained by the number of non-predefined
3052 -- primitive operations.
3055 and then Is_Concurrent_Record_Type
(Typ
)
3056 and then Implements_Interface
(
3058 Kind
=> Any_Limited_Interface
,
3059 Check_Parent
=> True)
3062 Make_Object_Declaration
(Loc
,
3063 Defining_Identifier
=> SSD
,
3064 Aliased_Present
=> True,
3065 Object_Definition
=>
3066 Make_Subtype_Indication
(Loc
,
3067 Subtype_Mark
=> New_Reference_To
(
3068 RTE
(RE_Select_Specific_Data
), Loc
),
3070 Make_Index_Or_Discriminant_Constraint
(Loc
,
3071 Constraints
=> New_List
(
3072 Make_Integer_Literal
(Loc
, Nb_Prim
))))));
3074 -- Set the pointer to the Select Specific Data table in the TSD
3076 Append_To
(Elab_Code
,
3077 Make_DT_Access_Action
(Typ
,
3080 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
3081 Make_Attribute_Reference
(Loc
, -- Value
3082 Prefix
=> New_Reference_To
(SSD
, Loc
),
3083 Attribute_Name
=> Name_Address
))));
3088 -- Generate: Exname : constant String := full_qualified_name (typ);
3089 -- The type itself may be an anonymous parent type, so use the first
3090 -- subtype to have a user-recognizable name.
3093 Make_Object_Declaration
(Loc
,
3094 Defining_Identifier
=> Exname
,
3095 Constant_Present
=> True,
3096 Object_Definition
=> New_Reference_To
(Standard_String
, Loc
),
3098 Make_String_Literal
(Loc
,
3099 Full_Qualified_Name
(First_Subtype
(Typ
)))));
3101 -- Generate: Set_Expanded_Name (DT_Ptr, exname'Address);
3103 Append_To
(Elab_Code
,
3104 Make_DT_Access_Action
(Typ
,
3105 Action
=> Set_Expanded_Name
,
3107 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
3109 Make_Attribute_Reference
(Loc
,
3110 Prefix
=> New_Reference_To
(Exname
, Loc
),
3111 Attribute_Name
=> Name_Address
))));
3113 if not Is_Interface
(Typ
) then
3114 -- Generate: Set_Access_Level (DT_Ptr, <type's accessibility level>);
3116 Append_To
(Elab_Code
,
3117 Make_DT_Access_Action
(Typ
,
3118 Action
=> Set_Access_Level
,
3120 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
3121 Node2
=> Make_Integer_Literal
(Loc
, Type_Access_Level
(Typ
)))));
3124 if Typ
= Etype
(Typ
)
3125 or else Is_CPP_Class
(Etype
(Typ
))
3126 or else Is_Interface
(Typ
)
3129 Unchecked_Convert_To
(Generalized_Tag
,
3130 Make_Integer_Literal
(Loc
, 0));
3132 Unchecked_Convert_To
(Generalized_Tag
,
3133 Make_Integer_Literal
(Loc
, 0));
3138 (Node
(First_Elmt
(Access_Disp_Table
(Etype
(Typ
)))), Loc
);
3141 (Node
(First_Elmt
(Access_Disp_Table
(Etype
(Typ
)))), Loc
);
3144 if Typ
/= Etype
(Typ
)
3145 and then not Is_Interface
(Typ
)
3146 and then not Restriction_Active
(No_Dispatching_Calls
)
3148 -- Generate: Inherit_DT (parent'tag, DT_Ptr, nb_prim of parent);
3150 if not Is_Interface
(Etype
(Typ
)) then
3151 if Restriction_Active
(No_Dispatching_Calls
) then
3152 Append_To
(Elab_Code
,
3153 Make_DT_Access_Action
(Typ
,
3154 Action
=> Inherit_DT
,
3157 Node2
=> New_Reference_To
(DT_Ptr
, Loc
),
3158 Node3
=> Make_Integer_Literal
(Loc
, Uint_0
))));
3160 Append_To
(Elab_Code
,
3161 Make_DT_Access_Action
(Typ
,
3162 Action
=> Inherit_DT
,
3165 Node2
=> New_Reference_To
(DT_Ptr
, Loc
),
3166 Node3
=> Make_Integer_Literal
(Loc
,
3168 (First_Tag_Component
(Etype
(Typ
)))))));
3172 -- Inherit the secondary dispatch tables of the ancestor
3174 if not Restriction_Active
(No_Dispatching_Calls
)
3175 and then not Is_CPP_Class
(Etype
(Typ
))
3178 Sec_DT_Ancestor
: Elmt_Id
:=
3181 (Access_Disp_Table
(Etype
(Typ
))));
3182 Sec_DT_Typ
: Elmt_Id
:=
3185 (Access_Disp_Table
(Typ
)));
3187 procedure Copy_Secondary_DTs
(Typ
: Entity_Id
);
3188 -- Local procedure required to climb through the ancestors and
3189 -- copy the contents of all their secondary dispatch tables.
3191 ------------------------
3192 -- Copy_Secondary_DTs --
3193 ------------------------
3195 procedure Copy_Secondary_DTs
(Typ
: Entity_Id
) is
3200 -- Climb to the ancestor (if any) handling private types
3202 if Present
(Full_View
(Etype
(Typ
))) then
3203 if Full_View
(Etype
(Typ
)) /= Typ
then
3204 Copy_Secondary_DTs
(Full_View
(Etype
(Typ
)));
3207 elsif Etype
(Typ
) /= Typ
then
3208 Copy_Secondary_DTs
(Etype
(Typ
));
3211 if Present
(Abstract_Interfaces
(Typ
))
3212 and then not Is_Empty_Elmt_List
3213 (Abstract_Interfaces
(Typ
))
3215 Iface
:= First_Elmt
(Abstract_Interfaces
(Typ
));
3216 E
:= First_Entity
(Typ
);
3218 and then Present
(Node
(Sec_DT_Ancestor
))
3220 if Is_Tag
(E
) and then Chars
(E
) /= Name_uTag
then
3221 if not Is_Interface
(Etype
(Typ
)) then
3222 Append_To
(Elab_Code
,
3223 Make_DT_Access_Action
(Typ
,
3224 Action
=> Inherit_DT
,
3226 Node1
=> Unchecked_Convert_To
3229 (Node
(Sec_DT_Ancestor
),
3231 Node2
=> Unchecked_Convert_To
3234 (Node
(Sec_DT_Typ
), Loc
)),
3235 Node3
=> Make_Integer_Literal
(Loc
,
3236 DT_Entry_Count
(E
)))));
3239 Next_Elmt
(Sec_DT_Ancestor
);
3240 Next_Elmt
(Sec_DT_Typ
);
3247 end Copy_Secondary_DTs
;
3250 if Present
(Node
(Sec_DT_Ancestor
)) then
3252 -- Handle private types
3254 if Present
(Full_View
(Typ
)) then
3255 Copy_Secondary_DTs
(Full_View
(Typ
));
3257 Copy_Secondary_DTs
(Typ
);
3265 -- Inherit_TSD (parent'tag, DT_Ptr);
3267 Append_To
(Elab_Code
,
3268 Make_DT_Access_Action
(Typ
,
3269 Action
=> Inherit_TSD
,
3272 Node2
=> New_Reference_To
(DT_Ptr
, Loc
))));
3274 if not Is_Interface
(Typ
) then
3276 -- For types with no controlled components, generate:
3277 -- Set_RC_Offset (DT_Ptr, 0);
3279 -- For simple types with controlled components, generate:
3280 -- Set_RC_Offset (DT_Ptr, type._record_controller'position);
3282 -- For complex types with controlled components where the position
3283 -- of the record controller is not statically computable, if there
3284 -- are controlled components at this level, generate:
3285 -- Set_RC_Offset (DT_Ptr, -1);
3286 -- to indicate that the _controller field is right after the _parent
3288 -- Or if there are no controlled components at this level, generate:
3289 -- Set_RC_Offset (DT_Ptr, -2);
3290 -- to indicate that we need to get the position from the parent.
3296 if not Has_Controlled_Component
(Typ
) then
3297 Position
:= Make_Integer_Literal
(Loc
, 0);
3299 elsif Etype
(Typ
) /= Typ
3300 and then Has_Discriminants
(Etype
(Typ
))
3302 if Has_New_Controlled_Component
(Typ
) then
3303 Position
:= Make_Integer_Literal
(Loc
, -1);
3305 Position
:= Make_Integer_Literal
(Loc
, -2);
3309 Make_Attribute_Reference
(Loc
,
3311 Make_Selected_Component
(Loc
,
3312 Prefix
=> New_Reference_To
(Typ
, Loc
),
3314 New_Reference_To
(Controller_Component
(Typ
), Loc
)),
3315 Attribute_Name
=> Name_Position
);
3317 -- This is not proper Ada code to use the attribute 'Position
3318 -- on something else than an object but this is supported by
3319 -- the back end (see comment on the Bit_Component attribute in
3320 -- sem_attr). So we avoid semantic checking here.
3322 -- Is this documented in sinfo.ads??? it should be!
3324 Set_Analyzed
(Position
);
3325 Set_Etype
(Prefix
(Position
), RTE
(RE_Record_Controller
));
3326 Set_Etype
(Prefix
(Prefix
(Position
)), Typ
);
3327 Set_Etype
(Selector_Name
(Prefix
(Position
)),
3328 RTE
(RE_Record_Controller
));
3329 Set_Etype
(Position
, RTE
(RE_Storage_Offset
));
3332 Append_To
(Elab_Code
,
3333 Make_DT_Access_Action
(Typ
,
3334 Action
=> Set_RC_Offset
,
3336 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
3337 Node2
=> Position
)));
3340 -- Generate: Set_Remotely_Callable (DT_Ptr, Status); where Status is
3341 -- described in E.4 (18)
3350 or else Is_Shared_Passive
(Typ
)
3352 ((Is_Remote_Types
(Typ
)
3353 or else Is_Remote_Call_Interface
(Typ
))
3354 and then Original_View_In_Visible_Part
(Typ
))
3355 or else not Comes_From_Source
(Typ
));
3357 Append_To
(Elab_Code
,
3358 Make_DT_Access_Action
(Typ
,
3359 Action
=> Set_Remotely_Callable
,
3361 New_Occurrence_Of
(DT_Ptr
, Loc
),
3362 New_Occurrence_Of
(Status
, Loc
))));
3365 if RTE_Available
(RE_Set_Offset_To_Top
) then
3367 -- Set_Offset_To_Top (0, DT_Ptr, True, 0, null);
3369 Append_To
(Elab_Code
,
3370 Make_Procedure_Call_Statement
(Loc
,
3371 Name
=> New_Reference_To
(RTE
(RE_Set_Offset_To_Top
), Loc
),
3372 Parameter_Associations
=> New_List
(
3373 New_Reference_To
(RTE
(RE_Null_Address
), Loc
),
3374 New_Reference_To
(DT_Ptr
, Loc
),
3375 New_Occurrence_Of
(Standard_True
, Loc
),
3376 Make_Integer_Literal
(Loc
, Uint_0
),
3377 New_Reference_To
(RTE
(RE_Null_Address
), Loc
))));
3381 -- Generate: Set_External_Tag (DT_Ptr, exname'Address);
3382 -- Should be the external name not the qualified name???
3384 if not Has_External_Tag_Rep_Clause
(Typ
) then
3385 Append_To
(Elab_Code
,
3386 Make_DT_Access_Action
(Typ
,
3387 Action
=> Set_External_Tag
,
3389 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
3391 Make_Attribute_Reference
(Loc
,
3392 Prefix
=> New_Reference_To
(Exname
, Loc
),
3393 Attribute_Name
=> Name_Address
))));
3395 -- Generate code to register the Tag in the External_Tag hash
3396 -- table for the pure Ada type only.
3398 -- Register_Tag (Dt_Ptr);
3400 -- Skip this if routine not available, or in No_Run_Time mode
3401 -- or Typ is an abstract interface type (because the table to
3402 -- register it is not available in the abstract type but in
3403 -- types implementing this interface)
3405 if not No_Run_Time_Mode
3406 and then RTE_Available
(RE_Register_Tag
)
3407 and then Is_RTE
(Generalized_Tag
, RE_Tag
)
3408 and then not Is_Interface
(Typ
)
3410 Append_To
(Elab_Code
,
3411 Make_Procedure_Call_Statement
(Loc
,
3412 Name
=> New_Reference_To
(RTE
(RE_Register_Tag
), Loc
),
3413 Parameter_Associations
=>
3414 New_List
(New_Reference_To
(DT_Ptr
, Loc
))));
3424 Append_To
(Elab_Code
,
3425 Make_Assignment_Statement
(Loc
,
3426 Name
=> New_Reference_To
(No_Reg
, Loc
),
3427 Expression
=> New_Reference_To
(Standard_False
, Loc
)));
3430 Make_Implicit_If_Statement
(Typ
,
3431 Condition
=> New_Reference_To
(No_Reg
, Loc
),
3432 Then_Statements
=> Elab_Code
));
3434 -- Ada 2005 (AI-251): Register the tag of the interfaces into
3435 -- the table of implemented interfaces.
3437 if not Is_Interface
(Typ
)
3438 and then Num_Ifaces
> 0
3444 -- If the parent is an interface we must generate code to register
3445 -- all its interfaces; otherwise this code is not needed because
3446 -- Inherit_TSD has already inherited such interfaces.
3448 if Is_Interface
(Etype
(Typ
)) then
3451 AI
:= First_Elmt
(Abstract_Interfaces
(Ancestor_Copy
));
3452 while Present
(AI
) loop
3454 -- Register_Interface (DT_Ptr, Interface'Tag);
3457 Make_DT_Access_Action
(Typ
,
3458 Action
=> Register_Interface_Tag
,
3460 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
3461 Node2
=> New_Reference_To
3464 (Access_Disp_Table
(Node
(AI
)))),
3466 Node3
=> Make_Integer_Literal
(Loc
, Position
))));
3468 Position
:= Position
+ 1;
3473 -- Register the interfaces that are not implemented by the
3476 if Present
(Abstract_Interfaces
(Typ_Copy
)) then
3477 AI
:= First_Elmt
(Abstract_Interfaces
(Typ_Copy
));
3479 -- Skip the interfaces implemented by the ancestor
3481 for Count
in 1 .. Parent_Num_Ifaces
loop
3485 -- Register the additional interfaces
3487 Position
:= Parent_Num_Ifaces
+ 1;
3488 while Present
(AI
) loop
3490 -- Register_Interface (DT_Ptr, Interface'Tag);
3493 Make_DT_Access_Action
(Typ
,
3494 Action
=> Register_Interface_Tag
,
3496 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
3497 Node2
=> New_Reference_To
3500 (Access_Disp_Table
(Node
(AI
)))),
3502 Node3
=> Make_Integer_Literal
(Loc
, Position
))));
3504 Position
:= Position
+ 1;
3509 pragma Assert
(Position
= Num_Ifaces
+ 1);
3516 ---------------------------
3517 -- Make_DT_Access_Action --
3518 ---------------------------
3520 function Make_DT_Access_Action
3522 Action
: DT_Access_Action
;
3523 Args
: List_Id
) return Node_Id
3525 Action_Name
: constant Entity_Id
:= RTE
(Ada_Actions
(Action
));
3531 -- This is a constant
3533 return New_Reference_To
(Action_Name
, Sloc
(Typ
));
3536 pragma Assert
(List_Length
(Args
) = Action_Nb_Arg
(Action
));
3538 Loc
:= Sloc
(First
(Args
));
3540 if Action_Is_Proc
(Action
) then
3542 Make_Procedure_Call_Statement
(Loc
,
3543 Name
=> New_Reference_To
(Action_Name
, Loc
),
3544 Parameter_Associations
=> Args
);
3548 Make_Function_Call
(Loc
,
3549 Name
=> New_Reference_To
(Action_Name
, Loc
),
3550 Parameter_Associations
=> Args
);
3552 end Make_DT_Access_Action
;
3554 -----------------------
3555 -- Make_Secondary_DT --
3556 -----------------------
3558 procedure Make_Secondary_DT
3560 Ancestor_Typ
: Entity_Id
;
3564 Acc_Disp_Tables
: in out Elist_Id
;
3565 Result
: out List_Id
)
3567 Loc
: constant Source_Ptr
:= Sloc
(AI_Tag
);
3568 Generalized_Tag
: constant Entity_Id
:= RTE
(RE_Interface_Tag
);
3569 Name_DT
: constant Name_Id
:= New_Internal_Name
('T');
3570 Empty_DT
: Boolean := False;
3572 Iface_DT_Ptr
: Node_Id
;
3573 Name_DT_Ptr
: Name_Id
;
3576 Size_Expr_Node
: Node_Id
;
3582 -- Generate a unique external name associated with the secondary
3583 -- dispatch table. This external name will be used to declare an
3584 -- access to this secondary dispatch table, value that will be used
3585 -- for the elaboration of Typ's objects and also for the elaboration
3586 -- of objects of any derivation of Typ that do not override any
3587 -- primitive operation of Typ.
3589 Get_Secondary_DT_External_Name
(Typ
, Ancestor_Typ
, Suffix_Index
);
3592 Name_DT_Ptr
:= New_External_Name
(Tname
, "P");
3593 Iface_DT
:= Make_Defining_Identifier
(Loc
, Name_DT
);
3594 Iface_DT_Ptr
:= Make_Defining_Identifier
(Loc
, Name_DT_Ptr
);
3596 -- Dispatch table and related entities are allocated statically
3598 Set_Ekind
(Iface_DT
, E_Variable
);
3599 Set_Is_Statically_Allocated
(Iface_DT
);
3601 Set_Ekind
(Iface_DT_Ptr
, E_Variable
);
3602 Set_Is_Statically_Allocated
(Iface_DT_Ptr
);
3604 -- Generate code to create the storage for the Dispatch_Table object.
3605 -- If the number of primitives of Typ is 0 we reserve a dummy single
3606 -- entry for its DT because at run-time the pointer to this dummy entry
3607 -- will be used as the tag.
3609 Nb_Prim
:= UI_To_Int
(DT_Entry_Count
(AI_Tag
));
3616 -- DT : Storage_Array (1..DT_Prologue_Size+nb_prim*DT_Entry_Size);
3617 -- for DT'Alignment use Address'Alignment
3621 Left_Opnd
=> Make_DT_Access_Action
(Etype
(AI_Tag
),
3625 Make_Op_Multiply
(Loc
,
3627 Make_DT_Access_Action
(Etype
(AI_Tag
),
3631 Make_Integer_Literal
(Loc
, Nb_Prim
)));
3634 Make_Object_Declaration
(Loc
,
3635 Defining_Identifier
=> Iface_DT
,
3636 Aliased_Present
=> True,
3637 Object_Definition
=>
3638 Make_Subtype_Indication
(Loc
,
3639 Subtype_Mark
=> New_Reference_To
(RTE
(RE_Storage_Array
), Loc
),
3640 Constraint
=> Make_Index_Or_Discriminant_Constraint
(Loc
,
3641 Constraints
=> New_List
(
3643 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
3644 High_Bound
=> Size_Expr_Node
))))));
3647 Make_Attribute_Definition_Clause
(Loc
,
3648 Name
=> New_Reference_To
(Iface_DT
, Loc
),
3649 Chars
=> Name_Alignment
,
3651 Make_Attribute_Reference
(Loc
,
3652 Prefix
=> New_Reference_To
(RTE
(RE_Integer_Address
), Loc
),
3653 Attribute_Name
=> Name_Alignment
)));
3655 -- Generate code to create the pointer to the dispatch table
3657 -- Iface_DT_Ptr : Tag := Tag!(DT'Address);
3659 -- According to the C++ ABI, the base of the vtable is located
3660 -- after the following prologue: Offset_To_Top, and Typeinfo_Ptr.
3661 -- Hence, move the pointer down to the real base of the vtable.
3664 Make_Object_Declaration
(Loc
,
3665 Defining_Identifier
=> Iface_DT_Ptr
,
3666 Constant_Present
=> True,
3667 Object_Definition
=> New_Reference_To
(Generalized_Tag
, Loc
),
3669 Unchecked_Convert_To
(Generalized_Tag
,
3672 Unchecked_Convert_To
(RTE
(RE_Storage_Offset
),
3673 Make_Attribute_Reference
(Loc
,
3674 Prefix
=> New_Reference_To
(Iface_DT
, Loc
),
3675 Attribute_Name
=> Name_Address
)),
3677 Make_DT_Access_Action
(Etype
(AI_Tag
),
3678 DT_Prologue_Size
, No_List
)))));
3680 -- Note: Offset_To_Top will be initialized by the init subprogram
3682 -- Set Access_Disp_Table field to be the dispatch table pointer
3684 if not (Present
(Acc_Disp_Tables
)) then
3685 Acc_Disp_Tables
:= New_Elmt_List
;
3688 Append_Elmt
(Iface_DT_Ptr
, Acc_Disp_Tables
);
3690 -- Step 1: Generate an Object Specific Data (OSD) table
3692 OSD
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('I'));
3694 -- Nothing to do if configurable run time does not support the
3695 -- Object_Specific_Data entity.
3697 if not RTE_Available
(RE_Object_Specific_Data
) then
3698 Error_Msg_CRT
("abstract interface types", Typ
);
3703 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims);
3704 -- where the constraint is used to allocate space for the
3705 -- non-predefined primitive operations only.
3708 Make_Object_Declaration
(Loc
,
3709 Defining_Identifier
=> OSD
,
3710 Object_Definition
=>
3711 Make_Subtype_Indication
(Loc
,
3712 Subtype_Mark
=> New_Reference_To
(
3713 RTE
(RE_Object_Specific_Data
), Loc
),
3715 Make_Index_Or_Discriminant_Constraint
(Loc
,
3716 Constraints
=> New_List
(
3717 Make_Integer_Literal
(Loc
, Nb_Prim
))))));
3720 Make_DT_Access_Action
(Typ
,
3721 Action
=> Set_Signature
,
3723 Unchecked_Convert_To
(RTE
(RE_Tag
),
3724 New_Reference_To
(Iface_DT_Ptr
, Loc
)),
3725 New_Reference_To
(RTE
(RE_Secondary_DT
), Loc
))));
3728 -- Ada.Tags.Set_OSD (Iface_DT_Ptr, OSD);
3731 Make_DT_Access_Action
(Typ
,
3734 Unchecked_Convert_To
(RTE
(RE_Tag
),
3735 New_Reference_To
(Iface_DT_Ptr
, Loc
)),
3736 Make_Attribute_Reference
(Loc
,
3737 Prefix
=> New_Reference_To
(OSD
, Loc
),
3738 Attribute_Name
=> Name_Address
))));
3741 -- Set_Num_Prim_Ops (T'Tag, Nb_Prim)
3743 if RTE_Available
(RE_Set_Num_Prim_Ops
) then
3746 Make_Procedure_Call_Statement
(Loc
,
3747 Name
=> New_Reference_To
(RTE
(RE_Set_Num_Prim_Ops
), Loc
),
3748 Parameter_Associations
=> New_List
(
3749 Unchecked_Convert_To
(RTE
(RE_Tag
),
3750 New_Reference_To
(Iface_DT_Ptr
, Loc
)),
3751 Make_Integer_Literal
(Loc
, Uint_0
))));
3754 Make_Procedure_Call_Statement
(Loc
,
3755 Name
=> New_Reference_To
(RTE
(RE_Set_Num_Prim_Ops
), Loc
),
3756 Parameter_Associations
=> New_List
(
3757 Unchecked_Convert_To
(RTE
(RE_Tag
),
3758 New_Reference_To
(Iface_DT_Ptr
, Loc
)),
3759 Make_Integer_Literal
(Loc
, Nb_Prim
))));
3763 if Ada_Version
>= Ada_05
3764 and then not Is_Interface
(Typ
)
3765 and then not Is_Abstract
(Typ
)
3766 and then not Is_Controlled
(Typ
)
3767 and then RTE_Available
(RE_Set_Tagged_Kind
)
3768 and then not Restriction_Active
(No_Dispatching_Calls
)
3771 -- Set_Tagged_Kind (Iface'Tag, Tagged_Kind (Iface));
3774 Make_DT_Access_Action
(Typ
,
3775 Action
=> Set_Tagged_Kind
,
3777 Unchecked_Convert_To
(RTE
(RE_Tag
), -- DTptr
3778 New_Reference_To
(Iface_DT_Ptr
, Loc
)),
3779 Tagged_Kind
(Typ
)))); -- Value
3782 and then Is_Concurrent_Record_Type
(Typ
)
3783 and then Implements_Interface
(
3785 Kind
=> Any_Limited_Interface
,
3786 Check_Parent
=> True)
3790 Prim_Alias
: Entity_Id
;
3791 Prim_Elmt
: Elmt_Id
;
3794 -- Step 2: Populate the OSD table
3796 Prim_Alias
:= Empty
;
3797 Prim_Elmt
:= First_Elmt
(Primitive_Operations
(Typ
));
3798 while Present
(Prim_Elmt
) loop
3799 Prim
:= Node
(Prim_Elmt
);
3801 if Present
(Abstract_Interface_Alias
(Prim
)) then
3802 Prim_Alias
:= Abstract_Interface_Alias
(Prim
);
3805 if Present
(Prim_Alias
)
3806 and then Present
(First_Entity
(Prim_Alias
))
3807 and then Etype
(First_Entity
(Prim_Alias
)) = Iface
3810 -- Ada.Tags.Set_Offset_Index (Tag (Iface_DT_Ptr),
3811 -- Secondary_DT_Pos, Primary_DT_pos);
3814 Make_DT_Access_Action
(Iface
,
3815 Action
=> Set_Offset_Index
,
3817 Unchecked_Convert_To
(RTE
(RE_Tag
),
3818 New_Reference_To
(Iface_DT_Ptr
, Loc
)),
3819 Make_Integer_Literal
(Loc
,
3820 DT_Position
(Prim_Alias
)),
3821 Make_Integer_Literal
(Loc
,
3822 DT_Position
(Prim
)))));
3824 Prim_Alias
:= Empty
;
3827 Next_Elmt
(Prim_Elmt
);
3832 end Make_Secondary_DT
;
3834 -------------------------------------
3835 -- Make_Select_Specific_Data_Table --
3836 -------------------------------------
3838 function Make_Select_Specific_Data_Table
3839 (Typ
: Entity_Id
) return List_Id
3841 Assignments
: constant List_Id
:= New_List
;
3842 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
3844 Conc_Typ
: Entity_Id
;
3848 Prim_Als
: Entity_Id
;
3849 Prim_Elmt
: Elmt_Id
;
3853 type Examined_Array
is array (Int
range <>) of Boolean;
3855 function Find_Entry_Index
(E
: Entity_Id
) return Uint
;
3856 -- Given an entry, find its index in the visible declarations of the
3857 -- corresponding concurrent type of Typ.
3859 ----------------------
3860 -- Find_Entry_Index --
3861 ----------------------
3863 function Find_Entry_Index
(E
: Entity_Id
) return Uint
is
3864 Index
: Uint
:= Uint_1
;
3865 Subp_Decl
: Entity_Id
;
3869 and then not Is_Empty_List
(Decls
)
3871 Subp_Decl
:= First
(Decls
);
3872 while Present
(Subp_Decl
) loop
3873 if Nkind
(Subp_Decl
) = N_Entry_Declaration
then
3874 if Defining_Identifier
(Subp_Decl
) = E
then
3886 end Find_Entry_Index
;
3888 -- Start of processing for Make_Select_Specific_Data_Table
3891 pragma Assert
(not Restriction_Active
(No_Dispatching_Calls
));
3893 DT_Ptr
:= Node
(First_Elmt
(Access_Disp_Table
(Typ
)));
3895 if Present
(Corresponding_Concurrent_Type
(Typ
)) then
3896 Conc_Typ
:= Corresponding_Concurrent_Type
(Typ
);
3898 if Ekind
(Conc_Typ
) = E_Protected_Type
then
3899 Decls
:= Visible_Declarations
(Protected_Definition
(
3900 Parent
(Conc_Typ
)));
3902 pragma Assert
(Ekind
(Conc_Typ
) = E_Task_Type
);
3903 Decls
:= Visible_Declarations
(Task_Definition
(
3904 Parent
(Conc_Typ
)));
3908 -- Count the non-predefined primitive operations
3910 Prim_Elmt
:= First_Elmt
(Primitive_Operations
(Typ
));
3911 while Present
(Prim_Elmt
) loop
3912 if not Is_Predefined_Dispatching_Operation
(Node
(Prim_Elmt
)) then
3913 Nb_Prim
:= Nb_Prim
+ 1;
3916 Next_Elmt
(Prim_Elmt
);
3920 Examined
: Examined_Array
(1 .. Nb_Prim
) := (others => False);
3923 Prim_Elmt
:= First_Elmt
(Primitive_Operations
(Typ
));
3924 while Present
(Prim_Elmt
) loop
3925 Prim
:= Node
(Prim_Elmt
);
3926 Prim_Pos
:= DT_Position
(Prim
);
3928 if not Is_Predefined_Dispatching_Operation
(Prim
) then
3929 pragma Assert
(UI_To_Int
(Prim_Pos
) <= Nb_Prim
);
3931 if Examined
(UI_To_Int
(Prim_Pos
)) then
3934 Examined
(UI_To_Int
(Prim_Pos
)) := True;
3937 -- The current primitive overrides an interface-level
3940 if Present
(Abstract_Interface_Alias
(Prim
)) then
3942 -- Set the primitive operation kind regardless of subprogram
3944 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
3946 Append_To
(Assignments
,
3947 Make_DT_Access_Action
(Typ
,
3952 New_Reference_To
(DT_Ptr
, Loc
),
3953 Make_Integer_Literal
(Loc
, Prim_Pos
),
3954 Prim_Op_Kind
(Prim
, Typ
))));
3956 -- Retrieve the root of the alias chain if one is present
3958 if Present
(Alias
(Prim
)) then
3960 while Present
(Alias
(Prim_Als
)) loop
3961 Prim_Als
:= Alias
(Prim_Als
);
3967 -- In the case of an entry wrapper, set the entry index
3969 if Ekind
(Prim
) = E_Procedure
3970 and then Present
(Prim_Als
)
3971 and then Is_Primitive_Wrapper
(Prim_Als
)
3972 and then Ekind
(Wrapped_Entity
(Prim_Als
)) = E_Entry
3976 -- Ada.Tags.Set_Entry_Index
3977 -- (DT_Ptr, <position>, <index>);
3979 Append_To
(Assignments
,
3980 Make_DT_Access_Action
(Typ
,
3985 New_Reference_To
(DT_Ptr
, Loc
),
3986 Make_Integer_Literal
(Loc
, Prim_Pos
),
3987 Make_Integer_Literal
(Loc
,
3989 (Wrapped_Entity
(Prim_Als
))))));
3996 Next_Elmt
(Prim_Elmt
);
4001 end Make_Select_Specific_Data_Table
;
4003 -----------------------------------
4004 -- Original_View_In_Visible_Part --
4005 -----------------------------------
4007 function Original_View_In_Visible_Part
(Typ
: Entity_Id
) return Boolean is
4008 Scop
: constant Entity_Id
:= Scope
(Typ
);
4011 -- The scope must be a package
4013 if Ekind
(Scop
) /= E_Package
4014 and then Ekind
(Scop
) /= E_Generic_Package
4019 -- A type with a private declaration has a private view declared in
4020 -- the visible part.
4022 if Has_Private_Declaration
(Typ
) then
4026 return List_Containing
(Parent
(Typ
)) =
4027 Visible_Declarations
(Specification
(Unit_Declaration_Node
(Scop
)));
4028 end Original_View_In_Visible_Part
;
4034 function Prim_Op_Kind
4036 Typ
: Entity_Id
) return Node_Id
4038 Full_Typ
: Entity_Id
:= Typ
;
4039 Loc
: constant Source_Ptr
:= Sloc
(Prim
);
4040 Prim_Op
: Entity_Id
;
4043 -- Retrieve the original primitive operation
4046 while Present
(Alias
(Prim_Op
)) loop
4047 Prim_Op
:= Alias
(Prim_Op
);
4050 if Ekind
(Typ
) = E_Record_Type
4051 and then Present
(Corresponding_Concurrent_Type
(Typ
))
4053 Full_Typ
:= Corresponding_Concurrent_Type
(Typ
);
4056 if Ekind
(Prim_Op
) = E_Function
then
4058 -- Protected function
4060 if Ekind
(Full_Typ
) = E_Protected_Type
then
4061 return New_Reference_To
(RTE
(RE_POK_Protected_Function
), Loc
);
4065 elsif Ekind
(Full_Typ
) = E_Task_Type
then
4066 return New_Reference_To
(RTE
(RE_POK_Task_Function
), Loc
);
4071 return New_Reference_To
(RTE
(RE_POK_Function
), Loc
);
4075 pragma Assert
(Ekind
(Prim_Op
) = E_Procedure
);
4077 if Ekind
(Full_Typ
) = E_Protected_Type
then
4081 if Is_Primitive_Wrapper
(Prim_Op
)
4082 and then Ekind
(Wrapped_Entity
(Prim_Op
)) = E_Entry
4084 return New_Reference_To
(RTE
(RE_POK_Protected_Entry
), Loc
);
4086 -- Protected procedure
4089 return New_Reference_To
(RTE
(RE_POK_Protected_Procedure
), Loc
);
4092 elsif Ekind
(Full_Typ
) = E_Task_Type
then
4096 if Is_Primitive_Wrapper
(Prim_Op
)
4097 and then Ekind
(Wrapped_Entity
(Prim_Op
)) = E_Entry
4099 return New_Reference_To
(RTE
(RE_POK_Task_Entry
), Loc
);
4101 -- Task "procedure". These are the internally Expander-generated
4102 -- procedures (task body for instance).
4105 return New_Reference_To
(RTE
(RE_POK_Task_Procedure
), Loc
);
4108 -- Regular procedure
4111 return New_Reference_To
(RTE
(RE_POK_Procedure
), Loc
);
4116 -------------------------
4117 -- Set_All_DT_Position --
4118 -------------------------
4120 procedure Set_All_DT_Position
(Typ
: Entity_Id
) is
4121 Parent_Typ
: constant Entity_Id
:= Etype
(Typ
);
4122 Root_Typ
: constant Entity_Id
:= Root_Type
(Typ
);
4123 First_Prim
: constant Elmt_Id
:= First_Elmt
(Primitive_Operations
(Typ
));
4124 The_Tag
: constant Entity_Id
:= First_Tag_Component
(Typ
);
4126 Adjusted
: Boolean := False;
4127 Finalized
: Boolean := False;
4134 Prim_Elmt
: Elmt_Id
;
4136 procedure Validate_Position
(Prim
: Entity_Id
);
4137 -- Check that the position assignated to Prim is completely safe
4138 -- (it has not been assigned to a previously defined primitive
4139 -- operation of Typ)
4141 -----------------------
4142 -- Validate_Position --
4143 -----------------------
4145 procedure Validate_Position
(Prim
: Entity_Id
) is
4146 Prim_Elmt
: Elmt_Id
;
4149 Prim_Elmt
:= First_Elmt
(Primitive_Operations
(Typ
));
4150 while Present
(Prim_Elmt
)
4151 and then Node
(Prim_Elmt
) /= Prim
4153 -- Primitive operations covering abstract interfaces are
4156 if Present
(Abstract_Interface_Alias
(Node
(Prim_Elmt
))) then
4159 -- Predefined dispatching operations are completely safe. They
4160 -- are allocated at fixed positions in a separate table.
4162 elsif Is_Predefined_Dispatching_Operation
(Node
(Prim_Elmt
)) then
4165 -- Aliased subprograms are safe
4167 elsif Present
(Alias
(Prim
)) then
4170 elsif DT_Position
(Node
(Prim_Elmt
)) = DT_Position
(Prim
) then
4172 -- Handle aliased subprograms
4179 Op_1
:= Node
(Prim_Elmt
);
4181 if Present
(Overridden_Operation
(Op_1
)) then
4182 Op_1
:= Overridden_Operation
(Op_1
);
4183 elsif Present
(Alias
(Op_1
)) then
4184 Op_1
:= Alias
(Op_1
);
4192 if Present
(Overridden_Operation
(Op_2
)) then
4193 Op_2
:= Overridden_Operation
(Op_2
);
4194 elsif Present
(Alias
(Op_2
)) then
4195 Op_2
:= Alias
(Op_2
);
4201 if Op_1
/= Op_2
then
4202 raise Program_Error
;
4207 Next_Elmt
(Prim_Elmt
);
4209 end Validate_Position
;
4211 -- Start of processing for Set_All_DT_Position
4214 -- Get Entry_Count of the parent
4216 if Parent_Typ
/= Typ
4217 and then DT_Entry_Count
(First_Tag_Component
(Parent_Typ
)) /= No_Uint
4219 Parent_EC
:= UI_To_Int
(DT_Entry_Count
4220 (First_Tag_Component
(Parent_Typ
)));
4225 -- C++ Case, check that pragma CPP_Class, CPP_Virtual and CPP_Vtable
4226 -- give a coherent set of information
4228 if Is_CPP_Class
(Root_Typ
) then
4230 -- Compute the number of primitive operations in the main Vtable
4231 -- Set their position:
4232 -- - where it was set if overriden or inherited
4233 -- - after the end of the parent vtable otherwise
4235 Prim_Elmt
:= First_Prim
;
4237 while Present
(Prim_Elmt
) loop
4238 Prim
:= Node
(Prim_Elmt
);
4240 if not Is_CPP_Class
(Typ
) then
4241 Set_DTC_Entity
(Prim
, The_Tag
);
4243 elsif Present
(Alias
(Prim
)) then
4244 Set_DTC_Entity
(Prim
, DTC_Entity
(Alias
(Prim
)));
4245 Set_DT_Position
(Prim
, DT_Position
(Alias
(Prim
)));
4247 elsif No
(DTC_Entity
(Prim
)) and then Is_CPP_Class
(Typ
) then
4248 Error_Msg_NE
("is a primitive operation of&," &
4249 " pragma Cpp_Virtual required", Prim
, Typ
);
4252 if DTC_Entity
(Prim
) = The_Tag
then
4254 -- Get the slot from the parent subprogram if any
4260 H
:= Homonym
(Prim
);
4261 while Present
(H
) loop
4262 if Present
(DTC_Entity
(H
))
4263 and then Root_Type
(Scope
(DTC_Entity
(H
))) = Root_Typ
4265 Set_DT_Position
(Prim
, DT_Position
(H
));
4273 -- Otherwise take the canonical slot after the end of the
4276 if DT_Position
(Prim
) = No_Uint
then
4277 Nb_Prim
:= Nb_Prim
+ 1;
4278 Set_DT_Position
(Prim
, UI_From_Int
(Parent_EC
+ Nb_Prim
));
4280 elsif UI_To_Int
(DT_Position
(Prim
)) > Parent_EC
then
4281 Nb_Prim
:= Nb_Prim
+ 1;
4285 Next_Elmt
(Prim_Elmt
);
4288 -- Check that the declared size of the Vtable is bigger or equal
4289 -- than the number of primitive operations (if bigger it means that
4290 -- some of the c++ virtual functions were not imported, that is
4293 if DT_Entry_Count
(The_Tag
) = No_Uint
4294 or else not Is_CPP_Class
(Typ
)
4296 Set_DT_Entry_Count
(The_Tag
, UI_From_Int
(Parent_EC
+ Nb_Prim
));
4298 elsif UI_To_Int
(DT_Entry_Count
(The_Tag
)) < Parent_EC
+ Nb_Prim
then
4299 Error_Msg_N
("not enough room in the Vtable for all virtual"
4300 & " functions", The_Tag
);
4303 -- Check that Positions are not duplicate nor outside the range of
4307 Size
: constant Int
:= UI_To_Int
(DT_Entry_Count
(The_Tag
));
4309 Prim_Pos_Table
: array (1 .. Size
) of Entity_Id
:=
4313 Prim_Elmt
:= First_Prim
;
4314 while Present
(Prim_Elmt
) loop
4315 Prim
:= Node
(Prim_Elmt
);
4317 if DTC_Entity
(Prim
) = The_Tag
then
4318 Pos
:= UI_To_Int
(DT_Position
(Prim
));
4320 if Pos
not in Prim_Pos_Table
'Range then
4322 ("position not in range of virtual table", Prim
);
4324 elsif Present
(Prim_Pos_Table
(Pos
)) then
4325 Error_Msg_NE
("cannot be at the same position in the"
4326 & " vtable than&", Prim
, Prim_Pos_Table
(Pos
));
4329 Prim_Pos_Table
(Pos
) := Prim
;
4333 Next_Elmt
(Prim_Elmt
);
4337 -- Generate listing showing the contents of the dispatch tables
4339 if Debug_Flag_ZZ
then
4343 -- For regular Ada tagged types, just set the DT_Position for
4344 -- each primitive operation. Perform some sanity checks to avoid
4345 -- to build completely inconsistant dispatch tables.
4347 -- Note that the _Size primitive is always set at position 1 in order
4348 -- to comply with the needs of Ada.Tags.Parent_Size (see documentation
4352 -- First stage: Set the DTC entity of all the primitive operations
4353 -- This is required to properly read the DT_Position attribute in
4354 -- the latter stages.
4356 Prim_Elmt
:= First_Prim
;
4358 while Present
(Prim_Elmt
) loop
4359 Count_Prim
:= Count_Prim
+ 1;
4360 Prim
:= Node
(Prim_Elmt
);
4362 -- Ada 2005 (AI-251)
4364 if Present
(Abstract_Interface_Alias
(Prim
))
4365 and then Is_Interface
(Scope
(DTC_Entity
4366 (Abstract_Interface_Alias
(Prim
))))
4368 Set_DTC_Entity
(Prim
,
4371 Iface
=> Scope
(DTC_Entity
4372 (Abstract_Interface_Alias
(Prim
)))));
4375 Set_DTC_Entity
(Prim
, The_Tag
);
4378 -- Clear any previous value of the DT_Position attribute. In this
4379 -- way we ensure that the final position of all the primitives is
4380 -- stablished by the following stages of this algorithm.
4382 Set_DT_Position
(Prim
, No_Uint
);
4384 Next_Elmt
(Prim_Elmt
);
4388 Fixed_Prim
: array (Int
range 0 .. Parent_EC
+ Count_Prim
)
4389 of Boolean := (others => False);
4394 -- Second stage: Register fixed entries
4397 Prim_Elmt
:= First_Prim
;
4398 while Present
(Prim_Elmt
) loop
4399 Prim
:= Node
(Prim_Elmt
);
4401 -- Predefined primitives have a separate table and all its
4402 -- entries are at predefined fixed positions
4404 if Is_Predefined_Dispatching_Operation
(Prim
) then
4405 Set_DT_Position
(Prim
, Default_Prim_Op_Position
(Prim
));
4407 -- Overriding interface primitives of an ancestor
4409 elsif DT_Position
(Prim
) = No_Uint
4410 and then Present
(Abstract_Interface_Alias
(Prim
))
4411 and then Present
(DTC_Entity
4412 (Abstract_Interface_Alias
(Prim
)))
4413 and then DT_Position
(Abstract_Interface_Alias
(Prim
))
4415 and then Is_Inherited_Operation
(Prim
)
4416 and then Is_Ancestor
(Scope
4418 (Abstract_Interface_Alias
(Prim
))),
4421 Set_DT_Position
(Prim
,
4422 DT_Position
(Abstract_Interface_Alias
(Prim
)));
4423 Set_DT_Position
(Alias
(Prim
),
4424 DT_Position
(Abstract_Interface_Alias
(Prim
)));
4425 Fixed_Prim
(UI_To_Int
(DT_Position
(Prim
))) := True;
4427 -- Overriding primitives must use the same entry as the
4428 -- overriden primitive
4430 elsif DT_Position
(Prim
) = No_Uint
4431 and then Present
(Alias
(Prim
))
4432 and then Present
(DTC_Entity
(Alias
(Prim
)))
4433 and then DT_Position
(Alias
(Prim
)) /= No_Uint
4434 and then Is_Inherited_Operation
(Prim
)
4435 and then Is_Ancestor
(Scope
(DTC_Entity
(Alias
(Prim
))), Typ
)
4438 while not (Present
(DTC_Entity
(E
))
4439 or else DT_Position
(E
) = No_Uint
)
4440 and then Present
(Alias
(E
))
4445 pragma Assert
(Present
(DTC_Entity
(E
))
4447 DT_Position
(E
) /= No_Uint
);
4449 Set_DT_Position
(Prim
, DT_Position
(E
));
4450 Fixed_Prim
(UI_To_Int
(DT_Position
(E
))) := True;
4452 -- If this is not the last element in the chain continue
4453 -- traversing the chain. This is required to properly
4454 -- handling renamed primitives
4456 while Present
(Alias
(E
)) loop
4458 Fixed_Prim
(UI_To_Int
(DT_Position
(E
))) := True;
4462 Next_Elmt
(Prim_Elmt
);
4465 -- Third stage: Fix the position of all the new primitives
4466 -- Entries associated with primitives covering interfaces
4467 -- are handled in a latter round.
4469 Prim_Elmt
:= First_Prim
;
4470 while Present
(Prim_Elmt
) loop
4471 Prim
:= Node
(Prim_Elmt
);
4473 -- Skip primitives previously set entries
4475 if Is_Predefined_Dispatching_Operation
(Prim
) then
4478 elsif DT_Position
(Prim
) /= No_Uint
then
4481 elsif Etype
(DTC_Entity
(Prim
)) /= RTE
(RE_Tag
) then
4484 -- Primitives covering interface primitives are
4487 elsif Present
(Abstract_Interface_Alias
(Prim
)) then
4491 -- Take the next available position in the DT
4494 Nb_Prim
:= Nb_Prim
+ 1;
4495 exit when not Fixed_Prim
(Nb_Prim
);
4498 Set_DT_Position
(Prim
, UI_From_Int
(Nb_Prim
));
4499 Fixed_Prim
(Nb_Prim
) := True;
4502 Next_Elmt
(Prim_Elmt
);
4506 -- Fourth stage: Complete the decoration of primitives covering
4507 -- interfaces (that is, propagate the DT_Position attribute
4508 -- from the aliased primitive)
4510 Prim_Elmt
:= First_Prim
;
4511 while Present
(Prim_Elmt
) loop
4512 Prim
:= Node
(Prim_Elmt
);
4514 if DT_Position
(Prim
) = No_Uint
4515 and then Present
(Abstract_Interface_Alias
(Prim
))
4517 -- Check if this entry will be placed in the primary DT
4519 if Etype
(DTC_Entity
(Abstract_Interface_Alias
(Prim
)))
4522 pragma Assert
(DT_Position
(Alias
(Prim
)) /= No_Uint
);
4523 Set_DT_Position
(Prim
, DT_Position
(Alias
(Prim
)));
4525 -- Otherwise it will be placed in the secondary DT
4529 (DT_Position
(Abstract_Interface_Alias
(Prim
)) /= No_Uint
);
4531 Set_DT_Position
(Prim
,
4532 DT_Position
(Abstract_Interface_Alias
(Prim
)));
4536 Next_Elmt
(Prim_Elmt
);
4539 -- Generate listing showing the contents of the dispatch tables.
4540 -- This action is done before some further static checks because
4541 -- in case of critical errors caused by a wrong dispatch table
4542 -- we need to see the contents of such table.
4544 if Debug_Flag_ZZ
then
4548 -- Final stage: Ensure that the table is correct plus some further
4549 -- verifications concerning the primitives.
4551 Prim_Elmt
:= First_Prim
;
4553 while Present
(Prim_Elmt
) loop
4554 Prim
:= Node
(Prim_Elmt
);
4556 -- At this point all the primitives MUST have a position
4557 -- in the dispatch table
4559 if DT_Position
(Prim
) = No_Uint
then
4560 raise Program_Error
;
4563 -- Calculate real size of the dispatch table
4565 if not Is_Predefined_Dispatching_Operation
(Prim
)
4566 and then UI_To_Int
(DT_Position
(Prim
)) > DT_Length
4568 DT_Length
:= UI_To_Int
(DT_Position
(Prim
));
4571 -- Ensure that the asignated position to non-predefined
4572 -- dispatching operations in the dispatch table is correct.
4574 if not Is_Predefined_Dispatching_Operation
(Prim
) then
4575 Validate_Position
(Prim
);
4578 if Chars
(Prim
) = Name_Finalize
then
4582 if Chars
(Prim
) = Name_Adjust
then
4586 -- An abstract operation cannot be declared in the private part
4587 -- for a visible abstract type, because it could never be over-
4588 -- ridden. For explicit declarations this is checked at the
4589 -- point of declaration, but for inherited operations it must
4590 -- be done when building the dispatch table. Input is excluded
4593 if Is_Abstract
(Typ
)
4594 and then Is_Abstract
(Prim
)
4595 and then Present
(Alias
(Prim
))
4596 and then Is_Derived_Type
(Typ
)
4597 and then In_Private_Part
(Current_Scope
)
4599 List_Containing
(Parent
(Prim
)) =
4600 Private_Declarations
4601 (Specification
(Unit_Declaration_Node
(Current_Scope
)))
4602 and then Original_View_In_Visible_Part
(Typ
)
4604 -- We exclude Input and Output stream operations because
4605 -- Limited_Controlled inherits useless Input and Output
4606 -- stream operations from Root_Controlled, which can
4607 -- never be overridden.
4609 if not Is_TSS
(Prim
, TSS_Stream_Input
)
4611 not Is_TSS
(Prim
, TSS_Stream_Output
)
4614 ("abstract inherited private operation&" &
4615 " must be overridden ('R'M 3.9.3(10))",
4616 Parent
(Typ
), Prim
);
4620 Next_Elmt
(Prim_Elmt
);
4625 if Is_Controlled
(Typ
) then
4626 if not Finalized
then
4628 ("controlled type has no explicit Finalize method?", Typ
);
4630 elsif not Adjusted
then
4632 ("controlled type has no explicit Adjust method?", Typ
);
4636 -- Set the final size of the Dispatch Table
4638 Set_DT_Entry_Count
(The_Tag
, UI_From_Int
(DT_Length
));
4640 -- The derived type must have at least as many components as its
4641 -- parent (for root types, the Etype points back to itself
4642 -- and the test should not fail)
4644 -- This test fails compiling the partial view of a tagged type
4645 -- derived from an interface which defines the overriding subprogram
4646 -- in the private part. This needs further investigation???
4648 if not Has_Private_Declaration
(Typ
) then
4650 DT_Entry_Count
(The_Tag
) >=
4651 DT_Entry_Count
(First_Tag_Component
(Parent_Typ
)));
4655 end Set_All_DT_Position
;
4657 -----------------------------
4658 -- Set_Default_Constructor --
4659 -----------------------------
4661 procedure Set_Default_Constructor
(Typ
: Entity_Id
) is
4668 -- Look for the default constructor entity. For now only the
4669 -- default constructor has the flag Is_Constructor.
4671 E
:= Next_Entity
(Typ
);
4673 and then (Ekind
(E
) /= E_Function
or else not Is_Constructor
(E
))
4678 -- Create the init procedure
4682 Init
:= Make_Defining_Identifier
(Loc
, Make_Init_Proc_Name
(Typ
));
4683 Param
:= Make_Defining_Identifier
(Loc
, Name_X
);
4686 Make_Subprogram_Declaration
(Loc
,
4687 Make_Procedure_Specification
(Loc
,
4688 Defining_Unit_Name
=> Init
,
4689 Parameter_Specifications
=> New_List
(
4690 Make_Parameter_Specification
(Loc
,
4691 Defining_Identifier
=> Param
,
4692 Parameter_Type
=> New_Reference_To
(Typ
, Loc
))))));
4694 Set_Init_Proc
(Typ
, Init
);
4695 Set_Is_Imported
(Init
);
4696 Set_Interface_Name
(Init
, Interface_Name
(E
));
4697 Set_Convention
(Init
, Convention_C
);
4698 Set_Is_Public
(Init
);
4699 Set_Has_Completion
(Init
);
4701 -- If there are no constructors, mark the type as abstract since we
4702 -- won't be able to declare objects of that type.
4705 Set_Is_Abstract
(Typ
);
4707 end Set_Default_Constructor
;
4713 function Tagged_Kind
(T
: Entity_Id
) return Node_Id
is
4714 Conc_Typ
: Entity_Id
;
4715 Loc
: constant Source_Ptr
:= Sloc
(T
);
4719 (Is_Tagged_Type
(T
) and then RTE_Available
(RE_Tagged_Kind
));
4723 if Is_Abstract
(T
) then
4724 if Is_Limited_Record
(T
) then
4725 return New_Reference_To
(RTE
(RE_TK_Abstract_Limited_Tagged
), Loc
);
4727 return New_Reference_To
(RTE
(RE_TK_Abstract_Tagged
), Loc
);
4732 elsif Is_Concurrent_Record_Type
(T
) then
4733 Conc_Typ
:= Corresponding_Concurrent_Type
(T
);
4735 if Ekind
(Conc_Typ
) = E_Protected_Type
then
4736 return New_Reference_To
(RTE
(RE_TK_Protected
), Loc
);
4738 pragma Assert
(Ekind
(Conc_Typ
) = E_Task_Type
);
4739 return New_Reference_To
(RTE
(RE_TK_Task
), Loc
);
4742 -- Regular tagged kinds
4745 if Is_Limited_Record
(T
) then
4746 return New_Reference_To
(RTE
(RE_TK_Limited_Tagged
), Loc
);
4748 return New_Reference_To
(RTE
(RE_TK_Tagged
), Loc
);
4757 procedure Write_DT
(Typ
: Entity_Id
) is
4762 -- Protect this procedure against wrong usage. Required because it will
4763 -- be used directly from GDB
4765 if not (Typ
in First_Node_Id
.. Last_Node_Id
)
4766 or else not Is_Tagged_Type
(Typ
)
4768 Write_Str
("wrong usage: Write_DT must be used with tagged types");
4773 Write_Int
(Int
(Typ
));
4775 Write_Name
(Chars
(Typ
));
4777 if Is_Interface
(Typ
) then
4778 Write_Str
(" is interface");
4783 Elmt
:= First_Elmt
(Primitive_Operations
(Typ
));
4784 while Present
(Elmt
) loop
4785 Prim
:= Node
(Elmt
);
4788 -- Indicate if this primitive will be allocated in the primary
4789 -- dispatch table or in a secondary dispatch table associated
4790 -- with an abstract interface type
4792 if Present
(DTC_Entity
(Prim
)) then
4793 if Etype
(DTC_Entity
(Prim
)) = RTE
(RE_Tag
) then
4800 -- Output the node of this primitive operation and its name
4802 Write_Int
(Int
(Prim
));
4805 if Is_Predefined_Dispatching_Operation
(Prim
) then
4806 Write_Str
("(predefined) ");
4809 Write_Name
(Chars
(Prim
));
4811 -- Indicate if this primitive has an aliased primitive
4813 if Present
(Alias
(Prim
)) then
4814 Write_Str
(" (alias = ");
4815 Write_Int
(Int
(Alias
(Prim
)));
4817 -- If the DTC_Entity attribute is already set we can also output
4818 -- the name of the interface covered by this primitive (if any)
4820 if Present
(DTC_Entity
(Alias
(Prim
)))
4821 and then Is_Interface
(Scope
(DTC_Entity
(Alias
(Prim
))))
4823 Write_Str
(" from interface ");
4824 Write_Name
(Chars
(Scope
(DTC_Entity
(Alias
(Prim
)))));
4827 if Present
(Abstract_Interface_Alias
(Prim
)) then
4828 Write_Str
(", AI_Alias of ");
4829 Write_Name
(Chars
(Scope
(DTC_Entity
4830 (Abstract_Interface_Alias
(Prim
)))));
4832 Write_Int
(Int
(Abstract_Interface_Alias
(Prim
)));
4838 -- Display the final position of this primitive in its associated
4839 -- (primary or secondary) dispatch table
4841 if Present
(DTC_Entity
(Prim
))
4842 and then DT_Position
(Prim
) /= No_Uint
4844 Write_Str
(" at #");
4845 Write_Int
(UI_To_Int
(DT_Position
(Prim
)));
4848 if Is_Abstract
(Prim
) then
4849 Write_Str
(" is abstract;");