1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
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. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with Atree; use Atree;
27 with Casing; use Casing;
28 with Checks; use Checks;
29 with Debug; use Debug;
30 with Einfo; use Einfo;
31 with Elists; use Elists;
32 with Errout; use Errout;
33 with Exp_Aggr; use Exp_Aggr;
34 with Exp_Ch6; use Exp_Ch6;
35 with Exp_Ch7; use Exp_Ch7;
36 with Inline; use Inline;
37 with Itypes; use Itypes;
39 with Nlists; use Nlists;
40 with Nmake; use Nmake;
42 with Restrict; use Restrict;
43 with Rident; use Rident;
45 with Sem_Aux; use Sem_Aux;
46 with Sem_Ch8; use Sem_Ch8;
47 with Sem_Eval; use Sem_Eval;
48 with Sem_Prag; use Sem_Prag;
49 with Sem_Res; use Sem_Res;
50 with Sem_Type; use Sem_Type;
51 with Sem_Util; use Sem_Util;
52 with Snames; use Snames;
53 with Stand; use Stand;
54 with Stringt; use Stringt;
55 with Targparm; use Targparm;
56 with Tbuild; use Tbuild;
57 with Ttypes; use Ttypes;
58 with Urealp; use Urealp;
59 with Validsw; use Validsw;
61 package body Exp_Util is
63 -----------------------
64 -- Local Subprograms --
65 -----------------------
67 function Build_Task_Array_Image
71 Dyn : Boolean := False) return Node_Id;
72 -- Build function to generate the image string for a task that is an array
73 -- component, concatenating the images of each index. To avoid storage
74 -- leaks, the string is built with successive slice assignments. The flag
75 -- Dyn indicates whether this is called for the initialization procedure of
76 -- an array of tasks, or for the name of a dynamically created task that is
77 -- assigned to an indexed component.
79 function Build_Task_Image_Function
83 Res : Entity_Id) return Node_Id;
84 -- Common processing for Task_Array_Image and Task_Record_Image. Build
85 -- function body that computes image.
87 procedure Build_Task_Image_Prefix
96 -- Common processing for Task_Array_Image and Task_Record_Image. Create
97 -- local variables and assign prefix of name to result string.
99 function Build_Task_Record_Image
102 Dyn : Boolean := False) return Node_Id;
103 -- Build function to generate the image string for a task that is a record
104 -- component. Concatenate name of variable with that of selector. The flag
105 -- Dyn indicates whether this is called for the initialization procedure of
106 -- record with task components, or for a dynamically created task that is
107 -- assigned to a selected component.
109 function Make_CW_Equivalent_Type
111 E : Node_Id) return Entity_Id;
112 -- T is a class-wide type entity, E is the initial expression node that
113 -- constrains T in case such as: " X: T := E" or "new T'(E)". This function
114 -- returns the entity of the Equivalent type and inserts on the fly the
115 -- necessary declaration such as:
117 -- type anon is record
118 -- _parent : Root_Type (T); constrained with E discriminants (if any)
119 -- Extension : String (1 .. expr to match size of E);
122 -- This record is compatible with any object of the class of T thanks to
123 -- the first field and has the same size as E thanks to the second.
125 function Make_Literal_Range
127 Literal_Typ : Entity_Id) return Node_Id;
128 -- Produce a Range node whose bounds are:
129 -- Low_Bound (Literal_Type) ..
130 -- Low_Bound (Literal_Type) + (Length (Literal_Typ) - 1)
131 -- this is used for expanding declarations like X : String := "sdfgdfg";
133 -- If the index type of the target array is not integer, we generate:
134 -- Low_Bound (Literal_Type) ..
136 -- (Literal_Type'Pos (Low_Bound (Literal_Type))
137 -- + (Length (Literal_Typ) -1))
139 function Make_Non_Empty_Check
141 N : Node_Id) return Node_Id;
142 -- Produce a boolean expression checking that the unidimensional array
143 -- node N is not empty.
145 function New_Class_Wide_Subtype
147 N : Node_Id) return Entity_Id;
148 -- Create an implicit subtype of CW_Typ attached to node N
150 function Requires_Cleanup_Actions
152 For_Package : Boolean;
153 Nested_Constructs : Boolean) return Boolean;
154 -- Given a list L, determine whether it contains one of the following:
156 -- 1) controlled objects
157 -- 2) library-level tagged types
159 -- Flag For_Package should be set when the list comes from a package spec
160 -- or body. Flag Nested_Constructs should be set when any nested packages
161 -- declared in L must be processed.
163 ----------------------
164 -- Adjust_Condition --
165 ----------------------
167 procedure Adjust_Condition (N : Node_Id) is
174 Loc : constant Source_Ptr := Sloc (N);
175 T : constant Entity_Id := Etype (N);
179 -- For now, we simply ignore a call where the argument has no type
180 -- (probably case of unanalyzed condition), or has a type that is not
181 -- Boolean. This is because this is a pretty marginal piece of
182 -- functionality, and violations of these rules are likely to be
183 -- truly marginal (how much code uses Fortran Logical as the barrier
184 -- to a protected entry?) and we do not want to blow up existing
185 -- programs. We can change this to an assertion after 3.12a is
188 if No (T) or else not Is_Boolean_Type (T) then
192 -- Apply validity checking if needed
194 if Validity_Checks_On and Validity_Check_Tests then
198 -- Immediate return if standard boolean, the most common case,
199 -- where nothing needs to be done.
201 if Base_Type (T) = Standard_Boolean then
205 -- Case of zero/non-zero semantics or non-standard enumeration
206 -- representation. In each case, we rewrite the node as:
208 -- ityp!(N) /= False'Enum_Rep
210 -- where ityp is an integer type with large enough size to hold any
213 if Nonzero_Is_True (T) or else Has_Non_Standard_Rep (T) then
214 if Esize (T) <= Esize (Standard_Integer) then
215 Ti := Standard_Integer;
217 Ti := Standard_Long_Long_Integer;
222 Left_Opnd => Unchecked_Convert_To (Ti, N),
224 Make_Attribute_Reference (Loc,
225 Attribute_Name => Name_Enum_Rep,
227 New_Occurrence_Of (First_Literal (T), Loc))));
228 Analyze_And_Resolve (N, Standard_Boolean);
231 Rewrite (N, Convert_To (Standard_Boolean, N));
232 Analyze_And_Resolve (N, Standard_Boolean);
235 end Adjust_Condition;
237 ------------------------
238 -- Adjust_Result_Type --
239 ------------------------
241 procedure Adjust_Result_Type (N : Node_Id; T : Entity_Id) is
243 -- Ignore call if current type is not Standard.Boolean
245 if Etype (N) /= Standard_Boolean then
249 -- If result is already of correct type, nothing to do. Note that
250 -- this will get the most common case where everything has a type
251 -- of Standard.Boolean.
253 if Base_Type (T) = Standard_Boolean then
258 KP : constant Node_Kind := Nkind (Parent (N));
261 -- If result is to be used as a Condition in the syntax, no need
262 -- to convert it back, since if it was changed to Standard.Boolean
263 -- using Adjust_Condition, that is just fine for this usage.
265 if KP in N_Raise_xxx_Error or else KP in N_Has_Condition then
268 -- If result is an operand of another logical operation, no need
269 -- to reset its type, since Standard.Boolean is just fine, and
270 -- such operations always do Adjust_Condition on their operands.
272 elsif KP in N_Op_Boolean
273 or else KP in N_Short_Circuit
274 or else KP = N_Op_Not
278 -- Otherwise we perform a conversion from the current type, which
279 -- must be Standard.Boolean, to the desired type.
283 Rewrite (N, Convert_To (T, N));
284 Analyze_And_Resolve (N, T);
288 end Adjust_Result_Type;
290 --------------------------
291 -- Append_Freeze_Action --
292 --------------------------
294 procedure Append_Freeze_Action (T : Entity_Id; N : Node_Id) is
298 Ensure_Freeze_Node (T);
299 Fnode := Freeze_Node (T);
301 if No (Actions (Fnode)) then
302 Set_Actions (Fnode, New_List);
305 Append (N, Actions (Fnode));
306 end Append_Freeze_Action;
308 ---------------------------
309 -- Append_Freeze_Actions --
310 ---------------------------
312 procedure Append_Freeze_Actions (T : Entity_Id; L : List_Id) is
313 Fnode : constant Node_Id := Freeze_Node (T);
320 if No (Actions (Fnode)) then
321 Set_Actions (Fnode, L);
323 Append_List (L, Actions (Fnode));
326 end Append_Freeze_Actions;
328 ------------------------------------
329 -- Build_Allocate_Deallocate_Proc --
330 ------------------------------------
332 procedure Build_Allocate_Deallocate_Proc
334 Is_Allocate : Boolean)
336 Expr : constant Node_Id := Expression (N);
337 Ptr_Typ : constant Entity_Id := Etype (Expr);
338 Desig_Typ : constant Entity_Id :=
339 Available_View (Designated_Type (Ptr_Typ));
341 function Find_Object (E : Node_Id) return Node_Id;
342 -- Given an arbitrary expression of an allocator, try to find an object
343 -- reference in it, otherwise return the original expression.
345 function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean;
346 -- Determine whether subprogram Subp denotes a custom allocate or
353 function Find_Object (E : Node_Id) return Node_Id is
357 pragma Assert (Is_Allocate);
361 if Nkind_In (Expr, N_Qualified_Expression,
362 N_Unchecked_Type_Conversion)
364 Expr := Expression (Expr);
366 elsif Nkind (Expr) = N_Explicit_Dereference then
367 Expr := Prefix (Expr);
377 ---------------------------------
378 -- Is_Allocate_Deallocate_Proc --
379 ---------------------------------
381 function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean is
383 -- Look for a subprogram body with only one statement which is a
384 -- call to one of the Allocate / Deallocate routines in package
385 -- Ada.Finalization.Heap_Management.
387 if Ekind (Subp) = E_Procedure
388 and then Nkind (Parent (Parent (Subp))) = N_Subprogram_Body
391 HSS : constant Node_Id :=
392 Handled_Statement_Sequence (Parent (Parent (Subp)));
396 if Present (Statements (HSS))
397 and then Nkind (First (Statements (HSS))) =
398 N_Procedure_Call_Statement
400 Proc := Entity (Name (First (Statements (HSS))));
403 Is_RTE (Proc, RE_Allocate)
404 or else Is_RTE (Proc, RE_Deallocate);
410 end Is_Allocate_Deallocate_Proc;
412 -- Start of processing for Build_Allocate_Deallocate_Proc
415 -- The allocation / deallocation of a non-controlled object does not
416 -- need the machinery created by this routine.
418 if not Needs_Finalization (Desig_Typ) then
421 -- The allocator or free statmenet has already been expanded and already
422 -- has a custom Allocate / Deallocate routine.
424 elsif Nkind (Expr) = N_Allocator
425 and then Present (Procedure_To_Call (Expr))
426 and then Is_Allocate_Deallocate_Proc (Procedure_To_Call (Expr))
432 Loc : constant Source_Ptr := Sloc (N);
433 Addr_Id : constant Entity_Id := Make_Temporary (Loc, 'A');
434 Alig_Id : constant Entity_Id := Make_Temporary (Loc, 'L');
435 Proc_Id : constant Entity_Id := Make_Temporary (Loc, 'P');
436 Size_Id : constant Entity_Id := Make_Temporary (Loc, 'S');
439 Collect_Act : Node_Id;
440 Collect_Id : Entity_Id;
441 Collect_Typ : Entity_Id;
442 Proc_To_Call : Entity_Id;
445 -- When dealing with an access subtype, use the collection of the
448 if Ekind (Ptr_Typ) = E_Access_Subtype then
449 Collect_Typ := Base_Type (Ptr_Typ);
451 Collect_Typ := Ptr_Typ;
454 Collect_Id := Associated_Collection (Collect_Typ);
455 Collect_Act := New_Reference_To (Collect_Id, Loc);
457 -- Handle the case where the collection is actually a pointer to a
458 -- collection. This case arises in build-in-place functions.
460 if Is_Access_Type (Etype (Collect_Id)) then
462 Make_Explicit_Dereference (Loc,
463 Prefix => Collect_Act);
466 -- Create the actuals for the call to Allocate / Deallocate
468 Actuals := New_List (
470 New_Reference_To (Addr_Id, Loc),
471 New_Reference_To (Size_Id, Loc),
472 New_Reference_To (Alig_Id, Loc));
474 -- Generate a run-time check to determine whether a class-wide object
475 -- is truly controlled.
477 if Is_Class_Wide_Type (Desig_Typ)
478 or else Is_Generic_Actual_Type (Desig_Typ)
481 Flag_Id : constant Entity_Id := Make_Temporary (Loc, 'F');
488 Temp := Find_Object (Expression (Expr));
493 -- Processing for generic actuals
495 if Is_Generic_Actual_Type (Desig_Typ) then
497 New_Reference_To (Boolean_Literals
498 (Needs_Finalization (Base_Type (Desig_Typ))), Loc);
500 -- Processing for subtype indications
502 elsif Nkind (Temp) in N_Has_Entity
503 and then Is_Type (Entity (Temp))
506 New_Reference_To (Boolean_Literals
507 (Needs_Finalization (Entity (Temp))), Loc);
509 -- Generate a runtime check to test the controlled state of an
510 -- object for the purposes of allocation / deallocation.
513 -- The following case arises when allocating through an
514 -- interface class-wide type, generate:
518 if Is_RTE (Etype (Temp), RE_Tag_Ptr) then
520 Make_Explicit_Dereference (Loc,
522 Relocate_Node (Temp));
529 Make_Attribute_Reference (Loc,
531 Relocate_Node (Temp),
532 Attribute_Name => Name_Tag);
536 -- Needs_Finalization (Param)
539 Make_Function_Call (Loc,
541 New_Reference_To (RTE (RE_Needs_Finalization), Loc),
542 Parameter_Associations => New_List (Param));
545 -- Create the temporary which represents the finalization state
546 -- of the expression. Generate:
548 -- F : constant Boolean := <Flag_Expr>;
551 Make_Object_Declaration (Loc,
552 Defining_Identifier => Flag_Id,
553 Constant_Present => True,
555 New_Reference_To (Standard_Boolean, Loc),
556 Expression => Flag_Expr));
558 -- The flag acts as the fifth actual
560 Append_To (Actuals, New_Reference_To (Flag_Id, Loc));
564 -- Select the proper routine to call
567 Proc_To_Call := RTE (RE_Allocate);
569 Proc_To_Call := RTE (RE_Deallocate);
572 -- Create a custom Allocate / Deallocate routine which has identical
573 -- profile to that of System.Storage_Pools.
576 Make_Subprogram_Body (Loc,
581 Make_Procedure_Specification (Loc,
582 Defining_Unit_Name => Proc_Id,
583 Parameter_Specifications => New_List (
585 -- P : Root_Storage_Pool
587 Make_Parameter_Specification (Loc,
588 Defining_Identifier =>
589 Make_Temporary (Loc, 'P'),
591 New_Reference_To (RTE (RE_Root_Storage_Pool), Loc)),
595 Make_Parameter_Specification (Loc,
596 Defining_Identifier => Addr_Id,
597 Out_Present => Is_Allocate,
599 New_Reference_To (RTE (RE_Address), Loc)),
603 Make_Parameter_Specification (Loc,
604 Defining_Identifier => Size_Id,
606 New_Reference_To (RTE (RE_Storage_Count), Loc)),
610 Make_Parameter_Specification (Loc,
611 Defining_Identifier => Alig_Id,
613 New_Reference_To (RTE (RE_Storage_Count), Loc)))),
615 Declarations => No_List,
617 Handled_Statement_Sequence =>
618 Make_Handled_Sequence_Of_Statements (Loc,
619 Statements => New_List (
621 -- Allocate / Deallocate
622 -- (<Ptr_Typ collection>, A, S, L[, F]);
624 Make_Procedure_Call_Statement (Loc,
626 New_Reference_To (Proc_To_Call, Loc),
627 Parameter_Associations => Actuals)))));
629 -- The newly generated Allocate / Deallocate becomes the default
630 -- procedure to call when the back end processes the allocation /
634 Set_Procedure_To_Call (Expr, Proc_Id);
636 Set_Procedure_To_Call (N, Proc_Id);
639 end Build_Allocate_Deallocate_Proc;
641 ------------------------
642 -- Build_Runtime_Call --
643 ------------------------
645 function Build_Runtime_Call (Loc : Source_Ptr; RE : RE_Id) return Node_Id is
647 -- If entity is not available, we can skip making the call (this avoids
648 -- junk duplicated error messages in a number of cases).
650 if not RTE_Available (RE) then
651 return Make_Null_Statement (Loc);
654 Make_Procedure_Call_Statement (Loc,
655 Name => New_Reference_To (RTE (RE), Loc));
657 end Build_Runtime_Call;
659 ----------------------------
660 -- Build_Task_Array_Image --
661 ----------------------------
663 -- This function generates the body for a function that constructs the
664 -- image string for a task that is an array component. The function is
665 -- local to the init proc for the array type, and is called for each one
666 -- of the components. The constructed image has the form of an indexed
667 -- component, whose prefix is the outer variable of the array type.
668 -- The n-dimensional array type has known indexes Index, Index2...
670 -- Id_Ref is an indexed component form created by the enclosing init proc.
671 -- Its successive indexes are Val1, Val2, ... which are the loop variables
672 -- in the loops that call the individual task init proc on each component.
674 -- The generated function has the following structure:
676 -- function F return String is
677 -- Pref : string renames Task_Name;
678 -- T1 : String := Index1'Image (Val1);
680 -- Tn : String := indexn'image (Valn);
681 -- Len : Integer := T1'Length + ... + Tn'Length + n + 1;
682 -- -- Len includes commas and the end parentheses.
683 -- Res : String (1..Len);
684 -- Pos : Integer := Pref'Length;
687 -- Res (1 .. Pos) := Pref;
691 -- Res (Pos .. Pos + T1'Length - 1) := T1;
692 -- Pos := Pos + T1'Length;
696 -- Res (Pos .. Pos + Tn'Length - 1) := Tn;
702 -- Needless to say, multidimensional arrays of tasks are rare enough that
703 -- the bulkiness of this code is not really a concern.
705 function Build_Task_Array_Image
709 Dyn : Boolean := False) return Node_Id
711 Dims : constant Nat := Number_Dimensions (A_Type);
712 -- Number of dimensions for array of tasks
714 Temps : array (1 .. Dims) of Entity_Id;
715 -- Array of temporaries to hold string for each index
721 -- Total length of generated name
724 -- Running index for substring assignments
726 Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
727 -- Name of enclosing variable, prefix of resulting name
730 -- String to hold result
733 -- Value of successive indexes
736 -- Expression to compute total size of string
739 -- Entity for name at one index position
741 Decls : constant List_Id := New_List;
742 Stats : constant List_Id := New_List;
745 -- For a dynamic task, the name comes from the target variable. For a
746 -- static one it is a formal of the enclosing init proc.
749 Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
751 Make_Object_Declaration (Loc,
752 Defining_Identifier => Pref,
753 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
755 Make_String_Literal (Loc,
756 Strval => String_From_Name_Buffer)));
760 Make_Object_Renaming_Declaration (Loc,
761 Defining_Identifier => Pref,
762 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
763 Name => Make_Identifier (Loc, Name_uTask_Name)));
766 Indx := First_Index (A_Type);
767 Val := First (Expressions (Id_Ref));
769 for J in 1 .. Dims loop
770 T := Make_Temporary (Loc, 'T');
774 Make_Object_Declaration (Loc,
775 Defining_Identifier => T,
776 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
778 Make_Attribute_Reference (Loc,
779 Attribute_Name => Name_Image,
780 Prefix => New_Occurrence_Of (Etype (Indx), Loc),
781 Expressions => New_List (New_Copy_Tree (Val)))));
787 Sum := Make_Integer_Literal (Loc, Dims + 1);
793 Make_Attribute_Reference (Loc,
794 Attribute_Name => Name_Length,
796 New_Occurrence_Of (Pref, Loc),
797 Expressions => New_List (Make_Integer_Literal (Loc, 1))));
799 for J in 1 .. Dims loop
804 Make_Attribute_Reference (Loc,
805 Attribute_Name => Name_Length,
807 New_Occurrence_Of (Temps (J), Loc),
808 Expressions => New_List (Make_Integer_Literal (Loc, 1))));
811 Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
813 Set_Character_Literal_Name (Char_Code (Character'Pos ('(')));
816 Make_Assignment_Statement (Loc,
817 Name => Make_Indexed_Component (Loc,
818 Prefix => New_Occurrence_Of (Res, Loc),
819 Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
821 Make_Character_Literal (Loc,
823 Char_Literal_Value =>
824 UI_From_Int (Character'Pos ('(')))));
827 Make_Assignment_Statement (Loc,
828 Name => New_Occurrence_Of (Pos, Loc),
831 Left_Opnd => New_Occurrence_Of (Pos, Loc),
832 Right_Opnd => Make_Integer_Literal (Loc, 1))));
834 for J in 1 .. Dims loop
837 Make_Assignment_Statement (Loc,
838 Name => Make_Slice (Loc,
839 Prefix => New_Occurrence_Of (Res, Loc),
842 Low_Bound => New_Occurrence_Of (Pos, Loc),
843 High_Bound => Make_Op_Subtract (Loc,
846 Left_Opnd => New_Occurrence_Of (Pos, Loc),
848 Make_Attribute_Reference (Loc,
849 Attribute_Name => Name_Length,
851 New_Occurrence_Of (Temps (J), Loc),
853 New_List (Make_Integer_Literal (Loc, 1)))),
854 Right_Opnd => Make_Integer_Literal (Loc, 1)))),
856 Expression => New_Occurrence_Of (Temps (J), Loc)));
860 Make_Assignment_Statement (Loc,
861 Name => New_Occurrence_Of (Pos, Loc),
864 Left_Opnd => New_Occurrence_Of (Pos, Loc),
866 Make_Attribute_Reference (Loc,
867 Attribute_Name => Name_Length,
868 Prefix => New_Occurrence_Of (Temps (J), Loc),
870 New_List (Make_Integer_Literal (Loc, 1))))));
872 Set_Character_Literal_Name (Char_Code (Character'Pos (',')));
875 Make_Assignment_Statement (Loc,
876 Name => Make_Indexed_Component (Loc,
877 Prefix => New_Occurrence_Of (Res, Loc),
878 Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
880 Make_Character_Literal (Loc,
882 Char_Literal_Value =>
883 UI_From_Int (Character'Pos (',')))));
886 Make_Assignment_Statement (Loc,
887 Name => New_Occurrence_Of (Pos, Loc),
890 Left_Opnd => New_Occurrence_Of (Pos, Loc),
891 Right_Opnd => Make_Integer_Literal (Loc, 1))));
895 Set_Character_Literal_Name (Char_Code (Character'Pos (')')));
898 Make_Assignment_Statement (Loc,
899 Name => Make_Indexed_Component (Loc,
900 Prefix => New_Occurrence_Of (Res, Loc),
901 Expressions => New_List (New_Occurrence_Of (Len, Loc))),
903 Make_Character_Literal (Loc,
905 Char_Literal_Value =>
906 UI_From_Int (Character'Pos (')')))));
907 return Build_Task_Image_Function (Loc, Decls, Stats, Res);
908 end Build_Task_Array_Image;
910 ----------------------------
911 -- Build_Task_Image_Decls --
912 ----------------------------
914 function Build_Task_Image_Decls
918 In_Init_Proc : Boolean := False) return List_Id
920 Decls : constant List_Id := New_List;
921 T_Id : Entity_Id := Empty;
923 Expr : Node_Id := Empty;
924 Fun : Node_Id := Empty;
925 Is_Dyn : constant Boolean :=
926 Nkind (Parent (Id_Ref)) = N_Assignment_Statement
928 Nkind (Expression (Parent (Id_Ref))) = N_Allocator;
931 -- If Discard_Names or No_Implicit_Heap_Allocations are in effect,
932 -- generate a dummy declaration only.
934 if Restriction_Active (No_Implicit_Heap_Allocations)
935 or else Global_Discard_Names
937 T_Id := Make_Temporary (Loc, 'J');
942 Make_Object_Declaration (Loc,
943 Defining_Identifier => T_Id,
944 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
946 Make_String_Literal (Loc,
947 Strval => String_From_Name_Buffer)));
950 if Nkind (Id_Ref) = N_Identifier
951 or else Nkind (Id_Ref) = N_Defining_Identifier
953 -- For a simple variable, the image of the task is built from
954 -- the name of the variable. To avoid possible conflict with the
955 -- anonymous type created for a single protected object, add a
959 Make_Defining_Identifier (Loc,
960 New_External_Name (Chars (Id_Ref), 'T', 1));
962 Get_Name_String (Chars (Id_Ref));
965 Make_String_Literal (Loc,
966 Strval => String_From_Name_Buffer);
968 elsif Nkind (Id_Ref) = N_Selected_Component then
970 Make_Defining_Identifier (Loc,
971 New_External_Name (Chars (Selector_Name (Id_Ref)), 'T'));
972 Fun := Build_Task_Record_Image (Loc, Id_Ref, Is_Dyn);
974 elsif Nkind (Id_Ref) = N_Indexed_Component then
976 Make_Defining_Identifier (Loc,
977 New_External_Name (Chars (A_Type), 'N'));
979 Fun := Build_Task_Array_Image (Loc, Id_Ref, A_Type, Is_Dyn);
983 if Present (Fun) then
985 Expr := Make_Function_Call (Loc,
986 Name => New_Occurrence_Of (Defining_Entity (Fun), Loc));
988 if not In_Init_Proc and then VM_Target = No_VM then
989 Set_Uses_Sec_Stack (Defining_Entity (Fun));
993 Decl := Make_Object_Declaration (Loc,
994 Defining_Identifier => T_Id,
995 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
996 Constant_Present => True,
999 Append (Decl, Decls);
1001 end Build_Task_Image_Decls;
1003 -------------------------------
1004 -- Build_Task_Image_Function --
1005 -------------------------------
1007 function Build_Task_Image_Function
1011 Res : Entity_Id) return Node_Id
1017 Make_Simple_Return_Statement (Loc,
1018 Expression => New_Occurrence_Of (Res, Loc)));
1020 Spec := Make_Function_Specification (Loc,
1021 Defining_Unit_Name => Make_Temporary (Loc, 'F'),
1022 Result_Definition => New_Occurrence_Of (Standard_String, Loc));
1024 -- Calls to 'Image use the secondary stack, which must be cleaned up
1025 -- after the task name is built.
1027 return Make_Subprogram_Body (Loc,
1028 Specification => Spec,
1029 Declarations => Decls,
1030 Handled_Statement_Sequence =>
1031 Make_Handled_Sequence_Of_Statements (Loc, Statements => Stats));
1032 end Build_Task_Image_Function;
1034 -----------------------------
1035 -- Build_Task_Image_Prefix --
1036 -----------------------------
1038 procedure Build_Task_Image_Prefix
1040 Len : out Entity_Id;
1041 Res : out Entity_Id;
1042 Pos : out Entity_Id;
1049 Len := Make_Temporary (Loc, 'L', Sum);
1052 Make_Object_Declaration (Loc,
1053 Defining_Identifier => Len,
1054 Object_Definition => New_Occurrence_Of (Standard_Integer, Loc),
1055 Expression => Sum));
1057 Res := Make_Temporary (Loc, 'R');
1060 Make_Object_Declaration (Loc,
1061 Defining_Identifier => Res,
1062 Object_Definition =>
1063 Make_Subtype_Indication (Loc,
1064 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
1066 Make_Index_Or_Discriminant_Constraint (Loc,
1070 Low_Bound => Make_Integer_Literal (Loc, 1),
1071 High_Bound => New_Occurrence_Of (Len, Loc)))))));
1073 Pos := Make_Temporary (Loc, 'P');
1076 Make_Object_Declaration (Loc,
1077 Defining_Identifier => Pos,
1078 Object_Definition => New_Occurrence_Of (Standard_Integer, Loc)));
1080 -- Pos := Prefix'Length;
1083 Make_Assignment_Statement (Loc,
1084 Name => New_Occurrence_Of (Pos, Loc),
1086 Make_Attribute_Reference (Loc,
1087 Attribute_Name => Name_Length,
1088 Prefix => New_Occurrence_Of (Prefix, Loc),
1089 Expressions => New_List (Make_Integer_Literal (Loc, 1)))));
1091 -- Res (1 .. Pos) := Prefix;
1094 Make_Assignment_Statement (Loc,
1097 Prefix => New_Occurrence_Of (Res, Loc),
1100 Low_Bound => Make_Integer_Literal (Loc, 1),
1101 High_Bound => New_Occurrence_Of (Pos, Loc))),
1103 Expression => New_Occurrence_Of (Prefix, Loc)));
1106 Make_Assignment_Statement (Loc,
1107 Name => New_Occurrence_Of (Pos, Loc),
1110 Left_Opnd => New_Occurrence_Of (Pos, Loc),
1111 Right_Opnd => Make_Integer_Literal (Loc, 1))));
1112 end Build_Task_Image_Prefix;
1114 -----------------------------
1115 -- Build_Task_Record_Image --
1116 -----------------------------
1118 function Build_Task_Record_Image
1121 Dyn : Boolean := False) return Node_Id
1124 -- Total length of generated name
1127 -- Index into result
1130 -- String to hold result
1132 Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
1133 -- Name of enclosing variable, prefix of resulting name
1136 -- Expression to compute total size of string
1139 -- Entity for selector name
1141 Decls : constant List_Id := New_List;
1142 Stats : constant List_Id := New_List;
1145 -- For a dynamic task, the name comes from the target variable. For a
1146 -- static one it is a formal of the enclosing init proc.
1149 Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
1151 Make_Object_Declaration (Loc,
1152 Defining_Identifier => Pref,
1153 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
1155 Make_String_Literal (Loc,
1156 Strval => String_From_Name_Buffer)));
1160 Make_Object_Renaming_Declaration (Loc,
1161 Defining_Identifier => Pref,
1162 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
1163 Name => Make_Identifier (Loc, Name_uTask_Name)));
1166 Sel := Make_Temporary (Loc, 'S');
1168 Get_Name_String (Chars (Selector_Name (Id_Ref)));
1171 Make_Object_Declaration (Loc,
1172 Defining_Identifier => Sel,
1173 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
1175 Make_String_Literal (Loc,
1176 Strval => String_From_Name_Buffer)));
1178 Sum := Make_Integer_Literal (Loc, Nat (Name_Len + 1));
1184 Make_Attribute_Reference (Loc,
1185 Attribute_Name => Name_Length,
1187 New_Occurrence_Of (Pref, Loc),
1188 Expressions => New_List (Make_Integer_Literal (Loc, 1))));
1190 Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
1192 Set_Character_Literal_Name (Char_Code (Character'Pos ('.')));
1194 -- Res (Pos) := '.';
1197 Make_Assignment_Statement (Loc,
1198 Name => Make_Indexed_Component (Loc,
1199 Prefix => New_Occurrence_Of (Res, Loc),
1200 Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
1202 Make_Character_Literal (Loc,
1204 Char_Literal_Value =>
1205 UI_From_Int (Character'Pos ('.')))));
1208 Make_Assignment_Statement (Loc,
1209 Name => New_Occurrence_Of (Pos, Loc),
1212 Left_Opnd => New_Occurrence_Of (Pos, Loc),
1213 Right_Opnd => Make_Integer_Literal (Loc, 1))));
1215 -- Res (Pos .. Len) := Selector;
1218 Make_Assignment_Statement (Loc,
1219 Name => Make_Slice (Loc,
1220 Prefix => New_Occurrence_Of (Res, Loc),
1223 Low_Bound => New_Occurrence_Of (Pos, Loc),
1224 High_Bound => New_Occurrence_Of (Len, Loc))),
1225 Expression => New_Occurrence_Of (Sel, Loc)));
1227 return Build_Task_Image_Function (Loc, Decls, Stats, Res);
1228 end Build_Task_Record_Image;
1230 ----------------------------------
1231 -- Component_May_Be_Bit_Aligned --
1232 ----------------------------------
1234 function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is
1238 -- If no component clause, then everything is fine, since the back end
1239 -- never bit-misaligns by default, even if there is a pragma Packed for
1242 if No (Comp) or else No (Component_Clause (Comp)) then
1246 UT := Underlying_Type (Etype (Comp));
1248 -- It is only array and record types that cause trouble
1250 if not Is_Record_Type (UT)
1251 and then not Is_Array_Type (UT)
1255 -- If we know that we have a small (64 bits or less) record or small
1256 -- bit-packed array, then everything is fine, since the back end can
1257 -- handle these cases correctly.
1259 elsif Esize (Comp) <= 64
1260 and then (Is_Record_Type (UT)
1261 or else Is_Bit_Packed_Array (UT))
1265 -- Otherwise if the component is not byte aligned, we know we have the
1266 -- nasty unaligned case.
1268 elsif Normalized_First_Bit (Comp) /= Uint_0
1269 or else Esize (Comp) mod System_Storage_Unit /= Uint_0
1273 -- If we are large and byte aligned, then OK at this level
1278 end Component_May_Be_Bit_Aligned;
1280 -----------------------------------
1281 -- Corresponding_Runtime_Package --
1282 -----------------------------------
1284 function Corresponding_Runtime_Package (Typ : Entity_Id) return RTU_Id is
1285 Pkg_Id : RTU_Id := RTU_Null;
1288 pragma Assert (Is_Concurrent_Type (Typ));
1290 if Ekind (Typ) in Protected_Kind then
1291 if Has_Entries (Typ)
1292 or else Has_Interrupt_Handler (Typ)
1293 or else (Has_Attach_Handler (Typ)
1294 and then not Restricted_Profile)
1296 -- A protected type without entries that covers an interface and
1297 -- overrides the abstract routines with protected procedures is
1298 -- considered equivalent to a protected type with entries in the
1299 -- context of dispatching select statements. It is sufficient to
1300 -- check for the presence of an interface list in the declaration
1301 -- node to recognize this case.
1303 or else Present (Interface_List (Parent (Typ)))
1306 or else Restriction_Active (No_Entry_Queue) = False
1307 or else Number_Entries (Typ) > 1
1308 or else (Has_Attach_Handler (Typ)
1309 and then not Restricted_Profile)
1311 Pkg_Id := System_Tasking_Protected_Objects_Entries;
1313 Pkg_Id := System_Tasking_Protected_Objects_Single_Entry;
1317 Pkg_Id := System_Tasking_Protected_Objects;
1322 end Corresponding_Runtime_Package;
1324 -------------------------------
1325 -- Convert_To_Actual_Subtype --
1326 -------------------------------
1328 procedure Convert_To_Actual_Subtype (Exp : Entity_Id) is
1332 Act_ST := Get_Actual_Subtype (Exp);
1334 if Act_ST = Etype (Exp) then
1339 Convert_To (Act_ST, Relocate_Node (Exp)));
1340 Analyze_And_Resolve (Exp, Act_ST);
1342 end Convert_To_Actual_Subtype;
1344 -----------------------------------
1345 -- Current_Sem_Unit_Declarations --
1346 -----------------------------------
1348 function Current_Sem_Unit_Declarations return List_Id is
1349 U : Node_Id := Unit (Cunit (Current_Sem_Unit));
1353 -- If the current unit is a package body, locate the visible
1354 -- declarations of the package spec.
1356 if Nkind (U) = N_Package_Body then
1357 U := Unit (Library_Unit (Cunit (Current_Sem_Unit)));
1360 if Nkind (U) = N_Package_Declaration then
1361 U := Specification (U);
1362 Decls := Visible_Declarations (U);
1366 Set_Visible_Declarations (U, Decls);
1370 Decls := Declarations (U);
1374 Set_Declarations (U, Decls);
1379 end Current_Sem_Unit_Declarations;
1381 -----------------------
1382 -- Duplicate_Subexpr --
1383 -----------------------
1385 function Duplicate_Subexpr
1387 Name_Req : Boolean := False) return Node_Id
1390 Remove_Side_Effects (Exp, Name_Req);
1391 return New_Copy_Tree (Exp);
1392 end Duplicate_Subexpr;
1394 ---------------------------------
1395 -- Duplicate_Subexpr_No_Checks --
1396 ---------------------------------
1398 function Duplicate_Subexpr_No_Checks
1400 Name_Req : Boolean := False) return Node_Id
1405 Remove_Side_Effects (Exp, Name_Req);
1406 New_Exp := New_Copy_Tree (Exp);
1407 Remove_Checks (New_Exp);
1409 end Duplicate_Subexpr_No_Checks;
1411 -----------------------------------
1412 -- Duplicate_Subexpr_Move_Checks --
1413 -----------------------------------
1415 function Duplicate_Subexpr_Move_Checks
1417 Name_Req : Boolean := False) return Node_Id
1422 Remove_Side_Effects (Exp, Name_Req);
1423 New_Exp := New_Copy_Tree (Exp);
1424 Remove_Checks (Exp);
1426 end Duplicate_Subexpr_Move_Checks;
1428 --------------------
1429 -- Ensure_Defined --
1430 --------------------
1432 procedure Ensure_Defined (Typ : Entity_Id; N : Node_Id) is
1436 -- An itype reference must only be created if this is a local itype, so
1437 -- that gigi can elaborate it on the proper objstack.
1440 and then Scope (Typ) = Current_Scope
1442 IR := Make_Itype_Reference (Sloc (N));
1443 Set_Itype (IR, Typ);
1444 Insert_Action (N, IR);
1448 --------------------
1449 -- Entry_Names_OK --
1450 --------------------
1452 function Entry_Names_OK return Boolean is
1455 not Restricted_Profile
1456 and then not Global_Discard_Names
1457 and then not Restriction_Active (No_Implicit_Heap_Allocations)
1458 and then not Restriction_Active (No_Local_Allocators);
1461 ---------------------
1462 -- Evolve_And_Then --
1463 ---------------------
1465 procedure Evolve_And_Then (Cond : in out Node_Id; Cond1 : Node_Id) is
1471 Make_And_Then (Sloc (Cond1),
1473 Right_Opnd => Cond1);
1475 end Evolve_And_Then;
1477 --------------------
1478 -- Evolve_Or_Else --
1479 --------------------
1481 procedure Evolve_Or_Else (Cond : in out Node_Id; Cond1 : Node_Id) is
1487 Make_Or_Else (Sloc (Cond1),
1489 Right_Opnd => Cond1);
1493 ------------------------------
1494 -- Expand_Subtype_From_Expr --
1495 ------------------------------
1497 -- This function is applicable for both static and dynamic allocation of
1498 -- objects which are constrained by an initial expression. Basically it
1499 -- transforms an unconstrained subtype indication into a constrained one.
1501 -- The expression may also be transformed in certain cases in order to
1502 -- avoid multiple evaluation. In the static allocation case, the general
1507 -- is transformed into
1509 -- Val : Constrained_Subtype_of_T := Maybe_Modified_Expr;
1511 -- Here are the main cases :
1513 -- <if Expr is a Slice>
1514 -- Val : T ([Index_Subtype (Expr)]) := Expr;
1516 -- <elsif Expr is a String Literal>
1517 -- Val : T (T'First .. T'First + Length (string literal) - 1) := Expr;
1519 -- <elsif Expr is Constrained>
1520 -- subtype T is Type_Of_Expr
1523 -- <elsif Expr is an entity_name>
1524 -- Val : T (constraints taken from Expr) := Expr;
1527 -- type Axxx is access all T;
1528 -- Rval : Axxx := Expr'ref;
1529 -- Val : T (constraints taken from Rval) := Rval.all;
1531 -- ??? note: when the Expression is allocated in the secondary stack
1532 -- we could use it directly instead of copying it by declaring
1533 -- Val : T (...) renames Rval.all
1535 procedure Expand_Subtype_From_Expr
1537 Unc_Type : Entity_Id;
1538 Subtype_Indic : Node_Id;
1541 Loc : constant Source_Ptr := Sloc (N);
1542 Exp_Typ : constant Entity_Id := Etype (Exp);
1546 -- In general we cannot build the subtype if expansion is disabled,
1547 -- because internal entities may not have been defined. However, to
1548 -- avoid some cascaded errors, we try to continue when the expression is
1549 -- an array (or string), because it is safe to compute the bounds. It is
1550 -- in fact required to do so even in a generic context, because there
1551 -- may be constants that depend on the bounds of a string literal, both
1552 -- standard string types and more generally arrays of characters.
1554 if not Expander_Active
1555 and then (No (Etype (Exp))
1556 or else not Is_String_Type (Etype (Exp)))
1561 if Nkind (Exp) = N_Slice then
1563 Slice_Type : constant Entity_Id := Etype (First_Index (Exp_Typ));
1566 Rewrite (Subtype_Indic,
1567 Make_Subtype_Indication (Loc,
1568 Subtype_Mark => New_Reference_To (Unc_Type, Loc),
1570 Make_Index_Or_Discriminant_Constraint (Loc,
1571 Constraints => New_List
1572 (New_Reference_To (Slice_Type, Loc)))));
1574 -- This subtype indication may be used later for constraint checks
1575 -- we better make sure that if a variable was used as a bound of
1576 -- of the original slice, its value is frozen.
1578 Force_Evaluation (Low_Bound (Scalar_Range (Slice_Type)));
1579 Force_Evaluation (High_Bound (Scalar_Range (Slice_Type)));
1582 elsif Ekind (Exp_Typ) = E_String_Literal_Subtype then
1583 Rewrite (Subtype_Indic,
1584 Make_Subtype_Indication (Loc,
1585 Subtype_Mark => New_Reference_To (Unc_Type, Loc),
1587 Make_Index_Or_Discriminant_Constraint (Loc,
1588 Constraints => New_List (
1589 Make_Literal_Range (Loc,
1590 Literal_Typ => Exp_Typ)))));
1592 elsif Is_Constrained (Exp_Typ)
1593 and then not Is_Class_Wide_Type (Unc_Type)
1595 if Is_Itype (Exp_Typ) then
1597 -- Within an initialization procedure, a selected component
1598 -- denotes a component of the enclosing record, and it appears as
1599 -- an actual in a call to its own initialization procedure. If
1600 -- this component depends on the outer discriminant, we must
1601 -- generate the proper actual subtype for it.
1603 if Nkind (Exp) = N_Selected_Component
1604 and then Within_Init_Proc
1607 Decl : constant Node_Id :=
1608 Build_Actual_Subtype_Of_Component (Exp_Typ, Exp);
1610 if Present (Decl) then
1611 Insert_Action (N, Decl);
1612 T := Defining_Identifier (Decl);
1618 -- No need to generate a new one (new what???)
1625 T := Make_Temporary (Loc, 'T');
1628 Make_Subtype_Declaration (Loc,
1629 Defining_Identifier => T,
1630 Subtype_Indication => New_Reference_To (Exp_Typ, Loc)));
1632 -- This type is marked as an itype even though it has an explicit
1633 -- declaration since otherwise Is_Generic_Actual_Type can get
1634 -- set, resulting in the generation of spurious errors. (See
1635 -- sem_ch8.Analyze_Package_Renaming and sem_type.covers)
1638 Set_Associated_Node_For_Itype (T, Exp);
1641 Rewrite (Subtype_Indic, New_Reference_To (T, Loc));
1643 -- Nothing needs to be done for private types with unknown discriminants
1644 -- if the underlying type is not an unconstrained composite type or it
1645 -- is an unchecked union.
1647 elsif Is_Private_Type (Unc_Type)
1648 and then Has_Unknown_Discriminants (Unc_Type)
1649 and then (not Is_Composite_Type (Underlying_Type (Unc_Type))
1650 or else Is_Constrained (Underlying_Type (Unc_Type))
1651 or else Is_Unchecked_Union (Underlying_Type (Unc_Type)))
1655 -- Case of derived type with unknown discriminants where the parent type
1656 -- also has unknown discriminants.
1658 elsif Is_Record_Type (Unc_Type)
1659 and then not Is_Class_Wide_Type (Unc_Type)
1660 and then Has_Unknown_Discriminants (Unc_Type)
1661 and then Has_Unknown_Discriminants (Underlying_Type (Unc_Type))
1663 -- Nothing to be done if no underlying record view available
1665 if No (Underlying_Record_View (Unc_Type)) then
1668 -- Otherwise use the Underlying_Record_View to create the proper
1669 -- constrained subtype for an object of a derived type with unknown
1673 Remove_Side_Effects (Exp);
1674 Rewrite (Subtype_Indic,
1675 Make_Subtype_From_Expr (Exp, Underlying_Record_View (Unc_Type)));
1678 -- Renamings of class-wide interface types require no equivalent
1679 -- constrained type declarations because we only need to reference
1680 -- the tag component associated with the interface. The same is
1681 -- presumably true for class-wide types in general, so this test
1682 -- is broadened to include all class-wide renamings, which also
1683 -- avoids cases of unbounded recursion in Remove_Side_Effects.
1684 -- (Is this really correct, or are there some cases of class-wide
1685 -- renamings that require action in this procedure???)
1688 and then Nkind (N) = N_Object_Renaming_Declaration
1689 and then Is_Class_Wide_Type (Unc_Type)
1693 -- In Ada95 nothing to be done if the type of the expression is limited,
1694 -- because in this case the expression cannot be copied, and its use can
1695 -- only be by reference.
1697 -- In Ada2005, the context can be an object declaration whose expression
1698 -- is a function that returns in place. If the nominal subtype has
1699 -- unknown discriminants, the call still provides constraints on the
1700 -- object, and we have to create an actual subtype from it.
1702 -- If the type is class-wide, the expression is dynamically tagged and
1703 -- we do not create an actual subtype either. Ditto for an interface.
1704 -- For now this applies only if the type is immutably limited, and the
1705 -- function being called is build-in-place. This will have to be revised
1706 -- when build-in-place functions are generalized to other types.
1708 elsif Is_Immutably_Limited_Type (Exp_Typ)
1710 (Is_Class_Wide_Type (Exp_Typ)
1711 or else Is_Interface (Exp_Typ)
1712 or else not Has_Unknown_Discriminants (Exp_Typ)
1713 or else not Is_Composite_Type (Unc_Type))
1717 -- For limited objects initialized with build in place function calls,
1718 -- nothing to be done; otherwise we prematurely introduce an N_Reference
1719 -- node in the expression initializing the object, which breaks the
1720 -- circuitry that detects and adds the additional arguments to the
1723 elsif Is_Build_In_Place_Function_Call (Exp) then
1727 Remove_Side_Effects (Exp);
1728 Rewrite (Subtype_Indic,
1729 Make_Subtype_From_Expr (Exp, Unc_Type));
1731 end Expand_Subtype_From_Expr;
1733 --------------------
1734 -- Find_Init_Call --
1735 --------------------
1737 function Find_Init_Call
1739 Rep_Clause : Node_Id) return Node_Id
1741 Typ : constant Entity_Id := Etype (Var);
1743 Init_Proc : Entity_Id;
1744 -- Initialization procedure for Typ
1746 function Find_Init_Call_In_List (From : Node_Id) return Node_Id;
1747 -- Look for init call for Var starting at From and scanning the
1748 -- enclosing list until Rep_Clause or the end of the list is reached.
1750 ----------------------------
1751 -- Find_Init_Call_In_List --
1752 ----------------------------
1754 function Find_Init_Call_In_List (From : Node_Id) return Node_Id is
1755 Init_Call : Node_Id;
1759 while Present (Init_Call) and then Init_Call /= Rep_Clause loop
1760 if Nkind (Init_Call) = N_Procedure_Call_Statement
1761 and then Is_Entity_Name (Name (Init_Call))
1762 and then Entity (Name (Init_Call)) = Init_Proc
1771 end Find_Init_Call_In_List;
1773 Init_Call : Node_Id;
1775 -- Start of processing for Find_Init_Call
1778 if not Has_Non_Null_Base_Init_Proc (Typ) then
1779 -- No init proc for the type, so obviously no call to be found
1784 Init_Proc := Base_Init_Proc (Typ);
1786 -- First scan the list containing the declaration of Var
1788 Init_Call := Find_Init_Call_In_List (From => Next (Parent (Var)));
1790 -- If not found, also look on Var's freeze actions list, if any, since
1791 -- the init call may have been moved there (case of an address clause
1792 -- applying to Var).
1794 if No (Init_Call) and then Present (Freeze_Node (Var)) then
1796 Find_Init_Call_In_List (First (Actions (Freeze_Node (Var))));
1802 ------------------------
1803 -- Find_Interface_ADT --
1804 ------------------------
1806 function Find_Interface_ADT
1808 Iface : Entity_Id) return Elmt_Id
1811 Typ : Entity_Id := T;
1814 pragma Assert (Is_Interface (Iface));
1816 -- Handle private types
1818 if Has_Private_Declaration (Typ)
1819 and then Present (Full_View (Typ))
1821 Typ := Full_View (Typ);
1824 -- Handle access types
1826 if Is_Access_Type (Typ) then
1827 Typ := Designated_Type (Typ);
1830 -- Handle task and protected types implementing interfaces
1832 if Is_Concurrent_Type (Typ) then
1833 Typ := Corresponding_Record_Type (Typ);
1837 (not Is_Class_Wide_Type (Typ)
1838 and then Ekind (Typ) /= E_Incomplete_Type);
1840 if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
1841 return First_Elmt (Access_Disp_Table (Typ));
1845 Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
1847 and then Present (Related_Type (Node (ADT)))
1848 and then Related_Type (Node (ADT)) /= Iface
1849 and then not Is_Ancestor (Iface, Related_Type (Node (ADT)),
1850 Use_Full_View => True)
1855 pragma Assert (Present (Related_Type (Node (ADT))));
1858 end Find_Interface_ADT;
1860 ------------------------
1861 -- Find_Interface_Tag --
1862 ------------------------
1864 function Find_Interface_Tag
1866 Iface : Entity_Id) return Entity_Id
1869 Found : Boolean := False;
1870 Typ : Entity_Id := T;
1872 procedure Find_Tag (Typ : Entity_Id);
1873 -- Internal subprogram used to recursively climb to the ancestors
1879 procedure Find_Tag (Typ : Entity_Id) is
1884 -- This routine does not handle the case in which the interface is an
1885 -- ancestor of Typ. That case is handled by the enclosing subprogram.
1887 pragma Assert (Typ /= Iface);
1889 -- Climb to the root type handling private types
1891 if Present (Full_View (Etype (Typ))) then
1892 if Full_View (Etype (Typ)) /= Typ then
1893 Find_Tag (Full_View (Etype (Typ)));
1896 elsif Etype (Typ) /= Typ then
1897 Find_Tag (Etype (Typ));
1900 -- Traverse the list of interfaces implemented by the type
1903 and then Present (Interfaces (Typ))
1904 and then not (Is_Empty_Elmt_List (Interfaces (Typ)))
1906 -- Skip the tag associated with the primary table
1908 pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
1909 AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
1910 pragma Assert (Present (AI_Tag));
1912 AI_Elmt := First_Elmt (Interfaces (Typ));
1913 while Present (AI_Elmt) loop
1914 AI := Node (AI_Elmt);
1917 or else Is_Ancestor (Iface, AI, Use_Full_View => True)
1923 AI_Tag := Next_Tag_Component (AI_Tag);
1924 Next_Elmt (AI_Elmt);
1929 -- Start of processing for Find_Interface_Tag
1932 pragma Assert (Is_Interface (Iface));
1934 -- Handle access types
1936 if Is_Access_Type (Typ) then
1937 Typ := Designated_Type (Typ);
1940 -- Handle class-wide types
1942 if Is_Class_Wide_Type (Typ) then
1943 Typ := Root_Type (Typ);
1946 -- Handle private types
1948 if Has_Private_Declaration (Typ)
1949 and then Present (Full_View (Typ))
1951 Typ := Full_View (Typ);
1954 -- Handle entities from the limited view
1956 if Ekind (Typ) = E_Incomplete_Type then
1957 pragma Assert (Present (Non_Limited_View (Typ)));
1958 Typ := Non_Limited_View (Typ);
1961 -- Handle task and protected types implementing interfaces
1963 if Is_Concurrent_Type (Typ) then
1964 Typ := Corresponding_Record_Type (Typ);
1967 -- If the interface is an ancestor of the type, then it shared the
1968 -- primary dispatch table.
1970 if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
1971 pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
1972 return First_Tag_Component (Typ);
1974 -- Otherwise we need to search for its associated tag component
1978 pragma Assert (Found);
1981 end Find_Interface_Tag;
1987 function Find_Prim_Op (T : Entity_Id; Name : Name_Id) return Entity_Id is
1989 Typ : Entity_Id := T;
1993 if Is_Class_Wide_Type (Typ) then
1994 Typ := Root_Type (Typ);
1997 Typ := Underlying_Type (Typ);
1999 -- Loop through primitive operations
2001 Prim := First_Elmt (Primitive_Operations (Typ));
2002 while Present (Prim) loop
2005 -- We can retrieve primitive operations by name if it is an internal
2006 -- name. For equality we must check that both of its operands have
2007 -- the same type, to avoid confusion with user-defined equalities
2008 -- than may have a non-symmetric signature.
2010 exit when Chars (Op) = Name
2013 or else Etype (First_Formal (Op)) = Etype (Last_Formal (Op)));
2017 -- Raise Program_Error if no primitive found
2020 raise Program_Error;
2031 function Find_Prim_Op
2033 Name : TSS_Name_Type) return Entity_Id
2035 Inher_Op : Entity_Id := Empty;
2036 Own_Op : Entity_Id := Empty;
2037 Prim_Elmt : Elmt_Id;
2038 Prim_Id : Entity_Id;
2039 Typ : Entity_Id := T;
2042 if Is_Class_Wide_Type (Typ) then
2043 Typ := Root_Type (Typ);
2046 Typ := Underlying_Type (Typ);
2048 -- This search is based on the assertion that the dispatching version
2049 -- of the TSS routine always precedes the real primitive.
2051 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2052 while Present (Prim_Elmt) loop
2053 Prim_Id := Node (Prim_Elmt);
2055 if Is_TSS (Prim_Id, Name) then
2056 if Present (Alias (Prim_Id)) then
2057 Inher_Op := Prim_Id;
2063 Next_Elmt (Prim_Elmt);
2066 if Present (Own_Op) then
2068 elsif Present (Inher_Op) then
2071 raise Program_Error;
2075 ----------------------------
2076 -- Find_Protection_Object --
2077 ----------------------------
2079 function Find_Protection_Object (Scop : Entity_Id) return Entity_Id is
2084 while Present (S) loop
2085 if (Ekind (S) = E_Entry
2086 or else Ekind (S) = E_Entry_Family
2087 or else Ekind (S) = E_Function
2088 or else Ekind (S) = E_Procedure)
2089 and then Present (Protection_Object (S))
2091 return Protection_Object (S);
2097 -- If we do not find a Protection object in the scope chain, then
2098 -- something has gone wrong, most likely the object was never created.
2100 raise Program_Error;
2101 end Find_Protection_Object;
2103 --------------------------
2104 -- Find_Protection_Type --
2105 --------------------------
2107 function Find_Protection_Type (Conc_Typ : Entity_Id) return Entity_Id is
2109 Typ : Entity_Id := Conc_Typ;
2112 if Is_Concurrent_Type (Typ) then
2113 Typ := Corresponding_Record_Type (Typ);
2116 Comp := First_Component (Typ);
2117 while Present (Comp) loop
2118 if Chars (Comp) = Name_uObject then
2119 return Base_Type (Etype (Comp));
2122 Next_Component (Comp);
2125 -- The corresponding record of a protected type should always have an
2128 raise Program_Error;
2129 end Find_Protection_Type;
2131 ----------------------
2132 -- Force_Evaluation --
2133 ----------------------
2135 procedure Force_Evaluation (Exp : Node_Id; Name_Req : Boolean := False) is
2137 Remove_Side_Effects (Exp, Name_Req, Variable_Ref => True);
2138 end Force_Evaluation;
2140 ---------------------------------
2141 -- Fully_Qualified_Name_String --
2142 ---------------------------------
2144 function Fully_Qualified_Name_String (E : Entity_Id) return String_Id is
2145 procedure Internal_Full_Qualified_Name (E : Entity_Id);
2146 -- Compute recursively the qualified name without NUL at the end, adding
2147 -- it to the currently started string being generated
2149 ----------------------------------
2150 -- Internal_Full_Qualified_Name --
2151 ----------------------------------
2153 procedure Internal_Full_Qualified_Name (E : Entity_Id) is
2157 -- Deal properly with child units
2159 if Nkind (E) = N_Defining_Program_Unit_Name then
2160 Ent := Defining_Identifier (E);
2165 -- Compute qualification recursively (only "Standard" has no scope)
2167 if Present (Scope (Scope (Ent))) then
2168 Internal_Full_Qualified_Name (Scope (Ent));
2169 Store_String_Char (Get_Char_Code ('.'));
2172 -- Every entity should have a name except some expanded blocks
2173 -- don't bother about those.
2175 if Chars (Ent) = No_Name then
2179 -- Generates the entity name in upper case
2181 Get_Decoded_Name_String (Chars (Ent));
2183 Store_String_Chars (Name_Buffer (1 .. Name_Len));
2185 end Internal_Full_Qualified_Name;
2187 -- Start of processing for Full_Qualified_Name
2191 Internal_Full_Qualified_Name (E);
2192 Store_String_Char (Get_Char_Code (ASCII.NUL));
2194 end Fully_Qualified_Name_String;
2196 ------------------------
2197 -- Generate_Poll_Call --
2198 ------------------------
2200 procedure Generate_Poll_Call (N : Node_Id) is
2202 -- No poll call if polling not active
2204 if not Polling_Required then
2207 -- Otherwise generate require poll call
2210 Insert_Before_And_Analyze (N,
2211 Make_Procedure_Call_Statement (Sloc (N),
2212 Name => New_Occurrence_Of (RTE (RE_Poll), Sloc (N))));
2214 end Generate_Poll_Call;
2216 ---------------------------------
2217 -- Get_Current_Value_Condition --
2218 ---------------------------------
2220 -- Note: the implementation of this procedure is very closely tied to the
2221 -- implementation of Set_Current_Value_Condition. In the Get procedure, we
2222 -- interpret Current_Value fields set by the Set procedure, so the two
2223 -- procedures need to be closely coordinated.
2225 procedure Get_Current_Value_Condition
2230 Loc : constant Source_Ptr := Sloc (Var);
2231 Ent : constant Entity_Id := Entity (Var);
2233 procedure Process_Current_Value_Condition
2236 -- N is an expression which holds either True (S = True) or False (S =
2237 -- False) in the condition. This procedure digs out the expression and
2238 -- if it refers to Ent, sets Op and Val appropriately.
2240 -------------------------------------
2241 -- Process_Current_Value_Condition --
2242 -------------------------------------
2244 procedure Process_Current_Value_Condition
2255 -- Deal with NOT operators, inverting sense
2257 while Nkind (Cond) = N_Op_Not loop
2258 Cond := Right_Opnd (Cond);
2262 -- Deal with AND THEN and AND cases
2264 if Nkind (Cond) = N_And_Then
2265 or else Nkind (Cond) = N_Op_And
2267 -- Don't ever try to invert a condition that is of the form of an
2268 -- AND or AND THEN (since we are not doing sufficiently general
2269 -- processing to allow this).
2271 if Sens = False then
2277 -- Recursively process AND and AND THEN branches
2279 Process_Current_Value_Condition (Left_Opnd (Cond), True);
2281 if Op /= N_Empty then
2285 Process_Current_Value_Condition (Right_Opnd (Cond), True);
2288 -- Case of relational operator
2290 elsif Nkind (Cond) in N_Op_Compare then
2293 -- Invert sense of test if inverted test
2295 if Sens = False then
2297 when N_Op_Eq => Op := N_Op_Ne;
2298 when N_Op_Ne => Op := N_Op_Eq;
2299 when N_Op_Lt => Op := N_Op_Ge;
2300 when N_Op_Gt => Op := N_Op_Le;
2301 when N_Op_Le => Op := N_Op_Gt;
2302 when N_Op_Ge => Op := N_Op_Lt;
2303 when others => raise Program_Error;
2307 -- Case of entity op value
2309 if Is_Entity_Name (Left_Opnd (Cond))
2310 and then Ent = Entity (Left_Opnd (Cond))
2311 and then Compile_Time_Known_Value (Right_Opnd (Cond))
2313 Val := Right_Opnd (Cond);
2315 -- Case of value op entity
2317 elsif Is_Entity_Name (Right_Opnd (Cond))
2318 and then Ent = Entity (Right_Opnd (Cond))
2319 and then Compile_Time_Known_Value (Left_Opnd (Cond))
2321 Val := Left_Opnd (Cond);
2323 -- We are effectively swapping operands
2326 when N_Op_Eq => null;
2327 when N_Op_Ne => null;
2328 when N_Op_Lt => Op := N_Op_Gt;
2329 when N_Op_Gt => Op := N_Op_Lt;
2330 when N_Op_Le => Op := N_Op_Ge;
2331 when N_Op_Ge => Op := N_Op_Le;
2332 when others => raise Program_Error;
2341 -- Case of Boolean variable reference, return as though the
2342 -- reference had said var = True.
2345 if Is_Entity_Name (Cond)
2346 and then Ent = Entity (Cond)
2348 Val := New_Occurrence_Of (Standard_True, Sloc (Cond));
2350 if Sens = False then
2357 end Process_Current_Value_Condition;
2359 -- Start of processing for Get_Current_Value_Condition
2365 -- Immediate return, nothing doing, if this is not an object
2367 if Ekind (Ent) not in Object_Kind then
2371 -- Otherwise examine current value
2374 CV : constant Node_Id := Current_Value (Ent);
2379 -- If statement. Condition is known true in THEN section, known False
2380 -- in any ELSIF or ELSE part, and unknown outside the IF statement.
2382 if Nkind (CV) = N_If_Statement then
2384 -- Before start of IF statement
2386 if Loc < Sloc (CV) then
2389 -- After end of IF statement
2391 elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then
2395 -- At this stage we know that we are within the IF statement, but
2396 -- unfortunately, the tree does not record the SLOC of the ELSE so
2397 -- we cannot use a simple SLOC comparison to distinguish between
2398 -- the then/else statements, so we have to climb the tree.
2405 while Parent (N) /= CV loop
2408 -- If we fall off the top of the tree, then that's odd, but
2409 -- perhaps it could occur in some error situation, and the
2410 -- safest response is simply to assume that the outcome of
2411 -- the condition is unknown. No point in bombing during an
2412 -- attempt to optimize things.
2419 -- Now we have N pointing to a node whose parent is the IF
2420 -- statement in question, so now we can tell if we are within
2421 -- the THEN statements.
2423 if Is_List_Member (N)
2424 and then List_Containing (N) = Then_Statements (CV)
2428 -- If the variable reference does not come from source, we
2429 -- cannot reliably tell whether it appears in the else part.
2430 -- In particular, if it appears in generated code for a node
2431 -- that requires finalization, it may be attached to a list
2432 -- that has not been yet inserted into the code. For now,
2433 -- treat it as unknown.
2435 elsif not Comes_From_Source (N) then
2438 -- Otherwise we must be in ELSIF or ELSE part
2445 -- ELSIF part. Condition is known true within the referenced
2446 -- ELSIF, known False in any subsequent ELSIF or ELSE part,
2447 -- and unknown before the ELSE part or after the IF statement.
2449 elsif Nkind (CV) = N_Elsif_Part then
2451 -- if the Elsif_Part had condition_actions, the elsif has been
2452 -- rewritten as a nested if, and the original elsif_part is
2453 -- detached from the tree, so there is no way to obtain useful
2454 -- information on the current value of the variable.
2455 -- Can this be improved ???
2457 if No (Parent (CV)) then
2463 -- Before start of ELSIF part
2465 if Loc < Sloc (CV) then
2468 -- After end of IF statement
2470 elsif Loc >= Sloc (Stm) +
2471 Text_Ptr (UI_To_Int (End_Span (Stm)))
2476 -- Again we lack the SLOC of the ELSE, so we need to climb the
2477 -- tree to see if we are within the ELSIF part in question.
2484 while Parent (N) /= Stm loop
2487 -- If we fall off the top of the tree, then that's odd, but
2488 -- perhaps it could occur in some error situation, and the
2489 -- safest response is simply to assume that the outcome of
2490 -- the condition is unknown. No point in bombing during an
2491 -- attempt to optimize things.
2498 -- Now we have N pointing to a node whose parent is the IF
2499 -- statement in question, so see if is the ELSIF part we want.
2500 -- the THEN statements.
2505 -- Otherwise we must be in subsequent ELSIF or ELSE part
2512 -- Iteration scheme of while loop. The condition is known to be
2513 -- true within the body of the loop.
2515 elsif Nkind (CV) = N_Iteration_Scheme then
2517 Loop_Stmt : constant Node_Id := Parent (CV);
2520 -- Before start of body of loop
2522 if Loc < Sloc (Loop_Stmt) then
2525 -- After end of LOOP statement
2527 elsif Loc >= Sloc (End_Label (Loop_Stmt)) then
2530 -- We are within the body of the loop
2537 -- All other cases of Current_Value settings
2543 -- If we fall through here, then we have a reportable condition, Sens
2544 -- is True if the condition is true and False if it needs inverting.
2546 Process_Current_Value_Condition (Condition (CV), Sens);
2548 end Get_Current_Value_Condition;
2550 ---------------------
2551 -- Get_Stream_Size --
2552 ---------------------
2554 function Get_Stream_Size (E : Entity_Id) return Uint is
2556 -- If we have a Stream_Size clause for this type use it
2558 if Has_Stream_Size_Clause (E) then
2559 return Static_Integer (Expression (Stream_Size_Clause (E)));
2561 -- Otherwise the Stream_Size if the size of the type
2566 end Get_Stream_Size;
2568 ---------------------------
2569 -- Has_Access_Constraint --
2570 ---------------------------
2572 function Has_Access_Constraint (E : Entity_Id) return Boolean is
2574 T : constant Entity_Id := Etype (E);
2577 if Has_Per_Object_Constraint (E)
2578 and then Has_Discriminants (T)
2580 Disc := First_Discriminant (T);
2581 while Present (Disc) loop
2582 if Is_Access_Type (Etype (Disc)) then
2586 Next_Discriminant (Disc);
2593 end Has_Access_Constraint;
2595 ----------------------------------
2596 -- Has_Following_Address_Clause --
2597 ----------------------------------
2599 -- Should this function check the private part in a package ???
2601 function Has_Following_Address_Clause (D : Node_Id) return Boolean is
2602 Id : constant Entity_Id := Defining_Identifier (D);
2607 while Present (Decl) loop
2608 if Nkind (Decl) = N_At_Clause
2609 and then Chars (Identifier (Decl)) = Chars (Id)
2613 elsif Nkind (Decl) = N_Attribute_Definition_Clause
2614 and then Chars (Decl) = Name_Address
2615 and then Chars (Name (Decl)) = Chars (Id)
2624 end Has_Following_Address_Clause;
2626 --------------------
2627 -- Homonym_Number --
2628 --------------------
2630 function Homonym_Number (Subp : Entity_Id) return Nat is
2636 Hom := Homonym (Subp);
2637 while Present (Hom) loop
2638 if Scope (Hom) = Scope (Subp) then
2642 Hom := Homonym (Hom);
2648 -----------------------------------
2649 -- In_Library_Level_Package_Body --
2650 -----------------------------------
2652 function In_Library_Level_Package_Body (Id : Entity_Id) return Boolean is
2654 -- First determine whether the entity appears at the library level, then
2655 -- look at the containing unit.
2657 if Is_Library_Level_Entity (Id) then
2659 Container : constant Node_Id := Cunit (Get_Source_Unit (Id));
2662 return Nkind (Unit (Container)) = N_Package_Body;
2667 end In_Library_Level_Package_Body;
2669 ------------------------------
2670 -- In_Unconditional_Context --
2671 ------------------------------
2673 function In_Unconditional_Context (Node : Node_Id) return Boolean is
2678 while Present (P) loop
2680 when N_Subprogram_Body =>
2683 when N_If_Statement =>
2686 when N_Loop_Statement =>
2689 when N_Case_Statement =>
2698 end In_Unconditional_Context;
2704 procedure Insert_Action (Assoc_Node : Node_Id; Ins_Action : Node_Id) is
2706 if Present (Ins_Action) then
2707 Insert_Actions (Assoc_Node, New_List (Ins_Action));
2711 -- Version with check(s) suppressed
2713 procedure Insert_Action
2714 (Assoc_Node : Node_Id; Ins_Action : Node_Id; Suppress : Check_Id)
2717 Insert_Actions (Assoc_Node, New_List (Ins_Action), Suppress);
2720 -------------------------
2721 -- Insert_Action_After --
2722 -------------------------
2724 procedure Insert_Action_After
2725 (Assoc_Node : Node_Id;
2726 Ins_Action : Node_Id)
2729 Insert_Actions_After (Assoc_Node, New_List (Ins_Action));
2730 end Insert_Action_After;
2732 --------------------
2733 -- Insert_Actions --
2734 --------------------
2736 procedure Insert_Actions (Assoc_Node : Node_Id; Ins_Actions : List_Id) is
2740 Wrapped_Node : Node_Id := Empty;
2743 if No (Ins_Actions) or else Is_Empty_List (Ins_Actions) then
2747 -- Ignore insert of actions from inside default expression (or other
2748 -- similar "spec expression") in the special spec-expression analyze
2749 -- mode. Any insertions at this point have no relevance, since we are
2750 -- only doing the analyze to freeze the types of any static expressions.
2751 -- See section "Handling of Default Expressions" in the spec of package
2752 -- Sem for further details.
2754 if In_Spec_Expression then
2758 -- If the action derives from stuff inside a record, then the actions
2759 -- are attached to the current scope, to be inserted and analyzed on
2760 -- exit from the scope. The reason for this is that we may also be
2761 -- generating freeze actions at the same time, and they must eventually
2762 -- be elaborated in the correct order.
2764 if Is_Record_Type (Current_Scope)
2765 and then not Is_Frozen (Current_Scope)
2767 if No (Scope_Stack.Table
2768 (Scope_Stack.Last).Pending_Freeze_Actions)
2770 Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions :=
2775 Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions);
2781 -- We now intend to climb up the tree to find the right point to
2782 -- insert the actions. We start at Assoc_Node, unless this node is a
2783 -- subexpression in which case we start with its parent. We do this for
2784 -- two reasons. First it speeds things up. Second, if Assoc_Node is
2785 -- itself one of the special nodes like N_And_Then, then we assume that
2786 -- an initial request to insert actions for such a node does not expect
2787 -- the actions to get deposited in the node for later handling when the
2788 -- node is expanded, since clearly the node is being dealt with by the
2789 -- caller. Note that in the subexpression case, N is always the child we
2792 -- N_Raise_xxx_Error is an annoying special case, it is a statement if
2793 -- it has type Standard_Void_Type, and a subexpression otherwise.
2794 -- otherwise. Procedure attribute references are also statements.
2796 if Nkind (Assoc_Node) in N_Subexpr
2797 and then (Nkind (Assoc_Node) in N_Raise_xxx_Error
2798 or else Etype (Assoc_Node) /= Standard_Void_Type)
2799 and then (Nkind (Assoc_Node) /= N_Attribute_Reference
2801 not Is_Procedure_Attribute_Name
2802 (Attribute_Name (Assoc_Node)))
2804 P := Assoc_Node; -- ??? does not agree with above!
2805 N := Parent (Assoc_Node);
2807 -- Non-subexpression case. Note that N is initially Empty in this case
2808 -- (N is only guaranteed Non-Empty in the subexpr case).
2815 -- Capture root of the transient scope
2817 if Scope_Is_Transient then
2818 Wrapped_Node := Node_To_Be_Wrapped;
2822 pragma Assert (Present (P));
2826 -- Case of right operand of AND THEN or OR ELSE. Put the actions
2827 -- in the Actions field of the right operand. They will be moved
2828 -- out further when the AND THEN or OR ELSE operator is expanded.
2829 -- Nothing special needs to be done for the left operand since
2830 -- in that case the actions are executed unconditionally.
2832 when N_Short_Circuit =>
2833 if N = Right_Opnd (P) then
2835 -- We are now going to either append the actions to the
2836 -- actions field of the short-circuit operation. We will
2837 -- also analyze the actions now.
2839 -- This analysis is really too early, the proper thing would
2840 -- be to just park them there now, and only analyze them if
2841 -- we find we really need them, and to it at the proper
2842 -- final insertion point. However attempting to this proved
2843 -- tricky, so for now we just kill current values before and
2844 -- after the analyze call to make sure we avoid peculiar
2845 -- optimizations from this out of order insertion.
2847 Kill_Current_Values;
2849 if Present (Actions (P)) then
2850 Insert_List_After_And_Analyze
2851 (Last (Actions (P)), Ins_Actions);
2853 Set_Actions (P, Ins_Actions);
2854 Analyze_List (Actions (P));
2857 Kill_Current_Values;
2862 -- Then or Else operand of conditional expression. Add actions to
2863 -- Then_Actions or Else_Actions field as appropriate. The actions
2864 -- will be moved further out when the conditional is expanded.
2866 when N_Conditional_Expression =>
2868 ThenX : constant Node_Id := Next (First (Expressions (P)));
2869 ElseX : constant Node_Id := Next (ThenX);
2872 -- If the enclosing expression is already analyzed, as
2873 -- is the case for nested elaboration checks, insert the
2874 -- conditional further out.
2876 if Analyzed (P) then
2879 -- Actions belong to the then expression, temporarily place
2880 -- them as Then_Actions of the conditional expr. They will
2881 -- be moved to the proper place later when the conditional
2882 -- expression is expanded.
2884 elsif N = ThenX then
2885 if Present (Then_Actions (P)) then
2886 Insert_List_After_And_Analyze
2887 (Last (Then_Actions (P)), Ins_Actions);
2889 Set_Then_Actions (P, Ins_Actions);
2890 Analyze_List (Then_Actions (P));
2895 -- Actions belong to the else expression, temporarily
2896 -- place them as Else_Actions of the conditional expr.
2897 -- They will be moved to the proper place later when
2898 -- the conditional expression is expanded.
2900 elsif N = ElseX then
2901 if Present (Else_Actions (P)) then
2902 Insert_List_After_And_Analyze
2903 (Last (Else_Actions (P)), Ins_Actions);
2905 Set_Else_Actions (P, Ins_Actions);
2906 Analyze_List (Else_Actions (P));
2911 -- Actions belong to the condition. In this case they are
2912 -- unconditionally executed, and so we can continue the
2913 -- search for the proper insert point.
2920 -- Alternative of case expression, we place the action in the
2921 -- Actions field of the case expression alternative, this will
2922 -- be handled when the case expression is expanded.
2924 when N_Case_Expression_Alternative =>
2925 if Present (Actions (P)) then
2926 Insert_List_After_And_Analyze
2927 (Last (Actions (P)), Ins_Actions);
2929 Set_Actions (P, Ins_Actions);
2930 Analyze_List (Actions (P));
2935 -- Case of appearing within an Expressions_With_Actions node. We
2936 -- prepend the actions to the list of actions already there, if
2937 -- the node has not been analyzed yet. Otherwise find insertion
2938 -- location further up the tree.
2940 when N_Expression_With_Actions =>
2941 if not Analyzed (P) then
2942 Prepend_List (Ins_Actions, Actions (P));
2946 -- Case of appearing in the condition of a while expression or
2947 -- elsif. We insert the actions into the Condition_Actions field.
2948 -- They will be moved further out when the while loop or elsif
2951 when N_Iteration_Scheme |
2954 if N = Condition (P) then
2955 if Present (Condition_Actions (P)) then
2956 Insert_List_After_And_Analyze
2957 (Last (Condition_Actions (P)), Ins_Actions);
2959 Set_Condition_Actions (P, Ins_Actions);
2961 -- Set the parent of the insert actions explicitly. This
2962 -- is not a syntactic field, but we need the parent field
2963 -- set, in particular so that freeze can understand that
2964 -- it is dealing with condition actions, and properly
2965 -- insert the freezing actions.
2967 Set_Parent (Ins_Actions, P);
2968 Analyze_List (Condition_Actions (P));
2974 -- Statements, declarations, pragmas, representation clauses
2979 N_Procedure_Call_Statement |
2980 N_Statement_Other_Than_Procedure_Call |
2986 -- Representation_Clause
2989 N_Attribute_Definition_Clause |
2990 N_Enumeration_Representation_Clause |
2991 N_Record_Representation_Clause |
2995 N_Abstract_Subprogram_Declaration |
2997 N_Exception_Declaration |
2998 N_Exception_Renaming_Declaration |
2999 N_Expression_Function |
3000 N_Formal_Abstract_Subprogram_Declaration |
3001 N_Formal_Concrete_Subprogram_Declaration |
3002 N_Formal_Object_Declaration |
3003 N_Formal_Type_Declaration |
3004 N_Full_Type_Declaration |
3005 N_Function_Instantiation |
3006 N_Generic_Function_Renaming_Declaration |
3007 N_Generic_Package_Declaration |
3008 N_Generic_Package_Renaming_Declaration |
3009 N_Generic_Procedure_Renaming_Declaration |
3010 N_Generic_Subprogram_Declaration |
3011 N_Implicit_Label_Declaration |
3012 N_Incomplete_Type_Declaration |
3013 N_Number_Declaration |
3014 N_Object_Declaration |
3015 N_Object_Renaming_Declaration |
3017 N_Package_Body_Stub |
3018 N_Package_Declaration |
3019 N_Package_Instantiation |
3020 N_Package_Renaming_Declaration |
3021 N_Private_Extension_Declaration |
3022 N_Private_Type_Declaration |
3023 N_Procedure_Instantiation |
3025 N_Protected_Body_Stub |
3026 N_Protected_Type_Declaration |
3027 N_Single_Task_Declaration |
3029 N_Subprogram_Body_Stub |
3030 N_Subprogram_Declaration |
3031 N_Subprogram_Renaming_Declaration |
3032 N_Subtype_Declaration |
3035 N_Task_Type_Declaration |
3037 -- Freeze entity behaves like a declaration or statement
3041 -- Do not insert here if the item is not a list member (this
3042 -- happens for example with a triggering statement, and the
3043 -- proper approach is to insert before the entire select).
3045 if not Is_List_Member (P) then
3048 -- Do not insert if parent of P is an N_Component_Association
3049 -- node (i.e. we are in the context of an N_Aggregate or
3050 -- N_Extension_Aggregate node. In this case we want to insert
3051 -- before the entire aggregate.
3053 elsif Nkind (Parent (P)) = N_Component_Association then
3056 -- Do not insert if the parent of P is either an N_Variant node
3057 -- or an N_Record_Definition node, meaning in either case that
3058 -- P is a member of a component list, and that therefore the
3059 -- actions should be inserted outside the complete record
3062 elsif Nkind (Parent (P)) = N_Variant
3063 or else Nkind (Parent (P)) = N_Record_Definition
3067 -- Do not insert freeze nodes within the loop generated for
3068 -- an aggregate, because they may be elaborated too late for
3069 -- subsequent use in the back end: within a package spec the
3070 -- loop is part of the elaboration procedure and is only
3071 -- elaborated during the second pass.
3073 -- If the loop comes from source, or the entity is local to the
3074 -- loop itself it must remain within.
3076 elsif Nkind (Parent (P)) = N_Loop_Statement
3077 and then not Comes_From_Source (Parent (P))
3078 and then Nkind (First (Ins_Actions)) = N_Freeze_Entity
3080 Scope (Entity (First (Ins_Actions))) /= Current_Scope
3084 -- Otherwise we can go ahead and do the insertion
3086 elsif P = Wrapped_Node then
3087 Store_Before_Actions_In_Scope (Ins_Actions);
3091 Insert_List_Before_And_Analyze (P, Ins_Actions);
3095 -- A special case, N_Raise_xxx_Error can act either as a statement
3096 -- or a subexpression. We tell the difference by looking at the
3097 -- Etype. It is set to Standard_Void_Type in the statement case.
3100 N_Raise_xxx_Error =>
3101 if Etype (P) = Standard_Void_Type then
3102 if P = Wrapped_Node then
3103 Store_Before_Actions_In_Scope (Ins_Actions);
3105 Insert_List_Before_And_Analyze (P, Ins_Actions);
3110 -- In the subexpression case, keep climbing
3116 -- If a component association appears within a loop created for
3117 -- an array aggregate, attach the actions to the association so
3118 -- they can be subsequently inserted within the loop. For other
3119 -- component associations insert outside of the aggregate. For
3120 -- an association that will generate a loop, its Loop_Actions
3121 -- attribute is already initialized (see exp_aggr.adb).
3123 -- The list of loop_actions can in turn generate additional ones,
3124 -- that are inserted before the associated node. If the associated
3125 -- node is outside the aggregate, the new actions are collected
3126 -- at the end of the loop actions, to respect the order in which
3127 -- they are to be elaborated.
3130 N_Component_Association =>
3131 if Nkind (Parent (P)) = N_Aggregate
3132 and then Present (Loop_Actions (P))
3134 if Is_Empty_List (Loop_Actions (P)) then
3135 Set_Loop_Actions (P, Ins_Actions);
3136 Analyze_List (Ins_Actions);
3143 -- Check whether these actions were generated by a
3144 -- declaration that is part of the loop_ actions
3145 -- for the component_association.
3148 while Present (Decl) loop
3149 exit when Parent (Decl) = P
3150 and then Is_List_Member (Decl)
3152 List_Containing (Decl) = Loop_Actions (P);
3153 Decl := Parent (Decl);
3156 if Present (Decl) then
3157 Insert_List_Before_And_Analyze
3158 (Decl, Ins_Actions);
3160 Insert_List_After_And_Analyze
3161 (Last (Loop_Actions (P)), Ins_Actions);
3172 -- Another special case, an attribute denoting a procedure call
3175 N_Attribute_Reference =>
3176 if Is_Procedure_Attribute_Name (Attribute_Name (P)) then
3177 if P = Wrapped_Node then
3178 Store_Before_Actions_In_Scope (Ins_Actions);
3180 Insert_List_Before_And_Analyze (P, Ins_Actions);
3185 -- In the subexpression case, keep climbing
3191 -- A contract node should not belong to the tree
3194 raise Program_Error;
3196 -- For all other node types, keep climbing tree
3200 N_Accept_Alternative |
3201 N_Access_Definition |
3202 N_Access_Function_Definition |
3203 N_Access_Procedure_Definition |
3204 N_Access_To_Object_Definition |
3207 N_Aspect_Specification |
3209 N_Case_Statement_Alternative |
3210 N_Character_Literal |
3211 N_Compilation_Unit |
3212 N_Compilation_Unit_Aux |
3213 N_Component_Clause |
3214 N_Component_Declaration |
3215 N_Component_Definition |
3217 N_Constrained_Array_Definition |
3218 N_Decimal_Fixed_Point_Definition |
3219 N_Defining_Character_Literal |
3220 N_Defining_Identifier |
3221 N_Defining_Operator_Symbol |
3222 N_Defining_Program_Unit_Name |
3223 N_Delay_Alternative |
3224 N_Delta_Constraint |
3225 N_Derived_Type_Definition |
3227 N_Digits_Constraint |
3228 N_Discriminant_Association |
3229 N_Discriminant_Specification |
3231 N_Entry_Body_Formal_Part |
3232 N_Entry_Call_Alternative |
3233 N_Entry_Declaration |
3234 N_Entry_Index_Specification |
3235 N_Enumeration_Type_Definition |
3237 N_Exception_Handler |
3239 N_Explicit_Dereference |
3240 N_Extension_Aggregate |
3241 N_Floating_Point_Definition |
3242 N_Formal_Decimal_Fixed_Point_Definition |
3243 N_Formal_Derived_Type_Definition |
3244 N_Formal_Discrete_Type_Definition |
3245 N_Formal_Floating_Point_Definition |
3246 N_Formal_Modular_Type_Definition |
3247 N_Formal_Ordinary_Fixed_Point_Definition |
3248 N_Formal_Package_Declaration |
3249 N_Formal_Private_Type_Definition |
3250 N_Formal_Signed_Integer_Type_Definition |
3252 N_Function_Specification |
3253 N_Generic_Association |
3254 N_Handled_Sequence_Of_Statements |
3257 N_Index_Or_Discriminant_Constraint |
3258 N_Indexed_Component |
3260 N_Iterator_Specification |
3263 N_Loop_Parameter_Specification |
3265 N_Modular_Type_Definition |
3291 N_Op_Shift_Right_Arithmetic |
3295 N_Ordinary_Fixed_Point_Definition |
3297 N_Package_Specification |
3298 N_Parameter_Association |
3299 N_Parameter_Specification |
3300 N_Pop_Constraint_Error_Label |
3301 N_Pop_Program_Error_Label |
3302 N_Pop_Storage_Error_Label |
3303 N_Pragma_Argument_Association |
3304 N_Procedure_Specification |
3305 N_Protected_Definition |
3306 N_Push_Constraint_Error_Label |
3307 N_Push_Program_Error_Label |
3308 N_Push_Storage_Error_Label |
3309 N_Qualified_Expression |
3310 N_Quantified_Expression |
3312 N_Range_Constraint |
3314 N_Real_Range_Specification |
3315 N_Record_Definition |
3317 N_SCIL_Dispatch_Table_Tag_Init |
3318 N_SCIL_Dispatching_Call |
3319 N_SCIL_Membership_Test |
3320 N_Selected_Component |
3321 N_Signed_Integer_Type_Definition |
3322 N_Single_Protected_Declaration |
3326 N_Subtype_Indication |
3329 N_Terminate_Alternative |
3330 N_Triggering_Alternative |
3332 N_Unchecked_Expression |
3333 N_Unchecked_Type_Conversion |
3334 N_Unconstrained_Array_Definition |
3337 N_Use_Package_Clause |
3341 N_Validate_Unchecked_Conversion |
3348 -- Make sure that inserted actions stay in the transient scope
3350 if P = Wrapped_Node then
3351 Store_Before_Actions_In_Scope (Ins_Actions);
3355 -- If we fall through above tests, keep climbing tree
3359 if Nkind (Parent (N)) = N_Subunit then
3361 -- This is the proper body corresponding to a stub. Insertion must
3362 -- be done at the point of the stub, which is in the declarative
3363 -- part of the parent unit.
3365 P := Corresponding_Stub (Parent (N));
3373 -- Version with check(s) suppressed
3375 procedure Insert_Actions
3376 (Assoc_Node : Node_Id;
3377 Ins_Actions : List_Id;
3378 Suppress : Check_Id)
3381 if Suppress = All_Checks then
3383 Svg : constant Suppress_Array := Scope_Suppress;
3385 Scope_Suppress := (others => True);
3386 Insert_Actions (Assoc_Node, Ins_Actions);
3387 Scope_Suppress := Svg;
3392 Svg : constant Boolean := Scope_Suppress (Suppress);
3394 Scope_Suppress (Suppress) := True;
3395 Insert_Actions (Assoc_Node, Ins_Actions);
3396 Scope_Suppress (Suppress) := Svg;
3401 --------------------------
3402 -- Insert_Actions_After --
3403 --------------------------
3405 procedure Insert_Actions_After
3406 (Assoc_Node : Node_Id;
3407 Ins_Actions : List_Id)
3410 if Scope_Is_Transient
3411 and then Assoc_Node = Node_To_Be_Wrapped
3413 Store_After_Actions_In_Scope (Ins_Actions);
3415 Insert_List_After_And_Analyze (Assoc_Node, Ins_Actions);
3417 end Insert_Actions_After;
3419 ---------------------------------
3420 -- Insert_Library_Level_Action --
3421 ---------------------------------
3423 procedure Insert_Library_Level_Action (N : Node_Id) is
3424 Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
3427 Push_Scope (Cunit_Entity (Main_Unit));
3428 -- ??? should this be Current_Sem_Unit instead of Main_Unit?
3430 if No (Actions (Aux)) then
3431 Set_Actions (Aux, New_List (N));
3433 Append (N, Actions (Aux));
3438 end Insert_Library_Level_Action;
3440 ----------------------------------
3441 -- Insert_Library_Level_Actions --
3442 ----------------------------------
3444 procedure Insert_Library_Level_Actions (L : List_Id) is
3445 Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
3448 if Is_Non_Empty_List (L) then
3449 Push_Scope (Cunit_Entity (Main_Unit));
3450 -- ??? should this be Current_Sem_Unit instead of Main_Unit?
3452 if No (Actions (Aux)) then
3453 Set_Actions (Aux, L);
3456 Insert_List_After_And_Analyze (Last (Actions (Aux)), L);
3461 end Insert_Library_Level_Actions;
3463 ----------------------
3464 -- Inside_Init_Proc --
3465 ----------------------
3467 function Inside_Init_Proc return Boolean is
3473 and then S /= Standard_Standard
3475 if Is_Init_Proc (S) then
3483 end Inside_Init_Proc;
3485 ----------------------------
3486 -- Is_All_Null_Statements --
3487 ----------------------------
3489 function Is_All_Null_Statements (L : List_Id) return Boolean is
3494 while Present (Stm) loop
3495 if Nkind (Stm) /= N_Null_Statement then
3503 end Is_All_Null_Statements;
3505 ------------------------------
3506 -- Is_Finalizable_Transient --
3507 ------------------------------
3509 function Is_Finalizable_Transient
3511 Rel_Node : Node_Id) return Boolean
3513 Obj_Id : constant Entity_Id := Defining_Identifier (Decl);
3514 Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id));
3515 Desig : Entity_Id := Obj_Typ;
3516 Has_Rens : Boolean := True;
3517 Ren_Obj : Entity_Id;
3519 function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean;
3520 -- Determine whether transient object Trans_Id is initialized either
3521 -- by a function call which returns an access type or simply renames
3524 function Initialized_By_Aliased_BIP_Func_Call
3525 (Trans_Id : Entity_Id) return Boolean;
3526 -- Determine whether transient object Trans_Id is initialized by a
3527 -- build-in-place function call where the BIPalloc parameter is of
3528 -- value 1 and BIPaccess is not null. This case creates an aliasing
3529 -- between the returned value and the value denoted by BIPaccess.
3531 function Is_Allocated (Trans_Id : Entity_Id) return Boolean;
3532 -- Determine whether transient object Trans_Id is allocated on the heap
3535 (Trans_Id : Entity_Id;
3536 First_Stmt : Node_Id) return Boolean;
3537 -- Determine whether transient object Trans_Id has been renamed in the
3538 -- statement list starting from First_Stmt.
3540 ---------------------------
3541 -- Initialized_By_Access --
3542 ---------------------------
3544 function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean is
3545 Expr : constant Node_Id := Expression (Parent (Trans_Id));
3550 and then Nkind (Expr) /= N_Reference
3551 and then Is_Access_Type (Etype (Expr));
3552 end Initialized_By_Access;
3554 ------------------------------------------
3555 -- Initialized_By_Aliased_BIP_Func_Call --
3556 ------------------------------------------
3558 function Initialized_By_Aliased_BIP_Func_Call
3559 (Trans_Id : Entity_Id) return Boolean
3561 Call : Node_Id := Expression (Parent (Trans_Id));
3564 -- Build-in-place calls usually appear in 'reference format
3566 if Nkind (Call) = N_Reference then
3567 Call := Prefix (Call);
3570 if Is_Build_In_Place_Function_Call (Call) then
3572 Access_Nam : Name_Id := No_Name;
3573 Access_OK : Boolean := False;
3575 Alloc_Nam : Name_Id := No_Name;
3576 Alloc_OK : Boolean := False;
3578 Func_Id : Entity_Id;
3582 -- Examine all parameter associations of the function call
3584 Param := First (Parameter_Associations (Call));
3585 while Present (Param) loop
3586 if Nkind (Param) = N_Parameter_Association
3587 and then Nkind (Selector_Name (Param)) = N_Identifier
3589 Actual := Explicit_Actual_Parameter (Param);
3590 Formal := Selector_Name (Param);
3592 -- Construct the names of formals BIPaccess and BIPalloc
3593 -- using the function name retrieved from an arbitrary
3596 if Access_Nam = No_Name
3597 and then Alloc_Nam = No_Name
3598 and then Present (Entity (Formal))
3600 Func_Id := Scope (Entity (Formal));
3603 New_External_Name (Chars (Func_Id),
3604 BIP_Formal_Suffix (BIP_Object_Access));
3607 New_External_Name (Chars (Func_Id),
3608 BIP_Formal_Suffix (BIP_Alloc_Form));
3611 -- A match for BIPaccess => Temp has been found
3613 if Chars (Formal) = Access_Nam
3614 and then Nkind (Actual) /= N_Null
3619 -- A match for BIPalloc => 1 has been found
3621 if Chars (Formal) = Alloc_Nam
3622 and then Nkind (Actual) = N_Integer_Literal
3623 and then Intval (Actual) = Uint_1
3632 return Access_OK and then Alloc_OK;
3637 end Initialized_By_Aliased_BIP_Func_Call;
3643 function Is_Allocated (Trans_Id : Entity_Id) return Boolean is
3644 Expr : constant Node_Id := Expression (Parent (Trans_Id));
3648 Is_Access_Type (Etype (Trans_Id))
3649 and then Present (Expr)
3650 and then Nkind (Expr) = N_Allocator;
3658 (Trans_Id : Entity_Id;
3659 First_Stmt : Node_Id) return Boolean
3663 function Extract_Renamed_Object
3664 (Ren_Decl : Node_Id) return Entity_Id;
3665 -- Given an object renaming declaration, retrieve the entity of the
3666 -- renamed name. Return Empty if the renamed name is anything other
3667 -- than a variable or a constant.
3669 ----------------------------
3670 -- Extract_Renamed_Object --
3671 ----------------------------
3673 function Extract_Renamed_Object
3674 (Ren_Decl : Node_Id) return Entity_Id
3681 Ren_Obj := Renamed_Object (Defining_Identifier (Ren_Decl));
3686 if Nkind_In (Ren_Obj, N_Explicit_Dereference,
3687 N_Indexed_Component,
3688 N_Selected_Component)
3690 Ren_Obj := Prefix (Ren_Obj);
3693 elsif Nkind_In (Ren_Obj, N_Type_Conversion,
3694 N_Unchecked_Type_Conversion)
3696 Ren_Obj := Expression (Ren_Obj);
3701 if Nkind (Ren_Obj) in N_Has_Entity then
3702 return Entity (Ren_Obj);
3706 end Extract_Renamed_Object;
3708 -- Start of processing for Is_Renamed
3711 -- If a previous invocation of this routine has determined that a
3712 -- list has no renamings, then no point in repeating the same scan.
3714 if not Has_Rens then
3718 -- Assume that the statement list does not have a renaming. This is a
3719 -- minor optimization.
3724 while Present (Stmt) loop
3725 if Nkind (Stmt) = N_Object_Renaming_Declaration then
3727 Ren_Obj := Extract_Renamed_Object (Stmt);
3729 if Present (Ren_Obj)
3730 and then Ren_Obj = Trans_Id
3742 -- Start of processing for Is_Finalizable_Transient
3745 -- Handle access types
3747 if Is_Access_Type (Desig) then
3748 Desig := Available_View (Designated_Type (Desig));
3752 Ekind_In (Obj_Id, E_Constant, E_Variable)
3753 and then Needs_Finalization (Desig)
3754 and then Requires_Transient_Scope (Desig)
3755 and then Nkind (Rel_Node) /= N_Simple_Return_Statement
3757 -- Do not consider transient objects allocated on the heap since they
3758 -- are attached to a finalization collection.
3760 and then not Is_Allocated (Obj_Id)
3762 -- If the transient object is a pointer, check that it is not
3763 -- initialized by a function which returns a pointer or acts as a
3764 -- renaming of another pointer.
3767 (not Is_Access_Type (Obj_Typ)
3768 or else not Initialized_By_Access (Obj_Id))
3770 -- Do not consider transient objects which act as indirect aliases of
3771 -- build-in-place function results.
3773 and then not Initialized_By_Aliased_BIP_Func_Call (Obj_Id)
3775 -- Do not consider renamed transient objects because the act of
3776 -- renaming extends the object's lifetime.
3778 and then not Is_Renamed (Obj_Id, Decl)
3780 -- Do not consider conversions of tags to class-wide types
3782 and then not Is_Tag_To_CW_Conversion (Obj_Id);
3783 end Is_Finalizable_Transient;
3785 ---------------------------------
3786 -- Is_Fully_Repped_Tagged_Type --
3787 ---------------------------------
3789 function Is_Fully_Repped_Tagged_Type (T : Entity_Id) return Boolean is
3790 U : constant Entity_Id := Underlying_Type (T);
3794 if No (U) or else not Is_Tagged_Type (U) then
3796 elsif Has_Discriminants (U) then
3798 elsif not Has_Specified_Layout (U) then
3802 -- Here we have a tagged type, see if it has any unlayed out fields
3803 -- other than a possible tag and parent fields. If so, we return False.
3805 Comp := First_Component (U);
3806 while Present (Comp) loop
3807 if not Is_Tag (Comp)
3808 and then Chars (Comp) /= Name_uParent
3809 and then No (Component_Clause (Comp))
3813 Next_Component (Comp);
3817 -- All components are layed out
3820 end Is_Fully_Repped_Tagged_Type;
3822 ----------------------------------
3823 -- Is_Library_Level_Tagged_Type --
3824 ----------------------------------
3826 function Is_Library_Level_Tagged_Type (Typ : Entity_Id) return Boolean is
3828 return Is_Tagged_Type (Typ)
3829 and then Is_Library_Level_Entity (Typ);
3830 end Is_Library_Level_Tagged_Type;
3832 ----------------------------------
3833 -- Is_Null_Access_BIP_Func_Call --
3834 ----------------------------------
3836 function Is_Null_Access_BIP_Func_Call (Expr : Node_Id) return Boolean is
3837 Call : Node_Id := Expr;
3840 -- Build-in-place calls usually appear in 'reference format
3842 if Nkind (Call) = N_Reference then
3843 Call := Prefix (Call);
3846 if Nkind_In (Call, N_Qualified_Expression,
3847 N_Unchecked_Type_Conversion)
3849 Call := Expression (Call);
3852 if Is_Build_In_Place_Function_Call (Call) then
3854 Access_Nam : Name_Id := No_Name;
3860 -- Examine all parameter associations of the function call
3862 Param := First (Parameter_Associations (Call));
3863 while Present (Param) loop
3864 if Nkind (Param) = N_Parameter_Association
3865 and then Nkind (Selector_Name (Param)) = N_Identifier
3867 Formal := Selector_Name (Param);
3868 Actual := Explicit_Actual_Parameter (Param);
3870 -- Construct the name of formal BIPaccess. It is much easier
3871 -- to extract the name of the function using an arbitrary
3872 -- formal's scope rather than the Name field of Call.
3874 if Access_Nam = No_Name
3875 and then Present (Entity (Formal))
3879 (Chars (Scope (Entity (Formal))),
3880 BIP_Formal_Suffix (BIP_Object_Access));
3883 -- A match for BIPaccess => null has been found
3885 if Chars (Formal) = Access_Nam
3886 and then Nkind (Actual) = N_Null
3898 end Is_Null_Access_BIP_Func_Call;
3900 --------------------------
3901 -- Is_Non_BIP_Func_Call --
3902 --------------------------
3904 function Is_Non_BIP_Func_Call (Expr : Node_Id) return Boolean is
3906 -- The expected call is of the format
3908 -- Func_Call'reference
3911 Nkind (Expr) = N_Reference
3912 and then Nkind (Prefix (Expr)) = N_Function_Call
3913 and then not Is_Build_In_Place_Function_Call (Prefix (Expr));
3914 end Is_Non_BIP_Func_Call;
3916 ----------------------------------
3917 -- Is_Possibly_Unaligned_Object --
3918 ----------------------------------
3920 function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean is
3921 T : constant Entity_Id := Etype (N);
3924 -- If renamed object, apply test to underlying object
3926 if Is_Entity_Name (N)
3927 and then Is_Object (Entity (N))
3928 and then Present (Renamed_Object (Entity (N)))
3930 return Is_Possibly_Unaligned_Object (Renamed_Object (Entity (N)));
3933 -- Tagged and controlled types and aliased types are always aligned, as
3934 -- are concurrent types.
3937 or else Has_Controlled_Component (T)
3938 or else Is_Concurrent_Type (T)
3939 or else Is_Tagged_Type (T)
3940 or else Is_Controlled (T)
3945 -- If this is an element of a packed array, may be unaligned
3947 if Is_Ref_To_Bit_Packed_Array (N) then
3951 -- Case of component reference
3953 if Nkind (N) = N_Selected_Component then
3955 P : constant Node_Id := Prefix (N);
3956 C : constant Entity_Id := Entity (Selector_Name (N));
3961 -- If component reference is for an array with non-static bounds,
3962 -- then it is always aligned: we can only process unaligned arrays
3963 -- with static bounds (more accurately bounds known at compile
3966 if Is_Array_Type (T)
3967 and then not Compile_Time_Known_Bounds (T)
3972 -- If component is aliased, it is definitely properly aligned
3974 if Is_Aliased (C) then
3978 -- If component is for a type implemented as a scalar, and the
3979 -- record is packed, and the component is other than the first
3980 -- component of the record, then the component may be unaligned.
3982 if Is_Packed (Etype (P))
3983 and then Represented_As_Scalar (Etype (C))
3984 and then First_Entity (Scope (C)) /= C
3989 -- Compute maximum possible alignment for T
3991 -- If alignment is known, then that settles things
3993 if Known_Alignment (T) then
3994 M := UI_To_Int (Alignment (T));
3996 -- If alignment is not known, tentatively set max alignment
3999 M := Ttypes.Maximum_Alignment;
4001 -- We can reduce this if the Esize is known since the default
4002 -- alignment will never be more than the smallest power of 2
4003 -- that does not exceed this Esize value.
4005 if Known_Esize (T) then
4006 S := UI_To_Int (Esize (T));
4008 while (M / 2) >= S loop
4014 -- The following code is historical, it used to be present but it
4015 -- is too cautious, because the front-end does not know the proper
4016 -- default alignments for the target. Also, if the alignment is
4017 -- not known, the front end can't know in any case! If a copy is
4018 -- needed, the back-end will take care of it. This whole section
4019 -- including this comment can be removed later ???
4021 -- If the component reference is for a record that has a specified
4022 -- alignment, and we either know it is too small, or cannot tell,
4023 -- then the component may be unaligned.
4025 -- if Known_Alignment (Etype (P))
4026 -- and then Alignment (Etype (P)) < Ttypes.Maximum_Alignment
4027 -- and then M > Alignment (Etype (P))
4032 -- Case of component clause present which may specify an
4033 -- unaligned position.
4035 if Present (Component_Clause (C)) then
4037 -- Otherwise we can do a test to make sure that the actual
4038 -- start position in the record, and the length, are both
4039 -- consistent with the required alignment. If not, we know
4040 -- that we are unaligned.
4043 Align_In_Bits : constant Nat := M * System_Storage_Unit;
4045 if Component_Bit_Offset (C) mod Align_In_Bits /= 0
4046 or else Esize (C) mod Align_In_Bits /= 0
4053 -- Otherwise, for a component reference, test prefix
4055 return Is_Possibly_Unaligned_Object (P);
4058 -- If not a component reference, must be aligned
4063 end Is_Possibly_Unaligned_Object;
4065 ---------------------------------
4066 -- Is_Possibly_Unaligned_Slice --
4067 ---------------------------------
4069 function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean is
4071 -- Go to renamed object
4073 if Is_Entity_Name (N)
4074 and then Is_Object (Entity (N))
4075 and then Present (Renamed_Object (Entity (N)))
4077 return Is_Possibly_Unaligned_Slice (Renamed_Object (Entity (N)));
4080 -- The reference must be a slice
4082 if Nkind (N) /= N_Slice then
4086 -- Always assume the worst for a nested record component with a
4087 -- component clause, which gigi/gcc does not appear to handle well.
4088 -- It is not clear why this special test is needed at all ???
4090 if Nkind (Prefix (N)) = N_Selected_Component
4091 and then Nkind (Prefix (Prefix (N))) = N_Selected_Component
4093 Present (Component_Clause (Entity (Selector_Name (Prefix (N)))))
4098 -- We only need to worry if the target has strict alignment
4100 if not Target_Strict_Alignment then
4104 -- If it is a slice, then look at the array type being sliced
4107 Sarr : constant Node_Id := Prefix (N);
4108 -- Prefix of the slice, i.e. the array being sliced
4110 Styp : constant Entity_Id := Etype (Prefix (N));
4111 -- Type of the array being sliced
4117 -- The problems arise if the array object that is being sliced
4118 -- is a component of a record or array, and we cannot guarantee
4119 -- the alignment of the array within its containing object.
4121 -- To investigate this, we look at successive prefixes to see
4122 -- if we have a worrisome indexed or selected component.
4126 -- Case of array is part of an indexed component reference
4128 if Nkind (Pref) = N_Indexed_Component then
4129 Ptyp := Etype (Prefix (Pref));
4131 -- The only problematic case is when the array is packed, in
4132 -- which case we really know nothing about the alignment of
4133 -- individual components.
4135 if Is_Bit_Packed_Array (Ptyp) then
4139 -- Case of array is part of a selected component reference
4141 elsif Nkind (Pref) = N_Selected_Component then
4142 Ptyp := Etype (Prefix (Pref));
4144 -- We are definitely in trouble if the record in question
4145 -- has an alignment, and either we know this alignment is
4146 -- inconsistent with the alignment of the slice, or we don't
4147 -- know what the alignment of the slice should be.
4149 if Known_Alignment (Ptyp)
4150 and then (Unknown_Alignment (Styp)
4151 or else Alignment (Styp) > Alignment (Ptyp))
4156 -- We are in potential trouble if the record type is packed.
4157 -- We could special case when we know that the array is the
4158 -- first component, but that's not such a simple case ???
4160 if Is_Packed (Ptyp) then
4164 -- We are in trouble if there is a component clause, and
4165 -- either we do not know the alignment of the slice, or
4166 -- the alignment of the slice is inconsistent with the
4167 -- bit position specified by the component clause.
4170 Field : constant Entity_Id := Entity (Selector_Name (Pref));
4172 if Present (Component_Clause (Field))
4174 (Unknown_Alignment (Styp)
4176 (Component_Bit_Offset (Field) mod
4177 (System_Storage_Unit * Alignment (Styp))) /= 0)
4183 -- For cases other than selected or indexed components we know we
4184 -- are OK, since no issues arise over alignment.
4190 -- We processed an indexed component or selected component
4191 -- reference that looked safe, so keep checking prefixes.
4193 Pref := Prefix (Pref);
4196 end Is_Possibly_Unaligned_Slice;
4198 -------------------------------
4199 -- Is_Related_To_Func_Return --
4200 -------------------------------
4202 function Is_Related_To_Func_Return (Id : Entity_Id) return Boolean is
4203 Expr : constant Node_Id := Related_Expression (Id);
4207 and then Nkind (Expr) = N_Explicit_Dereference
4208 and then Nkind (Parent (Expr)) = N_Simple_Return_Statement;
4209 end Is_Related_To_Func_Return;
4211 --------------------------------
4212 -- Is_Ref_To_Bit_Packed_Array --
4213 --------------------------------
4215 function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean is
4220 if Is_Entity_Name (N)
4221 and then Is_Object (Entity (N))
4222 and then Present (Renamed_Object (Entity (N)))
4224 return Is_Ref_To_Bit_Packed_Array (Renamed_Object (Entity (N)));
4227 if Nkind (N) = N_Indexed_Component
4229 Nkind (N) = N_Selected_Component
4231 if Is_Bit_Packed_Array (Etype (Prefix (N))) then
4234 Result := Is_Ref_To_Bit_Packed_Array (Prefix (N));
4237 if Result and then Nkind (N) = N_Indexed_Component then
4238 Expr := First (Expressions (N));
4239 while Present (Expr) loop
4240 Force_Evaluation (Expr);
4250 end Is_Ref_To_Bit_Packed_Array;
4252 --------------------------------
4253 -- Is_Ref_To_Bit_Packed_Slice --
4254 --------------------------------
4256 function Is_Ref_To_Bit_Packed_Slice (N : Node_Id) return Boolean is
4258 if Nkind (N) = N_Type_Conversion then
4259 return Is_Ref_To_Bit_Packed_Slice (Expression (N));
4261 elsif Is_Entity_Name (N)
4262 and then Is_Object (Entity (N))
4263 and then Present (Renamed_Object (Entity (N)))
4265 return Is_Ref_To_Bit_Packed_Slice (Renamed_Object (Entity (N)));
4267 elsif Nkind (N) = N_Slice
4268 and then Is_Bit_Packed_Array (Etype (Prefix (N)))
4272 elsif Nkind (N) = N_Indexed_Component
4274 Nkind (N) = N_Selected_Component
4276 return Is_Ref_To_Bit_Packed_Slice (Prefix (N));
4281 end Is_Ref_To_Bit_Packed_Slice;
4283 -----------------------
4284 -- Is_Renamed_Object --
4285 -----------------------
4287 function Is_Renamed_Object (N : Node_Id) return Boolean is
4288 Pnod : constant Node_Id := Parent (N);
4289 Kind : constant Node_Kind := Nkind (Pnod);
4291 if Kind = N_Object_Renaming_Declaration then
4293 elsif Nkind_In (Kind, N_Indexed_Component, N_Selected_Component) then
4294 return Is_Renamed_Object (Pnod);
4298 end Is_Renamed_Object;
4300 -----------------------------
4301 -- Is_Tag_To_CW_Conversion --
4302 -----------------------------
4304 function Is_Tag_To_CW_Conversion (Obj_Id : Entity_Id) return Boolean is
4305 Expr : constant Node_Id := Expression (Parent (Obj_Id));
4309 Is_Class_Wide_Type (Etype (Obj_Id))
4310 and then Present (Expr)
4311 and then Nkind (Expr) = N_Unchecked_Type_Conversion
4312 and then Etype (Expression (Expr)) = RTE (RE_Tag);
4313 end Is_Tag_To_CW_Conversion;
4315 ----------------------------
4316 -- Is_Untagged_Derivation --
4317 ----------------------------
4319 function Is_Untagged_Derivation (T : Entity_Id) return Boolean is
4321 return (not Is_Tagged_Type (T) and then Is_Derived_Type (T))
4323 (Is_Private_Type (T) and then Present (Full_View (T))
4324 and then not Is_Tagged_Type (Full_View (T))
4325 and then Is_Derived_Type (Full_View (T))
4326 and then Etype (Full_View (T)) /= T);
4327 end Is_Untagged_Derivation;
4329 ---------------------------
4330 -- Is_Volatile_Reference --
4331 ---------------------------
4333 function Is_Volatile_Reference (N : Node_Id) return Boolean is
4335 if Nkind (N) in N_Has_Etype
4336 and then Present (Etype (N))
4337 and then Treat_As_Volatile (Etype (N))
4341 elsif Is_Entity_Name (N) then
4342 return Treat_As_Volatile (Entity (N));
4344 elsif Nkind (N) = N_Slice then
4345 return Is_Volatile_Reference (Prefix (N));
4347 elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
4348 if (Is_Entity_Name (Prefix (N))
4349 and then Has_Volatile_Components (Entity (Prefix (N))))
4350 or else (Present (Etype (Prefix (N)))
4351 and then Has_Volatile_Components (Etype (Prefix (N))))
4355 return Is_Volatile_Reference (Prefix (N));
4361 end Is_Volatile_Reference;
4363 --------------------------
4364 -- Is_VM_By_Copy_Actual --
4365 --------------------------
4367 function Is_VM_By_Copy_Actual (N : Node_Id) return Boolean is
4369 return VM_Target /= No_VM
4370 and then (Nkind (N) = N_Slice
4372 (Nkind (N) = N_Identifier
4373 and then Present (Renamed_Object (Entity (N)))
4374 and then Nkind (Renamed_Object (Entity (N)))
4376 end Is_VM_By_Copy_Actual;
4378 --------------------
4379 -- Kill_Dead_Code --
4380 --------------------
4382 procedure Kill_Dead_Code (N : Node_Id; Warn : Boolean := False) is
4383 W : Boolean := Warn;
4384 -- Set False if warnings suppressed
4388 Remove_Warning_Messages (N);
4390 -- Generate warning if appropriate
4394 -- We suppress the warning if this code is under control of an
4395 -- if statement, whose condition is a simple identifier, and
4396 -- either we are in an instance, or warnings off is set for this
4397 -- identifier. The reason for killing it in the instance case is
4398 -- that it is common and reasonable for code to be deleted in
4399 -- instances for various reasons.
4401 if Nkind (Parent (N)) = N_If_Statement then
4403 C : constant Node_Id := Condition (Parent (N));
4405 if Nkind (C) = N_Identifier
4408 or else (Present (Entity (C))
4409 and then Has_Warnings_Off (Entity (C))))
4416 -- Generate warning if not suppressed
4420 ("?this code can never be executed and has been deleted!", N);
4424 -- Recurse into block statements and bodies to process declarations
4427 if Nkind (N) = N_Block_Statement
4428 or else Nkind (N) = N_Subprogram_Body
4429 or else Nkind (N) = N_Package_Body
4431 Kill_Dead_Code (Declarations (N), False);
4432 Kill_Dead_Code (Statements (Handled_Statement_Sequence (N)));
4434 if Nkind (N) = N_Subprogram_Body then
4435 Set_Is_Eliminated (Defining_Entity (N));
4438 elsif Nkind (N) = N_Package_Declaration then
4439 Kill_Dead_Code (Visible_Declarations (Specification (N)));
4440 Kill_Dead_Code (Private_Declarations (Specification (N)));
4442 -- ??? After this point, Delete_Tree has been called on all
4443 -- declarations in Specification (N), so references to entities
4444 -- therein look suspicious.
4447 E : Entity_Id := First_Entity (Defining_Entity (N));
4449 while Present (E) loop
4450 if Ekind (E) = E_Operator then
4451 Set_Is_Eliminated (E);
4458 -- Recurse into composite statement to kill individual statements in
4459 -- particular instantiations.
4461 elsif Nkind (N) = N_If_Statement then
4462 Kill_Dead_Code (Then_Statements (N));
4463 Kill_Dead_Code (Elsif_Parts (N));
4464 Kill_Dead_Code (Else_Statements (N));
4466 elsif Nkind (N) = N_Loop_Statement then
4467 Kill_Dead_Code (Statements (N));
4469 elsif Nkind (N) = N_Case_Statement then
4473 Alt := First (Alternatives (N));
4474 while Present (Alt) loop
4475 Kill_Dead_Code (Statements (Alt));
4480 elsif Nkind (N) = N_Case_Statement_Alternative then
4481 Kill_Dead_Code (Statements (N));
4483 -- Deal with dead instances caused by deleting instantiations
4485 elsif Nkind (N) in N_Generic_Instantiation then
4486 Remove_Dead_Instance (N);
4491 -- Case where argument is a list of nodes to be killed
4493 procedure Kill_Dead_Code (L : List_Id; Warn : Boolean := False) is
4498 if Is_Non_Empty_List (L) then
4500 while Present (N) loop
4501 Kill_Dead_Code (N, W);
4508 ------------------------
4509 -- Known_Non_Negative --
4510 ------------------------
4512 function Known_Non_Negative (Opnd : Node_Id) return Boolean is
4514 if Is_OK_Static_Expression (Opnd)
4515 and then Expr_Value (Opnd) >= 0
4521 Lo : constant Node_Id := Type_Low_Bound (Etype (Opnd));
4525 Is_OK_Static_Expression (Lo) and then Expr_Value (Lo) >= 0;
4528 end Known_Non_Negative;
4530 --------------------
4531 -- Known_Non_Null --
4532 --------------------
4534 function Known_Non_Null (N : Node_Id) return Boolean is
4536 -- Checks for case where N is an entity reference
4538 if Is_Entity_Name (N) and then Present (Entity (N)) then
4540 E : constant Entity_Id := Entity (N);
4545 -- First check if we are in decisive conditional
4547 Get_Current_Value_Condition (N, Op, Val);
4549 if Known_Null (Val) then
4550 if Op = N_Op_Eq then
4552 elsif Op = N_Op_Ne then
4557 -- If OK to do replacement, test Is_Known_Non_Null flag
4559 if OK_To_Do_Constant_Replacement (E) then
4560 return Is_Known_Non_Null (E);
4562 -- Otherwise if not safe to do replacement, then say so
4569 -- True if access attribute
4571 elsif Nkind (N) = N_Attribute_Reference
4572 and then (Attribute_Name (N) = Name_Access
4574 Attribute_Name (N) = Name_Unchecked_Access
4576 Attribute_Name (N) = Name_Unrestricted_Access)
4580 -- True if allocator
4582 elsif Nkind (N) = N_Allocator then
4585 -- For a conversion, true if expression is known non-null
4587 elsif Nkind (N) = N_Type_Conversion then
4588 return Known_Non_Null (Expression (N));
4590 -- Above are all cases where the value could be determined to be
4591 -- non-null. In all other cases, we don't know, so return False.
4602 function Known_Null (N : Node_Id) return Boolean is
4604 -- Checks for case where N is an entity reference
4606 if Is_Entity_Name (N) and then Present (Entity (N)) then
4608 E : constant Entity_Id := Entity (N);
4613 -- Constant null value is for sure null
4615 if Ekind (E) = E_Constant
4616 and then Known_Null (Constant_Value (E))
4621 -- First check if we are in decisive conditional
4623 Get_Current_Value_Condition (N, Op, Val);
4625 if Known_Null (Val) then
4626 if Op = N_Op_Eq then
4628 elsif Op = N_Op_Ne then
4633 -- If OK to do replacement, test Is_Known_Null flag
4635 if OK_To_Do_Constant_Replacement (E) then
4636 return Is_Known_Null (E);
4638 -- Otherwise if not safe to do replacement, then say so
4645 -- True if explicit reference to null
4647 elsif Nkind (N) = N_Null then
4650 -- For a conversion, true if expression is known null
4652 elsif Nkind (N) = N_Type_Conversion then
4653 return Known_Null (Expression (N));
4655 -- Above are all cases where the value could be determined to be null.
4656 -- In all other cases, we don't know, so return False.
4663 -----------------------------
4664 -- Make_CW_Equivalent_Type --
4665 -----------------------------
4667 -- Create a record type used as an equivalent of any member of the class
4668 -- which takes its size from exp.
4670 -- Generate the following code:
4672 -- type Equiv_T is record
4673 -- _parent : T (List of discriminant constraints taken from Exp);
4674 -- Ext__50 : Storage_Array (1 .. (Exp'size - Typ'object_size)/8);
4677 -- ??? Note that this type does not guarantee same alignment as all
4680 function Make_CW_Equivalent_Type
4682 E : Node_Id) return Entity_Id
4684 Loc : constant Source_Ptr := Sloc (E);
4685 Root_Typ : constant Entity_Id := Root_Type (T);
4686 List_Def : constant List_Id := Empty_List;
4687 Comp_List : constant List_Id := New_List;
4688 Equiv_Type : Entity_Id;
4689 Range_Type : Entity_Id;
4690 Str_Type : Entity_Id;
4691 Constr_Root : Entity_Id;
4695 -- If the root type is already constrained, there are no discriminants
4696 -- in the expression.
4698 if not Has_Discriminants (Root_Typ)
4699 or else Is_Constrained (Root_Typ)
4701 Constr_Root := Root_Typ;
4703 Constr_Root := Make_Temporary (Loc, 'R');
4705 -- subtype cstr__n is T (List of discr constraints taken from Exp)
4707 Append_To (List_Def,
4708 Make_Subtype_Declaration (Loc,
4709 Defining_Identifier => Constr_Root,
4710 Subtype_Indication => Make_Subtype_From_Expr (E, Root_Typ)));
4713 -- Generate the range subtype declaration
4715 Range_Type := Make_Temporary (Loc, 'G');
4717 if not Is_Interface (Root_Typ) then
4719 -- subtype rg__xx is
4720 -- Storage_Offset range 1 .. (Expr'size - typ'size) / Storage_Unit
4723 Make_Op_Subtract (Loc,
4725 Make_Attribute_Reference (Loc,
4727 OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
4728 Attribute_Name => Name_Size),
4730 Make_Attribute_Reference (Loc,
4731 Prefix => New_Reference_To (Constr_Root, Loc),
4732 Attribute_Name => Name_Object_Size));
4734 -- subtype rg__xx is
4735 -- Storage_Offset range 1 .. Expr'size / Storage_Unit
4738 Make_Attribute_Reference (Loc,
4740 OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
4741 Attribute_Name => Name_Size);
4744 Set_Paren_Count (Sizexpr, 1);
4746 Append_To (List_Def,
4747 Make_Subtype_Declaration (Loc,
4748 Defining_Identifier => Range_Type,
4749 Subtype_Indication =>
4750 Make_Subtype_Indication (Loc,
4751 Subtype_Mark => New_Reference_To (RTE (RE_Storage_Offset), Loc),
4752 Constraint => Make_Range_Constraint (Loc,
4755 Low_Bound => Make_Integer_Literal (Loc, 1),
4757 Make_Op_Divide (Loc,
4758 Left_Opnd => Sizexpr,
4759 Right_Opnd => Make_Integer_Literal (Loc,
4760 Intval => System_Storage_Unit)))))));
4762 -- subtype str__nn is Storage_Array (rg__x);
4764 Str_Type := Make_Temporary (Loc, 'S');
4765 Append_To (List_Def,
4766 Make_Subtype_Declaration (Loc,
4767 Defining_Identifier => Str_Type,
4768 Subtype_Indication =>
4769 Make_Subtype_Indication (Loc,
4770 Subtype_Mark => New_Reference_To (RTE (RE_Storage_Array), Loc),
4772 Make_Index_Or_Discriminant_Constraint (Loc,
4774 New_List (New_Reference_To (Range_Type, Loc))))));
4776 -- type Equiv_T is record
4777 -- [ _parent : Tnn; ]
4781 Equiv_Type := Make_Temporary (Loc, 'T');
4782 Set_Ekind (Equiv_Type, E_Record_Type);
4783 Set_Parent_Subtype (Equiv_Type, Constr_Root);
4785 -- Set Is_Class_Wide_Equivalent_Type very early to trigger the special
4786 -- treatment for this type. In particular, even though _parent's type
4787 -- is a controlled type or contains controlled components, we do not
4788 -- want to set Has_Controlled_Component on it to avoid making it gain
4789 -- an unwanted _controller component.
4791 Set_Is_Class_Wide_Equivalent_Type (Equiv_Type);
4793 if not Is_Interface (Root_Typ) then
4794 Append_To (Comp_List,
4795 Make_Component_Declaration (Loc,
4796 Defining_Identifier =>
4797 Make_Defining_Identifier (Loc, Name_uParent),
4798 Component_Definition =>
4799 Make_Component_Definition (Loc,
4800 Aliased_Present => False,
4801 Subtype_Indication => New_Reference_To (Constr_Root, Loc))));
4804 Append_To (Comp_List,
4805 Make_Component_Declaration (Loc,
4806 Defining_Identifier => Make_Temporary (Loc, 'C'),
4807 Component_Definition =>
4808 Make_Component_Definition (Loc,
4809 Aliased_Present => False,
4810 Subtype_Indication => New_Reference_To (Str_Type, Loc))));
4812 Append_To (List_Def,
4813 Make_Full_Type_Declaration (Loc,
4814 Defining_Identifier => Equiv_Type,
4816 Make_Record_Definition (Loc,
4818 Make_Component_List (Loc,
4819 Component_Items => Comp_List,
4820 Variant_Part => Empty))));
4822 -- Suppress all checks during the analysis of the expanded code to avoid
4823 -- the generation of spurious warnings under ZFP run-time.
4825 Insert_Actions (E, List_Def, Suppress => All_Checks);
4827 end Make_CW_Equivalent_Type;
4829 -------------------------
4830 -- Make_Invariant_Call --
4831 -------------------------
4833 function Make_Invariant_Call (Expr : Node_Id) return Node_Id is
4834 Loc : constant Source_Ptr := Sloc (Expr);
4835 Typ : constant Entity_Id := Etype (Expr);
4839 (Has_Invariants (Typ) and then Present (Invariant_Procedure (Typ)));
4841 if Check_Enabled (Name_Invariant)
4843 Check_Enabled (Name_Assertion)
4846 Make_Procedure_Call_Statement (Loc,
4848 New_Occurrence_Of (Invariant_Procedure (Typ), Loc),
4849 Parameter_Associations => New_List (Relocate_Node (Expr)));
4853 Make_Null_Statement (Loc);
4855 end Make_Invariant_Call;
4857 ------------------------
4858 -- Make_Literal_Range --
4859 ------------------------
4861 function Make_Literal_Range
4863 Literal_Typ : Entity_Id) return Node_Id
4865 Lo : constant Node_Id :=
4866 New_Copy_Tree (String_Literal_Low_Bound (Literal_Typ));
4867 Index : constant Entity_Id := Etype (Lo);
4870 Length_Expr : constant Node_Id :=
4871 Make_Op_Subtract (Loc,
4873 Make_Integer_Literal (Loc,
4874 Intval => String_Literal_Length (Literal_Typ)),
4876 Make_Integer_Literal (Loc, 1));
4879 Set_Analyzed (Lo, False);
4881 if Is_Integer_Type (Index) then
4884 Left_Opnd => New_Copy_Tree (Lo),
4885 Right_Opnd => Length_Expr);
4888 Make_Attribute_Reference (Loc,
4889 Attribute_Name => Name_Val,
4890 Prefix => New_Occurrence_Of (Index, Loc),
4891 Expressions => New_List (
4894 Make_Attribute_Reference (Loc,
4895 Attribute_Name => Name_Pos,
4896 Prefix => New_Occurrence_Of (Index, Loc),
4897 Expressions => New_List (New_Copy_Tree (Lo))),
4898 Right_Opnd => Length_Expr)));
4905 end Make_Literal_Range;
4907 --------------------------
4908 -- Make_Non_Empty_Check --
4909 --------------------------
4911 function Make_Non_Empty_Check
4913 N : Node_Id) return Node_Id
4919 Make_Attribute_Reference (Loc,
4920 Attribute_Name => Name_Length,
4921 Prefix => Duplicate_Subexpr_No_Checks (N, Name_Req => True)),
4923 Make_Integer_Literal (Loc, 0));
4924 end Make_Non_Empty_Check;
4926 -------------------------
4927 -- Make_Predicate_Call --
4928 -------------------------
4930 function Make_Predicate_Call
4932 Expr : Node_Id) return Node_Id
4934 Loc : constant Source_Ptr := Sloc (Expr);
4937 pragma Assert (Present (Predicate_Function (Typ)));
4940 Make_Function_Call (Loc,
4942 New_Occurrence_Of (Predicate_Function (Typ), Loc),
4943 Parameter_Associations => New_List (Relocate_Node (Expr)));
4944 end Make_Predicate_Call;
4946 --------------------------
4947 -- Make_Predicate_Check --
4948 --------------------------
4950 function Make_Predicate_Check
4952 Expr : Node_Id) return Node_Id
4954 Loc : constant Source_Ptr := Sloc (Expr);
4959 Pragma_Identifier => Make_Identifier (Loc, Name_Check),
4960 Pragma_Argument_Associations => New_List (
4961 Make_Pragma_Argument_Association (Loc,
4962 Expression => Make_Identifier (Loc, Name_Predicate)),
4963 Make_Pragma_Argument_Association (Loc,
4964 Expression => Make_Predicate_Call (Typ, Expr))));
4965 end Make_Predicate_Check;
4967 ----------------------------
4968 -- Make_Subtype_From_Expr --
4969 ----------------------------
4971 -- 1. If Expr is an unconstrained array expression, creates
4972 -- Unc_Type(Expr'first(1)..Expr'last(1),..., Expr'first(n)..Expr'last(n))
4974 -- 2. If Expr is a unconstrained discriminated type expression, creates
4975 -- Unc_Type(Expr.Discr1, ... , Expr.Discr_n)
4977 -- 3. If Expr is class-wide, creates an implicit class wide subtype
4979 function Make_Subtype_From_Expr
4981 Unc_Typ : Entity_Id) return Node_Id
4983 Loc : constant Source_Ptr := Sloc (E);
4984 List_Constr : constant List_Id := New_List;
4987 Full_Subtyp : Entity_Id;
4988 Priv_Subtyp : Entity_Id;
4993 if Is_Private_Type (Unc_Typ)
4994 and then Has_Unknown_Discriminants (Unc_Typ)
4996 -- Prepare the subtype completion, Go to base type to
4997 -- find underlying type, because the type may be a generic
4998 -- actual or an explicit subtype.
5000 Utyp := Underlying_Type (Base_Type (Unc_Typ));
5001 Full_Subtyp := Make_Temporary (Loc, 'C');
5003 Unchecked_Convert_To (Utyp, Duplicate_Subexpr_No_Checks (E));
5004 Set_Parent (Full_Exp, Parent (E));
5006 Priv_Subtyp := Make_Temporary (Loc, 'P');
5009 Make_Subtype_Declaration (Loc,
5010 Defining_Identifier => Full_Subtyp,
5011 Subtype_Indication => Make_Subtype_From_Expr (Full_Exp, Utyp)));
5013 -- Define the dummy private subtype
5015 Set_Ekind (Priv_Subtyp, Subtype_Kind (Ekind (Unc_Typ)));
5016 Set_Etype (Priv_Subtyp, Base_Type (Unc_Typ));
5017 Set_Scope (Priv_Subtyp, Full_Subtyp);
5018 Set_Is_Constrained (Priv_Subtyp);
5019 Set_Is_Tagged_Type (Priv_Subtyp, Is_Tagged_Type (Unc_Typ));
5020 Set_Is_Itype (Priv_Subtyp);
5021 Set_Associated_Node_For_Itype (Priv_Subtyp, E);
5023 if Is_Tagged_Type (Priv_Subtyp) then
5025 (Base_Type (Priv_Subtyp), Class_Wide_Type (Unc_Typ));
5026 Set_Direct_Primitive_Operations (Priv_Subtyp,
5027 Direct_Primitive_Operations (Unc_Typ));
5030 Set_Full_View (Priv_Subtyp, Full_Subtyp);
5032 return New_Reference_To (Priv_Subtyp, Loc);
5034 elsif Is_Array_Type (Unc_Typ) then
5035 for J in 1 .. Number_Dimensions (Unc_Typ) loop
5036 Append_To (List_Constr,
5039 Make_Attribute_Reference (Loc,
5040 Prefix => Duplicate_Subexpr_No_Checks (E),
5041 Attribute_Name => Name_First,
5042 Expressions => New_List (
5043 Make_Integer_Literal (Loc, J))),
5046 Make_Attribute_Reference (Loc,
5047 Prefix => Duplicate_Subexpr_No_Checks (E),
5048 Attribute_Name => Name_Last,
5049 Expressions => New_List (
5050 Make_Integer_Literal (Loc, J)))));
5053 elsif Is_Class_Wide_Type (Unc_Typ) then
5055 CW_Subtype : Entity_Id;
5056 EQ_Typ : Entity_Id := Empty;
5059 -- A class-wide equivalent type is not needed when VM_Target
5060 -- because the VM back-ends handle the class-wide object
5061 -- initialization itself (and doesn't need or want the
5062 -- additional intermediate type to handle the assignment).
5064 if Expander_Active and then Tagged_Type_Expansion then
5066 -- If this is the class_wide type of a completion that is a
5067 -- record subtype, set the type of the class_wide type to be
5068 -- the full base type, for use in the expanded code for the
5069 -- equivalent type. Should this be done earlier when the
5070 -- completion is analyzed ???
5072 if Is_Private_Type (Etype (Unc_Typ))
5074 Ekind (Full_View (Etype (Unc_Typ))) = E_Record_Subtype
5076 Set_Etype (Unc_Typ, Base_Type (Full_View (Etype (Unc_Typ))));
5079 EQ_Typ := Make_CW_Equivalent_Type (Unc_Typ, E);
5082 CW_Subtype := New_Class_Wide_Subtype (Unc_Typ, E);
5083 Set_Equivalent_Type (CW_Subtype, EQ_Typ);
5084 Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ));
5086 return New_Occurrence_Of (CW_Subtype, Loc);
5089 -- Indefinite record type with discriminants
5092 D := First_Discriminant (Unc_Typ);
5093 while Present (D) loop
5094 Append_To (List_Constr,
5095 Make_Selected_Component (Loc,
5096 Prefix => Duplicate_Subexpr_No_Checks (E),
5097 Selector_Name => New_Reference_To (D, Loc)));
5099 Next_Discriminant (D);
5104 Make_Subtype_Indication (Loc,
5105 Subtype_Mark => New_Reference_To (Unc_Typ, Loc),
5107 Make_Index_Or_Discriminant_Constraint (Loc,
5108 Constraints => List_Constr));
5109 end Make_Subtype_From_Expr;
5111 -----------------------------
5112 -- May_Generate_Large_Temp --
5113 -----------------------------
5115 -- At the current time, the only types that we return False for (i.e. where
5116 -- we decide we know they cannot generate large temps) are ones where we
5117 -- know the size is 256 bits or less at compile time, and we are still not
5118 -- doing a thorough job on arrays and records ???
5120 function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is
5122 if not Size_Known_At_Compile_Time (Typ) then
5125 elsif Esize (Typ) /= 0 and then Esize (Typ) <= 256 then
5128 elsif Is_Array_Type (Typ)
5129 and then Present (Packed_Array_Type (Typ))
5131 return May_Generate_Large_Temp (Packed_Array_Type (Typ));
5133 -- We could do more here to find other small types ???
5138 end May_Generate_Large_Temp;
5140 ------------------------
5141 -- Needs_Finalization --
5142 ------------------------
5144 function Needs_Finalization (T : Entity_Id) return Boolean is
5145 function Has_Some_Controlled_Component (Rec : Entity_Id) return Boolean;
5146 -- If type is not frozen yet, check explicitly among its components,
5147 -- because the Has_Controlled_Component flag is not necessarily set.
5149 -----------------------------------
5150 -- Has_Some_Controlled_Component --
5151 -----------------------------------
5153 function Has_Some_Controlled_Component
5154 (Rec : Entity_Id) return Boolean
5159 if Has_Controlled_Component (Rec) then
5162 elsif not Is_Frozen (Rec) then
5163 if Is_Record_Type (Rec) then
5164 Comp := First_Entity (Rec);
5166 while Present (Comp) loop
5167 if not Is_Type (Comp)
5168 and then Needs_Finalization (Etype (Comp))
5178 elsif Is_Array_Type (Rec) then
5179 return Needs_Finalization (Component_Type (Rec));
5182 return Has_Controlled_Component (Rec);
5187 end Has_Some_Controlled_Component;
5189 -- Start of processing for Needs_Finalization
5192 -- Certain run-time configurations and targets do not provide support
5193 -- for controlled types.
5195 if Restriction_Active (No_Finalization) then
5199 -- Class-wide types are treated as controlled because derivations
5200 -- from the root type can introduce controlled components.
5203 Is_Class_Wide_Type (T)
5204 or else Is_Controlled (T)
5205 or else Has_Controlled_Component (T)
5206 or else Has_Some_Controlled_Component (T)
5208 (Is_Concurrent_Type (T)
5209 and then Present (Corresponding_Record_Type (T))
5210 and then Needs_Finalization (Corresponding_Record_Type (T)));
5212 end Needs_Finalization;
5214 ----------------------------
5215 -- Needs_Constant_Address --
5216 ----------------------------
5218 function Needs_Constant_Address
5220 Typ : Entity_Id) return Boolean
5224 -- If we have no initialization of any kind, then we don't need to place
5225 -- any restrictions on the address clause, because the object will be
5226 -- elaborated after the address clause is evaluated. This happens if the
5227 -- declaration has no initial expression, or the type has no implicit
5228 -- initialization, or the object is imported.
5230 -- The same holds for all initialized scalar types and all access types.
5231 -- Packed bit arrays of size up to 64 are represented using a modular
5232 -- type with an initialization (to zero) and can be processed like other
5233 -- initialized scalar types.
5235 -- If the type is controlled, code to attach the object to a
5236 -- finalization chain is generated at the point of declaration, and
5237 -- therefore the elaboration of the object cannot be delayed: the
5238 -- address expression must be a constant.
5240 if No (Expression (Decl))
5241 and then not Needs_Finalization (Typ)
5243 (not Has_Non_Null_Base_Init_Proc (Typ)
5244 or else Is_Imported (Defining_Identifier (Decl)))
5248 elsif (Present (Expression (Decl)) and then Is_Scalar_Type (Typ))
5249 or else Is_Access_Type (Typ)
5251 (Is_Bit_Packed_Array (Typ)
5252 and then Is_Modular_Integer_Type (Packed_Array_Type (Typ)))
5258 -- Otherwise, we require the address clause to be constant because
5259 -- the call to the initialization procedure (or the attach code) has
5260 -- to happen at the point of the declaration.
5262 -- Actually the IP call has been moved to the freeze actions anyway,
5263 -- so maybe we can relax this restriction???
5267 end Needs_Constant_Address;
5269 ----------------------------
5270 -- New_Class_Wide_Subtype --
5271 ----------------------------
5273 function New_Class_Wide_Subtype
5274 (CW_Typ : Entity_Id;
5275 N : Node_Id) return Entity_Id
5277 Res : constant Entity_Id := Create_Itype (E_Void, N);
5278 Res_Name : constant Name_Id := Chars (Res);
5279 Res_Scope : constant Entity_Id := Scope (Res);
5282 Copy_Node (CW_Typ, Res);
5283 Set_Comes_From_Source (Res, False);
5284 Set_Sloc (Res, Sloc (N));
5286 Set_Associated_Node_For_Itype (Res, N);
5287 Set_Is_Public (Res, False); -- By default, may be changed below.
5288 Set_Public_Status (Res);
5289 Set_Chars (Res, Res_Name);
5290 Set_Scope (Res, Res_Scope);
5291 Set_Ekind (Res, E_Class_Wide_Subtype);
5292 Set_Next_Entity (Res, Empty);
5293 Set_Etype (Res, Base_Type (CW_Typ));
5294 Set_Is_Frozen (Res, False);
5295 Set_Freeze_Node (Res, Empty);
5297 end New_Class_Wide_Subtype;
5299 --------------------------------
5300 -- Non_Limited_Designated_Type --
5301 ---------------------------------
5303 function Non_Limited_Designated_Type (T : Entity_Id) return Entity_Id is
5304 Desig : constant Entity_Id := Designated_Type (T);
5306 if Ekind (Desig) = E_Incomplete_Type
5307 and then Present (Non_Limited_View (Desig))
5309 return Non_Limited_View (Desig);
5313 end Non_Limited_Designated_Type;
5315 -----------------------------------
5316 -- OK_To_Do_Constant_Replacement --
5317 -----------------------------------
5319 function OK_To_Do_Constant_Replacement (E : Entity_Id) return Boolean is
5320 ES : constant Entity_Id := Scope (E);
5324 -- Do not replace statically allocated objects, because they may be
5325 -- modified outside the current scope.
5327 if Is_Statically_Allocated (E) then
5330 -- Do not replace aliased or volatile objects, since we don't know what
5331 -- else might change the value.
5333 elsif Is_Aliased (E) or else Treat_As_Volatile (E) then
5336 -- Debug flag -gnatdM disconnects this optimization
5338 elsif Debug_Flag_MM then
5341 -- Otherwise check scopes
5344 CS := Current_Scope;
5347 -- If we are in right scope, replacement is safe
5352 -- Packages do not affect the determination of safety
5354 elsif Ekind (CS) = E_Package then
5355 exit when CS = Standard_Standard;
5358 -- Blocks do not affect the determination of safety
5360 elsif Ekind (CS) = E_Block then
5363 -- Loops do not affect the determination of safety. Note that we
5364 -- kill all current values on entry to a loop, so we are just
5365 -- talking about processing within a loop here.
5367 elsif Ekind (CS) = E_Loop then
5370 -- Otherwise, the reference is dubious, and we cannot be sure that
5371 -- it is safe to do the replacement.
5380 end OK_To_Do_Constant_Replacement;
5382 ------------------------------------
5383 -- Possible_Bit_Aligned_Component --
5384 ------------------------------------
5386 function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is
5390 -- Case of indexed component
5392 when N_Indexed_Component =>
5394 P : constant Node_Id := Prefix (N);
5395 Ptyp : constant Entity_Id := Etype (P);
5398 -- If we know the component size and it is less than 64, then
5399 -- we are definitely OK. The back end always does assignment of
5400 -- misaligned small objects correctly.
5402 if Known_Static_Component_Size (Ptyp)
5403 and then Component_Size (Ptyp) <= 64
5407 -- Otherwise, we need to test the prefix, to see if we are
5408 -- indexing from a possibly unaligned component.
5411 return Possible_Bit_Aligned_Component (P);
5415 -- Case of selected component
5417 when N_Selected_Component =>
5419 P : constant Node_Id := Prefix (N);
5420 Comp : constant Entity_Id := Entity (Selector_Name (N));
5423 -- If there is no component clause, then we are in the clear
5424 -- since the back end will never misalign a large component
5425 -- unless it is forced to do so. In the clear means we need
5426 -- only the recursive test on the prefix.
5428 if Component_May_Be_Bit_Aligned (Comp) then
5431 return Possible_Bit_Aligned_Component (P);
5435 -- For a slice, test the prefix, if that is possibly misaligned,
5436 -- then for sure the slice is!
5439 return Possible_Bit_Aligned_Component (Prefix (N));
5441 -- If we have none of the above, it means that we have fallen off the
5442 -- top testing prefixes recursively, and we now have a stand alone
5443 -- object, where we don't have a problem.
5449 end Possible_Bit_Aligned_Component;
5451 -----------------------------------------------
5452 -- Process_Statements_For_Controlled_Objects --
5453 -----------------------------------------------
5455 procedure Process_Statements_For_Controlled_Objects (N : Node_Id) is
5456 Loc : constant Source_Ptr := Sloc (N);
5458 function Are_Wrapped (L : List_Id) return Boolean;
5459 -- Determine whether list L contains only one statement which is a block
5461 function Wrap_Statements_In_Block (L : List_Id) return Node_Id;
5462 -- Given a list of statements L, wrap it in a block statement and return
5463 -- the generated node.
5469 function Are_Wrapped (L : List_Id) return Boolean is
5470 Stmt : constant Node_Id := First (L);
5474 and then No (Next (Stmt))
5475 and then Nkind (Stmt) = N_Block_Statement;
5478 ------------------------------
5479 -- Wrap_Statements_In_Block --
5480 ------------------------------
5482 function Wrap_Statements_In_Block (L : List_Id) return Node_Id is
5485 Make_Block_Statement (Loc,
5486 Declarations => No_List,
5487 Handled_Statement_Sequence =>
5488 Make_Handled_Sequence_Of_Statements (Loc,
5490 end Wrap_Statements_In_Block;
5492 -- Start of processing for Process_Statements_For_Controlled_Objects
5498 N_Conditional_Entry_Call |
5499 N_Selective_Accept =>
5501 -- Check the "then statements" for elsif parts and if statements
5503 if Nkind_In (N, N_Elsif_Part, N_If_Statement)
5504 and then not Is_Empty_List (Then_Statements (N))
5505 and then not Are_Wrapped (Then_Statements (N))
5506 and then Requires_Cleanup_Actions
5507 (Then_Statements (N), False, False)
5509 Set_Then_Statements (N, New_List (
5510 Wrap_Statements_In_Block (Then_Statements (N))));
5513 -- Check the "else statements" for conditional entry calls, if
5514 -- statements and selective accepts.
5516 if Nkind_In (N, N_Conditional_Entry_Call,
5519 and then not Is_Empty_List (Else_Statements (N))
5520 and then not Are_Wrapped (Else_Statements (N))
5521 and then Requires_Cleanup_Actions
5522 (Else_Statements (N), False, False)
5524 Set_Else_Statements (N, New_List (
5525 Wrap_Statements_In_Block (Else_Statements (N))));
5528 when N_Abortable_Part |
5529 N_Accept_Alternative |
5530 N_Case_Statement_Alternative |
5531 N_Delay_Alternative |
5532 N_Entry_Call_Alternative |
5533 N_Exception_Handler |
5535 N_Triggering_Alternative =>
5537 if not Is_Empty_List (Statements (N))
5538 and then not Are_Wrapped (Statements (N))
5539 and then Requires_Cleanup_Actions (Statements (N), False, False)
5541 Set_Statements (N, New_List (
5542 Wrap_Statements_In_Block (Statements (N))));
5548 end Process_Statements_For_Controlled_Objects;
5550 -------------------------
5551 -- Remove_Side_Effects --
5552 -------------------------
5554 procedure Remove_Side_Effects
5556 Name_Req : Boolean := False;
5557 Variable_Ref : Boolean := False)
5559 Loc : constant Source_Ptr := Sloc (Exp);
5560 Exp_Type : constant Entity_Id := Etype (Exp);
5561 Svg_Suppress : constant Suppress_Array := Scope_Suppress;
5563 Ref_Type : Entity_Id;
5565 Ptr_Typ_Decl : Node_Id;
5569 function Side_Effect_Free (N : Node_Id) return Boolean;
5570 -- Determines if the tree N represents an expression that is known not
5571 -- to have side effects, and for which no processing is required.
5573 function Side_Effect_Free (L : List_Id) return Boolean;
5574 -- Determines if all elements of the list L are side effect free
5576 function Safe_Prefixed_Reference (N : Node_Id) return Boolean;
5577 -- The argument N is a construct where the Prefix is dereferenced if it
5578 -- is an access type and the result is a variable. The call returns True
5579 -- if the construct is side effect free (not considering side effects in
5580 -- other than the prefix which are to be tested by the caller).
5582 function Within_In_Parameter (N : Node_Id) return Boolean;
5583 -- Determines if N is a subcomponent of a composite in-parameter. If so,
5584 -- N is not side-effect free when the actual is global and modifiable
5585 -- indirectly from within a subprogram, because it may be passed by
5586 -- reference. The front-end must be conservative here and assume that
5587 -- this may happen with any array or record type. On the other hand, we
5588 -- cannot create temporaries for all expressions for which this
5589 -- condition is true, for various reasons that might require clearing up
5590 -- ??? For example, discriminant references that appear out of place, or
5591 -- spurious type errors with class-wide expressions. As a result, we
5592 -- limit the transformation to loop bounds, which is so far the only
5593 -- case that requires it.
5595 -----------------------------
5596 -- Safe_Prefixed_Reference --
5597 -----------------------------
5599 function Safe_Prefixed_Reference (N : Node_Id) return Boolean is
5601 -- If prefix is not side effect free, definitely not safe
5603 if not Side_Effect_Free (Prefix (N)) then
5606 -- If the prefix is of an access type that is not access-to-constant,
5607 -- then this construct is a variable reference, which means it is to
5608 -- be considered to have side effects if Variable_Ref is set True.
5610 elsif Is_Access_Type (Etype (Prefix (N)))
5611 and then not Is_Access_Constant (Etype (Prefix (N)))
5612 and then Variable_Ref
5614 -- Exception is a prefix that is the result of a previous removal
5617 return Is_Entity_Name (Prefix (N))
5618 and then not Comes_From_Source (Prefix (N))
5619 and then Ekind (Entity (Prefix (N))) = E_Constant
5620 and then Is_Internal_Name (Chars (Entity (Prefix (N))));
5622 -- If the prefix is an explicit dereference then this construct is a
5623 -- variable reference, which means it is to be considered to have
5624 -- side effects if Variable_Ref is True.
5626 -- We do NOT exclude dereferences of access-to-constant types because
5627 -- we handle them as constant view of variables.
5629 -- Exception is an access to an entity that is a constant or an
5632 elsif Nkind (Prefix (N)) = N_Explicit_Dereference
5633 and then Variable_Ref
5636 DDT : constant Entity_Id :=
5637 Designated_Type (Etype (Prefix (Prefix (N))));
5639 return Ekind_In (DDT, E_Constant, E_In_Parameter);
5642 -- The following test is the simplest way of solving a complex
5643 -- problem uncovered by BB08-010: Side effect on loop bound that
5644 -- is a subcomponent of a global variable:
5646 -- If a loop bound is a subcomponent of a global variable, a
5647 -- modification of that variable within the loop may incorrectly
5648 -- affect the execution of the loop.
5651 (Nkind (Parent (Parent (N))) /= N_Loop_Parameter_Specification
5652 or else not Within_In_Parameter (Prefix (N)))
5656 -- All other cases are side effect free
5661 end Safe_Prefixed_Reference;
5663 ----------------------
5664 -- Side_Effect_Free --
5665 ----------------------
5667 function Side_Effect_Free (N : Node_Id) return Boolean is
5669 -- Note on checks that could raise Constraint_Error. Strictly, if we
5670 -- take advantage of 11.6, these checks do not count as side effects.
5671 -- However, we would prefer to consider that they are side effects,
5672 -- since the backend CSE does not work very well on expressions which
5673 -- can raise Constraint_Error. On the other hand if we don't consider
5674 -- them to be side effect free, then we get some awkward expansions
5675 -- in -gnato mode, resulting in code insertions at a point where we
5676 -- do not have a clear model for performing the insertions.
5678 -- Special handling for entity names
5680 if Is_Entity_Name (N) then
5682 -- Variables are considered to be a side effect if Variable_Ref
5683 -- is set or if we have a volatile reference and Name_Req is off.
5684 -- If Name_Req is True then we can't help returning a name which
5685 -- effectively allows multiple references in any case.
5687 if Is_Variable (N, Use_Original_Node => False) then
5688 return not Variable_Ref
5689 and then (not Is_Volatile_Reference (N) or else Name_Req);
5691 -- Any other entity (e.g. a subtype name) is definitely side
5698 -- A value known at compile time is always side effect free
5700 elsif Compile_Time_Known_Value (N) then
5703 -- A variable renaming is not side-effect free, because the renaming
5704 -- will function like a macro in the front-end in some cases, and an
5705 -- assignment can modify the component designated by N, so we need to
5706 -- create a temporary for it.
5708 -- The guard testing for Entity being present is needed at least in
5709 -- the case of rewritten predicate expressions, and may well also be
5710 -- appropriate elsewhere. Obviously we can't go testing the entity
5711 -- field if it does not exist, so it's reasonable to say that this is
5712 -- not the renaming case if it does not exist.
5714 elsif Is_Entity_Name (Original_Node (N))
5715 and then Present (Entity (Original_Node (N)))
5716 and then Is_Renaming_Of_Object (Entity (Original_Node (N)))
5717 and then Ekind (Entity (Original_Node (N))) /= E_Constant
5721 -- Remove_Side_Effects generates an object renaming declaration to
5722 -- capture the expression of a class-wide expression. In VM targets
5723 -- the frontend performs no expansion for dispatching calls to
5724 -- class- wide types since they are handled by the VM. Hence, we must
5725 -- locate here if this node corresponds to a previous invocation of
5726 -- Remove_Side_Effects to avoid a never ending loop in the frontend.
5728 elsif VM_Target /= No_VM
5729 and then not Comes_From_Source (N)
5730 and then Nkind (Parent (N)) = N_Object_Renaming_Declaration
5731 and then Is_Class_Wide_Type (Etype (N))
5736 -- For other than entity names and compile time known values,
5737 -- check the node kind for special processing.
5741 -- An attribute reference is side effect free if its expressions
5742 -- are side effect free and its prefix is side effect free or
5743 -- is an entity reference.
5745 -- Is this right? what about x'first where x is a variable???
5747 when N_Attribute_Reference =>
5748 return Side_Effect_Free (Expressions (N))
5749 and then Attribute_Name (N) /= Name_Input
5750 and then (Is_Entity_Name (Prefix (N))
5751 or else Side_Effect_Free (Prefix (N)));
5753 -- A binary operator is side effect free if and both operands are
5754 -- side effect free. For this purpose binary operators include
5755 -- membership tests and short circuit forms
5757 when N_Binary_Op | N_Membership_Test | N_Short_Circuit =>
5758 return Side_Effect_Free (Left_Opnd (N))
5760 Side_Effect_Free (Right_Opnd (N));
5762 -- An explicit dereference is side effect free only if it is
5763 -- a side effect free prefixed reference.
5765 when N_Explicit_Dereference =>
5766 return Safe_Prefixed_Reference (N);
5768 -- A call to _rep_to_pos is side effect free, since we generate
5769 -- this pure function call ourselves. Moreover it is critically
5770 -- important to make this exception, since otherwise we can have
5771 -- discriminants in array components which don't look side effect
5772 -- free in the case of an array whose index type is an enumeration
5773 -- type with an enumeration rep clause.
5775 -- All other function calls are not side effect free
5777 when N_Function_Call =>
5778 return Nkind (Name (N)) = N_Identifier
5779 and then Is_TSS (Name (N), TSS_Rep_To_Pos)
5781 Side_Effect_Free (First (Parameter_Associations (N)));
5783 -- An indexed component is side effect free if it is a side
5784 -- effect free prefixed reference and all the indexing
5785 -- expressions are side effect free.
5787 when N_Indexed_Component =>
5788 return Side_Effect_Free (Expressions (N))
5789 and then Safe_Prefixed_Reference (N);
5791 -- A type qualification is side effect free if the expression
5792 -- is side effect free.
5794 when N_Qualified_Expression =>
5795 return Side_Effect_Free (Expression (N));
5797 -- A selected component is side effect free only if it is a side
5798 -- effect free prefixed reference. If it designates a component
5799 -- with a rep. clause it must be treated has having a potential
5800 -- side effect, because it may be modified through a renaming, and
5801 -- a subsequent use of the renaming as a macro will yield the
5802 -- wrong value. This complex interaction between renaming and
5803 -- removing side effects is a reminder that the latter has become
5804 -- a headache to maintain, and that it should be removed in favor
5805 -- of the gcc mechanism to capture values ???
5807 when N_Selected_Component =>
5808 if Nkind (Parent (N)) = N_Explicit_Dereference
5809 and then Has_Non_Standard_Rep (Designated_Type (Etype (N)))
5813 return Safe_Prefixed_Reference (N);
5816 -- A range is side effect free if the bounds are side effect free
5819 return Side_Effect_Free (Low_Bound (N))
5820 and then Side_Effect_Free (High_Bound (N));
5822 -- A slice is side effect free if it is a side effect free
5823 -- prefixed reference and the bounds are side effect free.
5826 return Side_Effect_Free (Discrete_Range (N))
5827 and then Safe_Prefixed_Reference (N);
5829 -- A type conversion is side effect free if the expression to be
5830 -- converted is side effect free.
5832 when N_Type_Conversion =>
5833 return Side_Effect_Free (Expression (N));
5835 -- A unary operator is side effect free if the operand
5836 -- is side effect free.
5839 return Side_Effect_Free (Right_Opnd (N));
5841 -- An unchecked type conversion is side effect free only if it
5842 -- is safe and its argument is side effect free.
5844 when N_Unchecked_Type_Conversion =>
5845 return Safe_Unchecked_Type_Conversion (N)
5846 and then Side_Effect_Free (Expression (N));
5848 -- An unchecked expression is side effect free if its expression
5849 -- is side effect free.
5851 when N_Unchecked_Expression =>
5852 return Side_Effect_Free (Expression (N));
5854 -- A literal is side effect free
5856 when N_Character_Literal |
5862 -- We consider that anything else has side effects. This is a bit
5863 -- crude, but we are pretty close for most common cases, and we
5864 -- are certainly correct (i.e. we never return True when the
5865 -- answer should be False).
5870 end Side_Effect_Free;
5872 -- A list is side effect free if all elements of the list are side
5875 function Side_Effect_Free (L : List_Id) return Boolean is
5879 if L = No_List or else L = Error_List then
5884 while Present (N) loop
5885 if not Side_Effect_Free (N) then
5894 end Side_Effect_Free;
5896 -------------------------
5897 -- Within_In_Parameter --
5898 -------------------------
5900 function Within_In_Parameter (N : Node_Id) return Boolean is
5902 if not Comes_From_Source (N) then
5905 elsif Is_Entity_Name (N) then
5906 return Ekind (Entity (N)) = E_In_Parameter;
5908 elsif Nkind (N) = N_Indexed_Component
5909 or else Nkind (N) = N_Selected_Component
5911 return Within_In_Parameter (Prefix (N));
5916 end Within_In_Parameter;
5918 -- Start of processing for Remove_Side_Effects
5921 -- Handle cases in which there is nothing to do
5923 if not Expander_Active then
5926 -- Cannot generate temporaries if the invocation to remove side effects
5927 -- was issued too early and the type of the expression is not resolved
5928 -- (this happens because routines Duplicate_Subexpr_XX implicitly invoke
5929 -- Remove_Side_Effects).
5932 or else Ekind (Exp_Type) = E_Access_Attribute_Type
5936 -- No action needed for side-effect free expressions
5938 elsif Side_Effect_Free (Exp) then
5942 -- All this must not have any checks
5944 Scope_Suppress := (others => True);
5946 -- If it is a scalar type and we need to capture the value, just make
5947 -- a copy. Likewise for a function call, an attribute reference, an
5948 -- allocator, or an operator. And if we have a volatile reference and
5949 -- Name_Req is not set (see comments above for Side_Effect_Free).
5951 if Is_Elementary_Type (Exp_Type)
5952 and then (Variable_Ref
5953 or else Nkind (Exp) = N_Function_Call
5954 or else Nkind (Exp) = N_Attribute_Reference
5955 or else Nkind (Exp) = N_Allocator
5956 or else Nkind (Exp) in N_Op
5957 or else (not Name_Req and then Is_Volatile_Reference (Exp)))
5959 Def_Id := Make_Temporary (Loc, 'R', Exp);
5960 Set_Etype (Def_Id, Exp_Type);
5961 Res := New_Reference_To (Def_Id, Loc);
5963 -- If the expression is a packed reference, it must be reanalyzed and
5964 -- expanded, depending on context. This is the case for actuals where
5965 -- a constraint check may capture the actual before expansion of the
5966 -- call is complete.
5968 if Nkind (Exp) = N_Indexed_Component
5969 and then Is_Packed (Etype (Prefix (Exp)))
5971 Set_Analyzed (Exp, False);
5972 Set_Analyzed (Prefix (Exp), False);
5976 Make_Object_Declaration (Loc,
5977 Defining_Identifier => Def_Id,
5978 Object_Definition => New_Reference_To (Exp_Type, Loc),
5979 Constant_Present => True,
5980 Expression => Relocate_Node (Exp));
5982 Set_Assignment_OK (E);
5983 Insert_Action (Exp, E);
5985 -- If the expression has the form v.all then we can just capture the
5986 -- pointer, and then do an explicit dereference on the result.
5988 elsif Nkind (Exp) = N_Explicit_Dereference then
5989 Def_Id := Make_Temporary (Loc, 'R', Exp);
5991 Make_Explicit_Dereference (Loc, New_Reference_To (Def_Id, Loc));
5994 Make_Object_Declaration (Loc,
5995 Defining_Identifier => Def_Id,
5996 Object_Definition =>
5997 New_Reference_To (Etype (Prefix (Exp)), Loc),
5998 Constant_Present => True,
5999 Expression => Relocate_Node (Prefix (Exp))));
6001 -- Similar processing for an unchecked conversion of an expression of
6002 -- the form v.all, where we want the same kind of treatment.
6004 elsif Nkind (Exp) = N_Unchecked_Type_Conversion
6005 and then Nkind (Expression (Exp)) = N_Explicit_Dereference
6007 Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
6008 Scope_Suppress := Svg_Suppress;
6011 -- If this is a type conversion, leave the type conversion and remove
6012 -- the side effects in the expression. This is important in several
6013 -- circumstances: for change of representations, and also when this is a
6014 -- view conversion to a smaller object, where gigi can end up creating
6015 -- its own temporary of the wrong size.
6017 elsif Nkind (Exp) = N_Type_Conversion then
6018 Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
6019 Scope_Suppress := Svg_Suppress;
6022 -- If this is an unchecked conversion that Gigi can't handle, make
6023 -- a copy or a use a renaming to capture the value.
6025 elsif Nkind (Exp) = N_Unchecked_Type_Conversion
6026 and then not Safe_Unchecked_Type_Conversion (Exp)
6028 if CW_Or_Has_Controlled_Part (Exp_Type) then
6030 -- Use a renaming to capture the expression, rather than create
6031 -- a controlled temporary.
6033 Def_Id := Make_Temporary (Loc, 'R', Exp);
6034 Res := New_Reference_To (Def_Id, Loc);
6037 Make_Object_Renaming_Declaration (Loc,
6038 Defining_Identifier => Def_Id,
6039 Subtype_Mark => New_Reference_To (Exp_Type, Loc),
6040 Name => Relocate_Node (Exp)));
6043 Def_Id := Make_Temporary (Loc, 'R', Exp);
6044 Set_Etype (Def_Id, Exp_Type);
6045 Res := New_Reference_To (Def_Id, Loc);
6048 Make_Object_Declaration (Loc,
6049 Defining_Identifier => Def_Id,
6050 Object_Definition => New_Reference_To (Exp_Type, Loc),
6051 Constant_Present => not Is_Variable (Exp),
6052 Expression => Relocate_Node (Exp));
6054 Set_Assignment_OK (E);
6055 Insert_Action (Exp, E);
6058 -- For expressions that denote objects, we can use a renaming scheme.
6059 -- This is needed for correctness in the case of a volatile object of a
6060 -- non-volatile type because the Make_Reference call of the "default"
6061 -- approach would generate an illegal access value (an access value
6062 -- cannot designate such an object - see Analyze_Reference). We skip
6063 -- using this scheme if we have an object of a volatile type and we do
6064 -- not have Name_Req set true (see comments above for Side_Effect_Free).
6066 elsif Is_Object_Reference (Exp)
6067 and then Nkind (Exp) /= N_Function_Call
6068 and then (Name_Req or else not Treat_As_Volatile (Exp_Type))
6070 Def_Id := Make_Temporary (Loc, 'R', Exp);
6072 if Nkind (Exp) = N_Selected_Component
6073 and then Nkind (Prefix (Exp)) = N_Function_Call
6074 and then Is_Array_Type (Exp_Type)
6076 -- Avoid generating a variable-sized temporary, by generating
6077 -- the renaming declaration just for the function call. The
6078 -- transformation could be refined to apply only when the array
6079 -- component is constrained by a discriminant???
6082 Make_Selected_Component (Loc,
6083 Prefix => New_Occurrence_Of (Def_Id, Loc),
6084 Selector_Name => Selector_Name (Exp));
6087 Make_Object_Renaming_Declaration (Loc,
6088 Defining_Identifier => Def_Id,
6090 New_Reference_To (Base_Type (Etype (Prefix (Exp))), Loc),
6091 Name => Relocate_Node (Prefix (Exp))));
6094 Res := New_Reference_To (Def_Id, Loc);
6097 Make_Object_Renaming_Declaration (Loc,
6098 Defining_Identifier => Def_Id,
6099 Subtype_Mark => New_Reference_To (Exp_Type, Loc),
6100 Name => Relocate_Node (Exp)));
6103 -- If this is a packed reference, or a selected component with
6104 -- a non-standard representation, a reference to the temporary
6105 -- will be replaced by a copy of the original expression (see
6106 -- Exp_Ch2.Expand_Renaming). Otherwise the temporary must be
6107 -- elaborated by gigi, and is of course not to be replaced in-line
6108 -- by the expression it renames, which would defeat the purpose of
6109 -- removing the side-effect.
6111 if (Nkind (Exp) = N_Selected_Component
6112 or else Nkind (Exp) = N_Indexed_Component)
6113 and then Has_Non_Standard_Rep (Etype (Prefix (Exp)))
6117 Set_Is_Renaming_Of_Object (Def_Id, False);
6120 -- Otherwise we generate a reference to the value
6123 -- Special processing for function calls that return a limited type.
6124 -- We need to build a declaration that will enable build-in-place
6125 -- expansion of the call. This is not done if the context is already
6126 -- an object declaration, to prevent infinite recursion.
6128 -- This is relevant only in Ada 2005 mode. In Ada 95 programs we have
6129 -- to accommodate functions returning limited objects by reference.
6131 if Nkind (Exp) = N_Function_Call
6132 and then Is_Immutably_Limited_Type (Etype (Exp))
6133 and then Nkind (Parent (Exp)) /= N_Object_Declaration
6134 and then Ada_Version >= Ada_2005
6137 Obj : constant Entity_Id := Make_Temporary (Loc, 'F', Exp);
6142 Make_Object_Declaration (Loc,
6143 Defining_Identifier => Obj,
6144 Object_Definition => New_Occurrence_Of (Exp_Type, Loc),
6145 Expression => Relocate_Node (Exp));
6147 Insert_Action (Exp, Decl);
6148 Set_Etype (Obj, Exp_Type);
6149 Rewrite (Exp, New_Occurrence_Of (Obj, Loc));
6154 Ref_Type := Make_Temporary (Loc, 'A');
6157 Make_Full_Type_Declaration (Loc,
6158 Defining_Identifier => Ref_Type,
6160 Make_Access_To_Object_Definition (Loc,
6161 All_Present => True,
6162 Subtype_Indication =>
6163 New_Reference_To (Exp_Type, Loc)));
6166 Insert_Action (Exp, Ptr_Typ_Decl);
6168 Def_Id := Make_Temporary (Loc, 'R', Exp);
6169 Set_Etype (Def_Id, Exp_Type);
6172 Make_Explicit_Dereference (Loc,
6173 Prefix => New_Reference_To (Def_Id, Loc));
6175 if Nkind (E) = N_Explicit_Dereference then
6176 New_Exp := Relocate_Node (Prefix (E));
6178 E := Relocate_Node (E);
6179 New_Exp := Make_Reference (Loc, E);
6182 if Is_Delayed_Aggregate (E) then
6184 -- The expansion of nested aggregates is delayed until the
6185 -- enclosing aggregate is expanded. As aggregates are often
6186 -- qualified, the predicate applies to qualified expressions as
6187 -- well, indicating that the enclosing aggregate has not been
6188 -- expanded yet. At this point the aggregate is part of a
6189 -- stand-alone declaration, and must be fully expanded.
6191 if Nkind (E) = N_Qualified_Expression then
6192 Set_Expansion_Delayed (Expression (E), False);
6193 Set_Analyzed (Expression (E), False);
6195 Set_Expansion_Delayed (E, False);
6198 Set_Analyzed (E, False);
6202 Make_Object_Declaration (Loc,
6203 Defining_Identifier => Def_Id,
6204 Object_Definition => New_Reference_To (Ref_Type, Loc),
6205 Constant_Present => True,
6206 Expression => New_Exp));
6209 -- Preserve the Assignment_OK flag in all copies, since at least one
6210 -- copy may be used in a context where this flag must be set (otherwise
6211 -- why would the flag be set in the first place).
6213 Set_Assignment_OK (Res, Assignment_OK (Exp));
6215 -- Finally rewrite the original expression and we are done
6218 Analyze_And_Resolve (Exp, Exp_Type);
6219 Scope_Suppress := Svg_Suppress;
6220 end Remove_Side_Effects;
6222 ---------------------------
6223 -- Represented_As_Scalar --
6224 ---------------------------
6226 function Represented_As_Scalar (T : Entity_Id) return Boolean is
6227 UT : constant Entity_Id := Underlying_Type (T);
6229 return Is_Scalar_Type (UT)
6230 or else (Is_Bit_Packed_Array (UT)
6231 and then Is_Scalar_Type (Packed_Array_Type (UT)));
6232 end Represented_As_Scalar;
6234 ------------------------------
6235 -- Requires_Cleanup_Actions --
6236 ------------------------------
6238 function Requires_Cleanup_Actions (N : Node_Id) return Boolean is
6239 For_Pkg : constant Boolean :=
6240 Nkind_In (N, N_Package_Body, N_Package_Specification);
6244 when N_Accept_Statement |
6252 Requires_Cleanup_Actions (Declarations (N), For_Pkg, True)
6254 (Present (Handled_Statement_Sequence (N))
6256 Requires_Cleanup_Actions (Statements
6257 (Handled_Statement_Sequence (N)), For_Pkg, True));
6259 when N_Package_Specification =>
6261 Requires_Cleanup_Actions
6262 (Visible_Declarations (N), For_Pkg, True)
6264 Requires_Cleanup_Actions
6265 (Private_Declarations (N), For_Pkg, True);
6270 end Requires_Cleanup_Actions;
6272 ------------------------------
6273 -- Requires_Cleanup_Actions --
6274 ------------------------------
6276 function Requires_Cleanup_Actions
6278 For_Package : Boolean;
6279 Nested_Constructs : Boolean) return Boolean
6284 Obj_Typ : Entity_Id;
6285 Pack_Id : Entity_Id;
6290 or else Is_Empty_List (L)
6296 while Present (Decl) loop
6298 -- Library-level tagged types
6300 if Nkind (Decl) = N_Full_Type_Declaration then
6301 Typ := Defining_Identifier (Decl);
6303 if Is_Tagged_Type (Typ)
6304 and then Is_Library_Level_Entity (Typ)
6305 and then Convention (Typ) = Convention_Ada
6306 and then Present (Access_Disp_Table (Typ))
6307 and then RTE_Available (RE_Unregister_Tag)
6308 and then not No_Run_Time_Mode
6309 and then not Is_Abstract_Type (Typ)
6314 -- Regular object declarations
6316 elsif Nkind (Decl) = N_Object_Declaration then
6317 Obj_Id := Defining_Identifier (Decl);
6318 Obj_Typ := Base_Type (Etype (Obj_Id));
6319 Expr := Expression (Decl);
6321 -- Bypass any form of processing for objects which have their
6322 -- finalization disabled. This applies only to objects at the
6326 and then Finalize_Storage_Only (Obj_Typ)
6330 -- Transient variables are treated separately in order to minimize
6331 -- the size of the generated code. See Exp_Ch7.Process_Transient_
6334 elsif Is_Processed_Transient (Obj_Id) then
6337 -- The object is of the form:
6338 -- Obj : Typ [:= Expr];
6340 -- Do not process the incomplete view of a deferred constant. Do
6341 -- not consider tag-to-class-wide conversions.
6343 elsif not Is_Imported (Obj_Id)
6344 and then Needs_Finalization (Obj_Typ)
6345 and then not (Ekind (Obj_Id) = E_Constant
6346 and then not Has_Completion (Obj_Id))
6347 and then not Is_Tag_To_CW_Conversion (Obj_Id)
6351 -- The object is of the form:
6352 -- Obj : Access_Typ := Non_BIP_Function_Call'reference;
6354 -- Obj : Access_Typ :=
6355 -- BIP_Function_Call
6356 -- (..., BIPaccess => null, ...)'reference;
6358 elsif Is_Access_Type (Obj_Typ)
6359 and then Needs_Finalization
6360 (Available_View (Designated_Type (Obj_Typ)))
6361 and then Present (Expr)
6363 (Is_Null_Access_BIP_Func_Call (Expr)
6365 (Is_Non_BIP_Func_Call (Expr)
6366 and then not Is_Related_To_Func_Return (Obj_Id)))
6370 -- Processing for "hook" objects generated for controlled
6371 -- transients declared inside an Expression_With_Actions.
6373 elsif Is_Access_Type (Obj_Typ)
6374 and then Present (Return_Flag_Or_Transient_Decl (Obj_Id))
6375 and then Nkind (Return_Flag_Or_Transient_Decl (Obj_Id)) =
6376 N_Object_Declaration
6377 and then Is_Finalizable_Transient
6378 (Return_Flag_Or_Transient_Decl (Obj_Id), Decl)
6382 -- Simple protected objects which use type System.Tasking.
6383 -- Protected_Objects.Protection to manage their locks should be
6384 -- treated as controlled since they require manual cleanup.
6386 elsif Ekind (Obj_Id) = E_Variable
6388 (Is_Simple_Protected_Type (Obj_Typ)
6389 or else Has_Simple_Protected_Object (Obj_Typ))
6394 -- Specific cases of object renamings
6396 elsif Nkind (Decl) = N_Object_Renaming_Declaration
6397 and then Nkind (Name (Decl)) = N_Explicit_Dereference
6398 and then Nkind (Prefix (Name (Decl))) = N_Identifier
6400 Obj_Id := Defining_Identifier (Decl);
6401 Obj_Typ := Base_Type (Etype (Obj_Id));
6403 -- Bypass any form of processing for objects which have their
6404 -- finalization disabled. This applies only to objects at the
6408 and then Finalize_Storage_Only (Obj_Typ)
6412 -- Return object of a build-in-place function. This case is
6413 -- recognized and marked by the expansion of an extended return
6414 -- statement (see Expand_N_Extended_Return_Statement).
6416 elsif Needs_Finalization (Obj_Typ)
6417 and then Is_Return_Object (Obj_Id)
6418 and then Present (Return_Flag_Or_Transient_Decl (Obj_Id))
6423 -- Inspect the freeze node of an access-to-controlled type and
6424 -- look for a delayed finalization collection. This case arises
6425 -- when the freeze actions are inserted at a later time than the
6426 -- expansion of the context. Since Build_Finalizer is never called
6427 -- on a single construct twice, the collection will be ultimately
6428 -- left out and never finalized. This is also needed for freeze
6429 -- actions of designated types themselves, since in some cases the
6430 -- finalization collection is associated with a designated type's
6431 -- freeze node rather than that of the access type (see handling
6432 -- for freeze actions in Build_Finalization_Collection).
6434 elsif Nkind (Decl) = N_Freeze_Entity
6435 and then Present (Actions (Decl))
6437 Typ := Entity (Decl);
6439 if (Is_Access_Type (Typ)
6440 and then not Is_Access_Subprogram_Type (Typ)
6441 and then Needs_Finalization
6442 (Available_View (Designated_Type (Typ))))
6445 and then Needs_Finalization (Typ))
6450 -- Nested package declarations
6452 elsif Nested_Constructs
6453 and then Nkind (Decl) = N_Package_Declaration
6455 Pack_Id := Defining_Unit_Name (Specification (Decl));
6457 if Nkind (Pack_Id) = N_Defining_Program_Unit_Name then
6458 Pack_Id := Defining_Identifier (Pack_Id);
6461 if Ekind (Pack_Id) /= E_Generic_Package
6462 and then Requires_Cleanup_Actions (Specification (Decl))
6467 -- Nested package bodies
6469 elsif Nested_Constructs
6470 and then Nkind (Decl) = N_Package_Body
6472 Pack_Id := Corresponding_Spec (Decl);
6474 if Ekind (Pack_Id) /= E_Generic_Package
6475 and then Requires_Cleanup_Actions (Decl)
6485 end Requires_Cleanup_Actions;
6487 ------------------------------------
6488 -- Safe_Unchecked_Type_Conversion --
6489 ------------------------------------
6491 -- Note: this function knows quite a bit about the exact requirements of
6492 -- Gigi with respect to unchecked type conversions, and its code must be
6493 -- coordinated with any changes in Gigi in this area.
6495 -- The above requirements should be documented in Sinfo ???
6497 function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is
6502 Pexp : constant Node_Id := Parent (Exp);
6505 -- If the expression is the RHS of an assignment or object declaration
6506 -- we are always OK because there will always be a target.
6508 -- Object renaming declarations, (generated for view conversions of
6509 -- actuals in inlined calls), like object declarations, provide an
6510 -- explicit type, and are safe as well.
6512 if (Nkind (Pexp) = N_Assignment_Statement
6513 and then Expression (Pexp) = Exp)
6514 or else Nkind (Pexp) = N_Object_Declaration
6515 or else Nkind (Pexp) = N_Object_Renaming_Declaration
6519 -- If the expression is the prefix of an N_Selected_Component we should
6520 -- also be OK because GCC knows to look inside the conversion except if
6521 -- the type is discriminated. We assume that we are OK anyway if the
6522 -- type is not set yet or if it is controlled since we can't afford to
6523 -- introduce a temporary in this case.
6525 elsif Nkind (Pexp) = N_Selected_Component
6526 and then Prefix (Pexp) = Exp
6528 if No (Etype (Pexp)) then
6532 not Has_Discriminants (Etype (Pexp))
6533 or else Is_Constrained (Etype (Pexp));
6537 -- Set the output type, this comes from Etype if it is set, otherwise we
6538 -- take it from the subtype mark, which we assume was already fully
6541 if Present (Etype (Exp)) then
6542 Otyp := Etype (Exp);
6544 Otyp := Entity (Subtype_Mark (Exp));
6547 -- The input type always comes from the expression, and we assume
6548 -- this is indeed always analyzed, so we can simply get the Etype.
6550 Ityp := Etype (Expression (Exp));
6552 -- Initialize alignments to unknown so far
6557 -- Replace a concurrent type by its corresponding record type and each
6558 -- type by its underlying type and do the tests on those. The original
6559 -- type may be a private type whose completion is a concurrent type, so
6560 -- find the underlying type first.
6562 if Present (Underlying_Type (Otyp)) then
6563 Otyp := Underlying_Type (Otyp);
6566 if Present (Underlying_Type (Ityp)) then
6567 Ityp := Underlying_Type (Ityp);
6570 if Is_Concurrent_Type (Otyp) then
6571 Otyp := Corresponding_Record_Type (Otyp);
6574 if Is_Concurrent_Type (Ityp) then
6575 Ityp := Corresponding_Record_Type (Ityp);
6578 -- If the base types are the same, we know there is no problem since
6579 -- this conversion will be a noop.
6581 if Implementation_Base_Type (Otyp) = Implementation_Base_Type (Ityp) then
6584 -- Same if this is an upwards conversion of an untagged type, and there
6585 -- are no constraints involved (could be more general???)
6587 elsif Etype (Ityp) = Otyp
6588 and then not Is_Tagged_Type (Ityp)
6589 and then not Has_Discriminants (Ityp)
6590 and then No (First_Rep_Item (Base_Type (Ityp)))
6594 -- If the expression has an access type (object or subprogram) we assume
6595 -- that the conversion is safe, because the size of the target is safe,
6596 -- even if it is a record (which might be treated as having unknown size
6599 elsif Is_Access_Type (Ityp) then
6602 -- If the size of output type is known at compile time, there is never
6603 -- a problem. Note that unconstrained records are considered to be of
6604 -- known size, but we can't consider them that way here, because we are
6605 -- talking about the actual size of the object.
6607 -- We also make sure that in addition to the size being known, we do not
6608 -- have a case which might generate an embarrassingly large temp in
6609 -- stack checking mode.
6611 elsif Size_Known_At_Compile_Time (Otyp)
6613 (not Stack_Checking_Enabled
6614 or else not May_Generate_Large_Temp (Otyp))
6615 and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp))
6619 -- If either type is tagged, then we know the alignment is OK so
6620 -- Gigi will be able to use pointer punning.
6622 elsif Is_Tagged_Type (Otyp) or else Is_Tagged_Type (Ityp) then
6625 -- If either type is a limited record type, we cannot do a copy, so say
6626 -- safe since there's nothing else we can do.
6628 elsif Is_Limited_Record (Otyp) or else Is_Limited_Record (Ityp) then
6631 -- Conversions to and from packed array types are always ignored and
6634 elsif Is_Packed_Array_Type (Otyp)
6635 or else Is_Packed_Array_Type (Ityp)
6640 -- The only other cases known to be safe is if the input type's
6641 -- alignment is known to be at least the maximum alignment for the
6642 -- target or if both alignments are known and the output type's
6643 -- alignment is no stricter than the input's. We can use the component
6644 -- type alignement for an array if a type is an unpacked array type.
6646 if Present (Alignment_Clause (Otyp)) then
6647 Oalign := Expr_Value (Expression (Alignment_Clause (Otyp)));
6649 elsif Is_Array_Type (Otyp)
6650 and then Present (Alignment_Clause (Component_Type (Otyp)))
6652 Oalign := Expr_Value (Expression (Alignment_Clause
6653 (Component_Type (Otyp))));
6656 if Present (Alignment_Clause (Ityp)) then
6657 Ialign := Expr_Value (Expression (Alignment_Clause (Ityp)));
6659 elsif Is_Array_Type (Ityp)
6660 and then Present (Alignment_Clause (Component_Type (Ityp)))
6662 Ialign := Expr_Value (Expression (Alignment_Clause
6663 (Component_Type (Ityp))));
6666 if Ialign /= No_Uint and then Ialign > Maximum_Alignment then
6669 elsif Ialign /= No_Uint and then Oalign /= No_Uint
6670 and then Ialign <= Oalign
6674 -- Otherwise, Gigi cannot handle this and we must make a temporary
6679 end Safe_Unchecked_Type_Conversion;
6681 ---------------------------------
6682 -- Set_Current_Value_Condition --
6683 ---------------------------------
6685 -- Note: the implementation of this procedure is very closely tied to the
6686 -- implementation of Get_Current_Value_Condition. Here we set required
6687 -- Current_Value fields, and in Get_Current_Value_Condition, we interpret
6688 -- them, so they must have a consistent view.
6690 procedure Set_Current_Value_Condition (Cnode : Node_Id) is
6692 procedure Set_Entity_Current_Value (N : Node_Id);
6693 -- If N is an entity reference, where the entity is of an appropriate
6694 -- kind, then set the current value of this entity to Cnode, unless
6695 -- there is already a definite value set there.
6697 procedure Set_Expression_Current_Value (N : Node_Id);
6698 -- If N is of an appropriate form, sets an appropriate entry in current
6699 -- value fields of relevant entities. Multiple entities can be affected
6700 -- in the case of an AND or AND THEN.
6702 ------------------------------
6703 -- Set_Entity_Current_Value --
6704 ------------------------------
6706 procedure Set_Entity_Current_Value (N : Node_Id) is
6708 if Is_Entity_Name (N) then
6710 Ent : constant Entity_Id := Entity (N);
6713 -- Don't capture if not safe to do so
6715 if not Safe_To_Capture_Value (N, Ent, Cond => True) then
6719 -- Here we have a case where the Current_Value field may need
6720 -- to be set. We set it if it is not already set to a compile
6721 -- time expression value.
6723 -- Note that this represents a decision that one condition
6724 -- blots out another previous one. That's certainly right if
6725 -- they occur at the same level. If the second one is nested,
6726 -- then the decision is neither right nor wrong (it would be
6727 -- equally OK to leave the outer one in place, or take the new
6728 -- inner one. Really we should record both, but our data
6729 -- structures are not that elaborate.
6731 if Nkind (Current_Value (Ent)) not in N_Subexpr then
6732 Set_Current_Value (Ent, Cnode);
6736 end Set_Entity_Current_Value;
6738 ----------------------------------
6739 -- Set_Expression_Current_Value --
6740 ----------------------------------
6742 procedure Set_Expression_Current_Value (N : Node_Id) is
6748 -- Loop to deal with (ignore for now) any NOT operators present. The
6749 -- presence of NOT operators will be handled properly when we call
6750 -- Get_Current_Value_Condition.
6752 while Nkind (Cond) = N_Op_Not loop
6753 Cond := Right_Opnd (Cond);
6756 -- For an AND or AND THEN, recursively process operands
6758 if Nkind (Cond) = N_Op_And or else Nkind (Cond) = N_And_Then then
6759 Set_Expression_Current_Value (Left_Opnd (Cond));
6760 Set_Expression_Current_Value (Right_Opnd (Cond));
6764 -- Check possible relational operator
6766 if Nkind (Cond) in N_Op_Compare then
6767 if Compile_Time_Known_Value (Right_Opnd (Cond)) then
6768 Set_Entity_Current_Value (Left_Opnd (Cond));
6769 elsif Compile_Time_Known_Value (Left_Opnd (Cond)) then
6770 Set_Entity_Current_Value (Right_Opnd (Cond));
6773 -- Check possible boolean variable reference
6776 Set_Entity_Current_Value (Cond);
6778 end Set_Expression_Current_Value;
6780 -- Start of processing for Set_Current_Value_Condition
6783 Set_Expression_Current_Value (Condition (Cnode));
6784 end Set_Current_Value_Condition;
6786 --------------------------
6787 -- Set_Elaboration_Flag --
6788 --------------------------
6790 procedure Set_Elaboration_Flag (N : Node_Id; Spec_Id : Entity_Id) is
6791 Loc : constant Source_Ptr := Sloc (N);
6792 Ent : constant Entity_Id := Elaboration_Entity (Spec_Id);
6796 if Present (Ent) then
6798 -- Nothing to do if at the compilation unit level, because in this
6799 -- case the flag is set by the binder generated elaboration routine.
6801 if Nkind (Parent (N)) = N_Compilation_Unit then
6804 -- Here we do need to generate an assignment statement
6807 Check_Restriction (No_Elaboration_Code, N);
6809 Make_Assignment_Statement (Loc,
6810 Name => New_Occurrence_Of (Ent, Loc),
6811 Expression => Make_Integer_Literal (Loc, Uint_1));
6813 if Nkind (Parent (N)) = N_Subunit then
6814 Insert_After (Corresponding_Stub (Parent (N)), Asn);
6816 Insert_After (N, Asn);
6821 -- Kill current value indication. This is necessary because the
6822 -- tests of this flag are inserted out of sequence and must not
6823 -- pick up bogus indications of the wrong constant value.
6825 Set_Current_Value (Ent, Empty);
6828 end Set_Elaboration_Flag;
6830 ----------------------------
6831 -- Set_Renamed_Subprogram --
6832 ----------------------------
6834 procedure Set_Renamed_Subprogram (N : Node_Id; E : Entity_Id) is
6836 -- If input node is an identifier, we can just reset it
6838 if Nkind (N) = N_Identifier then
6839 Set_Chars (N, Chars (E));
6842 -- Otherwise we have to do a rewrite, preserving Comes_From_Source
6846 CS : constant Boolean := Comes_From_Source (N);
6848 Rewrite (N, Make_Identifier (Sloc (N), Chars (E)));
6850 Set_Comes_From_Source (N, CS);
6851 Set_Analyzed (N, True);
6854 end Set_Renamed_Subprogram;
6856 ----------------------------------
6857 -- Silly_Boolean_Array_Not_Test --
6858 ----------------------------------
6860 -- This procedure implements an odd and silly test. We explicitly check
6861 -- for the case where the 'First of the component type is equal to the
6862 -- 'Last of this component type, and if this is the case, we make sure
6863 -- that constraint error is raised. The reason is that the NOT is bound
6864 -- to cause CE in this case, and we will not otherwise catch it.
6866 -- No such check is required for AND and OR, since for both these cases
6867 -- False op False = False, and True op True = True. For the XOR case,
6868 -- see Silly_Boolean_Array_Xor_Test.
6870 -- Believe it or not, this was reported as a bug. Note that nearly always,
6871 -- the test will evaluate statically to False, so the code will be
6872 -- statically removed, and no extra overhead caused.
6874 procedure Silly_Boolean_Array_Not_Test (N : Node_Id; T : Entity_Id) is
6875 Loc : constant Source_Ptr := Sloc (N);
6876 CT : constant Entity_Id := Component_Type (T);
6879 -- The check we install is
6881 -- constraint_error when
6882 -- component_type'first = component_type'last
6883 -- and then array_type'Length /= 0)
6885 -- We need the last guard because we don't want to raise CE for empty
6886 -- arrays since no out of range values result. (Empty arrays with a
6887 -- component type of True .. True -- very useful -- even the ACATS
6888 -- does not test that marginal case!)
6891 Make_Raise_Constraint_Error (Loc,
6897 Make_Attribute_Reference (Loc,
6898 Prefix => New_Occurrence_Of (CT, Loc),
6899 Attribute_Name => Name_First),
6902 Make_Attribute_Reference (Loc,
6903 Prefix => New_Occurrence_Of (CT, Loc),
6904 Attribute_Name => Name_Last)),
6906 Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
6907 Reason => CE_Range_Check_Failed));
6908 end Silly_Boolean_Array_Not_Test;
6910 ----------------------------------
6911 -- Silly_Boolean_Array_Xor_Test --
6912 ----------------------------------
6914 -- This procedure implements an odd and silly test. We explicitly check
6915 -- for the XOR case where the component type is True .. True, since this
6916 -- will raise constraint error. A special check is required since CE
6917 -- will not be generated otherwise (cf Expand_Packed_Not).
6919 -- No such check is required for AND and OR, since for both these cases
6920 -- False op False = False, and True op True = True, and no check is
6921 -- required for the case of False .. False, since False xor False = False.
6922 -- See also Silly_Boolean_Array_Not_Test
6924 procedure Silly_Boolean_Array_Xor_Test (N : Node_Id; T : Entity_Id) is
6925 Loc : constant Source_Ptr := Sloc (N);
6926 CT : constant Entity_Id := Component_Type (T);
6929 -- The check we install is
6931 -- constraint_error when
6932 -- Boolean (component_type'First)
6933 -- and then Boolean (component_type'Last)
6934 -- and then array_type'Length /= 0)
6936 -- We need the last guard because we don't want to raise CE for empty
6937 -- arrays since no out of range values result (Empty arrays with a
6938 -- component type of True .. True -- very useful -- even the ACATS
6939 -- does not test that marginal case!).
6942 Make_Raise_Constraint_Error (Loc,
6948 Convert_To (Standard_Boolean,
6949 Make_Attribute_Reference (Loc,
6950 Prefix => New_Occurrence_Of (CT, Loc),
6951 Attribute_Name => Name_First)),
6954 Convert_To (Standard_Boolean,
6955 Make_Attribute_Reference (Loc,
6956 Prefix => New_Occurrence_Of (CT, Loc),
6957 Attribute_Name => Name_Last))),
6959 Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
6960 Reason => CE_Range_Check_Failed));
6961 end Silly_Boolean_Array_Xor_Test;
6963 --------------------------
6964 -- Target_Has_Fixed_Ops --
6965 --------------------------
6967 Integer_Sized_Small : Ureal;
6968 -- Set to 2.0 ** -(Integer'Size - 1) the first time that this function is
6969 -- called (we don't want to compute it more than once!)
6971 Long_Integer_Sized_Small : Ureal;
6972 -- Set to 2.0 ** -(Long_Integer'Size - 1) the first time that this function
6973 -- is called (we don't want to compute it more than once)
6975 First_Time_For_THFO : Boolean := True;
6976 -- Set to False after first call (if Fractional_Fixed_Ops_On_Target)
6978 function Target_Has_Fixed_Ops
6979 (Left_Typ : Entity_Id;
6980 Right_Typ : Entity_Id;
6981 Result_Typ : Entity_Id) return Boolean
6983 function Is_Fractional_Type (Typ : Entity_Id) return Boolean;
6984 -- Return True if the given type is a fixed-point type with a small
6985 -- value equal to 2 ** (-(T'Object_Size - 1)) and whose values have
6986 -- an absolute value less than 1.0. This is currently limited to
6987 -- fixed-point types that map to Integer or Long_Integer.
6989 ------------------------
6990 -- Is_Fractional_Type --
6991 ------------------------
6993 function Is_Fractional_Type (Typ : Entity_Id) return Boolean is
6995 if Esize (Typ) = Standard_Integer_Size then
6996 return Small_Value (Typ) = Integer_Sized_Small;
6998 elsif Esize (Typ) = Standard_Long_Integer_Size then
6999 return Small_Value (Typ) = Long_Integer_Sized_Small;
7004 end Is_Fractional_Type;
7006 -- Start of processing for Target_Has_Fixed_Ops
7009 -- Return False if Fractional_Fixed_Ops_On_Target is false
7011 if not Fractional_Fixed_Ops_On_Target then
7015 -- Here the target has Fractional_Fixed_Ops, if first time, compute
7016 -- standard constants used by Is_Fractional_Type.
7018 if First_Time_For_THFO then
7019 First_Time_For_THFO := False;
7021 Integer_Sized_Small :=
7024 Den => UI_From_Int (Standard_Integer_Size - 1),
7027 Long_Integer_Sized_Small :=
7030 Den => UI_From_Int (Standard_Long_Integer_Size - 1),
7034 -- Return True if target supports fixed-by-fixed multiply/divide for
7035 -- fractional fixed-point types (see Is_Fractional_Type) and the operand
7036 -- and result types are equivalent fractional types.
7038 return Is_Fractional_Type (Base_Type (Left_Typ))
7039 and then Is_Fractional_Type (Base_Type (Right_Typ))
7040 and then Is_Fractional_Type (Base_Type (Result_Typ))
7041 and then Esize (Left_Typ) = Esize (Right_Typ)
7042 and then Esize (Left_Typ) = Esize (Result_Typ);
7043 end Target_Has_Fixed_Ops;
7045 ------------------------------------------
7046 -- Type_May_Have_Bit_Aligned_Components --
7047 ------------------------------------------
7049 function Type_May_Have_Bit_Aligned_Components
7050 (Typ : Entity_Id) return Boolean
7053 -- Array type, check component type
7055 if Is_Array_Type (Typ) then
7057 Type_May_Have_Bit_Aligned_Components (Component_Type (Typ));
7059 -- Record type, check components
7061 elsif Is_Record_Type (Typ) then
7066 E := First_Component_Or_Discriminant (Typ);
7067 while Present (E) loop
7068 if Component_May_Be_Bit_Aligned (E)
7069 or else Type_May_Have_Bit_Aligned_Components (Etype (E))
7074 Next_Component_Or_Discriminant (E);
7080 -- Type other than array or record is always OK
7085 end Type_May_Have_Bit_Aligned_Components;
7087 ----------------------------
7088 -- Wrap_Cleanup_Procedure --
7089 ----------------------------
7091 procedure Wrap_Cleanup_Procedure (N : Node_Id) is
7092 Loc : constant Source_Ptr := Sloc (N);
7093 Stseq : constant Node_Id := Handled_Statement_Sequence (N);
7094 Stmts : constant List_Id := Statements (Stseq);
7097 if Abort_Allowed then
7098 Prepend_To (Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
7099 Append_To (Stmts, Build_Runtime_Call (Loc, RE_Abort_Undefer));
7101 end Wrap_Cleanup_Procedure;