[multiple changes]
[platform/upstream/gcc.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       --  Renamings of class-wide interface types require no equivalent
1354       --  constrained type declarations because we only need to reference
1355       --  the tag component associated with the interface.
1356
1357       elsif Present (N)
1358         and then Nkind (N) = N_Object_Renaming_Declaration
1359         and then Is_Interface (Unc_Type)
1360       then
1361          pragma Assert (Is_Class_Wide_Type (Unc_Type));
1362          null;
1363
1364       --  In Ada95, nothing to be done if the type of the expression is
1365       --  limited, because in this case the expression cannot be copied,
1366       --  and its use can only be by reference.
1367
1368       --  In Ada2005, the context can be an object declaration whose expression
1369       --  is a function that returns in place. If the nominal subtype has
1370       --  unknown discriminants, the call still provides constraints on the
1371       --  object, and we have to create an actual subtype from it.
1372
1373       --  If the type is class-wide, the expression is dynamically tagged and
1374       --  we do not create an actual subtype either. Ditto for an interface.
1375
1376       elsif Is_Limited_Type (Exp_Typ)
1377         and then
1378          (Is_Class_Wide_Type (Exp_Typ)
1379            or else Is_Interface (Exp_Typ)
1380            or else not Has_Unknown_Discriminants (Exp_Typ)
1381            or else not Is_Composite_Type (Unc_Type))
1382       then
1383          null;
1384
1385       --  For limited objects initialized with build in place function calls,
1386       --  nothing to be done; otherwise we prematurely introduce an N_Reference
1387       --  node in the expression initializing the object, which breaks the
1388       --  circuitry that detects and adds the additional arguments to the
1389       --  called function.
1390
1391       elsif Is_Build_In_Place_Function_Call (Exp) then
1392          null;
1393
1394       else
1395          Remove_Side_Effects (Exp);
1396          Rewrite (Subtype_Indic,
1397            Make_Subtype_From_Expr (Exp, Unc_Type));
1398       end if;
1399    end Expand_Subtype_From_Expr;
1400
1401    --------------------
1402    -- Find_Init_Call --
1403    --------------------
1404
1405    function Find_Init_Call
1406      (Var        : Entity_Id;
1407       Rep_Clause : Node_Id) return Node_Id
1408    is
1409       Typ : constant Entity_Id := Etype (Var);
1410
1411       Init_Proc : Entity_Id;
1412       --  Initialization procedure for Typ
1413
1414       function Find_Init_Call_In_List (From : Node_Id) return Node_Id;
1415       --  Look for init call for Var starting at From and scanning the
1416       --  enclosing list until Rep_Clause or the end of the list is reached.
1417
1418       ----------------------------
1419       -- Find_Init_Call_In_List --
1420       ----------------------------
1421
1422       function Find_Init_Call_In_List (From : Node_Id) return Node_Id is
1423          Init_Call : Node_Id;
1424       begin
1425          Init_Call := From;
1426
1427          while Present (Init_Call) and then Init_Call /= Rep_Clause loop
1428             if Nkind (Init_Call) = N_Procedure_Call_Statement
1429                  and then Is_Entity_Name (Name (Init_Call))
1430                  and then Entity (Name (Init_Call)) = Init_Proc
1431             then
1432                return Init_Call;
1433             end if;
1434             Next (Init_Call);
1435          end loop;
1436
1437          return Empty;
1438       end Find_Init_Call_In_List;
1439
1440       Init_Call : Node_Id;
1441
1442    --  Start of processing for Find_Init_Call
1443
1444    begin
1445       if not Has_Non_Null_Base_Init_Proc (Typ) then
1446          --  No init proc for the type, so obviously no call to be found
1447
1448          return Empty;
1449       end if;
1450
1451       Init_Proc := Base_Init_Proc (Typ);
1452
1453       --  First scan the list containing the declaration of Var
1454
1455       Init_Call := Find_Init_Call_In_List (From => Next (Parent (Var)));
1456
1457       --  If not found, also look on Var's freeze actions list, if any, since
1458       --  the init call may have been moved there (case of an address clause
1459       --  applying to Var).
1460
1461       if No (Init_Call) and then Present (Freeze_Node (Var)) then
1462          Init_Call := Find_Init_Call_In_List
1463                         (First (Actions (Freeze_Node (Var))));
1464       end if;
1465
1466       return Init_Call;
1467    end Find_Init_Call;
1468
1469    ------------------------
1470    -- Find_Interface_ADT --
1471    ------------------------
1472
1473    function Find_Interface_ADT
1474      (T     : Entity_Id;
1475       Iface : Entity_Id) return Elmt_Id
1476    is
1477       ADT : Elmt_Id;
1478       Typ : Entity_Id := T;
1479
1480    begin
1481       pragma Assert (Is_Interface (Iface));
1482
1483       --  Handle private types
1484
1485       if Has_Private_Declaration (Typ)
1486         and then Present (Full_View (Typ))
1487       then
1488          Typ := Full_View (Typ);
1489       end if;
1490
1491       --  Handle access types
1492
1493       if Is_Access_Type (Typ) then
1494          Typ := Directly_Designated_Type (Typ);
1495       end if;
1496
1497       --  Handle task and protected types implementing interfaces
1498
1499       if Is_Concurrent_Type (Typ) then
1500          Typ := Corresponding_Record_Type (Typ);
1501       end if;
1502
1503       pragma Assert
1504         (not Is_Class_Wide_Type (Typ)
1505           and then Ekind (Typ) /= E_Incomplete_Type);
1506
1507       if Is_Ancestor (Iface, Typ) then
1508          return First_Elmt (Access_Disp_Table (Typ));
1509
1510       else
1511          ADT :=
1512            Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
1513          while Present (ADT)
1514            and then Present (Related_Type (Node (ADT)))
1515            and then Related_Type (Node (ADT)) /= Iface
1516            and then not Is_Ancestor (Iface, Related_Type (Node (ADT)))
1517          loop
1518             Next_Elmt (ADT);
1519          end loop;
1520
1521          pragma Assert (Present (Related_Type (Node (ADT))));
1522          return ADT;
1523       end if;
1524    end Find_Interface_ADT;
1525
1526    ------------------------
1527    -- Find_Interface_Tag --
1528    ------------------------
1529
1530    function Find_Interface_Tag
1531      (T     : Entity_Id;
1532       Iface : Entity_Id) return Entity_Id
1533    is
1534       AI_Tag : Entity_Id;
1535       Found  : Boolean   := False;
1536       Typ    : Entity_Id := T;
1537
1538       procedure Find_Tag (Typ : Entity_Id);
1539       --  Internal subprogram used to recursively climb to the ancestors
1540
1541       --------------
1542       -- Find_Tag --
1543       --------------
1544
1545       procedure Find_Tag (Typ : Entity_Id) is
1546          AI_Elmt : Elmt_Id;
1547          AI      : Node_Id;
1548
1549       begin
1550          --  This routine does not handle the case in which the interface is an
1551          --  ancestor of Typ. That case is handled by the enclosing subprogram.
1552
1553          pragma Assert (Typ /= Iface);
1554
1555          --  Climb to the root type handling private types
1556
1557          if Present (Full_View (Etype (Typ))) then
1558             if Full_View (Etype (Typ)) /= Typ then
1559                Find_Tag (Full_View (Etype (Typ)));
1560             end if;
1561
1562          elsif Etype (Typ) /= Typ then
1563             Find_Tag (Etype (Typ));
1564          end if;
1565
1566          --  Traverse the list of interfaces implemented by the type
1567
1568          if not Found
1569            and then Present (Interfaces (Typ))
1570            and then not (Is_Empty_Elmt_List (Interfaces (Typ)))
1571          then
1572             --  Skip the tag associated with the primary table
1573
1574             pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
1575             AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
1576             pragma Assert (Present (AI_Tag));
1577
1578             AI_Elmt := First_Elmt (Interfaces (Typ));
1579             while Present (AI_Elmt) loop
1580                AI := Node (AI_Elmt);
1581
1582                if AI = Iface or else Is_Ancestor (Iface, AI) then
1583                   Found := True;
1584                   return;
1585                end if;
1586
1587                AI_Tag := Next_Tag_Component (AI_Tag);
1588                Next_Elmt (AI_Elmt);
1589             end loop;
1590          end if;
1591       end Find_Tag;
1592
1593    --  Start of processing for Find_Interface_Tag
1594
1595    begin
1596       pragma Assert (Is_Interface (Iface));
1597
1598       --  Handle access types
1599
1600       if Is_Access_Type (Typ) then
1601          Typ := Directly_Designated_Type (Typ);
1602       end if;
1603
1604       --  Handle class-wide types
1605
1606       if Is_Class_Wide_Type (Typ) then
1607          Typ := Root_Type (Typ);
1608       end if;
1609
1610       --  Handle private types
1611
1612       if Has_Private_Declaration (Typ)
1613         and then Present (Full_View (Typ))
1614       then
1615          Typ := Full_View (Typ);
1616       end if;
1617
1618       --  Handle entities from the limited view
1619
1620       if Ekind (Typ) = E_Incomplete_Type then
1621          pragma Assert (Present (Non_Limited_View (Typ)));
1622          Typ := Non_Limited_View (Typ);
1623       end if;
1624
1625       --  Handle task and protected types implementing interfaces
1626
1627       if Is_Concurrent_Type (Typ) then
1628          Typ := Corresponding_Record_Type (Typ);
1629       end if;
1630
1631       --  If the interface is an ancestor of the type, then it shared the
1632       --  primary dispatch table.
1633
1634       if Is_Ancestor (Iface, Typ) then
1635          pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
1636          return First_Tag_Component (Typ);
1637
1638       --  Otherwise we need to search for its associated tag component
1639
1640       else
1641          Find_Tag (Typ);
1642          pragma Assert (Found);
1643          return AI_Tag;
1644       end if;
1645    end Find_Interface_Tag;
1646
1647    ------------------
1648    -- Find_Prim_Op --
1649    ------------------
1650
1651    function Find_Prim_Op (T : Entity_Id; Name : Name_Id) return Entity_Id is
1652       Prim : Elmt_Id;
1653       Typ  : Entity_Id := T;
1654       Op   : Entity_Id;
1655
1656    begin
1657       if Is_Class_Wide_Type (Typ) then
1658          Typ := Root_Type (Typ);
1659       end if;
1660
1661       Typ := Underlying_Type (Typ);
1662
1663       --  Loop through primitive operations
1664
1665       Prim := First_Elmt (Primitive_Operations (Typ));
1666       while Present (Prim) loop
1667          Op := Node (Prim);
1668
1669          --  We can retrieve primitive operations by name if it is an internal
1670          --  name. For equality we must check that both of its operands have
1671          --  the same type, to avoid confusion with user-defined equalities
1672          --  than may have a non-symmetric signature.
1673
1674          exit when Chars (Op) = Name
1675            and then
1676              (Name /= Name_Op_Eq
1677                 or else Etype (First_Entity (Op)) = Etype (Last_Entity (Op)));
1678
1679          Next_Elmt (Prim);
1680
1681          --  Raise Program_Error if no primitive found
1682
1683          if No (Prim) then
1684             raise Program_Error;
1685          end if;
1686       end loop;
1687
1688       return Node (Prim);
1689    end Find_Prim_Op;
1690
1691    ------------------
1692    -- Find_Prim_Op --
1693    ------------------
1694
1695    function Find_Prim_Op
1696      (T    : Entity_Id;
1697       Name : TSS_Name_Type) return Entity_Id
1698    is
1699       Prim : Elmt_Id;
1700       Typ  : Entity_Id := T;
1701
1702    begin
1703       if Is_Class_Wide_Type (Typ) then
1704          Typ := Root_Type (Typ);
1705       end if;
1706
1707       Typ := Underlying_Type (Typ);
1708
1709       Prim := First_Elmt (Primitive_Operations (Typ));
1710       while not Is_TSS (Node (Prim), Name) loop
1711          Next_Elmt (Prim);
1712
1713          --  Raise program error if no primitive found
1714
1715          if No (Prim) then
1716             raise Program_Error;
1717          end if;
1718       end loop;
1719
1720       return Node (Prim);
1721    end Find_Prim_Op;
1722
1723    ----------------------------
1724    -- Find_Protection_Object --
1725    ----------------------------
1726
1727    function Find_Protection_Object (Scop : Entity_Id) return Entity_Id is
1728       S : Entity_Id;
1729
1730    begin
1731       S := Scop;
1732       while Present (S) loop
1733          if (Ekind (S) = E_Entry
1734                or else Ekind (S) = E_Entry_Family
1735                or else Ekind (S) = E_Function
1736                or else Ekind (S) = E_Procedure)
1737            and then Present (Protection_Object (S))
1738          then
1739             return Protection_Object (S);
1740          end if;
1741
1742          S := Scope (S);
1743       end loop;
1744
1745       --  If we do not find a Protection object in the scope chain, then
1746       --  something has gone wrong, most likely the object was never created.
1747
1748       raise Program_Error;
1749    end Find_Protection_Object;
1750
1751    ----------------------
1752    -- Force_Evaluation --
1753    ----------------------
1754
1755    procedure Force_Evaluation (Exp : Node_Id; Name_Req : Boolean := False) is
1756    begin
1757       Remove_Side_Effects (Exp, Name_Req, Variable_Ref => True);
1758    end Force_Evaluation;
1759
1760    ------------------------
1761    -- Generate_Poll_Call --
1762    ------------------------
1763
1764    procedure Generate_Poll_Call (N : Node_Id) is
1765    begin
1766       --  No poll call if polling not active
1767
1768       if not Polling_Required then
1769          return;
1770
1771       --  Otherwise generate require poll call
1772
1773       else
1774          Insert_Before_And_Analyze (N,
1775            Make_Procedure_Call_Statement (Sloc (N),
1776              Name => New_Occurrence_Of (RTE (RE_Poll), Sloc (N))));
1777       end if;
1778    end Generate_Poll_Call;
1779
1780    ---------------------------------
1781    -- Get_Current_Value_Condition --
1782    ---------------------------------
1783
1784    --  Note: the implementation of this procedure is very closely tied to the
1785    --  implementation of Set_Current_Value_Condition. In the Get procedure, we
1786    --  interpret Current_Value fields set by the Set procedure, so the two
1787    --  procedures need to be closely coordinated.
1788
1789    procedure Get_Current_Value_Condition
1790      (Var : Node_Id;
1791       Op  : out Node_Kind;
1792       Val : out Node_Id)
1793    is
1794       Loc : constant Source_Ptr := Sloc (Var);
1795       Ent : constant Entity_Id  := Entity (Var);
1796
1797       procedure Process_Current_Value_Condition
1798         (N : Node_Id;
1799          S : Boolean);
1800       --  N is an expression which holds either True (S = True) or False (S =
1801       --  False) in the condition. This procedure digs out the expression and
1802       --  if it refers to Ent, sets Op and Val appropriately.
1803
1804       -------------------------------------
1805       -- Process_Current_Value_Condition --
1806       -------------------------------------
1807
1808       procedure Process_Current_Value_Condition
1809         (N : Node_Id;
1810          S : Boolean)
1811       is
1812          Cond : Node_Id;
1813          Sens : Boolean;
1814
1815       begin
1816          Cond := N;
1817          Sens := S;
1818
1819          --  Deal with NOT operators, inverting sense
1820
1821          while Nkind (Cond) = N_Op_Not loop
1822             Cond := Right_Opnd (Cond);
1823             Sens := not Sens;
1824          end loop;
1825
1826          --  Deal with AND THEN and AND cases
1827
1828          if Nkind (Cond) = N_And_Then
1829            or else Nkind (Cond) = N_Op_And
1830          then
1831             --  Don't ever try to invert a condition that is of the form
1832             --  of an AND or AND THEN (since we are not doing sufficiently
1833             --  general processing to allow this).
1834
1835             if Sens = False then
1836                Op  := N_Empty;
1837                Val := Empty;
1838                return;
1839             end if;
1840
1841             --  Recursively process AND and AND THEN branches
1842
1843             Process_Current_Value_Condition (Left_Opnd (Cond), True);
1844
1845             if Op /= N_Empty then
1846                return;
1847             end if;
1848
1849             Process_Current_Value_Condition (Right_Opnd (Cond), True);
1850             return;
1851
1852          --  Case of relational operator
1853
1854          elsif Nkind (Cond) in N_Op_Compare then
1855             Op := Nkind (Cond);
1856
1857             --  Invert sense of test if inverted test
1858
1859             if Sens = False then
1860                case Op is
1861                   when N_Op_Eq => Op := N_Op_Ne;
1862                   when N_Op_Ne => Op := N_Op_Eq;
1863                   when N_Op_Lt => Op := N_Op_Ge;
1864                   when N_Op_Gt => Op := N_Op_Le;
1865                   when N_Op_Le => Op := N_Op_Gt;
1866                   when N_Op_Ge => Op := N_Op_Lt;
1867                   when others  => raise Program_Error;
1868                end case;
1869             end if;
1870
1871             --  Case of entity op value
1872
1873             if Is_Entity_Name (Left_Opnd (Cond))
1874               and then Ent = Entity (Left_Opnd (Cond))
1875               and then Compile_Time_Known_Value (Right_Opnd (Cond))
1876             then
1877                Val := Right_Opnd (Cond);
1878
1879             --  Case of value op entity
1880
1881             elsif Is_Entity_Name (Right_Opnd (Cond))
1882               and then Ent = Entity (Right_Opnd (Cond))
1883               and then Compile_Time_Known_Value (Left_Opnd (Cond))
1884             then
1885                Val := Left_Opnd (Cond);
1886
1887                --  We are effectively swapping operands
1888
1889                case Op is
1890                   when N_Op_Eq => null;
1891                   when N_Op_Ne => null;
1892                   when N_Op_Lt => Op := N_Op_Gt;
1893                   when N_Op_Gt => Op := N_Op_Lt;
1894                   when N_Op_Le => Op := N_Op_Ge;
1895                   when N_Op_Ge => Op := N_Op_Le;
1896                   when others  => raise Program_Error;
1897                end case;
1898
1899             else
1900                Op := N_Empty;
1901             end if;
1902
1903             return;
1904
1905             --  Case of Boolean variable reference, return as though the
1906             --  reference had said var = True.
1907
1908          else
1909             if Is_Entity_Name (Cond)
1910               and then Ent = Entity (Cond)
1911             then
1912                Val := New_Occurrence_Of (Standard_True, Sloc (Cond));
1913
1914                if Sens = False then
1915                   Op := N_Op_Ne;
1916                else
1917                   Op := N_Op_Eq;
1918                end if;
1919             end if;
1920          end if;
1921       end Process_Current_Value_Condition;
1922
1923    --  Start of processing for Get_Current_Value_Condition
1924
1925    begin
1926       Op  := N_Empty;
1927       Val := Empty;
1928
1929       --  Immediate return, nothing doing, if this is not an object
1930
1931       if Ekind (Ent) not in Object_Kind then
1932          return;
1933       end if;
1934
1935       --  Otherwise examine current value
1936
1937       declare
1938          CV   : constant Node_Id := Current_Value (Ent);
1939          Sens : Boolean;
1940          Stm  : Node_Id;
1941
1942       begin
1943          --  If statement. Condition is known true in THEN section, known False
1944          --  in any ELSIF or ELSE part, and unknown outside the IF statement.
1945
1946          if Nkind (CV) = N_If_Statement then
1947
1948             --  Before start of IF statement
1949
1950             if Loc < Sloc (CV) then
1951                return;
1952
1953                --  After end of IF statement
1954
1955             elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then
1956                return;
1957             end if;
1958
1959             --  At this stage we know that we are within the IF statement, but
1960             --  unfortunately, the tree does not record the SLOC of the ELSE so
1961             --  we cannot use a simple SLOC comparison to distinguish between
1962             --  the then/else statements, so we have to climb the tree.
1963
1964             declare
1965                N : Node_Id;
1966
1967             begin
1968                N := Parent (Var);
1969                while Parent (N) /= CV loop
1970                   N := Parent (N);
1971
1972                   --  If we fall off the top of the tree, then that's odd, but
1973                   --  perhaps it could occur in some error situation, and the
1974                   --  safest response is simply to assume that the outcome of
1975                   --  the condition is unknown. No point in bombing during an
1976                   --  attempt to optimize things.
1977
1978                   if No (N) then
1979                      return;
1980                   end if;
1981                end loop;
1982
1983                --  Now we have N pointing to a node whose parent is the IF
1984                --  statement in question, so now we can tell if we are within
1985                --  the THEN statements.
1986
1987                if Is_List_Member (N)
1988                  and then List_Containing (N) = Then_Statements (CV)
1989                then
1990                   Sens := True;
1991
1992                --  If the variable reference does not come from source, we
1993                --  cannot reliably tell whether it appears in the else part.
1994                --  In particular, if it appears in generated code for a node
1995                --  that requires finalization, it may be attached to a list
1996                --  that has not been yet inserted into the code. For now,
1997                --  treat it as unknown.
1998
1999                elsif not Comes_From_Source (N) then
2000                   return;
2001
2002                --  Otherwise we must be in ELSIF or ELSE part
2003
2004                else
2005                   Sens := False;
2006                end if;
2007             end;
2008
2009             --  ELSIF part. Condition is known true within the referenced
2010             --  ELSIF, known False in any subsequent ELSIF or ELSE part, and
2011             --  unknown before the ELSE part or after the IF statement.
2012
2013          elsif Nkind (CV) = N_Elsif_Part then
2014             Stm := Parent (CV);
2015
2016             --  Before start of ELSIF part
2017
2018             if Loc < Sloc (CV) then
2019                return;
2020
2021                --  After end of IF statement
2022
2023             elsif Loc >= Sloc (Stm) +
2024               Text_Ptr (UI_To_Int (End_Span (Stm)))
2025             then
2026                return;
2027             end if;
2028
2029             --  Again we lack the SLOC of the ELSE, so we need to climb the
2030             --  tree to see if we are within the ELSIF part in question.
2031
2032             declare
2033                N : Node_Id;
2034
2035             begin
2036                N := Parent (Var);
2037                while Parent (N) /= Stm loop
2038                   N := Parent (N);
2039
2040                   --  If we fall off the top of the tree, then that's odd, but
2041                   --  perhaps it could occur in some error situation, and the
2042                   --  safest response is simply to assume that the outcome of
2043                   --  the condition is unknown. No point in bombing during an
2044                   --  attempt to optimize things.
2045
2046                   if No (N) then
2047                      return;
2048                   end if;
2049                end loop;
2050
2051                --  Now we have N pointing to a node whose parent is the IF
2052                --  statement in question, so see if is the ELSIF part we want.
2053                --  the THEN statements.
2054
2055                if N = CV then
2056                   Sens := True;
2057
2058                   --  Otherwise we must be in subsequent ELSIF or ELSE part
2059
2060                else
2061                   Sens := False;
2062                end if;
2063             end;
2064
2065          --  Iteration scheme of while loop. The condition is known to be
2066          --  true within the body of the loop.
2067
2068          elsif Nkind (CV) = N_Iteration_Scheme then
2069             declare
2070                Loop_Stmt : constant Node_Id := Parent (CV);
2071
2072             begin
2073                --  Before start of body of loop
2074
2075                if Loc < Sloc (Loop_Stmt) then
2076                   return;
2077
2078                --  After end of LOOP statement
2079
2080                elsif Loc >= Sloc (End_Label (Loop_Stmt)) then
2081                   return;
2082
2083                --  We are within the body of the loop
2084
2085                else
2086                   Sens := True;
2087                end if;
2088             end;
2089
2090          --  All other cases of Current_Value settings
2091
2092          else
2093             return;
2094          end if;
2095
2096          --  If we fall through here, then we have a reportable condition, Sens
2097          --  is True if the condition is true and False if it needs inverting.
2098
2099          Process_Current_Value_Condition (Condition (CV), Sens);
2100       end;
2101    end Get_Current_Value_Condition;
2102
2103    ---------------------------------
2104    -- Has_Controlled_Coextensions --
2105    ---------------------------------
2106
2107    function Has_Controlled_Coextensions (Typ : Entity_Id) return Boolean is
2108       D_Typ : Entity_Id;
2109       Discr : Entity_Id;
2110
2111    begin
2112       --  Only consider record types
2113
2114       if Ekind (Typ) /= E_Record_Type
2115         and then Ekind (Typ) /= E_Record_Subtype
2116       then
2117          return False;
2118       end if;
2119
2120       if Has_Discriminants (Typ) then
2121          Discr := First_Discriminant (Typ);
2122          while Present (Discr) loop
2123             D_Typ := Etype (Discr);
2124
2125             if Ekind (D_Typ) = E_Anonymous_Access_Type
2126               and then
2127                 (Is_Controlled (Directly_Designated_Type (D_Typ))
2128                    or else
2129                  Is_Concurrent_Type (Directly_Designated_Type (D_Typ)))
2130             then
2131                return True;
2132             end if;
2133
2134             Next_Discriminant (Discr);
2135          end loop;
2136       end if;
2137
2138       return False;
2139    end Has_Controlled_Coextensions;
2140
2141    --------------------
2142    -- Homonym_Number --
2143    --------------------
2144
2145    function Homonym_Number (Subp : Entity_Id) return Nat is
2146       Count : Nat;
2147       Hom   : Entity_Id;
2148
2149    begin
2150       Count := 1;
2151       Hom := Homonym (Subp);
2152       while Present (Hom) loop
2153          if Scope (Hom) = Scope (Subp) then
2154             Count := Count + 1;
2155          end if;
2156
2157          Hom := Homonym (Hom);
2158       end loop;
2159
2160       return Count;
2161    end Homonym_Number;
2162
2163    ------------------------------
2164    -- In_Unconditional_Context --
2165    ------------------------------
2166
2167    function In_Unconditional_Context (Node : Node_Id) return Boolean is
2168       P : Node_Id;
2169
2170    begin
2171       P := Node;
2172       while Present (P) loop
2173          case Nkind (P) is
2174             when N_Subprogram_Body =>
2175                return True;
2176
2177             when N_If_Statement =>
2178                return False;
2179
2180             when N_Loop_Statement =>
2181                return False;
2182
2183             when N_Case_Statement =>
2184                return False;
2185
2186             when others =>
2187                P := Parent (P);
2188          end case;
2189       end loop;
2190
2191       return False;
2192    end In_Unconditional_Context;
2193
2194    -------------------
2195    -- Insert_Action --
2196    -------------------
2197
2198    procedure Insert_Action (Assoc_Node : Node_Id; Ins_Action : Node_Id) is
2199    begin
2200       if Present (Ins_Action) then
2201          Insert_Actions (Assoc_Node, New_List (Ins_Action));
2202       end if;
2203    end Insert_Action;
2204
2205    --  Version with check(s) suppressed
2206
2207    procedure Insert_Action
2208      (Assoc_Node : Node_Id; Ins_Action : Node_Id; Suppress : Check_Id)
2209    is
2210    begin
2211       Insert_Actions (Assoc_Node, New_List (Ins_Action), Suppress);
2212    end Insert_Action;
2213
2214    --------------------
2215    -- Insert_Actions --
2216    --------------------
2217
2218    procedure Insert_Actions (Assoc_Node : Node_Id; Ins_Actions : List_Id) is
2219       N : Node_Id;
2220       P : Node_Id;
2221
2222       Wrapped_Node : Node_Id := Empty;
2223
2224    begin
2225       if No (Ins_Actions) or else Is_Empty_List (Ins_Actions) then
2226          return;
2227       end if;
2228
2229       --  Ignore insert of actions from inside default expression (or other
2230       --  similar "spec expression") in the special spec-expression analyze
2231       --  mode. Any insertions at this point have no relevance, since we are
2232       --  only doing the analyze to freeze the types of any static expressions.
2233       --  See section "Handling of Default Expressions" in the spec of package
2234       --  Sem for further details.
2235
2236       if In_Spec_Expression then
2237          return;
2238       end if;
2239
2240       --  If the action derives from stuff inside a record, then the actions
2241       --  are attached to the current scope, to be inserted and analyzed on
2242       --  exit from the scope. The reason for this is that we may also
2243       --  be generating freeze actions at the same time, and they must
2244       --  eventually be elaborated in the correct order.
2245
2246       if Is_Record_Type (Current_Scope)
2247         and then not Is_Frozen (Current_Scope)
2248       then
2249          if No (Scope_Stack.Table
2250            (Scope_Stack.Last).Pending_Freeze_Actions)
2251          then
2252             Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions :=
2253               Ins_Actions;
2254          else
2255             Append_List
2256               (Ins_Actions,
2257                Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions);
2258          end if;
2259
2260          return;
2261       end if;
2262
2263       --  We now intend to climb up the tree to find the right point to
2264       --  insert the actions. We start at Assoc_Node, unless this node is
2265       --  a subexpression in which case we start with its parent. We do this
2266       --  for two reasons. First it speeds things up. Second, if Assoc_Node
2267       --  is itself one of the special nodes like N_And_Then, then we assume
2268       --  that an initial request to insert actions for such a node does not
2269       --  expect the actions to get deposited in the node for later handling
2270       --  when the node is expanded, since clearly the node is being dealt
2271       --  with by the caller. Note that in the subexpression case, N is
2272       --  always the child we came from.
2273
2274       --  N_Raise_xxx_Error is an annoying special case, it is a statement
2275       --  if it has type Standard_Void_Type, and a subexpression otherwise.
2276       --  otherwise. Procedure attribute references are also statements.
2277
2278       if Nkind (Assoc_Node) in N_Subexpr
2279         and then (Nkind (Assoc_Node) in N_Raise_xxx_Error
2280                    or else Etype (Assoc_Node) /= Standard_Void_Type)
2281         and then (Nkind (Assoc_Node) /= N_Attribute_Reference
2282                    or else
2283                      not Is_Procedure_Attribute_Name
2284                            (Attribute_Name (Assoc_Node)))
2285       then
2286          P := Assoc_Node;             -- ??? does not agree with above!
2287          N := Parent (Assoc_Node);
2288
2289       --  Non-subexpression case. Note that N is initially Empty in this
2290       --  case (N is only guaranteed Non-Empty in the subexpr case).
2291
2292       else
2293          P := Assoc_Node;
2294          N := Empty;
2295       end if;
2296
2297       --  Capture root of the transient scope
2298
2299       if Scope_Is_Transient then
2300          Wrapped_Node := Node_To_Be_Wrapped;
2301       end if;
2302
2303       loop
2304          pragma Assert (Present (P));
2305
2306          case Nkind (P) is
2307
2308             --  Case of right operand of AND THEN or OR ELSE. Put the actions
2309             --  in the Actions field of the right operand. They will be moved
2310             --  out further when the AND THEN or OR ELSE operator is expanded.
2311             --  Nothing special needs to be done for the left operand since
2312             --  in that case the actions are executed unconditionally.
2313
2314             when N_Short_Circuit =>
2315                if N = Right_Opnd (P) then
2316
2317                   --  We are now going to either append the actions to the
2318                   --  actions field of the short-circuit operation. We will
2319                   --  also analyze the actions now.
2320
2321                   --  This analysis is really too early, the proper thing would
2322                   --  be to just park them there now, and only analyze them if
2323                   --  we find we really need them, and to it at the proper
2324                   --  final insertion point. However attempting to this proved
2325                   --  tricky, so for now we just kill current values before and
2326                   --  after the analyze call to make sure we avoid peculiar
2327                   --  optimizations from this out of order insertion.
2328
2329                   Kill_Current_Values;
2330
2331                   if Present (Actions (P)) then
2332                      Insert_List_After_And_Analyze
2333                        (Last (Actions (P)), Ins_Actions);
2334                   else
2335                      Set_Actions (P, Ins_Actions);
2336                      Analyze_List (Actions (P));
2337                   end if;
2338
2339                   Kill_Current_Values;
2340
2341                   return;
2342                end if;
2343
2344             --  Then or Else operand of conditional expression. Add actions to
2345             --  Then_Actions or Else_Actions field as appropriate. The actions
2346             --  will be moved further out when the conditional is expanded.
2347
2348             when N_Conditional_Expression =>
2349                declare
2350                   ThenX : constant Node_Id := Next (First (Expressions (P)));
2351                   ElseX : constant Node_Id := Next (ThenX);
2352
2353                begin
2354                   --  Actions belong to the then expression, temporarily
2355                   --  place them as Then_Actions of the conditional expr.
2356                   --  They will be moved to the proper place later when
2357                   --  the conditional expression is expanded.
2358
2359                   if N = ThenX then
2360                      if Present (Then_Actions (P)) then
2361                         Insert_List_After_And_Analyze
2362                           (Last (Then_Actions (P)), Ins_Actions);
2363                      else
2364                         Set_Then_Actions (P, Ins_Actions);
2365                         Analyze_List (Then_Actions (P));
2366                      end if;
2367
2368                      return;
2369
2370                   --  Actions belong to the else expression, temporarily
2371                   --  place them as Else_Actions of the conditional expr.
2372                   --  They will be moved to the proper place later when
2373                   --  the conditional expression is expanded.
2374
2375                   elsif N = ElseX then
2376                      if Present (Else_Actions (P)) then
2377                         Insert_List_After_And_Analyze
2378                           (Last (Else_Actions (P)), Ins_Actions);
2379                      else
2380                         Set_Else_Actions (P, Ins_Actions);
2381                         Analyze_List (Else_Actions (P));
2382                      end if;
2383
2384                      return;
2385
2386                   --  Actions belong to the condition. In this case they are
2387                   --  unconditionally executed, and so we can continue the
2388                   --  search for the proper insert point.
2389
2390                   else
2391                      null;
2392                   end if;
2393                end;
2394
2395             --  Case of appearing in the condition of a while expression or
2396             --  elsif. We insert the actions into the Condition_Actions field.
2397             --  They will be moved further out when the while loop or elsif
2398             --  is analyzed.
2399
2400             when N_Iteration_Scheme |
2401                  N_Elsif_Part
2402             =>
2403                if N = Condition (P) then
2404                   if Present (Condition_Actions (P)) then
2405                      Insert_List_After_And_Analyze
2406                        (Last (Condition_Actions (P)), Ins_Actions);
2407                   else
2408                      Set_Condition_Actions (P, Ins_Actions);
2409
2410                      --  Set the parent of the insert actions explicitly.
2411                      --  This is not a syntactic field, but we need the
2412                      --  parent field set, in particular so that freeze
2413                      --  can understand that it is dealing with condition
2414                      --  actions, and properly insert the freezing actions.
2415
2416                      Set_Parent (Ins_Actions, P);
2417                      Analyze_List (Condition_Actions (P));
2418                   end if;
2419
2420                   return;
2421                end if;
2422
2423             --  Statements, declarations, pragmas, representation clauses
2424
2425             when
2426                --  Statements
2427
2428                N_Procedure_Call_Statement               |
2429                N_Statement_Other_Than_Procedure_Call    |
2430
2431                --  Pragmas
2432
2433                N_Pragma                                 |
2434
2435                --  Representation_Clause
2436
2437                N_At_Clause                              |
2438                N_Attribute_Definition_Clause            |
2439                N_Enumeration_Representation_Clause      |
2440                N_Record_Representation_Clause           |
2441
2442                --  Declarations
2443
2444                N_Abstract_Subprogram_Declaration        |
2445                N_Entry_Body                             |
2446                N_Exception_Declaration                  |
2447                N_Exception_Renaming_Declaration         |
2448                N_Formal_Abstract_Subprogram_Declaration |
2449                N_Formal_Concrete_Subprogram_Declaration |
2450                N_Formal_Object_Declaration              |
2451                N_Formal_Type_Declaration                |
2452                N_Full_Type_Declaration                  |
2453                N_Function_Instantiation                 |
2454                N_Generic_Function_Renaming_Declaration  |
2455                N_Generic_Package_Declaration            |
2456                N_Generic_Package_Renaming_Declaration   |
2457                N_Generic_Procedure_Renaming_Declaration |
2458                N_Generic_Subprogram_Declaration         |
2459                N_Implicit_Label_Declaration             |
2460                N_Incomplete_Type_Declaration            |
2461                N_Number_Declaration                     |
2462                N_Object_Declaration                     |
2463                N_Object_Renaming_Declaration            |
2464                N_Package_Body                           |
2465                N_Package_Body_Stub                      |
2466                N_Package_Declaration                    |
2467                N_Package_Instantiation                  |
2468                N_Package_Renaming_Declaration           |
2469                N_Private_Extension_Declaration          |
2470                N_Private_Type_Declaration               |
2471                N_Procedure_Instantiation                |
2472                N_Protected_Body                         |
2473                N_Protected_Body_Stub                    |
2474                N_Protected_Type_Declaration             |
2475                N_Single_Task_Declaration                |
2476                N_Subprogram_Body                        |
2477                N_Subprogram_Body_Stub                   |
2478                N_Subprogram_Declaration                 |
2479                N_Subprogram_Renaming_Declaration        |
2480                N_Subtype_Declaration                    |
2481                N_Task_Body                              |
2482                N_Task_Body_Stub                         |
2483                N_Task_Type_Declaration                  |
2484
2485                --  Freeze entity behaves like a declaration or statement
2486
2487                N_Freeze_Entity
2488             =>
2489                --  Do not insert here if the item is not a list member (this
2490                --  happens for example with a triggering statement, and the
2491                --  proper approach is to insert before the entire select).
2492
2493                if not Is_List_Member (P) then
2494                   null;
2495
2496                --  Do not insert if parent of P is an N_Component_Association
2497                --  node (i.e. we are in the context of an N_Aggregate or
2498                --  N_Extension_Aggregate node. In this case we want to insert
2499                --  before the entire aggregate.
2500
2501                elsif Nkind (Parent (P)) = N_Component_Association then
2502                   null;
2503
2504                --  Do not insert if the parent of P is either an N_Variant
2505                --  node or an N_Record_Definition node, meaning in either
2506                --  case that P is a member of a component list, and that
2507                --  therefore the actions should be inserted outside the
2508                --  complete record declaration.
2509
2510                elsif Nkind (Parent (P)) = N_Variant
2511                  or else Nkind (Parent (P)) = N_Record_Definition
2512                then
2513                   null;
2514
2515                --  Do not insert freeze nodes within the loop generated for
2516                --  an aggregate, because they may be elaborated too late for
2517                --  subsequent use in the back end: within a package spec the
2518                --  loop is part of the elaboration procedure and is only
2519                --  elaborated during the second pass.
2520                --  If the loop comes from source, or the entity is local to
2521                --  the loop itself it must remain within.
2522
2523                elsif Nkind (Parent (P)) = N_Loop_Statement
2524                  and then not Comes_From_Source (Parent (P))
2525                  and then Nkind (First (Ins_Actions)) = N_Freeze_Entity
2526                  and then
2527                    Scope (Entity (First (Ins_Actions))) /= Current_Scope
2528                then
2529                   null;
2530
2531                --  Otherwise we can go ahead and do the insertion
2532
2533                elsif P = Wrapped_Node then
2534                   Store_Before_Actions_In_Scope (Ins_Actions);
2535                   return;
2536
2537                else
2538                   Insert_List_Before_And_Analyze (P, Ins_Actions);
2539                   return;
2540                end if;
2541
2542             --  A special case, N_Raise_xxx_Error can act either as a
2543             --  statement or a subexpression. We tell the difference
2544             --  by looking at the Etype. It is set to Standard_Void_Type
2545             --  in the statement case.
2546
2547             when
2548                N_Raise_xxx_Error =>
2549                   if Etype (P) = Standard_Void_Type then
2550                      if  P = Wrapped_Node then
2551                         Store_Before_Actions_In_Scope (Ins_Actions);
2552                      else
2553                         Insert_List_Before_And_Analyze (P, Ins_Actions);
2554                      end if;
2555
2556                      return;
2557
2558                   --  In the subexpression case, keep climbing
2559
2560                   else
2561                      null;
2562                   end if;
2563
2564             --  If a component association appears within a loop created for
2565             --  an array aggregate, attach the actions to the association so
2566             --  they can be subsequently inserted within the loop. For other
2567             --  component associations insert outside of the aggregate. For
2568             --  an association that will generate a loop, its Loop_Actions
2569             --  attribute is already initialized (see exp_aggr.adb).
2570
2571             --  The list of loop_actions can in turn generate additional ones,
2572             --  that are inserted before the associated node. If the associated
2573             --  node is outside the aggregate, the new actions are collected
2574             --  at the end of the loop actions, to respect the order in which
2575             --  they are to be elaborated.
2576
2577             when
2578                N_Component_Association =>
2579                   if Nkind (Parent (P)) = N_Aggregate
2580                     and then Present (Loop_Actions (P))
2581                   then
2582                      if Is_Empty_List (Loop_Actions (P)) then
2583                         Set_Loop_Actions (P, Ins_Actions);
2584                         Analyze_List (Ins_Actions);
2585
2586                      else
2587                         declare
2588                            Decl : Node_Id;
2589
2590                         begin
2591                            --  Check whether these actions were generated
2592                            --  by a declaration that is part of the loop_
2593                            --  actions for the component_association.
2594
2595                            Decl := Assoc_Node;
2596                            while Present (Decl) loop
2597                               exit when Parent (Decl) = P
2598                                 and then Is_List_Member (Decl)
2599                                 and then
2600                                   List_Containing (Decl) = Loop_Actions (P);
2601                               Decl := Parent (Decl);
2602                            end loop;
2603
2604                            if Present (Decl) then
2605                               Insert_List_Before_And_Analyze
2606                                 (Decl, Ins_Actions);
2607                            else
2608                               Insert_List_After_And_Analyze
2609                                 (Last (Loop_Actions (P)), Ins_Actions);
2610                            end if;
2611                         end;
2612                      end if;
2613
2614                      return;
2615
2616                   else
2617                      null;
2618                   end if;
2619
2620             --  Another special case, an attribute denoting a procedure call
2621
2622             when
2623                N_Attribute_Reference =>
2624                   if Is_Procedure_Attribute_Name (Attribute_Name (P)) then
2625                      if P = Wrapped_Node then
2626                         Store_Before_Actions_In_Scope (Ins_Actions);
2627                      else
2628                         Insert_List_Before_And_Analyze (P, Ins_Actions);
2629                      end if;
2630
2631                      return;
2632
2633                   --  In the subexpression case, keep climbing
2634
2635                   else
2636                      null;
2637                   end if;
2638
2639             --  For all other node types, keep climbing tree
2640
2641             when
2642                N_Abortable_Part                         |
2643                N_Accept_Alternative                     |
2644                N_Access_Definition                      |
2645                N_Access_Function_Definition             |
2646                N_Access_Procedure_Definition            |
2647                N_Access_To_Object_Definition            |
2648                N_Aggregate                              |
2649                N_Allocator                              |
2650                N_Case_Statement_Alternative             |
2651                N_Character_Literal                      |
2652                N_Compilation_Unit                       |
2653                N_Compilation_Unit_Aux                   |
2654                N_Component_Clause                       |
2655                N_Component_Declaration                  |
2656                N_Component_Definition                   |
2657                N_Component_List                         |
2658                N_Constrained_Array_Definition           |
2659                N_Decimal_Fixed_Point_Definition         |
2660                N_Defining_Character_Literal             |
2661                N_Defining_Identifier                    |
2662                N_Defining_Operator_Symbol               |
2663                N_Defining_Program_Unit_Name             |
2664                N_Delay_Alternative                      |
2665                N_Delta_Constraint                       |
2666                N_Derived_Type_Definition                |
2667                N_Designator                             |
2668                N_Digits_Constraint                      |
2669                N_Discriminant_Association               |
2670                N_Discriminant_Specification             |
2671                N_Empty                                  |
2672                N_Entry_Body_Formal_Part                 |
2673                N_Entry_Call_Alternative                 |
2674                N_Entry_Declaration                      |
2675                N_Entry_Index_Specification              |
2676                N_Enumeration_Type_Definition            |
2677                N_Error                                  |
2678                N_Exception_Handler                      |
2679                N_Expanded_Name                          |
2680                N_Explicit_Dereference                   |
2681                N_Extension_Aggregate                    |
2682                N_Floating_Point_Definition              |
2683                N_Formal_Decimal_Fixed_Point_Definition  |
2684                N_Formal_Derived_Type_Definition         |
2685                N_Formal_Discrete_Type_Definition        |
2686                N_Formal_Floating_Point_Definition       |
2687                N_Formal_Modular_Type_Definition         |
2688                N_Formal_Ordinary_Fixed_Point_Definition |
2689                N_Formal_Package_Declaration             |
2690                N_Formal_Private_Type_Definition         |
2691                N_Formal_Signed_Integer_Type_Definition  |
2692                N_Function_Call                          |
2693                N_Function_Specification                 |
2694                N_Generic_Association                    |
2695                N_Handled_Sequence_Of_Statements         |
2696                N_Identifier                             |
2697                N_In                                     |
2698                N_Index_Or_Discriminant_Constraint       |
2699                N_Indexed_Component                      |
2700                N_Integer_Literal                        |
2701                N_Itype_Reference                        |
2702                N_Label                                  |
2703                N_Loop_Parameter_Specification           |
2704                N_Mod_Clause                             |
2705                N_Modular_Type_Definition                |
2706                N_Not_In                                 |
2707                N_Null                                   |
2708                N_Op_Abs                                 |
2709                N_Op_Add                                 |
2710                N_Op_And                                 |
2711                N_Op_Concat                              |
2712                N_Op_Divide                              |
2713                N_Op_Eq                                  |
2714                N_Op_Expon                               |
2715                N_Op_Ge                                  |
2716                N_Op_Gt                                  |
2717                N_Op_Le                                  |
2718                N_Op_Lt                                  |
2719                N_Op_Minus                               |
2720                N_Op_Mod                                 |
2721                N_Op_Multiply                            |
2722                N_Op_Ne                                  |
2723                N_Op_Not                                 |
2724                N_Op_Or                                  |
2725                N_Op_Plus                                |
2726                N_Op_Rem                                 |
2727                N_Op_Rotate_Left                         |
2728                N_Op_Rotate_Right                        |
2729                N_Op_Shift_Left                          |
2730                N_Op_Shift_Right                         |
2731                N_Op_Shift_Right_Arithmetic              |
2732                N_Op_Subtract                            |
2733                N_Op_Xor                                 |
2734                N_Operator_Symbol                        |
2735                N_Ordinary_Fixed_Point_Definition        |
2736                N_Others_Choice                          |
2737                N_Package_Specification                  |
2738                N_Parameter_Association                  |
2739                N_Parameter_Specification                |
2740                N_Pop_Constraint_Error_Label             |
2741                N_Pop_Program_Error_Label                |
2742                N_Pop_Storage_Error_Label                |
2743                N_Pragma_Argument_Association            |
2744                N_Procedure_Specification                |
2745                N_Protected_Definition                   |
2746                N_Push_Constraint_Error_Label            |
2747                N_Push_Program_Error_Label               |
2748                N_Push_Storage_Error_Label               |
2749                N_Qualified_Expression                   |
2750                N_Range                                  |
2751                N_Range_Constraint                       |
2752                N_Real_Literal                           |
2753                N_Real_Range_Specification               |
2754                N_Record_Definition                      |
2755                N_Reference                              |
2756                N_Selected_Component                     |
2757                N_Signed_Integer_Type_Definition         |
2758                N_Single_Protected_Declaration           |
2759                N_Slice                                  |
2760                N_String_Literal                         |
2761                N_Subprogram_Info                        |
2762                N_Subtype_Indication                     |
2763                N_Subunit                                |
2764                N_Task_Definition                        |
2765                N_Terminate_Alternative                  |
2766                N_Triggering_Alternative                 |
2767                N_Type_Conversion                        |
2768                N_Unchecked_Expression                   |
2769                N_Unchecked_Type_Conversion              |
2770                N_Unconstrained_Array_Definition         |
2771                N_Unused_At_End                          |
2772                N_Unused_At_Start                        |
2773                N_Use_Package_Clause                     |
2774                N_Use_Type_Clause                        |
2775                N_Variant                                |
2776                N_Variant_Part                           |
2777                N_Validate_Unchecked_Conversion          |
2778                N_With_Clause
2779             =>
2780                null;
2781
2782          end case;
2783
2784          --  Make sure that inserted actions stay in the transient scope
2785
2786          if P = Wrapped_Node then
2787             Store_Before_Actions_In_Scope (Ins_Actions);
2788             return;
2789          end if;
2790
2791          --  If we fall through above tests, keep climbing tree
2792
2793          N := P;
2794
2795          if Nkind (Parent (N)) = N_Subunit then
2796
2797             --  This is the proper body corresponding to a stub. Insertion
2798             --  must be done at the point of the stub, which is in the decla-
2799             --  rative part of the parent unit.
2800
2801             P := Corresponding_Stub (Parent (N));
2802
2803          else
2804             P := Parent (N);
2805          end if;
2806       end loop;
2807    end Insert_Actions;
2808
2809    --  Version with check(s) suppressed
2810
2811    procedure Insert_Actions
2812      (Assoc_Node  : Node_Id;
2813       Ins_Actions : List_Id;
2814       Suppress    : Check_Id)
2815    is
2816    begin
2817       if Suppress = All_Checks then
2818          declare
2819             Svg : constant Suppress_Array := Scope_Suppress;
2820          begin
2821             Scope_Suppress := (others => True);
2822             Insert_Actions (Assoc_Node, Ins_Actions);
2823             Scope_Suppress := Svg;
2824          end;
2825
2826       else
2827          declare
2828             Svg : constant Boolean := Scope_Suppress (Suppress);
2829          begin
2830             Scope_Suppress (Suppress) := True;
2831             Insert_Actions (Assoc_Node, Ins_Actions);
2832             Scope_Suppress (Suppress) := Svg;
2833          end;
2834       end if;
2835    end Insert_Actions;
2836
2837    --------------------------
2838    -- Insert_Actions_After --
2839    --------------------------
2840
2841    procedure Insert_Actions_After
2842      (Assoc_Node  : Node_Id;
2843       Ins_Actions : List_Id)
2844    is
2845    begin
2846       if Scope_Is_Transient
2847         and then Assoc_Node = Node_To_Be_Wrapped
2848       then
2849          Store_After_Actions_In_Scope (Ins_Actions);
2850       else
2851          Insert_List_After_And_Analyze (Assoc_Node, Ins_Actions);
2852       end if;
2853    end Insert_Actions_After;
2854
2855    ---------------------------------
2856    -- Insert_Library_Level_Action --
2857    ---------------------------------
2858
2859    procedure Insert_Library_Level_Action (N : Node_Id) is
2860       Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
2861
2862    begin
2863       Push_Scope (Cunit_Entity (Main_Unit));
2864       --  ??? should this be Current_Sem_Unit instead of Main_Unit?
2865
2866       if No (Actions (Aux)) then
2867          Set_Actions (Aux, New_List (N));
2868       else
2869          Append (N, Actions (Aux));
2870       end if;
2871
2872       Analyze (N);
2873       Pop_Scope;
2874    end Insert_Library_Level_Action;
2875
2876    ----------------------------------
2877    -- Insert_Library_Level_Actions --
2878    ----------------------------------
2879
2880    procedure Insert_Library_Level_Actions (L : List_Id) is
2881       Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
2882
2883    begin
2884       if Is_Non_Empty_List (L) then
2885          Push_Scope (Cunit_Entity (Main_Unit));
2886          --  ??? should this be Current_Sem_Unit instead of Main_Unit?
2887
2888          if No (Actions (Aux)) then
2889             Set_Actions (Aux, L);
2890             Analyze_List (L);
2891          else
2892             Insert_List_After_And_Analyze (Last (Actions (Aux)), L);
2893          end if;
2894
2895          Pop_Scope;
2896       end if;
2897    end Insert_Library_Level_Actions;
2898
2899    ----------------------
2900    -- Inside_Init_Proc --
2901    ----------------------
2902
2903    function Inside_Init_Proc return Boolean is
2904       S : Entity_Id;
2905
2906    begin
2907       S := Current_Scope;
2908       while Present (S)
2909         and then S /= Standard_Standard
2910       loop
2911          if Is_Init_Proc (S) then
2912             return True;
2913          else
2914             S := Scope (S);
2915          end if;
2916       end loop;
2917
2918       return False;
2919    end Inside_Init_Proc;
2920
2921    ----------------------------
2922    -- Is_All_Null_Statements --
2923    ----------------------------
2924
2925    function Is_All_Null_Statements (L : List_Id) return Boolean is
2926       Stm : Node_Id;
2927
2928    begin
2929       Stm := First (L);
2930       while Present (Stm) loop
2931          if Nkind (Stm) /= N_Null_Statement then
2932             return False;
2933          end if;
2934
2935          Next (Stm);
2936       end loop;
2937
2938       return True;
2939    end Is_All_Null_Statements;
2940
2941    ----------------------------------
2942    -- Is_Library_Level_Tagged_Type --
2943    ----------------------------------
2944
2945    function Is_Library_Level_Tagged_Type (Typ : Entity_Id) return Boolean is
2946    begin
2947       return Is_Tagged_Type (Typ)
2948         and then Is_Library_Level_Entity (Typ);
2949    end Is_Library_Level_Tagged_Type;
2950
2951    ----------------------------------
2952    -- Is_Possibly_Unaligned_Object --
2953    ----------------------------------
2954
2955    function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean is
2956       T  : constant Entity_Id := Etype (N);
2957
2958    begin
2959       --  If renamed object, apply test to underlying object
2960
2961       if Is_Entity_Name (N)
2962         and then Is_Object (Entity (N))
2963         and then Present (Renamed_Object (Entity (N)))
2964       then
2965          return Is_Possibly_Unaligned_Object (Renamed_Object (Entity (N)));
2966       end if;
2967
2968       --  Tagged and controlled types and aliased types are always aligned,
2969       --  as are concurrent types.
2970
2971       if Is_Aliased (T)
2972         or else Has_Controlled_Component (T)
2973         or else Is_Concurrent_Type (T)
2974         or else Is_Tagged_Type (T)
2975         or else Is_Controlled (T)
2976       then
2977          return False;
2978       end if;
2979
2980       --  If this is an element of a packed array, may be unaligned
2981
2982       if Is_Ref_To_Bit_Packed_Array (N) then
2983          return True;
2984       end if;
2985
2986       --  Case of component reference
2987
2988       if Nkind (N) = N_Selected_Component then
2989          declare
2990             P : constant Node_Id   := Prefix (N);
2991             C : constant Entity_Id := Entity (Selector_Name (N));
2992             M : Nat;
2993             S : Nat;
2994
2995          begin
2996             --  If component reference is for an array with non-static bounds,
2997             --  then it is always aligned: we can only process unaligned
2998             --  arrays with static bounds (more accurately bounds known at
2999             --  compile time).
3000
3001             if Is_Array_Type (T)
3002               and then not Compile_Time_Known_Bounds (T)
3003             then
3004                return False;
3005             end if;
3006
3007             --  If component is aliased, it is definitely properly aligned
3008
3009             if Is_Aliased (C) then
3010                return False;
3011             end if;
3012
3013             --  If component is for a type implemented as a scalar, and the
3014             --  record is packed, and the component is other than the first
3015             --  component of the record, then the component may be unaligned.
3016
3017             if Is_Packed (Etype (P))
3018               and then Represented_As_Scalar (Etype (C))
3019               and then First_Entity (Scope (C)) /= C
3020             then
3021                return True;
3022             end if;
3023
3024             --  Compute maximum possible alignment for T
3025
3026             --  If alignment is known, then that settles things
3027
3028             if Known_Alignment (T) then
3029                M := UI_To_Int (Alignment (T));
3030
3031             --  If alignment is not known, tentatively set max alignment
3032
3033             else
3034                M := Ttypes.Maximum_Alignment;
3035
3036                --  We can reduce this if the Esize is known since the default
3037                --  alignment will never be more than the smallest power of 2
3038                --  that does not exceed this Esize value.
3039
3040                if Known_Esize (T) then
3041                   S := UI_To_Int (Esize (T));
3042
3043                   while (M / 2) >= S loop
3044                      M := M / 2;
3045                   end loop;
3046                end if;
3047             end if;
3048
3049             --  If the component reference is for a record that has a specified
3050             --  alignment, and we either know it is too small, or cannot tell,
3051             --  then the component may be unaligned
3052
3053             if Known_Alignment (Etype (P))
3054               and then Alignment (Etype (P)) < Ttypes.Maximum_Alignment
3055               and then M > Alignment (Etype (P))
3056             then
3057                return True;
3058             end if;
3059
3060             --  Case of component clause present which may specify an
3061             --  unaligned position.
3062
3063             if Present (Component_Clause (C)) then
3064
3065                --  Otherwise we can do a test to make sure that the actual
3066                --  start position in the record, and the length, are both
3067                --  consistent with the required alignment. If not, we know
3068                --  that we are unaligned.
3069
3070                declare
3071                   Align_In_Bits : constant Nat := M * System_Storage_Unit;
3072                begin
3073                   if Component_Bit_Offset (C) mod Align_In_Bits /= 0
3074                     or else Esize (C) mod Align_In_Bits /= 0
3075                   then
3076                      return True;
3077                   end if;
3078                end;
3079             end if;
3080
3081             --  Otherwise, for a component reference, test prefix
3082
3083             return Is_Possibly_Unaligned_Object (P);
3084          end;
3085
3086       --  If not a component reference, must be aligned
3087
3088       else
3089          return False;
3090       end if;
3091    end Is_Possibly_Unaligned_Object;
3092
3093    ---------------------------------
3094    -- Is_Possibly_Unaligned_Slice --
3095    ---------------------------------
3096
3097    function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean is
3098    begin
3099       --  Go to renamed object
3100
3101       if Is_Entity_Name (N)
3102         and then Is_Object (Entity (N))
3103         and then Present (Renamed_Object (Entity (N)))
3104       then
3105          return Is_Possibly_Unaligned_Slice (Renamed_Object (Entity (N)));
3106       end if;
3107
3108       --  The reference must be a slice
3109
3110       if Nkind (N) /= N_Slice then
3111          return False;
3112       end if;
3113
3114       --  Always assume the worst for a nested record component with a
3115       --  component clause, which gigi/gcc does not appear to handle well.
3116       --  It is not clear why this special test is needed at all ???
3117
3118       if Nkind (Prefix (N)) = N_Selected_Component
3119         and then Nkind (Prefix (Prefix (N))) = N_Selected_Component
3120         and then
3121           Present (Component_Clause (Entity (Selector_Name (Prefix (N)))))
3122       then
3123          return True;
3124       end if;
3125
3126       --  We only need to worry if the target has strict alignment
3127
3128       if not Target_Strict_Alignment then
3129          return False;
3130       end if;
3131
3132       --  If it is a slice, then look at the array type being sliced
3133
3134       declare
3135          Sarr : constant Node_Id := Prefix (N);
3136          --  Prefix of the slice, i.e. the array being sliced
3137
3138          Styp : constant Entity_Id := Etype (Prefix (N));
3139          --  Type of the array being sliced
3140
3141          Pref : Node_Id;
3142          Ptyp : Entity_Id;
3143
3144       begin
3145          --  The problems arise if the array object that is being sliced
3146          --  is a component of a record or array, and we cannot guarantee
3147          --  the alignment of the array within its containing object.
3148
3149          --  To investigate this, we look at successive prefixes to see
3150          --  if we have a worrisome indexed or selected component.
3151
3152          Pref := Sarr;
3153          loop
3154             --  Case of array is part of an indexed component reference
3155
3156             if Nkind (Pref) = N_Indexed_Component then
3157                Ptyp := Etype (Prefix (Pref));
3158
3159                --  The only problematic case is when the array is packed,
3160                --  in which case we really know nothing about the alignment
3161                --  of individual components.
3162
3163                if Is_Bit_Packed_Array (Ptyp) then
3164                   return True;
3165                end if;
3166
3167             --  Case of array is part of a selected component reference
3168
3169             elsif Nkind (Pref) = N_Selected_Component then
3170                Ptyp := Etype (Prefix (Pref));
3171
3172                --  We are definitely in trouble if the record in question
3173                --  has an alignment, and either we know this alignment is
3174                --  inconsistent with the alignment of the slice, or we
3175                --  don't know what the alignment of the slice should be.
3176
3177                if Known_Alignment (Ptyp)
3178                  and then (Unknown_Alignment (Styp)
3179                              or else Alignment (Styp) > Alignment (Ptyp))
3180                then
3181                   return True;
3182                end if;
3183
3184                --  We are in potential trouble if the record type is packed.
3185                --  We could special case when we know that the array is the
3186                --  first component, but that's not such a simple case ???
3187
3188                if Is_Packed (Ptyp) then
3189                   return True;
3190                end if;
3191
3192                --  We are in trouble if there is a component clause, and
3193                --  either we do not know the alignment of the slice, or
3194                --  the alignment of the slice is inconsistent with the
3195                --  bit position specified by the component clause.
3196
3197                declare
3198                   Field : constant Entity_Id := Entity (Selector_Name (Pref));
3199                begin
3200                   if Present (Component_Clause (Field))
3201                     and then
3202                       (Unknown_Alignment (Styp)
3203                         or else
3204                          (Component_Bit_Offset (Field) mod
3205                            (System_Storage_Unit * Alignment (Styp))) /= 0)
3206                   then
3207                      return True;
3208                   end if;
3209                end;
3210
3211             --  For cases other than selected or indexed components we
3212             --  know we are OK, since no issues arise over alignment.
3213
3214             else
3215                return False;
3216             end if;
3217
3218             --  We processed an indexed component or selected component
3219             --  reference that looked safe, so keep checking prefixes.
3220
3221             Pref := Prefix (Pref);
3222          end loop;
3223       end;
3224    end Is_Possibly_Unaligned_Slice;
3225
3226    --------------------------------
3227    -- Is_Ref_To_Bit_Packed_Array --
3228    --------------------------------
3229
3230    function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean is
3231       Result : Boolean;
3232       Expr   : Node_Id;
3233
3234    begin
3235       if Is_Entity_Name (N)
3236         and then Is_Object (Entity (N))
3237         and then Present (Renamed_Object (Entity (N)))
3238       then
3239          return Is_Ref_To_Bit_Packed_Array (Renamed_Object (Entity (N)));
3240       end if;
3241
3242       if Nkind (N) = N_Indexed_Component
3243            or else
3244          Nkind (N) = N_Selected_Component
3245       then
3246          if Is_Bit_Packed_Array (Etype (Prefix (N))) then
3247             Result := True;
3248          else
3249             Result := Is_Ref_To_Bit_Packed_Array (Prefix (N));
3250          end if;
3251
3252          if Result and then Nkind (N) = N_Indexed_Component then
3253             Expr := First (Expressions (N));
3254             while Present (Expr) loop
3255                Force_Evaluation (Expr);
3256                Next (Expr);
3257             end loop;
3258          end if;
3259
3260          return Result;
3261
3262       else
3263          return False;
3264       end if;
3265    end Is_Ref_To_Bit_Packed_Array;
3266
3267    --------------------------------
3268    -- Is_Ref_To_Bit_Packed_Slice --
3269    --------------------------------
3270
3271    function Is_Ref_To_Bit_Packed_Slice (N : Node_Id) return Boolean is
3272    begin
3273       if Nkind (N) = N_Type_Conversion then
3274          return Is_Ref_To_Bit_Packed_Slice (Expression (N));
3275
3276       elsif Is_Entity_Name (N)
3277         and then Is_Object (Entity (N))
3278         and then Present (Renamed_Object (Entity (N)))
3279       then
3280          return Is_Ref_To_Bit_Packed_Slice (Renamed_Object (Entity (N)));
3281
3282       elsif Nkind (N) = N_Slice
3283         and then Is_Bit_Packed_Array (Etype (Prefix (N)))
3284       then
3285          return True;
3286
3287       elsif Nkind (N) = N_Indexed_Component
3288            or else
3289          Nkind (N) = N_Selected_Component
3290       then
3291          return Is_Ref_To_Bit_Packed_Slice (Prefix (N));
3292
3293       else
3294          return False;
3295       end if;
3296    end Is_Ref_To_Bit_Packed_Slice;
3297
3298    -----------------------
3299    -- Is_Renamed_Object --
3300    -----------------------
3301
3302    function Is_Renamed_Object (N : Node_Id) return Boolean is
3303       Pnod : constant Node_Id   := Parent (N);
3304       Kind : constant Node_Kind := Nkind (Pnod);
3305
3306    begin
3307       if Kind = N_Object_Renaming_Declaration then
3308          return True;
3309
3310       elsif Kind = N_Indexed_Component
3311         or else Kind = N_Selected_Component
3312       then
3313          return Is_Renamed_Object (Pnod);
3314
3315       else
3316          return False;
3317       end if;
3318    end Is_Renamed_Object;
3319
3320    ----------------------------
3321    -- Is_Untagged_Derivation --
3322    ----------------------------
3323
3324    function Is_Untagged_Derivation (T : Entity_Id) return Boolean is
3325    begin
3326       return (not Is_Tagged_Type (T) and then Is_Derived_Type (T))
3327                or else
3328              (Is_Private_Type (T) and then Present (Full_View (T))
3329                and then not Is_Tagged_Type (Full_View (T))
3330                and then Is_Derived_Type (Full_View (T))
3331                and then Etype (Full_View (T)) /= T);
3332    end Is_Untagged_Derivation;
3333
3334    ---------------------------
3335    -- Is_Volatile_Reference --
3336    ---------------------------
3337
3338    function Is_Volatile_Reference (N : Node_Id) return Boolean is
3339    begin
3340       if Nkind (N) in N_Has_Etype
3341         and then Present (Etype (N))
3342         and then Treat_As_Volatile (Etype (N))
3343       then
3344          return True;
3345
3346       elsif Is_Entity_Name (N) then
3347          return Treat_As_Volatile (Entity (N));
3348
3349       elsif Nkind (N) = N_Slice then
3350          return Is_Volatile_Reference (Prefix (N));
3351
3352       elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
3353          if (Is_Entity_Name (Prefix (N))
3354                and then Has_Volatile_Components (Entity (Prefix (N))))
3355            or else (Present (Etype (Prefix (N)))
3356                       and then Has_Volatile_Components (Etype (Prefix (N))))
3357          then
3358             return True;
3359          else
3360             return Is_Volatile_Reference (Prefix (N));
3361          end if;
3362
3363       else
3364          return False;
3365       end if;
3366    end Is_Volatile_Reference;
3367
3368    --------------------
3369    -- Kill_Dead_Code --
3370    --------------------
3371
3372    procedure Kill_Dead_Code (N : Node_Id; Warn : Boolean := False) is
3373    begin
3374       if Present (N) then
3375          Remove_Warning_Messages (N);
3376
3377          if Warn then
3378             Error_Msg_F
3379               ("?this code can never be executed and has been deleted!", N);
3380          end if;
3381
3382          --  Recurse into block statements and bodies to process declarations
3383          --  and statements
3384
3385          if Nkind (N) = N_Block_Statement
3386            or else Nkind (N) = N_Subprogram_Body
3387            or else Nkind (N) = N_Package_Body
3388          then
3389             Kill_Dead_Code (Declarations (N), False);
3390             Kill_Dead_Code (Statements (Handled_Statement_Sequence (N)));
3391
3392             if Nkind (N) = N_Subprogram_Body then
3393                Set_Is_Eliminated (Defining_Entity (N));
3394             end if;
3395
3396          elsif Nkind (N) = N_Package_Declaration then
3397             Kill_Dead_Code (Visible_Declarations (Specification (N)));
3398             Kill_Dead_Code (Private_Declarations (Specification (N)));
3399
3400             --  ??? After this point, Delete_Tree has been called on all
3401             --  declarations in Specification (N), so references to
3402             --  entities therein look suspicious.
3403
3404             declare
3405                E : Entity_Id := First_Entity (Defining_Entity (N));
3406             begin
3407                while Present (E) loop
3408                   if Ekind (E) = E_Operator then
3409                      Set_Is_Eliminated (E);
3410                   end if;
3411
3412                   Next_Entity (E);
3413                end loop;
3414             end;
3415
3416          --  Recurse into composite statement to kill individual statements,
3417          --  in particular instantiations.
3418
3419          elsif Nkind (N) = N_If_Statement then
3420             Kill_Dead_Code (Then_Statements (N));
3421             Kill_Dead_Code (Elsif_Parts (N));
3422             Kill_Dead_Code (Else_Statements (N));
3423
3424          elsif Nkind (N) = N_Loop_Statement then
3425             Kill_Dead_Code (Statements (N));
3426
3427          elsif Nkind (N) = N_Case_Statement then
3428             declare
3429                Alt : Node_Id;
3430             begin
3431                Alt := First (Alternatives (N));
3432                while Present (Alt) loop
3433                   Kill_Dead_Code (Statements (Alt));
3434                   Next (Alt);
3435                end loop;
3436             end;
3437
3438          elsif Nkind (N) = N_Case_Statement_Alternative then
3439             Kill_Dead_Code (Statements (N));
3440
3441          --  Deal with dead instances caused by deleting instantiations
3442
3443          elsif Nkind (N) in N_Generic_Instantiation then
3444             Remove_Dead_Instance (N);
3445          end if;
3446       end if;
3447    end Kill_Dead_Code;
3448
3449    --  Case where argument is a list of nodes to be killed
3450
3451    procedure Kill_Dead_Code (L : List_Id; Warn : Boolean := False) is
3452       N : Node_Id;
3453       W : Boolean;
3454    begin
3455       W := Warn;
3456       if Is_Non_Empty_List (L) then
3457          N := First (L);
3458          while Present (N) loop
3459             Kill_Dead_Code (N, W);
3460             W := False;
3461             Next (N);
3462          end loop;
3463       end if;
3464    end Kill_Dead_Code;
3465
3466    ------------------------
3467    -- Known_Non_Negative --
3468    ------------------------
3469
3470    function Known_Non_Negative (Opnd : Node_Id) return Boolean is
3471    begin
3472       if Is_OK_Static_Expression (Opnd)
3473         and then Expr_Value (Opnd) >= 0
3474       then
3475          return True;
3476
3477       else
3478          declare
3479             Lo : constant Node_Id := Type_Low_Bound (Etype (Opnd));
3480
3481          begin
3482             return
3483               Is_OK_Static_Expression (Lo) and then Expr_Value (Lo) >= 0;
3484          end;
3485       end if;
3486    end Known_Non_Negative;
3487
3488    --------------------
3489    -- Known_Non_Null --
3490    --------------------
3491
3492    function Known_Non_Null (N : Node_Id) return Boolean is
3493    begin
3494       --  Checks for case where N is an entity reference
3495
3496       if Is_Entity_Name (N) and then Present (Entity (N)) then
3497          declare
3498             E   : constant Entity_Id := Entity (N);
3499             Op  : Node_Kind;
3500             Val : Node_Id;
3501
3502          begin
3503             --  First check if we are in decisive conditional
3504
3505             Get_Current_Value_Condition (N, Op, Val);
3506
3507             if Known_Null (Val) then
3508                if Op = N_Op_Eq then
3509                   return False;
3510                elsif Op = N_Op_Ne then
3511                   return True;
3512                end if;
3513             end if;
3514
3515             --  If OK to do replacement, test Is_Known_Non_Null flag
3516
3517             if OK_To_Do_Constant_Replacement (E) then
3518                return Is_Known_Non_Null (E);
3519
3520             --  Otherwise if not safe to do replacement, then say so
3521
3522             else
3523                return False;
3524             end if;
3525          end;
3526
3527       --  True if access attribute
3528
3529       elsif Nkind (N) = N_Attribute_Reference
3530         and then (Attribute_Name (N) = Name_Access
3531                     or else
3532                   Attribute_Name (N) = Name_Unchecked_Access
3533                     or else
3534                   Attribute_Name (N) = Name_Unrestricted_Access)
3535       then
3536          return True;
3537
3538       --  True if allocator
3539
3540       elsif Nkind (N) = N_Allocator then
3541          return True;
3542
3543       --  For a conversion, true if expression is known non-null
3544
3545       elsif Nkind (N) = N_Type_Conversion then
3546          return Known_Non_Null (Expression (N));
3547
3548       --  Above are all cases where the value could be determined to be
3549       --  non-null. In all other cases, we don't know, so return False.
3550
3551       else
3552          return False;
3553       end if;
3554    end Known_Non_Null;
3555
3556    ----------------
3557    -- Known_Null --
3558    ----------------
3559
3560    function Known_Null (N : Node_Id) return Boolean is
3561    begin
3562       --  Checks for case where N is an entity reference
3563
3564       if Is_Entity_Name (N) and then Present (Entity (N)) then
3565          declare
3566             E   : constant Entity_Id := Entity (N);
3567             Op  : Node_Kind;
3568             Val : Node_Id;
3569
3570          begin
3571             --  Constant null value is for sure null
3572
3573             if Ekind (E) = E_Constant
3574               and then Known_Null (Constant_Value (E))
3575             then
3576                return True;
3577             end if;
3578
3579             --  First check if we are in decisive conditional
3580
3581             Get_Current_Value_Condition (N, Op, Val);
3582
3583             if Known_Null (Val) then
3584                if Op = N_Op_Eq then
3585                   return True;
3586                elsif Op = N_Op_Ne then
3587                   return False;
3588                end if;
3589             end if;
3590
3591             --  If OK to do replacement, test Is_Known_Null flag
3592
3593             if OK_To_Do_Constant_Replacement (E) then
3594                return Is_Known_Null (E);
3595
3596             --  Otherwise if not safe to do replacement, then say so
3597
3598             else
3599                return False;
3600             end if;
3601          end;
3602
3603       --  True if explicit reference to null
3604
3605       elsif Nkind (N) = N_Null then
3606          return True;
3607
3608       --  For a conversion, true if expression is known null
3609
3610       elsif Nkind (N) = N_Type_Conversion then
3611          return Known_Null (Expression (N));
3612
3613       --  Above are all cases where the value could be determined to be null.
3614       --  In all other cases, we don't know, so return False.
3615
3616       else
3617          return False;
3618       end if;
3619    end Known_Null;
3620
3621    -----------------------------
3622    -- Make_CW_Equivalent_Type --
3623    -----------------------------
3624
3625    --  Create a record type used as an equivalent of any member
3626    --  of the class which takes its size from exp.
3627
3628    --  Generate the following code:
3629
3630    --   type Equiv_T is record
3631    --     _parent :  T (List of discriminant constraints taken from Exp);
3632    --     Ext__50 : Storage_Array (1 .. (Exp'size - Typ'object_size)/8);
3633    --   end Equiv_T;
3634    --
3635    --   ??? Note that this type does not guarantee same alignment as all
3636    --   derived types
3637
3638    function Make_CW_Equivalent_Type
3639      (T : Entity_Id;
3640       E : Node_Id) return Entity_Id
3641    is
3642       Loc         : constant Source_Ptr := Sloc (E);
3643       Root_Typ    : constant Entity_Id  := Root_Type (T);
3644       List_Def    : constant List_Id    := Empty_List;
3645       Comp_List   : constant List_Id    := New_List;
3646       Equiv_Type  : Entity_Id;
3647       Range_Type  : Entity_Id;
3648       Str_Type    : Entity_Id;
3649       Constr_Root : Entity_Id;
3650       Sizexpr     : Node_Id;
3651
3652    begin
3653       if not Has_Discriminants (Root_Typ) then
3654          Constr_Root := Root_Typ;
3655       else
3656          Constr_Root :=
3657            Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
3658
3659          --  subtype cstr__n is T (List of discr constraints taken from Exp)
3660
3661          Append_To (List_Def,
3662            Make_Subtype_Declaration (Loc,
3663              Defining_Identifier => Constr_Root,
3664                Subtype_Indication =>
3665                  Make_Subtype_From_Expr (E, Root_Typ)));
3666       end if;
3667
3668       --  Generate the range subtype declaration
3669
3670       Range_Type := Make_Defining_Identifier (Loc, New_Internal_Name ('G'));
3671
3672       if not Is_Interface (Root_Typ) then
3673          --  subtype rg__xx is
3674          --    Storage_Offset range 1 .. (Expr'size - typ'size) / Storage_Unit
3675
3676          Sizexpr :=
3677            Make_Op_Subtract (Loc,
3678              Left_Opnd =>
3679                Make_Attribute_Reference (Loc,
3680                  Prefix =>
3681                    OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
3682                  Attribute_Name => Name_Size),
3683              Right_Opnd =>
3684                Make_Attribute_Reference (Loc,
3685                  Prefix => New_Reference_To (Constr_Root, Loc),
3686                  Attribute_Name => Name_Object_Size));
3687       else
3688          --  subtype rg__xx is
3689          --    Storage_Offset range 1 .. Expr'size / Storage_Unit
3690
3691          Sizexpr :=
3692            Make_Attribute_Reference (Loc,
3693              Prefix =>
3694                OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
3695              Attribute_Name => Name_Size);
3696       end if;
3697
3698       Set_Paren_Count (Sizexpr, 1);
3699
3700       Append_To (List_Def,
3701         Make_Subtype_Declaration (Loc,
3702           Defining_Identifier => Range_Type,
3703           Subtype_Indication =>
3704             Make_Subtype_Indication (Loc,
3705               Subtype_Mark => New_Reference_To (RTE (RE_Storage_Offset), Loc),
3706               Constraint => Make_Range_Constraint (Loc,
3707                 Range_Expression =>
3708                   Make_Range (Loc,
3709                     Low_Bound => Make_Integer_Literal (Loc, 1),
3710                     High_Bound =>
3711                       Make_Op_Divide (Loc,
3712                         Left_Opnd => Sizexpr,
3713                         Right_Opnd => Make_Integer_Literal (Loc,
3714                             Intval => System_Storage_Unit)))))));
3715
3716       --  subtype str__nn is Storage_Array (rg__x);
3717
3718       Str_Type := Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
3719       Append_To (List_Def,
3720         Make_Subtype_Declaration (Loc,
3721           Defining_Identifier => Str_Type,
3722           Subtype_Indication =>
3723             Make_Subtype_Indication (Loc,
3724               Subtype_Mark => New_Reference_To (RTE (RE_Storage_Array), Loc),
3725               Constraint =>
3726                 Make_Index_Or_Discriminant_Constraint (Loc,
3727                   Constraints =>
3728                     New_List (New_Reference_To (Range_Type, Loc))))));
3729
3730       --  type Equiv_T is record
3731       --    [ _parent : Tnn; ]
3732       --    E : Str_Type;
3733       --  end Equiv_T;
3734
3735       Equiv_Type := Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
3736
3737       --  When the target requires front-end layout, it's necessary to allow
3738       --  the equivalent type to be frozen so that layout can occur (when the
3739       --  associated class-wide subtype is frozen, the equivalent type will
3740       --  be frozen, see freeze.adb). For other targets, Gigi wants to have
3741       --  the equivalent type marked as frozen and deals with this type itself.
3742       --  In the Gigi case this will also avoid the generation of an init
3743       --  procedure for the type.
3744
3745       if not Frontend_Layout_On_Target then
3746          Set_Is_Frozen (Equiv_Type);
3747       end if;
3748
3749       Set_Ekind (Equiv_Type, E_Record_Type);
3750       Set_Parent_Subtype (Equiv_Type, Constr_Root);
3751
3752       if not Is_Interface (Root_Typ) then
3753          Append_To (Comp_List,
3754            Make_Component_Declaration (Loc,
3755              Defining_Identifier =>
3756                Make_Defining_Identifier (Loc, Name_uParent),
3757              Component_Definition =>
3758                Make_Component_Definition (Loc,
3759                  Aliased_Present    => False,
3760                  Subtype_Indication => New_Reference_To (Constr_Root, Loc))));
3761       end if;
3762
3763       Append_To (Comp_List,
3764         Make_Component_Declaration (Loc,
3765           Defining_Identifier =>
3766             Make_Defining_Identifier (Loc,
3767               Chars => New_Internal_Name ('C')),
3768           Component_Definition =>
3769             Make_Component_Definition (Loc,
3770               Aliased_Present    => False,
3771               Subtype_Indication => New_Reference_To (Str_Type, Loc))));
3772
3773       Append_To (List_Def,
3774         Make_Full_Type_Declaration (Loc,
3775           Defining_Identifier => Equiv_Type,
3776           Type_Definition =>
3777             Make_Record_Definition (Loc,
3778               Component_List =>
3779                 Make_Component_List (Loc,
3780                   Component_Items => Comp_List,
3781                   Variant_Part    => Empty))));
3782
3783       --  Suppress all checks during the analysis of the expanded code
3784       --  to avoid the generation of spurious warnings under ZFP run-time.
3785
3786       Insert_Actions (E, List_Def, Suppress => All_Checks);
3787       return Equiv_Type;
3788    end Make_CW_Equivalent_Type;
3789
3790    ------------------------
3791    -- Make_Literal_Range --
3792    ------------------------
3793
3794    function Make_Literal_Range
3795      (Loc         : Source_Ptr;
3796       Literal_Typ : Entity_Id) return Node_Id
3797    is
3798       Lo          : constant Node_Id :=
3799                       New_Copy_Tree (String_Literal_Low_Bound (Literal_Typ));
3800       Index       : constant Entity_Id := Etype (Lo);
3801
3802       Hi          : Node_Id;
3803       Length_Expr : constant Node_Id :=
3804                       Make_Op_Subtract (Loc,
3805                         Left_Opnd =>
3806                           Make_Integer_Literal (Loc,
3807                             Intval => String_Literal_Length (Literal_Typ)),
3808                         Right_Opnd =>
3809                           Make_Integer_Literal (Loc, 1));
3810
3811    begin
3812       Set_Analyzed (Lo, False);
3813
3814          if Is_Integer_Type (Index) then
3815             Hi :=
3816               Make_Op_Add (Loc,
3817                 Left_Opnd  => New_Copy_Tree (Lo),
3818                 Right_Opnd => Length_Expr);
3819          else
3820             Hi :=
3821               Make_Attribute_Reference (Loc,
3822                 Attribute_Name => Name_Val,
3823                 Prefix => New_Occurrence_Of (Index, Loc),
3824                 Expressions => New_List (
3825                  Make_Op_Add (Loc,
3826                    Left_Opnd =>
3827                      Make_Attribute_Reference (Loc,
3828                        Attribute_Name => Name_Pos,
3829                        Prefix => New_Occurrence_Of (Index, Loc),
3830                        Expressions => New_List (New_Copy_Tree (Lo))),
3831                   Right_Opnd => Length_Expr)));
3832          end if;
3833
3834          return
3835            Make_Range (Loc,
3836              Low_Bound  => Lo,
3837              High_Bound => Hi);
3838    end Make_Literal_Range;
3839
3840    --------------------------
3841    -- Make_Non_Empty_Check --
3842    --------------------------
3843
3844    function Make_Non_Empty_Check
3845      (Loc : Source_Ptr;
3846       N   : Node_Id) return Node_Id
3847    is
3848    begin
3849       return
3850         Make_Op_Ne (Loc,
3851           Left_Opnd =>
3852             Make_Attribute_Reference (Loc,
3853               Attribute_Name => Name_Length,
3854               Prefix => Duplicate_Subexpr_No_Checks (N, Name_Req => True)),
3855           Right_Opnd =>
3856             Make_Integer_Literal (Loc, 0));
3857    end Make_Non_Empty_Check;
3858
3859    ----------------------------
3860    -- Make_Subtype_From_Expr --
3861    ----------------------------
3862
3863    --  1. If Expr is an unconstrained array expression, creates
3864    --    Unc_Type(Expr'first(1)..Expr'last(1),..., Expr'first(n)..Expr'last(n))
3865
3866    --  2. If Expr is a unconstrained discriminated type expression, creates
3867    --    Unc_Type(Expr.Discr1, ... , Expr.Discr_n)
3868
3869    --  3. If Expr is class-wide, creates an implicit class wide subtype
3870
3871    function Make_Subtype_From_Expr
3872      (E       : Node_Id;
3873       Unc_Typ : Entity_Id) return Node_Id
3874    is
3875       Loc         : constant Source_Ptr := Sloc (E);
3876       List_Constr : constant List_Id    := New_List;
3877       D           : Entity_Id;
3878
3879       Full_Subtyp  : Entity_Id;
3880       Priv_Subtyp  : Entity_Id;
3881       Utyp         : Entity_Id;
3882       Full_Exp     : Node_Id;
3883
3884    begin
3885       if Is_Private_Type (Unc_Typ)
3886         and then Has_Unknown_Discriminants (Unc_Typ)
3887       then
3888          --  Prepare the subtype completion, Go to base type to
3889          --  find underlying type, because the type may be a generic
3890          --  actual or an explicit subtype.
3891
3892          Utyp        := Underlying_Type (Base_Type (Unc_Typ));
3893          Full_Subtyp := Make_Defining_Identifier (Loc,
3894                           New_Internal_Name ('C'));
3895          Full_Exp    :=
3896            Unchecked_Convert_To
3897              (Utyp, Duplicate_Subexpr_No_Checks (E));
3898          Set_Parent (Full_Exp, Parent (E));
3899
3900          Priv_Subtyp :=
3901            Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
3902
3903          Insert_Action (E,
3904            Make_Subtype_Declaration (Loc,
3905              Defining_Identifier => Full_Subtyp,
3906              Subtype_Indication  => Make_Subtype_From_Expr (Full_Exp, Utyp)));
3907
3908          --  Define the dummy private subtype
3909
3910          Set_Ekind          (Priv_Subtyp, Subtype_Kind (Ekind (Unc_Typ)));
3911          Set_Etype          (Priv_Subtyp, Base_Type (Unc_Typ));
3912          Set_Scope          (Priv_Subtyp, Full_Subtyp);
3913          Set_Is_Constrained (Priv_Subtyp);
3914          Set_Is_Tagged_Type (Priv_Subtyp, Is_Tagged_Type (Unc_Typ));
3915          Set_Is_Itype       (Priv_Subtyp);
3916          Set_Associated_Node_For_Itype (Priv_Subtyp, E);
3917
3918          if Is_Tagged_Type  (Priv_Subtyp) then
3919             Set_Class_Wide_Type
3920               (Base_Type (Priv_Subtyp), Class_Wide_Type (Unc_Typ));
3921             Set_Primitive_Operations (Priv_Subtyp,
3922               Primitive_Operations (Unc_Typ));
3923          end if;
3924
3925          Set_Full_View (Priv_Subtyp, Full_Subtyp);
3926
3927          return New_Reference_To (Priv_Subtyp, Loc);
3928
3929       elsif Is_Array_Type (Unc_Typ) then
3930          for J in 1 .. Number_Dimensions (Unc_Typ) loop
3931             Append_To (List_Constr,
3932               Make_Range (Loc,
3933                 Low_Bound =>
3934                   Make_Attribute_Reference (Loc,
3935                     Prefix => Duplicate_Subexpr_No_Checks (E),
3936                     Attribute_Name => Name_First,
3937                     Expressions => New_List (
3938                       Make_Integer_Literal (Loc, J))),
3939
3940                 High_Bound =>
3941                   Make_Attribute_Reference (Loc,
3942                     Prefix         => Duplicate_Subexpr_No_Checks (E),
3943                     Attribute_Name => Name_Last,
3944                     Expressions    => New_List (
3945                       Make_Integer_Literal (Loc, J)))));
3946          end loop;
3947
3948       elsif Is_Class_Wide_Type (Unc_Typ) then
3949          declare
3950             CW_Subtype : Entity_Id;
3951             EQ_Typ     : Entity_Id := Empty;
3952
3953          begin
3954             --  A class-wide equivalent type is not needed when VM_Target
3955             --  because the VM back-ends handle the class-wide object
3956             --  initialization itself (and doesn't need or want the
3957             --  additional intermediate type to handle the assignment).
3958
3959             if Expander_Active and then Tagged_Type_Expansion then
3960                EQ_Typ := Make_CW_Equivalent_Type (Unc_Typ, E);
3961             end if;
3962
3963             CW_Subtype := New_Class_Wide_Subtype (Unc_Typ, E);
3964             Set_Equivalent_Type (CW_Subtype, EQ_Typ);
3965
3966             if Present (EQ_Typ) then
3967                Set_Is_Class_Wide_Equivalent_Type (EQ_Typ);
3968             end if;
3969
3970             Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ));
3971
3972             return New_Occurrence_Of (CW_Subtype, Loc);
3973          end;
3974
3975       --  Indefinite record type with discriminants
3976
3977       else
3978          D := First_Discriminant (Unc_Typ);
3979          while Present (D) loop
3980             Append_To (List_Constr,
3981               Make_Selected_Component (Loc,
3982                 Prefix        => Duplicate_Subexpr_No_Checks (E),
3983                 Selector_Name => New_Reference_To (D, Loc)));
3984
3985             Next_Discriminant (D);
3986          end loop;
3987       end if;
3988
3989       return
3990         Make_Subtype_Indication (Loc,
3991           Subtype_Mark => New_Reference_To (Unc_Typ, Loc),
3992           Constraint   =>
3993             Make_Index_Or_Discriminant_Constraint (Loc,
3994               Constraints => List_Constr));
3995    end Make_Subtype_From_Expr;
3996
3997    -----------------------------
3998    -- May_Generate_Large_Temp --
3999    -----------------------------
4000
4001    --  At the current time, the only types that we return False for (i.e.
4002    --  where we decide we know they cannot generate large temps) are ones
4003    --  where we know the size is 256 bits or less at compile time, and we
4004    --  are still not doing a thorough job on arrays and records ???
4005
4006    function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is
4007    begin
4008       if not Size_Known_At_Compile_Time (Typ) then
4009          return False;
4010
4011       elsif Esize (Typ) /= 0 and then Esize (Typ) <= 256 then
4012          return False;
4013
4014       elsif Is_Array_Type (Typ)
4015         and then Present (Packed_Array_Type (Typ))
4016       then
4017          return May_Generate_Large_Temp (Packed_Array_Type (Typ));
4018
4019       --  We could do more here to find other small types ???
4020
4021       else
4022          return True;
4023       end if;
4024    end May_Generate_Large_Temp;
4025
4026    ----------------------------
4027    -- New_Class_Wide_Subtype --
4028    ----------------------------
4029
4030    function New_Class_Wide_Subtype
4031      (CW_Typ : Entity_Id;
4032       N      : Node_Id) return Entity_Id
4033    is
4034       Res       : constant Entity_Id := Create_Itype (E_Void, N);
4035       Res_Name  : constant Name_Id   := Chars (Res);
4036       Res_Scope : constant Entity_Id := Scope (Res);
4037
4038    begin
4039       Copy_Node (CW_Typ, Res);
4040       Set_Comes_From_Source (Res, False);
4041       Set_Sloc (Res, Sloc (N));
4042       Set_Is_Itype (Res);
4043       Set_Associated_Node_For_Itype (Res, N);
4044       Set_Is_Public (Res, False);   --  By default, may be changed below.
4045       Set_Public_Status (Res);
4046       Set_Chars (Res, Res_Name);
4047       Set_Scope (Res, Res_Scope);
4048       Set_Ekind (Res, E_Class_Wide_Subtype);
4049       Set_Next_Entity (Res, Empty);
4050       Set_Etype (Res, Base_Type (CW_Typ));
4051
4052       --  For targets where front-end layout is required, reset the Is_Frozen
4053       --  status of the subtype to False (it can be implicitly set to true
4054       --  from the copy of the class-wide type). For other targets, Gigi
4055       --  doesn't want the class-wide subtype to go through the freezing
4056       --  process (though it's unclear why that causes problems and it would
4057       --  be nice to allow freezing to occur normally for all targets ???).
4058
4059       if Frontend_Layout_On_Target then
4060          Set_Is_Frozen (Res, False);
4061       end if;
4062
4063       Set_Freeze_Node (Res, Empty);
4064       return (Res);
4065    end New_Class_Wide_Subtype;
4066
4067    --------------------------------
4068    -- Non_Limited_Designated_Type --
4069    ---------------------------------
4070
4071    function Non_Limited_Designated_Type (T : Entity_Id) return Entity_Id is
4072       Desig : constant Entity_Id := Designated_Type (T);
4073    begin
4074       if Ekind (Desig) = E_Incomplete_Type
4075         and then Present (Non_Limited_View (Desig))
4076       then
4077          return Non_Limited_View (Desig);
4078       else
4079          return Desig;
4080       end if;
4081    end Non_Limited_Designated_Type;
4082
4083    -----------------------------------
4084    -- OK_To_Do_Constant_Replacement --
4085    -----------------------------------
4086
4087    function OK_To_Do_Constant_Replacement (E : Entity_Id) return Boolean is
4088       ES : constant Entity_Id := Scope (E);
4089       CS : Entity_Id;
4090
4091    begin
4092       --  Do not replace statically allocated objects, because they may be
4093       --  modified outside the current scope.
4094
4095       if Is_Statically_Allocated (E) then
4096          return False;
4097
4098       --  Do not replace aliased or volatile objects, since we don't know what
4099       --  else might change the value.
4100
4101       elsif Is_Aliased (E) or else Treat_As_Volatile (E) then
4102          return False;
4103
4104       --  Debug flag -gnatdM disconnects this optimization
4105
4106       elsif Debug_Flag_MM then
4107          return False;
4108
4109       --  Otherwise check scopes
4110
4111       else
4112          CS := Current_Scope;
4113
4114          loop
4115             --  If we are in right scope, replacement is safe
4116
4117             if CS = ES then
4118                return True;
4119
4120             --  Packages do not affect the determination of safety
4121
4122             elsif Ekind (CS) = E_Package then
4123                exit when CS = Standard_Standard;
4124                CS := Scope (CS);
4125
4126             --  Blocks do not affect the determination of safety
4127
4128             elsif Ekind (CS) = E_Block then
4129                CS := Scope (CS);
4130
4131             --  Loops do not affect the determination of safety. Note that we
4132             --  kill all current values on entry to a loop, so we are just
4133             --  talking about processing within a loop here.
4134
4135             elsif Ekind (CS) = E_Loop then
4136                CS := Scope (CS);
4137
4138             --  Otherwise, the reference is dubious, and we cannot be sure that
4139             --  it is safe to do the replacement.
4140
4141             else
4142                exit;
4143             end if;
4144          end loop;
4145
4146          return False;
4147       end if;
4148    end OK_To_Do_Constant_Replacement;
4149
4150    ------------------------------------
4151    -- Possible_Bit_Aligned_Component --
4152    ------------------------------------
4153
4154    function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is
4155    begin
4156       case Nkind (N) is
4157
4158          --  Case of indexed component
4159
4160          when N_Indexed_Component =>
4161             declare
4162                P    : constant Node_Id   := Prefix (N);
4163                Ptyp : constant Entity_Id := Etype (P);
4164
4165             begin
4166                --  If we know the component size and it is less than 64, then
4167                --  we are definitely OK. The back end always does assignment of
4168                --  misaligned small objects correctly.
4169
4170                if Known_Static_Component_Size (Ptyp)
4171                  and then Component_Size (Ptyp) <= 64
4172                then
4173                   return False;
4174
4175                --  Otherwise, we need to test the prefix, to see if we are
4176                --  indexing from a possibly unaligned component.
4177
4178                else
4179                   return Possible_Bit_Aligned_Component (P);
4180                end if;
4181             end;
4182
4183          --  Case of selected component
4184
4185          when N_Selected_Component =>
4186             declare
4187                P    : constant Node_Id   := Prefix (N);
4188                Comp : constant Entity_Id := Entity (Selector_Name (N));
4189
4190             begin
4191                --  If there is no component clause, then we are in the clear
4192                --  since the back end will never misalign a large component
4193                --  unless it is forced to do so. In the clear means we need
4194                --  only the recursive test on the prefix.
4195
4196                if Component_May_Be_Bit_Aligned (Comp) then
4197                   return True;
4198                else
4199                   return Possible_Bit_Aligned_Component (P);
4200                end if;
4201             end;
4202
4203          --  For a slice, test the prefix, if that is possibly misaligned,
4204          --  then for sure the slice is!
4205
4206          when N_Slice =>
4207             return Possible_Bit_Aligned_Component (Prefix (N));
4208
4209          --  If we have none of the above, it means that we have fallen off the
4210          --  top testing prefixes recursively, and we now have a stand alone
4211          --  object, where we don't have a problem.
4212
4213          when others =>
4214             return False;
4215
4216       end case;
4217    end Possible_Bit_Aligned_Component;
4218
4219    -------------------------
4220    -- Remove_Side_Effects --
4221    -------------------------
4222
4223    procedure Remove_Side_Effects
4224      (Exp          : Node_Id;
4225       Name_Req     : Boolean := False;
4226       Variable_Ref : Boolean := False)
4227    is
4228       Loc          : constant Source_Ptr     := Sloc (Exp);
4229       Exp_Type     : constant Entity_Id      := Etype (Exp);
4230       Svg_Suppress : constant Suppress_Array := Scope_Suppress;
4231       Def_Id       : Entity_Id;
4232       Ref_Type     : Entity_Id;
4233       Res          : Node_Id;
4234       Ptr_Typ_Decl : Node_Id;
4235       New_Exp      : Node_Id;
4236       E            : Node_Id;
4237
4238       function Side_Effect_Free (N : Node_Id) return Boolean;
4239       --  Determines if the tree N represents an expression that is known not
4240       --  to have side effects, and for which no processing is required.
4241
4242       function Side_Effect_Free (L : List_Id) return Boolean;
4243       --  Determines if all elements of the list L are side effect free
4244
4245       function Safe_Prefixed_Reference (N : Node_Id) return Boolean;
4246       --  The argument N is a construct where the Prefix is dereferenced if it
4247       --  is an access type and the result is a variable. The call returns True
4248       --  if the construct is side effect free (not considering side effects in
4249       --  other than the prefix which are to be tested by the caller).
4250
4251       function Within_In_Parameter (N : Node_Id) return Boolean;
4252       --  Determines if N is a subcomponent of a composite in-parameter. If so,
4253       --  N is not side-effect free when the actual is global and modifiable
4254       --  indirectly from within a subprogram, because it may be passed by
4255       --  reference. The front-end must be conservative here and assume that
4256       --  this may happen with any array or record type. On the other hand, we
4257       --  cannot create temporaries for all expressions for which this
4258       --  condition is true, for various reasons that might require clearing up
4259       --  ??? For example, discriminant references that appear out of place, or
4260       --  spurious type errors with class-wide expressions. As a result, we
4261       --  limit the transformation to loop bounds, which is so far the only
4262       --  case that requires it.
4263
4264       -----------------------------
4265       -- Safe_Prefixed_Reference --
4266       -----------------------------
4267
4268       function Safe_Prefixed_Reference (N : Node_Id) return Boolean is
4269       begin
4270          --  If prefix is not side effect free, definitely not safe
4271
4272          if not Side_Effect_Free (Prefix (N)) then
4273             return False;
4274
4275          --  If the prefix is of an access type that is not access-to-constant,
4276          --  then this construct is a variable reference, which means it is to
4277          --  be considered to have side effects if Variable_Ref is set True
4278          --  Exception is an access to an entity that is a constant or an
4279          --  in-parameter which does not come from source, and is the result
4280          --  of a previous removal of side-effects.
4281
4282          elsif Is_Access_Type (Etype (Prefix (N)))
4283            and then not Is_Access_Constant (Etype (Prefix (N)))
4284            and then Variable_Ref
4285          then
4286             if not Is_Entity_Name (Prefix (N)) then
4287                return False;
4288             else
4289                return Ekind (Entity (Prefix (N))) = E_Constant
4290                  or else Ekind (Entity (Prefix (N))) = E_In_Parameter;
4291             end if;
4292
4293          --  The following test is the simplest way of solving a complex
4294          --  problem uncovered by BB08-010: Side effect on loop bound that
4295          --  is a subcomponent of a global variable:
4296          --    If a loop bound is a subcomponent of a global variable, a
4297          --    modification of that variable within the loop may incorrectly
4298          --    affect the execution of the loop.
4299
4300          elsif not
4301            (Nkind (Parent (Parent (N))) /= N_Loop_Parameter_Specification
4302               or else not Within_In_Parameter (Prefix (N)))
4303          then
4304             return False;
4305
4306          --  All other cases are side effect free
4307
4308          else
4309             return True;
4310          end if;
4311       end Safe_Prefixed_Reference;
4312
4313       ----------------------
4314       -- Side_Effect_Free --
4315       ----------------------
4316
4317       function Side_Effect_Free (N : Node_Id) return Boolean is
4318       begin
4319          --  Note on checks that could raise Constraint_Error. Strictly, if
4320          --  we take advantage of 11.6, these checks do not count as side
4321          --  effects. However, we would just as soon consider that they are
4322          --  side effects, since the backend CSE does not work very well on
4323          --  expressions which can raise Constraint_Error. On the other
4324          --  hand, if we do not consider them to be side effect free, then
4325          --  we get some awkward expansions in -gnato mode, resulting in
4326          --  code insertions at a point where we do not have a clear model
4327          --  for performing the insertions.
4328
4329          --  Special handling for entity names
4330
4331          if Is_Entity_Name (N) then
4332
4333             --  If the entity is a constant, it is definitely side effect
4334             --  free. Note that the test of Is_Variable (N) below might
4335             --  be expected to catch this case, but it does not, because
4336             --  this test goes to the original tree, and we may have
4337             --  already rewritten a variable node with a constant as
4338             --  a result of an earlier Force_Evaluation call.
4339
4340             if Ekind (Entity (N)) = E_Constant
4341               or else Ekind (Entity (N)) = E_In_Parameter
4342             then
4343                return True;
4344
4345             --  Functions are not side effect free
4346
4347             elsif Ekind (Entity (N)) = E_Function then
4348                return False;
4349
4350             --  Variables are considered to be a side effect if Variable_Ref
4351             --  is set or if we have a volatile reference and Name_Req is off.
4352             --  If Name_Req is True then we can't help returning a name which
4353             --  effectively allows multiple references in any case.
4354
4355             elsif Is_Variable (N) then
4356                return not Variable_Ref
4357                  and then (not Is_Volatile_Reference (N) or else Name_Req);
4358
4359             --  Any other entity (e.g. a subtype name) is definitely side
4360             --  effect free.
4361
4362             else
4363                return True;
4364             end if;
4365
4366          --  A value known at compile time is always side effect free
4367
4368          elsif Compile_Time_Known_Value (N) then
4369             return True;
4370
4371          --  A variable renaming is not side-effect free, because the
4372          --  renaming will function like a macro in the front-end in
4373          --  some cases, and an assignment can modify the component
4374          --  designated by N, so we need to create a temporary for it.
4375
4376          elsif Is_Entity_Name (Original_Node (N))
4377            and then Is_Renaming_Of_Object (Entity (Original_Node (N)))
4378            and then Ekind (Entity (Original_Node (N))) /= E_Constant
4379          then
4380             return False;
4381          end if;
4382
4383          --  For other than entity names and compile time known values,
4384          --  check the node kind for special processing.
4385
4386          case Nkind (N) is
4387
4388             --  An attribute reference is side effect free if its expressions
4389             --  are side effect free and its prefix is side effect free or
4390             --  is an entity reference.
4391
4392             --  Is this right? what about x'first where x is a variable???
4393
4394             when N_Attribute_Reference =>
4395                return Side_Effect_Free (Expressions (N))
4396                  and then Attribute_Name (N) /= Name_Input
4397                  and then (Is_Entity_Name (Prefix (N))
4398                             or else Side_Effect_Free (Prefix (N)));
4399
4400             --  A binary operator is side effect free if and both operands
4401             --  are side effect free. For this purpose binary operators
4402             --  include membership tests and short circuit forms
4403
4404             when N_Binary_Op | N_Membership_Test | N_Short_Circuit =>
4405                return Side_Effect_Free (Left_Opnd  (N))
4406                         and then
4407                       Side_Effect_Free (Right_Opnd (N));
4408
4409             --  An explicit dereference is side effect free only if it is
4410             --  a side effect free prefixed reference.
4411
4412             when N_Explicit_Dereference =>
4413                return Safe_Prefixed_Reference (N);
4414
4415             --  A call to _rep_to_pos is side effect free, since we generate
4416             --  this pure function call ourselves. Moreover it is critically
4417             --  important to make this exception, since otherwise we can
4418             --  have discriminants in array components which don't look
4419             --  side effect free in the case of an array whose index type
4420             --  is an enumeration type with an enumeration rep clause.
4421
4422             --  All other function calls are not side effect free
4423
4424             when N_Function_Call =>
4425                return Nkind (Name (N)) = N_Identifier
4426                  and then Is_TSS (Name (N), TSS_Rep_To_Pos)
4427                  and then
4428                    Side_Effect_Free (First (Parameter_Associations (N)));
4429
4430             --  An indexed component is side effect free if it is a side
4431             --  effect free prefixed reference and all the indexing
4432             --  expressions are side effect free.
4433
4434             when N_Indexed_Component =>
4435                return Side_Effect_Free (Expressions (N))
4436                  and then Safe_Prefixed_Reference (N);
4437
4438             --  A type qualification is side effect free if the expression
4439             --  is side effect free.
4440
4441             when N_Qualified_Expression =>
4442                return Side_Effect_Free (Expression (N));
4443
4444             --  A selected component is side effect free only if it is a
4445             --  side effect free prefixed reference. If it designates a
4446             --  component with a rep. clause it must be treated has having
4447             --  a potential side effect, because it may be modified through
4448             --  a renaming, and a subsequent use of the renaming as a macro
4449             --  will yield the wrong value. This complex interaction between
4450             --  renaming and removing side effects is a reminder that the
4451             --  latter has become a headache to maintain, and that it should
4452             --  be removed in favor of the gcc mechanism to capture values ???
4453
4454             when N_Selected_Component =>
4455                if Nkind (Parent (N)) = N_Explicit_Dereference
4456                  and then Has_Non_Standard_Rep (Designated_Type (Etype (N)))
4457                then
4458                   return False;
4459                else
4460                   return Safe_Prefixed_Reference (N);
4461                end if;
4462
4463             --  A range is side effect free if the bounds are side effect free
4464
4465             when N_Range =>
4466                return Side_Effect_Free (Low_Bound (N))
4467                  and then Side_Effect_Free (High_Bound (N));
4468
4469             --  A slice is side effect free if it is a side effect free
4470             --  prefixed reference and the bounds are side effect free.
4471
4472             when N_Slice =>
4473                return Side_Effect_Free (Discrete_Range (N))
4474                  and then Safe_Prefixed_Reference (N);
4475
4476             --  A type conversion is side effect free if the expression to be
4477             --  converted is side effect free.
4478
4479             when N_Type_Conversion =>
4480                return Side_Effect_Free (Expression (N));
4481
4482             --  A unary operator is side effect free if the operand
4483             --  is side effect free.
4484
4485             when N_Unary_Op =>
4486                return Side_Effect_Free (Right_Opnd (N));
4487
4488             --  An unchecked type conversion is side effect free only if it
4489             --  is safe and its argument is side effect free.
4490
4491             when N_Unchecked_Type_Conversion =>
4492                return Safe_Unchecked_Type_Conversion (N)
4493                  and then Side_Effect_Free (Expression (N));
4494
4495             --  An unchecked expression is side effect free if its expression
4496             --  is side effect free.
4497
4498             when N_Unchecked_Expression =>
4499                return Side_Effect_Free (Expression (N));
4500
4501             --  A literal is side effect free
4502
4503             when N_Character_Literal    |
4504                  N_Integer_Literal      |
4505                  N_Real_Literal         |
4506                  N_String_Literal       =>
4507                return True;
4508
4509             --  We consider that anything else has side effects. This is a bit
4510             --  crude, but we are pretty close for most common cases, and we
4511             --  are certainly correct (i.e. we never return True when the
4512             --  answer should be False).
4513
4514             when others =>
4515                return False;
4516          end case;
4517       end Side_Effect_Free;
4518
4519       --  A list is side effect free if all elements of the list are
4520       --  side effect free.
4521
4522       function Side_Effect_Free (L : List_Id) return Boolean is
4523          N : Node_Id;
4524
4525       begin
4526          if L = No_List or else L = Error_List then
4527             return True;
4528
4529          else
4530             N := First (L);
4531             while Present (N) loop
4532                if not Side_Effect_Free (N) then
4533                   return False;
4534                else
4535                   Next (N);
4536                end if;
4537             end loop;
4538
4539             return True;
4540          end if;
4541       end Side_Effect_Free;
4542
4543       -------------------------
4544       -- Within_In_Parameter --
4545       -------------------------
4546
4547       function Within_In_Parameter (N : Node_Id) return Boolean is
4548       begin
4549          if not Comes_From_Source (N) then
4550             return False;
4551
4552          elsif Is_Entity_Name (N) then
4553             return Ekind (Entity (N)) = E_In_Parameter;
4554
4555          elsif Nkind (N) = N_Indexed_Component
4556            or else Nkind (N) = N_Selected_Component
4557          then
4558             return Within_In_Parameter (Prefix (N));
4559          else
4560
4561             return False;
4562          end if;
4563       end Within_In_Parameter;
4564
4565    --  Start of processing for Remove_Side_Effects
4566
4567    begin
4568       --  If we are side effect free already or expansion is disabled,
4569       --  there is nothing to do.
4570
4571       if Side_Effect_Free (Exp) or else not Expander_Active then
4572          return;
4573       end if;
4574
4575       --  All this must not have any checks
4576
4577       Scope_Suppress := (others => True);
4578
4579       --  If it is a scalar type and we need to capture the value, just make
4580       --  a copy. Likewise for a function call, an attribute reference or an
4581       --  operator. And if we have a volatile reference and Name_Req is not
4582       --  set (see comments above for Side_Effect_Free).
4583
4584       if Is_Elementary_Type (Exp_Type)
4585         and then (Variable_Ref
4586                    or else Nkind (Exp) = N_Function_Call
4587                    or else Nkind (Exp) = N_Attribute_Reference
4588                    or else Nkind (Exp) in N_Op
4589                    or else (not Name_Req and then Is_Volatile_Reference (Exp)))
4590       then
4591          Def_Id := Make_Temporary (Loc, 'R', Exp);
4592          Set_Etype (Def_Id, Exp_Type);
4593          Res := New_Reference_To (Def_Id, Loc);
4594
4595          E :=
4596            Make_Object_Declaration (Loc,
4597              Defining_Identifier => Def_Id,
4598              Object_Definition   => New_Reference_To (Exp_Type, Loc),
4599              Constant_Present    => True,
4600              Expression          => Relocate_Node (Exp));
4601
4602          Set_Assignment_OK (E);
4603          Insert_Action (Exp, E);
4604
4605       --  If the expression has the form v.all then we can just capture
4606       --  the pointer, and then do an explicit dereference on the result.
4607
4608       elsif Nkind (Exp) = N_Explicit_Dereference then
4609          Def_Id := Make_Temporary (Loc, 'R', Exp);
4610          Res :=
4611            Make_Explicit_Dereference (Loc, New_Reference_To (Def_Id, Loc));
4612
4613          Insert_Action (Exp,
4614            Make_Object_Declaration (Loc,
4615              Defining_Identifier => Def_Id,
4616              Object_Definition   =>
4617                New_Reference_To (Etype (Prefix (Exp)), Loc),
4618              Constant_Present    => True,
4619              Expression          => Relocate_Node (Prefix (Exp))));
4620
4621       --  Similar processing for an unchecked conversion of an expression
4622       --  of the form v.all, where we want the same kind of treatment.
4623
4624       elsif Nkind (Exp) = N_Unchecked_Type_Conversion
4625         and then Nkind (Expression (Exp)) = N_Explicit_Dereference
4626       then
4627          Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
4628          Scope_Suppress := Svg_Suppress;
4629          return;
4630
4631       --  If this is a type conversion, leave the type conversion and remove
4632       --  the side effects in the expression. This is important in several
4633       --  circumstances: for change of representations, and also when this is
4634       --  a view conversion to a smaller object, where gigi can end up creating
4635       --  its own temporary of the wrong size.
4636
4637       elsif Nkind (Exp) = N_Type_Conversion then
4638          Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
4639          Scope_Suppress := Svg_Suppress;
4640          return;
4641
4642       --  If this is an unchecked conversion that Gigi can't handle, make
4643       --  a copy or a use a renaming to capture the value.
4644
4645       elsif Nkind (Exp) = N_Unchecked_Type_Conversion
4646         and then not Safe_Unchecked_Type_Conversion (Exp)
4647       then
4648          if CW_Or_Has_Controlled_Part (Exp_Type) then
4649
4650             --  Use a renaming to capture the expression, rather than create
4651             --  a controlled temporary.
4652
4653             Def_Id := Make_Temporary (Loc, 'R', Exp);
4654             Res := New_Reference_To (Def_Id, Loc);
4655
4656             Insert_Action (Exp,
4657               Make_Object_Renaming_Declaration (Loc,
4658                 Defining_Identifier => Def_Id,
4659                 Subtype_Mark        => New_Reference_To (Exp_Type, Loc),
4660                 Name                => Relocate_Node (Exp)));
4661
4662          else
4663             Def_Id := Make_Temporary (Loc, 'R', Exp);
4664             Set_Etype (Def_Id, Exp_Type);
4665             Res := New_Reference_To (Def_Id, Loc);
4666
4667             E :=
4668               Make_Object_Declaration (Loc,
4669                 Defining_Identifier => Def_Id,
4670                 Object_Definition   => New_Reference_To (Exp_Type, Loc),
4671                 Constant_Present    => not Is_Variable (Exp),
4672                 Expression          => Relocate_Node (Exp));
4673
4674             Set_Assignment_OK (E);
4675             Insert_Action (Exp, E);
4676          end if;
4677
4678       --  For expressions that denote objects, we can use a renaming scheme.
4679       --  We skip using this if we have a volatile reference and we do not
4680       --  have Name_Req set true (see comments above for Side_Effect_Free).
4681
4682       elsif Is_Object_Reference (Exp)
4683         and then Nkind (Exp) /= N_Function_Call
4684         and then (Name_Req or else not Is_Volatile_Reference (Exp))
4685       then
4686          Def_Id := Make_Temporary (Loc, 'R', Exp);
4687
4688          if Nkind (Exp) = N_Selected_Component
4689            and then Nkind (Prefix (Exp)) = N_Function_Call
4690            and then Is_Array_Type (Exp_Type)
4691          then
4692             --  Avoid generating a variable-sized temporary, by generating
4693             --  the renaming declaration just for the function call. The
4694             --  transformation could be refined to apply only when the array
4695             --  component is constrained by a discriminant???
4696
4697             Res :=
4698               Make_Selected_Component (Loc,
4699                 Prefix => New_Occurrence_Of (Def_Id, Loc),
4700                 Selector_Name => Selector_Name (Exp));
4701
4702             Insert_Action (Exp,
4703               Make_Object_Renaming_Declaration (Loc,
4704                 Defining_Identifier => Def_Id,
4705                 Subtype_Mark        =>
4706                   New_Reference_To (Base_Type (Etype (Prefix (Exp))), Loc),
4707                 Name                => Relocate_Node (Prefix (Exp))));
4708
4709          else
4710             Res := New_Reference_To (Def_Id, Loc);
4711
4712             Insert_Action (Exp,
4713               Make_Object_Renaming_Declaration (Loc,
4714                 Defining_Identifier => Def_Id,
4715                 Subtype_Mark        => New_Reference_To (Exp_Type, Loc),
4716                 Name                => Relocate_Node (Exp)));
4717          end if;
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 limited type.
4740          --  We need to build a declaration that will enable build-in-place
4741          --  expansion of the call. This is not done if the context is already
4742          --  an object declaration, to prevent infinite recursion.
4743
4744          --  This is relevant only in Ada 2005 mode. In Ada 95 programs we have
4745          --  to accommodate functions returning limited objects by reference.
4746
4747          if Nkind (Exp) = N_Function_Call
4748            and then Is_Inherently_Limited_Type (Etype (Exp))
4749            and then Nkind (Parent (Exp)) /= N_Object_Declaration
4750            and then Ada_Version >= Ada_05
4751          then
4752             declare
4753                Obj  : constant Entity_Id := Make_Temporary (Loc, 'F', Exp);
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                Rewrite (Exp, New_Occurrence_Of (Obj, Loc));
4765                return;
4766             end;
4767          end if;
4768
4769          Ref_Type := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
4770
4771          Ptr_Typ_Decl :=
4772            Make_Full_Type_Declaration (Loc,
4773              Defining_Identifier => Ref_Type,
4774              Type_Definition =>
4775                Make_Access_To_Object_Definition (Loc,
4776                  All_Present => True,
4777                  Subtype_Indication =>
4778                    New_Reference_To (Exp_Type, Loc)));
4779
4780          E := Exp;
4781          Insert_Action (Exp, Ptr_Typ_Decl);
4782
4783          Def_Id := Make_Temporary (Loc, 'R', Exp);
4784          Set_Etype (Def_Id, Exp_Type);
4785
4786          Res :=
4787            Make_Explicit_Dereference (Loc,
4788              Prefix => New_Reference_To (Def_Id, Loc));
4789
4790          if Nkind (E) = N_Explicit_Dereference then
4791             New_Exp := Relocate_Node (Prefix (E));
4792          else
4793             E := Relocate_Node (E);
4794             New_Exp := Make_Reference (Loc, E);
4795          end if;
4796
4797          if Is_Delayed_Aggregate (E) then
4798
4799             --  The expansion of nested aggregates is delayed until the
4800             --  enclosing aggregate is expanded. As aggregates are often
4801             --  qualified, the predicate applies to qualified expressions
4802             --  as well, indicating that the enclosing aggregate has not
4803             --  been expanded yet. At this point the aggregate is part of
4804             --  a stand-alone declaration, and must be fully expanded.
4805
4806             if Nkind (E) = N_Qualified_Expression then
4807                Set_Expansion_Delayed (Expression (E), False);
4808                Set_Analyzed (Expression (E), False);
4809             else
4810                Set_Expansion_Delayed (E, False);
4811             end if;
4812
4813             Set_Analyzed (E, False);
4814          end if;
4815
4816          Insert_Action (Exp,
4817            Make_Object_Declaration (Loc,
4818              Defining_Identifier => Def_Id,
4819              Object_Definition   => New_Reference_To (Ref_Type, Loc),
4820              Expression          => New_Exp));
4821       end if;
4822
4823       --  Preserve the Assignment_OK flag in all copies, since at least
4824       --  one copy may be used in a context where this flag must be set
4825       --  (otherwise why would the flag be set in the first place).
4826
4827       Set_Assignment_OK (Res, Assignment_OK (Exp));
4828
4829       --  Finally rewrite the original expression and we are done
4830
4831       Rewrite (Exp, Res);
4832       Analyze_And_Resolve (Exp, Exp_Type);
4833       Scope_Suppress := Svg_Suppress;
4834    end Remove_Side_Effects;
4835
4836    ---------------------------
4837    -- Represented_As_Scalar --
4838    ---------------------------
4839
4840    function Represented_As_Scalar (T : Entity_Id) return Boolean is
4841       UT : constant Entity_Id := Underlying_Type (T);
4842    begin
4843       return Is_Scalar_Type (UT)
4844         or else (Is_Bit_Packed_Array (UT)
4845                    and then Is_Scalar_Type (Packed_Array_Type (UT)));
4846    end Represented_As_Scalar;
4847
4848    ------------------------------------
4849    -- Safe_Unchecked_Type_Conversion --
4850    ------------------------------------
4851
4852    --  Note: this function knows quite a bit about the exact requirements
4853    --  of Gigi with respect to unchecked type conversions, and its code
4854    --  must be coordinated with any changes in Gigi in this area.
4855
4856    --  The above requirements should be documented in Sinfo ???
4857
4858    function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is
4859       Otyp   : Entity_Id;
4860       Ityp   : Entity_Id;
4861       Oalign : Uint;
4862       Ialign : Uint;
4863       Pexp   : constant Node_Id := Parent (Exp);
4864
4865    begin
4866       --  If the expression is the RHS of an assignment or object declaration
4867       --   we are always OK because there will always be a target.
4868
4869       --  Object renaming declarations, (generated for view conversions of
4870       --  actuals in inlined calls), like object declarations, provide an
4871       --  explicit type, and are safe as well.
4872
4873       if (Nkind (Pexp) = N_Assignment_Statement
4874            and then Expression (Pexp) = Exp)
4875         or else Nkind (Pexp) = N_Object_Declaration
4876         or else Nkind (Pexp) = N_Object_Renaming_Declaration
4877       then
4878          return True;
4879
4880       --  If the expression is the prefix of an N_Selected_Component
4881       --  we should also be OK because GCC knows to look inside the
4882       --  conversion except if the type is discriminated. We assume
4883       --  that we are OK anyway if the type is not set yet or if it is
4884       --  controlled since we can't afford to introduce a temporary in
4885       --  this case.
4886
4887       elsif Nkind (Pexp) = N_Selected_Component
4888          and then Prefix (Pexp) = Exp
4889       then
4890          if No (Etype (Pexp)) then
4891             return True;
4892          else
4893             return
4894               not Has_Discriminants (Etype (Pexp))
4895                 or else Is_Constrained (Etype (Pexp));
4896          end if;
4897       end if;
4898
4899       --  Set the output type, this comes from Etype if it is set, otherwise
4900       --  we take it from the subtype mark, which we assume was already
4901       --  fully analyzed.
4902
4903       if Present (Etype (Exp)) then
4904          Otyp := Etype (Exp);
4905       else
4906          Otyp := Entity (Subtype_Mark (Exp));
4907       end if;
4908
4909       --  The input type always comes from the expression, and we assume
4910       --  this is indeed always analyzed, so we can simply get the Etype.
4911
4912       Ityp := Etype (Expression (Exp));
4913
4914       --  Initialize alignments to unknown so far
4915
4916       Oalign := No_Uint;
4917       Ialign := No_Uint;
4918
4919       --  Replace a concurrent type by its corresponding record type
4920       --  and each type by its underlying type and do the tests on those.
4921       --  The original type may be a private type whose completion is a
4922       --  concurrent type, so find the underlying type first.
4923
4924       if Present (Underlying_Type (Otyp)) then
4925          Otyp := Underlying_Type (Otyp);
4926       end if;
4927
4928       if Present (Underlying_Type (Ityp)) then
4929          Ityp := Underlying_Type (Ityp);
4930       end if;
4931
4932       if Is_Concurrent_Type (Otyp) then
4933          Otyp := Corresponding_Record_Type (Otyp);
4934       end if;
4935
4936       if Is_Concurrent_Type (Ityp) then
4937          Ityp := Corresponding_Record_Type (Ityp);
4938       end if;
4939
4940       --  If the base types are the same, we know there is no problem since
4941       --  this conversion will be a noop.
4942
4943       if Implementation_Base_Type (Otyp) = Implementation_Base_Type (Ityp) then
4944          return True;
4945
4946       --  Same if this is an upwards conversion of an untagged type, and there
4947       --  are no constraints involved (could be more general???)
4948
4949       elsif Etype (Ityp) = Otyp
4950         and then not Is_Tagged_Type (Ityp)
4951         and then not Has_Discriminants (Ityp)
4952         and then No (First_Rep_Item (Base_Type (Ityp)))
4953       then
4954          return True;
4955
4956       --  If the expression has an access type (object or subprogram) we
4957       --  assume that the conversion is safe, because the size of the target
4958       --  is safe, even if it is a record (which might be treated as having
4959       --  unknown size at this point).
4960
4961       elsif Is_Access_Type (Ityp) then
4962          return True;
4963
4964       --  If the size of output type is known at compile time, there is
4965       --  never a problem.  Note that unconstrained records are considered
4966       --  to be of known size, but we can't consider them that way here,
4967       --  because we are talking about the actual size of the object.
4968
4969       --  We also make sure that in addition to the size being known, we do
4970       --  not have a case which might generate an embarrassingly large temp
4971       --  in stack checking mode.
4972
4973       elsif Size_Known_At_Compile_Time (Otyp)
4974         and then
4975           (not Stack_Checking_Enabled
4976              or else not May_Generate_Large_Temp (Otyp))
4977         and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp))
4978       then
4979          return True;
4980
4981       --  If either type is tagged, then we know the alignment is OK so
4982       --  Gigi will be able to use pointer punning.
4983
4984       elsif Is_Tagged_Type (Otyp) or else Is_Tagged_Type (Ityp) then
4985          return True;
4986
4987       --  If either type is a limited record type, we cannot do a copy, so
4988       --  say safe since there's nothing else we can do.
4989
4990       elsif Is_Limited_Record (Otyp) or else Is_Limited_Record (Ityp) then
4991          return True;
4992
4993       --  Conversions to and from packed array types are always ignored and
4994       --  hence are safe.
4995
4996       elsif Is_Packed_Array_Type (Otyp)
4997         or else Is_Packed_Array_Type (Ityp)
4998       then
4999          return True;
5000       end if;
5001
5002       --  The only other cases known to be safe is if the input type's
5003       --  alignment is known to be at least the maximum alignment for the
5004       --  target or if both alignments are known and the output type's
5005       --  alignment is no stricter than the input's.  We can use the alignment
5006       --  of the component type of an array if a type is an unpacked
5007       --  array type.
5008
5009       if Present (Alignment_Clause (Otyp)) then
5010          Oalign := Expr_Value (Expression (Alignment_Clause (Otyp)));
5011
5012       elsif Is_Array_Type (Otyp)
5013         and then Present (Alignment_Clause (Component_Type (Otyp)))
5014       then
5015          Oalign := Expr_Value (Expression (Alignment_Clause
5016                                            (Component_Type (Otyp))));
5017       end if;
5018
5019       if Present (Alignment_Clause (Ityp)) then
5020          Ialign := Expr_Value (Expression (Alignment_Clause (Ityp)));
5021
5022       elsif Is_Array_Type (Ityp)
5023         and then Present (Alignment_Clause (Component_Type (Ityp)))
5024       then
5025          Ialign := Expr_Value (Expression (Alignment_Clause
5026                                            (Component_Type (Ityp))));
5027       end if;
5028
5029       if Ialign /= No_Uint and then Ialign > Maximum_Alignment then
5030          return True;
5031
5032       elsif Ialign /= No_Uint and then Oalign /= No_Uint
5033         and then Ialign <= Oalign
5034       then
5035          return True;
5036
5037       --   Otherwise, Gigi cannot handle this and we must make a temporary
5038
5039       else
5040          return False;
5041       end if;
5042    end Safe_Unchecked_Type_Conversion;
5043
5044    ---------------------------------
5045    -- Set_Current_Value_Condition --
5046    ---------------------------------
5047
5048    --  Note: the implementation of this procedure is very closely tied to the
5049    --  implementation of Get_Current_Value_Condition. Here we set required
5050    --  Current_Value fields, and in Get_Current_Value_Condition, we interpret
5051    --  them, so they must have a consistent view.
5052
5053    procedure Set_Current_Value_Condition (Cnode : Node_Id) is
5054
5055       procedure Set_Entity_Current_Value (N : Node_Id);
5056       --  If N is an entity reference, where the entity is of an appropriate
5057       --  kind, then set the current value of this entity to Cnode, unless
5058       --  there is already a definite value set there.
5059
5060       procedure Set_Expression_Current_Value (N : Node_Id);
5061       --  If N is of an appropriate form, sets an appropriate entry in current
5062       --  value fields of relevant entities. Multiple entities can be affected
5063       --  in the case of an AND or AND THEN.
5064
5065       ------------------------------
5066       -- Set_Entity_Current_Value --
5067       ------------------------------
5068
5069       procedure Set_Entity_Current_Value (N : Node_Id) is
5070       begin
5071          if Is_Entity_Name (N) then
5072             declare
5073                Ent : constant Entity_Id := Entity (N);
5074
5075             begin
5076                --  Don't capture if not safe to do so
5077
5078                if not Safe_To_Capture_Value (N, Ent, Cond => True) then
5079                   return;
5080                end if;
5081
5082                --  Here we have a case where the Current_Value field may
5083                --  need to be set. We set it if it is not already set to a
5084                --  compile time expression value.
5085
5086                --  Note that this represents a decision that one condition
5087                --  blots out another previous one. That's certainly right
5088                --  if they occur at the same level. If the second one is
5089                --  nested, then the decision is neither right nor wrong (it
5090                --  would be equally OK to leave the outer one in place, or
5091                --  take the new inner one. Really we should record both, but
5092                --  our data structures are not that elaborate.
5093
5094                if Nkind (Current_Value (Ent)) not in N_Subexpr then
5095                   Set_Current_Value (Ent, Cnode);
5096                end if;
5097             end;
5098          end if;
5099       end Set_Entity_Current_Value;
5100
5101       ----------------------------------
5102       -- Set_Expression_Current_Value --
5103       ----------------------------------
5104
5105       procedure Set_Expression_Current_Value (N : Node_Id) is
5106          Cond : Node_Id;
5107
5108       begin
5109          Cond := N;
5110
5111          --  Loop to deal with (ignore for now) any NOT operators present. The
5112          --  presence of NOT operators will be handled properly when we call
5113          --  Get_Current_Value_Condition.
5114
5115          while Nkind (Cond) = N_Op_Not loop
5116             Cond := Right_Opnd (Cond);
5117          end loop;
5118
5119          --  For an AND or AND THEN, recursively process operands
5120
5121          if Nkind (Cond) = N_Op_And or else Nkind (Cond) = N_And_Then then
5122             Set_Expression_Current_Value (Left_Opnd (Cond));
5123             Set_Expression_Current_Value (Right_Opnd (Cond));
5124             return;
5125          end if;
5126
5127          --  Check possible relational operator
5128
5129          if Nkind (Cond) in N_Op_Compare then
5130             if Compile_Time_Known_Value (Right_Opnd (Cond)) then
5131                Set_Entity_Current_Value (Left_Opnd (Cond));
5132             elsif Compile_Time_Known_Value (Left_Opnd (Cond)) then
5133                Set_Entity_Current_Value (Right_Opnd (Cond));
5134             end if;
5135
5136             --  Check possible boolean variable reference
5137
5138          else
5139             Set_Entity_Current_Value (Cond);
5140          end if;
5141       end Set_Expression_Current_Value;
5142
5143    --  Start of processing for Set_Current_Value_Condition
5144
5145    begin
5146       Set_Expression_Current_Value (Condition (Cnode));
5147    end Set_Current_Value_Condition;
5148
5149    --------------------------
5150    -- Set_Elaboration_Flag --
5151    --------------------------
5152
5153    procedure Set_Elaboration_Flag (N : Node_Id; Spec_Id : Entity_Id) is
5154       Loc : constant Source_Ptr := Sloc (N);
5155       Ent : constant Entity_Id  := Elaboration_Entity (Spec_Id);
5156       Asn : Node_Id;
5157
5158    begin
5159       if Present (Ent) then
5160
5161          --  Nothing to do if at the compilation unit level, because in this
5162          --  case the flag is set by the binder generated elaboration routine.
5163
5164          if Nkind (Parent (N)) = N_Compilation_Unit then
5165             null;
5166
5167          --  Here we do need to generate an assignment statement
5168
5169          else
5170             Check_Restriction (No_Elaboration_Code, N);
5171             Asn :=
5172               Make_Assignment_Statement (Loc,
5173                 Name       => New_Occurrence_Of (Ent, Loc),
5174                 Expression => New_Occurrence_Of (Standard_True, Loc));
5175
5176             if Nkind (Parent (N)) = N_Subunit then
5177                Insert_After (Corresponding_Stub (Parent (N)), Asn);
5178             else
5179                Insert_After (N, Asn);
5180             end if;
5181
5182             Analyze (Asn);
5183
5184             --  Kill current value indication. This is necessary because the
5185             --  tests of this flag are inserted out of sequence and must not
5186             --  pick up bogus indications of the wrong constant value.
5187
5188             Set_Current_Value (Ent, Empty);
5189          end if;
5190       end if;
5191    end Set_Elaboration_Flag;
5192
5193    ----------------------------
5194    -- Set_Renamed_Subprogram --
5195    ----------------------------
5196
5197    procedure Set_Renamed_Subprogram (N : Node_Id; E : Entity_Id) is
5198    begin
5199       --  If input node is an identifier, we can just reset it
5200
5201       if Nkind (N) = N_Identifier then
5202          Set_Chars  (N, Chars (E));
5203          Set_Entity (N, E);
5204
5205          --  Otherwise we have to do a rewrite, preserving Comes_From_Source
5206
5207       else
5208          declare
5209             CS : constant Boolean := Comes_From_Source (N);
5210          begin
5211             Rewrite (N, Make_Identifier (Sloc (N), Chars => Chars (E)));
5212             Set_Entity (N, E);
5213             Set_Comes_From_Source (N, CS);
5214             Set_Analyzed (N, True);
5215          end;
5216       end if;
5217    end Set_Renamed_Subprogram;
5218
5219    ----------------------------------
5220    -- Silly_Boolean_Array_Not_Test --
5221    ----------------------------------
5222
5223    --  This procedure implements an odd and silly test. We explicitly check
5224    --  for the case where the 'First of the component type is equal to the
5225    --  'Last of this component type, and if this is the case, we make sure
5226    --  that constraint error is raised. The reason is that the NOT is bound
5227    --  to cause CE in this case, and we will not otherwise catch it.
5228
5229    --  No such check is required for AND and OR, since for both these cases
5230    --  False op False = False, and True op True = True. For the XOR case,
5231    --  see Silly_Boolean_Array_Xor_Test.
5232
5233    --  Believe it or not, this was reported as a bug. Note that nearly
5234    --  always, the test will evaluate statically to False, so the code will
5235    --  be statically removed, and no extra overhead caused.
5236
5237    procedure Silly_Boolean_Array_Not_Test (N : Node_Id; T : Entity_Id) is
5238       Loc : constant Source_Ptr := Sloc (N);
5239       CT  : constant Entity_Id  := Component_Type (T);
5240
5241    begin
5242       --  The check we install is
5243
5244       --    constraint_error when
5245       --      component_type'first = component_type'last
5246       --        and then array_type'Length /= 0)
5247
5248       --  We need the last guard because we don't want to raise CE for empty
5249       --  arrays since no out of range values result. (Empty arrays with a
5250       --  component type of True .. True -- very useful -- even the ACATS
5251       --  does not test that marginal case!)
5252
5253       Insert_Action (N,
5254         Make_Raise_Constraint_Error (Loc,
5255           Condition =>
5256             Make_And_Then (Loc,
5257               Left_Opnd =>
5258                 Make_Op_Eq (Loc,
5259                   Left_Opnd =>
5260                     Make_Attribute_Reference (Loc,
5261                       Prefix         => New_Occurrence_Of (CT, Loc),
5262                       Attribute_Name => Name_First),
5263
5264                   Right_Opnd =>
5265                     Make_Attribute_Reference (Loc,
5266                       Prefix         => New_Occurrence_Of (CT, Loc),
5267                       Attribute_Name => Name_Last)),
5268
5269               Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
5270           Reason => CE_Range_Check_Failed));
5271    end Silly_Boolean_Array_Not_Test;
5272
5273    ----------------------------------
5274    -- Silly_Boolean_Array_Xor_Test --
5275    ----------------------------------
5276
5277    --  This procedure implements an odd and silly test. We explicitly check
5278    --  for the XOR case where the component type is True .. True, since this
5279    --  will raise constraint error. A special check is required since CE
5280    --  will not be generated otherwise (cf Expand_Packed_Not).
5281
5282    --  No such check is required for AND and OR, since for both these cases
5283    --  False op False = False, and True op True = True, and no check is
5284    --  required for the case of False .. False, since False xor False = False.
5285    --  See also Silly_Boolean_Array_Not_Test
5286
5287    procedure Silly_Boolean_Array_Xor_Test (N : Node_Id; T : Entity_Id) is
5288       Loc : constant Source_Ptr := Sloc (N);
5289       CT  : constant Entity_Id  := Component_Type (T);
5290
5291    begin
5292       --  The check we install is
5293
5294       --    constraint_error when
5295       --      Boolean (component_type'First)
5296       --        and then Boolean (component_type'Last)
5297       --        and then array_type'Length /= 0)
5298
5299       --  We need the last guard because we don't want to raise CE for empty
5300       --  arrays since no out of range values result (Empty arrays with a
5301       --  component type of True .. True -- very useful -- even the ACATS
5302       --  does not test that marginal case!).
5303
5304       Insert_Action (N,
5305         Make_Raise_Constraint_Error (Loc,
5306           Condition =>
5307             Make_And_Then (Loc,
5308               Left_Opnd =>
5309                 Make_And_Then (Loc,
5310                   Left_Opnd =>
5311                     Convert_To (Standard_Boolean,
5312                       Make_Attribute_Reference (Loc,
5313                         Prefix         => New_Occurrence_Of (CT, Loc),
5314                         Attribute_Name => Name_First)),
5315
5316                   Right_Opnd =>
5317                     Convert_To (Standard_Boolean,
5318                       Make_Attribute_Reference (Loc,
5319                         Prefix         => New_Occurrence_Of (CT, Loc),
5320                         Attribute_Name => Name_Last))),
5321
5322               Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
5323           Reason => CE_Range_Check_Failed));
5324    end Silly_Boolean_Array_Xor_Test;
5325
5326    --------------------------
5327    -- Target_Has_Fixed_Ops --
5328    --------------------------
5329
5330    Integer_Sized_Small : Ureal;
5331    --  Set to 2.0 ** -(Integer'Size - 1) the first time that this
5332    --  function is called (we don't want to compute it more than once!)
5333
5334    Long_Integer_Sized_Small : Ureal;
5335    --  Set to 2.0 ** -(Long_Integer'Size - 1) the first time that this
5336    --  function is called (we don't want to compute it more than once)
5337
5338    First_Time_For_THFO : Boolean := True;
5339    --  Set to False after first call (if Fractional_Fixed_Ops_On_Target)
5340
5341    function Target_Has_Fixed_Ops
5342      (Left_Typ   : Entity_Id;
5343       Right_Typ  : Entity_Id;
5344       Result_Typ : Entity_Id) return Boolean
5345    is
5346       function Is_Fractional_Type (Typ : Entity_Id) return Boolean;
5347       --  Return True if the given type is a fixed-point type with a small
5348       --  value equal to 2 ** (-(T'Object_Size - 1)) and whose values have
5349       --  an absolute value less than 1.0. This is currently limited
5350       --  to fixed-point types that map to Integer or Long_Integer.
5351
5352       ------------------------
5353       -- Is_Fractional_Type --
5354       ------------------------
5355
5356       function Is_Fractional_Type (Typ : Entity_Id) return Boolean is
5357       begin
5358          if Esize (Typ) = Standard_Integer_Size then
5359             return Small_Value (Typ) = Integer_Sized_Small;
5360
5361          elsif Esize (Typ) = Standard_Long_Integer_Size then
5362             return Small_Value (Typ) = Long_Integer_Sized_Small;
5363
5364          else
5365             return False;
5366          end if;
5367       end Is_Fractional_Type;
5368
5369    --  Start of processing for Target_Has_Fixed_Ops
5370
5371    begin
5372       --  Return False if Fractional_Fixed_Ops_On_Target is false
5373
5374       if not Fractional_Fixed_Ops_On_Target then
5375          return False;
5376       end if;
5377
5378       --  Here the target has Fractional_Fixed_Ops, if first time, compute
5379       --  standard constants used by Is_Fractional_Type.
5380
5381       if First_Time_For_THFO then
5382          First_Time_For_THFO := False;
5383
5384          Integer_Sized_Small :=
5385            UR_From_Components
5386              (Num   => Uint_1,
5387               Den   => UI_From_Int (Standard_Integer_Size - 1),
5388               Rbase => 2);
5389
5390          Long_Integer_Sized_Small :=
5391            UR_From_Components
5392              (Num   => Uint_1,
5393               Den   => UI_From_Int (Standard_Long_Integer_Size - 1),
5394               Rbase => 2);
5395       end if;
5396
5397       --  Return True if target supports fixed-by-fixed multiply/divide
5398       --  for fractional fixed-point types (see Is_Fractional_Type) and
5399       --  the operand and result types are equivalent fractional types.
5400
5401       return Is_Fractional_Type (Base_Type (Left_Typ))
5402         and then Is_Fractional_Type (Base_Type (Right_Typ))
5403         and then Is_Fractional_Type (Base_Type (Result_Typ))
5404         and then Esize (Left_Typ) = Esize (Right_Typ)
5405         and then Esize (Left_Typ) = Esize (Result_Typ);
5406    end Target_Has_Fixed_Ops;
5407
5408    ------------------------------------------
5409    -- Type_May_Have_Bit_Aligned_Components --
5410    ------------------------------------------
5411
5412    function Type_May_Have_Bit_Aligned_Components
5413      (Typ : Entity_Id) return Boolean
5414    is
5415    begin
5416       --  Array type, check component type
5417
5418       if Is_Array_Type (Typ) then
5419          return
5420            Type_May_Have_Bit_Aligned_Components (Component_Type (Typ));
5421
5422       --  Record type, check components
5423
5424       elsif Is_Record_Type (Typ) then
5425          declare
5426             E : Entity_Id;
5427
5428          begin
5429             E := First_Component_Or_Discriminant (Typ);
5430             while Present (E) loop
5431                if Component_May_Be_Bit_Aligned (E)
5432                  or else Type_May_Have_Bit_Aligned_Components (Etype (E))
5433                then
5434                   return True;
5435                end if;
5436
5437                Next_Component_Or_Discriminant (E);
5438             end loop;
5439
5440             return False;
5441          end;
5442
5443       --  Type other than array or record is always OK
5444
5445       else
5446          return False;
5447       end if;
5448    end Type_May_Have_Bit_Aligned_Components;
5449
5450    ----------------------------
5451    -- Wrap_Cleanup_Procedure --
5452    ----------------------------
5453
5454    procedure Wrap_Cleanup_Procedure (N : Node_Id) is
5455       Loc   : constant Source_Ptr := Sloc (N);
5456       Stseq : constant Node_Id    := Handled_Statement_Sequence (N);
5457       Stmts : constant List_Id    := Statements (Stseq);
5458
5459    begin
5460       if Abort_Allowed then
5461          Prepend_To (Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
5462          Append_To  (Stmts, Build_Runtime_Call (Loc, RE_Abort_Undefer));
5463       end if;
5464    end Wrap_Cleanup_Procedure;
5465
5466 end Exp_Util;