OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

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

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

Line No. Rev Author Line
1 281 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT COMPILER COMPONENTS                         --
4
--                                                                          --
5
--                             E X P _ U T I L                              --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 1992-2009, Free Software Foundation, Inc.         --
10
--                                                                          --
11
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
12
-- terms of the  GNU General Public License as published  by the Free Soft- --
13
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17
-- for  more details.  You should have  received  a copy of the GNU General --
18
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19
-- http://www.gnu.org/licenses for a complete copy of the license.          --
20
--                                                                          --
21
-- GNAT was originally developed  by the GNAT team at  New York University. --
22
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
23
--                                                                          --
24
------------------------------------------------------------------------------
25
 
26
with Atree;    use Atree;
27
with Checks;   use Checks;
28
with Debug;    use Debug;
29
with Einfo;    use Einfo;
30
with Elists;   use Elists;
31
with Errout;   use Errout;
32
with Exp_Aggr; use Exp_Aggr;
33
with Exp_Ch6;  use Exp_Ch6;
34
with Exp_Ch7;  use Exp_Ch7;
35
with Inline;   use Inline;
36
with Itypes;   use Itypes;
37
with Lib;      use Lib;
38
with Nlists;   use Nlists;
39
with Nmake;    use Nmake;
40
with Opt;      use Opt;
41
with Restrict; use Restrict;
42
with Rident;   use Rident;
43
with Sem;      use Sem;
44
with Sem_Aux;  use Sem_Aux;
45
with Sem_Ch8;  use Sem_Ch8;
46
with Sem_SCIL; use Sem_SCIL;
47
with Sem_Eval; use Sem_Eval;
48
with Sem_Res;  use Sem_Res;
49
with Sem_Type; use Sem_Type;
50
with Sem_Util; use Sem_Util;
51
with Snames;   use Snames;
52
with Stand;    use Stand;
53
with Stringt;  use Stringt;
54
with Targparm; use Targparm;
55
with Tbuild;   use Tbuild;
56
with Ttypes;   use Ttypes;
57
with Uintp;    use Uintp;
58
with Urealp;   use Urealp;
59
with Validsw;  use Validsw;
60
 
61
package body Exp_Util is
62
 
63
   -----------------------
64
   -- Local Subprograms --
65
   -----------------------
66
 
67
   function Build_Task_Array_Image
68
     (Loc    : Source_Ptr;
69
      Id_Ref : Node_Id;
70
      A_Type : Entity_Id;
71
      Dyn    : Boolean := False) return Node_Id;
72
   --  Build function to generate the image string for a task that is an
73
   --  array component, concatenating the images of each index. To avoid
74
   --  storage leaks, the string is built with successive slice assignments.
75
   --  The flag Dyn indicates whether this is called for the initialization
76
   --  procedure of an array of tasks, or for the name of a dynamically
77
   --  created task that is assigned to an indexed component.
78
 
79
   function Build_Task_Image_Function
80
     (Loc   : Source_Ptr;
81
      Decls : List_Id;
82
      Stats : List_Id;
83
      Res   : Entity_Id) return Node_Id;
84
   --  Common processing for Task_Array_Image and Task_Record_Image.
85
   --  Build function body that computes image.
86
 
87
   procedure Build_Task_Image_Prefix
88
      (Loc    : Source_Ptr;
89
       Len    : out Entity_Id;
90
       Res    : out Entity_Id;
91
       Pos    : out Entity_Id;
92
       Prefix : Entity_Id;
93
       Sum    : Node_Id;
94
       Decls  : List_Id;
95
       Stats  : List_Id);
96
   --  Common processing for Task_Array_Image and Task_Record_Image.
97
   --  Create local variables and assign prefix of name to result string.
98
 
99
   function Build_Task_Record_Image
100
     (Loc    : Source_Ptr;
101
      Id_Ref : Node_Id;
102
      Dyn    : Boolean := False) return Node_Id;
103
   --  Build function to generate the image string for a task that is a
104
   --  record component. Concatenate name of variable with that of selector.
105
   --  The flag Dyn indicates whether this is called for the initialization
106
   --  procedure of record with task components, or for a dynamically
107
   --  created task that is assigned to a selected component.
108
 
109
   function Make_CW_Equivalent_Type
110
     (T : Entity_Id;
111
      E : Node_Id) return Entity_Id;
112
   --  T is a class-wide type entity, E is the initial expression node that
113
   --  constrains T in case such as: " X: T := E" or "new T'(E)"
114
   --  This function returns the entity of the Equivalent type and inserts
115
   --  on the fly the necessary declaration such as:
116
   --
117
   --    type anon is record
118
   --       _parent : Root_Type (T); constrained with E discriminants (if any)
119
   --       Extension : String (1 .. expr to match size of E);
120
   --    end record;
121
   --
122
   --  This record is compatible with any object of the class of T thanks
123
   --  to the first field and has the same size as E thanks to the second.
124
 
125
   function Make_Literal_Range
126
     (Loc         : Source_Ptr;
127
      Literal_Typ : Entity_Id) return Node_Id;
128
   --  Produce a Range node whose bounds are:
129
   --    Low_Bound (Literal_Type) ..
130
   --        Low_Bound (Literal_Type) + (Length (Literal_Typ) - 1)
131
   --  this is used for expanding declarations like X : String := "sdfgdfg";
132
   --
133
   --  If the index type of the target array is not integer, we generate:
134
   --     Low_Bound (Literal_Type) ..
135
   --        Literal_Type'Val
136
   --          (Literal_Type'Pos (Low_Bound (Literal_Type))
137
   --             + (Length (Literal_Typ) -1))
138
 
139
   function Make_Non_Empty_Check
140
     (Loc : Source_Ptr;
141
      N   : Node_Id) return Node_Id;
142
   --  Produce a boolean expression checking that the unidimensional array
143
   --  node N is not empty.
144
 
145
   function New_Class_Wide_Subtype
146
     (CW_Typ : Entity_Id;
147
      N      : Node_Id) return Entity_Id;
148
   --  Create an implicit subtype of CW_Typ attached to node N
149
 
150
   ----------------------
151
   -- Adjust_Condition --
152
   ----------------------
153
 
154
   procedure Adjust_Condition (N : Node_Id) is
155
   begin
156
      if No (N) then
157
         return;
158
      end if;
159
 
160
      declare
161
         Loc : constant Source_Ptr := Sloc (N);
162
         T   : constant Entity_Id  := Etype (N);
163
         Ti  : Entity_Id;
164
 
165
      begin
166
         --  For now, we simply ignore a call where the argument has no
167
         --  type (probably case of unanalyzed condition), or has a type
168
         --  that is not Boolean. This is because this is a pretty marginal
169
         --  piece of functionality, and violations of these rules are
170
         --  likely to be truly marginal (how much code uses Fortran Logical
171
         --  as the barrier to a protected entry?) and we do not want to
172
         --  blow up existing programs. We can change this to an assertion
173
         --  after 3.12a is released ???
174
 
175
         if No (T) or else not Is_Boolean_Type (T) then
176
            return;
177
         end if;
178
 
179
         --  Apply validity checking if needed
180
 
181
         if Validity_Checks_On and Validity_Check_Tests then
182
            Ensure_Valid (N);
183
         end if;
184
 
185
         --  Immediate return if standard boolean, the most common case,
186
         --  where nothing needs to be done.
187
 
188
         if Base_Type (T) = Standard_Boolean then
189
            return;
190
         end if;
191
 
192
         --  Case of zero/non-zero semantics or non-standard enumeration
193
         --  representation. In each case, we rewrite the node as:
194
 
195
         --      ityp!(N) /= False'Enum_Rep
196
 
197
         --  where ityp is an integer type with large enough size to hold
198
         --  any value of type T.
199
 
200
         if Nonzero_Is_True (T) or else Has_Non_Standard_Rep (T) then
201
            if Esize (T) <= Esize (Standard_Integer) then
202
               Ti := Standard_Integer;
203
            else
204
               Ti := Standard_Long_Long_Integer;
205
            end if;
206
 
207
            Rewrite (N,
208
              Make_Op_Ne (Loc,
209
                Left_Opnd  => Unchecked_Convert_To (Ti, N),
210
                Right_Opnd =>
211
                  Make_Attribute_Reference (Loc,
212
                    Attribute_Name => Name_Enum_Rep,
213
                    Prefix         =>
214
                      New_Occurrence_Of (First_Literal (T), Loc))));
215
            Analyze_And_Resolve (N, Standard_Boolean);
216
 
217
         else
218
            Rewrite (N, Convert_To (Standard_Boolean, N));
219
            Analyze_And_Resolve (N, Standard_Boolean);
220
         end if;
221
      end;
222
   end Adjust_Condition;
223
 
224
   ------------------------
225
   -- Adjust_Result_Type --
226
   ------------------------
227
 
228
   procedure Adjust_Result_Type (N : Node_Id; T : Entity_Id) is
229
   begin
230
      --  Ignore call if current type is not Standard.Boolean
231
 
232
      if Etype (N) /= Standard_Boolean then
233
         return;
234
      end if;
235
 
236
      --  If result is already of correct type, nothing to do. Note that
237
      --  this will get the most common case where everything has a type
238
      --  of Standard.Boolean.
239
 
240
      if Base_Type (T) = Standard_Boolean then
241
         return;
242
 
243
      else
244
         declare
245
            KP : constant Node_Kind := Nkind (Parent (N));
246
 
247
         begin
248
            --  If result is to be used as a Condition in the syntax, no need
249
            --  to convert it back, since if it was changed to Standard.Boolean
250
            --  using Adjust_Condition, that is just fine for this usage.
251
 
252
            if KP in N_Raise_xxx_Error or else KP in N_Has_Condition then
253
               return;
254
 
255
            --  If result is an operand of another logical operation, no need
256
            --  to reset its type, since Standard.Boolean is just fine, and
257
            --  such operations always do Adjust_Condition on their operands.
258
 
259
            elsif     KP in N_Op_Boolean
260
              or else KP in N_Short_Circuit
261
              or else KP = N_Op_Not
262
            then
263
               return;
264
 
265
            --  Otherwise we perform a conversion from the current type,
266
            --  which must be Standard.Boolean, to the desired type.
267
 
268
            else
269
               Set_Analyzed (N);
270
               Rewrite (N, Convert_To (T, N));
271
               Analyze_And_Resolve (N, T);
272
            end if;
273
         end;
274
      end if;
275
   end Adjust_Result_Type;
276
 
277
   --------------------------
278
   -- Append_Freeze_Action --
279
   --------------------------
280
 
281
   procedure Append_Freeze_Action (T : Entity_Id; N : Node_Id) is
282
      Fnode : Node_Id;
283
 
284
   begin
285
      Ensure_Freeze_Node (T);
286
      Fnode := Freeze_Node (T);
287
 
288
      if No (Actions (Fnode)) then
289
         Set_Actions (Fnode, New_List);
290
      end if;
291
 
292
      Append (N, Actions (Fnode));
293
   end Append_Freeze_Action;
294
 
295
   ---------------------------
296
   -- Append_Freeze_Actions --
297
   ---------------------------
298
 
299
   procedure Append_Freeze_Actions (T : Entity_Id; L : List_Id) is
300
      Fnode : constant Node_Id := Freeze_Node (T);
301
 
302
   begin
303
      if No (L) then
304
         return;
305
 
306
      else
307
         if No (Actions (Fnode)) then
308
            Set_Actions (Fnode, L);
309
 
310
         else
311
            Append_List (L, Actions (Fnode));
312
         end if;
313
 
314
      end if;
315
   end Append_Freeze_Actions;
316
 
317
   ------------------------
318
   -- Build_Runtime_Call --
319
   ------------------------
320
 
321
   function Build_Runtime_Call (Loc : Source_Ptr; RE : RE_Id) return Node_Id is
322
   begin
323
      --  If entity is not available, we can skip making the call (this avoids
324
      --  junk duplicated error messages in a number of cases).
325
 
326
      if not RTE_Available (RE) then
327
         return Make_Null_Statement (Loc);
328
      else
329
         return
330
           Make_Procedure_Call_Statement (Loc,
331
             Name => New_Reference_To (RTE (RE), Loc));
332
      end if;
333
   end Build_Runtime_Call;
334
 
335
   ----------------------------
336
   -- Build_Task_Array_Image --
337
   ----------------------------
338
 
339
   --  This function generates the body for a function that constructs the
340
   --  image string for a task that is an array component. The function is
341
   --  local to the init proc for the array type, and is called for each one
342
   --  of the components. The constructed image has the form of an indexed
343
   --  component, whose prefix is the outer variable of the array type.
344
   --  The n-dimensional array type has known indices Index, Index2...
345
   --  Id_Ref is an indexed component form created by the enclosing init proc.
346
   --  Its successive indices are Val1, Val2, ... which are the loop variables
347
   --  in the loops that call the individual task init proc on each component.
348
 
349
   --  The generated function has the following structure:
350
 
351
   --  function F return String is
352
   --     Pref : string renames Task_Name;
353
   --     T1   : String := Index1'Image (Val1);
354
   --     ...
355
   --     Tn   : String := indexn'image (Valn);
356
   --     Len  : Integer := T1'Length + ... + Tn'Length + n + 1;
357
   --     --  Len includes commas and the end parentheses.
358
   --     Res  : String (1..Len);
359
   --     Pos  : Integer := Pref'Length;
360
   --
361
   --  begin
362
   --     Res (1 .. Pos) := Pref;
363
   --     Pos := Pos + 1;
364
   --     Res (Pos)    := '(';
365
   --     Pos := Pos + 1;
