1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2007, 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 3, 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 COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with Atree; use Atree;
27 with Checks; use Checks;
28 with Debug; use Debug;
29 with Einfo; use Einfo;
30 with Elists; use Elists;
31 with Errout; use Errout;
32 with Exp_Atag; use Exp_Atag;
33 with Exp_Ch7; use Exp_Ch7;
34 with Exp_Dbug; use Exp_Dbug;
35 with Exp_Tss; use Exp_Tss;
36 with Exp_Util; use Exp_Util;
37 with Freeze; use Freeze;
38 with Itypes; use Itypes;
39 with Nlists; use Nlists;
40 with Nmake; use Nmake;
41 with Namet; use Namet;
43 with Output; use Output;
44 with Restrict; use Restrict;
45 with Rident; use Rident;
46 with Rtsfind; use Rtsfind;
48 with Sem_Ch6; use Sem_Ch6;
49 with Sem_Ch8; use Sem_Ch8;
50 with Sem_Disp; use Sem_Disp;
51 with Sem_Eval; use Sem_Eval;
52 with Sem_Res; use Sem_Res;
53 with Sem_Type; use Sem_Type;
54 with Sem_Util; use Sem_Util;
55 with Sinfo; use Sinfo;
56 with Snames; use Snames;
57 with Stand; use Stand;
58 with Stringt; use Stringt;
59 with Targparm; use Targparm;
60 with Tbuild; use Tbuild;
61 with Uintp; use Uintp;
63 package body Exp_Disp is
65 -----------------------
66 -- Local Subprograms --
67 -----------------------
69 function Default_Prim_Op_Position (E : Entity_Id) return Uint;
70 -- Ada 2005 (AI-251): Returns the fixed position in the dispatch table
71 -- of the default primitive operations.
73 function Has_DT (Typ : Entity_Id) return Boolean;
74 pragma Inline (Has_DT);
75 -- Returns true if we generate a dispatch table for tagged type Typ
77 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean;
78 -- Returns true if Prim is not a predefined dispatching primitive but it is
79 -- an alias of a predefined dispatching primitive (ie. through a renaming)
81 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean;
82 -- Check if the type has a private view or if the public view appears
83 -- in the visible part of a package spec.
87 Typ : Entity_Id) return Node_Id;
88 -- Ada 2005 (AI-345): Determine the primitive operation kind of Prim
89 -- according to its type Typ. Return a reference to an RE_Prim_Op_Kind
92 function Tagged_Kind (T : Entity_Id) return Node_Id;
93 -- Ada 2005 (AI-345): Determine the tagged kind of T and return a reference
94 -- to an RE_Tagged_Kind enumeration value.
96 ------------------------
97 -- Building_Static_DT --
98 ------------------------
100 function Building_Static_DT (Typ : Entity_Id) return Boolean is
102 return Static_Dispatch_Tables
103 and then Is_Library_Level_Tagged_Type (Typ)
105 -- If the type is derived from a CPP class we cannot statically
106 -- build the dispatch tables because we must inherit primitives
107 -- from the CPP side.
109 and then not Is_CPP_Class (Root_Type (Typ));
110 end Building_Static_DT;
112 ----------------------------------
113 -- Build_Static_Dispatch_Tables --
114 ----------------------------------
116 procedure Build_Static_Dispatch_Tables (N : Entity_Id) is
117 Target_List : List_Id;
119 procedure Build_Dispatch_Tables (List : List_Id);
120 -- Build the static dispatch table of tagged types found in the list of
121 -- declarations. The generated nodes are added at the end of Target_List
123 procedure Build_Package_Dispatch_Tables (N : Node_Id);
124 -- Build static dispatch tables associated with package declaration N
126 ---------------------------
127 -- Build_Dispatch_Tables --
128 ---------------------------
130 procedure Build_Dispatch_Tables (List : List_Id) is
135 while Present (D) loop
137 -- Handle nested packages and package bodies recursively. The
138 -- generated code is placed on the Target_List established for
139 -- the enclosing compilation unit.
141 if Nkind (D) = N_Package_Declaration then
142 Build_Package_Dispatch_Tables (D);
144 elsif Nkind (D) = N_Package_Body then
145 Build_Dispatch_Tables (Declarations (D));
147 elsif Nkind (D) = N_Package_Body_Stub
148 and then Present (Library_Unit (D))
150 Build_Dispatch_Tables
151 (Declarations (Proper_Body (Unit (Library_Unit (D)))));
153 -- Handle full type declarations and derivations of library
154 -- level tagged types
156 elsif (Nkind (D) = N_Full_Type_Declaration
157 or else Nkind (D) = N_Derived_Type_Definition)
158 and then Is_Library_Level_Tagged_Type (Defining_Entity (D))
159 and then Ekind (Defining_Entity (D)) /= E_Record_Subtype
160 and then not Is_Private_Type (Defining_Entity (D))
162 Insert_List_After_And_Analyze (Last (Target_List),
163 Make_DT (Defining_Entity (D)));
165 -- Handle private types of library level tagged types. We must
166 -- exchange the private and full-view to ensure the correct
169 elsif (Nkind (D) = N_Private_Type_Declaration
170 or else Nkind (D) = N_Private_Extension_Declaration)
171 and then Present (Full_View (Defining_Entity (D)))
172 and then Is_Library_Level_Tagged_Type
173 (Full_View (Defining_Entity (D)))
174 and then Ekind (Full_View (Defining_Entity (D)))
180 E1 := Defining_Entity (D);
181 E2 := Full_View (Defining_Entity (D));
182 Exchange_Entities (E1, E2);
183 Insert_List_After_And_Analyze (Last (Target_List),
185 Exchange_Entities (E1, E2);
191 end Build_Dispatch_Tables;
193 -----------------------------------
194 -- Build_Package_Dispatch_Tables --
195 -----------------------------------
197 procedure Build_Package_Dispatch_Tables (N : Node_Id) is
198 Spec : constant Node_Id := Specification (N);
199 Id : constant Entity_Id := Defining_Entity (N);
200 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
201 Priv_Decls : constant List_Id := Private_Declarations (Spec);
206 if Present (Priv_Decls) then
207 Build_Dispatch_Tables (Vis_Decls);
208 Build_Dispatch_Tables (Priv_Decls);
210 elsif Present (Vis_Decls) then
211 Build_Dispatch_Tables (Vis_Decls);
215 end Build_Package_Dispatch_Tables;
217 -- Start of processing for Build_Static_Dispatch_Tables
220 if not Expander_Active
221 or else VM_Target /= No_VM
226 if Nkind (N) = N_Package_Declaration then
228 Spec : constant Node_Id := Specification (N);
229 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
230 Priv_Decls : constant List_Id := Private_Declarations (Spec);
233 if Present (Priv_Decls)
234 and then Is_Non_Empty_List (Priv_Decls)
236 Target_List := Priv_Decls;
238 elsif not Present (Vis_Decls) then
239 Target_List := New_List;
240 Set_Private_Declarations (Spec, Target_List);
242 Target_List := Vis_Decls;
245 Build_Package_Dispatch_Tables (N);
248 else pragma Assert (Nkind (N) = N_Package_Body);
249 Target_List := Declarations (N);
250 Build_Dispatch_Tables (Target_List);
252 end Build_Static_Dispatch_Tables;
254 ------------------------------
255 -- Default_Prim_Op_Position --
256 ------------------------------
258 function Default_Prim_Op_Position (E : Entity_Id) return Uint is
259 TSS_Name : TSS_Name_Type;
262 Get_Name_String (Chars (E));
265 (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
267 if Chars (E) = Name_uSize then
270 elsif Chars (E) = Name_uAlignment then
273 elsif TSS_Name = TSS_Stream_Read then
276 elsif TSS_Name = TSS_Stream_Write then
279 elsif TSS_Name = TSS_Stream_Input then
282 elsif TSS_Name = TSS_Stream_Output then
285 elsif Chars (E) = Name_Op_Eq then
288 elsif Chars (E) = Name_uAssign then
291 elsif TSS_Name = TSS_Deep_Adjust then
294 elsif TSS_Name = TSS_Deep_Finalize then
297 elsif Ada_Version >= Ada_05 then
298 if Chars (E) = Name_uDisp_Asynchronous_Select then
301 elsif Chars (E) = Name_uDisp_Conditional_Select then
304 elsif Chars (E) = Name_uDisp_Get_Prim_Op_Kind then
307 elsif Chars (E) = Name_uDisp_Get_Task_Id then
310 elsif Chars (E) = Name_uDisp_Timed_Select then
316 end Default_Prim_Op_Position;
318 -----------------------------
319 -- Expand_Dispatching_Call --
320 -----------------------------
322 procedure Expand_Dispatching_Call (Call_Node : Node_Id) is
323 Loc : constant Source_Ptr := Sloc (Call_Node);
324 Call_Typ : constant Entity_Id := Etype (Call_Node);
326 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
327 Param_List : constant List_Id := Parameter_Associations (Call_Node);
332 New_Call_Name : Node_Id;
333 New_Params : List_Id := No_List;
336 Subp_Ptr_Typ : Entity_Id;
337 Subp_Typ : Entity_Id;
339 Eq_Prim_Op : Entity_Id := Empty;
340 Controlling_Tag : Node_Id;
342 function New_Value (From : Node_Id) return Node_Id;
343 -- From is the original Expression. New_Value is equivalent to a call
344 -- to Duplicate_Subexpr with an explicit dereference when From is an
351 function New_Value (From : Node_Id) return Node_Id is
352 Res : constant Node_Id := Duplicate_Subexpr (From);
354 if Is_Access_Type (Etype (From)) then
356 Make_Explicit_Dereference (Sloc (From),
363 -- Start of processing for Expand_Dispatching_Call
366 if No_Run_Time_Mode then
367 Error_Msg_CRT ("tagged types", Call_Node);
371 -- Expand_Dispatching_Call is called directly from the semantics,
372 -- so we need a check to see whether expansion is active before
373 -- proceeding. In addition, there is no need to expand the call
374 -- if we are compiling under restriction No_Dispatching_Calls;
375 -- the semantic analyzer has previously notified the violation
376 -- of this restriction.
378 if not Expander_Active
379 or else Restriction_Active (No_Dispatching_Calls)
384 -- Set subprogram. If this is an inherited operation that was
385 -- overridden, the body that is being called is its alias.
387 Subp := Entity (Name (Call_Node));
389 if Present (Alias (Subp))
390 and then Is_Inherited_Operation (Subp)
391 and then No (DTC_Entity (Subp))
393 Subp := Alias (Subp);
396 -- Definition of the class-wide type and the tagged type
398 -- If the controlling argument is itself a tag rather than a tagged
399 -- object, then use the class-wide type associated with the subprogram's
400 -- controlling type. This case can occur when a call to an inherited
401 -- primitive has an actual that originated from a default parameter
402 -- given by a tag-indeterminate call and when there is no other
403 -- controlling argument providing the tag (AI-239 requires dispatching).
404 -- This capability of dispatching directly by tag is also needed by the
405 -- implementation of AI-260 (for the generic dispatching constructors).
407 if Etype (Ctrl_Arg) = RTE (RE_Tag)
408 or else (RTE_Available (RE_Interface_Tag)
409 and then Etype (Ctrl_Arg) = RTE (RE_Interface_Tag))
411 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
413 -- Class_Wide_Type is applied to the expressions used to initialize
414 -- CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
415 -- there are cases where the controlling type is resolved to a specific
416 -- type (such as for designated types of arguments such as CW'Access).
418 elsif Is_Access_Type (Etype (Ctrl_Arg)) then
419 CW_Typ := Class_Wide_Type (Designated_Type (Etype (Ctrl_Arg)));
422 CW_Typ := Class_Wide_Type (Etype (Ctrl_Arg));
425 Typ := Root_Type (CW_Typ);
427 if Ekind (Typ) = E_Incomplete_Type then
428 Typ := Non_Limited_View (Typ);
431 if not Is_Limited_Type (Typ) then
432 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
435 -- Dispatching call to C++ primitive. Create a new parameter list
436 -- with no tag checks.
438 if Is_CPP_Class (Typ) then
439 New_Params := New_List;
440 Param := First_Actual (Call_Node);
441 while Present (Param) loop
442 Append_To (New_Params, Relocate_Node (Param));
446 -- Dispatching call to Ada primitive
448 elsif Present (Param_List) then
450 -- Generate the Tag checks when appropriate
452 New_Params := New_List;
453 Param := First_Actual (Call_Node);
454 while Present (Param) loop
456 -- No tag check with itself
458 if Param = Ctrl_Arg then
459 Append_To (New_Params,
460 Duplicate_Subexpr_Move_Checks (Param));
462 -- No tag check for parameter whose type is neither tagged nor
463 -- access to tagged (for access parameters)
465 elsif No (Find_Controlling_Arg (Param)) then
466 Append_To (New_Params, Relocate_Node (Param));
468 -- No tag check for function dispatching on result if the
469 -- Tag given by the context is this one
471 elsif Find_Controlling_Arg (Param) = Ctrl_Arg then
472 Append_To (New_Params, Relocate_Node (Param));
474 -- "=" is the only dispatching operation allowed to get
475 -- operands with incompatible tags (it just returns false).
476 -- We use Duplicate_Subexpr_Move_Checks instead of calling
477 -- Relocate_Node because the value will be duplicated to
480 elsif Subp = Eq_Prim_Op then
481 Append_To (New_Params,
482 Duplicate_Subexpr_Move_Checks (Param));
484 -- No check in presence of suppress flags
486 elsif Tag_Checks_Suppressed (Etype (Param))
487 or else (Is_Access_Type (Etype (Param))
488 and then Tag_Checks_Suppressed
489 (Designated_Type (Etype (Param))))
491 Append_To (New_Params, Relocate_Node (Param));
493 -- Optimization: no tag checks if the parameters are identical
495 elsif Is_Entity_Name (Param)
496 and then Is_Entity_Name (Ctrl_Arg)
497 and then Entity (Param) = Entity (Ctrl_Arg)
499 Append_To (New_Params, Relocate_Node (Param));
501 -- Now we need to generate the Tag check
504 -- Generate code for tag equality check
505 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
507 Insert_Action (Ctrl_Arg,
508 Make_Implicit_If_Statement (Call_Node,
512 Make_Selected_Component (Loc,
513 Prefix => New_Value (Ctrl_Arg),
516 (First_Tag_Component (Typ), Loc)),
519 Make_Selected_Component (Loc,
521 Unchecked_Convert_To (Typ, New_Value (Param)),
524 (First_Tag_Component (Typ), Loc))),
527 New_List (New_Constraint_Error (Loc))));
529 Append_To (New_Params, Relocate_Node (Param));
536 -- Generate the appropriate subprogram pointer type
538 if Etype (Subp) = Typ then
541 Res_Typ := Etype (Subp);
544 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
545 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
546 Set_Etype (Subp_Typ, Res_Typ);
547 Init_Size_Align (Subp_Ptr_Typ);
548 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
550 -- Create a new list of parameters which is a copy of the old formal
551 -- list including the creation of a new set of matching entities.
554 Old_Formal : Entity_Id := First_Formal (Subp);
555 New_Formal : Entity_Id;
556 Extra : Entity_Id := Empty;
559 if Present (Old_Formal) then
560 New_Formal := New_Copy (Old_Formal);
561 Set_First_Entity (Subp_Typ, New_Formal);
562 Param := First_Actual (Call_Node);
565 Set_Scope (New_Formal, Subp_Typ);
567 -- Change all the controlling argument types to be class-wide
568 -- to avoid a recursion in dispatching.
570 if Is_Controlling_Formal (New_Formal) then
571 Set_Etype (New_Formal, Etype (Param));
574 if Is_Itype (Etype (New_Formal)) then
575 Extra := New_Copy (Etype (New_Formal));
577 if Ekind (Extra) = E_Record_Subtype
578 or else Ekind (Extra) = E_Class_Wide_Subtype
580 Set_Cloned_Subtype (Extra, Etype (New_Formal));
583 Set_Etype (New_Formal, Extra);
584 Set_Scope (Etype (New_Formal), Subp_Typ);
588 Next_Formal (Old_Formal);
589 exit when No (Old_Formal);
591 Set_Next_Entity (New_Formal, New_Copy (Old_Formal));
592 Next_Entity (New_Formal);
596 Set_Next_Entity (New_Formal, Empty);
597 Set_Last_Entity (Subp_Typ, Extra);
600 -- Now that the explicit formals have been duplicated, any extra
601 -- formals needed by the subprogram must be created.
603 if Present (Extra) then
604 Set_Extra_Formal (Extra, Empty);
607 Create_Extra_Formals (Subp_Typ);
610 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
611 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
613 -- If the controlling argument is a value of type Ada.Tag or an abstract
614 -- interface class-wide type then use it directly. Otherwise, the tag
615 -- must be extracted from the controlling object.
617 if Etype (Ctrl_Arg) = RTE (RE_Tag)
618 or else (RTE_Available (RE_Interface_Tag)
619 and then Etype (Ctrl_Arg) = RTE (RE_Interface_Tag))
621 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
623 -- Extract the tag from an unchecked type conversion. Done to avoid
624 -- the expansion of additional code just to obtain the value of such
625 -- tag because the current management of interface type conversions
626 -- generates in some cases this unchecked type conversion with the
627 -- tag of the object (see Expand_Interface_Conversion).
629 elsif Nkind (Ctrl_Arg) = N_Unchecked_Type_Conversion
631 (Etype (Expression (Ctrl_Arg)) = RTE (RE_Tag)
633 (RTE_Available (RE_Interface_Tag)
635 Etype (Expression (Ctrl_Arg)) = RTE (RE_Interface_Tag)))
637 Controlling_Tag := Duplicate_Subexpr (Expression (Ctrl_Arg));
639 -- Ada 2005 (AI-251): Abstract interface class-wide type
641 elsif Is_Interface (Etype (Ctrl_Arg))
642 and then Is_Class_Wide_Type (Etype (Ctrl_Arg))
644 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
648 Make_Selected_Component (Loc,
649 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
650 Selector_Name => New_Reference_To (DTC_Entity (Subp), Loc));
653 -- Handle dispatching calls to predefined primitives
655 if Is_Predefined_Dispatching_Operation (Subp)
656 or else Is_Predefined_Dispatching_Alias (Subp)
659 Unchecked_Convert_To (Subp_Ptr_Typ,
660 Build_Get_Predefined_Prim_Op_Address (Loc,
661 Tag_Node => Controlling_Tag,
662 Position => DT_Position (Subp)));
664 -- Handle dispatching calls to user-defined primitives
668 Unchecked_Convert_To (Subp_Ptr_Typ,
669 Build_Get_Prim_Op_Address (Loc,
670 Typ => Find_Dispatching_Type (Subp),
671 Tag_Node => Controlling_Tag,
672 Position => DT_Position (Subp)));
675 if Nkind (Call_Node) = N_Function_Call then
678 Make_Function_Call (Loc,
679 Name => New_Call_Name,
680 Parameter_Associations => New_Params);
682 -- If this is a dispatching "=", we must first compare the tags so
683 -- we generate: x.tag = y.tag and then x = y
685 if Subp = Eq_Prim_Op then
686 Param := First_Actual (Call_Node);
692 Make_Selected_Component (Loc,
693 Prefix => New_Value (Param),
695 New_Reference_To (First_Tag_Component (Typ),
699 Make_Selected_Component (Loc,
701 Unchecked_Convert_To (Typ,
702 New_Value (Next_Actual (Param))),
704 New_Reference_To (First_Tag_Component (Typ),
706 Right_Opnd => New_Call);
711 Make_Procedure_Call_Statement (Loc,
712 Name => New_Call_Name,
713 Parameter_Associations => New_Params);
716 Rewrite (Call_Node, New_Call);
718 -- Suppress all checks during the analysis of the expanded code
719 -- to avoid the generation of spureous warnings under ZFP run-time.
721 Analyze_And_Resolve (Call_Node, Call_Typ, Suppress => All_Checks);
722 end Expand_Dispatching_Call;
724 ---------------------------------
725 -- Expand_Interface_Conversion --
726 ---------------------------------
728 procedure Expand_Interface_Conversion
730 Is_Static : Boolean := True)
732 Loc : constant Source_Ptr := Sloc (N);
733 Etyp : constant Entity_Id := Etype (N);
734 Operand : constant Node_Id := Expression (N);
735 Operand_Typ : Entity_Id := Etype (Operand);
737 Iface_Typ : Entity_Id := Etype (N);
738 Iface_Tag : Entity_Id;
741 -- Ada 2005 (AI-345): Handle synchronized interface type derivations
743 if Is_Concurrent_Type (Operand_Typ) then
744 Operand_Typ := Base_Type (Corresponding_Record_Type (Operand_Typ));
747 -- Handle access to class-wide interface types
749 if Is_Access_Type (Iface_Typ) then
750 Iface_Typ := Etype (Directly_Designated_Type (Iface_Typ));
753 -- Handle class-wide interface types. This conversion can appear
754 -- explicitly in the source code. Example: I'Class (Obj)
756 if Is_Class_Wide_Type (Iface_Typ) then
757 Iface_Typ := Root_Type (Iface_Typ);
760 pragma Assert (not Is_Static
761 or else (not Is_Class_Wide_Type (Iface_Typ)
762 and then Is_Interface (Iface_Typ)));
764 if VM_Target /= No_VM then
766 -- For VM, just do a conversion ???
768 Rewrite (N, Unchecked_Convert_To (Etype (N), N));
773 if not Is_Static then
775 -- Give error if configurable run time and Displace not available
777 if not RTE_Available (RE_Displace) then
778 Error_Msg_CRT ("abstract interface types", N);
782 -- Handle conversion of access-to-class-wide interface types. Target
783 -- can be an access to an object or an access to another class-wide
784 -- interface (see -1- and -2- in the following example):
786 -- type Iface1_Ref is access all Iface1'Class;
787 -- type Iface2_Ref is access all Iface1'Class;
789 -- Acc1 : Iface1_Ref := new ...
790 -- Obj : Obj_Ref := Obj_Ref (Acc); -- 1
791 -- Acc2 : Iface2_Ref := Iface2_Ref (Acc); -- 2
793 if Is_Access_Type (Operand_Typ) then
795 (Is_Interface (Directly_Designated_Type (Operand_Typ)));
798 Unchecked_Convert_To (Etype (N),
799 Make_Function_Call (Loc,
800 Name => New_Reference_To (RTE (RE_Displace), Loc),
801 Parameter_Associations => New_List (
803 Unchecked_Convert_To (RTE (RE_Address),
804 Relocate_Node (Expression (N))),
807 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
815 Make_Function_Call (Loc,
816 Name => New_Reference_To (RTE (RE_Displace), Loc),
817 Parameter_Associations => New_List (
818 Make_Attribute_Reference (Loc,
819 Prefix => Relocate_Node (Expression (N)),
820 Attribute_Name => Name_Address),
823 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
828 -- If the target is a class-wide interface we change the type of the
829 -- data returned by IW_Convert to indicate that this is a dispatching
833 New_Itype : Entity_Id;
836 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
837 Set_Etype (New_Itype, New_Itype);
838 Init_Esize (New_Itype);
839 Init_Size_Align (New_Itype);
840 Set_Directly_Designated_Type (New_Itype, Etyp);
843 Make_Explicit_Dereference (Loc,
845 Unchecked_Convert_To (New_Itype, Relocate_Node (N))));
847 Freeze_Itype (New_Itype, N);
853 Iface_Tag := Find_Interface_Tag (Operand_Typ, Iface_Typ);
854 pragma Assert (Iface_Tag /= Empty);
856 -- Keep separate access types to interfaces because one internal
857 -- function is used to handle the null value (see following comment)
859 if not Is_Access_Type (Etype (N)) then
861 Unchecked_Convert_To (Etype (N),
862 Make_Selected_Component (Loc,
863 Prefix => Relocate_Node (Expression (N)),
865 New_Occurrence_Of (Iface_Tag, Loc))));
868 -- Build internal function to handle the case in which the
869 -- actual is null. If the actual is null returns null because
870 -- no displacement is required; otherwise performs a type
871 -- conversion that will be expanded in the code that returns
872 -- the value of the displaced actual. That is:
874 -- function Func (O : Address) return Iface_Typ is
875 -- type Op_Typ is access all Operand_Typ;
876 -- Aux : Op_Typ := To_Op_Typ (O);
878 -- if O = Null_Address then
881 -- return Iface_Typ!(Aux.Iface_Tag'Address);
886 Desig_Typ : Entity_Id;
888 New_Typ_Decl : Node_Id;
892 Desig_Typ := Etype (Expression (N));
894 if Is_Access_Type (Desig_Typ) then
895 Desig_Typ := Directly_Designated_Type (Desig_Typ);
898 if Is_Concurrent_Type (Desig_Typ) then
899 Desig_Typ := Base_Type (Corresponding_Record_Type (Desig_Typ));
903 Make_Full_Type_Declaration (Loc,
904 Defining_Identifier =>
905 Make_Defining_Identifier (Loc, New_Internal_Name ('T')),
907 Make_Access_To_Object_Definition (Loc,
909 Null_Exclusion_Present => False,
910 Constant_Present => False,
911 Subtype_Indication =>
912 New_Reference_To (Desig_Typ, Loc)));
915 Make_Simple_Return_Statement (Loc,
916 Unchecked_Convert_To (Etype (N),
917 Make_Attribute_Reference (Loc,
919 Make_Selected_Component (Loc,
922 (Defining_Identifier (New_Typ_Decl),
923 Make_Identifier (Loc, Name_uO)),
925 New_Occurrence_Of (Iface_Tag, Loc)),
926 Attribute_Name => Name_Address))));
928 -- If the type is null-excluding, no need for the null branch.
929 -- Otherwise we need to check for it and return null.
931 if not Can_Never_Be_Null (Etype (N)) then
933 Make_If_Statement (Loc,
936 Left_Opnd => Make_Identifier (Loc, Name_uO),
937 Right_Opnd => New_Reference_To
938 (RTE (RE_Null_Address), Loc)),
940 Then_Statements => New_List (
941 Make_Simple_Return_Statement (Loc,
943 Else_Statements => Stats));
947 Make_Defining_Identifier (Loc,
948 New_Internal_Name ('F'));
951 Make_Subprogram_Body (Loc,
953 Make_Function_Specification (Loc,
954 Defining_Unit_Name => Fent,
956 Parameter_Specifications => New_List (
957 Make_Parameter_Specification (Loc,
958 Defining_Identifier =>
959 Make_Defining_Identifier (Loc, Name_uO),
961 New_Reference_To (RTE (RE_Address), Loc))),
964 New_Reference_To (Etype (N), Loc)),
966 Declarations => New_List (New_Typ_Decl),
968 Handled_Statement_Sequence =>
969 Make_Handled_Sequence_Of_Statements (Loc, Stats));
971 -- Place function body before the expression containing the
972 -- conversion. We suppress all checks because the body of the
973 -- internally generated function already takes care of the case
974 -- in which the actual is null; therefore there is no need to
975 -- double check that the pointer is not null when the program
976 -- executes the alternative that performs the type conversion).
978 Insert_Action (N, Func, Suppress => All_Checks);
980 if Is_Access_Type (Etype (Expression (N))) then
982 -- Generate: Func (Address!(Expression))
985 Make_Function_Call (Loc,
986 Name => New_Reference_To (Fent, Loc),
987 Parameter_Associations => New_List (
988 Unchecked_Convert_To (RTE (RE_Address),
989 Relocate_Node (Expression (N))))));
992 -- Generate: Func (Operand_Typ!(Expression)'Address)
995 Make_Function_Call (Loc,
996 Name => New_Reference_To (Fent, Loc),
997 Parameter_Associations => New_List (
998 Make_Attribute_Reference (Loc,
999 Prefix => Unchecked_Convert_To (Operand_Typ,
1000 Relocate_Node (Expression (N))),
1001 Attribute_Name => Name_Address))));
1007 end Expand_Interface_Conversion;
1009 ------------------------------
1010 -- Expand_Interface_Actuals --
1011 ------------------------------
1013 procedure Expand_Interface_Actuals (Call_Node : Node_Id) is
1014 Loc : constant Source_Ptr := Sloc (Call_Node);
1016 Actual_Dup : Node_Id;
1017 Actual_Typ : Entity_Id;
1019 Conversion : Node_Id;
1021 Formal_Typ : Entity_Id;
1024 Formal_DDT : Entity_Id;
1025 Actual_DDT : Entity_Id;
1028 -- This subprogram is called directly from the semantics, so we need a
1029 -- check to see whether expansion is active before proceeding.
1031 if not Expander_Active then
1035 -- Call using access to subprogram with explicit dereference
1037 if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
1038 Subp := Etype (Name (Call_Node));
1043 Subp := Entity (Name (Call_Node));
1046 -- Ada 2005 (AI-251): Look for interface type formals to force "this"
1049 Formal := First_Formal (Subp);
1050 Actual := First_Actual (Call_Node);
1051 while Present (Formal) loop
1052 Formal_Typ := Etype (Formal);
1054 if Ekind (Formal_Typ) = E_Record_Type_With_Private then
1055 Formal_Typ := Full_View (Formal_Typ);
1058 if Is_Access_Type (Formal_Typ) then
1059 Formal_DDT := Directly_Designated_Type (Formal_Typ);
1062 Actual_Typ := Etype (Actual);
1064 if Is_Access_Type (Actual_Typ) then
1065 Actual_DDT := Directly_Designated_Type (Actual_Typ);
1068 if Is_Interface (Formal_Typ)
1069 and then Is_Class_Wide_Type (Formal_Typ)
1071 -- No need to displace the pointer if the type of the actual
1072 -- coindices with the type of the formal.
1074 if Actual_Typ = Formal_Typ then
1077 -- No need to displace the pointer if the interface type is
1078 -- a parent of the type of the actual because in this case the
1079 -- interface primitives are located in the primary dispatch table.
1081 elsif Is_Parent (Formal_Typ, Actual_Typ) then
1084 -- Implicit conversion to the class-wide formal type to force
1085 -- the displacement of the pointer.
1088 Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
1089 Rewrite (Actual, Conversion);
1090 Analyze_And_Resolve (Actual, Formal_Typ);
1093 -- Access to class-wide interface type
1095 elsif Is_Access_Type (Formal_Typ)
1096 and then Is_Interface (Formal_DDT)
1097 and then Is_Class_Wide_Type (Formal_DDT)
1098 and then Interface_Present_In_Ancestor
1100 Iface => Etype (Formal_DDT))
1102 -- Handle attributes 'Access and 'Unchecked_Access
1104 if Nkind (Actual) = N_Attribute_Reference
1106 (Attribute_Name (Actual) = Name_Access
1107 or else Attribute_Name (Actual) = Name_Unchecked_Access)
1109 Nam := Attribute_Name (Actual);
1111 Conversion := Convert_To (Formal_DDT, Prefix (Actual));
1112 Rewrite (Actual, Conversion);
1113 Analyze_And_Resolve (Actual, Formal_DDT);
1116 Unchecked_Convert_To (Formal_Typ,
1117 Make_Attribute_Reference (Loc,
1118 Prefix => Relocate_Node (Actual),
1119 Attribute_Name => Nam)));
1120 Analyze_And_Resolve (Actual, Formal_Typ);
1122 -- No need to displace the pointer if the type of the actual
1123 -- coincides with the type of the formal.
1125 elsif Actual_DDT = Formal_DDT then
1128 -- No need to displace the pointer if the interface type is
1129 -- a parent of the type of the actual because in this case the
1130 -- interface primitives are located in the primary dispatch table.
1132 elsif Is_Parent (Formal_DDT, Actual_DDT) then
1136 Actual_Dup := Relocate_Node (Actual);
1138 if From_With_Type (Actual_Typ) then
1140 -- If the type of the actual parameter comes from a limited
1141 -- with-clause and the non-limited view is already available
1142 -- we replace the anonymous access type by a duplicate decla
1143 -- ration whose designated type is the non-limited view
1145 if Ekind (Actual_DDT) = E_Incomplete_Type
1146 and then Present (Non_Limited_View (Actual_DDT))
1148 Anon := New_Copy (Actual_Typ);
1150 if Is_Itype (Anon) then
1151 Set_Scope (Anon, Current_Scope);
1154 Set_Directly_Designated_Type (Anon,
1155 Non_Limited_View (Actual_DDT));
1156 Set_Etype (Actual_Dup, Anon);
1158 elsif Is_Class_Wide_Type (Actual_DDT)
1159 and then Ekind (Etype (Actual_DDT)) = E_Incomplete_Type
1160 and then Present (Non_Limited_View (Etype (Actual_DDT)))
1162 Anon := New_Copy (Actual_Typ);
1164 if Is_Itype (Anon) then
1165 Set_Scope (Anon, Current_Scope);
1168 Set_Directly_Designated_Type (Anon,
1169 New_Copy (Actual_DDT));
1170 Set_Class_Wide_Type (Directly_Designated_Type (Anon),
1171 New_Copy (Class_Wide_Type (Actual_DDT)));
1172 Set_Etype (Directly_Designated_Type (Anon),
1173 Non_Limited_View (Etype (Actual_DDT)));
1175 Class_Wide_Type (Directly_Designated_Type (Anon)),
1176 Non_Limited_View (Etype (Actual_DDT)));
1177 Set_Etype (Actual_Dup, Anon);
1181 Conversion := Convert_To (Formal_Typ, Actual_Dup);
1182 Rewrite (Actual, Conversion);
1183 Analyze_And_Resolve (Actual, Formal_Typ);
1187 Next_Actual (Actual);
1188 Next_Formal (Formal);
1190 end Expand_Interface_Actuals;
1192 ----------------------------
1193 -- Expand_Interface_Thunk --
1194 ----------------------------
1196 procedure Expand_Interface_Thunk
1198 Thunk_Id : out Entity_Id;
1199 Thunk_Code : out Node_Id)
1201 Loc : constant Source_Ptr := Sloc (Prim);
1202 Actuals : constant List_Id := New_List;
1203 Decl : constant List_Id := New_List;
1204 Formals : constant List_Id := New_List;
1206 Controlling_Typ : Entity_Id;
1211 Target_Formal : Entity_Id;
1215 Thunk_Code := Empty;
1217 -- Give message if configurable run-time and Offset_To_Top unavailable
1219 if not RTE_Available (RE_Offset_To_Top) then
1220 Error_Msg_CRT ("abstract interface types", Prim);
1224 -- Traverse the list of alias to find the final target
1227 while Present (Alias (Target)) loop
1228 Target := Alias (Target);
1231 -- In case of primitives that are functions without formals and
1232 -- a controlling result there is no need to build the thunk.
1234 if not Present (First_Formal (Target)) then
1235 pragma Assert (Ekind (Target) = E_Function
1236 and then Has_Controlling_Result (Target));
1240 -- Duplicate the formals
1242 Formal := First_Formal (Target);
1243 while Present (Formal) loop
1245 Make_Parameter_Specification (Loc,
1246 Defining_Identifier =>
1247 Make_Defining_Identifier (Sloc (Formal),
1248 Chars => Chars (Formal)),
1249 In_Present => In_Present (Parent (Formal)),
1250 Out_Present => Out_Present (Parent (Formal)),
1252 New_Reference_To (Etype (Formal), Loc),
1253 Expression => New_Copy_Tree (Expression (Parent (Formal)))));
1255 Next_Formal (Formal);
1258 Controlling_Typ := Find_Dispatching_Type (Target);
1260 Target_Formal := First_Formal (Target);
1261 Formal := First (Formals);
1262 while Present (Formal) loop
1263 if Ekind (Target_Formal) = E_In_Parameter
1264 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
1265 and then Directly_Designated_Type (Etype (Target_Formal))
1270 -- type T is access all <<type of the target formal>>
1271 -- S : Storage_Offset := Storage_Offset!(Formal)
1272 -- - Offset_To_Top (address!(Formal))
1275 Make_Full_Type_Declaration (Loc,
1276 Defining_Identifier =>
1277 Make_Defining_Identifier (Loc,
1278 New_Internal_Name ('T')),
1280 Make_Access_To_Object_Definition (Loc,
1281 All_Present => True,
1282 Null_Exclusion_Present => False,
1283 Constant_Present => False,
1284 Subtype_Indication =>
1286 (Directly_Designated_Type
1287 (Etype (Target_Formal)), Loc)));
1290 Make_Object_Declaration (Loc,
1291 Defining_Identifier =>
1292 Make_Defining_Identifier (Loc,
1293 New_Internal_Name ('S')),
1294 Constant_Present => True,
1295 Object_Definition =>
1296 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1298 Make_Op_Subtract (Loc,
1300 Unchecked_Convert_To
1301 (RTE (RE_Storage_Offset),
1302 New_Reference_To (Defining_Identifier (Formal), Loc)),
1304 Make_Function_Call (Loc,
1306 New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1307 Parameter_Associations => New_List (
1308 Unchecked_Convert_To
1311 (Defining_Identifier (Formal), Loc))))));
1313 Append_To (Decl, Decl_2);
1314 Append_To (Decl, Decl_1);
1316 -- Reference the new actual. Generate:
1320 Unchecked_Convert_To
1321 (Defining_Identifier (Decl_2),
1322 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1324 elsif Etype (Target_Formal) = Controlling_Typ then
1327 -- S1 : Storage_Offset := Storage_Offset!(Formal'Address)
1328 -- - Offset_To_Top (Formal'Address)
1329 -- S2 : Addr_Ptr := Addr_Ptr!(S1)
1332 Make_Object_Declaration (Loc,
1333 Defining_Identifier =>
1334 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1335 Constant_Present => True,
1336 Object_Definition =>
1337 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1339 Make_Op_Subtract (Loc,
1341 Unchecked_Convert_To
1342 (RTE (RE_Storage_Offset),
1343 Make_Attribute_Reference (Loc,
1346 (Defining_Identifier (Formal), Loc),
1347 Attribute_Name => Name_Address)),
1349 Make_Function_Call (Loc,
1351 New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1352 Parameter_Associations => New_List (
1353 Make_Attribute_Reference (Loc,
1356 (Defining_Identifier (Formal), Loc),
1357 Attribute_Name => Name_Address)))));
1360 Make_Object_Declaration (Loc,
1361 Defining_Identifier =>
1362 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1363 Constant_Present => True,
1364 Object_Definition => New_Reference_To (RTE (RE_Addr_Ptr), Loc),
1366 Unchecked_Convert_To
1368 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1370 Append_To (Decl, Decl_1);
1371 Append_To (Decl, Decl_2);
1373 -- Reference the new actual. Generate:
1374 -- Target_Formal (S2.all)
1377 Unchecked_Convert_To
1378 (Etype (Target_Formal),
1379 Make_Explicit_Dereference (Loc,
1380 New_Reference_To (Defining_Identifier (Decl_2), Loc))));
1382 -- No special management required for this actual
1386 New_Reference_To (Defining_Identifier (Formal), Loc));
1389 Next_Formal (Target_Formal);
1394 Make_Defining_Identifier (Loc,
1395 Chars => New_Internal_Name ('T'));
1397 Set_Is_Thunk (Thunk_Id);
1399 if Ekind (Target) = E_Procedure then
1401 Make_Subprogram_Body (Loc,
1403 Make_Procedure_Specification (Loc,
1404 Defining_Unit_Name => Thunk_Id,
1405 Parameter_Specifications => Formals),
1406 Declarations => Decl,
1407 Handled_Statement_Sequence =>
1408 Make_Handled_Sequence_Of_Statements (Loc,
1409 Statements => New_List (
1410 Make_Procedure_Call_Statement (Loc,
1411 Name => New_Occurrence_Of (Target, Loc),
1412 Parameter_Associations => Actuals))));
1414 else pragma Assert (Ekind (Target) = E_Function);
1417 Make_Subprogram_Body (Loc,
1419 Make_Function_Specification (Loc,
1420 Defining_Unit_Name => Thunk_Id,
1421 Parameter_Specifications => Formals,
1422 Result_Definition =>
1423 New_Copy (Result_Definition (Parent (Target)))),
1424 Declarations => Decl,
1425 Handled_Statement_Sequence =>
1426 Make_Handled_Sequence_Of_Statements (Loc,
1427 Statements => New_List (
1428 Make_Simple_Return_Statement (Loc,
1429 Make_Function_Call (Loc,
1430 Name => New_Occurrence_Of (Target, Loc),
1431 Parameter_Associations => Actuals)))));
1433 end Expand_Interface_Thunk;
1439 function Has_DT (Typ : Entity_Id) return Boolean is
1441 return not Is_Interface (Typ)
1442 and then not Restriction_Active (No_Dispatching_Calls);
1445 -------------------------------------
1446 -- Is_Predefined_Dispatching_Alias --
1447 -------------------------------------
1449 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
1454 if not Is_Predefined_Dispatching_Operation (Prim)
1455 and then Present (Alias (Prim))
1458 while Present (Alias (E)) loop
1462 if Is_Predefined_Dispatching_Operation (E) then
1468 end Is_Predefined_Dispatching_Alias;
1470 ----------------------------------------
1471 -- Make_Disp_Asynchronous_Select_Body --
1472 ----------------------------------------
1474 function Make_Disp_Asynchronous_Select_Body
1475 (Typ : Entity_Id) return Node_Id
1477 Com_Block : Entity_Id;
1478 Conc_Typ : Entity_Id := Empty;
1479 Decls : constant List_Id := New_List;
1481 Loc : constant Source_Ptr := Sloc (Typ);
1482 Stmts : constant List_Id := New_List;
1485 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1487 -- Null body is generated for interface types
1489 if Is_Interface (Typ) then
1491 Make_Subprogram_Body (Loc,
1493 Make_Disp_Asynchronous_Select_Spec (Typ),
1496 Handled_Statement_Sequence =>
1497 Make_Handled_Sequence_Of_Statements (Loc,
1498 New_List (Make_Null_Statement (Loc))));
1501 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1503 if Is_Concurrent_Record_Type (Typ) then
1504 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1507 -- I : Integer := Get_Entry_Index (tag! (<type>VP), S);
1509 -- where I will be used to capture the entry index of the primitive
1510 -- wrapper at position S.
1513 Make_Object_Declaration (Loc,
1514 Defining_Identifier =>
1515 Make_Defining_Identifier (Loc, Name_uI),
1516 Object_Definition =>
1517 New_Reference_To (Standard_Integer, Loc),
1519 Make_Function_Call (Loc,
1520 Name => New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
1521 Parameter_Associations => New_List (
1522 Unchecked_Convert_To (RTE (RE_Tag),
1523 New_Reference_To (DT_Ptr, Loc)),
1524 Make_Identifier (Loc, Name_uS)))));
1526 if Ekind (Conc_Typ) = E_Protected_Type then
1529 -- Com_Block : Communication_Block;
1532 Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1535 Make_Object_Declaration (Loc,
1536 Defining_Identifier =>
1538 Object_Definition =>
1539 New_Reference_To (RTE (RE_Communication_Block), Loc)));
1542 -- Protected_Entry_Call (
1543 -- T._object'access,
1544 -- protected_entry_index! (I),
1546 -- Asynchronous_Call,
1549 -- where T is the protected object, I is the entry index, P are
1550 -- the wrapped parameters and B is the name of the communication
1554 Make_Procedure_Call_Statement (Loc,
1556 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1557 Parameter_Associations =>
1560 Make_Attribute_Reference (Loc, -- T._object'access
1562 Name_Unchecked_Access,
1564 Make_Selected_Component (Loc,
1566 Make_Identifier (Loc, Name_uT),
1568 Make_Identifier (Loc, Name_uObject))),
1570 Make_Unchecked_Type_Conversion (Loc, -- entry index
1572 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
1574 Make_Identifier (Loc, Name_uI)),
1576 Make_Identifier (Loc, Name_uP), -- parameter block
1577 New_Reference_To ( -- Asynchronous_Call
1578 RTE (RE_Asynchronous_Call), Loc),
1580 New_Reference_To (Com_Block, Loc)))); -- comm block
1583 -- B := Dummy_Communication_Bloc (Com_Block);
1586 Make_Assignment_Statement (Loc,
1588 Make_Identifier (Loc, Name_uB),
1590 Make_Unchecked_Type_Conversion (Loc,
1593 RTE (RE_Dummy_Communication_Block), Loc),
1595 New_Reference_To (Com_Block, Loc))));
1598 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
1601 -- Protected_Entry_Call (
1603 -- task_entry_index! (I),
1605 -- Conditional_Call,
1608 -- where T is the task object, I is the entry index, P are the
1609 -- wrapped parameters and F is the status flag.
1612 Make_Procedure_Call_Statement (Loc,
1614 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
1615 Parameter_Associations =>
1618 Make_Selected_Component (Loc, -- T._task_id
1620 Make_Identifier (Loc, Name_uT),
1622 Make_Identifier (Loc, Name_uTask_Id)),
1624 Make_Unchecked_Type_Conversion (Loc, -- entry index
1626 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
1628 Make_Identifier (Loc, Name_uI)),
1630 Make_Identifier (Loc, Name_uP), -- parameter block
1631 New_Reference_To ( -- Asynchronous_Call
1632 RTE (RE_Asynchronous_Call), Loc),
1633 Make_Identifier (Loc, Name_uF)))); -- status flag
1638 Make_Subprogram_Body (Loc,
1640 Make_Disp_Asynchronous_Select_Spec (Typ),
1643 Handled_Statement_Sequence =>
1644 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
1645 end Make_Disp_Asynchronous_Select_Body;
1647 ----------------------------------------
1648 -- Make_Disp_Asynchronous_Select_Spec --
1649 ----------------------------------------
1651 function Make_Disp_Asynchronous_Select_Spec
1652 (Typ : Entity_Id) return Node_Id
1654 Loc : constant Source_Ptr := Sloc (Typ);
1655 Def_Id : constant Node_Id :=
1656 Make_Defining_Identifier (Loc,
1657 Name_uDisp_Asynchronous_Select);
1658 Params : constant List_Id := New_List;
1661 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1663 -- T : in out Typ; -- Object parameter
1664 -- S : Integer; -- Primitive operation slot
1665 -- P : Address; -- Wrapped parameters
1666 -- B : out Dummy_Communication_Block; -- Communication block dummy
1667 -- F : out Boolean; -- Status flag
1669 Append_List_To (Params, New_List (
1671 Make_Parameter_Specification (Loc,
1672 Defining_Identifier =>
1673 Make_Defining_Identifier (Loc, Name_uT),
1675 New_Reference_To (Typ, Loc),
1677 Out_Present => True),
1679 Make_Parameter_Specification (Loc,
1680 Defining_Identifier =>
1681 Make_Defining_Identifier (Loc, Name_uS),
1683 New_Reference_To (Standard_Integer, Loc)),
1685 Make_Parameter_Specification (Loc,
1686 Defining_Identifier =>
1687 Make_Defining_Identifier (Loc, Name_uP),
1689 New_Reference_To (RTE (RE_Address), Loc)),
1691 Make_Parameter_Specification (Loc,
1692 Defining_Identifier =>
1693 Make_Defining_Identifier (Loc, Name_uB),
1695 New_Reference_To (RTE (RE_Dummy_Communication_Block), Loc),
1696 Out_Present => True),
1698 Make_Parameter_Specification (Loc,
1699 Defining_Identifier =>
1700 Make_Defining_Identifier (Loc, Name_uF),
1702 New_Reference_To (Standard_Boolean, Loc),
1703 Out_Present => True)));
1706 Make_Procedure_Specification (Loc,
1707 Defining_Unit_Name => Def_Id,
1708 Parameter_Specifications => Params);
1709 end Make_Disp_Asynchronous_Select_Spec;
1711 ---------------------------------------
1712 -- Make_Disp_Conditional_Select_Body --
1713 ---------------------------------------
1715 function Make_Disp_Conditional_Select_Body
1716 (Typ : Entity_Id) return Node_Id
1718 Loc : constant Source_Ptr := Sloc (Typ);
1719 Blk_Nam : Entity_Id;
1720 Conc_Typ : Entity_Id := Empty;
1721 Decls : constant List_Id := New_List;
1723 Stmts : constant List_Id := New_List;
1726 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1728 -- Null body is generated for interface types
1730 if Is_Interface (Typ) then
1732 Make_Subprogram_Body (Loc,
1734 Make_Disp_Conditional_Select_Spec (Typ),
1737 Handled_Statement_Sequence =>
1738 Make_Handled_Sequence_Of_Statements (Loc,
1739 New_List (Make_Null_Statement (Loc))));
1742 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1744 if Is_Concurrent_Record_Type (Typ) then
1745 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1750 -- where I will be used to capture the entry index of the primitive
1751 -- wrapper at position S.
1754 Make_Object_Declaration (Loc,
1755 Defining_Identifier =>
1756 Make_Defining_Identifier (Loc, Name_uI),
1757 Object_Definition =>
1758 New_Reference_To (Standard_Integer, Loc)));
1761 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
1763 -- if C = POK_Procedure
1764 -- or else C = POK_Protected_Procedure
1765 -- or else C = POK_Task_Procedure;
1771 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
1774 -- Bnn : Communication_Block;
1776 -- where Bnn is the name of the communication block used in
1777 -- the call to Protected_Entry_Call.
1779 Blk_Nam := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1782 Make_Object_Declaration (Loc,
1783 Defining_Identifier =>
1785 Object_Definition =>
1786 New_Reference_To (RTE (RE_Communication_Block), Loc)));
1789 -- I := Get_Entry_Index (tag! (<type>VP), S);
1791 -- I is the entry index and S is the dispatch table slot
1794 Make_Assignment_Statement (Loc,
1796 Make_Identifier (Loc, Name_uI),
1798 Make_Function_Call (Loc,
1799 Name => New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
1800 Parameter_Associations => New_List (
1801 Unchecked_Convert_To (RTE (RE_Tag),
1802 New_Reference_To (DT_Ptr, Loc)),
1803 Make_Identifier (Loc, Name_uS)))));
1805 if Ekind (Conc_Typ) = E_Protected_Type then
1808 -- Protected_Entry_Call (
1809 -- T._object'access,
1810 -- protected_entry_index! (I),
1812 -- Conditional_Call,
1815 -- where T is the protected object, I is the entry index, P are
1816 -- the wrapped parameters and Bnn is the name of the communication
1820 Make_Procedure_Call_Statement (Loc,
1822 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1823 Parameter_Associations =>
1826 Make_Attribute_Reference (Loc, -- T._object'access
1828 Name_Unchecked_Access,
1830 Make_Selected_Component (Loc,
1832 Make_Identifier (Loc, Name_uT),
1834 Make_Identifier (Loc, Name_uObject))),
1836 Make_Unchecked_Type_Conversion (Loc, -- entry index
1838 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
1840 Make_Identifier (Loc, Name_uI)),
1842 Make_Identifier (Loc, Name_uP), -- parameter block
1843 New_Reference_To ( -- Conditional_Call
1844 RTE (RE_Conditional_Call), Loc),
1845 New_Reference_To ( -- Bnn
1849 -- F := not Cancelled (Bnn);
1851 -- where F is the success flag. The status of Cancelled is negated
1852 -- in order to match the behaviour of the version for task types.
1855 Make_Assignment_Statement (Loc,
1857 Make_Identifier (Loc, Name_uF),
1861 Make_Function_Call (Loc,
1863 New_Reference_To (RTE (RE_Cancelled), Loc),
1864 Parameter_Associations =>
1866 New_Reference_To (Blk_Nam, Loc))))));
1868 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
1871 -- Protected_Entry_Call (
1873 -- task_entry_index! (I),
1875 -- Conditional_Call,
1878 -- where T is the task object, I is the entry index, P are the
1879 -- wrapped parameters and F is the status flag.
1882 Make_Procedure_Call_Statement (Loc,
1884 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
1885 Parameter_Associations =>
1888 Make_Selected_Component (Loc, -- T._task_id
1890 Make_Identifier (Loc, Name_uT),
1892 Make_Identifier (Loc, Name_uTask_Id)),
1894 Make_Unchecked_Type_Conversion (Loc, -- entry index
1896 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
1898 Make_Identifier (Loc, Name_uI)),
1900 Make_Identifier (Loc, Name_uP), -- parameter block
1901 New_Reference_To ( -- Conditional_Call
1902 RTE (RE_Conditional_Call), Loc),
1903 Make_Identifier (Loc, Name_uF)))); -- status flag
1908 Make_Subprogram_Body (Loc,
1910 Make_Disp_Conditional_Select_Spec (Typ),
1913 Handled_Statement_Sequence =>
1914 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
1915 end Make_Disp_Conditional_Select_Body;
1917 ---------------------------------------
1918 -- Make_Disp_Conditional_Select_Spec --
1919 ---------------------------------------
1921 function Make_Disp_Conditional_Select_Spec
1922 (Typ : Entity_Id) return Node_Id
1924 Loc : constant Source_Ptr := Sloc (Typ);
1925 Def_Id : constant Node_Id :=
1926 Make_Defining_Identifier (Loc,
1927 Name_uDisp_Conditional_Select);
1928 Params : constant List_Id := New_List;
1931 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1933 -- T : in out Typ; -- Object parameter
1934 -- S : Integer; -- Primitive operation slot
1935 -- P : Address; -- Wrapped parameters
1936 -- C : out Prim_Op_Kind; -- Call kind
1937 -- F : out Boolean; -- Status flag
1939 Append_List_To (Params, New_List (
1941 Make_Parameter_Specification (Loc,
1942 Defining_Identifier =>
1943 Make_Defining_Identifier (Loc, Name_uT),
1945 New_Reference_To (Typ, Loc),
1947 Out_Present => True),
1949 Make_Parameter_Specification (Loc,
1950 Defining_Identifier =>
1951 Make_Defining_Identifier (Loc, Name_uS),
1953 New_Reference_To (Standard_Integer, Loc)),
1955 Make_Parameter_Specification (Loc,
1956 Defining_Identifier =>
1957 Make_Defining_Identifier (Loc, Name_uP),
1959 New_Reference_To (RTE (RE_Address), Loc)),
1961 Make_Parameter_Specification (Loc,
1962 Defining_Identifier =>
1963 Make_Defining_Identifier (Loc, Name_uC),
1965 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
1966 Out_Present => True),
1968 Make_Parameter_Specification (Loc,
1969 Defining_Identifier =>
1970 Make_Defining_Identifier (Loc, Name_uF),
1972 New_Reference_To (Standard_Boolean, Loc),
1973 Out_Present => True)));
1976 Make_Procedure_Specification (Loc,
1977 Defining_Unit_Name => Def_Id,
1978 Parameter_Specifications => Params);
1979 end Make_Disp_Conditional_Select_Spec;
1981 -------------------------------------
1982 -- Make_Disp_Get_Prim_Op_Kind_Body --
1983 -------------------------------------
1985 function Make_Disp_Get_Prim_Op_Kind_Body
1986 (Typ : Entity_Id) return Node_Id
1988 Loc : constant Source_Ptr := Sloc (Typ);
1992 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1994 if Is_Interface (Typ) then
1996 Make_Subprogram_Body (Loc,
1998 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2001 Handled_Statement_Sequence =>
2002 Make_Handled_Sequence_Of_Statements (Loc,
2003 New_List (Make_Null_Statement (Loc))));
2006 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2009 -- C := get_prim_op_kind (tag! (<type>VP), S);
2011 -- where C is the out parameter capturing the call kind and S is the
2012 -- dispatch table slot number.
2015 Make_Subprogram_Body (Loc,
2017 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2020 Handled_Statement_Sequence =>
2021 Make_Handled_Sequence_Of_Statements (Loc,
2023 Make_Assignment_Statement (Loc,
2025 Make_Identifier (Loc, Name_uC),
2027 Make_Function_Call (Loc,
2029 New_Reference_To (RTE (RE_Get_Prim_Op_Kind), Loc),
2030 Parameter_Associations => New_List (
2031 Unchecked_Convert_To (RTE (RE_Tag),
2032 New_Reference_To (DT_Ptr, Loc)),
2033 Make_Identifier (Loc, Name_uS)))))));
2034 end Make_Disp_Get_Prim_Op_Kind_Body;
2036 -------------------------------------
2037 -- Make_Disp_Get_Prim_Op_Kind_Spec --
2038 -------------------------------------
2040 function Make_Disp_Get_Prim_Op_Kind_Spec
2041 (Typ : Entity_Id) return Node_Id
2043 Loc : constant Source_Ptr := Sloc (Typ);
2044 Def_Id : constant Node_Id :=
2045 Make_Defining_Identifier (Loc,
2046 Name_uDisp_Get_Prim_Op_Kind);
2047 Params : constant List_Id := New_List;
2050 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2052 -- T : in out Typ; -- Object parameter
2053 -- S : Integer; -- Primitive operation slot
2054 -- C : out Prim_Op_Kind; -- Call kind
2056 Append_List_To (Params, New_List (
2058 Make_Parameter_Specification (Loc,
2059 Defining_Identifier =>
2060 Make_Defining_Identifier (Loc, Name_uT),
2062 New_Reference_To (Typ, Loc),
2064 Out_Present => True),
2066 Make_Parameter_Specification (Loc,
2067 Defining_Identifier =>
2068 Make_Defining_Identifier (Loc, Name_uS),
2070 New_Reference_To (Standard_Integer, Loc)),
2072 Make_Parameter_Specification (Loc,
2073 Defining_Identifier =>
2074 Make_Defining_Identifier (Loc, Name_uC),
2076 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2077 Out_Present => True)));
2080 Make_Procedure_Specification (Loc,
2081 Defining_Unit_Name => Def_Id,
2082 Parameter_Specifications => Params);
2083 end Make_Disp_Get_Prim_Op_Kind_Spec;
2085 --------------------------------
2086 -- Make_Disp_Get_Task_Id_Body --
2087 --------------------------------
2089 function Make_Disp_Get_Task_Id_Body
2090 (Typ : Entity_Id) return Node_Id
2092 Loc : constant Source_Ptr := Sloc (Typ);
2096 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2098 if Is_Concurrent_Record_Type (Typ)
2099 and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
2102 -- return To_Address (_T._task_id);
2105 Make_Simple_Return_Statement (Loc,
2107 Make_Unchecked_Type_Conversion (Loc,
2109 New_Reference_To (RTE (RE_Address), Loc),
2111 Make_Selected_Component (Loc,
2113 Make_Identifier (Loc, Name_uT),
2115 Make_Identifier (Loc, Name_uTask_Id))));
2117 -- A null body is constructed for non-task types
2121 -- return Null_Address;
2124 Make_Simple_Return_Statement (Loc,
2126 New_Reference_To (RTE (RE_Null_Address), Loc));
2130 Make_Subprogram_Body (Loc,
2132 Make_Disp_Get_Task_Id_Spec (Typ),
2135 Handled_Statement_Sequence =>
2136 Make_Handled_Sequence_Of_Statements (Loc,
2138 end Make_Disp_Get_Task_Id_Body;
2140 --------------------------------
2141 -- Make_Disp_Get_Task_Id_Spec --
2142 --------------------------------
2144 function Make_Disp_Get_Task_Id_Spec
2145 (Typ : Entity_Id) return Node_Id
2147 Loc : constant Source_Ptr := Sloc (Typ);
2150 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2153 Make_Function_Specification (Loc,
2154 Defining_Unit_Name =>
2155 Make_Defining_Identifier (Loc, Name_uDisp_Get_Task_Id),
2156 Parameter_Specifications => New_List (
2157 Make_Parameter_Specification (Loc,
2158 Defining_Identifier =>
2159 Make_Defining_Identifier (Loc, Name_uT),
2161 New_Reference_To (Typ, Loc))),
2162 Result_Definition =>
2163 New_Reference_To (RTE (RE_Address), Loc));
2164 end Make_Disp_Get_Task_Id_Spec;
2166 ---------------------------------
2167 -- Make_Disp_Timed_Select_Body --
2168 ---------------------------------
2170 function Make_Disp_Timed_Select_Body
2171 (Typ : Entity_Id) return Node_Id
2173 Loc : constant Source_Ptr := Sloc (Typ);
2174 Conc_Typ : Entity_Id := Empty;
2175 Decls : constant List_Id := New_List;
2177 Stmts : constant List_Id := New_List;
2180 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2182 -- Null body is generated for interface types
2184 if Is_Interface (Typ) then
2186 Make_Subprogram_Body (Loc,
2188 Make_Disp_Timed_Select_Spec (Typ),
2191 Handled_Statement_Sequence =>
2192 Make_Handled_Sequence_Of_Statements (Loc,
2193 New_List (Make_Null_Statement (Loc))));
2196 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2198 if Is_Concurrent_Record_Type (Typ) then
2199 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2204 -- where I will be used to capture the entry index of the primitive
2205 -- wrapper at position S.
2208 Make_Object_Declaration (Loc,
2209 Defining_Identifier =>
2210 Make_Defining_Identifier (Loc, Name_uI),
2211 Object_Definition =>
2212 New_Reference_To (Standard_Integer, Loc)));
2215 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
2217 -- if C = POK_Procedure
2218 -- or else C = POK_Protected_Procedure
2219 -- or else C = POK_Task_Procedure;
2225 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
2228 -- I := Get_Entry_Index (tag! (<type>VP), S);
2230 -- I is the entry index and S is the dispatch table slot
2233 Make_Assignment_Statement (Loc,
2235 Make_Identifier (Loc, Name_uI),
2237 Make_Function_Call (Loc,
2238 Name => New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
2239 Parameter_Associations => New_List (
2240 Unchecked_Convert_To (RTE (RE_Tag),
2241 New_Reference_To (DT_Ptr, Loc)),
2242 Make_Identifier (Loc, Name_uS)))));
2244 if Ekind (Conc_Typ) = E_Protected_Type then
2247 -- Timed_Protected_Entry_Call (
2248 -- T._object'access,
2249 -- protected_entry_index! (I),
2255 -- where T is the protected object, I is the entry index, P are
2256 -- the wrapped parameters, D is the delay amount, M is the delay
2257 -- mode and F is the status flag.
2260 Make_Procedure_Call_Statement (Loc,
2262 New_Reference_To (RTE (RE_Timed_Protected_Entry_Call), Loc),
2263 Parameter_Associations =>
2266 Make_Attribute_Reference (Loc, -- T._object'access
2268 Name_Unchecked_Access,
2270 Make_Selected_Component (Loc,
2272 Make_Identifier (Loc, Name_uT),
2274 Make_Identifier (Loc, Name_uObject))),
2276 Make_Unchecked_Type_Conversion (Loc, -- entry index
2278 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
2280 Make_Identifier (Loc, Name_uI)),
2282 Make_Identifier (Loc, Name_uP), -- parameter block
2283 Make_Identifier (Loc, Name_uD), -- delay
2284 Make_Identifier (Loc, Name_uM), -- delay mode
2285 Make_Identifier (Loc, Name_uF)))); -- status flag
2288 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2291 -- Timed_Task_Entry_Call (
2293 -- task_entry_index! (I),
2299 -- where T is the task object, I is the entry index, P are the
2300 -- wrapped parameters, D is the delay amount, M is the delay
2301 -- mode and F is the status flag.
2304 Make_Procedure_Call_Statement (Loc,
2306 New_Reference_To (RTE (RE_Timed_Task_Entry_Call), Loc),
2307 Parameter_Associations =>
2310 Make_Selected_Component (Loc, -- T._task_id
2312 Make_Identifier (Loc, Name_uT),
2314 Make_Identifier (Loc, Name_uTask_Id)),
2316 Make_Unchecked_Type_Conversion (Loc, -- entry index
2318 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2320 Make_Identifier (Loc, Name_uI)),
2322 Make_Identifier (Loc, Name_uP), -- parameter block
2323 Make_Identifier (Loc, Name_uD), -- delay
2324 Make_Identifier (Loc, Name_uM), -- delay mode
2325 Make_Identifier (Loc, Name_uF)))); -- status flag
2330 Make_Subprogram_Body (Loc,
2332 Make_Disp_Timed_Select_Spec (Typ),
2335 Handled_Statement_Sequence =>
2336 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2337 end Make_Disp_Timed_Select_Body;
2339 ---------------------------------
2340 -- Make_Disp_Timed_Select_Spec --
2341 ---------------------------------
2343 function Make_Disp_Timed_Select_Spec
2344 (Typ : Entity_Id) return Node_Id
2346 Loc : constant Source_Ptr := Sloc (Typ);
2347 Def_Id : constant Node_Id :=
2348 Make_Defining_Identifier (Loc,
2349 Name_uDisp_Timed_Select);
2350 Params : constant List_Id := New_List;
2353 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2355 -- T : in out Typ; -- Object parameter
2356 -- S : Integer; -- Primitive operation slot
2357 -- P : Address; -- Wrapped parameters
2358 -- D : Duration; -- Delay
2359 -- M : Integer; -- Delay Mode
2360 -- C : out Prim_Op_Kind; -- Call kind
2361 -- F : out Boolean; -- Status flag
2363 Append_List_To (Params, New_List (
2365 Make_Parameter_Specification (Loc,
2366 Defining_Identifier =>
2367 Make_Defining_Identifier (Loc, Name_uT),
2369 New_Reference_To (Typ, Loc),
2371 Out_Present => True),
2373 Make_Parameter_Specification (Loc,
2374 Defining_Identifier =>
2375 Make_Defining_Identifier (Loc, Name_uS),
2377 New_Reference_To (Standard_Integer, Loc)),
2379 Make_Parameter_Specification (Loc,
2380 Defining_Identifier =>
2381 Make_Defining_Identifier (Loc, Name_uP),
2383 New_Reference_To (RTE (RE_Address), Loc)),
2385 Make_Parameter_Specification (Loc,
2386 Defining_Identifier =>
2387 Make_Defining_Identifier (Loc, Name_uD),
2389 New_Reference_To (Standard_Duration, Loc)),
2391 Make_Parameter_Specification (Loc,
2392 Defining_Identifier =>
2393 Make_Defining_Identifier (Loc, Name_uM),
2395 New_Reference_To (Standard_Integer, Loc)),
2397 Make_Parameter_Specification (Loc,
2398 Defining_Identifier =>
2399 Make_Defining_Identifier (Loc, Name_uC),
2401 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2402 Out_Present => True)));
2405 Make_Parameter_Specification (Loc,
2406 Defining_Identifier =>
2407 Make_Defining_Identifier (Loc, Name_uF),
2409 New_Reference_To (Standard_Boolean, Loc),
2410 Out_Present => True));
2413 Make_Procedure_Specification (Loc,
2414 Defining_Unit_Name => Def_Id,
2415 Parameter_Specifications => Params);
2416 end Make_Disp_Timed_Select_Spec;
2422 -- The frontend supports two models for expanding dispatch tables
2423 -- associated with library-level defined tagged types: statically
2424 -- and non-statically allocated dispatch tables. In the former case
2425 -- the object containing the dispatch table is constant and it is
2426 -- initialized by means of a positional aggregate. In the latter case,
2427 -- the object containing the dispatch table is a variable which is
2428 -- initialized by means of assignments.
2430 -- In case of locally defined tagged types, the object containing the
2431 -- object containing the dispatch table is always a variable (instead
2432 -- of a constant). This is currently required to give support to late
2433 -- overriding of primitives. For example:
2435 -- procedure Example is
2437 -- type T1 is tagged null record;
2438 -- procedure Prim (O : T1);
2441 -- type T2 is new Pkg.T1 with null record;
2442 -- procedure Prim (X : T2) is -- late overriding
2448 function Make_DT (Typ : Entity_Id; N : Node_Id := Empty) return List_Id is
2449 Loc : constant Source_Ptr := Sloc (Typ);
2451 Max_Predef_Prims : constant Int :=
2455 (Parent (RTE (RE_Max_Predef_Prims)))));
2457 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id);
2458 -- Verify that all non-tagged types in the profile of a subprogram
2459 -- are frozen at the point the subprogram is frozen. This enforces
2460 -- the rule on RM 13.14 (14) as modified by AI05-019. At the point a
2461 -- subprogram is frozen, enough must be known about it to build the
2462 -- activation record for it, which requires at least that the size of
2463 -- all parameters be known. Controlling arguments are by-reference,
2464 -- and therefore the rule only applies to non-tagged types.
2465 -- Typical violation of the rule involves an object declaration that
2466 -- freezes a tagged type, when one of its primitive operations has a
2467 -- type in its profile whose full view has not been analyzed yet.
2469 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id);
2470 -- Export the dispatch table entity DT of tagged type Typ. Required to
2471 -- generate forward references and statically allocate the table.
2473 procedure Make_Secondary_DT
2477 Iface_DT_Ptr : Entity_Id;
2479 -- Ada 2005 (AI-251): Expand the declarations for the Secondary Dispatch
2480 -- Table of Typ associated with Iface (each abstract interface of Typ
2481 -- has a secondary dispatch table). The arguments Typ, Ancestor_Typ
2482 -- and Suffix_Index are used to generate an unique external name which
2483 -- is added at the end of Acc_Disp_Tables; this external name will be
2484 -- used later by the subprogram Exp_Ch3.Build_Init_Procedure.
2486 ------------------------------
2487 -- Check_Premature_Freezing --
2488 ------------------------------
2490 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id) is
2493 and then Is_Private_Type (Typ)
2494 and then No (Full_View (Typ))
2495 and then not Is_Generic_Type (Typ)
2496 and then not Is_Tagged_Type (Typ)
2497 and then not Is_Frozen (Typ)
2499 Error_Msg_Sloc := Sloc (Subp);
2501 ("declaration must appear after completion of type &", N, Typ);
2503 ("\which is an untagged type in the profile of"
2504 & " primitive operation & declared#",
2507 end Check_Premature_Freezing;
2513 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id) is
2515 Set_Is_Statically_Allocated (DT);
2516 Set_Is_True_Constant (DT);
2517 Set_Is_Exported (DT);
2519 pragma Assert (Present (Dispatch_Table_Wrapper (Typ)));
2520 Get_External_Name (Dispatch_Table_Wrapper (Typ), True);
2521 Set_Interface_Name (DT,
2522 Make_String_Literal (Loc,
2523 Strval => String_From_Name_Buffer));
2525 -- Ensure proper Sprint output of this implicit importation
2527 Set_Is_Internal (DT);
2531 -----------------------
2532 -- Make_Secondary_DT --
2533 -----------------------
2535 procedure Make_Secondary_DT
2539 Iface_DT_Ptr : Entity_Id;
2542 Loc : constant Source_Ptr := Sloc (Typ);
2543 Name_DT : constant Name_Id := New_Internal_Name ('T');
2544 Iface_DT : constant Entity_Id :=
2545 Make_Defining_Identifier (Loc, Name_DT);
2546 Name_Predef_Prims : constant Name_Id := New_Internal_Name ('R');
2547 Predef_Prims : constant Entity_Id :=
2548 Make_Defining_Identifier (Loc,
2550 DT_Constr_List : List_Id;
2551 DT_Aggr_List : List_Id;
2552 Empty_DT : Boolean := False;
2553 Nb_Predef_Prims : Nat := 0;
2557 OSD_Aggr_List : List_Id;
2560 Prim_Elmt : Elmt_Id;
2561 Prim_Ops_Aggr_List : List_Id;
2564 -- Handle cases in which we do not generate statically allocated
2567 if not Building_Static_DT (Typ) then
2568 Set_Ekind (Predef_Prims, E_Variable);
2569 Set_Is_Statically_Allocated (Predef_Prims);
2571 Set_Ekind (Iface_DT, E_Variable);
2572 Set_Is_Statically_Allocated (Iface_DT);
2574 -- Statically allocated dispatch tables and related entities are
2578 Set_Ekind (Predef_Prims, E_Constant);
2579 Set_Is_Statically_Allocated (Predef_Prims);
2580 Set_Is_True_Constant (Predef_Prims);
2582 Set_Ekind (Iface_DT, E_Constant);
2583 Set_Is_Statically_Allocated (Iface_DT);
2584 Set_Is_True_Constant (Iface_DT);
2587 -- Generate code to create the storage for the Dispatch_Table object.
2588 -- If the number of primitives of Typ is 0 we reserve a dummy single
2589 -- entry for its DT because at run-time the pointer to this dummy
2590 -- entry will be used as the tag.
2592 Nb_Prim := UI_To_Int (DT_Entry_Count (AI_Tag));
2601 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
2602 -- (predef-prim-op-thunk-1'address,
2603 -- predef-prim-op-thunk-2'address,
2605 -- predef-prim-op-thunk-n'address);
2606 -- for Predef_Prims'Alignment use Address'Alignment
2608 -- Stage 1: Calculate the number of predefined primitives
2610 if not Building_Static_DT (Typ) then
2611 Nb_Predef_Prims := Max_Predef_Prims;
2613 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2614 while Present (Prim_Elmt) loop
2615 Prim := Node (Prim_Elmt);
2617 if Is_Predefined_Dispatching_Operation (Prim)
2618 and then not Is_Abstract_Subprogram (Prim)
2620 Pos := UI_To_Int (DT_Position (Prim));
2622 if Pos > Nb_Predef_Prims then
2623 Nb_Predef_Prims := Pos;
2627 Next_Elmt (Prim_Elmt);
2631 -- Stage 2: Create the thunks associated with the predefined
2632 -- primitives and save their entity to fill the aggregate.
2635 Prim_Table : array (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
2636 Thunk_Id : Entity_Id;
2637 Thunk_Code : Node_Id;
2640 Prim_Ops_Aggr_List := New_List;
2641 Prim_Table := (others => Empty);
2643 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2644 while Present (Prim_Elmt) loop
2645 Prim := Node (Prim_Elmt);
2647 if Is_Predefined_Dispatching_Operation (Prim)
2648 and then not Is_Abstract_Subprogram (Prim)
2649 and then not Present (Prim_Table
2650 (UI_To_Int (DT_Position (Prim))))
2652 while Present (Alias (Prim)) loop
2653 Prim := Alias (Prim);
2656 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
2658 if Present (Thunk_Id) then
2659 Append_To (Result, Thunk_Code);
2660 Prim_Table (UI_To_Int (DT_Position (Prim))) := Thunk_Id;
2664 Next_Elmt (Prim_Elmt);
2667 for J in Prim_Table'Range loop
2668 if Present (Prim_Table (J)) then
2670 Make_Attribute_Reference (Loc,
2671 Prefix => New_Reference_To (Prim_Table (J), Loc),
2672 Attribute_Name => Name_Address);
2675 New_Reference_To (RTE (RE_Null_Address), Loc);
2678 Append_To (Prim_Ops_Aggr_List, New_Node);
2682 Make_Object_Declaration (Loc,
2683 Defining_Identifier => Predef_Prims,
2684 Constant_Present => Building_Static_DT (Typ),
2685 Aliased_Present => True,
2686 Object_Definition =>
2687 New_Reference_To (RTE (RE_Address_Array), Loc),
2688 Expression => Make_Aggregate (Loc,
2689 Expressions => Prim_Ops_Aggr_List)));
2692 Make_Attribute_Definition_Clause (Loc,
2693 Name => New_Reference_To (Predef_Prims, Loc),
2694 Chars => Name_Alignment,
2696 Make_Attribute_Reference (Loc,
2698 New_Reference_To (RTE (RE_Integer_Address), Loc),
2699 Attribute_Name => Name_Alignment)));
2704 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
2705 -- (OSD_Table => (1 => <value>,
2709 -- Iface_DT : Dispatch_Table (Nb_Prims) :=
2710 -- ([ Signature => <sig-value> ],
2711 -- Tag_Kind => <tag_kind-value>,
2712 -- Predef_Prims => Predef_Prims'Address,
2713 -- Offset_To_Top => 0,
2714 -- OSD => OSD'Address,
2715 -- Prims_Ptr => (prim-op-1'address,
2716 -- prim-op-2'address,
2718 -- prim-op-n'address));
2720 -- Stage 3: Initialize the discriminant and the record components
2722 DT_Constr_List := New_List;
2723 DT_Aggr_List := New_List;
2725 -- Nb_Prim. If the tagged type has no primitives we add a dummy
2726 -- slot whose address will be the tag of this type.
2729 New_Node := Make_Integer_Literal (Loc, 1);
2731 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
2734 Append_To (DT_Constr_List, New_Node);
2735 Append_To (DT_Aggr_List, New_Copy (New_Node));
2739 if RTE_Record_Component_Available (RE_Signature) then
2740 Append_To (DT_Aggr_List,
2741 New_Reference_To (RTE (RE_Secondary_DT), Loc));
2746 if RTE_Record_Component_Available (RE_Tag_Kind) then
2747 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
2752 Append_To (DT_Aggr_List,
2753 Make_Attribute_Reference (Loc,
2754 Prefix => New_Reference_To (Predef_Prims, Loc),
2755 Attribute_Name => Name_Address));
2757 -- Note: The correct value of Offset_To_Top will be set by the init
2760 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
2762 -- Generate the Object Specific Data table required to dispatch calls
2763 -- through synchronized interfaces.
2766 or else Is_Abstract_Type (Typ)
2767 or else Is_Controlled (Typ)
2768 or else Restriction_Active (No_Dispatching_Calls)
2769 or else not Is_Limited_Type (Typ)
2770 or else not Has_Abstract_Interfaces (Typ)
2772 -- No OSD table required
2774 Append_To (DT_Aggr_List,
2775 New_Reference_To (RTE (RE_Null_Address), Loc));
2778 OSD_Aggr_List := New_List;
2781 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
2783 Prim_Alias : Entity_Id;
2784 Prim_Elmt : Elmt_Id;
2790 Prim_Table := (others => Empty);
2791 Prim_Alias := Empty;
2793 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2794 while Present (Prim_Elmt) loop
2795 Prim := Node (Prim_Elmt);
2797 if Present (Abstract_Interface_Alias (Prim))
2798 and then Find_Dispatching_Type
2799 (Abstract_Interface_Alias (Prim)) = Iface
2801 Prim_Alias := Abstract_Interface_Alias (Prim);
2804 while Present (Alias (E)) loop
2808 Pos := UI_To_Int (DT_Position (Prim_Alias));
2810 if Present (Prim_Table (Pos)) then
2811 pragma Assert (Prim_Table (Pos) = E);
2815 Prim_Table (Pos) := E;
2817 Append_To (OSD_Aggr_List,
2818 Make_Component_Association (Loc,
2819 Choices => New_List (
2820 Make_Integer_Literal (Loc,
2821 DT_Position (Prim_Alias))),
2823 Make_Integer_Literal (Loc,
2824 DT_Position (Alias (Prim)))));
2830 Next_Elmt (Prim_Elmt);
2832 pragma Assert (Count = Nb_Prim);
2835 OSD := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
2838 Make_Object_Declaration (Loc,
2839 Defining_Identifier => OSD,
2840 Object_Definition =>
2841 Make_Subtype_Indication (Loc,
2843 New_Reference_To (RTE (RE_Object_Specific_Data), Loc),
2845 Make_Index_Or_Discriminant_Constraint (Loc,
2846 Constraints => New_List (
2847 Make_Integer_Literal (Loc, Nb_Prim)))),
2848 Expression => Make_Aggregate (Loc,
2849 Component_Associations => New_List (
2850 Make_Component_Association (Loc,
2851 Choices => New_List (
2853 (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
2855 Make_Integer_Literal (Loc, Nb_Prim)),
2857 Make_Component_Association (Loc,
2858 Choices => New_List (
2860 (RTE_Record_Component (RE_OSD_Table), Loc)),
2861 Expression => Make_Aggregate (Loc,
2862 Component_Associations => OSD_Aggr_List))))));
2865 Make_Attribute_Definition_Clause (Loc,
2866 Name => New_Reference_To (OSD, Loc),
2867 Chars => Name_Alignment,
2869 Make_Attribute_Reference (Loc,
2871 New_Reference_To (RTE (RE_Integer_Address), Loc),
2872 Attribute_Name => Name_Alignment)));
2874 -- In secondary dispatch tables the Typeinfo component contains
2875 -- the address of the Object Specific Data (see a-tags.ads)
2877 Append_To (DT_Aggr_List,
2878 Make_Attribute_Reference (Loc,
2879 Prefix => New_Reference_To (OSD, Loc),
2880 Attribute_Name => Name_Address));
2883 -- Initialize the table of primitive operations
2885 Prim_Ops_Aggr_List := New_List;
2888 Append_To (Prim_Ops_Aggr_List,
2889 New_Reference_To (RTE (RE_Null_Address), Loc));
2891 elsif Is_Abstract_Type (Typ)
2892 or else not Building_Static_DT (Typ)
2894 for J in 1 .. Nb_Prim loop
2895 Append_To (Prim_Ops_Aggr_List,
2896 New_Reference_To (RTE (RE_Null_Address), Loc));
2901 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
2903 Thunk_Code : Node_Id;
2904 Thunk_Id : Entity_Id;
2907 Prim_Table := (others => Empty);
2909 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2910 while Present (Prim_Elmt) loop
2911 Prim := Node (Prim_Elmt);
2913 if not Is_Predefined_Dispatching_Operation (Prim)
2914 and then Present (Abstract_Interface_Alias (Prim))
2915 and then not Is_Abstract_Subprogram (Alias (Prim))
2916 and then not Is_Imported (Alias (Prim))
2917 and then Find_Dispatching_Type
2918 (Abstract_Interface_Alias (Prim)) = Iface
2920 -- Generate the code of the thunk only if the abstract
2921 -- interface type is not an immediate ancestor of
2922 -- Tagged_Type; otherwise the DT associated with the
2923 -- interface is the primary DT.
2925 and then not Is_Parent (Iface, Typ)
2927 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
2929 if Present (Thunk_Id) then
2932 (DT_Position (Abstract_Interface_Alias (Prim)));
2934 Prim_Table (Pos) := Thunk_Id;
2935 Append_To (Result, Thunk_Code);
2939 Next_Elmt (Prim_Elmt);
2942 for J in Prim_Table'Range loop
2943 if Present (Prim_Table (J)) then
2945 Make_Attribute_Reference (Loc,
2946 Prefix => New_Reference_To (Prim_Table (J), Loc),
2947 Attribute_Name => Name_Address);
2950 New_Reference_To (RTE (RE_Null_Address), Loc);
2953 Append_To (Prim_Ops_Aggr_List, New_Node);
2958 Append_To (DT_Aggr_List,
2959 Make_Aggregate (Loc,
2960 Expressions => Prim_Ops_Aggr_List));
2963 Make_Object_Declaration (Loc,
2964 Defining_Identifier => Iface_DT,
2965 Aliased_Present => True,
2966 Object_Definition =>
2967 Make_Subtype_Indication (Loc,
2968 Subtype_Mark => New_Reference_To
2969 (RTE (RE_Dispatch_Table_Wrapper), Loc),
2970 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
2971 Constraints => DT_Constr_List)),
2973 Expression => Make_Aggregate (Loc,
2974 Expressions => DT_Aggr_List)));
2977 Make_Attribute_Definition_Clause (Loc,
2978 Name => New_Reference_To (Iface_DT, Loc),
2979 Chars => Name_Alignment,
2981 Make_Attribute_Reference (Loc,
2983 New_Reference_To (RTE (RE_Integer_Address), Loc),
2984 Attribute_Name => Name_Alignment)));
2986 -- Generate code to create the pointer to the dispatch table
2988 -- Iface_DT_Ptr : Tag := Tag!(DT'Address);
2991 Make_Object_Declaration (Loc,
2992 Defining_Identifier => Iface_DT_Ptr,
2993 Constant_Present => True,
2994 Object_Definition =>
2995 New_Reference_To (RTE (RE_Interface_Tag), Loc),
2997 Unchecked_Convert_To (RTE (RE_Interface_Tag),
2998 Make_Attribute_Reference (Loc,
3000 Make_Selected_Component (Loc,
3001 Prefix => New_Reference_To (Iface_DT, Loc),
3004 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
3005 Attribute_Name => Name_Address))));
3007 end Make_Secondary_DT;
3011 Elab_Code : constant List_Id := New_List;
3012 Result : constant List_Id := New_List;
3013 Tname : constant Name_Id := Chars (Typ);
3015 AI_Ptr_Elmt : Elmt_Id;
3016 AI_Tag_Comp : Elmt_Id;
3017 DT_Aggr_List : List_Id;
3018 DT_Constr_List : List_Id;
3022 Iface_Table_Node : Node_Id;
3023 Name_ITable : Name_Id;
3024 Name_No_Reg : Name_Id;
3025 Nb_Predef_Prims : Nat := 0;
3029 Null_Parent_Tag : Boolean := False;
3030 Num_Ifaces : Nat := 0;
3034 Prim_Elmt : Elmt_Id;
3035 Prim_Ops_Aggr_List : List_Id;
3037 Typ_Comps : Elist_Id;
3038 Typ_Ifaces : Elist_Id;
3039 TSD_Aggr_List : List_Id;
3040 TSD_Tags_List : List_Id;
3042 -- The following name entries are used by Make_DT to generate a number
3043 -- of entities related to a tagged type. These entities may be generated
3044 -- in a scope other than that of the tagged type declaration, and if
3045 -- the entities for two tagged types with the same name happen to be
3046 -- generated in the same scope, we have to take care to use different
3047 -- names. This is achieved by means of a unique serial number appended
3048 -- to each generated entity name.
3050 Name_DT : constant Name_Id :=
3051 New_External_Name (Tname, 'T', Suffix_Index => -1);
3052 Name_Exname : constant Name_Id :=
3053 New_External_Name (Tname, 'E', Suffix_Index => -1);
3054 Name_HT_Link : constant Name_Id :=
3055 New_External_Name (Tname, 'H', Suffix_Index => -1);
3056 Name_Predef_Prims : constant Name_Id :=
3057 New_External_Name (Tname, 'R', Suffix_Index => -1);
3058 Name_SSD : constant Name_Id :=
3059 New_External_Name (Tname, 'S', Suffix_Index => -1);
3060 Name_TSD : constant Name_Id :=
3061 New_External_Name (Tname, 'B', Suffix_Index => -1);
3063 -- Entities built with above names
3065 DT : constant Entity_Id :=
3066 Make_Defining_Identifier (Loc, Name_DT);
3067 Exname : constant Entity_Id :=
3068 Make_Defining_Identifier (Loc, Name_Exname);
3069 HT_Link : constant Entity_Id :=
3070 Make_Defining_Identifier (Loc, Name_HT_Link);
3071 Predef_Prims : constant Entity_Id :=
3072 Make_Defining_Identifier (Loc, Name_Predef_Prims);
3073 SSD : constant Entity_Id :=
3074 Make_Defining_Identifier (Loc, Name_SSD);
3075 TSD : constant Entity_Id :=
3076 Make_Defining_Identifier (Loc, Name_TSD);
3078 -- Start of processing for Make_DT
3081 pragma Assert (Is_Frozen (Typ));
3083 -- Handle cases in which there is no need to build the dispatch table
3085 if Has_Dispatch_Table (Typ)
3086 or else No (Access_Disp_Table (Typ))
3087 or else Is_CPP_Class (Typ)
3091 elsif No_Run_Time_Mode then
3092 Error_Msg_CRT ("tagged types", Typ);
3095 elsif not RTE_Available (RE_Tag) then
3097 Make_Object_Declaration (Loc,
3098 Defining_Identifier => Node (First_Elmt
3099 (Access_Disp_Table (Typ))),
3100 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
3101 Constant_Present => True,
3103 Unchecked_Convert_To (RTE (RE_Tag),
3104 New_Reference_To (RTE (RE_Null_Address), Loc))));
3106 Analyze_List (Result, Suppress => All_Checks);
3107 Error_Msg_CRT ("tagged types", Typ);
3111 -- Ensure that the value of Max_Predef_Prims defined in a-tags is
3112 -- correct. Valid values are 10 under configurable runtime or 15
3113 -- with full runtime.
3115 if RTE_Available (RE_Interface_Data) then
3116 if Max_Predef_Prims /= 15 then
3117 Error_Msg_N ("run-time library configuration error", Typ);
3121 if Max_Predef_Prims /= 10 then
3122 Error_Msg_N ("run-time library configuration error", Typ);
3123 Error_Msg_CRT ("tagged types", Typ);
3128 -- Ensure that all the primitives are frozen. This is only required when
3129 -- building static dispatch tables --- the primitives must be frozen to
3130 -- be referenced (otherwise we have problems with the backend). It is
3131 -- not a requirement with nonstatic dispatch tables because in this case
3132 -- we generate now an empty dispatch table; the extra code required to
3133 -- register the primitives in the slots will be generated later --- when
3134 -- each primitive is frozen (see Freeze_Subprogram).
3136 if Building_Static_DT (Typ)
3137 and then not Is_CPP_Class (Typ)
3140 Save : constant Boolean := Freezing_Library_Level_Tagged_Type;
3141 Prim_Elmt : Elmt_Id;
3145 Freezing_Library_Level_Tagged_Type := True;
3146 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3147 while Present (Prim_Elmt) loop
3148 Frnodes := Freeze_Entity (Node (Prim_Elmt), Loc);
3151 Subp : constant Entity_Id := Node (Prim_Elmt);
3155 F := First_Formal (Subp);
3156 while Present (F) loop
3157 Check_Premature_Freezing (Subp, Etype (F));
3161 Check_Premature_Freezing (Subp, Etype (Subp));
3164 if Present (Frnodes) then
3165 Append_List_To (Result, Frnodes);
3168 Next_Elmt (Prim_Elmt);
3170 Freezing_Library_Level_Tagged_Type := Save;
3174 -- Ada 2005 (AI-251): Build the secondary dispatch tables
3176 if Has_Abstract_Interfaces (Typ) then
3177 Collect_Interface_Components (Typ, Typ_Comps);
3180 AI_Ptr_Elmt := Next_Elmt (First_Elmt (Access_Disp_Table (Typ)));
3182 AI_Tag_Comp := First_Elmt (Typ_Comps);
3183 while Present (AI_Tag_Comp) loop
3187 (Related_Interface (Node (AI_Tag_Comp))),
3188 AI_Tag => Node (AI_Tag_Comp),
3189 Iface_DT_Ptr => Node (AI_Ptr_Elmt),
3192 Suffix_Index := Suffix_Index + 1;
3193 Next_Elmt (AI_Ptr_Elmt);
3194 Next_Elmt (AI_Tag_Comp);
3198 -- Get the _tag entity and the number of primitives of its dispatch
3201 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
3202 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
3204 Set_Is_Statically_Allocated (DT);
3205 Set_Is_Statically_Allocated (SSD);
3206 Set_Is_Statically_Allocated (TSD);
3207 Set_Is_Statically_Allocated (Predef_Prims);
3209 -- Generate code to define the boolean that controls registration, in
3210 -- order to avoid multiple registrations for tagged types defined in
3211 -- multiple-called scopes.
3213 if not Is_Interface (Typ) then
3214 Name_No_Reg := New_External_Name (Tname, 'F', Suffix_Index => -1);
3215 No_Reg := Make_Defining_Identifier (Loc, Name_No_Reg);
3217 Set_Ekind (No_Reg, E_Variable);
3218 Set_Is_Statically_Allocated (No_Reg);
3221 Make_Object_Declaration (Loc,
3222 Defining_Identifier => No_Reg,
3223 Object_Definition => New_Reference_To (Standard_Boolean, Loc),
3224 Expression => New_Reference_To (Standard_True, Loc)));
3227 -- In case of locally defined tagged type we declare the object
3228 -- contanining the dispatch table by means of a variable. Its
3229 -- initialization is done later by means of an assignment. This is
3230 -- required to generate its External_Tag.
3232 if not Building_Static_DT (Typ) then
3235 -- DT : No_Dispatch_Table_Wrapper;
3236 -- for DT'Alignment use Address'Alignment;
3237 -- DT_Ptr : Tag := !Tag (DT.NDT_Prims_Ptr'Address);
3239 if not Has_DT (Typ) then
3241 Make_Object_Declaration (Loc,
3242 Defining_Identifier => DT,
3243 Aliased_Present => True,
3244 Constant_Present => False,
3245 Object_Definition =>
3247 (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
3250 Make_Attribute_Definition_Clause (Loc,
3251 Name => New_Reference_To (DT, Loc),
3252 Chars => Name_Alignment,
3254 Make_Attribute_Reference (Loc,
3256 New_Reference_To (RTE (RE_Integer_Address), Loc),
3257 Attribute_Name => Name_Alignment)));
3260 Make_Object_Declaration (Loc,
3261 Defining_Identifier => DT_Ptr,
3262 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
3263 Constant_Present => True,
3265 Unchecked_Convert_To (RTE (RE_Tag),
3266 Make_Attribute_Reference (Loc,
3268 Make_Selected_Component (Loc,
3269 Prefix => New_Reference_To (DT, Loc),
3272 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
3273 Attribute_Name => Name_Address))));
3276 -- DT : Dispatch_Table_Wrapper (Nb_Prim);
3277 -- for DT'Alignment use Address'Alignment;
3278 -- DT_Ptr : Tag := !Tag (DT.Prims_Ptr'Address);
3281 -- If the tagged type has no primitives we add a dummy slot
3282 -- whose address will be the tag of this type.
3286 New_List (Make_Integer_Literal (Loc, 1));
3289 New_List (Make_Integer_Literal (Loc, Nb_Prim));
3293 Make_Object_Declaration (Loc,
3294 Defining_Identifier => DT,
3295 Aliased_Present => True,
3296 Constant_Present => False,
3297 Object_Definition =>
3298 Make_Subtype_Indication (Loc,
3300 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
3301 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
3302 Constraints => DT_Constr_List))));
3305 Make_Attribute_Definition_Clause (Loc,
3306 Name => New_Reference_To (DT, Loc),
3307 Chars => Name_Alignment,
3309 Make_Attribute_Reference (Loc,
3311 New_Reference_To (RTE (RE_Integer_Address), Loc),
3312 Attribute_Name => Name_Alignment)));
3315 Make_Object_Declaration (Loc,
3316 Defining_Identifier => DT_Ptr,
3317 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
3318 Constant_Present => True,
3320 Unchecked_Convert_To (RTE (RE_Tag),
3321 Make_Attribute_Reference (Loc,
3323 Make_Selected_Component (Loc,
3324 Prefix => New_Reference_To (DT, Loc),
3327 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
3328 Attribute_Name => Name_Address))));
3332 -- Generate: Exname : constant String := full_qualified_name (typ);
3333 -- The type itself may be an anonymous parent type, so use the first
3334 -- subtype to have a user-recognizable name.
3337 Make_Object_Declaration (Loc,
3338 Defining_Identifier => Exname,
3339 Constant_Present => True,
3340 Object_Definition => New_Reference_To (Standard_String, Loc),
3342 Make_String_Literal (Loc,
3343 Full_Qualified_Name (First_Subtype (Typ)))));
3345 Set_Is_Statically_Allocated (Exname);
3346 Set_Is_True_Constant (Exname);
3348 -- Declare the object used by Ada.Tags.Register_Tag
3350 if RTE_Available (RE_Register_Tag) then
3352 Make_Object_Declaration (Loc,
3353 Defining_Identifier => HT_Link,
3354 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc)));
3357 -- Generate code to create the storage for the type specific data object
3358 -- with enough space to store the tags of the ancestors plus the tags
3359 -- of all the implemented interfaces (as described in a-tags.adb).
3361 -- TSD : Type_Specific_Data (I_Depth) :=
3362 -- (Idepth => I_Depth,
3363 -- Access_Level => Type_Access_Level (Typ),
3364 -- Expanded_Name => Cstring_Ptr!(Exname'Address))
3365 -- External_Tag => Cstring_Ptr!(Exname'Address))
3366 -- HT_Link => HT_Link'Address,
3367 -- Transportable => <<boolean-value>>,
3368 -- RC_Offset => <<integer-value>>,
3369 -- [ Interfaces_Table => <<access-value>> ]
3370 -- [ SSD => SSD_Table'Address ]
3371 -- Tags_Table => (0 => null,
3374 -- for TSD'Alignment use Address'Alignment
3376 TSD_Aggr_List := New_List;
3378 -- Idepth: Count ancestors to compute the inheritance depth. For private
3379 -- extensions, always go to the full view in order to compute the real
3380 -- inheritance depth.
3383 Current_Typ : Entity_Id;
3384 Parent_Typ : Entity_Id;
3390 Parent_Typ := Etype (Current_Typ);
3392 if Is_Private_Type (Parent_Typ) then
3393 Parent_Typ := Full_View (Base_Type (Parent_Typ));
3396 exit when Parent_Typ = Current_Typ;
3398 I_Depth := I_Depth + 1;
3399 Current_Typ := Parent_Typ;
3403 Append_To (TSD_Aggr_List,
3404 Make_Integer_Literal (Loc, I_Depth));
3408 Append_To (TSD_Aggr_List,
3409 Make_Integer_Literal (Loc, Type_Access_Level (Typ)));
3413 Append_To (TSD_Aggr_List,
3414 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
3415 Make_Attribute_Reference (Loc,
3416 Prefix => New_Reference_To (Exname, Loc),
3417 Attribute_Name => Name_Address)));
3419 -- External_Tag of a local tagged type
3421 -- <typ>A : constant String :=
3422 -- "Internal tag at 16#tag-addr#: <full-name-of-typ>";
3424 -- The reason we generate this strange name is that we do not want to
3425 -- enter local tagged types in the global hash table used to compute
3426 -- the Internal_Tag attribute for two reasons:
3428 -- 1. It is hard to avoid a tasking race condition for entering the
3429 -- entry into the hash table.
3431 -- 2. It would cause a storage leak, unless we rig up considerable
3432 -- mechanism to remove the entry from the hash table on exit.
3434 -- So what we do is to generate the above external tag name, where the
3435 -- hex address is the address of the local dispatch table (i.e. exactly
3436 -- the value we want if Internal_Tag is computed from this string).
3438 -- Of course this value will only be valid if the tagged type is still
3439 -- in scope, but it clearly must be erroneous to compute the internal
3440 -- tag of a tagged type that is out of scope!
3442 -- We don't do this processing if an explicit external tag has been
3443 -- specified. That's an odd case for which we have already issued a
3444 -- warning, where we will not be able to compute the internal tag.
3446 if not Is_Library_Level_Entity (Typ)
3447 and then not Has_External_Tag_Rep_Clause (Typ)
3450 Exname : constant Entity_Id :=
3451 Make_Defining_Identifier (Loc,
3452 New_External_Name (Tname, 'A'));
3454 Full_Name : constant String_Id :=
3455 Full_Qualified_Name (First_Subtype (Typ));
3456 Str1_Id : String_Id;
3457 Str2_Id : String_Id;
3461 -- Str1 = "Internal tag at 16#";
3464 Store_String_Chars ("Internal tag at 16#");
3465 Str1_Id := End_String;
3468 -- Str2 = "#: <type-full-name>";
3471 Store_String_Chars ("#: ");
3472 Store_String_Chars (Full_Name);
3473 Str2_Id := End_String;
3476 -- Exname : constant String :=
3477 -- Str1 & Address_Image (Tag) & Str2;
3479 if RTE_Available (RE_Address_Image) then
3481 Make_Object_Declaration (Loc,
3482 Defining_Identifier => Exname,
3483 Constant_Present => True,
3484 Object_Definition => New_Reference_To
3485 (Standard_String, Loc),
3487 Make_Op_Concat (Loc,
3489 Make_String_Literal (Loc, Str1_Id),
3491 Make_Op_Concat (Loc,
3493 Make_Function_Call (Loc,
3496 (RTE (RE_Address_Image), Loc),
3497 Parameter_Associations => New_List (
3498 Unchecked_Convert_To (RTE (RE_Address),
3499 New_Reference_To (DT_Ptr, Loc)))),
3501 Make_String_Literal (Loc, Str2_Id)))));
3505 Make_Object_Declaration (Loc,
3506 Defining_Identifier => Exname,
3507 Constant_Present => True,
3508 Object_Definition => New_Reference_To
3509 (Standard_String, Loc),
3511 Make_Op_Concat (Loc,
3513 Make_String_Literal (Loc, Str1_Id),
3515 Make_String_Literal (Loc, Str2_Id))));
3519 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
3520 Make_Attribute_Reference (Loc,
3521 Prefix => New_Reference_To (Exname, Loc),
3522 Attribute_Name => Name_Address));
3525 -- External tag of a library-level tagged type: Check for a definition
3526 -- of External_Tag. The clause is considered only if it applies to this
3527 -- specific tagged type, as opposed to one of its ancestors.
3531 Def : constant Node_Id := Get_Attribute_Definition_Clause (Typ,
3532 Attribute_External_Tag);
3533 Old_Val : String_Id;
3534 New_Val : String_Id;
3538 if not Present (Def)
3539 or else Entity (Name (Def)) /= Typ
3542 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
3543 Make_Attribute_Reference (Loc,
3544 Prefix => New_Reference_To (Exname, Loc),
3545 Attribute_Name => Name_Address));
3547 Old_Val := Strval (Expr_Value_S (Expression (Def)));
3549 -- For the rep clause "for <typ>'external_tag use y" generate:
3551 -- <typ>A : constant string := y;
3553 -- <typ>A'Address is used to set the External_Tag component
3556 -- Create a new nul terminated string if it is not already
3558 if String_Length (Old_Val) > 0
3560 Get_String_Char (Old_Val, String_Length (Old_Val)) = 0
3564 Start_String (Old_Val);
3565 Store_String_Char (Get_Char_Code (ASCII.NUL));
3566 New_Val := End_String;
3569 E := Make_Defining_Identifier (Loc,
3570 New_External_Name (Chars (Typ), 'A'));
3573 Make_Object_Declaration (Loc,
3574 Defining_Identifier => E,
3575 Constant_Present => True,
3576 Object_Definition =>
3577 New_Reference_To (Standard_String, Loc),
3579 Make_String_Literal (Loc, New_Val)));
3582 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
3583 Make_Attribute_Reference (Loc,
3584 Prefix => New_Reference_To (E, Loc),
3585 Attribute_Name => Name_Address));
3590 Append_To (TSD_Aggr_List, New_Node);
3594 if RTE_Available (RE_Register_Tag) then
3595 Append_To (TSD_Aggr_List,
3596 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
3597 Make_Attribute_Reference (Loc,
3598 Prefix => New_Reference_To (HT_Link, Loc),
3599 Attribute_Name => Name_Address)));
3601 Append_To (TSD_Aggr_List,
3602 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
3603 New_Reference_To (RTE (RE_Null_Address), Loc)));
3606 -- Transportable: Set for types that can be used in remote calls
3607 -- with respect to E.4(18) legality rules.
3610 Transportable : Entity_Id;
3616 or else Is_Shared_Passive (Typ)
3618 ((Is_Remote_Types (Typ)
3619 or else Is_Remote_Call_Interface (Typ))
3620 and then Original_View_In_Visible_Part (Typ))
3621 or else not Comes_From_Source (Typ));
3623 Append_To (TSD_Aggr_List,
3624 New_Occurrence_Of (Transportable, Loc));
3627 -- RC_Offset: These are the valid values and their meaning:
3629 -- >0: For simple types with controlled components is
3630 -- type._record_controller'position
3632 -- 0: For types with no controlled components
3634 -- -1: For complex types with controlled components where the position
3635 -- of the record controller is not statically computable but there
3636 -- are controlled components at this level. The _Controller field
3637 -- is available right after the _parent.
3639 -- -2: There are no controlled components at this level. We need to
3640 -- get the position from the parent.
3643 RC_Offset_Node : Node_Id;
3646 if not Has_Controlled_Component (Typ) then
3647 RC_Offset_Node := Make_Integer_Literal (Loc, 0);
3649 elsif Etype (Typ) /= Typ
3650 and then Has_Discriminants (Etype (Typ))
3652 if Has_New_Controlled_Component (Typ) then
3653 RC_Offset_Node := Make_Integer_Literal (Loc, -1);
3655 RC_Offset_Node := Make_Integer_Literal (Loc, -2);
3659 Make_Attribute_Reference (Loc,
3661 Make_Selected_Component (Loc,
3662 Prefix => New_Reference_To (Typ, Loc),
3664 New_Reference_To (Controller_Component (Typ), Loc)),
3665 Attribute_Name => Name_Position);
3667 -- This is not proper Ada code to use the attribute 'Position
3668 -- on something else than an object but this is supported by
3669 -- the back end (see comment on the Bit_Component attribute in
3670 -- sem_attr). So we avoid semantic checking here.
3672 -- Is this documented in sinfo.ads??? it should be!
3674 Set_Analyzed (RC_Offset_Node);
3675 Set_Etype (Prefix (RC_Offset_Node), RTE (RE_Record_Controller));
3676 Set_Etype (Prefix (Prefix (RC_Offset_Node)), Typ);
3677 Set_Etype (Selector_Name (Prefix (RC_Offset_Node)),
3678 RTE (RE_Record_Controller));
3679 Set_Etype (RC_Offset_Node, RTE (RE_Storage_Offset));
3682 Append_To (TSD_Aggr_List, RC_Offset_Node);
3685 -- Interfaces_Table (required for AI-405)
3687 if RTE_Record_Component_Available (RE_Interfaces_Table) then
3689 -- Count the number of interface types implemented by Typ
3691 Collect_Abstract_Interfaces (Typ, Typ_Ifaces);
3693 AI := First_Elmt (Typ_Ifaces);
3694 while Present (AI) loop
3695 Num_Ifaces := Num_Ifaces + 1;
3699 if Num_Ifaces = 0 then
3700 Iface_Table_Node := Make_Null (Loc);
3702 -- Generate the Interface_Table object
3706 TSD_Ifaces_List : constant List_Id := New_List;
3709 AI := First_Elmt (Typ_Ifaces);
3710 while Present (AI) loop
3711 Append_To (TSD_Ifaces_List,
3712 Make_Aggregate (Loc,
3713 Expressions => New_List (
3717 Unchecked_Convert_To (RTE (RE_Tag),
3719 (Node (First_Elmt (Access_Disp_Table (Node (AI)))),
3722 -- Static_Offset_To_Top
3724 New_Reference_To (Standard_True, Loc),
3726 -- Offset_To_Top_Value
3728 Make_Integer_Literal (Loc, 0),
3730 -- Offset_To_Top_Func
3737 Name_ITable := New_External_Name (Tname, 'I');
3738 ITable := Make_Defining_Identifier (Loc, Name_ITable);
3739 Set_Is_Statically_Allocated (ITable);
3741 -- The table of interfaces is not constant; its slots are
3742 -- filled at run-time by the IP routine using attribute
3743 -- 'Position to know the location of the tag components
3744 -- (and this attribute cannot be safely used before the
3745 -- object is initialized).
3748 Make_Object_Declaration (Loc,
3749 Defining_Identifier => ITable,
3750 Aliased_Present => True,
3751 Constant_Present => False,
3752 Object_Definition =>
3753 Make_Subtype_Indication (Loc,
3755 New_Reference_To (RTE (RE_Interface_Data), Loc),
3756 Constraint => Make_Index_Or_Discriminant_Constraint
3758 Constraints => New_List (
3759 Make_Integer_Literal (Loc, Num_Ifaces)))),
3761 Expression => Make_Aggregate (Loc,
3762 Expressions => New_List (
3763 Make_Integer_Literal (Loc, Num_Ifaces),
3764 Make_Aggregate (Loc,
3765 Expressions => TSD_Ifaces_List)))));
3768 Make_Attribute_Definition_Clause (Loc,
3769 Name => New_Reference_To (ITable, Loc),
3770 Chars => Name_Alignment,
3772 Make_Attribute_Reference (Loc,
3774 New_Reference_To (RTE (RE_Integer_Address), Loc),
3775 Attribute_Name => Name_Alignment)));
3778 Make_Attribute_Reference (Loc,
3779 Prefix => New_Reference_To (ITable, Loc),
3780 Attribute_Name => Name_Unchecked_Access);
3784 Append_To (TSD_Aggr_List, Iface_Table_Node);
3787 -- Generate the Select Specific Data table for synchronized types that
3788 -- implement synchronized interfaces. The size of the table is
3789 -- constrained by the number of non-predefined primitive operations.
3791 if RTE_Record_Component_Available (RE_SSD) then
3792 if Ada_Version >= Ada_05
3793 and then Has_DT (Typ)
3794 and then Is_Concurrent_Record_Type (Typ)
3795 and then Has_Abstract_Interfaces (Typ)
3796 and then Nb_Prim > 0
3797 and then not Is_Abstract_Type (Typ)
3798 and then not Is_Controlled (Typ)
3799 and then not Restriction_Active (No_Dispatching_Calls)
3802 Make_Object_Declaration (Loc,
3803 Defining_Identifier => SSD,
3804 Aliased_Present => True,
3805 Object_Definition =>
3806 Make_Subtype_Indication (Loc,
3807 Subtype_Mark => New_Reference_To (
3808 RTE (RE_Select_Specific_Data), Loc),
3810 Make_Index_Or_Discriminant_Constraint (Loc,
3811 Constraints => New_List (
3812 Make_Integer_Literal (Loc, Nb_Prim))))));
3815 Make_Attribute_Definition_Clause (Loc,
3816 Name => New_Reference_To (SSD, Loc),
3817 Chars => Name_Alignment,
3819 Make_Attribute_Reference (Loc,
3821 New_Reference_To (RTE (RE_Integer_Address), Loc),
3822 Attribute_Name => Name_Alignment)));
3824 -- This table is initialized by Make_Select_Specific_Data_Table,
3825 -- which calls Set_Entry_Index and Set_Prim_Op_Kind.
3827 Append_To (TSD_Aggr_List,
3828 Make_Attribute_Reference (Loc,
3829 Prefix => New_Reference_To (SSD, Loc),
3830 Attribute_Name => Name_Unchecked_Access));
3832 Append_To (TSD_Aggr_List, Make_Null (Loc));
3836 -- Initialize the table of ancestor tags. In case of interface types
3837 -- this table is not needed.
3840 Current_Typ : Entity_Id;
3841 Parent_Typ : Entity_Id;
3845 TSD_Tags_List := New_List;
3847 -- If we are not statically allocating the dispatch table then we
3848 -- must fill position 0 with null because we still have not
3849 -- generated the tag of Typ.
3851 if not Building_Static_DT (Typ)
3852 or else Is_Interface (Typ)
3854 Append_To (TSD_Tags_List,
3855 Unchecked_Convert_To (RTE (RE_Tag),
3856 New_Reference_To (RTE (RE_Null_Address), Loc)));
3858 -- Otherwise we can safely reference the tag.
3861 Append_To (TSD_Tags_List,
3862 New_Reference_To (DT_Ptr, Loc));
3865 -- Fill the rest of the table with the tags of the ancestors
3871 Parent_Typ := Etype (Current_Typ);
3873 if Is_Private_Type (Parent_Typ) then
3874 Parent_Typ := Full_View (Base_Type (Parent_Typ));
3877 exit when Parent_Typ = Current_Typ;
3879 if Is_CPP_Class (Parent_Typ)
3880 or else Is_Interface (Typ)
3882 -- The tags defined in the C++ side will be inherited when
3883 -- the object is constructed (Exp_Ch3.Build_Init_Procedure)
3885 Append_To (TSD_Tags_List,
3886 Unchecked_Convert_To (RTE (RE_Tag),
3887 New_Reference_To (RTE (RE_Null_Address), Loc)));
3889 Append_To (TSD_Tags_List,
3891 (Node (First_Elmt (Access_Disp_Table (Parent_Typ))),
3896 Current_Typ := Parent_Typ;
3899 pragma Assert (Pos = I_Depth + 1);
3902 Append_To (TSD_Aggr_List,
3903 Make_Aggregate (Loc,
3904 Expressions => TSD_Tags_List));
3906 -- Build the TSD object
3909 Make_Object_Declaration (Loc,
3910 Defining_Identifier => TSD,
3911 Aliased_Present => True,
3912 Constant_Present => Building_Static_DT (Typ),
3913 Object_Definition =>
3914 Make_Subtype_Indication (Loc,
3915 Subtype_Mark => New_Reference_To (
3916 RTE (RE_Type_Specific_Data), Loc),
3918 Make_Index_Or_Discriminant_Constraint (Loc,
3919 Constraints => New_List (
3920 Make_Integer_Literal (Loc, I_Depth)))),
3922 Expression => Make_Aggregate (Loc,
3923 Expressions => TSD_Aggr_List)));
3925 Set_Is_True_Constant (TSD, Building_Static_DT (Typ));
3928 Make_Attribute_Definition_Clause (Loc,
3929 Name => New_Reference_To (TSD, Loc),
3930 Chars => Name_Alignment,
3932 Make_Attribute_Reference (Loc,
3933 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
3934 Attribute_Name => Name_Alignment)));
3936 -- Initialize or declare the dispatch table object
3938 if not Has_DT (Typ) then
3939 DT_Constr_List := New_List;
3940 DT_Aggr_List := New_List;
3945 Make_Attribute_Reference (Loc,
3946 Prefix => New_Reference_To (TSD, Loc),
3947 Attribute_Name => Name_Address);
3949 Append_To (DT_Constr_List, New_Node);
3950 Append_To (DT_Aggr_List, New_Copy (New_Node));
3951 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
3953 -- In case of locally defined tagged types we have already declared
3954 -- and uninitialized object for the dispatch table, which is now
3955 -- initialized by means of the following assignment:
3957 -- DT := (TSD'Address, 0);
3959 if not Building_Static_DT (Typ) then
3961 Make_Assignment_Statement (Loc,
3962 Name => New_Reference_To (DT, Loc),
3963 Expression => Make_Aggregate (Loc,
3964 Expressions => DT_Aggr_List)));
3966 -- In case of library level tagged types we declare and export now
3967 -- the constant object containing the dummy dispatch table. There
3968 -- is no need to declare the tag here because it has been previously
3969 -- declared by Make_Tags
3971 -- DT : aliased constant No_Dispatch_Table :=
3972 -- (NDT_TSD => TSD'Address;
3973 -- NDT_Prims_Ptr => 0);
3974 -- for DT'Alignment use Address'Alignment;
3978 Make_Object_Declaration (Loc,
3979 Defining_Identifier => DT,
3980 Aliased_Present => True,
3981 Constant_Present => True,
3982 Object_Definition =>
3983 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc),
3984 Expression => Make_Aggregate (Loc,
3985 Expressions => DT_Aggr_List)));
3988 Make_Attribute_Definition_Clause (Loc,
3989 Name => New_Reference_To (DT, Loc),
3990 Chars => Name_Alignment,
3992 Make_Attribute_Reference (Loc,
3994 New_Reference_To (RTE (RE_Integer_Address), Loc),
3995 Attribute_Name => Name_Alignment)));
3997 Export_DT (Typ, DT);
4000 -- Common case: Typ has a dispatch table
4004 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
4005 -- (predef-prim-op-1'address,
4006 -- predef-prim-op-2'address,
4008 -- predef-prim-op-n'address);
4009 -- for Predef_Prims'Alignment use Address'Alignment
4011 -- DT : Dispatch_Table (Nb_Prims) :=
4012 -- (Signature => <sig-value>,
4013 -- Tag_Kind => <tag_kind-value>,
4014 -- Predef_Prims => Predef_Prims'First'Address,
4015 -- Offset_To_Top => 0,
4016 -- TSD => TSD'Address;
4017 -- Prims_Ptr => (prim-op-1'address,
4018 -- prim-op-2'address,
4020 -- prim-op-n'address));
4021 -- for DT'Alignment use Address'Alignment
4028 if not Building_Static_DT (Typ) then
4029 Nb_Predef_Prims := Max_Predef_Prims;
4032 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4033 while Present (Prim_Elmt) loop
4034 Prim := Node (Prim_Elmt);
4036 if Is_Predefined_Dispatching_Operation (Prim)
4037 and then not Is_Abstract_Subprogram (Prim)
4039 Pos := UI_To_Int (DT_Position (Prim));
4041 if Pos > Nb_Predef_Prims then
4042 Nb_Predef_Prims := Pos;
4046 Next_Elmt (Prim_Elmt);
4052 (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
4056 Prim_Ops_Aggr_List := New_List;
4058 Prim_Table := (others => Empty);
4060 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4061 while Present (Prim_Elmt) loop
4062 Prim := Node (Prim_Elmt);
4064 if Building_Static_DT (Typ)
4065 and then Is_Predefined_Dispatching_Operation (Prim)
4066 and then not Is_Abstract_Subprogram (Prim)
4067 and then not Present (Prim_Table
4068 (UI_To_Int (DT_Position (Prim))))
4071 while Present (Alias (E)) loop
4075 pragma Assert (not Is_Abstract_Subprogram (E));
4076 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
4079 Next_Elmt (Prim_Elmt);
4082 for J in Prim_Table'Range loop
4083 if Present (Prim_Table (J)) then
4085 Make_Attribute_Reference (Loc,
4086 Prefix => New_Reference_To (Prim_Table (J), Loc),
4087 Attribute_Name => Name_Address);
4089 New_Node := New_Reference_To (RTE (RE_Null_Address), Loc);
4092 Append_To (Prim_Ops_Aggr_List, New_Node);
4096 Make_Object_Declaration (Loc,
4097 Defining_Identifier => Predef_Prims,
4098 Aliased_Present => True,
4099 Constant_Present => Building_Static_DT (Typ),
4100 Object_Definition =>
4101 New_Reference_To (RTE (RE_Address_Array), Loc),
4102 Expression => Make_Aggregate (Loc,
4103 Expressions => Prim_Ops_Aggr_List)));
4106 Make_Attribute_Definition_Clause (Loc,
4107 Name => New_Reference_To (Predef_Prims, Loc),
4108 Chars => Name_Alignment,
4110 Make_Attribute_Reference (Loc,
4112 New_Reference_To (RTE (RE_Integer_Address), Loc),
4113 Attribute_Name => Name_Alignment)));
4117 -- Stage 1: Initialize the discriminant and the record components
4119 DT_Constr_List := New_List;
4120 DT_Aggr_List := New_List;
4122 -- Num_Prims. If the tagged type has no primitives we add a dummy
4123 -- slot whose address will be the tag of this type.
4126 New_Node := Make_Integer_Literal (Loc, 1);
4128 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
4131 Append_To (DT_Constr_List, New_Node);
4132 Append_To (DT_Aggr_List, New_Copy (New_Node));
4136 if RTE_Record_Component_Available (RE_Signature) then
4137 Append_To (DT_Aggr_List,
4138 New_Reference_To (RTE (RE_Primary_DT), Loc));
4143 if RTE_Record_Component_Available (RE_Tag_Kind) then
4144 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
4149 Append_To (DT_Aggr_List,
4150 Make_Attribute_Reference (Loc,
4151 Prefix => New_Reference_To (Predef_Prims, Loc),
4152 Attribute_Name => Name_Address));
4156 if RTE_Record_Component_Available (RE_Offset_To_Top) then
4157 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
4162 Append_To (DT_Aggr_List,
4163 Make_Attribute_Reference (Loc,
4164 Prefix => New_Reference_To (TSD, Loc),
4165 Attribute_Name => Name_Address));
4167 -- Stage 2: Initialize the table of primitive operations
4169 Prim_Ops_Aggr_List := New_List;
4172 Append_To (Prim_Ops_Aggr_List,
4173 New_Reference_To (RTE (RE_Null_Address), Loc));
4175 elsif not Building_Static_DT (Typ) then
4176 for J in 1 .. Nb_Prim loop
4177 Append_To (Prim_Ops_Aggr_List,
4178 New_Reference_To (RTE (RE_Null_Address), Loc));
4183 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
4186 Prim_Elmt : Elmt_Id;
4189 Prim_Table := (others => Empty);
4190 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4191 while Present (Prim_Elmt) loop
4192 Prim := Node (Prim_Elmt);
4194 if Is_Imported (Prim)
4195 or else Present (Abstract_Interface_Alias (Prim))
4196 or else Is_Predefined_Dispatching_Operation (Prim)
4201 -- Traverse the list of aliased entities to handle
4202 -- renamings of predefined primitives.
4205 while Present (Alias (E)) loop
4209 if not Is_Predefined_Dispatching_Operation (E)
4210 and then not Is_Abstract_Subprogram (E)
4211 and then not Present (Abstract_Interface_Alias (E))
4214 (UI_To_Int (DT_Position (Prim)) <= Nb_Prim);
4216 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
4220 Next_Elmt (Prim_Elmt);
4223 for J in Prim_Table'Range loop
4224 if Present (Prim_Table (J)) then
4226 Make_Attribute_Reference (Loc,
4227 Prefix => New_Reference_To (Prim_Table (J), Loc),
4228 Attribute_Name => Name_Address);
4230 New_Node := New_Reference_To (RTE (RE_Null_Address), Loc);
4233 Append_To (Prim_Ops_Aggr_List, New_Node);
4238 Append_To (DT_Aggr_List,
4239 Make_Aggregate (Loc,
4240 Expressions => Prim_Ops_Aggr_List));
4242 -- In case of locally defined tagged types we have already declared
4243 -- and uninitialized object for the dispatch table, which is now
4244 -- initialized by means of an assignment.
4246 if not Building_Static_DT (Typ) then
4248 Make_Assignment_Statement (Loc,
4249 Name => New_Reference_To (DT, Loc),
4250 Expression => Make_Aggregate (Loc,
4251 Expressions => DT_Aggr_List)));
4253 -- In case of library level tagged types we declare now and export
4254 -- the constant object containing the dispatch table.
4258 Make_Object_Declaration (Loc,
4259 Defining_Identifier => DT,
4260 Aliased_Present => True,
4261 Constant_Present => True,
4262 Object_Definition =>
4263 Make_Subtype_Indication (Loc,
4264 Subtype_Mark => New_Reference_To
4265 (RTE (RE_Dispatch_Table_Wrapper), Loc),
4266 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4267 Constraints => DT_Constr_List)),
4268 Expression => Make_Aggregate (Loc,
4269 Expressions => DT_Aggr_List)));
4272 Make_Attribute_Definition_Clause (Loc,
4273 Name => New_Reference_To (DT, Loc),
4274 Chars => Name_Alignment,
4276 Make_Attribute_Reference (Loc,
4278 New_Reference_To (RTE (RE_Integer_Address), Loc),
4279 Attribute_Name => Name_Alignment)));
4281 Export_DT (Typ, DT);
4285 -- Initialize the table of ancestor tags
4287 if not Building_Static_DT (Typ)
4288 and then not Is_Interface (Typ)
4289 and then not Is_CPP_Class (Typ)
4292 Make_Assignment_Statement (Loc,
4294 Make_Indexed_Component (Loc,
4296 Make_Selected_Component (Loc,
4298 New_Reference_To (TSD, Loc),
4301 (RTE_Record_Component (RE_Tags_Table), Loc)),
4303 New_List (Make_Integer_Literal (Loc, 0))),
4307 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)));
4310 if Building_Static_DT (Typ) then
4313 -- If the ancestor is a CPP_Class type we inherit the dispatch tables
4314 -- in the init proc, and we don't need to fill them in here.
4316 elsif Is_CPP_Class (Etype (Typ)) then
4319 -- Otherwise we fill in the dispatch tables here
4322 if Typ = Etype (Typ)
4323 or else Is_CPP_Class (Etype (Typ))
4324 or else Is_Interface (Typ)
4326 Null_Parent_Tag := True;
4329 Unchecked_Convert_To (RTE (RE_Tag),
4330 Make_Integer_Literal (Loc, 0));
4332 Unchecked_Convert_To (RTE (RE_Tag),
4333 Make_Integer_Literal (Loc, 0));
4338 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc);
4341 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc);
4344 if Typ /= Etype (Typ)
4345 and then not Is_Interface (Typ)
4346 and then not Restriction_Active (No_Dispatching_Calls)
4348 -- Inherit the dispatch table
4350 if not Is_Interface (Etype (Typ)) then
4351 if not Null_Parent_Tag then
4353 Nb_Prims : constant Int :=
4354 UI_To_Int (DT_Entry_Count
4355 (First_Tag_Component (Etype (Typ))));
4357 Append_To (Elab_Code,
4358 Build_Inherit_Predefined_Prims (Loc,
4359 Old_Tag_Node => Old_Tag1,
4361 New_Reference_To (DT_Ptr, Loc)));
4363 if Nb_Prims /= 0 then
4364 Append_To (Elab_Code,
4365 Build_Inherit_Prims (Loc,
4367 Old_Tag_Node => Old_Tag2,
4368 New_Tag_Node => New_Reference_To (DT_Ptr, Loc),
4369 Num_Prims => Nb_Prims));
4375 -- Inherit the secondary dispatch tables of the ancestor
4377 if not Is_CPP_Class (Etype (Typ)) then
4379 Sec_DT_Ancestor : Elmt_Id :=
4382 (Access_Disp_Table (Etype (Typ))));
4383 Sec_DT_Typ : Elmt_Id :=
4386 (Access_Disp_Table (Typ)));
4388 procedure Copy_Secondary_DTs (Typ : Entity_Id);
4389 -- Local procedure required to climb through the ancestors
4390 -- and copy the contents of all their secondary dispatch
4393 ------------------------
4394 -- Copy_Secondary_DTs --
4395 ------------------------
4397 procedure Copy_Secondary_DTs (Typ : Entity_Id) is
4402 -- Climb to the ancestor (if any) handling private types
4404 if Present (Full_View (Etype (Typ))) then
4405 if Full_View (Etype (Typ)) /= Typ then
4406 Copy_Secondary_DTs (Full_View (Etype (Typ)));
4409 elsif Etype (Typ) /= Typ then
4410 Copy_Secondary_DTs (Etype (Typ));
4413 if Present (Abstract_Interfaces (Typ))
4414 and then not Is_Empty_Elmt_List
4415 (Abstract_Interfaces (Typ))
4417 Iface := First_Elmt (Abstract_Interfaces (Typ));
4418 E := First_Entity (Typ);
4420 and then Present (Node (Sec_DT_Ancestor))
4421 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
4423 if Is_Tag (E) and then Chars (E) /= Name_uTag then
4424 if not Is_Interface (Etype (Typ)) then
4426 -- Inherit the dispatch table
4429 Num_Prims : constant Int :=
4430 UI_To_Int (DT_Entry_Count (E));
4432 Append_To (Elab_Code,
4433 Build_Inherit_Predefined_Prims (Loc,
4435 Unchecked_Convert_To (RTE (RE_Tag),
4437 (Node (Sec_DT_Ancestor), Loc)),
4439 Unchecked_Convert_To (RTE (RE_Tag),
4441 (Node (Sec_DT_Typ), Loc))));
4443 if Num_Prims /= 0 then
4444 Append_To (Elab_Code,
4445 Build_Inherit_Prims (Loc,
4446 Typ => Node (Iface),
4448 Unchecked_Convert_To
4451 (Node (Sec_DT_Ancestor),
4454 Unchecked_Convert_To
4457 (Node (Sec_DT_Typ), Loc)),
4458 Num_Prims => Num_Prims));
4463 Next_Elmt (Sec_DT_Ancestor);
4464 Next_Elmt (Sec_DT_Typ);
4471 end Copy_Secondary_DTs;
4474 if Present (Node (Sec_DT_Ancestor))
4475 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
4477 -- Handle private types
4479 if Present (Full_View (Typ)) then
4480 Copy_Secondary_DTs (Full_View (Typ));
4482 Copy_Secondary_DTs (Typ);
4490 -- Generate code to register the Tag in the External_Tag hash table for
4491 -- the pure Ada type only.
4493 -- Register_Tag (Dt_Ptr);
4495 -- Skip this action in the following cases:
4496 -- 1) if Register_Tag is not available.
4497 -- 2) in No_Run_Time mode.
4498 -- 3) if Typ is an abstract interface type (the secondary tags will
4499 -- be registered later in types implementing this interface type).
4500 -- 4) if Typ is not defined at the library level (this is required
4501 -- to avoid adding concurrency control to the hash table used
4502 -- by the run-time to register the tags).
4507 -- [ Register_Tag (Dt_Ptr); ]
4511 if not Is_Interface (Typ) then
4512 if not No_Run_Time_Mode
4513 and then Is_Library_Level_Entity (Typ)
4514 and then RTE_Available (RE_Register_Tag)
4516 Append_To (Elab_Code,
4517 Make_Procedure_Call_Statement (Loc,
4518 Name => New_Reference_To (RTE (RE_Register_Tag), Loc),
4519 Parameter_Associations =>
4520 New_List (New_Reference_To (DT_Ptr, Loc))));
4523 Append_To (Elab_Code,
4524 Make_Assignment_Statement (Loc,
4525 Name => New_Reference_To (No_Reg, Loc),
4526 Expression => New_Reference_To (Standard_False, Loc)));
4529 Make_Implicit_If_Statement (Typ,
4530 Condition => New_Reference_To (No_Reg, Loc),
4531 Then_Statements => Elab_Code));
4534 -- Populate the two auxiliary tables used for dispatching
4535 -- asynchronous, conditional and timed selects for synchronized
4536 -- types that implement a limited interface.
4538 if Ada_Version >= Ada_05
4539 and then Is_Concurrent_Record_Type (Typ)
4540 and then Has_Abstract_Interfaces (Typ)
4542 Append_List_To (Result,
4543 Make_Select_Specific_Data_Table (Typ));
4546 Analyze_List (Result, Suppress => All_Checks);
4547 Set_Has_Dispatch_Table (Typ);
4552 -------------------------------------
4553 -- Make_Select_Specific_Data_Table --
4554 -------------------------------------
4556 function Make_Select_Specific_Data_Table
4557 (Typ : Entity_Id) return List_Id
4559 Assignments : constant List_Id := New_List;
4560 Loc : constant Source_Ptr := Sloc (Typ);
4562 Conc_Typ : Entity_Id;
4566 Prim_Als : Entity_Id;
4567 Prim_Elmt : Elmt_Id;
4571 type Examined_Array is array (Int range <>) of Boolean;
4573 function Find_Entry_Index (E : Entity_Id) return Uint;
4574 -- Given an entry, find its index in the visible declarations of the
4575 -- corresponding concurrent type of Typ.
4577 ----------------------
4578 -- Find_Entry_Index --
4579 ----------------------
4581 function Find_Entry_Index (E : Entity_Id) return Uint is
4582 Index : Uint := Uint_1;
4583 Subp_Decl : Entity_Id;
4587 and then not Is_Empty_List (Decls)
4589 Subp_Decl := First (Decls);
4590 while Present (Subp_Decl) loop
4591 if Nkind (Subp_Decl) = N_Entry_Declaration then
4592 if Defining_Identifier (Subp_Decl) = E then
4604 end Find_Entry_Index;
4606 -- Start of processing for Make_Select_Specific_Data_Table
4609 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
4611 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
4613 if Present (Corresponding_Concurrent_Type (Typ)) then
4614 Conc_Typ := Corresponding_Concurrent_Type (Typ);
4616 if Present (Full_View (Conc_Typ)) then
4617 Conc_Typ := Full_View (Conc_Typ);
4620 if Ekind (Conc_Typ) = E_Protected_Type then
4621 Decls := Visible_Declarations (Protected_Definition (
4622 Parent (Conc_Typ)));
4624 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
4625 Decls := Visible_Declarations (Task_Definition (
4626 Parent (Conc_Typ)));
4630 -- Count the non-predefined primitive operations
4632 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4633 while Present (Prim_Elmt) loop
4634 Prim := Node (Prim_Elmt);
4636 if not (Is_Predefined_Dispatching_Operation (Prim)
4637 or else Is_Predefined_Dispatching_Alias (Prim))
4639 Nb_Prim := Nb_Prim + 1;
4642 Next_Elmt (Prim_Elmt);
4646 Examined : Examined_Array (1 .. Nb_Prim) := (others => False);
4649 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4650 while Present (Prim_Elmt) loop
4651 Prim := Node (Prim_Elmt);
4653 -- Look for primitive overriding an abstract interface subprogram
4655 if Present (Abstract_Interface_Alias (Prim))
4656 and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
4658 Prim_Pos := DT_Position (Alias (Prim));
4659 pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
4660 Examined (UI_To_Int (Prim_Pos)) := True;
4662 -- Set the primitive operation kind regardless of subprogram
4664 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
4666 Append_To (Assignments,
4667 Make_Procedure_Call_Statement (Loc,
4668 Name => New_Reference_To (RTE (RE_Set_Prim_Op_Kind), Loc),
4669 Parameter_Associations => New_List (
4670 New_Reference_To (DT_Ptr, Loc),
4671 Make_Integer_Literal (Loc, Prim_Pos),
4672 Prim_Op_Kind (Alias (Prim), Typ))));
4674 -- Retrieve the root of the alias chain
4677 while Present (Alias (Prim_Als)) loop
4678 Prim_Als := Alias (Prim_Als);
4681 -- In the case of an entry wrapper, set the entry index
4683 if Ekind (Prim) = E_Procedure
4684 and then Is_Primitive_Wrapper (Prim_Als)
4685 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
4688 -- Ada.Tags.Set_Entry_Index
4689 -- (DT_Ptr, <position>, <index>);
4691 Append_To (Assignments,
4692 Make_Procedure_Call_Statement (Loc,
4694 New_Reference_To (RTE (RE_Set_Entry_Index), Loc),
4695 Parameter_Associations => New_List (
4696 New_Reference_To (DT_Ptr, Loc),
4697 Make_Integer_Literal (Loc, Prim_Pos),
4698 Make_Integer_Literal (Loc,
4699 Find_Entry_Index (Wrapped_Entity (Prim_Als))))));
4703 Next_Elmt (Prim_Elmt);
4708 end Make_Select_Specific_Data_Table;
4714 function Make_Tags (Typ : Entity_Id) return List_Id is
4715 Loc : constant Source_Ptr := Sloc (Typ);
4716 Tname : constant Name_Id := Chars (Typ);
4717 Result : constant List_Id := New_List;
4718 AI_Tag_Comp : Elmt_Id;
4720 DT_Constr_List : List_Id;
4722 Iface_DT_Ptr : Node_Id;
4726 Typ_Comps : Elist_Id;
4729 -- 1) Generate the primary and secondary tag entities
4731 -- Collect the components associated with secondary dispatch tables
4733 if Has_Abstract_Interfaces (Typ) then
4734 Collect_Interface_Components (Typ, Typ_Comps);
4737 -- 1) Generate the primary tag entity
4739 DT_Ptr := Make_Defining_Identifier (Loc,
4740 New_External_Name (Tname, 'P'));
4741 Set_Etype (DT_Ptr, RTE (RE_Tag));
4743 -- Import the forward declaration of the Dispatch Table wrapper record
4744 -- (Make_DT will take care of its exportation)
4746 if Building_Static_DT (Typ) then
4747 DT := Make_Defining_Identifier (Loc,
4748 New_External_Name (Tname, 'T'));
4751 -- DT : static aliased constant Dispatch_Table_Wrapper (Nb_Prim);
4752 -- $pragma import (ada, DT);
4754 Set_Is_Imported (DT);
4756 -- The scope must be set now to call Get_External_Name
4758 Set_Scope (DT, Current_Scope);
4760 Get_External_Name (DT, True);
4761 Set_Interface_Name (DT,
4762 Make_String_Literal (Loc,
4763 Strval => String_From_Name_Buffer));
4765 -- Ensure proper Sprint output of this implicit importation
4767 Set_Is_Internal (DT);
4769 -- Save this entity to allow Make_DT to generate its exportation
4771 Set_Dispatch_Table_Wrapper (Typ, DT);
4773 if Has_DT (Typ) then
4774 -- Calculate the number of primitives of the dispatch table and
4775 -- the size of the Type_Specific_Data record.
4777 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
4779 -- If the tagged type has no primitives we add a dummy slot
4780 -- whose address will be the tag of this type.
4784 New_List (Make_Integer_Literal (Loc, 1));
4787 New_List (Make_Integer_Literal (Loc, Nb_Prim));
4791 Make_Object_Declaration (Loc,
4792 Defining_Identifier => DT,
4793 Aliased_Present => True,
4794 Constant_Present => True,
4795 Object_Definition =>
4796 Make_Subtype_Indication (Loc,
4798 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
4799 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4800 Constraints => DT_Constr_List))));
4803 Make_Object_Declaration (Loc,
4804 Defining_Identifier => DT_Ptr,
4805 Constant_Present => True,
4806 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4808 Unchecked_Convert_To (RTE (RE_Tag),
4809 Make_Attribute_Reference (Loc,
4811 Make_Selected_Component (Loc,
4812 Prefix => New_Reference_To (DT, Loc),
4815 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
4816 Attribute_Name => Name_Address))));
4818 -- No dispatch table required
4822 Make_Object_Declaration (Loc,
4823 Defining_Identifier => DT,
4824 Aliased_Present => True,
4825 Constant_Present => True,
4826 Object_Definition =>
4827 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
4830 Make_Object_Declaration (Loc,
4831 Defining_Identifier => DT_Ptr,
4832 Constant_Present => True,
4833 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4835 Unchecked_Convert_To (RTE (RE_Tag),
4836 Make_Attribute_Reference (Loc,
4838 Make_Selected_Component (Loc,
4839 Prefix => New_Reference_To (DT, Loc),
4842 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
4843 Attribute_Name => Name_Address))));
4846 Set_Is_True_Constant (DT_Ptr);
4847 Set_Is_Statically_Allocated (DT_Ptr);
4850 pragma Assert (No (Access_Disp_Table (Typ)));
4851 Set_Access_Disp_Table (Typ, New_Elmt_List);
4852 Append_Elmt (DT_Ptr, Access_Disp_Table (Typ));
4854 -- 2) Generate the secondary tag entities
4856 if Has_Abstract_Interfaces (Typ) then
4859 -- For each interface type we build an unique external name
4860 -- associated with its corresponding secondary dispatch table.
4861 -- This external name will be used to declare an object that
4862 -- references this secondary dispatch table, value that will be
4863 -- used for the elaboration of Typ's objects and also for the
4864 -- elaboration of objects of derivations of Typ that do not
4865 -- override the primitive operation of this interface type.
4867 AI_Tag_Comp := First_Elmt (Typ_Comps);
4868 while Present (AI_Tag_Comp) loop
4869 Get_Secondary_DT_External_Name
4870 (Typ, Related_Interface (Node (AI_Tag_Comp)), Suffix_Index);
4872 Typ_Name := Name_Find;
4874 Make_Defining_Identifier (Loc,
4875 Chars => New_External_Name (Typ_Name, 'P'));
4876 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
4877 Set_Ekind (Iface_DT_Ptr, E_Constant);
4878 Set_Is_Statically_Allocated (Iface_DT_Ptr);
4879 Set_Is_True_Constant (Iface_DT_Ptr);
4880 Set_Related_Interface
4881 (Iface_DT_Ptr, Related_Interface (Node (AI_Tag_Comp)));
4882 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
4884 Next_Elmt (AI_Tag_Comp);
4888 -- 3) At the end of Access_Disp_Table we add the entity of an access
4889 -- type declaration. It is used by Build_Get_Prim_Op_Address to
4890 -- expand dispatching calls through the primary dispatch table.
4893 -- type Typ_DT is array (1 .. Nb_Prims) of Address;
4894 -- type Typ_DT_Acc is access Typ_DT;
4897 Name_DT_Prims : constant Name_Id :=
4898 New_External_Name (Tname, 'G');
4899 Name_DT_Prims_Acc : constant Name_Id :=
4900 New_External_Name (Tname, 'H');
4901 DT_Prims : constant Entity_Id :=
4902 Make_Defining_Identifier (Loc, Name_DT_Prims);
4903 DT_Prims_Acc : constant Entity_Id :=
4904 Make_Defining_Identifier (Loc,
4908 Make_Full_Type_Declaration (Loc,
4909 Defining_Identifier => DT_Prims,
4911 Make_Constrained_Array_Definition (Loc,
4912 Discrete_Subtype_Definitions => New_List (
4914 Low_Bound => Make_Integer_Literal (Loc, 1),
4915 High_Bound => Make_Integer_Literal (Loc,
4917 (First_Tag_Component (Typ))))),
4918 Component_Definition =>
4919 Make_Component_Definition (Loc,
4920 Subtype_Indication =>
4921 New_Reference_To (RTE (RE_Address), Loc)))));
4924 Make_Full_Type_Declaration (Loc,
4925 Defining_Identifier => DT_Prims_Acc,
4927 Make_Access_To_Object_Definition (Loc,
4928 Subtype_Indication =>
4929 New_Occurrence_Of (DT_Prims, Loc))));
4931 Append_Elmt (DT_Prims_Acc, Access_Disp_Table (Typ));
4933 -- Analyze the resulting list and suppress the generation of the
4934 -- Init_Proc associated with the above array declaration because
4935 -- we never use such type in object declarations; this type is only
4936 -- used to simplify the expansion associated with dispatching calls.
4938 Analyze_List (Result);
4939 Set_Suppress_Init_Proc (Base_Type (DT_Prims));
4945 -----------------------------------
4946 -- Original_View_In_Visible_Part --
4947 -----------------------------------
4949 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
4950 Scop : constant Entity_Id := Scope (Typ);
4953 -- The scope must be a package
4955 if Ekind (Scop) /= E_Package
4956 and then Ekind (Scop) /= E_Generic_Package
4961 -- A type with a private declaration has a private view declared in
4962 -- the visible part.
4964 if Has_Private_Declaration (Typ) then
4968 return List_Containing (Parent (Typ)) =
4969 Visible_Declarations (Specification (Unit_Declaration_Node (Scop)));
4970 end Original_View_In_Visible_Part;
4976 function Prim_Op_Kind
4978 Typ : Entity_Id) return Node_Id
4980 Full_Typ : Entity_Id := Typ;
4981 Loc : constant Source_Ptr := Sloc (Prim);
4982 Prim_Op : Entity_Id;
4985 -- Retrieve the original primitive operation
4988 while Present (Alias (Prim_Op)) loop
4989 Prim_Op := Alias (Prim_Op);
4992 if Ekind (Typ) = E_Record_Type
4993 and then Present (Corresponding_Concurrent_Type (Typ))
4995 Full_Typ := Corresponding_Concurrent_Type (Typ);
4998 if Ekind (Prim_Op) = E_Function then
5000 -- Protected function
5002 if Ekind (Full_Typ) = E_Protected_Type then
5003 return New_Reference_To (RTE (RE_POK_Protected_Function), Loc);
5007 elsif Ekind (Full_Typ) = E_Task_Type then
5008 return New_Reference_To (RTE (RE_POK_Task_Function), Loc);
5013 return New_Reference_To (RTE (RE_POK_Function), Loc);
5017 pragma Assert (Ekind (Prim_Op) = E_Procedure);
5019 if Ekind (Full_Typ) = E_Protected_Type then
5023 if Is_Primitive_Wrapper (Prim_Op)
5024 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
5026 return New_Reference_To (RTE (RE_POK_Protected_Entry), Loc);
5028 -- Protected procedure
5031 return New_Reference_To (RTE (RE_POK_Protected_Procedure), Loc);
5034 elsif Ekind (Full_Typ) = E_Task_Type then
5038 if Is_Primitive_Wrapper (Prim_Op)
5039 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
5041 return New_Reference_To (RTE (RE_POK_Task_Entry), Loc);
5043 -- Task "procedure". These are the internally Expander-generated
5044 -- procedures (task body for instance).
5047 return New_Reference_To (RTE (RE_POK_Task_Procedure), Loc);
5050 -- Regular procedure
5053 return New_Reference_To (RTE (RE_POK_Procedure), Loc);
5058 ------------------------
5059 -- Register_Primitive --
5060 ------------------------
5062 procedure Register_Primitive
5068 Iface_Prim : Entity_Id;
5069 Iface_Typ : Entity_Id;
5070 Iface_DT_Ptr : Entity_Id;
5073 Thunk_Id : Entity_Id;
5074 Thunk_Code : Node_Id;
5078 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
5080 if not RTE_Available (RE_Tag) then
5084 if not Present (Abstract_Interface_Alias (Prim)) then
5085 Typ := Scope (DTC_Entity (Prim));
5086 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
5087 Pos := DT_Position (Prim);
5088 Tag := First_Tag_Component (Typ);
5090 if Is_Predefined_Dispatching_Operation (Prim)
5091 or else Is_Predefined_Dispatching_Alias (Prim)
5093 Insert_After (Ins_Nod,
5094 Build_Set_Predefined_Prim_Op_Address (Loc,
5095 Tag_Node => New_Reference_To (DT_Ptr, Loc),
5097 Address_Node => Make_Attribute_Reference (Loc,
5098 Prefix => New_Reference_To (Prim, Loc),
5099 Attribute_Name => Name_Address)));
5102 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
5104 Insert_After (Ins_Nod,
5105 Build_Set_Prim_Op_Address (Loc,
5107 Tag_Node => New_Reference_To (DT_Ptr, Loc),
5109 Address_Node => Make_Attribute_Reference (Loc,
5110 Prefix => New_Reference_To (Prim, Loc),
5111 Attribute_Name => Name_Address)));
5114 -- Ada 2005 (AI-251): Primitive associated with an interface type
5115 -- Generate the code of the thunk only if the interface type is not an
5116 -- immediate ancestor of Typ; otherwise the dispatch table associated
5117 -- with the interface is the primary dispatch table and we have nothing
5121 Typ := Find_Dispatching_Type (Alias (Prim));
5122 Iface_Typ := Find_Dispatching_Type (Abstract_Interface_Alias (Prim));
5124 pragma Assert (Is_Interface (Iface_Typ));
5126 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
5128 if not Is_Parent (Iface_Typ, Typ)
5129 and then Present (Thunk_Code)
5131 -- Comment needed on why checks are suppressed. This is not just
5132 -- efficiency, but fundamental functionality (see 1.295 RH, which
5133 -- still does not answer this question) ???
5135 Insert_Action (Ins_Nod, Thunk_Code, Suppress => All_Checks);
5137 -- Generate the code necessary to fill the appropriate entry of
5138 -- the secondary dispatch table of Prim's controlling type with
5139 -- Thunk_Id's address.
5141 Iface_DT_Ptr := Find_Interface_ADT (Typ, Iface_Typ);
5142 Iface_Prim := Abstract_Interface_Alias (Prim);
5143 Pos := DT_Position (Iface_Prim);
5144 Tag := First_Tag_Component (Iface_Typ);
5146 if Is_Predefined_Dispatching_Operation (Prim)
5147 or else Is_Predefined_Dispatching_Alias (Prim)
5149 Insert_Action (Ins_Nod,
5150 Build_Set_Predefined_Prim_Op_Address (Loc,
5151 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
5154 Make_Attribute_Reference (Loc,
5155 Prefix => New_Reference_To (Thunk_Id, Loc),
5156 Attribute_Name => Name_Address)));
5158 pragma Assert (Pos /= Uint_0
5159 and then Pos <= DT_Entry_Count (Tag));
5161 Insert_Action (Ins_Nod,
5162 Build_Set_Prim_Op_Address (Loc,
5164 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
5166 Address_Node => Make_Attribute_Reference (Loc,
5168 New_Reference_To (Thunk_Id, Loc),
5169 Attribute_Name => Name_Address)));
5173 end Register_Primitive;
5175 -------------------------
5176 -- Set_All_DT_Position --
5177 -------------------------
5179 procedure Set_All_DT_Position (Typ : Entity_Id) is
5181 procedure Validate_Position (Prim : Entity_Id);
5182 -- Check that the position assignated to Prim is completely safe
5183 -- (it has not been assigned to a previously defined primitive
5184 -- operation of Typ)
5186 -----------------------
5187 -- Validate_Position --
5188 -----------------------
5190 procedure Validate_Position (Prim : Entity_Id) is
5195 -- Aliased primitives are safe
5197 if Present (Alias (Prim)) then
5201 Op_Elmt := First_Elmt (Primitive_Operations (Typ));
5202 while Present (Op_Elmt) loop
5203 Op := Node (Op_Elmt);
5205 -- No need to check against itself
5210 -- Primitive operations covering abstract interfaces are
5213 elsif Present (Abstract_Interface_Alias (Op)) then
5216 -- Predefined dispatching operations are completely safe. They
5217 -- are allocated at fixed positions in a separate table.
5219 elsif Is_Predefined_Dispatching_Operation (Op)
5220 or else Is_Predefined_Dispatching_Alias (Op)
5224 -- Aliased subprograms are safe
5226 elsif Present (Alias (Op)) then
5229 elsif DT_Position (Op) = DT_Position (Prim)
5230 and then not Is_Predefined_Dispatching_Operation (Op)
5231 and then not Is_Predefined_Dispatching_Operation (Prim)
5232 and then not Is_Predefined_Dispatching_Alias (Op)
5233 and then not Is_Predefined_Dispatching_Alias (Prim)
5236 -- Handle aliased subprograms
5245 if Present (Overridden_Operation (Op_1)) then
5246 Op_1 := Overridden_Operation (Op_1);
5247 elsif Present (Alias (Op_1)) then
5248 Op_1 := Alias (Op_1);
5256 if Present (Overridden_Operation (Op_2)) then
5257 Op_2 := Overridden_Operation (Op_2);
5258 elsif Present (Alias (Op_2)) then
5259 Op_2 := Alias (Op_2);
5265 if Op_1 /= Op_2 then
5266 raise Program_Error;
5271 Next_Elmt (Op_Elmt);
5273 end Validate_Position;
5277 Parent_Typ : constant Entity_Id := Etype (Typ);
5278 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
5279 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
5281 Adjusted : Boolean := False;
5282 Finalized : Boolean := False;
5288 Prim_Elmt : Elmt_Id;
5290 -- Start of processing for Set_All_DT_Position
5293 -- Set the DT_Position for each primitive operation. Perform some
5294 -- sanity checks to avoid to build completely inconsistant dispatch
5297 -- First stage: Set the DTC entity of all the primitive operations
5298 -- This is required to properly read the DT_Position attribute in
5299 -- the latter stages.
5301 Prim_Elmt := First_Prim;
5303 while Present (Prim_Elmt) loop
5304 Prim := Node (Prim_Elmt);
5306 -- Predefined primitives have a separate dispatch table
5308 if not (Is_Predefined_Dispatching_Operation (Prim)
5309 or else Is_Predefined_Dispatching_Alias (Prim))
5311 Count_Prim := Count_Prim + 1;
5314 Set_DTC_Entity_Value (Typ, Prim);
5316 -- Clear any previous value of the DT_Position attribute. In this
5317 -- way we ensure that the final position of all the primitives is
5318 -- stablished by the following stages of this algorithm.
5320 Set_DT_Position (Prim, No_Uint);
5322 Next_Elmt (Prim_Elmt);
5326 Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean
5327 := (others => False);
5330 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id);
5331 -- Called if Typ is declared in a nested package or a public child
5332 -- package to handle inherited primitives that were inherited by Typ
5333 -- in the visible part, but whose declaration was deferred because
5334 -- the parent operation was private and not visible at that point.
5336 procedure Set_Fixed_Prim (Pos : Nat);
5337 -- Sets to true an element of the Fixed_Prim table to indicate
5338 -- that this entry of the dispatch table of Typ is occupied.
5340 ------------------------------------------
5341 -- Handle_Inherited_Private_Subprograms --
5342 ------------------------------------------
5344 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id) is
5347 Op_Elmt_2 : Elmt_Id;
5348 Prim_Op : Entity_Id;
5349 Parent_Subp : Entity_Id;
5352 Op_List := Primitive_Operations (Typ);
5354 Op_Elmt := First_Elmt (Op_List);
5355 while Present (Op_Elmt) loop
5356 Prim_Op := Node (Op_Elmt);
5358 -- Search primitives that are implicit operations with an
5359 -- internal name whose parent operation has a normal name.
5361 if Present (Alias (Prim_Op))
5362 and then Find_Dispatching_Type (Alias (Prim_Op)) /= Typ
5363 and then not Comes_From_Source (Prim_Op)
5364 and then Is_Internal_Name (Chars (Prim_Op))
5365 and then not Is_Internal_Name (Chars (Alias (Prim_Op)))
5367 Parent_Subp := Alias (Prim_Op);
5369 -- Check if the type has an explicit overriding for this
5372 Op_Elmt_2 := Next_Elmt (Op_Elmt);
5373 while Present (Op_Elmt_2) loop
5374 if Chars (Node (Op_Elmt_2)) = Chars (Parent_Subp)
5375 and then Type_Conformant (Prim_Op, Node (Op_Elmt_2))
5377 Set_DT_Position (Prim_Op, DT_Position (Parent_Subp));
5378 Set_DT_Position (Node (Op_Elmt_2),
5379 DT_Position (Parent_Subp));
5380 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim_Op)));
5382 goto Next_Primitive;
5385 Next_Elmt (Op_Elmt_2);
5390 Next_Elmt (Op_Elmt);
5392 end Handle_Inherited_Private_Subprograms;
5394 --------------------
5395 -- Set_Fixed_Prim --
5396 --------------------
5398 procedure Set_Fixed_Prim (Pos : Nat) is
5400 pragma Assert (Pos >= 0 and then Pos <= Count_Prim);
5401 Fixed_Prim (Pos) := True;
5403 when Constraint_Error =>
5404 raise Program_Error;
5408 -- In case of nested packages and public child package it may be
5409 -- necessary a special management on inherited subprograms so that
5410 -- the dispatch table is properly filled.
5412 if Ekind (Scope (Scope (Typ))) = E_Package
5413 and then Scope (Scope (Typ)) /= Standard_Standard
5414 and then ((Is_Derived_Type (Typ) and then not Is_Private_Type (Typ))
5416 (Nkind (Parent (Typ)) = N_Private_Extension_Declaration
5417 and then Is_Generic_Type (Typ)))
5418 and then In_Open_Scopes (Scope (Etype (Typ)))
5419 and then Typ = Base_Type (Typ)
5421 Handle_Inherited_Private_Subprograms (Typ);
5424 -- Second stage: Register fixed entries
5427 Prim_Elmt := First_Prim;
5428 while Present (Prim_Elmt) loop
5429 Prim := Node (Prim_Elmt);
5431 -- Predefined primitives have a separate table and all its
5432 -- entries are at predefined fixed positions.
5434 if Is_Predefined_Dispatching_Operation (Prim) then
5435 Set_DT_Position (Prim, Default_Prim_Op_Position (Prim));
5437 elsif Is_Predefined_Dispatching_Alias (Prim) then
5439 while Present (Alias (E)) loop
5443 Set_DT_Position (Prim, Default_Prim_Op_Position (E));
5445 -- Overriding primitives of ancestor abstract interfaces
5447 elsif Present (Abstract_Interface_Alias (Prim))
5449 (Find_Dispatching_Type
5450 (Abstract_Interface_Alias (Prim)),
5453 pragma Assert (DT_Position (Prim) = No_Uint
5454 and then Present (DTC_Entity
5455 (Abstract_Interface_Alias (Prim))));
5457 E := Abstract_Interface_Alias (Prim);
5458 Set_DT_Position (Prim, DT_Position (E));
5461 (DT_Position (Alias (Prim)) = No_Uint
5462 or else DT_Position (Alias (Prim)) = DT_Position (E));
5463 Set_DT_Position (Alias (Prim), DT_Position (E));
5464 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));
5466 -- Overriding primitives must use the same entry as the
5467 -- overriden primitive.
5469 elsif not Present (Abstract_Interface_Alias (Prim))
5470 and then Present (Alias (Prim))
5471 and then Chars (Prim) = Chars (Alias (Prim))
5472 and then Find_Dispatching_Type (Alias (Prim)) /= Typ
5474 (Find_Dispatching_Type (Alias (Prim)), Typ)
5475 and then Present (DTC_Entity (Alias (Prim)))
5478 Set_DT_Position (Prim, DT_Position (E));
5480 if not Is_Predefined_Dispatching_Alias (E) then
5481 Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
5485 Next_Elmt (Prim_Elmt);
5488 -- Third stage: Fix the position of all the new primitives
5489 -- Entries associated with primitives covering interfaces
5490 -- are handled in a latter round.
5492 Prim_Elmt := First_Prim;
5493 while Present (Prim_Elmt) loop
5494 Prim := Node (Prim_Elmt);
5496 -- Skip primitives previously set entries
5498 if DT_Position (Prim) /= No_Uint then
5501 -- Primitives covering interface primitives are handled later
5503 elsif Present (Abstract_Interface_Alias (Prim)) then
5507 -- Take the next available position in the DT
5510 Nb_Prim := Nb_Prim + 1;
5511 pragma Assert (Nb_Prim <= Count_Prim);
5512 exit when not Fixed_Prim (Nb_Prim);
5515 Set_DT_Position (Prim, UI_From_Int (Nb_Prim));
5516 Set_Fixed_Prim (Nb_Prim);
5519 Next_Elmt (Prim_Elmt);
5523 -- Fourth stage: Complete the decoration of primitives covering
5524 -- interfaces (that is, propagate the DT_Position attribute
5525 -- from the aliased primitive)
5527 Prim_Elmt := First_Prim;
5528 while Present (Prim_Elmt) loop
5529 Prim := Node (Prim_Elmt);
5531 if DT_Position (Prim) = No_Uint
5532 and then Present (Abstract_Interface_Alias (Prim))
5534 pragma Assert (Present (Alias (Prim))
5535 and then Find_Dispatching_Type (Alias (Prim)) = Typ);
5537 -- Check if this entry will be placed in the primary DT
5539 if Is_Parent (Find_Dispatching_Type
5540 (Abstract_Interface_Alias (Prim)),
5543 pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
5544 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
5546 -- Otherwise it will be placed in the secondary DT
5550 (DT_Position (Abstract_Interface_Alias (Prim)) /= No_Uint);
5551 Set_DT_Position (Prim,
5552 DT_Position (Abstract_Interface_Alias (Prim)));
5556 Next_Elmt (Prim_Elmt);
5559 -- Generate listing showing the contents of the dispatch tables.
5560 -- This action is done before some further static checks because
5561 -- in case of critical errors caused by a wrong dispatch table
5562 -- we need to see the contents of such table.
5564 if Debug_Flag_ZZ then
5568 -- Final stage: Ensure that the table is correct plus some further
5569 -- verifications concerning the primitives.
5571 Prim_Elmt := First_Prim;
5573 while Present (Prim_Elmt) loop
5574 Prim := Node (Prim_Elmt);
5576 -- At this point all the primitives MUST have a position
5577 -- in the dispatch table
5579 if DT_Position (Prim) = No_Uint then
5580 raise Program_Error;
5583 -- Calculate real size of the dispatch table
5585 if not (Is_Predefined_Dispatching_Operation (Prim)
5586 or else Is_Predefined_Dispatching_Alias (Prim))
5587 and then UI_To_Int (DT_Position (Prim)) > DT_Length
5589 DT_Length := UI_To_Int (DT_Position (Prim));
5592 -- Ensure that the asignated position to non-predefined
5593 -- dispatching operations in the dispatch table is correct.
5595 if not (Is_Predefined_Dispatching_Operation (Prim)
5596 or else Is_Predefined_Dispatching_Alias (Prim))
5598 Validate_Position (Prim);
5601 if Chars (Prim) = Name_Finalize then
5605 if Chars (Prim) = Name_Adjust then
5609 -- An abstract operation cannot be declared in the private part
5610 -- for a visible abstract type, because it could never be over-
5611 -- ridden. For explicit declarations this is checked at the
5612 -- point of declaration, but for inherited operations it must
5613 -- be done when building the dispatch table.
5615 -- Ada 2005 (AI-251): Hidden entities associated with abstract
5616 -- interface primitives are not taken into account because the
5617 -- check is done with the aliased primitive.
5619 if Is_Abstract_Type (Typ)
5620 and then Is_Abstract_Subprogram (Prim)
5621 and then Present (Alias (Prim))
5622 and then not Present (Abstract_Interface_Alias (Prim))
5623 and then Is_Derived_Type (Typ)
5624 and then In_Private_Part (Current_Scope)
5626 List_Containing (Parent (Prim)) =
5627 Private_Declarations
5628 (Specification (Unit_Declaration_Node (Current_Scope)))
5629 and then Original_View_In_Visible_Part (Typ)
5631 -- We exclude Input and Output stream operations because
5632 -- Limited_Controlled inherits useless Input and Output
5633 -- stream operations from Root_Controlled, which can
5634 -- never be overridden.
5636 if not Is_TSS (Prim, TSS_Stream_Input)
5638 not Is_TSS (Prim, TSS_Stream_Output)
5641 ("abstract inherited private operation&" &
5642 " must be overridden (RM 3.9.3(10))",
5643 Parent (Typ), Prim);
5647 Next_Elmt (Prim_Elmt);
5652 if Is_Controlled (Typ) then
5653 if not Finalized then
5655 ("controlled type has no explicit Finalize method?", Typ);
5657 elsif not Adjusted then
5659 ("controlled type has no explicit Adjust method?", Typ);
5663 -- Set the final size of the Dispatch Table
5665 Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));
5667 -- The derived type must have at least as many components as its parent
5668 -- (for root types, the Etype points back to itself and the test cannot
5671 if DT_Entry_Count (The_Tag) <
5672 DT_Entry_Count (First_Tag_Component (Parent_Typ))
5674 raise Program_Error;
5676 end Set_All_DT_Position;
5678 -----------------------------
5679 -- Set_Default_Constructor --
5680 -----------------------------
5682 procedure Set_Default_Constructor (Typ : Entity_Id) is
5689 -- Look for the default constructor entity. For now only the
5690 -- default constructor has the flag Is_Constructor.
5692 E := Next_Entity (Typ);
5694 and then (Ekind (E) /= E_Function or else not Is_Constructor (E))
5699 -- Create the init procedure
5703 Init := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
5704 Param := Make_Defining_Identifier (Loc, Name_X);
5707 Make_Subprogram_Declaration (Loc,
5708 Make_Procedure_Specification (Loc,
5709 Defining_Unit_Name => Init,
5710 Parameter_Specifications => New_List (
5711 Make_Parameter_Specification (Loc,
5712 Defining_Identifier => Param,
5713 Parameter_Type => New_Reference_To (Typ, Loc))))));
5715 Set_Init_Proc (Typ, Init);
5716 Set_Is_Imported (Init);
5717 Set_Interface_Name (Init, Interface_Name (E));
5718 Set_Convention (Init, Convention_C);
5719 Set_Is_Public (Init);
5720 Set_Has_Completion (Init);
5722 -- If there are no constructors, mark the type as abstract since we
5723 -- won't be able to declare objects of that type.
5726 Set_Is_Abstract_Type (Typ);
5728 end Set_Default_Constructor;
5730 --------------------------
5731 -- Set_DTC_Entity_Value --
5732 --------------------------
5734 procedure Set_DTC_Entity_Value
5735 (Tagged_Type : Entity_Id;
5739 if Present (Abstract_Interface_Alias (Prim))
5740 and then Is_Interface
5741 (Find_Dispatching_Type
5742 (Abstract_Interface_Alias (Prim)))
5744 Set_DTC_Entity (Prim,
5747 Iface => Find_Dispatching_Type
5748 (Abstract_Interface_Alias (Prim))));
5750 Set_DTC_Entity (Prim,
5751 First_Tag_Component (Tagged_Type));
5753 end Set_DTC_Entity_Value;
5759 function Tagged_Kind (T : Entity_Id) return Node_Id is
5760 Conc_Typ : Entity_Id;
5761 Loc : constant Source_Ptr := Sloc (T);
5765 (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));
5769 if Is_Abstract_Type (T) then
5770 if Is_Limited_Record (T) then
5771 return New_Reference_To (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
5773 return New_Reference_To (RTE (RE_TK_Abstract_Tagged), Loc);
5778 elsif Is_Concurrent_Record_Type (T) then
5779 Conc_Typ := Corresponding_Concurrent_Type (T);
5781 if Present (Full_View (Conc_Typ)) then
5782 Conc_Typ := Full_View (Conc_Typ);
5785 if Ekind (Conc_Typ) = E_Protected_Type then
5786 return New_Reference_To (RTE (RE_TK_Protected), Loc);
5788 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
5789 return New_Reference_To (RTE (RE_TK_Task), Loc);
5792 -- Regular tagged kinds
5795 if Is_Limited_Record (T) then
5796 return New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc);
5798 return New_Reference_To (RTE (RE_TK_Tagged), Loc);
5807 procedure Write_DT (Typ : Entity_Id) is
5812 -- Protect this procedure against wrong usage. Required because it will
5813 -- be used directly from GDB
5815 if not (Typ <= Last_Node_Id)
5816 or else not Is_Tagged_Type (Typ)
5818 Write_Str ("wrong usage: Write_DT must be used with tagged types");
5823 Write_Int (Int (Typ));
5825 Write_Name (Chars (Typ));
5827 if Is_Interface (Typ) then
5828 Write_Str (" is interface");
5833 Elmt := First_Elmt (Primitive_Operations (Typ));
5834 while Present (Elmt) loop
5835 Prim := Node (Elmt);
5838 -- Indicate if this primitive will be allocated in the primary
5839 -- dispatch table or in a secondary dispatch table associated
5840 -- with an abstract interface type
5842 if Present (DTC_Entity (Prim)) then
5843 if Etype (DTC_Entity (Prim)) = RTE (RE_Tag) then
5850 -- Output the node of this primitive operation and its name
5852 Write_Int (Int (Prim));
5855 if Is_Predefined_Dispatching_Operation (Prim) then
5856 Write_Str ("(predefined) ");
5859 Write_Name (Chars (Prim));
5861 -- Indicate if this primitive has an aliased primitive
5863 if Present (Alias (Prim)) then
5864 Write_Str (" (alias = ");
5865 Write_Int (Int (Alias (Prim)));
5867 -- If the DTC_Entity attribute is already set we can also output
5868 -- the name of the interface covered by this primitive (if any)
5870 if Present (DTC_Entity (Alias (Prim)))
5871 and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
5873 Write_Str (" from interface ");
5874 Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
5877 if Present (Abstract_Interface_Alias (Prim)) then
5878 Write_Str (", AI_Alias of ");
5879 Write_Name (Chars (Scope (DTC_Entity
5880 (Abstract_Interface_Alias (Prim)))));
5882 Write_Int (Int (Abstract_Interface_Alias (Prim)));
5888 -- Display the final position of this primitive in its associated
5889 -- (primary or secondary) dispatch table
5891 if Present (DTC_Entity (Prim))
5892 and then DT_Position (Prim) /= No_Uint
5894 Write_Str (" at #");
5895 Write_Int (UI_To_Int (DT_Position (Prim)));
5898 if Is_Abstract_Subprogram (Prim) then
5899 Write_Str (" is abstract;");
5901 -- Check if this is a null primitive
5903 elsif Comes_From_Source (Prim)
5904 and then Ekind (Prim) = E_Procedure
5905 and then Null_Present (Parent (Prim))
5907 Write_Str (" is null;");