OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [exp_disp.adb] - Blame information for rev 717

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.