1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2007, 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, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, 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_Atag; use Exp_Atag;
34 with Exp_Ch3; use Exp_Ch3;
35 with Exp_Ch6; use Exp_Ch6;
36 with Exp_Ch7; use Exp_Ch7;
37 with Exp_Ch9; use Exp_Ch9;
38 with Exp_Disp; use Exp_Disp;
39 with Exp_Fixd; use Exp_Fixd;
40 with Exp_Pakd; use Exp_Pakd;
41 with Exp_Tss; use Exp_Tss;
42 with Exp_Util; use Exp_Util;
43 with Exp_VFpt; use Exp_VFpt;
44 with Freeze; use Freeze;
45 with Inline; use Inline;
46 with Namet; use Namet;
47 with Nlists; use Nlists;
48 with Nmake; use Nmake;
50 with Restrict; use Restrict;
51 with Rident; use Rident;
52 with Rtsfind; use Rtsfind;
54 with Sem_Cat; use Sem_Cat;
55 with Sem_Ch3; use Sem_Ch3;
56 with Sem_Ch8; use Sem_Ch8;
57 with Sem_Ch13; use Sem_Ch13;
58 with Sem_Eval; use Sem_Eval;
59 with Sem_Res; use Sem_Res;
60 with Sem_Type; use Sem_Type;
61 with Sem_Util; use Sem_Util;
62 with Sem_Warn; use Sem_Warn;
63 with Sinfo; use Sinfo;
64 with Snames; use Snames;
65 with Stand; use Stand;
66 with Targparm; use Targparm;
67 with Tbuild; use Tbuild;
68 with Ttypes; use Ttypes;
69 with Uintp; use Uintp;
70 with Urealp; use Urealp;
71 with Validsw; use Validsw;
73 package body Exp_Ch4 is
75 -----------------------
76 -- Local Subprograms --
77 -----------------------
79 procedure Binary_Op_Validity_Checks (N : Node_Id);
80 pragma Inline (Binary_Op_Validity_Checks);
81 -- Performs validity checks for a binary operator
83 procedure Build_Boolean_Array_Proc_Call
87 -- If an boolean array assignment can be done in place, build call to
88 -- corresponding library procedure.
90 procedure Displace_Allocator_Pointer (N : Node_Id);
91 -- Ada 2005 (AI-251): Subsidiary procedure to Expand_N_Allocator and
92 -- Expand_Allocator_Expression. Allocating class-wide interface objects
93 -- this routine displaces the pointer to the allocated object to reference
94 -- the component referencing the corresponding secondary dispatch table.
96 procedure Expand_Allocator_Expression (N : Node_Id);
97 -- Subsidiary to Expand_N_Allocator, for the case when the expression
98 -- is a qualified expression or an aggregate.
100 procedure Expand_Array_Comparison (N : Node_Id);
101 -- This routine handles expansion of the comparison operators (N_Op_Lt,
102 -- N_Op_Le, N_Op_Gt, N_Op_Ge) when operating on an array type. The basic
103 -- code for these operators is similar, differing only in the details of
104 -- the actual comparison call that is made. Special processing (call a
107 function Expand_Array_Equality
112 Typ : Entity_Id) return Node_Id;
113 -- Expand an array equality into a call to a function implementing this
114 -- equality, and a call to it. Loc is the location for the generated
115 -- nodes. Lhs and Rhs are the array expressions to be compared.
116 -- Bodies is a list on which to attach bodies of local functions that
117 -- are created in the process. It is the responsibility of the
118 -- caller to insert those bodies at the right place. Nod provides
119 -- the Sloc value for the generated code. Normally the types used
120 -- for the generated equality routine are taken from Lhs and Rhs.
121 -- However, in some situations of generated code, the Etype fields
122 -- of Lhs and Rhs are not set yet. In such cases, Typ supplies the
123 -- type to be used for the formal parameters.
125 procedure Expand_Boolean_Operator (N : Node_Id);
126 -- Common expansion processing for Boolean operators (And, Or, Xor)
127 -- for the case of array type arguments.
129 function Expand_Composite_Equality
134 Bodies : List_Id) return Node_Id;
135 -- Local recursive function used to expand equality for nested
136 -- composite types. Used by Expand_Record/Array_Equality, Bodies
137 -- is a list on which to attach bodies of local functions that are
138 -- created in the process. This is the responsability of the caller
139 -- to insert those bodies at the right place. Nod provides the Sloc
140 -- value for generated code. Lhs and Rhs are the left and right sides
141 -- for the comparison, and Typ is the type of the arrays to compare.
143 procedure Expand_Concatenate_Other (Cnode : Node_Id; Opnds : List_Id);
144 -- This routine handles expansion of concatenation operations, where
145 -- N is the N_Op_Concat node being expanded and Operands is the list
146 -- of operands (at least two are present). The caller has dealt with
147 -- converting any singleton operands into singleton aggregates.
149 procedure Expand_Concatenate_String (Cnode : Node_Id; Opnds : List_Id);
150 -- Routine to expand concatenation of 2-5 operands (in the list Operands)
151 -- and replace node Cnode with the result of the contatenation. If there
152 -- are two operands, they can be string or character. If there are more
153 -- than two operands, then are always of type string (i.e. the caller has
154 -- already converted character operands to strings in this case).
156 procedure Fixup_Universal_Fixed_Operation (N : Node_Id);
157 -- N is either an N_Op_Divide or N_Op_Multiply node whose result is
158 -- universal fixed. We do not have such a type at runtime, so the
159 -- purpose of this routine is to find the real type by looking up
160 -- the tree. We also determine if the operation must be rounded.
162 function Get_Allocator_Final_List
165 PtrT : Entity_Id) return Entity_Id;
166 -- If the designated type is controlled, build final_list expression
167 -- for created object. If context is an access parameter, create a
168 -- local access type to have a usable finalization list.
170 function Has_Inferable_Discriminants (N : Node_Id) return Boolean;
171 -- Ada 2005 (AI-216): A view of an Unchecked_Union object has inferable
172 -- discriminants if it has a constrained nominal type, unless the object
173 -- is a component of an enclosing Unchecked_Union object that is subject
174 -- to a per-object constraint and the enclosing object lacks inferable
177 -- An expression of an Unchecked_Union type has inferable discriminants
178 -- if it is either a name of an object with inferable discriminants or a
179 -- qualified expression whose subtype mark denotes a constrained subtype.
181 procedure Insert_Dereference_Action (N : Node_Id);
182 -- N is an expression whose type is an access. When the type of the
183 -- associated storage pool is derived from Checked_Pool, generate a
184 -- call to the 'Dereference' primitive operation.
186 function Make_Array_Comparison_Op
188 Nod : Node_Id) return Node_Id;
189 -- Comparisons between arrays are expanded in line. This function
190 -- produces the body of the implementation of (a > b), where a and b
191 -- are one-dimensional arrays of some discrete type. The original
192 -- node is then expanded into the appropriate call to this function.
193 -- Nod provides the Sloc value for the generated code.
195 function Make_Boolean_Array_Op
197 N : Node_Id) return Node_Id;
198 -- Boolean operations on boolean arrays are expanded in line. This
199 -- function produce the body for the node N, which is (a and b),
200 -- (a or b), or (a xor b). It is used only the normal case and not
201 -- the packed case. The type involved, Typ, is the Boolean array type,
202 -- and the logical operations in the body are simple boolean operations.
203 -- Note that Typ is always a constrained type (the caller has ensured
204 -- this by using Convert_To_Actual_Subtype if necessary).
206 procedure Rewrite_Comparison (N : Node_Id);
207 -- If N is the node for a comparison whose outcome can be determined at
208 -- compile time, then the node N can be rewritten with True or False. If
209 -- the outcome cannot be determined at compile time, the call has no
210 -- effect. If N is a type conversion, then this processing is applied to
211 -- its expression. If N is neither comparison nor a type conversion, the
212 -- call has no effect.
214 function Tagged_Membership (N : Node_Id) return Node_Id;
215 -- Construct the expression corresponding to the tagged membership test.
216 -- Deals with a second operand being (or not) a class-wide type.
218 function Safe_In_Place_Array_Op
221 Op2 : Node_Id) return Boolean;
222 -- In the context of an assignment, where the right-hand side is a
223 -- boolean operation on arrays, check whether operation can be performed
226 procedure Unary_Op_Validity_Checks (N : Node_Id);
227 pragma Inline (Unary_Op_Validity_Checks);
228 -- Performs validity checks for a unary operator
230 -------------------------------
231 -- Binary_Op_Validity_Checks --
232 -------------------------------
234 procedure Binary_Op_Validity_Checks (N : Node_Id) is
236 if Validity_Checks_On and Validity_Check_Operands then
237 Ensure_Valid (Left_Opnd (N));
238 Ensure_Valid (Right_Opnd (N));
240 end Binary_Op_Validity_Checks;
242 ------------------------------------
243 -- Build_Boolean_Array_Proc_Call --
244 ------------------------------------
246 procedure Build_Boolean_Array_Proc_Call
251 Loc : constant Source_Ptr := Sloc (N);
252 Kind : constant Node_Kind := Nkind (Expression (N));
253 Target : constant Node_Id :=
254 Make_Attribute_Reference (Loc,
256 Attribute_Name => Name_Address);
258 Arg1 : constant Node_Id := Op1;
259 Arg2 : Node_Id := Op2;
261 Proc_Name : Entity_Id;
264 if Kind = N_Op_Not then
265 if Nkind (Op1) in N_Binary_Op then
267 -- Use negated version of the binary operators
269 if Nkind (Op1) = N_Op_And then
270 Proc_Name := RTE (RE_Vector_Nand);
272 elsif Nkind (Op1) = N_Op_Or then
273 Proc_Name := RTE (RE_Vector_Nor);
275 else pragma Assert (Nkind (Op1) = N_Op_Xor);
276 Proc_Name := RTE (RE_Vector_Xor);
280 Make_Procedure_Call_Statement (Loc,
281 Name => New_Occurrence_Of (Proc_Name, Loc),
283 Parameter_Associations => New_List (
285 Make_Attribute_Reference (Loc,
286 Prefix => Left_Opnd (Op1),
287 Attribute_Name => Name_Address),
289 Make_Attribute_Reference (Loc,
290 Prefix => Right_Opnd (Op1),
291 Attribute_Name => Name_Address),
293 Make_Attribute_Reference (Loc,
294 Prefix => Left_Opnd (Op1),
295 Attribute_Name => Name_Length)));
298 Proc_Name := RTE (RE_Vector_Not);
301 Make_Procedure_Call_Statement (Loc,
302 Name => New_Occurrence_Of (Proc_Name, Loc),
303 Parameter_Associations => New_List (
306 Make_Attribute_Reference (Loc,
308 Attribute_Name => Name_Address),
310 Make_Attribute_Reference (Loc,
312 Attribute_Name => Name_Length)));
316 -- We use the following equivalences:
318 -- (not X) or (not Y) = not (X and Y) = Nand (X, Y)
319 -- (not X) and (not Y) = not (X or Y) = Nor (X, Y)
320 -- (not X) xor (not Y) = X xor Y
321 -- X xor (not Y) = not (X xor Y) = Nxor (X, Y)
323 if Nkind (Op1) = N_Op_Not then
324 if Kind = N_Op_And then
325 Proc_Name := RTE (RE_Vector_Nor);
327 elsif Kind = N_Op_Or then
328 Proc_Name := RTE (RE_Vector_Nand);
331 Proc_Name := RTE (RE_Vector_Xor);
335 if Kind = N_Op_And then
336 Proc_Name := RTE (RE_Vector_And);
338 elsif Kind = N_Op_Or then
339 Proc_Name := RTE (RE_Vector_Or);
341 elsif Nkind (Op2) = N_Op_Not then
342 Proc_Name := RTE (RE_Vector_Nxor);
343 Arg2 := Right_Opnd (Op2);
346 Proc_Name := RTE (RE_Vector_Xor);
351 Make_Procedure_Call_Statement (Loc,
352 Name => New_Occurrence_Of (Proc_Name, Loc),
353 Parameter_Associations => New_List (
355 Make_Attribute_Reference (Loc,
357 Attribute_Name => Name_Address),
358 Make_Attribute_Reference (Loc,
360 Attribute_Name => Name_Address),
361 Make_Attribute_Reference (Loc,
363 Attribute_Name => Name_Length)));
366 Rewrite (N, Call_Node);
370 when RE_Not_Available =>
372 end Build_Boolean_Array_Proc_Call;
374 --------------------------------
375 -- Displace_Allocator_Pointer --
376 --------------------------------
378 procedure Displace_Allocator_Pointer (N : Node_Id) is
379 Loc : constant Source_Ptr := Sloc (N);
380 Orig_Node : constant Node_Id := Original_Node (N);
386 pragma Assert (Nkind (N) = N_Identifier
387 and then Nkind (Orig_Node) = N_Allocator);
389 PtrT := Etype (Orig_Node);
390 Dtyp := Designated_Type (PtrT);
391 Etyp := Etype (Expression (Orig_Node));
393 if Is_Class_Wide_Type (Dtyp)
394 and then Is_Interface (Dtyp)
396 -- If the type of the allocator expression is not an interface type
397 -- we can generate code to reference the record component containing
398 -- the pointer to the secondary dispatch table.
400 if not Is_Interface (Etyp) then
402 Saved_Typ : constant Entity_Id := Etype (Orig_Node);
405 -- 1) Get access to the allocated object
408 Make_Explicit_Dereference (Loc,
413 -- 2) Add the conversion to displace the pointer to reference
414 -- the secondary dispatch table.
416 Rewrite (N, Convert_To (Dtyp, Relocate_Node (N)));
417 Analyze_And_Resolve (N, Dtyp);
419 -- 3) The 'access to the secondary dispatch table will be used
420 -- as the value returned by the allocator.
423 Make_Attribute_Reference (Loc,
424 Prefix => Relocate_Node (N),
425 Attribute_Name => Name_Access));
426 Set_Etype (N, Saved_Typ);
430 -- If the type of the allocator expression is an interface type we
431 -- generate a run-time call to displace "this" to reference the
432 -- component containing the pointer to the secondary dispatch table
433 -- or else raise Constraint_Error if the actual object does not
434 -- implement the target interface. This case corresponds with the
435 -- following example:
437 -- function Op (Obj : Iface_1'Class) return access Ifac_2e'Class is
439 -- return new Iface_2'Class'(Obj);
444 Unchecked_Convert_To (PtrT,
445 Make_Function_Call (Loc,
446 Name => New_Reference_To (RTE (RE_Displace), Loc),
447 Parameter_Associations => New_List (
448 Unchecked_Convert_To (RTE (RE_Address),
454 (Access_Disp_Table (Etype (Base_Type (Dtyp))))),
456 Analyze_And_Resolve (N, PtrT);
459 end Displace_Allocator_Pointer;
461 ---------------------------------
462 -- Expand_Allocator_Expression --
463 ---------------------------------
465 procedure Expand_Allocator_Expression (N : Node_Id) is
466 Loc : constant Source_Ptr := Sloc (N);
467 Exp : constant Node_Id := Expression (Expression (N));
468 PtrT : constant Entity_Id := Etype (N);
469 DesigT : constant Entity_Id := Designated_Type (PtrT);
471 procedure Apply_Accessibility_Check
473 Built_In_Place : Boolean := False);
474 -- Ada 2005 (AI-344): For an allocator with a class-wide designated
475 -- type, generate an accessibility check to verify that the level of
476 -- the type of the created object is not deeper than the level of the
477 -- access type. If the type of the qualified expression is class-
478 -- wide, then always generate the check (except in the case where it
479 -- is known to be unnecessary, see comment below). Otherwise, only
480 -- generate the check if the level of the qualified expression type
481 -- is statically deeper than the access type. Although the static
482 -- accessibility will generally have been performed as a legality
483 -- check, it won't have been done in cases where the allocator
484 -- appears in generic body, so a run-time check is needed in general.
485 -- One special case is when the access type is declared in the same
486 -- scope as the class-wide allocator, in which case the check can
487 -- never fail, so it need not be generated. As an open issue, there
488 -- seem to be cases where the static level associated with the
489 -- class-wide object's underlying type is not sufficient to perform
490 -- the proper accessibility check, such as for allocators in nested
491 -- subprograms or accept statements initialized by class-wide formals
492 -- when the actual originates outside at a deeper static level. The
493 -- nested subprogram case might require passing accessibility levels
494 -- along with class-wide parameters, and the task case seems to be
495 -- an actual gap in the language rules that needs to be fixed by the
498 -------------------------------
499 -- Apply_Accessibility_Check --
500 -------------------------------
502 procedure Apply_Accessibility_Check
504 Built_In_Place : Boolean := False)
509 -- Note: we skip the accessibility check for the VM case, since
510 -- there does not seem to be any practical way of implementing it.
512 if Ada_Version >= Ada_05
513 and then VM_Target = No_VM
514 and then Is_Class_Wide_Type (DesigT)
515 and then not Scope_Suppress (Accessibility_Check)
517 (Type_Access_Level (Etype (Exp)) > Type_Access_Level (PtrT)
519 (Is_Class_Wide_Type (Etype (Exp))
520 and then Scope (PtrT) /= Current_Scope))
522 -- If the allocator was built in place Ref is already a reference
523 -- to the access object initialized to the result of the allocator
524 -- (see Exp_Ch6.Make_Build_In_Place_Call_In_Allocator). Otherwise
525 -- it is the entity associated with the object containing the
526 -- address of the allocated object.
528 if Built_In_Place then
529 Ref_Node := New_Copy (Ref);
531 Ref_Node := New_Reference_To (Ref, Loc);
535 Make_Raise_Program_Error (Loc,
539 Build_Get_Access_Level (Loc,
540 Make_Attribute_Reference (Loc,
542 Attribute_Name => Name_Tag)),
544 Make_Integer_Literal (Loc,
545 Type_Access_Level (PtrT))),
546 Reason => PE_Accessibility_Check_Failed));
548 end Apply_Accessibility_Check;
552 Indic : constant Node_Id := Subtype_Mark (Expression (N));
553 T : constant Entity_Id := Entity (Indic);
558 TagT : Entity_Id := Empty;
559 -- Type used as source for tag assignment
561 TagR : Node_Id := Empty;
562 -- Target reference for tag assignment
564 Aggr_In_Place : constant Boolean := Is_Delayed_Aggregate (Exp);
566 Tag_Assign : Node_Id;
569 -- Start of processing for Expand_Allocator_Expression
572 if Is_Tagged_Type (T) or else Controlled_Type (T) then
574 -- Ada 2005 (AI-318-02): If the initialization expression is a
575 -- call to a build-in-place function, then access to the allocated
576 -- object must be passed to the function. Currently we limit such
577 -- functions to those with constrained limited result subtypes,
578 -- but eventually we plan to expand the allowed forms of funtions
579 -- that are treated as build-in-place.
581 if Ada_Version >= Ada_05
582 and then Is_Build_In_Place_Function_Call (Exp)
584 Make_Build_In_Place_Call_In_Allocator (N, Exp);
585 Apply_Accessibility_Check (N, Built_In_Place => True);
589 -- Actions inserted before:
590 -- Temp : constant ptr_T := new T'(Expression);
591 -- <no CW> Temp._tag := T'tag;
592 -- <CTRL> Adjust (Finalizable (Temp.all));
593 -- <CTRL> Attach_To_Final_List (Finalizable (Temp.all));
595 -- We analyze by hand the new internal allocator to avoid
596 -- any recursion and inappropriate call to Initialize
598 -- We don't want to remove side effects when the expression must be
599 -- built in place. In the case of a build-in-place function call,
600 -- that could lead to a duplication of the call, which was already
601 -- substituted for the allocator.
603 if not Aggr_In_Place then
604 Remove_Side_Effects (Exp);
608 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
610 -- For a class wide allocation generate the following code:
612 -- type Equiv_Record is record ... end record;
613 -- implicit subtype CW is <Class_Wide_Subytpe>;
614 -- temp : PtrT := new CW'(CW!(expr));
616 if Is_Class_Wide_Type (T) then
617 Expand_Subtype_From_Expr (Empty, T, Indic, Exp);
619 -- Ada 2005 (AI-251): If the expression is a class-wide interface
620 -- object we generate code to move up "this" to reference the
621 -- base of the object before allocating the new object.
623 -- Note that Exp'Address is recursively expanded into a call
624 -- to Base_Address (Exp.Tag)
626 if Is_Class_Wide_Type (Etype (Exp))
627 and then Is_Interface (Etype (Exp))
631 Unchecked_Convert_To (Entity (Indic),
632 Make_Explicit_Dereference (Loc,
633 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
634 Make_Attribute_Reference (Loc,
636 Attribute_Name => Name_Address)))));
641 Unchecked_Convert_To (Entity (Indic), Exp));
644 Analyze_And_Resolve (Expression (N), Entity (Indic));
647 -- Keep separate the management of allocators returning interfaces
649 if not Is_Interface (Directly_Designated_Type (PtrT)) then
650 if Aggr_In_Place then
652 Make_Object_Declaration (Loc,
653 Defining_Identifier => Temp,
654 Object_Definition => New_Reference_To (PtrT, Loc),
657 New_Reference_To (Etype (Exp), Loc)));
659 Set_Comes_From_Source
660 (Expression (Tmp_Node), Comes_From_Source (N));
662 Set_No_Initialization (Expression (Tmp_Node));
663 Insert_Action (N, Tmp_Node);
665 if Controlled_Type (T)
666 and then Ekind (PtrT) = E_Anonymous_Access_Type
668 -- Create local finalization list for access parameter
670 Flist := Get_Allocator_Final_List (N, Base_Type (T), PtrT);
673 Convert_Aggr_In_Allocator (N, Tmp_Node, Exp);
675 Node := Relocate_Node (N);
678 Make_Object_Declaration (Loc,
679 Defining_Identifier => Temp,
680 Constant_Present => True,
681 Object_Definition => New_Reference_To (PtrT, Loc),
682 Expression => Node));
685 -- Ada 2005 (AI-251): Handle allocators whose designated type is an
686 -- interface type. In this case we use the type of the qualified
687 -- expression to allocate the object.
691 Def_Id : constant Entity_Id :=
692 Make_Defining_Identifier (Loc,
693 New_Internal_Name ('T'));
698 Make_Full_Type_Declaration (Loc,
699 Defining_Identifier => Def_Id,
701 Make_Access_To_Object_Definition (Loc,
703 Null_Exclusion_Present => False,
704 Constant_Present => False,
705 Subtype_Indication =>
706 New_Reference_To (Etype (Exp), Loc)));
708 Insert_Action (N, New_Decl);
710 -- Inherit the final chain to ensure that the expansion of the
711 -- aggregate is correct in case of controlled types
713 if Controlled_Type (Directly_Designated_Type (PtrT)) then
714 Set_Associated_Final_Chain (Def_Id,
715 Associated_Final_Chain (PtrT));
718 -- Declare the object using the previous type declaration
720 if Aggr_In_Place then
722 Make_Object_Declaration (Loc,
723 Defining_Identifier => Temp,
724 Object_Definition => New_Reference_To (Def_Id, Loc),
727 New_Reference_To (Etype (Exp), Loc)));
729 Set_Comes_From_Source
730 (Expression (Tmp_Node), Comes_From_Source (N));
732 Set_No_Initialization (Expression (Tmp_Node));
733 Insert_Action (N, Tmp_Node);
735 if Controlled_Type (T)
736 and then Ekind (PtrT) = E_Anonymous_Access_Type
738 -- Create local finalization list for access parameter
741 Get_Allocator_Final_List (N, Base_Type (T), PtrT);
744 Convert_Aggr_In_Allocator (N, Tmp_Node, Exp);
746 Node := Relocate_Node (N);
749 Make_Object_Declaration (Loc,
750 Defining_Identifier => Temp,
751 Constant_Present => True,
752 Object_Definition => New_Reference_To (Def_Id, Loc),
753 Expression => Node));
756 -- Generate an additional object containing the address of the
757 -- returned object. The type of this second object declaration
758 -- is the correct type required for the common proceessing
759 -- that is still performed by this subprogram. The displacement
760 -- of this pointer to reference the component associated with
761 -- the interface type will be done at the end of the common
765 Make_Object_Declaration (Loc,
766 Defining_Identifier => Make_Defining_Identifier (Loc,
767 New_Internal_Name ('P')),
768 Object_Definition => New_Reference_To (PtrT, Loc),
769 Expression => Unchecked_Convert_To (PtrT,
770 New_Reference_To (Temp, Loc)));
772 Insert_Action (N, New_Decl);
774 Tmp_Node := New_Decl;
775 Temp := Defining_Identifier (New_Decl);
779 Apply_Accessibility_Check (Temp);
781 -- Generate the tag assignment
783 -- Suppress the tag assignment when VM_Target because VM tags are
784 -- represented implicitly in objects.
786 if VM_Target /= No_VM then
789 -- Ada 2005 (AI-251): Suppress the tag assignment with class-wide
790 -- interface objects because in this case the tag does not change.
792 elsif Is_Interface (Directly_Designated_Type (Etype (N))) then
793 pragma Assert (Is_Class_Wide_Type
794 (Directly_Designated_Type (Etype (N))));
797 elsif Is_Tagged_Type (T) and then not Is_Class_Wide_Type (T) then
799 TagR := New_Reference_To (Temp, Loc);
801 elsif Is_Private_Type (T)
802 and then Is_Tagged_Type (Underlying_Type (T))
804 TagT := Underlying_Type (T);
806 Unchecked_Convert_To (Underlying_Type (T),
807 Make_Explicit_Dereference (Loc,
808 Prefix => New_Reference_To (Temp, Loc)));
811 if Present (TagT) then
813 Make_Assignment_Statement (Loc,
815 Make_Selected_Component (Loc,
818 New_Reference_To (First_Tag_Component (TagT), Loc)),
821 Unchecked_Convert_To (RTE (RE_Tag),
823 (Elists.Node (First_Elmt (Access_Disp_Table (TagT))),
826 -- The previous assignment has to be done in any case
828 Set_Assignment_OK (Name (Tag_Assign));
829 Insert_Action (N, Tag_Assign);
832 if Controlled_Type (DesigT)
833 and then Controlled_Type (T)
837 Apool : constant Entity_Id :=
838 Associated_Storage_Pool (PtrT);
841 -- If it is an allocation on the secondary stack
842 -- (i.e. a value returned from a function), the object
843 -- is attached on the caller side as soon as the call
844 -- is completed (see Expand_Ctrl_Function_Call)
846 if Is_RTE (Apool, RE_SS_Pool) then
848 F : constant Entity_Id :=
849 Make_Defining_Identifier (Loc,
850 New_Internal_Name ('F'));
853 Make_Object_Declaration (Loc,
854 Defining_Identifier => F,
855 Object_Definition => New_Reference_To (RTE
856 (RE_Finalizable_Ptr), Loc)));
858 Flist := New_Reference_To (F, Loc);
859 Attach := Make_Integer_Literal (Loc, 1);
862 -- Normal case, not a secondary stack allocation
865 if Controlled_Type (T)
866 and then Ekind (PtrT) = E_Anonymous_Access_Type
868 -- Create local finalization list for access parameter
871 Get_Allocator_Final_List (N, Base_Type (T), PtrT);
873 Flist := Find_Final_List (PtrT);
876 Attach := Make_Integer_Literal (Loc, 2);
879 -- Generate an Adjust call if the object will be moved. In Ada
880 -- 2005, the object may be inherently limited, in which case
881 -- there is no Adjust procedure, and the object is built in
882 -- place. In Ada 95, the object can be limited but not
883 -- inherently limited if this allocator came from a return
884 -- statement (we're allocating the result on the secondary
885 -- stack). In that case, the object will be moved, so we _do_
889 and then not Is_Inherently_Limited_Type (T)
895 -- An unchecked conversion is needed in the
896 -- classwide case because the designated type
897 -- can be an ancestor of the subtype mark of
900 Unchecked_Convert_To (T,
901 Make_Explicit_Dereference (Loc,
902 Prefix => New_Reference_To (Temp, Loc))),
906 With_Attach => Attach,
912 Rewrite (N, New_Reference_To (Temp, Loc));
913 Analyze_And_Resolve (N, PtrT);
915 -- Ada 2005 (AI-251): Displace the pointer to reference the
916 -- record component containing the secondary dispatch table
917 -- of the interface type.
919 if Is_Interface (Directly_Designated_Type (PtrT)) then
920 Displace_Allocator_Pointer (N);
923 elsif Aggr_In_Place then
925 Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
927 Make_Object_Declaration (Loc,
928 Defining_Identifier => Temp,
929 Object_Definition => New_Reference_To (PtrT, Loc),
930 Expression => Make_Allocator (Loc,
931 New_Reference_To (Etype (Exp), Loc)));
933 Set_Comes_From_Source
934 (Expression (Tmp_Node), Comes_From_Source (N));
936 Set_No_Initialization (Expression (Tmp_Node));
937 Insert_Action (N, Tmp_Node);
938 Convert_Aggr_In_Allocator (N, Tmp_Node, Exp);
939 Rewrite (N, New_Reference_To (Temp, Loc));
940 Analyze_And_Resolve (N, PtrT);
942 elsif Is_Access_Type (DesigT)
943 and then Nkind (Exp) = N_Allocator
944 and then Nkind (Expression (Exp)) /= N_Qualified_Expression
946 -- Apply constraint to designated subtype indication
948 Apply_Constraint_Check (Expression (Exp),
949 Designated_Type (DesigT),
952 if Nkind (Expression (Exp)) = N_Raise_Constraint_Error then
954 -- Propagate constraint_error to enclosing allocator
956 Rewrite (Exp, New_Copy (Expression (Exp)));
959 -- First check against the type of the qualified expression
961 -- NOTE: The commented call should be correct, but for
962 -- some reason causes the compiler to bomb (sigsegv) on
963 -- ACVC test c34007g, so for now we just perform the old
964 -- (incorrect) test against the designated subtype with
965 -- no sliding in the else part of the if statement below.
968 -- Apply_Constraint_Check (Exp, T, No_Sliding => True);
970 -- A check is also needed in cases where the designated
971 -- subtype is constrained and differs from the subtype
972 -- given in the qualified expression. Note that the check
973 -- on the qualified expression does not allow sliding,
974 -- but this check does (a relaxation from Ada 83).
976 if Is_Constrained (DesigT)
977 and then not Subtypes_Statically_Match
980 Apply_Constraint_Check
981 (Exp, DesigT, No_Sliding => False);
983 -- The nonsliding check should really be performed
984 -- (unconditionally) against the subtype of the
985 -- qualified expression, but that causes a problem
986 -- with c34007g (see above), so for now we retain this.
989 Apply_Constraint_Check
990 (Exp, DesigT, No_Sliding => True);
993 -- For an access to unconstrained packed array, GIGI needs
994 -- to see an expression with a constrained subtype in order
995 -- to compute the proper size for the allocator.
998 and then not Is_Constrained (T)
999 and then Is_Packed (T)
1002 ConstrT : constant Entity_Id :=
1003 Make_Defining_Identifier (Loc,
1004 Chars => New_Internal_Name ('A'));
1005 Internal_Exp : constant Node_Id := Relocate_Node (Exp);
1008 Make_Subtype_Declaration (Loc,
1009 Defining_Identifier => ConstrT,
1010 Subtype_Indication =>
1011 Make_Subtype_From_Expr (Exp, T)));
1012 Freeze_Itype (ConstrT, Exp);
1013 Rewrite (Exp, OK_Convert_To (ConstrT, Internal_Exp));
1017 -- Ada 2005 (AI-318-02): If the initialization expression is a
1018 -- call to a build-in-place function, then access to the allocated
1019 -- object must be passed to the function. Currently we limit such
1020 -- functions to those with constrained limited result subtypes,
1021 -- but eventually we plan to expand the allowed forms of funtions
1022 -- that are treated as build-in-place.
1024 if Ada_Version >= Ada_05
1025 and then Is_Build_In_Place_Function_Call (Exp)
1027 Make_Build_In_Place_Call_In_Allocator (N, Exp);
1032 when RE_Not_Available =>
1034 end Expand_Allocator_Expression;
1036 -----------------------------
1037 -- Expand_Array_Comparison --
1038 -----------------------------
1040 -- Expansion is only required in the case of array types. For the
1041 -- unpacked case, an appropriate runtime routine is called. For
1042 -- packed cases, and also in some other cases where a runtime
1043 -- routine cannot be called, the form of the expansion is:
1045 -- [body for greater_nn; boolean_expression]
1047 -- The body is built by Make_Array_Comparison_Op, and the form of the
1048 -- Boolean expression depends on the operator involved.
1050 procedure Expand_Array_Comparison (N : Node_Id) is
1051 Loc : constant Source_Ptr := Sloc (N);
1052 Op1 : Node_Id := Left_Opnd (N);
1053 Op2 : Node_Id := Right_Opnd (N);
1054 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
1055 Ctyp : constant Entity_Id := Component_Type (Typ1);
1058 Func_Body : Node_Id;
1059 Func_Name : Entity_Id;
1063 Byte_Addressable : constant Boolean := System_Storage_Unit = Byte'Size;
1064 -- True for byte addressable target
1066 function Length_Less_Than_4 (Opnd : Node_Id) return Boolean;
1067 -- Returns True if the length of the given operand is known to be
1068 -- less than 4. Returns False if this length is known to be four
1069 -- or greater or is not known at compile time.
1071 ------------------------
1072 -- Length_Less_Than_4 --
1073 ------------------------
1075 function Length_Less_Than_4 (Opnd : Node_Id) return Boolean is
1076 Otyp : constant Entity_Id := Etype (Opnd);
1079 if Ekind (Otyp) = E_String_Literal_Subtype then
1080 return String_Literal_Length (Otyp) < 4;
1084 Ityp : constant Entity_Id := Etype (First_Index (Otyp));
1085 Lo : constant Node_Id := Type_Low_Bound (Ityp);
1086 Hi : constant Node_Id := Type_High_Bound (Ityp);
1091 if Compile_Time_Known_Value (Lo) then
1092 Lov := Expr_Value (Lo);
1097 if Compile_Time_Known_Value (Hi) then
1098 Hiv := Expr_Value (Hi);
1103 return Hiv < Lov + 3;
1106 end Length_Less_Than_4;
1108 -- Start of processing for Expand_Array_Comparison
1111 -- Deal first with unpacked case, where we can call a runtime routine
1112 -- except that we avoid this for targets for which are not addressable
1113 -- by bytes, and for the JVM/CIL, since they do not support direct
1114 -- addressing of array components.
1116 if not Is_Bit_Packed_Array (Typ1)
1117 and then Byte_Addressable
1118 and then VM_Target = No_VM
1120 -- The call we generate is:
1122 -- Compare_Array_xn[_Unaligned]
1123 -- (left'address, right'address, left'length, right'length) <op> 0
1125 -- x = U for unsigned, S for signed
1126 -- n = 8,16,32,64 for component size
1127 -- Add _Unaligned if length < 4 and component size is 8.
1128 -- <op> is the standard comparison operator
1130 if Component_Size (Typ1) = 8 then
1131 if Length_Less_Than_4 (Op1)
1133 Length_Less_Than_4 (Op2)
1135 if Is_Unsigned_Type (Ctyp) then
1136 Comp := RE_Compare_Array_U8_Unaligned;
1138 Comp := RE_Compare_Array_S8_Unaligned;
1142 if Is_Unsigned_Type (Ctyp) then
1143 Comp := RE_Compare_Array_U8;
1145 Comp := RE_Compare_Array_S8;
1149 elsif Component_Size (Typ1) = 16 then
1150 if Is_Unsigned_Type (Ctyp) then
1151 Comp := RE_Compare_Array_U16;
1153 Comp := RE_Compare_Array_S16;
1156 elsif Component_Size (Typ1) = 32 then
1157 if Is_Unsigned_Type (Ctyp) then
1158 Comp := RE_Compare_Array_U32;
1160 Comp := RE_Compare_Array_S32;
1163 else pragma Assert (Component_Size (Typ1) = 64);
1164 if Is_Unsigned_Type (Ctyp) then
1165 Comp := RE_Compare_Array_U64;
1167 Comp := RE_Compare_Array_S64;
1171 Remove_Side_Effects (Op1, Name_Req => True);
1172 Remove_Side_Effects (Op2, Name_Req => True);
1175 Make_Function_Call (Sloc (Op1),
1176 Name => New_Occurrence_Of (RTE (Comp), Loc),
1178 Parameter_Associations => New_List (
1179 Make_Attribute_Reference (Loc,
1180 Prefix => Relocate_Node (Op1),
1181 Attribute_Name => Name_Address),
1183 Make_Attribute_Reference (Loc,
1184 Prefix => Relocate_Node (Op2),
1185 Attribute_Name => Name_Address),
1187 Make_Attribute_Reference (Loc,
1188 Prefix => Relocate_Node (Op1),
1189 Attribute_Name => Name_Length),
1191 Make_Attribute_Reference (Loc,
1192 Prefix => Relocate_Node (Op2),
1193 Attribute_Name => Name_Length))));
1196 Make_Integer_Literal (Sloc (Op2),
1199 Analyze_And_Resolve (Op1, Standard_Integer);
1200 Analyze_And_Resolve (Op2, Standard_Integer);
1204 -- Cases where we cannot make runtime call
1206 -- For (a <= b) we convert to not (a > b)
1208 if Chars (N) = Name_Op_Le then
1214 Right_Opnd => Op2)));
1215 Analyze_And_Resolve (N, Standard_Boolean);
1218 -- For < the Boolean expression is
1219 -- greater__nn (op2, op1)
1221 elsif Chars (N) = Name_Op_Lt then
1222 Func_Body := Make_Array_Comparison_Op (Typ1, N);
1226 Op1 := Right_Opnd (N);
1227 Op2 := Left_Opnd (N);
1229 -- For (a >= b) we convert to not (a < b)
1231 elsif Chars (N) = Name_Op_Ge then
1237 Right_Opnd => Op2)));
1238 Analyze_And_Resolve (N, Standard_Boolean);
1241 -- For > the Boolean expression is
1242 -- greater__nn (op1, op2)
1245 pragma Assert (Chars (N) = Name_Op_Gt);
1246 Func_Body := Make_Array_Comparison_Op (Typ1, N);
1249 Func_Name := Defining_Unit_Name (Specification (Func_Body));
1251 Make_Function_Call (Loc,
1252 Name => New_Reference_To (Func_Name, Loc),
1253 Parameter_Associations => New_List (Op1, Op2));
1255 Insert_Action (N, Func_Body);
1257 Analyze_And_Resolve (N, Standard_Boolean);
1260 when RE_Not_Available =>
1262 end Expand_Array_Comparison;
1264 ---------------------------
1265 -- Expand_Array_Equality --
1266 ---------------------------
1268 -- Expand an equality function for multi-dimensional arrays. Here is
1269 -- an example of such a function for Nb_Dimension = 2
1271 -- function Enn (A : atyp; B : btyp) return boolean is
1273 -- if (A'length (1) = 0 or else A'length (2) = 0)
1275 -- (B'length (1) = 0 or else B'length (2) = 0)
1277 -- return True; -- RM 4.5.2(22)
1280 -- if A'length (1) /= B'length (1)
1282 -- A'length (2) /= B'length (2)
1284 -- return False; -- RM 4.5.2(23)
1288 -- A1 : Index_T1 := A'first (1);
1289 -- B1 : Index_T1 := B'first (1);
1293 -- A2 : Index_T2 := A'first (2);
1294 -- B2 : Index_T2 := B'first (2);
1297 -- if A (A1, A2) /= B (B1, B2) then
1301 -- exit when A2 = A'last (2);
1302 -- A2 := Index_T2'succ (A2);
1303 -- B2 := Index_T2'succ (B2);
1307 -- exit when A1 = A'last (1);
1308 -- A1 := Index_T1'succ (A1);
1309 -- B1 := Index_T1'succ (B1);
1316 -- Note on the formal types used (atyp and btyp). If either of the
1317 -- arrays is of a private type, we use the underlying type, and
1318 -- do an unchecked conversion of the actual. If either of the arrays
1319 -- has a bound depending on a discriminant, then we use the base type
1320 -- since otherwise we have an escaped discriminant in the function.
1322 -- If both arrays are constrained and have the same bounds, we can
1323 -- generate a loop with an explicit iteration scheme using a 'Range
1324 -- attribute over the first array.
1326 function Expand_Array_Equality
1331 Typ : Entity_Id) return Node_Id
1333 Loc : constant Source_Ptr := Sloc (Nod);
1334 Decls : constant List_Id := New_List;
1335 Index_List1 : constant List_Id := New_List;
1336 Index_List2 : constant List_Id := New_List;
1340 Func_Name : Entity_Id;
1341 Func_Body : Node_Id;
1343 A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
1344 B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
1348 -- The parameter types to be used for the formals
1353 Num : Int) return Node_Id;
1354 -- This builds the attribute reference Arr'Nam (Expr)
1356 function Component_Equality (Typ : Entity_Id) return Node_Id;
1357 -- Create one statement to compare corresponding components,
1358 -- designated by a full set of indices.
1360 function Get_Arg_Type (N : Node_Id) return Entity_Id;
1361 -- Given one of the arguments, computes the appropriate type to
1362 -- be used for that argument in the corresponding function formal
1364 function Handle_One_Dimension
1366 Index : Node_Id) return Node_Id;
1367 -- This procedure returns the following code
1370 -- Bn : Index_T := B'First (N);
1374 -- exit when An = A'Last (N);
1375 -- An := Index_T'Succ (An)
1376 -- Bn := Index_T'Succ (Bn)
1380 -- If both indices are constrained and identical, the procedure
1381 -- returns a simpler loop:
1383 -- for An in A'Range (N) loop
1387 -- N is the dimension for which we are generating a loop. Index is the
1388 -- N'th index node, whose Etype is Index_Type_n in the above code.
1389 -- The xxx statement is either the loop or declare for the next
1390 -- dimension or if this is the last dimension the comparison
1391 -- of corresponding components of the arrays.
1393 -- The actual way the code works is to return the comparison
1394 -- of corresponding components for the N+1 call. That's neater!
1396 function Test_Empty_Arrays return Node_Id;
1397 -- This function constructs the test for both arrays being empty
1398 -- (A'length (1) = 0 or else A'length (2) = 0 or else ...)
1400 -- (B'length (1) = 0 or else B'length (2) = 0 or else ...)
1402 function Test_Lengths_Correspond return Node_Id;
1403 -- This function constructs the test for arrays having different
1404 -- lengths in at least one index position, in which case resull
1406 -- A'length (1) /= B'length (1)
1408 -- A'length (2) /= B'length (2)
1419 Num : Int) return Node_Id
1423 Make_Attribute_Reference (Loc,
1424 Attribute_Name => Nam,
1425 Prefix => New_Reference_To (Arr, Loc),
1426 Expressions => New_List (Make_Integer_Literal (Loc, Num)));
1429 ------------------------
1430 -- Component_Equality --
1431 ------------------------
1433 function Component_Equality (Typ : Entity_Id) return Node_Id is
1438 -- if a(i1...) /= b(j1...) then return false; end if;
1441 Make_Indexed_Component (Loc,
1442 Prefix => Make_Identifier (Loc, Chars (A)),
1443 Expressions => Index_List1);
1446 Make_Indexed_Component (Loc,
1447 Prefix => Make_Identifier (Loc, Chars (B)),
1448 Expressions => Index_List2);
1450 Test := Expand_Composite_Equality
1451 (Nod, Component_Type (Typ), L, R, Decls);
1453 -- If some (sub)component is an unchecked_union, the whole operation
1454 -- will raise program error.
1456 if Nkind (Test) = N_Raise_Program_Error then
1458 -- This node is going to be inserted at a location where a
1459 -- statement is expected: clear its Etype so analysis will
1460 -- set it to the expected Standard_Void_Type.
1462 Set_Etype (Test, Empty);
1467 Make_Implicit_If_Statement (Nod,
1468 Condition => Make_Op_Not (Loc, Right_Opnd => Test),
1469 Then_Statements => New_List (
1470 Make_Simple_Return_Statement (Loc,
1471 Expression => New_Occurrence_Of (Standard_False, Loc))));
1473 end Component_Equality;
1479 function Get_Arg_Type (N : Node_Id) return Entity_Id is
1490 T := Underlying_Type (T);
1492 X := First_Index (T);
1493 while Present (X) loop
1494 if Denotes_Discriminant (Type_Low_Bound (Etype (X)))
1496 Denotes_Discriminant (Type_High_Bound (Etype (X)))
1509 --------------------------
1510 -- Handle_One_Dimension --
1511 ---------------------------
1513 function Handle_One_Dimension
1515 Index : Node_Id) return Node_Id
1517 Need_Separate_Indexes : constant Boolean :=
1519 or else not Is_Constrained (Ltyp);
1520 -- If the index types are identical, and we are working with
1521 -- constrained types, then we can use the same index for both of
1524 An : constant Entity_Id := Make_Defining_Identifier (Loc,
1525 Chars => New_Internal_Name ('A'));
1528 Index_T : Entity_Id;
1533 if N > Number_Dimensions (Ltyp) then
1534 return Component_Equality (Ltyp);
1537 -- Case where we generate a loop
1539 Index_T := Base_Type (Etype (Index));
1541 if Need_Separate_Indexes then
1543 Make_Defining_Identifier (Loc,
1544 Chars => New_Internal_Name ('B'));
1549 Append (New_Reference_To (An, Loc), Index_List1);
1550 Append (New_Reference_To (Bn, Loc), Index_List2);
1552 Stm_List := New_List (
1553 Handle_One_Dimension (N + 1, Next_Index (Index)));
1555 if Need_Separate_Indexes then
1557 -- Generate guard for loop, followed by increments of indices
1559 Append_To (Stm_List,
1560 Make_Exit_Statement (Loc,
1563 Left_Opnd => New_Reference_To (An, Loc),
1564 Right_Opnd => Arr_Attr (A, Name_Last, N))));
1566 Append_To (Stm_List,
1567 Make_Assignment_Statement (Loc,
1568 Name => New_Reference_To (An, Loc),
1570 Make_Attribute_Reference (Loc,
1571 Prefix => New_Reference_To (Index_T, Loc),
1572 Attribute_Name => Name_Succ,
1573 Expressions => New_List (New_Reference_To (An, Loc)))));
1575 Append_To (Stm_List,
1576 Make_Assignment_Statement (Loc,
1577 Name => New_Reference_To (Bn, Loc),
1579 Make_Attribute_Reference (Loc,
1580 Prefix => New_Reference_To (Index_T, Loc),
1581 Attribute_Name => Name_Succ,
1582 Expressions => New_List (New_Reference_To (Bn, Loc)))));
1585 -- If separate indexes, we need a declare block for An and Bn, and a
1586 -- loop without an iteration scheme.
1588 if Need_Separate_Indexes then
1590 Make_Implicit_Loop_Statement (Nod, Statements => Stm_List);
1593 Make_Block_Statement (Loc,
1594 Declarations => New_List (
1595 Make_Object_Declaration (Loc,
1596 Defining_Identifier => An,
1597 Object_Definition => New_Reference_To (Index_T, Loc),
1598 Expression => Arr_Attr (A, Name_First, N)),
1600 Make_Object_Declaration (Loc,
1601 Defining_Identifier => Bn,
1602 Object_Definition => New_Reference_To (Index_T, Loc),
1603 Expression => Arr_Attr (B, Name_First, N))),
1605 Handled_Statement_Sequence =>
1606 Make_Handled_Sequence_Of_Statements (Loc,
1607 Statements => New_List (Loop_Stm)));
1609 -- If no separate indexes, return loop statement with explicit
1610 -- iteration scheme on its own
1614 Make_Implicit_Loop_Statement (Nod,
1615 Statements => Stm_List,
1617 Make_Iteration_Scheme (Loc,
1618 Loop_Parameter_Specification =>
1619 Make_Loop_Parameter_Specification (Loc,
1620 Defining_Identifier => An,
1621 Discrete_Subtype_Definition =>
1622 Arr_Attr (A, Name_Range, N))));
1625 end Handle_One_Dimension;
1627 -----------------------
1628 -- Test_Empty_Arrays --
1629 -----------------------
1631 function Test_Empty_Arrays return Node_Id is
1641 for J in 1 .. Number_Dimensions (Ltyp) loop
1644 Left_Opnd => Arr_Attr (A, Name_Length, J),
1645 Right_Opnd => Make_Integer_Literal (Loc, 0));
1649 Left_Opnd => Arr_Attr (B, Name_Length, J),
1650 Right_Opnd => Make_Integer_Literal (Loc, 0));
1659 Left_Opnd => Relocate_Node (Alist),
1660 Right_Opnd => Atest);
1664 Left_Opnd => Relocate_Node (Blist),
1665 Right_Opnd => Btest);
1672 Right_Opnd => Blist);
1673 end Test_Empty_Arrays;
1675 -----------------------------
1676 -- Test_Lengths_Correspond --
1677 -----------------------------
1679 function Test_Lengths_Correspond return Node_Id is
1685 for J in 1 .. Number_Dimensions (Ltyp) loop
1688 Left_Opnd => Arr_Attr (A, Name_Length, J),
1689 Right_Opnd => Arr_Attr (B, Name_Length, J));
1696 Left_Opnd => Relocate_Node (Result),
1697 Right_Opnd => Rtest);
1702 end Test_Lengths_Correspond;
1704 -- Start of processing for Expand_Array_Equality
1707 Ltyp := Get_Arg_Type (Lhs);
1708 Rtyp := Get_Arg_Type (Rhs);
1710 -- For now, if the argument types are not the same, go to the
1711 -- base type, since the code assumes that the formals have the
1712 -- same type. This is fixable in future ???
1714 if Ltyp /= Rtyp then
1715 Ltyp := Base_Type (Ltyp);
1716 Rtyp := Base_Type (Rtyp);
1717 pragma Assert (Ltyp = Rtyp);
1720 -- Build list of formals for function
1722 Formals := New_List (
1723 Make_Parameter_Specification (Loc,
1724 Defining_Identifier => A,
1725 Parameter_Type => New_Reference_To (Ltyp, Loc)),
1727 Make_Parameter_Specification (Loc,
1728 Defining_Identifier => B,
1729 Parameter_Type => New_Reference_To (Rtyp, Loc)));
1731 Func_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
1733 -- Build statement sequence for function
1736 Make_Subprogram_Body (Loc,
1738 Make_Function_Specification (Loc,
1739 Defining_Unit_Name => Func_Name,
1740 Parameter_Specifications => Formals,
1741 Result_Definition => New_Reference_To (Standard_Boolean, Loc)),
1743 Declarations => Decls,
1745 Handled_Statement_Sequence =>
1746 Make_Handled_Sequence_Of_Statements (Loc,
1747 Statements => New_List (
1749 Make_Implicit_If_Statement (Nod,
1750 Condition => Test_Empty_Arrays,
1751 Then_Statements => New_List (
1752 Make_Simple_Return_Statement (Loc,
1754 New_Occurrence_Of (Standard_True, Loc)))),
1756 Make_Implicit_If_Statement (Nod,
1757 Condition => Test_Lengths_Correspond,
1758 Then_Statements => New_List (
1759 Make_Simple_Return_Statement (Loc,
1761 New_Occurrence_Of (Standard_False, Loc)))),
1763 Handle_One_Dimension (1, First_Index (Ltyp)),
1765 Make_Simple_Return_Statement (Loc,
1766 Expression => New_Occurrence_Of (Standard_True, Loc)))));
1768 Set_Has_Completion (Func_Name, True);
1769 Set_Is_Inlined (Func_Name);
1771 -- If the array type is distinct from the type of the arguments,
1772 -- it is the full view of a private type. Apply an unchecked
1773 -- conversion to insure that analysis of the call succeeds.
1783 or else Base_Type (Etype (Lhs)) /= Base_Type (Ltyp)
1785 L := OK_Convert_To (Ltyp, Lhs);
1789 or else Base_Type (Etype (Rhs)) /= Base_Type (Rtyp)
1791 R := OK_Convert_To (Rtyp, Rhs);
1794 Actuals := New_List (L, R);
1797 Append_To (Bodies, Func_Body);
1800 Make_Function_Call (Loc,
1801 Name => New_Reference_To (Func_Name, Loc),
1802 Parameter_Associations => Actuals);
1803 end Expand_Array_Equality;
1805 -----------------------------
1806 -- Expand_Boolean_Operator --
1807 -----------------------------
1809 -- Note that we first get the actual subtypes of the operands,
1810 -- since we always want to deal with types that have bounds.
1812 procedure Expand_Boolean_Operator (N : Node_Id) is
1813 Typ : constant Entity_Id := Etype (N);
1816 -- Special case of bit packed array where both operands are known
1817 -- to be properly aligned. In this case we use an efficient run time
1818 -- routine to carry out the operation (see System.Bit_Ops).
1820 if Is_Bit_Packed_Array (Typ)
1821 and then not Is_Possibly_Unaligned_Object (Left_Opnd (N))
1822 and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
1824 Expand_Packed_Boolean_Operator (N);
1828 -- For the normal non-packed case, the general expansion is to build
1829 -- function for carrying out the comparison (use Make_Boolean_Array_Op)
1830 -- and then inserting it into the tree. The original operator node is
1831 -- then rewritten as a call to this function. We also use this in the
1832 -- packed case if either operand is a possibly unaligned object.
1835 Loc : constant Source_Ptr := Sloc (N);
1836 L : constant Node_Id := Relocate_Node (Left_Opnd (N));
1837 R : constant Node_Id := Relocate_Node (Right_Opnd (N));
1838 Func_Body : Node_Id;
1839 Func_Name : Entity_Id;
1842 Convert_To_Actual_Subtype (L);
1843 Convert_To_Actual_Subtype (R);
1844 Ensure_Defined (Etype (L), N);
1845 Ensure_Defined (Etype (R), N);
1846 Apply_Length_Check (R, Etype (L));
1848 if Nkind (Parent (N)) = N_Assignment_Statement
1849 and then Safe_In_Place_Array_Op (Name (Parent (N)), L, R)
1851 Build_Boolean_Array_Proc_Call (Parent (N), L, R);
1853 elsif Nkind (Parent (N)) = N_Op_Not
1854 and then Nkind (N) = N_Op_And
1856 Safe_In_Place_Array_Op (Name (Parent (Parent (N))), L, R)
1861 Func_Body := Make_Boolean_Array_Op (Etype (L), N);
1862 Func_Name := Defining_Unit_Name (Specification (Func_Body));
1863 Insert_Action (N, Func_Body);
1865 -- Now rewrite the expression with a call
1868 Make_Function_Call (Loc,
1869 Name => New_Reference_To (Func_Name, Loc),
1870 Parameter_Associations =>
1873 Make_Type_Conversion
1874 (Loc, New_Reference_To (Etype (L), Loc), R))));
1876 Analyze_And_Resolve (N, Typ);
1879 end Expand_Boolean_Operator;
1881 -------------------------------
1882 -- Expand_Composite_Equality --
1883 -------------------------------
1885 -- This function is only called for comparing internal fields of composite
1886 -- types when these fields are themselves composites. This is a special
1887 -- case because it is not possible to respect normal Ada visibility rules.
1889 function Expand_Composite_Equality
1894 Bodies : List_Id) return Node_Id
1896 Loc : constant Source_Ptr := Sloc (Nod);
1897 Full_Type : Entity_Id;
1902 if Is_Private_Type (Typ) then
1903 Full_Type := Underlying_Type (Typ);
1908 -- Defense against malformed private types with no completion
1909 -- the error will be diagnosed later by check_completion
1911 if No (Full_Type) then
1912 return New_Reference_To (Standard_False, Loc);
1915 Full_Type := Base_Type (Full_Type);
1917 if Is_Array_Type (Full_Type) then
1919 -- If the operand is an elementary type other than a floating-point
1920 -- type, then we can simply use the built-in block bitwise equality,
1921 -- since the predefined equality operators always apply and bitwise
1922 -- equality is fine for all these cases.
1924 if Is_Elementary_Type (Component_Type (Full_Type))
1925 and then not Is_Floating_Point_Type (Component_Type (Full_Type))
1927 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
1929 -- For composite component types, and floating-point types, use
1930 -- the expansion. This deals with tagged component types (where
1931 -- we use the applicable equality routine) and floating-point,
1932 -- (where we need to worry about negative zeroes), and also the
1933 -- case of any composite type recursively containing such fields.
1936 return Expand_Array_Equality (Nod, Lhs, Rhs, Bodies, Full_Type);
1939 elsif Is_Tagged_Type (Full_Type) then
1941 -- Call the primitive operation "=" of this type
1943 if Is_Class_Wide_Type (Full_Type) then
1944 Full_Type := Root_Type (Full_Type);
1947 -- If this is derived from an untagged private type completed
1948 -- with a tagged type, it does not have a full view, so we
1949 -- use the primitive operations of the private type.
1950 -- This check should no longer be necessary when these
1951 -- types receive their full views ???
1953 if Is_Private_Type (Typ)
1954 and then not Is_Tagged_Type (Typ)
1955 and then not Is_Controlled (Typ)
1956 and then Is_Derived_Type (Typ)
1957 and then No (Full_View (Typ))
1959 Prim := First_Elmt (Collect_Primitive_Operations (Typ));
1961 Prim := First_Elmt (Primitive_Operations (Full_Type));
1965 Eq_Op := Node (Prim);
1966 exit when Chars (Eq_Op) = Name_Op_Eq
1967 and then Etype (First_Formal (Eq_Op)) =
1968 Etype (Next_Formal (First_Formal (Eq_Op)))
1969 and then Base_Type (Etype (Eq_Op)) = Standard_Boolean;
1971 pragma Assert (Present (Prim));
1974 Eq_Op := Node (Prim);
1977 Make_Function_Call (Loc,
1978 Name => New_Reference_To (Eq_Op, Loc),
1979 Parameter_Associations =>
1981 (Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Lhs),
1982 Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Rhs)));
1984 elsif Is_Record_Type (Full_Type) then
1985 Eq_Op := TSS (Full_Type, TSS_Composite_Equality);
1987 if Present (Eq_Op) then
1988 if Etype (First_Formal (Eq_Op)) /= Full_Type then
1990 -- Inherited equality from parent type. Convert the actuals
1991 -- to match signature of operation.
1994 T : constant Entity_Id := Etype (First_Formal (Eq_Op));
1998 Make_Function_Call (Loc,
1999 Name => New_Reference_To (Eq_Op, Loc),
2000 Parameter_Associations =>
2001 New_List (OK_Convert_To (T, Lhs),
2002 OK_Convert_To (T, Rhs)));
2006 -- Comparison between Unchecked_Union components
2008 if Is_Unchecked_Union (Full_Type) then
2010 Lhs_Type : Node_Id := Full_Type;
2011 Rhs_Type : Node_Id := Full_Type;
2012 Lhs_Discr_Val : Node_Id;
2013 Rhs_Discr_Val : Node_Id;
2018 if Nkind (Lhs) = N_Selected_Component then
2019 Lhs_Type := Etype (Entity (Selector_Name (Lhs)));
2024 if Nkind (Rhs) = N_Selected_Component then
2025 Rhs_Type := Etype (Entity (Selector_Name (Rhs)));
2028 -- Lhs of the composite equality
2030 if Is_Constrained (Lhs_Type) then
2032 -- Since the enclosing record can never be an
2033 -- Unchecked_Union (this code is executed for records
2034 -- that do not have variants), we may reference its
2037 if Nkind (Lhs) = N_Selected_Component
2038 and then Has_Per_Object_Constraint (
2039 Entity (Selector_Name (Lhs)))
2042 Make_Selected_Component (Loc,
2043 Prefix => Prefix (Lhs),
2046 Get_Discriminant_Value (
2047 First_Discriminant (Lhs_Type),
2049 Stored_Constraint (Lhs_Type))));
2052 Lhs_Discr_Val := New_Copy (
2053 Get_Discriminant_Value (
2054 First_Discriminant (Lhs_Type),
2056 Stored_Constraint (Lhs_Type)));
2060 -- It is not possible to infer the discriminant since
2061 -- the subtype is not constrained.
2064 Make_Raise_Program_Error (Loc,
2065 Reason => PE_Unchecked_Union_Restriction);
2068 -- Rhs of the composite equality
2070 if Is_Constrained (Rhs_Type) then
2071 if Nkind (Rhs) = N_Selected_Component
2072 and then Has_Per_Object_Constraint (
2073 Entity (Selector_Name (Rhs)))
2076 Make_Selected_Component (Loc,
2077 Prefix => Prefix (Rhs),
2080 Get_Discriminant_Value (
2081 First_Discriminant (Rhs_Type),
2083 Stored_Constraint (Rhs_Type))));
2086 Rhs_Discr_Val := New_Copy (
2087 Get_Discriminant_Value (
2088 First_Discriminant (Rhs_Type),
2090 Stored_Constraint (Rhs_Type)));
2095 Make_Raise_Program_Error (Loc,
2096 Reason => PE_Unchecked_Union_Restriction);
2099 -- Call the TSS equality function with the inferred
2100 -- discriminant values.
2103 Make_Function_Call (Loc,
2104 Name => New_Reference_To (Eq_Op, Loc),
2105 Parameter_Associations => New_List (
2113 -- Shouldn't this be an else, we can't fall through
2114 -- the above IF, right???
2117 Make_Function_Call (Loc,
2118 Name => New_Reference_To (Eq_Op, Loc),
2119 Parameter_Associations => New_List (Lhs, Rhs));
2123 return Expand_Record_Equality (Nod, Full_Type, Lhs, Rhs, Bodies);
2127 -- It can be a simple record or the full view of a scalar private
2129 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
2131 end Expand_Composite_Equality;
2133 ------------------------------
2134 -- Expand_Concatenate_Other --
2135 ------------------------------
2137 -- Let n be the number of array operands to be concatenated, Base_Typ
2138 -- their base type, Ind_Typ their index type, and Arr_Typ the original
2139 -- array type to which the concatenantion operator applies, then the
2140 -- following subprogram is constructed:
2142 -- [function Cnn (S1 : Base_Typ; ...; Sn : Base_Typ) return Base_Typ is
2145 -- if S1'Length /= 0 then
2146 -- L := XXX; --> XXX = S1'First if Arr_Typ is unconstrained
2147 -- XXX = Arr_Typ'First otherwise
2148 -- elsif S2'Length /= 0 then
2149 -- L := YYY; --> YYY = S2'First if Arr_Typ is unconstrained
2150 -- YYY = Arr_Typ'First otherwise
2152 -- elsif Sn-1'Length /= 0 then
2153 -- L := ZZZ; --> ZZZ = Sn-1'First if Arr_Typ is unconstrained
2154 -- ZZZ = Arr_Typ'First otherwise
2162 -- Ind_Typ'Val ((((S1'Length - 1) + S2'Length) + ... + Sn'Length)
2163 -- + Ind_Typ'Pos (L));
2164 -- R : Base_Typ (L .. H);
2166 -- if S1'Length /= 0 then
2170 -- L := Ind_Typ'Succ (L);
2171 -- exit when P = S1'Last;
2172 -- P := Ind_Typ'Succ (P);
2176 -- if S2'Length /= 0 then
2177 -- L := Ind_Typ'Succ (L);
2180 -- L := Ind_Typ'Succ (L);
2181 -- exit when P = S2'Last;
2182 -- P := Ind_Typ'Succ (P);
2188 -- if Sn'Length /= 0 then
2192 -- L := Ind_Typ'Succ (L);
2193 -- exit when P = Sn'Last;
2194 -- P := Ind_Typ'Succ (P);
2202 procedure Expand_Concatenate_Other (Cnode : Node_Id; Opnds : List_Id) is
2203 Loc : constant Source_Ptr := Sloc (Cnode);
2204 Nb_Opnds : constant Nat := List_Length (Opnds);
2206 Arr_Typ : constant Entity_Id := Etype (Entity (Cnode));
2207 Base_Typ : constant Entity_Id := Base_Type (Etype (Cnode));
2208 Ind_Typ : constant Entity_Id := Etype (First_Index (Base_Typ));
2211 Func_Spec : Node_Id;
2212 Param_Specs : List_Id;
2214 Func_Body : Node_Id;
2215 Func_Decls : List_Id;
2216 Func_Stmts : List_Id;
2221 Elsif_List : List_Id;
2223 Declare_Block : Node_Id;
2224 Declare_Decls : List_Id;
2225 Declare_Stmts : List_Id;
2237 function Copy_Into_R_S (I : Nat; Last : Boolean) return List_Id;
2238 -- Builds the sequence of statement:
2242 -- L := Ind_Typ'Succ (L);
2243 -- exit when P = Si'Last;
2244 -- P := Ind_Typ'Succ (P);
2247 -- where i is the input parameter I given.
2248 -- If the flag Last is true, the exit statement is emitted before
2249 -- incrementing the lower bound, to prevent the creation out of
2252 function Init_L (I : Nat) return Node_Id;
2253 -- Builds the statement:
2254 -- L := Arr_Typ'First; If Arr_Typ is constrained
2255 -- L := Si'First; otherwise (where I is the input param given)
2257 function H return Node_Id;
2258 -- Builds reference to identifier H
2260 function Ind_Val (E : Node_Id) return Node_Id;
2261 -- Builds expression Ind_Typ'Val (E);
2263 function L return Node_Id;
2264 -- Builds reference to identifier L
2266 function L_Pos return Node_Id;
2267 -- Builds expression Integer_Type'(Ind_Typ'Pos (L)). We qualify the
2268 -- expression to avoid universal_integer computations whenever possible,
2269 -- in the expression for the upper bound H.
2271 function L_Succ return Node_Id;
2272 -- Builds expression Ind_Typ'Succ (L)
2274 function One return Node_Id;
2275 -- Builds integer literal one
2277 function P return Node_Id;
2278 -- Builds reference to identifier P
2280 function P_Succ return Node_Id;
2281 -- Builds expression Ind_Typ'Succ (P)
2283 function R return Node_Id;
2284 -- Builds reference to identifier R
2286 function S (I : Nat) return Node_Id;
2287 -- Builds reference to identifier Si, where I is the value given
2289 function S_First (I : Nat) return Node_Id;
2290 -- Builds expression Si'First, where I is the value given
2292 function S_Last (I : Nat) return Node_Id;
2293 -- Builds expression Si'Last, where I is the value given
2295 function S_Length (I : Nat) return Node_Id;
2296 -- Builds expression Si'Length, where I is the value given
2298 function S_Length_Test (I : Nat) return Node_Id;
2299 -- Builds expression Si'Length /= 0, where I is the value given
2305 function Copy_Into_R_S (I : Nat; Last : Boolean) return List_Id is
2306 Stmts : constant List_Id := New_List;
2308 Loop_Stmt : Node_Id;
2310 Exit_Stmt : Node_Id;
2315 -- First construct the initializations
2317 P_Start := Make_Assignment_Statement (Loc,
2319 Expression => S_First (I));
2320 Append_To (Stmts, P_Start);
2322 -- Then build the loop
2324 R_Copy := Make_Assignment_Statement (Loc,
2325 Name => Make_Indexed_Component (Loc,
2327 Expressions => New_List (L)),
2328 Expression => Make_Indexed_Component (Loc,
2330 Expressions => New_List (P)));
2332 L_Inc := Make_Assignment_Statement (Loc,
2334 Expression => L_Succ);
2336 Exit_Stmt := Make_Exit_Statement (Loc,
2337 Condition => Make_Op_Eq (Loc, P, S_Last (I)));
2339 P_Inc := Make_Assignment_Statement (Loc,
2341 Expression => P_Succ);
2345 Make_Implicit_Loop_Statement (Cnode,
2346 Statements => New_List (R_Copy, Exit_Stmt, L_Inc, P_Inc));
2349 Make_Implicit_Loop_Statement (Cnode,
2350 Statements => New_List (R_Copy, L_Inc, Exit_Stmt, P_Inc));
2353 Append_To (Stmts, Loop_Stmt);
2362 function H return Node_Id is
2364 return Make_Identifier (Loc, Name_uH);
2371 function Ind_Val (E : Node_Id) return Node_Id is
2374 Make_Attribute_Reference (Loc,
2375 Prefix => New_Reference_To (Ind_Typ, Loc),
2376 Attribute_Name => Name_Val,
2377 Expressions => New_List (E));
2384 function Init_L (I : Nat) return Node_Id is
2388 if Is_Constrained (Arr_Typ) then
2389 E := Make_Attribute_Reference (Loc,
2390 Prefix => New_Reference_To (Arr_Typ, Loc),
2391 Attribute_Name => Name_First);
2397 return Make_Assignment_Statement (Loc, Name => L, Expression => E);
2404 function L return Node_Id is
2406 return Make_Identifier (Loc, Name_uL);
2413 function L_Pos return Node_Id is
2414 Target_Type : Entity_Id;
2417 -- If the index type is an enumeration type, the computation
2418 -- can be done in standard integer. Otherwise, choose a large
2419 -- enough integer type.
2421 if Is_Enumeration_Type (Ind_Typ)
2422 or else Root_Type (Ind_Typ) = Standard_Integer
2423 or else Root_Type (Ind_Typ) = Standard_Short_Integer
2424 or else Root_Type (Ind_Typ) = Standard_Short_Short_Integer
2426 Target_Type := Standard_Integer;
2428 Target_Type := Root_Type (Ind_Typ);
2432 Make_Qualified_Expression (Loc,
2433 Subtype_Mark => New_Reference_To (Target_Type, Loc),
2435 Make_Attribute_Reference (Loc,
2436 Prefix => New_Reference_To (Ind_Typ, Loc),
2437 Attribute_Name => Name_Pos,
2438 Expressions => New_List (L)));
2445 function L_Succ return Node_Id is
2448 Make_Attribute_Reference (Loc,
2449 Prefix => New_Reference_To (Ind_Typ, Loc),
2450 Attribute_Name => Name_Succ,
2451 Expressions => New_List (L));
2458 function One return Node_Id is
2460 return Make_Integer_Literal (Loc, 1);
2467 function P return Node_Id is
2469 return Make_Identifier (Loc, Name_uP);
2476 function P_Succ return Node_Id is
2479 Make_Attribute_Reference (Loc,
2480 Prefix => New_Reference_To (Ind_Typ, Loc),
2481 Attribute_Name => Name_Succ,
2482 Expressions => New_List (P));
2489 function R return Node_Id is
2491 return Make_Identifier (Loc, Name_uR);
2498 function S (I : Nat) return Node_Id is
2500 return Make_Identifier (Loc, New_External_Name ('S', I));
2507 function S_First (I : Nat) return Node_Id is
2509 return Make_Attribute_Reference (Loc,
2511 Attribute_Name => Name_First);
2518 function S_Last (I : Nat) return Node_Id is
2520 return Make_Attribute_Reference (Loc,
2522 Attribute_Name => Name_Last);
2529 function S_Length (I : Nat) return Node_Id is
2531 return Make_Attribute_Reference (Loc,
2533 Attribute_Name => Name_Length);
2540 function S_Length_Test (I : Nat) return Node_Id is
2544 Left_Opnd => S_Length (I),
2545 Right_Opnd => Make_Integer_Literal (Loc, 0));
2548 -- Start of processing for Expand_Concatenate_Other
2551 -- Construct the parameter specs and the overall function spec
2553 Param_Specs := New_List;
2554 for I in 1 .. Nb_Opnds loop
2557 Make_Parameter_Specification (Loc,
2558 Defining_Identifier =>
2559 Make_Defining_Identifier (Loc, New_External_Name ('S', I)),
2560 Parameter_Type => New_Reference_To (Base_Typ, Loc)));
2563 Func_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('C'));
2565 Make_Function_Specification (Loc,
2566 Defining_Unit_Name => Func_Id,
2567 Parameter_Specifications => Param_Specs,
2568 Result_Definition => New_Reference_To (Base_Typ, Loc));
2570 -- Construct L's object declaration
2573 Make_Object_Declaration (Loc,
2574 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uL),
2575 Object_Definition => New_Reference_To (Ind_Typ, Loc));
2577 Func_Decls := New_List (L_Decl);
2579 -- Construct the if-then-elsif statements
2581 Elsif_List := New_List;
2582 for I in 2 .. Nb_Opnds - 1 loop
2583 Append_To (Elsif_List, Make_Elsif_Part (Loc,
2584 Condition => S_Length_Test (I),
2585 Then_Statements => New_List (Init_L (I))));
2589 Make_Implicit_If_Statement (Cnode,
2590 Condition => S_Length_Test (1),
2591 Then_Statements => New_List (Init_L (1)),
2592 Elsif_Parts => Elsif_List,
2593 Else_Statements => New_List (Make_Simple_Return_Statement (Loc,
2594 Expression => S (Nb_Opnds))));
2596 -- Construct the declaration for H
2599 Make_Object_Declaration (Loc,
2600 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uP),
2601 Object_Definition => New_Reference_To (Ind_Typ, Loc));
2603 H_Init := Make_Op_Subtract (Loc, S_Length (1), One);
2604 for I in 2 .. Nb_Opnds loop
2605 H_Init := Make_Op_Add (Loc, H_Init, S_Length (I));
2607 H_Init := Ind_Val (Make_Op_Add (Loc, H_Init, L_Pos));
2610 Make_Object_Declaration (Loc,
2611 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uH),
2612 Object_Definition => New_Reference_To (Ind_Typ, Loc),
2613 Expression => H_Init);
2615 -- Construct the declaration for R
2617 R_Range := Make_Range (Loc, Low_Bound => L, High_Bound => H);
2619 Make_Index_Or_Discriminant_Constraint (Loc,
2620 Constraints => New_List (R_Range));
2623 Make_Object_Declaration (Loc,
2624 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uR),
2625 Object_Definition =>
2626 Make_Subtype_Indication (Loc,
2627 Subtype_Mark => New_Reference_To (Base_Typ, Loc),
2628 Constraint => R_Constr));
2630 -- Construct the declarations for the declare block
2632 Declare_Decls := New_List (P_Decl, H_Decl, R_Decl);
2634 -- Construct list of statements for the declare block
2636 Declare_Stmts := New_List;
2637 for I in 1 .. Nb_Opnds loop
2638 Append_To (Declare_Stmts,
2639 Make_Implicit_If_Statement (Cnode,
2640 Condition => S_Length_Test (I),
2641 Then_Statements => Copy_Into_R_S (I, I = Nb_Opnds)));
2645 (Declare_Stmts, Make_Simple_Return_Statement (Loc, Expression => R));
2647 -- Construct the declare block
2649 Declare_Block := Make_Block_Statement (Loc,
2650 Declarations => Declare_Decls,
2651 Handled_Statement_Sequence =>
2652 Make_Handled_Sequence_Of_Statements (Loc, Declare_Stmts));
2654 -- Construct the list of function statements
2656 Func_Stmts := New_List (If_Stmt, Declare_Block);
2658 -- Construct the function body
2661 Make_Subprogram_Body (Loc,
2662 Specification => Func_Spec,
2663 Declarations => Func_Decls,
2664 Handled_Statement_Sequence =>
2665 Make_Handled_Sequence_Of_Statements (Loc, Func_Stmts));
2667 -- Insert the newly generated function in the code. This is analyzed
2668 -- with all checks off, since we have completed all the checks.
2670 -- Note that this does *not* fix the array concatenation bug when the
2671 -- low bound is Integer'first sibce that bug comes from the pointer
2672 -- dereferencing an unconstrained array. An there we need a constraint
2673 -- check to make sure the length of the concatenated array is ok. ???
2675 Insert_Action (Cnode, Func_Body, Suppress => All_Checks);
2677 -- Construct list of arguments for the function call
2680 Operand := First (Opnds);
2681 for I in 1 .. Nb_Opnds loop
2682 Append_To (Params, Relocate_Node (Operand));
2686 -- Insert the function call
2690 Make_Function_Call (Loc, New_Reference_To (Func_Id, Loc), Params));
2692 Analyze_And_Resolve (Cnode, Base_Typ);
2693 Set_Is_Inlined (Func_Id);
2694 end Expand_Concatenate_Other;
2696 -------------------------------
2697 -- Expand_Concatenate_String --
2698 -------------------------------
2700 procedure Expand_Concatenate_String (Cnode : Node_Id; Opnds : List_Id) is
2701 Loc : constant Source_Ptr := Sloc (Cnode);
2702 Opnd1 : constant Node_Id := First (Opnds);
2703 Opnd2 : constant Node_Id := Next (Opnd1);
2704 Typ1 : constant Entity_Id := Base_Type (Etype (Opnd1));
2705 Typ2 : constant Entity_Id := Base_Type (Etype (Opnd2));
2708 -- RE_Id value for function to be called
2711 -- In all cases, we build a call to a routine giving the list of
2712 -- arguments as the parameter list to the routine.
2714 case List_Length (Opnds) is
2716 if Typ1 = Standard_Character then
2717 if Typ2 = Standard_Character then
2718 R := RE_Str_Concat_CC;
2721 pragma Assert (Typ2 = Standard_String);
2722 R := RE_Str_Concat_CS;
2725 elsif Typ1 = Standard_String then
2726 if Typ2 = Standard_Character then
2727 R := RE_Str_Concat_SC;
2730 pragma Assert (Typ2 = Standard_String);
2734 -- If we have anything other than Standard_Character or
2735 -- Standard_String, then we must have had a serious error
2736 -- earlier, so we just abandon the attempt at expansion.
2739 pragma Assert (Serious_Errors_Detected > 0);
2744 R := RE_Str_Concat_3;
2747 R := RE_Str_Concat_4;
2750 R := RE_Str_Concat_5;
2754 raise Program_Error;
2757 -- Now generate the appropriate call
2760 Make_Function_Call (Sloc (Cnode),
2761 Name => New_Occurrence_Of (RTE (R), Loc),
2762 Parameter_Associations => Opnds));
2764 Analyze_And_Resolve (Cnode, Standard_String);
2767 when RE_Not_Available =>
2769 end Expand_Concatenate_String;
2771 ------------------------
2772 -- Expand_N_Allocator --
2773 ------------------------
2775 procedure Expand_N_Allocator (N : Node_Id) is
2776 PtrT : constant Entity_Id := Etype (N);
2777 Dtyp : constant Entity_Id := Designated_Type (PtrT);
2778 Etyp : constant Entity_Id := Etype (Expression (N));
2779 Loc : constant Source_Ptr := Sloc (N);
2784 procedure Complete_Coextension_Finalization;
2785 -- Generate finalization calls for all nested coextensions of N. This
2786 -- routine may allocate list controllers if necessary.
2788 procedure Rewrite_Coextension (N : Node_Id);
2789 -- Static coextensions have the same lifetime as the entity they
2790 -- constrain. Such occurences can be rewritten as aliased objects
2791 -- and their unrestricted access used instead of the coextension.
2793 ---------------------------------------
2794 -- Complete_Coextension_Finalization --
2795 ---------------------------------------
2797 procedure Complete_Coextension_Finalization is
2799 Coext_Elmt : Elmt_Id;
2803 function Inside_A_Return_Statement (N : Node_Id) return Boolean;
2804 -- Determine whether node N is part of a return statement
2806 function Needs_Initialization_Call (N : Node_Id) return Boolean;
2807 -- Determine whether node N is a subtype indicator allocator which
2808 -- asts a coextension. Such coextensions need initialization.
2810 -------------------------------
2811 -- Inside_A_Return_Statement --
2812 -------------------------------
2814 function Inside_A_Return_Statement (N : Node_Id) return Boolean is
2819 while Present (P) loop
2820 if Nkind (P) = N_Extended_Return_Statement
2821 or else Nkind (P) = N_Simple_Return_Statement
2825 -- Stop the traversal when we reach a subprogram body
2827 elsif Nkind (P) = N_Subprogram_Body then
2835 end Inside_A_Return_Statement;
2837 -------------------------------
2838 -- Needs_Initialization_Call --
2839 -------------------------------
2841 function Needs_Initialization_Call (N : Node_Id) return Boolean is
2845 if Nkind (N) = N_Explicit_Dereference
2846 and then Nkind (Prefix (N)) = N_Identifier
2847 and then Nkind (Parent (Entity (Prefix (N)))) =
2848 N_Object_Declaration
2850 Obj_Decl := Parent (Entity (Prefix (N)));
2853 Present (Expression (Obj_Decl))
2854 and then Nkind (Expression (Obj_Decl)) = N_Allocator
2855 and then Nkind (Expression (Expression (Obj_Decl))) /=
2856 N_Qualified_Expression;
2860 end Needs_Initialization_Call;
2862 -- Start of processing for Complete_Coextension_Finalization
2865 -- When a coextension root is inside a return statement, we need to
2866 -- use the finalization chain of the function's scope. This does not
2867 -- apply for controlled named access types because in those cases we
2868 -- can use the finalization chain of the type itself.
2870 if Inside_A_Return_Statement (N)
2872 (Ekind (PtrT) = E_Anonymous_Access_Type
2874 (Ekind (PtrT) = E_Access_Type
2875 and then No (Associated_Final_Chain (PtrT))))
2879 Outer_S : Entity_Id;
2880 S : Entity_Id := Current_Scope;
2883 while Present (S) and then S /= Standard_Standard loop
2884 if Ekind (S) = E_Function then
2885 Outer_S := Scope (S);
2887 -- Retrieve the declaration of the body
2889 Decl := Parent (Parent (
2890 Corresponding_Body (Parent (Parent (S)))));
2897 -- Push the scope of the function body since we are inserting
2898 -- the list before the body, but we are currently in the body
2899 -- itself. Override the finalization list of PtrT since the
2900 -- finalization context is now different.
2902 Push_Scope (Outer_S);
2903 Build_Final_List (Decl, PtrT);
2907 -- The root allocator may not be controlled, but it still needs a
2908 -- finalization list for all nested coextensions.
2910 elsif No (Associated_Final_Chain (PtrT)) then
2911 Build_Final_List (N, PtrT);
2915 Make_Selected_Component (Loc,
2917 New_Reference_To (Associated_Final_Chain (PtrT), Loc),
2919 Make_Identifier (Loc, Name_F));
2921 Coext_Elmt := First_Elmt (Coextensions (N));
2922 while Present (Coext_Elmt) loop
2923 Coext := Node (Coext_Elmt);
2928 if Nkind (Coext) = N_Identifier then
2929 Ref := Make_Unchecked_Type_Conversion (Loc,
2931 New_Reference_To (Etype (Coext), Loc),
2933 Make_Explicit_Dereference (Loc,
2934 New_Copy_Tree (Coext)));
2936 Ref := New_Copy_Tree (Coext);
2941 -- attach_to_final_list (Ref, Flist, 2)
2943 if Needs_Initialization_Call (Coext) then
2947 Typ => Etype (Coext),
2949 With_Attach => Make_Integer_Literal (Loc, Uint_2)));
2952 -- attach_to_final_list (Ref, Flist, 2)
2958 Flist_Ref => New_Copy_Tree (Flist),
2959 With_Attach => Make_Integer_Literal (Loc, Uint_2)));
2962 Next_Elmt (Coext_Elmt);
2964 end Complete_Coextension_Finalization;
2966 -------------------------
2967 -- Rewrite_Coextension --
2968 -------------------------
2970 procedure Rewrite_Coextension (N : Node_Id) is
2971 Temp : constant Node_Id :=
2972 Make_Defining_Identifier (Loc,
2973 New_Internal_Name ('C'));
2976 -- Cnn : aliased Etyp;
2978 Decl : constant Node_Id :=
2979 Make_Object_Declaration (Loc,
2980 Defining_Identifier => Temp,
2981 Aliased_Present => True,
2982 Object_Definition =>
2983 New_Occurrence_Of (Etyp, Loc));
2987 if Nkind (Expression (N)) = N_Qualified_Expression then
2988 Set_Expression (Decl, Expression (Expression (N)));
2991 -- Find the proper insertion node for the declaration
2994 while Present (Nod) loop
2995 exit when Nkind (Nod) in N_Statement_Other_Than_Procedure_Call
2996 or else Nkind (Nod) = N_Procedure_Call_Statement
2997 or else Nkind (Nod) in N_Declaration;
2998 Nod := Parent (Nod);
3001 Insert_Before (Nod, Decl);
3005 Make_Attribute_Reference (Loc,
3006 Prefix => New_Occurrence_Of (Temp, Loc),
3007 Attribute_Name => Name_Unrestricted_Access));
3009 Analyze_And_Resolve (N, PtrT);
3010 end Rewrite_Coextension;
3012 -- Start of processing for Expand_N_Allocator
3015 -- RM E.2.3(22). We enforce that the expected type of an allocator
3016 -- shall not be a remote access-to-class-wide-limited-private type
3018 -- Why is this being done at expansion time, seems clearly wrong ???
3020 Validate_Remote_Access_To_Class_Wide_Type (N);
3022 -- Set the Storage Pool
3024 Set_Storage_Pool (N, Associated_Storage_Pool (Root_Type (PtrT)));
3026 if Present (Storage_Pool (N)) then
3027 if Is_RTE (Storage_Pool (N), RE_SS_Pool) then
3028 if VM_Target = No_VM then
3029 Set_Procedure_To_Call (N, RTE (RE_SS_Allocate));
3032 elsif Is_Class_Wide_Type (Etype (Storage_Pool (N))) then
3033 Set_Procedure_To_Call (N, RTE (RE_Allocate_Any));
3036 Set_Procedure_To_Call (N,
3037 Find_Prim_Op (Etype (Storage_Pool (N)), Name_Allocate));
3041 -- Under certain circumstances we can replace an allocator by an
3042 -- access to statically allocated storage. The conditions, as noted
3043 -- in AARM 3.10 (10c) are as follows:
3045 -- Size and initial value is known at compile time
3046 -- Access type is access-to-constant
3048 -- The allocator is not part of a constraint on a record component,
3049 -- because in that case the inserted actions are delayed until the
3050 -- record declaration is fully analyzed, which is too late for the
3051 -- analysis of the rewritten allocator.
3053 if Is_Access_Constant (PtrT)
3054 and then Nkind (Expression (N)) = N_Qualified_Expression
3055 and then Compile_Time_Known_Value (Expression (Expression (N)))
3056 and then Size_Known_At_Compile_Time (Etype (Expression
3058 and then not Is_Record_Type (Current_Scope)
3060 -- Here we can do the optimization. For the allocator
3064 -- We insert an object declaration
3066 -- Tnn : aliased x := y;
3068 -- and replace the allocator by Tnn'Unrestricted_Access.
3069 -- Tnn is marked as requiring static allocation.
3072 Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
3074 Desig := Subtype_Mark (Expression (N));
3076 -- If context is constrained, use constrained subtype directly,
3077 -- so that the constant is not labelled as having a nomimally
3078 -- unconstrained subtype.
3080 if Entity (Desig) = Base_Type (Dtyp) then
3081 Desig := New_Occurrence_Of (Dtyp, Loc);
3085 Make_Object_Declaration (Loc,
3086 Defining_Identifier => Temp,
3087 Aliased_Present => True,
3088 Constant_Present => Is_Access_Constant (PtrT),
3089 Object_Definition => Desig,
3090 Expression => Expression (Expression (N))));
3093 Make_Attribute_Reference (Loc,
3094 Prefix => New_Occurrence_Of (Temp, Loc),
3095 Attribute_Name => Name_Unrestricted_Access));
3097 Analyze_And_Resolve (N, PtrT);
3099 -- We set the variable as statically allocated, since we don't
3100 -- want it going on the stack of the current procedure!
3102 Set_Is_Statically_Allocated (Temp);
3106 -- Same if the allocator is an access discriminant for a local object:
3107 -- instead of an allocator we create a local value and constrain the
3108 -- the enclosing object with the corresponding access attribute.
3110 if Is_Static_Coextension (N) then
3111 Rewrite_Coextension (N);
3115 -- The current allocator creates an object which may contain nested
3116 -- coextensions. Use the current allocator's finalization list to
3117 -- generate finalization call for all nested coextensions.
3119 if Is_Coextension_Root (N) then
3120 Complete_Coextension_Finalization;
3123 -- Handle case of qualified expression (other than optimization above)
3125 if Nkind (Expression (N)) = N_Qualified_Expression then
3126 Expand_Allocator_Expression (N);
3130 -- If the allocator is for a type which requires initialization, and
3131 -- there is no initial value (i.e. operand is a subtype indication
3132 -- rather than a qualifed expression), then we must generate a call
3133 -- to the initialization routine. This is done using an expression
3136 -- [Pnnn : constant ptr_T := new (T); Init (Pnnn.all,...); Pnnn]
3138 -- Here ptr_T is the pointer type for the allocator, and T is the
3139 -- subtype of the allocator. A special case arises if the designated
3140 -- type of the access type is a task or contains tasks. In this case
3141 -- the call to Init (Temp.all ...) is replaced by code that ensures
3142 -- that tasks get activated (see Exp_Ch9.Build_Task_Allocate_Block
3143 -- for details). In addition, if the type T is a task T, then the
3144 -- first argument to Init must be converted to the task record type.
3147 T : constant Entity_Id := Entity (Expression (N));
3155 Temp_Decl : Node_Id;
3156 Temp_Type : Entity_Id;
3157 Attach_Level : Uint;
3160 if No_Initialization (N) then
3163 -- Case of no initialization procedure present
3165 elsif not Has_Non_Null_Base_Init_Proc (T) then
3167 -- Case of simple initialization required
3169 if Needs_Simple_Initialization (T) then
3170 Rewrite (Expression (N),
3171 Make_Qualified_Expression (Loc,
3172 Subtype_Mark => New_Occurrence_Of (T, Loc),
3173 Expression => Get_Simple_Init_Val (T, Loc)));
3175 Analyze_And_Resolve (Expression (Expression (N)), T);
3176 Analyze_And_Resolve (Expression (N), T);
3177 Set_Paren_Count (Expression (Expression (N)), 1);
3178 Expand_N_Allocator (N);
3180 -- No initialization required
3186 -- Case of initialization procedure present, must be called
3189 Init := Base_Init_Proc (T);
3191 Temp := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
3193 -- Construct argument list for the initialization routine call.
3194 -- The CPP constructor needs the address directly
3196 if Is_CPP_Class (T) then
3197 Arg1 := New_Reference_To (Temp, Loc);
3201 Arg1 := Make_Explicit_Dereference (Loc,
3202 Prefix => New_Reference_To (Temp, Loc));
3203 Set_Assignment_OK (Arg1);
3206 -- The initialization procedure expects a specific type. if
3207 -- the context is access to class wide, indicate that the
3208 -- object being allocated has the right specific type.
3210 if Is_Class_Wide_Type (Dtyp) then
3211 Arg1 := Unchecked_Convert_To (T, Arg1);
3215 -- If designated type is a concurrent type or if it is private
3216 -- type whose definition is a concurrent type, the first argument
3217 -- in the Init routine has to be unchecked conversion to the
3218 -- corresponding record type. If the designated type is a derived
3219 -- type, we also convert the argument to its root type.
3221 if Is_Concurrent_Type (T) then
3223 Unchecked_Convert_To (Corresponding_Record_Type (T), Arg1);
3225 elsif Is_Private_Type (T)
3226 and then Present (Full_View (T))
3227 and then Is_Concurrent_Type (Full_View (T))
3230 Unchecked_Convert_To
3231 (Corresponding_Record_Type (Full_View (T)), Arg1);
3233 elsif Etype (First_Formal (Init)) /= Base_Type (T) then
3235 Ftyp : constant Entity_Id := Etype (First_Formal (Init));
3238 Arg1 := OK_Convert_To (Etype (Ftyp), Arg1);
3239 Set_Etype (Arg1, Ftyp);
3243 Args := New_List (Arg1);
3245 -- For the task case, pass the Master_Id of the access type as
3246 -- the value of the _Master parameter, and _Chain as the value
3247 -- of the _Chain parameter (_Chain will be defined as part of
3248 -- the generated code for the allocator).
3250 -- In Ada 2005, the context may be a function that returns an
3251 -- anonymous access type. In that case the Master_Id has been
3252 -- created when expanding the function declaration.
3254 if Has_Task (T) then
3255 if No (Master_Id (Base_Type (PtrT))) then
3257 -- If we have a non-library level task with the restriction
3258 -- No_Task_Hierarchy set, then no point in expanding.
3260 if not Is_Library_Level_Entity (T)
3261 and then Restriction_Active (No_Task_Hierarchy)
3266 -- The designated type was an incomplete type, and the
3267 -- access type did not get expanded. Salvage it now.
3269 pragma Assert (Present (Parent (Base_Type (PtrT))));
3270 Expand_N_Full_Type_Declaration (Parent (Base_Type (PtrT)));
3273 -- If the context of the allocator is a declaration or an
3274 -- assignment, we can generate a meaningful image for it,
3275 -- even though subsequent assignments might remove the
3276 -- connection between task and entity. We build this image
3277 -- when the left-hand side is a simple variable, a simple
3278 -- indexed assignment or a simple selected component.
3280 if Nkind (Parent (N)) = N_Assignment_Statement then
3282 Nam : constant Node_Id := Name (Parent (N));
3285 if Is_Entity_Name (Nam) then
3287 Build_Task_Image_Decls (
3290 (Entity (Nam), Sloc (Nam)), T);
3292 elsif (Nkind (Nam) = N_Indexed_Component
3293 or else Nkind (Nam) = N_Selected_Component)
3294 and then Is_Entity_Name (Prefix (Nam))
3297 Build_Task_Image_Decls
3298 (Loc, Nam, Etype (Prefix (Nam)));
3300 Decls := Build_Task_Image_Decls (Loc, T, T);
3304 elsif Nkind (Parent (N)) = N_Object_Declaration then
3306 Build_Task_Image_Decls (
3307 Loc, Defining_Identifier (Parent (N)), T);
3310 Decls := Build_Task_Image_Decls (Loc, T, T);
3315 (Master_Id (Base_Type (Root_Type (PtrT))), Loc));
3316 Append_To (Args, Make_Identifier (Loc, Name_uChain));
3318 Decl := Last (Decls);
3320 New_Occurrence_Of (Defining_Identifier (Decl), Loc));
3322 -- Has_Task is false, Decls not used
3328 -- Add discriminants if discriminated type
3331 Dis : Boolean := False;
3335 if Has_Discriminants (T) then
3339 elsif Is_Private_Type (T)
3340 and then Present (Full_View (T))
3341 and then Has_Discriminants (Full_View (T))
3344 Typ := Full_View (T);
3348 -- If the allocated object will be constrained by the
3349 -- default values for discriminants, then build a
3350 -- subtype with those defaults, and change the allocated
3351 -- subtype to that. Note that this happens in fewer
3352 -- cases in Ada 2005 (AI-363).
3354 if not Is_Constrained (Typ)
3355 and then Present (Discriminant_Default_Value
3356 (First_Discriminant (Typ)))
3357 and then (Ada_Version < Ada_05
3358 or else not Has_Constrained_Partial_View (Typ))
3360 Typ := Build_Default_Subtype (Typ, N);
3361 Set_Expression (N, New_Reference_To (Typ, Loc));
3364 Discr := First_Elmt (Discriminant_Constraint (Typ));
3365 while Present (Discr) loop
3366 Nod := Node (Discr);
3367 Append (New_Copy_Tree (Node (Discr)), Args);
3369 -- AI-416: when the discriminant constraint is an
3370 -- anonymous access type make sure an accessibility
3371 -- check is inserted if necessary (3.10.2(22.q/2))
3373 if Ada_Version >= Ada_05
3374 and then Ekind (Etype (Nod)) = E_Anonymous_Access_Type
3376 Apply_Accessibility_Check (Nod, Typ);
3384 -- We set the allocator as analyzed so that when we analyze the
3385 -- expression actions node, we do not get an unwanted recursive
3386 -- expansion of the allocator expression.
3388 Set_Analyzed (N, True);
3389 Nod := Relocate_Node (N);
3391 -- Here is the transformation:
3393 -- output: Temp : constant ptr_T := new T;
3394 -- Init (Temp.all, ...);
3395 -- <CTRL> Attach_To_Final_List (Finalizable (Temp.all));
3396 -- <CTRL> Initialize (Finalizable (Temp.all));
3398 -- Here ptr_T is the pointer type for the allocator, and is the
3399 -- subtype of the allocator.
3402 Make_Object_Declaration (Loc,
3403 Defining_Identifier => Temp,
3404 Constant_Present => True,
3405 Object_Definition => New_Reference_To (Temp_Type, Loc),
3408 Set_Assignment_OK (Temp_Decl);
3410 if Is_CPP_Class (T) then
3411 Set_Aliased_Present (Temp_Decl);
3414 Insert_Action (N, Temp_Decl, Suppress => All_Checks);
3416 -- If the designated type is a task type or contains tasks,
3417 -- create block to activate created tasks, and insert
3418 -- declaration for Task_Image variable ahead of call.
3420 if Has_Task (T) then
3422 L : constant List_Id := New_List;
3426 Build_Task_Allocate_Block (L, Nod, Args);
3429 Insert_List_Before (First (Declarations (Blk)), Decls);
3430 Insert_Actions (N, L);
3435 Make_Procedure_Call_Statement (Loc,
3436 Name => New_Reference_To (Init, Loc),
3437 Parameter_Associations => Args));
3440 if Controlled_Type (T) then
3442 -- Postpone the generation of a finalization call for the
3443 -- current allocator if it acts as a coextension.
3445 if Is_Dynamic_Coextension (N) then
3446 if No (Coextensions (N)) then
3447 Set_Coextensions (N, New_Elmt_List);
3450 Append_Elmt (New_Copy_Tree (Arg1), Coextensions (N));
3453 Flist := Get_Allocator_Final_List (N, Base_Type (T), PtrT);
3455 -- Anonymous access types created for access parameters
3456 -- are attached to an explicitly constructed controller,
3457 -- which ensures that they can be finalized properly, even
3458 -- if their deallocation might not happen. The list
3459 -- associated with the controller is doubly-linked. For
3460 -- other anonymous access types, the object may end up
3461 -- on the global final list which is singly-linked.
3462 -- Work needed for access discriminants in Ada 2005 ???
3464 if Ekind (PtrT) = E_Anonymous_Access_Type
3466 Nkind (Associated_Node_For_Itype (PtrT))
3467 not in N_Subprogram_Specification
3469 Attach_Level := Uint_1;
3471 Attach_Level := Uint_2;
3476 Ref => New_Copy_Tree (Arg1),
3479 With_Attach => Make_Integer_Literal
3480 (Loc, Attach_Level)));
3484 if Is_CPP_Class (T) then
3486 Make_Attribute_Reference (Loc,
3487 Prefix => New_Reference_To (Temp, Loc),
3488 Attribute_Name => Name_Unchecked_Access));
3490 Rewrite (N, New_Reference_To (Temp, Loc));
3493 Analyze_And_Resolve (N, PtrT);
3497 -- Ada 2005 (AI-251): If the allocator is for a class-wide interface
3498 -- object that has been rewritten as a reference, we displace "this"
3499 -- to reference properly its secondary dispatch table.
3501 if Nkind (N) = N_Identifier
3502 and then Is_Interface (Dtyp)
3504 Displace_Allocator_Pointer (N);
3508 when RE_Not_Available =>
3510 end Expand_N_Allocator;
3512 -----------------------
3513 -- Expand_N_And_Then --
3514 -----------------------
3516 -- Expand into conditional expression if Actions present, and also deal
3517 -- with optimizing case of arguments being True or False.
3519 procedure Expand_N_And_Then (N : Node_Id) is
3520 Loc : constant Source_Ptr := Sloc (N);
3521 Typ : constant Entity_Id := Etype (N);
3522 Left : constant Node_Id := Left_Opnd (N);
3523 Right : constant Node_Id := Right_Opnd (N);
3527 -- Deal with non-standard booleans
3529 if Is_Boolean_Type (Typ) then
3530 Adjust_Condition (Left);
3531 Adjust_Condition (Right);
3532 Set_Etype (N, Standard_Boolean);
3535 -- Check for cases of left argument is True or False
3537 if Nkind (Left) = N_Identifier then
3539 -- If left argument is True, change (True and then Right) to Right.
3540 -- Any actions associated with Right will be executed unconditionally
3541 -- and can thus be inserted into the tree unconditionally.
3543 if Entity (Left) = Standard_True then
3544 if Present (Actions (N)) then
3545 Insert_Actions (N, Actions (N));
3549 Adjust_Result_Type (N, Typ);
3552 -- If left argument is False, change (False and then Right) to False.
3553 -- In this case we can forget the actions associated with Right,
3554 -- since they will never be executed.
3556 elsif Entity (Left) = Standard_False then
3557 Kill_Dead_Code (Right);
3558 Kill_Dead_Code (Actions (N));
3559 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
3560 Adjust_Result_Type (N, Typ);
3565 -- If Actions are present, we expand
3567 -- left and then right
3571 -- if left then right else false end
3573 -- with the actions becoming the Then_Actions of the conditional
3574 -- expression. This conditional expression is then further expanded
3575 -- (and will eventually disappear)
3577 if Present (Actions (N)) then
3578 Actlist := Actions (N);
3580 Make_Conditional_Expression (Loc,
3581 Expressions => New_List (
3584 New_Occurrence_Of (Standard_False, Loc))));
3586 Set_Then_Actions (N, Actlist);
3587 Analyze_And_Resolve (N, Standard_Boolean);
3588 Adjust_Result_Type (N, Typ);
3592 -- No actions present, check for cases of right argument True/False
3594 if Nkind (Right) = N_Identifier then
3596 -- Change (Left and then True) to Left. Note that we know there
3597 -- are no actions associated with the True operand, since we
3598 -- just checked for this case above.
3600 if Entity (Right) = Standard_True then
3603 -- Change (Left and then False) to False, making sure to preserve
3604 -- any side effects associated with the Left operand.
3606 elsif Entity (Right) = Standard_False then
3607 Remove_Side_Effects (Left);
3609 (N, New_Occurrence_Of (Standard_False, Loc));
3613 Adjust_Result_Type (N, Typ);
3614 end Expand_N_And_Then;
3616 -------------------------------------
3617 -- Expand_N_Conditional_Expression --
3618 -------------------------------------
3620 -- Expand into expression actions if then/else actions present
3622 procedure Expand_N_Conditional_Expression (N : Node_Id) is
3623 Loc : constant Source_Ptr := Sloc (N);
3624 Cond : constant Node_Id := First (Expressions (N));
3625 Thenx : constant Node_Id := Next (Cond);
3626 Elsex : constant Node_Id := Next (Thenx);
3627 Typ : constant Entity_Id := Etype (N);
3632 -- If either then or else actions are present, then given:
3634 -- if cond then then-expr else else-expr end
3636 -- we insert the following sequence of actions (using Insert_Actions):
3641 -- Cnn := then-expr;
3647 -- and replace the conditional expression by a reference to Cnn
3649 if Present (Then_Actions (N)) or else Present (Else_Actions (N)) then
3650 Cnn := Make_Defining_Identifier (Loc, New_Internal_Name ('C'));
3653 Make_Implicit_If_Statement (N,
3654 Condition => Relocate_Node (Cond),
3656 Then_Statements => New_List (
3657 Make_Assignment_Statement (Sloc (Thenx),
3658 Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
3659 Expression => Relocate_Node (Thenx))),
3661 Else_Statements => New_List (
3662 Make_Assignment_Statement (Sloc (Elsex),
3663 Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
3664 Expression => Relocate_Node (Elsex))));
3666 Set_Assignment_OK (Name (First (Then_Statements (New_If))));
3667 Set_Assignment_OK (Name (First (Else_Statements (New_If))));
3669 if Present (Then_Actions (N)) then
3671 (First (Then_Statements (New_If)), Then_Actions (N));
3674 if Present (Else_Actions (N)) then
3676 (First (Else_Statements (New_If)), Else_Actions (N));
3679 Rewrite (N, New_Occurrence_Of (Cnn, Loc));
3682 Make_Object_Declaration (Loc,
3683 Defining_Identifier => Cnn,
3684 Object_Definition => New_Occurrence_Of (Typ, Loc)));
3686 Insert_Action (N, New_If);
3687 Analyze_And_Resolve (N, Typ);
3689 end Expand_N_Conditional_Expression;
3691 -----------------------------------
3692 -- Expand_N_Explicit_Dereference --
3693 -----------------------------------
3695 procedure Expand_N_Explicit_Dereference (N : Node_Id) is
3697 -- Insert explicit dereference call for the checked storage pool case
3699 Insert_Dereference_Action (Prefix (N));
3700 end Expand_N_Explicit_Dereference;
3706 procedure Expand_N_In (N : Node_Id) is
3707 Loc : constant Source_Ptr := Sloc (N);
3708 Rtyp : constant Entity_Id := Etype (N);
3709 Lop : constant Node_Id := Left_Opnd (N);
3710 Rop : constant Node_Id := Right_Opnd (N);
3711 Static : constant Boolean := Is_OK_Static_Expression (N);
3713 procedure Substitute_Valid_Check;
3714 -- Replaces node N by Lop'Valid. This is done when we have an explicit
3715 -- test for the left operand being in range of its subtype.
3717 ----------------------------
3718 -- Substitute_Valid_Check --
3719 ----------------------------
3721 procedure Substitute_Valid_Check is
3724 Make_Attribute_Reference (Loc,
3725 Prefix => Relocate_Node (Lop),
3726 Attribute_Name => Name_Valid));
3728 Analyze_And_Resolve (N, Rtyp);
3730 Error_Msg_N ("?explicit membership test may be optimized away", N);
3731 Error_Msg_N ("\?use ''Valid attribute instead", N);
3733 end Substitute_Valid_Check;
3735 -- Start of processing for Expand_N_In
3738 -- Check case of explicit test for an expression in range of its
3739 -- subtype. This is suspicious usage and we replace it with a 'Valid
3740 -- test and give a warning.
3742 if Is_Scalar_Type (Etype (Lop))
3743 and then Nkind (Rop) in N_Has_Entity
3744 and then Etype (Lop) = Entity (Rop)
3745 and then Comes_From_Source (N)
3746 and then VM_Target = No_VM
3748 Substitute_Valid_Check;
3752 -- Do validity check on operands
3754 if Validity_Checks_On and Validity_Check_Operands then
3755 Ensure_Valid (Left_Opnd (N));
3756 Validity_Check_Range (Right_Opnd (N));
3759 -- Case of explicit range
3761 if Nkind (Rop) = N_Range then
3763 Lo : constant Node_Id := Low_Bound (Rop);
3764 Hi : constant Node_Id := High_Bound (Rop);
3766 Ltyp : constant Entity_Id := Etype (Lop);
3768 Lo_Orig : constant Node_Id := Original_Node (Lo);
3769 Hi_Orig : constant Node_Id := Original_Node (Hi);
3771 Lcheck : constant Compare_Result := Compile_Time_Compare (Lop, Lo);
3772 Ucheck : constant Compare_Result := Compile_Time_Compare (Lop, Hi);
3774 Warn1 : constant Boolean :=
3775 Constant_Condition_Warnings
3776 and then Comes_From_Source (N);
3777 -- This must be true for any of the optimization warnings, we
3778 -- clearly want to give them only for source with the flag on.
3780 Warn2 : constant Boolean :=
3782 and then Nkind (Original_Node (Rop)) = N_Range
3783 and then Is_Integer_Type (Etype (Lo));
3784 -- For the case where only one bound warning is elided, we also
3785 -- insist on an explicit range and an integer type. The reason is
3786 -- that the use of enumeration ranges including an end point is
3787 -- common, as is the use of a subtype name, one of whose bounds
3788 -- is the same as the type of the expression.
3791 -- If test is explicit x'first .. x'last, replace by valid check
3793 if Is_Scalar_Type (Ltyp)
3794 and then Nkind (Lo_Orig) = N_Attribute_Reference
3795 and then Attribute_Name (Lo_Orig) = Name_First
3796 and then Nkind (Prefix (Lo_Orig)) in N_Has_Entity
3797 and then Entity (Prefix (Lo_Orig)) = Ltyp
3798 and then Nkind (Hi_Orig) = N_Attribute_Reference
3799 and then Attribute_Name (Hi_Orig) = Name_Last
3800 and then Nkind (Prefix (Hi_Orig)) in N_Has_Entity
3801 and then Entity (Prefix (Hi_Orig)) = Ltyp
3802 and then Comes_From_Source (N)
3803 and then VM_Target = No_VM
3805 Substitute_Valid_Check;
3809 -- If bounds of type are known at compile time, and the end points
3810 -- are known at compile time and identical, this is another case
3811 -- for substituting a valid test. We only do this for discrete
3812 -- types, since it won't arise in practice for float types.
3814 if Comes_From_Source (N)
3815 and then Is_Discrete_Type (Ltyp)
3816 and then Compile_Time_Known_Value (Type_High_Bound (Ltyp))
3817 and then Compile_Time_Known_Value (Type_Low_Bound (Ltyp))
3818 and then Compile_Time_Known_Value (Lo)
3819 and then Compile_Time_Known_Value (Hi)
3820 and then Expr_Value (Type_High_Bound (Ltyp)) = Expr_Value (Hi)
3821 and then Expr_Value (Type_Low_Bound (Ltyp)) = Expr_Value (Lo)
3823 Substitute_Valid_Check;
3827 -- If we have an explicit range, do a bit of optimization based
3828 -- on range analysis (we may be able to kill one or both checks).
3830 -- If either check is known to fail, replace result by False since
3831 -- the other check does not matter. Preserve the static flag for
3832 -- legality checks, because we are constant-folding beyond RM 4.9.
3834 if Lcheck = LT or else Ucheck = GT then
3836 Error_Msg_N ("?range test optimized away", N);
3837 Error_Msg_N ("\?value is known to be out of range", N);
3841 New_Reference_To (Standard_False, Loc));
3842 Analyze_And_Resolve (N, Rtyp);
3843 Set_Is_Static_Expression (N, Static);
3847 -- If both checks are known to succeed, replace result
3848 -- by True, since we know we are in range.
3850 elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
3852 Error_Msg_N ("?range test optimized away", N);
3853 Error_Msg_N ("\?value is known to be in range", N);
3857 New_Reference_To (Standard_True, Loc));
3858 Analyze_And_Resolve (N, Rtyp);
3859 Set_Is_Static_Expression (N, Static);
3863 -- If lower bound check succeeds and upper bound check is not
3864 -- known to succeed or fail, then replace the range check with
3865 -- a comparison against the upper bound.
3867 elsif Lcheck in Compare_GE then
3869 Error_Msg_N ("?lower bound test optimized away", Lo);
3870 Error_Msg_N ("\?value is known to be in range", Lo);
3876 Right_Opnd => High_Bound (Rop)));
3877 Analyze_And_Resolve (N, Rtyp);
3881 -- If upper bound check succeeds and lower bound check is not
3882 -- known to succeed or fail, then replace the range check with
3883 -- a comparison against the lower bound.
3885 elsif Ucheck in Compare_LE then
3887 Error_Msg_N ("?upper bound test optimized away", Hi);
3888 Error_Msg_N ("\?value is known to be in range", Hi);
3894 Right_Opnd => Low_Bound (Rop)));
3895 Analyze_And_Resolve (N, Rtyp);
3901 -- For all other cases of an explicit range, nothing to be done
3905 -- Here right operand is a subtype mark
3909 Typ : Entity_Id := Etype (Rop);
3910 Is_Acc : constant Boolean := Is_Access_Type (Typ);
3911 Obj : Node_Id := Lop;
3912 Cond : Node_Id := Empty;
3915 Remove_Side_Effects (Obj);
3917 -- For tagged type, do tagged membership operation
3919 if Is_Tagged_Type (Typ) then
3921 -- No expansion will be performed when VM_Target, as the VM
3922 -- back-ends will handle the membership tests directly (tags
3923 -- are not explicitly represented in Java objects, so the
3924 -- normal tagged membership expansion is not what we want).
3926 if VM_Target = No_VM then
3927 Rewrite (N, Tagged_Membership (N));
3928 Analyze_And_Resolve (N, Rtyp);
3933 -- If type is scalar type, rewrite as x in t'first .. t'last.
3934 -- This reason we do this is that the bounds may have the wrong
3935 -- type if they come from the original type definition.
3937 elsif Is_Scalar_Type (Typ) then
3941 Make_Attribute_Reference (Loc,
3942 Attribute_Name => Name_First,
3943 Prefix => New_Reference_To (Typ, Loc)),
3946 Make_Attribute_Reference (Loc,
3947 Attribute_Name => Name_Last,
3948 Prefix => New_Reference_To (Typ, Loc))));
3949 Analyze_And_Resolve (N, Rtyp);
3952 -- Ada 2005 (AI-216): Program_Error is raised when evaluating
3953 -- a membership test if the subtype mark denotes a constrained
3954 -- Unchecked_Union subtype and the expression lacks inferable
3957 elsif Is_Unchecked_Union (Base_Type (Typ))
3958 and then Is_Constrained (Typ)
3959 and then not Has_Inferable_Discriminants (Lop)
3962 Make_Raise_Program_Error (Loc,
3963 Reason => PE_Unchecked_Union_Restriction));
3965 -- Prevent Gigi from generating incorrect code by rewriting
3966 -- the test as a standard False.
3969 New_Occurrence_Of (Standard_False, Loc));
3974 -- Here we have a non-scalar type
3977 Typ := Designated_Type (Typ);
3980 if not Is_Constrained (Typ) then
3982 New_Reference_To (Standard_True, Loc));
3983 Analyze_And_Resolve (N, Rtyp);
3985 -- For the constrained array case, we have to check the
3986 -- subscripts for an exact match if the lengths are
3987 -- non-zero (the lengths must match in any case).
3989 elsif Is_Array_Type (Typ) then
3991 Check_Subscripts : declare
3992 function Construct_Attribute_Reference
3995 Dim : Nat) return Node_Id;
3996 -- Build attribute reference E'Nam(Dim)
3998 -----------------------------------
3999 -- Construct_Attribute_Reference --
4000 -----------------------------------
4002 function Construct_Attribute_Reference
4005 Dim : Nat) return Node_Id
4009 Make_Attribute_Reference (Loc,
4011 Attribute_Name => Nam,
4012 Expressions => New_List (
4013 Make_Integer_Literal (Loc, Dim)));
4014 end Construct_Attribute_Reference;
4016 -- Start processing for Check_Subscripts
4019 for J in 1 .. Number_Dimensions (Typ) loop
4020 Evolve_And_Then (Cond,
4023 Construct_Attribute_Reference
4024 (Duplicate_Subexpr_No_Checks (Obj),
4027 Construct_Attribute_Reference
4028 (New_Occurrence_Of (Typ, Loc), Name_First, J)));
4030 Evolve_And_Then (Cond,
4033 Construct_Attribute_Reference
4034 (Duplicate_Subexpr_No_Checks (Obj),
4037 Construct_Attribute_Reference
4038 (New_Occurrence_Of (Typ, Loc), Name_Last, J)));
4047 Right_Opnd => Make_Null (Loc)),
4048 Right_Opnd => Cond);
4052 Analyze_And_Resolve (N, Rtyp);
4053 end Check_Subscripts;
4055 -- These are the cases where constraint checks may be
4056 -- required, e.g. records with possible discriminants
4059 -- Expand the test into a series of discriminant comparisons.
4060 -- The expression that is built is the negation of the one
4061 -- that is used for checking discriminant constraints.
4063 Obj := Relocate_Node (Left_Opnd (N));
4065 if Has_Discriminants (Typ) then
4066 Cond := Make_Op_Not (Loc,
4067 Right_Opnd => Build_Discriminant_Checks (Obj, Typ));
4070 Cond := Make_Or_Else (Loc,
4074 Right_Opnd => Make_Null (Loc)),
4075 Right_Opnd => Cond);
4079 Cond := New_Occurrence_Of (Standard_True, Loc);
4083 Analyze_And_Resolve (N, Rtyp);
4089 --------------------------------
4090 -- Expand_N_Indexed_Component --
4091 --------------------------------
4093 procedure Expand_N_Indexed_Component (N : Node_Id) is
4094 Loc : constant Source_Ptr := Sloc (N);
4095 Typ : constant Entity_Id := Etype (N);
4096 P : constant Node_Id := Prefix (N);
4097 T : constant Entity_Id := Etype (P);
4100 -- A special optimization, if we have an indexed component that
4101 -- is selecting from a slice, then we can eliminate the slice,
4102 -- since, for example, x (i .. j)(k) is identical to x(k). The
4103 -- only difference is the range check required by the slice. The
4104 -- range check for the slice itself has already been generated.
4105 -- The range check for the subscripting operation is ensured
4106 -- by converting the subject to the subtype of the slice.
4108 -- This optimization not only generates better code, avoiding
4109 -- slice messing especially in the packed case, but more importantly
4110 -- bypasses some problems in handling this peculiar case, for
4111 -- example, the issue of dealing specially with object renamings.
4113 if Nkind (P) = N_Slice then
4115 Make_Indexed_Component (Loc,
4116 Prefix => Prefix (P),
4117 Expressions => New_List (
4119 (Etype (First_Index (Etype (P))),
4120 First (Expressions (N))))));
4121 Analyze_And_Resolve (N, Typ);
4125 -- If the prefix is an access type, then we unconditionally rewrite
4126 -- if as an explicit deference. This simplifies processing for several
4127 -- cases, including packed array cases and certain cases in which
4128 -- checks must be generated. We used to try to do this only when it
4129 -- was necessary, but it cleans up the code to do it all the time.
4131 if Is_Access_Type (T) then
4132 Insert_Explicit_Dereference (P);
4133 Analyze_And_Resolve (P, Designated_Type (T));
4136 -- Generate index and validity checks
4138 Generate_Index_Checks (N);
4140 if Validity_Checks_On and then Validity_Check_Subscripts then
4141 Apply_Subscript_Validity_Checks (N);
4144 -- All done for the non-packed case
4146 if not Is_Packed (Etype (Prefix (N))) then
4150 -- For packed arrays that are not bit-packed (i.e. the case of an array
4151 -- with one or more index types with a non-coniguous enumeration type),
4152 -- we can always use the normal packed element get circuit.
4154 if not Is_Bit_Packed_Array (Etype (Prefix (N))) then
4155 Expand_Packed_Element_Reference (N);
4159 -- For a reference to a component of a bit packed array, we have to
4160 -- convert it to a reference to the corresponding Packed_Array_Type.
4161 -- We only want to do this for simple references, and not for:
4163 -- Left side of assignment, or prefix of left side of assignment,
4164 -- or prefix of the prefix, to handle packed arrays of packed arrays,
4165 -- This case is handled in Exp_Ch5.Expand_N_Assignment_Statement
4167 -- Renaming objects in renaming associations
4168 -- This case is handled when a use of the renamed variable occurs
4170 -- Actual parameters for a procedure call
4171 -- This case is handled in Exp_Ch6.Expand_Actuals
4173 -- The second expression in a 'Read attribute reference
4175 -- The prefix of an address or size attribute reference
4177 -- The following circuit detects these exceptions
4180 Child : Node_Id := N;
4181 Parnt : Node_Id := Parent (N);
4185 if Nkind (Parnt) = N_Unchecked_Expression then
4188 elsif Nkind (Parnt) = N_Object_Renaming_Declaration
4189 or else Nkind (Parnt) = N_Procedure_Call_Statement
4190 or else (Nkind (Parnt) = N_Parameter_Association
4192 Nkind (Parent (Parnt)) = N_Procedure_Call_Statement)
4196 elsif Nkind (Parnt) = N_Attribute_Reference
4197 and then (Attribute_Name (Parnt) = Name_Address
4199 Attribute_Name (Parnt) = Name_Size)
4200 and then Prefix (Parnt) = Child
4204 elsif Nkind (Parnt) = N_Assignment_Statement
4205 and then Name (Parnt) = Child
4209 -- If the expression is an index of an indexed component,
4210 -- it must be expanded regardless of context.
4212 elsif Nkind (Parnt) = N_Indexed_Component
4213 and then Child /= Prefix (Parnt)
4215 Expand_Packed_Element_Reference (N);
4218 elsif Nkind (Parent (Parnt)) = N_Assignment_Statement
4219 and then Name (Parent (Parnt)) = Parnt
4223 elsif Nkind (Parnt) = N_Attribute_Reference
4224 and then Attribute_Name (Parnt) = Name_Read
4225 and then Next (First (Expressions (Parnt))) = Child
4229 elsif (Nkind (Parnt) = N_Indexed_Component
4230 or else Nkind (Parnt) = N_Selected_Component)
4231 and then Prefix (Parnt) = Child
4236 Expand_Packed_Element_Reference (N);
4240 -- Keep looking up tree for unchecked expression, or if we are
4241 -- the prefix of a possible assignment left side.
4244 Parnt := Parent (Child);
4247 end Expand_N_Indexed_Component;
4249 ---------------------
4250 -- Expand_N_Not_In --
4251 ---------------------
4253 -- Replace a not in b by not (a in b) so that the expansions for (a in b)
4254 -- can be done. This avoids needing to duplicate this expansion code.
4256 procedure Expand_N_Not_In (N : Node_Id) is
4257 Loc : constant Source_Ptr := Sloc (N);
4258 Typ : constant Entity_Id := Etype (N);
4259 Cfs : constant Boolean := Comes_From_Source (N);
4266 Left_Opnd => Left_Opnd (N),
4267 Right_Opnd => Right_Opnd (N))));
4269 -- We want this to appear as coming from source if original does (see
4270 -- tranformations in Expand_N_In).
4272 Set_Comes_From_Source (N, Cfs);
4273 Set_Comes_From_Source (Right_Opnd (N), Cfs);
4275 -- Now analyze tranformed node
4277 Analyze_And_Resolve (N, Typ);
4278 end Expand_N_Not_In;
4284 -- The only replacement required is for the case of a null of type
4285 -- that is an access to protected subprogram. We represent such
4286 -- access values as a record, and so we must replace the occurrence
4287 -- of null by the equivalent record (with a null address and a null
4288 -- pointer in it), so that the backend creates the proper value.
4290 procedure Expand_N_Null (N : Node_Id) is
4291 Loc : constant Source_Ptr := Sloc (N);
4292 Typ : constant Entity_Id := Etype (N);
4296 if Is_Access_Protected_Subprogram_Type (Typ) then
4298 Make_Aggregate (Loc,
4299 Expressions => New_List (
4300 New_Occurrence_Of (RTE (RE_Null_Address), Loc),
4304 Analyze_And_Resolve (N, Equivalent_Type (Typ));
4306 -- For subsequent semantic analysis, the node must retain its
4307 -- type. Gigi in any case replaces this type by the corresponding
4308 -- record type before processing the node.
4314 when RE_Not_Available =>
4318 ---------------------
4319 -- Expand_N_Op_Abs --
4320 ---------------------
4322 procedure Expand_N_Op_Abs (N : Node_Id) is
4323 Loc : constant Source_Ptr := Sloc (N);
4324 Expr : constant Node_Id := Right_Opnd (N);
4327 Unary_Op_Validity_Checks (N);
4329 -- Deal with software overflow checking
4331 if not Backend_Overflow_Checks_On_Target
4332 and then Is_Signed_Integer_Type (Etype (N))
4333 and then Do_Overflow_Check (N)
4335 -- The only case to worry about is when the argument is
4336 -- equal to the largest negative number, so what we do is
4337 -- to insert the check:
4339 -- [constraint_error when Expr = typ'Base'First]
4341 -- with the usual Duplicate_Subexpr use coding for expr
4344 Make_Raise_Constraint_Error (Loc,
4347 Left_Opnd => Duplicate_Subexpr (Expr),
4349 Make_Attribute_Reference (Loc,
4351 New_Occurrence_Of (Base_Type (Etype (Expr)), Loc),
4352 Attribute_Name => Name_First)),
4353 Reason => CE_Overflow_Check_Failed));
4356 -- Vax floating-point types case
4358 if Vax_Float (Etype (N)) then
4359 Expand_Vax_Arith (N);
4361 end Expand_N_Op_Abs;
4363 ---------------------
4364 -- Expand_N_Op_Add --
4365 ---------------------
4367 procedure Expand_N_Op_Add (N : Node_Id) is
4368 Typ : constant Entity_Id := Etype (N);
4371 Binary_Op_Validity_Checks (N);
4373 -- N + 0 = 0 + N = N for integer types
4375 if Is_Integer_Type (Typ) then
4376 if Compile_Time_Known_Value (Right_Opnd (N))
4377 and then Expr_Value (Right_Opnd (N)) = Uint_0
4379 Rewrite (N, Left_Opnd (N));
4382 elsif Compile_Time_Known_Value (Left_Opnd (N))
4383 and then Expr_Value (Left_Opnd (N)) = Uint_0
4385 Rewrite (N, Right_Opnd (N));
4390 -- Arithmetic overflow checks for signed integer/fixed point types
4392 if Is_Signed_Integer_Type (Typ)
4393 or else Is_Fixed_Point_Type (Typ)
4395 Apply_Arithmetic_Overflow_Check (N);
4398 -- Vax floating-point types case
4400 elsif Vax_Float (Typ) then
4401 Expand_Vax_Arith (N);
4403 end Expand_N_Op_Add;
4405 ---------------------
4406 -- Expand_N_Op_And --
4407 ---------------------
4409 procedure Expand_N_Op_And (N : Node_Id) is
4410 Typ : constant Entity_Id := Etype (N);
4413 Binary_Op_Validity_Checks (N);
4415 if Is_Array_Type (Etype (N)) then
4416 Expand_Boolean_Operator (N);
4418 elsif Is_Boolean_Type (Etype (N)) then
4419 Adjust_Condition (Left_Opnd (N));
4420 Adjust_Condition (Right_Opnd (N));
4421 Set_Etype (N, Standard_Boolean);
4422 Adjust_Result_Type (N, Typ);
4424 end Expand_N_Op_And;
4426 ------------------------
4427 -- Expand_N_Op_Concat --
4428 ------------------------
4430 Max_Available_String_Operands : Int := -1;
4431 -- This is initialized the first time this routine is called. It records
4432 -- a value of 0,2,3,4,5 depending on what Str_Concat_n procedures are
4433 -- available in the run-time:
4436 -- 2 RE_Str_Concat available, RE_Str_Concat_3 not available
4437 -- 3 RE_Str_Concat/Concat_2 available, RE_Str_Concat_4 not available
4438 -- 4 RE_Str_Concat/Concat_2/3 available, RE_Str_Concat_5 not available
4439 -- 5 All routines including RE_Str_Concat_5 available
4441 Char_Concat_Available : Boolean;
4442 -- Records if the routines RE_Str_Concat_CC/CS/SC are available. True if
4443 -- all three are available, False if any one of these is unavailable.
4445 procedure Expand_N_Op_Concat (N : Node_Id) is
4447 -- List of operands to be concatenated
4450 -- Single operand for concatenation
4453 -- Node which is to be replaced by the result of concatenating
4454 -- the nodes in the list Opnds.
4457 -- Array type of concatenation result type
4460 -- Component type of concatenation represented by Cnode
4463 -- Initialize global variables showing run-time status
4465 if Max_Available_String_Operands < 1 then
4467 -- In No_Run_Time mode, consider that no entities are available
4469 -- This seems wrong, RTE_Available should return False for any entity
4470 -- that is not in the special No_Run_Time list of allowed entities???
4472 if No_Run_Time_Mode then
4473 Max_Available_String_Operands := 0;
4475 -- Otherwise see what routines are available and set max operand
4476 -- count according to the highest count available in the run-time.
4478 elsif not RTE_Available (RE_Str_Concat) then
4479 Max_Available_String_Operands := 0;
4481 elsif not RTE_Available (RE_Str_Concat_3) then
4482 Max_Available_String_Operands := 2;
4484 elsif not RTE_Available (RE_Str_Concat_4) then
4485 Max_Available_String_Operands := 3;
4487 elsif not RTE_Available (RE_Str_Concat_5) then
4488 Max_Available_String_Operands := 4;
4491 Max_Available_String_Operands := 5;
4494 Char_Concat_Available :=
4495 not No_Run_Time_Mode
4497 RTE_Available (RE_Str_Concat_CC)
4499 RTE_Available (RE_Str_Concat_CS)
4501 RTE_Available (RE_Str_Concat_SC);
4504 -- Ensure validity of both operands
4506 Binary_Op_Validity_Checks (N);
4508 -- If we are the left operand of a concatenation higher up the
4509 -- tree, then do nothing for now, since we want to deal with a
4510 -- series of concatenations as a unit.
4512 if Nkind (Parent (N)) = N_Op_Concat
4513 and then N = Left_Opnd (Parent (N))
4518 -- We get here with a concatenation whose left operand may be a
4519 -- concatenation itself with a consistent type. We need to process
4520 -- these concatenation operands from left to right, which means
4521 -- from the deepest node in the tree to the highest node.
4524 while Nkind (Left_Opnd (Cnode)) = N_Op_Concat loop
4525 Cnode := Left_Opnd (Cnode);
4528 -- Now Opnd is the deepest Opnd, and its parents are the concatenation
4529 -- nodes above, so now we process bottom up, doing the operations. We
4530 -- gather a string that is as long as possible up to five operands
4532 -- The outer loop runs more than once if there are more than five
4533 -- concatenations of type Standard.String, the most we handle for
4534 -- this case, or if more than one concatenation type is involved.
4537 Opnds := New_List (Left_Opnd (Cnode), Right_Opnd (Cnode));
4538 Set_Parent (Opnds, N);
4540 -- The inner loop gathers concatenation operands. We gather any
4541 -- number of these in the non-string case, or if no concatenation
4542 -- routines are available for string (since in that case we will
4543 -- treat string like any other non-string case). Otherwise we only
4544 -- gather as many operands as can be handled by the available
4545 -- procedures in the run-time library (normally 5, but may be
4546 -- less for the configurable run-time case).
4548 Inner : while Cnode /= N
4549 and then (Base_Type (Etype (Cnode)) /= Standard_String
4551 Max_Available_String_Operands = 0
4553 List_Length (Opnds) <
4554 Max_Available_String_Operands)
4555 and then Base_Type (Etype (Cnode)) =
4556 Base_Type (Etype (Parent (Cnode)))
4558 Cnode := Parent (Cnode);
4559 Append (Right_Opnd (Cnode), Opnds);
4562 -- Here we process the collected operands. First we convert
4563 -- singleton operands to singleton aggregates. This is skipped
4564 -- however for the case of two operands of type String, since
4565 -- we have special routines for these cases.
4567 Atyp := Base_Type (Etype (Cnode));
4568 Ctyp := Base_Type (Component_Type (Etype (Cnode)));
4570 if (List_Length (Opnds) > 2 or else Atyp /= Standard_String)
4571 or else not Char_Concat_Available
4573 Opnd := First (Opnds);
4575 if Base_Type (Etype (Opnd)) = Ctyp then
4577 Make_Aggregate (Sloc (Cnode),
4578 Expressions => New_List (Relocate_Node (Opnd))));
4579 Analyze_And_Resolve (Opnd, Atyp);
4583 exit when No (Opnd);
4587 -- Now call appropriate continuation routine
4589 if Atyp = Standard_String
4590 and then Max_Available_String_Operands > 0
4592 Expand_Concatenate_String (Cnode, Opnds);
4594 Expand_Concatenate_Other (Cnode, Opnds);
4597 exit Outer when Cnode = N;
4598 Cnode := Parent (Cnode);
4600 end Expand_N_Op_Concat;
4602 ------------------------
4603 -- Expand_N_Op_Divide --
4604 ------------------------
4606 procedure Expand_N_Op_Divide (N : Node_Id) is
4607 Loc : constant Source_Ptr := Sloc (N);
4608 Lopnd : constant Node_Id := Left_Opnd (N);
4609 Ropnd : constant Node_Id := Right_Opnd (N);
4610 Ltyp : constant Entity_Id := Etype (Lopnd);
4611 Rtyp : constant Entity_Id := Etype (Ropnd);
4612 Typ : Entity_Id := Etype (N);
4613 Rknow : constant Boolean := Is_Integer_Type (Typ)
4615 Compile_Time_Known_Value (Ropnd);
4619 Binary_Op_Validity_Checks (N);
4622 Rval := Expr_Value (Ropnd);
4625 -- N / 1 = N for integer types
4627 if Rknow and then Rval = Uint_1 then
4632 -- Convert x / 2 ** y to Shift_Right (x, y). Note that the fact that
4633 -- Is_Power_Of_2_For_Shift is set means that we know that our left
4634 -- operand is an unsigned integer, as required for this to work.
4636 if Nkind (Ropnd) = N_Op_Expon
4637 and then Is_Power_Of_2_For_Shift (Ropnd)
4639 -- We cannot do this transformation in configurable run time mode if we
4640 -- have 64-bit -- integers and long shifts are not available.
4644 or else Support_Long_Shifts_On_Target)
4647 Make_Op_Shift_Right (Loc,
4650 Convert_To (Standard_Natural, Right_Opnd (Ropnd))));
4651 Analyze_And_Resolve (N, Typ);
4655 -- Do required fixup of universal fixed operation
4657 if Typ = Universal_Fixed then
4658 Fixup_Universal_Fixed_Operation (N);
4662 -- Divisions with fixed-point results
4664 if Is_Fixed_Point_Type (Typ) then
4666 -- No special processing if Treat_Fixed_As_Integer is set,
4667 -- since from a semantic point of view such operations are
4668 -- simply integer operations and will be treated that way.
4670 if not Treat_Fixed_As_Integer (N) then
4671 if Is_Integer_Type (Rtyp) then
4672 Expand_Divide_Fixed_By_Integer_Giving_Fixed (N);
4674 Expand_Divide_Fixed_By_Fixed_Giving_Fixed (N);
4678 -- Other cases of division of fixed-point operands. Again we
4679 -- exclude the case where Treat_Fixed_As_Integer is set.
4681 elsif (Is_Fixed_Point_Type (Ltyp) or else
4682 Is_Fixed_Point_Type (Rtyp))
4683 and then not Treat_Fixed_As_Integer (N)
4685 if Is_Integer_Type (Typ) then
4686 Expand_Divide_Fixed_By_Fixed_Giving_Integer (N);
4688 pragma Assert (Is_Floating_Point_Type (Typ));
4689 Expand_Divide_Fixed_By_Fixed_Giving_Float (N);
4692 -- Mixed-mode operations can appear in a non-static universal
4693 -- context, in which case the integer argument must be converted
4696 elsif Typ = Universal_Real
4697 and then Is_Integer_Type (Rtyp)
4700 Convert_To (Universal_Real, Relocate_Node (Ropnd)));
4702 Analyze_And_Resolve (Ropnd, Universal_Real);
4704 elsif Typ = Universal_Real
4705 and then Is_Integer_Type (Ltyp)
4708 Convert_To (Universal_Real, Relocate_Node (Lopnd)));
4710 Analyze_And_Resolve (Lopnd, Universal_Real);
4712 -- Non-fixed point cases, do integer zero divide and overflow checks
4714 elsif Is_Integer_Type (Typ) then
4715 Apply_Divide_Check (N);
4717 -- Check for 64-bit division available, or long shifts if the divisor
4718 -- is a small power of 2 (since such divides will be converted into
4721 if Esize (Ltyp) > 32
4722 and then not Support_64_Bit_Divides_On_Target
4725 or else not Support_Long_Shifts_On_Target
4726 or else (Rval /= Uint_2 and then
4727 Rval /= Uint_4 and then
4728 Rval /= Uint_8 and then
4729 Rval /= Uint_16 and then
4730 Rval /= Uint_32 and then
4733 Error_Msg_CRT ("64-bit division", N);
4736 -- Deal with Vax_Float
4738 elsif Vax_Float (Typ) then
4739 Expand_Vax_Arith (N);
4742 end Expand_N_Op_Divide;
4744 --------------------
4745 -- Expand_N_Op_Eq --
4746 --------------------
4748 procedure Expand_N_Op_Eq (N : Node_Id) is
4749 Loc : constant Source_Ptr := Sloc (N);
4750 Typ : constant Entity_Id := Etype (N);
4751 Lhs : constant Node_Id := Left_Opnd (N);
4752 Rhs : constant Node_Id := Right_Opnd (N);
4753 Bodies : constant List_Id := New_List;
4754 A_Typ : constant Entity_Id := Etype (Lhs);
4756 Typl : Entity_Id := A_Typ;
4757 Op_Name : Entity_Id;
4760 procedure Build_Equality_Call (Eq : Entity_Id);
4761 -- If a constructed equality exists for the type or for its parent,
4762 -- build and analyze call, adding conversions if the operation is
4765 function Has_Unconstrained_UU_Component (Typ : Node_Id) return Boolean;
4766 -- Determines whether a type has a subcompoment of an unconstrained
4767 -- Unchecked_Union subtype. Typ is a record type.
4769 -------------------------
4770 -- Build_Equality_Call --
4771 -------------------------
4773 procedure Build_Equality_Call (Eq : Entity_Id) is
4774 Op_Type : constant Entity_Id := Etype (First_Formal (Eq));
4775 L_Exp : Node_Id := Relocate_Node (Lhs);
4776 R_Exp : Node_Id := Relocate_Node (Rhs);
4779 if Base_Type (Op_Type) /= Base_Type (A_Typ)
4780 and then not Is_Class_Wide_Type (A_Typ)
4782 L_Exp := OK_Convert_To (Op_Type, L_Exp);
4783 R_Exp := OK_Convert_To (Op_Type, R_Exp);
4786 -- If we have an Unchecked_Union, we need to add the inferred
4787 -- discriminant values as actuals in the function call. At this
4788 -- point, the expansion has determined that both operands have
4789 -- inferable discriminants.
4791 if Is_Unchecked_Union (Op_Type) then
4793 Lhs_Type : constant Node_Id := Etype (L_Exp);
4794 Rhs_Type : constant Node_Id := Etype (R_Exp);
4795 Lhs_Discr_Val : Node_Id;
4796 Rhs_Discr_Val : Node_Id;
4799 -- Per-object constrained selected components require special
4800 -- attention. If the enclosing scope of the component is an
4801 -- Unchecked_Union, we cannot reference its discriminants
4802 -- directly. This is why we use the two extra parameters of
4803 -- the equality function of the enclosing Unchecked_Union.
4805 -- type UU_Type (Discr : Integer := 0) is
4808 -- pragma Unchecked_Union (UU_Type);
4810 -- 1. Unchecked_Union enclosing record:
4812 -- type Enclosing_UU_Type (Discr : Integer := 0) is record
4814 -- Comp : UU_Type (Discr);
4816 -- end Enclosing_UU_Type;
4817 -- pragma Unchecked_Union (Enclosing_UU_Type);
4819 -- Obj1 : Enclosing_UU_Type;
4820 -- Obj2 : Enclosing_UU_Type (1);
4822 -- [. . .] Obj1 = Obj2 [. . .]
4826 -- if not (uu_typeEQ (obj1.comp, obj2.comp, a, b)) then
4828 -- A and B are the formal parameters of the equality function
4829 -- of Enclosing_UU_Type. The function always has two extra
4830 -- formals to capture the inferred discriminant values.
4832 -- 2. Non-Unchecked_Union enclosing record:
4835 -- Enclosing_Non_UU_Type (Discr : Integer := 0)
4838 -- Comp : UU_Type (Discr);
4840 -- end Enclosing_Non_UU_Type;
4842 -- Obj1 : Enclosing_Non_UU_Type;
4843 -- Obj2 : Enclosing_Non_UU_Type (1);
4845 -- ... Obj1 = Obj2 ...
4849 -- if not (uu_typeEQ (obj1.comp, obj2.comp,
4850 -- obj1.discr, obj2.discr)) then
4852 -- In this case we can directly reference the discriminants of
4853 -- the enclosing record.
4857 if Nkind (Lhs) = N_Selected_Component
4858 and then Has_Per_Object_Constraint
4859 (Entity (Selector_Name (Lhs)))
4861 -- Enclosing record is an Unchecked_Union, use formal A
4863 if Is_Unchecked_Union (Scope
4864 (Entity (Selector_Name (Lhs))))
4867 Make_Identifier (Loc,
4870 -- Enclosing record is of a non-Unchecked_Union type, it is
4871 -- possible to reference the discriminant.
4875 Make_Selected_Component (Loc,
4876 Prefix => Prefix (Lhs),
4879 (Get_Discriminant_Value
4880 (First_Discriminant (Lhs_Type),
4882 Stored_Constraint (Lhs_Type))));
4885 -- Comment needed here ???
4888 -- Infer the discriminant value
4892 (Get_Discriminant_Value
4893 (First_Discriminant (Lhs_Type),
4895 Stored_Constraint (Lhs_Type)));
4900 if Nkind (Rhs) = N_Selected_Component
4901 and then Has_Per_Object_Constraint
4902 (Entity (Selector_Name (Rhs)))
4904 if Is_Unchecked_Union
4905 (Scope (Entity (Selector_Name (Rhs))))
4908 Make_Identifier (Loc,
4913 Make_Selected_Component (Loc,
4914 Prefix => Prefix (Rhs),
4916 New_Copy (Get_Discriminant_Value (
4917 First_Discriminant (Rhs_Type),
4919 Stored_Constraint (Rhs_Type))));
4924 New_Copy (Get_Discriminant_Value (
4925 First_Discriminant (Rhs_Type),
4927 Stored_Constraint (Rhs_Type)));
4932 Make_Function_Call (Loc,
4933 Name => New_Reference_To (Eq, Loc),
4934 Parameter_Associations => New_List (
4941 -- Normal case, not an unchecked union
4945 Make_Function_Call (Loc,
4946 Name => New_Reference_To (Eq, Loc),
4947 Parameter_Associations => New_List (L_Exp, R_Exp)));
4950 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
4951 end Build_Equality_Call;
4953 ------------------------------------
4954 -- Has_Unconstrained_UU_Component --
4955 ------------------------------------
4957 function Has_Unconstrained_UU_Component
4958 (Typ : Node_Id) return Boolean
4960 Tdef : constant Node_Id :=
4961 Type_Definition (Declaration_Node (Base_Type (Typ)));
4965 function Component_Is_Unconstrained_UU
4966 (Comp : Node_Id) return Boolean;
4967 -- Determines whether the subtype of the component is an
4968 -- unconstrained Unchecked_Union.
4970 function Variant_Is_Unconstrained_UU
4971 (Variant : Node_Id) return Boolean;
4972 -- Determines whether a component of the variant has an unconstrained
4973 -- Unchecked_Union subtype.
4975 -----------------------------------
4976 -- Component_Is_Unconstrained_UU --
4977 -----------------------------------
4979 function Component_Is_Unconstrained_UU
4980 (Comp : Node_Id) return Boolean
4983 if Nkind (Comp) /= N_Component_Declaration then
4988 Sindic : constant Node_Id :=
4989 Subtype_Indication (Component_Definition (Comp));
4992 -- Unconstrained nominal type. In the case of a constraint
4993 -- present, the node kind would have been N_Subtype_Indication.
4995 if Nkind (Sindic) = N_Identifier then
4996 return Is_Unchecked_Union (Base_Type (Etype (Sindic)));
5001 end Component_Is_Unconstrained_UU;
5003 ---------------------------------
5004 -- Variant_Is_Unconstrained_UU --
5005 ---------------------------------
5007 function Variant_Is_Unconstrained_UU
5008 (Variant : Node_Id) return Boolean
5010 Clist : constant Node_Id := Component_List (Variant);
5013 if Is_Empty_List (Component_Items (Clist)) then
5017 -- We only need to test one component
5020 Comp : Node_Id := First (Component_Items (Clist));
5023 while Present (Comp) loop
5024 if Component_Is_Unconstrained_UU (Comp) then
5032 -- None of the components withing the variant were of
5033 -- unconstrained Unchecked_Union type.
5036 end Variant_Is_Unconstrained_UU;
5038 -- Start of processing for Has_Unconstrained_UU_Component
5041 if Null_Present (Tdef) then
5045 Clist := Component_List (Tdef);
5046 Vpart := Variant_Part (Clist);
5048 -- Inspect available components
5050 if Present (Component_Items (Clist)) then
5052 Comp : Node_Id := First (Component_Items (Clist));
5055 while Present (Comp) loop
5057 -- One component is sufficent
5059 if Component_Is_Unconstrained_UU (Comp) then
5068 -- Inspect available components withing variants
5070 if Present (Vpart) then
5072 Variant : Node_Id := First (Variants (Vpart));
5075 while Present (Variant) loop
5077 -- One component within a variant is sufficent
5079 if Variant_Is_Unconstrained_UU (Variant) then
5088 -- Neither the available components, nor the components inside the
5089 -- variant parts were of an unconstrained Unchecked_Union subtype.
5092 end Has_Unconstrained_UU_Component;
5094 -- Start of processing for Expand_N_Op_Eq
5097 Binary_Op_Validity_Checks (N);
5099 if Ekind (Typl) = E_Private_Type then
5100 Typl := Underlying_Type (Typl);
5101 elsif Ekind (Typl) = E_Private_Subtype then
5102 Typl := Underlying_Type (Base_Type (Typl));
5107 -- It may happen in error situations that the underlying type is not
5108 -- set. The error will be detected later, here we just defend the
5115 Typl := Base_Type (Typl);
5117 -- Boolean types (requiring handling of non-standard case)
5119 if Is_Boolean_Type (Typl) then
5120 Adjust_Condition (Left_Opnd (N));
5121 Adjust_Condition (Right_Opnd (N));
5122 Set_Etype (N, Standard_Boolean);
5123 Adjust_Result_Type (N, Typ);
5127 elsif Is_Array_Type (Typl) then
5129 -- If we are doing full validity checking, then expand out array
5130 -- comparisons to make sure that we check the array elements.
5132 if Validity_Check_Operands then
5134 Save_Force_Validity_Checks : constant Boolean :=
5135 Force_Validity_Checks;
5137 Force_Validity_Checks := True;
5139 Expand_Array_Equality
5141 Relocate_Node (Lhs),
5142 Relocate_Node (Rhs),
5145 Insert_Actions (N, Bodies);
5146 Analyze_And_Resolve (N, Standard_Boolean);
5147 Force_Validity_Checks := Save_Force_Validity_Checks;
5150 -- Packed case where both operands are known aligned
5152 elsif Is_Bit_Packed_Array (Typl)
5153 and then not Is_Possibly_Unaligned_Object (Lhs)
5154 and then not Is_Possibly_Unaligned_Object (Rhs)
5156 Expand_Packed_Eq (N);
5158 -- Where the component type is elementary we can use a block bit
5159 -- comparison (if supported on the target) exception in the case
5160 -- of floating-point (negative zero issues require element by
5161 -- element comparison), and atomic types (where we must be sure
5162 -- to load elements independently) and possibly unaligned arrays.
5164 elsif Is_Elementary_Type (Component_Type (Typl))
5165 and then not Is_Floating_Point_Type (Component_Type (Typl))
5166 and then not Is_Atomic (Component_Type (Typl))
5167 and then not Is_Possibly_Unaligned_Object (Lhs)
5168 and then not Is_Possibly_Unaligned_Object (Rhs)
5169 and then Support_Composite_Compare_On_Target
5173 -- For composite and floating-point cases, expand equality loop
5174 -- to make sure of using proper comparisons for tagged types,
5175 -- and correctly handling the floating-point case.
5179 Expand_Array_Equality
5181 Relocate_Node (Lhs),
5182 Relocate_Node (Rhs),
5185 Insert_Actions (N, Bodies, Suppress => All_Checks);
5186 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
5191 elsif Is_Record_Type (Typl) then
5193 -- For tagged types, use the primitive "="
5195 if Is_Tagged_Type (Typl) then
5197 -- No need to do anything else compiling under restriction
5198 -- No_Dispatching_Calls. During the semantic analysis we
5199 -- already notified such violation.
5201 if Restriction_Active (No_Dispatching_Calls) then
5205 -- If this is derived from an untagged private type completed
5206 -- with a tagged type, it does not have a full view, so we
5207 -- use the primitive operations of the private type.
5208 -- This check should no longer be necessary when these
5209 -- types receive their full views ???
5211 if Is_Private_Type (A_Typ)
5212 and then not Is_Tagged_Type (A_Typ)
5213 and then Is_Derived_Type (A_Typ)
5214 and then No (Full_View (A_Typ))
5216 -- Search for equality operation, checking that the
5217 -- operands have the same type. Note that we must find
5218 -- a matching entry, or something is very wrong!
5220 Prim := First_Elmt (Collect_Primitive_Operations (A_Typ));
5222 while Present (Prim) loop
5223 exit when Chars (Node (Prim)) = Name_Op_Eq
5224 and then Etype (First_Formal (Node (Prim))) =
5225 Etype (Next_Formal (First_Formal (Node (Prim))))
5227 Base_Type (Etype (Node (Prim))) = Standard_Boolean;
5232 pragma Assert (Present (Prim));
5233 Op_Name := Node (Prim);
5235 -- Find the type's predefined equality or an overriding
5236 -- user-defined equality. The reason for not simply calling
5237 -- Find_Prim_Op here is that there may be a user-defined
5238 -- overloaded equality op that precedes the equality that
5239 -- we want, so we have to explicitly search (e.g., there
5240 -- could be an equality with two different parameter types).
5243 if Is_Class_Wide_Type (Typl) then
5244 Typl := Root_Type (Typl);
5247 Prim := First_Elmt (Primitive_Operations (Typl));
5248 while Present (Prim) loop
5249 exit when Chars (Node (Prim)) = Name_Op_Eq
5250 and then Etype (First_Formal (Node (Prim))) =
5251 Etype (Next_Formal (First_Formal (Node (Prim))))
5253 Base_Type (Etype (Node (Prim))) = Standard_Boolean;
5258 pragma Assert (Present (Prim));
5259 Op_Name := Node (Prim);
5262 Build_Equality_Call (Op_Name);
5264 -- Ada 2005 (AI-216): Program_Error is raised when evaluating the
5265 -- predefined equality operator for a type which has a subcomponent
5266 -- of an Unchecked_Union type whose nominal subtype is unconstrained.
5268 elsif Has_Unconstrained_UU_Component (Typl) then
5270 Make_Raise_Program_Error (Loc,
5271 Reason => PE_Unchecked_Union_Restriction));
5273 -- Prevent Gigi from generating incorrect code by rewriting the
5274 -- equality as a standard False.
5277 New_Occurrence_Of (Standard_False, Loc));
5279 elsif Is_Unchecked_Union (Typl) then
5281 -- If we can infer the discriminants of the operands, we make a
5282 -- call to the TSS equality function.
5284 if Has_Inferable_Discriminants (Lhs)
5286 Has_Inferable_Discriminants (Rhs)
5289 (TSS (Root_Type (Typl), TSS_Composite_Equality));
5292 -- Ada 2005 (AI-216): Program_Error is raised when evaluating
5293 -- the predefined equality operator for an Unchecked_Union type
5294 -- if either of the operands lack inferable discriminants.
5297 Make_Raise_Program_Error (Loc,
5298 Reason => PE_Unchecked_Union_Restriction));
5300 -- Prevent Gigi from generating incorrect code by rewriting
5301 -- the equality as a standard False.
5304 New_Occurrence_Of (Standard_False, Loc));
5308 -- If a type support function is present (for complex cases), use it
5310 elsif Present (TSS (Root_Type (Typl), TSS_Composite_Equality)) then
5312 (TSS (Root_Type (Typl), TSS_Composite_Equality));
5314 -- Otherwise expand the component by component equality. Note that
5315 -- we never use block-bit coparisons for records, because of the
5316 -- problems with gaps. The backend will often be able to recombine
5317 -- the separate comparisons that we generate here.
5320 Remove_Side_Effects (Lhs);
5321 Remove_Side_Effects (Rhs);
5323 Expand_Record_Equality (N, Typl, Lhs, Rhs, Bodies));
5325 Insert_Actions (N, Bodies, Suppress => All_Checks);
5326 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
5330 -- Test if result is known at compile time
5332 Rewrite_Comparison (N);
5334 -- If we still have comparison for Vax_Float, process it
5336 if Vax_Float (Typl) and then Nkind (N) in N_Op_Compare then
5337 Expand_Vax_Comparison (N);
5342 -----------------------
5343 -- Expand_N_Op_Expon --
5344 -----------------------
5346 procedure Expand_N_Op_Expon (N : Node_Id) is
5347 Loc : constant Source_Ptr := Sloc (N);
5348 Typ : constant Entity_Id := Etype (N);
5349 Rtyp : constant Entity_Id := Root_Type (Typ);
5350 Base : constant Node_Id := Relocate_Node (Left_Opnd (N));
5351 Bastyp : constant Node_Id := Etype (Base);
5352 Exp : constant Node_Id := Relocate_Node (Right_Opnd (N));
5353 Exptyp : constant Entity_Id := Etype (Exp);
5354 Ovflo : constant Boolean := Do_Overflow_Check (N);
5363 Binary_Op_Validity_Checks (N);
5365 -- If either operand is of a private type, then we have the use of
5366 -- an intrinsic operator, and we get rid of the privateness, by using
5367 -- root types of underlying types for the actual operation. Otherwise
5368 -- the private types will cause trouble if we expand multiplications
5369 -- or shifts etc. We also do this transformation if the result type
5370 -- is different from the base type.
5372 if Is_Private_Type (Etype (Base))
5374 Is_Private_Type (Typ)
5376 Is_Private_Type (Exptyp)
5378 Rtyp /= Root_Type (Bastyp)
5381 Bt : constant Entity_Id := Root_Type (Underlying_Type (Bastyp));
5382 Et : constant Entity_Id := Root_Type (Underlying_Type (Exptyp));
5386 Unchecked_Convert_To (Typ,
5388 Left_Opnd => Unchecked_Convert_To (Bt, Base),
5389 Right_Opnd => Unchecked_Convert_To (Et, Exp))));
5390 Analyze_And_Resolve (N, Typ);
5395 -- Test for case of known right argument
5397 if Compile_Time_Known_Value (Exp) then
5398 Expv := Expr_Value (Exp);
5400 -- We only fold small non-negative exponents. You might think we
5401 -- could fold small negative exponents for the real case, but we
5402 -- can't because we are required to raise Constraint_Error for
5403 -- the case of 0.0 ** (negative) even if Machine_Overflows = False.
5404 -- See ACVC test C4A012B.
5406 if Expv >= 0 and then Expv <= 4 then
5408 -- X ** 0 = 1 (or 1.0)
5411 if Ekind (Typ) in Integer_Kind then
5412 Xnode := Make_Integer_Literal (Loc, Intval => 1);
5414 Xnode := Make_Real_Literal (Loc, Ureal_1);
5426 Make_Op_Multiply (Loc,
5427 Left_Opnd => Duplicate_Subexpr (Base),
5428 Right_Opnd => Duplicate_Subexpr_No_Checks (Base));
5430 -- X ** 3 = X * X * X
5434 Make_Op_Multiply (Loc,
5436 Make_Op_Multiply (Loc,
5437 Left_Opnd => Duplicate_Subexpr (Base),
5438 Right_Opnd => Duplicate_Subexpr_No_Checks (Base)),
5439 Right_Opnd => Duplicate_Subexpr_No_Checks (Base));
5442 -- En : constant base'type := base * base;
5448 Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
5450 Insert_Actions (N, New_List (
5451 Make_Object_Declaration (Loc,
5452 Defining_Identifier => Temp,
5453 Constant_Present => True,
5454 Object_Definition => New_Reference_To (Typ, Loc),
5456 Make_Op_Multiply (Loc,
5457 Left_Opnd => Duplicate_Subexpr (Base),
5458 Right_Opnd => Duplicate_Subexpr_No_Checks (Base)))));
5461 Make_Op_Multiply (Loc,
5462 Left_Opnd => New_Reference_To (Temp, Loc),
5463 Right_Opnd => New_Reference_To (Temp, Loc));
5467 Analyze_And_Resolve (N, Typ);
5472 -- Case of (2 ** expression) appearing as an argument of an integer
5473 -- multiplication, or as the right argument of a division of a non-
5474 -- negative integer. In such cases we leave the node untouched, setting
5475 -- the flag Is_Natural_Power_Of_2_for_Shift set, then the expansion
5476 -- of the higher level node converts it into a shift.
5478 if Nkind (Base) = N_Integer_Literal
5479 and then Intval (Base) = 2
5480 and then Is_Integer_Type (Root_Type (Exptyp))
5481 and then Esize (Root_Type (Exptyp)) <= Esize (Standard_Integer)
5482 and then Is_Unsigned_Type (Exptyp)
5484 and then Nkind (Parent (N)) in N_Binary_Op
5487 P : constant Node_Id := Parent (N);
5488 L : constant Node_Id := Left_Opnd (P);
5489 R : constant Node_Id := Right_Opnd (P);
5492 if (Nkind (P) = N_Op_Multiply
5494 ((Is_Integer_Type (Etype (L)) and then R = N)
5496 (Is_Integer_Type (Etype (R)) and then L = N))
5497 and then not Do_Overflow_Check (P))
5500 (Nkind (P) = N_Op_Divide
5501 and then Is_Integer_Type (Etype (L))
5502 and then Is_Unsigned_Type (Etype (L))
5504 and then not Do_Overflow_Check (P))
5506 Set_Is_Power_Of_2_For_Shift (N);
5512 -- Fall through if exponentiation must be done using a runtime routine
5514 -- First deal with modular case
5516 if Is_Modular_Integer_Type (Rtyp) then
5518 -- Non-binary case, we call the special exponentiation routine for
5519 -- the non-binary case, converting the argument to Long_Long_Integer
5520 -- and passing the modulus value. Then the result is converted back
5521 -- to the base type.
5523 if Non_Binary_Modulus (Rtyp) then
5526 Make_Function_Call (Loc,
5527 Name => New_Reference_To (RTE (RE_Exp_Modular), Loc),
5528 Parameter_Associations => New_List (
5529 Convert_To (Standard_Integer, Base),
5530 Make_Integer_Literal (Loc, Modulus (Rtyp)),
5533 -- Binary case, in this case, we call one of two routines, either
5534 -- the unsigned integer case, or the unsigned long long integer
5535 -- case, with a final "and" operation to do the required mod.
5538 if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
5539 Ent := RTE (RE_Exp_Unsigned);
5541 Ent := RTE (RE_Exp_Long_Long_Unsigned);
5548 Make_Function_Call (Loc,
5549 Name => New_Reference_To (Ent, Loc),
5550 Parameter_Associations => New_List (
5551 Convert_To (Etype (First_Formal (Ent)), Base),
5554 Make_Integer_Literal (Loc, Modulus (Rtyp) - 1))));
5558 -- Common exit point for modular type case
5560 Analyze_And_Resolve (N, Typ);
5563 -- Signed integer cases, done using either Integer or Long_Long_Integer.
5564 -- It is not worth having routines for Short_[Short_]Integer, since for
5565 -- most machines it would not help, and it would generate more code that
5566 -- might need certification when a certified run time is required.
5568 -- In the integer cases, we have two routines, one for when overflow
5569 -- checks are required, and one when they are not required, since there
5570 -- is a real gain in omitting checks on many machines.
5572 elsif Rtyp = Base_Type (Standard_Long_Long_Integer)
5573 or else (Rtyp = Base_Type (Standard_Long_Integer)
5575 Esize (Standard_Long_Integer) > Esize (Standard_Integer))
5576 or else (Rtyp = Universal_Integer)
5578 Etyp := Standard_Long_Long_Integer;
5581 Rent := RE_Exp_Long_Long_Integer;
5583 Rent := RE_Exn_Long_Long_Integer;
5586 elsif Is_Signed_Integer_Type (Rtyp) then
5587 Etyp := Standard_Integer;
5590 Rent := RE_Exp_Integer;
5592 Rent := RE_Exn_Integer;
5595 -- Floating-point cases, always done using Long_Long_Float. We do not
5596 -- need separate routines for the overflow case here, since in the case
5597 -- of floating-point, we generate infinities anyway as a rule (either
5598 -- that or we automatically trap overflow), and if there is an infinity
5599 -- generated and a range check is required, the check will fail anyway.
5602 pragma Assert (Is_Floating_Point_Type (Rtyp));
5603 Etyp := Standard_Long_Long_Float;
5604 Rent := RE_Exn_Long_Long_Float;
5607 -- Common processing for integer cases and floating-point cases.
5608 -- If we are in the right type, we can call runtime routine directly
5611 and then Rtyp /= Universal_Integer
5612 and then Rtyp /= Universal_Real
5615 Make_Function_Call (Loc,
5616 Name => New_Reference_To (RTE (Rent), Loc),
5617 Parameter_Associations => New_List (Base, Exp)));
5619 -- Otherwise we have to introduce conversions (conversions are also
5620 -- required in the universal cases, since the runtime routine is
5621 -- typed using one of the standard types.
5626 Make_Function_Call (Loc,
5627 Name => New_Reference_To (RTE (Rent), Loc),
5628 Parameter_Associations => New_List (
5629 Convert_To (Etyp, Base),
5633 Analyze_And_Resolve (N, Typ);
5637 when RE_Not_Available =>
5639 end Expand_N_Op_Expon;
5641 --------------------
5642 -- Expand_N_Op_Ge --
5643 --------------------
5645 procedure Expand_N_Op_Ge (N : Node_Id) is
5646 Typ : constant Entity_Id := Etype (N);
5647 Op1 : constant Node_Id := Left_Opnd (N);
5648 Op2 : constant Node_Id := Right_Opnd (N);
5649 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
5652 Binary_Op_Validity_Checks (N);
5654 if Is_Array_Type (Typ1) then
5655 Expand_Array_Comparison (N);
5659 if Is_Boolean_Type (Typ1) then
5660 Adjust_Condition (Op1);
5661 Adjust_Condition (Op2);
5662 Set_Etype (N, Standard_Boolean);
5663 Adjust_Result_Type (N, Typ);
5666 Rewrite_Comparison (N);
5668 -- If we still have comparison, and Vax_Float type, process it
5670 if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
5671 Expand_Vax_Comparison (N);
5676 --------------------
5677 -- Expand_N_Op_Gt --
5678 --------------------
5680 procedure Expand_N_Op_Gt (N : Node_Id) is
5681 Typ : constant Entity_Id := Etype (N);
5682 Op1 : constant Node_Id := Left_Opnd (N);
5683 Op2 : constant Node_Id := Right_Opnd (N);
5684 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
5687 Binary_Op_Validity_Checks (N);
5689 if Is_Array_Type (Typ1) then
5690 Expand_Array_Comparison (N);
5694 if Is_Boolean_Type (Typ1) then
5695 Adjust_Condition (Op1);
5696 Adjust_Condition (Op2);
5697 Set_Etype (N, Standard_Boolean);
5698 Adjust_Result_Type (N, Typ);
5701 Rewrite_Comparison (N);
5703 -- If we still have comparison, and Vax_Float type, process it
5705 if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
5706 Expand_Vax_Comparison (N);
5711 --------------------
5712 -- Expand_N_Op_Le --
5713 --------------------
5715 procedure Expand_N_Op_Le (N : Node_Id) is
5716 Typ : constant Entity_Id := Etype (N);
5717 Op1 : constant Node_Id := Left_Opnd (N);
5718 Op2 : constant Node_Id := Right_Opnd (N);
5719 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
5722 Binary_Op_Validity_Checks (N);
5724 if Is_Array_Type (Typ1) then
5725 Expand_Array_Comparison (N);
5729 if Is_Boolean_Type (Typ1) then
5730 Adjust_Condition (Op1);
5731 Adjust_Condition (Op2);
5732 Set_Etype (N, Standard_Boolean);
5733 Adjust_Result_Type (N, Typ);
5736 Rewrite_Comparison (N);
5738 -- If we still have comparison, and Vax_Float type, process it
5740 if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
5741 Expand_Vax_Comparison (N);
5746 --------------------
5747 -- Expand_N_Op_Lt --
5748 --------------------
5750 procedure Expand_N_Op_Lt (N : Node_Id) is
5751 Typ : constant Entity_Id := Etype (N);
5752 Op1 : constant Node_Id := Left_Opnd (N);
5753 Op2 : constant Node_Id := Right_Opnd (N);
5754 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
5757 Binary_Op_Validity_Checks (N);
5759 if Is_Array_Type (Typ1) then
5760 Expand_Array_Comparison (N);
5764 if Is_Boolean_Type (Typ1) then
5765 Adjust_Condition (Op1);
5766 Adjust_Condition (Op2);
5767 Set_Etype (N, Standard_Boolean);
5768 Adjust_Result_Type (N, Typ);
5771 Rewrite_Comparison (N);
5773 -- If we still have comparison, and Vax_Float type, process it
5775 if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
5776 Expand_Vax_Comparison (N);
5781 -----------------------
5782 -- Expand_N_Op_Minus --
5783 -----------------------
5785 procedure Expand_N_Op_Minus (N : Node_Id) is
5786 Loc : constant Source_Ptr := Sloc (N);
5787 Typ : constant Entity_Id := Etype (N);
5790 Unary_Op_Validity_Checks (N);
5792 if not Backend_Overflow_Checks_On_Target
5793 and then Is_Signed_Integer_Type (Etype (N))
5794 and then Do_Overflow_Check (N)
5796 -- Software overflow checking expands -expr into (0 - expr)
5799 Make_Op_Subtract (Loc,
5800 Left_Opnd => Make_Integer_Literal (Loc, 0),
5801 Right_Opnd => Right_Opnd (N)));
5803 Analyze_And_Resolve (N, Typ);
5805 -- Vax floating-point types case
5807 elsif Vax_Float (Etype (N)) then
5808 Expand_Vax_Arith (N);
5810 end Expand_N_Op_Minus;
5812 ---------------------
5813 -- Expand_N_Op_Mod --
5814 ---------------------
5816 procedure Expand_N_Op_Mod (N : Node_Id) is
5817 Loc : constant Source_Ptr := Sloc (N);
5818 Typ : constant Entity_Id := Etype (N);
5819 Left : constant Node_Id := Left_Opnd (N);
5820 Right : constant Node_Id := Right_Opnd (N);
5821 DOC : constant Boolean := Do_Overflow_Check (N);
5822 DDC : constant Boolean := Do_Division_Check (N);
5833 Binary_Op_Validity_Checks (N);
5835 Determine_Range (Right, ROK, Rlo, Rhi);
5836 Determine_Range (Left, LOK, Llo, Lhi);
5838 -- Convert mod to rem if operands are known non-negative. We do this
5839 -- since it is quite likely that this will improve the quality of code,
5840 -- (the operation now corresponds to the hardware remainder), and it
5841 -- does not seem likely that it could be harmful.
5843 if LOK and then Llo >= 0
5845 ROK and then Rlo >= 0
5848 Make_Op_Rem (Sloc (N),
5849 Left_Opnd => Left_Opnd (N),
5850 Right_Opnd => Right_Opnd (N)));
5852 -- Instead of reanalyzing the node we do the analysis manually.
5853 -- This avoids anomalies when the replacement is done in an
5854 -- instance and is epsilon more efficient.
5856 Set_Entity (N, Standard_Entity (S_Op_Rem));
5858 Set_Do_Overflow_Check (N, DOC);
5859 Set_Do_Division_Check (N, DDC);
5860 Expand_N_Op_Rem (N);
5863 -- Otherwise, normal mod processing
5866 if Is_Integer_Type (Etype (N)) then
5867 Apply_Divide_Check (N);
5870 -- Apply optimization x mod 1 = 0. We don't really need that with
5871 -- gcc, but it is useful with other back ends (e.g. AAMP), and is
5872 -- certainly harmless.
5874 if Is_Integer_Type (Etype (N))
5875 and then Compile_Time_Known_Value (Right)
5876 and then Expr_Value (Right) = Uint_1
5878 Rewrite (N, Make_Integer_Literal (Loc, 0));
5879 Analyze_And_Resolve (N, Typ);
5883 -- Deal with annoying case of largest negative number remainder
5884 -- minus one. Gigi does not handle this case correctly, because
5885 -- it generates a divide instruction which may trap in this case.
5887 -- In fact the check is quite easy, if the right operand is -1,
5888 -- then the mod value is always 0, and we can just ignore the
5889 -- left operand completely in this case.
5891 -- The operand type may be private (e.g. in the expansion of an
5892 -- an intrinsic operation) so we must use the underlying type to
5893 -- get the bounds, and convert the literals explicitly.
5897 (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
5899 if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
5901 ((not LOK) or else (Llo = LLB))
5904 Make_Conditional_Expression (Loc,
5905 Expressions => New_List (
5907 Left_Opnd => Duplicate_Subexpr (Right),
5909 Unchecked_Convert_To (Typ,
5910 Make_Integer_Literal (Loc, -1))),
5911 Unchecked_Convert_To (Typ,
5912 Make_Integer_Literal (Loc, Uint_0)),
5913 Relocate_Node (N))));
5915 Set_Analyzed (Next (Next (First (Expressions (N)))));
5916 Analyze_And_Resolve (N, Typ);
5919 end Expand_N_Op_Mod;
5921 --------------------------
5922 -- Expand_N_Op_Multiply --
5923 --------------------------
5925 procedure Expand_N_Op_Multiply (N : Node_Id) is
5926 Loc : constant Source_Ptr := Sloc (N);
5927 Lop : constant Node_Id := Left_Opnd (N);
5928 Rop : constant Node_Id := Right_Opnd (N);
5930 Lp2 : constant Boolean :=
5931 Nkind (Lop) = N_Op_Expon
5932 and then Is_Power_Of_2_For_Shift (Lop);
5934 Rp2 : constant Boolean :=
5935 Nkind (Rop) = N_Op_Expon
5936 and then Is_Power_Of_2_For_Shift (Rop);
5938 Ltyp : constant Entity_Id := Etype (Lop);
5939 Rtyp : constant Entity_Id := Etype (Rop);
5940 Typ : Entity_Id := Etype (N);
5943 Binary_Op_Validity_Checks (N);
5945 -- Special optimizations for integer types
5947 if Is_Integer_Type (Typ) then
5949 -- N * 0 = 0 * N = 0 for integer types
5951 if (Compile_Time_Known_Value (Rop)
5952 and then Expr_Value (Rop) = Uint_0)
5954 (Compile_Time_Known_Value (Lop)
5955 and then Expr_Value (Lop) = Uint_0)
5957 Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
5958 Analyze_And_Resolve (N, Typ);
5962 -- N * 1 = 1 * N = N for integer types
5964 -- This optimisation is not done if we are going to
5965 -- rewrite the product 1 * 2 ** N to a shift.
5967 if Compile_Time_Known_Value (Rop)
5968 and then Expr_Value (Rop) = Uint_1
5974 elsif Compile_Time_Known_Value (Lop)
5975 and then Expr_Value (Lop) = Uint_1
5983 -- Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that
5984 -- Is_Power_Of_2_For_Shift is set means that we know that our left
5985 -- operand is an integer, as required for this to work.
5990 -- Convert 2 ** A * 2 ** B into 2 ** (A + B)
5994 Left_Opnd => Make_Integer_Literal (Loc, 2),
5997 Left_Opnd => Right_Opnd (Lop),
5998 Right_Opnd => Right_Opnd (Rop))));
5999 Analyze_And_Resolve (N, Typ);
6004 Make_Op_Shift_Left (Loc,
6007 Convert_To (Standard_Natural, Right_Opnd (Rop))));
6008 Analyze_And_Resolve (N, Typ);
6012 -- Same processing for the operands the other way round
6016 Make_Op_Shift_Left (Loc,
6019 Convert_To (Standard_Natural, Right_Opnd (Lop))));
6020 Analyze_And_Resolve (N, Typ);
6024 -- Do required fixup of universal fixed operation
6026 if Typ = Universal_Fixed then
6027 Fixup_Universal_Fixed_Operation (N);
6031 -- Multiplications with fixed-point results
6033 if Is_Fixed_Point_Type (Typ) then
6035 -- No special processing if Treat_Fixed_As_Integer is set,
6036 -- since from a semantic point of view such operations are
6037 -- simply integer operations and will be treated that way.
6039 if not Treat_Fixed_As_Integer (N) then
6041 -- Case of fixed * integer => fixed
6043 if Is_Integer_Type (Rtyp) then
6044 Expand_Multiply_Fixed_By_Integer_Giving_Fixed (N);
6046 -- Case of integer * fixed => fixed
6048 elsif Is_Integer_Type (Ltyp) then
6049 Expand_Multiply_Integer_By_Fixed_Giving_Fixed (N);
6051 -- Case of fixed * fixed => fixed
6054 Expand_Multiply_Fixed_By_Fixed_Giving_Fixed (N);
6058 -- Other cases of multiplication of fixed-point operands. Again
6059 -- we exclude the cases where Treat_Fixed_As_Integer flag is set.
6061 elsif (Is_Fixed_Point_Type (Ltyp) or else Is_Fixed_Point_Type (Rtyp))
6062 and then not Treat_Fixed_As_Integer (N)
6064 if Is_Integer_Type (Typ) then
6065 Expand_Multiply_Fixed_By_Fixed_Giving_Integer (N);
6067 pragma Assert (Is_Floating_Point_Type (Typ));
6068 Expand_Multiply_Fixed_By_Fixed_Giving_Float (N);
6071 -- Mixed-mode operations can appear in a non-static universal
6072 -- context, in which case the integer argument must be converted
6075 elsif Typ = Universal_Real
6076 and then Is_Integer_Type (Rtyp)
6078 Rewrite (Rop, Convert_To (Universal_Real, Relocate_Node (Rop)));
6080 Analyze_And_Resolve (Rop, Universal_Real);
6082 elsif Typ = Universal_Real
6083 and then Is_Integer_Type (Ltyp)
6085 Rewrite (Lop, Convert_To (Universal_Real, Relocate_Node (Lop)));
6087 Analyze_And_Resolve (Lop, Universal_Real);
6089 -- Non-fixed point cases, check software overflow checking required
6091 elsif Is_Signed_Integer_Type (Etype (N)) then
6092 Apply_Arithmetic_Overflow_Check (N);
6094 -- Deal with VAX float case
6096 elsif Vax_Float (Typ) then
6097 Expand_Vax_Arith (N);
6100 end Expand_N_Op_Multiply;
6102 --------------------
6103 -- Expand_N_Op_Ne --
6104 --------------------
6106 procedure Expand_N_Op_Ne (N : Node_Id) is
6107 Typ : constant Entity_Id := Etype (Left_Opnd (N));
6110 -- Case of elementary type with standard operator
6112 if Is_Elementary_Type (Typ)
6113 and then Sloc (Entity (N)) = Standard_Location
6115 Binary_Op_Validity_Checks (N);
6117 -- Boolean types (requiring handling of non-standard case)
6119 if Is_Boolean_Type (Typ) then
6120 Adjust_Condition (Left_Opnd (N));
6121 Adjust_Condition (Right_Opnd (N));
6122 Set_Etype (N, Standard_Boolean);
6123 Adjust_Result_Type (N, Typ);
6126 Rewrite_Comparison (N);
6128 -- If we still have comparison for Vax_Float, process it
6130 if Vax_Float (Typ) and then Nkind (N) in N_Op_Compare then
6131 Expand_Vax_Comparison (N);
6135 -- For all cases other than elementary types, we rewrite node as the
6136 -- negation of an equality operation, and reanalyze. The equality to be
6137 -- used is defined in the same scope and has the same signature. This
6138 -- signature must be set explicitly since in an instance it may not have
6139 -- the same visibility as in the generic unit. This avoids duplicating
6140 -- or factoring the complex code for record/array equality tests etc.
6144 Loc : constant Source_Ptr := Sloc (N);
6146 Ne : constant Entity_Id := Entity (N);
6149 Binary_Op_Validity_Checks (N);
6155 Left_Opnd => Left_Opnd (N),
6156 Right_Opnd => Right_Opnd (N)));
6157 Set_Paren_Count (Right_Opnd (Neg), 1);
6159 if Scope (Ne) /= Standard_Standard then
6160 Set_Entity (Right_Opnd (Neg), Corresponding_Equality (Ne));
6163 -- For navigation purposes, the inequality is treated as an
6164 -- implicit reference to the corresponding equality. Preserve the
6165 -- Comes_From_ source flag so that the proper Xref entry is
6168 Preserve_Comes_From_Source (Neg, N);
6169 Preserve_Comes_From_Source (Right_Opnd (Neg), N);
6171 Analyze_And_Resolve (N, Standard_Boolean);
6176 ---------------------
6177 -- Expand_N_Op_Not --
6178 ---------------------
6180 -- If the argument is other than a Boolean array type, there is no
6181 -- special expansion required.
6183 -- For the packed case, we call the special routine in Exp_Pakd, except
6184 -- that if the component size is greater than one, we use the standard
6185 -- routine generating a gruesome loop (it is so peculiar to have packed
6186 -- arrays with non-standard Boolean representations anyway, so it does
6187 -- not matter that we do not handle this case efficiently).
6189 -- For the unpacked case (and for the special packed case where we have
6190 -- non standard Booleans, as discussed above), we generate and insert
6191 -- into the tree the following function definition:
6193 -- function Nnnn (A : arr) is
6196 -- for J in a'range loop
6197 -- B (J) := not A (J);
6202 -- Here arr is the actual subtype of the parameter (and hence always
6203 -- constrained). Then we replace the not with a call to this function.
6205 procedure Expand_N_Op_Not (N : Node_Id) is
6206 Loc : constant Source_Ptr := Sloc (N);
6207 Typ : constant Entity_Id := Etype (N);
6216 Func_Name : Entity_Id;
6217 Loop_Statement : Node_Id;
6220 Unary_Op_Validity_Checks (N);
6222 -- For boolean operand, deal with non-standard booleans
6224 if Is_Boolean_Type (Typ) then
6225 Adjust_Condition (Right_Opnd (N));
6226 Set_Etype (N, Standard_Boolean);
6227 Adjust_Result_Type (N, Typ);
6231 -- Only array types need any other processing
6233 if not Is_Array_Type (Typ) then
6237 -- Case of array operand. If bit packed with a component size of 1,
6238 -- handle it in Exp_Pakd if the operand is known to be aligned.
6240 if Is_Bit_Packed_Array (Typ)
6241 and then Component_Size (Typ) = 1
6242 and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
6244 Expand_Packed_Not (N);
6248 -- Case of array operand which is not bit-packed. If the context is
6249 -- a safe assignment, call in-place operation, If context is a larger
6250 -- boolean expression in the context of a safe assignment, expansion is
6251 -- done by enclosing operation.
6253 Opnd := Relocate_Node (Right_Opnd (N));
6254 Convert_To_Actual_Subtype (Opnd);
6255 Arr := Etype (Opnd);
6256 Ensure_Defined (Arr, N);
6258 if Nkind (Parent (N)) = N_Assignment_Statement then
6259 if Safe_In_Place_Array_Op (Name (Parent (N)), N, Empty) then
6260 Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
6263 -- Special case the negation of a binary operation
6265 elsif (Nkind (Opnd) = N_Op_And
6266 or else Nkind (Opnd) = N_Op_Or
6267 or else Nkind (Opnd) = N_Op_Xor)
6268 and then Safe_In_Place_Array_Op
6269 (Name (Parent (N)), Left_Opnd (Opnd), Right_Opnd (Opnd))
6271 Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
6275 elsif Nkind (Parent (N)) in N_Binary_Op
6276 and then Nkind (Parent (Parent (N))) = N_Assignment_Statement
6279 Op1 : constant Node_Id := Left_Opnd (Parent (N));
6280 Op2 : constant Node_Id := Right_Opnd (Parent (N));
6281 Lhs : constant Node_Id := Name (Parent (Parent (N)));
6284 if Safe_In_Place_Array_Op (Lhs, Op1, Op2) then
6286 and then Nkind (Op2) = N_Op_Not
6288 -- (not A) op (not B) can be reduced to a single call
6293 and then Nkind (Parent (N)) = N_Op_Xor
6295 -- A xor (not B) can also be special-cased
6303 A := Make_Defining_Identifier (Loc, Name_uA);
6304 B := Make_Defining_Identifier (Loc, Name_uB);
6305 J := Make_Defining_Identifier (Loc, Name_uJ);
6308 Make_Indexed_Component (Loc,
6309 Prefix => New_Reference_To (A, Loc),
6310 Expressions => New_List (New_Reference_To (J, Loc)));
6313 Make_Indexed_Component (Loc,
6314 Prefix => New_Reference_To (B, Loc),
6315 Expressions => New_List (New_Reference_To (J, Loc)));
6318 Make_Implicit_Loop_Statement (N,
6319 Identifier => Empty,
6322 Make_Iteration_Scheme (Loc,
6323 Loop_Parameter_Specification =>
6324 Make_Loop_Parameter_Specification (Loc,
6325 Defining_Identifier => J,
6326 Discrete_Subtype_Definition =>
6327 Make_Attribute_Reference (Loc,
6328 Prefix => Make_Identifier (Loc, Chars (A)),
6329 Attribute_Name => Name_Range))),
6331 Statements => New_List (
6332 Make_Assignment_Statement (Loc,
6334 Expression => Make_Op_Not (Loc, A_J))));
6336 Func_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('N'));
6337 Set_Is_Inlined (Func_Name);
6340 Make_Subprogram_Body (Loc,
6342 Make_Function_Specification (Loc,
6343 Defining_Unit_Name => Func_Name,
6344 Parameter_Specifications => New_List (
6345 Make_Parameter_Specification (Loc,
6346 Defining_Identifier => A,
6347 Parameter_Type => New_Reference_To (Typ, Loc))),
6348 Result_Definition => New_Reference_To (Typ, Loc)),
6350 Declarations => New_List (
6351 Make_Object_Declaration (Loc,
6352 Defining_Identifier => B,
6353 Object_Definition => New_Reference_To (Arr, Loc))),
6355 Handled_Statement_Sequence =>
6356 Make_Handled_Sequence_Of_Statements (Loc,
6357 Statements => New_List (
6359 Make_Simple_Return_Statement (Loc,
6361 Make_Identifier (Loc, Chars (B)))))));
6364 Make_Function_Call (Loc,
6365 Name => New_Reference_To (Func_Name, Loc),
6366 Parameter_Associations => New_List (Opnd)));
6368 Analyze_And_Resolve (N, Typ);
6369 end Expand_N_Op_Not;
6371 --------------------
6372 -- Expand_N_Op_Or --
6373 --------------------
6375 procedure Expand_N_Op_Or (N : Node_Id) is
6376 Typ : constant Entity_Id := Etype (N);
6379 Binary_Op_Validity_Checks (N);
6381 if Is_Array_Type (Etype (N)) then
6382 Expand_Boolean_Operator (N);
6384 elsif Is_Boolean_Type (Etype (N)) then
6385 Adjust_Condition (Left_Opnd (N));
6386 Adjust_Condition (Right_Opnd (N));
6387 Set_Etype (N, Standard_Boolean);
6388 Adjust_Result_Type (N, Typ);
6392 ----------------------
6393 -- Expand_N_Op_Plus --
6394 ----------------------
6396 procedure Expand_N_Op_Plus (N : Node_Id) is
6398 Unary_Op_Validity_Checks (N);
6399 end Expand_N_Op_Plus;
6401 ---------------------
6402 -- Expand_N_Op_Rem --
6403 ---------------------
6405 procedure Expand_N_Op_Rem (N : Node_Id) is
6406 Loc : constant Source_Ptr := Sloc (N);
6407 Typ : constant Entity_Id := Etype (N);
6409 Left : constant Node_Id := Left_Opnd (N);
6410 Right : constant Node_Id := Right_Opnd (N);
6421 Binary_Op_Validity_Checks (N);
6423 if Is_Integer_Type (Etype (N)) then
6424 Apply_Divide_Check (N);
6427 -- Apply optimization x rem 1 = 0. We don't really need that with
6428 -- gcc, but it is useful with other back ends (e.g. AAMP), and is
6429 -- certainly harmless.
6431 if Is_Integer_Type (Etype (N))
6432 and then Compile_Time_Known_Value (Right)
6433 and then Expr_Value (Right) = Uint_1
6435 Rewrite (N, Make_Integer_Literal (Loc, 0));
6436 Analyze_And_Resolve (N, Typ);
6440 -- Deal with annoying case of largest negative number remainder
6441 -- minus one. Gigi does not handle this case correctly, because
6442 -- it generates a divide instruction which may trap in this case.
6444 -- In fact the check is quite easy, if the right operand is -1,
6445 -- then the remainder is always 0, and we can just ignore the
6446 -- left operand completely in this case.
6448 Determine_Range (Right, ROK, Rlo, Rhi);
6449 Determine_Range (Left, LOK, Llo, Lhi);
6451 -- The operand type may be private (e.g. in the expansion of an
6452 -- an intrinsic operation) so we must use the underlying type to
6453 -- get the bounds, and convert the literals explicitly.
6457 (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
6459 -- Now perform the test, generating code only if needed
6461 if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
6463 ((not LOK) or else (Llo = LLB))
6466 Make_Conditional_Expression (Loc,
6467 Expressions => New_List (
6469 Left_Opnd => Duplicate_Subexpr (Right),
6471 Unchecked_Convert_To (Typ,
6472 Make_Integer_Literal (Loc, -1))),
6474 Unchecked_Convert_To (Typ,
6475 Make_Integer_Literal (Loc, Uint_0)),
6477 Relocate_Node (N))));
6479 Set_Analyzed (Next (Next (First (Expressions (N)))));
6480 Analyze_And_Resolve (N, Typ);
6482 end Expand_N_Op_Rem;
6484 -----------------------------
6485 -- Expand_N_Op_Rotate_Left --
6486 -----------------------------
6488 procedure Expand_N_Op_Rotate_Left (N : Node_Id) is
6490 Binary_Op_Validity_Checks (N);
6491 end Expand_N_Op_Rotate_Left;
6493 ------------------------------
6494 -- Expand_N_Op_Rotate_Right --
6495 ------------------------------
6497 procedure Expand_N_Op_Rotate_Right (N : Node_Id) is
6499 Binary_Op_Validity_Checks (N);
6500 end Expand_N_Op_Rotate_Right;
6502 ----------------------------
6503 -- Expand_N_Op_Shift_Left --
6504 ----------------------------
6506 procedure Expand_N_Op_Shift_Left (N : Node_Id) is
6508 Binary_Op_Validity_Checks (N);
6509 end Expand_N_Op_Shift_Left;
6511 -----------------------------
6512 -- Expand_N_Op_Shift_Right --
6513 -----------------------------
6515 procedure Expand_N_Op_Shift_Right (N : Node_Id) is
6517 Binary_Op_Validity_Checks (N);
6518 end Expand_N_Op_Shift_Right;
6520 ----------------------------------------
6521 -- Expand_N_Op_Shift_Right_Arithmetic --
6522 ----------------------------------------
6524 procedure Expand_N_Op_Shift_Right_Arithmetic (N : Node_Id) is
6526 Binary_Op_Validity_Checks (N);
6527 end Expand_N_Op_Shift_Right_Arithmetic;
6529 --------------------------
6530 -- Expand_N_Op_Subtract --
6531 --------------------------
6533 procedure Expand_N_Op_Subtract (N : Node_Id) is
6534 Typ : constant Entity_Id := Etype (N);
6537 Binary_Op_Validity_Checks (N);
6539 -- N - 0 = N for integer types
6541 if Is_Integer_Type (Typ)
6542 and then Compile_Time_Known_Value (Right_Opnd (N))
6543 and then Expr_Value (Right_Opnd (N)) = 0
6545 Rewrite (N, Left_Opnd (N));
6549 -- Arithemtic overflow checks for signed integer/fixed point types
6551 if Is_Signed_Integer_Type (Typ)
6552 or else Is_Fixed_Point_Type (Typ)
6554 Apply_Arithmetic_Overflow_Check (N);
6556 -- Vax floating-point types case
6558 elsif Vax_Float (Typ) then
6559 Expand_Vax_Arith (N);
6561 end Expand_N_Op_Subtract;
6563 ---------------------
6564 -- Expand_N_Op_Xor --
6565 ---------------------
6567 procedure Expand_N_Op_Xor (N : Node_Id) is
6568 Typ : constant Entity_Id := Etype (N);
6571 Binary_Op_Validity_Checks (N);
6573 if Is_Array_Type (Etype (N)) then
6574 Expand_Boolean_Operator (N);
6576 elsif Is_Boolean_Type (Etype (N)) then
6577 Adjust_Condition (Left_Opnd (N));
6578 Adjust_Condition (Right_Opnd (N));
6579 Set_Etype (N, Standard_Boolean);
6580 Adjust_Result_Type (N, Typ);
6582 end Expand_N_Op_Xor;
6584 ----------------------
6585 -- Expand_N_Or_Else --
6586 ----------------------
6588 -- Expand into conditional expression if Actions present, and also
6589 -- deal with optimizing case of arguments being True or False.
6591 procedure Expand_N_Or_Else (N : Node_Id) is
6592 Loc : constant Source_Ptr := Sloc (N);
6593 Typ : constant Entity_Id := Etype (N);
6594 Left : constant Node_Id := Left_Opnd (N);
6595 Right : constant Node_Id := Right_Opnd (N);
6599 -- Deal with non-standard booleans
6601 if Is_Boolean_Type (Typ) then
6602 Adjust_Condition (Left);
6603 Adjust_Condition (Right);
6604 Set_Etype (N, Standard_Boolean);
6607 -- Check for cases of left argument is True or False
6609 if Nkind (Left) = N_Identifier then
6611 -- If left argument is False, change (False or else Right) to Right.
6612 -- Any actions associated with Right will be executed unconditionally
6613 -- and can thus be inserted into the tree unconditionally.
6615 if Entity (Left) = Standard_False then
6616 if Present (Actions (N)) then
6617 Insert_Actions (N, Actions (N));
6621 Adjust_Result_Type (N, Typ);
6624 -- If left argument is True, change (True and then Right) to
6625 -- True. In this case we can forget the actions associated with
6626 -- Right, since they will never be executed.
6628 elsif Entity (Left) = Standard_True then
6629 Kill_Dead_Code (Right);
6630 Kill_Dead_Code (Actions (N));
6631 Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
6632 Adjust_Result_Type (N, Typ);
6637 -- If Actions are present, we expand
6639 -- left or else right
6643 -- if left then True else right end
6645 -- with the actions becoming the Else_Actions of the conditional
6646 -- expression. This conditional expression is then further expanded
6647 -- (and will eventually disappear)
6649 if Present (Actions (N)) then
6650 Actlist := Actions (N);
6652 Make_Conditional_Expression (Loc,
6653 Expressions => New_List (
6655 New_Occurrence_Of (Standard_True, Loc),
6658 Set_Else_Actions (N, Actlist);
6659 Analyze_And_Resolve (N, Standard_Boolean);
6660 Adjust_Result_Type (N, Typ);
6664 -- No actions present, check for cases of right argument True/False
6666 if Nkind (Right) = N_Identifier then
6668 -- Change (Left or else False) to Left. Note that we know there
6669 -- are no actions associated with the True operand, since we
6670 -- just checked for this case above.
6672 if Entity (Right) = Standard_False then
6675 -- Change (Left or else True) to True, making sure to preserve
6676 -- any side effects associated with the Left operand.
6678 elsif Entity (Right) = Standard_True then
6679 Remove_Side_Effects (Left);
6681 (N, New_Occurrence_Of (Standard_True, Loc));
6685 Adjust_Result_Type (N, Typ);
6686 end Expand_N_Or_Else;
6688 -----------------------------------
6689 -- Expand_N_Qualified_Expression --
6690 -----------------------------------
6692 procedure Expand_N_Qualified_Expression (N : Node_Id) is
6693 Operand : constant Node_Id := Expression (N);
6694 Target_Type : constant Entity_Id := Entity (Subtype_Mark (N));
6697 -- Do validity check if validity checking operands
6699 if Validity_Checks_On
6700 and then Validity_Check_Operands
6702 Ensure_Valid (Operand);
6705 -- Apply possible constraint check
6707 Apply_Constraint_Check (Operand, Target_Type, No_Sliding => True);
6708 end Expand_N_Qualified_Expression;
6710 ---------------------------------
6711 -- Expand_N_Selected_Component --
6712 ---------------------------------
6714 -- If the selector is a discriminant of a concurrent object, rewrite the
6715 -- prefix to denote the corresponding record type.
6717 procedure Expand_N_Selected_Component (N : Node_Id) is
6718 Loc : constant Source_Ptr := Sloc (N);
6719 Par : constant Node_Id := Parent (N);
6720 P : constant Node_Id := Prefix (N);
6721 Ptyp : Entity_Id := Underlying_Type (Etype (P));
6726 function In_Left_Hand_Side (Comp : Node_Id) return Boolean;
6727 -- Gigi needs a temporary for prefixes that depend on a discriminant,
6728 -- unless the context of an assignment can provide size information.
6729 -- Don't we have a general routine that does this???
6731 -----------------------
6732 -- In_Left_Hand_Side --
6733 -----------------------
6735 function In_Left_Hand_Side (Comp : Node_Id) return Boolean is
6737 return (Nkind (Parent (Comp)) = N_Assignment_Statement
6738 and then Comp = Name (Parent (Comp)))
6739 or else (Present (Parent (Comp))
6740 and then Nkind (Parent (Comp)) in N_Subexpr
6741 and then In_Left_Hand_Side (Parent (Comp)));
6742 end In_Left_Hand_Side;
6744 -- Start of processing for Expand_N_Selected_Component
6747 -- Insert explicit dereference if required
6749 if Is_Access_Type (Ptyp) then
6750 Insert_Explicit_Dereference (P);
6751 Analyze_And_Resolve (P, Designated_Type (Ptyp));
6753 if Ekind (Etype (P)) = E_Private_Subtype
6754 and then Is_For_Access_Subtype (Etype (P))
6756 Set_Etype (P, Base_Type (Etype (P)));
6762 -- Deal with discriminant check required
6764 if Do_Discriminant_Check (N) then
6766 -- Present the discrminant checking function to the backend,
6767 -- so that it can inline the call to the function.
6770 (Discriminant_Checking_Func
6771 (Original_Record_Component (Entity (Selector_Name (N)))));
6773 -- Now reset the flag and generate the call
6775 Set_Do_Discriminant_Check (N, False);
6776 Generate_Discriminant_Check (N);
6779 -- Gigi cannot handle unchecked conversions that are the prefix of a
6780 -- selected component with discriminants. This must be checked during
6781 -- expansion, because during analysis the type of the selector is not
6782 -- known at the point the prefix is analyzed. If the conversion is the
6783 -- target of an assignment, then we cannot force the evaluation.
6785 if Nkind (Prefix (N)) = N_Unchecked_Type_Conversion
6786 and then Has_Discriminants (Etype (N))
6787 and then not In_Left_Hand_Side (N)
6789 Force_Evaluation (Prefix (N));
6792 -- Remaining processing applies only if selector is a discriminant
6794 if Ekind (Entity (Selector_Name (N))) = E_Discriminant then
6796 -- If the selector is a discriminant of a constrained record type,
6797 -- we may be able to rewrite the expression with the actual value
6798 -- of the discriminant, a useful optimization in some cases.
6800 if Is_Record_Type (Ptyp)
6801 and then Has_Discriminants (Ptyp)
6802 and then Is_Constrained (Ptyp)
6804 -- Do this optimization for discrete types only, and not for
6805 -- access types (access discriminants get us into trouble!)
6807 if not Is_Discrete_Type (Etype (N)) then
6810 -- Don't do this on the left hand of an assignment statement.
6811 -- Normally one would think that references like this would
6812 -- not occur, but they do in generated code, and mean that
6813 -- we really do want to assign the discriminant!
6815 elsif Nkind (Par) = N_Assignment_Statement
6816 and then Name (Par) = N
6820 -- Don't do this optimization for the prefix of an attribute
6821 -- or the operand of an object renaming declaration since these
6822 -- are contexts where we do not want the value anyway.
6824 elsif (Nkind (Par) = N_Attribute_Reference
6825 and then Prefix (Par) = N)
6826 or else Is_Renamed_Object (N)
6830 -- Don't do this optimization if we are within the code for a
6831 -- discriminant check, since the whole point of such a check may
6832 -- be to verify the condition on which the code below depends!
6834 elsif Is_In_Discriminant_Check (N) then
6837 -- Green light to see if we can do the optimization. There is
6838 -- still one condition that inhibits the optimization below
6839 -- but now is the time to check the particular discriminant.
6842 -- Loop through discriminants to find the matching
6843 -- discriminant constraint to see if we can copy it.
6845 Disc := First_Discriminant (Ptyp);
6846 Dcon := First_Elmt (Discriminant_Constraint (Ptyp));
6847 Discr_Loop : while Present (Dcon) loop
6849 -- Check if this is the matching discriminant
6851 if Disc = Entity (Selector_Name (N)) then
6853 -- Here we have the matching discriminant. Check for
6854 -- the case of a discriminant of a component that is
6855 -- constrained by an outer discriminant, which cannot
6856 -- be optimized away.
6859 Denotes_Discriminant
6860 (Node (Dcon), Check_Concurrent => True)
6864 -- In the context of a case statement, the expression
6865 -- may have the base type of the discriminant, and we
6866 -- need to preserve the constraint to avoid spurious
6867 -- errors on missing cases.
6869 elsif Nkind (Parent (N)) = N_Case_Statement
6870 and then Etype (Node (Dcon)) /= Etype (Disc)
6873 Make_Qualified_Expression (Loc,
6875 New_Occurrence_Of (Etype (Disc), Loc),
6877 New_Copy_Tree (Node (Dcon))));
6878 Analyze_And_Resolve (N, Etype (Disc));
6880 -- In case that comes out as a static expression,
6881 -- reset it (a selected component is never static).
6883 Set_Is_Static_Expression (N, False);
6886 -- Otherwise we can just copy the constraint, but the
6887 -- result is certainly not static! In some cases the
6888 -- discriminant constraint has been analyzed in the
6889 -- context of the original subtype indication, but for
6890 -- itypes the constraint might not have been analyzed
6891 -- yet, and this must be done now.
6894 Rewrite (N, New_Copy_Tree (Node (Dcon)));
6895 Analyze_And_Resolve (N);
6896 Set_Is_Static_Expression (N, False);
6902 Next_Discriminant (Disc);
6903 end loop Discr_Loop;
6905 -- Note: the above loop should always find a matching
6906 -- discriminant, but if it does not, we just missed an
6907 -- optimization due to some glitch (perhaps a previous
6908 -- error), so ignore.
6913 -- The only remaining processing is in the case of a discriminant of
6914 -- a concurrent object, where we rewrite the prefix to denote the
6915 -- corresponding record type. If the type is derived and has renamed
6916 -- discriminants, use corresponding discriminant, which is the one
6917 -- that appears in the corresponding record.
6919 if not Is_Concurrent_Type (Ptyp) then
6923 Disc := Entity (Selector_Name (N));
6925 if Is_Derived_Type (Ptyp)
6926 and then Present (Corresponding_Discriminant (Disc))
6928 Disc := Corresponding_Discriminant (Disc);
6932 Make_Selected_Component (Loc,
6934 Unchecked_Convert_To (Corresponding_Record_Type (Ptyp),
6936 Selector_Name => Make_Identifier (Loc, Chars (Disc)));
6941 end Expand_N_Selected_Component;
6943 --------------------
6944 -- Expand_N_Slice --
6945 --------------------
6947 procedure Expand_N_Slice (N : Node_Id) is
6948 Loc : constant Source_Ptr := Sloc (N);
6949 Typ : constant Entity_Id := Etype (N);
6950 Pfx : constant Node_Id := Prefix (N);
6951 Ptp : Entity_Id := Etype (Pfx);
6953 function Is_Procedure_Actual (N : Node_Id) return Boolean;
6954 -- Check whether the argument is an actual for a procedure call,
6955 -- in which case the expansion of a bit-packed slice is deferred
6956 -- until the call itself is expanded. The reason this is required
6957 -- is that we might have an IN OUT or OUT parameter, and the copy out
6958 -- is essential, and that copy out would be missed if we created a
6959 -- temporary here in Expand_N_Slice. Note that we don't bother
6960 -- to test specifically for an IN OUT or OUT mode parameter, since it
6961 -- is a bit tricky to do, and it is harmless to defer expansion
6962 -- in the IN case, since the call processing will still generate the
6963 -- appropriate copy in operation, which will take care of the slice.
6965 procedure Make_Temporary;
6966 -- Create a named variable for the value of the slice, in
6967 -- cases where the back-end cannot handle it properly, e.g.
6968 -- when packed types or unaligned slices are involved.
6970 -------------------------
6971 -- Is_Procedure_Actual --
6972 -------------------------
6974 function Is_Procedure_Actual (N : Node_Id) return Boolean is
6975 Par : Node_Id := Parent (N);
6979 -- If our parent is a procedure call we can return
6981 if Nkind (Par) = N_Procedure_Call_Statement then
6984 -- If our parent is a type conversion, keep climbing the
6985 -- tree, since a type conversion can be a procedure actual.
6986 -- Also keep climbing if parameter association or a qualified
6987 -- expression, since these are additional cases that do can
6988 -- appear on procedure actuals.
6990 elsif Nkind (Par) = N_Type_Conversion
6991 or else Nkind (Par) = N_Parameter_Association
6992 or else Nkind (Par) = N_Qualified_Expression
6994 Par := Parent (Par);
6996 -- Any other case is not what we are looking for
7002 end Is_Procedure_Actual;
7004 --------------------
7005 -- Make_Temporary --
7006 --------------------
7008 procedure Make_Temporary is
7010 Ent : constant Entity_Id :=
7011 Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
7014 Make_Object_Declaration (Loc,
7015 Defining_Identifier => Ent,
7016 Object_Definition => New_Occurrence_Of (Typ, Loc));
7018 Set_No_Initialization (Decl);
7020 Insert_Actions (N, New_List (
7022 Make_Assignment_Statement (Loc,
7023 Name => New_Occurrence_Of (Ent, Loc),
7024 Expression => Relocate_Node (N))));
7026 Rewrite (N, New_Occurrence_Of (Ent, Loc));
7027 Analyze_And_Resolve (N, Typ);
7030 -- Start of processing for Expand_N_Slice
7033 -- Special handling for access types
7035 if Is_Access_Type (Ptp) then
7037 Ptp := Designated_Type (Ptp);
7040 Make_Explicit_Dereference (Sloc (N),
7041 Prefix => Relocate_Node (Pfx)));
7043 Analyze_And_Resolve (Pfx, Ptp);
7046 -- Range checks are potentially also needed for cases involving
7047 -- a slice indexed by a subtype indication, but Do_Range_Check
7048 -- can currently only be set for expressions ???
7050 if not Index_Checks_Suppressed (Ptp)
7051 and then (not Is_Entity_Name (Pfx)
7052 or else not Index_Checks_Suppressed (Entity (Pfx)))
7053 and then Nkind (Discrete_Range (N)) /= N_Subtype_Indication
7055 -- Do not enable range check to nodes associated with the frontend
7056 -- expansion of the dispatch table. We first check if Ada.Tags is
7057 -- already loaded to avoid the addition of an undesired dependence
7058 -- on such run-time unit.
7063 (RTU_Loaded (Ada_Tags)
7064 and then Nkind (Prefix (N)) = N_Selected_Component
7065 and then Present (Entity (Selector_Name (Prefix (N))))
7066 and then Entity (Selector_Name (Prefix (N))) =
7067 RTE_Record_Component (RE_Prims_Ptr)))
7069 Enable_Range_Check (Discrete_Range (N));
7072 -- The remaining case to be handled is packed slices. We can leave
7073 -- packed slices as they are in the following situations:
7075 -- 1. Right or left side of an assignment (we can handle this
7076 -- situation correctly in the assignment statement expansion).
7078 -- 2. Prefix of indexed component (the slide is optimized away
7079 -- in this case, see the start of Expand_N_Slice.)
7081 -- 3. Object renaming declaration, since we want the name of
7082 -- the slice, not the value.
7084 -- 4. Argument to procedure call, since copy-in/copy-out handling
7085 -- may be required, and this is handled in the expansion of
7088 -- 5. Prefix of an address attribute (this is an error which
7089 -- is caught elsewhere, and the expansion would intefere
7090 -- with generating the error message).
7092 if not Is_Packed (Typ) then
7094 -- Apply transformation for actuals of a function call,
7095 -- where Expand_Actuals is not used.
7097 if Nkind (Parent (N)) = N_Function_Call
7098 and then Is_Possibly_Unaligned_Slice (N)
7103 elsif Nkind (Parent (N)) = N_Assignment_Statement
7104 or else (Nkind (Parent (Parent (N))) = N_Assignment_Statement
7105 and then Parent (N) = Name (Parent (Parent (N))))
7109 elsif Nkind (Parent (N)) = N_Indexed_Component
7110 or else Is_Renamed_Object (N)
7111 or else Is_Procedure_Actual (N)
7115 elsif Nkind (Parent (N)) = N_Attribute_Reference
7116 and then Attribute_Name (Parent (N)) = Name_Address
7125 ------------------------------
7126 -- Expand_N_Type_Conversion --
7127 ------------------------------
7129 procedure Expand_N_Type_Conversion (N : Node_Id) is
7130 Loc : constant Source_Ptr := Sloc (N);
7131 Operand : constant Node_Id := Expression (N);
7132 Target_Type : constant Entity_Id := Etype (N);
7133 Operand_Type : Entity_Id := Etype (Operand);
7135 procedure Handle_Changed_Representation;
7136 -- This is called in the case of record and array type conversions
7137 -- to see if there is a change of representation to be handled.
7138 -- Change of representation is actually handled at the assignment
7139 -- statement level, and what this procedure does is rewrite node N
7140 -- conversion as an assignment to temporary. If there is no change
7141 -- of representation, then the conversion node is unchanged.
7143 procedure Real_Range_Check;
7144 -- Handles generation of range check for real target value
7146 -----------------------------------
7147 -- Handle_Changed_Representation --
7148 -----------------------------------
7150 procedure Handle_Changed_Representation is
7159 -- Nothing else to do if no change of representation
7161 if Same_Representation (Operand_Type, Target_Type) then
7164 -- The real change of representation work is done by the assignment
7165 -- statement processing. So if this type conversion is appearing as
7166 -- the expression of an assignment statement, nothing needs to be
7167 -- done to the conversion.
7169 elsif Nkind (Parent (N)) = N_Assignment_Statement then
7172 -- Otherwise we need to generate a temporary variable, and do the
7173 -- change of representation assignment into that temporary variable.
7174 -- The conversion is then replaced by a reference to this variable.
7179 -- If type is unconstrained we have to add a constraint,
7180 -- copied from the actual value of the left hand side.
7182 if not Is_Constrained (Target_Type) then
7183 if Has_Discriminants (Operand_Type) then
7184 Disc := First_Discriminant (Operand_Type);
7186 if Disc /= First_Stored_Discriminant (Operand_Type) then
7187 Disc := First_Stored_Discriminant (Operand_Type);
7191 while Present (Disc) loop
7193 Make_Selected_Component (Loc,
7194 Prefix => Duplicate_Subexpr_Move_Checks (Operand),
7196 Make_Identifier (Loc, Chars (Disc))));
7197 Next_Discriminant (Disc);
7200 elsif Is_Array_Type (Operand_Type) then
7201 N_Ix := First_Index (Target_Type);
7204 for J in 1 .. Number_Dimensions (Operand_Type) loop
7206 -- We convert the bounds explicitly. We use an unchecked
7207 -- conversion because bounds checks are done elsewhere.
7212 Unchecked_Convert_To (Etype (N_Ix),
7213 Make_Attribute_Reference (Loc,
7215 Duplicate_Subexpr_No_Checks
7216 (Operand, Name_Req => True),
7217 Attribute_Name => Name_First,
7218 Expressions => New_List (
7219 Make_Integer_Literal (Loc, J)))),
7222 Unchecked_Convert_To (Etype (N_Ix),
7223 Make_Attribute_Reference (Loc,
7225 Duplicate_Subexpr_No_Checks
7226 (Operand, Name_Req => True),
7227 Attribute_Name => Name_Last,
7228 Expressions => New_List (
7229 Make_Integer_Literal (Loc, J))))));
7236 Odef := New_Occurrence_Of (Target_Type, Loc);
7238 if Present (Cons) then
7240 Make_Subtype_Indication (Loc,
7241 Subtype_Mark => Odef,
7243 Make_Index_Or_Discriminant_Constraint (Loc,
7244 Constraints => Cons));
7247 Temp := Make_Defining_Identifier (Loc, New_Internal_Name ('C'));
7249 Make_Object_Declaration (Loc,
7250 Defining_Identifier => Temp,
7251 Object_Definition => Odef);
7253 Set_No_Initialization (Decl, True);
7255 -- Insert required actions. It is essential to suppress checks
7256 -- since we have suppressed default initialization, which means
7257 -- that the variable we create may have no discriminants.
7262 Make_Assignment_Statement (Loc,
7263 Name => New_Occurrence_Of (Temp, Loc),
7264 Expression => Relocate_Node (N))),
7265 Suppress => All_Checks);
7267 Rewrite (N, New_Occurrence_Of (Temp, Loc));
7270 end Handle_Changed_Representation;
7272 ----------------------
7273 -- Real_Range_Check --
7274 ----------------------
7276 -- Case of conversions to floating-point or fixed-point. If range
7277 -- checks are enabled and the target type has a range constraint,
7284 -- Tnn : typ'Base := typ'Base (x);
7285 -- [constraint_error when Tnn < typ'First or else Tnn > typ'Last]
7288 -- This is necessary when there is a conversion of integer to float
7289 -- or to fixed-point to ensure that the correct checks are made. It
7290 -- is not necessary for float to float where it is enough to simply
7291 -- set the Do_Range_Check flag.
7293 procedure Real_Range_Check is
7294 Btyp : constant Entity_Id := Base_Type (Target_Type);
7295 Lo : constant Node_Id := Type_Low_Bound (Target_Type);
7296 Hi : constant Node_Id := Type_High_Bound (Target_Type);
7297 Xtyp : constant Entity_Id := Etype (Operand);
7302 -- Nothing to do if conversion was rewritten
7304 if Nkind (N) /= N_Type_Conversion then
7308 -- Nothing to do if range checks suppressed, or target has the
7309 -- same range as the base type (or is the base type).
7311 if Range_Checks_Suppressed (Target_Type)
7312 or else (Lo = Type_Low_Bound (Btyp)
7314 Hi = Type_High_Bound (Btyp))
7319 -- Nothing to do if expression is an entity on which checks
7320 -- have been suppressed.
7322 if Is_Entity_Name (Operand)
7323 and then Range_Checks_Suppressed (Entity (Operand))
7328 -- Nothing to do if bounds are all static and we can tell that
7329 -- the expression is within the bounds of the target. Note that
7330 -- if the operand is of an unconstrained floating-point type,
7331 -- then we do not trust it to be in range (might be infinite)
7334 S_Lo : constant Node_Id := Type_Low_Bound (Xtyp);
7335 S_Hi : constant Node_Id := Type_High_Bound (Xtyp);
7338 if (not Is_Floating_Point_Type (Xtyp)
7339 or else Is_Constrained (Xtyp))
7340 and then Compile_Time_Known_Value (S_Lo)
7341 and then Compile_Time_Known_Value (S_Hi)
7342 and then Compile_Time_Known_Value (Hi)
7343 and then Compile_Time_Known_Value (Lo)
7346 D_Lov : constant Ureal := Expr_Value_R (Lo);
7347 D_Hiv : constant Ureal := Expr_Value_R (Hi);
7352 if Is_Real_Type (Xtyp) then
7353 S_Lov := Expr_Value_R (S_Lo);
7354 S_Hiv := Expr_Value_R (S_Hi);
7356 S_Lov := UR_From_Uint (Expr_Value (S_Lo));
7357 S_Hiv := UR_From_Uint (Expr_Value (S_Hi));
7361 and then S_Lov >= D_Lov
7362 and then S_Hiv <= D_Hiv
7364 Set_Do_Range_Check (Operand, False);
7371 -- For float to float conversions, we are done
7373 if Is_Floating_Point_Type (Xtyp)
7375 Is_Floating_Point_Type (Btyp)
7380 -- Otherwise rewrite the conversion as described above
7382 Conv := Relocate_Node (N);
7384 (Subtype_Mark (Conv), New_Occurrence_Of (Btyp, Loc));
7385 Set_Etype (Conv, Btyp);
7387 -- Enable overflow except for case of integer to float conversions,
7388 -- where it is never required, since we can never have overflow in
7391 if not Is_Integer_Type (Etype (Operand)) then
7392 Enable_Overflow_Check (Conv);
7396 Make_Defining_Identifier (Loc,
7397 Chars => New_Internal_Name ('T'));
7399 Insert_Actions (N, New_List (
7400 Make_Object_Declaration (Loc,
7401 Defining_Identifier => Tnn,
7402 Object_Definition => New_Occurrence_Of (Btyp, Loc),
7403 Expression => Conv),
7405 Make_Raise_Constraint_Error (Loc,
7410 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
7412 Make_Attribute_Reference (Loc,
7413 Attribute_Name => Name_First,
7415 New_Occurrence_Of (Target_Type, Loc))),
7419 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
7421 Make_Attribute_Reference (Loc,
7422 Attribute_Name => Name_Last,
7424 New_Occurrence_Of (Target_Type, Loc)))),
7425 Reason => CE_Range_Check_Failed)));
7427 Rewrite (N, New_Occurrence_Of (Tnn, Loc));
7428 Analyze_And_Resolve (N, Btyp);
7429 end Real_Range_Check;
7431 -- Start of processing for Expand_N_Type_Conversion
7434 -- Nothing at all to do if conversion is to the identical type
7435 -- so remove the conversion completely, it is useless.
7437 if Operand_Type = Target_Type then
7438 Rewrite (N, Relocate_Node (Operand));
7442 -- Nothing to do if this is the second argument of read. This
7443 -- is a "backwards" conversion that will be handled by the
7444 -- specialized code in attribute processing.
7446 if Nkind (Parent (N)) = N_Attribute_Reference
7447 and then Attribute_Name (Parent (N)) = Name_Read
7448 and then Next (First (Expressions (Parent (N)))) = N
7453 -- Here if we may need to expand conversion
7455 -- Do validity check if validity checking operands
7457 if Validity_Checks_On
7458 and then Validity_Check_Operands
7460 Ensure_Valid (Operand);
7463 -- Special case of converting from non-standard boolean type
7465 if Is_Boolean_Type (Operand_Type)
7466 and then (Nonzero_Is_True (Operand_Type))
7468 Adjust_Condition (Operand);
7469 Set_Etype (Operand, Standard_Boolean);
7470 Operand_Type := Standard_Boolean;
7473 -- Case of converting to an access type
7475 if Is_Access_Type (Target_Type) then
7477 -- Apply an accessibility check when the conversion operand is an
7478 -- access parameter (or a renaming thereof), unless conversion was
7479 -- expanded from an unchecked or unrestricted access attribute. Note
7480 -- that other checks may still need to be applied below (such as
7481 -- tagged type checks).
7483 if Is_Entity_Name (Operand)
7485 (Is_Formal (Entity (Operand))
7487 (Present (Renamed_Object (Entity (Operand)))
7488 and then Is_Entity_Name (Renamed_Object (Entity (Operand)))
7490 (Entity (Renamed_Object (Entity (Operand))))))
7491 and then Ekind (Etype (Operand)) = E_Anonymous_Access_Type
7492 and then (Nkind (Original_Node (N)) /= N_Attribute_Reference
7493 or else Attribute_Name (Original_Node (N)) = Name_Access)
7495 Apply_Accessibility_Check (Operand, Target_Type);
7497 -- If the level of the operand type is statically deeper
7498 -- then the level of the target type, then force Program_Error.
7499 -- Note that this can only occur for cases where the attribute
7500 -- is within the body of an instantiation (otherwise the
7501 -- conversion will already have been rejected as illegal).
7502 -- Note: warnings are issued by the analyzer for the instance
7505 elsif In_Instance_Body
7506 and then Type_Access_Level (Operand_Type) >
7507 Type_Access_Level (Target_Type)
7510 Make_Raise_Program_Error (Sloc (N),
7511 Reason => PE_Accessibility_Check_Failed));
7512 Set_Etype (N, Target_Type);
7514 -- When the operand is a selected access discriminant
7515 -- the check needs to be made against the level of the
7516 -- object denoted by the prefix of the selected name.
7517 -- Force Program_Error for this case as well (this
7518 -- accessibility violation can only happen if within
7519 -- the body of an instantiation).
7521 elsif In_Instance_Body
7522 and then Ekind (Operand_Type) = E_Anonymous_Access_Type
7523 and then Nkind (Operand) = N_Selected_Component
7524 and then Object_Access_Level (Operand) >
7525 Type_Access_Level (Target_Type)
7528 Make_Raise_Program_Error (Sloc (N),
7529 Reason => PE_Accessibility_Check_Failed));
7530 Set_Etype (N, Target_Type);
7534 -- Case of conversions of tagged types and access to tagged types
7536 -- When needed, that is to say when the expression is class-wide,
7537 -- Add runtime a tag check for (strict) downward conversion by using
7538 -- the membership test, generating:
7540 -- [constraint_error when Operand not in Target_Type'Class]
7542 -- or in the access type case
7544 -- [constraint_error
7545 -- when Operand /= null
7546 -- and then Operand.all not in
7547 -- Designated_Type (Target_Type)'Class]
7549 if (Is_Access_Type (Target_Type)
7550 and then Is_Tagged_Type (Designated_Type (Target_Type)))
7551 or else Is_Tagged_Type (Target_Type)
7553 -- Do not do any expansion in the access type case if the
7554 -- parent is a renaming, since this is an error situation
7555 -- which will be caught by Sem_Ch8, and the expansion can
7556 -- intefere with this error check.
7558 if Is_Access_Type (Target_Type)
7559 and then Is_Renamed_Object (N)
7564 -- Otherwise, proceed with processing tagged conversion
7567 Actual_Operand_Type : Entity_Id;
7568 Actual_Target_Type : Entity_Id;
7573 if Is_Access_Type (Target_Type) then
7574 Actual_Operand_Type := Designated_Type (Operand_Type);
7575 Actual_Target_Type := Designated_Type (Target_Type);
7578 Actual_Operand_Type := Operand_Type;
7579 Actual_Target_Type := Target_Type;
7582 -- Ada 2005 (AI-251): Handle interface type conversion
7584 if Is_Interface (Actual_Operand_Type) then
7585 Expand_Interface_Conversion (N, Is_Static => False);
7589 if Is_Class_Wide_Type (Actual_Operand_Type)
7590 and then Root_Type (Actual_Operand_Type) /= Actual_Target_Type
7591 and then Is_Ancestor
7592 (Root_Type (Actual_Operand_Type),
7594 and then not Tag_Checks_Suppressed (Actual_Target_Type)
7596 -- The conversion is valid for any descendant of the
7599 Actual_Target_Type := Class_Wide_Type (Actual_Target_Type);
7601 if Is_Access_Type (Target_Type) then
7606 Left_Opnd => Duplicate_Subexpr_No_Checks (Operand),
7607 Right_Opnd => Make_Null (Loc)),
7612 Make_Explicit_Dereference (Loc,
7614 Duplicate_Subexpr_No_Checks (Operand)),
7616 New_Reference_To (Actual_Target_Type, Loc)));
7621 Left_Opnd => Duplicate_Subexpr_No_Checks (Operand),
7623 New_Reference_To (Actual_Target_Type, Loc));
7627 Make_Raise_Constraint_Error (Loc,
7629 Reason => CE_Tag_Check_Failed));
7635 Make_Unchecked_Type_Conversion (Loc,
7636 Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
7637 Expression => Relocate_Node (Expression (N)));
7639 Analyze_And_Resolve (N, Target_Type);
7644 -- Case of other access type conversions
7646 elsif Is_Access_Type (Target_Type) then
7647 Apply_Constraint_Check (Operand, Target_Type);
7649 -- Case of conversions from a fixed-point type
7651 -- These conversions require special expansion and processing, found
7652 -- in the Exp_Fixd package. We ignore cases where Conversion_OK is
7653 -- set, since from a semantic point of view, these are simple integer
7654 -- conversions, which do not need further processing.
7656 elsif Is_Fixed_Point_Type (Operand_Type)
7657 and then not Conversion_OK (N)
7659 -- We should never see universal fixed at this case, since the
7660 -- expansion of the constituent divide or multiply should have
7661 -- eliminated the explicit mention of universal fixed.
7663 pragma Assert (Operand_Type /= Universal_Fixed);
7665 -- Check for special case of the conversion to universal real
7666 -- that occurs as a result of the use of a round attribute.
7667 -- In this case, the real type for the conversion is taken
7668 -- from the target type of the Round attribute and the
7669 -- result must be marked as rounded.
7671 if Target_Type = Universal_Real
7672 and then Nkind (Parent (N)) = N_Attribute_Reference
7673 and then Attribute_Name (Parent (N)) = Name_Round
7675 Set_Rounded_Result (N);
7676 Set_Etype (N, Etype (Parent (N)));
7679 -- Otherwise do correct fixed-conversion, but skip these if the
7680 -- Conversion_OK flag is set, because from a semantic point of
7681 -- view these are simple integer conversions needing no further
7682 -- processing (the backend will simply treat them as integers)
7684 if not Conversion_OK (N) then
7685 if Is_Fixed_Point_Type (Etype (N)) then
7686 Expand_Convert_Fixed_To_Fixed (N);
7689 elsif Is_Integer_Type (Etype (N)) then
7690 Expand_Convert_Fixed_To_Integer (N);
7693 pragma Assert (Is_Floating_Point_Type (Etype (N)));
7694 Expand_Convert_Fixed_To_Float (N);
7699 -- Case of conversions to a fixed-point type
7701 -- These conversions require special expansion and processing, found
7702 -- in the Exp_Fixd package. Again, ignore cases where Conversion_OK
7703 -- is set, since from a semantic point of view, these are simple
7704 -- integer conversions, which do not need further processing.
7706 elsif Is_Fixed_Point_Type (Target_Type)
7707 and then not Conversion_OK (N)
7709 if Is_Integer_Type (Operand_Type) then
7710 Expand_Convert_Integer_To_Fixed (N);
7713 pragma Assert (Is_Floating_Point_Type (Operand_Type));
7714 Expand_Convert_Float_To_Fixed (N);
7718 -- Case of float-to-integer conversions
7720 -- We also handle float-to-fixed conversions with Conversion_OK set
7721 -- since semantically the fixed-point target is treated as though it
7722 -- were an integer in such cases.
7724 elsif Is_Floating_Point_Type (Operand_Type)
7726 (Is_Integer_Type (Target_Type)
7728 (Is_Fixed_Point_Type (Target_Type) and then Conversion_OK (N)))
7730 -- One more check here, gcc is still not able to do conversions of
7731 -- this type with proper overflow checking, and so gigi is doing an
7732 -- approximation of what is required by doing floating-point compares
7733 -- with the end-point. But that can lose precision in some cases, and
7734 -- give a wrong result. Converting the operand to Universal_Real is
7735 -- helpful, but still does not catch all cases with 64-bit integers
7736 -- on targets with only 64-bit floats
7738 -- The above comment seems obsoleted by Apply_Float_Conversion_Check
7739 -- Can this code be removed ???
7741 if Do_Range_Check (Operand) then
7743 Make_Type_Conversion (Loc,
7745 New_Occurrence_Of (Universal_Real, Loc),
7747 Relocate_Node (Operand)));
7749 Set_Etype (Operand, Universal_Real);
7750 Enable_Range_Check (Operand);
7751 Set_Do_Range_Check (Expression (Operand), False);
7754 -- Case of array conversions
7756 -- Expansion of array conversions, add required length/range checks
7757 -- but only do this if there is no change of representation. For
7758 -- handling of this case, see Handle_Changed_Representation.
7760 elsif Is_Array_Type (Target_Type) then
7762 if Is_Constrained (Target_Type) then
7763 Apply_Length_Check (Operand, Target_Type);
7765 Apply_Range_Check (Operand, Target_Type);
7768 Handle_Changed_Representation;
7770 -- Case of conversions of discriminated types
7772 -- Add required discriminant checks if target is constrained. Again
7773 -- this change is skipped if we have a change of representation.
7775 elsif Has_Discriminants (Target_Type)
7776 and then Is_Constrained (Target_Type)
7778 Apply_Discriminant_Check (Operand, Target_Type);
7779 Handle_Changed_Representation;
7781 -- Case of all other record conversions. The only processing required
7782 -- is to check for a change of representation requiring the special
7783 -- assignment processing.
7785 elsif Is_Record_Type (Target_Type) then
7787 -- Ada 2005 (AI-216): Program_Error is raised when converting from
7788 -- a derived Unchecked_Union type to an unconstrained non-Unchecked_
7789 -- Union type if the operand lacks inferable discriminants.
7791 if Is_Derived_Type (Operand_Type)
7792 and then Is_Unchecked_Union (Base_Type (Operand_Type))
7793 and then not Is_Constrained (Target_Type)
7794 and then not Is_Unchecked_Union (Base_Type (Target_Type))
7795 and then not Has_Inferable_Discriminants (Operand)
7797 -- To prevent Gigi from generating illegal code, we make a
7798 -- Program_Error node, but we give it the target type of the
7802 PE : constant Node_Id := Make_Raise_Program_Error (Loc,
7803 Reason => PE_Unchecked_Union_Restriction);
7806 Set_Etype (PE, Target_Type);
7811 Handle_Changed_Representation;
7814 -- Case of conversions of enumeration types
7816 elsif Is_Enumeration_Type (Target_Type) then
7818 -- Special processing is required if there is a change of
7819 -- representation (from enumeration representation clauses)
7821 if not Same_Representation (Target_Type, Operand_Type) then
7823 -- Convert: x(y) to x'val (ytyp'val (y))
7826 Make_Attribute_Reference (Loc,
7827 Prefix => New_Occurrence_Of (Target_Type, Loc),
7828 Attribute_Name => Name_Val,
7829 Expressions => New_List (
7830 Make_Attribute_Reference (Loc,
7831 Prefix => New_Occurrence_Of (Operand_Type, Loc),
7832 Attribute_Name => Name_Pos,
7833 Expressions => New_List (Operand)))));
7835 Analyze_And_Resolve (N, Target_Type);
7838 -- Case of conversions to floating-point
7840 elsif Is_Floating_Point_Type (Target_Type) then
7844 -- At this stage, either the conversion node has been transformed
7845 -- into some other equivalent expression, or left as a conversion
7846 -- that can be handled by Gigi. The conversions that Gigi can handle
7847 -- are the following:
7849 -- Conversions with no change of representation or type
7851 -- Numeric conversions involving integer values, floating-point
7852 -- values, and fixed-point values. Fixed-point values are allowed
7853 -- only if Conversion_OK is set, i.e. if the fixed-point values
7854 -- are to be treated as integers.
7856 -- No other conversions should be passed to Gigi
7858 -- Check: are these rules stated in sinfo??? if so, why restate here???
7860 -- The only remaining step is to generate a range check if we still
7861 -- have a type conversion at this stage and Do_Range_Check is set.
7862 -- For now we do this only for conversions of discrete types.
7864 if Nkind (N) = N_Type_Conversion
7865 and then Is_Discrete_Type (Etype (N))
7868 Expr : constant Node_Id := Expression (N);
7873 if Do_Range_Check (Expr)
7874 and then Is_Discrete_Type (Etype (Expr))
7876 Set_Do_Range_Check (Expr, False);
7878 -- Before we do a range check, we have to deal with treating
7879 -- a fixed-point operand as an integer. The way we do this
7880 -- is simply to do an unchecked conversion to an appropriate
7881 -- integer type large enough to hold the result.
7883 -- This code is not active yet, because we are only dealing
7884 -- with discrete types so far ???
7886 if Nkind (Expr) in N_Has_Treat_Fixed_As_Integer
7887 and then Treat_Fixed_As_Integer (Expr)
7889 Ftyp := Base_Type (Etype (Expr));
7891 if Esize (Ftyp) >= Esize (Standard_Integer) then
7892 Ityp := Standard_Long_Long_Integer;
7894 Ityp := Standard_Integer;
7897 Rewrite (Expr, Unchecked_Convert_To (Ityp, Expr));
7900 -- Reset overflow flag, since the range check will include
7901 -- dealing with possible overflow, and generate the check
7902 -- If Address is either source or target type, suppress
7903 -- range check to avoid typing anomalies when it is a visible
7906 Set_Do_Overflow_Check (N, False);
7907 if not Is_Descendent_Of_Address (Etype (Expr))
7908 and then not Is_Descendent_Of_Address (Target_Type)
7910 Generate_Range_Check
7911 (Expr, Target_Type, CE_Range_Check_Failed);
7917 -- Final step, if the result is a type conversion involving Vax_Float
7918 -- types, then it is subject for further special processing.
7920 if Nkind (N) = N_Type_Conversion
7921 and then (Vax_Float (Operand_Type) or else Vax_Float (Target_Type))
7923 Expand_Vax_Conversion (N);
7926 end Expand_N_Type_Conversion;
7928 -----------------------------------
7929 -- Expand_N_Unchecked_Expression --
7930 -----------------------------------
7932 -- Remove the unchecked expression node from the tree. It's job was simply
7933 -- to make sure that its constituent expression was handled with checks
7934 -- off, and now that that is done, we can remove it from the tree, and
7935 -- indeed must, since gigi does not expect to see these nodes.
7937 procedure Expand_N_Unchecked_Expression (N : Node_Id) is
7938 Exp : constant Node_Id := Expression (N);
7941 Set_Assignment_OK (Exp, Assignment_OK (N) or Assignment_OK (Exp));
7943 end Expand_N_Unchecked_Expression;
7945 ----------------------------------------
7946 -- Expand_N_Unchecked_Type_Conversion --
7947 ----------------------------------------
7949 -- If this cannot be handled by Gigi and we haven't already made
7950 -- a temporary for it, do it now.
7952 procedure Expand_N_Unchecked_Type_Conversion (N : Node_Id) is
7953 Target_Type : constant Entity_Id := Etype (N);
7954 Operand : constant Node_Id := Expression (N);
7955 Operand_Type : constant Entity_Id := Etype (Operand);
7958 -- If we have a conversion of a compile time known value to a target
7959 -- type and the value is in range of the target type, then we can simply
7960 -- replace the construct by an integer literal of the correct type. We
7961 -- only apply this to integer types being converted. Possibly it may
7962 -- apply in other cases, but it is too much trouble to worry about.
7964 -- Note that we do not do this transformation if the Kill_Range_Check
7965 -- flag is set, since then the value may be outside the expected range.
7966 -- This happens in the Normalize_Scalars case.
7968 -- We also skip this if either the target or operand type is biased
7969 -- because in this case, the unchecked conversion is supposed to
7970 -- preserve the bit pattern, not the integer value.
7972 if Is_Integer_Type (Target_Type)
7973 and then not Has_Biased_Representation (Target_Type)
7974 and then Is_Integer_Type (Operand_Type)
7975 and then not Has_Biased_Representation (Operand_Type)
7976 and then Compile_Time_Known_Value (Operand)
7977 and then not Kill_Range_Check (N)
7980 Val : constant Uint := Expr_Value (Operand);
7983 if Compile_Time_Known_Value (Type_Low_Bound (Target_Type))
7985 Compile_Time_Known_Value (Type_High_Bound (Target_Type))
7987 Val >= Expr_Value (Type_Low_Bound (Target_Type))
7989 Val <= Expr_Value (Type_High_Bound (Target_Type))
7991 Rewrite (N, Make_Integer_Literal (Sloc (N), Val));
7993 -- If Address is the target type, just set the type
7994 -- to avoid a spurious type error on the literal when
7995 -- Address is a visible integer type.
7997 if Is_Descendent_Of_Address (Target_Type) then
7998 Set_Etype (N, Target_Type);
8000 Analyze_And_Resolve (N, Target_Type);
8008 -- Nothing to do if conversion is safe
8010 if Safe_Unchecked_Type_Conversion (N) then
8014 -- Otherwise force evaluation unless Assignment_OK flag is set (this
8015 -- flag indicates ??? -- more comments needed here)
8017 if Assignment_OK (N) then
8020 Force_Evaluation (N);
8022 end Expand_N_Unchecked_Type_Conversion;
8024 ----------------------------
8025 -- Expand_Record_Equality --
8026 ----------------------------
8028 -- For non-variant records, Equality is expanded when needed into:
8030 -- and then Lhs.Discr1 = Rhs.Discr1
8032 -- and then Lhs.Discrn = Rhs.Discrn
8033 -- and then Lhs.Cmp1 = Rhs.Cmp1
8035 -- and then Lhs.Cmpn = Rhs.Cmpn
8037 -- The expression is folded by the back-end for adjacent fields. This
8038 -- function is called for tagged record in only one occasion: for imple-
8039 -- menting predefined primitive equality (see Predefined_Primitives_Bodies)
8040 -- otherwise the primitive "=" is used directly.
8042 function Expand_Record_Equality
8047 Bodies : List_Id) return Node_Id
8049 Loc : constant Source_Ptr := Sloc (Nod);
8054 First_Time : Boolean := True;
8056 function Suitable_Element (C : Entity_Id) return Entity_Id;
8057 -- Return the first field to compare beginning with C, skipping the
8058 -- inherited components.
8060 ----------------------
8061 -- Suitable_Element --
8062 ----------------------
8064 function Suitable_Element (C : Entity_Id) return Entity_Id is
8069 elsif Ekind (C) /= E_Discriminant
8070 and then Ekind (C) /= E_Component
8072 return Suitable_Element (Next_Entity (C));
8074 elsif Is_Tagged_Type (Typ)
8075 and then C /= Original_Record_Component (C)
8077 return Suitable_Element (Next_Entity (C));
8079 elsif Chars (C) = Name_uController
8080 or else Chars (C) = Name_uTag
8082 return Suitable_Element (Next_Entity (C));
8084 elsif Is_Interface (Etype (C)) then
8085 return Suitable_Element (Next_Entity (C));
8090 end Suitable_Element;
8092 -- Start of processing for Expand_Record_Equality
8095 -- Generates the following code: (assuming that Typ has one Discr and
8096 -- component C2 is also a record)
8099 -- and then Lhs.Discr1 = Rhs.Discr1
8100 -- and then Lhs.C1 = Rhs.C1
8101 -- and then Lhs.C2.C1=Rhs.C2.C1 and then ... Lhs.C2.Cn=Rhs.C2.Cn
8103 -- and then Lhs.Cmpn = Rhs.Cmpn
8105 Result := New_Reference_To (Standard_True, Loc);
8106 C := Suitable_Element (First_Entity (Typ));
8108 while Present (C) loop
8116 First_Time := False;
8120 New_Lhs := New_Copy_Tree (Lhs);
8121 New_Rhs := New_Copy_Tree (Rhs);
8125 Expand_Composite_Equality (Nod, Etype (C),
8127 Make_Selected_Component (Loc,
8129 Selector_Name => New_Reference_To (C, Loc)),
8131 Make_Selected_Component (Loc,
8133 Selector_Name => New_Reference_To (C, Loc)),
8136 -- If some (sub)component is an unchecked_union, the whole
8137 -- operation will raise program error.
8139 if Nkind (Check) = N_Raise_Program_Error then
8141 Set_Etype (Result, Standard_Boolean);
8146 Left_Opnd => Result,
8147 Right_Opnd => Check);
8151 C := Suitable_Element (Next_Entity (C));
8155 end Expand_Record_Equality;
8157 -------------------------------------
8158 -- Fixup_Universal_Fixed_Operation --
8159 -------------------------------------
8161 procedure Fixup_Universal_Fixed_Operation (N : Node_Id) is
8162 Conv : constant Node_Id := Parent (N);
8165 -- We must have a type conversion immediately above us
8167 pragma Assert (Nkind (Conv) = N_Type_Conversion);
8169 -- Normally the type conversion gives our target type. The exception
8170 -- occurs in the case of the Round attribute, where the conversion
8171 -- will be to universal real, and our real type comes from the Round
8172 -- attribute (as well as an indication that we must round the result)
8174 if Nkind (Parent (Conv)) = N_Attribute_Reference
8175 and then Attribute_Name (Parent (Conv)) = Name_Round
8177 Set_Etype (N, Etype (Parent (Conv)));
8178 Set_Rounded_Result (N);
8180 -- Normal case where type comes from conversion above us
8183 Set_Etype (N, Etype (Conv));
8185 end Fixup_Universal_Fixed_Operation;
8187 ------------------------------
8188 -- Get_Allocator_Final_List --
8189 ------------------------------
8191 function Get_Allocator_Final_List
8194 PtrT : Entity_Id) return Entity_Id
8196 Loc : constant Source_Ptr := Sloc (N);
8198 Owner : Entity_Id := PtrT;
8199 -- The entity whose finalization list must be used to attach the
8200 -- allocated object.
8203 if Ekind (PtrT) = E_Anonymous_Access_Type then
8205 -- If the context is an access parameter, we need to create a
8206 -- non-anonymous access type in order to have a usable final list,
8207 -- because there is otherwise no pool to which the allocated object
8208 -- can belong. We create both the type and the finalization chain
8209 -- here, because freezing an internal type does not create such a
8210 -- chain. The Final_Chain that is thus created is shared by the
8211 -- access parameter. The access type is tested against the result
8212 -- type of the function to exclude allocators whose type is an
8213 -- anonymous access result type.
8215 if Nkind (Associated_Node_For_Itype (PtrT))
8216 in N_Subprogram_Specification
8219 Etype (Defining_Unit_Name (Associated_Node_For_Itype (PtrT)))
8221 Owner := Make_Defining_Identifier (Loc, New_Internal_Name ('J'));
8223 Make_Full_Type_Declaration (Loc,
8224 Defining_Identifier => Owner,
8226 Make_Access_To_Object_Definition (Loc,
8227 Subtype_Indication =>
8228 New_Occurrence_Of (T, Loc))));
8230 Build_Final_List (N, Owner);
8231 Set_Associated_Final_Chain (PtrT, Associated_Final_Chain (Owner));
8233 -- Ada 2005 (AI-318-02): If the context is a return object
8234 -- declaration, then the anonymous return subtype is defined to have
8235 -- the same accessibility level as that of the function's result
8236 -- subtype, which means that we want the scope where the function is
8239 elsif Nkind (Associated_Node_For_Itype (PtrT)) = N_Object_Declaration
8240 and then Ekind (Scope (PtrT)) = E_Return_Statement
8242 Owner := Scope (Return_Applies_To (Scope (PtrT)));
8244 -- Case of an access discriminant, or (Ada 2005), of an anonymous
8245 -- access component or anonymous access function result: find the
8246 -- final list associated with the scope of the type. (In the
8247 -- anonymous access component kind, a list controller will have
8248 -- been allocated when freezing the record type, and PtrT has an
8249 -- Associated_Final_Chain attribute designating it.)
8251 elsif No (Associated_Final_Chain (PtrT)) then
8252 Owner := Scope (PtrT);
8256 return Find_Final_List (Owner);
8257 end Get_Allocator_Final_List;
8259 ---------------------------------
8260 -- Has_Inferable_Discriminants --
8261 ---------------------------------
8263 function Has_Inferable_Discriminants (N : Node_Id) return Boolean is
8265 function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean;
8266 -- Determines whether the left-most prefix of a selected component is a
8267 -- formal parameter in a subprogram. Assumes N is a selected component.
8269 --------------------------------
8270 -- Prefix_Is_Formal_Parameter --
8271 --------------------------------
8273 function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean is
8274 Sel_Comp : Node_Id := N;
8277 -- Move to the left-most prefix by climbing up the tree
8279 while Present (Parent (Sel_Comp))
8280 and then Nkind (Parent (Sel_Comp)) = N_Selected_Component
8282 Sel_Comp := Parent (Sel_Comp);
8285 return Ekind (Entity (Prefix (Sel_Comp))) in Formal_Kind;
8286 end Prefix_Is_Formal_Parameter;
8288 -- Start of processing for Has_Inferable_Discriminants
8291 -- For identifiers and indexed components, it is sufficent to have a
8292 -- constrained Unchecked_Union nominal subtype.
8294 if Nkind (N) = N_Identifier
8296 Nkind (N) = N_Indexed_Component
8298 return Is_Unchecked_Union (Base_Type (Etype (N)))
8300 Is_Constrained (Etype (N));
8302 -- For selected components, the subtype of the selector must be a
8303 -- constrained Unchecked_Union. If the component is subject to a
8304 -- per-object constraint, then the enclosing object must have inferable
8307 elsif Nkind (N) = N_Selected_Component then
8308 if Has_Per_Object_Constraint (Entity (Selector_Name (N))) then
8310 -- A small hack. If we have a per-object constrained selected
8311 -- component of a formal parameter, return True since we do not
8312 -- know the actual parameter association yet.
8314 if Prefix_Is_Formal_Parameter (N) then
8318 -- Otherwise, check the enclosing object and the selector
8320 return Has_Inferable_Discriminants (Prefix (N))
8322 Has_Inferable_Discriminants (Selector_Name (N));
8325 -- The call to Has_Inferable_Discriminants will determine whether
8326 -- the selector has a constrained Unchecked_Union nominal type.
8328 return Has_Inferable_Discriminants (Selector_Name (N));
8330 -- A qualified expression has inferable discriminants if its subtype
8331 -- mark is a constrained Unchecked_Union subtype.
8333 elsif Nkind (N) = N_Qualified_Expression then
8334 return Is_Unchecked_Union (Subtype_Mark (N))
8336 Is_Constrained (Subtype_Mark (N));
8341 end Has_Inferable_Discriminants;
8343 -------------------------------
8344 -- Insert_Dereference_Action --
8345 -------------------------------
8347 procedure Insert_Dereference_Action (N : Node_Id) is
8348 Loc : constant Source_Ptr := Sloc (N);
8349 Typ : constant Entity_Id := Etype (N);
8350 Pool : constant Entity_Id := Associated_Storage_Pool (Typ);
8351 Pnod : constant Node_Id := Parent (N);
8353 function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean;
8354 -- Return true if type of P is derived from Checked_Pool;
8356 -----------------------------
8357 -- Is_Checked_Storage_Pool --
8358 -----------------------------
8360 function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean is
8369 while T /= Etype (T) loop
8370 if Is_RTE (T, RE_Checked_Pool) then
8378 end Is_Checked_Storage_Pool;
8380 -- Start of processing for Insert_Dereference_Action
8383 pragma Assert (Nkind (Pnod) = N_Explicit_Dereference);
8385 if not (Is_Checked_Storage_Pool (Pool)
8386 and then Comes_From_Source (Original_Node (Pnod)))
8392 Make_Procedure_Call_Statement (Loc,
8393 Name => New_Reference_To (
8394 Find_Prim_Op (Etype (Pool), Name_Dereference), Loc),
8396 Parameter_Associations => New_List (
8400 New_Reference_To (Pool, Loc),
8402 -- Storage_Address. We use the attribute Pool_Address,
8403 -- which uses the pointer itself to find the address of
8404 -- the object, and which handles unconstrained arrays
8405 -- properly by computing the address of the template.
8406 -- i.e. the correct address of the corresponding allocation.
8408 Make_Attribute_Reference (Loc,
8409 Prefix => Duplicate_Subexpr_Move_Checks (N),
8410 Attribute_Name => Name_Pool_Address),
8412 -- Size_In_Storage_Elements
8414 Make_Op_Divide (Loc,
8416 Make_Attribute_Reference (Loc,
8418 Make_Explicit_Dereference (Loc,
8419 Duplicate_Subexpr_Move_Checks (N)),
8420 Attribute_Name => Name_Size),
8422 Make_Integer_Literal (Loc, System_Storage_Unit)),
8426 Make_Attribute_Reference (Loc,
8428 Make_Explicit_Dereference (Loc,
8429 Duplicate_Subexpr_Move_Checks (N)),
8430 Attribute_Name => Name_Alignment))));
8433 when RE_Not_Available =>
8435 end Insert_Dereference_Action;
8437 ------------------------------
8438 -- Make_Array_Comparison_Op --
8439 ------------------------------
8441 -- This is a hand-coded expansion of the following generic function:
8444 -- type elem is (<>);
8445 -- type index is (<>);
8446 -- type a is array (index range <>) of elem;
8448 -- function Gnnn (X : a; Y: a) return boolean is
8449 -- J : index := Y'first;
8452 -- if X'length = 0 then
8455 -- elsif Y'length = 0 then
8459 -- for I in X'range loop
8460 -- if X (I) = Y (J) then
8461 -- if J = Y'last then
8464 -- J := index'succ (J);
8468 -- return X (I) > Y (J);
8472 -- return X'length > Y'length;
8476 -- Note that since we are essentially doing this expansion by hand, we
8477 -- do not need to generate an actual or formal generic part, just the
8478 -- instantiated function itself.
8480 function Make_Array_Comparison_Op
8482 Nod : Node_Id) return Node_Id
8484 Loc : constant Source_Ptr := Sloc (Nod);
8486 X : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uX);
8487 Y : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uY);
8488 I : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uI);
8489 J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
8491 Index : constant Entity_Id := Base_Type (Etype (First_Index (Typ)));
8493 Loop_Statement : Node_Id;
8494 Loop_Body : Node_Id;
8497 Final_Expr : Node_Id;
8498 Func_Body : Node_Id;
8499 Func_Name : Entity_Id;
8505 -- if J = Y'last then
8508 -- J := index'succ (J);
8512 Make_Implicit_If_Statement (Nod,
8515 Left_Opnd => New_Reference_To (J, Loc),
8517 Make_Attribute_Reference (Loc,
8518 Prefix => New_Reference_To (Y, Loc),
8519 Attribute_Name => Name_Last)),
8521 Then_Statements => New_List (
8522 Make_Exit_Statement (Loc)),
8526 Make_Assignment_Statement (Loc,
8527 Name => New_Reference_To (J, Loc),
8529 Make_Attribute_Reference (Loc,
8530 Prefix => New_Reference_To (Index, Loc),
8531 Attribute_Name => Name_Succ,
8532 Expressions => New_List (New_Reference_To (J, Loc))))));
8534 -- if X (I) = Y (J) then
8537 -- return X (I) > Y (J);
8541 Make_Implicit_If_Statement (Nod,
8545 Make_Indexed_Component (Loc,
8546 Prefix => New_Reference_To (X, Loc),
8547 Expressions => New_List (New_Reference_To (I, Loc))),
8550 Make_Indexed_Component (Loc,
8551 Prefix => New_Reference_To (Y, Loc),
8552 Expressions => New_List (New_Reference_To (J, Loc)))),
8554 Then_Statements => New_List (Inner_If),
8556 Else_Statements => New_List (
8557 Make_Simple_Return_Statement (Loc,
8561 Make_Indexed_Component (Loc,
8562 Prefix => New_Reference_To (X, Loc),
8563 Expressions => New_List (New_Reference_To (I, Loc))),
8566 Make_Indexed_Component (Loc,
8567 Prefix => New_Reference_To (Y, Loc),
8568 Expressions => New_List (
8569 New_Reference_To (J, Loc)))))));
8571 -- for I in X'range loop
8576 Make_Implicit_Loop_Statement (Nod,
8577 Identifier => Empty,
8580 Make_Iteration_Scheme (Loc,
8581 Loop_Parameter_Specification =>
8582 Make_Loop_Parameter_Specification (Loc,
8583 Defining_Identifier => I,
8584 Discrete_Subtype_Definition =>
8585 Make_Attribute_Reference (Loc,
8586 Prefix => New_Reference_To (X, Loc),
8587 Attribute_Name => Name_Range))),
8589 Statements => New_List (Loop_Body));
8591 -- if X'length = 0 then
8593 -- elsif Y'length = 0 then
8596 -- for ... loop ... end loop;
8597 -- return X'length > Y'length;
8601 Make_Attribute_Reference (Loc,
8602 Prefix => New_Reference_To (X, Loc),
8603 Attribute_Name => Name_Length);
8606 Make_Attribute_Reference (Loc,
8607 Prefix => New_Reference_To (Y, Loc),
8608 Attribute_Name => Name_Length);
8612 Left_Opnd => Length1,
8613 Right_Opnd => Length2);
8616 Make_Implicit_If_Statement (Nod,
8620 Make_Attribute_Reference (Loc,
8621 Prefix => New_Reference_To (X, Loc),
8622 Attribute_Name => Name_Length),
8624 Make_Integer_Literal (Loc, 0)),
8628 Make_Simple_Return_Statement (Loc,
8629 Expression => New_Reference_To (Standard_False, Loc))),
8631 Elsif_Parts => New_List (
8632 Make_Elsif_Part (Loc,
8636 Make_Attribute_Reference (Loc,
8637 Prefix => New_Reference_To (Y, Loc),
8638 Attribute_Name => Name_Length),
8640 Make_Integer_Literal (Loc, 0)),
8644 Make_Simple_Return_Statement (Loc,
8645 Expression => New_Reference_To (Standard_True, Loc))))),
8647 Else_Statements => New_List (
8649 Make_Simple_Return_Statement (Loc,
8650 Expression => Final_Expr)));
8654 Formals := New_List (
8655 Make_Parameter_Specification (Loc,
8656 Defining_Identifier => X,
8657 Parameter_Type => New_Reference_To (Typ, Loc)),
8659 Make_Parameter_Specification (Loc,
8660 Defining_Identifier => Y,
8661 Parameter_Type => New_Reference_To (Typ, Loc)));
8663 -- function Gnnn (...) return boolean is
8664 -- J : index := Y'first;
8669 Func_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('G'));
8672 Make_Subprogram_Body (Loc,
8674 Make_Function_Specification (Loc,
8675 Defining_Unit_Name => Func_Name,
8676 Parameter_Specifications => Formals,
8677 Result_Definition => New_Reference_To (Standard_Boolean, Loc)),
8679 Declarations => New_List (
8680 Make_Object_Declaration (Loc,
8681 Defining_Identifier => J,
8682 Object_Definition => New_Reference_To (Index, Loc),
8684 Make_Attribute_Reference (Loc,
8685 Prefix => New_Reference_To (Y, Loc),
8686 Attribute_Name => Name_First))),
8688 Handled_Statement_Sequence =>
8689 Make_Handled_Sequence_Of_Statements (Loc,
8690 Statements => New_List (If_Stat)));
8693 end Make_Array_Comparison_Op;
8695 ---------------------------
8696 -- Make_Boolean_Array_Op --
8697 ---------------------------
8699 -- For logical operations on boolean arrays, expand in line the
8700 -- following, replacing 'and' with 'or' or 'xor' where needed:
8702 -- function Annn (A : typ; B: typ) return typ is
8705 -- for J in A'range loop
8706 -- C (J) := A (J) op B (J);
8711 -- Here typ is the boolean array type
8713 function Make_Boolean_Array_Op
8715 N : Node_Id) return Node_Id
8717 Loc : constant Source_Ptr := Sloc (N);
8719 A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
8720 B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
8721 C : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uC);
8722 J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
8730 Func_Name : Entity_Id;
8731 Func_Body : Node_Id;
8732 Loop_Statement : Node_Id;
8736 Make_Indexed_Component (Loc,
8737 Prefix => New_Reference_To (A, Loc),
8738 Expressions => New_List (New_Reference_To (J, Loc)));
8741 Make_Indexed_Component (Loc,
8742 Prefix => New_Reference_To (B, Loc),
8743 Expressions => New_List (New_Reference_To (J, Loc)));
8746 Make_Indexed_Component (Loc,
8747 Prefix => New_Reference_To (C, Loc),
8748 Expressions => New_List (New_Reference_To (J, Loc)));
8750 if Nkind (N) = N_Op_And then
8756 elsif Nkind (N) = N_Op_Or then
8770 Make_Implicit_Loop_Statement (N,
8771 Identifier => Empty,
8774 Make_Iteration_Scheme (Loc,
8775 Loop_Parameter_Specification =>
8776 Make_Loop_Parameter_Specification (Loc,
8777 Defining_Identifier => J,
8778 Discrete_Subtype_Definition =>
8779 Make_Attribute_Reference (Loc,
8780 Prefix => New_Reference_To (A, Loc),
8781 Attribute_Name => Name_Range))),
8783 Statements => New_List (
8784 Make_Assignment_Statement (Loc,
8786 Expression => Op)));
8788 Formals := New_List (
8789 Make_Parameter_Specification (Loc,
8790 Defining_Identifier => A,
8791 Parameter_Type => New_Reference_To (Typ, Loc)),
8793 Make_Parameter_Specification (Loc,
8794 Defining_Identifier => B,
8795 Parameter_Type => New_Reference_To (Typ, Loc)));
8798 Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
8799 Set_Is_Inlined (Func_Name);
8802 Make_Subprogram_Body (Loc,
8804 Make_Function_Specification (Loc,
8805 Defining_Unit_Name => Func_Name,
8806 Parameter_Specifications => Formals,
8807 Result_Definition => New_Reference_To (Typ, Loc)),
8809 Declarations => New_List (
8810 Make_Object_Declaration (Loc,
8811 Defining_Identifier => C,
8812 Object_Definition => New_Reference_To (Typ, Loc))),
8814 Handled_Statement_Sequence =>
8815 Make_Handled_Sequence_Of_Statements (Loc,
8816 Statements => New_List (
8818 Make_Simple_Return_Statement (Loc,
8819 Expression => New_Reference_To (C, Loc)))));
8822 end Make_Boolean_Array_Op;
8824 ------------------------
8825 -- Rewrite_Comparison --
8826 ------------------------
8828 procedure Rewrite_Comparison (N : Node_Id) is
8830 if Nkind (N) = N_Type_Conversion then
8831 Rewrite_Comparison (Expression (N));
8834 elsif Nkind (N) not in N_Op_Compare then
8839 Typ : constant Entity_Id := Etype (N);
8840 Op1 : constant Node_Id := Left_Opnd (N);
8841 Op2 : constant Node_Id := Right_Opnd (N);
8843 Res : constant Compare_Result := Compile_Time_Compare (Op1, Op2);
8844 -- Res indicates if compare outcome can be compile time determined
8846 True_Result : Boolean;
8847 False_Result : Boolean;
8850 case N_Op_Compare (Nkind (N)) is
8852 True_Result := Res = EQ;
8853 False_Result := Res = LT or else Res = GT or else Res = NE;
8856 True_Result := Res in Compare_GE;
8857 False_Result := Res = LT;
8860 and then Constant_Condition_Warnings
8861 and then Comes_From_Source (Original_Node (N))
8862 and then Nkind (Original_Node (N)) = N_Op_Ge
8863 and then not In_Instance
8864 and then not Warnings_Off (Etype (Left_Opnd (N)))
8865 and then Is_Integer_Type (Etype (Left_Opnd (N)))
8868 ("can never be greater than, could replace by ""'=""?", N);
8872 True_Result := Res = GT;
8873 False_Result := Res in Compare_LE;
8876 True_Result := Res = LT;
8877 False_Result := Res in Compare_GE;
8880 True_Result := Res in Compare_LE;
8881 False_Result := Res = GT;
8884 and then Constant_Condition_Warnings
8885 and then Comes_From_Source (Original_Node (N))
8886 and then Nkind (Original_Node (N)) = N_Op_Le
8887 and then not In_Instance
8888 and then not Warnings_Off (Etype (Left_Opnd (N)))
8889 and then Is_Integer_Type (Etype (Left_Opnd (N)))
8892 ("can never be less than, could replace by ""'=""?", N);
8896 True_Result := Res = NE or else Res = GT or else Res = LT;
8897 False_Result := Res = EQ;
8903 New_Occurrence_Of (Standard_True, Sloc (N))));
8904 Analyze_And_Resolve (N, Typ);
8905 Warn_On_Known_Condition (N);
8907 elsif False_Result then
8910 New_Occurrence_Of (Standard_False, Sloc (N))));
8911 Analyze_And_Resolve (N, Typ);
8912 Warn_On_Known_Condition (N);
8915 end Rewrite_Comparison;
8917 ----------------------------
8918 -- Safe_In_Place_Array_Op --
8919 ----------------------------
8921 function Safe_In_Place_Array_Op
8924 Op2 : Node_Id) return Boolean
8928 function Is_Safe_Operand (Op : Node_Id) return Boolean;
8929 -- Operand is safe if it cannot overlap part of the target of the
8930 -- operation. If the operand and the target are identical, the operand
8931 -- is safe. The operand can be empty in the case of negation.
8933 function Is_Unaliased (N : Node_Id) return Boolean;
8934 -- Check that N is a stand-alone entity
8940 function Is_Unaliased (N : Node_Id) return Boolean is
8944 and then No (Address_Clause (Entity (N)))
8945 and then No (Renamed_Object (Entity (N)));
8948 ---------------------
8949 -- Is_Safe_Operand --
8950 ---------------------
8952 function Is_Safe_Operand (Op : Node_Id) return Boolean is
8957 elsif Is_Entity_Name (Op) then
8958 return Is_Unaliased (Op);
8960 elsif Nkind (Op) = N_Indexed_Component
8961 or else Nkind (Op) = N_Selected_Component
8963 return Is_Unaliased (Prefix (Op));
8965 elsif Nkind (Op) = N_Slice then
8967 Is_Unaliased (Prefix (Op))
8968 and then Entity (Prefix (Op)) /= Target;
8970 elsif Nkind (Op) = N_Op_Not then
8971 return Is_Safe_Operand (Right_Opnd (Op));
8976 end Is_Safe_Operand;
8978 -- Start of processing for Is_Safe_In_Place_Array_Op
8981 -- We skip this processing if the component size is not the
8982 -- same as a system storage unit (since at least for NOT
8983 -- this would cause problems).
8985 if Component_Size (Etype (Lhs)) /= System_Storage_Unit then
8988 -- Cannot do in place stuff on VM_Target since cannot pass addresses
8990 elsif VM_Target /= No_VM then
8993 -- Cannot do in place stuff if non-standard Boolean representation
8995 elsif Has_Non_Standard_Rep (Component_Type (Etype (Lhs))) then
8998 elsif not Is_Unaliased (Lhs) then
9001 Target := Entity (Lhs);
9004 Is_Safe_Operand (Op1)
9005 and then Is_Safe_Operand (Op2);
9007 end Safe_In_Place_Array_Op;
9009 -----------------------
9010 -- Tagged_Membership --
9011 -----------------------
9013 -- There are two different cases to consider depending on whether
9014 -- the right operand is a class-wide type or not. If not we just
9015 -- compare the actual tag of the left expr to the target type tag:
9017 -- Left_Expr.Tag = Right_Type'Tag;
9019 -- If it is a class-wide type we use the RT function CW_Membership which
9020 -- is usually implemented by looking in the ancestor tables contained in
9021 -- the dispatch table pointed by Left_Expr.Tag for Typ'Tag
9023 -- Ada 2005 (AI-251): If it is a class-wide interface type we use the RT
9024 -- function IW_Membership which is usually implemented by looking in the
9025 -- table of abstract interface types plus the ancestor table contained in
9026 -- the dispatch table pointed by Left_Expr.Tag for Typ'Tag
9028 function Tagged_Membership (N : Node_Id) return Node_Id is
9029 Left : constant Node_Id := Left_Opnd (N);
9030 Right : constant Node_Id := Right_Opnd (N);
9031 Loc : constant Source_Ptr := Sloc (N);
9033 Left_Type : Entity_Id;
9034 Right_Type : Entity_Id;
9038 Left_Type := Etype (Left);
9039 Right_Type := Etype (Right);
9041 if Is_Class_Wide_Type (Left_Type) then
9042 Left_Type := Root_Type (Left_Type);
9046 Make_Selected_Component (Loc,
9047 Prefix => Relocate_Node (Left),
9049 New_Reference_To (First_Tag_Component (Left_Type), Loc));
9051 if Is_Class_Wide_Type (Right_Type) then
9053 -- No need to issue a run-time check if we statically know that the
9054 -- result of this membership test is always true. For example,
9055 -- considering the following declarations:
9057 -- type Iface is interface;
9058 -- type T is tagged null record;
9059 -- type DT is new T and Iface with null record;
9064 -- These membership tests are always true:
9068 -- Obj2 in Iface'Class;
9070 -- We do not need to handle cases where the membership is illegal.
9073 -- Obj1 in DT'Class; -- Compile time error
9074 -- Obj1 in Iface'Class; -- Compile time error
9076 if not Is_Class_Wide_Type (Left_Type)
9077 and then (Is_Parent (Etype (Right_Type), Left_Type)
9078 or else (Is_Interface (Etype (Right_Type))
9079 and then Interface_Present_In_Ancestor
9081 Iface => Etype (Right_Type))))
9083 return New_Reference_To (Standard_True, Loc);
9086 -- Ada 2005 (AI-251): Class-wide applied to interfaces
9088 if Is_Interface (Etype (Class_Wide_Type (Right_Type)))
9090 -- Support to: "Iface_CW_Typ in Typ'Class"
9092 or else Is_Interface (Left_Type)
9094 -- Issue error if IW_Membership operation not available in a
9095 -- configurable run time setting.
9097 if not RTE_Available (RE_IW_Membership) then
9098 Error_Msg_CRT ("abstract interface types", N);
9103 Make_Function_Call (Loc,
9104 Name => New_Occurrence_Of (RTE (RE_IW_Membership), Loc),
9105 Parameter_Associations => New_List (
9106 Make_Attribute_Reference (Loc,
9108 Attribute_Name => Name_Address),
9111 (Access_Disp_Table (Root_Type (Right_Type)))),
9114 -- Ada 95: Normal case
9118 Build_CW_Membership (Loc,
9119 Obj_Tag_Node => Obj_Tag,
9123 (Access_Disp_Table (Root_Type (Right_Type)))),
9127 -- Right_Type is not a class-wide type
9130 -- No need to check the tag of the object if Right_Typ is abstract
9132 if Is_Abstract_Type (Right_Type) then
9133 return New_Reference_To (Standard_False, Loc);
9138 Left_Opnd => Obj_Tag,
9141 (Node (First_Elmt (Access_Disp_Table (Right_Type))), Loc));
9144 end Tagged_Membership;
9146 ------------------------------
9147 -- Unary_Op_Validity_Checks --
9148 ------------------------------
9150 procedure Unary_Op_Validity_Checks (N : Node_Id) is
9152 if Validity_Checks_On and Validity_Check_Operands then
9153 Ensure_Valid (Right_Opnd (N));
9155 end Unary_Op_Validity_Checks;