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