1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with Atree
; use Atree
;
27 with Checks
; use Checks
;
28 with Einfo
; use Einfo
;
29 with Elists
; use Elists
;
30 with Errout
; use Errout
;
31 with Exp_Aggr
; use Exp_Aggr
;
32 with Exp_Atag
; use Exp_Atag
;
33 with Exp_Ch3
; use Exp_Ch3
;
34 with Exp_Ch6
; use Exp_Ch6
;
35 with Exp_Ch7
; use Exp_Ch7
;
36 with Exp_Ch9
; use Exp_Ch9
;
37 with Exp_Disp
; use Exp_Disp
;
38 with Exp_Fixd
; use Exp_Fixd
;
39 with Exp_Pakd
; use Exp_Pakd
;
40 with Exp_Tss
; use Exp_Tss
;
41 with Exp_Util
; use Exp_Util
;
42 with Exp_VFpt
; use Exp_VFpt
;
43 with Freeze
; use Freeze
;
44 with Inline
; use Inline
;
45 with Namet
; use Namet
;
46 with Nlists
; use Nlists
;
47 with Nmake
; use Nmake
;
49 with Restrict
; use Restrict
;
50 with Rident
; use Rident
;
51 with Rtsfind
; use Rtsfind
;
53 with Sem_Cat
; use Sem_Cat
;
54 with Sem_Ch3
; use Sem_Ch3
;
55 with Sem_Ch8
; use Sem_Ch8
;
56 with Sem_Ch13
; use Sem_Ch13
;
57 with Sem_Eval
; use Sem_Eval
;
58 with Sem_Res
; use Sem_Res
;
59 with Sem_Type
; use Sem_Type
;
60 with Sem_Util
; use Sem_Util
;
61 with Sem_Warn
; use Sem_Warn
;
62 with Sinfo
; use Sinfo
;
63 with Snames
; use Snames
;
64 with Stand
; use Stand
;
65 with Targparm
; use Targparm
;
66 with Tbuild
; use Tbuild
;
67 with Ttypes
; use Ttypes
;
68 with Uintp
; use Uintp
;
69 with Urealp
; use Urealp
;
70 with Validsw
; use Validsw
;
72 package body Exp_Ch4
is
74 -----------------------
75 -- Local Subprograms --
76 -----------------------
78 procedure Binary_Op_Validity_Checks
(N
: Node_Id
);
79 pragma Inline
(Binary_Op_Validity_Checks
);
80 -- Performs validity checks for a binary operator
82 procedure Build_Boolean_Array_Proc_Call
86 -- If a boolean array assignment can be done in place, build call to
87 -- corresponding library procedure.
89 procedure Displace_Allocator_Pointer
(N
: Node_Id
);
90 -- Ada 2005 (AI-251): Subsidiary procedure to Expand_N_Allocator and
91 -- Expand_Allocator_Expression. Allocating class-wide interface objects
92 -- this routine displaces the pointer to the allocated object to reference
93 -- the component referencing the corresponding secondary dispatch table.
95 procedure Expand_Allocator_Expression
(N
: Node_Id
);
96 -- Subsidiary to Expand_N_Allocator, for the case when the expression
97 -- is a qualified expression or an aggregate.
99 procedure Expand_Array_Comparison
(N
: Node_Id
);
100 -- This routine handles expansion of the comparison operators (N_Op_Lt,
101 -- N_Op_Le, N_Op_Gt, N_Op_Ge) when operating on an array type. The basic
102 -- code for these operators is similar, differing only in the details of
103 -- the actual comparison call that is made. Special processing (call a
106 function Expand_Array_Equality
111 Typ
: Entity_Id
) return Node_Id
;
112 -- Expand an array equality into a call to a function implementing this
113 -- equality, and a call to it. Loc is the location for the generated nodes.
114 -- Lhs and Rhs are the array expressions to be compared. Bodies is a list
115 -- on which to attach bodies of local functions that are created in the
116 -- process. It is the responsibility of the caller to insert those bodies
117 -- at the right place. Nod provides the Sloc value for the generated code.
118 -- Normally the types used for the generated equality routine are taken
119 -- from Lhs and Rhs. However, in some situations of generated code, the
120 -- Etype fields of Lhs and Rhs are not set yet. In such cases, Typ supplies
121 -- the type to be used for the formal parameters.
123 procedure Expand_Boolean_Operator
(N
: Node_Id
);
124 -- Common expansion processing for Boolean operators (And, Or, Xor) for the
125 -- case of array type arguments.
127 function Expand_Composite_Equality
132 Bodies
: List_Id
) return Node_Id
;
133 -- Local recursive function used to expand equality for nested composite
134 -- types. Used by Expand_Record/Array_Equality, Bodies is a list on which
135 -- to attach bodies of local functions that are created in the process.
136 -- This is the responsibility of the caller to insert those bodies at the
137 -- right place. Nod provides the Sloc value for generated code. Lhs and Rhs
138 -- are the left and right sides for the comparison, and Typ is the type of
139 -- the arrays to compare.
141 procedure Expand_Concatenate_Other
(Cnode
: Node_Id
; Opnds
: List_Id
);
142 -- This routine handles expansion of concatenation operations, where N is
143 -- the N_Op_Concat node being expanded and Operands is the list of operands
144 -- (at least two are present). The caller has dealt with converting any
145 -- singleton operands into singleton aggregates.
147 procedure Expand_Concatenate_String
(Cnode
: Node_Id
; Opnds
: List_Id
);
148 -- Routine to expand concatenation of 2-5 operands (in the list Operands)
149 -- and replace node Cnode with the result of the concatenation. If there
150 -- are two operands, they can be string or character. If there are more
151 -- than two operands, then are always of type string (i.e. the caller has
152 -- already converted character operands to strings in this case).
154 procedure Fixup_Universal_Fixed_Operation
(N
: Node_Id
);
155 -- N is a N_Op_Divide or N_Op_Multiply node whose result is universal
156 -- fixed. We do not have such a type at runtime, so the purpose of this
157 -- routine is to find the real type by looking up the tree. We also
158 -- determine if the operation must be rounded.
160 function Get_Allocator_Final_List
163 PtrT
: Entity_Id
) return Entity_Id
;
164 -- If the designated type is controlled, build final_list expression for
165 -- created object. If context is an access parameter, create a local access
166 -- type to have a usable finalization list.
168 function Has_Inferable_Discriminants
(N
: Node_Id
) return Boolean;
169 -- Ada 2005 (AI-216): A view of an Unchecked_Union object has inferable
170 -- discriminants if it has a constrained nominal type, unless the object
171 -- is a component of an enclosing Unchecked_Union object that is subject
172 -- to a per-object constraint and the enclosing object lacks inferable
175 -- An expression of an Unchecked_Union type has inferable discriminants
176 -- if it is either a name of an object with inferable discriminants or a
177 -- qualified expression whose subtype mark denotes a constrained subtype.
179 procedure Insert_Dereference_Action
(N
: Node_Id
);
180 -- N is an expression whose type is an access. When the type of the
181 -- associated storage pool is derived from Checked_Pool, generate a
182 -- call to the 'Dereference' primitive operation.
184 function Make_Array_Comparison_Op
186 Nod
: Node_Id
) return Node_Id
;
187 -- Comparisons between arrays are expanded in line. This function produces
188 -- the body of the implementation of (a > b), where a and b are one-
189 -- dimensional arrays of some discrete type. The original node is then
190 -- expanded into the appropriate call to this function. Nod provides the
191 -- Sloc value for the generated code.
193 function Make_Boolean_Array_Op
195 N
: Node_Id
) return Node_Id
;
196 -- Boolean operations on boolean arrays are expanded in line. This function
197 -- produce the body for the node N, which is (a and b), (a or b), or (a xor
198 -- b). It is used only the normal case and not the packed case. The type
199 -- involved, Typ, is the Boolean array type, and the logical operations in
200 -- the body are simple boolean operations. Note that Typ is always a
201 -- constrained type (the caller has ensured this by using
202 -- Convert_To_Actual_Subtype if necessary).
204 procedure Rewrite_Comparison
(N
: Node_Id
);
205 -- If N is the node for a comparison whose outcome can be determined at
206 -- compile time, then the node N can be rewritten with True or False. If
207 -- the outcome cannot be determined at compile time, the call has no
208 -- effect. If N is a type conversion, then this processing is applied to
209 -- its expression. If N is neither comparison nor a type conversion, the
210 -- call has no effect.
212 function Tagged_Membership
(N
: Node_Id
) return Node_Id
;
213 -- Construct the expression corresponding to the tagged membership test.
214 -- Deals with a second operand being (or not) a class-wide type.
216 function Safe_In_Place_Array_Op
219 Op2
: Node_Id
) return Boolean;
220 -- In the context of an assignment, where the right-hand side is a boolean
221 -- operation on arrays, check whether operation can be performed in place.
223 procedure Unary_Op_Validity_Checks
(N
: Node_Id
);
224 pragma Inline
(Unary_Op_Validity_Checks
);
225 -- Performs validity checks for a unary operator
227 -------------------------------
228 -- Binary_Op_Validity_Checks --
229 -------------------------------
231 procedure Binary_Op_Validity_Checks
(N
: Node_Id
) is
233 if Validity_Checks_On
and Validity_Check_Operands
then
234 Ensure_Valid
(Left_Opnd
(N
));
235 Ensure_Valid
(Right_Opnd
(N
));
237 end Binary_Op_Validity_Checks
;
239 ------------------------------------
240 -- Build_Boolean_Array_Proc_Call --
241 ------------------------------------
243 procedure Build_Boolean_Array_Proc_Call
248 Loc
: constant Source_Ptr
:= Sloc
(N
);
249 Kind
: constant Node_Kind
:= Nkind
(Expression
(N
));
250 Target
: constant Node_Id
:=
251 Make_Attribute_Reference
(Loc
,
253 Attribute_Name
=> Name_Address
);
255 Arg1
: constant Node_Id
:= Op1
;
256 Arg2
: Node_Id
:= Op2
;
258 Proc_Name
: Entity_Id
;
261 if Kind
= N_Op_Not
then
262 if Nkind
(Op1
) in N_Binary_Op
then
264 -- Use negated version of the binary operators
266 if Nkind
(Op1
) = N_Op_And
then
267 Proc_Name
:= RTE
(RE_Vector_Nand
);
269 elsif Nkind
(Op1
) = N_Op_Or
then
270 Proc_Name
:= RTE
(RE_Vector_Nor
);
272 else pragma Assert
(Nkind
(Op1
) = N_Op_Xor
);
273 Proc_Name
:= RTE
(RE_Vector_Xor
);
277 Make_Procedure_Call_Statement
(Loc
,
278 Name
=> New_Occurrence_Of
(Proc_Name
, Loc
),
280 Parameter_Associations
=> New_List
(
282 Make_Attribute_Reference
(Loc
,
283 Prefix
=> Left_Opnd
(Op1
),
284 Attribute_Name
=> Name_Address
),
286 Make_Attribute_Reference
(Loc
,
287 Prefix
=> Right_Opnd
(Op1
),
288 Attribute_Name
=> Name_Address
),
290 Make_Attribute_Reference
(Loc
,
291 Prefix
=> Left_Opnd
(Op1
),
292 Attribute_Name
=> Name_Length
)));
295 Proc_Name
:= RTE
(RE_Vector_Not
);
298 Make_Procedure_Call_Statement
(Loc
,
299 Name
=> New_Occurrence_Of
(Proc_Name
, Loc
),
300 Parameter_Associations
=> New_List
(
303 Make_Attribute_Reference
(Loc
,
305 Attribute_Name
=> Name_Address
),
307 Make_Attribute_Reference
(Loc
,
309 Attribute_Name
=> Name_Length
)));
313 -- We use the following equivalences:
315 -- (not X) or (not Y) = not (X and Y) = Nand (X, Y)
316 -- (not X) and (not Y) = not (X or Y) = Nor (X, Y)
317 -- (not X) xor (not Y) = X xor Y
318 -- X xor (not Y) = not (X xor Y) = Nxor (X, Y)
320 if Nkind
(Op1
) = N_Op_Not
then
321 if Kind
= N_Op_And
then
322 Proc_Name
:= RTE
(RE_Vector_Nor
);
324 elsif Kind
= N_Op_Or
then
325 Proc_Name
:= RTE
(RE_Vector_Nand
);
328 Proc_Name
:= RTE
(RE_Vector_Xor
);
332 if Kind
= N_Op_And
then
333 Proc_Name
:= RTE
(RE_Vector_And
);
335 elsif Kind
= N_Op_Or
then
336 Proc_Name
:= RTE
(RE_Vector_Or
);
338 elsif Nkind
(Op2
) = N_Op_Not
then
339 Proc_Name
:= RTE
(RE_Vector_Nxor
);
340 Arg2
:= Right_Opnd
(Op2
);
343 Proc_Name
:= RTE
(RE_Vector_Xor
);
348 Make_Procedure_Call_Statement
(Loc
,
349 Name
=> New_Occurrence_Of
(Proc_Name
, Loc
),
350 Parameter_Associations
=> New_List
(
352 Make_Attribute_Reference
(Loc
,
354 Attribute_Name
=> Name_Address
),
355 Make_Attribute_Reference
(Loc
,
357 Attribute_Name
=> Name_Address
),
358 Make_Attribute_Reference
(Loc
,
360 Attribute_Name
=> Name_Length
)));
363 Rewrite
(N
, Call_Node
);
367 when RE_Not_Available
=>
369 end Build_Boolean_Array_Proc_Call
;
371 --------------------------------
372 -- Displace_Allocator_Pointer --
373 --------------------------------
375 procedure Displace_Allocator_Pointer
(N
: Node_Id
) is
376 Loc
: constant Source_Ptr
:= Sloc
(N
);
377 Orig_Node
: constant Node_Id
:= Original_Node
(N
);
383 -- Do nothing in case of VM targets: the virtual machine will handle
384 -- interfaces directly.
386 if VM_Target
/= No_VM
then
390 pragma Assert
(Nkind
(N
) = N_Identifier
391 and then Nkind
(Orig_Node
) = N_Allocator
);
393 PtrT
:= Etype
(Orig_Node
);
394 Dtyp
:= Designated_Type
(PtrT
);
395 Etyp
:= Etype
(Expression
(Orig_Node
));
397 if Is_Class_Wide_Type
(Dtyp
)
398 and then Is_Interface
(Dtyp
)
400 -- If the type of the allocator expression is not an interface type
401 -- we can generate code to reference the record component containing
402 -- the pointer to the secondary dispatch table.
404 if not Is_Interface
(Etyp
) then
406 Saved_Typ
: constant Entity_Id
:= Etype
(Orig_Node
);
409 -- 1) Get access to the allocated object
412 Make_Explicit_Dereference
(Loc
,
417 -- 2) Add the conversion to displace the pointer to reference
418 -- the secondary dispatch table.
420 Rewrite
(N
, Convert_To
(Dtyp
, Relocate_Node
(N
)));
421 Analyze_And_Resolve
(N
, Dtyp
);
423 -- 3) The 'access to the secondary dispatch table will be used
424 -- as the value returned by the allocator.
427 Make_Attribute_Reference
(Loc
,
428 Prefix
=> Relocate_Node
(N
),
429 Attribute_Name
=> Name_Access
));
430 Set_Etype
(N
, Saved_Typ
);
434 -- If the type of the allocator expression is an interface type we
435 -- generate a run-time call to displace "this" to reference the
436 -- component containing the pointer to the secondary dispatch table
437 -- or else raise Constraint_Error if the actual object does not
438 -- implement the target interface. This case corresponds with the
439 -- following example:
441 -- function Op (Obj : Iface_1'Class) return access Iface_2'Class is
443 -- return new Iface_2'Class'(Obj);
448 Unchecked_Convert_To
(PtrT
,
449 Make_Function_Call
(Loc
,
450 Name
=> New_Reference_To
(RTE
(RE_Displace
), Loc
),
451 Parameter_Associations
=> New_List
(
452 Unchecked_Convert_To
(RTE
(RE_Address
),
458 (Access_Disp_Table
(Etype
(Base_Type
(Dtyp
))))),
460 Analyze_And_Resolve
(N
, PtrT
);
463 end Displace_Allocator_Pointer
;
465 ---------------------------------
466 -- Expand_Allocator_Expression --
467 ---------------------------------
469 procedure Expand_Allocator_Expression
(N
: Node_Id
) is
470 Loc
: constant Source_Ptr
:= Sloc
(N
);
471 Exp
: constant Node_Id
:= Expression
(Expression
(N
));
472 PtrT
: constant Entity_Id
:= Etype
(N
);
473 DesigT
: constant Entity_Id
:= Designated_Type
(PtrT
);
475 procedure Apply_Accessibility_Check
477 Built_In_Place
: Boolean := False);
478 -- Ada 2005 (AI-344): For an allocator with a class-wide designated
479 -- type, generate an accessibility check to verify that the level of the
480 -- type of the created object is not deeper than the level of the access
481 -- type. If the type of the qualified expression is class- wide, then
482 -- always generate the check (except in the case where it is known to be
483 -- unnecessary, see comment below). Otherwise, only generate the check
484 -- if the level of the qualified expression type is statically deeper
485 -- than the access type.
487 -- Although the static accessibility will generally have been performed
488 -- as a legality check, it won't have been done in cases where the
489 -- allocator appears in generic body, so a run-time check is needed in
490 -- general. One special case is when the access type is declared in the
491 -- same scope as the class-wide allocator, in which case the check can
492 -- never fail, so it need not be generated.
494 -- As an open issue, there seem to be cases where the static level
495 -- associated with the class-wide object's underlying type is not
496 -- sufficient to perform the proper accessibility check, such as for
497 -- allocators in nested subprograms or accept statements initialized by
498 -- class-wide formals when the actual originates outside at a deeper
499 -- static level. The nested subprogram case might require passing
500 -- accessibility levels along with class-wide parameters, and the task
501 -- case seems to be an actual gap in the language rules that needs to
502 -- be fixed by the ARG. ???
504 -------------------------------
505 -- Apply_Accessibility_Check --
506 -------------------------------
508 procedure Apply_Accessibility_Check
510 Built_In_Place
: Boolean := False)
515 -- Note: we skip the accessibility check for the VM case, since
516 -- there does not seem to be any practical way of implementing it.
518 if Ada_Version
>= Ada_05
519 and then VM_Target
= No_VM
520 and then Is_Class_Wide_Type
(DesigT
)
521 and then not Scope_Suppress
(Accessibility_Check
)
523 (Type_Access_Level
(Etype
(Exp
)) > Type_Access_Level
(PtrT
)
525 (Is_Class_Wide_Type
(Etype
(Exp
))
526 and then Scope
(PtrT
) /= Current_Scope
))
528 -- If the allocator was built in place Ref is already a reference
529 -- to the access object initialized to the result of the allocator
530 -- (see Exp_Ch6.Make_Build_In_Place_Call_In_Allocator). Otherwise
531 -- it is the entity associated with the object containing the
532 -- address of the allocated object.
534 if Built_In_Place
then
535 Ref_Node
:= New_Copy
(Ref
);
537 Ref_Node
:= New_Reference_To
(Ref
, Loc
);
541 Make_Raise_Program_Error
(Loc
,
545 Build_Get_Access_Level
(Loc
,
546 Make_Attribute_Reference
(Loc
,
548 Attribute_Name
=> Name_Tag
)),
550 Make_Integer_Literal
(Loc
,
551 Type_Access_Level
(PtrT
))),
552 Reason
=> PE_Accessibility_Check_Failed
));
554 end Apply_Accessibility_Check
;
558 Indic
: constant Node_Id
:= Subtype_Mark
(Expression
(N
));
559 T
: constant Entity_Id
:= Entity
(Indic
);
564 TagT
: Entity_Id
:= Empty
;
565 -- Type used as source for tag assignment
567 TagR
: Node_Id
:= Empty
;
568 -- Target reference for tag assignment
570 Aggr_In_Place
: constant Boolean := Is_Delayed_Aggregate
(Exp
);
572 Tag_Assign
: Node_Id
;
575 -- Start of processing for Expand_Allocator_Expression
578 if Is_Tagged_Type
(T
) or else Needs_Finalization
(T
) then
580 -- Ada 2005 (AI-318-02): If the initialization expression is a call
581 -- to a build-in-place function, then access to the allocated object
582 -- must be passed to the function. Currently we limit such functions
583 -- to those with constrained limited result subtypes, but eventually
584 -- we plan to expand the allowed forms of functions that are treated
585 -- as build-in-place.
587 if Ada_Version
>= Ada_05
588 and then Is_Build_In_Place_Function_Call
(Exp
)
590 Make_Build_In_Place_Call_In_Allocator
(N
, Exp
);
591 Apply_Accessibility_Check
(N
, Built_In_Place
=> True);
595 -- Actions inserted before:
596 -- Temp : constant ptr_T := new T'(Expression);
597 -- <no CW> Temp._tag := T'tag;
598 -- <CTRL> Adjust (Finalizable (Temp.all));
599 -- <CTRL> Attach_To_Final_List (Finalizable (Temp.all));
601 -- We analyze by hand the new internal allocator to avoid
602 -- any recursion and inappropriate call to Initialize
604 -- We don't want to remove side effects when the expression must be
605 -- built in place. In the case of a build-in-place function call,
606 -- that could lead to a duplication of the call, which was already
607 -- substituted for the allocator.
609 if not Aggr_In_Place
then
610 Remove_Side_Effects
(Exp
);
614 Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
616 -- For a class wide allocation generate the following code:
618 -- type Equiv_Record is record ... end record;
619 -- implicit subtype CW is <Class_Wide_Subytpe>;
620 -- temp : PtrT := new CW'(CW!(expr));
622 if Is_Class_Wide_Type
(T
) then
623 Expand_Subtype_From_Expr
(Empty
, T
, Indic
, Exp
);
625 -- Ada 2005 (AI-251): If the expression is a class-wide interface
626 -- object we generate code to move up "this" to reference the
627 -- base of the object before allocating the new object.
629 -- Note that Exp'Address is recursively expanded into a call
630 -- to Base_Address (Exp.Tag)
632 if Is_Class_Wide_Type
(Etype
(Exp
))
633 and then Is_Interface
(Etype
(Exp
))
634 and then VM_Target
= No_VM
638 Unchecked_Convert_To
(Entity
(Indic
),
639 Make_Explicit_Dereference
(Loc
,
640 Unchecked_Convert_To
(RTE
(RE_Tag_Ptr
),
641 Make_Attribute_Reference
(Loc
,
643 Attribute_Name
=> Name_Address
)))));
648 Unchecked_Convert_To
(Entity
(Indic
), Exp
));
651 Analyze_And_Resolve
(Expression
(N
), Entity
(Indic
));
654 -- Keep separate the management of allocators returning interfaces
656 if not Is_Interface
(Directly_Designated_Type
(PtrT
)) then
657 if Aggr_In_Place
then
659 Make_Object_Declaration
(Loc
,
660 Defining_Identifier
=> Temp
,
661 Object_Definition
=> New_Reference_To
(PtrT
, Loc
),
664 New_Reference_To
(Etype
(Exp
), Loc
)));
666 Set_Comes_From_Source
667 (Expression
(Tmp_Node
), Comes_From_Source
(N
));
669 Set_No_Initialization
(Expression
(Tmp_Node
));
670 Insert_Action
(N
, Tmp_Node
);
672 if Needs_Finalization
(T
)
673 and then Ekind
(PtrT
) = E_Anonymous_Access_Type
675 -- Create local finalization list for access parameter
677 Flist
:= Get_Allocator_Final_List
(N
, Base_Type
(T
), PtrT
);
680 Convert_Aggr_In_Allocator
(N
, Tmp_Node
, Exp
);
682 Node
:= Relocate_Node
(N
);
685 Make_Object_Declaration
(Loc
,
686 Defining_Identifier
=> Temp
,
687 Constant_Present
=> True,
688 Object_Definition
=> New_Reference_To
(PtrT
, Loc
),
689 Expression
=> Node
));
692 -- Ada 2005 (AI-251): Handle allocators whose designated type is an
693 -- interface type. In this case we use the type of the qualified
694 -- expression to allocate the object.
698 Def_Id
: constant Entity_Id
:=
699 Make_Defining_Identifier
(Loc
,
700 New_Internal_Name
('T'));
705 Make_Full_Type_Declaration
(Loc
,
706 Defining_Identifier
=> Def_Id
,
708 Make_Access_To_Object_Definition
(Loc
,
710 Null_Exclusion_Present
=> False,
711 Constant_Present
=> False,
712 Subtype_Indication
=>
713 New_Reference_To
(Etype
(Exp
), Loc
)));
715 Insert_Action
(N
, New_Decl
);
717 -- Inherit the final chain to ensure that the expansion of the
718 -- aggregate is correct in case of controlled types
720 if Needs_Finalization
(Directly_Designated_Type
(PtrT
)) then
721 Set_Associated_Final_Chain
(Def_Id
,
722 Associated_Final_Chain
(PtrT
));
725 -- Declare the object using the previous type declaration
727 if Aggr_In_Place
then
729 Make_Object_Declaration
(Loc
,
730 Defining_Identifier
=> Temp
,
731 Object_Definition
=> New_Reference_To
(Def_Id
, Loc
),
734 New_Reference_To
(Etype
(Exp
), Loc
)));
736 Set_Comes_From_Source
737 (Expression
(Tmp_Node
), Comes_From_Source
(N
));
739 Set_No_Initialization
(Expression
(Tmp_Node
));
740 Insert_Action
(N
, Tmp_Node
);
742 if Needs_Finalization
(T
)
743 and then Ekind
(PtrT
) = E_Anonymous_Access_Type
745 -- Create local finalization list for access parameter
748 Get_Allocator_Final_List
(N
, Base_Type
(T
), PtrT
);
751 Convert_Aggr_In_Allocator
(N
, Tmp_Node
, Exp
);
753 Node
:= Relocate_Node
(N
);
756 Make_Object_Declaration
(Loc
,
757 Defining_Identifier
=> Temp
,
758 Constant_Present
=> True,
759 Object_Definition
=> New_Reference_To
(Def_Id
, Loc
),
760 Expression
=> Node
));
763 -- Generate an additional object containing the address of the
764 -- returned object. The type of this second object declaration
765 -- is the correct type required for the common processing that
766 -- is still performed by this subprogram. The displacement of
767 -- this pointer to reference the component associated with the
768 -- interface type will be done at the end of common processing.
771 Make_Object_Declaration
(Loc
,
772 Defining_Identifier
=> Make_Defining_Identifier
(Loc
,
773 New_Internal_Name
('P')),
774 Object_Definition
=> New_Reference_To
(PtrT
, Loc
),
775 Expression
=> Unchecked_Convert_To
(PtrT
,
776 New_Reference_To
(Temp
, Loc
)));
778 Insert_Action
(N
, New_Decl
);
780 Tmp_Node
:= New_Decl
;
781 Temp
:= Defining_Identifier
(New_Decl
);
785 Apply_Accessibility_Check
(Temp
);
787 -- Generate the tag assignment
789 -- Suppress the tag assignment when VM_Target because VM tags are
790 -- represented implicitly in objects.
792 if VM_Target
/= No_VM
then
795 -- Ada 2005 (AI-251): Suppress the tag assignment with class-wide
796 -- interface objects because in this case the tag does not change.
798 elsif Is_Interface
(Directly_Designated_Type
(Etype
(N
))) then
799 pragma Assert
(Is_Class_Wide_Type
800 (Directly_Designated_Type
(Etype
(N
))));
803 elsif Is_Tagged_Type
(T
) and then not Is_Class_Wide_Type
(T
) then
805 TagR
:= New_Reference_To
(Temp
, Loc
);
807 elsif Is_Private_Type
(T
)
808 and then Is_Tagged_Type
(Underlying_Type
(T
))
810 TagT
:= Underlying_Type
(T
);
812 Unchecked_Convert_To
(Underlying_Type
(T
),
813 Make_Explicit_Dereference
(Loc
,
814 Prefix
=> New_Reference_To
(Temp
, Loc
)));
817 if Present
(TagT
) then
819 Make_Assignment_Statement
(Loc
,
821 Make_Selected_Component
(Loc
,
824 New_Reference_To
(First_Tag_Component
(TagT
), Loc
)),
827 Unchecked_Convert_To
(RTE
(RE_Tag
),
829 (Elists
.Node
(First_Elmt
(Access_Disp_Table
(TagT
))),
832 -- The previous assignment has to be done in any case
834 Set_Assignment_OK
(Name
(Tag_Assign
));
835 Insert_Action
(N
, Tag_Assign
);
838 if Needs_Finalization
(DesigT
)
839 and then Needs_Finalization
(T
)
843 Apool
: constant Entity_Id
:=
844 Associated_Storage_Pool
(PtrT
);
847 -- If it is an allocation on the secondary stack (i.e. a value
848 -- returned from a function), the object is attached on the
849 -- caller side as soon as the call is completed (see
850 -- Expand_Ctrl_Function_Call)
852 if Is_RTE
(Apool
, RE_SS_Pool
) then
854 F
: constant Entity_Id
:=
855 Make_Defining_Identifier
(Loc
,
856 New_Internal_Name
('F'));
859 Make_Object_Declaration
(Loc
,
860 Defining_Identifier
=> F
,
861 Object_Definition
=> New_Reference_To
(RTE
862 (RE_Finalizable_Ptr
), Loc
)));
864 Flist
:= New_Reference_To
(F
, Loc
);
865 Attach
:= Make_Integer_Literal
(Loc
, 1);
868 -- Normal case, not a secondary stack allocation
871 if Needs_Finalization
(T
)
872 and then Ekind
(PtrT
) = E_Anonymous_Access_Type
874 -- Create local finalization list for access parameter
877 Get_Allocator_Final_List
(N
, Base_Type
(T
), PtrT
);
879 Flist
:= Find_Final_List
(PtrT
);
882 Attach
:= Make_Integer_Literal
(Loc
, 2);
885 -- Generate an Adjust call if the object will be moved. In Ada
886 -- 2005, the object may be inherently limited, in which case
887 -- there is no Adjust procedure, and the object is built in
888 -- place. In Ada 95, the object can be limited but not
889 -- inherently limited if this allocator came from a return
890 -- statement (we're allocating the result on the secondary
891 -- stack). In that case, the object will be moved, so we _do_
895 and then not Is_Inherently_Limited_Type
(T
)
901 -- An unchecked conversion is needed in the classwide
902 -- case because the designated type can be an ancestor of
903 -- the subtype mark of the allocator.
905 Unchecked_Convert_To
(T
,
906 Make_Explicit_Dereference
(Loc
,
907 Prefix
=> New_Reference_To
(Temp
, Loc
))),
911 With_Attach
=> Attach
,
917 Rewrite
(N
, New_Reference_To
(Temp
, Loc
));
918 Analyze_And_Resolve
(N
, PtrT
);
920 -- Ada 2005 (AI-251): Displace the pointer to reference the record
921 -- component containing the secondary dispatch table of the interface
924 if Is_Interface
(Directly_Designated_Type
(PtrT
)) then
925 Displace_Allocator_Pointer
(N
);
928 elsif Aggr_In_Place
then
930 Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
932 Make_Object_Declaration
(Loc
,
933 Defining_Identifier
=> Temp
,
934 Object_Definition
=> New_Reference_To
(PtrT
, Loc
),
935 Expression
=> Make_Allocator
(Loc
,
936 New_Reference_To
(Etype
(Exp
), Loc
)));
938 Set_Comes_From_Source
939 (Expression
(Tmp_Node
), Comes_From_Source
(N
));
941 Set_No_Initialization
(Expression
(Tmp_Node
));
942 Insert_Action
(N
, Tmp_Node
);
943 Convert_Aggr_In_Allocator
(N
, Tmp_Node
, Exp
);
944 Rewrite
(N
, New_Reference_To
(Temp
, Loc
));
945 Analyze_And_Resolve
(N
, PtrT
);
947 elsif Is_Access_Type
(T
)
948 and then Can_Never_Be_Null
(T
)
950 Install_Null_Excluding_Check
(Exp
);
952 elsif Is_Access_Type
(DesigT
)
953 and then Nkind
(Exp
) = N_Allocator
954 and then Nkind
(Expression
(Exp
)) /= N_Qualified_Expression
956 -- Apply constraint to designated subtype indication
958 Apply_Constraint_Check
(Expression
(Exp
),
959 Designated_Type
(DesigT
),
962 if Nkind
(Expression
(Exp
)) = N_Raise_Constraint_Error
then
964 -- Propagate constraint_error to enclosing allocator
966 Rewrite
(Exp
, New_Copy
(Expression
(Exp
)));
969 -- First check against the type of the qualified expression
971 -- NOTE: The commented call should be correct, but for some reason
972 -- causes the compiler to bomb (sigsegv) on ACVC test c34007g, so for
973 -- now we just perform the old (incorrect) test against the
974 -- designated subtype with no sliding in the else part of the if
975 -- statement below. ???
977 -- Apply_Constraint_Check (Exp, T, No_Sliding => True);
979 -- A check is also needed in cases where the designated subtype is
980 -- constrained and differs from the subtype given in the qualified
981 -- expression. Note that the check on the qualified expression does
982 -- not allow sliding, but this check does (a relaxation from Ada 83).
984 if Is_Constrained
(DesigT
)
985 and then not Subtypes_Statically_Match
(T
, DesigT
)
987 Apply_Constraint_Check
988 (Exp
, DesigT
, No_Sliding
=> False);
990 -- The nonsliding check should really be performed (unconditionally)
991 -- against the subtype of the qualified expression, but that causes a
992 -- problem with c34007g (see above), so for now we retain this.
995 Apply_Constraint_Check
996 (Exp
, DesigT
, No_Sliding
=> True);
999 -- For an access to unconstrained packed array, GIGI needs to see an
1000 -- expression with a constrained subtype in order to compute the
1001 -- proper size for the allocator.
1003 if Is_Array_Type
(T
)
1004 and then not Is_Constrained
(T
)
1005 and then Is_Packed
(T
)
1008 ConstrT
: constant Entity_Id
:=
1009 Make_Defining_Identifier
(Loc
,
1010 Chars
=> New_Internal_Name
('A'));
1011 Internal_Exp
: constant Node_Id
:= Relocate_Node
(Exp
);
1014 Make_Subtype_Declaration
(Loc
,
1015 Defining_Identifier
=> ConstrT
,
1016 Subtype_Indication
=>
1017 Make_Subtype_From_Expr
(Exp
, T
)));
1018 Freeze_Itype
(ConstrT
, Exp
);
1019 Rewrite
(Exp
, OK_Convert_To
(ConstrT
, Internal_Exp
));
1023 -- Ada 2005 (AI-318-02): If the initialization expression is a call
1024 -- to a build-in-place function, then access to the allocated object
1025 -- must be passed to the function. Currently we limit such functions
1026 -- to those with constrained limited result subtypes, but eventually
1027 -- we plan to expand the allowed forms of functions that are treated
1028 -- as build-in-place.
1030 if Ada_Version
>= Ada_05
1031 and then Is_Build_In_Place_Function_Call
(Exp
)
1033 Make_Build_In_Place_Call_In_Allocator
(N
, Exp
);
1038 when RE_Not_Available
=>
1040 end Expand_Allocator_Expression
;
1042 -----------------------------
1043 -- Expand_Array_Comparison --
1044 -----------------------------
1046 -- Expansion is only required in the case of array types. For the unpacked
1047 -- case, an appropriate runtime routine is called. For packed cases, and
1048 -- also in some other cases where a runtime routine cannot be called, the
1049 -- form of the expansion is:
1051 -- [body for greater_nn; boolean_expression]
1053 -- The body is built by Make_Array_Comparison_Op, and the form of the
1054 -- Boolean expression depends on the operator involved.
1056 procedure Expand_Array_Comparison
(N
: Node_Id
) is
1057 Loc
: constant Source_Ptr
:= Sloc
(N
);
1058 Op1
: Node_Id
:= Left_Opnd
(N
);
1059 Op2
: Node_Id
:= Right_Opnd
(N
);
1060 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
1061 Ctyp
: constant Entity_Id
:= Component_Type
(Typ1
);
1064 Func_Body
: Node_Id
;
1065 Func_Name
: Entity_Id
;
1069 Byte_Addressable
: constant Boolean := System_Storage_Unit
= Byte
'Size;
1070 -- True for byte addressable target
1072 function Length_Less_Than_4
(Opnd
: Node_Id
) return Boolean;
1073 -- Returns True if the length of the given operand is known to be less
1074 -- than 4. Returns False if this length is known to be four or greater
1075 -- or is not known at compile time.
1077 ------------------------
1078 -- Length_Less_Than_4 --
1079 ------------------------
1081 function Length_Less_Than_4
(Opnd
: Node_Id
) return Boolean is
1082 Otyp
: constant Entity_Id
:= Etype
(Opnd
);
1085 if Ekind
(Otyp
) = E_String_Literal_Subtype
then
1086 return String_Literal_Length
(Otyp
) < 4;
1090 Ityp
: constant Entity_Id
:= Etype
(First_Index
(Otyp
));
1091 Lo
: constant Node_Id
:= Type_Low_Bound
(Ityp
);
1092 Hi
: constant Node_Id
:= Type_High_Bound
(Ityp
);
1097 if Compile_Time_Known_Value
(Lo
) then
1098 Lov
:= Expr_Value
(Lo
);
1103 if Compile_Time_Known_Value
(Hi
) then
1104 Hiv
:= Expr_Value
(Hi
);
1109 return Hiv
< Lov
+ 3;
1112 end Length_Less_Than_4
;
1114 -- Start of processing for Expand_Array_Comparison
1117 -- Deal first with unpacked case, where we can call a runtime routine
1118 -- except that we avoid this for targets for which are not addressable
1119 -- by bytes, and for the JVM/CIL, since they do not support direct
1120 -- addressing of array components.
1122 if not Is_Bit_Packed_Array
(Typ1
)
1123 and then Byte_Addressable
1124 and then VM_Target
= No_VM
1126 -- The call we generate is:
1128 -- Compare_Array_xn[_Unaligned]
1129 -- (left'address, right'address, left'length, right'length) <op> 0
1131 -- x = U for unsigned, S for signed
1132 -- n = 8,16,32,64 for component size
1133 -- Add _Unaligned if length < 4 and component size is 8.
1134 -- <op> is the standard comparison operator
1136 if Component_Size
(Typ1
) = 8 then
1137 if Length_Less_Than_4
(Op1
)
1139 Length_Less_Than_4
(Op2
)
1141 if Is_Unsigned_Type
(Ctyp
) then
1142 Comp
:= RE_Compare_Array_U8_Unaligned
;
1144 Comp
:= RE_Compare_Array_S8_Unaligned
;
1148 if Is_Unsigned_Type
(Ctyp
) then
1149 Comp
:= RE_Compare_Array_U8
;
1151 Comp
:= RE_Compare_Array_S8
;
1155 elsif Component_Size
(Typ1
) = 16 then
1156 if Is_Unsigned_Type
(Ctyp
) then
1157 Comp
:= RE_Compare_Array_U16
;
1159 Comp
:= RE_Compare_Array_S16
;
1162 elsif Component_Size
(Typ1
) = 32 then
1163 if Is_Unsigned_Type
(Ctyp
) then
1164 Comp
:= RE_Compare_Array_U32
;
1166 Comp
:= RE_Compare_Array_S32
;
1169 else pragma Assert
(Component_Size
(Typ1
) = 64);
1170 if Is_Unsigned_Type
(Ctyp
) then
1171 Comp
:= RE_Compare_Array_U64
;
1173 Comp
:= RE_Compare_Array_S64
;
1177 Remove_Side_Effects
(Op1
, Name_Req
=> True);
1178 Remove_Side_Effects
(Op2
, Name_Req
=> True);
1181 Make_Function_Call
(Sloc
(Op1
),
1182 Name
=> New_Occurrence_Of
(RTE
(Comp
), Loc
),
1184 Parameter_Associations
=> New_List
(
1185 Make_Attribute_Reference
(Loc
,
1186 Prefix
=> Relocate_Node
(Op1
),
1187 Attribute_Name
=> Name_Address
),
1189 Make_Attribute_Reference
(Loc
,
1190 Prefix
=> Relocate_Node
(Op2
),
1191 Attribute_Name
=> Name_Address
),
1193 Make_Attribute_Reference
(Loc
,
1194 Prefix
=> Relocate_Node
(Op1
),
1195 Attribute_Name
=> Name_Length
),
1197 Make_Attribute_Reference
(Loc
,
1198 Prefix
=> Relocate_Node
(Op2
),
1199 Attribute_Name
=> Name_Length
))));
1202 Make_Integer_Literal
(Sloc
(Op2
),
1205 Analyze_And_Resolve
(Op1
, Standard_Integer
);
1206 Analyze_And_Resolve
(Op2
, Standard_Integer
);
1210 -- Cases where we cannot make runtime call
1212 -- For (a <= b) we convert to not (a > b)
1214 if Chars
(N
) = Name_Op_Le
then
1220 Right_Opnd
=> Op2
)));
1221 Analyze_And_Resolve
(N
, Standard_Boolean
);
1224 -- For < the Boolean expression is
1225 -- greater__nn (op2, op1)
1227 elsif Chars
(N
) = Name_Op_Lt
then
1228 Func_Body
:= Make_Array_Comparison_Op
(Typ1
, N
);
1232 Op1
:= Right_Opnd
(N
);
1233 Op2
:= Left_Opnd
(N
);
1235 -- For (a >= b) we convert to not (a < b)
1237 elsif Chars
(N
) = Name_Op_Ge
then
1243 Right_Opnd
=> Op2
)));
1244 Analyze_And_Resolve
(N
, Standard_Boolean
);
1247 -- For > the Boolean expression is
1248 -- greater__nn (op1, op2)
1251 pragma Assert
(Chars
(N
) = Name_Op_Gt
);
1252 Func_Body
:= Make_Array_Comparison_Op
(Typ1
, N
);
1255 Func_Name
:= Defining_Unit_Name
(Specification
(Func_Body
));
1257 Make_Function_Call
(Loc
,
1258 Name
=> New_Reference_To
(Func_Name
, Loc
),
1259 Parameter_Associations
=> New_List
(Op1
, Op2
));
1261 Insert_Action
(N
, Func_Body
);
1263 Analyze_And_Resolve
(N
, Standard_Boolean
);
1266 when RE_Not_Available
=>
1268 end Expand_Array_Comparison
;
1270 ---------------------------
1271 -- Expand_Array_Equality --
1272 ---------------------------
1274 -- Expand an equality function for multi-dimensional arrays. Here is an
1275 -- example of such a function for Nb_Dimension = 2
1277 -- function Enn (A : atyp; B : btyp) return boolean is
1279 -- if (A'length (1) = 0 or else A'length (2) = 0)
1281 -- (B'length (1) = 0 or else B'length (2) = 0)
1283 -- return True; -- RM 4.5.2(22)
1286 -- if A'length (1) /= B'length (1)
1288 -- A'length (2) /= B'length (2)
1290 -- return False; -- RM 4.5.2(23)
1294 -- A1 : Index_T1 := A'first (1);
1295 -- B1 : Index_T1 := B'first (1);
1299 -- A2 : Index_T2 := A'first (2);
1300 -- B2 : Index_T2 := B'first (2);
1303 -- if A (A1, A2) /= B (B1, B2) then
1307 -- exit when A2 = A'last (2);
1308 -- A2 := Index_T2'succ (A2);
1309 -- B2 := Index_T2'succ (B2);
1313 -- exit when A1 = A'last (1);
1314 -- A1 := Index_T1'succ (A1);
1315 -- B1 := Index_T1'succ (B1);
1322 -- Note on the formal types used (atyp and btyp). If either of the arrays
1323 -- is of a private type, we use the underlying type, and do an unchecked
1324 -- conversion of the actual. If either of the arrays has a bound depending
1325 -- on a discriminant, then we use the base type since otherwise we have an
1326 -- escaped discriminant in the function.
1328 -- If both arrays are constrained and have the same bounds, we can generate
1329 -- a loop with an explicit iteration scheme using a 'Range attribute over
1332 function Expand_Array_Equality
1337 Typ
: Entity_Id
) return Node_Id
1339 Loc
: constant Source_Ptr
:= Sloc
(Nod
);
1340 Decls
: constant List_Id
:= New_List
;
1341 Index_List1
: constant List_Id
:= New_List
;
1342 Index_List2
: constant List_Id
:= New_List
;
1346 Func_Name
: Entity_Id
;
1347 Func_Body
: Node_Id
;
1349 A
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uA
);
1350 B
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uB
);
1354 -- The parameter types to be used for the formals
1359 Num
: Int
) return Node_Id
;
1360 -- This builds the attribute reference Arr'Nam (Expr)
1362 function Component_Equality
(Typ
: Entity_Id
) return Node_Id
;
1363 -- Create one statement to compare corresponding components, designated
1364 -- by a full set of indices.
1366 function Get_Arg_Type
(N
: Node_Id
) return Entity_Id
;
1367 -- Given one of the arguments, computes the appropriate type to be used
1368 -- for that argument in the corresponding function formal
1370 function Handle_One_Dimension
1372 Index
: Node_Id
) return Node_Id
;
1373 -- This procedure returns the following code
1376 -- Bn : Index_T := B'First (N);
1380 -- exit when An = A'Last (N);
1381 -- An := Index_T'Succ (An)
1382 -- Bn := Index_T'Succ (Bn)
1386 -- If both indices are constrained and identical, the procedure
1387 -- returns a simpler loop:
1389 -- for An in A'Range (N) loop
1393 -- N is the dimension for which we are generating a loop. Index is the
1394 -- N'th index node, whose Etype is Index_Type_n in the above code. The
1395 -- xxx statement is either the loop or declare for the next dimension
1396 -- or if this is the last dimension the comparison of corresponding
1397 -- components of the arrays.
1399 -- The actual way the code works is to return the comparison of
1400 -- corresponding components for the N+1 call. That's neater!
1402 function Test_Empty_Arrays
return Node_Id
;
1403 -- This function constructs the test for both arrays being empty
1404 -- (A'length (1) = 0 or else A'length (2) = 0 or else ...)
1406 -- (B'length (1) = 0 or else B'length (2) = 0 or else ...)
1408 function Test_Lengths_Correspond
return Node_Id
;
1409 -- This function constructs the test for arrays having different lengths
1410 -- in at least one index position, in which case the resulting code is:
1412 -- A'length (1) /= B'length (1)
1414 -- A'length (2) /= B'length (2)
1425 Num
: Int
) return Node_Id
1429 Make_Attribute_Reference
(Loc
,
1430 Attribute_Name
=> Nam
,
1431 Prefix
=> New_Reference_To
(Arr
, Loc
),
1432 Expressions
=> New_List
(Make_Integer_Literal
(Loc
, Num
)));
1435 ------------------------
1436 -- Component_Equality --
1437 ------------------------
1439 function Component_Equality
(Typ
: Entity_Id
) return Node_Id
is
1444 -- if a(i1...) /= b(j1...) then return false; end if;
1447 Make_Indexed_Component
(Loc
,
1448 Prefix
=> Make_Identifier
(Loc
, Chars
(A
)),
1449 Expressions
=> Index_List1
);
1452 Make_Indexed_Component
(Loc
,
1453 Prefix
=> Make_Identifier
(Loc
, Chars
(B
)),
1454 Expressions
=> Index_List2
);
1456 Test
:= Expand_Composite_Equality
1457 (Nod
, Component_Type
(Typ
), L
, R
, Decls
);
1459 -- If some (sub)component is an unchecked_union, the whole operation
1460 -- will raise program error.
1462 if Nkind
(Test
) = N_Raise_Program_Error
then
1464 -- This node is going to be inserted at a location where a
1465 -- statement is expected: clear its Etype so analysis will set
1466 -- it to the expected Standard_Void_Type.
1468 Set_Etype
(Test
, Empty
);
1473 Make_Implicit_If_Statement
(Nod
,
1474 Condition
=> Make_Op_Not
(Loc
, Right_Opnd
=> Test
),
1475 Then_Statements
=> New_List
(
1476 Make_Simple_Return_Statement
(Loc
,
1477 Expression
=> New_Occurrence_Of
(Standard_False
, Loc
))));
1479 end Component_Equality
;
1485 function Get_Arg_Type
(N
: Node_Id
) return Entity_Id
is
1496 T
:= Underlying_Type
(T
);
1498 X
:= First_Index
(T
);
1499 while Present
(X
) loop
1500 if Denotes_Discriminant
(Type_Low_Bound
(Etype
(X
)))
1502 Denotes_Discriminant
(Type_High_Bound
(Etype
(X
)))
1515 --------------------------
1516 -- Handle_One_Dimension --
1517 ---------------------------
1519 function Handle_One_Dimension
1521 Index
: Node_Id
) return Node_Id
1523 Need_Separate_Indexes
: constant Boolean :=
1525 or else not Is_Constrained
(Ltyp
);
1526 -- If the index types are identical, and we are working with
1527 -- constrained types, then we can use the same index for both
1530 An
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
,
1531 Chars
=> New_Internal_Name
('A'));
1534 Index_T
: Entity_Id
;
1539 if N
> Number_Dimensions
(Ltyp
) then
1540 return Component_Equality
(Ltyp
);
1543 -- Case where we generate a loop
1545 Index_T
:= Base_Type
(Etype
(Index
));
1547 if Need_Separate_Indexes
then
1549 Make_Defining_Identifier
(Loc
,
1550 Chars
=> New_Internal_Name
('B'));
1555 Append
(New_Reference_To
(An
, Loc
), Index_List1
);
1556 Append
(New_Reference_To
(Bn
, Loc
), Index_List2
);
1558 Stm_List
:= New_List
(
1559 Handle_One_Dimension
(N
+ 1, Next_Index
(Index
)));
1561 if Need_Separate_Indexes
then
1563 -- Generate guard for loop, followed by increments of indices
1565 Append_To
(Stm_List
,
1566 Make_Exit_Statement
(Loc
,
1569 Left_Opnd
=> New_Reference_To
(An
, Loc
),
1570 Right_Opnd
=> Arr_Attr
(A
, Name_Last
, N
))));
1572 Append_To
(Stm_List
,
1573 Make_Assignment_Statement
(Loc
,
1574 Name
=> New_Reference_To
(An
, Loc
),
1576 Make_Attribute_Reference
(Loc
,
1577 Prefix
=> New_Reference_To
(Index_T
, Loc
),
1578 Attribute_Name
=> Name_Succ
,
1579 Expressions
=> New_List
(New_Reference_To
(An
, Loc
)))));
1581 Append_To
(Stm_List
,
1582 Make_Assignment_Statement
(Loc
,
1583 Name
=> New_Reference_To
(Bn
, Loc
),
1585 Make_Attribute_Reference
(Loc
,
1586 Prefix
=> New_Reference_To
(Index_T
, Loc
),
1587 Attribute_Name
=> Name_Succ
,
1588 Expressions
=> New_List
(New_Reference_To
(Bn
, Loc
)))));
1591 -- If separate indexes, we need a declare block for An and Bn, and a
1592 -- loop without an iteration scheme.
1594 if Need_Separate_Indexes
then
1596 Make_Implicit_Loop_Statement
(Nod
, Statements
=> Stm_List
);
1599 Make_Block_Statement
(Loc
,
1600 Declarations
=> New_List
(
1601 Make_Object_Declaration
(Loc
,
1602 Defining_Identifier
=> An
,
1603 Object_Definition
=> New_Reference_To
(Index_T
, Loc
),
1604 Expression
=> Arr_Attr
(A
, Name_First
, N
)),
1606 Make_Object_Declaration
(Loc
,
1607 Defining_Identifier
=> Bn
,
1608 Object_Definition
=> New_Reference_To
(Index_T
, Loc
),
1609 Expression
=> Arr_Attr
(B
, Name_First
, N
))),
1611 Handled_Statement_Sequence
=>
1612 Make_Handled_Sequence_Of_Statements
(Loc
,
1613 Statements
=> New_List
(Loop_Stm
)));
1615 -- If no separate indexes, return loop statement with explicit
1616 -- iteration scheme on its own
1620 Make_Implicit_Loop_Statement
(Nod
,
1621 Statements
=> Stm_List
,
1623 Make_Iteration_Scheme
(Loc
,
1624 Loop_Parameter_Specification
=>
1625 Make_Loop_Parameter_Specification
(Loc
,
1626 Defining_Identifier
=> An
,
1627 Discrete_Subtype_Definition
=>
1628 Arr_Attr
(A
, Name_Range
, N
))));
1631 end Handle_One_Dimension
;
1633 -----------------------
1634 -- Test_Empty_Arrays --
1635 -----------------------
1637 function Test_Empty_Arrays
return Node_Id
is
1647 for J
in 1 .. Number_Dimensions
(Ltyp
) loop
1650 Left_Opnd
=> Arr_Attr
(A
, Name_Length
, J
),
1651 Right_Opnd
=> Make_Integer_Literal
(Loc
, 0));
1655 Left_Opnd
=> Arr_Attr
(B
, Name_Length
, J
),
1656 Right_Opnd
=> Make_Integer_Literal
(Loc
, 0));
1665 Left_Opnd
=> Relocate_Node
(Alist
),
1666 Right_Opnd
=> Atest
);
1670 Left_Opnd
=> Relocate_Node
(Blist
),
1671 Right_Opnd
=> Btest
);
1678 Right_Opnd
=> Blist
);
1679 end Test_Empty_Arrays
;
1681 -----------------------------
1682 -- Test_Lengths_Correspond --
1683 -----------------------------
1685 function Test_Lengths_Correspond
return Node_Id
is
1691 for J
in 1 .. Number_Dimensions
(Ltyp
) loop
1694 Left_Opnd
=> Arr_Attr
(A
, Name_Length
, J
),
1695 Right_Opnd
=> Arr_Attr
(B
, Name_Length
, J
));
1702 Left_Opnd
=> Relocate_Node
(Result
),
1703 Right_Opnd
=> Rtest
);
1708 end Test_Lengths_Correspond
;
1710 -- Start of processing for Expand_Array_Equality
1713 Ltyp
:= Get_Arg_Type
(Lhs
);
1714 Rtyp
:= Get_Arg_Type
(Rhs
);
1716 -- For now, if the argument types are not the same, go to the base type,
1717 -- since the code assumes that the formals have the same type. This is
1718 -- fixable in future ???
1720 if Ltyp
/= Rtyp
then
1721 Ltyp
:= Base_Type
(Ltyp
);
1722 Rtyp
:= Base_Type
(Rtyp
);
1723 pragma Assert
(Ltyp
= Rtyp
);
1726 -- Build list of formals for function
1728 Formals
:= New_List
(
1729 Make_Parameter_Specification
(Loc
,
1730 Defining_Identifier
=> A
,
1731 Parameter_Type
=> New_Reference_To
(Ltyp
, Loc
)),
1733 Make_Parameter_Specification
(Loc
,
1734 Defining_Identifier
=> B
,
1735 Parameter_Type
=> New_Reference_To
(Rtyp
, Loc
)));
1737 Func_Name
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('E'));
1739 -- Build statement sequence for function
1742 Make_Subprogram_Body
(Loc
,
1744 Make_Function_Specification
(Loc
,
1745 Defining_Unit_Name
=> Func_Name
,
1746 Parameter_Specifications
=> Formals
,
1747 Result_Definition
=> New_Reference_To
(Standard_Boolean
, Loc
)),
1749 Declarations
=> Decls
,
1751 Handled_Statement_Sequence
=>
1752 Make_Handled_Sequence_Of_Statements
(Loc
,
1753 Statements
=> New_List
(
1755 Make_Implicit_If_Statement
(Nod
,
1756 Condition
=> Test_Empty_Arrays
,
1757 Then_Statements
=> New_List
(
1758 Make_Simple_Return_Statement
(Loc
,
1760 New_Occurrence_Of
(Standard_True
, Loc
)))),
1762 Make_Implicit_If_Statement
(Nod
,
1763 Condition
=> Test_Lengths_Correspond
,
1764 Then_Statements
=> New_List
(
1765 Make_Simple_Return_Statement
(Loc
,
1767 New_Occurrence_Of
(Standard_False
, Loc
)))),
1769 Handle_One_Dimension
(1, First_Index
(Ltyp
)),
1771 Make_Simple_Return_Statement
(Loc
,
1772 Expression
=> New_Occurrence_Of
(Standard_True
, Loc
)))));
1774 Set_Has_Completion
(Func_Name
, True);
1775 Set_Is_Inlined
(Func_Name
);
1777 -- If the array type is distinct from the type of the arguments, it
1778 -- is the full view of a private type. Apply an unchecked conversion
1779 -- to insure that analysis of the call succeeds.
1789 or else Base_Type
(Etype
(Lhs
)) /= Base_Type
(Ltyp
)
1791 L
:= OK_Convert_To
(Ltyp
, Lhs
);
1795 or else Base_Type
(Etype
(Rhs
)) /= Base_Type
(Rtyp
)
1797 R
:= OK_Convert_To
(Rtyp
, Rhs
);
1800 Actuals
:= New_List
(L
, R
);
1803 Append_To
(Bodies
, Func_Body
);
1806 Make_Function_Call
(Loc
,
1807 Name
=> New_Reference_To
(Func_Name
, Loc
),
1808 Parameter_Associations
=> Actuals
);
1809 end Expand_Array_Equality
;
1811 -----------------------------
1812 -- Expand_Boolean_Operator --
1813 -----------------------------
1815 -- Note that we first get the actual subtypes of the operands, since we
1816 -- always want to deal with types that have bounds.
1818 procedure Expand_Boolean_Operator
(N
: Node_Id
) is
1819 Typ
: constant Entity_Id
:= Etype
(N
);
1822 -- Special case of bit packed array where both operands are known to be
1823 -- properly aligned. In this case we use an efficient run time routine
1824 -- to carry out the operation (see System.Bit_Ops).
1826 if Is_Bit_Packed_Array
(Typ
)
1827 and then not Is_Possibly_Unaligned_Object
(Left_Opnd
(N
))
1828 and then not Is_Possibly_Unaligned_Object
(Right_Opnd
(N
))
1830 Expand_Packed_Boolean_Operator
(N
);
1834 -- For the normal non-packed case, the general expansion is to build
1835 -- function for carrying out the comparison (use Make_Boolean_Array_Op)
1836 -- and then inserting it into the tree. The original operator node is
1837 -- then rewritten as a call to this function. We also use this in the
1838 -- packed case if either operand is a possibly unaligned object.
1841 Loc
: constant Source_Ptr
:= Sloc
(N
);
1842 L
: constant Node_Id
:= Relocate_Node
(Left_Opnd
(N
));
1843 R
: constant Node_Id
:= Relocate_Node
(Right_Opnd
(N
));
1844 Func_Body
: Node_Id
;
1845 Func_Name
: Entity_Id
;
1848 Convert_To_Actual_Subtype
(L
);
1849 Convert_To_Actual_Subtype
(R
);
1850 Ensure_Defined
(Etype
(L
), N
);
1851 Ensure_Defined
(Etype
(R
), N
);
1852 Apply_Length_Check
(R
, Etype
(L
));
1854 if Nkind
(N
) = N_Op_Xor
then
1855 Silly_Boolean_Array_Xor_Test
(N
, Etype
(L
));
1858 if Nkind
(Parent
(N
)) = N_Assignment_Statement
1859 and then Safe_In_Place_Array_Op
(Name
(Parent
(N
)), L
, R
)
1861 Build_Boolean_Array_Proc_Call
(Parent
(N
), L
, R
);
1863 elsif Nkind
(Parent
(N
)) = N_Op_Not
1864 and then Nkind
(N
) = N_Op_And
1866 Safe_In_Place_Array_Op
(Name
(Parent
(Parent
(N
))), L
, R
)
1871 Func_Body
:= Make_Boolean_Array_Op
(Etype
(L
), N
);
1872 Func_Name
:= Defining_Unit_Name
(Specification
(Func_Body
));
1873 Insert_Action
(N
, Func_Body
);
1875 -- Now rewrite the expression with a call
1878 Make_Function_Call
(Loc
,
1879 Name
=> New_Reference_To
(Func_Name
, Loc
),
1880 Parameter_Associations
=>
1883 Make_Type_Conversion
1884 (Loc
, New_Reference_To
(Etype
(L
), Loc
), R
))));
1886 Analyze_And_Resolve
(N
, Typ
);
1889 end Expand_Boolean_Operator
;
1891 -------------------------------
1892 -- Expand_Composite_Equality --
1893 -------------------------------
1895 -- This function is only called for comparing internal fields of composite
1896 -- types when these fields are themselves composites. This is a special
1897 -- case because it is not possible to respect normal Ada visibility rules.
1899 function Expand_Composite_Equality
1904 Bodies
: List_Id
) return Node_Id
1906 Loc
: constant Source_Ptr
:= Sloc
(Nod
);
1907 Full_Type
: Entity_Id
;
1912 if Is_Private_Type
(Typ
) then
1913 Full_Type
:= Underlying_Type
(Typ
);
1918 -- Defense against malformed private types with no completion the error
1919 -- will be diagnosed later by check_completion
1921 if No
(Full_Type
) then
1922 return New_Reference_To
(Standard_False
, Loc
);
1925 Full_Type
:= Base_Type
(Full_Type
);
1927 if Is_Array_Type
(Full_Type
) then
1929 -- If the operand is an elementary type other than a floating-point
1930 -- type, then we can simply use the built-in block bitwise equality,
1931 -- since the predefined equality operators always apply and bitwise
1932 -- equality is fine for all these cases.
1934 if Is_Elementary_Type
(Component_Type
(Full_Type
))
1935 and then not Is_Floating_Point_Type
(Component_Type
(Full_Type
))
1937 return Make_Op_Eq
(Loc
, Left_Opnd
=> Lhs
, Right_Opnd
=> Rhs
);
1939 -- For composite component types, and floating-point types, use the
1940 -- expansion. This deals with tagged component types (where we use
1941 -- the applicable equality routine) and floating-point, (where we
1942 -- need to worry about negative zeroes), and also the case of any
1943 -- composite type recursively containing such fields.
1946 return Expand_Array_Equality
(Nod
, Lhs
, Rhs
, Bodies
, Full_Type
);
1949 elsif Is_Tagged_Type
(Full_Type
) then
1951 -- Call the primitive operation "=" of this type
1953 if Is_Class_Wide_Type
(Full_Type
) then
1954 Full_Type
:= Root_Type
(Full_Type
);
1957 -- If this is derived from an untagged private type completed with a
1958 -- tagged type, it does not have a full view, so we use the primitive
1959 -- operations of the private type. This check should no longer be
1960 -- necessary when these types receive their full views ???
1962 if Is_Private_Type
(Typ
)
1963 and then not Is_Tagged_Type
(Typ
)
1964 and then not Is_Controlled
(Typ
)
1965 and then Is_Derived_Type
(Typ
)
1966 and then No
(Full_View
(Typ
))
1968 Prim
:= First_Elmt
(Collect_Primitive_Operations
(Typ
));
1970 Prim
:= First_Elmt
(Primitive_Operations
(Full_Type
));
1974 Eq_Op
:= Node
(Prim
);
1975 exit when Chars
(Eq_Op
) = Name_Op_Eq
1976 and then Etype
(First_Formal
(Eq_Op
)) =
1977 Etype
(Next_Formal
(First_Formal
(Eq_Op
)))
1978 and then Base_Type
(Etype
(Eq_Op
)) = Standard_Boolean
;
1980 pragma Assert
(Present
(Prim
));
1983 Eq_Op
:= Node
(Prim
);
1986 Make_Function_Call
(Loc
,
1987 Name
=> New_Reference_To
(Eq_Op
, Loc
),
1988 Parameter_Associations
=>
1990 (Unchecked_Convert_To
(Etype
(First_Formal
(Eq_Op
)), Lhs
),
1991 Unchecked_Convert_To
(Etype
(First_Formal
(Eq_Op
)), Rhs
)));
1993 elsif Is_Record_Type
(Full_Type
) then
1994 Eq_Op
:= TSS
(Full_Type
, TSS_Composite_Equality
);
1996 if Present
(Eq_Op
) then
1997 if Etype
(First_Formal
(Eq_Op
)) /= Full_Type
then
1999 -- Inherited equality from parent type. Convert the actuals to
2000 -- match signature of operation.
2003 T
: constant Entity_Id
:= Etype
(First_Formal
(Eq_Op
));
2007 Make_Function_Call
(Loc
,
2008 Name
=> New_Reference_To
(Eq_Op
, Loc
),
2009 Parameter_Associations
=>
2010 New_List
(OK_Convert_To
(T
, Lhs
),
2011 OK_Convert_To
(T
, Rhs
)));
2015 -- Comparison between Unchecked_Union components
2017 if Is_Unchecked_Union
(Full_Type
) then
2019 Lhs_Type
: Node_Id
:= Full_Type
;
2020 Rhs_Type
: Node_Id
:= Full_Type
;
2021 Lhs_Discr_Val
: Node_Id
;
2022 Rhs_Discr_Val
: Node_Id
;
2027 if Nkind
(Lhs
) = N_Selected_Component
then
2028 Lhs_Type
:= Etype
(Entity
(Selector_Name
(Lhs
)));
2033 if Nkind
(Rhs
) = N_Selected_Component
then
2034 Rhs_Type
:= Etype
(Entity
(Selector_Name
(Rhs
)));
2037 -- Lhs of the composite equality
2039 if Is_Constrained
(Lhs_Type
) then
2041 -- Since the enclosing record type can never be an
2042 -- Unchecked_Union (this code is executed for records
2043 -- that do not have variants), we may reference its
2046 if Nkind
(Lhs
) = N_Selected_Component
2047 and then Has_Per_Object_Constraint
(
2048 Entity
(Selector_Name
(Lhs
)))
2051 Make_Selected_Component
(Loc
,
2052 Prefix
=> Prefix
(Lhs
),
2055 Get_Discriminant_Value
(
2056 First_Discriminant
(Lhs_Type
),
2058 Stored_Constraint
(Lhs_Type
))));
2061 Lhs_Discr_Val
:= New_Copy
(
2062 Get_Discriminant_Value
(
2063 First_Discriminant
(Lhs_Type
),
2065 Stored_Constraint
(Lhs_Type
)));
2069 -- It is not possible to infer the discriminant since
2070 -- the subtype is not constrained.
2073 Make_Raise_Program_Error
(Loc
,
2074 Reason
=> PE_Unchecked_Union_Restriction
);
2077 -- Rhs of the composite equality
2079 if Is_Constrained
(Rhs_Type
) then
2080 if Nkind
(Rhs
) = N_Selected_Component
2081 and then Has_Per_Object_Constraint
(
2082 Entity
(Selector_Name
(Rhs
)))
2085 Make_Selected_Component
(Loc
,
2086 Prefix
=> Prefix
(Rhs
),
2089 Get_Discriminant_Value
(
2090 First_Discriminant
(Rhs_Type
),
2092 Stored_Constraint
(Rhs_Type
))));
2095 Rhs_Discr_Val
:= New_Copy
(
2096 Get_Discriminant_Value
(
2097 First_Discriminant
(Rhs_Type
),
2099 Stored_Constraint
(Rhs_Type
)));
2104 Make_Raise_Program_Error
(Loc
,
2105 Reason
=> PE_Unchecked_Union_Restriction
);
2108 -- Call the TSS equality function with the inferred
2109 -- discriminant values.
2112 Make_Function_Call
(Loc
,
2113 Name
=> New_Reference_To
(Eq_Op
, Loc
),
2114 Parameter_Associations
=> New_List
(
2122 -- Shouldn't this be an else, we can't fall through the above
2126 Make_Function_Call
(Loc
,
2127 Name
=> New_Reference_To
(Eq_Op
, Loc
),
2128 Parameter_Associations
=> New_List
(Lhs
, Rhs
));
2132 return Expand_Record_Equality
(Nod
, Full_Type
, Lhs
, Rhs
, Bodies
);
2136 -- It can be a simple record or the full view of a scalar private
2138 return Make_Op_Eq
(Loc
, Left_Opnd
=> Lhs
, Right_Opnd
=> Rhs
);
2140 end Expand_Composite_Equality
;
2142 ------------------------------
2143 -- Expand_Concatenate_Other --
2144 ------------------------------
2146 -- Let n be the number of array operands to be concatenated, Base_Typ their
2147 -- base type, Ind_Typ their index type, and Arr_Typ the original array type
2148 -- to which the concatenation operator applies, then the following
2149 -- subprogram is constructed:
2151 -- [function Cnn (S1 : Base_Typ; ...; Sn : Base_Typ) return Base_Typ is
2154 -- if S1'Length /= 0 then
2155 -- L := XXX; --> XXX = S1'First if Arr_Typ is unconstrained
2156 -- XXX = Arr_Typ'First otherwise
2157 -- elsif S2'Length /= 0 then
2158 -- L := YYY; --> YYY = S2'First if Arr_Typ is unconstrained
2159 -- YYY = Arr_Typ'First otherwise
2161 -- elsif Sn-1'Length /= 0 then
2162 -- L := ZZZ; --> ZZZ = Sn-1'First if Arr_Typ is unconstrained
2163 -- ZZZ = Arr_Typ'First otherwise
2171 -- Ind_Typ'Val ((((S1'Length - 1) + S2'Length) + ... + Sn'Length)
2172 -- + Ind_Typ'Pos (L));
2173 -- R : Base_Typ (L .. H);
2175 -- if S1'Length /= 0 then
2179 -- L := Ind_Typ'Succ (L);
2180 -- exit when P = S1'Last;
2181 -- P := Ind_Typ'Succ (P);
2185 -- if S2'Length /= 0 then
2186 -- L := Ind_Typ'Succ (L);
2189 -- L := Ind_Typ'Succ (L);
2190 -- exit when P = S2'Last;
2191 -- P := Ind_Typ'Succ (P);
2197 -- if Sn'Length /= 0 then
2201 -- L := Ind_Typ'Succ (L);
2202 -- exit when P = Sn'Last;
2203 -- P := Ind_Typ'Succ (P);
2211 procedure Expand_Concatenate_Other
(Cnode
: Node_Id
; Opnds
: List_Id
) is
2212 Loc
: constant Source_Ptr
:= Sloc
(Cnode
);
2213 Nb_Opnds
: constant Nat
:= List_Length
(Opnds
);
2215 Arr_Typ
: constant Entity_Id
:= Etype
(Entity
(Cnode
));
2216 Base_Typ
: constant Entity_Id
:= Base_Type
(Etype
(Cnode
));
2217 Ind_Typ
: constant Entity_Id
:= Etype
(First_Index
(Base_Typ
));
2220 Func_Spec
: Node_Id
;
2221 Param_Specs
: List_Id
;
2223 Func_Body
: Node_Id
;
2224 Func_Decls
: List_Id
;
2225 Func_Stmts
: List_Id
;
2230 Elsif_List
: List_Id
;
2232 Declare_Block
: Node_Id
;
2233 Declare_Decls
: List_Id
;
2234 Declare_Stmts
: List_Id
;
2247 function Copy_Into_R_S
(I
: Nat
; Last
: Boolean) return List_Id
;
2248 -- Builds the sequence of statement:
2252 -- L := Ind_Typ'Succ (L);
2253 -- exit when P = Si'Last;
2254 -- P := Ind_Typ'Succ (P);
2257 -- where i is the input parameter I given.
2258 -- If the flag Last is true, the exit statement is emitted before
2259 -- incrementing the lower bound, to prevent the creation out of
2262 function Init_L
(I
: Nat
) return Node_Id
;
2263 -- Builds the statement:
2264 -- L := Arr_Typ'First; If Arr_Typ is constrained
2265 -- L := Si'First; otherwise (where I is the input param given)
2267 function H
return Node_Id
;
2268 -- Builds reference to identifier H
2270 function Ind_Val
(E
: Node_Id
) return Node_Id
;
2271 -- Builds expression Ind_Typ'Val (E);
2273 function L
return Node_Id
;
2274 -- Builds reference to identifier L
2276 function L_Pos
return Node_Id
;
2277 -- Builds expression Integer_Type'(Ind_Typ'Pos (L)). We qualify the
2278 -- expression to avoid universal_integer computations whenever possible,
2279 -- in the expression for the upper bound H.
2281 function L_Succ
return Node_Id
;
2282 -- Builds expression Ind_Typ'Succ (L)
2284 function One
return Node_Id
;
2285 -- Builds integer literal one
2287 function P
return Node_Id
;
2288 -- Builds reference to identifier P
2290 function P_Succ
return Node_Id
;
2291 -- Builds expression Ind_Typ'Succ (P)
2293 function R
return Node_Id
;
2294 -- Builds reference to identifier R
2296 function S
(I
: Nat
) return Node_Id
;
2297 -- Builds reference to identifier Si, where I is the value given
2299 function S_First
(I
: Nat
) return Node_Id
;
2300 -- Builds expression Si'First, where I is the value given
2302 function S_Last
(I
: Nat
) return Node_Id
;
2303 -- Builds expression Si'Last, where I is the value given
2305 function S_Length
(I
: Nat
) return Node_Id
;
2306 -- Builds expression Si'Length, where I is the value given
2308 function S_Length_Test
(I
: Nat
) return Node_Id
;
2309 -- Builds expression Si'Length /= 0, where I is the value given
2315 function Copy_Into_R_S
(I
: Nat
; Last
: Boolean) return List_Id
is
2316 Stmts
: constant List_Id
:= New_List
;
2318 Loop_Stmt
: Node_Id
;
2320 Exit_Stmt
: Node_Id
;
2325 -- First construct the initializations
2327 P_Start
:= Make_Assignment_Statement
(Loc
,
2329 Expression
=> S_First
(I
));
2330 Append_To
(Stmts
, P_Start
);
2332 -- Then build the loop
2334 R_Copy
:= Make_Assignment_Statement
(Loc
,
2335 Name
=> Make_Indexed_Component
(Loc
,
2337 Expressions
=> New_List
(L
)),
2338 Expression
=> Make_Indexed_Component
(Loc
,
2340 Expressions
=> New_List
(P
)));
2342 L_Inc
:= Make_Assignment_Statement
(Loc
,
2344 Expression
=> L_Succ
);
2346 Exit_Stmt
:= Make_Exit_Statement
(Loc
,
2347 Condition
=> Make_Op_Eq
(Loc
, P
, S_Last
(I
)));
2349 P_Inc
:= Make_Assignment_Statement
(Loc
,
2351 Expression
=> P_Succ
);
2355 Make_Implicit_Loop_Statement
(Cnode
,
2356 Statements
=> New_List
(R_Copy
, Exit_Stmt
, L_Inc
, P_Inc
));
2359 Make_Implicit_Loop_Statement
(Cnode
,
2360 Statements
=> New_List
(R_Copy
, L_Inc
, Exit_Stmt
, P_Inc
));
2363 Append_To
(Stmts
, Loop_Stmt
);
2372 function H
return Node_Id
is
2374 return Make_Identifier
(Loc
, Name_uH
);
2381 function Ind_Val
(E
: Node_Id
) return Node_Id
is
2384 Make_Attribute_Reference
(Loc
,
2385 Prefix
=> New_Reference_To
(Ind_Typ
, Loc
),
2386 Attribute_Name
=> Name_Val
,
2387 Expressions
=> New_List
(E
));
2394 function Init_L
(I
: Nat
) return Node_Id
is
2398 if Is_Constrained
(Arr_Typ
) then
2399 E
:= Make_Attribute_Reference
(Loc
,
2400 Prefix
=> New_Reference_To
(Arr_Typ
, Loc
),
2401 Attribute_Name
=> Name_First
);
2407 return Make_Assignment_Statement
(Loc
, Name
=> L
, Expression
=> E
);
2414 function L
return Node_Id
is
2416 return Make_Identifier
(Loc
, Name_uL
);
2423 function L_Pos
return Node_Id
is
2424 Target_Type
: Entity_Id
;
2427 -- If the index type is an enumeration type, the computation can be
2428 -- done in standard integer. Otherwise, choose a large enough integer
2429 -- type to accommodate the index type computation.
2431 if Is_Enumeration_Type
(Ind_Typ
)
2432 or else Root_Type
(Ind_Typ
) = Standard_Integer
2433 or else Root_Type
(Ind_Typ
) = Standard_Short_Integer
2434 or else Root_Type
(Ind_Typ
) = Standard_Short_Short_Integer
2435 or else Is_Modular_Integer_Type
(Ind_Typ
)
2437 Target_Type
:= Standard_Integer
;
2439 Target_Type
:= Root_Type
(Ind_Typ
);
2443 Make_Qualified_Expression
(Loc
,
2444 Subtype_Mark
=> New_Reference_To
(Target_Type
, Loc
),
2446 Make_Attribute_Reference
(Loc
,
2447 Prefix
=> New_Reference_To
(Ind_Typ
, Loc
),
2448 Attribute_Name
=> Name_Pos
,
2449 Expressions
=> New_List
(L
)));
2456 function L_Succ
return Node_Id
is
2459 Make_Attribute_Reference
(Loc
,
2460 Prefix
=> New_Reference_To
(Ind_Typ
, Loc
),
2461 Attribute_Name
=> Name_Succ
,
2462 Expressions
=> New_List
(L
));
2469 function One
return Node_Id
is
2471 return Make_Integer_Literal
(Loc
, 1);
2478 function P
return Node_Id
is
2480 return Make_Identifier
(Loc
, Name_uP
);
2487 function P_Succ
return Node_Id
is
2490 Make_Attribute_Reference
(Loc
,
2491 Prefix
=> New_Reference_To
(Ind_Typ
, Loc
),
2492 Attribute_Name
=> Name_Succ
,
2493 Expressions
=> New_List
(P
));
2500 function R
return Node_Id
is
2502 return Make_Identifier
(Loc
, Name_uR
);
2509 function S
(I
: Nat
) return Node_Id
is
2511 return Make_Identifier
(Loc
, New_External_Name
('S', I
));
2518 function S_First
(I
: Nat
) return Node_Id
is
2520 return Make_Attribute_Reference
(Loc
,
2522 Attribute_Name
=> Name_First
);
2529 function S_Last
(I
: Nat
) return Node_Id
is
2531 return Make_Attribute_Reference
(Loc
,
2533 Attribute_Name
=> Name_Last
);
2540 function S_Length
(I
: Nat
) return Node_Id
is
2542 return Make_Attribute_Reference
(Loc
,
2544 Attribute_Name
=> Name_Length
);
2551 function S_Length_Test
(I
: Nat
) return Node_Id
is
2555 Left_Opnd
=> S_Length
(I
),
2556 Right_Opnd
=> Make_Integer_Literal
(Loc
, 0));
2559 -- Start of processing for Expand_Concatenate_Other
2562 -- Construct the parameter specs and the overall function spec
2564 Param_Specs
:= New_List
;
2565 for I
in 1 .. Nb_Opnds
loop
2568 Make_Parameter_Specification
(Loc
,
2569 Defining_Identifier
=>
2570 Make_Defining_Identifier
(Loc
, New_External_Name
('S', I
)),
2571 Parameter_Type
=> New_Reference_To
(Base_Typ
, Loc
)));
2574 Func_Id
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('C'));
2576 Make_Function_Specification
(Loc
,
2577 Defining_Unit_Name
=> Func_Id
,
2578 Parameter_Specifications
=> Param_Specs
,
2579 Result_Definition
=> New_Reference_To
(Base_Typ
, Loc
));
2581 -- Construct L's object declaration
2584 Make_Object_Declaration
(Loc
,
2585 Defining_Identifier
=> Make_Defining_Identifier
(Loc
, Name_uL
),
2586 Object_Definition
=> New_Reference_To
(Ind_Typ
, Loc
));
2588 Func_Decls
:= New_List
(L_Decl
);
2590 -- Construct the if-then-elsif statements
2592 Elsif_List
:= New_List
;
2593 for I
in 2 .. Nb_Opnds
- 1 loop
2594 Append_To
(Elsif_List
, Make_Elsif_Part
(Loc
,
2595 Condition
=> S_Length_Test
(I
),
2596 Then_Statements
=> New_List
(Init_L
(I
))));
2600 Make_Implicit_If_Statement
(Cnode
,
2601 Condition
=> S_Length_Test
(1),
2602 Then_Statements
=> New_List
(Init_L
(1)),
2603 Elsif_Parts
=> Elsif_List
,
2604 Else_Statements
=> New_List
(Make_Simple_Return_Statement
(Loc
,
2605 Expression
=> S
(Nb_Opnds
))));
2607 -- Construct the declaration for H
2610 Make_Object_Declaration
(Loc
,
2611 Defining_Identifier
=> Make_Defining_Identifier
(Loc
, Name_uP
),
2612 Object_Definition
=> New_Reference_To
(Ind_Typ
, Loc
));
2614 H_Init
:= Make_Op_Subtract
(Loc
, S_Length
(1), One
);
2615 for I
in 2 .. Nb_Opnds
loop
2616 H_Init
:= Make_Op_Add
(Loc
, H_Init
, S_Length
(I
));
2619 -- If the index type is small modular type, we need to perform an
2620 -- additional check that the upper bound fits in the index type.
2621 -- Otherwise the computation of the upper bound can wrap around
2622 -- and yield meaningless results. The constraint check has to be
2623 -- explicit in the code, because the generated function is compiled
2624 -- with checks disabled, for efficiency.
2626 if Is_Modular_Integer_Type
(Ind_Typ
)
2627 and then Esize
(Ind_Typ
) < Esize
(Standard_Integer
)
2630 Make_Object_Declaration
(Loc
,
2631 Defining_Identifier
=> Make_Defining_Identifier
(Loc
, Name_uI
),
2632 Object_Definition
=> New_Reference_To
(Standard_Integer
, Loc
),
2634 Make_Type_Conversion
(Loc
,
2635 New_Reference_To
(Standard_Integer
, Loc
),
2636 Make_Op_Add
(Loc
, H_Init
, L_Pos
)));
2640 Make_Type_Conversion
(Loc
,
2641 New_Reference_To
(Ind_Typ
, Loc
),
2642 New_Reference_To
(Defining_Identifier
(I_Decl
), Loc
)));
2644 -- For other index types, computation is safe
2647 H_Init
:= Ind_Val
(Make_Op_Add
(Loc
, H_Init
, L_Pos
));
2651 Make_Object_Declaration
(Loc
,
2652 Defining_Identifier
=> Make_Defining_Identifier
(Loc
, Name_uH
),
2653 Object_Definition
=> New_Reference_To
(Ind_Typ
, Loc
),
2654 Expression
=> H_Init
);
2656 -- Construct the declaration for R
2658 R_Range
:= Make_Range
(Loc
, Low_Bound
=> L
, High_Bound
=> H
);
2660 Make_Index_Or_Discriminant_Constraint
(Loc
,
2661 Constraints
=> New_List
(R_Range
));
2664 Make_Object_Declaration
(Loc
,
2665 Defining_Identifier
=> Make_Defining_Identifier
(Loc
, Name_uR
),
2666 Object_Definition
=>
2667 Make_Subtype_Indication
(Loc
,
2668 Subtype_Mark
=> New_Reference_To
(Base_Typ
, Loc
),
2669 Constraint
=> R_Constr
));
2671 -- Construct the declarations for the declare block
2673 Declare_Decls
:= New_List
(P_Decl
, H_Decl
, R_Decl
);
2675 -- Add constraint check for the modular index case
2677 if Is_Modular_Integer_Type
(Ind_Typ
)
2678 and then Esize
(Ind_Typ
) < Esize
(Standard_Integer
)
2680 Insert_After
(P_Decl
, I_Decl
);
2682 Insert_After
(I_Decl
,
2683 Make_Raise_Constraint_Error
(Loc
,
2687 New_Reference_To
(Defining_Identifier
(I_Decl
), Loc
),
2689 Make_Type_Conversion
(Loc
,
2690 New_Reference_To
(Standard_Integer
, Loc
),
2691 Make_Attribute_Reference
(Loc
,
2692 Prefix
=> New_Reference_To
(Ind_Typ
, Loc
),
2693 Attribute_Name
=> Name_Last
))),
2694 Reason
=> CE_Range_Check_Failed
));
2697 -- Construct list of statements for the declare block
2699 Declare_Stmts
:= New_List
;
2700 for I
in 1 .. Nb_Opnds
loop
2701 Append_To
(Declare_Stmts
,
2702 Make_Implicit_If_Statement
(Cnode
,
2703 Condition
=> S_Length_Test
(I
),
2704 Then_Statements
=> Copy_Into_R_S
(I
, I
= Nb_Opnds
)));
2708 (Declare_Stmts
, Make_Simple_Return_Statement
(Loc
, Expression
=> R
));
2710 -- Construct the declare block
2712 Declare_Block
:= Make_Block_Statement
(Loc
,
2713 Declarations
=> Declare_Decls
,
2714 Handled_Statement_Sequence
=>
2715 Make_Handled_Sequence_Of_Statements
(Loc
, Declare_Stmts
));
2717 -- Construct the list of function statements
2719 Func_Stmts
:= New_List
(If_Stmt
, Declare_Block
);
2721 -- Construct the function body
2724 Make_Subprogram_Body
(Loc
,
2725 Specification
=> Func_Spec
,
2726 Declarations
=> Func_Decls
,
2727 Handled_Statement_Sequence
=>
2728 Make_Handled_Sequence_Of_Statements
(Loc
, Func_Stmts
));
2730 -- Insert the newly generated function in the code. This is analyzed
2731 -- with all checks off, since we have completed all the checks.
2733 -- Note that this does *not* fix the array concatenation bug when the
2734 -- low bound is Integer'first sibce that bug comes from the pointer
2735 -- dereferencing an unconstrained array. And there we need a constraint
2736 -- check to make sure the length of the concatenated array is ok. ???
2738 Insert_Action
(Cnode
, Func_Body
, Suppress
=> All_Checks
);
2740 -- Construct list of arguments for the function call
2743 Operand
:= First
(Opnds
);
2744 for I
in 1 .. Nb_Opnds
loop
2745 Append_To
(Params
, Relocate_Node
(Operand
));
2749 -- Insert the function call
2753 Make_Function_Call
(Loc
, New_Reference_To
(Func_Id
, Loc
), Params
));
2755 Analyze_And_Resolve
(Cnode
, Base_Typ
);
2756 Set_Is_Inlined
(Func_Id
);
2757 end Expand_Concatenate_Other
;
2759 -------------------------------
2760 -- Expand_Concatenate_String --
2761 -------------------------------
2763 procedure Expand_Concatenate_String
(Cnode
: Node_Id
; Opnds
: List_Id
) is
2764 Loc
: constant Source_Ptr
:= Sloc
(Cnode
);
2765 Opnd1
: constant Node_Id
:= First
(Opnds
);
2766 Opnd2
: constant Node_Id
:= Next
(Opnd1
);
2767 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Opnd1
));
2768 Typ2
: constant Entity_Id
:= Base_Type
(Etype
(Opnd2
));
2771 -- RE_Id value for function to be called
2774 -- In all cases, we build a call to a routine giving the list of
2775 -- arguments as the parameter list to the routine.
2777 case List_Length
(Opnds
) is
2779 if Typ1
= Standard_Character
then
2780 if Typ2
= Standard_Character
then
2781 R
:= RE_Str_Concat_CC
;
2784 pragma Assert
(Typ2
= Standard_String
);
2785 R
:= RE_Str_Concat_CS
;
2788 elsif Typ1
= Standard_String
then
2789 if Typ2
= Standard_Character
then
2790 R
:= RE_Str_Concat_SC
;
2793 pragma Assert
(Typ2
= Standard_String
);
2797 -- If we have anything other than Standard_Character or
2798 -- Standard_String, then we must have had a serious error
2799 -- earlier, so we just abandon the attempt at expansion.
2802 pragma Assert
(Serious_Errors_Detected
> 0);
2807 R
:= RE_Str_Concat_3
;
2810 R
:= RE_Str_Concat_4
;
2813 R
:= RE_Str_Concat_5
;
2817 raise Program_Error
;
2820 -- Now generate the appropriate call
2823 Make_Function_Call
(Sloc
(Cnode
),
2824 Name
=> New_Occurrence_Of
(RTE
(R
), Loc
),
2825 Parameter_Associations
=> Opnds
));
2827 Analyze_And_Resolve
(Cnode
, Standard_String
);
2830 when RE_Not_Available
=>
2832 end Expand_Concatenate_String
;
2834 ------------------------
2835 -- Expand_N_Allocator --
2836 ------------------------
2838 procedure Expand_N_Allocator
(N
: Node_Id
) is
2839 PtrT
: constant Entity_Id
:= Etype
(N
);
2840 Dtyp
: constant Entity_Id
:= Designated_Type
(PtrT
);
2841 Etyp
: constant Entity_Id
:= Etype
(Expression
(N
));
2842 Loc
: constant Source_Ptr
:= Sloc
(N
);
2847 procedure Complete_Coextension_Finalization
;
2848 -- Generate finalization calls for all nested coextensions of N. This
2849 -- routine may allocate list controllers if necessary.
2851 procedure Rewrite_Coextension
(N
: Node_Id
);
2852 -- Static coextensions have the same lifetime as the entity they
2853 -- constrain. Such occurrences can be rewritten as aliased objects
2854 -- and their unrestricted access used instead of the coextension.
2856 ---------------------------------------
2857 -- Complete_Coextension_Finalization --
2858 ---------------------------------------
2860 procedure Complete_Coextension_Finalization
is
2862 Coext_Elmt
: Elmt_Id
;
2866 function Inside_A_Return_Statement
(N
: Node_Id
) return Boolean;
2867 -- Determine whether node N is part of a return statement
2869 function Needs_Initialization_Call
(N
: Node_Id
) return Boolean;
2870 -- Determine whether node N is a subtype indicator allocator which
2871 -- acts a coextension. Such coextensions need initialization.
2873 -------------------------------
2874 -- Inside_A_Return_Statement --
2875 -------------------------------
2877 function Inside_A_Return_Statement
(N
: Node_Id
) return Boolean is
2882 while Present
(P
) loop
2884 (P
, N_Extended_Return_Statement
, N_Simple_Return_Statement
)
2888 -- Stop the traversal when we reach a subprogram body
2890 elsif Nkind
(P
) = N_Subprogram_Body
then
2898 end Inside_A_Return_Statement
;
2900 -------------------------------
2901 -- Needs_Initialization_Call --
2902 -------------------------------
2904 function Needs_Initialization_Call
(N
: Node_Id
) return Boolean is
2908 if Nkind
(N
) = N_Explicit_Dereference
2909 and then Nkind
(Prefix
(N
)) = N_Identifier
2910 and then Nkind
(Parent
(Entity
(Prefix
(N
)))) =
2911 N_Object_Declaration
2913 Obj_Decl
:= Parent
(Entity
(Prefix
(N
)));
2916 Present
(Expression
(Obj_Decl
))
2917 and then Nkind
(Expression
(Obj_Decl
)) = N_Allocator
2918 and then Nkind
(Expression
(Expression
(Obj_Decl
))) /=
2919 N_Qualified_Expression
;
2923 end Needs_Initialization_Call
;
2925 -- Start of processing for Complete_Coextension_Finalization
2928 -- When a coextension root is inside a return statement, we need to
2929 -- use the finalization chain of the function's scope. This does not
2930 -- apply for controlled named access types because in those cases we
2931 -- can use the finalization chain of the type itself.
2933 if Inside_A_Return_Statement
(N
)
2935 (Ekind
(PtrT
) = E_Anonymous_Access_Type
2937 (Ekind
(PtrT
) = E_Access_Type
2938 and then No
(Associated_Final_Chain
(PtrT
))))
2942 Outer_S
: Entity_Id
;
2943 S
: Entity_Id
:= Current_Scope
;
2946 while Present
(S
) and then S
/= Standard_Standard
loop
2947 if Ekind
(S
) = E_Function
then
2948 Outer_S
:= Scope
(S
);
2950 -- Retrieve the declaration of the body
2952 Decl
:= Parent
(Parent
(
2953 Corresponding_Body
(Parent
(Parent
(S
)))));
2960 -- Push the scope of the function body since we are inserting
2961 -- the list before the body, but we are currently in the body
2962 -- itself. Override the finalization list of PtrT since the
2963 -- finalization context is now different.
2965 Push_Scope
(Outer_S
);
2966 Build_Final_List
(Decl
, PtrT
);
2970 -- The root allocator may not be controlled, but it still needs a
2971 -- finalization list for all nested coextensions.
2973 elsif No
(Associated_Final_Chain
(PtrT
)) then
2974 Build_Final_List
(N
, PtrT
);
2978 Make_Selected_Component
(Loc
,
2980 New_Reference_To
(Associated_Final_Chain
(PtrT
), Loc
),
2982 Make_Identifier
(Loc
, Name_F
));
2984 Coext_Elmt
:= First_Elmt
(Coextensions
(N
));
2985 while Present
(Coext_Elmt
) loop
2986 Coext
:= Node
(Coext_Elmt
);
2991 if Nkind
(Coext
) = N_Identifier
then
2993 Make_Unchecked_Type_Conversion
(Loc
,
2994 Subtype_Mark
=> New_Reference_To
(Etype
(Coext
), Loc
),
2996 Make_Explicit_Dereference
(Loc
,
2997 Prefix
=> New_Copy_Tree
(Coext
)));
2999 Ref
:= New_Copy_Tree
(Coext
);
3002 -- No initialization call if not allowed
3004 Check_Restriction
(No_Default_Initialization
, N
);
3006 if not Restriction_Active
(No_Default_Initialization
) then
3010 -- attach_to_final_list (Ref, Flist, 2)
3012 if Needs_Initialization_Call
(Coext
) then
3016 Typ
=> Etype
(Coext
),
3018 With_Attach
=> Make_Integer_Literal
(Loc
, Uint_2
)));
3021 -- attach_to_final_list (Ref, Flist, 2)
3027 Flist_Ref
=> New_Copy_Tree
(Flist
),
3028 With_Attach
=> Make_Integer_Literal
(Loc
, Uint_2
)));
3032 Next_Elmt
(Coext_Elmt
);
3034 end Complete_Coextension_Finalization
;
3036 -------------------------
3037 -- Rewrite_Coextension --
3038 -------------------------
3040 procedure Rewrite_Coextension
(N
: Node_Id
) is
3041 Temp
: constant Node_Id
:=
3042 Make_Defining_Identifier
(Loc
,
3043 New_Internal_Name
('C'));
3046 -- Cnn : aliased Etyp;
3048 Decl
: constant Node_Id
:=
3049 Make_Object_Declaration
(Loc
,
3050 Defining_Identifier
=> Temp
,
3051 Aliased_Present
=> True,
3052 Object_Definition
=>
3053 New_Occurrence_Of
(Etyp
, Loc
));
3057 if Nkind
(Expression
(N
)) = N_Qualified_Expression
then
3058 Set_Expression
(Decl
, Expression
(Expression
(N
)));
3061 -- Find the proper insertion node for the declaration
3064 while Present
(Nod
) loop
3065 exit when Nkind
(Nod
) in N_Statement_Other_Than_Procedure_Call
3066 or else Nkind
(Nod
) = N_Procedure_Call_Statement
3067 or else Nkind
(Nod
) in N_Declaration
;
3068 Nod
:= Parent
(Nod
);
3071 Insert_Before
(Nod
, Decl
);
3075 Make_Attribute_Reference
(Loc
,
3076 Prefix
=> New_Occurrence_Of
(Temp
, Loc
),
3077 Attribute_Name
=> Name_Unrestricted_Access
));
3079 Analyze_And_Resolve
(N
, PtrT
);
3080 end Rewrite_Coextension
;
3082 -- Start of processing for Expand_N_Allocator
3085 -- RM E.2.3(22). We enforce that the expected type of an allocator
3086 -- shall not be a remote access-to-class-wide-limited-private type
3088 -- Why is this being done at expansion time, seems clearly wrong ???
3090 Validate_Remote_Access_To_Class_Wide_Type
(N
);
3092 -- Set the Storage Pool
3094 Set_Storage_Pool
(N
, Associated_Storage_Pool
(Root_Type
(PtrT
)));
3096 if Present
(Storage_Pool
(N
)) then
3097 if Is_RTE
(Storage_Pool
(N
), RE_SS_Pool
) then
3098 if VM_Target
= No_VM
then
3099 Set_Procedure_To_Call
(N
, RTE
(RE_SS_Allocate
));
3102 elsif Is_Class_Wide_Type
(Etype
(Storage_Pool
(N
))) then
3103 Set_Procedure_To_Call
(N
, RTE
(RE_Allocate_Any
));
3106 Set_Procedure_To_Call
(N
,
3107 Find_Prim_Op
(Etype
(Storage_Pool
(N
)), Name_Allocate
));
3111 -- Under certain circumstances we can replace an allocator by an access
3112 -- to statically allocated storage. The conditions, as noted in AARM
3113 -- 3.10 (10c) are as follows:
3115 -- Size and initial value is known at compile time
3116 -- Access type is access-to-constant
3118 -- The allocator is not part of a constraint on a record component,
3119 -- because in that case the inserted actions are delayed until the
3120 -- record declaration is fully analyzed, which is too late for the
3121 -- analysis of the rewritten allocator.
3123 if Is_Access_Constant
(PtrT
)
3124 and then Nkind
(Expression
(N
)) = N_Qualified_Expression
3125 and then Compile_Time_Known_Value
(Expression
(Expression
(N
)))
3126 and then Size_Known_At_Compile_Time
(Etype
(Expression
3128 and then not Is_Record_Type
(Current_Scope
)
3130 -- Here we can do the optimization. For the allocator
3134 -- We insert an object declaration
3136 -- Tnn : aliased x := y;
3138 -- and replace the allocator by Tnn'Unrestricted_Access. Tnn is
3139 -- marked as requiring static allocation.
3142 Make_Defining_Identifier
(Loc
, New_Internal_Name
('T'));
3144 Desig
:= Subtype_Mark
(Expression
(N
));
3146 -- If context is constrained, use constrained subtype directly,
3147 -- so that the constant is not labelled as having a nominally
3148 -- unconstrained subtype.
3150 if Entity
(Desig
) = Base_Type
(Dtyp
) then
3151 Desig
:= New_Occurrence_Of
(Dtyp
, Loc
);
3155 Make_Object_Declaration
(Loc
,
3156 Defining_Identifier
=> Temp
,
3157 Aliased_Present
=> True,
3158 Constant_Present
=> Is_Access_Constant
(PtrT
),
3159 Object_Definition
=> Desig
,
3160 Expression
=> Expression
(Expression
(N
))));
3163 Make_Attribute_Reference
(Loc
,
3164 Prefix
=> New_Occurrence_Of
(Temp
, Loc
),
3165 Attribute_Name
=> Name_Unrestricted_Access
));
3167 Analyze_And_Resolve
(N
, PtrT
);
3169 -- We set the variable as statically allocated, since we don't want
3170 -- it going on the stack of the current procedure!
3172 Set_Is_Statically_Allocated
(Temp
);
3176 -- Same if the allocator is an access discriminant for a local object:
3177 -- instead of an allocator we create a local value and constrain the
3178 -- the enclosing object with the corresponding access attribute.
3180 if Is_Static_Coextension
(N
) then
3181 Rewrite_Coextension
(N
);
3185 -- The current allocator creates an object which may contain nested
3186 -- coextensions. Use the current allocator's finalization list to
3187 -- generate finalization call for all nested coextensions.
3189 if Is_Coextension_Root
(N
) then
3190 Complete_Coextension_Finalization
;
3193 -- Handle case of qualified expression (other than optimization above)
3195 if Nkind
(Expression
(N
)) = N_Qualified_Expression
then
3196 Expand_Allocator_Expression
(N
);
3200 -- If the allocator is for a type which requires initialization, and
3201 -- there is no initial value (i.e. operand is a subtype indication
3202 -- rather than a qualified expression), then we must generate a call to
3203 -- the initialization routine using an expressions action node:
3205 -- [Pnnn : constant ptr_T := new (T); Init (Pnnn.all,...); Pnnn]
3207 -- Here ptr_T is the pointer type for the allocator, and T is the
3208 -- subtype of the allocator. A special case arises if the designated
3209 -- type of the access type is a task or contains tasks. In this case
3210 -- the call to Init (Temp.all ...) is replaced by code that ensures
3211 -- that tasks get activated (see Exp_Ch9.Build_Task_Allocate_Block
3212 -- for details). In addition, if the type T is a task T, then the
3213 -- first argument to Init must be converted to the task record type.
3216 T
: constant Entity_Id
:= Entity
(Expression
(N
));
3224 Temp_Decl
: Node_Id
;
3225 Temp_Type
: Entity_Id
;
3226 Attach_Level
: Uint
;
3229 if No_Initialization
(N
) then
3232 -- Case of no initialization procedure present
3234 elsif not Has_Non_Null_Base_Init_Proc
(T
) then
3236 -- Case of simple initialization required
3238 if Needs_Simple_Initialization
(T
) then
3239 Check_Restriction
(No_Default_Initialization
, N
);
3240 Rewrite
(Expression
(N
),
3241 Make_Qualified_Expression
(Loc
,
3242 Subtype_Mark
=> New_Occurrence_Of
(T
, Loc
),
3243 Expression
=> Get_Simple_Init_Val
(T
, N
)));
3245 Analyze_And_Resolve
(Expression
(Expression
(N
)), T
);
3246 Analyze_And_Resolve
(Expression
(N
), T
);
3247 Set_Paren_Count
(Expression
(Expression
(N
)), 1);
3248 Expand_N_Allocator
(N
);
3250 -- No initialization required
3256 -- Case of initialization procedure present, must be called
3259 Check_Restriction
(No_Default_Initialization
, N
);
3261 if not Restriction_Active
(No_Default_Initialization
) then
3262 Init
:= Base_Init_Proc
(T
);
3264 Temp
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
3266 -- Construct argument list for the initialization routine call
3269 Make_Explicit_Dereference
(Loc
,
3270 Prefix
=> New_Reference_To
(Temp
, Loc
));
3271 Set_Assignment_OK
(Arg1
);
3274 -- The initialization procedure expects a specific type. if the
3275 -- context is access to class wide, indicate that the object
3276 -- being allocated has the right specific type.
3278 if Is_Class_Wide_Type
(Dtyp
) then
3279 Arg1
:= Unchecked_Convert_To
(T
, Arg1
);
3282 -- If designated type is a concurrent type or if it is private
3283 -- type whose definition is a concurrent type, the first
3284 -- argument in the Init routine has to be unchecked conversion
3285 -- to the corresponding record type. If the designated type is
3286 -- a derived type, we also convert the argument to its root
3289 if Is_Concurrent_Type
(T
) then
3291 Unchecked_Convert_To
(Corresponding_Record_Type
(T
), Arg1
);
3293 elsif Is_Private_Type
(T
)
3294 and then Present
(Full_View
(T
))
3295 and then Is_Concurrent_Type
(Full_View
(T
))
3298 Unchecked_Convert_To
3299 (Corresponding_Record_Type
(Full_View
(T
)), Arg1
);
3301 elsif Etype
(First_Formal
(Init
)) /= Base_Type
(T
) then
3303 Ftyp
: constant Entity_Id
:= Etype
(First_Formal
(Init
));
3305 Arg1
:= OK_Convert_To
(Etype
(Ftyp
), Arg1
);
3306 Set_Etype
(Arg1
, Ftyp
);
3310 Args
:= New_List
(Arg1
);
3312 -- For the task case, pass the Master_Id of the access type as
3313 -- the value of the _Master parameter, and _Chain as the value
3314 -- of the _Chain parameter (_Chain will be defined as part of
3315 -- the generated code for the allocator).
3317 -- In Ada 2005, the context may be a function that returns an
3318 -- anonymous access type. In that case the Master_Id has been
3319 -- created when expanding the function declaration.
3321 if Has_Task
(T
) then
3322 if No
(Master_Id
(Base_Type
(PtrT
))) then
3324 -- If we have a non-library level task with restriction
3325 -- No_Task_Hierarchy set, then no point in expanding.
3327 if not Is_Library_Level_Entity
(T
)
3328 and then Restriction_Active
(No_Task_Hierarchy
)
3333 -- The designated type was an incomplete type, and the
3334 -- access type did not get expanded. Salvage it now.
3336 pragma Assert
(Present
(Parent
(Base_Type
(PtrT
))));
3337 Expand_N_Full_Type_Declaration
3338 (Parent
(Base_Type
(PtrT
)));
3341 -- If the context of the allocator is a declaration or an
3342 -- assignment, we can generate a meaningful image for it,
3343 -- even though subsequent assignments might remove the
3344 -- connection between task and entity. We build this image
3345 -- when the left-hand side is a simple variable, a simple
3346 -- indexed assignment or a simple selected component.
3348 if Nkind
(Parent
(N
)) = N_Assignment_Statement
then
3350 Nam
: constant Node_Id
:= Name
(Parent
(N
));
3353 if Is_Entity_Name
(Nam
) then
3355 Build_Task_Image_Decls
3358 (Entity
(Nam
), Sloc
(Nam
)), T
);
3361 (Nam
, N_Indexed_Component
, N_Selected_Component
)
3362 and then Is_Entity_Name
(Prefix
(Nam
))
3365 Build_Task_Image_Decls
3366 (Loc
, Nam
, Etype
(Prefix
(Nam
)));
3368 Decls
:= Build_Task_Image_Decls
(Loc
, T
, T
);
3372 elsif Nkind
(Parent
(N
)) = N_Object_Declaration
then
3374 Build_Task_Image_Decls
3375 (Loc
, Defining_Identifier
(Parent
(N
)), T
);
3378 Decls
:= Build_Task_Image_Decls
(Loc
, T
, T
);
3383 (Master_Id
(Base_Type
(Root_Type
(PtrT
))), Loc
));
3384 Append_To
(Args
, Make_Identifier
(Loc
, Name_uChain
));
3386 Decl
:= Last
(Decls
);
3388 New_Occurrence_Of
(Defining_Identifier
(Decl
), Loc
));
3390 -- Has_Task is false, Decls not used
3396 -- Add discriminants if discriminated type
3399 Dis
: Boolean := False;
3403 if Has_Discriminants
(T
) then
3407 elsif Is_Private_Type
(T
)
3408 and then Present
(Full_View
(T
))
3409 and then Has_Discriminants
(Full_View
(T
))
3412 Typ
:= Full_View
(T
);
3417 -- If the allocated object will be constrained by the
3418 -- default values for discriminants, then build a subtype
3419 -- with those defaults, and change the allocated subtype
3420 -- to that. Note that this happens in fewer cases in Ada
3423 if not Is_Constrained
(Typ
)
3424 and then Present
(Discriminant_Default_Value
3425 (First_Discriminant
(Typ
)))
3426 and then (Ada_Version
< Ada_05
3428 not Has_Constrained_Partial_View
(Typ
))
3430 Typ
:= Build_Default_Subtype
(Typ
, N
);
3431 Set_Expression
(N
, New_Reference_To
(Typ
, Loc
));
3434 Discr
:= First_Elmt
(Discriminant_Constraint
(Typ
));
3435 while Present
(Discr
) loop
3436 Nod
:= Node
(Discr
);
3437 Append
(New_Copy_Tree
(Node
(Discr
)), Args
);
3439 -- AI-416: when the discriminant constraint is an
3440 -- anonymous access type make sure an accessibility
3441 -- check is inserted if necessary (3.10.2(22.q/2))
3443 if Ada_Version
>= Ada_05
3445 Ekind
(Etype
(Nod
)) = E_Anonymous_Access_Type
3447 Apply_Accessibility_Check
3448 (Nod
, Typ
, Insert_Node
=> Nod
);
3456 -- We set the allocator as analyzed so that when we analyze the
3457 -- expression actions node, we do not get an unwanted recursive
3458 -- expansion of the allocator expression.
3460 Set_Analyzed
(N
, True);
3461 Nod
:= Relocate_Node
(N
);
3463 -- Here is the transformation:
3465 -- output: Temp : constant ptr_T := new T;
3466 -- Init (Temp.all, ...);
3467 -- <CTRL> Attach_To_Final_List (Finalizable (Temp.all));
3468 -- <CTRL> Initialize (Finalizable (Temp.all));
3470 -- Here ptr_T is the pointer type for the allocator, and is the
3471 -- subtype of the allocator.
3474 Make_Object_Declaration
(Loc
,
3475 Defining_Identifier
=> Temp
,
3476 Constant_Present
=> True,
3477 Object_Definition
=> New_Reference_To
(Temp_Type
, Loc
),
3480 Set_Assignment_OK
(Temp_Decl
);
3481 Insert_Action
(N
, Temp_Decl
, Suppress
=> All_Checks
);
3483 -- If the designated type is a task type or contains tasks,
3484 -- create block to activate created tasks, and insert
3485 -- declaration for Task_Image variable ahead of call.
3487 if Has_Task
(T
) then
3489 L
: constant List_Id
:= New_List
;
3492 Build_Task_Allocate_Block
(L
, Nod
, Args
);
3494 Insert_List_Before
(First
(Declarations
(Blk
)), Decls
);
3495 Insert_Actions
(N
, L
);
3500 Make_Procedure_Call_Statement
(Loc
,
3501 Name
=> New_Reference_To
(Init
, Loc
),
3502 Parameter_Associations
=> Args
));
3505 if Needs_Finalization
(T
) then
3507 -- Postpone the generation of a finalization call for the
3508 -- current allocator if it acts as a coextension.
3510 if Is_Dynamic_Coextension
(N
) then
3511 if No
(Coextensions
(N
)) then
3512 Set_Coextensions
(N
, New_Elmt_List
);
3515 Append_Elmt
(New_Copy_Tree
(Arg1
), Coextensions
(N
));
3519 Get_Allocator_Final_List
(N
, Base_Type
(T
), PtrT
);
3521 -- Anonymous access types created for access parameters
3522 -- are attached to an explicitly constructed controller,
3523 -- which ensures that they can be finalized properly,
3524 -- even if their deallocation might not happen. The list
3525 -- associated with the controller is doubly-linked. For
3526 -- other anonymous access types, the object may end up
3527 -- on the global final list which is singly-linked.
3528 -- Work needed for access discriminants in Ada 2005 ???
3530 if Ekind
(PtrT
) = E_Anonymous_Access_Type
3532 Nkind
(Associated_Node_For_Itype
(PtrT
))
3533 not in N_Subprogram_Specification
3535 Attach_Level
:= Uint_1
;
3537 Attach_Level
:= Uint_2
;
3542 Ref
=> New_Copy_Tree
(Arg1
),
3545 With_Attach
=> Make_Integer_Literal
(Loc
,
3546 Intval
=> Attach_Level
)));
3550 Rewrite
(N
, New_Reference_To
(Temp
, Loc
));
3551 Analyze_And_Resolve
(N
, PtrT
);
3556 -- Ada 2005 (AI-251): If the allocator is for a class-wide interface
3557 -- object that has been rewritten as a reference, we displace "this"
3558 -- to reference properly its secondary dispatch table.
3560 if Nkind
(N
) = N_Identifier
3561 and then Is_Interface
(Dtyp
)
3563 Displace_Allocator_Pointer
(N
);
3567 when RE_Not_Available
=>
3569 end Expand_N_Allocator
;
3571 -----------------------
3572 -- Expand_N_And_Then --
3573 -----------------------
3575 -- Expand into conditional expression if Actions present, and also deal
3576 -- with optimizing case of arguments being True or False.
3578 procedure Expand_N_And_Then
(N
: Node_Id
) is
3579 Loc
: constant Source_Ptr
:= Sloc
(N
);
3580 Typ
: constant Entity_Id
:= Etype
(N
);
3581 Left
: constant Node_Id
:= Left_Opnd
(N
);
3582 Right
: constant Node_Id
:= Right_Opnd
(N
);
3586 -- Deal with non-standard booleans
3588 if Is_Boolean_Type
(Typ
) then
3589 Adjust_Condition
(Left
);
3590 Adjust_Condition
(Right
);
3591 Set_Etype
(N
, Standard_Boolean
);
3594 -- Check for cases where left argument is known to be True or False
3596 if Compile_Time_Known_Value
(Left
) then
3598 -- If left argument is True, change (True and then Right) to Right.
3599 -- Any actions associated with Right will be executed unconditionally
3600 -- and can thus be inserted into the tree unconditionally.
3602 if Expr_Value_E
(Left
) = Standard_True
then
3603 if Present
(Actions
(N
)) then
3604 Insert_Actions
(N
, Actions
(N
));
3609 -- If left argument is False, change (False and then Right) to False.
3610 -- In this case we can forget the actions associated with Right,
3611 -- since they will never be executed.
3613 else pragma Assert
(Expr_Value_E
(Left
) = Standard_False
);
3614 Kill_Dead_Code
(Right
);
3615 Kill_Dead_Code
(Actions
(N
));
3616 Rewrite
(N
, New_Occurrence_Of
(Standard_False
, Loc
));
3619 Adjust_Result_Type
(N
, Typ
);
3623 -- If Actions are present, we expand
3625 -- left and then right
3629 -- if left then right else false end
3631 -- with the actions becoming the Then_Actions of the conditional
3632 -- expression. This conditional expression is then further expanded
3633 -- (and will eventually disappear)
3635 if Present
(Actions
(N
)) then
3636 Actlist
:= Actions
(N
);
3638 Make_Conditional_Expression
(Loc
,
3639 Expressions
=> New_List
(
3642 New_Occurrence_Of
(Standard_False
, Loc
))));
3644 Set_Then_Actions
(N
, Actlist
);
3645 Analyze_And_Resolve
(N
, Standard_Boolean
);
3646 Adjust_Result_Type
(N
, Typ
);
3650 -- No actions present, check for cases of right argument True/False
3652 if Compile_Time_Known_Value
(Right
) then
3654 -- Change (Left and then True) to Left. Note that we know there are
3655 -- no actions associated with the True operand, since we just checked
3656 -- for this case above.
3658 if Expr_Value_E
(Right
) = Standard_True
then
3661 -- Change (Left and then False) to False, making sure to preserve any
3662 -- side effects associated with the Left operand.
3664 else pragma Assert
(Expr_Value_E
(Right
) = Standard_False
);
3665 Remove_Side_Effects
(Left
);
3667 (N
, New_Occurrence_Of
(Standard_False
, Loc
));
3671 Adjust_Result_Type
(N
, Typ
);
3672 end Expand_N_And_Then
;
3674 -------------------------------------
3675 -- Expand_N_Conditional_Expression --
3676 -------------------------------------
3678 -- Expand into expression actions if then/else actions present
3680 procedure Expand_N_Conditional_Expression
(N
: Node_Id
) is
3681 Loc
: constant Source_Ptr
:= Sloc
(N
);
3682 Cond
: constant Node_Id
:= First
(Expressions
(N
));
3683 Thenx
: constant Node_Id
:= Next
(Cond
);
3684 Elsex
: constant Node_Id
:= Next
(Thenx
);
3685 Typ
: constant Entity_Id
:= Etype
(N
);
3690 -- If either then or else actions are present, then given:
3692 -- if cond then then-expr else else-expr end
3694 -- we insert the following sequence of actions (using Insert_Actions):
3699 -- Cnn := then-expr;
3705 -- and replace the conditional expression by a reference to Cnn
3707 if Present
(Then_Actions
(N
)) or else Present
(Else_Actions
(N
)) then
3708 Cnn
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('C'));
3711 Make_Implicit_If_Statement
(N
,
3712 Condition
=> Relocate_Node
(Cond
),
3714 Then_Statements
=> New_List
(
3715 Make_Assignment_Statement
(Sloc
(Thenx
),
3716 Name
=> New_Occurrence_Of
(Cnn
, Sloc
(Thenx
)),
3717 Expression
=> Relocate_Node
(Thenx
))),
3719 Else_Statements
=> New_List
(
3720 Make_Assignment_Statement
(Sloc
(Elsex
),
3721 Name
=> New_Occurrence_Of
(Cnn
, Sloc
(Elsex
)),
3722 Expression
=> Relocate_Node
(Elsex
))));
3724 Set_Assignment_OK
(Name
(First
(Then_Statements
(New_If
))));
3725 Set_Assignment_OK
(Name
(First
(Else_Statements
(New_If
))));
3727 if Present
(Then_Actions
(N
)) then
3729 (First
(Then_Statements
(New_If
)), Then_Actions
(N
));
3732 if Present
(Else_Actions
(N
)) then
3734 (First
(Else_Statements
(New_If
)), Else_Actions
(N
));
3737 Rewrite
(N
, New_Occurrence_Of
(Cnn
, Loc
));
3740 Make_Object_Declaration
(Loc
,
3741 Defining_Identifier
=> Cnn
,
3742 Object_Definition
=> New_Occurrence_Of
(Typ
, Loc
)));
3744 Insert_Action
(N
, New_If
);
3745 Analyze_And_Resolve
(N
, Typ
);
3747 end Expand_N_Conditional_Expression
;
3749 -----------------------------------
3750 -- Expand_N_Explicit_Dereference --
3751 -----------------------------------
3753 procedure Expand_N_Explicit_Dereference
(N
: Node_Id
) is
3755 -- Insert explicit dereference call for the checked storage pool case
3757 Insert_Dereference_Action
(Prefix
(N
));
3758 end Expand_N_Explicit_Dereference
;
3764 procedure Expand_N_In
(N
: Node_Id
) is
3765 Loc
: constant Source_Ptr
:= Sloc
(N
);
3766 Rtyp
: constant Entity_Id
:= Etype
(N
);
3767 Lop
: constant Node_Id
:= Left_Opnd
(N
);
3768 Rop
: constant Node_Id
:= Right_Opnd
(N
);
3769 Static
: constant Boolean := Is_OK_Static_Expression
(N
);
3771 procedure Substitute_Valid_Check
;
3772 -- Replaces node N by Lop'Valid. This is done when we have an explicit
3773 -- test for the left operand being in range of its subtype.
3775 ----------------------------
3776 -- Substitute_Valid_Check --
3777 ----------------------------
3779 procedure Substitute_Valid_Check
is
3782 Make_Attribute_Reference
(Loc
,
3783 Prefix
=> Relocate_Node
(Lop
),
3784 Attribute_Name
=> Name_Valid
));
3786 Analyze_And_Resolve
(N
, Rtyp
);
3788 Error_Msg_N
("?explicit membership test may be optimized away", N
);
3789 Error_Msg_N
("\?use ''Valid attribute instead", N
);
3791 end Substitute_Valid_Check
;
3793 -- Start of processing for Expand_N_In
3796 -- Check case of explicit test for an expression in range of its
3797 -- subtype. This is suspicious usage and we replace it with a 'Valid
3798 -- test and give a warning.
3800 if Is_Scalar_Type
(Etype
(Lop
))
3801 and then Nkind
(Rop
) in N_Has_Entity
3802 and then Etype
(Lop
) = Entity
(Rop
)
3803 and then Comes_From_Source
(N
)
3804 and then VM_Target
= No_VM
3806 Substitute_Valid_Check
;
3810 -- Do validity check on operands
3812 if Validity_Checks_On
and Validity_Check_Operands
then
3813 Ensure_Valid
(Left_Opnd
(N
));
3814 Validity_Check_Range
(Right_Opnd
(N
));
3817 -- Case of explicit range
3819 if Nkind
(Rop
) = N_Range
then
3821 Lo
: constant Node_Id
:= Low_Bound
(Rop
);
3822 Hi
: constant Node_Id
:= High_Bound
(Rop
);
3824 Ltyp
: constant Entity_Id
:= Etype
(Lop
);
3826 Lo_Orig
: constant Node_Id
:= Original_Node
(Lo
);
3827 Hi_Orig
: constant Node_Id
:= Original_Node
(Hi
);
3829 Lcheck
: constant Compare_Result
:=
3830 Compile_Time_Compare
(Lop
, Lo
, Assume_Valid
=> True);
3831 Ucheck
: constant Compare_Result
:=
3832 Compile_Time_Compare
(Lop
, Hi
, Assume_Valid
=> True);
3834 Warn1
: constant Boolean :=
3835 Constant_Condition_Warnings
3836 and then Comes_From_Source
(N
);
3837 -- This must be true for any of the optimization warnings, we
3838 -- clearly want to give them only for source with the flag on.
3840 Warn2
: constant Boolean :=
3842 and then Nkind
(Original_Node
(Rop
)) = N_Range
3843 and then Is_Integer_Type
(Etype
(Lo
));
3844 -- For the case where only one bound warning is elided, we also
3845 -- insist on an explicit range and an integer type. The reason is
3846 -- that the use of enumeration ranges including an end point is
3847 -- common, as is the use of a subtype name, one of whose bounds
3848 -- is the same as the type of the expression.
3851 -- If test is explicit x'first .. x'last, replace by valid check
3853 if Is_Scalar_Type
(Ltyp
)
3854 and then Nkind
(Lo_Orig
) = N_Attribute_Reference
3855 and then Attribute_Name
(Lo_Orig
) = Name_First
3856 and then Nkind
(Prefix
(Lo_Orig
)) in N_Has_Entity
3857 and then Entity
(Prefix
(Lo_Orig
)) = Ltyp
3858 and then Nkind
(Hi_Orig
) = N_Attribute_Reference
3859 and then Attribute_Name
(Hi_Orig
) = Name_Last
3860 and then Nkind
(Prefix
(Hi_Orig
)) in N_Has_Entity
3861 and then Entity
(Prefix
(Hi_Orig
)) = Ltyp
3862 and then Comes_From_Source
(N
)
3863 and then VM_Target
= No_VM
3865 Substitute_Valid_Check
;
3869 -- If bounds of type are known at compile time, and the end points
3870 -- are known at compile time and identical, this is another case
3871 -- for substituting a valid test. We only do this for discrete
3872 -- types, since it won't arise in practice for float types.
3874 if Comes_From_Source
(N
)
3875 and then Is_Discrete_Type
(Ltyp
)
3876 and then Compile_Time_Known_Value
(Type_High_Bound
(Ltyp
))
3877 and then Compile_Time_Known_Value
(Type_Low_Bound
(Ltyp
))
3878 and then Compile_Time_Known_Value
(Lo
)
3879 and then Compile_Time_Known_Value
(Hi
)
3880 and then Expr_Value
(Type_High_Bound
(Ltyp
)) = Expr_Value
(Hi
)
3881 and then Expr_Value
(Type_Low_Bound
(Ltyp
)) = Expr_Value
(Lo
)
3883 -- Kill warnings in instances, since they may be cases where we
3884 -- have a test in the generic that makes sense with some types
3885 -- and not with other types.
3887 and then not In_Instance
3889 Substitute_Valid_Check
;
3893 -- If we have an explicit range, do a bit of optimization based
3894 -- on range analysis (we may be able to kill one or both checks).
3896 -- If either check is known to fail, replace result by False since
3897 -- the other check does not matter. Preserve the static flag for
3898 -- legality checks, because we are constant-folding beyond RM 4.9.
3900 if Lcheck
= LT
or else Ucheck
= GT
then
3901 if Warn1
and then not In_Instance
then
3902 Error_Msg_N
("?range test optimized away", N
);
3903 Error_Msg_N
("\?value is known to be out of range", N
);
3907 New_Reference_To
(Standard_False
, Loc
));
3908 Analyze_And_Resolve
(N
, Rtyp
);
3909 Set_Is_Static_Expression
(N
, Static
);
3913 -- If both checks are known to succeed, replace result by True,
3914 -- since we know we are in range.
3916 elsif Lcheck
in Compare_GE
and then Ucheck
in Compare_LE
then
3917 if Warn1
and then not In_Instance
then
3918 Error_Msg_N
("?range test optimized away", N
);
3919 Error_Msg_N
("\?value is known to be in range", N
);
3923 New_Reference_To
(Standard_True
, Loc
));
3924 Analyze_And_Resolve
(N
, Rtyp
);
3925 Set_Is_Static_Expression
(N
, Static
);
3929 -- If lower bound check succeeds and upper bound check is not
3930 -- known to succeed or fail, then replace the range check with
3931 -- a comparison against the upper bound.
3933 elsif Lcheck
in Compare_GE
then
3934 if Warn2
and then not In_Instance
then
3935 Error_Msg_N
("?lower bound test optimized away", Lo
);
3936 Error_Msg_N
("\?value is known to be in range", Lo
);
3942 Right_Opnd
=> High_Bound
(Rop
)));
3943 Analyze_And_Resolve
(N
, Rtyp
);
3947 -- If upper bound check succeeds and lower bound check is not
3948 -- known to succeed or fail, then replace the range check with
3949 -- a comparison against the lower bound.
3951 elsif Ucheck
in Compare_LE
then
3952 if Warn2
and then not In_Instance
then
3953 Error_Msg_N
("?upper bound test optimized away", Hi
);
3954 Error_Msg_N
("\?value is known to be in range", Hi
);
3960 Right_Opnd
=> Low_Bound
(Rop
)));
3961 Analyze_And_Resolve
(N
, Rtyp
);
3967 -- For all other cases of an explicit range, nothing to be done
3971 -- Here right operand is a subtype mark
3975 Typ
: Entity_Id
:= Etype
(Rop
);
3976 Is_Acc
: constant Boolean := Is_Access_Type
(Typ
);
3977 Obj
: Node_Id
:= Lop
;
3978 Cond
: Node_Id
:= Empty
;
3981 Remove_Side_Effects
(Obj
);
3983 -- For tagged type, do tagged membership operation
3985 if Is_Tagged_Type
(Typ
) then
3987 -- No expansion will be performed when VM_Target, as the VM
3988 -- back-ends will handle the membership tests directly (tags
3989 -- are not explicitly represented in Java objects, so the
3990 -- normal tagged membership expansion is not what we want).
3992 if VM_Target
= No_VM
then
3993 Rewrite
(N
, Tagged_Membership
(N
));
3994 Analyze_And_Resolve
(N
, Rtyp
);
3999 -- If type is scalar type, rewrite as x in t'first .. t'last.
4000 -- This reason we do this is that the bounds may have the wrong
4001 -- type if they come from the original type definition.
4003 elsif Is_Scalar_Type
(Typ
) then
4007 Make_Attribute_Reference
(Loc
,
4008 Attribute_Name
=> Name_First
,
4009 Prefix
=> New_Reference_To
(Typ
, Loc
)),
4012 Make_Attribute_Reference
(Loc
,
4013 Attribute_Name
=> Name_Last
,
4014 Prefix
=> New_Reference_To
(Typ
, Loc
))));
4015 Analyze_And_Resolve
(N
, Rtyp
);
4018 -- Ada 2005 (AI-216): Program_Error is raised when evaluating
4019 -- a membership test if the subtype mark denotes a constrained
4020 -- Unchecked_Union subtype and the expression lacks inferable
4023 elsif Is_Unchecked_Union
(Base_Type
(Typ
))
4024 and then Is_Constrained
(Typ
)
4025 and then not Has_Inferable_Discriminants
(Lop
)
4028 Make_Raise_Program_Error
(Loc
,
4029 Reason
=> PE_Unchecked_Union_Restriction
));
4031 -- Prevent Gigi from generating incorrect code by rewriting
4032 -- the test as a standard False.
4035 New_Occurrence_Of
(Standard_False
, Loc
));
4040 -- Here we have a non-scalar type
4043 Typ
:= Designated_Type
(Typ
);
4046 if not Is_Constrained
(Typ
) then
4048 New_Reference_To
(Standard_True
, Loc
));
4049 Analyze_And_Resolve
(N
, Rtyp
);
4051 -- For the constrained array case, we have to check the subscripts
4052 -- for an exact match if the lengths are non-zero (the lengths
4053 -- must match in any case).
4055 elsif Is_Array_Type
(Typ
) then
4057 Check_Subscripts
: declare
4058 function Construct_Attribute_Reference
4061 Dim
: Nat
) return Node_Id
;
4062 -- Build attribute reference E'Nam(Dim)
4064 -----------------------------------
4065 -- Construct_Attribute_Reference --
4066 -----------------------------------
4068 function Construct_Attribute_Reference
4071 Dim
: Nat
) return Node_Id
4075 Make_Attribute_Reference
(Loc
,
4077 Attribute_Name
=> Nam
,
4078 Expressions
=> New_List
(
4079 Make_Integer_Literal
(Loc
, Dim
)));
4080 end Construct_Attribute_Reference
;
4082 -- Start processing for Check_Subscripts
4085 for J
in 1 .. Number_Dimensions
(Typ
) loop
4086 Evolve_And_Then
(Cond
,
4089 Construct_Attribute_Reference
4090 (Duplicate_Subexpr_No_Checks
(Obj
),
4093 Construct_Attribute_Reference
4094 (New_Occurrence_Of
(Typ
, Loc
), Name_First
, J
)));
4096 Evolve_And_Then
(Cond
,
4099 Construct_Attribute_Reference
4100 (Duplicate_Subexpr_No_Checks
(Obj
),
4103 Construct_Attribute_Reference
4104 (New_Occurrence_Of
(Typ
, Loc
), Name_Last
, J
)));
4113 Right_Opnd
=> Make_Null
(Loc
)),
4114 Right_Opnd
=> Cond
);
4118 Analyze_And_Resolve
(N
, Rtyp
);
4119 end Check_Subscripts
;
4121 -- These are the cases where constraint checks may be required,
4122 -- e.g. records with possible discriminants
4125 -- Expand the test into a series of discriminant comparisons.
4126 -- The expression that is built is the negation of the one that
4127 -- is used for checking discriminant constraints.
4129 Obj
:= Relocate_Node
(Left_Opnd
(N
));
4131 if Has_Discriminants
(Typ
) then
4132 Cond
:= Make_Op_Not
(Loc
,
4133 Right_Opnd
=> Build_Discriminant_Checks
(Obj
, Typ
));
4136 Cond
:= Make_Or_Else
(Loc
,
4140 Right_Opnd
=> Make_Null
(Loc
)),
4141 Right_Opnd
=> Cond
);
4145 Cond
:= New_Occurrence_Of
(Standard_True
, Loc
);
4149 Analyze_And_Resolve
(N
, Rtyp
);
4155 --------------------------------
4156 -- Expand_N_Indexed_Component --
4157 --------------------------------
4159 procedure Expand_N_Indexed_Component
(N
: Node_Id
) is
4160 Loc
: constant Source_Ptr
:= Sloc
(N
);
4161 Typ
: constant Entity_Id
:= Etype
(N
);
4162 P
: constant Node_Id
:= Prefix
(N
);
4163 T
: constant Entity_Id
:= Etype
(P
);
4166 -- A special optimization, if we have an indexed component that is
4167 -- selecting from a slice, then we can eliminate the slice, since, for
4168 -- example, x (i .. j)(k) is identical to x(k). The only difference is
4169 -- the range check required by the slice. The range check for the slice
4170 -- itself has already been generated. The range check for the
4171 -- subscripting operation is ensured by converting the subject to
4172 -- the subtype of the slice.
4174 -- This optimization not only generates better code, avoiding slice
4175 -- messing especially in the packed case, but more importantly bypasses
4176 -- some problems in handling this peculiar case, for example, the issue
4177 -- of dealing specially with object renamings.
4179 if Nkind
(P
) = N_Slice
then
4181 Make_Indexed_Component
(Loc
,
4182 Prefix
=> Prefix
(P
),
4183 Expressions
=> New_List
(
4185 (Etype
(First_Index
(Etype
(P
))),
4186 First
(Expressions
(N
))))));
4187 Analyze_And_Resolve
(N
, Typ
);
4191 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
4192 -- function, then additional actuals must be passed.
4194 if Ada_Version
>= Ada_05
4195 and then Is_Build_In_Place_Function_Call
(P
)
4197 Make_Build_In_Place_Call_In_Anonymous_Context
(P
);
4200 -- If the prefix is an access type, then we unconditionally rewrite if
4201 -- as an explicit deference. This simplifies processing for several
4202 -- cases, including packed array cases and certain cases in which checks
4203 -- must be generated. We used to try to do this only when it was
4204 -- necessary, but it cleans up the code to do it all the time.
4206 if Is_Access_Type
(T
) then
4207 Insert_Explicit_Dereference
(P
);
4208 Analyze_And_Resolve
(P
, Designated_Type
(T
));
4211 -- Generate index and validity checks
4213 Generate_Index_Checks
(N
);
4215 if Validity_Checks_On
and then Validity_Check_Subscripts
then
4216 Apply_Subscript_Validity_Checks
(N
);
4219 -- All done for the non-packed case
4221 if not Is_Packed
(Etype
(Prefix
(N
))) then
4225 -- For packed arrays that are not bit-packed (i.e. the case of an array
4226 -- with one or more index types with a non-contiguous enumeration type),
4227 -- we can always use the normal packed element get circuit.
4229 if not Is_Bit_Packed_Array
(Etype
(Prefix
(N
))) then
4230 Expand_Packed_Element_Reference
(N
);
4234 -- For a reference to a component of a bit packed array, we have to
4235 -- convert it to a reference to the corresponding Packed_Array_Type.
4236 -- We only want to do this for simple references, and not for:
4238 -- Left side of assignment, or prefix of left side of assignment, or
4239 -- prefix of the prefix, to handle packed arrays of packed arrays,
4240 -- This case is handled in Exp_Ch5.Expand_N_Assignment_Statement
4242 -- Renaming objects in renaming associations
4243 -- This case is handled when a use of the renamed variable occurs
4245 -- Actual parameters for a procedure call
4246 -- This case is handled in Exp_Ch6.Expand_Actuals
4248 -- The second expression in a 'Read attribute reference
4250 -- The prefix of an address or size attribute reference
4252 -- The following circuit detects these exceptions
4255 Child
: Node_Id
:= N
;
4256 Parnt
: Node_Id
:= Parent
(N
);
4260 if Nkind
(Parnt
) = N_Unchecked_Expression
then
4263 elsif Nkind_In
(Parnt
, N_Object_Renaming_Declaration
,
4264 N_Procedure_Call_Statement
)
4265 or else (Nkind
(Parnt
) = N_Parameter_Association
4267 Nkind
(Parent
(Parnt
)) = N_Procedure_Call_Statement
)
4271 elsif Nkind
(Parnt
) = N_Attribute_Reference
4272 and then (Attribute_Name
(Parnt
) = Name_Address
4274 Attribute_Name
(Parnt
) = Name_Size
)
4275 and then Prefix
(Parnt
) = Child
4279 elsif Nkind
(Parnt
) = N_Assignment_Statement
4280 and then Name
(Parnt
) = Child
4284 -- If the expression is an index of an indexed component, it must
4285 -- be expanded regardless of context.
4287 elsif Nkind
(Parnt
) = N_Indexed_Component
4288 and then Child
/= Prefix
(Parnt
)
4290 Expand_Packed_Element_Reference
(N
);
4293 elsif Nkind
(Parent
(Parnt
)) = N_Assignment_Statement
4294 and then Name
(Parent
(Parnt
)) = Parnt
4298 elsif Nkind
(Parnt
) = N_Attribute_Reference
4299 and then Attribute_Name
(Parnt
) = Name_Read
4300 and then Next
(First
(Expressions
(Parnt
))) = Child
4304 elsif Nkind_In
(Parnt
, N_Indexed_Component
, N_Selected_Component
)
4305 and then Prefix
(Parnt
) = Child
4310 Expand_Packed_Element_Reference
(N
);
4314 -- Keep looking up tree for unchecked expression, or if we are the
4315 -- prefix of a possible assignment left side.
4318 Parnt
:= Parent
(Child
);
4321 end Expand_N_Indexed_Component
;
4323 ---------------------
4324 -- Expand_N_Not_In --
4325 ---------------------
4327 -- Replace a not in b by not (a in b) so that the expansions for (a in b)
4328 -- can be done. This avoids needing to duplicate this expansion code.
4330 procedure Expand_N_Not_In
(N
: Node_Id
) is
4331 Loc
: constant Source_Ptr
:= Sloc
(N
);
4332 Typ
: constant Entity_Id
:= Etype
(N
);
4333 Cfs
: constant Boolean := Comes_From_Source
(N
);
4340 Left_Opnd
=> Left_Opnd
(N
),
4341 Right_Opnd
=> Right_Opnd
(N
))));
4343 -- We want this to appear as coming from source if original does (see
4344 -- transformations in Expand_N_In).
4346 Set_Comes_From_Source
(N
, Cfs
);
4347 Set_Comes_From_Source
(Right_Opnd
(N
), Cfs
);
4349 -- Now analyze transformed node
4351 Analyze_And_Resolve
(N
, Typ
);
4352 end Expand_N_Not_In
;
4358 -- The only replacement required is for the case of a null of type that is
4359 -- an access to protected subprogram. We represent such access values as a
4360 -- record, and so we must replace the occurrence of null by the equivalent
4361 -- record (with a null address and a null pointer in it), so that the
4362 -- backend creates the proper value.
4364 procedure Expand_N_Null
(N
: Node_Id
) is
4365 Loc
: constant Source_Ptr
:= Sloc
(N
);
4366 Typ
: constant Entity_Id
:= Etype
(N
);
4370 if Is_Access_Protected_Subprogram_Type
(Typ
) then
4372 Make_Aggregate
(Loc
,
4373 Expressions
=> New_List
(
4374 New_Occurrence_Of
(RTE
(RE_Null_Address
), Loc
),
4378 Analyze_And_Resolve
(N
, Equivalent_Type
(Typ
));
4380 -- For subsequent semantic analysis, the node must retain its type.
4381 -- Gigi in any case replaces this type by the corresponding record
4382 -- type before processing the node.
4388 when RE_Not_Available
=>
4392 ---------------------
4393 -- Expand_N_Op_Abs --
4394 ---------------------
4396 procedure Expand_N_Op_Abs
(N
: Node_Id
) is
4397 Loc
: constant Source_Ptr
:= Sloc
(N
);
4398 Expr
: constant Node_Id
:= Right_Opnd
(N
);
4401 Unary_Op_Validity_Checks
(N
);
4403 -- Deal with software overflow checking
4405 if not Backend_Overflow_Checks_On_Target
4406 and then Is_Signed_Integer_Type
(Etype
(N
))
4407 and then Do_Overflow_Check
(N
)
4409 -- The only case to worry about is when the argument is equal to the
4410 -- largest negative number, so what we do is to insert the check:
4412 -- [constraint_error when Expr = typ'Base'First]
4414 -- with the usual Duplicate_Subexpr use coding for expr
4417 Make_Raise_Constraint_Error
(Loc
,
4420 Left_Opnd
=> Duplicate_Subexpr
(Expr
),
4422 Make_Attribute_Reference
(Loc
,
4424 New_Occurrence_Of
(Base_Type
(Etype
(Expr
)), Loc
),
4425 Attribute_Name
=> Name_First
)),
4426 Reason
=> CE_Overflow_Check_Failed
));
4429 -- Vax floating-point types case
4431 if Vax_Float
(Etype
(N
)) then
4432 Expand_Vax_Arith
(N
);
4434 end Expand_N_Op_Abs
;
4436 ---------------------
4437 -- Expand_N_Op_Add --
4438 ---------------------
4440 procedure Expand_N_Op_Add
(N
: Node_Id
) is
4441 Typ
: constant Entity_Id
:= Etype
(N
);
4444 Binary_Op_Validity_Checks
(N
);
4446 -- N + 0 = 0 + N = N for integer types
4448 if Is_Integer_Type
(Typ
) then
4449 if Compile_Time_Known_Value
(Right_Opnd
(N
))
4450 and then Expr_Value
(Right_Opnd
(N
)) = Uint_0
4452 Rewrite
(N
, Left_Opnd
(N
));
4455 elsif Compile_Time_Known_Value
(Left_Opnd
(N
))
4456 and then Expr_Value
(Left_Opnd
(N
)) = Uint_0
4458 Rewrite
(N
, Right_Opnd
(N
));
4463 -- Arithmetic overflow checks for signed integer/fixed point types
4465 if Is_Signed_Integer_Type
(Typ
)
4466 or else Is_Fixed_Point_Type
(Typ
)
4468 Apply_Arithmetic_Overflow_Check
(N
);
4471 -- Vax floating-point types case
4473 elsif Vax_Float
(Typ
) then
4474 Expand_Vax_Arith
(N
);
4476 end Expand_N_Op_Add
;
4478 ---------------------
4479 -- Expand_N_Op_And --
4480 ---------------------
4482 procedure Expand_N_Op_And
(N
: Node_Id
) is
4483 Typ
: constant Entity_Id
:= Etype
(N
);
4486 Binary_Op_Validity_Checks
(N
);
4488 if Is_Array_Type
(Etype
(N
)) then
4489 Expand_Boolean_Operator
(N
);
4491 elsif Is_Boolean_Type
(Etype
(N
)) then
4492 Adjust_Condition
(Left_Opnd
(N
));
4493 Adjust_Condition
(Right_Opnd
(N
));
4494 Set_Etype
(N
, Standard_Boolean
);
4495 Adjust_Result_Type
(N
, Typ
);
4497 end Expand_N_Op_And
;
4499 ------------------------
4500 -- Expand_N_Op_Concat --
4501 ------------------------
4503 Max_Available_String_Operands
: Int
:= -1;
4504 -- This is initialized the first time this routine is called. It records
4505 -- a value of 0,2,3,4,5 depending on what Str_Concat_n procedures are
4506 -- available in the run-time:
4509 -- 2 RE_Str_Concat available, RE_Str_Concat_3 not available
4510 -- 3 RE_Str_Concat/Concat_2 available, RE_Str_Concat_4 not available
4511 -- 4 RE_Str_Concat/Concat_2/3 available, RE_Str_Concat_5 not available
4512 -- 5 All routines including RE_Str_Concat_5 available
4514 Char_Concat_Available
: Boolean;
4515 -- Records if the routines RE_Str_Concat_CC/CS/SC are available. True if
4516 -- all three are available, False if any one of these is unavailable.
4518 procedure Expand_N_Op_Concat
(N
: Node_Id
) is
4520 -- List of operands to be concatenated
4523 -- Single operand for concatenation
4526 -- Node which is to be replaced by the result of concatenating the nodes
4527 -- in the list Opnds.
4530 -- Array type of concatenation result type
4533 -- Component type of concatenation represented by Cnode
4536 -- Initialize global variables showing run-time status
4538 if Max_Available_String_Operands
< 1 then
4540 -- See what routines are available and set max operand count
4541 -- according to the highest count available in the run-time.
4543 if not RTE_Available
(RE_Str_Concat
) then
4544 Max_Available_String_Operands
:= 0;
4546 elsif not RTE_Available
(RE_Str_Concat_3
) then
4547 Max_Available_String_Operands
:= 2;
4549 elsif not RTE_Available
(RE_Str_Concat_4
) then
4550 Max_Available_String_Operands
:= 3;
4552 elsif not RTE_Available
(RE_Str_Concat_5
) then
4553 Max_Available_String_Operands
:= 4;
4556 Max_Available_String_Operands
:= 5;
4559 Char_Concat_Available
:=
4560 RTE_Available
(RE_Str_Concat_CC
)
4562 RTE_Available
(RE_Str_Concat_CS
)
4564 RTE_Available
(RE_Str_Concat_SC
);
4567 -- Ensure validity of both operands
4569 Binary_Op_Validity_Checks
(N
);
4571 -- If we are the left operand of a concatenation higher up the tree,
4572 -- then do nothing for now, since we want to deal with a series of
4573 -- concatenations as a unit.
4575 if Nkind
(Parent
(N
)) = N_Op_Concat
4576 and then N
= Left_Opnd
(Parent
(N
))
4581 -- We get here with a concatenation whose left operand may be a
4582 -- concatenation itself with a consistent type. We need to process
4583 -- these concatenation operands from left to right, which means
4584 -- from the deepest node in the tree to the highest node.
4587 while Nkind
(Left_Opnd
(Cnode
)) = N_Op_Concat
loop
4588 Cnode
:= Left_Opnd
(Cnode
);
4591 -- Now Opnd is the deepest Opnd, and its parents are the concatenation
4592 -- nodes above, so now we process bottom up, doing the operations. We
4593 -- gather a string that is as long as possible up to five operands
4595 -- The outer loop runs more than once if there are more than five
4596 -- concatenations of type Standard.String, the most we handle for
4597 -- this case, or if more than one concatenation type is involved.
4600 Opnds
:= New_List
(Left_Opnd
(Cnode
), Right_Opnd
(Cnode
));
4601 Set_Parent
(Opnds
, N
);
4603 -- The inner loop gathers concatenation operands. We gather any
4604 -- number of these in the non-string case, or if no concatenation
4605 -- routines are available for string (since in that case we will
4606 -- treat string like any other non-string case). Otherwise we only
4607 -- gather as many operands as can be handled by the available
4608 -- procedures in the run-time library (normally 5, but may be
4609 -- less for the configurable run-time case).
4611 Inner
: while Cnode
/= N
4612 and then (Base_Type
(Etype
(Cnode
)) /= Standard_String
4614 Max_Available_String_Operands
= 0
4616 List_Length
(Opnds
) <
4617 Max_Available_String_Operands
)
4618 and then Base_Type
(Etype
(Cnode
)) =
4619 Base_Type
(Etype
(Parent
(Cnode
)))
4621 Cnode
:= Parent
(Cnode
);
4622 Append
(Right_Opnd
(Cnode
), Opnds
);
4625 -- Here we process the collected operands. First we convert singleton
4626 -- operands to singleton aggregates. This is skipped however for the
4627 -- case of two operands of type String since we have special routines
4630 Atyp
:= Base_Type
(Etype
(Cnode
));
4631 Ctyp
:= Base_Type
(Component_Type
(Etype
(Cnode
)));
4633 if (List_Length
(Opnds
) > 2 or else Atyp
/= Standard_String
)
4634 or else not Char_Concat_Available
4636 Opnd
:= First
(Opnds
);
4638 if Base_Type
(Etype
(Opnd
)) = Ctyp
then
4640 Make_Aggregate
(Sloc
(Cnode
),
4641 Expressions
=> New_List
(Relocate_Node
(Opnd
))));
4642 Analyze_And_Resolve
(Opnd
, Atyp
);
4646 exit when No
(Opnd
);
4650 -- Now call appropriate continuation routine
4652 if Atyp
= Standard_String
4653 and then Max_Available_String_Operands
> 0
4655 Expand_Concatenate_String
(Cnode
, Opnds
);
4657 Expand_Concatenate_Other
(Cnode
, Opnds
);
4660 exit Outer
when Cnode
= N
;
4661 Cnode
:= Parent
(Cnode
);
4663 end Expand_N_Op_Concat
;
4665 ------------------------
4666 -- Expand_N_Op_Divide --
4667 ------------------------
4669 procedure Expand_N_Op_Divide
(N
: Node_Id
) is
4670 Loc
: constant Source_Ptr
:= Sloc
(N
);
4671 Lopnd
: constant Node_Id
:= Left_Opnd
(N
);
4672 Ropnd
: constant Node_Id
:= Right_Opnd
(N
);
4673 Ltyp
: constant Entity_Id
:= Etype
(Lopnd
);
4674 Rtyp
: constant Entity_Id
:= Etype
(Ropnd
);
4675 Typ
: Entity_Id
:= Etype
(N
);
4676 Rknow
: constant Boolean := Is_Integer_Type
(Typ
)
4678 Compile_Time_Known_Value
(Ropnd
);
4682 Binary_Op_Validity_Checks
(N
);
4685 Rval
:= Expr_Value
(Ropnd
);
4688 -- N / 1 = N for integer types
4690 if Rknow
and then Rval
= Uint_1
then
4695 -- Convert x / 2 ** y to Shift_Right (x, y). Note that the fact that
4696 -- Is_Power_Of_2_For_Shift is set means that we know that our left
4697 -- operand is an unsigned integer, as required for this to work.
4699 if Nkind
(Ropnd
) = N_Op_Expon
4700 and then Is_Power_Of_2_For_Shift
(Ropnd
)
4702 -- We cannot do this transformation in configurable run time mode if we
4703 -- have 64-bit -- integers and long shifts are not available.
4707 or else Support_Long_Shifts_On_Target
)
4710 Make_Op_Shift_Right
(Loc
,
4713 Convert_To
(Standard_Natural
, Right_Opnd
(Ropnd
))));
4714 Analyze_And_Resolve
(N
, Typ
);
4718 -- Do required fixup of universal fixed operation
4720 if Typ
= Universal_Fixed
then
4721 Fixup_Universal_Fixed_Operation
(N
);
4725 -- Divisions with fixed-point results
4727 if Is_Fixed_Point_Type
(Typ
) then
4729 -- No special processing if Treat_Fixed_As_Integer is set, since
4730 -- from a semantic point of view such operations are simply integer
4731 -- operations and will be treated that way.
4733 if not Treat_Fixed_As_Integer
(N
) then
4734 if Is_Integer_Type
(Rtyp
) then
4735 Expand_Divide_Fixed_By_Integer_Giving_Fixed
(N
);
4737 Expand_Divide_Fixed_By_Fixed_Giving_Fixed
(N
);
4741 -- Other cases of division of fixed-point operands. Again we exclude the
4742 -- case where Treat_Fixed_As_Integer is set.
4744 elsif (Is_Fixed_Point_Type
(Ltyp
) or else
4745 Is_Fixed_Point_Type
(Rtyp
))
4746 and then not Treat_Fixed_As_Integer
(N
)
4748 if Is_Integer_Type
(Typ
) then
4749 Expand_Divide_Fixed_By_Fixed_Giving_Integer
(N
);
4751 pragma Assert
(Is_Floating_Point_Type
(Typ
));
4752 Expand_Divide_Fixed_By_Fixed_Giving_Float
(N
);
4755 -- Mixed-mode operations can appear in a non-static universal context,
4756 -- in which case the integer argument must be converted explicitly.
4758 elsif Typ
= Universal_Real
4759 and then Is_Integer_Type
(Rtyp
)
4762 Convert_To
(Universal_Real
, Relocate_Node
(Ropnd
)));
4764 Analyze_And_Resolve
(Ropnd
, Universal_Real
);
4766 elsif Typ
= Universal_Real
4767 and then Is_Integer_Type
(Ltyp
)
4770 Convert_To
(Universal_Real
, Relocate_Node
(Lopnd
)));
4772 Analyze_And_Resolve
(Lopnd
, Universal_Real
);
4774 -- Non-fixed point cases, do integer zero divide and overflow checks
4776 elsif Is_Integer_Type
(Typ
) then
4777 Apply_Divide_Check
(N
);
4779 -- Check for 64-bit division available, or long shifts if the divisor
4780 -- is a small power of 2 (since such divides will be converted into
4783 if Esize
(Ltyp
) > 32
4784 and then not Support_64_Bit_Divides_On_Target
4787 or else not Support_Long_Shifts_On_Target
4788 or else (Rval
/= Uint_2
and then
4789 Rval
/= Uint_4
and then
4790 Rval
/= Uint_8
and then
4791 Rval
/= Uint_16
and then
4792 Rval
/= Uint_32
and then
4795 Error_Msg_CRT
("64-bit division", N
);
4798 -- Deal with Vax_Float
4800 elsif Vax_Float
(Typ
) then
4801 Expand_Vax_Arith
(N
);
4804 end Expand_N_Op_Divide
;
4806 --------------------
4807 -- Expand_N_Op_Eq --
4808 --------------------
4810 procedure Expand_N_Op_Eq
(N
: Node_Id
) is
4811 Loc
: constant Source_Ptr
:= Sloc
(N
);
4812 Typ
: constant Entity_Id
:= Etype
(N
);
4813 Lhs
: constant Node_Id
:= Left_Opnd
(N
);
4814 Rhs
: constant Node_Id
:= Right_Opnd
(N
);
4815 Bodies
: constant List_Id
:= New_List
;
4816 A_Typ
: constant Entity_Id
:= Etype
(Lhs
);
4818 Typl
: Entity_Id
:= A_Typ
;
4819 Op_Name
: Entity_Id
;
4822 procedure Build_Equality_Call
(Eq
: Entity_Id
);
4823 -- If a constructed equality exists for the type or for its parent,
4824 -- build and analyze call, adding conversions if the operation is
4827 function Has_Unconstrained_UU_Component
(Typ
: Node_Id
) return Boolean;
4828 -- Determines whether a type has a subcomponent of an unconstrained
4829 -- Unchecked_Union subtype. Typ is a record type.
4831 -------------------------
4832 -- Build_Equality_Call --
4833 -------------------------
4835 procedure Build_Equality_Call
(Eq
: Entity_Id
) is
4836 Op_Type
: constant Entity_Id
:= Etype
(First_Formal
(Eq
));
4837 L_Exp
: Node_Id
:= Relocate_Node
(Lhs
);
4838 R_Exp
: Node_Id
:= Relocate_Node
(Rhs
);
4841 if Base_Type
(Op_Type
) /= Base_Type
(A_Typ
)
4842 and then not Is_Class_Wide_Type
(A_Typ
)
4844 L_Exp
:= OK_Convert_To
(Op_Type
, L_Exp
);
4845 R_Exp
:= OK_Convert_To
(Op_Type
, R_Exp
);
4848 -- If we have an Unchecked_Union, we need to add the inferred
4849 -- discriminant values as actuals in the function call. At this
4850 -- point, the expansion has determined that both operands have
4851 -- inferable discriminants.
4853 if Is_Unchecked_Union
(Op_Type
) then
4855 Lhs_Type
: constant Node_Id
:= Etype
(L_Exp
);
4856 Rhs_Type
: constant Node_Id
:= Etype
(R_Exp
);
4857 Lhs_Discr_Val
: Node_Id
;
4858 Rhs_Discr_Val
: Node_Id
;
4861 -- Per-object constrained selected components require special
4862 -- attention. If the enclosing scope of the component is an
4863 -- Unchecked_Union, we cannot reference its discriminants
4864 -- directly. This is why we use the two extra parameters of
4865 -- the equality function of the enclosing Unchecked_Union.
4867 -- type UU_Type (Discr : Integer := 0) is
4870 -- pragma Unchecked_Union (UU_Type);
4872 -- 1. Unchecked_Union enclosing record:
4874 -- type Enclosing_UU_Type (Discr : Integer := 0) is record
4876 -- Comp : UU_Type (Discr);
4878 -- end Enclosing_UU_Type;
4879 -- pragma Unchecked_Union (Enclosing_UU_Type);
4881 -- Obj1 : Enclosing_UU_Type;
4882 -- Obj2 : Enclosing_UU_Type (1);
4884 -- [. . .] Obj1 = Obj2 [. . .]
4888 -- if not (uu_typeEQ (obj1.comp, obj2.comp, a, b)) then
4890 -- A and B are the formal parameters of the equality function
4891 -- of Enclosing_UU_Type. The function always has two extra
4892 -- formals to capture the inferred discriminant values.
4894 -- 2. Non-Unchecked_Union enclosing record:
4897 -- Enclosing_Non_UU_Type (Discr : Integer := 0)
4900 -- Comp : UU_Type (Discr);
4902 -- end Enclosing_Non_UU_Type;
4904 -- Obj1 : Enclosing_Non_UU_Type;
4905 -- Obj2 : Enclosing_Non_UU_Type (1);
4907 -- ... Obj1 = Obj2 ...
4911 -- if not (uu_typeEQ (obj1.comp, obj2.comp,
4912 -- obj1.discr, obj2.discr)) then
4914 -- In this case we can directly reference the discriminants of
4915 -- the enclosing record.
4919 if Nkind
(Lhs
) = N_Selected_Component
4920 and then Has_Per_Object_Constraint
4921 (Entity
(Selector_Name
(Lhs
)))
4923 -- Enclosing record is an Unchecked_Union, use formal A
4925 if Is_Unchecked_Union
(Scope
4926 (Entity
(Selector_Name
(Lhs
))))
4929 Make_Identifier
(Loc
,
4932 -- Enclosing record is of a non-Unchecked_Union type, it is
4933 -- possible to reference the discriminant.
4937 Make_Selected_Component
(Loc
,
4938 Prefix
=> Prefix
(Lhs
),
4941 (Get_Discriminant_Value
4942 (First_Discriminant
(Lhs_Type
),
4944 Stored_Constraint
(Lhs_Type
))));
4947 -- Comment needed here ???
4950 -- Infer the discriminant value
4954 (Get_Discriminant_Value
4955 (First_Discriminant
(Lhs_Type
),
4957 Stored_Constraint
(Lhs_Type
)));
4962 if Nkind
(Rhs
) = N_Selected_Component
4963 and then Has_Per_Object_Constraint
4964 (Entity
(Selector_Name
(Rhs
)))
4966 if Is_Unchecked_Union
4967 (Scope
(Entity
(Selector_Name
(Rhs
))))
4970 Make_Identifier
(Loc
,
4975 Make_Selected_Component
(Loc
,
4976 Prefix
=> Prefix
(Rhs
),
4978 New_Copy
(Get_Discriminant_Value
(
4979 First_Discriminant
(Rhs_Type
),
4981 Stored_Constraint
(Rhs_Type
))));
4986 New_Copy
(Get_Discriminant_Value
(
4987 First_Discriminant
(Rhs_Type
),
4989 Stored_Constraint
(Rhs_Type
)));
4994 Make_Function_Call
(Loc
,
4995 Name
=> New_Reference_To
(Eq
, Loc
),
4996 Parameter_Associations
=> New_List
(
5003 -- Normal case, not an unchecked union
5007 Make_Function_Call
(Loc
,
5008 Name
=> New_Reference_To
(Eq
, Loc
),
5009 Parameter_Associations
=> New_List
(L_Exp
, R_Exp
)));
5012 Analyze_And_Resolve
(N
, Standard_Boolean
, Suppress
=> All_Checks
);
5013 end Build_Equality_Call
;
5015 ------------------------------------
5016 -- Has_Unconstrained_UU_Component --
5017 ------------------------------------
5019 function Has_Unconstrained_UU_Component
5020 (Typ
: Node_Id
) return Boolean
5022 Tdef
: constant Node_Id
:=
5023 Type_Definition
(Declaration_Node
(Base_Type
(Typ
)));
5027 function Component_Is_Unconstrained_UU
5028 (Comp
: Node_Id
) return Boolean;
5029 -- Determines whether the subtype of the component is an
5030 -- unconstrained Unchecked_Union.
5032 function Variant_Is_Unconstrained_UU
5033 (Variant
: Node_Id
) return Boolean;
5034 -- Determines whether a component of the variant has an unconstrained
5035 -- Unchecked_Union subtype.
5037 -----------------------------------
5038 -- Component_Is_Unconstrained_UU --
5039 -----------------------------------
5041 function Component_Is_Unconstrained_UU
5042 (Comp
: Node_Id
) return Boolean
5045 if Nkind
(Comp
) /= N_Component_Declaration
then
5050 Sindic
: constant Node_Id
:=
5051 Subtype_Indication
(Component_Definition
(Comp
));
5054 -- Unconstrained nominal type. In the case of a constraint
5055 -- present, the node kind would have been N_Subtype_Indication.
5057 if Nkind
(Sindic
) = N_Identifier
then
5058 return Is_Unchecked_Union
(Base_Type
(Etype
(Sindic
)));
5063 end Component_Is_Unconstrained_UU
;
5065 ---------------------------------
5066 -- Variant_Is_Unconstrained_UU --
5067 ---------------------------------
5069 function Variant_Is_Unconstrained_UU
5070 (Variant
: Node_Id
) return Boolean
5072 Clist
: constant Node_Id
:= Component_List
(Variant
);
5075 if Is_Empty_List
(Component_Items
(Clist
)) then
5079 -- We only need to test one component
5082 Comp
: Node_Id
:= First
(Component_Items
(Clist
));
5085 while Present
(Comp
) loop
5086 if Component_Is_Unconstrained_UU
(Comp
) then
5094 -- None of the components withing the variant were of
5095 -- unconstrained Unchecked_Union type.
5098 end Variant_Is_Unconstrained_UU
;
5100 -- Start of processing for Has_Unconstrained_UU_Component
5103 if Null_Present
(Tdef
) then
5107 Clist
:= Component_List
(Tdef
);
5108 Vpart
:= Variant_Part
(Clist
);
5110 -- Inspect available components
5112 if Present
(Component_Items
(Clist
)) then
5114 Comp
: Node_Id
:= First
(Component_Items
(Clist
));
5117 while Present
(Comp
) loop
5119 -- One component is sufficient
5121 if Component_Is_Unconstrained_UU
(Comp
) then
5130 -- Inspect available components withing variants
5132 if Present
(Vpart
) then
5134 Variant
: Node_Id
:= First
(Variants
(Vpart
));
5137 while Present
(Variant
) loop
5139 -- One component within a variant is sufficient
5141 if Variant_Is_Unconstrained_UU
(Variant
) then
5150 -- Neither the available components, nor the components inside the
5151 -- variant parts were of an unconstrained Unchecked_Union subtype.
5154 end Has_Unconstrained_UU_Component
;
5156 -- Start of processing for Expand_N_Op_Eq
5159 Binary_Op_Validity_Checks
(N
);
5161 if Ekind
(Typl
) = E_Private_Type
then
5162 Typl
:= Underlying_Type
(Typl
);
5163 elsif Ekind
(Typl
) = E_Private_Subtype
then
5164 Typl
:= Underlying_Type
(Base_Type
(Typl
));
5169 -- It may happen in error situations that the underlying type is not
5170 -- set. The error will be detected later, here we just defend the
5177 Typl
:= Base_Type
(Typl
);
5179 -- Boolean types (requiring handling of non-standard case)
5181 if Is_Boolean_Type
(Typl
) then
5182 Adjust_Condition
(Left_Opnd
(N
));
5183 Adjust_Condition
(Right_Opnd
(N
));
5184 Set_Etype
(N
, Standard_Boolean
);
5185 Adjust_Result_Type
(N
, Typ
);
5189 elsif Is_Array_Type
(Typl
) then
5191 -- If we are doing full validity checking, and it is possible for the
5192 -- array elements to be invalid then expand out array comparisons to
5193 -- make sure that we check the array elements.
5195 if Validity_Check_Operands
5196 and then not Is_Known_Valid
(Component_Type
(Typl
))
5199 Save_Force_Validity_Checks
: constant Boolean :=
5200 Force_Validity_Checks
;
5202 Force_Validity_Checks
:= True;
5204 Expand_Array_Equality
5206 Relocate_Node
(Lhs
),
5207 Relocate_Node
(Rhs
),
5210 Insert_Actions
(N
, Bodies
);
5211 Analyze_And_Resolve
(N
, Standard_Boolean
);
5212 Force_Validity_Checks
:= Save_Force_Validity_Checks
;
5215 -- Packed case where both operands are known aligned
5217 elsif Is_Bit_Packed_Array
(Typl
)
5218 and then not Is_Possibly_Unaligned_Object
(Lhs
)
5219 and then not Is_Possibly_Unaligned_Object
(Rhs
)
5221 Expand_Packed_Eq
(N
);
5223 -- Where the component type is elementary we can use a block bit
5224 -- comparison (if supported on the target) exception in the case
5225 -- of floating-point (negative zero issues require element by
5226 -- element comparison), and atomic types (where we must be sure
5227 -- to load elements independently) and possibly unaligned arrays.
5229 elsif Is_Elementary_Type
(Component_Type
(Typl
))
5230 and then not Is_Floating_Point_Type
(Component_Type
(Typl
))
5231 and then not Is_Atomic
(Component_Type
(Typl
))
5232 and then not Is_Possibly_Unaligned_Object
(Lhs
)
5233 and then not Is_Possibly_Unaligned_Object
(Rhs
)
5234 and then Support_Composite_Compare_On_Target
5238 -- For composite and floating-point cases, expand equality loop to
5239 -- make sure of using proper comparisons for tagged types, and
5240 -- correctly handling the floating-point case.
5244 Expand_Array_Equality
5246 Relocate_Node
(Lhs
),
5247 Relocate_Node
(Rhs
),
5250 Insert_Actions
(N
, Bodies
, Suppress
=> All_Checks
);
5251 Analyze_And_Resolve
(N
, Standard_Boolean
, Suppress
=> All_Checks
);
5256 elsif Is_Record_Type
(Typl
) then
5258 -- For tagged types, use the primitive "="
5260 if Is_Tagged_Type
(Typl
) then
5262 -- No need to do anything else compiling under restriction
5263 -- No_Dispatching_Calls. During the semantic analysis we
5264 -- already notified such violation.
5266 if Restriction_Active
(No_Dispatching_Calls
) then
5270 -- If this is derived from an untagged private type completed with
5271 -- a tagged type, it does not have a full view, so we use the
5272 -- primitive operations of the private type. This check should no
5273 -- longer be necessary when these types get their full views???
5275 if Is_Private_Type
(A_Typ
)
5276 and then not Is_Tagged_Type
(A_Typ
)
5277 and then Is_Derived_Type
(A_Typ
)
5278 and then No
(Full_View
(A_Typ
))
5280 -- Search for equality operation, checking that the operands
5281 -- have the same type. Note that we must find a matching entry,
5282 -- or something is very wrong!
5284 Prim
:= First_Elmt
(Collect_Primitive_Operations
(A_Typ
));
5286 while Present
(Prim
) loop
5287 exit when Chars
(Node
(Prim
)) = Name_Op_Eq
5288 and then Etype
(First_Formal
(Node
(Prim
))) =
5289 Etype
(Next_Formal
(First_Formal
(Node
(Prim
))))
5291 Base_Type
(Etype
(Node
(Prim
))) = Standard_Boolean
;
5296 pragma Assert
(Present
(Prim
));
5297 Op_Name
:= Node
(Prim
);
5299 -- Find the type's predefined equality or an overriding
5300 -- user- defined equality. The reason for not simply calling
5301 -- Find_Prim_Op here is that there may be a user-defined
5302 -- overloaded equality op that precedes the equality that we want,
5303 -- so we have to explicitly search (e.g., there could be an
5304 -- equality with two different parameter types).
5307 if Is_Class_Wide_Type
(Typl
) then
5308 Typl
:= Root_Type
(Typl
);
5311 Prim
:= First_Elmt
(Primitive_Operations
(Typl
));
5312 while Present
(Prim
) loop
5313 exit when Chars
(Node
(Prim
)) = Name_Op_Eq
5314 and then Etype
(First_Formal
(Node
(Prim
))) =
5315 Etype
(Next_Formal
(First_Formal
(Node
(Prim
))))
5317 Base_Type
(Etype
(Node
(Prim
))) = Standard_Boolean
;
5322 pragma Assert
(Present
(Prim
));
5323 Op_Name
:= Node
(Prim
);
5326 Build_Equality_Call
(Op_Name
);
5328 -- Ada 2005 (AI-216): Program_Error is raised when evaluating the
5329 -- predefined equality operator for a type which has a subcomponent
5330 -- of an Unchecked_Union type whose nominal subtype is unconstrained.
5332 elsif Has_Unconstrained_UU_Component
(Typl
) then
5334 Make_Raise_Program_Error
(Loc
,
5335 Reason
=> PE_Unchecked_Union_Restriction
));
5337 -- Prevent Gigi from generating incorrect code by rewriting the
5338 -- equality as a standard False.
5341 New_Occurrence_Of
(Standard_False
, Loc
));
5343 elsif Is_Unchecked_Union
(Typl
) then
5345 -- If we can infer the discriminants of the operands, we make a
5346 -- call to the TSS equality function.
5348 if Has_Inferable_Discriminants
(Lhs
)
5350 Has_Inferable_Discriminants
(Rhs
)
5353 (TSS
(Root_Type
(Typl
), TSS_Composite_Equality
));
5356 -- Ada 2005 (AI-216): Program_Error is raised when evaluating
5357 -- the predefined equality operator for an Unchecked_Union type
5358 -- if either of the operands lack inferable discriminants.
5361 Make_Raise_Program_Error
(Loc
,
5362 Reason
=> PE_Unchecked_Union_Restriction
));
5364 -- Prevent Gigi from generating incorrect code by rewriting
5365 -- the equality as a standard False.
5368 New_Occurrence_Of
(Standard_False
, Loc
));
5372 -- If a type support function is present (for complex cases), use it
5374 elsif Present
(TSS
(Root_Type
(Typl
), TSS_Composite_Equality
)) then
5376 (TSS
(Root_Type
(Typl
), TSS_Composite_Equality
));
5378 -- Otherwise expand the component by component equality. Note that
5379 -- we never use block-bit comparisons for records, because of the
5380 -- problems with gaps. The backend will often be able to recombine
5381 -- the separate comparisons that we generate here.
5384 Remove_Side_Effects
(Lhs
);
5385 Remove_Side_Effects
(Rhs
);
5387 Expand_Record_Equality
(N
, Typl
, Lhs
, Rhs
, Bodies
));
5389 Insert_Actions
(N
, Bodies
, Suppress
=> All_Checks
);
5390 Analyze_And_Resolve
(N
, Standard_Boolean
, Suppress
=> All_Checks
);
5394 -- Test if result is known at compile time
5396 Rewrite_Comparison
(N
);
5398 -- If we still have comparison for Vax_Float, process it
5400 if Vax_Float
(Typl
) and then Nkind
(N
) in N_Op_Compare
then
5401 Expand_Vax_Comparison
(N
);
5406 -----------------------
5407 -- Expand_N_Op_Expon --
5408 -----------------------
5410 procedure Expand_N_Op_Expon
(N
: Node_Id
) is
5411 Loc
: constant Source_Ptr
:= Sloc
(N
);
5412 Typ
: constant Entity_Id
:= Etype
(N
);
5413 Rtyp
: constant Entity_Id
:= Root_Type
(Typ
);
5414 Base
: constant Node_Id
:= Relocate_Node
(Left_Opnd
(N
));
5415 Bastyp
: constant Node_Id
:= Etype
(Base
);
5416 Exp
: constant Node_Id
:= Relocate_Node
(Right_Opnd
(N
));
5417 Exptyp
: constant Entity_Id
:= Etype
(Exp
);
5418 Ovflo
: constant Boolean := Do_Overflow_Check
(N
);
5427 Binary_Op_Validity_Checks
(N
);
5429 -- If either operand is of a private type, then we have the use of an
5430 -- intrinsic operator, and we get rid of the privateness, by using root
5431 -- types of underlying types for the actual operation. Otherwise the
5432 -- private types will cause trouble if we expand multiplications or
5433 -- shifts etc. We also do this transformation if the result type is
5434 -- different from the base type.
5436 if Is_Private_Type
(Etype
(Base
))
5438 Is_Private_Type
(Typ
)
5440 Is_Private_Type
(Exptyp
)
5442 Rtyp
/= Root_Type
(Bastyp
)
5445 Bt
: constant Entity_Id
:= Root_Type
(Underlying_Type
(Bastyp
));
5446 Et
: constant Entity_Id
:= Root_Type
(Underlying_Type
(Exptyp
));
5450 Unchecked_Convert_To
(Typ
,
5452 Left_Opnd
=> Unchecked_Convert_To
(Bt
, Base
),
5453 Right_Opnd
=> Unchecked_Convert_To
(Et
, Exp
))));
5454 Analyze_And_Resolve
(N
, Typ
);
5459 -- Test for case of known right argument
5461 if Compile_Time_Known_Value
(Exp
) then
5462 Expv
:= Expr_Value
(Exp
);
5464 -- We only fold small non-negative exponents. You might think we
5465 -- could fold small negative exponents for the real case, but we
5466 -- can't because we are required to raise Constraint_Error for
5467 -- the case of 0.0 ** (negative) even if Machine_Overflows = False.
5468 -- See ACVC test C4A012B.
5470 if Expv
>= 0 and then Expv
<= 4 then
5472 -- X ** 0 = 1 (or 1.0)
5476 -- Call Remove_Side_Effects to ensure that any side effects
5477 -- in the ignored left operand (in particular function calls
5478 -- to user defined functions) are properly executed.
5480 Remove_Side_Effects
(Base
);
5482 if Ekind
(Typ
) in Integer_Kind
then
5483 Xnode
:= Make_Integer_Literal
(Loc
, Intval
=> 1);
5485 Xnode
:= Make_Real_Literal
(Loc
, Ureal_1
);
5497 Make_Op_Multiply
(Loc
,
5498 Left_Opnd
=> Duplicate_Subexpr
(Base
),
5499 Right_Opnd
=> Duplicate_Subexpr_No_Checks
(Base
));
5501 -- X ** 3 = X * X * X
5505 Make_Op_Multiply
(Loc
,
5507 Make_Op_Multiply
(Loc
,
5508 Left_Opnd
=> Duplicate_Subexpr
(Base
),
5509 Right_Opnd
=> Duplicate_Subexpr_No_Checks
(Base
)),
5510 Right_Opnd
=> Duplicate_Subexpr_No_Checks
(Base
));
5513 -- En : constant base'type := base * base;
5519 Make_Defining_Identifier
(Loc
, New_Internal_Name
('E'));
5521 Insert_Actions
(N
, New_List
(
5522 Make_Object_Declaration
(Loc
,
5523 Defining_Identifier
=> Temp
,
5524 Constant_Present
=> True,
5525 Object_Definition
=> New_Reference_To
(Typ
, Loc
),
5527 Make_Op_Multiply
(Loc
,
5528 Left_Opnd
=> Duplicate_Subexpr
(Base
),
5529 Right_Opnd
=> Duplicate_Subexpr_No_Checks
(Base
)))));
5532 Make_Op_Multiply
(Loc
,
5533 Left_Opnd
=> New_Reference_To
(Temp
, Loc
),
5534 Right_Opnd
=> New_Reference_To
(Temp
, Loc
));
5538 Analyze_And_Resolve
(N
, Typ
);
5543 -- Case of (2 ** expression) appearing as an argument of an integer
5544 -- multiplication, or as the right argument of a division of a non-
5545 -- negative integer. In such cases we leave the node untouched, setting
5546 -- the flag Is_Natural_Power_Of_2_for_Shift set, then the expansion
5547 -- of the higher level node converts it into a shift.
5549 -- Note: this transformation is not applicable for a modular type with
5550 -- a non-binary modulus in the multiplication case, since we get a wrong
5551 -- result if the shift causes an overflow before the modular reduction.
5553 if Nkind
(Base
) = N_Integer_Literal
5554 and then Intval
(Base
) = 2
5555 and then Is_Integer_Type
(Root_Type
(Exptyp
))
5556 and then Esize
(Root_Type
(Exptyp
)) <= Esize
(Standard_Integer
)
5557 and then Is_Unsigned_Type
(Exptyp
)
5559 and then Nkind
(Parent
(N
)) in N_Binary_Op
5562 P
: constant Node_Id
:= Parent
(N
);
5563 L
: constant Node_Id
:= Left_Opnd
(P
);
5564 R
: constant Node_Id
:= Right_Opnd
(P
);
5567 if (Nkind
(P
) = N_Op_Multiply
5568 and then not Non_Binary_Modulus
(Typ
)
5570 ((Is_Integer_Type
(Etype
(L
)) and then R
= N
)
5572 (Is_Integer_Type
(Etype
(R
)) and then L
= N
))
5573 and then not Do_Overflow_Check
(P
))
5576 (Nkind
(P
) = N_Op_Divide
5577 and then Is_Integer_Type
(Etype
(L
))
5578 and then Is_Unsigned_Type
(Etype
(L
))
5580 and then not Do_Overflow_Check
(P
))
5582 Set_Is_Power_Of_2_For_Shift
(N
);
5588 -- Fall through if exponentiation must be done using a runtime routine
5590 -- First deal with modular case
5592 if Is_Modular_Integer_Type
(Rtyp
) then
5594 -- Non-binary case, we call the special exponentiation routine for
5595 -- the non-binary case, converting the argument to Long_Long_Integer
5596 -- and passing the modulus value. Then the result is converted back
5597 -- to the base type.
5599 if Non_Binary_Modulus
(Rtyp
) then
5602 Make_Function_Call
(Loc
,
5603 Name
=> New_Reference_To
(RTE
(RE_Exp_Modular
), Loc
),
5604 Parameter_Associations
=> New_List
(
5605 Convert_To
(Standard_Integer
, Base
),
5606 Make_Integer_Literal
(Loc
, Modulus
(Rtyp
)),
5609 -- Binary case, in this case, we call one of two routines, either the
5610 -- unsigned integer case, or the unsigned long long integer case,
5611 -- with a final "and" operation to do the required mod.
5614 if UI_To_Int
(Esize
(Rtyp
)) <= Standard_Integer_Size
then
5615 Ent
:= RTE
(RE_Exp_Unsigned
);
5617 Ent
:= RTE
(RE_Exp_Long_Long_Unsigned
);
5624 Make_Function_Call
(Loc
,
5625 Name
=> New_Reference_To
(Ent
, Loc
),
5626 Parameter_Associations
=> New_List
(
5627 Convert_To
(Etype
(First_Formal
(Ent
)), Base
),
5630 Make_Integer_Literal
(Loc
, Modulus
(Rtyp
) - 1))));
5634 -- Common exit point for modular type case
5636 Analyze_And_Resolve
(N
, Typ
);
5639 -- Signed integer cases, done using either Integer or Long_Long_Integer.
5640 -- It is not worth having routines for Short_[Short_]Integer, since for
5641 -- most machines it would not help, and it would generate more code that
5642 -- might need certification when a certified run time is required.
5644 -- In the integer cases, we have two routines, one for when overflow
5645 -- checks are required, and one when they are not required, since there
5646 -- is a real gain in omitting checks on many machines.
5648 elsif Rtyp
= Base_Type
(Standard_Long_Long_Integer
)
5649 or else (Rtyp
= Base_Type
(Standard_Long_Integer
)
5651 Esize
(Standard_Long_Integer
) > Esize
(Standard_Integer
))
5652 or else (Rtyp
= Universal_Integer
)
5654 Etyp
:= Standard_Long_Long_Integer
;
5657 Rent
:= RE_Exp_Long_Long_Integer
;
5659 Rent
:= RE_Exn_Long_Long_Integer
;
5662 elsif Is_Signed_Integer_Type
(Rtyp
) then
5663 Etyp
:= Standard_Integer
;
5666 Rent
:= RE_Exp_Integer
;
5668 Rent
:= RE_Exn_Integer
;
5671 -- Floating-point cases, always done using Long_Long_Float. We do not
5672 -- need separate routines for the overflow case here, since in the case
5673 -- of floating-point, we generate infinities anyway as a rule (either
5674 -- that or we automatically trap overflow), and if there is an infinity
5675 -- generated and a range check is required, the check will fail anyway.
5678 pragma Assert
(Is_Floating_Point_Type
(Rtyp
));
5679 Etyp
:= Standard_Long_Long_Float
;
5680 Rent
:= RE_Exn_Long_Long_Float
;
5683 -- Common processing for integer cases and floating-point cases.
5684 -- If we are in the right type, we can call runtime routine directly
5687 and then Rtyp
/= Universal_Integer
5688 and then Rtyp
/= Universal_Real
5691 Make_Function_Call
(Loc
,
5692 Name
=> New_Reference_To
(RTE
(Rent
), Loc
),
5693 Parameter_Associations
=> New_List
(Base
, Exp
)));
5695 -- Otherwise we have to introduce conversions (conversions are also
5696 -- required in the universal cases, since the runtime routine is
5697 -- typed using one of the standard types.
5702 Make_Function_Call
(Loc
,
5703 Name
=> New_Reference_To
(RTE
(Rent
), Loc
),
5704 Parameter_Associations
=> New_List
(
5705 Convert_To
(Etyp
, Base
),
5709 Analyze_And_Resolve
(N
, Typ
);
5713 when RE_Not_Available
=>
5715 end Expand_N_Op_Expon
;
5717 --------------------
5718 -- Expand_N_Op_Ge --
5719 --------------------
5721 procedure Expand_N_Op_Ge
(N
: Node_Id
) is
5722 Typ
: constant Entity_Id
:= Etype
(N
);
5723 Op1
: constant Node_Id
:= Left_Opnd
(N
);
5724 Op2
: constant Node_Id
:= Right_Opnd
(N
);
5725 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
5728 Binary_Op_Validity_Checks
(N
);
5730 if Is_Array_Type
(Typ1
) then
5731 Expand_Array_Comparison
(N
);
5735 if Is_Boolean_Type
(Typ1
) then
5736 Adjust_Condition
(Op1
);
5737 Adjust_Condition
(Op2
);
5738 Set_Etype
(N
, Standard_Boolean
);
5739 Adjust_Result_Type
(N
, Typ
);
5742 Rewrite_Comparison
(N
);
5744 -- If we still have comparison, and Vax_Float type, process it
5746 if Vax_Float
(Typ1
) and then Nkind
(N
) in N_Op_Compare
then
5747 Expand_Vax_Comparison
(N
);
5752 --------------------
5753 -- Expand_N_Op_Gt --
5754 --------------------
5756 procedure Expand_N_Op_Gt
(N
: Node_Id
) is
5757 Typ
: constant Entity_Id
:= Etype
(N
);
5758 Op1
: constant Node_Id
:= Left_Opnd
(N
);
5759 Op2
: constant Node_Id
:= Right_Opnd
(N
);
5760 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
5763 Binary_Op_Validity_Checks
(N
);
5765 if Is_Array_Type
(Typ1
) then
5766 Expand_Array_Comparison
(N
);
5770 if Is_Boolean_Type
(Typ1
) then
5771 Adjust_Condition
(Op1
);
5772 Adjust_Condition
(Op2
);
5773 Set_Etype
(N
, Standard_Boolean
);
5774 Adjust_Result_Type
(N
, Typ
);
5777 Rewrite_Comparison
(N
);
5779 -- If we still have comparison, and Vax_Float type, process it
5781 if Vax_Float
(Typ1
) and then Nkind
(N
) in N_Op_Compare
then
5782 Expand_Vax_Comparison
(N
);
5787 --------------------
5788 -- Expand_N_Op_Le --
5789 --------------------
5791 procedure Expand_N_Op_Le
(N
: Node_Id
) is
5792 Typ
: constant Entity_Id
:= Etype
(N
);
5793 Op1
: constant Node_Id
:= Left_Opnd
(N
);
5794 Op2
: constant Node_Id
:= Right_Opnd
(N
);
5795 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
5798 Binary_Op_Validity_Checks
(N
);
5800 if Is_Array_Type
(Typ1
) then
5801 Expand_Array_Comparison
(N
);
5805 if Is_Boolean_Type
(Typ1
) then
5806 Adjust_Condition
(Op1
);
5807 Adjust_Condition
(Op2
);
5808 Set_Etype
(N
, Standard_Boolean
);
5809 Adjust_Result_Type
(N
, Typ
);
5812 Rewrite_Comparison
(N
);
5814 -- If we still have comparison, and Vax_Float type, process it
5816 if Vax_Float
(Typ1
) and then Nkind
(N
) in N_Op_Compare
then
5817 Expand_Vax_Comparison
(N
);
5822 --------------------
5823 -- Expand_N_Op_Lt --
5824 --------------------
5826 procedure Expand_N_Op_Lt
(N
: Node_Id
) is
5827 Typ
: constant Entity_Id
:= Etype
(N
);
5828 Op1
: constant Node_Id
:= Left_Opnd
(N
);
5829 Op2
: constant Node_Id
:= Right_Opnd
(N
);
5830 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
5833 Binary_Op_Validity_Checks
(N
);
5835 if Is_Array_Type
(Typ1
) then
5836 Expand_Array_Comparison
(N
);
5840 if Is_Boolean_Type
(Typ1
) then
5841 Adjust_Condition
(Op1
);
5842 Adjust_Condition
(Op2
);
5843 Set_Etype
(N
, Standard_Boolean
);
5844 Adjust_Result_Type
(N
, Typ
);
5847 Rewrite_Comparison
(N
);
5849 -- If we still have comparison, and Vax_Float type, process it
5851 if Vax_Float
(Typ1
) and then Nkind
(N
) in N_Op_Compare
then
5852 Expand_Vax_Comparison
(N
);
5857 -----------------------
5858 -- Expand_N_Op_Minus --
5859 -----------------------
5861 procedure Expand_N_Op_Minus
(N
: Node_Id
) is
5862 Loc
: constant Source_Ptr
:= Sloc
(N
);
5863 Typ
: constant Entity_Id
:= Etype
(N
);
5866 Unary_Op_Validity_Checks
(N
);
5868 if not Backend_Overflow_Checks_On_Target
5869 and then Is_Signed_Integer_Type
(Etype
(N
))
5870 and then Do_Overflow_Check
(N
)
5872 -- Software overflow checking expands -expr into (0 - expr)
5875 Make_Op_Subtract
(Loc
,
5876 Left_Opnd
=> Make_Integer_Literal
(Loc
, 0),
5877 Right_Opnd
=> Right_Opnd
(N
)));
5879 Analyze_And_Resolve
(N
, Typ
);
5881 -- Vax floating-point types case
5883 elsif Vax_Float
(Etype
(N
)) then
5884 Expand_Vax_Arith
(N
);
5886 end Expand_N_Op_Minus
;
5888 ---------------------
5889 -- Expand_N_Op_Mod --
5890 ---------------------
5892 procedure Expand_N_Op_Mod
(N
: Node_Id
) is
5893 Loc
: constant Source_Ptr
:= Sloc
(N
);
5894 Typ
: constant Entity_Id
:= Etype
(N
);
5895 Left
: constant Node_Id
:= Left_Opnd
(N
);
5896 Right
: constant Node_Id
:= Right_Opnd
(N
);
5897 DOC
: constant Boolean := Do_Overflow_Check
(N
);
5898 DDC
: constant Boolean := Do_Division_Check
(N
);
5908 pragma Warnings
(Off
, Lhi
);
5911 Binary_Op_Validity_Checks
(N
);
5913 Determine_Range
(Right
, ROK
, Rlo
, Rhi
);
5914 Determine_Range
(Left
, LOK
, Llo
, Lhi
);
5916 -- Convert mod to rem if operands are known non-negative. We do this
5917 -- since it is quite likely that this will improve the quality of code,
5918 -- (the operation now corresponds to the hardware remainder), and it
5919 -- does not seem likely that it could be harmful.
5921 if LOK
and then Llo
>= 0
5923 ROK
and then Rlo
>= 0
5926 Make_Op_Rem
(Sloc
(N
),
5927 Left_Opnd
=> Left_Opnd
(N
),
5928 Right_Opnd
=> Right_Opnd
(N
)));
5930 -- Instead of reanalyzing the node we do the analysis manually. This
5931 -- avoids anomalies when the replacement is done in an instance and
5932 -- is epsilon more efficient.
5934 Set_Entity
(N
, Standard_Entity
(S_Op_Rem
));
5936 Set_Do_Overflow_Check
(N
, DOC
);
5937 Set_Do_Division_Check
(N
, DDC
);
5938 Expand_N_Op_Rem
(N
);
5941 -- Otherwise, normal mod processing
5944 if Is_Integer_Type
(Etype
(N
)) then
5945 Apply_Divide_Check
(N
);
5948 -- Apply optimization x mod 1 = 0. We don't really need that with
5949 -- gcc, but it is useful with other back ends (e.g. AAMP), and is
5950 -- certainly harmless.
5952 if Is_Integer_Type
(Etype
(N
))
5953 and then Compile_Time_Known_Value
(Right
)
5954 and then Expr_Value
(Right
) = Uint_1
5956 -- Call Remove_Side_Effects to ensure that any side effects in
5957 -- the ignored left operand (in particular function calls to
5958 -- user defined functions) are properly executed.
5960 Remove_Side_Effects
(Left
);
5962 Rewrite
(N
, Make_Integer_Literal
(Loc
, 0));
5963 Analyze_And_Resolve
(N
, Typ
);
5967 -- Deal with annoying case of largest negative number remainder
5968 -- minus one. Gigi does not handle this case correctly, because
5969 -- it generates a divide instruction which may trap in this case.
5971 -- In fact the check is quite easy, if the right operand is -1, then
5972 -- the mod value is always 0, and we can just ignore the left operand
5973 -- completely in this case.
5975 -- The operand type may be private (e.g. in the expansion of an
5976 -- intrinsic operation) so we must use the underlying type to get the
5977 -- bounds, and convert the literals explicitly.
5981 (Type_Low_Bound
(Base_Type
(Underlying_Type
(Etype
(Left
)))));
5983 if ((not ROK
) or else (Rlo
<= (-1) and then (-1) <= Rhi
))
5985 ((not LOK
) or else (Llo
= LLB
))
5988 Make_Conditional_Expression
(Loc
,
5989 Expressions
=> New_List
(
5991 Left_Opnd
=> Duplicate_Subexpr
(Right
),
5993 Unchecked_Convert_To
(Typ
,
5994 Make_Integer_Literal
(Loc
, -1))),
5995 Unchecked_Convert_To
(Typ
,
5996 Make_Integer_Literal
(Loc
, Uint_0
)),
5997 Relocate_Node
(N
))));
5999 Set_Analyzed
(Next
(Next
(First
(Expressions
(N
)))));
6000 Analyze_And_Resolve
(N
, Typ
);
6003 end Expand_N_Op_Mod
;
6005 --------------------------
6006 -- Expand_N_Op_Multiply --
6007 --------------------------
6009 procedure Expand_N_Op_Multiply
(N
: Node_Id
) is
6010 Loc
: constant Source_Ptr
:= Sloc
(N
);
6011 Lop
: constant Node_Id
:= Left_Opnd
(N
);
6012 Rop
: constant Node_Id
:= Right_Opnd
(N
);
6014 Lp2
: constant Boolean :=
6015 Nkind
(Lop
) = N_Op_Expon
6016 and then Is_Power_Of_2_For_Shift
(Lop
);
6018 Rp2
: constant Boolean :=
6019 Nkind
(Rop
) = N_Op_Expon
6020 and then Is_Power_Of_2_For_Shift
(Rop
);
6022 Ltyp
: constant Entity_Id
:= Etype
(Lop
);
6023 Rtyp
: constant Entity_Id
:= Etype
(Rop
);
6024 Typ
: Entity_Id
:= Etype
(N
);
6027 Binary_Op_Validity_Checks
(N
);
6029 -- Special optimizations for integer types
6031 if Is_Integer_Type
(Typ
) then
6033 -- N * 0 = 0 for integer types
6035 if Compile_Time_Known_Value
(Rop
)
6036 and then Expr_Value
(Rop
) = Uint_0
6038 -- Call Remove_Side_Effects to ensure that any side effects in
6039 -- the ignored left operand (in particular function calls to
6040 -- user defined functions) are properly executed.
6042 Remove_Side_Effects
(Lop
);
6044 Rewrite
(N
, Make_Integer_Literal
(Loc
, Uint_0
));
6045 Analyze_And_Resolve
(N
, Typ
);
6049 -- Similar handling for 0 * N = 0
6051 if Compile_Time_Known_Value
(Lop
)
6052 and then Expr_Value
(Lop
) = Uint_0
6054 Remove_Side_Effects
(Rop
);
6055 Rewrite
(N
, Make_Integer_Literal
(Loc
, Uint_0
));
6056 Analyze_And_Resolve
(N
, Typ
);
6060 -- N * 1 = 1 * N = N for integer types
6062 -- This optimisation is not done if we are going to
6063 -- rewrite the product 1 * 2 ** N to a shift.
6065 if Compile_Time_Known_Value
(Rop
)
6066 and then Expr_Value
(Rop
) = Uint_1
6072 elsif Compile_Time_Known_Value
(Lop
)
6073 and then Expr_Value
(Lop
) = Uint_1
6081 -- Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that
6082 -- Is_Power_Of_2_For_Shift is set means that we know that our left
6083 -- operand is an integer, as required for this to work.
6088 -- Convert 2 ** A * 2 ** B into 2 ** (A + B)
6092 Left_Opnd
=> Make_Integer_Literal
(Loc
, 2),
6095 Left_Opnd
=> Right_Opnd
(Lop
),
6096 Right_Opnd
=> Right_Opnd
(Rop
))));
6097 Analyze_And_Resolve
(N
, Typ
);
6102 Make_Op_Shift_Left
(Loc
,
6105 Convert_To
(Standard_Natural
, Right_Opnd
(Rop
))));
6106 Analyze_And_Resolve
(N
, Typ
);
6110 -- Same processing for the operands the other way round
6114 Make_Op_Shift_Left
(Loc
,
6117 Convert_To
(Standard_Natural
, Right_Opnd
(Lop
))));
6118 Analyze_And_Resolve
(N
, Typ
);
6122 -- Do required fixup of universal fixed operation
6124 if Typ
= Universal_Fixed
then
6125 Fixup_Universal_Fixed_Operation
(N
);
6129 -- Multiplications with fixed-point results
6131 if Is_Fixed_Point_Type
(Typ
) then
6133 -- No special processing if Treat_Fixed_As_Integer is set, since from
6134 -- a semantic point of view such operations are simply integer
6135 -- operations and will be treated that way.
6137 if not Treat_Fixed_As_Integer
(N
) then
6139 -- Case of fixed * integer => fixed
6141 if Is_Integer_Type
(Rtyp
) then
6142 Expand_Multiply_Fixed_By_Integer_Giving_Fixed
(N
);
6144 -- Case of integer * fixed => fixed
6146 elsif Is_Integer_Type
(Ltyp
) then
6147 Expand_Multiply_Integer_By_Fixed_Giving_Fixed
(N
);
6149 -- Case of fixed * fixed => fixed
6152 Expand_Multiply_Fixed_By_Fixed_Giving_Fixed
(N
);
6156 -- Other cases of multiplication of fixed-point operands. Again we
6157 -- exclude the cases where Treat_Fixed_As_Integer flag is set.
6159 elsif (Is_Fixed_Point_Type
(Ltyp
) or else Is_Fixed_Point_Type
(Rtyp
))
6160 and then not Treat_Fixed_As_Integer
(N
)
6162 if Is_Integer_Type
(Typ
) then
6163 Expand_Multiply_Fixed_By_Fixed_Giving_Integer
(N
);
6165 pragma Assert
(Is_Floating_Point_Type
(Typ
));
6166 Expand_Multiply_Fixed_By_Fixed_Giving_Float
(N
);
6169 -- Mixed-mode operations can appear in a non-static universal context,
6170 -- in which case the integer argument must be converted explicitly.
6172 elsif Typ
= Universal_Real
6173 and then Is_Integer_Type
(Rtyp
)
6175 Rewrite
(Rop
, Convert_To
(Universal_Real
, Relocate_Node
(Rop
)));
6177 Analyze_And_Resolve
(Rop
, Universal_Real
);
6179 elsif Typ
= Universal_Real
6180 and then Is_Integer_Type
(Ltyp
)
6182 Rewrite
(Lop
, Convert_To
(Universal_Real
, Relocate_Node
(Lop
)));
6184 Analyze_And_Resolve
(Lop
, Universal_Real
);
6186 -- Non-fixed point cases, check software overflow checking required
6188 elsif Is_Signed_Integer_Type
(Etype
(N
)) then
6189 Apply_Arithmetic_Overflow_Check
(N
);
6191 -- Deal with VAX float case
6193 elsif Vax_Float
(Typ
) then
6194 Expand_Vax_Arith
(N
);
6197 end Expand_N_Op_Multiply
;
6199 --------------------
6200 -- Expand_N_Op_Ne --
6201 --------------------
6203 procedure Expand_N_Op_Ne
(N
: Node_Id
) is
6204 Typ
: constant Entity_Id
:= Etype
(Left_Opnd
(N
));
6207 -- Case of elementary type with standard operator
6209 if Is_Elementary_Type
(Typ
)
6210 and then Sloc
(Entity
(N
)) = Standard_Location
6212 Binary_Op_Validity_Checks
(N
);
6214 -- Boolean types (requiring handling of non-standard case)
6216 if Is_Boolean_Type
(Typ
) then
6217 Adjust_Condition
(Left_Opnd
(N
));
6218 Adjust_Condition
(Right_Opnd
(N
));
6219 Set_Etype
(N
, Standard_Boolean
);
6220 Adjust_Result_Type
(N
, Typ
);
6223 Rewrite_Comparison
(N
);
6225 -- If we still have comparison for Vax_Float, process it
6227 if Vax_Float
(Typ
) and then Nkind
(N
) in N_Op_Compare
then
6228 Expand_Vax_Comparison
(N
);
6232 -- For all cases other than elementary types, we rewrite node as the
6233 -- negation of an equality operation, and reanalyze. The equality to be
6234 -- used is defined in the same scope and has the same signature. This
6235 -- signature must be set explicitly since in an instance it may not have
6236 -- the same visibility as in the generic unit. This avoids duplicating
6237 -- or factoring the complex code for record/array equality tests etc.
6241 Loc
: constant Source_Ptr
:= Sloc
(N
);
6243 Ne
: constant Entity_Id
:= Entity
(N
);
6246 Binary_Op_Validity_Checks
(N
);
6252 Left_Opnd
=> Left_Opnd
(N
),
6253 Right_Opnd
=> Right_Opnd
(N
)));
6254 Set_Paren_Count
(Right_Opnd
(Neg
), 1);
6256 if Scope
(Ne
) /= Standard_Standard
then
6257 Set_Entity
(Right_Opnd
(Neg
), Corresponding_Equality
(Ne
));
6260 -- For navigation purposes, the inequality is treated as an
6261 -- implicit reference to the corresponding equality. Preserve the
6262 -- Comes_From_ source flag so that the proper Xref entry is
6265 Preserve_Comes_From_Source
(Neg
, N
);
6266 Preserve_Comes_From_Source
(Right_Opnd
(Neg
), N
);
6268 Analyze_And_Resolve
(N
, Standard_Boolean
);
6273 ---------------------
6274 -- Expand_N_Op_Not --
6275 ---------------------
6277 -- If the argument is other than a Boolean array type, there is no special
6278 -- expansion required.
6280 -- For the packed case, we call the special routine in Exp_Pakd, except
6281 -- that if the component size is greater than one, we use the standard
6282 -- routine generating a gruesome loop (it is so peculiar to have packed
6283 -- arrays with non-standard Boolean representations anyway, so it does not
6284 -- matter that we do not handle this case efficiently).
6286 -- For the unpacked case (and for the special packed case where we have non
6287 -- standard Booleans, as discussed above), we generate and insert into the
6288 -- tree the following function definition:
6290 -- function Nnnn (A : arr) is
6293 -- for J in a'range loop
6294 -- B (J) := not A (J);
6299 -- Here arr is the actual subtype of the parameter (and hence always
6300 -- constrained). Then we replace the not with a call to this function.
6302 procedure Expand_N_Op_Not
(N
: Node_Id
) is
6303 Loc
: constant Source_Ptr
:= Sloc
(N
);
6304 Typ
: constant Entity_Id
:= Etype
(N
);
6313 Func_Name
: Entity_Id
;
6314 Loop_Statement
: Node_Id
;
6317 Unary_Op_Validity_Checks
(N
);
6319 -- For boolean operand, deal with non-standard booleans
6321 if Is_Boolean_Type
(Typ
) then
6322 Adjust_Condition
(Right_Opnd
(N
));
6323 Set_Etype
(N
, Standard_Boolean
);
6324 Adjust_Result_Type
(N
, Typ
);
6328 -- Only array types need any other processing
6330 if not Is_Array_Type
(Typ
) then
6334 -- Case of array operand. If bit packed with a component size of 1,
6335 -- handle it in Exp_Pakd if the operand is known to be aligned.
6337 if Is_Bit_Packed_Array
(Typ
)
6338 and then Component_Size
(Typ
) = 1
6339 and then not Is_Possibly_Unaligned_Object
(Right_Opnd
(N
))
6341 Expand_Packed_Not
(N
);
6345 -- Case of array operand which is not bit-packed. If the context is
6346 -- a safe assignment, call in-place operation, If context is a larger
6347 -- boolean expression in the context of a safe assignment, expansion is
6348 -- done by enclosing operation.
6350 Opnd
:= Relocate_Node
(Right_Opnd
(N
));
6351 Convert_To_Actual_Subtype
(Opnd
);
6352 Arr
:= Etype
(Opnd
);
6353 Ensure_Defined
(Arr
, N
);
6354 Silly_Boolean_Array_Not_Test
(N
, Arr
);
6356 if Nkind
(Parent
(N
)) = N_Assignment_Statement
then
6357 if Safe_In_Place_Array_Op
(Name
(Parent
(N
)), N
, Empty
) then
6358 Build_Boolean_Array_Proc_Call
(Parent
(N
), Opnd
, Empty
);
6361 -- Special case the negation of a binary operation
6363 elsif Nkind_In
(Opnd
, N_Op_And
, N_Op_Or
, N_Op_Xor
)
6364 and then Safe_In_Place_Array_Op
6365 (Name
(Parent
(N
)), Left_Opnd
(Opnd
), Right_Opnd
(Opnd
))
6367 Build_Boolean_Array_Proc_Call
(Parent
(N
), Opnd
, Empty
);
6371 elsif Nkind
(Parent
(N
)) in N_Binary_Op
6372 and then Nkind
(Parent
(Parent
(N
))) = N_Assignment_Statement
6375 Op1
: constant Node_Id
:= Left_Opnd
(Parent
(N
));
6376 Op2
: constant Node_Id
:= Right_Opnd
(Parent
(N
));
6377 Lhs
: constant Node_Id
:= Name
(Parent
(Parent
(N
)));
6380 if Safe_In_Place_Array_Op
(Lhs
, Op1
, Op2
) then
6382 and then Nkind
(Op2
) = N_Op_Not
6384 -- (not A) op (not B) can be reduced to a single call
6389 and then Nkind
(Parent
(N
)) = N_Op_Xor
6391 -- A xor (not B) can also be special-cased
6399 A
:= Make_Defining_Identifier
(Loc
, Name_uA
);
6400 B
:= Make_Defining_Identifier
(Loc
, Name_uB
);
6401 J
:= Make_Defining_Identifier
(Loc
, Name_uJ
);
6404 Make_Indexed_Component
(Loc
,
6405 Prefix
=> New_Reference_To
(A
, Loc
),
6406 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
6409 Make_Indexed_Component
(Loc
,
6410 Prefix
=> New_Reference_To
(B
, Loc
),
6411 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
6414 Make_Implicit_Loop_Statement
(N
,
6415 Identifier
=> Empty
,
6418 Make_Iteration_Scheme
(Loc
,
6419 Loop_Parameter_Specification
=>
6420 Make_Loop_Parameter_Specification
(Loc
,
6421 Defining_Identifier
=> J
,
6422 Discrete_Subtype_Definition
=>
6423 Make_Attribute_Reference
(Loc
,
6424 Prefix
=> Make_Identifier
(Loc
, Chars
(A
)),
6425 Attribute_Name
=> Name_Range
))),
6427 Statements
=> New_List
(
6428 Make_Assignment_Statement
(Loc
,
6430 Expression
=> Make_Op_Not
(Loc
, A_J
))));
6432 Func_Name
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('N'));
6433 Set_Is_Inlined
(Func_Name
);
6436 Make_Subprogram_Body
(Loc
,
6438 Make_Function_Specification
(Loc
,
6439 Defining_Unit_Name
=> Func_Name
,
6440 Parameter_Specifications
=> New_List
(
6441 Make_Parameter_Specification
(Loc
,
6442 Defining_Identifier
=> A
,
6443 Parameter_Type
=> New_Reference_To
(Typ
, Loc
))),
6444 Result_Definition
=> New_Reference_To
(Typ
, Loc
)),
6446 Declarations
=> New_List
(
6447 Make_Object_Declaration
(Loc
,
6448 Defining_Identifier
=> B
,
6449 Object_Definition
=> New_Reference_To
(Arr
, Loc
))),
6451 Handled_Statement_Sequence
=>
6452 Make_Handled_Sequence_Of_Statements
(Loc
,
6453 Statements
=> New_List
(
6455 Make_Simple_Return_Statement
(Loc
,
6457 Make_Identifier
(Loc
, Chars
(B
)))))));
6460 Make_Function_Call
(Loc
,
6461 Name
=> New_Reference_To
(Func_Name
, Loc
),
6462 Parameter_Associations
=> New_List
(Opnd
)));
6464 Analyze_And_Resolve
(N
, Typ
);
6465 end Expand_N_Op_Not
;
6467 --------------------
6468 -- Expand_N_Op_Or --
6469 --------------------
6471 procedure Expand_N_Op_Or
(N
: Node_Id
) is
6472 Typ
: constant Entity_Id
:= Etype
(N
);
6475 Binary_Op_Validity_Checks
(N
);
6477 if Is_Array_Type
(Etype
(N
)) then
6478 Expand_Boolean_Operator
(N
);
6480 elsif Is_Boolean_Type
(Etype
(N
)) then
6481 Adjust_Condition
(Left_Opnd
(N
));
6482 Adjust_Condition
(Right_Opnd
(N
));
6483 Set_Etype
(N
, Standard_Boolean
);
6484 Adjust_Result_Type
(N
, Typ
);
6488 ----------------------
6489 -- Expand_N_Op_Plus --
6490 ----------------------
6492 procedure Expand_N_Op_Plus
(N
: Node_Id
) is
6494 Unary_Op_Validity_Checks
(N
);
6495 end Expand_N_Op_Plus
;
6497 ---------------------
6498 -- Expand_N_Op_Rem --
6499 ---------------------
6501 procedure Expand_N_Op_Rem
(N
: Node_Id
) is
6502 Loc
: constant Source_Ptr
:= Sloc
(N
);
6503 Typ
: constant Entity_Id
:= Etype
(N
);
6505 Left
: constant Node_Id
:= Left_Opnd
(N
);
6506 Right
: constant Node_Id
:= Right_Opnd
(N
);
6516 pragma Warnings
(Off
, Lhi
);
6519 Binary_Op_Validity_Checks
(N
);
6521 if Is_Integer_Type
(Etype
(N
)) then
6522 Apply_Divide_Check
(N
);
6525 -- Apply optimization x rem 1 = 0. We don't really need that with gcc,
6526 -- but it is useful with other back ends (e.g. AAMP), and is certainly
6529 if Is_Integer_Type
(Etype
(N
))
6530 and then Compile_Time_Known_Value
(Right
)
6531 and then Expr_Value
(Right
) = Uint_1
6533 -- Call Remove_Side_Effects to ensure that any side effects in the
6534 -- ignored left operand (in particular function calls to user defined
6535 -- functions) are properly executed.
6537 Remove_Side_Effects
(Left
);
6539 Rewrite
(N
, Make_Integer_Literal
(Loc
, 0));
6540 Analyze_And_Resolve
(N
, Typ
);
6544 -- Deal with annoying case of largest negative number remainder minus
6545 -- one. Gigi does not handle this case correctly, because it generates
6546 -- a divide instruction which may trap in this case.
6548 -- In fact the check is quite easy, if the right operand is -1, then
6549 -- the remainder is always 0, and we can just ignore the left operand
6550 -- completely in this case.
6552 Determine_Range
(Right
, ROK
, Rlo
, Rhi
);
6553 Determine_Range
(Left
, LOK
, Llo
, Lhi
);
6555 -- The operand type may be private (e.g. in the expansion of an
6556 -- intrinsic operation) so we must use the underlying type to get the
6557 -- bounds, and convert the literals explicitly.
6561 (Type_Low_Bound
(Base_Type
(Underlying_Type
(Etype
(Left
)))));
6563 -- Now perform the test, generating code only if needed
6565 if ((not ROK
) or else (Rlo
<= (-1) and then (-1) <= Rhi
))
6567 ((not LOK
) or else (Llo
= LLB
))
6570 Make_Conditional_Expression
(Loc
,
6571 Expressions
=> New_List
(
6573 Left_Opnd
=> Duplicate_Subexpr
(Right
),
6575 Unchecked_Convert_To
(Typ
,
6576 Make_Integer_Literal
(Loc
, -1))),
6578 Unchecked_Convert_To
(Typ
,
6579 Make_Integer_Literal
(Loc
, Uint_0
)),
6581 Relocate_Node
(N
))));
6583 Set_Analyzed
(Next
(Next
(First
(Expressions
(N
)))));
6584 Analyze_And_Resolve
(N
, Typ
);
6586 end Expand_N_Op_Rem
;
6588 -----------------------------
6589 -- Expand_N_Op_Rotate_Left --
6590 -----------------------------
6592 procedure Expand_N_Op_Rotate_Left
(N
: Node_Id
) is
6594 Binary_Op_Validity_Checks
(N
);
6595 end Expand_N_Op_Rotate_Left
;
6597 ------------------------------
6598 -- Expand_N_Op_Rotate_Right --
6599 ------------------------------
6601 procedure Expand_N_Op_Rotate_Right
(N
: Node_Id
) is
6603 Binary_Op_Validity_Checks
(N
);
6604 end Expand_N_Op_Rotate_Right
;
6606 ----------------------------
6607 -- Expand_N_Op_Shift_Left --
6608 ----------------------------
6610 procedure Expand_N_Op_Shift_Left
(N
: Node_Id
) is
6612 Binary_Op_Validity_Checks
(N
);
6613 end Expand_N_Op_Shift_Left
;
6615 -----------------------------
6616 -- Expand_N_Op_Shift_Right --
6617 -----------------------------
6619 procedure Expand_N_Op_Shift_Right
(N
: Node_Id
) is
6621 Binary_Op_Validity_Checks
(N
);
6622 end Expand_N_Op_Shift_Right
;
6624 ----------------------------------------
6625 -- Expand_N_Op_Shift_Right_Arithmetic --
6626 ----------------------------------------
6628 procedure Expand_N_Op_Shift_Right_Arithmetic
(N
: Node_Id
) is
6630 Binary_Op_Validity_Checks
(N
);
6631 end Expand_N_Op_Shift_Right_Arithmetic
;
6633 --------------------------
6634 -- Expand_N_Op_Subtract --
6635 --------------------------
6637 procedure Expand_N_Op_Subtract
(N
: Node_Id
) is
6638 Typ
: constant Entity_Id
:= Etype
(N
);
6641 Binary_Op_Validity_Checks
(N
);
6643 -- N - 0 = N for integer types
6645 if Is_Integer_Type
(Typ
)
6646 and then Compile_Time_Known_Value
(Right_Opnd
(N
))
6647 and then Expr_Value
(Right_Opnd
(N
)) = 0
6649 Rewrite
(N
, Left_Opnd
(N
));
6653 -- Arithmetic overflow checks for signed integer/fixed point types
6655 if Is_Signed_Integer_Type
(Typ
)
6656 or else Is_Fixed_Point_Type
(Typ
)
6658 Apply_Arithmetic_Overflow_Check
(N
);
6660 -- Vax floating-point types case
6662 elsif Vax_Float
(Typ
) then
6663 Expand_Vax_Arith
(N
);
6665 end Expand_N_Op_Subtract
;
6667 ---------------------
6668 -- Expand_N_Op_Xor --
6669 ---------------------
6671 procedure Expand_N_Op_Xor
(N
: Node_Id
) is
6672 Typ
: constant Entity_Id
:= Etype
(N
);
6675 Binary_Op_Validity_Checks
(N
);
6677 if Is_Array_Type
(Etype
(N
)) then
6678 Expand_Boolean_Operator
(N
);
6680 elsif Is_Boolean_Type
(Etype
(N
)) then
6681 Adjust_Condition
(Left_Opnd
(N
));
6682 Adjust_Condition
(Right_Opnd
(N
));
6683 Set_Etype
(N
, Standard_Boolean
);
6684 Adjust_Result_Type
(N
, Typ
);
6686 end Expand_N_Op_Xor
;
6688 ----------------------
6689 -- Expand_N_Or_Else --
6690 ----------------------
6692 -- Expand into conditional expression if Actions present, and also
6693 -- deal with optimizing case of arguments being True or False.
6695 procedure Expand_N_Or_Else
(N
: Node_Id
) is
6696 Loc
: constant Source_Ptr
:= Sloc
(N
);
6697 Typ
: constant Entity_Id
:= Etype
(N
);
6698 Left
: constant Node_Id
:= Left_Opnd
(N
);
6699 Right
: constant Node_Id
:= Right_Opnd
(N
);
6703 -- Deal with non-standard booleans
6705 if Is_Boolean_Type
(Typ
) then
6706 Adjust_Condition
(Left
);
6707 Adjust_Condition
(Right
);
6708 Set_Etype
(N
, Standard_Boolean
);
6711 -- Check for cases where left argument is known to be True or False
6713 if Compile_Time_Known_Value
(Left
) then
6715 -- If left argument is False, change (False or else Right) to Right.
6716 -- Any actions associated with Right will be executed unconditionally
6717 -- and can thus be inserted into the tree unconditionally.
6719 if Expr_Value_E
(Left
) = Standard_False
then
6720 if Present
(Actions
(N
)) then
6721 Insert_Actions
(N
, Actions
(N
));
6726 -- If left argument is True, change (True and then Right) to True. In
6727 -- this case we can forget the actions associated with Right, since
6728 -- they will never be executed.
6730 else pragma Assert
(Expr_Value_E
(Left
) = Standard_True
);
6731 Kill_Dead_Code
(Right
);
6732 Kill_Dead_Code
(Actions
(N
));
6733 Rewrite
(N
, New_Occurrence_Of
(Standard_True
, Loc
));
6736 Adjust_Result_Type
(N
, Typ
);
6740 -- If Actions are present, we expand
6742 -- left or else right
6746 -- if left then True else right end
6748 -- with the actions becoming the Else_Actions of the conditional
6749 -- expression. This conditional expression is then further expanded
6750 -- (and will eventually disappear)
6752 if Present
(Actions
(N
)) then
6753 Actlist
:= Actions
(N
);
6755 Make_Conditional_Expression
(Loc
,
6756 Expressions
=> New_List
(
6758 New_Occurrence_Of
(Standard_True
, Loc
),
6761 Set_Else_Actions
(N
, Actlist
);
6762 Analyze_And_Resolve
(N
, Standard_Boolean
);
6763 Adjust_Result_Type
(N
, Typ
);
6767 -- No actions present, check for cases of right argument True/False
6769 if Compile_Time_Known_Value
(Right
) then
6771 -- Change (Left or else False) to Left. Note that we know there are
6772 -- no actions associated with the True operand, since we just checked
6773 -- for this case above.
6775 if Expr_Value_E
(Right
) = Standard_False
then
6778 -- Change (Left or else True) to True, making sure to preserve any
6779 -- side effects associated with the Left operand.
6781 else pragma Assert
(Expr_Value_E
(Right
) = Standard_True
);
6782 Remove_Side_Effects
(Left
);
6784 (N
, New_Occurrence_Of
(Standard_True
, Loc
));
6788 Adjust_Result_Type
(N
, Typ
);
6789 end Expand_N_Or_Else
;
6791 -----------------------------------
6792 -- Expand_N_Qualified_Expression --
6793 -----------------------------------
6795 procedure Expand_N_Qualified_Expression
(N
: Node_Id
) is
6796 Operand
: constant Node_Id
:= Expression
(N
);
6797 Target_Type
: constant Entity_Id
:= Entity
(Subtype_Mark
(N
));
6800 -- Do validity check if validity checking operands
6802 if Validity_Checks_On
6803 and then Validity_Check_Operands
6805 Ensure_Valid
(Operand
);
6808 -- Apply possible constraint check
6810 Apply_Constraint_Check
(Operand
, Target_Type
, No_Sliding
=> True);
6811 end Expand_N_Qualified_Expression
;
6813 ---------------------------------
6814 -- Expand_N_Selected_Component --
6815 ---------------------------------
6817 -- If the selector is a discriminant of a concurrent object, rewrite the
6818 -- prefix to denote the corresponding record type.
6820 procedure Expand_N_Selected_Component
(N
: Node_Id
) is
6821 Loc
: constant Source_Ptr
:= Sloc
(N
);
6822 Par
: constant Node_Id
:= Parent
(N
);
6823 P
: constant Node_Id
:= Prefix
(N
);
6824 Ptyp
: Entity_Id
:= Underlying_Type
(Etype
(P
));
6829 function In_Left_Hand_Side
(Comp
: Node_Id
) return Boolean;
6830 -- Gigi needs a temporary for prefixes that depend on a discriminant,
6831 -- unless the context of an assignment can provide size information.
6832 -- Don't we have a general routine that does this???
6834 -----------------------
6835 -- In_Left_Hand_Side --
6836 -----------------------
6838 function In_Left_Hand_Side
(Comp
: Node_Id
) return Boolean is
6840 return (Nkind
(Parent
(Comp
)) = N_Assignment_Statement
6841 and then Comp
= Name
(Parent
(Comp
)))
6842 or else (Present
(Parent
(Comp
))
6843 and then Nkind
(Parent
(Comp
)) in N_Subexpr
6844 and then In_Left_Hand_Side
(Parent
(Comp
)));
6845 end In_Left_Hand_Side
;
6847 -- Start of processing for Expand_N_Selected_Component
6850 -- Insert explicit dereference if required
6852 if Is_Access_Type
(Ptyp
) then
6853 Insert_Explicit_Dereference
(P
);
6854 Analyze_And_Resolve
(P
, Designated_Type
(Ptyp
));
6856 if Ekind
(Etype
(P
)) = E_Private_Subtype
6857 and then Is_For_Access_Subtype
(Etype
(P
))
6859 Set_Etype
(P
, Base_Type
(Etype
(P
)));
6865 -- Deal with discriminant check required
6867 if Do_Discriminant_Check
(N
) then
6869 -- Present the discriminant checking function to the backend, so that
6870 -- it can inline the call to the function.
6873 (Discriminant_Checking_Func
6874 (Original_Record_Component
(Entity
(Selector_Name
(N
)))));
6876 -- Now reset the flag and generate the call
6878 Set_Do_Discriminant_Check
(N
, False);
6879 Generate_Discriminant_Check
(N
);
6882 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
6883 -- function, then additional actuals must be passed.
6885 if Ada_Version
>= Ada_05
6886 and then Is_Build_In_Place_Function_Call
(P
)
6888 Make_Build_In_Place_Call_In_Anonymous_Context
(P
);
6891 -- Gigi cannot handle unchecked conversions that are the prefix of a
6892 -- selected component with discriminants. This must be checked during
6893 -- expansion, because during analysis the type of the selector is not
6894 -- known at the point the prefix is analyzed. If the conversion is the
6895 -- target of an assignment, then we cannot force the evaluation.
6897 if Nkind
(Prefix
(N
)) = N_Unchecked_Type_Conversion
6898 and then Has_Discriminants
(Etype
(N
))
6899 and then not In_Left_Hand_Side
(N
)
6901 Force_Evaluation
(Prefix
(N
));
6904 -- Remaining processing applies only if selector is a discriminant
6906 if Ekind
(Entity
(Selector_Name
(N
))) = E_Discriminant
then
6908 -- If the selector is a discriminant of a constrained record type,
6909 -- we may be able to rewrite the expression with the actual value
6910 -- of the discriminant, a useful optimization in some cases.
6912 if Is_Record_Type
(Ptyp
)
6913 and then Has_Discriminants
(Ptyp
)
6914 and then Is_Constrained
(Ptyp
)
6916 -- Do this optimization for discrete types only, and not for
6917 -- access types (access discriminants get us into trouble!)
6919 if not Is_Discrete_Type
(Etype
(N
)) then
6922 -- Don't do this on the left hand of an assignment statement.
6923 -- Normally one would think that references like this would
6924 -- not occur, but they do in generated code, and mean that
6925 -- we really do want to assign the discriminant!
6927 elsif Nkind
(Par
) = N_Assignment_Statement
6928 and then Name
(Par
) = N
6932 -- Don't do this optimization for the prefix of an attribute or
6933 -- the operand of an object renaming declaration since these are
6934 -- contexts where we do not want the value anyway.
6936 elsif (Nkind
(Par
) = N_Attribute_Reference
6937 and then Prefix
(Par
) = N
)
6938 or else Is_Renamed_Object
(N
)
6942 -- Don't do this optimization if we are within the code for a
6943 -- discriminant check, since the whole point of such a check may
6944 -- be to verify the condition on which the code below depends!
6946 elsif Is_In_Discriminant_Check
(N
) then
6949 -- Green light to see if we can do the optimization. There is
6950 -- still one condition that inhibits the optimization below but
6951 -- now is the time to check the particular discriminant.
6954 -- Loop through discriminants to find the matching discriminant
6955 -- constraint to see if we can copy it.
6957 Disc
:= First_Discriminant
(Ptyp
);
6958 Dcon
:= First_Elmt
(Discriminant_Constraint
(Ptyp
));
6959 Discr_Loop
: while Present
(Dcon
) loop
6961 -- Check if this is the matching discriminant
6963 if Disc
= Entity
(Selector_Name
(N
)) then
6965 -- Here we have the matching discriminant. Check for
6966 -- the case of a discriminant of a component that is
6967 -- constrained by an outer discriminant, which cannot
6968 -- be optimized away.
6971 Denotes_Discriminant
6972 (Node
(Dcon
), Check_Concurrent
=> True)
6976 -- In the context of a case statement, the expression may
6977 -- have the base type of the discriminant, and we need to
6978 -- preserve the constraint to avoid spurious errors on
6981 elsif Nkind
(Parent
(N
)) = N_Case_Statement
6982 and then Etype
(Node
(Dcon
)) /= Etype
(Disc
)
6985 Make_Qualified_Expression
(Loc
,
6987 New_Occurrence_Of
(Etype
(Disc
), Loc
),
6989 New_Copy_Tree
(Node
(Dcon
))));
6990 Analyze_And_Resolve
(N
, Etype
(Disc
));
6992 -- In case that comes out as a static expression,
6993 -- reset it (a selected component is never static).
6995 Set_Is_Static_Expression
(N
, False);
6998 -- Otherwise we can just copy the constraint, but the
6999 -- result is certainly not static! In some cases the
7000 -- discriminant constraint has been analyzed in the
7001 -- context of the original subtype indication, but for
7002 -- itypes the constraint might not have been analyzed
7003 -- yet, and this must be done now.
7006 Rewrite
(N
, New_Copy_Tree
(Node
(Dcon
)));
7007 Analyze_And_Resolve
(N
);
7008 Set_Is_Static_Expression
(N
, False);
7014 Next_Discriminant
(Disc
);
7015 end loop Discr_Loop
;
7017 -- Note: the above loop should always find a matching
7018 -- discriminant, but if it does not, we just missed an
7019 -- optimization due to some glitch (perhaps a previous error),
7025 -- The only remaining processing is in the case of a discriminant of
7026 -- a concurrent object, where we rewrite the prefix to denote the
7027 -- corresponding record type. If the type is derived and has renamed
7028 -- discriminants, use corresponding discriminant, which is the one
7029 -- that appears in the corresponding record.
7031 if not Is_Concurrent_Type
(Ptyp
) then
7035 Disc
:= Entity
(Selector_Name
(N
));
7037 if Is_Derived_Type
(Ptyp
)
7038 and then Present
(Corresponding_Discriminant
(Disc
))
7040 Disc
:= Corresponding_Discriminant
(Disc
);
7044 Make_Selected_Component
(Loc
,
7046 Unchecked_Convert_To
(Corresponding_Record_Type
(Ptyp
),
7048 Selector_Name
=> Make_Identifier
(Loc
, Chars
(Disc
)));
7053 end Expand_N_Selected_Component
;
7055 --------------------
7056 -- Expand_N_Slice --
7057 --------------------
7059 procedure Expand_N_Slice
(N
: Node_Id
) is
7060 Loc
: constant Source_Ptr
:= Sloc
(N
);
7061 Typ
: constant Entity_Id
:= Etype
(N
);
7062 Pfx
: constant Node_Id
:= Prefix
(N
);
7063 Ptp
: Entity_Id
:= Etype
(Pfx
);
7065 function Is_Procedure_Actual
(N
: Node_Id
) return Boolean;
7066 -- Check whether the argument is an actual for a procedure call, in
7067 -- which case the expansion of a bit-packed slice is deferred until the
7068 -- call itself is expanded. The reason this is required is that we might
7069 -- have an IN OUT or OUT parameter, and the copy out is essential, and
7070 -- that copy out would be missed if we created a temporary here in
7071 -- Expand_N_Slice. Note that we don't bother to test specifically for an
7072 -- IN OUT or OUT mode parameter, since it is a bit tricky to do, and it
7073 -- is harmless to defer expansion in the IN case, since the call
7074 -- processing will still generate the appropriate copy in operation,
7075 -- which will take care of the slice.
7077 procedure Make_Temporary
;
7078 -- Create a named variable for the value of the slice, in cases where
7079 -- the back-end cannot handle it properly, e.g. when packed types or
7080 -- unaligned slices are involved.
7082 -------------------------
7083 -- Is_Procedure_Actual --
7084 -------------------------
7086 function Is_Procedure_Actual
(N
: Node_Id
) return Boolean is
7087 Par
: Node_Id
:= Parent
(N
);
7091 -- If our parent is a procedure call we can return
7093 if Nkind
(Par
) = N_Procedure_Call_Statement
then
7096 -- If our parent is a type conversion, keep climbing the tree,
7097 -- since a type conversion can be a procedure actual. Also keep
7098 -- climbing if parameter association or a qualified expression,
7099 -- since these are additional cases that do can appear on
7100 -- procedure actuals.
7102 elsif Nkind_In
(Par
, N_Type_Conversion
,
7103 N_Parameter_Association
,
7104 N_Qualified_Expression
)
7106 Par
:= Parent
(Par
);
7108 -- Any other case is not what we are looking for
7114 end Is_Procedure_Actual
;
7116 --------------------
7117 -- Make_Temporary --
7118 --------------------
7120 procedure Make_Temporary
is
7122 Ent
: constant Entity_Id
:=
7123 Make_Defining_Identifier
(Loc
, New_Internal_Name
('T'));
7126 Make_Object_Declaration
(Loc
,
7127 Defining_Identifier
=> Ent
,
7128 Object_Definition
=> New_Occurrence_Of
(Typ
, Loc
));
7130 Set_No_Initialization
(Decl
);
7132 Insert_Actions
(N
, New_List
(
7134 Make_Assignment_Statement
(Loc
,
7135 Name
=> New_Occurrence_Of
(Ent
, Loc
),
7136 Expression
=> Relocate_Node
(N
))));
7138 Rewrite
(N
, New_Occurrence_Of
(Ent
, Loc
));
7139 Analyze_And_Resolve
(N
, Typ
);
7142 -- Start of processing for Expand_N_Slice
7145 -- Special handling for access types
7147 if Is_Access_Type
(Ptp
) then
7149 Ptp
:= Designated_Type
(Ptp
);
7152 Make_Explicit_Dereference
(Sloc
(N
),
7153 Prefix
=> Relocate_Node
(Pfx
)));
7155 Analyze_And_Resolve
(Pfx
, Ptp
);
7158 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
7159 -- function, then additional actuals must be passed.
7161 if Ada_Version
>= Ada_05
7162 and then Is_Build_In_Place_Function_Call
(Pfx
)
7164 Make_Build_In_Place_Call_In_Anonymous_Context
(Pfx
);
7167 -- Range checks are potentially also needed for cases involving a slice
7168 -- indexed by a subtype indication, but Do_Range_Check can currently
7169 -- only be set for expressions ???
7171 if not Index_Checks_Suppressed
(Ptp
)
7172 and then (not Is_Entity_Name
(Pfx
)
7173 or else not Index_Checks_Suppressed
(Entity
(Pfx
)))
7174 and then Nkind
(Discrete_Range
(N
)) /= N_Subtype_Indication
7176 -- Do not enable range check to nodes associated with the frontend
7177 -- expansion of the dispatch table. We first check if Ada.Tags is
7178 -- already loaded to avoid the addition of an undesired dependence
7179 -- on such run-time unit.
7184 (RTU_Loaded
(Ada_Tags
)
7185 and then Nkind
(Prefix
(N
)) = N_Selected_Component
7186 and then Present
(Entity
(Selector_Name
(Prefix
(N
))))
7187 and then Entity
(Selector_Name
(Prefix
(N
))) =
7188 RTE_Record_Component
(RE_Prims_Ptr
)))
7190 Enable_Range_Check
(Discrete_Range
(N
));
7193 -- The remaining case to be handled is packed slices. We can leave
7194 -- packed slices as they are in the following situations:
7196 -- 1. Right or left side of an assignment (we can handle this
7197 -- situation correctly in the assignment statement expansion).
7199 -- 2. Prefix of indexed component (the slide is optimized away in this
7200 -- case, see the start of Expand_N_Slice.)
7202 -- 3. Object renaming declaration, since we want the name of the
7203 -- slice, not the value.
7205 -- 4. Argument to procedure call, since copy-in/copy-out handling may
7206 -- be required, and this is handled in the expansion of call
7209 -- 5. Prefix of an address attribute (this is an error which is caught
7210 -- elsewhere, and the expansion would interfere with generating the
7213 if not Is_Packed
(Typ
) then
7215 -- Apply transformation for actuals of a function call, where
7216 -- Expand_Actuals is not used.
7218 if Nkind
(Parent
(N
)) = N_Function_Call
7219 and then Is_Possibly_Unaligned_Slice
(N
)
7224 elsif Nkind
(Parent
(N
)) = N_Assignment_Statement
7225 or else (Nkind
(Parent
(Parent
(N
))) = N_Assignment_Statement
7226 and then Parent
(N
) = Name
(Parent
(Parent
(N
))))
7230 elsif Nkind
(Parent
(N
)) = N_Indexed_Component
7231 or else Is_Renamed_Object
(N
)
7232 or else Is_Procedure_Actual
(N
)
7236 elsif Nkind
(Parent
(N
)) = N_Attribute_Reference
7237 and then Attribute_Name
(Parent
(N
)) = Name_Address
7246 ------------------------------
7247 -- Expand_N_Type_Conversion --
7248 ------------------------------
7250 procedure Expand_N_Type_Conversion
(N
: Node_Id
) is
7251 Loc
: constant Source_Ptr
:= Sloc
(N
);
7252 Operand
: constant Node_Id
:= Expression
(N
);
7253 Target_Type
: constant Entity_Id
:= Etype
(N
);
7254 Operand_Type
: Entity_Id
:= Etype
(Operand
);
7256 procedure Handle_Changed_Representation
;
7257 -- This is called in the case of record and array type conversions to
7258 -- see if there is a change of representation to be handled. Change of
7259 -- representation is actually handled at the assignment statement level,
7260 -- and what this procedure does is rewrite node N conversion as an
7261 -- assignment to temporary. If there is no change of representation,
7262 -- then the conversion node is unchanged.
7264 procedure Real_Range_Check
;
7265 -- Handles generation of range check for real target value
7267 -----------------------------------
7268 -- Handle_Changed_Representation --
7269 -----------------------------------
7271 procedure Handle_Changed_Representation
is
7280 -- Nothing else to do if no change of representation
7282 if Same_Representation
(Operand_Type
, Target_Type
) then
7285 -- The real change of representation work is done by the assignment
7286 -- statement processing. So if this type conversion is appearing as
7287 -- the expression of an assignment statement, nothing needs to be
7288 -- done to the conversion.
7290 elsif Nkind
(Parent
(N
)) = N_Assignment_Statement
then
7293 -- Otherwise we need to generate a temporary variable, and do the
7294 -- change of representation assignment into that temporary variable.
7295 -- The conversion is then replaced by a reference to this variable.
7300 -- If type is unconstrained we have to add a constraint, copied
7301 -- from the actual value of the left hand side.
7303 if not Is_Constrained
(Target_Type
) then
7304 if Has_Discriminants
(Operand_Type
) then
7305 Disc
:= First_Discriminant
(Operand_Type
);
7307 if Disc
/= First_Stored_Discriminant
(Operand_Type
) then
7308 Disc
:= First_Stored_Discriminant
(Operand_Type
);
7312 while Present
(Disc
) loop
7314 Make_Selected_Component
(Loc
,
7315 Prefix
=> Duplicate_Subexpr_Move_Checks
(Operand
),
7317 Make_Identifier
(Loc
, Chars
(Disc
))));
7318 Next_Discriminant
(Disc
);
7321 elsif Is_Array_Type
(Operand_Type
) then
7322 N_Ix
:= First_Index
(Target_Type
);
7325 for J
in 1 .. Number_Dimensions
(Operand_Type
) loop
7327 -- We convert the bounds explicitly. We use an unchecked
7328 -- conversion because bounds checks are done elsewhere.
7333 Unchecked_Convert_To
(Etype
(N_Ix
),
7334 Make_Attribute_Reference
(Loc
,
7336 Duplicate_Subexpr_No_Checks
7337 (Operand
, Name_Req
=> True),
7338 Attribute_Name
=> Name_First
,
7339 Expressions
=> New_List
(
7340 Make_Integer_Literal
(Loc
, J
)))),
7343 Unchecked_Convert_To
(Etype
(N_Ix
),
7344 Make_Attribute_Reference
(Loc
,
7346 Duplicate_Subexpr_No_Checks
7347 (Operand
, Name_Req
=> True),
7348 Attribute_Name
=> Name_Last
,
7349 Expressions
=> New_List
(
7350 Make_Integer_Literal
(Loc
, J
))))));
7357 Odef
:= New_Occurrence_Of
(Target_Type
, Loc
);
7359 if Present
(Cons
) then
7361 Make_Subtype_Indication
(Loc
,
7362 Subtype_Mark
=> Odef
,
7364 Make_Index_Or_Discriminant_Constraint
(Loc
,
7365 Constraints
=> Cons
));
7368 Temp
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('C'));
7370 Make_Object_Declaration
(Loc
,
7371 Defining_Identifier
=> Temp
,
7372 Object_Definition
=> Odef
);
7374 Set_No_Initialization
(Decl
, True);
7376 -- Insert required actions. It is essential to suppress checks
7377 -- since we have suppressed default initialization, which means
7378 -- that the variable we create may have no discriminants.
7383 Make_Assignment_Statement
(Loc
,
7384 Name
=> New_Occurrence_Of
(Temp
, Loc
),
7385 Expression
=> Relocate_Node
(N
))),
7386 Suppress
=> All_Checks
);
7388 Rewrite
(N
, New_Occurrence_Of
(Temp
, Loc
));
7391 end Handle_Changed_Representation
;
7393 ----------------------
7394 -- Real_Range_Check --
7395 ----------------------
7397 -- Case of conversions to floating-point or fixed-point. If range checks
7398 -- are enabled and the target type has a range constraint, we convert:
7404 -- Tnn : typ'Base := typ'Base (x);
7405 -- [constraint_error when Tnn < typ'First or else Tnn > typ'Last]
7408 -- This is necessary when there is a conversion of integer to float or
7409 -- to fixed-point to ensure that the correct checks are made. It is not
7410 -- necessary for float to float where it is enough to simply set the
7411 -- Do_Range_Check flag.
7413 procedure Real_Range_Check
is
7414 Btyp
: constant Entity_Id
:= Base_Type
(Target_Type
);
7415 Lo
: constant Node_Id
:= Type_Low_Bound
(Target_Type
);
7416 Hi
: constant Node_Id
:= Type_High_Bound
(Target_Type
);
7417 Xtyp
: constant Entity_Id
:= Etype
(Operand
);
7422 -- Nothing to do if conversion was rewritten
7424 if Nkind
(N
) /= N_Type_Conversion
then
7428 -- Nothing to do if range checks suppressed, or target has the same
7429 -- range as the base type (or is the base type).
7431 if Range_Checks_Suppressed
(Target_Type
)
7432 or else (Lo
= Type_Low_Bound
(Btyp
)
7434 Hi
= Type_High_Bound
(Btyp
))
7439 -- Nothing to do if expression is an entity on which checks have been
7442 if Is_Entity_Name
(Operand
)
7443 and then Range_Checks_Suppressed
(Entity
(Operand
))
7448 -- Nothing to do if bounds are all static and we can tell that the
7449 -- expression is within the bounds of the target. Note that if the
7450 -- operand is of an unconstrained floating-point type, then we do
7451 -- not trust it to be in range (might be infinite)
7454 S_Lo
: constant Node_Id
:= Type_Low_Bound
(Xtyp
);
7455 S_Hi
: constant Node_Id
:= Type_High_Bound
(Xtyp
);
7458 if (not Is_Floating_Point_Type
(Xtyp
)
7459 or else Is_Constrained
(Xtyp
))
7460 and then Compile_Time_Known_Value
(S_Lo
)
7461 and then Compile_Time_Known_Value
(S_Hi
)
7462 and then Compile_Time_Known_Value
(Hi
)
7463 and then Compile_Time_Known_Value
(Lo
)
7466 D_Lov
: constant Ureal
:= Expr_Value_R
(Lo
);
7467 D_Hiv
: constant Ureal
:= Expr_Value_R
(Hi
);
7472 if Is_Real_Type
(Xtyp
) then
7473 S_Lov
:= Expr_Value_R
(S_Lo
);
7474 S_Hiv
:= Expr_Value_R
(S_Hi
);
7476 S_Lov
:= UR_From_Uint
(Expr_Value
(S_Lo
));
7477 S_Hiv
:= UR_From_Uint
(Expr_Value
(S_Hi
));
7481 and then S_Lov
>= D_Lov
7482 and then S_Hiv
<= D_Hiv
7484 Set_Do_Range_Check
(Operand
, False);
7491 -- For float to float conversions, we are done
7493 if Is_Floating_Point_Type
(Xtyp
)
7495 Is_Floating_Point_Type
(Btyp
)
7500 -- Otherwise rewrite the conversion as described above
7502 Conv
:= Relocate_Node
(N
);
7504 (Subtype_Mark
(Conv
), New_Occurrence_Of
(Btyp
, Loc
));
7505 Set_Etype
(Conv
, Btyp
);
7507 -- Enable overflow except for case of integer to float conversions,
7508 -- where it is never required, since we can never have overflow in
7511 if not Is_Integer_Type
(Etype
(Operand
)) then
7512 Enable_Overflow_Check
(Conv
);
7516 Make_Defining_Identifier
(Loc
,
7517 Chars
=> New_Internal_Name
('T'));
7519 Insert_Actions
(N
, New_List
(
7520 Make_Object_Declaration
(Loc
,
7521 Defining_Identifier
=> Tnn
,
7522 Object_Definition
=> New_Occurrence_Of
(Btyp
, Loc
),
7523 Expression
=> Conv
),
7525 Make_Raise_Constraint_Error
(Loc
,
7530 Left_Opnd
=> New_Occurrence_Of
(Tnn
, Loc
),
7532 Make_Attribute_Reference
(Loc
,
7533 Attribute_Name
=> Name_First
,
7535 New_Occurrence_Of
(Target_Type
, Loc
))),
7539 Left_Opnd
=> New_Occurrence_Of
(Tnn
, Loc
),
7541 Make_Attribute_Reference
(Loc
,
7542 Attribute_Name
=> Name_Last
,
7544 New_Occurrence_Of
(Target_Type
, Loc
)))),
7545 Reason
=> CE_Range_Check_Failed
)));
7547 Rewrite
(N
, New_Occurrence_Of
(Tnn
, Loc
));
7548 Analyze_And_Resolve
(N
, Btyp
);
7549 end Real_Range_Check
;
7551 -- Start of processing for Expand_N_Type_Conversion
7554 -- Nothing at all to do if conversion is to the identical type so remove
7555 -- the conversion completely, it is useless.
7557 if Operand_Type
= Target_Type
then
7558 Rewrite
(N
, Relocate_Node
(Operand
));
7562 -- Nothing to do if this is the second argument of read. This is a
7563 -- "backwards" conversion that will be handled by the specialized code
7564 -- in attribute processing.
7566 if Nkind
(Parent
(N
)) = N_Attribute_Reference
7567 and then Attribute_Name
(Parent
(N
)) = Name_Read
7568 and then Next
(First
(Expressions
(Parent
(N
)))) = N
7573 -- Here if we may need to expand conversion
7575 -- Do validity check if validity checking operands
7577 if Validity_Checks_On
7578 and then Validity_Check_Operands
7580 Ensure_Valid
(Operand
);
7583 -- Special case of converting from non-standard boolean type
7585 if Is_Boolean_Type
(Operand_Type
)
7586 and then (Nonzero_Is_True
(Operand_Type
))
7588 Adjust_Condition
(Operand
);
7589 Set_Etype
(Operand
, Standard_Boolean
);
7590 Operand_Type
:= Standard_Boolean
;
7593 -- Case of converting to an access type
7595 if Is_Access_Type
(Target_Type
) then
7597 -- Apply an accessibility check when the conversion operand is an
7598 -- access parameter (or a renaming thereof), unless conversion was
7599 -- expanded from an Unchecked_ or Unrestricted_Access attribute.
7600 -- Note that other checks may still need to be applied below (such
7601 -- as tagged type checks).
7603 if Is_Entity_Name
(Operand
)
7605 (Is_Formal
(Entity
(Operand
))
7607 (Present
(Renamed_Object
(Entity
(Operand
)))
7608 and then Is_Entity_Name
(Renamed_Object
(Entity
(Operand
)))
7610 (Entity
(Renamed_Object
(Entity
(Operand
))))))
7611 and then Ekind
(Etype
(Operand
)) = E_Anonymous_Access_Type
7612 and then (Nkind
(Original_Node
(N
)) /= N_Attribute_Reference
7613 or else Attribute_Name
(Original_Node
(N
)) = Name_Access
)
7615 Apply_Accessibility_Check
7616 (Operand
, Target_Type
, Insert_Node
=> Operand
);
7618 -- If the level of the operand type is statically deeper than the
7619 -- level of the target type, then force Program_Error. Note that this
7620 -- can only occur for cases where the attribute is within the body of
7621 -- an instantiation (otherwise the conversion will already have been
7622 -- rejected as illegal). Note: warnings are issued by the analyzer
7623 -- for the instance cases.
7625 elsif In_Instance_Body
7626 and then Type_Access_Level
(Operand_Type
) >
7627 Type_Access_Level
(Target_Type
)
7630 Make_Raise_Program_Error
(Sloc
(N
),
7631 Reason
=> PE_Accessibility_Check_Failed
));
7632 Set_Etype
(N
, Target_Type
);
7634 -- When the operand is a selected access discriminant the check needs
7635 -- to be made against the level of the object denoted by the prefix
7636 -- of the selected name. Force Program_Error for this case as well
7637 -- (this accessibility violation can only happen if within the body
7638 -- of an instantiation).
7640 elsif In_Instance_Body
7641 and then Ekind
(Operand_Type
) = E_Anonymous_Access_Type
7642 and then Nkind
(Operand
) = N_Selected_Component
7643 and then Object_Access_Level
(Operand
) >
7644 Type_Access_Level
(Target_Type
)
7647 Make_Raise_Program_Error
(Sloc
(N
),
7648 Reason
=> PE_Accessibility_Check_Failed
));
7649 Set_Etype
(N
, Target_Type
);
7653 -- Case of conversions of tagged types and access to tagged types
7655 -- When needed, that is to say when the expression is class-wide, Add
7656 -- runtime a tag check for (strict) downward conversion by using the
7657 -- membership test, generating:
7659 -- [constraint_error when Operand not in Target_Type'Class]
7661 -- or in the access type case
7663 -- [constraint_error
7664 -- when Operand /= null
7665 -- and then Operand.all not in
7666 -- Designated_Type (Target_Type)'Class]
7668 if (Is_Access_Type
(Target_Type
)
7669 and then Is_Tagged_Type
(Designated_Type
(Target_Type
)))
7670 or else Is_Tagged_Type
(Target_Type
)
7672 -- Do not do any expansion in the access type case if the parent is a
7673 -- renaming, since this is an error situation which will be caught by
7674 -- Sem_Ch8, and the expansion can interfere with this error check.
7676 if Is_Access_Type
(Target_Type
)
7677 and then Is_Renamed_Object
(N
)
7682 -- Otherwise, proceed with processing tagged conversion
7685 Actual_Op_Typ
: Entity_Id
;
7686 Actual_Targ_Typ
: Entity_Id
;
7687 Make_Conversion
: Boolean := False;
7688 Root_Op_Typ
: Entity_Id
;
7690 procedure Make_Tag_Check
(Targ_Typ
: Entity_Id
);
7691 -- Create a membership check to test whether Operand is a member
7692 -- of Targ_Typ. If the original Target_Type is an access, include
7693 -- a test for null value. The check is inserted at N.
7695 --------------------
7696 -- Make_Tag_Check --
7697 --------------------
7699 procedure Make_Tag_Check
(Targ_Typ
: Entity_Id
) is
7704 -- [Constraint_Error
7705 -- when Operand /= null
7706 -- and then Operand.all not in Targ_Typ]
7708 if Is_Access_Type
(Target_Type
) then
7713 Left_Opnd
=> Duplicate_Subexpr_No_Checks
(Operand
),
7714 Right_Opnd
=> Make_Null
(Loc
)),
7719 Make_Explicit_Dereference
(Loc
,
7720 Prefix
=> Duplicate_Subexpr_No_Checks
(Operand
)),
7721 Right_Opnd
=> New_Reference_To
(Targ_Typ
, Loc
)));
7724 -- [Constraint_Error when Operand not in Targ_Typ]
7729 Left_Opnd
=> Duplicate_Subexpr_No_Checks
(Operand
),
7730 Right_Opnd
=> New_Reference_To
(Targ_Typ
, Loc
));
7734 Make_Raise_Constraint_Error
(Loc
,
7736 Reason
=> CE_Tag_Check_Failed
));
7739 -- Start of processing
7742 if Is_Access_Type
(Target_Type
) then
7743 Actual_Op_Typ
:= Designated_Type
(Operand_Type
);
7744 Actual_Targ_Typ
:= Designated_Type
(Target_Type
);
7747 Actual_Op_Typ
:= Operand_Type
;
7748 Actual_Targ_Typ
:= Target_Type
;
7751 Root_Op_Typ
:= Root_Type
(Actual_Op_Typ
);
7753 -- Ada 2005 (AI-251): Handle interface type conversion
7755 if Is_Interface
(Actual_Op_Typ
) then
7756 Expand_Interface_Conversion
(N
, Is_Static
=> False);
7760 if not Tag_Checks_Suppressed
(Actual_Targ_Typ
) then
7762 -- Create a runtime tag check for a downward class-wide type
7765 if Is_Class_Wide_Type
(Actual_Op_Typ
)
7766 and then Root_Op_Typ
/= Actual_Targ_Typ
7767 and then Is_Ancestor
(Root_Op_Typ
, Actual_Targ_Typ
)
7769 Make_Tag_Check
(Class_Wide_Type
(Actual_Targ_Typ
));
7770 Make_Conversion
:= True;
7773 -- AI05-0073: If the result subtype of the function is defined
7774 -- by an access_definition designating a specific tagged type
7775 -- T, a check is made that the result value is null or the tag
7776 -- of the object designated by the result value identifies T.
7777 -- Constraint_Error is raised if this check fails.
7779 if Nkind
(Parent
(N
)) = Sinfo
.N_Return_Statement
then
7782 Func_Typ
: Entity_Id
;
7785 -- Climb scope stack looking for the enclosing function
7787 Func
:= Current_Scope
;
7788 while Present
(Func
)
7789 and then Ekind
(Func
) /= E_Function
7791 Func
:= Scope
(Func
);
7794 -- The function's return subtype must be defined using
7795 -- an access definition.
7797 if Nkind
(Result_Definition
(Parent
(Func
))) =
7800 Func_Typ
:= Directly_Designated_Type
(Etype
(Func
));
7802 -- The return subtype denotes a specific tagged type,
7803 -- in other words, a non class-wide type.
7805 if Is_Tagged_Type
(Func_Typ
)
7806 and then not Is_Class_Wide_Type
(Func_Typ
)
7808 Make_Tag_Check
(Actual_Targ_Typ
);
7809 Make_Conversion
:= True;
7815 -- We have generated a tag check for either a class-wide type
7816 -- conversion or for AI05-0073.
7818 if Make_Conversion
then
7823 Make_Unchecked_Type_Conversion
(Loc
,
7824 Subtype_Mark
=> New_Occurrence_Of
(Target_Type
, Loc
),
7825 Expression
=> Relocate_Node
(Expression
(N
)));
7827 Analyze_And_Resolve
(N
, Target_Type
);
7833 -- Case of other access type conversions
7835 elsif Is_Access_Type
(Target_Type
) then
7836 Apply_Constraint_Check
(Operand
, Target_Type
);
7838 -- Case of conversions from a fixed-point type
7840 -- These conversions require special expansion and processing, found in
7841 -- the Exp_Fixd package. We ignore cases where Conversion_OK is set,
7842 -- since from a semantic point of view, these are simple integer
7843 -- conversions, which do not need further processing.
7845 elsif Is_Fixed_Point_Type
(Operand_Type
)
7846 and then not Conversion_OK
(N
)
7848 -- We should never see universal fixed at this case, since the
7849 -- expansion of the constituent divide or multiply should have
7850 -- eliminated the explicit mention of universal fixed.
7852 pragma Assert
(Operand_Type
/= Universal_Fixed
);
7854 -- Check for special case of the conversion to universal real that
7855 -- occurs as a result of the use of a round attribute. In this case,
7856 -- the real type for the conversion is taken from the target type of
7857 -- the Round attribute and the result must be marked as rounded.
7859 if Target_Type
= Universal_Real
7860 and then Nkind
(Parent
(N
)) = N_Attribute_Reference
7861 and then Attribute_Name
(Parent
(N
)) = Name_Round
7863 Set_Rounded_Result
(N
);
7864 Set_Etype
(N
, Etype
(Parent
(N
)));
7867 -- Otherwise do correct fixed-conversion, but skip these if the
7868 -- Conversion_OK flag is set, because from a semantic point of
7869 -- view these are simple integer conversions needing no further
7870 -- processing (the backend will simply treat them as integers)
7872 if not Conversion_OK
(N
) then
7873 if Is_Fixed_Point_Type
(Etype
(N
)) then
7874 Expand_Convert_Fixed_To_Fixed
(N
);
7877 elsif Is_Integer_Type
(Etype
(N
)) then
7878 Expand_Convert_Fixed_To_Integer
(N
);
7881 pragma Assert
(Is_Floating_Point_Type
(Etype
(N
)));
7882 Expand_Convert_Fixed_To_Float
(N
);
7887 -- Case of conversions to a fixed-point type
7889 -- These conversions require special expansion and processing, found in
7890 -- the Exp_Fixd package. Again, ignore cases where Conversion_OK is set,
7891 -- since from a semantic point of view, these are simple integer
7892 -- conversions, which do not need further processing.
7894 elsif Is_Fixed_Point_Type
(Target_Type
)
7895 and then not Conversion_OK
(N
)
7897 if Is_Integer_Type
(Operand_Type
) then
7898 Expand_Convert_Integer_To_Fixed
(N
);
7901 pragma Assert
(Is_Floating_Point_Type
(Operand_Type
));
7902 Expand_Convert_Float_To_Fixed
(N
);
7906 -- Case of float-to-integer conversions
7908 -- We also handle float-to-fixed conversions with Conversion_OK set
7909 -- since semantically the fixed-point target is treated as though it
7910 -- were an integer in such cases.
7912 elsif Is_Floating_Point_Type
(Operand_Type
)
7914 (Is_Integer_Type
(Target_Type
)
7916 (Is_Fixed_Point_Type
(Target_Type
) and then Conversion_OK
(N
)))
7918 -- One more check here, gcc is still not able to do conversions of
7919 -- this type with proper overflow checking, and so gigi is doing an
7920 -- approximation of what is required by doing floating-point compares
7921 -- with the end-point. But that can lose precision in some cases, and
7922 -- give a wrong result. Converting the operand to Universal_Real is
7923 -- helpful, but still does not catch all cases with 64-bit integers
7924 -- on targets with only 64-bit floats
7926 -- The above comment seems obsoleted by Apply_Float_Conversion_Check
7927 -- Can this code be removed ???
7929 if Do_Range_Check
(Operand
) then
7931 Make_Type_Conversion
(Loc
,
7933 New_Occurrence_Of
(Universal_Real
, Loc
),
7935 Relocate_Node
(Operand
)));
7937 Set_Etype
(Operand
, Universal_Real
);
7938 Enable_Range_Check
(Operand
);
7939 Set_Do_Range_Check
(Expression
(Operand
), False);
7942 -- Case of array conversions
7944 -- Expansion of array conversions, add required length/range checks but
7945 -- only do this if there is no change of representation. For handling of
7946 -- this case, see Handle_Changed_Representation.
7948 elsif Is_Array_Type
(Target_Type
) then
7950 if Is_Constrained
(Target_Type
) then
7951 Apply_Length_Check
(Operand
, Target_Type
);
7953 Apply_Range_Check
(Operand
, Target_Type
);
7956 Handle_Changed_Representation
;
7958 -- Case of conversions of discriminated types
7960 -- Add required discriminant checks if target is constrained. Again this
7961 -- change is skipped if we have a change of representation.
7963 elsif Has_Discriminants
(Target_Type
)
7964 and then Is_Constrained
(Target_Type
)
7966 Apply_Discriminant_Check
(Operand
, Target_Type
);
7967 Handle_Changed_Representation
;
7969 -- Case of all other record conversions. The only processing required
7970 -- is to check for a change of representation requiring the special
7971 -- assignment processing.
7973 elsif Is_Record_Type
(Target_Type
) then
7975 -- Ada 2005 (AI-216): Program_Error is raised when converting from
7976 -- a derived Unchecked_Union type to an unconstrained type that is
7977 -- not Unchecked_Union if the operand lacks inferable discriminants.
7979 if Is_Derived_Type
(Operand_Type
)
7980 and then Is_Unchecked_Union
(Base_Type
(Operand_Type
))
7981 and then not Is_Constrained
(Target_Type
)
7982 and then not Is_Unchecked_Union
(Base_Type
(Target_Type
))
7983 and then not Has_Inferable_Discriminants
(Operand
)
7985 -- To prevent Gigi from generating illegal code, we generate a
7986 -- Program_Error node, but we give it the target type of the
7990 PE
: constant Node_Id
:= Make_Raise_Program_Error
(Loc
,
7991 Reason
=> PE_Unchecked_Union_Restriction
);
7994 Set_Etype
(PE
, Target_Type
);
7999 Handle_Changed_Representation
;
8002 -- Case of conversions of enumeration types
8004 elsif Is_Enumeration_Type
(Target_Type
) then
8006 -- Special processing is required if there is a change of
8007 -- representation (from enumeration representation clauses)
8009 if not Same_Representation
(Target_Type
, Operand_Type
) then
8011 -- Convert: x(y) to x'val (ytyp'val (y))
8014 Make_Attribute_Reference
(Loc
,
8015 Prefix
=> New_Occurrence_Of
(Target_Type
, Loc
),
8016 Attribute_Name
=> Name_Val
,
8017 Expressions
=> New_List
(
8018 Make_Attribute_Reference
(Loc
,
8019 Prefix
=> New_Occurrence_Of
(Operand_Type
, Loc
),
8020 Attribute_Name
=> Name_Pos
,
8021 Expressions
=> New_List
(Operand
)))));
8023 Analyze_And_Resolve
(N
, Target_Type
);
8026 -- Case of conversions to floating-point
8028 elsif Is_Floating_Point_Type
(Target_Type
) then
8032 -- At this stage, either the conversion node has been transformed into
8033 -- some other equivalent expression, or left as a conversion that can
8034 -- be handled by Gigi. The conversions that Gigi can handle are the
8037 -- Conversions with no change of representation or type
8039 -- Numeric conversions involving integer, floating- and fixed-point
8040 -- values. Fixed-point values are allowed only if Conversion_OK is
8041 -- set, i.e. if the fixed-point values are to be treated as integers.
8043 -- No other conversions should be passed to Gigi
8045 -- Check: are these rules stated in sinfo??? if so, why restate here???
8047 -- The only remaining step is to generate a range check if we still have
8048 -- a type conversion at this stage and Do_Range_Check is set. For now we
8049 -- do this only for conversions of discrete types.
8051 if Nkind
(N
) = N_Type_Conversion
8052 and then Is_Discrete_Type
(Etype
(N
))
8055 Expr
: constant Node_Id
:= Expression
(N
);
8060 if Do_Range_Check
(Expr
)
8061 and then Is_Discrete_Type
(Etype
(Expr
))
8063 Set_Do_Range_Check
(Expr
, False);
8065 -- Before we do a range check, we have to deal with treating a
8066 -- fixed-point operand as an integer. The way we do this is
8067 -- simply to do an unchecked conversion to an appropriate
8068 -- integer type large enough to hold the result.
8070 -- This code is not active yet, because we are only dealing
8071 -- with discrete types so far ???
8073 if Nkind
(Expr
) in N_Has_Treat_Fixed_As_Integer
8074 and then Treat_Fixed_As_Integer
(Expr
)
8076 Ftyp
:= Base_Type
(Etype
(Expr
));
8078 if Esize
(Ftyp
) >= Esize
(Standard_Integer
) then
8079 Ityp
:= Standard_Long_Long_Integer
;
8081 Ityp
:= Standard_Integer
;
8084 Rewrite
(Expr
, Unchecked_Convert_To
(Ityp
, Expr
));
8087 -- Reset overflow flag, since the range check will include
8088 -- dealing with possible overflow, and generate the check If
8089 -- Address is either a source type or target type, suppress
8090 -- range check to avoid typing anomalies when it is a visible
8093 Set_Do_Overflow_Check
(N
, False);
8094 if not Is_Descendent_Of_Address
(Etype
(Expr
))
8095 and then not Is_Descendent_Of_Address
(Target_Type
)
8097 Generate_Range_Check
8098 (Expr
, Target_Type
, CE_Range_Check_Failed
);
8104 -- Final step, if the result is a type conversion involving Vax_Float
8105 -- types, then it is subject for further special processing.
8107 if Nkind
(N
) = N_Type_Conversion
8108 and then (Vax_Float
(Operand_Type
) or else Vax_Float
(Target_Type
))
8110 Expand_Vax_Conversion
(N
);
8113 end Expand_N_Type_Conversion
;
8115 -----------------------------------
8116 -- Expand_N_Unchecked_Expression --
8117 -----------------------------------
8119 -- Remove the unchecked expression node from the tree. It's job was simply
8120 -- to make sure that its constituent expression was handled with checks
8121 -- off, and now that that is done, we can remove it from the tree, and
8122 -- indeed must, since gigi does not expect to see these nodes.
8124 procedure Expand_N_Unchecked_Expression
(N
: Node_Id
) is
8125 Exp
: constant Node_Id
:= Expression
(N
);
8128 Set_Assignment_OK
(Exp
, Assignment_OK
(N
) or Assignment_OK
(Exp
));
8130 end Expand_N_Unchecked_Expression
;
8132 ----------------------------------------
8133 -- Expand_N_Unchecked_Type_Conversion --
8134 ----------------------------------------
8136 -- If this cannot be handled by Gigi and we haven't already made a
8137 -- temporary for it, do it now.
8139 procedure Expand_N_Unchecked_Type_Conversion
(N
: Node_Id
) is
8140 Target_Type
: constant Entity_Id
:= Etype
(N
);
8141 Operand
: constant Node_Id
:= Expression
(N
);
8142 Operand_Type
: constant Entity_Id
:= Etype
(Operand
);
8145 -- If we have a conversion of a compile time known value to a target
8146 -- type and the value is in range of the target type, then we can simply
8147 -- replace the construct by an integer literal of the correct type. We
8148 -- only apply this to integer types being converted. Possibly it may
8149 -- apply in other cases, but it is too much trouble to worry about.
8151 -- Note that we do not do this transformation if the Kill_Range_Check
8152 -- flag is set, since then the value may be outside the expected range.
8153 -- This happens in the Normalize_Scalars case.
8155 -- We also skip this if either the target or operand type is biased
8156 -- because in this case, the unchecked conversion is supposed to
8157 -- preserve the bit pattern, not the integer value.
8159 if Is_Integer_Type
(Target_Type
)
8160 and then not Has_Biased_Representation
(Target_Type
)
8161 and then Is_Integer_Type
(Operand_Type
)
8162 and then not Has_Biased_Representation
(Operand_Type
)
8163 and then Compile_Time_Known_Value
(Operand
)
8164 and then not Kill_Range_Check
(N
)
8167 Val
: constant Uint
:= Expr_Value
(Operand
);
8170 if Compile_Time_Known_Value
(Type_Low_Bound
(Target_Type
))
8172 Compile_Time_Known_Value
(Type_High_Bound
(Target_Type
))
8174 Val
>= Expr_Value
(Type_Low_Bound
(Target_Type
))
8176 Val
<= Expr_Value
(Type_High_Bound
(Target_Type
))
8178 Rewrite
(N
, Make_Integer_Literal
(Sloc
(N
), Val
));
8180 -- If Address is the target type, just set the type to avoid a
8181 -- spurious type error on the literal when Address is a visible
8184 if Is_Descendent_Of_Address
(Target_Type
) then
8185 Set_Etype
(N
, Target_Type
);
8187 Analyze_And_Resolve
(N
, Target_Type
);
8195 -- Nothing to do if conversion is safe
8197 if Safe_Unchecked_Type_Conversion
(N
) then
8201 -- Otherwise force evaluation unless Assignment_OK flag is set (this
8202 -- flag indicates ??? -- more comments needed here)
8204 if Assignment_OK
(N
) then
8207 Force_Evaluation
(N
);
8209 end Expand_N_Unchecked_Type_Conversion
;
8211 ----------------------------
8212 -- Expand_Record_Equality --
8213 ----------------------------
8215 -- For non-variant records, Equality is expanded when needed into:
8217 -- and then Lhs.Discr1 = Rhs.Discr1
8219 -- and then Lhs.Discrn = Rhs.Discrn
8220 -- and then Lhs.Cmp1 = Rhs.Cmp1
8222 -- and then Lhs.Cmpn = Rhs.Cmpn
8224 -- The expression is folded by the back-end for adjacent fields. This
8225 -- function is called for tagged record in only one occasion: for imple-
8226 -- menting predefined primitive equality (see Predefined_Primitives_Bodies)
8227 -- otherwise the primitive "=" is used directly.
8229 function Expand_Record_Equality
8234 Bodies
: List_Id
) return Node_Id
8236 Loc
: constant Source_Ptr
:= Sloc
(Nod
);
8241 First_Time
: Boolean := True;
8243 function Suitable_Element
(C
: Entity_Id
) return Entity_Id
;
8244 -- Return the first field to compare beginning with C, skipping the
8245 -- inherited components.
8247 ----------------------
8248 -- Suitable_Element --
8249 ----------------------
8251 function Suitable_Element
(C
: Entity_Id
) return Entity_Id
is
8256 elsif Ekind
(C
) /= E_Discriminant
8257 and then Ekind
(C
) /= E_Component
8259 return Suitable_Element
(Next_Entity
(C
));
8261 elsif Is_Tagged_Type
(Typ
)
8262 and then C
/= Original_Record_Component
(C
)
8264 return Suitable_Element
(Next_Entity
(C
));
8266 elsif Chars
(C
) = Name_uController
8267 or else Chars
(C
) = Name_uTag
8269 return Suitable_Element
(Next_Entity
(C
));
8271 elsif Is_Interface
(Etype
(C
)) then
8272 return Suitable_Element
(Next_Entity
(C
));
8277 end Suitable_Element
;
8279 -- Start of processing for Expand_Record_Equality
8282 -- Generates the following code: (assuming that Typ has one Discr and
8283 -- component C2 is also a record)
8286 -- and then Lhs.Discr1 = Rhs.Discr1
8287 -- and then Lhs.C1 = Rhs.C1
8288 -- and then Lhs.C2.C1=Rhs.C2.C1 and then ... Lhs.C2.Cn=Rhs.C2.Cn
8290 -- and then Lhs.Cmpn = Rhs.Cmpn
8292 Result
:= New_Reference_To
(Standard_True
, Loc
);
8293 C
:= Suitable_Element
(First_Entity
(Typ
));
8295 while Present
(C
) loop
8303 First_Time
:= False;
8307 New_Lhs
:= New_Copy_Tree
(Lhs
);
8308 New_Rhs
:= New_Copy_Tree
(Rhs
);
8312 Expand_Composite_Equality
(Nod
, Etype
(C
),
8314 Make_Selected_Component
(Loc
,
8316 Selector_Name
=> New_Reference_To
(C
, Loc
)),
8318 Make_Selected_Component
(Loc
,
8320 Selector_Name
=> New_Reference_To
(C
, Loc
)),
8323 -- If some (sub)component is an unchecked_union, the whole
8324 -- operation will raise program error.
8326 if Nkind
(Check
) = N_Raise_Program_Error
then
8328 Set_Etype
(Result
, Standard_Boolean
);
8333 Left_Opnd
=> Result
,
8334 Right_Opnd
=> Check
);
8338 C
:= Suitable_Element
(Next_Entity
(C
));
8342 end Expand_Record_Equality
;
8344 -------------------------------------
8345 -- Fixup_Universal_Fixed_Operation --
8346 -------------------------------------
8348 procedure Fixup_Universal_Fixed_Operation
(N
: Node_Id
) is
8349 Conv
: constant Node_Id
:= Parent
(N
);
8352 -- We must have a type conversion immediately above us
8354 pragma Assert
(Nkind
(Conv
) = N_Type_Conversion
);
8356 -- Normally the type conversion gives our target type. The exception
8357 -- occurs in the case of the Round attribute, where the conversion
8358 -- will be to universal real, and our real type comes from the Round
8359 -- attribute (as well as an indication that we must round the result)
8361 if Nkind
(Parent
(Conv
)) = N_Attribute_Reference
8362 and then Attribute_Name
(Parent
(Conv
)) = Name_Round
8364 Set_Etype
(N
, Etype
(Parent
(Conv
)));
8365 Set_Rounded_Result
(N
);
8367 -- Normal case where type comes from conversion above us
8370 Set_Etype
(N
, Etype
(Conv
));
8372 end Fixup_Universal_Fixed_Operation
;
8374 ------------------------------
8375 -- Get_Allocator_Final_List --
8376 ------------------------------
8378 function Get_Allocator_Final_List
8381 PtrT
: Entity_Id
) return Entity_Id
8383 Loc
: constant Source_Ptr
:= Sloc
(N
);
8385 Owner
: Entity_Id
:= PtrT
;
8386 -- The entity whose finalization list must be used to attach the
8387 -- allocated object.
8390 if Ekind
(PtrT
) = E_Anonymous_Access_Type
then
8392 -- If the context is an access parameter, we need to create a
8393 -- non-anonymous access type in order to have a usable final list,
8394 -- because there is otherwise no pool to which the allocated object
8395 -- can belong. We create both the type and the finalization chain
8396 -- here, because freezing an internal type does not create such a
8397 -- chain. The Final_Chain that is thus created is shared by the
8398 -- access parameter. The access type is tested against the result
8399 -- type of the function to exclude allocators whose type is an
8400 -- anonymous access result type. We freeze the type at once to
8401 -- ensure that it is properly decorated for the back-end, even
8402 -- if the context and current scope is a loop.
8404 if Nkind
(Associated_Node_For_Itype
(PtrT
))
8405 in N_Subprogram_Specification
8408 Etype
(Defining_Unit_Name
(Associated_Node_For_Itype
(PtrT
)))
8410 Owner
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('J'));
8412 Make_Full_Type_Declaration
(Loc
,
8413 Defining_Identifier
=> Owner
,
8415 Make_Access_To_Object_Definition
(Loc
,
8416 Subtype_Indication
=>
8417 New_Occurrence_Of
(T
, Loc
))));
8419 Freeze_Before
(N
, Owner
);
8420 Build_Final_List
(N
, Owner
);
8421 Set_Associated_Final_Chain
(PtrT
, Associated_Final_Chain
(Owner
));
8423 -- Ada 2005 (AI-318-02): If the context is a return object
8424 -- declaration, then the anonymous return subtype is defined to have
8425 -- the same accessibility level as that of the function's result
8426 -- subtype, which means that we want the scope where the function is
8429 elsif Nkind
(Associated_Node_For_Itype
(PtrT
)) = N_Object_Declaration
8430 and then Ekind
(Scope
(PtrT
)) = E_Return_Statement
8432 Owner
:= Scope
(Return_Applies_To
(Scope
(PtrT
)));
8434 -- Case of an access discriminant, or (Ada 2005), of an anonymous
8435 -- access component or anonymous access function result: find the
8436 -- final list associated with the scope of the type. (In the
8437 -- anonymous access component kind, a list controller will have
8438 -- been allocated when freezing the record type, and PtrT has an
8439 -- Associated_Final_Chain attribute designating it.)
8441 elsif No
(Associated_Final_Chain
(PtrT
)) then
8442 Owner
:= Scope
(PtrT
);
8446 return Find_Final_List
(Owner
);
8447 end Get_Allocator_Final_List
;
8449 ---------------------------------
8450 -- Has_Inferable_Discriminants --
8451 ---------------------------------
8453 function Has_Inferable_Discriminants
(N
: Node_Id
) return Boolean is
8455 function Prefix_Is_Formal_Parameter
(N
: Node_Id
) return Boolean;
8456 -- Determines whether the left-most prefix of a selected component is a
8457 -- formal parameter in a subprogram. Assumes N is a selected component.
8459 --------------------------------
8460 -- Prefix_Is_Formal_Parameter --
8461 --------------------------------
8463 function Prefix_Is_Formal_Parameter
(N
: Node_Id
) return Boolean is
8464 Sel_Comp
: Node_Id
:= N
;
8467 -- Move to the left-most prefix by climbing up the tree
8469 while Present
(Parent
(Sel_Comp
))
8470 and then Nkind
(Parent
(Sel_Comp
)) = N_Selected_Component
8472 Sel_Comp
:= Parent
(Sel_Comp
);
8475 return Ekind
(Entity
(Prefix
(Sel_Comp
))) in Formal_Kind
;
8476 end Prefix_Is_Formal_Parameter
;
8478 -- Start of processing for Has_Inferable_Discriminants
8481 -- For identifiers and indexed components, it is sufficient to have a
8482 -- constrained Unchecked_Union nominal subtype.
8484 if Nkind_In
(N
, N_Identifier
, N_Indexed_Component
) then
8485 return Is_Unchecked_Union
(Base_Type
(Etype
(N
)))
8487 Is_Constrained
(Etype
(N
));
8489 -- For selected components, the subtype of the selector must be a
8490 -- constrained Unchecked_Union. If the component is subject to a
8491 -- per-object constraint, then the enclosing object must have inferable
8494 elsif Nkind
(N
) = N_Selected_Component
then
8495 if Has_Per_Object_Constraint
(Entity
(Selector_Name
(N
))) then
8497 -- A small hack. If we have a per-object constrained selected
8498 -- component of a formal parameter, return True since we do not
8499 -- know the actual parameter association yet.
8501 if Prefix_Is_Formal_Parameter
(N
) then
8505 -- Otherwise, check the enclosing object and the selector
8507 return Has_Inferable_Discriminants
(Prefix
(N
))
8509 Has_Inferable_Discriminants
(Selector_Name
(N
));
8512 -- The call to Has_Inferable_Discriminants will determine whether
8513 -- the selector has a constrained Unchecked_Union nominal type.
8515 return Has_Inferable_Discriminants
(Selector_Name
(N
));
8517 -- A qualified expression has inferable discriminants if its subtype
8518 -- mark is a constrained Unchecked_Union subtype.
8520 elsif Nkind
(N
) = N_Qualified_Expression
then
8521 return Is_Unchecked_Union
(Subtype_Mark
(N
))
8523 Is_Constrained
(Subtype_Mark
(N
));
8528 end Has_Inferable_Discriminants
;
8530 -------------------------------
8531 -- Insert_Dereference_Action --
8532 -------------------------------
8534 procedure Insert_Dereference_Action
(N
: Node_Id
) is
8535 Loc
: constant Source_Ptr
:= Sloc
(N
);
8536 Typ
: constant Entity_Id
:= Etype
(N
);
8537 Pool
: constant Entity_Id
:= Associated_Storage_Pool
(Typ
);
8538 Pnod
: constant Node_Id
:= Parent
(N
);
8540 function Is_Checked_Storage_Pool
(P
: Entity_Id
) return Boolean;
8541 -- Return true if type of P is derived from Checked_Pool;
8543 -----------------------------
8544 -- Is_Checked_Storage_Pool --
8545 -----------------------------
8547 function Is_Checked_Storage_Pool
(P
: Entity_Id
) return Boolean is
8556 while T
/= Etype
(T
) loop
8557 if Is_RTE
(T
, RE_Checked_Pool
) then
8565 end Is_Checked_Storage_Pool
;
8567 -- Start of processing for Insert_Dereference_Action
8570 pragma Assert
(Nkind
(Pnod
) = N_Explicit_Dereference
);
8572 if not (Is_Checked_Storage_Pool
(Pool
)
8573 and then Comes_From_Source
(Original_Node
(Pnod
)))
8579 Make_Procedure_Call_Statement
(Loc
,
8580 Name
=> New_Reference_To
(
8581 Find_Prim_Op
(Etype
(Pool
), Name_Dereference
), Loc
),
8583 Parameter_Associations
=> New_List
(
8587 New_Reference_To
(Pool
, Loc
),
8589 -- Storage_Address. We use the attribute Pool_Address, which uses
8590 -- the pointer itself to find the address of the object, and which
8591 -- handles unconstrained arrays properly by computing the address
8592 -- of the template. i.e. the correct address of the corresponding
8595 Make_Attribute_Reference
(Loc
,
8596 Prefix
=> Duplicate_Subexpr_Move_Checks
(N
),
8597 Attribute_Name
=> Name_Pool_Address
),
8599 -- Size_In_Storage_Elements
8601 Make_Op_Divide
(Loc
,
8603 Make_Attribute_Reference
(Loc
,
8605 Make_Explicit_Dereference
(Loc
,
8606 Duplicate_Subexpr_Move_Checks
(N
)),
8607 Attribute_Name
=> Name_Size
),
8609 Make_Integer_Literal
(Loc
, System_Storage_Unit
)),
8613 Make_Attribute_Reference
(Loc
,
8615 Make_Explicit_Dereference
(Loc
,
8616 Duplicate_Subexpr_Move_Checks
(N
)),
8617 Attribute_Name
=> Name_Alignment
))));
8620 when RE_Not_Available
=>
8622 end Insert_Dereference_Action
;
8624 ------------------------------
8625 -- Make_Array_Comparison_Op --
8626 ------------------------------
8628 -- This is a hand-coded expansion of the following generic function:
8631 -- type elem is (<>);
8632 -- type index is (<>);
8633 -- type a is array (index range <>) of elem;
8635 -- function Gnnn (X : a; Y: a) return boolean is
8636 -- J : index := Y'first;
8639 -- if X'length = 0 then
8642 -- elsif Y'length = 0 then
8646 -- for I in X'range loop
8647 -- if X (I) = Y (J) then
8648 -- if J = Y'last then
8651 -- J := index'succ (J);
8655 -- return X (I) > Y (J);
8659 -- return X'length > Y'length;
8663 -- Note that since we are essentially doing this expansion by hand, we
8664 -- do not need to generate an actual or formal generic part, just the
8665 -- instantiated function itself.
8667 function Make_Array_Comparison_Op
8669 Nod
: Node_Id
) return Node_Id
8671 Loc
: constant Source_Ptr
:= Sloc
(Nod
);
8673 X
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uX
);
8674 Y
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uY
);
8675 I
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uI
);
8676 J
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uJ
);
8678 Index
: constant Entity_Id
:= Base_Type
(Etype
(First_Index
(Typ
)));
8680 Loop_Statement
: Node_Id
;
8681 Loop_Body
: Node_Id
;
8684 Final_Expr
: Node_Id
;
8685 Func_Body
: Node_Id
;
8686 Func_Name
: Entity_Id
;
8692 -- if J = Y'last then
8695 -- J := index'succ (J);
8699 Make_Implicit_If_Statement
(Nod
,
8702 Left_Opnd
=> New_Reference_To
(J
, Loc
),
8704 Make_Attribute_Reference
(Loc
,
8705 Prefix
=> New_Reference_To
(Y
, Loc
),
8706 Attribute_Name
=> Name_Last
)),
8708 Then_Statements
=> New_List
(
8709 Make_Exit_Statement
(Loc
)),
8713 Make_Assignment_Statement
(Loc
,
8714 Name
=> New_Reference_To
(J
, Loc
),
8716 Make_Attribute_Reference
(Loc
,
8717 Prefix
=> New_Reference_To
(Index
, Loc
),
8718 Attribute_Name
=> Name_Succ
,
8719 Expressions
=> New_List
(New_Reference_To
(J
, Loc
))))));
8721 -- if X (I) = Y (J) then
8724 -- return X (I) > Y (J);
8728 Make_Implicit_If_Statement
(Nod
,
8732 Make_Indexed_Component
(Loc
,
8733 Prefix
=> New_Reference_To
(X
, Loc
),
8734 Expressions
=> New_List
(New_Reference_To
(I
, Loc
))),
8737 Make_Indexed_Component
(Loc
,
8738 Prefix
=> New_Reference_To
(Y
, Loc
),
8739 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)))),
8741 Then_Statements
=> New_List
(Inner_If
),
8743 Else_Statements
=> New_List
(
8744 Make_Simple_Return_Statement
(Loc
,
8748 Make_Indexed_Component
(Loc
,
8749 Prefix
=> New_Reference_To
(X
, Loc
),
8750 Expressions
=> New_List
(New_Reference_To
(I
, Loc
))),
8753 Make_Indexed_Component
(Loc
,
8754 Prefix
=> New_Reference_To
(Y
, Loc
),
8755 Expressions
=> New_List
(
8756 New_Reference_To
(J
, Loc
)))))));
8758 -- for I in X'range loop
8763 Make_Implicit_Loop_Statement
(Nod
,
8764 Identifier
=> Empty
,
8767 Make_Iteration_Scheme
(Loc
,
8768 Loop_Parameter_Specification
=>
8769 Make_Loop_Parameter_Specification
(Loc
,
8770 Defining_Identifier
=> I
,
8771 Discrete_Subtype_Definition
=>
8772 Make_Attribute_Reference
(Loc
,
8773 Prefix
=> New_Reference_To
(X
, Loc
),
8774 Attribute_Name
=> Name_Range
))),
8776 Statements
=> New_List
(Loop_Body
));
8778 -- if X'length = 0 then
8780 -- elsif Y'length = 0 then
8783 -- for ... loop ... end loop;
8784 -- return X'length > Y'length;
8788 Make_Attribute_Reference
(Loc
,
8789 Prefix
=> New_Reference_To
(X
, Loc
),
8790 Attribute_Name
=> Name_Length
);
8793 Make_Attribute_Reference
(Loc
,
8794 Prefix
=> New_Reference_To
(Y
, Loc
),
8795 Attribute_Name
=> Name_Length
);
8799 Left_Opnd
=> Length1
,
8800 Right_Opnd
=> Length2
);
8803 Make_Implicit_If_Statement
(Nod
,
8807 Make_Attribute_Reference
(Loc
,
8808 Prefix
=> New_Reference_To
(X
, Loc
),
8809 Attribute_Name
=> Name_Length
),
8811 Make_Integer_Literal
(Loc
, 0)),
8815 Make_Simple_Return_Statement
(Loc
,
8816 Expression
=> New_Reference_To
(Standard_False
, Loc
))),
8818 Elsif_Parts
=> New_List
(
8819 Make_Elsif_Part
(Loc
,
8823 Make_Attribute_Reference
(Loc
,
8824 Prefix
=> New_Reference_To
(Y
, Loc
),
8825 Attribute_Name
=> Name_Length
),
8827 Make_Integer_Literal
(Loc
, 0)),
8831 Make_Simple_Return_Statement
(Loc
,
8832 Expression
=> New_Reference_To
(Standard_True
, Loc
))))),
8834 Else_Statements
=> New_List
(
8836 Make_Simple_Return_Statement
(Loc
,
8837 Expression
=> Final_Expr
)));
8841 Formals
:= New_List
(
8842 Make_Parameter_Specification
(Loc
,
8843 Defining_Identifier
=> X
,
8844 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)),
8846 Make_Parameter_Specification
(Loc
,
8847 Defining_Identifier
=> Y
,
8848 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)));
8850 -- function Gnnn (...) return boolean is
8851 -- J : index := Y'first;
8856 Func_Name
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('G'));
8859 Make_Subprogram_Body
(Loc
,
8861 Make_Function_Specification
(Loc
,
8862 Defining_Unit_Name
=> Func_Name
,
8863 Parameter_Specifications
=> Formals
,
8864 Result_Definition
=> New_Reference_To
(Standard_Boolean
, Loc
)),
8866 Declarations
=> New_List
(
8867 Make_Object_Declaration
(Loc
,
8868 Defining_Identifier
=> J
,
8869 Object_Definition
=> New_Reference_To
(Index
, Loc
),
8871 Make_Attribute_Reference
(Loc
,
8872 Prefix
=> New_Reference_To
(Y
, Loc
),
8873 Attribute_Name
=> Name_First
))),
8875 Handled_Statement_Sequence
=>
8876 Make_Handled_Sequence_Of_Statements
(Loc
,
8877 Statements
=> New_List
(If_Stat
)));
8880 end Make_Array_Comparison_Op
;
8882 ---------------------------
8883 -- Make_Boolean_Array_Op --
8884 ---------------------------
8886 -- For logical operations on boolean arrays, expand in line the following,
8887 -- replacing 'and' with 'or' or 'xor' where needed:
8889 -- function Annn (A : typ; B: typ) return typ is
8892 -- for J in A'range loop
8893 -- C (J) := A (J) op B (J);
8898 -- Here typ is the boolean array type
8900 function Make_Boolean_Array_Op
8902 N
: Node_Id
) return Node_Id
8904 Loc
: constant Source_Ptr
:= Sloc
(N
);
8906 A
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uA
);
8907 B
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uB
);
8908 C
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uC
);
8909 J
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uJ
);
8917 Func_Name
: Entity_Id
;
8918 Func_Body
: Node_Id
;
8919 Loop_Statement
: Node_Id
;
8923 Make_Indexed_Component
(Loc
,
8924 Prefix
=> New_Reference_To
(A
, Loc
),
8925 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
8928 Make_Indexed_Component
(Loc
,
8929 Prefix
=> New_Reference_To
(B
, Loc
),
8930 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
8933 Make_Indexed_Component
(Loc
,
8934 Prefix
=> New_Reference_To
(C
, Loc
),
8935 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
8937 if Nkind
(N
) = N_Op_And
then
8943 elsif Nkind
(N
) = N_Op_Or
then
8957 Make_Implicit_Loop_Statement
(N
,
8958 Identifier
=> Empty
,
8961 Make_Iteration_Scheme
(Loc
,
8962 Loop_Parameter_Specification
=>
8963 Make_Loop_Parameter_Specification
(Loc
,
8964 Defining_Identifier
=> J
,
8965 Discrete_Subtype_Definition
=>
8966 Make_Attribute_Reference
(Loc
,
8967 Prefix
=> New_Reference_To
(A
, Loc
),
8968 Attribute_Name
=> Name_Range
))),
8970 Statements
=> New_List
(
8971 Make_Assignment_Statement
(Loc
,
8973 Expression
=> Op
)));
8975 Formals
:= New_List
(
8976 Make_Parameter_Specification
(Loc
,
8977 Defining_Identifier
=> A
,
8978 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)),
8980 Make_Parameter_Specification
(Loc
,
8981 Defining_Identifier
=> B
,
8982 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)));
8985 Make_Defining_Identifier
(Loc
, New_Internal_Name
('A'));
8986 Set_Is_Inlined
(Func_Name
);
8989 Make_Subprogram_Body
(Loc
,
8991 Make_Function_Specification
(Loc
,
8992 Defining_Unit_Name
=> Func_Name
,
8993 Parameter_Specifications
=> Formals
,
8994 Result_Definition
=> New_Reference_To
(Typ
, Loc
)),
8996 Declarations
=> New_List
(
8997 Make_Object_Declaration
(Loc
,
8998 Defining_Identifier
=> C
,
8999 Object_Definition
=> New_Reference_To
(Typ
, Loc
))),
9001 Handled_Statement_Sequence
=>
9002 Make_Handled_Sequence_Of_Statements
(Loc
,
9003 Statements
=> New_List
(
9005 Make_Simple_Return_Statement
(Loc
,
9006 Expression
=> New_Reference_To
(C
, Loc
)))));
9009 end Make_Boolean_Array_Op
;
9011 ------------------------
9012 -- Rewrite_Comparison --
9013 ------------------------
9015 procedure Rewrite_Comparison
(N
: Node_Id
) is
9017 if Nkind
(N
) = N_Type_Conversion
then
9018 Rewrite_Comparison
(Expression
(N
));
9021 elsif Nkind
(N
) not in N_Op_Compare
then
9026 Typ
: constant Entity_Id
:= Etype
(N
);
9027 Op1
: constant Node_Id
:= Left_Opnd
(N
);
9028 Op2
: constant Node_Id
:= Right_Opnd
(N
);
9030 Res
: constant Compare_Result
:=
9031 Compile_Time_Compare
(Op1
, Op2
, Assume_Valid
=> True);
9032 -- Res indicates if compare outcome can be compile time determined
9034 True_Result
: Boolean;
9035 False_Result
: Boolean;
9038 case N_Op_Compare
(Nkind
(N
)) is
9040 True_Result
:= Res
= EQ
;
9041 False_Result
:= Res
= LT
or else Res
= GT
or else Res
= NE
;
9044 True_Result
:= Res
in Compare_GE
;
9045 False_Result
:= Res
= LT
;
9048 and then Constant_Condition_Warnings
9049 and then Comes_From_Source
(Original_Node
(N
))
9050 and then Nkind
(Original_Node
(N
)) = N_Op_Ge
9051 and then not In_Instance
9052 and then Is_Integer_Type
(Etype
(Left_Opnd
(N
)))
9053 and then not Has_Warnings_Off
(Etype
(Left_Opnd
(N
)))
9056 ("can never be greater than, could replace by ""'=""?", N
);
9060 True_Result
:= Res
= GT
;
9061 False_Result
:= Res
in Compare_LE
;
9064 True_Result
:= Res
= LT
;
9065 False_Result
:= Res
in Compare_GE
;
9068 True_Result
:= Res
in Compare_LE
;
9069 False_Result
:= Res
= GT
;
9072 and then Constant_Condition_Warnings
9073 and then Comes_From_Source
(Original_Node
(N
))
9074 and then Nkind
(Original_Node
(N
)) = N_Op_Le
9075 and then not In_Instance
9076 and then Is_Integer_Type
(Etype
(Left_Opnd
(N
)))
9077 and then not Has_Warnings_Off
(Etype
(Left_Opnd
(N
)))
9080 ("can never be less than, could replace by ""'=""?", N
);
9084 True_Result
:= Res
= NE
or else Res
= GT
or else Res
= LT
;
9085 False_Result
:= Res
= EQ
;
9091 New_Occurrence_Of
(Standard_True
, Sloc
(N
))));
9092 Analyze_And_Resolve
(N
, Typ
);
9093 Warn_On_Known_Condition
(N
);
9095 elsif False_Result
then
9098 New_Occurrence_Of
(Standard_False
, Sloc
(N
))));
9099 Analyze_And_Resolve
(N
, Typ
);
9100 Warn_On_Known_Condition
(N
);
9103 end Rewrite_Comparison
;
9105 ----------------------------
9106 -- Safe_In_Place_Array_Op --
9107 ----------------------------
9109 function Safe_In_Place_Array_Op
9112 Op2
: Node_Id
) return Boolean
9116 function Is_Safe_Operand
(Op
: Node_Id
) return Boolean;
9117 -- Operand is safe if it cannot overlap part of the target of the
9118 -- operation. If the operand and the target are identical, the operand
9119 -- is safe. The operand can be empty in the case of negation.
9121 function Is_Unaliased
(N
: Node_Id
) return Boolean;
9122 -- Check that N is a stand-alone entity
9128 function Is_Unaliased
(N
: Node_Id
) return Boolean is
9132 and then No
(Address_Clause
(Entity
(N
)))
9133 and then No
(Renamed_Object
(Entity
(N
)));
9136 ---------------------
9137 -- Is_Safe_Operand --
9138 ---------------------
9140 function Is_Safe_Operand
(Op
: Node_Id
) return Boolean is
9145 elsif Is_Entity_Name
(Op
) then
9146 return Is_Unaliased
(Op
);
9148 elsif Nkind_In
(Op
, N_Indexed_Component
, N_Selected_Component
) then
9149 return Is_Unaliased
(Prefix
(Op
));
9151 elsif Nkind
(Op
) = N_Slice
then
9153 Is_Unaliased
(Prefix
(Op
))
9154 and then Entity
(Prefix
(Op
)) /= Target
;
9156 elsif Nkind
(Op
) = N_Op_Not
then
9157 return Is_Safe_Operand
(Right_Opnd
(Op
));
9162 end Is_Safe_Operand
;
9164 -- Start of processing for Is_Safe_In_Place_Array_Op
9167 -- Skip this processing if the component size is different from system
9168 -- storage unit (since at least for NOT this would cause problems).
9170 if Component_Size
(Etype
(Lhs
)) /= System_Storage_Unit
then
9173 -- Cannot do in place stuff on VM_Target since cannot pass addresses
9175 elsif VM_Target
/= No_VM
then
9178 -- Cannot do in place stuff if non-standard Boolean representation
9180 elsif Has_Non_Standard_Rep
(Component_Type
(Etype
(Lhs
))) then
9183 elsif not Is_Unaliased
(Lhs
) then
9186 Target
:= Entity
(Lhs
);
9189 Is_Safe_Operand
(Op1
)
9190 and then Is_Safe_Operand
(Op2
);
9192 end Safe_In_Place_Array_Op
;
9194 -----------------------
9195 -- Tagged_Membership --
9196 -----------------------
9198 -- There are two different cases to consider depending on whether the right
9199 -- operand is a class-wide type or not. If not we just compare the actual
9200 -- tag of the left expr to the target type tag:
9202 -- Left_Expr.Tag = Right_Type'Tag;
9204 -- If it is a class-wide type we use the RT function CW_Membership which is
9205 -- usually implemented by looking in the ancestor tables contained in the
9206 -- dispatch table pointed by Left_Expr.Tag for Typ'Tag
9208 -- Ada 2005 (AI-251): If it is a class-wide interface type we use the RT
9209 -- function IW_Membership which is usually implemented by looking in the
9210 -- table of abstract interface types plus the ancestor table contained in
9211 -- the dispatch table pointed by Left_Expr.Tag for Typ'Tag
9213 function Tagged_Membership
(N
: Node_Id
) return Node_Id
is
9214 Left
: constant Node_Id
:= Left_Opnd
(N
);
9215 Right
: constant Node_Id
:= Right_Opnd
(N
);
9216 Loc
: constant Source_Ptr
:= Sloc
(N
);
9218 Left_Type
: Entity_Id
;
9219 Right_Type
: Entity_Id
;
9223 Left_Type
:= Etype
(Left
);
9224 Right_Type
:= Etype
(Right
);
9226 if Is_Class_Wide_Type
(Left_Type
) then
9227 Left_Type
:= Root_Type
(Left_Type
);
9231 Make_Selected_Component
(Loc
,
9232 Prefix
=> Relocate_Node
(Left
),
9234 New_Reference_To
(First_Tag_Component
(Left_Type
), Loc
));
9236 if Is_Class_Wide_Type
(Right_Type
) then
9238 -- No need to issue a run-time check if we statically know that the
9239 -- result of this membership test is always true. For example,
9240 -- considering the following declarations:
9242 -- type Iface is interface;
9243 -- type T is tagged null record;
9244 -- type DT is new T and Iface with null record;
9249 -- These membership tests are always true:
9253 -- Obj2 in Iface'Class;
9255 -- We do not need to handle cases where the membership is illegal.
9258 -- Obj1 in DT'Class; -- Compile time error
9259 -- Obj1 in Iface'Class; -- Compile time error
9261 if not Is_Class_Wide_Type
(Left_Type
)
9262 and then (Is_Ancestor
(Etype
(Right_Type
), Left_Type
)
9263 or else (Is_Interface
(Etype
(Right_Type
))
9264 and then Interface_Present_In_Ancestor
9266 Iface
=> Etype
(Right_Type
))))
9268 return New_Reference_To
(Standard_True
, Loc
);
9271 -- Ada 2005 (AI-251): Class-wide applied to interfaces
9273 if Is_Interface
(Etype
(Class_Wide_Type
(Right_Type
)))
9275 -- Support to: "Iface_CW_Typ in Typ'Class"
9277 or else Is_Interface
(Left_Type
)
9279 -- Issue error if IW_Membership operation not available in a
9280 -- configurable run time setting.
9282 if not RTE_Available
(RE_IW_Membership
) then
9284 ("dynamic membership test on interface types", N
);
9289 Make_Function_Call
(Loc
,
9290 Name
=> New_Occurrence_Of
(RTE
(RE_IW_Membership
), Loc
),
9291 Parameter_Associations
=> New_List
(
9292 Make_Attribute_Reference
(Loc
,
9294 Attribute_Name
=> Name_Address
),
9297 (Access_Disp_Table
(Root_Type
(Right_Type
)))),
9300 -- Ada 95: Normal case
9304 Build_CW_Membership
(Loc
,
9305 Obj_Tag_Node
=> Obj_Tag
,
9309 (Access_Disp_Table
(Root_Type
(Right_Type
)))),
9313 -- Right_Type is not a class-wide type
9316 -- No need to check the tag of the object if Right_Typ is abstract
9318 if Is_Abstract_Type
(Right_Type
) then
9319 return New_Reference_To
(Standard_False
, Loc
);
9324 Left_Opnd
=> Obj_Tag
,
9327 (Node
(First_Elmt
(Access_Disp_Table
(Right_Type
))), Loc
));
9330 end Tagged_Membership
;
9332 ------------------------------
9333 -- Unary_Op_Validity_Checks --
9334 ------------------------------
9336 procedure Unary_Op_Validity_Checks
(N
: Node_Id
) is
9338 if Validity_Checks_On
and Validity_Check_Operands
then
9339 Ensure_Valid
(Right_Opnd
(N
));
9341 end Unary_Op_Validity_Checks
;