366
   --     Res (Pos .. Pos + T1'Length - 1) := T1;
367
   --     Pos := Pos + T1'Length;
368
   --     Res (Pos) := '.';
369
   --     Pos := Pos + 1;
370
   --     ...
371
   --     Res (Pos .. Pos + Tn'Length - 1) := Tn;
372
   --     Res (Len) := ')';
373
   --
374
   --     return Res;
375
   --  end F;
376
   --
377
   --  Needless to say, multidimensional arrays of tasks are rare enough
378
   --  that the bulkiness of this code is not really a concern.
379
 
380
   function Build_Task_Array_Image
381
     (Loc    : Source_Ptr;
382
      Id_Ref : Node_Id;
383
      A_Type : Entity_Id;
384
      Dyn    : Boolean := False) return Node_Id
385
   is
386
      Dims : constant Nat := Number_Dimensions (A_Type);
387
      --  Number of dimensions for array of tasks
388
 
389
      Temps : array (1 .. Dims) of Entity_Id;
390
      --  Array of temporaries to hold string for each index
391
 
392
      Indx : Node_Id;
393
      --  Index expression
394
 
395
      Len : Entity_Id;
396
      --  Total length of generated name
397
 
398
      Pos : Entity_Id;
399
      --  Running index for substring assignments
400
 
401
      Pref : Entity_Id;
402
      --  Name of enclosing variable, prefix of resulting name
403
 
404
      Res : Entity_Id;
405
      --  String to hold result
406
 
407
      Val : Node_Id;
408
      --  Value of successive indices
409
 
410
      Sum : Node_Id;
411
      --  Expression to compute total size of string
412
 
413
      T : Entity_Id;
414
      --  Entity for name at one index position
415
 
416
      Decls : constant List_Id := New_List;
417
      Stats : constant List_Id := New_List;
418
 
419
   begin
420
      Pref := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
421
 
422
      --  For a dynamic task, the name comes from the target variable.
423
      --  For a static one it is a formal of the enclosing init proc.
424
 
425
      if Dyn then
426
         Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
427
         Append_To (Decls,
428
           Make_Object_Declaration (Loc,
429
             Defining_Identifier => Pref,
430
             Object_Definition => New_Occurrence_Of (Standard_String, Loc),
431
             Expression =>
432
               Make_String_Literal (Loc,
433
                 Strval => String_From_Name_Buffer)));
434
 
435
      else
436
         Append_To (Decls,
437
           Make_Object_Renaming_Declaration (Loc,
438
             Defining_Identifier => Pref,
439
             Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
440
             Name                => Make_Identifier (Loc, Name_uTask_Name)));
441
      end if;
442
 
443
      Indx := First_Index (A_Type);
444
      Val  := First (Expressions (Id_Ref));
445
 
446
      for J in 1 .. Dims loop
447
         T := Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
448
         Temps (J) := T;
449
 
450
         Append_To (Decls,
451
            Make_Object_Declaration (Loc,
452
               Defining_Identifier => T,
453
               Object_Definition => New_Occurrence_Of (Standard_String, Loc),
454
               Expression =>
455
                 Make_Attribute_Reference (Loc,
456
                   Attribute_Name => Name_Image,
457
                   Prefix =>
458
                     New_Occurrence_Of (Etype (Indx), Loc),
459
                   Expressions => New_List (
460
                     New_Copy_Tree (Val)))));
461
 
462
         Next_Index (Indx);
463
         Next (Val);
464
      end loop;
465
 
466
      Sum := Make_Integer_Literal (Loc, Dims + 1);
467
 
468
      Sum :=
469
        Make_Op_Add (Loc,
470
          Left_Opnd => Sum,
471
          Right_Opnd =>
472
           Make_Attribute_Reference (Loc,
473
             Attribute_Name => Name_Length,
474
             Prefix =>
475
               New_Occurrence_Of (Pref, Loc),
476
             Expressions => New_List (Make_Integer_Literal (Loc, 1))));
477
 
478
      for J in 1 .. Dims loop
479
         Sum :=
480
            Make_Op_Add (Loc,
481
             Left_Opnd => Sum,
482
             Right_Opnd =>
483
              Make_Attribute_Reference (Loc,
484
                Attribute_Name => Name_Length,
485
                Prefix =>
486
                  New_Occurrence_Of (Temps (J), Loc),
487
                Expressions => New_List (Make_Integer_Literal (Loc, 1))));
488
      end loop;
489
 
490
      Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
491
 
492
      Set_Character_Literal_Name (Char_Code (Character'Pos ('(')));
493
 
494
      Append_To (Stats,
495
         Make_Assignment_Statement (Loc,
496
           Name => Make_Indexed_Component (Loc,
497
              Prefix => New_Occurrence_Of (Res, Loc),
498
              Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
499
           Expression =>
500
             Make_Character_Literal (Loc,
501
               Chars => Name_Find,
502
               Char_Literal_Value =>
503
                 UI_From_Int (Character'Pos ('(')))));
504
 
505
      Append_To (Stats,
506
         Make_Assignment_Statement (Loc,
507
            Name => New_Occurrence_Of (Pos, Loc),
508
            Expression =>
509
              Make_Op_Add (Loc,
510
                Left_Opnd => New_Occurrence_Of (Pos, Loc),
511
                Right_Opnd => Make_Integer_Literal (Loc, 1))));
512
 
513
      for J in 1 .. Dims loop
514
 
515
         Append_To (Stats,
516
            Make_Assignment_Statement (Loc,
517
              Name => Make_Slice (Loc,
518
                 Prefix => New_Occurrence_Of (Res, Loc),
519
                 Discrete_Range  =>
520
                   Make_Range (Loc,
521
                      Low_Bound => New_Occurrence_Of  (Pos, Loc),
522
                      High_Bound => Make_Op_Subtract (Loc,
523
                        Left_Opnd =>
524
                          Make_Op_Add (Loc,
525
                            Left_Opnd => New_Occurrence_Of (Pos, Loc),
526
                            Right_Opnd =>
527
                              Make_Attribute_Reference (Loc,
528
                                Attribute_Name => Name_Length,
529
                                Prefix =>
530
                                  New_Occurrence_Of (Temps (J), Loc),
531
                                Expressions =>
532
                                  New_List (Make_Integer_Literal (Loc, 1)))),
533
                         Right_Opnd => Make_Integer_Literal (Loc, 1)))),
534
 
535
              Expression => New_Occurrence_Of (Temps (J), Loc)));
536
 
537
         if J < Dims then
538
            Append_To (Stats,
539
               Make_Assignment_Statement (Loc,
540
                  Name => New_Occurrence_Of (Pos, Loc),
541
                  Expression =>
542
                    Make_Op_Add (Loc,
543
                      Left_Opnd => New_Occurrence_Of (Pos, Loc),
544
                      Right_Opnd =>
545
                        Make_Attribute_Reference (Loc,
546
                          Attribute_Name => Name_Length,
547
                            Prefix => New_Occurrence_Of (Temps (J), Loc),
548
                            Expressions =>
549
                              New_List (Make_Integer_Literal (Loc, 1))))));
550
 
551
            Set_Character_Literal_Name (Char_Code (Character'Pos (',')));
552
 
553
            Append_To (Stats,
554
               Make_Assignment_Statement (Loc,
555
                 Name => Make_Indexed_Component (Loc,
556
                    Prefix => New_Occurrence_Of (Res, Loc),
557
                    Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
558
                 Expression =>
559
                   Make_Character_Literal (Loc,
560
                     Chars => Name_Find,
561
                     Char_Literal_Value =>
562
                       UI_From_Int (Character'Pos (',')))));
563
 
564
            Append_To (Stats,
565
              Make_Assignment_Statement (Loc,
566
                Name => New_Occurrence_Of (Pos, Loc),
567
                  Expression =>
568
                    Make_Op_Add (Loc,
569
                      Left_Opnd => New_Occurrence_Of (Pos, Loc),
570
                      Right_Opnd => Make_Integer_Literal (Loc, 1))));
571
         end if;
572
      end loop;
573
 
574
      Set_Character_Literal_Name (Char_Code (Character'Pos (')')));
575
 
576
      Append_To (Stats,
577
         Make_Assignment_Statement (Loc,
578
           Name => Make_Indexed_Component (Loc,
579
              Prefix => New_Occurrence_Of (Res, Loc),
580
              Expressions => New_List (New_Occurrence_Of (Len, Loc))),
581
           Expression =>
582
             Make_Character_Literal (Loc,
583
               Chars => Name_Find,
584
               Char_Literal_Value =>
585
                 UI_From_Int (Character'Pos (')')))));
586
      return Build_Task_Image_Function (Loc, Decls, Stats, Res);
587
   end Build_Task_Array_Image;
588
 
589
   ----------------------------
590
   -- Build_Task_Image_Decls --
591
   ----------------------------
592
 
593
   function Build_Task_Image_Decls
594
     (Loc          : Source_Ptr;
595
      Id_Ref       : Node_Id;
596
      A_Type       : Entity_Id;
597
      In_Init_Proc : Boolean := False) return List_Id
598
   is
599
      Decls  : constant List_Id   := New_List;
600
      T_Id   : Entity_Id := Empty;
601
      Decl   : Node_Id;
602
      Expr   : Node_Id   := Empty;
603
      Fun    : Node_Id   := Empty;
604
      Is_Dyn : constant Boolean :=
605
                 Nkind (Parent (Id_Ref)) = N_Assignment_Statement
606
                   and then
607
                 Nkind (Expression (Parent (Id_Ref))) = N_Allocator;
608
 
609
   begin
610
      --  If Discard_Names or No_Implicit_Heap_Allocations are in effect,
611
      --  generate a dummy declaration only.
612
 
613
      if Restriction_Active (No_Implicit_Heap_Allocations)
614
        or else Global_Discard_Names
615
      then
616
         T_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('J'));
617
         Name_Len := 0;
618
 
619
         return
620
           New_List (
621
             Make_Object_Declaration (Loc,
622
               Defining_Identifier => T_Id,
623
               Object_Definition => New_Occurrence_Of (Standard_String, Loc),
624
               Expression =>
625
                 Make_String_Literal (Loc,
626
                   Strval => String_From_Name_Buffer)));
627
 
628
      else
629
         if Nkind (Id_Ref) = N_Identifier
630
           or else Nkind (Id_Ref) = N_Defining_Identifier
631
         then
632
            --  For a simple variable, the image of the task is built from
633
            --  the name of the variable. To avoid possible conflict with
634
            --  the anonymous type created for a single protected object,
635
            --  add a numeric suffix.
636
 
637
            T_Id :=
638
              Make_Defining_Identifier (Loc,
639
                New_External_Name (Chars (Id_Ref), 'T', 1));
640
 
641
            Get_Name_String (Chars (Id_Ref));
642
 
643
            Expr :=
644
              Make_String_Literal (Loc,
645
                Strval => String_From_Name_Buffer);
646
 
647
         elsif Nkind (Id_Ref) = N_Selected_Component then
648
            T_Id :=
649
              Make_Defining_Identifier (Loc,
650
                New_External_Name (Chars (Selector_Name (Id_Ref)), 'T'));
651
            Fun := Build_Task_Record_Image (Loc, Id_Ref, Is_Dyn);
652
 
653
         elsif Nkind (Id_Ref) = N_Indexed_Component then
654
            T_Id :=
655
              Make_Defining_Identifier (Loc,
656
                New_External_Name (Chars (A_Type), 'N'));
657
 
658
            Fun := Build_Task_Array_Image (Loc, Id_Ref, A_Type, Is_Dyn);
659
         end if;
660
      end if;
661
 
662
      if Present (Fun) then
663
         Append (Fun, Decls);
664
         Expr := Make_Function_Call (Loc,
665
           Name => New_Occurrence_Of (Defining_Entity (Fun), Loc));
666
 
667
         if not In_Init_Proc and then VM_Target = No_VM then
668
            Set_Uses_Sec_Stack (Defining_Entity (Fun));
669
         end if;
670
      end if;
671
 
672
      Decl := Make_Object_Declaration (Loc,
673
        Defining_Identifier => T_Id,
674
        Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
675
        Constant_Present    => True,
676
        Expression          => Expr);
677
 
678
      Append (Decl, Decls);
679
      return Decls;
680
   end Build_Task_Image_Decls;
681
 
682
   -------------------------------
683
   -- Build_Task_Image_Function --
684
   -------------------------------
685
 
686
   function Build_Task_Image_Function
687
     (Loc   : Source_Ptr;
688
      Decls : List_Id;
689
      Stats : List_Id;
690
      Res   : Entity_Id) return Node_Id
691
   is
692
      Spec : Node_Id;
693
 
694
   begin
695
      Append_To (Stats,
696
        Make_Simple_Return_Statement (Loc,
697
          Expression => New_Occurrence_Of (Res, Loc)));
698
 
699
      Spec := Make_Function_Specification (Loc,
700
        Defining_Unit_Name =>
701
          Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
702
        Result_Definition => New_Occurrence_Of (Standard_String, Loc));
703
 
704
      --  Calls to 'Image use the secondary stack, which must be cleaned
705
      --  up after the task name is built.
706
 
707
      return Make_Subprogram_Body (Loc,
708
         Specification => Spec,
709
         Declarations => Decls,
710
         Handled_Statement_Sequence =>
711
           Make_Handled_Sequence_Of_Statements (Loc, Statements => Stats));
712
   end Build_Task_Image_Function;
713
 
714
   -----------------------------
715
   -- Build_Task_Image_Prefix --
716
   -----------------------------
717
 
718
   procedure Build_Task_Image_Prefix
719
      (Loc    : Source_Ptr;
720
       Len    : out Entity_Id;
721
       Res    : out Entity_Id;
722
       Pos    : out Entity_Id;
723
       Prefix : Entity_Id;
724
       Sum    : Node_Id;
725
       Decls  : List_Id;
726
       Stats  : List_Id)
727
   is
728
   begin
729
      Len := Make_Defining_Identifier (Loc, New_Internal_Name ('L'));
730
 
731
      Append_To (Decls,
732
        Make_Object_Declaration (Loc,
733
          Defining_Identifier => Len,
734
          Object_Definition => New_Occurrence_Of (Standard_Integer, Loc),
735
          Expression        => Sum));
736
 
737
      Res := Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
738
 
739
      Append_To (Decls,
740
         Make_Object_Declaration (Loc,
741
            Defining_Identifier => Res,
742
            Object_Definition =>
743
               Make_Subtype_Indication (Loc,
744
                  Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
745
               Constraint =>
746
                 Make_Index_Or_Discriminant_Constraint (Loc,
747
                   Constraints =>
748
                     New_List (
749
                       Make_Range (Loc,
750
                         Low_Bound => Make_Integer_Literal (Loc, 1),
751
                         High_Bound => New_Occurrence_Of (Len, Loc)))))));
752
 
753
      Pos := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
754
 
755
      Append_To (Decls,
756
         Make_Object_Declaration (Loc,
757
            Defining_Identifier => Pos,
758
            Object_Definition => New_Occurrence_Of (Standard_Integer, Loc)));
759
 
760
      --  Pos := Prefix'Length;
761
 
762
      Append_To (Stats,
763
         Make_Assignment_Statement (Loc,
764
            Name => New_Occurrence_Of (Pos, Loc),
765
            Expression =>
766
              Make_Attribute_Reference (Loc,
767
                Attribute_Name => Name_Length,
768
                Prefix => New_Occurrence_Of (Prefix, Loc),
769
                Expressions =>
770
                    New_List (Make_Integer_Literal (Loc, 1)))));
771
 
772
      --  Res (1 .. Pos) := Prefix;
773
 
774
      Append_To (Stats,
775
         Make_Assignment_Statement (Loc,
776
           Name => Make_Slice (Loc,
777
              Prefix => New_Occurrence_Of (Res, Loc),
778
              Discrete_Range  =>
779
                Make_Range (Loc,
780
                   Low_Bound => Make_Integer_Literal (Loc, 1),
781
                   High_Bound => New_Occurrence_Of (Pos, Loc))),
782
 
783
           Expression => New_Occurrence_Of (Prefix, Loc)));
784
 
785
      Append_To (Stats,
786
         Make_Assignment_Statement (Loc,
787
            Name => New_Occurrence_Of (Pos, Loc),
788
            Expression =>
789
              Make_Op_Add (Loc,
790
                Left_Opnd => New_Occurrence_Of (Pos, Loc),
791
                Right_Opnd => Make_Integer_Literal (Loc, 1))));
792
   end Build_Task_Image_Prefix;
793
 
794
   -----------------------------
795
   -- Build_Task_Record_Image --
796
   -----------------------------
797
 
798
   function Build_Task_Record_Image
799
     (Loc    : Source_Ptr;
800
      Id_Ref : Node_Id;
801
      Dyn    : Boolean := False) return Node_Id
802
   is
803
      Len : Entity_Id;
804
      --  Total length of generated name
805
 
806
      Pos : Entity_Id;
807
      --  Index into result
808
 
809
      Res : Entity_Id;
810
      --  String to hold result
811
 
812
      Pref : Entity_Id;
813
      --  Name of enclosing variable, prefix of resulting name
814
 
815
      Sum : Node_Id;
816
      --  Expression to compute total size of string
817
 
818
      Sel : Entity_Id;
819
      --  Entity for selector name
820
 
821
      Decls : constant List_Id := New_List;
822
      Stats : constant List_Id := New_List;
823
 
824
   begin
825
      Pref := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
826
 
827
      --  For a dynamic task, the name comes from the target variable.
828
      --  For a static one it is a formal of the enclosing init proc.
829
 
830
      if Dyn then
831
         Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
832
         Append_To (Decls,
833
           Make_Object_Declaration (Loc,
834
             Defining_Identifier => Pref,
835
             Object_Definition => New_Occurrence_Of (Standard_String, Loc),
836
             Expression =>
837
               Make_String_Literal (Loc,
838
                 Strval => String_From_Name_Buffer)));
839
 
840
      else
841
         Append_To (Decls,
842
           Make_Object_Renaming_Declaration (Loc,
843
             Defining_Identifier => Pref,
844
             Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
845
             Name                => Make_Identifier (Loc, Name_uTask_Name)));
846
      end if;
847
 
848
      Sel := Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
849
 
850
      Get_Name_String (Chars (Selector_Name (Id_Ref)));
851
 
852
      Append_To (Decls,
853
         Make_Object_Declaration (Loc,
854
           Defining_Identifier => Sel,
855
           Object_Definition => New_Occurrence_Of (Standard_String, Loc),
856
           Expression =>
857
             Make_String_Literal (Loc,
858
               Strval => String_From_Name_Buffer)));
859
 
860
      Sum := Make_Integer_Literal (Loc, Nat (Name_Len + 1));
861
 
862
      Sum :=
863
        Make_Op_Add (Loc,
864
          Left_Opnd => Sum,
865
          Right_Opnd =>
866
           Make_Attribute_Reference (Loc,
867
             Attribute_Name => Name_Length,
868
             Prefix =>
869
               New_Occurrence_Of (Pref, Loc),
870
             Expressions => New_List (Make_Integer_Literal (Loc, 1))));
871
 
872
      Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
873
 
874
      Set_Character_Literal_Name (Char_Code (Character'Pos ('.')));
875
 
876
      --  Res (Pos) := '.';
877
 
878
      Append_To (Stats,
879
         Make_Assignment_Statement (Loc,
880
           Name => Make_Indexed_Component (Loc,
881
              Prefix => New_Occurrence_Of (Res, Loc),
882
              Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
883
           Expression =>
884
             Make_Character_Literal (Loc,
885
               Chars => Name_Find,
886
               Char_Literal_Value =>
887
                 UI_From_Int (Character'Pos ('.')))));
888
 
889
      Append_To (Stats,
890
        Make_Assignment_Statement (Loc,
891
          Name => New_Occurrence_Of (Pos, Loc),
892
          Expression =>
893
            Make_Op_Add (Loc,
894
              Left_Opnd => New_Occurrence_Of (Pos, Loc),
895
              Right_Opnd => Make_Integer_Literal (Loc, 1))));
896
 
897
      --  Res (Pos .. Len) := Selector;
898
 
899
      Append_To (Stats,
900
        Make_Assignment_Statement (Loc,
901
          Name => Make_Slice (Loc,
902
             Prefix => New_Occurrence_Of (Res, Loc),
903
             Discrete_Range  =>
904
               Make_Range (Loc,
905
                 Low_Bound  => New_Occurrence_Of (Pos, Loc),
906
                 High_Bound => New_Occurrence_Of (Len, Loc))),
907
          Expression => New_Occurrence_Of (Sel, Loc)));
908
 
909
      return Build_Task_Image_Function (Loc, Decls, Stats, Res);
910
   end Build_Task_Record_Image;
911
 
912
   ----------------------------------
913
   -- Component_May_Be_Bit_Aligned --
914
   ----------------------------------
915
 
916
   function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is
917
      UT : constant Entity_Id := Underlying_Type (Etype (Comp));
918
 
919
   begin
920
      --  If no component clause, then everything is fine, since the back end
921
      --  never bit-misaligns by default, even if there is a pragma Packed for
922
      --  the record.
923
 
924
      if No (Component_Clause (Comp)) then
925
         return False;
926
      end if;
927
 
928
      --  It is only array and record types that cause trouble
929
 
930
      if not Is_Record_Type (UT)
931
        and then not Is_Array_Type (UT)
932
      then
933
         return False;
934
 
935
      --  If we know that we have a small (64 bits or less) record or small
936
      --  bit-packed array, then everything is fine, since the back end can
937
      --  handle these cases correctly.
938
 
939
      elsif Esize (Comp) <= 64
940
        and then (Is_Record_Type (UT)
941
                   or else Is_Bit_Packed_Array (UT))
942
      then
943
         return False;
944
 
945
      --  Otherwise if the component is not byte aligned, we know we have the
946
      --  nasty unaligned case.
947
 
948
      elsif Normalized_First_Bit (Comp) /= Uint_0
949
        or else Esize (Comp) mod System_Storage_Unit /= Uint_0
950
      then
951
         return True;
952
 
953
      --  If we are large and byte aligned, then OK at this level
954
 
955
      else
956
         return False;
957
      end if;
958
   end Component_May_Be_Bit_Aligned;
959
 
960
   -----------------------------------
961
   -- Corresponding_Runtime_Package --
962
   -----------------------------------
963
 
964
   function Corresponding_Runtime_Package (Typ : Entity_Id) return RTU_Id is
965
      Pkg_Id : RTU_Id := RTU_Null;
966
 
967
   begin
968
      pragma Assert (Is_Concurrent_Type (Typ));
969
 
970
      if Ekind (Typ) in Protected_Kind then
971
         if Has_Entries (Typ)
972
           or else Has_Interrupt_Handler (Typ)
973
           or else (Has_Attach_Handler (Typ)
974
                      and then not Restricted_Profile)
975
 
976
            --  A protected type without entries that covers an interface and
977
            --  overrides the abstract routines with protected procedures is
978
            --  considered equivalent to a protected type with entries in the
979
            --  context of dispatching select statements. It is sufficient to
980
            --  check for the presence of an interface list in the declaration
981
            --  node to recognize this case.
982
 
983
           or else Present (Interface_List (Parent (Typ)))
984
         then
985
            if Abort_Allowed
986
              or else Restriction_Active (No_Entry_Queue) = False
987
              or else Number_Entries (Typ) > 1
988
              or else (Has_Attach_Handler (Typ)
989
                         and then not Restricted_Profile)
990
            then
991
               Pkg_Id := System_Tasking_Protected_Objects_Entries;
992
            else
993
               Pkg_Id := System_Tasking_Protected_Objects_Single_Entry;
994
            end if;
995
 
996
         else
997
            Pkg_Id := System_Tasking_Protected_Objects;
998
         end if;
999
      end if;
1000
 
1001
      return Pkg_Id;
1002
   end Corresponding_Runtime_Package;
1003
 
1004
   -------------------------------
1005
   -- Convert_To_Actual_Subtype --
1006
   -------------------------------
1007
 
1008
   procedure Convert_To_Actual_Subtype (Exp : Entity_Id) is
1009
      Act_ST : Entity_Id;
1010
 
1011
   begin
1012
      Act_ST := Get_Actual_Subtype (Exp);
1013
 
1014
      if Act_ST = Etype (Exp) then
1015
         return;
1016
 
1017
      else
1018
         Rewrite (Exp,
1019
           Convert_To (Act_ST, Relocate_Node (Exp)));
1020
         Analyze_And_Resolve (Exp, Act_ST);
1021
      end if;
1022
   end Convert_To_Actual_Subtype;
1023
 
1024
   -----------------------------------
1025
   -- Current_Sem_Unit_Declarations --
1026
   -----------------------------------
1027
 
1028
   function Current_Sem_Unit_Declarations return List_Id is
1029
      U     : Node_Id := Unit (Cunit (Current_Sem_Unit));
1030
      Decls : List_Id;
1031
 
1032
   begin
1033
      --  If the current unit is a package body, locate the visible
1034
      --  declarations of the package spec.
1035
 
1036
      if Nkind (U) = N_Package_Body then
1037
         U := Unit (Library_Unit (Cunit (Current_Sem_Unit)));
1038
      end if;
1039
 
1040
      if Nkind (U) = N_Package_Declaration then
1041
         U := Specification (U);
1042
         Decls := Visible_Declarations (U);
1043
 
1044
         if No (Decls) then
1045
            Decls := New_List;
1046
            Set_Visible_Declarations (U, Decls);
1047
         end if;
1048
 
1049
      else
1050
         Decls := Declarations (U);
1051
 
1052
         if No (Decls) then
1053
            Decls := New_List;
1054
            Set_Declarations (U, Decls);
1055
         end if;
1056
      end if;
1057
 
1058
      return Decls;
1059
   end Current_Sem_Unit_Declarations;
1060
 
1061
   -----------------------
1062
   -- Duplicate_Subexpr --
1063
   -----------------------
1064
 
1065
   function Duplicate_Subexpr
1066
     (Exp      : Node_Id;
1067
      Name_Req : Boolean := False) return Node_Id
1068
   is
1069
   begin
1070
      Remove_Side_Effects (Exp, Name_Req);
1071
      return New_Copy_Tree (Exp);
1072
   end Duplicate_Subexpr;
1073
 
1074
   ---------------------------------
1075
   -- Duplicate_Subexpr_No_Checks --
1076
   ---------------------------------
1077
 
1078
   function Duplicate_Subexpr_No_Checks
1079
     (Exp      : Node_Id;
1080
      Name_Req : Boolean := False) return Node_Id
1081
   is
1082
      New_Exp : Node_Id;
1083
 
1084
   begin
1085
      Remove_Side_Effects (Exp, Name_Req);
1086
      New_Exp := New_Copy_Tree (Exp);
1087
      Remove_Checks (New_Exp);
1088
      return New_Exp;
1089
   end Duplicate_Subexpr_No_Checks;
1090
 
1091
   -----------------------------------
1092
   -- Duplicate_Subexpr_Move_Checks --
1093
   -----------------------------------
1094
 
1095
   function Duplicate_Subexpr_Move_Checks
1096
     (Exp      : Node_Id;
1097
      Name_Req : Boolean := False) return Node_Id
1098
   is
1099
      New_Exp : Node_Id;
1100
 
1101
   begin
1102
      Remove_Side_Effects (Exp, Name_Req);
1103
      New_Exp := New_Copy_Tree (Exp);
1104
      Remove_Checks (Exp);
1105
      return New_Exp;
1106
   end Duplicate_Subexpr_Move_Checks;
1107
 
1108
   --------------------
1109
   -- Ensure_Defined --
1110
   --------------------
1111
 
1112
   procedure Ensure_Defined (Typ : Entity_Id; N : Node_Id) is
1113
      IR : Node_Id;
1114
 
1115
   begin
1116
      --  An itype reference must only be created if this is a local
1117
      --  itype, so that gigi can elaborate it on the proper objstack.
1118
 
1119
      if Is_Itype (Typ)
1120
        and then Scope (Typ) = Current_Scope
1121
      then
1122
         IR := Make_Itype_Reference (Sloc (N));
1123
         Set_Itype (IR, Typ);
1124
         Insert_Action (N, IR);
1125
      end if;
1126
   end Ensure_Defined;
1127
 
1128
   --------------------
1129
   -- Entry_Names_OK --
1130
   --------------------
1131
 
1132
   function Entry_Names_OK return Boolean is
1133
   begin
1134
      return
1135
        not Restricted_Profile
1136
          and then not Global_Discard_Names
1137
          and then not Restriction_Active (No_Implicit_Heap_Allocations)
1138
          and then not Restriction_Active (No_Local_Allocators);
1139
   end Entry_Names_OK;
1140
 
1141
   ---------------------
1142
   -- Evolve_And_Then --
1143
   ---------------------
1144
 
1145
   procedure Evolve_And_Then (Cond : in out Node_Id; Cond1 : Node_Id) is
1146
   begin
1147
      if No (Cond) then
1148
         Cond := Cond1;
1149
      else
1150
         Cond :=
1151
           Make_And_Then (Sloc (Cond1),
1152
             Left_Opnd  => Cond,
1153
             Right_Opnd => Cond1);
1154
      end if;
1155
   end Evolve_And_Then;
1156
 
1157
   --------------------
1158
   -- Evolve_Or_Else --
1159
   --------------------
1160
 
1161
   procedure Evolve_Or_Else (Cond : in out Node_Id; Cond1 : Node_Id) is
1162
   begin
1163
      if No (Cond) then
1164
         Cond := Cond1;
1165
      else
1166
         Cond :=
1167
           Make_Or_Else (Sloc (Cond1),
1168
             Left_Opnd  => Cond,
1169
             Right_Opnd => Cond1);
1170
      end if;
1171
   end Evolve_Or_Else;
1172
 
1173
   ------------------------------
1174
   -- Expand_Subtype_From_Expr --
1175
   ------------------------------
1176
 
1177
   --  This function is applicable for both static and dynamic allocation of
1178
   --  objects which are constrained by an initial expression. Basically it
1179
   --  transforms an unconstrained subtype indication into a constrained one.
1180
   --  The expression may also be transformed in certain cases in order to
1181
   --  avoid multiple evaluation. In the static allocation case, the general
1182
   --  scheme is:
1183
 
1184
   --     Val : T := Expr;
1185
 
1186
   --        is transformed into
1187
 
1188
   --     Val : Constrained_Subtype_of_T := Maybe_Modified_Expr;
1189
   --
1190
   --  Here are the main cases :
1191
   --
1192
   --  <if Expr is a Slice>
1193
   --    Val : T ([Index_Subtype (Expr)]) := Expr;
1194
   --
1195
   --  <elsif Expr is a String Literal>
1196
   --    Val : T (T'First .. T'First + Length (string literal) - 1) := Expr;
1197
   --
1198
   --  <elsif Expr is Constrained>
1199
   --    subtype T is Type_Of_Expr
1200
   --    Val : T := Expr;
1201
   --
1202
   --  <elsif Expr is an entity_name>
1203
   --    Val : T (constraints taken from Expr) := Expr;
1204
   --
1205
   --  <else>
1206
   --    type Axxx is access all T;
1207
   --    Rval : Axxx := Expr'ref;
1208
   --    Val  : T (constraints taken from Rval) := Rval.all;
1209
 
1210
   --    ??? note: when the Expression is allocated in the secondary stack
1211
   --              we could use it directly instead of copying it by declaring
1212
   --              Val : T (...) renames Rval.all
1213
 
1214
   procedure Expand_Subtype_From_Expr
1215
     (N             : Node_Id;
1216
      Unc_Type      : Entity_Id;
1217
      Subtype_Indic : Node_Id;
1218
      Exp           : Node_Id)
1219
   is
1220
      Loc     : constant Source_Ptr := Sloc (N);
1221
      Exp_Typ : constant Entity_Id  := Etype (Exp);
1222
      T       : Entity_Id;
1223
 
1224
   begin
1225
      --  In general we cannot build the subtype if expansion is disabled,
1226
      --  because internal entities may not have been defined. However, to
1227
      --  avoid some cascaded errors, we try to continue when the expression
1228
      --  is an array (or string), because it is safe to compute the bounds.
1229
      --  It is in fact required to do so even in a generic context, because
1230
      --  there may be constants that depend on bounds of string literal.
1231
 
1232
      if not Expander_Active
1233
        and then (No (Etype (Exp))
1234
                   or else Base_Type (Etype (Exp)) /= Standard_String)
1235
      then
1236
         return;
1237
      end if;
1238
 
1239
      if Nkind (Exp) = N_Slice then
1240
         declare
1241
            Slice_Type : constant Entity_Id := Etype (First_Index (Exp_Typ));
1242
 
1243
         begin
1244
            Rewrite (Subtype_Indic,
1245
              Make_Subtype_Indication (Loc,
1246
                Subtype_Mark => New_Reference_To (Unc_Type, Loc),
1247
                Constraint =>
1248
                  Make_Index_Or_Discriminant_Constraint (Loc,
1249
                    Constraints => New_List
1250
                      (New_Reference_To (Slice_Type, Loc)))));
1251
 
1252
            --  This subtype indication may be used later for constraint checks
1253
            --  we better make sure that if a variable was used as a bound of
1254
            --  of the original slice, its value is frozen.
1255
 
1256
            Force_Evaluation (Low_Bound (Scalar_Range (Slice_Type)));
1257
            Force_Evaluation (High_Bound (Scalar_Range (Slice_Type)));
1258
         end;
1259
 
1260
      elsif Ekind (Exp_Typ) = E_String_Literal_Subtype then
1261
         Rewrite (Subtype_Indic,
1262
           Make_Subtype_Indication (Loc,
1263
             Subtype_Mark => New_Reference_To (Unc_Type, Loc),
1264
             Constraint =>
1265
               Make_Index_Or_Discriminant_Constraint (Loc,
1266
                 Constraints => New_List (
1267
                   Make_Literal_Range (Loc,
1268
                     Literal_Typ => Exp_Typ)))));
1269
 
1270
      elsif Is_Constrained (Exp_Typ)
1271
        and then not Is_Class_Wide_Type (Unc_Type)
1272
      then
1273
         if Is_Itype (Exp_Typ) then
1274
 
1275
            --  Within an initialization procedure, a selected component
1276
            --  denotes a component of the enclosing record, and it appears
1277
            --  as an actual in a call to its own initialization procedure.
1278
            --  If this component depends on the outer discriminant, we must
1279
            --  generate the proper actual subtype for it.
1280
 
1281
            if Nkind (Exp) = N_Selected_Component
1282
              and then Within_Init_Proc
1283
            then
1284
               declare
1285
                  Decl : constant Node_Id :=
1286
                           Build_Actual_Subtype_Of_Component (Exp_Typ, Exp);
1287
               begin
1288
                  if Present (Decl) then
1289
                     Insert_Action (N, Decl);
1290
                     T := Defining_Identifier (Decl);
1291
                  else
1292
                     T := Exp_Typ;
1293
                  end if;
1294
               end;
1295
 
1296
            --  No need to generate a new one (new what???)
1297
 
1298
            else
1299
               T := Exp_Typ;
1300
            end if;
1301
 
1302
         else
1303
            T :=
1304
              Make_Defining_Identifier (Loc,
1305
                Chars => New_Internal_Name ('T'));
1306
 
1307
            Insert_Action (N,
1308
              Make_Subtype_Declaration (Loc,
1309
                Defining_Identifier => T,
1310
                Subtype_Indication  => New_Reference_To (Exp_Typ, Loc)));
1311
 
1312
            --  This type is marked as an itype even though it has an
1313
            --  explicit declaration because otherwise it can be marked
1314
            --  with Is_Generic_Actual_Type and generate spurious errors.
1315
            --  (see sem_ch8.Analyze_Package_Renaming and sem_type.covers)
1316
 
1317
            Set_Is_Itype (T);
1318
            Set_Associated_Node_For_Itype (T, Exp);
1319
         end if;
1320
 
1321
         Rewrite (Subtype_Indic, New_Reference_To (T, Loc));
1322
 
1323
      --  Nothing needs to be done for private types with unknown discriminants
1324
      --  if the underlying type is not an unconstrained composite type or it
1325
      --  is an unchecked union.
1326
 
1327
      elsif Is_Private_Type (Unc_Type)
1328
        and then Has_Unknown_Discriminants (Unc_Type)
1329
        and then (not Is_Composite_Type (Underlying_Type (Unc_Type))
1330
                   or else Is_Constrained (Underlying_Type (Unc_Type))
1331
                   or else Is_Unchecked_Union (Underlying_Type (Unc_Type)))
1332
      then
1333
         null;
1334
 
1335
      --  Case of derived type with unknown discriminants where the parent type
1336
      --  also has unknown discriminants.
1337
 
1338
      elsif Is_Record_Type (Unc_Type)
1339
        and then not Is_Class_Wide_Type (Unc_Type)
1340
        and then Has_Unknown_Discriminants (Unc_Type)
1341
        and then Has_Unknown_Discriminants (Underlying_Type (Unc_Type))
1342
      then
1343
         --  Nothing to be done if no underlying record view available
1344
 
1345
         if No (Underlying_Record_View (Unc_Type)) then
1346
            null;
1347
 
1348
         --  Otherwise use the Underlying_Record_View to create the proper
1349
         --  constrained subtype for an object of a derived type with unknown
1350
         --  discriminants.
1351
 
1352
         else
1353
            Remove_Side_Effects (Exp);
1354
            Rewrite (Subtype_Indic,
1355
              Make_Subtype_From_Expr (Exp, Underlying_Record_View (Unc_Type)));
1356
         end if;
1357
 
1358
      --  Renamings of class-wide interface types require no equivalent
1359
      --  constrained type declarations because we only need to reference
1360
      --  the tag component associated with the interface.
1361
 
1362
      elsif Present (N)
1363
        and then Nkind (N) = N_Object_Renaming_Declaration
1364
        and then Is_Interface (Unc_Type)
1365
      then
1366
         pragma Assert (Is_Class_Wide_Type (Unc_Type));
1367
         null;
1368
 
1369
      --  In Ada95, nothing to be done if the type of the expression is
1370
      --  limited, because in this case the expression cannot be copied,
1371
      --  and its use can only be by reference.
1372
 
1373
      --  In Ada2005, the context can be an object declaration whose expression
1374
      --  is a function that returns in place. If the nominal subtype has
1375
      --  unknown discriminants, the call still provides constraints on the
1376
      --  object, and we have to create an actual subtype from it.
1377
 
1378
      --  If the type is class-wide, the expression is dynamically tagged and
1379
      --  we do not create an actual subtype either. Ditto for an interface.
1380
 
1381
      elsif Is_Limited_Type (Exp_Typ)
1382
        and then
1383
         (Is_Class_Wide_Type (Exp_Typ)
1384
           or else Is_Interface (Exp_Typ)
1385
           or else not Has_Unknown_Discriminants (Exp_Typ)
1386
           or else not Is_Composite_Type (Unc_Type))
1387
      then
1388
         null;
1389
 
1390
      --  For limited objects initialized with build in place function calls,
1391
      --  nothing to be done; otherwise we prematurely introduce an N_Reference
1392
      --  node in the expression initializing the object, which breaks the
1393
      --  circuitry that detects and adds the additional arguments to the
1394
      --  called function.
1395
 
1396
      elsif Is_Build_In_Place_Function_Call (Exp) then
1397
         null;
1398
 
1399
      else
1400
         Remove_Side_Effects (Exp);
1401
         Rewrite (Subtype_Indic,
1402
           Make_Subtype_From_Expr (Exp, Unc_Type));
1403
      end if;
1404
   end Expand_Subtype_From_Expr;
1405
 
1406
   --------------------
1407
   -- Find_Init_Call --
1408
   --------------------
1409
 
1410
   function Find_Init_Call
1411
     (Var        : Entity_Id;
1412
      Rep_Clause : Node_Id) return Node_Id
1413
   is
1414
      Typ : constant Entity_Id := Etype (Var);
1415
 
1416
      Init_Proc : Entity_Id;
1417
      --  Initialization procedure for Typ
1418
 
1419
      function Find_Init_Call_In_List (From : Node_Id) return Node_Id;
1420
      --  Look for init call for Var starting at From and scanning the
1421
      --  enclosing list until Rep_Clause or the end of the list is reached.
1422
 
1423
      ----------------------------
1424
      -- Find_Init_Call_In_List --
1425
      ----------------------------
1426
 
1427
      function Find_Init_Call_In_List (From : Node_Id) return Node_Id is
1428
         Init_Call : Node_Id;
1429
      begin
1430
         Init_Call := From;
1431
 
1432
         while Present (Init_Call) and then Init_Call /= Rep_Clause loop
1433
            if Nkind (Init_Call) = N_Procedure_Call_Statement
1434
                 and then Is_Entity_Name (Name (Init_Call))
1435
                 and then Entity (Name (Init_Call)) = Init_Proc
1436
            then
1437
               return Init_Call;
1438
            end if;
1439
            Next (Init_Call);
1440
         end loop;
1441
 
1442
         return Empty;
1443
      end Find_Init_Call_In_List;
1444
 
1445
      Init_Call : Node_Id;
1446
 
1447
   --  Start of processing for Find_Init_Call
1448
 
1449
   begin
1450
      if not Has_Non_Null_Base_Init_Proc (Typ) then
1451
         --  No init proc for the type, so obviously no call to be found
1452
 
1453
         return Empty;
1454
      end if;
1455
 
1456
      Init_Proc := Base_Init_Proc (Typ);
1457
 
1458
      --  First scan the list containing the declaration of Var
1459
 
1460
      Init_Call := Find_Init_Call_In_List (From => Next (Parent (Var)));
1461
 
1462
      --  If not found, also look on Var's freeze actions list, if any, since
1463
      --  the init call may have been moved there (case of an address clause
1464
      --  applying to Var).
1465
 
1466
      if No (Init_Call) and then Present (Freeze_Node (Var)) then
1467
         Init_Call := Find_Init_Call_In_List
1468
                        (First (Actions (Freeze_Node (Var))));
1469
      end if;
1470
 
1471
      return Init_Call;
1472
   end Find_Init_Call;
1473
 
1474
   ------------------------
1475
   -- Find_Interface_ADT --
1476
   ------------------------
1477
 
1478
   function Find_Interface_ADT
1479
     (T     : Entity_Id;
1480
      Iface : Entity_Id) return Elmt_Id
1481
   is
1482
      ADT : Elmt_Id;
1483
      Typ : Entity_Id := T;
1484
 
1485
   begin
1486
      pragma Assert (Is_Interface (Iface));
1487
 
1488
      --  Handle private types
1489
 
1490
      if Has_Private_Declaration (Typ)
1491
        and then Present (Full_View (Typ))
1492
      then
1493
         Typ := Full_View (Typ);
1494
      end if;
1495
 
1496
      --  Handle access types
1497
 
1498
      if Is_Access_Type (Typ) then
1499
         Typ := Directly_Designated_Type (Typ);
1500
      end if;
1501
 
1502
      --  Handle task and protected types implementing interfaces
1503
 
1504
      if Is_Concurrent_Type (Typ) then
1505
         Typ := Corresponding_Record_Type (Typ);
1506
      end if;
1507
 
1508
      pragma Assert
1509
        (not Is_Class_Wide_Type (Typ)
1510
          and then Ekind (Typ) /= E_Incomplete_Type);
1511
 
1512
      if Is_Ancestor (Iface, Typ) then
1513
         return First_Elmt (Access_Disp_Table (Typ));
1514
 
1515
      else
1516
         ADT :=
1517
           Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
1518
         while Present (ADT)
1519
           and then Present (Related_Type (Node (ADT)))
1520
           and then Related_Type (Node (ADT)) /= Iface
1521
           and then not Is_Ancestor (Iface, Related_Type (Node (ADT)))
1522
         loop
1523
            Next_Elmt (ADT);
1524
         end loop;
1525
 
1526
         pragma Assert (Present (Related_Type (Node (ADT))));
1527
         return ADT;
1528
      end if;
1529
   end Find_Interface_ADT;
1530
 
1531
   ------------------------
1532
   -- Find_Interface_Tag --
1533
   ------------------------
1534
 
1535
   function Find_Interface_Tag
1536
     (T     : Entity_Id;
1537
      Iface : Entity_Id) return Entity_Id
1538
   is
1539
      AI_Tag : Entity_Id;
1540
      Found  : Boolean   := False;
1541
      Typ    : Entity_Id := T;
1542
 
1543
      procedure Find_Tag (Typ : Entity_Id);
1544
      --  Internal subprogram used to recursively climb to the ancestors
1545
 
1546
      --------------
1547
      -- Find_Tag --
1548
      --------------
1549
 
1550
      procedure Find_Tag (Typ : Entity_Id) is
1551
         AI_Elmt : Elmt_Id;
1552
         AI      : Node_Id;
1553
 
1554
      begin
1555
         --  This routine does not handle the case in which the interface is an
1556
         --  ancestor of Typ. That case is handled by the enclosing subprogram.
1557
 
1558
         pragma Assert (Typ /= Iface);
1559
 
1560
         --  Climb to the root type handling private types
1561
 
1562
         if Present (Full_View (Etype (Typ))) then
1563
            if Full_View (Etype (Typ)) /= Typ then
1564
               Find_Tag (Full_View (Etype (Typ)));
1565
            end if;
1566
 
1567
         elsif Etype (Typ) /= Typ then
1568
            Find_Tag (Etype (Typ));
1569
         end if;
1570
 
1571
         --  Traverse the list of interfaces implemented by the type
1572
 
1573
         if not Found
1574
           and then Present (Interfaces (Typ))
1575
           and then not (Is_Empty_Elmt_List (Interfaces (Typ)))
1576
         then
1577
            --  Skip the tag associated with the primary table
1578
 
1579
            pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
1580
            AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
1581
            pragma Assert (Present (AI_Tag));
1582
 
1583
            AI_Elmt := First_Elmt (Interfaces (Typ));
1584
            while Present (AI_Elmt) loop
1585
               AI := Node (AI_Elmt);
1586
 
1587
               if AI = Iface or else Is_Ancestor (Iface, AI) then
1588
                  Found := True;
1589
                  return;
1590
               end if;
1591
 
1592
               AI_Tag := Next_Tag_Component (AI_Tag);
1593
               Next_Elmt (AI_Elmt);
1594
            end loop;
1595
         end if;
1596
      end Find_Tag;
1597
 
1598
   --  Start of processing for Find_Interface_Tag
1599
 
1600
   begin
1601
      pragma Assert (Is_Interface (Iface));
1602
 
1603
      --  Handle access types
1604
 
1605
      if Is_Access_Type (Typ) then
1606
         Typ := Directly_Designated_Type (Typ);
1607
      end if;
1608
 
1609
      --  Handle class-wide types
1610
 
1611
      if Is_Class_Wide_Type (Typ) then
1612
         Typ := Root_Type (Typ);
1613
      end if;
1614
 
1615
      --  Handle private types
1616
 
1617
      if Has_Private_Declaration (Typ)
1618
        and then Present (Full_View (Typ))
1619
      then
1620
         Typ := Full_View (Typ);
1621
      end if;
1622
 
1623
      --  Handle entities from the limited view
1624
 
1625
      if Ekind (Typ) = E_Incomplete_Type then
1626
         pragma Assert (Present (Non_Limited_View (Typ)));
1627
         Typ := Non_Limited_View (Typ);
1628
      end if;
1629
 
1630
      --  Handle task and protected types implementing interfaces
1631
 
1632
      if Is_Concurrent_Type (Typ) then
1633
         Typ := Corresponding_Record_Type (Typ);
1634
      end if;
1635
 
1636
      --  If the interface is an ancestor of the type, then it shared the
1637
      --  primary dispatch table.
1638
 
1639
      if Is_Ancestor (Iface, Typ) then
1640
         pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
1641
         return First_Tag_Component (Typ);
1642
 
1643
      --  Otherwise we need to search for its associated tag component
1644
 
1645
      else
1646
         Find_Tag (Typ);
1647
         pragma Assert (Found);
1648
         return AI_Tag;
1649
      end if;
1650
   end Find_Interface_Tag;
1651
 
1652
   ------------------
1653
   -- Find_Prim_Op --
1654
   ------------------
1655
 
1656
   function Find_Prim_Op (T : Entity_Id; Name : Name_Id) return Entity_Id is
1657
      Prim : Elmt_Id;
1658
      Typ  : Entity_Id := T;
1659
      Op   : Entity_Id;
1660
 
1661
   begin
1662
      if Is_Class_Wide_Type (Typ) then
1663
         Typ := Root_Type (Typ);
1664
      end if;
1665
 
1666
      Typ := Underlying_Type (Typ);
1667
 
1668
      --  Loop through primitive operations
1669
 
1670
      Prim := First_Elmt (Primitive_Operations (Typ));
1671
      while Present (Prim) loop
1672
         Op := Node (Prim);
1673
 
1674
         --  We can retrieve primitive operations by name if it is an internal
1675
         --  name. For equality we must check that both of its operands have
1676
         --  the same type, to avoid confusion with user-defined equalities
1677
         --  than may have a non-symmetric signature.
1678
 
1679
         exit when Chars (Op) = Name
1680
           and then
1681
             (Name /= Name_Op_Eq
1682
                or else Etype (First_Entity (Op)) = Etype (Last_Entity (Op)));
1683
 
1684
         Next_Elmt (Prim);
1685
 
1686
         --  Raise Program_Error if no primitive found
1687
 
1688
         if No (Prim) then
1689
            raise Program_Error;
1690
         end if;
1691
      end loop;
1692
 
1693
      return Node (Prim);
1694
   end Find_Prim_Op;
1695
 
1696
   ------------------
1697
   -- Find_Prim_Op --
1698
   ------------------
1699
 
1700
   function Find_Prim_Op
1701
     (T    : Entity_Id;
1702
      Name : TSS_Name_Type) return Entity_Id
1703
   is
1704
      Prim : Elmt_Id;
1705
      Typ  : Entity_Id := T;
1706
 
1707
   begin
1708
      if Is_Class_Wide_Type (Typ) then
1709
         Typ := Root_Type (Typ);
1710
      end if;
1711
 
1712
      Typ := Underlying_Type (Typ);
1713
 
1714
      Prim := First_Elmt (Primitive_Operations (Typ));
1715
      while not Is_TSS (Node (Prim), Name) loop
1716
         Next_Elmt (Prim);
1717
 
1718
         --  Raise program error if no primitive found
1719
 
1720
         if No (Prim) then
1721
            raise Program_Error;
1722
         end if;
1723
      end loop;
1724
 
1725
      return Node (Prim);
1726
   end Find_Prim_Op;
1727
 
1728
   ----------------------------
1729
   -- Find_Protection_Object --
1730
   ----------------------------
1731
 
1732
   function Find_Protection_Object (Scop : Entity_Id) return Entity_Id is
1733
      S : Entity_Id;
1734
 
1735
   begin
1736
      S := Scop;
1737
      while Present (S) loop
1738
         if (Ekind (S) = E_Entry
1739
               or else Ekind (S) = E_Entry_Family
1740
               or else Ekind (S) = E_Function
1741
               or else Ekind (S) = E_Procedure)
1742
           and then Present (Protection_Object (S))
1743
         then
1744
            return Protection_Object (S);
1745
         end if;
1746
 
1747
         S := Scope (S);
1748
      end loop;
1749
 
1750
      --  If we do not find a Protection object in the scope chain, then
1751
      --  something has gone wrong, most likely the object was never created.
1752
 
1753
      raise Program_Error;
1754
   end Find_Protection_Object;
1755
 
1756
   ----------------------
1757
   -- Force_Evaluation --
1758
   ----------------------
1759
 
1760
   procedure Force_Evaluation (Exp : Node_Id; Name_Req : Boolean := False) is
1761
   begin
1762
      Remove_Side_Effects (Exp, Name_Req, Variable_Ref => True);
1763
   end Force_Evaluation;
1764
 
1765
   ------------------------
1766
   -- Generate_Poll_Call --
1767
   ------------------------
1768
 
1769
   procedure Generate_Poll_Call (N : Node_Id) is
1770
   begin
1771
      --  No poll call if polling not active
1772
 
1773
      if not Polling_Required then
1774
         return;
1775
 
1776
      --  Otherwise generate require poll call
1777
 
1778
      else
1779
         Insert_Before_And_Analyze (N,
1780
           Make_Procedure_Call_Statement (Sloc (N),
1781
             Name => New_Occurrence_Of (RTE (RE_Poll), Sloc (N))));
1782
      end if;
1783
   end Generate_Poll_Call;
1784
 
1785
   ---------------------------------
1786
   -- Get_Current_Value_Condition --
1787
   ---------------------------------
1788
 
1789
   --  Note: the implementation of this procedure is very closely tied to the
1790
   --  implementation of Set_Current_Value_Condition. In the Get procedure, we
1791
   --  interpret Current_Value fields set by the Set procedure, so the two
1792
   --  procedures need to be closely coordinated.
1793
 
1794
   procedure Get_Current_Value_Condition
1795
     (Var : Node_Id;
1796
      Op  : out Node_Kind;
1797
      Val : out Node_Id)
1798
   is
1799
      Loc : constant Source_Ptr := Sloc (Var);
1800
      Ent : constant Entity_Id  := Entity (Var);
1801
 
1802
      procedure Process_Current_Value_Condition
1803
        (N : Node_Id;
1804
         S : Boolean);
1805
      --  N is an expression which holds either True (S = True) or False (S =
1806
      --  False) in the condition. This procedure digs out the expression and
1807
      --  if it refers to Ent, sets Op and Val appropriately.
1808
 
1809
      -------------------------------------
1810
      -- Process_Current_Value_Condition --
1811
      -------------------------------------
1812
 
1813
      procedure Process_Current_Value_Condition
1814
        (N : Node_Id;
1815
         S : Boolean)
1816
      is
1817
         Cond : Node_Id;
1818
         Sens : Boolean;
1819
 
1820
      begin
1821
         Cond := N;
1822
         Sens := S;
1823
 
1824
         --  Deal with NOT operators, inverting sense
1825
 
1826
         while Nkind (Cond) = N_Op_Not loop
1827
            Cond := Right_Opnd (Cond);
1828
            Sens := not Sens;
1829
         end loop;
1830
 
1831
         --  Deal with AND THEN and AND cases
1832
 
1833
         if Nkind (Cond) = N_And_Then
1834
           or else Nkind (Cond) = N_Op_And
1835
         then
1836
            --  Don't ever try to invert a condition that is of the form
1837
            --  of an AND or AND THEN (since we are not doing sufficiently
1838
            --  general processing to allow this).
1839
 
1840
            if Sens = False then
1841
               Op  := N_Empty;
1842
               Val := Empty;
1843
               return;
1844
            end if;
1845
 
1846
            --  Recursively process AND and AND THEN branches
1847
 
1848
            Process_Current_Value_Condition (Left_Opnd (Cond), True);
1849
 
1850
            if Op /= N_Empty then
1851
               return;
1852
            end if;
1853
 
1854
            Process_Current_Value_Condition (Right_Opnd (Cond), True);
1855
            return;
1856
 
1857
         --  Case of relational operator
1858
 
1859
         elsif Nkind (Cond) in N_Op_Compare then
1860
            Op := Nkind (Cond);
1861
 
1862
            --  Invert sense of test if inverted test
1863
 
1864
            if Sens = False then
1865
               case Op is
1866
                  when N_Op_Eq => Op := N_Op_Ne;
1867
                  when N_Op_Ne => Op := N_Op_Eq;
1868
                  when N_Op_Lt => Op := N_Op_Ge;
1869
                  when N_Op_Gt => Op := N_Op_Le;
1870
                  when N_Op_Le => Op := N_Op_Gt;
1871
                  when N_Op_Ge => Op := N_Op_Lt;
1872
                  when others  => raise Program_Error;
1873
               end case;
1874
            end if;
1875
 
1876
            --  Case of entity op value
1877
 
1878
            if Is_Entity_Name (Left_Opnd (Cond))
1879
              and then Ent = Entity (Left_Opnd (Cond))
1880
              and then Compile_Time_Known_Value (Right_Opnd (Cond))
1881
            then
1882
               Val := Right_Opnd (Cond);
1883
 
1884
            --  Case of value op entity
1885
 
1886
            elsif Is_Entity_Name (Right_Opnd (Cond))
1887
              and then Ent = Entity (Right_Opnd (Cond))
1888
              and then Compile_Time_Known_Value (Left_Opnd (Cond))
1889
            then
1890
               Val := Left_Opnd (Cond);
1891
 
1892
               --  We are effectively swapping operands
1893
 
1894
               case Op is
1895
                  when N_Op_Eq => null;
1896
                  when N_Op_Ne => null;
1897
                  when N_Op_Lt => Op := N_Op_Gt;
1898
                  when N_Op_Gt => Op := N_Op_Lt;
1899
                  when N_Op_Le => Op := N_Op_Ge;
1900
                  when N_Op_Ge => Op := N_Op_Le;
1901
                  when others  => raise Program_Error;
1902
               end case;
1903
 
1904
            else
1905
               Op := N_Empty;
1906
            end if;
1907
 
1908
            return;
1909
 
1910
            --  Case of Boolean variable reference, return as though the
1911
            --  reference had said var = True.
1912
 
1913
         else
1914
            if Is_Entity_Name (Cond)
1915
              and then Ent = Entity (Cond)
1916
            then
1917
               Val := New_Occurrence_Of (Standard_True, Sloc (Cond));
1918
 
1919
               if Sens = False then
1920
                  Op := N_Op_Ne;
1921
               else
1922
                  Op := N_Op_Eq;
1923
               end if;
1924
            end if;
1925
         end if;
1926
      end Process_Current_Value_Condition;
1927
 
1928
   --  Start of processing for Get_Current_Value_Condition
1929
 
1930
   begin
1931
      Op  := N_Empty;
1932
      Val := Empty;
1933
 
1934
      --  Immediate return, nothing doing, if this is not an object
1935
 
1936
      if Ekind (Ent) not in Object_Kind then
1937
         return;
1938
      end if;
1939
 
1940
      --  Otherwise examine current value
1941
 
1942
      declare
1943
         CV   : constant Node_Id := Current_Value (Ent);
1944
         Sens : Boolean;
1945
         Stm  : Node_Id;
1946
 
1947
      begin
1948
         --  If statement. Condition is known true in THEN section, known False
1949
         --  in any ELSIF or ELSE part, and unknown outside the IF statement.
1950
 
1951
         if Nkind (CV) = N_If_Statement then
1952
 
1953
            --  Before start of IF statement
1954
 
1955
            if Loc < Sloc (CV) then
1956
               return;
1957
 
1958
               --  After end of IF statement
1959
 
1960
            elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then
1961
               return;
1962
            end if;
1963
 
1964
            --  At this stage we know that we are within the IF statement, but
1965
            --  unfortunately, the tree does not record the SLOC of the ELSE so
1966
            --  we cannot use a simple SLOC comparison to distinguish between
1967
            --  the then/else statements, so we have to climb the tree.
1968
 
1969
            declare
1970
               N : Node_Id;
1971
 
1972
            begin
1973
               N := Parent (Var);
1974
               while Parent (N) /= CV loop
1975
                  N := Parent (N);
1976
 
1977
                  --  If we fall off the top of the tree, then that's odd, but
1978
                  --  perhaps it could occur in some error situation, and the
1979
                  --  safest response is simply to assume that the outcome of
1980
                  --  the condition is unknown. No point in bombing during an
1981
                  --  attempt to optimize things.
1982
 
1983
                  if No (N) then
1984
                     return;
1985
                  end if;
1986
               end loop;
1987
 
1988
               --  Now we have N pointing to a node whose parent is the IF
1989
               --  statement in question, so now we can tell if we are within
1990
               --  the THEN statements.
1991
 
1992
               if Is_List_Member (N)
1993
                 and then List_Containing (N) = Then_Statements (CV)
1994
               then
1995
                  Sens := True;
1996
 
1997
               --  If the variable reference does not come from source, we
1998
               --  cannot reliably tell whether it appears in the else part.
1999
               --  In particular, if it appears in generated code for a node
2000
               --  that requires finalization, it may be attached to a list
2001
               --  that has not been yet inserted into the code. For now,
2002
               --  treat it as unknown.
2003
 
2004
               elsif not Comes_From_Source (N) then
2005
                  return;
2006
 
2007
               --  Otherwise we must be in ELSIF or ELSE part
2008
 
2009
               else
2010
                  Sens := False;
2011
               end if;
2012
            end;
2013
 
2014
            --  ELSIF part. Condition is known true within the referenced
2015
            --  ELSIF, known False in any subsequent ELSIF or ELSE part, and
2016
            --  unknown before the ELSE part or after the IF statement.
2017
 
2018
         elsif Nkind (CV) = N_Elsif_Part then
2019
            Stm := Parent (CV);
2020
 
2021
            --  Before start of ELSIF part
2022
 
2023
            if Loc < Sloc (CV) then
2024
               return;
2025
 
2026
               --  After end of IF statement
2027
 
2028
            elsif Loc >= Sloc (Stm) +
2029
              Text_Ptr (UI_To_Int (End_Span (Stm)))
2030
            then
2031
               return;
2032
            end if;
2033
 
2034
            --  Again we lack the SLOC of the ELSE, so we need to climb the
2035
            --  tree to see if we are within the ELSIF part in question.
2036
 
2037
            declare
2038
               N : Node_Id;
2039
 
2040
            begin
2041
               N := Parent (Var);
2042
               while Parent (N) /= Stm loop
2043
                  N := Parent (N);
2044
 
2045
                  --  If we fall off the top of the tree, then that's odd, but
2046
                  --  perhaps it could occur in some error situation, and the
2047
                  --  safest response is simply to assume that the outcome of
2048
                  --  the condition is unknown. No point in bombing during an
2049
                  --  attempt to optimize things.
2050
 
2051
                  if No (N) then
2052
                     return;
2053
                  end if;
2054
               end loop;
2055
 
2056
               --  Now we have N pointing to a node whose parent is the IF
2057
               --  statement in question, so see if is the ELSIF part we want.
2058
               --  the THEN statements.
2059
 
2060
               if N = CV then
2061
                  Sens := True;
2062
 
2063
                  --  Otherwise we must be in subsequent ELSIF or ELSE part
2064
 
2065
               else
2066
                  Sens := False;
2067
               end if;
2068
            end;
2069
 
2070
         --  Iteration scheme of while loop. The condition is known to be
2071
         --  true within the body of the loop.
2072
 
2073
         elsif Nkind (CV) = N_Iteration_Scheme then
2074
            declare
2075
               Loop_Stmt : constant Node_Id := Parent (CV);
2076
 
2077
            begin
2078
               --  Before start of body of loop
2079
 
2080
               if Loc < Sloc (Loop_Stmt) then
2081
                  return;
2082
 
2083
               --  After end of LOOP statement
2084
 
2085
               elsif Loc >= Sloc (End_Label (Loop_Stmt)) then
2086
                  return;
2087
 
2088
               --  We are within the body of the loop
2089
 
2090
               else
2091
                  Sens := True;
2092
               end if;
2093
            end;
2094
 
2095
         --  All other cases of Current_Value settings
2096
 
2097
         else
2098
            return;
2099
         end if;
2100
 
2101
         --  If we fall through here, then we have a reportable condition, Sens
2102
         --  is True if the condition is true and False if it needs inverting.
2103
 
2104
         Process_Current_Value_Condition (Condition (CV), Sens);
2105
      end;
2106
   end Get_Current_Value_Condition;
2107
 
2108
   ---------------------------------
2109
   -- Has_Controlled_Coextensions --
2110
   ---------------------------------
2111
 
2112
   function Has_Controlled_Coextensions (Typ : Entity_Id) return Boolean is
2113
      D_Typ : Entity_Id;
2114
      Discr : Entity_Id;
2115
 
2116
   begin
2117
      --  Only consider record types
2118
 
2119
      if Ekind (Typ) /= E_Record_Type
2120
        and then Ekind (Typ) /= E_Record_Subtype
2121
      then
2122
         return False;
2123
      end if;
2124
 
2125
      if Has_Discriminants (Typ) then
2126
         Discr := First_Discriminant (Typ);
2127
         while Present (Discr) loop
2128
            D_Typ := Etype (Discr);
2129
 
2130
            if Ekind (D_Typ) = E_Anonymous_Access_Type
2131
              and then
2132
                (Is_Controlled (Directly_Designated_Type (D_Typ))
2133
                   or else
2134
                 Is_Concurrent_Type (Directly_Designated_Type (D_Typ)))
2135
            then
2136
               return True;
2137
            end if;
2138
 
2139
            Next_Discriminant (Discr);
2140
         end loop;
2141
      end if;
2142
 
2143
      return False;
2144
   end Has_Controlled_Coextensions;
2145
 
2146
   --------------------
2147
   -- Homonym_Number --
2148
   --------------------
2149
 
2150
   function Homonym_Number (Subp : Entity_Id) return Nat is
2151
      Count : Nat;
2152
      Hom   : Entity_Id;
2153
 
2154
   begin
2155
      Count := 1;
2156
      Hom := Homonym (Subp);
2157
      while Present (Hom) loop
2158
         if Scope (Hom) = Scope (Subp) then
2159
            Count := Count + 1;
2160
         end if;
2161
 
2162
         Hom := Homonym (Hom);
2163
      end loop;
2164
 
2165
      return Count;
2166
   end Homonym_Number;
2167
 
2168
   ------------------------------
2169
   -- In_Unconditional_Context --
2170
   ------------------------------
2171
 
2172
   function In_Unconditional_Context (Node : Node_Id) return Boolean is
2173
      P : Node_Id;
2174
 
2175
   begin
2176
      P := Node;
2177
      while Present (P) loop
2178
         case Nkind (P) is
2179
            when N_Subprogram_Body =>
2180
               return True;
2181
 
2182
            when N_If_Statement =>
2183
               return False;
2184
 
2185
            when N_Loop_Statement =>
2186
               return False;
2187
 
2188
            when N_Case_Statement =>
2189
               return False;
2190
 
2191
            when others =>
2192
               P := Parent (P);
2193
         end case;
2194
      end loop;
2195
 
2196
      return False;
2197
   end In_Unconditional_Context;
2198
 
2199
   -------------------
2200
   -- Insert_Action --
2201
   -------------------
2202
 
2203
   procedure Insert_Action (Assoc_Node : Node_Id; Ins_Action : Node_Id) is
2204
   begin
2205
      if Present (Ins_Action) then
2206
         Insert_Actions (Assoc_Node, New_List (Ins_Action));
2207
      end if;
2208
   end Insert_Action;
2209
 
2210
   --  Version with check(s) suppressed
2211
 
2212
   procedure Insert_Action
2213
     (Assoc_Node : Node_Id; Ins_Action : Node_Id; Suppress : Check_Id)
2214
   is
2215
   begin
2216
      Insert_Actions (Assoc_Node, New_List (Ins_Action), Suppress);
2217
   end Insert_Action;
2218
 
2219
   --------------------
2220
   -- Insert_Actions --
2221
   --------------------
2222
 
2223
   procedure Insert_Actions (Assoc_Node : Node_Id; Ins_Actions : List_Id) is
2224
      N : Node_Id;
2225
      P : Node_Id;
2226
 
2227
      Wrapped_Node : Node_Id := Empty;
2228
 
2229
   begin
2230
      if No (Ins_Actions) or else Is_Empty_List (Ins_Actions) then
2231
         return;
2232
      end if;
2233
 
2234
      --  Ignore insert of actions from inside default expression (or other
2235
      --  similar "spec expression") in the special spec-expression analyze
2236
      --  mode. Any insertions at this point have no relevance, since we are
2237
      --  only doing the analyze to freeze the types of any static expressions.
2238
      --  See section "Handling of Default Expressions" in the spec of package
2239
      --  Sem for further details.
2240
 
2241
      if In_Spec_Expression then
2242
         return;
2243
      end if;
2244
 
2245
      --  If the action derives from stuff inside a record, then the actions
2246
      --  are attached to the current scope, to be inserted and analyzed on
2247
      --  exit from the scope. The reason for this is that we may also
2248
      --  be generating freeze actions at the same time, and they must
2249
      --  eventually be elaborated in the correct order.
2250
 
2251
      if Is_Record_Type (Current_Scope)
2252
        and then not Is_Frozen (Current_Scope)
2253
      then
2254
         if No (Scope_Stack.Table
2255
           (Scope_Stack.Last).Pending_Freeze_Actions)
2256
         then
2257
            Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions :=
2258
              Ins_Actions;
2259
         else
2260
            Append_List
2261
              (Ins_Actions,
2262
               Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions);
2263
         end if;
2264
 
2265
         return;
2266
      end if;
2267
 
2268
      --  We now intend to climb up the tree to find the right point to
2269
      --  insert the actions. We start at Assoc_Node, unless this node is
2270
      --  a subexpression in which case we start with its parent. We do this
2271
      --  for two reasons. First it speeds things up. Second, if Assoc_Node
2272
      --  is itself one of the special nodes like N_And_Then, then we assume
2273
      --  that an initial request to insert actions for such a node does not
2274
      --  expect the actions to get deposited in the node for later handling
2275
      --  when the node is expanded, since clearly the node is being dealt
2276
      --  with by the caller. Note that in the subexpression case, N is
2277
      --  always the child we came from.
2278
 
2279
      --  N_Raise_xxx_Error is an annoying special case, it is a statement
2280
      --  if it has type Standard_Void_Type, and a subexpression otherwise.
2281
      --  otherwise. Procedure attribute references are also statements.
2282
 
2283
      if Nkind (Assoc_Node) in N_Subexpr
2284
        and then (Nkind (Assoc_Node) in N_Raise_xxx_Error
2285
                   or else Etype (Assoc_Node) /= Standard_Void_Type)
2286
        and then (Nkind (Assoc_Node) /= N_Attribute_Reference
2287
                   or else
2288
                     not Is_Procedure_Attribute_Name
2289
                           (Attribute_Name (Assoc_Node)))
2290
      then
2291
         P := Assoc_Node;             -- ??? does not agree with above!
2292
         N := Parent (Assoc_Node);
2293
 
2294
      --  Non-subexpression case. Note that N is initially Empty in this
2295
      --  case (N is only guaranteed Non-Empty in the subexpr case).
2296
 
2297
      else
2298
         P := Assoc_Node;
2299
         N := Empty;
2300
      end if;
2301
 
2302
      --  Capture root of the transient scope
2303
 
2304
      if Scope_Is_Transient then
2305
         Wrapped_Node := Node_To_Be_Wrapped;
2306
      end if;
2307
 
2308
      loop
2309
         pragma Assert (Present (P));
2310
 
2311
         case Nkind (P) is
2312
 
2313
            --  Case of right operand of AND THEN or OR ELSE. Put the actions
2314
            --  in the Actions field of the right operand. They will be moved
2315
            --  out further when the AND THEN or OR ELSE operator is expanded.
2316
            --  Nothing special needs to be done for the left operand since
2317
            --  in that case the actions are executed unconditionally.
2318
 
2319
            when N_Short_Circuit =>
2320
               if N = Right_Opnd (P) then
2321
 
2322
                  --  We are now going to either append the actions to the
2323
                  --  actions field of the short-circuit operation. We will
2324
                  --  also analyze the actions now.
2325
 
2326
                  --  This analysis is really too early, the proper thing would
2327
                  --  be to just park them there now, and only analyze them if
2328
                  --  we find we really need them, and to it at the proper
2329
                  --  final insertion point. However attempting to this proved
2330
                  --  tricky, so for now we just kill current values before and
2331
                  --  after the analyze call to make sure we avoid peculiar
2332
                  --  optimizations from this out of order insertion.
2333
 
2334
                  Kill_Current_Values;
2335
 
2336
                  if Present (Actions (P)) then
2337
                     Insert_List_After_And_Analyze
2338
                       (Last (Actions (P)), Ins_Actions);
2339
                  else
2340
                     Set_Actions (P, Ins_Actions);
2341
                     Analyze_List (Actions (P));
2342
                  end if;
2343
 
2344
                  Kill_Current_Values;
2345
 
2346
                  return;
2347
               end if;
2348
 
2349
            --  Then or Else operand of conditional expression. Add actions to
2350
            --  Then_Actions or Else_Actions field as appropriate. The actions
2351
            --  will be moved further out when the conditional is expanded.
2352
 
2353
            when N_Conditional_Expression =>
2354
               declare
2355
                  ThenX : constant Node_Id := Next (First (Expressions (P)));
2356
                  ElseX : constant Node_Id := Next (ThenX);
2357
 
2358
               begin
2359
                  --  Actions belong to the then expression, temporarily
2360
                  --  place them as Then_Actions of the conditional expr.
2361
                  --  They will be moved to the proper place later when
2362
                  --  the conditional expression is expanded.
2363
 
2364
                  if N = ThenX then
2365
                     if Present (Then_Actions (P)) then
2366
                        Insert_List_After_And_Analyze
2367
                          (Last (Then_Actions (P)), Ins_Actions);
2368
                     else
2369
                        Set_Then_Actions (P, Ins_Actions);
2370
                        Analyze_List (Then_Actions (P));
2371
                     end if;
2372
 
2373
                     return;
2374
 
2375
                  --  Actions belong to the else expression, temporarily
2376
                  --  place them as Else_Actions of the conditional expr.
2377
                  --  They will be moved to the proper place later when
2378
                  --  the conditional expression is expanded.
2379
 
2380
                  elsif N = ElseX then
2381
                     if Present (Else_Actions (P)) then
2382
                        Insert_List_After_And_Analyze
2383
                          (Last (Else_Actions (P)), Ins_Actions);
2384
                     else
2385
                        Set_Else_Actions (P, Ins_Actions);
2386
                        Analyze_List (Else_Actions (P));
2387
                     end if;
2388
 
2389
                     return;
2390
 
2391
                  --  Actions belong to the condition. In this case they are
2392
                  --  unconditionally executed, and so we can continue the
2393
                  --  search for the proper insert point.
2394
 
2395
                  else
2396
                     null;
2397
                  end if;
2398
               end;
2399
 
2400
            --  Case of appearing in the condition of a while expression or
2401
            --  elsif. We insert the actions into the Condition_Actions field.
2402
            --  They will be moved further out when the while loop or elsif
2403
            --  is analyzed.
2404
 
2405
            when N_Iteration_Scheme |
2406
                 N_Elsif_Part
2407
            =>
2408
               if N = Condition (P) then
2409
                  if Present (Condition_Actions (P)) then
2410
                     Insert_List_After_And_Analyze
2411
                       (Last (Condition_Actions (P)), Ins_Actions);
2412
                  else
2413
                     Set_Condition_Actions (P, Ins_Actions);
2414
 
2415
                     --  Set the parent of the insert actions explicitly.
2416
                     --  This is not a syntactic field, but we need the
2417
                     --  parent field set, in particular so that freeze
2418
                     --  can understand that it is dealing with condition
2419
                     --  actions, and properly insert the freezing actions.
2420
 
2421
                     Set_Parent (Ins_Actions, P);
2422
                     Analyze_List (Condition_Actions (P));
2423
                  end if;
2424
 
2425
                  return;
2426
               end if;
2427
 
2428
            --  Statements, declarations, pragmas, representation clauses
2429
 
2430
            when
2431
               --  Statements
2432
 
2433
               N_Procedure_Call_Statement               |
2434
               N_Statement_Other_Than_Procedure_Call    |
2435
 
2436
               --  Pragmas
2437
 
2438
               N_Pragma                                 |
2439
 
2440
               --  Representation_Clause
2441
 
2442
               N_At_Clause                              |
2443
               N_Attribute_Definition_Clause            |
2444
               N_Enumeration_Representation_Clause      |
2445
               N_Record_Representation_Clause           |
2446
 
2447
               --  Declarations
2448
 
2449
               N_Abstract_Subprogram_Declaration        |
2450
               N_Entry_Body                             |
2451
               N_Exception_Declaration                  |
2452
               N_Exception_Renaming_Declaration         |
2453
               N_Formal_Abstract_Subprogram_Declaration |
2454
               N_Formal_Concrete_Subprogram_Declaration |
2455
               N_Formal_Object_Declaration              |
2456
               N_Formal_Type_Declaration                |
2457
               N_Full_Type_Declaration                  |
2458
               N_Function_Instantiation                 |
2459
               N_Generic_Function_Renaming_Declaration  |
2460
               N_Generic_Package_Declaration            |
2461
               N_Generic_Package_Renaming_Declaration   |
2462
               N_Generic_Procedure_Renaming_Declaration |
2463
               N_Generic_Subprogram_Declaration         |
2464
               N_Implicit_Label_Declaration             |
2465
               N_Incomplete_Type_Declaration            |
2466
               N_Number_Declaration                     |
2467
               N_Object_Declaration                     |
2468
               N_Object_Renaming_Declaration            |
2469
               N_Package_Body                           |
2470
               N_Package_Body_Stub                      |
2471
               N_Package_Declaration                    |
2472
               N_Package_Instantiation                  |
2473
               N_Package_Renaming_Declaration           |
2474
               N_Private_Extension_Declaration          |
2475
               N_Private_Type_Declaration               |
2476
               N_Procedure_Instantiation                |
2477
               N_Protected_Body                         |
2478
               N_Protected_Body_Stub                    |
2479
               N_Protected_Type_Declaration             |
2480
               N_Single_Task_Declaration                |
2481
               N_Subprogram_Body                        |
2482
               N_Subprogram_Body_Stub                   |
2483
               N_Subprogram_Declaration                 |
2484
               N_Subprogram_Renaming_Declaration        |
2485
               N_Subtype_Declaration                    |
2486
               N_Task_Body                              |
2487
               N_Task_Body_Stub                         |
2488
               N_Task_Type_Declaration                  |
2489
 
2490
               --  Freeze entity behaves like a declaration or statement
2491
 
2492
               N_Freeze_Entity
2493
            =>
2494
               --  Do not insert here if the item is not a list member (this
2495
               --  happens for example with a triggering statement, and the
2496
               --  proper approach is to insert before the entire select).
2497
 
2498
               if not Is_List_Member (P) then
2499
                  null;
2500
 
2501
               --  Do not insert if parent of P is an N_Component_Association
2502
               --  node (i.e. we are in the context of an N_Aggregate or
2503
               --  N_Extension_Aggregate node. In this case we want to insert
2504
               --  before the entire aggregate.
2505
 
2506
               elsif Nkind (Parent (P)) = N_Component_Association then
2507
                  null;
2508
 
2509
               --  Do not insert if the parent of P is either an N_Variant
2510
               --  node or an N_Record_Definition node, meaning in either
2511
               --  case that P is a member of a component list, and that
2512
               --  therefore the actions should be inserted outside the
2513
               --  complete record declaration.
2514
 
2515
               elsif Nkind (Parent (P)) = N_Variant
2516
                 or else Nkind (Parent (P)) = N_Record_Definition
2517
               then
2518
                  null;
2519
 
2520
               --  Do not insert freeze nodes within the loop generated for
2521
               --  an aggregate, because they may be elaborated too late for
2522
               --  subsequent use in the back end: within a package spec the
2523
               --  loop is part of the elaboration procedure and is only
2524
               --  elaborated during the second pass.
2525
               --  If the loop comes from source, or the entity is local to
2526
               --  the loop itself it must remain within.
2527
 
2528
               elsif Nkind (Parent (P)) = N_Loop_Statement
2529
                 and then not Comes_From_Source (Parent (P))
2530
                 and then Nkind (First (Ins_Actions)) = N_Freeze_Entity
2531
                 and then
2532
                   Scope (Entity (First (Ins_Actions))) /= Current_Scope
2533
               then
2534
                  null;
2535
 
2536
               --  Otherwise we can go ahead and do the insertion
2537
 
2538
               elsif P = Wrapped_Node then
2539
                  Store_Before_Actions_In_Scope (Ins_Actions);
2540
                  return;
2541
 
2542
               else
2543
                  Insert_List_Before_And_Analyze (P, Ins_Actions);
2544
                  return;
2545
               end if;
2546
 
2547
            --  A special case, N_Raise_xxx_Error can act either as a
2548
            --  statement or a subexpression. We tell the difference
2549
            --  by looking at the Etype. It is set to Standard_Void_Type
2550
            --  in the statement case.
2551
 
2552
            when
2553
               N_Raise_xxx_Error =>
2554
                  if Etype (P) = Standard_Void_Type then
2555
                     if  P = Wrapped_Node then
2556
                        Store_Before_Actions_In_Scope (Ins_Actions);
2557
                     else
2558
                        Insert_List_Before_And_Analyze (P, Ins_Actions);
2559
                     end if;
2560
 
2561
                     return;
2562
 
2563
                  --  In the subexpression case, keep climbing
2564
 
2565
                  else
2566
                     null;
2567
                  end if;
2568
 
2569
            --  If a component association appears within a loop created for
2570
            --  an array aggregate, attach the actions to the association so
2571
            --  they can be subsequently inserted within the loop. For other
2572
            --  component associations insert outside of the aggregate. For
2573
            --  an association that will generate a loop, its Loop_Actions
2574
            --  attribute is already initialized (see exp_aggr.adb).
2575
 
2576
            --  The list of loop_actions can in turn generate additional ones,
2577
            --  that are inserted before the associated node. If the associated
2578
            --  node is outside the aggregate, the new actions are collected
2579
            --  at the end of the loop actions, to respect the order in which
2580
            --  they are to be elaborated.
2581
 
2582
            when
2583
               N_Component_Association =>
2584
                  if Nkind (Parent (P)) = N_Aggregate
2585
                    and then Present (Loop_Actions (P))
2586
                  then
2587
                     if Is_Empty_List (Loop_Actions (P)) then
2588
                        Set_Loop_Actions (P, Ins_Actions);
2589
                        Analyze_List (Ins_Actions);
2590
 
2591
                     else
2592
                        declare
2593
                           Decl : Node_Id;
2594
 
2595
                        begin
2596
                           --  Check whether these actions were generated
2597
                           --  by a declaration that is part of the loop_
2598
                           --  actions for the component_association.
2599
 
2600
                           Decl := Assoc_Node;
2601
                           while Present (Decl) loop
2602
                              exit when Parent (Decl) = P
2603
                                and then Is_List_Member (Decl)
2604
                                and then
2605
                                  List_Containing (Decl) = Loop_Actions (P);
2606
                              Decl := Parent (Decl);
2607
                           end loop;
2608
 
2609
                           if Present (Decl) then
2610
                              Insert_List_Before_And_Analyze
2611
                                (Decl, Ins_Actions);
2612
                           else
2613
                              Insert_List_After_And_Analyze
2614
                                (Last (Loop_Actions (P)), Ins_Actions);
2615
                           end if;
2616
                        end;
2617
                     end if;
2618
 
2619
                     return;
2620
 
2621
                  else
2622
                     null;
2623
                  end if;
2624
 
2625
            --  Another special case, an attribute denoting a procedure call
2626
 
2627
            when
2628
               N_Attribute_Reference =>
2629
                  if Is_Procedure_Attribute_Name (Attribute_Name (P)) then
2630
                     if P = Wrapped_Node then
2631
                        Store_Before_Actions_In_Scope (Ins_Actions);
2632
                     else
2633
                        Insert_List_Before_And_Analyze (P, Ins_Actions);
2634
                     end if;
2635
 
2636
                     return;
2637
 
2638
                  --  In the subexpression case, keep climbing
2639
 
2640
                  else
2641
                     null;
2642
                  end if;
2643
 
2644
            --  For all other node types, keep climbing tree
2645
 
2646
            when
2647
               N_Abortable_Part                         |
2648
               N_Accept_Alternative                     |
2649
               N_Access_Definition                      |
2650
               N_Access_Function_Definition             |
2651
               N_Access_Procedure_Definition            |
2652
               N_Access_To_Object_Definition            |
2653
               N_Aggregate                              |
2654
               N_Allocator                              |
2655
               N_Case_Statement_Alternative             |
2656
               N_Character_Literal                      |
2657
               N_Compilation_Unit                       |
2658
               N_Compilation_Unit_Aux                   |
2659
               N_Component_Clause                       |
2660
               N_Component_Declaration                  |
2661
               N_Component_Definition                   |
2662
               N_Component_List                         |
2663
               N_Constrained_Array_Definition           |
2664
               N_Decimal_Fixed_Point_Definition         |
2665
               N_Defining_Character_Literal             |
2666
               N_Defining_Identifier                    |
2667
               N_Defining_Operator_Symbol               |
2668
               N_Defining_Program_Unit_Name             |
2669
               N_Delay_Alternative                      |
2670
               N_Delta_Constraint                       |
2671
               N_Derived_Type_Definition                |
2672
               N_Designator                             |
2673
               N_Digits_Constraint                      |
2674
               N_Discriminant_Association               |
2675
               N_Discriminant_Specification             |
2676
               N_Empty                                  |
2677
               N_Entry_Body_Formal_Part                 |
2678
               N_Entry_Call_Alternative                 |
2679
               N_Entry_Declaration                      |
2680
               N_Entry_Index_Specification              |
2681
               N_Enumeration_Type_Definition            |
2682
               N_Error                                  |
2683
               N_Exception_Handler                      |
2684
               N_Expanded_Name                          |
2685
               N_Explicit_Dereference                   |
2686
               N_Extension_Aggregate                    |
2687
               N_Floating_Point_Definition              |
2688
               N_Formal_Decimal_Fixed_Point_Definition  |
2689
               N_Formal_Derived_Type_Definition         |
2690
               N_Formal_Discrete_Type_Definition        |
2691
               N_Formal_Floating_Point_Definition       |
2692
               N_Formal_Modular_Type_Definition         |
2693
               N_Formal_Ordinary_Fixed_Point_Definition |
2694
               N_Formal_Package_Declaration             |
2695
               N_Formal_Private_Type_Definition         |
2696
               N_Formal_Signed_Integer_Type_Definition  |
2697
               N_Function_Call                          |
2698
               N_Function_Specification                 |
2699
               N_Generic_Association                    |
2700
               N_Handled_Sequence_Of_Statements         |
2701
               N_Identifier                             |
2702
               N_In                                     |
2703
               N_Index_Or_Discriminant_Constraint       |
2704
               N_Indexed_Component                      |
2705
               N_Integer_Literal                        |
2706
               N_Itype_Reference                        |
2707
               N_Label                                  |
2708
               N_Loop_Parameter_Specification           |
2709
               N_Mod_Clause                             |
2710
               N_Modular_Type_Definition                |
2711
               N_Not_In                                 |
2712
               N_Null                                   |
2713
               N_Op_Abs                                 |
2714
               N_Op_Add                                 |
2715
               N_Op_And                                 |
2716
               N_Op_Concat                              |
2717
               N_Op_Divide                              |
2718
               N_Op_Eq                                  |
2719
               N_Op_Expon                               |
2720
               N_Op_Ge                                  |
2721
               N_Op_Gt                                  |
2722
               N_Op_Le                                  |
2723
               N_Op_Lt                                  |
2724
               N_Op_Minus                               |
2725
               N_Op_Mod                                 |
2726
               N_Op_Multiply                            |
2727
               N_Op_Ne                                  |
2728
               N_Op_Not                                 |
2729
               N_Op_Or                                  |
2730
               N_Op_Plus                                |
2731
               N_Op_Rem                                 |
2732
               N_Op_Rotate_Left                         |
2733
               N_Op_Rotate_Right                        |
2734
               N_Op_Shift_Left                          |
2735
               N_Op_Shift_Right                         |
2736
               N_Op_Shift_Right_Arithmetic              |
2737
               N_Op_Subtract                            |
2738
               N_Op_Xor                                 |
2739
               N_Operator_Symbol                        |
2740
               N_Ordinary_Fixed_Point_Definition        |
2741
               N_Others_Choice                          |
2742
               N_Package_Specification                  |
2743
               N_Parameter_Association                  |
2744
               N_Parameter_Specification                |
2745
               N_Pop_Constraint_Error_Label             |
2746
               N_Pop_Program_Error_Label                |
2747
               N_Pop_Storage_Error_Label                |
2748
               N_Pragma_Argument_Association            |
2749
               N_Procedure_Specification                |
2750
               N_Protected_Definition                   |
2751
               N_Push_Constraint_Error_Label            |
2752
               N_Push_Program_Error_Label               |
2753
               N_Push_Storage_Error_Label               |
2754
               N_Qualified_Expression                   |
2755
               N_Range                                  |
2756
               N_Range_Constraint                       |
2757
               N_Real_Literal                           |
2758
               N_Real_Range_Specification               |
2759
               N_Record_Definition                      |
2760
               N_Reference                              |
2761
               N_SCIL_Dispatch_Table_Object_Init        |
2762
               N_SCIL_Dispatch_Table_Tag_Init           |
2763
               N_SCIL_Dispatching_Call                  |
2764
               N_SCIL_Membership_Test                   |
2765
               N_SCIL_Tag_Init                          |
2766
               N_Selected_Component                     |
2767
               N_Signed_Integer_Type_Definition         |
2768
               N_Single_Protected_Declaration           |
2769
               N_Slice                                  |
2770
               N_String_Literal                         |
2771
               N_Subprogram_Info                        |
2772
               N_Subtype_Indication                     |
2773
               N_Subunit                                |
2774
               N_Task_Definition                        |
2775
               N_Terminate_Alternative                  |
2776
               N_Triggering_Alternative                 |
2777
               N_Type_Conversion                        |
2778
               N_Unchecked_Expression                   |
2779
               N_Unchecked_Type_Conversion              |
2780
               N_Unconstrained_Array_Definition         |
2781
               N_Unused_At_End                          |
2782
               N_Unused_At_Start                        |
2783
               N_Use_Package_Clause                     |
2784
               N_Use_Type_Clause                        |
2785
               N_Variant                                |
2786
               N_Variant_Part                           |
2787
               N_Validate_Unchecked_Conversion          |
2788
               N_With_Clause
2789
            =>
2790
               null;
2791
 
2792
         end case;
2793
 
2794
         --  Make sure that inserted actions stay in the transient scope
2795
 
2796
         if P = Wrapped_Node then
2797
            Store_Before_Actions_In_Scope (Ins_Actions);
2798
            return;
2799
         end if;
2800
 
2801
         --  If we fall through above tests, keep climbing tree
2802
 
2803
         N := P;
2804
 
2805
         if Nkind (Parent (N)) = N_Subunit then
2806
 
2807
            --  This is the proper body corresponding to a stub. Insertion
2808
            --  must be done at the point of the stub, which is in the decla-
2809
            --  rative part of the parent unit.
2810
 
2811
            P := Corresponding_Stub (Parent (N));
2812
 
2813
         else
2814
            P := Parent (N);
2815
         end if;
2816
      end loop;
2817
   end Insert_Actions;
2818
 
2819
   --  Version with check(s) suppressed
2820
 
2821
   procedure Insert_Actions
2822
     (Assoc_Node  : Node_Id;
2823
      Ins_Actions : List_Id;
2824
      Suppress    : Check_Id)
2825
   is
2826
   begin
2827
      if Suppress = All_Checks then
2828
         declare
2829
            Svg : constant Suppress_Array := Scope_Suppress;
2830
         begin
2831
            Scope_Suppress := (others => True);
2832
            Insert_Actions (Assoc_Node, Ins_Actions);
2833
            Scope_Suppress := Svg;
2834
         end;
2835
 
2836
      else
2837
         declare
2838
            Svg : constant Boolean := Scope_Suppress (Suppress);
2839
         begin
2840
            Scope_Suppress (Suppress) := True;
2841
            Insert_Actions (Assoc_Node, Ins_Actions);
2842
            Scope_Suppress (Suppress) := Svg;
2843
         end;
2844
      end if;
2845
   end Insert_Actions;
2846
 
2847
   --------------------------
2848
   -- Insert_Actions_After --
2849
   --------------------------
2850
 
2851
   procedure Insert_Actions_After
2852
     (Assoc_Node  : Node_Id;
2853
      Ins_Actions : List_Id)
2854
   is
2855
   begin
2856
      if Scope_Is_Transient
2857
        and then Assoc_Node = Node_To_Be_Wrapped
2858
      then
2859
         Store_After_Actions_In_Scope (Ins_Actions);
2860
      else
2861
         Insert_List_After_And_Analyze (Assoc_Node, Ins_Actions);
2862
      end if;
2863
   end Insert_Actions_After;
2864
 
2865
   ---------------------------------
2866
   -- Insert_Library_Level_Action --
2867
   ---------------------------------
2868
 
2869
   procedure Insert_Library_Level_Action (N : Node_Id) is
2870
      Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
2871
 
2872
   begin
2873
      Push_Scope (Cunit_Entity (Main_Unit));
2874
      --  ??? should this be Current_Sem_Unit instead of Main_Unit?
2875
 
2876
      if No (Actions (Aux)) then
2877
         Set_Actions (Aux, New_List (N));
2878
      else
2879
         Append (N, Actions (Aux));
2880
      end if;
2881
 
2882
      Analyze (N);
2883
      Pop_Scope;
2884
   end Insert_Library_Level_Action;
2885
 
2886
   ----------------------------------
2887
   -- Insert_Library_Level_Actions --
2888
   ----------------------------------
2889
 
2890
   procedure Insert_Library_Level_Actions (L : List_Id) is
2891
      Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
2892
 
2893
   begin
2894
      if Is_Non_Empty_List (L) then
2895
         Push_Scope (Cunit_Entity (Main_Unit));
2896
         --  ??? should this be Current_Sem_Unit instead of Main_Unit?
2897
 
2898
         if No (Actions (Aux)) then
2899
            Set_Actions (Aux, L);
2900
            Analyze_List (L);
2901
         else
2902
            Insert_List_After_And_Analyze (Last (Actions (Aux)), L);
2903
         end if;
2904
 
2905
         Pop_Scope;
2906
      end if;
2907
   end Insert_Library_Level_Actions;
2908
 
2909
   ----------------------
2910
   -- Inside_Init_Proc --
2911
   ----------------------
2912
 
2913
   function Inside_Init_Proc return Boolean is
2914
      S : Entity_Id;
2915
 
2916
   begin
2917
      S := Current_Scope;
2918
      while Present (S)
2919
        and then S /= Standard_Standard
2920
      loop
2921
         if Is_Init_Proc (S) then
2922
            return True;
2923
         else
2924
            S := Scope (S);
2925
         end if;
2926
      end loop;
2927
 
2928
      return False;
2929
   end Inside_Init_Proc;
2930
 
2931
   ----------------------------
2932
   -- Is_All_Null_Statements --
2933
   ----------------------------
2934
 
2935
   function Is_All_Null_Statements (L : List_Id) return Boolean is
2936
      Stm : Node_Id;
2937
 
2938
   begin
2939
      Stm := First (L);
2940
      while Present (Stm) loop
2941
         if Nkind (Stm) /= N_Null_Statement then
2942
            return False;
2943
         end if;
2944
 
2945
         Next (Stm);
2946
      end loop;
2947
 
2948
      return True;
2949
   end Is_All_Null_Statements;
2950
 
2951
   ---------------------------------
2952
   -- Is_Fully_Repped_Tagged_Type --
2953
   ---------------------------------
2954
 
2955
   function Is_Fully_Repped_Tagged_Type (T : Entity_Id) return Boolean is
2956
      U    : constant Entity_Id := Underlying_Type (T);
2957
      Comp : Entity_Id;
2958
 
2959
   begin
2960
      if No (U) or else not Is_Tagged_Type (U) then
2961
         return False;
2962
      elsif Has_Discriminants (U) then
2963
         return False;
2964
      elsif not Has_Specified_Layout (U) then
2965
         return False;
2966
      end if;
2967
 
2968
      --  Here we have a tagged type, see if it has any unlayed out fields
2969
      --  other than a possible tag and parent fields. If so, we return False.
2970
 
2971
      Comp := First_Component (U);
2972
      while Present (Comp) loop
2973
         if not Is_Tag (Comp)
2974
           and then Chars (Comp) /= Name_uParent
2975
           and then No (Component_Clause (Comp))
2976
         then
2977
            return False;
2978
         else
2979
            Next_Component (Comp);
2980
         end if;
2981
      end loop;
2982
 
2983
      --  All components are layed out
2984
 
2985
      return True;
2986
   end Is_Fully_Repped_Tagged_Type;
2987
 
2988
   ----------------------------------
2989
   -- Is_Library_Level_Tagged_Type --
2990
   ----------------------------------
2991
 
2992
   function Is_Library_Level_Tagged_Type (Typ : Entity_Id) return Boolean is
2993
   begin
2994
      return Is_Tagged_Type (Typ)
2995
        and then Is_Library_Level_Entity (Typ);
2996
   end Is_Library_Level_Tagged_Type;
2997
 
2998
   ----------------------------------
2999
   -- Is_Possibly_Unaligned_Object --
3000
   ----------------------------------
3001
 
3002
   function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean is
3003
      T  : constant Entity_Id := Etype (N);
3004
 
3005
   begin
3006
      --  If renamed object, apply test to underlying object
3007
 
3008
      if Is_Entity_Name (N)
3009
        and then Is_Object (Entity (N))
3010
        and then Present (Renamed_Object (Entity (N)))
3011
      then
3012
         return Is_Possibly_Unaligned_Object (Renamed_Object (Entity (N)));
3013
      end if;
3014
 
3015
      --  Tagged and controlled types and aliased types are always aligned,
3016
      --  as are concurrent types.
3017
 
3018
      if Is_Aliased (T)
3019
        or else Has_Controlled_Component (T)
3020
        or else Is_Concurrent_Type (T)
3021
        or else Is_Tagged_Type (T)
3022
        or else Is_Controlled (T)
3023
      then
3024
         return False;
3025
      end if;
3026
 
3027
      --  If this is an element of a packed array, may be unaligned
3028
 
3029
      if Is_Ref_To_Bit_Packed_Array (N) then
3030
         return True;
3031
      end if;
3032
 
3033
      --  Case of component reference
3034
 
3035
      if Nkind (N) = N_Selected_Component then
3036
         declare
3037
            P : constant Node_Id   := Prefix (N);
3038
            C : constant Entity_Id := Entity (Selector_Name (N));
3039
            M : Nat;
3040
            S : Nat;
3041
 
3042
         begin
3043
            --  If component reference is for an array with non-static bounds,
3044
            --  then it is always aligned: we can only process unaligned
3045
            --  arrays with static bounds (more accurately bounds known at
3046
            --  compile time).
3047
 
3048
            if Is_Array_Type (T)
3049
              and then not Compile_Time_Known_Bounds (T)
3050
            then
3051
               return False;
3052
            end if;
3053
 
3054
            --  If component is aliased, it is definitely properly aligned
3055
 
3056
            if Is_Aliased (C) then
3057
               return False;
3058
            end if;
3059
 
3060
            --  If component is for a type implemented as a scalar, and the
3061
            --  record is packed, and the component is other than the first
3062
            --  component of the record, then the component may be unaligned.
3063
 
3064
            if Is_Packed (Etype (P))
3065
              and then Represented_As_Scalar (Etype (C))
3066
              and then First_Entity (Scope (C)) /= C
3067
            then
3068
               return True;
3069
            end if;
3070
 
3071
            --  Compute maximum possible alignment for T
3072
 
3073
            --  If alignment is known, then that settles things
3074
 
3075
            if Known_Alignment (T) then
3076
               M := UI_To_Int (Alignment (T));
3077
 
3078
            --  If alignment is not known, tentatively set max alignment
3079
 
3080
            else
3081
               M := Ttypes.Maximum_Alignment;
3082
 
3083
               --  We can reduce this if the Esize is known since the default
3084
               --  alignment will never be more than the smallest power of 2
3085
               --  that does not exceed this Esize value.
3086
 
3087
               if Known_Esize (T) then
3088
                  S := UI_To_Int (Esize (T));
3089
 
3090
                  while (M / 2) >= S loop
3091
                     M := M / 2;
3092
                  end loop;
3093
               end if;
3094
            end if;
3095
 
3096
            --  If the component reference is for a record that has a specified
3097
            --  alignment, and we either know it is too small, or cannot tell,
3098
            --  then the component may be unaligned
3099
 
3100
            if Known_Alignment (Etype (P))
3101
              and then Alignment (Etype (P)) < Ttypes.Maximum_Alignment
3102
              and then M > Alignment (Etype (P))
3103
            then
3104
               return True;
3105
            end if;
3106
 
3107
            --  Case of component clause present which may specify an
3108
            --  unaligned position.
3109
 
3110
            if Present (Component_Clause (C)) then
3111
 
3112
               --  Otherwise we can do a test to make sure that the actual
3113
               --  start position in the record, and the length, are both
3114
               --  consistent with the required alignment. If not, we know
3115
               --  that we are unaligned.
3116
 
3117
               declare
3118
                  Align_In_Bits : constant Nat := M * System_Storage_Unit;
3119
               begin
3120
                  if Component_Bit_Offset (C) mod Align_In_Bits /= 0
3121
                    or else Esize (C) mod Align_In_Bits /= 0
3122
                  then
3123
                     return True;
3124
                  end if;
3125
               end;
3126
            end if;
3127
 
3128
            --  Otherwise, for a component reference, test prefix
3129
 
3130
            return Is_Possibly_Unaligned_Object (P);
3131
         end;
3132
 
3133
      --  If not a component reference, must be aligned
3134
 
3135
      else
3136
         return False;
3137
      end if;
3138
   end Is_Possibly_Unaligned_Object;
3139
 
3140
   ---------------------------------
3141
   -- Is_Possibly_Unaligned_Slice --
3142
   ---------------------------------
3143
 
3144
   function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean is
3145
   begin
3146
      --  Go to renamed object
3147
 
3148
      if Is_Entity_Name (N)
3149
        and then Is_Object (Entity (N))
3150
        and then Present (Renamed_Object (Entity (N)))
3151
      then
3152
         return Is_Possibly_Unaligned_Slice (Renamed_Object (Entity (N)));
3153
      end if;
3154
 
3155
      --  The reference must be a slice
3156
 
3157
      if Nkind (N) /= N_Slice then
3158
         return False;
3159
      end if;
3160
 
3161
      --  Always assume the worst for a nested record component with a
3162
      --  component clause, which gigi/gcc does not appear to handle well.
3163
      --  It is not clear why this special test is needed at all ???
3164
 
3165
      if Nkind (Prefix (N)) = N_Selected_Component
3166
        and then Nkind (Prefix (Prefix (N))) = N_Selected_Component
3167
        and then
3168
          Present (Component_Clause (Entity (Selector_Name (Prefix (N)))))
3169
      then
3170
         return True;
3171
      end if;
3172
 
3173
      --  We only need to worry if the target has strict alignment
3174
 
3175
      if not Target_Strict_Alignment then
3176
         return False;
3177
      end if;
3178
 
3179
      --  If it is a slice, then look at the array type being sliced
3180
 
3181
      declare
3182
         Sarr : constant Node_Id := Prefix (N);
3183
         --  Prefix of the slice, i.e. the array being sliced
3184
 
3185
         Styp : constant Entity_Id := Etype (Prefix (N));
3186
         --  Type of the array being sliced
3187
 
3188
         Pref : Node_Id;
3189
         Ptyp : Entity_Id;
3190
 
3191
      begin
3192
         --  The problems arise if the array object that is being sliced
3193
         --  is a component of a record or array, and we cannot guarantee
3194
         --  the alignment of the array within its containing object.
3195
 
3196
         --  To investigate this, we look at successive prefixes to see
3197
         --  if we have a worrisome indexed or selected component.
3198
 
3199
         Pref := Sarr;
3200
         loop
3201
            --  Case of array is part of an indexed component reference
3202
 
3203
            if Nkind (Pref) = N_Indexed_Component then
3204
               Ptyp := Etype (Prefix (Pref));
3205
 
3206
               --  The only problematic case is when the array is packed,
3207
               --  in which case we really know nothing about the alignment
3208
               --  of individual components.
3209
 
3210
               if Is_Bit_Packed_Array (Ptyp) then
3211
                  return True;
3212
               end if;
3213
 
3214
            --  Case of array is part of a selected component reference
3215
 
3216
            elsif Nkind (Pref) = N_Selected_Component then
3217
               Ptyp := Etype (Prefix (Pref));
3218
 
3219
               --  We are definitely in trouble if the record in question
3220
               --  has an alignment, and either we know this alignment is
3221
               --  inconsistent with the alignment of the slice, or we
3222
               --  don't know what the alignment of the slice should be.
3223
 
3224
               if Known_Alignment (Ptyp)
3225
                 and then (Unknown_Alignment (Styp)
3226
                             or else Alignment (Styp) > Alignment (Ptyp))
3227
               then
3228
                  return True;
3229
               end if;
3230
 
3231
               --  We are in potential trouble if the record type is packed.
3232
               --  We could special case when we know that the array is the
3233
               --  first component, but that's not such a simple case ???
3234
 
3235
               if Is_Packed (Ptyp) then
3236
                  return True;
3237
               end if;
3238
 
3239
               --  We are in trouble if there is a component clause, and
3240
               --  either we do not know the alignment of the slice, or
3241
               --  the alignment of the slice is inconsistent with the
3242
               --  bit position specified by the component clause.
3243
 
3244
               declare
3245
                  Field : constant Entity_Id := Entity (Selector_Name (Pref));
3246
               begin
3247
                  if Present (Component_Clause (Field))
3248
                    and then
3249
                      (Unknown_Alignment (Styp)
3250
                        or else
3251
                         (Component_Bit_Offset (Field) mod
3252
                           (System_Storage_Unit * Alignment (Styp))) /= 0)
3253
                  then
3254
                     return True;
3255
                  end if;
3256
               end;
3257
 
3258
            --  For cases other than selected or indexed components we
3259
            --  know we are OK, since no issues arise over alignment.
3260
 
3261
            else
3262
               return False;
3263
            end if;
3264
 
3265
            --  We processed an indexed component or selected component
3266
            --  reference that looked safe, so keep checking prefixes.
3267
 
3268
            Pref := Prefix (Pref);
3269
         end loop;
3270
      end;
3271
   end Is_Possibly_Unaligned_Slice;
3272
 
3273
   --------------------------------
3274
   -- Is_Ref_To_Bit_Packed_Array --
3275
   --------------------------------
3276
 
3277
   function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean is
3278
      Result : Boolean;
3279
      Expr   : Node_Id;
3280
 
3281
   begin
3282
      if Is_Entity_Name (N)
3283
        and then Is_Object (Entity (N))
3284
        and then Present (Renamed_Object (Entity (N)))
3285
      then
3286
         return Is_Ref_To_Bit_Packed_Array (Renamed_Object (Entity (N)));
3287
      end if;
3288
 
3289
      if Nkind (N) = N_Indexed_Component
3290
           or else
3291
         Nkind (N) = N_Selected_Component
3292
      then
3293
         if Is_Bit_Packed_Array (Etype (Prefix (N))) then
3294
            Result := True;
3295
         else
3296
            Result := Is_Ref_To_Bit_Packed_Array (Prefix (N));
3297
         end if;
3298
 
3299
         if Result and then Nkind (N) = N_Indexed_Component then
3300
            Expr := First (Expressions (N));
3301
            while Present (Expr) loop
3302
               Force_Evaluation (Expr);
3303
               Next (Expr);
3304
            end loop;
3305
         end if;
3306
 
3307
         return Result;
3308
 
3309
      else
3310
         return False;
3311
      end if;
3312
   end Is_Ref_To_Bit_Packed_Array;
3313
 
3314
   --------------------------------
3315
   -- Is_Ref_To_Bit_Packed_Slice --
3316
   --------------------------------
3317
 
3318
   function Is_Ref_To_Bit_Packed_Slice (N : Node_Id) return Boolean is
3319
   begin
3320
      if Nkind (N) = N_Type_Conversion then
3321
         return Is_Ref_To_Bit_Packed_Slice (Expression (N));
3322
 
3323
      elsif Is_Entity_Name (N)
3324
        and then Is_Object (Entity (N))
3325
        and then Present (Renamed_Object (Entity (N)))
3326
      then
3327
         return Is_Ref_To_Bit_Packed_Slice (Renamed_Object (Entity (N)));
3328
 
3329
      elsif Nkind (N) = N_Slice
3330
        and then Is_Bit_Packed_Array (Etype (Prefix (N)))
3331
      then
3332
         return True;
3333
 
3334
      elsif Nkind (N) = N_Indexed_Component
3335
           or else
3336
         Nkind (N) = N_Selected_Component
3337
      then
3338
         return Is_Ref_To_Bit_Packed_Slice (Prefix (N));
3339
 
3340
      else
3341
         return False;
3342
      end if;
3343
   end Is_Ref_To_Bit_Packed_Slice;
3344
 
3345
   -----------------------
3346
   -- Is_Renamed_Object --
3347
   -----------------------
3348
 
3349
   function Is_Renamed_Object (N : Node_Id) return Boolean is
3350
      Pnod : constant Node_Id   := Parent (N);
3351
      Kind : constant Node_Kind := Nkind (Pnod);
3352
   begin
3353
      if Kind = N_Object_Renaming_Declaration then
3354
         return True;
3355
      elsif Nkind_In (Kind, N_Indexed_Component, N_Selected_Component) then
3356
         return Is_Renamed_Object (Pnod);
3357
      else
3358
         return False;
3359
      end if;
3360
   end Is_Renamed_Object;
3361
 
3362
   ----------------------------
3363
   -- Is_Untagged_Derivation --
3364
   ----------------------------
3365
 
3366
   function Is_Untagged_Derivation (T : Entity_Id) return Boolean is
3367
   begin
3368
      return (not Is_Tagged_Type (T) and then Is_Derived_Type (T))
3369
               or else
3370
             (Is_Private_Type (T) and then Present (Full_View (T))
3371
               and then not Is_Tagged_Type (Full_View (T))
3372
               and then Is_Derived_Type (Full_View (T))
3373
               and then Etype (Full_View (T)) /= T);
3374
   end Is_Untagged_Derivation;
3375
 
3376
   ---------------------------
3377
   -- Is_Volatile_Reference --
3378
   ---------------------------
3379
 
3380
   function Is_Volatile_Reference (N : Node_Id) return Boolean is
3381
   begin
3382
      if Nkind (N) in N_Has_Etype
3383
        and then Present (Etype (N))
3384
        and then Treat_As_Volatile (Etype (N))
3385
      then
3386
         return True;
3387
 
3388
      elsif Is_Entity_Name (N) then
3389
         return Treat_As_Volatile (Entity (N));
3390
 
3391
      elsif Nkind (N) = N_Slice then
3392
         return Is_Volatile_Reference (Prefix (N));
3393
 
3394
      elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
3395
         if (Is_Entity_Name (Prefix (N))
3396
               and then Has_Volatile_Components (Entity (Prefix (N))))
3397
           or else (Present (Etype (Prefix (N)))
3398
                      and then Has_Volatile_Components (Etype (Prefix (N))))
3399
         then
3400
            return True;
3401
         else
3402
            return Is_Volatile_Reference (Prefix (N));
3403
         end if;
3404
 
3405
      else
3406
         return False;
3407
      end if;
3408
   end Is_Volatile_Reference;
3409
 
3410
   --------------------
3411
   -- Kill_Dead_Code --
3412
   --------------------
3413
 
3414
   procedure Kill_Dead_Code (N : Node_Id; Warn : Boolean := False) is
3415
      W : Boolean := Warn;
3416
      --  Set False if warnings suppressed
3417
 
3418
   begin
3419
      if Present (N) then
3420
         Remove_Warning_Messages (N);
3421
 
3422
         --  Generate warning if appropriate
3423
 
3424
         if W then
3425
 
3426
            --  We suppress the warning if this code is under control of an
3427
            --  if statement, whose condition is a simple identifier, and
3428
            --  either we are in an instance, or warnings off is set for this
3429
            --  identifier. The reason for killing it in the instance case is
3430
            --  that it is common and reasonable for code to be deleted in
3431
            --  instances for various reasons.
3432
 
3433
            if Nkind (Parent (N)) = N_If_Statement then
3434
               declare
3435
                  C : constant Node_Id := Condition (Parent (N));
3436
               begin
3437
                  if Nkind (C) = N_Identifier
3438
                    and then
3439
                      (In_Instance
3440
                        or else (Present (Entity (C))
3441
                                   and then Has_Warnings_Off (Entity (C))))
3442
                  then
3443
                     W := False;
3444
                  end if;
3445
               end;
3446
            end if;
3447
 
3448
            --  Generate warning if not suppressed
3449
 
3450
            if W then
3451
               Error_Msg_F
3452
                 ("?this code can never be executed and has been deleted!", N);
3453
            end if;
3454
         end if;
3455
 
3456
         --  Recurse into block statements and bodies to process declarations
3457
         --  and statements.
3458
 
3459
         if Nkind (N) = N_Block_Statement
3460
           or else Nkind (N) = N_Subprogram_Body
3461
           or else Nkind (N) = N_Package_Body
3462
         then
3463
            Kill_Dead_Code (Declarations (N), False);
3464
            Kill_Dead_Code (Statements (Handled_Statement_Sequence (N)));
3465
 
3466
            if Nkind (N) = N_Subprogram_Body then
3467
               Set_Is_Eliminated (Defining_Entity (N));
3468
            end if;
3469
 
3470
         elsif Nkind (N) = N_Package_Declaration then
3471
            Kill_Dead_Code (Visible_Declarations (Specification (N)));
3472
            Kill_Dead_Code (Private_Declarations (Specification (N)));
3473
 
3474
            --  ??? After this point, Delete_Tree has been called on all
3475
            --  declarations in Specification (N), so references to
3476
            --  entities therein look suspicious.
3477
 
3478
            declare
3479
               E : Entity_Id := First_Entity (Defining_Entity (N));
3480
            begin
3481
               while Present (E) loop
3482
                  if Ekind (E) = E_Operator then
3483
                     Set_Is_Eliminated (E);
3484
                  end if;
3485
 
3486
                  Next_Entity (E);
3487
               end loop;
3488
            end;
3489
 
3490
         --  Recurse into composite statement to kill individual statements,
3491
         --  in particular instantiations.
3492
 
3493
         elsif Nkind (N) = N_If_Statement then
3494
            Kill_Dead_Code (Then_Statements (N));
3495
            Kill_Dead_Code (Elsif_Parts (N));
3496
            Kill_Dead_Code (Else_Statements (N));
3497
 
3498
         elsif Nkind (N) = N_Loop_Statement then
3499
            Kill_Dead_Code (Statements (N));
3500
 
3501
         elsif Nkind (N) = N_Case_Statement then
3502
            declare
3503
               Alt : Node_Id;
3504
            begin
3505
               Alt := First (Alternatives (N));
3506
               while Present (Alt) loop
3507
                  Kill_Dead_Code (Statements (Alt));
3508
                  Next (Alt);
3509
               end loop;
3510
            end;
3511
 
3512
         elsif Nkind (N) = N_Case_Statement_Alternative then
3513
            Kill_Dead_Code (Statements (N));
3514
 
3515
         --  Deal with dead instances caused by deleting instantiations
3516
 
3517
         elsif Nkind (N) in N_Generic_Instantiation then
3518
            Remove_Dead_Instance (N);
3519
         end if;
3520
      end if;
3521
   end Kill_Dead_Code;
3522
 
3523
   --  Case where argument is a list of nodes to be killed
3524
 
3525
   procedure Kill_Dead_Code (L : List_Id; Warn : Boolean := False) is
3526
      N : Node_Id;
3527
      W : Boolean;
3528
   begin
3529
      W := Warn;
3530
      if Is_Non_Empty_List (L) then
3531
         N := First (L);
3532
         while Present (N) loop
3533
            Kill_Dead_Code (N, W);
3534
            W := False;
3535
            Next (N);
3536
         end loop;
3537
      end if;
3538
   end Kill_Dead_Code;
3539
 
3540
   ------------------------
3541
   -- Known_Non_Negative --
3542
   ------------------------
3543
 
3544
   function Known_Non_Negative (Opnd : Node_Id) return Boolean is
3545
   begin
3546
      if Is_OK_Static_Expression (Opnd)
3547
        and then Expr_Value (Opnd) >= 0
3548
      then
3549
         return True;
3550
 
3551
      else
3552
         declare
3553
            Lo : constant Node_Id := Type_Low_Bound (Etype (Opnd));
3554
 
3555
         begin
3556
            return
3557
              Is_OK_Static_Expression (Lo) and then Expr_Value (Lo) >= 0;
3558
         end;
3559
      end if;
3560
   end Known_Non_Negative;
3561
 
3562
   --------------------
3563
   -- Known_Non_Null --
3564
   --------------------
3565
 
3566
   function Known_Non_Null (N : Node_Id) return Boolean is
3567
   begin
3568
      --  Checks for case where N is an entity reference
3569
 
3570
      if Is_Entity_Name (N) and then Present (Entity (N)) then
3571
         declare
3572
            E   : constant Entity_Id := Entity (N);
3573
            Op  : Node_Kind;
3574
            Val : Node_Id;
3575
 
3576
         begin
3577
            --  First check if we are in decisive conditional
3578
 
3579
            Get_Current_Value_Condition (N, Op, Val);
3580
 
3581
            if Known_Null (Val) then
3582
               if Op = N_Op_Eq then
3583
                  return False;
3584
               elsif Op = N_Op_Ne then
3585
                  return True;
3586
               end if;
3587
            end if;
3588
 
3589
            --  If OK to do replacement, test Is_Known_Non_Null flag
3590
 
3591
            if OK_To_Do_Constant_Replacement (E) then
3592
               return Is_Known_Non_Null (E);
3593
 
3594
            --  Otherwise if not safe to do replacement, then say so
3595
 
3596
            else
3597
               return False;
3598
            end if;
3599
         end;
3600
 
3601
      --  True if access attribute
3602
 
3603
      elsif Nkind (N) = N_Attribute_Reference
3604
        and then (Attribute_Name (N) = Name_Access
3605
                    or else
3606
                  Attribute_Name (N) = Name_Unchecked_Access
3607
                    or else
3608
                  Attribute_Name (N) = Name_Unrestricted_Access)
3609
      then
3610
         return True;
3611
 
3612
      --  True if allocator
3613
 
3614
      elsif Nkind (N) = N_Allocator then
3615
         return True;
3616
 
3617
      --  For a conversion, true if expression is known non-null
3618
 
3619
      elsif Nkind (N) = N_Type_Conversion then
3620
         return Known_Non_Null (Expression (N));
3621
 
3622
      --  Above are all cases where the value could be determined to be
3623
      --  non-null. In all other cases, we don't know, so return False.
3624
 
3625
      else
3626
         return False;
3627
      end if;
3628
   end Known_Non_Null;
3629
 
3630
   ----------------
3631
   -- Known_Null --
3632
   ----------------
3633
 
3634
   function Known_Null (N : Node_Id) return Boolean is
3635
   begin
3636
      --  Checks for case where N is an entity reference
3637
 
3638
      if Is_Entity_Name (N) and then Present (Entity (N)) then
3639
         declare
3640
            E   : constant Entity_Id := Entity (N);
3641
            Op  : Node_Kind;
3642
            Val : Node_Id;
3643
 
3644
         begin
3645
            --  Constant null value is for sure null
3646
 
3647
            if Ekind (E) = E_Constant
3648
              and then Known_Null (Constant_Value (E))
3649
            then
3650
               return True;
3651
            end if;
3652
 
3653
            --  First check if we are in decisive conditional
3654
 
3655
            Get_Current_Value_Condition (N, Op, Val);
3656
 
3657
            if Known_Null (Val) then
3658
               if Op = N_Op_Eq then
3659
                  return True;
3660
               elsif Op = N_Op_Ne then
3661
                  return False;
3662
               end if;
3663
            end if;
3664
 
3665
            --  If OK to do replacement, test Is_Known_Null flag
3666
 
3667
            if OK_To_Do_Constant_Replacement (E) then
3668
               return Is_Known_Null (E);
3669
 
3670
            --  Otherwise if not safe to do replacement, then say so
3671
 
3672
            else
3673
               return False;
3674
            end if;
3675
         end;
3676
 
3677
      --  True if explicit reference to null
3678
 
3679
      elsif Nkind (N) = N_Null then
3680
         return True;
3681
 
3682
      --  For a conversion, true if expression is known null
3683
 
3684
      elsif Nkind (N) = N_Type_Conversion then
3685
         return Known_Null (Expression (N));
3686
 
3687
      --  Above are all cases where the value could be determined to be null.
3688
      --  In all other cases, we don't know, so return False.
3689
 
3690
      else
3691
         return False;
3692
      end if;
3693
   end Known_Null;
3694
 
3695
   -----------------------------
3696
   -- Make_CW_Equivalent_Type --
3697
   -----------------------------
3698
 
3699
   --  Create a record type used as an equivalent of any member of the class
3700
   --  which takes its size from exp.
3701
 
3702
   --  Generate the following code:
3703
 
3704
   --   type Equiv_T is record
3705
   --     _parent :  T (List of discriminant constraints taken from Exp);
3706
   --     Ext__50 : Storage_Array (1 .. (Exp'size - Typ'object_size)/8);
3707
   --   end Equiv_T;
3708
   --
3709
   --   ??? Note that this type does not guarantee same alignment as all
3710
   --   derived types
3711
 
3712
   function Make_CW_Equivalent_Type
3713
     (T : Entity_Id;
3714
      E : Node_Id) return Entity_Id
3715
   is
3716
      Loc         : constant Source_Ptr := Sloc (E);
3717
      Root_Typ    : constant Entity_Id  := Root_Type (T);
3718
      List_Def    : constant List_Id    := Empty_List;
3719
      Comp_List   : constant List_Id    := New_List;
3720
      Equiv_Type  : Entity_Id;
3721
      Range_Type  : Entity_Id;
3722
      Str_Type    : Entity_Id;
3723
      Constr_Root : Entity_Id;
3724
      Sizexpr     : Node_Id;
3725
 
3726
   begin
3727
      if not Has_Discriminants (Root_Typ) then
3728
         Constr_Root := Root_Typ;
3729
      else
3730
         Constr_Root :=
3731
           Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
3732
 
3733
         --  subtype cstr__n is T (List of discr constraints taken from Exp)
3734
 
3735
         Append_To (List_Def,
3736
           Make_Subtype_Declaration (Loc,
3737
             Defining_Identifier => Constr_Root,
3738
               Subtype_Indication =>
3739
                 Make_Subtype_From_Expr (E, Root_Typ)));
3740
      end if;
3741
 
3742
      --  Generate the range subtype declaration
3743
 
3744
      Range_Type := Make_Defining_Identifier (Loc, New_Internal_Name ('G'));
3745
 
3746
      if not Is_Interface (Root_Typ) then
3747
 
3748
         --  subtype rg__xx is
3749
         --    Storage_Offset range 1 .. (Expr'size - typ'size) / Storage_Unit
3750
 
3751
         Sizexpr :=
3752
           Make_Op_Subtract (Loc,
3753
             Left_Opnd =>
3754
               Make_Attribute_Reference (Loc,
3755
                 Prefix =>
3756
                   OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
3757
                 Attribute_Name => Name_Size),
3758
             Right_Opnd =>
3759
               Make_Attribute_Reference (Loc,
3760
                 Prefix => New_Reference_To (Constr_Root, Loc),
3761
                 Attribute_Name => Name_Object_Size));
3762
      else
3763
         --  subtype rg__xx is
3764
         --    Storage_Offset range 1 .. Expr'size / Storage_Unit
3765
 
3766
         Sizexpr :=
3767
           Make_Attribute_Reference (Loc,
3768
             Prefix =>
3769
               OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
3770
             Attribute_Name => Name_Size);
3771
      end if;
3772
 
3773
      Set_Paren_Count (Sizexpr, 1);
3774
 
3775
      Append_To (List_Def,
3776
        Make_Subtype_Declaration (Loc,
3777
          Defining_Identifier => Range_Type,
3778
          Subtype_Indication =>
3779
            Make_Subtype_Indication (Loc,
3780
              Subtype_Mark => New_Reference_To (RTE (RE_Storage_Offset), Loc),
3781
              Constraint => Make_Range_Constraint (Loc,
3782
                Range_Expression =>
3783
                  Make_Range (Loc,
3784
                    Low_Bound => Make_Integer_Literal (Loc, 1),
3785
                    High_Bound =>
3786
                      Make_Op_Divide (Loc,
3787
                        Left_Opnd => Sizexpr,
3788
                        Right_Opnd => Make_Integer_Literal (Loc,
3789
                            Intval => System_Storage_Unit)))))));
3790
 
3791
      --  subtype str__nn is Storage_Array (rg__x);
3792
 
3793
      Str_Type := Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
3794
      Append_To (List_Def,
3795
        Make_Subtype_Declaration (Loc,
3796
          Defining_Identifier => Str_Type,
3797
          Subtype_Indication =>
3798
            Make_Subtype_Indication (Loc,
3799
              Subtype_Mark => New_Reference_To (RTE (RE_Storage_Array), Loc),
3800
              Constraint =>
3801
                Make_Index_Or_Discriminant_Constraint (Loc,
3802
                  Constraints =>
3803
                    New_List (New_Reference_To (Range_Type, Loc))))));
3804
 
3805
      --  type Equiv_T is record
3806
      --    [ _parent : Tnn; ]
3807
      --    E : Str_Type;
3808
      --  end Equiv_T;
3809
 
3810
      Equiv_Type := Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
3811
      Set_Ekind (Equiv_Type, E_Record_Type);
3812
      Set_Parent_Subtype (Equiv_Type, Constr_Root);
3813
 
3814
      --  Set Is_Class_Wide_Equivalent_Type very early to trigger the special
3815
      --  treatment for this type. In particular, even though _parent's type
3816
      --  is a controlled type or contains controlled components, we do not
3817
      --  want to set Has_Controlled_Component on it to avoid making it gain
3818
      --  an unwanted _controller component.
3819
 
3820
      Set_Is_Class_Wide_Equivalent_Type (Equiv_Type);
3821
 
3822
      if not Is_Interface (Root_Typ) then
3823
         Append_To (Comp_List,
3824
           Make_Component_Declaration (Loc,
3825
             Defining_Identifier =>
3826
               Make_Defining_Identifier (Loc, Name_uParent),
3827
             Component_Definition =>
3828
               Make_Component_Definition (Loc,
3829
                 Aliased_Present    => False,
3830
                 Subtype_Indication => New_Reference_To (Constr_Root, Loc))));
3831
      end if;
3832
 
3833
      Append_To (Comp_List,
3834
        Make_Component_Declaration (Loc,
3835
          Defining_Identifier =>
3836
            Make_Defining_Identifier (Loc,
3837
              Chars => New_Internal_Name ('C')),
3838
          Component_Definition =>
3839
            Make_Component_Definition (Loc,
3840
              Aliased_Present    => False,
3841
              Subtype_Indication => New_Reference_To (Str_Type, Loc))));
3842
 
3843
      Append_To (List_Def,
3844
        Make_Full_Type_Declaration (Loc,
3845
          Defining_Identifier => Equiv_Type,
3846
          Type_Definition =>
3847
            Make_Record_Definition (Loc,
3848
              Component_List =>
3849
                Make_Component_List (Loc,
3850
                  Component_Items => Comp_List,
3851
                  Variant_Part    => Empty))));
3852
 
3853
      --  Suppress all checks during the analysis of the expanded code
3854
      --  to avoid the generation of spurious warnings under ZFP run-time.
3855
 
3856
      Insert_Actions (E, List_Def, Suppress => All_Checks);
3857
      return Equiv_Type;
3858
   end Make_CW_Equivalent_Type;
3859
 
3860
   ------------------------
3861
   -- Make_Literal_Range --
3862
   ------------------------
3863
 
3864
   function Make_Literal_Range
3865
     (Loc         : Source_Ptr;
3866
      Literal_Typ : Entity_Id) return Node_Id
3867
   is
3868
      Lo          : constant Node_Id :=
3869
                      New_Copy_Tree (String_Literal_Low_Bound (Literal_Typ));
3870
      Index       : constant Entity_Id := Etype (Lo);
3871
 
3872
      Hi          : Node_Id;
3873
      Length_Expr : constant Node_Id :=
3874
                      Make_Op_Subtract (Loc,
3875
                        Left_Opnd =>
3876
                          Make_Integer_Literal (Loc,
3877
                            Intval => String_Literal_Length (Literal_Typ)),
3878
                        Right_Opnd =>
3879
                          Make_Integer_Literal (Loc, 1));
3880
 
3881
   begin
3882
      Set_Analyzed (Lo, False);
3883
 
3884
         if Is_Integer_Type (Index) then
3885
            Hi :=
3886
              Make_Op_Add (Loc,
3887
                Left_Opnd  => New_Copy_Tree (Lo),
3888
                Right_Opnd => Length_Expr);
3889
         else
3890
            Hi :=
3891
              Make_Attribute_Reference (Loc,
3892
                Attribute_Name => Name_Val,
3893
                Prefix => New_Occurrence_Of (Index, Loc),
3894
                Expressions => New_List (
3895
                 Make_Op_Add (Loc,
3896
                   Left_Opnd =>
3897
                     Make_Attribute_Reference (Loc,
3898
                       Attribute_Name => Name_Pos,
3899
                       Prefix => New_Occurrence_Of (Index, Loc),
3900
                       Expressions => New_List (New_Copy_Tree (Lo))),
3901
                  Right_Opnd => Length_Expr)));
3902
         end if;
3903
 
3904
         return
3905
           Make_Range (Loc,
3906
             Low_Bound  => Lo,
3907
             High_Bound => Hi);
3908
   end Make_Literal_Range;
3909
 
3910
   --------------------------
3911
   -- Make_Non_Empty_Check --
3912
   --------------------------
3913
 
3914
   function Make_Non_Empty_Check
3915
     (Loc : Source_Ptr;
3916
      N   : Node_Id) return Node_Id
3917
   is
3918
   begin
3919
      return
3920
        Make_Op_Ne (Loc,
3921
          Left_Opnd =>
3922
            Make_Attribute_Reference (Loc,
3923
              Attribute_Name => Name_Length,
3924
              Prefix => Duplicate_Subexpr_No_Checks (N, Name_Req => True)),
3925
          Right_Opnd =>
3926
            Make_Integer_Literal (Loc, 0));
3927
   end Make_Non_Empty_Check;
3928
 
3929
   ----------------------------
3930
   -- Make_Subtype_From_Expr --
3931
   ----------------------------
3932
 
3933
   --  1. If Expr is an unconstrained array expression, creates
3934
   --    Unc_Type(Expr'first(1)..Expr'last(1),..., Expr'first(n)..Expr'last(n))
3935
 
3936
   --  2. If Expr is a unconstrained discriminated type expression, creates
3937
   --    Unc_Type(Expr.Discr1, ... , Expr.Discr_n)
3938
 
3939
   --  3. If Expr is class-wide, creates an implicit class wide subtype
3940
 
3941
   function Make_Subtype_From_Expr
3942
     (E       : Node_Id;
3943
      Unc_Typ : Entity_Id) return Node_Id
3944
   is
3945
      Loc         : constant Source_Ptr := Sloc (E);
3946
      List_Constr : constant List_Id    := New_List;
3947
      D           : Entity_Id;
3948
 
3949
      Full_Subtyp  : Entity_Id;
3950
      Priv_Subtyp  : Entity_Id;
3951
      Utyp         : Entity_Id;
3952
      Full_Exp     : Node_Id;
3953
 
3954
   begin
3955
      if Is_Private_Type (Unc_Typ)
3956
        and then Has_Unknown_Discriminants (Unc_Typ)
3957
      then
3958
         --  Prepare the subtype completion, Go to base type to
3959
         --  find underlying type, because the type may be a generic
3960
         --  actual or an explicit subtype.
3961
 
3962
         Utyp        := Underlying_Type (Base_Type (Unc_Typ));
3963
         Full_Subtyp := Make_Defining_Identifier (Loc,
3964
                          New_Internal_Name ('C'));
3965
         Full_Exp    :=
3966
           Unchecked_Convert_To
3967
             (Utyp, Duplicate_Subexpr_No_Checks (E));
3968
         Set_Parent (Full_Exp, Parent (E));
3969
 
3970
         Priv_Subtyp :=
3971
           Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
3972
 
3973
         Insert_Action (E,
3974
           Make_Subtype_Declaration (Loc,
3975
             Defining_Identifier => Full_Subtyp,
3976
             Subtype_Indication  => Make_Subtype_From_Expr (Full_Exp, Utyp)));
3977
 
3978
         --  Define the dummy private subtype
3979
 
3980
         Set_Ekind          (Priv_Subtyp, Subtype_Kind (Ekind (Unc_Typ)));
3981
         Set_Etype          (Priv_Subtyp, Base_Type (Unc_Typ));
3982
         Set_Scope          (Priv_Subtyp, Full_Subtyp);
3983
         Set_Is_Constrained (Priv_Subtyp);
3984
         Set_Is_Tagged_Type (Priv_Subtyp, Is_Tagged_Type (Unc_Typ));
3985
         Set_Is_Itype       (Priv_Subtyp);
3986
         Set_Associated_Node_For_Itype (Priv_Subtyp, E);
3987
 
3988
         if Is_Tagged_Type  (Priv_Subtyp) then
3989
            Set_Class_Wide_Type
3990
              (Base_Type (Priv_Subtyp), Class_Wide_Type (Unc_Typ));
3991
            Set_Primitive_Operations (Priv_Subtyp,
3992
              Primitive_Operations (Unc_Typ));
3993
         end if;
3994
 
3995
         Set_Full_View (Priv_Subtyp, Full_Subtyp);
3996
 
3997
         return New_Reference_To (Priv_Subtyp, Loc);
3998
 
3999
      elsif Is_Array_Type (Unc_Typ) then
4000
         for J in 1 .. Number_Dimensions (Unc_Typ) loop
4001
            Append_To (List_Constr,
4002
              Make_Range (Loc,
4003
                Low_Bound =>
4004
                  Make_Attribute_Reference (Loc,
4005
                    Prefix => Duplicate_Subexpr_No_Checks (E),
4006
                    Attribute_Name => Name_First,
4007
                    Expressions => New_List (
4008
                      Make_Integer_Literal (Loc, J))),
4009
 
4010
                High_Bound =>
4011
                  Make_Attribute_Reference (Loc,
4012
                    Prefix         => Duplicate_Subexpr_No_Checks (E),
4013
                    Attribute_Name => Name_Last,
4014
                    Expressions    => New_List (
4015
                      Make_Integer_Literal (Loc, J)))));
4016
         end loop;
4017
 
4018
      elsif Is_Class_Wide_Type (Unc_Typ) then
4019
         declare
4020
            CW_Subtype : Entity_Id;
4021
            EQ_Typ     : Entity_Id := Empty;
4022
 
4023
         begin
4024
            --  A class-wide equivalent type is not needed when VM_Target
4025
            --  because the VM back-ends handle the class-wide object
4026
            --  initialization itself (and doesn't need or want the
4027
            --  additional intermediate type to handle the assignment).
4028
 
4029
            if Expander_Active and then Tagged_Type_Expansion then
4030
               EQ_Typ := Make_CW_Equivalent_Type (Unc_Typ, E);
4031
            end if;
4032
 
4033
            CW_Subtype := New_Class_Wide_Subtype (Unc_Typ, E);
4034
            Set_Equivalent_Type (CW_Subtype, EQ_Typ);
4035
            Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ));
4036
 
4037
            return New_Occurrence_Of (CW_Subtype, Loc);
4038
         end;
4039
 
4040
      --  Indefinite record type with discriminants
4041
 
4042
      else
4043
         D := First_Discriminant (Unc_Typ);
4044
         while Present (D) loop
4045
            Append_To (List_Constr,
4046
              Make_Selected_Component (Loc,
4047
                Prefix        => Duplicate_Subexpr_No_Checks (E),
4048
                Selector_Name => New_Reference_To (D, Loc)));
4049
 
4050
            Next_Discriminant (D);
4051
         end loop;
4052
      end if;
4053
 
4054
      return
4055
        Make_Subtype_Indication (Loc,
4056
          Subtype_Mark => New_Reference_To (Unc_Typ, Loc),
4057
          Constraint   =>
4058
            Make_Index_Or_Discriminant_Constraint (Loc,
4059
              Constraints => List_Constr));
4060
   end Make_Subtype_From_Expr;
4061
 
4062
   -----------------------------
4063
   -- May_Generate_Large_Temp --
4064
   -----------------------------
4065
 
4066
   --  At the current time, the only types that we return False for (i.e.
4067
   --  where we decide we know they cannot generate large temps) are ones
4068
   --  where we know the size is 256 bits or less at compile time, and we
4069
   --  are still not doing a thorough job on arrays and records ???
4070
 
4071
   function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is
4072
   begin
4073
      if not Size_Known_At_Compile_Time (Typ) then
4074
         return False;
4075
 
4076
      elsif Esize (Typ) /= 0 and then Esize (Typ) <= 256 then
4077
         return False;
4078
 
4079
      elsif Is_Array_Type (Typ)
4080
        and then Present (Packed_Array_Type (Typ))
4081
      then
4082
         return May_Generate_Large_Temp (Packed_Array_Type (Typ));
4083
 
4084
      --  We could do more here to find other small types ???
4085
 
4086
      else
4087
         return True;
4088
      end if;
4089
   end May_Generate_Large_Temp;
4090
 
4091
   ----------------------------
4092
   -- New_Class_Wide_Subtype --
4093
   ----------------------------
4094
 
4095
   function New_Class_Wide_Subtype
4096
     (CW_Typ : Entity_Id;
4097
      N      : Node_Id) return Entity_Id
4098
   is
4099
      Res       : constant Entity_Id := Create_Itype (E_Void, N);
4100
      Res_Name  : constant Name_Id   := Chars (Res);
4101
      Res_Scope : constant Entity_Id := Scope (Res);
4102
 
4103
   begin
4104
      Copy_Node (CW_Typ, Res);
4105
      Set_Comes_From_Source (Res, False);
4106
      Set_Sloc (Res, Sloc (N));
4107
      Set_Is_Itype (Res);
4108
      Set_Associated_Node_For_Itype (Res, N);
4109
      Set_Is_Public (Res, False);   --  By default, may be changed below.
4110
      Set_Public_Status (Res);
4111
      Set_Chars (Res, Res_Name);
4112
      Set_Scope (Res, Res_Scope);
4113
      Set_Ekind (Res, E_Class_Wide_Subtype);
4114
      Set_Next_Entity (Res, Empty);
4115
      Set_Etype (Res, Base_Type (CW_Typ));
4116
      Set_Is_Frozen (Res, False);
4117
      Set_Freeze_Node (Res, Empty);
4118
      return (Res);
4119
   end New_Class_Wide_Subtype;
4120
 
4121
   --------------------------------
4122
   -- Non_Limited_Designated_Type --
4123
   ---------------------------------
4124
 
4125
   function Non_Limited_Designated_Type (T : Entity_Id) return Entity_Id is
4126
      Desig : constant Entity_Id := Designated_Type (T);
4127
   begin
4128
      if Ekind (Desig) = E_Incomplete_Type
4129
        and then Present (Non_Limited_View (Desig))
4130
      then
4131
         return Non_Limited_View (Desig);
4132
      else
4133
         return Desig;
4134
      end if;
4135
   end Non_Limited_Designated_Type;
4136
 
4137
   -----------------------------------
4138
   -- OK_To_Do_Constant_Replacement --
4139
   -----------------------------------
4140
 
4141
   function OK_To_Do_Constant_Replacement (E : Entity_Id) return Boolean is
4142
      ES : constant Entity_Id := Scope (E);
4143
      CS : Entity_Id;
4144
 
4145
   begin
4146
      --  Do not replace statically allocated objects, because they may be
4147
      --  modified outside the current scope.
4148
 
4149
      if Is_Statically_Allocated (E) then
4150
         return False;
4151
 
4152
      --  Do not replace aliased or volatile objects, since we don't know what
4153
      --  else might change the value.
4154
 
4155
      elsif Is_Aliased (E) or else Treat_As_Volatile (E) then
4156
         return False;
4157
 
4158
      --  Debug flag -gnatdM disconnects this optimization
4159
 
4160
      elsif Debug_Flag_MM then
4161
         return False;
4162
 
4163
      --  Otherwise check scopes
4164
 
4165
      else
4166
         CS := Current_Scope;
4167
 
4168
         loop
4169
            --  If we are in right scope, replacement is safe
4170
 
4171
            if CS = ES then
4172
               return True;
4173
 
4174
            --  Packages do not affect the determination of safety
4175
 
4176
            elsif Ekind (CS) = E_Package then
4177
               exit when CS = Standard_Standard;
4178
               CS := Scope (CS);
4179
 
4180
            --  Blocks do not affect the determination of safety
4181
 
4182
            elsif Ekind (CS) = E_Block then
4183
               CS := Scope (CS);
4184
 
4185
            --  Loops do not affect the determination of safety. Note that we
4186
            --  kill all current values on entry to a loop, so we are just
4187
            --  talking about processing within a loop here.
4188
 
4189
            elsif Ekind (CS) = E_Loop then
4190
               CS := Scope (CS);
4191
 
4192
            --  Otherwise, the reference is dubious, and we cannot be sure that
4193
            --  it is safe to do the replacement.
4194
 
4195
            else
4196
               exit;
4197
            end if;
4198
         end loop;
4199
 
4200
         return False;
4201
      end if;
4202
   end OK_To_Do_Constant_Replacement;
4203
 
4204
   ------------------------------------
4205
   -- Possible_Bit_Aligned_Component --
4206
   ------------------------------------
4207
 
4208
   function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is
4209
   begin
4210
      case Nkind (N) is
4211
 
4212
         --  Case of indexed component
4213
 
4214
         when N_Indexed_Component =>
4215
            declare
4216
               P    : constant Node_Id   := Prefix (N);
4217
               Ptyp : constant Entity_Id := Etype (P);
4218
 
4219
            begin
4220
               --  If we know the component size and it is less than 64, then
4221
               --  we are definitely OK. The back end always does assignment of
4222
               --  misaligned small objects correctly.
4223
 
4224
               if Known_Static_Component_Size (Ptyp)
4225
                 and then Component_Size (Ptyp) <= 64
4226
               then
4227
                  return False;
4228
 
4229
               --  Otherwise, we need to test the prefix, to see if we are
4230
               --  indexing from a possibly unaligned component.
4231
 
4232
               else
4233
                  return Possible_Bit_Aligned_Component (P);
4234
               end if;
4235
            end;
4236
 
4237
         --  Case of selected component
4238
 
4239
         when N_Selected_Component =>
4240
            declare
4241
               P    : constant Node_Id   := Prefix (N);
4242
               Comp : constant Entity_Id := Entity (Selector_Name (N));
4243
 
4244
            begin
4245
               --  If there is no component clause, then we are in the clear
4246
               --  since the back end will never misalign a large component
4247
               --  unless it is forced to do so. In the clear means we need
4248
               --  only the recursive test on the prefix.
4249
 
4250
               if Component_May_Be_Bit_Aligned (Comp) then
4251
                  return True;
4252
               else
4253
                  return Possible_Bit_Aligned_Component (P);
4254
               end if;
4255
            end;
4256
 
4257
         --  For a slice, test the prefix, if that is possibly misaligned,
4258
         --  then for sure the slice is!
4259
 
4260
         when N_Slice =>
4261
            return Possible_Bit_Aligned_Component (Prefix (N));
4262
 
4263
         --  If we have none of the above, it means that we have fallen off the
4264
         --  top testing prefixes recursively, and we now have a stand alone
4265
         --  object, where we don't have a problem.
4266
 
4267
         when others =>
4268
            return False;
4269
 
4270
      end case;
4271
   end Possible_Bit_Aligned_Component;
4272
 
4273
   -------------------------
4274
   -- Remove_Side_Effects --
4275
   -------------------------
4276
 
4277
   procedure Remove_Side_Effects
4278
     (Exp          : Node_Id;
4279
      Name_Req     : Boolean := False;
4280
      Variable_Ref : Boolean := False)
4281
   is
4282
      Loc          : constant Source_Ptr     := Sloc (Exp);
4283
      Exp_Type     : constant Entity_Id      := Etype (Exp);
4284
      Svg_Suppress : constant Suppress_Array := Scope_Suppress;
4285
      Def_Id       : Entity_Id;
4286
      Ref_Type     : Entity_Id;
4287
      Res          : Node_Id;
4288
      Ptr_Typ_Decl : Node_Id;
4289
      New_Exp      : Node_Id;
4290
      E            : Node_Id;
4291
 
4292
      function Side_Effect_Free (N : Node_Id) return Boolean;
4293
      --  Determines if the tree N represents an expression that is known not
4294
      --  to have side effects, and for which no processing is required.
4295
 
4296
      function Side_Effect_Free (L : List_Id) return Boolean;
4297
      --  Determines if all elements of the list L are side effect free
4298
 
4299
      function Safe_Prefixed_Reference (N : Node_Id) return Boolean;
4300
      --  The argument N is a construct where the Prefix is dereferenced if it
4301
      --  is an access type and the result is a variable. The call returns True
4302
      --  if the construct is side effect free (not considering side effects in
4303
      --  other than the prefix which are to be tested by the caller).
4304
 
4305
      function Within_In_Parameter (N : Node_Id) return Boolean;
4306
      --  Determines if N is a subcomponent of a composite in-parameter. If so,
4307
      --  N is not side-effect free when the actual is global and modifiable
4308
      --  indirectly from within a subprogram, because it may be passed by
4309
      --  reference. The front-end must be conservative here and assume that
4310
      --  this may happen with any array or record type. On the other hand, we
4311
      --  cannot create temporaries for all expressions for which this
4312
      --  condition is true, for various reasons that might require clearing up
4313
      --  ??? For example, discriminant references that appear out of place, or
4314
      --  spurious type errors with class-wide expressions. As a result, we
4315
      --  limit the transformation to loop bounds, which is so far the only
4316
      --  case that requires it.
4317
 
4318
      -----------------------------
4319
      -- Safe_Prefixed_Reference --
4320
      -----------------------------
4321
 
4322
      function Safe_Prefixed_Reference (N : Node_Id) return Boolean is
4323
      begin
4324
         --  If prefix is not side effect free, definitely not safe
4325
 
4326
         if not Side_Effect_Free (Prefix (N)) then
4327
            return False;
4328
 
4329
         --  If the prefix is of an access type that is not access-to-constant,
4330
         --  then this construct is a variable reference, which means it is to
4331
         --  be considered to have side effects if Variable_Ref is set True
4332
         --  Exception is an access to an entity that is a constant or an
4333
         --  in-parameter which does not come from source, and is the result
4334
         --  of a previous removal of side-effects.
4335
 
4336
         elsif Is_Access_Type (Etype (Prefix (N)))
4337
           and then not Is_Access_Constant (Etype (Prefix (N)))
4338
           and then Variable_Ref
4339
         then
4340
            if not Is_Entity_Name (Prefix (N)) then
4341
               return False;
4342
            else
4343
               return Ekind (Entity (Prefix (N))) = E_Constant
4344
                 or else Ekind (Entity (Prefix (N))) = E_In_Parameter;
4345
            end if;
4346
 
4347
         --  The following test is the simplest way of solving a complex
4348
         --  problem uncovered by BB08-010: Side effect on loop bound that
4349
         --  is a subcomponent of a global variable:
4350
         --    If a loop bound is a subcomponent of a global variable, a
4351
         --    modification of that variable within the loop may incorrectly
4352
         --    affect the execution of the loop.
4353
 
4354
         elsif not
4355
           (Nkind (Parent (Parent (N))) /= N_Loop_Parameter_Specification
4356
              or else not Within_In_Parameter (Prefix (N)))
4357
         then
4358
            return False;
4359
 
4360
         --  All other cases are side effect free
4361
 
4362
         else
4363
            return True;
4364
         end if;
4365
      end Safe_Prefixed_Reference;
4366
 
4367
      ----------------------
4368
      -- Side_Effect_Free --
4369
      ----------------------
4370
 
4371
      function Side_Effect_Free (N : Node_Id) return Boolean is
4372
      begin
4373
         --  Note on checks that could raise Constraint_Error. Strictly, if
4374
         --  we take advantage of 11.6, these checks do not count as side
4375
         --  effects. However, we would just as soon consider that they are
4376
         --  side effects, since the backend CSE does not work very well on
4377
         --  expressions which can raise Constraint_Error. On the other
4378
         --  hand, if we do not consider them to be side effect free, then
4379
         --  we get some awkward expansions in -gnato mode, resulting in
4380
         --  code insertions at a point where we do not have a clear model
4381
         --  for performing the insertions.
4382
 
4383
         --  Special handling for entity names
4384
 
4385
         if Is_Entity_Name (N) then
4386
 
4387
            --  If the entity is a constant, it is definitely side effect
4388
            --  free. Note that the test of Is_Variable (N) below might
4389
            --  be expected to catch this case, but it does not, because
4390
            --  this test goes to the original tree, and we may have
4391
            --  already rewritten a variable node with a constant as
4392
            --  a result of an earlier Force_Evaluation call.
4393
 
4394
            if Ekind (Entity (N)) = E_Constant
4395
              or else Ekind (Entity (N)) = E_In_Parameter
4396
            then
4397
               return True;
4398
 
4399
            --  Functions are not side effect free
4400
 
4401
            elsif Ekind (Entity (N)) = E_Function then
4402
               return False;
4403
 
4404
            --  Variables are considered to be a side effect if Variable_Ref
4405
            --  is set or if we have a volatile reference and Name_Req is off.
4406
            --  If Name_Req is True then we can't help returning a name which
4407
            --  effectively allows multiple references in any case.
4408
 
4409
            elsif Is_Variable (N) then
4410
               return not Variable_Ref
4411
                 and then (not Is_Volatile_Reference (N) or else Name_Req);
4412
 
4413
            --  Any other entity (e.g. a subtype name) is definitely side
4414
            --  effect free.
4415
 
4416
            else
4417
               return True;
4418
            end if;
4419
 
4420
         --  A value known at compile time is always side effect free
4421
 
4422
         elsif Compile_Time_Known_Value (N) then
4423
            return True;
4424
 
4425
         --  A variable renaming is not side-effect free, because the
4426
         --  renaming will function like a macro in the front-end in
4427
         --  some cases, and an assignment can modify the component
4428
         --  designated by N, so we need to create a temporary for it.
4429
 
4430
         elsif Is_Entity_Name (Original_Node (N))
4431
           and then Is_Renaming_Of_Object (Entity (Original_Node (N)))
4432
           and then Ekind (Entity (Original_Node (N))) /= E_Constant
4433
         then
4434
            return False;
4435
         end if;
4436
 
4437
         --  For other than entity names and compile time known values,
4438
         --  check the node kind for special processing.
4439
 
4440
         case Nkind (N) is
4441
 
4442
            --  An attribute reference is side effect free if its expressions
4443
            --  are side effect free and its prefix is side effect free or
4444
            --  is an entity reference.
4445
 
4446
            --  Is this right? what about x'first where x is a variable???
4447
 
4448
            when N_Attribute_Reference =>
4449
               return Side_Effect_Free (Expressions (N))
4450
                 and then Attribute_Name (N) /= Name_Input
4451
                 and then (Is_Entity_Name (Prefix (N))
4452
                            or else Side_Effect_Free (Prefix (N)));
4453
 
4454
            --  A binary operator is side effect free if and both operands
4455
            --  are side effect free. For this purpose binary operators
4456
            --  include membership tests and short circuit forms
4457
 
4458
            when N_Binary_Op | N_Membership_Test | N_Short_Circuit =>
4459
               return Side_Effect_Free (Left_Opnd  (N))
4460
                        and then
4461
                      Side_Effect_Free (Right_Opnd (N));
4462
 
4463
            --  An explicit dereference is side effect free only if it is
4464
            --  a side effect free prefixed reference.
4465
 
4466
            when N_Explicit_Dereference =>
4467
               return Safe_Prefixed_Reference (N);
4468
 
4469
            --  A call to _rep_to_pos is side effect free, since we generate
4470
            --  this pure function call ourselves. Moreover it is critically
4471
            --  important to make this exception, since otherwise we can
4472
            --  have discriminants in array components which don't look
4473
            --  side effect free in the case of an array whose index type
4474
            --  is an enumeration type with an enumeration rep clause.
4475
 
4476
            --  All other function calls are not side effect free
4477
 
4478
            when N_Function_Call =>
4479
               return Nkind (Name (N)) = N_Identifier
4480
                 and then Is_TSS (Name (N), TSS_Rep_To_Pos)
4481
                 and then
4482
                   Side_Effect_Free (First (Parameter_Associations (N)));
4483
 
4484
            --  An indexed component is side effect free if it is a side
4485
            --  effect free prefixed reference and all the indexing
4486
            --  expressions are side effect free.
4487
 
4488
            when N_Indexed_Component =>
4489
               return Side_Effect_Free (Expressions (N))
4490
                 and then Safe_Prefixed_Reference (N);
4491
 
4492
            --  A type qualification is side effect free if the expression
4493
            --  is side effect free.
4494
 
4495
            when N_Qualified_Expression =>
4496
               return Side_Effect_Free (Expression (N));
4497
 
4498
            --  A selected component is side effect free only if it is a
4499
            --  side effect free prefixed reference. If it designates a
4500
            --  component with a rep. clause it must be treated has having
4501
            --  a potential side effect, because it may be modified through
4502
            --  a renaming, and a subsequent use of the renaming as a macro
4503
            --  will yield the wrong value. This complex interaction between
4504
            --  renaming and removing side effects is a reminder that the
4505
            --  latter has become a headache to maintain, and that it should
4506
            --  be removed in favor of the gcc mechanism to capture values ???
4507
 
4508
            when N_Selected_Component =>
4509
               if Nkind (Parent (N)) = N_Explicit_Dereference
4510
                 and then Has_Non_Standard_Rep (Designated_Type (Etype (N)))
4511
               then
4512
                  return False;
4513
               else
4514
                  return Safe_Prefixed_Reference (N);
4515
               end if;
4516
 
4517
            --  A range is side effect free if the bounds are side effect free
4518
 
4519
            when N_Range =>
4520
               return Side_Effect_Free (Low_Bound (N))
4521
                 and then Side_Effect_Free (High_Bound (N));
4522
 
4523
            --  A slice is side effect free if it is a side effect free
4524
            --  prefixed reference and the bounds are side effect free.
4525
 
4526
            when N_Slice =>
4527
               return Side_Effect_Free (Discrete_Range (N))
4528
                 and then Safe_Prefixed_Reference (N);
4529
 
4530
            --  A type conversion is side effect free if the expression to be
4531
            --  converted is side effect free.
4532
 
4533
            when N_Type_Conversion =>
4534
               return Side_Effect_Free (Expression (N));
4535
 
4536
            --  A unary operator is side effect free if the operand
4537
            --  is side effect free.
4538
 
4539
            when N_Unary_Op =>
4540
               return Side_Effect_Free (Right_Opnd (N));
4541
 
4542
            --  An unchecked type conversion is side effect free only if it
4543
            --  is safe and its argument is side effect free.
4544
 
4545
            when N_Unchecked_Type_Conversion =>
4546
               return Safe_Unchecked_Type_Conversion (N)
4547
                 and then Side_Effect_Free (Expression (N));
4548
 
4549
            --  An unchecked expression is side effect free if its expression
4550
            --  is side effect free.
4551
 
4552
            when N_Unchecked_Expression =>
4553
               return Side_Effect_Free (Expression (N));
4554
 
4555
            --  A literal is side effect free
4556
 
4557
            when N_Character_Literal    |
4558
                 N_Integer_Literal      |
4559
                 N_Real_Literal         |
4560
                 N_String_Literal       =>
4561
               return True;
4562
 
4563
            --  We consider that anything else has side effects. This is a bit
4564
            --  crude, but we are pretty close for most common cases, and we
4565
            --  are certainly correct (i.e. we never return True when the
4566
            --  answer should be False).
4567
 
4568
            when others =>
4569
               return False;
4570
         end case;
4571
      end Side_Effect_Free;
4572
 
4573
      --  A list is side effect free if all elements of the list are
4574
      --  side effect free.
4575
 
4576
      function Side_Effect_Free (L : List_Id) return Boolean is
4577
         N : Node_Id;
4578
 
4579
      begin
4580
         if L = No_List or else L = Error_List then
4581
            return True;
4582
 
4583
         else
4584
            N := First (L);
4585
            while Present (N) loop
4586
               if not Side_Effect_Free (N) then
4587
                  return False;
4588
               else
4589
                  Next (N);
4590
               end if;
4591
            end loop;
4592
 
4593
            return True;
4594
         end if;
4595
      end Side_Effect_Free;
4596
 
4597
      -------------------------
4598
      -- Within_In_Parameter --
4599
      -------------------------
4600
 
4601
      function Within_In_Parameter (N : Node_Id) return Boolean is
4602
      begin
4603
         if not Comes_From_Source (N) then
4604
            return False;
4605
 
4606
         elsif Is_Entity_Name (N) then
4607
            return Ekind (Entity (N)) = E_In_Parameter;
4608
 
4609
         elsif Nkind (N) = N_Indexed_Component
4610
           or else Nkind (N) = N_Selected_Component
4611
         then
4612
            return Within_In_Parameter (Prefix (N));
4613
         else
4614
 
4615
            return False;
4616
         end if;
4617
      end Within_In_Parameter;
4618
 
4619
   --  Start of processing for Remove_Side_Effects
4620
 
4621
   begin
4622
      --  If we are side effect free already or expansion is disabled,
4623
      --  there is nothing to do.
4624
 
4625
      if Side_Effect_Free (Exp) or else not Expander_Active then
4626
         return;
4627
      end if;
4628
 
4629
      --  All this must not have any checks
4630
 
4631
      Scope_Suppress := (others => True);
4632
 
4633
      --  If it is a scalar type and we need to capture the value, just make
4634
      --  a copy. Likewise for a function call, an attribute reference or an
4635
      --  operator. And if we have a volatile reference and Name_Req is not
4636
      --  set (see comments above for Side_Effect_Free).
4637
 
4638
      if Is_Elementary_Type (Exp_Type)
4639
        and then (Variable_Ref
4640
                   or else Nkind (Exp) = N_Function_Call
4641
                   or else Nkind (Exp) = N_Attribute_Reference
4642
                   or else Nkind (Exp) in N_Op
4643
                   or else (not Name_Req and then Is_Volatile_Reference (Exp)))
4644
      then
4645
         Def_Id := Make_Temporary (Loc, 'R', Exp);
4646
         Set_Etype (Def_Id, Exp_Type);
4647
         Res := New_Reference_To (Def_Id, Loc);
4648
 
4649
         E :=
4650
           Make_Object_Declaration (Loc,
4651
             Defining_Identifier => Def_Id,
4652
             Object_Definition   => New_Reference_To (Exp_Type, Loc),
4653
             Constant_Present    => True,
4654
             Expression          => Relocate_Node (Exp));
4655
 
4656
         --  Check if the previous node relocation requires readjustment of
4657
         --  some SCIL Dispatching node.
4658
 
4659
         if Generate_SCIL
4660
           and then Nkind (Exp) = N_Function_Call
4661
         then
4662
            Adjust_SCIL_Node (Exp, Expression (E));
4663
         end if;
4664
 
4665
         Set_Assignment_OK (E);
4666
         Insert_Action (Exp, E);
4667
 
4668
      --  If the expression has the form v.all then we can just capture
4669
      --  the pointer, and then do an explicit dereference on the result.
4670
 
4671
      elsif Nkind (Exp) = N_Explicit_Dereference then
4672
         Def_Id := Make_Temporary (Loc, 'R', Exp);
4673
         Res :=
4674
           Make_Explicit_Dereference (Loc, New_Reference_To (Def_Id, Loc));
4675
 
4676
         Insert_Action (Exp,
4677
           Make_Object_Declaration (Loc,
4678
             Defining_Identifier => Def_Id,
4679
             Object_Definition   =>
4680
               New_Reference_To (Etype (Prefix (Exp)), Loc),
4681
             Constant_Present    => True,
4682
             Expression          => Relocate_Node (Prefix (Exp))));
4683
 
4684
      --  Similar processing for an unchecked conversion of an expression
4685
      --  of the form v.all, where we want the same kind of treatment.
4686
 
4687
      elsif Nkind (Exp) = N_Unchecked_Type_Conversion
4688
        and then Nkind (Expression (Exp)) = N_Explicit_Dereference
4689
      then
4690
         Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
4691
         Scope_Suppress := Svg_Suppress;
4692
         return;
4693
 
4694
      --  If this is a type conversion, leave the type conversion and remove
4695
      --  the side effects in the expression. This is important in several
4696
      --  circumstances: for change of representations, and also when this is
4697
      --  a view conversion to a smaller object, where gigi can end up creating
4698
      --  its own temporary of the wrong size.
4699
 
4700
      elsif Nkind (Exp) = N_Type_Conversion then
4701
         Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
4702
         Scope_Suppress := Svg_Suppress;
4703
         return;
4704
 
4705
      --  If this is an unchecked conversion that Gigi can't handle, make
4706
      --  a copy or a use a renaming to capture the value.
4707
 
4708
      elsif Nkind (Exp) = N_Unchecked_Type_Conversion
4709
        and then not Safe_Unchecked_Type_Conversion (Exp)
4710
      then
4711
         if CW_Or_Has_Controlled_Part (Exp_Type) then
4712
 
4713
            --  Use a renaming to capture the expression, rather than create
4714
            --  a controlled temporary.
4715
 
4716
            Def_Id := Make_Temporary (Loc, 'R', Exp);
4717
            Res := New_Reference_To (Def_Id, Loc);
4718
 
4719
            Insert_Action (Exp,
4720
              Make_Object_Renaming_Declaration (Loc,
4721
                Defining_Identifier => Def_Id,
4722
                Subtype_Mark        => New_Reference_To (Exp_Type, Loc),
4723
                Name                => Relocate_Node (Exp)));
4724
 
4725
         else
4726
            Def_Id := Make_Temporary (Loc, 'R', Exp);
4727
            Set_Etype (Def_Id, Exp_Type);
4728
            Res := New_Reference_To (Def_Id, Loc);
4729
 
4730
            E :=
4731
              Make_Object_Declaration (Loc,
4732
                Defining_Identifier => Def_Id,
4733
                Object_Definition   => New_Reference_To (Exp_Type, Loc),
4734
                Constant_Present    => not Is_Variable (Exp),
4735
                Expression          => Relocate_Node (Exp));
4736
 
4737
            Set_Assignment_OK (E);
4738
            Insert_Action (Exp, E);
4739
         end if;
4740
 
4741
      --  For expressions that denote objects, we can use a renaming scheme.
4742
      --  We skip using this if we have a volatile reference and we do not
4743
      --  have Name_Req set true (see comments above for Side_Effect_Free).
4744
 
4745
      elsif Is_Object_Reference (Exp)
4746
        and then Nkind (Exp) /= N_Function_Call
4747
        and then (Name_Req or else not Is_Volatile_Reference (Exp))
4748
      then
4749
         Def_Id := Make_Temporary (Loc, 'R', Exp);
4750
 
4751
         if Nkind (Exp) = N_Selected_Component
4752
           and then Nkind (Prefix (Exp)) = N_Function_Call
4753
           and then Is_Array_Type (Exp_Type)
4754
         then
4755
            --  Avoid generating a variable-sized temporary, by generating
4756
            --  the renaming declaration just for the function call. The
4757
            --  transformation could be refined to apply only when the array
4758
            --  component is constrained by a discriminant???
4759
 
4760
            Res :=
4761
              Make_Selected_Component (Loc,
4762
                Prefix => New_Occurrence_Of (Def_Id, Loc),
4763
                Selector_Name => Selector_Name (Exp));
4764
 
4765
            Insert_Action (Exp,
4766
              Make_Object_Renaming_Declaration (Loc,
4767
                Defining_Identifier => Def_Id,
4768
                Subtype_Mark        =>
4769
                  New_Reference_To (Base_Type (Etype (Prefix (Exp))), Loc),
4770
                Name                => Relocate_Node (Prefix (Exp))));
4771
 
4772
         else
4773
            Res := New_Reference_To (Def_Id, Loc);
4774
 
4775
            Insert_Action (Exp,
4776
              Make_Object_Renaming_Declaration (Loc,
4777
                Defining_Identifier => Def_Id,
4778
                Subtype_Mark        => New_Reference_To (Exp_Type, Loc),
4779
                Name                => Relocate_Node (Exp)));
4780
         end if;
4781
 
4782
         --  If this is a packed reference, or a selected component with a
4783
         --  non-standard representation, a reference to the temporary will
4784
         --  be replaced by a copy of the original expression (see
4785
         --  Exp_Ch2.Expand_Renaming). Otherwise the temporary must be
4786
         --  elaborated by gigi, and is of course not to be replaced in-line
4787
         --  by the expression it renames, which would defeat the purpose of
4788
         --  removing the side-effect.
4789
 
4790
         if (Nkind (Exp) = N_Selected_Component
4791
              or else Nkind (Exp) = N_Indexed_Component)
4792
           and then Has_Non_Standard_Rep (Etype (Prefix (Exp)))
4793
         then
4794
            null;
4795
         else
4796
            Set_Is_Renaming_Of_Object (Def_Id, False);
4797
         end if;
4798
 
4799
      --  Otherwise we generate a reference to the value
4800
 
4801
      else
4802
         --  Special processing for function calls that return a limited type.
4803
         --  We need to build a declaration that will enable build-in-place
4804
         --  expansion of the call. This is not done if the context is already
4805
         --  an object declaration, to prevent infinite recursion.
4806
 
4807
         --  This is relevant only in Ada 2005 mode. In Ada 95 programs we have
4808
         --  to accommodate functions returning limited objects by reference.
4809
 
4810
         if Nkind (Exp) = N_Function_Call
4811
           and then Is_Inherently_Limited_Type (Etype (Exp))
4812
           and then Nkind (Parent (Exp)) /= N_Object_Declaration
4813
           and then Ada_Version >= Ada_05
4814
         then
4815
            declare
4816
               Obj  : constant Entity_Id := Make_Temporary (Loc, 'F', Exp);
4817
               Decl : Node_Id;
4818
 
4819
            begin
4820
               Decl :=
4821
                 Make_Object_Declaration (Loc,
4822
                   Defining_Identifier => Obj,
4823
                   Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
4824
                   Expression          => Relocate_Node (Exp));
4825
 
4826
               --  Check if the previous node relocation requires readjustment
4827
               --  of some SCIL Dispatching node.
4828
 
4829
               if Generate_SCIL
4830
                 and then Nkind (Exp) = N_Function_Call
4831
               then
4832
                  Adjust_SCIL_Node (Exp, Expression (Decl));
4833
               end if;
4834
 
4835
               Insert_Action (Exp, Decl);
4836
               Set_Etype (Obj, Exp_Type);
4837
               Rewrite (Exp, New_Occurrence_Of (Obj, Loc));
4838
               return;
4839
            end;
4840
         end if;
4841
 
4842
         Ref_Type := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
4843
 
4844
         Ptr_Typ_Decl :=
4845
           Make_Full_Type_Declaration (Loc,
4846
             Defining_Identifier => Ref_Type,
4847
             Type_Definition =>
4848
               Make_Access_To_Object_Definition (Loc,
4849
                 All_Present => True,
4850
                 Subtype_Indication =>
4851
                   New_Reference_To (Exp_Type, Loc)));
4852
 
4853
         E := Exp;
4854
         Insert_Action (Exp, Ptr_Typ_Decl);
4855
 
4856
         Def_Id := Make_Temporary (Loc, 'R', Exp);
4857
         Set_Etype (Def_Id, Exp_Type);
4858
 
4859
         Res :=
4860
           Make_Explicit_Dereference (Loc,
4861
             Prefix => New_Reference_To (Def_Id, Loc));
4862
 
4863
         if Nkind (E) = N_Explicit_Dereference then
4864
            New_Exp := Relocate_Node (Prefix (E));
4865
         else
4866
            E := Relocate_Node (E);
4867
            New_Exp := Make_Reference (Loc, E);
4868
         end if;
4869
 
4870
         if Is_Delayed_Aggregate (E) then
4871
 
4872
            --  The expansion of nested aggregates is delayed until the
4873
            --  enclosing aggregate is expanded. As aggregates are often
4874
            --  qualified, the predicate applies to qualified expressions
4875
            --  as well, indicating that the enclosing aggregate has not
4876
            --  been expanded yet. At this point the aggregate is part of
4877
            --  a stand-alone declaration, and must be fully expanded.
4878
 
4879
            if Nkind (E) = N_Qualified_Expression then
4880
               Set_Expansion_Delayed (Expression (E), False);
4881
               Set_Analyzed (Expression (E), False);
4882
            else
4883
               Set_Expansion_Delayed (E, False);
4884
            end if;
4885
 
4886
            Set_Analyzed (E, False);
4887
         end if;
4888
 
4889
         Insert_Action (Exp,
4890
           Make_Object_Declaration (Loc,
4891
             Defining_Identifier => Def_Id,
4892
             Object_Definition   => New_Reference_To (Ref_Type, Loc),
4893
             Expression          => New_Exp));
4894
 
4895
         --  Check if the previous node relocation requires readjustment
4896
         --  of some SCIL Dispatching node.
4897
 
4898
         if Generate_SCIL
4899
           and then Nkind (Exp) = N_Function_Call
4900
         then
4901
            Adjust_SCIL_Node (Exp, Prefix (New_Exp));
4902
         end if;
4903
      end if;
4904
 
4905
      --  Preserve the Assignment_OK flag in all copies, since at least
4906
      --  one copy may be used in a context where this flag must be set
4907
      --  (otherwise why would the flag be set in the first place).
4908
 
4909
      Set_Assignment_OK (Res, Assignment_OK (Exp));
4910
 
4911
      --  Finally rewrite the original expression and we are done
4912
 
4913
      Rewrite (Exp, Res);
4914
      Analyze_And_Resolve (Exp, Exp_Type);
4915
      Scope_Suppress := Svg_Suppress;
4916
   end Remove_Side_Effects;
4917
 
4918
   ---------------------------
4919
   -- Represented_As_Scalar --
4920
   ---------------------------
4921
 
4922
   function Represented_As_Scalar (T : Entity_Id) return Boolean is
4923
      UT : constant Entity_Id := Underlying_Type (T);
4924
   begin
4925
      return Is_Scalar_Type (UT)
4926
        or else (Is_Bit_Packed_Array (UT)
4927
                   and then Is_Scalar_Type (Packed_Array_Type (UT)));
4928
   end Represented_As_Scalar;
4929
 
4930
   ------------------------------------
4931
   -- Safe_Unchecked_Type_Conversion --
4932
   ------------------------------------
4933
 
4934
   --  Note: this function knows quite a bit about the exact requirements
4935
   --  of Gigi with respect to unchecked type conversions, and its code
4936
   --  must be coordinated with any changes in Gigi in this area.
4937
 
4938
   --  The above requirements should be documented in Sinfo ???
4939
 
4940
   function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is
4941
      Otyp   : Entity_Id;
4942
      Ityp   : Entity_Id;
4943
      Oalign : Uint;
4944
      Ialign : Uint;
4945
      Pexp   : constant Node_Id := Parent (Exp);
4946
 
4947
   begin
4948
      --  If the expression is the RHS of an assignment or object declaration
4949
      --   we are always OK because there will always be a target.
4950
 
4951
      --  Object renaming declarations, (generated for view conversions of
4952
      --  actuals in inlined calls), like object declarations, provide an
4953
      --  explicit type, and are safe as well.
4954
 
4955
      if (Nkind (Pexp) = N_Assignment_Statement
4956
           and then Expression (Pexp) = Exp)
4957
        or else Nkind (Pexp) = N_Object_Declaration
4958
        or else Nkind (Pexp) = N_Object_Renaming_Declaration
4959
      then
4960
         return True;
4961
 
4962
      --  If the expression is the prefix of an N_Selected_Component
4963
      --  we should also be OK because GCC knows to look inside the
4964
      --  conversion except if the type is discriminated. We assume
4965
      --  that we are OK anyway if the type is not set yet or if it is
4966
      --  controlled since we can't afford to introduce a temporary in
4967
      --  this case.
4968
 
4969
      elsif Nkind (Pexp) = N_Selected_Component
4970
         and then Prefix (Pexp) = Exp
4971
      then
4972
         if No (Etype (Pexp)) then
4973
            return True;
4974
         else
4975
            return
4976
              not Has_Discriminants (Etype (Pexp))
4977
                or else Is_Constrained (Etype (Pexp));
4978
         end if;
4979
      end if;
4980
 
4981
      --  Set the output type, this comes from Etype if it is set, otherwise
4982
      --  we take it from the subtype mark, which we assume was already
4983
      --  fully analyzed.
4984
 
4985
      if Present (Etype (Exp)) then
4986
         Otyp := Etype (Exp);
4987
      else
4988
         Otyp := Entity (Subtype_Mark (Exp));
4989
      end if;
4990
 
4991
      --  The input type always comes from the expression, and we assume
4992
      --  this is indeed always analyzed, so we can simply get the Etype.
4993
 
4994
      Ityp := Etype (Expression (Exp));
4995
 
4996
      --  Initialize alignments to unknown so far
4997
 
4998
      Oalign := No_Uint;
4999
      Ialign := No_Uint;
5000
 
5001
      --  Replace a concurrent type by its corresponding record type
5002
      --  and each type by its underlying type and do the tests on those.
5003
      --  The original type may be a private type whose completion is a
5004
      --  concurrent type, so find the underlying type first.
5005
 
5006
      if Present (Underlying_Type (Otyp)) then
5007
         Otyp := Underlying_Type (Otyp);
5008
      end if;
5009
 
5010
      if Present (Underlying_Type (Ityp)) then
5011
         Ityp := Underlying_Type (Ityp);
5012
      end if;
5013
 
5014
      if Is_Concurrent_Type (Otyp) then
5015
         Otyp := Corresponding_Record_Type (Otyp);
5016
      end if;
5017
 
5018
      if Is_Concurrent_Type (Ityp) then
5019
         Ityp := Corresponding_Record_Type (Ityp);
5020
      end if;
5021
 
5022
      --  If the base types are the same, we know there is no problem since
5023
      --  this conversion will be a noop.
5024
 
5025
      if Implementation_Base_Type (Otyp) = Implementation_Base_Type (Ityp) then
5026
         return True;
5027
 
5028
      --  Same if this is an upwards conversion of an untagged type, and there
5029
      --  are no constraints involved (could be more general???)
5030
 
5031
      elsif Etype (Ityp) = Otyp
5032
        and then not Is_Tagged_Type (Ityp)
5033
        and then not Has_Discriminants (Ityp)
5034
        and then No (First_Rep_Item (Base_Type (Ityp)))
5035
      then
5036
         return True;
5037
 
5038
      --  If the expression has an access type (object or subprogram) we
5039
      --  assume that the conversion is safe, because the size of the target
5040
      --  is safe, even if it is a record (which might be treated as having
5041
      --  unknown size at this point).
5042
 
5043
      elsif Is_Access_Type (Ityp) then
5044
         return True;
5045
 
5046
      --  If the size of output type is known at compile time, there is
5047
      --  never a problem.  Note that unconstrained records are considered
5048
      --  to be of known size, but we can't consider them that way here,
5049
      --  because we are talking about the actual size of the object.
5050
 
5051
      --  We also make sure that in addition to the size being known, we do
5052
      --  not have a case which might generate an embarrassingly large temp
5053
      --  in stack checking mode.
5054
 
5055
      elsif Size_Known_At_Compile_Time (Otyp)
5056
        and then
5057
          (not Stack_Checking_Enabled
5058
             or else not May_Generate_Large_Temp (Otyp))
5059
        and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp))
5060
      then
5061
         return True;
5062
 
5063
      --  If either type is tagged, then we know the alignment is OK so
5064
      --  Gigi will be able to use pointer punning.
5065
 
5066
      elsif Is_Tagged_Type (Otyp) or else Is_Tagged_Type (Ityp) then
5067
         return True;
5068
 
5069
      --  If either type is a limited record type, we cannot do a copy, so
5070
      --  say safe since there's nothing else we can do.
5071
 
5072
      elsif Is_Limited_Record (Otyp) or else Is_Limited_Record (Ityp) then
5073
         return True;
5074
 
5075
      --  Conversions to and from packed array types are always ignored and
5076
      --  hence are safe.
5077
 
5078
      elsif Is_Packed_Array_Type (Otyp)
5079
        or else Is_Packed_Array_Type (Ityp)
5080
      then
5081
         return True;
5082
      end if;
5083
 
5084
      --  The only other cases known to be safe is if the input type's
5085
      --  alignment is known to be at least the maximum alignment for the
5086
      --  target or if both alignments are known and the output type's
5087
      --  alignment is no stricter than the input's.  We can use the alignment
5088
      --  of the component type of an array if a type is an unpacked
5089
      --  array type.
5090
 
5091
      if Present (Alignment_Clause (Otyp)) then
5092
         Oalign := Expr_Value (Expression (Alignment_Clause (Otyp)));
5093
 
5094
      elsif Is_Array_Type (Otyp)
5095
        and then Present (Alignment_Clause (Component_Type (Otyp)))
5096
      then
5097
         Oalign := Expr_Value (Expression (Alignment_Clause
5098
                                           (Component_Type (Otyp))));
5099
      end if;
5100
 
5101
      if Present (Alignment_Clause (Ityp)) then
5102
         Ialign := Expr_Value (Expression (Alignment_Clause (Ityp)));
5103
 
5104
      elsif Is_Array_Type (Ityp)
5105
        and then Present (Alignment_Clause (Component_Type (Ityp)))
5106
      then
5107
         Ialign := Expr_Value (Expression (Alignment_Clause
5108
                                           (Component_Type (Ityp))));
5109
      end if;
5110
 
5111
      if Ialign /= No_Uint and then Ialign > Maximum_Alignment then
5112
         return True;
5113
 
5114
      elsif Ialign /= No_Uint and then Oalign /= No_Uint
5115
        and then Ialign <= Oalign
5116
      then
5117
         return True;
5118
 
5119
      --   Otherwise, Gigi cannot handle this and we must make a temporary
5120
 
5121
      else
5122
         return False;
5123
      end if;
5124
   end Safe_Unchecked_Type_Conversion;
5125
 
5126
   ---------------------------------
5127
   -- Set_Current_Value_Condition --
5128
   ---------------------------------
5129
 
5130
   --  Note: the implementation of this procedure is very closely tied to the
5131
   --  implementation of Get_Current_Value_Condition. Here we set required
5132
   --  Current_Value fields, and in Get_Current_Value_Condition, we interpret
5133
   --  them, so they must have a consistent view.
5134
 
5135
   procedure Set_Current_Value_Condition (Cnode : Node_Id) is
5136
 
5137
      procedure Set_Entity_Current_Value (N : Node_Id);
5138
      --  If N is an entity reference, where the entity is of an appropriate
5139
      --  kind, then set the current value of this entity to Cnode, unless
5140
      --  there is already a definite value set there.
5141
 
5142
      procedure Set_Expression_Current_Value (N : Node_Id);
5143
      --  If N is of an appropriate form, sets an appropriate entry in current
5144
      --  value fields of relevant entities. Multiple entities can be affected
5145
      --  in the case of an AND or AND THEN.
5146
 
5147
      ------------------------------
5148
      -- Set_Entity_Current_Value --
5149
      ------------------------------
5150
 
5151
      procedure Set_Entity_Current_Value (N : Node_Id) is
5152
      begin
5153
         if Is_Entity_Name (N) then
5154
            declare
5155
               Ent : constant Entity_Id := Entity (N);
5156
 
5157
            begin
5158
               --  Don't capture if not safe to do so
5159
 
5160
               if not Safe_To_Capture_Value (N, Ent, Cond => True) then
5161
                  return;
5162
               end if;
5163
 
5164
               --  Here we have a case where the Current_Value field may
5165
               --  need to be set. We set it if it is not already set to a
5166
               --  compile time expression value.
5167
 
5168
               --  Note that this represents a decision that one condition
5169
               --  blots out another previous one. That's certainly right
5170
               --  if they occur at the same level. If the second one is
5171
               --  nested, then the decision is neither right nor wrong (it
5172
               --  would be equally OK to leave the outer one in place, or
5173
               --  take the new inner one. Really we should record both, but
5174
               --  our data structures are not that elaborate.
5175
 
5176
               if Nkind (Current_Value (Ent)) not in N_Subexpr then
5177
                  Set_Current_Value (Ent, Cnode);
5178
               end if;
5179
            end;
5180
         end if;
5181
      end Set_Entity_Current_Value;
5182
 
5183
      ----------------------------------
5184
      -- Set_Expression_Current_Value --
5185
      ----------------------------------
5186
 
5187
      procedure Set_Expression_Current_Value (N : Node_Id) is
5188
         Cond : Node_Id;
5189
 
5190
      begin
5191
         Cond := N;
5192
 
5193
         --  Loop to deal with (ignore for now) any NOT operators present. The
5194
         --  presence of NOT operators will be handled properly when we call
5195
         --  Get_Current_Value_Condition.
5196
 
5197
         while Nkind (Cond) = N_Op_Not loop
5198
            Cond := Right_Opnd (Cond);
5199
         end loop;
5200
 
5201
         --  For an AND or AND THEN, recursively process operands
5202
 
5203
         if Nkind (Cond) = N_Op_And or else Nkind (Cond) = N_And_Then then
5204
            Set_Expression_Current_Value (Left_Opnd (Cond));
5205
            Set_Expression_Current_Value (Right_Opnd (Cond));
5206
            return;
5207
         end if;
5208
 
5209
         --  Check possible relational operator
5210
 
5211
         if Nkind (Cond) in N_Op_Compare then
5212
            if Compile_Time_Known_Value (Right_Opnd (Cond)) then
5213
               Set_Entity_Current_Value (Left_Opnd (Cond));
5214
            elsif Compile_Time_Known_Value (Left_Opnd (Cond)) then
5215
               Set_Entity_Current_Value (Right_Opnd (Cond));
5216
            end if;
5217
 
5218
            --  Check possible boolean variable reference
5219
 
5220
         else
5221
            Set_Entity_Current_Value (Cond);
5222
         end if;
5223
      end Set_Expression_Current_Value;
5224
 
5225
   --  Start of processing for Set_Current_Value_Condition
5226
 
5227
   begin
5228
      Set_Expression_Current_Value (Condition (Cnode));
5229
   end Set_Current_Value_Condition;
5230
 
5231
   --------------------------
5232
   -- Set_Elaboration_Flag --
5233
   --------------------------
5234
 
5235
   procedure Set_Elaboration_Flag (N : Node_Id; Spec_Id : Entity_Id) is
5236
      Loc : constant Source_Ptr := Sloc (N);
5237
      Ent : constant Entity_Id  := Elaboration_Entity (Spec_Id);
5238
      Asn : Node_Id;
5239
 
5240
   begin
5241
      if Present (Ent) then
5242
 
5243
         --  Nothing to do if at the compilation unit level, because in this
5244
         --  case the flag is set by the binder generated elaboration routine.
5245
 
5246
         if Nkind (Parent (N)) = N_Compilation_Unit then
5247
            null;
5248
 
5249
         --  Here we do need to generate an assignment statement
5250
 
5251
         else
5252
            Check_Restriction (No_Elaboration_Code, N);
5253
            Asn :=
5254
              Make_Assignment_Statement (Loc,
5255
                Name       => New_Occurrence_Of (Ent, Loc),
5256
                Expression => New_Occurrence_Of (Standard_True, Loc));
5257
 
5258
            if Nkind (Parent (N)) = N_Subunit then
5259
               Insert_After (Corresponding_Stub (Parent (N)), Asn);
5260
            else
5261
               Insert_After (N, Asn);
5262
            end if;
5263
 
5264
            Analyze (Asn);
5265
 
5266
            --  Kill current value indication. This is necessary because the
5267
            --  tests of this flag are inserted out of sequence and must not
5268
            --  pick up bogus indications of the wrong constant value.
5269
 
5270
            Set_Current_Value (Ent, Empty);
5271
         end if;
5272
      end if;
5273
   end Set_Elaboration_Flag;
5274
 
5275
   ----------------------------
5276
   -- Set_Renamed_Subprogram --
5277
   ----------------------------
5278
 
5279
   procedure Set_Renamed_Subprogram (N : Node_Id; E : Entity_Id) is
5280
   begin
5281
      --  If input node is an identifier, we can just reset it
5282
 
5283
      if Nkind (N) = N_Identifier then
5284
         Set_Chars  (N, Chars (E));
5285
         Set_Entity (N, E);
5286
 
5287
         --  Otherwise we have to do a rewrite, preserving Comes_From_Source
5288
 
5289
      else
5290
         declare
5291
            CS : constant Boolean := Comes_From_Source (N);
5292
         begin
5293
            Rewrite (N, Make_Identifier (Sloc (N), Chars => Chars (E)));
5294
            Set_Entity (N, E);
5295
            Set_Comes_From_Source (N, CS);
5296
            Set_Analyzed (N, True);
5297
         end;
5298
      end if;
5299
   end Set_Renamed_Subprogram;
5300
 
5301
   ----------------------------------
5302
   -- Silly_Boolean_Array_Not_Test --
5303
   ----------------------------------
5304
 
5305
   --  This procedure implements an odd and silly test. We explicitly check
5306
   --  for the case where the 'First of the component type is equal to the
5307
   --  'Last of this component type, and if this is the case, we make sure
5308
   --  that constraint error is raised. The reason is that the NOT is bound
5309
   --  to cause CE in this case, and we will not otherwise catch it.
5310
 
5311
   --  No such check is required for AND and OR, since for both these cases
5312
   --  False op False = False, and True op True = True. For the XOR case,
5313
   --  see Silly_Boolean_Array_Xor_Test.
5314
 
5315
   --  Believe it or not, this was reported as a bug. Note that nearly
5316
   --  always, the test will evaluate statically to False, so the code will
5317
   --  be statically removed, and no extra overhead caused.
5318
 
5319
   procedure Silly_Boolean_Array_Not_Test (N : Node_Id; T : Entity_Id) is
5320
      Loc : constant Source_Ptr := Sloc (N);
5321
      CT  : constant Entity_Id  := Component_Type (T);
5322
 
5323
   begin
5324
      --  The check we install is
5325
 
5326
      --    constraint_error when
5327
      --      component_type'first = component_type'last
5328
      --        and then array_type'Length /= 0)
5329
 
5330
      --  We need the last guard because we don't want to raise CE for empty
5331
      --  arrays since no out of range values result. (Empty arrays with a
5332
      --  component type of True .. True -- very useful -- even the ACATS
5333
      --  does not test that marginal case!)
5334
 
5335
      Insert_Action (N,
5336
        Make_Raise_Constraint_Error (Loc,
5337
          Condition =>
5338
            Make_And_Then (Loc,
5339
              Left_Opnd =>
5340
                Make_Op_Eq (Loc,
5341
                  Left_Opnd =>
5342
                    Make_Attribute_Reference (Loc,
5343
                      Prefix         => New_Occurrence_Of (CT, Loc),
5344
                      Attribute_Name => Name_First),
5345
 
5346
                  Right_Opnd =>
5347
                    Make_Attribute_Reference (Loc,
5348
                      Prefix         => New_Occurrence_Of (CT, Loc),
5349
                      Attribute_Name => Name_Last)),
5350
 
5351
              Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
5352
          Reason => CE_Range_Check_Failed));
5353
   end Silly_Boolean_Array_Not_Test;
5354
 
5355
   ----------------------------------
5356
   -- Silly_Boolean_Array_Xor_Test --
5357
   ----------------------------------
5358
 
5359
   --  This procedure implements an odd and silly test. We explicitly check
5360
   --  for the XOR case where the component type is True .. True, since this
5361
   --  will raise constraint error. A special check is required since CE
5362
   --  will not be generated otherwise (cf Expand_Packed_Not).
5363
 
5364
   --  No such check is required for AND and OR, since for both these cases
5365
   --  False op False = False, and True op True = True, and no check is
5366
   --  required for the case of False .. False, since False xor False = False.
5367
   --  See also Silly_Boolean_Array_Not_Test
5368
 
5369
   procedure Silly_Boolean_Array_Xor_Test (N : Node_Id; T : Entity_Id) is
5370
      Loc : constant Source_Ptr := Sloc (N);
5371
      CT  : constant Entity_Id  := Component_Type (T);
5372
 
5373
   begin
5374
      --  The check we install is
5375
 
5376
      --    constraint_error when
5377
      --      Boolean (component_type'First)
5378
      --        and then Boolean (component_type'Last)
5379
      --        and then array_type'Length /= 0)
5380
 
5381
      --  We need the last guard because we don't want to raise CE for empty
5382
      --  arrays since no out of range values result (Empty arrays with a
5383
      --  component type of True .. True -- very useful -- even the ACATS
5384
      --  does not test that marginal case!).
5385
 
5386
      Insert_Action (N,
5387
        Make_Raise_Constraint_Error (Loc,
5388
          Condition =>
5389
            Make_And_Then (Loc,
5390
              Left_Opnd =>
5391
                Make_And_Then (Loc,
5392
                  Left_Opnd =>
5393
                    Convert_To (Standard_Boolean,
5394
                      Make_Attribute_Reference (Loc,
5395
                        Prefix         => New_Occurrence_Of (CT, Loc),
5396
                        Attribute_Name => Name_First)),
5397
 
5398
                  Right_Opnd =>
5399
                    Convert_To (Standard_Boolean,
5400
                      Make_Attribute_Reference (Loc,
5401
                        Prefix         => New_Occurrence_Of (CT, Loc),
5402
                        Attribute_Name => Name_Last))),
5403
 
5404
              Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
5405
          Reason => CE_Range_Check_Failed));
5406
   end Silly_Boolean_Array_Xor_Test;
5407
 
5408
   --------------------------
5409
   -- Target_Has_Fixed_Ops --
5410
   --------------------------
5411
 
5412
   Integer_Sized_Small : Ureal;
5413
   --  Set to 2.0 ** -(Integer'Size - 1) the first time that this
5414
   --  function is called (we don't want to compute it more than once!)
5415
 
5416
   Long_Integer_Sized_Small : Ureal;
5417
   --  Set to 2.0 ** -(Long_Integer'Size - 1) the first time that this
5418
   --  function is called (we don't want to compute it more than once)
5419
 
5420
   First_Time_For_THFO : Boolean := True;
5421
   --  Set to False after first call (if Fractional_Fixed_Ops_On_Target)
5422
 
5423
   function Target_Has_Fixed_Ops
5424
     (Left_Typ   : Entity_Id;
5425
      Right_Typ  : Entity_Id;
5426
      Result_Typ : Entity_Id) return Boolean
5427
   is
5428
      function Is_Fractional_Type (Typ : Entity_Id) return Boolean;
5429
      --  Return True if the given type is a fixed-point type with a small
5430
      --  value equal to 2 ** (-(T'Object_Size - 1)) and whose values have
5431
      --  an absolute value less than 1.0. This is currently limited
5432
      --  to fixed-point types that map to Integer or Long_Integer.
5433
 
5434
      ------------------------
5435
      -- Is_Fractional_Type --
5436
      ------------------------
5437
 
5438
      function Is_Fractional_Type (Typ : Entity_Id) return Boolean is
5439
      begin
5440
         if Esize (Typ) = Standard_Integer_Size then
5441
            return Small_Value (Typ) = Integer_Sized_Small;
5442
 
5443
         elsif Esize (Typ) = Standard_Long_Integer_Size then
5444
            return Small_Value (Typ) = Long_Integer_Sized_Small;
5445
 
5446
         else
5447
            return False;
5448
         end if;
5449
      end Is_Fractional_Type;
5450
 
5451
   --  Start of processing for Target_Has_Fixed_Ops
5452
 
5453
   begin
5454
      --  Return False if Fractional_Fixed_Ops_On_Target is false
5455
 
5456
      if not Fractional_Fixed_Ops_On_Target then
5457
         return False;
5458
      end if;
5459
 
5460
      --  Here the target has Fractional_Fixed_Ops, if first time, compute
5461
      --  standard constants used by Is_Fractional_Type.
5462
 
5463
      if First_Time_For_THFO then
5464
         First_Time_For_THFO := False;
5465
 
5466
         Integer_Sized_Small :=
5467
           UR_From_Components
5468
             (Num   => Uint_1,
5469
              Den   => UI_From_Int (Standard_Integer_Size - 1),
5470
              Rbase => 2);
5471
 
5472
         Long_Integer_Sized_Small :=
5473
           UR_From_Components
5474
             (Num   => Uint_1,
5475
              Den   => UI_From_Int (Standard_Long_Integer_Size - 1),
5476
              Rbase => 2);
5477
      end if;
5478
 
5479
      --  Return True if target supports fixed-by-fixed multiply/divide
5480
      --  for fractional fixed-point types (see Is_Fractional_Type) and
5481
      --  the operand and result types are equivalent fractional types.
5482
 
5483
      return Is_Fractional_Type (Base_Type (Left_Typ))
5484
        and then Is_Fractional_Type (Base_Type (Right_Typ))
5485
        and then Is_Fractional_Type (Base_Type (Result_Typ))
5486
        and then Esize (Left_Typ) = Esize (Right_Typ)
5487
        and then Esize (Left_Typ) = Esize (Result_Typ);
5488
   end Target_Has_Fixed_Ops;
5489
 
5490
   ------------------------------------------
5491
   -- Type_May_Have_Bit_Aligned_Components --
5492
   ------------------------------------------
5493
 
5494
   function Type_May_Have_Bit_Aligned_Components
5495
     (Typ : Entity_Id) return Boolean
5496
   is
5497
   begin
5498
      --  Array type, check component type
5499
 
5500
      if Is_Array_Type (Typ) then
5501
         return
5502
           Type_May_Have_Bit_Aligned_Components (Component_Type (Typ));
5503
 
5504
      --  Record type, check components
5505
 
5506
      elsif Is_Record_Type (Typ) then
5507
         declare
5508
            E : Entity_Id;
5509
 
5510
         begin
5511
            E := First_Component_Or_Discriminant (Typ);
5512
            while Present (E) loop
5513
               if Component_May_Be_Bit_Aligned (E)
5514
                 or else Type_May_Have_Bit_Aligned_Components (Etype (E))
5515
               then
5516
                  return True;
5517
               end if;
5518
 
5519
               Next_Component_Or_Discriminant (E);
5520
            end loop;
5521
 
5522
            return False;
5523
         end;
5524
 
5525
      --  Type other than array or record is always OK
5526
 
5527
      else
5528
         return False;
5529
      end if;
5530
   end Type_May_Have_Bit_Aligned_Components;
5531
 
5532
   ----------------------------
5533
   -- Wrap_Cleanup_Procedure --
5534
   ----------------------------
5535
 
5536
   procedure Wrap_Cleanup_Procedure (N : Node_Id) is
5537
      Loc   : constant Source_Ptr := Sloc (N);
5538
      Stseq : constant Node_Id    := Handled_Statement_Sequence (N);
5539
      Stmts : constant List_Id    := Statements (Stseq);
5540
 
5541
   begin
5542
      if Abort_Allowed then
5543
         Prepend_To (Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
5544
         Append_To  (Stmts, Build_Runtime_Call (Loc, RE_Abort_Undefer));
5545
      end if;
5546
   end Wrap_Cleanup_Procedure;
5547
 
5548
end Exp_Util;

powered by: WebSVN 2.1.0

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