1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
11 -- Copyright (C) 1992-2001, Free Software Foundation, Inc. --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
24 -- GNAT was originally developed by the GNAT team at New York University. --
25 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
27 ------------------------------------------------------------------------------
29 with Atree
; use Atree
;
30 with Checks
; use Checks
;
31 with Einfo
; use Einfo
;
32 with Elists
; use Elists
;
33 with Errout
; use Errout
;
34 with Exp_Aggr
; use Exp_Aggr
;
35 with Exp_Ch3
; use Exp_Ch3
;
36 with Exp_Ch7
; use Exp_Ch7
;
37 with Exp_Ch9
; use Exp_Ch9
;
38 with Exp_Disp
; use Exp_Disp
;
39 with Exp_Fixd
; use Exp_Fixd
;
40 with Exp_Pakd
; use Exp_Pakd
;
41 with Exp_Tss
; use Exp_Tss
;
42 with Exp_Util
; use Exp_Util
;
43 with Exp_VFpt
; use Exp_VFpt
;
44 with Hostparm
; use Hostparm
;
45 with Inline
; use Inline
;
46 with Nlists
; use Nlists
;
47 with Nmake
; use Nmake
;
49 with Rtsfind
; use Rtsfind
;
51 with Sem_Cat
; use Sem_Cat
;
52 with Sem_Ch13
; use Sem_Ch13
;
53 with Sem_Eval
; use Sem_Eval
;
54 with Sem_Res
; use Sem_Res
;
55 with Sem_Type
; use Sem_Type
;
56 with Sem_Util
; use Sem_Util
;
57 with Sinfo
; use Sinfo
;
58 with Sinfo
.CN
; use Sinfo
.CN
;
59 with Snames
; use Snames
;
60 with Stand
; use Stand
;
61 with Tbuild
; use Tbuild
;
62 with Ttypes
; use Ttypes
;
63 with Uintp
; use Uintp
;
64 with Urealp
; use Urealp
;
65 with Validsw
; use Validsw
;
67 package body Exp_Ch4
is
69 ------------------------
70 -- Local Subprograms --
71 ------------------------
73 procedure Binary_Op_Validity_Checks
(N
: Node_Id
);
74 pragma Inline
(Binary_Op_Validity_Checks
);
75 -- Performs validity checks for a binary operator
77 procedure Expand_Array_Comparison
(N
: Node_Id
);
78 -- This routine handles expansion of the comparison operators (N_Op_Lt,
79 -- N_Op_Le, N_Op_Gt, N_Op_Ge) when operating on an array type. The basic
80 -- code for these operators is similar, differing only in the details of
81 -- the actual comparison call that is made.
83 function Expand_Array_Equality
91 -- Expand an array equality into a call to a function implementing this
92 -- equality, and a call to it. Loc is the location for the generated
93 -- nodes. Typ is the type of the array, and Lhs, Rhs are the array
94 -- expressions to be compared. A_Typ is the type of the arguments,
95 -- which may be a private type, in which case Typ is its full view.
96 -- Bodies is a list on which to attach bodies of local functions that
97 -- are created in the process. This is the responsability of the
98 -- caller to insert those bodies at the right place. Nod provides
99 -- the Sloc value for the generated code.
101 procedure Expand_Boolean_Operator
(N
: Node_Id
);
102 -- Common expansion processing for Boolean operators (And, Or, Xor)
103 -- for the case of array type arguments.
105 function Expand_Composite_Equality
112 -- Local recursive function used to expand equality for nested
113 -- composite types. Used by Expand_Record/Array_Equality, Bodies
114 -- is a list on which to attach bodies of local functions that are
115 -- created in the process. This is the responsability of the caller
116 -- to insert those bodies at the right place. Nod provides the Sloc
117 -- value for generated code.
119 procedure Expand_Concatenate_Other
(Cnode
: Node_Id
; Opnds
: List_Id
);
120 -- This routine handles expansion of concatenation operations, where
121 -- N is the N_Op_Concat node being expanded and Operands is the list
122 -- of operands (at least two are present). The caller has dealt with
123 -- converting any singleton operands into singleton aggregates.
125 procedure Expand_Concatenate_String
(Cnode
: Node_Id
; Opnds
: List_Id
);
126 -- Routine to expand concatenation of 2-5 operands (in the list Operands)
127 -- and replace node Cnode with the result of the contatenation. If there
128 -- are two operands, they can be string or character. If there are more
129 -- than two operands, then are always of type string (i.e. the caller has
130 -- already converted character operands to strings in this case).
132 procedure Fixup_Universal_Fixed_Operation
(N
: Node_Id
);
133 -- N is either an N_Op_Divide or N_Op_Multiply node whose result is
134 -- universal fixed. We do not have such a type at runtime, so the
135 -- purpose of this routine is to find the real type by looking up
136 -- the tree. We also determine if the operation must be rounded.
138 procedure Insert_Dereference_Action
(N
: Node_Id
);
139 -- N is an expression whose type is an access. When the type is derived
140 -- from Checked_Pool, expands a call to the primitive 'dereference'.
142 function Make_Array_Comparison_Op
146 -- Comparisons between arrays are expanded in line. This function
147 -- produces the body of the implementation of (a > b), where a and b
148 -- are one-dimensional arrays of some discrete type. The original
149 -- node is then expanded into the appropriate call to this function.
150 -- Nod provides the Sloc value for the generated code.
152 function Make_Boolean_Array_Op
156 -- Boolean operations on boolean arrays are expanded in line. This
157 -- function produce the body for the node N, which is (a and b),
158 -- (a or b), or (a xor b). It is used only the normal case and not
159 -- the packed case. The type involved, Typ, is the Boolean array type,
160 -- and the logical operations in the body are simple boolean operations.
161 -- Note that Typ is always a constrained type (the caller has ensured
162 -- this by using Convert_To_Actual_Subtype if necessary).
164 procedure Rewrite_Comparison
(N
: Node_Id
);
165 -- N is the node for a compile time comparison. If this outcome of this
166 -- comparison can be determined at compile time, then the node N can be
167 -- rewritten with True or False. If the outcome cannot be determined at
168 -- compile time, the call has no effect.
170 function Tagged_Membership
(N
: Node_Id
) return Node_Id
;
171 -- Construct the expression corresponding to the tagged membership test.
172 -- Deals with a second operand being (or not) a class-wide type.
174 procedure Unary_Op_Validity_Checks
(N
: Node_Id
);
175 pragma Inline
(Unary_Op_Validity_Checks
);
176 -- Performs validity checks for a unary operator
178 -------------------------------
179 -- Binary_Op_Validity_Checks --
180 -------------------------------
182 procedure Binary_Op_Validity_Checks
(N
: Node_Id
) is
184 if Validity_Checks_On
and Validity_Check_Operands
then
185 Ensure_Valid
(Left_Opnd
(N
));
186 Ensure_Valid
(Right_Opnd
(N
));
188 end Binary_Op_Validity_Checks
;
190 -----------------------------
191 -- Expand_Array_Comparison --
192 -----------------------------
194 -- Expansion is only required in the case of array types. The form of
197 -- [body for greater_nn; boolean_expression]
199 -- The body is built by Make_Array_Comparison_Op, and the form of the
200 -- Boolean expression depends on the operator involved.
202 procedure Expand_Array_Comparison
(N
: Node_Id
) is
203 Loc
: constant Source_Ptr
:= Sloc
(N
);
204 Op1
: Node_Id
:= Left_Opnd
(N
);
205 Op2
: Node_Id
:= Right_Opnd
(N
);
206 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
210 Func_Name
: Entity_Id
;
213 -- For (a <= b) we convert to not (a > b)
215 if Chars
(N
) = Name_Op_Le
then
221 Right_Opnd
=> Op2
)));
222 Analyze_And_Resolve
(N
, Standard_Boolean
);
225 -- For < the Boolean expression is
226 -- greater__nn (op2, op1)
228 elsif Chars
(N
) = Name_Op_Lt
then
229 Func_Body
:= Make_Array_Comparison_Op
(Typ1
, N
);
233 Op1
:= Right_Opnd
(N
);
234 Op2
:= Left_Opnd
(N
);
236 -- For (a >= b) we convert to not (a < b)
238 elsif Chars
(N
) = Name_Op_Ge
then
244 Right_Opnd
=> Op2
)));
245 Analyze_And_Resolve
(N
, Standard_Boolean
);
248 -- For > the Boolean expression is
249 -- greater__nn (op1, op2)
252 pragma Assert
(Chars
(N
) = Name_Op_Gt
);
253 Func_Body
:= Make_Array_Comparison_Op
(Typ1
, N
);
256 Func_Name
:= Defining_Unit_Name
(Specification
(Func_Body
));
258 Make_Function_Call
(Loc
,
259 Name
=> New_Reference_To
(Func_Name
, Loc
),
260 Parameter_Associations
=> New_List
(Op1
, Op2
));
262 Insert_Action
(N
, Func_Body
);
264 Analyze_And_Resolve
(N
, Standard_Boolean
);
266 end Expand_Array_Comparison
;
268 ---------------------------
269 -- Expand_Array_Equality --
270 ---------------------------
272 -- Expand an equality function for multi-dimensional arrays. Here is
273 -- an example of such a function for Nb_Dimension = 2
275 -- function Enn (A : arr; B : arr) return boolean is
280 -- if A'length (1) /= B'length (1) then
283 -- J1 := B'first (1);
284 -- for I1 in A'first (1) .. A'last (1) loop
285 -- if A'length (2) /= B'length (2) then
288 -- J2 := B'first (2);
289 -- for I2 in A'first (2) .. A'last (2) loop
290 -- if A (I1, I2) /= B (J1, J2) then
293 -- J2 := Integer'succ (J2);
296 -- J1 := Integer'succ (J1);
302 function Expand_Array_Equality
311 Loc
: constant Source_Ptr
:= Sloc
(Nod
);
313 Decls
: List_Id
:= New_List
;
314 Index_List1
: List_Id
:= New_List
;
315 Index_List2
: List_Id
:= New_List
;
318 Func_Name
: Entity_Id
;
321 A
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uA
);
322 B
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uB
);
324 function Component_Equality
(Typ
: Entity_Id
) return Node_Id
;
325 -- Create one statement to compare corresponding components, designated
326 -- by a full set of indices.
328 function Loop_One_Dimension
332 -- Loop over the n'th dimension of the arrays. The single statement
333 -- in the body of the loop is a loop over the next dimension, or
334 -- the comparison of corresponding components.
336 ------------------------
337 -- Component_Equality --
338 ------------------------
340 function Component_Equality
(Typ
: Entity_Id
) return Node_Id
is
345 -- if a(i1...) /= b(j1...) then return false; end if;
348 Make_Indexed_Component
(Loc
,
349 Prefix
=> Make_Identifier
(Loc
, Chars
(A
)),
350 Expressions
=> Index_List1
);
353 Make_Indexed_Component
(Loc
,
354 Prefix
=> Make_Identifier
(Loc
, Chars
(B
)),
355 Expressions
=> Index_List2
);
357 Test
:= Expand_Composite_Equality
358 (Nod
, Component_Type
(Typ
), L
, R
, Decls
);
361 Make_Implicit_If_Statement
(Nod
,
362 Condition
=> Make_Op_Not
(Loc
, Right_Opnd
=> Test
),
363 Then_Statements
=> New_List
(
364 Make_Return_Statement
(Loc
,
365 Expression
=> New_Occurrence_Of
(Standard_False
, Loc
))));
367 end Component_Equality
;
369 ------------------------
370 -- Loop_One_Dimension --
371 ------------------------
373 function Loop_One_Dimension
378 I
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
,
379 New_Internal_Name
('I'));
380 J
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
,
381 New_Internal_Name
('J'));
382 Index_Type
: Entity_Id
;
386 if N
> Number_Dimensions
(Typ
) then
387 return Component_Equality
(Typ
);
390 -- Generate the following:
395 -- if a'length (n) /= b'length (n) then
399 -- for i in a'range (n) loop
400 -- -- loop over remaining dimensions.
401 -- j := index_type'succ (j);
405 -- retrieve index type for current dimension.
407 Index_Type
:= Base_Type
(Etype
(Index
));
408 Append
(New_Reference_To
(I
, Loc
), Index_List1
);
409 Append
(New_Reference_To
(J
, Loc
), Index_List2
);
411 -- Declare index for j as a local variable to the function.
412 -- Index i is a loop variable.
415 Make_Object_Declaration
(Loc
,
416 Defining_Identifier
=> J
,
417 Object_Definition
=> New_Reference_To
(Index_Type
, Loc
)));
420 Make_Implicit_If_Statement
(Nod
,
424 Make_Attribute_Reference
(Loc
,
425 Prefix
=> New_Reference_To
(A
, Loc
),
426 Attribute_Name
=> Name_Length
,
427 Expressions
=> New_List
(
428 Make_Integer_Literal
(Loc
, N
))),
430 Make_Attribute_Reference
(Loc
,
431 Prefix
=> New_Reference_To
(B
, Loc
),
432 Attribute_Name
=> Name_Length
,
433 Expressions
=> New_List
(
434 Make_Integer_Literal
(Loc
, N
)))),
436 Then_Statements
=> New_List
(
437 Make_Return_Statement
(Loc
,
438 Expression
=> New_Occurrence_Of
(Standard_False
, Loc
))),
440 Else_Statements
=> New_List
(
442 Make_Assignment_Statement
(Loc
,
443 Name
=> New_Reference_To
(J
, Loc
),
445 Make_Attribute_Reference
(Loc
,
446 Prefix
=> New_Reference_To
(B
, Loc
),
447 Attribute_Name
=> Name_First
,
448 Expressions
=> New_List
(
449 Make_Integer_Literal
(Loc
, N
)))),
451 Make_Implicit_Loop_Statement
(Nod
,
454 Make_Iteration_Scheme
(Loc
,
455 Loop_Parameter_Specification
=>
456 Make_Loop_Parameter_Specification
(Loc
,
457 Defining_Identifier
=> I
,
458 Discrete_Subtype_Definition
=>
459 Make_Attribute_Reference
(Loc
,
460 Prefix
=> New_Reference_To
(A
, Loc
),
461 Attribute_Name
=> Name_Range
,
462 Expressions
=> New_List
(
463 Make_Integer_Literal
(Loc
, N
))))),
465 Statements
=> New_List
(
466 Loop_One_Dimension
(N
+ 1, Next_Index
(Index
)),
467 Make_Assignment_Statement
(Loc
,
468 Name
=> New_Reference_To
(J
, Loc
),
470 Make_Attribute_Reference
(Loc
,
471 Prefix
=> New_Reference_To
(Index_Type
, Loc
),
472 Attribute_Name
=> Name_Succ
,
473 Expressions
=> New_List
(
474 New_Reference_To
(J
, Loc
))))))));
478 end Loop_One_Dimension
;
480 -- Start of processing for Expand_Array_Equality
483 Formals
:= New_List
(
484 Make_Parameter_Specification
(Loc
,
485 Defining_Identifier
=> A
,
486 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)),
488 Make_Parameter_Specification
(Loc
,
489 Defining_Identifier
=> B
,
490 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)));
492 Func_Name
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('E'));
494 Stats
:= Loop_One_Dimension
(1, First_Index
(Typ
));
497 Make_Subprogram_Body
(Loc
,
499 Make_Function_Specification
(Loc
,
500 Defining_Unit_Name
=> Func_Name
,
501 Parameter_Specifications
=> Formals
,
502 Subtype_Mark
=> New_Reference_To
(Standard_Boolean
, Loc
)),
503 Declarations
=> Decls
,
504 Handled_Statement_Sequence
=>
505 Make_Handled_Sequence_Of_Statements
(Loc
,
506 Statements
=> New_List
(
508 Make_Return_Statement
(Loc
,
509 Expression
=> New_Occurrence_Of
(Standard_True
, Loc
)))));
511 Set_Has_Completion
(Func_Name
, True);
513 -- If the array type is distinct from the type of the arguments,
514 -- it is the full view of a private type. Apply an unchecked
515 -- conversion to insure that analysis of the call succeeds.
517 if Base_Type
(A_Typ
) /= Base_Type
(Typ
) then
518 Actuals
:= New_List
(
519 OK_Convert_To
(Typ
, Lhs
),
520 OK_Convert_To
(Typ
, Rhs
));
522 Actuals
:= New_List
(Lhs
, Rhs
);
525 Append_To
(Bodies
, Func_Body
);
528 Make_Function_Call
(Loc
,
529 Name
=> New_Reference_To
(Func_Name
, Loc
),
530 Parameter_Associations
=> Actuals
);
531 end Expand_Array_Equality
;
533 -----------------------------
534 -- Expand_Boolean_Operator --
535 -----------------------------
537 -- Note that we first get the actual subtypes of the operands,
538 -- since we always want to deal with types that have bounds.
540 procedure Expand_Boolean_Operator
(N
: Node_Id
) is
541 Typ
: constant Entity_Id
:= Etype
(N
);
544 if Is_Bit_Packed_Array
(Typ
) then
545 Expand_Packed_Boolean_Operator
(N
);
549 -- For the normal non-packed case, the expansion is
550 -- to build a function for carrying out the comparison
551 -- (using Make_Boolean_Array_Op) and then inserting it
552 -- into the tree. The original operator node is then
553 -- rewritten as a call to this function.
556 Loc
: constant Source_Ptr
:= Sloc
(N
);
557 L
: constant Node_Id
:= Relocate_Node
(Left_Opnd
(N
));
558 R
: constant Node_Id
:= Relocate_Node
(Right_Opnd
(N
));
560 Func_Name
: Entity_Id
;
562 Convert_To_Actual_Subtype
(L
);
563 Convert_To_Actual_Subtype
(R
);
564 Ensure_Defined
(Etype
(L
), N
);
565 Ensure_Defined
(Etype
(R
), N
);
566 Apply_Length_Check
(R
, Etype
(L
));
568 Func_Body
:= Make_Boolean_Array_Op
(Etype
(L
), N
);
569 Func_Name
:= Defining_Unit_Name
(Specification
(Func_Body
));
570 Insert_Action
(N
, Func_Body
);
572 -- Now rewrite the expression with a call
575 Make_Function_Call
(Loc
,
576 Name
=> New_Reference_To
(Func_Name
, Loc
),
577 Parameter_Associations
=>
579 (L
, Make_Type_Conversion
580 (Loc
, New_Reference_To
(Etype
(L
), Loc
), R
))));
582 Analyze_And_Resolve
(N
, Typ
);
585 end Expand_Boolean_Operator
;
587 -------------------------------
588 -- Expand_Composite_Equality --
589 -------------------------------
591 -- This function is only called for comparing internal fields of composite
592 -- types when these fields are themselves composites. This is a special
593 -- case because it is not possible to respect normal Ada visibility rules.
595 function Expand_Composite_Equality
603 Loc
: constant Source_Ptr
:= Sloc
(Nod
);
604 Full_Type
: Entity_Id
;
609 if Is_Private_Type
(Typ
) then
610 Full_Type
:= Underlying_Type
(Typ
);
615 -- Defense against malformed private types with no completion
616 -- the error will be diagnosed later by check_completion
618 if No
(Full_Type
) then
619 return New_Reference_To
(Standard_False
, Loc
);
622 Full_Type
:= Base_Type
(Full_Type
);
624 if Is_Array_Type
(Full_Type
) then
626 -- If the operand is an elementary type other than a floating-point
627 -- type, then we can simply use the built-in block bitwise equality,
628 -- since the predefined equality operators always apply and bitwise
629 -- equality is fine for all these cases.
631 if Is_Elementary_Type
(Component_Type
(Full_Type
))
632 and then not Is_Floating_Point_Type
(Component_Type
(Full_Type
))
634 return Make_Op_Eq
(Loc
, Left_Opnd
=> Lhs
, Right_Opnd
=> Rhs
);
636 -- For composite component types, and floating-point types, use
637 -- the expansion. This deals with tagged component types (where
638 -- we use the applicable equality routine) and floating-point,
639 -- (where we need to worry about negative zeroes), and also the
640 -- case of any composite type recursively containing such fields.
643 return Expand_Array_Equality
644 (Nod
, Full_Type
, Typ
, Lhs
, Rhs
, Bodies
);
647 elsif Is_Tagged_Type
(Full_Type
) then
649 -- Call the primitive operation "=" of this type
651 if Is_Class_Wide_Type
(Full_Type
) then
652 Full_Type
:= Root_Type
(Full_Type
);
655 -- If this is derived from an untagged private type completed
656 -- with a tagged type, it does not have a full view, so we
657 -- use the primitive operations of the private type.
658 -- This check should no longer be necessary when these
659 -- types receive their full views ???
661 if Is_Private_Type
(Typ
)
662 and then not Is_Tagged_Type
(Typ
)
663 and then not Is_Controlled
(Typ
)
664 and then Is_Derived_Type
(Typ
)
665 and then No
(Full_View
(Typ
))
667 Prim
:= First_Elmt
(Collect_Primitive_Operations
(Typ
));
669 Prim
:= First_Elmt
(Primitive_Operations
(Full_Type
));
673 Eq_Op
:= Node
(Prim
);
674 exit when Chars
(Eq_Op
) = Name_Op_Eq
675 and then Etype
(First_Formal
(Eq_Op
)) =
676 Etype
(Next_Formal
(First_Formal
(Eq_Op
)));
678 pragma Assert
(Present
(Prim
));
681 Eq_Op
:= Node
(Prim
);
684 Make_Function_Call
(Loc
,
685 Name
=> New_Reference_To
(Eq_Op
, Loc
),
686 Parameter_Associations
=>
688 (Unchecked_Convert_To
(Etype
(First_Formal
(Eq_Op
)), Lhs
),
689 Unchecked_Convert_To
(Etype
(First_Formal
(Eq_Op
)), Rhs
)));
691 elsif Is_Record_Type
(Full_Type
) then
692 Eq_Op
:= TSS
(Full_Type
, Name_uEquality
);
694 if Present
(Eq_Op
) then
695 if Etype
(First_Formal
(Eq_Op
)) /= Full_Type
then
697 -- Inherited equality from parent type. Convert the actuals
698 -- to match signature of operation.
701 T
: Entity_Id
:= Etype
(First_Formal
(Eq_Op
));
705 Make_Function_Call
(Loc
,
706 Name
=> New_Reference_To
(Eq_Op
, Loc
),
707 Parameter_Associations
=>
708 New_List
(OK_Convert_To
(T
, Lhs
),
709 OK_Convert_To
(T
, Rhs
)));
714 Make_Function_Call
(Loc
,
715 Name
=> New_Reference_To
(Eq_Op
, Loc
),
716 Parameter_Associations
=> New_List
(Lhs
, Rhs
));
720 return Expand_Record_Equality
(Nod
, Full_Type
, Lhs
, Rhs
, Bodies
);
724 -- It can be a simple record or the full view of a scalar private
726 return Make_Op_Eq
(Loc
, Left_Opnd
=> Lhs
, Right_Opnd
=> Rhs
);
728 end Expand_Composite_Equality
;
730 ------------------------------
731 -- Expand_Concatenate_Other --
732 ------------------------------
734 -- Let n be the number of array operands to be concatenated, Base_Typ
735 -- their base type, Ind_Typ their index type, and Arr_Typ the original
736 -- array type to which the concatenantion operator applies, then the
737 -- following subprogram is constructed:
739 -- [function Cnn (S1 : Base_Typ; ...; Sn : Base_Typ) return Base_Typ is
742 -- if S1'Length /= 0 then
743 -- L := XXX; --> XXX = S1'First if Arr_Typ is unconstrained
744 -- XXX = Arr_Typ'First otherwise
745 -- elsif S2'Length /= 0 then
746 -- L := YYY; --> YYY = S2'First if Arr_Typ is unconstrained
747 -- YYY = Arr_Typ'First otherwise
749 -- elsif Sn-1'Length /= 0 then
750 -- L := ZZZ; --> ZZZ = Sn-1'First if Arr_Typ is unconstrained
751 -- ZZZ = Arr_Typ'First otherwise
759 -- Ind_Typ'Val ((((S1'Length - 1) + S2'Length) + ... + Sn'Length)
760 -- + Ind_Typ'Pos (L));
761 -- R : Base_Typ (L .. H);
763 -- if S1'Length /= 0 then
767 -- L := Ind_Typ'Succ (L);
768 -- exit when P = S1'Last;
769 -- P := Ind_Typ'Succ (P);
773 -- if S2'Length /= 0 then
774 -- L := Ind_Typ'Succ (L);
777 -- L := Ind_Typ'Succ (L);
778 -- exit when P = S2'Last;
779 -- P := Ind_Typ'Succ (P);
785 -- if Sn'Length /= 0 then
789 -- L := Ind_Typ'Succ (L);
790 -- exit when P = Sn'Last;
791 -- P := Ind_Typ'Succ (P);
799 procedure Expand_Concatenate_Other
(Cnode
: Node_Id
; Opnds
: List_Id
) is
800 Loc
: constant Source_Ptr
:= Sloc
(Cnode
);
801 Nb_Opnds
: constant Nat
:= List_Length
(Opnds
);
803 Arr_Typ
: constant Entity_Id
:= Etype
(Entity
(Cnode
));
804 Base_Typ
: constant Entity_Id
:= Base_Type
(Etype
(Cnode
));
805 Ind_Typ
: constant Entity_Id
:= Etype
(First_Index
(Base_Typ
));
809 Param_Specs
: List_Id
;
812 Func_Decls
: List_Id
;
813 Func_Stmts
: List_Id
;
818 Elsif_List
: List_Id
;
820 Declare_Block
: Node_Id
;
821 Declare_Decls
: List_Id
;
822 Declare_Stmts
: List_Id
;
834 function Copy_Into_R_S
(I
: Nat
) return List_Id
;
835 -- Builds the sequence of statement:
839 -- L := Ind_Typ'Succ (L);
840 -- exit when P = Si'Last;
841 -- P := Ind_Typ'Succ (P);
844 -- where i is the input parameter I given.
846 function Init_L
(I
: Nat
) return Node_Id
;
847 -- Builds the statement:
848 -- L := Arr_Typ'First; If Arr_Typ is constrained
849 -- L := Si'First; otherwise (where I is the input param given)
851 function H
return Node_Id
;
852 -- Builds reference to identifier H.
854 function Ind_Val
(E
: Node_Id
) return Node_Id
;
855 -- Builds expression Ind_Typ'Val (E);
857 function L
return Node_Id
;
858 -- Builds reference to identifier L.
860 function L_Pos
return Node_Id
;
861 -- Builds expression Ind_Typ'Pos (L).
863 function L_Succ
return Node_Id
;
864 -- Builds expression Ind_Typ'Succ (L).
866 function One
return Node_Id
;
867 -- Builds integer literal one.
869 function P
return Node_Id
;
870 -- Builds reference to identifier P.
872 function P_Succ
return Node_Id
;
873 -- Builds expression Ind_Typ'Succ (P).
875 function R
return Node_Id
;
876 -- Builds reference to identifier R.
878 function S
(I
: Nat
) return Node_Id
;
879 -- Builds reference to identifier Si, where I is the value given.
881 function S_First
(I
: Nat
) return Node_Id
;
882 -- Builds expression Si'First, where I is the value given.
884 function S_Last
(I
: Nat
) return Node_Id
;
885 -- Builds expression Si'Last, where I is the value given.
887 function S_Length
(I
: Nat
) return Node_Id
;
888 -- Builds expression Si'Length, where I is the value given.
890 function S_Length_Test
(I
: Nat
) return Node_Id
;
891 -- Builds expression Si'Length /= 0, where I is the value given.
897 function Copy_Into_R_S
(I
: Nat
) return List_Id
is
898 Stmts
: List_Id
:= New_List
;
907 -- First construct the initializations
909 P_Start
:= Make_Assignment_Statement
(Loc
,
911 Expression
=> S_First
(I
));
912 Append_To
(Stmts
, P_Start
);
914 -- Then build the loop
916 R_Copy
:= Make_Assignment_Statement
(Loc
,
917 Name
=> Make_Indexed_Component
(Loc
,
919 Expressions
=> New_List
(L
)),
920 Expression
=> Make_Indexed_Component
(Loc
,
922 Expressions
=> New_List
(P
)));
924 L_Inc
:= Make_Assignment_Statement
(Loc
,
926 Expression
=> L_Succ
);
928 Exit_Stmt
:= Make_Exit_Statement
(Loc
,
929 Condition
=> Make_Op_Eq
(Loc
, P
, S_Last
(I
)));
931 P_Inc
:= Make_Assignment_Statement
(Loc
,
933 Expression
=> P_Succ
);
936 Make_Implicit_Loop_Statement
(Cnode
,
937 Statements
=> New_List
(R_Copy
, L_Inc
, Exit_Stmt
, P_Inc
));
939 Append_To
(Stmts
, Loop_Stmt
);
948 function H
return Node_Id
is
950 return Make_Identifier
(Loc
, Name_uH
);
957 function Ind_Val
(E
: Node_Id
) return Node_Id
is
960 Make_Attribute_Reference
(Loc
,
961 Prefix
=> New_Reference_To
(Ind_Typ
, Loc
),
962 Attribute_Name
=> Name_Val
,
963 Expressions
=> New_List
(E
));
970 function Init_L
(I
: Nat
) return Node_Id
is
974 if Is_Constrained
(Arr_Typ
) then
975 E
:= Make_Attribute_Reference
(Loc
,
976 Prefix
=> New_Reference_To
(Arr_Typ
, Loc
),
977 Attribute_Name
=> Name_First
);
983 return Make_Assignment_Statement
(Loc
, Name
=> L
, Expression
=> E
);
990 function L
return Node_Id
is
992 return Make_Identifier
(Loc
, Name_uL
);
999 function L_Pos
return Node_Id
is
1002 Make_Attribute_Reference
(Loc
,
1003 Prefix
=> New_Reference_To
(Ind_Typ
, Loc
),
1004 Attribute_Name
=> Name_Pos
,
1005 Expressions
=> New_List
(L
));
1012 function L_Succ
return Node_Id
is
1015 Make_Attribute_Reference
(Loc
,
1016 Prefix
=> New_Reference_To
(Ind_Typ
, Loc
),
1017 Attribute_Name
=> Name_Succ
,
1018 Expressions
=> New_List
(L
));
1025 function One
return Node_Id
is
1027 return Make_Integer_Literal
(Loc
, 1);
1034 function P
return Node_Id
is
1036 return Make_Identifier
(Loc
, Name_uP
);
1043 function P_Succ
return Node_Id
is
1046 Make_Attribute_Reference
(Loc
,
1047 Prefix
=> New_Reference_To
(Ind_Typ
, Loc
),
1048 Attribute_Name
=> Name_Succ
,
1049 Expressions
=> New_List
(P
));
1056 function R
return Node_Id
is
1058 return Make_Identifier
(Loc
, Name_uR
);
1065 function S
(I
: Nat
) return Node_Id
is
1067 return Make_Identifier
(Loc
, New_External_Name
('S', I
));
1074 function S_First
(I
: Nat
) return Node_Id
is
1076 return Make_Attribute_Reference
(Loc
,
1078 Attribute_Name
=> Name_First
);
1085 function S_Last
(I
: Nat
) return Node_Id
is
1087 return Make_Attribute_Reference
(Loc
,
1089 Attribute_Name
=> Name_Last
);
1096 function S_Length
(I
: Nat
) return Node_Id
is
1098 return Make_Attribute_Reference
(Loc
,
1100 Attribute_Name
=> Name_Length
);
1107 function S_Length_Test
(I
: Nat
) return Node_Id
is
1111 Left_Opnd
=> S_Length
(I
),
1112 Right_Opnd
=> Make_Integer_Literal
(Loc
, 0));
1115 -- Start of processing for Expand_Concatenate_Other
1118 -- Construct the parameter specs and the overall function spec
1120 Param_Specs
:= New_List
;
1121 for I
in 1 .. Nb_Opnds
loop
1124 Make_Parameter_Specification
(Loc
,
1125 Defining_Identifier
=>
1126 Make_Defining_Identifier
(Loc
, New_External_Name
('S', I
)),
1127 Parameter_Type
=> New_Reference_To
(Base_Typ
, Loc
)));
1130 Func_Id
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('C'));
1132 Make_Function_Specification
(Loc
,
1133 Defining_Unit_Name
=> Func_Id
,
1134 Parameter_Specifications
=> Param_Specs
,
1135 Subtype_Mark
=> New_Reference_To
(Base_Typ
, Loc
));
1137 -- Construct L's object declaration
1140 Make_Object_Declaration
(Loc
,
1141 Defining_Identifier
=> Make_Defining_Identifier
(Loc
, Name_uL
),
1142 Object_Definition
=> New_Reference_To
(Ind_Typ
, Loc
));
1144 Func_Decls
:= New_List
(L_Decl
);
1146 -- Construct the if-then-elsif statements
1148 Elsif_List
:= New_List
;
1149 for I
in 2 .. Nb_Opnds
- 1 loop
1150 Append_To
(Elsif_List
, Make_Elsif_Part
(Loc
,
1151 Condition
=> S_Length_Test
(I
),
1152 Then_Statements
=> New_List
(Init_L
(I
))));
1156 Make_Implicit_If_Statement
(Cnode
,
1157 Condition
=> S_Length_Test
(1),
1158 Then_Statements
=> New_List
(Init_L
(1)),
1159 Elsif_Parts
=> Elsif_List
,
1160 Else_Statements
=> New_List
(Make_Return_Statement
(Loc
,
1161 Expression
=> S
(Nb_Opnds
))));
1163 -- Construct the declaration for H
1166 Make_Object_Declaration
(Loc
,
1167 Defining_Identifier
=> Make_Defining_Identifier
(Loc
, Name_uP
),
1168 Object_Definition
=> New_Reference_To
(Ind_Typ
, Loc
));
1170 H_Init
:= Make_Op_Subtract
(Loc
, S_Length
(1), One
);
1171 for I
in 2 .. Nb_Opnds
loop
1172 H_Init
:= Make_Op_Add
(Loc
, H_Init
, S_Length
(I
));
1174 H_Init
:= Ind_Val
(Make_Op_Add
(Loc
, H_Init
, L_Pos
));
1177 Make_Object_Declaration
(Loc
,
1178 Defining_Identifier
=> Make_Defining_Identifier
(Loc
, Name_uH
),
1179 Object_Definition
=> New_Reference_To
(Ind_Typ
, Loc
),
1180 Expression
=> H_Init
);
1182 -- Construct the declaration for R
1184 R_Range
:= Make_Range
(Loc
, Low_Bound
=> L
, High_Bound
=> H
);
1186 Make_Index_Or_Discriminant_Constraint
(Loc
,
1187 Constraints
=> New_List
(R_Range
));
1190 Make_Object_Declaration
(Loc
,
1191 Defining_Identifier
=> Make_Defining_Identifier
(Loc
, Name_uR
),
1192 Object_Definition
=>
1193 Make_Subtype_Indication
(Loc
,
1194 Subtype_Mark
=> New_Reference_To
(Base_Typ
, Loc
),
1195 Constraint
=> R_Constr
));
1197 -- Construct the declarations for the declare block
1199 Declare_Decls
:= New_List
(P_Decl
, H_Decl
, R_Decl
);
1201 -- Construct list of statements for the declare block
1203 Declare_Stmts
:= New_List
;
1204 for I
in 1 .. Nb_Opnds
loop
1205 Append_To
(Declare_Stmts
,
1206 Make_Implicit_If_Statement
(Cnode
,
1207 Condition
=> S_Length_Test
(I
),
1208 Then_Statements
=> Copy_Into_R_S
(I
)));
1211 Append_To
(Declare_Stmts
, Make_Return_Statement
(Loc
, Expression
=> R
));
1213 -- Construct the declare block
1215 Declare_Block
:= Make_Block_Statement
(Loc
,
1216 Declarations
=> Declare_Decls
,
1217 Handled_Statement_Sequence
=>
1218 Make_Handled_Sequence_Of_Statements
(Loc
, Declare_Stmts
));
1220 -- Construct the list of function statements
1222 Func_Stmts
:= New_List
(If_Stmt
, Declare_Block
);
1224 -- Construct the function body
1227 Make_Subprogram_Body
(Loc
,
1228 Specification
=> Func_Spec
,
1229 Declarations
=> Func_Decls
,
1230 Handled_Statement_Sequence
=>
1231 Make_Handled_Sequence_Of_Statements
(Loc
, Func_Stmts
));
1233 -- Insert the newly generated function in the code. This is analyzed
1234 -- with all checks off, since we have completed all the checks.
1236 -- Note that this does *not* fix the array concatenation bug when the
1237 -- low bound is Integer'first sibce that bug comes from the pointer
1238 -- derefencing an unconstrained array. An there we need a constraint
1239 -- check to make sure the length of the concatenated array is ok. ???
1241 Insert_Action
(Cnode
, Func_Body
, Suppress
=> All_Checks
);
1243 -- Construct list of arguments for the function call
1246 Operand
:= First
(Opnds
);
1247 for I
in 1 .. Nb_Opnds
loop
1248 Append_To
(Params
, Relocate_Node
(Operand
));
1252 -- Insert the function call
1256 Make_Function_Call
(Loc
, New_Reference_To
(Func_Id
, Loc
), Params
));
1258 Analyze_And_Resolve
(Cnode
, Base_Typ
);
1259 Set_Is_Inlined
(Func_Id
);
1260 end Expand_Concatenate_Other
;
1262 -------------------------------
1263 -- Expand_Concatenate_String --
1264 -------------------------------
1266 procedure Expand_Concatenate_String
(Cnode
: Node_Id
; Opnds
: List_Id
) is
1267 Loc
: constant Source_Ptr
:= Sloc
(Cnode
);
1268 Opnd1
: constant Node_Id
:= First
(Opnds
);
1269 Opnd2
: constant Node_Id
:= Next
(Opnd1
);
1270 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Opnd1
));
1271 Typ2
: constant Entity_Id
:= Base_Type
(Etype
(Opnd2
));
1274 -- RE_Id value for function to be called
1277 -- In all cases, we build a call to a routine giving the list of
1278 -- arguments as the parameter list to the routine.
1280 case List_Length
(Opnds
) is
1282 if Typ1
= Standard_Character
then
1283 if Typ2
= Standard_Character
then
1284 R
:= RE_Str_Concat_CC
;
1287 pragma Assert
(Typ2
= Standard_String
);
1288 R
:= RE_Str_Concat_CS
;
1291 elsif Typ1
= Standard_String
then
1292 if Typ2
= Standard_Character
then
1293 R
:= RE_Str_Concat_SC
;
1296 pragma Assert
(Typ2
= Standard_String
);
1300 -- If we have anything other than Standard_Character or
1301 -- Standard_String, then we must have had an error earlier.
1302 -- So we just abandon the attempt at expansion.
1305 pragma Assert
(Errors_Detected
> 0);
1310 R
:= RE_Str_Concat_3
;
1313 R
:= RE_Str_Concat_4
;
1316 R
:= RE_Str_Concat_5
;
1320 raise Program_Error
;
1323 -- Now generate the appropriate call
1326 Make_Function_Call
(Sloc
(Cnode
),
1327 Name
=> New_Occurrence_Of
(RTE
(R
), Loc
),
1328 Parameter_Associations
=> Opnds
));
1330 Analyze_And_Resolve
(Cnode
, Standard_String
);
1331 end Expand_Concatenate_String
;
1333 ------------------------
1334 -- Expand_N_Allocator --
1335 ------------------------
1337 procedure Expand_N_Allocator
(N
: Node_Id
) is
1338 PtrT
: constant Entity_Id
:= Etype
(N
);
1340 Loc
: constant Source_Ptr
:= Sloc
(N
);
1345 -- RM E.2.3(22). We enforce that the expected type of an allocator
1346 -- shall not be a remote access-to-class-wide-limited-private type
1348 -- Why is this being done at expansion time, seems clearly wrong ???
1350 Validate_Remote_Access_To_Class_Wide_Type
(N
);
1352 -- Set the Storage Pool
1354 Set_Storage_Pool
(N
, Associated_Storage_Pool
(Root_Type
(PtrT
)));
1356 if Present
(Storage_Pool
(N
)) then
1357 if Is_RTE
(Storage_Pool
(N
), RE_SS_Pool
) then
1359 Set_Procedure_To_Call
(N
, RTE
(RE_SS_Allocate
));
1362 Set_Procedure_To_Call
(N
,
1363 Find_Prim_Op
(Etype
(Storage_Pool
(N
)), Name_Allocate
));
1367 -- Under certain circumstances we can replace an allocator by an
1368 -- access to statically allocated storage. The conditions, as noted
1369 -- in AARM 3.10 (10c) are as follows:
1371 -- Size and initial value is known at compile time
1372 -- Access type is access-to-constant
1374 if Is_Access_Constant
(PtrT
)
1375 and then Nkind
(Expression
(N
)) = N_Qualified_Expression
1376 and then Compile_Time_Known_Value
(Expression
(Expression
(N
)))
1377 and then Size_Known_At_Compile_Time
(Etype
(Expression
1380 -- Here we can do the optimization. For the allocator
1384 -- We insert an object declaration
1386 -- Tnn : aliased x := y;
1388 -- and replace the allocator by Tnn'Unrestricted_Access.
1389 -- Tnn is marked as requiring static allocation.
1392 Make_Defining_Identifier
(Loc
, New_Internal_Name
('T'));
1394 Desig
:= Subtype_Mark
(Expression
(N
));
1396 -- If context is constrained, use constrained subtype directly,
1397 -- so that the constant is not labelled as having a nomimally
1398 -- unconstrained subtype.
1400 if Entity
(Desig
) = Base_Type
(Designated_Type
(PtrT
)) then
1401 Desig
:= New_Occurrence_Of
(Designated_Type
(PtrT
), Loc
);
1405 Make_Object_Declaration
(Loc
,
1406 Defining_Identifier
=> Temp
,
1407 Aliased_Present
=> True,
1408 Constant_Present
=> Is_Access_Constant
(PtrT
),
1409 Object_Definition
=> Desig
,
1410 Expression
=> Expression
(Expression
(N
))));
1413 Make_Attribute_Reference
(Loc
,
1414 Prefix
=> New_Occurrence_Of
(Temp
, Loc
),
1415 Attribute_Name
=> Name_Unrestricted_Access
));
1417 Analyze_And_Resolve
(N
, PtrT
);
1419 -- We set the variable as statically allocated, since we don't
1420 -- want it going on the stack of the current procedure!
1422 Set_Is_Statically_Allocated
(Temp
);
1426 -- If the allocator is for a type which requires initialization, and
1427 -- there is no initial value (i.e. the operand is a subtype indication
1428 -- rather than a qualifed expression), then we must generate a call to
1429 -- the initialization routine. This is done using an expression actions
1432 -- [Pnnn : constant ptr_T := new (T); Init (Pnnn.all,...); Pnnn]
1434 -- Here ptr_T is the pointer type for the allocator, and T is the
1435 -- subtype of the allocator. A special case arises if the designated
1436 -- type of the access type is a task or contains tasks. In this case
1437 -- the call to Init (Temp.all ...) is replaced by code that ensures
1438 -- that the tasks get activated (see Exp_Ch9.Build_Task_Allocate_Block
1439 -- for details). In addition, if the type T is a task T, then the first
1440 -- argument to Init must be converted to the task record type.
1442 if Nkind
(Expression
(N
)) = N_Qualified_Expression
then
1444 Indic
: constant Node_Id
:= Subtype_Mark
(Expression
(N
));
1445 T
: constant Entity_Id
:= Entity
(Indic
);
1446 Exp
: constant Node_Id
:= Expression
(Expression
(N
));
1448 Aggr_In_Place
: constant Boolean := Is_Delayed_Aggregate
(Exp
);
1450 Tag_Assign
: Node_Id
;
1454 if Is_Tagged_Type
(T
) or else Controlled_Type
(T
) then
1456 -- Actions inserted before:
1457 -- Temp : constant ptr_T := new T'(Expression);
1458 -- <no CW> Temp._tag := T'tag;
1459 -- <CTRL> Adjust (Finalizable (Temp.all));
1460 -- <CTRL> Attach_To_Final_List (Finalizable (Temp.all));
1462 -- We analyze by hand the new internal allocator to avoid
1463 -- any recursion and inappropriate call to Initialize
1464 if not Aggr_In_Place
then
1465 Remove_Side_Effects
(Exp
);
1469 Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
1471 -- For a class wide allocation generate the following code:
1473 -- type Equiv_Record is record ... end record;
1474 -- implicit subtype CW is <Class_Wide_Subytpe>;
1475 -- temp : PtrT := new CW'(CW!(expr));
1477 if Is_Class_Wide_Type
(T
) then
1478 Expand_Subtype_From_Expr
(Empty
, T
, Indic
, Exp
);
1480 Set_Expression
(Expression
(N
),
1481 Unchecked_Convert_To
(Entity
(Indic
), Exp
));
1483 Analyze_And_Resolve
(Expression
(N
), Entity
(Indic
));
1486 if Aggr_In_Place
then
1488 Make_Object_Declaration
(Loc
,
1489 Defining_Identifier
=> Temp
,
1490 Object_Definition
=> New_Reference_To
(PtrT
, Loc
),
1491 Expression
=> Make_Allocator
(Loc
,
1492 New_Reference_To
(Etype
(Exp
), Loc
)));
1494 Set_No_Initialization
(Expression
(Tmp_Node
));
1495 Insert_Action
(N
, Tmp_Node
);
1496 Convert_Aggr_In_Allocator
(Tmp_Node
, Exp
);
1498 Node
:= Relocate_Node
(N
);
1499 Set_Analyzed
(Node
);
1501 Make_Object_Declaration
(Loc
,
1502 Defining_Identifier
=> Temp
,
1503 Constant_Present
=> True,
1504 Object_Definition
=> New_Reference_To
(PtrT
, Loc
),
1505 Expression
=> Node
));
1508 -- Suppress the tag assignment when Java_VM because JVM tags
1509 -- are represented implicitly in objects.
1511 if Is_Tagged_Type
(T
)
1512 and then not Is_Class_Wide_Type
(T
)
1513 and then not Java_VM
1516 Make_Assignment_Statement
(Loc
,
1518 Make_Selected_Component
(Loc
,
1519 Prefix
=> New_Reference_To
(Temp
, Loc
),
1521 New_Reference_To
(Tag_Component
(T
), Loc
)),
1524 Unchecked_Convert_To
(RTE
(RE_Tag
),
1525 New_Reference_To
(Access_Disp_Table
(T
), Loc
)));
1527 -- The previous assignment has to be done in any case
1529 Set_Assignment_OK
(Name
(Tag_Assign
));
1530 Insert_Action
(N
, Tag_Assign
);
1532 elsif Is_Private_Type
(T
)
1533 and then Is_Tagged_Type
(Underlying_Type
(T
))
1534 and then not Java_VM
1537 Utyp
: constant Entity_Id
:= Underlying_Type
(T
);
1538 Ref
: constant Node_Id
:=
1539 Unchecked_Convert_To
(Utyp
,
1540 Make_Explicit_Dereference
(Loc
,
1541 New_Reference_To
(Temp
, Loc
)));
1545 Make_Assignment_Statement
(Loc
,
1547 Make_Selected_Component
(Loc
,
1550 New_Reference_To
(Tag_Component
(Utyp
), Loc
)),
1553 Unchecked_Convert_To
(RTE
(RE_Tag
),
1555 Access_Disp_Table
(Utyp
), Loc
)));
1557 Set_Assignment_OK
(Name
(Tag_Assign
));
1558 Insert_Action
(N
, Tag_Assign
);
1562 if Controlled_Type
(Designated_Type
(PtrT
))
1563 and then Controlled_Type
(T
)
1568 Apool
: constant Entity_Id
:=
1569 Associated_Storage_Pool
(PtrT
);
1572 -- If it is an allocation on the secondary stack
1573 -- (i.e. a value returned from a function), the object
1574 -- is attached on the caller side as soon as the call
1575 -- is completed (see Expand_Ctrl_Function_Call)
1577 if Is_RTE
(Apool
, RE_SS_Pool
) then
1579 F
: constant Entity_Id
:=
1580 Make_Defining_Identifier
(Loc
,
1581 New_Internal_Name
('F'));
1584 Make_Object_Declaration
(Loc
,
1585 Defining_Identifier
=> F
,
1586 Object_Definition
=> New_Reference_To
(RTE
1587 (RE_Finalizable_Ptr
), Loc
)));
1589 Flist
:= New_Reference_To
(F
, Loc
);
1590 Attach
:= Make_Integer_Literal
(Loc
, 1);
1593 -- Normal case, not a secondary stack allocation
1596 Flist
:= Find_Final_List
(PtrT
);
1597 Attach
:= Make_Integer_Literal
(Loc
, 2);
1600 if not Aggr_In_Place
then
1605 -- An unchecked conversion is needed in the
1606 -- classwide case because the designated type
1607 -- can be an ancestor of the subtype mark of
1610 Unchecked_Convert_To
(T
,
1611 Make_Explicit_Dereference
(Loc
,
1612 New_Reference_To
(Temp
, Loc
))),
1616 With_Attach
=> Attach
));
1621 Rewrite
(N
, New_Reference_To
(Temp
, Loc
));
1622 Analyze_And_Resolve
(N
, PtrT
);
1624 elsif Aggr_In_Place
then
1626 Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
1628 Make_Object_Declaration
(Loc
,
1629 Defining_Identifier
=> Temp
,
1630 Object_Definition
=> New_Reference_To
(PtrT
, Loc
),
1631 Expression
=> Make_Allocator
(Loc
,
1632 New_Reference_To
(Etype
(Exp
), Loc
)));
1634 Set_No_Initialization
(Expression
(Tmp_Node
));
1635 Insert_Action
(N
, Tmp_Node
);
1636 Convert_Aggr_In_Allocator
(Tmp_Node
, Exp
);
1637 Rewrite
(N
, New_Reference_To
(Temp
, Loc
));
1638 Analyze_And_Resolve
(N
, PtrT
);
1640 elsif Is_Access_Type
(Designated_Type
(PtrT
))
1641 and then Nkind
(Exp
) = N_Allocator
1642 and then Nkind
(Expression
(Exp
)) /= N_Qualified_Expression
1644 -- Apply constraint to designated subtype indication.
1646 Apply_Constraint_Check
(Expression
(Exp
),
1647 Designated_Type
(Designated_Type
(PtrT
)),
1648 No_Sliding
=> True);
1650 if Nkind
(Expression
(Exp
)) = N_Raise_Constraint_Error
then
1652 -- Propagate constraint_error to enclosing allocator.
1655 (Exp
, New_Copy
(Expression
(Exp
)));
1658 -- First check against the type of the qualified expression
1660 -- NOTE: The commented call should be correct, but for
1661 -- some reason causes the compiler to bomb (sigsegv) on
1662 -- ACVC test c34007g, so for now we just perform the old
1663 -- (incorrect) test against the designated subtype with
1664 -- no sliding in the else part of the if statement below.
1667 -- Apply_Constraint_Check (Exp, T, No_Sliding => True);
1669 -- A check is also needed in cases where the designated
1670 -- subtype is constrained and differs from the subtype
1671 -- given in the qualified expression. Note that the check
1672 -- on the qualified expression does not allow sliding,
1673 -- but this check does (a relaxation from Ada 83).
1675 if Is_Constrained
(Designated_Type
(PtrT
))
1676 and then not Subtypes_Statically_Match
1677 (T
, Designated_Type
(PtrT
))
1679 Apply_Constraint_Check
1680 (Exp
, Designated_Type
(PtrT
), No_Sliding
=> False);
1682 -- The nonsliding check should really be performed
1683 -- (unconditionally) against the subtype of the
1684 -- qualified expression, but that causes a problem
1685 -- with c34007g (see above), so for now we retain this.
1688 Apply_Constraint_Check
1689 (Exp
, Designated_Type
(PtrT
), No_Sliding
=> True);
1694 -- Here if not qualified expression case.
1695 -- In this case, an initialization routine may be required
1699 T
: constant Entity_Id
:= Entity
(Expression
(N
));
1707 Temp_Decl
: Node_Id
;
1708 Temp_Type
: Entity_Id
;
1712 if No_Initialization
(N
) then
1715 -- Case of no initialization procedure present
1717 elsif not Has_Non_Null_Base_Init_Proc
(T
) then
1719 -- Case of simple initialization required
1721 if Needs_Simple_Initialization
(T
) then
1722 Rewrite
(Expression
(N
),
1723 Make_Qualified_Expression
(Loc
,
1724 Subtype_Mark
=> New_Occurrence_Of
(T
, Loc
),
1725 Expression
=> Get_Simple_Init_Val
(T
, Loc
)));
1727 Analyze_And_Resolve
(Expression
(Expression
(N
)), T
);
1728 Analyze_And_Resolve
(Expression
(N
), T
);
1729 Set_Paren_Count
(Expression
(Expression
(N
)), 1);
1730 Expand_N_Allocator
(N
);
1732 -- No initialization required
1738 -- Case of initialization procedure present, must be called
1741 Init
:= Base_Init_Proc
(T
);
1744 Make_Defining_Identifier
(Loc
, New_Internal_Name
('P'));
1746 -- Construct argument list for the initialization routine call
1747 -- The CPP constructor needs the address directly
1749 if Is_CPP_Class
(T
) then
1750 Arg1
:= New_Reference_To
(Temp
, Loc
);
1755 Make_Explicit_Dereference
(Loc
,
1756 Prefix
=> New_Reference_To
(Temp
, Loc
));
1757 Set_Assignment_OK
(Arg1
);
1760 -- The initialization procedure expects a specific type.
1761 -- if the context is access to class wide, indicate that
1762 -- the object being allocated has the right specific type.
1764 if Is_Class_Wide_Type
(Designated_Type
(PtrT
)) then
1765 Arg1
:= Unchecked_Convert_To
(T
, Arg1
);
1769 -- If designated type is a concurrent type or if it is a
1770 -- private type whose definition is a concurrent type,
1771 -- the first argument in the Init routine has to be
1772 -- unchecked conversion to the corresponding record type.
1773 -- If the designated type is a derived type, we also
1774 -- convert the argument to its root type.
1776 if Is_Concurrent_Type
(T
) then
1778 Unchecked_Convert_To
(Corresponding_Record_Type
(T
), Arg1
);
1780 elsif Is_Private_Type
(T
)
1781 and then Present
(Full_View
(T
))
1782 and then Is_Concurrent_Type
(Full_View
(T
))
1785 Unchecked_Convert_To
1786 (Corresponding_Record_Type
(Full_View
(T
)), Arg1
);
1788 elsif Etype
(First_Formal
(Init
)) /= Base_Type
(T
) then
1791 Ftyp
: constant Entity_Id
:= Etype
(First_Formal
(Init
));
1794 Arg1
:= OK_Convert_To
(Etype
(Ftyp
), Arg1
);
1795 Set_Etype
(Arg1
, Ftyp
);
1799 Args
:= New_List
(Arg1
);
1801 -- For the task case, pass the Master_Id of the access type
1802 -- as the value of the _Master parameter, and _Chain as the
1803 -- value of the _Chain parameter (_Chain will be defined as
1804 -- part of the generated code for the allocator).
1806 if Has_Task
(T
) then
1808 if No
(Master_Id
(Base_Type
(PtrT
))) then
1810 -- The designated type was an incomplete type, and
1811 -- the access type did not get expanded. Salvage
1814 Expand_N_Full_Type_Declaration
1815 (Parent
(Base_Type
(PtrT
)));
1818 -- If the context of the allocator is a declaration or
1819 -- an assignment, we can generate a meaningful image for
1820 -- it, even though subsequent assignments might remove
1821 -- the connection between task and entity. We build this
1822 -- image when the left-hand side is a simple variable,
1823 -- a simple indexed assignment or a simple selected
1826 if Nkind
(Parent
(N
)) = N_Assignment_Statement
then
1828 Nam
: constant Node_Id
:= Name
(Parent
(N
));
1831 if Is_Entity_Name
(Nam
) then
1833 Build_Task_Image_Decls
(
1836 (Entity
(Nam
), Sloc
(Nam
)), T
);
1838 elsif (Nkind
(Nam
) = N_Indexed_Component
1839 or else Nkind
(Nam
) = N_Selected_Component
)
1840 and then Is_Entity_Name
(Prefix
(Nam
))
1843 Build_Task_Image_Decls
1844 (Loc
, Nam
, Etype
(Prefix
(Nam
)));
1846 Decls
:= Build_Task_Image_Decls
(Loc
, T
, T
);
1850 elsif Nkind
(Parent
(N
)) = N_Object_Declaration
then
1852 Build_Task_Image_Decls
(
1853 Loc
, Defining_Identifier
(Parent
(N
)), T
);
1856 Decls
:= Build_Task_Image_Decls
(Loc
, T
, T
);
1861 (Master_Id
(Base_Type
(Root_Type
(PtrT
))), Loc
));
1862 Append_To
(Args
, Make_Identifier
(Loc
, Name_uChain
));
1864 Decl
:= Last
(Decls
);
1866 New_Occurrence_Of
(Defining_Identifier
(Decl
), Loc
));
1868 -- Has_Task is false, Decls not used
1874 -- Add discriminants if discriminated type
1876 if Has_Discriminants
(T
) then
1877 Discr
:= First_Elmt
(Discriminant_Constraint
(T
));
1879 while Present
(Discr
) loop
1880 Append
(New_Copy
(Elists
.Node
(Discr
)), Args
);
1884 elsif Is_Private_Type
(T
)
1885 and then Present
(Full_View
(T
))
1886 and then Has_Discriminants
(Full_View
(T
))
1889 First_Elmt
(Discriminant_Constraint
(Full_View
(T
)));
1891 while Present
(Discr
) loop
1892 Append
(New_Copy
(Elists
.Node
(Discr
)), Args
);
1897 -- We set the allocator as analyzed so that when we analyze the
1898 -- expression actions node, we do not get an unwanted recursive
1899 -- expansion of the allocator expression.
1901 Set_Analyzed
(N
, True);
1902 Node
:= Relocate_Node
(N
);
1904 -- Here is the transformation:
1906 -- output: Temp : constant ptr_T := new T;
1907 -- Init (Temp.all, ...);
1908 -- <CTRL> Attach_To_Final_List (Finalizable (Temp.all));
1909 -- <CTRL> Initialize (Finalizable (Temp.all));
1911 -- Here ptr_T is the pointer type for the allocator, and T
1912 -- is the subtype of the allocator.
1915 Make_Object_Declaration
(Loc
,
1916 Defining_Identifier
=> Temp
,
1917 Constant_Present
=> True,
1918 Object_Definition
=> New_Reference_To
(Temp_Type
, Loc
),
1919 Expression
=> Node
);
1921 Set_Assignment_OK
(Temp_Decl
);
1923 if Is_CPP_Class
(T
) then
1924 Set_Aliased_Present
(Temp_Decl
);
1927 Insert_Action
(N
, Temp_Decl
, Suppress
=> All_Checks
);
1929 -- Case of designated type is task or contains task
1930 -- Create block to activate created tasks, and insert
1931 -- declaration for Task_Image variable ahead of call.
1933 if Has_Task
(T
) then
1935 L
: List_Id
:= New_List
;
1939 Build_Task_Allocate_Block
(L
, Node
, Args
);
1942 Insert_List_Before
(First
(Declarations
(Blk
)), Decls
);
1943 Insert_Actions
(N
, L
);
1948 Make_Procedure_Call_Statement
(Loc
,
1949 Name
=> New_Reference_To
(Init
, Loc
),
1950 Parameter_Associations
=> Args
));
1953 if Controlled_Type
(T
) then
1955 -- If the context is an access parameter, we need to create
1956 -- a non-anonymous access type in order to have a usable
1957 -- final list, because there is otherwise no pool to which
1958 -- the allocated object can belong. We create both the type
1959 -- and the finalization chain here, because freezing an
1960 -- internal type does not create such a chain.
1962 if Ekind
(PtrT
) = E_Anonymous_Access_Type
then
1965 Make_Defining_Identifier
(Loc
,
1966 New_Internal_Name
('I'));
1969 Make_Full_Type_Declaration
(Loc
,
1970 Defining_Identifier
=> Acc
,
1972 Make_Access_To_Object_Definition
(Loc
,
1973 Subtype_Indication
=>
1974 New_Occurrence_Of
(T
, Loc
))));
1976 Build_Final_List
(N
, Acc
);
1977 Flist
:= Find_Final_List
(Acc
);
1981 Flist
:= Find_Final_List
(PtrT
);
1986 Ref
=> New_Copy_Tree
(Arg1
),
1989 With_Attach
=> Make_Integer_Literal
(Loc
, 2)));
1992 if Is_CPP_Class
(T
) then
1994 Make_Attribute_Reference
(Loc
,
1995 Prefix
=> New_Reference_To
(Temp
, Loc
),
1996 Attribute_Name
=> Name_Unchecked_Access
));
1998 Rewrite
(N
, New_Reference_To
(Temp
, Loc
));
2001 Analyze_And_Resolve
(N
, PtrT
);
2005 end Expand_N_Allocator
;
2007 -----------------------
2008 -- Expand_N_And_Then --
2009 -----------------------
2011 -- Expand into conditional expression if Actions present, and also
2012 -- deal with optimizing case of arguments being True or False.
2014 procedure Expand_N_And_Then
(N
: Node_Id
) is
2015 Loc
: constant Source_Ptr
:= Sloc
(N
);
2016 Typ
: constant Entity_Id
:= Etype
(N
);
2017 Left
: constant Node_Id
:= Left_Opnd
(N
);
2018 Right
: constant Node_Id
:= Right_Opnd
(N
);
2022 -- Deal with non-standard booleans
2024 if Is_Boolean_Type
(Typ
) then
2025 Adjust_Condition
(Left
);
2026 Adjust_Condition
(Right
);
2027 Set_Etype
(N
, Standard_Boolean
);
2030 -- Check for cases of left argument is True or False
2032 if Nkind
(Left
) = N_Identifier
then
2034 -- If left argument is True, change (True and then Right) to Right.
2035 -- Any actions associated with Right will be executed unconditionally
2036 -- and can thus be inserted into the tree unconditionally.
2038 if Entity
(Left
) = Standard_True
then
2039 if Present
(Actions
(N
)) then
2040 Insert_Actions
(N
, Actions
(N
));
2044 Adjust_Result_Type
(N
, Typ
);
2047 -- If left argument is False, change (False and then Right) to
2048 -- False. In this case we can forget the actions associated with
2049 -- Right, since they will never be executed.
2051 elsif Entity
(Left
) = Standard_False
then
2052 Kill_Dead_Code
(Right
);
2053 Kill_Dead_Code
(Actions
(N
));
2054 Rewrite
(N
, New_Occurrence_Of
(Standard_False
, Loc
));
2055 Adjust_Result_Type
(N
, Typ
);
2060 -- If Actions are present, we expand
2062 -- left and then right
2066 -- if left then right else false end
2068 -- with the actions becoming the Then_Actions of the conditional
2069 -- expression. This conditional expression is then further expanded
2070 -- (and will eventually disappear)
2072 if Present
(Actions
(N
)) then
2073 Actlist
:= Actions
(N
);
2075 Make_Conditional_Expression
(Loc
,
2076 Expressions
=> New_List
(
2079 New_Occurrence_Of
(Standard_False
, Loc
))));
2081 Set_Then_Actions
(N
, Actlist
);
2082 Analyze_And_Resolve
(N
, Standard_Boolean
);
2083 Adjust_Result_Type
(N
, Typ
);
2087 -- No actions present, check for cases of right argument True/False
2089 if Nkind
(Right
) = N_Identifier
then
2091 -- Change (Left and then True) to Left. Note that we know there
2092 -- are no actions associated with the True operand, since we
2093 -- just checked for this case above.
2095 if Entity
(Right
) = Standard_True
then
2098 -- Change (Left and then False) to False, making sure to preserve
2099 -- any side effects associated with the Left operand.
2101 elsif Entity
(Right
) = Standard_False
then
2102 Remove_Side_Effects
(Left
);
2104 (N
, New_Occurrence_Of
(Standard_False
, Loc
));
2108 Adjust_Result_Type
(N
, Typ
);
2109 end Expand_N_And_Then
;
2111 -------------------------------------
2112 -- Expand_N_Conditional_Expression --
2113 -------------------------------------
2115 -- Expand into expression actions if then/else actions present
2117 procedure Expand_N_Conditional_Expression
(N
: Node_Id
) is
2118 Loc
: constant Source_Ptr
:= Sloc
(N
);
2119 Cond
: constant Node_Id
:= First
(Expressions
(N
));
2120 Thenx
: constant Node_Id
:= Next
(Cond
);
2121 Elsex
: constant Node_Id
:= Next
(Thenx
);
2122 Typ
: constant Entity_Id
:= Etype
(N
);
2127 -- If either then or else actions are present, then given:
2129 -- if cond then then-expr else else-expr end
2131 -- we insert the following sequence of actions (using Insert_Actions):
2136 -- Cnn := then-expr;
2142 -- and replace the conditional expression by a reference to Cnn.
2144 if Present
(Then_Actions
(N
)) or else Present
(Else_Actions
(N
)) then
2145 Cnn
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('C'));
2148 Make_Implicit_If_Statement
(N
,
2149 Condition
=> Relocate_Node
(Cond
),
2151 Then_Statements
=> New_List
(
2152 Make_Assignment_Statement
(Sloc
(Thenx
),
2153 Name
=> New_Occurrence_Of
(Cnn
, Sloc
(Thenx
)),
2154 Expression
=> Relocate_Node
(Thenx
))),
2156 Else_Statements
=> New_List
(
2157 Make_Assignment_Statement
(Sloc
(Elsex
),
2158 Name
=> New_Occurrence_Of
(Cnn
, Sloc
(Elsex
)),
2159 Expression
=> Relocate_Node
(Elsex
))));
2161 if Present
(Then_Actions
(N
)) then
2163 (First
(Then_Statements
(New_If
)), Then_Actions
(N
));
2166 if Present
(Else_Actions
(N
)) then
2168 (First
(Else_Statements
(New_If
)), Else_Actions
(N
));
2171 Rewrite
(N
, New_Occurrence_Of
(Cnn
, Loc
));
2174 Make_Object_Declaration
(Loc
,
2175 Defining_Identifier
=> Cnn
,
2176 Object_Definition
=> New_Occurrence_Of
(Typ
, Loc
)));
2178 Insert_Action
(N
, New_If
);
2179 Analyze_And_Resolve
(N
, Typ
);
2181 end Expand_N_Conditional_Expression
;
2183 -----------------------------------
2184 -- Expand_N_Explicit_Dereference --
2185 -----------------------------------
2187 procedure Expand_N_Explicit_Dereference
(N
: Node_Id
) is
2189 -- The only processing required is an insertion of an explicit
2190 -- dereference call for the checked storage pool case.
2192 Insert_Dereference_Action
(Prefix
(N
));
2193 end Expand_N_Explicit_Dereference
;
2199 procedure Expand_N_In
(N
: Node_Id
) is
2200 Loc
: constant Source_Ptr
:= Sloc
(N
);
2201 Rtyp
: constant Entity_Id
:= Etype
(N
);
2204 -- No expansion is required if we have an explicit range
2206 if Nkind
(Right_Opnd
(N
)) = N_Range
then
2209 -- Here right operand is a subtype mark
2213 Typ
: Entity_Id
:= Etype
(Right_Opnd
(N
));
2214 Obj
: Node_Id
:= Left_Opnd
(N
);
2215 Cond
: Node_Id
:= Empty
;
2216 Is_Acc
: Boolean := Is_Access_Type
(Typ
);
2219 Remove_Side_Effects
(Obj
);
2221 -- For tagged type, do tagged membership operation
2223 if Is_Tagged_Type
(Typ
) then
2224 -- No expansion will be performed when Java_VM, as the
2225 -- JVM back end will handle the membership tests directly
2226 -- (tags are not explicitly represented in Java objects,
2227 -- so the normal tagged membership expansion is not what
2231 Rewrite
(N
, Tagged_Membership
(N
));
2232 Analyze_And_Resolve
(N
, Rtyp
);
2237 -- If type is scalar type, rewrite as x in t'first .. t'last
2238 -- This reason we do this is that the bounds may have the wrong
2239 -- type if they come from the original type definition.
2241 elsif Is_Scalar_Type
(Typ
) then
2242 Rewrite
(Right_Opnd
(N
),
2245 Make_Attribute_Reference
(Loc
,
2246 Attribute_Name
=> Name_First
,
2247 Prefix
=> New_Reference_To
(Typ
, Loc
)),
2250 Make_Attribute_Reference
(Loc
,
2251 Attribute_Name
=> Name_Last
,
2252 Prefix
=> New_Reference_To
(Typ
, Loc
))));
2253 Analyze_And_Resolve
(N
, Rtyp
);
2258 Typ
:= Designated_Type
(Typ
);
2261 if not Is_Constrained
(Typ
) then
2263 New_Reference_To
(Standard_True
, Loc
));
2264 Analyze_And_Resolve
(N
, Rtyp
);
2266 -- For the constrained array case, we have to check the
2267 -- subscripts for an exact match if the lengths are
2268 -- non-zero (the lengths must match in any case).
2270 elsif Is_Array_Type
(Typ
) then
2273 function Construct_Attribute_Reference
2278 -- Build attribute reference E'Nam(Dim)
2280 function Construct_Attribute_Reference
2288 Make_Attribute_Reference
(Loc
,
2290 Attribute_Name
=> Nam
,
2291 Expressions
=> New_List
(
2292 Make_Integer_Literal
(Loc
, Dim
)));
2293 end Construct_Attribute_Reference
;
2296 for J
in 1 .. Number_Dimensions
(Typ
) loop
2297 Evolve_And_Then
(Cond
,
2300 Construct_Attribute_Reference
2301 (Duplicate_Subexpr
(Obj
), Name_First
, J
),
2303 Construct_Attribute_Reference
2304 (New_Occurrence_Of
(Typ
, Loc
), Name_First
, J
)));
2306 Evolve_And_Then
(Cond
,
2309 Construct_Attribute_Reference
2310 (Duplicate_Subexpr
(Obj
), Name_Last
, J
),
2312 Construct_Attribute_Reference
2313 (New_Occurrence_Of
(Typ
, Loc
), Name_Last
, J
)));
2317 Cond
:= Make_Or_Else
(Loc
,
2321 Right_Opnd
=> Make_Null
(Loc
)),
2322 Right_Opnd
=> Cond
);
2326 Analyze_And_Resolve
(N
, Rtyp
);
2329 -- These are the cases where constraint checks may be
2330 -- required, e.g. records with possible discriminants
2333 -- Expand the test into a series of discriminant comparisons.
2334 -- The expression that is built is the negation of the one
2335 -- that is used for checking discriminant constraints.
2337 Obj
:= Relocate_Node
(Left_Opnd
(N
));
2339 if Has_Discriminants
(Typ
) then
2340 Cond
:= Make_Op_Not
(Loc
,
2341 Right_Opnd
=> Build_Discriminant_Checks
(Obj
, Typ
));
2344 Cond
:= Make_Or_Else
(Loc
,
2348 Right_Opnd
=> Make_Null
(Loc
)),
2349 Right_Opnd
=> Cond
);
2353 Cond
:= New_Occurrence_Of
(Standard_True
, Loc
);
2357 Analyze_And_Resolve
(N
, Rtyp
);
2363 --------------------------------
2364 -- Expand_N_Indexed_Component --
2365 --------------------------------
2367 procedure Expand_N_Indexed_Component
(N
: Node_Id
) is
2368 Loc
: constant Source_Ptr
:= Sloc
(N
);
2369 Typ
: constant Entity_Id
:= Etype
(N
);
2370 P
: constant Node_Id
:= Prefix
(N
);
2371 T
: constant Entity_Id
:= Etype
(P
);
2374 -- A special optimization, if we have an indexed component that
2375 -- is selecting from a slice, then we can eliminate the slice,
2376 -- since, for example, x (i .. j)(k) is identical to x(k). The
2377 -- only difference is the range check required by the slice. The
2378 -- range check for the slice itself has already been generated.
2379 -- The range check for the subscripting operation is ensured
2380 -- by converting the subject to the subtype of the slice.
2382 -- This optimization not only generates better code, avoiding
2383 -- slice messing especially in the packed case, but more importantly
2384 -- bypasses some problems in handling this peculiar case, for
2385 -- example, the issue of dealing specially with object renamings.
2387 if Nkind
(P
) = N_Slice
then
2389 Make_Indexed_Component
(Loc
,
2390 Prefix
=> Prefix
(P
),
2391 Expressions
=> New_List
(
2393 (Etype
(First_Index
(Etype
(P
))),
2394 First
(Expressions
(N
))))));
2395 Analyze_And_Resolve
(N
, Typ
);
2399 -- If the prefix is an access type, then we unconditionally rewrite
2400 -- if as an explicit deference. This simplifies processing for several
2401 -- cases, including packed array cases and certain cases in which
2402 -- checks must be generated. We used to try to do this only when it
2403 -- was necessary, but it cleans up the code to do it all the time.
2405 if Is_Access_Type
(T
) then
2407 Make_Explicit_Dereference
(Sloc
(N
),
2408 Prefix
=> Relocate_Node
(P
)));
2409 Analyze_And_Resolve
(P
, Designated_Type
(T
));
2412 if Validity_Checks_On
and then Validity_Check_Subscripts
then
2413 Apply_Subscript_Validity_Checks
(N
);
2416 -- All done for the non-packed case
2418 if not Is_Packed
(Etype
(Prefix
(N
))) then
2422 -- For packed arrays that are not bit-packed (i.e. the case of an array
2423 -- with one or more index types with a non-coniguous enumeration type),
2424 -- we can always use the normal packed element get circuit.
2426 if not Is_Bit_Packed_Array
(Etype
(Prefix
(N
))) then
2427 Expand_Packed_Element_Reference
(N
);
2431 -- For a reference to a component of a bit packed array, we have to
2432 -- convert it to a reference to the corresponding Packed_Array_Type.
2433 -- We only want to do this for simple references, and not for:
2435 -- Left side of assignment (or prefix of left side of assignment)
2436 -- This case is handled in Exp_Ch5.Expand_N_Assignment_Statement
2438 -- Renaming objects in renaming associations
2439 -- This case is handled when a use of the renamed variable occurs
2441 -- Actual parameters for a procedure call
2442 -- This case is handled in Exp_Ch6.Expand_Actuals
2444 -- The second expression in a 'Read attribute reference
2446 -- The prefix of an address or size attribute reference
2448 -- The following circuit detects these exceptions
2451 Child
: Node_Id
:= N
;
2452 Parnt
: Node_Id
:= Parent
(N
);
2456 if Nkind
(Parnt
) = N_Unchecked_Expression
then
2459 elsif Nkind
(Parnt
) = N_Object_Renaming_Declaration
2460 or else Nkind
(Parnt
) = N_Procedure_Call_Statement
2461 or else (Nkind
(Parnt
) = N_Parameter_Association
2463 Nkind
(Parent
(Parnt
)) = N_Procedure_Call_Statement
)
2467 elsif Nkind
(Parnt
) = N_Attribute_Reference
2468 and then (Attribute_Name
(Parnt
) = Name_Address
2470 Attribute_Name
(Parnt
) = Name_Size
)
2471 and then Prefix
(Parnt
) = Child
2475 elsif Nkind
(Parnt
) = N_Assignment_Statement
2476 and then Name
(Parnt
) = Child
2480 elsif Nkind
(Parnt
) = N_Attribute_Reference
2481 and then Attribute_Name
(Parnt
) = Name_Read
2482 and then Next
(First
(Expressions
(Parnt
))) = Child
2486 elsif (Nkind
(Parnt
) = N_Indexed_Component
2487 or else Nkind
(Parnt
) = N_Selected_Component
)
2488 and then Prefix
(Parnt
) = Child
2493 Expand_Packed_Element_Reference
(N
);
2497 -- Keep looking up tree for unchecked expression, or if we are
2498 -- the prefix of a possible assignment left side.
2501 Parnt
:= Parent
(Child
);
2505 end Expand_N_Indexed_Component
;
2507 ---------------------
2508 -- Expand_N_Not_In --
2509 ---------------------
2511 -- Replace a not in b by not (a in b) so that the expansions for (a in b)
2512 -- can be done. This avoids needing to duplicate this expansion code.
2514 procedure Expand_N_Not_In
(N
: Node_Id
) is
2515 Loc
: constant Source_Ptr
:= Sloc
(N
);
2516 Typ
: constant Entity_Id
:= Etype
(N
);
2523 Left_Opnd
=> Left_Opnd
(N
),
2524 Right_Opnd
=> Right_Opnd
(N
))));
2525 Analyze_And_Resolve
(N
, Typ
);
2526 end Expand_N_Not_In
;
2532 -- The only replacement required is for the case of a null of type
2533 -- that is an access to protected subprogram. We represent such
2534 -- access values as a record, and so we must replace the occurrence
2535 -- of null by the equivalent record (with a null address and a null
2536 -- pointer in it), so that the backend creates the proper value.
2538 procedure Expand_N_Null
(N
: Node_Id
) is
2539 Loc
: constant Source_Ptr
:= Sloc
(N
);
2540 Typ
: constant Entity_Id
:= Etype
(N
);
2544 if Ekind
(Typ
) = E_Access_Protected_Subprogram_Type
then
2546 Make_Aggregate
(Loc
,
2547 Expressions
=> New_List
(
2548 New_Occurrence_Of
(RTE
(RE_Null_Address
), Loc
),
2552 Analyze_And_Resolve
(N
, Equivalent_Type
(Typ
));
2554 -- For subsequent semantic analysis, the node must retain its
2555 -- type. Gigi in any case replaces this type by the corresponding
2556 -- record type before processing the node.
2562 ---------------------
2563 -- Expand_N_Op_Abs --
2564 ---------------------
2566 procedure Expand_N_Op_Abs
(N
: Node_Id
) is
2567 Loc
: constant Source_Ptr
:= Sloc
(N
);
2568 Expr
: constant Node_Id
:= Right_Opnd
(N
);
2571 Unary_Op_Validity_Checks
(N
);
2573 -- Deal with software overflow checking
2575 if Software_Overflow_Checking
2576 and then Is_Signed_Integer_Type
(Etype
(N
))
2577 and then Do_Overflow_Check
(N
)
2579 -- Software overflow checking expands abs (expr) into
2581 -- (if expr >= 0 then expr else -expr)
2583 -- with the usual Duplicate_Subexpr use coding for expr
2586 Make_Conditional_Expression
(Loc
,
2587 Expressions
=> New_List
(
2589 Left_Opnd
=> Duplicate_Subexpr
(Expr
),
2590 Right_Opnd
=> Make_Integer_Literal
(Loc
, 0)),
2592 Duplicate_Subexpr
(Expr
),
2595 Right_Opnd
=> Duplicate_Subexpr
(Expr
)))));
2597 Analyze_And_Resolve
(N
);
2599 -- Vax floating-point types case
2601 elsif Vax_Float
(Etype
(N
)) then
2602 Expand_Vax_Arith
(N
);
2604 end Expand_N_Op_Abs
;
2606 ---------------------
2607 -- Expand_N_Op_Add --
2608 ---------------------
2610 procedure Expand_N_Op_Add
(N
: Node_Id
) is
2611 Typ
: constant Entity_Id
:= Etype
(N
);
2614 Binary_Op_Validity_Checks
(N
);
2616 -- N + 0 = 0 + N = N for integer types
2618 if Is_Integer_Type
(Typ
) then
2619 if Compile_Time_Known_Value
(Right_Opnd
(N
))
2620 and then Expr_Value
(Right_Opnd
(N
)) = Uint_0
2622 Rewrite
(N
, Left_Opnd
(N
));
2625 elsif Compile_Time_Known_Value
(Left_Opnd
(N
))
2626 and then Expr_Value
(Left_Opnd
(N
)) = Uint_0
2628 Rewrite
(N
, Right_Opnd
(N
));
2633 -- Arithemtic overflow checks for signed integer/fixed point types
2635 if Is_Signed_Integer_Type
(Typ
)
2636 or else Is_Fixed_Point_Type
(Typ
)
2638 Apply_Arithmetic_Overflow_Check
(N
);
2641 -- Vax floating-point types case
2643 elsif Vax_Float
(Typ
) then
2644 Expand_Vax_Arith
(N
);
2646 end Expand_N_Op_Add
;
2648 ---------------------
2649 -- Expand_N_Op_And --
2650 ---------------------
2652 procedure Expand_N_Op_And
(N
: Node_Id
) is
2653 Typ
: constant Entity_Id
:= Etype
(N
);
2656 Binary_Op_Validity_Checks
(N
);
2658 if Is_Array_Type
(Etype
(N
)) then
2659 Expand_Boolean_Operator
(N
);
2661 elsif Is_Boolean_Type
(Etype
(N
)) then
2662 Adjust_Condition
(Left_Opnd
(N
));
2663 Adjust_Condition
(Right_Opnd
(N
));
2664 Set_Etype
(N
, Standard_Boolean
);
2665 Adjust_Result_Type
(N
, Typ
);
2667 end Expand_N_Op_And
;
2669 ------------------------
2670 -- Expand_N_Op_Concat --
2671 ------------------------
2673 procedure Expand_N_Op_Concat
(N
: Node_Id
) is
2676 -- List of operands to be concatenated
2679 -- Single operand for concatenation
2682 -- Node which is to be replaced by the result of concatenating
2683 -- the nodes in the list Opnds.
2686 -- Array type of concatenation result type
2689 -- Component type of concatenation represented by Cnode
2692 Binary_Op_Validity_Checks
(N
);
2694 -- If we are the left operand of a concatenation higher up the
2695 -- tree, then do nothing for now, since we want to deal with a
2696 -- series of concatenations as a unit.
2698 if Nkind
(Parent
(N
)) = N_Op_Concat
2699 and then N
= Left_Opnd
(Parent
(N
))
2704 -- We get here with a concatenation whose left operand may be a
2705 -- concatenation itself with a consistent type. We need to process
2706 -- these concatenation operands from left to right, which means
2707 -- from the deepest node in the tree to the highest node.
2710 while Nkind
(Left_Opnd
(Cnode
)) = N_Op_Concat
loop
2711 Cnode
:= Left_Opnd
(Cnode
);
2714 -- Now Opnd is the deepest Opnd, and its parents are the concatenation
2715 -- nodes above, so now we process bottom up, doing the operations. We
2716 -- gather a string that is as long as possible up to five operands
2718 -- The outer loop runs more than once if there are more than five
2719 -- concatenations of type Standard.String, the most we handle for
2720 -- this case, or if more than one concatenation type is involved.
2723 Opnds
:= New_List
(Left_Opnd
(Cnode
), Right_Opnd
(Cnode
));
2724 Set_Parent
(Opnds
, N
);
2726 -- The inner loop gathers concatenation operands
2728 Inner
: while Cnode
/= N
2729 and then (Base_Type
(Etype
(Cnode
)) /= Standard_String
2731 List_Length
(Opnds
) < 5)
2732 and then Base_Type
(Etype
(Cnode
)) =
2733 Base_Type
(Etype
(Parent
(Cnode
)))
2735 Cnode
:= Parent
(Cnode
);
2736 Append
(Right_Opnd
(Cnode
), Opnds
);
2739 -- Here we process the collected operands. First we convert
2740 -- singleton operands to singleton aggregates. This is skipped
2741 -- however for the case of two operands of type String, since
2742 -- we have special routines for these cases.
2744 Atyp
:= Base_Type
(Etype
(Cnode
));
2745 Ctyp
:= Base_Type
(Component_Type
(Etype
(Cnode
)));
2747 if List_Length
(Opnds
) > 2 or else Atyp
/= Standard_String
then
2748 Opnd
:= First
(Opnds
);
2750 if Base_Type
(Etype
(Opnd
)) = Ctyp
then
2752 Make_Aggregate
(Sloc
(Cnode
),
2753 Expressions
=> New_List
(Relocate_Node
(Opnd
))));
2754 Analyze_And_Resolve
(Opnd
, Atyp
);
2758 exit when No
(Opnd
);
2762 -- Now call appropriate continuation routine
2764 if Atyp
= Standard_String
then
2765 Expand_Concatenate_String
(Cnode
, Opnds
);
2767 Expand_Concatenate_Other
(Cnode
, Opnds
);
2770 exit Outer
when Cnode
= N
;
2771 Cnode
:= Parent
(Cnode
);
2773 end Expand_N_Op_Concat
;
2775 ------------------------
2776 -- Expand_N_Op_Divide --
2777 ------------------------
2779 procedure Expand_N_Op_Divide
(N
: Node_Id
) is
2780 Loc
: constant Source_Ptr
:= Sloc
(N
);
2781 Ltyp
: constant Entity_Id
:= Etype
(Left_Opnd
(N
));
2782 Rtyp
: constant Entity_Id
:= Etype
(Right_Opnd
(N
));
2783 Typ
: Entity_Id
:= Etype
(N
);
2786 Binary_Op_Validity_Checks
(N
);
2788 -- Vax_Float is a special case
2790 if Vax_Float
(Typ
) then
2791 Expand_Vax_Arith
(N
);
2795 -- N / 1 = N for integer types
2797 if Is_Integer_Type
(Typ
)
2798 and then Compile_Time_Known_Value
(Right_Opnd
(N
))
2799 and then Expr_Value
(Right_Opnd
(N
)) = Uint_1
2801 Rewrite
(N
, Left_Opnd
(N
));
2805 -- Convert x / 2 ** y to Shift_Right (x, y). Note that the fact that
2806 -- Is_Power_Of_2_For_Shift is set means that we know that our left
2807 -- operand is an unsigned integer, as required for this to work.
2809 if Nkind
(Right_Opnd
(N
)) = N_Op_Expon
2810 and then Is_Power_Of_2_For_Shift
(Right_Opnd
(N
))
2813 Make_Op_Shift_Right
(Loc
,
2814 Left_Opnd
=> Left_Opnd
(N
),
2816 Convert_To
(Standard_Natural
, Right_Opnd
(Right_Opnd
(N
)))));
2817 Analyze_And_Resolve
(N
, Typ
);
2821 -- Do required fixup of universal fixed operation
2823 if Typ
= Universal_Fixed
then
2824 Fixup_Universal_Fixed_Operation
(N
);
2828 -- Divisions with fixed-point results
2830 if Is_Fixed_Point_Type
(Typ
) then
2832 -- No special processing if Treat_Fixed_As_Integer is set,
2833 -- since from a semantic point of view such operations are
2834 -- simply integer operations and will be treated that way.
2836 if not Treat_Fixed_As_Integer
(N
) then
2837 if Is_Integer_Type
(Rtyp
) then
2838 Expand_Divide_Fixed_By_Integer_Giving_Fixed
(N
);
2840 Expand_Divide_Fixed_By_Fixed_Giving_Fixed
(N
);
2844 -- Other cases of division of fixed-point operands. Again we
2845 -- exclude the case where Treat_Fixed_As_Integer is set.
2847 elsif (Is_Fixed_Point_Type
(Ltyp
) or else
2848 Is_Fixed_Point_Type
(Rtyp
))
2849 and then not Treat_Fixed_As_Integer
(N
)
2851 if Is_Integer_Type
(Typ
) then
2852 Expand_Divide_Fixed_By_Fixed_Giving_Integer
(N
);
2854 pragma Assert
(Is_Floating_Point_Type
(Typ
));
2855 Expand_Divide_Fixed_By_Fixed_Giving_Float
(N
);
2858 -- Mixed-mode operations can appear in a non-static universal
2859 -- context, in which case the integer argument must be converted
2862 elsif Typ
= Universal_Real
2863 and then Is_Integer_Type
(Rtyp
)
2865 Rewrite
(Right_Opnd
(N
),
2866 Convert_To
(Universal_Real
, Relocate_Node
(Right_Opnd
(N
))));
2868 Analyze_And_Resolve
(Right_Opnd
(N
), Universal_Real
);
2870 elsif Typ
= Universal_Real
2871 and then Is_Integer_Type
(Ltyp
)
2873 Rewrite
(Left_Opnd
(N
),
2874 Convert_To
(Universal_Real
, Relocate_Node
(Left_Opnd
(N
))));
2876 Analyze_And_Resolve
(Left_Opnd
(N
), Universal_Real
);
2878 -- Non-fixed point cases, do zero divide and overflow checks
2880 elsif Is_Integer_Type
(Typ
) then
2881 Apply_Divide_Check
(N
);
2883 end Expand_N_Op_Divide
;
2885 --------------------
2886 -- Expand_N_Op_Eq --
2887 --------------------
2889 procedure Expand_N_Op_Eq
(N
: Node_Id
) is
2890 Loc
: constant Source_Ptr
:= Sloc
(N
);
2891 Typ
: constant Entity_Id
:= Etype
(N
);
2892 Lhs
: constant Node_Id
:= Left_Opnd
(N
);
2893 Rhs
: constant Node_Id
:= Right_Opnd
(N
);
2894 A_Typ
: Entity_Id
:= Etype
(Lhs
);
2895 Typl
: Entity_Id
:= A_Typ
;
2896 Op_Name
: Entity_Id
;
2898 Bodies
: List_Id
:= New_List
;
2900 procedure Build_Equality_Call
(Eq
: Entity_Id
);
2901 -- If a constructed equality exists for the type or for its parent,
2902 -- build and analyze call, adding conversions if the operation is
2905 -------------------------
2906 -- Build_Equality_Call --
2907 -------------------------
2909 procedure Build_Equality_Call
(Eq
: Entity_Id
) is
2910 Op_Type
: constant Entity_Id
:= Etype
(First_Formal
(Eq
));
2911 L_Exp
: Node_Id
:= Relocate_Node
(Lhs
);
2912 R_Exp
: Node_Id
:= Relocate_Node
(Rhs
);
2915 if Base_Type
(Op_Type
) /= Base_Type
(A_Typ
)
2916 and then not Is_Class_Wide_Type
(A_Typ
)
2918 L_Exp
:= OK_Convert_To
(Op_Type
, L_Exp
);
2919 R_Exp
:= OK_Convert_To
(Op_Type
, R_Exp
);
2923 Make_Function_Call
(Loc
,
2924 Name
=> New_Reference_To
(Eq
, Loc
),
2925 Parameter_Associations
=> New_List
(L_Exp
, R_Exp
)));
2927 Analyze_And_Resolve
(N
, Standard_Boolean
, Suppress
=> All_Checks
);
2928 end Build_Equality_Call
;
2930 -- Start of processing for Expand_N_Op_Eq
2933 Binary_Op_Validity_Checks
(N
);
2935 if Ekind
(Typl
) = E_Private_Type
then
2936 Typl
:= Underlying_Type
(Typl
);
2938 elsif Ekind
(Typl
) = E_Private_Subtype
then
2939 Typl
:= Underlying_Type
(Base_Type
(Typl
));
2942 -- It may happen in error situations that the underlying type is not
2943 -- set. The error will be detected later, here we just defend the
2950 Typl
:= Base_Type
(Typl
);
2954 if Vax_Float
(Typl
) then
2955 Expand_Vax_Comparison
(N
);
2958 -- Boolean types (requiring handling of non-standard case)
2960 elsif Is_Boolean_Type
(Typl
) then
2961 Adjust_Condition
(Left_Opnd
(N
));
2962 Adjust_Condition
(Right_Opnd
(N
));
2963 Set_Etype
(N
, Standard_Boolean
);
2964 Adjust_Result_Type
(N
, Typ
);
2968 elsif Is_Array_Type
(Typl
) then
2972 if Is_Bit_Packed_Array
(Typl
) then
2973 Expand_Packed_Eq
(N
);
2975 -- For non-floating-point elementary types, the primitive equality
2976 -- always applies, and block-bit comparison is fine. Floating-point
2977 -- is an exception because of negative zeroes.
2979 -- However, we never use block bit comparison in No_Run_Time mode,
2980 -- since this may result in a call to a run time routine
2982 elsif Is_Elementary_Type
(Component_Type
(Typl
))
2983 and then not Is_Floating_Point_Type
(Component_Type
(Typl
))
2984 and then not No_Run_Time
2988 -- For composite and floating-point cases, expand equality loop
2989 -- to make sure of using proper comparisons for tagged types,
2990 -- and correctly handling the floating-point case.
2994 Expand_Array_Equality
(N
, Typl
, A_Typ
,
2995 Relocate_Node
(Lhs
), Relocate_Node
(Rhs
), Bodies
));
2997 Insert_Actions
(N
, Bodies
, Suppress
=> All_Checks
);
2998 Analyze_And_Resolve
(N
, Standard_Boolean
, Suppress
=> All_Checks
);
3003 elsif Is_Record_Type
(Typl
) then
3005 -- For tagged types, use the primitive "="
3007 if Is_Tagged_Type
(Typl
) then
3009 -- If this is derived from an untagged private type completed
3010 -- with a tagged type, it does not have a full view, so we
3011 -- use the primitive operations of the private type.
3012 -- This check should no longer be necessary when these
3013 -- types receive their full views ???
3015 if Is_Private_Type
(A_Typ
)
3016 and then not Is_Tagged_Type
(A_Typ
)
3017 and then Is_Derived_Type
(A_Typ
)
3018 and then No
(Full_View
(A_Typ
))
3020 Prim
:= First_Elmt
(Collect_Primitive_Operations
(A_Typ
));
3022 while Chars
(Node
(Prim
)) /= Name_Op_Eq
loop
3024 pragma Assert
(Present
(Prim
));
3027 Op_Name
:= Node
(Prim
);
3029 Op_Name
:= Find_Prim_Op
(Typl
, Name_Op_Eq
);
3032 Build_Equality_Call
(Op_Name
);
3034 -- If a type support function is present (for complex cases), use it
3036 elsif Present
(TSS
(Root_Type
(Typl
), Name_uEquality
)) then
3037 Build_Equality_Call
(TSS
(Root_Type
(Typl
), Name_uEquality
));
3039 -- Otherwise expand the component by component equality. Note that
3040 -- we never use block-bit coparisons for records, because of the
3041 -- problems with gaps. The backend will often be able to recombine
3042 -- the separate comparisons that we generate here.
3045 Remove_Side_Effects
(Lhs
);
3046 Remove_Side_Effects
(Rhs
);
3048 Expand_Record_Equality
(N
, Typl
, Lhs
, Rhs
, Bodies
));
3050 Insert_Actions
(N
, Bodies
, Suppress
=> All_Checks
);
3051 Analyze_And_Resolve
(N
, Standard_Boolean
, Suppress
=> All_Checks
);
3055 -- If we still have an equality comparison (i.e. it was not rewritten
3056 -- in some way), then we can test if result is needed at compile time).
3058 if Nkind
(N
) = N_Op_Eq
then
3059 Rewrite_Comparison
(N
);
3063 -----------------------
3064 -- Expand_N_Op_Expon --
3065 -----------------------
3067 procedure Expand_N_Op_Expon
(N
: Node_Id
) is
3068 Loc
: constant Source_Ptr
:= Sloc
(N
);
3069 Typ
: constant Entity_Id
:= Etype
(N
);
3070 Rtyp
: constant Entity_Id
:= Root_Type
(Typ
);
3071 Base
: constant Node_Id
:= Relocate_Node
(Left_Opnd
(N
));
3072 Exp
: constant Node_Id
:= Relocate_Node
(Right_Opnd
(N
));
3073 Exptyp
: constant Entity_Id
:= Etype
(Exp
);
3074 Ovflo
: constant Boolean := Do_Overflow_Check
(N
);
3082 Binary_Op_Validity_Checks
(N
);
3084 -- At this point the exponentiation must be dynamic since the static
3085 -- case has already been folded after Resolve by Eval_Op_Expon.
3087 -- Test for case of literal right argument
3089 if Compile_Time_Known_Value
(Exp
) then
3090 Expv
:= Expr_Value
(Exp
);
3092 -- We only fold small non-negative exponents. You might think we
3093 -- could fold small negative exponents for the real case, but we
3094 -- can't because we are required to raise Constraint_Error for
3095 -- the case of 0.0 ** (negative) even if Machine_Overflows = False.
3096 -- See ACVC test C4A012B.
3098 if Expv
>= 0 and then Expv
<= 4 then
3100 -- X ** 0 = 1 (or 1.0)
3103 if Ekind
(Typ
) in Integer_Kind
then
3104 Xnode
:= Make_Integer_Literal
(Loc
, Intval
=> 1);
3106 Xnode
:= Make_Real_Literal
(Loc
, Ureal_1
);
3118 Make_Op_Multiply
(Loc
,
3119 Left_Opnd
=> Duplicate_Subexpr
(Base
),
3120 Right_Opnd
=> Duplicate_Subexpr
(Base
));
3122 -- X ** 3 = X * X * X
3126 Make_Op_Multiply
(Loc
,
3128 Make_Op_Multiply
(Loc
,
3129 Left_Opnd
=> Duplicate_Subexpr
(Base
),
3130 Right_Opnd
=> Duplicate_Subexpr
(Base
)),
3131 Right_Opnd
=> Duplicate_Subexpr
(Base
));
3134 -- En : constant base'type := base * base;
3140 Make_Defining_Identifier
(Loc
, New_Internal_Name
('E'));
3142 Insert_Actions
(N
, New_List
(
3143 Make_Object_Declaration
(Loc
,
3144 Defining_Identifier
=> Temp
,
3145 Constant_Present
=> True,
3146 Object_Definition
=> New_Reference_To
(Typ
, Loc
),
3148 Make_Op_Multiply
(Loc
,
3149 Left_Opnd
=> Duplicate_Subexpr
(Base
),
3150 Right_Opnd
=> Duplicate_Subexpr
(Base
)))));
3153 Make_Op_Multiply
(Loc
,
3154 Left_Opnd
=> New_Reference_To
(Temp
, Loc
),
3155 Right_Opnd
=> New_Reference_To
(Temp
, Loc
));
3159 Analyze_And_Resolve
(N
, Typ
);
3164 -- Case of (2 ** expression) appearing as an argument of an integer
3165 -- multiplication, or as the right argument of a division of a non-
3166 -- negative integer. In such cases we lave the node untouched, setting
3167 -- the flag Is_Natural_Power_Of_2_for_Shift set, then the expansion
3168 -- of the higher level node converts it into a shift.
3170 if Nkind
(Base
) = N_Integer_Literal
3171 and then Intval
(Base
) = 2
3172 and then Is_Integer_Type
(Root_Type
(Exptyp
))
3173 and then Esize
(Root_Type
(Exptyp
)) <= Esize
(Standard_Integer
)
3174 and then Is_Unsigned_Type
(Exptyp
)
3176 and then Nkind
(Parent
(N
)) in N_Binary_Op
3179 P
: constant Node_Id
:= Parent
(N
);
3180 L
: constant Node_Id
:= Left_Opnd
(P
);
3181 R
: constant Node_Id
:= Right_Opnd
(P
);
3184 if (Nkind
(P
) = N_Op_Multiply
3186 ((Is_Integer_Type
(Etype
(L
)) and then R
= N
)
3188 (Is_Integer_Type
(Etype
(R
)) and then L
= N
))
3189 and then not Do_Overflow_Check
(P
))
3192 (Nkind
(P
) = N_Op_Divide
3193 and then Is_Integer_Type
(Etype
(L
))
3194 and then Is_Unsigned_Type
(Etype
(L
))
3196 and then not Do_Overflow_Check
(P
))
3198 Set_Is_Power_Of_2_For_Shift
(N
);
3204 -- Fall through if exponentiation must be done using a runtime routine.
3206 -- First deal with modular case.
3208 if Is_Modular_Integer_Type
(Rtyp
) then
3210 -- Non-binary case, we call the special exponentiation routine for
3211 -- the non-binary case, converting the argument to Long_Long_Integer
3212 -- and passing the modulus value. Then the result is converted back
3213 -- to the base type.
3215 if Non_Binary_Modulus
(Rtyp
) then
3219 Make_Function_Call
(Loc
,
3220 Name
=> New_Reference_To
(RTE
(RE_Exp_Modular
), Loc
),
3221 Parameter_Associations
=> New_List
(
3222 Convert_To
(Standard_Integer
, Base
),
3223 Make_Integer_Literal
(Loc
, Modulus
(Rtyp
)),
3226 -- Binary case, in this case, we call one of two routines, either
3227 -- the unsigned integer case, or the unsigned long long integer
3228 -- case, with a final "and" operation to do the required mod.
3231 if UI_To_Int
(Esize
(Rtyp
)) <= Standard_Integer_Size
then
3232 Ent
:= RTE
(RE_Exp_Unsigned
);
3234 Ent
:= RTE
(RE_Exp_Long_Long_Unsigned
);
3241 Make_Function_Call
(Loc
,
3242 Name
=> New_Reference_To
(Ent
, Loc
),
3243 Parameter_Associations
=> New_List
(
3244 Convert_To
(Etype
(First_Formal
(Ent
)), Base
),
3247 Make_Integer_Literal
(Loc
, Modulus
(Rtyp
) - 1))));
3251 -- Common exit point for modular type case
3253 Analyze_And_Resolve
(N
, Typ
);
3256 -- Signed integer cases
3258 elsif Rtyp
= Base_Type
(Standard_Integer
) then
3260 Rent
:= RE_Exp_Integer
;
3262 Rent
:= RE_Exn_Integer
;
3265 elsif Rtyp
= Base_Type
(Standard_Short_Integer
) then
3267 Rent
:= RE_Exp_Short_Integer
;
3269 Rent
:= RE_Exn_Short_Integer
;
3272 elsif Rtyp
= Base_Type
(Standard_Short_Short_Integer
) then
3274 Rent
:= RE_Exp_Short_Short_Integer
;
3276 Rent
:= RE_Exn_Short_Short_Integer
;
3279 elsif Rtyp
= Base_Type
(Standard_Long_Integer
) then
3281 Rent
:= RE_Exp_Long_Integer
;
3283 Rent
:= RE_Exn_Long_Integer
;
3286 elsif (Rtyp
= Base_Type
(Standard_Long_Long_Integer
)
3287 or else Rtyp
= Universal_Integer
)
3290 Rent
:= RE_Exp_Long_Long_Integer
;
3292 Rent
:= RE_Exn_Long_Long_Integer
;
3295 -- Floating-point cases
3297 elsif Rtyp
= Standard_Float
then
3299 Rent
:= RE_Exp_Float
;
3301 Rent
:= RE_Exn_Float
;
3304 elsif Rtyp
= Standard_Short_Float
then
3306 Rent
:= RE_Exp_Short_Float
;
3308 Rent
:= RE_Exn_Short_Float
;
3311 elsif Rtyp
= Standard_Long_Float
then
3313 Rent
:= RE_Exp_Long_Float
;
3315 Rent
:= RE_Exn_Long_Float
;
3320 (Rtyp
= Standard_Long_Long_Float
or else Rtyp
= Universal_Real
);
3323 Rent
:= RE_Exp_Long_Long_Float
;
3325 Rent
:= RE_Exn_Long_Long_Float
;
3329 -- Common processing for integer cases and floating-point cases.
3330 -- If we are in the base type, we can call runtime routine directly
3333 and then Rtyp
/= Universal_Integer
3334 and then Rtyp
/= Universal_Real
3337 Make_Function_Call
(Loc
,
3338 Name
=> New_Reference_To
(RTE
(Rent
), Loc
),
3339 Parameter_Associations
=> New_List
(Base
, Exp
)));
3341 -- Otherwise we have to introduce conversions (conversions are also
3342 -- required in the universal cases, since the runtime routine was
3343 -- typed using the largest integer or real case.
3348 Make_Function_Call
(Loc
,
3349 Name
=> New_Reference_To
(RTE
(Rent
), Loc
),
3350 Parameter_Associations
=> New_List
(
3351 Convert_To
(Rtyp
, Base
),
3355 Analyze_And_Resolve
(N
, Typ
);
3358 end Expand_N_Op_Expon
;
3360 --------------------
3361 -- Expand_N_Op_Ge --
3362 --------------------
3364 procedure Expand_N_Op_Ge
(N
: Node_Id
) is
3365 Typ
: constant Entity_Id
:= Etype
(N
);
3366 Op1
: constant Node_Id
:= Left_Opnd
(N
);
3367 Op2
: constant Node_Id
:= Right_Opnd
(N
);
3368 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
3371 Binary_Op_Validity_Checks
(N
);
3373 if Vax_Float
(Typ1
) then
3374 Expand_Vax_Comparison
(N
);
3377 elsif Is_Array_Type
(Typ1
) then
3378 Expand_Array_Comparison
(N
);
3382 if Is_Boolean_Type
(Typ1
) then
3383 Adjust_Condition
(Op1
);
3384 Adjust_Condition
(Op2
);
3385 Set_Etype
(N
, Standard_Boolean
);
3386 Adjust_Result_Type
(N
, Typ
);
3389 Rewrite_Comparison
(N
);
3392 --------------------
3393 -- Expand_N_Op_Gt --
3394 --------------------
3396 procedure Expand_N_Op_Gt
(N
: Node_Id
) is
3397 Typ
: constant Entity_Id
:= Etype
(N
);
3398 Op1
: constant Node_Id
:= Left_Opnd
(N
);
3399 Op2
: constant Node_Id
:= Right_Opnd
(N
);
3400 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
3403 Binary_Op_Validity_Checks
(N
);
3405 if Vax_Float
(Typ1
) then
3406 Expand_Vax_Comparison
(N
);
3409 elsif Is_Array_Type
(Typ1
) then
3410 Expand_Array_Comparison
(N
);
3414 if Is_Boolean_Type
(Typ1
) then
3415 Adjust_Condition
(Op1
);
3416 Adjust_Condition
(Op2
);
3417 Set_Etype
(N
, Standard_Boolean
);
3418 Adjust_Result_Type
(N
, Typ
);
3421 Rewrite_Comparison
(N
);
3424 --------------------
3425 -- Expand_N_Op_Le --
3426 --------------------
3428 procedure Expand_N_Op_Le
(N
: Node_Id
) is
3429 Typ
: constant Entity_Id
:= Etype
(N
);
3430 Op1
: constant Node_Id
:= Left_Opnd
(N
);
3431 Op2
: constant Node_Id
:= Right_Opnd
(N
);
3432 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
3435 Binary_Op_Validity_Checks
(N
);
3437 if Vax_Float
(Typ1
) then
3438 Expand_Vax_Comparison
(N
);
3441 elsif Is_Array_Type
(Typ1
) then
3442 Expand_Array_Comparison
(N
);
3446 if Is_Boolean_Type
(Typ1
) then
3447 Adjust_Condition
(Op1
);
3448 Adjust_Condition
(Op2
);
3449 Set_Etype
(N
, Standard_Boolean
);
3450 Adjust_Result_Type
(N
, Typ
);
3453 Rewrite_Comparison
(N
);
3456 --------------------
3457 -- Expand_N_Op_Lt --
3458 --------------------
3460 procedure Expand_N_Op_Lt
(N
: Node_Id
) is
3461 Typ
: constant Entity_Id
:= Etype
(N
);
3462 Op1
: constant Node_Id
:= Left_Opnd
(N
);
3463 Op2
: constant Node_Id
:= Right_Opnd
(N
);
3464 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
3467 Binary_Op_Validity_Checks
(N
);
3469 if Vax_Float
(Typ1
) then
3470 Expand_Vax_Comparison
(N
);
3473 elsif Is_Array_Type
(Typ1
) then
3474 Expand_Array_Comparison
(N
);
3478 if Is_Boolean_Type
(Typ1
) then
3479 Adjust_Condition
(Op1
);
3480 Adjust_Condition
(Op2
);
3481 Set_Etype
(N
, Standard_Boolean
);
3482 Adjust_Result_Type
(N
, Typ
);
3485 Rewrite_Comparison
(N
);
3488 -----------------------
3489 -- Expand_N_Op_Minus --
3490 -----------------------
3492 procedure Expand_N_Op_Minus
(N
: Node_Id
) is
3493 Loc
: constant Source_Ptr
:= Sloc
(N
);
3494 Typ
: constant Entity_Id
:= Etype
(N
);
3497 Unary_Op_Validity_Checks
(N
);
3499 if Software_Overflow_Checking
3500 and then Is_Signed_Integer_Type
(Etype
(N
))
3501 and then Do_Overflow_Check
(N
)
3503 -- Software overflow checking expands -expr into (0 - expr)
3506 Make_Op_Subtract
(Loc
,
3507 Left_Opnd
=> Make_Integer_Literal
(Loc
, 0),
3508 Right_Opnd
=> Right_Opnd
(N
)));
3510 Analyze_And_Resolve
(N
, Typ
);
3512 -- Vax floating-point types case
3514 elsif Vax_Float
(Etype
(N
)) then
3515 Expand_Vax_Arith
(N
);
3517 end Expand_N_Op_Minus
;
3519 ---------------------
3520 -- Expand_N_Op_Mod --
3521 ---------------------
3523 procedure Expand_N_Op_Mod
(N
: Node_Id
) is
3524 Loc
: constant Source_Ptr
:= Sloc
(N
);
3525 T
: constant Entity_Id
:= Etype
(N
);
3526 Left
: constant Node_Id
:= Left_Opnd
(N
);
3527 Right
: constant Node_Id
:= Right_Opnd
(N
);
3528 DOC
: constant Boolean := Do_Overflow_Check
(N
);
3529 DDC
: constant Boolean := Do_Division_Check
(N
);
3540 Binary_Op_Validity_Checks
(N
);
3542 Determine_Range
(Right
, ROK
, Rlo
, Rhi
);
3543 Determine_Range
(Left
, LOK
, Llo
, Lhi
);
3545 -- Convert mod to rem if operands are known non-negative. We do this
3546 -- since it is quite likely that this will improve the quality of code,
3547 -- (the operation now corresponds to the hardware remainder), and it
3548 -- does not seem likely that it could be harmful.
3550 if LOK
and then Llo
>= 0
3552 ROK
and then Rlo
>= 0
3555 Make_Op_Rem
(Sloc
(N
),
3556 Left_Opnd
=> Left_Opnd
(N
),
3557 Right_Opnd
=> Right_Opnd
(N
)));
3559 -- Instead of reanalyzing the node we do the analysis manually.
3560 -- This avoids anomalies when the replacement is done in an
3561 -- instance and is epsilon more efficient.
3563 Set_Entity
(N
, Standard_Entity
(S_Op_Rem
));
3565 Set_Do_Overflow_Check
(N
, DOC
);
3566 Set_Do_Division_Check
(N
, DDC
);
3567 Expand_N_Op_Rem
(N
);
3570 -- Otherwise, normal mod processing
3573 if Is_Integer_Type
(Etype
(N
)) then
3574 Apply_Divide_Check
(N
);
3577 -- Deal with annoying case of largest negative number remainder
3578 -- minus one. Gigi does not handle this case correctly, because
3579 -- it generates a divide instruction which may trap in this case.
3581 -- In fact the check is quite easy, if the right operand is -1,
3582 -- then the mod value is always 0, and we can just ignore the
3583 -- left operand completely in this case.
3585 LLB
:= Expr_Value
(Type_Low_Bound
(Base_Type
(Etype
(Left
))));
3587 if ((not ROK
) or else (Rlo
<= (-1) and then (-1) <= Rhi
))
3589 ((not LOK
) or else (Llo
= LLB
))
3592 Make_Conditional_Expression
(Loc
,
3593 Expressions
=> New_List
(
3595 Left_Opnd
=> Duplicate_Subexpr
(Right
),
3597 Make_Integer_Literal
(Loc
, -1)),
3598 Make_Integer_Literal
(Loc
, Uint_0
),
3599 Relocate_Node
(N
))));
3601 Set_Analyzed
(Next
(Next
(First
(Expressions
(N
)))));
3602 Analyze_And_Resolve
(N
, T
);
3605 end Expand_N_Op_Mod
;
3607 --------------------------
3608 -- Expand_N_Op_Multiply --
3609 --------------------------
3611 procedure Expand_N_Op_Multiply
(N
: Node_Id
) is
3612 Loc
: constant Source_Ptr
:= Sloc
(N
);
3613 Lop
: constant Node_Id
:= Left_Opnd
(N
);
3614 Rop
: constant Node_Id
:= Right_Opnd
(N
);
3615 Ltyp
: constant Entity_Id
:= Etype
(Lop
);
3616 Rtyp
: constant Entity_Id
:= Etype
(Rop
);
3617 Typ
: Entity_Id
:= Etype
(N
);
3620 Binary_Op_Validity_Checks
(N
);
3622 -- Special optimizations for integer types
3624 if Is_Integer_Type
(Typ
) then
3626 -- N * 0 = 0 * N = 0 for integer types
3628 if (Compile_Time_Known_Value
(Right_Opnd
(N
))
3629 and then Expr_Value
(Right_Opnd
(N
)) = Uint_0
)
3631 (Compile_Time_Known_Value
(Left_Opnd
(N
))
3632 and then Expr_Value
(Left_Opnd
(N
)) = Uint_0
)
3634 Rewrite
(N
, Make_Integer_Literal
(Loc
, Uint_0
));
3635 Analyze_And_Resolve
(N
, Typ
);
3639 -- N * 1 = 1 * N = N for integer types
3641 if Compile_Time_Known_Value
(Right_Opnd
(N
))
3642 and then Expr_Value
(Right_Opnd
(N
)) = Uint_1
3644 Rewrite
(N
, Left_Opnd
(N
));
3647 elsif Compile_Time_Known_Value
(Left_Opnd
(N
))
3648 and then Expr_Value
(Left_Opnd
(N
)) = Uint_1
3650 Rewrite
(N
, Right_Opnd
(N
));
3655 -- Deal with VAX float case
3657 if Vax_Float
(Typ
) then
3658 Expand_Vax_Arith
(N
);
3662 -- Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that
3663 -- Is_Power_Of_2_For_Shift is set means that we know that our left
3664 -- operand is an integer, as required for this to work.
3666 if Nkind
(Rop
) = N_Op_Expon
3667 and then Is_Power_Of_2_For_Shift
(Rop
)
3669 if Nkind
(Lop
) = N_Op_Expon
3670 and then Is_Power_Of_2_For_Shift
(Lop
)
3673 -- convert 2 ** A * 2 ** B into 2 ** (A + B)
3677 Left_Opnd
=> Make_Integer_Literal
(Loc
, 2),
3680 Left_Opnd
=> Right_Opnd
(Lop
),
3681 Right_Opnd
=> Right_Opnd
(Rop
))));
3682 Analyze_And_Resolve
(N
, Typ
);
3687 Make_Op_Shift_Left
(Loc
,
3690 Convert_To
(Standard_Natural
, Right_Opnd
(Rop
))));
3691 Analyze_And_Resolve
(N
, Typ
);
3695 -- Same processing for the operands the other way round
3697 elsif Nkind
(Lop
) = N_Op_Expon
3698 and then Is_Power_Of_2_For_Shift
(Lop
)
3701 Make_Op_Shift_Left
(Loc
,
3704 Convert_To
(Standard_Natural
, Right_Opnd
(Lop
))));
3705 Analyze_And_Resolve
(N
, Typ
);
3709 -- Do required fixup of universal fixed operation
3711 if Typ
= Universal_Fixed
then
3712 Fixup_Universal_Fixed_Operation
(N
);
3716 -- Multiplications with fixed-point results
3718 if Is_Fixed_Point_Type
(Typ
) then
3720 -- No special processing if Treat_Fixed_As_Integer is set,
3721 -- since from a semantic point of view such operations are
3722 -- simply integer operations and will be treated that way.
3724 if not Treat_Fixed_As_Integer
(N
) then
3726 -- Case of fixed * integer => fixed
3728 if Is_Integer_Type
(Rtyp
) then
3729 Expand_Multiply_Fixed_By_Integer_Giving_Fixed
(N
);
3731 -- Case of integer * fixed => fixed
3733 elsif Is_Integer_Type
(Ltyp
) then
3734 Expand_Multiply_Integer_By_Fixed_Giving_Fixed
(N
);
3736 -- Case of fixed * fixed => fixed
3739 Expand_Multiply_Fixed_By_Fixed_Giving_Fixed
(N
);
3743 -- Other cases of multiplication of fixed-point operands. Again
3744 -- we exclude the cases where Treat_Fixed_As_Integer flag is set.
3746 elsif (Is_Fixed_Point_Type
(Ltyp
) or else Is_Fixed_Point_Type
(Rtyp
))
3747 and then not Treat_Fixed_As_Integer
(N
)
3749 if Is_Integer_Type
(Typ
) then
3750 Expand_Multiply_Fixed_By_Fixed_Giving_Integer
(N
);
3752 pragma Assert
(Is_Floating_Point_Type
(Typ
));
3753 Expand_Multiply_Fixed_By_Fixed_Giving_Float
(N
);
3756 -- Mixed-mode operations can appear in a non-static universal
3757 -- context, in which case the integer argument must be converted
3760 elsif Typ
= Universal_Real
3761 and then Is_Integer_Type
(Rtyp
)
3763 Rewrite
(Rop
, Convert_To
(Universal_Real
, Relocate_Node
(Rop
)));
3765 Analyze_And_Resolve
(Rop
, Universal_Real
);
3767 elsif Typ
= Universal_Real
3768 and then Is_Integer_Type
(Ltyp
)
3770 Rewrite
(Lop
, Convert_To
(Universal_Real
, Relocate_Node
(Lop
)));
3772 Analyze_And_Resolve
(Lop
, Universal_Real
);
3774 -- Non-fixed point cases, check software overflow checking required
3776 elsif Is_Signed_Integer_Type
(Etype
(N
)) then
3777 Apply_Arithmetic_Overflow_Check
(N
);
3779 end Expand_N_Op_Multiply
;
3781 --------------------
3782 -- Expand_N_Op_Ne --
3783 --------------------
3785 -- Rewrite node as the negation of an equality operation, and reanalyze.
3786 -- The equality to be used is defined in the same scope and has the same
3787 -- signature. It must be set explicitly because in an instance it may not
3788 -- have the same visibility as in the generic unit.
3790 procedure Expand_N_Op_Ne
(N
: Node_Id
) is
3791 Loc
: constant Source_Ptr
:= Sloc
(N
);
3793 Ne
: constant Entity_Id
:= Entity
(N
);
3796 Binary_Op_Validity_Checks
(N
);
3802 Left_Opnd
=> Left_Opnd
(N
),
3803 Right_Opnd
=> Right_Opnd
(N
)));
3804 Set_Paren_Count
(Right_Opnd
(Neg
), 1);
3806 if Scope
(Ne
) /= Standard_Standard
then
3807 Set_Entity
(Right_Opnd
(Neg
), Corresponding_Equality
(Ne
));
3811 Analyze_And_Resolve
(N
, Standard_Boolean
);
3814 ---------------------
3815 -- Expand_N_Op_Not --
3816 ---------------------
3818 -- If the argument is other than a Boolean array type, there is no
3819 -- special expansion required.
3821 -- For the packed case, we call the special routine in Exp_Pakd, except
3822 -- that if the component size is greater than one, we use the standard
3823 -- routine generating a gruesome loop (it is so peculiar to have packed
3824 -- arrays with non-standard Boolean representations anyway, so it does
3825 -- not matter that we do not handle this case efficiently).
3827 -- For the unpacked case (and for the special packed case where we have
3828 -- non standard Booleans, as discussed above), we generate and insert
3829 -- into the tree the following function definition:
3831 -- function Nnnn (A : arr) is
3834 -- for J in a'range loop
3835 -- B (J) := not A (J);
3840 -- Here arr is the actual subtype of the parameter (and hence always
3841 -- constrained). Then we replace the not with a call to this function.
3843 procedure Expand_N_Op_Not
(N
: Node_Id
) is
3844 Loc
: constant Source_Ptr
:= Sloc
(N
);
3845 Typ
: constant Entity_Id
:= Etype
(N
);
3854 Func_Name
: Entity_Id
;
3855 Loop_Statement
: Node_Id
;
3858 Unary_Op_Validity_Checks
(N
);
3860 -- For boolean operand, deal with non-standard booleans
3862 if Is_Boolean_Type
(Typ
) then
3863 Adjust_Condition
(Right_Opnd
(N
));
3864 Set_Etype
(N
, Standard_Boolean
);
3865 Adjust_Result_Type
(N
, Typ
);
3869 -- Only array types need any other processing
3871 if not Is_Array_Type
(Typ
) then
3875 -- Case of array operand. If bit packed, handle it in Exp_Pakd
3877 if Is_Bit_Packed_Array
(Typ
) and then Component_Size
(Typ
) = 1 then
3878 Expand_Packed_Not
(N
);
3882 -- Case of array operand which is not bit-packed
3884 Opnd
:= Relocate_Node
(Right_Opnd
(N
));
3885 Convert_To_Actual_Subtype
(Opnd
);
3886 Arr
:= Etype
(Opnd
);
3887 Ensure_Defined
(Arr
, N
);
3889 A
:= Make_Defining_Identifier
(Loc
, Name_uA
);
3890 B
:= Make_Defining_Identifier
(Loc
, Name_uB
);
3891 J
:= Make_Defining_Identifier
(Loc
, Name_uJ
);
3894 Make_Indexed_Component
(Loc
,
3895 Prefix
=> New_Reference_To
(A
, Loc
),
3896 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
3899 Make_Indexed_Component
(Loc
,
3900 Prefix
=> New_Reference_To
(B
, Loc
),
3901 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
3904 Make_Implicit_Loop_Statement
(N
,
3905 Identifier
=> Empty
,
3908 Make_Iteration_Scheme
(Loc
,
3909 Loop_Parameter_Specification
=>
3910 Make_Loop_Parameter_Specification
(Loc
,
3911 Defining_Identifier
=> J
,
3912 Discrete_Subtype_Definition
=>
3913 Make_Attribute_Reference
(Loc
,
3914 Prefix
=> Make_Identifier
(Loc
, Chars
(A
)),
3915 Attribute_Name
=> Name_Range
))),
3917 Statements
=> New_List
(
3918 Make_Assignment_Statement
(Loc
,
3920 Expression
=> Make_Op_Not
(Loc
, A_J
))));
3922 Func_Name
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('N'));
3923 Set_Is_Inlined
(Func_Name
);
3926 Make_Subprogram_Body
(Loc
,
3928 Make_Function_Specification
(Loc
,
3929 Defining_Unit_Name
=> Func_Name
,
3930 Parameter_Specifications
=> New_List
(
3931 Make_Parameter_Specification
(Loc
,
3932 Defining_Identifier
=> A
,
3933 Parameter_Type
=> New_Reference_To
(Typ
, Loc
))),
3934 Subtype_Mark
=> New_Reference_To
(Typ
, Loc
)),
3936 Declarations
=> New_List
(
3937 Make_Object_Declaration
(Loc
,
3938 Defining_Identifier
=> B
,
3939 Object_Definition
=> New_Reference_To
(Arr
, Loc
))),
3941 Handled_Statement_Sequence
=>
3942 Make_Handled_Sequence_Of_Statements
(Loc
,
3943 Statements
=> New_List
(
3945 Make_Return_Statement
(Loc
,
3947 Make_Identifier
(Loc
, Chars
(B
)))))));
3950 Make_Function_Call
(Loc
,
3951 Name
=> New_Reference_To
(Func_Name
, Loc
),
3952 Parameter_Associations
=> New_List
(Opnd
)));
3954 Analyze_And_Resolve
(N
, Typ
);
3955 end Expand_N_Op_Not
;
3957 --------------------
3958 -- Expand_N_Op_Or --
3959 --------------------
3961 procedure Expand_N_Op_Or
(N
: Node_Id
) is
3962 Typ
: constant Entity_Id
:= Etype
(N
);
3965 Binary_Op_Validity_Checks
(N
);
3967 if Is_Array_Type
(Etype
(N
)) then
3968 Expand_Boolean_Operator
(N
);
3970 elsif Is_Boolean_Type
(Etype
(N
)) then
3971 Adjust_Condition
(Left_Opnd
(N
));
3972 Adjust_Condition
(Right_Opnd
(N
));
3973 Set_Etype
(N
, Standard_Boolean
);
3974 Adjust_Result_Type
(N
, Typ
);
3978 ----------------------
3979 -- Expand_N_Op_Plus --
3980 ----------------------
3982 procedure Expand_N_Op_Plus
(N
: Node_Id
) is
3984 Unary_Op_Validity_Checks
(N
);
3985 end Expand_N_Op_Plus
;
3987 ---------------------
3988 -- Expand_N_Op_Rem --
3989 ---------------------
3991 procedure Expand_N_Op_Rem
(N
: Node_Id
) is
3992 Loc
: constant Source_Ptr
:= Sloc
(N
);
3994 Left
: constant Node_Id
:= Left_Opnd
(N
);
3995 Right
: constant Node_Id
:= Right_Opnd
(N
);
4007 Binary_Op_Validity_Checks
(N
);
4009 if Is_Integer_Type
(Etype
(N
)) then
4010 Apply_Divide_Check
(N
);
4013 -- Deal with annoying case of largest negative number remainder
4014 -- minus one. Gigi does not handle this case correctly, because
4015 -- it generates a divide instruction which may trap in this case.
4017 -- In fact the check is quite easy, if the right operand is -1,
4018 -- then the remainder is always 0, and we can just ignore the
4019 -- left operand completely in this case.
4021 Determine_Range
(Right
, ROK
, Rlo
, Rhi
);
4022 Determine_Range
(Left
, LOK
, Llo
, Lhi
);
4023 LLB
:= Expr_Value
(Type_Low_Bound
(Base_Type
(Etype
(Left
))));
4026 if ((not ROK
) or else (Rlo
<= (-1) and then (-1) <= Rhi
))
4028 ((not LOK
) or else (Llo
= LLB
))
4031 Make_Conditional_Expression
(Loc
,
4032 Expressions
=> New_List
(
4034 Left_Opnd
=> Duplicate_Subexpr
(Right
),
4036 Make_Integer_Literal
(Loc
, -1)),
4038 Make_Integer_Literal
(Loc
, Uint_0
),
4040 Relocate_Node
(N
))));
4042 Set_Analyzed
(Next
(Next
(First
(Expressions
(N
)))));
4043 Analyze_And_Resolve
(N
, Typ
);
4045 end Expand_N_Op_Rem
;
4047 -----------------------------
4048 -- Expand_N_Op_Rotate_Left --
4049 -----------------------------
4051 procedure Expand_N_Op_Rotate_Left
(N
: Node_Id
) is
4053 Binary_Op_Validity_Checks
(N
);
4054 end Expand_N_Op_Rotate_Left
;
4056 ------------------------------
4057 -- Expand_N_Op_Rotate_Right --
4058 ------------------------------
4060 procedure Expand_N_Op_Rotate_Right
(N
: Node_Id
) is
4062 Binary_Op_Validity_Checks
(N
);
4063 end Expand_N_Op_Rotate_Right
;
4065 ----------------------------
4066 -- Expand_N_Op_Shift_Left --
4067 ----------------------------
4069 procedure Expand_N_Op_Shift_Left
(N
: Node_Id
) is
4071 Binary_Op_Validity_Checks
(N
);
4072 end Expand_N_Op_Shift_Left
;
4074 -----------------------------
4075 -- Expand_N_Op_Shift_Right --
4076 -----------------------------
4078 procedure Expand_N_Op_Shift_Right
(N
: Node_Id
) is
4080 Binary_Op_Validity_Checks
(N
);
4081 end Expand_N_Op_Shift_Right
;
4083 ----------------------------------------
4084 -- Expand_N_Op_Shift_Right_Arithmetic --
4085 ----------------------------------------
4087 procedure Expand_N_Op_Shift_Right_Arithmetic
(N
: Node_Id
) is
4089 Binary_Op_Validity_Checks
(N
);
4090 end Expand_N_Op_Shift_Right_Arithmetic
;
4092 --------------------------
4093 -- Expand_N_Op_Subtract --
4094 --------------------------
4096 procedure Expand_N_Op_Subtract
(N
: Node_Id
) is
4097 Typ
: constant Entity_Id
:= Etype
(N
);
4100 Binary_Op_Validity_Checks
(N
);
4102 -- N - 0 = N for integer types
4104 if Is_Integer_Type
(Typ
)
4105 and then Compile_Time_Known_Value
(Right_Opnd
(N
))
4106 and then Expr_Value
(Right_Opnd
(N
)) = 0
4108 Rewrite
(N
, Left_Opnd
(N
));
4112 -- Arithemtic overflow checks for signed integer/fixed point types
4114 if Is_Signed_Integer_Type
(Typ
)
4115 or else Is_Fixed_Point_Type
(Typ
)
4117 Apply_Arithmetic_Overflow_Check
(N
);
4119 -- Vax floating-point types case
4121 elsif Vax_Float
(Typ
) then
4122 Expand_Vax_Arith
(N
);
4124 end Expand_N_Op_Subtract
;
4126 ---------------------
4127 -- Expand_N_Op_Xor --
4128 ---------------------
4130 procedure Expand_N_Op_Xor
(N
: Node_Id
) is
4131 Typ
: constant Entity_Id
:= Etype
(N
);
4134 Binary_Op_Validity_Checks
(N
);
4136 if Is_Array_Type
(Etype
(N
)) then
4137 Expand_Boolean_Operator
(N
);
4139 elsif Is_Boolean_Type
(Etype
(N
)) then
4140 Adjust_Condition
(Left_Opnd
(N
));
4141 Adjust_Condition
(Right_Opnd
(N
));
4142 Set_Etype
(N
, Standard_Boolean
);
4143 Adjust_Result_Type
(N
, Typ
);
4145 end Expand_N_Op_Xor
;
4147 ----------------------
4148 -- Expand_N_Or_Else --
4149 ----------------------
4151 -- Expand into conditional expression if Actions present, and also
4152 -- deal with optimizing case of arguments being True or False.
4154 procedure Expand_N_Or_Else
(N
: Node_Id
) is
4155 Loc
: constant Source_Ptr
:= Sloc
(N
);
4156 Typ
: constant Entity_Id
:= Etype
(N
);
4157 Left
: constant Node_Id
:= Left_Opnd
(N
);
4158 Right
: constant Node_Id
:= Right_Opnd
(N
);
4162 -- Deal with non-standard booleans
4164 if Is_Boolean_Type
(Typ
) then
4165 Adjust_Condition
(Left
);
4166 Adjust_Condition
(Right
);
4167 Set_Etype
(N
, Standard_Boolean
);
4169 -- Check for cases of left argument is True or False
4171 elsif Nkind
(Left
) = N_Identifier
then
4173 -- If left argument is False, change (False or else Right) to Right.
4174 -- Any actions associated with Right will be executed unconditionally
4175 -- and can thus be inserted into the tree unconditionally.
4177 if Entity
(Left
) = Standard_False
then
4178 if Present
(Actions
(N
)) then
4179 Insert_Actions
(N
, Actions
(N
));
4183 Adjust_Result_Type
(N
, Typ
);
4186 -- If left argument is True, change (True and then Right) to
4187 -- True. In this case we can forget the actions associated with
4188 -- Right, since they will never be executed.
4190 elsif Entity
(Left
) = Standard_True
then
4191 Kill_Dead_Code
(Right
);
4192 Kill_Dead_Code
(Actions
(N
));
4193 Rewrite
(N
, New_Occurrence_Of
(Standard_True
, Loc
));
4194 Adjust_Result_Type
(N
, Typ
);
4199 -- If Actions are present, we expand
4201 -- left or else right
4205 -- if left then True else right end
4207 -- with the actions becoming the Else_Actions of the conditional
4208 -- expression. This conditional expression is then further expanded
4209 -- (and will eventually disappear)
4211 if Present
(Actions
(N
)) then
4212 Actlist
:= Actions
(N
);
4214 Make_Conditional_Expression
(Loc
,
4215 Expressions
=> New_List
(
4217 New_Occurrence_Of
(Standard_True
, Loc
),
4220 Set_Else_Actions
(N
, Actlist
);
4221 Analyze_And_Resolve
(N
, Standard_Boolean
);
4222 Adjust_Result_Type
(N
, Typ
);
4226 -- No actions present, check for cases of right argument True/False
4228 if Nkind
(Right
) = N_Identifier
then
4230 -- Change (Left or else False) to Left. Note that we know there
4231 -- are no actions associated with the True operand, since we
4232 -- just checked for this case above.
4234 if Entity
(Right
) = Standard_False
then
4237 -- Change (Left or else True) to True, making sure to preserve
4238 -- any side effects associated with the Left operand.
4240 elsif Entity
(Right
) = Standard_True
then
4241 Remove_Side_Effects
(Left
);
4243 (N
, New_Occurrence_Of
(Standard_True
, Loc
));
4247 Adjust_Result_Type
(N
, Typ
);
4248 end Expand_N_Or_Else
;
4250 -----------------------------------
4251 -- Expand_N_Qualified_Expression --
4252 -----------------------------------
4254 procedure Expand_N_Qualified_Expression
(N
: Node_Id
) is
4255 Operand
: constant Node_Id
:= Expression
(N
);
4256 Target_Type
: constant Entity_Id
:= Entity
(Subtype_Mark
(N
));
4259 Apply_Constraint_Check
(Operand
, Target_Type
, No_Sliding
=> True);
4260 end Expand_N_Qualified_Expression
;
4262 ---------------------------------
4263 -- Expand_N_Selected_Component --
4264 ---------------------------------
4266 -- If the selector is a discriminant of a concurrent object, rewrite the
4267 -- prefix to denote the corresponding record type.
4269 procedure Expand_N_Selected_Component
(N
: Node_Id
) is
4270 Loc
: constant Source_Ptr
:= Sloc
(N
);
4271 Par
: constant Node_Id
:= Parent
(N
);
4272 P
: constant Node_Id
:= Prefix
(N
);
4274 Ptyp
: Entity_Id
:= Underlying_Type
(Etype
(P
));
4277 function In_Left_Hand_Side
(Comp
: Node_Id
) return Boolean;
4278 -- Gigi needs a temporary for prefixes that depend on a discriminant,
4279 -- unless the context of an assignment can provide size information.
4281 function In_Left_Hand_Side
(Comp
: Node_Id
) return Boolean is
4284 (Nkind
(Parent
(Comp
)) = N_Assignment_Statement
4285 and then Comp
= Name
(Parent
(Comp
)))
4287 (Present
(Parent
(Comp
))
4288 and then Nkind
(Parent
(Comp
)) in N_Subexpr
4289 and then In_Left_Hand_Side
(Parent
(Comp
)));
4290 end In_Left_Hand_Side
;
4293 if Do_Discriminant_Check
(N
) then
4295 -- Present the discrminant checking function to the backend,
4296 -- so that it can inline the call to the function.
4299 (Discriminant_Checking_Func
4300 (Original_Record_Component
(Entity
(Selector_Name
(N
)))));
4303 -- Insert explicit dereference call for the checked storage pool case
4305 if Is_Access_Type
(Ptyp
) then
4306 Insert_Dereference_Action
(P
);
4310 -- Gigi cannot handle unchecked conversions that are the prefix of
4311 -- a selected component with discriminants. This must be checked
4312 -- during expansion, because during analysis the type of the selector
4313 -- is not known at the point the prefix is analyzed. If the conversion
4314 -- is the target of an assignment, we cannot force the evaluation, of
4317 if Nkind
(Prefix
(N
)) = N_Unchecked_Type_Conversion
4318 and then Has_Discriminants
(Etype
(N
))
4319 and then not In_Left_Hand_Side
(N
)
4321 Force_Evaluation
(Prefix
(N
));
4324 -- Remaining processing applies only if selector is a discriminant
4326 if Ekind
(Entity
(Selector_Name
(N
))) = E_Discriminant
then
4328 -- If the selector is a discriminant of a constrained record type,
4329 -- rewrite the expression with the actual value of the discriminant.
4330 -- Don't do this on the left hand of an assignment statement (this
4331 -- happens in generated code, and means we really want to set it!)
4332 -- We also only do this optimization for discrete types, and not
4333 -- for access types (access discriminants get us into trouble!)
4334 -- We also do not expand the prefix of an attribute or the
4335 -- operand of an object renaming declaration.
4337 if Is_Record_Type
(Ptyp
)
4338 and then Has_Discriminants
(Ptyp
)
4339 and then Is_Constrained
(Ptyp
)
4340 and then Is_Discrete_Type
(Etype
(N
))
4341 and then (Nkind
(Par
) /= N_Assignment_Statement
4342 or else Name
(Par
) /= N
)
4343 and then (Nkind
(Par
) /= N_Attribute_Reference
4344 or else Prefix
(Par
) /= N
)
4345 and then not Is_Renamed_Object
(N
)
4352 D
:= First_Discriminant
(Ptyp
);
4353 E
:= First_Elmt
(Discriminant_Constraint
(Ptyp
));
4355 while Present
(E
) loop
4356 if D
= Entity
(Selector_Name
(N
)) then
4358 -- In the context of a case statement, the expression
4359 -- may have the base type of the discriminant, and we
4360 -- need to preserve the constraint to avoid spurious
4361 -- errors on missing cases.
4363 if Nkind
(Parent
(N
)) = N_Case_Statement
4364 and then Etype
(Node
(E
)) /= Etype
(D
)
4367 Make_Qualified_Expression
(Loc
,
4368 Subtype_Mark
=> New_Occurrence_Of
(Etype
(D
), Loc
),
4369 Expression
=> New_Copy
(Node
(E
))));
4372 Rewrite
(N
, New_Copy
(Node
(E
)));
4375 Set_Is_Static_Expression
(N
, False);
4380 Next_Discriminant
(D
);
4383 -- Note: the above loop should always terminate, but if
4384 -- it does not, we just missed an optimization due to
4385 -- some glitch (perhaps a previous error), so ignore!
4389 -- The only remaining processing is in the case of a discriminant of
4390 -- a concurrent object, where we rewrite the prefix to denote the
4391 -- corresponding record type. If the type is derived and has renamed
4392 -- discriminants, use corresponding discriminant, which is the one
4393 -- that appears in the corresponding record.
4395 if not Is_Concurrent_Type
(Ptyp
) then
4399 Disc
:= Entity
(Selector_Name
(N
));
4401 if Is_Derived_Type
(Ptyp
)
4402 and then Present
(Corresponding_Discriminant
(Disc
))
4404 Disc
:= Corresponding_Discriminant
(Disc
);
4408 Make_Selected_Component
(Loc
,
4410 Unchecked_Convert_To
(Corresponding_Record_Type
(Ptyp
),
4412 Selector_Name
=> Make_Identifier
(Loc
, Chars
(Disc
)));
4418 end Expand_N_Selected_Component
;
4420 --------------------
4421 -- Expand_N_Slice --
4422 --------------------
4424 procedure Expand_N_Slice
(N
: Node_Id
) is
4425 Loc
: constant Source_Ptr
:= Sloc
(N
);
4426 Typ
: constant Entity_Id
:= Etype
(N
);
4427 Pfx
: constant Node_Id
:= Prefix
(N
);
4428 Ptp
: Entity_Id
:= Etype
(Pfx
);
4433 -- Special handling for access types
4435 if Is_Access_Type
(Ptp
) then
4437 -- Check for explicit dereference required for checked pool
4439 Insert_Dereference_Action
(Pfx
);
4441 -- If we have an access to a packed array type, then put in an
4442 -- explicit dereference. We do this in case the slice must be
4443 -- expanded, and we want to make sure we get an access check.
4445 Ptp
:= Designated_Type
(Ptp
);
4447 if Is_Array_Type
(Ptp
) and then Is_Packed
(Ptp
) then
4449 Make_Explicit_Dereference
(Sloc
(N
),
4450 Prefix
=> Relocate_Node
(Pfx
)));
4452 Analyze_And_Resolve
(Pfx
, Ptp
);
4454 -- The prefix will now carry the Access_Check flag for the back
4455 -- end, remove it from slice itself.
4457 Set_Do_Access_Check
(N
, False);
4461 -- Range checks are potentially also needed for cases involving
4462 -- a slice indexed by a subtype indication, but Do_Range_Check
4463 -- can currently only be set for expressions ???
4465 if not Index_Checks_Suppressed
(Ptp
)
4466 and then (not Is_Entity_Name
(Pfx
)
4467 or else not Index_Checks_Suppressed
(Entity
(Pfx
)))
4468 and then Nkind
(Discrete_Range
(N
)) /= N_Subtype_Indication
4470 Enable_Range_Check
(Discrete_Range
(N
));
4473 -- The remaining case to be handled is packed slices. We can leave
4474 -- packed slices as they are in the following situations:
4476 -- 1. Right or left side of an assignment (we can handle this
4477 -- situation correctly in the assignment statement expansion).
4479 -- 2. Prefix of indexed component (the slide is optimized away
4480 -- in this case, see the start of Expand_N_Slice.
4482 -- 3. Object renaming declaration, since we want the name of
4483 -- the slice, not the value.
4485 -- 4. Argument to procedure call, since copy-in/copy-out handling
4486 -- may be required, and this is handled in the expansion of
4489 -- 5. Prefix of an address attribute (this is an error which
4490 -- is caught elsewhere, and the expansion would intefere
4491 -- with generating the error message).
4494 and then Nkind
(Parent
(N
)) /= N_Assignment_Statement
4495 and then Nkind
(Parent
(N
)) /= N_Indexed_Component
4496 and then not Is_Renamed_Object
(N
)
4497 and then Nkind
(Parent
(N
)) /= N_Procedure_Call_Statement
4498 and then (Nkind
(Parent
(N
)) /= N_Attribute_Reference
4500 Attribute_Name
(Parent
(N
)) /= Name_Address
)
4503 Make_Defining_Identifier
(Loc
, New_Internal_Name
('T'));
4506 Make_Object_Declaration
(Loc
,
4507 Defining_Identifier
=> Ent
,
4508 Object_Definition
=> New_Occurrence_Of
(Typ
, Loc
));
4510 Set_No_Initialization
(Decl
);
4512 Insert_Actions
(N
, New_List
(
4514 Make_Assignment_Statement
(Loc
,
4515 Name
=> New_Occurrence_Of
(Ent
, Loc
),
4516 Expression
=> Relocate_Node
(N
))));
4518 Rewrite
(N
, New_Occurrence_Of
(Ent
, Loc
));
4519 Analyze_And_Resolve
(N
, Typ
);
4523 ------------------------------
4524 -- Expand_N_Type_Conversion --
4525 ------------------------------
4527 procedure Expand_N_Type_Conversion
(N
: Node_Id
) is
4528 Loc
: constant Source_Ptr
:= Sloc
(N
);
4529 Operand
: constant Node_Id
:= Expression
(N
);
4530 Target_Type
: constant Entity_Id
:= Etype
(N
);
4531 Operand_Type
: Entity_Id
:= Etype
(Operand
);
4533 procedure Handle_Changed_Representation
;
4534 -- This is called in the case of record and array type conversions
4535 -- to see if there is a change of representation to be handled.
4536 -- Change of representation is actually handled at the assignment
4537 -- statement level, and what this procedure does is rewrite node N
4538 -- conversion as an assignment to temporary. If there is no change
4539 -- of representation, then the conversion node is unchanged.
4541 procedure Real_Range_Check
;
4542 -- Handles generation of range check for real target value
4544 -----------------------------------
4545 -- Handle_Changed_Representation --
4546 -----------------------------------
4548 procedure Handle_Changed_Representation
is
4557 -- Nothing to do if no change of representation
4559 if Same_Representation
(Operand_Type
, Target_Type
) then
4562 -- The real change of representation work is done by the assignment
4563 -- statement processing. So if this type conversion is appearing as
4564 -- the expression of an assignment statement, nothing needs to be
4565 -- done to the conversion.
4567 elsif Nkind
(Parent
(N
)) = N_Assignment_Statement
then
4570 -- Otherwise we need to generate a temporary variable, and do the
4571 -- change of representation assignment into that temporary variable.
4572 -- The conversion is then replaced by a reference to this variable.
4577 -- If type is unconstrained we have to add a constraint,
4578 -- copied from the actual value of the left hand side.
4580 if not Is_Constrained
(Target_Type
) then
4581 if Has_Discriminants
(Operand_Type
) then
4582 Disc
:= First_Discriminant
(Operand_Type
);
4584 while Present
(Disc
) loop
4586 Make_Selected_Component
(Loc
,
4587 Prefix
=> Duplicate_Subexpr
(Operand
),
4589 Make_Identifier
(Loc
, Chars
(Disc
))));
4590 Next_Discriminant
(Disc
);
4593 elsif Is_Array_Type
(Operand_Type
) then
4594 N_Ix
:= First_Index
(Target_Type
);
4597 for J
in 1 .. Number_Dimensions
(Operand_Type
) loop
4599 -- We convert the bounds explicitly. We use an unchecked
4600 -- conversion because bounds checks are done elsewhere.
4605 Unchecked_Convert_To
(Etype
(N_Ix
),
4606 Make_Attribute_Reference
(Loc
,
4609 (Operand
, Name_Req
=> True),
4610 Attribute_Name
=> Name_First
,
4611 Expressions
=> New_List
(
4612 Make_Integer_Literal
(Loc
, J
)))),
4615 Unchecked_Convert_To
(Etype
(N_Ix
),
4616 Make_Attribute_Reference
(Loc
,
4619 (Operand
, Name_Req
=> True),
4620 Attribute_Name
=> Name_Last
,
4621 Expressions
=> New_List
(
4622 Make_Integer_Literal
(Loc
, J
))))));
4629 Odef
:= New_Occurrence_Of
(Target_Type
, Loc
);
4631 if Present
(Cons
) then
4633 Make_Subtype_Indication
(Loc
,
4634 Subtype_Mark
=> Odef
,
4636 Make_Index_Or_Discriminant_Constraint
(Loc
,
4637 Constraints
=> Cons
));
4640 Temp
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('C'));
4642 Make_Object_Declaration
(Loc
,
4643 Defining_Identifier
=> Temp
,
4644 Object_Definition
=> Odef
);
4646 Set_No_Initialization
(Decl
, True);
4648 -- Insert required actions. It is essential to suppress checks
4649 -- since we have suppressed default initialization, which means
4650 -- that the variable we create may have no discriminants.
4655 Make_Assignment_Statement
(Loc
,
4656 Name
=> New_Occurrence_Of
(Temp
, Loc
),
4657 Expression
=> Relocate_Node
(N
))),
4658 Suppress
=> All_Checks
);
4660 Rewrite
(N
, New_Occurrence_Of
(Temp
, Loc
));
4663 end Handle_Changed_Representation
;
4665 ----------------------
4666 -- Real_Range_Check --
4667 ----------------------
4669 -- Case of conversions to floating-point or fixed-point. If range
4670 -- checks are enabled and the target type has a range constraint,
4677 -- Tnn : typ'Base := typ'Base (x);
4678 -- [constraint_error when Tnn < typ'First or else Tnn > typ'Last]
4681 procedure Real_Range_Check
is
4682 Btyp
: constant Entity_Id
:= Base_Type
(Target_Type
);
4683 Lo
: constant Node_Id
:= Type_Low_Bound
(Target_Type
);
4684 Hi
: constant Node_Id
:= Type_High_Bound
(Target_Type
);
4689 -- Nothing to do if conversion was rewritten
4691 if Nkind
(N
) /= N_Type_Conversion
then
4695 -- Nothing to do if range checks suppressed, or target has the
4696 -- same range as the base type (or is the base type).
4698 if Range_Checks_Suppressed
(Target_Type
)
4699 or else (Lo
= Type_Low_Bound
(Btyp
)
4701 Hi
= Type_High_Bound
(Btyp
))
4706 -- Nothing to do if expression is an entity on which checks
4707 -- have been suppressed.
4709 if Is_Entity_Name
(Expression
(N
))
4710 and then Range_Checks_Suppressed
(Entity
(Expression
(N
)))
4715 -- Here we rewrite the conversion as described above
4717 Conv
:= Relocate_Node
(N
);
4719 (Subtype_Mark
(Conv
), New_Occurrence_Of
(Btyp
, Loc
));
4720 Set_Etype
(Conv
, Btyp
);
4722 -- Skip overflow check for integer to float conversions,
4723 -- since it is not needed, and in any case gigi generates
4724 -- incorrect code for such overflow checks ???
4726 if not Is_Integer_Type
(Etype
(Expression
(N
))) then
4727 Set_Do_Overflow_Check
(Conv
, True);
4731 Make_Defining_Identifier
(Loc
,
4732 Chars
=> New_Internal_Name
('T'));
4734 Insert_Actions
(N
, New_List
(
4735 Make_Object_Declaration
(Loc
,
4736 Defining_Identifier
=> Tnn
,
4737 Object_Definition
=> New_Occurrence_Of
(Btyp
, Loc
),
4738 Expression
=> Conv
),
4740 Make_Raise_Constraint_Error
(Loc
,
4745 Left_Opnd
=> New_Occurrence_Of
(Tnn
, Loc
),
4747 Make_Attribute_Reference
(Loc
,
4748 Attribute_Name
=> Name_First
,
4750 New_Occurrence_Of
(Target_Type
, Loc
))),
4754 Left_Opnd
=> New_Occurrence_Of
(Tnn
, Loc
),
4756 Make_Attribute_Reference
(Loc
,
4757 Attribute_Name
=> Name_Last
,
4759 New_Occurrence_Of
(Target_Type
, Loc
)))))));
4761 Rewrite
(N
, New_Occurrence_Of
(Tnn
, Loc
));
4762 Analyze_And_Resolve
(N
, Btyp
);
4763 end Real_Range_Check
;
4765 -- Start of processing for Expand_N_Type_Conversion
4768 -- Nothing at all to do if conversion is to the identical type
4769 -- so remove the conversion completely, it is useless.
4771 if Operand_Type
= Target_Type
then
4772 Rewrite
(N
, Relocate_Node
(Expression
(N
)));
4776 -- Deal with Vax floating-point cases
4778 if Vax_Float
(Operand_Type
) or else Vax_Float
(Target_Type
) then
4779 Expand_Vax_Conversion
(N
);
4783 -- Nothing to do if this is the second argument of read. This
4784 -- is a "backwards" conversion that will be handled by the
4785 -- specialized code in attribute processing.
4787 if Nkind
(Parent
(N
)) = N_Attribute_Reference
4788 and then Attribute_Name
(Parent
(N
)) = Name_Read
4789 and then Next
(First
(Expressions
(Parent
(N
)))) = N
4794 -- Here if we may need to expand conversion
4796 -- Special case of converting from non-standard boolean type
4798 if Is_Boolean_Type
(Operand_Type
)
4799 and then (Nonzero_Is_True
(Operand_Type
))
4801 Adjust_Condition
(Operand
);
4802 Set_Etype
(Operand
, Standard_Boolean
);
4803 Operand_Type
:= Standard_Boolean
;
4806 -- Case of converting to an access type
4808 if Is_Access_Type
(Target_Type
) then
4810 -- Apply an accessibility check if the operand is an
4811 -- access parameter. Note that other checks may still
4812 -- need to be applied below (such as tagged type checks).
4814 if Is_Entity_Name
(Operand
)
4815 and then Ekind
(Entity
(Operand
)) in Formal_Kind
4816 and then Ekind
(Etype
(Operand
)) = E_Anonymous_Access_Type
4818 Apply_Accessibility_Check
(Operand
, Target_Type
);
4820 -- If the level of the operand type is statically deeper
4821 -- then the level of the target type, then force Program_Error.
4822 -- Note that this can only occur for cases where the attribute
4823 -- is within the body of an instantiation (otherwise the
4824 -- conversion will already have been rejected as illegal).
4825 -- Note: warnings are issued by the analyzer for the instance
4828 elsif In_Instance_Body
4829 and then Type_Access_Level
(Operand_Type
)
4830 > Type_Access_Level
(Target_Type
)
4832 Rewrite
(N
, Make_Raise_Program_Error
(Sloc
(N
)));
4833 Set_Etype
(N
, Target_Type
);
4835 -- When the operand is a selected access discriminant
4836 -- the check needs to be made against the level of the
4837 -- object denoted by the prefix of the selected name.
4838 -- Force Program_Error for this case as well (this
4839 -- accessibility violation can only happen if within
4840 -- the body of an instantiation).
4842 elsif In_Instance_Body
4843 and then Ekind
(Operand_Type
) = E_Anonymous_Access_Type
4844 and then Nkind
(Operand
) = N_Selected_Component
4845 and then Object_Access_Level
(Operand
) >
4846 Type_Access_Level
(Target_Type
)
4848 Rewrite
(N
, Make_Raise_Program_Error
(Sloc
(N
)));
4849 Set_Etype
(N
, Target_Type
);
4853 -- Case of conversions of tagged types and access to tagged types
4855 -- When needed, that is to say when the expression is class-wide,
4856 -- Add runtime a tag check for (strict) downward conversion by using
4857 -- the membership test, generating:
4859 -- [constraint_error when Operand not in Target_Type'Class]
4861 -- or in the access type case
4863 -- [constraint_error
4864 -- when Operand /= null
4865 -- and then Operand.all not in
4866 -- Designated_Type (Target_Type)'Class]
4868 if (Is_Access_Type
(Target_Type
)
4869 and then Is_Tagged_Type
(Designated_Type
(Target_Type
)))
4870 or else Is_Tagged_Type
(Target_Type
)
4872 -- Do not do any expansion in the access type case if the
4873 -- parent is a renaming, since this is an error situation
4874 -- which will be caught by Sem_Ch8, and the expansion can
4875 -- intefere with this error check.
4877 if Is_Access_Type
(Target_Type
)
4878 and then Is_Renamed_Object
(N
)
4883 -- Oherwise, proceed with processing tagged conversion
4886 Actual_Operand_Type
: Entity_Id
;
4887 Actual_Target_Type
: Entity_Id
;
4892 if Is_Access_Type
(Target_Type
) then
4893 Actual_Operand_Type
:= Designated_Type
(Operand_Type
);
4894 Actual_Target_Type
:= Designated_Type
(Target_Type
);
4897 Actual_Operand_Type
:= Operand_Type
;
4898 Actual_Target_Type
:= Target_Type
;
4901 if Is_Class_Wide_Type
(Actual_Operand_Type
)
4902 and then Root_Type
(Actual_Operand_Type
) /= Actual_Target_Type
4903 and then Is_Ancestor
4904 (Root_Type
(Actual_Operand_Type
),
4906 and then not Tag_Checks_Suppressed
(Actual_Target_Type
)
4908 -- The conversion is valid for any descendant of the
4911 Actual_Target_Type
:= Class_Wide_Type
(Actual_Target_Type
);
4913 if Is_Access_Type
(Target_Type
) then
4918 Left_Opnd
=> Duplicate_Subexpr
(Operand
),
4919 Right_Opnd
=> Make_Null
(Loc
)),
4924 Make_Explicit_Dereference
(Loc
,
4925 Prefix
=> Duplicate_Subexpr
(Operand
)),
4927 New_Reference_To
(Actual_Target_Type
, Loc
)));
4932 Left_Opnd
=> Duplicate_Subexpr
(Operand
),
4934 New_Reference_To
(Actual_Target_Type
, Loc
));
4938 Make_Raise_Constraint_Error
(Loc
,
4939 Condition
=> Cond
));
4941 Change_Conversion_To_Unchecked
(N
);
4942 Analyze_And_Resolve
(N
, Target_Type
);
4946 -- Case of other access type conversions
4948 elsif Is_Access_Type
(Target_Type
) then
4949 Apply_Constraint_Check
(Operand
, Target_Type
);
4951 -- Case of conversions from a fixed-point type
4953 -- These conversions require special expansion and processing, found
4954 -- in the Exp_Fixd package. We ignore cases where Conversion_OK is
4955 -- set, since from a semantic point of view, these are simple integer
4956 -- conversions, which do not need further processing.
4958 elsif Is_Fixed_Point_Type
(Operand_Type
)
4959 and then not Conversion_OK
(N
)
4961 -- We should never see universal fixed at this case, since the
4962 -- expansion of the constituent divide or multiply should have
4963 -- eliminated the explicit mention of universal fixed.
4965 pragma Assert
(Operand_Type
/= Universal_Fixed
);
4967 -- Check for special case of the conversion to universal real
4968 -- that occurs as a result of the use of a round attribute.
4969 -- In this case, the real type for the conversion is taken
4970 -- from the target type of the Round attribute and the
4971 -- result must be marked as rounded.
4973 if Target_Type
= Universal_Real
4974 and then Nkind
(Parent
(N
)) = N_Attribute_Reference
4975 and then Attribute_Name
(Parent
(N
)) = Name_Round
4977 Set_Rounded_Result
(N
);
4978 Set_Etype
(N
, Etype
(Parent
(N
)));
4981 -- Otherwise do correct fixed-conversion, but skip these if the
4982 -- Conversion_OK flag is set, because from a semantic point of
4983 -- view these are simple integer conversions needing no further
4984 -- processing (the backend will simply treat them as integers)
4986 if not Conversion_OK
(N
) then
4987 if Is_Fixed_Point_Type
(Etype
(N
)) then
4988 Expand_Convert_Fixed_To_Fixed
(N
);
4991 elsif Is_Integer_Type
(Etype
(N
)) then
4992 Expand_Convert_Fixed_To_Integer
(N
);
4995 pragma Assert
(Is_Floating_Point_Type
(Etype
(N
)));
4996 Expand_Convert_Fixed_To_Float
(N
);
5001 -- Case of conversions to a fixed-point type
5003 -- These conversions require special expansion and processing, found
5004 -- in the Exp_Fixd package. Again, ignore cases where Conversion_OK
5005 -- is set, since from a semantic point of view, these are simple
5006 -- integer conversions, which do not need further processing.
5008 elsif Is_Fixed_Point_Type
(Target_Type
)
5009 and then not Conversion_OK
(N
)
5011 if Is_Integer_Type
(Operand_Type
) then
5012 Expand_Convert_Integer_To_Fixed
(N
);
5015 pragma Assert
(Is_Floating_Point_Type
(Operand_Type
));
5016 Expand_Convert_Float_To_Fixed
(N
);
5020 -- Case of float-to-integer conversions
5022 -- We also handle float-to-fixed conversions with Conversion_OK set
5023 -- since semantically the fixed-point target is treated as though it
5024 -- were an integer in such cases.
5026 elsif Is_Floating_Point_Type
(Operand_Type
)
5028 (Is_Integer_Type
(Target_Type
)
5030 (Is_Fixed_Point_Type
(Target_Type
) and then Conversion_OK
(N
)))
5032 -- Special processing required if the conversion is the expression
5033 -- of a Truncation attribute reference. In this case we replace:
5035 -- ityp (ftyp'Truncation (x))
5041 -- with the Float_Truncate flag set. This is clearly more efficient.
5043 if Nkind
(Operand
) = N_Attribute_Reference
5044 and then Attribute_Name
(Operand
) = Name_Truncation
5047 Relocate_Node
(First
(Expressions
(Operand
))));
5048 Set_Float_Truncate
(N
, True);
5051 -- One more check here, gcc is still not able to do conversions of
5052 -- this type with proper overflow checking, and so gigi is doing an
5053 -- approximation of what is required by doing floating-point compares
5054 -- with the end-point. But that can lose precision in some cases, and
5055 -- give a wrong result. Converting the operand to Long_Long_Float is
5056 -- helpful, but still does not catch all cases with 64-bit integers
5057 -- on targets with only 64-bit floats ???
5059 if Do_Range_Check
(Expression
(N
)) then
5060 Rewrite
(Expression
(N
),
5061 Make_Type_Conversion
(Loc
,
5063 New_Occurrence_Of
(Standard_Long_Long_Float
, Loc
),
5065 Relocate_Node
(Expression
(N
))));
5067 Set_Etype
(Expression
(N
), Standard_Long_Long_Float
);
5068 Enable_Range_Check
(Expression
(N
));
5069 Set_Do_Range_Check
(Expression
(Expression
(N
)), False);
5072 -- Case of array conversions
5074 -- Expansion of array conversions, add required length/range checks
5075 -- but only do this if there is no change of representation. For
5076 -- handling of this case, see Handle_Changed_Representation.
5078 elsif Is_Array_Type
(Target_Type
) then
5080 if Is_Constrained
(Target_Type
) then
5081 Apply_Length_Check
(Operand
, Target_Type
);
5083 Apply_Range_Check
(Operand
, Target_Type
);
5086 Handle_Changed_Representation
;
5088 -- Case of conversions of discriminated types
5090 -- Add required discriminant checks if target is constrained. Again
5091 -- this change is skipped if we have a change of representation.
5093 elsif Has_Discriminants
(Target_Type
)
5094 and then Is_Constrained
(Target_Type
)
5096 Apply_Discriminant_Check
(Operand
, Target_Type
);
5097 Handle_Changed_Representation
;
5099 -- Case of all other record conversions. The only processing required
5100 -- is to check for a change of representation requiring the special
5101 -- assignment processing.
5103 elsif Is_Record_Type
(Target_Type
) then
5104 Handle_Changed_Representation
;
5106 -- Case of conversions of enumeration types
5108 elsif Is_Enumeration_Type
(Target_Type
) then
5110 -- Special processing is required if there is a change of
5111 -- representation (from enumeration representation clauses)
5113 if not Same_Representation
(Target_Type
, Operand_Type
) then
5115 -- Convert: x(y) to x'val (ytyp'val (y))
5118 Make_Attribute_Reference
(Loc
,
5119 Prefix
=> New_Occurrence_Of
(Target_Type
, Loc
),
5120 Attribute_Name
=> Name_Val
,
5121 Expressions
=> New_List
(
5122 Make_Attribute_Reference
(Loc
,
5123 Prefix
=> New_Occurrence_Of
(Operand_Type
, Loc
),
5124 Attribute_Name
=> Name_Pos
,
5125 Expressions
=> New_List
(Operand
)))));
5127 Analyze_And_Resolve
(N
, Target_Type
);
5130 -- Case of conversions to floating-point
5132 elsif Is_Floating_Point_Type
(Target_Type
) then
5135 -- The remaining cases require no front end processing
5141 -- At this stage, either the conversion node has been transformed
5142 -- into some other equivalent expression, or left as a conversion
5143 -- that can be handled by Gigi. The conversions that Gigi can handle
5144 -- are the following:
5146 -- Conversions with no change of representation or type
5148 -- Numeric conversions involving integer values, floating-point
5149 -- values, and fixed-point values. Fixed-point values are allowed
5150 -- only if Conversion_OK is set, i.e. if the fixed-point values
5151 -- are to be treated as integers.
5153 -- No other conversions should be passed to Gigi.
5155 end Expand_N_Type_Conversion
;
5157 -----------------------------------
5158 -- Expand_N_Unchecked_Expression --
5159 -----------------------------------
5161 -- Remove the unchecked expression node from the tree. It's job was simply
5162 -- to make sure that its constituent expression was handled with checks
5163 -- off, and now that that is done, we can remove it from the tree, and
5164 -- indeed must, since gigi does not expect to see these nodes.
5166 procedure Expand_N_Unchecked_Expression
(N
: Node_Id
) is
5167 Exp
: constant Node_Id
:= Expression
(N
);
5170 Set_Assignment_OK
(Exp
, Assignment_OK
(N
) or Assignment_OK
(Exp
));
5172 end Expand_N_Unchecked_Expression
;
5174 ----------------------------------------
5175 -- Expand_N_Unchecked_Type_Conversion --
5176 ----------------------------------------
5178 -- If this cannot be handled by Gigi and we haven't already made
5179 -- a temporary for it, do it now.
5181 procedure Expand_N_Unchecked_Type_Conversion
(N
: Node_Id
) is
5182 Target_Type
: constant Entity_Id
:= Etype
(N
);
5183 Operand
: constant Node_Id
:= Expression
(N
);
5184 Operand_Type
: constant Entity_Id
:= Etype
(Operand
);
5187 -- If we have a conversion of a compile time known value to a target
5188 -- type and the value is in range of the target type, then we can simply
5189 -- replace the construct by an integer literal of the correct type. We
5190 -- only apply this to integer types being converted. Possibly it may
5191 -- apply in other cases, but it is too much trouble to worry about.
5193 -- Note that we do not do this transformation if the Kill_Range_Check
5194 -- flag is set, since then the value may be outside the expected range.
5195 -- This happens in the Normalize_Scalars case.
5197 if Is_Integer_Type
(Target_Type
)
5198 and then Is_Integer_Type
(Operand_Type
)
5199 and then Compile_Time_Known_Value
(Operand
)
5200 and then not Kill_Range_Check
(N
)
5203 Val
: constant Uint
:= Expr_Value
(Operand
);
5206 if Compile_Time_Known_Value
(Type_Low_Bound
(Target_Type
))
5208 Compile_Time_Known_Value
(Type_High_Bound
(Target_Type
))
5210 Val
>= Expr_Value
(Type_Low_Bound
(Target_Type
))
5212 Val
<= Expr_Value
(Type_High_Bound
(Target_Type
))
5214 Rewrite
(N
, Make_Integer_Literal
(Sloc
(N
), Val
));
5215 Analyze_And_Resolve
(N
, Target_Type
);
5221 -- Nothing to do if conversion is safe
5223 if Safe_Unchecked_Type_Conversion
(N
) then
5227 -- Otherwise force evaluation unless Assignment_OK flag is set (this
5228 -- flag indicates ??? -- more comments needed here)
5230 if Assignment_OK
(N
) then
5233 Force_Evaluation
(N
);
5235 end Expand_N_Unchecked_Type_Conversion
;
5237 ----------------------------
5238 -- Expand_Record_Equality --
5239 ----------------------------
5241 -- For non-variant records, Equality is expanded when needed into:
5243 -- and then Lhs.Discr1 = Rhs.Discr1
5245 -- and then Lhs.Discrn = Rhs.Discrn
5246 -- and then Lhs.Cmp1 = Rhs.Cmp1
5248 -- and then Lhs.Cmpn = Rhs.Cmpn
5250 -- The expression is folded by the back-end for adjacent fields. This
5251 -- function is called for tagged record in only one occasion: for imple-
5252 -- menting predefined primitive equality (see Predefined_Primitives_Bodies)
5253 -- otherwise the primitive "=" is used directly.
5255 function Expand_Record_Equality
5263 Loc
: constant Source_Ptr
:= Sloc
(Nod
);
5265 function Suitable_Element
(C
: Entity_Id
) return Entity_Id
;
5266 -- Return the first field to compare beginning with C, skipping the
5267 -- inherited components
5269 function Suitable_Element
(C
: Entity_Id
) return Entity_Id
is
5274 elsif Ekind
(C
) /= E_Discriminant
5275 and then Ekind
(C
) /= E_Component
5277 return Suitable_Element
(Next_Entity
(C
));
5279 elsif Is_Tagged_Type
(Typ
)
5280 and then C
/= Original_Record_Component
(C
)
5282 return Suitable_Element
(Next_Entity
(C
));
5284 elsif Chars
(C
) = Name_uController
5285 or else Chars
(C
) = Name_uTag
5287 return Suitable_Element
(Next_Entity
(C
));
5292 end Suitable_Element
;
5297 First_Time
: Boolean := True;
5299 -- Start of processing for Expand_Record_Equality
5302 -- Special processing for the unchecked union case, which will occur
5303 -- only in the context of tagged types and dynamic dispatching, since
5304 -- other cases are handled statically. We return True, but insert a
5305 -- raise Program_Error statement.
5307 if Is_Unchecked_Union
(Typ
) then
5309 -- If this is a component of an enclosing record, return the Raise
5310 -- statement directly.
5312 if No
(Parent
(Lhs
)) then
5313 Result
:= Make_Raise_Program_Error
(Loc
);
5314 Set_Etype
(Result
, Standard_Boolean
);
5319 Make_Raise_Program_Error
(Loc
));
5320 return New_Occurrence_Of
(Standard_True
, Loc
);
5324 -- Generates the following code: (assuming that Typ has one Discr and
5325 -- component C2 is also a record)
5328 -- and then Lhs.Discr1 = Rhs.Discr1
5329 -- and then Lhs.C1 = Rhs.C1
5330 -- and then Lhs.C2.C1=Rhs.C2.C1 and then ... Lhs.C2.Cn=Rhs.C2.Cn
5332 -- and then Lhs.Cmpn = Rhs.Cmpn
5334 Result
:= New_Reference_To
(Standard_True
, Loc
);
5335 C
:= Suitable_Element
(First_Entity
(Typ
));
5337 while Present
(C
) loop
5345 First_Time
:= False;
5350 New_Lhs
:= New_Copy_Tree
(Lhs
);
5351 New_Rhs
:= New_Copy_Tree
(Rhs
);
5356 Left_Opnd
=> Result
,
5358 Expand_Composite_Equality
(Nod
, Etype
(C
),
5360 Make_Selected_Component
(Loc
,
5362 Selector_Name
=> New_Reference_To
(C
, Loc
)),
5364 Make_Selected_Component
(Loc
,
5366 Selector_Name
=> New_Reference_To
(C
, Loc
)),
5370 C
:= Suitable_Element
(Next_Entity
(C
));
5374 end Expand_Record_Equality
;
5376 -------------------------------------
5377 -- Fixup_Universal_Fixed_Operation --
5378 -------------------------------------
5380 procedure Fixup_Universal_Fixed_Operation
(N
: Node_Id
) is
5381 Conv
: constant Node_Id
:= Parent
(N
);
5384 -- We must have a type conversion immediately above us
5386 pragma Assert
(Nkind
(Conv
) = N_Type_Conversion
);
5388 -- Normally the type conversion gives our target type. The exception
5389 -- occurs in the case of the Round attribute, where the conversion
5390 -- will be to universal real, and our real type comes from the Round
5391 -- attribute (as well as an indication that we must round the result)
5393 if Nkind
(Parent
(Conv
)) = N_Attribute_Reference
5394 and then Attribute_Name
(Parent
(Conv
)) = Name_Round
5396 Set_Etype
(N
, Etype
(Parent
(Conv
)));
5397 Set_Rounded_Result
(N
);
5399 -- Normal case where type comes from conversion above us
5402 Set_Etype
(N
, Etype
(Conv
));
5404 end Fixup_Universal_Fixed_Operation
;
5406 -------------------------------
5407 -- Insert_Dereference_Action --
5408 -------------------------------
5410 procedure Insert_Dereference_Action
(N
: Node_Id
) is
5411 Loc
: constant Source_Ptr
:= Sloc
(N
);
5412 Typ
: constant Entity_Id
:= Etype
(N
);
5413 Pool
: constant Entity_Id
:= Associated_Storage_Pool
(Typ
);
5415 function Is_Checked_Storage_Pool
(P
: Entity_Id
) return Boolean;
5416 -- return true if type of P is derived from Checked_Pool;
5418 function Is_Checked_Storage_Pool
(P
: Entity_Id
) return Boolean is
5427 while T
/= Etype
(T
) loop
5428 if Is_RTE
(T
, RE_Checked_Pool
) then
5436 end Is_Checked_Storage_Pool
;
5438 -- Start of processing for Insert_Dereference_Action
5441 if not Comes_From_Source
(Parent
(N
)) then
5444 elsif not Is_Checked_Storage_Pool
(Pool
) then
5449 Make_Procedure_Call_Statement
(Loc
,
5450 Name
=> New_Reference_To
(
5451 Find_Prim_Op
(Etype
(Pool
), Name_Dereference
), Loc
),
5453 Parameter_Associations
=> New_List
(
5457 New_Reference_To
(Pool
, Loc
),
5461 Make_Attribute_Reference
(Loc
,
5463 Make_Explicit_Dereference
(Loc
, Duplicate_Subexpr
(N
)),
5464 Attribute_Name
=> Name_Address
),
5466 -- Size_In_Storage_Elements
5468 Make_Op_Divide
(Loc
,
5470 Make_Attribute_Reference
(Loc
,
5472 Make_Explicit_Dereference
(Loc
, Duplicate_Subexpr
(N
)),
5473 Attribute_Name
=> Name_Size
),
5475 Make_Integer_Literal
(Loc
, System_Storage_Unit
)),
5479 Make_Attribute_Reference
(Loc
,
5481 Make_Explicit_Dereference
(Loc
, Duplicate_Subexpr
(N
)),
5482 Attribute_Name
=> Name_Alignment
))));
5484 end Insert_Dereference_Action
;
5486 ------------------------------
5487 -- Make_Array_Comparison_Op --
5488 ------------------------------
5490 -- This is a hand-coded expansion of the following generic function:
5493 -- type elem is (<>);
5494 -- type index is (<>);
5495 -- type a is array (index range <>) of elem;
5497 -- function Gnnn (X : a; Y: a) return boolean is
5498 -- J : index := Y'first;
5501 -- if X'length = 0 then
5504 -- elsif Y'length = 0 then
5508 -- for I in X'range loop
5509 -- if X (I) = Y (J) then
5510 -- if J = Y'last then
5513 -- J := index'succ (J);
5517 -- return X (I) > Y (J);
5521 -- return X'length > Y'length;
5525 -- Note that since we are essentially doing this expansion by hand, we
5526 -- do not need to generate an actual or formal generic part, just the
5527 -- instantiated function itself.
5529 function Make_Array_Comparison_Op
5534 Loc
: constant Source_Ptr
:= Sloc
(Nod
);
5536 X
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uX
);
5537 Y
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uY
);
5538 I
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uI
);
5539 J
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uJ
);
5541 Index
: constant Entity_Id
:= Base_Type
(Etype
(First_Index
(Typ
)));
5543 Loop_Statement
: Node_Id
;
5544 Loop_Body
: Node_Id
;
5547 Final_Expr
: Node_Id
;
5548 Func_Body
: Node_Id
;
5549 Func_Name
: Entity_Id
;
5555 -- if J = Y'last then
5558 -- J := index'succ (J);
5562 Make_Implicit_If_Statement
(Nod
,
5565 Left_Opnd
=> New_Reference_To
(J
, Loc
),
5567 Make_Attribute_Reference
(Loc
,
5568 Prefix
=> New_Reference_To
(Y
, Loc
),
5569 Attribute_Name
=> Name_Last
)),
5571 Then_Statements
=> New_List
(
5572 Make_Exit_Statement
(Loc
)),
5576 Make_Assignment_Statement
(Loc
,
5577 Name
=> New_Reference_To
(J
, Loc
),
5579 Make_Attribute_Reference
(Loc
,
5580 Prefix
=> New_Reference_To
(Index
, Loc
),
5581 Attribute_Name
=> Name_Succ
,
5582 Expressions
=> New_List
(New_Reference_To
(J
, Loc
))))));
5584 -- if X (I) = Y (J) then
5587 -- return X (I) > Y (J);
5591 Make_Implicit_If_Statement
(Nod
,
5595 Make_Indexed_Component
(Loc
,
5596 Prefix
=> New_Reference_To
(X
, Loc
),
5597 Expressions
=> New_List
(New_Reference_To
(I
, Loc
))),
5600 Make_Indexed_Component
(Loc
,
5601 Prefix
=> New_Reference_To
(Y
, Loc
),
5602 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)))),
5604 Then_Statements
=> New_List
(Inner_If
),
5606 Else_Statements
=> New_List
(
5607 Make_Return_Statement
(Loc
,
5611 Make_Indexed_Component
(Loc
,
5612 Prefix
=> New_Reference_To
(X
, Loc
),
5613 Expressions
=> New_List
(New_Reference_To
(I
, Loc
))),
5616 Make_Indexed_Component
(Loc
,
5617 Prefix
=> New_Reference_To
(Y
, Loc
),
5618 Expressions
=> New_List
(
5619 New_Reference_To
(J
, Loc
)))))));
5621 -- for I in X'range loop
5626 Make_Implicit_Loop_Statement
(Nod
,
5627 Identifier
=> Empty
,
5630 Make_Iteration_Scheme
(Loc
,
5631 Loop_Parameter_Specification
=>
5632 Make_Loop_Parameter_Specification
(Loc
,
5633 Defining_Identifier
=> I
,
5634 Discrete_Subtype_Definition
=>
5635 Make_Attribute_Reference
(Loc
,
5636 Prefix
=> New_Reference_To
(X
, Loc
),
5637 Attribute_Name
=> Name_Range
))),
5639 Statements
=> New_List
(Loop_Body
));
5641 -- if X'length = 0 then
5643 -- elsif Y'length = 0 then
5646 -- for ... loop ... end loop;
5647 -- return X'length > Y'length;
5651 Make_Attribute_Reference
(Loc
,
5652 Prefix
=> New_Reference_To
(X
, Loc
),
5653 Attribute_Name
=> Name_Length
);
5656 Make_Attribute_Reference
(Loc
,
5657 Prefix
=> New_Reference_To
(Y
, Loc
),
5658 Attribute_Name
=> Name_Length
);
5662 Left_Opnd
=> Length1
,
5663 Right_Opnd
=> Length2
);
5666 Make_Implicit_If_Statement
(Nod
,
5670 Make_Attribute_Reference
(Loc
,
5671 Prefix
=> New_Reference_To
(X
, Loc
),
5672 Attribute_Name
=> Name_Length
),
5674 Make_Integer_Literal
(Loc
, 0)),
5678 Make_Return_Statement
(Loc
,
5679 Expression
=> New_Reference_To
(Standard_False
, Loc
))),
5681 Elsif_Parts
=> New_List
(
5682 Make_Elsif_Part
(Loc
,
5686 Make_Attribute_Reference
(Loc
,
5687 Prefix
=> New_Reference_To
(Y
, Loc
),
5688 Attribute_Name
=> Name_Length
),
5690 Make_Integer_Literal
(Loc
, 0)),
5694 Make_Return_Statement
(Loc
,
5695 Expression
=> New_Reference_To
(Standard_True
, Loc
))))),
5697 Else_Statements
=> New_List
(
5699 Make_Return_Statement
(Loc
,
5700 Expression
=> Final_Expr
)));
5704 Formals
:= New_List
(
5705 Make_Parameter_Specification
(Loc
,
5706 Defining_Identifier
=> X
,
5707 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)),
5709 Make_Parameter_Specification
(Loc
,
5710 Defining_Identifier
=> Y
,
5711 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)));
5713 -- function Gnnn (...) return boolean is
5714 -- J : index := Y'first;
5719 Func_Name
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('G'));
5722 Make_Subprogram_Body
(Loc
,
5724 Make_Function_Specification
(Loc
,
5725 Defining_Unit_Name
=> Func_Name
,
5726 Parameter_Specifications
=> Formals
,
5727 Subtype_Mark
=> New_Reference_To
(Standard_Boolean
, Loc
)),
5729 Declarations
=> New_List
(
5730 Make_Object_Declaration
(Loc
,
5731 Defining_Identifier
=> J
,
5732 Object_Definition
=> New_Reference_To
(Index
, Loc
),
5734 Make_Attribute_Reference
(Loc
,
5735 Prefix
=> New_Reference_To
(Y
, Loc
),
5736 Attribute_Name
=> Name_First
))),
5738 Handled_Statement_Sequence
=>
5739 Make_Handled_Sequence_Of_Statements
(Loc
,
5740 Statements
=> New_List
(If_Stat
)));
5744 end Make_Array_Comparison_Op
;
5746 ---------------------------
5747 -- Make_Boolean_Array_Op --
5748 ---------------------------
5750 -- For logical operations on boolean arrays, expand in line the
5751 -- following, replacing 'and' with 'or' or 'xor' where needed:
5753 -- function Annn (A : typ; B: typ) return typ is
5756 -- for J in A'range loop
5757 -- C (J) := A (J) op B (J);
5762 -- Here typ is the boolean array type
5764 function Make_Boolean_Array_Op
5769 Loc
: constant Source_Ptr
:= Sloc
(N
);
5771 A
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uA
);
5772 B
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uB
);
5773 C
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uC
);
5774 J
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uJ
);
5782 Func_Name
: Entity_Id
;
5783 Func_Body
: Node_Id
;
5784 Loop_Statement
: Node_Id
;
5788 Make_Indexed_Component
(Loc
,
5789 Prefix
=> New_Reference_To
(A
, Loc
),
5790 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
5793 Make_Indexed_Component
(Loc
,
5794 Prefix
=> New_Reference_To
(B
, Loc
),
5795 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
5798 Make_Indexed_Component
(Loc
,
5799 Prefix
=> New_Reference_To
(C
, Loc
),
5800 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
5802 if Nkind
(N
) = N_Op_And
then
5808 elsif Nkind
(N
) = N_Op_Or
then
5822 Make_Implicit_Loop_Statement
(N
,
5823 Identifier
=> Empty
,
5826 Make_Iteration_Scheme
(Loc
,
5827 Loop_Parameter_Specification
=>
5828 Make_Loop_Parameter_Specification
(Loc
,
5829 Defining_Identifier
=> J
,
5830 Discrete_Subtype_Definition
=>
5831 Make_Attribute_Reference
(Loc
,
5832 Prefix
=> New_Reference_To
(A
, Loc
),
5833 Attribute_Name
=> Name_Range
))),
5835 Statements
=> New_List
(
5836 Make_Assignment_Statement
(Loc
,
5838 Expression
=> Op
)));
5840 Formals
:= New_List
(
5841 Make_Parameter_Specification
(Loc
,
5842 Defining_Identifier
=> A
,
5843 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)),
5845 Make_Parameter_Specification
(Loc
,
5846 Defining_Identifier
=> B
,
5847 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)));
5850 Make_Defining_Identifier
(Loc
, New_Internal_Name
('A'));
5851 Set_Is_Inlined
(Func_Name
);
5854 Make_Subprogram_Body
(Loc
,
5856 Make_Function_Specification
(Loc
,
5857 Defining_Unit_Name
=> Func_Name
,
5858 Parameter_Specifications
=> Formals
,
5859 Subtype_Mark
=> New_Reference_To
(Typ
, Loc
)),
5861 Declarations
=> New_List
(
5862 Make_Object_Declaration
(Loc
,
5863 Defining_Identifier
=> C
,
5864 Object_Definition
=> New_Reference_To
(Typ
, Loc
))),
5866 Handled_Statement_Sequence
=>
5867 Make_Handled_Sequence_Of_Statements
(Loc
,
5868 Statements
=> New_List
(
5870 Make_Return_Statement
(Loc
,
5871 Expression
=> New_Reference_To
(C
, Loc
)))));
5874 end Make_Boolean_Array_Op
;
5876 ------------------------
5877 -- Rewrite_Comparison --
5878 ------------------------
5880 procedure Rewrite_Comparison
(N
: Node_Id
) is
5881 Typ
: constant Entity_Id
:= Etype
(N
);
5882 Op1
: constant Node_Id
:= Left_Opnd
(N
);
5883 Op2
: constant Node_Id
:= Right_Opnd
(N
);
5885 Res
: constant Compare_Result
:= Compile_Time_Compare
(Op1
, Op2
);
5886 -- Res indicates if compare outcome can be determined at compile time
5888 True_Result
: Boolean;
5889 False_Result
: Boolean;
5892 case N_Op_Compare
(Nkind
(N
)) is
5894 True_Result
:= Res
= EQ
;
5895 False_Result
:= Res
= LT
or else Res
= GT
or else Res
= NE
;
5898 True_Result
:= Res
in Compare_GE
;
5899 False_Result
:= Res
= LT
;
5902 True_Result
:= Res
= GT
;
5903 False_Result
:= Res
in Compare_LE
;
5906 True_Result
:= Res
= LT
;
5907 False_Result
:= Res
in Compare_GE
;
5910 True_Result
:= Res
in Compare_LE
;
5911 False_Result
:= Res
= GT
;
5914 True_Result
:= Res
= NE
;
5915 False_Result
:= Res
= LT
or else Res
= GT
or else Res
= EQ
;
5920 Convert_To
(Typ
, New_Occurrence_Of
(Standard_True
, Sloc
(N
))));
5921 Analyze_And_Resolve
(N
, Typ
);
5923 elsif False_Result
then
5925 Convert_To
(Typ
, New_Occurrence_Of
(Standard_False
, Sloc
(N
))));
5926 Analyze_And_Resolve
(N
, Typ
);
5928 end Rewrite_Comparison
;
5930 -----------------------
5931 -- Tagged_Membership --
5932 -----------------------
5934 -- There are two different cases to consider depending on whether
5935 -- the right operand is a class-wide type or not. If not we just
5936 -- compare the actual tag of the left expr to the target type tag:
5938 -- Left_Expr.Tag = Right_Type'Tag;
5940 -- If it is a class-wide type we use the RT function CW_Membership which
5941 -- is usually implemented by looking in the ancestor tables contained in
5942 -- the dispatch table pointed by Left_Expr.Tag for Typ'Tag
5944 function Tagged_Membership
(N
: Node_Id
) return Node_Id
is
5945 Left
: constant Node_Id
:= Left_Opnd
(N
);
5946 Right
: constant Node_Id
:= Right_Opnd
(N
);
5947 Loc
: constant Source_Ptr
:= Sloc
(N
);
5949 Left_Type
: Entity_Id
;
5950 Right_Type
: Entity_Id
;
5954 Left_Type
:= Etype
(Left
);
5955 Right_Type
:= Etype
(Right
);
5957 if Is_Class_Wide_Type
(Left_Type
) then
5958 Left_Type
:= Root_Type
(Left_Type
);
5962 Make_Selected_Component
(Loc
,
5963 Prefix
=> Relocate_Node
(Left
),
5964 Selector_Name
=> New_Reference_To
(Tag_Component
(Left_Type
), Loc
));
5966 if Is_Class_Wide_Type
(Right_Type
) then
5968 Make_DT_Access_Action
(Left_Type
,
5969 Action
=> CW_Membership
,
5973 Access_Disp_Table
(Root_Type
(Right_Type
)), Loc
)));
5977 Left_Opnd
=> Obj_Tag
,
5979 New_Reference_To
(Access_Disp_Table
(Right_Type
), Loc
));
5982 end Tagged_Membership
;
5984 ------------------------------
5985 -- Unary_Op_Validity_Checks --
5986 ------------------------------
5988 procedure Unary_Op_Validity_Checks
(N
: Node_Id
) is
5990 if Validity_Checks_On
and Validity_Check_Operands
then
5991 Ensure_Valid
(Right_Opnd
(N
));
5993 end Unary_Op_Validity_Checks
;