1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
11 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
24 -- GNAT was originally developed by the GNAT team at New York University. --
25 -- Extensive contributions were provided by Ada Core Technologies Inc. --
27 ------------------------------------------------------------------------------
29 with Atree
; use Atree
;
30 with Checks
; use Checks
;
31 with Einfo
; use Einfo
;
32 with Elists
; use Elists
;
33 with Errout
; use Errout
;
34 with Exp_Ch7
; use Exp_Ch7
;
35 with Exp_Tss
; use Exp_Tss
;
36 with Exp_Util
; use Exp_Util
;
37 with Fname
; use Fname
;
38 with Itypes
; use Itypes
;
40 with Nlists
; use Nlists
;
41 with Nmake
; use Nmake
;
43 with Rtsfind
; use Rtsfind
;
44 with Sem_Disp
; use Sem_Disp
;
45 with Sem_Res
; use Sem_Res
;
46 with Sem_Util
; use Sem_Util
;
47 with Sinfo
; use Sinfo
;
48 with Snames
; use Snames
;
49 with Stand
; use Stand
;
50 with Tbuild
; use Tbuild
;
51 with Uintp
; use Uintp
;
53 package body Exp_Disp
is
55 Ada_Actions
: constant array (DT_Access_Action
) of RE_Id
:=
56 (CW_Membership
=> RE_CW_Membership
,
57 DT_Entry_Size
=> RE_DT_Entry_Size
,
58 DT_Prologue_Size
=> RE_DT_Prologue_Size
,
59 Get_Expanded_Name
=> RE_Get_Expanded_Name
,
60 Get_External_Tag
=> RE_Get_External_Tag
,
61 Get_Prim_Op_Address
=> RE_Get_Prim_Op_Address
,
62 Get_RC_Offset
=> RE_Get_RC_Offset
,
63 Get_Remotely_Callable
=> RE_Get_Remotely_Callable
,
64 Get_TSD
=> RE_Get_TSD
,
65 Inherit_DT
=> RE_Inherit_DT
,
66 Inherit_TSD
=> RE_Inherit_TSD
,
67 Register_Tag
=> RE_Register_Tag
,
68 Set_Expanded_Name
=> RE_Set_Expanded_Name
,
69 Set_External_Tag
=> RE_Set_External_Tag
,
70 Set_Prim_Op_Address
=> RE_Set_Prim_Op_Address
,
71 Set_RC_Offset
=> RE_Set_RC_Offset
,
72 Set_Remotely_Callable
=> RE_Set_Remotely_Callable
,
73 Set_TSD
=> RE_Set_TSD
,
74 TSD_Entry_Size
=> RE_TSD_Entry_Size
,
75 TSD_Prologue_Size
=> RE_TSD_Prologue_Size
);
77 CPP_Actions
: constant array (DT_Access_Action
) of RE_Id
:=
78 (CW_Membership
=> RE_CPP_CW_Membership
,
79 DT_Entry_Size
=> RE_CPP_DT_Entry_Size
,
80 DT_Prologue_Size
=> RE_CPP_DT_Prologue_Size
,
81 Get_Expanded_Name
=> RE_CPP_Get_Expanded_Name
,
82 Get_External_Tag
=> RE_CPP_Get_External_Tag
,
83 Get_Prim_Op_Address
=> RE_CPP_Get_Prim_Op_Address
,
84 Get_RC_Offset
=> RE_CPP_Get_RC_Offset
,
85 Get_Remotely_Callable
=> RE_CPP_Get_Remotely_Callable
,
86 Get_TSD
=> RE_CPP_Get_TSD
,
87 Inherit_DT
=> RE_CPP_Inherit_DT
,
88 Inherit_TSD
=> RE_CPP_Inherit_TSD
,
89 Register_Tag
=> RE_CPP_Register_Tag
,
90 Set_Expanded_Name
=> RE_CPP_Set_Expanded_Name
,
91 Set_External_Tag
=> RE_CPP_Set_External_Tag
,
92 Set_Prim_Op_Address
=> RE_CPP_Set_Prim_Op_Address
,
93 Set_RC_Offset
=> RE_CPP_Set_RC_Offset
,
94 Set_Remotely_Callable
=> RE_CPP_Set_Remotely_Callable
,
95 Set_TSD
=> RE_CPP_Set_TSD
,
96 TSD_Entry_Size
=> RE_CPP_TSD_Entry_Size
,
97 TSD_Prologue_Size
=> RE_CPP_TSD_Prologue_Size
);
99 Action_Is_Proc
: constant array (DT_Access_Action
) of Boolean :=
100 (CW_Membership
=> False,
101 DT_Entry_Size
=> False,
102 DT_Prologue_Size
=> False,
103 Get_Expanded_Name
=> False,
104 Get_External_Tag
=> False,
105 Get_Prim_Op_Address
=> False,
106 Get_Remotely_Callable
=> False,
107 Get_RC_Offset
=> False,
111 Register_Tag
=> True,
112 Set_Expanded_Name
=> True,
113 Set_External_Tag
=> True,
114 Set_Prim_Op_Address
=> True,
115 Set_RC_Offset
=> True,
116 Set_Remotely_Callable
=> True,
118 TSD_Entry_Size
=> False,
119 TSD_Prologue_Size
=> False);
121 Action_Nb_Arg
: constant array (DT_Access_Action
) of Int
:=
124 DT_Prologue_Size
=> 0,
125 Get_Expanded_Name
=> 1,
126 Get_External_Tag
=> 1,
127 Get_Prim_Op_Address
=> 2,
129 Get_Remotely_Callable
=> 1,
134 Set_Expanded_Name
=> 2,
135 Set_External_Tag
=> 2,
136 Set_Prim_Op_Address
=> 3,
138 Set_Remotely_Callable
=> 2,
141 TSD_Prologue_Size
=> 0);
143 function Original_View_In_Visible_Part
(Typ
: Entity_Id
) return Boolean;
144 -- Check if the type has a private view or if the public view appears
145 -- in the visible part of a package spec.
147 --------------------------
148 -- Expand_Dispatch_Call --
149 --------------------------
151 procedure Expand_Dispatch_Call
(Call_Node
: Node_Id
) is
152 Loc
: constant Source_Ptr
:= Sloc
(Call_Node
);
153 Call_Typ
: constant Entity_Id
:= Etype
(Call_Node
);
155 Ctrl_Arg
: constant Node_Id
:= Controlling_Argument
(Call_Node
);
156 Param_List
: constant List_Id
:= Parameter_Associations
(Call_Node
);
157 Subp
: Entity_Id
:= Entity
(Name
(Call_Node
));
161 New_Call_Name
: Node_Id
;
162 New_Params
: List_Id
:= No_List
;
165 Subp_Ptr_Typ
: Entity_Id
;
166 Subp_Typ
: Entity_Id
;
168 Eq_Prim_Op
: Entity_Id
:= Empty
;
170 function New_Value
(From
: Node_Id
) return Node_Id
;
171 -- From is the original Expression. New_Value is equivalent to
172 -- Duplicate_Subexpr with an explicit dereference when From is an
175 function New_Value
(From
: Node_Id
) return Node_Id
is
176 Res
: constant Node_Id
:= Duplicate_Subexpr
(From
);
179 if Is_Access_Type
(Etype
(From
)) then
180 return Make_Explicit_Dereference
(Sloc
(From
), Res
);
186 -- Start of processing for Expand_Dispatch_Call
189 -- If this is an inherited operation that was overriden, the body
190 -- that is being called is its alias.
192 if Present
(Alias
(Subp
))
193 and then Is_Inherited_Operation
(Subp
)
194 and then No
(DTC_Entity
(Subp
))
196 Subp
:= Alias
(Subp
);
199 -- Expand_Dispatch is called directly from the semantics, so we need
200 -- a check to see whether expansion is active before proceeding
202 if not Expander_Active
then
206 -- Definition of the ClassWide Type and the Tagged type
208 if Is_Access_Type
(Etype
(Ctrl_Arg
)) then
209 CW_Typ
:= Designated_Type
(Etype
(Ctrl_Arg
));
211 CW_Typ
:= Etype
(Ctrl_Arg
);
214 Typ
:= Root_Type
(CW_Typ
);
216 if not Is_Limited_Type
(Typ
) then
217 Eq_Prim_Op
:= Find_Prim_Op
(Typ
, Name_Op_Eq
);
220 if Is_CPP_Class
(Root_Type
(Typ
)) then
222 -- Create a new parameter list with the displaced 'this'
224 New_Params
:= New_List
;
225 Param
:= First_Actual
(Call_Node
);
226 while Present
(Param
) loop
228 -- We assume that dispatching through the main dispatch table
229 -- (referenced by Tag_Component) doesn't require a displacement
230 -- so the expansion below is only done when dispatching on
231 -- another vtable pointer, in which case the first argument
232 -- is expanded into :
234 -- typ!(Displaced_This (Address!(Param)))
237 and then DTC_Entity
(Subp
) /= Tag_Component
(Typ
)
239 Append_To
(New_Params
,
241 Unchecked_Convert_To
(Etype
(Param
),
242 Make_Function_Call
(Loc
,
243 Name
=> New_Reference_To
(RTE
(RE_Displaced_This
), Loc
),
244 Parameter_Associations
=> New_List
(
248 Make_Unchecked_Type_Conversion
(Loc
,
250 New_Reference_To
(RTE
(RE_Address
), Loc
),
251 Expression
=> Relocate_Node
(Param
)),
255 Make_Selected_Component
(Loc
,
256 Prefix
=> Duplicate_Subexpr
(Ctrl_Arg
),
258 New_Reference_To
(DTC_Entity
(Subp
), Loc
)),
262 Make_Integer_Literal
(Loc
, DT_Position
(Subp
))))));
265 Append_To
(New_Params
, Relocate_Node
(Param
));
271 elsif Present
(Param_List
) then
273 -- Generate the Tag checks when appropriate
275 New_Params
:= New_List
;
277 Param
:= First_Actual
(Call_Node
);
278 while Present
(Param
) loop
280 -- No tag check with itself
282 if Param
= Ctrl_Arg
then
283 Append_To
(New_Params
, Duplicate_Subexpr
(Param
));
285 -- No tag check for parameter whose type is neither tagged nor
286 -- access to tagged (for access parameters)
288 elsif No
(Find_Controlling_Arg
(Param
)) then
289 Append_To
(New_Params
, Relocate_Node
(Param
));
291 -- No tag check for function dispatching on result it the
292 -- Tag given by the context is this one
294 elsif Find_Controlling_Arg
(Param
) = Ctrl_Arg
then
295 Append_To
(New_Params
, Relocate_Node
(Param
));
297 -- "=" is the only dispatching operation allowed to get
298 -- operands with incompatible tags (it just returns false).
299 -- We use Duplicate_subexpr instead of relocate_node because
300 -- the value will be duplicated to check the tags.
302 elsif Subp
= Eq_Prim_Op
then
303 Append_To
(New_Params
, Duplicate_Subexpr
(Param
));
305 -- No check in presence of suppress flags
307 elsif Tag_Checks_Suppressed
(Etype
(Param
))
308 or else (Is_Access_Type
(Etype
(Param
))
309 and then Tag_Checks_Suppressed
310 (Designated_Type
(Etype
(Param
))))
312 Append_To
(New_Params
, Relocate_Node
(Param
));
314 -- Optimization: no tag checks if the parameters are identical
316 elsif Is_Entity_Name
(Param
)
317 and then Is_Entity_Name
(Ctrl_Arg
)
318 and then Entity
(Param
) = Entity
(Ctrl_Arg
)
320 Append_To
(New_Params
, Relocate_Node
(Param
));
322 -- Now we need to generate the Tag check
325 -- Generate code for tag equality check
326 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
328 Insert_Action
(Ctrl_Arg
,
329 Make_Implicit_If_Statement
(Call_Node
,
333 Make_Selected_Component
(Loc
,
334 Prefix
=> New_Value
(Ctrl_Arg
),
336 New_Reference_To
(Tag_Component
(Typ
), Loc
)),
339 Make_Selected_Component
(Loc
,
341 Unchecked_Convert_To
(Typ
, New_Value
(Param
)),
343 New_Reference_To
(Tag_Component
(Typ
), Loc
))),
346 New_List
(New_Constraint_Error
(Loc
))));
348 Append_To
(New_Params
, Relocate_Node
(Param
));
355 -- Generate the appropriate subprogram pointer type
357 if Etype
(Subp
) = Typ
then
360 Res_Typ
:= Etype
(Subp
);
363 Subp_Typ
:= Create_Itype
(E_Subprogram_Type
, Call_Node
);
364 Subp_Ptr_Typ
:= Create_Itype
(E_Access_Subprogram_Type
, Call_Node
);
365 Set_Etype
(Subp_Typ
, Res_Typ
);
366 Init_Size_Align
(Subp_Ptr_Typ
);
367 Set_Returns_By_Ref
(Subp_Typ
, Returns_By_Ref
(Subp
));
369 -- Create a new list of parameters which is a copy of the old formal
370 -- list including the creation of a new set of matching entities.
373 Old_Formal
: Entity_Id
:= First_Formal
(Subp
);
374 New_Formal
: Entity_Id
;
378 if Present
(Old_Formal
) then
379 New_Formal
:= New_Copy
(Old_Formal
);
380 Set_First_Entity
(Subp_Typ
, New_Formal
);
381 Param
:= First_Actual
(Call_Node
);
384 Set_Scope
(New_Formal
, Subp_Typ
);
386 -- Change all the controlling argument types to be class-wide
387 -- to avoid a recursion in dispatching
389 if Is_Controlling_Actual
(Param
) then
390 Set_Etype
(New_Formal
, Etype
(Param
));
393 if Is_Itype
(Etype
(New_Formal
)) then
394 Extra
:= New_Copy
(Etype
(New_Formal
));
396 if Ekind
(Extra
) = E_Record_Subtype
397 or else Ekind
(Extra
) = E_Class_Wide_Subtype
399 Set_Cloned_Subtype
(Extra
, Etype
(New_Formal
));
402 Set_Etype
(New_Formal
, Extra
);
403 Set_Scope
(Etype
(New_Formal
), Subp_Typ
);
407 Next_Formal
(Old_Formal
);
408 exit when No
(Old_Formal
);
410 Set_Next_Entity
(New_Formal
, New_Copy
(Old_Formal
));
411 Next_Entity
(New_Formal
);
414 Set_Last_Entity
(Subp_Typ
, Extra
);
416 -- Copy extra formals
418 New_Formal
:= First_Entity
(Subp_Typ
);
419 while Present
(New_Formal
) loop
420 if Present
(Extra_Constrained
(New_Formal
)) then
421 Set_Extra_Formal
(Extra
,
422 New_Copy
(Extra_Constrained
(New_Formal
)));
423 Extra
:= Extra_Formal
(Extra
);
424 Set_Extra_Constrained
(New_Formal
, Extra
);
426 elsif Present
(Extra_Accessibility
(New_Formal
)) then
427 Set_Extra_Formal
(Extra
,
428 New_Copy
(Extra_Accessibility
(New_Formal
)));
429 Extra
:= Extra_Formal
(Extra
);
430 Set_Extra_Accessibility
(New_Formal
, Extra
);
433 Next_Formal
(New_Formal
);
438 Set_Etype
(Subp_Ptr_Typ
, Subp_Ptr_Typ
);
439 Set_Directly_Designated_Type
(Subp_Ptr_Typ
, Subp_Typ
);
442 -- Subp_Ptr_Typ!(Get_Prim_Op_Address (Ctrl._Tag, pos));
445 Unchecked_Convert_To
(Subp_Ptr_Typ
,
446 Make_DT_Access_Action
(Typ
,
447 Action
=> Get_Prim_Op_Address
,
452 Make_Selected_Component
(Loc
,
453 Prefix
=> Duplicate_Subexpr
(Ctrl_Arg
),
454 Selector_Name
=> New_Reference_To
(DTC_Entity
(Subp
), Loc
)),
458 Make_Integer_Literal
(Loc
, DT_Position
(Subp
)))));
460 if Nkind
(Call_Node
) = N_Function_Call
then
462 Make_Function_Call
(Loc
,
463 Name
=> New_Call_Name
,
464 Parameter_Associations
=> New_Params
);
466 -- if this is a dispatching "=", we must first compare the tags so
467 -- we generate: x.tag = y.tag and then x = y
469 if Subp
= Eq_Prim_Op
then
471 Param
:= First_Actual
(Call_Node
);
477 Make_Selected_Component
(Loc
,
478 Prefix
=> New_Value
(Param
),
480 New_Reference_To
(Tag_Component
(Typ
), Loc
)),
483 Make_Selected_Component
(Loc
,
485 Unchecked_Convert_To
(Typ
,
486 New_Value
(Next_Actual
(Param
))),
488 New_Reference_To
(Tag_Component
(Typ
), Loc
))),
490 Right_Opnd
=> New_Call
);
495 Make_Procedure_Call_Statement
(Loc
,
496 Name
=> New_Call_Name
,
497 Parameter_Associations
=> New_Params
);
500 Rewrite
(Call_Node
, New_Call
);
501 Analyze_And_Resolve
(Call_Node
, Call_Typ
);
502 end Expand_Dispatch_Call
;
508 function Fill_DT_Entry
513 Typ
: constant Entity_Id
:= Scope
(DTC_Entity
(Prim
));
514 DT_Ptr
: constant Entity_Id
:= Access_Disp_Table
(Typ
);
518 Make_DT_Access_Action
(Typ
,
519 Action
=> Set_Prim_Op_Address
,
521 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
523 Make_Integer_Literal
(Loc
, DT_Position
(Prim
)), -- Position
525 Make_Attribute_Reference
(Loc
, -- Value
526 Prefix
=> New_Reference_To
(Prim
, Loc
),
527 Attribute_Name
=> Name_Address
)));
530 ---------------------------
531 -- Get_Remotely_Callable --
532 ---------------------------
534 function Get_Remotely_Callable
(Obj
: Node_Id
) return Node_Id
is
535 Loc
: constant Source_Ptr
:= Sloc
(Obj
);
538 return Make_DT_Access_Action
540 Action
=> Get_Remotely_Callable
,
542 Make_Selected_Component
(Loc
,
544 Selector_Name
=> Make_Identifier
(Loc
, Name_uTag
))));
545 end Get_Remotely_Callable
;
551 function Make_DT
(Typ
: Entity_Id
) return List_Id
is
552 Loc
: constant Source_Ptr
:= Sloc
(Typ
);
554 Result
: constant List_Id
:= New_List
;
555 Elab_Code
: constant List_Id
:= New_List
;
557 Tname
: constant Name_Id
:= Chars
(Typ
);
558 Name_DT
: constant Name_Id
:= New_External_Name
(Tname
, 'T');
559 Name_DT_Ptr
: constant Name_Id
:= New_External_Name
(Tname
, 'P');
560 Name_TSD
: constant Name_Id
:= New_External_Name
(Tname
, 'B');
561 Name_Exname
: constant Name_Id
:= New_External_Name
(Tname
, 'E');
562 Name_No_Reg
: constant Name_Id
:= New_External_Name
(Tname
, 'F');
564 DT
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_DT
);
565 DT_Ptr
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_DT_Ptr
);
566 TSD
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_TSD
);
567 Exname
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_Exname
);
568 No_Reg
: constant Node_Id
:= Make_Defining_Identifier
(Loc
, Name_No_Reg
);
571 Generalized_Tag
: Entity_Id
;
572 Size_Expr_Node
: Node_Id
;
577 if Is_CPP_Class
(Root_Type
(Typ
)) then
578 Generalized_Tag
:= RTE
(RE_Vtable_Ptr
);
580 Generalized_Tag
:= RTE
(RE_Tag
);
583 -- Dispatch table and related entities are allocated statically
585 Set_Ekind
(DT
, E_Variable
);
586 Set_Is_Statically_Allocated
(DT
);
588 Set_Ekind
(DT_Ptr
, E_Variable
);
589 Set_Is_Statically_Allocated
(DT_Ptr
);
591 Set_Ekind
(TSD
, E_Variable
);
592 Set_Is_Statically_Allocated
(TSD
);
594 Set_Ekind
(Exname
, E_Variable
);
595 Set_Is_Statically_Allocated
(Exname
);
597 Set_Ekind
(No_Reg
, E_Variable
);
598 Set_Is_Statically_Allocated
(No_Reg
);
600 -- Generate code to create the storage for the Dispatch_Table object:
602 -- DT : Storage_Array (1..DT_Prologue_Size+nb_prim*DT_Entry_Size);
603 -- for DT'Alignment use Address'Alignment
607 Left_Opnd
=> Make_DT_Access_Action
(Typ
, DT_Prologue_Size
, No_List
),
609 Make_Op_Multiply
(Loc
,
611 Make_DT_Access_Action
(Typ
, DT_Entry_Size
, No_List
),
613 Make_Integer_Literal
(Loc
,
614 DT_Entry_Count
(Tag_Component
(Typ
)))));
617 Make_Object_Declaration
(Loc
,
618 Defining_Identifier
=> DT
,
619 Aliased_Present
=> True,
621 Make_Subtype_Indication
(Loc
,
622 Subtype_Mark
=> New_Reference_To
(RTE
(RE_Storage_Array
), Loc
),
623 Constraint
=> Make_Index_Or_Discriminant_Constraint
(Loc
,
624 Constraints
=> New_List
(
626 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
627 High_Bound
=> Size_Expr_Node
))))));
630 Make_Attribute_Definition_Clause
(Loc
,
631 Name
=> New_Reference_To
(DT
, Loc
),
632 Chars
=> Name_Alignment
,
634 Make_Attribute_Reference
(Loc
,
635 Prefix
=> New_Reference_To
(RTE
(RE_Integer_Address
), Loc
),
636 Attribute_Name
=> Name_Alignment
)));
638 -- Generate code to create the pointer to the dispatch table
640 -- DT_Ptr : Tag := Tag!(DT'Address); Ada case
642 -- DT_Ptr : Vtable_Ptr := Vtable_Ptr!(DT'Address); CPP case
645 Make_Object_Declaration
(Loc
,
646 Defining_Identifier
=> DT_Ptr
,
647 Constant_Present
=> True,
648 Object_Definition
=> New_Reference_To
(Generalized_Tag
, Loc
),
650 Unchecked_Convert_To
(Generalized_Tag
,
651 Make_Attribute_Reference
(Loc
,
652 Prefix
=> New_Reference_To
(DT
, Loc
),
653 Attribute_Name
=> Name_Address
))));
655 -- Generate code to define the boolean that controls registration, in
656 -- order to avoid multiple registrations for tagged types defined in
657 -- multiple-called scopes
660 Make_Object_Declaration
(Loc
,
661 Defining_Identifier
=> No_Reg
,
662 Object_Definition
=> New_Reference_To
(Standard_Boolean
, Loc
),
663 Expression
=> New_Reference_To
(Standard_True
, Loc
)));
665 -- Set Access_Disp_Table field to be the dispatch table pointer
667 Set_Access_Disp_Table
(Typ
, DT_Ptr
);
669 -- Count ancestors to compute the inheritance depth. For private
670 -- extensions, always go to the full view in order to compute the real
671 -- inheritance depth.
674 Parent_Type
: Entity_Id
:= Typ
;
681 P
:= Etype
(Parent_Type
);
683 if Is_Private_Type
(P
) then
684 P
:= Full_View
(Base_Type
(P
));
687 exit when P
= Parent_Type
;
689 I_Depth
:= I_Depth
+ 1;
694 -- Generate code to create the storage for the type specific data object
696 -- TSD: Storage_Array (1..TSD_Prologue_Size+(1+Idepth)*TSD_Entry_Size);
697 -- for TSD'Alignment use Address'Alignment
702 Make_DT_Access_Action
(Typ
, TSD_Prologue_Size
, No_List
),
704 Make_Op_Multiply
(Loc
,
706 Make_DT_Access_Action
(Typ
, TSD_Entry_Size
, No_List
),
709 Left_Opnd
=> Make_Integer_Literal
(Loc
, 1),
711 Make_Integer_Literal
(Loc
, I_Depth
))));
714 Make_Object_Declaration
(Loc
,
715 Defining_Identifier
=> TSD
,
716 Aliased_Present
=> True,
718 Make_Subtype_Indication
(Loc
,
719 Subtype_Mark
=> New_Reference_To
(RTE
(RE_Storage_Array
), Loc
),
720 Constraint
=> Make_Index_Or_Discriminant_Constraint
(Loc
,
721 Constraints
=> New_List
(
723 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
724 High_Bound
=> Size_Expr_Node
))))));
727 Make_Attribute_Definition_Clause
(Loc
,
728 Name
=> New_Reference_To
(TSD
, Loc
),
729 Chars
=> Name_Alignment
,
731 Make_Attribute_Reference
(Loc
,
732 Prefix
=> New_Reference_To
(RTE
(RE_Integer_Address
), Loc
),
733 Attribute_Name
=> Name_Alignment
)));
735 -- Generate code to put the Address of the TSD in the dispatch table
736 -- Set_TSD (DT_Ptr, TSD);
738 Append_To
(Elab_Code
,
739 Make_DT_Access_Action
(Typ
,
742 New_Reference_To
(DT_Ptr
, Loc
), -- DTptr
743 Make_Attribute_Reference
(Loc
, -- Value
744 Prefix
=> New_Reference_To
(TSD
, Loc
),
745 Attribute_Name
=> Name_Address
))));
748 or else Is_CPP_Class
(Etype
(Typ
))
751 Unchecked_Convert_To
(Generalized_Tag
,
752 Make_Integer_Literal
(Loc
, 0));
755 Unchecked_Convert_To
(RTE
(RE_Address
),
756 Make_Integer_Literal
(Loc
, 0));
759 Old_Tag
:= New_Reference_To
(Access_Disp_Table
(Etype
(Typ
)), Loc
);
761 Make_DT_Access_Action
(Typ
,
764 New_Reference_To
(Access_Disp_Table
(Etype
(Typ
)), Loc
)));
767 -- Generate: Inherit_DT (parent'tag, DT_Ptr, nb_prim of parent);
769 Append_To
(Elab_Code
,
770 Make_DT_Access_Action
(Typ
,
771 Action
=> Inherit_DT
,
774 Node2
=> New_Reference_To
(DT_Ptr
, Loc
),
775 Node3
=> Make_Integer_Literal
(Loc
,
776 DT_Entry_Count
(Tag_Component
(Etype
(Typ
)))))));
778 -- Generate: Inherit_TSD (Get_TSD (parent), DT_Ptr);
780 Append_To
(Elab_Code
,
781 Make_DT_Access_Action
(Typ
,
782 Action
=> Inherit_TSD
,
785 Node2
=> New_Reference_To
(DT_Ptr
, Loc
))));
787 -- Generate: Exname : constant String := full_qualified_name (typ);
788 -- The type itself may be an anonymous parent type, so use the first
789 -- subtype to have a user-recognizable name.
792 Make_Object_Declaration
(Loc
,
793 Defining_Identifier
=> Exname
,
794 Constant_Present
=> True,
795 Object_Definition
=> New_Reference_To
(Standard_String
, Loc
),
797 Make_String_Literal
(Loc
,
798 Full_Qualified_Name
(First_Subtype
(Typ
)))));
800 -- Generate: Set_Expanded_Name (DT_Ptr, exname'Address);
802 Append_To
(Elab_Code
,
803 Make_DT_Access_Action
(Typ
,
804 Action
=> Set_Expanded_Name
,
806 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
808 Make_Attribute_Reference
(Loc
,
809 Prefix
=> New_Reference_To
(Exname
, Loc
),
810 Attribute_Name
=> Name_Address
))));
812 -- for types with no controlled components
813 -- Generate: Set_RC_Offset (DT_Ptr, 0);
814 -- for simple types with controlled components
815 -- Generate: Set_RC_Offset (DT_Ptr, type._record_controller'position);
816 -- for complex types with controlled components where the position
817 -- of the record controller
818 -- Generate: Set_RC_Offset (DT_Ptr, -1);
824 if not Has_Controlled_Component
(Typ
) then
825 Position
:= Make_Integer_Literal
(Loc
, 0);
827 elsif Etype
(Typ
) /= Typ
and then Has_Discriminants
(Etype
(Typ
)) then
828 Position
:= Make_Integer_Literal
(Loc
, -1);
832 Make_Attribute_Reference
(Loc
,
834 Make_Selected_Component
(Loc
,
835 Prefix
=> New_Reference_To
(Typ
, Loc
),
837 New_Reference_To
(Controller_Component
(Typ
), Loc
)),
838 Attribute_Name
=> Name_Position
);
840 -- This is not proper Ada code to use the attribute component
841 -- on something else than an object but this is supported by
842 -- the back end (see comment on the Bit_Component attribute in
843 -- sem_attr). So we avoid semantic checking here.
845 Set_Analyzed
(Position
);
846 Set_Etype
(Prefix
(Position
), RTE
(RE_Record_Controller
));
847 Set_Etype
(Prefix
(Prefix
(Position
)), Typ
);
848 Set_Etype
(Selector_Name
(Prefix
(Position
)),
849 RTE
(RE_Record_Controller
));
850 Set_Etype
(Position
, RTE
(RE_Storage_Offset
));
854 Append_To
(Elab_Code
,
855 Make_DT_Access_Action
(Typ
,
856 Action
=> Set_RC_Offset
,
858 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
859 Node2
=> Position
)));
862 -- Generate: Set_Remotely_Callable (DT_Ptr, status);
863 -- where status is described in E.4 (18)
870 or else Is_Shared_Passive
(Typ
)
872 ((Is_Remote_Types
(Typ
) or else Is_Remote_Call_Interface
(Typ
))
873 and then Original_View_In_Visible_Part
(Typ
))
874 or else not Comes_From_Source
(Typ
)
876 Status
:= Standard_True
;
878 Status
:= Standard_False
;
881 Append_To
(Elab_Code
,
882 Make_DT_Access_Action
(Typ
,
883 Action
=> Set_Remotely_Callable
,
885 New_Occurrence_Of
(DT_Ptr
, Loc
),
886 New_Occurrence_Of
(Status
, Loc
))));
889 -- Generate: Set_External_Tag (DT_Ptr, exname'Address);
890 -- Should be the external name not the qualified name???
892 if not Has_External_Tag_Rep_Clause
(Typ
) then
893 Append_To
(Elab_Code
,
894 Make_DT_Access_Action
(Typ
,
895 Action
=> Set_External_Tag
,
897 Node1
=> New_Reference_To
(DT_Ptr
, Loc
),
899 Make_Attribute_Reference
(Loc
,
900 Prefix
=> New_Reference_To
(Exname
, Loc
),
901 Attribute_Name
=> Name_Address
))));
903 -- Generate code to register the Tag in the External_Tag hash
904 -- table for the pure Ada type only. We skip this in No_Run_Time
905 -- mode where the External_Tag attribute is not allowed anyway.
907 -- Register_Tag (Dt_Ptr);
909 if Is_RTE
(Generalized_Tag
, RE_Tag
)
910 and then not No_Run_Time
912 Append_To
(Elab_Code
,
913 Make_Procedure_Call_Statement
(Loc
,
914 Name
=> New_Reference_To
(RTE
(RE_Register_Tag
), Loc
),
915 Parameter_Associations
=>
916 New_List
(New_Reference_To
(DT_Ptr
, Loc
))));
926 Append_To
(Elab_Code
,
927 Make_Assignment_Statement
(Loc
,
928 Name
=> New_Reference_To
(No_Reg
, Loc
),
929 Expression
=> New_Reference_To
(Standard_False
, Loc
)));
932 Make_Implicit_If_Statement
(Typ
,
933 Condition
=> New_Reference_To
(No_Reg
, Loc
),
934 Then_Statements
=> Elab_Code
));
939 ---------------------------
940 -- Make_DT_Access_Action --
941 ---------------------------
943 function Make_DT_Access_Action
945 Action
: DT_Access_Action
;
949 Action_Name
: Entity_Id
;
953 if Is_CPP_Class
(Root_Type
(Typ
)) then
954 Action_Name
:= RTE
(CPP_Actions
(Action
));
956 Action_Name
:= RTE
(Ada_Actions
(Action
));
961 -- This is a constant
963 return New_Reference_To
(Action_Name
, Sloc
(Typ
));
966 pragma Assert
(List_Length
(Args
) = Action_Nb_Arg
(Action
));
968 Loc
:= Sloc
(First
(Args
));
970 if Action_Is_Proc
(Action
) then
972 Make_Procedure_Call_Statement
(Loc
,
973 Name
=> New_Reference_To
(Action_Name
, Loc
),
974 Parameter_Associations
=> Args
);
978 Make_Function_Call
(Loc
,
979 Name
=> New_Reference_To
(Action_Name
, Loc
),
980 Parameter_Associations
=> Args
);
982 end Make_DT_Access_Action
;
984 -----------------------------------
985 -- Original_View_In_Visible_Part --
986 -----------------------------------
988 function Original_View_In_Visible_Part
(Typ
: Entity_Id
) return Boolean is
989 Scop
: constant Entity_Id
:= Scope
(Typ
);
992 -- The scope must be a package
994 if Ekind
(Scop
) /= E_Package
995 and then Ekind
(Scop
) /= E_Generic_Package
1000 -- A type with a private declaration has a private view declared in
1001 -- the visible part.
1003 if Has_Private_Declaration
(Typ
) then
1007 return List_Containing
(Parent
(Typ
)) =
1008 Visible_Declarations
(Specification
(Unit_Declaration_Node
(Scop
)));
1009 end Original_View_In_Visible_Part
;
1011 -------------------------
1012 -- Set_All_DT_Position --
1013 -------------------------
1015 procedure Set_All_DT_Position
(Typ
: Entity_Id
) is
1016 Parent_Typ
: constant Entity_Id
:= Etype
(Typ
);
1017 Root_Typ
: constant Entity_Id
:= Root_Type
(Typ
);
1018 First_Prim
: constant Elmt_Id
:= First_Elmt
(Primitive_Operations
(Typ
));
1019 The_Tag
: constant Entity_Id
:= Tag_Component
(Typ
);
1020 Adjusted
: Boolean := False;
1021 Finalized
: Boolean := False;
1025 Prim_Elmt
: Elmt_Id
;
1029 -- Get Entry_Count of the parent
1031 if Parent_Typ
/= Typ
1032 and then DT_Entry_Count
(Tag_Component
(Parent_Typ
)) /= No_Uint
1034 Parent_EC
:= UI_To_Int
(DT_Entry_Count
(Tag_Component
(Parent_Typ
)));
1039 -- C++ Case, check that pragma CPP_Class, CPP_Virtual and CPP_Vtable
1040 -- give a coherent set of information
1042 if Is_CPP_Class
(Root_Typ
) then
1044 -- Compute the number of primitive operations in the main Vtable
1045 -- Set their position:
1046 -- - where it was set if overriden or inherited
1047 -- - after the end of the parent vtable otherwise
1049 Prim_Elmt
:= First_Prim
;
1051 while Present
(Prim_Elmt
) loop
1052 Prim
:= Node
(Prim_Elmt
);
1054 if not Is_CPP_Class
(Typ
) then
1055 Set_DTC_Entity
(Prim
, The_Tag
);
1057 elsif Present
(Alias
(Prim
)) then
1058 Set_DTC_Entity
(Prim
, DTC_Entity
(Alias
(Prim
)));
1059 Set_DT_Position
(Prim
, DT_Position
(Alias
(Prim
)));
1061 elsif No
(DTC_Entity
(Prim
)) and then Is_CPP_Class
(Typ
) then
1062 Error_Msg_NE
("is a primitive operation of&," &
1063 " pragma Cpp_Virtual required", Prim
, Typ
);
1066 if DTC_Entity
(Prim
) = The_Tag
then
1068 -- Get the slot from the parent subprogram if any
1071 H
: Entity_Id
:= Homonym
(Prim
);
1074 while Present
(H
) loop
1075 if Present
(DTC_Entity
(H
))
1076 and then Root_Type
(Scope
(DTC_Entity
(H
))) = Root_Typ
1078 Set_DT_Position
(Prim
, DT_Position
(H
));
1086 -- Otherwise take the canonical slot after the end of the
1089 if DT_Position
(Prim
) = No_Uint
then
1090 Nb_Prim
:= Nb_Prim
+ 1;
1091 Set_DT_Position
(Prim
, UI_From_Int
(Parent_EC
+ Nb_Prim
));
1093 elsif UI_To_Int
(DT_Position
(Prim
)) > Parent_EC
then
1094 Nb_Prim
:= Nb_Prim
+ 1;
1098 Next_Elmt
(Prim_Elmt
);
1101 -- Check that the declared size of the Vtable is bigger or equal
1102 -- than the number of primitive operations (if bigger it means that
1103 -- some of the c++ virtual functions were not imported, that is
1106 if DT_Entry_Count
(The_Tag
) = No_Uint
1107 or else not Is_CPP_Class
(Typ
)
1109 Set_DT_Entry_Count
(The_Tag
, UI_From_Int
(Parent_EC
+ Nb_Prim
));
1111 elsif UI_To_Int
(DT_Entry_Count
(The_Tag
)) < Parent_EC
+ Nb_Prim
then
1112 Error_Msg_N
("not enough room in the Vtable for all virtual"
1113 & " functions", The_Tag
);
1116 -- Check that Positions are not duplicate nor outside the range of
1120 Size
: constant Int
:= UI_To_Int
(DT_Entry_Count
(The_Tag
));
1122 Prim_Pos_Table
: array (1 .. Size
) of Entity_Id
:=
1126 Prim_Elmt
:= First_Prim
;
1127 while Present
(Prim_Elmt
) loop
1128 Prim
:= Node
(Prim_Elmt
);
1130 if DTC_Entity
(Prim
) = The_Tag
then
1131 Pos
:= UI_To_Int
(DT_Position
(Prim
));
1133 if Pos
not in Prim_Pos_Table
'Range then
1135 ("position not in range of virtual table", Prim
);
1137 elsif Present
(Prim_Pos_Table
(Pos
)) then
1138 Error_Msg_NE
("cannot be at the same position in the"
1139 & " vtable than&", Prim
, Prim_Pos_Table
(Pos
));
1142 Prim_Pos_Table
(Pos
) := Prim
;
1146 Next_Elmt
(Prim_Elmt
);
1150 -- For regular Ada tagged types, just set the DT_Position for
1151 -- each primitive operation. Perform some sanity checks to avoid
1152 -- to build completely inconsistant dispatch tables.
1157 Prim_Elmt
:= First_Prim
;
1158 while Present
(Prim_Elmt
) loop
1159 Nb_Prim
:= Nb_Prim
+ 1;
1160 Prim
:= Node
(Prim_Elmt
);
1161 Set_DTC_Entity
(Prim
, The_Tag
);
1162 Set_DT_Position
(Prim
, UI_From_Int
(Nb_Prim
));
1164 if Chars
(Prim
) = Name_Finalize
1165 and then (Is_Predefined_File_Name
1166 (Unit_File_Name
(Current_Sem_Unit
))
1168 not Is_Predefined_File_Name
1169 (Unit_File_Name
(Get_Source_Unit
(Prim
))))
1174 if Chars
(Prim
) = Name_Adjust
then
1178 -- An abstract operation cannot be declared in the private part
1179 -- for a visible abstract type, because it could never be over-
1180 -- ridden. For explicit declarations this is checked at the point
1181 -- of declaration, but for inherited operations it must be done
1182 -- when building the dispatch table. Input is excluded because
1183 -- Limited_Controlled inherits a useless Input stream operation
1184 -- from Root_Controlled, which cannot be overridden.
1186 if Is_Abstract
(Typ
)
1187 and then Is_Abstract
(Prim
)
1188 and then Present
(Alias
(Prim
))
1189 and then Is_Derived_Type
(Typ
)
1190 and then In_Private_Part
(Current_Scope
)
1191 and then List_Containing
(Parent
(Prim
))
1192 = Private_Declarations
1193 (Specification
(Unit_Declaration_Node
(Current_Scope
)))
1194 and then Original_View_In_Visible_Part
(Typ
)
1195 and then Chars
(Prim
) /= Name_uInput
1197 Error_Msg_NE
("abstract inherited private operation&"
1198 & " must be overriden", Parent
(Typ
), Prim
);
1200 Next_Elmt
(Prim_Elmt
);
1203 if Is_Controlled
(Typ
) then
1204 if not Finalized
then
1206 ("controlled type has no explicit Finalize method?", Typ
);
1208 elsif not Adjusted
then
1210 ("controlled type has no explicit Adjust method?", Typ
);
1214 Set_DT_Entry_Count
(The_Tag
, UI_From_Int
(Nb_Prim
));
1216 -- The derived type must have at least as many components than
1217 -- its parent (for root types, the etype points back to itself
1218 -- and the test should not fail)
1221 DT_Entry_Count
(The_Tag
) >=
1222 DT_Entry_Count
(Tag_Component
(Parent_Typ
)));
1224 end Set_All_DT_Position
;
1226 -----------------------------
1227 -- Set_Default_Constructor --
1228 -----------------------------
1230 procedure Set_Default_Constructor
(Typ
: Entity_Id
) is
1238 -- Look for the default constructor entity. For now only the
1239 -- default constructor has the flag Is_Constructor.
1241 E
:= Next_Entity
(Typ
);
1243 and then (Ekind
(E
) /= E_Function
or else not Is_Constructor
(E
))
1248 -- Create the init procedure
1252 Init
:= Make_Defining_Identifier
(Loc
, Name_uInit_Proc
);
1253 Param
:= Make_Defining_Identifier
(Loc
, Name_X
);
1255 Make_Subprogram_Declaration
(Loc
,
1256 Make_Procedure_Specification
(Loc
,
1257 Defining_Unit_Name
=> Init
,
1258 Parameter_Specifications
=> New_List
(
1259 Make_Parameter_Specification
(Loc
,
1260 Defining_Identifier
=> Param
,
1261 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)))));
1263 Set_Init_Proc
(Typ
, Init
);
1264 Set_Is_Imported
(Init
);
1265 Set_Interface_Name
(Init
, Interface_Name
(E
));
1266 Set_Convention
(Init
, Convention_C
);
1267 Set_Is_Public
(Init
);
1268 Set_Has_Completion
(Init
);
1270 -- if there are no constructors, mark the type as abstract since we
1271 -- won't be able to declare objects of that type.
1274 Set_Is_Abstract
(Typ
);
1276 end Set_Default_Constructor
;