1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2003, 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 2, 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 COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 ------------------------------------------------------------------------------
27 with Atree; use Atree;
28 with Checks; use Checks;
29 with Einfo; use Einfo;
30 with Elists; use Elists;
31 with Errout; use Errout;
32 with Exp_Aggr; use Exp_Aggr;
33 with Exp_Ch3; use Exp_Ch3;
34 with Exp_Ch7; use Exp_Ch7;
35 with Exp_Ch9; use Exp_Ch9;
36 with Exp_Disp; use Exp_Disp;
37 with Exp_Fixd; use Exp_Fixd;
38 with Exp_Pakd; use Exp_Pakd;
39 with Exp_Tss; use Exp_Tss;
40 with Exp_Util; use Exp_Util;
41 with Exp_VFpt; use Exp_VFpt;
42 with Hostparm; use Hostparm;
43 with Inline; use Inline;
44 with Nlists; use Nlists;
45 with Nmake; use Nmake;
47 with Rtsfind; use Rtsfind;
49 with Sem_Cat; use Sem_Cat;
50 with Sem_Ch13; use Sem_Ch13;
51 with Sem_Eval; use Sem_Eval;
52 with Sem_Res; use Sem_Res;
53 with Sem_Type; use Sem_Type;
54 with Sem_Util; use Sem_Util;
55 with Sem_Warn; use Sem_Warn;
56 with Sinfo; use Sinfo;
57 with Sinfo.CN; use Sinfo.CN;
58 with Snames; use Snames;
59 with Stand; use Stand;
60 with Targparm; use Targparm;
61 with Tbuild; use Tbuild;
62 with Ttypes; use Ttypes;
63 with Uintp; use Uintp;
64 with Urealp; use Urealp;
65 with Validsw; use Validsw;
67 package body Exp_Ch4 is
69 ------------------------
70 -- Local Subprograms --
71 ------------------------
73 procedure Binary_Op_Validity_Checks (N : Node_Id);
74 pragma Inline (Binary_Op_Validity_Checks);
75 -- Performs validity checks for a binary operator
77 procedure Build_Boolean_Array_Proc_Call
81 -- If an boolean array assignment can be done in place, build call to
82 -- corresponding library procedure.
84 procedure Expand_Allocator_Expression (N : Node_Id);
85 -- Subsidiary to Expand_N_Allocator, for the case when the expression
86 -- is a qualified expression or an aggregate.
88 procedure Expand_Array_Comparison (N : Node_Id);
89 -- This routine handles expansion of the comparison operators (N_Op_Lt,
90 -- N_Op_Le, N_Op_Gt, N_Op_Ge) when operating on an array type. The basic
91 -- code for these operators is similar, differing only in the details of
92 -- the actual comparison call that is made. Special processing (call a
95 function Expand_Array_Equality
103 -- Expand an array equality into a call to a function implementing this
104 -- equality, and a call to it. Loc is the location for the generated
105 -- nodes. Typ is the type of the array, and Lhs, Rhs are the array
106 -- expressions to be compared. A_Typ is the type of the arguments,
107 -- which may be a private type, in which case Typ is its full view.
108 -- Bodies is a list on which to attach bodies of local functions that
109 -- are created in the process. This is the responsibility of the
110 -- caller to insert those bodies at the right place. Nod provides
111 -- the Sloc value for the generated code.
113 procedure Expand_Boolean_Operator (N : Node_Id);
114 -- Common expansion processing for Boolean operators (And, Or, Xor)
115 -- for the case of array type arguments.
117 function Expand_Composite_Equality
124 -- Local recursive function used to expand equality for nested
125 -- composite types. Used by Expand_Record/Array_Equality, Bodies
126 -- is a list on which to attach bodies of local functions that are
127 -- created in the process. This is the responsability of the caller
128 -- to insert those bodies at the right place. Nod provides the Sloc
129 -- value for generated code.
131 procedure Expand_Concatenate_Other (Cnode : Node_Id; Opnds : List_Id);
132 -- This routine handles expansion of concatenation operations, where
133 -- N is the N_Op_Concat node being expanded and Operands is the list
134 -- of operands (at least two are present). The caller has dealt with
135 -- converting any singleton operands into singleton aggregates.
137 procedure Expand_Concatenate_String (Cnode : Node_Id; Opnds : List_Id);
138 -- Routine to expand concatenation of 2-5 operands (in the list Operands)
139 -- and replace node Cnode with the result of the contatenation. If there
140 -- are two operands, they can be string or character. If there are more
141 -- than two operands, then are always of type string (i.e. the caller has
142 -- already converted character operands to strings in this case).
144 procedure Fixup_Universal_Fixed_Operation (N : Node_Id);
145 -- N is either an N_Op_Divide or N_Op_Multiply node whose result is
146 -- universal fixed. We do not have such a type at runtime, so the
147 -- purpose of this routine is to find the real type by looking up
148 -- the tree. We also determine if the operation must be rounded.
150 function Get_Allocator_Final_List
155 -- If the designated type is controlled, build final_list expression
156 -- for created object. If context is an access parameter, create a
157 -- local access type to have a usable finalization list.
159 procedure Insert_Dereference_Action (N : Node_Id);
160 -- N is an expression whose type is an access. When the type is derived
161 -- from Checked_Pool, expands a call to the primitive 'dereference'.
163 function Make_Array_Comparison_Op
167 -- Comparisons between arrays are expanded in line. This function
168 -- produces the body of the implementation of (a > b), where a and b
169 -- are one-dimensional arrays of some discrete type. The original
170 -- node is then expanded into the appropriate call to this function.
171 -- Nod provides the Sloc value for the generated code.
173 function Make_Boolean_Array_Op
177 -- Boolean operations on boolean arrays are expanded in line. This
178 -- function produce the body for the node N, which is (a and b),
179 -- (a or b), or (a xor b). It is used only the normal case and not
180 -- the packed case. The type involved, Typ, is the Boolean array type,
181 -- and the logical operations in the body are simple boolean operations.
182 -- Note that Typ is always a constrained type (the caller has ensured
183 -- this by using Convert_To_Actual_Subtype if necessary).
185 procedure Rewrite_Comparison (N : Node_Id);
186 -- N is the node for a compile time comparison. If this outcome of this
187 -- comparison can be determined at compile time, then the node N can be
188 -- rewritten with True or False. If the outcome cannot be determined at
189 -- compile time, the call has no effect.
191 function Tagged_Membership (N : Node_Id) return Node_Id;
192 -- Construct the expression corresponding to the tagged membership test.
193 -- Deals with a second operand being (or not) a class-wide type.
195 function Safe_In_Place_Array_Op
200 -- In the context of an assignment, where the right-hand side is a
201 -- boolean operation on arrays, check whether operation can be performed
204 procedure Unary_Op_Validity_Checks (N : Node_Id);
205 pragma Inline (Unary_Op_Validity_Checks);
206 -- Performs validity checks for a unary operator
208 -------------------------------
209 -- Binary_Op_Validity_Checks --
210 -------------------------------
212 procedure Binary_Op_Validity_Checks (N : Node_Id) is
214 if Validity_Checks_On and Validity_Check_Operands then
215 Ensure_Valid (Left_Opnd (N));
216 Ensure_Valid (Right_Opnd (N));
218 end Binary_Op_Validity_Checks;
220 ------------------------------------
221 -- Build_Boolean_Array_Proc_Call --
222 ------------------------------------
224 procedure Build_Boolean_Array_Proc_Call
229 Loc : constant Source_Ptr := Sloc (N);
230 Kind : constant Node_Kind := Nkind (Expression (N));
231 Target : constant Node_Id :=
232 Make_Attribute_Reference (Loc,
234 Attribute_Name => Name_Address);
236 Arg1 : constant Node_Id := Op1;
237 Arg2 : Node_Id := Op2;
239 Proc_Name : Entity_Id;
242 if Kind = N_Op_Not then
243 if Nkind (Op1) in N_Binary_Op then
245 -- Use negated version of the binary operators.
247 if Nkind (Op1) = N_Op_And then
248 Proc_Name := RTE (RE_Vector_Nand);
250 elsif Nkind (Op1) = N_Op_Or then
251 Proc_Name := RTE (RE_Vector_Nor);
253 else pragma Assert (Nkind (Op1) = N_Op_Xor);
254 Proc_Name := RTE (RE_Vector_Xor);
258 Make_Procedure_Call_Statement (Loc,
259 Name => New_Occurrence_Of (Proc_Name, Loc),
261 Parameter_Associations => New_List (
263 Make_Attribute_Reference (Loc,
264 Prefix => Left_Opnd (Op1),
265 Attribute_Name => Name_Address),
267 Make_Attribute_Reference (Loc,
268 Prefix => Right_Opnd (Op1),
269 Attribute_Name => Name_Address),
271 Make_Attribute_Reference (Loc,
272 Prefix => Left_Opnd (Op1),
273 Attribute_Name => Name_Length)));
276 Proc_Name := RTE (RE_Vector_Not);
279 Make_Procedure_Call_Statement (Loc,
280 Name => New_Occurrence_Of (Proc_Name, Loc),
281 Parameter_Associations => New_List (
284 Make_Attribute_Reference (Loc,
286 Attribute_Name => Name_Address),
288 Make_Attribute_Reference (Loc,
290 Attribute_Name => Name_Length)));
294 -- We use the following equivalences:
296 -- (not X) or (not Y) = not (X and Y) = Nand (X, Y)
297 -- (not X) and (not Y) = not (X or Y) = Nor (X, Y)
298 -- (not X) xor (not Y) = X xor Y
299 -- X xor (not Y) = not (X xor Y) = Nxor (X, Y)
301 if Nkind (Op1) = N_Op_Not then
302 if Kind = N_Op_And then
303 Proc_Name := RTE (RE_Vector_Nor);
305 elsif Kind = N_Op_Or then
306 Proc_Name := RTE (RE_Vector_Nand);
309 Proc_Name := RTE (RE_Vector_Xor);
313 if Kind = N_Op_And then
314 Proc_Name := RTE (RE_Vector_And);
316 elsif Kind = N_Op_Or then
317 Proc_Name := RTE (RE_Vector_Or);
319 elsif Nkind (Op2) = N_Op_Not then
320 Proc_Name := RTE (RE_Vector_Nxor);
321 Arg2 := Right_Opnd (Op2);
324 Proc_Name := RTE (RE_Vector_Xor);
329 Make_Procedure_Call_Statement (Loc,
330 Name => New_Occurrence_Of (Proc_Name, Loc),
331 Parameter_Associations => New_List (
333 Make_Attribute_Reference (Loc,
335 Attribute_Name => Name_Address),
336 Make_Attribute_Reference (Loc,
338 Attribute_Name => Name_Address),
339 Make_Attribute_Reference (Loc,
341 Attribute_Name => Name_Length)));
344 Rewrite (N, Call_Node);
348 when RE_Not_Available =>
350 end Build_Boolean_Array_Proc_Call;
352 ---------------------------------
353 -- Expand_Allocator_Expression --
354 ---------------------------------
356 procedure Expand_Allocator_Expression (N : Node_Id) is
357 Loc : constant Source_Ptr := Sloc (N);
358 Exp : constant Node_Id := Expression (Expression (N));
359 Indic : constant Node_Id := Subtype_Mark (Expression (N));
360 PtrT : constant Entity_Id := Etype (N);
361 T : constant Entity_Id := Entity (Indic);
366 Aggr_In_Place : constant Boolean := Is_Delayed_Aggregate (Exp);
368 Tag_Assign : Node_Id;
372 if Is_Tagged_Type (T) or else Controlled_Type (T) then
374 -- Actions inserted before:
375 -- Temp : constant ptr_T := new T'(Expression);
376 -- <no CW> Temp._tag := T'tag;
377 -- <CTRL> Adjust (Finalizable (Temp.all));
378 -- <CTRL> Attach_To_Final_List (Finalizable (Temp.all));
380 -- We analyze by hand the new internal allocator to avoid
381 -- any recursion and inappropriate call to Initialize
382 if not Aggr_In_Place then
383 Remove_Side_Effects (Exp);
387 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
389 -- For a class wide allocation generate the following code:
391 -- type Equiv_Record is record ... end record;
392 -- implicit subtype CW is <Class_Wide_Subytpe>;
393 -- temp : PtrT := new CW'(CW!(expr));
395 if Is_Class_Wide_Type (T) then
396 Expand_Subtype_From_Expr (Empty, T, Indic, Exp);
398 Set_Expression (Expression (N),
399 Unchecked_Convert_To (Entity (Indic), Exp));
401 Analyze_And_Resolve (Expression (N), Entity (Indic));
404 if Aggr_In_Place then
406 Make_Object_Declaration (Loc,
407 Defining_Identifier => Temp,
408 Object_Definition => New_Reference_To (PtrT, Loc),
411 New_Reference_To (Etype (Exp), Loc)));
413 Set_Comes_From_Source
414 (Expression (Tmp_Node), Comes_From_Source (N));
416 Set_No_Initialization (Expression (Tmp_Node));
417 Insert_Action (N, Tmp_Node);
419 if Controlled_Type (T)
420 and then Ekind (PtrT) = E_Anonymous_Access_Type
422 -- Create local finalization list for access parameter.
424 Flist := Get_Allocator_Final_List (N, Base_Type (T), PtrT);
427 Convert_Aggr_In_Allocator (Tmp_Node, Exp);
429 Node := Relocate_Node (N);
432 Make_Object_Declaration (Loc,
433 Defining_Identifier => Temp,
434 Constant_Present => True,
435 Object_Definition => New_Reference_To (PtrT, Loc),
436 Expression => Node));
439 -- Suppress the tag assignment when Java_VM because JVM tags
440 -- are represented implicitly in objects.
442 if Is_Tagged_Type (T)
443 and then not Is_Class_Wide_Type (T)
447 Make_Assignment_Statement (Loc,
449 Make_Selected_Component (Loc,
450 Prefix => New_Reference_To (Temp, Loc),
452 New_Reference_To (Tag_Component (T), Loc)),
455 Unchecked_Convert_To (RTE (RE_Tag),
456 New_Reference_To (Access_Disp_Table (T), Loc)));
458 -- The previous assignment has to be done in any case
460 Set_Assignment_OK (Name (Tag_Assign));
461 Insert_Action (N, Tag_Assign);
463 elsif Is_Private_Type (T)
464 and then Is_Tagged_Type (Underlying_Type (T))
468 Utyp : constant Entity_Id := Underlying_Type (T);
469 Ref : constant Node_Id :=
470 Unchecked_Convert_To (Utyp,
471 Make_Explicit_Dereference (Loc,
472 New_Reference_To (Temp, Loc)));
476 Make_Assignment_Statement (Loc,
478 Make_Selected_Component (Loc,
481 New_Reference_To (Tag_Component (Utyp), Loc)),
484 Unchecked_Convert_To (RTE (RE_Tag),
486 Access_Disp_Table (Utyp), Loc)));
488 Set_Assignment_OK (Name (Tag_Assign));
489 Insert_Action (N, Tag_Assign);
493 if Controlled_Type (Designated_Type (PtrT))
494 and then Controlled_Type (T)
498 Apool : constant Entity_Id :=
499 Associated_Storage_Pool (PtrT);
502 -- If it is an allocation on the secondary stack
503 -- (i.e. a value returned from a function), the object
504 -- is attached on the caller side as soon as the call
505 -- is completed (see Expand_Ctrl_Function_Call)
507 if Is_RTE (Apool, RE_SS_Pool) then
509 F : constant Entity_Id :=
510 Make_Defining_Identifier (Loc,
511 New_Internal_Name ('F'));
514 Make_Object_Declaration (Loc,
515 Defining_Identifier => F,
516 Object_Definition => New_Reference_To (RTE
517 (RE_Finalizable_Ptr), Loc)));
519 Flist := New_Reference_To (F, Loc);
520 Attach := Make_Integer_Literal (Loc, 1);
523 -- Normal case, not a secondary stack allocation
526 Flist := Find_Final_List (PtrT);
527 Attach := Make_Integer_Literal (Loc, 2);
530 if not Aggr_In_Place then
535 -- An unchecked conversion is needed in the
536 -- classwide case because the designated type
537 -- can be an ancestor of the subtype mark of
540 Unchecked_Convert_To (T,
541 Make_Explicit_Dereference (Loc,
542 New_Reference_To (Temp, Loc))),
546 With_Attach => Attach));
551 Rewrite (N, New_Reference_To (Temp, Loc));
552 Analyze_And_Resolve (N, PtrT);
554 elsif Aggr_In_Place then
556 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
558 Make_Object_Declaration (Loc,
559 Defining_Identifier => Temp,
560 Object_Definition => New_Reference_To (PtrT, Loc),
561 Expression => Make_Allocator (Loc,
562 New_Reference_To (Etype (Exp), Loc)));
564 Set_Comes_From_Source
565 (Expression (Tmp_Node), Comes_From_Source (N));
567 Set_No_Initialization (Expression (Tmp_Node));
568 Insert_Action (N, Tmp_Node);
569 Convert_Aggr_In_Allocator (Tmp_Node, Exp);
570 Rewrite (N, New_Reference_To (Temp, Loc));
571 Analyze_And_Resolve (N, PtrT);
573 elsif Is_Access_Type (Designated_Type (PtrT))
574 and then Nkind (Exp) = N_Allocator
575 and then Nkind (Expression (Exp)) /= N_Qualified_Expression
577 -- Apply constraint to designated subtype indication.
579 Apply_Constraint_Check (Expression (Exp),
580 Designated_Type (Designated_Type (PtrT)),
583 if Nkind (Expression (Exp)) = N_Raise_Constraint_Error then
585 -- Propagate constraint_error to enclosing allocator
587 Rewrite (Exp, New_Copy (Expression (Exp)));
590 -- First check against the type of the qualified expression
592 -- NOTE: The commented call should be correct, but for
593 -- some reason causes the compiler to bomb (sigsegv) on
594 -- ACVC test c34007g, so for now we just perform the old
595 -- (incorrect) test against the designated subtype with
596 -- no sliding in the else part of the if statement below.
599 -- Apply_Constraint_Check (Exp, T, No_Sliding => True);
601 -- A check is also needed in cases where the designated
602 -- subtype is constrained and differs from the subtype
603 -- given in the qualified expression. Note that the check
604 -- on the qualified expression does not allow sliding,
605 -- but this check does (a relaxation from Ada 83).
607 if Is_Constrained (Designated_Type (PtrT))
608 and then not Subtypes_Statically_Match
609 (T, Designated_Type (PtrT))
611 Apply_Constraint_Check
612 (Exp, Designated_Type (PtrT), No_Sliding => False);
614 -- The nonsliding check should really be performed
615 -- (unconditionally) against the subtype of the
616 -- qualified expression, but that causes a problem
617 -- with c34007g (see above), so for now we retain this.
620 Apply_Constraint_Check
621 (Exp, Designated_Type (PtrT), No_Sliding => True);
626 when RE_Not_Available =>
628 end Expand_Allocator_Expression;
630 -----------------------------
631 -- Expand_Array_Comparison --
632 -----------------------------
634 -- Expansion is only required in the case of array types. For the
635 -- unpacked case, an appropriate runtime routine is called. For
636 -- packed cases, and also in some other cases where a runtime
637 -- routine cannot be called, the form of the expansion is:
639 -- [body for greater_nn; boolean_expression]
641 -- The body is built by Make_Array_Comparison_Op, and the form of the
642 -- Boolean expression depends on the operator involved.
644 procedure Expand_Array_Comparison (N : Node_Id) is
645 Loc : constant Source_Ptr := Sloc (N);
646 Op1 : Node_Id := Left_Opnd (N);
647 Op2 : Node_Id := Right_Opnd (N);
648 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
649 Ctyp : constant Entity_Id := Component_Type (Typ1);
653 Func_Name : Entity_Id;
657 function Length_Less_Than_4 (Opnd : Node_Id) return Boolean;
658 -- Returns True if the length of the given operand is known to be
659 -- less than 4. Returns False if this length is known to be four
660 -- or greater or is not known at compile time.
662 ------------------------
663 -- Length_Less_Than_4 --
664 ------------------------
666 function Length_Less_Than_4 (Opnd : Node_Id) return Boolean is
667 Otyp : constant Entity_Id := Etype (Opnd);
670 if Ekind (Otyp) = E_String_Literal_Subtype then
671 return String_Literal_Length (Otyp) < 4;
675 Ityp : constant Entity_Id := Etype (First_Index (Otyp));
676 Lo : constant Node_Id := Type_Low_Bound (Ityp);
677 Hi : constant Node_Id := Type_High_Bound (Ityp);
682 if Compile_Time_Known_Value (Lo) then
683 Lov := Expr_Value (Lo);
688 if Compile_Time_Known_Value (Hi) then
689 Hiv := Expr_Value (Hi);
694 return Hiv < Lov + 3;
697 end Length_Less_Than_4;
699 -- Start of processing for Expand_Array_Comparison
702 -- Deal first with unpacked case, where we can call a runtime routine
703 -- except that we avoid this for targets for which are not addressable
704 -- by bytes, and for the JVM, since the JVM does not support direct
705 -- addressing of array components.
707 if not Is_Bit_Packed_Array (Typ1)
708 and then System_Storage_Unit = Byte'Size
711 -- The call we generate is:
713 -- Compare_Array_xn[_Unaligned]
714 -- (left'address, right'address, left'length, right'length) <op> 0
716 -- x = U for unsigned, S for signed
717 -- n = 8,16,32,64 for component size
718 -- Add _Unaligned if length < 4 and component size is 8.
719 -- <op> is the standard comparison operator
721 if Component_Size (Typ1) = 8 then
722 if Length_Less_Than_4 (Op1)
724 Length_Less_Than_4 (Op2)
726 if Is_Unsigned_Type (Ctyp) then
727 Comp := RE_Compare_Array_U8_Unaligned;
729 Comp := RE_Compare_Array_S8_Unaligned;
733 if Is_Unsigned_Type (Ctyp) then
734 Comp := RE_Compare_Array_U8;
736 Comp := RE_Compare_Array_S8;
740 elsif Component_Size (Typ1) = 16 then
741 if Is_Unsigned_Type (Ctyp) then
742 Comp := RE_Compare_Array_U16;
744 Comp := RE_Compare_Array_S16;
747 elsif Component_Size (Typ1) = 32 then
748 if Is_Unsigned_Type (Ctyp) then
749 Comp := RE_Compare_Array_U32;
751 Comp := RE_Compare_Array_S32;
754 else pragma Assert (Component_Size (Typ1) = 64);
755 if Is_Unsigned_Type (Ctyp) then
756 Comp := RE_Compare_Array_U64;
758 Comp := RE_Compare_Array_S64;
762 Remove_Side_Effects (Op1, Name_Req => True);
763 Remove_Side_Effects (Op2, Name_Req => True);
766 Make_Function_Call (Sloc (Op1),
767 Name => New_Occurrence_Of (RTE (Comp), Loc),
769 Parameter_Associations => New_List (
770 Make_Attribute_Reference (Loc,
771 Prefix => Relocate_Node (Op1),
772 Attribute_Name => Name_Address),
774 Make_Attribute_Reference (Loc,
775 Prefix => Relocate_Node (Op2),
776 Attribute_Name => Name_Address),
778 Make_Attribute_Reference (Loc,
779 Prefix => Relocate_Node (Op1),
780 Attribute_Name => Name_Length),
782 Make_Attribute_Reference (Loc,
783 Prefix => Relocate_Node (Op2),
784 Attribute_Name => Name_Length))));
787 Make_Integer_Literal (Sloc (Op2),
790 Analyze_And_Resolve (Op1, Standard_Integer);
791 Analyze_And_Resolve (Op2, Standard_Integer);
795 -- Cases where we cannot make runtime call
797 -- For (a <= b) we convert to not (a > b)
799 if Chars (N) = Name_Op_Le then
805 Right_Opnd => Op2)));
806 Analyze_And_Resolve (N, Standard_Boolean);
809 -- For < the Boolean expression is
810 -- greater__nn (op2, op1)
812 elsif Chars (N) = Name_Op_Lt then
813 Func_Body := Make_Array_Comparison_Op (Typ1, N);
817 Op1 := Right_Opnd (N);
818 Op2 := Left_Opnd (N);
820 -- For (a >= b) we convert to not (a < b)
822 elsif Chars (N) = Name_Op_Ge then
828 Right_Opnd => Op2)));
829 Analyze_And_Resolve (N, Standard_Boolean);
832 -- For > the Boolean expression is
833 -- greater__nn (op1, op2)
836 pragma Assert (Chars (N) = Name_Op_Gt);
837 Func_Body := Make_Array_Comparison_Op (Typ1, N);
840 Func_Name := Defining_Unit_Name (Specification (Func_Body));
842 Make_Function_Call (Loc,
843 Name => New_Reference_To (Func_Name, Loc),
844 Parameter_Associations => New_List (Op1, Op2));
846 Insert_Action (N, Func_Body);
848 Analyze_And_Resolve (N, Standard_Boolean);
851 when RE_Not_Available =>
853 end Expand_Array_Comparison;
855 ---------------------------
856 -- Expand_Array_Equality --
857 ---------------------------
859 -- Expand an equality function for multi-dimensional arrays. Here is
860 -- an example of such a function for Nb_Dimension = 2
862 -- function Enn (A : arr; B : arr) return boolean is
864 -- if (A'length (1) = 0 or else A'length (2) = 0)
866 -- (B'length (1) = 0 or else B'length (2) = 0)
868 -- return True; -- RM 4.5.2(22)
871 -- if A'length (1) /= B'length (1)
873 -- A'length (2) /= B'length (2)
875 -- return False; -- RM 4.5.2(23)
879 -- A1 : Index_type_1 := A'first (1)
880 -- B1 : Index_Type_1 := B'first (1)
884 -- A2 : Index_type_2 := A'first (2);
885 -- B2 : Index_type_2 := B'first (2)
888 -- if A (A1, A2) /= B (B1, B2) then
892 -- exit when A2 = A'last (2);
893 -- A2 := Index_type2'succ (A2);
894 -- B2 := Index_type2'succ (B2);
898 -- exit when A1 = A'last (1);
899 -- A1 := Index_type1'succ (A1);
900 -- B1 := Index_type1'succ (B1);
907 function Expand_Array_Equality
916 Loc : constant Source_Ptr := Sloc (Nod);
917 Decls : constant List_Id := New_List;
918 Index_List1 : constant List_Id := New_List;
919 Index_List2 : constant List_Id := New_List;
923 Func_Name : Entity_Id;
926 A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
927 B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
934 -- This builds the attribute reference Arr'Nam (Expr).
936 function Component_Equality (Typ : Entity_Id) return Node_Id;
937 -- Create one statement to compare corresponding components,
938 -- designated by a full set of indices.
940 function Handle_One_Dimension
944 -- This procedure returns a declare block:
947 -- An : Index_Type_n := A'First (n);
948 -- Bn : Index_Type_n := B'First (n);
952 -- exit when An = A'Last (n);
953 -- An := Index_Type_n'Succ (An)
954 -- Bn := Index_Type_n'Succ (Bn)
958 -- where N is the value of "n" in the above code. Index is the
959 -- N'th index node, whose Etype is Index_Type_n in the above code.
960 -- The xxx statement is either the declare block for the next
961 -- dimension or if this is the last dimension the comparison
962 -- of corresponding components of the arrays.
964 -- The actual way the code works is to return the comparison
965 -- of corresponding components for the N+1 call. That's neater!
967 function Test_Empty_Arrays return Node_Id;
968 -- This function constructs the test for both arrays being empty
969 -- (A'length (1) = 0 or else A'length (2) = 0 or else ...)
971 -- (B'length (1) = 0 or else B'length (2) = 0 or else ...)
973 function Test_Lengths_Correspond return Node_Id;
974 -- This function constructs the test for arrays having different
975 -- lengths in at least one index position, in which case resull
977 -- A'length (1) /= B'length (1)
979 -- A'length (2) /= B'length (2)
995 Make_Attribute_Reference (Loc,
996 Attribute_Name => Nam,
997 Prefix => New_Reference_To (Arr, Loc),
998 Expressions => New_List (Make_Integer_Literal (Loc, Num)));
1001 ------------------------
1002 -- Component_Equality --
1003 ------------------------
1005 function Component_Equality (Typ : Entity_Id) return Node_Id is
1010 -- if a(i1...) /= b(j1...) then return false; end if;
1013 Make_Indexed_Component (Loc,
1014 Prefix => Make_Identifier (Loc, Chars (A)),
1015 Expressions => Index_List1);
1018 Make_Indexed_Component (Loc,
1019 Prefix => Make_Identifier (Loc, Chars (B)),
1020 Expressions => Index_List2);
1022 Test := Expand_Composite_Equality
1023 (Nod, Component_Type (Typ), L, R, Decls);
1026 Make_Implicit_If_Statement (Nod,
1027 Condition => Make_Op_Not (Loc, Right_Opnd => Test),
1028 Then_Statements => New_List (
1029 Make_Return_Statement (Loc,
1030 Expression => New_Occurrence_Of (Standard_False, Loc))));
1031 end Component_Equality;
1033 --------------------------
1034 -- Handle_One_Dimension --
1035 ---------------------------
1037 function Handle_One_Dimension
1042 An : constant Entity_Id := Make_Defining_Identifier (Loc,
1043 Chars => New_Internal_Name ('A'));
1044 Bn : constant Entity_Id := Make_Defining_Identifier (Loc,
1045 Chars => New_Internal_Name ('B'));
1046 Index_Type_n : Entity_Id;
1049 if N > Number_Dimensions (Typ) then
1050 return Component_Equality (Typ);
1053 -- Case where we generate a declare block
1055 Index_Type_n := Base_Type (Etype (Index));
1056 Append (New_Reference_To (An, Loc), Index_List1);
1057 Append (New_Reference_To (Bn, Loc), Index_List2);
1060 Make_Block_Statement (Loc,
1061 Declarations => New_List (
1062 Make_Object_Declaration (Loc,
1063 Defining_Identifier => An,
1064 Object_Definition =>
1065 New_Reference_To (Index_Type_n, Loc),
1066 Expression => Arr_Attr (A, Name_First, N)),
1068 Make_Object_Declaration (Loc,
1069 Defining_Identifier => Bn,
1070 Object_Definition =>
1071 New_Reference_To (Index_Type_n, Loc),
1072 Expression => Arr_Attr (B, Name_First, N))),
1074 Handled_Statement_Sequence =>
1075 Make_Handled_Sequence_Of_Statements (Loc,
1076 Statements => New_List (
1077 Make_Implicit_Loop_Statement (Nod,
1078 Statements => New_List (
1079 Handle_One_Dimension (N + 1, Next_Index (Index)),
1081 Make_Exit_Statement (Loc,
1084 Left_Opnd => New_Reference_To (An, Loc),
1085 Right_Opnd => Arr_Attr (A, Name_Last, N))),
1087 Make_Assignment_Statement (Loc,
1088 Name => New_Reference_To (An, Loc),
1090 Make_Attribute_Reference (Loc,
1092 New_Reference_To (Index_Type_n, Loc),
1093 Attribute_Name => Name_Succ,
1094 Expressions => New_List (
1095 New_Reference_To (An, Loc)))),
1097 Make_Assignment_Statement (Loc,
1098 Name => New_Reference_To (Bn, Loc),
1100 Make_Attribute_Reference (Loc,
1102 New_Reference_To (Index_Type_n, Loc),
1103 Attribute_Name => Name_Succ,
1104 Expressions => New_List (
1105 New_Reference_To (Bn, Loc)))))))));
1106 end Handle_One_Dimension;
1108 -----------------------
1109 -- Test_Empty_Arrays --
1110 -----------------------
1112 function Test_Empty_Arrays return Node_Id is
1122 for J in 1 .. Number_Dimensions (Typ) loop
1125 Left_Opnd => Arr_Attr (A, Name_Length, J),
1126 Right_Opnd => Make_Integer_Literal (Loc, 0));
1130 Left_Opnd => Arr_Attr (B, Name_Length, J),
1131 Right_Opnd => Make_Integer_Literal (Loc, 0));
1140 Left_Opnd => Relocate_Node (Alist),
1141 Right_Opnd => Atest);
1145 Left_Opnd => Relocate_Node (Blist),
1146 Right_Opnd => Btest);
1153 Right_Opnd => Blist);
1154 end Test_Empty_Arrays;
1156 -----------------------------
1157 -- Test_Lengths_Correspond --
1158 -----------------------------
1160 function Test_Lengths_Correspond return Node_Id is
1166 for J in 1 .. Number_Dimensions (Typ) loop
1169 Left_Opnd => Arr_Attr (A, Name_Length, J),
1170 Right_Opnd => Arr_Attr (B, Name_Length, J));
1177 Left_Opnd => Relocate_Node (Result),
1178 Right_Opnd => Rtest);
1183 end Test_Lengths_Correspond;
1185 -- Start of processing for Expand_Array_Equality
1188 Formals := New_List (
1189 Make_Parameter_Specification (Loc,
1190 Defining_Identifier => A,
1191 Parameter_Type => New_Reference_To (Typ, Loc)),
1193 Make_Parameter_Specification (Loc,
1194 Defining_Identifier => B,
1195 Parameter_Type => New_Reference_To (Typ, Loc)));
1197 Func_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
1199 -- Build statement sequence for function
1202 Make_Subprogram_Body (Loc,
1204 Make_Function_Specification (Loc,
1205 Defining_Unit_Name => Func_Name,
1206 Parameter_Specifications => Formals,
1207 Subtype_Mark => New_Reference_To (Standard_Boolean, Loc)),
1209 Declarations => Decls,
1211 Handled_Statement_Sequence =>
1212 Make_Handled_Sequence_Of_Statements (Loc,
1213 Statements => New_List (
1215 Make_Implicit_If_Statement (Nod,
1216 Condition => Test_Empty_Arrays,
1217 Then_Statements => New_List (
1218 Make_Return_Statement (Loc,
1220 New_Occurrence_Of (Standard_True, Loc)))),
1222 Make_Implicit_If_Statement (Nod,
1223 Condition => Test_Lengths_Correspond,
1224 Then_Statements => New_List (
1225 Make_Return_Statement (Loc,
1227 New_Occurrence_Of (Standard_False, Loc)))),
1229 Handle_One_Dimension (1, First_Index (Typ)),
1231 Make_Return_Statement (Loc,
1232 Expression => New_Occurrence_Of (Standard_True, Loc)))));
1234 Set_Has_Completion (Func_Name, True);
1236 -- If the array type is distinct from the type of the arguments,
1237 -- it is the full view of a private type. Apply an unchecked
1238 -- conversion to insure that analysis of the call succeeds.
1240 if Base_Type (A_Typ) /= Base_Type (Typ) then
1241 Actuals := New_List (
1242 OK_Convert_To (Typ, Lhs),
1243 OK_Convert_To (Typ, Rhs));
1245 Actuals := New_List (Lhs, Rhs);
1248 Append_To (Bodies, Func_Body);
1251 Make_Function_Call (Loc,
1252 Name => New_Reference_To (Func_Name, Loc),
1253 Parameter_Associations => Actuals);
1254 end Expand_Array_Equality;
1256 -----------------------------
1257 -- Expand_Boolean_Operator --
1258 -----------------------------
1260 -- Note that we first get the actual subtypes of the operands,
1261 -- since we always want to deal with types that have bounds.
1263 procedure Expand_Boolean_Operator (N : Node_Id) is
1264 Typ : constant Entity_Id := Etype (N);
1267 if Is_Bit_Packed_Array (Typ) then
1268 Expand_Packed_Boolean_Operator (N);
1271 -- For the normal non-packed case, the general expansion is
1272 -- to build a function for carrying out the comparison (using
1273 -- Make_Boolean_Array_Op) and then inserting it into the tree.
1274 -- The original operator node is then rewritten as a call to
1278 Loc : constant Source_Ptr := Sloc (N);
1279 L : constant Node_Id := Relocate_Node (Left_Opnd (N));
1280 R : constant Node_Id := Relocate_Node (Right_Opnd (N));
1281 Func_Body : Node_Id;
1282 Func_Name : Entity_Id;
1285 Convert_To_Actual_Subtype (L);
1286 Convert_To_Actual_Subtype (R);
1287 Ensure_Defined (Etype (L), N);
1288 Ensure_Defined (Etype (R), N);
1289 Apply_Length_Check (R, Etype (L));
1291 if Nkind (Parent (N)) = N_Assignment_Statement
1292 and then Safe_In_Place_Array_Op (Name (Parent (N)), L, R)
1294 Build_Boolean_Array_Proc_Call (Parent (N), L, R);
1296 elsif Nkind (Parent (N)) = N_Op_Not
1297 and then Nkind (N) = N_Op_And
1299 Safe_In_Place_Array_Op (Name (Parent (Parent (N))), L, R)
1304 Func_Body := Make_Boolean_Array_Op (Etype (L), N);
1305 Func_Name := Defining_Unit_Name (Specification (Func_Body));
1306 Insert_Action (N, Func_Body);
1308 -- Now rewrite the expression with a call
1311 Make_Function_Call (Loc,
1312 Name => New_Reference_To (Func_Name, Loc),
1313 Parameter_Associations =>
1315 (L, Make_Type_Conversion
1316 (Loc, New_Reference_To (Etype (L), Loc), R))));
1318 Analyze_And_Resolve (N, Typ);
1322 end Expand_Boolean_Operator;
1324 -------------------------------
1325 -- Expand_Composite_Equality --
1326 -------------------------------
1328 -- This function is only called for comparing internal fields of composite
1329 -- types when these fields are themselves composites. This is a special
1330 -- case because it is not possible to respect normal Ada visibility rules.
1332 function Expand_Composite_Equality
1340 Loc : constant Source_Ptr := Sloc (Nod);
1341 Full_Type : Entity_Id;
1346 if Is_Private_Type (Typ) then
1347 Full_Type := Underlying_Type (Typ);
1352 -- Defense against malformed private types with no completion
1353 -- the error will be diagnosed later by check_completion
1355 if No (Full_Type) then
1356 return New_Reference_To (Standard_False, Loc);
1359 Full_Type := Base_Type (Full_Type);
1361 if Is_Array_Type (Full_Type) then
1363 -- If the operand is an elementary type other than a floating-point
1364 -- type, then we can simply use the built-in block bitwise equality,
1365 -- since the predefined equality operators always apply and bitwise
1366 -- equality is fine for all these cases.
1368 if Is_Elementary_Type (Component_Type (Full_Type))
1369 and then not Is_Floating_Point_Type (Component_Type (Full_Type))
1371 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
1373 -- For composite component types, and floating-point types, use
1374 -- the expansion. This deals with tagged component types (where
1375 -- we use the applicable equality routine) and floating-point,
1376 -- (where we need to worry about negative zeroes), and also the
1377 -- case of any composite type recursively containing such fields.
1380 return Expand_Array_Equality
1381 (Nod, Full_Type, Typ, Lhs, Rhs, Bodies);
1384 elsif Is_Tagged_Type (Full_Type) then
1386 -- Call the primitive operation "=" of this type
1388 if Is_Class_Wide_Type (Full_Type) then
1389 Full_Type := Root_Type (Full_Type);
1392 -- If this is derived from an untagged private type completed
1393 -- with a tagged type, it does not have a full view, so we
1394 -- use the primitive operations of the private type.
1395 -- This check should no longer be necessary when these
1396 -- types receive their full views ???
1398 if Is_Private_Type (Typ)
1399 and then not Is_Tagged_Type (Typ)
1400 and then not Is_Controlled (Typ)
1401 and then Is_Derived_Type (Typ)
1402 and then No (Full_View (Typ))
1404 Prim := First_Elmt (Collect_Primitive_Operations (Typ));
1406 Prim := First_Elmt (Primitive_Operations (Full_Type));
1410 Eq_Op := Node (Prim);
1411 exit when Chars (Eq_Op) = Name_Op_Eq
1412 and then Etype (First_Formal (Eq_Op)) =
1413 Etype (Next_Formal (First_Formal (Eq_Op)));
1415 pragma Assert (Present (Prim));
1418 Eq_Op := Node (Prim);
1421 Make_Function_Call (Loc,
1422 Name => New_Reference_To (Eq_Op, Loc),
1423 Parameter_Associations =>
1425 (Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Lhs),
1426 Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Rhs)));
1428 elsif Is_Record_Type (Full_Type) then
1429 Eq_Op := TSS (Full_Type, TSS_Composite_Equality);
1431 if Present (Eq_Op) then
1432 if Etype (First_Formal (Eq_Op)) /= Full_Type then
1434 -- Inherited equality from parent type. Convert the actuals
1435 -- to match signature of operation.
1438 T : constant Entity_Id := Etype (First_Formal (Eq_Op));
1442 Make_Function_Call (Loc,
1443 Name => New_Reference_To (Eq_Op, Loc),
1444 Parameter_Associations =>
1445 New_List (OK_Convert_To (T, Lhs),
1446 OK_Convert_To (T, Rhs)));
1451 Make_Function_Call (Loc,
1452 Name => New_Reference_To (Eq_Op, Loc),
1453 Parameter_Associations => New_List (Lhs, Rhs));
1457 return Expand_Record_Equality (Nod, Full_Type, Lhs, Rhs, Bodies);
1461 -- It can be a simple record or the full view of a scalar private
1463 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
1465 end Expand_Composite_Equality;
1467 ------------------------------
1468 -- Expand_Concatenate_Other --
1469 ------------------------------
1471 -- Let n be the number of array operands to be concatenated, Base_Typ
1472 -- their base type, Ind_Typ their index type, and Arr_Typ the original
1473 -- array type to which the concatenantion operator applies, then the
1474 -- following subprogram is constructed:
1476 -- [function Cnn (S1 : Base_Typ; ...; Sn : Base_Typ) return Base_Typ is
1479 -- if S1'Length /= 0 then
1480 -- L := XXX; --> XXX = S1'First if Arr_Typ is unconstrained
1481 -- XXX = Arr_Typ'First otherwise
1482 -- elsif S2'Length /= 0 then
1483 -- L := YYY; --> YYY = S2'First if Arr_Typ is unconstrained
1484 -- YYY = Arr_Typ'First otherwise
1486 -- elsif Sn-1'Length /= 0 then
1487 -- L := ZZZ; --> ZZZ = Sn-1'First if Arr_Typ is unconstrained
1488 -- ZZZ = Arr_Typ'First otherwise
1496 -- Ind_Typ'Val ((((S1'Length - 1) + S2'Length) + ... + Sn'Length)
1497 -- + Ind_Typ'Pos (L));
1498 -- R : Base_Typ (L .. H);
1500 -- if S1'Length /= 0 then
1504 -- L := Ind_Typ'Succ (L);
1505 -- exit when P = S1'Last;
1506 -- P := Ind_Typ'Succ (P);
1510 -- if S2'Length /= 0 then
1511 -- L := Ind_Typ'Succ (L);
1514 -- L := Ind_Typ'Succ (L);
1515 -- exit when P = S2'Last;
1516 -- P := Ind_Typ'Succ (P);
1522 -- if Sn'Length /= 0 then
1526 -- L := Ind_Typ'Succ (L);
1527 -- exit when P = Sn'Last;
1528 -- P := Ind_Typ'Succ (P);
1536 procedure Expand_Concatenate_Other (Cnode : Node_Id; Opnds : List_Id) is
1537 Loc : constant Source_Ptr := Sloc (Cnode);
1538 Nb_Opnds : constant Nat := List_Length (Opnds);
1540 Arr_Typ : constant Entity_Id := Etype (Entity (Cnode));
1541 Base_Typ : constant Entity_Id := Base_Type (Etype (Cnode));
1542 Ind_Typ : constant Entity_Id := Etype (First_Index (Base_Typ));
1545 Func_Spec : Node_Id;
1546 Param_Specs : List_Id;
1548 Func_Body : Node_Id;
1549 Func_Decls : List_Id;
1550 Func_Stmts : List_Id;
1555 Elsif_List : List_Id;
1557 Declare_Block : Node_Id;
1558 Declare_Decls : List_Id;
1559 Declare_Stmts : List_Id;
1571 function Copy_Into_R_S (I : Nat; Last : Boolean) return List_Id;
1572 -- Builds the sequence of statement:
1576 -- L := Ind_Typ'Succ (L);
1577 -- exit when P = Si'Last;
1578 -- P := Ind_Typ'Succ (P);
1581 -- where i is the input parameter I given.
1582 -- If the flag Last is true, the exit statement is emitted before
1583 -- incrementing the lower bound, to prevent the creation out of
1586 function Init_L (I : Nat) return Node_Id;
1587 -- Builds the statement:
1588 -- L := Arr_Typ'First; If Arr_Typ is constrained
1589 -- L := Si'First; otherwise (where I is the input param given)
1591 function H return Node_Id;
1592 -- Builds reference to identifier H.
1594 function Ind_Val (E : Node_Id) return Node_Id;
1595 -- Builds expression Ind_Typ'Val (E);
1597 function L return Node_Id;
1598 -- Builds reference to identifier L.
1600 function L_Pos return Node_Id;
1601 -- Builds expression Ind_Typ'Pos (L).
1603 function L_Succ return Node_Id;
1604 -- Builds expression Ind_Typ'Succ (L).
1606 function One return Node_Id;
1607 -- Builds integer literal one.
1609 function P return Node_Id;
1610 -- Builds reference to identifier P.
1612 function P_Succ return Node_Id;
1613 -- Builds expression Ind_Typ'Succ (P).
1615 function R return Node_Id;
1616 -- Builds reference to identifier R.
1618 function S (I : Nat) return Node_Id;
1619 -- Builds reference to identifier Si, where I is the value given.
1621 function S_First (I : Nat) return Node_Id;
1622 -- Builds expression Si'First, where I is the value given.
1624 function S_Last (I : Nat) return Node_Id;
1625 -- Builds expression Si'Last, where I is the value given.
1627 function S_Length (I : Nat) return Node_Id;
1628 -- Builds expression Si'Length, where I is the value given.
1630 function S_Length_Test (I : Nat) return Node_Id;
1631 -- Builds expression Si'Length /= 0, where I is the value given.
1637 function Copy_Into_R_S (I : Nat; Last : Boolean) return List_Id is
1638 Stmts : constant List_Id := New_List;
1640 Loop_Stmt : Node_Id;
1642 Exit_Stmt : Node_Id;
1647 -- First construct the initializations
1649 P_Start := Make_Assignment_Statement (Loc,
1651 Expression => S_First (I));
1652 Append_To (Stmts, P_Start);
1654 -- Then build the loop
1656 R_Copy := Make_Assignment_Statement (Loc,
1657 Name => Make_Indexed_Component (Loc,
1659 Expressions => New_List (L)),
1660 Expression => Make_Indexed_Component (Loc,
1662 Expressions => New_List (P)));
1664 L_Inc := Make_Assignment_Statement (Loc,
1666 Expression => L_Succ);
1668 Exit_Stmt := Make_Exit_Statement (Loc,
1669 Condition => Make_Op_Eq (Loc, P, S_Last (I)));
1671 P_Inc := Make_Assignment_Statement (Loc,
1673 Expression => P_Succ);
1677 Make_Implicit_Loop_Statement (Cnode,
1678 Statements => New_List (R_Copy, Exit_Stmt, L_Inc, P_Inc));
1681 Make_Implicit_Loop_Statement (Cnode,
1682 Statements => New_List (R_Copy, L_Inc, Exit_Stmt, P_Inc));
1685 Append_To (Stmts, Loop_Stmt);
1694 function H return Node_Id is
1696 return Make_Identifier (Loc, Name_uH);
1703 function Ind_Val (E : Node_Id) return Node_Id is
1706 Make_Attribute_Reference (Loc,
1707 Prefix => New_Reference_To (Ind_Typ, Loc),
1708 Attribute_Name => Name_Val,
1709 Expressions => New_List (E));
1716 function Init_L (I : Nat) return Node_Id is
1720 if Is_Constrained (Arr_Typ) then
1721 E := Make_Attribute_Reference (Loc,
1722 Prefix => New_Reference_To (Arr_Typ, Loc),
1723 Attribute_Name => Name_First);
1729 return Make_Assignment_Statement (Loc, Name => L, Expression => E);
1736 function L return Node_Id is
1738 return Make_Identifier (Loc, Name_uL);
1745 function L_Pos return Node_Id is
1748 Make_Attribute_Reference (Loc,
1749 Prefix => New_Reference_To (Ind_Typ, Loc),
1750 Attribute_Name => Name_Pos,
1751 Expressions => New_List (L));
1758 function L_Succ return Node_Id is
1761 Make_Attribute_Reference (Loc,
1762 Prefix => New_Reference_To (Ind_Typ, Loc),
1763 Attribute_Name => Name_Succ,
1764 Expressions => New_List (L));
1771 function One return Node_Id is
1773 return Make_Integer_Literal (Loc, 1);
1780 function P return Node_Id is
1782 return Make_Identifier (Loc, Name_uP);
1789 function P_Succ return Node_Id is
1792 Make_Attribute_Reference (Loc,
1793 Prefix => New_Reference_To (Ind_Typ, Loc),
1794 Attribute_Name => Name_Succ,
1795 Expressions => New_List (P));
1802 function R return Node_Id is
1804 return Make_Identifier (Loc, Name_uR);
1811 function S (I : Nat) return Node_Id is
1813 return Make_Identifier (Loc, New_External_Name ('S', I));
1820 function S_First (I : Nat) return Node_Id is
1822 return Make_Attribute_Reference (Loc,
1824 Attribute_Name => Name_First);
1831 function S_Last (I : Nat) return Node_Id is
1833 return Make_Attribute_Reference (Loc,
1835 Attribute_Name => Name_Last);
1842 function S_Length (I : Nat) return Node_Id is
1844 return Make_Attribute_Reference (Loc,
1846 Attribute_Name => Name_Length);
1853 function S_Length_Test (I : Nat) return Node_Id is
1857 Left_Opnd => S_Length (I),
1858 Right_Opnd => Make_Integer_Literal (Loc, 0));
1861 -- Start of processing for Expand_Concatenate_Other
1864 -- Construct the parameter specs and the overall function spec
1866 Param_Specs := New_List;
1867 for I in 1 .. Nb_Opnds loop
1870 Make_Parameter_Specification (Loc,
1871 Defining_Identifier =>
1872 Make_Defining_Identifier (Loc, New_External_Name ('S', I)),
1873 Parameter_Type => New_Reference_To (Base_Typ, Loc)));
1876 Func_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('C'));
1878 Make_Function_Specification (Loc,
1879 Defining_Unit_Name => Func_Id,
1880 Parameter_Specifications => Param_Specs,
1881 Subtype_Mark => New_Reference_To (Base_Typ, Loc));
1883 -- Construct L's object declaration
1886 Make_Object_Declaration (Loc,
1887 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uL),
1888 Object_Definition => New_Reference_To (Ind_Typ, Loc));
1890 Func_Decls := New_List (L_Decl);
1892 -- Construct the if-then-elsif statements
1894 Elsif_List := New_List;
1895 for I in 2 .. Nb_Opnds - 1 loop
1896 Append_To (Elsif_List, Make_Elsif_Part (Loc,
1897 Condition => S_Length_Test (I),
1898 Then_Statements => New_List (Init_L (I))));
1902 Make_Implicit_If_Statement (Cnode,
1903 Condition => S_Length_Test (1),
1904 Then_Statements => New_List (Init_L (1)),
1905 Elsif_Parts => Elsif_List,
1906 Else_Statements => New_List (Make_Return_Statement (Loc,
1907 Expression => S (Nb_Opnds))));
1909 -- Construct the declaration for H
1912 Make_Object_Declaration (Loc,
1913 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uP),
1914 Object_Definition => New_Reference_To (Ind_Typ, Loc));
1916 H_Init := Make_Op_Subtract (Loc, S_Length (1), One);
1917 for I in 2 .. Nb_Opnds loop
1918 H_Init := Make_Op_Add (Loc, H_Init, S_Length (I));
1920 H_Init := Ind_Val (Make_Op_Add (Loc, H_Init, L_Pos));
1923 Make_Object_Declaration (Loc,
1924 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uH),
1925 Object_Definition => New_Reference_To (Ind_Typ, Loc),
1926 Expression => H_Init);
1928 -- Construct the declaration for R
1930 R_Range := Make_Range (Loc, Low_Bound => L, High_Bound => H);
1932 Make_Index_Or_Discriminant_Constraint (Loc,
1933 Constraints => New_List (R_Range));
1936 Make_Object_Declaration (Loc,
1937 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uR),
1938 Object_Definition =>
1939 Make_Subtype_Indication (Loc,
1940 Subtype_Mark => New_Reference_To (Base_Typ, Loc),
1941 Constraint => R_Constr));
1943 -- Construct the declarations for the declare block
1945 Declare_Decls := New_List (P_Decl, H_Decl, R_Decl);
1947 -- Construct list of statements for the declare block
1949 Declare_Stmts := New_List;
1950 for I in 1 .. Nb_Opnds loop
1951 Append_To (Declare_Stmts,
1952 Make_Implicit_If_Statement (Cnode,
1953 Condition => S_Length_Test (I),
1954 Then_Statements => Copy_Into_R_S (I, I = Nb_Opnds)));
1957 Append_To (Declare_Stmts, Make_Return_Statement (Loc, Expression => R));
1959 -- Construct the declare block
1961 Declare_Block := Make_Block_Statement (Loc,
1962 Declarations => Declare_Decls,
1963 Handled_Statement_Sequence =>
1964 Make_Handled_Sequence_Of_Statements (Loc, Declare_Stmts));
1966 -- Construct the list of function statements
1968 Func_Stmts := New_List (If_Stmt, Declare_Block);
1970 -- Construct the function body
1973 Make_Subprogram_Body (Loc,
1974 Specification => Func_Spec,
1975 Declarations => Func_Decls,
1976 Handled_Statement_Sequence =>
1977 Make_Handled_Sequence_Of_Statements (Loc, Func_Stmts));
1979 -- Insert the newly generated function in the code. This is analyzed
1980 -- with all checks off, since we have completed all the checks.
1982 -- Note that this does *not* fix the array concatenation bug when the
1983 -- low bound is Integer'first sibce that bug comes from the pointer
1984 -- dereferencing an unconstrained array. An there we need a constraint
1985 -- check to make sure the length of the concatenated array is ok. ???
1987 Insert_Action (Cnode, Func_Body, Suppress => All_Checks);
1989 -- Construct list of arguments for the function call
1992 Operand := First (Opnds);
1993 for I in 1 .. Nb_Opnds loop
1994 Append_To (Params, Relocate_Node (Operand));
1998 -- Insert the function call
2002 Make_Function_Call (Loc, New_Reference_To (Func_Id, Loc), Params));
2004 Analyze_And_Resolve (Cnode, Base_Typ);
2005 Set_Is_Inlined (Func_Id);
2006 end Expand_Concatenate_Other;
2008 -------------------------------
2009 -- Expand_Concatenate_String --
2010 -------------------------------
2012 procedure Expand_Concatenate_String (Cnode : Node_Id; Opnds : List_Id) is
2013 Loc : constant Source_Ptr := Sloc (Cnode);
2014 Opnd1 : constant Node_Id := First (Opnds);
2015 Opnd2 : constant Node_Id := Next (Opnd1);
2016 Typ1 : constant Entity_Id := Base_Type (Etype (Opnd1));
2017 Typ2 : constant Entity_Id := Base_Type (Etype (Opnd2));
2020 -- RE_Id value for function to be called
2023 -- In all cases, we build a call to a routine giving the list of
2024 -- arguments as the parameter list to the routine.
2026 case List_Length (Opnds) is
2028 if Typ1 = Standard_Character then
2029 if Typ2 = Standard_Character then
2030 R := RE_Str_Concat_CC;
2033 pragma Assert (Typ2 = Standard_String);
2034 R := RE_Str_Concat_CS;
2037 elsif Typ1 = Standard_String then
2038 if Typ2 = Standard_Character then
2039 R := RE_Str_Concat_SC;
2042 pragma Assert (Typ2 = Standard_String);
2046 -- If we have anything other than Standard_Character or
2047 -- Standard_String, then we must have had a serious error
2048 -- earlier, so we just abandon the attempt at expansion.
2051 pragma Assert (Serious_Errors_Detected > 0);
2056 R := RE_Str_Concat_3;
2059 R := RE_Str_Concat_4;
2062 R := RE_Str_Concat_5;
2066 raise Program_Error;
2069 -- Now generate the appropriate call
2072 Make_Function_Call (Sloc (Cnode),
2073 Name => New_Occurrence_Of (RTE (R), Loc),
2074 Parameter_Associations => Opnds));
2076 Analyze_And_Resolve (Cnode, Standard_String);
2079 when RE_Not_Available =>
2081 end Expand_Concatenate_String;
2083 ------------------------
2084 -- Expand_N_Allocator --
2085 ------------------------
2087 procedure Expand_N_Allocator (N : Node_Id) is
2088 PtrT : constant Entity_Id := Etype (N);
2090 Loc : constant Source_Ptr := Sloc (N);
2095 -- RM E.2.3(22). We enforce that the expected type of an allocator
2096 -- shall not be a remote access-to-class-wide-limited-private type
2098 -- Why is this being done at expansion time, seems clearly wrong ???
2100 Validate_Remote_Access_To_Class_Wide_Type (N);
2102 -- Set the Storage Pool
2104 Set_Storage_Pool (N, Associated_Storage_Pool (Root_Type (PtrT)));
2106 if Present (Storage_Pool (N)) then
2107 if Is_RTE (Storage_Pool (N), RE_SS_Pool) then
2109 Set_Procedure_To_Call (N, RTE (RE_SS_Allocate));
2112 elsif Is_Class_Wide_Type (Etype (Storage_Pool (N))) then
2113 Set_Procedure_To_Call (N, RTE (RE_Allocate_Any));
2116 Set_Procedure_To_Call (N,
2117 Find_Prim_Op (Etype (Storage_Pool (N)), Name_Allocate));
2121 -- Under certain circumstances we can replace an allocator by an
2122 -- access to statically allocated storage. The conditions, as noted
2123 -- in AARM 3.10 (10c) are as follows:
2125 -- Size and initial value is known at compile time
2126 -- Access type is access-to-constant
2128 -- The allocator is not part of a constraint on a record component,
2129 -- because in that case the inserted actions are delayed until the
2130 -- record declaration is fully analyzed, which is too late for the
2131 -- analysis of the rewritten allocator.
2133 if Is_Access_Constant (PtrT)
2134 and then Nkind (Expression (N)) = N_Qualified_Expression
2135 and then Compile_Time_Known_Value (Expression (Expression (N)))
2136 and then Size_Known_At_Compile_Time (Etype (Expression
2138 and then not Is_Record_Type (Current_Scope)
2140 -- Here we can do the optimization. For the allocator
2144 -- We insert an object declaration
2146 -- Tnn : aliased x := y;
2148 -- and replace the allocator by Tnn'Unrestricted_Access.
2149 -- Tnn is marked as requiring static allocation.
2152 Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
2154 Desig := Subtype_Mark (Expression (N));
2156 -- If context is constrained, use constrained subtype directly,
2157 -- so that the constant is not labelled as having a nomimally
2158 -- unconstrained subtype.
2160 if Entity (Desig) = Base_Type (Designated_Type (PtrT)) then
2161 Desig := New_Occurrence_Of (Designated_Type (PtrT), Loc);
2165 Make_Object_Declaration (Loc,
2166 Defining_Identifier => Temp,
2167 Aliased_Present => True,
2168 Constant_Present => Is_Access_Constant (PtrT),
2169 Object_Definition => Desig,
2170 Expression => Expression (Expression (N))));
2173 Make_Attribute_Reference (Loc,
2174 Prefix => New_Occurrence_Of (Temp, Loc),
2175 Attribute_Name => Name_Unrestricted_Access));
2177 Analyze_And_Resolve (N, PtrT);
2179 -- We set the variable as statically allocated, since we don't
2180 -- want it going on the stack of the current procedure!
2182 Set_Is_Statically_Allocated (Temp);
2186 if Nkind (Expression (N)) = N_Qualified_Expression then
2187 Expand_Allocator_Expression (N);
2189 -- If the allocator is for a type which requires initialization, and
2190 -- there is no initial value (i.e. operand is a subtype indication
2191 -- rather than a qualifed expression), then we must generate a call
2192 -- to the initialization routine. This is done using an expression
2195 -- [Pnnn : constant ptr_T := new (T); Init (Pnnn.all,...); Pnnn]
2197 -- Here ptr_T is the pointer type for the allocator, and T is the
2198 -- subtype of the allocator. A special case arises if the designated
2199 -- type of the access type is a task or contains tasks. In this case
2200 -- the call to Init (Temp.all ...) is replaced by code that ensures
2201 -- that tasks get activated (see Exp_Ch9.Build_Task_Allocate_Block
2202 -- for details). In addition, if the type T is a task T, then the
2203 -- first argument to Init must be converted to the task record type.
2207 T : constant Entity_Id := Entity (Expression (N));
2215 Temp_Decl : Node_Id;
2216 Temp_Type : Entity_Id;
2220 if No_Initialization (N) then
2223 -- Case of no initialization procedure present
2225 elsif not Has_Non_Null_Base_Init_Proc (T) then
2227 -- Case of simple initialization required
2229 if Needs_Simple_Initialization (T) then
2230 Rewrite (Expression (N),
2231 Make_Qualified_Expression (Loc,
2232 Subtype_Mark => New_Occurrence_Of (T, Loc),
2233 Expression => Get_Simple_Init_Val (T, Loc)));
2235 Analyze_And_Resolve (Expression (Expression (N)), T);
2236 Analyze_And_Resolve (Expression (N), T);
2237 Set_Paren_Count (Expression (Expression (N)), 1);
2238 Expand_N_Allocator (N);
2240 -- No initialization required
2246 -- Case of initialization procedure present, must be called
2249 Init := Base_Init_Proc (T);
2252 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
2254 -- Construct argument list for the initialization routine call
2255 -- The CPP constructor needs the address directly
2257 if Is_CPP_Class (T) then
2258 Arg1 := New_Reference_To (Temp, Loc);
2263 Make_Explicit_Dereference (Loc,
2264 Prefix => New_Reference_To (Temp, Loc));
2265 Set_Assignment_OK (Arg1);
2268 -- The initialization procedure expects a specific type.
2269 -- if the context is access to class wide, indicate that
2270 -- the object being allocated has the right specific type.
2272 if Is_Class_Wide_Type (Designated_Type (PtrT)) then
2273 Arg1 := Unchecked_Convert_To (T, Arg1);
2277 -- If designated type is a concurrent type or if it is a
2278 -- private type whose definition is a concurrent type,
2279 -- the first argument in the Init routine has to be
2280 -- unchecked conversion to the corresponding record type.
2281 -- If the designated type is a derived type, we also
2282 -- convert the argument to its root type.
2284 if Is_Concurrent_Type (T) then
2286 Unchecked_Convert_To (Corresponding_Record_Type (T), Arg1);
2288 elsif Is_Private_Type (T)
2289 and then Present (Full_View (T))
2290 and then Is_Concurrent_Type (Full_View (T))
2293 Unchecked_Convert_To
2294 (Corresponding_Record_Type (Full_View (T)), Arg1);
2296 elsif Etype (First_Formal (Init)) /= Base_Type (T) then
2299 Ftyp : constant Entity_Id := Etype (First_Formal (Init));
2302 Arg1 := OK_Convert_To (Etype (Ftyp), Arg1);
2303 Set_Etype (Arg1, Ftyp);
2307 Args := New_List (Arg1);
2309 -- For the task case, pass the Master_Id of the access type
2310 -- as the value of the _Master parameter, and _Chain as the
2311 -- value of the _Chain parameter (_Chain will be defined as
2312 -- part of the generated code for the allocator).
2314 if Has_Task (T) then
2316 if No (Master_Id (Base_Type (PtrT))) then
2318 -- The designated type was an incomplete type, and
2319 -- the access type did not get expanded. Salvage
2322 Expand_N_Full_Type_Declaration
2323 (Parent (Base_Type (PtrT)));
2326 -- If the context of the allocator is a declaration or
2327 -- an assignment, we can generate a meaningful image for
2328 -- it, even though subsequent assignments might remove
2329 -- the connection between task and entity. We build this
2330 -- image when the left-hand side is a simple variable,
2331 -- a simple indexed assignment or a simple selected
2334 if Nkind (Parent (N)) = N_Assignment_Statement then
2336 Nam : constant Node_Id := Name (Parent (N));
2339 if Is_Entity_Name (Nam) then
2341 Build_Task_Image_Decls (
2344 (Entity (Nam), Sloc (Nam)), T);
2346 elsif (Nkind (Nam) = N_Indexed_Component
2347 or else Nkind (Nam) = N_Selected_Component)
2348 and then Is_Entity_Name (Prefix (Nam))
2351 Build_Task_Image_Decls
2352 (Loc, Nam, Etype (Prefix (Nam)));
2354 Decls := Build_Task_Image_Decls (Loc, T, T);
2358 elsif Nkind (Parent (N)) = N_Object_Declaration then
2360 Build_Task_Image_Decls (
2361 Loc, Defining_Identifier (Parent (N)), T);
2364 Decls := Build_Task_Image_Decls (Loc, T, T);
2369 (Master_Id (Base_Type (Root_Type (PtrT))), Loc));
2370 Append_To (Args, Make_Identifier (Loc, Name_uChain));
2372 Decl := Last (Decls);
2374 New_Occurrence_Of (Defining_Identifier (Decl), Loc));
2376 -- Has_Task is false, Decls not used
2382 -- Add discriminants if discriminated type
2384 if Has_Discriminants (T) then
2385 Discr := First_Elmt (Discriminant_Constraint (T));
2387 while Present (Discr) loop
2388 Append (New_Copy_Tree (Elists.Node (Discr)), Args);
2392 elsif Is_Private_Type (T)
2393 and then Present (Full_View (T))
2394 and then Has_Discriminants (Full_View (T))
2397 First_Elmt (Discriminant_Constraint (Full_View (T)));
2399 while Present (Discr) loop
2400 Append (New_Copy_Tree (Elists.Node (Discr)), Args);
2405 -- We set the allocator as analyzed so that when we analyze the
2406 -- expression actions node, we do not get an unwanted recursive
2407 -- expansion of the allocator expression.
2409 Set_Analyzed (N, True);
2410 Node := Relocate_Node (N);
2412 -- Here is the transformation:
2414 -- output: Temp : constant ptr_T := new T;
2415 -- Init (Temp.all, ...);
2416 -- <CTRL> Attach_To_Final_List (Finalizable (Temp.all));
2417 -- <CTRL> Initialize (Finalizable (Temp.all));
2419 -- Here ptr_T is the pointer type for the allocator, and T
2420 -- is the subtype of the allocator.
2423 Make_Object_Declaration (Loc,
2424 Defining_Identifier => Temp,
2425 Constant_Present => True,
2426 Object_Definition => New_Reference_To (Temp_Type, Loc),
2427 Expression => Node);
2429 Set_Assignment_OK (Temp_Decl);
2431 if Is_CPP_Class (T) then
2432 Set_Aliased_Present (Temp_Decl);
2435 Insert_Action (N, Temp_Decl, Suppress => All_Checks);
2437 -- If the designated type is task type or contains tasks,
2438 -- Create block to activate created tasks, and insert
2439 -- declaration for Task_Image variable ahead of call.
2441 if Has_Task (T) then
2443 L : constant List_Id := New_List;
2447 Build_Task_Allocate_Block (L, Node, Args);
2450 Insert_List_Before (First (Declarations (Blk)), Decls);
2451 Insert_Actions (N, L);
2456 Make_Procedure_Call_Statement (Loc,
2457 Name => New_Reference_To (Init, Loc),
2458 Parameter_Associations => Args));
2461 if Controlled_Type (T) then
2462 Flist := Get_Allocator_Final_List (N, Base_Type (T), PtrT);
2466 Ref => New_Copy_Tree (Arg1),
2469 With_Attach => Make_Integer_Literal (Loc, 2)));
2472 if Is_CPP_Class (T) then
2474 Make_Attribute_Reference (Loc,
2475 Prefix => New_Reference_To (Temp, Loc),
2476 Attribute_Name => Name_Unchecked_Access));
2478 Rewrite (N, New_Reference_To (Temp, Loc));
2481 Analyze_And_Resolve (N, PtrT);
2487 when RE_Not_Available =>
2489 end Expand_N_Allocator;
2491 -----------------------
2492 -- Expand_N_And_Then --
2493 -----------------------
2495 -- Expand into conditional expression if Actions present, and also
2496 -- deal with optimizing case of arguments being True or False.
2498 procedure Expand_N_And_Then (N : Node_Id) is
2499 Loc : constant Source_Ptr := Sloc (N);
2500 Typ : constant Entity_Id := Etype (N);
2501 Left : constant Node_Id := Left_Opnd (N);
2502 Right : constant Node_Id := Right_Opnd (N);
2506 -- Deal with non-standard booleans
2508 if Is_Boolean_Type (Typ) then
2509 Adjust_Condition (Left);
2510 Adjust_Condition (Right);
2511 Set_Etype (N, Standard_Boolean);
2514 -- Check for cases of left argument is True or False
2516 if Nkind (Left) = N_Identifier then
2518 -- If left argument is True, change (True and then Right) to Right.
2519 -- Any actions associated with Right will be executed unconditionally
2520 -- and can thus be inserted into the tree unconditionally.
2522 if Entity (Left) = Standard_True then
2523 if Present (Actions (N)) then
2524 Insert_Actions (N, Actions (N));
2528 Adjust_Result_Type (N, Typ);
2531 -- If left argument is False, change (False and then Right) to
2532 -- False. In this case we can forget the actions associated with
2533 -- Right, since they will never be executed.
2535 elsif Entity (Left) = Standard_False then
2536 Kill_Dead_Code (Right);
2537 Kill_Dead_Code (Actions (N));
2538 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
2539 Adjust_Result_Type (N, Typ);
2544 -- If Actions are present, we expand
2546 -- left and then right
2550 -- if left then right else false end
2552 -- with the actions becoming the Then_Actions of the conditional
2553 -- expression. This conditional expression is then further expanded
2554 -- (and will eventually disappear)
2556 if Present (Actions (N)) then
2557 Actlist := Actions (N);
2559 Make_Conditional_Expression (Loc,
2560 Expressions => New_List (
2563 New_Occurrence_Of (Standard_False, Loc))));
2565 Set_Then_Actions (N, Actlist);
2566 Analyze_And_Resolve (N, Standard_Boolean);
2567 Adjust_Result_Type (N, Typ);
2571 -- No actions present, check for cases of right argument True/False
2573 if Nkind (Right) = N_Identifier then
2575 -- Change (Left and then True) to Left. Note that we know there
2576 -- are no actions associated with the True operand, since we
2577 -- just checked for this case above.
2579 if Entity (Right) = Standard_True then
2582 -- Change (Left and then False) to False, making sure to preserve
2583 -- any side effects associated with the Left operand.
2585 elsif Entity (Right) = Standard_False then
2586 Remove_Side_Effects (Left);
2588 (N, New_Occurrence_Of (Standard_False, Loc));
2592 Adjust_Result_Type (N, Typ);
2593 end Expand_N_And_Then;
2595 -------------------------------------
2596 -- Expand_N_Conditional_Expression --
2597 -------------------------------------
2599 -- Expand into expression actions if then/else actions present
2601 procedure Expand_N_Conditional_Expression (N : Node_Id) is
2602 Loc : constant Source_Ptr := Sloc (N);
2603 Cond : constant Node_Id := First (Expressions (N));
2604 Thenx : constant Node_Id := Next (Cond);
2605 Elsex : constant Node_Id := Next (Thenx);
2606 Typ : constant Entity_Id := Etype (N);
2611 -- If either then or else actions are present, then given:
2613 -- if cond then then-expr else else-expr end
2615 -- we insert the following sequence of actions (using Insert_Actions):
2620 -- Cnn := then-expr;
2626 -- and replace the conditional expression by a reference to Cnn.
2628 if Present (Then_Actions (N)) or else Present (Else_Actions (N)) then
2629 Cnn := Make_Defining_Identifier (Loc, New_Internal_Name ('C'));
2632 Make_Implicit_If_Statement (N,
2633 Condition => Relocate_Node (Cond),
2635 Then_Statements => New_List (
2636 Make_Assignment_Statement (Sloc (Thenx),
2637 Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
2638 Expression => Relocate_Node (Thenx))),
2640 Else_Statements => New_List (
2641 Make_Assignment_Statement (Sloc (Elsex),
2642 Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
2643 Expression => Relocate_Node (Elsex))));
2645 Set_Assignment_OK (Name (First (Then_Statements (New_If))));
2646 Set_Assignment_OK (Name (First (Else_Statements (New_If))));
2648 if Present (Then_Actions (N)) then
2650 (First (Then_Statements (New_If)), Then_Actions (N));
2653 if Present (Else_Actions (N)) then
2655 (First (Else_Statements (New_If)), Else_Actions (N));
2658 Rewrite (N, New_Occurrence_Of (Cnn, Loc));
2661 Make_Object_Declaration (Loc,
2662 Defining_Identifier => Cnn,
2663 Object_Definition => New_Occurrence_Of (Typ, Loc)));
2665 Insert_Action (N, New_If);
2666 Analyze_And_Resolve (N, Typ);
2668 end Expand_N_Conditional_Expression;
2670 -----------------------------------
2671 -- Expand_N_Explicit_Dereference --
2672 -----------------------------------
2674 procedure Expand_N_Explicit_Dereference (N : Node_Id) is
2676 -- The only processing required is an insertion of an explicit
2677 -- dereference call for the checked storage pool case.
2679 Insert_Dereference_Action (Prefix (N));
2680 end Expand_N_Explicit_Dereference;
2686 procedure Expand_N_In (N : Node_Id) is
2687 Loc : constant Source_Ptr := Sloc (N);
2688 Rtyp : constant Entity_Id := Etype (N);
2689 Lop : constant Node_Id := Left_Opnd (N);
2690 Rop : constant Node_Id := Right_Opnd (N);
2693 -- If we have an explicit range, do a bit of optimization based
2694 -- on range analysis (we may be able to kill one or both checks).
2696 if Nkind (Rop) = N_Range then
2698 Lcheck : constant Compare_Result :=
2699 Compile_Time_Compare (Lop, Low_Bound (Rop));
2700 Ucheck : constant Compare_Result :=
2701 Compile_Time_Compare (Lop, High_Bound (Rop));
2704 -- If either check is known to fail, replace result
2705 -- by False, since the other check does not matter.
2707 if Lcheck = LT or else Ucheck = GT then
2709 New_Reference_To (Standard_False, Loc));
2710 Analyze_And_Resolve (N, Rtyp);
2713 -- If both checks are known to succeed, replace result
2714 -- by True, since we know we are in range.
2716 elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
2718 New_Reference_To (Standard_True, Loc));
2719 Analyze_And_Resolve (N, Rtyp);
2722 -- If lower bound check succeeds and upper bound check is
2723 -- not known to succeed or fail, then replace the range check
2724 -- with a comparison against the upper bound.
2726 elsif Lcheck in Compare_GE then
2730 Right_Opnd => High_Bound (Rop)));
2731 Analyze_And_Resolve (N, Rtyp);
2734 -- If upper bound check succeeds and lower bound check is
2735 -- not known to succeed or fail, then replace the range check
2736 -- with a comparison against the lower bound.
2738 elsif Ucheck in Compare_LE then
2742 Right_Opnd => Low_Bound (Rop)));
2743 Analyze_And_Resolve (N, Rtyp);
2748 -- For all other cases of an explicit range, nothing to be done
2752 -- Here right operand is a subtype mark
2756 Typ : Entity_Id := Etype (Rop);
2757 Is_Acc : constant Boolean := Is_Access_Type (Typ);
2758 Obj : Node_Id := Lop;
2759 Cond : Node_Id := Empty;
2762 Remove_Side_Effects (Obj);
2764 -- For tagged type, do tagged membership operation
2766 if Is_Tagged_Type (Typ) then
2768 -- No expansion will be performed when Java_VM, as the
2769 -- JVM back end will handle the membership tests directly
2770 -- (tags are not explicitly represented in Java objects,
2771 -- so the normal tagged membership expansion is not what
2775 Rewrite (N, Tagged_Membership (N));
2776 Analyze_And_Resolve (N, Rtyp);
2781 -- If type is scalar type, rewrite as x in t'first .. t'last
2782 -- This reason we do this is that the bounds may have the wrong
2783 -- type if they come from the original type definition.
2785 elsif Is_Scalar_Type (Typ) then
2789 Make_Attribute_Reference (Loc,
2790 Attribute_Name => Name_First,
2791 Prefix => New_Reference_To (Typ, Loc)),
2794 Make_Attribute_Reference (Loc,
2795 Attribute_Name => Name_Last,
2796 Prefix => New_Reference_To (Typ, Loc))));
2797 Analyze_And_Resolve (N, Rtyp);
2801 -- Here we have a non-scalar type
2804 Typ := Designated_Type (Typ);
2807 if not Is_Constrained (Typ) then
2809 New_Reference_To (Standard_True, Loc));
2810 Analyze_And_Resolve (N, Rtyp);
2812 -- For the constrained array case, we have to check the
2813 -- subscripts for an exact match if the lengths are
2814 -- non-zero (the lengths must match in any case).
2816 elsif Is_Array_Type (Typ) then
2818 Check_Subscripts : declare
2819 function Construct_Attribute_Reference
2824 -- Build attribute reference E'Nam(Dim)
2826 -----------------------------------
2827 -- Construct_Attribute_Reference --
2828 -----------------------------------
2830 function Construct_Attribute_Reference
2838 Make_Attribute_Reference (Loc,
2840 Attribute_Name => Nam,
2841 Expressions => New_List (
2842 Make_Integer_Literal (Loc, Dim)));
2843 end Construct_Attribute_Reference;
2845 -- Start processing for Check_Subscripts
2848 for J in 1 .. Number_Dimensions (Typ) loop
2849 Evolve_And_Then (Cond,
2852 Construct_Attribute_Reference
2853 (Duplicate_Subexpr_No_Checks (Obj),
2856 Construct_Attribute_Reference
2857 (New_Occurrence_Of (Typ, Loc), Name_First, J)));
2859 Evolve_And_Then (Cond,
2862 Construct_Attribute_Reference
2863 (Duplicate_Subexpr_No_Checks (Obj),
2866 Construct_Attribute_Reference
2867 (New_Occurrence_Of (Typ, Loc), Name_Last, J)));
2876 Right_Opnd => Make_Null (Loc)),
2877 Right_Opnd => Cond);
2881 Analyze_And_Resolve (N, Rtyp);
2882 end Check_Subscripts;
2884 -- These are the cases where constraint checks may be
2885 -- required, e.g. records with possible discriminants
2888 -- Expand the test into a series of discriminant comparisons.
2889 -- The expression that is built is the negation of the one
2890 -- that is used for checking discriminant constraints.
2892 Obj := Relocate_Node (Left_Opnd (N));
2894 if Has_Discriminants (Typ) then
2895 Cond := Make_Op_Not (Loc,
2896 Right_Opnd => Build_Discriminant_Checks (Obj, Typ));
2899 Cond := Make_Or_Else (Loc,
2903 Right_Opnd => Make_Null (Loc)),
2904 Right_Opnd => Cond);
2908 Cond := New_Occurrence_Of (Standard_True, Loc);
2912 Analyze_And_Resolve (N, Rtyp);
2918 --------------------------------
2919 -- Expand_N_Indexed_Component --
2920 --------------------------------
2922 procedure Expand_N_Indexed_Component (N : Node_Id) is
2923 Loc : constant Source_Ptr := Sloc (N);
2924 Typ : constant Entity_Id := Etype (N);
2925 P : constant Node_Id := Prefix (N);
2926 T : constant Entity_Id := Etype (P);
2929 -- A special optimization, if we have an indexed component that
2930 -- is selecting from a slice, then we can eliminate the slice,
2931 -- since, for example, x (i .. j)(k) is identical to x(k). The
2932 -- only difference is the range check required by the slice. The
2933 -- range check for the slice itself has already been generated.
2934 -- The range check for the subscripting operation is ensured
2935 -- by converting the subject to the subtype of the slice.
2937 -- This optimization not only generates better code, avoiding
2938 -- slice messing especially in the packed case, but more importantly
2939 -- bypasses some problems in handling this peculiar case, for
2940 -- example, the issue of dealing specially with object renamings.
2942 if Nkind (P) = N_Slice then
2944 Make_Indexed_Component (Loc,
2945 Prefix => Prefix (P),
2946 Expressions => New_List (
2948 (Etype (First_Index (Etype (P))),
2949 First (Expressions (N))))));
2950 Analyze_And_Resolve (N, Typ);
2954 -- If the prefix is an access type, then we unconditionally rewrite
2955 -- if as an explicit deference. This simplifies processing for several
2956 -- cases, including packed array cases and certain cases in which
2957 -- checks must be generated. We used to try to do this only when it
2958 -- was necessary, but it cleans up the code to do it all the time.
2960 if Is_Access_Type (T) then
2962 -- Check whether the prefix comes from a debug pool, and generate
2963 -- the check before rewriting.
2965 Insert_Dereference_Action (P);
2968 Make_Explicit_Dereference (Sloc (N),
2969 Prefix => Relocate_Node (P)));
2970 Analyze_And_Resolve (P, Designated_Type (T));
2973 -- Generate index and validity checks
2975 Generate_Index_Checks (N);
2977 if Validity_Checks_On and then Validity_Check_Subscripts then
2978 Apply_Subscript_Validity_Checks (N);
2981 -- All done for the non-packed case
2983 if not Is_Packed (Etype (Prefix (N))) then
2987 -- For packed arrays that are not bit-packed (i.e. the case of an array
2988 -- with one or more index types with a non-coniguous enumeration type),
2989 -- we can always use the normal packed element get circuit.
2991 if not Is_Bit_Packed_Array (Etype (Prefix (N))) then
2992 Expand_Packed_Element_Reference (N);
2996 -- For a reference to a component of a bit packed array, we have to
2997 -- convert it to a reference to the corresponding Packed_Array_Type.
2998 -- We only want to do this for simple references, and not for:
3000 -- Left side of assignment, or prefix of left side of assignment,
3001 -- or prefix of the prefix, to handle packed arrays of packed arrays,
3002 -- This case is handled in Exp_Ch5.Expand_N_Assignment_Statement
3004 -- Renaming objects in renaming associations
3005 -- This case is handled when a use of the renamed variable occurs
3007 -- Actual parameters for a procedure call
3008 -- This case is handled in Exp_Ch6.Expand_Actuals
3010 -- The second expression in a 'Read attribute reference
3012 -- The prefix of an address or size attribute reference
3014 -- The following circuit detects these exceptions
3017 Child : Node_Id := N;
3018 Parnt : Node_Id := Parent (N);
3022 if Nkind (Parnt) = N_Unchecked_Expression then
3025 elsif Nkind (Parnt) = N_Object_Renaming_Declaration
3026 or else Nkind (Parnt) = N_Procedure_Call_Statement
3027 or else (Nkind (Parnt) = N_Parameter_Association
3029 Nkind (Parent (Parnt)) = N_Procedure_Call_Statement)
3033 elsif Nkind (Parnt) = N_Attribute_Reference
3034 and then (Attribute_Name (Parnt) = Name_Address
3036 Attribute_Name (Parnt) = Name_Size)
3037 and then Prefix (Parnt) = Child
3041 elsif Nkind (Parnt) = N_Assignment_Statement
3042 and then Name (Parnt) = Child
3046 -- If the expression is an index of an indexed component,
3047 -- it must be expanded regardless of context.
3049 elsif Nkind (Parnt) = N_Indexed_Component
3050 and then Child /= Prefix (Parnt)
3052 Expand_Packed_Element_Reference (N);
3055 elsif Nkind (Parent (Parnt)) = N_Assignment_Statement
3056 and then Name (Parent (Parnt)) = Parnt
3060 elsif Nkind (Parnt) = N_Attribute_Reference
3061 and then Attribute_Name (Parnt) = Name_Read
3062 and then Next (First (Expressions (Parnt))) = Child
3066 elsif (Nkind (Parnt) = N_Indexed_Component
3067 or else Nkind (Parnt) = N_Selected_Component)
3068 and then Prefix (Parnt) = Child
3073 Expand_Packed_Element_Reference (N);
3077 -- Keep looking up tree for unchecked expression, or if we are
3078 -- the prefix of a possible assignment left side.
3081 Parnt := Parent (Child);
3085 end Expand_N_Indexed_Component;
3087 ---------------------
3088 -- Expand_N_Not_In --
3089 ---------------------
3091 -- Replace a not in b by not (a in b) so that the expansions for (a in b)
3092 -- can be done. This avoids needing to duplicate this expansion code.
3094 procedure Expand_N_Not_In (N : Node_Id) is
3095 Loc : constant Source_Ptr := Sloc (N);
3096 Typ : constant Entity_Id := Etype (N);
3103 Left_Opnd => Left_Opnd (N),
3104 Right_Opnd => Right_Opnd (N))));
3105 Analyze_And_Resolve (N, Typ);
3106 end Expand_N_Not_In;
3112 -- The only replacement required is for the case of a null of type
3113 -- that is an access to protected subprogram. We represent such
3114 -- access values as a record, and so we must replace the occurrence
3115 -- of null by the equivalent record (with a null address and a null
3116 -- pointer in it), so that the backend creates the proper value.
3118 procedure Expand_N_Null (N : Node_Id) is
3119 Loc : constant Source_Ptr := Sloc (N);
3120 Typ : constant Entity_Id := Etype (N);
3124 if Ekind (Typ) = E_Access_Protected_Subprogram_Type then
3126 Make_Aggregate (Loc,
3127 Expressions => New_List (
3128 New_Occurrence_Of (RTE (RE_Null_Address), Loc),
3132 Analyze_And_Resolve (N, Equivalent_Type (Typ));
3134 -- For subsequent semantic analysis, the node must retain its
3135 -- type. Gigi in any case replaces this type by the corresponding
3136 -- record type before processing the node.
3142 when RE_Not_Available =>
3146 ---------------------
3147 -- Expand_N_Op_Abs --
3148 ---------------------
3150 procedure Expand_N_Op_Abs (N : Node_Id) is
3151 Loc : constant Source_Ptr := Sloc (N);
3152 Expr : constant Node_Id := Right_Opnd (N);
3155 Unary_Op_Validity_Checks (N);
3157 -- Deal with software overflow checking
3159 if not Backend_Overflow_Checks_On_Target
3160 and then Is_Signed_Integer_Type (Etype (N))
3161 and then Do_Overflow_Check (N)
3163 -- The only case to worry about is when the argument is
3164 -- equal to the largest negative number, so what we do is
3165 -- to insert the check:
3167 -- [constraint_error when Expr = typ'Base'First]
3169 -- with the usual Duplicate_Subexpr use coding for expr
3172 Make_Raise_Constraint_Error (Loc,
3175 Left_Opnd => Duplicate_Subexpr (Expr),
3177 Make_Attribute_Reference (Loc,
3179 New_Occurrence_Of (Base_Type (Etype (Expr)), Loc),
3180 Attribute_Name => Name_First)),
3181 Reason => CE_Overflow_Check_Failed));
3184 -- Vax floating-point types case
3186 if Vax_Float (Etype (N)) then
3187 Expand_Vax_Arith (N);
3189 end Expand_N_Op_Abs;
3191 ---------------------
3192 -- Expand_N_Op_Add --
3193 ---------------------
3195 procedure Expand_N_Op_Add (N : Node_Id) is
3196 Typ : constant Entity_Id := Etype (N);
3199 Binary_Op_Validity_Checks (N);
3201 -- N + 0 = 0 + N = N for integer types
3203 if Is_Integer_Type (Typ) then
3204 if Compile_Time_Known_Value (Right_Opnd (N))
3205 and then Expr_Value (Right_Opnd (N)) = Uint_0
3207 Rewrite (N, Left_Opnd (N));
3210 elsif Compile_Time_Known_Value (Left_Opnd (N))
3211 and then Expr_Value (Left_Opnd (N)) = Uint_0
3213 Rewrite (N, Right_Opnd (N));
3218 -- Arithmetic overflow checks for signed integer/fixed point types
3220 if Is_Signed_Integer_Type (Typ)
3221 or else Is_Fixed_Point_Type (Typ)
3223 Apply_Arithmetic_Overflow_Check (N);
3226 -- Vax floating-point types case
3228 elsif Vax_Float (Typ) then
3229 Expand_Vax_Arith (N);
3231 end Expand_N_Op_Add;
3233 ---------------------
3234 -- Expand_N_Op_And --
3235 ---------------------
3237 procedure Expand_N_Op_And (N : Node_Id) is
3238 Typ : constant Entity_Id := Etype (N);
3241 Binary_Op_Validity_Checks (N);
3243 if Is_Array_Type (Etype (N)) then
3244 Expand_Boolean_Operator (N);
3246 elsif Is_Boolean_Type (Etype (N)) then
3247 Adjust_Condition (Left_Opnd (N));
3248 Adjust_Condition (Right_Opnd (N));
3249 Set_Etype (N, Standard_Boolean);
3250 Adjust_Result_Type (N, Typ);
3252 end Expand_N_Op_And;
3254 ------------------------
3255 -- Expand_N_Op_Concat --
3256 ------------------------
3258 Max_Available_String_Operands : Int := -1;
3259 -- This is initialized the first time this routine is called. It records
3260 -- a value of 0,2,3,4,5 depending on what Str_Concat_n procedures are
3261 -- available in the run-time:
3264 -- 2 RE_Str_Concat available, RE_Str_Concat_3 not available
3265 -- 3 RE_Str_Concat/Concat_2 available, RE_Str_Concat_4 not available
3266 -- 4 RE_Str_Concat/Concat_2/3 available, RE_Str_Concat_5 not available
3267 -- 5 All routines including RE_Str_Concat_5 available
3269 Char_Concat_Available : Boolean;
3270 -- Records if the routines RE_Str_Concat_CC/CS/SC are available. True if
3271 -- all three are available, False if any one of these is unavailable.
3273 procedure Expand_N_Op_Concat (N : Node_Id) is
3276 -- List of operands to be concatenated
3279 -- Single operand for concatenation
3282 -- Node which is to be replaced by the result of concatenating
3283 -- the nodes in the list Opnds.
3286 -- Array type of concatenation result type
3289 -- Component type of concatenation represented by Cnode
3292 -- Initialize global variables showing run-time status
3294 if Max_Available_String_Operands < 1 then
3295 if not RTE_Available (RE_Str_Concat) then
3296 Max_Available_String_Operands := 0;
3297 elsif not RTE_Available (RE_Str_Concat_3) then
3298 Max_Available_String_Operands := 2;
3299 elsif not RTE_Available (RE_Str_Concat_4) then
3300 Max_Available_String_Operands := 3;
3301 elsif not RTE_Available (RE_Str_Concat_5) then
3302 Max_Available_String_Operands := 4;
3304 Max_Available_String_Operands := 5;
3307 Char_Concat_Available :=
3308 RTE_Available (RE_Str_Concat_CC)
3310 RTE_Available (RE_Str_Concat_CS)
3312 RTE_Available (RE_Str_Concat_SC);
3315 -- Ensure validity of both operands
3317 Binary_Op_Validity_Checks (N);
3319 -- If we are the left operand of a concatenation higher up the
3320 -- tree, then do nothing for now, since we want to deal with a
3321 -- series of concatenations as a unit.
3323 if Nkind (Parent (N)) = N_Op_Concat
3324 and then N = Left_Opnd (Parent (N))
3329 -- We get here with a concatenation whose left operand may be a
3330 -- concatenation itself with a consistent type. We need to process
3331 -- these concatenation operands from left to right, which means
3332 -- from the deepest node in the tree to the highest node.
3335 while Nkind (Left_Opnd (Cnode)) = N_Op_Concat loop
3336 Cnode := Left_Opnd (Cnode);
3339 -- Now Opnd is the deepest Opnd, and its parents are the concatenation
3340 -- nodes above, so now we process bottom up, doing the operations. We
3341 -- gather a string that is as long as possible up to five operands
3343 -- The outer loop runs more than once if there are more than five
3344 -- concatenations of type Standard.String, the most we handle for
3345 -- this case, or if more than one concatenation type is involved.
3348 Opnds := New_List (Left_Opnd (Cnode), Right_Opnd (Cnode));
3349 Set_Parent (Opnds, N);
3351 -- The inner loop gathers concatenation operands. We gather any
3352 -- number of these in the non-string case, or if no concatenation
3353 -- routines are available for string (since in that case we will
3354 -- treat string like any other non-string case). Otherwise we only
3355 -- gather as many operands as can be handled by the available
3356 -- procedures in the run-time library (normally 5, but may be
3357 -- less for the configurable run-time case).
3359 Inner : while Cnode /= N
3360 and then (Base_Type (Etype (Cnode)) /= Standard_String
3362 Max_Available_String_Operands = 0
3364 List_Length (Opnds) <
3365 Max_Available_String_Operands)
3366 and then Base_Type (Etype (Cnode)) =
3367 Base_Type (Etype (Parent (Cnode)))
3369 Cnode := Parent (Cnode);
3370 Append (Right_Opnd (Cnode), Opnds);
3373 -- Here we process the collected operands. First we convert
3374 -- singleton operands to singleton aggregates. This is skipped
3375 -- however for the case of two operands of type String, since
3376 -- we have special routines for these cases.
3378 Atyp := Base_Type (Etype (Cnode));
3379 Ctyp := Base_Type (Component_Type (Etype (Cnode)));
3381 if (List_Length (Opnds) > 2 or else Atyp /= Standard_String)
3382 or else not Char_Concat_Available
3384 Opnd := First (Opnds);
3386 if Base_Type (Etype (Opnd)) = Ctyp then
3388 Make_Aggregate (Sloc (Cnode),
3389 Expressions => New_List (Relocate_Node (Opnd))));
3390 Analyze_And_Resolve (Opnd, Atyp);
3394 exit when No (Opnd);
3398 -- Now call appropriate continuation routine
3400 if Atyp = Standard_String
3401 and then Max_Available_String_Operands > 0
3403 Expand_Concatenate_String (Cnode, Opnds);
3405 Expand_Concatenate_Other (Cnode, Opnds);
3408 exit Outer when Cnode = N;
3409 Cnode := Parent (Cnode);
3411 end Expand_N_Op_Concat;
3413 ------------------------
3414 -- Expand_N_Op_Divide --
3415 ------------------------
3417 procedure Expand_N_Op_Divide (N : Node_Id) is
3418 Loc : constant Source_Ptr := Sloc (N);
3419 Ltyp : constant Entity_Id := Etype (Left_Opnd (N));
3420 Rtyp : constant Entity_Id := Etype (Right_Opnd (N));
3421 Typ : Entity_Id := Etype (N);
3424 Binary_Op_Validity_Checks (N);
3426 -- Vax_Float is a special case
3428 if Vax_Float (Typ) then
3429 Expand_Vax_Arith (N);
3433 -- N / 1 = N for integer types
3435 if Is_Integer_Type (Typ)
3436 and then Compile_Time_Known_Value (Right_Opnd (N))
3437 and then Expr_Value (Right_Opnd (N)) = Uint_1
3439 Rewrite (N, Left_Opnd (N));
3443 -- Convert x / 2 ** y to Shift_Right (x, y). Note that the fact that
3444 -- Is_Power_Of_2_For_Shift is set means that we know that our left
3445 -- operand is an unsigned integer, as required for this to work.
3447 if Nkind (Right_Opnd (N)) = N_Op_Expon
3448 and then Is_Power_Of_2_For_Shift (Right_Opnd (N))
3450 -- We cannot do this transformation in configurable run time mode if we
3451 -- have 64-bit -- integers and long shifts are not available.
3455 or else Support_Long_Shifts_On_Target)
3458 Make_Op_Shift_Right (Loc,
3459 Left_Opnd => Left_Opnd (N),
3461 Convert_To (Standard_Natural, Right_Opnd (Right_Opnd (N)))));
3462 Analyze_And_Resolve (N, Typ);
3466 -- Do required fixup of universal fixed operation
3468 if Typ = Universal_Fixed then
3469 Fixup_Universal_Fixed_Operation (N);
3473 -- Divisions with fixed-point results
3475 if Is_Fixed_Point_Type (Typ) then
3477 -- No special processing if Treat_Fixed_As_Integer is set,
3478 -- since from a semantic point of view such operations are
3479 -- simply integer operations and will be treated that way.
3481 if not Treat_Fixed_As_Integer (N) then
3482 if Is_Integer_Type (Rtyp) then
3483 Expand_Divide_Fixed_By_Integer_Giving_Fixed (N);
3485 Expand_Divide_Fixed_By_Fixed_Giving_Fixed (N);
3489 -- Other cases of division of fixed-point operands. Again we
3490 -- exclude the case where Treat_Fixed_As_Integer is set.
3492 elsif (Is_Fixed_Point_Type (Ltyp) or else
3493 Is_Fixed_Point_Type (Rtyp))
3494 and then not Treat_Fixed_As_Integer (N)
3496 if Is_Integer_Type (Typ) then
3497 Expand_Divide_Fixed_By_Fixed_Giving_Integer (N);
3499 pragma Assert (Is_Floating_Point_Type (Typ));
3500 Expand_Divide_Fixed_By_Fixed_Giving_Float (N);
3503 -- Mixed-mode operations can appear in a non-static universal
3504 -- context, in which case the integer argument must be converted
3507 elsif Typ = Universal_Real
3508 and then Is_Integer_Type (Rtyp)
3510 Rewrite (Right_Opnd (N),
3511 Convert_To (Universal_Real, Relocate_Node (Right_Opnd (N))));
3513 Analyze_And_Resolve (Right_Opnd (N), Universal_Real);
3515 elsif Typ = Universal_Real
3516 and then Is_Integer_Type (Ltyp)
3518 Rewrite (Left_Opnd (N),
3519 Convert_To (Universal_Real, Relocate_Node (Left_Opnd (N))));
3521 Analyze_And_Resolve (Left_Opnd (N), Universal_Real);
3523 -- Non-fixed point cases, do zero divide and overflow checks
3525 elsif Is_Integer_Type (Typ) then
3526 Apply_Divide_Check (N);
3528 -- Check for 64-bit division available
3530 if Esize (Ltyp) > 32
3531 and then not Support_64_Bit_Divides_On_Target
3533 Error_Msg_CRT ("64-bit division", N);
3536 end Expand_N_Op_Divide;
3538 --------------------
3539 -- Expand_N_Op_Eq --
3540 --------------------
3542 procedure Expand_N_Op_Eq (N : Node_Id) is
3543 Loc : constant Source_Ptr := Sloc (N);
3544 Typ : constant Entity_Id := Etype (N);
3545 Lhs : constant Node_Id := Left_Opnd (N);
3546 Rhs : constant Node_Id := Right_Opnd (N);
3547 Bodies : constant List_Id := New_List;
3548 A_Typ : constant Entity_Id := Etype (Lhs);
3550 Typl : Entity_Id := A_Typ;
3551 Op_Name : Entity_Id;
3554 procedure Build_Equality_Call (Eq : Entity_Id);
3555 -- If a constructed equality exists for the type or for its parent,
3556 -- build and analyze call, adding conversions if the operation is
3559 -------------------------
3560 -- Build_Equality_Call --
3561 -------------------------
3563 procedure Build_Equality_Call (Eq : Entity_Id) is
3564 Op_Type : constant Entity_Id := Etype (First_Formal (Eq));
3565 L_Exp : Node_Id := Relocate_Node (Lhs);
3566 R_Exp : Node_Id := Relocate_Node (Rhs);
3569 if Base_Type (Op_Type) /= Base_Type (A_Typ)
3570 and then not Is_Class_Wide_Type (A_Typ)
3572 L_Exp := OK_Convert_To (Op_Type, L_Exp);
3573 R_Exp := OK_Convert_To (Op_Type, R_Exp);
3577 Make_Function_Call (Loc,
3578 Name => New_Reference_To (Eq, Loc),
3579 Parameter_Associations => New_List (L_Exp, R_Exp)));
3581 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
3582 end Build_Equality_Call;
3584 -- Start of processing for Expand_N_Op_Eq
3587 Binary_Op_Validity_Checks (N);
3589 if Ekind (Typl) = E_Private_Type then
3590 Typl := Underlying_Type (Typl);
3592 elsif Ekind (Typl) = E_Private_Subtype then
3593 Typl := Underlying_Type (Base_Type (Typl));
3596 -- It may happen in error situations that the underlying type is not
3597 -- set. The error will be detected later, here we just defend the
3604 Typl := Base_Type (Typl);
3608 if Vax_Float (Typl) then
3609 Expand_Vax_Comparison (N);
3612 -- Boolean types (requiring handling of non-standard case)
3614 elsif Is_Boolean_Type (Typl) then
3615 Adjust_Condition (Left_Opnd (N));
3616 Adjust_Condition (Right_Opnd (N));
3617 Set_Etype (N, Standard_Boolean);
3618 Adjust_Result_Type (N, Typ);
3622 elsif Is_Array_Type (Typl) then
3624 -- If we are doing full validity checking, then expand out array
3625 -- comparisons to make sure that we check the array elements.
3627 if Validity_Check_Operands then
3629 Save_Force_Validity_Checks : constant Boolean :=
3630 Force_Validity_Checks;
3632 Force_Validity_Checks := True;
3634 Expand_Array_Equality (N, Typl, A_Typ,
3635 Relocate_Node (Lhs), Relocate_Node (Rhs), Bodies));
3637 Insert_Actions (N, Bodies);
3638 Analyze_And_Resolve (N, Standard_Boolean);
3639 Force_Validity_Checks := Save_Force_Validity_Checks;
3644 elsif Is_Bit_Packed_Array (Typl) then
3645 Expand_Packed_Eq (N);
3647 -- For non-floating-point elementary types, the primitive equality
3648 -- always applies, and block-bit comparison is fine. Floating-point
3649 -- is an exception because of negative zeroes.
3651 elsif Is_Elementary_Type (Component_Type (Typl))
3652 and then not Is_Floating_Point_Type (Component_Type (Typl))
3653 and then Support_Composite_Compare_On_Target
3657 -- For composite and floating-point cases, expand equality loop
3658 -- to make sure of using proper comparisons for tagged types,
3659 -- and correctly handling the floating-point case.
3663 Expand_Array_Equality (N, Typl, A_Typ,
3664 Relocate_Node (Lhs), Relocate_Node (Rhs), Bodies));
3666 Insert_Actions (N, Bodies, Suppress => All_Checks);
3667 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
3672 elsif Is_Record_Type (Typl) then
3674 -- For tagged types, use the primitive "="
3676 if Is_Tagged_Type (Typl) then
3678 -- If this is derived from an untagged private type completed
3679 -- with a tagged type, it does not have a full view, so we
3680 -- use the primitive operations of the private type.
3681 -- This check should no longer be necessary when these
3682 -- types receive their full views ???
3684 if Is_Private_Type (A_Typ)
3685 and then not Is_Tagged_Type (A_Typ)
3686 and then Is_Derived_Type (A_Typ)
3687 and then No (Full_View (A_Typ))
3689 Prim := First_Elmt (Collect_Primitive_Operations (A_Typ));
3691 while Chars (Node (Prim)) /= Name_Op_Eq loop
3693 pragma Assert (Present (Prim));
3696 Op_Name := Node (Prim);
3698 -- Find the type's predefined equality or an overriding
3699 -- user-defined equality. The reason for not simply calling
3700 -- Find_Prim_Op here is that there may be a user-defined
3701 -- overloaded equality op that precedes the equality that
3702 -- we want, so we have to explicitly search (e.g., there
3703 -- could be an equality with two different parameter types).
3706 if Is_Class_Wide_Type (Typl) then
3707 Typl := Root_Type (Typl);
3710 Prim := First_Elmt (Primitive_Operations (Typl));
3712 while Present (Prim) loop
3713 exit when Chars (Node (Prim)) = Name_Op_Eq
3714 and then Etype (First_Formal (Node (Prim))) =
3715 Etype (Next_Formal (First_Formal (Node (Prim))))
3717 Base_Type (Etype (Node (Prim))) = Standard_Boolean;
3720 pragma Assert (Present (Prim));
3723 Op_Name := Node (Prim);
3726 Build_Equality_Call (Op_Name);
3728 -- If a type support function is present (for complex cases), use it
3730 elsif Present (TSS (Root_Type (Typl), TSS_Composite_Equality)) then
3732 (TSS (Root_Type (Typl), TSS_Composite_Equality));
3734 -- Otherwise expand the component by component equality. Note that
3735 -- we never use block-bit coparisons for records, because of the
3736 -- problems with gaps. The backend will often be able to recombine
3737 -- the separate comparisons that we generate here.
3740 Remove_Side_Effects (Lhs);
3741 Remove_Side_Effects (Rhs);
3743 Expand_Record_Equality (N, Typl, Lhs, Rhs, Bodies));
3745 Insert_Actions (N, Bodies, Suppress => All_Checks);
3746 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
3750 -- If we still have an equality comparison (i.e. it was not rewritten
3751 -- in some way), then we can test if result is needed at compile time).
3753 if Nkind (N) = N_Op_Eq then
3754 Rewrite_Comparison (N);
3758 -----------------------
3759 -- Expand_N_Op_Expon --
3760 -----------------------
3762 procedure Expand_N_Op_Expon (N : Node_Id) is
3763 Loc : constant Source_Ptr := Sloc (N);
3764 Typ : constant Entity_Id := Etype (N);
3765 Rtyp : constant Entity_Id := Root_Type (Typ);
3766 Base : constant Node_Id := Relocate_Node (Left_Opnd (N));
3767 Bastyp : constant Node_Id := Etype (Base);
3768 Exp : constant Node_Id := Relocate_Node (Right_Opnd (N));
3769 Exptyp : constant Entity_Id := Etype (Exp);
3770 Ovflo : constant Boolean := Do_Overflow_Check (N);
3779 Binary_Op_Validity_Checks (N);
3781 -- If either operand is of a private type, then we have the use of
3782 -- an intrinsic operator, and we get rid of the privateness, by using
3783 -- root types of underlying types for the actual operation. Otherwise
3784 -- the private types will cause trouble if we expand multiplications
3785 -- or shifts etc. We also do this transformation if the result type
3786 -- is different from the base type.
3788 if Is_Private_Type (Etype (Base))
3790 Is_Private_Type (Typ)
3792 Is_Private_Type (Exptyp)
3794 Rtyp /= Root_Type (Bastyp)
3797 Bt : constant Entity_Id := Root_Type (Underlying_Type (Bastyp));
3798 Et : constant Entity_Id := Root_Type (Underlying_Type (Exptyp));
3802 Unchecked_Convert_To (Typ,
3804 Left_Opnd => Unchecked_Convert_To (Bt, Base),
3805 Right_Opnd => Unchecked_Convert_To (Et, Exp))));
3806 Analyze_And_Resolve (N, Typ);
3811 -- Test for case of known right argument
3813 if Compile_Time_Known_Value (Exp) then
3814 Expv := Expr_Value (Exp);
3816 -- We only fold small non-negative exponents. You might think we
3817 -- could fold small negative exponents for the real case, but we
3818 -- can't because we are required to raise Constraint_Error for
3819 -- the case of 0.0 ** (negative) even if Machine_Overflows = False.
3820 -- See ACVC test C4A012B.
3822 if Expv >= 0 and then Expv <= 4 then
3824 -- X ** 0 = 1 (or 1.0)
3827 if Ekind (Typ) in Integer_Kind then
3828 Xnode := Make_Integer_Literal (Loc, Intval => 1);
3830 Xnode := Make_Real_Literal (Loc, Ureal_1);
3842 Make_Op_Multiply (Loc,
3843 Left_Opnd => Duplicate_Subexpr (Base),
3844 Right_Opnd => Duplicate_Subexpr_No_Checks (Base));
3846 -- X ** 3 = X * X * X
3850 Make_Op_Multiply (Loc,
3852 Make_Op_Multiply (Loc,
3853 Left_Opnd => Duplicate_Subexpr (Base),
3854 Right_Opnd => Duplicate_Subexpr_No_Checks (Base)),
3855 Right_Opnd => Duplicate_Subexpr_No_Checks (Base));
3858 -- En : constant base'type := base * base;
3864 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
3866 Insert_Actions (N, New_List (
3867 Make_Object_Declaration (Loc,
3868 Defining_Identifier => Temp,
3869 Constant_Present => True,
3870 Object_Definition => New_Reference_To (Typ, Loc),
3872 Make_Op_Multiply (Loc,
3873 Left_Opnd => Duplicate_Subexpr (Base),
3874 Right_Opnd => Duplicate_Subexpr_No_Checks (Base)))));
3877 Make_Op_Multiply (Loc,
3878 Left_Opnd => New_Reference_To (Temp, Loc),
3879 Right_Opnd => New_Reference_To (Temp, Loc));
3883 Analyze_And_Resolve (N, Typ);
3888 -- Case of (2 ** expression) appearing as an argument of an integer
3889 -- multiplication, or as the right argument of a division of a non-
3890 -- negative integer. In such cases we leave the node untouched, setting
3891 -- the flag Is_Natural_Power_Of_2_for_Shift set, then the expansion
3892 -- of the higher level node converts it into a shift.
3894 if Nkind (Base) = N_Integer_Literal
3895 and then Intval (Base) = 2
3896 and then Is_Integer_Type (Root_Type (Exptyp))
3897 and then Esize (Root_Type (Exptyp)) <= Esize (Standard_Integer)
3898 and then Is_Unsigned_Type (Exptyp)
3900 and then Nkind (Parent (N)) in N_Binary_Op
3903 P : constant Node_Id := Parent (N);
3904 L : constant Node_Id := Left_Opnd (P);
3905 R : constant Node_Id := Right_Opnd (P);
3908 if (Nkind (P) = N_Op_Multiply
3910 ((Is_Integer_Type (Etype (L)) and then R = N)
3912 (Is_Integer_Type (Etype (R)) and then L = N))
3913 and then not Do_Overflow_Check (P))
3916 (Nkind (P) = N_Op_Divide
3917 and then Is_Integer_Type (Etype (L))
3918 and then Is_Unsigned_Type (Etype (L))
3920 and then not Do_Overflow_Check (P))
3922 Set_Is_Power_Of_2_For_Shift (N);
3928 -- Fall through if exponentiation must be done using a runtime routine
3930 -- First deal with modular case
3932 if Is_Modular_Integer_Type (Rtyp) then
3934 -- Non-binary case, we call the special exponentiation routine for
3935 -- the non-binary case, converting the argument to Long_Long_Integer
3936 -- and passing the modulus value. Then the result is converted back
3937 -- to the base type.
3939 if Non_Binary_Modulus (Rtyp) then
3942 Make_Function_Call (Loc,
3943 Name => New_Reference_To (RTE (RE_Exp_Modular), Loc),
3944 Parameter_Associations => New_List (
3945 Convert_To (Standard_Integer, Base),
3946 Make_Integer_Literal (Loc, Modulus (Rtyp)),
3949 -- Binary case, in this case, we call one of two routines, either
3950 -- the unsigned integer case, or the unsigned long long integer
3951 -- case, with a final "and" operation to do the required mod.
3954 if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
3955 Ent := RTE (RE_Exp_Unsigned);
3957 Ent := RTE (RE_Exp_Long_Long_Unsigned);
3964 Make_Function_Call (Loc,
3965 Name => New_Reference_To (Ent, Loc),
3966 Parameter_Associations => New_List (
3967 Convert_To (Etype (First_Formal (Ent)), Base),
3970 Make_Integer_Literal (Loc, Modulus (Rtyp) - 1))));
3974 -- Common exit point for modular type case
3976 Analyze_And_Resolve (N, Typ);
3979 -- Signed integer cases, done using either Integer or Long_Long_Integer.
3980 -- It is not worth having routines for Short_[Short_]Integer, since for
3981 -- most machines it would not help, and it would generate more code that
3982 -- might need certification in the HI-E case.
3984 -- In the integer cases, we have two routines, one for when overflow
3985 -- checks are required, and one when they are not required, since
3986 -- there is a real gain in ommitting checks on many machines.
3988 elsif Rtyp = Base_Type (Standard_Long_Long_Integer)
3989 or else (Rtyp = Base_Type (Standard_Long_Integer)
3991 Esize (Standard_Long_Integer) > Esize (Standard_Integer))
3992 or else (Rtyp = Universal_Integer)
3994 Etyp := Standard_Long_Long_Integer;
3997 Rent := RE_Exp_Long_Long_Integer;
3999 Rent := RE_Exn_Long_Long_Integer;
4002 elsif Is_Signed_Integer_Type (Rtyp) then
4003 Etyp := Standard_Integer;
4006 Rent := RE_Exp_Integer;
4008 Rent := RE_Exn_Integer;
4011 -- Floating-point cases, always done using Long_Long_Float. We do not
4012 -- need separate routines for the overflow case here, since in the case
4013 -- of floating-point, we generate infinities anyway as a rule (either
4014 -- that or we automatically trap overflow), and if there is an infinity
4015 -- generated and a range check is required, the check will fail anyway.
4018 pragma Assert (Is_Floating_Point_Type (Rtyp));
4019 Etyp := Standard_Long_Long_Float;
4020 Rent := RE_Exn_Long_Long_Float;
4023 -- Common processing for integer cases and floating-point cases.
4024 -- If we are in the right type, we can call runtime routine directly
4027 and then Rtyp /= Universal_Integer
4028 and then Rtyp /= Universal_Real
4031 Make_Function_Call (Loc,
4032 Name => New_Reference_To (RTE (Rent), Loc),
4033 Parameter_Associations => New_List (Base, Exp)));
4035 -- Otherwise we have to introduce conversions (conversions are also
4036 -- required in the universal cases, since the runtime routine is
4037 -- typed using one of the standard types.
4042 Make_Function_Call (Loc,
4043 Name => New_Reference_To (RTE (Rent), Loc),
4044 Parameter_Associations => New_List (
4045 Convert_To (Etyp, Base),
4049 Analyze_And_Resolve (N, Typ);
4053 when RE_Not_Available =>
4055 end Expand_N_Op_Expon;
4057 --------------------
4058 -- Expand_N_Op_Ge --
4059 --------------------
4061 procedure Expand_N_Op_Ge (N : Node_Id) is
4062 Typ : constant Entity_Id := Etype (N);
4063 Op1 : constant Node_Id := Left_Opnd (N);
4064 Op2 : constant Node_Id := Right_Opnd (N);
4065 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
4068 Binary_Op_Validity_Checks (N);
4070 if Vax_Float (Typ1) then
4071 Expand_Vax_Comparison (N);
4074 elsif Is_Array_Type (Typ1) then
4075 Expand_Array_Comparison (N);
4079 if Is_Boolean_Type (Typ1) then
4080 Adjust_Condition (Op1);
4081 Adjust_Condition (Op2);
4082 Set_Etype (N, Standard_Boolean);
4083 Adjust_Result_Type (N, Typ);
4086 Rewrite_Comparison (N);
4089 --------------------
4090 -- Expand_N_Op_Gt --
4091 --------------------
4093 procedure Expand_N_Op_Gt (N : Node_Id) is
4094 Typ : constant Entity_Id := Etype (N);
4095 Op1 : constant Node_Id := Left_Opnd (N);
4096 Op2 : constant Node_Id := Right_Opnd (N);
4097 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
4100 Binary_Op_Validity_Checks (N);
4102 if Vax_Float (Typ1) then
4103 Expand_Vax_Comparison (N);
4106 elsif Is_Array_Type (Typ1) then
4107 Expand_Array_Comparison (N);
4111 if Is_Boolean_Type (Typ1) then
4112 Adjust_Condition (Op1);
4113 Adjust_Condition (Op2);
4114 Set_Etype (N, Standard_Boolean);
4115 Adjust_Result_Type (N, Typ);
4118 Rewrite_Comparison (N);
4121 --------------------
4122 -- Expand_N_Op_Le --
4123 --------------------
4125 procedure Expand_N_Op_Le (N : Node_Id) is
4126 Typ : constant Entity_Id := Etype (N);
4127 Op1 : constant Node_Id := Left_Opnd (N);
4128 Op2 : constant Node_Id := Right_Opnd (N);
4129 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
4132 Binary_Op_Validity_Checks (N);
4134 if Vax_Float (Typ1) then
4135 Expand_Vax_Comparison (N);
4138 elsif Is_Array_Type (Typ1) then
4139 Expand_Array_Comparison (N);
4143 if Is_Boolean_Type (Typ1) then
4144 Adjust_Condition (Op1);
4145 Adjust_Condition (Op2);
4146 Set_Etype (N, Standard_Boolean);
4147 Adjust_Result_Type (N, Typ);
4150 Rewrite_Comparison (N);
4153 --------------------
4154 -- Expand_N_Op_Lt --
4155 --------------------
4157 procedure Expand_N_Op_Lt (N : Node_Id) is
4158 Typ : constant Entity_Id := Etype (N);
4159 Op1 : constant Node_Id := Left_Opnd (N);
4160 Op2 : constant Node_Id := Right_Opnd (N);
4161 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
4164 Binary_Op_Validity_Checks (N);
4166 if Vax_Float (Typ1) then
4167 Expand_Vax_Comparison (N);
4170 elsif Is_Array_Type (Typ1) then
4171 Expand_Array_Comparison (N);
4175 if Is_Boolean_Type (Typ1) then
4176 Adjust_Condition (Op1);
4177 Adjust_Condition (Op2);
4178 Set_Etype (N, Standard_Boolean);
4179 Adjust_Result_Type (N, Typ);
4182 Rewrite_Comparison (N);
4185 -----------------------
4186 -- Expand_N_Op_Minus --
4187 -----------------------
4189 procedure Expand_N_Op_Minus (N : Node_Id) is
4190 Loc : constant Source_Ptr := Sloc (N);
4191 Typ : constant Entity_Id := Etype (N);
4194 Unary_Op_Validity_Checks (N);
4196 if not Backend_Overflow_Checks_On_Target
4197 and then Is_Signed_Integer_Type (Etype (N))
4198 and then Do_Overflow_Check (N)
4200 -- Software overflow checking expands -expr into (0 - expr)
4203 Make_Op_Subtract (Loc,
4204 Left_Opnd => Make_Integer_Literal (Loc, 0),
4205 Right_Opnd => Right_Opnd (N)));
4207 Analyze_And_Resolve (N, Typ);
4209 -- Vax floating-point types case
4211 elsif Vax_Float (Etype (N)) then
4212 Expand_Vax_Arith (N);
4214 end Expand_N_Op_Minus;
4216 ---------------------
4217 -- Expand_N_Op_Mod --
4218 ---------------------
4220 procedure Expand_N_Op_Mod (N : Node_Id) is
4221 Loc : constant Source_Ptr := Sloc (N);
4222 Typ : constant Entity_Id := Etype (N);
4223 Left : constant Node_Id := Left_Opnd (N);
4224 Right : constant Node_Id := Right_Opnd (N);
4225 DOC : constant Boolean := Do_Overflow_Check (N);
4226 DDC : constant Boolean := Do_Division_Check (N);
4237 Binary_Op_Validity_Checks (N);
4239 Determine_Range (Right, ROK, Rlo, Rhi);
4240 Determine_Range (Left, LOK, Llo, Lhi);
4242 -- Convert mod to rem if operands are known non-negative. We do this
4243 -- since it is quite likely that this will improve the quality of code,
4244 -- (the operation now corresponds to the hardware remainder), and it
4245 -- does not seem likely that it could be harmful.
4247 if LOK and then Llo >= 0
4249 ROK and then Rlo >= 0
4252 Make_Op_Rem (Sloc (N),
4253 Left_Opnd => Left_Opnd (N),
4254 Right_Opnd => Right_Opnd (N)));
4256 -- Instead of reanalyzing the node we do the analysis manually.
4257 -- This avoids anomalies when the replacement is done in an
4258 -- instance and is epsilon more efficient.
4260 Set_Entity (N, Standard_Entity (S_Op_Rem));
4262 Set_Do_Overflow_Check (N, DOC);
4263 Set_Do_Division_Check (N, DDC);
4264 Expand_N_Op_Rem (N);
4267 -- Otherwise, normal mod processing
4270 if Is_Integer_Type (Etype (N)) then
4271 Apply_Divide_Check (N);
4274 -- Apply optimization x mod 1 = 0. We don't really need that with
4275 -- gcc, but it is useful with other back ends (e.g. AAMP), and is
4276 -- certainly harmless.
4278 if Is_Integer_Type (Etype (N))
4279 and then Compile_Time_Known_Value (Right)
4280 and then Expr_Value (Right) = Uint_1
4282 Rewrite (N, Make_Integer_Literal (Loc, 0));
4283 Analyze_And_Resolve (N, Typ);
4287 -- Deal with annoying case of largest negative number remainder
4288 -- minus one. Gigi does not handle this case correctly, because
4289 -- it generates a divide instruction which may trap in this case.
4291 -- In fact the check is quite easy, if the right operand is -1,
4292 -- then the mod value is always 0, and we can just ignore the
4293 -- left operand completely in this case.
4295 -- The operand type may be private (e.g. in the expansion of an
4296 -- an intrinsic operation) so we must use the underlying type to
4297 -- get the bounds, and convert the literals explicitly.
4301 (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
4303 if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
4305 ((not LOK) or else (Llo = LLB))
4308 Make_Conditional_Expression (Loc,
4309 Expressions => New_List (
4311 Left_Opnd => Duplicate_Subexpr (Right),
4313 Unchecked_Convert_To (Typ,
4314 Make_Integer_Literal (Loc, -1))),
4315 Unchecked_Convert_To (Typ,
4316 Make_Integer_Literal (Loc, Uint_0)),
4317 Relocate_Node (N))));
4319 Set_Analyzed (Next (Next (First (Expressions (N)))));
4320 Analyze_And_Resolve (N, Typ);
4323 end Expand_N_Op_Mod;
4325 --------------------------
4326 -- Expand_N_Op_Multiply --
4327 --------------------------
4329 procedure Expand_N_Op_Multiply (N : Node_Id) is
4330 Loc : constant Source_Ptr := Sloc (N);
4331 Lop : constant Node_Id := Left_Opnd (N);
4332 Rop : constant Node_Id := Right_Opnd (N);
4334 Lp2 : constant Boolean :=
4335 Nkind (Lop) = N_Op_Expon
4336 and then Is_Power_Of_2_For_Shift (Lop);
4338 Rp2 : constant Boolean :=
4339 Nkind (Rop) = N_Op_Expon
4340 and then Is_Power_Of_2_For_Shift (Rop);
4342 Ltyp : constant Entity_Id := Etype (Lop);
4343 Rtyp : constant Entity_Id := Etype (Rop);
4344 Typ : Entity_Id := Etype (N);
4347 Binary_Op_Validity_Checks (N);
4349 -- Special optimizations for integer types
4351 if Is_Integer_Type (Typ) then
4353 -- N * 0 = 0 * N = 0 for integer types
4355 if (Compile_Time_Known_Value (Rop)
4356 and then Expr_Value (Rop) = Uint_0)
4358 (Compile_Time_Known_Value (Lop)
4359 and then Expr_Value (Lop) = Uint_0)
4361 Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
4362 Analyze_And_Resolve (N, Typ);
4366 -- N * 1 = 1 * N = N for integer types
4368 -- This optimisation is not done if we are going to
4369 -- rewrite the product 1 * 2 ** N to a shift.
4371 if Compile_Time_Known_Value (Rop)
4372 and then Expr_Value (Rop) = Uint_1
4378 elsif Compile_Time_Known_Value (Lop)
4379 and then Expr_Value (Lop) = Uint_1
4387 -- Deal with VAX float case
4389 if Vax_Float (Typ) then
4390 Expand_Vax_Arith (N);
4394 -- Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that
4395 -- Is_Power_Of_2_For_Shift is set means that we know that our left
4396 -- operand is an integer, as required for this to work.
4401 -- Convert 2 ** A * 2 ** B into 2 ** (A + B)
4405 Left_Opnd => Make_Integer_Literal (Loc, 2),
4408 Left_Opnd => Right_Opnd (Lop),
4409 Right_Opnd => Right_Opnd (Rop))));
4410 Analyze_And_Resolve (N, Typ);
4415 Make_Op_Shift_Left (Loc,
4418 Convert_To (Standard_Natural, Right_Opnd (Rop))));
4419 Analyze_And_Resolve (N, Typ);
4423 -- Same processing for the operands the other way round
4427 Make_Op_Shift_Left (Loc,
4430 Convert_To (Standard_Natural, Right_Opnd (Lop))));
4431 Analyze_And_Resolve (N, Typ);
4435 -- Do required fixup of universal fixed operation
4437 if Typ = Universal_Fixed then
4438 Fixup_Universal_Fixed_Operation (N);
4442 -- Multiplications with fixed-point results
4444 if Is_Fixed_Point_Type (Typ) then
4446 -- No special processing if Treat_Fixed_As_Integer is set,
4447 -- since from a semantic point of view such operations are
4448 -- simply integer operations and will be treated that way.
4450 if not Treat_Fixed_As_Integer (N) then
4452 -- Case of fixed * integer => fixed
4454 if Is_Integer_Type (Rtyp) then
4455 Expand_Multiply_Fixed_By_Integer_Giving_Fixed (N);
4457 -- Case of integer * fixed => fixed
4459 elsif Is_Integer_Type (Ltyp) then
4460 Expand_Multiply_Integer_By_Fixed_Giving_Fixed (N);
4462 -- Case of fixed * fixed => fixed
4465 Expand_Multiply_Fixed_By_Fixed_Giving_Fixed (N);
4469 -- Other cases of multiplication of fixed-point operands. Again
4470 -- we exclude the cases where Treat_Fixed_As_Integer flag is set.
4472 elsif (Is_Fixed_Point_Type (Ltyp) or else Is_Fixed_Point_Type (Rtyp))
4473 and then not Treat_Fixed_As_Integer (N)
4475 if Is_Integer_Type (Typ) then
4476 Expand_Multiply_Fixed_By_Fixed_Giving_Integer (N);
4478 pragma Assert (Is_Floating_Point_Type (Typ));
4479 Expand_Multiply_Fixed_By_Fixed_Giving_Float (N);
4482 -- Mixed-mode operations can appear in a non-static universal
4483 -- context, in which case the integer argument must be converted
4486 elsif Typ = Universal_Real
4487 and then Is_Integer_Type (Rtyp)
4489 Rewrite (Rop, Convert_To (Universal_Real, Relocate_Node (Rop)));
4491 Analyze_And_Resolve (Rop, Universal_Real);
4493 elsif Typ = Universal_Real
4494 and then Is_Integer_Type (Ltyp)
4496 Rewrite (Lop, Convert_To (Universal_Real, Relocate_Node (Lop)));
4498 Analyze_And_Resolve (Lop, Universal_Real);
4500 -- Non-fixed point cases, check software overflow checking required
4502 elsif Is_Signed_Integer_Type (Etype (N)) then
4503 Apply_Arithmetic_Overflow_Check (N);
4505 end Expand_N_Op_Multiply;
4507 --------------------
4508 -- Expand_N_Op_Ne --
4509 --------------------
4511 -- Rewrite node as the negation of an equality operation, and reanalyze.
4512 -- The equality to be used is defined in the same scope and has the same
4513 -- signature. It must be set explicitly because in an instance it may not
4514 -- have the same visibility as in the generic unit.
4516 procedure Expand_N_Op_Ne (N : Node_Id) is
4517 Loc : constant Source_Ptr := Sloc (N);
4519 Ne : constant Entity_Id := Entity (N);
4522 Binary_Op_Validity_Checks (N);
4528 Left_Opnd => Left_Opnd (N),
4529 Right_Opnd => Right_Opnd (N)));
4530 Set_Paren_Count (Right_Opnd (Neg), 1);
4532 if Scope (Ne) /= Standard_Standard then
4533 Set_Entity (Right_Opnd (Neg), Corresponding_Equality (Ne));
4536 -- For navigation purposes, the inequality is treated as an implicit
4537 -- reference to the corresponding equality. Preserve the Comes_From_
4538 -- source flag so that the proper Xref entry is generated.
4540 Preserve_Comes_From_Source (Neg, N);
4541 Preserve_Comes_From_Source (Right_Opnd (Neg), N);
4543 Analyze_And_Resolve (N, Standard_Boolean);
4546 ---------------------
4547 -- Expand_N_Op_Not --
4548 ---------------------
4550 -- If the argument is other than a Boolean array type, there is no
4551 -- special expansion required.
4553 -- For the packed case, we call the special routine in Exp_Pakd, except
4554 -- that if the component size is greater than one, we use the standard
4555 -- routine generating a gruesome loop (it is so peculiar to have packed
4556 -- arrays with non-standard Boolean representations anyway, so it does
4557 -- not matter that we do not handle this case efficiently).
4559 -- For the unpacked case (and for the special packed case where we have
4560 -- non standard Booleans, as discussed above), we generate and insert
4561 -- into the tree the following function definition:
4563 -- function Nnnn (A : arr) is
4566 -- for J in a'range loop
4567 -- B (J) := not A (J);
4572 -- Here arr is the actual subtype of the parameter (and hence always
4573 -- constrained). Then we replace the not with a call to this function.
4575 procedure Expand_N_Op_Not (N : Node_Id) is
4576 Loc : constant Source_Ptr := Sloc (N);
4577 Typ : constant Entity_Id := Etype (N);
4586 Func_Name : Entity_Id;
4587 Loop_Statement : Node_Id;
4590 Unary_Op_Validity_Checks (N);
4592 -- For boolean operand, deal with non-standard booleans
4594 if Is_Boolean_Type (Typ) then
4595 Adjust_Condition (Right_Opnd (N));
4596 Set_Etype (N, Standard_Boolean);
4597 Adjust_Result_Type (N, Typ);
4601 -- Only array types need any other processing
4603 if not Is_Array_Type (Typ) then
4607 -- Case of array operand. If bit packed, handle it in Exp_Pakd
4609 if Is_Bit_Packed_Array (Typ) and then Component_Size (Typ) = 1 then
4610 Expand_Packed_Not (N);
4614 -- Case of array operand which is not bit-packed. If the context is
4615 -- a safe assignment, call in-place operation, If context is a larger
4616 -- boolean expression in the context of a safe assignment, expansion is
4617 -- done by enclosing operation.
4619 Opnd := Relocate_Node (Right_Opnd (N));
4620 Convert_To_Actual_Subtype (Opnd);
4621 Arr := Etype (Opnd);
4622 Ensure_Defined (Arr, N);
4624 if Nkind (Parent (N)) = N_Assignment_Statement then
4625 if Safe_In_Place_Array_Op (Name (Parent (N)), N, Empty) then
4626 Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
4629 -- Special case the negation of a binary operation.
4631 elsif (Nkind (Opnd) = N_Op_And
4632 or else Nkind (Opnd) = N_Op_Or
4633 or else Nkind (Opnd) = N_Op_Xor)
4634 and then Safe_In_Place_Array_Op
4635 (Name (Parent (N)), Left_Opnd (Opnd), Right_Opnd (Opnd))
4637 Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
4641 elsif Nkind (Parent (N)) in N_Binary_Op
4642 and then Nkind (Parent (Parent (N))) = N_Assignment_Statement
4645 Op1 : constant Node_Id := Left_Opnd (Parent (N));
4646 Op2 : constant Node_Id := Right_Opnd (Parent (N));
4647 Lhs : constant Node_Id := Name (Parent (Parent (N)));
4650 if Safe_In_Place_Array_Op (Lhs, Op1, Op2) then
4652 and then Nkind (Op2) = N_Op_Not
4654 -- (not A) op (not B) can be reduced to a single call.
4659 and then Nkind (Parent (N)) = N_Op_Xor
4661 -- A xor (not B) can also be special-cased.
4669 A := Make_Defining_Identifier (Loc, Name_uA);
4670 B := Make_Defining_Identifier (Loc, Name_uB);
4671 J := Make_Defining_Identifier (Loc, Name_uJ);
4674 Make_Indexed_Component (Loc,
4675 Prefix => New_Reference_To (A, Loc),
4676 Expressions => New_List (New_Reference_To (J, Loc)));
4679 Make_Indexed_Component (Loc,
4680 Prefix => New_Reference_To (B, Loc),
4681 Expressions => New_List (New_Reference_To (J, Loc)));
4684 Make_Implicit_Loop_Statement (N,
4685 Identifier => Empty,
4688 Make_Iteration_Scheme (Loc,
4689 Loop_Parameter_Specification =>
4690 Make_Loop_Parameter_Specification (Loc,
4691 Defining_Identifier => J,
4692 Discrete_Subtype_Definition =>
4693 Make_Attribute_Reference (Loc,
4694 Prefix => Make_Identifier (Loc, Chars (A)),
4695 Attribute_Name => Name_Range))),
4697 Statements => New_List (
4698 Make_Assignment_Statement (Loc,
4700 Expression => Make_Op_Not (Loc, A_J))));
4702 Func_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('N'));
4703 Set_Is_Inlined (Func_Name);
4706 Make_Subprogram_Body (Loc,
4708 Make_Function_Specification (Loc,
4709 Defining_Unit_Name => Func_Name,
4710 Parameter_Specifications => New_List (
4711 Make_Parameter_Specification (Loc,
4712 Defining_Identifier => A,
4713 Parameter_Type => New_Reference_To (Typ, Loc))),
4714 Subtype_Mark => New_Reference_To (Typ, Loc)),
4716 Declarations => New_List (
4717 Make_Object_Declaration (Loc,
4718 Defining_Identifier => B,
4719 Object_Definition => New_Reference_To (Arr, Loc))),
4721 Handled_Statement_Sequence =>
4722 Make_Handled_Sequence_Of_Statements (Loc,
4723 Statements => New_List (
4725 Make_Return_Statement (Loc,
4727 Make_Identifier (Loc, Chars (B)))))));
4730 Make_Function_Call (Loc,
4731 Name => New_Reference_To (Func_Name, Loc),
4732 Parameter_Associations => New_List (Opnd)));
4734 Analyze_And_Resolve (N, Typ);
4735 end Expand_N_Op_Not;
4737 --------------------
4738 -- Expand_N_Op_Or --
4739 --------------------
4741 procedure Expand_N_Op_Or (N : Node_Id) is
4742 Typ : constant Entity_Id := Etype (N);
4745 Binary_Op_Validity_Checks (N);
4747 if Is_Array_Type (Etype (N)) then
4748 Expand_Boolean_Operator (N);
4750 elsif Is_Boolean_Type (Etype (N)) then
4751 Adjust_Condition (Left_Opnd (N));
4752 Adjust_Condition (Right_Opnd (N));
4753 Set_Etype (N, Standard_Boolean);
4754 Adjust_Result_Type (N, Typ);
4758 ----------------------
4759 -- Expand_N_Op_Plus --
4760 ----------------------
4762 procedure Expand_N_Op_Plus (N : Node_Id) is
4764 Unary_Op_Validity_Checks (N);
4765 end Expand_N_Op_Plus;
4767 ---------------------
4768 -- Expand_N_Op_Rem --
4769 ---------------------
4771 procedure Expand_N_Op_Rem (N : Node_Id) is
4772 Loc : constant Source_Ptr := Sloc (N);
4773 Typ : constant Entity_Id := Etype (N);
4775 Left : constant Node_Id := Left_Opnd (N);
4776 Right : constant Node_Id := Right_Opnd (N);
4787 Binary_Op_Validity_Checks (N);
4789 if Is_Integer_Type (Etype (N)) then
4790 Apply_Divide_Check (N);
4793 -- Apply optimization x rem 1 = 0. We don't really need that with
4794 -- gcc, but it is useful with other back ends (e.g. AAMP), and is
4795 -- certainly harmless.
4797 if Is_Integer_Type (Etype (N))
4798 and then Compile_Time_Known_Value (Right)
4799 and then Expr_Value (Right) = Uint_1
4801 Rewrite (N, Make_Integer_Literal (Loc, 0));
4802 Analyze_And_Resolve (N, Typ);
4806 -- Deal with annoying case of largest negative number remainder
4807 -- minus one. Gigi does not handle this case correctly, because
4808 -- it generates a divide instruction which may trap in this case.
4810 -- In fact the check is quite easy, if the right operand is -1,
4811 -- then the remainder is always 0, and we can just ignore the
4812 -- left operand completely in this case.
4814 Determine_Range (Right, ROK, Rlo, Rhi);
4815 Determine_Range (Left, LOK, Llo, Lhi);
4817 -- The operand type may be private (e.g. in the expansion of an
4818 -- an intrinsic operation) so we must use the underlying type to
4819 -- get the bounds, and convert the literals explicitly.
4823 (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
4825 -- Now perform the test, generating code only if needed
4827 if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
4829 ((not LOK) or else (Llo = LLB))
4832 Make_Conditional_Expression (Loc,
4833 Expressions => New_List (
4835 Left_Opnd => Duplicate_Subexpr (Right),
4837 Unchecked_Convert_To (Typ,
4838 Make_Integer_Literal (Loc, -1))),
4840 Unchecked_Convert_To (Typ,
4841 Make_Integer_Literal (Loc, Uint_0)),
4843 Relocate_Node (N))));
4845 Set_Analyzed (Next (Next (First (Expressions (N)))));
4846 Analyze_And_Resolve (N, Typ);
4848 end Expand_N_Op_Rem;
4850 -----------------------------
4851 -- Expand_N_Op_Rotate_Left --
4852 -----------------------------
4854 procedure Expand_N_Op_Rotate_Left (N : Node_Id) is
4856 Binary_Op_Validity_Checks (N);
4857 end Expand_N_Op_Rotate_Left;
4859 ------------------------------
4860 -- Expand_N_Op_Rotate_Right --
4861 ------------------------------
4863 procedure Expand_N_Op_Rotate_Right (N : Node_Id) is
4865 Binary_Op_Validity_Checks (N);
4866 end Expand_N_Op_Rotate_Right;
4868 ----------------------------
4869 -- Expand_N_Op_Shift_Left --
4870 ----------------------------
4872 procedure Expand_N_Op_Shift_Left (N : Node_Id) is
4874 Binary_Op_Validity_Checks (N);
4875 end Expand_N_Op_Shift_Left;
4877 -----------------------------
4878 -- Expand_N_Op_Shift_Right --
4879 -----------------------------
4881 procedure Expand_N_Op_Shift_Right (N : Node_Id) is
4883 Binary_Op_Validity_Checks (N);
4884 end Expand_N_Op_Shift_Right;
4886 ----------------------------------------
4887 -- Expand_N_Op_Shift_Right_Arithmetic --
4888 ----------------------------------------
4890 procedure Expand_N_Op_Shift_Right_Arithmetic (N : Node_Id) is
4892 Binary_Op_Validity_Checks (N);
4893 end Expand_N_Op_Shift_Right_Arithmetic;
4895 --------------------------
4896 -- Expand_N_Op_Subtract --
4897 --------------------------
4899 procedure Expand_N_Op_Subtract (N : Node_Id) is
4900 Typ : constant Entity_Id := Etype (N);
4903 Binary_Op_Validity_Checks (N);
4905 -- N - 0 = N for integer types
4907 if Is_Integer_Type (Typ)
4908 and then Compile_Time_Known_Value (Right_Opnd (N))
4909 and then Expr_Value (Right_Opnd (N)) = 0
4911 Rewrite (N, Left_Opnd (N));
4915 -- Arithemtic overflow checks for signed integer/fixed point types
4917 if Is_Signed_Integer_Type (Typ)
4918 or else Is_Fixed_Point_Type (Typ)
4920 Apply_Arithmetic_Overflow_Check (N);
4922 -- Vax floating-point types case
4924 elsif Vax_Float (Typ) then
4925 Expand_Vax_Arith (N);
4927 end Expand_N_Op_Subtract;
4929 ---------------------
4930 -- Expand_N_Op_Xor --
4931 ---------------------
4933 procedure Expand_N_Op_Xor (N : Node_Id) is
4934 Typ : constant Entity_Id := Etype (N);
4937 Binary_Op_Validity_Checks (N);
4939 if Is_Array_Type (Etype (N)) then
4940 Expand_Boolean_Operator (N);
4942 elsif Is_Boolean_Type (Etype (N)) then
4943 Adjust_Condition (Left_Opnd (N));
4944 Adjust_Condition (Right_Opnd (N));
4945 Set_Etype (N, Standard_Boolean);
4946 Adjust_Result_Type (N, Typ);
4948 end Expand_N_Op_Xor;
4950 ----------------------
4951 -- Expand_N_Or_Else --
4952 ----------------------
4954 -- Expand into conditional expression if Actions present, and also
4955 -- deal with optimizing case of arguments being True or False.
4957 procedure Expand_N_Or_Else (N : Node_Id) is
4958 Loc : constant Source_Ptr := Sloc (N);
4959 Typ : constant Entity_Id := Etype (N);
4960 Left : constant Node_Id := Left_Opnd (N);
4961 Right : constant Node_Id := Right_Opnd (N);
4965 -- Deal with non-standard booleans
4967 if Is_Boolean_Type (Typ) then
4968 Adjust_Condition (Left);
4969 Adjust_Condition (Right);
4970 Set_Etype (N, Standard_Boolean);
4973 -- Check for cases of left argument is True or False
4975 if Nkind (Left) = N_Identifier then
4977 -- If left argument is False, change (False or else Right) to Right.
4978 -- Any actions associated with Right will be executed unconditionally
4979 -- and can thus be inserted into the tree unconditionally.
4981 if Entity (Left) = Standard_False then
4982 if Present (Actions (N)) then
4983 Insert_Actions (N, Actions (N));
4987 Adjust_Result_Type (N, Typ);
4990 -- If left argument is True, change (True and then Right) to
4991 -- True. In this case we can forget the actions associated with
4992 -- Right, since they will never be executed.
4994 elsif Entity (Left) = Standard_True then
4995 Kill_Dead_Code (Right);
4996 Kill_Dead_Code (Actions (N));
4997 Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
4998 Adjust_Result_Type (N, Typ);
5003 -- If Actions are present, we expand
5005 -- left or else right
5009 -- if left then True else right end
5011 -- with the actions becoming the Else_Actions of the conditional
5012 -- expression. This conditional expression is then further expanded
5013 -- (and will eventually disappear)
5015 if Present (Actions (N)) then
5016 Actlist := Actions (N);
5018 Make_Conditional_Expression (Loc,
5019 Expressions => New_List (
5021 New_Occurrence_Of (Standard_True, Loc),
5024 Set_Else_Actions (N, Actlist);
5025 Analyze_And_Resolve (N, Standard_Boolean);
5026 Adjust_Result_Type (N, Typ);
5030 -- No actions present, check for cases of right argument True/False
5032 if Nkind (Right) = N_Identifier then
5034 -- Change (Left or else False) to Left. Note that we know there
5035 -- are no actions associated with the True operand, since we
5036 -- just checked for this case above.
5038 if Entity (Right) = Standard_False then
5041 -- Change (Left or else True) to True, making sure to preserve
5042 -- any side effects associated with the Left operand.
5044 elsif Entity (Right) = Standard_True then
5045 Remove_Side_Effects (Left);
5047 (N, New_Occurrence_Of (Standard_True, Loc));
5051 Adjust_Result_Type (N, Typ);
5052 end Expand_N_Or_Else;
5054 -----------------------------------
5055 -- Expand_N_Qualified_Expression --
5056 -----------------------------------
5058 procedure Expand_N_Qualified_Expression (N : Node_Id) is
5059 Operand : constant Node_Id := Expression (N);
5060 Target_Type : constant Entity_Id := Entity (Subtype_Mark (N));
5063 Apply_Constraint_Check (Operand, Target_Type, No_Sliding => True);
5064 end Expand_N_Qualified_Expression;
5066 ---------------------------------
5067 -- Expand_N_Selected_Component --
5068 ---------------------------------
5070 -- If the selector is a discriminant of a concurrent object, rewrite the
5071 -- prefix to denote the corresponding record type.
5073 procedure Expand_N_Selected_Component (N : Node_Id) is
5074 Loc : constant Source_Ptr := Sloc (N);
5075 Par : constant Node_Id := Parent (N);
5076 P : constant Node_Id := Prefix (N);
5077 Ptyp : Entity_Id := Underlying_Type (Etype (P));
5082 function In_Left_Hand_Side (Comp : Node_Id) return Boolean;
5083 -- Gigi needs a temporary for prefixes that depend on a discriminant,
5084 -- unless the context of an assignment can provide size information.
5085 -- Don't we have a general routine that does this???
5087 -----------------------
5088 -- In_Left_Hand_Side --
5089 -----------------------
5091 function In_Left_Hand_Side (Comp : Node_Id) return Boolean is
5093 return (Nkind (Parent (Comp)) = N_Assignment_Statement
5094 and then Comp = Name (Parent (Comp)))
5095 or else (Present (Parent (Comp))
5096 and then Nkind (Parent (Comp)) in N_Subexpr
5097 and then In_Left_Hand_Side (Parent (Comp)));
5098 end In_Left_Hand_Side;
5100 -- Start of processing for Expand_N_Selected_Component
5103 -- Insert explicit dereference if required
5105 if Is_Access_Type (Ptyp) then
5106 Insert_Explicit_Dereference (P);
5108 if Ekind (Etype (P)) = E_Private_Subtype
5109 and then Is_For_Access_Subtype (Etype (P))
5111 Set_Etype (P, Base_Type (Etype (P)));
5117 -- Deal with discriminant check required
5119 if Do_Discriminant_Check (N) then
5121 -- Present the discrminant checking function to the backend,
5122 -- so that it can inline the call to the function.
5125 (Discriminant_Checking_Func
5126 (Original_Record_Component (Entity (Selector_Name (N)))));
5128 -- Now reset the flag and generate the call
5130 Set_Do_Discriminant_Check (N, False);
5131 Generate_Discriminant_Check (N);
5134 -- Gigi cannot handle unchecked conversions that are the prefix of a
5135 -- selected component with discriminants. This must be checked during
5136 -- expansion, because during analysis the type of the selector is not
5137 -- known at the point the prefix is analyzed. If the conversion is the
5138 -- target of an assignment, then we cannot force the evaluation.
5140 if Nkind (Prefix (N)) = N_Unchecked_Type_Conversion
5141 and then Has_Discriminants (Etype (N))
5142 and then not In_Left_Hand_Side (N)
5144 Force_Evaluation (Prefix (N));
5147 -- Remaining processing applies only if selector is a discriminant
5149 if Ekind (Entity (Selector_Name (N))) = E_Discriminant then
5151 -- If the selector is a discriminant of a constrained record type,
5152 -- we may be able to rewrite the expression with the actual value
5153 -- of the discriminant, a useful optimization in some cases.
5155 if Is_Record_Type (Ptyp)
5156 and then Has_Discriminants (Ptyp)
5157 and then Is_Constrained (Ptyp)
5159 -- Do this optimization for discrete types only, and not for
5160 -- access types (access discriminants get us into trouble!)
5162 if not Is_Discrete_Type (Etype (N)) then
5165 -- Don't do this on the left hand of an assignment statement.
5166 -- Normally one would think that references like this would
5167 -- not occur, but they do in generated code, and mean that
5168 -- we really do want to assign the discriminant!
5170 elsif Nkind (Par) = N_Assignment_Statement
5171 and then Name (Par) = N
5175 -- Don't do this optimization for the prefix of an attribute
5176 -- or the operand of an object renaming declaration since these
5177 -- are contexts where we do not want the value anyway.
5179 elsif (Nkind (Par) = N_Attribute_Reference
5180 and then Prefix (Par) = N)
5181 or else Is_Renamed_Object (N)
5185 -- Don't do this optimization if we are within the code for a
5186 -- discriminant check, since the whole point of such a check may
5187 -- be to verify the condition on which the code below depends!
5189 elsif Is_In_Discriminant_Check (N) then
5192 -- Green light to see if we can do the optimization. There is
5193 -- still one condition that inhibits the optimization below
5194 -- but now is the time to check the particular discriminant.
5197 -- Loop through discriminants to find the matching
5198 -- discriminant constraint to see if we can copy it.
5200 Disc := First_Discriminant (Ptyp);
5201 Dcon := First_Elmt (Discriminant_Constraint (Ptyp));
5202 Discr_Loop : while Present (Dcon) loop
5204 -- Check if this is the matching discriminant
5206 if Disc = Entity (Selector_Name (N)) then
5208 -- Here we have the matching discriminant. Check for
5209 -- the case of a discriminant of a component that is
5210 -- constrained by an outer discriminant, which cannot
5211 -- be optimized away.
5214 Denotes_Discriminant
5215 (Node (Dcon), Check_Protected => True)
5219 -- In the context of a case statement, the expression
5220 -- may have the base type of the discriminant, and we
5221 -- need to preserve the constraint to avoid spurious
5222 -- errors on missing cases.
5224 elsif Nkind (Parent (N)) = N_Case_Statement
5225 and then Etype (Node (Dcon)) /= Etype (Disc)
5227 -- RBKD is suspicious of the following code. The
5228 -- call to New_Copy instead of New_Copy_Tree is
5229 -- suspicious, and the call to Analyze instead
5230 -- of Analyze_And_Resolve is also suspicious ???
5232 -- Wouldn't it be good enough to do a perfectly
5233 -- normal Analyze_And_Resolve call using the
5234 -- subtype of the discriminant here???
5237 Make_Qualified_Expression (Loc,
5239 New_Occurrence_Of (Etype (Disc), Loc),
5241 New_Copy (Node (Dcon))));
5244 -- In case that comes out as a static expression,
5245 -- reset it (a selected component is never static).
5247 Set_Is_Static_Expression (N, False);
5250 -- Otherwise we can just copy the constraint, but the
5251 -- result is certainly not static!
5253 -- Again the New_Copy here and the failure to even
5254 -- to an analyze call is uneasy ???
5257 Rewrite (N, New_Copy (Node (Dcon)));
5258 Set_Is_Static_Expression (N, False);
5264 Next_Discriminant (Disc);
5265 end loop Discr_Loop;
5267 -- Note: the above loop should always find a matching
5268 -- discriminant, but if it does not, we just missed an
5269 -- optimization due to some glitch (perhaps a previous
5270 -- error), so ignore.
5275 -- The only remaining processing is in the case of a discriminant of
5276 -- a concurrent object, where we rewrite the prefix to denote the
5277 -- corresponding record type. If the type is derived and has renamed
5278 -- discriminants, use corresponding discriminant, which is the one
5279 -- that appears in the corresponding record.
5281 if not Is_Concurrent_Type (Ptyp) then
5285 Disc := Entity (Selector_Name (N));
5287 if Is_Derived_Type (Ptyp)
5288 and then Present (Corresponding_Discriminant (Disc))
5290 Disc := Corresponding_Discriminant (Disc);
5294 Make_Selected_Component (Loc,
5296 Unchecked_Convert_To (Corresponding_Record_Type (Ptyp),
5298 Selector_Name => Make_Identifier (Loc, Chars (Disc)));
5303 end Expand_N_Selected_Component;
5305 --------------------
5306 -- Expand_N_Slice --
5307 --------------------
5309 procedure Expand_N_Slice (N : Node_Id) is
5310 Loc : constant Source_Ptr := Sloc (N);
5311 Typ : constant Entity_Id := Etype (N);
5312 Pfx : constant Node_Id := Prefix (N);
5313 Ptp : Entity_Id := Etype (Pfx);
5315 procedure Make_Temporary;
5316 -- Create a named variable for the value of the slice, in
5317 -- cases where the back-end cannot handle it properly, e.g.
5318 -- when packed types or unaligned slices are involved.
5320 --------------------
5321 -- Make_Temporary --
5322 --------------------
5324 procedure Make_Temporary is
5326 Ent : constant Entity_Id :=
5327 Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
5330 Make_Object_Declaration (Loc,
5331 Defining_Identifier => Ent,
5332 Object_Definition => New_Occurrence_Of (Typ, Loc));
5334 Set_No_Initialization (Decl);
5336 Insert_Actions (N, New_List (
5338 Make_Assignment_Statement (Loc,
5339 Name => New_Occurrence_Of (Ent, Loc),
5340 Expression => Relocate_Node (N))));
5342 Rewrite (N, New_Occurrence_Of (Ent, Loc));
5343 Analyze_And_Resolve (N, Typ);
5346 -- Start of processing for Expand_N_Slice
5349 -- Special handling for access types
5351 if Is_Access_Type (Ptp) then
5353 -- Check for explicit dereference required for checked pool
5355 Insert_Dereference_Action (Pfx);
5357 -- If we have an access to a packed array type, then put in an
5358 -- explicit dereference. We do this in case the slice must be
5359 -- expanded, and we want to make sure we get an access check.
5361 Ptp := Designated_Type (Ptp);
5363 if Is_Array_Type (Ptp) and then Is_Packed (Ptp) then
5365 Make_Explicit_Dereference (Sloc (N),
5366 Prefix => Relocate_Node (Pfx)));
5368 Analyze_And_Resolve (Pfx, Ptp);
5372 -- Range checks are potentially also needed for cases involving
5373 -- a slice indexed by a subtype indication, but Do_Range_Check
5374 -- can currently only be set for expressions ???
5376 if not Index_Checks_Suppressed (Ptp)
5377 and then (not Is_Entity_Name (Pfx)
5378 or else not Index_Checks_Suppressed (Entity (Pfx)))
5379 and then Nkind (Discrete_Range (N)) /= N_Subtype_Indication
5381 Enable_Range_Check (Discrete_Range (N));
5384 -- The remaining case to be handled is packed slices. We can leave
5385 -- packed slices as they are in the following situations:
5387 -- 1. Right or left side of an assignment (we can handle this
5388 -- situation correctly in the assignment statement expansion).
5390 -- 2. Prefix of indexed component (the slide is optimized away
5391 -- in this case, see the start of Expand_N_Slice.
5393 -- 3. Object renaming declaration, since we want the name of
5394 -- the slice, not the value.
5396 -- 4. Argument to procedure call, since copy-in/copy-out handling
5397 -- may be required, and this is handled in the expansion of
5400 -- 5. Prefix of an address attribute (this is an error which
5401 -- is caught elsewhere, and the expansion would intefere
5402 -- with generating the error message).
5405 and then Nkind (Parent (N)) /= N_Assignment_Statement
5406 and then (Nkind (Parent (Parent (N))) /= N_Assignment_Statement
5408 Parent (N) /= Name (Parent (Parent (N))))
5409 and then Nkind (Parent (N)) /= N_Indexed_Component
5410 and then not Is_Renamed_Object (N)
5411 and then Nkind (Parent (N)) /= N_Procedure_Call_Statement
5412 and then (Nkind (Parent (N)) /= N_Attribute_Reference
5414 Attribute_Name (Parent (N)) /= Name_Address)
5418 -- Same transformation for actuals in a function call, where
5419 -- Expand_Actuals is not used.
5421 elsif Nkind (Parent (N)) = N_Function_Call
5422 and then Is_Possibly_Unaligned_Slice (N)
5428 ------------------------------
5429 -- Expand_N_Type_Conversion --
5430 ------------------------------
5432 procedure Expand_N_Type_Conversion (N : Node_Id) is
5433 Loc : constant Source_Ptr := Sloc (N);
5434 Operand : constant Node_Id := Expression (N);
5435 Target_Type : constant Entity_Id := Etype (N);
5436 Operand_Type : Entity_Id := Etype (Operand);
5438 procedure Handle_Changed_Representation;
5439 -- This is called in the case of record and array type conversions
5440 -- to see if there is a change of representation to be handled.
5441 -- Change of representation is actually handled at the assignment
5442 -- statement level, and what this procedure does is rewrite node N
5443 -- conversion as an assignment to temporary. If there is no change
5444 -- of representation, then the conversion node is unchanged.
5446 procedure Real_Range_Check;
5447 -- Handles generation of range check for real target value
5449 -----------------------------------
5450 -- Handle_Changed_Representation --
5451 -----------------------------------
5453 procedure Handle_Changed_Representation is
5462 -- Nothing to do if no change of representation
5464 if Same_Representation (Operand_Type, Target_Type) then
5467 -- The real change of representation work is done by the assignment
5468 -- statement processing. So if this type conversion is appearing as
5469 -- the expression of an assignment statement, nothing needs to be
5470 -- done to the conversion.
5472 elsif Nkind (Parent (N)) = N_Assignment_Statement then
5475 -- Otherwise we need to generate a temporary variable, and do the
5476 -- change of representation assignment into that temporary variable.
5477 -- The conversion is then replaced by a reference to this variable.
5482 -- If type is unconstrained we have to add a constraint,
5483 -- copied from the actual value of the left hand side.
5485 if not Is_Constrained (Target_Type) then
5486 if Has_Discriminants (Operand_Type) then
5487 Disc := First_Discriminant (Operand_Type);
5489 if Disc /= First_Stored_Discriminant (Operand_Type) then
5490 Disc := First_Stored_Discriminant (Operand_Type);
5494 while Present (Disc) loop
5496 Make_Selected_Component (Loc,
5497 Prefix => Duplicate_Subexpr_Move_Checks (Operand),
5499 Make_Identifier (Loc, Chars (Disc))));
5500 Next_Discriminant (Disc);
5503 elsif Is_Array_Type (Operand_Type) then
5504 N_Ix := First_Index (Target_Type);
5507 for J in 1 .. Number_Dimensions (Operand_Type) loop
5509 -- We convert the bounds explicitly. We use an unchecked
5510 -- conversion because bounds checks are done elsewhere.
5515 Unchecked_Convert_To (Etype (N_Ix),
5516 Make_Attribute_Reference (Loc,
5518 Duplicate_Subexpr_No_Checks
5519 (Operand, Name_Req => True),
5520 Attribute_Name => Name_First,
5521 Expressions => New_List (
5522 Make_Integer_Literal (Loc, J)))),
5525 Unchecked_Convert_To (Etype (N_Ix),
5526 Make_Attribute_Reference (Loc,
5528 Duplicate_Subexpr_No_Checks
5529 (Operand, Name_Req => True),
5530 Attribute_Name => Name_Last,
5531 Expressions => New_List (
5532 Make_Integer_Literal (Loc, J))))));
5539 Odef := New_Occurrence_Of (Target_Type, Loc);
5541 if Present (Cons) then
5543 Make_Subtype_Indication (Loc,
5544 Subtype_Mark => Odef,
5546 Make_Index_Or_Discriminant_Constraint (Loc,
5547 Constraints => Cons));
5550 Temp := Make_Defining_Identifier (Loc, New_Internal_Name ('C'));
5552 Make_Object_Declaration (Loc,
5553 Defining_Identifier => Temp,
5554 Object_Definition => Odef);
5556 Set_No_Initialization (Decl, True);
5558 -- Insert required actions. It is essential to suppress checks
5559 -- since we have suppressed default initialization, which means
5560 -- that the variable we create may have no discriminants.
5565 Make_Assignment_Statement (Loc,
5566 Name => New_Occurrence_Of (Temp, Loc),
5567 Expression => Relocate_Node (N))),
5568 Suppress => All_Checks);
5570 Rewrite (N, New_Occurrence_Of (Temp, Loc));
5573 end Handle_Changed_Representation;
5575 ----------------------
5576 -- Real_Range_Check --
5577 ----------------------
5579 -- Case of conversions to floating-point or fixed-point. If range
5580 -- checks are enabled and the target type has a range constraint,
5587 -- Tnn : typ'Base := typ'Base (x);
5588 -- [constraint_error when Tnn < typ'First or else Tnn > typ'Last]
5591 -- This is necessary when there is a conversion of integer to float
5592 -- or to fixed-point to ensure that the correct checks are made. It
5593 -- is not necessary for float to float where it is enough to simply
5594 -- set the Do_Range_Check flag.
5596 procedure Real_Range_Check is
5597 Btyp : constant Entity_Id := Base_Type (Target_Type);
5598 Lo : constant Node_Id := Type_Low_Bound (Target_Type);
5599 Hi : constant Node_Id := Type_High_Bound (Target_Type);
5600 Xtyp : constant Entity_Id := Etype (Operand);
5605 -- Nothing to do if conversion was rewritten
5607 if Nkind (N) /= N_Type_Conversion then
5611 -- Nothing to do if range checks suppressed, or target has the
5612 -- same range as the base type (or is the base type).
5614 if Range_Checks_Suppressed (Target_Type)
5615 or else (Lo = Type_Low_Bound (Btyp)
5617 Hi = Type_High_Bound (Btyp))
5622 -- Nothing to do if expression is an entity on which checks
5623 -- have been suppressed.
5625 if Is_Entity_Name (Operand)
5626 and then Range_Checks_Suppressed (Entity (Operand))
5631 -- Nothing to do if bounds are all static and we can tell that
5632 -- the expression is within the bounds of the target. Note that
5633 -- if the operand is of an unconstrained floating-point type,
5634 -- then we do not trust it to be in range (might be infinite)
5637 S_Lo : constant Node_Id := Type_Low_Bound (Xtyp);
5638 S_Hi : constant Node_Id := Type_High_Bound (Xtyp);
5641 if (not Is_Floating_Point_Type (Xtyp)
5642 or else Is_Constrained (Xtyp))
5643 and then Compile_Time_Known_Value (S_Lo)
5644 and then Compile_Time_Known_Value (S_Hi)
5645 and then Compile_Time_Known_Value (Hi)
5646 and then Compile_Time_Known_Value (Lo)
5649 D_Lov : constant Ureal := Expr_Value_R (Lo);
5650 D_Hiv : constant Ureal := Expr_Value_R (Hi);
5655 if Is_Real_Type (Xtyp) then
5656 S_Lov := Expr_Value_R (S_Lo);
5657 S_Hiv := Expr_Value_R (S_Hi);
5659 S_Lov := UR_From_Uint (Expr_Value (S_Lo));
5660 S_Hiv := UR_From_Uint (Expr_Value (S_Hi));
5664 and then S_Lov >= D_Lov
5665 and then S_Hiv <= D_Hiv
5667 Set_Do_Range_Check (Operand, False);
5674 -- For float to float conversions, we are done
5676 if Is_Floating_Point_Type (Xtyp)
5678 Is_Floating_Point_Type (Btyp)
5683 -- Otherwise rewrite the conversion as described above
5685 Conv := Relocate_Node (N);
5687 (Subtype_Mark (Conv), New_Occurrence_Of (Btyp, Loc));
5688 Set_Etype (Conv, Btyp);
5690 -- Enable overflow except in the case of integer to float
5691 -- conversions, where it is never required, since we can
5692 -- never have overflow in this case.
5694 if not Is_Integer_Type (Etype (Operand)) then
5695 Enable_Overflow_Check (Conv);
5699 Make_Defining_Identifier (Loc,
5700 Chars => New_Internal_Name ('T'));
5702 Insert_Actions (N, New_List (
5703 Make_Object_Declaration (Loc,
5704 Defining_Identifier => Tnn,
5705 Object_Definition => New_Occurrence_Of (Btyp, Loc),
5706 Expression => Conv),
5708 Make_Raise_Constraint_Error (Loc,
5713 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
5715 Make_Attribute_Reference (Loc,
5716 Attribute_Name => Name_First,
5718 New_Occurrence_Of (Target_Type, Loc))),
5722 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
5724 Make_Attribute_Reference (Loc,
5725 Attribute_Name => Name_Last,
5727 New_Occurrence_Of (Target_Type, Loc)))),
5728 Reason => CE_Range_Check_Failed)));
5730 Rewrite (N, New_Occurrence_Of (Tnn, Loc));
5731 Analyze_And_Resolve (N, Btyp);
5732 end Real_Range_Check;
5734 -- Start of processing for Expand_N_Type_Conversion
5737 -- Nothing at all to do if conversion is to the identical type
5738 -- so remove the conversion completely, it is useless.
5740 if Operand_Type = Target_Type then
5741 Rewrite (N, Relocate_Node (Operand));
5745 -- Deal with Vax floating-point cases
5747 if Vax_Float (Operand_Type) or else Vax_Float (Target_Type) then
5748 Expand_Vax_Conversion (N);
5752 -- Nothing to do if this is the second argument of read. This
5753 -- is a "backwards" conversion that will be handled by the
5754 -- specialized code in attribute processing.
5756 if Nkind (Parent (N)) = N_Attribute_Reference
5757 and then Attribute_Name (Parent (N)) = Name_Read
5758 and then Next (First (Expressions (Parent (N)))) = N
5763 -- Here if we may need to expand conversion
5765 -- Special case of converting from non-standard boolean type
5767 if Is_Boolean_Type (Operand_Type)
5768 and then (Nonzero_Is_True (Operand_Type))
5770 Adjust_Condition (Operand);
5771 Set_Etype (Operand, Standard_Boolean);
5772 Operand_Type := Standard_Boolean;
5775 -- Case of converting to an access type
5777 if Is_Access_Type (Target_Type) then
5779 -- Apply an accessibility check if the operand is an
5780 -- access parameter. Note that other checks may still
5781 -- need to be applied below (such as tagged type checks).
5783 if Is_Entity_Name (Operand)
5784 and then Ekind (Entity (Operand)) in Formal_Kind
5785 and then Ekind (Etype (Operand)) = E_Anonymous_Access_Type
5787 Apply_Accessibility_Check (Operand, Target_Type);
5789 -- If the level of the operand type is statically deeper
5790 -- then the level of the target type, then force Program_Error.
5791 -- Note that this can only occur for cases where the attribute
5792 -- is within the body of an instantiation (otherwise the
5793 -- conversion will already have been rejected as illegal).
5794 -- Note: warnings are issued by the analyzer for the instance
5797 elsif In_Instance_Body
5798 and then Type_Access_Level (Operand_Type) >
5799 Type_Access_Level (Target_Type)
5802 Make_Raise_Program_Error (Sloc (N),
5803 Reason => PE_Accessibility_Check_Failed));
5804 Set_Etype (N, Target_Type);
5806 -- When the operand is a selected access discriminant
5807 -- the check needs to be made against the level of the
5808 -- object denoted by the prefix of the selected name.
5809 -- Force Program_Error for this case as well (this
5810 -- accessibility violation can only happen if within
5811 -- the body of an instantiation).
5813 elsif In_Instance_Body
5814 and then Ekind (Operand_Type) = E_Anonymous_Access_Type
5815 and then Nkind (Operand) = N_Selected_Component
5816 and then Object_Access_Level (Operand) >
5817 Type_Access_Level (Target_Type)
5820 Make_Raise_Program_Error (Sloc (N),
5821 Reason => PE_Accessibility_Check_Failed));
5822 Set_Etype (N, Target_Type);
5826 -- Case of conversions of tagged types and access to tagged types
5828 -- When needed, that is to say when the expression is class-wide,
5829 -- Add runtime a tag check for (strict) downward conversion by using
5830 -- the membership test, generating:
5832 -- [constraint_error when Operand not in Target_Type'Class]
5834 -- or in the access type case
5836 -- [constraint_error
5837 -- when Operand /= null
5838 -- and then Operand.all not in
5839 -- Designated_Type (Target_Type)'Class]
5841 if (Is_Access_Type (Target_Type)
5842 and then Is_Tagged_Type (Designated_Type (Target_Type)))
5843 or else Is_Tagged_Type (Target_Type)
5845 -- Do not do any expansion in the access type case if the
5846 -- parent is a renaming, since this is an error situation
5847 -- which will be caught by Sem_Ch8, and the expansion can
5848 -- intefere with this error check.
5850 if Is_Access_Type (Target_Type)
5851 and then Is_Renamed_Object (N)
5856 -- Oherwise, proceed with processing tagged conversion
5859 Actual_Operand_Type : Entity_Id;
5860 Actual_Target_Type : Entity_Id;
5865 if Is_Access_Type (Target_Type) then
5866 Actual_Operand_Type := Designated_Type (Operand_Type);
5867 Actual_Target_Type := Designated_Type (Target_Type);
5870 Actual_Operand_Type := Operand_Type;
5871 Actual_Target_Type := Target_Type;
5874 if Is_Class_Wide_Type (Actual_Operand_Type)
5875 and then Root_Type (Actual_Operand_Type) /= Actual_Target_Type
5876 and then Is_Ancestor
5877 (Root_Type (Actual_Operand_Type),
5879 and then not Tag_Checks_Suppressed (Actual_Target_Type)
5881 -- The conversion is valid for any descendant of the
5884 Actual_Target_Type := Class_Wide_Type (Actual_Target_Type);
5886 if Is_Access_Type (Target_Type) then
5891 Left_Opnd => Duplicate_Subexpr_No_Checks (Operand),
5892 Right_Opnd => Make_Null (Loc)),
5897 Make_Explicit_Dereference (Loc,
5899 Duplicate_Subexpr_No_Checks (Operand)),
5901 New_Reference_To (Actual_Target_Type, Loc)));
5906 Left_Opnd => Duplicate_Subexpr_No_Checks (Operand),
5908 New_Reference_To (Actual_Target_Type, Loc));
5912 Make_Raise_Constraint_Error (Loc,
5914 Reason => CE_Tag_Check_Failed));
5916 Change_Conversion_To_Unchecked (N);
5917 Analyze_And_Resolve (N, Target_Type);
5921 -- Case of other access type conversions
5923 elsif Is_Access_Type (Target_Type) then
5924 Apply_Constraint_Check (Operand, Target_Type);
5926 -- Case of conversions from a fixed-point type
5928 -- These conversions require special expansion and processing, found
5929 -- in the Exp_Fixd package. We ignore cases where Conversion_OK is
5930 -- set, since from a semantic point of view, these are simple integer
5931 -- conversions, which do not need further processing.
5933 elsif Is_Fixed_Point_Type (Operand_Type)
5934 and then not Conversion_OK (N)
5936 -- We should never see universal fixed at this case, since the
5937 -- expansion of the constituent divide or multiply should have
5938 -- eliminated the explicit mention of universal fixed.
5940 pragma Assert (Operand_Type /= Universal_Fixed);
5942 -- Check for special case of the conversion to universal real
5943 -- that occurs as a result of the use of a round attribute.
5944 -- In this case, the real type for the conversion is taken
5945 -- from the target type of the Round attribute and the
5946 -- result must be marked as rounded.
5948 if Target_Type = Universal_Real
5949 and then Nkind (Parent (N)) = N_Attribute_Reference
5950 and then Attribute_Name (Parent (N)) = Name_Round
5952 Set_Rounded_Result (N);
5953 Set_Etype (N, Etype (Parent (N)));
5956 -- Otherwise do correct fixed-conversion, but skip these if the
5957 -- Conversion_OK flag is set, because from a semantic point of
5958 -- view these are simple integer conversions needing no further
5959 -- processing (the backend will simply treat them as integers)
5961 if not Conversion_OK (N) then
5962 if Is_Fixed_Point_Type (Etype (N)) then
5963 Expand_Convert_Fixed_To_Fixed (N);
5966 elsif Is_Integer_Type (Etype (N)) then
5967 Expand_Convert_Fixed_To_Integer (N);
5970 pragma Assert (Is_Floating_Point_Type (Etype (N)));
5971 Expand_Convert_Fixed_To_Float (N);
5976 -- Case of conversions to a fixed-point type
5978 -- These conversions require special expansion and processing, found
5979 -- in the Exp_Fixd package. Again, ignore cases where Conversion_OK
5980 -- is set, since from a semantic point of view, these are simple
5981 -- integer conversions, which do not need further processing.
5983 elsif Is_Fixed_Point_Type (Target_Type)
5984 and then not Conversion_OK (N)
5986 if Is_Integer_Type (Operand_Type) then
5987 Expand_Convert_Integer_To_Fixed (N);
5990 pragma Assert (Is_Floating_Point_Type (Operand_Type));
5991 Expand_Convert_Float_To_Fixed (N);
5995 -- Case of float-to-integer conversions
5997 -- We also handle float-to-fixed conversions with Conversion_OK set
5998 -- since semantically the fixed-point target is treated as though it
5999 -- were an integer in such cases.
6001 elsif Is_Floating_Point_Type (Operand_Type)
6003 (Is_Integer_Type (Target_Type)
6005 (Is_Fixed_Point_Type (Target_Type) and then Conversion_OK (N)))
6007 -- Special processing required if the conversion is the expression
6008 -- of a Truncation attribute reference. In this case we replace:
6010 -- ityp (ftyp'Truncation (x))
6016 -- with the Float_Truncate flag set. This is clearly more efficient.
6018 if Nkind (Operand) = N_Attribute_Reference
6019 and then Attribute_Name (Operand) = Name_Truncation
6022 Relocate_Node (First (Expressions (Operand))));
6023 Set_Float_Truncate (N, True);
6026 -- One more check here, gcc is still not able to do conversions of
6027 -- this type with proper overflow checking, and so gigi is doing an
6028 -- approximation of what is required by doing floating-point compares
6029 -- with the end-point. But that can lose precision in some cases, and
6030 -- give a wrong result. Converting the operand to Long_Long_Float is
6031 -- helpful, but still does not catch all cases with 64-bit integers
6032 -- on targets with only 64-bit floats ???
6034 if Do_Range_Check (Operand) then
6036 Make_Type_Conversion (Loc,
6038 New_Occurrence_Of (Standard_Long_Long_Float, Loc),
6040 Relocate_Node (Operand)));
6042 Set_Etype (Operand, Standard_Long_Long_Float);
6043 Enable_Range_Check (Operand);
6044 Set_Do_Range_Check (Expression (Operand), False);
6047 -- Case of array conversions
6049 -- Expansion of array conversions, add required length/range checks
6050 -- but only do this if there is no change of representation. For
6051 -- handling of this case, see Handle_Changed_Representation.
6053 elsif Is_Array_Type (Target_Type) then
6055 if Is_Constrained (Target_Type) then
6056 Apply_Length_Check (Operand, Target_Type);
6058 Apply_Range_Check (Operand, Target_Type);
6061 Handle_Changed_Representation;
6063 -- Case of conversions of discriminated types
6065 -- Add required discriminant checks if target is constrained. Again
6066 -- this change is skipped if we have a change of representation.
6068 elsif Has_Discriminants (Target_Type)
6069 and then Is_Constrained (Target_Type)
6071 Apply_Discriminant_Check (Operand, Target_Type);
6072 Handle_Changed_Representation;
6074 -- Case of all other record conversions. The only processing required
6075 -- is to check for a change of representation requiring the special
6076 -- assignment processing.
6078 elsif Is_Record_Type (Target_Type) then
6079 Handle_Changed_Representation;
6081 -- Case of conversions of enumeration types
6083 elsif Is_Enumeration_Type (Target_Type) then
6085 -- Special processing is required if there is a change of
6086 -- representation (from enumeration representation clauses)
6088 if not Same_Representation (Target_Type, Operand_Type) then
6090 -- Convert: x(y) to x'val (ytyp'val (y))
6093 Make_Attribute_Reference (Loc,
6094 Prefix => New_Occurrence_Of (Target_Type, Loc),
6095 Attribute_Name => Name_Val,
6096 Expressions => New_List (
6097 Make_Attribute_Reference (Loc,
6098 Prefix => New_Occurrence_Of (Operand_Type, Loc),
6099 Attribute_Name => Name_Pos,
6100 Expressions => New_List (Operand)))));
6102 Analyze_And_Resolve (N, Target_Type);
6105 -- Case of conversions to floating-point
6107 elsif Is_Floating_Point_Type (Target_Type) then
6110 -- The remaining cases require no front end processing
6116 -- At this stage, either the conversion node has been transformed
6117 -- into some other equivalent expression, or left as a conversion
6118 -- that can be handled by Gigi. The conversions that Gigi can handle
6119 -- are the following:
6121 -- Conversions with no change of representation or type
6123 -- Numeric conversions involving integer values, floating-point
6124 -- values, and fixed-point values. Fixed-point values are allowed
6125 -- only if Conversion_OK is set, i.e. if the fixed-point values
6126 -- are to be treated as integers.
6128 -- No other conversions should be passed to Gigi.
6130 -- The only remaining step is to generate a range check if we still
6131 -- have a type conversion at this stage and Do_Range_Check is set.
6132 -- For now we do this only for conversions of discrete types.
6134 if Nkind (N) = N_Type_Conversion
6135 and then Is_Discrete_Type (Etype (N))
6138 Expr : constant Node_Id := Expression (N);
6143 if Do_Range_Check (Expr)
6144 and then Is_Discrete_Type (Etype (Expr))
6146 Set_Do_Range_Check (Expr, False);
6148 -- Before we do a range check, we have to deal with treating
6149 -- a fixed-point operand as an integer. The way we do this
6150 -- is simply to do an unchecked conversion to an appropriate
6151 -- integer type large enough to hold the result.
6153 -- This code is not active yet, because we are only dealing
6154 -- with discrete types so far ???
6156 if Nkind (Expr) in N_Has_Treat_Fixed_As_Integer
6157 and then Treat_Fixed_As_Integer (Expr)
6159 Ftyp := Base_Type (Etype (Expr));
6161 if Esize (Ftyp) >= Esize (Standard_Integer) then
6162 Ityp := Standard_Long_Long_Integer;
6164 Ityp := Standard_Integer;
6167 Rewrite (Expr, Unchecked_Convert_To (Ityp, Expr));
6170 -- Reset overflow flag, since the range check will include
6171 -- dealing with possible overflow, and generate the check
6173 Set_Do_Overflow_Check (N, False);
6174 Generate_Range_Check
6175 (Expr, Target_Type, CE_Range_Check_Failed);
6179 end Expand_N_Type_Conversion;
6181 -----------------------------------
6182 -- Expand_N_Unchecked_Expression --
6183 -----------------------------------
6185 -- Remove the unchecked expression node from the tree. It's job was simply
6186 -- to make sure that its constituent expression was handled with checks
6187 -- off, and now that that is done, we can remove it from the tree, and
6188 -- indeed must, since gigi does not expect to see these nodes.
6190 procedure Expand_N_Unchecked_Expression (N : Node_Id) is
6191 Exp : constant Node_Id := Expression (N);
6194 Set_Assignment_OK (Exp, Assignment_OK (N) or Assignment_OK (Exp));
6196 end Expand_N_Unchecked_Expression;
6198 ----------------------------------------
6199 -- Expand_N_Unchecked_Type_Conversion --
6200 ----------------------------------------
6202 -- If this cannot be handled by Gigi and we haven't already made
6203 -- a temporary for it, do it now.
6205 procedure Expand_N_Unchecked_Type_Conversion (N : Node_Id) is
6206 Target_Type : constant Entity_Id := Etype (N);
6207 Operand : constant Node_Id := Expression (N);
6208 Operand_Type : constant Entity_Id := Etype (Operand);
6211 -- If we have a conversion of a compile time known value to a target
6212 -- type and the value is in range of the target type, then we can simply
6213 -- replace the construct by an integer literal of the correct type. We
6214 -- only apply this to integer types being converted. Possibly it may
6215 -- apply in other cases, but it is too much trouble to worry about.
6217 -- Note that we do not do this transformation if the Kill_Range_Check
6218 -- flag is set, since then the value may be outside the expected range.
6219 -- This happens in the Normalize_Scalars case.
6221 if Is_Integer_Type (Target_Type)
6222 and then Is_Integer_Type (Operand_Type)
6223 and then Compile_Time_Known_Value (Operand)
6224 and then not Kill_Range_Check (N)
6227 Val : constant Uint := Expr_Value (Operand);
6230 if Compile_Time_Known_Value (Type_Low_Bound (Target_Type))
6232 Compile_Time_Known_Value (Type_High_Bound (Target_Type))
6234 Val >= Expr_Value (Type_Low_Bound (Target_Type))
6236 Val <= Expr_Value (Type_High_Bound (Target_Type))
6238 Rewrite (N, Make_Integer_Literal (Sloc (N), Val));
6239 Analyze_And_Resolve (N, Target_Type);
6245 -- Nothing to do if conversion is safe
6247 if Safe_Unchecked_Type_Conversion (N) then
6251 -- Otherwise force evaluation unless Assignment_OK flag is set (this
6252 -- flag indicates ??? -- more comments needed here)
6254 if Assignment_OK (N) then
6257 Force_Evaluation (N);
6259 end Expand_N_Unchecked_Type_Conversion;
6261 ----------------------------
6262 -- Expand_Record_Equality --
6263 ----------------------------
6265 -- For non-variant records, Equality is expanded when needed into:
6267 -- and then Lhs.Discr1 = Rhs.Discr1
6269 -- and then Lhs.Discrn = Rhs.Discrn
6270 -- and then Lhs.Cmp1 = Rhs.Cmp1
6272 -- and then Lhs.Cmpn = Rhs.Cmpn
6274 -- The expression is folded by the back-end for adjacent fields. This
6275 -- function is called for tagged record in only one occasion: for imple-
6276 -- menting predefined primitive equality (see Predefined_Primitives_Bodies)
6277 -- otherwise the primitive "=" is used directly.
6279 function Expand_Record_Equality
6287 Loc : constant Source_Ptr := Sloc (Nod);
6289 function Suitable_Element (C : Entity_Id) return Entity_Id;
6290 -- Return the first field to compare beginning with C, skipping the
6291 -- inherited components
6293 function Suitable_Element (C : Entity_Id) return Entity_Id is
6298 elsif Ekind (C) /= E_Discriminant
6299 and then Ekind (C) /= E_Component
6301 return Suitable_Element (Next_Entity (C));
6303 elsif Is_Tagged_Type (Typ)
6304 and then C /= Original_Record_Component (C)
6306 return Suitable_Element (Next_Entity (C));
6308 elsif Chars (C) = Name_uController
6309 or else Chars (C) = Name_uTag
6311 return Suitable_Element (Next_Entity (C));
6316 end Suitable_Element;
6321 First_Time : Boolean := True;
6323 -- Start of processing for Expand_Record_Equality
6326 -- Special processing for the unchecked union case, which will occur
6327 -- only in the context of tagged types and dynamic dispatching, since
6328 -- other cases are handled statically. We return True, but insert a
6329 -- raise Program_Error statement.
6331 if Is_Unchecked_Union (Typ) then
6333 -- If this is a component of an enclosing record, return the Raise
6334 -- statement directly.
6336 if No (Parent (Lhs)) then
6338 Make_Raise_Program_Error (Loc,
6339 Reason => PE_Unchecked_Union_Restriction);
6340 Set_Etype (Result, Standard_Boolean);
6345 Make_Raise_Program_Error (Loc,
6346 Reason => PE_Unchecked_Union_Restriction));
6347 return New_Occurrence_Of (Standard_True, Loc);
6351 -- Generates the following code: (assuming that Typ has one Discr and
6352 -- component C2 is also a record)
6355 -- and then Lhs.Discr1 = Rhs.Discr1
6356 -- and then Lhs.C1 = Rhs.C1
6357 -- and then Lhs.C2.C1=Rhs.C2.C1 and then ... Lhs.C2.Cn=Rhs.C2.Cn
6359 -- and then Lhs.Cmpn = Rhs.Cmpn
6361 Result := New_Reference_To (Standard_True, Loc);
6362 C := Suitable_Element (First_Entity (Typ));
6364 while Present (C) loop
6372 First_Time := False;
6377 New_Lhs := New_Copy_Tree (Lhs);
6378 New_Rhs := New_Copy_Tree (Rhs);
6383 Left_Opnd => Result,
6385 Expand_Composite_Equality (Nod, Etype (C),
6387 Make_Selected_Component (Loc,
6389 Selector_Name => New_Reference_To (C, Loc)),
6391 Make_Selected_Component (Loc,
6393 Selector_Name => New_Reference_To (C, Loc)),
6397 C := Suitable_Element (Next_Entity (C));
6401 end Expand_Record_Equality;
6403 -------------------------------------
6404 -- Fixup_Universal_Fixed_Operation --
6405 -------------------------------------
6407 procedure Fixup_Universal_Fixed_Operation (N : Node_Id) is
6408 Conv : constant Node_Id := Parent (N);
6411 -- We must have a type conversion immediately above us
6413 pragma Assert (Nkind (Conv) = N_Type_Conversion);
6415 -- Normally the type conversion gives our target type. The exception
6416 -- occurs in the case of the Round attribute, where the conversion
6417 -- will be to universal real, and our real type comes from the Round
6418 -- attribute (as well as an indication that we must round the result)
6420 if Nkind (Parent (Conv)) = N_Attribute_Reference
6421 and then Attribute_Name (Parent (Conv)) = Name_Round
6423 Set_Etype (N, Etype (Parent (Conv)));
6424 Set_Rounded_Result (N);
6426 -- Normal case where type comes from conversion above us
6429 Set_Etype (N, Etype (Conv));
6431 end Fixup_Universal_Fixed_Operation;
6433 ------------------------------
6434 -- Get_Allocator_Final_List --
6435 ------------------------------
6437 function Get_Allocator_Final_List
6443 Loc : constant Source_Ptr := Sloc (N);
6447 -- If the context is an access parameter, we need to create
6448 -- a non-anonymous access type in order to have a usable
6449 -- final list, because there is otherwise no pool to which
6450 -- the allocated object can belong. We create both the type
6451 -- and the finalization chain here, because freezing an
6452 -- internal type does not create such a chain. The Final_Chain
6453 -- that is thus created is shared by the access parameter.
6455 if Ekind (PtrT) = E_Anonymous_Access_Type then
6456 Acc := Make_Defining_Identifier (Loc, New_Internal_Name ('J'));
6458 Make_Full_Type_Declaration (Loc,
6459 Defining_Identifier => Acc,
6461 Make_Access_To_Object_Definition (Loc,
6462 Subtype_Indication =>
6463 New_Occurrence_Of (T, Loc))));
6465 Build_Final_List (N, Acc);
6466 Set_Associated_Final_Chain (PtrT, Associated_Final_Chain (Acc));
6467 return Find_Final_List (Acc);
6470 return Find_Final_List (PtrT);
6472 end Get_Allocator_Final_List;
6474 -------------------------------
6475 -- Insert_Dereference_Action --
6476 -------------------------------
6478 procedure Insert_Dereference_Action (N : Node_Id) is
6479 Loc : constant Source_Ptr := Sloc (N);
6480 Typ : constant Entity_Id := Etype (N);
6481 Pool : constant Entity_Id := Associated_Storage_Pool (Typ);
6483 function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean;
6484 -- return true if type of P is derived from Checked_Pool;
6486 function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean is
6495 while T /= Etype (T) loop
6496 if Is_RTE (T, RE_Checked_Pool) then
6504 end Is_Checked_Storage_Pool;
6506 -- Start of processing for Insert_Dereference_Action
6509 if not Comes_From_Source (Parent (N)) then
6512 elsif not Is_Checked_Storage_Pool (Pool) then
6517 Make_Procedure_Call_Statement (Loc,
6518 Name => New_Reference_To (
6519 Find_Prim_Op (Etype (Pool), Name_Dereference), Loc),
6521 Parameter_Associations => New_List (
6525 New_Reference_To (Pool, Loc),
6527 -- Storage_Address. We use the attribute Pool_Address,
6528 -- which uses the pointer itself to find the address of
6529 -- the object, and which handles unconstrained arrays
6530 -- properly by computing the address of the template.
6531 -- i.e. the correct address of the corresponding allocation.
6533 Make_Attribute_Reference (Loc,
6534 Prefix => Duplicate_Subexpr_Move_Checks (N),
6535 Attribute_Name => Name_Pool_Address),
6537 -- Size_In_Storage_Elements
6539 Make_Op_Divide (Loc,
6541 Make_Attribute_Reference (Loc,
6543 Make_Explicit_Dereference (Loc,
6544 Duplicate_Subexpr_Move_Checks (N)),
6545 Attribute_Name => Name_Size),
6547 Make_Integer_Literal (Loc, System_Storage_Unit)),
6551 Make_Attribute_Reference (Loc,
6553 Make_Explicit_Dereference (Loc,
6554 Duplicate_Subexpr_Move_Checks (N)),
6555 Attribute_Name => Name_Alignment))));
6558 when RE_Not_Available =>
6560 end Insert_Dereference_Action;
6562 ------------------------------
6563 -- Make_Array_Comparison_Op --
6564 ------------------------------
6566 -- This is a hand-coded expansion of the following generic function:
6569 -- type elem is (<>);
6570 -- type index is (<>);
6571 -- type a is array (index range <>) of elem;
6573 -- function Gnnn (X : a; Y: a) return boolean is
6574 -- J : index := Y'first;
6577 -- if X'length = 0 then
6580 -- elsif Y'length = 0 then
6584 -- for I in X'range loop
6585 -- if X (I) = Y (J) then
6586 -- if J = Y'last then
6589 -- J := index'succ (J);
6593 -- return X (I) > Y (J);
6597 -- return X'length > Y'length;
6601 -- Note that since we are essentially doing this expansion by hand, we
6602 -- do not need to generate an actual or formal generic part, just the
6603 -- instantiated function itself.
6605 function Make_Array_Comparison_Op
6610 Loc : constant Source_Ptr := Sloc (Nod);
6612 X : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uX);
6613 Y : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uY);
6614 I : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uI);
6615 J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
6617 Index : constant Entity_Id := Base_Type (Etype (First_Index (Typ)));
6619 Loop_Statement : Node_Id;
6620 Loop_Body : Node_Id;
6623 Final_Expr : Node_Id;
6624 Func_Body : Node_Id;
6625 Func_Name : Entity_Id;
6631 -- if J = Y'last then
6634 -- J := index'succ (J);
6638 Make_Implicit_If_Statement (Nod,
6641 Left_Opnd => New_Reference_To (J, Loc),
6643 Make_Attribute_Reference (Loc,
6644 Prefix => New_Reference_To (Y, Loc),
6645 Attribute_Name => Name_Last)),
6647 Then_Statements => New_List (
6648 Make_Exit_Statement (Loc)),
6652 Make_Assignment_Statement (Loc,
6653 Name => New_Reference_To (J, Loc),
6655 Make_Attribute_Reference (Loc,
6656 Prefix => New_Reference_To (Index, Loc),
6657 Attribute_Name => Name_Succ,
6658 Expressions => New_List (New_Reference_To (J, Loc))))));
6660 -- if X (I) = Y (J) then
6663 -- return X (I) > Y (J);
6667 Make_Implicit_If_Statement (Nod,
6671 Make_Indexed_Component (Loc,
6672 Prefix => New_Reference_To (X, Loc),
6673 Expressions => New_List (New_Reference_To (I, Loc))),
6676 Make_Indexed_Component (Loc,
6677 Prefix => New_Reference_To (Y, Loc),
6678 Expressions => New_List (New_Reference_To (J, Loc)))),
6680 Then_Statements => New_List (Inner_If),
6682 Else_Statements => New_List (
6683 Make_Return_Statement (Loc,
6687 Make_Indexed_Component (Loc,
6688 Prefix => New_Reference_To (X, Loc),
6689 Expressions => New_List (New_Reference_To (I, Loc))),
6692 Make_Indexed_Component (Loc,
6693 Prefix => New_Reference_To (Y, Loc),
6694 Expressions => New_List (
6695 New_Reference_To (J, Loc)))))));
6697 -- for I in X'range loop
6702 Make_Implicit_Loop_Statement (Nod,
6703 Identifier => Empty,
6706 Make_Iteration_Scheme (Loc,
6707 Loop_Parameter_Specification =>
6708 Make_Loop_Parameter_Specification (Loc,
6709 Defining_Identifier => I,
6710 Discrete_Subtype_Definition =>
6711 Make_Attribute_Reference (Loc,
6712 Prefix => New_Reference_To (X, Loc),
6713 Attribute_Name => Name_Range))),
6715 Statements => New_List (Loop_Body));
6717 -- if X'length = 0 then
6719 -- elsif Y'length = 0 then
6722 -- for ... loop ... end loop;
6723 -- return X'length > Y'length;
6727 Make_Attribute_Reference (Loc,
6728 Prefix => New_Reference_To (X, Loc),
6729 Attribute_Name => Name_Length);
6732 Make_Attribute_Reference (Loc,
6733 Prefix => New_Reference_To (Y, Loc),
6734 Attribute_Name => Name_Length);
6738 Left_Opnd => Length1,
6739 Right_Opnd => Length2);
6742 Make_Implicit_If_Statement (Nod,
6746 Make_Attribute_Reference (Loc,
6747 Prefix => New_Reference_To (X, Loc),
6748 Attribute_Name => Name_Length),
6750 Make_Integer_Literal (Loc, 0)),
6754 Make_Return_Statement (Loc,
6755 Expression => New_Reference_To (Standard_False, Loc))),
6757 Elsif_Parts => New_List (
6758 Make_Elsif_Part (Loc,
6762 Make_Attribute_Reference (Loc,
6763 Prefix => New_Reference_To (Y, Loc),
6764 Attribute_Name => Name_Length),
6766 Make_Integer_Literal (Loc, 0)),
6770 Make_Return_Statement (Loc,
6771 Expression => New_Reference_To (Standard_True, Loc))))),
6773 Else_Statements => New_List (
6775 Make_Return_Statement (Loc,
6776 Expression => Final_Expr)));
6780 Formals := New_List (
6781 Make_Parameter_Specification (Loc,
6782 Defining_Identifier => X,
6783 Parameter_Type => New_Reference_To (Typ, Loc)),
6785 Make_Parameter_Specification (Loc,
6786 Defining_Identifier => Y,
6787 Parameter_Type => New_Reference_To (Typ, Loc)));
6789 -- function Gnnn (...) return boolean is
6790 -- J : index := Y'first;
6795 Func_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('G'));
6798 Make_Subprogram_Body (Loc,
6800 Make_Function_Specification (Loc,
6801 Defining_Unit_Name => Func_Name,
6802 Parameter_Specifications => Formals,
6803 Subtype_Mark => New_Reference_To (Standard_Boolean, Loc)),
6805 Declarations => New_List (
6806 Make_Object_Declaration (Loc,
6807 Defining_Identifier => J,
6808 Object_Definition => New_Reference_To (Index, Loc),
6810 Make_Attribute_Reference (Loc,
6811 Prefix => New_Reference_To (Y, Loc),
6812 Attribute_Name => Name_First))),
6814 Handled_Statement_Sequence =>
6815 Make_Handled_Sequence_Of_Statements (Loc,
6816 Statements => New_List (If_Stat)));
6820 end Make_Array_Comparison_Op;
6822 ---------------------------
6823 -- Make_Boolean_Array_Op --
6824 ---------------------------
6826 -- For logical operations on boolean arrays, expand in line the
6827 -- following, replacing 'and' with 'or' or 'xor' where needed:
6829 -- function Annn (A : typ; B: typ) return typ is
6832 -- for J in A'range loop
6833 -- C (J) := A (J) op B (J);
6838 -- Here typ is the boolean array type
6840 function Make_Boolean_Array_Op
6845 Loc : constant Source_Ptr := Sloc (N);
6847 A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
6848 B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
6849 C : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uC);
6850 J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
6858 Func_Name : Entity_Id;
6859 Func_Body : Node_Id;
6860 Loop_Statement : Node_Id;
6864 Make_Indexed_Component (Loc,
6865 Prefix => New_Reference_To (A, Loc),
6866 Expressions => New_List (New_Reference_To (J, Loc)));
6869 Make_Indexed_Component (Loc,
6870 Prefix => New_Reference_To (B, Loc),
6871 Expressions => New_List (New_Reference_To (J, Loc)));
6874 Make_Indexed_Component (Loc,
6875 Prefix => New_Reference_To (C, Loc),
6876 Expressions => New_List (New_Reference_To (J, Loc)));
6878 if Nkind (N) = N_Op_And then
6884 elsif Nkind (N) = N_Op_Or then
6898 Make_Implicit_Loop_Statement (N,
6899 Identifier => Empty,
6902 Make_Iteration_Scheme (Loc,
6903 Loop_Parameter_Specification =>
6904 Make_Loop_Parameter_Specification (Loc,
6905 Defining_Identifier => J,
6906 Discrete_Subtype_Definition =>
6907 Make_Attribute_Reference (Loc,
6908 Prefix => New_Reference_To (A, Loc),
6909 Attribute_Name => Name_Range))),
6911 Statements => New_List (
6912 Make_Assignment_Statement (Loc,
6914 Expression => Op)));
6916 Formals := New_List (
6917 Make_Parameter_Specification (Loc,
6918 Defining_Identifier => A,
6919 Parameter_Type => New_Reference_To (Typ, Loc)),
6921 Make_Parameter_Specification (Loc,
6922 Defining_Identifier => B,
6923 Parameter_Type => New_Reference_To (Typ, Loc)));
6926 Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
6927 Set_Is_Inlined (Func_Name);
6930 Make_Subprogram_Body (Loc,
6932 Make_Function_Specification (Loc,
6933 Defining_Unit_Name => Func_Name,
6934 Parameter_Specifications => Formals,
6935 Subtype_Mark => New_Reference_To (Typ, Loc)),
6937 Declarations => New_List (
6938 Make_Object_Declaration (Loc,
6939 Defining_Identifier => C,
6940 Object_Definition => New_Reference_To (Typ, Loc))),
6942 Handled_Statement_Sequence =>
6943 Make_Handled_Sequence_Of_Statements (Loc,
6944 Statements => New_List (
6946 Make_Return_Statement (Loc,
6947 Expression => New_Reference_To (C, Loc)))));
6950 end Make_Boolean_Array_Op;
6952 ------------------------
6953 -- Rewrite_Comparison --
6954 ------------------------
6956 procedure Rewrite_Comparison (N : Node_Id) is
6957 Typ : constant Entity_Id := Etype (N);
6958 Op1 : constant Node_Id := Left_Opnd (N);
6959 Op2 : constant Node_Id := Right_Opnd (N);
6961 Res : constant Compare_Result := Compile_Time_Compare (Op1, Op2);
6962 -- Res indicates if compare outcome can be determined at compile time
6964 True_Result : Boolean;
6965 False_Result : Boolean;
6968 case N_Op_Compare (Nkind (N)) is
6970 True_Result := Res = EQ;
6971 False_Result := Res = LT or else Res = GT or else Res = NE;
6974 True_Result := Res in Compare_GE;
6975 False_Result := Res = LT;
6978 True_Result := Res = GT;
6979 False_Result := Res in Compare_LE;
6982 True_Result := Res = LT;
6983 False_Result := Res in Compare_GE;
6986 True_Result := Res in Compare_LE;
6987 False_Result := Res = GT;
6990 True_Result := Res = NE;
6991 False_Result := Res = LT or else Res = GT or else Res = EQ;
6996 Convert_To (Typ, New_Occurrence_Of (Standard_True, Sloc (N))));
6997 Analyze_And_Resolve (N, Typ);
6998 Warn_On_Known_Condition (N);
7000 elsif False_Result then
7002 Convert_To (Typ, New_Occurrence_Of (Standard_False, Sloc (N))));
7003 Analyze_And_Resolve (N, Typ);
7004 Warn_On_Known_Condition (N);
7006 end Rewrite_Comparison;
7008 ----------------------------
7009 -- Safe_In_Place_Array_Op --
7010 ----------------------------
7012 function Safe_In_Place_Array_Op
7020 function Is_Safe_Operand (Op : Node_Id) return Boolean;
7021 -- Operand is safe if it cannot overlap part of the target of the
7022 -- operation. If the operand and the target are identical, the operand
7023 -- is safe. The operand can be empty in the case of negation.
7025 function Is_Unaliased (N : Node_Id) return Boolean;
7026 -- Check that N is a stand-alone entity.
7032 function Is_Unaliased (N : Node_Id) return Boolean is
7036 and then No (Address_Clause (Entity (N)))
7037 and then No (Renamed_Object (Entity (N)));
7040 ---------------------
7041 -- Is_Safe_Operand --
7042 ---------------------
7044 function Is_Safe_Operand (Op : Node_Id) return Boolean is
7049 elsif Is_Entity_Name (Op) then
7050 return Is_Unaliased (Op);
7052 elsif Nkind (Op) = N_Indexed_Component
7053 or else Nkind (Op) = N_Selected_Component
7055 return Is_Unaliased (Prefix (Op));
7057 elsif Nkind (Op) = N_Slice then
7059 Is_Unaliased (Prefix (Op))
7060 and then Entity (Prefix (Op)) /= Target;
7062 elsif Nkind (Op) = N_Op_Not then
7063 return Is_Safe_Operand (Right_Opnd (Op));
7068 end Is_Safe_Operand;
7070 -- Start of processing for Is_Safe_In_Place_Array_Op
7073 -- We skip this processing if the component size is not the
7074 -- same as a system storage unit (since at least for NOT
7075 -- this would cause problems).
7077 if Component_Size (Etype (Lhs)) /= System_Storage_Unit then
7080 -- Cannot do in place stuff on Java_VM since cannot pass addresses
7085 -- Cannot do in place stuff if non-standard Boolean representation
7087 elsif Has_Non_Standard_Rep (Component_Type (Etype (Lhs))) then
7090 elsif not Is_Unaliased (Lhs) then
7093 Target := Entity (Lhs);
7096 Is_Safe_Operand (Op1)
7097 and then Is_Safe_Operand (Op2);
7099 end Safe_In_Place_Array_Op;
7101 -----------------------
7102 -- Tagged_Membership --
7103 -----------------------
7105 -- There are two different cases to consider depending on whether
7106 -- the right operand is a class-wide type or not. If not we just
7107 -- compare the actual tag of the left expr to the target type tag:
7109 -- Left_Expr.Tag = Right_Type'Tag;
7111 -- If it is a class-wide type we use the RT function CW_Membership which
7112 -- is usually implemented by looking in the ancestor tables contained in
7113 -- the dispatch table pointed by Left_Expr.Tag for Typ'Tag
7115 function Tagged_Membership (N : Node_Id) return Node_Id is
7116 Left : constant Node_Id := Left_Opnd (N);
7117 Right : constant Node_Id := Right_Opnd (N);
7118 Loc : constant Source_Ptr := Sloc (N);
7120 Left_Type : Entity_Id;
7121 Right_Type : Entity_Id;
7125 Left_Type := Etype (Left);
7126 Right_Type := Etype (Right);
7128 if Is_Class_Wide_Type (Left_Type) then
7129 Left_Type := Root_Type (Left_Type);
7133 Make_Selected_Component (Loc,
7134 Prefix => Relocate_Node (Left),
7135 Selector_Name => New_Reference_To (Tag_Component (Left_Type), Loc));
7137 if Is_Class_Wide_Type (Right_Type) then
7139 Make_DT_Access_Action (Left_Type,
7140 Action => CW_Membership,
7144 Access_Disp_Table (Root_Type (Right_Type)), Loc)));
7148 Left_Opnd => Obj_Tag,
7150 New_Reference_To (Access_Disp_Table (Right_Type), Loc));
7153 end Tagged_Membership;
7155 ------------------------------
7156 -- Unary_Op_Validity_Checks --
7157 ------------------------------
7159 procedure Unary_Op_Validity_Checks (N : Node_Id) is
7161 if Validity_Checks_On and Validity_Check_Operands then
7162 Ensure_Valid (Right_Opnd (N));
7164 end Unary_Op_Validity_Checks;