* gcc.dg/compat/struct-layout-1_generate.c (dg_options): New. Moved
[official-gcc.git] / gcc / ada / exp_disp.adb
blobb44ea2e3027c5cbf3ba4f8468f32c605643d9e72
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ D I S P --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
10 -- --
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. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
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;
42 with Opt; use Opt;
43 with Output; use Output;
44 with Restrict; use Restrict;
45 with Rident; use Rident;
46 with Rtsfind; use Rtsfind;
47 with Sem; use Sem;
48 with Sem_Ch6; use Sem_Ch6;
49 with Sem_Ch7; use Sem_Ch7;
50 with Sem_Ch8; use Sem_Ch8;
51 with Sem_Disp; use Sem_Disp;
52 with Sem_Eval; use Sem_Eval;
53 with Sem_Res; use Sem_Res;
54 with Sem_Type; use Sem_Type;
55 with Sem_Util; use Sem_Util;
56 with Sinfo; use Sinfo;
57 with Snames; use Snames;
58 with Stand; use Stand;
59 with Stringt; use Stringt;
60 with Targparm; use Targparm;
61 with Tbuild; use Tbuild;
62 with Uintp; use Uintp;
64 package body Exp_Disp is
66 -----------------------
67 -- Local Subprograms --
68 -----------------------
70 function Default_Prim_Op_Position (E : Entity_Id) return Uint;
71 -- Ada 2005 (AI-251): Returns the fixed position in the dispatch table
72 -- of the default primitive operations.
74 function Has_DT (Typ : Entity_Id) return Boolean;
75 pragma Inline (Has_DT);
76 -- Returns true if we generate a dispatch table for tagged type Typ
78 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean;
79 -- Returns true if Prim is not a predefined dispatching primitive but it is
80 -- an alias of a predefined dispatching primitive (i.e. through a renaming)
82 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean;
83 -- Check if the type has a private view or if the public view appears
84 -- in the visible part of a package spec.
86 function Prim_Op_Kind
87 (Prim : Entity_Id;
88 Typ : Entity_Id) return Node_Id;
89 -- Ada 2005 (AI-345): Determine the primitive operation kind of Prim
90 -- according to its type Typ. Return a reference to an RE_Prim_Op_Kind
91 -- enumeration value.
93 function Tagged_Kind (T : Entity_Id) return Node_Id;
94 -- Ada 2005 (AI-345): Determine the tagged kind of T and return a reference
95 -- to an RE_Tagged_Kind enumeration value.
97 ------------------------
98 -- Building_Static_DT --
99 ------------------------
101 function Building_Static_DT (Typ : Entity_Id) return Boolean is
102 Root_Typ : Entity_Id := Root_Type (Typ);
104 begin
105 -- Handle private types
107 if Present (Full_View (Root_Typ)) then
108 Root_Typ := Full_View (Root_Typ);
109 end if;
111 return Static_Dispatch_Tables
112 and then Is_Library_Level_Tagged_Type (Typ)
114 -- If the type is derived from a CPP class we cannot statically
115 -- build the dispatch tables because we must inherit primitives
116 -- from the CPP side.
118 and then not Is_CPP_Class (Root_Typ);
119 end Building_Static_DT;
121 ----------------------------------
122 -- Build_Static_Dispatch_Tables --
123 ----------------------------------
125 procedure Build_Static_Dispatch_Tables (N : Entity_Id) is
126 Target_List : List_Id;
128 procedure Build_Dispatch_Tables (List : List_Id);
129 -- Build the static dispatch table of tagged types found in the list of
130 -- declarations. The generated nodes are added at the end of Target_List
132 procedure Build_Package_Dispatch_Tables (N : Node_Id);
133 -- Build static dispatch tables associated with package declaration N
135 ---------------------------
136 -- Build_Dispatch_Tables --
137 ---------------------------
139 procedure Build_Dispatch_Tables (List : List_Id) is
140 D : Node_Id;
142 begin
143 D := First (List);
144 while Present (D) loop
146 -- Handle nested packages and package bodies recursively. The
147 -- generated code is placed on the Target_List established for
148 -- the enclosing compilation unit.
150 if Nkind (D) = N_Package_Declaration then
151 Build_Package_Dispatch_Tables (D);
153 elsif Nkind (D) = N_Package_Body then
154 Build_Dispatch_Tables (Declarations (D));
156 elsif Nkind (D) = N_Package_Body_Stub
157 and then Present (Library_Unit (D))
158 then
159 Build_Dispatch_Tables
160 (Declarations (Proper_Body (Unit (Library_Unit (D)))));
162 -- Handle full type declarations and derivations of library
163 -- level tagged types
165 elsif (Nkind (D) = N_Full_Type_Declaration
166 or else Nkind (D) = N_Derived_Type_Definition)
167 and then Is_Library_Level_Tagged_Type (Defining_Entity (D))
168 and then Ekind (Defining_Entity (D)) /= E_Record_Subtype
169 and then not Is_Private_Type (Defining_Entity (D))
170 then
171 Insert_List_After_And_Analyze (Last (Target_List),
172 Make_DT (Defining_Entity (D)));
174 -- Handle private types of library level tagged types. We must
175 -- exchange the private and full-view to ensure the correct
176 -- expansion. If the full view is a synchronized type ignore
177 -- the type because the table will be built for the corresponding
178 -- record type, that has its own declaration.
180 elsif (Nkind (D) = N_Private_Type_Declaration
181 or else Nkind (D) = N_Private_Extension_Declaration)
182 and then Present (Full_View (Defining_Entity (D)))
183 then
184 declare
185 E1 : constant Entity_Id := Defining_Entity (D);
186 E2 : constant Entity_Id := Full_View (E1);
188 begin
189 if Is_Library_Level_Tagged_Type (E2)
190 and then Ekind (E2) /= E_Record_Subtype
191 and then not Is_Concurrent_Type (E2)
192 then
193 Exchange_Declarations (E1);
194 Insert_List_After_And_Analyze (Last (Target_List),
195 Make_DT (E1));
196 Exchange_Declarations (E2);
197 end if;
198 end;
199 end if;
201 Next (D);
202 end loop;
203 end Build_Dispatch_Tables;
205 -----------------------------------
206 -- Build_Package_Dispatch_Tables --
207 -----------------------------------
209 procedure Build_Package_Dispatch_Tables (N : Node_Id) is
210 Spec : constant Node_Id := Specification (N);
211 Id : constant Entity_Id := Defining_Entity (N);
212 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
213 Priv_Decls : constant List_Id := Private_Declarations (Spec);
215 begin
216 Push_Scope (Id);
218 if Present (Priv_Decls) then
219 Build_Dispatch_Tables (Vis_Decls);
220 Build_Dispatch_Tables (Priv_Decls);
222 elsif Present (Vis_Decls) then
223 Build_Dispatch_Tables (Vis_Decls);
224 end if;
226 Pop_Scope;
227 end Build_Package_Dispatch_Tables;
229 -- Start of processing for Build_Static_Dispatch_Tables
231 begin
232 if not Expander_Active
233 or else VM_Target /= No_VM
234 then
235 return;
236 end if;
238 if Nkind (N) = N_Package_Declaration then
239 declare
240 Spec : constant Node_Id := Specification (N);
241 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
242 Priv_Decls : constant List_Id := Private_Declarations (Spec);
244 begin
245 if Present (Priv_Decls)
246 and then Is_Non_Empty_List (Priv_Decls)
247 then
248 Target_List := Priv_Decls;
250 elsif not Present (Vis_Decls) then
251 Target_List := New_List;
252 Set_Private_Declarations (Spec, Target_List);
253 else
254 Target_List := Vis_Decls;
255 end if;
257 Build_Package_Dispatch_Tables (N);
258 end;
260 else pragma Assert (Nkind (N) = N_Package_Body);
261 Target_List := Declarations (N);
262 Build_Dispatch_Tables (Target_List);
263 end if;
264 end Build_Static_Dispatch_Tables;
266 ------------------------------
267 -- Default_Prim_Op_Position --
268 ------------------------------
270 function Default_Prim_Op_Position (E : Entity_Id) return Uint is
271 TSS_Name : TSS_Name_Type;
273 begin
274 Get_Name_String (Chars (E));
275 TSS_Name :=
276 TSS_Name_Type
277 (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
279 if Chars (E) = Name_uSize then
280 return Uint_1;
282 elsif Chars (E) = Name_uAlignment then
283 return Uint_2;
285 elsif TSS_Name = TSS_Stream_Read then
286 return Uint_3;
288 elsif TSS_Name = TSS_Stream_Write then
289 return Uint_4;
291 elsif TSS_Name = TSS_Stream_Input then
292 return Uint_5;
294 elsif TSS_Name = TSS_Stream_Output then
295 return Uint_6;
297 elsif Chars (E) = Name_Op_Eq then
298 return Uint_7;
300 elsif Chars (E) = Name_uAssign then
301 return Uint_8;
303 elsif TSS_Name = TSS_Deep_Adjust then
304 return Uint_9;
306 elsif TSS_Name = TSS_Deep_Finalize then
307 return Uint_10;
309 elsif Ada_Version >= Ada_05 then
310 if Chars (E) = Name_uDisp_Asynchronous_Select then
311 return Uint_11;
313 elsif Chars (E) = Name_uDisp_Conditional_Select then
314 return Uint_12;
316 elsif Chars (E) = Name_uDisp_Get_Prim_Op_Kind then
317 return Uint_13;
319 elsif Chars (E) = Name_uDisp_Get_Task_Id then
320 return Uint_14;
322 elsif Chars (E) = Name_uDisp_Requeue then
323 return Uint_15;
325 elsif Chars (E) = Name_uDisp_Timed_Select then
326 return Uint_16;
327 end if;
328 end if;
330 raise Program_Error;
331 end Default_Prim_Op_Position;
333 -----------------------------
334 -- Expand_Dispatching_Call --
335 -----------------------------
337 procedure Expand_Dispatching_Call (Call_Node : Node_Id) is
338 Loc : constant Source_Ptr := Sloc (Call_Node);
339 Call_Typ : constant Entity_Id := Etype (Call_Node);
341 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
342 Ctrl_Typ : constant Entity_Id := Base_Type (Etype (Ctrl_Arg));
343 Param_List : constant List_Id := Parameter_Associations (Call_Node);
345 Subp : Entity_Id;
346 CW_Typ : Entity_Id;
347 New_Call : Node_Id;
348 New_Call_Name : Node_Id;
349 New_Params : List_Id := No_List;
350 Param : Node_Id;
351 Res_Typ : Entity_Id;
352 Subp_Ptr_Typ : Entity_Id;
353 Subp_Typ : Entity_Id;
354 Typ : Entity_Id;
355 Eq_Prim_Op : Entity_Id := Empty;
356 Controlling_Tag : Node_Id;
358 function New_Value (From : Node_Id) return Node_Id;
359 -- From is the original Expression. New_Value is equivalent to a call
360 -- to Duplicate_Subexpr with an explicit dereference when From is an
361 -- access parameter.
363 ---------------
364 -- New_Value --
365 ---------------
367 function New_Value (From : Node_Id) return Node_Id is
368 Res : constant Node_Id := Duplicate_Subexpr (From);
369 begin
370 if Is_Access_Type (Etype (From)) then
371 return
372 Make_Explicit_Dereference (Sloc (From),
373 Prefix => Res);
374 else
375 return Res;
376 end if;
377 end New_Value;
379 -- Start of processing for Expand_Dispatching_Call
381 begin
382 if No_Run_Time_Mode then
383 Error_Msg_CRT ("tagged types", Call_Node);
384 return;
385 end if;
387 -- Expand_Dispatching_Call is called directly from the semantics,
388 -- so we need a check to see whether expansion is active before
389 -- proceeding. In addition, there is no need to expand the call
390 -- if we are compiling under restriction No_Dispatching_Calls;
391 -- the semantic analyzer has previously notified the violation
392 -- of this restriction.
394 if not Expander_Active
395 or else Restriction_Active (No_Dispatching_Calls)
396 then
397 return;
398 end if;
400 -- Set subprogram. If this is an inherited operation that was
401 -- overridden, the body that is being called is its alias.
403 Subp := Entity (Name (Call_Node));
405 if Present (Alias (Subp))
406 and then Is_Inherited_Operation (Subp)
407 and then No (DTC_Entity (Subp))
408 then
409 Subp := Alias (Subp);
410 end if;
412 -- Definition of the class-wide type and the tagged type
414 -- If the controlling argument is itself a tag rather than a tagged
415 -- object, then use the class-wide type associated with the subprogram's
416 -- controlling type. This case can occur when a call to an inherited
417 -- primitive has an actual that originated from a default parameter
418 -- given by a tag-indeterminate call and when there is no other
419 -- controlling argument providing the tag (AI-239 requires dispatching).
420 -- This capability of dispatching directly by tag is also needed by the
421 -- implementation of AI-260 (for the generic dispatching constructors).
423 if Ctrl_Typ = RTE (RE_Tag)
424 or else (RTE_Available (RE_Interface_Tag)
425 and then Ctrl_Typ = RTE (RE_Interface_Tag))
426 then
427 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
429 -- Class_Wide_Type is applied to the expressions used to initialize
430 -- CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
431 -- there are cases where the controlling type is resolved to a specific
432 -- type (such as for designated types of arguments such as CW'Access).
434 elsif Is_Access_Type (Ctrl_Typ) then
435 CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));
437 else
438 CW_Typ := Class_Wide_Type (Ctrl_Typ);
439 end if;
441 Typ := Root_Type (CW_Typ);
443 if Ekind (Typ) = E_Incomplete_Type then
444 Typ := Non_Limited_View (Typ);
445 end if;
447 if not Is_Limited_Type (Typ) then
448 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
449 end if;
451 -- Dispatching call to C++ primitive. Create a new parameter list
452 -- with no tag checks.
454 if Is_CPP_Class (Typ) then
455 New_Params := New_List;
456 Param := First_Actual (Call_Node);
457 while Present (Param) loop
458 Append_To (New_Params, Relocate_Node (Param));
459 Next_Actual (Param);
460 end loop;
462 -- Dispatching call to Ada primitive
464 elsif Present (Param_List) then
466 -- Generate the Tag checks when appropriate
468 New_Params := New_List;
469 Param := First_Actual (Call_Node);
470 while Present (Param) loop
472 -- No tag check with itself
474 if Param = Ctrl_Arg then
475 Append_To (New_Params,
476 Duplicate_Subexpr_Move_Checks (Param));
478 -- No tag check for parameter whose type is neither tagged nor
479 -- access to tagged (for access parameters)
481 elsif No (Find_Controlling_Arg (Param)) then
482 Append_To (New_Params, Relocate_Node (Param));
484 -- No tag check for function dispatching on result if the
485 -- Tag given by the context is this one
487 elsif Find_Controlling_Arg (Param) = Ctrl_Arg then
488 Append_To (New_Params, Relocate_Node (Param));
490 -- "=" is the only dispatching operation allowed to get
491 -- operands with incompatible tags (it just returns false).
492 -- We use Duplicate_Subexpr_Move_Checks instead of calling
493 -- Relocate_Node because the value will be duplicated to
494 -- check the tags.
496 elsif Subp = Eq_Prim_Op then
497 Append_To (New_Params,
498 Duplicate_Subexpr_Move_Checks (Param));
500 -- No check in presence of suppress flags
502 elsif Tag_Checks_Suppressed (Etype (Param))
503 or else (Is_Access_Type (Etype (Param))
504 and then Tag_Checks_Suppressed
505 (Designated_Type (Etype (Param))))
506 then
507 Append_To (New_Params, Relocate_Node (Param));
509 -- Optimization: no tag checks if the parameters are identical
511 elsif Is_Entity_Name (Param)
512 and then Is_Entity_Name (Ctrl_Arg)
513 and then Entity (Param) = Entity (Ctrl_Arg)
514 then
515 Append_To (New_Params, Relocate_Node (Param));
517 -- Now we need to generate the Tag check
519 else
520 -- Generate code for tag equality check
521 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
523 Insert_Action (Ctrl_Arg,
524 Make_Implicit_If_Statement (Call_Node,
525 Condition =>
526 Make_Op_Ne (Loc,
527 Left_Opnd =>
528 Make_Selected_Component (Loc,
529 Prefix => New_Value (Ctrl_Arg),
530 Selector_Name =>
531 New_Reference_To
532 (First_Tag_Component (Typ), Loc)),
534 Right_Opnd =>
535 Make_Selected_Component (Loc,
536 Prefix =>
537 Unchecked_Convert_To (Typ, New_Value (Param)),
538 Selector_Name =>
539 New_Reference_To
540 (First_Tag_Component (Typ), Loc))),
542 Then_Statements =>
543 New_List (New_Constraint_Error (Loc))));
545 Append_To (New_Params, Relocate_Node (Param));
546 end if;
548 Next_Actual (Param);
549 end loop;
550 end if;
552 -- Generate the appropriate subprogram pointer type
554 if Etype (Subp) = Typ then
555 Res_Typ := CW_Typ;
556 else
557 Res_Typ := Etype (Subp);
558 end if;
560 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
561 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
562 Set_Etype (Subp_Typ, Res_Typ);
563 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
565 -- Create a new list of parameters which is a copy of the old formal
566 -- list including the creation of a new set of matching entities.
568 declare
569 Old_Formal : Entity_Id := First_Formal (Subp);
570 New_Formal : Entity_Id;
571 Extra : Entity_Id := Empty;
573 begin
574 if Present (Old_Formal) then
575 New_Formal := New_Copy (Old_Formal);
576 Set_First_Entity (Subp_Typ, New_Formal);
577 Param := First_Actual (Call_Node);
579 loop
580 Set_Scope (New_Formal, Subp_Typ);
582 -- Change all the controlling argument types to be class-wide
583 -- to avoid a recursion in dispatching.
585 if Is_Controlling_Formal (New_Formal) then
586 Set_Etype (New_Formal, Etype (Param));
587 end if;
589 -- If the type of the formal is an itype, there was code here
590 -- introduced in 1998 in revision 1.46, to create a new itype
591 -- by copy. This seems useless, and in fact leads to semantic
592 -- errors when the itype is the completion of a type derived
593 -- from a private type.
595 Extra := New_Formal;
596 Next_Formal (Old_Formal);
597 exit when No (Old_Formal);
599 Set_Next_Entity (New_Formal, New_Copy (Old_Formal));
600 Next_Entity (New_Formal);
601 Next_Actual (Param);
602 end loop;
604 Set_Next_Entity (New_Formal, Empty);
605 Set_Last_Entity (Subp_Typ, Extra);
606 end if;
608 -- Now that the explicit formals have been duplicated, any extra
609 -- formals needed by the subprogram must be created.
611 if Present (Extra) then
612 Set_Extra_Formal (Extra, Empty);
613 end if;
615 Create_Extra_Formals (Subp_Typ);
616 end;
618 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
619 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
620 Set_Convention (Subp_Ptr_Typ, Convention (Subp_Typ));
622 -- If the controlling argument is a value of type Ada.Tag or an abstract
623 -- interface class-wide type then use it directly. Otherwise, the tag
624 -- must be extracted from the controlling object.
626 if Ctrl_Typ = RTE (RE_Tag)
627 or else (RTE_Available (RE_Interface_Tag)
628 and then Ctrl_Typ = RTE (RE_Interface_Tag))
629 then
630 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
632 -- Extract the tag from an unchecked type conversion. Done to avoid
633 -- the expansion of additional code just to obtain the value of such
634 -- tag because the current management of interface type conversions
635 -- generates in some cases this unchecked type conversion with the
636 -- tag of the object (see Expand_Interface_Conversion).
638 elsif Nkind (Ctrl_Arg) = N_Unchecked_Type_Conversion
639 and then
640 (Etype (Expression (Ctrl_Arg)) = RTE (RE_Tag)
641 or else
642 (RTE_Available (RE_Interface_Tag)
643 and then
644 Etype (Expression (Ctrl_Arg)) = RTE (RE_Interface_Tag)))
645 then
646 Controlling_Tag := Duplicate_Subexpr (Expression (Ctrl_Arg));
648 -- Ada 2005 (AI-251): Abstract interface class-wide type
650 elsif Is_Interface (Ctrl_Typ)
651 and then Is_Class_Wide_Type (Ctrl_Typ)
652 then
653 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
655 else
656 Controlling_Tag :=
657 Make_Selected_Component (Loc,
658 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
659 Selector_Name => New_Reference_To (DTC_Entity (Subp), Loc));
660 end if;
662 -- Handle dispatching calls to predefined primitives
664 if Is_Predefined_Dispatching_Operation (Subp)
665 or else Is_Predefined_Dispatching_Alias (Subp)
666 then
667 New_Call_Name :=
668 Unchecked_Convert_To (Subp_Ptr_Typ,
669 Build_Get_Predefined_Prim_Op_Address (Loc,
670 Tag_Node => Controlling_Tag,
671 Position => DT_Position (Subp)));
673 -- Handle dispatching calls to user-defined primitives
675 else
676 New_Call_Name :=
677 Unchecked_Convert_To (Subp_Ptr_Typ,
678 Build_Get_Prim_Op_Address (Loc,
679 Typ => Find_Dispatching_Type (Subp),
680 Tag_Node => Controlling_Tag,
681 Position => DT_Position (Subp)));
682 end if;
684 if Nkind (Call_Node) = N_Function_Call then
686 New_Call :=
687 Make_Function_Call (Loc,
688 Name => New_Call_Name,
689 Parameter_Associations => New_Params);
691 -- If this is a dispatching "=", we must first compare the tags so
692 -- we generate: x.tag = y.tag and then x = y
694 if Subp = Eq_Prim_Op then
695 Param := First_Actual (Call_Node);
696 New_Call :=
697 Make_And_Then (Loc,
698 Left_Opnd =>
699 Make_Op_Eq (Loc,
700 Left_Opnd =>
701 Make_Selected_Component (Loc,
702 Prefix => New_Value (Param),
703 Selector_Name =>
704 New_Reference_To (First_Tag_Component (Typ),
705 Loc)),
707 Right_Opnd =>
708 Make_Selected_Component (Loc,
709 Prefix =>
710 Unchecked_Convert_To (Typ,
711 New_Value (Next_Actual (Param))),
712 Selector_Name =>
713 New_Reference_To (First_Tag_Component (Typ),
714 Loc))),
715 Right_Opnd => New_Call);
716 end if;
718 else
719 New_Call :=
720 Make_Procedure_Call_Statement (Loc,
721 Name => New_Call_Name,
722 Parameter_Associations => New_Params);
723 end if;
725 Rewrite (Call_Node, New_Call);
727 -- Suppress all checks during the analysis of the expanded code
728 -- to avoid the generation of spurious warnings under ZFP run-time.
730 Analyze_And_Resolve (Call_Node, Call_Typ, Suppress => All_Checks);
731 end Expand_Dispatching_Call;
733 ---------------------------------
734 -- Expand_Interface_Conversion --
735 ---------------------------------
737 procedure Expand_Interface_Conversion
738 (N : Node_Id;
739 Is_Static : Boolean := True)
741 Loc : constant Source_Ptr := Sloc (N);
742 Etyp : constant Entity_Id := Etype (N);
743 Operand : constant Node_Id := Expression (N);
744 Operand_Typ : Entity_Id := Etype (Operand);
745 Func : Node_Id;
746 Iface_Typ : Entity_Id := Etype (N);
747 Iface_Tag : Entity_Id;
749 begin
750 -- Ada 2005 (AI-345): Handle synchronized interface type derivations
752 if Is_Concurrent_Type (Operand_Typ) then
753 Operand_Typ := Base_Type (Corresponding_Record_Type (Operand_Typ));
754 end if;
756 -- Handle access to class-wide interface types
758 if Is_Access_Type (Iface_Typ) then
759 Iface_Typ := Etype (Directly_Designated_Type (Iface_Typ));
760 end if;
762 -- Handle class-wide interface types. This conversion can appear
763 -- explicitly in the source code. Example: I'Class (Obj)
765 if Is_Class_Wide_Type (Iface_Typ) then
766 Iface_Typ := Root_Type (Iface_Typ);
767 end if;
769 -- If the target type is a tagged synchronized type, the dispatch table
770 -- info is in the corresponding record type.
772 if Is_Concurrent_Type (Iface_Typ) then
773 Iface_Typ := Corresponding_Record_Type (Iface_Typ);
774 end if;
776 -- Freeze the entity associated with the target interface to have
777 -- available the attribute Access_Disp_Table.
779 Freeze_Before (N, Iface_Typ);
781 pragma Assert (not Is_Static
782 or else (not Is_Class_Wide_Type (Iface_Typ)
783 and then Is_Interface (Iface_Typ)));
785 if VM_Target /= No_VM then
787 -- For VM, just do a conversion ???
789 Rewrite (N, Unchecked_Convert_To (Etype (N), N));
790 Analyze (N);
791 return;
792 end if;
794 if not Is_Static then
796 -- Give error if configurable run time and Displace not available
798 if not RTE_Available (RE_Displace) then
799 Error_Msg_CRT ("dynamic interface conversion", N);
800 return;
801 end if;
803 -- Handle conversion of access-to-class-wide interface types. Target
804 -- can be an access to an object or an access to another class-wide
805 -- interface (see -1- and -2- in the following example):
807 -- type Iface1_Ref is access all Iface1'Class;
808 -- type Iface2_Ref is access all Iface1'Class;
810 -- Acc1 : Iface1_Ref := new ...
811 -- Obj : Obj_Ref := Obj_Ref (Acc); -- 1
812 -- Acc2 : Iface2_Ref := Iface2_Ref (Acc); -- 2
814 if Is_Access_Type (Operand_Typ) then
815 Rewrite (N,
816 Unchecked_Convert_To (Etype (N),
817 Make_Function_Call (Loc,
818 Name => New_Reference_To (RTE (RE_Displace), Loc),
819 Parameter_Associations => New_List (
821 Unchecked_Convert_To (RTE (RE_Address),
822 Relocate_Node (Expression (N))),
824 New_Occurrence_Of
825 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
826 Loc)))));
828 Analyze (N);
829 return;
830 end if;
832 Rewrite (N,
833 Make_Function_Call (Loc,
834 Name => New_Reference_To (RTE (RE_Displace), Loc),
835 Parameter_Associations => New_List (
836 Make_Attribute_Reference (Loc,
837 Prefix => Relocate_Node (Expression (N)),
838 Attribute_Name => Name_Address),
840 New_Occurrence_Of
841 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
842 Loc))));
844 Analyze (N);
846 -- If the target is a class-wide interface we change the type of the
847 -- data returned by IW_Convert to indicate that this is a dispatching
848 -- call.
850 declare
851 New_Itype : Entity_Id;
853 begin
854 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
855 Set_Etype (New_Itype, New_Itype);
856 Set_Directly_Designated_Type (New_Itype, Etyp);
858 Rewrite (N,
859 Make_Explicit_Dereference (Loc,
860 Prefix =>
861 Unchecked_Convert_To (New_Itype, Relocate_Node (N))));
862 Analyze (N);
863 Freeze_Itype (New_Itype, N);
865 return;
866 end;
867 end if;
869 Iface_Tag := Find_Interface_Tag (Operand_Typ, Iface_Typ);
870 pragma Assert (Iface_Tag /= Empty);
872 -- Keep separate access types to interfaces because one internal
873 -- function is used to handle the null value (see following comment)
875 if not Is_Access_Type (Etype (N)) then
876 Rewrite (N,
877 Unchecked_Convert_To (Etype (N),
878 Make_Selected_Component (Loc,
879 Prefix => Relocate_Node (Expression (N)),
880 Selector_Name =>
881 New_Occurrence_Of (Iface_Tag, Loc))));
883 else
884 -- Build internal function to handle the case in which the
885 -- actual is null. If the actual is null returns null because
886 -- no displacement is required; otherwise performs a type
887 -- conversion that will be expanded in the code that returns
888 -- the value of the displaced actual. That is:
890 -- function Func (O : Address) return Iface_Typ is
891 -- type Op_Typ is access all Operand_Typ;
892 -- Aux : Op_Typ := To_Op_Typ (O);
893 -- begin
894 -- if O = Null_Address then
895 -- return null;
896 -- else
897 -- return Iface_Typ!(Aux.Iface_Tag'Address);
898 -- end if;
899 -- end Func;
901 declare
902 Desig_Typ : Entity_Id;
903 Fent : Entity_Id;
904 New_Typ_Decl : Node_Id;
905 Stats : List_Id;
907 begin
908 Desig_Typ := Etype (Expression (N));
910 if Is_Access_Type (Desig_Typ) then
911 Desig_Typ := Directly_Designated_Type (Desig_Typ);
912 end if;
914 if Is_Concurrent_Type (Desig_Typ) then
915 Desig_Typ := Base_Type (Corresponding_Record_Type (Desig_Typ));
916 end if;
918 New_Typ_Decl :=
919 Make_Full_Type_Declaration (Loc,
920 Defining_Identifier =>
921 Make_Defining_Identifier (Loc, New_Internal_Name ('T')),
922 Type_Definition =>
923 Make_Access_To_Object_Definition (Loc,
924 All_Present => True,
925 Null_Exclusion_Present => False,
926 Constant_Present => False,
927 Subtype_Indication =>
928 New_Reference_To (Desig_Typ, Loc)));
930 Stats := New_List (
931 Make_Simple_Return_Statement (Loc,
932 Unchecked_Convert_To (Etype (N),
933 Make_Attribute_Reference (Loc,
934 Prefix =>
935 Make_Selected_Component (Loc,
936 Prefix =>
937 Unchecked_Convert_To
938 (Defining_Identifier (New_Typ_Decl),
939 Make_Identifier (Loc, Name_uO)),
940 Selector_Name =>
941 New_Occurrence_Of (Iface_Tag, Loc)),
942 Attribute_Name => Name_Address))));
944 -- If the type is null-excluding, no need for the null branch.
945 -- Otherwise we need to check for it and return null.
947 if not Can_Never_Be_Null (Etype (N)) then
948 Stats := New_List (
949 Make_If_Statement (Loc,
950 Condition =>
951 Make_Op_Eq (Loc,
952 Left_Opnd => Make_Identifier (Loc, Name_uO),
953 Right_Opnd => New_Reference_To
954 (RTE (RE_Null_Address), Loc)),
956 Then_Statements => New_List (
957 Make_Simple_Return_Statement (Loc,
958 Make_Null (Loc))),
959 Else_Statements => Stats));
960 end if;
962 Fent :=
963 Make_Defining_Identifier (Loc,
964 New_Internal_Name ('F'));
966 Func :=
967 Make_Subprogram_Body (Loc,
968 Specification =>
969 Make_Function_Specification (Loc,
970 Defining_Unit_Name => Fent,
972 Parameter_Specifications => New_List (
973 Make_Parameter_Specification (Loc,
974 Defining_Identifier =>
975 Make_Defining_Identifier (Loc, Name_uO),
976 Parameter_Type =>
977 New_Reference_To (RTE (RE_Address), Loc))),
979 Result_Definition =>
980 New_Reference_To (Etype (N), Loc)),
982 Declarations => New_List (New_Typ_Decl),
984 Handled_Statement_Sequence =>
985 Make_Handled_Sequence_Of_Statements (Loc, Stats));
987 -- Place function body before the expression containing the
988 -- conversion. We suppress all checks because the body of the
989 -- internally generated function already takes care of the case
990 -- in which the actual is null; therefore there is no need to
991 -- double check that the pointer is not null when the program
992 -- executes the alternative that performs the type conversion).
994 Insert_Action (N, Func, Suppress => All_Checks);
996 if Is_Access_Type (Etype (Expression (N))) then
998 -- Generate: Func (Address!(Expression))
1000 Rewrite (N,
1001 Make_Function_Call (Loc,
1002 Name => New_Reference_To (Fent, Loc),
1003 Parameter_Associations => New_List (
1004 Unchecked_Convert_To (RTE (RE_Address),
1005 Relocate_Node (Expression (N))))));
1007 else
1008 -- Generate: Func (Operand_Typ!(Expression)'Address)
1010 Rewrite (N,
1011 Make_Function_Call (Loc,
1012 Name => New_Reference_To (Fent, Loc),
1013 Parameter_Associations => New_List (
1014 Make_Attribute_Reference (Loc,
1015 Prefix => Unchecked_Convert_To (Operand_Typ,
1016 Relocate_Node (Expression (N))),
1017 Attribute_Name => Name_Address))));
1018 end if;
1019 end;
1020 end if;
1022 Analyze (N);
1023 end Expand_Interface_Conversion;
1025 ------------------------------
1026 -- Expand_Interface_Actuals --
1027 ------------------------------
1029 procedure Expand_Interface_Actuals (Call_Node : Node_Id) is
1030 Actual : Node_Id;
1031 Actual_Dup : Node_Id;
1032 Actual_Typ : Entity_Id;
1033 Anon : Entity_Id;
1034 Conversion : Node_Id;
1035 Formal : Entity_Id;
1036 Formal_Typ : Entity_Id;
1037 Subp : Entity_Id;
1038 Formal_DDT : Entity_Id;
1039 Actual_DDT : Entity_Id;
1041 begin
1042 -- This subprogram is called directly from the semantics, so we need a
1043 -- check to see whether expansion is active before proceeding.
1045 if not Expander_Active then
1046 return;
1047 end if;
1049 -- Call using access to subprogram with explicit dereference
1051 if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
1052 Subp := Etype (Name (Call_Node));
1054 -- Call using selected component
1056 elsif Nkind (Name (Call_Node)) = N_Selected_Component then
1057 Subp := Entity (Selector_Name (Name (Call_Node)));
1059 -- Call using direct name
1061 else
1062 Subp := Entity (Name (Call_Node));
1063 end if;
1065 -- Ada 2005 (AI-251): Look for interface type formals to force "this"
1066 -- displacement
1068 Formal := First_Formal (Subp);
1069 Actual := First_Actual (Call_Node);
1070 while Present (Formal) loop
1071 Formal_Typ := Etype (Formal);
1073 if Ekind (Formal_Typ) = E_Record_Type_With_Private then
1074 Formal_Typ := Full_View (Formal_Typ);
1075 end if;
1077 if Is_Access_Type (Formal_Typ) then
1078 Formal_DDT := Directly_Designated_Type (Formal_Typ);
1079 end if;
1081 Actual_Typ := Etype (Actual);
1083 if Is_Access_Type (Actual_Typ) then
1084 Actual_DDT := Directly_Designated_Type (Actual_Typ);
1085 end if;
1087 if Is_Interface (Formal_Typ)
1088 and then Is_Class_Wide_Type (Formal_Typ)
1089 then
1090 -- No need to displace the pointer if the type of the actual
1091 -- coindices with the type of the formal.
1093 if Actual_Typ = Formal_Typ then
1094 null;
1096 -- No need to displace the pointer if the interface type is
1097 -- a parent of the type of the actual because in this case the
1098 -- interface primitives are located in the primary dispatch table.
1100 elsif Is_Ancestor (Formal_Typ, Actual_Typ) then
1101 null;
1103 -- Implicit conversion to the class-wide formal type to force
1104 -- the displacement of the pointer.
1106 else
1107 Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
1108 Rewrite (Actual, Conversion);
1109 Analyze_And_Resolve (Actual, Formal_Typ);
1110 end if;
1112 -- Access to class-wide interface type
1114 elsif Is_Access_Type (Formal_Typ)
1115 and then Is_Interface (Formal_DDT)
1116 and then Is_Class_Wide_Type (Formal_DDT)
1117 and then Interface_Present_In_Ancestor
1118 (Typ => Actual_DDT,
1119 Iface => Etype (Formal_DDT))
1120 then
1121 -- Handle attributes 'Access and 'Unchecked_Access
1123 if Nkind (Actual) = N_Attribute_Reference
1124 and then
1125 (Attribute_Name (Actual) = Name_Access
1126 or else Attribute_Name (Actual) = Name_Unchecked_Access)
1127 then
1128 -- This case must have been handled by the analysis and
1129 -- expansion of 'Access. The only exception is when types
1130 -- match and no further expansion is required.
1132 pragma Assert (Base_Type (Etype (Prefix (Actual)))
1133 = Base_Type (Formal_DDT));
1134 null;
1136 -- No need to displace the pointer if the type of the actual
1137 -- coincides with the type of the formal.
1139 elsif Actual_DDT = Formal_DDT then
1140 null;
1142 -- No need to displace the pointer if the interface type is
1143 -- a parent of the type of the actual because in this case the
1144 -- interface primitives are located in the primary dispatch table.
1146 elsif Is_Ancestor (Formal_DDT, Actual_DDT) then
1147 null;
1149 else
1150 Actual_Dup := Relocate_Node (Actual);
1152 if From_With_Type (Actual_Typ) then
1154 -- If the type of the actual parameter comes from a limited
1155 -- with-clause and the non-limited view is already available
1156 -- we replace the anonymous access type by a duplicate
1157 -- declaration whose designated type is the non-limited view
1159 if Ekind (Actual_DDT) = E_Incomplete_Type
1160 and then Present (Non_Limited_View (Actual_DDT))
1161 then
1162 Anon := New_Copy (Actual_Typ);
1164 if Is_Itype (Anon) then
1165 Set_Scope (Anon, Current_Scope);
1166 end if;
1168 Set_Directly_Designated_Type (Anon,
1169 Non_Limited_View (Actual_DDT));
1170 Set_Etype (Actual_Dup, Anon);
1172 elsif Is_Class_Wide_Type (Actual_DDT)
1173 and then Ekind (Etype (Actual_DDT)) = E_Incomplete_Type
1174 and then Present (Non_Limited_View (Etype (Actual_DDT)))
1175 then
1176 Anon := New_Copy (Actual_Typ);
1178 if Is_Itype (Anon) then
1179 Set_Scope (Anon, Current_Scope);
1180 end if;
1182 Set_Directly_Designated_Type (Anon,
1183 New_Copy (Actual_DDT));
1184 Set_Class_Wide_Type (Directly_Designated_Type (Anon),
1185 New_Copy (Class_Wide_Type (Actual_DDT)));
1186 Set_Etype (Directly_Designated_Type (Anon),
1187 Non_Limited_View (Etype (Actual_DDT)));
1188 Set_Etype (
1189 Class_Wide_Type (Directly_Designated_Type (Anon)),
1190 Non_Limited_View (Etype (Actual_DDT)));
1191 Set_Etype (Actual_Dup, Anon);
1192 end if;
1193 end if;
1195 Conversion := Convert_To (Formal_Typ, Actual_Dup);
1196 Rewrite (Actual, Conversion);
1197 Analyze_And_Resolve (Actual, Formal_Typ);
1198 end if;
1199 end if;
1201 Next_Actual (Actual);
1202 Next_Formal (Formal);
1203 end loop;
1204 end Expand_Interface_Actuals;
1206 ----------------------------
1207 -- Expand_Interface_Thunk --
1208 ----------------------------
1210 procedure Expand_Interface_Thunk
1211 (Prim : Node_Id;
1212 Thunk_Id : out Entity_Id;
1213 Thunk_Code : out Node_Id)
1215 Loc : constant Source_Ptr := Sloc (Prim);
1216 Actuals : constant List_Id := New_List;
1217 Decl : constant List_Id := New_List;
1218 Formals : constant List_Id := New_List;
1220 Controlling_Typ : Entity_Id;
1221 Decl_1 : Node_Id;
1222 Decl_2 : Node_Id;
1223 Formal : Node_Id;
1224 New_Arg : Node_Id;
1225 Offset_To_Top : Node_Id;
1226 Target : Entity_Id;
1227 Target_Formal : Entity_Id;
1229 begin
1230 Thunk_Id := Empty;
1231 Thunk_Code := Empty;
1233 -- Traverse the list of alias to find the final target
1235 Target := Prim;
1236 while Present (Alias (Target)) loop
1237 Target := Alias (Target);
1238 end loop;
1240 -- In case of primitives that are functions without formals and
1241 -- a controlling result there is no need to build the thunk.
1243 if not Present (First_Formal (Target)) then
1244 pragma Assert (Ekind (Target) = E_Function
1245 and then Has_Controlling_Result (Target));
1246 return;
1247 end if;
1249 -- Duplicate the formals
1251 Formal := First_Formal (Target);
1252 while Present (Formal) loop
1253 Append_To (Formals,
1254 Make_Parameter_Specification (Loc,
1255 Defining_Identifier =>
1256 Make_Defining_Identifier (Sloc (Formal),
1257 Chars => Chars (Formal)),
1258 In_Present => In_Present (Parent (Formal)),
1259 Out_Present => Out_Present (Parent (Formal)),
1260 Parameter_Type =>
1261 New_Reference_To (Etype (Formal), Loc),
1262 Expression => New_Copy_Tree (Expression (Parent (Formal)))));
1264 Next_Formal (Formal);
1265 end loop;
1267 Controlling_Typ := Find_Dispatching_Type (Target);
1269 Target_Formal := First_Formal (Target);
1270 Formal := First (Formals);
1271 while Present (Formal) loop
1272 if Ekind (Target_Formal) = E_In_Parameter
1273 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
1274 and then Directly_Designated_Type (Etype (Target_Formal))
1275 = Controlling_Typ
1276 then
1277 -- Generate:
1279 -- type T is access all <<type of the target formal>>
1280 -- S : Storage_Offset := Storage_Offset!(Formal)
1281 -- - Offset_To_Top (address!(Formal))
1283 Decl_2 :=
1284 Make_Full_Type_Declaration (Loc,
1285 Defining_Identifier =>
1286 Make_Defining_Identifier (Loc,
1287 New_Internal_Name ('T')),
1288 Type_Definition =>
1289 Make_Access_To_Object_Definition (Loc,
1290 All_Present => True,
1291 Null_Exclusion_Present => False,
1292 Constant_Present => False,
1293 Subtype_Indication =>
1294 New_Reference_To
1295 (Directly_Designated_Type
1296 (Etype (Target_Formal)), Loc)));
1298 New_Arg :=
1299 Unchecked_Convert_To (RTE (RE_Address),
1300 New_Reference_To (Defining_Identifier (Formal), Loc));
1302 if not RTE_Available (RE_Offset_To_Top) then
1303 Offset_To_Top :=
1304 Build_Offset_To_Top (Loc, New_Arg);
1305 else
1306 Offset_To_Top :=
1307 Make_Function_Call (Loc,
1308 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1309 Parameter_Associations => New_List (New_Arg));
1310 end if;
1312 Decl_1 :=
1313 Make_Object_Declaration (Loc,
1314 Defining_Identifier =>
1315 Make_Defining_Identifier (Loc,
1316 New_Internal_Name ('S')),
1317 Constant_Present => True,
1318 Object_Definition =>
1319 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1320 Expression =>
1321 Make_Op_Subtract (Loc,
1322 Left_Opnd =>
1323 Unchecked_Convert_To
1324 (RTE (RE_Storage_Offset),
1325 New_Reference_To (Defining_Identifier (Formal), Loc)),
1326 Right_Opnd =>
1327 Offset_To_Top));
1329 Append_To (Decl, Decl_2);
1330 Append_To (Decl, Decl_1);
1332 -- Reference the new actual. Generate:
1333 -- T!(S)
1335 Append_To (Actuals,
1336 Unchecked_Convert_To
1337 (Defining_Identifier (Decl_2),
1338 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1340 elsif Etype (Target_Formal) = Controlling_Typ then
1341 -- Generate:
1343 -- S1 : Storage_Offset := Storage_Offset!(Formal'Address)
1344 -- - Offset_To_Top (Formal'Address)
1345 -- S2 : Addr_Ptr := Addr_Ptr!(S1)
1347 New_Arg :=
1348 Make_Attribute_Reference (Loc,
1349 Prefix =>
1350 New_Reference_To (Defining_Identifier (Formal), Loc),
1351 Attribute_Name =>
1352 Name_Address);
1354 if not RTE_Available (RE_Offset_To_Top) then
1355 Offset_To_Top :=
1356 Build_Offset_To_Top (Loc, New_Arg);
1357 else
1358 Offset_To_Top :=
1359 Make_Function_Call (Loc,
1360 Name => New_Reference_To (RTE (RE_Offset_To_Top), Loc),
1361 Parameter_Associations => New_List (New_Arg));
1362 end if;
1364 Decl_1 :=
1365 Make_Object_Declaration (Loc,
1366 Defining_Identifier =>
1367 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1368 Constant_Present => True,
1369 Object_Definition =>
1370 New_Reference_To (RTE (RE_Storage_Offset), Loc),
1371 Expression =>
1372 Make_Op_Subtract (Loc,
1373 Left_Opnd =>
1374 Unchecked_Convert_To
1375 (RTE (RE_Storage_Offset),
1376 Make_Attribute_Reference (Loc,
1377 Prefix =>
1378 New_Reference_To
1379 (Defining_Identifier (Formal), Loc),
1380 Attribute_Name => Name_Address)),
1381 Right_Opnd =>
1382 Offset_To_Top));
1384 Decl_2 :=
1385 Make_Object_Declaration (Loc,
1386 Defining_Identifier =>
1387 Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
1388 Constant_Present => True,
1389 Object_Definition => New_Reference_To (RTE (RE_Addr_Ptr), Loc),
1390 Expression =>
1391 Unchecked_Convert_To
1392 (RTE (RE_Addr_Ptr),
1393 New_Reference_To (Defining_Identifier (Decl_1), Loc)));
1395 Append_To (Decl, Decl_1);
1396 Append_To (Decl, Decl_2);
1398 -- Reference the new actual. Generate:
1399 -- Target_Formal (S2.all)
1401 Append_To (Actuals,
1402 Unchecked_Convert_To
1403 (Etype (Target_Formal),
1404 Make_Explicit_Dereference (Loc,
1405 New_Reference_To (Defining_Identifier (Decl_2), Loc))));
1407 -- No special management required for this actual
1409 else
1410 Append_To (Actuals,
1411 New_Reference_To (Defining_Identifier (Formal), Loc));
1412 end if;
1414 Next_Formal (Target_Formal);
1415 Next (Formal);
1416 end loop;
1418 Thunk_Id :=
1419 Make_Defining_Identifier (Loc,
1420 Chars => New_Internal_Name ('T'));
1422 Set_Is_Thunk (Thunk_Id);
1424 if Ekind (Target) = E_Procedure then
1425 Thunk_Code :=
1426 Make_Subprogram_Body (Loc,
1427 Specification =>
1428 Make_Procedure_Specification (Loc,
1429 Defining_Unit_Name => Thunk_Id,
1430 Parameter_Specifications => Formals),
1431 Declarations => Decl,
1432 Handled_Statement_Sequence =>
1433 Make_Handled_Sequence_Of_Statements (Loc,
1434 Statements => New_List (
1435 Make_Procedure_Call_Statement (Loc,
1436 Name => New_Occurrence_Of (Target, Loc),
1437 Parameter_Associations => Actuals))));
1439 else pragma Assert (Ekind (Target) = E_Function);
1441 Thunk_Code :=
1442 Make_Subprogram_Body (Loc,
1443 Specification =>
1444 Make_Function_Specification (Loc,
1445 Defining_Unit_Name => Thunk_Id,
1446 Parameter_Specifications => Formals,
1447 Result_Definition =>
1448 New_Copy (Result_Definition (Parent (Target)))),
1449 Declarations => Decl,
1450 Handled_Statement_Sequence =>
1451 Make_Handled_Sequence_Of_Statements (Loc,
1452 Statements => New_List (
1453 Make_Simple_Return_Statement (Loc,
1454 Make_Function_Call (Loc,
1455 Name => New_Occurrence_Of (Target, Loc),
1456 Parameter_Associations => Actuals)))));
1457 end if;
1458 end Expand_Interface_Thunk;
1460 ------------
1461 -- Has_DT --
1462 ------------
1464 function Has_DT (Typ : Entity_Id) return Boolean is
1465 begin
1466 return not Is_Interface (Typ)
1467 and then not Restriction_Active (No_Dispatching_Calls);
1468 end Has_DT;
1470 -----------------------------------------
1471 -- Is_Predefined_Dispatching_Operation --
1472 -----------------------------------------
1474 function Is_Predefined_Dispatching_Operation
1475 (E : Entity_Id) return Boolean
1477 TSS_Name : TSS_Name_Type;
1479 begin
1480 if not Is_Dispatching_Operation (E) then
1481 return False;
1482 end if;
1484 Get_Name_String (Chars (E));
1486 -- Most predefined primitives have internally generated names. Equality
1487 -- must be treated differently; the predefined operation is recognized
1488 -- as a homogeneous binary operator that returns Boolean.
1490 if Name_Len > TSS_Name_Type'Last then
1491 TSS_Name := TSS_Name_Type (Name_Buffer (Name_Len - TSS_Name'Length + 1
1492 .. Name_Len));
1493 if Chars (E) = Name_uSize
1494 or else Chars (E) = Name_uAlignment
1495 or else TSS_Name = TSS_Stream_Read
1496 or else TSS_Name = TSS_Stream_Write
1497 or else TSS_Name = TSS_Stream_Input
1498 or else TSS_Name = TSS_Stream_Output
1499 or else
1500 (Chars (E) = Name_Op_Eq
1501 and then Etype (First_Entity (E)) = Etype (Last_Entity (E)))
1502 or else Chars (E) = Name_uAssign
1503 or else TSS_Name = TSS_Deep_Adjust
1504 or else TSS_Name = TSS_Deep_Finalize
1505 or else Is_Predefined_Interface_Primitive (E)
1506 then
1507 return True;
1508 end if;
1509 end if;
1511 return False;
1512 end Is_Predefined_Dispatching_Operation;
1514 -------------------------------------
1515 -- Is_Predefined_Dispatching_Alias --
1516 -------------------------------------
1518 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
1520 E : Entity_Id;
1522 begin
1523 if not Is_Predefined_Dispatching_Operation (Prim)
1524 and then Present (Alias (Prim))
1525 then
1526 E := Prim;
1527 while Present (Alias (E)) loop
1528 E := Alias (E);
1529 end loop;
1531 if Is_Predefined_Dispatching_Operation (E) then
1532 return True;
1533 end if;
1534 end if;
1536 return False;
1537 end Is_Predefined_Dispatching_Alias;
1539 ---------------------------------------
1540 -- Is_Predefined_Interface_Primitive --
1541 ---------------------------------------
1543 function Is_Predefined_Interface_Primitive (E : Entity_Id) return Boolean is
1544 begin
1545 return Ada_Version >= Ada_05
1546 and then (Chars (E) = Name_uDisp_Asynchronous_Select or else
1547 Chars (E) = Name_uDisp_Conditional_Select or else
1548 Chars (E) = Name_uDisp_Get_Prim_Op_Kind or else
1549 Chars (E) = Name_uDisp_Get_Task_Id or else
1550 Chars (E) = Name_uDisp_Requeue or else
1551 Chars (E) = Name_uDisp_Timed_Select);
1552 end Is_Predefined_Interface_Primitive;
1554 ----------------------------------------
1555 -- Make_Disp_Asynchronous_Select_Body --
1556 ----------------------------------------
1558 -- For interface types, generate:
1560 -- procedure _Disp_Asynchronous_Select
1561 -- (T : in out <Typ>;
1562 -- S : Integer;
1563 -- P : System.Address;
1564 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1565 -- F : out Boolean)
1566 -- is
1567 -- begin
1568 -- null;
1569 -- end _Disp_Asynchronous_Select;
1571 -- For protected types, generate:
1573 -- procedure _Disp_Asynchronous_Select
1574 -- (T : in out <Typ>;
1575 -- S : Integer;
1576 -- P : System.Address;
1577 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1578 -- F : out Boolean)
1579 -- is
1580 -- I : Integer :=
1581 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1582 -- Bnn : System.Tasking.Protected_Objects.Operations.
1583 -- Communication_Block;
1584 -- begin
1585 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
1586 -- (T._object'Access,
1587 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
1588 -- P,
1589 -- System.Tasking.Asynchronous_Call,
1590 -- Bnn);
1591 -- B := System.Storage_Elements.Dummy_Communication_Block (Bnn);
1592 -- end _Disp_Asynchronous_Select;
1594 -- For task types, generate:
1596 -- procedure _Disp_Asynchronous_Select
1597 -- (T : in out <Typ>;
1598 -- S : Integer;
1599 -- P : System.Address;
1600 -- B : out System.Storage_Elements.Dummy_Communication_Block;
1601 -- F : out Boolean)
1602 -- is
1603 -- I : Integer :=
1604 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1605 -- begin
1606 -- System.Tasking.Rendezvous.Task_Entry_Call
1607 -- (T._task_id,
1608 -- System.Tasking.Task_Entry_Index (I),
1609 -- P,
1610 -- System.Tasking.Asynchronous_Call,
1611 -- F);
1612 -- end _Disp_Asynchronous_Select;
1614 function Make_Disp_Asynchronous_Select_Body
1615 (Typ : Entity_Id) return Node_Id
1617 Com_Block : Entity_Id;
1618 Conc_Typ : Entity_Id := Empty;
1619 Decls : constant List_Id := New_List;
1620 DT_Ptr : Entity_Id;
1621 Loc : constant Source_Ptr := Sloc (Typ);
1622 Obj_Ref : Node_Id;
1623 Stmts : constant List_Id := New_List;
1625 begin
1626 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1628 -- Null body is generated for interface types
1630 if Is_Interface (Typ) then
1631 return
1632 Make_Subprogram_Body (Loc,
1633 Specification =>
1634 Make_Disp_Asynchronous_Select_Spec (Typ),
1635 Declarations =>
1636 New_List,
1637 Handled_Statement_Sequence =>
1638 Make_Handled_Sequence_Of_Statements (Loc,
1639 New_List (Make_Null_Statement (Loc))));
1640 end if;
1642 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1644 if Is_Concurrent_Record_Type (Typ) then
1645 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1647 -- Generate:
1648 -- I : Integer :=
1649 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
1651 -- where I will be used to capture the entry index of the primitive
1652 -- wrapper at position S.
1654 Append_To (Decls,
1655 Make_Object_Declaration (Loc,
1656 Defining_Identifier =>
1657 Make_Defining_Identifier (Loc, Name_uI),
1658 Object_Definition =>
1659 New_Reference_To (Standard_Integer, Loc),
1660 Expression =>
1661 Make_Function_Call (Loc,
1662 Name =>
1663 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
1664 Parameter_Associations =>
1665 New_List (
1666 Unchecked_Convert_To (RTE (RE_Tag),
1667 New_Reference_To (DT_Ptr, Loc)),
1668 Make_Identifier (Loc, Name_uS)))));
1670 if Ekind (Conc_Typ) = E_Protected_Type then
1672 -- Generate:
1673 -- Bnn : Communication_Block;
1675 Com_Block :=
1676 Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
1678 Append_To (Decls,
1679 Make_Object_Declaration (Loc,
1680 Defining_Identifier =>
1681 Com_Block,
1682 Object_Definition =>
1683 New_Reference_To (RTE (RE_Communication_Block), Loc)));
1685 -- Build T._object'Access for calls below
1687 Obj_Ref :=
1688 Make_Attribute_Reference (Loc,
1689 Attribute_Name => Name_Unchecked_Access,
1690 Prefix =>
1691 Make_Selected_Component (Loc,
1692 Prefix => Make_Identifier (Loc, Name_uT),
1693 Selector_Name => Make_Identifier (Loc, Name_uObject)));
1695 case Corresponding_Runtime_Package (Conc_Typ) is
1696 when System_Tasking_Protected_Objects_Entries =>
1698 -- Generate:
1699 -- Protected_Entry_Call
1700 -- (T._object'Access, -- Object
1701 -- Protected_Entry_Index! (I), -- E
1702 -- P, -- Uninterpreted_Data
1703 -- Asynchronous_Call, -- Mode
1704 -- Bnn); -- Communication_Block
1706 -- where T is the protected object, I is the entry index, P
1707 -- is the wrapped parameters and B is the name of the
1708 -- communication block.
1710 Append_To (Stmts,
1711 Make_Procedure_Call_Statement (Loc,
1712 Name =>
1713 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
1714 Parameter_Associations =>
1715 New_List (
1716 Obj_Ref,
1718 Make_Unchecked_Type_Conversion (Loc, -- entry index
1719 Subtype_Mark =>
1720 New_Reference_To
1721 (RTE (RE_Protected_Entry_Index), Loc),
1722 Expression => Make_Identifier (Loc, Name_uI)),
1724 Make_Identifier (Loc, Name_uP), -- parameter block
1725 New_Reference_To ( -- Asynchronous_Call
1726 RTE (RE_Asynchronous_Call), Loc),
1728 New_Reference_To (Com_Block, Loc)))); -- comm block
1730 when System_Tasking_Protected_Objects_Single_Entry =>
1732 -- Generate:
1733 -- procedure Protected_Single_Entry_Call
1734 -- (Object : Protection_Entry_Access;
1735 -- Uninterpreted_Data : System.Address;
1736 -- Mode : Call_Modes);
1738 Append_To (Stmts,
1739 Make_Procedure_Call_Statement (Loc,
1740 Name =>
1741 New_Reference_To
1742 (RTE (RE_Protected_Single_Entry_Call), Loc),
1743 Parameter_Associations =>
1744 New_List (
1745 Obj_Ref,
1747 Make_Attribute_Reference (Loc,
1748 Prefix => Make_Identifier (Loc, Name_uP),
1749 Attribute_Name => Name_Address),
1751 New_Reference_To
1752 (RTE (RE_Asynchronous_Call), Loc))));
1754 when others =>
1755 raise Program_Error;
1756 end case;
1758 -- Generate:
1759 -- B := Dummy_Communication_Block (Bnn);
1761 Append_To (Stmts,
1762 Make_Assignment_Statement (Loc,
1763 Name =>
1764 Make_Identifier (Loc, Name_uB),
1765 Expression =>
1766 Make_Unchecked_Type_Conversion (Loc,
1767 Subtype_Mark =>
1768 New_Reference_To (
1769 RTE (RE_Dummy_Communication_Block), Loc),
1770 Expression =>
1771 New_Reference_To (Com_Block, Loc))));
1773 else
1774 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
1776 -- Generate:
1777 -- Task_Entry_Call
1778 -- (T._task_id, -- Acceptor
1779 -- Task_Entry_Index! (I), -- E
1780 -- P, -- Uninterpreted_Data
1781 -- Asynchronous_Call, -- Mode
1782 -- F); -- Rendezvous_Successful
1784 -- where T is the task object, I is the entry index, P is the
1785 -- wrapped parameters and F is the status flag.
1787 Append_To (Stmts,
1788 Make_Procedure_Call_Statement (Loc,
1789 Name =>
1790 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
1791 Parameter_Associations =>
1792 New_List (
1793 Make_Selected_Component (Loc, -- T._task_id
1794 Prefix =>
1795 Make_Identifier (Loc, Name_uT),
1796 Selector_Name =>
1797 Make_Identifier (Loc, Name_uTask_Id)),
1799 Make_Unchecked_Type_Conversion (Loc, -- entry index
1800 Subtype_Mark =>
1801 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
1802 Expression =>
1803 Make_Identifier (Loc, Name_uI)),
1805 Make_Identifier (Loc, Name_uP), -- parameter block
1806 New_Reference_To ( -- Asynchronous_Call
1807 RTE (RE_Asynchronous_Call), Loc),
1808 Make_Identifier (Loc, Name_uF)))); -- status flag
1809 end if;
1810 end if;
1812 return
1813 Make_Subprogram_Body (Loc,
1814 Specification =>
1815 Make_Disp_Asynchronous_Select_Spec (Typ),
1816 Declarations =>
1817 Decls,
1818 Handled_Statement_Sequence =>
1819 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
1820 end Make_Disp_Asynchronous_Select_Body;
1822 ----------------------------------------
1823 -- Make_Disp_Asynchronous_Select_Spec --
1824 ----------------------------------------
1826 function Make_Disp_Asynchronous_Select_Spec
1827 (Typ : Entity_Id) return Node_Id
1829 Loc : constant Source_Ptr := Sloc (Typ);
1830 Def_Id : constant Node_Id :=
1831 Make_Defining_Identifier (Loc,
1832 Name_uDisp_Asynchronous_Select);
1833 Params : constant List_Id := New_List;
1835 begin
1836 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1838 -- T : in out Typ; -- Object parameter
1839 -- S : Integer; -- Primitive operation slot
1840 -- P : Address; -- Wrapped parameters
1841 -- B : out Dummy_Communication_Block; -- Communication block dummy
1842 -- F : out Boolean; -- Status flag
1844 Append_List_To (Params, New_List (
1846 Make_Parameter_Specification (Loc,
1847 Defining_Identifier =>
1848 Make_Defining_Identifier (Loc, Name_uT),
1849 Parameter_Type =>
1850 New_Reference_To (Typ, Loc),
1851 In_Present => True,
1852 Out_Present => True),
1854 Make_Parameter_Specification (Loc,
1855 Defining_Identifier =>
1856 Make_Defining_Identifier (Loc, Name_uS),
1857 Parameter_Type =>
1858 New_Reference_To (Standard_Integer, Loc)),
1860 Make_Parameter_Specification (Loc,
1861 Defining_Identifier =>
1862 Make_Defining_Identifier (Loc, Name_uP),
1863 Parameter_Type =>
1864 New_Reference_To (RTE (RE_Address), Loc)),
1866 Make_Parameter_Specification (Loc,
1867 Defining_Identifier =>
1868 Make_Defining_Identifier (Loc, Name_uB),
1869 Parameter_Type =>
1870 New_Reference_To (RTE (RE_Dummy_Communication_Block), Loc),
1871 Out_Present => True),
1873 Make_Parameter_Specification (Loc,
1874 Defining_Identifier =>
1875 Make_Defining_Identifier (Loc, Name_uF),
1876 Parameter_Type =>
1877 New_Reference_To (Standard_Boolean, Loc),
1878 Out_Present => True)));
1880 return
1881 Make_Procedure_Specification (Loc,
1882 Defining_Unit_Name => Def_Id,
1883 Parameter_Specifications => Params);
1884 end Make_Disp_Asynchronous_Select_Spec;
1886 ---------------------------------------
1887 -- Make_Disp_Conditional_Select_Body --
1888 ---------------------------------------
1890 -- For interface types, generate:
1892 -- procedure _Disp_Conditional_Select
1893 -- (T : in out <Typ>;
1894 -- S : Integer;
1895 -- P : System.Address;
1896 -- C : out Ada.Tags.Prim_Op_Kind;
1897 -- F : out Boolean)
1898 -- is
1899 -- begin
1900 -- null;
1901 -- end _Disp_Conditional_Select;
1903 -- For protected types, generate:
1905 -- procedure _Disp_Conditional_Select
1906 -- (T : in out <Typ>;
1907 -- S : Integer;
1908 -- P : System.Address;
1909 -- C : out Ada.Tags.Prim_Op_Kind;
1910 -- F : out Boolean)
1911 -- is
1912 -- I : Integer;
1913 -- Bnn : System.Tasking.Protected_Objects.Operations.
1914 -- Communication_Block;
1916 -- begin
1917 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP, S));
1919 -- if C = Ada.Tags.POK_Procedure
1920 -- or else C = Ada.Tags.POK_Protected_Procedure
1921 -- or else C = Ada.Tags.POK_Task_Procedure
1922 -- then
1923 -- F := True;
1924 -- return;
1925 -- end if;
1927 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1928 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
1929 -- (T.object'Access,
1930 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
1931 -- P,
1932 -- System.Tasking.Conditional_Call,
1933 -- Bnn);
1934 -- F := not Cancelled (Bnn);
1935 -- end _Disp_Conditional_Select;
1937 -- For task types, generate:
1939 -- procedure _Disp_Conditional_Select
1940 -- (T : in out <Typ>;
1941 -- S : Integer;
1942 -- P : System.Address;
1943 -- C : out Ada.Tags.Prim_Op_Kind;
1944 -- F : out Boolean)
1945 -- is
1946 -- I : Integer;
1948 -- begin
1949 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
1950 -- System.Tasking.Rendezvous.Task_Entry_Call
1951 -- (T._task_id,
1952 -- System.Tasking.Task_Entry_Index (I),
1953 -- P,
1954 -- System.Tasking.Conditional_Call,
1955 -- F);
1956 -- end _Disp_Conditional_Select;
1958 function Make_Disp_Conditional_Select_Body
1959 (Typ : Entity_Id) return Node_Id
1961 Loc : constant Source_Ptr := Sloc (Typ);
1962 Blk_Nam : Entity_Id;
1963 Conc_Typ : Entity_Id := Empty;
1964 Decls : constant List_Id := New_List;
1965 DT_Ptr : Entity_Id;
1966 Obj_Ref : Node_Id;
1967 Stmts : constant List_Id := New_List;
1969 begin
1970 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
1972 -- Null body is generated for interface types
1974 if Is_Interface (Typ) then
1975 return
1976 Make_Subprogram_Body (Loc,
1977 Specification =>
1978 Make_Disp_Conditional_Select_Spec (Typ),
1979 Declarations =>
1980 No_List,
1981 Handled_Statement_Sequence =>
1982 Make_Handled_Sequence_Of_Statements (Loc,
1983 New_List (Make_Null_Statement (Loc))));
1984 end if;
1986 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
1988 if Is_Concurrent_Record_Type (Typ) then
1989 Conc_Typ := Corresponding_Concurrent_Type (Typ);
1991 -- Generate:
1992 -- I : Integer;
1994 -- where I will be used to capture the entry index of the primitive
1995 -- wrapper at position S.
1997 Append_To (Decls,
1998 Make_Object_Declaration (Loc,
1999 Defining_Identifier =>
2000 Make_Defining_Identifier (Loc, Name_uI),
2001 Object_Definition =>
2002 New_Reference_To (Standard_Integer, Loc)));
2004 -- Generate:
2005 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag! (<type>VP), S);
2007 -- if C = POK_Procedure
2008 -- or else C = POK_Protected_Procedure
2009 -- or else C = POK_Task_Procedure;
2010 -- then
2011 -- F := True;
2012 -- return;
2013 -- end if;
2015 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
2017 -- Generate:
2018 -- Bnn : Communication_Block;
2020 -- where Bnn is the name of the communication block used in the
2021 -- call to Protected_Entry_Call.
2023 Blk_Nam := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
2025 Append_To (Decls,
2026 Make_Object_Declaration (Loc,
2027 Defining_Identifier =>
2028 Blk_Nam,
2029 Object_Definition =>
2030 New_Reference_To (RTE (RE_Communication_Block), Loc)));
2032 -- Generate:
2033 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
2035 -- I is the entry index and S is the dispatch table slot
2037 Append_To (Stmts,
2038 Make_Assignment_Statement (Loc,
2039 Name =>
2040 Make_Identifier (Loc, Name_uI),
2041 Expression =>
2042 Make_Function_Call (Loc,
2043 Name =>
2044 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
2045 Parameter_Associations =>
2046 New_List (
2047 Unchecked_Convert_To (RTE (RE_Tag),
2048 New_Reference_To (DT_Ptr, Loc)),
2049 Make_Identifier (Loc, Name_uS)))));
2051 if Ekind (Conc_Typ) = E_Protected_Type then
2053 Obj_Ref := -- T._object'Access
2054 Make_Attribute_Reference (Loc,
2055 Attribute_Name => Name_Unchecked_Access,
2056 Prefix =>
2057 Make_Selected_Component (Loc,
2058 Prefix => Make_Identifier (Loc, Name_uT),
2059 Selector_Name => Make_Identifier (Loc, Name_uObject)));
2061 case Corresponding_Runtime_Package (Conc_Typ) is
2062 when System_Tasking_Protected_Objects_Entries =>
2063 -- Generate:
2065 -- Protected_Entry_Call
2066 -- (T._object'Access, -- Object
2067 -- Protected_Entry_Index! (I), -- E
2068 -- P, -- Uninterpreted_Data
2069 -- Conditional_Call, -- Mode
2070 -- Bnn); -- Block
2072 -- where T is the protected object, I is the entry index, P
2073 -- are the wrapped parameters and Bnn is the name of the
2074 -- communication block.
2076 Append_To (Stmts,
2077 Make_Procedure_Call_Statement (Loc,
2078 Name =>
2079 New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
2080 Parameter_Associations =>
2081 New_List (
2082 Obj_Ref,
2084 Make_Unchecked_Type_Conversion (Loc, -- entry index
2085 Subtype_Mark =>
2086 New_Reference_To
2087 (RTE (RE_Protected_Entry_Index), Loc),
2088 Expression => Make_Identifier (Loc, Name_uI)),
2090 Make_Identifier (Loc, Name_uP), -- parameter block
2092 New_Reference_To ( -- Conditional_Call
2093 RTE (RE_Conditional_Call), Loc),
2094 New_Reference_To ( -- Bnn
2095 Blk_Nam, Loc))));
2097 when System_Tasking_Protected_Objects_Single_Entry =>
2099 -- If we are compiling for a restricted run-time, the call
2100 -- uses the simpler form.
2102 Append_To (Stmts,
2103 Make_Procedure_Call_Statement (Loc,
2104 Name =>
2105 New_Reference_To
2106 (RTE (RE_Protected_Single_Entry_Call), Loc),
2107 Parameter_Associations =>
2108 New_List (
2109 Obj_Ref,
2111 Make_Attribute_Reference (Loc,
2112 Prefix => Make_Identifier (Loc, Name_uP),
2113 Attribute_Name => Name_Address),
2115 New_Reference_To
2116 (RTE (RE_Conditional_Call), Loc))));
2117 when others =>
2118 raise Program_Error;
2119 end case;
2121 -- Generate:
2122 -- F := not Cancelled (Bnn);
2124 -- where F is the success flag. The status of Cancelled is negated
2125 -- in order to match the behaviour of the version for task types.
2127 Append_To (Stmts,
2128 Make_Assignment_Statement (Loc,
2129 Name =>
2130 Make_Identifier (Loc, Name_uF),
2131 Expression =>
2132 Make_Op_Not (Loc,
2133 Right_Opnd =>
2134 Make_Function_Call (Loc,
2135 Name =>
2136 New_Reference_To (RTE (RE_Cancelled), Loc),
2137 Parameter_Associations =>
2138 New_List (
2139 New_Reference_To (Blk_Nam, Loc))))));
2140 else
2141 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2143 -- Generate:
2144 -- Task_Entry_Call
2145 -- (T._task_id, -- Acceptor
2146 -- Task_Entry_Index! (I), -- E
2147 -- P, -- Uninterpreted_Data
2148 -- Conditional_Call, -- Mode
2149 -- F); -- Rendezvous_Successful
2151 -- where T is the task object, I is the entry index, P are the
2152 -- wrapped parameters and F is the status flag.
2154 Append_To (Stmts,
2155 Make_Procedure_Call_Statement (Loc,
2156 Name =>
2157 New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
2158 Parameter_Associations =>
2159 New_List (
2161 Make_Selected_Component (Loc, -- T._task_id
2162 Prefix =>
2163 Make_Identifier (Loc, Name_uT),
2164 Selector_Name =>
2165 Make_Identifier (Loc, Name_uTask_Id)),
2167 Make_Unchecked_Type_Conversion (Loc, -- entry index
2168 Subtype_Mark =>
2169 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2170 Expression =>
2171 Make_Identifier (Loc, Name_uI)),
2173 Make_Identifier (Loc, Name_uP), -- parameter block
2174 New_Reference_To ( -- Conditional_Call
2175 RTE (RE_Conditional_Call), Loc),
2176 Make_Identifier (Loc, Name_uF)))); -- status flag
2177 end if;
2178 end if;
2180 return
2181 Make_Subprogram_Body (Loc,
2182 Specification =>
2183 Make_Disp_Conditional_Select_Spec (Typ),
2184 Declarations =>
2185 Decls,
2186 Handled_Statement_Sequence =>
2187 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2188 end Make_Disp_Conditional_Select_Body;
2190 ---------------------------------------
2191 -- Make_Disp_Conditional_Select_Spec --
2192 ---------------------------------------
2194 function Make_Disp_Conditional_Select_Spec
2195 (Typ : Entity_Id) return Node_Id
2197 Loc : constant Source_Ptr := Sloc (Typ);
2198 Def_Id : constant Node_Id :=
2199 Make_Defining_Identifier (Loc,
2200 Name_uDisp_Conditional_Select);
2201 Params : constant List_Id := New_List;
2203 begin
2204 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2206 -- T : in out Typ; -- Object parameter
2207 -- S : Integer; -- Primitive operation slot
2208 -- P : Address; -- Wrapped parameters
2209 -- C : out Prim_Op_Kind; -- Call kind
2210 -- F : out Boolean; -- Status flag
2212 Append_List_To (Params, New_List (
2214 Make_Parameter_Specification (Loc,
2215 Defining_Identifier =>
2216 Make_Defining_Identifier (Loc, Name_uT),
2217 Parameter_Type =>
2218 New_Reference_To (Typ, Loc),
2219 In_Present => True,
2220 Out_Present => True),
2222 Make_Parameter_Specification (Loc,
2223 Defining_Identifier =>
2224 Make_Defining_Identifier (Loc, Name_uS),
2225 Parameter_Type =>
2226 New_Reference_To (Standard_Integer, Loc)),
2228 Make_Parameter_Specification (Loc,
2229 Defining_Identifier =>
2230 Make_Defining_Identifier (Loc, Name_uP),
2231 Parameter_Type =>
2232 New_Reference_To (RTE (RE_Address), Loc)),
2234 Make_Parameter_Specification (Loc,
2235 Defining_Identifier =>
2236 Make_Defining_Identifier (Loc, Name_uC),
2237 Parameter_Type =>
2238 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2239 Out_Present => True),
2241 Make_Parameter_Specification (Loc,
2242 Defining_Identifier =>
2243 Make_Defining_Identifier (Loc, Name_uF),
2244 Parameter_Type =>
2245 New_Reference_To (Standard_Boolean, Loc),
2246 Out_Present => True)));
2248 return
2249 Make_Procedure_Specification (Loc,
2250 Defining_Unit_Name => Def_Id,
2251 Parameter_Specifications => Params);
2252 end Make_Disp_Conditional_Select_Spec;
2254 -------------------------------------
2255 -- Make_Disp_Get_Prim_Op_Kind_Body --
2256 -------------------------------------
2258 function Make_Disp_Get_Prim_Op_Kind_Body
2259 (Typ : Entity_Id) return Node_Id
2261 Loc : constant Source_Ptr := Sloc (Typ);
2262 DT_Ptr : Entity_Id;
2264 begin
2265 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2267 if Is_Interface (Typ) then
2268 return
2269 Make_Subprogram_Body (Loc,
2270 Specification =>
2271 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2272 Declarations =>
2273 New_List,
2274 Handled_Statement_Sequence =>
2275 Make_Handled_Sequence_Of_Statements (Loc,
2276 New_List (Make_Null_Statement (Loc))));
2277 end if;
2279 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2281 -- Generate:
2282 -- C := get_prim_op_kind (tag! (<type>VP), S);
2284 -- where C is the out parameter capturing the call kind and S is the
2285 -- dispatch table slot number.
2287 return
2288 Make_Subprogram_Body (Loc,
2289 Specification =>
2290 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
2291 Declarations =>
2292 New_List,
2293 Handled_Statement_Sequence =>
2294 Make_Handled_Sequence_Of_Statements (Loc,
2295 New_List (
2296 Make_Assignment_Statement (Loc,
2297 Name =>
2298 Make_Identifier (Loc, Name_uC),
2299 Expression =>
2300 Make_Function_Call (Loc,
2301 Name =>
2302 New_Reference_To (RTE (RE_Get_Prim_Op_Kind), Loc),
2303 Parameter_Associations => New_List (
2304 Unchecked_Convert_To (RTE (RE_Tag),
2305 New_Reference_To (DT_Ptr, Loc)),
2306 Make_Identifier (Loc, Name_uS)))))));
2307 end Make_Disp_Get_Prim_Op_Kind_Body;
2309 -------------------------------------
2310 -- Make_Disp_Get_Prim_Op_Kind_Spec --
2311 -------------------------------------
2313 function Make_Disp_Get_Prim_Op_Kind_Spec
2314 (Typ : Entity_Id) return Node_Id
2316 Loc : constant Source_Ptr := Sloc (Typ);
2317 Def_Id : constant Node_Id :=
2318 Make_Defining_Identifier (Loc,
2319 Name_uDisp_Get_Prim_Op_Kind);
2320 Params : constant List_Id := New_List;
2322 begin
2323 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2325 -- T : in out Typ; -- Object parameter
2326 -- S : Integer; -- Primitive operation slot
2327 -- C : out Prim_Op_Kind; -- Call kind
2329 Append_List_To (Params, New_List (
2331 Make_Parameter_Specification (Loc,
2332 Defining_Identifier =>
2333 Make_Defining_Identifier (Loc, Name_uT),
2334 Parameter_Type =>
2335 New_Reference_To (Typ, Loc),
2336 In_Present => True,
2337 Out_Present => True),
2339 Make_Parameter_Specification (Loc,
2340 Defining_Identifier =>
2341 Make_Defining_Identifier (Loc, Name_uS),
2342 Parameter_Type =>
2343 New_Reference_To (Standard_Integer, Loc)),
2345 Make_Parameter_Specification (Loc,
2346 Defining_Identifier =>
2347 Make_Defining_Identifier (Loc, Name_uC),
2348 Parameter_Type =>
2349 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
2350 Out_Present => True)));
2352 return
2353 Make_Procedure_Specification (Loc,
2354 Defining_Unit_Name => Def_Id,
2355 Parameter_Specifications => Params);
2356 end Make_Disp_Get_Prim_Op_Kind_Spec;
2358 --------------------------------
2359 -- Make_Disp_Get_Task_Id_Body --
2360 --------------------------------
2362 function Make_Disp_Get_Task_Id_Body
2363 (Typ : Entity_Id) return Node_Id
2365 Loc : constant Source_Ptr := Sloc (Typ);
2366 Ret : Node_Id;
2368 begin
2369 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2371 if Is_Concurrent_Record_Type (Typ)
2372 and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
2373 then
2374 -- Generate:
2375 -- return To_Address (_T._task_id);
2377 Ret :=
2378 Make_Simple_Return_Statement (Loc,
2379 Expression =>
2380 Make_Unchecked_Type_Conversion (Loc,
2381 Subtype_Mark =>
2382 New_Reference_To (RTE (RE_Address), Loc),
2383 Expression =>
2384 Make_Selected_Component (Loc,
2385 Prefix =>
2386 Make_Identifier (Loc, Name_uT),
2387 Selector_Name =>
2388 Make_Identifier (Loc, Name_uTask_Id))));
2390 -- A null body is constructed for non-task types
2392 else
2393 -- Generate:
2394 -- return Null_Address;
2396 Ret :=
2397 Make_Simple_Return_Statement (Loc,
2398 Expression =>
2399 New_Reference_To (RTE (RE_Null_Address), Loc));
2400 end if;
2402 return
2403 Make_Subprogram_Body (Loc,
2404 Specification =>
2405 Make_Disp_Get_Task_Id_Spec (Typ),
2406 Declarations =>
2407 New_List,
2408 Handled_Statement_Sequence =>
2409 Make_Handled_Sequence_Of_Statements (Loc,
2410 New_List (Ret)));
2411 end Make_Disp_Get_Task_Id_Body;
2413 --------------------------------
2414 -- Make_Disp_Get_Task_Id_Spec --
2415 --------------------------------
2417 function Make_Disp_Get_Task_Id_Spec
2418 (Typ : Entity_Id) return Node_Id
2420 Loc : constant Source_Ptr := Sloc (Typ);
2422 begin
2423 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2425 return
2426 Make_Function_Specification (Loc,
2427 Defining_Unit_Name =>
2428 Make_Defining_Identifier (Loc, Name_uDisp_Get_Task_Id),
2429 Parameter_Specifications => New_List (
2430 Make_Parameter_Specification (Loc,
2431 Defining_Identifier =>
2432 Make_Defining_Identifier (Loc, Name_uT),
2433 Parameter_Type =>
2434 New_Reference_To (Typ, Loc))),
2435 Result_Definition =>
2436 New_Reference_To (RTE (RE_Address), Loc));
2437 end Make_Disp_Get_Task_Id_Spec;
2439 ----------------------------
2440 -- Make_Disp_Requeue_Body --
2441 ----------------------------
2443 function Make_Disp_Requeue_Body
2444 (Typ : Entity_Id) return Node_Id
2446 Loc : constant Source_Ptr := Sloc (Typ);
2447 Conc_Typ : Entity_Id := Empty;
2448 Stmts : constant List_Id := New_List;
2450 begin
2451 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2453 -- Null body is generated for interface types and non-concurrent
2454 -- tagged types.
2456 if Is_Interface (Typ)
2457 or else not Is_Concurrent_Record_Type (Typ)
2458 then
2459 return
2460 Make_Subprogram_Body (Loc,
2461 Specification =>
2462 Make_Disp_Requeue_Spec (Typ),
2463 Declarations =>
2464 No_List,
2465 Handled_Statement_Sequence =>
2466 Make_Handled_Sequence_Of_Statements (Loc,
2467 New_List (Make_Null_Statement (Loc))));
2468 end if;
2470 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2472 if Ekind (Conc_Typ) = E_Protected_Type then
2474 -- Generate statements:
2475 -- if F then
2476 -- System.Tasking.Protected_Objects.Operations.
2477 -- Requeue_Protected_Entry
2478 -- (Protection_Entries_Access (P),
2479 -- O._object'Unchecked_Access,
2480 -- Protected_Entry_Index (I),
2481 -- A);
2482 -- else
2483 -- System.Tasking.Protected_Objects.Operations.
2484 -- Requeue_Task_To_Protected_Entry
2485 -- (O._object'Unchecked_Access,
2486 -- Protected_Entry_Index (I),
2487 -- A);
2488 -- end if;
2490 if Restriction_Active (No_Entry_Queue) then
2491 Append_To (Stmts, Make_Null_Statement (Loc));
2492 else
2493 Append_To (Stmts,
2494 Make_If_Statement (Loc,
2495 Condition =>
2496 Make_Identifier (Loc, Name_uF),
2498 Then_Statements =>
2499 New_List (
2501 -- Call to Requeue_Protected_Entry
2503 Make_Procedure_Call_Statement (Loc,
2504 Name =>
2505 New_Reference_To (
2506 RTE (RE_Requeue_Protected_Entry), Loc),
2507 Parameter_Associations =>
2508 New_List (
2510 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
2511 Subtype_Mark =>
2512 New_Reference_To (
2513 RTE (RE_Protection_Entries_Access), Loc),
2514 Expression =>
2515 Make_Identifier (Loc, Name_uP)),
2517 Make_Attribute_Reference (Loc, -- O._object'Acc
2518 Attribute_Name =>
2519 Name_Unchecked_Access,
2520 Prefix =>
2521 Make_Selected_Component (Loc,
2522 Prefix =>
2523 Make_Identifier (Loc, Name_uO),
2524 Selector_Name =>
2525 Make_Identifier (Loc, Name_uObject))),
2527 Make_Unchecked_Type_Conversion (Loc, -- entry index
2528 Subtype_Mark =>
2529 New_Reference_To (
2530 RTE (RE_Protected_Entry_Index), Loc),
2531 Expression =>
2532 Make_Identifier (Loc, Name_uI)),
2534 Make_Identifier (Loc, Name_uA)))), -- abort status
2536 Else_Statements =>
2537 New_List (
2539 -- Call to Requeue_Task_To_Protected_Entry
2541 Make_Procedure_Call_Statement (Loc,
2542 Name =>
2543 New_Reference_To (
2544 RTE (RE_Requeue_Task_To_Protected_Entry), Loc),
2545 Parameter_Associations =>
2546 New_List (
2548 Make_Attribute_Reference (Loc, -- O._object'Acc
2549 Attribute_Name =>
2550 Name_Unchecked_Access,
2551 Prefix =>
2552 Make_Selected_Component (Loc,
2553 Prefix =>
2554 Make_Identifier (Loc, Name_uO),
2555 Selector_Name =>
2556 Make_Identifier (Loc, Name_uObject))),
2558 Make_Unchecked_Type_Conversion (Loc, -- entry index
2559 Subtype_Mark =>
2560 New_Reference_To (
2561 RTE (RE_Protected_Entry_Index), Loc),
2562 Expression =>
2563 Make_Identifier (Loc, Name_uI)),
2565 Make_Identifier (Loc, Name_uA)))))); -- abort status
2566 end if;
2567 else
2568 pragma Assert (Is_Task_Type (Conc_Typ));
2570 -- Generate:
2571 -- if F then
2572 -- System.Tasking.Rendezvous.Requeue_Protected_To_Task_Entry
2573 -- (Protection_Entries_Access (P),
2574 -- O._task_id,
2575 -- Task_Entry_Index (I),
2576 -- A);
2577 -- else
2578 -- System.Tasking.Rendezvous.Requeue_Task_Entry
2579 -- (O._task_id,
2580 -- Task_Entry_Index (I),
2581 -- A);
2582 -- end if;
2584 Append_To (Stmts,
2585 Make_If_Statement (Loc,
2586 Condition =>
2587 Make_Identifier (Loc, Name_uF),
2589 Then_Statements =>
2590 New_List (
2592 -- Call to Requeue_Protected_To_Task_Entry
2594 Make_Procedure_Call_Statement (Loc,
2595 Name =>
2596 New_Reference_To (
2597 RTE (RE_Requeue_Protected_To_Task_Entry), Loc),
2599 Parameter_Associations =>
2600 New_List (
2602 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
2603 Subtype_Mark =>
2604 New_Reference_To (
2605 RTE (RE_Protection_Entries_Access), Loc),
2606 Expression =>
2607 Make_Identifier (Loc, Name_uP)),
2609 Make_Selected_Component (Loc, -- O._task_id
2610 Prefix =>
2611 Make_Identifier (Loc, Name_uO),
2612 Selector_Name =>
2613 Make_Identifier (Loc, Name_uTask_Id)),
2615 Make_Unchecked_Type_Conversion (Loc, -- entry index
2616 Subtype_Mark =>
2617 New_Reference_To (
2618 RTE (RE_Task_Entry_Index), Loc),
2619 Expression =>
2620 Make_Identifier (Loc, Name_uI)),
2622 Make_Identifier (Loc, Name_uA)))), -- abort status
2624 Else_Statements =>
2625 New_List (
2627 -- Call to Requeue_Task_Entry
2629 Make_Procedure_Call_Statement (Loc,
2630 Name =>
2631 New_Reference_To (RTE (RE_Requeue_Task_Entry), Loc),
2633 Parameter_Associations =>
2634 New_List (
2636 Make_Selected_Component (Loc, -- O._task_id
2637 Prefix =>
2638 Make_Identifier (Loc, Name_uO),
2639 Selector_Name =>
2640 Make_Identifier (Loc, Name_uTask_Id)),
2642 Make_Unchecked_Type_Conversion (Loc, -- entry index
2643 Subtype_Mark =>
2644 New_Reference_To (
2645 RTE (RE_Task_Entry_Index), Loc),
2646 Expression =>
2647 Make_Identifier (Loc, Name_uI)),
2649 Make_Identifier (Loc, Name_uA)))))); -- abort status
2650 end if;
2652 -- Even though no declarations are needed in both cases, we allocate
2653 -- a list for entities added by Freeze.
2655 return
2656 Make_Subprogram_Body (Loc,
2657 Specification =>
2658 Make_Disp_Requeue_Spec (Typ),
2659 Declarations =>
2660 New_List,
2661 Handled_Statement_Sequence =>
2662 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2663 end Make_Disp_Requeue_Body;
2665 ----------------------------
2666 -- Make_Disp_Requeue_Spec --
2667 ----------------------------
2669 function Make_Disp_Requeue_Spec
2670 (Typ : Entity_Id) return Node_Id
2672 Loc : constant Source_Ptr := Sloc (Typ);
2674 begin
2675 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2677 -- O : in out Typ; - Object parameter
2678 -- F : Boolean; - Protected (True) / task (False) flag
2679 -- P : Address; - Protection_Entries_Access value
2680 -- I : Entry_Index - Index of entry call
2681 -- A : Boolean - Abort flag
2683 -- Note that the Protection_Entries_Access value is represented as a
2684 -- System.Address in order to avoid dragging in the tasking runtime
2685 -- when compiling sources without tasking constructs.
2687 return
2688 Make_Procedure_Specification (Loc,
2689 Defining_Unit_Name =>
2690 Make_Defining_Identifier (Loc, Name_uDisp_Requeue),
2692 Parameter_Specifications =>
2693 New_List (
2695 Make_Parameter_Specification (Loc, -- O
2696 Defining_Identifier =>
2697 Make_Defining_Identifier (Loc, Name_uO),
2698 Parameter_Type =>
2699 New_Reference_To (Typ, Loc),
2700 In_Present => True,
2701 Out_Present => True),
2703 Make_Parameter_Specification (Loc, -- F
2704 Defining_Identifier =>
2705 Make_Defining_Identifier (Loc, Name_uF),
2706 Parameter_Type =>
2707 New_Reference_To (Standard_Boolean, Loc)),
2709 Make_Parameter_Specification (Loc, -- P
2710 Defining_Identifier =>
2711 Make_Defining_Identifier (Loc, Name_uP),
2712 Parameter_Type =>
2713 New_Reference_To (RTE (RE_Address), Loc)),
2715 Make_Parameter_Specification (Loc, -- I
2716 Defining_Identifier =>
2717 Make_Defining_Identifier (Loc, Name_uI),
2718 Parameter_Type =>
2719 New_Reference_To (Standard_Integer, Loc)),
2721 Make_Parameter_Specification (Loc, -- A
2722 Defining_Identifier =>
2723 Make_Defining_Identifier (Loc, Name_uA),
2724 Parameter_Type =>
2725 New_Reference_To (Standard_Boolean, Loc))));
2726 end Make_Disp_Requeue_Spec;
2728 ---------------------------------
2729 -- Make_Disp_Timed_Select_Body --
2730 ---------------------------------
2732 -- For interface types, generate:
2734 -- procedure _Disp_Timed_Select
2735 -- (T : in out <Typ>;
2736 -- S : Integer;
2737 -- P : System.Address;
2738 -- D : Duration;
2739 -- M : Integer;
2740 -- C : out Ada.Tags.Prim_Op_Kind;
2741 -- F : out Boolean)
2742 -- is
2743 -- begin
2744 -- null;
2745 -- end _Disp_Timed_Select;
2747 -- For protected types, generate:
2749 -- procedure _Disp_Timed_Select
2750 -- (T : in out <Typ>;
2751 -- S : Integer;
2752 -- P : System.Address;
2753 -- D : Duration;
2754 -- M : Integer;
2755 -- C : out Ada.Tags.Prim_Op_Kind;
2756 -- F : out Boolean)
2757 -- is
2758 -- I : Integer;
2760 -- begin
2761 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP), S);
2763 -- if C = Ada.Tags.POK_Procedure
2764 -- or else C = Ada.Tags.POK_Protected_Procedure
2765 -- or else C = Ada.Tags.POK_Task_Procedure
2766 -- then
2767 -- F := True;
2768 -- return;
2769 -- end if;
2771 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
2772 -- System.Tasking.Protected_Objects.Operations.
2773 -- Timed_Protected_Entry_Call
2774 -- (T._object'Access,
2775 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
2776 -- P,
2777 -- D,
2778 -- M,
2779 -- F);
2780 -- end _Disp_Timed_Select;
2782 -- For task types, generate:
2784 -- procedure _Disp_Timed_Select
2785 -- (T : in out <Typ>;
2786 -- S : Integer;
2787 -- P : System.Address;
2788 -- D : Duration;
2789 -- M : Integer;
2790 -- C : out Ada.Tags.Prim_Op_Kind;
2791 -- F : out Boolean)
2792 -- is
2793 -- I : Integer;
2795 -- begin
2796 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
2797 -- System.Tasking.Rendezvous.Timed_Task_Entry_Call
2798 -- (T._task_id,
2799 -- System.Tasking.Task_Entry_Index (I),
2800 -- P,
2801 -- D,
2802 -- M,
2803 -- D);
2804 -- end _Disp_Time_Select;
2806 function Make_Disp_Timed_Select_Body
2807 (Typ : Entity_Id) return Node_Id
2809 Loc : constant Source_Ptr := Sloc (Typ);
2810 Conc_Typ : Entity_Id := Empty;
2811 Decls : constant List_Id := New_List;
2812 DT_Ptr : Entity_Id;
2813 Obj_Ref : Node_Id;
2814 Stmts : constant List_Id := New_List;
2816 begin
2817 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2819 -- Null body is generated for interface types
2821 if Is_Interface (Typ) then
2822 return
2823 Make_Subprogram_Body (Loc,
2824 Specification =>
2825 Make_Disp_Timed_Select_Spec (Typ),
2826 Declarations =>
2827 New_List,
2828 Handled_Statement_Sequence =>
2829 Make_Handled_Sequence_Of_Statements (Loc,
2830 New_List (Make_Null_Statement (Loc))));
2831 end if;
2833 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
2835 if Is_Concurrent_Record_Type (Typ) then
2836 Conc_Typ := Corresponding_Concurrent_Type (Typ);
2838 -- Generate:
2839 -- I : Integer;
2841 -- where I will be used to capture the entry index of the primitive
2842 -- wrapper at position S.
2844 Append_To (Decls,
2845 Make_Object_Declaration (Loc,
2846 Defining_Identifier =>
2847 Make_Defining_Identifier (Loc, Name_uI),
2848 Object_Definition =>
2849 New_Reference_To (Standard_Integer, Loc)));
2851 -- Generate:
2852 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
2854 -- if C = POK_Procedure
2855 -- or else C = POK_Protected_Procedure
2856 -- or else C = POK_Task_Procedure;
2857 -- then
2858 -- F := True;
2859 -- return;
2860 -- end if;
2862 Build_Common_Dispatching_Select_Statements (Loc, DT_Ptr, Stmts);
2864 -- Generate:
2865 -- I := Get_Entry_Index (tag! (<type>VP), S);
2867 -- I is the entry index and S is the dispatch table slot
2869 Append_To (Stmts,
2870 Make_Assignment_Statement (Loc,
2871 Name =>
2872 Make_Identifier (Loc, Name_uI),
2873 Expression =>
2874 Make_Function_Call (Loc,
2875 Name =>
2876 New_Reference_To (RTE (RE_Get_Entry_Index), Loc),
2877 Parameter_Associations =>
2878 New_List (
2879 Unchecked_Convert_To (RTE (RE_Tag),
2880 New_Reference_To (DT_Ptr, Loc)),
2881 Make_Identifier (Loc, Name_uS)))));
2883 -- Protected case
2885 if Ekind (Conc_Typ) = E_Protected_Type then
2887 -- Build T._object'Access
2889 Obj_Ref :=
2890 Make_Attribute_Reference (Loc,
2891 Attribute_Name => Name_Unchecked_Access,
2892 Prefix =>
2893 Make_Selected_Component (Loc,
2894 Prefix => Make_Identifier (Loc, Name_uT),
2895 Selector_Name => Make_Identifier (Loc, Name_uObject)));
2897 -- Normal case, No_Entry_Queue restriction not active. In this
2898 -- case we generate:
2900 -- Timed_Protected_Entry_Call
2901 -- (T._object'access,
2902 -- Protected_Entry_Index! (I),
2903 -- P, D, M, F);
2905 -- where T is the protected object, I is the entry index, P are
2906 -- the wrapped parameters, D is the delay amount, M is the delay
2907 -- mode and F is the status flag.
2909 case Corresponding_Runtime_Package (Conc_Typ) is
2910 when System_Tasking_Protected_Objects_Entries =>
2911 Append_To (Stmts,
2912 Make_Procedure_Call_Statement (Loc,
2913 Name =>
2914 New_Reference_To
2915 (RTE (RE_Timed_Protected_Entry_Call), Loc),
2916 Parameter_Associations =>
2917 New_List (
2918 Obj_Ref,
2920 Make_Unchecked_Type_Conversion (Loc, -- entry index
2921 Subtype_Mark =>
2922 New_Reference_To
2923 (RTE (RE_Protected_Entry_Index), Loc),
2924 Expression =>
2925 Make_Identifier (Loc, Name_uI)),
2927 Make_Identifier (Loc, Name_uP), -- parameter block
2928 Make_Identifier (Loc, Name_uD), -- delay
2929 Make_Identifier (Loc, Name_uM), -- delay mode
2930 Make_Identifier (Loc, Name_uF)))); -- status flag
2932 when System_Tasking_Protected_Objects_Single_Entry =>
2933 -- Generate:
2935 -- Timed_Protected_Single_Entry_Call
2936 -- (T._object'access, P, D, M, F);
2938 -- where T is the protected object, P is the wrapped
2939 -- parameters, D is the delay amount, M is the delay mode, F
2940 -- is the status flag.
2942 Append_To (Stmts,
2943 Make_Procedure_Call_Statement (Loc,
2944 Name =>
2945 New_Reference_To
2946 (RTE (RE_Timed_Protected_Single_Entry_Call), Loc),
2947 Parameter_Associations =>
2948 New_List (
2949 Obj_Ref,
2950 Make_Identifier (Loc, Name_uP), -- parameter block
2951 Make_Identifier (Loc, Name_uD), -- delay
2952 Make_Identifier (Loc, Name_uM), -- delay mode
2953 Make_Identifier (Loc, Name_uF)))); -- status flag
2955 when others =>
2956 raise Program_Error;
2957 end case;
2959 -- Task case
2961 else
2962 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
2964 -- Generate:
2965 -- Timed_Task_Entry_Call (
2966 -- T._task_id,
2967 -- Task_Entry_Index! (I),
2968 -- P,
2969 -- D,
2970 -- M,
2971 -- F);
2973 -- where T is the task object, I is the entry index, P are the
2974 -- wrapped parameters, D is the delay amount, M is the delay
2975 -- mode and F is the status flag.
2977 Append_To (Stmts,
2978 Make_Procedure_Call_Statement (Loc,
2979 Name =>
2980 New_Reference_To (RTE (RE_Timed_Task_Entry_Call), Loc),
2981 Parameter_Associations =>
2982 New_List (
2984 Make_Selected_Component (Loc, -- T._task_id
2985 Prefix =>
2986 Make_Identifier (Loc, Name_uT),
2987 Selector_Name =>
2988 Make_Identifier (Loc, Name_uTask_Id)),
2990 Make_Unchecked_Type_Conversion (Loc, -- entry index
2991 Subtype_Mark =>
2992 New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
2993 Expression =>
2994 Make_Identifier (Loc, Name_uI)),
2996 Make_Identifier (Loc, Name_uP), -- parameter block
2997 Make_Identifier (Loc, Name_uD), -- delay
2998 Make_Identifier (Loc, Name_uM), -- delay mode
2999 Make_Identifier (Loc, Name_uF)))); -- status flag
3000 end if;
3001 end if;
3003 return
3004 Make_Subprogram_Body (Loc,
3005 Specification =>
3006 Make_Disp_Timed_Select_Spec (Typ),
3007 Declarations =>
3008 Decls,
3009 Handled_Statement_Sequence =>
3010 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
3011 end Make_Disp_Timed_Select_Body;
3013 ---------------------------------
3014 -- Make_Disp_Timed_Select_Spec --
3015 ---------------------------------
3017 function Make_Disp_Timed_Select_Spec
3018 (Typ : Entity_Id) return Node_Id
3020 Loc : constant Source_Ptr := Sloc (Typ);
3021 Def_Id : constant Node_Id :=
3022 Make_Defining_Identifier (Loc,
3023 Name_uDisp_Timed_Select);
3024 Params : constant List_Id := New_List;
3026 begin
3027 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3029 -- T : in out Typ; -- Object parameter
3030 -- S : Integer; -- Primitive operation slot
3031 -- P : Address; -- Wrapped parameters
3032 -- D : Duration; -- Delay
3033 -- M : Integer; -- Delay Mode
3034 -- C : out Prim_Op_Kind; -- Call kind
3035 -- F : out Boolean; -- Status flag
3037 Append_List_To (Params, New_List (
3039 Make_Parameter_Specification (Loc,
3040 Defining_Identifier =>
3041 Make_Defining_Identifier (Loc, Name_uT),
3042 Parameter_Type =>
3043 New_Reference_To (Typ, Loc),
3044 In_Present => True,
3045 Out_Present => True),
3047 Make_Parameter_Specification (Loc,
3048 Defining_Identifier =>
3049 Make_Defining_Identifier (Loc, Name_uS),
3050 Parameter_Type =>
3051 New_Reference_To (Standard_Integer, Loc)),
3053 Make_Parameter_Specification (Loc,
3054 Defining_Identifier =>
3055 Make_Defining_Identifier (Loc, Name_uP),
3056 Parameter_Type =>
3057 New_Reference_To (RTE (RE_Address), Loc)),
3059 Make_Parameter_Specification (Loc,
3060 Defining_Identifier =>
3061 Make_Defining_Identifier (Loc, Name_uD),
3062 Parameter_Type =>
3063 New_Reference_To (Standard_Duration, Loc)),
3065 Make_Parameter_Specification (Loc,
3066 Defining_Identifier =>
3067 Make_Defining_Identifier (Loc, Name_uM),
3068 Parameter_Type =>
3069 New_Reference_To (Standard_Integer, Loc)),
3071 Make_Parameter_Specification (Loc,
3072 Defining_Identifier =>
3073 Make_Defining_Identifier (Loc, Name_uC),
3074 Parameter_Type =>
3075 New_Reference_To (RTE (RE_Prim_Op_Kind), Loc),
3076 Out_Present => True)));
3078 Append_To (Params,
3079 Make_Parameter_Specification (Loc,
3080 Defining_Identifier =>
3081 Make_Defining_Identifier (Loc, Name_uF),
3082 Parameter_Type =>
3083 New_Reference_To (Standard_Boolean, Loc),
3084 Out_Present => True));
3086 return
3087 Make_Procedure_Specification (Loc,
3088 Defining_Unit_Name => Def_Id,
3089 Parameter_Specifications => Params);
3090 end Make_Disp_Timed_Select_Spec;
3092 -------------
3093 -- Make_DT --
3094 -------------
3096 -- The frontend supports two models for expanding dispatch tables
3097 -- associated with library-level defined tagged types: statically
3098 -- and non-statically allocated dispatch tables. In the former case
3099 -- the object containing the dispatch table is constant and it is
3100 -- initialized by means of a positional aggregate. In the latter case,
3101 -- the object containing the dispatch table is a variable which is
3102 -- initialized by means of assignments.
3104 -- In case of locally defined tagged types, the object containing the
3105 -- object containing the dispatch table is always a variable (instead
3106 -- of a constant). This is currently required to give support to late
3107 -- overriding of primitives. For example:
3109 -- procedure Example is
3110 -- package Pkg is
3111 -- type T1 is tagged null record;
3112 -- procedure Prim (O : T1);
3113 -- end Pkg;
3115 -- type T2 is new Pkg.T1 with null record;
3116 -- procedure Prim (X : T2) is -- late overriding
3117 -- begin
3118 -- ...
3119 -- ...
3120 -- end;
3122 function Make_DT (Typ : Entity_Id; N : Node_Id := Empty) return List_Id is
3123 Loc : constant Source_Ptr := Sloc (Typ);
3125 Max_Predef_Prims : constant Int :=
3126 UI_To_Int
3127 (Intval
3128 (Expression
3129 (Parent (RTE (RE_Max_Predef_Prims)))));
3131 DT_Decl : constant Elist_Id := New_Elmt_List;
3132 DT_Aggr : constant Elist_Id := New_Elmt_List;
3133 -- Entities marked with attribute Is_Dispatch_Table_Entity
3135 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id);
3136 -- Verify that all non-tagged types in the profile of a subprogram
3137 -- are frozen at the point the subprogram is frozen. This enforces
3138 -- the rule on RM 13.14 (14) as modified by AI05-019. At the point a
3139 -- subprogram is frozen, enough must be known about it to build the
3140 -- activation record for it, which requires at least that the size of
3141 -- all parameters be known. Controlling arguments are by-reference,
3142 -- and therefore the rule only applies to non-tagged types.
3143 -- Typical violation of the rule involves an object declaration that
3144 -- freezes a tagged type, when one of its primitive operations has a
3145 -- type in its profile whose full view has not been analyzed yet.
3147 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id);
3148 -- Export the dispatch table entity DT of tagged type Typ. Required to
3149 -- generate forward references and statically allocate the table.
3151 procedure Make_Secondary_DT
3152 (Typ : Entity_Id;
3153 Iface : Entity_Id;
3154 Num_Iface_Prims : Nat;
3155 Iface_DT_Ptr : Entity_Id;
3156 Predef_Prims_Ptr : Entity_Id;
3157 Build_Thunks : Boolean;
3158 Result : List_Id);
3159 -- Ada 2005 (AI-251): Expand the declarations for a Secondary Dispatch
3160 -- Table of Typ associated with Iface. Each abstract interface of Typ
3161 -- has two secondary dispatch tables: one containing pointers to thunks
3162 -- and another containing pointers to the primitives covering the
3163 -- interface primitives. The former secondary table is generated when
3164 -- Build_Thunks is True, and provides common support for dispatching
3165 -- calls through interface types; the latter secondary table is
3166 -- generated when Build_Thunks is False, and provides support for
3167 -- Generic Dispatching Constructors that dispatch calls through
3168 -- interface types.
3170 ------------------------------
3171 -- Check_Premature_Freezing --
3172 ------------------------------
3174 procedure Check_Premature_Freezing (Subp : Entity_Id; Typ : Entity_Id) is
3175 begin
3176 if Present (N)
3177 and then Is_Private_Type (Typ)
3178 and then No (Full_View (Typ))
3179 and then not Is_Generic_Type (Typ)
3180 and then not Is_Tagged_Type (Typ)
3181 and then not Is_Frozen (Typ)
3182 then
3183 Error_Msg_Sloc := Sloc (Subp);
3184 Error_Msg_NE
3185 ("declaration must appear after completion of type &", N, Typ);
3186 Error_Msg_NE
3187 ("\which is an untagged type in the profile of"
3188 & " primitive operation & declared#",
3189 N, Subp);
3190 end if;
3191 end Check_Premature_Freezing;
3193 ---------------
3194 -- Export_DT --
3195 ---------------
3197 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id) is
3198 begin
3199 Set_Is_Statically_Allocated (DT);
3200 Set_Is_True_Constant (DT);
3201 Set_Is_Exported (DT);
3203 pragma Assert (Present (Dispatch_Table_Wrapper (Typ)));
3204 Get_External_Name (Dispatch_Table_Wrapper (Typ), True);
3205 Set_Interface_Name (DT,
3206 Make_String_Literal (Loc,
3207 Strval => String_From_Name_Buffer));
3209 -- Ensure proper Sprint output of this implicit importation
3211 Set_Is_Internal (DT);
3212 Set_Is_Public (DT);
3213 end Export_DT;
3215 -----------------------
3216 -- Make_Secondary_DT --
3217 -----------------------
3219 procedure Make_Secondary_DT
3220 (Typ : Entity_Id;
3221 Iface : Entity_Id;
3222 Num_Iface_Prims : Nat;
3223 Iface_DT_Ptr : Entity_Id;
3224 Predef_Prims_Ptr : Entity_Id;
3225 Build_Thunks : Boolean;
3226 Result : List_Id)
3228 Loc : constant Source_Ptr := Sloc (Typ);
3229 Name_DT : constant Name_Id := New_Internal_Name ('T');
3230 Iface_DT : constant Entity_Id :=
3231 Make_Defining_Identifier (Loc, Name_DT);
3232 Name_Predef_Prims : constant Name_Id := New_Internal_Name ('R');
3233 Predef_Prims : constant Entity_Id :=
3234 Make_Defining_Identifier (Loc,
3235 Name_Predef_Prims);
3236 DT_Constr_List : List_Id;
3237 DT_Aggr_List : List_Id;
3238 Empty_DT : Boolean := False;
3239 Nb_Predef_Prims : Nat := 0;
3240 Nb_Prim : Nat;
3241 New_Node : Node_Id;
3242 OSD : Entity_Id;
3243 OSD_Aggr_List : List_Id;
3244 Pos : Nat;
3245 Prim : Entity_Id;
3246 Prim_Elmt : Elmt_Id;
3247 Prim_Ops_Aggr_List : List_Id;
3249 begin
3250 -- Handle cases in which we do not generate statically allocated
3251 -- dispatch tables.
3253 if not Building_Static_DT (Typ) then
3254 Set_Ekind (Predef_Prims, E_Variable);
3255 Set_Ekind (Iface_DT, E_Variable);
3257 -- Statically allocated dispatch tables and related entities are
3258 -- constants.
3260 else
3261 Set_Ekind (Predef_Prims, E_Constant);
3262 Set_Is_Statically_Allocated (Predef_Prims);
3263 Set_Is_True_Constant (Predef_Prims);
3265 Set_Ekind (Iface_DT, E_Constant);
3266 Set_Is_Statically_Allocated (Iface_DT);
3267 Set_Is_True_Constant (Iface_DT);
3268 end if;
3270 -- Generate code to create the storage for the Dispatch_Table object.
3271 -- If the number of primitives of Typ is 0 we reserve a dummy single
3272 -- entry for its DT because at run-time the pointer to this dummy
3273 -- entry will be used as the tag.
3275 if Num_Iface_Prims = 0 then
3276 Empty_DT := True;
3277 Nb_Prim := 1;
3278 else
3279 Nb_Prim := Num_Iface_Prims;
3280 end if;
3282 -- Generate:
3284 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
3285 -- (predef-prim-op-thunk-1'address,
3286 -- predef-prim-op-thunk-2'address,
3287 -- ...
3288 -- predef-prim-op-thunk-n'address);
3289 -- for Predef_Prims'Alignment use Address'Alignment
3291 -- Stage 1: Calculate the number of predefined primitives
3293 if not Building_Static_DT (Typ) then
3294 Nb_Predef_Prims := Max_Predef_Prims;
3295 else
3296 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3297 while Present (Prim_Elmt) loop
3298 Prim := Node (Prim_Elmt);
3300 if Is_Predefined_Dispatching_Operation (Prim)
3301 and then not Is_Abstract_Subprogram (Prim)
3302 then
3303 Pos := UI_To_Int (DT_Position (Prim));
3305 if Pos > Nb_Predef_Prims then
3306 Nb_Predef_Prims := Pos;
3307 end if;
3308 end if;
3310 Next_Elmt (Prim_Elmt);
3311 end loop;
3312 end if;
3314 -- Stage 2: Create the thunks associated with the predefined
3315 -- primitives and save their entity to fill the aggregate.
3317 declare
3318 Prim_Table : array (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
3319 Decl : Node_Id;
3320 Thunk_Id : Entity_Id;
3321 Thunk_Code : Node_Id;
3323 begin
3324 Prim_Ops_Aggr_List := New_List;
3325 Prim_Table := (others => Empty);
3327 if Building_Static_DT (Typ) then
3328 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3329 while Present (Prim_Elmt) loop
3330 Prim := Node (Prim_Elmt);
3332 if Is_Predefined_Dispatching_Operation (Prim)
3333 and then not Is_Abstract_Subprogram (Prim)
3334 and then not Present (Prim_Table
3335 (UI_To_Int (DT_Position (Prim))))
3336 then
3337 if not Build_Thunks then
3338 Prim_Table (UI_To_Int (DT_Position (Prim))) :=
3339 Alias (Prim);
3341 else
3342 while Present (Alias (Prim)) loop
3343 Prim := Alias (Prim);
3344 end loop;
3346 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
3348 if Present (Thunk_Id) then
3349 Append_To (Result, Thunk_Code);
3350 Prim_Table (UI_To_Int (DT_Position (Prim)))
3351 := Thunk_Id;
3352 end if;
3353 end if;
3354 end if;
3356 Next_Elmt (Prim_Elmt);
3357 end loop;
3358 end if;
3360 for J in Prim_Table'Range loop
3361 if Present (Prim_Table (J)) then
3362 New_Node :=
3363 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
3364 Make_Attribute_Reference (Loc,
3365 Prefix => New_Reference_To (Prim_Table (J), Loc),
3366 Attribute_Name => Name_Unrestricted_Access));
3367 else
3368 New_Node := Make_Null (Loc);
3369 end if;
3371 Append_To (Prim_Ops_Aggr_List, New_Node);
3372 end loop;
3374 New_Node :=
3375 Make_Aggregate (Loc,
3376 Expressions => Prim_Ops_Aggr_List);
3378 -- Remember aggregates initializing dispatch tables
3380 Append_Elmt (New_Node, DT_Aggr);
3382 Decl :=
3383 Make_Subtype_Declaration (Loc,
3384 Defining_Identifier =>
3385 Make_Defining_Identifier (Loc,
3386 New_Internal_Name ('S')),
3387 Subtype_Indication =>
3388 New_Reference_To (RTE (RE_Address_Array), Loc));
3390 Append_To (Result, Decl);
3392 Append_To (Result,
3393 Make_Object_Declaration (Loc,
3394 Defining_Identifier => Predef_Prims,
3395 Constant_Present => Building_Static_DT (Typ),
3396 Aliased_Present => True,
3397 Object_Definition => New_Reference_To
3398 (Defining_Identifier (Decl), Loc),
3399 Expression => New_Node));
3401 Append_To (Result,
3402 Make_Attribute_Definition_Clause (Loc,
3403 Name => New_Reference_To (Predef_Prims, Loc),
3404 Chars => Name_Alignment,
3405 Expression =>
3406 Make_Attribute_Reference (Loc,
3407 Prefix =>
3408 New_Reference_To (RTE (RE_Integer_Address), Loc),
3409 Attribute_Name => Name_Alignment)));
3410 end;
3412 -- Generate
3414 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
3415 -- (OSD_Table => (1 => <value>,
3416 -- ...
3417 -- N => <value>));
3419 -- Iface_DT : Dispatch_Table (Nb_Prims) :=
3420 -- ([ Signature => <sig-value> ],
3421 -- Tag_Kind => <tag_kind-value>,
3422 -- Predef_Prims => Predef_Prims'Address,
3423 -- Offset_To_Top => 0,
3424 -- OSD => OSD'Address,
3425 -- Prims_Ptr => (prim-op-1'address,
3426 -- prim-op-2'address,
3427 -- ...
3428 -- prim-op-n'address));
3430 -- Stage 3: Initialize the discriminant and the record components
3432 DT_Constr_List := New_List;
3433 DT_Aggr_List := New_List;
3435 -- Nb_Prim. If the tagged type has no primitives we add a dummy
3436 -- slot whose address will be the tag of this type.
3438 if Nb_Prim = 0 then
3439 New_Node := Make_Integer_Literal (Loc, 1);
3440 else
3441 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
3442 end if;
3444 Append_To (DT_Constr_List, New_Node);
3445 Append_To (DT_Aggr_List, New_Copy (New_Node));
3447 -- Signature
3449 if RTE_Record_Component_Available (RE_Signature) then
3450 Append_To (DT_Aggr_List,
3451 New_Reference_To (RTE (RE_Secondary_DT), Loc));
3452 end if;
3454 -- Tag_Kind
3456 if RTE_Record_Component_Available (RE_Tag_Kind) then
3457 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
3458 end if;
3460 -- Predef_Prims
3462 Append_To (DT_Aggr_List,
3463 Make_Attribute_Reference (Loc,
3464 Prefix => New_Reference_To (Predef_Prims, Loc),
3465 Attribute_Name => Name_Address));
3467 -- Note: The correct value of Offset_To_Top will be set by the init
3468 -- subprogram
3470 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
3472 -- Generate the Object Specific Data table required to dispatch calls
3473 -- through synchronized interfaces.
3475 if Empty_DT
3476 or else Is_Abstract_Type (Typ)
3477 or else Is_Controlled (Typ)
3478 or else Restriction_Active (No_Dispatching_Calls)
3479 or else not Is_Limited_Type (Typ)
3480 or else not Has_Interfaces (Typ)
3481 or else not Build_Thunks
3482 then
3483 -- No OSD table required
3485 Append_To (DT_Aggr_List,
3486 New_Reference_To (RTE (RE_Null_Address), Loc));
3488 else
3489 OSD_Aggr_List := New_List;
3491 declare
3492 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
3493 Prim : Entity_Id;
3494 Prim_Alias : Entity_Id;
3495 Prim_Elmt : Elmt_Id;
3496 E : Entity_Id;
3497 Count : Nat := 0;
3498 Pos : Nat;
3500 begin
3501 Prim_Table := (others => Empty);
3502 Prim_Alias := Empty;
3504 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3505 while Present (Prim_Elmt) loop
3506 Prim := Node (Prim_Elmt);
3508 if Present (Interface_Alias (Prim))
3509 and then Find_Dispatching_Type
3510 (Interface_Alias (Prim)) = Iface
3511 then
3512 Prim_Alias := Interface_Alias (Prim);
3514 E := Prim;
3515 while Present (Alias (E)) loop
3516 E := Alias (E);
3517 end loop;
3519 Pos := UI_To_Int (DT_Position (Prim_Alias));
3521 if Present (Prim_Table (Pos)) then
3522 pragma Assert (Prim_Table (Pos) = E);
3523 null;
3525 else
3526 Prim_Table (Pos) := E;
3528 Append_To (OSD_Aggr_List,
3529 Make_Component_Association (Loc,
3530 Choices => New_List (
3531 Make_Integer_Literal (Loc,
3532 DT_Position (Prim_Alias))),
3533 Expression =>
3534 Make_Integer_Literal (Loc,
3535 DT_Position (Alias (Prim)))));
3537 Count := Count + 1;
3538 end if;
3539 end if;
3541 Next_Elmt (Prim_Elmt);
3542 end loop;
3543 pragma Assert (Count = Nb_Prim);
3544 end;
3546 OSD := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
3548 Append_To (Result,
3549 Make_Object_Declaration (Loc,
3550 Defining_Identifier => OSD,
3551 Object_Definition =>
3552 Make_Subtype_Indication (Loc,
3553 Subtype_Mark =>
3554 New_Reference_To (RTE (RE_Object_Specific_Data), Loc),
3555 Constraint =>
3556 Make_Index_Or_Discriminant_Constraint (Loc,
3557 Constraints => New_List (
3558 Make_Integer_Literal (Loc, Nb_Prim)))),
3559 Expression => Make_Aggregate (Loc,
3560 Component_Associations => New_List (
3561 Make_Component_Association (Loc,
3562 Choices => New_List (
3563 New_Occurrence_Of
3564 (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
3565 Expression =>
3566 Make_Integer_Literal (Loc, Nb_Prim)),
3568 Make_Component_Association (Loc,
3569 Choices => New_List (
3570 New_Occurrence_Of
3571 (RTE_Record_Component (RE_OSD_Table), Loc)),
3572 Expression => Make_Aggregate (Loc,
3573 Component_Associations => OSD_Aggr_List))))));
3575 Append_To (Result,
3576 Make_Attribute_Definition_Clause (Loc,
3577 Name => New_Reference_To (OSD, Loc),
3578 Chars => Name_Alignment,
3579 Expression =>
3580 Make_Attribute_Reference (Loc,
3581 Prefix =>
3582 New_Reference_To (RTE (RE_Integer_Address), Loc),
3583 Attribute_Name => Name_Alignment)));
3585 -- In secondary dispatch tables the Typeinfo component contains
3586 -- the address of the Object Specific Data (see a-tags.ads)
3588 Append_To (DT_Aggr_List,
3589 Make_Attribute_Reference (Loc,
3590 Prefix => New_Reference_To (OSD, Loc),
3591 Attribute_Name => Name_Address));
3592 end if;
3594 -- Initialize the table of primitive operations
3596 Prim_Ops_Aggr_List := New_List;
3598 if Empty_DT then
3599 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
3601 elsif Is_Abstract_Type (Typ)
3602 or else not Building_Static_DT (Typ)
3603 then
3604 for J in 1 .. Nb_Prim loop
3605 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
3606 end loop;
3608 else
3609 declare
3610 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
3611 Pos : Nat;
3612 Thunk_Code : Node_Id;
3613 Thunk_Id : Entity_Id;
3615 begin
3616 Prim_Table := (others => Empty);
3618 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3619 while Present (Prim_Elmt) loop
3620 Prim := Node (Prim_Elmt);
3622 if not Is_Predefined_Dispatching_Operation (Prim)
3623 and then Present (Interface_Alias (Prim))
3624 and then not Is_Abstract_Subprogram (Alias (Prim))
3625 and then not Is_Imported (Alias (Prim))
3626 and then Find_Dispatching_Type
3627 (Interface_Alias (Prim)) = Iface
3629 -- Generate the code of the thunk only if the abstract
3630 -- interface type is not an immediate ancestor of
3631 -- Tagged_Type; otherwise the DT associated with the
3632 -- interface is the primary DT.
3634 and then not Is_Ancestor (Iface, Typ)
3635 then
3636 if not Build_Thunks then
3637 Pos :=
3638 UI_To_Int (DT_Position (Interface_Alias (Prim)));
3639 Prim_Table (Pos) := Alias (Prim);
3640 else
3641 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
3643 if Present (Thunk_Id) then
3644 Pos :=
3645 UI_To_Int (DT_Position (Interface_Alias (Prim)));
3647 Prim_Table (Pos) := Thunk_Id;
3648 Append_To (Result, Thunk_Code);
3649 end if;
3650 end if;
3651 end if;
3653 Next_Elmt (Prim_Elmt);
3654 end loop;
3656 for J in Prim_Table'Range loop
3657 if Present (Prim_Table (J)) then
3658 New_Node :=
3659 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
3660 Make_Attribute_Reference (Loc,
3661 Prefix => New_Reference_To (Prim_Table (J), Loc),
3662 Attribute_Name => Name_Unrestricted_Access));
3663 else
3664 New_Node := Make_Null (Loc);
3665 end if;
3667 Append_To (Prim_Ops_Aggr_List, New_Node);
3668 end loop;
3669 end;
3670 end if;
3672 New_Node :=
3673 Make_Aggregate (Loc,
3674 Expressions => Prim_Ops_Aggr_List);
3676 Append_To (DT_Aggr_List, New_Node);
3678 -- Remember aggregates initializing dispatch tables
3680 Append_Elmt (New_Node, DT_Aggr);
3682 Append_To (Result,
3683 Make_Object_Declaration (Loc,
3684 Defining_Identifier => Iface_DT,
3685 Aliased_Present => True,
3686 Object_Definition =>
3687 Make_Subtype_Indication (Loc,
3688 Subtype_Mark => New_Reference_To
3689 (RTE (RE_Dispatch_Table_Wrapper), Loc),
3690 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
3691 Constraints => DT_Constr_List)),
3693 Expression => Make_Aggregate (Loc,
3694 Expressions => DT_Aggr_List)));
3696 Append_To (Result,
3697 Make_Attribute_Definition_Clause (Loc,
3698 Name => New_Reference_To (Iface_DT, Loc),
3699 Chars => Name_Alignment,
3700 Expression =>
3701 Make_Attribute_Reference (Loc,
3702 Prefix =>
3703 New_Reference_To (RTE (RE_Integer_Address), Loc),
3704 Attribute_Name => Name_Alignment)));
3706 -- Generate code to create the pointer to the dispatch table
3708 -- Iface_DT_Ptr : Tag := Tag!(DT'Address);
3710 Append_To (Result,
3711 Make_Object_Declaration (Loc,
3712 Defining_Identifier => Iface_DT_Ptr,
3713 Constant_Present => True,
3714 Object_Definition =>
3715 New_Reference_To (RTE (RE_Interface_Tag), Loc),
3716 Expression =>
3717 Unchecked_Convert_To (RTE (RE_Interface_Tag),
3718 Make_Attribute_Reference (Loc,
3719 Prefix =>
3720 Make_Selected_Component (Loc,
3721 Prefix => New_Reference_To (Iface_DT, Loc),
3722 Selector_Name =>
3723 New_Occurrence_Of
3724 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
3725 Attribute_Name => Name_Address))));
3727 Append_To (Result,
3728 Make_Object_Declaration (Loc,
3729 Defining_Identifier => Predef_Prims_Ptr,
3730 Constant_Present => True,
3731 Object_Definition =>
3732 New_Reference_To (RTE (RE_Address), Loc),
3733 Expression =>
3734 Make_Attribute_Reference (Loc,
3735 Prefix =>
3736 Make_Selected_Component (Loc,
3737 Prefix => New_Reference_To (Iface_DT, Loc),
3738 Selector_Name =>
3739 New_Occurrence_Of
3740 (RTE_Record_Component (RE_Predef_Prims), Loc)),
3741 Attribute_Name => Name_Address)));
3743 -- Remember entities containing dispatch tables
3745 Append_Elmt (Predef_Prims, DT_Decl);
3746 Append_Elmt (Iface_DT, DT_Decl);
3747 end Make_Secondary_DT;
3749 -- Local variables
3751 Elab_Code : constant List_Id := New_List;
3752 Result : constant List_Id := New_List;
3753 Tname : constant Name_Id := Chars (Typ);
3754 AI : Elmt_Id;
3755 AI_Tag_Elmt : Elmt_Id;
3756 AI_Tag_Comp : Elmt_Id;
3757 DT_Aggr_List : List_Id;
3758 DT_Constr_List : List_Id;
3759 DT_Ptr : Entity_Id;
3760 ITable : Node_Id;
3761 I_Depth : Nat := 0;
3762 Iface_Table_Node : Node_Id;
3763 Name_ITable : Name_Id;
3764 Nb_Predef_Prims : Nat := 0;
3765 Nb_Prim : Nat := 0;
3766 New_Node : Node_Id;
3767 Num_Ifaces : Nat := 0;
3768 Parent_Typ : Entity_Id;
3769 Prim : Entity_Id;
3770 Prim_Elmt : Elmt_Id;
3771 Prim_Ops_Aggr_List : List_Id;
3772 Suffix_Index : Int;
3773 Typ_Comps : Elist_Id;
3774 Typ_Ifaces : Elist_Id;
3775 TSD_Aggr_List : List_Id;
3776 TSD_Tags_List : List_Id;
3778 -- The following name entries are used by Make_DT to generate a number
3779 -- of entities related to a tagged type. These entities may be generated
3780 -- in a scope other than that of the tagged type declaration, and if
3781 -- the entities for two tagged types with the same name happen to be
3782 -- generated in the same scope, we have to take care to use different
3783 -- names. This is achieved by means of a unique serial number appended
3784 -- to each generated entity name.
3786 Name_DT : constant Name_Id :=
3787 New_External_Name (Tname, 'T', Suffix_Index => -1);
3788 Name_Exname : constant Name_Id :=
3789 New_External_Name (Tname, 'E', Suffix_Index => -1);
3790 Name_HT_Link : constant Name_Id :=
3791 New_External_Name (Tname, 'H', Suffix_Index => -1);
3792 Name_Predef_Prims : constant Name_Id :=
3793 New_External_Name (Tname, 'R', Suffix_Index => -1);
3794 Name_SSD : constant Name_Id :=
3795 New_External_Name (Tname, 'S', Suffix_Index => -1);
3796 Name_TSD : constant Name_Id :=
3797 New_External_Name (Tname, 'B', Suffix_Index => -1);
3799 -- Entities built with above names
3801 DT : constant Entity_Id :=
3802 Make_Defining_Identifier (Loc, Name_DT);
3803 Exname : constant Entity_Id :=
3804 Make_Defining_Identifier (Loc, Name_Exname);
3805 HT_Link : constant Entity_Id :=
3806 Make_Defining_Identifier (Loc, Name_HT_Link);
3807 Predef_Prims : constant Entity_Id :=
3808 Make_Defining_Identifier (Loc, Name_Predef_Prims);
3809 SSD : constant Entity_Id :=
3810 Make_Defining_Identifier (Loc, Name_SSD);
3811 TSD : constant Entity_Id :=
3812 Make_Defining_Identifier (Loc, Name_TSD);
3814 -- Start of processing for Make_DT
3816 begin
3817 pragma Assert (Is_Frozen (Typ));
3819 -- Handle cases in which there is no need to build the dispatch table
3821 if Has_Dispatch_Table (Typ)
3822 or else No (Access_Disp_Table (Typ))
3823 or else Is_CPP_Class (Typ)
3824 then
3825 return Result;
3827 elsif No_Run_Time_Mode then
3828 Error_Msg_CRT ("tagged types", Typ);
3829 return Result;
3831 elsif not RTE_Available (RE_Tag) then
3832 Append_To (Result,
3833 Make_Object_Declaration (Loc,
3834 Defining_Identifier => Node (First_Elmt
3835 (Access_Disp_Table (Typ))),
3836 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
3837 Constant_Present => True,
3838 Expression =>
3839 Unchecked_Convert_To (RTE (RE_Tag),
3840 New_Reference_To (RTE (RE_Null_Address), Loc))));
3842 Analyze_List (Result, Suppress => All_Checks);
3843 Error_Msg_CRT ("tagged types", Typ);
3844 return Result;
3845 end if;
3847 -- Ensure that the value of Max_Predef_Prims defined in a-tags is
3848 -- correct. Valid values are 10 under configurable runtime or 16
3849 -- with full runtime.
3851 if RTE_Available (RE_Interface_Data) then
3852 if Max_Predef_Prims /= 16 then
3853 Error_Msg_N ("run-time library configuration error", Typ);
3854 return Result;
3855 end if;
3856 else
3857 if Max_Predef_Prims /= 10 then
3858 Error_Msg_N ("run-time library configuration error", Typ);
3859 Error_Msg_CRT ("tagged types", Typ);
3860 return Result;
3861 end if;
3862 end if;
3864 -- Initialize Parent_Typ handling private types
3866 Parent_Typ := Etype (Typ);
3868 if Present (Full_View (Parent_Typ)) then
3869 Parent_Typ := Full_View (Parent_Typ);
3870 end if;
3872 -- Ensure that all the primitives are frozen. This is only required when
3873 -- building static dispatch tables --- the primitives must be frozen to
3874 -- be referenced (otherwise we have problems with the backend). It is
3875 -- not a requirement with nonstatic dispatch tables because in this case
3876 -- we generate now an empty dispatch table; the extra code required to
3877 -- register the primitives in the slots will be generated later --- when
3878 -- each primitive is frozen (see Freeze_Subprogram).
3880 if Building_Static_DT (Typ)
3881 and then not Is_CPP_Class (Typ)
3882 then
3883 declare
3884 Save : constant Boolean := Freezing_Library_Level_Tagged_Type;
3885 Prim_Elmt : Elmt_Id;
3886 Frnodes : List_Id;
3888 begin
3889 Freezing_Library_Level_Tagged_Type := True;
3890 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
3891 while Present (Prim_Elmt) loop
3892 Frnodes := Freeze_Entity (Node (Prim_Elmt), Loc);
3894 declare
3895 Subp : constant Entity_Id := Node (Prim_Elmt);
3896 F : Entity_Id;
3898 begin
3899 F := First_Formal (Subp);
3900 while Present (F) loop
3901 Check_Premature_Freezing (Subp, Etype (F));
3902 Next_Formal (F);
3903 end loop;
3905 Check_Premature_Freezing (Subp, Etype (Subp));
3906 end;
3908 if Present (Frnodes) then
3909 Append_List_To (Result, Frnodes);
3910 end if;
3912 Next_Elmt (Prim_Elmt);
3913 end loop;
3914 Freezing_Library_Level_Tagged_Type := Save;
3915 end;
3916 end if;
3918 -- Ada 2005 (AI-251): Build the secondary dispatch tables
3920 if Has_Interfaces (Typ) then
3921 Collect_Interface_Components (Typ, Typ_Comps);
3923 Suffix_Index := 0;
3924 AI_Tag_Elmt :=
3925 Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
3927 AI_Tag_Comp := First_Elmt (Typ_Comps);
3928 while Present (AI_Tag_Comp) loop
3930 -- Build the secondary table containing pointers to thunks
3932 Make_Secondary_DT
3933 (Typ => Typ,
3934 Iface => Base_Type (Related_Type (Node (AI_Tag_Comp))),
3935 Num_Iface_Prims => UI_To_Int
3936 (DT_Entry_Count (Node (AI_Tag_Comp))),
3937 Iface_DT_Ptr => Node (AI_Tag_Elmt),
3938 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
3939 Build_Thunks => True,
3940 Result => Result);
3941 Next_Elmt (AI_Tag_Elmt);
3943 -- Skip the secondary dispatch table of predefined primitives
3945 Next_Elmt (AI_Tag_Elmt);
3947 -- Build the secondary table containing pointers to primitives
3948 -- (used to give support to Generic Dispatching Constructors).
3950 Make_Secondary_DT
3951 (Typ => Typ,
3952 Iface => Base_Type (Related_Type (Node (AI_Tag_Comp))),
3953 Num_Iface_Prims => UI_To_Int
3954 (DT_Entry_Count (Node (AI_Tag_Comp))),
3955 Iface_DT_Ptr => Node (AI_Tag_Elmt),
3956 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
3957 Build_Thunks => False,
3958 Result => Result);
3959 Next_Elmt (AI_Tag_Elmt);
3961 -- Skip the secondary dispatch table of predefined primitives
3963 Next_Elmt (AI_Tag_Elmt);
3965 Suffix_Index := Suffix_Index + 1;
3966 Next_Elmt (AI_Tag_Comp);
3967 end loop;
3968 end if;
3970 -- Get the _tag entity and the number of primitives of its dispatch
3971 -- table.
3973 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
3974 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
3976 Set_Is_Statically_Allocated (DT, Is_Library_Level_Tagged_Type (Typ));
3977 Set_Is_Statically_Allocated (SSD, Is_Library_Level_Tagged_Type (Typ));
3978 Set_Is_Statically_Allocated (TSD, Is_Library_Level_Tagged_Type (Typ));
3979 Set_Is_Statically_Allocated (Predef_Prims,
3980 Is_Library_Level_Tagged_Type (Typ));
3982 -- In case of locally defined tagged type we declare the object
3983 -- containing the dispatch table by means of a variable. Its
3984 -- initialization is done later by means of an assignment. This is
3985 -- required to generate its External_Tag.
3987 if not Building_Static_DT (Typ) then
3989 -- Generate:
3990 -- DT : No_Dispatch_Table_Wrapper;
3991 -- for DT'Alignment use Address'Alignment;
3992 -- DT_Ptr : Tag := !Tag (DT.NDT_Prims_Ptr'Address);
3994 if not Has_DT (Typ) then
3995 Append_To (Result,
3996 Make_Object_Declaration (Loc,
3997 Defining_Identifier => DT,
3998 Aliased_Present => True,
3999 Constant_Present => False,
4000 Object_Definition =>
4001 New_Reference_To
4002 (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
4004 Append_To (Result,
4005 Make_Attribute_Definition_Clause (Loc,
4006 Name => New_Reference_To (DT, Loc),
4007 Chars => Name_Alignment,
4008 Expression =>
4009 Make_Attribute_Reference (Loc,
4010 Prefix =>
4011 New_Reference_To (RTE (RE_Integer_Address), Loc),
4012 Attribute_Name => Name_Alignment)));
4014 Append_To (Result,
4015 Make_Object_Declaration (Loc,
4016 Defining_Identifier => DT_Ptr,
4017 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4018 Constant_Present => True,
4019 Expression =>
4020 Unchecked_Convert_To (RTE (RE_Tag),
4021 Make_Attribute_Reference (Loc,
4022 Prefix =>
4023 Make_Selected_Component (Loc,
4024 Prefix => New_Reference_To (DT, Loc),
4025 Selector_Name =>
4026 New_Occurrence_Of
4027 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
4028 Attribute_Name => Name_Address))));
4030 -- Generate:
4031 -- DT : Dispatch_Table_Wrapper (Nb_Prim);
4032 -- for DT'Alignment use Address'Alignment;
4033 -- DT_Ptr : Tag := !Tag (DT.Prims_Ptr'Address);
4035 else
4036 -- If the tagged type has no primitives we add a dummy slot
4037 -- whose address will be the tag of this type.
4039 if Nb_Prim = 0 then
4040 DT_Constr_List :=
4041 New_List (Make_Integer_Literal (Loc, 1));
4042 else
4043 DT_Constr_List :=
4044 New_List (Make_Integer_Literal (Loc, Nb_Prim));
4045 end if;
4047 Append_To (Result,
4048 Make_Object_Declaration (Loc,
4049 Defining_Identifier => DT,
4050 Aliased_Present => True,
4051 Constant_Present => False,
4052 Object_Definition =>
4053 Make_Subtype_Indication (Loc,
4054 Subtype_Mark =>
4055 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
4056 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4057 Constraints => DT_Constr_List))));
4059 Append_To (Result,
4060 Make_Attribute_Definition_Clause (Loc,
4061 Name => New_Reference_To (DT, Loc),
4062 Chars => Name_Alignment,
4063 Expression =>
4064 Make_Attribute_Reference (Loc,
4065 Prefix =>
4066 New_Reference_To (RTE (RE_Integer_Address), Loc),
4067 Attribute_Name => Name_Alignment)));
4069 Append_To (Result,
4070 Make_Object_Declaration (Loc,
4071 Defining_Identifier => DT_Ptr,
4072 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
4073 Constant_Present => True,
4074 Expression =>
4075 Unchecked_Convert_To (RTE (RE_Tag),
4076 Make_Attribute_Reference (Loc,
4077 Prefix =>
4078 Make_Selected_Component (Loc,
4079 Prefix => New_Reference_To (DT, Loc),
4080 Selector_Name =>
4081 New_Occurrence_Of
4082 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
4083 Attribute_Name => Name_Address))));
4085 Append_To (Result,
4086 Make_Object_Declaration (Loc,
4087 Defining_Identifier =>
4088 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Typ)))),
4089 Constant_Present => True,
4090 Object_Definition => New_Reference_To
4091 (RTE (RE_Address), Loc),
4092 Expression =>
4093 Make_Attribute_Reference (Loc,
4094 Prefix =>
4095 Make_Selected_Component (Loc,
4096 Prefix => New_Reference_To (DT, Loc),
4097 Selector_Name =>
4098 New_Occurrence_Of
4099 (RTE_Record_Component (RE_Predef_Prims), Loc)),
4100 Attribute_Name => Name_Address)));
4101 end if;
4102 end if;
4104 -- Generate: Exname : constant String := full_qualified_name (typ);
4105 -- The type itself may be an anonymous parent type, so use the first
4106 -- subtype to have a user-recognizable name.
4108 Append_To (Result,
4109 Make_Object_Declaration (Loc,
4110 Defining_Identifier => Exname,
4111 Constant_Present => True,
4112 Object_Definition => New_Reference_To (Standard_String, Loc),
4113 Expression =>
4114 Make_String_Literal (Loc,
4115 Full_Qualified_Name (First_Subtype (Typ)))));
4117 Set_Is_Statically_Allocated (Exname);
4118 Set_Is_True_Constant (Exname);
4120 -- Declare the object used by Ada.Tags.Register_Tag
4122 if RTE_Available (RE_Register_Tag) then
4123 Append_To (Result,
4124 Make_Object_Declaration (Loc,
4125 Defining_Identifier => HT_Link,
4126 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc)));
4127 end if;
4129 -- Generate code to create the storage for the type specific data object
4130 -- with enough space to store the tags of the ancestors plus the tags
4131 -- of all the implemented interfaces (as described in a-tags.adb).
4133 -- TSD : Type_Specific_Data (I_Depth) :=
4134 -- (Idepth => I_Depth,
4135 -- Access_Level => Type_Access_Level (Typ),
4136 -- Expanded_Name => Cstring_Ptr!(Exname'Address))
4137 -- External_Tag => Cstring_Ptr!(Exname'Address))
4138 -- HT_Link => HT_Link'Address,
4139 -- Transportable => <<boolean-value>>,
4140 -- RC_Offset => <<integer-value>>,
4141 -- [ Size_Func => Size_Prim'Access ]
4142 -- [ Interfaces_Table => <<access-value>> ]
4143 -- [ SSD => SSD_Table'Address ]
4144 -- Tags_Table => (0 => null,
4145 -- 1 => Parent'Tag
4146 -- ...);
4147 -- for TSD'Alignment use Address'Alignment
4149 TSD_Aggr_List := New_List;
4151 -- Idepth: Count ancestors to compute the inheritance depth. For private
4152 -- extensions, always go to the full view in order to compute the real
4153 -- inheritance depth.
4155 declare
4156 Current_Typ : Entity_Id;
4157 Parent_Typ : Entity_Id;
4159 begin
4160 I_Depth := 0;
4161 Current_Typ := Typ;
4162 loop
4163 Parent_Typ := Etype (Current_Typ);
4165 if Is_Private_Type (Parent_Typ) then
4166 Parent_Typ := Full_View (Base_Type (Parent_Typ));
4167 end if;
4169 exit when Parent_Typ = Current_Typ;
4171 I_Depth := I_Depth + 1;
4172 Current_Typ := Parent_Typ;
4173 end loop;
4174 end;
4176 Append_To (TSD_Aggr_List,
4177 Make_Integer_Literal (Loc, I_Depth));
4179 -- Access_Level
4181 Append_To (TSD_Aggr_List,
4182 Make_Integer_Literal (Loc, Type_Access_Level (Typ)));
4184 -- Expanded_Name
4186 Append_To (TSD_Aggr_List,
4187 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4188 Make_Attribute_Reference (Loc,
4189 Prefix => New_Reference_To (Exname, Loc),
4190 Attribute_Name => Name_Address)));
4192 -- External_Tag of a local tagged type
4194 -- <typ>A : constant String :=
4195 -- "Internal tag at 16#tag-addr#: <full-name-of-typ>";
4197 -- The reason we generate this strange name is that we do not want to
4198 -- enter local tagged types in the global hash table used to compute
4199 -- the Internal_Tag attribute for two reasons:
4201 -- 1. It is hard to avoid a tasking race condition for entering the
4202 -- entry into the hash table.
4204 -- 2. It would cause a storage leak, unless we rig up considerable
4205 -- mechanism to remove the entry from the hash table on exit.
4207 -- So what we do is to generate the above external tag name, where the
4208 -- hex address is the address of the local dispatch table (i.e. exactly
4209 -- the value we want if Internal_Tag is computed from this string).
4211 -- Of course this value will only be valid if the tagged type is still
4212 -- in scope, but it clearly must be erroneous to compute the internal
4213 -- tag of a tagged type that is out of scope!
4215 -- We don't do this processing if an explicit external tag has been
4216 -- specified. That's an odd case for which we have already issued a
4217 -- warning, where we will not be able to compute the internal tag.
4219 if not Is_Library_Level_Entity (Typ)
4220 and then not Has_External_Tag_Rep_Clause (Typ)
4221 then
4222 declare
4223 Exname : constant Entity_Id :=
4224 Make_Defining_Identifier (Loc,
4225 New_External_Name (Tname, 'A'));
4227 Full_Name : constant String_Id :=
4228 Full_Qualified_Name (First_Subtype (Typ));
4229 Str1_Id : String_Id;
4230 Str2_Id : String_Id;
4232 begin
4233 -- Generate:
4234 -- Str1 = "Internal tag at 16#";
4236 Start_String;
4237 Store_String_Chars ("Internal tag at 16#");
4238 Str1_Id := End_String;
4240 -- Generate:
4241 -- Str2 = "#: <type-full-name>";
4243 Start_String;
4244 Store_String_Chars ("#: ");
4245 Store_String_Chars (Full_Name);
4246 Str2_Id := End_String;
4248 -- Generate:
4249 -- Exname : constant String :=
4250 -- Str1 & Address_Image (Tag) & Str2;
4252 if RTE_Available (RE_Address_Image) then
4253 Append_To (Result,
4254 Make_Object_Declaration (Loc,
4255 Defining_Identifier => Exname,
4256 Constant_Present => True,
4257 Object_Definition => New_Reference_To
4258 (Standard_String, Loc),
4259 Expression =>
4260 Make_Op_Concat (Loc,
4261 Left_Opnd =>
4262 Make_String_Literal (Loc, Str1_Id),
4263 Right_Opnd =>
4264 Make_Op_Concat (Loc,
4265 Left_Opnd =>
4266 Make_Function_Call (Loc,
4267 Name =>
4268 New_Reference_To
4269 (RTE (RE_Address_Image), Loc),
4270 Parameter_Associations => New_List (
4271 Unchecked_Convert_To (RTE (RE_Address),
4272 New_Reference_To (DT_Ptr, Loc)))),
4273 Right_Opnd =>
4274 Make_String_Literal (Loc, Str2_Id)))));
4276 else
4277 Append_To (Result,
4278 Make_Object_Declaration (Loc,
4279 Defining_Identifier => Exname,
4280 Constant_Present => True,
4281 Object_Definition => New_Reference_To
4282 (Standard_String, Loc),
4283 Expression =>
4284 Make_Op_Concat (Loc,
4285 Left_Opnd =>
4286 Make_String_Literal (Loc, Str1_Id),
4287 Right_Opnd =>
4288 Make_String_Literal (Loc, Str2_Id))));
4289 end if;
4291 New_Node :=
4292 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4293 Make_Attribute_Reference (Loc,
4294 Prefix => New_Reference_To (Exname, Loc),
4295 Attribute_Name => Name_Address));
4296 end;
4298 -- External tag of a library-level tagged type: Check for a definition
4299 -- of External_Tag. The clause is considered only if it applies to this
4300 -- specific tagged type, as opposed to one of its ancestors.
4301 -- If the type is an unconstrained type extension, we are building the
4302 -- dispatch table of its anonymous base type, so the external tag, if
4303 -- any was specified, must be retrieved from the first subtype.
4305 else
4306 declare
4307 Def : constant Node_Id := Get_Attribute_Definition_Clause
4308 (First_Subtype (Typ),
4309 Attribute_External_Tag);
4311 Old_Val : String_Id;
4312 New_Val : String_Id;
4313 E : Entity_Id;
4315 begin
4316 if not Present (Def)
4317 or else Entity (Name (Def)) /= First_Subtype (Typ)
4318 then
4319 New_Node :=
4320 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4321 Make_Attribute_Reference (Loc,
4322 Prefix => New_Reference_To (Exname, Loc),
4323 Attribute_Name => Name_Address));
4324 else
4325 Old_Val := Strval (Expr_Value_S (Expression (Def)));
4327 -- For the rep clause "for <typ>'external_tag use y" generate:
4329 -- <typ>A : constant string := y;
4331 -- <typ>A'Address is used to set the External_Tag component
4332 -- of the TSD
4334 -- Create a new nul terminated string if it is not already
4336 if String_Length (Old_Val) > 0
4337 and then
4338 Get_String_Char (Old_Val, String_Length (Old_Val)) = 0
4339 then
4340 New_Val := Old_Val;
4341 else
4342 Start_String (Old_Val);
4343 Store_String_Char (Get_Char_Code (ASCII.NUL));
4344 New_Val := End_String;
4345 end if;
4347 E := Make_Defining_Identifier (Loc,
4348 New_External_Name (Chars (Typ), 'A'));
4350 Append_To (Result,
4351 Make_Object_Declaration (Loc,
4352 Defining_Identifier => E,
4353 Constant_Present => True,
4354 Object_Definition =>
4355 New_Reference_To (Standard_String, Loc),
4356 Expression =>
4357 Make_String_Literal (Loc, New_Val)));
4359 New_Node :=
4360 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
4361 Make_Attribute_Reference (Loc,
4362 Prefix => New_Reference_To (E, Loc),
4363 Attribute_Name => Name_Address));
4364 end if;
4365 end;
4366 end if;
4368 Append_To (TSD_Aggr_List, New_Node);
4370 -- HT_Link
4372 if RTE_Available (RE_Register_Tag) then
4373 Append_To (TSD_Aggr_List,
4374 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
4375 Make_Attribute_Reference (Loc,
4376 Prefix => New_Reference_To (HT_Link, Loc),
4377 Attribute_Name => Name_Address)));
4378 else
4379 Append_To (TSD_Aggr_List,
4380 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
4381 New_Reference_To (RTE (RE_Null_Address), Loc)));
4382 end if;
4384 -- Transportable: Set for types that can be used in remote calls
4385 -- with respect to E.4(18) legality rules.
4387 declare
4388 Transportable : Entity_Id;
4390 begin
4391 Transportable :=
4392 Boolean_Literals
4393 (Is_Pure (Typ)
4394 or else Is_Shared_Passive (Typ)
4395 or else
4396 ((Is_Remote_Types (Typ)
4397 or else Is_Remote_Call_Interface (Typ))
4398 and then Original_View_In_Visible_Part (Typ))
4399 or else not Comes_From_Source (Typ));
4401 Append_To (TSD_Aggr_List,
4402 New_Occurrence_Of (Transportable, Loc));
4403 end;
4405 -- RC_Offset: These are the valid values and their meaning:
4407 -- >0: For simple types with controlled components is
4408 -- type._record_controller'position
4410 -- 0: For types with no controlled components
4412 -- -1: For complex types with controlled components where the position
4413 -- of the record controller is not statically computable but there
4414 -- are controlled components at this level. The _Controller field
4415 -- is available right after the _parent.
4417 -- -2: There are no controlled components at this level. We need to
4418 -- get the position from the parent.
4420 declare
4421 RC_Offset_Node : Node_Id;
4423 begin
4424 if not Has_Controlled_Component (Typ) then
4425 RC_Offset_Node := Make_Integer_Literal (Loc, 0);
4427 elsif Etype (Typ) /= Typ
4428 and then Has_Discriminants (Parent_Typ)
4429 then
4430 if Has_New_Controlled_Component (Typ) then
4431 RC_Offset_Node := Make_Integer_Literal (Loc, -1);
4432 else
4433 RC_Offset_Node := Make_Integer_Literal (Loc, -2);
4434 end if;
4435 else
4436 RC_Offset_Node :=
4437 Make_Attribute_Reference (Loc,
4438 Prefix =>
4439 Make_Selected_Component (Loc,
4440 Prefix => New_Reference_To (Typ, Loc),
4441 Selector_Name =>
4442 New_Reference_To (Controller_Component (Typ), Loc)),
4443 Attribute_Name => Name_Position);
4445 -- This is not proper Ada code to use the attribute 'Position
4446 -- on something else than an object but this is supported by
4447 -- the back end (see comment on the Bit_Component attribute in
4448 -- sem_attr). So we avoid semantic checking here.
4450 -- Is this documented in sinfo.ads??? it should be!
4452 Set_Analyzed (RC_Offset_Node);
4453 Set_Etype (Prefix (RC_Offset_Node), RTE (RE_Record_Controller));
4454 Set_Etype (Prefix (Prefix (RC_Offset_Node)), Typ);
4455 Set_Etype (Selector_Name (Prefix (RC_Offset_Node)),
4456 RTE (RE_Record_Controller));
4457 Set_Etype (RC_Offset_Node, RTE (RE_Storage_Offset));
4458 end if;
4460 Append_To (TSD_Aggr_List, RC_Offset_Node);
4461 end;
4463 -- Size_Func
4465 if RTE_Record_Component_Available (RE_Size_Func) then
4466 if not Building_Static_DT (Typ)
4467 or else Is_Interface (Typ)
4468 then
4469 Append_To (TSD_Aggr_List,
4470 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4471 New_Reference_To (RTE (RE_Null_Address), Loc)));
4473 else
4474 declare
4475 Prim_Elmt : Elmt_Id;
4476 Prim : Entity_Id;
4478 begin
4479 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4480 while Present (Prim_Elmt) loop
4481 Prim := Node (Prim_Elmt);
4483 if Chars (Prim) = Name_uSize then
4484 while Present (Alias (Prim)) loop
4485 Prim := Alias (Prim);
4486 end loop;
4488 if Is_Abstract_Subprogram (Prim) then
4489 Append_To (TSD_Aggr_List,
4490 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4491 New_Reference_To (RTE (RE_Null_Address), Loc)));
4492 else
4493 Append_To (TSD_Aggr_List,
4494 Unchecked_Convert_To (RTE (RE_Size_Ptr),
4495 Make_Attribute_Reference (Loc,
4496 Prefix => New_Reference_To (Prim, Loc),
4497 Attribute_Name => Name_Unrestricted_Access)));
4498 end if;
4500 exit;
4501 end if;
4503 Next_Elmt (Prim_Elmt);
4504 end loop;
4505 end;
4506 end if;
4507 end if;
4509 -- Interfaces_Table (required for AI-405)
4511 if RTE_Record_Component_Available (RE_Interfaces_Table) then
4513 -- Count the number of interface types implemented by Typ
4515 Collect_Interfaces (Typ, Typ_Ifaces);
4517 AI := First_Elmt (Typ_Ifaces);
4518 while Present (AI) loop
4519 Num_Ifaces := Num_Ifaces + 1;
4520 Next_Elmt (AI);
4521 end loop;
4523 if Num_Ifaces = 0 then
4524 Iface_Table_Node := Make_Null (Loc);
4526 -- Generate the Interface_Table object
4528 else
4529 declare
4530 TSD_Ifaces_List : constant List_Id := New_List;
4531 Elmt : Elmt_Id;
4532 Sec_DT_Tag : Node_Id;
4534 begin
4535 AI := First_Elmt (Typ_Ifaces);
4536 while Present (AI) loop
4537 if Is_Ancestor (Node (AI), Typ) then
4538 Sec_DT_Tag :=
4539 New_Reference_To (DT_Ptr, Loc);
4540 else
4541 Elmt :=
4542 Next_Elmt
4543 (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
4544 pragma Assert (Has_Thunks (Node (Elmt)));
4546 while Ekind (Node (Elmt)) = E_Constant
4547 and then not
4548 Is_Ancestor (Node (AI), Related_Type (Node (Elmt)))
4549 loop
4550 pragma Assert (Has_Thunks (Node (Elmt)));
4551 Next_Elmt (Elmt);
4552 pragma Assert (Has_Thunks (Node (Elmt)));
4553 Next_Elmt (Elmt);
4554 pragma Assert (not Has_Thunks (Node (Elmt)));
4555 Next_Elmt (Elmt);
4556 pragma Assert (not Has_Thunks (Node (Elmt)));
4557 Next_Elmt (Elmt);
4558 end loop;
4560 pragma Assert (Ekind (Node (Elmt)) = E_Constant
4561 and then not
4562 Has_Thunks (Node (Next_Elmt (Next_Elmt (Elmt)))));
4563 Sec_DT_Tag :=
4564 New_Reference_To (Node (Next_Elmt (Next_Elmt (Elmt))),
4565 Loc);
4566 end if;
4568 Append_To (TSD_Ifaces_List,
4569 Make_Aggregate (Loc,
4570 Expressions => New_List (
4572 -- Iface_Tag
4574 Unchecked_Convert_To (RTE (RE_Tag),
4575 New_Reference_To
4576 (Node (First_Elmt (Access_Disp_Table (Node (AI)))),
4577 Loc)),
4579 -- Static_Offset_To_Top
4581 New_Reference_To (Standard_True, Loc),
4583 -- Offset_To_Top_Value
4585 Make_Integer_Literal (Loc, 0),
4587 -- Offset_To_Top_Func
4589 Make_Null (Loc),
4591 -- Secondary_DT
4593 Unchecked_Convert_To (RTE (RE_Tag), Sec_DT_Tag)
4595 )));
4597 Next_Elmt (AI);
4598 end loop;
4600 Name_ITable := New_External_Name (Tname, 'I');
4601 ITable := Make_Defining_Identifier (Loc, Name_ITable);
4602 Set_Is_Statically_Allocated (ITable,
4603 Is_Library_Level_Tagged_Type (Typ));
4605 -- The table of interfaces is not constant; its slots are
4606 -- filled at run-time by the IP routine using attribute
4607 -- 'Position to know the location of the tag components
4608 -- (and this attribute cannot be safely used before the
4609 -- object is initialized).
4611 Append_To (Result,
4612 Make_Object_Declaration (Loc,
4613 Defining_Identifier => ITable,
4614 Aliased_Present => True,
4615 Constant_Present => False,
4616 Object_Definition =>
4617 Make_Subtype_Indication (Loc,
4618 Subtype_Mark =>
4619 New_Reference_To (RTE (RE_Interface_Data), Loc),
4620 Constraint => Make_Index_Or_Discriminant_Constraint
4621 (Loc,
4622 Constraints => New_List (
4623 Make_Integer_Literal (Loc, Num_Ifaces)))),
4625 Expression => Make_Aggregate (Loc,
4626 Expressions => New_List (
4627 Make_Integer_Literal (Loc, Num_Ifaces),
4628 Make_Aggregate (Loc,
4629 Expressions => TSD_Ifaces_List)))));
4631 Append_To (Result,
4632 Make_Attribute_Definition_Clause (Loc,
4633 Name => New_Reference_To (ITable, Loc),
4634 Chars => Name_Alignment,
4635 Expression =>
4636 Make_Attribute_Reference (Loc,
4637 Prefix =>
4638 New_Reference_To (RTE (RE_Integer_Address), Loc),
4639 Attribute_Name => Name_Alignment)));
4641 Iface_Table_Node :=
4642 Make_Attribute_Reference (Loc,
4643 Prefix => New_Reference_To (ITable, Loc),
4644 Attribute_Name => Name_Unchecked_Access);
4645 end;
4646 end if;
4648 Append_To (TSD_Aggr_List, Iface_Table_Node);
4649 end if;
4651 -- Generate the Select Specific Data table for synchronized types that
4652 -- implement synchronized interfaces. The size of the table is
4653 -- constrained by the number of non-predefined primitive operations.
4655 if RTE_Record_Component_Available (RE_SSD) then
4656 if Ada_Version >= Ada_05
4657 and then Has_DT (Typ)
4658 and then Is_Concurrent_Record_Type (Typ)
4659 and then Has_Interfaces (Typ)
4660 and then Nb_Prim > 0
4661 and then not Is_Abstract_Type (Typ)
4662 and then not Is_Controlled (Typ)
4663 and then not Restriction_Active (No_Dispatching_Calls)
4664 then
4665 Append_To (Result,
4666 Make_Object_Declaration (Loc,
4667 Defining_Identifier => SSD,
4668 Aliased_Present => True,
4669 Object_Definition =>
4670 Make_Subtype_Indication (Loc,
4671 Subtype_Mark => New_Reference_To (
4672 RTE (RE_Select_Specific_Data), Loc),
4673 Constraint =>
4674 Make_Index_Or_Discriminant_Constraint (Loc,
4675 Constraints => New_List (
4676 Make_Integer_Literal (Loc, Nb_Prim))))));
4678 Append_To (Result,
4679 Make_Attribute_Definition_Clause (Loc,
4680 Name => New_Reference_To (SSD, Loc),
4681 Chars => Name_Alignment,
4682 Expression =>
4683 Make_Attribute_Reference (Loc,
4684 Prefix =>
4685 New_Reference_To (RTE (RE_Integer_Address), Loc),
4686 Attribute_Name => Name_Alignment)));
4688 -- This table is initialized by Make_Select_Specific_Data_Table,
4689 -- which calls Set_Entry_Index and Set_Prim_Op_Kind.
4691 Append_To (TSD_Aggr_List,
4692 Make_Attribute_Reference (Loc,
4693 Prefix => New_Reference_To (SSD, Loc),
4694 Attribute_Name => Name_Unchecked_Access));
4695 else
4696 Append_To (TSD_Aggr_List, Make_Null (Loc));
4697 end if;
4698 end if;
4700 -- Initialize the table of ancestor tags. In case of interface types
4701 -- this table is not needed.
4703 TSD_Tags_List := New_List;
4705 -- If we are not statically allocating the dispatch table then we must
4706 -- fill position 0 with null because we still have not generated the
4707 -- tag of Typ.
4709 if not Building_Static_DT (Typ)
4710 or else Is_Interface (Typ)
4711 then
4712 Append_To (TSD_Tags_List,
4713 Unchecked_Convert_To (RTE (RE_Tag),
4714 New_Reference_To (RTE (RE_Null_Address), Loc)));
4716 -- Otherwise we can safely reference the tag
4718 else
4719 Append_To (TSD_Tags_List,
4720 New_Reference_To (DT_Ptr, Loc));
4721 end if;
4723 -- Fill the rest of the table with the tags of the ancestors
4725 declare
4726 Current_Typ : Entity_Id;
4727 Parent_Typ : Entity_Id;
4728 Pos : Nat;
4730 begin
4731 Pos := 1;
4732 Current_Typ := Typ;
4734 loop
4735 Parent_Typ := Etype (Current_Typ);
4737 if Is_Private_Type (Parent_Typ) then
4738 Parent_Typ := Full_View (Base_Type (Parent_Typ));
4739 end if;
4741 exit when Parent_Typ = Current_Typ;
4743 if Is_CPP_Class (Parent_Typ)
4744 or else Is_Interface (Typ)
4745 then
4746 -- The tags defined in the C++ side will be inherited when
4747 -- the object is constructed (Exp_Ch3.Build_Init_Procedure)
4749 Append_To (TSD_Tags_List,
4750 Unchecked_Convert_To (RTE (RE_Tag),
4751 New_Reference_To (RTE (RE_Null_Address), Loc)));
4752 else
4753 Append_To (TSD_Tags_List,
4754 New_Reference_To
4755 (Node (First_Elmt (Access_Disp_Table (Parent_Typ))),
4756 Loc));
4757 end if;
4759 Pos := Pos + 1;
4760 Current_Typ := Parent_Typ;
4761 end loop;
4763 pragma Assert (Pos = I_Depth + 1);
4764 end;
4766 Append_To (TSD_Aggr_List,
4767 Make_Aggregate (Loc,
4768 Expressions => TSD_Tags_List));
4770 -- Build the TSD object
4772 Append_To (Result,
4773 Make_Object_Declaration (Loc,
4774 Defining_Identifier => TSD,
4775 Aliased_Present => True,
4776 Constant_Present => Building_Static_DT (Typ),
4777 Object_Definition =>
4778 Make_Subtype_Indication (Loc,
4779 Subtype_Mark => New_Reference_To (
4780 RTE (RE_Type_Specific_Data), Loc),
4781 Constraint =>
4782 Make_Index_Or_Discriminant_Constraint (Loc,
4783 Constraints => New_List (
4784 Make_Integer_Literal (Loc, I_Depth)))),
4786 Expression => Make_Aggregate (Loc,
4787 Expressions => TSD_Aggr_List)));
4789 Set_Is_True_Constant (TSD, Building_Static_DT (Typ));
4791 Append_To (Result,
4792 Make_Attribute_Definition_Clause (Loc,
4793 Name => New_Reference_To (TSD, Loc),
4794 Chars => Name_Alignment,
4795 Expression =>
4796 Make_Attribute_Reference (Loc,
4797 Prefix => New_Reference_To (RTE (RE_Integer_Address), Loc),
4798 Attribute_Name => Name_Alignment)));
4800 -- Initialize or declare the dispatch table object
4802 if not Has_DT (Typ) then
4803 DT_Constr_List := New_List;
4804 DT_Aggr_List := New_List;
4806 -- Typeinfo
4808 New_Node :=
4809 Make_Attribute_Reference (Loc,
4810 Prefix => New_Reference_To (TSD, Loc),
4811 Attribute_Name => Name_Address);
4813 Append_To (DT_Constr_List, New_Node);
4814 Append_To (DT_Aggr_List, New_Copy (New_Node));
4815 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
4817 -- In case of locally defined tagged types we have already declared
4818 -- and uninitialized object for the dispatch table, which is now
4819 -- initialized by means of the following assignment:
4821 -- DT := (TSD'Address, 0);
4823 if not Building_Static_DT (Typ) then
4824 Append_To (Result,
4825 Make_Assignment_Statement (Loc,
4826 Name => New_Reference_To (DT, Loc),
4827 Expression => Make_Aggregate (Loc,
4828 Expressions => DT_Aggr_List)));
4830 -- In case of library level tagged types we declare and export now
4831 -- the constant object containing the dummy dispatch table. There
4832 -- is no need to declare the tag here because it has been previously
4833 -- declared by Make_Tags
4835 -- DT : aliased constant No_Dispatch_Table :=
4836 -- (NDT_TSD => TSD'Address;
4837 -- NDT_Prims_Ptr => 0);
4838 -- for DT'Alignment use Address'Alignment;
4840 else
4841 Append_To (Result,
4842 Make_Object_Declaration (Loc,
4843 Defining_Identifier => DT,
4844 Aliased_Present => True,
4845 Constant_Present => True,
4846 Object_Definition =>
4847 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc),
4848 Expression => Make_Aggregate (Loc,
4849 Expressions => DT_Aggr_List)));
4851 Append_To (Result,
4852 Make_Attribute_Definition_Clause (Loc,
4853 Name => New_Reference_To (DT, Loc),
4854 Chars => Name_Alignment,
4855 Expression =>
4856 Make_Attribute_Reference (Loc,
4857 Prefix =>
4858 New_Reference_To (RTE (RE_Integer_Address), Loc),
4859 Attribute_Name => Name_Alignment)));
4861 Export_DT (Typ, DT);
4862 end if;
4864 -- Common case: Typ has a dispatch table
4866 -- Generate:
4868 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
4869 -- (predef-prim-op-1'address,
4870 -- predef-prim-op-2'address,
4871 -- ...
4872 -- predef-prim-op-n'address);
4873 -- for Predef_Prims'Alignment use Address'Alignment
4875 -- DT : Dispatch_Table (Nb_Prims) :=
4876 -- (Signature => <sig-value>,
4877 -- Tag_Kind => <tag_kind-value>,
4878 -- Predef_Prims => Predef_Prims'First'Address,
4879 -- Offset_To_Top => 0,
4880 -- TSD => TSD'Address;
4881 -- Prims_Ptr => (prim-op-1'address,
4882 -- prim-op-2'address,
4883 -- ...
4884 -- prim-op-n'address));
4885 -- for DT'Alignment use Address'Alignment
4887 else
4888 declare
4889 Pos : Nat;
4891 begin
4892 if not Building_Static_DT (Typ) then
4893 Nb_Predef_Prims := Max_Predef_Prims;
4895 else
4896 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4897 while Present (Prim_Elmt) loop
4898 Prim := Node (Prim_Elmt);
4900 if Is_Predefined_Dispatching_Operation (Prim)
4901 and then not Is_Abstract_Subprogram (Prim)
4902 then
4903 Pos := UI_To_Int (DT_Position (Prim));
4905 if Pos > Nb_Predef_Prims then
4906 Nb_Predef_Prims := Pos;
4907 end if;
4908 end if;
4910 Next_Elmt (Prim_Elmt);
4911 end loop;
4912 end if;
4914 declare
4915 Prim_Table : array
4916 (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
4917 Decl : Node_Id;
4918 E : Entity_Id;
4920 begin
4921 Prim_Ops_Aggr_List := New_List;
4923 Prim_Table := (others => Empty);
4925 if Building_Static_DT (Typ) then
4926 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4927 while Present (Prim_Elmt) loop
4928 Prim := Node (Prim_Elmt);
4930 if Is_Predefined_Dispatching_Operation (Prim)
4931 and then not Is_Abstract_Subprogram (Prim)
4932 and then not Present (Prim_Table
4933 (UI_To_Int (DT_Position (Prim))))
4934 then
4935 E := Prim;
4936 while Present (Alias (E)) loop
4937 E := Alias (E);
4938 end loop;
4940 pragma Assert (not Is_Abstract_Subprogram (E));
4941 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
4942 end if;
4944 Next_Elmt (Prim_Elmt);
4945 end loop;
4946 end if;
4948 for J in Prim_Table'Range loop
4949 if Present (Prim_Table (J)) then
4950 New_Node :=
4951 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
4952 Make_Attribute_Reference (Loc,
4953 Prefix => New_Reference_To (Prim_Table (J), Loc),
4954 Attribute_Name => Name_Unrestricted_Access));
4955 else
4956 New_Node := Make_Null (Loc);
4957 end if;
4959 Append_To (Prim_Ops_Aggr_List, New_Node);
4960 end loop;
4962 New_Node :=
4963 Make_Aggregate (Loc,
4964 Expressions => Prim_Ops_Aggr_List);
4966 Decl :=
4967 Make_Subtype_Declaration (Loc,
4968 Defining_Identifier =>
4969 Make_Defining_Identifier (Loc,
4970 New_Internal_Name ('S')),
4971 Subtype_Indication =>
4972 New_Reference_To (RTE (RE_Address_Array), Loc));
4974 Append_To (Result, Decl);
4976 Append_To (Result,
4977 Make_Object_Declaration (Loc,
4978 Defining_Identifier => Predef_Prims,
4979 Aliased_Present => True,
4980 Constant_Present => Building_Static_DT (Typ),
4981 Object_Definition => New_Reference_To
4982 (Defining_Identifier (Decl), Loc),
4983 Expression => New_Node));
4985 -- Remember aggregates initializing dispatch tables
4987 Append_Elmt (New_Node, DT_Aggr);
4989 Append_To (Result,
4990 Make_Attribute_Definition_Clause (Loc,
4991 Name => New_Reference_To (Predef_Prims, Loc),
4992 Chars => Name_Alignment,
4993 Expression =>
4994 Make_Attribute_Reference (Loc,
4995 Prefix =>
4996 New_Reference_To (RTE (RE_Integer_Address), Loc),
4997 Attribute_Name => Name_Alignment)));
4998 end;
4999 end;
5001 -- Stage 1: Initialize the discriminant and the record components
5003 DT_Constr_List := New_List;
5004 DT_Aggr_List := New_List;
5006 -- Num_Prims. If the tagged type has no primitives we add a dummy
5007 -- slot whose address will be the tag of this type.
5009 if Nb_Prim = 0 then
5010 New_Node := Make_Integer_Literal (Loc, 1);
5011 else
5012 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
5013 end if;
5015 Append_To (DT_Constr_List, New_Node);
5016 Append_To (DT_Aggr_List, New_Copy (New_Node));
5018 -- Signature
5020 if RTE_Record_Component_Available (RE_Signature) then
5021 Append_To (DT_Aggr_List,
5022 New_Reference_To (RTE (RE_Primary_DT), Loc));
5023 end if;
5025 -- Tag_Kind
5027 if RTE_Record_Component_Available (RE_Tag_Kind) then
5028 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
5029 end if;
5031 -- Predef_Prims
5033 Append_To (DT_Aggr_List,
5034 Make_Attribute_Reference (Loc,
5035 Prefix => New_Reference_To (Predef_Prims, Loc),
5036 Attribute_Name => Name_Address));
5038 -- Offset_To_Top
5040 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
5042 -- Typeinfo
5044 Append_To (DT_Aggr_List,
5045 Make_Attribute_Reference (Loc,
5046 Prefix => New_Reference_To (TSD, Loc),
5047 Attribute_Name => Name_Address));
5049 -- Stage 2: Initialize the table of primitive operations
5051 Prim_Ops_Aggr_List := New_List;
5053 if Nb_Prim = 0 then
5054 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
5056 elsif not Building_Static_DT (Typ) then
5057 for J in 1 .. Nb_Prim loop
5058 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
5059 end loop;
5061 else
5062 declare
5063 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
5064 E : Entity_Id;
5065 Prim : Entity_Id;
5066 Prim_Elmt : Elmt_Id;
5068 begin
5069 Prim_Table := (others => Empty);
5071 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5072 while Present (Prim_Elmt) loop
5073 Prim := Node (Prim_Elmt);
5075 if Is_Imported (Prim)
5076 or else Present (Interface_Alias (Prim))
5077 or else Is_Predefined_Dispatching_Operation (Prim)
5078 then
5079 null;
5081 else
5082 -- Traverse the list of aliased entities to handle
5083 -- renamings of predefined primitives.
5085 E := Prim;
5086 while Present (Alias (E)) loop
5087 E := Alias (E);
5088 end loop;
5090 if not Is_Predefined_Dispatching_Operation (E)
5091 and then not Is_Abstract_Subprogram (E)
5092 and then not Present (Interface_Alias (E))
5093 then
5094 pragma Assert
5095 (UI_To_Int (DT_Position (Prim)) <= Nb_Prim);
5097 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
5098 end if;
5099 end if;
5101 Next_Elmt (Prim_Elmt);
5102 end loop;
5104 for J in Prim_Table'Range loop
5105 if Present (Prim_Table (J)) then
5106 New_Node :=
5107 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
5108 Make_Attribute_Reference (Loc,
5109 Prefix => New_Reference_To (Prim_Table (J), Loc),
5110 Attribute_Name => Name_Unrestricted_Access));
5111 else
5112 New_Node := Make_Null (Loc);
5113 end if;
5115 Append_To (Prim_Ops_Aggr_List, New_Node);
5116 end loop;
5117 end;
5118 end if;
5120 New_Node :=
5121 Make_Aggregate (Loc,
5122 Expressions => Prim_Ops_Aggr_List);
5124 Append_To (DT_Aggr_List, New_Node);
5126 -- Remember aggregates initializing dispatch tables
5128 Append_Elmt (New_Node, DT_Aggr);
5130 -- In case of locally defined tagged types we have already declared
5131 -- and uninitialized object for the dispatch table, which is now
5132 -- initialized by means of an assignment.
5134 if not Building_Static_DT (Typ) then
5135 Append_To (Result,
5136 Make_Assignment_Statement (Loc,
5137 Name => New_Reference_To (DT, Loc),
5138 Expression => Make_Aggregate (Loc,
5139 Expressions => DT_Aggr_List)));
5141 -- In case of library level tagged types we declare now and export
5142 -- the constant object containing the dispatch table.
5144 else
5145 Append_To (Result,
5146 Make_Object_Declaration (Loc,
5147 Defining_Identifier => DT,
5148 Aliased_Present => True,
5149 Constant_Present => True,
5150 Object_Definition =>
5151 Make_Subtype_Indication (Loc,
5152 Subtype_Mark => New_Reference_To
5153 (RTE (RE_Dispatch_Table_Wrapper), Loc),
5154 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
5155 Constraints => DT_Constr_List)),
5156 Expression => Make_Aggregate (Loc,
5157 Expressions => DT_Aggr_List)));
5159 Append_To (Result,
5160 Make_Attribute_Definition_Clause (Loc,
5161 Name => New_Reference_To (DT, Loc),
5162 Chars => Name_Alignment,
5163 Expression =>
5164 Make_Attribute_Reference (Loc,
5165 Prefix =>
5166 New_Reference_To (RTE (RE_Integer_Address), Loc),
5167 Attribute_Name => Name_Alignment)));
5169 Export_DT (Typ, DT);
5170 end if;
5171 end if;
5173 -- Initialize the table of ancestor tags
5175 if not Building_Static_DT (Typ)
5176 and then not Is_Interface (Typ)
5177 and then not Is_CPP_Class (Typ)
5178 then
5179 Append_To (Result,
5180 Make_Assignment_Statement (Loc,
5181 Name =>
5182 Make_Indexed_Component (Loc,
5183 Prefix =>
5184 Make_Selected_Component (Loc,
5185 Prefix =>
5186 New_Reference_To (TSD, Loc),
5187 Selector_Name =>
5188 New_Reference_To
5189 (RTE_Record_Component (RE_Tags_Table), Loc)),
5190 Expressions =>
5191 New_List (Make_Integer_Literal (Loc, 0))),
5193 Expression =>
5194 New_Reference_To
5195 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)));
5196 end if;
5198 -- Inherit the dispatch tables of the parent
5200 -- There is no need to inherit anything from the parent when building
5201 -- static dispatch tables because the whole dispatch table (including
5202 -- inherited primitives) has been already built.
5204 if Building_Static_DT (Typ) then
5205 null;
5207 -- If the ancestor is a CPP_Class type we inherit the dispatch tables
5208 -- in the init proc, and we don't need to fill them in here.
5210 elsif Is_CPP_Class (Parent_Typ) then
5211 null;
5213 -- Otherwise we fill in the dispatch tables here
5215 else
5216 if Typ /= Parent_Typ
5217 and then not Is_Interface (Typ)
5218 and then not Restriction_Active (No_Dispatching_Calls)
5219 then
5220 -- Inherit the dispatch table
5222 if not Is_Interface (Typ)
5223 and then not Is_Interface (Parent_Typ)
5224 and then not Is_CPP_Class (Parent_Typ)
5225 then
5226 declare
5227 Nb_Prims : constant Int :=
5228 UI_To_Int (DT_Entry_Count
5229 (First_Tag_Component (Parent_Typ)));
5231 begin
5232 Append_To (Elab_Code,
5233 Build_Inherit_Predefined_Prims (Loc,
5234 Old_Tag_Node =>
5235 New_Reference_To
5236 (Node
5237 (Next_Elmt
5238 (First_Elmt
5239 (Access_Disp_Table (Parent_Typ)))), Loc),
5240 New_Tag_Node =>
5241 New_Reference_To
5242 (Node
5243 (Next_Elmt
5244 (First_Elmt
5245 (Access_Disp_Table (Typ)))), Loc)));
5247 if Nb_Prims /= 0 then
5248 Append_To (Elab_Code,
5249 Build_Inherit_Prims (Loc,
5250 Typ => Typ,
5251 Old_Tag_Node =>
5252 New_Reference_To
5253 (Node
5254 (First_Elmt
5255 (Access_Disp_Table (Parent_Typ))), Loc),
5256 New_Tag_Node => New_Reference_To (DT_Ptr, Loc),
5257 Num_Prims => Nb_Prims));
5258 end if;
5259 end;
5260 end if;
5262 -- Inherit the secondary dispatch tables of the ancestor
5264 if not Is_CPP_Class (Parent_Typ) then
5265 declare
5266 Sec_DT_Ancestor : Elmt_Id :=
5267 Next_Elmt
5268 (Next_Elmt
5269 (First_Elmt
5270 (Access_Disp_Table (Parent_Typ))));
5271 Sec_DT_Typ : Elmt_Id :=
5272 Next_Elmt
5273 (Next_Elmt
5274 (First_Elmt
5275 (Access_Disp_Table (Typ))));
5277 procedure Copy_Secondary_DTs (Typ : Entity_Id);
5278 -- Local procedure required to climb through the ancestors
5279 -- and copy the contents of all their secondary dispatch
5280 -- tables.
5282 ------------------------
5283 -- Copy_Secondary_DTs --
5284 ------------------------
5286 procedure Copy_Secondary_DTs (Typ : Entity_Id) is
5287 E : Entity_Id;
5288 Iface : Elmt_Id;
5290 begin
5291 -- Climb to the ancestor (if any) handling private types
5293 if Present (Full_View (Etype (Typ))) then
5294 if Full_View (Etype (Typ)) /= Typ then
5295 Copy_Secondary_DTs (Full_View (Etype (Typ)));
5296 end if;
5298 elsif Etype (Typ) /= Typ then
5299 Copy_Secondary_DTs (Etype (Typ));
5300 end if;
5302 if Present (Interfaces (Typ))
5303 and then not Is_Empty_Elmt_List (Interfaces (Typ))
5304 then
5305 Iface := First_Elmt (Interfaces (Typ));
5306 E := First_Entity (Typ);
5307 while Present (E)
5308 and then Present (Node (Sec_DT_Ancestor))
5309 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
5310 loop
5311 if Is_Tag (E) and then Chars (E) /= Name_uTag then
5312 declare
5313 Num_Prims : constant Int :=
5314 UI_To_Int (DT_Entry_Count (E));
5316 begin
5317 if not Is_Interface (Etype (Typ)) then
5319 -- Inherit first secondary dispatch table
5321 Append_To (Elab_Code,
5322 Build_Inherit_Predefined_Prims (Loc,
5323 Old_Tag_Node =>
5324 Unchecked_Convert_To (RTE (RE_Tag),
5325 New_Reference_To
5326 (Node
5327 (Next_Elmt (Sec_DT_Ancestor)),
5328 Loc)),
5329 New_Tag_Node =>
5330 Unchecked_Convert_To (RTE (RE_Tag),
5331 New_Reference_To
5332 (Node (Next_Elmt (Sec_DT_Typ)),
5333 Loc))));
5335 if Num_Prims /= 0 then
5336 Append_To (Elab_Code,
5337 Build_Inherit_Prims (Loc,
5338 Typ => Node (Iface),
5339 Old_Tag_Node =>
5340 Unchecked_Convert_To
5341 (RTE (RE_Tag),
5342 New_Reference_To
5343 (Node (Sec_DT_Ancestor),
5344 Loc)),
5345 New_Tag_Node =>
5346 Unchecked_Convert_To
5347 (RTE (RE_Tag),
5348 New_Reference_To
5349 (Node (Sec_DT_Typ), Loc)),
5350 Num_Prims => Num_Prims));
5351 end if;
5352 end if;
5354 Next_Elmt (Sec_DT_Ancestor);
5355 Next_Elmt (Sec_DT_Typ);
5357 -- Skip the secondary dispatch table of
5358 -- predefined primitives
5360 Next_Elmt (Sec_DT_Ancestor);
5361 Next_Elmt (Sec_DT_Typ);
5363 if not Is_Interface (Etype (Typ)) then
5365 -- Inherit second secondary dispatch table
5367 Append_To (Elab_Code,
5368 Build_Inherit_Predefined_Prims (Loc,
5369 Old_Tag_Node =>
5370 Unchecked_Convert_To (RTE (RE_Tag),
5371 New_Reference_To
5372 (Node
5373 (Next_Elmt (Sec_DT_Ancestor)),
5374 Loc)),
5375 New_Tag_Node =>
5376 Unchecked_Convert_To (RTE (RE_Tag),
5377 New_Reference_To
5378 (Node (Next_Elmt (Sec_DT_Typ)),
5379 Loc))));
5381 if Num_Prims /= 0 then
5382 Append_To (Elab_Code,
5383 Build_Inherit_Prims (Loc,
5384 Typ => Node (Iface),
5385 Old_Tag_Node =>
5386 Unchecked_Convert_To
5387 (RTE (RE_Tag),
5388 New_Reference_To
5389 (Node (Sec_DT_Ancestor),
5390 Loc)),
5391 New_Tag_Node =>
5392 Unchecked_Convert_To
5393 (RTE (RE_Tag),
5394 New_Reference_To
5395 (Node (Sec_DT_Typ), Loc)),
5396 Num_Prims => Num_Prims));
5397 end if;
5398 end if;
5399 end;
5401 Next_Elmt (Sec_DT_Ancestor);
5402 Next_Elmt (Sec_DT_Typ);
5404 -- Skip the secondary dispatch table of
5405 -- predefined primitives
5407 Next_Elmt (Sec_DT_Ancestor);
5408 Next_Elmt (Sec_DT_Typ);
5410 Next_Elmt (Iface);
5411 end if;
5413 Next_Entity (E);
5414 end loop;
5415 end if;
5416 end Copy_Secondary_DTs;
5418 begin
5419 if Present (Node (Sec_DT_Ancestor))
5420 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
5421 then
5422 -- Handle private types
5424 if Present (Full_View (Typ)) then
5425 Copy_Secondary_DTs (Full_View (Typ));
5426 else
5427 Copy_Secondary_DTs (Typ);
5428 end if;
5429 end if;
5430 end;
5431 end if;
5432 end if;
5433 end if;
5435 -- Generate code to register the Tag in the External_Tag hash table for
5436 -- the pure Ada type only.
5438 -- Register_Tag (Dt_Ptr);
5440 -- Skip this action in the following cases:
5441 -- 1) if Register_Tag is not available.
5442 -- 2) in No_Run_Time mode.
5443 -- 3) if Typ is not defined at the library level (this is required
5444 -- to avoid adding concurrency control to the hash table used
5445 -- by the run-time to register the tags).
5447 if not No_Run_Time_Mode
5448 and then Is_Library_Level_Entity (Typ)
5449 and then RTE_Available (RE_Register_Tag)
5450 then
5451 Append_To (Elab_Code,
5452 Make_Procedure_Call_Statement (Loc,
5453 Name => New_Reference_To (RTE (RE_Register_Tag), Loc),
5454 Parameter_Associations =>
5455 New_List (New_Reference_To (DT_Ptr, Loc))));
5456 end if;
5458 if not Is_Empty_List (Elab_Code) then
5459 Append_List_To (Result, Elab_Code);
5460 end if;
5462 -- Populate the two auxiliary tables used for dispatching
5463 -- asynchronous, conditional and timed selects for synchronized
5464 -- types that implement a limited interface.
5466 if Ada_Version >= Ada_05
5467 and then Is_Concurrent_Record_Type (Typ)
5468 and then Has_Interfaces (Typ)
5469 then
5470 Append_List_To (Result,
5471 Make_Select_Specific_Data_Table (Typ));
5472 end if;
5474 -- Remember entities containing dispatch tables
5476 Append_Elmt (Predef_Prims, DT_Decl);
5477 Append_Elmt (DT, DT_Decl);
5479 Analyze_List (Result, Suppress => All_Checks);
5480 Set_Has_Dispatch_Table (Typ);
5482 -- Mark entities containing dispatch tables. Required by the
5483 -- backend to handle them properly.
5485 if not Is_Interface (Typ) then
5486 declare
5487 Elmt : Elmt_Id;
5489 begin
5490 -- Ensure that entities Prim_Ptr and Predef_Prims_Table_Ptr have
5491 -- the decoration required by the backend
5493 Set_Is_Dispatch_Table_Entity (RTE (RE_Prim_Ptr));
5494 Set_Is_Dispatch_Table_Entity (RTE (RE_Predef_Prims_Table_Ptr));
5496 -- Object declarations
5498 Elmt := First_Elmt (DT_Decl);
5499 while Present (Elmt) loop
5500 Set_Is_Dispatch_Table_Entity (Node (Elmt));
5501 pragma Assert (Ekind (Etype (Node (Elmt))) = E_Array_Subtype
5502 or else Ekind (Etype (Node (Elmt))) = E_Record_Subtype);
5503 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
5504 Next_Elmt (Elmt);
5505 end loop;
5507 -- Aggregates initializing dispatch tables
5509 Elmt := First_Elmt (DT_Aggr);
5510 while Present (Elmt) loop
5511 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
5512 Next_Elmt (Elmt);
5513 end loop;
5514 end;
5515 end if;
5517 return Result;
5518 end Make_DT;
5520 -------------------------------------
5521 -- Make_Select_Specific_Data_Table --
5522 -------------------------------------
5524 function Make_Select_Specific_Data_Table
5525 (Typ : Entity_Id) return List_Id
5527 Assignments : constant List_Id := New_List;
5528 Loc : constant Source_Ptr := Sloc (Typ);
5530 Conc_Typ : Entity_Id;
5531 Decls : List_Id;
5532 DT_Ptr : Entity_Id;
5533 Prim : Entity_Id;
5534 Prim_Als : Entity_Id;
5535 Prim_Elmt : Elmt_Id;
5536 Prim_Pos : Uint;
5537 Nb_Prim : Nat := 0;
5539 type Examined_Array is array (Int range <>) of Boolean;
5541 function Find_Entry_Index (E : Entity_Id) return Uint;
5542 -- Given an entry, find its index in the visible declarations of the
5543 -- corresponding concurrent type of Typ.
5545 ----------------------
5546 -- Find_Entry_Index --
5547 ----------------------
5549 function Find_Entry_Index (E : Entity_Id) return Uint is
5550 Index : Uint := Uint_1;
5551 Subp_Decl : Entity_Id;
5553 begin
5554 if Present (Decls)
5555 and then not Is_Empty_List (Decls)
5556 then
5557 Subp_Decl := First (Decls);
5558 while Present (Subp_Decl) loop
5559 if Nkind (Subp_Decl) = N_Entry_Declaration then
5560 if Defining_Identifier (Subp_Decl) = E then
5561 return Index;
5562 end if;
5564 Index := Index + 1;
5565 end if;
5567 Next (Subp_Decl);
5568 end loop;
5569 end if;
5571 return Uint_0;
5572 end Find_Entry_Index;
5574 -- Start of processing for Make_Select_Specific_Data_Table
5576 begin
5577 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
5579 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
5581 if Present (Corresponding_Concurrent_Type (Typ)) then
5582 Conc_Typ := Corresponding_Concurrent_Type (Typ);
5584 if Present (Full_View (Conc_Typ)) then
5585 Conc_Typ := Full_View (Conc_Typ);
5586 end if;
5588 if Ekind (Conc_Typ) = E_Protected_Type then
5589 Decls := Visible_Declarations (Protected_Definition (
5590 Parent (Conc_Typ)));
5591 else
5592 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
5593 Decls := Visible_Declarations (Task_Definition (
5594 Parent (Conc_Typ)));
5595 end if;
5596 end if;
5598 -- Count the non-predefined primitive operations
5600 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5601 while Present (Prim_Elmt) loop
5602 Prim := Node (Prim_Elmt);
5604 if not (Is_Predefined_Dispatching_Operation (Prim)
5605 or else Is_Predefined_Dispatching_Alias (Prim))
5606 then
5607 Nb_Prim := Nb_Prim + 1;
5608 end if;
5610 Next_Elmt (Prim_Elmt);
5611 end loop;
5613 declare
5614 Examined : Examined_Array (1 .. Nb_Prim) := (others => False);
5616 begin
5617 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5618 while Present (Prim_Elmt) loop
5619 Prim := Node (Prim_Elmt);
5621 -- Look for primitive overriding an abstract interface subprogram
5623 if Present (Interface_Alias (Prim))
5624 and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
5625 then
5626 Prim_Pos := DT_Position (Alias (Prim));
5627 pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
5628 Examined (UI_To_Int (Prim_Pos)) := True;
5630 -- Set the primitive operation kind regardless of subprogram
5631 -- type. Generate:
5632 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
5634 Append_To (Assignments,
5635 Make_Procedure_Call_Statement (Loc,
5636 Name => New_Reference_To (RTE (RE_Set_Prim_Op_Kind), Loc),
5637 Parameter_Associations => New_List (
5638 New_Reference_To (DT_Ptr, Loc),
5639 Make_Integer_Literal (Loc, Prim_Pos),
5640 Prim_Op_Kind (Alias (Prim), Typ))));
5642 -- Retrieve the root of the alias chain
5644 Prim_Als := Prim;
5645 while Present (Alias (Prim_Als)) loop
5646 Prim_Als := Alias (Prim_Als);
5647 end loop;
5649 -- In the case of an entry wrapper, set the entry index
5651 if Ekind (Prim) = E_Procedure
5652 and then Is_Primitive_Wrapper (Prim_Als)
5653 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
5654 then
5655 -- Generate:
5656 -- Ada.Tags.Set_Entry_Index
5657 -- (DT_Ptr, <position>, <index>);
5659 Append_To (Assignments,
5660 Make_Procedure_Call_Statement (Loc,
5661 Name =>
5662 New_Reference_To (RTE (RE_Set_Entry_Index), Loc),
5663 Parameter_Associations => New_List (
5664 New_Reference_To (DT_Ptr, Loc),
5665 Make_Integer_Literal (Loc, Prim_Pos),
5666 Make_Integer_Literal (Loc,
5667 Find_Entry_Index (Wrapped_Entity (Prim_Als))))));
5668 end if;
5669 end if;
5671 Next_Elmt (Prim_Elmt);
5672 end loop;
5673 end;
5675 return Assignments;
5676 end Make_Select_Specific_Data_Table;
5678 ---------------
5679 -- Make_Tags --
5680 ---------------
5682 function Make_Tags (Typ : Entity_Id) return List_Id is
5683 Loc : constant Source_Ptr := Sloc (Typ);
5684 Tname : constant Name_Id := Chars (Typ);
5685 Result : constant List_Id := New_List;
5686 AI_Tag_Comp : Elmt_Id;
5687 DT : Node_Id;
5688 DT_Constr_List : List_Id;
5689 DT_Ptr : Node_Id;
5690 Predef_Prims_Ptr : Node_Id;
5691 Iface_DT_Ptr : Node_Id;
5692 Nb_Prim : Nat;
5693 Suffix_Index : Int;
5694 Typ_Name : Name_Id;
5695 Typ_Comps : Elist_Id;
5697 begin
5698 -- 1) Generate the primary and secondary tag entities
5700 -- Collect the components associated with secondary dispatch tables
5702 if Has_Interfaces (Typ) then
5703 Collect_Interface_Components (Typ, Typ_Comps);
5704 end if;
5706 -- 1) Generate the primary tag entities
5708 -- Primary dispatch table containing user-defined primitives
5710 DT_Ptr := Make_Defining_Identifier (Loc,
5711 New_External_Name (Tname, 'P'));
5712 Set_Etype (DT_Ptr, RTE (RE_Tag));
5714 -- Primary dispatch table containing predefined primitives
5716 Predef_Prims_Ptr :=
5717 Make_Defining_Identifier (Loc,
5718 Chars => New_External_Name (Tname, 'Y'));
5719 Set_Etype (Predef_Prims_Ptr, RTE (RE_Address));
5721 -- Import the forward declaration of the Dispatch Table wrapper record
5722 -- (Make_DT will take care of its exportation)
5724 if Building_Static_DT (Typ) then
5725 DT :=
5726 Make_Defining_Identifier (Loc,
5727 Chars => New_External_Name (Tname, 'T'));
5729 -- Generate:
5730 -- DT : static aliased constant Dispatch_Table_Wrapper (Nb_Prim);
5731 -- $pragma import (ada, DT);
5733 Set_Is_Imported (DT);
5735 -- The scope must be set now to call Get_External_Name
5737 Set_Scope (DT, Current_Scope);
5739 Get_External_Name (DT, True);
5740 Set_Interface_Name (DT,
5741 Make_String_Literal (Loc,
5742 Strval => String_From_Name_Buffer));
5744 -- Ensure proper Sprint output of this implicit importation
5746 Set_Is_Internal (DT);
5748 -- Save this entity to allow Make_DT to generate its exportation
5750 Set_Dispatch_Table_Wrapper (Typ, DT);
5752 if Has_DT (Typ) then
5754 -- Calculate the number of primitives of the dispatch table and
5755 -- the size of the Type_Specific_Data record.
5757 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
5759 -- If the tagged type has no primitives we add a dummy slot
5760 -- whose address will be the tag of this type.
5762 if Nb_Prim = 0 then
5763 DT_Constr_List :=
5764 New_List (Make_Integer_Literal (Loc, 1));
5765 else
5766 DT_Constr_List :=
5767 New_List (Make_Integer_Literal (Loc, Nb_Prim));
5768 end if;
5770 Append_To (Result,
5771 Make_Object_Declaration (Loc,
5772 Defining_Identifier => DT,
5773 Aliased_Present => True,
5774 Constant_Present => True,
5775 Object_Definition =>
5776 Make_Subtype_Indication (Loc,
5777 Subtype_Mark =>
5778 New_Reference_To (RTE (RE_Dispatch_Table_Wrapper), Loc),
5779 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
5780 Constraints => DT_Constr_List))));
5782 Append_To (Result,
5783 Make_Object_Declaration (Loc,
5784 Defining_Identifier => DT_Ptr,
5785 Constant_Present => True,
5786 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
5787 Expression =>
5788 Unchecked_Convert_To (RTE (RE_Tag),
5789 Make_Attribute_Reference (Loc,
5790 Prefix =>
5791 Make_Selected_Component (Loc,
5792 Prefix => New_Reference_To (DT, Loc),
5793 Selector_Name =>
5794 New_Occurrence_Of
5795 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
5796 Attribute_Name => Name_Address))));
5798 Append_To (Result,
5799 Make_Object_Declaration (Loc,
5800 Defining_Identifier => Predef_Prims_Ptr,
5801 Constant_Present => True,
5802 Object_Definition => New_Reference_To
5803 (RTE (RE_Address), Loc),
5804 Expression =>
5805 Make_Attribute_Reference (Loc,
5806 Prefix =>
5807 Make_Selected_Component (Loc,
5808 Prefix => New_Reference_To (DT, Loc),
5809 Selector_Name =>
5810 New_Occurrence_Of
5811 (RTE_Record_Component (RE_Predef_Prims), Loc)),
5812 Attribute_Name => Name_Address)));
5814 -- No dispatch table required
5816 else
5817 Append_To (Result,
5818 Make_Object_Declaration (Loc,
5819 Defining_Identifier => DT,
5820 Aliased_Present => True,
5821 Constant_Present => True,
5822 Object_Definition =>
5823 New_Reference_To (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
5825 Append_To (Result,
5826 Make_Object_Declaration (Loc,
5827 Defining_Identifier => DT_Ptr,
5828 Constant_Present => True,
5829 Object_Definition => New_Reference_To (RTE (RE_Tag), Loc),
5830 Expression =>
5831 Unchecked_Convert_To (RTE (RE_Tag),
5832 Make_Attribute_Reference (Loc,
5833 Prefix =>
5834 Make_Selected_Component (Loc,
5835 Prefix => New_Reference_To (DT, Loc),
5836 Selector_Name =>
5837 New_Occurrence_Of
5838 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
5839 Attribute_Name => Name_Address))));
5840 end if;
5842 Set_Is_True_Constant (DT_Ptr);
5843 Set_Is_Statically_Allocated (DT_Ptr);
5844 end if;
5846 pragma Assert (No (Access_Disp_Table (Typ)));
5847 Set_Access_Disp_Table (Typ, New_Elmt_List);
5848 Append_Elmt (DT_Ptr, Access_Disp_Table (Typ));
5849 Append_Elmt (Predef_Prims_Ptr, Access_Disp_Table (Typ));
5851 -- 2) Generate the secondary tag entities
5853 if Has_Interfaces (Typ) then
5854 Suffix_Index := 0;
5856 -- For each interface type we build an unique external name
5857 -- associated with its corresponding secondary dispatch table.
5858 -- This external name will be used to declare an object that
5859 -- references this secondary dispatch table, value that will be
5860 -- used for the elaboration of Typ's objects and also for the
5861 -- elaboration of objects of derivations of Typ that do not
5862 -- override the primitive operation of this interface type.
5864 AI_Tag_Comp := First_Elmt (Typ_Comps);
5865 while Present (AI_Tag_Comp) loop
5866 Get_Secondary_DT_External_Name
5867 (Typ, Related_Type (Node (AI_Tag_Comp)), Suffix_Index);
5869 Typ_Name := Name_Find;
5871 -- Secondary dispatch table referencing thunks to user-defined
5872 -- primitives covered by this interface.
5874 Iface_DT_Ptr :=
5875 Make_Defining_Identifier (Loc,
5876 Chars => New_External_Name (Typ_Name, 'P'));
5877 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
5878 Set_Ekind (Iface_DT_Ptr, E_Constant);
5879 Set_Is_Tag (Iface_DT_Ptr);
5880 Set_Has_Thunks (Iface_DT_Ptr);
5881 Set_Is_Statically_Allocated (Iface_DT_Ptr,
5882 Is_Library_Level_Tagged_Type (Typ));
5883 Set_Is_True_Constant (Iface_DT_Ptr);
5884 Set_Related_Type
5885 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
5886 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
5888 -- Secondary dispatch table referencing thunks to predefined
5889 -- primitives.
5891 Iface_DT_Ptr :=
5892 Make_Defining_Identifier (Loc,
5893 Chars => New_External_Name (Typ_Name, 'Y'));
5894 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
5895 Set_Ekind (Iface_DT_Ptr, E_Constant);
5896 Set_Is_Tag (Iface_DT_Ptr);
5897 Set_Has_Thunks (Iface_DT_Ptr);
5898 Set_Is_Statically_Allocated (Iface_DT_Ptr,
5899 Is_Library_Level_Tagged_Type (Typ));
5900 Set_Is_True_Constant (Iface_DT_Ptr);
5901 Set_Related_Type
5902 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
5903 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
5905 -- Secondary dispatch table referencing user-defined primitives
5906 -- covered by this interface.
5908 Iface_DT_Ptr :=
5909 Make_Defining_Identifier (Loc,
5910 Chars => New_External_Name (Typ_Name, 'D'));
5911 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
5912 Set_Ekind (Iface_DT_Ptr, E_Constant);
5913 Set_Is_Tag (Iface_DT_Ptr);
5914 Set_Is_Statically_Allocated (Iface_DT_Ptr,
5915 Is_Library_Level_Tagged_Type (Typ));
5916 Set_Is_True_Constant (Iface_DT_Ptr);
5917 Set_Related_Type
5918 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
5919 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
5921 -- Secondary dispatch table referencing predefined primitives
5923 Iface_DT_Ptr :=
5924 Make_Defining_Identifier (Loc,
5925 Chars => New_External_Name (Typ_Name, 'Z'));
5926 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
5927 Set_Ekind (Iface_DT_Ptr, E_Constant);
5928 Set_Is_Tag (Iface_DT_Ptr);
5929 Set_Is_Statically_Allocated (Iface_DT_Ptr,
5930 Is_Library_Level_Tagged_Type (Typ));
5931 Set_Is_True_Constant (Iface_DT_Ptr);
5932 Set_Related_Type
5933 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
5934 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
5936 Next_Elmt (AI_Tag_Comp);
5937 end loop;
5938 end if;
5940 -- 3) At the end of Access_Disp_Table we add the entity of an access
5941 -- type declaration. It is used by Build_Get_Prim_Op_Address to
5942 -- expand dispatching calls through the primary dispatch table.
5944 -- Generate:
5945 -- type Typ_DT is array (1 .. Nb_Prims) of Prim_Ptr;
5946 -- type Typ_DT_Acc is access Typ_DT;
5948 declare
5949 Name_DT_Prims : constant Name_Id :=
5950 New_External_Name (Tname, 'G');
5951 Name_DT_Prims_Acc : constant Name_Id :=
5952 New_External_Name (Tname, 'H');
5953 DT_Prims : constant Entity_Id :=
5954 Make_Defining_Identifier (Loc, Name_DT_Prims);
5955 DT_Prims_Acc : constant Entity_Id :=
5956 Make_Defining_Identifier (Loc,
5957 Name_DT_Prims_Acc);
5958 begin
5959 Append_To (Result,
5960 Make_Full_Type_Declaration (Loc,
5961 Defining_Identifier => DT_Prims,
5962 Type_Definition =>
5963 Make_Constrained_Array_Definition (Loc,
5964 Discrete_Subtype_Definitions => New_List (
5965 Make_Range (Loc,
5966 Low_Bound => Make_Integer_Literal (Loc, 1),
5967 High_Bound => Make_Integer_Literal (Loc,
5968 DT_Entry_Count
5969 (First_Tag_Component (Typ))))),
5970 Component_Definition =>
5971 Make_Component_Definition (Loc,
5972 Subtype_Indication =>
5973 New_Reference_To (RTE (RE_Prim_Ptr), Loc)))));
5975 Append_To (Result,
5976 Make_Full_Type_Declaration (Loc,
5977 Defining_Identifier => DT_Prims_Acc,
5978 Type_Definition =>
5979 Make_Access_To_Object_Definition (Loc,
5980 Subtype_Indication =>
5981 New_Occurrence_Of (DT_Prims, Loc))));
5983 Append_Elmt (DT_Prims_Acc, Access_Disp_Table (Typ));
5985 -- Analyze the resulting list and suppress the generation of the
5986 -- Init_Proc associated with the above array declaration because
5987 -- we never use such type in object declarations; this type is only
5988 -- used to simplify the expansion associated with dispatching calls.
5990 Analyze_List (Result);
5991 Set_Suppress_Init_Proc (Base_Type (DT_Prims));
5993 -- Mark entity of dispatch table. Required by the backend to handle
5994 -- the properly.
5996 Set_Is_Dispatch_Table_Entity (DT_Prims);
5997 end;
5999 Set_Ekind (DT_Ptr, E_Constant);
6000 Set_Is_Tag (DT_Ptr);
6001 Set_Related_Type (DT_Ptr, Typ);
6003 return Result;
6004 end Make_Tags;
6006 -----------------------------------
6007 -- Original_View_In_Visible_Part --
6008 -----------------------------------
6010 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
6011 Scop : constant Entity_Id := Scope (Typ);
6013 begin
6014 -- The scope must be a package
6016 if not Is_Package_Or_Generic_Package (Scop) then
6017 return False;
6018 end if;
6020 -- A type with a private declaration has a private view declared in
6021 -- the visible part.
6023 if Has_Private_Declaration (Typ) then
6024 return True;
6025 end if;
6027 return List_Containing (Parent (Typ)) =
6028 Visible_Declarations (Specification (Unit_Declaration_Node (Scop)));
6029 end Original_View_In_Visible_Part;
6031 ------------------
6032 -- Prim_Op_Kind --
6033 ------------------
6035 function Prim_Op_Kind
6036 (Prim : Entity_Id;
6037 Typ : Entity_Id) return Node_Id
6039 Full_Typ : Entity_Id := Typ;
6040 Loc : constant Source_Ptr := Sloc (Prim);
6041 Prim_Op : Entity_Id;
6043 begin
6044 -- Retrieve the original primitive operation
6046 Prim_Op := Prim;
6047 while Present (Alias (Prim_Op)) loop
6048 Prim_Op := Alias (Prim_Op);
6049 end loop;
6051 if Ekind (Typ) = E_Record_Type
6052 and then Present (Corresponding_Concurrent_Type (Typ))
6053 then
6054 Full_Typ := Corresponding_Concurrent_Type (Typ);
6055 end if;
6057 -- When a private tagged type is completed by a concurrent type,
6058 -- retrieve the full view.
6060 if Is_Private_Type (Full_Typ) then
6061 Full_Typ := Full_View (Full_Typ);
6062 end if;
6064 if Ekind (Prim_Op) = E_Function then
6066 -- Protected function
6068 if Ekind (Full_Typ) = E_Protected_Type then
6069 return New_Reference_To (RTE (RE_POK_Protected_Function), Loc);
6071 -- Task function
6073 elsif Ekind (Full_Typ) = E_Task_Type then
6074 return New_Reference_To (RTE (RE_POK_Task_Function), Loc);
6076 -- Regular function
6078 else
6079 return New_Reference_To (RTE (RE_POK_Function), Loc);
6080 end if;
6082 else
6083 pragma Assert (Ekind (Prim_Op) = E_Procedure);
6085 if Ekind (Full_Typ) = E_Protected_Type then
6087 -- Protected entry
6089 if Is_Primitive_Wrapper (Prim_Op)
6090 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
6091 then
6092 return New_Reference_To (RTE (RE_POK_Protected_Entry), Loc);
6094 -- Protected procedure
6096 else
6097 return New_Reference_To (RTE (RE_POK_Protected_Procedure), Loc);
6098 end if;
6100 elsif Ekind (Full_Typ) = E_Task_Type then
6102 -- Task entry
6104 if Is_Primitive_Wrapper (Prim_Op)
6105 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
6106 then
6107 return New_Reference_To (RTE (RE_POK_Task_Entry), Loc);
6109 -- Task "procedure". These are the internally Expander-generated
6110 -- procedures (task body for instance).
6112 else
6113 return New_Reference_To (RTE (RE_POK_Task_Procedure), Loc);
6114 end if;
6116 -- Regular procedure
6118 else
6119 return New_Reference_To (RTE (RE_POK_Procedure), Loc);
6120 end if;
6121 end if;
6122 end Prim_Op_Kind;
6124 ------------------------
6125 -- Register_Primitive --
6126 ------------------------
6128 procedure Register_Primitive
6129 (Loc : Source_Ptr;
6130 Prim : Entity_Id;
6131 Ins_Nod : Node_Id)
6133 DT_Ptr : Entity_Id;
6134 Iface_Prim : Entity_Id;
6135 Iface_Typ : Entity_Id;
6136 Iface_DT_Ptr : Entity_Id;
6137 Iface_DT_Elmt : Elmt_Id;
6138 L : List_Id;
6139 Pos : Uint;
6140 Tag : Entity_Id;
6141 Tag_Typ : Entity_Id;
6142 Thunk_Id : Entity_Id;
6143 Thunk_Code : Node_Id;
6145 begin
6146 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
6148 if not RTE_Available (RE_Tag) then
6149 return;
6150 end if;
6152 if not Present (Interface_Alias (Prim)) then
6153 Tag_Typ := Scope (DTC_Entity (Prim));
6154 Pos := DT_Position (Prim);
6155 Tag := First_Tag_Component (Tag_Typ);
6157 if Is_Predefined_Dispatching_Operation (Prim)
6158 or else Is_Predefined_Dispatching_Alias (Prim)
6159 then
6160 DT_Ptr :=
6161 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Tag_Typ))));
6163 Insert_After (Ins_Nod,
6164 Build_Set_Predefined_Prim_Op_Address (Loc,
6165 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6166 Position => Pos,
6167 Address_Node =>
6168 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6169 Make_Attribute_Reference (Loc,
6170 Prefix => New_Reference_To (Prim, Loc),
6171 Attribute_Name => Name_Unrestricted_Access))));
6173 -- Register copy of the pointer to the 'size primitive in the TSD.
6175 if Chars (Prim) = Name_uSize
6176 and then RTE_Record_Component_Available (RE_Size_Func)
6177 then
6178 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
6179 Insert_After (Ins_Nod,
6180 Build_Set_Size_Function (Loc,
6181 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6182 Size_Func => Prim));
6183 end if;
6185 else
6186 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
6188 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
6189 Insert_After (Ins_Nod,
6190 Build_Set_Prim_Op_Address (Loc,
6191 Typ => Tag_Typ,
6192 Tag_Node => New_Reference_To (DT_Ptr, Loc),
6193 Position => Pos,
6194 Address_Node =>
6195 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6196 Make_Attribute_Reference (Loc,
6197 Prefix => New_Reference_To (Prim, Loc),
6198 Attribute_Name => Name_Unrestricted_Access))));
6199 end if;
6201 -- Ada 2005 (AI-251): Primitive associated with an interface type
6202 -- Generate the code of the thunk only if the interface type is not an
6203 -- immediate ancestor of Typ; otherwise the dispatch table associated
6204 -- with the interface is the primary dispatch table and we have nothing
6205 -- else to do here.
6207 else
6208 Tag_Typ := Find_Dispatching_Type (Alias (Prim));
6209 Iface_Typ := Find_Dispatching_Type (Interface_Alias (Prim));
6211 pragma Assert (Is_Interface (Iface_Typ));
6213 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
6215 if not Is_Ancestor (Iface_Typ, Tag_Typ)
6216 and then Present (Thunk_Code)
6217 then
6218 -- Comment needed on why checks are suppressed. This is not just
6219 -- efficiency, but fundamental functionality (see 1.295 RH, which
6220 -- still does not answer this question) ???
6222 Insert_Action (Ins_Nod, Thunk_Code, Suppress => All_Checks);
6224 -- Generate the code necessary to fill the appropriate entry of
6225 -- the secondary dispatch table of Prim's controlling type with
6226 -- Thunk_Id's address.
6228 Iface_DT_Elmt := Find_Interface_ADT (Tag_Typ, Iface_Typ);
6229 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6230 pragma Assert (Has_Thunks (Iface_DT_Ptr));
6232 Iface_Prim := Interface_Alias (Prim);
6233 Pos := DT_Position (Iface_Prim);
6234 Tag := First_Tag_Component (Iface_Typ);
6235 L := New_List;
6237 if Is_Predefined_Dispatching_Operation (Prim)
6238 or else Is_Predefined_Dispatching_Alias (Prim)
6239 then
6240 Append_To (L,
6241 Build_Set_Predefined_Prim_Op_Address (Loc,
6242 Tag_Node =>
6243 New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
6244 Position => Pos,
6245 Address_Node =>
6246 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6247 Make_Attribute_Reference (Loc,
6248 Prefix => New_Reference_To (Thunk_Id, Loc),
6249 Attribute_Name => Name_Unrestricted_Access))));
6251 Next_Elmt (Iface_DT_Elmt);
6252 Next_Elmt (Iface_DT_Elmt);
6253 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6254 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
6256 Append_To (L,
6257 Build_Set_Predefined_Prim_Op_Address (Loc,
6258 Tag_Node =>
6259 New_Reference_To (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
6260 Position => Pos,
6261 Address_Node =>
6262 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6263 Make_Attribute_Reference (Loc,
6264 Prefix => New_Reference_To (Alias (Prim), Loc),
6265 Attribute_Name => Name_Unrestricted_Access))));
6267 Insert_Actions_After (Ins_Nod, L);
6269 else
6270 pragma Assert (Pos /= Uint_0
6271 and then Pos <= DT_Entry_Count (Tag));
6273 Append_To (L,
6274 Build_Set_Prim_Op_Address (Loc,
6275 Typ => Iface_Typ,
6276 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
6277 Position => Pos,
6278 Address_Node =>
6279 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6280 Make_Attribute_Reference (Loc,
6281 Prefix => New_Reference_To (Thunk_Id, Loc),
6282 Attribute_Name => Name_Unrestricted_Access))));
6284 Next_Elmt (Iface_DT_Elmt);
6285 Next_Elmt (Iface_DT_Elmt);
6286 Iface_DT_Ptr := Node (Iface_DT_Elmt);
6287 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
6289 Append_To (L,
6290 Build_Set_Prim_Op_Address (Loc,
6291 Typ => Iface_Typ,
6292 Tag_Node => New_Reference_To (Iface_DT_Ptr, Loc),
6293 Position => Pos,
6294 Address_Node =>
6295 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6296 Make_Attribute_Reference (Loc,
6297 Prefix => New_Reference_To (Alias (Prim), Loc),
6298 Attribute_Name => Name_Unrestricted_Access))));
6300 Insert_Actions_After (Ins_Nod, L);
6301 end if;
6302 end if;
6303 end if;
6304 end Register_Primitive;
6306 -------------------------
6307 -- Set_All_DT_Position --
6308 -------------------------
6310 procedure Set_All_DT_Position (Typ : Entity_Id) is
6312 procedure Validate_Position (Prim : Entity_Id);
6313 -- Check that the position assigned to Prim is completely safe
6314 -- (it has not been assigned to a previously defined primitive
6315 -- operation of Typ)
6317 -----------------------
6318 -- Validate_Position --
6319 -----------------------
6321 procedure Validate_Position (Prim : Entity_Id) is
6322 Op_Elmt : Elmt_Id;
6323 Op : Entity_Id;
6325 begin
6326 -- Aliased primitives are safe
6328 if Present (Alias (Prim)) then
6329 return;
6330 end if;
6332 Op_Elmt := First_Elmt (Primitive_Operations (Typ));
6333 while Present (Op_Elmt) loop
6334 Op := Node (Op_Elmt);
6336 -- No need to check against itself
6338 if Op = Prim then
6339 null;
6341 -- Primitive operations covering abstract interfaces are
6342 -- allocated later
6344 elsif Present (Interface_Alias (Op)) then
6345 null;
6347 -- Predefined dispatching operations are completely safe. They
6348 -- are allocated at fixed positions in a separate table.
6350 elsif Is_Predefined_Dispatching_Operation (Op)
6351 or else Is_Predefined_Dispatching_Alias (Op)
6352 then
6353 null;
6355 -- Aliased subprograms are safe
6357 elsif Present (Alias (Op)) then
6358 null;
6360 elsif DT_Position (Op) = DT_Position (Prim)
6361 and then not Is_Predefined_Dispatching_Operation (Op)
6362 and then not Is_Predefined_Dispatching_Operation (Prim)
6363 and then not Is_Predefined_Dispatching_Alias (Op)
6364 and then not Is_Predefined_Dispatching_Alias (Prim)
6365 then
6367 -- Handle aliased subprograms
6369 declare
6370 Op_1 : Entity_Id;
6371 Op_2 : Entity_Id;
6373 begin
6374 Op_1 := Op;
6375 loop
6376 if Present (Overridden_Operation (Op_1)) then
6377 Op_1 := Overridden_Operation (Op_1);
6378 elsif Present (Alias (Op_1)) then
6379 Op_1 := Alias (Op_1);
6380 else
6381 exit;
6382 end if;
6383 end loop;
6385 Op_2 := Prim;
6386 loop
6387 if Present (Overridden_Operation (Op_2)) then
6388 Op_2 := Overridden_Operation (Op_2);
6389 elsif Present (Alias (Op_2)) then
6390 Op_2 := Alias (Op_2);
6391 else
6392 exit;
6393 end if;
6394 end loop;
6396 if Op_1 /= Op_2 then
6397 raise Program_Error;
6398 end if;
6399 end;
6400 end if;
6402 Next_Elmt (Op_Elmt);
6403 end loop;
6404 end Validate_Position;
6406 -- Local variables
6408 Parent_Typ : constant Entity_Id := Etype (Typ);
6409 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
6410 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
6412 Adjusted : Boolean := False;
6413 Finalized : Boolean := False;
6415 Count_Prim : Nat;
6416 DT_Length : Nat;
6417 Nb_Prim : Nat;
6418 Prim : Entity_Id;
6419 Prim_Elmt : Elmt_Id;
6421 -- Start of processing for Set_All_DT_Position
6423 begin
6424 pragma Assert (Present (First_Tag_Component (Typ)));
6426 -- Set the DT_Position for each primitive operation. Perform some
6427 -- sanity checks to avoid to build completely inconsistent dispatch
6428 -- tables.
6430 -- First stage: Set the DTC entity of all the primitive operations
6431 -- This is required to properly read the DT_Position attribute in
6432 -- the latter stages.
6434 Prim_Elmt := First_Prim;
6435 Count_Prim := 0;
6436 while Present (Prim_Elmt) loop
6437 Prim := Node (Prim_Elmt);
6439 -- Predefined primitives have a separate dispatch table
6441 if not (Is_Predefined_Dispatching_Operation (Prim)
6442 or else Is_Predefined_Dispatching_Alias (Prim))
6443 then
6444 Count_Prim := Count_Prim + 1;
6445 end if;
6447 Set_DTC_Entity_Value (Typ, Prim);
6449 -- Clear any previous value of the DT_Position attribute. In this
6450 -- way we ensure that the final position of all the primitives is
6451 -- established by the following stages of this algorithm.
6453 Set_DT_Position (Prim, No_Uint);
6455 Next_Elmt (Prim_Elmt);
6456 end loop;
6458 declare
6459 Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean :=
6460 (others => False);
6462 E : Entity_Id;
6464 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id);
6465 -- Called if Typ is declared in a nested package or a public child
6466 -- package to handle inherited primitives that were inherited by Typ
6467 -- in the visible part, but whose declaration was deferred because
6468 -- the parent operation was private and not visible at that point.
6470 procedure Set_Fixed_Prim (Pos : Nat);
6471 -- Sets to true an element of the Fixed_Prim table to indicate
6472 -- that this entry of the dispatch table of Typ is occupied.
6474 ------------------------------------------
6475 -- Handle_Inherited_Private_Subprograms --
6476 ------------------------------------------
6478 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id) is
6479 Op_List : Elist_Id;
6480 Op_Elmt : Elmt_Id;
6481 Op_Elmt_2 : Elmt_Id;
6482 Prim_Op : Entity_Id;
6483 Parent_Subp : Entity_Id;
6485 begin
6486 Op_List := Primitive_Operations (Typ);
6488 Op_Elmt := First_Elmt (Op_List);
6489 while Present (Op_Elmt) loop
6490 Prim_Op := Node (Op_Elmt);
6492 -- Search primitives that are implicit operations with an
6493 -- internal name whose parent operation has a normal name.
6495 if Present (Alias (Prim_Op))
6496 and then Find_Dispatching_Type (Alias (Prim_Op)) /= Typ
6497 and then not Comes_From_Source (Prim_Op)
6498 and then Is_Internal_Name (Chars (Prim_Op))
6499 and then not Is_Internal_Name (Chars (Alias (Prim_Op)))
6500 then
6501 Parent_Subp := Alias (Prim_Op);
6503 -- Check if the type has an explicit overriding for this
6504 -- primitive.
6506 Op_Elmt_2 := Next_Elmt (Op_Elmt);
6507 while Present (Op_Elmt_2) loop
6508 if Chars (Node (Op_Elmt_2)) = Chars (Parent_Subp)
6509 and then Type_Conformant (Prim_Op, Node (Op_Elmt_2))
6510 then
6511 Set_DT_Position (Prim_Op, DT_Position (Parent_Subp));
6512 Set_DT_Position (Node (Op_Elmt_2),
6513 DT_Position (Parent_Subp));
6514 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim_Op)));
6516 goto Next_Primitive;
6517 end if;
6519 Next_Elmt (Op_Elmt_2);
6520 end loop;
6521 end if;
6523 <<Next_Primitive>>
6524 Next_Elmt (Op_Elmt);
6525 end loop;
6526 end Handle_Inherited_Private_Subprograms;
6528 --------------------
6529 -- Set_Fixed_Prim --
6530 --------------------
6532 procedure Set_Fixed_Prim (Pos : Nat) is
6533 begin
6534 pragma Assert (Pos >= 0 and then Pos <= Count_Prim);
6535 Fixed_Prim (Pos) := True;
6536 exception
6537 when Constraint_Error =>
6538 raise Program_Error;
6539 end Set_Fixed_Prim;
6541 begin
6542 -- In case of nested packages and public child package it may be
6543 -- necessary a special management on inherited subprograms so that
6544 -- the dispatch table is properly filled.
6546 if Ekind (Scope (Scope (Typ))) = E_Package
6547 and then Scope (Scope (Typ)) /= Standard_Standard
6548 and then ((Is_Derived_Type (Typ) and then not Is_Private_Type (Typ))
6549 or else
6550 (Nkind (Parent (Typ)) = N_Private_Extension_Declaration
6551 and then Is_Generic_Type (Typ)))
6552 and then In_Open_Scopes (Scope (Etype (Typ)))
6553 and then Typ = Base_Type (Typ)
6554 then
6555 Handle_Inherited_Private_Subprograms (Typ);
6556 end if;
6558 -- Second stage: Register fixed entries
6560 Nb_Prim := 0;
6561 Prim_Elmt := First_Prim;
6562 while Present (Prim_Elmt) loop
6563 Prim := Node (Prim_Elmt);
6565 -- Predefined primitives have a separate table and all its
6566 -- entries are at predefined fixed positions.
6568 if Is_Predefined_Dispatching_Operation (Prim) then
6569 Set_DT_Position (Prim, Default_Prim_Op_Position (Prim));
6571 elsif Is_Predefined_Dispatching_Alias (Prim) then
6572 E := Alias (Prim);
6573 while Present (Alias (E)) loop
6574 E := Alias (E);
6575 end loop;
6577 Set_DT_Position (Prim, Default_Prim_Op_Position (E));
6579 -- Overriding primitives of ancestor abstract interfaces
6581 elsif Present (Interface_Alias (Prim))
6582 and then Is_Ancestor
6583 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ)
6584 then
6585 pragma Assert (DT_Position (Prim) = No_Uint
6586 and then Present (DTC_Entity (Interface_Alias (Prim))));
6588 E := Interface_Alias (Prim);
6589 Set_DT_Position (Prim, DT_Position (E));
6591 pragma Assert
6592 (DT_Position (Alias (Prim)) = No_Uint
6593 or else DT_Position (Alias (Prim)) = DT_Position (E));
6594 Set_DT_Position (Alias (Prim), DT_Position (E));
6595 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));
6597 -- Overriding primitives must use the same entry as the
6598 -- overridden primitive.
6600 elsif not Present (Interface_Alias (Prim))
6601 and then Present (Alias (Prim))
6602 and then Chars (Prim) = Chars (Alias (Prim))
6603 and then Find_Dispatching_Type (Alias (Prim)) /= Typ
6604 and then Is_Ancestor
6605 (Find_Dispatching_Type (Alias (Prim)), Typ)
6606 and then Present (DTC_Entity (Alias (Prim)))
6607 then
6608 E := Alias (Prim);
6609 Set_DT_Position (Prim, DT_Position (E));
6611 if not Is_Predefined_Dispatching_Alias (E) then
6612 Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
6613 end if;
6614 end if;
6616 Next_Elmt (Prim_Elmt);
6617 end loop;
6619 -- Third stage: Fix the position of all the new primitives
6620 -- Entries associated with primitives covering interfaces
6621 -- are handled in a latter round.
6623 Prim_Elmt := First_Prim;
6624 while Present (Prim_Elmt) loop
6625 Prim := Node (Prim_Elmt);
6627 -- Skip primitives previously set entries
6629 if DT_Position (Prim) /= No_Uint then
6630 null;
6632 -- Primitives covering interface primitives are handled later
6634 elsif Present (Interface_Alias (Prim)) then
6635 null;
6637 else
6638 -- Take the next available position in the DT
6640 loop
6641 Nb_Prim := Nb_Prim + 1;
6642 pragma Assert (Nb_Prim <= Count_Prim);
6643 exit when not Fixed_Prim (Nb_Prim);
6644 end loop;
6646 Set_DT_Position (Prim, UI_From_Int (Nb_Prim));
6647 Set_Fixed_Prim (Nb_Prim);
6648 end if;
6650 Next_Elmt (Prim_Elmt);
6651 end loop;
6652 end;
6654 -- Fourth stage: Complete the decoration of primitives covering
6655 -- interfaces (that is, propagate the DT_Position attribute
6656 -- from the aliased primitive)
6658 Prim_Elmt := First_Prim;
6659 while Present (Prim_Elmt) loop
6660 Prim := Node (Prim_Elmt);
6662 if DT_Position (Prim) = No_Uint
6663 and then Present (Interface_Alias (Prim))
6664 then
6665 pragma Assert (Present (Alias (Prim))
6666 and then Find_Dispatching_Type (Alias (Prim)) = Typ);
6668 -- Check if this entry will be placed in the primary DT
6670 if Is_Ancestor
6671 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ)
6672 then
6673 pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
6674 Set_DT_Position (Prim, DT_Position (Alias (Prim)));
6676 -- Otherwise it will be placed in the secondary DT
6678 else
6679 pragma Assert
6680 (DT_Position (Interface_Alias (Prim)) /= No_Uint);
6681 Set_DT_Position (Prim,
6682 DT_Position (Interface_Alias (Prim)));
6683 end if;
6684 end if;
6686 Next_Elmt (Prim_Elmt);
6687 end loop;
6689 -- Generate listing showing the contents of the dispatch tables.
6690 -- This action is done before some further static checks because
6691 -- in case of critical errors caused by a wrong dispatch table
6692 -- we need to see the contents of such table.
6694 if Debug_Flag_ZZ then
6695 Write_DT (Typ);
6696 end if;
6698 -- Final stage: Ensure that the table is correct plus some further
6699 -- verifications concerning the primitives.
6701 Prim_Elmt := First_Prim;
6702 DT_Length := 0;
6703 while Present (Prim_Elmt) loop
6704 Prim := Node (Prim_Elmt);
6706 -- At this point all the primitives MUST have a position
6707 -- in the dispatch table.
6709 if DT_Position (Prim) = No_Uint then
6710 raise Program_Error;
6711 end if;
6713 -- Calculate real size of the dispatch table
6715 if not (Is_Predefined_Dispatching_Operation (Prim)
6716 or else Is_Predefined_Dispatching_Alias (Prim))
6717 and then UI_To_Int (DT_Position (Prim)) > DT_Length
6718 then
6719 DT_Length := UI_To_Int (DT_Position (Prim));
6720 end if;
6722 -- Ensure that the assigned position to non-predefined
6723 -- dispatching operations in the dispatch table is correct.
6725 if not (Is_Predefined_Dispatching_Operation (Prim)
6726 or else Is_Predefined_Dispatching_Alias (Prim))
6727 then
6728 Validate_Position (Prim);
6729 end if;
6731 if Chars (Prim) = Name_Finalize then
6732 Finalized := True;
6733 end if;
6735 if Chars (Prim) = Name_Adjust then
6736 Adjusted := True;
6737 end if;
6739 -- An abstract operation cannot be declared in the private part
6740 -- for a visible abstract type, because it could never be over-
6741 -- ridden. For explicit declarations this is checked at the
6742 -- point of declaration, but for inherited operations it must
6743 -- be done when building the dispatch table.
6745 -- Ada 2005 (AI-251): Primitives associated with interfaces are
6746 -- excluded from this check because interfaces must be visible in
6747 -- the public and private part (RM 7.3 (7.3/2))
6749 if Is_Abstract_Type (Typ)
6750 and then Is_Abstract_Subprogram (Prim)
6751 and then Present (Alias (Prim))
6752 and then not Is_Interface
6753 (Find_Dispatching_Type (Ultimate_Alias (Prim)))
6754 and then not Present (Interface_Alias (Prim))
6755 and then Is_Derived_Type (Typ)
6756 and then In_Private_Part (Current_Scope)
6757 and then
6758 List_Containing (Parent (Prim)) =
6759 Private_Declarations
6760 (Specification (Unit_Declaration_Node (Current_Scope)))
6761 and then Original_View_In_Visible_Part (Typ)
6762 then
6763 -- We exclude Input and Output stream operations because
6764 -- Limited_Controlled inherits useless Input and Output
6765 -- stream operations from Root_Controlled, which can
6766 -- never be overridden.
6768 if not Is_TSS (Prim, TSS_Stream_Input)
6769 and then
6770 not Is_TSS (Prim, TSS_Stream_Output)
6771 then
6772 Error_Msg_NE
6773 ("abstract inherited private operation&" &
6774 " must be overridden (RM 3.9.3(10))",
6775 Parent (Typ), Prim);
6776 end if;
6777 end if;
6779 Next_Elmt (Prim_Elmt);
6780 end loop;
6782 -- Additional check
6784 if Is_Controlled (Typ) then
6785 if not Finalized then
6786 Error_Msg_N
6787 ("controlled type has no explicit Finalize method?", Typ);
6789 elsif not Adjusted then
6790 Error_Msg_N
6791 ("controlled type has no explicit Adjust method?", Typ);
6792 end if;
6793 end if;
6795 -- Set the final size of the Dispatch Table
6797 Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));
6799 -- The derived type must have at least as many components as its parent
6800 -- (for root types Etype points to itself and the test cannot fail).
6802 if DT_Entry_Count (The_Tag) <
6803 DT_Entry_Count (First_Tag_Component (Parent_Typ))
6804 then
6805 raise Program_Error;
6806 end if;
6807 end Set_All_DT_Position;
6809 -----------------------------
6810 -- Set_Default_Constructor --
6811 -----------------------------
6813 procedure Set_Default_Constructor (Typ : Entity_Id) is
6814 Loc : Source_Ptr;
6815 Init : Entity_Id;
6816 Param : Entity_Id;
6817 E : Entity_Id;
6819 begin
6820 -- Look for the default constructor entity. For now only the
6821 -- default constructor has the flag Is_Constructor.
6823 E := Next_Entity (Typ);
6824 while Present (E)
6825 and then (Ekind (E) /= E_Function or else not Is_Constructor (E))
6826 loop
6827 Next_Entity (E);
6828 end loop;
6830 -- Create the init procedure
6832 if Present (E) then
6833 Loc := Sloc (E);
6834 Init := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
6835 Param := Make_Defining_Identifier (Loc, Name_X);
6837 Discard_Node (
6838 Make_Subprogram_Declaration (Loc,
6839 Make_Procedure_Specification (Loc,
6840 Defining_Unit_Name => Init,
6841 Parameter_Specifications => New_List (
6842 Make_Parameter_Specification (Loc,
6843 Defining_Identifier => Param,
6844 Parameter_Type => New_Reference_To (Typ, Loc))))));
6846 Set_Init_Proc (Typ, Init);
6847 Set_Is_Imported (Init);
6848 Set_Interface_Name (Init, Interface_Name (E));
6849 Set_Convention (Init, Convention_C);
6850 Set_Is_Public (Init);
6851 Set_Has_Completion (Init);
6853 -- If there are no constructors, mark the type as abstract since we
6854 -- won't be able to declare objects of that type.
6856 else
6857 Set_Is_Abstract_Type (Typ);
6858 end if;
6859 end Set_Default_Constructor;
6861 --------------------------
6862 -- Set_DTC_Entity_Value --
6863 --------------------------
6865 procedure Set_DTC_Entity_Value
6866 (Tagged_Type : Entity_Id;
6867 Prim : Entity_Id)
6869 begin
6870 if Present (Interface_Alias (Prim))
6871 and then Is_Interface
6872 (Find_Dispatching_Type (Interface_Alias (Prim)))
6873 then
6874 Set_DTC_Entity (Prim,
6875 Find_Interface_Tag
6876 (T => Tagged_Type,
6877 Iface => Find_Dispatching_Type (Interface_Alias (Prim))));
6878 else
6879 Set_DTC_Entity (Prim,
6880 First_Tag_Component (Tagged_Type));
6881 end if;
6882 end Set_DTC_Entity_Value;
6884 -----------------
6885 -- Tagged_Kind --
6886 -----------------
6888 function Tagged_Kind (T : Entity_Id) return Node_Id is
6889 Conc_Typ : Entity_Id;
6890 Loc : constant Source_Ptr := Sloc (T);
6892 begin
6893 pragma Assert
6894 (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));
6896 -- Abstract kinds
6898 if Is_Abstract_Type (T) then
6899 if Is_Limited_Record (T) then
6900 return New_Reference_To (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
6901 else
6902 return New_Reference_To (RTE (RE_TK_Abstract_Tagged), Loc);
6903 end if;
6905 -- Concurrent kinds
6907 elsif Is_Concurrent_Record_Type (T) then
6908 Conc_Typ := Corresponding_Concurrent_Type (T);
6910 if Present (Full_View (Conc_Typ)) then
6911 Conc_Typ := Full_View (Conc_Typ);
6912 end if;
6914 if Ekind (Conc_Typ) = E_Protected_Type then
6915 return New_Reference_To (RTE (RE_TK_Protected), Loc);
6916 else
6917 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
6918 return New_Reference_To (RTE (RE_TK_Task), Loc);
6919 end if;
6921 -- Regular tagged kinds
6923 else
6924 if Is_Limited_Record (T) then
6925 return New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc);
6926 else
6927 return New_Reference_To (RTE (RE_TK_Tagged), Loc);
6928 end if;
6929 end if;
6930 end Tagged_Kind;
6932 --------------
6933 -- Write_DT --
6934 --------------
6936 procedure Write_DT (Typ : Entity_Id) is
6937 Elmt : Elmt_Id;
6938 Prim : Node_Id;
6940 begin
6941 -- Protect this procedure against wrong usage. Required because it will
6942 -- be used directly from GDB
6944 if not (Typ <= Last_Node_Id)
6945 or else not Is_Tagged_Type (Typ)
6946 then
6947 Write_Str ("wrong usage: Write_DT must be used with tagged types");
6948 Write_Eol;
6949 return;
6950 end if;
6952 Write_Int (Int (Typ));
6953 Write_Str (": ");
6954 Write_Name (Chars (Typ));
6956 if Is_Interface (Typ) then
6957 Write_Str (" is interface");
6958 end if;
6960 Write_Eol;
6962 Elmt := First_Elmt (Primitive_Operations (Typ));
6963 while Present (Elmt) loop
6964 Prim := Node (Elmt);
6965 Write_Str (" - ");
6967 -- Indicate if this primitive will be allocated in the primary
6968 -- dispatch table or in a secondary dispatch table associated
6969 -- with an abstract interface type
6971 if Present (DTC_Entity (Prim)) then
6972 if Etype (DTC_Entity (Prim)) = RTE (RE_Tag) then
6973 Write_Str ("[P] ");
6974 else
6975 Write_Str ("[s] ");
6976 end if;
6977 end if;
6979 -- Output the node of this primitive operation and its name
6981 Write_Int (Int (Prim));
6982 Write_Str (": ");
6984 if Is_Predefined_Dispatching_Operation (Prim) then
6985 Write_Str ("(predefined) ");
6986 end if;
6988 Write_Name (Chars (Prim));
6990 -- Indicate if this primitive has an aliased primitive
6992 if Present (Alias (Prim)) then
6993 Write_Str (" (alias = ");
6994 Write_Int (Int (Alias (Prim)));
6996 -- If the DTC_Entity attribute is already set we can also output
6997 -- the name of the interface covered by this primitive (if any)
6999 if Present (DTC_Entity (Alias (Prim)))
7000 and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
7001 then
7002 Write_Str (" from interface ");
7003 Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
7004 end if;
7006 if Present (Interface_Alias (Prim)) then
7007 Write_Str (", AI_Alias of ");
7008 Write_Name
7009 (Chars (Find_Dispatching_Type (Interface_Alias (Prim))));
7010 Write_Char (':');
7011 Write_Int (Int (Interface_Alias (Prim)));
7012 end if;
7014 Write_Str (")");
7015 end if;
7017 -- Display the final position of this primitive in its associated
7018 -- (primary or secondary) dispatch table
7020 if Present (DTC_Entity (Prim))
7021 and then DT_Position (Prim) /= No_Uint
7022 then
7023 Write_Str (" at #");
7024 Write_Int (UI_To_Int (DT_Position (Prim)));
7025 end if;
7027 if Is_Abstract_Subprogram (Prim) then
7028 Write_Str (" is abstract;");
7030 -- Check if this is a null primitive
7032 elsif Comes_From_Source (Prim)
7033 and then Ekind (Prim) = E_Procedure
7034 and then Null_Present (Parent (Prim))
7035 then
7036 Write_Str (" is null;");
7037 end if;
7039 Write_Eol;
7041 Next_Elmt (Elmt);
7042 end loop;
7043 end Write_DT;
7045 end Exp_Disp;