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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 706 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT COMPILER COMPONENTS                         --
4
--                                                                          --
5
--                             E X P _ U T I L                              --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 1992-2012, Free Software Foundation, Inc.         --
10
--                                                                          --
11
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
12
-- terms of the  GNU General Public License as published  by the Free Soft- --
13
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17
-- for  more details.  You should have  received  a copy of the GNU General --
18
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19
-- http://www.gnu.org/licenses for a complete copy of the license.          --
20
--                                                                          --
21
-- GNAT was originally developed  by the GNAT team at  New York University. --
22
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
23
--                                                                          --
24
------------------------------------------------------------------------------
25
 
26
with Aspects;  use Aspects;
27
with Atree;    use Atree;
28
with Casing;   use Casing;
29
with Checks;   use Checks;
30
with Debug;    use Debug;
31
with Einfo;    use Einfo;
32
with Elists;   use Elists;
33
with Errout;   use Errout;
34
with Exp_Aggr; use Exp_Aggr;
35
with Exp_Ch6;  use Exp_Ch6;
36
with Exp_Ch7;  use Exp_Ch7;
37
with Inline;   use Inline;
38
with Itypes;   use Itypes;
39
with Lib;      use Lib;
40
with Nlists;   use Nlists;
41
with Nmake;    use Nmake;
42
with Opt;      use Opt;
43
with Restrict; use Restrict;
44
with Rident;   use Rident;
45
with Sem;      use Sem;
46
with Sem_Aux;  use Sem_Aux;
47
with Sem_Ch8;  use Sem_Ch8;
48
with Sem_Eval; use Sem_Eval;
49
with Sem_Prag; use Sem_Prag;
50
with Sem_Res;  use Sem_Res;
51
with Sem_Type; use Sem_Type;
52
with Sem_Util; use Sem_Util;
53
with Snames;   use Snames;
54
with Stand;    use Stand;
55
with Stringt;  use Stringt;
56
with Targparm; use Targparm;
57
with Tbuild;   use Tbuild;
58
with Ttypes;   use Ttypes;
59
with Urealp;   use Urealp;
60
with Validsw;  use Validsw;
61
 
62
package body Exp_Util is
63
 
64
   -----------------------
65
   -- Local Subprograms --
66
   -----------------------
67
 
68
   function Build_Task_Array_Image
69
     (Loc    : Source_Ptr;
70
      Id_Ref : Node_Id;
71
      A_Type : Entity_Id;
72
      Dyn    : Boolean := False) return Node_Id;
73
   --  Build function to generate the image string for a task that is an array
74
   --  component, concatenating the images of each index. To avoid storage
75
   --  leaks, the string is built with successive slice assignments. The flag
76
   --  Dyn indicates whether this is called for the initialization procedure of
77
   --  an array of tasks, or for the name of a dynamically created task that is
78
   --  assigned to an indexed component.
79
 
80
   function Build_Task_Image_Function
81
     (Loc   : Source_Ptr;
82
      Decls : List_Id;
83
      Stats : List_Id;
84
      Res   : Entity_Id) return Node_Id;
85
   --  Common processing for Task_Array_Image and Task_Record_Image. Build
86
   --  function body that computes image.
87
 
88
   procedure Build_Task_Image_Prefix
89
      (Loc    : Source_Ptr;
90
       Len    : out Entity_Id;
91
       Res    : out Entity_Id;
92
       Pos    : out Entity_Id;
93
       Prefix : Entity_Id;
94
       Sum    : Node_Id;
95
       Decls  : List_Id;
96
       Stats  : List_Id);
97
   --  Common processing for Task_Array_Image and Task_Record_Image. Create
98
   --  local variables and assign prefix of name to result string.
99
 
100
   function Build_Task_Record_Image
101
     (Loc    : Source_Ptr;
102
      Id_Ref : Node_Id;
103
      Dyn    : Boolean := False) return Node_Id;
104
   --  Build function to generate the image string for a task that is a record
105
   --  component. Concatenate name of variable with that of selector. The flag
106
   --  Dyn indicates whether this is called for the initialization procedure of
107
   --  record with task components, or for a dynamically created task that is
108
   --  assigned to a selected component.
109
 
110
   function Make_CW_Equivalent_Type
111
     (T : Entity_Id;
112
      E : Node_Id) return Entity_Id;
113
   --  T is a class-wide type entity, E is the initial expression node that
114
   --  constrains T in case such as: " X: T := E" or "new T'(E)". This function
115
   --  returns the entity of the Equivalent type and inserts on the fly the
116
   --  necessary declaration such as:
117
   --
118
   --    type anon is record
119
   --       _parent : Root_Type (T); constrained with E discriminants (if any)
120
   --       Extension : String (1 .. expr to match size of E);
121
   --    end record;
122
   --
123
   --  This record is compatible with any object of the class of T thanks to
124
   --  the first field and has the same size as E thanks to the second.
125
 
126
   function Make_Literal_Range
127
     (Loc         : Source_Ptr;
128
      Literal_Typ : Entity_Id) return Node_Id;
129
   --  Produce a Range node whose bounds are:
130
   --    Low_Bound (Literal_Type) ..
131
   --        Low_Bound (Literal_Type) + (Length (Literal_Typ) - 1)
132
   --  this is used for expanding declarations like X : String := "sdfgdfg";
133
   --
134
   --  If the index type of the target array is not integer, we generate:
135
   --     Low_Bound (Literal_Type) ..
136
   --        Literal_Type'Val
137
   --          (Literal_Type'Pos (Low_Bound (Literal_Type))
138
   --             + (Length (Literal_Typ) -1))
139
 
140
   function Make_Non_Empty_Check
141
     (Loc : Source_Ptr;
142
      N   : Node_Id) return Node_Id;
143
   --  Produce a boolean expression checking that the unidimensional array
144
   --  node N is not empty.
145
 
146
   function New_Class_Wide_Subtype
147
     (CW_Typ : Entity_Id;
148
      N      : Node_Id) return Entity_Id;
149
   --  Create an implicit subtype of CW_Typ attached to node N
150
 
151
   function Requires_Cleanup_Actions
152
     (L                 : List_Id;
153
      For_Package       : Boolean;
154
      Nested_Constructs : Boolean) return Boolean;
155
   --  Given a list L, determine whether it contains one of the following:
156
   --
157
   --    1) controlled objects
158
   --    2) library-level tagged types
159
   --
160
   --  Flag For_Package should be set when the list comes from a package spec
161
   --  or body. Flag Nested_Constructs should be set when any nested packages
162
   --  declared in L must be processed.
163
 
164
   -------------------------------------
165
   -- Activate_Atomic_Synchronization --
166
   -------------------------------------
167
 
168
   procedure Activate_Atomic_Synchronization (N : Node_Id) is
169
      Msg_Node : Node_Id;
170
 
171
   begin
172
      case Nkind (Parent (N)) is
173
 
174
         --  Check for cases of appearing in the prefix of a construct where
175
         --  we don't need atomic synchronization for this kind of usage.
176
 
177
         when
178
              --  Nothing to do if we are the prefix of an attribute, since we
179
              --  do not want an atomic sync operation for things like 'Size.
180
 
181
              N_Attribute_Reference |
182
 
183
              --  The N_Reference node is like an attribute
184
 
185
              N_Reference           |
186
 
187
              --  Nothing to do for a reference to a component (or components)
188
              --  of a composite object. Only reads and updates of the object
189
              --  as a whole require atomic synchronization (RM C.6 (15)).
190
 
191
              N_Indexed_Component   |
192
              N_Selected_Component  |
193
              N_Slice               =>
194
 
195
            --  For all the above cases, nothing to do if we are the prefix
196
 
197
            if Prefix (Parent (N)) = N then
198
               return;
199
            end if;
200
 
201
         when others => null;
202
      end case;
203
 
204
      --  Go ahead and set the flag
205
 
206
      Set_Atomic_Sync_Required (N);
207
 
208
      --  Generate info message if requested
209
 
210
      if Warn_On_Atomic_Synchronization then
211
         case Nkind (N) is
212
            when N_Identifier =>
213
               Msg_Node := N;
214
 
215
            when N_Selected_Component | N_Expanded_Name =>
216
               Msg_Node := Selector_Name (N);
217
 
218
            when N_Explicit_Dereference | N_Indexed_Component =>
219
               Msg_Node := Empty;
220
 
221
            when others =>
222
               pragma Assert (False);
223
               return;
224
         end case;
225
 
226
         if Present (Msg_Node) then
227
            Error_Msg_N ("?info: atomic synchronization set for &", Msg_Node);
228
         else
229
            Error_Msg_N ("?info: atomic synchronization set", N);
230
         end if;
231
      end if;
232
   end Activate_Atomic_Synchronization;
233
 
234
   ----------------------
235
   -- Adjust_Condition --
236
   ----------------------
237
 
238
   procedure Adjust_Condition (N : Node_Id) is
239
   begin
240
      if No (N) then
241
         return;
242
      end if;
243
 
244
      declare
245
         Loc : constant Source_Ptr := Sloc (N);
246
         T   : constant Entity_Id  := Etype (N);
247
         Ti  : Entity_Id;
248
 
249
      begin
250
         --  Defend against a call where the argument has no type, or has a
251
         --  type that is not Boolean. This can occur because of prior errors.
252
 
253
         if No (T) or else not Is_Boolean_Type (T) then
254
            return;
255
         end if;
256
 
257
         --  Apply validity checking if needed
258
 
259
         if Validity_Checks_On and Validity_Check_Tests then
260
            Ensure_Valid (N);
261
         end if;
262
 
263
         --  Immediate return if standard boolean, the most common case,
264
         --  where nothing needs to be done.
265
 
266
         if Base_Type (T) = Standard_Boolean then
267
            return;
268
         end if;
269
 
270
         --  Case of zero/non-zero semantics or non-standard enumeration
271
         --  representation. In each case, we rewrite the node as:
272
 
273
         --      ityp!(N) /= False'Enum_Rep
274
 
275
         --  where ityp is an integer type with large enough size to hold any
276
         --  value of type T.
277
 
278
         if Nonzero_Is_True (T) or else Has_Non_Standard_Rep (T) then
279
            if Esize (T) <= Esize (Standard_Integer) then
280
               Ti := Standard_Integer;
281
            else
282
               Ti := Standard_Long_Long_Integer;
283
            end if;
284
 
285
            Rewrite (N,
286
              Make_Op_Ne (Loc,
287
                Left_Opnd  => Unchecked_Convert_To (Ti, N),
288
                Right_Opnd =>
289
                  Make_Attribute_Reference (Loc,
290
                    Attribute_Name => Name_Enum_Rep,
291
                    Prefix         =>
292
                      New_Occurrence_Of (First_Literal (T), Loc))));
293
            Analyze_And_Resolve (N, Standard_Boolean);
294
 
295
         else
296
            Rewrite (N, Convert_To (Standard_Boolean, N));
297
            Analyze_And_Resolve (N, Standard_Boolean);
298
         end if;
299
      end;
300
   end Adjust_Condition;
301
 
302
   ------------------------
303
   -- Adjust_Result_Type --
304
   ------------------------
305
 
306
   procedure Adjust_Result_Type (N : Node_Id; T : Entity_Id) is
307
   begin
308
      --  Ignore call if current type is not Standard.Boolean
309
 
310
      if Etype (N) /= Standard_Boolean then
311
         return;
312
      end if;
313
 
314
      --  If result is already of correct type, nothing to do. Note that
315
      --  this will get the most common case where everything has a type
316
      --  of Standard.Boolean.
317
 
318
      if Base_Type (T) = Standard_Boolean then
319
         return;
320
 
321
      else
322
         declare
323
            KP : constant Node_Kind := Nkind (Parent (N));
324
 
325
         begin
326
            --  If result is to be used as a Condition in the syntax, no need
327
            --  to convert it back, since if it was changed to Standard.Boolean
328
            --  using Adjust_Condition, that is just fine for this usage.
329
 
330
            if KP in N_Raise_xxx_Error or else KP in N_Has_Condition then
331
               return;
332
 
333
            --  If result is an operand of another logical operation, no need
334
            --  to reset its type, since Standard.Boolean is just fine, and
335
            --  such operations always do Adjust_Condition on their operands.
336
 
337
            elsif     KP in N_Op_Boolean
338
              or else KP in N_Short_Circuit
339
              or else KP = N_Op_Not
340
            then
341
               return;
342
 
343
            --  Otherwise we perform a conversion from the current type, which
344
            --  must be Standard.Boolean, to the desired type.
345
 
346
            else
347
               Set_Analyzed (N);
348
               Rewrite (N, Convert_To (T, N));
349
               Analyze_And_Resolve (N, T);
350
            end if;
351
         end;
352
      end if;
353
   end Adjust_Result_Type;
354
 
355
   --------------------------
356
   -- Append_Freeze_Action --
357
   --------------------------
358
 
359
   procedure Append_Freeze_Action (T : Entity_Id; N : Node_Id) is
360
      Fnode : Node_Id;
361
 
362
   begin
363
      Ensure_Freeze_Node (T);
364
      Fnode := Freeze_Node (T);
365
 
366
      if No (Actions (Fnode)) then
367
         Set_Actions (Fnode, New_List);
368
      end if;
369
 
370
      Append (N, Actions (Fnode));
371
   end Append_Freeze_Action;
372
 
373
   ---------------------------
374
   -- Append_Freeze_Actions --
375
   ---------------------------
376
 
377
   procedure Append_Freeze_Actions (T : Entity_Id; L : List_Id) is
378
      Fnode : constant Node_Id := Freeze_Node (T);
379
 
380
   begin
381
      if No (L) then
382
         return;
383
 
384
      else
385
         if No (Actions (Fnode)) then
386
            Set_Actions (Fnode, L);
387
         else
388
            Append_List (L, Actions (Fnode));
389
         end if;
390
      end if;
391
   end Append_Freeze_Actions;
392
 
393
   ------------------------------------
394
   -- Build_Allocate_Deallocate_Proc --
395
   ------------------------------------
396
 
397
   procedure Build_Allocate_Deallocate_Proc
398
     (N           : Node_Id;
399
      Is_Allocate : Boolean)
400
   is
401
      Desig_Typ    : Entity_Id;
402
      Expr         : Node_Id;
403
      Pool_Id      : Entity_Id;
404
      Proc_To_Call : Node_Id := Empty;
405
      Ptr_Typ      : Entity_Id;
406
 
407
      function Find_Finalize_Address (Typ : Entity_Id) return Entity_Id;
408
      --  Locate TSS primitive Finalize_Address in type Typ
409
 
410
      function Find_Object (E : Node_Id) return Node_Id;
411
      --  Given an arbitrary expression of an allocator, try to find an object
412
      --  reference in it, otherwise return the original expression.
413
 
414
      function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean;
415
      --  Determine whether subprogram Subp denotes a custom allocate or
416
      --  deallocate.
417
 
418
      ---------------------------
419
      -- Find_Finalize_Address --
420
      ---------------------------
421
 
422
      function Find_Finalize_Address (Typ : Entity_Id) return Entity_Id is
423
         Utyp : Entity_Id := Typ;
424
 
425
      begin
426
         --  Handle protected class-wide or task class-wide types
427
 
428
         if Is_Class_Wide_Type (Utyp) then
429
            if Is_Concurrent_Type (Root_Type (Utyp)) then
430
               Utyp := Root_Type (Utyp);
431
 
432
            elsif Is_Private_Type (Root_Type (Utyp))
433
              and then Present (Full_View (Root_Type (Utyp)))
434
              and then Is_Concurrent_Type (Full_View (Root_Type (Utyp)))
435
            then
436
               Utyp := Full_View (Root_Type (Utyp));
437
            end if;
438
         end if;
439
 
440
         --  Handle private types
441
 
442
         if Is_Private_Type (Utyp)
443
           and then Present (Full_View (Utyp))
444
         then
445
            Utyp := Full_View (Utyp);
446
         end if;
447
 
448
         --  Handle protected and task types
449
 
450
         if Is_Concurrent_Type (Utyp)
451
           and then Present (Corresponding_Record_Type (Utyp))
452
         then
453
            Utyp := Corresponding_Record_Type (Utyp);
454
         end if;
455
 
456
         Utyp := Underlying_Type (Base_Type (Utyp));
457
 
458
         --  Deal with non-tagged derivation of private views. If the parent is
459
         --  now known to be protected, the finalization routine is the one
460
         --  defined on the corresponding record of the ancestor (corresponding
461
         --  records do not automatically inherit operations, but maybe they
462
         --  should???)
463
 
464
         if Is_Untagged_Derivation (Typ) then
465
            if Is_Protected_Type (Typ) then
466
               Utyp := Corresponding_Record_Type (Root_Type (Base_Type (Typ)));
467
            else
468
               Utyp := Underlying_Type (Root_Type (Base_Type (Typ)));
469
 
470
               if Is_Protected_Type (Utyp) then
471
                  Utyp := Corresponding_Record_Type (Utyp);
472
               end if;
473
            end if;
474
         end if;
475
 
476
         --  If the underlying_type is a subtype, we are dealing with the
477
         --  completion of a private type. We need to access the base type and
478
         --  generate a conversion to it.
479
 
480
         if Utyp /= Base_Type (Utyp) then
481
            pragma Assert (Is_Private_Type (Typ));
482
 
483
            Utyp := Base_Type (Utyp);
484
         end if;
485
 
486
         --  When dealing with an internally built full view for a type with
487
         --  unknown discriminants, use the original record type.
488
 
489
         if Is_Underlying_Record_View (Utyp) then
490
            Utyp := Etype (Utyp);
491
         end if;
492
 
493
         return TSS (Utyp, TSS_Finalize_Address);
494
      end Find_Finalize_Address;
495
 
496
      -----------------
497
      -- Find_Object --
498
      -----------------
499
 
500
      function Find_Object (E : Node_Id) return Node_Id is
501
         Expr : Node_Id;
502
 
503
      begin
504
         pragma Assert (Is_Allocate);
505
 
506
         Expr := E;
507
         loop
508
            if Nkind_In (Expr, N_Qualified_Expression,
509
                               N_Unchecked_Type_Conversion)
510
            then
511
               Expr := Expression (Expr);
512
 
513
            elsif Nkind (Expr) = N_Explicit_Dereference then
514
               Expr := Prefix (Expr);
515
 
516
            else
517
               exit;
518
            end if;
519
         end loop;
520
 
521
         return Expr;
522
      end Find_Object;
523
 
524
      ---------------------------------
525
      -- Is_Allocate_Deallocate_Proc --
526
      ---------------------------------
527
 
528
      function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean is
529
      begin
530
         --  Look for a subprogram body with only one statement which is a
531
         --  call to Allocate_Any_Controlled / Deallocate_Any_Controlled.
532
 
533
         if Ekind (Subp) = E_Procedure
534
           and then Nkind (Parent (Parent (Subp))) = N_Subprogram_Body
535
         then
536
            declare
537
               HSS  : constant Node_Id :=
538
                        Handled_Statement_Sequence (Parent (Parent (Subp)));
539
               Proc : Entity_Id;
540
 
541
            begin
542
               if Present (Statements (HSS))
543
                 and then Nkind (First (Statements (HSS))) =
544
                            N_Procedure_Call_Statement
545
               then
546
                  Proc := Entity (Name (First (Statements (HSS))));
547
 
548
                  return
549
                    Is_RTE (Proc, RE_Allocate_Any_Controlled)
550
                      or else Is_RTE (Proc, RE_Deallocate_Any_Controlled);
551
               end if;
552
            end;
553
         end if;
554
 
555
         return False;
556
      end Is_Allocate_Deallocate_Proc;
557
 
558
   --  Start of processing for Build_Allocate_Deallocate_Proc
559
 
560
   begin
561
      --  Do not perform this expansion in Alfa mode because it is not
562
      --  necessary.
563
 
564
      if Alfa_Mode then
565
         return;
566
      end if;
567
 
568
      --  Obtain the attributes of the allocation / deallocation
569
 
570
      if Nkind (N) = N_Free_Statement then
571
         Expr := Expression (N);
572
         Ptr_Typ := Base_Type (Etype (Expr));
573
         Proc_To_Call := Procedure_To_Call (N);
574
 
575
      else
576
         if Nkind (N) = N_Object_Declaration then
577
            Expr := Expression (N);
578
         else
579
            Expr := N;
580
         end if;
581
 
582
         --  In certain cases an allocator with a qualified expression may
583
         --  be relocated and used as the initialization expression of a
584
         --  temporary:
585
 
586
         --    before:
587
         --       Obj : Ptr_Typ := new Desig_Typ'(...);
588
 
589
         --    after:
590
         --       Tmp : Ptr_Typ := new Desig_Typ'(...);
591
         --       Obj : Ptr_Typ := Tmp;
592
 
593
         --  Since the allocator is always marked as analyzed to avoid infinite
594
         --  expansion, it will never be processed by this routine given that
595
         --  the designated type needs finalization actions. Detect this case
596
         --  and complete the expansion of the allocator.
597
 
598
         if Nkind (Expr) = N_Identifier
599
           and then Nkind (Parent (Entity (Expr))) = N_Object_Declaration
600
           and then Nkind (Expression (Parent (Entity (Expr)))) = N_Allocator
601
         then
602
            Build_Allocate_Deallocate_Proc (Parent (Entity (Expr)), True);
603
            return;
604
         end if;
605
 
606
         --  The allocator may have been rewritten into something else in which
607
         --  case the expansion performed by this routine does not apply.
608
 
609
         if Nkind (Expr) /= N_Allocator then
610
            return;
611
         end if;
612
 
613
         Ptr_Typ := Base_Type (Etype (Expr));
614
         Proc_To_Call := Procedure_To_Call (Expr);
615
      end if;
616
 
617
      Pool_Id := Associated_Storage_Pool (Ptr_Typ);
618
      Desig_Typ := Available_View (Designated_Type (Ptr_Typ));
619
 
620
      --  Handle concurrent types
621
 
622
      if Is_Concurrent_Type (Desig_Typ)
623
        and then Present (Corresponding_Record_Type (Desig_Typ))
624
      then
625
         Desig_Typ := Corresponding_Record_Type (Desig_Typ);
626
      end if;
627
 
628
      --  Do not process allocations / deallocations without a pool
629
 
630
      if No (Pool_Id) then
631
         return;
632
 
633
      --  Do not process allocations on / deallocations from the secondary
634
      --  stack.
635
 
636
      elsif Is_RTE (Pool_Id, RE_SS_Pool) then
637
         return;
638
 
639
      --  Do not replicate the machinery if the allocator / free has already
640
      --  been expanded and has a custom Allocate / Deallocate.
641
 
642
      elsif Present (Proc_To_Call)
643
        and then Is_Allocate_Deallocate_Proc (Proc_To_Call)
644
      then
645
         return;
646
      end if;
647
 
648
      if Needs_Finalization (Desig_Typ) then
649
 
650
         --  Certain run-time configurations and targets do not provide support
651
         --  for controlled types.
652
 
653
         if Restriction_Active (No_Finalization) then
654
            return;
655
 
656
         --  Do nothing if the access type may never allocate / deallocate
657
         --  objects.
658
 
659
         elsif No_Pool_Assigned (Ptr_Typ) then
660
            return;
661
 
662
         --  Access-to-controlled types are not supported on .NET/JVM since
663
         --  these targets cannot support pools and address arithmetic.
664
 
665
         elsif VM_Target /= No_VM then
666
            return;
667
         end if;
668
 
669
         --  The allocation / deallocation of a controlled object must be
670
         --  chained on / detached from a finalization master.
671
 
672
         pragma Assert (Present (Finalization_Master (Ptr_Typ)));
673
 
674
      --  The only other kind of allocation / deallocation supported by this
675
      --  routine is on / from a subpool.
676
 
677
      elsif Nkind (Expr) = N_Allocator
678
        and then No (Subpool_Handle_Name (Expr))
679
      then
680
         return;
681
      end if;
682
 
683
      declare
684
         Loc     : constant Source_Ptr := Sloc (N);
685
         Addr_Id : constant Entity_Id := Make_Temporary (Loc, 'A');
686
         Alig_Id : constant Entity_Id := Make_Temporary (Loc, 'L');
687
         Proc_Id : constant Entity_Id := Make_Temporary (Loc, 'P');
688
         Size_Id : constant Entity_Id := Make_Temporary (Loc, 'S');
689
 
690
         Actuals      : List_Id;
691
         Fin_Addr_Id  : Entity_Id;
692
         Fin_Mas_Act  : Node_Id;
693
         Fin_Mas_Id   : Entity_Id;
694
         Proc_To_Call : Entity_Id;
695
         Subpool      : Node_Id := Empty;
696
 
697
      begin
698
         --  Step 1: Construct all the actuals for the call to library routine
699
         --  Allocate_Any_Controlled / Deallocate_Any_Controlled.
700
 
701
         --  a) Storage pool
702
 
703
         Actuals := New_List (New_Reference_To (Pool_Id, Loc));
704
 
705
         if Is_Allocate then
706
 
707
            --  b) Subpool
708
 
709
            if Nkind (Expr) = N_Allocator then
710
               Subpool := Subpool_Handle_Name (Expr);
711
            end if;
712
 
713
            if Present (Subpool) then
714
               Append_To (Actuals, New_Reference_To (Entity (Subpool), Loc));
715
            else
716
               Append_To (Actuals, Make_Null (Loc));
717
            end if;
718
 
719
            --  c) Finalization master
720
 
721
            if Needs_Finalization (Desig_Typ) then
722
               Fin_Mas_Id  := Finalization_Master (Ptr_Typ);
723
               Fin_Mas_Act := New_Reference_To (Fin_Mas_Id, Loc);
724
 
725
               --  Handle the case where the master is actually a pointer to a
726
               --  master. This case arises in build-in-place functions.
727
 
728
               if Is_Access_Type (Etype (Fin_Mas_Id)) then
729
                  Append_To (Actuals, Fin_Mas_Act);
730
               else
731
                  Append_To (Actuals,
732
                    Make_Attribute_Reference (Loc,
733
                      Prefix         => Fin_Mas_Act,
734
                      Attribute_Name => Name_Unrestricted_Access));
735
               end if;
736
            else
737
               Append_To (Actuals, Make_Null (Loc));
738
            end if;
739
 
740
            --  d) Finalize_Address
741
 
742
            --  Primitive Finalize_Address is never generated in CodePeer mode
743
            --  since it contains an Unchecked_Conversion.
744
 
745
            if Needs_Finalization (Desig_Typ)
746
              and then not CodePeer_Mode
747
            then
748
               Fin_Addr_Id := Find_Finalize_Address (Desig_Typ);
749
               pragma Assert (Present (Fin_Addr_Id));
750
 
751
               Append_To (Actuals,
752
                 Make_Attribute_Reference (Loc,
753
                   Prefix         => New_Reference_To (Fin_Addr_Id, Loc),
754
                   Attribute_Name => Name_Unrestricted_Access));
755
            else
756
               Append_To (Actuals, Make_Null (Loc));
757
            end if;
758
         end if;
759
 
760
         --  e) Address
761
         --  f) Storage_Size
762
         --  g) Alignment
763
 
764
         Append_To (Actuals, New_Reference_To (Addr_Id, Loc));
765
         Append_To (Actuals, New_Reference_To (Size_Id, Loc));
766
 
767
         if Is_Allocate or else not Is_Class_Wide_Type (Desig_Typ) then
768
            Append_To (Actuals, New_Reference_To (Alig_Id, Loc));
769
 
770
         --  For deallocation of class wide types we obtain the value of
771
         --  alignment from the Type Specific Record of the deallocated object.
772
         --  This is needed because the frontend expansion of class-wide types
773
         --  into equivalent types confuses the backend.
774
 
775
         else
776
            --  Generate:
777
            --     Obj.all'Alignment
778
 
779
            --  ... because 'Alignment applied to class-wide types is expanded
780
            --  into the code that reads the value of alignment from the TSD
781
            --  (see Expand_N_Attribute_Reference)
782
 
783
            Append_To (Actuals,
784
              Unchecked_Convert_To (RTE (RE_Storage_Offset),
785
                Make_Attribute_Reference (Loc,
786
                  Prefix         =>
787
                    Make_Explicit_Dereference (Loc, Relocate_Node (Expr)),
788
                  Attribute_Name => Name_Alignment)));
789
         end if;
790
 
791
         --  h) Is_Controlled
792
 
793
         --  Generate a run-time check to determine whether a class-wide object
794
         --  is truly controlled.
795
 
796
         if Needs_Finalization (Desig_Typ) then
797
            if Is_Class_Wide_Type (Desig_Typ)
798
              or else Is_Generic_Actual_Type (Desig_Typ)
799
            then
800
               declare
801
                  Flag_Id   : constant Entity_Id := Make_Temporary (Loc, 'F');
802
                  Flag_Expr : Node_Id;
803
                  Param     : Node_Id;
804
                  Temp      : Node_Id;
805
 
806
               begin
807
                  if Is_Allocate then
808
                     Temp := Find_Object (Expression (Expr));
809
                  else
810
                     Temp := Expr;
811
                  end if;
812
 
813
                  --  Processing for generic actuals
814
 
815
                  if Is_Generic_Actual_Type (Desig_Typ) then
816
                     Flag_Expr :=
817
                       New_Reference_To (Boolean_Literals
818
                         (Needs_Finalization (Base_Type (Desig_Typ))), Loc);
819
 
820
                  --  Processing for subtype indications
821
 
822
                  elsif Nkind (Temp) in N_Has_Entity
823
                    and then Is_Type (Entity (Temp))
824
                  then
825
                     Flag_Expr :=
826
                       New_Reference_To (Boolean_Literals
827
                         (Needs_Finalization (Entity (Temp))), Loc);
828
 
829
                  --  Generate a runtime check to test the controlled state of
830
                  --  an object for the purposes of allocation / deallocation.
831
 
832
                  else
833
                     --  The following case arises when allocating through an
834
                     --  interface class-wide type, generate:
835
                     --
836
                     --    Temp.all
837
 
838
                     if Is_RTE (Etype (Temp), RE_Tag_Ptr) then
839
                        Param :=
840
                          Make_Explicit_Dereference (Loc,
841
                            Prefix =>
842
                              Relocate_Node (Temp));
843
 
844
                     --  Generate:
845
                     --    Temp'Tag
846
 
847
                     else
848
                        Param :=
849
                          Make_Attribute_Reference (Loc,
850
                            Prefix =>
851
                              Relocate_Node (Temp),
852
                            Attribute_Name => Name_Tag);
853
                     end if;
854
 
855
                     --  Generate:
856
                     --    Needs_Finalization (<Param>)
857
 
858
                     Flag_Expr :=
859
                       Make_Function_Call (Loc,
860
                         Name =>
861
                           New_Reference_To (RTE (RE_Needs_Finalization), Loc),
862
                         Parameter_Associations => New_List (Param));
863
                  end if;
864
 
865
                  --  Create the temporary which represents the finalization
866
                  --  state of the expression. Generate:
867
                  --
868
                  --    F : constant Boolean := <Flag_Expr>;
869
 
870
                  Insert_Action (N,
871
                    Make_Object_Declaration (Loc,
872
                      Defining_Identifier => Flag_Id,
873
                      Constant_Present => True,
874
                      Object_Definition =>
875
                        New_Reference_To (Standard_Boolean, Loc),
876
                      Expression => Flag_Expr));
877
 
878
                  --  The flag acts as the last actual
879
 
880
                  Append_To (Actuals, New_Reference_To (Flag_Id, Loc));
881
               end;
882
 
883
            --  The object is statically known to be controlled
884
 
885
            else
886
               Append_To (Actuals, New_Reference_To (Standard_True, Loc));
887
            end if;
888
 
889
         else
890
            Append_To (Actuals, New_Reference_To (Standard_False, Loc));
891
         end if;
892
 
893
         --  i) On_Subpool
894
 
895
         if Is_Allocate then
896
            Append_To (Actuals,
897
              New_Reference_To (Boolean_Literals (Present (Subpool)), Loc));
898
         end if;
899
 
900
         --  Step 2: Build a wrapper Allocate / Deallocate which internally
901
         --  calls Allocate_Any_Controlled / Deallocate_Any_Controlled.
902
 
903
         --  Select the proper routine to call
904
 
905
         if Is_Allocate then
906
            Proc_To_Call := RTE (RE_Allocate_Any_Controlled);
907
         else
908
            Proc_To_Call := RTE (RE_Deallocate_Any_Controlled);
909
         end if;
910
 
911
         --  Create a custom Allocate / Deallocate routine which has identical
912
         --  profile to that of System.Storage_Pools.
913
 
914
         Insert_Action (N,
915
           Make_Subprogram_Body (Loc,
916
             Specification =>
917
 
918
               --  procedure Pnn
919
 
920
               Make_Procedure_Specification (Loc,
921
                 Defining_Unit_Name => Proc_Id,
922
                 Parameter_Specifications => New_List (
923
 
924
                  --  P : Root_Storage_Pool
925
 
926
                   Make_Parameter_Specification (Loc,
927
                     Defining_Identifier => Make_Temporary (Loc, 'P'),
928
                     Parameter_Type =>
929
                       New_Reference_To (RTE (RE_Root_Storage_Pool), Loc)),
930
 
931
                  --  A : [out] Address
932
 
933
                   Make_Parameter_Specification (Loc,
934
                     Defining_Identifier => Addr_Id,
935
                     Out_Present         => Is_Allocate,
936
                     Parameter_Type      =>
937
                       New_Reference_To (RTE (RE_Address), Loc)),
938
 
939
                  --  S : Storage_Count
940
 
941
                   Make_Parameter_Specification (Loc,
942
                     Defining_Identifier => Size_Id,
943
                     Parameter_Type      =>
944
                       New_Reference_To (RTE (RE_Storage_Count), Loc)),
945
 
946
                  --  L : Storage_Count
947
 
948
                   Make_Parameter_Specification (Loc,
949
                     Defining_Identifier => Alig_Id,
950
                     Parameter_Type      =>
951
                       New_Reference_To (RTE (RE_Storage_Count), Loc)))),
952
 
953
             Declarations => No_List,
954
 
955
             Handled_Statement_Sequence =>
956
               Make_Handled_Sequence_Of_Statements (Loc,
957
                 Statements => New_List (
958
                   Make_Procedure_Call_Statement (Loc,
959
                     Name => New_Reference_To (Proc_To_Call, Loc),
960
                     Parameter_Associations => Actuals)))));
961
 
962
         --  The newly generated Allocate / Deallocate becomes the default
963
         --  procedure to call when the back end processes the allocation /
964
         --  deallocation.
965
 
966
         if Is_Allocate then
967
            Set_Procedure_To_Call (Expr, Proc_Id);
968
         else
969
            Set_Procedure_To_Call (N, Proc_Id);
970
         end if;
971
      end;
972
   end Build_Allocate_Deallocate_Proc;
973
 
974
   ------------------------
975
   -- Build_Runtime_Call --
976
   ------------------------
977
 
978
   function Build_Runtime_Call (Loc : Source_Ptr; RE : RE_Id) return Node_Id is
979
   begin
980
      --  If entity is not available, we can skip making the call (this avoids
981
      --  junk duplicated error messages in a number of cases).
982
 
983
      if not RTE_Available (RE) then
984
         return Make_Null_Statement (Loc);
985
      else
986
         return
987
           Make_Procedure_Call_Statement (Loc,
988
             Name => New_Reference_To (RTE (RE), Loc));
989
      end if;
990
   end Build_Runtime_Call;
991
 
992
   ----------------------------
993
   -- Build_Task_Array_Image --
994
   ----------------------------
995
 
996
   --  This function generates the body for a function that constructs the
997
   --  image string for a task that is an array component. The function is
998
   --  local to the init proc for the array type, and is called for each one
999
   --  of the components. The constructed image has the form of an indexed
1000
   --  component, whose prefix is the outer variable of the array type.
1001
   --  The n-dimensional array type has known indexes Index, Index2...
1002
 
1003
   --  Id_Ref is an indexed component form created by the enclosing init proc.
1004
   --  Its successive indexes are Val1, Val2, ... which are the loop variables
1005
   --  in the loops that call the individual task init proc on each component.
1006
 
1007
   --  The generated function has the following structure:
1008
 
1009
   --  function F return String is
1010
   --     Pref : string renames Task_Name;
1011
   --     T1   : String := Index1'Image (Val1);
1012
   --     ...
1013
   --     Tn   : String := indexn'image (Valn);
1014
   --     Len  : Integer := T1'Length + ... + Tn'Length + n + 1;
1015
   --     --  Len includes commas and the end parentheses.
1016
   --     Res  : String (1..Len);
1017
   --     Pos  : Integer := Pref'Length;
1018
   --
1019
   --  begin
1020
   --     Res (1 .. Pos) := Pref;
1021
   --     Pos := Pos + 1;
1022
   --     Res (Pos)    := '(';
1023
   --     Pos := Pos + 1;
