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