]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ada/exp_disp.adb
[Ada] Variable-sized node types
[thirdparty/gcc.git] / gcc / ada / exp_disp.adb
CommitLineData
70482933
RK
1------------------------------------------------------------------------------
2-- --
3-- GNAT COMPILER COMPONENTS --
4-- --
5-- E X P _ D I S P --
6-- --
7-- B o d y --
8-- --
8d0d46f4 9-- Copyright (C) 1992-2021, Free Software Foundation, Inc. --
70482933
RK
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- --
e18d6a15 13-- ware Foundation; either version 3, or (at your option) any later ver- --
70482933
RK
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 --
e18d6a15
JM
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. --
70482933
RK
20-- --
21-- GNAT was originally developed by the GNAT team at New York University. --
71ff80dc 22-- Extensive contributions were provided by Ada Core Technologies Inc. --
70482933
RK
23-- --
24------------------------------------------------------------------------------
25
26with Atree; use Atree;
27with Checks; use Checks;
758c442c 28with Debug; use Debug;
76f9c7f4
BD
29with Einfo; use Einfo;
30with Einfo.Entities; use Einfo.Entities;
31with Einfo.Utils; use Einfo.Utils;
70482933
RK
32with Elists; use Elists;
33with Errout; use Errout;
15529d0a 34with Expander; use Expander;
dee4682a 35with Exp_Atag; use Exp_Atag;
23b86353 36with Exp_Ch6; use Exp_Ch6;
9c41193c 37with Exp_CG; use Exp_CG;
f4d379b8 38with Exp_Dbug; use Exp_Dbug;
70482933
RK
39with Exp_Tss; use Exp_Tss;
40with Exp_Util; use Exp_Util;
bfef8d0d 41with Freeze; use Freeze;
8636f52f 42with Ghost; use Ghost;
70482933 43with Itypes; use Itypes;
4da17013 44with Layout; use Layout;
70482933
RK
45with Nlists; use Nlists;
46with Nmake; use Nmake;
758c442c 47with Namet; use Namet;
70482933 48with Opt; use Opt;
758c442c 49with Output; use Output;
b0efe69e
JM
50with Restrict; use Restrict;
51with Rident; use Rident;
70482933 52with Rtsfind; use Rtsfind;
758c442c 53with Sem; use Sem;
a4100e55 54with Sem_Aux; use Sem_Aux;
d0dd5209 55with Sem_Ch6; use Sem_Ch6;
1923d2d6 56with Sem_Ch7; use Sem_Ch7;
d0dd5209 57with Sem_Ch8; use Sem_Ch8;
70482933 58with Sem_Disp; use Sem_Disp;
d0dd5209 59with Sem_Eval; use Sem_Eval;
70482933 60with Sem_Res; use Sem_Res;
758c442c 61with Sem_Type; use Sem_Type;
70482933 62with Sem_Util; use Sem_Util;
76f9c7f4
BD
63with Sinfo; use Sinfo;
64with Sinfo.Nodes; use Sinfo.Nodes;
65with Sinfo.Utils; use Sinfo.Utils;
304757d2 66with Sinput; use Sinput;
70482933
RK
67with Snames; use Snames;
68with Stand; use Stand;
d0dd5209 69with Stringt; use Stringt;
7665e4bd 70with SCIL_LL; use SCIL_LL;
70482933 71with Tbuild; use Tbuild;
70482933
RK
72
73package body Exp_Disp is
74
d0dd5209
JM
75 -----------------------
76 -- Local Subprograms --
77 -----------------------
70482933 78
b0efe69e 79 function Default_Prim_Op_Position (E : Entity_Id) return Uint;
758c442c
GD
80 -- Ada 2005 (AI-251): Returns the fixed position in the dispatch table
81 -- of the default primitive operations.
82
e18d6a15
JM
83 function Has_DT (Typ : Entity_Id) return Boolean;
84 pragma Inline (Has_DT);
85 -- Returns true if we generate a dispatch table for tagged type Typ
86
bfef8d0d
JM
87 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean;
88 -- Returns true if Prim is not a predefined dispatching primitive but it is
8fc789c8 89 -- an alias of a predefined dispatching primitive (i.e. through a renaming)
bfef8d0d 90
5a1ccfb1 91 function New_Value (From : Node_Id) return Node_Id;
6782b1ef
AC
92 -- From is the original Expression. New_Value is equivalent to a call to
93 -- Duplicate_Subexpr with an explicit dereference when From is an access
94 -- parameter.
5a1ccfb1 95
70482933 96 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean;
6782b1ef
AC
97 -- Check if the type has a private view or if the public view appears in
98 -- the visible part of a package spec.
70482933 99
10b93b2e
HK
100 function Prim_Op_Kind
101 (Prim : Entity_Id;
102 Typ : Entity_Id) return Node_Id;
103 -- Ada 2005 (AI-345): Determine the primitive operation kind of Prim
4d744221 104 -- according to its type Typ. Return a reference to an RE_Prim_Op_Kind
10b93b2e 105 -- enumeration value.
758c442c 106
4d744221
JM
107 function Tagged_Kind (T : Entity_Id) return Node_Id;
108 -- Ada 2005 (AI-345): Determine the tagged kind of T and return a reference
109 -- to an RE_Tagged_Kind enumeration value.
110
5a1ccfb1
AC
111 ----------------------
112 -- Apply_Tag_Checks --
113 ----------------------
114
115 procedure Apply_Tag_Checks (Call_Node : Node_Id) is
116 Loc : constant Source_Ptr := Sloc (Call_Node);
117 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
118 Ctrl_Typ : constant Entity_Id := Base_Type (Etype (Ctrl_Arg));
119 Param_List : constant List_Id := Parameter_Associations (Call_Node);
120
121 Subp : Entity_Id;
122 CW_Typ : Entity_Id;
123 Param : Node_Id;
124 Typ : Entity_Id;
125 Eq_Prim_Op : Entity_Id := Empty;
126
127 begin
128 if No_Run_Time_Mode then
129 Error_Msg_CRT ("tagged types", Call_Node);
130 return;
131 end if;
132
6782b1ef
AC
133 -- Apply_Tag_Checks is called directly from the semantics, so we
134 -- need a check to see whether expansion is active before proceeding.
135 -- In addition, there is no need to expand the call when compiling
136 -- under restriction No_Dispatching_Calls; the semantic analyzer has
5a1ccfb1
AC
137 -- previously notified the violation of this restriction.
138
139 if not Expander_Active
140 or else Restriction_Active (No_Dispatching_Calls)
141 then
142 return;
143 end if;
144
145 -- Set subprogram. If this is an inherited operation that was
146 -- overridden, the body that is being called is its alias.
147
148 Subp := Entity (Name (Call_Node));
149
150 if Present (Alias (Subp))
151 and then Is_Inherited_Operation (Subp)
152 and then No (DTC_Entity (Subp))
153 then
154 Subp := Alias (Subp);
155 end if;
156
157 -- Definition of the class-wide type and the tagged type
158
159 -- If the controlling argument is itself a tag rather than a tagged
160 -- object, then use the class-wide type associated with the subprogram's
161 -- controlling type. This case can occur when a call to an inherited
162 -- primitive has an actual that originated from a default parameter
163 -- given by a tag-indeterminate call and when there is no other
164 -- controlling argument providing the tag (AI-239 requires dispatching).
165 -- This capability of dispatching directly by tag is also needed by the
166 -- implementation of AI-260 (for the generic dispatching constructors).
167
3477e0b2
PT
168 if Is_RTE (Ctrl_Typ, RE_Tag)
169 or else Is_RTE (Ctrl_Typ, RE_Interface_Tag)
5a1ccfb1
AC
170 then
171 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
172
173 -- Class_Wide_Type is applied to the expressions used to initialize
174 -- CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
175 -- there are cases where the controlling type is resolved to a specific
176 -- type (such as for designated types of arguments such as CW'Access).
177
178 elsif Is_Access_Type (Ctrl_Typ) then
179 CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));
180
181 else
182 CW_Typ := Class_Wide_Type (Ctrl_Typ);
183 end if;
184
98ee6f8d 185 Typ := Find_Specific_Type (CW_Typ);
5a1ccfb1
AC
186
187 if not Is_Limited_Type (Typ) then
188 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
189 end if;
190
191 -- Dispatching call to C++ primitive
192
193 if Is_CPP_Class (Typ) then
194 null;
195
196 -- Dispatching call to Ada primitive
197
198 elsif Present (Param_List) then
199
200 -- Generate the Tag checks when appropriate
201
202 Param := First_Actual (Call_Node);
203 while Present (Param) loop
204
205 -- No tag check with itself
206
207 if Param = Ctrl_Arg then
208 null;
209
210 -- No tag check for parameter whose type is neither tagged nor
211 -- access to tagged (for access parameters)
212
213 elsif No (Find_Controlling_Arg (Param)) then
214 null;
215
216 -- No tag check for function dispatching on result if the
217 -- Tag given by the context is this one
218
219 elsif Find_Controlling_Arg (Param) = Ctrl_Arg then
220 null;
221
6782b1ef
AC
222 -- "=" is the only dispatching operation allowed to get operands
223 -- with incompatible tags (it just returns false). We use
224 -- Duplicate_Subexpr_Move_Checks instead of calling Relocate_Node
225 -- because the value will be duplicated to check the tags.
5a1ccfb1
AC
226
227 elsif Subp = Eq_Prim_Op then
228 null;
229
230 -- No check in presence of suppress flags
231
232 elsif Tag_Checks_Suppressed (Etype (Param))
233 or else (Is_Access_Type (Etype (Param))
234 and then Tag_Checks_Suppressed
235 (Designated_Type (Etype (Param))))
236 then
237 null;
238
239 -- Optimization: no tag checks if the parameters are identical
240
241 elsif Is_Entity_Name (Param)
242 and then Is_Entity_Name (Ctrl_Arg)
243 and then Entity (Param) = Entity (Ctrl_Arg)
244 then
245 null;
246
247 -- Now we need to generate the Tag check
248
249 else
250 -- Generate code for tag equality check
6782b1ef 251
5a1ccfb1
AC
252 -- Perhaps should have Checks.Apply_Tag_Equality_Check???
253
254 Insert_Action (Ctrl_Arg,
255 Make_Implicit_If_Statement (Call_Node,
256 Condition =>
257 Make_Op_Ne (Loc,
258 Left_Opnd =>
259 Make_Selected_Component (Loc,
260 Prefix => New_Value (Ctrl_Arg),
261 Selector_Name =>
e4494292 262 New_Occurrence_Of
5a1ccfb1
AC
263 (First_Tag_Component (Typ), Loc)),
264
265 Right_Opnd =>
266 Make_Selected_Component (Loc,
267 Prefix =>
268 Unchecked_Convert_To (Typ, New_Value (Param)),
269 Selector_Name =>
e4494292 270 New_Occurrence_Of
5a1ccfb1
AC
271 (First_Tag_Component (Typ), Loc))),
272
273 Then_Statements =>
274 New_List (New_Constraint_Error (Loc))));
275 end if;
276
277 Next_Actual (Param);
278 end loop;
279 end if;
280 end Apply_Tag_Checks;
281
e18d6a15
JM
282 ------------------------
283 -- Building_Static_DT --
284 ------------------------
285
286 function Building_Static_DT (Typ : Entity_Id) return Boolean is
6214b83b
PMR
287 Root_Typ : Entity_Id := Root_Type (Typ);
288 Static_DT : Boolean;
f2cbd970 289
e18d6a15 290 begin
f2cbd970
JM
291 -- Handle private types
292
293 if Present (Full_View (Root_Typ)) then
294 Root_Typ := Full_View (Root_Typ);
295 end if;
296
65e5747e
PMR
297 Static_DT :=
298 Building_Static_Dispatch_Tables
299 and then Is_Library_Level_Tagged_Type (Typ)
6e818918 300
65e5747e
PMR
301 -- If the type is derived from a CPP class we cannot statically
302 -- build the dispatch tables because we must inherit primitives
303 -- from the CPP side.
6e818918 304
65e5747e 305 and then not Is_CPP_Class (Root_Typ);
6214b83b
PMR
306
307 if not Static_DT then
308 Check_Restriction (Static_Dispatch_Tables, Typ);
309 end if;
310
311 return Static_DT;
e18d6a15
JM
312 end Building_Static_DT;
313
15529d0a
PMR
314 ----------------------------------
315 -- Building_Static_Secondary_DT --
316 ----------------------------------
317
318 function Building_Static_Secondary_DT (Typ : Entity_Id) return Boolean is
6214b83b
PMR
319 Full_Typ : Entity_Id := Typ;
320 Root_Typ : Entity_Id := Root_Type (Typ);
321 Static_DT : Boolean;
15529d0a
PMR
322
323 begin
324 -- Handle private types
325
326 if Present (Full_View (Typ)) then
327 Full_Typ := Full_View (Typ);
328 end if;
329
330 if Present (Full_View (Root_Typ)) then
331 Root_Typ := Full_View (Root_Typ);
332 end if;
333
65e5747e
PMR
334 Static_DT :=
335 Building_Static_DT (Full_Typ)
336 and then not Is_Interface (Full_Typ)
337 and then Has_Interfaces (Full_Typ)
338 and then (Full_Typ = Root_Typ
339 or else not Is_Variable_Size_Record (Etype (Full_Typ)));
6214b83b
PMR
340
341 if not Static_DT
342 and then not Is_Interface (Full_Typ)
343 and then Has_Interfaces (Full_Typ)
344 then
345 Check_Restriction (Static_Dispatch_Tables, Typ);
346 end if;
347
348 return Static_DT;
15529d0a
PMR
349 end Building_Static_Secondary_DT;
350
b2e1beb3
ES
351 ----------------------------------
352 -- Build_Static_Dispatch_Tables --
353 ----------------------------------
354
355 procedure Build_Static_Dispatch_Tables (N : Entity_Id) is
356 Target_List : List_Id;
357
358 procedure Build_Dispatch_Tables (List : List_Id);
359 -- Build the static dispatch table of tagged types found in the list of
360 -- declarations. The generated nodes are added at the end of Target_List
361
362 procedure Build_Package_Dispatch_Tables (N : Node_Id);
363 -- Build static dispatch tables associated with package declaration N
364
365 ---------------------------
366 -- Build_Dispatch_Tables --
367 ---------------------------
368
369 procedure Build_Dispatch_Tables (List : List_Id) is
370 D : Node_Id;
371
372 begin
373 D := First (List);
374 while Present (D) loop
375
376 -- Handle nested packages and package bodies recursively. The
377 -- generated code is placed on the Target_List established for
378 -- the enclosing compilation unit.
379
380 if Nkind (D) = N_Package_Declaration then
381 Build_Package_Dispatch_Tables (D);
382
383 elsif Nkind (D) = N_Package_Body then
384 Build_Dispatch_Tables (Declarations (D));
385
386 elsif Nkind (D) = N_Package_Body_Stub
387 and then Present (Library_Unit (D))
388 then
389 Build_Dispatch_Tables
390 (Declarations (Proper_Body (Unit (Library_Unit (D)))));
391
6782b1ef
AC
392 -- Handle full type declarations and derivations of library level
393 -- tagged types
b2e1beb3 394
4a08c95c
AC
395 elsif Nkind (D) in
396 N_Full_Type_Declaration | N_Derived_Type_Definition
b2e1beb3
ES
397 and then Is_Library_Level_Tagged_Type (Defining_Entity (D))
398 and then Ekind (Defining_Entity (D)) /= E_Record_Subtype
399 and then not Is_Private_Type (Defining_Entity (D))
400 then
9013065b 401 -- We do not generate dispatch tables for the internal types
39f346aa
ES
402 -- created for a type extension with unknown discriminants
403 -- The needed information is shared with the source type,
404 -- See Expand_N_Record_Extension.
405
9013065b
AC
406 if Is_Underlying_Record_View (Defining_Entity (D))
407 or else
408 (not Comes_From_Source (Defining_Entity (D))
409 and then
8737a29a 410 Has_Unknown_Discriminants (Etype (Defining_Entity (D)))
9013065b 411 and then
8737a29a
AC
412 not Comes_From_Source
413 (First_Subtype (Defining_Entity (D))))
39f346aa
ES
414 then
415 null;
39f346aa
ES
416 else
417 Insert_List_After_And_Analyze (Last (Target_List),
418 Make_DT (Defining_Entity (D)));
419 end if;
b2e1beb3
ES
420
421 -- Handle private types of library level tagged types. We must
422 -- exchange the private and full-view to ensure the correct
39314862
ES
423 -- expansion. If the full view is a synchronized type ignore
424 -- the type because the table will be built for the corresponding
425 -- record type, that has its own declaration.
b2e1beb3
ES
426
427 elsif (Nkind (D) = N_Private_Type_Declaration
428 or else Nkind (D) = N_Private_Extension_Declaration)
429 and then Present (Full_View (Defining_Entity (D)))
b2e1beb3
ES
430 then
431 declare
1923d2d6 432 E1 : constant Entity_Id := Defining_Entity (D);
39314862 433 E2 : constant Entity_Id := Full_View (E1);
1923d2d6 434
b2e1beb3 435 begin
39314862
ES
436 if Is_Library_Level_Tagged_Type (E2)
437 and then Ekind (E2) /= E_Record_Subtype
438 and then not Is_Concurrent_Type (E2)
439 then
440 Exchange_Declarations (E1);
441 Insert_List_After_And_Analyze (Last (Target_List),
442 Make_DT (E1));
443 Exchange_Declarations (E2);
444 end if;
b2e1beb3
ES
445 end;
446 end if;
447
448 Next (D);
449 end loop;
450 end Build_Dispatch_Tables;
451
452 -----------------------------------
453 -- Build_Package_Dispatch_Tables --
454 -----------------------------------
455
456 procedure Build_Package_Dispatch_Tables (N : Node_Id) is
457 Spec : constant Node_Id := Specification (N);
458 Id : constant Entity_Id := Defining_Entity (N);
459 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
460 Priv_Decls : constant List_Id := Private_Declarations (Spec);
461
462 begin
463 Push_Scope (Id);
464
465 if Present (Priv_Decls) then
466 Build_Dispatch_Tables (Vis_Decls);
467 Build_Dispatch_Tables (Priv_Decls);
468
469 elsif Present (Vis_Decls) then
470 Build_Dispatch_Tables (Vis_Decls);
471 end if;
472
473 Pop_Scope;
474 end Build_Package_Dispatch_Tables;
475
476 -- Start of processing for Build_Static_Dispatch_Tables
477
478 begin
479 if not Expander_Active
1f110335 480 or else not Tagged_Type_Expansion
b2e1beb3
ES
481 then
482 return;
483 end if;
484
485 if Nkind (N) = N_Package_Declaration then
486 declare
487 Spec : constant Node_Id := Specification (N);
488 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
489 Priv_Decls : constant List_Id := Private_Declarations (Spec);
490
491 begin
492 if Present (Priv_Decls)
493 and then Is_Non_Empty_List (Priv_Decls)
494 then
495 Target_List := Priv_Decls;
496
497 elsif not Present (Vis_Decls) then
498 Target_List := New_List;
499 Set_Private_Declarations (Spec, Target_List);
500 else
501 Target_List := Vis_Decls;
502 end if;
503
504 Build_Package_Dispatch_Tables (N);
505 end;
506
507 else pragma Assert (Nkind (N) = N_Package_Body);
508 Target_List := Declarations (N);
509 Build_Dispatch_Tables (Target_List);
510 end if;
511 end Build_Static_Dispatch_Tables;
512
bed8af19
AC
513 ------------------------------
514 -- Convert_Tag_To_Interface --
515 ------------------------------
516
517 function Convert_Tag_To_Interface
518 (Typ : Entity_Id;
519 Expr : Node_Id) return Node_Id
520 is
521 Loc : constant Source_Ptr := Sloc (Expr);
522 Anon_Type : Entity_Id;
523 Result : Node_Id;
524
525 begin
526 pragma Assert (Is_Class_Wide_Type (Typ)
527 and then Is_Interface (Typ)
528 and then
529 ((Nkind (Expr) = N_Selected_Component
3ce5ca75 530 and then Is_Tag (Entity (Selector_Name (Expr))))
bed8af19
AC
531 or else
532 (Nkind (Expr) = N_Function_Call
3477e0b2 533 and then Is_RTE (Entity (Name (Expr)), RE_Displace))));
bed8af19
AC
534
535 Anon_Type := Create_Itype (E_Anonymous_Access_Type, Expr);
536 Set_Directly_Designated_Type (Anon_Type, Typ);
537 Set_Etype (Anon_Type, Anon_Type);
538 Set_Can_Never_Be_Null (Anon_Type);
539
540 -- Decorate the size and alignment attributes of the anonymous access
6782b1ef 541 -- type, as required by the back end.
bed8af19
AC
542
543 Layout_Type (Anon_Type);
544
545 if Nkind (Expr) = N_Selected_Component
546 and then Is_Tag (Entity (Selector_Name (Expr)))
547 then
548 Result :=
549 Make_Explicit_Dereference (Loc,
550 Unchecked_Convert_To (Anon_Type,
551 Make_Attribute_Reference (Loc,
552 Prefix => Expr,
553 Attribute_Name => Name_Address)));
554 else
555 Result :=
556 Make_Explicit_Dereference (Loc,
557 Unchecked_Convert_To (Anon_Type, Expr));
558 end if;
559
560 return Result;
561 end Convert_Tag_To_Interface;
562
cefce34c
JM
563 -------------------
564 -- CPP_Num_Prims --
565 -------------------
566
567 function CPP_Num_Prims (Typ : Entity_Id) return Nat is
568 CPP_Typ : Entity_Id;
569 Tag_Comp : Entity_Id;
570
571 begin
572 if not Is_Tagged_Type (Typ)
573 or else not Is_CPP_Class (Root_Type (Typ))
574 then
575 return 0;
576
577 else
578 CPP_Typ := Enclosing_CPP_Parent (Typ);
579 Tag_Comp := First_Tag_Component (CPP_Typ);
580
6782b1ef 581 -- If number of primitives already set in the tag component, use it
cefce34c
JM
582
583 if Present (Tag_Comp)
584 and then DT_Entry_Count (Tag_Comp) /= No_Uint
585 then
586 return UI_To_Int (DT_Entry_Count (Tag_Comp));
587
588 -- Otherwise, count the primitives of the enclosing CPP type
589
590 else
591 declare
592 Count : Nat := 0;
593 Elmt : Elmt_Id;
594
595 begin
596 Elmt := First_Elmt (Primitive_Operations (CPP_Typ));
597 while Present (Elmt) loop
598 Count := Count + 1;
599 Next_Elmt (Elmt);
600 end loop;
601
602 return Count;
603 end;
604 end if;
605 end if;
606 end CPP_Num_Prims;
607
758c442c
GD
608 ------------------------------
609 -- Default_Prim_Op_Position --
610 ------------------------------
611
b0efe69e 612 function Default_Prim_Op_Position (E : Entity_Id) return Uint is
758c442c 613 TSS_Name : TSS_Name_Type;
758c442c
GD
614
615 begin
758c442c
GD
616 Get_Name_String (Chars (E));
617 TSS_Name :=
618 TSS_Name_Type
619 (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
620
621 if Chars (E) = Name_uSize then
622 return Uint_1;
623
758c442c 624 elsif TSS_Name = TSS_Stream_Read then
6bed26b5 625 return Uint_2;
758c442c
GD
626
627 elsif TSS_Name = TSS_Stream_Write then
6bed26b5 628 return Uint_3;
758c442c
GD
629
630 elsif TSS_Name = TSS_Stream_Input then
6bed26b5 631 return Uint_4;
758c442c
GD
632
633 elsif TSS_Name = TSS_Stream_Output then
6bed26b5 634 return Uint_5;
758c442c
GD
635
636 elsif Chars (E) = Name_Op_Eq then
6bed26b5 637 return Uint_6;
758c442c
GD
638
639 elsif Chars (E) = Name_uAssign then
6bed26b5 640 return Uint_7;
758c442c
GD
641
642 elsif TSS_Name = TSS_Deep_Adjust then
6bed26b5 643 return Uint_8;
758c442c
GD
644
645 elsif TSS_Name = TSS_Deep_Finalize then
6bed26b5 646 return Uint_9;
758c442c 647
110d0820
BD
648 elsif TSS_Name = TSS_Put_Image then
649 return Uint_10;
650
4fbad0ba
AC
651 -- In VM targets unconditionally allow obtaining the position associated
652 -- with predefined interface primitives since in these platforms any
653 -- tagged type has these primitives.
654
655 elsif Ada_Version >= Ada_2005 or else not Tagged_Type_Expansion then
f4d379b8 656 if Chars (E) = Name_uDisp_Asynchronous_Select then
110d0820 657 return Uint_11;
10b93b2e 658
f4d379b8 659 elsif Chars (E) = Name_uDisp_Conditional_Select then
110d0820 660 return Uint_12;
10b93b2e 661
f4d379b8 662 elsif Chars (E) = Name_uDisp_Get_Prim_Op_Kind then
110d0820 663 return Uint_13;
10b93b2e 664
f4d379b8 665 elsif Chars (E) = Name_uDisp_Get_Task_Id then
110d0820 666 return Uint_14;
10b93b2e 667
80b992ae 668 elsif Chars (E) = Name_uDisp_Requeue then
110d0820 669 return Uint_15;
80b992ae
HK
670
671 elsif Chars (E) = Name_uDisp_Timed_Select then
110d0820 672 return Uint_16;
f4d379b8 673 end if;
758c442c 674 end if;
f4d379b8
HK
675
676 raise Program_Error;
758c442c
GD
677 end Default_Prim_Op_Position;
678
fe683ef6
AC
679 ----------------------
680 -- Elab_Flag_Needed --
681 ----------------------
682
683 function Elab_Flag_Needed (Typ : Entity_Id) return Boolean is
684 begin
685 return Ada_Version >= Ada_2005
686 and then not Is_Interface (Typ)
3ec54569
PMR
687 and then Has_Interfaces (Typ)
688 and then not Building_Static_DT (Typ);
fe683ef6
AC
689 end Elab_Flag_Needed;
690
82c80734
RD
691 -----------------------------
692 -- Expand_Dispatching_Call --
693 -----------------------------
70482933 694
82c80734 695 procedure Expand_Dispatching_Call (Call_Node : Node_Id) is
70482933
RK
696 Loc : constant Source_Ptr := Sloc (Call_Node);
697 Call_Typ : constant Entity_Id := Etype (Call_Node);
698
5b7dd52d
JM
699 Ctrl_Arg : constant Node_Id := Controlling_Argument (Call_Node);
700 Ctrl_Typ : constant Entity_Id := Base_Type (Etype (Ctrl_Arg));
701 Param_List : constant List_Id := Parameter_Associations (Call_Node);
70482933 702
bfef8d0d 703 Subp : Entity_Id;
82c80734
RD
704 CW_Typ : Entity_Id;
705 New_Call : Node_Id;
706 New_Call_Name : Node_Id;
707 New_Params : List_Id := No_List;
708 Param : Node_Id;
709 Res_Typ : Entity_Id;
710 Subp_Ptr_Typ : Entity_Id;
711 Subp_Typ : Entity_Id;
712 Typ : Entity_Id;
713 Eq_Prim_Op : Entity_Id := Empty;
714 Controlling_Tag : Node_Id;
70482933 715
2fd7689c 716 procedure Build_Class_Wide_Check (E : Entity_Id);
ef952fd5
HK
717 -- If the denoted subprogram has a class-wide precondition, generate a
718 -- check using that precondition before the dispatching call, because
2fd7689c
JM
719 -- this is the only class-wide precondition that applies to the call;
720 -- otherwise climb to the ancestors searching for the enclosing
721 -- overridden primitive of E that has a class-wide precondition (and
722 -- use it to generate the check).
304757d2 723
70482933 724 function New_Value (From : Node_Id) return Node_Id;
fbf5a39b
AC
725 -- From is the original Expression. New_Value is equivalent to a call
726 -- to Duplicate_Subexpr with an explicit dereference when From is an
82c80734
RD
727 -- access parameter.
728
304757d2
AC
729 ----------------------------
730 -- Build_Class_Wide_Check --
731 ----------------------------
732
2fd7689c
JM
733 procedure Build_Class_Wide_Check (E : Entity_Id) is
734 Subp : Entity_Id := E;
735
736 function Has_Class_Wide_Precondition
737 (Subp : Entity_Id) return Boolean;
738 -- Evaluates if the dispatching subprogram Subp has a class-wide
739 -- precondition.
740
304757d2
AC
741 function Replace_Formals (N : Node_Id) return Traverse_Result;
742 -- Replace occurrences of the formals of the subprogram by the
743 -- corresponding actuals in the call, given that this check is
744 -- performed outside of the body of the subprogram.
745
1233757a
ES
746 -- If the dispatching call appears in the same scope as the
747 -- declaration of the dispatching subprogram (for example in
31fde973 748 -- the expression of a local expression function), the spec
1233757a
ES
749 -- has not been analyzed yet, in which case we use the Chars
750 -- field to recognize intended occurrences of the formals.
751
2fd7689c
JM
752 ---------------------------------
753 -- Has_Class_Wide_Precondition --
754 ---------------------------------
755
756 function Has_Class_Wide_Precondition
757 (Subp : Entity_Id) return Boolean
758 is
759 Prec : Node_Id := Empty;
760
761 begin
762 if Present (Contract (Subp))
763 and then Present (Pre_Post_Conditions (Contract (Subp)))
764 then
765 Prec := Pre_Post_Conditions (Contract (Subp));
766
767 while Present (Prec) loop
768 exit when Pragma_Name (Prec) = Name_Precondition
769 and then Class_Present (Prec);
770 Prec := Next_Pragma (Prec);
771 end loop;
772 end if;
773
774 return Present (Prec)
775 and then not Is_Ignored (Prec);
776 end Has_Class_Wide_Precondition;
777
304757d2
AC
778 ---------------------
779 -- Replace_Formals --
780 ---------------------
781
782 function Replace_Formals (N : Node_Id) return Traverse_Result is
1233757a
ES
783 A : Node_Id;
784 F : Entity_Id;
304757d2 785 begin
1233757a
ES
786 if Is_Entity_Name (N) then
787 F := First_Formal (Subp);
788 A := First_Actual (Call_Node);
304757d2 789
31fde973 790 if Present (Entity (N)) and then Is_Formal (Entity (N)) then
304757d2
AC
791 while Present (F) loop
792 if F = Entity (N) then
2fd7689c
JM
793 if not Is_Controlling_Actual (N) then
794 Rewrite (N, New_Copy_Tree (A));
795
796 -- If the formal is class-wide, and thus not a
797 -- controlling argument, preserve its type because
798 -- it may appear in a nested call with a class-wide
799 -- parameter.
800
801 if Is_Class_Wide_Type (Etype (F)) then
802 Set_Etype (N, Etype (F));
803
804 -- Conversely, if this is a controlling argument
805 -- (in a dispatching call in the condition) that
806 -- is a dereference, the source is an access-to-
807 -- -class-wide type, so preserve the dispatching
808 -- nature of the call in the rewritten condition.
809
810 elsif Nkind (Parent (N)) = N_Explicit_Dereference
811 and then Is_Controlling_Actual (Parent (N))
812 then
813 Set_Controlling_Argument (Parent (Parent (N)),
814 Parent (N));
815 end if;
816
817 -- Ensure that the type of the controlling actual
818 -- matches the type of the controlling formal of the
819 -- parent primitive Subp defining the class-wide
820 -- precondition.
821
822 elsif Is_Class_Wide_Type (Etype (A)) then
823 Rewrite (N,
824 Convert_To
825 (Class_Wide_Type (Etype (F)),
826 New_Copy_Tree (A)));
827
828 else
829 Rewrite (N,
830 Convert_To
831 (Etype (F),
832 New_Copy_Tree (A)));
83b77c5c
AC
833 end if;
834
304757d2
AC
835 exit;
836 end if;
ef952fd5 837
304757d2
AC
838 Next_Formal (F);
839 Next_Actual (A);
840 end loop;
1233757a 841
31fde973
GD
842 -- If the node is not analyzed, recognize occurrences of a
843 -- formal by name, as would be done when resolving the aspect
844 -- expression in the context of the subprogram.
1233757a
ES
845
846 elsif not Analyzed (N)
847 and then Nkind (N) = N_Identifier
848 and then No (Entity (N))
849 then
850 while Present (F) loop
851 if Chars (N) = Chars (F) then
852 Rewrite (N, New_Copy_Tree (A));
853 return Skip;
854 end if;
855
856 Next_Formal (F);
857 Next_Actual (A);
858 end loop;
859 end if;
304757d2
AC
860 end if;
861
862 return OK;
863 end Replace_Formals;
864
865 procedure Update is new Traverse_Proc (Replace_Formals);
ef952fd5
HK
866
867 -- Local variables
868
869 Str_Loc : constant String := Build_Location_String (Loc);
870
871 Cond : Node_Id;
872 Msg : Node_Id;
873 Prec : Node_Id;
874
875 -- Start of processing for Build_Class_Wide_Check
876
304757d2 877 begin
2fd7689c
JM
878 -- Climb searching for the enclosing class-wide precondition
879
880 while not Has_Class_Wide_Precondition (Subp)
881 and then Present (Overridden_Operation (Subp))
882 loop
883 Subp := Overridden_Operation (Subp);
884 end loop;
304757d2
AC
885
886 -- Locate class-wide precondition, if any
887
888 if Present (Contract (Subp))
889 and then Present (Pre_Post_Conditions (Contract (Subp)))
890 then
891 Prec := Pre_Post_Conditions (Contract (Subp));
892
893 while Present (Prec) loop
894 exit when Pragma_Name (Prec) = Name_Precondition
895 and then Class_Present (Prec);
896 Prec := Next_Pragma (Prec);
897 end loop;
898
db38c41b 899 if No (Prec) or else Is_Ignored (Prec) then
304757d2
AC
900 return;
901 end if;
902
903 -- The expression for the precondition is analyzed within the
ef952fd5
HK
904 -- generated pragma. The message text is the last parameter of
905 -- the generated pragma, indicating source of precondition.
304757d2 906
ef952fd5
HK
907 Cond :=
908 New_Copy_Tree
909 (Expression (First (Pragma_Argument_Associations (Prec))));
304757d2
AC
910 Update (Cond);
911
912 -- Build message indicating the failed precondition and the
913 -- dispatching call that caused it.
914
915 Msg := Expression (Last (Pragma_Argument_Associations (Prec)));
916 Name_Len := 0;
917 Append (Global_Name_Buffer, Strval (Msg));
918 Append (Global_Name_Buffer, " in dispatching call at ");
919 Append (Global_Name_Buffer, Str_Loc);
920 Msg := Make_String_Literal (Loc, Name_Buffer (1 .. Name_Len));
921
922 Insert_Action (Call_Node,
ef952fd5
HK
923 Make_If_Statement (Loc,
924 Condition => Make_Op_Not (Loc, Cond),
925 Then_Statements => New_List (
926 Make_Procedure_Call_Statement (Loc,
927 Name =>
928 New_Occurrence_Of (RTE (RE_Raise_Assert_Failure), Loc),
929 Parameter_Associations => New_List (Msg)))));
304757d2
AC
930 end if;
931 end Build_Class_Wide_Check;
932
fbf5a39b
AC
933 ---------------
934 -- New_Value --
935 ---------------
936
70482933
RK
937 function New_Value (From : Node_Id) return Node_Id is
938 Res : constant Node_Id := Duplicate_Subexpr (From);
70482933
RK
939 begin
940 if Is_Access_Type (Etype (From)) then
bfef8d0d
JM
941 return
942 Make_Explicit_Dereference (Sloc (From),
943 Prefix => Res);
70482933
RK
944 else
945 return Res;
946 end if;
947 end New_Value;
948
327503f1
JM
949 -- Local variables
950
7665e4bd 951 New_Node : Node_Id;
a6d25cad 952 SCIL_Node : Node_Id := Empty;
7665e4bd 953 SCIL_Related_Node : Node_Id := Call_Node;
327503f1 954
82c80734 955 -- Start of processing for Expand_Dispatching_Call
70482933
RK
956
957 begin
d0dd5209
JM
958 if No_Run_Time_Mode then
959 Error_Msg_CRT ("tagged types", Call_Node);
960 return;
961 end if;
962
6782b1ef
AC
963 -- Expand_Dispatching_Call is called directly from the semantics, so we
964 -- only proceed if the expander is active.
dee4682a 965
4460a9bc 966 if not Expander_Active
c199ccf7
AC
967
968 -- And there is no need to expand the call if we are compiling under
969 -- restriction No_Dispatching_Calls; the semantic analyzer has
970 -- previously notified the violation of this restriction.
971
dee4682a 972 or else Restriction_Active (No_Dispatching_Calls)
7af1cf83
AC
973
974 -- No action needed if the dispatching call has been already expanded
975
976 or else Is_Expanded_Dispatching_Call (Name (Call_Node))
dee4682a
JM
977 then
978 return;
979 end if;
b0efe69e 980
bfef8d0d
JM
981 -- Set subprogram. If this is an inherited operation that was
982 -- overridden, the body that is being called is its alias.
983
984 Subp := Entity (Name (Call_Node));
70482933
RK
985
986 if Present (Alias (Subp))
987 and then Is_Inherited_Operation (Subp)
988 and then No (DTC_Entity (Subp))
989 then
990 Subp := Alias (Subp);
991 end if;
992
2fd7689c 993 Build_Class_Wide_Check (Subp);
304757d2 994
82c80734 995 -- Definition of the class-wide type and the tagged type
70482933 996
82c80734
RD
997 -- If the controlling argument is itself a tag rather than a tagged
998 -- object, then use the class-wide type associated with the subprogram's
999 -- controlling type. This case can occur when a call to an inherited
1000 -- primitive has an actual that originated from a default parameter
1001 -- given by a tag-indeterminate call and when there is no other
1002 -- controlling argument providing the tag (AI-239 requires dispatching).
1003 -- This capability of dispatching directly by tag is also needed by the
1004 -- implementation of AI-260 (for the generic dispatching constructors).
1005
3477e0b2
PT
1006 if Is_RTE (Ctrl_Typ, RE_Tag)
1007 or else Is_RTE (Ctrl_Typ, RE_Interface_Tag)
758c442c 1008 then
bfef8d0d 1009 CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));
82c80734 1010
d0dd5209
JM
1011 -- Class_Wide_Type is applied to the expressions used to initialize
1012 -- CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
1013 -- there are cases where the controlling type is resolved to a specific
1014 -- type (such as for designated types of arguments such as CW'Access).
1015
5b7dd52d
JM
1016 elsif Is_Access_Type (Ctrl_Typ) then
1017 CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));
82c80734 1018
70482933 1019 else
5b7dd52d 1020 CW_Typ := Class_Wide_Type (Ctrl_Typ);
70482933
RK
1021 end if;
1022
98ee6f8d 1023 Typ := Find_Specific_Type (CW_Typ);
10b93b2e 1024
70482933
RK
1025 if not Is_Limited_Type (Typ) then
1026 Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
1027 end if;
1028
dee4682a
JM
1029 -- Dispatching call to C++ primitive. Create a new parameter list
1030 -- with no tag checks.
70482933 1031
5a1ccfb1
AC
1032 New_Params := New_List;
1033
dee4682a 1034 if Is_CPP_Class (Typ) then
70482933
RK
1035 Param := First_Actual (Call_Node);
1036 while Present (Param) loop
758c442c 1037 Append_To (New_Params, Relocate_Node (Param));
70482933
RK
1038 Next_Actual (Param);
1039 end loop;
1040
dee4682a
JM
1041 -- Dispatching call to Ada primitive
1042
70482933 1043 elsif Present (Param_List) then
5a1ccfb1 1044 Apply_Tag_Checks (Call_Node);
70482933 1045
70482933
RK
1046 Param := First_Actual (Call_Node);
1047 while Present (Param) loop
1048
e6d5d940
GD
1049 -- Cases in which we may have generated run-time checks. Note that
1050 -- we strip any qualification from Param before comparing with the
1051 -- already-stripped controlling argument.
1052
1053 if Unqualify (Param) = Ctrl_Arg or else Subp = Eq_Prim_Op then
fbf5a39b
AC
1054 Append_To (New_Params,
1055 Duplicate_Subexpr_Move_Checks (Param));
70482933 1056
75a64833
AC
1057 elsif Nkind (Parent (Param)) /= N_Parameter_Association
1058 or else not Is_Accessibility_Actual (Parent (Param))
1059 then
70482933
RK
1060 Append_To (New_Params, Relocate_Node (Param));
1061 end if;
1062
1063 Next_Actual (Param);
1064 end loop;
1065 end if;
1066
1067 -- Generate the appropriate subprogram pointer type
1068
b0efe69e 1069 if Etype (Subp) = Typ then
70482933
RK
1070 Res_Typ := CW_Typ;
1071 else
82c80734 1072 Res_Typ := Etype (Subp);
70482933
RK
1073 end if;
1074
4da17013 1075 Subp_Typ := Create_Itype (E_Subprogram_Type, Call_Node);
70482933
RK
1076 Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
1077 Set_Etype (Subp_Typ, Res_Typ);
70482933 1078 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
28dd0055
EB
1079 Set_Convention (Subp_Typ, Convention (Subp));
1080
1081 -- Notify gigi that the designated type is a dispatching primitive
1082
1083 Set_Is_Dispatch_Table_Entity (Subp_Typ);
70482933
RK
1084
1085 -- Create a new list of parameters which is a copy of the old formal
1086 -- list including the creation of a new set of matching entities.
1087
1088 declare
765005dd
JM
1089 Old_Formal : Entity_Id := First_Formal (Subp);
1090 New_Formal : Entity_Id;
1091 Last_Formal : Entity_Id := Empty;
70482933
RK
1092
1093 begin
1094 if Present (Old_Formal) then
1095 New_Formal := New_Copy (Old_Formal);
1096 Set_First_Entity (Subp_Typ, New_Formal);
1097 Param := First_Actual (Call_Node);
1098
1099 loop
1100 Set_Scope (New_Formal, Subp_Typ);
1101
1102 -- Change all the controlling argument types to be class-wide
82c80734 1103 -- to avoid a recursion in dispatching.
70482933 1104
82c80734 1105 if Is_Controlling_Formal (New_Formal) then
70482933
RK
1106 Set_Etype (New_Formal, Etype (Param));
1107 end if;
1108
f2cbd970
JM
1109 -- If the type of the formal is an itype, there was code here
1110 -- introduced in 1998 in revision 1.46, to create a new itype
1111 -- by copy. This seems useless, and in fact leads to semantic
1112 -- errors when the itype is the completion of a type derived
1113 -- from a private type.
70482933 1114
765005dd 1115 Last_Formal := New_Formal;
70482933
RK
1116 Next_Formal (Old_Formal);
1117 exit when No (Old_Formal);
1118
3f6d1daa
JS
1119 Link_Entities (New_Formal, New_Copy (Old_Formal));
1120 Next_Entity (New_Formal);
1121 Next_Actual (Param);
70482933 1122 end loop;
bfef8d0d 1123
3f6d1daa 1124 Unlink_Next_Entity (New_Formal);
765005dd 1125 Set_Last_Entity (Subp_Typ, Last_Formal);
d0dd5209 1126 end if;
70482933 1127
d0dd5209 1128 -- Now that the explicit formals have been duplicated, any extra
765005dd
JM
1129 -- formals needed by the subprogram must be duplicated; we know
1130 -- that extra formals are available because they were added when
1131 -- the tagged type was frozen (see Expand_Freeze_Record_Type).
70482933 1132
765005dd
JM
1133 pragma Assert (Is_Frozen (Typ));
1134
1135 -- Warning: The addition of the extra formals cannot be performed
1136 -- here invoking Create_Extra_Formals since we must ensure that all
1137 -- the extra formals of the pointer type and the target subprogram
1138 -- match (and for functions that return a tagged type the profile of
1139 -- the built subprogram type always returns a class-wide type, which
1140 -- may affect the addition of some extra formals).
1141
1142 if Present (Last_Formal)
1143 and then Present (Extra_Formal (Last_Formal))
1144 then
1145 Old_Formal := Extra_Formal (Last_Formal);
1146 New_Formal := New_Copy (Old_Formal);
b93d80bc 1147 Set_Scope (New_Formal, Subp_Typ);
d0dd5209 1148
765005dd
JM
1149 Set_Extra_Formal (Last_Formal, New_Formal);
1150 Set_Extra_Formals (Subp_Typ, New_Formal);
1151
01264f72
JM
1152 if Ekind (Subp) = E_Function
1153 and then Present (Extra_Accessibility_Of_Result (Subp))
1154 and then Extra_Accessibility_Of_Result (Subp) = Old_Formal
1155 then
1156 Set_Extra_Accessibility_Of_Result (Subp_Typ, New_Formal);
1157 end if;
1158
765005dd
JM
1159 Old_Formal := Extra_Formal (Old_Formal);
1160 while Present (Old_Formal) loop
1161 Set_Extra_Formal (New_Formal, New_Copy (Old_Formal));
1162 New_Formal := Extra_Formal (New_Formal);
1163 Set_Scope (New_Formal, Subp_Typ);
1164
01264f72
JM
1165 if Ekind (Subp) = E_Function
1166 and then Present (Extra_Accessibility_Of_Result (Subp))
1167 and then Extra_Accessibility_Of_Result (Subp) = Old_Formal
1168 then
1169 Set_Extra_Accessibility_Of_Result (Subp_Typ, New_Formal);
1170 end if;
1171
765005dd
JM
1172 Old_Formal := Extra_Formal (Old_Formal);
1173 end loop;
1174 end if;
70482933
RK
1175 end;
1176
4da17013
AC
1177 -- Complete description of pointer type, including size information, as
1178 -- must be done with itypes to prevent order-of-elaboration anomalies
1179 -- in gigi.
1180
70482933
RK
1181 Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
1182 Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
1923d2d6 1183 Set_Convention (Subp_Ptr_Typ, Convention (Subp_Typ));
4da17013 1184 Layout_Type (Subp_Ptr_Typ);
70482933 1185
b0efe69e
JM
1186 -- If the controlling argument is a value of type Ada.Tag or an abstract
1187 -- interface class-wide type then use it directly. Otherwise, the tag
1188 -- must be extracted from the controlling object.
82c80734 1189
3477e0b2
PT
1190 if Is_RTE (Ctrl_Typ, RE_Tag)
1191 or else Is_RTE (Ctrl_Typ, RE_Interface_Tag)
b0efe69e
JM
1192 then
1193 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
1194
dee4682a
JM
1195 -- Extract the tag from an unchecked type conversion. Done to avoid
1196 -- the expansion of additional code just to obtain the value of such
1197 -- tag because the current management of interface type conversions
1198 -- generates in some cases this unchecked type conversion with the
1199 -- tag of the object (see Expand_Interface_Conversion).
1200
1201 elsif Nkind (Ctrl_Arg) = N_Unchecked_Type_Conversion
1202 and then
3477e0b2 1203 (Is_RTE (Etype (Expression (Ctrl_Arg)), RE_Tag)
dee4682a 1204 or else
3477e0b2 1205 Is_RTE (Etype (Expression (Ctrl_Arg)), RE_Interface_Tag))
dee4682a
JM
1206 then
1207 Controlling_Tag := Duplicate_Subexpr (Expression (Ctrl_Arg));
1208
b0efe69e
JM
1209 -- Ada 2005 (AI-251): Abstract interface class-wide type
1210
5b7dd52d
JM
1211 elsif Is_Interface (Ctrl_Typ)
1212 and then Is_Class_Wide_Type (Ctrl_Typ)
758c442c 1213 then
82c80734
RD
1214 Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);
1215
f715a5bd
EB
1216 elsif Is_Access_Type (Ctrl_Typ) then
1217 Controlling_Tag :=
1218 Make_Selected_Component (Loc,
1219 Prefix =>
1220 Make_Explicit_Dereference (Loc,
1221 Duplicate_Subexpr_Move_Checks (Ctrl_Arg)),
1222 Selector_Name => New_Occurrence_Of (DTC_Entity (Subp), Loc));
1223
82c80734
RD
1224 else
1225 Controlling_Tag :=
1226 Make_Selected_Component (Loc,
a73734f5 1227 Prefix => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
e4494292 1228 Selector_Name => New_Occurrence_Of (DTC_Entity (Subp), Loc));
82c80734
RD
1229 end if;
1230
a73734f5 1231 -- Handle dispatching calls to predefined primitives
70482933 1232
bfef8d0d
JM
1233 if Is_Predefined_Dispatching_Operation (Subp)
1234 or else Is_Predefined_Dispatching_Alias (Subp)
1235 then
d06b3b1d
JM
1236 Build_Get_Predefined_Prim_Op_Address (Loc,
1237 Tag_Node => Controlling_Tag,
1238 Position => DT_Position (Subp),
1239 New_Node => New_Node);
70482933 1240
dee4682a 1241 -- Handle dispatching calls to user-defined primitives
b0efe69e
JM
1242
1243 else
d06b3b1d 1244 Build_Get_Prim_Op_Address (Loc,
38171f43 1245 Typ => Underlying_Type (Find_Dispatching_Type (Subp)),
d06b3b1d
JM
1246 Tag_Node => Controlling_Tag,
1247 Position => DT_Position (Subp),
1248 New_Node => New_Node);
b0efe69e 1249 end if;
70482933 1250
d06b3b1d
JM
1251 New_Call_Name :=
1252 Unchecked_Convert_To (Subp_Ptr_Typ, New_Node);
1253
7665e4bd
AC
1254 -- Generate the SCIL node for this dispatching call. Done now because
1255 -- attribute SCIL_Controlling_Tag must be set after the new call name
1256 -- is built to reference the nodes that will see the SCIL backend
1257 -- (because Build_Get_Prim_Op_Address generates an unchecked type
1258 -- conversion which relocates the controlling tag node).
70482933 1259
d06b3b1d 1260 if Generate_SCIL then
7665e4bd
AC
1261 SCIL_Node := Make_SCIL_Dispatching_Call (Sloc (Call_Node));
1262 Set_SCIL_Entity (SCIL_Node, Typ);
1263 Set_SCIL_Target_Prim (SCIL_Node, Subp);
d06b3b1d
JM
1264
1265 -- Common case: the controlling tag is the tag of an object
1266 -- (for example, obj.tag)
1267
1268 if Nkind (Controlling_Tag) = N_Selected_Component then
1269 Set_SCIL_Controlling_Tag (SCIL_Node, Controlling_Tag);
1270
1271 -- Handle renaming of selected component
1272
1273 elsif Nkind (Controlling_Tag) = N_Identifier
a73734f5
AC
1274 and then Nkind (Parent (Entity (Controlling_Tag))) =
1275 N_Object_Renaming_Declaration
1276 and then Nkind (Name (Parent (Entity (Controlling_Tag)))) =
1277 N_Selected_Component
d06b3b1d
JM
1278 then
1279 Set_SCIL_Controlling_Tag (SCIL_Node,
1280 Name (Parent (Entity (Controlling_Tag))));
1281
1282 -- If the controlling tag is an identifier, the SCIL node references
1283 -- the corresponding object or parameter declaration
1284
1285 elsif Nkind (Controlling_Tag) = N_Identifier
4a08c95c
AC
1286 and then Nkind (Parent (Entity (Controlling_Tag))) in
1287 N_Object_Declaration | N_Parameter_Specification
d06b3b1d
JM
1288 then
1289 Set_SCIL_Controlling_Tag (SCIL_Node,
1290 Parent (Entity (Controlling_Tag)));
1291
1292 -- If the controlling tag is a dereference, the SCIL node references
1293 -- the corresponding object or parameter declaration
1294
1295 elsif Nkind (Controlling_Tag) = N_Explicit_Dereference
1296 and then Nkind (Prefix (Controlling_Tag)) = N_Identifier
4a08c95c
AC
1297 and then Nkind (Parent (Entity (Prefix (Controlling_Tag)))) in
1298 N_Object_Declaration | N_Parameter_Specification
d06b3b1d
JM
1299 then
1300 Set_SCIL_Controlling_Tag (SCIL_Node,
1301 Parent (Entity (Prefix (Controlling_Tag))));
1302
1303 -- For a direct reference of the tag of the type the SCIL node
308e6f3a 1304 -- references the internal object declaration containing the tag
d06b3b1d
JM
1305 -- of the type.
1306
1307 elsif Nkind (Controlling_Tag) = N_Attribute_Reference
1308 and then Attribute_Name (Controlling_Tag) = Name_Tag
1309 then
1310 Set_SCIL_Controlling_Tag (SCIL_Node,
1311 Parent
a73734f5
AC
1312 (Node
1313 (First_Elmt
1314 (Access_Disp_Table (Entity (Prefix (Controlling_Tag)))))));
d06b3b1d
JM
1315
1316 -- Interfaces are not supported. For now we leave the SCIL node
1317 -- decorated with the Controlling_Tag. More work needed here???
1318
1319 elsif Is_Interface (Etype (Controlling_Tag)) then
1320 Set_SCIL_Controlling_Tag (SCIL_Node, Controlling_Tag);
1321
1322 else
1323 pragma Assert (False);
1324 null;
1325 end if;
1326 end if;
1327
1328 if Nkind (Call_Node) = N_Function_Call then
d0dd5209
JM
1329 New_Call :=
1330 Make_Function_Call (Loc,
a73734f5 1331 Name => New_Call_Name,
d0dd5209 1332 Parameter_Associations => New_Params);
70482933 1333
d0dd5209
JM
1334 -- If this is a dispatching "=", we must first compare the tags so
1335 -- we generate: x.tag = y.tag and then x = y
70482933 1336
d0dd5209
JM
1337 if Subp = Eq_Prim_Op then
1338 Param := First_Actual (Call_Node);
758c442c 1339 New_Call :=
d0dd5209
JM
1340 Make_And_Then (Loc,
1341 Left_Opnd =>
1342 Make_Op_Eq (Loc,
1343 Left_Opnd =>
1344 Make_Selected_Component (Loc,
a73734f5 1345 Prefix => New_Value (Param),
d0dd5209 1346 Selector_Name =>
e4494292 1347 New_Occurrence_Of (First_Tag_Component (Typ),
d0dd5209 1348 Loc)),
70482933 1349
d0dd5209
JM
1350 Right_Opnd =>
1351 Make_Selected_Component (Loc,
a73734f5 1352 Prefix =>
d0dd5209
JM
1353 Unchecked_Convert_To (Typ,
1354 New_Value (Next_Actual (Param))),
1355 Selector_Name =>
e4494292 1356 New_Occurrence_Of
a73734f5 1357 (First_Tag_Component (Typ), Loc))),
d0dd5209 1358 Right_Opnd => New_Call);
7665e4bd
AC
1359
1360 SCIL_Related_Node := Right_Opnd (New_Call);
70482933
RK
1361 end if;
1362
1363 else
1364 New_Call :=
1365 Make_Procedure_Call_Statement (Loc,
a73734f5 1366 Name => New_Call_Name,
70482933
RK
1367 Parameter_Associations => New_Params);
1368 end if;
1369
9c41193c
JM
1370 -- Register the dispatching call in the call graph nodes table
1371
1372 Register_CG_Node (Call_Node);
1373
70482933 1374 Rewrite (Call_Node, New_Call);
d0dd5209 1375
7665e4bd
AC
1376 -- Associate the SCIL node of this dispatching call
1377
1378 if Generate_SCIL then
1379 Set_SCIL_Node (SCIL_Related_Node, SCIL_Node);
1380 end if;
1381
6782b1ef
AC
1382 -- Suppress all checks during the analysis of the expanded code to avoid
1383 -- the generation of spurious warnings under ZFP run-time.
d0dd5209
JM
1384
1385 Analyze_And_Resolve (Call_Node, Call_Typ, Suppress => All_Checks);
82c80734 1386 end Expand_Dispatching_Call;
70482933 1387
758c442c
GD
1388 ---------------------------------
1389 -- Expand_Interface_Conversion --
1390 ---------------------------------
1391
f6f4d8d4
JM
1392 procedure Expand_Interface_Conversion (N : Node_Id) is
1393 function Underlying_Record_Type (Typ : Entity_Id) return Entity_Id;
72a26637 1394 -- Return the underlying record type of Typ
758c442c 1395
f6f4d8d4
JM
1396 ----------------------------
1397 -- Underlying_Record_Type --
1398 ----------------------------
758c442c 1399
f6f4d8d4
JM
1400 function Underlying_Record_Type (Typ : Entity_Id) return Entity_Id is
1401 E : Entity_Id := Typ;
758c442c 1402
f6f4d8d4 1403 begin
4ac62786 1404 -- Handle access types
758c442c 1405
f6f4d8d4 1406 if Is_Access_Type (E) then
4ac62786 1407 E := Directly_Designated_Type (E);
f6f4d8d4 1408 end if;
758c442c 1409
f6f4d8d4
JM
1410 -- Handle class-wide types. This conversion can appear explicitly in
1411 -- the source code. Example: I'Class (Obj)
758c442c 1412
f6f4d8d4
JM
1413 if Is_Class_Wide_Type (E) then
1414 E := Root_Type (E);
1415 end if;
10b93b2e 1416
f6f4d8d4
JM
1417 -- If the target type is a tagged synchronized type, the dispatch
1418 -- table info is in the corresponding record type.
0f300ef5 1419
f6f4d8d4
JM
1420 if Is_Concurrent_Type (E) then
1421 E := Corresponding_Record_Type (E);
1422 end if;
0f300ef5 1423
f6f4d8d4
JM
1424 -- Handle private types
1425
1426 E := Underlying_Type (E);
38171f43 1427
f6f4d8d4 1428 -- Handle subtypes
38171f43 1429
f6f4d8d4
JM
1430 return Base_Type (E);
1431 end Underlying_Record_Type;
1432
1433 -- Local variables
1434
1435 Loc : constant Source_Ptr := Sloc (N);
1436 Etyp : constant Entity_Id := Etype (N);
1437 Operand : constant Node_Id := Expression (N);
1438 Operand_Typ : Entity_Id := Etype (Operand);
1439 Func : Node_Id;
1440 Iface_Typ : constant Entity_Id := Underlying_Record_Type (Etype (N));
1441 Iface_Tag : Entity_Id;
1442 Is_Static : Boolean;
1443
1444 -- Start of processing for Expand_Interface_Conversion
1445
1446 begin
ea08fcdc
AC
1447 -- Freeze the entity associated with the target interface to have
1448 -- available the attribute Access_Disp_Table.
1449
1450 Freeze_Before (N, Iface_Typ);
1451
f6f4d8d4
JM
1452 -- Ada 2005 (AI-345): Handle synchronized interface type derivations
1453
1454 if Is_Concurrent_Type (Operand_Typ) then
1455 Operand_Typ := Base_Type (Corresponding_Record_Type (Operand_Typ));
1456 end if;
1457
1a779058
AC
1458 -- No displacement of the pointer to the object needed when the type of
1459 -- the operand is not an interface type and the interface is one of
1460 -- its parent types (since they share the primary dispatch table).
1461
1462 declare
1463 Opnd : Entity_Id := Operand_Typ;
1464
1465 begin
1466 if Is_Access_Type (Opnd) then
1467 Opnd := Designated_Type (Opnd);
1468 end if;
1469
2d9c4206
JM
1470 Opnd := Underlying_Record_Type (Opnd);
1471
1a779058
AC
1472 if not Is_Interface (Opnd)
1473 and then Is_Ancestor (Iface_Typ, Opnd, Use_Full_View => True)
1474 then
1475 return;
1476 end if;
2d9c4206
JM
1477
1478 -- When the type of the operand and the target interface type match,
1479 -- it is generally safe to skip generating code to displace the
1480 -- pointer to the object to reference the secondary dispatch table
1481 -- associated with the target interface type. The exception to this
1482 -- general rule is when the underlying object of the type conversion
1483 -- is an object built by means of a dispatching constructor (since in
1484 -- such case the expansion of the constructor call is a direct call
1485 -- to an object primitive, i.e. without thunks, and the expansion of
1486 -- the constructor call adds an explicit conversion to the target
1487 -- interface type to force the displacement of the pointer to the
1488 -- object to reference the corresponding secondary dispatch table
1489 -- (cf. Make_DT and Expand_Dispatching_Constructor_Call)).
1490
1491 -- At this stage we cannot identify whether the underlying object is
1492 -- a BIP object and hence we cannot skip generating the code to try
1493 -- displacing the pointer to the object. However, under configurable
1494 -- runtime it is safe to skip generating code to displace the pointer
1495 -- to the object, because generic dispatching constructors are not
1496 -- supported.
1497
c7862167 1498 if Opnd = Iface_Typ and then not RTE_Available (RE_Displace) then
2d9c4206
JM
1499 return;
1500 end if;
1a779058
AC
1501 end;
1502
f6f4d8d4
JM
1503 -- Evaluate if we can statically displace the pointer to the object
1504
1505 declare
1506 Opnd_Typ : constant Node_Id := Underlying_Record_Type (Operand_Typ);
1507
1508 begin
1509 Is_Static :=
1510 not Is_Interface (Opnd_Typ)
1511 and then Interface_Present_In_Ancestor
1512 (Typ => Opnd_Typ,
1513 Iface => Iface_Typ)
1514 and then (Etype (Opnd_Typ) = Opnd_Typ
1515 or else not
1516 Is_Variable_Size_Record (Etype (Opnd_Typ)));
1517 end;
758c442c 1518
1f110335 1519 if not Tagged_Type_Expansion then
d0dd5209 1520 return;
9d2a2071 1521
304757d2 1522 -- A static conversion to an interface type that is not class-wide is
9d2a2071
AC
1523 -- curious but legal if the interface operation is a null procedure.
1524 -- If the operation is abstract it will be rejected later.
1525
1526 elsif Is_Static
1527 and then Is_Interface (Etype (N))
1528 and then not Is_Class_Wide_Type (Etype (N))
1529 and then Comes_From_Source (N)
1530 then
1531 Rewrite (N, Unchecked_Convert_To (Etype (N), N));
1532 Analyze (N);
1533 return;
d0dd5209
JM
1534 end if;
1535
4d744221 1536 if not Is_Static then
b0efe69e 1537
304757d2 1538 -- Give error if configurable run-time and Displace not available
b0efe69e
JM
1539
1540 if not RTE_Available (RE_Displace) then
f2cbd970 1541 Error_Msg_CRT ("dynamic interface conversion", N);
b0efe69e
JM
1542 return;
1543 end if;
1544
d0dd5209
JM
1545 -- Handle conversion of access-to-class-wide interface types. Target
1546 -- can be an access to an object or an access to another class-wide
1547 -- interface (see -1- and -2- in the following example):
bfef8d0d
JM
1548
1549 -- type Iface1_Ref is access all Iface1'Class;
1550 -- type Iface2_Ref is access all Iface1'Class;
1551
1552 -- Acc1 : Iface1_Ref := new ...
1553 -- Obj : Obj_Ref := Obj_Ref (Acc); -- 1
1554 -- Acc2 : Iface2_Ref := Iface2_Ref (Acc); -- 2
1555
1556 if Is_Access_Type (Operand_Typ) then
bfef8d0d
JM
1557 Rewrite (N,
1558 Unchecked_Convert_To (Etype (N),
1559 Make_Function_Call (Loc,
e4494292 1560 Name => New_Occurrence_Of (RTE (RE_Displace), Loc),
bfef8d0d
JM
1561 Parameter_Associations => New_List (
1562
1563 Unchecked_Convert_To (RTE (RE_Address),
1564 Relocate_Node (Expression (N))),
1565
1566 New_Occurrence_Of
1567 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
1568 Loc)))));
1569
1570 Analyze (N);
1571 return;
1572 end if;
1573
4d744221
JM
1574 Rewrite (N,
1575 Make_Function_Call (Loc,
e4494292 1576 Name => New_Occurrence_Of (RTE (RE_Displace), Loc),
4d744221
JM
1577 Parameter_Associations => New_List (
1578 Make_Attribute_Reference (Loc,
1579 Prefix => Relocate_Node (Expression (N)),
1580 Attribute_Name => Name_Address),
bfef8d0d 1581
4d744221
JM
1582 New_Occurrence_Of
1583 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
1584 Loc))));
1585
1586 Analyze (N);
1587
6782b1ef
AC
1588 -- If target is a class-wide interface, change the type of the data
1589 -- returned by IW_Convert to indicate this is a dispatching call.
4d744221 1590
b2e1beb3
ES
1591 declare
1592 New_Itype : Entity_Id;
4d744221 1593
b2e1beb3
ES
1594 begin
1595 New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
f2cbd970 1596 Set_Etype (New_Itype, New_Itype);
b2e1beb3 1597 Set_Directly_Designated_Type (New_Itype, Etyp);
4d744221 1598
b2e1beb3
ES
1599 Rewrite (N,
1600 Make_Explicit_Dereference (Loc,
1601 Prefix =>
1602 Unchecked_Convert_To (New_Itype, Relocate_Node (N))));
1603 Analyze (N);
1604 Freeze_Itype (New_Itype, N);
1605
1606 return;
1607 end;
4d744221
JM
1608 end if;
1609
10b93b2e 1610 Iface_Tag := Find_Interface_Tag (Operand_Typ, Iface_Typ);
d58008d2 1611 pragma Assert (Present (Iface_Tag));
758c442c 1612
10b93b2e 1613 -- Keep separate access types to interfaces because one internal
bed8af19 1614 -- function is used to handle the null value (see following comments)
10b93b2e
HK
1615
1616 if not Is_Access_Type (Etype (N)) then
bed8af19 1617
6782b1ef
AC
1618 -- Statically displace the pointer to the object to reference the
1619 -- component containing the secondary dispatch table.
bed8af19 1620
10b93b2e 1621 Rewrite (N,
bed8af19 1622 Convert_Tag_To_Interface (Class_Wide_Type (Iface_Typ),
10b93b2e
HK
1623 Make_Selected_Component (Loc,
1624 Prefix => Relocate_Node (Expression (N)),
bed8af19 1625 Selector_Name => New_Occurrence_Of (Iface_Tag, Loc))));
10b93b2e
HK
1626
1627 else
a90bd866
RD
1628 -- Build internal function to handle the case in which the actual is
1629 -- null. If the actual is null returns null because no displacement
1630 -- is required; otherwise performs a type conversion that will be
1631 -- expanded in the code that returns the value of the displaced
1632 -- actual. That is:
10b93b2e 1633
bfef8d0d 1634 -- function Func (O : Address) return Iface_Typ is
b2e1beb3
ES
1635 -- type Op_Typ is access all Operand_Typ;
1636 -- Aux : Op_Typ := To_Op_Typ (O);
10b93b2e 1637 -- begin
bfef8d0d 1638 -- if O = Null_Address then
10b93b2e
HK
1639 -- return null;
1640 -- else
b2e1beb3 1641 -- return Iface_Typ!(Aux.Iface_Tag'Address);
10b93b2e
HK
1642 -- end if;
1643 -- end Func;
1644
bfef8d0d 1645 declare
b2e1beb3
ES
1646 Desig_Typ : Entity_Id;
1647 Fent : Entity_Id;
1648 New_Typ_Decl : Node_Id;
b2e1beb3
ES
1649 Stats : List_Id;
1650
bfef8d0d
JM
1651 begin
1652 Desig_Typ := Etype (Expression (N));
10b93b2e 1653
bfef8d0d 1654 if Is_Access_Type (Desig_Typ) then
c2369146
AC
1655 Desig_Typ :=
1656 Available_View (Directly_Designated_Type (Desig_Typ));
bfef8d0d 1657 end if;
10b93b2e 1658
6e818918
JM
1659 if Is_Concurrent_Type (Desig_Typ) then
1660 Desig_Typ := Base_Type (Corresponding_Record_Type (Desig_Typ));
1661 end if;
1662
b2e1beb3
ES
1663 New_Typ_Decl :=
1664 Make_Full_Type_Declaration (Loc,
2287a75d 1665 Defining_Identifier => Make_Temporary (Loc, 'T'),
b2e1beb3
ES
1666 Type_Definition =>
1667 Make_Access_To_Object_Definition (Loc,
1668 All_Present => True,
1669 Null_Exclusion_Present => False,
1670 Constant_Present => False,
1671 Subtype_Indication =>
e4494292 1672 New_Occurrence_Of (Desig_Typ, Loc)));
10b93b2e 1673
d0dd5209 1674 Stats := New_List (
b2e1beb3
ES
1675 Make_Simple_Return_Statement (Loc,
1676 Unchecked_Convert_To (Etype (N),
1677 Make_Attribute_Reference (Loc,
6782b1ef 1678 Prefix =>
b2e1beb3 1679 Make_Selected_Component (Loc,
6782b1ef 1680 Prefix =>
6e818918
JM
1681 Unchecked_Convert_To
1682 (Defining_Identifier (New_Typ_Decl),
1683 Make_Identifier (Loc, Name_uO)),
b2e1beb3
ES
1684 Selector_Name =>
1685 New_Occurrence_Of (Iface_Tag, Loc)),
1686 Attribute_Name => Name_Address))));
d0dd5209 1687
b2e1beb3
ES
1688 -- If the type is null-excluding, no need for the null branch.
1689 -- Otherwise we need to check for it and return null.
1690
1691 if not Can_Never_Be_Null (Etype (N)) then
1692 Stats := New_List (
1693 Make_If_Statement (Loc,
1694 Condition =>
1695 Make_Op_Eq (Loc,
1696 Left_Opnd => Make_Identifier (Loc, Name_uO),
e4494292 1697 Right_Opnd => New_Occurrence_Of
b2e1beb3
ES
1698 (RTE (RE_Null_Address), Loc)),
1699
1700 Then_Statements => New_List (
6782b1ef 1701 Make_Simple_Return_Statement (Loc, Make_Null (Loc))),
b2e1beb3
ES
1702 Else_Statements => Stats));
1703 end if;
10b93b2e 1704
2287a75d 1705 Fent := Make_Temporary (Loc, 'F');
b2e1beb3
ES
1706 Func :=
1707 Make_Subprogram_Body (Loc,
1708 Specification =>
1709 Make_Function_Specification (Loc,
1710 Defining_Unit_Name => Fent,
10b93b2e 1711
b2e1beb3
ES
1712 Parameter_Specifications => New_List (
1713 Make_Parameter_Specification (Loc,
1714 Defining_Identifier =>
1715 Make_Defining_Identifier (Loc, Name_uO),
1716 Parameter_Type =>
e4494292 1717 New_Occurrence_Of (RTE (RE_Address), Loc))),
10b93b2e 1718
b2e1beb3 1719 Result_Definition =>
e4494292 1720 New_Occurrence_Of (Etype (N), Loc)),
10b93b2e 1721
6e818918 1722 Declarations => New_List (New_Typ_Decl),
10b93b2e 1723
b2e1beb3
ES
1724 Handled_Statement_Sequence =>
1725 Make_Handled_Sequence_Of_Statements (Loc, Stats));
10b93b2e 1726
b2e1beb3
ES
1727 -- Place function body before the expression containing the
1728 -- conversion. We suppress all checks because the body of the
1729 -- internally generated function already takes care of the case
1730 -- in which the actual is null; therefore there is no need to
1731 -- double check that the pointer is not null when the program
1732 -- executes the alternative that performs the type conversion).
bfef8d0d 1733
b2e1beb3 1734 Insert_Action (N, Func, Suppress => All_Checks);
bfef8d0d 1735
b2e1beb3 1736 if Is_Access_Type (Etype (Expression (N))) then
bfef8d0d 1737
6e818918 1738 -- Generate: Func (Address!(Expression))
bfef8d0d 1739
b2e1beb3
ES
1740 Rewrite (N,
1741 Make_Function_Call (Loc,
95e0ceef 1742 Name => New_Occurrence_Of (Fent, Loc),
b2e1beb3 1743 Parameter_Associations => New_List (
6e818918
JM
1744 Unchecked_Convert_To (RTE (RE_Address),
1745 Relocate_Node (Expression (N))))));
b2e1beb3
ES
1746
1747 else
6e818918 1748 -- Generate: Func (Operand_Typ!(Expression)'Address)
b2e1beb3
ES
1749
1750 Rewrite (N,
1751 Make_Function_Call (Loc,
95e0ceef 1752 Name => New_Occurrence_Of (Fent, Loc),
b2e1beb3
ES
1753 Parameter_Associations => New_List (
1754 Make_Attribute_Reference (Loc,
1755 Prefix => Unchecked_Convert_To (Operand_Typ,
1756 Relocate_Node (Expression (N))),
1757 Attribute_Name => Name_Address))));
1758 end if;
1759 end;
10b93b2e 1760 end if;
758c442c
GD
1761
1762 Analyze (N);
1763 end Expand_Interface_Conversion;
1764
1765 ------------------------------
1766 -- Expand_Interface_Actuals --
1767 ------------------------------
1768
1769 procedure Expand_Interface_Actuals (Call_Node : Node_Id) is
758c442c 1770 Actual : Node_Id;
10b93b2e 1771 Actual_Dup : Node_Id;
758c442c 1772 Actual_Typ : Entity_Id;
10b93b2e 1773 Anon : Entity_Id;
758c442c
GD
1774 Conversion : Node_Id;
1775 Formal : Entity_Id;
1776 Formal_Typ : Entity_Id;
1777 Subp : Entity_Id;
1f8766d3
AC
1778 Formal_DDT : Entity_Id := Empty; -- initialize to prevent warning
1779 Actual_DDT : Entity_Id := Empty; -- initialize to prevent warning
758c442c
GD
1780
1781 begin
1782 -- This subprogram is called directly from the semantics, so we need a
1783 -- check to see whether expansion is active before proceeding.
1784
1785 if not Expander_Active then
1786 return;
1787 end if;
1788
1789 -- Call using access to subprogram with explicit dereference
1790
1791 if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
1792 Subp := Etype (Name (Call_Node));
1793
2a26a7ec
JM
1794 -- Call using selected component
1795
1796 elsif Nkind (Name (Call_Node)) = N_Selected_Component then
1797 Subp := Entity (Selector_Name (Name (Call_Node)));
1798
1799 -- Call using direct name
758c442c
GD
1800
1801 else
1802 Subp := Entity (Name (Call_Node));
1803 end if;
1804
d0dd5209
JM
1805 -- Ada 2005 (AI-251): Look for interface type formals to force "this"
1806 -- displacement
1807
758c442c
GD
1808 Formal := First_Formal (Subp);
1809 Actual := First_Actual (Call_Node);
758c442c 1810 while Present (Formal) loop
d0dd5209 1811 Formal_Typ := Etype (Formal);
10b93b2e 1812
5a644684
JM
1813 if Has_Non_Limited_View (Formal_Typ) then
1814 Formal_Typ := Non_Limited_View (Formal_Typ);
1815 end if;
1816
10b93b2e
HK
1817 if Ekind (Formal_Typ) = E_Record_Type_With_Private then
1818 Formal_Typ := Full_View (Formal_Typ);
1819 end if;
1820
1821 if Is_Access_Type (Formal_Typ) then
1822 Formal_DDT := Directly_Designated_Type (Formal_Typ);
5a644684
JM
1823
1824 if Has_Non_Limited_View (Formal_DDT) then
1825 Formal_DDT := Non_Limited_View (Formal_DDT);
1826 end if;
10b93b2e
HK
1827 end if;
1828
758c442c
GD
1829 Actual_Typ := Etype (Actual);
1830
5a644684
JM
1831 if Has_Non_Limited_View (Actual_Typ) then
1832 Actual_Typ := Non_Limited_View (Actual_Typ);
1833 end if;
1834
10b93b2e
HK
1835 if Is_Access_Type (Actual_Typ) then
1836 Actual_DDT := Directly_Designated_Type (Actual_Typ);
5a644684
JM
1837
1838 if Has_Non_Limited_View (Actual_DDT) then
1839 Actual_DDT := Non_Limited_View (Actual_DDT);
1840 end if;
10b93b2e
HK
1841 end if;
1842
d0dd5209
JM
1843 if Is_Interface (Formal_Typ)
1844 and then Is_Class_Wide_Type (Formal_Typ)
1845 then
10b93b2e 1846 -- No need to displace the pointer if the type of the actual
3b42c566 1847 -- coincides with the type of the formal.
758c442c 1848
d0dd5209 1849 if Actual_Typ = Formal_Typ then
10b93b2e
HK
1850 null;
1851
6782b1ef
AC
1852 -- No need to displace the pointer if the interface type is a
1853 -- parent of the type of the actual because in this case the
d0dd5209 1854 -- interface primitives are located in the primary dispatch table.
758c442c 1855
4ac2477e
JM
1856 elsif Is_Ancestor (Formal_Typ, Actual_Typ,
1857 Use_Full_View => True)
1858 then
10b93b2e
HK
1859 null;
1860
6782b1ef
AC
1861 -- Implicit conversion to the class-wide formal type to force the
1862 -- displacement of the pointer.
d0dd5209 1863
10b93b2e 1864 else
23b86353
AC
1865 -- Normally, expansion of actuals for calls to build-in-place
1866 -- functions happens as part of Expand_Actuals, but in this
1867 -- case the call will be wrapped in a conversion and soon after
1868 -- expanded further to handle the displacement for a class-wide
1869 -- interface conversion, so if this is a BIP call then we need
1870 -- to handle it now.
1871
d4dfb005 1872 if Is_Build_In_Place_Function_Call (Actual) then
23b86353
AC
1873 Make_Build_In_Place_Call_In_Anonymous_Context (Actual);
1874 end if;
1875
10b93b2e 1876 Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
d0dd5209 1877 Rewrite (Actual, Conversion);
10b93b2e
HK
1878 Analyze_And_Resolve (Actual, Formal_Typ);
1879 end if;
758c442c 1880
d0dd5209 1881 -- Access to class-wide interface type
758c442c
GD
1882
1883 elsif Is_Access_Type (Formal_Typ)
d0dd5209
JM
1884 and then Is_Interface (Formal_DDT)
1885 and then Is_Class_Wide_Type (Formal_DDT)
758c442c 1886 and then Interface_Present_In_Ancestor
10b93b2e
HK
1887 (Typ => Actual_DDT,
1888 Iface => Etype (Formal_DDT))
758c442c 1889 then
d0dd5209
JM
1890 -- Handle attributes 'Access and 'Unchecked_Access
1891
758c442c
GD
1892 if Nkind (Actual) = N_Attribute_Reference
1893 and then
1894 (Attribute_Name (Actual) = Name_Access
1895 or else Attribute_Name (Actual) = Name_Unchecked_Access)
1896 then
3192631e
JM
1897 -- This case must have been handled by the analysis and
1898 -- expansion of 'Access. The only exception is when types
1899 -- match and no further expansion is required.
758c442c 1900
3192631e
JM
1901 pragma Assert (Base_Type (Etype (Prefix (Actual)))
1902 = Base_Type (Formal_DDT));
1903 null;
758c442c 1904
d0dd5209
JM
1905 -- No need to displace the pointer if the type of the actual
1906 -- coincides with the type of the formal.
10b93b2e 1907
d0dd5209 1908 elsif Actual_DDT = Formal_DDT then
10b93b2e
HK
1909 null;
1910
d0dd5209
JM
1911 -- No need to displace the pointer if the interface type is
1912 -- a parent of the type of the actual because in this case the
1913 -- interface primitives are located in the primary dispatch table.
10b93b2e 1914
4ac2477e
JM
1915 elsif Is_Ancestor (Formal_DDT, Actual_DDT,
1916 Use_Full_View => True)
1917 then
10b93b2e
HK
1918 null;
1919
758c442c 1920 else
10b93b2e
HK
1921 Actual_Dup := Relocate_Node (Actual);
1922
7b56a91b 1923 if From_Limited_With (Actual_Typ) then
10b93b2e 1924
15529d0a
PMR
1925 -- If the type of the actual parameter comes from a limited
1926 -- with_clause and the nonlimited view is already available,
1927 -- we replace the anonymous access type by a duplicate
1928 -- declaration whose designated type is the nonlimited view.
10b93b2e 1929
47346923 1930 if Has_Non_Limited_View (Actual_DDT) then
10b93b2e
HK
1931 Anon := New_Copy (Actual_Typ);
1932
1933 if Is_Itype (Anon) then
1934 Set_Scope (Anon, Current_Scope);
1935 end if;
1936
e23e04db
AC
1937 Set_Directly_Designated_Type
1938 (Anon, Non_Limited_View (Actual_DDT));
10b93b2e 1939 Set_Etype (Actual_Dup, Anon);
10b93b2e
HK
1940 end if;
1941 end if;
1942
1943 Conversion := Convert_To (Formal_Typ, Actual_Dup);
1944 Rewrite (Actual, Conversion);
758c442c
GD
1945 Analyze_And_Resolve (Actual, Formal_Typ);
1946 end if;
1947 end if;
1948
1949 Next_Actual (Actual);
1950 Next_Formal (Formal);
1951 end loop;
1952 end Expand_Interface_Actuals;
1953
1954 ----------------------------
1955 -- Expand_Interface_Thunk --
1956 ----------------------------
1957
d0dd5209 1958 procedure Expand_Interface_Thunk
b2e1beb3
ES
1959 (Prim : Node_Id;
1960 Thunk_Id : out Entity_Id;
20dc266e
JM
1961 Thunk_Code : out Node_Id;
1962 Iface : Entity_Id)
758c442c 1963 is
95cb33a5
AC
1964 Loc : constant Source_Ptr := Sloc (Prim);
1965 Actuals : constant List_Id := New_List;
1966 Decl : constant List_Id := New_List;
1967 Formals : constant List_Id := New_List;
1968 Target : constant Entity_Id := Ultimate_Alias (Prim);
d0dd5209 1969
b9daa96e
AC
1970 Decl_1 : Node_Id;
1971 Decl_2 : Node_Id;
1972 Expr : Node_Id;
1973 Formal : Node_Id;
1974 Ftyp : Entity_Id;
1f8766d3 1975 Iface_Formal : Node_Id := Empty; -- initialize to prevent warning
4faf522b
JM
1976 Is_Predef_Op : constant Boolean :=
1977 Is_Predefined_Dispatching_Operation (Prim)
1978 or else Is_Predefined_Dispatching_Operation (Target);
b9daa96e
AC
1979 New_Arg : Node_Id;
1980 Offset_To_Top : Node_Id;
1981 Target_Formal : Entity_Id;
758c442c
GD
1982
1983 begin
d0dd5209
JM
1984 Thunk_Id := Empty;
1985 Thunk_Code := Empty;
1986
9e9df9da
AC
1987 -- No thunk needed if the primitive has been eliminated
1988
4faf522b 1989 if Is_Eliminated (Target) then
9e9df9da
AC
1990 return;
1991
95cb33a5
AC
1992 -- In case of primitives that are functions without formals and a
1993 -- controlling result there is no need to build the thunk.
d0dd5209 1994
9e9df9da 1995 elsif not Present (First_Formal (Target)) then
d0dd5209
JM
1996 pragma Assert (Ekind (Target) = E_Function
1997 and then Has_Controlling_Result (Target));
1998 return;
1999 end if;
2000
21d11f4f
AC
2001 -- Duplicate the formals of the Target primitive. In the thunk, the type
2002 -- of the controlling formal is the covered interface type (instead of
2003 -- the target tagged type). Done to avoid problems with discriminated
2004 -- tagged types because, if the controlling type has discriminants with
95cb33a5
AC
2005 -- default values, then the type conversions done inside the body of
2006 -- the thunk (after the displacement of the pointer to the base of the
21d11f4f
AC
2007 -- actual object) generate code that modify its contents.
2008
2009 -- Note: This special management is not done for predefined primitives
4faf522b
JM
2010 -- because they don't have available the Interface_Alias attribute (see
2011 -- Sem_Ch3.Add_Internal_Interface_Entities).
21d11f4f 2012
4faf522b 2013 if not Is_Predef_Op then
21d11f4f
AC
2014 Iface_Formal := First_Formal (Interface_Alias (Prim));
2015 end if;
758c442c 2016
10b93b2e 2017 Formal := First_Formal (Target);
758c442c 2018 while Present (Formal) loop
21d11f4f
AC
2019 Ftyp := Etype (Formal);
2020
2021 -- Use the interface type as the type of the controlling formal (see
95cb33a5 2022 -- comment above).
21d11f4f 2023
20dc266e 2024 if not Is_Controlling_Formal (Formal) then
21d11f4f
AC
2025 Ftyp := Etype (Formal);
2026 Expr := New_Copy_Tree (Expression (Parent (Formal)));
20dc266e
JM
2027
2028 -- For predefined primitives the controlling type of the thunk is
2029 -- the interface type passed by the caller (since they don't have
2030 -- available the Interface_Alias attribute; see comment above).
2031
2032 elsif Is_Predef_Op then
2033 Ftyp := Iface;
2034 Expr := Empty;
2035
21d11f4f
AC
2036 else
2037 Ftyp := Etype (Iface_Formal);
2038 Expr := Empty;
20dc266e
JM
2039
2040 -- Sanity check performed to ensure the proper controlling type
2041 -- when the thunk has exactly one controlling parameter and it
2042 -- comes first. In such case the GCC backend reuses the C++
2043 -- thunks machinery which perform a computation equivalent to
2044 -- the code generated by the expander; for other cases the GCC
2045 -- backend translates the expanded code unmodified. However, as
2046 -- a generalization, the check is performed for all controlling
2047 -- types.
2048
2049 if Is_Access_Type (Ftyp) then
2050 pragma Assert (Base_Type (Designated_Type (Ftyp)) = Iface);
2051 null;
2052 else
2053 Ftyp := Base_Type (Ftyp);
2054 pragma Assert (Ftyp = Iface);
2055 end if;
21d11f4f
AC
2056 end if;
2057
d0dd5209
JM
2058 Append_To (Formals,
2059 Make_Parameter_Specification (Loc,
2060 Defining_Identifier =>
2061 Make_Defining_Identifier (Sloc (Formal),
2062 Chars => Chars (Formal)),
2063 In_Present => In_Present (Parent (Formal)),
2064 Out_Present => Out_Present (Parent (Formal)),
e4494292 2065 Parameter_Type => New_Occurrence_Of (Ftyp, Loc),
21d11f4f
AC
2066 Expression => Expr));
2067
4faf522b 2068 if not Is_Predef_Op then
21d11f4f
AC
2069 Next_Formal (Iface_Formal);
2070 end if;
10b93b2e 2071
758c442c
GD
2072 Next_Formal (Formal);
2073 end loop;
2074
d0dd5209
JM
2075 Target_Formal := First_Formal (Target);
2076 Formal := First (Formals);
2077 while Present (Formal) loop
21d11f4f 2078
b29def53
AC
2079 -- If the parent is a constrained discriminated type, then the
2080 -- primitive operation will have been defined on a first subtype.
2081 -- For proper matching with controlling type, use base type.
21d11f4f
AC
2082
2083 if Ekind (Target_Formal) = E_In_Parameter
2084 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
2085 then
b29def53
AC
2086 Ftyp :=
2087 Base_Type (Directly_Designated_Type (Etype (Target_Formal)));
21d11f4f 2088 else
7cec010e 2089 Ftyp := Base_Type (Etype (Target_Formal));
21d11f4f
AC
2090 end if;
2091
c736294d
RD
2092 -- For concurrent types, the relevant information is found in the
2093 -- Corresponding_Record_Type, rather than the type entity itself.
b29def53 2094
21d11f4f
AC
2095 if Is_Concurrent_Type (Ftyp) then
2096 Ftyp := Corresponding_Record_Type (Ftyp);
2097 end if;
2098
d0dd5209
JM
2099 if Ekind (Target_Formal) = E_In_Parameter
2100 and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
de6cad7c 2101 and then Is_Controlling_Formal (Target_Formal)
d0dd5209
JM
2102 then
2103 -- Generate:
b2e1beb3
ES
2104 -- type T is access all <<type of the target formal>>
2105 -- S : Storage_Offset := Storage_Offset!(Formal)
d0567dc0 2106 -- + Offset_To_Top (address!(Formal))
d0dd5209
JM
2107
2108 Decl_2 :=
2109 Make_Full_Type_Declaration (Loc,
2287a75d 2110 Defining_Identifier => Make_Temporary (Loc, 'T'),
d0dd5209
JM
2111 Type_Definition =>
2112 Make_Access_To_Object_Definition (Loc,
2113 All_Present => True,
2114 Null_Exclusion_Present => False,
2115 Constant_Present => False,
2116 Subtype_Indication =>
e4494292 2117 New_Occurrence_Of (Ftyp, Loc)));
d0dd5209 2118
f2cbd970
JM
2119 New_Arg :=
2120 Unchecked_Convert_To (RTE (RE_Address),
e4494292 2121 New_Occurrence_Of (Defining_Identifier (Formal), Loc));
f2cbd970
JM
2122
2123 if not RTE_Available (RE_Offset_To_Top) then
2124 Offset_To_Top :=
2125 Build_Offset_To_Top (Loc, New_Arg);
2126 else
2127 Offset_To_Top :=
2128 Make_Function_Call (Loc,
e4494292 2129 Name => New_Occurrence_Of (RTE (RE_Offset_To_Top), Loc),
f2cbd970
JM
2130 Parameter_Associations => New_List (New_Arg));
2131 end if;
2132
d0dd5209
JM
2133 Decl_1 :=
2134 Make_Object_Declaration (Loc,
2287a75d 2135 Defining_Identifier => Make_Temporary (Loc, 'S'),
d0dd5209
JM
2136 Constant_Present => True,
2137 Object_Definition =>
e4494292 2138 New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
d0dd5209 2139 Expression =>
d0567dc0 2140 Make_Op_Add (Loc,
d0dd5209
JM
2141 Left_Opnd =>
2142 Unchecked_Convert_To
2143 (RTE (RE_Storage_Offset),
e4494292
RD
2144 New_Occurrence_Of
2145 (Defining_Identifier (Formal), Loc)),
d0dd5209 2146 Right_Opnd =>
f2cbd970 2147 Offset_To_Top));
d0dd5209
JM
2148
2149 Append_To (Decl, Decl_2);
2150 Append_To (Decl, Decl_1);
2151
b2e1beb3
ES
2152 -- Reference the new actual. Generate:
2153 -- T!(S)
d0dd5209
JM
2154
2155 Append_To (Actuals,
2156 Unchecked_Convert_To
2157 (Defining_Identifier (Decl_2),
e4494292 2158 New_Occurrence_Of (Defining_Identifier (Decl_1), Loc)));
d0dd5209 2159
de6cad7c 2160 elsif Is_Controlling_Formal (Target_Formal) then
758c442c 2161
95cb33a5 2162 -- Generate:
b2e1beb3 2163 -- S1 : Storage_Offset := Storage_Offset!(Formal'Address)
d0567dc0 2164 -- + Offset_To_Top (Formal'Address)
b2e1beb3 2165 -- S2 : Addr_Ptr := Addr_Ptr!(S1)
758c442c 2166
f2cbd970
JM
2167 New_Arg :=
2168 Make_Attribute_Reference (Loc,
2169 Prefix =>
e4494292 2170 New_Occurrence_Of (Defining_Identifier (Formal), Loc),
f2cbd970
JM
2171 Attribute_Name =>
2172 Name_Address);
2173
2174 if not RTE_Available (RE_Offset_To_Top) then
2175 Offset_To_Top :=
2176 Build_Offset_To_Top (Loc, New_Arg);
2177 else
2178 Offset_To_Top :=
2179 Make_Function_Call (Loc,
e4494292 2180 Name => New_Occurrence_Of (RTE (RE_Offset_To_Top), Loc),
f2cbd970
JM
2181 Parameter_Associations => New_List (New_Arg));
2182 end if;
2183
d0dd5209
JM
2184 Decl_1 :=
2185 Make_Object_Declaration (Loc,
2287a75d 2186 Defining_Identifier => Make_Temporary (Loc, 'S'),
d0dd5209
JM
2187 Constant_Present => True,
2188 Object_Definition =>
e4494292 2189 New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
d0dd5209 2190 Expression =>
d0567dc0 2191 Make_Op_Add (Loc,
d0dd5209
JM
2192 Left_Opnd =>
2193 Unchecked_Convert_To
2194 (RTE (RE_Storage_Offset),
2195 Make_Attribute_Reference (Loc,
2196 Prefix =>
e4494292 2197 New_Occurrence_Of
d0dd5209
JM
2198 (Defining_Identifier (Formal), Loc),
2199 Attribute_Name => Name_Address)),
2200 Right_Opnd =>
f2cbd970 2201 Offset_To_Top));
758c442c 2202
d0dd5209
JM
2203 Decl_2 :=
2204 Make_Object_Declaration (Loc,
2287a75d
AC
2205 Defining_Identifier => Make_Temporary (Loc, 'S'),
2206 Constant_Present => True,
2207 Object_Definition =>
e4494292 2208 New_Occurrence_Of (RTE (RE_Addr_Ptr), Loc),
2287a75d 2209 Expression =>
d0dd5209
JM
2210 Unchecked_Convert_To
2211 (RTE (RE_Addr_Ptr),
e4494292 2212 New_Occurrence_Of (Defining_Identifier (Decl_1), Loc)));
758c442c 2213
d0dd5209
JM
2214 Append_To (Decl, Decl_1);
2215 Append_To (Decl, Decl_2);
4d744221 2216
2287a75d 2217 -- Reference the new actual, generate:
b2e1beb3 2218 -- Target_Formal (S2.all)
758c442c 2219
d0dd5209 2220 Append_To (Actuals,
21d11f4f 2221 Unchecked_Convert_To (Ftyp,
d0dd5209 2222 Make_Explicit_Dereference (Loc,
e4494292 2223 New_Occurrence_Of (Defining_Identifier (Decl_2), Loc))));
758c442c 2224
8a49a499
AC
2225 -- Ensure proper matching of access types. Required to avoid
2226 -- reporting spurious errors.
2227
2228 elsif Is_Access_Type (Etype (Target_Formal)) then
2229 Append_To (Actuals,
2230 Unchecked_Convert_To (Base_Type (Etype (Target_Formal)),
e4494292 2231 New_Occurrence_Of (Defining_Identifier (Formal), Loc)));
8a49a499 2232
d0dd5209 2233 -- No special management required for this actual
758c442c 2234
d0dd5209
JM
2235 else
2236 Append_To (Actuals,
e4494292 2237 New_Occurrence_Of (Defining_Identifier (Formal), Loc));
d0dd5209
JM
2238 end if;
2239
2240 Next_Formal (Target_Formal);
758c442c
GD
2241 Next (Formal);
2242 end loop;
2243
2287a75d 2244 Thunk_Id := Make_Temporary (Loc, 'T');
3af132b8
TQ
2245
2246 -- Note: any change to this symbol name needs to be coordinated
2247 -- with GNATcoverage, as that tool relies on it to identify
2248 -- thunks and exclude them from source coverage analysis.
2249
da1c23dd 2250 Set_Ekind (Thunk_Id, Ekind (Prim));
6e818918 2251 Set_Is_Thunk (Thunk_Id);
28dd0055 2252 Set_Convention (Thunk_Id, Convention (Prim));
d58008d2 2253 Set_Needs_Debug_Info (Thunk_Id, Needs_Debug_Info (Target));
e2441021 2254 Set_Thunk_Entity (Thunk_Id, Target);
6e818918 2255
95cb33a5
AC
2256 -- Procedure case
2257
10b93b2e 2258 if Ekind (Target) = E_Procedure then
d0dd5209 2259 Thunk_Code :=
758c442c
GD
2260 Make_Subprogram_Body (Loc,
2261 Specification =>
2262 Make_Procedure_Specification (Loc,
2263 Defining_Unit_Name => Thunk_Id,
2264 Parameter_Specifications => Formals),
2265 Declarations => Decl,
2266 Handled_Statement_Sequence =>
2267 Make_Handled_Sequence_Of_Statements (Loc,
2268 Statements => New_List (
2269 Make_Procedure_Call_Statement (Loc,
d0dd5209
JM
2270 Name => New_Occurrence_Of (Target, Loc),
2271 Parameter_Associations => Actuals))));
758c442c 2272
95cb33a5 2273 -- Function case
758c442c 2274
95cb33a5 2275 else pragma Assert (Ekind (Target) = E_Function);
f6f4d8d4
JM
2276 declare
2277 Result_Def : Node_Id;
2278 Call_Node : Node_Id;
2279
2280 begin
2281 Call_Node :=
2282 Make_Function_Call (Loc,
2283 Name => New_Occurrence_Of (Target, Loc),
2284 Parameter_Associations => Actuals);
2285
2286 if not Is_Interface (Etype (Prim)) then
2287 Result_Def := New_Copy (Result_Definition (Parent (Target)));
2288
2289 -- Thunk of function returning a class-wide interface object. No
2290 -- extra displacement needed since the displacement is generated
2291 -- in the return statement of Prim. Example:
2292
2293 -- type Iface is interface ...
2294 -- function F (O : Iface) return Iface'Class;
2295
2296 -- type T is new ... and Iface with ...
2297 -- function F (O : T) return Iface'Class;
2298
2299 elsif Is_Class_Wide_Type (Etype (Prim)) then
2300 Result_Def := New_Occurrence_Of (Etype (Prim), Loc);
2301
2302 -- Thunk of function returning an interface object. Displacement
2303 -- needed. Example:
2304
2305 -- type Iface is interface ...
2306 -- function F (O : Iface) return Iface;
2307
2308 -- type T is new ... and Iface with ...
2309 -- function F (O : T) return T;
2310
2311 else
2312 Result_Def :=
2313 New_Occurrence_Of (Class_Wide_Type (Etype (Prim)), Loc);
2314
2315 -- Adding implicit conversion to force the displacement of
2316 -- the pointer to the object to reference the corresponding
2317 -- secondary dispatch table.
2318
2319 Call_Node :=
2320 Make_Type_Conversion (Loc,
2321 Subtype_Mark =>
2322 New_Occurrence_Of (Class_Wide_Type (Etype (Prim)), Loc),
2323 Expression => Relocate_Node (Call_Node));
2324 end if;
2325
2326 Thunk_Code :=
2327 Make_Subprogram_Body (Loc,
6782b1ef 2328 Specification =>
f6f4d8d4
JM
2329 Make_Function_Specification (Loc,
2330 Defining_Unit_Name => Thunk_Id,
2331 Parameter_Specifications => Formals,
2332 Result_Definition => Result_Def),
6782b1ef 2333 Declarations => Decl,
f6f4d8d4
JM
2334 Handled_Statement_Sequence =>
2335 Make_Handled_Sequence_Of_Statements (Loc,
2336 Statements => New_List (
2337 Make_Simple_Return_Statement (Loc, Call_Node))));
2338 end;
758c442c 2339 end if;
758c442c
GD
2340 end Expand_Interface_Thunk;
2341
cefce34c
JM
2342 --------------------------
2343 -- Has_CPP_Constructors --
2344 --------------------------
2345
2346 function Has_CPP_Constructors (Typ : Entity_Id) return Boolean is
2347 E : Entity_Id;
2348
2349 begin
2350 -- Look for the constructor entities
2351
2352 E := Next_Entity (Typ);
2353 while Present (E) loop
6782b1ef 2354 if Ekind (E) = E_Function and then Is_Constructor (E) then
cefce34c
JM
2355 return True;
2356 end if;
2357
2358 Next_Entity (E);
2359 end loop;
2360
2361 return False;
2362 end Has_CPP_Constructors;
2363
e18d6a15
JM
2364 ------------
2365 -- Has_DT --
2366 ------------
2367
2368 function Has_DT (Typ : Entity_Id) return Boolean is
2369 begin
2370 return not Is_Interface (Typ)
6782b1ef 2371 and then not Restriction_Active (No_Dispatching_Calls);
e18d6a15
JM
2372 end Has_DT;
2373
7af1cf83
AC
2374 ----------------------------------
2375 -- Is_Expanded_Dispatching_Call --
2376 ----------------------------------
2377
2378 function Is_Expanded_Dispatching_Call (N : Node_Id) return Boolean is
2379 begin
2380 return Nkind (N) in N_Subprogram_Call
2381 and then Nkind (Name (N)) = N_Explicit_Dereference
2382 and then Is_Dispatch_Table_Entity (Etype (Name (N)));
2383 end Is_Expanded_Dispatching_Call;
2384
bfef8d0d
JM
2385 -------------------------------------
2386 -- Is_Predefined_Dispatching_Alias --
2387 -------------------------------------
2388
2389 function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
2390 is
bfef8d0d 2391 begin
b81a5940 2392 return not Is_Predefined_Dispatching_Operation (Prim)
bfef8d0d 2393 and then Present (Alias (Prim))
b81a5940 2394 and then Is_Predefined_Dispatching_Operation (Ultimate_Alias (Prim));
bfef8d0d
JM
2395 end Is_Predefined_Dispatching_Alias;
2396
f4d379b8
HK
2397 ----------------------------------------
2398 -- Make_Disp_Asynchronous_Select_Body --
2399 ----------------------------------------
70482933 2400
80b992ae
HK
2401 -- For interface types, generate:
2402
2403 -- procedure _Disp_Asynchronous_Select
2404 -- (T : in out <Typ>;
2405 -- S : Integer;
2406 -- P : System.Address;
2407 -- B : out System.Storage_Elements.Dummy_Communication_Block;
2408 -- F : out Boolean)
2409 -- is
2410 -- begin
14848f57
AC
2411 -- F := False;
2412 -- C := Ada.Tags.POK_Function;
80b992ae
HK
2413 -- end _Disp_Asynchronous_Select;
2414
2415 -- For protected types, generate:
2416
2417 -- procedure _Disp_Asynchronous_Select
2418 -- (T : in out <Typ>;
2419 -- S : Integer;
2420 -- P : System.Address;
2421 -- B : out System.Storage_Elements.Dummy_Communication_Block;
2422 -- F : out Boolean)
2423 -- is
2424 -- I : Integer :=
2425 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2426 -- Bnn : System.Tasking.Protected_Objects.Operations.
2427 -- Communication_Block;
2428 -- begin
2429 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
2430 -- (T._object'Access,
2431 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
2432 -- P,
2433 -- System.Tasking.Asynchronous_Call,
2434 -- Bnn);
2435 -- B := System.Storage_Elements.Dummy_Communication_Block (Bnn);
2436 -- end _Disp_Asynchronous_Select;
2437
2438 -- For task types, generate:
2439
2440 -- procedure _Disp_Asynchronous_Select
2441 -- (T : in out <Typ>;
2442 -- S : Integer;
2443 -- P : System.Address;
2444 -- B : out System.Storage_Elements.Dummy_Communication_Block;
2445 -- F : out Boolean)
2446 -- is
2447 -- I : Integer :=
2448 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2449 -- begin
2450 -- System.Tasking.Rendezvous.Task_Entry_Call
2451 -- (T._task_id,
2452 -- System.Tasking.Task_Entry_Index (I),
2453 -- P,
2454 -- System.Tasking.Asynchronous_Call,
2455 -- F);
2456 -- end _Disp_Asynchronous_Select;
2457
f4d379b8
HK
2458 function Make_Disp_Asynchronous_Select_Body
2459 (Typ : Entity_Id) return Node_Id
2460 is
d0dd5209
JM
2461 Com_Block : Entity_Id;
2462 Conc_Typ : Entity_Id := Empty;
2463 Decls : constant List_Id := New_List;
d0dd5209 2464 Loc : constant Source_Ptr := Sloc (Typ);
1923d2d6 2465 Obj_Ref : Node_Id;
d0dd5209 2466 Stmts : constant List_Id := New_List;
e8374e7a 2467 Tag_Node : Node_Id;
70482933
RK
2468
2469 begin
b0efe69e
JM
2470 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2471
4d744221
JM
2472 -- Null body is generated for interface types
2473
f4d379b8
HK
2474 if Is_Interface (Typ) then
2475 return
2476 Make_Subprogram_Body (Loc,
6782b1ef
AC
2477 Specification =>
2478 Make_Disp_Asynchronous_Select_Spec (Typ),
2479 Declarations => New_List,
f4d379b8
HK
2480 Handled_Statement_Sequence =>
2481 Make_Handled_Sequence_Of_Statements (Loc,
6782b1ef
AC
2482 New_List (
2483 Make_Assignment_Statement (Loc,
2484 Name => Make_Identifier (Loc, Name_uF),
2485 Expression => New_Occurrence_Of (Standard_False, Loc)))));
fbf5a39b
AC
2486 end if;
2487
4d744221
JM
2488 if Is_Concurrent_Record_Type (Typ) then
2489 Conc_Typ := Corresponding_Concurrent_Type (Typ);
758c442c 2490
f4d379b8 2491 -- Generate:
80b992ae
HK
2492 -- I : Integer :=
2493 -- Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
758c442c 2494
f4d379b8
HK
2495 -- where I will be used to capture the entry index of the primitive
2496 -- wrapper at position S.
758c442c 2497
e8374e7a
AC
2498 if Tagged_Type_Expansion then
2499 Tag_Node :=
2500 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 2501 New_Occurrence_Of
e8374e7a
AC
2502 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));
2503 else
2504 Tag_Node :=
2505 Make_Attribute_Reference (Loc,
6782b1ef 2506 Prefix => New_Occurrence_Of (Typ, Loc),
e8374e7a
AC
2507 Attribute_Name => Name_Tag);
2508 end if;
2509
f4d379b8
HK
2510 Append_To (Decls,
2511 Make_Object_Declaration (Loc,
2512 Defining_Identifier =>
2513 Make_Defining_Identifier (Loc, Name_uI),
6782b1ef 2514 Object_Definition =>
e4494292 2515 New_Occurrence_Of (Standard_Integer, Loc),
6782b1ef 2516 Expression =>
d0dd5209 2517 Make_Function_Call (Loc,
6782b1ef 2518 Name =>
e4494292 2519 New_Occurrence_Of (RTE (RE_Get_Entry_Index), Loc),
80b992ae 2520 Parameter_Associations =>
6782b1ef 2521 New_List (Tag_Node, Make_Identifier (Loc, Name_uS)))));
758c442c 2522
f4d379b8 2523 if Ekind (Conc_Typ) = E_Protected_Type then
758c442c 2524
d0dd5209 2525 -- Generate:
80b992ae 2526 -- Bnn : Communication_Block;
d0dd5209 2527
2287a75d 2528 Com_Block := Make_Temporary (Loc, 'B');
d0dd5209
JM
2529 Append_To (Decls,
2530 Make_Object_Declaration (Loc,
6782b1ef
AC
2531 Defining_Identifier => Com_Block,
2532 Object_Definition =>
e4494292 2533 New_Occurrence_Of (RTE (RE_Communication_Block), Loc)));
d0dd5209 2534
1923d2d6 2535 -- Build T._object'Access for calls below
758c442c 2536
1923d2d6
JM
2537 Obj_Ref :=
2538 Make_Attribute_Reference (Loc,
2539 Attribute_Name => Name_Unchecked_Access,
2540 Prefix =>
2541 Make_Selected_Component (Loc,
2542 Prefix => Make_Identifier (Loc, Name_uT),
2543 Selector_Name => Make_Identifier (Loc, Name_uObject)));
758c442c 2544
1923d2d6
JM
2545 case Corresponding_Runtime_Package (Conc_Typ) is
2546 when System_Tasking_Protected_Objects_Entries =>
758c442c 2547
1923d2d6
JM
2548 -- Generate:
2549 -- Protected_Entry_Call
2550 -- (T._object'Access, -- Object
2551 -- Protected_Entry_Index! (I), -- E
2552 -- P, -- Uninterpreted_Data
2553 -- Asynchronous_Call, -- Mode
2554 -- Bnn); -- Communication_Block
2555
2556 -- where T is the protected object, I is the entry index, P
2557 -- is the wrapped parameters and B is the name of the
2558 -- communication block.
2559
2560 Append_To (Stmts,
2561 Make_Procedure_Call_Statement (Loc,
6782b1ef 2562 Name =>
e4494292 2563 New_Occurrence_Of (RTE (RE_Protected_Entry_Call), Loc),
1923d2d6
JM
2564 Parameter_Associations =>
2565 New_List (
2566 Obj_Ref,
758c442c 2567
1923d2d6
JM
2568 Make_Unchecked_Type_Conversion (Loc, -- entry index
2569 Subtype_Mark =>
e4494292 2570 New_Occurrence_Of
7675ad4f 2571 (RTE (RE_Protected_Entry_Index), Loc),
1923d2d6 2572 Expression => Make_Identifier (Loc, Name_uI)),
10b93b2e 2573
1923d2d6 2574 Make_Identifier (Loc, Name_uP), -- parameter block
e4494292 2575 New_Occurrence_Of -- Asynchronous_Call
7675ad4f 2576 (RTE (RE_Asynchronous_Call), Loc),
e4494292
RD
2577 New_Occurrence_Of -- comm block
2578 (Com_Block, Loc))));
1923d2d6 2579
1923d2d6
JM
2580 when others =>
2581 raise Program_Error;
2582 end case;
d0dd5209
JM
2583
2584 -- Generate:
80b992ae 2585 -- B := Dummy_Communication_Block (Bnn);
d0dd5209
JM
2586
2587 Append_To (Stmts,
2588 Make_Assignment_Statement (Loc,
7675ad4f 2589 Name => Make_Identifier (Loc, Name_uB),
d0dd5209
JM
2590 Expression =>
2591 Make_Unchecked_Type_Conversion (Loc,
2592 Subtype_Mark =>
6782b1ef
AC
2593 New_Occurrence_Of
2594 (RTE (RE_Dummy_Communication_Block), Loc),
2595 Expression => New_Occurrence_Of (Com_Block, Loc))));
d0dd5209 2596
14848f57
AC
2597 -- Generate:
2598 -- F := False;
2599
2600 Append_To (Stmts,
2601 Make_Assignment_Statement (Loc,
833eaa8a 2602 Name => Make_Identifier (Loc, Name_uF),
e4494292 2603 Expression => New_Occurrence_Of (Standard_False, Loc)));
14848f57 2604
f4d379b8
HK
2605 else
2606 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
10b93b2e 2607
f4d379b8 2608 -- Generate:
80b992ae
HK
2609 -- Task_Entry_Call
2610 -- (T._task_id, -- Acceptor
2611 -- Task_Entry_Index! (I), -- E
2612 -- P, -- Uninterpreted_Data
2613 -- Asynchronous_Call, -- Mode
2614 -- F); -- Rendezvous_Successful
70482933 2615
1923d2d6 2616 -- where T is the task object, I is the entry index, P is the
f4d379b8 2617 -- wrapped parameters and F is the status flag.
70482933 2618
f4d379b8
HK
2619 Append_To (Stmts,
2620 Make_Procedure_Call_Statement (Loc,
6782b1ef 2621 Name =>
e4494292 2622 New_Occurrence_Of (RTE (RE_Task_Entry_Call), Loc),
f4d379b8
HK
2623 Parameter_Associations =>
2624 New_List (
f4d379b8 2625 Make_Selected_Component (Loc, -- T._task_id
7675ad4f
AC
2626 Prefix => Make_Identifier (Loc, Name_uT),
2627 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
70482933 2628
f4d379b8
HK
2629 Make_Unchecked_Type_Conversion (Loc, -- entry index
2630 Subtype_Mark =>
e4494292 2631 New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
6782b1ef 2632 Expression => Make_Identifier (Loc, Name_uI)),
70482933 2633
f4d379b8 2634 Make_Identifier (Loc, Name_uP), -- parameter block
e4494292 2635 New_Occurrence_Of -- Asynchronous_Call
7675ad4f 2636 (RTE (RE_Asynchronous_Call), Loc),
f4d379b8
HK
2637 Make_Identifier (Loc, Name_uF)))); -- status flag
2638 end if;
f2abc637
AC
2639
2640 else
2641 -- Ensure that the statements list is non-empty
2642
14848f57
AC
2643 Append_To (Stmts,
2644 Make_Assignment_Statement (Loc,
833eaa8a 2645 Name => Make_Identifier (Loc, Name_uF),
e4494292 2646 Expression => New_Occurrence_Of (Standard_False, Loc)));
f4d379b8 2647 end if;
70482933 2648
f4d379b8
HK
2649 return
2650 Make_Subprogram_Body (Loc,
833eaa8a 2651 Specification =>
f4d379b8 2652 Make_Disp_Asynchronous_Select_Spec (Typ),
833eaa8a 2653 Declarations => Decls,
f4d379b8
HK
2654 Handled_Statement_Sequence =>
2655 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
2656 end Make_Disp_Asynchronous_Select_Body;
70482933 2657
f4d379b8
HK
2658 ----------------------------------------
2659 -- Make_Disp_Asynchronous_Select_Spec --
2660 ----------------------------------------
70482933 2661
f4d379b8
HK
2662 function Make_Disp_Asynchronous_Select_Spec
2663 (Typ : Entity_Id) return Node_Id
2664 is
2665 Loc : constant Source_Ptr := Sloc (Typ);
c7862167
HK
2666 B_Id : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
2667 Def_Id : constant Entity_Id :=
f4d379b8
HK
2668 Make_Defining_Identifier (Loc,
2669 Name_uDisp_Asynchronous_Select);
2670 Params : constant List_Id := New_List;
70482933 2671
f4d379b8 2672 begin
b0efe69e
JM
2673 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2674
d0dd5209
JM
2675 -- T : in out Typ; -- Object parameter
2676 -- S : Integer; -- Primitive operation slot
2677 -- P : Address; -- Wrapped parameters
2678 -- B : out Dummy_Communication_Block; -- Communication block dummy
2679 -- F : out Boolean; -- Status flag
70482933 2680
865234bf 2681 -- The B parameter may be left uninitialized
c7862167 2682
865234bf
EB
2683 Set_Warnings_Off (B_Id);
2684
d0dd5209
JM
2685 Append_List_To (Params, New_List (
2686
2687 Make_Parameter_Specification (Loc,
6782b1ef
AC
2688 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
2689 Parameter_Type => New_Occurrence_Of (Typ, Loc),
2690 In_Present => True,
2691 Out_Present => True),
d0dd5209
JM
2692
2693 Make_Parameter_Specification (Loc,
6782b1ef
AC
2694 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uS),
2695 Parameter_Type => New_Occurrence_Of (Standard_Integer, Loc)),
d0dd5209
JM
2696
2697 Make_Parameter_Specification (Loc,
6782b1ef
AC
2698 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uP),
2699 Parameter_Type => New_Occurrence_Of (RTE (RE_Address), Loc)),
d0dd5209
JM
2700
2701 Make_Parameter_Specification (Loc,
865234bf 2702 Defining_Identifier => B_Id,
6782b1ef 2703 Parameter_Type =>
e4494292 2704 New_Occurrence_Of (RTE (RE_Dummy_Communication_Block), Loc),
6782b1ef 2705 Out_Present => True),
70482933 2706
d0dd5209 2707 Make_Parameter_Specification (Loc,
6782b1ef
AC
2708 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uF),
2709 Parameter_Type => New_Occurrence_Of (Standard_Boolean, Loc),
2710 Out_Present => True)));
82c80734 2711
f4d379b8 2712 return
d0dd5209
JM
2713 Make_Procedure_Specification (Loc,
2714 Defining_Unit_Name => Def_Id,
2715 Parameter_Specifications => Params);
f4d379b8 2716 end Make_Disp_Asynchronous_Select_Spec;
70482933 2717
f4d379b8
HK
2718 ---------------------------------------
2719 -- Make_Disp_Conditional_Select_Body --
2720 ---------------------------------------
70482933 2721
80b992ae
HK
2722 -- For interface types, generate:
2723
2724 -- procedure _Disp_Conditional_Select
2725 -- (T : in out <Typ>;
2726 -- S : Integer;
2727 -- P : System.Address;
2728 -- C : out Ada.Tags.Prim_Op_Kind;
2729 -- F : out Boolean)
2730 -- is
2731 -- begin
14848f57
AC
2732 -- F := False;
2733 -- C := Ada.Tags.POK_Function;
80b992ae
HK
2734 -- end _Disp_Conditional_Select;
2735
2736 -- For protected types, generate:
2737
2738 -- procedure _Disp_Conditional_Select
2739 -- (T : in out <Typ>;
2740 -- S : Integer;
2741 -- P : System.Address;
2742 -- C : out Ada.Tags.Prim_Op_Kind;
2743 -- F : out Boolean)
2744 -- is
2745 -- I : Integer;
2746 -- Bnn : System.Tasking.Protected_Objects.Operations.
2747 -- Communication_Block;
2748
2749 -- begin
2750 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP, S));
2751
2752 -- if C = Ada.Tags.POK_Procedure
2753 -- or else C = Ada.Tags.POK_Protected_Procedure
2754 -- or else C = Ada.Tags.POK_Task_Procedure
2755 -- then
2756 -- F := True;
2757 -- return;
2758 -- end if;
2759
2760 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2761 -- System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
2762 -- (T.object'Access,
2763 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
2764 -- P,
2765 -- System.Tasking.Conditional_Call,
2766 -- Bnn);
2767 -- F := not Cancelled (Bnn);
2768 -- end _Disp_Conditional_Select;
2769
2770 -- For task types, generate:
2771
2772 -- procedure _Disp_Conditional_Select
2773 -- (T : in out <Typ>;
2774 -- S : Integer;
2775 -- P : System.Address;
2776 -- C : out Ada.Tags.Prim_Op_Kind;
2777 -- F : out Boolean)
2778 -- is
2779 -- I : Integer;
2780
2781 -- begin
2782 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
2783 -- System.Tasking.Rendezvous.Task_Entry_Call
2784 -- (T._task_id,
2785 -- System.Tasking.Task_Entry_Index (I),
2786 -- P,
2787 -- System.Tasking.Conditional_Call,
2788 -- F);
2789 -- end _Disp_Conditional_Select;
2790
f4d379b8
HK
2791 function Make_Disp_Conditional_Select_Body
2792 (Typ : Entity_Id) return Node_Id
2793 is
2794 Loc : constant Source_Ptr := Sloc (Typ);
2795 Blk_Nam : Entity_Id;
2796 Conc_Typ : Entity_Id := Empty;
2797 Decls : constant List_Id := New_List;
1923d2d6 2798 Obj_Ref : Node_Id;
f4d379b8 2799 Stmts : constant List_Id := New_List;
e8374e7a 2800 Tag_Node : Node_Id;
70482933 2801
f4d379b8 2802 begin
b0efe69e
JM
2803 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
2804
4d744221
JM
2805 -- Null body is generated for interface types
2806
f4d379b8
HK
2807 if Is_Interface (Typ) then
2808 return
2809 Make_Subprogram_Body (Loc,
6782b1ef 2810 Specification =>
f4d379b8 2811 Make_Disp_Conditional_Select_Spec (Typ),
6782b1ef 2812 Declarations => No_List,
f4d379b8
HK
2813 Handled_Statement_Sequence =>
2814 Make_Handled_Sequence_Of_Statements (Loc,
14848f57 2815 New_List (Make_Assignment_Statement (Loc,
833eaa8a 2816 Name => Make_Identifier (Loc, Name_uF),
e4494292 2817 Expression => New_Occurrence_Of (Standard_False, Loc)))));
f4d379b8 2818 end if;
70482933 2819
4d744221
JM
2820 if Is_Concurrent_Record_Type (Typ) then
2821 Conc_Typ := Corresponding_Concurrent_Type (Typ);
70482933 2822
f4d379b8
HK
2823 -- Generate:
2824 -- I : Integer;
70482933 2825
f4d379b8
HK
2826 -- where I will be used to capture the entry index of the primitive
2827 -- wrapper at position S.
70482933 2828
f4d379b8
HK
2829 Append_To (Decls,
2830 Make_Object_Declaration (Loc,
6782b1ef
AC
2831 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uI),
2832 Object_Definition =>
e4494292 2833 New_Occurrence_Of (Standard_Integer, Loc)));
70482933 2834
4d744221 2835 -- Generate:
80b992ae 2836 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag! (<type>VP), S);
70482933 2837
4d744221
JM
2838 -- if C = POK_Procedure
2839 -- or else C = POK_Protected_Procedure
2840 -- or else C = POK_Task_Procedure;
2841 -- then
2842 -- F := True;
2843 -- return;
2844 -- end if;
758c442c 2845
1138cf59 2846 Build_Common_Dispatching_Select_Statements (Typ, Stmts);
758c442c 2847
f4d379b8
HK
2848 -- Generate:
2849 -- Bnn : Communication_Block;
758c442c 2850
80b992ae
HK
2851 -- where Bnn is the name of the communication block used in the
2852 -- call to Protected_Entry_Call.
758c442c 2853
2287a75d 2854 Blk_Nam := Make_Temporary (Loc, 'B');
f4d379b8
HK
2855 Append_To (Decls,
2856 Make_Object_Declaration (Loc,
6782b1ef
AC
2857 Defining_Identifier => Blk_Nam,
2858 Object_Definition =>
e4494292 2859 New_Occurrence_Of (RTE (RE_Communication_Block), Loc)));
758c442c 2860
f4d379b8 2861 -- Generate:
80b992ae 2862 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);
758c442c 2863
f4d379b8 2864 -- I is the entry index and S is the dispatch table slot
758c442c 2865
e8374e7a
AC
2866 if Tagged_Type_Expansion then
2867 Tag_Node :=
2868 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 2869 New_Occurrence_Of
e8374e7a
AC
2870 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));
2871
2872 else
2873 Tag_Node :=
2874 Make_Attribute_Reference (Loc,
6782b1ef 2875 Prefix => New_Occurrence_Of (Typ, Loc),
e8374e7a
AC
2876 Attribute_Name => Name_Tag);
2877 end if;
2878
f4d379b8
HK
2879 Append_To (Stmts,
2880 Make_Assignment_Statement (Loc,
6782b1ef 2881 Name => Make_Identifier (Loc, Name_uI),
f4d379b8 2882 Expression =>
d0dd5209 2883 Make_Function_Call (Loc,
6782b1ef 2884 Name =>
e4494292 2885 New_Occurrence_Of (RTE (RE_Get_Entry_Index), Loc),
6782b1ef
AC
2886 Parameter_Associations => New_List (
2887 Tag_Node,
2888 Make_Identifier (Loc, Name_uS)))));
70482933 2889
f4d379b8 2890 if Ekind (Conc_Typ) = E_Protected_Type then
70482933 2891
1923d2d6
JM
2892 Obj_Ref := -- T._object'Access
2893 Make_Attribute_Reference (Loc,
2894 Attribute_Name => Name_Unchecked_Access,
2895 Prefix =>
2896 Make_Selected_Component (Loc,
2897 Prefix => Make_Identifier (Loc, Name_uT),
2898 Selector_Name => Make_Identifier (Loc, Name_uObject)));
70482933 2899
1923d2d6
JM
2900 case Corresponding_Runtime_Package (Conc_Typ) is
2901 when System_Tasking_Protected_Objects_Entries =>
2902 -- Generate:
3ca505dc 2903
1923d2d6
JM
2904 -- Protected_Entry_Call
2905 -- (T._object'Access, -- Object
2906 -- Protected_Entry_Index! (I), -- E
2907 -- P, -- Uninterpreted_Data
2908 -- Conditional_Call, -- Mode
2909 -- Bnn); -- Block
3ca505dc 2910
1923d2d6
JM
2911 -- where T is the protected object, I is the entry index, P
2912 -- are the wrapped parameters and Bnn is the name of the
2913 -- communication block.
10b93b2e 2914
1923d2d6
JM
2915 Append_To (Stmts,
2916 Make_Procedure_Call_Statement (Loc,
6782b1ef 2917 Name =>
e4494292 2918 New_Occurrence_Of (RTE (RE_Protected_Entry_Call), Loc),
6782b1ef 2919 Parameter_Associations => New_List (
1923d2d6 2920 Obj_Ref,
10b93b2e 2921
1923d2d6
JM
2922 Make_Unchecked_Type_Conversion (Loc, -- entry index
2923 Subtype_Mark =>
e4494292 2924 New_Occurrence_Of
1923d2d6
JM
2925 (RTE (RE_Protected_Entry_Index), Loc),
2926 Expression => Make_Identifier (Loc, Name_uI)),
2927
2928 Make_Identifier (Loc, Name_uP), -- parameter block
2929
e4494292
RD
2930 New_Occurrence_Of -- Conditional_Call
2931 (RTE (RE_Conditional_Call), Loc),
2932 New_Occurrence_Of -- Bnn
2933 (Blk_Nam, Loc))));
1923d2d6
JM
2934
2935 when System_Tasking_Protected_Objects_Single_Entry =>
2936
2937 -- If we are compiling for a restricted run-time, the call
2938 -- uses the simpler form.
2939
2940 Append_To (Stmts,
2941 Make_Procedure_Call_Statement (Loc,
6782b1ef 2942 Name =>
e4494292 2943 New_Occurrence_Of
1923d2d6 2944 (RTE (RE_Protected_Single_Entry_Call), Loc),
6782b1ef 2945 Parameter_Associations => New_List (
1923d2d6
JM
2946 Obj_Ref,
2947
2948 Make_Attribute_Reference (Loc,
7675ad4f 2949 Prefix => Make_Identifier (Loc, Name_uP),
1923d2d6
JM
2950 Attribute_Name => Name_Address),
2951
e4494292 2952 New_Occurrence_Of
1923d2d6
JM
2953 (RTE (RE_Conditional_Call), Loc))));
2954 when others =>
2955 raise Program_Error;
2956 end case;
10b93b2e 2957
f4d379b8
HK
2958 -- Generate:
2959 -- F := not Cancelled (Bnn);
3ca505dc 2960
f4d379b8 2961 -- where F is the success flag. The status of Cancelled is negated
9c582551 2962 -- in order to match the behavior of the version for task types.
3ca505dc 2963
f4d379b8
HK
2964 Append_To (Stmts,
2965 Make_Assignment_Statement (Loc,
7675ad4f 2966 Name => Make_Identifier (Loc, Name_uF),
f4d379b8
HK
2967 Expression =>
2968 Make_Op_Not (Loc,
2969 Right_Opnd =>
2970 Make_Function_Call (Loc,
6782b1ef 2971 Name =>
e4494292 2972 New_Occurrence_Of (RTE (RE_Cancelled), Loc),
6782b1ef 2973 Parameter_Associations => New_List (
e4494292 2974 New_Occurrence_Of (Blk_Nam, Loc))))));
f4d379b8
HK
2975 else
2976 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
10b93b2e 2977
f4d379b8 2978 -- Generate:
80b992ae
HK
2979 -- Task_Entry_Call
2980 -- (T._task_id, -- Acceptor
2981 -- Task_Entry_Index! (I), -- E
2982 -- P, -- Uninterpreted_Data
2983 -- Conditional_Call, -- Mode
2984 -- F); -- Rendezvous_Successful
10b93b2e 2985
f4d379b8
HK
2986 -- where T is the task object, I is the entry index, P are the
2987 -- wrapped parameters and F is the status flag.
3ca505dc 2988
f4d379b8
HK
2989 Append_To (Stmts,
2990 Make_Procedure_Call_Statement (Loc,
6782b1ef 2991 Name =>
e4494292 2992 New_Occurrence_Of (RTE (RE_Task_Entry_Call), Loc),
6782b1ef 2993 Parameter_Associations => New_List (
f4d379b8
HK
2994
2995 Make_Selected_Component (Loc, -- T._task_id
7675ad4f
AC
2996 Prefix => Make_Identifier (Loc, Name_uT),
2997 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
f4d379b8
HK
2998
2999 Make_Unchecked_Type_Conversion (Loc, -- entry index
3000 Subtype_Mark =>
e4494292 3001 New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
7675ad4f 3002 Expression => Make_Identifier (Loc, Name_uI)),
f4d379b8
HK
3003
3004 Make_Identifier (Loc, Name_uP), -- parameter block
e4494292 3005 New_Occurrence_Of -- Conditional_Call
7675ad4f 3006 (RTE (RE_Conditional_Call), Loc),
f4d379b8 3007 Make_Identifier (Loc, Name_uF)))); -- status flag
10b93b2e 3008 end if;
f2abc637
AC
3009
3010 else
14848f57 3011 -- Initialize out parameters
f2abc637 3012
14848f57
AC
3013 Append_To (Stmts,
3014 Make_Assignment_Statement (Loc,
833eaa8a 3015 Name => Make_Identifier (Loc, Name_uF),
e4494292 3016 Expression => New_Occurrence_Of (Standard_False, Loc)));
14848f57
AC
3017 Append_To (Stmts,
3018 Make_Assignment_Statement (Loc,
833eaa8a 3019 Name => Make_Identifier (Loc, Name_uC),
e4494292 3020 Expression => New_Occurrence_Of (RTE (RE_POK_Function), Loc)));
f4d379b8
HK
3021 end if;
3022
3023 return
3024 Make_Subprogram_Body (Loc,
833eaa8a 3025 Specification =>
f4d379b8 3026 Make_Disp_Conditional_Select_Spec (Typ),
833eaa8a 3027 Declarations => Decls,
f4d379b8
HK
3028 Handled_Statement_Sequence =>
3029 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
3030 end Make_Disp_Conditional_Select_Body;
3031
3032 ---------------------------------------
3033 -- Make_Disp_Conditional_Select_Spec --
3034 ---------------------------------------
3035
3036 function Make_Disp_Conditional_Select_Spec
3037 (Typ : Entity_Id) return Node_Id
3038 is
3039 Loc : constant Source_Ptr := Sloc (Typ);
3040 Def_Id : constant Node_Id :=
3041 Make_Defining_Identifier (Loc,
3042 Name_uDisp_Conditional_Select);
3043 Params : constant List_Id := New_List;
3044
3045 begin
b0efe69e
JM
3046 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3047
d0dd5209
JM
3048 -- T : in out Typ; -- Object parameter
3049 -- S : Integer; -- Primitive operation slot
3050 -- P : Address; -- Wrapped parameters
3051 -- C : out Prim_Op_Kind; -- Call kind
3052 -- F : out Boolean; -- Status flag
3053
3054 Append_List_To (Params, New_List (
3055
3056 Make_Parameter_Specification (Loc,
6782b1ef
AC
3057 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
3058 Parameter_Type => New_Occurrence_Of (Typ, Loc),
3059 In_Present => True,
3060 Out_Present => True),
d0dd5209
JM
3061
3062 Make_Parameter_Specification (Loc,
6782b1ef
AC
3063 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uS),
3064 Parameter_Type => New_Occurrence_Of (Standard_Integer, Loc)),
d0dd5209
JM
3065
3066 Make_Parameter_Specification (Loc,
6782b1ef
AC
3067 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uP),
3068 Parameter_Type => New_Occurrence_Of (RTE (RE_Address), Loc)),
f4d379b8 3069
d0dd5209 3070 Make_Parameter_Specification (Loc,
6782b1ef
AC
3071 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uC),
3072 Parameter_Type =>
e4494292 3073 New_Occurrence_Of (RTE (RE_Prim_Op_Kind), Loc),
6782b1ef 3074 Out_Present => True),
f4d379b8 3075
d0dd5209 3076 Make_Parameter_Specification (Loc,
6782b1ef
AC
3077 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uF),
3078 Parameter_Type => New_Occurrence_Of (Standard_Boolean, Loc),
3079 Out_Present => True)));
f4d379b8
HK
3080
3081 return
3082 Make_Procedure_Specification (Loc,
3083 Defining_Unit_Name => Def_Id,
3084 Parameter_Specifications => Params);
3085 end Make_Disp_Conditional_Select_Spec;
3086
3087 -------------------------------------
3088 -- Make_Disp_Get_Prim_Op_Kind_Body --
3089 -------------------------------------
3090
6782b1ef 3091 function Make_Disp_Get_Prim_Op_Kind_Body (Typ : Entity_Id) return Node_Id is
e8374e7a
AC
3092 Loc : constant Source_Ptr := Sloc (Typ);
3093 Tag_Node : Node_Id;
f4d379b8
HK
3094
3095 begin
b0efe69e
JM
3096 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3097
f4d379b8
HK
3098 if Is_Interface (Typ) then
3099 return
3100 Make_Subprogram_Body (Loc,
6782b1ef 3101 Specification =>
f4d379b8 3102 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
6782b1ef 3103 Declarations => New_List,
f4d379b8
HK
3104 Handled_Statement_Sequence =>
3105 Make_Handled_Sequence_Of_Statements (Loc,
3106 New_List (Make_Null_Statement (Loc))));
3ca505dc
JM
3107 end if;
3108
10b93b2e 3109 -- Generate:
f4d379b8 3110 -- C := get_prim_op_kind (tag! (<type>VP), S);
70482933 3111
f4d379b8
HK
3112 -- where C is the out parameter capturing the call kind and S is the
3113 -- dispatch table slot number.
70482933 3114
e8374e7a
AC
3115 if Tagged_Type_Expansion then
3116 Tag_Node :=
3117 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 3118 New_Occurrence_Of
e8374e7a
AC
3119 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));
3120
3121 else
3122 Tag_Node :=
3123 Make_Attribute_Reference (Loc,
6782b1ef 3124 Prefix => New_Occurrence_Of (Typ, Loc),
e8374e7a
AC
3125 Attribute_Name => Name_Tag);
3126 end if;
3127
f4d379b8
HK
3128 return
3129 Make_Subprogram_Body (Loc,
6782b1ef 3130 Specification =>
f4d379b8 3131 Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
6782b1ef 3132 Declarations => New_List,
f4d379b8
HK
3133 Handled_Statement_Sequence =>
3134 Make_Handled_Sequence_Of_Statements (Loc,
3135 New_List (
3136 Make_Assignment_Statement (Loc,
6782b1ef 3137 Name => Make_Identifier (Loc, Name_uC),
f4d379b8 3138 Expression =>
d0dd5209
JM
3139 Make_Function_Call (Loc,
3140 Name =>
e4494292 3141 New_Occurrence_Of (RTE (RE_Get_Prim_Op_Kind), Loc),
d0dd5209 3142 Parameter_Associations => New_List (
e8374e7a
AC
3143 Tag_Node,
3144 Make_Identifier (Loc, Name_uS)))))));
f4d379b8 3145 end Make_Disp_Get_Prim_Op_Kind_Body;
3ca505dc 3146
f4d379b8
HK
3147 -------------------------------------
3148 -- Make_Disp_Get_Prim_Op_Kind_Spec --
3149 -------------------------------------
3ca505dc 3150
f4d379b8
HK
3151 function Make_Disp_Get_Prim_Op_Kind_Spec
3152 (Typ : Entity_Id) return Node_Id
3153 is
3154 Loc : constant Source_Ptr := Sloc (Typ);
3155 Def_Id : constant Node_Id :=
6782b1ef 3156 Make_Defining_Identifier (Loc, Name_uDisp_Get_Prim_Op_Kind);
f4d379b8 3157 Params : constant List_Id := New_List;
3ca505dc 3158
f4d379b8 3159 begin
b0efe69e
JM
3160 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3161
d0dd5209
JM
3162 -- T : in out Typ; -- Object parameter
3163 -- S : Integer; -- Primitive operation slot
3164 -- C : out Prim_Op_Kind; -- Call kind
3165
3166 Append_List_To (Params, New_List (
3167
3168 Make_Parameter_Specification (Loc,
6782b1ef
AC
3169 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
3170 Parameter_Type => New_Occurrence_Of (Typ, Loc),
3171 In_Present => True,
3172 Out_Present => True),
70482933 3173
d0dd5209 3174 Make_Parameter_Specification (Loc,
6782b1ef
AC
3175 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uS),
3176 Parameter_Type => New_Occurrence_Of (Standard_Integer, Loc)),
70482933 3177
d0dd5209 3178 Make_Parameter_Specification (Loc,
6782b1ef
AC
3179 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uC),
3180 Parameter_Type =>
e4494292 3181 New_Occurrence_Of (RTE (RE_Prim_Op_Kind), Loc),
6782b1ef 3182 Out_Present => True)));
f4d379b8
HK
3183
3184 return
3185 Make_Procedure_Specification (Loc,
3186 Defining_Unit_Name => Def_Id,
3187 Parameter_Specifications => Params);
3188 end Make_Disp_Get_Prim_Op_Kind_Spec;
3189
3190 --------------------------------
3191 -- Make_Disp_Get_Task_Id_Body --
3192 --------------------------------
3193
3194 function Make_Disp_Get_Task_Id_Body
3195 (Typ : Entity_Id) return Node_Id
3196 is
3197 Loc : constant Source_Ptr := Sloc (Typ);
3198 Ret : Node_Id;
3199
3200 begin
b0efe69e
JM
3201 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3202
f4d379b8
HK
3203 if Is_Concurrent_Record_Type (Typ)
3204 and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
3205 then
d0dd5209
JM
3206 -- Generate:
3207 -- return To_Address (_T._task_id);
3208
f4d379b8 3209 Ret :=
b2e1beb3 3210 Make_Simple_Return_Statement (Loc,
f4d379b8 3211 Expression =>
d0dd5209 3212 Make_Unchecked_Type_Conversion (Loc,
6782b1ef
AC
3213 Subtype_Mark => New_Occurrence_Of (RTE (RE_Address), Loc),
3214 Expression =>
d0dd5209 3215 Make_Selected_Component (Loc,
7675ad4f
AC
3216 Prefix => Make_Identifier (Loc, Name_uT),
3217 Selector_Name => Make_Identifier (Loc, Name_uTask_Id))));
f4d379b8
HK
3218
3219 -- A null body is constructed for non-task types
3220
3221 else
d0dd5209
JM
3222 -- Generate:
3223 -- return Null_Address;
3224
f4d379b8 3225 Ret :=
b2e1beb3 3226 Make_Simple_Return_Statement (Loc,
6782b1ef 3227 Expression => New_Occurrence_Of (RTE (RE_Null_Address), Loc));
f4d379b8
HK
3228 end if;
3229
3230 return
3231 Make_Subprogram_Body (Loc,
6782b1ef
AC
3232 Specification => Make_Disp_Get_Task_Id_Spec (Typ),
3233 Declarations => New_List,
f4d379b8 3234 Handled_Statement_Sequence =>
6782b1ef 3235 Make_Handled_Sequence_Of_Statements (Loc, New_List (Ret)));
f4d379b8
HK
3236 end Make_Disp_Get_Task_Id_Body;
3237
3238 --------------------------------
3239 -- Make_Disp_Get_Task_Id_Spec --
3240 --------------------------------
3241
3242 function Make_Disp_Get_Task_Id_Spec
3243 (Typ : Entity_Id) return Node_Id
3244 is
d0dd5209 3245 Loc : constant Source_Ptr := Sloc (Typ);
f4d379b8
HK
3246
3247 begin
b0efe69e
JM
3248 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3249
f4d379b8
HK
3250 return
3251 Make_Function_Specification (Loc,
6782b1ef 3252 Defining_Unit_Name =>
d0dd5209 3253 Make_Defining_Identifier (Loc, Name_uDisp_Get_Task_Id),
f4d379b8
HK
3254 Parameter_Specifications => New_List (
3255 Make_Parameter_Specification (Loc,
6782b1ef
AC
3256 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
3257 Parameter_Type => New_Occurrence_Of (Typ, Loc))),
3258 Result_Definition =>
e4494292 3259 New_Occurrence_Of (RTE (RE_Address), Loc));
f4d379b8
HK
3260 end Make_Disp_Get_Task_Id_Spec;
3261
80b992ae
HK
3262 ----------------------------
3263 -- Make_Disp_Requeue_Body --
3264 ----------------------------
3265
3266 function Make_Disp_Requeue_Body
3267 (Typ : Entity_Id) return Node_Id
3268 is
3269 Loc : constant Source_Ptr := Sloc (Typ);
3270 Conc_Typ : Entity_Id := Empty;
3271 Stmts : constant List_Id := New_List;
3272
3273 begin
3274 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3275
3276 -- Null body is generated for interface types and non-concurrent
3277 -- tagged types.
3278
3279 if Is_Interface (Typ)
3280 or else not Is_Concurrent_Record_Type (Typ)
3281 then
3282 return
3283 Make_Subprogram_Body (Loc,
6782b1ef
AC
3284 Specification => Make_Disp_Requeue_Spec (Typ),
3285 Declarations => No_List,
80b992ae
HK
3286 Handled_Statement_Sequence =>
3287 Make_Handled_Sequence_Of_Statements (Loc,
3288 New_List (Make_Null_Statement (Loc))));
3289 end if;
3290
3291 Conc_Typ := Corresponding_Concurrent_Type (Typ);
3292
3293 if Ekind (Conc_Typ) = E_Protected_Type then
3294
3295 -- Generate statements:
3296 -- if F then
3297 -- System.Tasking.Protected_Objects.Operations.
3298 -- Requeue_Protected_Entry
3299 -- (Protection_Entries_Access (P),
3300 -- O._object'Unchecked_Access,
3301 -- Protected_Entry_Index (I),
3302 -- A);
3303 -- else
3304 -- System.Tasking.Protected_Objects.Operations.
3305 -- Requeue_Task_To_Protected_Entry
3306 -- (O._object'Unchecked_Access,
3307 -- Protected_Entry_Index (I),
3308 -- A);
3309 -- end if;
3310
1923d2d6
JM
3311 if Restriction_Active (No_Entry_Queue) then
3312 Append_To (Stmts, Make_Null_Statement (Loc));
3313 else
3314 Append_To (Stmts,
3315 Make_If_Statement (Loc,
7675ad4f 3316 Condition => Make_Identifier (Loc, Name_uF),
80b992ae 3317
1923d2d6
JM
3318 Then_Statements =>
3319 New_List (
80b992ae 3320
1923d2d6 3321 -- Call to Requeue_Protected_Entry
80b992ae 3322
1923d2d6
JM
3323 Make_Procedure_Call_Statement (Loc,
3324 Name =>
6782b1ef
AC
3325 New_Occurrence_Of
3326 (RTE (RE_Requeue_Protected_Entry), Loc),
1923d2d6
JM
3327 Parameter_Associations =>
3328 New_List (
3329
3330 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
3331 Subtype_Mark =>
e4494292 3332 New_Occurrence_Of (
1923d2d6
JM
3333 RTE (RE_Protection_Entries_Access), Loc),
3334 Expression =>
3335 Make_Identifier (Loc, Name_uP)),
3336
3337 Make_Attribute_Reference (Loc, -- O._object'Acc
3338 Attribute_Name =>
3339 Name_Unchecked_Access,
6782b1ef 3340 Prefix =>
1923d2d6 3341 Make_Selected_Component (Loc,
7675ad4f 3342 Prefix =>
1923d2d6
JM
3343 Make_Identifier (Loc, Name_uO),
3344 Selector_Name =>
3345 Make_Identifier (Loc, Name_uObject))),
3346
3347 Make_Unchecked_Type_Conversion (Loc, -- entry index
3348 Subtype_Mark =>
6782b1ef
AC
3349 New_Occurrence_Of
3350 (RTE (RE_Protected_Entry_Index), Loc),
7675ad4f 3351 Expression => Make_Identifier (Loc, Name_uI)),
80b992ae 3352
1923d2d6 3353 Make_Identifier (Loc, Name_uA)))), -- abort status
80b992ae 3354
1923d2d6
JM
3355 Else_Statements =>
3356 New_List (
80b992ae 3357
1923d2d6 3358 -- Call to Requeue_Task_To_Protected_Entry
80b992ae 3359
1923d2d6
JM
3360 Make_Procedure_Call_Statement (Loc,
3361 Name =>
6782b1ef
AC
3362 New_Occurrence_Of
3363 (RTE (RE_Requeue_Task_To_Protected_Entry), Loc),
1923d2d6
JM
3364 Parameter_Associations =>
3365 New_List (
3366
3367 Make_Attribute_Reference (Loc, -- O._object'Acc
6782b1ef
AC
3368 Attribute_Name => Name_Unchecked_Access,
3369 Prefix =>
1923d2d6 3370 Make_Selected_Component (Loc,
6782b1ef 3371 Prefix =>
1923d2d6
JM
3372 Make_Identifier (Loc, Name_uO),
3373 Selector_Name =>
3374 Make_Identifier (Loc, Name_uObject))),
3375
3376 Make_Unchecked_Type_Conversion (Loc, -- entry index
3377 Subtype_Mark =>
6782b1ef
AC
3378 New_Occurrence_Of
3379 (RTE (RE_Protected_Entry_Index), Loc),
3380 Expression => Make_Identifier (Loc, Name_uI)),
80b992ae 3381
1923d2d6
JM
3382 Make_Identifier (Loc, Name_uA)))))); -- abort status
3383 end if;
6782b1ef 3384
80b992ae
HK
3385 else
3386 pragma Assert (Is_Task_Type (Conc_Typ));
3387
3388 -- Generate:
3389 -- if F then
3390 -- System.Tasking.Rendezvous.Requeue_Protected_To_Task_Entry
3391 -- (Protection_Entries_Access (P),
3392 -- O._task_id,
3393 -- Task_Entry_Index (I),
3394 -- A);
3395 -- else
3396 -- System.Tasking.Rendezvous.Requeue_Task_Entry
3397 -- (O._task_id,
3398 -- Task_Entry_Index (I),
3399 -- A);
3400 -- end if;
3401
3402 Append_To (Stmts,
3403 Make_If_Statement (Loc,
7675ad4f 3404 Condition => Make_Identifier (Loc, Name_uF),
80b992ae 3405
7675ad4f 3406 Then_Statements => New_List (
80b992ae 3407
7675ad4f 3408 -- Call to Requeue_Protected_To_Task_Entry
80b992ae 3409
7675ad4f
AC
3410 Make_Procedure_Call_Statement (Loc,
3411 Name =>
e4494292 3412 New_Occurrence_Of
7675ad4f 3413 (RTE (RE_Requeue_Protected_To_Task_Entry), Loc),
80b992ae 3414
7675ad4f 3415 Parameter_Associations => New_List (
80b992ae 3416
7675ad4f
AC
3417 Make_Unchecked_Type_Conversion (Loc, -- PEA (P)
3418 Subtype_Mark =>
e4494292 3419 New_Occurrence_Of
7675ad4f
AC
3420 (RTE (RE_Protection_Entries_Access), Loc),
3421 Expression => Make_Identifier (Loc, Name_uP)),
80b992ae 3422
7675ad4f
AC
3423 Make_Selected_Component (Loc, -- O._task_id
3424 Prefix => Make_Identifier (Loc, Name_uO),
3425 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
80b992ae 3426
7675ad4f
AC
3427 Make_Unchecked_Type_Conversion (Loc, -- entry index
3428 Subtype_Mark =>
e4494292 3429 New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
7675ad4f 3430 Expression => Make_Identifier (Loc, Name_uI)),
80b992ae 3431
7675ad4f 3432 Make_Identifier (Loc, Name_uA)))), -- abort status
80b992ae 3433
7675ad4f 3434 Else_Statements => New_List (
80b992ae 3435
7675ad4f 3436 -- Call to Requeue_Task_Entry
80b992ae 3437
7675ad4f 3438 Make_Procedure_Call_Statement (Loc,
6782b1ef
AC
3439 Name =>
3440 New_Occurrence_Of (RTE (RE_Requeue_Task_Entry), Loc),
80b992ae 3441
7675ad4f 3442 Parameter_Associations => New_List (
80b992ae 3443
7675ad4f
AC
3444 Make_Selected_Component (Loc, -- O._task_id
3445 Prefix => Make_Identifier (Loc, Name_uO),
3446 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
80b992ae 3447
7675ad4f
AC
3448 Make_Unchecked_Type_Conversion (Loc, -- entry index
3449 Subtype_Mark =>
e4494292 3450 New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
7675ad4f 3451 Expression => Make_Identifier (Loc, Name_uI)),
80b992ae 3452
7675ad4f 3453 Make_Identifier (Loc, Name_uA)))))); -- abort status
80b992ae
HK
3454 end if;
3455
3456 -- Even though no declarations are needed in both cases, we allocate
3457 -- a list for entities added by Freeze.
3458
3459 return
3460 Make_Subprogram_Body (Loc,
6782b1ef
AC
3461 Specification => Make_Disp_Requeue_Spec (Typ),
3462 Declarations => New_List,
80b992ae
HK
3463 Handled_Statement_Sequence =>
3464 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
3465 end Make_Disp_Requeue_Body;
3466
3467 ----------------------------
3468 -- Make_Disp_Requeue_Spec --
3469 ----------------------------
3470
3471 function Make_Disp_Requeue_Spec
3472 (Typ : Entity_Id) return Node_Id
3473 is
3474 Loc : constant Source_Ptr := Sloc (Typ);
3475
3476 begin
3477 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3478
3479 -- O : in out Typ; - Object parameter
3480 -- F : Boolean; - Protected (True) / task (False) flag
3481 -- P : Address; - Protection_Entries_Access value
3482 -- I : Entry_Index - Index of entry call
3483 -- A : Boolean - Abort flag
3484
3485 -- Note that the Protection_Entries_Access value is represented as a
3486 -- System.Address in order to avoid dragging in the tasking runtime
3487 -- when compiling sources without tasking constructs.
3488
3489 return
3490 Make_Procedure_Specification (Loc,
3491 Defining_Unit_Name =>
3492 Make_Defining_Identifier (Loc, Name_uDisp_Requeue),
3493
6782b1ef 3494 Parameter_Specifications => New_List (
80b992ae
HK
3495
3496 Make_Parameter_Specification (Loc, -- O
3497 Defining_Identifier =>
3498 Make_Defining_Identifier (Loc, Name_uO),
6782b1ef 3499 Parameter_Type =>
e4494292 3500 New_Occurrence_Of (Typ, Loc),
6782b1ef
AC
3501 In_Present => True,
3502 Out_Present => True),
80b992ae
HK
3503
3504 Make_Parameter_Specification (Loc, -- F
3505 Defining_Identifier =>
3506 Make_Defining_Identifier (Loc, Name_uF),
6782b1ef 3507 Parameter_Type =>
e4494292 3508 New_Occurrence_Of (Standard_Boolean, Loc)),
80b992ae
HK
3509
3510 Make_Parameter_Specification (Loc, -- P
3511 Defining_Identifier =>
3512 Make_Defining_Identifier (Loc, Name_uP),
6782b1ef 3513 Parameter_Type =>
e4494292 3514 New_Occurrence_Of (RTE (RE_Address), Loc)),
80b992ae
HK
3515
3516 Make_Parameter_Specification (Loc, -- I
3517 Defining_Identifier =>
3518 Make_Defining_Identifier (Loc, Name_uI),
6782b1ef 3519 Parameter_Type =>
e4494292 3520 New_Occurrence_Of (Standard_Integer, Loc)),
80b992ae
HK
3521
3522 Make_Parameter_Specification (Loc, -- A
3523 Defining_Identifier =>
3524 Make_Defining_Identifier (Loc, Name_uA),
6782b1ef 3525 Parameter_Type =>
e4494292 3526 New_Occurrence_Of (Standard_Boolean, Loc))));
80b992ae
HK
3527 end Make_Disp_Requeue_Spec;
3528
f4d379b8
HK
3529 ---------------------------------
3530 -- Make_Disp_Timed_Select_Body --
3531 ---------------------------------
3532
80b992ae
HK
3533 -- For interface types, generate:
3534
3535 -- procedure _Disp_Timed_Select
3536 -- (T : in out <Typ>;
3537 -- S : Integer;
3538 -- P : System.Address;
3539 -- D : Duration;
3540 -- M : Integer;
3541 -- C : out Ada.Tags.Prim_Op_Kind;
3542 -- F : out Boolean)
3543 -- is
3544 -- begin
14848f57
AC
3545 -- F := False;
3546 -- C := Ada.Tags.POK_Function;
80b992ae
HK
3547 -- end _Disp_Timed_Select;
3548
3549 -- For protected types, generate:
3550
3551 -- procedure _Disp_Timed_Select
3552 -- (T : in out <Typ>;
3553 -- S : Integer;
3554 -- P : System.Address;
3555 -- D : Duration;
3556 -- M : Integer;
3557 -- C : out Ada.Tags.Prim_Op_Kind;
3558 -- F : out Boolean)
3559 -- is
3560 -- I : Integer;
3561
3562 -- begin
3563 -- C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP), S);
3564
3565 -- if C = Ada.Tags.POK_Procedure
3566 -- or else C = Ada.Tags.POK_Protected_Procedure
3567 -- or else C = Ada.Tags.POK_Task_Procedure
3568 -- then
3569 -- F := True;
3570 -- return;
3571 -- end if;
3572
3573 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
3574 -- System.Tasking.Protected_Objects.Operations.
3575 -- Timed_Protected_Entry_Call
3576 -- (T._object'Access,
3577 -- System.Tasking.Protected_Objects.Protected_Entry_Index (I),
3578 -- P,
3579 -- D,
3580 -- M,
3581 -- F);
3582 -- end _Disp_Timed_Select;
3583
3584 -- For task types, generate:
3585
3586 -- procedure _Disp_Timed_Select
3587 -- (T : in out <Typ>;
3588 -- S : Integer;
3589 -- P : System.Address;
3590 -- D : Duration;
3591 -- M : Integer;
3592 -- C : out Ada.Tags.Prim_Op_Kind;
3593 -- F : out Boolean)
3594 -- is
3595 -- I : Integer;
3596
3597 -- begin
3598 -- I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
3599 -- System.Tasking.Rendezvous.Timed_Task_Entry_Call
3600 -- (T._task_id,
3601 -- System.Tasking.Task_Entry_Index (I),
3602 -- P,
3603 -- D,
3604 -- M,
14848f57 3605 -- F);
80b992ae
HK
3606 -- end _Disp_Time_Select;
3607
f4d379b8
HK
3608 function Make_Disp_Timed_Select_Body
3609 (Typ : Entity_Id) return Node_Id
3610 is
3611 Loc : constant Source_Ptr := Sloc (Typ);
3612 Conc_Typ : Entity_Id := Empty;
3613 Decls : constant List_Id := New_List;
1923d2d6 3614 Obj_Ref : Node_Id;
f4d379b8 3615 Stmts : constant List_Id := New_List;
e8374e7a 3616 Tag_Node : Node_Id;
f4d379b8
HK
3617
3618 begin
b0efe69e
JM
3619 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3620
4d744221
JM
3621 -- Null body is generated for interface types
3622
f4d379b8
HK
3623 if Is_Interface (Typ) then
3624 return
3625 Make_Subprogram_Body (Loc,
6782b1ef
AC
3626 Specification => Make_Disp_Timed_Select_Spec (Typ),
3627 Declarations => New_List,
f4d379b8
HK
3628 Handled_Statement_Sequence =>
3629 Make_Handled_Sequence_Of_Statements (Loc,
833eaa8a
AC
3630 New_List (
3631 Make_Assignment_Statement (Loc,
3632 Name => Make_Identifier (Loc, Name_uF),
e4494292 3633 Expression => New_Occurrence_Of (Standard_False, Loc)))));
f4d379b8
HK
3634 end if;
3635
4d744221
JM
3636 if Is_Concurrent_Record_Type (Typ) then
3637 Conc_Typ := Corresponding_Concurrent_Type (Typ);
f4d379b8
HK
3638
3639 -- Generate:
3640 -- I : Integer;
3641
3642 -- where I will be used to capture the entry index of the primitive
3643 -- wrapper at position S.
3644
3645 Append_To (Decls,
3646 Make_Object_Declaration (Loc,
833eaa8a 3647 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uI),
e4494292
RD
3648 Object_Definition =>
3649 New_Occurrence_Of (Standard_Integer, Loc)));
f4d379b8 3650
4d744221
JM
3651 -- Generate:
3652 -- C := Get_Prim_Op_Kind (tag! (<type>VP), S);
f4d379b8 3653
4d744221
JM
3654 -- if C = POK_Procedure
3655 -- or else C = POK_Protected_Procedure
3656 -- or else C = POK_Task_Procedure;
3657 -- then
3658 -- F := True;
3659 -- return;
3660 -- end if;
f4d379b8 3661
1138cf59 3662 Build_Common_Dispatching_Select_Statements (Typ, Stmts);
f4d379b8
HK
3663
3664 -- Generate:
4d744221 3665 -- I := Get_Entry_Index (tag! (<type>VP), S);
f4d379b8
HK
3666
3667 -- I is the entry index and S is the dispatch table slot
3668
e8374e7a
AC
3669 if Tagged_Type_Expansion then
3670 Tag_Node :=
3671 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 3672 New_Occurrence_Of
e8374e7a
AC
3673 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));
3674
3675 else
3676 Tag_Node :=
3677 Make_Attribute_Reference (Loc,
e4494292 3678 Prefix => New_Occurrence_Of (Typ, Loc),
e8374e7a
AC
3679 Attribute_Name => Name_Tag);
3680 end if;
3681
f4d379b8
HK
3682 Append_To (Stmts,
3683 Make_Assignment_Statement (Loc,
7675ad4f 3684 Name => Make_Identifier (Loc, Name_uI),
f4d379b8 3685 Expression =>
d0dd5209 3686 Make_Function_Call (Loc,
e4494292 3687 Name => New_Occurrence_Of (RTE (RE_Get_Entry_Index), Loc),
6782b1ef
AC
3688 Parameter_Associations => New_List (
3689 Tag_Node,
3690 Make_Identifier (Loc, Name_uS)))));
f4d379b8 3691
1923d2d6
JM
3692 -- Protected case
3693
f4d379b8
HK
3694 if Ekind (Conc_Typ) = E_Protected_Type then
3695
1923d2d6
JM
3696 -- Build T._object'Access
3697
3698 Obj_Ref :=
3699 Make_Attribute_Reference (Loc,
3700 Attribute_Name => Name_Unchecked_Access,
3701 Prefix =>
3702 Make_Selected_Component (Loc,
3703 Prefix => Make_Identifier (Loc, Name_uT),
3704 Selector_Name => Make_Identifier (Loc, Name_uObject)));
3705
3706 -- Normal case, No_Entry_Queue restriction not active. In this
3707 -- case we generate:
3708
3709 -- Timed_Protected_Entry_Call
3710 -- (T._object'access,
80b992ae 3711 -- Protected_Entry_Index! (I),
1923d2d6 3712 -- P, D, M, F);
f4d379b8
HK
3713
3714 -- where T is the protected object, I is the entry index, P are
3715 -- the wrapped parameters, D is the delay amount, M is the delay
3716 -- mode and F is the status flag.
3717
bdfb8ec4
AC
3718 -- Historically, there was also an implementation for single
3719 -- entry protected types (in s-tposen). However, it was removed
3720 -- by also testing for no No_Select_Statements restriction in
3721 -- Exp_Utils.Corresponding_Runtime_Package. This simplified the
74c10109
AC
3722 -- implementation of s-tposen.adb and provided consistency between
3723 -- all versions of System.Tasking.Protected_Objects.Single_Entry
3724 -- (s-tposen*.adb).
bdfb8ec4 3725
1923d2d6
JM
3726 case Corresponding_Runtime_Package (Conc_Typ) is
3727 when System_Tasking_Protected_Objects_Entries =>
3728 Append_To (Stmts,
3729 Make_Procedure_Call_Statement (Loc,
3730 Name =>
e4494292 3731 New_Occurrence_Of
1923d2d6 3732 (RTE (RE_Timed_Protected_Entry_Call), Loc),
6782b1ef
AC
3733 Parameter_Associations => New_List (
3734 Obj_Ref,
1923d2d6 3735
6782b1ef
AC
3736 Make_Unchecked_Type_Conversion (Loc, -- entry index
3737 Subtype_Mark =>
3738 New_Occurrence_Of
3739 (RTE (RE_Protected_Entry_Index), Loc),
3740 Expression => Make_Identifier (Loc, Name_uI)),
f4d379b8 3741
d8f43ee6
HK
3742 Make_Identifier (Loc, Name_uP), -- parameter block
3743 Make_Identifier (Loc, Name_uD), -- delay
3744 Make_Identifier (Loc, Name_uM), -- delay mode
6782b1ef 3745 Make_Identifier (Loc, Name_uF)))); -- status flag
f4d379b8 3746
1923d2d6
JM
3747 when others =>
3748 raise Program_Error;
3749 end case;
3750
3751 -- Task case
70482933 3752
70482933 3753 else
f4d379b8
HK
3754 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
3755
3756 -- Generate:
3757 -- Timed_Task_Entry_Call (
3758 -- T._task_id,
80b992ae 3759 -- Task_Entry_Index! (I),
f4d379b8
HK
3760 -- P,
3761 -- D,
3762 -- M,
3763 -- F);
3764
3765 -- where T is the task object, I is the entry index, P are the
3766 -- wrapped parameters, D is the delay amount, M is the delay
3767 -- mode and F is the status flag.
3768
3769 Append_To (Stmts,
3770 Make_Procedure_Call_Statement (Loc,
6782b1ef 3771 Name =>
e4494292 3772 New_Occurrence_Of (RTE (RE_Timed_Task_Entry_Call), Loc),
f4d379b8 3773
6782b1ef
AC
3774 Parameter_Associations => New_List (
3775 Make_Selected_Component (Loc, -- T._task_id
3776 Prefix => Make_Identifier (Loc, Name_uT),
3777 Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
f4d379b8 3778
6782b1ef
AC
3779 Make_Unchecked_Type_Conversion (Loc, -- entry index
3780 Subtype_Mark =>
3781 New_Occurrence_Of (RTE (RE_Task_Entry_Index), Loc),
3782 Expression => Make_Identifier (Loc, Name_uI)),
f4d379b8 3783
6782b1ef
AC
3784 Make_Identifier (Loc, Name_uP), -- parameter block
3785 Make_Identifier (Loc, Name_uD), -- delay
3786 Make_Identifier (Loc, Name_uM), -- delay mode
3787 Make_Identifier (Loc, Name_uF)))); -- status flag
70482933 3788 end if;
f2abc637
AC
3789
3790 else
14848f57 3791 -- Initialize out parameters
f2abc637 3792
14848f57
AC
3793 Append_To (Stmts,
3794 Make_Assignment_Statement (Loc,
833eaa8a 3795 Name => Make_Identifier (Loc, Name_uF),
e4494292 3796 Expression => New_Occurrence_Of (Standard_False, Loc)));
14848f57
AC
3797 Append_To (Stmts,
3798 Make_Assignment_Statement (Loc,
833eaa8a 3799 Name => Make_Identifier (Loc, Name_uC),
e4494292 3800 Expression => New_Occurrence_Of (RTE (RE_POK_Function), Loc)));
f4d379b8
HK
3801 end if;
3802
3803 return
3804 Make_Subprogram_Body (Loc,
833eaa8a
AC
3805 Specification => Make_Disp_Timed_Select_Spec (Typ),
3806 Declarations => Decls,
f4d379b8
HK
3807 Handled_Statement_Sequence =>
3808 Make_Handled_Sequence_Of_Statements (Loc, Stmts));
3809 end Make_Disp_Timed_Select_Body;
3810
3811 ---------------------------------
3812 -- Make_Disp_Timed_Select_Spec --
3813 ---------------------------------
3814
3815 function Make_Disp_Timed_Select_Spec
3816 (Typ : Entity_Id) return Node_Id
3817 is
3818 Loc : constant Source_Ptr := Sloc (Typ);
3819 Def_Id : constant Node_Id :=
3820 Make_Defining_Identifier (Loc,
3821 Name_uDisp_Timed_Select);
3822 Params : constant List_Id := New_List;
70482933 3823
f4d379b8 3824 begin
b0efe69e
JM
3825 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
3826
d0dd5209
JM
3827 -- T : in out Typ; -- Object parameter
3828 -- S : Integer; -- Primitive operation slot
3829 -- P : Address; -- Wrapped parameters
3830 -- D : Duration; -- Delay
3831 -- M : Integer; -- Delay Mode
3832 -- C : out Prim_Op_Kind; -- Call kind
3833 -- F : out Boolean; -- Status flag
f4d379b8 3834
d0dd5209
JM
3835 Append_List_To (Params, New_List (
3836
3837 Make_Parameter_Specification (Loc,
6782b1ef
AC
3838 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
3839 Parameter_Type => New_Occurrence_Of (Typ, Loc),
3840 In_Present => True,
3841 Out_Present => True),
d0dd5209
JM
3842
3843 Make_Parameter_Specification (Loc,
6782b1ef
AC
3844 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uS),
3845 Parameter_Type => New_Occurrence_Of (Standard_Integer, Loc)),
d0dd5209
JM
3846
3847 Make_Parameter_Specification (Loc,
6782b1ef
AC
3848 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uP),
3849 Parameter_Type => New_Occurrence_Of (RTE (RE_Address), Loc)),
f4d379b8 3850
f4d379b8 3851 Make_Parameter_Specification (Loc,
6782b1ef
AC
3852 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uD),
3853 Parameter_Type => New_Occurrence_Of (Standard_Duration, Loc)),
f4d379b8 3854
f4d379b8 3855 Make_Parameter_Specification (Loc,
6782b1ef
AC
3856 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uM),
3857 Parameter_Type => New_Occurrence_Of (Standard_Integer, Loc)),
70482933 3858
d0dd5209 3859 Make_Parameter_Specification (Loc,
6782b1ef
AC
3860 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uC),
3861 Parameter_Type =>
e4494292 3862 New_Occurrence_Of (RTE (RE_Prim_Op_Kind), Loc),
6782b1ef 3863 Out_Present => True)));
70482933 3864
d0dd5209
JM
3865 Append_To (Params,
3866 Make_Parameter_Specification (Loc,
6782b1ef
AC
3867 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uF),
3868 Parameter_Type => New_Occurrence_Of (Standard_Boolean, Loc),
3869 Out_Present => True));
70482933 3870
f4d379b8
HK
3871 return
3872 Make_Procedure_Specification (Loc,
3873 Defining_Unit_Name => Def_Id,
3874 Parameter_Specifications => Params);
3875 end Make_Disp_Timed_Select_Spec;
70482933 3876
f4d379b8
HK
3877 -------------
3878 -- Make_DT --
3879 -------------
70482933 3880
d0dd5209 3881 -- The frontend supports two models for expanding dispatch tables
6782b1ef
AC
3882 -- associated with library-level defined tagged types: statically and
3883 -- non-statically allocated dispatch tables. In the former case the object
3884 -- containing the dispatch table is constant and it is initialized by means
3885 -- of a positional aggregate. In the latter case, the object containing
3886 -- the dispatch table is a variable which is initialized by means of
3887 -- assignments.
d0dd5209
JM
3888
3889 -- In case of locally defined tagged types, the object containing the
6782b1ef
AC
3890 -- object containing the dispatch table is always a variable (instead of a
3891 -- constant). This is currently required to give support to late overriding
3892 -- of primitives. For example:
d0dd5209
JM
3893
3894 -- procedure Example is
3895 -- package Pkg is
3896 -- type T1 is tagged null record;
3897 -- procedure Prim (O : T1);
3898 -- end Pkg;
3899
3900 -- type T2 is new Pkg.T1 with null record;
3901 -- procedure Prim (X : T2) is -- late overriding
3902 -- begin
3903 -- ...
3904 -- ...
3905 -- end;
4d744221 3906
b0bf18ad
AC
3907 -- WARNING: This routine manages Ghost regions. Return statements must be
3908 -- replaced by gotos which jump to the end of the routine and restore the
3909 -- Ghost mode.
3910
b2e1beb3
ES
3911 function Make_DT (Typ : Entity_Id; N : Node_Id := Empty) return List_Id is
3912 Loc : constant Source_Ptr := Sloc (Typ);
3913
d0dd5209
JM
3914 Max_Predef_Prims : constant Int :=
3915 UI_To_Int
3916 (Intval
3917 (Expression
b2e1beb3
ES
3918 (Parent (RTE (RE_Max_Predef_Prims)))));
3919
f2cbd970
JM
3920 DT_Decl : constant Elist_Id := New_Elmt_List;
3921 DT_Aggr : constant Elist_Id := New_Elmt_List;
3922 -- Entities marked with attribute Is_Dispatch_Table_Entity
3923
15529d0a
PMR
3924 Dummy_Object : Entity_Id := Empty;
3925 -- Extra nonexistent object of type Typ internally used to compute the
3926 -- offset to the components that reference secondary dispatch tables.
7225a479 3927 -- Used to compute the offset of components located at fixed position.
15529d0a 3928
c0b11850
AC
3929 procedure Check_Premature_Freezing
3930 (Subp : Entity_Id;
3931 Tagged_Type : Entity_Id;
3932 Typ : Entity_Id);
1fb63e89
RD
3933 -- Verify that all untagged types in the profile of a subprogram are
3934 -- frozen at the point the subprogram is frozen. This enforces the rule
3935 -- on RM 13.14 (14) as modified by AI05-019. At the point a subprogram
3936 -- is frozen, enough must be known about it to build the activation
3937 -- record for it, which requires at least that the size of all
3938 -- parameters be known. Controlling arguments are by-reference,
7c0c194b 3939 -- and therefore the rule only applies to untagged types. Typical
1fb63e89
RD
3940 -- violation of the rule involves an object declaration that freezes a
3941 -- tagged type, when one of its primitive operations has a type in its
3942 -- profile whose full view has not been analyzed yet. More complex cases
3943 -- involve composite types that have one private unfrozen subcomponent.
2d6f6e08 3944 -- Move this check to sem???
d0dd5209 3945
b16d9747
JM
3946 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0);
3947 -- Export the dispatch table DT of tagged type Typ. Required to generate
3948 -- forward references and statically allocate the table. For primary
3949 -- dispatch tables Index is 0; for secondary dispatch tables the value
3950 -- of index must match the Suffix_Index value assigned to the table by
3951 -- Make_Tags when generating its unique external name, and it is used to
3952 -- retrieve from the Dispatch_Table_Wrappers list associated with Typ
3953 -- the external name generated by Import_DT.
e18d6a15 3954
d0dd5209 3955 procedure Make_Secondary_DT
1923d2d6
JM
3956 (Typ : Entity_Id;
3957 Iface : Entity_Id;
15529d0a 3958 Iface_Comp : Node_Id;
b16d9747 3959 Suffix_Index : Int;
1923d2d6
JM
3960 Num_Iface_Prims : Nat;
3961 Iface_DT_Ptr : Entity_Id;
3962 Predef_Prims_Ptr : Entity_Id;
3963 Build_Thunks : Boolean;
3964 Result : List_Id);
80b992ae
HK
3965 -- Ada 2005 (AI-251): Expand the declarations for a Secondary Dispatch
3966 -- Table of Typ associated with Iface. Each abstract interface of Typ
3967 -- has two secondary dispatch tables: one containing pointers to thunks
3968 -- and another containing pointers to the primitives covering the
3969 -- interface primitives. The former secondary table is generated when
3970 -- Build_Thunks is True, and provides common support for dispatching
3971 -- calls through interface types; the latter secondary table is
3972 -- generated when Build_Thunks is False, and provides support for
3973 -- Generic Dispatching Constructors that dispatch calls through
53f29d4f
AC
3974 -- interface types. When constructing this latter table the value of
3975 -- Suffix_Index is -1 to indicate that there is no need to export such
3976 -- table when building statically allocated dispatch tables; a positive
3977 -- value of Suffix_Index must match the Suffix_Index value assigned to
3978 -- this secondary dispatch table by Make_Tags when its unique external
3979 -- name was generated.
fbf5a39b 3980
bd5ed03a
JM
3981 function Number_Of_Predefined_Prims (Typ : Entity_Id) return Nat;
3982 -- Returns the number of predefined primitives of Typ
3983
b2e1beb3
ES
3984 ------------------------------
3985 -- Check_Premature_Freezing --
3986 ------------------------------
3987
c0b11850
AC
3988 procedure Check_Premature_Freezing
3989 (Subp : Entity_Id;
3990 Tagged_Type : Entity_Id;
3991 Typ : Entity_Id)
3992 is
3993 Comp : Entity_Id;
c95aa61c
AC
3994
3995 function Is_Actual_For_Formal_Incomplete_Type
3996 (T : Entity_Id) return Boolean;
590549fb
AC
3997 -- In Ada 2012, if a nested generic has an incomplete formal type,
3998 -- the actual may be (and usually is) a private type whose completion
7134062a
AC
3999 -- appears later. It is safe to build the dispatch table in this
4000 -- case, gigi will have full views available.
4001
4002 ------------------------------------------
4003 -- Is_Actual_For_Formal_Incomplete_Type --
4004 ------------------------------------------
4005
c95aa61c
AC
4006 function Is_Actual_For_Formal_Incomplete_Type
4007 (T : Entity_Id) return Boolean
7134062a
AC
4008 is
4009 Gen_Par : Entity_Id;
4010 F : Node_Id;
c95aa61c 4011
7134062a
AC
4012 begin
4013 if not Is_Generic_Instance (Current_Scope)
4014 or else not Used_As_Generic_Actual (T)
4015 then
4016 return False;
7134062a
AC
4017 else
4018 Gen_Par := Generic_Parent (Parent (Current_Scope));
4019 end if;
4020
4021 F :=
4022 First
4023 (Generic_Formal_Declarations
6782b1ef 4024 (Unit_Declaration_Node (Gen_Par)));
7134062a
AC
4025 while Present (F) loop
4026 if Ekind (Defining_Identifier (F)) = E_Incomplete_Type then
4027 return True;
4028 end if;
4029
4030 Next (F);
4031 end loop;
4032
4033 return False;
4034 end Is_Actual_For_Formal_Incomplete_Type;
53f29d4f 4035
c95aa61c
AC
4036 -- Start of processing for Check_Premature_Freezing
4037
b2e1beb3 4038 begin
b7539c3b
AC
4039 -- Note that if the type is a (subtype of) a generic actual, the
4040 -- actual will have been frozen by the instantiation.
4041
b2e1beb3 4042 if Present (N)
c0b11850 4043 and then Is_Private_Type (Typ)
b2e1beb3
ES
4044 and then No (Full_View (Typ))
4045 and then not Is_Generic_Type (Typ)
4046 and then not Is_Tagged_Type (Typ)
4047 and then not Is_Frozen (Typ)
b7539c3b 4048 and then not Is_Generic_Actual_Type (Typ)
b2e1beb3
ES
4049 then
4050 Error_Msg_Sloc := Sloc (Subp);
ed2233dc 4051 Error_Msg_NE
b2e1beb3
ES
4052 ("declaration must appear after completion of type &", N, Typ);
4053 Error_Msg_NE
6782b1ef
AC
4054 ("\which is an untagged type in the profile of "
4055 & "primitive operation & declared#", N, Subp);
c0b11850
AC
4056
4057 else
4058 Comp := Private_Component (Typ);
4059
4060 if not Is_Tagged_Type (Typ)
4061 and then Present (Comp)
4062 and then not Is_Frozen (Comp)
6782b1ef 4063 and then not Is_Actual_For_Formal_Incomplete_Type (Comp)
c0b11850
AC
4064 then
4065 Error_Msg_Sloc := Sloc (Subp);
4066 Error_Msg_Node_2 := Subp;
4067 Error_Msg_Name_1 := Chars (Tagged_Type);
4068 Error_Msg_NE
4069 ("declaration must appear after completion of type &",
6782b1ef 4070 N, Comp);
c0b11850 4071 Error_Msg_NE
6782b1ef
AC
4072 ("\which is a component of untagged type& in the profile "
4073 & "of primitive & of type % that is frozen by the "
0bfa2f3c 4074 & "declaration", N, Typ);
c0b11850 4075 end if;
b2e1beb3
ES
4076 end if;
4077 end Check_Premature_Freezing;
4078
e18d6a15
JM
4079 ---------------
4080 -- Export_DT --
4081 ---------------
4082
b16d9747
JM
4083 procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0)
4084 is
4085 Count : Nat;
4086 Elmt : Elmt_Id;
4087
e18d6a15
JM
4088 begin
4089 Set_Is_Statically_Allocated (DT);
4090 Set_Is_True_Constant (DT);
4091 Set_Is_Exported (DT);
4092
b16d9747
JM
4093 Count := 0;
4094 Elmt := First_Elmt (Dispatch_Table_Wrappers (Typ));
4095 while Count /= Index loop
4096 Next_Elmt (Elmt);
4097 Count := Count + 1;
4098 end loop;
4099
76f9c7f4
BD
4100 -- Related_Type (Node (Elmt)) should be equal to Typ here, but we
4101 -- can't assert that, because it is sometimes false in illegal
4102 -- programs. We can't check Serious_Errors_Detected, because the
4103 -- errors have not yet been detected.
b16d9747 4104
93582885 4105 Get_External_Name (Node (Elmt));
e18d6a15
JM
4106 Set_Interface_Name (DT,
4107 Make_String_Literal (Loc,
4108 Strval => String_From_Name_Buffer));
4109
4110 -- Ensure proper Sprint output of this implicit importation
4111
4112 Set_Is_Internal (DT);
4113 Set_Is_Public (DT);
4114 end Export_DT;
4115
d0dd5209
JM
4116 -----------------------
4117 -- Make_Secondary_DT --
4118 -----------------------
70482933 4119
d0dd5209 4120 procedure Make_Secondary_DT
1923d2d6
JM
4121 (Typ : Entity_Id;
4122 Iface : Entity_Id;
15529d0a 4123 Iface_Comp : Node_Id;
b16d9747 4124 Suffix_Index : Int;
1923d2d6
JM
4125 Num_Iface_Prims : Nat;
4126 Iface_DT_Ptr : Entity_Id;
4127 Predef_Prims_Ptr : Entity_Id;
4128 Build_Thunks : Boolean;
4129 Result : List_Id)
d0dd5209
JM
4130 is
4131 Loc : constant Source_Ptr := Sloc (Typ);
b16d9747
JM
4132 Exporting_Table : constant Boolean :=
4133 Building_Static_DT (Typ)
4134 and then Suffix_Index > 0;
2287a75d
AC
4135 Iface_DT : constant Entity_Id := Make_Temporary (Loc, 'T');
4136 Predef_Prims : constant Entity_Id := Make_Temporary (Loc, 'R');
d0dd5209
JM
4137 DT_Constr_List : List_Id;
4138 DT_Aggr_List : List_Id;
4139 Empty_DT : Boolean := False;
d0dd5209
JM
4140 Nb_Prim : Nat;
4141 New_Node : Node_Id;
4142 OSD : Entity_Id;
4143 OSD_Aggr_List : List_Id;
d0dd5209
JM
4144 Prim : Entity_Id;
4145 Prim_Elmt : Elmt_Id;
4146 Prim_Ops_Aggr_List : List_Id;
dee4682a 4147
d0dd5209 4148 begin
b2e1beb3
ES
4149 -- Handle cases in which we do not generate statically allocated
4150 -- dispatch tables.
dee4682a 4151
e18d6a15 4152 if not Building_Static_DT (Typ) then
d0dd5209 4153 Set_Ekind (Predef_Prims, E_Variable);
d0dd5209 4154 Set_Ekind (Iface_DT, E_Variable);
dee4682a 4155
d0dd5209
JM
4156 -- Statically allocated dispatch tables and related entities are
4157 -- constants.
dee4682a 4158
d0dd5209
JM
4159 else
4160 Set_Ekind (Predef_Prims, E_Constant);
4161 Set_Is_Statically_Allocated (Predef_Prims);
4162 Set_Is_True_Constant (Predef_Prims);
dee4682a 4163
d0dd5209
JM
4164 Set_Ekind (Iface_DT, E_Constant);
4165 Set_Is_Statically_Allocated (Iface_DT);
4166 Set_Is_True_Constant (Iface_DT);
dee4682a
JM
4167 end if;
4168
b16d9747
JM
4169 -- Calculate the number of slots of the dispatch table. If the number
4170 -- of primitives of Typ is 0 we reserve a dummy single entry for its
e7c0dd39 4171 -- DT because at run time the pointer to this dummy entry will be
b16d9747 4172 -- used as the tag.
b0efe69e 4173
80b992ae 4174 if Num_Iface_Prims = 0 then
d0dd5209
JM
4175 Empty_DT := True;
4176 Nb_Prim := 1;
80b992ae
HK
4177 else
4178 Nb_Prim := Num_Iface_Prims;
d0dd5209 4179 end if;
f4d379b8 4180
d0dd5209 4181 -- Generate:
4d744221 4182
d0dd5209
JM
4183 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
4184 -- (predef-prim-op-thunk-1'address,
4185 -- predef-prim-op-thunk-2'address,
4186 -- ...
4187 -- predef-prim-op-thunk-n'address);
4d744221 4188
bd5ed03a
JM
4189 -- Create the thunks associated with the predefined primitives and
4190 -- save their entity to fill the aggregate.
70482933 4191
d0dd5209 4192 declare
bd5ed03a
JM
4193 Nb_P_Prims : constant Nat := Number_Of_Predefined_Prims (Typ);
4194 Prim_Table : array (Nat range 1 .. Nb_P_Prims) of Entity_Id;
f2cbd970 4195 Decl : Node_Id;
d0dd5209
JM
4196 Thunk_Id : Entity_Id;
4197 Thunk_Code : Node_Id;
758c442c 4198
d0dd5209
JM
4199 begin
4200 Prim_Ops_Aggr_List := New_List;
4201 Prim_Table := (others => Empty);
758c442c 4202
80b992ae
HK
4203 if Building_Static_DT (Typ) then
4204 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4205 while Present (Prim_Elmt) loop
4206 Prim := Node (Prim_Elmt);
758c442c 4207
80b992ae
HK
4208 if Is_Predefined_Dispatching_Operation (Prim)
4209 and then not Is_Abstract_Subprogram (Prim)
9e9df9da 4210 and then not Is_Eliminated (Prim)
078b1a5f 4211 and then not Generate_SCIL
80b992ae
HK
4212 and then not Present (Prim_Table
4213 (UI_To_Int (DT_Position (Prim))))
4214 then
4215 if not Build_Thunks then
4216 Prim_Table (UI_To_Int (DT_Position (Prim))) :=
4217 Alias (Prim);
758c442c 4218
80b992ae 4219 else
20dc266e
JM
4220 Expand_Interface_Thunk
4221 (Prim, Thunk_Id, Thunk_Code, Iface);
758c442c 4222
80b992ae
HK
4223 if Present (Thunk_Id) then
4224 Append_To (Result, Thunk_Code);
497a660d
AC
4225 Prim_Table (UI_To_Int (DT_Position (Prim))) :=
4226 Thunk_Id;
80b992ae
HK
4227 end if;
4228 end if;
d0dd5209 4229 end if;
758c442c 4230
80b992ae
HK
4231 Next_Elmt (Prim_Elmt);
4232 end loop;
4233 end if;
758c442c 4234
d0dd5209
JM
4235 for J in Prim_Table'Range loop
4236 if Present (Prim_Table (J)) then
4237 New_Node :=
f2cbd970 4238 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
1923d2d6 4239 Make_Attribute_Reference (Loc,
e4494292 4240 Prefix => New_Occurrence_Of (Prim_Table (J), Loc),
1923d2d6 4241 Attribute_Name => Name_Unrestricted_Access));
d0dd5209 4242 else
f2cbd970 4243 New_Node := Make_Null (Loc);
d0dd5209 4244 end if;
4d744221 4245
d0dd5209
JM
4246 Append_To (Prim_Ops_Aggr_List, New_Node);
4247 end loop;
4d744221 4248
f2cbd970 4249 New_Node :=
6782b1ef 4250 Make_Aggregate (Loc, Expressions => Prim_Ops_Aggr_List);
f2cbd970
JM
4251
4252 -- Remember aggregates initializing dispatch tables
4253
4254 Append_Elmt (New_Node, DT_Aggr);
4255
4256 Decl :=
4257 Make_Subtype_Declaration (Loc,
2287a75d
AC
4258 Defining_Identifier => Make_Temporary (Loc, 'S'),
4259 Subtype_Indication =>
e4494292 4260 New_Occurrence_Of (RTE (RE_Address_Array), Loc));
f2cbd970
JM
4261
4262 Append_To (Result, Decl);
4263
d0dd5209
JM
4264 Append_To (Result,
4265 Make_Object_Declaration (Loc,
4266 Defining_Identifier => Predef_Prims,
e18d6a15 4267 Constant_Present => Building_Static_DT (Typ),
d0dd5209 4268 Aliased_Present => True,
e4494292 4269 Object_Definition => New_Occurrence_Of
f2cbd970
JM
4270 (Defining_Identifier (Decl), Loc),
4271 Expression => New_Node));
d0dd5209 4272 end;
758c442c 4273
d0dd5209 4274 -- Generate
f4d379b8 4275
d0dd5209
JM
4276 -- OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
4277 -- (OSD_Table => (1 => <value>,
4278 -- ...
4279 -- N => <value>));
f04e9787 4280 -- for OSD'Alignment use Address'Alignment;
f4d379b8 4281
d0dd5209
JM
4282 -- Iface_DT : Dispatch_Table (Nb_Prims) :=
4283 -- ([ Signature => <sig-value> ],
4284 -- Tag_Kind => <tag_kind-value>,
4285 -- Predef_Prims => Predef_Prims'Address,
4286 -- Offset_To_Top => 0,
4287 -- OSD => OSD'Address,
4288 -- Prims_Ptr => (prim-op-1'address,
4289 -- prim-op-2'address,
4290 -- ...
4291 -- prim-op-n'address));
f4d379b8 4292
d0dd5209 4293 -- Stage 3: Initialize the discriminant and the record components
758c442c 4294
d0dd5209
JM
4295 DT_Constr_List := New_List;
4296 DT_Aggr_List := New_List;
dee4682a 4297
9b7424a7 4298 -- Nb_Prim
dee4682a 4299
9b7424a7
AC
4300 Append_To (DT_Constr_List, Make_Integer_Literal (Loc, Nb_Prim));
4301 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, Nb_Prim));
dee4682a 4302
d0dd5209 4303 -- Signature
dee4682a 4304
d0dd5209
JM
4305 if RTE_Record_Component_Available (RE_Signature) then
4306 Append_To (DT_Aggr_List,
e4494292 4307 New_Occurrence_Of (RTE (RE_Secondary_DT), Loc));
d0dd5209 4308 end if;
dee4682a 4309
d0dd5209 4310 -- Tag_Kind
dee4682a 4311
d0dd5209
JM
4312 if RTE_Record_Component_Available (RE_Tag_Kind) then
4313 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
4314 end if;
758c442c 4315
d0dd5209 4316 -- Predef_Prims
758c442c 4317
d0dd5209
JM
4318 Append_To (DT_Aggr_List,
4319 Make_Attribute_Reference (Loc,
6782b1ef 4320 Prefix => New_Occurrence_Of (Predef_Prims, Loc),
d0dd5209 4321 Attribute_Name => Name_Address));
758c442c 4322
7225a479
JM
4323 -- Interface component located at variable offset; the value of
4324 -- Offset_To_Top will be set by the init subprogram.
758c442c 4325
7225a479
JM
4326 if No (Dummy_Object)
4327 or else Is_Variable_Size_Record (Etype (Scope (Iface_Comp)))
4328 then
15529d0a
PMR
4329 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
4330
7225a479
JM
4331 -- Interface component located at fixed offset
4332
15529d0a
PMR
4333 else
4334 Append_To (DT_Aggr_List,
d0567dc0
PMR
4335 Make_Op_Minus (Loc,
4336 Make_Attribute_Reference (Loc,
4337 Prefix =>
4338 Make_Selected_Component (Loc,
4339 Prefix =>
4340 New_Occurrence_Of (Dummy_Object, Loc),
4341 Selector_Name =>
4342 New_Occurrence_Of (Iface_Comp, Loc)),
4343 Attribute_Name => Name_Position)));
15529d0a 4344 end if;
758c442c 4345
d0dd5209
JM
4346 -- Generate the Object Specific Data table required to dispatch calls
4347 -- through synchronized interfaces.
758c442c 4348
d0dd5209
JM
4349 if Empty_DT
4350 or else Is_Abstract_Type (Typ)
4351 or else Is_Controlled (Typ)
4352 or else Restriction_Active (No_Dispatching_Calls)
4353 or else not Is_Limited_Type (Typ)
ce2b6ba5 4354 or else not Has_Interfaces (Typ)
80b992ae 4355 or else not Build_Thunks
3dd9959c 4356 or else not RTE_Record_Component_Available (RE_OSD_Table)
d0dd5209
JM
4357 then
4358 -- No OSD table required
70482933 4359
d0dd5209 4360 Append_To (DT_Aggr_List,
e4494292 4361 New_Occurrence_Of (RTE (RE_Null_Address), Loc));
10b93b2e 4362
d0dd5209
JM
4363 else
4364 OSD_Aggr_List := New_List;
10b93b2e 4365
d0dd5209
JM
4366 declare
4367 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
4368 Prim : Entity_Id;
4369 Prim_Alias : Entity_Id;
4370 Prim_Elmt : Elmt_Id;
4371 E : Entity_Id;
4372 Count : Nat := 0;
4373 Pos : Nat;
10b93b2e 4374
d0dd5209
JM
4375 begin
4376 Prim_Table := (others => Empty);
4377 Prim_Alias := Empty;
10b93b2e 4378
d0dd5209
JM
4379 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4380 while Present (Prim_Elmt) loop
4381 Prim := Node (Prim_Elmt);
10b93b2e 4382
ce2b6ba5 4383 if Present (Interface_Alias (Prim))
d0dd5209 4384 and then Find_Dispatching_Type
ce2b6ba5 4385 (Interface_Alias (Prim)) = Iface
d0dd5209 4386 then
ce2b6ba5 4387 Prim_Alias := Interface_Alias (Prim);
b81a5940 4388 E := Ultimate_Alias (Prim);
d0dd5209 4389 Pos := UI_To_Int (DT_Position (Prim_Alias));
b0efe69e 4390
d0dd5209
JM
4391 if Present (Prim_Table (Pos)) then
4392 pragma Assert (Prim_Table (Pos) = E);
4393 null;
b0efe69e 4394
d0dd5209
JM
4395 else
4396 Prim_Table (Pos) := E;
4397
4398 Append_To (OSD_Aggr_List,
4399 Make_Component_Association (Loc,
6782b1ef 4400 Choices => New_List (
d0dd5209
JM
4401 Make_Integer_Literal (Loc,
4402 DT_Position (Prim_Alias))),
4403 Expression =>
4404 Make_Integer_Literal (Loc,
4405 DT_Position (Alias (Prim)))));
4406
4407 Count := Count + 1;
4408 end if;
4409 end if;
4410
4411 Next_Elmt (Prim_Elmt);
4412 end loop;
4413 pragma Assert (Count = Nb_Prim);
4414 end;
4415
2287a75d 4416 OSD := Make_Temporary (Loc, 'I');
d0dd5209
JM
4417
4418 Append_To (Result,
4419 Make_Object_Declaration (Loc,
4420 Defining_Identifier => OSD,
6dc56535 4421 Constant_Present => True,
d0dd5209
JM
4422 Object_Definition =>
4423 Make_Subtype_Indication (Loc,
4424 Subtype_Mark =>
e4494292 4425 New_Occurrence_Of (RTE (RE_Object_Specific_Data), Loc),
6782b1ef 4426 Constraint =>
d0dd5209
JM
4427 Make_Index_Or_Discriminant_Constraint (Loc,
4428 Constraints => New_List (
4429 Make_Integer_Literal (Loc, Nb_Prim)))),
d0dd5209 4430
2287a75d
AC
4431 Expression =>
4432 Make_Aggregate (Loc,
4433 Component_Associations => New_List (
4434 Make_Component_Association (Loc,
6782b1ef 4435 Choices => New_List (
2287a75d
AC
4436 New_Occurrence_Of
4437 (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
4438 Expression =>
4439 Make_Integer_Literal (Loc, Nb_Prim)),
4440
4441 Make_Component_Association (Loc,
6782b1ef 4442 Choices => New_List (
2287a75d
AC
4443 New_Occurrence_Of
4444 (RTE_Record_Component (RE_OSD_Table), Loc)),
4445 Expression => Make_Aggregate (Loc,
4446 Component_Associations => OSD_Aggr_List))))));
d0dd5209 4447
b2e1beb3
ES
4448 Append_To (Result,
4449 Make_Attribute_Definition_Clause (Loc,
e4494292 4450 Name => New_Occurrence_Of (OSD, Loc),
b2e1beb3
ES
4451 Chars => Name_Alignment,
4452 Expression =>
4453 Make_Attribute_Reference (Loc,
6782b1ef 4454 Prefix =>
e4494292 4455 New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
b2e1beb3
ES
4456 Attribute_Name => Name_Alignment)));
4457
d0dd5209 4458 -- In secondary dispatch tables the Typeinfo component contains
c7cb99f8 4459 -- the address of the Object Specific Data (see a-tags.ads).
d0dd5209
JM
4460
4461 Append_To (DT_Aggr_List,
4462 Make_Attribute_Reference (Loc,
6782b1ef 4463 Prefix => New_Occurrence_Of (OSD, Loc),
d0dd5209
JM
4464 Attribute_Name => Name_Address));
4465 end if;
4466
4467 -- Initialize the table of primitive operations
4468
4469 Prim_Ops_Aggr_List := New_List;
4470
4471 if Empty_DT then
f2cbd970 4472 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
d0dd5209
JM
4473
4474 elsif Is_Abstract_Type (Typ)
bfae1846 4475 or else not Building_Static_DT (Typ)
d0dd5209
JM
4476 then
4477 for J in 1 .. Nb_Prim loop
f2cbd970 4478 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
d0dd5209
JM
4479 end loop;
4480
4481 else
4482 declare
cefce34c
JM
4483 CPP_Nb_Prims : constant Nat := CPP_Num_Prims (Typ);
4484 E : Entity_Id;
4485 Prim_Pos : Nat;
4486 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
4487 Thunk_Code : Node_Id;
4488 Thunk_Id : Entity_Id;
d0dd5209
JM
4489
4490 begin
4491 Prim_Table := (others => Empty);
4492
4493 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4494 while Present (Prim_Elmt) loop
cefce34c
JM
4495 Prim := Node (Prim_Elmt);
4496 E := Ultimate_Alias (Prim);
4497 Prim_Pos := UI_To_Int (DT_Position (E));
d0dd5209 4498
cefce34c
JM
4499 -- Do not reference predefined primitives because they are
4500 -- located in a separate dispatch table; skip abstract and
4501 -- eliminated primitives; skip primitives located in the C++
4502 -- part of the dispatch table because their slot is set by
4503 -- the IC routine.
9e9df9da 4504
d0dd5209 4505 if not Is_Predefined_Dispatching_Operation (Prim)
ce2b6ba5 4506 and then Present (Interface_Alias (Prim))
d0dd5209 4507 and then not Is_Abstract_Subprogram (Alias (Prim))
9e9df9da 4508 and then not Is_Eliminated (Alias (Prim))
cefce34c
JM
4509 and then (not Is_CPP_Class (Root_Type (Typ))
4510 or else Prim_Pos > CPP_Nb_Prims)
d0dd5209 4511 and then Find_Dispatching_Type
ce2b6ba5 4512 (Interface_Alias (Prim)) = Iface
d0dd5209
JM
4513
4514 -- Generate the code of the thunk only if the abstract
4515 -- interface type is not an immediate ancestor of
cefce34c 4516 -- Tagged_Type. Otherwise the DT associated with the
d0dd5209
JM
4517 -- interface is the primary DT.
4518
4ac2477e
JM
4519 and then not Is_Ancestor (Iface, Typ,
4520 Use_Full_View => True)
d0dd5209 4521 then
80b992ae 4522 if not Build_Thunks then
cefce34c 4523 Prim_Pos :=
ce2b6ba5 4524 UI_To_Int (DT_Position (Interface_Alias (Prim)));
cefce34c
JM
4525 Prim_Table (Prim_Pos) := Alias (Prim);
4526
80b992ae 4527 else
20dc266e
JM
4528 Expand_Interface_Thunk
4529 (Prim, Thunk_Id, Thunk_Code, Iface);
d0dd5209 4530
80b992ae 4531 if Present (Thunk_Id) then
cefce34c 4532 Prim_Pos :=
ce2b6ba5 4533 UI_To_Int (DT_Position (Interface_Alias (Prim)));
80b992ae 4534
cefce34c 4535 Prim_Table (Prim_Pos) := Thunk_Id;
80b992ae
HK
4536 Append_To (Result, Thunk_Code);
4537 end if;
d0dd5209
JM
4538 end if;
4539 end if;
4540
4541 Next_Elmt (Prim_Elmt);
4542 end loop;
4543
4544 for J in Prim_Table'Range loop
4545 if Present (Prim_Table (J)) then
4546 New_Node :=
f2cbd970 4547 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
1923d2d6 4548 Make_Attribute_Reference (Loc,
e4494292 4549 Prefix => New_Occurrence_Of (Prim_Table (J), Loc),
1923d2d6 4550 Attribute_Name => Name_Unrestricted_Access));
cefce34c 4551
d0dd5209 4552 else
f2cbd970 4553 New_Node := Make_Null (Loc);
d0dd5209
JM
4554 end if;
4555
4556 Append_To (Prim_Ops_Aggr_List, New_Node);
4557 end loop;
4558 end;
4559 end if;
4560
f2cbd970 4561 New_Node :=
d0dd5209 4562 Make_Aggregate (Loc,
f2cbd970
JM
4563 Expressions => Prim_Ops_Aggr_List);
4564
4565 Append_To (DT_Aggr_List, New_Node);
4566
4567 -- Remember aggregates initializing dispatch tables
4568
4569 Append_Elmt (New_Node, DT_Aggr);
d0dd5209 4570
15529d0a
PMR
4571 -- Note: Secondary dispatch tables are declared constant only if
4572 -- we can compute their offset field by means of the extra dummy
4573 -- object; otherwise they cannot be declared constant and the
4574 -- Offset_To_Top component is initialized by the IP routine.
b16d9747 4575
d0dd5209
JM
4576 Append_To (Result,
4577 Make_Object_Declaration (Loc,
4578 Defining_Identifier => Iface_DT,
4579 Aliased_Present => True,
7225a479 4580 Constant_Present => Building_Static_Secondary_DT (Typ),
b16d9747 4581
d0dd5209
JM
4582 Object_Definition =>
4583 Make_Subtype_Indication (Loc,
e4494292 4584 Subtype_Mark => New_Occurrence_Of
d0dd5209
JM
4585 (RTE (RE_Dispatch_Table_Wrapper), Loc),
4586 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
4587 Constraints => DT_Constr_List)),
4588
b16d9747
JM
4589 Expression =>
4590 Make_Aggregate (Loc,
4591 Expressions => DT_Aggr_List)));
d0dd5209 4592
b16d9747
JM
4593 if Exporting_Table then
4594 Export_DT (Typ, Iface_DT, Suffix_Index);
4595
d0dd5209
JM
4596 -- Generate code to create the pointer to the dispatch table
4597
b16d9747 4598 -- Iface_DT_Ptr : Tag := Tag!(DT.Prims_Ptr'Address);
d0dd5209 4599
b16d9747
JM
4600 -- Note: This declaration is not added here if the table is exported
4601 -- because in such case Make_Tags has already added this declaration.
4602
4603 else
4604 Append_To (Result,
4605 Make_Object_Declaration (Loc,
4606 Defining_Identifier => Iface_DT_Ptr,
4607 Constant_Present => True,
4608
4609 Object_Definition =>
e4494292 4610 New_Occurrence_Of (RTE (RE_Interface_Tag), Loc),
b16d9747
JM
4611
4612 Expression =>
4613 Unchecked_Convert_To (RTE (RE_Interface_Tag),
4614 Make_Attribute_Reference (Loc,
4615 Prefix =>
4616 Make_Selected_Component (Loc,
e4494292 4617 Prefix => New_Occurrence_Of (Iface_DT, Loc),
b16d9747
JM
4618 Selector_Name =>
4619 New_Occurrence_Of
4620 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
4621 Attribute_Name => Name_Address))));
4622 end if;
d0dd5209 4623
1923d2d6
JM
4624 Append_To (Result,
4625 Make_Object_Declaration (Loc,
4626 Defining_Identifier => Predef_Prims_Ptr,
4627 Constant_Present => True,
b16d9747
JM
4628
4629 Object_Definition =>
e4494292 4630 New_Occurrence_Of (RTE (RE_Address), Loc),
b16d9747
JM
4631
4632 Expression =>
1923d2d6 4633 Make_Attribute_Reference (Loc,
b16d9747 4634 Prefix =>
1923d2d6 4635 Make_Selected_Component (Loc,
e4494292 4636 Prefix => New_Occurrence_Of (Iface_DT, Loc),
b16d9747
JM
4637 Selector_Name =>
4638 New_Occurrence_Of
4639 (RTE_Record_Component (RE_Predef_Prims), Loc)),
1923d2d6
JM
4640 Attribute_Name => Name_Address)));
4641
f2cbd970 4642 -- Remember entities containing dispatch tables
1923d2d6 4643
f2cbd970
JM
4644 Append_Elmt (Predef_Prims, DT_Decl);
4645 Append_Elmt (Iface_DT, DT_Decl);
d0dd5209
JM
4646 end Make_Secondary_DT;
4647
bd5ed03a
JM
4648 --------------------------------
4649 -- Number_Of_Predefined_Prims --
4650 --------------------------------
4651
4652 function Number_Of_Predefined_Prims (Typ : Entity_Id) return Nat is
4653 Nb_Predef_Prims : Nat := 0;
4654
4655 begin
4656 if not Generate_SCIL then
4657 declare
4658 Prim : Entity_Id;
4659 Prim_Elmt : Elmt_Id;
4660 Pos : Nat;
4661
4662 begin
4663 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4664 while Present (Prim_Elmt) loop
4665 Prim := Node (Prim_Elmt);
4666
4667 if Is_Predefined_Dispatching_Operation (Prim)
4668 and then not Is_Abstract_Subprogram (Prim)
4669 then
4670 Pos := UI_To_Int (DT_Position (Prim));
4671
4672 if Pos > Nb_Predef_Prims then
4673 Nb_Predef_Prims := Pos;
4674 end if;
4675 end if;
4676
4677 Next_Elmt (Prim_Elmt);
4678 end loop;
4679 end;
4680 end if;
4681
4682 pragma Assert (Nb_Predef_Prims <= Max_Predef_Prims);
4683 return Nb_Predef_Prims;
4684 end Number_Of_Predefined_Prims;
4685
d0dd5209
JM
4686 -- Local variables
4687
d65a80fd
HK
4688 Elab_Code : constant List_Id := New_List;
4689 Result : constant List_Id := New_List;
4690 Tname : constant Name_Id := Chars (Typ);
4691
51ab2a39
JM
4692 -- When pragmas Discard_Names and No_Tagged_Streams simultaneously apply
4693 -- we initialize the Expanded_Name and the External_Tag of this tagged
4694 -- type with an empty string. This is useful to avoid exposing entity
4695 -- names at binary level. It can be done when both pragmas apply because
4696 -- (1) Discard_Names allows initializing Expanded_Name with an
4697 -- implementation defined value (Ada RM Section C.5 (7/2)).
4698 -- (2) External_Tag (combined with Internal_Tag) is used for object
4699 -- streaming and No_Tagged_Streams inhibits the generation of
4700 -- streams.
4701
4702 Discard_Names : constant Boolean :=
4703 Present (No_Tagged_Streams_Pragma (Typ))
76f9c7f4
BD
4704 and then
4705 (Global_Discard_Names or else Einfo.Entities.Discard_Names (Typ));
51ab2a39 4706
d65a80fd
HK
4707 -- The following name entries are used by Make_DT to generate a number
4708 -- of entities related to a tagged type. These entities may be generated
4709 -- in a scope other than that of the tagged type declaration, and if
4710 -- the entities for two tagged types with the same name happen to be
4711 -- generated in the same scope, we have to take care to use different
4712 -- names. This is achieved by means of a unique serial number appended
4713 -- to each generated entity name.
4714
4715 Name_DT : constant Name_Id :=
4716 New_External_Name (Tname, 'T', Suffix_Index => -1);
4717 Name_Exname : constant Name_Id :=
4718 New_External_Name (Tname, 'E', Suffix_Index => -1);
4719 Name_HT_Link : constant Name_Id :=
4720 New_External_Name (Tname, 'H', Suffix_Index => -1);
4721 Name_Predef_Prims : constant Name_Id :=
4722 New_External_Name (Tname, 'R', Suffix_Index => -1);
4723 Name_SSD : constant Name_Id :=
4724 New_External_Name (Tname, 'S', Suffix_Index => -1);
4725 Name_TSD : constant Name_Id :=
4726 New_External_Name (Tname, 'B', Suffix_Index => -1);
4727
9057bd6a
HK
4728 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode;
4729 Saved_IGR : constant Node_Id := Ignored_Ghost_Region;
4730 -- Save the Ghost-related attributes to restore on exit
f9a8f910 4731
d0dd5209 4732 AI : Elmt_Id;
80b992ae 4733 AI_Tag_Elmt : Elmt_Id;
e18d6a15 4734 AI_Tag_Comp : Elmt_Id;
d65a80fd 4735 DT : Entity_Id;
0f4cb75c 4736 DT_Aggr_List : List_Id;
e18d6a15 4737 DT_Constr_List : List_Id;
d0dd5209 4738 DT_Ptr : Entity_Id;
51ab2a39 4739 Exname : Entity_Id;
d65a80fd 4740 HT_Link : Entity_Id;
d0dd5209
JM
4741 ITable : Node_Id;
4742 I_Depth : Nat := 0;
4743 Iface_Table_Node : Node_Id;
4744 Name_ITable : Name_Id;
d0dd5209
JM
4745 Nb_Prim : Nat := 0;
4746 New_Node : Node_Id;
d0dd5209 4747 Num_Ifaces : Nat := 0;
f2cbd970 4748 Parent_Typ : Entity_Id;
d65a80fd 4749 Predef_Prims : Entity_Id;
d0dd5209
JM
4750 Prim : Entity_Id;
4751 Prim_Elmt : Elmt_Id;
4752 Prim_Ops_Aggr_List : List_Id;
d65a80fd 4753 SSD : Entity_Id;
d0dd5209
JM
4754 Suffix_Index : Int;
4755 Typ_Comps : Elist_Id;
4756 Typ_Ifaces : Elist_Id;
d65a80fd 4757 TSD : Entity_Id;
d0dd5209
JM
4758 TSD_Aggr_List : List_Id;
4759 TSD_Tags_List : List_Id;
b2e1beb3 4760
d0dd5209
JM
4761 -- Start of processing for Make_DT
4762
4763 begin
b2e1beb3 4764 pragma Assert (Is_Frozen (Typ));
d0dd5209 4765
1af4455a
HK
4766 -- The tagged type being processed may be subject to pragma Ghost. Set
4767 -- the mode now to ensure that any nodes generated during dispatch table
4768 -- creation are properly marked as Ghost.
8636f52f 4769
f9a8f910 4770 Set_Ghost_Mode (Typ);
8636f52f 4771
b2e1beb3 4772 -- Handle cases in which there is no need to build the dispatch table
d0dd5209 4773
b2e1beb3
ES
4774 if Has_Dispatch_Table (Typ)
4775 or else No (Access_Disp_Table (Typ))
4776 or else Is_CPP_Class (Typ)
4777 then
d65a80fd 4778 goto Leave;
d0dd5209 4779
b2e1beb3
ES
4780 elsif No_Run_Time_Mode then
4781 Error_Msg_CRT ("tagged types", Typ);
d65a80fd 4782 goto Leave;
d0dd5209 4783
b2e1beb3 4784 elsif not RTE_Available (RE_Tag) then
d0dd5209
JM
4785 Append_To (Result,
4786 Make_Object_Declaration (Loc,
d65a80fd
HK
4787 Defining_Identifier =>
4788 Node (First_Elmt (Access_Disp_Table (Typ))),
e4494292 4789 Object_Definition => New_Occurrence_Of (RTE (RE_Tag), Loc),
d0dd5209
JM
4790 Constant_Present => True,
4791 Expression =>
e18d6a15 4792 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 4793 New_Occurrence_Of (RTE (RE_Null_Address), Loc))));
d0dd5209
JM
4794
4795 Analyze_List (Result, Suppress => All_Checks);
4796 Error_Msg_CRT ("tagged types", Typ);
d65a80fd 4797 goto Leave;
d0dd5209
JM
4798 end if;
4799
b2e1beb3 4800 -- Ensure that the value of Max_Predef_Prims defined in a-tags is
110d0820 4801 -- correct. Valid values are 10 under configurable runtime or 16
b2e1beb3
ES
4802 -- with full runtime.
4803
4804 if RTE_Available (RE_Interface_Data) then
110d0820 4805 if Max_Predef_Prims /= 16 then
b2e1beb3 4806 Error_Msg_N ("run-time library configuration error", Typ);
d65a80fd 4807 goto Leave;
b2e1beb3 4808 end if;
d0dd5209 4809 else
110d0820 4810 if Max_Predef_Prims /= 10 then
b2e1beb3
ES
4811 Error_Msg_N ("run-time library configuration error", Typ);
4812 Error_Msg_CRT ("tagged types", Typ);
d65a80fd 4813 goto Leave;
b2e1beb3 4814 end if;
d0dd5209
JM
4815 end if;
4816
51ab2a39
JM
4817 DT := Make_Defining_Identifier (Loc, Name_DT);
4818 Exname := Make_Defining_Identifier (Loc, Name_Exname);
4819 HT_Link := Make_Defining_Identifier (Loc, Name_HT_Link);
4820 Predef_Prims := Make_Defining_Identifier (Loc, Name_Predef_Prims);
4821 SSD := Make_Defining_Identifier (Loc, Name_SSD);
4822 TSD := Make_Defining_Identifier (Loc, Name_TSD);
d65a80fd 4823
f2cbd970
JM
4824 -- Initialize Parent_Typ handling private types
4825
4826 Parent_Typ := Etype (Typ);
4827
4828 if Present (Full_View (Parent_Typ)) then
4829 Parent_Typ := Full_View (Parent_Typ);
4830 end if;
4831
b2e1beb3
ES
4832 -- Ensure that all the primitives are frozen. This is only required when
4833 -- building static dispatch tables --- the primitives must be frozen to
4834 -- be referenced (otherwise we have problems with the backend). It is
4835 -- not a requirement with nonstatic dispatch tables because in this case
4836 -- we generate now an empty dispatch table; the extra code required to
e18d6a15 4837 -- register the primitives in the slots will be generated later --- when
b2e1beb3 4838 -- each primitive is frozen (see Freeze_Subprogram).
d0dd5209 4839
cefce34c 4840 if Building_Static_DT (Typ) then
b2e1beb3 4841 declare
b63d61f7
AC
4842 Saved_FLLTT : constant Boolean :=
4843 Freezing_Library_Level_Tagged_Type;
4844
4845 Formal : Entity_Id;
4846 Frnodes : List_Id;
361effb1 4847 Prim : Entity_Id;
b2e1beb3 4848 Prim_Elmt : Elmt_Id;
d0dd5209 4849
b2e1beb3
ES
4850 begin
4851 Freezing_Library_Level_Tagged_Type := True;
361effb1 4852
b2e1beb3
ES
4853 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
4854 while Present (Prim_Elmt) loop
361effb1 4855 Prim := Node (Prim_Elmt);
c159409f 4856 Frnodes := Freeze_Entity (Prim, Typ);
d0dd5209 4857
b63d61f7
AC
4858 -- We disable this check for abstract subprograms, given that
4859 -- they cannot be called directly and thus the state of their
4860 -- untagged formals is of no concern. The RM is unclear in any
4861 -- case concerning the need for this check, and this topic may
4862 -- go back to the ARG.
4863
4864 if not Is_Abstract_Subprogram (Prim) then
4865 Formal := First_Formal (Prim);
4866 while Present (Formal) loop
4867 Check_Premature_Freezing (Prim, Typ, Etype (Formal));
4868 Next_Formal (Formal);
b2e1beb3
ES
4869 end loop;
4870
c0b11850 4871 Check_Premature_Freezing (Prim, Typ, Etype (Prim));
b63d61f7 4872 end if;
b2e1beb3
ES
4873
4874 if Present (Frnodes) then
4875 Append_List_To (Result, Frnodes);
4876 end if;
4877
4878 Next_Elmt (Prim_Elmt);
4879 end loop;
361effb1 4880
b63d61f7 4881 Freezing_Library_Level_Tagged_Type := Saved_FLLTT;
b2e1beb3
ES
4882 end;
4883 end if;
d0dd5209 4884
7225a479 4885 if not Is_Interface (Typ) and then Has_Interfaces (Typ) then
15529d0a
PMR
4886 declare
4887 Cannot_Have_Null_Disc : Boolean := False;
7225a479 4888 Dummy_Object_Typ : constant Entity_Id := Typ;
15529d0a
PMR
4889 Name_Dummy_Object : constant Name_Id :=
4890 New_External_Name (Tname,
4891 'P', Suffix_Index => -1);
4892 begin
4893 Dummy_Object := Make_Defining_Identifier (Loc, Name_Dummy_Object);
4894
4895 -- Define the extra object imported and constant to avoid linker
4896 -- errors (since this object is never declared). Required because
4897 -- we implement RM 13.3(19) for exported and imported (variable)
4898 -- objects by making them volatile.
4899
4900 Set_Is_Imported (Dummy_Object);
4901 Set_Ekind (Dummy_Object, E_Constant);
4902 Set_Is_True_Constant (Dummy_Object);
4903 Set_Related_Type (Dummy_Object, Typ);
4904
4905 -- The scope must be set now to call Get_External_Name
4906
4907 Set_Scope (Dummy_Object, Current_Scope);
4908
4909 Get_External_Name (Dummy_Object);
4910 Set_Interface_Name (Dummy_Object,
4911 Make_String_Literal (Loc, Strval => String_From_Name_Buffer));
4912
4913 -- Ensure proper Sprint output of this implicit importation
4914
4915 Set_Is_Internal (Dummy_Object);
4916
7225a479 4917 if not Has_Discriminants (Dummy_Object_Typ) then
15529d0a
PMR
4918 Append_To (Result,
4919 Make_Object_Declaration (Loc,
4920 Defining_Identifier => Dummy_Object,
4921 Constant_Present => True,
7225a479
JM
4922 Object_Definition => New_Occurrence_Of
4923 (Dummy_Object_Typ, Loc)));
15529d0a
PMR
4924 else
4925 declare
4926 Constr_List : constant List_Id := New_List;
4927 Discrim : Node_Id;
4928
4929 begin
7225a479 4930 Discrim := First_Discriminant (Dummy_Object_Typ);
15529d0a
PMR
4931 while Present (Discrim) loop
4932 if Is_Discrete_Type (Etype (Discrim)) then
4933 Append_To (Constr_List,
4934 Make_Attribute_Reference (Loc,
7f5e671b
PMR
4935 Prefix =>
4936 New_Occurrence_Of (Etype (Discrim), Loc),
15529d0a
PMR
4937 Attribute_Name => Name_First));
4938
4939 else
4940 pragma Assert (Is_Access_Type (Etype (Discrim)));
4941 Cannot_Have_Null_Disc :=
4942 Cannot_Have_Null_Disc
4943 or else Can_Never_Be_Null (Etype (Discrim));
4944 Append_To (Constr_List, Make_Null (Loc));
4945 end if;
4946
4947 Next_Discriminant (Discrim);
4948 end loop;
4949
4950 Append_To (Result,
4951 Make_Object_Declaration (Loc,
4952 Defining_Identifier => Dummy_Object,
4953 Constant_Present => True,
4954 Object_Definition =>
4955 Make_Subtype_Indication (Loc,
7225a479
JM
4956 Subtype_Mark =>
4957 New_Occurrence_Of (Dummy_Object_Typ, Loc),
15529d0a
PMR
4958 Constraint =>
4959 Make_Index_Or_Discriminant_Constraint (Loc,
4960 Constraints => Constr_List))));
4961 end;
4962 end if;
4963
4964 -- Given that the dummy object will not be declared at run time,
4965 -- analyze its declaration with expansion disabled and warnings
4966 -- and error messages ignored.
4967
4968 Expander_Mode_Save_And_Set (False);
4969 Ignore_Errors_Enable := Ignore_Errors_Enable + 1;
4970 Analyze (Last (Result), Suppress => All_Checks);
4971 Ignore_Errors_Enable := Ignore_Errors_Enable - 1;
4972 Expander_Mode_Restore;
4973 end;
4974 end if;
4975
b2e1beb3
ES
4976 -- Ada 2005 (AI-251): Build the secondary dispatch tables
4977
ce2b6ba5 4978 if Has_Interfaces (Typ) then
b2e1beb3
ES
4979 Collect_Interface_Components (Typ, Typ_Comps);
4980
b16d9747
JM
4981 -- Each secondary dispatch table is assigned an unique positive
4982 -- suffix index; such value also corresponds with the location of
4983 -- its entity in the Dispatch_Table_Wrappers list (see Make_Tags).
4984
4985 -- Note: This value must be kept sync with the Suffix_Index values
4986 -- generated by Make_Tags
4987
4988 Suffix_Index := 1;
1923d2d6
JM
4989 AI_Tag_Elmt :=
4990 Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
b2e1beb3
ES
4991
4992 AI_Tag_Comp := First_Elmt (Typ_Comps);
4993 while Present (AI_Tag_Comp) loop
cefce34c 4994 pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'P'));
80b992ae
HK
4995
4996 -- Build the secondary table containing pointers to thunks
4997
b2e1beb3 4998 Make_Secondary_DT
6782b1ef 4999 (Typ => Typ,
7f5e671b
PMR
5000 Iface =>
5001 Base_Type (Related_Type (Node (AI_Tag_Comp))),
15529d0a 5002 Iface_Comp => Node (AI_Tag_Comp),
6782b1ef 5003 Suffix_Index => Suffix_Index,
7f5e671b
PMR
5004 Num_Iface_Prims =>
5005 UI_To_Int (DT_Entry_Count (Node (AI_Tag_Comp))),
6782b1ef 5006 Iface_DT_Ptr => Node (AI_Tag_Elmt),
1923d2d6 5007 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
6782b1ef
AC
5008 Build_Thunks => True,
5009 Result => Result);
80b992ae 5010
cefce34c
JM
5011 -- Skip secondary dispatch table referencing thunks to predefined
5012 -- primitives.
1923d2d6 5013
b16d9747 5014 Next_Elmt (AI_Tag_Elmt);
cefce34c
JM
5015 pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'Y'));
5016
5017 -- Secondary dispatch table referencing user-defined primitives
5018 -- covered by this interface.
5019
1923d2d6 5020 Next_Elmt (AI_Tag_Elmt);
cefce34c 5021 pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'D'));
1923d2d6 5022
8fc789c8 5023 -- Build the secondary table containing pointers to primitives
80b992ae
HK
5024 -- (used to give support to Generic Dispatching Constructors).
5025
5026 Make_Secondary_DT
cefce34c
JM
5027 (Typ => Typ,
5028 Iface => Base_Type
5029 (Related_Type (Node (AI_Tag_Comp))),
15529d0a 5030 Iface_Comp => Node (AI_Tag_Comp),
cefce34c
JM
5031 Suffix_Index => -1,
5032 Num_Iface_Prims => UI_To_Int
5033 (DT_Entry_Count (Node (AI_Tag_Comp))),
5034 Iface_DT_Ptr => Node (AI_Tag_Elmt),
5035 Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
5036 Build_Thunks => False,
5037 Result => Result);
5038
5039 -- Skip secondary dispatch table referencing predefined primitives
1923d2d6 5040
b16d9747 5041 Next_Elmt (AI_Tag_Elmt);
cefce34c 5042 pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'Z'));
1923d2d6 5043
b2e1beb3 5044 Suffix_Index := Suffix_Index + 1;
cefce34c 5045 Next_Elmt (AI_Tag_Elmt);
b2e1beb3
ES
5046 Next_Elmt (AI_Tag_Comp);
5047 end loop;
5048 end if;
d0dd5209 5049
afbcdf5e 5050 -- Get the _tag entity and number of primitives of its dispatch table
d0dd5209 5051
e18d6a15
JM
5052 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Typ)));
5053 Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));
d0dd5209 5054
078b1a5f
AC
5055 if Generate_SCIL then
5056 Nb_Prim := 0;
5057 end if;
5058
5b7dd52d
JM
5059 Set_Is_Statically_Allocated (DT, Is_Library_Level_Tagged_Type (Typ));
5060 Set_Is_Statically_Allocated (SSD, Is_Library_Level_Tagged_Type (Typ));
5061 Set_Is_Statically_Allocated (TSD, Is_Library_Level_Tagged_Type (Typ));
5062 Set_Is_Statically_Allocated (Predef_Prims,
5063 Is_Library_Level_Tagged_Type (Typ));
d0dd5209
JM
5064
5065 -- In case of locally defined tagged type we declare the object
8fc789c8 5066 -- containing the dispatch table by means of a variable. Its
d0dd5209
JM
5067 -- initialization is done later by means of an assignment. This is
5068 -- required to generate its External_Tag.
5069
e18d6a15 5070 if not Building_Static_DT (Typ) then
d0dd5209
JM
5071
5072 -- Generate:
5073 -- DT : No_Dispatch_Table_Wrapper;
5074 -- DT_Ptr : Tag := !Tag (DT.NDT_Prims_Ptr'Address);
5075
e18d6a15 5076 if not Has_DT (Typ) then
d0dd5209
JM
5077 Append_To (Result,
5078 Make_Object_Declaration (Loc,
5079 Defining_Identifier => DT,
5080 Aliased_Present => True,
5081 Constant_Present => False,
5082 Object_Definition =>
e4494292 5083 New_Occurrence_Of
d0dd5209
JM
5084 (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
5085
5086 Append_To (Result,
5087 Make_Object_Declaration (Loc,
5088 Defining_Identifier => DT_Ptr,
e4494292 5089 Object_Definition => New_Occurrence_Of (RTE (RE_Tag), Loc),
d0dd5209
JM
5090 Constant_Present => True,
5091 Expression =>
e18d6a15 5092 Unchecked_Convert_To (RTE (RE_Tag),
d0dd5209 5093 Make_Attribute_Reference (Loc,
6782b1ef 5094 Prefix =>
d0dd5209 5095 Make_Selected_Component (Loc,
6782b1ef
AC
5096 Prefix => New_Occurrence_Of (DT, Loc),
5097 Selector_Name =>
5098 New_Occurrence_Of
5099 (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
d0dd5209
JM
5100 Attribute_Name => Name_Address))));
5101
d151d6a3
AC
5102 Set_Is_Statically_Allocated (DT_Ptr,
5103 Is_Library_Level_Tagged_Type (Typ));
5104
a50790d1
JM
5105 -- Generate the SCIL node for the previous object declaration
5106 -- because it has a tag initialization.
5107
81d93365 5108 if Generate_SCIL then
327503f1
JM
5109 New_Node :=
5110 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
327503f1 5111 Set_SCIL_Entity (New_Node, Typ);
7665e4bd 5112 Set_SCIL_Node (Last (Result), New_Node);
078b1a5f 5113
d65a80fd 5114 goto Leave_SCIL;
078b1a5f
AC
5115
5116 -- Gnat2scil has its own implementation of dispatch tables,
5117 -- different than what is being implemented here. Generating
5118 -- further dispatch table initialization code would just
5119 -- cause gnat2scil to generate useless Scil which CodePeer
5120 -- would waste time and space analyzing, so we skip it.
81d93365
AC
5121 end if;
5122
d0dd5209
JM
5123 -- Generate:
5124 -- DT : Dispatch_Table_Wrapper (Nb_Prim);
d0dd5209
JM
5125 -- DT_Ptr : Tag := !Tag (DT.Prims_Ptr'Address);
5126
5127 else
5128 -- If the tagged type has no primitives we add a dummy slot
5129 -- whose address will be the tag of this type.
5130
5131 if Nb_Prim = 0 then
5132 DT_Constr_List :=
5133 New_List (Make_Integer_Literal (Loc, 1));
5134 else
5135 DT_Constr_List :=
5136 New_List (Make_Integer_Literal (Loc, Nb_Prim));
5137 end if;
5138
5139 Append_To (Result,
5140 Make_Object_Declaration (Loc,
5141 Defining_Identifier => DT,
5142 Aliased_Present => True,
5143 Constant_Present => False,
5144 Object_Definition =>
5145 Make_Subtype_Indication (Loc,
5146 Subtype_Mark =>
e4494292 5147 New_Occurrence_Of (RTE (RE_Dispatch_Table_Wrapper), Loc),
6782b1ef
AC
5148 Constraint =>
5149 Make_Index_Or_Discriminant_Constraint (Loc,
5150 Constraints => DT_Constr_List))));
d0dd5209 5151
d0dd5209
JM
5152 Append_To (Result,
5153 Make_Object_Declaration (Loc,
5154 Defining_Identifier => DT_Ptr,
e4494292 5155 Object_Definition => New_Occurrence_Of (RTE (RE_Tag), Loc),
d0dd5209
JM
5156 Constant_Present => True,
5157 Expression =>
e18d6a15 5158 Unchecked_Convert_To (RTE (RE_Tag),
d0dd5209 5159 Make_Attribute_Reference (Loc,
6782b1ef 5160 Prefix =>
d0dd5209 5161 Make_Selected_Component (Loc,
6782b1ef
AC
5162 Prefix => New_Occurrence_Of (DT, Loc),
5163 Selector_Name =>
5164 New_Occurrence_Of
5165 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
d0dd5209 5166 Attribute_Name => Name_Address))));
1923d2d6 5167
d151d6a3
AC
5168 Set_Is_Statically_Allocated (DT_Ptr,
5169 Is_Library_Level_Tagged_Type (Typ));
5170
a50790d1
JM
5171 -- Generate the SCIL node for the previous object declaration
5172 -- because it has a tag initialization.
97cb64f0 5173
81d93365 5174 if Generate_SCIL then
327503f1
JM
5175 New_Node :=
5176 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
327503f1 5177 Set_SCIL_Entity (New_Node, Typ);
7665e4bd 5178 Set_SCIL_Node (Last (Result), New_Node);
078b1a5f 5179
d65a80fd 5180 goto Leave_SCIL;
078b1a5f
AC
5181
5182 -- Gnat2scil has its own implementation of dispatch tables,
5183 -- different than what is being implemented here. Generating
5184 -- further dispatch table initialization code would just
5185 -- cause gnat2scil to generate useless Scil which CodePeer
5186 -- would waste time and space analyzing, so we skip it.
81d93365
AC
5187 end if;
5188
1923d2d6
JM
5189 Append_To (Result,
5190 Make_Object_Declaration (Loc,
5191 Defining_Identifier =>
5192 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Typ)))),
5193 Constant_Present => True,
6782b1ef
AC
5194 Object_Definition =>
5195 New_Occurrence_Of (RTE (RE_Address), Loc),
3d581777 5196 Expression =>
1923d2d6 5197 Make_Attribute_Reference (Loc,
6782b1ef 5198 Prefix =>
1923d2d6 5199 Make_Selected_Component (Loc,
6782b1ef
AC
5200 Prefix => New_Occurrence_Of (DT, Loc),
5201 Selector_Name =>
5202 New_Occurrence_Of
5203 (RTE_Record_Component (RE_Predef_Prims), Loc)),
1923d2d6 5204 Attribute_Name => Name_Address)));
d0dd5209
JM
5205 end if;
5206 end if;
5207
51ab2a39 5208 -- Generate: Expanded_Name : constant String := "";
b00baef5 5209
51ab2a39 5210 if Discard_Names then
b00baef5
JM
5211 Append_To (Result,
5212 Make_Object_Declaration (Loc,
51ab2a39 5213 Defining_Identifier => Exname,
b00baef5
JM
5214 Constant_Present => True,
5215 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
5216 Expression =>
5217 Make_String_Literal (Loc, "")));
5218
51ab2a39 5219 -- Generate: Exname : constant String := full_qualified_name (typ);
dee4682a
JM
5220 -- The type itself may be an anonymous parent type, so use the first
5221 -- subtype to have a user-recognizable name.
10b93b2e 5222
b00baef5
JM
5223 else
5224 Append_To (Result,
5225 Make_Object_Declaration (Loc,
51ab2a39 5226 Defining_Identifier => Exname,
b00baef5
JM
5227 Constant_Present => True,
5228 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
5229 Expression =>
5230 Make_String_Literal (Loc,
5231 Fully_Qualified_Name_String (First_Subtype (Typ)))));
5232 end if;
5233
51ab2a39
JM
5234 Set_Is_Statically_Allocated (Exname);
5235 Set_Is_True_Constant (Exname);
e18d6a15 5236
6e818918
JM
5237 -- Declare the object used by Ada.Tags.Register_Tag
5238
5239 if RTE_Available (RE_Register_Tag) then
5240 Append_To (Result,
5241 Make_Object_Declaration (Loc,
5242 Defining_Identifier => HT_Link,
6214b83b
PMR
5243 Object_Definition => New_Occurrence_Of (RTE (RE_Tag), Loc),
5244 Expression => New_Occurrence_Of (RTE (RE_No_Tag), Loc)));
6e818918
JM
5245 end if;
5246
d0dd5209
JM
5247 -- Generate code to create the storage for the type specific data object
5248 -- with enough space to store the tags of the ancestors plus the tags
5249 -- of all the implemented interfaces (as described in a-tags.adb).
5250
5251 -- TSD : Type_Specific_Data (I_Depth) :=
5252 -- (Idepth => I_Depth,
5253 -- Access_Level => Type_Access_Level (Typ),
6bed26b5 5254 -- Alignment => Typ'Alignment,
51ab2a39
JM
5255 -- Expanded_Name => Cstring_Ptr!(Exname'Address))
5256 -- External_Tag => Cstring_Ptr!(Exname'Address))
6e818918 5257 -- HT_Link => HT_Link'Address,
d0dd5209 5258 -- Transportable => <<boolean-value>>,
b6e6a4e3 5259 -- Is_Abstract => <<boolean-value>>,
df3e68b1 5260 -- Needs_Finalization => <<boolean-value>>,
ee1a7572
AC
5261 -- [ Size_Func => Size_Prim'Access, ]
5262 -- [ Interfaces_Table => <<access-value>>, ]
e18d6a15 5263 -- [ SSD => SSD_Table'Address ]
d0dd5209
JM
5264 -- Tags_Table => (0 => null,
5265 -- 1 => Parent'Tag
5266 -- ...);
d0dd5209
JM
5267
5268 TSD_Aggr_List := New_List;
5269
5270 -- Idepth: Count ancestors to compute the inheritance depth. For private
5271 -- extensions, always go to the full view in order to compute the real
5272 -- inheritance depth.
5273
5274 declare
5275 Current_Typ : Entity_Id;
5276 Parent_Typ : Entity_Id;
5277
5278 begin
5279 I_Depth := 0;
5280 Current_Typ := Typ;
5281 loop
5282 Parent_Typ := Etype (Current_Typ);
5283
5284 if Is_Private_Type (Parent_Typ) then
5285 Parent_Typ := Full_View (Base_Type (Parent_Typ));
5286 end if;
5287
5288 exit when Parent_Typ = Current_Typ;
5289
5290 I_Depth := I_Depth + 1;
5291 Current_Typ := Parent_Typ;
5292 end loop;
5293 end;
5294
5295 Append_To (TSD_Aggr_List,
b2e1beb3 5296 Make_Integer_Literal (Loc, I_Depth));
d0dd5209
JM
5297
5298 -- Access_Level
5299
5300 Append_To (TSD_Aggr_List,
b2e1beb3 5301 Make_Integer_Literal (Loc, Type_Access_Level (Typ)));
d0dd5209 5302
6bed26b5
AC
5303 -- Alignment
5304
5305 -- For CPP types we cannot rely on the value of 'Alignment provided
5306 -- by the backend to initialize this TSD field.
5307
5308 if Convention (Typ) = Convention_CPP
5309 or else Is_CPP_Class (Root_Type (Typ))
5310 then
5311 Append_To (TSD_Aggr_List,
5312 Make_Integer_Literal (Loc, 0));
5313 else
5314 Append_To (TSD_Aggr_List,
5315 Make_Attribute_Reference (Loc,
6782b1ef 5316 Prefix => New_Occurrence_Of (Typ, Loc),
6bed26b5
AC
5317 Attribute_Name => Name_Alignment));
5318 end if;
5319
d0dd5209
JM
5320 -- Expanded_Name
5321
5322 Append_To (TSD_Aggr_List,
b2e1beb3
ES
5323 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
5324 Make_Attribute_Reference (Loc,
51ab2a39 5325 Prefix => New_Occurrence_Of (Exname, Loc),
b2e1beb3 5326 Attribute_Name => Name_Address)));
d0dd5209
JM
5327
5328 -- External_Tag of a local tagged type
5329
b2e1beb3 5330 -- <typ>A : constant String :=
d0dd5209
JM
5331 -- "Internal tag at 16#tag-addr#: <full-name-of-typ>";
5332
5333 -- The reason we generate this strange name is that we do not want to
5334 -- enter local tagged types in the global hash table used to compute
5335 -- the Internal_Tag attribute for two reasons:
5336
5337 -- 1. It is hard to avoid a tasking race condition for entering the
5338 -- entry into the hash table.
5339
5340 -- 2. It would cause a storage leak, unless we rig up considerable
5341 -- mechanism to remove the entry from the hash table on exit.
5342
5343 -- So what we do is to generate the above external tag name, where the
5344 -- hex address is the address of the local dispatch table (i.e. exactly
5345 -- the value we want if Internal_Tag is computed from this string).
5346
5347 -- Of course this value will only be valid if the tagged type is still
5348 -- in scope, but it clearly must be erroneous to compute the internal
a90bd866 5349 -- tag of a tagged type that is out of scope.
d0dd5209 5350
b2e1beb3
ES
5351 -- We don't do this processing if an explicit external tag has been
5352 -- specified. That's an odd case for which we have already issued a
5353 -- warning, where we will not be able to compute the internal tag.
5354
51ab2a39
JM
5355 if not Discard_Names
5356 and then not Is_Library_Level_Entity (Typ)
b2e1beb3
ES
5357 and then not Has_External_Tag_Rep_Clause (Typ)
5358 then
d0dd5209 5359 declare
6782b1ef
AC
5360 Exname : constant Entity_Id :=
5361 Make_Defining_Identifier (Loc,
5362 Chars => New_External_Name (Tname, 'A'));
5363 Full_Name : constant String_Id :=
afbcdf5e 5364 Fully_Qualified_Name_String (First_Subtype (Typ));
6782b1ef
AC
5365 Str1_Id : String_Id;
5366 Str2_Id : String_Id;
d0dd5209
JM
5367
5368 begin
5369 -- Generate:
b2e1beb3 5370 -- Str1 = "Internal tag at 16#";
d0dd5209
JM
5371
5372 Start_String;
5373 Store_String_Chars ("Internal tag at 16#");
5374 Str1_Id := End_String;
5375
5376 -- Generate:
b2e1beb3 5377 -- Str2 = "#: <type-full-name>";
d0dd5209
JM
5378
5379 Start_String;
5380 Store_String_Chars ("#: ");
d0dd5209 5381 Store_String_Chars (Full_Name);
b2e1beb3 5382 Str2_Id := End_String;
d0dd5209
JM
5383
5384 -- Generate:
5385 -- Exname : constant String :=
b2e1beb3 5386 -- Str1 & Address_Image (Tag) & Str2;
d0dd5209
JM
5387
5388 if RTE_Available (RE_Address_Image) then
5389 Append_To (Result,
5390 Make_Object_Declaration (Loc,
5391 Defining_Identifier => Exname,
5392 Constant_Present => True,
e4494292 5393 Object_Definition => New_Occurrence_Of
d0dd5209
JM
5394 (Standard_String, Loc),
5395 Expression =>
5396 Make_Op_Concat (Loc,
6782b1ef 5397 Left_Opnd => Make_String_Literal (Loc, Str1_Id),
d0dd5209
JM
5398 Right_Opnd =>
5399 Make_Op_Concat (Loc,
6782b1ef 5400 Left_Opnd =>
d0dd5209
JM
5401 Make_Function_Call (Loc,
5402 Name =>
e4494292 5403 New_Occurrence_Of
d0dd5209
JM
5404 (RTE (RE_Address_Image), Loc),
5405 Parameter_Associations => New_List (
5406 Unchecked_Convert_To (RTE (RE_Address),
e4494292 5407 New_Occurrence_Of (DT_Ptr, Loc)))),
d0dd5209 5408 Right_Opnd =>
b2e1beb3
ES
5409 Make_String_Literal (Loc, Str2_Id)))));
5410
b00baef5
JM
5411 -- Generate:
5412 -- Exname : constant String := Str1 & Str2;
5413
d0dd5209
JM
5414 else
5415 Append_To (Result,
5416 Make_Object_Declaration (Loc,
5417 Defining_Identifier => Exname,
5418 Constant_Present => True,
6782b1ef
AC
5419 Object_Definition =>
5420 New_Occurrence_Of (Standard_String, Loc),
5421 Expression =>
d0dd5209 5422 Make_Op_Concat (Loc,
6782b1ef
AC
5423 Left_Opnd => Make_String_Literal (Loc, Str1_Id),
5424 Right_Opnd => Make_String_Literal (Loc, Str2_Id))));
d0dd5209
JM
5425 end if;
5426
5427 New_Node :=
5428 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
5429 Make_Attribute_Reference (Loc,
6782b1ef 5430 Prefix => New_Occurrence_Of (Exname, Loc),
d0dd5209
JM
5431 Attribute_Name => Name_Address));
5432 end;
5433
5434 -- External tag of a library-level tagged type: Check for a definition
5435 -- of External_Tag. The clause is considered only if it applies to this
5436 -- specific tagged type, as opposed to one of its ancestors.
f2cbd970
JM
5437 -- If the type is an unconstrained type extension, we are building the
5438 -- dispatch table of its anonymous base type, so the external tag, if
46fe0142
AC
5439 -- any was specified, must be retrieved from the first subtype. Go to
5440 -- the full view in case the clause is in the private part.
d0dd5209
JM
5441
5442 else
5443 declare
f2cbd970 5444 Def : constant Node_Id := Get_Attribute_Definition_Clause
46fe0142 5445 (Underlying_Type (First_Subtype (Typ)),
f2cbd970
JM
5446 Attribute_External_Tag);
5447
d0dd5209
JM
5448 Old_Val : String_Id;
5449 New_Val : String_Id;
5450 E : Entity_Id;
5451
5452 begin
5453 if not Present (Def)
f2cbd970 5454 or else Entity (Name (Def)) /= First_Subtype (Typ)
d0dd5209
JM
5455 then
5456 New_Node :=
5457 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
5458 Make_Attribute_Reference (Loc,
51ab2a39 5459 Prefix => New_Occurrence_Of (Exname, Loc),
d0dd5209
JM
5460 Attribute_Name => Name_Address));
5461 else
5462 Old_Val := Strval (Expr_Value_S (Expression (Def)));
5463
b2e1beb3 5464 -- For the rep clause "for <typ>'external_tag use y" generate:
d0dd5209 5465
b2e1beb3
ES
5466 -- <typ>A : constant string := y;
5467 --
5468 -- <typ>A'Address is used to set the External_Tag component
5469 -- of the TSD
d0dd5209
JM
5470
5471 -- Create a new nul terminated string if it is not already
5472
5473 if String_Length (Old_Val) > 0
5474 and then
5475 Get_String_Char (Old_Val, String_Length (Old_Val)) = 0
5476 then
5477 New_Val := Old_Val;
5478 else
5479 Start_String (Old_Val);
5480 Store_String_Char (Get_Char_Code (ASCII.NUL));
5481 New_Val := End_String;
5482 end if;
5483
5484 E := Make_Defining_Identifier (Loc,
5485 New_External_Name (Chars (Typ), 'A'));
5486
5487 Append_To (Result,
5488 Make_Object_Declaration (Loc,
5489 Defining_Identifier => E,
5490 Constant_Present => True,
5491 Object_Definition =>
e4494292 5492 New_Occurrence_Of (Standard_String, Loc),
d0dd5209
JM
5493 Expression =>
5494 Make_String_Literal (Loc, New_Val)));
5495
5496 New_Node :=
5497 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
5498 Make_Attribute_Reference (Loc,
6782b1ef 5499 Prefix => New_Occurrence_Of (E, Loc),
d0dd5209
JM
5500 Attribute_Name => Name_Address));
5501 end if;
5502 end;
5503 end if;
5504
b2e1beb3 5505 Append_To (TSD_Aggr_List, New_Node);
d0dd5209
JM
5506
5507 -- HT_Link
5508
6e818918
JM
5509 if RTE_Available (RE_Register_Tag) then
5510 Append_To (TSD_Aggr_List,
5511 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
5512 Make_Attribute_Reference (Loc,
6782b1ef 5513 Prefix => New_Occurrence_Of (HT_Link, Loc),
6e818918 5514 Attribute_Name => Name_Address)));
5612989e
PMR
5515
5516 elsif RTE_Record_Component_Available (RE_HT_Link) then
6e818918
JM
5517 Append_To (TSD_Aggr_List,
5518 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
e4494292 5519 New_Occurrence_Of (RTE (RE_Null_Address), Loc)));
6e818918 5520 end if;
d0dd5209
JM
5521
5522 -- Transportable: Set for types that can be used in remote calls
5523 -- with respect to E.4(18) legality rules.
5524
b2e1beb3
ES
5525 declare
5526 Transportable : Entity_Id;
d0dd5209 5527
b2e1beb3
ES
5528 begin
5529 Transportable :=
5530 Boolean_Literals
5531 (Is_Pure (Typ)
5532 or else Is_Shared_Passive (Typ)
5533 or else
5534 ((Is_Remote_Types (Typ)
6782b1ef 5535 or else Is_Remote_Call_Interface (Typ))
b2e1beb3
ES
5536 and then Original_View_In_Visible_Part (Typ))
5537 or else not Comes_From_Source (Typ));
5538
5539 Append_To (TSD_Aggr_List,
5540 New_Occurrence_Of (Transportable, Loc));
5541 end;
d0dd5209 5542
b6e6a4e3
AC
5543 -- Is_Abstract (Ada 2012: AI05-0173). This functionality is not
5544 -- available in the HIE runtime.
0eb4c1a7 5545
b6e6a4e3 5546 if RTE_Record_Component_Available (RE_Is_Abstract) then
0eb4c1a7 5547 declare
b6e6a4e3 5548 Is_Abstract : Entity_Id;
0eb4c1a7 5549 begin
b6e6a4e3 5550 Is_Abstract := Boolean_Literals (Is_Abstract_Type (Typ));
0eb4c1a7 5551 Append_To (TSD_Aggr_List,
b6e6a4e3 5552 New_Occurrence_Of (Is_Abstract, Loc));
0eb4c1a7
AC
5553 end;
5554 end if;
5555
df3e68b1
HK
5556 -- Needs_Finalization: Set if the type is controlled or has controlled
5557 -- components.
4d744221 5558
b2e1beb3 5559 declare
df3e68b1 5560 Needs_Fin : Entity_Id;
b2e1beb3 5561 begin
df3e68b1
HK
5562 Needs_Fin := Boolean_Literals (Needs_Finalization (Typ));
5563 Append_To (TSD_Aggr_List, New_Occurrence_Of (Needs_Fin, Loc));
b2e1beb3 5564 end;
d0dd5209 5565
f2cbd970
JM
5566 -- Size_Func
5567
5568 if RTE_Record_Component_Available (RE_Size_Func) then
87dc09cb
AC
5569
5570 -- Initialize this field to Null_Address if we are not building
5571 -- static dispatch tables static or if the size function is not
5572 -- available. In the former case we cannot initialize this field
5573 -- until the function is frozen and registered in the dispatch
5574 -- table (see Register_Primitive).
5575
5576 if not Building_Static_DT (Typ) or else not Has_DT (Typ) then
f2cbd970
JM
5577 Append_To (TSD_Aggr_List,
5578 Unchecked_Convert_To (RTE (RE_Size_Ptr),
e4494292 5579 New_Occurrence_Of (RTE (RE_Null_Address), Loc)));
f2cbd970
JM
5580
5581 else
5582 declare
5583 Prim_Elmt : Elmt_Id;
5584 Prim : Entity_Id;
1f8766d3 5585 Size_Comp : Node_Id := Empty;
f2cbd970
JM
5586
5587 begin
5588 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5589 while Present (Prim_Elmt) loop
5590 Prim := Node (Prim_Elmt);
5591
5592 if Chars (Prim) = Name_uSize then
b81a5940 5593 Prim := Ultimate_Alias (Prim);
f2cbd970
JM
5594
5595 if Is_Abstract_Subprogram (Prim) then
1c218ac3 5596 Size_Comp :=
f2cbd970 5597 Unchecked_Convert_To (RTE (RE_Size_Ptr),
e4494292 5598 New_Occurrence_Of (RTE (RE_Null_Address), Loc));
f2cbd970 5599 else
1c218ac3 5600 Size_Comp :=
f2cbd970
JM
5601 Unchecked_Convert_To (RTE (RE_Size_Ptr),
5602 Make_Attribute_Reference (Loc,
6782b1ef 5603 Prefix => New_Occurrence_Of (Prim, Loc),
1c218ac3 5604 Attribute_Name => Name_Unrestricted_Access));
f2cbd970
JM
5605 end if;
5606
5607 exit;
5608 end if;
5609
5610 Next_Elmt (Prim_Elmt);
5611 end loop;
1c218ac3
AC
5612
5613 pragma Assert (Present (Size_Comp));
5614 Append_To (TSD_Aggr_List, Size_Comp);
f2cbd970
JM
5615 end;
5616 end if;
5617 end if;
5618
d0dd5209
JM
5619 -- Interfaces_Table (required for AI-405)
5620
5621 if RTE_Record_Component_Available (RE_Interfaces_Table) then
5622
5623 -- Count the number of interface types implemented by Typ
5624
ce2b6ba5 5625 Collect_Interfaces (Typ, Typ_Ifaces);
d0dd5209
JM
5626
5627 AI := First_Elmt (Typ_Ifaces);
5628 while Present (AI) loop
5629 Num_Ifaces := Num_Ifaces + 1;
5630 Next_Elmt (AI);
5631 end loop;
4d744221 5632
dee4682a 5633 if Num_Ifaces = 0 then
d0dd5209 5634 Iface_Table_Node := Make_Null (Loc);
4d744221 5635
d0dd5209 5636 -- Generate the Interface_Table object
dee4682a
JM
5637
5638 else
d0dd5209 5639 declare
3ec54569
PMR
5640 TSD_Ifaces_List : constant List_Id := New_List;
5641 Elmt : Elmt_Id;
3ec54569
PMR
5642 Offset_To_Top : Node_Id;
5643 Sec_DT_Tag : Node_Id;
d0dd5209 5644
7225a479
JM
5645 Dummy_Object_Ifaces_List : Elist_Id := No_Elist;
5646 Dummy_Object_Ifaces_Comp_List : Elist_Id := No_Elist;
5647 Dummy_Object_Ifaces_Tag_List : Elist_Id := No_Elist;
5648 -- Interfaces information of the dummy object
5649
d0dd5209 5650 begin
3ec54569
PMR
5651 -- Collect interfaces information if we need to compute the
5652 -- offset to the top using the dummy object.
5653
5654 if Present (Dummy_Object) then
5655 Collect_Interfaces_Info (Typ,
7225a479
JM
5656 Ifaces_List => Dummy_Object_Ifaces_List,
5657 Components_List => Dummy_Object_Ifaces_Comp_List,
5658 Tags_List => Dummy_Object_Ifaces_Tag_List);
3ec54569
PMR
5659 end if;
5660
d0dd5209
JM
5661 AI := First_Elmt (Typ_Ifaces);
5662 while Present (AI) loop
4ac2477e 5663 if Is_Ancestor (Node (AI), Typ, Use_Full_View => True) then
65e5747e
PMR
5664 Sec_DT_Tag := New_Occurrence_Of (DT_Ptr, Loc);
5665
80b992ae 5666 else
1923d2d6
JM
5667 Elmt :=
5668 Next_Elmt
5669 (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
80b992ae
HK
5670 pragma Assert (Has_Thunks (Node (Elmt)));
5671
cefce34c 5672 while Is_Tag (Node (Elmt))
65e5747e
PMR
5673 and then not
5674 Is_Ancestor (Node (AI), Related_Type (Node (Elmt)),
5675 Use_Full_View => True)
80b992ae
HK
5676 loop
5677 pragma Assert (Has_Thunks (Node (Elmt)));
5678 Next_Elmt (Elmt);
1923d2d6
JM
5679 pragma Assert (Has_Thunks (Node (Elmt)));
5680 Next_Elmt (Elmt);
5681 pragma Assert (not Has_Thunks (Node (Elmt)));
5682 Next_Elmt (Elmt);
80b992ae
HK
5683 pragma Assert (not Has_Thunks (Node (Elmt)));
5684 Next_Elmt (Elmt);
5685 end loop;
5686
5687 pragma Assert (Ekind (Node (Elmt)) = E_Constant
1923d2d6
JM
5688 and then not
5689 Has_Thunks (Node (Next_Elmt (Next_Elmt (Elmt)))));
65e5747e 5690
80b992ae 5691 Sec_DT_Tag :=
65e5747e
PMR
5692 New_Occurrence_Of
5693 (Node (Next_Elmt (Next_Elmt (Elmt))), Loc);
80b992ae
HK
5694 end if;
5695
7225a479
JM
5696 -- Use the dummy object to compute Offset_To_Top of
5697 -- components located at fixed position.
3ec54569
PMR
5698
5699 if Present (Dummy_Object) then
5700 declare
5701 Iface : constant Node_Id := Node (AI);
5702 Iface_Comp : Node_Id := Empty;
5703 Iface_Comp_Elmt : Elmt_Id;
5704 Iface_Elmt : Elmt_Id;
5705
5706 begin
7225a479
JM
5707 Iface_Elmt :=
5708 First_Elmt (Dummy_Object_Ifaces_List);
5709 Iface_Comp_Elmt :=
5710 First_Elmt (Dummy_Object_Ifaces_Comp_List);
3ec54569
PMR
5711
5712 while Present (Iface_Elmt) loop
5713 if Node (Iface_Elmt) = Iface then
5714 Iface_Comp := Node (Iface_Comp_Elmt);
5715 exit;
5716 end if;
5717
5718 Next_Elmt (Iface_Elmt);
5719 Next_Elmt (Iface_Comp_Elmt);
5720 end loop;
65e5747e 5721
3ec54569
PMR
5722 pragma Assert (Present (Iface_Comp));
5723
7225a479
JM
5724 if not
5725 Is_Variable_Size_Record (Etype (Scope (Iface_Comp)))
5726 then
5727 Offset_To_Top :=
5728 Make_Op_Minus (Loc,
5729 Make_Attribute_Reference (Loc,
5730 Prefix =>
5731 Make_Selected_Component (Loc,
5732 Prefix =>
5733 New_Occurrence_Of (Dummy_Object, Loc),
5734 Selector_Name =>
5735 New_Occurrence_Of (Iface_Comp, Loc)),
5736 Attribute_Name => Name_Position));
5737 else
5738 Offset_To_Top := Make_Integer_Literal (Loc, 0);
5739 end if;
3ec54569
PMR
5740 end;
5741 else
5742 Offset_To_Top := Make_Integer_Literal (Loc, 0);
5743 end if;
5744
b2e1beb3 5745 Append_To (TSD_Ifaces_List,
65e5747e
PMR
5746 Make_Aggregate (Loc,
5747 Expressions => New_List (
b2e1beb3
ES
5748
5749 -- Iface_Tag
5750
e18d6a15 5751 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 5752 New_Occurrence_Of
d0dd5209 5753 (Node (First_Elmt (Access_Disp_Table (Node (AI)))),
b2e1beb3 5754 Loc)),
d0dd5209 5755
b2e1beb3 5756 -- Static_Offset_To_Top
d0dd5209 5757
e4494292 5758 New_Occurrence_Of (Standard_True, Loc),
d0dd5209 5759
b2e1beb3
ES
5760 -- Offset_To_Top_Value
5761
3ec54569 5762 Offset_To_Top,
b2e1beb3
ES
5763
5764 -- Offset_To_Top_Func
5765
80b992ae
HK
5766 Make_Null (Loc),
5767
5768 -- Secondary_DT
5769
65e5747e 5770 Unchecked_Convert_To (RTE (RE_Tag), Sec_DT_Tag))));
d0dd5209 5771
d0dd5209
JM
5772 Next_Elmt (AI);
5773 end loop;
d0dd5209 5774
b2e1beb3
ES
5775 Name_ITable := New_External_Name (Tname, 'I');
5776 ITable := Make_Defining_Identifier (Loc, Name_ITable);
5b7dd52d
JM
5777 Set_Is_Statically_Allocated (ITable,
5778 Is_Library_Level_Tagged_Type (Typ));
d0dd5209 5779
3ec54569
PMR
5780 -- The table of interfaces is constant if we are building a
5781 -- static dispatch table; otherwise is not constant because
5782 -- its slots are filled at run time by the IP routine.
d0dd5209 5783
b2e1beb3
ES
5784 Append_To (Result,
5785 Make_Object_Declaration (Loc,
5786 Defining_Identifier => ITable,
5787 Aliased_Present => True,
7225a479 5788 Constant_Present => Building_Static_Secondary_DT (Typ),
b2e1beb3
ES
5789 Object_Definition =>
5790 Make_Subtype_Indication (Loc,
5791 Subtype_Mark =>
e4494292 5792 New_Occurrence_Of (RTE (RE_Interface_Data), Loc),
6782b1ef
AC
5793 Constraint =>
5794 Make_Index_Or_Discriminant_Constraint (Loc,
5795 Constraints => New_List (
5796 Make_Integer_Literal (Loc, Num_Ifaces)))),
d0dd5209 5797
65e5747e
PMR
5798 Expression =>
5799 Make_Aggregate (Loc,
5800 Expressions => New_List (
5801 Make_Integer_Literal (Loc, Num_Ifaces),
5802 Make_Aggregate (Loc, TSD_Ifaces_List)))));
d0dd5209 5803
b2e1beb3
ES
5804 Iface_Table_Node :=
5805 Make_Attribute_Reference (Loc,
e4494292 5806 Prefix => New_Occurrence_Of (ITable, Loc),
b2e1beb3
ES
5807 Attribute_Name => Name_Unchecked_Access);
5808 end;
d0dd5209
JM
5809 end if;
5810
b2e1beb3 5811 Append_To (TSD_Aggr_List, Iface_Table_Node);
d0dd5209
JM
5812 end if;
5813
5814 -- Generate the Select Specific Data table for synchronized types that
5815 -- implement synchronized interfaces. The size of the table is
5816 -- constrained by the number of non-predefined primitive operations.
5817
5818 if RTE_Record_Component_Available (RE_SSD) then
0791fbe9 5819 if Ada_Version >= Ada_2005
e18d6a15 5820 and then Has_DT (Typ)
d0dd5209 5821 and then Is_Concurrent_Record_Type (Typ)
ce2b6ba5 5822 and then Has_Interfaces (Typ)
d0dd5209
JM
5823 and then Nb_Prim > 0
5824 and then not Is_Abstract_Type (Typ)
5825 and then not Is_Controlled (Typ)
5826 and then not Restriction_Active (No_Dispatching_Calls)
c09a557e 5827 and then not Restriction_Active (No_Select_Statements)
d0dd5209 5828 then
dee4682a
JM
5829 Append_To (Result,
5830 Make_Object_Declaration (Loc,
d0dd5209 5831 Defining_Identifier => SSD,
dee4682a
JM
5832 Aliased_Present => True,
5833 Object_Definition =>
5834 Make_Subtype_Indication (Loc,
e4494292 5835 Subtype_Mark => New_Occurrence_Of (
d0dd5209
JM
5836 RTE (RE_Select_Specific_Data), Loc),
5837 Constraint =>
5838 Make_Index_Or_Discriminant_Constraint (Loc,
5839 Constraints => New_List (
5840 Make_Integer_Literal (Loc, Nb_Prim))))));
5841
b2e1beb3
ES
5842 Append_To (Result,
5843 Make_Attribute_Definition_Clause (Loc,
e4494292 5844 Name => New_Occurrence_Of (SSD, Loc),
b2e1beb3
ES
5845 Chars => Name_Alignment,
5846 Expression =>
5847 Make_Attribute_Reference (Loc,
6782b1ef 5848 Prefix =>
e4494292 5849 New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
b2e1beb3
ES
5850 Attribute_Name => Name_Alignment)));
5851
d0dd5209
JM
5852 -- This table is initialized by Make_Select_Specific_Data_Table,
5853 -- which calls Set_Entry_Index and Set_Prim_Op_Kind.
5854
5855 Append_To (TSD_Aggr_List,
b2e1beb3 5856 Make_Attribute_Reference (Loc,
6782b1ef 5857 Prefix => New_Occurrence_Of (SSD, Loc),
b2e1beb3 5858 Attribute_Name => Name_Unchecked_Access));
d0dd5209 5859 else
b2e1beb3 5860 Append_To (TSD_Aggr_List, Make_Null (Loc));
dee4682a 5861 end if;
4d744221
JM
5862 end if;
5863
d0dd5209
JM
5864 -- Initialize the table of ancestor tags. In case of interface types
5865 -- this table is not needed.
10b93b2e 5866
f2cbd970 5867 TSD_Tags_List := New_List;
4d744221 5868
f2cbd970
JM
5869 -- If we are not statically allocating the dispatch table then we must
5870 -- fill position 0 with null because we still have not generated the
5871 -- tag of Typ.
dee4682a 5872
f2cbd970
JM
5873 if not Building_Static_DT (Typ)
5874 or else Is_Interface (Typ)
5875 then
5876 Append_To (TSD_Tags_List,
5877 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 5878 New_Occurrence_Of (RTE (RE_Null_Address), Loc)));
dee4682a 5879
f2cbd970 5880 -- Otherwise we can safely reference the tag
dee4682a 5881
f2cbd970
JM
5882 else
5883 Append_To (TSD_Tags_List,
e4494292 5884 New_Occurrence_Of (DT_Ptr, Loc));
f2cbd970 5885 end if;
dee4682a 5886
f2cbd970 5887 -- Fill the rest of the table with the tags of the ancestors
dee4682a 5888
f2cbd970
JM
5889 declare
5890 Current_Typ : Entity_Id;
5891 Parent_Typ : Entity_Id;
5892 Pos : Nat;
d0dd5209 5893
f2cbd970 5894 begin
b2e1beb3
ES
5895 Pos := 1;
5896 Current_Typ := Typ;
d0dd5209 5897
b2e1beb3
ES
5898 loop
5899 Parent_Typ := Etype (Current_Typ);
dee4682a 5900
b2e1beb3
ES
5901 if Is_Private_Type (Parent_Typ) then
5902 Parent_Typ := Full_View (Base_Type (Parent_Typ));
5903 end if;
5904
5905 exit when Parent_Typ = Current_Typ;
5906
daa72421
AC
5907 if Is_CPP_Class (Parent_Typ) then
5908
b2e1beb3
ES
5909 -- The tags defined in the C++ side will be inherited when
5910 -- the object is constructed (Exp_Ch3.Build_Init_Procedure)
5911
5912 Append_To (TSD_Tags_List,
5913 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 5914 New_Occurrence_Of (RTE (RE_Null_Address), Loc)));
b2e1beb3
ES
5915 else
5916 Append_To (TSD_Tags_List,
e4494292 5917 New_Occurrence_Of
b2e1beb3
ES
5918 (Node (First_Elmt (Access_Disp_Table (Parent_Typ))),
5919 Loc));
5920 end if;
5921
5922 Pos := Pos + 1;
5923 Current_Typ := Parent_Typ;
5924 end loop;
5925
5926 pragma Assert (Pos = I_Depth + 1);
5927 end;
5928
5929 Append_To (TSD_Aggr_List,
5930 Make_Aggregate (Loc,
5931 Expressions => TSD_Tags_List));
dee4682a 5932
d0dd5209 5933 -- Build the TSD object
dee4682a
JM
5934
5935 Append_To (Result,
5936 Make_Object_Declaration (Loc,
5937 Defining_Identifier => TSD,
5938 Aliased_Present => True,
e18d6a15 5939 Constant_Present => Building_Static_DT (Typ),
dee4682a
JM
5940 Object_Definition =>
5941 Make_Subtype_Indication (Loc,
e4494292 5942 Subtype_Mark => New_Occurrence_Of (
dee4682a
JM
5943 RTE (RE_Type_Specific_Data), Loc),
5944 Constraint =>
5945 Make_Index_Or_Discriminant_Constraint (Loc,
5946 Constraints => New_List (
5947 Make_Integer_Literal (Loc, I_Depth)))),
d0dd5209 5948
dee4682a 5949 Expression => Make_Aggregate (Loc,
b2e1beb3 5950 Expressions => TSD_Aggr_List)));
dee4682a 5951
e18d6a15
JM
5952 Set_Is_True_Constant (TSD, Building_Static_DT (Typ));
5953
e18d6a15 5954 -- Initialize or declare the dispatch table object
dee4682a 5955
e18d6a15 5956 if not Has_DT (Typ) then
d0dd5209
JM
5957 DT_Constr_List := New_List;
5958 DT_Aggr_List := New_List;
dee4682a 5959
d0dd5209 5960 -- Typeinfo
4d744221 5961
d0dd5209
JM
5962 New_Node :=
5963 Make_Attribute_Reference (Loc,
6782b1ef 5964 Prefix => New_Occurrence_Of (TSD, Loc),
d0dd5209
JM
5965 Attribute_Name => Name_Address);
5966
5967 Append_To (DT_Constr_List, New_Node);
5968 Append_To (DT_Aggr_List, New_Copy (New_Node));
5969 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
5970
5971 -- In case of locally defined tagged types we have already declared
5972 -- and uninitialized object for the dispatch table, which is now
e18d6a15
JM
5973 -- initialized by means of the following assignment:
5974
5975 -- DT := (TSD'Address, 0);
d0dd5209 5976
e18d6a15 5977 if not Building_Static_DT (Typ) then
d0dd5209
JM
5978 Append_To (Result,
5979 Make_Assignment_Statement (Loc,
6782b1ef
AC
5980 Name => New_Occurrence_Of (DT, Loc),
5981 Expression => Make_Aggregate (Loc, DT_Aggr_List)));
d0dd5209 5982
e18d6a15
JM
5983 -- In case of library level tagged types we declare and export now
5984 -- the constant object containing the dummy dispatch table. There
5985 -- is no need to declare the tag here because it has been previously
5986 -- declared by Make_Tags
5987
5988 -- DT : aliased constant No_Dispatch_Table :=
5989 -- (NDT_TSD => TSD'Address;
5990 -- NDT_Prims_Ptr => 0);
d0dd5209
JM
5991
5992 else
5993 Append_To (Result,
5994 Make_Object_Declaration (Loc,
5995 Defining_Identifier => DT,
5996 Aliased_Present => True,
b2e1beb3 5997 Constant_Present => True,
d0dd5209 5998 Object_Definition =>
e4494292 5999 New_Occurrence_Of (RTE (RE_No_Dispatch_Table_Wrapper), Loc),
6782b1ef 6000 Expression => Make_Aggregate (Loc, DT_Aggr_List)));
d0dd5209 6001
e18d6a15 6002 Export_DT (Typ, DT);
d0dd5209
JM
6003 end if;
6004
6005 -- Common case: Typ has a dispatch table
6006
6007 -- Generate:
6008
6009 -- Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
6010 -- (predef-prim-op-1'address,
6011 -- predef-prim-op-2'address,
6012 -- ...
6013 -- predef-prim-op-n'address);
d0dd5209
JM
6014
6015 -- DT : Dispatch_Table (Nb_Prims) :=
6016 -- (Signature => <sig-value>,
6017 -- Tag_Kind => <tag_kind-value>,
6018 -- Predef_Prims => Predef_Prims'First'Address,
6019 -- Offset_To_Top => 0,
6020 -- TSD => TSD'Address;
6021 -- Prims_Ptr => (prim-op-1'address,
6022 -- prim-op-2'address,
6023 -- ...
6024 -- prim-op-n'address));
b2e1beb3 6025 -- for DT'Alignment use Address'Alignment
d0dd5209
JM
6026
6027 else
6028 declare
bd5ed03a
JM
6029 Nb_P_Prims : constant Nat := Number_Of_Predefined_Prims (Typ);
6030 Prim_Table : array (Nat range 1 .. Nb_P_Prims) of Entity_Id;
6031 Decl : Node_Id;
6032 E : Entity_Id;
d0dd5209
JM
6033
6034 begin
bd5ed03a
JM
6035 Prim_Ops_Aggr_List := New_List;
6036 Prim_Table := (others => Empty);
d0dd5209 6037
bd5ed03a
JM
6038 if Building_Static_DT (Typ) then
6039 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
d0dd5209
JM
6040 while Present (Prim_Elmt) loop
6041 Prim := Node (Prim_Elmt);
6042
6043 if Is_Predefined_Dispatching_Operation (Prim)
6044 and then not Is_Abstract_Subprogram (Prim)
bd5ed03a
JM
6045 and then not Is_Eliminated (Prim)
6046 and then not Generate_SCIL
6047 and then not Present (Prim_Table
6048 (UI_To_Int (DT_Position (Prim))))
d0dd5209 6049 then
bd5ed03a
JM
6050 E := Ultimate_Alias (Prim);
6051 pragma Assert (not Is_Abstract_Subprogram (E));
6052 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
d0dd5209
JM
6053 end if;
6054
6055 Next_Elmt (Prim_Elmt);
6056 end loop;
6057 end if;
6058
bd5ed03a
JM
6059 for J in Prim_Table'Range loop
6060 if Present (Prim_Table (J)) then
6061 New_Node :=
6062 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
6063 Make_Attribute_Reference (Loc,
6064 Prefix =>
6065 New_Occurrence_Of (Prim_Table (J), Loc),
6066 Attribute_Name => Name_Unrestricted_Access));
6067 else
6068 New_Node := Make_Null (Loc);
80b992ae 6069 end if;
d0dd5209 6070
bd5ed03a
JM
6071 Append_To (Prim_Ops_Aggr_List, New_Node);
6072 end loop;
dee4682a 6073
bd5ed03a
JM
6074 New_Node :=
6075 Make_Aggregate (Loc,
6076 Expressions => Prim_Ops_Aggr_List);
f2cbd970 6077
bd5ed03a
JM
6078 Decl :=
6079 Make_Subtype_Declaration (Loc,
6080 Defining_Identifier => Make_Temporary (Loc, 'S'),
6081 Subtype_Indication =>
6082 New_Occurrence_Of (RTE (RE_Address_Array), Loc));
f2cbd970 6083
bd5ed03a 6084 Append_To (Result, Decl);
f2cbd970 6085
bd5ed03a
JM
6086 Append_To (Result,
6087 Make_Object_Declaration (Loc,
6088 Defining_Identifier => Predef_Prims,
6089 Aliased_Present => True,
6090 Constant_Present => Building_Static_DT (Typ),
6091 Object_Definition =>
6092 New_Occurrence_Of (Defining_Identifier (Decl), Loc),
6093 Expression => New_Node));
f2cbd970 6094
bd5ed03a 6095 -- Remember aggregates initializing dispatch tables
f2cbd970 6096
bd5ed03a 6097 Append_Elmt (New_Node, DT_Aggr);
d0dd5209
JM
6098 end;
6099
6100 -- Stage 1: Initialize the discriminant and the record components
6101
6102 DT_Constr_List := New_List;
6103 DT_Aggr_List := New_List;
6104
6105 -- Num_Prims. If the tagged type has no primitives we add a dummy
6106 -- slot whose address will be the tag of this type.
6107
6108 if Nb_Prim = 0 then
6109 New_Node := Make_Integer_Literal (Loc, 1);
6110 else
6111 New_Node := Make_Integer_Literal (Loc, Nb_Prim);
6112 end if;
6113
6114 Append_To (DT_Constr_List, New_Node);
6115 Append_To (DT_Aggr_List, New_Copy (New_Node));
6116
6117 -- Signature
6118
6119 if RTE_Record_Component_Available (RE_Signature) then
6120 Append_To (DT_Aggr_List,
e4494292 6121 New_Occurrence_Of (RTE (RE_Primary_DT), Loc));
d0dd5209
JM
6122 end if;
6123
6124 -- Tag_Kind
6125
6126 if RTE_Record_Component_Available (RE_Tag_Kind) then
6127 Append_To (DT_Aggr_List, Tagged_Kind (Typ));
6128 end if;
6129
6130 -- Predef_Prims
6131
6132 Append_To (DT_Aggr_List,
6133 Make_Attribute_Reference (Loc,
6782b1ef 6134 Prefix => New_Occurrence_Of (Predef_Prims, Loc),
d0dd5209
JM
6135 Attribute_Name => Name_Address));
6136
6137 -- Offset_To_Top
6138
f2cbd970 6139 Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
d0dd5209
JM
6140
6141 -- Typeinfo
6142
6143 Append_To (DT_Aggr_List,
6144 Make_Attribute_Reference (Loc,
6782b1ef 6145 Prefix => New_Occurrence_Of (TSD, Loc),
d0dd5209
JM
6146 Attribute_Name => Name_Address));
6147
22a83cea 6148 -- Stage 2: Initialize the table of user-defined primitive operations
d0dd5209
JM
6149
6150 Prim_Ops_Aggr_List := New_List;
6151
6152 if Nb_Prim = 0 then
f2cbd970 6153 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
d0dd5209 6154
bfae1846 6155 elsif not Building_Static_DT (Typ) then
d0dd5209 6156 for J in 1 .. Nb_Prim loop
f2cbd970 6157 Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
d0dd5209
JM
6158 end loop;
6159
6160 else
6161 declare
cefce34c
JM
6162 CPP_Nb_Prims : constant Nat := CPP_Num_Prims (Typ);
6163 E : Entity_Id;
6164 Prim : Entity_Id;
6165 Prim_Elmt : Elmt_Id;
6166 Prim_Pos : Nat;
6167 Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
d0dd5209
JM
6168
6169 begin
6170 Prim_Table := (others => Empty);
80b992ae
HK
6171
6172 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
d0dd5209
JM
6173 while Present (Prim_Elmt) loop
6174 Prim := Node (Prim_Elmt);
6175
16212e89
GD
6176 -- Retrieve the ultimate alias of the primitive for proper
6177 -- handling of renamings and eliminated primitives.
6178
cc3a2986 6179 E := Ultimate_Alias (Prim);
74a78a4f
AC
6180
6181 -- If the alias is not a primitive operation then Prim does
6182 -- not rename another primitive, but rather an operation
6183 -- declared elsewhere (e.g. in another scope) and therefore
6184 -- Prim is a new primitive.
6185
6186 if No (Find_Dispatching_Type (E)) then
6187 E := Prim;
6188 end if;
6189
cefce34c 6190 Prim_Pos := UI_To_Int (DT_Position (E));
16212e89 6191
241ebe89
HK
6192 -- Skip predefined primitives because they are located in a
6193 -- separate dispatch table.
d0dd5209 6194
9e9df9da
AC
6195 if not Is_Predefined_Dispatching_Operation (Prim)
6196 and then not Is_Predefined_Dispatching_Operation (E)
241ebe89
HK
6197
6198 -- Skip entities with attribute Interface_Alias because
6199 -- those are only required to build secondary dispatch
6200 -- tables.
6201
9e9df9da 6202 and then not Present (Interface_Alias (Prim))
241ebe89
HK
6203
6204 -- Skip abstract and eliminated primitives
6205
9e9df9da 6206 and then not Is_Abstract_Subprogram (E)
9e9df9da 6207 and then not Is_Eliminated (E)
241ebe89
HK
6208
6209 -- For derivations of CPP types skip primitives located in
6210 -- the C++ part of the dispatch table because their slots
6211 -- are initialized by the IC routine.
6212
cefce34c
JM
6213 and then (not Is_CPP_Class (Root_Type (Typ))
6214 or else Prim_Pos > CPP_Nb_Prims)
241ebe89
HK
6215
6216 -- Skip ignored Ghost subprograms as those will be removed
6217 -- from the executable.
6218
6219 and then not Is_Ignored_Ghost_Entity (E)
9e9df9da
AC
6220 then
6221 pragma Assert
6222 (UI_To_Int (DT_Position (Prim)) <= Nb_Prim);
6223
6224 Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
d0dd5209
JM
6225 end if;
6226
6227 Next_Elmt (Prim_Elmt);
6228 end loop;
6229
6230 for J in Prim_Table'Range loop
6231 if Present (Prim_Table (J)) then
6232 New_Node :=
f2cbd970 6233 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
1923d2d6 6234 Make_Attribute_Reference (Loc,
6782b1ef
AC
6235 Prefix =>
6236 New_Occurrence_Of (Prim_Table (J), Loc),
1923d2d6 6237 Attribute_Name => Name_Unrestricted_Access));
d0dd5209 6238 else
f2cbd970 6239 New_Node := Make_Null (Loc);
d0dd5209
JM
6240 end if;
6241
6242 Append_To (Prim_Ops_Aggr_List, New_Node);
6243 end loop;
6244 end;
6245 end if;
6246
f2cbd970 6247 New_Node :=
d0dd5209 6248 Make_Aggregate (Loc,
f2cbd970
JM
6249 Expressions => Prim_Ops_Aggr_List);
6250
6251 Append_To (DT_Aggr_List, New_Node);
6252
6253 -- Remember aggregates initializing dispatch tables
6254
6255 Append_Elmt (New_Node, DT_Aggr);
d0dd5209
JM
6256
6257 -- In case of locally defined tagged types we have already declared
6258 -- and uninitialized object for the dispatch table, which is now
6259 -- initialized by means of an assignment.
6260
e18d6a15 6261 if not Building_Static_DT (Typ) then
d0dd5209
JM
6262 Append_To (Result,
6263 Make_Assignment_Statement (Loc,
6782b1ef
AC
6264 Name => New_Occurrence_Of (DT, Loc),
6265 Expression => Make_Aggregate (Loc, DT_Aggr_List)));
d0dd5209 6266
e18d6a15
JM
6267 -- In case of library level tagged types we declare now and export
6268 -- the constant object containing the dispatch table.
d0dd5209
JM
6269
6270 else
6271 Append_To (Result,
6272 Make_Object_Declaration (Loc,
6273 Defining_Identifier => DT,
6274 Aliased_Present => True,
b2e1beb3 6275 Constant_Present => True,
d0dd5209
JM
6276 Object_Definition =>
6277 Make_Subtype_Indication (Loc,
e4494292 6278 Subtype_Mark => New_Occurrence_Of
d0dd5209
JM
6279 (RTE (RE_Dispatch_Table_Wrapper), Loc),
6280 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
6281 Constraints => DT_Constr_List)),
6782b1ef 6282 Expression => Make_Aggregate (Loc, DT_Aggr_List)));
d0dd5209 6283
e18d6a15 6284 Export_DT (Typ, DT);
4d744221 6285 end if;
f4d379b8 6286 end if;
10b93b2e 6287
b16d9747
JM
6288 -- Initialize the table of ancestor tags if not building static
6289 -- dispatch table
d0dd5209 6290
e18d6a15 6291 if not Building_Static_DT (Typ)
b2e1beb3 6292 and then not Is_Interface (Typ)
d0dd5209
JM
6293 and then not Is_CPP_Class (Typ)
6294 then
6295 Append_To (Result,
6296 Make_Assignment_Statement (Loc,
6782b1ef 6297 Name =>
d0dd5209 6298 Make_Indexed_Component (Loc,
6782b1ef 6299 Prefix =>
d0dd5209 6300 Make_Selected_Component (Loc,
6782b1ef 6301 Prefix => New_Occurrence_Of (TSD, Loc),
d0dd5209 6302 Selector_Name =>
e4494292 6303 New_Occurrence_Of
d0dd5209
JM
6304 (RTE_Record_Component (RE_Tags_Table), Loc)),
6305 Expressions =>
6306 New_List (Make_Integer_Literal (Loc, 0))),
6307
6308 Expression =>
e4494292 6309 New_Occurrence_Of
d0dd5209
JM
6310 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)));
6311 end if;
6312
b16d9747
JM
6313 -- Inherit the dispatch tables of the parent. There is no need to
6314 -- inherit anything from the parent when building static dispatch tables
6315 -- because the whole dispatch table (including inherited primitives) has
6316 -- been already built.
1923d2d6 6317
bfae1846 6318 if Building_Static_DT (Typ) then
d0dd5209
JM
6319 null;
6320
bfef8d0d
JM
6321 -- If the ancestor is a CPP_Class type we inherit the dispatch tables
6322 -- in the init proc, and we don't need to fill them in here.
10b93b2e 6323
f2cbd970 6324 elsif Is_CPP_Class (Parent_Typ) then
bfef8d0d 6325 null;
10b93b2e 6326
1923d2d6 6327 -- Otherwise we fill in the dispatch tables here
10b93b2e 6328
bfef8d0d 6329 else
f2cbd970 6330 if Typ /= Parent_Typ
bfef8d0d
JM
6331 and then not Is_Interface (Typ)
6332 and then not Restriction_Active (No_Dispatching_Calls)
b0efe69e 6333 then
dee4682a 6334 -- Inherit the dispatch table
10b93b2e 6335
1923d2d6 6336 if not Is_Interface (Typ)
f2cbd970
JM
6337 and then not Is_Interface (Parent_Typ)
6338 and then not Is_CPP_Class (Parent_Typ)
1923d2d6
JM
6339 then
6340 declare
6341 Nb_Prims : constant Int :=
6342 UI_To_Int (DT_Entry_Count
f2cbd970
JM
6343 (First_Tag_Component (Parent_Typ)));
6344
1923d2d6
JM
6345 begin
6346 Append_To (Elab_Code,
6347 Build_Inherit_Predefined_Prims (Loc,
6348 Old_Tag_Node =>
e4494292 6349 New_Occurrence_Of
1923d2d6 6350 (Node
6782b1ef
AC
6351 (Next_Elmt
6352 (First_Elmt
6353 (Access_Disp_Table (Parent_Typ)))), Loc),
1923d2d6 6354 New_Tag_Node =>
e4494292 6355 New_Occurrence_Of
1923d2d6 6356 (Node
6782b1ef
AC
6357 (Next_Elmt
6358 (First_Elmt
bd5ed03a
JM
6359 (Access_Disp_Table (Typ)))), Loc),
6360 Num_Predef_Prims =>
6361 Number_Of_Predefined_Prims (Parent_Typ)));
1923d2d6
JM
6362
6363 if Nb_Prims /= 0 then
d0dd5209 6364 Append_To (Elab_Code,
1923d2d6
JM
6365 Build_Inherit_Prims (Loc,
6366 Typ => Typ,
6367 Old_Tag_Node =>
e4494292 6368 New_Occurrence_Of
1923d2d6 6369 (Node
6782b1ef
AC
6370 (First_Elmt
6371 (Access_Disp_Table (Parent_Typ))), Loc),
e4494292 6372 New_Tag_Node => New_Occurrence_Of (DT_Ptr, Loc),
1923d2d6
JM
6373 Num_Prims => Nb_Prims));
6374 end if;
6375 end;
bfef8d0d 6376 end if;
10b93b2e 6377
bfef8d0d 6378 -- Inherit the secondary dispatch tables of the ancestor
10b93b2e 6379
f2cbd970 6380 if not Is_CPP_Class (Parent_Typ) then
bfef8d0d
JM
6381 declare
6382 Sec_DT_Ancestor : Elmt_Id :=
6383 Next_Elmt
6782b1ef
AC
6384 (Next_Elmt
6385 (First_Elmt
6386 (Access_Disp_Table
6387 (Parent_Typ))));
bfef8d0d
JM
6388 Sec_DT_Typ : Elmt_Id :=
6389 Next_Elmt
6782b1ef
AC
6390 (Next_Elmt
6391 (First_Elmt
6392 (Access_Disp_Table (Typ))));
bfef8d0d
JM
6393
6394 procedure Copy_Secondary_DTs (Typ : Entity_Id);
6395 -- Local procedure required to climb through the ancestors
6396 -- and copy the contents of all their secondary dispatch
6397 -- tables.
6398
6399 ------------------------
6400 -- Copy_Secondary_DTs --
6401 ------------------------
6402
6403 procedure Copy_Secondary_DTs (Typ : Entity_Id) is
6404 E : Entity_Id;
6405 Iface : Elmt_Id;
6406
6407 begin
6408 -- Climb to the ancestor (if any) handling private types
6409
6410 if Present (Full_View (Etype (Typ))) then
6411 if Full_View (Etype (Typ)) /= Typ then
6412 Copy_Secondary_DTs (Full_View (Etype (Typ)));
6413 end if;
10b93b2e 6414
bfef8d0d
JM
6415 elsif Etype (Typ) /= Typ then
6416 Copy_Secondary_DTs (Etype (Typ));
6417 end if;
10b93b2e 6418
ce2b6ba5
JM
6419 if Present (Interfaces (Typ))
6420 and then not Is_Empty_Elmt_List (Interfaces (Typ))
bfef8d0d 6421 then
ce2b6ba5 6422 Iface := First_Elmt (Interfaces (Typ));
bfef8d0d
JM
6423 E := First_Entity (Typ);
6424 while Present (E)
6425 and then Present (Node (Sec_DT_Ancestor))
d0dd5209 6426 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
bfef8d0d
JM
6427 loop
6428 if Is_Tag (E) and then Chars (E) /= Name_uTag then
80b992ae
HK
6429 declare
6430 Num_Prims : constant Int :=
6431 UI_To_Int (DT_Entry_Count (E));
6432
6433 begin
6434 if not Is_Interface (Etype (Typ)) then
6435
6436 -- Inherit first secondary dispatch table
6437
6438 Append_To (Elab_Code,
6439 Build_Inherit_Predefined_Prims (Loc,
6440 Old_Tag_Node =>
6441 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 6442 New_Occurrence_Of
1923d2d6
JM
6443 (Node
6444 (Next_Elmt (Sec_DT_Ancestor)),
6445 Loc)),
80b992ae
HK
6446 New_Tag_Node =>
6447 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 6448 New_Occurrence_Of
1923d2d6 6449 (Node (Next_Elmt (Sec_DT_Typ)),
bd5ed03a
JM
6450 Loc)),
6451 Num_Predef_Prims =>
6452 Number_Of_Predefined_Prims
6453 (Parent_Typ)));
80b992ae
HK
6454
6455 if Num_Prims /= 0 then
6456 Append_To (Elab_Code,
6457 Build_Inherit_Prims (Loc,
6458 Typ => Node (Iface),
6459 Old_Tag_Node =>
6460 Unchecked_Convert_To
6461 (RTE (RE_Tag),
e4494292 6462 New_Occurrence_Of
80b992ae
HK
6463 (Node (Sec_DT_Ancestor),
6464 Loc)),
6465 New_Tag_Node =>
6466 Unchecked_Convert_To
6467 (RTE (RE_Tag),
e4494292 6468 New_Occurrence_Of
80b992ae
HK
6469 (Node (Sec_DT_Typ), Loc)),
6470 Num_Prims => Num_Prims));
6471 end if;
6472 end if;
6473
6474 Next_Elmt (Sec_DT_Ancestor);
6475 Next_Elmt (Sec_DT_Typ);
dee4682a 6476
1923d2d6
JM
6477 -- Skip the secondary dispatch table of
6478 -- predefined primitives
6479
6480 Next_Elmt (Sec_DT_Ancestor);
6481 Next_Elmt (Sec_DT_Typ);
6482
80b992ae
HK
6483 if not Is_Interface (Etype (Typ)) then
6484
6485 -- Inherit second secondary dispatch table
dee4682a 6486
dee4682a
JM
6487 Append_To (Elab_Code,
6488 Build_Inherit_Predefined_Prims (Loc,
6489 Old_Tag_Node =>
6490 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 6491 New_Occurrence_Of
1923d2d6
JM
6492 (Node
6493 (Next_Elmt (Sec_DT_Ancestor)),
6494 Loc)),
dee4682a
JM
6495 New_Tag_Node =>
6496 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 6497 New_Occurrence_Of
1923d2d6 6498 (Node (Next_Elmt (Sec_DT_Typ)),
bd5ed03a
JM
6499 Loc)),
6500 Num_Predef_Prims =>
6501 Number_Of_Predefined_Prims
6502 (Parent_Typ)));
dee4682a
JM
6503
6504 if Num_Prims /= 0 then
6505 Append_To (Elab_Code,
6506 Build_Inherit_Prims (Loc,
b2e1beb3 6507 Typ => Node (Iface),
dee4682a
JM
6508 Old_Tag_Node =>
6509 Unchecked_Convert_To
6510 (RTE (RE_Tag),
e4494292 6511 New_Occurrence_Of
dee4682a
JM
6512 (Node (Sec_DT_Ancestor),
6513 Loc)),
6514 New_Tag_Node =>
6515 Unchecked_Convert_To
6516 (RTE (RE_Tag),
e4494292 6517 New_Occurrence_Of
dee4682a 6518 (Node (Sec_DT_Typ), Loc)),
b2e1beb3 6519 Num_Prims => Num_Prims));
dee4682a 6520 end if;
80b992ae
HK
6521 end if;
6522 end;
bfef8d0d
JM
6523
6524 Next_Elmt (Sec_DT_Ancestor);
6525 Next_Elmt (Sec_DT_Typ);
1923d2d6
JM
6526
6527 -- Skip the secondary dispatch table of
6528 -- predefined primitives
6529
6530 Next_Elmt (Sec_DT_Ancestor);
6531 Next_Elmt (Sec_DT_Typ);
6532
bfef8d0d
JM
6533 Next_Elmt (Iface);
6534 end if;
10b93b2e 6535
bfef8d0d
JM
6536 Next_Entity (E);
6537 end loop;
6538 end if;
6539 end Copy_Secondary_DTs;
10b93b2e 6540
bfef8d0d 6541 begin
d0dd5209
JM
6542 if Present (Node (Sec_DT_Ancestor))
6543 and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
6544 then
bfef8d0d 6545 -- Handle private types
f4d379b8 6546
bfef8d0d
JM
6547 if Present (Full_View (Typ)) then
6548 Copy_Secondary_DTs (Full_View (Typ));
6549 else
6550 Copy_Secondary_DTs (Typ);
6551 end if;
f4d379b8 6552 end if;
bfef8d0d
JM
6553 end;
6554 end if;
f4d379b8 6555 end if;
dee4682a 6556 end if;
10b93b2e 6557
36295779
AC
6558 -- Generate code to check if the external tag of this type is the same
6559 -- as the external tag of some other declaration.
8c4ee6f5
AC
6560
6561 -- Check_TSD (TSD'Unrestricted_Access);
6562
e526d0c7
AC
6563 -- This check is a consequence of AI05-0113-1/06, so it officially
6564 -- applies to Ada 2005 (and Ada 2012). It might be argued that it is
6565 -- a desirable check to add in Ada 95 mode, but we hesitate to make
6566 -- this change, as it would be incompatible, and could conceivably
51ab2a39 6567 -- cause a problem in existing Ada 95 code.
e526d0c7
AC
6568
6569 -- We check for No_Run_Time_Mode here, because we do not want to pick
6570 -- up the RE_Check_TSD entity and call it in No_Run_Time mode.
5ad4969d 6571
b00baef5
JM
6572 -- We cannot perform this check if the generation of its expanded name
6573 -- was discarded.
6574
8c4ee6f5 6575 if not No_Run_Time_Mode
51ab2a39 6576 and then not Discard_Names
e526d0c7 6577 and then Ada_Version >= Ada_2005
8c4ee6f5 6578 and then RTE_Available (RE_Check_TSD)
59f4d038 6579 and then not Duplicated_Tag_Checks_Suppressed (Typ)
8c4ee6f5
AC
6580 then
6581 Append_To (Elab_Code,
6582 Make_Procedure_Call_Statement (Loc,
36295779
AC
6583 Name =>
6584 New_Occurrence_Of (RTE (RE_Check_TSD), Loc),
8c4ee6f5
AC
6585 Parameter_Associations => New_List (
6586 Make_Attribute_Reference (Loc,
36295779 6587 Prefix => New_Occurrence_Of (TSD, Loc),
8c4ee6f5
AC
6588 Attribute_Name => Name_Unchecked_Access))));
6589 end if;
6590
dee4682a
JM
6591 -- Generate code to register the Tag in the External_Tag hash table for
6592 -- the pure Ada type only.
10b93b2e 6593
dee4682a 6594 -- Register_Tag (Dt_Ptr);
10b93b2e 6595
d0dd5209
JM
6596 -- Skip this action in the following cases:
6597 -- 1) if Register_Tag is not available.
6598 -- 2) in No_Run_Time mode.
5b7dd52d 6599 -- 3) if Typ is not defined at the library level (this is required
d0dd5209
JM
6600 -- to avoid adding concurrency control to the hash table used
6601 -- by the run-time to register the tags).
10b93b2e 6602
80b992ae
HK
6603 if not No_Run_Time_Mode
6604 and then Is_Library_Level_Entity (Typ)
6605 and then RTE_Available (RE_Register_Tag)
6606 then
d0dd5209 6607 Append_To (Elab_Code,
80b992ae 6608 Make_Procedure_Call_Statement (Loc,
6782b1ef
AC
6609 Name =>
6610 New_Occurrence_Of (RTE (RE_Register_Tag), Loc),
80b992ae 6611 Parameter_Associations =>
e4494292 6612 New_List (New_Occurrence_Of (DT_Ptr, Loc))));
10b93b2e
HK
6613 end if;
6614
5b7dd52d
JM
6615 if not Is_Empty_List (Elab_Code) then
6616 Append_List_To (Result, Elab_Code);
6617 end if;
80b992ae 6618
c09a557e
AC
6619 -- Populate the two auxiliary tables used for dispatching asynchronous,
6620 -- conditional and timed selects for synchronized types that implement
6621 -- a limited interface. Skip this step in Ravenscar profile or when
6622 -- general dispatching is forbidden.
b2e1beb3 6623
0791fbe9 6624 if Ada_Version >= Ada_2005
b2e1beb3 6625 and then Is_Concurrent_Record_Type (Typ)
ce2b6ba5 6626 and then Has_Interfaces (Typ)
c09a557e
AC
6627 and then not Restriction_Active (No_Dispatching_Calls)
6628 and then not Restriction_Active (No_Select_Statements)
b2e1beb3
ES
6629 then
6630 Append_List_To (Result,
6631 Make_Select_Specific_Data_Table (Typ));
6632 end if;
6633
f2cbd970 6634 -- Remember entities containing dispatch tables
1923d2d6 6635
f2cbd970
JM
6636 Append_Elmt (Predef_Prims, DT_Decl);
6637 Append_Elmt (DT, DT_Decl);
1923d2d6 6638
d0dd5209 6639 Analyze_List (Result, Suppress => All_Checks);
b2e1beb3
ES
6640 Set_Has_Dispatch_Table (Typ);
6641
b16d9747
JM
6642 -- Mark entities containing dispatch tables. Required by the backend to
6643 -- handle them properly.
f2cbd970 6644
87dc09cb 6645 if Has_DT (Typ) then
f2cbd970
JM
6646 declare
6647 Elmt : Elmt_Id;
6648
6649 begin
f2cbd970
JM
6650 -- Object declarations
6651
6652 Elmt := First_Elmt (DT_Decl);
6653 while Present (Elmt) loop
6654 Set_Is_Dispatch_Table_Entity (Node (Elmt));
6655 pragma Assert (Ekind (Etype (Node (Elmt))) = E_Array_Subtype
6656 or else Ekind (Etype (Node (Elmt))) = E_Record_Subtype);
6657 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
6658 Next_Elmt (Elmt);
6659 end loop;
6660
6661 -- Aggregates initializing dispatch tables
6662
6663 Elmt := First_Elmt (DT_Aggr);
6664 while Present (Elmt) loop
6665 Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
6666 Next_Elmt (Elmt);
6667 end loop;
6668 end;
6669 end if;
6670
d65a80fd 6671 <<Leave_SCIL>>
078b1a5f 6672
9c41193c
JM
6673 -- Register the tagged type in the call graph nodes table
6674
6675 Register_CG_Node (Typ);
6676
d65a80fd 6677 <<Leave>>
9057bd6a 6678 Restore_Ghost_Region (Saved_GM, Saved_IGR);
d65a80fd 6679
f4d379b8
HK
6680 return Result;
6681 end Make_DT;
10b93b2e 6682
f4d379b8
HK
6683 -------------------------------------
6684 -- Make_Select_Specific_Data_Table --
6685 -------------------------------------
10b93b2e 6686
f4d379b8
HK
6687 function Make_Select_Specific_Data_Table
6688 (Typ : Entity_Id) return List_Id
6689 is
6690 Assignments : constant List_Id := New_List;
6691 Loc : constant Source_Ptr := Sloc (Typ);
10b93b2e 6692
b0efe69e 6693 Conc_Typ : Entity_Id;
1f8766d3 6694 Decls : List_Id := No_List;
b0efe69e
JM
6695 Prim : Entity_Id;
6696 Prim_Als : Entity_Id;
6697 Prim_Elmt : Elmt_Id;
6698 Prim_Pos : Uint;
dee4682a 6699 Nb_Prim : Nat := 0;
10b93b2e 6700
f4d379b8 6701 type Examined_Array is array (Int range <>) of Boolean;
10b93b2e 6702
f4d379b8
HK
6703 function Find_Entry_Index (E : Entity_Id) return Uint;
6704 -- Given an entry, find its index in the visible declarations of the
6705 -- corresponding concurrent type of Typ.
10b93b2e 6706
f4d379b8
HK
6707 ----------------------
6708 -- Find_Entry_Index --
6709 ----------------------
10b93b2e 6710
f4d379b8 6711 function Find_Entry_Index (E : Entity_Id) return Uint is
7faaabcc
PT
6712 Index : Uint := Uint_0;
6713 Subp_Decl : Node_Id;
10b93b2e 6714
f4d379b8 6715 begin
7faaabcc
PT
6716 Subp_Decl := First (Decls);
6717 while Present (Subp_Decl) loop
6718 if Nkind (Subp_Decl) = N_Entry_Declaration then
6719 Index := Index + 1;
10b93b2e 6720
7faaabcc
PT
6721 if Defining_Identifier (Subp_Decl) = E then
6722 exit;
f4d379b8 6723 end if;
10b93b2e 6724
7faaabcc
PT
6725 end if;
6726
6727 Next (Subp_Decl);
6728 end loop;
10b93b2e 6729
7faaabcc 6730 return Index;
f4d379b8
HK
6731 end Find_Entry_Index;
6732
e8374e7a
AC
6733 -- Local variables
6734
6735 Tag_Node : Node_Id;
6736
f4d379b8
HK
6737 -- Start of processing for Make_Select_Specific_Data_Table
6738
6739 begin
b0efe69e
JM
6740 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
6741
f4d379b8
HK
6742 if Present (Corresponding_Concurrent_Type (Typ)) then
6743 Conc_Typ := Corresponding_Concurrent_Type (Typ);
6744
b2e1beb3
ES
6745 if Present (Full_View (Conc_Typ)) then
6746 Conc_Typ := Full_View (Conc_Typ);
6747 end if;
6748
f4d379b8
HK
6749 if Ekind (Conc_Typ) = E_Protected_Type then
6750 Decls := Visible_Declarations (Protected_Definition (
6751 Parent (Conc_Typ)));
10b93b2e
HK
6752 else
6753 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
f4d379b8
HK
6754 Decls := Visible_Declarations (Task_Definition (
6755 Parent (Conc_Typ)));
6756 end if;
6757 end if;
10b93b2e 6758
f4d379b8 6759 -- Count the non-predefined primitive operations
10b93b2e 6760
f4d379b8
HK
6761 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6762 while Present (Prim_Elmt) loop
bfef8d0d
JM
6763 Prim := Node (Prim_Elmt);
6764
6765 if not (Is_Predefined_Dispatching_Operation (Prim)
6766 or else Is_Predefined_Dispatching_Alias (Prim))
6767 then
f4d379b8
HK
6768 Nb_Prim := Nb_Prim + 1;
6769 end if;
10b93b2e 6770
f4d379b8
HK
6771 Next_Elmt (Prim_Elmt);
6772 end loop;
10b93b2e 6773
f4d379b8 6774 declare
b0efe69e 6775 Examined : Examined_Array (1 .. Nb_Prim) := (others => False);
10b93b2e 6776
f4d379b8
HK
6777 begin
6778 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6779 while Present (Prim_Elmt) loop
6780 Prim := Node (Prim_Elmt);
10b93b2e 6781
bfef8d0d 6782 -- Look for primitive overriding an abstract interface subprogram
10b93b2e 6783
ce2b6ba5 6784 if Present (Interface_Alias (Prim))
b4d7b435
AC
6785 and then not
6786 Is_Ancestor
4ac2477e
JM
6787 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ,
6788 Use_Full_View => True)
bfef8d0d
JM
6789 and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
6790 then
6791 Prim_Pos := DT_Position (Alias (Prim));
6792 pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
6793 Examined (UI_To_Int (Prim_Pos)) := True;
10b93b2e 6794
bfef8d0d
JM
6795 -- Set the primitive operation kind regardless of subprogram
6796 -- type. Generate:
6797 -- Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);
10b93b2e 6798
e8374e7a
AC
6799 if Tagged_Type_Expansion then
6800 Tag_Node :=
e4494292 6801 New_Occurrence_Of
e8374e7a
AC
6802 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc);
6803
6804 else
6805 Tag_Node :=
6806 Make_Attribute_Reference (Loc,
e4494292 6807 Prefix => New_Occurrence_Of (Typ, Loc),
e8374e7a
AC
6808 Attribute_Name => Name_Tag);
6809 end if;
6810
bfef8d0d 6811 Append_To (Assignments,
d0dd5209 6812 Make_Procedure_Call_Statement (Loc,
e4494292 6813 Name => New_Occurrence_Of (RTE (RE_Set_Prim_Op_Kind), Loc),
d0dd5209 6814 Parameter_Associations => New_List (
e8374e7a 6815 Tag_Node,
d0dd5209
JM
6816 Make_Integer_Literal (Loc, Prim_Pos),
6817 Prim_Op_Kind (Alias (Prim), Typ))));
b0efe69e 6818
bfef8d0d 6819 -- Retrieve the root of the alias chain
b0efe69e 6820
b81a5940 6821 Prim_Als := Ultimate_Alias (Prim);
b0efe69e 6822
bfef8d0d 6823 -- In the case of an entry wrapper, set the entry index
b0efe69e 6824
bfef8d0d
JM
6825 if Ekind (Prim) = E_Procedure
6826 and then Is_Primitive_Wrapper (Prim_Als)
6827 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
6828 then
6829 -- Generate:
6830 -- Ada.Tags.Set_Entry_Index
6831 -- (DT_Ptr, <position>, <index>);
b0efe69e 6832
e8374e7a
AC
6833 if Tagged_Type_Expansion then
6834 Tag_Node :=
e4494292 6835 New_Occurrence_Of
7b9db926 6836 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc);
e8374e7a
AC
6837 else
6838 Tag_Node :=
6839 Make_Attribute_Reference (Loc,
e4494292 6840 Prefix => New_Occurrence_Of (Typ, Loc),
e8374e7a
AC
6841 Attribute_Name => Name_Tag);
6842 end if;
6843
bfef8d0d 6844 Append_To (Assignments,
d0dd5209
JM
6845 Make_Procedure_Call_Statement (Loc,
6846 Name =>
e4494292 6847 New_Occurrence_Of (RTE (RE_Set_Entry_Index), Loc),
d0dd5209 6848 Parameter_Associations => New_List (
e8374e7a 6849 Tag_Node,
d0dd5209
JM
6850 Make_Integer_Literal (Loc, Prim_Pos),
6851 Make_Integer_Literal (Loc,
6852 Find_Entry_Index (Wrapped_Entity (Prim_Als))))));
f4d379b8
HK
6853 end if;
6854 end if;
6855
f4d379b8
HK
6856 Next_Elmt (Prim_Elmt);
6857 end loop;
6858 end;
6859
6860 return Assignments;
6861 end Make_Select_Specific_Data_Table;
10b93b2e 6862
b2e1beb3
ES
6863 ---------------
6864 -- Make_Tags --
6865 ---------------
6866
6867 function Make_Tags (Typ : Entity_Id) return List_Id is
b16d9747
JM
6868 Loc : constant Source_Ptr := Sloc (Typ);
6869 Result : constant List_Id := New_List;
6870
6871 procedure Import_DT
6872 (Tag_Typ : Entity_Id;
6873 DT : Entity_Id;
6874 Is_Secondary_DT : Boolean);
6875 -- Import the dispatch table DT of tagged type Tag_Typ. Required to
6876 -- generate forward references and statically allocate the table. For
6877 -- primary dispatch tables that require no dispatch table generate:
c95e0edc 6878
b16d9747 6879 -- DT : static aliased constant Non_Dispatch_Table_Wrapper;
c95e0edc
AC
6880 -- pragma Import (Ada, DT);
6881
b16d9747 6882 -- Otherwise generate:
c95e0edc 6883
b16d9747 6884 -- DT : static aliased constant Dispatch_Table_Wrapper (Nb_Prim);
c95e0edc 6885 -- pragma Import (Ada, DT);
7986e000 6886
b16d9747
JM
6887 ---------------
6888 -- Import_DT --
6889 ---------------
e18d6a15 6890
b16d9747
JM
6891 procedure Import_DT
6892 (Tag_Typ : Entity_Id;
6893 DT : Entity_Id;
6894 Is_Secondary_DT : Boolean)
6895 is
6896 DT_Constr_List : List_Id;
6897 Nb_Prim : Nat;
e18d6a15 6898
b16d9747
JM
6899 begin
6900 Set_Is_Imported (DT);
6901 Set_Ekind (DT, E_Constant);
6902 Set_Related_Type (DT, Typ);
e18d6a15 6903
e18d6a15
JM
6904 -- The scope must be set now to call Get_External_Name
6905
6906 Set_Scope (DT, Current_Scope);
6907
93582885 6908 Get_External_Name (DT);
e18d6a15 6909 Set_Interface_Name (DT,
c95e0edc 6910 Make_String_Literal (Loc, Strval => String_From_Name_Buffer));
b2e1beb3 6911
e18d6a15 6912 -- Ensure proper Sprint output of this implicit importation
b2e1beb3 6913
e18d6a15 6914 Set_Is_Internal (DT);
b2e1beb3 6915
e18d6a15
JM
6916 -- Save this entity to allow Make_DT to generate its exportation
6917
b16d9747 6918 Append_Elmt (DT, Dispatch_Table_Wrappers (Typ));
e18d6a15 6919
b16d9747 6920 -- No dispatch table required
1923d2d6 6921
c95e0edc 6922 if not Is_Secondary_DT and then not Has_DT (Tag_Typ) then
b16d9747
JM
6923 Append_To (Result,
6924 Make_Object_Declaration (Loc,
6925 Defining_Identifier => DT,
6926 Aliased_Present => True,
6927 Constant_Present => True,
6928 Object_Definition =>
e4494292
RD
6929 New_Occurrence_Of
6930 (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));
b16d9747
JM
6931
6932 else
e18d6a15
JM
6933 -- Calculate the number of primitives of the dispatch table and
6934 -- the size of the Type_Specific_Data record.
6935
b16d9747
JM
6936 Nb_Prim :=
6937 UI_To_Int (DT_Entry_Count (First_Tag_Component (Tag_Typ)));
e18d6a15 6938
c95e0edc
AC
6939 -- If the tagged type has no primitives we add a dummy slot whose
6940 -- address will be the tag of this type.
e18d6a15
JM
6941
6942 if Nb_Prim = 0 then
6943 DT_Constr_List :=
6944 New_List (Make_Integer_Literal (Loc, 1));
6945 else
6946 DT_Constr_List :=
6947 New_List (Make_Integer_Literal (Loc, Nb_Prim));
6948 end if;
6949
6950 Append_To (Result,
6951 Make_Object_Declaration (Loc,
6952 Defining_Identifier => DT,
6953 Aliased_Present => True,
6954 Constant_Present => True,
6955 Object_Definition =>
6956 Make_Subtype_Indication (Loc,
6957 Subtype_Mark =>
e4494292 6958 New_Occurrence_Of (RTE (RE_Dispatch_Table_Wrapper), Loc),
e18d6a15
JM
6959 Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
6960 Constraints => DT_Constr_List))));
b16d9747
JM
6961 end if;
6962 end Import_DT;
6963
6964 -- Local variables
6965
6966 Tname : constant Name_Id := Chars (Typ);
6967 AI_Tag_Comp : Elmt_Id;
901ad63f 6968 DT : Node_Id := Empty;
b16d9747
JM
6969 DT_Ptr : Node_Id;
6970 Predef_Prims_Ptr : Node_Id;
c679a915 6971 Iface_DT : Node_Id := Empty;
b16d9747 6972 Iface_DT_Ptr : Node_Id;
327503f1 6973 New_Node : Node_Id;
b16d9747
JM
6974 Suffix_Index : Int;
6975 Typ_Name : Name_Id;
6976 Typ_Comps : Elist_Id;
6977
6978 -- Start of processing for Make_Tags
6979
6980 begin
cefce34c
JM
6981 pragma Assert (No (Access_Disp_Table (Typ)));
6982 Set_Access_Disp_Table (Typ, New_Elmt_List);
b16d9747 6983
fe683ef6
AC
6984 -- If the elaboration of this tagged type needs a boolean flag then
6985 -- define now its entity. It is initialized to True to indicate that
6986 -- elaboration is still pending; set to False by the IP routine.
6987
6988 -- TypFxx : boolean := True;
6989
6990 if Elab_Flag_Needed (Typ) then
6991 Set_Access_Disp_Table_Elab_Flag (Typ,
6992 Make_Defining_Identifier (Loc,
ed323421 6993 Chars => New_External_Name (Tname, 'F')));
fe683ef6
AC
6994
6995 Append_To (Result,
6996 Make_Object_Declaration (Loc,
6997 Defining_Identifier => Access_Disp_Table_Elab_Flag (Typ),
6998 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
6999 Expression => New_Occurrence_Of (Standard_True, Loc)));
7000 end if;
7001
b16d9747
JM
7002 -- 1) Generate the primary tag entities
7003
7004 -- Primary dispatch table containing user-defined primitives
7005
cefce34c
JM
7006 DT_Ptr := Make_Defining_Identifier (Loc, New_External_Name (Tname, 'P'));
7007 Set_Etype (DT_Ptr, RTE (RE_Tag));
7008 Append_Elmt (DT_Ptr, Access_Disp_Table (Typ));
b16d9747 7009
cefce34c 7010 -- Minimum decoration
b16d9747 7011
cefce34c
JM
7012 Set_Ekind (DT_Ptr, E_Variable);
7013 Set_Related_Type (DT_Ptr, Typ);
b16d9747 7014
6782b1ef 7015 -- Notify back end that the types are associated with a dispatch table
e3b3266c
AC
7016
7017 Set_Is_Dispatch_Table_Entity (RTE (RE_Prim_Ptr));
7018 Set_Is_Dispatch_Table_Entity (RTE (RE_Predef_Prims_Table_Ptr));
7019
cefce34c 7020 -- For CPP types there is no need to build the dispatch tables since
a8cc3e46
RD
7021 -- they are imported from the C++ side. If the CPP type has an IP then
7022 -- we declare now the variable that will store the copy of the C++ tag.
c95e0edc
AC
7023 -- If the CPP type is an interface, we need the variable as well because
7024 -- it becomes the pointer to the corresponding secondary table.
b16d9747 7025
cefce34c 7026 if Is_CPP_Class (Typ) then
a8cc3e46 7027 if Has_CPP_Constructors (Typ) or else Is_Interface (Typ) then
e18d6a15
JM
7028 Append_To (Result,
7029 Make_Object_Declaration (Loc,
7030 Defining_Identifier => DT_Ptr,
e4494292 7031 Object_Definition => New_Occurrence_Of (RTE (RE_Tag), Loc),
e18d6a15
JM
7032 Expression =>
7033 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 7034 New_Occurrence_Of (RTE (RE_Null_Address), Loc))));
e18d6a15 7035
cefce34c
JM
7036 Set_Is_Statically_Allocated (DT_Ptr,
7037 Is_Library_Level_Tagged_Type (Typ));
7038 end if;
97cb64f0 7039
cefce34c 7040 -- Ada types
81d93365 7041
cefce34c
JM
7042 else
7043 -- Primary dispatch table containing predefined primitives
1923d2d6 7044
cefce34c
JM
7045 Predef_Prims_Ptr :=
7046 Make_Defining_Identifier (Loc,
7047 Chars => New_External_Name (Tname, 'Y'));
7048 Set_Etype (Predef_Prims_Ptr, RTE (RE_Address));
7049 Append_Elmt (Predef_Prims_Ptr, Access_Disp_Table (Typ));
e18d6a15 7050
cefce34c 7051 -- Import the forward declaration of the Dispatch Table wrapper
c95e0edc 7052 -- record (Make_DT will take care of exporting it).
e18d6a15 7053
cefce34c
JM
7054 if Building_Static_DT (Typ) then
7055 Set_Dispatch_Table_Wrappers (Typ, New_Elmt_List);
b2e1beb3 7056
cefce34c
JM
7057 DT :=
7058 Make_Defining_Identifier (Loc,
7059 Chars => New_External_Name (Tname, 'T'));
7060
7061 Import_DT (Typ, DT, Is_Secondary_DT => False);
7062
7063 if Has_DT (Typ) then
7064 Append_To (Result,
7065 Make_Object_Declaration (Loc,
7066 Defining_Identifier => DT_Ptr,
7067 Constant_Present => True,
e4494292
RD
7068 Object_Definition =>
7069 New_Occurrence_Of (RTE (RE_Tag), Loc),
cf7bb903 7070 Expression =>
cefce34c
JM
7071 Unchecked_Convert_To (RTE (RE_Tag),
7072 Make_Attribute_Reference (Loc,
cf7bb903 7073 Prefix =>
cefce34c 7074 Make_Selected_Component (Loc,
e4494292 7075 Prefix => New_Occurrence_Of (DT, Loc),
cf7bb903
RD
7076 Selector_Name =>
7077 New_Occurrence_Of
7078 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
cefce34c
JM
7079 Attribute_Name => Name_Address))));
7080
7081 -- Generate the SCIL node for the previous object declaration
7082 -- because it has a tag initialization.
7083
7084 if Generate_SCIL then
7085 New_Node :=
7086 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
7087 Set_SCIL_Entity (New_Node, Typ);
7088 Set_SCIL_Node (Last (Result), New_Node);
7089 end if;
7090
7091 Append_To (Result,
7092 Make_Object_Declaration (Loc,
7093 Defining_Identifier => Predef_Prims_Ptr,
7094 Constant_Present => True,
cf7bb903 7095 Object_Definition =>
e4494292 7096 New_Occurrence_Of (RTE (RE_Address), Loc),
cf7bb903 7097 Expression =>
cefce34c 7098 Make_Attribute_Reference (Loc,
cf7bb903 7099 Prefix =>
cefce34c 7100 Make_Selected_Component (Loc,
e4494292 7101 Prefix => New_Occurrence_Of (DT, Loc),
cf7bb903
RD
7102 Selector_Name =>
7103 New_Occurrence_Of
7104 (RTE_Record_Component (RE_Predef_Prims), Loc)),
cefce34c
JM
7105 Attribute_Name => Name_Address)));
7106
7107 -- No dispatch table required
7108
7109 else
7110 Append_To (Result,
7111 Make_Object_Declaration (Loc,
7112 Defining_Identifier => DT_Ptr,
7113 Constant_Present => True,
e4494292
RD
7114 Object_Definition =>
7115 New_Occurrence_Of (RTE (RE_Tag), Loc),
cf7bb903 7116 Expression =>
cefce34c
JM
7117 Unchecked_Convert_To (RTE (RE_Tag),
7118 Make_Attribute_Reference (Loc,
cf7bb903 7119 Prefix =>
cefce34c 7120 Make_Selected_Component (Loc,
e4494292 7121 Prefix => New_Occurrence_Of (DT, Loc),
cf7bb903
RD
7122 Selector_Name =>
7123 New_Occurrence_Of
7124 (RTE_Record_Component (RE_NDT_Prims_Ptr),
7125 Loc)),
cefce34c
JM
7126 Attribute_Name => Name_Address))));
7127 end if;
7128
7129 Set_Is_True_Constant (DT_Ptr);
7130 Set_Is_Statically_Allocated (DT_Ptr);
7131 end if;
7132 end if;
b2e1beb3
ES
7133
7134 -- 2) Generate the secondary tag entities
7135
cefce34c
JM
7136 -- Collect the components associated with secondary dispatch tables
7137
ce2b6ba5 7138 if Has_Interfaces (Typ) then
cefce34c 7139 Collect_Interface_Components (Typ, Typ_Comps);
b16d9747 7140
c95e0edc
AC
7141 -- For each interface type we build a unique external name associated
7142 -- with its secondary dispatch table. This name is used to declare an
7143 -- object that references this secondary dispatch table, whose value
7144 -- will be used for the elaboration of Typ objects, and also for the
7145 -- elaboration of objects of types derived from Typ that do not
7146 -- override the primitives of this interface type.
b16d9747
JM
7147
7148 Suffix_Index := 1;
b2e1beb3 7149
6782b1ef
AC
7150 -- Note: The value of Suffix_Index must be in sync with the values of
7151 -- Suffix_Index in secondary dispatch tables generated by Make_DT.
b2e1beb3 7152
cefce34c
JM
7153 if Is_CPP_Class (Typ) then
7154 AI_Tag_Comp := First_Elmt (Typ_Comps);
7155 while Present (AI_Tag_Comp) loop
7156 Get_Secondary_DT_External_Name
7157 (Typ, Related_Type (Node (AI_Tag_Comp)), Suffix_Index);
7158 Typ_Name := Name_Find;
b2e1beb3 7159
6782b1ef 7160 -- Declare variables to store copy of the C++ secondary tags
b16d9747 7161
cefce34c
JM
7162 Iface_DT_Ptr :=
7163 Make_Defining_Identifier (Loc,
7164 Chars => New_External_Name (Typ_Name, 'P'));
7165 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
7166 Set_Ekind (Iface_DT_Ptr, E_Variable);
7167 Set_Is_Tag (Iface_DT_Ptr);
1923d2d6 7168
cefce34c
JM
7169 Set_Has_Thunks (Iface_DT_Ptr);
7170 Set_Related_Type
7171 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7172 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
80b992ae 7173
b16d9747
JM
7174 Append_To (Result,
7175 Make_Object_Declaration (Loc,
7176 Defining_Identifier => Iface_DT_Ptr,
e4494292 7177 Object_Definition => New_Occurrence_Of
b16d9747
JM
7178 (RTE (RE_Interface_Tag), Loc),
7179 Expression =>
7180 Unchecked_Convert_To (RTE (RE_Interface_Tag),
e4494292 7181 New_Occurrence_Of (RTE (RE_Null_Address), Loc))));
b16d9747 7182
cefce34c
JM
7183 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7184 Is_Library_Level_Tagged_Type (Typ));
1923d2d6 7185
cefce34c
JM
7186 Next_Elmt (AI_Tag_Comp);
7187 end loop;
1923d2d6 7188
cefce34c 7189 -- This is not a CPP_Class type
1923d2d6 7190
cefce34c
JM
7191 else
7192 AI_Tag_Comp := First_Elmt (Typ_Comps);
7193 while Present (AI_Tag_Comp) loop
7194 Get_Secondary_DT_External_Name
7195 (Typ, Related_Type (Node (AI_Tag_Comp)), Suffix_Index);
7196 Typ_Name := Name_Find;
b2e1beb3 7197
cefce34c
JM
7198 if Building_Static_DT (Typ) then
7199 Iface_DT :=
7200 Make_Defining_Identifier (Loc,
8d4611f7 7201 Chars => New_External_Name (Typ_Name, 'T'));
cefce34c
JM
7202 Import_DT
7203 (Tag_Typ => Related_Type (Node (AI_Tag_Comp)),
7204 DT => Iface_DT,
7205 Is_Secondary_DT => True);
7206 end if;
1923d2d6 7207
cefce34c
JM
7208 -- Secondary dispatch table referencing thunks to user-defined
7209 -- primitives covered by this interface.
1923d2d6 7210
cefce34c
JM
7211 Iface_DT_Ptr :=
7212 Make_Defining_Identifier (Loc,
7213 Chars => New_External_Name (Typ_Name, 'P'));
7214 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
7215 Set_Ekind (Iface_DT_Ptr, E_Constant);
7216 Set_Is_Tag (Iface_DT_Ptr);
7217 Set_Has_Thunks (Iface_DT_Ptr);
7218 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7219 Is_Library_Level_Tagged_Type (Typ));
7220 Set_Is_True_Constant (Iface_DT_Ptr);
7221 Set_Related_Type
7222 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7223 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
7224
7225 if Building_Static_DT (Typ) then
7226 Append_To (Result,
7227 Make_Object_Declaration (Loc,
7228 Defining_Identifier => Iface_DT_Ptr,
7229 Constant_Present => True,
e4494292 7230 Object_Definition => New_Occurrence_Of
cefce34c 7231 (RTE (RE_Interface_Tag), Loc),
cf7bb903 7232 Expression =>
cefce34c
JM
7233 Unchecked_Convert_To (RTE (RE_Interface_Tag),
7234 Make_Attribute_Reference (Loc,
cf7bb903 7235 Prefix =>
cefce34c 7236 Make_Selected_Component (Loc,
cf7bb903 7237 Prefix =>
e4494292 7238 New_Occurrence_Of (Iface_DT, Loc),
cf7bb903
RD
7239 Selector_Name =>
7240 New_Occurrence_Of
7241 (RTE_Record_Component (RE_Prims_Ptr),
7242 Loc)),
cefce34c
JM
7243 Attribute_Name => Name_Address))));
7244 end if;
7245
7246 -- Secondary dispatch table referencing thunks to predefined
7247 -- primitives.
7248
7249 Iface_DT_Ptr :=
7250 Make_Defining_Identifier (Loc,
7251 Chars => New_External_Name (Typ_Name, 'Y'));
7252 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
7253 Set_Ekind (Iface_DT_Ptr, E_Constant);
7254 Set_Is_Tag (Iface_DT_Ptr);
7255 Set_Has_Thunks (Iface_DT_Ptr);
7256 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7257 Is_Library_Level_Tagged_Type (Typ));
7258 Set_Is_True_Constant (Iface_DT_Ptr);
7259 Set_Related_Type
7260 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7261 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
7262
7263 -- Secondary dispatch table referencing user-defined primitives
7264 -- covered by this interface.
7265
7266 Iface_DT_Ptr :=
7267 Make_Defining_Identifier (Loc,
7268 Chars => New_External_Name (Typ_Name, 'D'));
7269 Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
7270 Set_Ekind (Iface_DT_Ptr, E_Constant);
7271 Set_Is_Tag (Iface_DT_Ptr);
7272 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7273 Is_Library_Level_Tagged_Type (Typ));
7274 Set_Is_True_Constant (Iface_DT_Ptr);
7275 Set_Related_Type
7276 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7277 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
7278
7279 -- Secondary dispatch table referencing predefined primitives
7280
7281 Iface_DT_Ptr :=
7282 Make_Defining_Identifier (Loc,
7283 Chars => New_External_Name (Typ_Name, 'Z'));
7284 Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
7285 Set_Ekind (Iface_DT_Ptr, E_Constant);
7286 Set_Is_Tag (Iface_DT_Ptr);
7287 Set_Is_Statically_Allocated (Iface_DT_Ptr,
7288 Is_Library_Level_Tagged_Type (Typ));
7289 Set_Is_True_Constant (Iface_DT_Ptr);
7290 Set_Related_Type
7291 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
7292 Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));
7293
7294 Next_Elmt (AI_Tag_Comp);
7295 end loop;
7296 end if;
b2e1beb3
ES
7297 end if;
7298
0e41a941
AC
7299 -- 3) At the end of Access_Disp_Table, if the type has user-defined
7300 -- primitives, we add the entity of an access type declaration that
7301 -- is used by Build_Get_Prim_Op_Address to expand dispatching calls
7302 -- through the primary dispatch table.
7303
9c852dfb 7304 if DT_Entry_Count (First_Tag_Component (Typ)) = 0 then
0e41a941 7305 Analyze_List (Result);
b2e1beb3
ES
7306
7307 -- Generate:
02fd37f5 7308 -- subtype Typ_DT is Address_Array (1 .. Nb_Prims);
b2e1beb3
ES
7309 -- type Typ_DT_Acc is access Typ_DT;
7310
0e41a941
AC
7311 else
7312 declare
7313 Name_DT_Prims : constant Name_Id :=
7314 New_External_Name (Tname, 'G');
7315 Name_DT_Prims_Acc : constant Name_Id :=
7316 New_External_Name (Tname, 'H');
7317 DT_Prims : constant Entity_Id :=
7318 Make_Defining_Identifier (Loc,
7319 Name_DT_Prims);
7320 DT_Prims_Acc : constant Entity_Id :=
7321 Make_Defining_Identifier (Loc,
7322 Name_DT_Prims_Acc);
7323 begin
7324 Append_To (Result,
02fd37f5 7325 Make_Subtype_Declaration (Loc,
0e41a941 7326 Defining_Identifier => DT_Prims,
02fd37f5
EB
7327 Subtype_Indication =>
7328 Make_Subtype_Indication (Loc,
7329 Subtype_Mark =>
7330 New_Occurrence_Of (RTE (RE_Address_Array), Loc),
61770974 7331 Constraint =>
02fd37f5
EB
7332 Make_Index_Or_Discriminant_Constraint (Loc, New_List (
7333 Make_Range (Loc,
7334 Low_Bound => Make_Integer_Literal (Loc, 1),
61770974
HK
7335 High_Bound =>
7336 Make_Integer_Literal (Loc,
7337 DT_Entry_Count
7338 (First_Tag_Component (Typ)))))))));
b2e1beb3 7339
0e41a941
AC
7340 Append_To (Result,
7341 Make_Full_Type_Declaration (Loc,
7342 Defining_Identifier => DT_Prims_Acc,
61770974 7343 Type_Definition =>
0e41a941
AC
7344 Make_Access_To_Object_Definition (Loc,
7345 Subtype_Indication =>
7346 New_Occurrence_Of (DT_Prims, Loc))));
b2e1beb3 7347
0e41a941 7348 Append_Elmt (DT_Prims_Acc, Access_Disp_Table (Typ));
b2e1beb3 7349
0e41a941
AC
7350 -- Analyze the resulting list and suppress the generation of the
7351 -- Init_Proc associated with the above array declaration because
7352 -- this type is never used in object declarations. It is only used
7353 -- to simplify the expansion associated with dispatching calls.
b2e1beb3 7354
0e41a941 7355 Analyze_List (Result);
5b1e6aca 7356 Set_Suppress_Initialization (Base_Type (DT_Prims));
f2cbd970 7357
d151d6a3
AC
7358 -- Disable backend optimizations based on assumptions about the
7359 -- aliasing status of objects designated by the access to the
7360 -- dispatch table. Required to handle dispatch tables imported
7361 -- from C++.
7362
7363 Set_No_Strict_Aliasing (Base_Type (DT_Prims_Acc));
7364
cefce34c
JM
7365 -- Add the freezing nodes of these declarations; required to avoid
7366 -- generating these freezing nodes in wrong scopes (for example in
7367 -- the IC routine of a derivation of Typ).
6782b1ef 7368
c95e0edc 7369 -- What is an "IC routine"? Is "init_proc" meant here???
cefce34c 7370
c159409f
AC
7371 Append_List_To (Result, Freeze_Entity (DT_Prims, Typ));
7372 Append_List_To (Result, Freeze_Entity (DT_Prims_Acc, Typ));
cefce34c 7373
0e41a941
AC
7374 -- Mark entity of dispatch table. Required by the back end to
7375 -- handle them properly.
f2cbd970 7376
0e41a941
AC
7377 Set_Is_Dispatch_Table_Entity (DT_Prims);
7378 end;
7379 end if;
b2e1beb3 7380
3c1ecd7e
AC
7381 -- Mark entities of dispatch table. Required by the back end to handle
7382 -- them properly.
901ad63f
EB
7383
7384 if Present (DT) then
7385 Set_Is_Dispatch_Table_Entity (DT);
7386 Set_Is_Dispatch_Table_Entity (Etype (DT));
7387 end if;
7388
c679a915
EB
7389 if Present (Iface_DT) then
7390 Set_Is_Dispatch_Table_Entity (Iface_DT);
7391 Set_Is_Dispatch_Table_Entity (Etype (Iface_DT));
7392 end if;
7393
cefce34c
JM
7394 if Is_CPP_Class (Root_Type (Typ)) then
7395 Set_Ekind (DT_Ptr, E_Variable);
7396 else
7397 Set_Ekind (DT_Ptr, E_Constant);
7398 end if;
7399
80b992ae
HK
7400 Set_Is_Tag (DT_Ptr);
7401 Set_Related_Type (DT_Ptr, Typ);
7402
b2e1beb3
ES
7403 return Result;
7404 end Make_Tags;
7405
5a1ccfb1
AC
7406 ---------------
7407 -- New_Value --
7408 ---------------
7409
7410 function New_Value (From : Node_Id) return Node_Id is
7411 Res : constant Node_Id := Duplicate_Subexpr (From);
7412 begin
7413 if Is_Access_Type (Etype (From)) then
6782b1ef 7414 return Make_Explicit_Dereference (Sloc (From), Prefix => Res);
5a1ccfb1
AC
7415 else
7416 return Res;
7417 end if;
7418 end New_Value;
7419
70482933
RK
7420 -----------------------------------
7421 -- Original_View_In_Visible_Part --
7422 -----------------------------------
7423
7424 function Original_View_In_Visible_Part (Typ : Entity_Id) return Boolean is
7425 Scop : constant Entity_Id := Scope (Typ);
7426
7427 begin
7428 -- The scope must be a package
7429
b9b2405f 7430 if not Is_Package_Or_Generic_Package (Scop) then
70482933
RK
7431 return False;
7432 end if;
7433
7434 -- A type with a private declaration has a private view declared in
7435 -- the visible part.
7436
7437 if Has_Private_Declaration (Typ) then
7438 return True;
7439 end if;
7440
7441 return List_Containing (Parent (Typ)) =
d12b19fa 7442 Visible_Declarations (Package_Specification (Scop));
70482933
RK
7443 end Original_View_In_Visible_Part;
7444
10b93b2e
HK
7445 ------------------
7446 -- Prim_Op_Kind --
7447 ------------------
7448
7449 function Prim_Op_Kind
7450 (Prim : Entity_Id;
7451 Typ : Entity_Id) return Node_Id
7452 is
7453 Full_Typ : Entity_Id := Typ;
7454 Loc : constant Source_Ptr := Sloc (Prim);
b0efe69e 7455 Prim_Op : Entity_Id;
10b93b2e
HK
7456
7457 begin
7458 -- Retrieve the original primitive operation
7459
b81a5940 7460 Prim_Op := Ultimate_Alias (Prim);
10b93b2e
HK
7461
7462 if Ekind (Typ) = E_Record_Type
7463 and then Present (Corresponding_Concurrent_Type (Typ))
7464 then
7465 Full_Typ := Corresponding_Concurrent_Type (Typ);
7466 end if;
7467
2653cbda
HK
7468 -- When a private tagged type is completed by a concurrent type,
7469 -- retrieve the full view.
7470
7471 if Is_Private_Type (Full_Typ) then
7472 Full_Typ := Full_View (Full_Typ);
7473 end if;
7474
10b93b2e
HK
7475 if Ekind (Prim_Op) = E_Function then
7476
7477 -- Protected function
7478
7479 if Ekind (Full_Typ) = E_Protected_Type then
e4494292 7480 return New_Occurrence_Of (RTE (RE_POK_Protected_Function), Loc);
10b93b2e 7481
f4d379b8
HK
7482 -- Task function
7483
7484 elsif Ekind (Full_Typ) = E_Task_Type then
e4494292 7485 return New_Occurrence_Of (RTE (RE_POK_Task_Function), Loc);
f4d379b8 7486
10b93b2e
HK
7487 -- Regular function
7488
7489 else
e4494292 7490 return New_Occurrence_Of (RTE (RE_POK_Function), Loc);
10b93b2e
HK
7491 end if;
7492
7493 else
7494 pragma Assert (Ekind (Prim_Op) = E_Procedure);
7495
7496 if Ekind (Full_Typ) = E_Protected_Type then
7497
7498 -- Protected entry
7499
7500 if Is_Primitive_Wrapper (Prim_Op)
7501 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
7502 then
e4494292 7503 return New_Occurrence_Of (RTE (RE_POK_Protected_Entry), Loc);
10b93b2e
HK
7504
7505 -- Protected procedure
7506
7507 else
e4494292
RD
7508 return
7509 New_Occurrence_Of (RTE (RE_POK_Protected_Procedure), Loc);
10b93b2e
HK
7510 end if;
7511
7512 elsif Ekind (Full_Typ) = E_Task_Type then
7513
7514 -- Task entry
7515
7516 if Is_Primitive_Wrapper (Prim_Op)
7517 and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
7518 then
e4494292 7519 return New_Occurrence_Of (RTE (RE_POK_Task_Entry), Loc);
10b93b2e
HK
7520
7521 -- Task "procedure". These are the internally Expander-generated
7522 -- procedures (task body for instance).
7523
7524 else
e4494292 7525 return New_Occurrence_Of (RTE (RE_POK_Task_Procedure), Loc);
10b93b2e
HK
7526 end if;
7527
7528 -- Regular procedure
7529
7530 else
e4494292 7531 return New_Occurrence_Of (RTE (RE_POK_Procedure), Loc);
10b93b2e
HK
7532 end if;
7533 end if;
7534 end Prim_Op_Kind;
7535
d0dd5209
JM
7536 ------------------------
7537 -- Register_Primitive --
7538 ------------------------
7539
991395ab 7540 function Register_Primitive
d0dd5209 7541 (Loc : Source_Ptr;
991395ab 7542 Prim : Entity_Id) return List_Id
d0dd5209 7543 is
80b992ae
HK
7544 DT_Ptr : Entity_Id;
7545 Iface_Prim : Entity_Id;
7546 Iface_Typ : Entity_Id;
7547 Iface_DT_Ptr : Entity_Id;
7548 Iface_DT_Elmt : Elmt_Id;
991395ab 7549 L : constant List_Id := New_List;
80b992ae
HK
7550 Pos : Uint;
7551 Tag : Entity_Id;
f2cbd970 7552 Tag_Typ : Entity_Id;
80b992ae
HK
7553 Thunk_Id : Entity_Id;
7554 Thunk_Code : Node_Id;
d0dd5209
JM
7555
7556 begin
7557 pragma Assert (not Restriction_Active (No_Dispatching_Calls));
7558
9e9df9da
AC
7559 -- Do not register in the dispatch table eliminated primitives
7560
7561 if not RTE_Available (RE_Tag)
7562 or else Is_Eliminated (Ultimate_Alias (Prim))
078b1a5f 7563 or else Generate_SCIL
9e9df9da 7564 then
991395ab 7565 return L;
d0dd5209
JM
7566 end if;
7567
ce2b6ba5 7568 if not Present (Interface_Alias (Prim)) then
f2cbd970 7569 Tag_Typ := Scope (DTC_Entity (Prim));
1923d2d6 7570 Pos := DT_Position (Prim);
f2cbd970 7571 Tag := First_Tag_Component (Tag_Typ);
d0dd5209
JM
7572
7573 if Is_Predefined_Dispatching_Operation (Prim)
7574 or else Is_Predefined_Dispatching_Alias (Prim)
7575 then
f2cbd970
JM
7576 DT_Ptr :=
7577 Node (Next_Elmt (First_Elmt (Access_Disp_Table (Tag_Typ))));
7578
991395ab 7579 Append_To (L,
d0dd5209 7580 Build_Set_Predefined_Prim_Op_Address (Loc,
e4494292 7581 Tag_Node => New_Occurrence_Of (DT_Ptr, Loc),
d0dd5209 7582 Position => Pos,
1923d2d6 7583 Address_Node =>
f2cbd970 7584 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
1923d2d6 7585 Make_Attribute_Reference (Loc,
e4494292 7586 Prefix => New_Occurrence_Of (Prim, Loc),
1923d2d6 7587 Attribute_Name => Name_Unrestricted_Access))));
d0dd5209 7588
5f143024 7589 -- Register copy of the pointer to the 'size primitive in the TSD
f2cbd970
JM
7590
7591 if Chars (Prim) = Name_uSize
7592 and then RTE_Record_Component_Available (RE_Size_Func)
7593 then
7594 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
991395ab 7595 Append_To (L,
f2cbd970 7596 Build_Set_Size_Function (Loc,
e4494292 7597 Tag_Node => New_Occurrence_Of (DT_Ptr, Loc),
f2cbd970
JM
7598 Size_Func => Prim));
7599 end if;
7600
d0dd5209
JM
7601 else
7602 pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));
7603
cefce34c
JM
7604 -- Skip registration of primitives located in the C++ part of the
7605 -- dispatch table. Their slot is set by the IC routine.
7606
7607 if not Is_CPP_Class (Root_Type (Tag_Typ))
7608 or else Pos > CPP_Num_Prims (Tag_Typ)
7609 then
7610 DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
7611 Append_To (L,
7612 Build_Set_Prim_Op_Address (Loc,
7613 Typ => Tag_Typ,
e4494292 7614 Tag_Node => New_Occurrence_Of (DT_Ptr, Loc),
cefce34c
JM
7615 Position => Pos,
7616 Address_Node =>
7617 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
7618 Make_Attribute_Reference (Loc,
e4494292 7619 Prefix => New_Occurrence_Of (Prim, Loc),
cefce34c
JM
7620 Attribute_Name => Name_Unrestricted_Access))));
7621 end if;
d0dd5209
JM
7622 end if;
7623
7624 -- Ada 2005 (AI-251): Primitive associated with an interface type
6782b1ef 7625
d0dd5209
JM
7626 -- Generate the code of the thunk only if the interface type is not an
7627 -- immediate ancestor of Typ; otherwise the dispatch table associated
7628 -- with the interface is the primary dispatch table and we have nothing
7629 -- else to do here.
7630
7631 else
f2cbd970 7632 Tag_Typ := Find_Dispatching_Type (Alias (Prim));
ce2b6ba5 7633 Iface_Typ := Find_Dispatching_Type (Interface_Alias (Prim));
d0dd5209
JM
7634
7635 pragma Assert (Is_Interface (Iface_Typ));
7636
b4d7b435
AC
7637 -- No action needed for interfaces that are ancestors of Typ because
7638 -- their primitives are located in the primary dispatch table.
7639
4ac2477e 7640 if Is_Ancestor (Iface_Typ, Tag_Typ, Use_Full_View => True) then
b4d7b435 7641 return L;
cefce34c
JM
7642
7643 -- No action needed for primitives located in the C++ part of the
7644 -- dispatch table. Their slot is set by the IC routine.
7645
7646 elsif Is_CPP_Class (Root_Type (Tag_Typ))
7647 and then DT_Position (Alias (Prim)) <= CPP_Num_Prims (Tag_Typ)
7648 and then not Is_Predefined_Dispatching_Operation (Prim)
7649 and then not Is_Predefined_Dispatching_Alias (Prim)
7650 then
7651 return L;
b4d7b435
AC
7652 end if;
7653
20dc266e 7654 Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code, Iface_Typ);
d0dd5209 7655
4ac2477e 7656 if not Is_Ancestor (Iface_Typ, Tag_Typ, Use_Full_View => True)
d0dd5209
JM
7657 and then Present (Thunk_Code)
7658 then
d0dd5209
JM
7659 -- Generate the code necessary to fill the appropriate entry of
7660 -- the secondary dispatch table of Prim's controlling type with
7661 -- Thunk_Id's address.
7662
f2cbd970 7663 Iface_DT_Elmt := Find_Interface_ADT (Tag_Typ, Iface_Typ);
80b992ae
HK
7664 Iface_DT_Ptr := Node (Iface_DT_Elmt);
7665 pragma Assert (Has_Thunks (Iface_DT_Ptr));
7666
ce2b6ba5 7667 Iface_Prim := Interface_Alias (Prim);
1923d2d6
JM
7668 Pos := DT_Position (Iface_Prim);
7669 Tag := First_Tag_Component (Iface_Typ);
991395ab
AC
7670
7671 Prepend_To (L, Thunk_Code);
d0dd5209
JM
7672
7673 if Is_Predefined_Dispatching_Operation (Prim)
7674 or else Is_Predefined_Dispatching_Alias (Prim)
7675 then
80b992ae 7676 Append_To (L,
d0dd5209 7677 Build_Set_Predefined_Prim_Op_Address (Loc,
1923d2d6 7678 Tag_Node =>
e4494292 7679 New_Occurrence_Of (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
d0dd5209
JM
7680 Position => Pos,
7681 Address_Node =>
f2cbd970 7682 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
1923d2d6 7683 Make_Attribute_Reference (Loc,
e4494292 7684 Prefix => New_Occurrence_Of (Thunk_Id, Loc),
1923d2d6 7685 Attribute_Name => Name_Unrestricted_Access))));
80b992ae 7686
1923d2d6 7687 Next_Elmt (Iface_DT_Elmt);
80b992ae
HK
7688 Next_Elmt (Iface_DT_Elmt);
7689 Iface_DT_Ptr := Node (Iface_DT_Elmt);
7690 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
7691
7692 Append_To (L,
7693 Build_Set_Predefined_Prim_Op_Address (Loc,
1923d2d6 7694 Tag_Node =>
e4494292 7695 New_Occurrence_Of (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
80b992ae
HK
7696 Position => Pos,
7697 Address_Node =>
f2cbd970 7698 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
1923d2d6 7699 Make_Attribute_Reference (Loc,
cf7bb903 7700 Prefix =>
e4494292 7701 New_Occurrence_Of (Alias (Prim), Loc),
1923d2d6 7702 Attribute_Name => Name_Unrestricted_Access))));
80b992ae 7703
d0dd5209
JM
7704 else
7705 pragma Assert (Pos /= Uint_0
7706 and then Pos <= DT_Entry_Count (Tag));
7707
80b992ae
HK
7708 Append_To (L,
7709 Build_Set_Prim_Op_Address (Loc,
7710 Typ => Iface_Typ,
e4494292 7711 Tag_Node => New_Occurrence_Of (Iface_DT_Ptr, Loc),
80b992ae 7712 Position => Pos,
1923d2d6 7713 Address_Node =>
f2cbd970 7714 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
1923d2d6 7715 Make_Attribute_Reference (Loc,
e4494292 7716 Prefix => New_Occurrence_Of (Thunk_Id, Loc),
1923d2d6 7717 Attribute_Name => Name_Unrestricted_Access))));
80b992ae 7718
1923d2d6 7719 Next_Elmt (Iface_DT_Elmt);
80b992ae
HK
7720 Next_Elmt (Iface_DT_Elmt);
7721 Iface_DT_Ptr := Node (Iface_DT_Elmt);
7722 pragma Assert (not Has_Thunks (Iface_DT_Ptr));
7723
7724 Append_To (L,
d0dd5209
JM
7725 Build_Set_Prim_Op_Address (Loc,
7726 Typ => Iface_Typ,
e4494292 7727 Tag_Node => New_Occurrence_Of (Iface_DT_Ptr, Loc),
d0dd5209 7728 Position => Pos,
1923d2d6 7729 Address_Node =>
f2cbd970 7730 Unchecked_Convert_To (RTE (RE_Prim_Ptr),
1923d2d6 7731 Make_Attribute_Reference (Loc,
cf7bb903 7732 Prefix =>
4a0e6ac1 7733 New_Occurrence_Of (Ultimate_Alias (Prim), Loc),
1923d2d6 7734 Attribute_Name => Name_Unrestricted_Access))));
80b992ae 7735
d0dd5209
JM
7736 end if;
7737 end if;
7738 end if;
991395ab
AC
7739
7740 return L;
d0dd5209
JM
7741 end Register_Primitive;
7742
70482933
RK
7743 -------------------------
7744 -- Set_All_DT_Position --
7745 -------------------------
7746
7747 procedure Set_All_DT_Position (Typ : Entity_Id) is
70482933 7748
44a10091
AC
7749 function In_Predef_Prims_DT (Prim : Entity_Id) return Boolean;
7750 -- Returns True if Prim is located in the dispatch table of
7751 -- predefined primitives
7752
758c442c 7753 procedure Validate_Position (Prim : Entity_Id);
6782b1ef
AC
7754 -- Check that position assigned to Prim is completely safe (it has not
7755 -- been assigned to a previously defined primitive operation of Typ).
758c442c 7756
44a10091
AC
7757 ------------------------
7758 -- In_Predef_Prims_DT --
7759 ------------------------
7760
7761 function In_Predef_Prims_DT (Prim : Entity_Id) return Boolean is
44a10091
AC
7762 begin
7763 -- Predefined primitives
7764
7765 if Is_Predefined_Dispatching_Operation (Prim) then
7766 return True;
7767
7768 -- Renamings of predefined primitives
7769
7770 elsif Present (Alias (Prim))
7771 and then Is_Predefined_Dispatching_Operation (Ultimate_Alias (Prim))
7772 then
7773 if Chars (Ultimate_Alias (Prim)) /= Name_Op_Eq then
7774 return True;
7775
b55993b3
AC
7776 -- An overriding operation that is a user-defined renaming of
7777 -- predefined equality inherits its slot from the overridden
7778 -- operation. Otherwise it is treated as a predefined op and
7779 -- occupies the same predefined slot as equality. A call to it is
7780 -- transformed into a call to its alias, which is the predefined
7781 -- equality op. A dispatching call thus uses the proper slot if
7782 -- operation is further inherited and called with class-wide
7783 -- arguments.
44a10091
AC
7784
7785 else
b55993b3
AC
7786 return
7787 not Comes_From_Source (Prim)
7788 or else No (Overridden_Operation (Prim));
44a10091
AC
7789 end if;
7790
7791 -- User-defined primitives
7792
7793 else
7794 return False;
7795 end if;
7796 end In_Predef_Prims_DT;
7797
758c442c
GD
7798 -----------------------
7799 -- Validate_Position --
7800 -----------------------
7801
7802 procedure Validate_Position (Prim : Entity_Id) is
bfef8d0d
JM
7803 Op_Elmt : Elmt_Id;
7804 Op : Entity_Id;
10b93b2e 7805
758c442c 7806 begin
bfef8d0d
JM
7807 -- Aliased primitives are safe
7808
7809 if Present (Alias (Prim)) then
7810 return;
7811 end if;
7812
7813 Op_Elmt := First_Elmt (Primitive_Operations (Typ));
7814 while Present (Op_Elmt) loop
7815 Op := Node (Op_Elmt);
7816
7817 -- No need to check against itself
7818
7819 if Op = Prim then
7820 null;
7821
758c442c
GD
7822 -- Primitive operations covering abstract interfaces are
7823 -- allocated later
7824
ce2b6ba5 7825 elsif Present (Interface_Alias (Op)) then
758c442c
GD
7826 null;
7827
b0efe69e
JM
7828 -- Predefined dispatching operations are completely safe. They
7829 -- are allocated at fixed positions in a separate table.
758c442c 7830
bfef8d0d
JM
7831 elsif Is_Predefined_Dispatching_Operation (Op)
7832 or else Is_Predefined_Dispatching_Alias (Op)
7833 then
758c442c 7834 null;
70482933 7835
758c442c
GD
7836 -- Aliased subprograms are safe
7837
bfef8d0d 7838 elsif Present (Alias (Op)) then
758c442c
GD
7839 null;
7840
bfef8d0d
JM
7841 elsif DT_Position (Op) = DT_Position (Prim)
7842 and then not Is_Predefined_Dispatching_Operation (Op)
7843 and then not Is_Predefined_Dispatching_Operation (Prim)
7844 and then not Is_Predefined_Dispatching_Alias (Op)
7845 and then not Is_Predefined_Dispatching_Alias (Prim)
7846 then
10b93b2e
HK
7847 -- Handle aliased subprograms
7848
7849 declare
7850 Op_1 : Entity_Id;
7851 Op_2 : Entity_Id;
7852
7853 begin
bfef8d0d 7854 Op_1 := Op;
10b93b2e
HK
7855 loop
7856 if Present (Overridden_Operation (Op_1)) then
7857 Op_1 := Overridden_Operation (Op_1);
7858 elsif Present (Alias (Op_1)) then
7859 Op_1 := Alias (Op_1);
7860 else
7861 exit;
7862 end if;
7863 end loop;
7864
7865 Op_2 := Prim;
7866 loop
7867 if Present (Overridden_Operation (Op_2)) then
7868 Op_2 := Overridden_Operation (Op_2);
7869 elsif Present (Alias (Op_2)) then
7870 Op_2 := Alias (Op_2);
7871 else
7872 exit;
7873 end if;
7874 end loop;
7875
7876 if Op_1 /= Op_2 then
7877 raise Program_Error;
7878 end if;
7879 end;
758c442c
GD
7880 end if;
7881
bfef8d0d 7882 Next_Elmt (Op_Elmt);
758c442c
GD
7883 end loop;
7884 end Validate_Position;
7885
bfef8d0d
JM
7886 -- Local variables
7887
7888 Parent_Typ : constant Entity_Id := Etype (Typ);
bfef8d0d
JM
7889 First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
7890 The_Tag : constant Entity_Id := First_Tag_Component (Typ);
7891
dedac3eb
RD
7892 Adjusted : Boolean := False;
7893 Finalized : Boolean := False;
bfef8d0d 7894
dee4682a
JM
7895 Count_Prim : Nat;
7896 DT_Length : Nat;
7897 Nb_Prim : Nat;
bfef8d0d
JM
7898 Prim : Entity_Id;
7899 Prim_Elmt : Elmt_Id;
7900
758c442c
GD
7901 -- Start of processing for Set_All_DT_Position
7902
7903 begin
ce2b6ba5
JM
7904 pragma Assert (Present (First_Tag_Component (Typ)));
7905
16c5f1c6
RD
7906 -- Set the DT_Position for each primitive operation. Perform some sanity
7907 -- checks to avoid building inconsistent dispatch tables.
70482933 7908
6782b1ef
AC
7909 -- First stage: Set DTC entity of all the primitive operations. This is
7910 -- required to properly read the DT_Position attribute in latter stages.
70482933 7911
dee4682a
JM
7912 Prim_Elmt := First_Prim;
7913 Count_Prim := 0;
7914 while Present (Prim_Elmt) loop
7915 Prim := Node (Prim_Elmt);
70482933 7916
dee4682a 7917 -- Predefined primitives have a separate dispatch table
70482933 7918
44a10091 7919 if not In_Predef_Prims_DT (Prim) then
dee4682a
JM
7920 Count_Prim := Count_Prim + 1;
7921 end if;
70482933 7922
d0dd5209 7923 Set_DTC_Entity_Value (Typ, Prim);
70482933 7924
dee4682a
JM
7925 -- Clear any previous value of the DT_Position attribute. In this
7926 -- way we ensure that the final position of all the primitives is
8fc789c8 7927 -- established by the following stages of this algorithm.
70482933 7928
024d33d8 7929 Set_DT_Position_Value (Prim, No_Uint);
70482933 7930
dee4682a
JM
7931 Next_Elmt (Prim_Elmt);
7932 end loop;
70482933 7933
dee4682a 7934 declare
1923d2d6
JM
7935 Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean :=
7936 (others => False);
7937
dee4682a 7938 E : Entity_Id;
70482933 7939
d0dd5209
JM
7940 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id);
7941 -- Called if Typ is declared in a nested package or a public child
7942 -- package to handle inherited primitives that were inherited by Typ
329ea7ec 7943 -- in the visible part, but whose declaration was deferred because
d0dd5209
JM
7944 -- the parent operation was private and not visible at that point.
7945
dee4682a
JM
7946 procedure Set_Fixed_Prim (Pos : Nat);
7947 -- Sets to true an element of the Fixed_Prim table to indicate
7948 -- that this entry of the dispatch table of Typ is occupied.
70482933 7949
d0dd5209
JM
7950 ------------------------------------------
7951 -- Handle_Inherited_Private_Subprograms --
7952 ------------------------------------------
7953
7954 procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id) is
7955 Op_List : Elist_Id;
7956 Op_Elmt : Elmt_Id;
7957 Op_Elmt_2 : Elmt_Id;
7958 Prim_Op : Entity_Id;
7959 Parent_Subp : Entity_Id;
7960
7961 begin
7962 Op_List := Primitive_Operations (Typ);
7963
7964 Op_Elmt := First_Elmt (Op_List);
7965 while Present (Op_Elmt) loop
7966 Prim_Op := Node (Op_Elmt);
7967
7968 -- Search primitives that are implicit operations with an
7969 -- internal name whose parent operation has a normal name.
7970
7971 if Present (Alias (Prim_Op))
7972 and then Find_Dispatching_Type (Alias (Prim_Op)) /= Typ
7973 and then not Comes_From_Source (Prim_Op)
7974 and then Is_Internal_Name (Chars (Prim_Op))
7975 and then not Is_Internal_Name (Chars (Alias (Prim_Op)))
7976 then
7977 Parent_Subp := Alias (Prim_Op);
7978
7979 -- Check if the type has an explicit overriding for this
7980 -- primitive.
7981
7982 Op_Elmt_2 := Next_Elmt (Op_Elmt);
7983 while Present (Op_Elmt_2) loop
7984 if Chars (Node (Op_Elmt_2)) = Chars (Parent_Subp)
7985 and then Type_Conformant (Prim_Op, Node (Op_Elmt_2))
7986 then
024d33d8
JM
7987 Set_DT_Position_Value (Prim_Op,
7988 DT_Position (Parent_Subp));
7989 Set_DT_Position_Value (Node (Op_Elmt_2),
d0dd5209
JM
7990 DT_Position (Parent_Subp));
7991 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim_Op)));
7992
7993 goto Next_Primitive;
7994 end if;
7995
7996 Next_Elmt (Op_Elmt_2);
7997 end loop;
7998 end if;
7999
8000 <<Next_Primitive>>
8001 Next_Elmt (Op_Elmt);
8002 end loop;
8003 end Handle_Inherited_Private_Subprograms;
8004
dee4682a
JM
8005 --------------------
8006 -- Set_Fixed_Prim --
8007 --------------------
70482933 8008
dee4682a 8009 procedure Set_Fixed_Prim (Pos : Nat) is
70482933 8010 begin
5f143024 8011 pragma Assert (Pos <= Count_Prim);
dee4682a
JM
8012 Fixed_Prim (Pos) := True;
8013 exception
8014 when Constraint_Error =>
8015 raise Program_Error;
8016 end Set_Fixed_Prim;
70482933 8017
dee4682a 8018 begin
d0dd5209
JM
8019 -- In case of nested packages and public child package it may be
8020 -- necessary a special management on inherited subprograms so that
8021 -- the dispatch table is properly filled.
8022
8023 if Ekind (Scope (Scope (Typ))) = E_Package
8024 and then Scope (Scope (Typ)) /= Standard_Standard
8025 and then ((Is_Derived_Type (Typ) and then not Is_Private_Type (Typ))
8026 or else
8027 (Nkind (Parent (Typ)) = N_Private_Extension_Declaration
8028 and then Is_Generic_Type (Typ)))
8029 and then In_Open_Scopes (Scope (Etype (Typ)))
d347f572 8030 and then Is_Base_Type (Typ)
d0dd5209
JM
8031 then
8032 Handle_Inherited_Private_Subprograms (Typ);
8033 end if;
8034
dee4682a 8035 -- Second stage: Register fixed entries
70482933 8036
dee4682a
JM
8037 Nb_Prim := 0;
8038 Prim_Elmt := First_Prim;
8039 while Present (Prim_Elmt) loop
8040 Prim := Node (Prim_Elmt);
70482933 8041
dee4682a
JM
8042 -- Predefined primitives have a separate table and all its
8043 -- entries are at predefined fixed positions.
70482933 8044
44a10091
AC
8045 if In_Predef_Prims_DT (Prim) then
8046 if Is_Predefined_Dispatching_Operation (Prim) then
024d33d8
JM
8047 Set_DT_Position_Value (Prim,
8048 Default_Prim_Op_Position (Prim));
70482933 8049
44a10091 8050 else pragma Assert (Present (Alias (Prim)));
024d33d8 8051 Set_DT_Position_Value (Prim,
44a10091
AC
8052 Default_Prim_Op_Position (Ultimate_Alias (Prim)));
8053 end if;
10b93b2e 8054
dee4682a 8055 -- Overriding primitives of ancestor abstract interfaces
70482933 8056
ce2b6ba5
JM
8057 elsif Present (Interface_Alias (Prim))
8058 and then Is_Ancestor
4ac2477e
JM
8059 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ,
8060 Use_Full_View => True)
dee4682a
JM
8061 then
8062 pragma Assert (DT_Position (Prim) = No_Uint
ce2b6ba5 8063 and then Present (DTC_Entity (Interface_Alias (Prim))));
70482933 8064
ce2b6ba5 8065 E := Interface_Alias (Prim);
024d33d8 8066 Set_DT_Position_Value (Prim, DT_Position (E));
758c442c 8067
dee4682a
JM
8068 pragma Assert
8069 (DT_Position (Alias (Prim)) = No_Uint
8070 or else DT_Position (Alias (Prim)) = DT_Position (E));
024d33d8 8071 Set_DT_Position_Value (Alias (Prim), DT_Position (E));
dee4682a 8072 Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));
bfef8d0d 8073
74a78a4f
AC
8074 -- Overriding primitives must use the same entry as the overridden
8075 -- primitive. Note that the Alias of the operation is set when the
8076 -- operation is declared by a renaming, in which case it is not
8077 -- overriding. If it renames another primitive it will use the
8078 -- same dispatch table slot, but if it renames an operation in a
8079 -- nested package it's a new primitive and will have its own slot.
bfef8d0d 8080
ce2b6ba5 8081 elsif not Present (Interface_Alias (Prim))
dee4682a 8082 and then Present (Alias (Prim))
b2e1beb3 8083 and then Chars (Prim) = Chars (Alias (Prim))
74a78a4f
AC
8084 and then Nkind (Unit_Declaration_Node (Prim)) /=
8085 N_Subprogram_Renaming_Declaration
bfef8d0d 8086 then
74a78a4f
AC
8087 declare
8088 Par_Type : constant Entity_Id :=
cc3a2986
AC
8089 Find_Dispatching_Type (Alias (Prim));
8090
74a78a4f
AC
8091 begin
8092 if Present (Par_Type)
8093 and then Par_Type /= Typ
8094 and then Is_Ancestor (Par_Type, Typ, Use_Full_View => True)
8095 and then Present (DTC_Entity (Alias (Prim)))
8096 then
8097 E := Alias (Prim);
8098 Set_DT_Position_Value (Prim, DT_Position (E));
758c442c 8099
74a78a4f
AC
8100 if not Is_Predefined_Dispatching_Alias (E) then
8101 Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
8102 end if;
8103 end if;
8104 end;
fbf5a39b 8105 end if;
70482933 8106
758c442c
GD
8107 Next_Elmt (Prim_Elmt);
8108 end loop;
8109
6782b1ef
AC
8110 -- Third stage: Fix the position of all the new primitives. Entries
8111 -- associated with primitives covering interfaces are handled in a
8112 -- latter round.
758c442c 8113
dee4682a
JM
8114 Prim_Elmt := First_Prim;
8115 while Present (Prim_Elmt) loop
8116 Prim := Node (Prim_Elmt);
758c442c 8117
dee4682a 8118 -- Skip primitives previously set entries
758c442c 8119
dee4682a
JM
8120 if DT_Position (Prim) /= No_Uint then
8121 null;
758c442c 8122
dee4682a 8123 -- Primitives covering interface primitives are handled later
758c442c 8124
ce2b6ba5 8125 elsif Present (Interface_Alias (Prim)) then
dee4682a 8126 null;
758c442c 8127
dee4682a
JM
8128 else
8129 -- Take the next available position in the DT
758c442c 8130
dee4682a
JM
8131 loop
8132 Nb_Prim := Nb_Prim + 1;
8133 pragma Assert (Nb_Prim <= Count_Prim);
8134 exit when not Fixed_Prim (Nb_Prim);
8135 end loop;
758c442c 8136
024d33d8 8137 Set_DT_Position_Value (Prim, UI_From_Int (Nb_Prim));
dee4682a
JM
8138 Set_Fixed_Prim (Nb_Prim);
8139 end if;
758c442c 8140
dee4682a
JM
8141 Next_Elmt (Prim_Elmt);
8142 end loop;
8143 end;
758c442c 8144
dee4682a 8145 -- Fourth stage: Complete the decoration of primitives covering
6782b1ef
AC
8146 -- interfaces (that is, propagate the DT_Position attribute from
8147 -- the aliased primitive)
758c442c 8148
dee4682a
JM
8149 Prim_Elmt := First_Prim;
8150 while Present (Prim_Elmt) loop
8151 Prim := Node (Prim_Elmt);
758c442c 8152
dee4682a 8153 if DT_Position (Prim) = No_Uint
ce2b6ba5 8154 and then Present (Interface_Alias (Prim))
dee4682a
JM
8155 then
8156 pragma Assert (Present (Alias (Prim))
8157 and then Find_Dispatching_Type (Alias (Prim)) = Typ);
758c442c 8158
dee4682a 8159 -- Check if this entry will be placed in the primary DT
758c442c 8160
ce2b6ba5 8161 if Is_Ancestor
4ac2477e
JM
8162 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ,
8163 Use_Full_View => True)
70482933 8164 then
dee4682a 8165 pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
024d33d8 8166 Set_DT_Position_Value (Prim, DT_Position (Alias (Prim)));
758c442c 8167
dee4682a 8168 -- Otherwise it will be placed in the secondary DT
758c442c 8169
dee4682a
JM
8170 else
8171 pragma Assert
ce2b6ba5 8172 (DT_Position (Interface_Alias (Prim)) /= No_Uint);
024d33d8 8173 Set_DT_Position_Value (Prim,
ce2b6ba5 8174 DT_Position (Interface_Alias (Prim)));
758c442c 8175 end if;
dee4682a 8176 end if;
758c442c 8177
dee4682a
JM
8178 Next_Elmt (Prim_Elmt);
8179 end loop;
10b93b2e 8180
6782b1ef
AC
8181 -- Generate listing showing the contents of the dispatch tables. This
8182 -- action is done before some further static checks because in case of
8183 -- critical errors caused by a wrong dispatch table we need to see the
8184 -- contents of such table.
10b93b2e 8185
dee4682a
JM
8186 if Debug_Flag_ZZ then
8187 Write_DT (Typ);
8188 end if;
758c442c 8189
dee4682a
JM
8190 -- Final stage: Ensure that the table is correct plus some further
8191 -- verifications concerning the primitives.
758c442c 8192
dee4682a
JM
8193 Prim_Elmt := First_Prim;
8194 DT_Length := 0;
8195 while Present (Prim_Elmt) loop
8196 Prim := Node (Prim_Elmt);
758c442c 8197
6782b1ef
AC
8198 -- At this point all the primitives MUST have a position in the
8199 -- dispatch table.
758c442c 8200
dee4682a
JM
8201 if DT_Position (Prim) = No_Uint then
8202 raise Program_Error;
8203 end if;
758c442c 8204
dee4682a 8205 -- Calculate real size of the dispatch table
758c442c 8206
44a10091 8207 if not In_Predef_Prims_DT (Prim)
dee4682a
JM
8208 and then UI_To_Int (DT_Position (Prim)) > DT_Length
8209 then
8210 DT_Length := UI_To_Int (DT_Position (Prim));
8211 end if;
758c442c 8212
6782b1ef
AC
8213 -- Ensure that the assigned position to non-predefined dispatching
8214 -- operations in the dispatch table is correct.
758c442c 8215
44a10091
AC
8216 if not Is_Predefined_Dispatching_Operation (Prim)
8217 and then not Is_Predefined_Dispatching_Alias (Prim)
dee4682a
JM
8218 then
8219 Validate_Position (Prim);
8220 end if;
70482933 8221
dee4682a
JM
8222 if Chars (Prim) = Name_Finalize then
8223 Finalized := True;
8224 end if;
70482933 8225
dee4682a
JM
8226 if Chars (Prim) = Name_Adjust then
8227 Adjusted := True;
8228 end if;
bfef8d0d 8229
ed2233dc
AC
8230 -- An abstract operation cannot be declared in the private part for a
8231 -- visible abstract type, because it can't be overridden outside this
8232 -- package hierarchy. For explicit declarations this is checked at
8233 -- the point of declaration, but for inherited operations it must be
8234 -- done when building the dispatch table.
dee4682a 8235
ce2b6ba5
JM
8236 -- Ada 2005 (AI-251): Primitives associated with interfaces are
8237 -- excluded from this check because interfaces must be visible in
8238 -- the public and private part (RM 7.3 (7.3/2))
dee4682a 8239
6782b1ef
AC
8240 -- We disable this check in Relaxed_RM_Semantics mode, to accommodate
8241 -- legacy Ada code.
f0709ca6 8242
303fbb20 8243 if not Relaxed_RM_Semantics
f0709ca6 8244 and then Is_Abstract_Type (Typ)
dee4682a
JM
8245 and then Is_Abstract_Subprogram (Prim)
8246 and then Present (Alias (Prim))
ce2b6ba5
JM
8247 and then not Is_Interface
8248 (Find_Dispatching_Type (Ultimate_Alias (Prim)))
8249 and then not Present (Interface_Alias (Prim))
dee4682a
JM
8250 and then Is_Derived_Type (Typ)
8251 and then In_Private_Part (Current_Scope)
8252 and then
8253 List_Containing (Parent (Prim)) =
d12b19fa 8254 Private_Declarations (Package_Specification (Current_Scope))
dee4682a
JM
8255 and then Original_View_In_Visible_Part (Typ)
8256 then
8257 -- We exclude Input and Output stream operations because
6782b1ef
AC
8258 -- Limited_Controlled inherits useless Input and Output stream
8259 -- operations from Root_Controlled, which can never be overridden.
2d6f6e08 8260 -- Move this check to sem???
70482933 8261
dee4682a
JM
8262 if not Is_TSS (Prim, TSS_Stream_Input)
8263 and then
8264 not Is_TSS (Prim, TSS_Stream_Output)
70482933 8265 then
ed2233dc 8266 Error_Msg_NE
dee4682a 8267 ("abstract inherited private operation&" &
b2e1beb3 8268 " must be overridden (RM 3.9.3(10))",
dee4682a 8269 Parent (Typ), Prim);
70482933 8270 end if;
dee4682a 8271 end if;
758c442c 8272
dee4682a
JM
8273 Next_Elmt (Prim_Elmt);
8274 end loop;
70482933 8275
dee4682a 8276 -- Additional check
758c442c 8277
dee4682a
JM
8278 if Is_Controlled (Typ) then
8279 if not Finalized then
ed2233dc 8280 Error_Msg_N
685bc70f 8281 ("controlled type has no explicit Finalize method??", Typ);
70482933 8282
dee4682a 8283 elsif not Adjusted then
ed2233dc 8284 Error_Msg_N
685bc70f 8285 ("controlled type has no explicit Adjust method??", Typ);
70482933 8286 end if;
dee4682a 8287 end if;
70482933 8288
dee4682a 8289 -- Set the final size of the Dispatch Table
758c442c 8290
dee4682a 8291 Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));
70482933 8292
d0dd5209 8293 -- The derived type must have at least as many components as its parent
1923d2d6 8294 -- (for root types Etype points to itself and the test cannot fail).
758c442c 8295
d0dd5209
JM
8296 if DT_Entry_Count (The_Tag) <
8297 DT_Entry_Count (First_Tag_Component (Parent_Typ))
8298 then
8299 raise Program_Error;
758c442c 8300 end if;
70482933
RK
8301 end Set_All_DT_Position;
8302
236fecbf
JM
8303 --------------------------
8304 -- Set_CPP_Constructors --
8305 --------------------------
70482933 8306
236fecbf 8307 procedure Set_CPP_Constructors (Typ : Entity_Id) is
cefce34c 8308
f62b296e
AC
8309 function Gen_Parameters_Profile (E : Entity_Id) return List_Id;
8310 -- Duplicate the parameters profile of the imported C++ constructor
3a09e026
EB
8311 -- adding the "this" pointer to the object as the additional first
8312 -- parameter under the usual form _Init : in out Typ.
cefce34c 8313
6782b1ef
AC
8314 ----------------------------
8315 -- Gen_Parameters_Profile --
8316 ----------------------------
8317
f62b296e
AC
8318 function Gen_Parameters_Profile (E : Entity_Id) return List_Id is
8319 Loc : constant Source_Ptr := Sloc (E);
8320 Parms : List_Id;
8321 P : Node_Id;
71fb4dc8 8322
cefce34c 8323 begin
f62b296e
AC
8324 Parms :=
8325 New_List (
8326 Make_Parameter_Specification (Loc,
8327 Defining_Identifier =>
8328 Make_Defining_Identifier (Loc, Name_uInit),
3a09e026
EB
8329 In_Present => True,
8330 Out_Present => True,
e4494292 8331 Parameter_Type => New_Occurrence_Of (Typ, Loc)));
f62b296e
AC
8332
8333 if Present (Parameter_Specifications (Parent (E))) then
8334 P := First (Parameter_Specifications (Parent (E)));
8335 while Present (P) loop
8336 Append_To (Parms,
8337 Make_Parameter_Specification (Loc,
8338 Defining_Identifier =>
8339 Make_Defining_Identifier (Loc,
8340 Chars => Chars (Defining_Identifier (P))),
8341 Parameter_Type => New_Copy_Tree (Parameter_Type (P)),
8342 Expression => New_Copy_Tree (Expression (P))));
8343 Next (P);
8344 end loop;
cefce34c 8345 end if;
71fb4dc8 8346
f62b296e
AC
8347 return Parms;
8348 end Gen_Parameters_Profile;
cefce34c
JM
8349
8350 -- Local variables
8351
f62b296e
AC
8352 Loc : Source_Ptr;
8353 E : Entity_Id;
8354 Found : Boolean := False;
8355 IP : Entity_Id;
8356 IP_Body : Node_Id;
8357 P : Node_Id;
8358 Parms : List_Id;
cefce34c 8359
73534138
AC
8360 Covers_Default_Constructor : Entity_Id := Empty;
8361
8362 -- Start of processing for Set_CPP_Constructor
8363
70482933 8364 begin
cefce34c
JM
8365 pragma Assert (Is_CPP_Class (Typ));
8366
236fecbf 8367 -- Look for the constructor entities
70482933
RK
8368
8369 E := Next_Entity (Typ);
236fecbf
JM
8370 while Present (E) loop
8371 if Ekind (E) = E_Function
8372 and then Is_Constructor (E)
8373 then
236fecbf
JM
8374 Found := True;
8375 Loc := Sloc (E);
f62b296e 8376 Parms := Gen_Parameters_Profile (E);
3a09e026 8377 IP := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
f62b296e 8378
1fb63e89 8379 -- Case 1: Constructor of untagged type
f62b296e
AC
8380
8381 -- If the C++ class has no virtual methods then the matching Ada
1fb63e89 8382 -- type is an untagged record type. In such case there is no need
f62b296e
AC
8383 -- to generate a wrapper of the C++ constructor because the _tag
8384 -- component is not available.
8385
8386 if not Is_Tagged_Type (Typ) then
8387 Discard_Node
8388 (Make_Subprogram_Declaration (Loc,
8389 Specification =>
8390 Make_Procedure_Specification (Loc,
8391 Defining_Unit_Name => IP,
8392 Parameter_Specifications => Parms)));
8393
8394 Set_Init_Proc (Typ, IP);
8395 Set_Is_Imported (IP);
8396 Set_Is_Constructor (IP);
8397 Set_Interface_Name (IP, Interface_Name (E));
8398 Set_Convention (IP, Convention_CPP);
8399 Set_Is_Public (IP);
8400 Set_Has_Completion (IP);
8401
8402 -- Case 2: Constructor of a tagged type
8403
3a09e026
EB
8404 -- In this case we generate the IP routine as a wrapper of the
8405 -- C++ constructor because IP must also save a copy of the _tag
f62b296e
AC
8406 -- generated in the C++ side. The copy of the _tag is used by
8407 -- Build_CPP_Init_Procedure to elaborate derivations of C++ types.
cefce34c 8408
f62b296e 8409 -- Generate:
3a09e026
EB
8410 -- procedure IP (_init : in out Typ; ...) is
8411 -- procedure ConstructorP (_init : in out Typ; ...);
f62b296e
AC
8412 -- pragma Import (ConstructorP);
8413 -- begin
8414 -- ConstructorP (_init, ...);
8415 -- if Typ._tag = null then
8416 -- Typ._tag := _init._tag;
8417 -- end if;
8418 -- end IP;
cefce34c 8419
f62b296e
AC
8420 else
8421 declare
8422 Body_Stmts : constant List_Id := New_List;
8423 Constructor_Id : Entity_Id;
8424 Constructor_Decl_Node : Node_Id;
8425 Init_Tags_List : List_Id;
cefce34c 8426
f62b296e
AC
8427 begin
8428 Constructor_Id := Make_Temporary (Loc, 'P');
cefce34c 8429
f62b296e
AC
8430 Constructor_Decl_Node :=
8431 Make_Subprogram_Declaration (Loc,
8432 Make_Procedure_Specification (Loc,
8433 Defining_Unit_Name => Constructor_Id,
8434 Parameter_Specifications => Parms));
cefce34c 8435
f62b296e
AC
8436 Set_Is_Imported (Constructor_Id);
8437 Set_Is_Constructor (Constructor_Id);
8438 Set_Interface_Name (Constructor_Id, Interface_Name (E));
8439 Set_Convention (Constructor_Id, Convention_CPP);
8440 Set_Is_Public (Constructor_Id);
8441 Set_Has_Completion (Constructor_Id);
cefce34c 8442
f62b296e 8443 -- Build the init procedure as a wrapper of this constructor
cefce34c 8444
f62b296e 8445 Parms := Gen_Parameters_Profile (E);
cefce34c 8446
f62b296e 8447 -- Invoke the C++ constructor
cefce34c 8448
f62b296e
AC
8449 declare
8450 Actuals : constant List_Id := New_List;
cefce34c 8451
f62b296e
AC
8452 begin
8453 P := First (Parms);
8454 while Present (P) loop
8455 Append_To (Actuals,
e4494292 8456 New_Occurrence_Of (Defining_Identifier (P), Loc));
f62b296e
AC
8457 Next (P);
8458 end loop;
cefce34c 8459
f62b296e
AC
8460 Append_To (Body_Stmts,
8461 Make_Procedure_Call_Statement (Loc,
e4494292 8462 Name => New_Occurrence_Of (Constructor_Id, Loc),
f62b296e
AC
8463 Parameter_Associations => Actuals));
8464 end;
cefce34c 8465
f62b296e 8466 -- Initialize copies of C++ primary and secondary tags
cefce34c 8467
f62b296e 8468 Init_Tags_List := New_List;
cefce34c 8469
f62b296e
AC
8470 declare
8471 Tag_Elmt : Elmt_Id;
8472 Tag_Comp : Node_Id;
cefce34c 8473
f62b296e
AC
8474 begin
8475 Tag_Elmt := First_Elmt (Access_Disp_Table (Typ));
8476 Tag_Comp := First_Tag_Component (Typ);
cefce34c 8477
f62b296e
AC
8478 while Present (Tag_Elmt)
8479 and then Is_Tag (Node (Tag_Elmt))
8480 loop
8481 -- Skip the following assertion with primary tags
8482 -- because Related_Type is not set on primary tag
3a09e026 8483 -- components.
f62b296e
AC
8484
8485 pragma Assert
8486 (Tag_Comp = First_Tag_Component (Typ)
8487 or else Related_Type (Node (Tag_Elmt))
8488 = Related_Type (Tag_Comp));
8489
8490 Append_To (Init_Tags_List,
8491 Make_Assignment_Statement (Loc,
8492 Name =>
e4494292 8493 New_Occurrence_Of (Node (Tag_Elmt), Loc),
f62b296e
AC
8494 Expression =>
8495 Make_Selected_Component (Loc,
8496 Prefix =>
8497 Make_Identifier (Loc, Name_uInit),
8498 Selector_Name =>
e4494292 8499 New_Occurrence_Of (Tag_Comp, Loc))));
cefce34c 8500
f62b296e
AC
8501 Tag_Comp := Next_Tag_Component (Tag_Comp);
8502 Next_Elmt (Tag_Elmt);
8503 end loop;
8504 end;
cefce34c 8505
f62b296e
AC
8506 Append_To (Body_Stmts,
8507 Make_If_Statement (Loc,
8508 Condition =>
8509 Make_Op_Eq (Loc,
8510 Left_Opnd =>
e4494292 8511 New_Occurrence_Of
f62b296e
AC
8512 (Node (First_Elmt (Access_Disp_Table (Typ))),
8513 Loc),
8514 Right_Opnd =>
8515 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 8516 New_Occurrence_Of (RTE (RE_Null_Address), Loc))),
f62b296e
AC
8517 Then_Statements => Init_Tags_List));
8518
8519 IP_Body :=
8520 Make_Subprogram_Body (Loc,
8521 Specification =>
8522 Make_Procedure_Specification (Loc,
8523 Defining_Unit_Name => IP,
8524 Parameter_Specifications => Parms),
8525 Declarations => New_List (Constructor_Decl_Node),
8526 Handled_Statement_Sequence =>
8527 Make_Handled_Sequence_Of_Statements (Loc,
8528 Statements => Body_Stmts,
8529 Exception_Handlers => No_List));
8530
8531 Discard_Node (IP_Body);
8532 Set_Init_Proc (Typ, IP);
8533 end;
8534 end if;
73534138 8535
6782b1ef
AC
8536 -- If this constructor has parameters and all its parameters have
8537 -- defaults then it covers the default constructor. The semantic
8538 -- analyzer ensures that only one constructor with defaults covers
8539 -- the default constructor.
73534138
AC
8540
8541 if Present (Parameter_Specifications (Parent (E)))
8542 and then Needs_No_Actuals (E)
8543 then
f62b296e 8544 Covers_Default_Constructor := IP;
73534138 8545 end if;
236fecbf
JM
8546 end if;
8547
70482933
RK
8548 Next_Entity (E);
8549 end loop;
8550
fbf5a39b 8551 -- If there are no constructors, mark the type as abstract since we
70482933
RK
8552 -- won't be able to declare objects of that type.
8553
236fecbf 8554 if not Found then
dee4682a 8555 Set_Is_Abstract_Type (Typ);
70482933 8556 end if;
cefce34c 8557
73534138
AC
8558 -- Handle constructor that has all its parameters with defaults and
8559 -- hence it covers the default constructor. We generate a wrapper IP
8560 -- which calls the covering constructor.
8561
8562 if Present (Covers_Default_Constructor) then
f62b296e
AC
8563 declare
8564 Body_Stmts : List_Id;
73534138 8565
f62b296e
AC
8566 begin
8567 Loc := Sloc (Covers_Default_Constructor);
73534138 8568
f62b296e
AC
8569 Body_Stmts := New_List (
8570 Make_Procedure_Call_Statement (Loc,
8571 Name =>
e4494292 8572 New_Occurrence_Of (Covers_Default_Constructor, Loc),
f62b296e
AC
8573 Parameter_Associations => New_List (
8574 Make_Identifier (Loc, Name_uInit))));
73534138 8575
f62b296e 8576 IP := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
73534138 8577
f62b296e
AC
8578 IP_Body :=
8579 Make_Subprogram_Body (Loc,
8580 Specification =>
8581 Make_Procedure_Specification (Loc,
8582 Defining_Unit_Name => IP,
8583 Parameter_Specifications => New_List (
8584 Make_Parameter_Specification (Loc,
8585 Defining_Identifier =>
8586 Make_Defining_Identifier (Loc, Name_uInit),
e4494292 8587 Parameter_Type => New_Occurrence_Of (Typ, Loc)))),
73534138 8588
f62b296e
AC
8589 Declarations => No_List,
8590
8591 Handled_Statement_Sequence =>
8592 Make_Handled_Sequence_Of_Statements (Loc,
8593 Statements => Body_Stmts,
8594 Exception_Handlers => No_List));
8595
8596 Discard_Node (IP_Body);
8597 Set_Init_Proc (Typ, IP);
8598 end;
73534138
AC
8599 end if;
8600
cefce34c
JM
8601 -- If the CPP type has constructors then it must import also the default
8602 -- C++ constructor. It is required for default initialization of objects
8603 -- of the type. It is also required to elaborate objects of Ada types
8604 -- that are defined as derivations of this CPP type.
8605
8606 if Has_CPP_Constructors (Typ)
8607 and then No (Init_Proc (Typ))
8608 then
685bc70f 8609 Error_Msg_N ("??default constructor must be imported from C++", Typ);
cefce34c 8610 end if;
236fecbf 8611 end Set_CPP_Constructors;
70482933 8612
024d33d8
JM
8613 ---------------------------
8614 -- Set_DT_Position_Value --
8615 ---------------------------
8616
8617 procedure Set_DT_Position_Value (Prim : Entity_Id; Value : Uint) is
8618 begin
8619 Set_DT_Position (Prim, Value);
8620
8621 -- Propagate the value to the wrapped subprogram (if one is present)
8622
4a08c95c 8623 if Ekind (Prim) in E_Function | E_Procedure
024d33d8
JM
8624 and then Is_Primitive_Wrapper (Prim)
8625 and then Present (Wrapped_Entity (Prim))
8626 and then Is_Dispatching_Operation (Wrapped_Entity (Prim))
8627 then
8628 Set_DT_Position (Wrapped_Entity (Prim), Value);
8629 end if;
8630 end Set_DT_Position_Value;
8631
d0dd5209
JM
8632 --------------------------
8633 -- Set_DTC_Entity_Value --
8634 --------------------------
8635
8636 procedure Set_DTC_Entity_Value
8637 (Tagged_Type : Entity_Id;
8638 Prim : Entity_Id)
8639 is
8640 begin
ce2b6ba5 8641 if Present (Interface_Alias (Prim))
d0dd5209 8642 and then Is_Interface
ce2b6ba5 8643 (Find_Dispatching_Type (Interface_Alias (Prim)))
d0dd5209
JM
8644 then
8645 Set_DTC_Entity (Prim,
8646 Find_Interface_Tag
8647 (T => Tagged_Type,
ce2b6ba5 8648 Iface => Find_Dispatching_Type (Interface_Alias (Prim))));
d0dd5209
JM
8649 else
8650 Set_DTC_Entity (Prim,
8651 First_Tag_Component (Tagged_Type));
8652 end if;
024d33d8
JM
8653
8654 -- Propagate the value to the wrapped subprogram (if one is present)
8655
4a08c95c 8656 if Ekind (Prim) in E_Function | E_Procedure
024d33d8
JM
8657 and then Is_Primitive_Wrapper (Prim)
8658 and then Present (Wrapped_Entity (Prim))
8659 and then Is_Dispatching_Operation (Wrapped_Entity (Prim))
8660 then
8661 Set_DTC_Entity (Wrapped_Entity (Prim), DTC_Entity (Prim));
8662 end if;
d0dd5209
JM
8663 end Set_DTC_Entity_Value;
8664
4d744221
JM
8665 -----------------
8666 -- Tagged_Kind --
8667 -----------------
8668
8669 function Tagged_Kind (T : Entity_Id) return Node_Id is
8670 Conc_Typ : Entity_Id;
8671 Loc : constant Source_Ptr := Sloc (T);
8672
8673 begin
b0efe69e
JM
8674 pragma Assert
8675 (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));
4d744221
JM
8676
8677 -- Abstract kinds
8678
dee4682a 8679 if Is_Abstract_Type (T) then
4d744221 8680 if Is_Limited_Record (T) then
e4494292
RD
8681 return New_Occurrence_Of
8682 (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
4d744221 8683 else
e4494292
RD
8684 return New_Occurrence_Of
8685 (RTE (RE_TK_Abstract_Tagged), Loc);
4d744221
JM
8686 end if;
8687
8688 -- Concurrent kinds
8689
8690 elsif Is_Concurrent_Record_Type (T) then
8691 Conc_Typ := Corresponding_Concurrent_Type (T);
8692
b2e1beb3
ES
8693 if Present (Full_View (Conc_Typ)) then
8694 Conc_Typ := Full_View (Conc_Typ);
8695 end if;
8696
4d744221 8697 if Ekind (Conc_Typ) = E_Protected_Type then
e4494292 8698 return New_Occurrence_Of (RTE (RE_TK_Protected), Loc);
4d744221
JM
8699 else
8700 pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
e4494292 8701 return New_Occurrence_Of (RTE (RE_TK_Task), Loc);
4d744221
JM
8702 end if;
8703
8704 -- Regular tagged kinds
8705
8706 else
8707 if Is_Limited_Record (T) then
e4494292 8708 return New_Occurrence_Of (RTE (RE_TK_Limited_Tagged), Loc);
4d744221 8709 else
e4494292 8710 return New_Occurrence_Of (RTE (RE_TK_Tagged), Loc);
4d744221
JM
8711 end if;
8712 end if;
8713 end Tagged_Kind;
8714
758c442c
GD
8715 --------------
8716 -- Write_DT --
8717 --------------
8718
8719 procedure Write_DT (Typ : Entity_Id) is
8720 Elmt : Elmt_Id;
8721 Prim : Node_Id;
8722
8723 begin
8724 -- Protect this procedure against wrong usage. Required because it will
8725 -- be used directly from GDB
8726
b2e1beb3 8727 if not (Typ <= Last_Node_Id)
758c442c
GD
8728 or else not Is_Tagged_Type (Typ)
8729 then
10b93b2e 8730 Write_Str ("wrong usage: Write_DT must be used with tagged types");
758c442c
GD
8731 Write_Eol;
8732 return;
8733 end if;
8734
8735 Write_Int (Int (Typ));
8736 Write_Str (": ");
8737 Write_Name (Chars (Typ));
8738
8739 if Is_Interface (Typ) then
8740 Write_Str (" is interface");
8741 end if;
8742
8743 Write_Eol;
8744
8745 Elmt := First_Elmt (Primitive_Operations (Typ));
8746 while Present (Elmt) loop
8747 Prim := Node (Elmt);
8748 Write_Str (" - ");
8749
8750 -- Indicate if this primitive will be allocated in the primary
8751 -- dispatch table or in a secondary dispatch table associated
8752 -- with an abstract interface type
8753
8754 if Present (DTC_Entity (Prim)) then
3477e0b2 8755 if Is_RTE (Etype (DTC_Entity (Prim)), RE_Tag) then
758c442c
GD
8756 Write_Str ("[P] ");
8757 else
8758 Write_Str ("[s] ");
8759 end if;
8760 end if;
8761
8762 -- Output the node of this primitive operation and its name
8763
8764 Write_Int (Int (Prim));
8765 Write_Str (": ");
b0efe69e
JM
8766
8767 if Is_Predefined_Dispatching_Operation (Prim) then
8768 Write_Str ("(predefined) ");
8769 end if;
8770
74853971
AC
8771 -- Prefix the name of the primitive with its corresponding tagged
8772 -- type to facilitate seeing inherited primitives.
8773
8774 if Present (Alias (Prim)) then
8775 Write_Name
8776 (Chars (Find_Dispatching_Type (Ultimate_Alias (Prim))));
8777 else
8778 Write_Name (Chars (Typ));
8779 end if;
8780
8781 Write_Str (".");
758c442c
GD
8782 Write_Name (Chars (Prim));
8783
8784 -- Indicate if this primitive has an aliased primitive
8785
8786 if Present (Alias (Prim)) then
8787 Write_Str (" (alias = ");
8788 Write_Int (Int (Alias (Prim)));
8789
8790 -- If the DTC_Entity attribute is already set we can also output
3ce5ca75 8791 -- the name of the interface covered by this primitive (if any).
758c442c 8792
4a08c95c 8793 if Ekind (Alias (Prim)) in E_Function | E_Procedure
22a83cea 8794 and then Present (DTC_Entity (Alias (Prim)))
758c442c
GD
8795 and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
8796 then
8797 Write_Str (" from interface ");
8798 Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
8799 end if;
8800
ce2b6ba5 8801 if Present (Interface_Alias (Prim)) then
758c442c 8802 Write_Str (", AI_Alias of ");
bed8af19
AC
8803
8804 if Is_Null_Interface_Primitive (Interface_Alias (Prim)) then
8805 Write_Str ("null primitive ");
8806 end if;
8807
ce2b6ba5
JM
8808 Write_Name
8809 (Chars (Find_Dispatching_Type (Interface_Alias (Prim))));
758c442c 8810 Write_Char (':');
ce2b6ba5 8811 Write_Int (Int (Interface_Alias (Prim)));
758c442c
GD
8812 end if;
8813
8814 Write_Str (")");
8815 end if;
8816
8817 -- Display the final position of this primitive in its associated
6782b1ef 8818 -- (primary or secondary) dispatch table.
758c442c
GD
8819
8820 if Present (DTC_Entity (Prim))
8821 and then DT_Position (Prim) /= No_Uint
8822 then
8823 Write_Str (" at #");
8824 Write_Int (UI_To_Int (DT_Position (Prim)));
8825 end if;
8826
dee4682a 8827 if Is_Abstract_Subprogram (Prim) then
758c442c 8828 Write_Str (" is abstract;");
bfef8d0d
JM
8829
8830 -- Check if this is a null primitive
8831
8832 elsif Comes_From_Source (Prim)
8833 and then Ekind (Prim) = E_Procedure
8834 and then Null_Present (Parent (Prim))
8835 then
8836 Write_Str (" is null;");
758c442c
GD
8837 end if;
8838
361effb1
AC
8839 if Is_Eliminated (Ultimate_Alias (Prim)) then
8840 Write_Str (" (eliminated)");
8841 end if;
8842
cefce34c
JM
8843 if Is_Imported (Prim)
8844 and then Convention (Prim) = Convention_CPP
8845 then
8846 Write_Str (" (C++)");
8847 end if;
8848
758c442c
GD
8849 Write_Eol;
8850
8851 Next_Elmt (Elmt);
8852 end loop;
8853 end Write_DT;
8854
70482933 8855end Exp_Disp;