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_External_Tag => RE_Get_External_Tag,
58 Get_Prim_Op_Address => RE_Get_Prim_Op_Address,
59 Get_RC_Offset => RE_Get_RC_Offset,
60 Get_Remotely_Callable => RE_Get_Remotely_Callable,
61 Get_TSD => RE_Get_TSD,
62 Inherit_DT => RE_Inherit_DT,
63 Inherit_TSD => RE_Inherit_TSD,
64 Register_Tag => RE_Register_Tag,
65 Set_Expanded_Name => RE_Set_Expanded_Name,
66 Set_External_Tag => RE_Set_External_Tag,
67 Set_Prim_Op_Address => RE_Set_Prim_Op_Address,
68 Set_RC_Offset => RE_Set_RC_Offset,
69 Set_Remotely_Callable => RE_Set_Remotely_Callable,
70 Set_TSD => RE_Set_TSD,
71 TSD_Entry_Size => RE_TSD_Entry_Size,
72 TSD_Prologue_Size => RE_TSD_Prologue_Size);
74 CPP_Actions : constant array (DT_Access_Action) of RE_Id :=
75 (CW_Membership => RE_CPP_CW_Membership,
76 DT_Entry_Size => RE_CPP_DT_Entry_Size,
77 DT_Prologue_Size => RE_CPP_DT_Prologue_Size,
78 Get_External_Tag => RE_CPP_Get_External_Tag,
79 Get_Prim_Op_Address => RE_CPP_Get_Prim_Op_Address,
80 Get_RC_Offset => RE_CPP_Get_RC_Offset,
81 Get_Remotely_Callable => RE_CPP_Get_Remotely_Callable,
82 Get_TSD => RE_CPP_Get_TSD,
83 Inherit_DT => RE_CPP_Inherit_DT,
84 Inherit_TSD => RE_CPP_Inherit_TSD,
85 Register_Tag => RE_CPP_Register_Tag,
86 Set_Expanded_Name => RE_CPP_Set_Expanded_Name,
87 Set_External_Tag => RE_CPP_Set_External_Tag,
88 Set_Prim_Op_Address => RE_CPP_Set_Prim_Op_Address,
89 Set_RC_Offset => RE_CPP_Set_RC_Offset,
90 Set_Remotely_Callable => RE_CPP_Set_Remotely_Callable,
91 Set_TSD => RE_CPP_Set_TSD,
92 TSD_Entry_Size => RE_CPP_TSD_Entry_Size,
93 TSD_Prologue_Size => RE_CPP_TSD_Prologue_Size);
95 Action_Is_Proc : constant array (DT_Access_Action) of Boolean :=
96 (CW_Membership => False,
97 DT_Entry_Size => False,
98 DT_Prologue_Size => False,
99 Get_External_Tag => False,
100 Get_Prim_Op_Address => False,
101 Get_Remotely_Callable => False,
102 Get_RC_Offset => False,
106 Register_Tag => True,
107 Set_Expanded_Name => True,
108 Set_External_Tag => True,
109 Set_Prim_Op_Address => True,
110 Set_RC_Offset => True,
111 Set_Remotely_Callable => True,
113 TSD_Entry_Size => False,
114 TSD_Prologue_Size => False);
116 Action_Nb_Arg : constant array (DT_Access_Action) of Int :=
119 DT_Prologue_Size => 0,
120 Get_External_Tag => 1,
121 Get_Prim_Op_Address => 2,
123 Get_Remotely_Callable => 1,
128 Set_Expanded_Name => 2,
129 Set_External_Tag => 2,
130 Set_Prim_Op_Address => 3,
132 Set_Remotely_Callable => 2,
135 TSD_Prologue_Size => 0);
137 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean;
138 -- Check if the type has a private view or if the public view appears
139 -- in the visible part of a package spec.
141 -----------------------------
142 -- Expand_Dispatching_Call --
143 -----------------------------
145 procedure Expand_Dispatching_Call (Call_Node : Node_Id) is
146 Loc : constant Source_Ptr := Sloc (Call_Node);
147 Call_Typ : constant Entity_Id := Etype (Call_Node);
149 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
150 Param_List : constant List_Id := Parameter_Associations (Call_Node);
151 Subp : Entity_Id := Entity (Name (Call_Node));
155 New_Call_Name : Node_Id;
156 New_Params : List_Id := No_List;
159 Subp_Ptr_Typ : Entity_Id;
160 Subp_Typ : Entity_Id;
162 Eq_Prim_Op : Entity_Id := Empty;
163 Controlling_Tag : Node_Id;
165 function New_Value (From : Node_Id) return Node_Id;
166 -- From is the original Expression. New_Value is equivalent to a call
167 -- to Duplicate_Subexpr with an explicit dereference when From is an
170 function Controlling_Type (Subp : Entity_Id) return Entity_Id;
171 -- Returns the tagged type for which Subp is a primitive subprogram
177 function New_Value (From : Node_Id) return Node_Id is
178 Res : constant Node_Id := Duplicate_Subexpr (From);
180 if Is_Access_Type (Etype (From)) then
181 return Make_Explicit_Dereference (Sloc (From), Res);
187 ----------------------
188 -- Controlling_Type --
189 ----------------------
191 function Controlling_Type (Subp : Entity_Id) return Entity_Id is
193 if Ekind (Subp) = E_Function
194 and then Has_Controlling_Result (Subp)
196 return Base_Type (Etype (Subp));
200 Formal : Entity_Id := First_Formal (Subp);
203 while Present (Formal) loop
204 if Is_Controlling_Formal (Formal) then
205 if Is_Access_Type (Etype (Formal)) then
206 return Base_Type (Designated_Type (Etype (Formal)));
208 return Base_Type (Etype (Formal));
212 Next_Formal (Formal);
217 -- Controlling type not found (should never happen)
220 end Controlling_Type;
222 -- Start of processing for Expand_Dispatching_Call
225 -- If this is an inherited operation that was overridden, the body
226 -- that is being called is its alias.
228 if Present (Alias (Subp))
229 and then Is_Inherited_Operation (Subp)
230 and then No (DTC_Entity (Subp))
232 Subp := Alias (Subp);
235 -- Expand_Dispatching_Call is called directly from the semantics,
236 -- so we need a check to see whether expansion is active before
239 if not Expander_Active then
243 -- Definition of the class-wide type and the tagged type
245 -- If the controlling argument is itself a tag rather than a tagged
246 -- object, then use the class-wide type associated with the subprogram's
247 -- controlling type. This case can occur when a call to an inherited
248 -- primitive has an actual that originated from a default parameter
249 -- given by a tag-indeterminate call and when there is no other
250 -- controlling argument providing the tag (AI-239 requires dispatching).
251 -- This capability of dispatching directly by tag is also needed by the
252 -- implementation of AI-260 (for the generic dispatching constructors).
254 if Etype (Ctrl_Arg) = RTE (RE_Tag) then
255 CW_Typ := Class_Wide_Type (Controlling_Type (Subp));
257 elsif Is_Access_Type (Etype (Ctrl_Arg)) then
258 CW_Typ := Designated_Type (Etype (Ctrl_Arg));
261 CW_Typ := Etype (Ctrl_Arg);
264 Typ := Root_Type (CW_Typ);
266 if not Is_Limited_Type (Typ) then
267 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
270 if Is_CPP_Class (Root_Type (Typ)) then
272 -- Create a new parameter list with the displaced 'this'
274 New_Params := New_List;
275 Param := First_Actual (Call_Node);
276 while Present (Param) loop
278 -- We assume that dispatching through the main dispatch table
279 -- (referenced by Tag_Component) doesn't require a displacement
280 -- so the expansion below is only done when dispatching on
281 -- another vtable pointer, in which case the first argument
282 -- is expanded into :
284 -- typ!(Displaced_This (Address!(Param)))
287 and then DTC_Entity (Subp) /= First_Tag_Component (Typ)
289 Append_To (New_Params,
291 Unchecked_Convert_To (Etype (Param),
292 Make_Function_Call (Loc,
293 Name => New_Reference_To (RTE (RE_Displaced_This), Loc),
294 Parameter_Associations => New_List (
298 Make_Unchecked_Type_Conversion (Loc,
300 New_Reference_To (RTE (RE_Address), Loc),
301 Expression => Relocate_Node (Param)),
305 Make_Selected_Component (Loc,
306 Prefix => Duplicate_Subexpr (Ctrl_Arg),
308 New_Reference_To (DTC_Entity (Subp), Loc)),
312 Make_Integer_Literal (Loc, DT_Position (Subp))))));
315 Append_To (New_Params, Relocate_Node (Param));
321 elsif Present (Param_List) then
323 -- Generate the Tag checks when appropriate
325 New_Params := New_List;
327 Param := First_Actual (Call_Node);
328 while Present (Param) loop
330 -- No tag check with itself
332 if Param = Ctrl_Arg then
333 Append_To (New_Params,
334 Duplicate_Subexpr_Move_Checks (Param));
336 -- No tag check for parameter whose type is neither tagged nor
337 -- access to tagged (for access parameters)
339 elsif No (Find_Controlling_Arg (Param)) then
340 Append_To (New_Params, Relocate_Node (Param));
342 -- No tag check for function dispatching on result if the
343 -- Tag given by the context is this one
345 elsif Find_Controlling_Arg (Param) = Ctrl_Arg then
346 Append_To (New_Params, Relocate_Node (Param));
348 -- "=" is the only dispatching operation allowed to get
349 -- operands with incompatible tags (it just returns false).
350 -- We use Duplicate_Subexpr_Move_Checks instead of calling
351 -- Relocate_Node because the value will be duplicated to
354 elsif Subp = Eq_Prim_Op then
355 Append_To (New_Params,
356 Duplicate_Subexpr_Move_Checks (Param));
358 -- No check in presence of suppress flags
360 elsif Tag_Checks_Suppressed (Etype (Param))
361 or else (Is_Access_Type (Etype (Param))
362 and then Tag_Checks_Suppressed
363 (Designated_Type (Etype (Param))))
365 Append_To (New_Params, Relocate_Node (Param));
367 -- Optimization: no tag checks if the parameters are identical
369 elsif Is_Entity_Name (Param)
370 and then Is_Entity_Name (Ctrl_Arg)
371 and then Entity (Param) = Entity (Ctrl_Arg)
373 Append_To (New_Params, Relocate_Node (Param));
375 -- Now we need to generate the Tag check
378 -- Generate code for tag equality check
379 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
381 Insert_Action (Ctrl_Arg,
382 Make_Implicit_If_Statement (Call_Node,
386 Make_Selected_Component (Loc,
387 Prefix => New_Value (Ctrl_Arg),
390 (First_Tag_Component (Typ), Loc)),
393 Make_Selected_Component (Loc,
395 Unchecked_Convert_To (Typ, New_Value (Param)),
398 (First_Tag_Component (Typ), Loc))),
401 New_List (New_Constraint_Error (Loc))));
403 Append_To (New_Params, Relocate_Node (Param));
410 -- Generate the appropriate subprogram pointer type
412 if Etype (Subp) = Typ then
415 Res_Typ := Etype (Subp);
418 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
419 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
420 Set_Etype (Subp_Typ, Res_Typ);
421 Init_Size_Align (Subp_Ptr_Typ);
422 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
424 -- Create a new list of parameters which is a copy of the old formal
425 -- list including the creation of a new set of matching entities.
428 Old_Formal : Entity_Id := First_Formal (Subp);
429 New_Formal : Entity_Id;
433 if Present (Old_Formal) then
434 New_Formal := New_Copy (Old_Formal);
435 Set_First_Entity (Subp_Typ, New_Formal);
436 Param := First_Actual (Call_Node);
439 Set_Scope (New_Formal, Subp_Typ);
441 -- Change all the controlling argument types to be class-wide
442 -- to avoid a recursion in dispatching.
444 if Is_Controlling_Formal (New_Formal) then
445 Set_Etype (New_Formal, Etype (Param));
448 if Is_Itype (Etype (New_Formal)) then
449 Extra := New_Copy (Etype (New_Formal));
451 if Ekind (Extra) = E_Record_Subtype
452 or else Ekind (Extra) = E_Class_Wide_Subtype
454 Set_Cloned_Subtype (Extra, Etype (New_Formal));
457 Set_Etype (New_Formal, Extra);
458 Set_Scope (Etype (New_Formal), Subp_Typ);
462 Next_Formal (Old_Formal);
463 exit when No (Old_Formal);
465 Set_Next_Entity (New_Formal, New_Copy (Old_Formal));
466 Next_Entity (New_Formal);
469 Set_Last_Entity (Subp_Typ, Extra);
471 -- Copy extra formals
473 New_Formal := First_Entity (Subp_Typ);
474 while Present (New_Formal) loop
475 if Present (Extra_Constrained (New_Formal)) then
476 Set_Extra_Formal (Extra,
477 New_Copy (Extra_Constrained (New_Formal)));
478 Extra := Extra_Formal (Extra);
479 Set_Extra_Constrained (New_Formal, Extra);
481 elsif Present (Extra_Accessibility (New_Formal)) then
482 Set_Extra_Formal (Extra,
483 New_Copy (Extra_Accessibility (New_Formal)));
484 Extra := Extra_Formal (Extra);
485 Set_Extra_Accessibility (New_Formal, Extra);
488 Next_Formal (New_Formal);
493 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
494 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
496 -- If the controlling argument is a value of type Ada.Tag then
497 -- use it directly. Otherwise, the tag must be extracted from
498 -- the controlling object.
500 if Etype (Ctrl_Arg) = RTE (RE_Tag) then
501 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
505 Make_Selected_Component (Loc,
506 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
507 Selector_Name => New_Reference_To (DTC_Entity (Subp), Loc));
511 -- Subp_Ptr_Typ!(Get_Prim_Op_Address (Ctrl._Tag, pos));
514 Unchecked_Convert_To (Subp_Ptr_Typ,
515 Make_DT_Access_Action (Typ,
516 Action => Get_Prim_Op_Address,
525 Make_Integer_Literal (Loc, DT_Position (Subp)))));
527 if Nkind (Call_Node) = N_Function_Call then
529 Make_Function_Call (Loc,
530 Name => New_Call_Name,
531 Parameter_Associations => New_Params);
533 -- If this is a dispatching "=", we must first compare the tags so
534 -- we generate: x.tag = y.tag and then x = y
536 if Subp = Eq_Prim_Op then
537 Param := First_Actual (Call_Node);
543 Make_Selected_Component (Loc,
544 Prefix => New_Value (Param),
547 (First_Tag_Component (Typ), Loc)),
550 Make_Selected_Component (Loc,
552 Unchecked_Convert_To (Typ,
553 New_Value (Next_Actual (Param))),
556 (First_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 := Node (First_Elmt
583 (Access_Disp_Table (Typ)));
587 Make_DT_Access_Action (Typ,
588 Action => Set_Prim_Op_Address,
590 New_Reference_To (DT_Ptr, Loc), -- DTptr
592 Make_Integer_Literal (Loc, DT_Position (Prim)), -- Position
594 Make_Attribute_Reference (Loc, -- Value
595 Prefix => New_Reference_To (Prim, Loc),
596 Attribute_Name => Name_Address)));
599 ---------------------------
600 -- Get_Remotely_Callable --
601 ---------------------------
603 function Get_Remotely_Callable (Obj : Node_Id) return Node_Id is
604 Loc : constant Source_Ptr := Sloc (Obj);
607 return Make_DT_Access_Action
609 Action => Get_Remotely_Callable,
611 Make_Selected_Component (Loc,
613 Selector_Name => Make_Identifier (Loc, Name_uTag))));
614 end Get_Remotely_Callable;
620 function Make_DT (Typ : Entity_Id) return List_Id is
621 Loc : constant Source_Ptr := Sloc (Typ);
623 ADT_List : constant Elist_Id := New_Elmt_List;
624 Result : constant List_Id := New_List;
625 Elab_Code : constant List_Id := New_List;
627 Tname : constant Name_Id := Chars (Typ);
628 Name_DT : constant Name_Id := New_External_Name (Tname, 'T');
629 Name_DT_Ptr : constant Name_Id := New_External_Name (Tname, 'P');
630 Name_TSD : constant Name_Id := New_External_Name (Tname, 'B');
631 Name_Exname : constant Name_Id := New_External_Name (Tname, 'E');
632 Name_No_Reg : constant Name_Id := New_External_Name (Tname, 'F');
634 DT : constant Node_Id := Make_Defining_Identifier (Loc, Name_DT);
635 DT_Ptr : constant Node_Id := Make_Defining_Identifier (Loc, Name_DT_Ptr);
636 TSD : constant Node_Id := Make_Defining_Identifier (Loc, Name_TSD);
637 Exname : constant Node_Id := Make_Defining_Identifier (Loc, Name_Exname);
638 No_Reg : constant Node_Id := Make_Defining_Identifier (Loc, Name_No_Reg);
641 Generalized_Tag : Entity_Id;
642 Size_Expr_Node : Node_Id;
647 if not RTE_Available (RE_Tag) then
648 Error_Msg_CRT ("tagged types", Typ);
652 if Is_CPP_Class (Root_Type (Typ)) then
653 Generalized_Tag := RTE (RE_Vtable_Ptr);
655 Generalized_Tag := RTE (RE_Tag);
658 -- Dispatch table and related entities are allocated statically
660 Set_Ekind (DT, E_Variable);
661 Set_Is_Statically_Allocated (DT);
663 Set_Ekind (DT_Ptr, E_Variable);
664 Set_Is_Statically_Allocated (DT_Ptr);
666 Set_Ekind (TSD, E_Variable);
667 Set_Is_Statically_Allocated (TSD);
669 Set_Ekind (Exname, E_Variable);
670 Set_Is_Statically_Allocated (Exname);
672 Set_Ekind (No_Reg, E_Variable);
673 Set_Is_Statically_Allocated (No_Reg);
675 -- Generate code to create the storage for the Dispatch_Table object:
677 -- DT : Storage_Array (1..DT_Prologue_Size+nb_prim*DT_Entry_Size);
678 -- for DT'Alignment use Address'Alignment
682 Left_Opnd => Make_DT_Access_Action (Typ, DT_Prologue_Size, No_List),
684 Make_Op_Multiply (Loc,
686 Make_DT_Access_Action (Typ, DT_Entry_Size, No_List),
688 Make_Integer_Literal (Loc,
689 DT_Entry_Count (First_Tag_Component (Typ)))));
692 Make_Object_Declaration (Loc,
693 Defining_Identifier => DT,
694 Aliased_Present => True,
696 Make_Subtype_Indication (Loc,
697 Subtype_Mark => New_Reference_To (RTE (RE_Storage_Array), Loc),
698 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
699 Constraints => New_List (
701 Low_Bound => Make_Integer_Literal (Loc, 1),
702 High_Bound => Size_Expr_Node))))));
705 Make_Attribute_Definition_Clause (Loc,
706 Name => New_Reference_To (DT, Loc),
707 Chars => Name_Alignment,
709 Make_Attribute_Reference (Loc,
710 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
711 Attribute_Name => Name_Alignment)));
713 -- Generate code to create the pointer to the dispatch table
715 -- DT_Ptr : Tag := Tag!(DT'Address); Ada case
717 -- DT_Ptr : Vtable_Ptr := Vtable_Ptr!(DT'Address); CPP case
719 -- According to the C++ ABI, the base of the vtable is located
720 -- after the following prologue: Offset_To_Top, Typeinfo_Ptr.
721 -- Hence, move the pointer to the base of the vtable down, after
725 Make_Object_Declaration (Loc,
726 Defining_Identifier => DT_Ptr,
727 Constant_Present => True,
728 Object_Definition => New_Reference_To (Generalized_Tag, Loc),
730 Unchecked_Convert_To (Generalized_Tag,
733 Unchecked_Convert_To (RTE (RE_Storage_Offset),
734 Make_Attribute_Reference (Loc,
735 Prefix => New_Reference_To (DT, Loc),
736 Attribute_Name => Name_Address)),
738 Make_DT_Access_Action (Typ,
739 DT_Prologue_Size, No_List)))));
741 -- Generate code to define the boolean that controls registration, in
742 -- order to avoid multiple registrations for tagged types defined in
743 -- multiple-called scopes
746 Make_Object_Declaration (Loc,
747 Defining_Identifier => No_Reg,
748 Object_Definition => New_Reference_To (Standard_Boolean, Loc),
749 Expression => New_Reference_To (Standard_True, Loc)));
751 -- Set Access_Disp_Table field to be the dispatch table pointer
753 Append_Elmt (DT_Ptr, ADT_List);
754 Set_Access_Disp_Table (Typ, ADT_List);
756 -- Count ancestors to compute the inheritance depth. For private
757 -- extensions, always go to the full view in order to compute the real
758 -- inheritance depth.
761 Parent_Type : Entity_Id := Typ;
768 P := Etype (Parent_Type);
770 if Is_Private_Type (P) then
771 P := Full_View (Base_Type (P));
774 exit when P = Parent_Type;
776 I_Depth := I_Depth + 1;
781 -- Generate code to create the storage for the type specific data object
783 -- TSD: Storage_Array (1..TSD_Prologue_Size+(1+Idepth)*TSD_Entry_Size);
784 -- for TSD'Alignment use Address'Alignment
789 Make_DT_Access_Action (Typ, TSD_Prologue_Size, No_List),
791 Make_Op_Multiply (Loc,
793 Make_DT_Access_Action (Typ, TSD_Entry_Size, No_List),
796 Left_Opnd => Make_Integer_Literal (Loc, 1),
798 Make_Integer_Literal (Loc, I_Depth))));
801 Make_Object_Declaration (Loc,
802 Defining_Identifier => TSD,
803 Aliased_Present => True,
805 Make_Subtype_Indication (Loc,
806 Subtype_Mark => New_Reference_To (RTE (RE_Storage_Array), Loc),
807 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
808 Constraints => New_List (
810 Low_Bound => Make_Integer_Literal (Loc, 1),
811 High_Bound => Size_Expr_Node))))));
814 Make_Attribute_Definition_Clause (Loc,
815 Name => New_Reference_To (TSD, Loc),
816 Chars => Name_Alignment,
818 Make_Attribute_Reference (Loc,
819 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
820 Attribute_Name => Name_Alignment)));
822 -- Generate code to put the Address of the TSD in the dispatch table
823 -- Set_TSD (DT_Ptr, TSD);
825 Append_To (Elab_Code,
826 Make_DT_Access_Action (Typ,
829 New_Reference_To (DT_Ptr, Loc), -- DTptr
830 Make_Attribute_Reference (Loc, -- Value
831 Prefix => New_Reference_To (TSD, Loc),
832 Attribute_Name => Name_Address))));
835 or else Is_CPP_Class (Etype (Typ))
838 Unchecked_Convert_To (Generalized_Tag,
839 Make_Integer_Literal (Loc, 0));
842 Unchecked_Convert_To (RTE (RE_Address),
843 Make_Integer_Literal (Loc, 0));
848 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc);
850 Make_DT_Access_Action (Typ,
854 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc)));
857 -- Generate: Inherit_DT (parent'tag, DT_Ptr, nb_prim of parent);
859 Append_To (Elab_Code,
860 Make_DT_Access_Action (Typ,
861 Action => Inherit_DT,
864 Node2 => New_Reference_To (DT_Ptr, Loc),
865 Node3 => Make_Integer_Literal (Loc,
866 DT_Entry_Count (First_Tag_Component (Etype (Typ)))))));
868 -- Generate: Inherit_TSD (Get_TSD (parent), DT_Ptr);
870 Append_To (Elab_Code,
871 Make_DT_Access_Action (Typ,
872 Action => Inherit_TSD,
875 Node2 => New_Reference_To (DT_Ptr, Loc))));
877 -- Generate: Exname : constant String := full_qualified_name (typ);
878 -- The type itself may be an anonymous parent type, so use the first
879 -- subtype to have a user-recognizable name.
882 Make_Object_Declaration (Loc,
883 Defining_Identifier => Exname,
884 Constant_Present => True,
885 Object_Definition => New_Reference_To (Standard_String, Loc),
887 Make_String_Literal (Loc,
888 Full_Qualified_Name (First_Subtype (Typ)))));
890 -- Generate: Set_Expanded_Name (DT_Ptr, exname'Address);
892 Append_To (Elab_Code,
893 Make_DT_Access_Action (Typ,
894 Action => Set_Expanded_Name,
896 Node1 => New_Reference_To (DT_Ptr, Loc),
898 Make_Attribute_Reference (Loc,
899 Prefix => New_Reference_To (Exname, Loc),
900 Attribute_Name => Name_Address))));
902 -- for types with no controlled components
903 -- Generate: Set_RC_Offset (DT_Ptr, 0);
904 -- for simple types with controlled components
905 -- Generate: Set_RC_Offset (DT_Ptr, type._record_controller'position);
906 -- for complex types with controlled components where the position
907 -- of the record controller is not statically computable, if there are
908 -- controlled components at this level
909 -- Generate: Set_RC_Offset (DT_Ptr, -1);
910 -- to indicate that the _controller field is right after the _parent or
911 -- if there are no controlled components at this level,
912 -- Generate: Set_RC_Offset (DT_Ptr, -2);
913 -- to indicate that we need to get the position from the parent.
919 if not Has_Controlled_Component (Typ) then
920 Position := Make_Integer_Literal (Loc, 0);
922 elsif Etype (Typ) /= Typ and then Has_Discriminants (Etype (Typ)) then
923 if Has_New_Controlled_Component (Typ) then
924 Position := Make_Integer_Literal (Loc, -1);
926 Position := Make_Integer_Literal (Loc, -2);
930 Make_Attribute_Reference (Loc,
932 Make_Selected_Component (Loc,
933 Prefix => New_Reference_To (Typ, Loc),
935 New_Reference_To (Controller_Component (Typ), Loc)),
936 Attribute_Name => Name_Position);
938 -- This is not proper Ada code to use the attribute 'Position
939 -- on something else than an object but this is supported by
940 -- the back end (see comment on the Bit_Component attribute in
941 -- sem_attr). So we avoid semantic checking here.
943 Set_Analyzed (Position);
944 Set_Etype (Prefix (Position), RTE (RE_Record_Controller));
945 Set_Etype (Prefix (Prefix (Position)), Typ);
946 Set_Etype (Selector_Name (Prefix (Position)),
947 RTE (RE_Record_Controller));
948 Set_Etype (Position, RTE (RE_Storage_Offset));
951 Append_To (Elab_Code,
952 Make_DT_Access_Action (Typ,
953 Action => Set_RC_Offset,
955 Node1 => New_Reference_To (DT_Ptr, Loc),
956 Node2 => Position)));
959 -- Generate: Set_Remotely_Callable (DT_Ptr, Status);
960 -- where Status is described in E.4 (18)
969 or else Is_Shared_Passive (Typ)
971 ((Is_Remote_Types (Typ)
972 or else Is_Remote_Call_Interface (Typ))
973 and then Original_View_In_Visible_Part (Typ))
974 or else not Comes_From_Source (Typ));
976 Append_To (Elab_Code,
977 Make_DT_Access_Action (Typ,
978 Action => Set_Remotely_Callable,
980 New_Occurrence_Of (DT_Ptr, Loc),
981 New_Occurrence_Of (Status, Loc))));
984 -- Generate: Set_External_Tag (DT_Ptr, exname'Address);
985 -- Should be the external name not the qualified name???
987 if not Has_External_Tag_Rep_Clause (Typ) then
988 Append_To (Elab_Code,
989 Make_DT_Access_Action (Typ,
990 Action => Set_External_Tag,
992 Node1 => New_Reference_To (DT_Ptr, Loc),
994 Make_Attribute_Reference (Loc,
995 Prefix => New_Reference_To (Exname, Loc),
996 Attribute_Name => Name_Address))));
998 -- Generate code to register the Tag in the External_Tag hash
999 -- table for the pure Ada type only.
1001 -- Register_Tag (Dt_Ptr);
1003 -- Skip this if routine not available, or in No_Run_Time mode
1005 if RTE_Available (RE_Register_Tag)
1006 and then Is_RTE (Generalized_Tag, RE_Tag)
1007 and then not No_Run_Time_Mode
1009 Append_To (Elab_Code,
1010 Make_Procedure_Call_Statement (Loc,
1011 Name => New_Reference_To (RTE (RE_Register_Tag), Loc),
1012 Parameter_Associations =>
1013 New_List (New_Reference_To (DT_Ptr, Loc))));
1023 Append_To (Elab_Code,
1024 Make_Assignment_Statement (Loc,
1025 Name => New_Reference_To (No_Reg, Loc),
1026 Expression => New_Reference_To (Standard_False, Loc)));
1029 Make_Implicit_If_Statement (Typ,
1030 Condition => New_Reference_To (No_Reg, Loc),
1031 Then_Statements => Elab_Code));
1036 ---------------------------
1037 -- Make_DT_Access_Action --
1038 ---------------------------
1040 function Make_DT_Access_Action
1042 Action : DT_Access_Action;
1046 Action_Name : Entity_Id;
1050 if Is_CPP_Class (Root_Type (Typ)) then
1051 Action_Name := RTE (CPP_Actions (Action));
1053 Action_Name := RTE (Ada_Actions (Action));
1058 -- This is a constant
1060 return New_Reference_To (Action_Name, Sloc (Typ));
1063 pragma Assert (List_Length (Args) = Action_Nb_Arg (Action));
1065 Loc := Sloc (First (Args));
1067 if Action_Is_Proc (Action) then
1069 Make_Procedure_Call_Statement (Loc,
1070 Name => New_Reference_To (Action_Name, Loc),
1071 Parameter_Associations => Args);
1075 Make_Function_Call (Loc,
1076 Name => New_Reference_To (Action_Name, Loc),
1077 Parameter_Associations => Args);
1079 end Make_DT_Access_Action;
1081 -----------------------------------
1082 -- Original_View_In_Visible_Part --
1083 -----------------------------------
1085 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
1086 Scop : constant Entity_Id := Scope (Typ);
1089 -- The scope must be a package
1091 if Ekind (Scop) /= E_Package
1092 and then Ekind (Scop) /= E_Generic_Package
1097 -- A type with a private declaration has a private view declared in
1098 -- the visible part.
1100 if Has_Private_Declaration (Typ) then
1104 return List_Containing (Parent (Typ)) =
1105 Visible_Declarations (Specification (Unit_Declaration_Node (Scop)));
1106 end Original_View_In_Visible_Part;
1108 -------------------------
1109 -- Set_All_DT_Position --
1110 -------------------------
1112 procedure Set_All_DT_Position (Typ : Entity_Id) is
1113 Parent_Typ : constant Entity_Id := Etype (Typ);
1114 Root_Typ : constant Entity_Id := Root_Type (Typ);
1115 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
1116 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
1117 Adjusted : Boolean := False;
1118 Finalized : Boolean := False;
1122 Prim_Elmt : Elmt_Id;
1126 -- Get Entry_Count of the parent
1128 if Parent_Typ /= Typ
1129 and then DT_Entry_Count (First_Tag_Component (Parent_Typ)) /= No_Uint
1131 Parent_EC := UI_To_Int (DT_Entry_Count
1132 (First_Tag_Component (Parent_Typ)));
1137 -- C++ Case, check that pragma CPP_Class, CPP_Virtual and CPP_Vtable
1138 -- give a coherent set of information
1140 if Is_CPP_Class (Root_Typ) then
1142 -- Compute the number of primitive operations in the main Vtable
1143 -- Set their position:
1144 -- - where it was set if overriden or inherited
1145 -- - after the end of the parent vtable otherwise
1147 Prim_Elmt := First_Prim;
1149 while Present (Prim_Elmt) loop
1150 Prim := Node (Prim_Elmt);
1152 if not Is_CPP_Class (Typ) then
1153 Set_DTC_Entity (Prim, The_Tag);
1155 elsif Present (Alias (Prim)) then
1156 Set_DTC_Entity (Prim, DTC_Entity (Alias (Prim)));
1157 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
1159 elsif No (DTC_Entity (Prim)) and then Is_CPP_Class (Typ) then
1160 Error_Msg_NE ("is a primitive operation of&," &
1161 " pragma Cpp_Virtual required", Prim, Typ);
1164 if DTC_Entity (Prim) = The_Tag then
1166 -- Get the slot from the parent subprogram if any
1169 H : Entity_Id := Homonym (Prim);
1172 while Present (H) loop
1173 if Present (DTC_Entity (H))
1174 and then Root_Type (Scope (DTC_Entity (H))) = Root_Typ
1176 Set_DT_Position (Prim, DT_Position (H));
1184 -- Otherwise take the canonical slot after the end of the
1187 if DT_Position (Prim) = No_Uint then
1188 Nb_Prim := Nb_Prim + 1;
1189 Set_DT_Position (Prim, UI_From_Int (Parent_EC + Nb_Prim));
1191 elsif UI_To_Int (DT_Position (Prim)) > Parent_EC then
1192 Nb_Prim := Nb_Prim + 1;
1196 Next_Elmt (Prim_Elmt);
1199 -- Check that the declared size of the Vtable is bigger or equal
1200 -- than the number of primitive operations (if bigger it means that
1201 -- some of the c++ virtual functions were not imported, that is
1204 if DT_Entry_Count (The_Tag) = No_Uint
1205 or else not Is_CPP_Class (Typ)
1207 Set_DT_Entry_Count (The_Tag, UI_From_Int (Parent_EC + Nb_Prim));
1209 elsif UI_To_Int (DT_Entry_Count (The_Tag)) < Parent_EC + Nb_Prim then
1210 Error_Msg_N ("not enough room in the Vtable for all virtual"
1211 & " functions", The_Tag);
1214 -- Check that Positions are not duplicate nor outside the range of
1218 Size : constant Int := UI_To_Int (DT_Entry_Count (The_Tag));
1220 Prim_Pos_Table : array (1 .. Size) of Entity_Id :=
1224 Prim_Elmt := First_Prim;
1225 while Present (Prim_Elmt) loop
1226 Prim := Node (Prim_Elmt);
1228 if DTC_Entity (Prim) = The_Tag then
1229 Pos := UI_To_Int (DT_Position (Prim));
1231 if Pos not in Prim_Pos_Table'Range then
1233 ("position not in range of virtual table", Prim);
1235 elsif Present (Prim_Pos_Table (Pos)) then
1236 Error_Msg_NE ("cannot be at the same position in the"
1237 & " vtable than&", Prim, Prim_Pos_Table (Pos));
1240 Prim_Pos_Table (Pos) := Prim;
1244 Next_Elmt (Prim_Elmt);
1248 -- For regular Ada tagged types, just set the DT_Position for
1249 -- each primitive operation. Perform some sanity checks to avoid
1250 -- to build completely inconsistant dispatch tables.
1252 -- Note that the _Size primitive is always set at position 1 in order
1253 -- to comply with the needs of Ada.Tags.Parent_Size (see documentation
1258 Prim_Elmt := First_Prim;
1259 while Present (Prim_Elmt) loop
1260 Nb_Prim := Nb_Prim + 1;
1261 Prim := Node (Prim_Elmt);
1262 Set_DTC_Entity (Prim, The_Tag);
1264 if Chars (Prim) = Name_uSize then
1265 Set_DT_Position (Prim, Uint_1);
1266 Nb_Prim := Nb_Prim - 1;
1268 Set_DT_Position (Prim, UI_From_Int (Nb_Prim));
1271 if Chars (Prim) = Name_Finalize
1273 (Is_Predefined_File_Name (Unit_File_Name (Current_Sem_Unit))
1274 or else not Is_Predefined_File_Name
1275 (Unit_File_Name (Get_Source_Unit (Prim))))
1280 if Chars (Prim) = Name_Adjust then
1284 -- An abstract operation cannot be declared in the private part
1285 -- for a visible abstract type, because it could never be over-
1286 -- ridden. For explicit declarations this is checked at the point
1287 -- of declaration, but for inherited operations it must be done
1288 -- when building the dispatch table. Input is excluded because
1290 if Is_Abstract (Typ)
1291 and then Is_Abstract (Prim)
1292 and then Present (Alias (Prim))
1293 and then Is_Derived_Type (Typ)
1294 and then In_Private_Part (Current_Scope)
1295 and then List_Containing (Parent (Prim))
1296 = Private_Declarations
1297 (Specification (Unit_Declaration_Node (Current_Scope)))
1298 and then Original_View_In_Visible_Part (Typ)
1300 -- We exclude Input and Output stream operations because
1301 -- Limited_Controlled inherits useless Input and Output
1302 -- stream operations from Root_Controlled, which can
1303 -- never be overridden.
1305 if not Is_TSS (Prim, TSS_Stream_Input)
1307 not Is_TSS (Prim, TSS_Stream_Output)
1310 ("abstract inherited private operation&" &
1311 " must be overridden ('R'M 3.9.3(10))",
1312 Parent (Typ), Prim);
1315 Next_Elmt (Prim_Elmt);
1318 if Is_Controlled (Typ) then
1319 if not Finalized then
1321 ("controlled type has no explicit Finalize method?", Typ);
1323 elsif not Adjusted then
1325 ("controlled type has no explicit Adjust method?", Typ);
1329 Set_DT_Entry_Count (The_Tag, UI_From_Int (Nb_Prim));
1331 -- The derived type must have at least as many components as its
1332 -- parent (for root types, the Etype points back to itself
1333 -- and the test should not fail)
1336 DT_Entry_Count (The_Tag) >=
1337 DT_Entry_Count (First_Tag_Component (Parent_Typ)));
1339 end Set_All_DT_Position;
1341 -----------------------------
1342 -- Set_Default_Constructor --
1343 -----------------------------
1345 procedure Set_Default_Constructor (Typ : Entity_Id) is
1352 -- Look for the default constructor entity. For now only the
1353 -- default constructor has the flag Is_Constructor.
1355 E := Next_Entity (Typ);
1357 and then (Ekind (E) /= E_Function or else not Is_Constructor (E))
1362 -- Create the init procedure
1366 Init := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
1367 Param := Make_Defining_Identifier (Loc, Name_X);
1370 Make_Subprogram_Declaration (Loc,
1371 Make_Procedure_Specification (Loc,
1372 Defining_Unit_Name => Init,
1373 Parameter_Specifications => New_List (
1374 Make_Parameter_Specification (Loc,
1375 Defining_Identifier => Param,
1376 Parameter_Type => New_Reference_To (Typ, Loc))))));
1378 Set_Init_Proc (Typ, Init);
1379 Set_Is_Imported (Init);
1380 Set_Interface_Name (Init, Interface_Name (E));
1381 Set_Convention (Init, Convention_C);
1382 Set_Is_Public (Init);
1383 Set_Has_Completion (Init);
1385 -- If there are no constructors, mark the type as abstract since we
1386 -- won't be able to declare objects of that type.
1389 Set_Is_Abstract (Typ);
1391 end Set_Default_Constructor;