1024
   --     Res (Pos .. Pos + T1'Length - 1) := T1;
1025
   --     Pos := Pos + T1'Length;
1026
   --     Res (Pos) := '.';
1027
   --     Pos := Pos + 1;
1028
   --     ...
1029
   --     Res (Pos .. Pos + Tn'Length - 1) := Tn;
1030
   --     Res (Len) := ')';
1031
   --
1032
   --     return Res;
1033
   --  end F;
1034
   --
1035
   --  Needless to say, multidimensional arrays of tasks are rare enough that
1036
   --  the bulkiness of this code is not really a concern.
1037
 
1038
   function Build_Task_Array_Image
1039
     (Loc    : Source_Ptr;
1040
      Id_Ref : Node_Id;
1041
      A_Type : Entity_Id;
1042
      Dyn    : Boolean := False) return Node_Id
1043
   is
1044
      Dims : constant Nat := Number_Dimensions (A_Type);
1045
      --  Number of dimensions for array of tasks
1046
 
1047
      Temps : array (1 .. Dims) of Entity_Id;
1048
      --  Array of temporaries to hold string for each index
1049
 
1050
      Indx : Node_Id;
1051
      --  Index expression
1052
 
1053
      Len : Entity_Id;
1054
      --  Total length of generated name
1055
 
1056
      Pos : Entity_Id;
1057
      --  Running index for substring assignments
1058
 
1059
      Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
1060
      --  Name of enclosing variable, prefix of resulting name
1061
 
1062
      Res : Entity_Id;
1063
      --  String to hold result
1064
 
1065
      Val : Node_Id;
1066
      --  Value of successive indexes
1067
 
1068
      Sum : Node_Id;
1069
      --  Expression to compute total size of string
1070
 
1071
      T : Entity_Id;
1072
      --  Entity for name at one index position
1073
 
1074
      Decls : constant List_Id := New_List;
1075
      Stats : constant List_Id := New_List;
1076
 
1077
   begin
1078
      --  For a dynamic task, the name comes from the target variable. For a
1079
      --  static one it is a formal of the enclosing init proc.
1080
 
1081
      if Dyn then
1082
         Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
1083
         Append_To (Decls,
1084
           Make_Object_Declaration (Loc,
1085
             Defining_Identifier => Pref,
1086
             Object_Definition => New_Occurrence_Of (Standard_String, Loc),
1087
             Expression =>
1088
               Make_String_Literal (Loc,
1089
                 Strval => String_From_Name_Buffer)));
1090
 
1091
      else
1092
         Append_To (Decls,
1093
           Make_Object_Renaming_Declaration (Loc,
1094
             Defining_Identifier => Pref,
1095
             Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
1096
             Name                => Make_Identifier (Loc, Name_uTask_Name)));
1097
      end if;
1098
 
1099
      Indx := First_Index (A_Type);
1100
      Val  := First (Expressions (Id_Ref));
1101
 
1102
      for J in 1 .. Dims loop
1103
         T := Make_Temporary (Loc, 'T');
1104
         Temps (J) := T;
1105
 
1106
         Append_To (Decls,
1107
            Make_Object_Declaration (Loc,
1108
               Defining_Identifier => T,
1109
               Object_Definition => New_Occurrence_Of (Standard_String, Loc),
1110
               Expression =>
1111
                 Make_Attribute_Reference (Loc,
1112
                   Attribute_Name => Name_Image,
1113
                   Prefix         => New_Occurrence_Of (Etype (Indx), Loc),
1114
                   Expressions    => New_List (New_Copy_Tree (Val)))));
1115
 
1116
         Next_Index (Indx);
1117
         Next (Val);
1118
      end loop;
1119
 
1120
      Sum := Make_Integer_Literal (Loc, Dims + 1);
1121
 
1122
      Sum :=
1123
        Make_Op_Add (Loc,
1124
          Left_Opnd => Sum,
1125
          Right_Opnd =>
1126
           Make_Attribute_Reference (Loc,
1127
             Attribute_Name => Name_Length,
1128
             Prefix =>
1129
               New_Occurrence_Of (Pref, Loc),
1130
             Expressions => New_List (Make_Integer_Literal (Loc, 1))));
1131
 
1132
      for J in 1 .. Dims loop
1133
         Sum :=
1134
            Make_Op_Add (Loc,
1135
             Left_Opnd => Sum,
1136
             Right_Opnd =>
1137
              Make_Attribute_Reference (Loc,
1138
                Attribute_Name => Name_Length,
1139
                Prefix =>
1140
                  New_Occurrence_Of (Temps (J), Loc),
1141
                Expressions => New_List (Make_Integer_Literal (Loc, 1))));
1142
      end loop;
1143
 
1144
      Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
1145
 
1146
      Set_Character_Literal_Name (Char_Code (Character'Pos ('(')));
1147
 
1148
      Append_To (Stats,
1149
         Make_Assignment_Statement (Loc,
1150
           Name => Make_Indexed_Component (Loc,
1151
              Prefix => New_Occurrence_Of (Res, Loc),
1152
              Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
1153
           Expression =>
1154
             Make_Character_Literal (Loc,
1155
               Chars => Name_Find,
1156
               Char_Literal_Value =>
1157
                 UI_From_Int (Character'Pos ('(')))));
1158
 
1159
      Append_To (Stats,
1160
         Make_Assignment_Statement (Loc,
1161
            Name => New_Occurrence_Of (Pos, Loc),
1162
            Expression =>
1163
              Make_Op_Add (Loc,
1164
                Left_Opnd => New_Occurrence_Of (Pos, Loc),
1165
                Right_Opnd => Make_Integer_Literal (Loc, 1))));
1166
 
1167
      for J in 1 .. Dims loop
1168
 
1169
         Append_To (Stats,
1170
            Make_Assignment_Statement (Loc,
1171
              Name => Make_Slice (Loc,
1172
                 Prefix => New_Occurrence_Of (Res, Loc),
1173
                 Discrete_Range  =>
1174
                   Make_Range (Loc,
1175
                      Low_Bound => New_Occurrence_Of  (Pos, Loc),
1176
                      High_Bound => Make_Op_Subtract (Loc,
1177
                        Left_Opnd =>
1178
                          Make_Op_Add (Loc,
1179
                            Left_Opnd => New_Occurrence_Of (Pos, Loc),
1180
                            Right_Opnd =>
1181
                              Make_Attribute_Reference (Loc,
1182
                                Attribute_Name => Name_Length,
1183
                                Prefix =>
1184
                                  New_Occurrence_Of (Temps (J), Loc),
1185
                                Expressions =>
1186
                                  New_List (Make_Integer_Literal (Loc, 1)))),
1187
                         Right_Opnd => Make_Integer_Literal (Loc, 1)))),
1188
 
1189
              Expression => New_Occurrence_Of (Temps (J), Loc)));
1190
 
1191
         if J < Dims then
1192
            Append_To (Stats,
1193
               Make_Assignment_Statement (Loc,
1194
                  Name => New_Occurrence_Of (Pos, Loc),
1195
                  Expression =>
1196
                    Make_Op_Add (Loc,
1197
                      Left_Opnd => New_Occurrence_Of (Pos, Loc),
1198
                      Right_Opnd =>
1199
                        Make_Attribute_Reference (Loc,
1200
                          Attribute_Name => Name_Length,
1201
                            Prefix => New_Occurrence_Of (Temps (J), Loc),
1202
                            Expressions =>
1203
                              New_List (Make_Integer_Literal (Loc, 1))))));
1204
 
1205
            Set_Character_Literal_Name (Char_Code (Character'Pos (',')));
1206
 
1207
            Append_To (Stats,
1208
               Make_Assignment_Statement (Loc,
1209
                 Name => Make_Indexed_Component (Loc,
1210
                    Prefix => New_Occurrence_Of (Res, Loc),
1211
                    Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
1212
                 Expression =>
1213
                   Make_Character_Literal (Loc,
1214
                     Chars => Name_Find,
1215
                     Char_Literal_Value =>
1216
                       UI_From_Int (Character'Pos (',')))));
1217
 
1218
            Append_To (Stats,
1219
              Make_Assignment_Statement (Loc,
1220
                Name => New_Occurrence_Of (Pos, Loc),
1221
                  Expression =>
1222
                    Make_Op_Add (Loc,
1223
                      Left_Opnd => New_Occurrence_Of (Pos, Loc),
1224
                      Right_Opnd => Make_Integer_Literal (Loc, 1))));
1225
         end if;
1226
      end loop;
1227
 
1228
      Set_Character_Literal_Name (Char_Code (Character'Pos (')')));
1229
 
1230
      Append_To (Stats,
1231
         Make_Assignment_Statement (Loc,
1232
           Name => Make_Indexed_Component (Loc,
1233
              Prefix => New_Occurrence_Of (Res, Loc),
1234
              Expressions => New_List (New_Occurrence_Of (Len, Loc))),
1235
           Expression =>
1236
             Make_Character_Literal (Loc,
1237
               Chars => Name_Find,
1238
               Char_Literal_Value =>
1239
                 UI_From_Int (Character'Pos (')')))));
1240
      return Build_Task_Image_Function (Loc, Decls, Stats, Res);
1241
   end Build_Task_Array_Image;
1242
 
1243
   ----------------------------
1244
   -- Build_Task_Image_Decls --
1245
   ----------------------------
1246
 
1247
   function Build_Task_Image_Decls
1248
     (Loc          : Source_Ptr;
1249
      Id_Ref       : Node_Id;
1250
      A_Type       : Entity_Id;
1251
      In_Init_Proc : Boolean := False) return List_Id
1252
   is
1253
      Decls  : constant List_Id   := New_List;
1254
      T_Id   : Entity_Id := Empty;
1255
      Decl   : Node_Id;
1256
      Expr   : Node_Id   := Empty;
1257
      Fun    : Node_Id   := Empty;
1258
      Is_Dyn : constant Boolean :=
1259
                 Nkind (Parent (Id_Ref)) = N_Assignment_Statement
1260
                   and then
1261
                 Nkind (Expression (Parent (Id_Ref))) = N_Allocator;
1262
 
1263
   begin
1264
      --  If Discard_Names or No_Implicit_Heap_Allocations are in effect,
1265
      --  generate a dummy declaration only.
1266
 
1267
      if Restriction_Active (No_Implicit_Heap_Allocations)
1268
        or else Global_Discard_Names
1269
      then
1270
         T_Id := Make_Temporary (Loc, 'J');
1271
         Name_Len := 0;
1272
 
1273
         return
1274
           New_List (
1275
             Make_Object_Declaration (Loc,
1276
               Defining_Identifier => T_Id,
1277
               Object_Definition => New_Occurrence_Of (Standard_String, Loc),
1278
               Expression =>
1279
                 Make_String_Literal (Loc,
1280
                   Strval => String_From_Name_Buffer)));
1281
 
1282
      else
1283
         if Nkind (Id_Ref) = N_Identifier
1284
           or else Nkind (Id_Ref) = N_Defining_Identifier
1285
         then
1286
            --  For a simple variable, the image of the task is built from
1287
            --  the name of the variable. To avoid possible conflict with the
1288
            --  anonymous type created for a single protected object, add a
1289
            --  numeric suffix.
1290
 
1291
            T_Id :=
1292
              Make_Defining_Identifier (Loc,
1293
                New_External_Name (Chars (Id_Ref), 'T', 1));
1294
 
1295
            Get_Name_String (Chars (Id_Ref));
1296
 
1297
            Expr :=
1298
              Make_String_Literal (Loc,
1299
                Strval => String_From_Name_Buffer);
1300
 
1301
         elsif Nkind (Id_Ref) = N_Selected_Component then
1302
            T_Id :=
1303
              Make_Defining_Identifier (Loc,
1304
                New_External_Name (Chars (Selector_Name (Id_Ref)), 'T'));
1305
            Fun := Build_Task_Record_Image (Loc, Id_Ref, Is_Dyn);
1306
 
1307
         elsif Nkind (Id_Ref) = N_Indexed_Component then
1308
            T_Id :=
1309
              Make_Defining_Identifier (Loc,
1310
                New_External_Name (Chars (A_Type), 'N'));
1311
 
1312
            Fun := Build_Task_Array_Image (Loc, Id_Ref, A_Type, Is_Dyn);
1313
         end if;
1314
      end if;
1315
 
1316
      if Present (Fun) then
1317
         Append (Fun, Decls);
1318
         Expr := Make_Function_Call (Loc,
1319
           Name => New_Occurrence_Of (Defining_Entity (Fun), Loc));
1320
 
1321
         if not In_Init_Proc and then VM_Target = No_VM then
1322
            Set_Uses_Sec_Stack (Defining_Entity (Fun));
1323
         end if;
1324
      end if;
1325
 
1326
      Decl := Make_Object_Declaration (Loc,
1327
        Defining_Identifier => T_Id,
1328
        Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
1329
        Constant_Present    => True,
1330
        Expression          => Expr);
1331
 
1332
      Append (Decl, Decls);
1333
      return Decls;
1334
   end Build_Task_Image_Decls;
1335
 
1336
   -------------------------------
1337
   -- Build_Task_Image_Function --
1338
   -------------------------------
1339
 
1340
   function Build_Task_Image_Function
1341
     (Loc   : Source_Ptr;
1342
      Decls : List_Id;
1343
      Stats : List_Id;
1344
      Res   : Entity_Id) return Node_Id
1345
   is
1346
      Spec : Node_Id;
1347
 
1348
   begin
1349
      Append_To (Stats,
1350
        Make_Simple_Return_Statement (Loc,
1351
          Expression => New_Occurrence_Of (Res, Loc)));
1352
 
1353
      Spec := Make_Function_Specification (Loc,
1354
        Defining_Unit_Name => Make_Temporary (Loc, 'F'),
1355
        Result_Definition  => New_Occurrence_Of (Standard_String, Loc));
1356
 
1357
      --  Calls to 'Image use the secondary stack, which must be cleaned up
1358
      --  after the task name is built.
1359
 
1360
      return Make_Subprogram_Body (Loc,
1361
         Specification => Spec,
1362
         Declarations => Decls,
1363
         Handled_Statement_Sequence =>
1364
           Make_Handled_Sequence_Of_Statements (Loc, Statements => Stats));
1365
   end Build_Task_Image_Function;
1366
 
1367
   -----------------------------
1368
   -- Build_Task_Image_Prefix --
1369
   -----------------------------
1370
 
1371
   procedure Build_Task_Image_Prefix
1372
      (Loc    : Source_Ptr;
1373
       Len    : out Entity_Id;
1374
       Res    : out Entity_Id;
1375
       Pos    : out Entity_Id;
1376
       Prefix : Entity_Id;
1377
       Sum    : Node_Id;
1378
       Decls  : List_Id;
1379
       Stats  : List_Id)
1380
   is
1381
   begin
1382
      Len := Make_Temporary (Loc, 'L', Sum);
1383
 
1384
      Append_To (Decls,
1385
        Make_Object_Declaration (Loc,
1386
          Defining_Identifier => Len,
1387
          Object_Definition   => New_Occurrence_Of (Standard_Integer, Loc),
1388
          Expression          => Sum));
1389
 
1390
      Res := Make_Temporary (Loc, 'R');
1391
 
1392
      Append_To (Decls,
1393
         Make_Object_Declaration (Loc,
1394
            Defining_Identifier => Res,
1395
            Object_Definition =>
1396
               Make_Subtype_Indication (Loc,
1397
                  Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
1398
               Constraint =>
1399
                 Make_Index_Or_Discriminant_Constraint (Loc,
1400
                   Constraints =>
1401
                     New_List (
1402
                       Make_Range (Loc,
1403
                         Low_Bound => Make_Integer_Literal (Loc, 1),
1404
                         High_Bound => New_Occurrence_Of (Len, Loc)))))));
1405
 
1406
      Pos := Make_Temporary (Loc, 'P');
1407
 
1408
      Append_To (Decls,
1409
         Make_Object_Declaration (Loc,
1410
            Defining_Identifier => Pos,
1411
            Object_Definition   => New_Occurrence_Of (Standard_Integer, Loc)));
1412
 
1413
      --  Pos := Prefix'Length;
1414
 
1415
      Append_To (Stats,
1416
         Make_Assignment_Statement (Loc,
1417
            Name => New_Occurrence_Of (Pos, Loc),
1418
            Expression =>
1419
              Make_Attribute_Reference (Loc,
1420
                Attribute_Name => Name_Length,
1421
                Prefix         => New_Occurrence_Of (Prefix, Loc),
1422
                Expressions    => New_List (Make_Integer_Literal (Loc, 1)))));
1423
 
1424
      --  Res (1 .. Pos) := Prefix;
1425
 
1426
      Append_To (Stats,
1427
        Make_Assignment_Statement (Loc,
1428
          Name =>
1429
            Make_Slice (Loc,
1430
              Prefix          => New_Occurrence_Of (Res, Loc),
1431
              Discrete_Range  =>
1432
                Make_Range (Loc,
1433
                   Low_Bound  => Make_Integer_Literal (Loc, 1),
1434
                   High_Bound => New_Occurrence_Of (Pos, Loc))),
1435
 
1436
          Expression => New_Occurrence_Of (Prefix, Loc)));
1437
 
1438
      Append_To (Stats,
1439
         Make_Assignment_Statement (Loc,
1440
            Name       => New_Occurrence_Of (Pos, Loc),
1441
            Expression =>
1442
              Make_Op_Add (Loc,
1443
                Left_Opnd  => New_Occurrence_Of (Pos, Loc),
1444
                Right_Opnd => Make_Integer_Literal (Loc, 1))));
1445
   end Build_Task_Image_Prefix;
1446
 
1447
   -----------------------------
1448
   -- Build_Task_Record_Image --
1449
   -----------------------------
1450
 
1451
   function Build_Task_Record_Image
1452
     (Loc    : Source_Ptr;
1453
      Id_Ref : Node_Id;
1454
      Dyn    : Boolean := False) return Node_Id
1455
   is
1456
      Len : Entity_Id;
1457
      --  Total length of generated name
1458
 
1459
      Pos : Entity_Id;
1460
      --  Index into result
1461
 
1462
      Res : Entity_Id;
1463
      --  String to hold result
1464
 
1465
      Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
1466
      --  Name of enclosing variable, prefix of resulting name
1467
 
1468
      Sum : Node_Id;
1469
      --  Expression to compute total size of string
1470
 
1471
      Sel : Entity_Id;
1472
      --  Entity for selector name
1473
 
1474
      Decls : constant List_Id := New_List;
1475
      Stats : constant List_Id := New_List;
1476
 
1477
   begin
1478
      --  For a dynamic task, the name comes from the target variable. For a
1479
      --  static one it is a formal of the enclosing init proc.
1480
 
1481
      if Dyn then
1482
         Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
1483
         Append_To (Decls,
1484
           Make_Object_Declaration (Loc,
1485
             Defining_Identifier => Pref,
1486
             Object_Definition => New_Occurrence_Of (Standard_String, Loc),
1487
             Expression =>
1488
               Make_String_Literal (Loc,
1489
                 Strval => String_From_Name_Buffer)));
1490
 
1491
      else
1492
         Append_To (Decls,
1493
           Make_Object_Renaming_Declaration (Loc,
1494
             Defining_Identifier => Pref,
1495
             Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
1496
             Name                => Make_Identifier (Loc, Name_uTask_Name)));
1497
      end if;
1498
 
1499
      Sel := Make_Temporary (Loc, 'S');
1500
 
1501
      Get_Name_String (Chars (Selector_Name (Id_Ref)));
1502
 
1503
      Append_To (Decls,
1504
         Make_Object_Declaration (Loc,
1505
           Defining_Identifier => Sel,
1506
           Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
1507
           Expression          =>
1508
             Make_String_Literal (Loc,
1509
               Strval => String_From_Name_Buffer)));
1510
 
1511
      Sum := Make_Integer_Literal (Loc, Nat (Name_Len + 1));
1512
 
1513
      Sum :=
1514
        Make_Op_Add (Loc,
1515
          Left_Opnd => Sum,
1516
          Right_Opnd =>
1517
           Make_Attribute_Reference (Loc,
1518
             Attribute_Name => Name_Length,
1519
             Prefix =>
1520
               New_Occurrence_Of (Pref, Loc),
1521
             Expressions => New_List (Make_Integer_Literal (Loc, 1))));
1522
 
1523
      Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
1524
 
1525
      Set_Character_Literal_Name (Char_Code (Character'Pos ('.')));
1526
 
1527
      --  Res (Pos) := '.';
1528
 
1529
      Append_To (Stats,
1530
         Make_Assignment_Statement (Loc,
1531
           Name => Make_Indexed_Component (Loc,
1532
              Prefix => New_Occurrence_Of (Res, Loc),
1533
              Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
1534
           Expression =>
1535
             Make_Character_Literal (Loc,
1536
               Chars => Name_Find,
1537
               Char_Literal_Value =>
1538
                 UI_From_Int (Character'Pos ('.')))));
1539
 
1540
      Append_To (Stats,
1541
        Make_Assignment_Statement (Loc,
1542
          Name => New_Occurrence_Of (Pos, Loc),
1543
          Expression =>
1544
            Make_Op_Add (Loc,
1545
              Left_Opnd => New_Occurrence_Of (Pos, Loc),
1546
              Right_Opnd => Make_Integer_Literal (Loc, 1))));
1547
 
1548
      --  Res (Pos .. Len) := Selector;
1549
 
1550
      Append_To (Stats,
1551
        Make_Assignment_Statement (Loc,
1552
          Name => Make_Slice (Loc,
1553
             Prefix => New_Occurrence_Of (Res, Loc),
1554
             Discrete_Range  =>
1555
               Make_Range (Loc,
1556
                 Low_Bound  => New_Occurrence_Of (Pos, Loc),
1557
                 High_Bound => New_Occurrence_Of (Len, Loc))),
1558
          Expression => New_Occurrence_Of (Sel, Loc)));
1559
 
1560
      return Build_Task_Image_Function (Loc, Decls, Stats, Res);
1561
   end Build_Task_Record_Image;
1562
 
1563
   ----------------------------------
1564
   -- Component_May_Be_Bit_Aligned --
1565
   ----------------------------------
1566
 
1567
   function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is
1568
      UT : Entity_Id;
1569
 
1570
   begin
1571
      --  If no component clause, then everything is fine, since the back end
1572
      --  never bit-misaligns by default, even if there is a pragma Packed for
1573
      --  the record.
1574
 
1575
      if No (Comp) or else No (Component_Clause (Comp)) then
1576
         return False;
1577
      end if;
1578
 
1579
      UT := Underlying_Type (Etype (Comp));
1580
 
1581
      --  It is only array and record types that cause trouble
1582
 
1583
      if not Is_Record_Type (UT)
1584
        and then not Is_Array_Type (UT)
1585
      then
1586
         return False;
1587
 
1588
      --  If we know that we have a small (64 bits or less) record or small
1589
      --  bit-packed array, then everything is fine, since the back end can
1590
      --  handle these cases correctly.
1591
 
1592
      elsif Esize (Comp) <= 64
1593
        and then (Is_Record_Type (UT)
1594
                   or else Is_Bit_Packed_Array (UT))
1595
      then
1596
         return False;
1597
 
1598
      --  Otherwise if the component is not byte aligned, we know we have the
1599
      --  nasty unaligned case.
1600
 
1601
      elsif Normalized_First_Bit (Comp) /= Uint_0
1602
        or else Esize (Comp) mod System_Storage_Unit /= Uint_0
1603
      then
1604
         return True;
1605
 
1606
      --  If we are large and byte aligned, then OK at this level
1607
 
1608
      else
1609
         return False;
1610
      end if;
1611
   end Component_May_Be_Bit_Aligned;
1612
 
1613
   -----------------------------------
1614
   -- Corresponding_Runtime_Package --
1615
   -----------------------------------
1616
 
1617
   function Corresponding_Runtime_Package (Typ : Entity_Id) return RTU_Id is
1618
      Pkg_Id : RTU_Id := RTU_Null;
1619
 
1620
   begin
1621
      pragma Assert (Is_Concurrent_Type (Typ));
1622
 
1623
      if Ekind (Typ) in Protected_Kind then
1624
         if Has_Entries (Typ)
1625
 
1626
            --  A protected type without entries that covers an interface and
1627
            --  overrides the abstract routines with protected procedures is
1628
            --  considered equivalent to a protected type with entries in the
1629
            --  context of dispatching select statements. It is sufficient to
1630
            --  check for the presence of an interface list in the declaration
1631
            --  node to recognize this case.
1632
 
1633
           or else Present (Interface_List (Parent (Typ)))
1634
           or else
1635
             (((Has_Attach_Handler (Typ) and then not Restricted_Profile)
1636
                 or else Has_Interrupt_Handler (Typ))
1637
               and then not Restriction_Active (No_Dynamic_Attachment))
1638
         then
1639
            if Abort_Allowed
1640
              or else Restriction_Active (No_Entry_Queue) = False
1641
              or else Number_Entries (Typ) > 1
1642
              or else (Has_Attach_Handler (Typ)
1643
                        and then not Restricted_Profile)
1644
            then
1645
               Pkg_Id := System_Tasking_Protected_Objects_Entries;
1646
            else
1647
               Pkg_Id := System_Tasking_Protected_Objects_Single_Entry;
1648
            end if;
1649
 
1650
         else
1651
            Pkg_Id := System_Tasking_Protected_Objects;
1652
         end if;
1653
      end if;
1654
 
1655
      return Pkg_Id;
1656
   end Corresponding_Runtime_Package;
1657
 
1658
   -------------------------------
1659
   -- Convert_To_Actual_Subtype --
1660
   -------------------------------
1661
 
1662
   procedure Convert_To_Actual_Subtype (Exp : Entity_Id) is
1663
      Act_ST : Entity_Id;
1664
 
1665
   begin
1666
      Act_ST := Get_Actual_Subtype (Exp);
1667
 
1668
      if Act_ST = Etype (Exp) then
1669
         return;
1670
      else
1671
         Rewrite (Exp, Convert_To (Act_ST, Relocate_Node (Exp)));
1672
         Analyze_And_Resolve (Exp, Act_ST);
1673
      end if;
1674
   end Convert_To_Actual_Subtype;
1675
 
1676
   -----------------------------------
1677
   -- Current_Sem_Unit_Declarations --
1678
   -----------------------------------
1679
 
1680
   function Current_Sem_Unit_Declarations return List_Id is
1681
      U     : Node_Id := Unit (Cunit (Current_Sem_Unit));
1682
      Decls : List_Id;
1683
 
1684
   begin
1685
      --  If the current unit is a package body, locate the visible
1686
      --  declarations of the package spec.
1687
 
1688
      if Nkind (U) = N_Package_Body then
1689
         U := Unit (Library_Unit (Cunit (Current_Sem_Unit)));
1690
      end if;
1691
 
1692
      if Nkind (U) = N_Package_Declaration then
1693
         U := Specification (U);
1694
         Decls := Visible_Declarations (U);
1695
 
1696
         if No (Decls) then
1697
            Decls := New_List;
1698
            Set_Visible_Declarations (U, Decls);
1699
         end if;
1700
 
1701
      else
1702
         Decls := Declarations (U);
1703
 
1704
         if No (Decls) then
1705
            Decls := New_List;
1706
            Set_Declarations (U, Decls);
1707
         end if;
1708
      end if;
1709
 
1710
      return Decls;
1711
   end Current_Sem_Unit_Declarations;
1712
 
1713
   -----------------------
1714
   -- Duplicate_Subexpr --
1715
   -----------------------
1716
 
1717
   function Duplicate_Subexpr
1718
     (Exp      : Node_Id;
1719
      Name_Req : Boolean := False) return Node_Id
1720
   is
1721
   begin
1722
      Remove_Side_Effects (Exp, Name_Req);
1723
      return New_Copy_Tree (Exp);
1724
   end Duplicate_Subexpr;
1725
 
1726
   ---------------------------------
1727
   -- Duplicate_Subexpr_No_Checks --
1728
   ---------------------------------
1729
 
1730
   function Duplicate_Subexpr_No_Checks
1731
     (Exp      : Node_Id;
1732
      Name_Req : Boolean := False) return Node_Id
1733
   is
1734
      New_Exp : Node_Id;
1735
 
1736
   begin
1737
      Remove_Side_Effects (Exp, Name_Req);
1738
      New_Exp := New_Copy_Tree (Exp);
1739
      Remove_Checks (New_Exp);
1740
      return New_Exp;
1741
   end Duplicate_Subexpr_No_Checks;
1742
 
1743
   -----------------------------------
1744
   -- Duplicate_Subexpr_Move_Checks --
1745
   -----------------------------------
1746
 
1747
   function Duplicate_Subexpr_Move_Checks
1748
     (Exp      : Node_Id;
1749
      Name_Req : Boolean := False) return Node_Id
1750
   is
1751
      New_Exp : Node_Id;
1752
   begin
1753
      Remove_Side_Effects (Exp, Name_Req);
1754
      New_Exp := New_Copy_Tree (Exp);
1755
      Remove_Checks (Exp);
1756
      return New_Exp;
1757
   end Duplicate_Subexpr_Move_Checks;
1758
 
1759
   --------------------
1760
   -- Ensure_Defined --
1761
   --------------------
1762
 
1763
   procedure Ensure_Defined (Typ : Entity_Id; N : Node_Id) is
1764
      IR : Node_Id;
1765
 
1766
   begin
1767
      --  An itype reference must only be created if this is a local itype, so
1768
      --  that gigi can elaborate it on the proper objstack.
1769
 
1770
      if Is_Itype (Typ)
1771
        and then Scope (Typ) = Current_Scope
1772
      then
1773
         IR := Make_Itype_Reference (Sloc (N));
1774
         Set_Itype (IR, Typ);
1775
         Insert_Action (N, IR);
1776
      end if;
1777
   end Ensure_Defined;
1778
 
1779
   --------------------
1780
   -- Entry_Names_OK --
1781
   --------------------
1782
 
1783
   function Entry_Names_OK return Boolean is
1784
   begin
1785
      return
1786
        not Restricted_Profile
1787
          and then not Global_Discard_Names
1788
          and then not Restriction_Active (No_Implicit_Heap_Allocations)
1789
          and then not Restriction_Active (No_Local_Allocators);
1790
   end Entry_Names_OK;
1791
 
1792
   -------------------
1793
   -- Evaluate_Name --
1794
   -------------------
1795
 
1796
   procedure Evaluate_Name (Nam : Node_Id) is
1797
      K : constant Node_Kind := Nkind (Nam);
1798
 
1799
   begin
1800
      --  For an explicit dereference, we simply force the evaluation of the
1801
      --  name expression. The dereference provides a value that is the address
1802
      --  for the renamed object, and it is precisely this value that we want
1803
      --  to preserve.
1804
 
1805
      if K = N_Explicit_Dereference then
1806
         Force_Evaluation (Prefix (Nam));
1807
 
1808
      --  For a selected component, we simply evaluate the prefix
1809
 
1810
      elsif K = N_Selected_Component then
1811
         Evaluate_Name (Prefix (Nam));
1812
 
1813
      --  For an indexed component, or an attribute reference, we evaluate the
1814
      --  prefix, which is itself a name, recursively, and then force the
1815
      --  evaluation of all the subscripts (or attribute expressions).
1816
 
1817
      elsif Nkind_In (K, N_Indexed_Component, N_Attribute_Reference) then
1818
         Evaluate_Name (Prefix (Nam));
1819
 
1820
         declare
1821
            E : Node_Id;
1822
 
1823
         begin
1824
            E := First (Expressions (Nam));
1825
            while Present (E) loop
1826
               Force_Evaluation (E);
1827
 
1828
               if Original_Node (E) /= E then
1829
                  Set_Do_Range_Check (E, Do_Range_Check (Original_Node (E)));
1830
               end if;
1831
 
1832
               Next (E);
1833
            end loop;
1834
         end;
1835
 
1836
      --  For a slice, we evaluate the prefix, as for the indexed component
1837
      --  case and then, if there is a range present, either directly or as the
1838
      --  constraint of a discrete subtype indication, we evaluate the two
1839
      --  bounds of this range.
1840
 
1841
      elsif K = N_Slice then
1842
         Evaluate_Name (Prefix (Nam));
1843
 
1844
         declare
1845
            DR     : constant Node_Id := Discrete_Range (Nam);
1846
            Constr : Node_Id;
1847
            Rexpr  : Node_Id;
1848
 
1849
         begin
1850
            if Nkind (DR) = N_Range then
1851
               Force_Evaluation (Low_Bound (DR));
1852
               Force_Evaluation (High_Bound (DR));
1853
 
1854
            elsif Nkind (DR) = N_Subtype_Indication then
1855
               Constr := Constraint (DR);
1856
 
1857
               if Nkind (Constr) = N_Range_Constraint then
1858
                  Rexpr := Range_Expression (Constr);
1859
 
1860
                  Force_Evaluation (Low_Bound (Rexpr));
1861
                  Force_Evaluation (High_Bound (Rexpr));
1862
               end if;
1863
            end if;
1864
         end;
1865
 
1866
      --  For a type conversion, the expression of the conversion must be the
1867
      --  name of an object, and we simply need to evaluate this name.
1868
 
1869
      elsif K = N_Type_Conversion then
1870
         Evaluate_Name (Expression (Nam));
1871
 
1872
      --  For a function call, we evaluate the call
1873
 
1874
      elsif K = N_Function_Call then
1875
         Force_Evaluation (Nam);
1876
 
1877
      --  The remaining cases are direct name, operator symbol and character
1878
      --  literal. In all these cases, we do nothing, since we want to
1879
      --  reevaluate each time the renamed object is used.
1880
 
1881
      else
1882
         return;
1883
      end if;
1884
   end Evaluate_Name;
1885
 
1886
   ---------------------
1887
   -- Evolve_And_Then --
1888
   ---------------------
1889
 
1890
   procedure Evolve_And_Then (Cond : in out Node_Id; Cond1 : Node_Id) is
1891
   begin
1892
      if No (Cond) then
1893
         Cond := Cond1;
1894
      else
1895
         Cond :=
1896
           Make_And_Then (Sloc (Cond1),
1897
             Left_Opnd  => Cond,
1898
             Right_Opnd => Cond1);
1899
      end if;
1900
   end Evolve_And_Then;
1901
 
1902
   --------------------
1903
   -- Evolve_Or_Else --
1904
   --------------------
1905
 
1906
   procedure Evolve_Or_Else (Cond : in out Node_Id; Cond1 : Node_Id) is
1907
   begin
1908
      if No (Cond) then
1909
         Cond := Cond1;
1910
      else
1911
         Cond :=
1912
           Make_Or_Else (Sloc (Cond1),
1913
             Left_Opnd  => Cond,
1914
             Right_Opnd => Cond1);
1915
      end if;
1916
   end Evolve_Or_Else;
1917
 
1918
   ------------------------------
1919
   -- Expand_Subtype_From_Expr --
1920
   ------------------------------
1921
 
1922
   --  This function is applicable for both static and dynamic allocation of
1923
   --  objects which are constrained by an initial expression. Basically it
1924
   --  transforms an unconstrained subtype indication into a constrained one.
1925
 
1926
   --  The expression may also be transformed in certain cases in order to
1927
   --  avoid multiple evaluation. In the static allocation case, the general
1928
   --  scheme is:
1929
 
1930
   --     Val : T := Expr;
1931
 
1932
   --        is transformed into
1933
 
1934
   --     Val : Constrained_Subtype_of_T := Maybe_Modified_Expr;
1935
   --
1936
   --  Here are the main cases :
1937
   --
1938
   --  <if Expr is a Slice>
1939
   --    Val : T ([Index_Subtype (Expr)]) := Expr;
1940
   --
1941
   --  <elsif Expr is a String Literal>
1942
   --    Val : T (T'First .. T'First + Length (string literal) - 1) := Expr;
1943
   --
1944
   --  <elsif Expr is Constrained>
1945
   --    subtype T is Type_Of_Expr
1946
   --    Val : T := Expr;
1947
   --
1948
   --  <elsif Expr is an entity_name>
1949
   --    Val : T (constraints taken from Expr) := Expr;
1950
   --
1951
   --  <else>
1952
   --    type Axxx is access all T;
1953
   --    Rval : Axxx := Expr'ref;
1954
   --    Val  : T (constraints taken from Rval) := Rval.all;
1955
 
1956
   --    ??? note: when the Expression is allocated in the secondary stack
1957
   --              we could use it directly instead of copying it by declaring
1958
   --              Val : T (...) renames Rval.all
1959
 
1960
   procedure Expand_Subtype_From_Expr
1961
     (N             : Node_Id;
1962
      Unc_Type      : Entity_Id;
1963
      Subtype_Indic : Node_Id;
1964
      Exp           : Node_Id)
1965
   is
1966
      Loc     : constant Source_Ptr := Sloc (N);
1967
      Exp_Typ : constant Entity_Id  := Etype (Exp);
1968
      T       : Entity_Id;
1969
 
1970
   begin
1971
      --  In general we cannot build the subtype if expansion is disabled,
1972
      --  because internal entities may not have been defined. However, to
1973
      --  avoid some cascaded errors, we try to continue when the expression is
1974
      --  an array (or string), because it is safe to compute the bounds. It is
1975
      --  in fact required to do so even in a generic context, because there
1976
      --  may be constants that depend on the bounds of a string literal, both
1977
      --  standard string types and more generally arrays of characters.
1978
 
1979
      if not Expander_Active
1980
        and then (No (Etype (Exp))
1981
                   or else not Is_String_Type (Etype (Exp)))
1982
      then
1983
         return;
1984
      end if;
1985
 
1986
      if Nkind (Exp) = N_Slice then
1987
         declare
1988
            Slice_Type : constant Entity_Id := Etype (First_Index (Exp_Typ));
1989
 
1990
         begin
1991
            Rewrite (Subtype_Indic,
1992
              Make_Subtype_Indication (Loc,
1993
                Subtype_Mark => New_Reference_To (Unc_Type, Loc),
1994
                Constraint =>
1995
                  Make_Index_Or_Discriminant_Constraint (Loc,
1996
                    Constraints => New_List
1997
                      (New_Reference_To (Slice_Type, Loc)))));
1998
 
1999
            --  This subtype indication may be used later for constraint checks
2000
            --  we better make sure that if a variable was used as a bound of
2001
            --  of the original slice, its value is frozen.
2002
 
2003
            Force_Evaluation (Low_Bound (Scalar_Range (Slice_Type)));
2004
            Force_Evaluation (High_Bound (Scalar_Range (Slice_Type)));
2005
         end;
2006
 
2007
      elsif Ekind (Exp_Typ) = E_String_Literal_Subtype then
2008
         Rewrite (Subtype_Indic,
2009
           Make_Subtype_Indication (Loc,
2010
             Subtype_Mark => New_Reference_To (Unc_Type, Loc),
2011
             Constraint =>
2012
               Make_Index_Or_Discriminant_Constraint (Loc,
2013
                 Constraints => New_List (
2014
                   Make_Literal_Range (Loc,
2015
                     Literal_Typ => Exp_Typ)))));
2016
 
2017
      elsif Is_Constrained (Exp_Typ)
2018
        and then not Is_Class_Wide_Type (Unc_Type)
2019
      then
2020
         if Is_Itype (Exp_Typ) then
2021
 
2022
            --  Within an initialization procedure, a selected component
2023
            --  denotes a component of the enclosing record, and it appears as
2024
            --  an actual in a call to its own initialization procedure. If
2025
            --  this component depends on the outer discriminant, we must
2026
            --  generate the proper actual subtype for it.
2027
 
2028
            if Nkind (Exp) = N_Selected_Component
2029
              and then Within_Init_Proc
2030
            then
2031
               declare
2032
                  Decl : constant Node_Id :=
2033
                           Build_Actual_Subtype_Of_Component (Exp_Typ, Exp);
2034
               begin
2035
                  if Present (Decl) then
2036
                     Insert_Action (N, Decl);
2037
                     T := Defining_Identifier (Decl);
2038
                  else
2039
                     T := Exp_Typ;
2040
                  end if;
2041
               end;
2042
 
2043
            --  No need to generate a new one (new what???)
2044
 
2045
            else
2046
               T := Exp_Typ;
2047
            end if;
2048
 
2049
         else
2050
            T := Make_Temporary (Loc, 'T');
2051
 
2052
            Insert_Action (N,
2053
              Make_Subtype_Declaration (Loc,
2054
                Defining_Identifier => T,
2055
                Subtype_Indication  => New_Reference_To (Exp_Typ, Loc)));
2056
 
2057
            --  This type is marked as an itype even though it has an explicit
2058
            --  declaration since otherwise Is_Generic_Actual_Type can get
2059
            --  set, resulting in the generation of spurious errors. (See
2060
            --  sem_ch8.Analyze_Package_Renaming and sem_type.covers)
2061
 
2062
            Set_Is_Itype (T);
2063
            Set_Associated_Node_For_Itype (T, Exp);
2064
         end if;
2065
 
2066
         Rewrite (Subtype_Indic, New_Reference_To (T, Loc));
2067
 
2068
      --  Nothing needs to be done for private types with unknown discriminants
2069
      --  if the underlying type is not an unconstrained composite type or it
2070
      --  is an unchecked union.
2071
 
2072
      elsif Is_Private_Type (Unc_Type)
2073
        and then Has_Unknown_Discriminants (Unc_Type)
2074
        and then (not Is_Composite_Type (Underlying_Type (Unc_Type))
2075
                   or else Is_Constrained (Underlying_Type (Unc_Type))
2076
                   or else Is_Unchecked_Union (Underlying_Type (Unc_Type)))
2077
      then
2078
         null;
2079
 
2080
      --  Case of derived type with unknown discriminants where the parent type
2081
      --  also has unknown discriminants.
2082
 
2083
      elsif Is_Record_Type (Unc_Type)
2084
        and then not Is_Class_Wide_Type (Unc_Type)
2085
        and then Has_Unknown_Discriminants (Unc_Type)
2086
        and then Has_Unknown_Discriminants (Underlying_Type (Unc_Type))
2087
      then
2088
         --  Nothing to be done if no underlying record view available
2089
 
2090
         if No (Underlying_Record_View (Unc_Type)) then
2091
            null;
2092
 
2093
         --  Otherwise use the Underlying_Record_View to create the proper
2094
         --  constrained subtype for an object of a derived type with unknown
2095
         --  discriminants.
2096
 
2097
         else
2098
            Remove_Side_Effects (Exp);
2099
            Rewrite (Subtype_Indic,
2100
              Make_Subtype_From_Expr (Exp, Underlying_Record_View (Unc_Type)));
2101
         end if;
2102
 
2103
      --  Renamings of class-wide interface types require no equivalent
2104
      --  constrained type declarations because we only need to reference
2105
      --  the tag component associated with the interface. The same is
2106
      --  presumably true for class-wide types in general, so this test
2107
      --  is broadened to include all class-wide renamings, which also
2108
      --  avoids cases of unbounded recursion in Remove_Side_Effects.
2109
      --  (Is this really correct, or are there some cases of class-wide
2110
      --  renamings that require action in this procedure???)
2111
 
2112
      elsif Present (N)
2113
        and then Nkind (N) = N_Object_Renaming_Declaration
2114
        and then Is_Class_Wide_Type (Unc_Type)
2115
      then
2116
         null;
2117
 
2118
      --  In Ada 95 nothing to be done if the type of the expression is limited
2119
      --  because in this case the expression cannot be copied, and its use can
2120
      --  only be by reference.
2121
 
2122
      --  In Ada 2005 the context can be an object declaration whose expression
2123
      --  is a function that returns in place. If the nominal subtype has
2124
      --  unknown discriminants, the call still provides constraints on the
2125
      --  object, and we have to create an actual subtype from it.
2126
 
2127
      --  If the type is class-wide, the expression is dynamically tagged and
2128
      --  we do not create an actual subtype either. Ditto for an interface.
2129
      --  For now this applies only if the type is immutably limited, and the
2130
      --  function being called is build-in-place. This will have to be revised
2131
      --  when build-in-place functions are generalized to other types.
2132
 
2133
      elsif Is_Immutably_Limited_Type (Exp_Typ)
2134
        and then
2135
         (Is_Class_Wide_Type (Exp_Typ)
2136
           or else Is_Interface (Exp_Typ)
2137
           or else not Has_Unknown_Discriminants (Exp_Typ)
2138
           or else not Is_Composite_Type (Unc_Type))
2139
      then
2140
         null;
2141
 
2142
      --  For limited objects initialized with build in place function calls,
2143
      --  nothing to be done; otherwise we prematurely introduce an N_Reference
2144
      --  node in the expression initializing the object, which breaks the
2145
      --  circuitry that detects and adds the additional arguments to the
2146
      --  called function.
2147
 
2148
      elsif Is_Build_In_Place_Function_Call (Exp) then
2149
         null;
2150
 
2151
      else
2152
         Remove_Side_Effects (Exp);
2153
         Rewrite (Subtype_Indic,
2154
           Make_Subtype_From_Expr (Exp, Unc_Type));
2155
      end if;
2156
   end Expand_Subtype_From_Expr;
2157
 
2158
   --------------------
2159
   -- Find_Init_Call --
2160
   --------------------
2161
 
2162
   function Find_Init_Call
2163
     (Var        : Entity_Id;
2164
      Rep_Clause : Node_Id) return Node_Id
2165
   is
2166
      Typ : constant Entity_Id := Etype (Var);
2167
 
2168
      Init_Proc : Entity_Id;
2169
      --  Initialization procedure for Typ
2170
 
2171
      function Find_Init_Call_In_List (From : Node_Id) return Node_Id;
2172
      --  Look for init call for Var starting at From and scanning the
2173
      --  enclosing list until Rep_Clause or the end of the list is reached.
2174
 
2175
      ----------------------------
2176
      -- Find_Init_Call_In_List --
2177
      ----------------------------
2178
 
2179
      function Find_Init_Call_In_List (From : Node_Id) return Node_Id is
2180
         Init_Call : Node_Id;
2181
      begin
2182
         Init_Call := From;
2183
 
2184
         while Present (Init_Call) and then Init_Call /= Rep_Clause loop
2185
            if Nkind (Init_Call) = N_Procedure_Call_Statement
2186
              and then Is_Entity_Name (Name (Init_Call))
2187
              and then Entity (Name (Init_Call)) = Init_Proc
2188
            then
2189
               return Init_Call;
2190
            end if;
2191
 
2192
            Next (Init_Call);
2193
         end loop;
2194
 
2195
         return Empty;
2196
      end Find_Init_Call_In_List;
2197
 
2198
      Init_Call : Node_Id;
2199
 
2200
   --  Start of processing for Find_Init_Call
2201
 
2202
   begin
2203
      if not Has_Non_Null_Base_Init_Proc (Typ) then
2204
         --  No init proc for the type, so obviously no call to be found
2205
 
2206
         return Empty;
2207
      end if;
2208
 
2209
      Init_Proc := Base_Init_Proc (Typ);
2210
 
2211
      --  First scan the list containing the declaration of Var
2212
 
2213
      Init_Call := Find_Init_Call_In_List (From => Next (Parent (Var)));
2214
 
2215
      --  If not found, also look on Var's freeze actions list, if any, since
2216
      --  the init call may have been moved there (case of an address clause
2217
      --  applying to Var).
2218
 
2219
      if No (Init_Call) and then Present (Freeze_Node (Var)) then
2220
         Init_Call :=
2221
           Find_Init_Call_In_List (First (Actions (Freeze_Node (Var))));
2222
      end if;
2223
 
2224
      return Init_Call;
2225
   end Find_Init_Call;
2226
 
2227
   ------------------------
2228
   -- Find_Interface_ADT --
2229
   ------------------------
2230
 
2231
   function Find_Interface_ADT
2232
     (T     : Entity_Id;
2233
      Iface : Entity_Id) return Elmt_Id
2234
   is
2235
      ADT : Elmt_Id;
2236
      Typ : Entity_Id := T;
2237
 
2238
   begin
2239
      pragma Assert (Is_Interface (Iface));
2240
 
2241
      --  Handle private types
2242
 
2243
      if Has_Private_Declaration (Typ)
2244
        and then Present (Full_View (Typ))
2245
      then
2246
         Typ := Full_View (Typ);
2247
      end if;
2248
 
2249
      --  Handle access types
2250
 
2251
      if Is_Access_Type (Typ) then
2252
         Typ := Designated_Type (Typ);
2253
      end if;
2254
 
2255
      --  Handle task and protected types implementing interfaces
2256
 
2257
      if Is_Concurrent_Type (Typ) then
2258
         Typ := Corresponding_Record_Type (Typ);
2259
      end if;
2260
 
2261
      pragma Assert
2262
        (not Is_Class_Wide_Type (Typ)
2263
          and then Ekind (Typ) /= E_Incomplete_Type);
2264
 
2265
      if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
2266
         return First_Elmt (Access_Disp_Table (Typ));
2267
 
2268
      else
2269
         ADT :=
2270
           Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
2271
         while Present (ADT)
2272
           and then Present (Related_Type (Node (ADT)))
2273
           and then Related_Type (Node (ADT)) /= Iface
2274
           and then not Is_Ancestor (Iface, Related_Type (Node (ADT)),
2275
                                     Use_Full_View => True)
2276
         loop
2277
            Next_Elmt (ADT);
2278
         end loop;
2279
 
2280
         pragma Assert (Present (Related_Type (Node (ADT))));
2281
         return ADT;
2282
      end if;
2283
   end Find_Interface_ADT;
2284
 
2285
   ------------------------
2286
   -- Find_Interface_Tag --
2287
   ------------------------
2288
 
2289
   function Find_Interface_Tag
2290
     (T     : Entity_Id;
2291
      Iface : Entity_Id) return Entity_Id
2292
   is
2293
      AI_Tag : Entity_Id;
2294
      Found  : Boolean   := False;
2295
      Typ    : Entity_Id := T;
2296
 
2297
      procedure Find_Tag (Typ : Entity_Id);
2298
      --  Internal subprogram used to recursively climb to the ancestors
2299
 
2300
      --------------
2301
      -- Find_Tag --
2302
      --------------
2303
 
2304
      procedure Find_Tag (Typ : Entity_Id) is
2305
         AI_Elmt : Elmt_Id;
2306
         AI      : Node_Id;
2307
 
2308
      begin
2309
         --  This routine does not handle the case in which the interface is an
2310
         --  ancestor of Typ. That case is handled by the enclosing subprogram.
2311
 
2312
         pragma Assert (Typ /= Iface);
2313
 
2314
         --  Climb to the root type handling private types
2315
 
2316
         if Present (Full_View (Etype (Typ))) then
2317
            if Full_View (Etype (Typ)) /= Typ then
2318
               Find_Tag (Full_View (Etype (Typ)));
2319
            end if;
2320
 
2321
         elsif Etype (Typ) /= Typ then
2322
            Find_Tag (Etype (Typ));
2323
         end if;
2324
 
2325
         --  Traverse the list of interfaces implemented by the type
2326
 
2327
         if not Found
2328
           and then Present (Interfaces (Typ))
2329
           and then not (Is_Empty_Elmt_List (Interfaces (Typ)))
2330
         then
2331
            --  Skip the tag associated with the primary table
2332
 
2333
            pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
2334
            AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
2335
            pragma Assert (Present (AI_Tag));
2336
 
2337
            AI_Elmt := First_Elmt (Interfaces (Typ));
2338
            while Present (AI_Elmt) loop
2339
               AI := Node (AI_Elmt);
2340
 
2341
               if AI = Iface
2342
                 or else Is_Ancestor (Iface, AI, Use_Full_View => True)
2343
               then
2344
                  Found := True;
2345
                  return;
2346
               end if;
2347
 
2348
               AI_Tag := Next_Tag_Component (AI_Tag);
2349
               Next_Elmt (AI_Elmt);
2350
            end loop;
2351
         end if;
2352
      end Find_Tag;
2353
 
2354
   --  Start of processing for Find_Interface_Tag
2355
 
2356
   begin
2357
      pragma Assert (Is_Interface (Iface));
2358
 
2359
      --  Handle access types
2360
 
2361
      if Is_Access_Type (Typ) then
2362
         Typ := Designated_Type (Typ);
2363
      end if;
2364
 
2365
      --  Handle class-wide types
2366
 
2367
      if Is_Class_Wide_Type (Typ) then
2368
         Typ := Root_Type (Typ);
2369
      end if;
2370
 
2371
      --  Handle private types
2372
 
2373
      if Has_Private_Declaration (Typ)
2374
        and then Present (Full_View (Typ))
2375
      then
2376
         Typ := Full_View (Typ);
2377
      end if;
2378
 
2379
      --  Handle entities from the limited view
2380
 
2381
      if Ekind (Typ) = E_Incomplete_Type then
2382
         pragma Assert (Present (Non_Limited_View (Typ)));
2383
         Typ := Non_Limited_View (Typ);
2384
      end if;
2385
 
2386
      --  Handle task and protected types implementing interfaces
2387
 
2388
      if Is_Concurrent_Type (Typ) then
2389
         Typ := Corresponding_Record_Type (Typ);
2390
      end if;
2391
 
2392
      --  If the interface is an ancestor of the type, then it shared the
2393
      --  primary dispatch table.
2394
 
2395
      if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
2396
         pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
2397
         return First_Tag_Component (Typ);
2398
 
2399
      --  Otherwise we need to search for its associated tag component
2400
 
2401
      else
2402
         Find_Tag (Typ);
2403
         pragma Assert (Found);
2404
         return AI_Tag;
2405
      end if;
2406
   end Find_Interface_Tag;
2407
 
2408
   ------------------
2409
   -- Find_Prim_Op --
2410
   ------------------
2411
 
2412
   function Find_Prim_Op (T : Entity_Id; Name : Name_Id) return Entity_Id is
2413
      Prim : Elmt_Id;
2414
      Typ  : Entity_Id := T;
2415
      Op   : Entity_Id;
2416
 
2417
   begin
2418
      if Is_Class_Wide_Type (Typ) then
2419
         Typ := Root_Type (Typ);
2420
      end if;
2421
 
2422
      Typ := Underlying_Type (Typ);
2423
 
2424
      --  Loop through primitive operations
2425
 
2426
      Prim := First_Elmt (Primitive_Operations (Typ));
2427
      while Present (Prim) loop
2428
         Op := Node (Prim);
2429
 
2430
         --  We can retrieve primitive operations by name if it is an internal
2431
         --  name. For equality we must check that both of its operands have
2432
         --  the same type, to avoid confusion with user-defined equalities
2433
         --  than may have a non-symmetric signature.
2434
 
2435
         exit when Chars (Op) = Name
2436
           and then
2437
             (Name /= Name_Op_Eq
2438
                or else Etype (First_Formal (Op)) = Etype (Last_Formal (Op)));
2439
 
2440
         Next_Elmt (Prim);
2441
 
2442
         --  Raise Program_Error if no primitive found
2443
 
2444
         if No (Prim) then
2445
            raise Program_Error;
2446
         end if;
2447
      end loop;
2448
 
2449
      return Node (Prim);
2450
   end Find_Prim_Op;
2451
 
2452
   ------------------
2453
   -- Find_Prim_Op --
2454
   ------------------
2455
 
2456
   function Find_Prim_Op
2457
     (T    : Entity_Id;
2458
      Name : TSS_Name_Type) return Entity_Id
2459
   is
2460
      Inher_Op  : Entity_Id := Empty;
2461
      Own_Op    : Entity_Id := Empty;
2462
      Prim_Elmt : Elmt_Id;
2463
      Prim_Id   : Entity_Id;
2464
      Typ       : Entity_Id := T;
2465
 
2466
   begin
2467
      if Is_Class_Wide_Type (Typ) then
2468
         Typ := Root_Type (Typ);
2469
      end if;
2470
 
2471
      Typ := Underlying_Type (Typ);
2472
 
2473
      --  This search is based on the assertion that the dispatching version
2474
      --  of the TSS routine always precedes the real primitive.
2475
 
2476
      Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2477
      while Present (Prim_Elmt) loop
2478
         Prim_Id := Node (Prim_Elmt);
2479
 
2480
         if Is_TSS (Prim_Id, Name) then
2481
            if Present (Alias (Prim_Id)) then
2482
               Inher_Op := Prim_Id;
2483
            else
2484
               Own_Op := Prim_Id;
2485
            end if;
2486
         end if;
2487
 
2488
         Next_Elmt (Prim_Elmt);
2489
      end loop;
2490
 
2491
      if Present (Own_Op) then
2492
         return Own_Op;
2493
      elsif Present (Inher_Op) then
2494
         return Inher_Op;
2495
      else
2496
         raise Program_Error;
2497
      end if;
2498
   end Find_Prim_Op;
2499
 
2500
   ----------------------------
2501
   -- Find_Protection_Object --
2502
   ----------------------------
2503
 
2504
   function Find_Protection_Object (Scop : Entity_Id) return Entity_Id is
2505
      S : Entity_Id;
2506
 
2507
   begin
2508
      S := Scop;
2509
      while Present (S) loop
2510
         if (Ekind (S) = E_Entry
2511
               or else Ekind (S) = E_Entry_Family
2512
               or else Ekind (S) = E_Function
2513
               or else Ekind (S) = E_Procedure)
2514
           and then Present (Protection_Object (S))
2515
         then
2516
            return Protection_Object (S);
2517
         end if;
2518
 
2519
         S := Scope (S);
2520
      end loop;
2521
 
2522
      --  If we do not find a Protection object in the scope chain, then
2523
      --  something has gone wrong, most likely the object was never created.
2524
 
2525
      raise Program_Error;
2526
   end Find_Protection_Object;
2527
 
2528
   --------------------------
2529
   -- Find_Protection_Type --
2530
   --------------------------
2531
 
2532
   function Find_Protection_Type (Conc_Typ : Entity_Id) return Entity_Id is
2533
      Comp : Entity_Id;
2534
      Typ  : Entity_Id := Conc_Typ;
2535
 
2536
   begin
2537
      if Is_Concurrent_Type (Typ) then
2538
         Typ := Corresponding_Record_Type (Typ);
2539
      end if;
2540
 
2541
      --  Since restriction violations are not considered serious errors, the
2542
      --  expander remains active, but may leave the corresponding record type
2543
      --  malformed. In such cases, component _object is not available so do
2544
      --  not look for it.
2545
 
2546
      if not Analyzed (Typ) then
2547
         return Empty;
2548
      end if;
2549
 
2550
      Comp := First_Component (Typ);
2551
      while Present (Comp) loop
2552
         if Chars (Comp) = Name_uObject then
2553
            return Base_Type (Etype (Comp));
2554
         end if;
2555
 
2556
         Next_Component (Comp);
2557
      end loop;
2558
 
2559
      --  The corresponding record of a protected type should always have an
2560
      --  _object field.
2561
 
2562
      raise Program_Error;
2563
   end Find_Protection_Type;
2564
 
2565
   ----------------------
2566
   -- Force_Evaluation --
2567
   ----------------------
2568
 
2569
   procedure Force_Evaluation (Exp : Node_Id; Name_Req : Boolean := False) is
2570
   begin
2571
      Remove_Side_Effects (Exp, Name_Req, Variable_Ref => True);
2572
   end Force_Evaluation;
2573
 
2574
   ---------------------------------
2575
   -- Fully_Qualified_Name_String --
2576
   ---------------------------------
2577
 
2578
   function Fully_Qualified_Name_String (E : Entity_Id) return String_Id is
2579
      procedure Internal_Full_Qualified_Name (E : Entity_Id);
2580
      --  Compute recursively the qualified name without NUL at the end, adding
2581
      --  it to the currently started string being generated
2582
 
2583
      ----------------------------------
2584
      -- Internal_Full_Qualified_Name --
2585
      ----------------------------------
2586
 
2587
      procedure Internal_Full_Qualified_Name (E : Entity_Id) is
2588
         Ent : Entity_Id;
2589
 
2590
      begin
2591
         --  Deal properly with child units
2592
 
2593
         if Nkind (E) = N_Defining_Program_Unit_Name then
2594
            Ent := Defining_Identifier (E);
2595
         else
2596
            Ent := E;
2597
         end if;
2598
 
2599
         --  Compute qualification recursively (only "Standard" has no scope)
2600
 
2601
         if Present (Scope (Scope (Ent))) then
2602
            Internal_Full_Qualified_Name (Scope (Ent));
2603
            Store_String_Char (Get_Char_Code ('.'));
2604
         end if;
2605
 
2606
         --  Every entity should have a name except some expanded blocks
2607
         --  don't bother about those.
2608
 
2609
         if Chars (Ent) = No_Name then
2610
            return;
2611
         end if;
2612
 
2613
         --  Generates the entity name in upper case
2614
 
2615
         Get_Decoded_Name_String (Chars (Ent));
2616
         Set_All_Upper_Case;
2617
         Store_String_Chars (Name_Buffer (1 .. Name_Len));
2618
         return;
2619
      end Internal_Full_Qualified_Name;
2620
 
2621
   --  Start of processing for Full_Qualified_Name
2622
 
2623
   begin
2624
      Start_String;
2625
      Internal_Full_Qualified_Name (E);
2626
      Store_String_Char (Get_Char_Code (ASCII.NUL));
2627
      return End_String;
2628
   end Fully_Qualified_Name_String;
2629
 
2630
   ------------------------
2631
   -- Generate_Poll_Call --
2632
   ------------------------
2633
 
2634
   procedure Generate_Poll_Call (N : Node_Id) is
2635
   begin
2636
      --  No poll call if polling not active
2637
 
2638
      if not Polling_Required then
2639
         return;
2640
 
2641
      --  Otherwise generate require poll call
2642
 
2643
      else
2644
         Insert_Before_And_Analyze (N,
2645
           Make_Procedure_Call_Statement (Sloc (N),
2646
             Name => New_Occurrence_Of (RTE (RE_Poll), Sloc (N))));
2647
      end if;
2648
   end Generate_Poll_Call;
2649
 
2650
   ---------------------------------
2651
   -- Get_Current_Value_Condition --
2652
   ---------------------------------
2653
 
2654
   --  Note: the implementation of this procedure is very closely tied to the
2655
   --  implementation of Set_Current_Value_Condition. In the Get procedure, we
2656
   --  interpret Current_Value fields set by the Set procedure, so the two
2657
   --  procedures need to be closely coordinated.
2658
 
2659
   procedure Get_Current_Value_Condition
2660
     (Var : Node_Id;
2661
      Op  : out Node_Kind;
2662
      Val : out Node_Id)
2663
   is
2664
      Loc : constant Source_Ptr := Sloc (Var);
2665
      Ent : constant Entity_Id  := Entity (Var);
2666
 
2667
      procedure Process_Current_Value_Condition
2668
        (N : Node_Id;
2669
         S : Boolean);
2670
      --  N is an expression which holds either True (S = True) or False (S =
2671
      --  False) in the condition. This procedure digs out the expression and
2672
      --  if it refers to Ent, sets Op and Val appropriately.
2673
 
2674
      -------------------------------------
2675
      -- Process_Current_Value_Condition --
2676
      -------------------------------------
2677
 
2678
      procedure Process_Current_Value_Condition
2679
        (N : Node_Id;
2680
         S : Boolean)
2681
      is
2682
         Cond : Node_Id;
2683
         Sens : Boolean;
2684
 
2685
      begin
2686
         Cond := N;
2687
         Sens := S;
2688
 
2689
         --  Deal with NOT operators, inverting sense
2690
 
2691
         while Nkind (Cond) = N_Op_Not loop
2692
            Cond := Right_Opnd (Cond);
2693
            Sens := not Sens;
2694
         end loop;
2695
 
2696
         --  Deal with AND THEN and AND cases
2697
 
2698
         if Nkind (Cond) = N_And_Then
2699
           or else Nkind (Cond) = N_Op_And
2700
         then
2701
            --  Don't ever try to invert a condition that is of the form of an
2702
            --  AND or AND THEN (since we are not doing sufficiently general
2703
            --  processing to allow this).
2704
 
2705
            if Sens = False then
2706
               Op  := N_Empty;
2707
               Val := Empty;
2708
               return;
2709
            end if;
2710
 
2711
            --  Recursively process AND and AND THEN branches
2712
 
2713
            Process_Current_Value_Condition (Left_Opnd (Cond), True);
2714
 
2715
            if Op /= N_Empty then
2716
               return;
2717
            end if;
2718
 
2719
            Process_Current_Value_Condition (Right_Opnd (Cond), True);
2720
            return;
2721
 
2722
         --  Case of relational operator
2723
 
2724
         elsif Nkind (Cond) in N_Op_Compare then
2725
            Op := Nkind (Cond);
2726
 
2727
            --  Invert sense of test if inverted test
2728
 
2729
            if Sens = False then
2730
               case Op is
2731
                  when N_Op_Eq => Op := N_Op_Ne;
2732
                  when N_Op_Ne => Op := N_Op_Eq;
2733
                  when N_Op_Lt => Op := N_Op_Ge;
2734
                  when N_Op_Gt => Op := N_Op_Le;
2735
                  when N_Op_Le => Op := N_Op_Gt;
2736
                  when N_Op_Ge => Op := N_Op_Lt;
2737
                  when others  => raise Program_Error;
2738
               end case;
2739
            end if;
2740
 
2741
            --  Case of entity op value
2742
 
2743
            if Is_Entity_Name (Left_Opnd (Cond))
2744
              and then Ent = Entity (Left_Opnd (Cond))
2745
              and then Compile_Time_Known_Value (Right_Opnd (Cond))
2746
            then
2747
               Val := Right_Opnd (Cond);
2748
 
2749
            --  Case of value op entity
2750
 
2751
            elsif Is_Entity_Name (Right_Opnd (Cond))
2752
              and then Ent = Entity (Right_Opnd (Cond))
2753
              and then Compile_Time_Known_Value (Left_Opnd (Cond))
2754
            then
2755
               Val := Left_Opnd (Cond);
2756
 
2757
               --  We are effectively swapping operands
2758
 
2759
               case Op is
2760
                  when N_Op_Eq => null;
2761
                  when N_Op_Ne => null;
2762
                  when N_Op_Lt => Op := N_Op_Gt;
2763
                  when N_Op_Gt => Op := N_Op_Lt;
2764
                  when N_Op_Le => Op := N_Op_Ge;
2765
                  when N_Op_Ge => Op := N_Op_Le;
2766
                  when others  => raise Program_Error;
2767
               end case;
2768
 
2769
            else
2770
               Op := N_Empty;
2771
            end if;
2772
 
2773
            return;
2774
 
2775
            --  Case of Boolean variable reference, return as though the
2776
            --  reference had said var = True.
2777
 
2778
         else
2779
            if Is_Entity_Name (Cond)
2780
              and then Ent = Entity (Cond)
2781
            then
2782
               Val := New_Occurrence_Of (Standard_True, Sloc (Cond));
2783
 
2784
               if Sens = False then
2785
                  Op := N_Op_Ne;
2786
               else
2787
                  Op := N_Op_Eq;
2788
               end if;
2789
            end if;
2790
         end if;
2791
      end Process_Current_Value_Condition;
2792
 
2793
   --  Start of processing for Get_Current_Value_Condition
2794
 
2795
   begin
2796
      Op  := N_Empty;
2797
      Val := Empty;
2798
 
2799
      --  Immediate return, nothing doing, if this is not an object
2800
 
2801
      if Ekind (Ent) not in Object_Kind then
2802
         return;
2803
      end if;
2804
 
2805
      --  Otherwise examine current value
2806
 
2807
      declare
2808
         CV   : constant Node_Id := Current_Value (Ent);
2809
         Sens : Boolean;
2810
         Stm  : Node_Id;
2811
 
2812
      begin
2813
         --  If statement. Condition is known true in THEN section, known False
2814
         --  in any ELSIF or ELSE part, and unknown outside the IF statement.
2815
 
2816
         if Nkind (CV) = N_If_Statement then
2817
 
2818
            --  Before start of IF statement
2819
 
2820
            if Loc < Sloc (CV) then
2821
               return;
2822
 
2823
               --  After end of IF statement
2824
 
2825
            elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then
2826
               return;
2827
            end if;
2828
 
2829
            --  At this stage we know that we are within the IF statement, but
2830
            --  unfortunately, the tree does not record the SLOC of the ELSE so
2831
            --  we cannot use a simple SLOC comparison to distinguish between
2832
            --  the then/else statements, so we have to climb the tree.
2833
 
2834
            declare
2835
               N : Node_Id;
2836
 
2837
            begin
2838
               N := Parent (Var);
2839
               while Parent (N) /= CV loop
2840
                  N := Parent (N);
2841
 
2842
                  --  If we fall off the top of the tree, then that's odd, but
2843
                  --  perhaps it could occur in some error situation, and the
2844
                  --  safest response is simply to assume that the outcome of
2845
                  --  the condition is unknown. No point in bombing during an
2846
                  --  attempt to optimize things.
2847
 
2848
                  if No (N) then
2849
                     return;
2850
                  end if;
2851
               end loop;
2852
 
2853
               --  Now we have N pointing to a node whose parent is the IF
2854
               --  statement in question, so now we can tell if we are within
2855
               --  the THEN statements.
2856
 
2857
               if Is_List_Member (N)
2858
                 and then List_Containing (N) = Then_Statements (CV)
2859
               then
2860
                  Sens := True;
2861
 
2862
               --  If the variable reference does not come from source, we
2863
               --  cannot reliably tell whether it appears in the else part.
2864
               --  In particular, if it appears in generated code for a node
2865
               --  that requires finalization, it may be attached to a list
2866
               --  that has not been yet inserted into the code. For now,
2867
               --  treat it as unknown.
2868
 
2869
               elsif not Comes_From_Source (N) then
2870
                  return;
2871
 
2872
               --  Otherwise we must be in ELSIF or ELSE part
2873
 
2874
               else
2875
                  Sens := False;
2876
               end if;
2877
            end;
2878
 
2879
            --  ELSIF part. Condition is known true within the referenced
2880
            --  ELSIF, known False in any subsequent ELSIF or ELSE part,
2881
            --  and unknown before the ELSE part or after the IF statement.
2882
 
2883
         elsif Nkind (CV) = N_Elsif_Part then
2884
 
2885
            --  if the Elsif_Part had condition_actions, the elsif has been
2886
            --  rewritten as a nested if, and the original elsif_part is
2887
            --  detached from the tree, so there is no way to obtain useful
2888
            --  information on the current value of the variable.
2889
            --  Can this be improved ???
2890
 
2891
            if No (Parent (CV)) then
2892
               return;
2893
            end if;
2894
 
2895
            Stm := Parent (CV);
2896
 
2897
            --  Before start of ELSIF part
2898
 
2899
            if Loc < Sloc (CV) then
2900
               return;
2901
 
2902
               --  After end of IF statement
2903
 
2904
            elsif Loc >= Sloc (Stm) +
2905
              Text_Ptr (UI_To_Int (End_Span (Stm)))
2906
            then
2907
               return;
2908
            end if;
2909
 
2910
            --  Again we lack the SLOC of the ELSE, so we need to climb the
2911
            --  tree to see if we are within the ELSIF part in question.
2912
 
2913
            declare
2914
               N : Node_Id;
2915
 
2916
            begin
2917
               N := Parent (Var);
2918
               while Parent (N) /= Stm loop
2919
                  N := Parent (N);
2920
 
2921
                  --  If we fall off the top of the tree, then that's odd, but
2922
                  --  perhaps it could occur in some error situation, and the
2923
                  --  safest response is simply to assume that the outcome of
2924
                  --  the condition is unknown. No point in bombing during an
2925
                  --  attempt to optimize things.
2926
 
2927
                  if No (N) then
2928
                     return;
2929
                  end if;
2930
               end loop;
2931
 
2932
               --  Now we have N pointing to a node whose parent is the IF
2933
               --  statement in question, so see if is the ELSIF part we want.
2934
               --  the THEN statements.
2935
 
2936
               if N = CV then
2937
                  Sens := True;
2938
 
2939
                  --  Otherwise we must be in subsequent ELSIF or ELSE part
2940
 
2941
               else
2942
                  Sens := False;
2943
               end if;
2944
            end;
2945
 
2946
         --  Iteration scheme of while loop. The condition is known to be
2947
         --  true within the body of the loop.
2948
 
2949
         elsif Nkind (CV) = N_Iteration_Scheme then
2950
            declare
2951
               Loop_Stmt : constant Node_Id := Parent (CV);
2952
 
2953
            begin
2954
               --  Before start of body of loop
2955
 
2956
               if Loc < Sloc (Loop_Stmt) then
2957
                  return;
2958
 
2959
               --  After end of LOOP statement
2960
 
2961
               elsif Loc >= Sloc (End_Label (Loop_Stmt)) then
2962
                  return;
2963
 
2964
               --  We are within the body of the loop
2965
 
2966
               else
2967
                  Sens := True;
2968
               end if;
2969
            end;
2970
 
2971
         --  All other cases of Current_Value settings
2972
 
2973
         else
2974
            return;
2975
         end if;
2976
 
2977
         --  If we fall through here, then we have a reportable condition, Sens
2978
         --  is True if the condition is true and False if it needs inverting.
2979
 
2980
         Process_Current_Value_Condition (Condition (CV), Sens);
2981
      end;
2982
   end Get_Current_Value_Condition;
2983
 
2984
   ---------------------
2985
   -- Get_Stream_Size --
2986
   ---------------------
2987
 
2988
   function Get_Stream_Size (E : Entity_Id) return Uint is
2989
   begin
2990
      --  If we have a Stream_Size clause for this type use it
2991
 
2992
      if Has_Stream_Size_Clause (E) then
2993
         return Static_Integer (Expression (Stream_Size_Clause (E)));
2994
 
2995
      --  Otherwise the Stream_Size if the size of the type
2996
 
2997
      else
2998
         return Esize (E);
2999
      end if;
3000
   end Get_Stream_Size;
3001
 
3002
   ---------------------------
3003
   -- Has_Access_Constraint --
3004
   ---------------------------
3005
 
3006
   function Has_Access_Constraint (E : Entity_Id) return Boolean is
3007
      Disc : Entity_Id;
3008
      T    : constant Entity_Id := Etype (E);
3009
 
3010
   begin
3011
      if Has_Per_Object_Constraint (E)
3012
        and then Has_Discriminants (T)
3013
      then
3014
         Disc := First_Discriminant (T);
3015
         while Present (Disc) loop
3016
            if Is_Access_Type (Etype (Disc)) then
3017
               return True;
3018
            end if;
3019
 
3020
            Next_Discriminant (Disc);
3021
         end loop;
3022
 
3023
         return False;
3024
      else
3025
         return False;
3026
      end if;
3027
   end Has_Access_Constraint;
3028
 
3029
   ----------------------------------
3030
   -- Has_Following_Address_Clause --
3031
   ----------------------------------
3032
 
3033
   --  Should this function check the private part in a package ???
3034
 
3035
   function Has_Following_Address_Clause (D : Node_Id) return Boolean is
3036
      Id   : constant Entity_Id := Defining_Identifier (D);
3037
      Decl : Node_Id;
3038
 
3039
   begin
3040
      Decl := Next (D);
3041
      while Present (Decl) loop
3042
         if Nkind (Decl) = N_At_Clause
3043
           and then Chars (Identifier (Decl)) = Chars (Id)
3044
         then
3045
            return True;
3046
 
3047
         elsif Nkind (Decl) = N_Attribute_Definition_Clause
3048
           and then Chars (Decl) = Name_Address
3049
           and then Chars (Name (Decl)) = Chars (Id)
3050
         then
3051
            return True;
3052
         end if;
3053
 
3054
         Next (Decl);
3055
      end loop;
3056
 
3057
      return False;
3058
   end Has_Following_Address_Clause;
3059
 
3060
   --------------------
3061
   -- Homonym_Number --
3062
   --------------------
3063
 
3064
   function Homonym_Number (Subp : Entity_Id) return Nat is
3065
      Count : Nat;
3066
      Hom   : Entity_Id;
3067
 
3068
   begin
3069
      Count := 1;
3070
      Hom := Homonym (Subp);
3071
      while Present (Hom) loop
3072
         if Scope (Hom) = Scope (Subp) then
3073
            Count := Count + 1;
3074
         end if;
3075
 
3076
         Hom := Homonym (Hom);
3077
      end loop;
3078
 
3079
      return Count;
3080
   end Homonym_Number;
3081
 
3082
   -----------------------------------
3083
   -- In_Library_Level_Package_Body --
3084
   -----------------------------------
3085
 
3086
   function In_Library_Level_Package_Body (Id : Entity_Id) return Boolean is
3087
   begin
3088
      --  First determine whether the entity appears at the library level, then
3089
      --  look at the containing unit.
3090
 
3091
      if Is_Library_Level_Entity (Id) then
3092
         declare
3093
            Container : constant Node_Id := Cunit (Get_Source_Unit (Id));
3094
 
3095
         begin
3096
            return Nkind (Unit (Container)) = N_Package_Body;
3097
         end;
3098
      end if;
3099
 
3100
      return False;
3101
   end In_Library_Level_Package_Body;
3102
 
3103
   ------------------------------
3104
   -- In_Unconditional_Context --
3105
   ------------------------------
3106
 
3107
   function In_Unconditional_Context (Node : Node_Id) return Boolean is
3108
      P : Node_Id;
3109
 
3110
   begin
3111
      P := Node;
3112
      while Present (P) loop
3113
         case Nkind (P) is
3114
            when N_Subprogram_Body =>
3115
               return True;
3116
 
3117
            when N_If_Statement =>
3118
               return False;
3119
 
3120
            when N_Loop_Statement =>
3121
               return False;
3122
 
3123
            when N_Case_Statement =>
3124
               return False;
3125
 
3126
            when others =>
3127
               P := Parent (P);
3128
         end case;
3129
      end loop;
3130
 
3131
      return False;
3132
   end In_Unconditional_Context;
3133
 
3134
   -------------------
3135
   -- Insert_Action --
3136
   -------------------
3137
 
3138
   procedure Insert_Action (Assoc_Node : Node_Id; Ins_Action : Node_Id) is
3139
   begin
3140
      if Present (Ins_Action) then
3141
         Insert_Actions (Assoc_Node, New_List (Ins_Action));
3142
      end if;
3143
   end Insert_Action;
3144
 
3145
   --  Version with check(s) suppressed
3146
 
3147
   procedure Insert_Action
3148
     (Assoc_Node : Node_Id; Ins_Action : Node_Id; Suppress : Check_Id)
3149
   is
3150
   begin
3151
      Insert_Actions (Assoc_Node, New_List (Ins_Action), Suppress);
3152
   end Insert_Action;
3153
 
3154
   -------------------------
3155
   -- Insert_Action_After --
3156
   -------------------------
3157
 
3158
   procedure Insert_Action_After
3159
     (Assoc_Node : Node_Id;
3160
      Ins_Action : Node_Id)
3161
   is
3162
   begin
3163
      Insert_Actions_After (Assoc_Node, New_List (Ins_Action));
3164
   end Insert_Action_After;
3165
 
3166
   --------------------
3167
   -- Insert_Actions --
3168
   --------------------
3169
 
3170
   procedure Insert_Actions (Assoc_Node : Node_Id; Ins_Actions : List_Id) is
3171
      N : Node_Id;
3172
      P : Node_Id;
3173
 
3174
      Wrapped_Node : Node_Id := Empty;
3175
 
3176
   begin
3177
      if No (Ins_Actions) or else Is_Empty_List (Ins_Actions) then
3178
         return;
3179
      end if;
3180
 
3181
      --  Ignore insert of actions from inside default expression (or other
3182
      --  similar "spec expression") in the special spec-expression analyze
3183
      --  mode. Any insertions at this point have no relevance, since we are
3184
      --  only doing the analyze to freeze the types of any static expressions.
3185
      --  See section "Handling of Default Expressions" in the spec of package
3186
      --  Sem for further details.
3187
 
3188
      if In_Spec_Expression then
3189
         return;
3190
      end if;
3191
 
3192
      --  If the action derives from stuff inside a record, then the actions
3193
      --  are attached to the current scope, to be inserted and analyzed on
3194
      --  exit from the scope. The reason for this is that we may also be
3195
      --  generating freeze actions at the same time, and they must eventually
3196
      --  be elaborated in the correct order.
3197
 
3198
      if Is_Record_Type (Current_Scope)
3199
        and then not Is_Frozen (Current_Scope)
3200
      then
3201
         if No (Scope_Stack.Table
3202
           (Scope_Stack.Last).Pending_Freeze_Actions)
3203
         then
3204
            Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions :=
3205
              Ins_Actions;
3206
         else
3207
            Append_List
3208
              (Ins_Actions,
3209
               Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions);
3210
         end if;
3211
 
3212
         return;
3213
      end if;
3214
 
3215
      --  We now intend to climb up the tree to find the right point to
3216
      --  insert the actions. We start at Assoc_Node, unless this node is a
3217
      --  subexpression in which case we start with its parent. We do this for
3218
      --  two reasons. First it speeds things up. Second, if Assoc_Node is
3219
      --  itself one of the special nodes like N_And_Then, then we assume that
3220
      --  an initial request to insert actions for such a node does not expect
3221
      --  the actions to get deposited in the node for later handling when the
3222
      --  node is expanded, since clearly the node is being dealt with by the
3223
      --  caller. Note that in the subexpression case, N is always the child we
3224
      --  came from.
3225
 
3226
      --  N_Raise_xxx_Error is an annoying special case, it is a statement if
3227
      --  it has type Standard_Void_Type, and a subexpression otherwise.
3228
      --  otherwise. Procedure attribute references are also statements.
3229
 
3230
      if Nkind (Assoc_Node) in N_Subexpr
3231
        and then (Nkind (Assoc_Node) in N_Raise_xxx_Error
3232
                   or else Etype (Assoc_Node) /= Standard_Void_Type)
3233
        and then (Nkind (Assoc_Node) /= N_Attribute_Reference
3234
                   or else
3235
                     not Is_Procedure_Attribute_Name
3236
                           (Attribute_Name (Assoc_Node)))
3237
      then
3238
         P := Assoc_Node;             -- ??? does not agree with above!
3239
         N := Parent (Assoc_Node);
3240
 
3241
      --  Non-subexpression case. Note that N is initially Empty in this case
3242
      --  (N is only guaranteed Non-Empty in the subexpr case).
3243
 
3244
      else
3245
         P := Assoc_Node;
3246
         N := Empty;
3247
      end if;
3248
 
3249
      --  Capture root of the transient scope
3250
 
3251
      if Scope_Is_Transient then
3252
         Wrapped_Node := Node_To_Be_Wrapped;
3253
      end if;
3254
 
3255
      loop
3256
         pragma Assert (Present (P));
3257
 
3258
         case Nkind (P) is
3259
 
3260
            --  Case of right operand of AND THEN or OR ELSE. Put the actions
3261
            --  in the Actions field of the right operand. They will be moved
3262
            --  out further when the AND THEN or OR ELSE operator is expanded.
3263
            --  Nothing special needs to be done for the left operand since
3264
            --  in that case the actions are executed unconditionally.
3265
 
3266
            when N_Short_Circuit =>
3267
               if N = Right_Opnd (P) then
3268
 
3269
                  --  We are now going to either append the actions to the
3270
                  --  actions field of the short-circuit operation. We will
3271
                  --  also analyze the actions now.
3272
 
3273
                  --  This analysis is really too early, the proper thing would
3274
                  --  be to just park them there now, and only analyze them if
3275
                  --  we find we really need them, and to it at the proper
3276
                  --  final insertion point. However attempting to this proved
3277
                  --  tricky, so for now we just kill current values before and
3278
                  --  after the analyze call to make sure we avoid peculiar
3279
                  --  optimizations from this out of order insertion.
3280
 
3281
                  Kill_Current_Values;
3282
 
3283
                  if Present (Actions (P)) then
3284
                     Insert_List_After_And_Analyze
3285
                       (Last (Actions (P)), Ins_Actions);
3286
                  else
3287
                     Set_Actions (P, Ins_Actions);
3288
                     Analyze_List (Actions (P));
3289
                  end if;
3290
 
3291
                  Kill_Current_Values;
3292
 
3293
                  return;
3294
               end if;
3295
 
3296
            --  Then or Else operand of conditional expression. Add actions to
3297
            --  Then_Actions or Else_Actions field as appropriate. The actions
3298
            --  will be moved further out when the conditional is expanded.
3299
 
3300
            when N_Conditional_Expression =>
3301
               declare
3302
                  ThenX : constant Node_Id := Next (First (Expressions (P)));
3303
                  ElseX : constant Node_Id := Next (ThenX);
3304
 
3305
               begin
3306
                  --  If the enclosing expression is already analyzed, as
3307
                  --  is the case for nested elaboration checks, insert the
3308
                  --  conditional further out.
3309
 
3310
                  if Analyzed (P) then
3311
                     null;
3312
 
3313
                  --  Actions belong to the then expression, temporarily place
3314
                  --  them as Then_Actions of the conditional expr. They will
3315
                  --  be moved to the proper place later when the conditional
3316
                  --  expression is expanded.
3317
 
3318
                  elsif N = ThenX then
3319
                     if Present (Then_Actions (P)) then
3320
                        Insert_List_After_And_Analyze
3321
                          (Last (Then_Actions (P)), Ins_Actions);
3322
                     else
3323
                        Set_Then_Actions (P, Ins_Actions);
3324
                        Analyze_List (Then_Actions (P));
3325
                     end if;
3326
 
3327
                     return;
3328
 
3329
                  --  Actions belong to the else expression, temporarily
3330
                  --  place them as Else_Actions of the conditional expr.
3331
                  --  They will be moved to the proper place later when
3332
                  --  the conditional expression is expanded.
3333
 
3334
                  elsif N = ElseX then
3335
                     if Present (Else_Actions (P)) then
3336
                        Insert_List_After_And_Analyze
3337
                          (Last (Else_Actions (P)), Ins_Actions);
3338
                     else
3339
                        Set_Else_Actions (P, Ins_Actions);
3340
                        Analyze_List (Else_Actions (P));
3341
                     end if;
3342
 
3343
                     return;
3344
 
3345
                  --  Actions belong to the condition. In this case they are
3346
                  --  unconditionally executed, and so we can continue the
3347
                  --  search for the proper insert point.
3348
 
3349
                  else
3350
                     null;
3351
                  end if;
3352
               end;
3353
 
3354
            --  Alternative of case expression, we place the action in the
3355
            --  Actions field of the case expression alternative, this will
3356
            --  be handled when the case expression is expanded.
3357
 
3358
            when N_Case_Expression_Alternative =>
3359
               if Present (Actions (P)) then
3360
                  Insert_List_After_And_Analyze
3361
                    (Last (Actions (P)), Ins_Actions);
3362
               else
3363
                  Set_Actions (P, Ins_Actions);
3364
                  Analyze_List (Actions (P));
3365
               end if;
3366
 
3367
               return;
3368
 
3369
            --  Case of appearing within an Expressions_With_Actions node. We
3370
            --  prepend the actions to the list of actions already there, if
3371
            --  the node has not been analyzed yet. Otherwise find insertion
3372
            --  location further up the tree.
3373
 
3374
            when N_Expression_With_Actions =>
3375
               if not Analyzed (P) then
3376
                  Prepend_List (Ins_Actions, Actions (P));
3377
                  return;
3378
               end if;
3379
 
3380
            --  Case of appearing in the condition of a while expression or
3381
            --  elsif. We insert the actions into the Condition_Actions field.
3382
            --  They will be moved further out when the while loop or elsif
3383
            --  is analyzed.
3384
 
3385
            when N_Iteration_Scheme |
3386
                 N_Elsif_Part
3387
            =>
3388
               if N = Condition (P) then
3389
                  if Present (Condition_Actions (P)) then
3390
                     Insert_List_After_And_Analyze
3391
                       (Last (Condition_Actions (P)), Ins_Actions);
3392
                  else
3393
                     Set_Condition_Actions (P, Ins_Actions);
3394
 
3395
                     --  Set the parent of the insert actions explicitly. This
3396
                     --  is not a syntactic field, but we need the parent field
3397
                     --  set, in particular so that freeze can understand that
3398
                     --  it is dealing with condition actions, and properly
3399
                     --  insert the freezing actions.
3400
 
3401
                     Set_Parent (Ins_Actions, P);
3402
                     Analyze_List (Condition_Actions (P));
3403
                  end if;
3404
 
3405
                  return;
3406
               end if;
3407
 
3408
            --  Statements, declarations, pragmas, representation clauses
3409
 
3410
            when
3411
               --  Statements
3412
 
3413
               N_Procedure_Call_Statement               |
3414
               N_Statement_Other_Than_Procedure_Call    |
3415
 
3416
               --  Pragmas
3417
 
3418
               N_Pragma                                 |
3419
 
3420
               --  Representation_Clause
3421
 
3422
               N_At_Clause                              |
3423
               N_Attribute_Definition_Clause            |
3424
               N_Enumeration_Representation_Clause      |
3425
               N_Record_Representation_Clause           |
3426
 
3427
               --  Declarations
3428
 
3429
               N_Abstract_Subprogram_Declaration        |
3430
               N_Entry_Body                             |
3431
               N_Exception_Declaration                  |
3432
               N_Exception_Renaming_Declaration         |
3433
               N_Expression_Function                    |
3434
               N_Formal_Abstract_Subprogram_Declaration |
3435
               N_Formal_Concrete_Subprogram_Declaration |
3436
               N_Formal_Object_Declaration              |
3437
               N_Formal_Type_Declaration                |
3438
               N_Full_Type_Declaration                  |
3439
               N_Function_Instantiation                 |
3440
               N_Generic_Function_Renaming_Declaration  |
3441
               N_Generic_Package_Declaration            |
3442
               N_Generic_Package_Renaming_Declaration   |
3443
               N_Generic_Procedure_Renaming_Declaration |
3444
               N_Generic_Subprogram_Declaration         |
3445
               N_Implicit_Label_Declaration             |
3446
               N_Incomplete_Type_Declaration            |
3447
               N_Number_Declaration                     |
3448
               N_Object_Declaration                     |
3449
               N_Object_Renaming_Declaration            |
3450
               N_Package_Body                           |
3451
               N_Package_Body_Stub                      |
3452
               N_Package_Declaration                    |
3453
               N_Package_Instantiation                  |
3454
               N_Package_Renaming_Declaration           |
3455
               N_Private_Extension_Declaration          |
3456
               N_Private_Type_Declaration               |
3457
               N_Procedure_Instantiation                |
3458
               N_Protected_Body                         |
3459
               N_Protected_Body_Stub                    |
3460
               N_Protected_Type_Declaration             |
3461
               N_Single_Task_Declaration                |
3462
               N_Subprogram_Body                        |
3463
               N_Subprogram_Body_Stub                   |
3464
               N_Subprogram_Declaration                 |
3465
               N_Subprogram_Renaming_Declaration        |
3466
               N_Subtype_Declaration                    |
3467
               N_Task_Body                              |
3468
               N_Task_Body_Stub                         |
3469
               N_Task_Type_Declaration                  |
3470
 
3471
               --  Use clauses can appear in lists of declarations
3472
 
3473
               N_Use_Package_Clause                     |
3474
               N_Use_Type_Clause                        |
3475
 
3476
               --  Freeze entity behaves like a declaration or statement
3477
 
3478
               N_Freeze_Entity
3479
            =>
3480
               --  Do not insert here if the item is not a list member (this
3481
               --  happens for example with a triggering statement, and the
3482
               --  proper approach is to insert before the entire select).
3483
 
3484
               if not Is_List_Member (P) then
3485
                  null;
3486
 
3487
               --  Do not insert if parent of P is an N_Component_Association
3488
               --  node (i.e. we are in the context of an N_Aggregate or
3489
               --  N_Extension_Aggregate node. In this case we want to insert
3490
               --  before the entire aggregate.
3491
 
3492
               elsif Nkind (Parent (P)) = N_Component_Association then
3493
                  null;
3494
 
3495
               --  Do not insert if the parent of P is either an N_Variant node
3496
               --  or an N_Record_Definition node, meaning in either case that
3497
               --  P is a member of a component list, and that therefore the
3498
               --  actions should be inserted outside the complete record
3499
               --  declaration.
3500
 
3501
               elsif Nkind (Parent (P)) = N_Variant
3502
                 or else Nkind (Parent (P)) = N_Record_Definition
3503
               then
3504
                  null;
3505
 
3506
               --  Do not insert freeze nodes within the loop generated for
3507
               --  an aggregate, because they may be elaborated too late for
3508
               --  subsequent use in the back end: within a package spec the
3509
               --  loop is part of the elaboration procedure and is only
3510
               --  elaborated during the second pass.
3511
 
3512
               --  If the loop comes from source, or the entity is local to the
3513
               --  loop itself it must remain within.
3514
 
3515
               elsif Nkind (Parent (P)) = N_Loop_Statement
3516
                 and then not Comes_From_Source (Parent (P))
3517
                 and then Nkind (First (Ins_Actions)) = N_Freeze_Entity
3518
                 and then
3519
                   Scope (Entity (First (Ins_Actions))) /= Current_Scope
3520
               then
3521
                  null;
3522
 
3523
               --  Otherwise we can go ahead and do the insertion
3524
 
3525
               elsif P = Wrapped_Node then
3526
                  Store_Before_Actions_In_Scope (Ins_Actions);
3527
                  return;
3528
 
3529
               else
3530
                  Insert_List_Before_And_Analyze (P, Ins_Actions);
3531
                  return;
3532
               end if;
3533
 
3534
            --  A special case, N_Raise_xxx_Error can act either as a statement
3535
            --  or a subexpression. We tell the difference by looking at the
3536
            --  Etype. It is set to Standard_Void_Type in the statement case.
3537
 
3538
            when
3539
               N_Raise_xxx_Error =>
3540
                  if Etype (P) = Standard_Void_Type then
3541
                     if  P = Wrapped_Node then
3542
                        Store_Before_Actions_In_Scope (Ins_Actions);
3543
                     else
3544
                        Insert_List_Before_And_Analyze (P, Ins_Actions);
3545
                     end if;
3546
 
3547
                     return;
3548
 
3549
                  --  In the subexpression case, keep climbing
3550
 
3551
                  else
3552
                     null;
3553
                  end if;
3554
 
3555
            --  If a component association appears within a loop created for
3556
            --  an array aggregate, attach the actions to the association so
3557
            --  they can be subsequently inserted within the loop. For other
3558
            --  component associations insert outside of the aggregate. For
3559
            --  an association that will generate a loop, its Loop_Actions
3560
            --  attribute is already initialized (see exp_aggr.adb).
3561
 
3562
            --  The list of loop_actions can in turn generate additional ones,
3563
            --  that are inserted before the associated node. If the associated
3564
            --  node is outside the aggregate, the new actions are collected
3565
            --  at the end of the loop actions, to respect the order in which
3566
            --  they are to be elaborated.
3567
 
3568
            when
3569
               N_Component_Association =>
3570
                  if Nkind (Parent (P)) = N_Aggregate
3571
                    and then Present (Loop_Actions (P))
3572
                  then
3573
                     if Is_Empty_List (Loop_Actions (P)) then
3574
                        Set_Loop_Actions (P, Ins_Actions);
3575
                        Analyze_List (Ins_Actions);
3576
 
3577
                     else
3578
                        declare
3579
                           Decl : Node_Id;
3580
 
3581
                        begin
3582
                           --  Check whether these actions were generated by a
3583
                           --  declaration that is part of the loop_ actions
3584
                           --  for the component_association.
3585
 
3586
                           Decl := Assoc_Node;
3587
                           while Present (Decl) loop
3588
                              exit when Parent (Decl) = P
3589
                                and then Is_List_Member (Decl)
3590
                                and then
3591
                                  List_Containing (Decl) = Loop_Actions (P);
3592
                              Decl := Parent (Decl);
3593
                           end loop;
3594
 
3595
                           if Present (Decl) then
3596
                              Insert_List_Before_And_Analyze
3597
                                (Decl, Ins_Actions);
3598
                           else
3599
                              Insert_List_After_And_Analyze
3600
                                (Last (Loop_Actions (P)), Ins_Actions);
3601
                           end if;
3602
                        end;
3603
                     end if;
3604
 
3605
                     return;
3606
 
3607
                  else
3608
                     null;
3609
                  end if;
3610
 
3611
            --  Another special case, an attribute denoting a procedure call
3612
 
3613
            when
3614
               N_Attribute_Reference =>
3615
                  if Is_Procedure_Attribute_Name (Attribute_Name (P)) then
3616
                     if P = Wrapped_Node then
3617
                        Store_Before_Actions_In_Scope (Ins_Actions);
3618
                     else
3619
                        Insert_List_Before_And_Analyze (P, Ins_Actions);
3620
                     end if;
3621
 
3622
                     return;
3623
 
3624
                  --  In the subexpression case, keep climbing
3625
 
3626
                  else
3627
                     null;
3628
                  end if;
3629
 
3630
            --  A contract node should not belong to the tree
3631
 
3632
            when N_Contract =>
3633
               raise Program_Error;
3634
 
3635
            --  For all other node types, keep climbing tree
3636
 
3637
            when
3638
               N_Abortable_Part                         |
3639
               N_Accept_Alternative                     |
3640
               N_Access_Definition                      |
3641
               N_Access_Function_Definition             |
3642
               N_Access_Procedure_Definition            |
3643
               N_Access_To_Object_Definition            |
3644
               N_Aggregate                              |
3645
               N_Allocator                              |
3646
               N_Aspect_Specification                   |
3647
               N_Case_Expression                        |
3648
               N_Case_Statement_Alternative             |
3649
               N_Character_Literal                      |
3650
               N_Compilation_Unit                       |
3651
               N_Compilation_Unit_Aux                   |
3652
               N_Component_Clause                       |
3653
               N_Component_Declaration                  |
3654
               N_Component_Definition                   |
3655
               N_Component_List                         |
3656
               N_Constrained_Array_Definition           |
3657
               N_Decimal_Fixed_Point_Definition         |
3658
               N_Defining_Character_Literal             |
3659
               N_Defining_Identifier                    |
3660
               N_Defining_Operator_Symbol               |
3661
               N_Defining_Program_Unit_Name             |
3662
               N_Delay_Alternative                      |
3663
               N_Delta_Constraint                       |
3664
               N_Derived_Type_Definition                |
3665
               N_Designator                             |
3666
               N_Digits_Constraint                      |
3667
               N_Discriminant_Association               |
3668
               N_Discriminant_Specification             |
3669
               N_Empty                                  |
3670
               N_Entry_Body_Formal_Part                 |
3671
               N_Entry_Call_Alternative                 |
3672
               N_Entry_Declaration                      |
3673
               N_Entry_Index_Specification              |
3674
               N_Enumeration_Type_Definition            |
3675
               N_Error                                  |
3676
               N_Exception_Handler                      |
3677
               N_Expanded_Name                          |
3678
               N_Explicit_Dereference                   |
3679
               N_Extension_Aggregate                    |
3680
               N_Floating_Point_Definition              |
3681
               N_Formal_Decimal_Fixed_Point_Definition  |
3682
               N_Formal_Derived_Type_Definition         |
3683
               N_Formal_Discrete_Type_Definition        |
3684
               N_Formal_Floating_Point_Definition       |
3685
               N_Formal_Modular_Type_Definition         |
3686
               N_Formal_Ordinary_Fixed_Point_Definition |
3687
               N_Formal_Package_Declaration             |
3688
               N_Formal_Private_Type_Definition         |
3689
               N_Formal_Incomplete_Type_Definition      |
3690
               N_Formal_Signed_Integer_Type_Definition  |
3691
               N_Function_Call                          |
3692
               N_Function_Specification                 |
3693
               N_Generic_Association                    |
3694
               N_Handled_Sequence_Of_Statements         |
3695
               N_Identifier                             |
3696
               N_In                                     |
3697
               N_Index_Or_Discriminant_Constraint       |
3698
               N_Indexed_Component                      |
3699
               N_Integer_Literal                        |
3700
               N_Iterator_Specification                 |
3701
               N_Itype_Reference                        |
3702
               N_Label                                  |
3703
               N_Loop_Parameter_Specification           |
3704
               N_Mod_Clause                             |
3705
               N_Modular_Type_Definition                |
3706
               N_Not_In                                 |
3707
               N_Null                                   |
3708
               N_Op_Abs                                 |
3709
               N_Op_Add                                 |
3710
               N_Op_And                                 |
3711
               N_Op_Concat                              |
3712
               N_Op_Divide                              |
3713
               N_Op_Eq                                  |
3714
               N_Op_Expon                               |
3715
               N_Op_Ge                                  |
3716
               N_Op_Gt                                  |
3717
               N_Op_Le                                  |
3718
               N_Op_Lt                                  |
3719
               N_Op_Minus                               |
3720
               N_Op_Mod                                 |
3721
               N_Op_Multiply                            |
3722
               N_Op_Ne                                  |
3723
               N_Op_Not                                 |
3724
               N_Op_Or                                  |
3725
               N_Op_Plus                                |
3726
               N_Op_Rem                                 |
3727
               N_Op_Rotate_Left                         |
3728
               N_Op_Rotate_Right                        |
3729
               N_Op_Shift_Left                          |
3730
               N_Op_Shift_Right                         |
3731
               N_Op_Shift_Right_Arithmetic              |
3732
               N_Op_Subtract                            |
3733
               N_Op_Xor                                 |
3734
               N_Operator_Symbol                        |
3735
               N_Ordinary_Fixed_Point_Definition        |
3736
               N_Others_Choice                          |
3737
               N_Package_Specification                  |
3738
               N_Parameter_Association                  |
3739
               N_Parameter_Specification                |
3740
               N_Pop_Constraint_Error_Label             |
3741
               N_Pop_Program_Error_Label                |
3742
               N_Pop_Storage_Error_Label                |
3743
               N_Pragma_Argument_Association            |
3744
               N_Procedure_Specification                |
3745
               N_Protected_Definition                   |
3746
               N_Push_Constraint_Error_Label            |
3747
               N_Push_Program_Error_Label               |
3748
               N_Push_Storage_Error_Label               |
3749
               N_Qualified_Expression                   |
3750
               N_Quantified_Expression                  |
3751
               N_Range                                  |
3752
               N_Range_Constraint                       |
3753
               N_Real_Literal                           |
3754
               N_Real_Range_Specification               |
3755
               N_Record_Definition                      |
3756
               N_Reference                              |
3757
               N_SCIL_Dispatch_Table_Tag_Init           |
3758
               N_SCIL_Dispatching_Call                  |
3759
               N_SCIL_Membership_Test                   |
3760
               N_Selected_Component                     |
3761
               N_Signed_Integer_Type_Definition         |
3762
               N_Single_Protected_Declaration           |
3763
               N_Slice                                  |
3764
               N_String_Literal                         |
3765
               N_Subprogram_Info                        |
3766
               N_Subtype_Indication                     |
3767
               N_Subunit                                |
3768
               N_Task_Definition                        |
3769
               N_Terminate_Alternative                  |
3770
               N_Triggering_Alternative                 |
3771
               N_Type_Conversion                        |
3772
               N_Unchecked_Expression                   |
3773
               N_Unchecked_Type_Conversion              |
3774
               N_Unconstrained_Array_Definition         |
3775
               N_Unused_At_End                          |
3776
               N_Unused_At_Start                        |
3777
               N_Variant                                |
3778
               N_Variant_Part                           |
3779
               N_Validate_Unchecked_Conversion          |
3780
               N_With_Clause
3781
            =>
3782
               null;
3783
 
3784
         end case;
3785
 
3786
         --  Make sure that inserted actions stay in the transient scope
3787
 
3788
         if P = Wrapped_Node then
3789
            Store_Before_Actions_In_Scope (Ins_Actions);
3790
            return;
3791
         end if;
3792
 
3793
         --  If we fall through above tests, keep climbing tree
3794
 
3795
         N := P;
3796
 
3797
         if Nkind (Parent (N)) = N_Subunit then
3798
 
3799
            --  This is the proper body corresponding to a stub. Insertion must
3800
            --  be done at the point of the stub, which is in the declarative
3801
            --  part of the parent unit.
3802
 
3803
            P := Corresponding_Stub (Parent (N));
3804
 
3805
         else
3806
            P := Parent (N);
3807
         end if;
3808
      end loop;
3809
   end Insert_Actions;
3810
 
3811
   --  Version with check(s) suppressed
3812
 
3813
   procedure Insert_Actions
3814
     (Assoc_Node  : Node_Id;
3815
      Ins_Actions : List_Id;
3816
      Suppress    : Check_Id)
3817
   is
3818
   begin
3819
      if Suppress = All_Checks then
3820
         declare
3821
            Svg : constant Suppress_Array := Scope_Suppress;
3822
         begin
3823
            Scope_Suppress := (others => True);
3824
            Insert_Actions (Assoc_Node, Ins_Actions);
3825
            Scope_Suppress := Svg;
3826
         end;
3827
 
3828
      else
3829
         declare
3830
            Svg : constant Boolean := Scope_Suppress (Suppress);
3831
         begin
3832
            Scope_Suppress (Suppress) := True;
3833
            Insert_Actions (Assoc_Node, Ins_Actions);
3834
            Scope_Suppress (Suppress) := Svg;
3835
         end;
3836
      end if;
3837
   end Insert_Actions;
3838
 
3839
   --------------------------
3840
   -- Insert_Actions_After --
3841
   --------------------------
3842
 
3843
   procedure Insert_Actions_After
3844
     (Assoc_Node  : Node_Id;
3845
      Ins_Actions : List_Id)
3846
   is
3847
   begin
3848
      if Scope_Is_Transient
3849
        and then Assoc_Node = Node_To_Be_Wrapped
3850
      then
3851
         Store_After_Actions_In_Scope (Ins_Actions);
3852
      else
3853
         Insert_List_After_And_Analyze (Assoc_Node, Ins_Actions);
3854
      end if;
3855
   end Insert_Actions_After;
3856
 
3857
   ---------------------------------
3858
   -- Insert_Library_Level_Action --
3859
   ---------------------------------
3860
 
3861
   procedure Insert_Library_Level_Action (N : Node_Id) is
3862
      Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
3863
 
3864
   begin
3865
      Push_Scope (Cunit_Entity (Main_Unit));
3866
      --  ??? should this be Current_Sem_Unit instead of Main_Unit?
3867
 
3868
      if No (Actions (Aux)) then
3869
         Set_Actions (Aux, New_List (N));
3870
      else
3871
         Append (N, Actions (Aux));
3872
      end if;
3873
 
3874
      Analyze (N);
3875
      Pop_Scope;
3876
   end Insert_Library_Level_Action;
3877
 
3878
   ----------------------------------
3879
   -- Insert_Library_Level_Actions --
3880
   ----------------------------------
3881
 
3882
   procedure Insert_Library_Level_Actions (L : List_Id) is
3883
      Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
3884
 
3885
   begin
3886
      if Is_Non_Empty_List (L) then
3887
         Push_Scope (Cunit_Entity (Main_Unit));
3888
         --  ??? should this be Current_Sem_Unit instead of Main_Unit?
3889
 
3890
         if No (Actions (Aux)) then
3891
            Set_Actions (Aux, L);
3892
            Analyze_List (L);
3893
         else
3894
            Insert_List_After_And_Analyze (Last (Actions (Aux)), L);
3895
         end if;
3896
 
3897
         Pop_Scope;
3898
      end if;
3899
   end Insert_Library_Level_Actions;
3900
 
3901
   ----------------------
3902
   -- Inside_Init_Proc --
3903
   ----------------------
3904
 
3905
   function Inside_Init_Proc return Boolean is
3906
      S : Entity_Id;
3907
 
3908
   begin
3909
      S := Current_Scope;
3910
      while Present (S)
3911
        and then S /= Standard_Standard
3912
      loop
3913
         if Is_Init_Proc (S) then
3914
            return True;
3915
         else
3916
            S := Scope (S);
3917
         end if;
3918
      end loop;
3919
 
3920
      return False;
3921
   end Inside_Init_Proc;
3922
 
3923
   ----------------------------
3924
   -- Is_All_Null_Statements --
3925
   ----------------------------
3926
 
3927
   function Is_All_Null_Statements (L : List_Id) return Boolean is
3928
      Stm : Node_Id;
3929
 
3930
   begin
3931
      Stm := First (L);
3932
      while Present (Stm) loop
3933
         if Nkind (Stm) /= N_Null_Statement then
3934
            return False;
3935
         end if;
3936
 
3937
         Next (Stm);
3938
      end loop;
3939
 
3940
      return True;
3941
   end Is_All_Null_Statements;
3942
 
3943
   ---------------------------------------------
3944
   -- Is_Displacement_Of_Ctrl_Function_Result --
3945
   ---------------------------------------------
3946
 
3947
   function Is_Displacement_Of_Ctrl_Function_Result
3948
     (Obj_Id : Entity_Id) return Boolean
3949
   is
3950
      function Initialized_By_Ctrl_Function (N : Node_Id) return Boolean;
3951
      --  Determine whether object declaration N is initialized by a controlled
3952
      --  function call.
3953
 
3954
      function Is_Displace_Call (N : Node_Id) return Boolean;
3955
      --  Determine whether a particular node is a call to Ada.Tags.Displace.
3956
      --  The call might be nested within other actions such as conversions.
3957
 
3958
      ----------------------------------
3959
      -- Initialized_By_Ctrl_Function --
3960
      ----------------------------------
3961
 
3962
      function Initialized_By_Ctrl_Function (N : Node_Id) return Boolean is
3963
         Expr : constant Node_Id := Original_Node (Expression (N));
3964
      begin
3965
         return
3966
            Nkind (Expr) = N_Function_Call
3967
              and then Needs_Finalization (Etype (Expr));
3968
      end Initialized_By_Ctrl_Function;
3969
 
3970
      ----------------------
3971
      -- Is_Displace_Call --
3972
      ----------------------
3973
 
3974
      function Is_Displace_Call (N : Node_Id) return Boolean is
3975
         Call : Node_Id := N;
3976
 
3977
      begin
3978
         --  Strip various actions which may precede a call to Displace
3979
 
3980
         loop
3981
            if Nkind (Call) = N_Explicit_Dereference then
3982
               Call := Prefix (Call);
3983
 
3984
            elsif Nkind_In (Call, N_Type_Conversion,
3985
                                  N_Unchecked_Type_Conversion)
3986
            then
3987
               Call := Expression (Call);
3988
 
3989
            else
3990
               exit;
3991
            end if;
3992
         end loop;
3993
 
3994
         return
3995
           Nkind (Call) = N_Function_Call
3996
             and then Is_RTE (Entity (Name (Call)), RE_Displace);
3997
      end Is_Displace_Call;
3998
 
3999
      --  Local variables
4000
 
4001
      Decl      : constant Node_Id   := Parent (Obj_Id);
4002
      Obj_Typ   : constant Entity_Id := Base_Type (Etype (Obj_Id));
4003
      Orig_Decl : constant Node_Id   := Original_Node (Decl);
4004
 
4005
   --  Start of processing for Is_Displacement_Of_Ctrl_Function_Result
4006
 
4007
   begin
4008
      --  Detect the following case:
4009
 
4010
      --     Obj : Class_Wide_Type := Function_Call (...);
4011
 
4012
      --  which is rewritten into:
4013
 
4014
      --     Temp : ... := Function_Call (...)'reference;
4015
      --     Obj  : Class_Wide_Type renames (... Ada.Tags.Displace (Temp));
4016
 
4017
      --  when the return type of the function and the class-wide type require
4018
      --  dispatch table pointer displacement.
4019
 
4020
      return
4021
        Nkind (Decl) = N_Object_Renaming_Declaration
4022
          and then Nkind (Orig_Decl) = N_Object_Declaration
4023
          and then Comes_From_Source (Orig_Decl)
4024
          and then Initialized_By_Ctrl_Function (Orig_Decl)
4025
          and then Is_Class_Wide_Type (Obj_Typ)
4026
          and then Is_Displace_Call (Renamed_Object (Obj_Id));
4027
   end Is_Displacement_Of_Ctrl_Function_Result;
4028
 
4029
   ------------------------------
4030
   -- Is_Finalizable_Transient --
4031
   ------------------------------
4032
 
4033
   function Is_Finalizable_Transient
4034
     (Decl     : Node_Id;
4035
      Rel_Node : Node_Id) return Boolean
4036
   is
4037
      Obj_Id  : constant Entity_Id := Defining_Identifier (Decl);
4038
      Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id));
4039
      Desig   : Entity_Id := Obj_Typ;
4040
 
4041
      function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean;
4042
      --  Determine whether transient object Trans_Id is initialized either
4043
      --  by a function call which returns an access type or simply renames
4044
      --  another pointer.
4045
 
4046
      function Initialized_By_Aliased_BIP_Func_Call
4047
        (Trans_Id : Entity_Id) return Boolean;
4048
      --  Determine whether transient object Trans_Id is initialized by a
4049
      --  build-in-place function call where the BIPalloc parameter is of
4050
      --  value 1 and BIPaccess is not null. This case creates an aliasing
4051
      --  between the returned value and the value denoted by BIPaccess.
4052
 
4053
      function Is_Aliased
4054
        (Trans_Id   : Entity_Id;
4055
         First_Stmt : Node_Id) return Boolean;
4056
      --  Determine whether transient object Trans_Id has been renamed or
4057
      --  aliased through 'reference in the statement list starting from
4058
      --  First_Stmt.
4059
 
4060
      function Is_Allocated (Trans_Id : Entity_Id) return Boolean;
4061
      --  Determine whether transient object Trans_Id is allocated on the heap
4062
 
4063
      function Is_Iterated_Container
4064
        (Trans_Id   : Entity_Id;
4065
         First_Stmt : Node_Id) return Boolean;
4066
      --  Determine whether transient object Trans_Id denotes a container which
4067
      --  is in the process of being iterated in the statement list starting
4068
      --  from First_Stmt.
4069
 
4070
      ---------------------------
4071
      -- Initialized_By_Access --
4072
      ---------------------------
4073
 
4074
      function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean is
4075
         Expr : constant Node_Id := Expression (Parent (Trans_Id));
4076
 
4077
      begin
4078
         return
4079
           Present (Expr)
4080
             and then Nkind (Expr) /= N_Reference
4081
             and then Is_Access_Type (Etype (Expr));
4082
      end Initialized_By_Access;
4083
 
4084
      ------------------------------------------
4085
      -- Initialized_By_Aliased_BIP_Func_Call --
4086
      ------------------------------------------
4087
 
4088
      function Initialized_By_Aliased_BIP_Func_Call
4089
        (Trans_Id : Entity_Id) return Boolean
4090
      is
4091
         Call : Node_Id := Expression (Parent (Trans_Id));
4092
 
4093
      begin
4094
         --  Build-in-place calls usually appear in 'reference format
4095
 
4096
         if Nkind (Call) = N_Reference then
4097
            Call := Prefix (Call);
4098
         end if;
4099
 
4100
         if Is_Build_In_Place_Function_Call (Call) then
4101
            declare
4102
               Access_Nam : Name_Id := No_Name;
4103
               Access_OK  : Boolean := False;
4104
               Actual     : Node_Id;
4105
               Alloc_Nam  : Name_Id := No_Name;
4106
               Alloc_OK   : Boolean := False;
4107
               Formal     : Node_Id;
4108
               Func_Id    : Entity_Id;
4109
               Param      : Node_Id;
4110
 
4111
            begin
4112
               --  Examine all parameter associations of the function call
4113
 
4114
               Param := First (Parameter_Associations (Call));
4115
               while Present (Param) loop
4116
                  if Nkind (Param) = N_Parameter_Association
4117
                    and then Nkind (Selector_Name (Param)) = N_Identifier
4118
                  then
4119
                     Actual := Explicit_Actual_Parameter (Param);
4120
                     Formal := Selector_Name (Param);
4121
 
4122
                     --  Construct the names of formals BIPaccess and BIPalloc
4123
                     --  using the function name retrieved from an arbitrary
4124
                     --  formal.
4125
 
4126
                     if Access_Nam = No_Name
4127
                       and then Alloc_Nam = No_Name
4128
                       and then Present (Entity (Formal))
4129
                     then
4130
                        Func_Id := Scope (Entity (Formal));
4131
 
4132
                        Access_Nam :=
4133
                          New_External_Name (Chars (Func_Id),
4134
                            BIP_Formal_Suffix (BIP_Object_Access));
4135
 
4136
                        Alloc_Nam :=
4137
                          New_External_Name (Chars (Func_Id),
4138
                            BIP_Formal_Suffix (BIP_Alloc_Form));
4139
                     end if;
4140
 
4141
                     --  A match for BIPaccess => Temp has been found
4142
 
4143
                     if Chars (Formal) = Access_Nam
4144
                       and then Nkind (Actual) /= N_Null
4145
                     then
4146
                        Access_OK := True;
4147
                     end if;
4148
 
4149
                     --  A match for BIPalloc => 1 has been found
4150
 
4151
                     if Chars (Formal) = Alloc_Nam
4152
                       and then Nkind (Actual) = N_Integer_Literal
4153
                       and then Intval (Actual) = Uint_1
4154
                     then
4155
                        Alloc_OK := True;
4156
                     end if;
4157
                  end if;
4158
 
4159
                  Next (Param);
4160
               end loop;
4161
 
4162
               return Access_OK and then Alloc_OK;
4163
            end;
4164
         end if;
4165
 
4166
         return False;
4167
      end Initialized_By_Aliased_BIP_Func_Call;
4168
 
4169
      ----------------
4170
      -- Is_Aliased --
4171
      ----------------
4172
 
4173
      function Is_Aliased
4174
        (Trans_Id   : Entity_Id;
4175
         First_Stmt : Node_Id) return Boolean
4176
      is
4177
         function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id;
4178
         --  Given an object renaming declaration, retrieve the entity of the
4179
         --  renamed name. Return Empty if the renamed name is anything other
4180
         --  than a variable or a constant.
4181
 
4182
         -------------------------
4183
         -- Find_Renamed_Object --
4184
         -------------------------
4185
 
4186
         function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id is
4187
            Ren_Obj : Node_Id := Empty;
4188
 
4189
            function Find_Object (N : Node_Id) return Traverse_Result;
4190
            --  Try to detect an object which is either a constant or a
4191
            --  variable.
4192
 
4193
            -----------------
4194
            -- Find_Object --
4195
            -----------------
4196
 
4197
            function Find_Object (N : Node_Id) return Traverse_Result is
4198
            begin
4199
               --  Stop the search once a constant or a variable has been
4200
               --  detected.
4201
 
4202
               if Nkind (N) = N_Identifier
4203
                 and then Present (Entity (N))
4204
                 and then Ekind_In (Entity (N), E_Constant, E_Variable)
4205
               then
4206
                  Ren_Obj := Entity (N);
4207
                  return Abandon;
4208
               end if;
4209
 
4210
               return OK;
4211
            end Find_Object;
4212
 
4213
            procedure Search is new Traverse_Proc (Find_Object);
4214
 
4215
            --  Local variables
4216
 
4217
            Typ : constant Entity_Id := Etype (Defining_Identifier (Ren_Decl));
4218
 
4219
         --  Start of processing for Find_Renamed_Object
4220
 
4221
         begin
4222
            --  Actions related to dispatching calls may appear as renamings of
4223
            --  tags. Do not process this type of renaming because it does not
4224
            --  use the actual value of the object.
4225
 
4226
            if not Is_RTE (Typ, RE_Tag_Ptr) then
4227
               Search (Name (Ren_Decl));
4228
            end if;
4229
 
4230
            return Ren_Obj;
4231
         end Find_Renamed_Object;
4232
 
4233
         --  Local variables
4234
 
4235
         Expr    : Node_Id;
4236
         Ren_Obj : Entity_Id;
4237
         Stmt    : Node_Id;
4238
 
4239
      --  Start of processing for Is_Aliased
4240
 
4241
      begin
4242
         Stmt := First_Stmt;
4243
         while Present (Stmt) loop
4244
            if Nkind (Stmt) = N_Object_Declaration then
4245
               Expr := Expression (Stmt);
4246
 
4247
               if Present (Expr)
4248
                 and then Nkind (Expr) = N_Reference
4249
                 and then Nkind (Prefix (Expr)) = N_Identifier
4250
                 and then Entity (Prefix (Expr)) = Trans_Id
4251
               then
4252
                  return True;
4253
               end if;
4254
 
4255
            elsif Nkind (Stmt) = N_Object_Renaming_Declaration then
4256
               Ren_Obj := Find_Renamed_Object (Stmt);
4257
 
4258
               if Present (Ren_Obj)
4259
                 and then Ren_Obj = Trans_Id
4260
               then
4261
                  return True;
4262
               end if;
4263
            end if;
4264
 
4265
            Next (Stmt);
4266
         end loop;
4267
 
4268
         return False;
4269
      end Is_Aliased;
4270
 
4271
      ------------------
4272
      -- Is_Allocated --
4273
      ------------------
4274
 
4275
      function Is_Allocated (Trans_Id : Entity_Id) return Boolean is
4276
         Expr : constant Node_Id := Expression (Parent (Trans_Id));
4277
      begin
4278
         return
4279
           Is_Access_Type (Etype (Trans_Id))
4280
             and then Present (Expr)
4281
             and then Nkind (Expr) = N_Allocator;
4282
      end Is_Allocated;
4283
 
4284
      ---------------------------
4285
      -- Is_Iterated_Container --
4286
      ---------------------------
4287
 
4288
      function Is_Iterated_Container
4289
        (Trans_Id   : Entity_Id;
4290
         First_Stmt : Node_Id) return Boolean
4291
      is
4292
         Aspect : Node_Id;
4293
         Call   : Node_Id;
4294
         Iter   : Entity_Id;
4295
         Param  : Node_Id;
4296
         Stmt   : Node_Id;
4297
         Typ    : Entity_Id;
4298
 
4299
      begin
4300
         --  It is not possible to iterate over containers in non-Ada 2012 code
4301
 
4302
         if Ada_Version < Ada_2012 then
4303
            return False;
4304
         end if;
4305
 
4306
         Typ := Etype (Trans_Id);
4307
 
4308
         --  Handle access type created for secondary stack use
4309
 
4310
         if Is_Access_Type (Typ) then
4311
            Typ := Designated_Type (Typ);
4312
         end if;
4313
 
4314
         --  Look for aspect Default_Iterator
4315
 
4316
         if Has_Aspects (Parent (Typ)) then
4317
            Aspect := Find_Aspect (Typ, Aspect_Default_Iterator);
4318
 
4319
            if Present (Aspect) then
4320
               Iter := Entity (Aspect);
4321
 
4322
               --  Examine the statements following the container object and
4323
               --  look for a call to the default iterate routine where the
4324
               --  first parameter is the transient. Such a call appears as:
4325
 
4326
               --     It : Access_To_CW_Iterator :=
4327
               --            Iterate (Tran_Id.all, ...)'reference;
4328
 
4329
               Stmt := First_Stmt;
4330
               while Present (Stmt) loop
4331
 
4332
                  --  Detect an object declaration which is initialized by a
4333
                  --  secondary stack function call.
4334
 
4335
                  if Nkind (Stmt) = N_Object_Declaration
4336
                    and then Present (Expression (Stmt))
4337
                    and then Nkind (Expression (Stmt)) = N_Reference
4338
                    and then Nkind (Prefix (Expression (Stmt))) =
4339
                               N_Function_Call
4340
                  then
4341
                     Call := Prefix (Expression (Stmt));
4342
 
4343
                     --  The call must invoke the default iterate routine of
4344
                     --  the container and the transient object must appear as
4345
                     --  the first actual parameter. Skip any calls whose names
4346
                     --  are not entities.
4347
 
4348
                     if Is_Entity_Name (Name (Call))
4349
                       and then Entity (Name (Call)) = Iter
4350
                       and then Present (Parameter_Associations (Call))
4351
                     then
4352
                        Param := First (Parameter_Associations (Call));
4353
 
4354
                        if Nkind (Param) = N_Explicit_Dereference
4355
                          and then Entity (Prefix (Param)) = Trans_Id
4356
                        then
4357
                           return True;
4358
                        end if;
4359
                     end if;
4360
                  end if;
4361
 
4362
                  Next (Stmt);
4363
               end loop;
4364
            end if;
4365
         end if;
4366
 
4367
         return False;
4368
      end Is_Iterated_Container;
4369
 
4370
   --  Start of processing for Is_Finalizable_Transient
4371
 
4372
   begin
4373
      --  Handle access types
4374
 
4375
      if Is_Access_Type (Desig) then
4376
         Desig := Available_View (Designated_Type (Desig));
4377
      end if;
4378
 
4379
      return
4380
        Ekind_In (Obj_Id, E_Constant, E_Variable)
4381
          and then Needs_Finalization (Desig)
4382
          and then Requires_Transient_Scope (Desig)
4383
          and then Nkind (Rel_Node) /= N_Simple_Return_Statement
4384
 
4385
          --  Do not consider renamed or 'reference-d transient objects because
4386
          --  the act of renaming extends the object's lifetime.
4387
 
4388
          and then not Is_Aliased (Obj_Id, Decl)
4389
 
4390
          --  Do not consider transient objects allocated on the heap since
4391
          --  they are attached to a finalization master.
4392
 
4393
          and then not Is_Allocated (Obj_Id)
4394
 
4395
          --  If the transient object is a pointer, check that it is not
4396
          --  initialized by a function which returns a pointer or acts as a
4397
          --  renaming of another pointer.
4398
 
4399
          and then
4400
            (not Is_Access_Type (Obj_Typ)
4401
               or else not Initialized_By_Access (Obj_Id))
4402
 
4403
          --  Do not consider transient objects which act as indirect aliases
4404
          --  of build-in-place function results.
4405
 
4406
          and then not Initialized_By_Aliased_BIP_Func_Call (Obj_Id)
4407
 
4408
          --  Do not consider conversions of tags to class-wide types
4409
 
4410
          and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id)
4411
 
4412
          --  Do not consider containers in the context of iterator loops. Such
4413
          --  transient objects must exist for as long as the loop is around,
4414
          --  otherwise any operation carried out by the iterator will fail.
4415
 
4416
          and then not Is_Iterated_Container (Obj_Id, Decl);
4417
   end Is_Finalizable_Transient;
4418
 
4419
   ---------------------------------
4420
   -- Is_Fully_Repped_Tagged_Type --
4421
   ---------------------------------
4422
 
4423
   function Is_Fully_Repped_Tagged_Type (T : Entity_Id) return Boolean is
4424
      U    : constant Entity_Id := Underlying_Type (T);
4425
      Comp : Entity_Id;
4426
 
4427
   begin
4428
      if No (U) or else not Is_Tagged_Type (U) then
4429
         return False;
4430
      elsif Has_Discriminants (U) then
4431
         return False;
4432
      elsif not Has_Specified_Layout (U) then
4433
         return False;
4434
      end if;
4435
 
4436
      --  Here we have a tagged type, see if it has any unlayed out fields
4437
      --  other than a possible tag and parent fields. If so, we return False.
4438
 
4439
      Comp := First_Component (U);
4440
      while Present (Comp) loop
4441
         if not Is_Tag (Comp)
4442
           and then Chars (Comp) /= Name_uParent
4443
           and then No (Component_Clause (Comp))
4444
         then
4445
            return False;
4446
         else
4447
            Next_Component (Comp);
4448
         end if;
4449
      end loop;
4450
 
4451
      --  All components are layed out
4452
 
4453
      return True;
4454
   end Is_Fully_Repped_Tagged_Type;
4455
 
4456
   ----------------------------------
4457
   -- Is_Library_Level_Tagged_Type --
4458
   ----------------------------------
4459
 
4460
   function Is_Library_Level_Tagged_Type (Typ : Entity_Id) return Boolean is
4461
   begin
4462
      return Is_Tagged_Type (Typ)
4463
        and then Is_Library_Level_Entity (Typ);
4464
   end Is_Library_Level_Tagged_Type;
4465
 
4466
   ----------------------------------
4467
   -- Is_Null_Access_BIP_Func_Call --
4468
   ----------------------------------
4469
 
4470
   function Is_Null_Access_BIP_Func_Call (Expr : Node_Id) return Boolean is
4471
      Call : Node_Id := Expr;
4472
 
4473
   begin
4474
      --  Build-in-place calls usually appear in 'reference format
4475
 
4476
      if Nkind (Call) = N_Reference then
4477
         Call := Prefix (Call);
4478
      end if;
4479
 
4480
      if Nkind_In (Call, N_Qualified_Expression,
4481
                         N_Unchecked_Type_Conversion)
4482
      then
4483
         Call := Expression (Call);
4484
      end if;
4485
 
4486
      if Is_Build_In_Place_Function_Call (Call) then
4487
         declare
4488
            Access_Nam : Name_Id := No_Name;
4489
            Actual     : Node_Id;
4490
            Param      : Node_Id;
4491
            Formal     : Node_Id;
4492
 
4493
         begin
4494
            --  Examine all parameter associations of the function call
4495
 
4496
            Param := First (Parameter_Associations (Call));
4497
            while Present (Param) loop
4498
               if Nkind (Param) = N_Parameter_Association
4499
                 and then Nkind (Selector_Name (Param)) = N_Identifier
4500
               then
4501
                  Formal := Selector_Name (Param);
4502
                  Actual := Explicit_Actual_Parameter (Param);
4503
 
4504
                  --  Construct the name of formal BIPaccess. It is much easier
4505
                  --  to extract the name of the function using an arbitrary
4506
                  --  formal's scope rather than the Name field of Call.
4507
 
4508
                  if Access_Nam = No_Name
4509
                    and then Present (Entity (Formal))
4510
                  then
4511
                     Access_Nam :=
4512
                       New_External_Name
4513
                         (Chars (Scope (Entity (Formal))),
4514
                          BIP_Formal_Suffix (BIP_Object_Access));
4515
                  end if;
4516
 
4517
                  --  A match for BIPaccess => null has been found
4518
 
4519
                  if Chars (Formal) = Access_Nam
4520
                    and then Nkind (Actual) = N_Null
4521
                  then
4522
                     return True;
4523
                  end if;
4524
               end if;
4525
 
4526
               Next (Param);
4527
            end loop;
4528
         end;
4529
      end if;
4530
 
4531
      return False;
4532
   end Is_Null_Access_BIP_Func_Call;
4533
 
4534
   --------------------------
4535
   -- Is_Non_BIP_Func_Call --
4536
   --------------------------
4537
 
4538
   function Is_Non_BIP_Func_Call (Expr : Node_Id) return Boolean is
4539
   begin
4540
      --  The expected call is of the format
4541
      --
4542
      --    Func_Call'reference
4543
 
4544
      return
4545
        Nkind (Expr) = N_Reference
4546
          and then Nkind (Prefix (Expr)) = N_Function_Call
4547
          and then not Is_Build_In_Place_Function_Call (Prefix (Expr));
4548
   end Is_Non_BIP_Func_Call;
4549
 
4550
   ----------------------------------
4551
   -- Is_Possibly_Unaligned_Object --
4552
   ----------------------------------
4553
 
4554
   function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean is
4555
      T  : constant Entity_Id := Etype (N);
4556
 
4557
   begin
4558
      --  If renamed object, apply test to underlying object
4559
 
4560
      if Is_Entity_Name (N)
4561
        and then Is_Object (Entity (N))
4562
        and then Present (Renamed_Object (Entity (N)))
4563
      then
4564
         return Is_Possibly_Unaligned_Object (Renamed_Object (Entity (N)));
4565
      end if;
4566
 
4567
      --  Tagged and controlled types and aliased types are always aligned, as
4568
      --  are concurrent types.
4569
 
4570
      if Is_Aliased (T)
4571
        or else Has_Controlled_Component (T)
4572
        or else Is_Concurrent_Type (T)
4573
        or else Is_Tagged_Type (T)
4574
        or else Is_Controlled (T)
4575
      then
4576
         return False;
4577
      end if;
4578
 
4579
      --  If this is an element of a packed array, may be unaligned
4580
 
4581
      if Is_Ref_To_Bit_Packed_Array (N) then
4582
         return True;
4583
      end if;
4584
 
4585
      --  Case of indexed component reference: test whether prefix is unaligned
4586
 
4587
      if Nkind (N) = N_Indexed_Component then
4588
         return Is_Possibly_Unaligned_Object (Prefix (N));
4589
 
4590
      --  Case of selected component reference
4591
 
4592
      elsif Nkind (N) = N_Selected_Component then
4593
         declare
4594
            P : constant Node_Id   := Prefix (N);
4595
            C : constant Entity_Id := Entity (Selector_Name (N));
4596
            M : Nat;
4597
            S : Nat;
4598
 
4599
         begin
4600
            --  If component reference is for an array with non-static bounds,
4601
            --  then it is always aligned: we can only process unaligned arrays
4602
            --  with static bounds (more precisely compile time known bounds).
4603
 
4604
            if Is_Array_Type (T)
4605
              and then not Compile_Time_Known_Bounds (T)
4606
            then
4607
               return False;
4608
            end if;
4609
 
4610
            --  If component is aliased, it is definitely properly aligned
4611
 
4612
            if Is_Aliased (C) then
4613
               return False;
4614
            end if;
4615
 
4616
            --  If component is for a type implemented as a scalar, and the
4617
            --  record is packed, and the component is other than the first
4618
            --  component of the record, then the component may be unaligned.
4619
 
4620
            if Is_Packed (Etype (P))
4621
              and then Represented_As_Scalar (Etype (C))
4622
              and then First_Entity (Scope (C)) /= C
4623
            then
4624
               return True;
4625
            end if;
4626
 
4627
            --  Compute maximum possible alignment for T
4628
 
4629
            --  If alignment is known, then that settles things
4630
 
4631
            if Known_Alignment (T) then
4632
               M := UI_To_Int (Alignment (T));
4633
 
4634
            --  If alignment is not known, tentatively set max alignment
4635
 
4636
            else
4637
               M := Ttypes.Maximum_Alignment;
4638
 
4639
               --  We can reduce this if the Esize is known since the default
4640
               --  alignment will never be more than the smallest power of 2
4641
               --  that does not exceed this Esize value.
4642
 
4643
               if Known_Esize (T) then
4644
                  S := UI_To_Int (Esize (T));
4645
 
4646
                  while (M / 2) >= S loop
4647
                     M := M / 2;
4648
                  end loop;
4649
               end if;
4650
            end if;
4651
 
4652
            --  The following code is historical, it used to be present but it
4653
            --  is too cautious, because the front-end does not know the proper
4654
            --  default alignments for the target. Also, if the alignment is
4655
            --  not known, the front end can't know in any case! If a copy is
4656
            --  needed, the back-end will take care of it. This whole section
4657
            --  including this comment can be removed later ???
4658
 
4659
            --  If the component reference is for a record that has a specified
4660
            --  alignment, and we either know it is too small, or cannot tell,
4661
            --  then the component may be unaligned.
4662
 
4663
            --  What is the following commented out code ???
4664
 
4665
            --  if Known_Alignment (Etype (P))
4666
            --    and then Alignment (Etype (P)) < Ttypes.Maximum_Alignment
4667
            --    and then M > Alignment (Etype (P))
4668
            --  then
4669
            --     return True;
4670
            --  end if;
4671
 
4672
            --  Case of component clause present which may specify an
4673
            --  unaligned position.
4674
 
4675
            if Present (Component_Clause (C)) then
4676
 
4677
               --  Otherwise we can do a test to make sure that the actual
4678
               --  start position in the record, and the length, are both
4679
               --  consistent with the required alignment. If not, we know
4680
               --  that we are unaligned.
4681
 
4682
               declare
4683
                  Align_In_Bits : constant Nat := M * System_Storage_Unit;
4684
               begin
4685
                  if Component_Bit_Offset (C) mod Align_In_Bits /= 0
4686
                    or else Esize (C) mod Align_In_Bits /= 0
4687
                  then
4688
                     return True;
4689
                  end if;
4690
               end;
4691
            end if;
4692
 
4693
            --  Otherwise, for a component reference, test prefix
4694
 
4695
            return Is_Possibly_Unaligned_Object (P);
4696
         end;
4697
 
4698
      --  If not a component reference, must be aligned
4699
 
4700
      else
4701
         return False;
4702
      end if;
4703
   end Is_Possibly_Unaligned_Object;
4704
 
4705
   ---------------------------------
4706
   -- Is_Possibly_Unaligned_Slice --
4707
   ---------------------------------
4708
 
4709
   function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean is
4710
   begin
4711
      --  Go to renamed object
4712
 
4713
      if Is_Entity_Name (N)
4714
        and then Is_Object (Entity (N))
4715
        and then Present (Renamed_Object (Entity (N)))
4716
      then
4717
         return Is_Possibly_Unaligned_Slice (Renamed_Object (Entity (N)));
4718
      end if;
4719
 
4720
      --  The reference must be a slice
4721
 
4722
      if Nkind (N) /= N_Slice then
4723
         return False;
4724
      end if;
4725
 
4726
      --  Always assume the worst for a nested record component with a
4727
      --  component clause, which gigi/gcc does not appear to handle well.
4728
      --  It is not clear why this special test is needed at all ???
4729
 
4730
      if Nkind (Prefix (N)) = N_Selected_Component
4731
        and then Nkind (Prefix (Prefix (N))) = N_Selected_Component
4732
        and then
4733
          Present (Component_Clause (Entity (Selector_Name (Prefix (N)))))
4734
      then
4735
         return True;
4736
      end if;
4737
 
4738
      --  We only need to worry if the target has strict alignment
4739
 
4740
      if not Target_Strict_Alignment then
4741
         return False;
4742
      end if;
4743
 
4744
      --  If it is a slice, then look at the array type being sliced
4745
 
4746
      declare
4747
         Sarr : constant Node_Id := Prefix (N);
4748
         --  Prefix of the slice, i.e. the array being sliced
4749
 
4750
         Styp : constant Entity_Id := Etype (Prefix (N));
4751
         --  Type of the array being sliced
4752
 
4753
         Pref : Node_Id;
4754
         Ptyp : Entity_Id;
4755
 
4756
      begin
4757
         --  The problems arise if the array object that is being sliced
4758
         --  is a component of a record or array, and we cannot guarantee
4759
         --  the alignment of the array within its containing object.
4760
 
4761
         --  To investigate this, we look at successive prefixes to see
4762
         --  if we have a worrisome indexed or selected component.
4763
 
4764
         Pref := Sarr;
4765
         loop
4766
            --  Case of array is part of an indexed component reference
4767
 
4768
            if Nkind (Pref) = N_Indexed_Component then
4769
               Ptyp := Etype (Prefix (Pref));
4770
 
4771
               --  The only problematic case is when the array is packed, in
4772
               --  which case we really know nothing about the alignment of
4773
               --  individual components.
4774
 
4775
               if Is_Bit_Packed_Array (Ptyp) then
4776
                  return True;
4777
               end if;
4778
 
4779
            --  Case of array is part of a selected component reference
4780
 
4781
            elsif Nkind (Pref) = N_Selected_Component then
4782
               Ptyp := Etype (Prefix (Pref));
4783
 
4784
               --  We are definitely in trouble if the record in question
4785
               --  has an alignment, and either we know this alignment is
4786
               --  inconsistent with the alignment of the slice, or we don't
4787
               --  know what the alignment of the slice should be.
4788
 
4789
               if Known_Alignment (Ptyp)
4790
                 and then (Unknown_Alignment (Styp)
4791
                             or else Alignment (Styp) > Alignment (Ptyp))
4792
               then
4793
                  return True;
4794
               end if;
4795
 
4796
               --  We are in potential trouble if the record type is packed.
4797
               --  We could special case when we know that the array is the
4798
               --  first component, but that's not such a simple case ???
4799
 
4800
               if Is_Packed (Ptyp) then
4801
                  return True;
4802
               end if;
4803
 
4804
               --  We are in trouble if there is a component clause, and
4805
               --  either we do not know the alignment of the slice, or
4806
               --  the alignment of the slice is inconsistent with the
4807
               --  bit position specified by the component clause.
4808
 
4809
               declare
4810
                  Field : constant Entity_Id := Entity (Selector_Name (Pref));
4811
               begin
4812
                  if Present (Component_Clause (Field))
4813
                    and then
4814
                      (Unknown_Alignment (Styp)
4815
                        or else
4816
                         (Component_Bit_Offset (Field) mod
4817
                           (System_Storage_Unit * Alignment (Styp))) /= 0)
4818
                  then
4819
                     return True;
4820
                  end if;
4821
               end;
4822
 
4823
            --  For cases other than selected or indexed components we know we
4824
            --  are OK, since no issues arise over alignment.
4825
 
4826
            else
4827
               return False;
4828
            end if;
4829
 
4830
            --  We processed an indexed component or selected component
4831
            --  reference that looked safe, so keep checking prefixes.
4832
 
4833
            Pref := Prefix (Pref);
4834
         end loop;
4835
      end;
4836
   end Is_Possibly_Unaligned_Slice;
4837
 
4838
   -------------------------------
4839
   -- Is_Related_To_Func_Return --
4840
   -------------------------------
4841
 
4842
   function Is_Related_To_Func_Return (Id : Entity_Id) return Boolean is
4843
      Expr : constant Node_Id := Related_Expression (Id);
4844
   begin
4845
      return
4846
        Present (Expr)
4847
          and then Nkind (Expr) = N_Explicit_Dereference
4848
          and then Nkind (Parent (Expr)) = N_Simple_Return_Statement;
4849
   end Is_Related_To_Func_Return;
4850
 
4851
   --------------------------------
4852
   -- Is_Ref_To_Bit_Packed_Array --
4853
   --------------------------------
4854
 
4855
   function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean is
4856
      Result : Boolean;
4857
      Expr   : Node_Id;
4858
 
4859
   begin
4860
      if Is_Entity_Name (N)
4861
        and then Is_Object (Entity (N))
4862
        and then Present (Renamed_Object (Entity (N)))
4863
      then
4864
         return Is_Ref_To_Bit_Packed_Array (Renamed_Object (Entity (N)));
4865
      end if;
4866
 
4867
      if Nkind (N) = N_Indexed_Component
4868
           or else
4869
         Nkind (N) = N_Selected_Component
4870
      then
4871
         if Is_Bit_Packed_Array (Etype (Prefix (N))) then
4872
            Result := True;
4873
         else
4874
            Result := Is_Ref_To_Bit_Packed_Array (Prefix (N));
4875
         end if;
4876
 
4877
         if Result and then Nkind (N) = N_Indexed_Component then
4878
            Expr := First (Expressions (N));
4879
            while Present (Expr) loop
4880
               Force_Evaluation (Expr);
4881
               Next (Expr);
4882
            end loop;
4883
         end if;
4884
 
4885
         return Result;
4886
 
4887
      else
4888
         return False;
4889
      end if;
4890
   end Is_Ref_To_Bit_Packed_Array;
4891
 
4892
   --------------------------------
4893
   -- Is_Ref_To_Bit_Packed_Slice --
4894
   --------------------------------
4895
 
4896
   function Is_Ref_To_Bit_Packed_Slice (N : Node_Id) return Boolean is
4897
   begin
4898
      if Nkind (N) = N_Type_Conversion then
4899
         return Is_Ref_To_Bit_Packed_Slice (Expression (N));
4900
 
4901
      elsif Is_Entity_Name (N)
4902
        and then Is_Object (Entity (N))
4903
        and then Present (Renamed_Object (Entity (N)))
4904
      then
4905
         return Is_Ref_To_Bit_Packed_Slice (Renamed_Object (Entity (N)));
4906
 
4907
      elsif Nkind (N) = N_Slice
4908
        and then Is_Bit_Packed_Array (Etype (Prefix (N)))
4909
      then
4910
         return True;
4911
 
4912
      elsif Nkind (N) = N_Indexed_Component
4913
           or else
4914
         Nkind (N) = N_Selected_Component
4915
      then
4916
         return Is_Ref_To_Bit_Packed_Slice (Prefix (N));
4917
 
4918
      else
4919
         return False;
4920
      end if;
4921
   end Is_Ref_To_Bit_Packed_Slice;
4922
 
4923
   -----------------------
4924
   -- Is_Renamed_Object --
4925
   -----------------------
4926
 
4927
   function Is_Renamed_Object (N : Node_Id) return Boolean is
4928
      Pnod : constant Node_Id   := Parent (N);
4929
      Kind : constant Node_Kind := Nkind (Pnod);
4930
   begin
4931
      if Kind = N_Object_Renaming_Declaration then
4932
         return True;
4933
      elsif Nkind_In (Kind, N_Indexed_Component, N_Selected_Component) then
4934
         return Is_Renamed_Object (Pnod);
4935
      else
4936
         return False;
4937
      end if;
4938
   end Is_Renamed_Object;
4939
 
4940
   -------------------------------------
4941
   -- Is_Tag_To_Class_Wide_Conversion --
4942
   -------------------------------------
4943
 
4944
   function Is_Tag_To_Class_Wide_Conversion
4945
     (Obj_Id : Entity_Id) return Boolean
4946
   is
4947
      Expr : constant Node_Id := Expression (Parent (Obj_Id));
4948
 
4949
   begin
4950
      return
4951
        Is_Class_Wide_Type (Etype (Obj_Id))
4952
          and then Present (Expr)
4953
          and then Nkind (Expr) = N_Unchecked_Type_Conversion
4954
          and then Etype (Expression (Expr)) = RTE (RE_Tag);
4955
   end Is_Tag_To_Class_Wide_Conversion;
4956
 
4957
   ----------------------------
4958
   -- Is_Untagged_Derivation --
4959
   ----------------------------
4960
 
4961
   function Is_Untagged_Derivation (T : Entity_Id) return Boolean is
4962
   begin
4963
      return (not Is_Tagged_Type (T) and then Is_Derived_Type (T))
4964
               or else
4965
             (Is_Private_Type (T) and then Present (Full_View (T))
4966
               and then not Is_Tagged_Type (Full_View (T))
4967
               and then Is_Derived_Type (Full_View (T))
4968
               and then Etype (Full_View (T)) /= T);
4969
   end Is_Untagged_Derivation;
4970
 
4971
   ---------------------------
4972
   -- Is_Volatile_Reference --
4973
   ---------------------------
4974
 
4975
   function Is_Volatile_Reference (N : Node_Id) return Boolean is
4976
   begin
4977
      if Nkind (N) in N_Has_Etype
4978
        and then Present (Etype (N))
4979
        and then Treat_As_Volatile (Etype (N))
4980
      then
4981
         return True;
4982
 
4983
      elsif Is_Entity_Name (N) then
4984
         return Treat_As_Volatile (Entity (N));
4985
 
4986
      elsif Nkind (N) = N_Slice then
4987
         return Is_Volatile_Reference (Prefix (N));
4988
 
4989
      elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
4990
         if (Is_Entity_Name (Prefix (N))
4991
               and then Has_Volatile_Components (Entity (Prefix (N))))
4992
           or else (Present (Etype (Prefix (N)))
4993
                      and then Has_Volatile_Components (Etype (Prefix (N))))
4994
         then
4995
            return True;
4996
         else
4997
            return Is_Volatile_Reference (Prefix (N));
4998
         end if;
4999
 
5000
      else
5001
         return False;
5002
      end if;
5003
   end Is_Volatile_Reference;
5004
 
5005
   --------------------------
5006
   -- Is_VM_By_Copy_Actual --
5007
   --------------------------
5008
 
5009
   function Is_VM_By_Copy_Actual (N : Node_Id) return Boolean is
5010
   begin
5011
      return VM_Target /= No_VM
5012
        and then (Nkind (N) = N_Slice
5013
                    or else
5014
                      (Nkind (N) = N_Identifier
5015
                         and then Present (Renamed_Object (Entity (N)))
5016
                         and then Nkind (Renamed_Object (Entity (N)))
5017
                                    = N_Slice));
5018
   end Is_VM_By_Copy_Actual;
5019
 
5020
   --------------------
5021
   -- Kill_Dead_Code --
5022
   --------------------
5023
 
5024
   procedure Kill_Dead_Code (N : Node_Id; Warn : Boolean := False) is
5025
      W : Boolean := Warn;
5026
      --  Set False if warnings suppressed
5027
 
5028
   begin
5029
      if Present (N) then
5030
         Remove_Warning_Messages (N);
5031
 
5032
         --  Generate warning if appropriate
5033
 
5034
         if W then
5035
 
5036
            --  We suppress the warning if this code is under control of an
5037
            --  if statement, whose condition is a simple identifier, and
5038
            --  either we are in an instance, or warnings off is set for this
5039
            --  identifier. The reason for killing it in the instance case is
5040
            --  that it is common and reasonable for code to be deleted in
5041
            --  instances for various reasons.
5042
 
5043
            if Nkind (Parent (N)) = N_If_Statement then
5044
               declare
5045
                  C : constant Node_Id := Condition (Parent (N));
5046
               begin
5047
                  if Nkind (C) = N_Identifier
5048
                    and then
5049
                      (In_Instance
5050
                        or else (Present (Entity (C))
5051
                                   and then Has_Warnings_Off (Entity (C))))
5052
                  then
5053
                     W := False;
5054
                  end if;
5055
               end;
5056
            end if;
5057
 
5058
            --  Generate warning if not suppressed
5059
 
5060
            if W then
5061
               Error_Msg_F
5062
                 ("?this code can never be executed and has been deleted!", N);
5063
            end if;
5064
         end if;
5065
 
5066
         --  Recurse into block statements and bodies to process declarations
5067
         --  and statements.
5068
 
5069
         if Nkind (N) = N_Block_Statement
5070
           or else Nkind (N) = N_Subprogram_Body
5071
           or else Nkind (N) = N_Package_Body
5072
         then
5073
            Kill_Dead_Code (Declarations (N), False);
5074
            Kill_Dead_Code (Statements (Handled_Statement_Sequence (N)));
5075
 
5076
            if Nkind (N) = N_Subprogram_Body then
5077
               Set_Is_Eliminated (Defining_Entity (N));
5078
            end if;
5079
 
5080
         elsif Nkind (N) = N_Package_Declaration then
5081
            Kill_Dead_Code (Visible_Declarations (Specification (N)));
5082
            Kill_Dead_Code (Private_Declarations (Specification (N)));
5083
 
5084
            --  ??? After this point, Delete_Tree has been called on all
5085
            --  declarations in Specification (N), so references to entities
5086
            --  therein look suspicious.
5087
 
5088
            declare
5089
               E : Entity_Id := First_Entity (Defining_Entity (N));
5090
            begin
5091
               while Present (E) loop
5092
                  if Ekind (E) = E_Operator then
5093
                     Set_Is_Eliminated (E);
5094
                  end if;
5095
 
5096
                  Next_Entity (E);
5097
               end loop;
5098
            end;
5099
 
5100
         --  Recurse into composite statement to kill individual statements in
5101
         --  particular instantiations.
5102
 
5103
         elsif Nkind (N) = N_If_Statement then
5104
            Kill_Dead_Code (Then_Statements (N));
5105
            Kill_Dead_Code (Elsif_Parts (N));
5106
            Kill_Dead_Code (Else_Statements (N));
5107
 
5108
         elsif Nkind (N) = N_Loop_Statement then
5109
            Kill_Dead_Code (Statements (N));
5110
 
5111
         elsif Nkind (N) = N_Case_Statement then
5112
            declare
5113
               Alt : Node_Id;
5114
            begin
5115
               Alt := First (Alternatives (N));
5116
               while Present (Alt) loop
5117
                  Kill_Dead_Code (Statements (Alt));
5118
                  Next (Alt);
5119
               end loop;
5120
            end;
5121
 
5122
         elsif Nkind (N) = N_Case_Statement_Alternative then
5123
            Kill_Dead_Code (Statements (N));
5124
 
5125
         --  Deal with dead instances caused by deleting instantiations
5126
 
5127
         elsif Nkind (N) in N_Generic_Instantiation then
5128
            Remove_Dead_Instance (N);
5129
         end if;
5130
      end if;
5131
   end Kill_Dead_Code;
5132
 
5133
   --  Case where argument is a list of nodes to be killed
5134
 
5135
   procedure Kill_Dead_Code (L : List_Id; Warn : Boolean := False) is
5136
      N : Node_Id;
5137
      W : Boolean;
5138
   begin
5139
      W := Warn;
5140
      if Is_Non_Empty_List (L) then
5141
         N := First (L);
5142
         while Present (N) loop
5143
            Kill_Dead_Code (N, W);
5144
            W := False;
5145
            Next (N);
5146
         end loop;
5147
      end if;
5148
   end Kill_Dead_Code;
5149
 
5150
   ------------------------
5151
   -- Known_Non_Negative --
5152
   ------------------------
5153
 
5154
   function Known_Non_Negative (Opnd : Node_Id) return Boolean is
5155
   begin
5156
      if Is_OK_Static_Expression (Opnd)
5157
        and then Expr_Value (Opnd) >= 0
5158
      then
5159
         return True;
5160
 
5161
      else
5162
         declare
5163
            Lo : constant Node_Id := Type_Low_Bound (Etype (Opnd));
5164
 
5165
         begin
5166
            return
5167
              Is_OK_Static_Expression (Lo) and then Expr_Value (Lo) >= 0;
5168
         end;
5169
      end if;
5170
   end Known_Non_Negative;
5171
 
5172
   --------------------
5173
   -- Known_Non_Null --
5174
   --------------------
5175
 
5176
   function Known_Non_Null (N : Node_Id) return Boolean is
5177
   begin
5178
      --  Checks for case where N is an entity reference
5179
 
5180
      if Is_Entity_Name (N) and then Present (Entity (N)) then
5181
         declare
5182
            E   : constant Entity_Id := Entity (N);
5183
            Op  : Node_Kind;
5184
            Val : Node_Id;
5185
 
5186
         begin
5187
            --  First check if we are in decisive conditional
5188
 
5189
            Get_Current_Value_Condition (N, Op, Val);
5190
 
5191
            if Known_Null (Val) then
5192
               if Op = N_Op_Eq then
5193
                  return False;
5194
               elsif Op = N_Op_Ne then
5195
                  return True;
5196
               end if;
5197
            end if;
5198
 
5199
            --  If OK to do replacement, test Is_Known_Non_Null flag
5200
 
5201
            if OK_To_Do_Constant_Replacement (E) then
5202
               return Is_Known_Non_Null (E);
5203
 
5204
            --  Otherwise if not safe to do replacement, then say so
5205
 
5206
            else
5207
               return False;
5208
            end if;
5209
         end;
5210
 
5211
      --  True if access attribute
5212
 
5213
      elsif Nkind (N) = N_Attribute_Reference
5214
        and then (Attribute_Name (N) = Name_Access
5215
                    or else
5216
                  Attribute_Name (N) = Name_Unchecked_Access
5217
                    or else
5218
                  Attribute_Name (N) = Name_Unrestricted_Access)
5219
      then
5220
         return True;
5221
 
5222
      --  True if allocator
5223
 
5224
      elsif Nkind (N) = N_Allocator then
5225
         return True;
5226
 
5227
      --  For a conversion, true if expression is known non-null
5228
 
5229
      elsif Nkind (N) = N_Type_Conversion then
5230
         return Known_Non_Null (Expression (N));
5231
 
5232
      --  Above are all cases where the value could be determined to be
5233
      --  non-null. In all other cases, we don't know, so return False.
5234
 
5235
      else
5236
         return False;
5237
      end if;
5238
   end Known_Non_Null;
5239
 
5240
   ----------------
5241
   -- Known_Null --
5242
   ----------------
5243
 
5244
   function Known_Null (N : Node_Id) return Boolean is
5245
   begin
5246
      --  Checks for case where N is an entity reference
5247
 
5248
      if Is_Entity_Name (N) and then Present (Entity (N)) then
5249
         declare
5250
            E   : constant Entity_Id := Entity (N);
5251
            Op  : Node_Kind;
5252
            Val : Node_Id;
5253
 
5254
         begin
5255
            --  Constant null value is for sure null
5256
 
5257
            if Ekind (E) = E_Constant
5258
              and then Known_Null (Constant_Value (E))
5259
            then
5260
               return True;
5261
            end if;
5262
 
5263
            --  First check if we are in decisive conditional
5264
 
5265
            Get_Current_Value_Condition (N, Op, Val);
5266
 
5267
            if Known_Null (Val) then
5268
               if Op = N_Op_Eq then
5269
                  return True;
5270
               elsif Op = N_Op_Ne then
5271
                  return False;
5272
               end if;
5273
            end if;
5274
 
5275
            --  If OK to do replacement, test Is_Known_Null flag
5276
 
5277
            if OK_To_Do_Constant_Replacement (E) then
5278
               return Is_Known_Null (E);
5279
 
5280
            --  Otherwise if not safe to do replacement, then say so
5281
 
5282
            else
5283
               return False;
5284
            end if;
5285
         end;
5286
 
5287
      --  True if explicit reference to null
5288
 
5289
      elsif Nkind (N) = N_Null then
5290
         return True;
5291
 
5292
      --  For a conversion, true if expression is known null
5293
 
5294
      elsif Nkind (N) = N_Type_Conversion then
5295
         return Known_Null (Expression (N));
5296
 
5297
      --  Above are all cases where the value could be determined to be null.
5298
      --  In all other cases, we don't know, so return False.
5299
 
5300
      else
5301
         return False;
5302
      end if;
5303
   end Known_Null;
5304
 
5305
   -----------------------------
5306
   -- Make_CW_Equivalent_Type --
5307
   -----------------------------
5308
 
5309
   --  Create a record type used as an equivalent of any member of the class
5310
   --  which takes its size from exp.
5311
 
5312
   --  Generate the following code:
5313
 
5314
   --   type Equiv_T is record
5315
   --     _parent :  T (List of discriminant constraints taken from Exp);
5316
   --     Ext__50 : Storage_Array (1 .. (Exp'size - Typ'object_size)/8);
5317
   --   end Equiv_T;
5318
   --
5319
   --   ??? Note that this type does not guarantee same alignment as all
5320
   --   derived types
5321
 
5322
   function Make_CW_Equivalent_Type
5323
     (T : Entity_Id;
5324
      E : Node_Id) return Entity_Id
5325
   is
5326
      Loc         : constant Source_Ptr := Sloc (E);
5327
      Root_Typ    : constant Entity_Id  := Root_Type (T);
5328
      List_Def    : constant List_Id    := Empty_List;
5329
      Comp_List   : constant List_Id    := New_List;
5330
      Equiv_Type  : Entity_Id;
5331
      Range_Type  : Entity_Id;
5332
      Str_Type    : Entity_Id;
5333
      Constr_Root : Entity_Id;
5334
      Sizexpr     : Node_Id;
5335
 
5336
   begin
5337
      --  If the root type is already constrained, there are no discriminants
5338
      --  in the expression.
5339
 
5340
      if not Has_Discriminants (Root_Typ)
5341
        or else Is_Constrained (Root_Typ)
5342
      then
5343
         Constr_Root := Root_Typ;
5344
      else
5345
         Constr_Root := Make_Temporary (Loc, 'R');
5346
 
5347
         --  subtype cstr__n is T (List of discr constraints taken from Exp)
5348
 
5349
         Append_To (List_Def,
5350
           Make_Subtype_Declaration (Loc,
5351
             Defining_Identifier => Constr_Root,
5352
             Subtype_Indication  => Make_Subtype_From_Expr (E, Root_Typ)));
5353
      end if;
5354
 
5355
      --  Generate the range subtype declaration
5356
 
5357
      Range_Type := Make_Temporary (Loc, 'G');
5358
 
5359
      if not Is_Interface (Root_Typ) then
5360
 
5361
         --  subtype rg__xx is
5362
         --    Storage_Offset range 1 .. (Expr'size - typ'size) / Storage_Unit
5363
 
5364
         Sizexpr :=
5365
           Make_Op_Subtract (Loc,
5366
             Left_Opnd =>
5367
               Make_Attribute_Reference (Loc,
5368
                 Prefix =>
5369
                   OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
5370
                 Attribute_Name => Name_Size),
5371
             Right_Opnd =>
5372
               Make_Attribute_Reference (Loc,
5373
                 Prefix => New_Reference_To (Constr_Root, Loc),
5374
                 Attribute_Name => Name_Object_Size));
5375
      else
5376
         --  subtype rg__xx is
5377
         --    Storage_Offset range 1 .. Expr'size / Storage_Unit
5378
 
5379
         Sizexpr :=
5380
           Make_Attribute_Reference (Loc,
5381
             Prefix =>
5382
               OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
5383
             Attribute_Name => Name_Size);
5384
      end if;
5385
 
5386
      Set_Paren_Count (Sizexpr, 1);
5387
 
5388
      Append_To (List_Def,
5389
        Make_Subtype_Declaration (Loc,
5390
          Defining_Identifier => Range_Type,
5391
          Subtype_Indication =>
5392
            Make_Subtype_Indication (Loc,
5393
              Subtype_Mark => New_Reference_To (RTE (RE_Storage_Offset), Loc),
5394
              Constraint => Make_Range_Constraint (Loc,
5395
                Range_Expression =>
5396
                  Make_Range (Loc,
5397
                    Low_Bound => Make_Integer_Literal (Loc, 1),
5398
                    High_Bound =>
5399
                      Make_Op_Divide (Loc,
5400
                        Left_Opnd => Sizexpr,
5401
                        Right_Opnd => Make_Integer_Literal (Loc,
5402
                            Intval => System_Storage_Unit)))))));
5403
 
5404
      --  subtype str__nn is Storage_Array (rg__x);
5405
 
5406
      Str_Type := Make_Temporary (Loc, 'S');
5407
      Append_To (List_Def,
5408
        Make_Subtype_Declaration (Loc,
5409
          Defining_Identifier => Str_Type,
5410
          Subtype_Indication =>
5411
            Make_Subtype_Indication (Loc,
5412
              Subtype_Mark => New_Reference_To (RTE (RE_Storage_Array), Loc),
5413
              Constraint =>
5414
                Make_Index_Or_Discriminant_Constraint (Loc,
5415
                  Constraints =>
5416
                    New_List (New_Reference_To (Range_Type, Loc))))));
5417
 
5418
      --  type Equiv_T is record
5419
      --    [ _parent : Tnn; ]
5420
      --    E : Str_Type;
5421
      --  end Equiv_T;
5422
 
5423
      Equiv_Type := Make_Temporary (Loc, 'T');
5424
      Set_Ekind (Equiv_Type, E_Record_Type);
5425
      Set_Parent_Subtype (Equiv_Type, Constr_Root);
5426
 
5427
      --  Set Is_Class_Wide_Equivalent_Type very early to trigger the special
5428
      --  treatment for this type. In particular, even though _parent's type
5429
      --  is a controlled type or contains controlled components, we do not
5430
      --  want to set Has_Controlled_Component on it to avoid making it gain
5431
      --  an unwanted _controller component.
5432
 
5433
      Set_Is_Class_Wide_Equivalent_Type (Equiv_Type);
5434
 
5435
      if not Is_Interface (Root_Typ) then
5436
         Append_To (Comp_List,
5437
           Make_Component_Declaration (Loc,
5438
             Defining_Identifier =>
5439
               Make_Defining_Identifier (Loc, Name_uParent),
5440
             Component_Definition =>
5441
               Make_Component_Definition (Loc,
5442
                 Aliased_Present    => False,
5443
                 Subtype_Indication => New_Reference_To (Constr_Root, Loc))));
5444
      end if;
5445
 
5446
      Append_To (Comp_List,
5447
        Make_Component_Declaration (Loc,
5448
          Defining_Identifier  => Make_Temporary (Loc, 'C'),
5449
          Component_Definition =>
5450
            Make_Component_Definition (Loc,
5451
              Aliased_Present    => False,
5452
              Subtype_Indication => New_Reference_To (Str_Type, Loc))));
5453
 
5454
      Append_To (List_Def,
5455
        Make_Full_Type_Declaration (Loc,
5456
          Defining_Identifier => Equiv_Type,
5457
          Type_Definition =>
5458
            Make_Record_Definition (Loc,
5459
              Component_List =>
5460
                Make_Component_List (Loc,
5461
                  Component_Items => Comp_List,
5462
                  Variant_Part    => Empty))));
5463
 
5464
      --  Suppress all checks during the analysis of the expanded code to avoid
5465
      --  the generation of spurious warnings under ZFP run-time.
5466
 
5467
      Insert_Actions (E, List_Def, Suppress => All_Checks);
5468
      return Equiv_Type;
5469
   end Make_CW_Equivalent_Type;
5470
 
5471
   -------------------------
5472
   -- Make_Invariant_Call --
5473
   -------------------------
5474
 
5475
   function Make_Invariant_Call (Expr : Node_Id) return Node_Id is
5476
      Loc : constant Source_Ptr := Sloc (Expr);
5477
      Typ : constant Entity_Id  := Etype (Expr);
5478
 
5479
   begin
5480
      pragma Assert
5481
        (Has_Invariants (Typ) and then Present (Invariant_Procedure (Typ)));
5482
 
5483
      if Check_Enabled (Name_Invariant)
5484
           or else
5485
         Check_Enabled (Name_Assertion)
5486
      then
5487
         return
5488
           Make_Procedure_Call_Statement (Loc,
5489
             Name                   =>
5490
               New_Occurrence_Of (Invariant_Procedure (Typ), Loc),
5491
             Parameter_Associations => New_List (Relocate_Node (Expr)));
5492
 
5493
      else
5494
         return
5495
           Make_Null_Statement (Loc);
5496
      end if;
5497
   end Make_Invariant_Call;
5498
 
5499
   ------------------------
5500
   -- Make_Literal_Range --
5501
   ------------------------
5502
 
5503
   function Make_Literal_Range
5504
     (Loc         : Source_Ptr;
5505
      Literal_Typ : Entity_Id) return Node_Id
5506
   is
5507
      Lo          : constant Node_Id :=
5508
                      New_Copy_Tree (String_Literal_Low_Bound (Literal_Typ));
5509
      Index       : constant Entity_Id := Etype (Lo);
5510
 
5511
      Hi          : Node_Id;
5512
      Length_Expr : constant Node_Id :=
5513
                      Make_Op_Subtract (Loc,
5514
                        Left_Opnd =>
5515
                          Make_Integer_Literal (Loc,
5516
                            Intval => String_Literal_Length (Literal_Typ)),
5517
                        Right_Opnd =>
5518
                          Make_Integer_Literal (Loc, 1));
5519
 
5520
   begin
5521
      Set_Analyzed (Lo, False);
5522
 
5523
         if Is_Integer_Type (Index) then
5524
            Hi :=
5525
              Make_Op_Add (Loc,
5526
                Left_Opnd  => New_Copy_Tree (Lo),
5527
                Right_Opnd => Length_Expr);
5528
         else
5529
            Hi :=
5530
              Make_Attribute_Reference (Loc,
5531
                Attribute_Name => Name_Val,
5532
                Prefix => New_Occurrence_Of (Index, Loc),
5533
                Expressions => New_List (
5534
                 Make_Op_Add (Loc,
5535
                   Left_Opnd =>
5536
                     Make_Attribute_Reference (Loc,
5537
                       Attribute_Name => Name_Pos,
5538
                       Prefix => New_Occurrence_Of (Index, Loc),
5539
                       Expressions => New_List (New_Copy_Tree (Lo))),
5540
                  Right_Opnd => Length_Expr)));
5541
         end if;
5542
 
5543
         return
5544
           Make_Range (Loc,
5545
             Low_Bound  => Lo,
5546
             High_Bound => Hi);
5547
   end Make_Literal_Range;
5548
 
5549
   --------------------------
5550
   -- Make_Non_Empty_Check --
5551
   --------------------------
5552
 
5553
   function Make_Non_Empty_Check
5554
     (Loc : Source_Ptr;
5555
      N   : Node_Id) return Node_Id
5556
   is
5557
   begin
5558
      return
5559
        Make_Op_Ne (Loc,
5560
          Left_Opnd =>
5561
            Make_Attribute_Reference (Loc,
5562
              Attribute_Name => Name_Length,
5563
              Prefix => Duplicate_Subexpr_No_Checks (N, Name_Req => True)),
5564
          Right_Opnd =>
5565
            Make_Integer_Literal (Loc, 0));
5566
   end Make_Non_Empty_Check;
5567
 
5568
   -------------------------
5569
   -- Make_Predicate_Call --
5570
   -------------------------
5571
 
5572
   function Make_Predicate_Call
5573
     (Typ  : Entity_Id;
5574
      Expr : Node_Id) return Node_Id
5575
   is
5576
      Loc : constant Source_Ptr := Sloc (Expr);
5577
 
5578
   begin
5579
      pragma Assert (Present (Predicate_Function (Typ)));
5580
 
5581
      return
5582
        Make_Function_Call (Loc,
5583
          Name                   =>
5584
            New_Occurrence_Of (Predicate_Function (Typ), Loc),
5585
          Parameter_Associations => New_List (Relocate_Node (Expr)));
5586
   end Make_Predicate_Call;
5587
 
5588
   --------------------------
5589
   -- Make_Predicate_Check --
5590
   --------------------------
5591
 
5592
   function Make_Predicate_Check
5593
     (Typ  : Entity_Id;
5594
      Expr : Node_Id) return Node_Id
5595
   is
5596
      Loc : constant Source_Ptr := Sloc (Expr);
5597
 
5598
   begin
5599
      return
5600
        Make_Pragma (Loc,
5601
          Pragma_Identifier            => Make_Identifier (Loc, Name_Check),
5602
          Pragma_Argument_Associations => New_List (
5603
            Make_Pragma_Argument_Association (Loc,
5604
              Expression => Make_Identifier (Loc, Name_Predicate)),
5605
            Make_Pragma_Argument_Association (Loc,
5606
              Expression => Make_Predicate_Call (Typ, Expr))));
5607
   end Make_Predicate_Check;
5608
 
5609
   ----------------------------
5610
   -- Make_Subtype_From_Expr --
5611
   ----------------------------
5612
 
5613
   --  1. If Expr is an unconstrained array expression, creates
5614
   --    Unc_Type(Expr'first(1)..Expr'last(1),..., Expr'first(n)..Expr'last(n))
5615
 
5616
   --  2. If Expr is a unconstrained discriminated type expression, creates
5617
   --    Unc_Type(Expr.Discr1, ... , Expr.Discr_n)
5618
 
5619
   --  3. If Expr is class-wide, creates an implicit class wide subtype
5620
 
5621
   function Make_Subtype_From_Expr
5622
     (E       : Node_Id;
5623
      Unc_Typ : Entity_Id) return Node_Id
5624
   is
5625
      Loc         : constant Source_Ptr := Sloc (E);
5626
      List_Constr : constant List_Id    := New_List;
5627
      D           : Entity_Id;
5628
 
5629
      Full_Subtyp  : Entity_Id;
5630
      Priv_Subtyp  : Entity_Id;
5631
      Utyp         : Entity_Id;
5632
      Full_Exp     : Node_Id;
5633
 
5634
   begin
5635
      if Is_Private_Type (Unc_Typ)
5636
        and then Has_Unknown_Discriminants (Unc_Typ)
5637
      then
5638
         --  Prepare the subtype completion, Go to base type to
5639
         --  find underlying type, because the type may be a generic
5640
         --  actual or an explicit subtype.
5641
 
5642
         Utyp        := Underlying_Type (Base_Type (Unc_Typ));
5643
         Full_Subtyp := Make_Temporary (Loc, 'C');
5644
         Full_Exp    :=
5645
           Unchecked_Convert_To (Utyp, Duplicate_Subexpr_No_Checks (E));
5646
         Set_Parent (Full_Exp, Parent (E));
5647
 
5648
         Priv_Subtyp := Make_Temporary (Loc, 'P');
5649
 
5650
         Insert_Action (E,
5651
           Make_Subtype_Declaration (Loc,
5652
             Defining_Identifier => Full_Subtyp,
5653
             Subtype_Indication  => Make_Subtype_From_Expr (Full_Exp, Utyp)));
5654
 
5655
         --  Define the dummy private subtype
5656
 
5657
         Set_Ekind          (Priv_Subtyp, Subtype_Kind (Ekind (Unc_Typ)));
5658
         Set_Etype          (Priv_Subtyp, Base_Type (Unc_Typ));
5659
         Set_Scope          (Priv_Subtyp, Full_Subtyp);
5660
         Set_Is_Constrained (Priv_Subtyp);
5661
         Set_Is_Tagged_Type (Priv_Subtyp, Is_Tagged_Type (Unc_Typ));
5662
         Set_Is_Itype       (Priv_Subtyp);
5663
         Set_Associated_Node_For_Itype (Priv_Subtyp, E);
5664
 
5665
         if Is_Tagged_Type  (Priv_Subtyp) then
5666
            Set_Class_Wide_Type
5667
              (Base_Type (Priv_Subtyp), Class_Wide_Type (Unc_Typ));
5668
            Set_Direct_Primitive_Operations (Priv_Subtyp,
5669
              Direct_Primitive_Operations (Unc_Typ));
5670
         end if;
5671
 
5672
         Set_Full_View (Priv_Subtyp, Full_Subtyp);
5673
 
5674
         return New_Reference_To (Priv_Subtyp, Loc);
5675
 
5676
      elsif Is_Array_Type (Unc_Typ) then
5677
         for J in 1 .. Number_Dimensions (Unc_Typ) loop
5678
            Append_To (List_Constr,
5679
              Make_Range (Loc,
5680
                Low_Bound =>
5681
                  Make_Attribute_Reference (Loc,
5682
                    Prefix => Duplicate_Subexpr_No_Checks (E),
5683
                    Attribute_Name => Name_First,
5684
                    Expressions => New_List (
5685
                      Make_Integer_Literal (Loc, J))),
5686
 
5687
                High_Bound =>
5688
                  Make_Attribute_Reference (Loc,
5689
                    Prefix         => Duplicate_Subexpr_No_Checks (E),
5690
                    Attribute_Name => Name_Last,
5691
                    Expressions    => New_List (
5692
                      Make_Integer_Literal (Loc, J)))));
5693
         end loop;
5694
 
5695
      elsif Is_Class_Wide_Type (Unc_Typ) then
5696
         declare
5697
            CW_Subtype : Entity_Id;
5698
            EQ_Typ     : Entity_Id := Empty;
5699
 
5700
         begin
5701
            --  A class-wide equivalent type is not needed when VM_Target
5702
            --  because the VM back-ends handle the class-wide object
5703
            --  initialization itself (and doesn't need or want the
5704
            --  additional intermediate type to handle the assignment).
5705
 
5706
            if Expander_Active and then Tagged_Type_Expansion then
5707
 
5708
               --  If this is the class_wide type of a completion that is a
5709
               --  record subtype, set the type of the class_wide type to be
5710
               --  the full base type, for use in the expanded code for the
5711
               --  equivalent type. Should this be done earlier when the
5712
               --  completion is analyzed ???
5713
 
5714
               if Is_Private_Type (Etype (Unc_Typ))
5715
                 and then
5716
                   Ekind (Full_View (Etype (Unc_Typ))) = E_Record_Subtype
5717
               then
5718
                  Set_Etype (Unc_Typ, Base_Type (Full_View (Etype (Unc_Typ))));
5719
               end if;
5720
 
5721
               EQ_Typ := Make_CW_Equivalent_Type (Unc_Typ, E);
5722
            end if;
5723
 
5724
            CW_Subtype := New_Class_Wide_Subtype (Unc_Typ, E);
5725
            Set_Equivalent_Type (CW_Subtype, EQ_Typ);
5726
            Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ));
5727
 
5728
            return New_Occurrence_Of (CW_Subtype, Loc);
5729
         end;
5730
 
5731
      --  Indefinite record type with discriminants
5732
 
5733
      else
5734
         D := First_Discriminant (Unc_Typ);
5735
         while Present (D) loop
5736
            Append_To (List_Constr,
5737
              Make_Selected_Component (Loc,
5738
                Prefix        => Duplicate_Subexpr_No_Checks (E),
5739
                Selector_Name => New_Reference_To (D, Loc)));
5740
 
5741
            Next_Discriminant (D);
5742
         end loop;
5743
      end if;
5744
 
5745
      return
5746
        Make_Subtype_Indication (Loc,
5747
          Subtype_Mark => New_Reference_To (Unc_Typ, Loc),
5748
          Constraint   =>
5749
            Make_Index_Or_Discriminant_Constraint (Loc,
5750
              Constraints => List_Constr));
5751
   end Make_Subtype_From_Expr;
5752
 
5753
   -----------------------------
5754
   -- May_Generate_Large_Temp --
5755
   -----------------------------
5756
 
5757
   --  At the current time, the only types that we return False for (i.e. where
5758
   --  we decide we know they cannot generate large temps) are ones where we
5759
   --  know the size is 256 bits or less at compile time, and we are still not
5760
   --  doing a thorough job on arrays and records ???
5761
 
5762
   function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is
5763
   begin
5764
      if not Size_Known_At_Compile_Time (Typ) then
5765
         return False;
5766
 
5767
      elsif Esize (Typ) /= 0 and then Esize (Typ) <= 256 then
5768
         return False;
5769
 
5770
      elsif Is_Array_Type (Typ)
5771
        and then Present (Packed_Array_Type (Typ))
5772
      then
5773
         return May_Generate_Large_Temp (Packed_Array_Type (Typ));
5774
 
5775
      --  We could do more here to find other small types ???
5776
 
5777
      else
5778
         return True;
5779
      end if;
5780
   end May_Generate_Large_Temp;
5781
 
5782
   ------------------------
5783
   -- Needs_Finalization --
5784
   ------------------------
5785
 
5786
   function Needs_Finalization (T : Entity_Id) return Boolean is
5787
      function Has_Some_Controlled_Component (Rec : Entity_Id) return Boolean;
5788
      --  If type is not frozen yet, check explicitly among its components,
5789
      --  because the Has_Controlled_Component flag is not necessarily set.
5790
 
5791
      -----------------------------------
5792
      -- Has_Some_Controlled_Component --
5793
      -----------------------------------
5794
 
5795
      function Has_Some_Controlled_Component
5796
        (Rec : Entity_Id) return Boolean
5797
      is
5798
         Comp : Entity_Id;
5799
 
5800
      begin
5801
         if Has_Controlled_Component (Rec) then
5802
            return True;
5803
 
5804
         elsif not Is_Frozen (Rec) then
5805
            if Is_Record_Type (Rec) then
5806
               Comp := First_Entity (Rec);
5807
 
5808
               while Present (Comp) loop
5809
                  if not Is_Type (Comp)
5810
                    and then Needs_Finalization (Etype (Comp))
5811
                  then
5812
                     return True;
5813
                  end if;
5814
 
5815
                  Next_Entity (Comp);
5816
               end loop;
5817
 
5818
               return False;
5819
 
5820
            elsif Is_Array_Type (Rec) then
5821
               return Needs_Finalization (Component_Type (Rec));
5822
 
5823
            else
5824
               return Has_Controlled_Component (Rec);
5825
            end if;
5826
         else
5827
            return False;
5828
         end if;
5829
      end Has_Some_Controlled_Component;
5830
 
5831
   --  Start of processing for Needs_Finalization
5832
 
5833
   begin
5834
      --  Certain run-time configurations and targets do not provide support
5835
      --  for controlled types.
5836
 
5837
      if Restriction_Active (No_Finalization) then
5838
         return False;
5839
 
5840
      --  C, C++, CIL and Java types are not considered controlled. It is
5841
      --  assumed that the non-Ada side will handle their clean up.
5842
 
5843
      elsif Convention (T) = Convention_C
5844
        or else Convention (T) = Convention_CIL
5845
        or else Convention (T) = Convention_CPP
5846
        or else Convention (T) = Convention_Java
5847
      then
5848
         return False;
5849
 
5850
      else
5851
         --  Class-wide types are treated as controlled because derivations
5852
         --  from the root type can introduce controlled components.
5853
 
5854
         return
5855
           Is_Class_Wide_Type (T)
5856
             or else Is_Controlled (T)
5857
             or else Has_Controlled_Component (T)
5858
             or else Has_Some_Controlled_Component (T)
5859
             or else
5860
               (Is_Concurrent_Type (T)
5861
                  and then Present (Corresponding_Record_Type (T))
5862
                  and then Needs_Finalization (Corresponding_Record_Type (T)));
5863
      end if;
5864
   end Needs_Finalization;
5865
 
5866
   ----------------------------
5867
   -- Needs_Constant_Address --
5868
   ----------------------------
5869
 
5870
   function Needs_Constant_Address
5871
     (Decl : Node_Id;
5872
      Typ  : Entity_Id) return Boolean
5873
   is
5874
   begin
5875
 
5876
      --  If we have no initialization of any kind, then we don't need to place
5877
      --  any restrictions on the address clause, because the object will be
5878
      --  elaborated after the address clause is evaluated. This happens if the
5879
      --  declaration has no initial expression, or the type has no implicit
5880
      --  initialization, or the object is imported.
5881
 
5882
      --  The same holds for all initialized scalar types and all access types.
5883
      --  Packed bit arrays of size up to 64 are represented using a modular
5884
      --  type with an initialization (to zero) and can be processed like other
5885
      --  initialized scalar types.
5886
 
5887
      --  If the type is controlled, code to attach the object to a
5888
      --  finalization chain is generated at the point of declaration, and
5889
      --  therefore the elaboration of the object cannot be delayed: the
5890
      --  address expression must be a constant.
5891
 
5892
      if No (Expression (Decl))
5893
        and then not Needs_Finalization (Typ)
5894
        and then
5895
          (not Has_Non_Null_Base_Init_Proc (Typ)
5896
            or else Is_Imported (Defining_Identifier (Decl)))
5897
      then
5898
         return False;
5899
 
5900
      elsif (Present (Expression (Decl)) and then Is_Scalar_Type (Typ))
5901
        or else Is_Access_Type (Typ)
5902
        or else
5903
          (Is_Bit_Packed_Array (Typ)
5904
             and then Is_Modular_Integer_Type (Packed_Array_Type (Typ)))
5905
      then
5906
         return False;
5907
 
5908
      else
5909
 
5910
         --  Otherwise, we require the address clause to be constant because
5911
         --  the call to the initialization procedure (or the attach code) has
5912
         --  to happen at the point of the declaration.
5913
 
5914
         --  Actually the IP call has been moved to the freeze actions anyway,
5915
         --  so maybe we can relax this restriction???
5916
 
5917
         return True;
5918
      end if;
5919
   end Needs_Constant_Address;
5920
 
5921
   ----------------------------
5922
   -- New_Class_Wide_Subtype --
5923
   ----------------------------
5924
 
5925
   function New_Class_Wide_Subtype
5926
     (CW_Typ : Entity_Id;
5927
      N      : Node_Id) return Entity_Id
5928
   is
5929
      Res       : constant Entity_Id := Create_Itype (E_Void, N);
5930
      Res_Name  : constant Name_Id   := Chars (Res);
5931
      Res_Scope : constant Entity_Id := Scope (Res);
5932
 
5933
   begin
5934
      Copy_Node (CW_Typ, Res);
5935
      Set_Comes_From_Source (Res, False);
5936
      Set_Sloc (Res, Sloc (N));
5937
      Set_Is_Itype (Res);
5938
      Set_Associated_Node_For_Itype (Res, N);
5939
      Set_Is_Public (Res, False);   --  By default, may be changed below.
5940
      Set_Public_Status (Res);
5941
      Set_Chars (Res, Res_Name);
5942
      Set_Scope (Res, Res_Scope);
5943
      Set_Ekind (Res, E_Class_Wide_Subtype);
5944
      Set_Next_Entity (Res, Empty);
5945
      Set_Etype (Res, Base_Type (CW_Typ));
5946
      Set_Is_Frozen (Res, False);
5947
      Set_Freeze_Node (Res, Empty);
5948
      return (Res);
5949
   end New_Class_Wide_Subtype;
5950
 
5951
   --------------------------------
5952
   -- Non_Limited_Designated_Type --
5953
   ---------------------------------
5954
 
5955
   function Non_Limited_Designated_Type (T : Entity_Id) return Entity_Id is
5956
      Desig : constant Entity_Id := Designated_Type (T);
5957
   begin
5958
      if Ekind (Desig) = E_Incomplete_Type
5959
        and then Present (Non_Limited_View (Desig))
5960
      then
5961
         return Non_Limited_View (Desig);
5962
      else
5963
         return Desig;
5964
      end if;
5965
   end Non_Limited_Designated_Type;
5966
 
5967
   -----------------------------------
5968
   -- OK_To_Do_Constant_Replacement --
5969
   -----------------------------------
5970
 
5971
   function OK_To_Do_Constant_Replacement (E : Entity_Id) return Boolean is
5972
      ES : constant Entity_Id := Scope (E);
5973
      CS : Entity_Id;
5974
 
5975
   begin
5976
      --  Do not replace statically allocated objects, because they may be
5977
      --  modified outside the current scope.
5978
 
5979
      if Is_Statically_Allocated (E) then
5980
         return False;
5981
 
5982
      --  Do not replace aliased or volatile objects, since we don't know what
5983
      --  else might change the value.
5984
 
5985
      elsif Is_Aliased (E) or else Treat_As_Volatile (E) then
5986
         return False;
5987
 
5988
      --  Debug flag -gnatdM disconnects this optimization
5989
 
5990
      elsif Debug_Flag_MM then
5991
         return False;
5992
 
5993
      --  Otherwise check scopes
5994
 
5995
      else
5996
         CS := Current_Scope;
5997
 
5998
         loop
5999
            --  If we are in right scope, replacement is safe
6000
 
6001
            if CS = ES then
6002
               return True;
6003
 
6004
            --  Packages do not affect the determination of safety
6005
 
6006
            elsif Ekind (CS) = E_Package then
6007
               exit when CS = Standard_Standard;
6008
               CS := Scope (CS);
6009
 
6010
            --  Blocks do not affect the determination of safety
6011
 
6012
            elsif Ekind (CS) = E_Block then
6013
               CS := Scope (CS);
6014
 
6015
            --  Loops do not affect the determination of safety. Note that we
6016
            --  kill all current values on entry to a loop, so we are just
6017
            --  talking about processing within a loop here.
6018
 
6019
            elsif Ekind (CS) = E_Loop then
6020
               CS := Scope (CS);
6021
 
6022
            --  Otherwise, the reference is dubious, and we cannot be sure that
6023
            --  it is safe to do the replacement.
6024
 
6025
            else
6026
               exit;
6027
            end if;
6028
         end loop;
6029
 
6030
         return False;
6031
      end if;
6032
   end OK_To_Do_Constant_Replacement;
6033
 
6034
   ------------------------------------
6035
   -- Possible_Bit_Aligned_Component --
6036
   ------------------------------------
6037
 
6038
   function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is
6039
   begin
6040
      case Nkind (N) is
6041
 
6042
         --  Case of indexed component
6043
 
6044
         when N_Indexed_Component =>
6045
            declare
6046
               P    : constant Node_Id   := Prefix (N);
6047
               Ptyp : constant Entity_Id := Etype (P);
6048
 
6049
            begin
6050
               --  If we know the component size and it is less than 64, then
6051
               --  we are definitely OK. The back end always does assignment of
6052
               --  misaligned small objects correctly.
6053
 
6054
               if Known_Static_Component_Size (Ptyp)
6055
                 and then Component_Size (Ptyp) <= 64
6056
               then
6057
                  return False;
6058
 
6059
               --  Otherwise, we need to test the prefix, to see if we are
6060
               --  indexing from a possibly unaligned component.
6061
 
6062
               else
6063
                  return Possible_Bit_Aligned_Component (P);
6064
               end if;
6065
            end;
6066
 
6067
         --  Case of selected component
6068
 
6069
         when N_Selected_Component =>
6070
            declare
6071
               P    : constant Node_Id   := Prefix (N);
6072
               Comp : constant Entity_Id := Entity (Selector_Name (N));
6073
 
6074
            begin
6075
               --  If there is no component clause, then we are in the clear
6076
               --  since the back end will never misalign a large component
6077
               --  unless it is forced to do so. In the clear means we need
6078
               --  only the recursive test on the prefix.
6079
 
6080
               if Component_May_Be_Bit_Aligned (Comp) then
6081
                  return True;
6082
               else
6083
                  return Possible_Bit_Aligned_Component (P);
6084
               end if;
6085
            end;
6086
 
6087
         --  For a slice, test the prefix, if that is possibly misaligned,
6088
         --  then for sure the slice is!
6089
 
6090
         when N_Slice =>
6091
            return Possible_Bit_Aligned_Component (Prefix (N));
6092
 
6093
         --  For an unchecked conversion, check whether the expression may
6094
         --  be bit-aligned.
6095
 
6096
         when N_Unchecked_Type_Conversion =>
6097
            return Possible_Bit_Aligned_Component (Expression (N));
6098
 
6099
         --  If we have none of the above, it means that we have fallen off the
6100
         --  top testing prefixes recursively, and we now have a stand alone
6101
         --  object, where we don't have a problem.
6102
 
6103
         when others =>
6104
            return False;
6105
 
6106
      end case;
6107
   end Possible_Bit_Aligned_Component;
6108
 
6109
   -----------------------------------------------
6110
   -- Process_Statements_For_Controlled_Objects --
6111
   -----------------------------------------------
6112
 
6113
   procedure Process_Statements_For_Controlled_Objects (N : Node_Id) is
6114
      Loc : constant Source_Ptr := Sloc (N);
6115
 
6116
      function Are_Wrapped (L : List_Id) return Boolean;
6117
      --  Determine whether list L contains only one statement which is a block
6118
 
6119
      function Wrap_Statements_In_Block (L : List_Id) return Node_Id;
6120
      --  Given a list of statements L, wrap it in a block statement and return
6121
      --  the generated node.
6122
 
6123
      -----------------
6124
      -- Are_Wrapped --
6125
      -----------------
6126
 
6127
      function Are_Wrapped (L : List_Id) return Boolean is
6128
         Stmt : constant Node_Id := First (L);
6129
      begin
6130
         return
6131
           Present (Stmt)
6132
             and then No (Next (Stmt))
6133
             and then Nkind (Stmt) = N_Block_Statement;
6134
      end Are_Wrapped;
6135
 
6136
      ------------------------------
6137
      -- Wrap_Statements_In_Block --
6138
      ------------------------------
6139
 
6140
      function Wrap_Statements_In_Block (L : List_Id) return Node_Id is
6141
      begin
6142
         return
6143
           Make_Block_Statement (Loc,
6144
             Declarations => No_List,
6145
             Handled_Statement_Sequence =>
6146
               Make_Handled_Sequence_Of_Statements (Loc,
6147
                 Statements => L));
6148
      end Wrap_Statements_In_Block;
6149
 
6150
      --  Local variables
6151
 
6152
      Block : Node_Id;
6153
 
6154
   --  Start of processing for Process_Statements_For_Controlled_Objects
6155
 
6156
   begin
6157
      --  Whenever a non-handled statement list is wrapped in a block, the
6158
      --  block must be explicitly analyzed to redecorate all entities in the
6159
      --  list and ensure that a finalizer is properly built.
6160
 
6161
      case Nkind (N) is
6162
         when N_Elsif_Part             |
6163
              N_If_Statement           |
6164
              N_Conditional_Entry_Call |
6165
              N_Selective_Accept       =>
6166
 
6167
            --  Check the "then statements" for elsif parts and if statements
6168
 
6169
            if Nkind_In (N, N_Elsif_Part, N_If_Statement)
6170
              and then not Is_Empty_List (Then_Statements (N))
6171
              and then not Are_Wrapped (Then_Statements (N))
6172
              and then Requires_Cleanup_Actions
6173
                         (Then_Statements (N), False, False)
6174
            then
6175
               Block := Wrap_Statements_In_Block (Then_Statements (N));
6176
               Set_Then_Statements (N, New_List (Block));
6177
 
6178
               Analyze (Block);
6179
            end if;
6180
 
6181
            --  Check the "else statements" for conditional entry calls, if
6182
            --  statements and selective accepts.
6183
 
6184
            if Nkind_In (N, N_Conditional_Entry_Call,
6185
                            N_If_Statement,
6186
                            N_Selective_Accept)
6187
              and then not Is_Empty_List (Else_Statements (N))
6188
              and then not Are_Wrapped (Else_Statements (N))
6189
              and then Requires_Cleanup_Actions
6190
                         (Else_Statements (N), False, False)
6191
            then
6192
               Block := Wrap_Statements_In_Block (Else_Statements (N));
6193
               Set_Else_Statements (N, New_List (Block));
6194
 
6195
               Analyze (Block);
6196
            end if;
6197
 
6198
         when N_Abortable_Part             |
6199
              N_Accept_Alternative         |
6200
              N_Case_Statement_Alternative |
6201
              N_Delay_Alternative          |
6202
              N_Entry_Call_Alternative     |
6203
              N_Exception_Handler          |
6204
              N_Loop_Statement             |
6205
              N_Triggering_Alternative     =>
6206
 
6207
            if not Is_Empty_List (Statements (N))
6208
              and then not Are_Wrapped (Statements (N))
6209
              and then Requires_Cleanup_Actions (Statements (N), False, False)
6210
            then
6211
               Block := Wrap_Statements_In_Block (Statements (N));
6212
               Set_Statements (N, New_List (Block));
6213
 
6214
               Analyze (Block);
6215
            end if;
6216
 
6217
         when others                       =>
6218
            null;
6219
      end case;
6220
   end Process_Statements_For_Controlled_Objects;
6221
 
6222
   -------------------------
6223
   -- Remove_Side_Effects --
6224
   -------------------------
6225
 
6226
   procedure Remove_Side_Effects
6227
     (Exp          : Node_Id;
6228
      Name_Req     : Boolean := False;
6229
      Variable_Ref : Boolean := False)
6230
   is
6231
      Loc          : constant Source_Ptr     := Sloc (Exp);
6232
      Exp_Type     : constant Entity_Id      := Etype (Exp);
6233
      Svg_Suppress : constant Suppress_Array := Scope_Suppress;
6234
      Def_Id       : Entity_Id;
6235
      E            : Node_Id;
6236
      New_Exp      : Node_Id;
6237
      Ptr_Typ_Decl : Node_Id;
6238
      Ref_Type     : Entity_Id;
6239
      Res          : Node_Id;
6240
 
6241
      function Side_Effect_Free (N : Node_Id) return Boolean;
6242
      --  Determines if the tree N represents an expression that is known not
6243
      --  to have side effects, and for which no processing is required.
6244
 
6245
      function Side_Effect_Free (L : List_Id) return Boolean;
6246
      --  Determines if all elements of the list L are side effect free
6247
 
6248
      function Safe_Prefixed_Reference (N : Node_Id) return Boolean;
6249
      --  The argument N is a construct where the Prefix is dereferenced if it
6250
      --  is an access type and the result is a variable. The call returns True
6251
      --  if the construct is side effect free (not considering side effects in
6252
      --  other than the prefix which are to be tested by the caller).
6253
 
6254
      function Within_In_Parameter (N : Node_Id) return Boolean;
6255
      --  Determines if N is a subcomponent of a composite in-parameter. If so,
6256
      --  N is not side-effect free when the actual is global and modifiable
6257
      --  indirectly from within a subprogram, because it may be passed by
6258
      --  reference. The front-end must be conservative here and assume that
6259
      --  this may happen with any array or record type. On the other hand, we
6260
      --  cannot create temporaries for all expressions for which this
6261
      --  condition is true, for various reasons that might require clearing up
6262
      --  ??? For example, discriminant references that appear out of place, or
6263
      --  spurious type errors with class-wide expressions. As a result, we
6264
      --  limit the transformation to loop bounds, which is so far the only
6265
      --  case that requires it.
6266
 
6267
      -----------------------------
6268
      -- Safe_Prefixed_Reference --
6269
      -----------------------------
6270
 
6271
      function Safe_Prefixed_Reference (N : Node_Id) return Boolean is
6272
      begin
6273
         --  If prefix is not side effect free, definitely not safe
6274
 
6275
         if not Side_Effect_Free (Prefix (N)) then
6276
            return False;
6277
 
6278
         --  If the prefix is of an access type that is not access-to-constant,
6279
         --  then this construct is a variable reference, which means it is to
6280
         --  be considered to have side effects if Variable_Ref is set True.
6281
 
6282
         elsif Is_Access_Type (Etype (Prefix (N)))
6283
           and then not Is_Access_Constant (Etype (Prefix (N)))
6284
           and then Variable_Ref
6285
         then
6286
            --  Exception is a prefix that is the result of a previous removal
6287
            --  of side-effects.
6288
 
6289
            return Is_Entity_Name (Prefix (N))
6290
              and then not Comes_From_Source (Prefix (N))
6291
              and then Ekind (Entity (Prefix (N))) = E_Constant
6292
              and then Is_Internal_Name (Chars (Entity (Prefix (N))));
6293
 
6294
         --  If the prefix is an explicit dereference then this construct is a
6295
         --  variable reference, which means it is to be considered to have
6296
         --  side effects if Variable_Ref is True.
6297
 
6298
         --  We do NOT exclude dereferences of access-to-constant types because
6299
         --  we handle them as constant view of variables.
6300
 
6301
         elsif Nkind (Prefix (N)) = N_Explicit_Dereference
6302
           and then Variable_Ref
6303
         then
6304
            return False;
6305
 
6306
         --  Note: The following test is the simplest way of solving a complex
6307
         --  problem uncovered by the following test (Side effect on loop bound
6308
         --  that is a subcomponent of a global variable:
6309
 
6310
         --    with Text_Io; use Text_Io;
6311
         --    procedure Tloop is
6312
         --      type X is
6313
         --        record
6314
         --          V : Natural := 4;
6315
         --          S : String (1..5) := (others => 'a');
6316
         --        end record;
6317
         --      X1 : X;
6318
 
6319
         --      procedure Modi;
6320
 
6321
         --      generic
6322
         --        with procedure Action;
6323
         --      procedure Loop_G (Arg : X; Msg : String)
6324
 
6325
         --      procedure Loop_G (Arg : X; Msg : String) is
6326
         --      begin
6327
         --        Put_Line ("begin loop_g " & Msg & " will loop till: "
6328
         --                  & Natural'Image (Arg.V));
6329
         --        for Index in 1 .. Arg.V loop
6330
         --          Text_Io.Put_Line
6331
         --            (Natural'Image (Index) & " " & Arg.S (Index));
6332
         --          if Index > 2 then
6333
         --            Modi;
6334
         --          end if;
6335
         --        end loop;
6336
         --        Put_Line ("end loop_g " & Msg);
6337
         --      end;
6338
 
6339
         --      procedure Loop1 is new Loop_G (Modi);
6340
         --      procedure Modi is
6341
         --      begin
6342
         --        X1.V := 1;
6343
         --        Loop1 (X1, "from modi");
6344
         --      end;
6345
         --
6346
         --    begin
6347
         --      Loop1 (X1, "initial");
6348
         --    end;
6349
 
6350
         --  The output of the above program should be:
6351
 
6352
         --    begin loop_g initial will loop till:  4
6353
         --     1 a
6354
         --     2 a
6355
         --     3 a
6356
         --    begin loop_g from modi will loop till:  1
6357
         --     1 a
6358
         --    end loop_g from modi
6359
         --     4 a
6360
         --    begin loop_g from modi will loop till:  1
6361
         --     1 a
6362
         --    end loop_g from modi
6363
         --    end loop_g initial
6364
 
6365
         --  If a loop bound is a subcomponent of a global variable, a
6366
         --  modification of that variable within the loop may incorrectly
6367
         --  affect the execution of the loop.
6368
 
6369
         elsif Nkind (Parent (Parent (N))) = N_Loop_Parameter_Specification
6370
           and then Within_In_Parameter (Prefix (N))
6371
           and then Variable_Ref
6372
         then
6373
            return False;
6374
 
6375
         --  All other cases are side effect free
6376
 
6377
         else
6378
            return True;
6379
         end if;
6380
      end Safe_Prefixed_Reference;
6381
 
6382
      ----------------------
6383
      -- Side_Effect_Free --
6384
      ----------------------
6385
 
6386
      function Side_Effect_Free (N : Node_Id) return Boolean is
6387
      begin
6388
         --  Note on checks that could raise Constraint_Error. Strictly, if we
6389
         --  take advantage of 11.6, these checks do not count as side effects.
6390
         --  However, we would prefer to consider that they are side effects,
6391
         --  since the backend CSE does not work very well on expressions which
6392
         --  can raise Constraint_Error. On the other hand if we don't consider
6393
         --  them to be side effect free, then we get some awkward expansions
6394
         --  in -gnato mode, resulting in code insertions at a point where we
6395
         --  do not have a clear model for performing the insertions.
6396
 
6397
         --  Special handling for entity names
6398
 
6399
         if Is_Entity_Name (N) then
6400
 
6401
            --  Variables are considered to be a side effect if Variable_Ref
6402
            --  is set or if we have a volatile reference and Name_Req is off.
6403
            --  If Name_Req is True then we can't help returning a name which
6404
            --  effectively allows multiple references in any case.
6405
 
6406
            if Is_Variable (N, Use_Original_Node => False) then
6407
               return not Variable_Ref
6408
                 and then (not Is_Volatile_Reference (N) or else Name_Req);
6409
 
6410
            --  Any other entity (e.g. a subtype name) is definitely side
6411
            --  effect free.
6412
 
6413
            else
6414
               return True;
6415
            end if;
6416
 
6417
         --  A value known at compile time is always side effect free
6418
 
6419
         elsif Compile_Time_Known_Value (N) then
6420
            return True;
6421
 
6422
         --  A variable renaming is not side-effect free, because the renaming
6423
         --  will function like a macro in the front-end in some cases, and an
6424
         --  assignment can modify the component designated by N, so we need to
6425
         --  create a temporary for it.
6426
 
6427
         --  The guard testing for Entity being present is needed at least in
6428
         --  the case of rewritten predicate expressions, and may well also be
6429
         --  appropriate elsewhere. Obviously we can't go testing the entity
6430
         --  field if it does not exist, so it's reasonable to say that this is
6431
         --  not the renaming case if it does not exist.
6432
 
6433
         elsif Is_Entity_Name (Original_Node (N))
6434
           and then Present (Entity (Original_Node (N)))
6435
           and then Is_Renaming_Of_Object (Entity (Original_Node (N)))
6436
           and then Ekind (Entity (Original_Node (N))) /= E_Constant
6437
         then
6438
            return False;
6439
 
6440
         --  Remove_Side_Effects generates an object renaming declaration to
6441
         --  capture the expression of a class-wide expression. In VM targets
6442
         --  the frontend performs no expansion for dispatching calls to
6443
         --  class- wide types since they are handled by the VM. Hence, we must
6444
         --  locate here if this node corresponds to a previous invocation of
6445
         --  Remove_Side_Effects to avoid a never ending loop in the frontend.
6446
 
6447
         elsif VM_Target /= No_VM
6448
            and then not Comes_From_Source (N)
6449
            and then Nkind (Parent (N)) = N_Object_Renaming_Declaration
6450
            and then Is_Class_Wide_Type (Etype (N))
6451
         then
6452
            return True;
6453
         end if;
6454
 
6455
         --  For other than entity names and compile time known values,
6456
         --  check the node kind for special processing.
6457
 
6458
         case Nkind (N) is
6459
 
6460
            --  An attribute reference is side effect free if its expressions
6461
            --  are side effect free and its prefix is side effect free or
6462
            --  is an entity reference.
6463
 
6464
            --  Is this right? what about x'first where x is a variable???
6465
 
6466
            when N_Attribute_Reference =>
6467
               return Side_Effect_Free (Expressions (N))
6468
                 and then Attribute_Name (N) /= Name_Input
6469
                 and then (Is_Entity_Name (Prefix (N))
6470
                            or else Side_Effect_Free (Prefix (N)));
6471
 
6472
            --  A binary operator is side effect free if and both operands are
6473
            --  side effect free. For this purpose binary operators include
6474
            --  membership tests and short circuit forms.
6475
 
6476
            when N_Binary_Op | N_Membership_Test | N_Short_Circuit =>
6477
               return Side_Effect_Free (Left_Opnd  (N))
6478
                        and then
6479
                      Side_Effect_Free (Right_Opnd (N));
6480
 
6481
            --  An explicit dereference is side effect free only if it is
6482
            --  a side effect free prefixed reference.
6483
 
6484
            when N_Explicit_Dereference =>
6485
               return Safe_Prefixed_Reference (N);
6486
 
6487
            --  A call to _rep_to_pos is side effect free, since we generate
6488
            --  this pure function call ourselves. Moreover it is critically
6489
            --  important to make this exception, since otherwise we can have
6490
            --  discriminants in array components which don't look side effect
6491
            --  free in the case of an array whose index type is an enumeration
6492
            --  type with an enumeration rep clause.
6493
 
6494
            --  All other function calls are not side effect free
6495
 
6496
            when N_Function_Call =>
6497
               return Nkind (Name (N)) = N_Identifier
6498
                 and then Is_TSS (Name (N), TSS_Rep_To_Pos)
6499
                 and then
6500
                   Side_Effect_Free (First (Parameter_Associations (N)));
6501
 
6502
            --  An indexed component is side effect free if it is a side
6503
            --  effect free prefixed reference and all the indexing
6504
            --  expressions are side effect free.
6505
 
6506
            when N_Indexed_Component =>
6507
               return Side_Effect_Free (Expressions (N))
6508
                 and then Safe_Prefixed_Reference (N);
6509
 
6510
            --  A type qualification is side effect free if the expression
6511
            --  is side effect free.
6512
 
6513
            when N_Qualified_Expression =>
6514
               return Side_Effect_Free (Expression (N));
6515
 
6516
            --  A selected component is side effect free only if it is a side
6517
            --  effect free prefixed reference. If it designates a component
6518
            --  with a rep. clause it must be treated has having a potential
6519
            --  side effect, because it may be modified through a renaming, and
6520
            --  a subsequent use of the renaming as a macro will yield the
6521
            --  wrong value. This complex interaction between renaming and
6522
            --  removing side effects is a reminder that the latter has become
6523
            --  a headache to maintain, and that it should be removed in favor
6524
            --  of the gcc mechanism to capture values ???
6525
 
6526
            when N_Selected_Component =>
6527
               if Nkind (Parent (N)) = N_Explicit_Dereference
6528
                 and then Has_Non_Standard_Rep (Designated_Type (Etype (N)))
6529
               then
6530
                  return False;
6531
               else
6532
                  return Safe_Prefixed_Reference (N);
6533
               end if;
6534
 
6535
            --  A range is side effect free if the bounds are side effect free
6536
 
6537
            when N_Range =>
6538
               return Side_Effect_Free (Low_Bound (N))
6539
                 and then Side_Effect_Free (High_Bound (N));
6540
 
6541
            --  A slice is side effect free if it is a side effect free
6542
            --  prefixed reference and the bounds are side effect free.
6543
 
6544
            when N_Slice =>
6545
               return Side_Effect_Free (Discrete_Range (N))
6546
                 and then Safe_Prefixed_Reference (N);
6547
 
6548
            --  A type conversion is side effect free if the expression to be
6549
            --  converted is side effect free.
6550
 
6551
            when N_Type_Conversion =>
6552
               return Side_Effect_Free (Expression (N));
6553
 
6554
            --  A unary operator is side effect free if the operand
6555
            --  is side effect free.
6556
 
6557
            when N_Unary_Op =>
6558
               return Side_Effect_Free (Right_Opnd (N));
6559
 
6560
            --  An unchecked type conversion is side effect free only if it
6561
            --  is safe and its argument is side effect free.
6562
 
6563
            when N_Unchecked_Type_Conversion =>
6564
               return Safe_Unchecked_Type_Conversion (N)
6565
                 and then Side_Effect_Free (Expression (N));
6566
 
6567
            --  An unchecked expression is side effect free if its expression
6568
            --  is side effect free.
6569
 
6570
            when N_Unchecked_Expression =>
6571
               return Side_Effect_Free (Expression (N));
6572
 
6573
            --  A literal is side effect free
6574
 
6575
            when N_Character_Literal    |
6576
                 N_Integer_Literal      |
6577
                 N_Real_Literal         |
6578
                 N_String_Literal       =>
6579
               return True;
6580
 
6581
            --  We consider that anything else has side effects. This is a bit
6582
            --  crude, but we are pretty close for most common cases, and we
6583
            --  are certainly correct (i.e. we never return True when the
6584
            --  answer should be False).
6585
 
6586
            when others =>
6587
               return False;
6588
         end case;
6589
      end Side_Effect_Free;
6590
 
6591
      --  A list is side effect free if all elements of the list are side
6592
      --  effect free.
6593
 
6594
      function Side_Effect_Free (L : List_Id) return Boolean is
6595
         N : Node_Id;
6596
 
6597
      begin
6598
         if L = No_List or else L = Error_List then
6599
            return True;
6600
 
6601
         else
6602
            N := First (L);
6603
            while Present (N) loop
6604
               if not Side_Effect_Free (N) then
6605
                  return False;
6606
               else
6607
                  Next (N);
6608
               end if;
6609
            end loop;
6610
 
6611
            return True;
6612
         end if;
6613
      end Side_Effect_Free;
6614
 
6615
      -------------------------
6616
      -- Within_In_Parameter --
6617
      -------------------------
6618
 
6619
      function Within_In_Parameter (N : Node_Id) return Boolean is
6620
      begin
6621
         if not Comes_From_Source (N) then
6622
            return False;
6623
 
6624
         elsif Is_Entity_Name (N) then
6625
            return Ekind (Entity (N)) = E_In_Parameter;
6626
 
6627
         elsif Nkind (N) = N_Indexed_Component
6628
           or else Nkind (N) = N_Selected_Component
6629
         then
6630
            return Within_In_Parameter (Prefix (N));
6631
         else
6632
 
6633
            return False;
6634
         end if;
6635
      end Within_In_Parameter;
6636
 
6637
   --  Start of processing for Remove_Side_Effects
6638
 
6639
   begin
6640
      --  Handle cases in which there is nothing to do
6641
 
6642
      if not Expander_Active then
6643
         return;
6644
      end if;
6645
 
6646
      --  Cannot generate temporaries if the invocation to remove side effects
6647
      --  was issued too early and the type of the expression is not resolved
6648
      --  (this happens because routines Duplicate_Subexpr_XX implicitly invoke
6649
      --  Remove_Side_Effects).
6650
 
6651
      if No (Exp_Type)
6652
        or else Ekind (Exp_Type) = E_Access_Attribute_Type
6653
      then
6654
         return;
6655
 
6656
      --  No action needed for side-effect free expressions
6657
 
6658
      elsif Side_Effect_Free (Exp) then
6659
         return;
6660
      end if;
6661
 
6662
      --  All this must not have any checks
6663
 
6664
      Scope_Suppress := (others => True);
6665
 
6666
      --  If it is a scalar type and we need to capture the value, just make
6667
      --  a copy. Likewise for a function call, an attribute reference, an
6668
      --  allocator, or an operator. And if we have a volatile reference and
6669
      --  Name_Req is not set (see comments above for Side_Effect_Free).
6670
 
6671
      if Is_Elementary_Type (Exp_Type)
6672
        and then (Variable_Ref
6673
                   or else Nkind (Exp) = N_Function_Call
6674
                   or else Nkind (Exp) = N_Attribute_Reference
6675
                   or else Nkind (Exp) = N_Allocator
6676
                   or else Nkind (Exp) in N_Op
6677
                   or else (not Name_Req and then Is_Volatile_Reference (Exp)))
6678
      then
6679
         Def_Id := Make_Temporary (Loc, 'R', Exp);
6680
         Set_Etype (Def_Id, Exp_Type);
6681
         Res := New_Reference_To (Def_Id, Loc);
6682
 
6683
         --  If the expression is a packed reference, it must be reanalyzed and
6684
         --  expanded, depending on context. This is the case for actuals where
6685
         --  a constraint check may capture the actual before expansion of the
6686
         --  call is complete.
6687
 
6688
         if Nkind (Exp) = N_Indexed_Component
6689
           and then Is_Packed (Etype (Prefix (Exp)))
6690
         then
6691
            Set_Analyzed (Exp, False);
6692
            Set_Analyzed (Prefix (Exp), False);
6693
         end if;
6694
 
6695
         E :=
6696
           Make_Object_Declaration (Loc,
6697
             Defining_Identifier => Def_Id,
6698
             Object_Definition   => New_Reference_To (Exp_Type, Loc),
6699
             Constant_Present    => True,
6700
             Expression          => Relocate_Node (Exp));
6701
 
6702
         Set_Assignment_OK (E);
6703
         Insert_Action (Exp, E);
6704
 
6705
      --  If the expression has the form v.all then we can just capture the
6706
      --  pointer, and then do an explicit dereference on the result.
6707
 
6708
      elsif Nkind (Exp) = N_Explicit_Dereference then
6709
         Def_Id := Make_Temporary (Loc, 'R', Exp);
6710
         Res :=
6711
           Make_Explicit_Dereference (Loc, New_Reference_To (Def_Id, Loc));
6712
 
6713
         Insert_Action (Exp,
6714
           Make_Object_Declaration (Loc,
6715
             Defining_Identifier => Def_Id,
6716
             Object_Definition   =>
6717
               New_Reference_To (Etype (Prefix (Exp)), Loc),
6718
             Constant_Present    => True,
6719
             Expression          => Relocate_Node (Prefix (Exp))));
6720
 
6721
      --  Similar processing for an unchecked conversion of an expression of
6722
      --  the form v.all, where we want the same kind of treatment.
6723
 
6724
      elsif Nkind (Exp) = N_Unchecked_Type_Conversion
6725
        and then Nkind (Expression (Exp)) = N_Explicit_Dereference
6726
      then
6727
         Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
6728
         Scope_Suppress := Svg_Suppress;
6729
         return;
6730
 
6731
      --  If this is a type conversion, leave the type conversion and remove
6732
      --  the side effects in the expression. This is important in several
6733
      --  circumstances: for change of representations, and also when this is a
6734
      --  view conversion to a smaller object, where gigi can end up creating
6735
      --  its own temporary of the wrong size.
6736
 
6737
      elsif Nkind (Exp) = N_Type_Conversion then
6738
         Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
6739
         Scope_Suppress := Svg_Suppress;
6740
         return;
6741
 
6742
      --  If this is an unchecked conversion that Gigi can't handle, make
6743
      --  a copy or a use a renaming to capture the value.
6744
 
6745
      elsif Nkind (Exp) = N_Unchecked_Type_Conversion
6746
        and then not Safe_Unchecked_Type_Conversion (Exp)
6747
      then
6748
         if CW_Or_Has_Controlled_Part (Exp_Type) then
6749
 
6750
            --  Use a renaming to capture the expression, rather than create
6751
            --  a controlled temporary.
6752
 
6753
            Def_Id := Make_Temporary (Loc, 'R', Exp);
6754
            Res := New_Reference_To (Def_Id, Loc);
6755
 
6756
            Insert_Action (Exp,
6757
              Make_Object_Renaming_Declaration (Loc,
6758
                Defining_Identifier => Def_Id,
6759
                Subtype_Mark        => New_Reference_To (Exp_Type, Loc),
6760
                Name                => Relocate_Node (Exp)));
6761
 
6762
         else
6763
            Def_Id := Make_Temporary (Loc, 'R', Exp);
6764
            Set_Etype (Def_Id, Exp_Type);
6765
            Res := New_Reference_To (Def_Id, Loc);
6766
 
6767
            E :=
6768
              Make_Object_Declaration (Loc,
6769
                Defining_Identifier => Def_Id,
6770
                Object_Definition   => New_Reference_To (Exp_Type, Loc),
6771
                Constant_Present    => not Is_Variable (Exp),
6772
                Expression          => Relocate_Node (Exp));
6773
 
6774
            Set_Assignment_OK (E);
6775
            Insert_Action (Exp, E);
6776
         end if;
6777
 
6778
      --  For expressions that denote objects, we can use a renaming scheme.
6779
      --  This is needed for correctness in the case of a volatile object of a
6780
      --  non-volatile type because the Make_Reference call of the "default"
6781
      --  approach would generate an illegal access value (an access value
6782
      --  cannot designate such an object - see Analyze_Reference). We skip
6783
      --  using this scheme if we have an object of a volatile type and we do
6784
      --  not have Name_Req set true (see comments above for Side_Effect_Free).
6785
 
6786
      elsif Is_Object_Reference (Exp)
6787
        and then Nkind (Exp) /= N_Function_Call
6788
        and then (Name_Req or else not Treat_As_Volatile (Exp_Type))
6789
      then
6790
         Def_Id := Make_Temporary (Loc, 'R', Exp);
6791
 
6792
         if Nkind (Exp) = N_Selected_Component
6793
           and then Nkind (Prefix (Exp)) = N_Function_Call
6794
           and then Is_Array_Type (Exp_Type)
6795
         then
6796
            --  Avoid generating a variable-sized temporary, by generating
6797
            --  the renaming declaration just for the function call. The
6798
            --  transformation could be refined to apply only when the array
6799
            --  component is constrained by a discriminant???
6800
 
6801
            Res :=
6802
              Make_Selected_Component (Loc,
6803
                Prefix => New_Occurrence_Of (Def_Id, Loc),
6804
                Selector_Name => Selector_Name (Exp));
6805
 
6806
            Insert_Action (Exp,
6807
              Make_Object_Renaming_Declaration (Loc,
6808
                Defining_Identifier => Def_Id,
6809
                Subtype_Mark        =>
6810
                  New_Reference_To (Base_Type (Etype (Prefix (Exp))), Loc),
6811
                Name                => Relocate_Node (Prefix (Exp))));
6812
 
6813
         else
6814
            Res := New_Reference_To (Def_Id, Loc);
6815
 
6816
            Insert_Action (Exp,
6817
              Make_Object_Renaming_Declaration (Loc,
6818
                Defining_Identifier => Def_Id,
6819
                Subtype_Mark        => New_Reference_To (Exp_Type, Loc),
6820
                Name                => Relocate_Node (Exp)));
6821
         end if;
6822
 
6823
         --  If this is a packed reference, or a selected component with
6824
         --  a non-standard representation, a reference to the temporary
6825
         --  will be replaced by a copy of the original expression (see
6826
         --  Exp_Ch2.Expand_Renaming). Otherwise the temporary must be
6827
         --  elaborated by gigi, and is of course not to be replaced in-line
6828
         --  by the expression it renames, which would defeat the purpose of
6829
         --  removing the side-effect.
6830
 
6831
         if (Nkind (Exp) = N_Selected_Component
6832
              or else Nkind (Exp) = N_Indexed_Component)
6833
           and then Has_Non_Standard_Rep (Etype (Prefix (Exp)))
6834
         then
6835
            null;
6836
         else
6837
            Set_Is_Renaming_Of_Object (Def_Id, False);
6838
         end if;
6839
 
6840
      --  Otherwise we generate a reference to the value
6841
 
6842
      else
6843
         --  An expression which is in Alfa mode is considered side effect free
6844
         --  if the resulting value is captured by a variable or a constant.
6845
 
6846
         if Alfa_Mode
6847
           and then Nkind (Parent (Exp)) = N_Object_Declaration
6848
         then
6849
            return;
6850
         end if;
6851
 
6852
         --  Special processing for function calls that return a limited type.
6853
         --  We need to build a declaration that will enable build-in-place
6854
         --  expansion of the call. This is not done if the context is already
6855
         --  an object declaration, to prevent infinite recursion.
6856
 
6857
         --  This is relevant only in Ada 2005 mode. In Ada 95 programs we have
6858
         --  to accommodate functions returning limited objects by reference.
6859
 
6860
         if Ada_Version >= Ada_2005
6861
           and then Nkind (Exp) = N_Function_Call
6862
           and then Is_Immutably_Limited_Type (Etype (Exp))
6863
           and then Nkind (Parent (Exp)) /= N_Object_Declaration
6864
         then
6865
            declare
6866
               Obj  : constant Entity_Id := Make_Temporary (Loc, 'F', Exp);
6867
               Decl : Node_Id;
6868
 
6869
            begin
6870
               Decl :=
6871
                 Make_Object_Declaration (Loc,
6872
                   Defining_Identifier => Obj,
6873
                   Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
6874
                   Expression          => Relocate_Node (Exp));
6875
 
6876
               Insert_Action (Exp, Decl);
6877
               Set_Etype (Obj, Exp_Type);
6878
               Rewrite (Exp, New_Occurrence_Of (Obj, Loc));
6879
               return;
6880
            end;
6881
         end if;
6882
 
6883
         Def_Id := Make_Temporary (Loc, 'R', Exp);
6884
         Set_Etype (Def_Id, Exp_Type);
6885
 
6886
         --  The regular expansion of functions with side effects involves the
6887
         --  generation of an access type to capture the return value found on
6888
         --  the secondary stack. Since Alfa (and why) cannot process access
6889
         --  types, use a different approach which ignores the secondary stack
6890
         --  and "copies" the returned object.
6891
 
6892
         if Alfa_Mode then
6893
            Res := New_Reference_To (Def_Id, Loc);
6894
            Ref_Type := Exp_Type;
6895
 
6896
         --  Regular expansion utilizing an access type and 'reference
6897
 
6898
         else
6899
            Res :=
6900
              Make_Explicit_Dereference (Loc,
6901
                Prefix => New_Reference_To (Def_Id, Loc));
6902
 
6903
            --  Generate:
6904
            --    type Ann is access all <Exp_Type>;
6905
 
6906
            Ref_Type := Make_Temporary (Loc, 'A');
6907
 
6908
            Ptr_Typ_Decl :=
6909
              Make_Full_Type_Declaration (Loc,
6910
                Defining_Identifier => Ref_Type,
6911
                Type_Definition     =>
6912
                  Make_Access_To_Object_Definition (Loc,
6913
                    All_Present        => True,
6914
                    Subtype_Indication =>
6915
                      New_Reference_To (Exp_Type, Loc)));
6916
 
6917
            Insert_Action (Exp, Ptr_Typ_Decl);
6918
         end if;
6919
 
6920
         E := Exp;
6921
         if Nkind (E) = N_Explicit_Dereference then
6922
            New_Exp := Relocate_Node (Prefix (E));
6923
         else
6924
            E := Relocate_Node (E);
6925
 
6926
            --  Do not generate a 'reference in Alfa mode since the access type
6927
            --  is not created in the first place.
6928
 
6929
            if Alfa_Mode then
6930
               New_Exp := E;
6931
 
6932
            --  Otherwise generate reference, marking the value as non-null
6933
            --  since we know it cannot be null and we don't want a check.
6934
 
6935
            else
6936
               New_Exp := Make_Reference (Loc, E);
6937
               Set_Is_Known_Non_Null (Def_Id);
6938
            end if;
6939
         end if;
6940
 
6941
         if Is_Delayed_Aggregate (E) then
6942
 
6943
            --  The expansion of nested aggregates is delayed until the
6944
            --  enclosing aggregate is expanded. As aggregates are often
6945
            --  qualified, the predicate applies to qualified expressions as
6946
            --  well, indicating that the enclosing aggregate has not been
6947
            --  expanded yet. At this point the aggregate is part of a
6948
            --  stand-alone declaration, and must be fully expanded.
6949
 
6950
            if Nkind (E) = N_Qualified_Expression then
6951
               Set_Expansion_Delayed (Expression (E), False);
6952
               Set_Analyzed (Expression (E), False);
6953
            else
6954
               Set_Expansion_Delayed (E, False);
6955
            end if;
6956
 
6957
            Set_Analyzed (E, False);
6958
         end if;
6959
 
6960
         Insert_Action (Exp,
6961
           Make_Object_Declaration (Loc,
6962
             Defining_Identifier => Def_Id,
6963
             Object_Definition   => New_Reference_To (Ref_Type, Loc),
6964
             Constant_Present    => True,
6965
             Expression          => New_Exp));
6966
      end if;
6967
 
6968
      --  Preserve the Assignment_OK flag in all copies, since at least one
6969
      --  copy may be used in a context where this flag must be set (otherwise
6970
      --  why would the flag be set in the first place).
6971
 
6972
      Set_Assignment_OK (Res, Assignment_OK (Exp));
6973
 
6974
      --  Finally rewrite the original expression and we are done
6975
 
6976
      Rewrite (Exp, Res);
6977
      Analyze_And_Resolve (Exp, Exp_Type);
6978
      Scope_Suppress := Svg_Suppress;
6979
   end Remove_Side_Effects;
6980
 
6981
   ---------------------------
6982
   -- Represented_As_Scalar --
6983
   ---------------------------
6984
 
6985
   function Represented_As_Scalar (T : Entity_Id) return Boolean is
6986
      UT : constant Entity_Id := Underlying_Type (T);
6987
   begin
6988
      return Is_Scalar_Type (UT)
6989
        or else (Is_Bit_Packed_Array (UT)
6990
                   and then Is_Scalar_Type (Packed_Array_Type (UT)));
6991
   end Represented_As_Scalar;
6992
 
6993
   ------------------------------
6994
   -- Requires_Cleanup_Actions --
6995
   ------------------------------
6996
 
6997
   function Requires_Cleanup_Actions (N : Node_Id) return Boolean is
6998
      For_Pkg : constant Boolean :=
6999
                  Nkind_In (N, N_Package_Body, N_Package_Specification);
7000
 
7001
   begin
7002
      case Nkind (N) is
7003
         when N_Accept_Statement      |
7004
              N_Block_Statement       |
7005
              N_Entry_Body            |
7006
              N_Package_Body          |
7007
              N_Protected_Body        |
7008
              N_Subprogram_Body       |
7009
              N_Task_Body             =>
7010
            return
7011
              Requires_Cleanup_Actions (Declarations (N), For_Pkg, True)
7012
                or else
7013
              (Present (Handled_Statement_Sequence (N))
7014
                and then
7015
              Requires_Cleanup_Actions (Statements
7016
                (Handled_Statement_Sequence (N)), For_Pkg, True));
7017
 
7018
         when N_Package_Specification =>
7019
            return
7020
              Requires_Cleanup_Actions
7021
                (Visible_Declarations (N), For_Pkg, True)
7022
                  or else
7023
              Requires_Cleanup_Actions
7024
                (Private_Declarations (N), For_Pkg, True);
7025
 
7026
         when others                  =>
7027
            return False;
7028
      end case;
7029
   end Requires_Cleanup_Actions;
7030
 
7031
   ------------------------------
7032
   -- Requires_Cleanup_Actions --
7033
   ------------------------------
7034
 
7035
   function Requires_Cleanup_Actions
7036
     (L                 : List_Id;
7037
      For_Package       : Boolean;
7038
      Nested_Constructs : Boolean) return Boolean
7039
   is
7040
      Decl    : Node_Id;
7041
      Expr    : Node_Id;
7042
      Obj_Id  : Entity_Id;
7043
      Obj_Typ : Entity_Id;
7044
      Pack_Id : Entity_Id;
7045
      Typ     : Entity_Id;
7046
 
7047
   begin
7048
      if No (L)
7049
        or else Is_Empty_List (L)
7050
      then
7051
         return False;
7052
      end if;
7053
 
7054
      Decl := First (L);
7055
      while Present (Decl) loop
7056
 
7057
         --  Library-level tagged types
7058
 
7059
         if Nkind (Decl) = N_Full_Type_Declaration then
7060
            Typ := Defining_Identifier (Decl);
7061
 
7062
            if Is_Tagged_Type (Typ)
7063
              and then Is_Library_Level_Entity (Typ)
7064
              and then Convention (Typ) = Convention_Ada
7065
              and then Present (Access_Disp_Table (Typ))
7066
              and then RTE_Available (RE_Unregister_Tag)
7067
              and then not No_Run_Time_Mode
7068
              and then not Is_Abstract_Type (Typ)
7069
            then
7070
               return True;
7071
            end if;
7072
 
7073
         --  Regular object declarations
7074
 
7075
         elsif Nkind (Decl) = N_Object_Declaration then
7076
            Obj_Id  := Defining_Identifier (Decl);
7077
            Obj_Typ := Base_Type (Etype (Obj_Id));
7078
            Expr    := Expression (Decl);
7079
 
7080
            --  Bypass any form of processing for objects which have their
7081
            --  finalization disabled. This applies only to objects at the
7082
            --  library level.
7083
 
7084
            if For_Package
7085
              and then Finalize_Storage_Only (Obj_Typ)
7086
            then
7087
               null;
7088
 
7089
            --  Transient variables are treated separately in order to minimize
7090
            --  the size of the generated code. See Exp_Ch7.Process_Transient_
7091
            --  Objects.
7092
 
7093
            elsif Is_Processed_Transient (Obj_Id) then
7094
               null;
7095
 
7096
            --  The object is of the form:
7097
            --    Obj : Typ [:= Expr];
7098
            --
7099
            --  Do not process the incomplete view of a deferred constant. Do
7100
            --  not consider tag-to-class-wide conversions.
7101
 
7102
            elsif not Is_Imported (Obj_Id)
7103
              and then Needs_Finalization (Obj_Typ)
7104
              and then not (Ekind (Obj_Id) = E_Constant
7105
                              and then not Has_Completion (Obj_Id))
7106
              and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id)
7107
            then
7108
               return True;
7109
 
7110
            --  The object is of the form:
7111
            --    Obj : Access_Typ := Non_BIP_Function_Call'reference;
7112
            --
7113
            --    Obj : Access_Typ :=
7114
            --            BIP_Function_Call
7115
            --              (..., BIPaccess => null, ...)'reference;
7116
 
7117
            elsif Is_Access_Type (Obj_Typ)
7118
              and then Needs_Finalization
7119
                         (Available_View (Designated_Type (Obj_Typ)))
7120
              and then Present (Expr)
7121
              and then
7122
                (Is_Null_Access_BIP_Func_Call (Expr)
7123
                   or else
7124
                (Is_Non_BIP_Func_Call (Expr)
7125
                   and then not Is_Related_To_Func_Return (Obj_Id)))
7126
            then
7127
               return True;
7128
 
7129
            --  Processing for "hook" objects generated for controlled
7130
            --  transients declared inside an Expression_With_Actions.
7131
 
7132
            elsif Is_Access_Type (Obj_Typ)
7133
              and then Present (Return_Flag_Or_Transient_Decl (Obj_Id))
7134
              and then Nkind (Return_Flag_Or_Transient_Decl (Obj_Id)) =
7135
                         N_Object_Declaration
7136
              and then Is_Finalizable_Transient
7137
                         (Return_Flag_Or_Transient_Decl (Obj_Id), Decl)
7138
            then
7139
               return True;
7140
 
7141
            --  Simple protected objects which use type System.Tasking.
7142
            --  Protected_Objects.Protection to manage their locks should be
7143
            --  treated as controlled since they require manual cleanup.
7144
 
7145
            elsif Ekind (Obj_Id) = E_Variable
7146
              and then
7147
                (Is_Simple_Protected_Type (Obj_Typ)
7148
                  or else Has_Simple_Protected_Object (Obj_Typ))
7149
            then
7150
               return True;
7151
            end if;
7152
 
7153
         --  Specific cases of object renamings
7154
 
7155
         elsif Nkind (Decl) = N_Object_Renaming_Declaration then
7156
            Obj_Id  := Defining_Identifier (Decl);
7157
            Obj_Typ := Base_Type (Etype (Obj_Id));
7158
 
7159
            --  Bypass any form of processing for objects which have their
7160
            --  finalization disabled. This applies only to objects at the
7161
            --  library level.
7162
 
7163
            if For_Package
7164
              and then Finalize_Storage_Only (Obj_Typ)
7165
            then
7166
               null;
7167
 
7168
            --  Return object of a build-in-place function. This case is
7169
            --  recognized and marked by the expansion of an extended return
7170
            --  statement (see Expand_N_Extended_Return_Statement).
7171
 
7172
            elsif Needs_Finalization (Obj_Typ)
7173
              and then Is_Return_Object (Obj_Id)
7174
              and then Present (Return_Flag_Or_Transient_Decl (Obj_Id))
7175
            then
7176
               return True;
7177
 
7178
            --  Detect a case where a source object has been initialized by a
7179
            --  controlled function call which was later rewritten as a class-
7180
            --  wide conversion of Ada.Tags.Displace.
7181
 
7182
            --     Obj : Class_Wide_Type := Function_Call (...);
7183
 
7184
            --     Temp : ... := Function_Call (...)'reference;
7185
            --     Obj  : Class_Wide_Type renames
7186
            --              (... Ada.Tags.Displace (Temp));
7187
 
7188
            elsif Is_Displacement_Of_Ctrl_Function_Result (Obj_Id) then
7189
               return True;
7190
            end if;
7191
 
7192
         --  Inspect the freeze node of an access-to-controlled type and look
7193
         --  for a delayed finalization master. This case arises when the
7194
         --  freeze actions are inserted at a later time than the expansion of
7195
         --  the context. Since Build_Finalizer is never called on a single
7196
         --  construct twice, the master will be ultimately left out and never
7197
         --  finalized. This is also needed for freeze actions of designated
7198
         --  types themselves, since in some cases the finalization master is
7199
         --  associated with a designated type's freeze node rather than that
7200
         --  of the access type (see handling for freeze actions in
7201
         --  Build_Finalization_Master).
7202
 
7203
         elsif Nkind (Decl) = N_Freeze_Entity
7204
           and then Present (Actions (Decl))
7205
         then
7206
            Typ := Entity (Decl);
7207
 
7208
            if ((Is_Access_Type (Typ)
7209
                  and then not Is_Access_Subprogram_Type (Typ)
7210
                  and then Needs_Finalization
7211
                             (Available_View (Designated_Type (Typ))))
7212
               or else
7213
                (Is_Type (Typ)
7214
                   and then Needs_Finalization (Typ)))
7215
              and then Requires_Cleanup_Actions
7216
                         (Actions (Decl), For_Package, Nested_Constructs)
7217
            then
7218
               return True;
7219
            end if;
7220
 
7221
         --  Nested package declarations
7222
 
7223
         elsif Nested_Constructs
7224
           and then Nkind (Decl) = N_Package_Declaration
7225
         then
7226
            Pack_Id := Defining_Unit_Name (Specification (Decl));
7227
 
7228
            if Nkind (Pack_Id) = N_Defining_Program_Unit_Name then
7229
               Pack_Id := Defining_Identifier (Pack_Id);
7230
            end if;
7231
 
7232
            if Ekind (Pack_Id) /= E_Generic_Package
7233
              and then Requires_Cleanup_Actions (Specification (Decl))
7234
            then
7235
               return True;
7236
            end if;
7237
 
7238
         --  Nested package bodies
7239
 
7240
         elsif Nested_Constructs
7241
           and then Nkind (Decl) = N_Package_Body
7242
         then
7243
            Pack_Id := Corresponding_Spec (Decl);
7244
 
7245
            if Ekind (Pack_Id) /= E_Generic_Package
7246
              and then Requires_Cleanup_Actions (Decl)
7247
            then
7248
               return True;
7249
            end if;
7250
         end if;
7251
 
7252
         Next (Decl);
7253
      end loop;
7254
 
7255
      return False;
7256
   end Requires_Cleanup_Actions;
7257
 
7258
   ------------------------------------
7259
   -- Safe_Unchecked_Type_Conversion --
7260
   ------------------------------------
7261
 
7262
   --  Note: this function knows quite a bit about the exact requirements of
7263
   --  Gigi with respect to unchecked type conversions, and its code must be
7264
   --  coordinated with any changes in Gigi in this area.
7265
 
7266
   --  The above requirements should be documented in Sinfo ???
7267
 
7268
   function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is
7269
      Otyp   : Entity_Id;
7270
      Ityp   : Entity_Id;
7271
      Oalign : Uint;
7272
      Ialign : Uint;
7273
      Pexp   : constant Node_Id := Parent (Exp);
7274
 
7275
   begin
7276
      --  If the expression is the RHS of an assignment or object declaration
7277
      --   we are always OK because there will always be a target.
7278
 
7279
      --  Object renaming declarations, (generated for view conversions of
7280
      --  actuals in inlined calls), like object declarations, provide an
7281
      --  explicit type, and are safe as well.
7282
 
7283
      if (Nkind (Pexp) = N_Assignment_Statement
7284
           and then Expression (Pexp) = Exp)
7285
        or else Nkind (Pexp) = N_Object_Declaration
7286
        or else Nkind (Pexp) = N_Object_Renaming_Declaration
7287
      then
7288
         return True;
7289
 
7290
      --  If the expression is the prefix of an N_Selected_Component we should
7291
      --  also be OK because GCC knows to look inside the conversion except if
7292
      --  the type is discriminated. We assume that we are OK anyway if the
7293
      --  type is not set yet or if it is controlled since we can't afford to
7294
      --  introduce a temporary in this case.
7295
 
7296
      elsif Nkind (Pexp) = N_Selected_Component
7297
         and then Prefix (Pexp) = Exp
7298
      then
7299
         if No (Etype (Pexp)) then
7300
            return True;
7301
         else
7302
            return
7303
              not Has_Discriminants (Etype (Pexp))
7304
                or else Is_Constrained (Etype (Pexp));
7305
         end if;
7306
      end if;
7307
 
7308
      --  Set the output type, this comes from Etype if it is set, otherwise we
7309
      --  take it from the subtype mark, which we assume was already fully
7310
      --  analyzed.
7311
 
7312
      if Present (Etype (Exp)) then
7313
         Otyp := Etype (Exp);
7314
      else
7315
         Otyp := Entity (Subtype_Mark (Exp));
7316
      end if;
7317
 
7318
      --  The input type always comes from the expression, and we assume
7319
      --  this is indeed always analyzed, so we can simply get the Etype.
7320
 
7321
      Ityp := Etype (Expression (Exp));
7322
 
7323
      --  Initialize alignments to unknown so far
7324
 
7325
      Oalign := No_Uint;
7326
      Ialign := No_Uint;
7327
 
7328
      --  Replace a concurrent type by its corresponding record type and each
7329
      --  type by its underlying type and do the tests on those. The original
7330
      --  type may be a private type whose completion is a concurrent type, so
7331
      --  find the underlying type first.
7332
 
7333
      if Present (Underlying_Type (Otyp)) then
7334
         Otyp := Underlying_Type (Otyp);
7335
      end if;
7336
 
7337
      if Present (Underlying_Type (Ityp)) then
7338
         Ityp := Underlying_Type (Ityp);
7339
      end if;
7340
 
7341
      if Is_Concurrent_Type (Otyp) then
7342
         Otyp := Corresponding_Record_Type (Otyp);
7343
      end if;
7344
 
7345
      if Is_Concurrent_Type (Ityp) then
7346
         Ityp := Corresponding_Record_Type (Ityp);
7347
      end if;
7348
 
7349
      --  If the base types are the same, we know there is no problem since
7350
      --  this conversion will be a noop.
7351
 
7352
      if Implementation_Base_Type (Otyp) = Implementation_Base_Type (Ityp) then
7353
         return True;
7354
 
7355
      --  Same if this is an upwards conversion of an untagged type, and there
7356
      --  are no constraints involved (could be more general???)
7357
 
7358
      elsif Etype (Ityp) = Otyp
7359
        and then not Is_Tagged_Type (Ityp)
7360
        and then not Has_Discriminants (Ityp)
7361
        and then No (First_Rep_Item (Base_Type (Ityp)))
7362
      then
7363
         return True;
7364
 
7365
      --  If the expression has an access type (object or subprogram) we assume
7366
      --  that the conversion is safe, because the size of the target is safe,
7367
      --  even if it is a record (which might be treated as having unknown size
7368
      --  at this point).
7369
 
7370
      elsif Is_Access_Type (Ityp) then
7371
         return True;
7372
 
7373
      --  If the size of output type is known at compile time, there is never
7374
      --  a problem. Note that unconstrained records are considered to be of
7375
      --  known size, but we can't consider them that way here, because we are
7376
      --  talking about the actual size of the object.
7377
 
7378
      --  We also make sure that in addition to the size being known, we do not
7379
      --  have a case which might generate an embarrassingly large temp in
7380
      --  stack checking mode.
7381
 
7382
      elsif Size_Known_At_Compile_Time (Otyp)
7383
        and then
7384
          (not Stack_Checking_Enabled
7385
             or else not May_Generate_Large_Temp (Otyp))
7386
        and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp))
7387
      then
7388
         return True;
7389
 
7390
      --  If either type is tagged, then we know the alignment is OK so
7391
      --  Gigi will be able to use pointer punning.
7392
 
7393
      elsif Is_Tagged_Type (Otyp) or else Is_Tagged_Type (Ityp) then
7394
         return True;
7395
 
7396
      --  If either type is a limited record type, we cannot do a copy, so say
7397
      --  safe since there's nothing else we can do.
7398
 
7399
      elsif Is_Limited_Record (Otyp) or else Is_Limited_Record (Ityp) then
7400
         return True;
7401
 
7402
      --  Conversions to and from packed array types are always ignored and
7403
      --  hence are safe.
7404
 
7405
      elsif Is_Packed_Array_Type (Otyp)
7406
        or else Is_Packed_Array_Type (Ityp)
7407
      then
7408
         return True;
7409
      end if;
7410
 
7411
      --  The only other cases known to be safe is if the input type's
7412
      --  alignment is known to be at least the maximum alignment for the
7413
      --  target or if both alignments are known and the output type's
7414
      --  alignment is no stricter than the input's. We can use the component
7415
      --  type alignement for an array if a type is an unpacked array type.
7416
 
7417
      if Present (Alignment_Clause (Otyp)) then
7418
         Oalign := Expr_Value (Expression (Alignment_Clause (Otyp)));
7419
 
7420
      elsif Is_Array_Type (Otyp)
7421
        and then Present (Alignment_Clause (Component_Type (Otyp)))
7422
      then
7423
         Oalign := Expr_Value (Expression (Alignment_Clause
7424
                                           (Component_Type (Otyp))));
7425
      end if;
7426
 
7427
      if Present (Alignment_Clause (Ityp)) then
7428
         Ialign := Expr_Value (Expression (Alignment_Clause (Ityp)));
7429
 
7430
      elsif Is_Array_Type (Ityp)
7431
        and then Present (Alignment_Clause (Component_Type (Ityp)))
7432
      then
7433
         Ialign := Expr_Value (Expression (Alignment_Clause
7434
                                           (Component_Type (Ityp))));
7435
      end if;
7436
 
7437
      if Ialign /= No_Uint and then Ialign > Maximum_Alignment then
7438
         return True;
7439
 
7440
      elsif Ialign /= No_Uint and then Oalign /= No_Uint
7441
        and then Ialign <= Oalign
7442
      then
7443
         return True;
7444
 
7445
      --   Otherwise, Gigi cannot handle this and we must make a temporary
7446
 
7447
      else
7448
         return False;
7449
      end if;
7450
   end Safe_Unchecked_Type_Conversion;
7451
 
7452
   ---------------------------------
7453
   -- Set_Current_Value_Condition --
7454
   ---------------------------------
7455
 
7456
   --  Note: the implementation of this procedure is very closely tied to the
7457
   --  implementation of Get_Current_Value_Condition. Here we set required
7458
   --  Current_Value fields, and in Get_Current_Value_Condition, we interpret
7459
   --  them, so they must have a consistent view.
7460
 
7461
   procedure Set_Current_Value_Condition (Cnode : Node_Id) is
7462
 
7463
      procedure Set_Entity_Current_Value (N : Node_Id);
7464
      --  If N is an entity reference, where the entity is of an appropriate
7465
      --  kind, then set the current value of this entity to Cnode, unless
7466
      --  there is already a definite value set there.
7467
 
7468
      procedure Set_Expression_Current_Value (N : Node_Id);
7469
      --  If N is of an appropriate form, sets an appropriate entry in current
7470
      --  value fields of relevant entities. Multiple entities can be affected
7471
      --  in the case of an AND or AND THEN.
7472
 
7473
      ------------------------------
7474
      -- Set_Entity_Current_Value --
7475
      ------------------------------
7476
 
7477
      procedure Set_Entity_Current_Value (N : Node_Id) is
7478
      begin
7479
         if Is_Entity_Name (N) then
7480
            declare
7481
               Ent : constant Entity_Id := Entity (N);
7482
 
7483
            begin
7484
               --  Don't capture if not safe to do so
7485
 
7486
               if not Safe_To_Capture_Value (N, Ent, Cond => True) then
7487
                  return;
7488
               end if;
7489
 
7490
               --  Here we have a case where the Current_Value field may need
7491
               --  to be set. We set it if it is not already set to a compile
7492
               --  time expression value.
7493
 
7494
               --  Note that this represents a decision that one condition
7495
               --  blots out another previous one. That's certainly right if
7496
               --  they occur at the same level. If the second one is nested,
7497
               --  then the decision is neither right nor wrong (it would be
7498
               --  equally OK to leave the outer one in place, or take the new
7499
               --  inner one. Really we should record both, but our data
7500
               --  structures are not that elaborate.
7501
 
7502
               if Nkind (Current_Value (Ent)) not in N_Subexpr then
7503
                  Set_Current_Value (Ent, Cnode);
7504
               end if;
7505
            end;
7506
         end if;
7507
      end Set_Entity_Current_Value;
7508
 
7509
      ----------------------------------
7510
      -- Set_Expression_Current_Value --
7511
      ----------------------------------
7512
 
7513
      procedure Set_Expression_Current_Value (N : Node_Id) is
7514
         Cond : Node_Id;
7515
 
7516
      begin
7517
         Cond := N;
7518
 
7519
         --  Loop to deal with (ignore for now) any NOT operators present. The
7520
         --  presence of NOT operators will be handled properly when we call
7521
         --  Get_Current_Value_Condition.
7522
 
7523
         while Nkind (Cond) = N_Op_Not loop
7524
            Cond := Right_Opnd (Cond);
7525
         end loop;
7526
 
7527
         --  For an AND or AND THEN, recursively process operands
7528
 
7529
         if Nkind (Cond) = N_Op_And or else Nkind (Cond) = N_And_Then then
7530
            Set_Expression_Current_Value (Left_Opnd (Cond));
7531
            Set_Expression_Current_Value (Right_Opnd (Cond));
7532
            return;
7533
         end if;
7534
 
7535
         --  Check possible relational operator
7536
 
7537
         if Nkind (Cond) in N_Op_Compare then
7538
            if Compile_Time_Known_Value (Right_Opnd (Cond)) then
7539
               Set_Entity_Current_Value (Left_Opnd (Cond));
7540
            elsif Compile_Time_Known_Value (Left_Opnd (Cond)) then
7541
               Set_Entity_Current_Value (Right_Opnd (Cond));
7542
            end if;
7543
 
7544
            --  Check possible boolean variable reference
7545
 
7546
         else
7547
            Set_Entity_Current_Value (Cond);
7548
         end if;
7549
      end Set_Expression_Current_Value;
7550
 
7551
   --  Start of processing for Set_Current_Value_Condition
7552
 
7553
   begin
7554
      Set_Expression_Current_Value (Condition (Cnode));
7555
   end Set_Current_Value_Condition;
7556
 
7557
   --------------------------
7558
   -- Set_Elaboration_Flag --
7559
   --------------------------
7560
 
7561
   procedure Set_Elaboration_Flag (N : Node_Id; Spec_Id : Entity_Id) is
7562
      Loc : constant Source_Ptr := Sloc (N);
7563
      Ent : constant Entity_Id  := Elaboration_Entity (Spec_Id);
7564
      Asn : Node_Id;
7565
 
7566
   begin
7567
      if Present (Ent) then
7568
 
7569
         --  Nothing to do if at the compilation unit level, because in this
7570
         --  case the flag is set by the binder generated elaboration routine.
7571
 
7572
         if Nkind (Parent (N)) = N_Compilation_Unit then
7573
            null;
7574
 
7575
         --  Here we do need to generate an assignment statement
7576
 
7577
         else
7578
            Check_Restriction (No_Elaboration_Code, N);
7579
            Asn :=
7580
              Make_Assignment_Statement (Loc,
7581
                Name       => New_Occurrence_Of (Ent, Loc),
7582
                Expression => Make_Integer_Literal (Loc, Uint_1));
7583
 
7584
            if Nkind (Parent (N)) = N_Subunit then
7585
               Insert_After (Corresponding_Stub (Parent (N)), Asn);
7586
            else
7587
               Insert_After (N, Asn);
7588
            end if;
7589
 
7590
            Analyze (Asn);
7591
 
7592
            --  Kill current value indication. This is necessary because the
7593
            --  tests of this flag are inserted out of sequence and must not
7594
            --  pick up bogus indications of the wrong constant value.
7595
 
7596
            Set_Current_Value (Ent, Empty);
7597
         end if;
7598
      end if;
7599
   end Set_Elaboration_Flag;
7600
 
7601
   ----------------------------
7602
   -- Set_Renamed_Subprogram --
7603
   ----------------------------
7604
 
7605
   procedure Set_Renamed_Subprogram (N : Node_Id; E : Entity_Id) is
7606
   begin
7607
      --  If input node is an identifier, we can just reset it
7608
 
7609
      if Nkind (N) = N_Identifier then
7610
         Set_Chars  (N, Chars (E));
7611
         Set_Entity (N, E);
7612
 
7613
         --  Otherwise we have to do a rewrite, preserving Comes_From_Source
7614
 
7615
      else
7616
         declare
7617
            CS : constant Boolean := Comes_From_Source (N);
7618
         begin
7619
            Rewrite (N, Make_Identifier (Sloc (N), Chars (E)));
7620
            Set_Entity (N, E);
7621
            Set_Comes_From_Source (N, CS);
7622
            Set_Analyzed (N, True);
7623
         end;
7624
      end if;
7625
   end Set_Renamed_Subprogram;
7626
 
7627
   ----------------------------------
7628
   -- Silly_Boolean_Array_Not_Test --
7629
   ----------------------------------
7630
 
7631
   --  This procedure implements an odd and silly test. We explicitly check
7632
   --  for the case where the 'First of the component type is equal to the
7633
   --  'Last of this component type, and if this is the case, we make sure
7634
   --  that constraint error is raised. The reason is that the NOT is bound
7635
   --  to cause CE in this case, and we will not otherwise catch it.
7636
 
7637
   --  No such check is required for AND and OR, since for both these cases
7638
   --  False op False = False, and True op True = True. For the XOR case,
7639
   --  see Silly_Boolean_Array_Xor_Test.
7640
 
7641
   --  Believe it or not, this was reported as a bug. Note that nearly always,
7642
   --  the test will evaluate statically to False, so the code will be
7643
   --  statically removed, and no extra overhead caused.
7644
 
7645
   procedure Silly_Boolean_Array_Not_Test (N : Node_Id; T : Entity_Id) is
7646
      Loc : constant Source_Ptr := Sloc (N);
7647
      CT  : constant Entity_Id  := Component_Type (T);
7648
 
7649
   begin
7650
      --  The check we install is
7651
 
7652
      --    constraint_error when
7653
      --      component_type'first = component_type'last
7654
      --        and then array_type'Length /= 0)
7655
 
7656
      --  We need the last guard because we don't want to raise CE for empty
7657
      --  arrays since no out of range values result. (Empty arrays with a
7658
      --  component type of True .. True -- very useful -- even the ACATS
7659
      --  does not test that marginal case!)
7660
 
7661
      Insert_Action (N,
7662
        Make_Raise_Constraint_Error (Loc,
7663
          Condition =>
7664
            Make_And_Then (Loc,
7665
              Left_Opnd =>
7666
                Make_Op_Eq (Loc,
7667
                  Left_Opnd =>
7668
                    Make_Attribute_Reference (Loc,
7669
                      Prefix         => New_Occurrence_Of (CT, Loc),
7670
                      Attribute_Name => Name_First),
7671
 
7672
                  Right_Opnd =>
7673
                    Make_Attribute_Reference (Loc,
7674
                      Prefix         => New_Occurrence_Of (CT, Loc),
7675
                      Attribute_Name => Name_Last)),
7676
 
7677
              Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
7678
          Reason => CE_Range_Check_Failed));
7679
   end Silly_Boolean_Array_Not_Test;
7680
 
7681
   ----------------------------------
7682
   -- Silly_Boolean_Array_Xor_Test --
7683
   ----------------------------------
7684
 
7685
   --  This procedure implements an odd and silly test. We explicitly check
7686
   --  for the XOR case where the component type is True .. True, since this
7687
   --  will raise constraint error. A special check is required since CE
7688
   --  will not be generated otherwise (cf Expand_Packed_Not).
7689
 
7690
   --  No such check is required for AND and OR, since for both these cases
7691
   --  False op False = False, and True op True = True, and no check is
7692
   --  required for the case of False .. False, since False xor False = False.
7693
   --  See also Silly_Boolean_Array_Not_Test
7694
 
7695
   procedure Silly_Boolean_Array_Xor_Test (N : Node_Id; T : Entity_Id) is
7696
      Loc : constant Source_Ptr := Sloc (N);
7697
      CT  : constant Entity_Id  := Component_Type (T);
7698
 
7699
   begin
7700
      --  The check we install is
7701
 
7702
      --    constraint_error when
7703
      --      Boolean (component_type'First)
7704
      --        and then Boolean (component_type'Last)
7705
      --        and then array_type'Length /= 0)
7706
 
7707
      --  We need the last guard because we don't want to raise CE for empty
7708
      --  arrays since no out of range values result (Empty arrays with a
7709
      --  component type of True .. True -- very useful -- even the ACATS
7710
      --  does not test that marginal case!).
7711
 
7712
      Insert_Action (N,
7713
        Make_Raise_Constraint_Error (Loc,
7714
          Condition =>
7715
            Make_And_Then (Loc,
7716
              Left_Opnd =>
7717
                Make_And_Then (Loc,
7718
                  Left_Opnd =>
7719
                    Convert_To (Standard_Boolean,
7720
                      Make_Attribute_Reference (Loc,
7721
                        Prefix         => New_Occurrence_Of (CT, Loc),
7722
                        Attribute_Name => Name_First)),
7723
 
7724
                  Right_Opnd =>
7725
                    Convert_To (Standard_Boolean,
7726
                      Make_Attribute_Reference (Loc,
7727
                        Prefix         => New_Occurrence_Of (CT, Loc),
7728
                        Attribute_Name => Name_Last))),
7729
 
7730
              Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
7731
          Reason => CE_Range_Check_Failed));
7732
   end Silly_Boolean_Array_Xor_Test;
7733
 
7734
   --------------------------
7735
   -- Target_Has_Fixed_Ops --
7736
   --------------------------
7737
 
7738
   Integer_Sized_Small : Ureal;
7739
   --  Set to 2.0 ** -(Integer'Size - 1) the first time that this function is
7740
   --  called (we don't want to compute it more than once!)
7741
 
7742
   Long_Integer_Sized_Small : Ureal;
7743
   --  Set to 2.0 ** -(Long_Integer'Size - 1) the first time that this function
7744
   --  is called (we don't want to compute it more than once)
7745
 
7746
   First_Time_For_THFO : Boolean := True;
7747
   --  Set to False after first call (if Fractional_Fixed_Ops_On_Target)
7748
 
7749
   function Target_Has_Fixed_Ops
7750
     (Left_Typ   : Entity_Id;
7751
      Right_Typ  : Entity_Id;
7752
      Result_Typ : Entity_Id) return Boolean
7753
   is
7754
      function Is_Fractional_Type (Typ : Entity_Id) return Boolean;
7755
      --  Return True if the given type is a fixed-point type with a small
7756
      --  value equal to 2 ** (-(T'Object_Size - 1)) and whose values have
7757
      --  an absolute value less than 1.0. This is currently limited to
7758
      --  fixed-point types that map to Integer or Long_Integer.
7759
 
7760
      ------------------------
7761
      -- Is_Fractional_Type --
7762
      ------------------------
7763
 
7764
      function Is_Fractional_Type (Typ : Entity_Id) return Boolean is
7765
      begin
7766
         if Esize (Typ) = Standard_Integer_Size then
7767
            return Small_Value (Typ) = Integer_Sized_Small;
7768
 
7769
         elsif Esize (Typ) = Standard_Long_Integer_Size then
7770
            return Small_Value (Typ) = Long_Integer_Sized_Small;
7771
 
7772
         else
7773
            return False;
7774
         end if;
7775
      end Is_Fractional_Type;
7776
 
7777
   --  Start of processing for Target_Has_Fixed_Ops
7778
 
7779
   begin
7780
      --  Return False if Fractional_Fixed_Ops_On_Target is false
7781
 
7782
      if not Fractional_Fixed_Ops_On_Target then
7783
         return False;
7784
      end if;
7785
 
7786
      --  Here the target has Fractional_Fixed_Ops, if first time, compute
7787
      --  standard constants used by Is_Fractional_Type.
7788
 
7789
      if First_Time_For_THFO then
7790
         First_Time_For_THFO := False;
7791
 
7792
         Integer_Sized_Small :=
7793
           UR_From_Components
7794
             (Num   => Uint_1,
7795
              Den   => UI_From_Int (Standard_Integer_Size - 1),
7796
              Rbase => 2);
7797
 
7798
         Long_Integer_Sized_Small :=
7799
           UR_From_Components
7800
             (Num   => Uint_1,
7801
              Den   => UI_From_Int (Standard_Long_Integer_Size - 1),
7802
              Rbase => 2);
7803
      end if;
7804
 
7805
      --  Return True if target supports fixed-by-fixed multiply/divide for
7806
      --  fractional fixed-point types (see Is_Fractional_Type) and the operand
7807
      --  and result types are equivalent fractional types.
7808
 
7809
      return Is_Fractional_Type (Base_Type (Left_Typ))
7810
        and then Is_Fractional_Type (Base_Type (Right_Typ))
7811
        and then Is_Fractional_Type (Base_Type (Result_Typ))
7812
        and then Esize (Left_Typ) = Esize (Right_Typ)
7813
        and then Esize (Left_Typ) = Esize (Result_Typ);
7814
   end Target_Has_Fixed_Ops;
7815
 
7816
   ------------------------------------------
7817
   -- Type_May_Have_Bit_Aligned_Components --
7818
   ------------------------------------------
7819
 
7820
   function Type_May_Have_Bit_Aligned_Components
7821
     (Typ : Entity_Id) return Boolean
7822
   is
7823
   begin
7824
      --  Array type, check component type
7825
 
7826
      if Is_Array_Type (Typ) then
7827
         return
7828
           Type_May_Have_Bit_Aligned_Components (Component_Type (Typ));
7829
 
7830
      --  Record type, check components
7831
 
7832
      elsif Is_Record_Type (Typ) then
7833
         declare
7834
            E : Entity_Id;
7835
 
7836
         begin
7837
            E := First_Component_Or_Discriminant (Typ);
7838
            while Present (E) loop
7839
               if Component_May_Be_Bit_Aligned (E)
7840
                 or else Type_May_Have_Bit_Aligned_Components (Etype (E))
7841
               then
7842
                  return True;
7843
               end if;
7844
 
7845
               Next_Component_Or_Discriminant (E);
7846
            end loop;
7847
 
7848
            return False;
7849
         end;
7850
 
7851
      --  Type other than array or record is always OK
7852
 
7853
      else
7854
         return False;
7855
      end if;
7856
   end Type_May_Have_Bit_Aligned_Components;
7857
 
7858
   ----------------------------
7859
   -- Wrap_Cleanup_Procedure --
7860
   ----------------------------
7861
 
7862
   procedure Wrap_Cleanup_Procedure (N : Node_Id) is
7863
      Loc   : constant Source_Ptr := Sloc (N);
7864
      Stseq : constant Node_Id    := Handled_Statement_Sequence (N);
7865
      Stmts : constant List_Id    := Statements (Stseq);
7866
 
7867
   begin
7868
      if Abort_Allowed then
7869
         Prepend_To (Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
7870
         Append_To  (Stmts, Build_Runtime_Call (Loc, RE_Abort_Undefer));
7871
      end if;
7872
   end Wrap_Cleanup_Procedure;
7873
 
7874
end Exp_Util;

powered by: WebSVN 2.1.0

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