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
1015 Actual_Dup : Node_Id;
1016 Actual_Typ : Entity_Id;
1018 Conversion : Node_Id;
1020 Formal_Typ : Entity_Id;
1022 Formal_DDT : Entity_Id;
1023 Actual_DDT : Entity_Id;
1026 -- This subprogram is called directly from the semantics, so we need a
1027 -- check to see whether expansion is active before proceeding.
1029 if not Expander_Active then
1033 -- Call using access to subprogram with explicit dereference
1035 if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
1036 Subp := Etype (Name (Call_Node));
1041 Subp := Entity (Name (Call_Node));
1044 -- Ada 2005 (AI-251): Look for interface type formals to force "this"
1047 Formal := First_Formal (Subp);
1048 Actual := First_Actual (Call_Node);
1049 while Present (Formal) loop
1050 Formal_Typ := Etype (Formal);
1052 if Ekind (Formal_Typ) = E_Record_Type_With_Private then
1053 Formal_Typ := Full_View (Formal_Typ);
1056 if Is_Access_Type (Formal_Typ) then
1057 Formal_DDT := Directly_Designated_Type (Formal_Typ);
1060 Actual_Typ := Etype (Actual);
1062 if Is_Access_Type (Actual_Typ) then
1063 Actual_DDT := Directly_Designated_Type (Actual_Typ);
1066 if Is_Interface (Formal_Typ)
1067 and then Is_Class_Wide_Type (Formal_Typ)
1069 -- No need to displace the pointer if the type of the actual
1070 -- coindices with the type of the formal.
1072 if Actual_Typ = Formal_Typ then
1075 -- No need to displace the pointer if the interface type is
1076 -- a parent of the type of the actual because in this case the
1077 -- interface primitives are located in the primary dispatch table.
1079 elsif Is_Parent (Formal_Typ, Actual_Typ) then
1082 -- Implicit conversion to the class-wide formal type to force
1083 -- the displacement of the pointer.
1086 Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
1087 Rewrite (Actual, Conversion);
1088 Analyze_And_Resolve (Actual, Formal_Typ);
1091 -- Access to class-wide interface type
1093 elsif Is_Access_Type (Formal_Typ)
1094 and then Is_Interface (Formal_DDT)
1095 and then Is_Class_Wide_Type (Formal_DDT)
1096 and then Interface_Present_In_Ancestor
1098 Iface => Etype (Formal_DDT))
1100 -- Handle attributes 'Access and 'Unchecked_Access
1102 if Nkind (Actual) = N_Attribute_Reference
1104 (Attribute_Name (Actual) = Name_Access
1105 or else Attribute_Name (Actual) = Name_Unchecked_Access)
1107 -- This case must have been handled by the analysis and
1108 -- expansion of 'Access. The only exception is when types
1109 -- match and no further expansion is required.
1111 pragma Assert (Base_Type (Etype (Prefix (Actual)))
1112 = Base_Type (Formal_DDT));
1115 -- No need to displace the pointer if the type of the actual
1116 -- coincides with the type of the formal.
1118 elsif Actual_DDT = Formal_DDT then
1121 -- No need to displace the pointer if the interface type is
1122 -- a parent of the type of the actual because in this case the
1123 -- interface primitives are located in the primary dispatch table.
1125 elsif Is_Parent (Formal_DDT, Actual_DDT) then
1129 Actual_Dup := Relocate_Node (Actual);
1131 if From_With_Type (Actual_Typ) then
1133 -- If the type of the actual parameter comes from a limited
1134 -- with-clause and the non-limited view is already available
1135 -- we replace the anonymous access type by a duplicate decla
1136 -- ration whose designated type is the non-limited view
1138 if Ekind (Actual_DDT) = E_Incomplete_Type
1139 and then Present (Non_Limited_View (Actual_DDT))
1141 Anon := New_Copy (Actual_Typ);
1143 if Is_Itype (Anon) then
1144 Set_Scope (Anon, Current_Scope);
1147 Set_Directly_Designated_Type (Anon,
1148 Non_Limited_View (Actual_DDT));
1149 Set_Etype (Actual_Dup, Anon);
1151 elsif Is_Class_Wide_Type (Actual_DDT)
1152 and then Ekind (Etype (Actual_DDT)) = E_Incomplete_Type
1153 and then Present (Non_Limited_View (Etype (Actual_DDT)))
1155 Anon := New_Copy (Actual_Typ);
1157 if Is_Itype (Anon) then
1158 Set_Scope (Anon, Current_Scope);
1161 Set_Directly_Designated_Type (Anon,
1162 New_Copy (Actual_DDT));
1163 Set_Class_Wide_Type (Directly_Designated_Type (Anon),
1164 New_Copy (Class_Wide_Type (Actual_DDT)));
1165 Set_Etype (Directly_Designated_Type (Anon),
1166 Non_Limited_View (Etype (Actual_DDT)));
1168 Class_Wide_Type (Directly_Designated_Type (Anon)),
1169 Non_Limited_View (Etype (Actual_DDT)));
1170 Set_Etype (Actual_Dup, Anon);
1174 Conversion := Convert_To (Formal_Typ, Actual_Dup);
1175 Rewrite (Actual, Conversion);
1176 Analyze_And_Resolve (Actual, Formal_Typ);
1180 Next_Actual (Actual);
1181 Next_Formal (Formal);
1183 end Expand_Interface_Actuals;
1185 ----------------------------
1186 -- Expand_Interface_Thunk --
1187 ----------------------------
1189 procedure Expand_Interface_Thunk
1191 Thunk_Id : out Entity_Id;
1192 Thunk_Code : out Node_Id)
1194 Loc : constant Source_Ptr := Sloc (Prim);
1195 Actuals : constant List_Id := New_List;
1196 Decl : constant List_Id := New_List;
1197 Formals : constant List_Id := New_List;
1199 Controlling_Typ : Entity_Id;
1204 Target_Formal : Entity_Id;
1208 Thunk_Code := Empty;
1210 -- Give message if configurable run-time and Offset_To_Top unavailable
1212 if not RTE_Available (RE_Offset_To_Top) then
1213 Error_Msg_CRT ("abstract interface types", Prim);
1217 -- Traverse the list of alias to find the final target
1220 while Present (Alias (Target)) loop
1221 Target := Alias (Target);
1224 -- In case of primitives that are functions without formals and
1225 -- a controlling result there is no need to build the thunk.
1227 if not Present (First_Formal (Target)) then
1228 pragma Assert (Ekind (Target) = E_Function
1229 and then Has_Controlling_Result (Target));
1233 -- Duplicate the formals
1235 Formal := First_Formal (Target);
1236 while Present (Formal) loop
1238 Make_Parameter_Specification (Loc,
1239 Defining_Identifier =>
1240 Make_Defining_Identifier (Sloc (Formal),
1241 Chars => Chars (Formal)),
1242 In_Present => In_Present (Parent (Formal)),
1243 Out_Present => Out_Present (Parent (Formal)),
1245 New_Reference_To (Etype (Formal), Loc),
1246 Expression => New_Copy_Tree (Expression (Parent (Formal)))));
1248 Next_Formal (Formal);
1251 Controlling_Typ := Find_Dispatching_Type (Target);
1253 Target_Formal := First_Formal (Target);
1254 Formal := First (Formals);
1255 while Present (Formal) loop
1256 if Ekind (Target_Formal) = E_In_Parameter
1257 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
1258 and then Directly_Designated_Type (Etype (Target_Formal))
1263 -- type T is access all <<type of the target formal>>
1264 -- S : Storage_Offset := Storage_Offset!(Formal)
1265 -- - Offset_To_Top (address!(Formal))
1268 Make_Full_Type_Declaration (Loc,
1269 Defining_Identifier =>
1270 Make_Defining_Identifier (Loc,
1271 New_Internal_Name ('T')),
1273 Make_Access_To_Object_Definition (Loc,
1274 All_Present => True,
1275 Null_Exclusion_Present => False,
1276 Constant_Present => False,
1277 Subtype_Indication =>
1279 (Directly_Designated_Type
1280 (Etype (Target_Formal)), Loc)));
1283 Make_Object_Declaration (Loc,
1284 Defining_Identifier =>
1285 Make_Defining_Identifier (Loc,
1286 New_Internal_Name ('S')),
1287 Constant_Present => True,
1288 Object_Definition =>
1289 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1291 Make_Op_Subtract (Loc,
1293 Unchecked_Convert_To
1294 (RTE (RE_Storage_Offset),
1295 New_Reference_To (Defining_Identifier (Formal), Loc)),
1297 Make_Function_Call (Loc,
1299 New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1300 Parameter_Associations => New_List (
1301 Unchecked_Convert_To
1304 (Defining_Identifier (Formal), Loc))))));
1306 Append_To (Decl, Decl_2);
1307 Append_To (Decl, Decl_1);
1309 -- Reference the new actual. Generate:
1313 Unchecked_Convert_To
1314 (Defining_Identifier (Decl_2),
1315 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1317 elsif Etype (Target_Formal) = Controlling_Typ then
1320 -- S1 : Storage_Offset := Storage_Offset!(Formal'Address)
1321 -- - Offset_To_Top (Formal'Address)
1322 -- S2 : Addr_Ptr := Addr_Ptr!(S1)
1325 Make_Object_Declaration (Loc,
1326 Defining_Identifier =>
1327 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1328 Constant_Present => True,
1329 Object_Definition =>
1330 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1332 Make_Op_Subtract (Loc,
1334 Unchecked_Convert_To
1335 (RTE (RE_Storage_Offset),
1336 Make_Attribute_Reference (Loc,
1339 (Defining_Identifier (Formal), Loc),
1340 Attribute_Name => Name_Address)),
1342 Make_Function_Call (Loc,
1344 New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1345 Parameter_Associations => New_List (
1346 Make_Attribute_Reference (Loc,
1349 (Defining_Identifier (Formal), Loc),
1350 Attribute_Name => Name_Address)))));
1353 Make_Object_Declaration (Loc,
1354 Defining_Identifier =>
1355 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1356 Constant_Present => True,
1357 Object_Definition => New_Reference_To (RTE (RE_Addr_Ptr), Loc),
1359 Unchecked_Convert_To
1361 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1363 Append_To (Decl, Decl_1);
1364 Append_To (Decl, Decl_2);
1366 -- Reference the new actual. Generate:
1367 -- Target_Formal (S2.all)
1370 Unchecked_Convert_To
1371 (Etype (Target_Formal),
1372 Make_Explicit_Dereference (Loc,
1373 New_Reference_To (Defining_Identifier (Decl_2), Loc))));
1375 -- No special management required for this actual
1379 New_Reference_To (Defining_Identifier (Formal), Loc));
1382 Next_Formal (Target_Formal);
1387 Make_Defining_Identifier (Loc,
1388 Chars => New_Internal_Name ('T'));
1390 Set_Is_Thunk (Thunk_Id);
1392 if Ekind (Target) = E_Procedure then
1394 Make_Subprogram_Body (Loc,
1396 Make_Procedure_Specification (Loc,
1397 Defining_Unit_Name => Thunk_Id,
1398 Parameter_Specifications => Formals),
1399 Declarations => Decl,
1400 Handled_Statement_Sequence =>
1401 Make_Handled_Sequence_Of_Statements (Loc,
1402 Statements => New_List (
1403 Make_Procedure_Call_Statement (Loc,
1404 Name => New_Occurrence_Of (Target, Loc),
1405 Parameter_Associations => Actuals))));
1407 else pragma Assert (Ekind (Target) = E_Function);
1410 Make_Subprogram_Body (Loc,
1412 Make_Function_Specification (Loc,
1413 Defining_Unit_Name => Thunk_Id,
1414 Parameter_Specifications => Formals,
1415 Result_Definition =>
1416 New_Copy (Result_Definition (Parent (Target)))),
1417 Declarations => Decl,
1418 Handled_Statement_Sequence =>
1419 Make_Handled_Sequence_Of_Statements (Loc,
1420 Statements => New_List (
1421 Make_Simple_Return_Statement (Loc,
1422 Make_Function_Call (Loc,
1423 Name => New_Occurrence_Of (Target, Loc),
1424 Parameter_Associations => Actuals)))));
1426 end Expand_Interface_Thunk;
1432 function Has_DT (Typ : Entity_Id) return Boolean is
1434 return not Is_Interface (Typ)
1435 and then not Restriction_Active (No_Dispatching_Calls);
1438 -------------------------------------
1439 -- Is_Predefined_Dispatching_Alias --
1440 -------------------------------------
1442 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
1447 if not Is_Predefined_Dispatching_Operation (Prim)
1448 and then Present (Alias (Prim))
1451 while Present (Alias (E)) loop
1455 if Is_Predefined_Dispatching_Operation (E) then
1461 end Is_Predefined_Dispatching_Alias;
1463 ----------------------------------------
1464 -- Make_Disp_Asynchronous_Select_Body --
1465 ----------------------------------------
1467 function Make_Disp_Asynchronous_Select_Body
1468 (Typ : Entity_Id) return Node_Id
1470 Com_Block : Entity_Id;
1471 Conc_Typ : Entity_Id := Empty;
1472 Decls : constant List_Id := New_List;
1474 Loc : constant Source_Ptr := Sloc (Typ);
1475 Stmts : constant List_Id := New_List;
1478 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1480 -- Null body is generated for interface types
1482 if Is_Interface (Typ) then
1484 Make_Subprogram_Body (Loc,
1486 Make_Disp_Asynchronous_Select_Spec (Typ),
1489 Handled_Statement_Sequence =>
1490 Make_Handled_Sequence_Of_Statements (Loc,
1491 New_List (Make_Null_Statement (Loc))));
1494 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1496 if Is_Concurrent_Record_Type (Typ) then
1497 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1500 -- I : Integer := Get_Entry_Index (tag! (<type>VP), S);
1502 -- where I will be used to capture the entry index of the primitive
1503 -- wrapper at position S.
1506 Make_Object_Declaration (Loc,
1507 Defining_Identifier =>
1508 Make_Defining_Identifier (Loc, Name_uI),
1509 Object_Definition =>
1510 New_Reference_To (Standard_Integer, Loc),
1512 Make_Function_Call (Loc,
1513 Name => New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
1514 Parameter_Associations => New_List (
1515 Unchecked_Convert_To (RTE (RE_Tag),
1516 New_Reference_To (DT_Ptr, Loc)),
1517 Make_Identifier (Loc, Name_uS)))));
1519 if Ekind (Conc_Typ) = E_Protected_Type then
1522 -- Com_Block : Communication_Block;
1525 Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1528 Make_Object_Declaration (Loc,
1529 Defining_Identifier =>
1531 Object_Definition =>
1532 New_Reference_To (RTE (RE_Communication_Block), Loc)));
1535 -- Protected_Entry_Call (
1536 -- T._object'access,
1537 -- protected_entry_index! (I),
1539 -- Asynchronous_Call,
1542 -- where T is the protected object, I is the entry index, P are
1543 -- the wrapped parameters and B is the name of the communication
1547 Make_Procedure_Call_Statement (Loc,
1549 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1550 Parameter_Associations =>
1553 Make_Attribute_Reference (Loc, -- T._object'access
1555 Name_Unchecked_Access,
1557 Make_Selected_Component (Loc,
1559 Make_Identifier (Loc, Name_uT),
1561 Make_Identifier (Loc, Name_uObject))),
1563 Make_Unchecked_Type_Conversion (Loc, -- entry index
1565 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
1567 Make_Identifier (Loc, Name_uI)),
1569 Make_Identifier (Loc, Name_uP), -- parameter block
1570 New_Reference_To ( -- Asynchronous_Call
1571 RTE (RE_Asynchronous_Call), Loc),
1573 New_Reference_To (Com_Block, Loc)))); -- comm block
1576 -- B := Dummy_Communication_Bloc (Com_Block);
1579 Make_Assignment_Statement (Loc,
1581 Make_Identifier (Loc, Name_uB),
1583 Make_Unchecked_Type_Conversion (Loc,
1586 RTE (RE_Dummy_Communication_Block), Loc),
1588 New_Reference_To (Com_Block, Loc))));
1591 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
1594 -- Protected_Entry_Call (
1596 -- task_entry_index! (I),
1598 -- Conditional_Call,
1601 -- where T is the task object, I is the entry index, P are the
1602 -- wrapped parameters and F is the status flag.
1605 Make_Procedure_Call_Statement (Loc,
1607 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
1608 Parameter_Associations =>
1611 Make_Selected_Component (Loc, -- T._task_id
1613 Make_Identifier (Loc, Name_uT),
1615 Make_Identifier (Loc, Name_uTask_Id)),
1617 Make_Unchecked_Type_Conversion (Loc, -- entry index
1619 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
1621 Make_Identifier (Loc, Name_uI)),
1623 Make_Identifier (Loc, Name_uP), -- parameter block
1624 New_Reference_To ( -- Asynchronous_Call
1625 RTE (RE_Asynchronous_Call), Loc),
1626 Make_Identifier (Loc, Name_uF)))); -- status flag
1631 Make_Subprogram_Body (Loc,
1633 Make_Disp_Asynchronous_Select_Spec (Typ),
1636 Handled_Statement_Sequence =>
1637 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
1638 end Make_Disp_Asynchronous_Select_Body;
1640 ----------------------------------------
1641 -- Make_Disp_Asynchronous_Select_Spec --
1642 ----------------------------------------
1644 function Make_Disp_Asynchronous_Select_Spec
1645 (Typ : Entity_Id) return Node_Id
1647 Loc : constant Source_Ptr := Sloc (Typ);
1648 Def_Id : constant Node_Id :=
1649 Make_Defining_Identifier (Loc,
1650 Name_uDisp_Asynchronous_Select);
1651 Params : constant List_Id := New_List;
1654 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1656 -- T : in out Typ; -- Object parameter
1657 -- S : Integer; -- Primitive operation slot
1658 -- P : Address; -- Wrapped parameters
1659 -- B : out Dummy_Communication_Block; -- Communication block dummy
1660 -- F : out Boolean; -- Status flag
1662 Append_List_To (Params, New_List (
1664 Make_Parameter_Specification (Loc,
1665 Defining_Identifier =>
1666 Make_Defining_Identifier (Loc, Name_uT),
1668 New_Reference_To (Typ, Loc),
1670 Out_Present => True),
1672 Make_Parameter_Specification (Loc,
1673 Defining_Identifier =>
1674 Make_Defining_Identifier (Loc, Name_uS),
1676 New_Reference_To (Standard_Integer, Loc)),
1678 Make_Parameter_Specification (Loc,
1679 Defining_Identifier =>
1680 Make_Defining_Identifier (Loc, Name_uP),
1682 New_Reference_To (RTE (RE_Address), Loc)),
1684 Make_Parameter_Specification (Loc,
1685 Defining_Identifier =>
1686 Make_Defining_Identifier (Loc, Name_uB),
1688 New_Reference_To (RTE (RE_Dummy_Communication_Block), Loc),
1689 Out_Present => True),
1691 Make_Parameter_Specification (Loc,
1692 Defining_Identifier =>
1693 Make_Defining_Identifier (Loc, Name_uF),
1695 New_Reference_To (Standard_Boolean, Loc),
1696 Out_Present => True)));
1699 Make_Procedure_Specification (Loc,
1700 Defining_Unit_Name => Def_Id,
1701 Parameter_Specifications => Params);
1702 end Make_Disp_Asynchronous_Select_Spec;
1704 ---------------------------------------
1705 -- Make_Disp_Conditional_Select_Body --
1706 ---------------------------------------
1708 function Make_Disp_Conditional_Select_Body
1709 (Typ : Entity_Id) return Node_Id
1711 Loc : constant Source_Ptr := Sloc (Typ);
1712 Blk_Nam : Entity_Id;
1713 Conc_Typ : Entity_Id := Empty;
1714 Decls : constant List_Id := New_List;
1716 Stmts : constant List_Id := New_List;
1719 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1721 -- Null body is generated for interface types
1723 if Is_Interface (Typ) then
1725 Make_Subprogram_Body (Loc,
1727 Make_Disp_Conditional_Select_Spec (Typ),
1730 Handled_Statement_Sequence =>
1731 Make_Handled_Sequence_Of_Statements (Loc,
1732 New_List (Make_Null_Statement (Loc))));
1735 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1737 if Is_Concurrent_Record_Type (Typ) then
1738 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1743 -- where I will be used to capture the entry index of the primitive
1744 -- wrapper at position S.
1747 Make_Object_Declaration (Loc,
1748 Defining_Identifier =>
1749 Make_Defining_Identifier (Loc, Name_uI),
1750 Object_Definition =>
1751 New_Reference_To (Standard_Integer, Loc)));
1754 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
1756 -- if C = POK_Procedure
1757 -- or else C = POK_Protected_Procedure
1758 -- or else C = POK_Task_Procedure;
1764 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
1767 -- Bnn : Communication_Block;
1769 -- where Bnn is the name of the communication block used in
1770 -- the call to Protected_Entry_Call.
1772 Blk_Nam := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1775 Make_Object_Declaration (Loc,
1776 Defining_Identifier =>
1778 Object_Definition =>
1779 New_Reference_To (RTE (RE_Communication_Block), Loc)));
1782 -- I := Get_Entry_Index (tag! (<type>VP), S);
1784 -- I is the entry index and S is the dispatch table slot
1787 Make_Assignment_Statement (Loc,
1789 Make_Identifier (Loc, Name_uI),
1791 Make_Function_Call (Loc,
1792 Name => New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
1793 Parameter_Associations => New_List (
1794 Unchecked_Convert_To (RTE (RE_Tag),
1795 New_Reference_To (DT_Ptr, Loc)),
1796 Make_Identifier (Loc, Name_uS)))));
1798 if Ekind (Conc_Typ) = E_Protected_Type then
1801 -- Protected_Entry_Call (
1802 -- T._object'access,
1803 -- protected_entry_index! (I),
1805 -- Conditional_Call,
1808 -- where T is the protected object, I is the entry index, P are
1809 -- the wrapped parameters and Bnn is the name of the communication
1813 Make_Procedure_Call_Statement (Loc,
1815 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1816 Parameter_Associations =>
1819 Make_Attribute_Reference (Loc, -- T._object'access
1821 Name_Unchecked_Access,
1823 Make_Selected_Component (Loc,
1825 Make_Identifier (Loc, Name_uT),
1827 Make_Identifier (Loc, Name_uObject))),
1829 Make_Unchecked_Type_Conversion (Loc, -- entry index
1831 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
1833 Make_Identifier (Loc, Name_uI)),
1835 Make_Identifier (Loc, Name_uP), -- parameter block
1836 New_Reference_To ( -- Conditional_Call
1837 RTE (RE_Conditional_Call), Loc),
1838 New_Reference_To ( -- Bnn
1842 -- F := not Cancelled (Bnn);
1844 -- where F is the success flag. The status of Cancelled is negated
1845 -- in order to match the behaviour of the version for task types.
1848 Make_Assignment_Statement (Loc,
1850 Make_Identifier (Loc, Name_uF),
1854 Make_Function_Call (Loc,
1856 New_Reference_To (RTE (RE_Cancelled), Loc),
1857 Parameter_Associations =>
1859 New_Reference_To (Blk_Nam, Loc))))));
1861 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
1864 -- Protected_Entry_Call (
1866 -- task_entry_index! (I),
1868 -- Conditional_Call,
1871 -- where T is the task object, I is the entry index, P are the
1872 -- wrapped parameters and F is the status flag.
1875 Make_Procedure_Call_Statement (Loc,
1877 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
1878 Parameter_Associations =>
1881 Make_Selected_Component (Loc, -- T._task_id
1883 Make_Identifier (Loc, Name_uT),
1885 Make_Identifier (Loc, Name_uTask_Id)),
1887 Make_Unchecked_Type_Conversion (Loc, -- entry index
1889 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
1891 Make_Identifier (Loc, Name_uI)),
1893 Make_Identifier (Loc, Name_uP), -- parameter block
1894 New_Reference_To ( -- Conditional_Call
1895 RTE (RE_Conditional_Call), Loc),
1896 Make_Identifier (Loc, Name_uF)))); -- status flag
1901 Make_Subprogram_Body (Loc,
1903 Make_Disp_Conditional_Select_Spec (Typ),
1906 Handled_Statement_Sequence =>
1907 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
1908 end Make_Disp_Conditional_Select_Body;
1910 ---------------------------------------
1911 -- Make_Disp_Conditional_Select_Spec --
1912 ---------------------------------------
1914 function Make_Disp_Conditional_Select_Spec
1915 (Typ : Entity_Id) return Node_Id
1917 Loc : constant Source_Ptr := Sloc (Typ);
1918 Def_Id : constant Node_Id :=
1919 Make_Defining_Identifier (Loc,
1920 Name_uDisp_Conditional_Select);
1921 Params : constant List_Id := New_List;
1924 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1926 -- T : in out Typ; -- Object parameter
1927 -- S : Integer; -- Primitive operation slot
1928 -- P : Address; -- Wrapped parameters
1929 -- C : out Prim_Op_Kind; -- Call kind
1930 -- F : out Boolean; -- Status flag
1932 Append_List_To (Params, New_List (
1934 Make_Parameter_Specification (Loc,
1935 Defining_Identifier =>
1936 Make_Defining_Identifier (Loc, Name_uT),
1938 New_Reference_To (Typ, Loc),
1940 Out_Present => True),
1942 Make_Parameter_Specification (Loc,
1943 Defining_Identifier =>
1944 Make_Defining_Identifier (Loc, Name_uS),
1946 New_Reference_To (Standard_Integer, Loc)),
1948 Make_Parameter_Specification (Loc,
1949 Defining_Identifier =>
1950 Make_Defining_Identifier (Loc, Name_uP),
1952 New_Reference_To (RTE (RE_Address), Loc)),
1954 Make_Parameter_Specification (Loc,
1955 Defining_Identifier =>
1956 Make_Defining_Identifier (Loc, Name_uC),
1958 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
1959 Out_Present => True),
1961 Make_Parameter_Specification (Loc,
1962 Defining_Identifier =>
1963 Make_Defining_Identifier (Loc, Name_uF),
1965 New_Reference_To (Standard_Boolean, Loc),
1966 Out_Present => True)));
1969 Make_Procedure_Specification (Loc,
1970 Defining_Unit_Name => Def_Id,
1971 Parameter_Specifications => Params);
1972 end Make_Disp_Conditional_Select_Spec;
1974 -------------------------------------
1975 -- Make_Disp_Get_Prim_Op_Kind_Body --
1976 -------------------------------------
1978 function Make_Disp_Get_Prim_Op_Kind_Body
1979 (Typ : Entity_Id) return Node_Id
1981 Loc : constant Source_Ptr := Sloc (Typ);
1985 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1987 if Is_Interface (Typ) then
1989 Make_Subprogram_Body (Loc,
1991 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
1994 Handled_Statement_Sequence =>
1995 Make_Handled_Sequence_Of_Statements (Loc,
1996 New_List (Make_Null_Statement (Loc))));
1999 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2002 -- C := get_prim_op_kind (tag! (<type>VP), S);
2004 -- where C is the out parameter capturing the call kind and S is the
2005 -- dispatch table slot number.
2008 Make_Subprogram_Body (Loc,
2010 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2013 Handled_Statement_Sequence =>
2014 Make_Handled_Sequence_Of_Statements (Loc,
2016 Make_Assignment_Statement (Loc,
2018 Make_Identifier (Loc, Name_uC),
2020 Make_Function_Call (Loc,
2022 New_Reference_To (RTE (RE_Get_Prim_Op_Kind), Loc),
2023 Parameter_Associations => New_List (
2024 Unchecked_Convert_To (RTE (RE_Tag),
2025 New_Reference_To (DT_Ptr, Loc)),
2026 Make_Identifier (Loc, Name_uS)))))));
2027 end Make_Disp_Get_Prim_Op_Kind_Body;
2029 -------------------------------------
2030 -- Make_Disp_Get_Prim_Op_Kind_Spec --
2031 -------------------------------------
2033 function Make_Disp_Get_Prim_Op_Kind_Spec
2034 (Typ : Entity_Id) return Node_Id
2036 Loc : constant Source_Ptr := Sloc (Typ);
2037 Def_Id : constant Node_Id :=
2038 Make_Defining_Identifier (Loc,
2039 Name_uDisp_Get_Prim_Op_Kind);
2040 Params : constant List_Id := New_List;
2043 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2045 -- T : in out Typ; -- Object parameter
2046 -- S : Integer; -- Primitive operation slot
2047 -- C : out Prim_Op_Kind; -- Call kind
2049 Append_List_To (Params, New_List (
2051 Make_Parameter_Specification (Loc,
2052 Defining_Identifier =>
2053 Make_Defining_Identifier (Loc, Name_uT),
2055 New_Reference_To (Typ, Loc),
2057 Out_Present => True),
2059 Make_Parameter_Specification (Loc,
2060 Defining_Identifier =>
2061 Make_Defining_Identifier (Loc, Name_uS),
2063 New_Reference_To (Standard_Integer, Loc)),
2065 Make_Parameter_Specification (Loc,
2066 Defining_Identifier =>
2067 Make_Defining_Identifier (Loc, Name_uC),
2069 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2070 Out_Present => True)));
2073 Make_Procedure_Specification (Loc,
2074 Defining_Unit_Name => Def_Id,
2075 Parameter_Specifications => Params);
2076 end Make_Disp_Get_Prim_Op_Kind_Spec;
2078 --------------------------------
2079 -- Make_Disp_Get_Task_Id_Body --
2080 --------------------------------
2082 function Make_Disp_Get_Task_Id_Body
2083 (Typ : Entity_Id) return Node_Id
2085 Loc : constant Source_Ptr := Sloc (Typ);
2089 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2091 if Is_Concurrent_Record_Type (Typ)
2092 and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
2095 -- return To_Address (_T._task_id);
2098 Make_Simple_Return_Statement (Loc,
2100 Make_Unchecked_Type_Conversion (Loc,
2102 New_Reference_To (RTE (RE_Address), Loc),
2104 Make_Selected_Component (Loc,
2106 Make_Identifier (Loc, Name_uT),
2108 Make_Identifier (Loc, Name_uTask_Id))));
2110 -- A null body is constructed for non-task types
2114 -- return Null_Address;
2117 Make_Simple_Return_Statement (Loc,
2119 New_Reference_To (RTE (RE_Null_Address), Loc));
2123 Make_Subprogram_Body (Loc,
2125 Make_Disp_Get_Task_Id_Spec (Typ),
2128 Handled_Statement_Sequence =>
2129 Make_Handled_Sequence_Of_Statements (Loc,
2131 end Make_Disp_Get_Task_Id_Body;
2133 --------------------------------
2134 -- Make_Disp_Get_Task_Id_Spec --
2135 --------------------------------
2137 function Make_Disp_Get_Task_Id_Spec
2138 (Typ : Entity_Id) return Node_Id
2140 Loc : constant Source_Ptr := Sloc (Typ);
2143 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2146 Make_Function_Specification (Loc,
2147 Defining_Unit_Name =>
2148 Make_Defining_Identifier (Loc, Name_uDisp_Get_Task_Id),
2149 Parameter_Specifications => New_List (
2150 Make_Parameter_Specification (Loc,
2151 Defining_Identifier =>
2152 Make_Defining_Identifier (Loc, Name_uT),
2154 New_Reference_To (Typ, Loc))),
2155 Result_Definition =>
2156 New_Reference_To (RTE (RE_Address), Loc));
2157 end Make_Disp_Get_Task_Id_Spec;
2159 ---------------------------------
2160 -- Make_Disp_Timed_Select_Body --
2161 ---------------------------------
2163 function Make_Disp_Timed_Select_Body
2164 (Typ : Entity_Id) return Node_Id
2166 Loc : constant Source_Ptr := Sloc (Typ);
2167 Conc_Typ : Entity_Id := Empty;
2168 Decls : constant List_Id := New_List;
2170 Stmts : constant List_Id := New_List;
2173 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2175 -- Null body is generated for interface types
2177 if Is_Interface (Typ) then
2179 Make_Subprogram_Body (Loc,
2181 Make_Disp_Timed_Select_Spec (Typ),
2184 Handled_Statement_Sequence =>
2185 Make_Handled_Sequence_Of_Statements (Loc,
2186 New_List (Make_Null_Statement (Loc))));
2189 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2191 if Is_Concurrent_Record_Type (Typ) then
2192 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2197 -- where I will be used to capture the entry index of the primitive
2198 -- wrapper at position S.
2201 Make_Object_Declaration (Loc,
2202 Defining_Identifier =>
2203 Make_Defining_Identifier (Loc, Name_uI),
2204 Object_Definition =>
2205 New_Reference_To (Standard_Integer, Loc)));
2208 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
2210 -- if C = POK_Procedure
2211 -- or else C = POK_Protected_Procedure
2212 -- or else C = POK_Task_Procedure;
2218 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
2221 -- I := Get_Entry_Index (tag! (<type>VP), S);
2223 -- I is the entry index and S is the dispatch table slot
2226 Make_Assignment_Statement (Loc,
2228 Make_Identifier (Loc, Name_uI),
2230 Make_Function_Call (Loc,
2231 Name => New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
2232 Parameter_Associations => New_List (
2233 Unchecked_Convert_To (RTE (RE_Tag),
2234 New_Reference_To (DT_Ptr, Loc)),
2235 Make_Identifier (Loc, Name_uS)))));
2237 if Ekind (Conc_Typ) = E_Protected_Type then
2240 -- Timed_Protected_Entry_Call (
2241 -- T._object'access,
2242 -- protected_entry_index! (I),
2248 -- where T is the protected object, I is the entry index, P are
2249 -- the wrapped parameters, D is the delay amount, M is the delay
2250 -- mode and F is the status flag.
2253 Make_Procedure_Call_Statement (Loc,
2255 New_Reference_To (RTE (RE_Timed_Protected_Entry_Call), Loc),
2256 Parameter_Associations =>
2259 Make_Attribute_Reference (Loc, -- T._object'access
2261 Name_Unchecked_Access,
2263 Make_Selected_Component (Loc,
2265 Make_Identifier (Loc, Name_uT),
2267 Make_Identifier (Loc, Name_uObject))),
2269 Make_Unchecked_Type_Conversion (Loc, -- entry index
2271 New_Reference_To (RTE (RE_Protected_Entry_Index), Loc),
2273 Make_Identifier (Loc, Name_uI)),
2275 Make_Identifier (Loc, Name_uP), -- parameter block
2276 Make_Identifier (Loc, Name_uD), -- delay
2277 Make_Identifier (Loc, Name_uM), -- delay mode
2278 Make_Identifier (Loc, Name_uF)))); -- status flag
2281 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2284 -- Timed_Task_Entry_Call (
2286 -- task_entry_index! (I),
2292 -- where T is the task object, I is the entry index, P are the
2293 -- wrapped parameters, D is the delay amount, M is the delay
2294 -- mode and F is the status flag.
2297 Make_Procedure_Call_Statement (Loc,
2299 New_Reference_To (RTE (RE_Timed_Task_Entry_Call), Loc),
2300 Parameter_Associations =>
2303 Make_Selected_Component (Loc, -- T._task_id
2305 Make_Identifier (Loc, Name_uT),
2307 Make_Identifier (Loc, Name_uTask_Id)),
2309 Make_Unchecked_Type_Conversion (Loc, -- entry index
2311 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2313 Make_Identifier (Loc, Name_uI)),
2315 Make_Identifier (Loc, Name_uP), -- parameter block
2316 Make_Identifier (Loc, Name_uD), -- delay
2317 Make_Identifier (Loc, Name_uM), -- delay mode
2318 Make_Identifier (Loc, Name_uF)))); -- status flag
2323 Make_Subprogram_Body (Loc,
2325 Make_Disp_Timed_Select_Spec (Typ),
2328 Handled_Statement_Sequence =>
2329 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2330 end Make_Disp_Timed_Select_Body;
2332 ---------------------------------
2333 -- Make_Disp_Timed_Select_Spec --
2334 ---------------------------------
2336 function Make_Disp_Timed_Select_Spec
2337 (Typ : Entity_Id) return Node_Id
2339 Loc : constant Source_Ptr := Sloc (Typ);
2340 Def_Id : constant Node_Id :=
2341 Make_Defining_Identifier (Loc,
2342 Name_uDisp_Timed_Select);
2343 Params : constant List_Id := New_List;
2346 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2348 -- T : in out Typ; -- Object parameter
2349 -- S : Integer; -- Primitive operation slot
2350 -- P : Address; -- Wrapped parameters
2351 -- D : Duration; -- Delay
2352 -- M : Integer; -- Delay Mode
2353 -- C : out Prim_Op_Kind; -- Call kind
2354 -- F : out Boolean; -- Status flag
2356 Append_List_To (Params, New_List (
2358 Make_Parameter_Specification (Loc,
2359 Defining_Identifier =>
2360 Make_Defining_Identifier (Loc, Name_uT),
2362 New_Reference_To (Typ, Loc),
2364 Out_Present => True),
2366 Make_Parameter_Specification (Loc,
2367 Defining_Identifier =>
2368 Make_Defining_Identifier (Loc, Name_uS),
2370 New_Reference_To (Standard_Integer, Loc)),
2372 Make_Parameter_Specification (Loc,
2373 Defining_Identifier =>
2374 Make_Defining_Identifier (Loc, Name_uP),
2376 New_Reference_To (RTE (RE_Address), Loc)),
2378 Make_Parameter_Specification (Loc,
2379 Defining_Identifier =>
2380 Make_Defining_Identifier (Loc, Name_uD),
2382 New_Reference_To (Standard_Duration, Loc)),
2384 Make_Parameter_Specification (Loc,
2385 Defining_Identifier =>
2386 Make_Defining_Identifier (Loc, Name_uM),
2388 New_Reference_To (Standard_Integer, Loc)),
2390 Make_Parameter_Specification (Loc,
2391 Defining_Identifier =>
2392 Make_Defining_Identifier (Loc, Name_uC),
2394 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2395 Out_Present => True)));
2398 Make_Parameter_Specification (Loc,
2399 Defining_Identifier =>
2400 Make_Defining_Identifier (Loc, Name_uF),
2402 New_Reference_To (Standard_Boolean, Loc),
2403 Out_Present => True));
2406 Make_Procedure_Specification (Loc,
2407 Defining_Unit_Name => Def_Id,
2408 Parameter_Specifications => Params);
2409 end Make_Disp_Timed_Select_Spec;
2415 -- The frontend supports two models for expanding dispatch tables
2416 -- associated with library-level defined tagged types: statically
2417 -- and non-statically allocated dispatch tables. In the former case
2418 -- the object containing the dispatch table is constant and it is
2419 -- initialized by means of a positional aggregate. In the latter case,
2420 -- the object containing the dispatch table is a variable which is
2421 -- initialized by means of assignments.
2423 -- In case of locally defined tagged types, the object containing the
2424 -- object containing the dispatch table is always a variable (instead
2425 -- of a constant). This is currently required to give support to late
2426 -- overriding of primitives. For example:
2428 -- procedure Example is
2430 -- type T1 is tagged null record;
2431 -- procedure Prim (O : T1);
2434 -- type T2 is new Pkg.T1 with null record;
2435 -- procedure Prim (X : T2) is -- late overriding
2441 function Make_DT (Typ : Entity_Id; N : Node_Id := Empty) return List_Id is
2442 Loc : constant Source_Ptr := Sloc (Typ);
2444 Max_Predef_Prims : constant Int :=
2448 (Parent (RTE (RE_Max_Predef_Prims)))));
2450 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id);
2451 -- Verify that all non-tagged types in the profile of a subprogram
2452 -- are frozen at the point the subprogram is frozen. This enforces
2453 -- the rule on RM 13.14 (14) as modified by AI05-019. At the point a
2454 -- subprogram is frozen, enough must be known about it to build the
2455 -- activation record for it, which requires at least that the size of
2456 -- all parameters be known. Controlling arguments are by-reference,
2457 -- and therefore the rule only applies to non-tagged types.
2458 -- Typical violation of the rule involves an object declaration that
2459 -- freezes a tagged type, when one of its primitive operations has a
2460 -- type in its profile whose full view has not been analyzed yet.
2462 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id);
2463 -- Export the dispatch table entity DT of tagged type Typ. Required to
2464 -- generate forward references and statically allocate the table.
2466 procedure Make_Secondary_DT
2470 Iface_DT_Ptr : Entity_Id;
2472 -- Ada 2005 (AI-251): Expand the declarations for the Secondary Dispatch
2473 -- Table of Typ associated with Iface (each abstract interface of Typ
2474 -- has a secondary dispatch table). The arguments Typ, Ancestor_Typ
2475 -- and Suffix_Index are used to generate an unique external name which
2476 -- is added at the end of Acc_Disp_Tables; this external name will be
2477 -- used later by the subprogram Exp_Ch3.Build_Init_Procedure.
2479 ------------------------------
2480 -- Check_Premature_Freezing --
2481 ------------------------------
2483 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id) is
2486 and then Is_Private_Type (Typ)
2487 and then No (Full_View (Typ))
2488 and then not Is_Generic_Type (Typ)
2489 and then not Is_Tagged_Type (Typ)
2490 and then not Is_Frozen (Typ)
2492 Error_Msg_Sloc := Sloc (Subp);
2494 ("declaration must appear after completion of type &", N, Typ);
2496 ("\which is an untagged type in the profile of"
2497 & " primitive operation & declared#",
2500 end Check_Premature_Freezing;
2506 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id) is
2508 Set_Is_Statically_Allocated (DT);
2509 Set_Is_True_Constant (DT);
2510 Set_Is_Exported (DT);
2512 pragma Assert (Present (Dispatch_Table_Wrapper (Typ)));
2513 Get_External_Name (Dispatch_Table_Wrapper (Typ), True);
2514 Set_Interface_Name (DT,
2515 Make_String_Literal (Loc,
2516 Strval => String_From_Name_Buffer));
2518 -- Ensure proper Sprint output of this implicit importation
2520 Set_Is_Internal (DT);
2524 -----------------------
2525 -- Make_Secondary_DT --
2526 -----------------------
2528 procedure Make_Secondary_DT
2532 Iface_DT_Ptr : Entity_Id;
2535 Loc : constant Source_Ptr := Sloc (Typ);
2536 Name_DT : constant Name_Id := New_Internal_Name ('T');
2537 Iface_DT : constant Entity_Id :=
2538 Make_Defining_Identifier (Loc, Name_DT);
2539 Name_Predef_Prims : constant Name_Id := New_Internal_Name ('R');
2540 Predef_Prims : constant Entity_Id :=
2541 Make_Defining_Identifier (Loc,
2543 DT_Constr_List : List_Id;
2544 DT_Aggr_List : List_Id;
2545 Empty_DT : Boolean := False;
2546 Nb_Predef_Prims : Nat := 0;
2550 OSD_Aggr_List : List_Id;
2553 Prim_Elmt : Elmt_Id;
2554 Prim_Ops_Aggr_List : List_Id;
2557 -- Handle cases in which we do not generate statically allocated
2560 if not Building_Static_DT (Typ) then
2561 Set_Ekind (Predef_Prims, E_Variable);
2562 Set_Is_Statically_Allocated (Predef_Prims);
2564 Set_Ekind (Iface_DT, E_Variable);
2565 Set_Is_Statically_Allocated (Iface_DT);
2567 -- Statically allocated dispatch tables and related entities are
2571 Set_Ekind (Predef_Prims, E_Constant);
2572 Set_Is_Statically_Allocated (Predef_Prims);
2573 Set_Is_True_Constant (Predef_Prims);
2575 Set_Ekind (Iface_DT, E_Constant);
2576 Set_Is_Statically_Allocated (Iface_DT);
2577 Set_Is_True_Constant (Iface_DT);
2580 -- Generate code to create the storage for the Dispatch_Table object.
2581 -- If the number of primitives of Typ is 0 we reserve a dummy single
2582 -- entry for its DT because at run-time the pointer to this dummy
2583 -- entry will be used as the tag.
2585 Nb_Prim := UI_To_Int (DT_Entry_Count (AI_Tag));
2594 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
2595 -- (predef-prim-op-thunk-1'address,
2596 -- predef-prim-op-thunk-2'address,
2598 -- predef-prim-op-thunk-n'address);
2599 -- for Predef_Prims'Alignment use Address'Alignment
2601 -- Stage 1: Calculate the number of predefined primitives
2603 if not Building_Static_DT (Typ) then
2604 Nb_Predef_Prims := Max_Predef_Prims;
2606 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2607 while Present (Prim_Elmt) loop
2608 Prim := Node (Prim_Elmt);
2610 if Is_Predefined_Dispatching_Operation (Prim)
2611 and then not Is_Abstract_Subprogram (Prim)
2613 Pos := UI_To_Int (DT_Position (Prim));
2615 if Pos > Nb_Predef_Prims then
2616 Nb_Predef_Prims := Pos;
2620 Next_Elmt (Prim_Elmt);
2624 -- Stage 2: Create the thunks associated with the predefined
2625 -- primitives and save their entity to fill the aggregate.
2628 Prim_Table : array (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
2629 Thunk_Id : Entity_Id;
2630 Thunk_Code : Node_Id;
2633 Prim_Ops_Aggr_List := New_List;
2634 Prim_Table := (others => Empty);
2636 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2637 while Present (Prim_Elmt) loop
2638 Prim := Node (Prim_Elmt);
2640 if Is_Predefined_Dispatching_Operation (Prim)
2641 and then not Is_Abstract_Subprogram (Prim)
2642 and then not Present (Prim_Table
2643 (UI_To_Int (DT_Position (Prim))))
2645 while Present (Alias (Prim)) loop
2646 Prim := Alias (Prim);
2649 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
2651 if Present (Thunk_Id) then
2652 Append_To (Result, Thunk_Code);
2653 Prim_Table (UI_To_Int (DT_Position (Prim))) := Thunk_Id;
2657 Next_Elmt (Prim_Elmt);
2660 for J in Prim_Table'Range loop
2661 if Present (Prim_Table (J)) then
2663 Make_Attribute_Reference (Loc,
2664 Prefix => New_Reference_To (Prim_Table (J), Loc),
2665 Attribute_Name => Name_Address);
2668 New_Reference_To (RTE (RE_Null_Address), Loc);
2671 Append_To (Prim_Ops_Aggr_List, New_Node);
2675 Make_Object_Declaration (Loc,
2676 Defining_Identifier => Predef_Prims,
2677 Constant_Present => Building_Static_DT (Typ),
2678 Aliased_Present => True,
2679 Object_Definition =>
2680 New_Reference_To (RTE (RE_Address_Array), Loc),
2681 Expression => Make_Aggregate (Loc,
2682 Expressions => Prim_Ops_Aggr_List)));
2685 Make_Attribute_Definition_Clause (Loc,
2686 Name => New_Reference_To (Predef_Prims, Loc),
2687 Chars => Name_Alignment,
2689 Make_Attribute_Reference (Loc,
2691 New_Reference_To (RTE (RE_Integer_Address), Loc),
2692 Attribute_Name => Name_Alignment)));
2697 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
2698 -- (OSD_Table => (1 => <value>,
2702 -- Iface_DT : Dispatch_Table (Nb_Prims) :=
2703 -- ([ Signature => <sig-value> ],
2704 -- Tag_Kind => <tag_kind-value>,
2705 -- Predef_Prims => Predef_Prims'Address,
2706 -- Offset_To_Top => 0,
2707 -- OSD => OSD'Address,
2708 -- Prims_Ptr => (prim-op-1'address,
2709 -- prim-op-2'address,
2711 -- prim-op-n'address));
2713 -- Stage 3: Initialize the discriminant and the record components
2715 DT_Constr_List := New_List;
2716 DT_Aggr_List := New_List;
2718 -- Nb_Prim. If the tagged type has no primitives we add a dummy
2719 -- slot whose address will be the tag of this type.
2722 New_Node := Make_Integer_Literal (Loc, 1);
2724 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
2727 Append_To (DT_Constr_List, New_Node);
2728 Append_To (DT_Aggr_List, New_Copy (New_Node));
2732 if RTE_Record_Component_Available (RE_Signature) then
2733 Append_To (DT_Aggr_List,
2734 New_Reference_To (RTE (RE_Secondary_DT), Loc));
2739 if RTE_Record_Component_Available (RE_Tag_Kind) then
2740 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
2745 Append_To (DT_Aggr_List,
2746 Make_Attribute_Reference (Loc,
2747 Prefix => New_Reference_To (Predef_Prims, Loc),
2748 Attribute_Name => Name_Address));
2750 -- Note: The correct value of Offset_To_Top will be set by the init
2753 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
2755 -- Generate the Object Specific Data table required to dispatch calls
2756 -- through synchronized interfaces.
2759 or else Is_Abstract_Type (Typ)
2760 or else Is_Controlled (Typ)
2761 or else Restriction_Active (No_Dispatching_Calls)
2762 or else not Is_Limited_Type (Typ)
2763 or else not Has_Abstract_Interfaces (Typ)
2765 -- No OSD table required
2767 Append_To (DT_Aggr_List,
2768 New_Reference_To (RTE (RE_Null_Address), Loc));
2771 OSD_Aggr_List := New_List;
2774 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
2776 Prim_Alias : Entity_Id;
2777 Prim_Elmt : Elmt_Id;
2783 Prim_Table := (others => Empty);
2784 Prim_Alias := Empty;
2786 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2787 while Present (Prim_Elmt) loop
2788 Prim := Node (Prim_Elmt);
2790 if Present (Abstract_Interface_Alias (Prim))
2791 and then Find_Dispatching_Type
2792 (Abstract_Interface_Alias (Prim)) = Iface
2794 Prim_Alias := Abstract_Interface_Alias (Prim);
2797 while Present (Alias (E)) loop
2801 Pos := UI_To_Int (DT_Position (Prim_Alias));
2803 if Present (Prim_Table (Pos)) then
2804 pragma Assert (Prim_Table (Pos) = E);
2808 Prim_Table (Pos) := E;
2810 Append_To (OSD_Aggr_List,
2811 Make_Component_Association (Loc,
2812 Choices => New_List (
2813 Make_Integer_Literal (Loc,
2814 DT_Position (Prim_Alias))),
2816 Make_Integer_Literal (Loc,
2817 DT_Position (Alias (Prim)))));
2823 Next_Elmt (Prim_Elmt);
2825 pragma Assert (Count = Nb_Prim);
2828 OSD := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
2831 Make_Object_Declaration (Loc,
2832 Defining_Identifier => OSD,
2833 Object_Definition =>
2834 Make_Subtype_Indication (Loc,
2836 New_Reference_To (RTE (RE_Object_Specific_Data), Loc),
2838 Make_Index_Or_Discriminant_Constraint (Loc,
2839 Constraints => New_List (
2840 Make_Integer_Literal (Loc, Nb_Prim)))),
2841 Expression => Make_Aggregate (Loc,
2842 Component_Associations => New_List (
2843 Make_Component_Association (Loc,
2844 Choices => New_List (
2846 (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
2848 Make_Integer_Literal (Loc, Nb_Prim)),
2850 Make_Component_Association (Loc,
2851 Choices => New_List (
2853 (RTE_Record_Component (RE_OSD_Table), Loc)),
2854 Expression => Make_Aggregate (Loc,
2855 Component_Associations => OSD_Aggr_List))))));
2858 Make_Attribute_Definition_Clause (Loc,
2859 Name => New_Reference_To (OSD, Loc),
2860 Chars => Name_Alignment,
2862 Make_Attribute_Reference (Loc,
2864 New_Reference_To (RTE (RE_Integer_Address), Loc),
2865 Attribute_Name => Name_Alignment)));
2867 -- In secondary dispatch tables the Typeinfo component contains
2868 -- the address of the Object Specific Data (see a-tags.ads)
2870 Append_To (DT_Aggr_List,
2871 Make_Attribute_Reference (Loc,
2872 Prefix => New_Reference_To (OSD, Loc),
2873 Attribute_Name => Name_Address));
2876 -- Initialize the table of primitive operations
2878 Prim_Ops_Aggr_List := New_List;
2881 Append_To (Prim_Ops_Aggr_List,
2882 New_Reference_To (RTE (RE_Null_Address), Loc));
2884 elsif Is_Abstract_Type (Typ)
2885 or else not Building_Static_DT (Typ)
2887 for J in 1 .. Nb_Prim loop
2888 Append_To (Prim_Ops_Aggr_List,
2889 New_Reference_To (RTE (RE_Null_Address), Loc));
2894 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
2896 Thunk_Code : Node_Id;
2897 Thunk_Id : Entity_Id;
2900 Prim_Table := (others => Empty);
2902 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2903 while Present (Prim_Elmt) loop
2904 Prim := Node (Prim_Elmt);
2906 if not Is_Predefined_Dispatching_Operation (Prim)
2907 and then Present (Abstract_Interface_Alias (Prim))
2908 and then not Is_Abstract_Subprogram (Alias (Prim))
2909 and then not Is_Imported (Alias (Prim))
2910 and then Find_Dispatching_Type
2911 (Abstract_Interface_Alias (Prim)) = Iface
2913 -- Generate the code of the thunk only if the abstract
2914 -- interface type is not an immediate ancestor of
2915 -- Tagged_Type; otherwise the DT associated with the
2916 -- interface is the primary DT.
2918 and then not Is_Parent (Iface, Typ)
2920 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
2922 if Present (Thunk_Id) then
2925 (DT_Position (Abstract_Interface_Alias (Prim)));
2927 Prim_Table (Pos) := Thunk_Id;
2928 Append_To (Result, Thunk_Code);
2932 Next_Elmt (Prim_Elmt);
2935 for J in Prim_Table'Range loop
2936 if Present (Prim_Table (J)) then
2938 Make_Attribute_Reference (Loc,
2939 Prefix => New_Reference_To (Prim_Table (J), Loc),
2940 Attribute_Name => Name_Address);
2943 New_Reference_To (RTE (RE_Null_Address), Loc);
2946 Append_To (Prim_Ops_Aggr_List, New_Node);
2951 Append_To (DT_Aggr_List,
2952 Make_Aggregate (Loc,
2953 Expressions => Prim_Ops_Aggr_List));
2956 Make_Object_Declaration (Loc,
2957 Defining_Identifier => Iface_DT,
2958 Aliased_Present => True,
2959 Object_Definition =>
2960 Make_Subtype_Indication (Loc,
2961 Subtype_Mark => New_Reference_To
2962 (RTE (RE_Dispatch_Table_Wrapper), Loc),
2963 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
2964 Constraints => DT_Constr_List)),
2966 Expression => Make_Aggregate (Loc,
2967 Expressions => DT_Aggr_List)));
2970 Make_Attribute_Definition_Clause (Loc,
2971 Name => New_Reference_To (Iface_DT, Loc),
2972 Chars => Name_Alignment,
2974 Make_Attribute_Reference (Loc,
2976 New_Reference_To (RTE (RE_Integer_Address), Loc),
2977 Attribute_Name => Name_Alignment)));
2979 -- Generate code to create the pointer to the dispatch table
2981 -- Iface_DT_Ptr : Tag := Tag!(DT'Address);
2984 Make_Object_Declaration (Loc,
2985 Defining_Identifier => Iface_DT_Ptr,
2986 Constant_Present => True,
2987 Object_Definition =>
2988 New_Reference_To (RTE (RE_Interface_Tag), Loc),
2990 Unchecked_Convert_To (RTE (RE_Interface_Tag),
2991 Make_Attribute_Reference (Loc,
2993 Make_Selected_Component (Loc,
2994 Prefix => New_Reference_To (Iface_DT, Loc),
2997 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
2998 Attribute_Name => Name_Address))));
3000 end Make_Secondary_DT;
3004 Elab_Code : constant List_Id := New_List;
3005 Result : constant List_Id := New_List;
3006 Tname : constant Name_Id := Chars (Typ);
3008 AI_Ptr_Elmt : Elmt_Id;
3009 AI_Tag_Comp : Elmt_Id;
3010 DT_Aggr_List : List_Id;
3011 DT_Constr_List : List_Id;
3015 Iface_Table_Node : Node_Id;
3016 Name_ITable : Name_Id;
3017 Name_No_Reg : Name_Id;
3018 Nb_Predef_Prims : Nat := 0;
3022 Null_Parent_Tag : Boolean := False;
3023 Num_Ifaces : Nat := 0;
3027 Prim_Elmt : Elmt_Id;
3028 Prim_Ops_Aggr_List : List_Id;
3030 Typ_Comps : Elist_Id;
3031 Typ_Ifaces : Elist_Id;
3032 TSD_Aggr_List : List_Id;
3033 TSD_Tags_List : List_Id;
3035 -- The following name entries are used by Make_DT to generate a number
3036 -- of entities related to a tagged type. These entities may be generated
3037 -- in a scope other than that of the tagged type declaration, and if
3038 -- the entities for two tagged types with the same name happen to be
3039 -- generated in the same scope, we have to take care to use different
3040 -- names. This is achieved by means of a unique serial number appended
3041 -- to each generated entity name.
3043 Name_DT : constant Name_Id :=
3044 New_External_Name (Tname, 'T', Suffix_Index => -1);
3045 Name_Exname : constant Name_Id :=
3046 New_External_Name (Tname, 'E', Suffix_Index => -1);
3047 Name_HT_Link : constant Name_Id :=
3048 New_External_Name (Tname, 'H', Suffix_Index => -1);
3049 Name_Predef_Prims : constant Name_Id :=
3050 New_External_Name (Tname, 'R', Suffix_Index => -1);
3051 Name_SSD : constant Name_Id :=
3052 New_External_Name (Tname, 'S', Suffix_Index => -1);
3053 Name_TSD : constant Name_Id :=
3054 New_External_Name (Tname, 'B', Suffix_Index => -1);
3056 -- Entities built with above names
3058 DT : constant Entity_Id :=
3059 Make_Defining_Identifier (Loc, Name_DT);
3060 Exname : constant Entity_Id :=
3061 Make_Defining_Identifier (Loc, Name_Exname);
3062 HT_Link : constant Entity_Id :=
3063 Make_Defining_Identifier (Loc, Name_HT_Link);
3064 Predef_Prims : constant Entity_Id :=
3065 Make_Defining_Identifier (Loc, Name_Predef_Prims);
3066 SSD : constant Entity_Id :=
3067 Make_Defining_Identifier (Loc, Name_SSD);
3068 TSD : constant Entity_Id :=
3069 Make_Defining_Identifier (Loc, Name_TSD);
3071 -- Start of processing for Make_DT
3074 pragma Assert (Is_Frozen (Typ));
3076 -- Handle cases in which there is no need to build the dispatch table
3078 if Has_Dispatch_Table (Typ)
3079 or else No (Access_Disp_Table (Typ))
3080 or else Is_CPP_Class (Typ)
3084 elsif No_Run_Time_Mode then
3085 Error_Msg_CRT ("tagged types", Typ);
3088 elsif not RTE_Available (RE_Tag) then
3090 Make_Object_Declaration (Loc,
3091 Defining_Identifier => Node (First_Elmt
3092 (Access_Disp_Table (Typ))),
3093 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
3094 Constant_Present => True,
3096 Unchecked_Convert_To (RTE (RE_Tag),
3097 New_Reference_To (RTE (RE_Null_Address), Loc))));
3099 Analyze_List (Result, Suppress => All_Checks);
3100 Error_Msg_CRT ("tagged types", Typ);
3104 -- Ensure that the value of Max_Predef_Prims defined in a-tags is
3105 -- correct. Valid values are 10 under configurable runtime or 15
3106 -- with full runtime.
3108 if RTE_Available (RE_Interface_Data) then
3109 if Max_Predef_Prims /= 15 then
3110 Error_Msg_N ("run-time library configuration error", Typ);
3114 if Max_Predef_Prims /= 10 then
3115 Error_Msg_N ("run-time library configuration error", Typ);
3116 Error_Msg_CRT ("tagged types", Typ);
3121 -- Ensure that all the primitives are frozen. This is only required when
3122 -- building static dispatch tables --- the primitives must be frozen to
3123 -- be referenced (otherwise we have problems with the backend). It is
3124 -- not a requirement with nonstatic dispatch tables because in this case
3125 -- we generate now an empty dispatch table; the extra code required to
3126 -- register the primitives in the slots will be generated later --- when
3127 -- each primitive is frozen (see Freeze_Subprogram).
3129 if Building_Static_DT (Typ)
3130 and then not Is_CPP_Class (Typ)
3133 Save : constant Boolean := Freezing_Library_Level_Tagged_Type;
3134 Prim_Elmt : Elmt_Id;
3138 Freezing_Library_Level_Tagged_Type := True;
3139 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3140 while Present (Prim_Elmt) loop
3141 Frnodes := Freeze_Entity (Node (Prim_Elmt), Loc);
3144 Subp : constant Entity_Id := Node (Prim_Elmt);
3148 F := First_Formal (Subp);
3149 while Present (F) loop
3150 Check_Premature_Freezing (Subp, Etype (F));
3154 Check_Premature_Freezing (Subp, Etype (Subp));
3157 if Present (Frnodes) then
3158 Append_List_To (Result, Frnodes);
3161 Next_Elmt (Prim_Elmt);
3163 Freezing_Library_Level_Tagged_Type := Save;
3167 -- Ada 2005 (AI-251): Build the secondary dispatch tables
3169 if Has_Abstract_Interfaces (Typ) then
3170 Collect_Interface_Components (Typ, Typ_Comps);
3173 AI_Ptr_Elmt := Next_Elmt (First_Elmt (Access_Disp_Table (Typ)));
3175 AI_Tag_Comp := First_Elmt (Typ_Comps);
3176 while Present (AI_Tag_Comp) loop
3180 (Related_Interface (Node (AI_Tag_Comp))),
3181 AI_Tag => Node (AI_Tag_Comp),
3182 Iface_DT_Ptr => Node (AI_Ptr_Elmt),
3185 Suffix_Index := Suffix_Index + 1;
3186 Next_Elmt (AI_Ptr_Elmt);
3187 Next_Elmt (AI_Tag_Comp);
3191 -- Get the _tag entity and the number of primitives of its dispatch
3194 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
3195 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
3197 Set_Is_Statically_Allocated (DT);
3198 Set_Is_Statically_Allocated (SSD);
3199 Set_Is_Statically_Allocated (TSD);
3200 Set_Is_Statically_Allocated (Predef_Prims);
3202 -- Generate code to define the boolean that controls registration, in
3203 -- order to avoid multiple registrations for tagged types defined in
3204 -- multiple-called scopes.
3206 if not Is_Interface (Typ) then
3207 Name_No_Reg := New_External_Name (Tname, 'F', Suffix_Index => -1);
3208 No_Reg := Make_Defining_Identifier (Loc, Name_No_Reg);
3210 Set_Ekind (No_Reg, E_Variable);
3211 Set_Is_Statically_Allocated (No_Reg);
3214 Make_Object_Declaration (Loc,
3215 Defining_Identifier => No_Reg,
3216 Object_Definition => New_Reference_To (Standard_Boolean, Loc),
3217 Expression => New_Reference_To (Standard_True, Loc)));
3220 -- In case of locally defined tagged type we declare the object
3221 -- contanining the dispatch table by means of a variable. Its
3222 -- initialization is done later by means of an assignment. This is
3223 -- required to generate its External_Tag.
3225 if not Building_Static_DT (Typ) then
3228 -- DT : No_Dispatch_Table_Wrapper;
3229 -- for DT'Alignment use Address'Alignment;
3230 -- DT_Ptr : Tag := !Tag (DT.NDT_Prims_Ptr'Address);
3232 if not Has_DT (Typ) then
3234 Make_Object_Declaration (Loc,
3235 Defining_Identifier => DT,
3236 Aliased_Present => True,
3237 Constant_Present => False,
3238 Object_Definition =>
3240 (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
3243 Make_Attribute_Definition_Clause (Loc,
3244 Name => New_Reference_To (DT, Loc),
3245 Chars => Name_Alignment,
3247 Make_Attribute_Reference (Loc,
3249 New_Reference_To (RTE (RE_Integer_Address), Loc),
3250 Attribute_Name => Name_Alignment)));
3253 Make_Object_Declaration (Loc,
3254 Defining_Identifier => DT_Ptr,
3255 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
3256 Constant_Present => True,
3258 Unchecked_Convert_To (RTE (RE_Tag),
3259 Make_Attribute_Reference (Loc,
3261 Make_Selected_Component (Loc,
3262 Prefix => New_Reference_To (DT, Loc),
3265 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
3266 Attribute_Name => Name_Address))));
3269 -- DT : Dispatch_Table_Wrapper (Nb_Prim);
3270 -- for DT'Alignment use Address'Alignment;
3271 -- DT_Ptr : Tag := !Tag (DT.Prims_Ptr'Address);
3274 -- If the tagged type has no primitives we add a dummy slot
3275 -- whose address will be the tag of this type.
3279 New_List (Make_Integer_Literal (Loc, 1));
3282 New_List (Make_Integer_Literal (Loc, Nb_Prim));
3286 Make_Object_Declaration (Loc,
3287 Defining_Identifier => DT,
3288 Aliased_Present => True,
3289 Constant_Present => False,
3290 Object_Definition =>
3291 Make_Subtype_Indication (Loc,
3293 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
3294 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
3295 Constraints => DT_Constr_List))));
3298 Make_Attribute_Definition_Clause (Loc,
3299 Name => New_Reference_To (DT, Loc),
3300 Chars => Name_Alignment,
3302 Make_Attribute_Reference (Loc,
3304 New_Reference_To (RTE (RE_Integer_Address), Loc),
3305 Attribute_Name => Name_Alignment)));
3308 Make_Object_Declaration (Loc,
3309 Defining_Identifier => DT_Ptr,
3310 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
3311 Constant_Present => True,
3313 Unchecked_Convert_To (RTE (RE_Tag),
3314 Make_Attribute_Reference (Loc,
3316 Make_Selected_Component (Loc,
3317 Prefix => New_Reference_To (DT, Loc),
3320 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
3321 Attribute_Name => Name_Address))));
3325 -- Generate: Exname : constant String := full_qualified_name (typ);
3326 -- The type itself may be an anonymous parent type, so use the first
3327 -- subtype to have a user-recognizable name.
3330 Make_Object_Declaration (Loc,
3331 Defining_Identifier => Exname,
3332 Constant_Present => True,
3333 Object_Definition => New_Reference_To (Standard_String, Loc),
3335 Make_String_Literal (Loc,
3336 Full_Qualified_Name (First_Subtype (Typ)))));
3338 Set_Is_Statically_Allocated (Exname);
3339 Set_Is_True_Constant (Exname);
3341 -- Declare the object used by Ada.Tags.Register_Tag
3343 if RTE_Available (RE_Register_Tag) then
3345 Make_Object_Declaration (Loc,
3346 Defining_Identifier => HT_Link,
3347 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc)));
3350 -- Generate code to create the storage for the type specific data object
3351 -- with enough space to store the tags of the ancestors plus the tags
3352 -- of all the implemented interfaces (as described in a-tags.adb).
3354 -- TSD : Type_Specific_Data (I_Depth) :=
3355 -- (Idepth => I_Depth,
3356 -- Access_Level => Type_Access_Level (Typ),
3357 -- Expanded_Name => Cstring_Ptr!(Exname'Address))
3358 -- External_Tag => Cstring_Ptr!(Exname'Address))
3359 -- HT_Link => HT_Link'Address,
3360 -- Transportable => <<boolean-value>>,
3361 -- RC_Offset => <<integer-value>>,
3362 -- [ Interfaces_Table => <<access-value>> ]
3363 -- [ SSD => SSD_Table'Address ]
3364 -- Tags_Table => (0 => null,
3367 -- for TSD'Alignment use Address'Alignment
3369 TSD_Aggr_List := New_List;
3371 -- Idepth: Count ancestors to compute the inheritance depth. For private
3372 -- extensions, always go to the full view in order to compute the real
3373 -- inheritance depth.
3376 Current_Typ : Entity_Id;
3377 Parent_Typ : Entity_Id;
3383 Parent_Typ := Etype (Current_Typ);
3385 if Is_Private_Type (Parent_Typ) then
3386 Parent_Typ := Full_View (Base_Type (Parent_Typ));
3389 exit when Parent_Typ = Current_Typ;
3391 I_Depth := I_Depth + 1;
3392 Current_Typ := Parent_Typ;
3396 Append_To (TSD_Aggr_List,
3397 Make_Integer_Literal (Loc, I_Depth));
3401 Append_To (TSD_Aggr_List,
3402 Make_Integer_Literal (Loc, Type_Access_Level (Typ)));
3406 Append_To (TSD_Aggr_List,
3407 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
3408 Make_Attribute_Reference (Loc,
3409 Prefix => New_Reference_To (Exname, Loc),
3410 Attribute_Name => Name_Address)));
3412 -- External_Tag of a local tagged type
3414 -- <typ>A : constant String :=
3415 -- "Internal tag at 16#tag-addr#: <full-name-of-typ>";
3417 -- The reason we generate this strange name is that we do not want to
3418 -- enter local tagged types in the global hash table used to compute
3419 -- the Internal_Tag attribute for two reasons:
3421 -- 1. It is hard to avoid a tasking race condition for entering the
3422 -- entry into the hash table.
3424 -- 2. It would cause a storage leak, unless we rig up considerable
3425 -- mechanism to remove the entry from the hash table on exit.
3427 -- So what we do is to generate the above external tag name, where the
3428 -- hex address is the address of the local dispatch table (i.e. exactly
3429 -- the value we want if Internal_Tag is computed from this string).
3431 -- Of course this value will only be valid if the tagged type is still
3432 -- in scope, but it clearly must be erroneous to compute the internal
3433 -- tag of a tagged type that is out of scope!
3435 -- We don't do this processing if an explicit external tag has been
3436 -- specified. That's an odd case for which we have already issued a
3437 -- warning, where we will not be able to compute the internal tag.
3439 if not Is_Library_Level_Entity (Typ)
3440 and then not Has_External_Tag_Rep_Clause (Typ)
3443 Exname : constant Entity_Id :=
3444 Make_Defining_Identifier (Loc,
3445 New_External_Name (Tname, 'A'));
3447 Full_Name : constant String_Id :=
3448 Full_Qualified_Name (First_Subtype (Typ));
3449 Str1_Id : String_Id;
3450 Str2_Id : String_Id;
3454 -- Str1 = "Internal tag at 16#";
3457 Store_String_Chars ("Internal tag at 16#");
3458 Str1_Id := End_String;
3461 -- Str2 = "#: <type-full-name>";
3464 Store_String_Chars ("#: ");
3465 Store_String_Chars (Full_Name);
3466 Str2_Id := End_String;
3469 -- Exname : constant String :=
3470 -- Str1 & Address_Image (Tag) & Str2;
3472 if RTE_Available (RE_Address_Image) then
3474 Make_Object_Declaration (Loc,
3475 Defining_Identifier => Exname,
3476 Constant_Present => True,
3477 Object_Definition => New_Reference_To
3478 (Standard_String, Loc),
3480 Make_Op_Concat (Loc,
3482 Make_String_Literal (Loc, Str1_Id),
3484 Make_Op_Concat (Loc,
3486 Make_Function_Call (Loc,
3489 (RTE (RE_Address_Image), Loc),
3490 Parameter_Associations => New_List (
3491 Unchecked_Convert_To (RTE (RE_Address),
3492 New_Reference_To (DT_Ptr, Loc)))),
3494 Make_String_Literal (Loc, Str2_Id)))));
3498 Make_Object_Declaration (Loc,
3499 Defining_Identifier => Exname,
3500 Constant_Present => True,
3501 Object_Definition => New_Reference_To
3502 (Standard_String, Loc),
3504 Make_Op_Concat (Loc,
3506 Make_String_Literal (Loc, Str1_Id),
3508 Make_String_Literal (Loc, Str2_Id))));
3512 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
3513 Make_Attribute_Reference (Loc,
3514 Prefix => New_Reference_To (Exname, Loc),
3515 Attribute_Name => Name_Address));
3518 -- External tag of a library-level tagged type: Check for a definition
3519 -- of External_Tag. The clause is considered only if it applies to this
3520 -- specific tagged type, as opposed to one of its ancestors.
3524 Def : constant Node_Id := Get_Attribute_Definition_Clause (Typ,
3525 Attribute_External_Tag);
3526 Old_Val : String_Id;
3527 New_Val : String_Id;
3531 if not Present (Def)
3532 or else Entity (Name (Def)) /= Typ
3535 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
3536 Make_Attribute_Reference (Loc,
3537 Prefix => New_Reference_To (Exname, Loc),
3538 Attribute_Name => Name_Address));
3540 Old_Val := Strval (Expr_Value_S (Expression (Def)));
3542 -- For the rep clause "for <typ>'external_tag use y" generate:
3544 -- <typ>A : constant string := y;
3546 -- <typ>A'Address is used to set the External_Tag component
3549 -- Create a new nul terminated string if it is not already
3551 if String_Length (Old_Val) > 0
3553 Get_String_Char (Old_Val, String_Length (Old_Val)) = 0
3557 Start_String (Old_Val);
3558 Store_String_Char (Get_Char_Code (ASCII.NUL));
3559 New_Val := End_String;
3562 E := Make_Defining_Identifier (Loc,
3563 New_External_Name (Chars (Typ), 'A'));
3566 Make_Object_Declaration (Loc,
3567 Defining_Identifier => E,
3568 Constant_Present => True,
3569 Object_Definition =>
3570 New_Reference_To (Standard_String, Loc),
3572 Make_String_Literal (Loc, New_Val)));
3575 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
3576 Make_Attribute_Reference (Loc,
3577 Prefix => New_Reference_To (E, Loc),
3578 Attribute_Name => Name_Address));
3583 Append_To (TSD_Aggr_List, New_Node);
3587 if RTE_Available (RE_Register_Tag) then
3588 Append_To (TSD_Aggr_List,
3589 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
3590 Make_Attribute_Reference (Loc,
3591 Prefix => New_Reference_To (HT_Link, Loc),
3592 Attribute_Name => Name_Address)));
3594 Append_To (TSD_Aggr_List,
3595 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
3596 New_Reference_To (RTE (RE_Null_Address), Loc)));
3599 -- Transportable: Set for types that can be used in remote calls
3600 -- with respect to E.4(18) legality rules.
3603 Transportable : Entity_Id;
3609 or else Is_Shared_Passive (Typ)
3611 ((Is_Remote_Types (Typ)
3612 or else Is_Remote_Call_Interface (Typ))
3613 and then Original_View_In_Visible_Part (Typ))
3614 or else not Comes_From_Source (Typ));
3616 Append_To (TSD_Aggr_List,
3617 New_Occurrence_Of (Transportable, Loc));
3620 -- RC_Offset: These are the valid values and their meaning:
3622 -- >0: For simple types with controlled components is
3623 -- type._record_controller'position
3625 -- 0: For types with no controlled components
3627 -- -1: For complex types with controlled components where the position
3628 -- of the record controller is not statically computable but there
3629 -- are controlled components at this level. The _Controller field
3630 -- is available right after the _parent.
3632 -- -2: There are no controlled components at this level. We need to
3633 -- get the position from the parent.
3636 RC_Offset_Node : Node_Id;
3639 if not Has_Controlled_Component (Typ) then
3640 RC_Offset_Node := Make_Integer_Literal (Loc, 0);
3642 elsif Etype (Typ) /= Typ
3643 and then Has_Discriminants (Etype (Typ))
3645 if Has_New_Controlled_Component (Typ) then
3646 RC_Offset_Node := Make_Integer_Literal (Loc, -1);
3648 RC_Offset_Node := Make_Integer_Literal (Loc, -2);
3652 Make_Attribute_Reference (Loc,
3654 Make_Selected_Component (Loc,
3655 Prefix => New_Reference_To (Typ, Loc),
3657 New_Reference_To (Controller_Component (Typ), Loc)),
3658 Attribute_Name => Name_Position);
3660 -- This is not proper Ada code to use the attribute 'Position
3661 -- on something else than an object but this is supported by
3662 -- the back end (see comment on the Bit_Component attribute in
3663 -- sem_attr). So we avoid semantic checking here.
3665 -- Is this documented in sinfo.ads??? it should be!
3667 Set_Analyzed (RC_Offset_Node);
3668 Set_Etype (Prefix (RC_Offset_Node), RTE (RE_Record_Controller));
3669 Set_Etype (Prefix (Prefix (RC_Offset_Node)), Typ);
3670 Set_Etype (Selector_Name (Prefix (RC_Offset_Node)),
3671 RTE (RE_Record_Controller));
3672 Set_Etype (RC_Offset_Node, RTE (RE_Storage_Offset));
3675 Append_To (TSD_Aggr_List, RC_Offset_Node);
3678 -- Interfaces_Table (required for AI-405)
3680 if RTE_Record_Component_Available (RE_Interfaces_Table) then
3682 -- Count the number of interface types implemented by Typ
3684 Collect_Abstract_Interfaces (Typ, Typ_Ifaces);
3686 AI := First_Elmt (Typ_Ifaces);
3687 while Present (AI) loop
3688 Num_Ifaces := Num_Ifaces + 1;
3692 if Num_Ifaces = 0 then
3693 Iface_Table_Node := Make_Null (Loc);
3695 -- Generate the Interface_Table object
3699 TSD_Ifaces_List : constant List_Id := New_List;
3702 AI := First_Elmt (Typ_Ifaces);
3703 while Present (AI) loop
3704 Append_To (TSD_Ifaces_List,
3705 Make_Aggregate (Loc,
3706 Expressions => New_List (
3710 Unchecked_Convert_To (RTE (RE_Tag),
3712 (Node (First_Elmt (Access_Disp_Table (Node (AI)))),
3715 -- Static_Offset_To_Top
3717 New_Reference_To (Standard_True, Loc),
3719 -- Offset_To_Top_Value
3721 Make_Integer_Literal (Loc, 0),
3723 -- Offset_To_Top_Func
3730 Name_ITable := New_External_Name (Tname, 'I');
3731 ITable := Make_Defining_Identifier (Loc, Name_ITable);
3732 Set_Is_Statically_Allocated (ITable);
3734 -- The table of interfaces is not constant; its slots are
3735 -- filled at run-time by the IP routine using attribute
3736 -- 'Position to know the location of the tag components
3737 -- (and this attribute cannot be safely used before the
3738 -- object is initialized).
3741 Make_Object_Declaration (Loc,
3742 Defining_Identifier => ITable,
3743 Aliased_Present => True,
3744 Constant_Present => False,
3745 Object_Definition =>
3746 Make_Subtype_Indication (Loc,
3748 New_Reference_To (RTE (RE_Interface_Data), Loc),
3749 Constraint => Make_Index_Or_Discriminant_Constraint
3751 Constraints => New_List (
3752 Make_Integer_Literal (Loc, Num_Ifaces)))),
3754 Expression => Make_Aggregate (Loc,
3755 Expressions => New_List (
3756 Make_Integer_Literal (Loc, Num_Ifaces),
3757 Make_Aggregate (Loc,
3758 Expressions => TSD_Ifaces_List)))));
3761 Make_Attribute_Definition_Clause (Loc,
3762 Name => New_Reference_To (ITable, Loc),
3763 Chars => Name_Alignment,
3765 Make_Attribute_Reference (Loc,
3767 New_Reference_To (RTE (RE_Integer_Address), Loc),
3768 Attribute_Name => Name_Alignment)));
3771 Make_Attribute_Reference (Loc,
3772 Prefix => New_Reference_To (ITable, Loc),
3773 Attribute_Name => Name_Unchecked_Access);
3777 Append_To (TSD_Aggr_List, Iface_Table_Node);
3780 -- Generate the Select Specific Data table for synchronized types that
3781 -- implement synchronized interfaces. The size of the table is
3782 -- constrained by the number of non-predefined primitive operations.
3784 if RTE_Record_Component_Available (RE_SSD) then
3785 if Ada_Version >= Ada_05
3786 and then Has_DT (Typ)
3787 and then Is_Concurrent_Record_Type (Typ)
3788 and then Has_Abstract_Interfaces (Typ)
3789 and then Nb_Prim > 0
3790 and then not Is_Abstract_Type (Typ)
3791 and then not Is_Controlled (Typ)
3792 and then not Restriction_Active (No_Dispatching_Calls)
3795 Make_Object_Declaration (Loc,
3796 Defining_Identifier => SSD,
3797 Aliased_Present => True,
3798 Object_Definition =>
3799 Make_Subtype_Indication (Loc,
3800 Subtype_Mark => New_Reference_To (
3801 RTE (RE_Select_Specific_Data), Loc),
3803 Make_Index_Or_Discriminant_Constraint (Loc,
3804 Constraints => New_List (
3805 Make_Integer_Literal (Loc, Nb_Prim))))));
3808 Make_Attribute_Definition_Clause (Loc,
3809 Name => New_Reference_To (SSD, Loc),
3810 Chars => Name_Alignment,
3812 Make_Attribute_Reference (Loc,
3814 New_Reference_To (RTE (RE_Integer_Address), Loc),
3815 Attribute_Name => Name_Alignment)));
3817 -- This table is initialized by Make_Select_Specific_Data_Table,
3818 -- which calls Set_Entry_Index and Set_Prim_Op_Kind.
3820 Append_To (TSD_Aggr_List,
3821 Make_Attribute_Reference (Loc,
3822 Prefix => New_Reference_To (SSD, Loc),
3823 Attribute_Name => Name_Unchecked_Access));
3825 Append_To (TSD_Aggr_List, Make_Null (Loc));
3829 -- Initialize the table of ancestor tags. In case of interface types
3830 -- this table is not needed.
3833 Current_Typ : Entity_Id;
3834 Parent_Typ : Entity_Id;
3838 TSD_Tags_List := New_List;
3840 -- If we are not statically allocating the dispatch table then we
3841 -- must fill position 0 with null because we still have not
3842 -- generated the tag of Typ.
3844 if not Building_Static_DT (Typ)
3845 or else Is_Interface (Typ)
3847 Append_To (TSD_Tags_List,
3848 Unchecked_Convert_To (RTE (RE_Tag),
3849 New_Reference_To (RTE (RE_Null_Address), Loc)));
3851 -- Otherwise we can safely reference the tag.
3854 Append_To (TSD_Tags_List,
3855 New_Reference_To (DT_Ptr, Loc));
3858 -- Fill the rest of the table with the tags of the ancestors
3864 Parent_Typ := Etype (Current_Typ);
3866 if Is_Private_Type (Parent_Typ) then
3867 Parent_Typ := Full_View (Base_Type (Parent_Typ));
3870 exit when Parent_Typ = Current_Typ;
3872 if Is_CPP_Class (Parent_Typ)
3873 or else Is_Interface (Typ)
3875 -- The tags defined in the C++ side will be inherited when
3876 -- the object is constructed (Exp_Ch3.Build_Init_Procedure)
3878 Append_To (TSD_Tags_List,
3879 Unchecked_Convert_To (RTE (RE_Tag),
3880 New_Reference_To (RTE (RE_Null_Address), Loc)));
3882 Append_To (TSD_Tags_List,
3884 (Node (First_Elmt (Access_Disp_Table (Parent_Typ))),
3889 Current_Typ := Parent_Typ;
3892 pragma Assert (Pos = I_Depth + 1);
3895 Append_To (TSD_Aggr_List,
3896 Make_Aggregate (Loc,
3897 Expressions => TSD_Tags_List));
3899 -- Build the TSD object
3902 Make_Object_Declaration (Loc,
3903 Defining_Identifier => TSD,
3904 Aliased_Present => True,
3905 Constant_Present => Building_Static_DT (Typ),
3906 Object_Definition =>
3907 Make_Subtype_Indication (Loc,
3908 Subtype_Mark => New_Reference_To (
3909 RTE (RE_Type_Specific_Data), Loc),
3911 Make_Index_Or_Discriminant_Constraint (Loc,
3912 Constraints => New_List (
3913 Make_Integer_Literal (Loc, I_Depth)))),
3915 Expression => Make_Aggregate (Loc,
3916 Expressions => TSD_Aggr_List)));
3918 Set_Is_True_Constant (TSD, Building_Static_DT (Typ));
3921 Make_Attribute_Definition_Clause (Loc,
3922 Name => New_Reference_To (TSD, Loc),
3923 Chars => Name_Alignment,
3925 Make_Attribute_Reference (Loc,
3926 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
3927 Attribute_Name => Name_Alignment)));
3929 -- Initialize or declare the dispatch table object
3931 if not Has_DT (Typ) then
3932 DT_Constr_List := New_List;
3933 DT_Aggr_List := New_List;
3938 Make_Attribute_Reference (Loc,
3939 Prefix => New_Reference_To (TSD, Loc),
3940 Attribute_Name => Name_Address);
3942 Append_To (DT_Constr_List, New_Node);
3943 Append_To (DT_Aggr_List, New_Copy (New_Node));
3944 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
3946 -- In case of locally defined tagged types we have already declared
3947 -- and uninitialized object for the dispatch table, which is now
3948 -- initialized by means of the following assignment:
3950 -- DT := (TSD'Address, 0);
3952 if not Building_Static_DT (Typ) then
3954 Make_Assignment_Statement (Loc,
3955 Name => New_Reference_To (DT, Loc),
3956 Expression => Make_Aggregate (Loc,
3957 Expressions => DT_Aggr_List)));
3959 -- In case of library level tagged types we declare and export now
3960 -- the constant object containing the dummy dispatch table. There
3961 -- is no need to declare the tag here because it has been previously
3962 -- declared by Make_Tags
3964 -- DT : aliased constant No_Dispatch_Table :=
3965 -- (NDT_TSD => TSD'Address;
3966 -- NDT_Prims_Ptr => 0);
3967 -- for DT'Alignment use Address'Alignment;
3971 Make_Object_Declaration (Loc,
3972 Defining_Identifier => DT,
3973 Aliased_Present => True,
3974 Constant_Present => True,
3975 Object_Definition =>
3976 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc),
3977 Expression => Make_Aggregate (Loc,
3978 Expressions => DT_Aggr_List)));
3981 Make_Attribute_Definition_Clause (Loc,
3982 Name => New_Reference_To (DT, Loc),
3983 Chars => Name_Alignment,
3985 Make_Attribute_Reference (Loc,
3987 New_Reference_To (RTE (RE_Integer_Address), Loc),
3988 Attribute_Name => Name_Alignment)));
3990 Export_DT (Typ, DT);
3993 -- Common case: Typ has a dispatch table
3997 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
3998 -- (predef-prim-op-1'address,
3999 -- predef-prim-op-2'address,
4001 -- predef-prim-op-n'address);
4002 -- for Predef_Prims'Alignment use Address'Alignment
4004 -- DT : Dispatch_Table (Nb_Prims) :=
4005 -- (Signature => <sig-value>,
4006 -- Tag_Kind => <tag_kind-value>,
4007 -- Predef_Prims => Predef_Prims'First'Address,
4008 -- Offset_To_Top => 0,
4009 -- TSD => TSD'Address;
4010 -- Prims_Ptr => (prim-op-1'address,
4011 -- prim-op-2'address,
4013 -- prim-op-n'address));
4014 -- for DT'Alignment use Address'Alignment
4021 if not Building_Static_DT (Typ) then
4022 Nb_Predef_Prims := Max_Predef_Prims;
4025 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4026 while Present (Prim_Elmt) loop
4027 Prim := Node (Prim_Elmt);
4029 if Is_Predefined_Dispatching_Operation (Prim)
4030 and then not Is_Abstract_Subprogram (Prim)
4032 Pos := UI_To_Int (DT_Position (Prim));
4034 if Pos > Nb_Predef_Prims then
4035 Nb_Predef_Prims := Pos;
4039 Next_Elmt (Prim_Elmt);
4045 (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
4049 Prim_Ops_Aggr_List := New_List;
4051 Prim_Table := (others => Empty);
4053 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4054 while Present (Prim_Elmt) loop
4055 Prim := Node (Prim_Elmt);
4057 if Building_Static_DT (Typ)
4058 and then Is_Predefined_Dispatching_Operation (Prim)
4059 and then not Is_Abstract_Subprogram (Prim)
4060 and then not Present (Prim_Table
4061 (UI_To_Int (DT_Position (Prim))))
4064 while Present (Alias (E)) loop
4068 pragma Assert (not Is_Abstract_Subprogram (E));
4069 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
4072 Next_Elmt (Prim_Elmt);
4075 for J in Prim_Table'Range loop
4076 if Present (Prim_Table (J)) then
4078 Make_Attribute_Reference (Loc,
4079 Prefix => New_Reference_To (Prim_Table (J), Loc),
4080 Attribute_Name => Name_Address);
4082 New_Node := New_Reference_To (RTE (RE_Null_Address), Loc);
4085 Append_To (Prim_Ops_Aggr_List, New_Node);
4089 Make_Object_Declaration (Loc,
4090 Defining_Identifier => Predef_Prims,
4091 Aliased_Present => True,
4092 Constant_Present => Building_Static_DT (Typ),
4093 Object_Definition =>
4094 New_Reference_To (RTE (RE_Address_Array), Loc),
4095 Expression => Make_Aggregate (Loc,
4096 Expressions => Prim_Ops_Aggr_List)));
4099 Make_Attribute_Definition_Clause (Loc,
4100 Name => New_Reference_To (Predef_Prims, Loc),
4101 Chars => Name_Alignment,
4103 Make_Attribute_Reference (Loc,
4105 New_Reference_To (RTE (RE_Integer_Address), Loc),
4106 Attribute_Name => Name_Alignment)));
4110 -- Stage 1: Initialize the discriminant and the record components
4112 DT_Constr_List := New_List;
4113 DT_Aggr_List := New_List;
4115 -- Num_Prims. If the tagged type has no primitives we add a dummy
4116 -- slot whose address will be the tag of this type.
4119 New_Node := Make_Integer_Literal (Loc, 1);
4121 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
4124 Append_To (DT_Constr_List, New_Node);
4125 Append_To (DT_Aggr_List, New_Copy (New_Node));
4129 if RTE_Record_Component_Available (RE_Signature) then
4130 Append_To (DT_Aggr_List,
4131 New_Reference_To (RTE (RE_Primary_DT), Loc));
4136 if RTE_Record_Component_Available (RE_Tag_Kind) then
4137 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
4142 Append_To (DT_Aggr_List,
4143 Make_Attribute_Reference (Loc,
4144 Prefix => New_Reference_To (Predef_Prims, Loc),
4145 Attribute_Name => Name_Address));
4149 if RTE_Record_Component_Available (RE_Offset_To_Top) then
4150 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
4155 Append_To (DT_Aggr_List,
4156 Make_Attribute_Reference (Loc,
4157 Prefix => New_Reference_To (TSD, Loc),
4158 Attribute_Name => Name_Address));
4160 -- Stage 2: Initialize the table of primitive operations
4162 Prim_Ops_Aggr_List := New_List;
4165 Append_To (Prim_Ops_Aggr_List,
4166 New_Reference_To (RTE (RE_Null_Address), Loc));
4168 elsif not Building_Static_DT (Typ) then
4169 for J in 1 .. Nb_Prim loop
4170 Append_To (Prim_Ops_Aggr_List,
4171 New_Reference_To (RTE (RE_Null_Address), Loc));
4176 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
4179 Prim_Elmt : Elmt_Id;
4182 Prim_Table := (others => Empty);
4183 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4184 while Present (Prim_Elmt) loop
4185 Prim := Node (Prim_Elmt);
4187 if Is_Imported (Prim)
4188 or else Present (Abstract_Interface_Alias (Prim))
4189 or else Is_Predefined_Dispatching_Operation (Prim)
4194 -- Traverse the list of aliased entities to handle
4195 -- renamings of predefined primitives.
4198 while Present (Alias (E)) loop
4202 if not Is_Predefined_Dispatching_Operation (E)
4203 and then not Is_Abstract_Subprogram (E)
4204 and then not Present (Abstract_Interface_Alias (E))
4207 (UI_To_Int (DT_Position (Prim)) <= Nb_Prim);
4209 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
4213 Next_Elmt (Prim_Elmt);
4216 for J in Prim_Table'Range loop
4217 if Present (Prim_Table (J)) then
4219 Make_Attribute_Reference (Loc,
4220 Prefix => New_Reference_To (Prim_Table (J), Loc),
4221 Attribute_Name => Name_Address);
4223 New_Node := New_Reference_To (RTE (RE_Null_Address), Loc);
4226 Append_To (Prim_Ops_Aggr_List, New_Node);
4231 Append_To (DT_Aggr_List,
4232 Make_Aggregate (Loc,
4233 Expressions => Prim_Ops_Aggr_List));
4235 -- In case of locally defined tagged types we have already declared
4236 -- and uninitialized object for the dispatch table, which is now
4237 -- initialized by means of an assignment.
4239 if not Building_Static_DT (Typ) then
4241 Make_Assignment_Statement (Loc,
4242 Name => New_Reference_To (DT, Loc),
4243 Expression => Make_Aggregate (Loc,
4244 Expressions => DT_Aggr_List)));
4246 -- In case of library level tagged types we declare now and export
4247 -- the constant object containing the dispatch table.
4251 Make_Object_Declaration (Loc,
4252 Defining_Identifier => DT,
4253 Aliased_Present => True,
4254 Constant_Present => True,
4255 Object_Definition =>
4256 Make_Subtype_Indication (Loc,
4257 Subtype_Mark => New_Reference_To
4258 (RTE (RE_Dispatch_Table_Wrapper), Loc),
4259 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4260 Constraints => DT_Constr_List)),
4261 Expression => Make_Aggregate (Loc,
4262 Expressions => DT_Aggr_List)));
4265 Make_Attribute_Definition_Clause (Loc,
4266 Name => New_Reference_To (DT, Loc),
4267 Chars => Name_Alignment,
4269 Make_Attribute_Reference (Loc,
4271 New_Reference_To (RTE (RE_Integer_Address), Loc),
4272 Attribute_Name => Name_Alignment)));
4274 Export_DT (Typ, DT);
4278 -- Initialize the table of ancestor tags
4280 if not Building_Static_DT (Typ)
4281 and then not Is_Interface (Typ)
4282 and then not Is_CPP_Class (Typ)
4285 Make_Assignment_Statement (Loc,
4287 Make_Indexed_Component (Loc,
4289 Make_Selected_Component (Loc,
4291 New_Reference_To (TSD, Loc),
4294 (RTE_Record_Component (RE_Tags_Table), Loc)),
4296 New_List (Make_Integer_Literal (Loc, 0))),
4300 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)));
4303 if Building_Static_DT (Typ) then
4306 -- If the ancestor is a CPP_Class type we inherit the dispatch tables
4307 -- in the init proc, and we don't need to fill them in here.
4309 elsif Is_CPP_Class (Etype (Typ)) then
4312 -- Otherwise we fill in the dispatch tables here
4315 if Typ = Etype (Typ)
4316 or else Is_CPP_Class (Etype (Typ))
4317 or else Is_Interface (Typ)
4319 Null_Parent_Tag := True;
4322 Unchecked_Convert_To (RTE (RE_Tag),
4323 Make_Integer_Literal (Loc, 0));
4325 Unchecked_Convert_To (RTE (RE_Tag),
4326 Make_Integer_Literal (Loc, 0));
4331 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc);
4334 (Node (First_Elmt (Access_Disp_Table (Etype (Typ)))), Loc);
4337 if Typ /= Etype (Typ)
4338 and then not Is_Interface (Typ)
4339 and then not Restriction_Active (No_Dispatching_Calls)
4341 -- Inherit the dispatch table
4343 if not Is_Interface (Etype (Typ)) then
4344 if not Null_Parent_Tag then
4346 Nb_Prims : constant Int :=
4347 UI_To_Int (DT_Entry_Count
4348 (First_Tag_Component (Etype (Typ))));
4350 Append_To (Elab_Code,
4351 Build_Inherit_Predefined_Prims (Loc,
4352 Old_Tag_Node => Old_Tag1,
4354 New_Reference_To (DT_Ptr, Loc)));
4356 if Nb_Prims /= 0 then
4357 Append_To (Elab_Code,
4358 Build_Inherit_Prims (Loc,
4360 Old_Tag_Node => Old_Tag2,
4361 New_Tag_Node => New_Reference_To (DT_Ptr, Loc),
4362 Num_Prims => Nb_Prims));
4368 -- Inherit the secondary dispatch tables of the ancestor
4370 if not Is_CPP_Class (Etype (Typ)) then
4372 Sec_DT_Ancestor : Elmt_Id :=
4375 (Access_Disp_Table (Etype (Typ))));
4376 Sec_DT_Typ : Elmt_Id :=
4379 (Access_Disp_Table (Typ)));
4381 procedure Copy_Secondary_DTs (Typ : Entity_Id);
4382 -- Local procedure required to climb through the ancestors
4383 -- and copy the contents of all their secondary dispatch
4386 ------------------------
4387 -- Copy_Secondary_DTs --
4388 ------------------------
4390 procedure Copy_Secondary_DTs (Typ : Entity_Id) is
4395 -- Climb to the ancestor (if any) handling private types
4397 if Present (Full_View (Etype (Typ))) then
4398 if Full_View (Etype (Typ)) /= Typ then
4399 Copy_Secondary_DTs (Full_View (Etype (Typ)));
4402 elsif Etype (Typ) /= Typ then
4403 Copy_Secondary_DTs (Etype (Typ));
4406 if Present (Abstract_Interfaces (Typ))
4407 and then not Is_Empty_Elmt_List
4408 (Abstract_Interfaces (Typ))
4410 Iface := First_Elmt (Abstract_Interfaces (Typ));
4411 E := First_Entity (Typ);
4413 and then Present (Node (Sec_DT_Ancestor))
4414 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
4416 if Is_Tag (E) and then Chars (E) /= Name_uTag then
4417 if not Is_Interface (Etype (Typ)) then
4419 -- Inherit the dispatch table
4422 Num_Prims : constant Int :=
4423 UI_To_Int (DT_Entry_Count (E));
4425 Append_To (Elab_Code,
4426 Build_Inherit_Predefined_Prims (Loc,
4428 Unchecked_Convert_To (RTE (RE_Tag),
4430 (Node (Sec_DT_Ancestor), Loc)),
4432 Unchecked_Convert_To (RTE (RE_Tag),
4434 (Node (Sec_DT_Typ), Loc))));
4436 if Num_Prims /= 0 then
4437 Append_To (Elab_Code,
4438 Build_Inherit_Prims (Loc,
4439 Typ => Node (Iface),
4441 Unchecked_Convert_To
4444 (Node (Sec_DT_Ancestor),
4447 Unchecked_Convert_To
4450 (Node (Sec_DT_Typ), Loc)),
4451 Num_Prims => Num_Prims));
4456 Next_Elmt (Sec_DT_Ancestor);
4457 Next_Elmt (Sec_DT_Typ);
4464 end Copy_Secondary_DTs;
4467 if Present (Node (Sec_DT_Ancestor))
4468 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
4470 -- Handle private types
4472 if Present (Full_View (Typ)) then
4473 Copy_Secondary_DTs (Full_View (Typ));
4475 Copy_Secondary_DTs (Typ);
4483 -- Generate code to register the Tag in the External_Tag hash table for
4484 -- the pure Ada type only.
4486 -- Register_Tag (Dt_Ptr);
4488 -- Skip this action in the following cases:
4489 -- 1) if Register_Tag is not available.
4490 -- 2) in No_Run_Time mode.
4491 -- 3) if Typ is an abstract interface type (the secondary tags will
4492 -- be registered later in types implementing this interface type).
4493 -- 4) if Typ is not defined at the library level (this is required
4494 -- to avoid adding concurrency control to the hash table used
4495 -- by the run-time to register the tags).
4500 -- [ Register_Tag (Dt_Ptr); ]
4504 if not Is_Interface (Typ) then
4505 if not No_Run_Time_Mode
4506 and then Is_Library_Level_Entity (Typ)
4507 and then RTE_Available (RE_Register_Tag)
4509 Append_To (Elab_Code,
4510 Make_Procedure_Call_Statement (Loc,
4511 Name => New_Reference_To (RTE (RE_Register_Tag), Loc),
4512 Parameter_Associations =>
4513 New_List (New_Reference_To (DT_Ptr, Loc))));
4516 Append_To (Elab_Code,
4517 Make_Assignment_Statement (Loc,
4518 Name => New_Reference_To (No_Reg, Loc),
4519 Expression => New_Reference_To (Standard_False, Loc)));
4522 Make_Implicit_If_Statement (Typ,
4523 Condition => New_Reference_To (No_Reg, Loc),
4524 Then_Statements => Elab_Code));
4527 -- Populate the two auxiliary tables used for dispatching
4528 -- asynchronous, conditional and timed selects for synchronized
4529 -- types that implement a limited interface.
4531 if Ada_Version >= Ada_05
4532 and then Is_Concurrent_Record_Type (Typ)
4533 and then Has_Abstract_Interfaces (Typ)
4535 Append_List_To (Result,
4536 Make_Select_Specific_Data_Table (Typ));
4539 Analyze_List (Result, Suppress => All_Checks);
4540 Set_Has_Dispatch_Table (Typ);
4545 -------------------------------------
4546 -- Make_Select_Specific_Data_Table --
4547 -------------------------------------
4549 function Make_Select_Specific_Data_Table
4550 (Typ : Entity_Id) return List_Id
4552 Assignments : constant List_Id := New_List;
4553 Loc : constant Source_Ptr := Sloc (Typ);
4555 Conc_Typ : Entity_Id;
4559 Prim_Als : Entity_Id;
4560 Prim_Elmt : Elmt_Id;
4564 type Examined_Array is array (Int range <>) of Boolean;
4566 function Find_Entry_Index (E : Entity_Id) return Uint;
4567 -- Given an entry, find its index in the visible declarations of the
4568 -- corresponding concurrent type of Typ.
4570 ----------------------
4571 -- Find_Entry_Index --
4572 ----------------------
4574 function Find_Entry_Index (E : Entity_Id) return Uint is
4575 Index : Uint := Uint_1;
4576 Subp_Decl : Entity_Id;
4580 and then not Is_Empty_List (Decls)
4582 Subp_Decl := First (Decls);
4583 while Present (Subp_Decl) loop
4584 if Nkind (Subp_Decl) = N_Entry_Declaration then
4585 if Defining_Identifier (Subp_Decl) = E then
4597 end Find_Entry_Index;
4599 -- Start of processing for Make_Select_Specific_Data_Table
4602 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
4604 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
4606 if Present (Corresponding_Concurrent_Type (Typ)) then
4607 Conc_Typ := Corresponding_Concurrent_Type (Typ);
4609 if Present (Full_View (Conc_Typ)) then
4610 Conc_Typ := Full_View (Conc_Typ);
4613 if Ekind (Conc_Typ) = E_Protected_Type then
4614 Decls := Visible_Declarations (Protected_Definition (
4615 Parent (Conc_Typ)));
4617 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
4618 Decls := Visible_Declarations (Task_Definition (
4619 Parent (Conc_Typ)));
4623 -- Count the non-predefined primitive operations
4625 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4626 while Present (Prim_Elmt) loop
4627 Prim := Node (Prim_Elmt);
4629 if not (Is_Predefined_Dispatching_Operation (Prim)
4630 or else Is_Predefined_Dispatching_Alias (Prim))
4632 Nb_Prim := Nb_Prim + 1;
4635 Next_Elmt (Prim_Elmt);
4639 Examined : Examined_Array (1 .. Nb_Prim) := (others => False);
4642 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4643 while Present (Prim_Elmt) loop
4644 Prim := Node (Prim_Elmt);
4646 -- Look for primitive overriding an abstract interface subprogram
4648 if Present (Abstract_Interface_Alias (Prim))
4649 and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
4651 Prim_Pos := DT_Position (Alias (Prim));
4652 pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
4653 Examined (UI_To_Int (Prim_Pos)) := True;
4655 -- Set the primitive operation kind regardless of subprogram
4657 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
4659 Append_To (Assignments,
4660 Make_Procedure_Call_Statement (Loc,
4661 Name => New_Reference_To (RTE (RE_Set_Prim_Op_Kind), Loc),
4662 Parameter_Associations => New_List (
4663 New_Reference_To (DT_Ptr, Loc),
4664 Make_Integer_Literal (Loc, Prim_Pos),
4665 Prim_Op_Kind (Alias (Prim), Typ))));
4667 -- Retrieve the root of the alias chain
4670 while Present (Alias (Prim_Als)) loop
4671 Prim_Als := Alias (Prim_Als);
4674 -- In the case of an entry wrapper, set the entry index
4676 if Ekind (Prim) = E_Procedure
4677 and then Is_Primitive_Wrapper (Prim_Als)
4678 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
4681 -- Ada.Tags.Set_Entry_Index
4682 -- (DT_Ptr, <position>, <index>);
4684 Append_To (Assignments,
4685 Make_Procedure_Call_Statement (Loc,
4687 New_Reference_To (RTE (RE_Set_Entry_Index), Loc),
4688 Parameter_Associations => New_List (
4689 New_Reference_To (DT_Ptr, Loc),
4690 Make_Integer_Literal (Loc, Prim_Pos),
4691 Make_Integer_Literal (Loc,
4692 Find_Entry_Index (Wrapped_Entity (Prim_Als))))));
4696 Next_Elmt (Prim_Elmt);
4701 end Make_Select_Specific_Data_Table;
4707 function Make_Tags (Typ : Entity_Id) return List_Id is
4708 Loc : constant Source_Ptr := Sloc (Typ);
4709 Tname : constant Name_Id := Chars (Typ);
4710 Result : constant List_Id := New_List;
4711 AI_Tag_Comp : Elmt_Id;
4713 DT_Constr_List : List_Id;
4715 Iface_DT_Ptr : Node_Id;
4719 Typ_Comps : Elist_Id;
4722 -- 1) Generate the primary and secondary tag entities
4724 -- Collect the components associated with secondary dispatch tables
4726 if Has_Abstract_Interfaces (Typ) then
4727 Collect_Interface_Components (Typ, Typ_Comps);
4730 -- 1) Generate the primary tag entity
4732 DT_Ptr := Make_Defining_Identifier (Loc,
4733 New_External_Name (Tname, 'P'));
4734 Set_Etype (DT_Ptr, RTE (RE_Tag));
4736 -- Import the forward declaration of the Dispatch Table wrapper record
4737 -- (Make_DT will take care of its exportation)
4739 if Building_Static_DT (Typ) then
4740 DT := Make_Defining_Identifier (Loc,
4741 New_External_Name (Tname, 'T'));
4744 -- DT : static aliased constant Dispatch_Table_Wrapper (Nb_Prim);
4745 -- $pragma import (ada, DT);
4747 Set_Is_Imported (DT);
4749 -- The scope must be set now to call Get_External_Name
4751 Set_Scope (DT, Current_Scope);
4753 Get_External_Name (DT, True);
4754 Set_Interface_Name (DT,
4755 Make_String_Literal (Loc,
4756 Strval => String_From_Name_Buffer));
4758 -- Ensure proper Sprint output of this implicit importation
4760 Set_Is_Internal (DT);
4762 -- Save this entity to allow Make_DT to generate its exportation
4764 Set_Dispatch_Table_Wrapper (Typ, DT);
4766 if Has_DT (Typ) then
4767 -- Calculate the number of primitives of the dispatch table and
4768 -- the size of the Type_Specific_Data record.
4770 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
4772 -- If the tagged type has no primitives we add a dummy slot
4773 -- whose address will be the tag of this type.
4777 New_List (Make_Integer_Literal (Loc, 1));
4780 New_List (Make_Integer_Literal (Loc, Nb_Prim));
4784 Make_Object_Declaration (Loc,
4785 Defining_Identifier => DT,
4786 Aliased_Present => True,
4787 Constant_Present => True,
4788 Object_Definition =>
4789 Make_Subtype_Indication (Loc,
4791 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
4792 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4793 Constraints => DT_Constr_List))));
4796 Make_Object_Declaration (Loc,
4797 Defining_Identifier => DT_Ptr,
4798 Constant_Present => True,
4799 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4801 Unchecked_Convert_To (RTE (RE_Tag),
4802 Make_Attribute_Reference (Loc,
4804 Make_Selected_Component (Loc,
4805 Prefix => New_Reference_To (DT, Loc),
4808 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
4809 Attribute_Name => Name_Address))));
4811 -- No dispatch table required
4815 Make_Object_Declaration (Loc,
4816 Defining_Identifier => DT,
4817 Aliased_Present => True,
4818 Constant_Present => True,
4819 Object_Definition =>
4820 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
4823 Make_Object_Declaration (Loc,
4824 Defining_Identifier => DT_Ptr,
4825 Constant_Present => True,
4826 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4828 Unchecked_Convert_To (RTE (RE_Tag),
4829 Make_Attribute_Reference (Loc,
4831 Make_Selected_Component (Loc,
4832 Prefix => New_Reference_To (DT, Loc),
4835 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
4836 Attribute_Name => Name_Address))));
4839 Set_Is_True_Constant (DT_Ptr);
4840 Set_Is_Statically_Allocated (DT_Ptr);
4843 pragma Assert (No (Access_Disp_Table (Typ)));
4844 Set_Access_Disp_Table (Typ, New_Elmt_List);
4845 Append_Elmt (DT_Ptr, Access_Disp_Table (Typ));
4847 -- 2) Generate the secondary tag entities
4849 if Has_Abstract_Interfaces (Typ) then
4852 -- For each interface type we build an unique external name
4853 -- associated with its corresponding secondary dispatch table.
4854 -- This external name will be used to declare an object that
4855 -- references this secondary dispatch table, value that will be
4856 -- used for the elaboration of Typ's objects and also for the
4857 -- elaboration of objects of derivations of Typ that do not
4858 -- override the primitive operation of this interface type.
4860 AI_Tag_Comp := First_Elmt (Typ_Comps);
4861 while Present (AI_Tag_Comp) loop
4862 Get_Secondary_DT_External_Name
4863 (Typ, Related_Interface (Node (AI_Tag_Comp)), Suffix_Index);
4865 Typ_Name := Name_Find;
4867 Make_Defining_Identifier (Loc,
4868 Chars => New_External_Name (Typ_Name, 'P'));
4869 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
4870 Set_Ekind (Iface_DT_Ptr, E_Constant);
4871 Set_Is_Statically_Allocated (Iface_DT_Ptr);
4872 Set_Is_True_Constant (Iface_DT_Ptr);
4873 Set_Related_Interface
4874 (Iface_DT_Ptr, Related_Interface (Node (AI_Tag_Comp)));
4875 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
4877 Next_Elmt (AI_Tag_Comp);
4881 -- 3) At the end of Access_Disp_Table we add the entity of an access
4882 -- type declaration. It is used by Build_Get_Prim_Op_Address to
4883 -- expand dispatching calls through the primary dispatch table.
4886 -- type Typ_DT is array (1 .. Nb_Prims) of Address;
4887 -- type Typ_DT_Acc is access Typ_DT;
4890 Name_DT_Prims : constant Name_Id :=
4891 New_External_Name (Tname, 'G');
4892 Name_DT_Prims_Acc : constant Name_Id :=
4893 New_External_Name (Tname, 'H');
4894 DT_Prims : constant Entity_Id :=
4895 Make_Defining_Identifier (Loc, Name_DT_Prims);
4896 DT_Prims_Acc : constant Entity_Id :=
4897 Make_Defining_Identifier (Loc,
4901 Make_Full_Type_Declaration (Loc,
4902 Defining_Identifier => DT_Prims,
4904 Make_Constrained_Array_Definition (Loc,
4905 Discrete_Subtype_Definitions => New_List (
4907 Low_Bound => Make_Integer_Literal (Loc, 1),
4908 High_Bound => Make_Integer_Literal (Loc,
4910 (First_Tag_Component (Typ))))),
4911 Component_Definition =>
4912 Make_Component_Definition (Loc,
4913 Subtype_Indication =>
4914 New_Reference_To (RTE (RE_Address), Loc)))));
4917 Make_Full_Type_Declaration (Loc,
4918 Defining_Identifier => DT_Prims_Acc,
4920 Make_Access_To_Object_Definition (Loc,
4921 Subtype_Indication =>
4922 New_Occurrence_Of (DT_Prims, Loc))));
4924 Append_Elmt (DT_Prims_Acc, Access_Disp_Table (Typ));
4926 -- Analyze the resulting list and suppress the generation of the
4927 -- Init_Proc associated with the above array declaration because
4928 -- we never use such type in object declarations; this type is only
4929 -- used to simplify the expansion associated with dispatching calls.
4931 Analyze_List (Result);
4932 Set_Suppress_Init_Proc (Base_Type (DT_Prims));
4938 -----------------------------------
4939 -- Original_View_In_Visible_Part --
4940 -----------------------------------
4942 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
4943 Scop : constant Entity_Id := Scope (Typ);
4946 -- The scope must be a package
4948 if Ekind (Scop) /= E_Package
4949 and then Ekind (Scop) /= E_Generic_Package
4954 -- A type with a private declaration has a private view declared in
4955 -- the visible part.
4957 if Has_Private_Declaration (Typ) then
4961 return List_Containing (Parent (Typ)) =
4962 Visible_Declarations (Specification (Unit_Declaration_Node (Scop)));
4963 end Original_View_In_Visible_Part;
4969 function Prim_Op_Kind
4971 Typ : Entity_Id) return Node_Id
4973 Full_Typ : Entity_Id := Typ;
4974 Loc : constant Source_Ptr := Sloc (Prim);
4975 Prim_Op : Entity_Id;
4978 -- Retrieve the original primitive operation
4981 while Present (Alias (Prim_Op)) loop
4982 Prim_Op := Alias (Prim_Op);
4985 if Ekind (Typ) = E_Record_Type
4986 and then Present (Corresponding_Concurrent_Type (Typ))
4988 Full_Typ := Corresponding_Concurrent_Type (Typ);
4991 if Ekind (Prim_Op) = E_Function then
4993 -- Protected function
4995 if Ekind (Full_Typ) = E_Protected_Type then
4996 return New_Reference_To (RTE (RE_POK_Protected_Function), Loc);
5000 elsif Ekind (Full_Typ) = E_Task_Type then
5001 return New_Reference_To (RTE (RE_POK_Task_Function), Loc);
5006 return New_Reference_To (RTE (RE_POK_Function), Loc);
5010 pragma Assert (Ekind (Prim_Op) = E_Procedure);
5012 if Ekind (Full_Typ) = E_Protected_Type then
5016 if Is_Primitive_Wrapper (Prim_Op)
5017 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
5019 return New_Reference_To (RTE (RE_POK_Protected_Entry), Loc);
5021 -- Protected procedure
5024 return New_Reference_To (RTE (RE_POK_Protected_Procedure), Loc);
5027 elsif Ekind (Full_Typ) = E_Task_Type then
5031 if Is_Primitive_Wrapper (Prim_Op)
5032 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
5034 return New_Reference_To (RTE (RE_POK_Task_Entry), Loc);
5036 -- Task "procedure". These are the internally Expander-generated
5037 -- procedures (task body for instance).
5040 return New_Reference_To (RTE (RE_POK_Task_Procedure), Loc);
5043 -- Regular procedure
5046 return New_Reference_To (RTE (RE_POK_Procedure), Loc);
5051 ------------------------
5052 -- Register_Primitive --
5053 ------------------------
5055 procedure Register_Primitive
5061 Iface_Prim : Entity_Id;
5062 Iface_Typ : Entity_Id;
5063 Iface_DT_Ptr : Entity_Id;
5066 Thunk_Id : Entity_Id;
5067 Thunk_Code : Node_Id;
5071 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
5073 if not RTE_Available (RE_Tag) then
5077 if not Present (Abstract_Interface_Alias (Prim)) then
5078 Typ := Scope (DTC_Entity (Prim));
5079 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
5080 Pos := DT_Position (Prim);
5081 Tag := First_Tag_Component (Typ);
5083 if Is_Predefined_Dispatching_Operation (Prim)
5084 or else Is_Predefined_Dispatching_Alias (Prim)
5086 Insert_After (Ins_Nod,
5087 Build_Set_Predefined_Prim_Op_Address (Loc,
5088 Tag_Node => New_Reference_To (DT_Ptr, Loc),
5090 Address_Node => Make_Attribute_Reference (Loc,
5091 Prefix => New_Reference_To (Prim, Loc),
5092 Attribute_Name => Name_Address)));
5095 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
5097 Insert_After (Ins_Nod,
5098 Build_Set_Prim_Op_Address (Loc,
5100 Tag_Node => New_Reference_To (DT_Ptr, Loc),
5102 Address_Node => Make_Attribute_Reference (Loc,
5103 Prefix => New_Reference_To (Prim, Loc),
5104 Attribute_Name => Name_Address)));
5107 -- Ada 2005 (AI-251): Primitive associated with an interface type
5108 -- Generate the code of the thunk only if the interface type is not an
5109 -- immediate ancestor of Typ; otherwise the dispatch table associated
5110 -- with the interface is the primary dispatch table and we have nothing
5114 Typ := Find_Dispatching_Type (Alias (Prim));
5115 Iface_Typ := Find_Dispatching_Type (Abstract_Interface_Alias (Prim));
5117 pragma Assert (Is_Interface (Iface_Typ));
5119 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
5121 if not Is_Parent (Iface_Typ, Typ)
5122 and then Present (Thunk_Code)
5124 -- Comment needed on why checks are suppressed. This is not just
5125 -- efficiency, but fundamental functionality (see 1.295 RH, which
5126 -- still does not answer this question) ???
5128 Insert_Action (Ins_Nod, Thunk_Code, Suppress => All_Checks);
5130 -- Generate the code necessary to fill the appropriate entry of
5131 -- the secondary dispatch table of Prim's controlling type with
5132 -- Thunk_Id's address.
5134 Iface_DT_Ptr := Find_Interface_ADT (Typ, Iface_Typ);
5135 Iface_Prim := Abstract_Interface_Alias (Prim);
5136 Pos := DT_Position (Iface_Prim);
5137 Tag := First_Tag_Component (Iface_Typ);
5139 if Is_Predefined_Dispatching_Operation (Prim)
5140 or else Is_Predefined_Dispatching_Alias (Prim)
5142 Insert_Action (Ins_Nod,
5143 Build_Set_Predefined_Prim_Op_Address (Loc,
5144 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
5147 Make_Attribute_Reference (Loc,
5148 Prefix => New_Reference_To (Thunk_Id, Loc),
5149 Attribute_Name => Name_Address)));
5151 pragma Assert (Pos /= Uint_0
5152 and then Pos <= DT_Entry_Count (Tag));
5154 Insert_Action (Ins_Nod,
5155 Build_Set_Prim_Op_Address (Loc,
5157 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
5159 Address_Node => Make_Attribute_Reference (Loc,
5161 New_Reference_To (Thunk_Id, Loc),
5162 Attribute_Name => Name_Address)));
5166 end Register_Primitive;
5168 -------------------------
5169 -- Set_All_DT_Position --
5170 -------------------------
5172 procedure Set_All_DT_Position (Typ : Entity_Id) is
5174 procedure Validate_Position (Prim : Entity_Id);
5175 -- Check that the position assignated to Prim is completely safe
5176 -- (it has not been assigned to a previously defined primitive
5177 -- operation of Typ)
5179 -----------------------
5180 -- Validate_Position --
5181 -----------------------
5183 procedure Validate_Position (Prim : Entity_Id) is
5188 -- Aliased primitives are safe
5190 if Present (Alias (Prim)) then
5194 Op_Elmt := First_Elmt (Primitive_Operations (Typ));
5195 while Present (Op_Elmt) loop
5196 Op := Node (Op_Elmt);
5198 -- No need to check against itself
5203 -- Primitive operations covering abstract interfaces are
5206 elsif Present (Abstract_Interface_Alias (Op)) then
5209 -- Predefined dispatching operations are completely safe. They
5210 -- are allocated at fixed positions in a separate table.
5212 elsif Is_Predefined_Dispatching_Operation (Op)
5213 or else Is_Predefined_Dispatching_Alias (Op)
5217 -- Aliased subprograms are safe
5219 elsif Present (Alias (Op)) then
5222 elsif DT_Position (Op) = DT_Position (Prim)
5223 and then not Is_Predefined_Dispatching_Operation (Op)
5224 and then not Is_Predefined_Dispatching_Operation (Prim)
5225 and then not Is_Predefined_Dispatching_Alias (Op)
5226 and then not Is_Predefined_Dispatching_Alias (Prim)
5229 -- Handle aliased subprograms
5238 if Present (Overridden_Operation (Op_1)) then
5239 Op_1 := Overridden_Operation (Op_1);
5240 elsif Present (Alias (Op_1)) then
5241 Op_1 := Alias (Op_1);
5249 if Present (Overridden_Operation (Op_2)) then
5250 Op_2 := Overridden_Operation (Op_2);
5251 elsif Present (Alias (Op_2)) then
5252 Op_2 := Alias (Op_2);
5258 if Op_1 /= Op_2 then
5259 raise Program_Error;
5264 Next_Elmt (Op_Elmt);
5266 end Validate_Position;
5270 Parent_Typ : constant Entity_Id := Etype (Typ);
5271 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
5272 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
5274 Adjusted : Boolean := False;
5275 Finalized : Boolean := False;
5281 Prim_Elmt : Elmt_Id;
5283 -- Start of processing for Set_All_DT_Position
5286 -- Set the DT_Position for each primitive operation. Perform some
5287 -- sanity checks to avoid to build completely inconsistant dispatch
5290 -- First stage: Set the DTC entity of all the primitive operations
5291 -- This is required to properly read the DT_Position attribute in
5292 -- the latter stages.
5294 Prim_Elmt := First_Prim;
5296 while Present (Prim_Elmt) loop
5297 Prim := Node (Prim_Elmt);
5299 -- Predefined primitives have a separate dispatch table
5301 if not (Is_Predefined_Dispatching_Operation (Prim)
5302 or else Is_Predefined_Dispatching_Alias (Prim))
5304 Count_Prim := Count_Prim + 1;
5307 Set_DTC_Entity_Value (Typ, Prim);
5309 -- Clear any previous value of the DT_Position attribute. In this
5310 -- way we ensure that the final position of all the primitives is
5311 -- stablished by the following stages of this algorithm.
5313 Set_DT_Position (Prim, No_Uint);
5315 Next_Elmt (Prim_Elmt);
5319 Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean
5320 := (others => False);
5323 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id);
5324 -- Called if Typ is declared in a nested package or a public child
5325 -- package to handle inherited primitives that were inherited by Typ
5326 -- in the visible part, but whose declaration was deferred because
5327 -- the parent operation was private and not visible at that point.
5329 procedure Set_Fixed_Prim (Pos : Nat);
5330 -- Sets to true an element of the Fixed_Prim table to indicate
5331 -- that this entry of the dispatch table of Typ is occupied.
5333 ------------------------------------------
5334 -- Handle_Inherited_Private_Subprograms --
5335 ------------------------------------------
5337 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id) is
5340 Op_Elmt_2 : Elmt_Id;
5341 Prim_Op : Entity_Id;
5342 Parent_Subp : Entity_Id;
5345 Op_List := Primitive_Operations (Typ);
5347 Op_Elmt := First_Elmt (Op_List);
5348 while Present (Op_Elmt) loop
5349 Prim_Op := Node (Op_Elmt);
5351 -- Search primitives that are implicit operations with an
5352 -- internal name whose parent operation has a normal name.
5354 if Present (Alias (Prim_Op))
5355 and then Find_Dispatching_Type (Alias (Prim_Op)) /= Typ
5356 and then not Comes_From_Source (Prim_Op)
5357 and then Is_Internal_Name (Chars (Prim_Op))
5358 and then not Is_Internal_Name (Chars (Alias (Prim_Op)))
5360 Parent_Subp := Alias (Prim_Op);
5362 -- Check if the type has an explicit overriding for this
5365 Op_Elmt_2 := Next_Elmt (Op_Elmt);
5366 while Present (Op_Elmt_2) loop
5367 if Chars (Node (Op_Elmt_2)) = Chars (Parent_Subp)
5368 and then Type_Conformant (Prim_Op, Node (Op_Elmt_2))
5370 Set_DT_Position (Prim_Op, DT_Position (Parent_Subp));
5371 Set_DT_Position (Node (Op_Elmt_2),
5372 DT_Position (Parent_Subp));
5373 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim_Op)));
5375 goto Next_Primitive;
5378 Next_Elmt (Op_Elmt_2);
5383 Next_Elmt (Op_Elmt);
5385 end Handle_Inherited_Private_Subprograms;
5387 --------------------
5388 -- Set_Fixed_Prim --
5389 --------------------
5391 procedure Set_Fixed_Prim (Pos : Nat) is
5393 pragma Assert (Pos >= 0 and then Pos <= Count_Prim);
5394 Fixed_Prim (Pos) := True;
5396 when Constraint_Error =>
5397 raise Program_Error;
5401 -- In case of nested packages and public child package it may be
5402 -- necessary a special management on inherited subprograms so that
5403 -- the dispatch table is properly filled.
5405 if Ekind (Scope (Scope (Typ))) = E_Package
5406 and then Scope (Scope (Typ)) /= Standard_Standard
5407 and then ((Is_Derived_Type (Typ) and then not Is_Private_Type (Typ))
5409 (Nkind (Parent (Typ)) = N_Private_Extension_Declaration
5410 and then Is_Generic_Type (Typ)))
5411 and then In_Open_Scopes (Scope (Etype (Typ)))
5412 and then Typ = Base_Type (Typ)
5414 Handle_Inherited_Private_Subprograms (Typ);
5417 -- Second stage: Register fixed entries
5420 Prim_Elmt := First_Prim;
5421 while Present (Prim_Elmt) loop
5422 Prim := Node (Prim_Elmt);
5424 -- Predefined primitives have a separate table and all its
5425 -- entries are at predefined fixed positions.
5427 if Is_Predefined_Dispatching_Operation (Prim) then
5428 Set_DT_Position (Prim, Default_Prim_Op_Position (Prim));
5430 elsif Is_Predefined_Dispatching_Alias (Prim) then
5432 while Present (Alias (E)) loop
5436 Set_DT_Position (Prim, Default_Prim_Op_Position (E));
5438 -- Overriding primitives of ancestor abstract interfaces
5440 elsif Present (Abstract_Interface_Alias (Prim))
5442 (Find_Dispatching_Type
5443 (Abstract_Interface_Alias (Prim)),
5446 pragma Assert (DT_Position (Prim) = No_Uint
5447 and then Present (DTC_Entity
5448 (Abstract_Interface_Alias (Prim))));
5450 E := Abstract_Interface_Alias (Prim);
5451 Set_DT_Position (Prim, DT_Position (E));
5454 (DT_Position (Alias (Prim)) = No_Uint
5455 or else DT_Position (Alias (Prim)) = DT_Position (E));
5456 Set_DT_Position (Alias (Prim), DT_Position (E));
5457 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));
5459 -- Overriding primitives must use the same entry as the
5460 -- overriden primitive.
5462 elsif not Present (Abstract_Interface_Alias (Prim))
5463 and then Present (Alias (Prim))
5464 and then Chars (Prim) = Chars (Alias (Prim))
5465 and then Find_Dispatching_Type (Alias (Prim)) /= Typ
5467 (Find_Dispatching_Type (Alias (Prim)), Typ)
5468 and then Present (DTC_Entity (Alias (Prim)))
5471 Set_DT_Position (Prim, DT_Position (E));
5473 if not Is_Predefined_Dispatching_Alias (E) then
5474 Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
5478 Next_Elmt (Prim_Elmt);
5481 -- Third stage: Fix the position of all the new primitives
5482 -- Entries associated with primitives covering interfaces
5483 -- are handled in a latter round.
5485 Prim_Elmt := First_Prim;
5486 while Present (Prim_Elmt) loop
5487 Prim := Node (Prim_Elmt);
5489 -- Skip primitives previously set entries
5491 if DT_Position (Prim) /= No_Uint then
5494 -- Primitives covering interface primitives are handled later
5496 elsif Present (Abstract_Interface_Alias (Prim)) then
5500 -- Take the next available position in the DT
5503 Nb_Prim := Nb_Prim + 1;
5504 pragma Assert (Nb_Prim <= Count_Prim);
5505 exit when not Fixed_Prim (Nb_Prim);
5508 Set_DT_Position (Prim, UI_From_Int (Nb_Prim));
5509 Set_Fixed_Prim (Nb_Prim);
5512 Next_Elmt (Prim_Elmt);
5516 -- Fourth stage: Complete the decoration of primitives covering
5517 -- interfaces (that is, propagate the DT_Position attribute
5518 -- from the aliased primitive)
5520 Prim_Elmt := First_Prim;
5521 while Present (Prim_Elmt) loop
5522 Prim := Node (Prim_Elmt);
5524 if DT_Position (Prim) = No_Uint
5525 and then Present (Abstract_Interface_Alias (Prim))
5527 pragma Assert (Present (Alias (Prim))
5528 and then Find_Dispatching_Type (Alias (Prim)) = Typ);
5530 -- Check if this entry will be placed in the primary DT
5532 if Is_Parent (Find_Dispatching_Type
5533 (Abstract_Interface_Alias (Prim)),
5536 pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
5537 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
5539 -- Otherwise it will be placed in the secondary DT
5543 (DT_Position (Abstract_Interface_Alias (Prim)) /= No_Uint);
5544 Set_DT_Position (Prim,
5545 DT_Position (Abstract_Interface_Alias (Prim)));
5549 Next_Elmt (Prim_Elmt);
5552 -- Generate listing showing the contents of the dispatch tables.
5553 -- This action is done before some further static checks because
5554 -- in case of critical errors caused by a wrong dispatch table
5555 -- we need to see the contents of such table.
5557 if Debug_Flag_ZZ then
5561 -- Final stage: Ensure that the table is correct plus some further
5562 -- verifications concerning the primitives.
5564 Prim_Elmt := First_Prim;
5566 while Present (Prim_Elmt) loop
5567 Prim := Node (Prim_Elmt);
5569 -- At this point all the primitives MUST have a position
5570 -- in the dispatch table
5572 if DT_Position (Prim) = No_Uint then
5573 raise Program_Error;
5576 -- Calculate real size of the dispatch table
5578 if not (Is_Predefined_Dispatching_Operation (Prim)
5579 or else Is_Predefined_Dispatching_Alias (Prim))
5580 and then UI_To_Int (DT_Position (Prim)) > DT_Length
5582 DT_Length := UI_To_Int (DT_Position (Prim));
5585 -- Ensure that the asignated position to non-predefined
5586 -- dispatching operations in the dispatch table is correct.
5588 if not (Is_Predefined_Dispatching_Operation (Prim)
5589 or else Is_Predefined_Dispatching_Alias (Prim))
5591 Validate_Position (Prim);
5594 if Chars (Prim) = Name_Finalize then
5598 if Chars (Prim) = Name_Adjust then
5602 -- An abstract operation cannot be declared in the private part
5603 -- for a visible abstract type, because it could never be over-
5604 -- ridden. For explicit declarations this is checked at the
5605 -- point of declaration, but for inherited operations it must
5606 -- be done when building the dispatch table.
5608 -- Ada 2005 (AI-251): Hidden entities associated with abstract
5609 -- interface primitives are not taken into account because the
5610 -- check is done with the aliased primitive.
5612 if Is_Abstract_Type (Typ)
5613 and then Is_Abstract_Subprogram (Prim)
5614 and then Present (Alias (Prim))
5615 and then not Present (Abstract_Interface_Alias (Prim))
5616 and then Is_Derived_Type (Typ)
5617 and then In_Private_Part (Current_Scope)
5619 List_Containing (Parent (Prim)) =
5620 Private_Declarations
5621 (Specification (Unit_Declaration_Node (Current_Scope)))
5622 and then Original_View_In_Visible_Part (Typ)
5624 -- We exclude Input and Output stream operations because
5625 -- Limited_Controlled inherits useless Input and Output
5626 -- stream operations from Root_Controlled, which can
5627 -- never be overridden.
5629 if not Is_TSS (Prim, TSS_Stream_Input)
5631 not Is_TSS (Prim, TSS_Stream_Output)
5634 ("abstract inherited private operation&" &
5635 " must be overridden (RM 3.9.3(10))",
5636 Parent (Typ), Prim);
5640 Next_Elmt (Prim_Elmt);
5645 if Is_Controlled (Typ) then
5646 if not Finalized then
5648 ("controlled type has no explicit Finalize method?", Typ);
5650 elsif not Adjusted then
5652 ("controlled type has no explicit Adjust method?", Typ);
5656 -- Set the final size of the Dispatch Table
5658 Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));
5660 -- The derived type must have at least as many components as its parent
5661 -- (for root types, the Etype points back to itself and the test cannot
5664 if DT_Entry_Count (The_Tag) <
5665 DT_Entry_Count (First_Tag_Component (Parent_Typ))
5667 raise Program_Error;
5669 end Set_All_DT_Position;
5671 -----------------------------
5672 -- Set_Default_Constructor --
5673 -----------------------------
5675 procedure Set_Default_Constructor (Typ : Entity_Id) is
5682 -- Look for the default constructor entity. For now only the
5683 -- default constructor has the flag Is_Constructor.
5685 E := Next_Entity (Typ);
5687 and then (Ekind (E) /= E_Function or else not Is_Constructor (E))
5692 -- Create the init procedure
5696 Init := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
5697 Param := Make_Defining_Identifier (Loc, Name_X);
5700 Make_Subprogram_Declaration (Loc,
5701 Make_Procedure_Specification (Loc,
5702 Defining_Unit_Name => Init,
5703 Parameter_Specifications => New_List (
5704 Make_Parameter_Specification (Loc,
5705 Defining_Identifier => Param,
5706 Parameter_Type => New_Reference_To (Typ, Loc))))));
5708 Set_Init_Proc (Typ, Init);
5709 Set_Is_Imported (Init);
5710 Set_Interface_Name (Init, Interface_Name (E));
5711 Set_Convention (Init, Convention_C);
5712 Set_Is_Public (Init);
5713 Set_Has_Completion (Init);
5715 -- If there are no constructors, mark the type as abstract since we
5716 -- won't be able to declare objects of that type.
5719 Set_Is_Abstract_Type (Typ);
5721 end Set_Default_Constructor;
5723 --------------------------
5724 -- Set_DTC_Entity_Value --
5725 --------------------------
5727 procedure Set_DTC_Entity_Value
5728 (Tagged_Type : Entity_Id;
5732 if Present (Abstract_Interface_Alias (Prim))
5733 and then Is_Interface
5734 (Find_Dispatching_Type
5735 (Abstract_Interface_Alias (Prim)))
5737 Set_DTC_Entity (Prim,
5740 Iface => Find_Dispatching_Type
5741 (Abstract_Interface_Alias (Prim))));
5743 Set_DTC_Entity (Prim,
5744 First_Tag_Component (Tagged_Type));
5746 end Set_DTC_Entity_Value;
5752 function Tagged_Kind (T : Entity_Id) return Node_Id is
5753 Conc_Typ : Entity_Id;
5754 Loc : constant Source_Ptr := Sloc (T);
5758 (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));
5762 if Is_Abstract_Type (T) then
5763 if Is_Limited_Record (T) then
5764 return New_Reference_To (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
5766 return New_Reference_To (RTE (RE_TK_Abstract_Tagged), Loc);
5771 elsif Is_Concurrent_Record_Type (T) then
5772 Conc_Typ := Corresponding_Concurrent_Type (T);
5774 if Present (Full_View (Conc_Typ)) then
5775 Conc_Typ := Full_View (Conc_Typ);
5778 if Ekind (Conc_Typ) = E_Protected_Type then
5779 return New_Reference_To (RTE (RE_TK_Protected), Loc);
5781 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
5782 return New_Reference_To (RTE (RE_TK_Task), Loc);
5785 -- Regular tagged kinds
5788 if Is_Limited_Record (T) then
5789 return New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc);
5791 return New_Reference_To (RTE (RE_TK_Tagged), Loc);
5800 procedure Write_DT (Typ : Entity_Id) is
5805 -- Protect this procedure against wrong usage. Required because it will
5806 -- be used directly from GDB
5808 if not (Typ <= Last_Node_Id)
5809 or else not Is_Tagged_Type (Typ)
5811 Write_Str ("wrong usage: Write_DT must be used with tagged types");
5816 Write_Int (Int (Typ));
5818 Write_Name (Chars (Typ));
5820 if Is_Interface (Typ) then
5821 Write_Str (" is interface");
5826 Elmt := First_Elmt (Primitive_Operations (Typ));
5827 while Present (Elmt) loop
5828 Prim := Node (Elmt);
5831 -- Indicate if this primitive will be allocated in the primary
5832 -- dispatch table or in a secondary dispatch table associated
5833 -- with an abstract interface type
5835 if Present (DTC_Entity (Prim)) then
5836 if Etype (DTC_Entity (Prim)) = RTE (RE_Tag) then
5843 -- Output the node of this primitive operation and its name
5845 Write_Int (Int (Prim));
5848 if Is_Predefined_Dispatching_Operation (Prim) then
5849 Write_Str ("(predefined) ");
5852 Write_Name (Chars (Prim));
5854 -- Indicate if this primitive has an aliased primitive
5856 if Present (Alias (Prim)) then
5857 Write_Str (" (alias = ");
5858 Write_Int (Int (Alias (Prim)));
5860 -- If the DTC_Entity attribute is already set we can also output
5861 -- the name of the interface covered by this primitive (if any)
5863 if Present (DTC_Entity (Alias (Prim)))
5864 and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
5866 Write_Str (" from interface ");
5867 Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
5870 if Present (Abstract_Interface_Alias (Prim)) then
5871 Write_Str (", AI_Alias of ");
5872 Write_Name (Chars (Scope (DTC_Entity
5873 (Abstract_Interface_Alias (Prim)))));
5875 Write_Int (Int (Abstract_Interface_Alias (Prim)));
5881 -- Display the final position of this primitive in its associated
5882 -- (primary or secondary) dispatch table
5884 if Present (DTC_Entity (Prim))
5885 and then DT_Position (Prim) /= No_Uint
5887 Write_Str (" at #");
5888 Write_Int (UI_To_Int (DT_Position (Prim)));
5891 if Is_Abstract_Subprogram (Prim) then
5892 Write_Str (" is abstract;");
5894 -- Check if this is a null primitive
5896 elsif Comes_From_Source (Prim)
5897 and then Ekind (Prim) = E_Procedure
5898 and then Null_Present (Parent (Prim))
5900 Write_Str (" is null;");