1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2005 Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, 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 Einfo
; use Einfo
;
30 with Elists
; use Elists
;
31 with Errout
; use Errout
;
32 with Exp_Ch7
; use Exp_Ch7
;
33 with Exp_Tss
; use Exp_Tss
;
34 with Exp_Util
; use Exp_Util
;
35 with Fname
; use Fname
;
36 with Itypes
; use Itypes
;
38 with Nlists
; use Nlists
;
39 with Nmake
; use Nmake
;
41 with Rtsfind
; use Rtsfind
;
42 with Sem_Disp
; use Sem_Disp
;
43 with Sem_Res
; use Sem_Res
;
44 with Sem_Util
; use Sem_Util
;
45 with Sinfo
; use Sinfo
;
46 with Snames
; use Snames
;
47 with Stand
; use Stand
;
48 with Tbuild
; use Tbuild
;
49 with Uintp
; use Uintp
;
51 package body Exp_Disp
is
53 Ada_Actions
: constant array (DT_Access_Action
) of RE_Id
:=
54 (CW_Membership
=> RE_CW_Membership
,
55 DT_Entry_Size
=> RE_DT_Entry_Size
,
56 DT_Prologue_Size
=> RE_DT_Prologue_Size
,
57 Get_Expanded_Name
=> RE_Get_Expanded_Name
,
58 Get_External_Tag
=> RE_Get_External_Tag
,
59 Get_Prim_Op_Address
=> RE_Get_Prim_Op_Address
,
60 Get_RC_Offset
=> RE_Get_RC_Offset
,
61 Get_Remotely_Callable
=> RE_Get_Remotely_Callable
,
62 Get_TSD
=> RE_Get_TSD
,
63 Inherit_DT
=> RE_Inherit_DT
,
64 Inherit_TSD
=> RE_Inherit_TSD
,
65 Register_Tag
=> RE_Register_Tag
,
66 Set_Expanded_Name
=> RE_Set_Expanded_Name
,
67 Set_External_Tag
=> RE_Set_External_Tag
,
68 Set_Prim_Op_Address
=> RE_Set_Prim_Op_Address
,
69 Set_RC_Offset
=> RE_Set_RC_Offset
,
70 Set_Remotely_Callable
=> RE_Set_Remotely_Callable
,
71 Set_TSD
=> RE_Set_TSD
,
72 TSD_Entry_Size
=> RE_TSD_Entry_Size
,
73 TSD_Prologue_Size
=> RE_TSD_Prologue_Size
);
75 CPP_Actions
: constant array (DT_Access_Action
) of RE_Id
:=
76 (CW_Membership
=> RE_CPP_CW_Membership
,
77 DT_Entry_Size
=> RE_CPP_DT_Entry_Size
,
78 DT_Prologue_Size
=> RE_CPP_DT_Prologue_Size
,
79 Get_Expanded_Name
=> RE_CPP_Get_Expanded_Name
,
80 Get_External_Tag
=> RE_CPP_Get_External_Tag
,
81 Get_Prim_Op_Address
=> RE_CPP_Get_Prim_Op_Address
,
82 Get_RC_Offset
=> RE_CPP_Get_RC_Offset
,
83 Get_Remotely_Callable
=> RE_CPP_Get_Remotely_Callable
,
84 Get_TSD
=> RE_CPP_Get_TSD
,
85 Inherit_DT
=> RE_CPP_Inherit_DT
,
86 Inherit_TSD
=> RE_CPP_Inherit_TSD
,
87 Register_Tag
=> RE_CPP_Register_Tag
,
88 Set_Expanded_Name
=> RE_CPP_Set_Expanded_Name
,
89 Set_External_Tag
=> RE_CPP_Set_External_Tag
,
90 Set_Prim_Op_Address
=> RE_CPP_Set_Prim_Op_Address
,
91 Set_RC_Offset
=> RE_CPP_Set_RC_Offset
,
92 Set_Remotely_Callable
=> RE_CPP_Set_Remotely_Callable
,
93 Set_TSD
=> RE_CPP_Set_TSD
,
94 TSD_Entry_Size
=> RE_CPP_TSD_Entry_Size
,
95 TSD_Prologue_Size
=> RE_CPP_TSD_Prologue_Size
);
97 Action_Is_Proc
: constant array (DT_Access_Action
) of Boolean :=
98 (CW_Membership
=> False,
99 DT_Entry_Size
=> False,
100 DT_Prologue_Size
=> False,
101 Get_Expanded_Name
=> False,
102 Get_External_Tag
=> False,
103 Get_Prim_Op_Address
=> False,
104 Get_Remotely_Callable
=> False,
105 Get_RC_Offset
=> False,
109 Register_Tag
=> True,
110 Set_Expanded_Name
=> True,
111 Set_External_Tag
=> True,
112 Set_Prim_Op_Address
=> True,
113 Set_RC_Offset
=> True,
114 Set_Remotely_Callable
=> True,
116 TSD_Entry_Size
=> False,
117 TSD_Prologue_Size
=> False);
119 Action_Nb_Arg
: constant array (DT_Access_Action
) of Int
:=
122 DT_Prologue_Size
=> 0,
123 Get_Expanded_Name
=> 1,
124 Get_External_Tag
=> 1,
125 Get_Prim_Op_Address
=> 2,
127 Get_Remotely_Callable
=> 1,
132 Set_Expanded_Name
=> 2,
133 Set_External_Tag
=> 2,
134 Set_Prim_Op_Address
=> 3,
136 Set_Remotely_Callable
=> 2,
139 TSD_Prologue_Size
=> 0);
141 function Original_View_In_Visible_Part
(Typ
: Entity_Id
) return Boolean;
142 -- Check if the type has a private view or if the public view appears
143 -- in the visible part of a package spec.
145 -----------------------------
146 -- Expand_Dispatching_Call --
147 -----------------------------
149 procedure Expand_Dispatching_Call
(Call_Node
: Node_Id
) is
150 Loc
: constant Source_Ptr
:= Sloc
(Call_Node
);
151 Call_Typ
: constant Entity_Id
:= Etype
(Call_Node
);
153 Ctrl_Arg
: constant Node_Id
:= Controlling_Argument
(Call_Node
);
154 Param_List
: constant List_Id
:= Parameter_Associations
(Call_Node
);
155 Subp
: Entity_Id
:= Entity
(Name
(Call_Node
));
159 New_Call_Name
: Node_Id
;
160 New_Params
: List_Id
:= No_List
;
163 Subp_Ptr_Typ
: Entity_Id
;
164 Subp_Typ
: Entity_Id
;
166 Eq_Prim_Op
: Entity_Id
:= Empty
;
167 Controlling_Tag
: Node_Id
;
169 function New_Value
(From
: Node_Id
) return Node_Id
;
170 -- From is the original Expression. New_Value is equivalent to a call
171 -- to Duplicate_Subexpr with an explicit dereference when From is an
174 function Controlling_Type
(Subp
: Entity_Id
) return Entity_Id
;
175 -- Returns the tagged type for which Subp is a primitive subprogram
181 function New_Value
(From
: Node_Id
) return Node_Id
is
182 Res
: constant Node_Id
:= Duplicate_Subexpr
(From
);
184 if Is_Access_Type
(Etype
(From
)) then
185 return Make_Explicit_Dereference
(Sloc
(From
), Res
);
191 ----------------------
192 -- Controlling_Type --
193 ----------------------
195 function Controlling_Type
(Subp
: Entity_Id
) return Entity_Id
is
197 if Ekind
(Subp
) = E_Function
198 and then Has_Controlling_Result
(Subp
)
200 return Base_Type
(Etype
(Subp
));
204 Formal
: Entity_Id
:= First_Formal
(Subp
);
207 while Present
(Formal
) loop
208 if Is_Controlling_Formal
(Formal
) then
209 if Is_Access_Type
(Etype
(Formal
)) then
210 return Base_Type
(Designated_Type
(Etype
(Formal
)));
212 return Base_Type
(Etype
(Formal
));
216 Next_Formal
(Formal
);
221 -- Controlling type not found (should never happen)
224 end Controlling_Type
;
226 -- Start of processing for Expand_Dispatching_Call
229 -- If this is an inherited operation that was overridden, the body
230 -- that is being called is its alias.
232 if Present
(Alias
(Subp
))
233 and then Is_Inherited_Operation
(Subp
)
234 and then No
(DTC_Entity
(Subp
))
236 Subp
:= Alias
(Subp
);
239 -- Expand_Dispatching_Call is called directly from the semantics,
240 -- so we need a check to see whether expansion is active before
243 if not Expander_Active
then
247 -- Definition of the class-wide type and the tagged type
249 -- If the controlling argument is itself a tag rather than a tagged
250 -- object, then use the class-wide type associated with the subprogram's
251 -- controlling type. This case can occur when a call to an inherited
252 -- primitive has an actual that originated from a default parameter
253 -- given by a tag-indeterminate call and when there is no other
254 -- controlling argument providing the tag (AI-239 requires dispatching).
255 -- This capability of dispatching directly by tag is also needed by the
256 -- implementation of AI-260 (for the generic dispatching constructors).
258 if Etype
(Ctrl_Arg
) = RTE
(RE_Tag
) then
259 CW_Typ
:= Class_Wide_Type
(Controlling_Type
(Subp
));
261 elsif Is_Access_Type
(Etype
(Ctrl_Arg
)) then
262 CW_Typ
:= Designated_Type
(Etype
(Ctrl_Arg
));
265 CW_Typ
:= Etype
(Ctrl_Arg
);
268 Typ
:= Root_Type
(CW_Typ
);
270 if not Is_Limited_Type
(Typ
) then
271 Eq_Prim_Op
:= Find_Prim_Op
(Typ
, Name_Op_Eq
);
274 if Is_CPP_Class
(Root_Type
(Typ
)) then
276 -- Create a new parameter list with the displaced 'this'
278 New_Params
:= New_List
;
279 Param
:= First_Actual
(Call_Node
);
280 while Present
(Param
) loop
282 -- We assume that dispatching through the main dispatch table
283 -- (referenced by Tag_Component) doesn't require a displacement
284 -- so the expansion below is only done when dispatching on
285 -- another vtable pointer, in which case the first argument
286 -- is expanded into :
288 -- typ!(Displaced_This (Address!(Param)))
291 and then DTC_Entity
(Subp
) /= Tag_Component
(Typ
)
293 Append_To
(New_Params
,
295 Unchecked_Convert_To
(Etype
(Param
),
296 Make_Function_Call
(Loc
,
297 Name
=> New_Reference_To
(RTE
(RE_Displaced_This
), Loc
),
298 Parameter_Associations
=> New_List
(
302 Make_Unchecked_Type_Conversion
(Loc
,
304 New_Reference_To
(RTE
(RE_Address
), Loc
),
305 Expression
=> Relocate_Node
(Param
)),
309 Make_Selected_Component
(Loc
,
310 Prefix
=> Duplicate_Subexpr
(Ctrl_Arg
),
312 New_Reference_To
(DTC_Entity
(Subp
), Loc
)),
316 Make_Integer_Literal
(Loc
, DT_Position
(Subp
))))));
319 Append_To
(New_Params
, Relocate_Node
(Param
));
325 elsif Present
(Param_List
) then
327 -- Generate the Tag checks when appropriate
329 New_Params
:= New_List
;
331 Param
:= First_Actual
(Call_Node
);
332 while Present
(Param
) loop
334 -- No tag check with itself
336 if Param
= Ctrl_Arg
then
337 Append_To
(New_Params
,
338 Duplicate_Subexpr_Move_Checks
(Param
));
340 -- No tag check for parameter whose type is neither tagged nor
341 -- access to tagged (for access parameters)
343 elsif No
(Find_Controlling_Arg
(Param
)) then
344 Append_To
(New_Params
, Relocate_Node
(Param
));
346 -- No tag check for function dispatching on result if the
347 -- Tag given by the context is this one
349 elsif Find_Controlling_Arg
(Param
) = Ctrl_Arg
then
350 Append_To
(New_Params
, Relocate_Node
(Param
));
352 -- "=" is the only dispatching operation allowed to get
353 -- operands with incompatible tags (it just returns false).
354 -- We use Duplicate_Subexpr_Move_Checks instead of calling
355 -- Relocate_Node because the value will be duplicated to
358 elsif Subp
= Eq_Prim_Op
then
359 Append_To
(New_Params
,
360 Duplicate_Subexpr_Move_Checks
(Param
));
362 -- No check in presence of suppress flags
364 elsif Tag_Checks_Suppressed
(Etype
(Param
))
365 or else (Is_Access_Type
(Etype
(Param
))
366 and then Tag_Checks_Suppressed
367 (Designated_Type
(Etype
(Param
))))
369 Append_To
(New_Params
, Relocate_Node
(Param
));
371 -- Optimization: no tag checks if the parameters are identical
373 elsif Is_Entity_Name
(Param
)
374 and then Is_Entity_Name
(Ctrl_Arg
)
375 and then Entity
(Param
) = Entity
(Ctrl_Arg
)
377 Append_To
(New_Params
, Relocate_Node
(Param
));
379 -- Now we need to generate the Tag check
382 -- Generate code for tag equality check
383 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
385 Insert_Action
(Ctrl_Arg
,
386 Make_Implicit_If_Statement
(Call_Node
,
390 Make_Selected_Component
(Loc
,
391 Prefix
=> New_Value
(Ctrl_Arg
),
393 New_Reference_To
(Tag_Component
(Typ
), Loc
)),
396 Make_Selected_Component
(Loc
,
398 Unchecked_Convert_To
(Typ
, New_Value
(Param
)),
400 New_Reference_To
(Tag_Component
(Typ
), Loc
))),
403 New_List
(New_Constraint_Error
(Loc
))));
405 Append_To
(New_Params
, Relocate_Node
(Param
));
412 -- Generate the appropriate subprogram pointer type
414 if Etype
(Subp
) = Typ
then
417 Res_Typ
:= Etype
(Subp
);
420 Subp_Typ
:= Create_Itype
(E_Subprogram_Type
, Call_Node
);
421 Subp_Ptr_Typ
:= Create_Itype
(E_Access_Subprogram_Type
, Call_Node
);
422 Set_Etype
(Subp_Typ
, Res_Typ
);
423 Init_Size_Align
(Subp_Ptr_Typ
);
424 Set_Returns_By_Ref
(Subp_Typ
, Returns_By_Ref
(Subp
));
426 -- Create a new list of parameters which is a copy of the old formal
427 -- list including the creation of a new set of matching entities.
430 Old_Formal
: Entity_Id
:= First_Formal
(Subp
);
431 New_Formal
: Entity_Id
;
435 if Present
(Old_Formal
) then
436 New_Formal
:= New_Copy
(Old_Formal
);
437 Set_First_Entity
(Subp_Typ
, New_Formal
);
438 Param
:= First_Actual
(Call_Node
);
441 Set_Scope
(New_Formal
, Subp_Typ
);
443 -- Change all the controlling argument types to be class-wide
444 -- to avoid a recursion in dispatching.
446 if Is_Controlling_Formal
(New_Formal
) then
447 Set_Etype
(New_Formal
, Etype
(Param
));
450 if Is_Itype
(Etype
(New_Formal
)) then
451 Extra
:= New_Copy
(Etype
(New_Formal
));
453 if Ekind
(Extra
) = E_Record_Subtype
454 or else Ekind
(Extra
) = E_Class_Wide_Subtype
456 Set_Cloned_Subtype
(Extra
, Etype
(New_Formal
));
459 Set_Etype
(New_Formal
, Extra
);
460 Set_Scope
(Etype
(New_Formal
), Subp_Typ
);
464 Next_Formal
(Old_Formal
);
465 exit when No
(Old_Formal
);
467 Set_Next_Entity
(New_Formal
, New_Copy
(Old_Formal
));
468 Next_Entity
(New_Formal
);
471 Set_Last_Entity
(Subp_Typ
, Extra
);
473 -- Copy extra formals
475 New_Formal
:= First_Entity
(Subp_Typ
);
476 while Present
(New_Formal
) loop
477 if Present
(Extra_Constrained
(New_Formal
)) then
478 Set_Extra_Formal
(Extra
,
479 New_Copy
(Extra_Constrained
(New_Formal
)));
480 Extra
:= Extra_Formal
(Extra
);
481 Set_Extra_Constrained
(New_Formal
, Extra
);
483 elsif Present
(Extra_Accessibility
(New_Formal
)) then
484 Set_Extra_Formal
(Extra
,
485 New_Copy
(Extra_Accessibility
(New_Formal
)));
486 Extra
:= Extra_Formal
(Extra
);
487 Set_Extra_Accessibility
(New_Formal
, Extra
);
490 Next_Formal
(New_Formal
);
495 Set_Etype
(Subp_Ptr_Typ
, Subp_Ptr_Typ
);
496 Set_Directly_Designated_Type
(Subp_Ptr_Typ
, Subp_Typ
);
498 -- If the controlling argument is a value of type Ada.Tag then
499 -- use it directly. Otherwise, the tag must be extracted from
500 -- the controlling object.
502 if Etype
(Ctrl_Arg
) = RTE
(RE_Tag
) then
503 Controlling_Tag
:= Duplicate_Subexpr
(Ctrl_Arg
);
507 Make_Selected_Component
(Loc
,
508 Prefix
=> Duplicate_Subexpr_Move_Checks
(Ctrl_Arg
),
509 Selector_Name
=> New_Reference_To
(DTC_Entity
(Subp
), Loc
));
513 -- Subp_Ptr_Typ!(Get_Prim_Op_Address (Ctrl._Tag, pos));
516 Unchecked_Convert_To
(Subp_Ptr_Typ
,
517 Make_DT_Access_Action
(Typ
,
518 Action
=> Get_Prim_Op_Address
,
527 Make_Integer_Literal
(Loc
, DT_Position
(Subp
)))));
529 if Nkind
(Call_Node
) = N_Function_Call
then
531 Make_Function_Call
(Loc
,
532 Name
=> New_Call_Name
,
533 Parameter_Associations
=> New_Params
);
535 -- If this is a dispatching "=", we must first compare the tags so
536 -- we generate: x.tag = y.tag and then x = y
538 if Subp
= Eq_Prim_Op
then
539 Param
:= First_Actual
(Call_Node
);
545 Make_Selected_Component
(Loc
,
546 Prefix
=> New_Value
(Param
),
548 New_Reference_To
(Tag_Component
(Typ
), Loc
)),
551 Make_Selected_Component
(Loc
,
553 Unchecked_Convert_To
(Typ
,
554 New_Value
(Next_Actual
(Param
))),
556 New_Reference_To
(Tag_Component
(Typ
), Loc
))),
558 Right_Opnd
=> New_Call
);
563 Make_Procedure_Call_Statement
(Loc
,
564 Name
=> New_Call_Name
,
565 Parameter_Associations
=> New_Params
);
568 Rewrite
(Call_Node
, New_Call
);
569 Analyze_And_Resolve
(Call_Node
, Call_Typ
);
570 end Expand_Dispatching_Call
;
576 function Fill_DT_Entry
581 Typ
: constant Entity_Id
:= Scope
(DTC_Entity
(Prim
));
582 DT_Ptr
: constant Entity_Id
:= Access_Disp_Table
(Typ
);
586 Make_DT_Access_Action
(Typ
,
587 Action
=> Set_Prim_Op_Address
,
589 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
591 Make_Integer_Literal
(Loc
, DT_Position
(Prim
)), -- Position
593 Make_Attribute_Reference
(Loc
, -- Value
594 Prefix
=> New_Reference_To
(Prim
, Loc
),
595 Attribute_Name
=> Name_Address
)));
598 ---------------------------
599 -- Get_Remotely_Callable --
600 ---------------------------
602 function Get_Remotely_Callable
(Obj
: Node_Id
) return Node_Id
is
603 Loc
: constant Source_Ptr
:= Sloc
(Obj
);
606 return Make_DT_Access_Action
608 Action
=> Get_Remotely_Callable
,
610 Make_Selected_Component
(Loc
,
612 Selector_Name
=> Make_Identifier
(Loc
, Name_uTag
))));
613 end Get_Remotely_Callable
;
619 function Make_DT
(Typ
: Entity_Id
) return List_Id
is
620 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
622 Result
: constant List_Id
:= New_List
;
623 Elab_Code
: constant List_Id
:= New_List
;
625 Tname
: constant Name_Id
:= Chars
(Typ
);
626 Name_DT
: constant Name_Id
:= New_External_Name
(Tname
, 'T');
627 Name_DT_Ptr
: constant Name_Id
:= New_External_Name
(Tname
, 'P');
628 Name_TSD
: constant Name_Id
:= New_External_Name
(Tname
, 'B');
629 Name_Exname
: constant Name_Id
:= New_External_Name
(Tname
, 'E');
630 Name_No_Reg
: constant Name_Id
:= New_External_Name
(Tname
, 'F');
632 DT
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_DT
);
633 DT_Ptr
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_DT_Ptr
);
634 TSD
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_TSD
);
635 Exname
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_Exname
);
636 No_Reg
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_No_Reg
);
639 Generalized_Tag
: Entity_Id
;
640 Size_Expr_Node
: Node_Id
;
645 if not RTE_Available
(RE_Tag
) then
646 Error_Msg_CRT
("tagged types", Typ
);
650 if Is_CPP_Class
(Root_Type
(Typ
)) then
651 Generalized_Tag
:= RTE
(RE_Vtable_Ptr
);
653 Generalized_Tag
:= RTE
(RE_Tag
);
656 -- Dispatch table and related entities are allocated statically
658 Set_Ekind
(DT
, E_Variable
);
659 Set_Is_Statically_Allocated
(DT
);
661 Set_Ekind
(DT_Ptr
, E_Variable
);
662 Set_Is_Statically_Allocated
(DT_Ptr
);
664 Set_Ekind
(TSD
, E_Variable
);
665 Set_Is_Statically_Allocated
(TSD
);
667 Set_Ekind
(Exname
, E_Variable
);
668 Set_Is_Statically_Allocated
(Exname
);
670 Set_Ekind
(No_Reg
, E_Variable
);
671 Set_Is_Statically_Allocated
(No_Reg
);
673 -- Generate code to create the storage for the Dispatch_Table object:
675 -- DT : Storage_Array (1..DT_Prologue_Size+nb_prim*DT_Entry_Size);
676 -- for DT'Alignment use Address'Alignment
680 Left_Opnd
=> Make_DT_Access_Action
(Typ
, DT_Prologue_Size
, No_List
),
682 Make_Op_Multiply
(Loc
,
684 Make_DT_Access_Action
(Typ
, DT_Entry_Size
, No_List
),
686 Make_Integer_Literal
(Loc
,
687 DT_Entry_Count
(Tag_Component
(Typ
)))));
690 Make_Object_Declaration
(Loc
,
691 Defining_Identifier
=> DT
,
692 Aliased_Present
=> True,
694 Make_Subtype_Indication
(Loc
,
695 Subtype_Mark
=> New_Reference_To
(RTE
(RE_Storage_Array
), Loc
),
696 Constraint
=> Make_Index_Or_Discriminant_Constraint
(Loc
,
697 Constraints
=> New_List
(
699 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
700 High_Bound
=> Size_Expr_Node
))))));
703 Make_Attribute_Definition_Clause
(Loc
,
704 Name
=> New_Reference_To
(DT
, Loc
),
705 Chars
=> Name_Alignment
,
707 Make_Attribute_Reference
(Loc
,
708 Prefix
=> New_Reference_To
(RTE
(RE_Integer_Address
), Loc
),
709 Attribute_Name
=> Name_Alignment
)));
711 -- Generate code to create the pointer to the dispatch table
713 -- DT_Ptr : Tag := Tag!(DT'Address); Ada case
715 -- DT_Ptr : Vtable_Ptr := Vtable_Ptr!(DT'Address); CPP case
717 -- According to the C++ ABI, the base of the vtable is located
718 -- after the following prologue: Offset_To_Top, Typeinfo_Ptr.
719 -- Hence, move the pointer to the base of the vtable down, after
723 Make_Object_Declaration
(Loc
,
724 Defining_Identifier
=> DT_Ptr
,
725 Constant_Present
=> True,
726 Object_Definition
=> New_Reference_To
(Generalized_Tag
, Loc
),
728 Unchecked_Convert_To
(Generalized_Tag
,
731 Unchecked_Convert_To
(RTE
(RE_Storage_Offset
),
732 Make_Attribute_Reference
(Loc
,
733 Prefix
=> New_Reference_To
(DT
, Loc
),
734 Attribute_Name
=> Name_Address
)),
736 Make_DT_Access_Action
(Typ
,
737 DT_Prologue_Size
, No_List
)))));
739 -- Generate code to define the boolean that controls registration, in
740 -- order to avoid multiple registrations for tagged types defined in
741 -- multiple-called scopes
744 Make_Object_Declaration
(Loc
,
745 Defining_Identifier
=> No_Reg
,
746 Object_Definition
=> New_Reference_To
(Standard_Boolean
, Loc
),
747 Expression
=> New_Reference_To
(Standard_True
, Loc
)));
749 -- Set Access_Disp_Table field to be the dispatch table pointer
751 Set_Access_Disp_Table
(Typ
, DT_Ptr
);
753 -- Count ancestors to compute the inheritance depth. For private
754 -- extensions, always go to the full view in order to compute the real
755 -- inheritance depth.
758 Parent_Type
: Entity_Id
:= Typ
;
765 P
:= Etype
(Parent_Type
);
767 if Is_Private_Type
(P
) then
768 P
:= Full_View
(Base_Type
(P
));
771 exit when P
= Parent_Type
;
773 I_Depth
:= I_Depth
+ 1;
778 -- Generate code to create the storage for the type specific data object
780 -- TSD: Storage_Array (1..TSD_Prologue_Size+(1+Idepth)*TSD_Entry_Size);
781 -- for TSD'Alignment use Address'Alignment
786 Make_DT_Access_Action
(Typ
, TSD_Prologue_Size
, No_List
),
788 Make_Op_Multiply
(Loc
,
790 Make_DT_Access_Action
(Typ
, TSD_Entry_Size
, No_List
),
793 Left_Opnd
=> Make_Integer_Literal
(Loc
, 1),
795 Make_Integer_Literal
(Loc
, I_Depth
))));
798 Make_Object_Declaration
(Loc
,
799 Defining_Identifier
=> TSD
,
800 Aliased_Present
=> True,
802 Make_Subtype_Indication
(Loc
,
803 Subtype_Mark
=> New_Reference_To
(RTE
(RE_Storage_Array
), Loc
),
804 Constraint
=> Make_Index_Or_Discriminant_Constraint
(Loc
,
805 Constraints
=> New_List
(
807 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
808 High_Bound
=> Size_Expr_Node
))))));
811 Make_Attribute_Definition_Clause
(Loc
,
812 Name
=> New_Reference_To
(TSD
, Loc
),
813 Chars
=> Name_Alignment
,
815 Make_Attribute_Reference
(Loc
,
816 Prefix
=> New_Reference_To
(RTE
(RE_Integer_Address
), Loc
),
817 Attribute_Name
=> Name_Alignment
)));
819 -- Generate code to put the Address of the TSD in the dispatch table
820 -- Set_TSD (DT_Ptr, TSD);
822 Append_To
(Elab_Code
,
823 Make_DT_Access_Action
(Typ
,
826 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
827 Make_Attribute_Reference
(Loc
, -- Value
828 Prefix
=> New_Reference_To
(TSD
, Loc
),
829 Attribute_Name
=> Name_Address
))));
832 or else Is_CPP_Class
(Etype
(Typ
))
835 Unchecked_Convert_To
(Generalized_Tag
,
836 Make_Integer_Literal
(Loc
, 0));
839 Unchecked_Convert_To
(RTE
(RE_Address
),
840 Make_Integer_Literal
(Loc
, 0));
843 Old_Tag
:= New_Reference_To
(Access_Disp_Table
(Etype
(Typ
)), Loc
);
845 Make_DT_Access_Action
(Typ
,
848 New_Reference_To
(Access_Disp_Table
(Etype
(Typ
)), Loc
)));
851 -- Generate: Inherit_DT (parent'tag, DT_Ptr, nb_prim of parent);
853 Append_To
(Elab_Code
,
854 Make_DT_Access_Action
(Typ
,
855 Action
=> Inherit_DT
,
858 Node2
=> New_Reference_To
(DT_Ptr
, Loc
),
859 Node3
=> Make_Integer_Literal
(Loc
,
860 DT_Entry_Count
(Tag_Component
(Etype
(Typ
)))))));
862 -- Generate: Inherit_TSD (Get_TSD (parent), DT_Ptr);
864 Append_To
(Elab_Code
,
865 Make_DT_Access_Action
(Typ
,
866 Action
=> Inherit_TSD
,
869 Node2
=> New_Reference_To
(DT_Ptr
, Loc
))));
871 -- Generate: Exname : constant String := full_qualified_name (typ);
872 -- The type itself may be an anonymous parent type, so use the first
873 -- subtype to have a user-recognizable name.
876 Make_Object_Declaration
(Loc
,
877 Defining_Identifier
=> Exname
,
878 Constant_Present
=> True,
879 Object_Definition
=> New_Reference_To
(Standard_String
, Loc
),
881 Make_String_Literal
(Loc
,
882 Full_Qualified_Name
(First_Subtype
(Typ
)))));
884 -- Generate: Set_Expanded_Name (DT_Ptr, exname'Address);
886 Append_To
(Elab_Code
,
887 Make_DT_Access_Action
(Typ
,
888 Action
=> Set_Expanded_Name
,
890 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
892 Make_Attribute_Reference
(Loc
,
893 Prefix
=> New_Reference_To
(Exname
, Loc
),
894 Attribute_Name
=> Name_Address
))));
896 -- for types with no controlled components
897 -- Generate: Set_RC_Offset (DT_Ptr, 0);
898 -- for simple types with controlled components
899 -- Generate: Set_RC_Offset (DT_Ptr, type._record_controller'position);
900 -- for complex types with controlled components where the position
901 -- of the record controller is not statically computable, if there are
902 -- controlled components at this level
903 -- Generate: Set_RC_Offset (DT_Ptr, -1);
904 -- to indicate that the _controller field is right after the _parent or
905 -- if there are no controlled components at this level,
906 -- Generate: Set_RC_Offset (DT_Ptr, -2);
907 -- to indicate that we need to get the position from the parent.
913 if not Has_Controlled_Component
(Typ
) then
914 Position
:= Make_Integer_Literal
(Loc
, 0);
916 elsif Etype
(Typ
) /= Typ
and then Has_Discriminants
(Etype
(Typ
)) then
917 if Has_New_Controlled_Component
(Typ
) then
918 Position
:= Make_Integer_Literal
(Loc
, -1);
920 Position
:= Make_Integer_Literal
(Loc
, -2);
924 Make_Attribute_Reference
(Loc
,
926 Make_Selected_Component
(Loc
,
927 Prefix
=> New_Reference_To
(Typ
, Loc
),
929 New_Reference_To
(Controller_Component
(Typ
), Loc
)),
930 Attribute_Name
=> Name_Position
);
932 -- This is not proper Ada code to use the attribute 'Position
933 -- on something else than an object but this is supported by
934 -- the back end (see comment on the Bit_Component attribute in
935 -- sem_attr). So we avoid semantic checking here.
937 Set_Analyzed
(Position
);
938 Set_Etype
(Prefix
(Position
), RTE
(RE_Record_Controller
));
939 Set_Etype
(Prefix
(Prefix
(Position
)), Typ
);
940 Set_Etype
(Selector_Name
(Prefix
(Position
)),
941 RTE
(RE_Record_Controller
));
942 Set_Etype
(Position
, RTE
(RE_Storage_Offset
));
945 Append_To
(Elab_Code
,
946 Make_DT_Access_Action
(Typ
,
947 Action
=> Set_RC_Offset
,
949 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
950 Node2
=> Position
)));
953 -- Generate: Set_Remotely_Callable (DT_Ptr, Status);
954 -- where Status is described in E.4 (18)
963 or else Is_Shared_Passive
(Typ
)
965 ((Is_Remote_Types
(Typ
)
966 or else Is_Remote_Call_Interface
(Typ
))
967 and then Original_View_In_Visible_Part
(Typ
))
968 or else not Comes_From_Source
(Typ
));
970 Append_To
(Elab_Code
,
971 Make_DT_Access_Action
(Typ
,
972 Action
=> Set_Remotely_Callable
,
974 New_Occurrence_Of
(DT_Ptr
, Loc
),
975 New_Occurrence_Of
(Status
, Loc
))));
978 -- Generate: Set_External_Tag (DT_Ptr, exname'Address);
979 -- Should be the external name not the qualified name???
981 if not Has_External_Tag_Rep_Clause
(Typ
) then
982 Append_To
(Elab_Code
,
983 Make_DT_Access_Action
(Typ
,
984 Action
=> Set_External_Tag
,
986 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
988 Make_Attribute_Reference
(Loc
,
989 Prefix
=> New_Reference_To
(Exname
, Loc
),
990 Attribute_Name
=> Name_Address
))));
992 -- Generate code to register the Tag in the External_Tag hash
993 -- table for the pure Ada type only.
995 -- Register_Tag (Dt_Ptr);
997 -- Skip this if routine not available, or in No_Run_Time mode
999 if RTE_Available
(RE_Register_Tag
)
1000 and then Is_RTE
(Generalized_Tag
, RE_Tag
)
1001 and then not No_Run_Time_Mode
1003 Append_To
(Elab_Code
,
1004 Make_Procedure_Call_Statement
(Loc
,
1005 Name
=> New_Reference_To
(RTE
(RE_Register_Tag
), Loc
),
1006 Parameter_Associations
=>
1007 New_List
(New_Reference_To
(DT_Ptr
, Loc
))));
1017 Append_To
(Elab_Code
,
1018 Make_Assignment_Statement
(Loc
,
1019 Name
=> New_Reference_To
(No_Reg
, Loc
),
1020 Expression
=> New_Reference_To
(Standard_False
, Loc
)));
1023 Make_Implicit_If_Statement
(Typ
,
1024 Condition
=> New_Reference_To
(No_Reg
, Loc
),
1025 Then_Statements
=> Elab_Code
));
1030 ---------------------------
1031 -- Make_DT_Access_Action --
1032 ---------------------------
1034 function Make_DT_Access_Action
1036 Action
: DT_Access_Action
;
1040 Action_Name
: Entity_Id
;
1044 if Is_CPP_Class
(Root_Type
(Typ
)) then
1045 Action_Name
:= RTE
(CPP_Actions
(Action
));
1047 Action_Name
:= RTE
(Ada_Actions
(Action
));
1052 -- This is a constant
1054 return New_Reference_To
(Action_Name
, Sloc
(Typ
));
1057 pragma Assert
(List_Length
(Args
) = Action_Nb_Arg
(Action
));
1059 Loc
:= Sloc
(First
(Args
));
1061 if Action_Is_Proc
(Action
) then
1063 Make_Procedure_Call_Statement
(Loc
,
1064 Name
=> New_Reference_To
(Action_Name
, Loc
),
1065 Parameter_Associations
=> Args
);
1069 Make_Function_Call
(Loc
,
1070 Name
=> New_Reference_To
(Action_Name
, Loc
),
1071 Parameter_Associations
=> Args
);
1073 end Make_DT_Access_Action
;
1075 -----------------------------------
1076 -- Original_View_In_Visible_Part --
1077 -----------------------------------
1079 function Original_View_In_Visible_Part
(Typ
: Entity_Id
) return Boolean is
1080 Scop
: constant Entity_Id
:= Scope
(Typ
);
1083 -- The scope must be a package
1085 if Ekind
(Scop
) /= E_Package
1086 and then Ekind
(Scop
) /= E_Generic_Package
1091 -- A type with a private declaration has a private view declared in
1092 -- the visible part.
1094 if Has_Private_Declaration
(Typ
) then
1098 return List_Containing
(Parent
(Typ
)) =
1099 Visible_Declarations
(Specification
(Unit_Declaration_Node
(Scop
)));
1100 end Original_View_In_Visible_Part
;
1102 -------------------------
1103 -- Set_All_DT_Position --
1104 -------------------------
1106 procedure Set_All_DT_Position
(Typ
: Entity_Id
) is
1107 Parent_Typ
: constant Entity_Id
:= Etype
(Typ
);
1108 Root_Typ
: constant Entity_Id
:= Root_Type
(Typ
);
1109 First_Prim
: constant Elmt_Id
:= First_Elmt
(Primitive_Operations
(Typ
));
1110 The_Tag
: constant Entity_Id
:= Tag_Component
(Typ
);
1111 Adjusted
: Boolean := False;
1112 Finalized
: Boolean := False;
1116 Prim_Elmt
: Elmt_Id
;
1120 -- Get Entry_Count of the parent
1122 if Parent_Typ
/= Typ
1123 and then DT_Entry_Count
(Tag_Component
(Parent_Typ
)) /= No_Uint
1125 Parent_EC
:= UI_To_Int
(DT_Entry_Count
(Tag_Component
(Parent_Typ
)));
1130 -- C++ Case, check that pragma CPP_Class, CPP_Virtual and CPP_Vtable
1131 -- give a coherent set of information
1133 if Is_CPP_Class
(Root_Typ
) then
1135 -- Compute the number of primitive operations in the main Vtable
1136 -- Set their position:
1137 -- - where it was set if overriden or inherited
1138 -- - after the end of the parent vtable otherwise
1140 Prim_Elmt
:= First_Prim
;
1142 while Present
(Prim_Elmt
) loop
1143 Prim
:= Node
(Prim_Elmt
);
1145 if not Is_CPP_Class
(Typ
) then
1146 Set_DTC_Entity
(Prim
, The_Tag
);
1148 elsif Present
(Alias
(Prim
)) then
1149 Set_DTC_Entity
(Prim
, DTC_Entity
(Alias
(Prim
)));
1150 Set_DT_Position
(Prim
, DT_Position
(Alias
(Prim
)));
1152 elsif No
(DTC_Entity
(Prim
)) and then Is_CPP_Class
(Typ
) then
1153 Error_Msg_NE
("is a primitive operation of&," &
1154 " pragma Cpp_Virtual required", Prim
, Typ
);
1157 if DTC_Entity
(Prim
) = The_Tag
then
1159 -- Get the slot from the parent subprogram if any
1162 H
: Entity_Id
:= Homonym
(Prim
);
1165 while Present
(H
) loop
1166 if Present
(DTC_Entity
(H
))
1167 and then Root_Type
(Scope
(DTC_Entity
(H
))) = Root_Typ
1169 Set_DT_Position
(Prim
, DT_Position
(H
));
1177 -- Otherwise take the canonical slot after the end of the
1180 if DT_Position
(Prim
) = No_Uint
then
1181 Nb_Prim
:= Nb_Prim
+ 1;
1182 Set_DT_Position
(Prim
, UI_From_Int
(Parent_EC
+ Nb_Prim
));
1184 elsif UI_To_Int
(DT_Position
(Prim
)) > Parent_EC
then
1185 Nb_Prim
:= Nb_Prim
+ 1;
1189 Next_Elmt
(Prim_Elmt
);
1192 -- Check that the declared size of the Vtable is bigger or equal
1193 -- than the number of primitive operations (if bigger it means that
1194 -- some of the c++ virtual functions were not imported, that is
1197 if DT_Entry_Count
(The_Tag
) = No_Uint
1198 or else not Is_CPP_Class
(Typ
)
1200 Set_DT_Entry_Count
(The_Tag
, UI_From_Int
(Parent_EC
+ Nb_Prim
));
1202 elsif UI_To_Int
(DT_Entry_Count
(The_Tag
)) < Parent_EC
+ Nb_Prim
then
1203 Error_Msg_N
("not enough room in the Vtable for all virtual"
1204 & " functions", The_Tag
);
1207 -- Check that Positions are not duplicate nor outside the range of
1211 Size
: constant Int
:= UI_To_Int
(DT_Entry_Count
(The_Tag
));
1213 Prim_Pos_Table
: array (1 .. Size
) of Entity_Id
:=
1217 Prim_Elmt
:= First_Prim
;
1218 while Present
(Prim_Elmt
) loop
1219 Prim
:= Node
(Prim_Elmt
);
1221 if DTC_Entity
(Prim
) = The_Tag
then
1222 Pos
:= UI_To_Int
(DT_Position
(Prim
));
1224 if Pos
not in Prim_Pos_Table
'Range then
1226 ("position not in range of virtual table", Prim
);
1228 elsif Present
(Prim_Pos_Table
(Pos
)) then
1229 Error_Msg_NE
("cannot be at the same position in the"
1230 & " vtable than&", Prim
, Prim_Pos_Table
(Pos
));
1233 Prim_Pos_Table
(Pos
) := Prim
;
1237 Next_Elmt
(Prim_Elmt
);
1241 -- For regular Ada tagged types, just set the DT_Position for
1242 -- each primitive operation. Perform some sanity checks to avoid
1243 -- to build completely inconsistant dispatch tables.
1245 -- Note that the _Size primitive is always set at position 1 in order
1246 -- to comply with the needs of Ada.Tags.Parent_Size (see documentation
1251 Prim_Elmt
:= First_Prim
;
1252 while Present
(Prim_Elmt
) loop
1253 Nb_Prim
:= Nb_Prim
+ 1;
1254 Prim
:= Node
(Prim_Elmt
);
1255 Set_DTC_Entity
(Prim
, The_Tag
);
1257 if Chars
(Prim
) = Name_uSize
then
1258 Set_DT_Position
(Prim
, Uint_1
);
1259 Nb_Prim
:= Nb_Prim
- 1;
1261 Set_DT_Position
(Prim
, UI_From_Int
(Nb_Prim
));
1264 if Chars
(Prim
) = Name_Finalize
1266 (Is_Predefined_File_Name
(Unit_File_Name
(Current_Sem_Unit
))
1267 or else not Is_Predefined_File_Name
1268 (Unit_File_Name
(Get_Source_Unit
(Prim
))))
1273 if Chars
(Prim
) = Name_Adjust
then
1277 -- An abstract operation cannot be declared in the private part
1278 -- for a visible abstract type, because it could never be over-
1279 -- ridden. For explicit declarations this is checked at the point
1280 -- of declaration, but for inherited operations it must be done
1281 -- when building the dispatch table. Input is excluded because
1283 if Is_Abstract
(Typ
)
1284 and then Is_Abstract
(Prim
)
1285 and then Present
(Alias
(Prim
))
1286 and then Is_Derived_Type
(Typ
)
1287 and then In_Private_Part
(Current_Scope
)
1288 and then List_Containing
(Parent
(Prim
))
1289 = Private_Declarations
1290 (Specification
(Unit_Declaration_Node
(Current_Scope
)))
1291 and then Original_View_In_Visible_Part
(Typ
)
1293 -- We exclude Input and Output stream operations because
1294 -- Limited_Controlled inherits useless Input and Output
1295 -- stream operations from Root_Controlled, which can
1296 -- never be overridden.
1298 if not Is_TSS
(Prim
, TSS_Stream_Input
)
1300 not Is_TSS
(Prim
, TSS_Stream_Output
)
1303 ("abstract inherited private operation&" &
1304 " must be overridden ('R'M 3.9.3(10))",
1305 Parent
(Typ
), Prim
);
1308 Next_Elmt
(Prim_Elmt
);
1311 if Is_Controlled
(Typ
) then
1312 if not Finalized
then
1314 ("controlled type has no explicit Finalize method?", Typ
);
1316 elsif not Adjusted
then
1318 ("controlled type has no explicit Adjust method?", Typ
);
1322 Set_DT_Entry_Count
(The_Tag
, UI_From_Int
(Nb_Prim
));
1324 -- The derived type must have at least as many components as its
1325 -- parent (for root types, the Etype points back to itself
1326 -- and the test should not fail)
1329 DT_Entry_Count
(The_Tag
) >=
1330 DT_Entry_Count
(Tag_Component
(Parent_Typ
)));
1332 end Set_All_DT_Position
;
1334 -----------------------------
1335 -- Set_Default_Constructor --
1336 -----------------------------
1338 procedure Set_Default_Constructor
(Typ
: Entity_Id
) is
1345 -- Look for the default constructor entity. For now only the
1346 -- default constructor has the flag Is_Constructor.
1348 E
:= Next_Entity
(Typ
);
1350 and then (Ekind
(E
) /= E_Function
or else not Is_Constructor
(E
))
1355 -- Create the init procedure
1359 Init
:= Make_Defining_Identifier
(Loc
, Make_Init_Proc_Name
(Typ
));
1360 Param
:= Make_Defining_Identifier
(Loc
, Name_X
);
1363 Make_Subprogram_Declaration
(Loc
,
1364 Make_Procedure_Specification
(Loc
,
1365 Defining_Unit_Name
=> Init
,
1366 Parameter_Specifications
=> New_List
(
1367 Make_Parameter_Specification
(Loc
,
1368 Defining_Identifier
=> Param
,
1369 Parameter_Type
=> New_Reference_To
(Typ
, Loc
))))));
1371 Set_Init_Proc
(Typ
, Init
);
1372 Set_Is_Imported
(Init
);
1373 Set_Interface_Name
(Init
, Interface_Name
(E
));
1374 Set_Convention
(Init
, Convention_C
);
1375 Set_Is_Public
(Init
);
1376 Set_Has_Completion
(Init
);
1378 -- If there are no constructors, mark the type as abstract since we
1379 -- won't be able to declare objects of that type.
1382 Set_Is_Abstract
(Typ
);
1384 end Set_Default_Constructor
;