OSDN Git Service

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