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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [ada/] [exp_disp.adb] - Blame information for rev 290

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

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

powered by: WebSVN 2.1.0

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