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 Einfo
; use Einfo
;
31 with Errout
; use Errout
;
32 with Exp_Ch4
; use Exp_Ch4
;
33 with Exp_Ch7
; use Exp_Ch7
;
34 with Exp_Ch9
; use Exp_Ch9
;
35 with Exp_Ch11
; use Exp_Ch11
;
36 with Exp_Code
; use Exp_Code
;
37 with Exp_Fixd
; use Exp_Fixd
;
38 with Exp_Util
; use Exp_Util
;
39 with Itypes
; use Itypes
;
40 with Namet
; use Namet
;
41 with Nmake
; use Nmake
;
42 with Nlists
; use Nlists
;
43 with Restrict
; use Restrict
;
44 with Rtsfind
; use Rtsfind
;
46 with Sem_Eval
; use Sem_Eval
;
47 with Sem_Res
; use Sem_Res
;
48 with Sem_Util
; use Sem_Util
;
49 with Sinfo
; use Sinfo
;
50 with Sinput
; use Sinput
;
51 with Snames
; use Snames
;
52 with Stand
; use Stand
;
53 with Stringt
; use Stringt
;
54 with Tbuild
; use Tbuild
;
55 with Uintp
; use Uintp
;
56 with Urealp
; use Urealp
;
58 package body Exp_Intr
is
60 -----------------------
61 -- Local Subprograms --
62 -----------------------
64 procedure Expand_Is_Negative
(N
: Node_Id
);
65 -- Expand a call to the intrinsic Is_Negative function
67 procedure Expand_Exception_Call
(N
: Node_Id
; Ent
: RE_Id
);
68 -- Expand a call to Exception_Information/Message/Name. The first
69 -- parameter, N, is the node for the function call, and Ent is the
70 -- entity for the corresponding routine in the Ada.Exceptions package.
72 procedure Expand_Import_Call
(N
: Node_Id
);
73 -- Expand a call to Import_Address/Longest_Integer/Value. The parameter
74 -- N is the node for the function call.
76 procedure Expand_Shift
(N
: Node_Id
; E
: Entity_Id
; K
: Node_Kind
);
77 -- Expand an intrinsic shift operation, N and E are from the call to
78 -- Expand_Instrinsic_Call (call node and subprogram spec entity) and
79 -- K is the kind for the shift node
81 procedure Expand_Unc_Conversion
(N
: Node_Id
; E
: Entity_Id
);
82 -- Expand a call to an instantiation of Unchecked_Convertion into a node
83 -- N_Unchecked_Type_Conversion.
85 procedure Expand_Unc_Deallocation
(N
: Node_Id
; E
: Entity_Id
);
86 -- Expand a call to an instantiation of Unchecked_Deallocation into a node
87 -- N_Free_Statement and appropriate context.
89 procedure Expand_Source_Info
(N
: Node_Id
; E
: Entity_Id
; Nam
: Name_Id
);
90 -- Rewrite the node by the appropriate string or positive constant.
91 -- Nam can be one of the following:
92 -- Name_File - expand string that is the name of source file
93 -- Name_Line - expand integer line number
94 -- Name_Source_Location - expand string of form file:line
95 -- Name_Enclosing_Entity - expand string with name of enclosing entity
97 ---------------------------
98 -- Expand_Exception_Call --
99 ---------------------------
101 -- If the function call is not within an exception handler, then the
102 -- call is replaced by a null string. Otherwise the appropriate routine
103 -- in Ada.Exceptions is called passing the choice parameter specification
104 -- from the enclosing handler. If the enclosing handler lacks a choice
105 -- parameter, then one is supplied.
107 procedure Expand_Exception_Call
(N
: Node_Id
; Ent
: RE_Id
) is
108 Loc
: constant Source_Ptr
:= Sloc
(N
);
114 -- Climb up parents to see if we are in exception handler
118 -- Case of not in exception handler
124 Make_String_Literal
(Loc
,
128 -- Case of in exception handler
130 elsif Nkind
(P
) = N_Exception_Handler
then
131 if No
(Choice_Parameter
(P
)) then
133 -- If no choice parameter present, then put one there. Note
134 -- that we do not need to put it on the entity chain, since
135 -- no one will be referencing it by normal visibility methods.
137 E
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('E'));
138 Set_Choice_Parameter
(P
, E
);
139 Set_Ekind
(E
, E_Variable
);
140 Set_Etype
(E
, RTE
(RE_Exception_Occurrence
));
141 Set_Scope
(E
, Current_Scope
);
145 Make_Function_Call
(Loc
,
146 Name
=> New_Occurrence_Of
(RTE
(Ent
), Loc
),
147 Parameter_Associations
=> New_List
(
148 New_Occurrence_Of
(Choice_Parameter
(P
), Loc
))));
158 Analyze_And_Resolve
(N
, Standard_String
);
159 end Expand_Exception_Call
;
161 ------------------------
162 -- Expand_Import_Call --
163 ------------------------
165 -- The function call must have a static string as its argument. We create
166 -- a dummy variable which uses this string as the external name in an
167 -- Import pragma. The result is then obtained as the address of this
168 -- dummy variable, converted to the appropriate target type.
170 procedure Expand_Import_Call
(N
: Node_Id
) is
171 Loc
: constant Source_Ptr
:= Sloc
(N
);
172 Ent
: constant Entity_Id
:= Entity
(Name
(N
));
173 Str
: constant Node_Id
:= First_Actual
(N
);
177 Dum
:= Make_Defining_Identifier
(Loc
, New_Internal_Name
('D'));
179 Insert_Actions
(N
, New_List
(
180 Make_Object_Declaration
(Loc
,
181 Defining_Identifier
=> Dum
,
183 New_Occurrence_Of
(Standard_Character
, Loc
)),
186 Chars
=> Name_Import
,
187 Pragma_Argument_Associations
=> New_List
(
188 Make_Pragma_Argument_Association
(Loc
,
189 Expression
=> Make_Identifier
(Loc
, Name_Ada
)),
191 Make_Pragma_Argument_Association
(Loc
,
192 Expression
=> Make_Identifier
(Loc
, Chars
(Dum
))),
194 Make_Pragma_Argument_Association
(Loc
,
195 Chars
=> Name_Link_Name
,
196 Expression
=> Relocate_Node
(Str
))))));
199 Unchecked_Convert_To
(Etype
(Ent
),
200 Make_Attribute_Reference
(Loc
,
201 Attribute_Name
=> Name_Address
,
202 Prefix
=> Make_Identifier
(Loc
, Chars
(Dum
)))));
204 Analyze_And_Resolve
(N
, Etype
(Ent
));
205 end Expand_Import_Call
;
207 ---------------------------
208 -- Expand_Intrinsic_Call --
209 ---------------------------
211 procedure Expand_Intrinsic_Call
(N
: Node_Id
; E
: Entity_Id
) is
215 -- If the intrinsic subprogram is generic, gets its original name.
217 if Present
(Parent
(E
))
218 and then Present
(Generic_Parent
(Parent
(E
)))
220 Nam
:= Chars
(Generic_Parent
(Parent
(E
)));
225 if Nam
= Name_Asm
then
228 elsif Nam
= Name_Divide
then
229 Expand_Decimal_Divide_Call
(N
);
231 elsif Nam
= Name_Exception_Information
then
232 Expand_Exception_Call
(N
, RE_Exception_Information
);
234 elsif Nam
= Name_Exception_Message
then
235 Expand_Exception_Call
(N
, RE_Exception_Message
);
237 elsif Nam
= Name_Exception_Name
then
238 Expand_Exception_Call
(N
, RE_Exception_Name_Simple
);
240 elsif Nam
= Name_Import_Address
242 Nam
= Name_Import_Largest_Value
244 Nam
= Name_Import_Value
246 Expand_Import_Call
(N
);
248 elsif Nam
= Name_Is_Negative
then
249 Expand_Is_Negative
(N
);
251 elsif Nam
= Name_Rotate_Left
then
252 Expand_Shift
(N
, E
, N_Op_Rotate_Left
);
254 elsif Nam
= Name_Rotate_Right
then
255 Expand_Shift
(N
, E
, N_Op_Rotate_Right
);
257 elsif Nam
= Name_Shift_Left
then
258 Expand_Shift
(N
, E
, N_Op_Shift_Left
);
260 elsif Nam
= Name_Shift_Right
then
261 Expand_Shift
(N
, E
, N_Op_Shift_Right
);
263 elsif Nam
= Name_Shift_Right_Arithmetic
then
264 Expand_Shift
(N
, E
, N_Op_Shift_Right_Arithmetic
);
266 elsif Nam
= Name_Unchecked_Conversion
then
267 Expand_Unc_Conversion
(N
, E
);
269 elsif Nam
= Name_Unchecked_Deallocation
then
270 Expand_Unc_Deallocation
(N
, E
);
272 elsif Nam
= Name_File
273 or else Nam
= Name_Line
274 or else Nam
= Name_Source_Location
275 or else Nam
= Name_Enclosing_Entity
277 Expand_Source_Info
(N
, E
, Nam
);
280 -- Only other possibility is a renaming, in which case we expand
281 -- the call to the original operation (which must be intrinsic).
283 pragma Assert
(Present
(Alias
(E
)));
284 Expand_Intrinsic_Call
(N
, Alias
(E
));
287 end Expand_Intrinsic_Call
;
289 ------------------------
290 -- Expand_Is_Negative --
291 ------------------------
293 procedure Expand_Is_Negative
(N
: Node_Id
) is
294 Loc
: constant Source_Ptr
:= Sloc
(N
);
295 Opnd
: constant Node_Id
:= Relocate_Node
(First_Actual
(N
));
299 -- We replace the function call by the following expression
301 -- if Opnd < 0.0 then
304 -- if Opnd > 0.0 then
307 -- Float_Unsigned!(Float (Opnd)) /= 0
312 Make_Conditional_Expression
(Loc
,
313 Expressions
=> New_List
(
315 Left_Opnd
=> Duplicate_Subexpr
(Opnd
),
316 Right_Opnd
=> Make_Real_Literal
(Loc
, Ureal_0
)),
318 New_Occurrence_Of
(Standard_True
, Loc
),
320 Make_Conditional_Expression
(Loc
,
321 Expressions
=> New_List
(
323 Left_Opnd
=> Duplicate_Subexpr
(Opnd
),
324 Right_Opnd
=> Make_Real_Literal
(Loc
, Ureal_0
)),
326 New_Occurrence_Of
(Standard_False
, Loc
),
330 Unchecked_Convert_To
(RTE
(RE_Float_Unsigned
),
331 Convert_To
(Standard_Float
,
332 Duplicate_Subexpr
(Opnd
))),
334 Make_Integer_Literal
(Loc
, 0)))))));
336 Analyze_And_Resolve
(N
, Standard_Boolean
);
337 end Expand_Is_Negative
;
343 -- This procedure is used to convert a call to a shift function to the
344 -- corresponding operator node. This conversion is not done by the usual
345 -- circuit for converting calls to operator functions (e.g. "+"(1,2)) to
346 -- operator nodes, because shifts are not predefined operators.
348 -- As a result, whenever a shift is used in the source program, it will
349 -- remain as a call until converted by this routine to the operator node
350 -- form which Gigi is expecting to see.
352 -- Note: it is possible for the expander to generate shift operator nodes
353 -- directly, which will be analyzed in the normal manner by calling Analyze
354 -- and Resolve. Such shift operator nodes will not be seen by Expand_Shift.
356 procedure Expand_Shift
(N
: Node_Id
; E
: Entity_Id
; K
: Node_Kind
) is
357 Loc
: constant Source_Ptr
:= Sloc
(N
);
358 Typ
: constant Entity_Id
:= Etype
(N
);
359 Left
: constant Node_Id
:= First_Actual
(N
);
360 Right
: constant Node_Id
:= Next_Actual
(Left
);
361 Ltyp
: constant Node_Id
:= Etype
(Left
);
362 Rtyp
: constant Node_Id
:= Etype
(Right
);
366 Snode
:= New_Node
(K
, Loc
);
367 Set_Left_Opnd
(Snode
, Relocate_Node
(Left
));
368 Set_Right_Opnd
(Snode
, Relocate_Node
(Right
));
369 Set_Chars
(Snode
, Chars
(E
));
370 Set_Etype
(Snode
, Base_Type
(Typ
));
371 Set_Entity
(Snode
, E
);
373 if Compile_Time_Known_Value
(Type_High_Bound
(Rtyp
))
374 and then Expr_Value
(Type_High_Bound
(Rtyp
)) < Esize
(Ltyp
)
376 Set_Shift_Count_OK
(Snode
, True);
379 -- Do the rewrite. Note that we don't call Analyze and Resolve on
380 -- this node, because it already got analyzed and resolved when
381 -- it was a function call!
388 ------------------------
389 -- Expand_Source_Info --
390 ------------------------
392 procedure Expand_Source_Info
(N
: Node_Id
; E
: Entity_Id
; Nam
: Name_Id
) is
393 Loc
: constant Source_Ptr
:= Sloc
(N
);
399 if Nam
= Name_Line
then
401 Make_Integer_Literal
(Loc
,
402 Intval
=> UI_From_Int
(Int
(Get_Logical_Line_Number
(Loc
)))));
403 Analyze_And_Resolve
(N
, Standard_Positive
);
410 Get_Decoded_Name_String
411 (Reference_Name
(Get_Source_File_Index
(Loc
)));
413 when Name_Source_Location
=>
414 Build_Location_String
(Loc
);
416 when Name_Enclosing_Entity
=>
419 Ent
:= Current_Scope
;
421 -- Skip enclosing blocks to reach enclosing unit.
423 while Present
(Ent
) loop
424 exit when Ekind
(Ent
) /= E_Block
425 and then Ekind
(Ent
) /= E_Loop
;
429 -- Ent now points to the relevant defining entity
432 SDef
: Source_Ptr
:= Sloc
(Ent
);
433 TDef
: Source_Buffer_Ptr
;
436 TDef
:= Source_Text
(Get_Source_File_Index
(SDef
));
439 while TDef
(SDef
) in '0' .. '9'
440 or else TDef
(SDef
) >= 'A'
441 or else TDef
(SDef
) = ASCII
.ESC
443 Add_Char_To_Name_Buffer
(TDef
(SDef
));
453 Make_String_Literal
(Loc
, Strval
=> String_From_Name_Buffer
));
454 Analyze_And_Resolve
(N
, Standard_String
);
457 Set_Is_Static_Expression
(N
);
458 end Expand_Source_Info
;
460 ---------------------------
461 -- Expand_Unc_Conversion --
462 ---------------------------
464 procedure Expand_Unc_Conversion
(N
: Node_Id
; E
: Entity_Id
) is
465 Func
: constant Entity_Id
:= Entity
(Name
(N
));
470 -- Rewrite as unchecked conversion node. Note that we must convert
471 -- the operand to the formal type of the input parameter of the
472 -- function, so that the resulting N_Unchecked_Type_Conversion
473 -- call indicates the correct types for Gigi.
475 -- Right now, we only do this if a scalar type is involved. It is
476 -- not clear if it is needed in other cases. If we do attempt to
477 -- do the conversion unconditionally, it crashes 3411-018. To be
478 -- investigated further ???
480 Conv
:= Relocate_Node
(First_Actual
(N
));
481 Ftyp
:= Etype
(First_Formal
(Func
));
483 if Is_Scalar_Type
(Ftyp
) then
484 Conv
:= Convert_To
(Ftyp
, Conv
);
485 Set_Parent
(Conv
, N
);
486 Analyze_And_Resolve
(Conv
);
489 -- We do the analysis here, because we do not want the compiler
490 -- to try to optimize or otherwise reorganize the unchecked
493 Rewrite
(N
, Unchecked_Convert_To
(Etype
(E
), Conv
));
494 Set_Etype
(N
, Etype
(E
));
497 if Nkind
(N
) = N_Unchecked_Type_Conversion
then
498 Expand_N_Unchecked_Type_Conversion
(N
);
500 end Expand_Unc_Conversion
;
502 -----------------------------
503 -- Expand_Unc_Deallocation --
504 -----------------------------
506 -- Generate the following Code :
508 -- if Arg /= null then
509 -- <Finalize_Call> (.., T'Class(Arg.all), ..); -- for controlled types
514 -- For a task, we also generate a call to Free_Task to ensure that the
515 -- task itself is freed if it is terminated, ditto for a simple protected
516 -- object, with a call to Finalize_Protection
518 procedure Expand_Unc_Deallocation
(N
: Node_Id
; E
: Entity_Id
) is
519 Loc
: constant Source_Ptr
:= Sloc
(N
);
520 Arg
: constant Node_Id
:= First_Actual
(N
);
521 Typ
: constant Entity_Id
:= Etype
(Arg
);
522 Stmts
: constant List_Id
:= New_List
;
523 Pool
: constant Entity_Id
:=
524 Associated_Storage_Pool
(Underlying_Type
(Root_Type
(Typ
)));
526 Desig_T
: Entity_Id
:= Designated_Type
(Typ
);
535 if Controlled_Type
(Desig_T
) then
537 Deref
:= Make_Explicit_Dereference
(Loc
, Duplicate_Subexpr
(Arg
));
539 -- If the type is tagged, then we must force dispatching on the
540 -- finalization call because the designated type may not be the
541 -- actual type of the object
543 if Is_Tagged_Type
(Desig_T
)
544 and then not Is_Class_Wide_Type
(Desig_T
)
546 Deref
:= Unchecked_Convert_To
(Class_Wide_Type
(Desig_T
), Deref
);
553 With_Detach
=> New_Reference_To
(Standard_True
, Loc
));
555 if Abort_Allowed
then
556 Prepend_To
(Free_Cod
,
557 Build_Runtime_Call
(Loc
, RE_Abort_Defer
));
560 Make_Block_Statement
(Loc
, Handled_Statement_Sequence
=>
561 Make_Handled_Sequence_Of_Statements
(Loc
,
562 Statements
=> Free_Cod
,
564 New_Occurrence_Of
(RTE
(RE_Abort_Undefer_Direct
), Loc
)));
566 -- We now expand the exception (at end) handler. We set a
567 -- temporary parent pointer since we have not attached Blk
572 Expand_At_End_Handler
573 (Handled_Statement_Sequence
(Blk
), Entity
(Identifier
(Blk
)));
577 Append_List_To
(Stmts
, Free_Cod
);
581 -- For a task type, call Free_Task before freeing the ATCB.
583 if Is_Task_Type
(Desig_T
) then
586 Stat
: Node_Id
:= Prev
(N
);
591 -- An Abort followed by a Free will not do what the user
592 -- expects, because the abort is not immediate. This is worth
593 -- a friendly warning.
596 and then not Comes_From_Source
(Original_Node
(Stat
))
602 and then Nkind
(Original_Node
(Stat
)) = N_Abort_Statement
604 Stat
:= Original_Node
(Stat
);
605 Nam1
:= First
(Names
(Stat
));
606 Nam2
:= Original_Node
(First
(Parameter_Associations
(N
)));
608 if Nkind
(Nam1
) = N_Explicit_Dereference
609 and then Is_Entity_Name
(Prefix
(Nam1
))
610 and then Is_Entity_Name
(Nam2
)
611 and then Entity
(Prefix
(Nam1
)) = Entity
(Nam2
)
613 Error_Msg_N
("Abort may take time to complete?", N
);
614 Error_Msg_N
("\deallocation might have no effect?", N
);
615 Error_Msg_N
("\safer to wait for termination.?", N
);
621 Make_Procedure_Call_Statement
(Loc
,
622 Name
=> New_Reference_To
(RTE
(RE_Free_Task
), Loc
),
623 Parameter_Associations
=> New_List
(
624 Concurrent_Ref
(Duplicate_Subexpr
(Arg
)))));
627 -- For a protected type with no entries, call Finalize_Protection
628 -- before freeing the PO.
630 if Is_Protected_Type
(Desig_T
) and then not Has_Entries
(Desig_T
) then
632 Make_Procedure_Call_Statement
(Loc
,
633 Name
=> New_Reference_To
(RTE
(RE_Finalize_Protection
), Loc
),
634 Parameter_Associations
=> New_List
(
635 Concurrent_Ref
(Duplicate_Subexpr
(Arg
)))));
638 -- Normal processing for non-controlled types
640 Free_Arg
:= Duplicate_Subexpr
(Arg
);
641 Free_Node
:= Make_Free_Statement
(Loc
, Empty
);
642 Append_To
(Stmts
, Free_Node
);
643 Set_Storage_Pool
(Free_Node
, Pool
);
645 -- Make implicit if statement. We omit this if we are the then part
646 -- of a test of the form:
648 -- if not (Arg = null) then
650 -- i.e. if the test is explicit in the source. Arg must be a simple
651 -- identifier for the purposes of this special test. Note that the
652 -- use of /= in the source is always transformed into the above form.
655 Test_Needed
: Boolean := True;
656 P
: constant Node_Id
:= Parent
(N
);
660 if Nkind
(Arg
) = N_Identifier
661 and then Nkind
(P
) = N_If_Statement
662 and then First
(Then_Statements
(P
)) = N
664 if Nkind
(Condition
(P
)) = N_Op_Not
then
665 C
:= Right_Opnd
(Condition
(P
));
667 if Nkind
(C
) = N_Op_Eq
668 and then Nkind
(Left_Opnd
(C
)) = N_Identifier
669 and then Chars
(Arg
) = Chars
(Left_Opnd
(C
))
670 and then Nkind
(Right_Opnd
(C
)) = N_Null
672 Test_Needed
:= False;
677 -- Generate If_Statement if needed
681 Make_Implicit_If_Statement
(N
,
684 Left_Opnd
=> Duplicate_Subexpr
(Arg
),
685 Right_Opnd
=> Make_Null
(Loc
)),
686 Then_Statements
=> Stmts
);
690 Make_Block_Statement
(Loc
,
691 Handled_Statement_Sequence
=>
692 Make_Handled_Sequence_Of_Statements
(Loc
,
693 Statements
=> Stmts
));
697 -- Deal with storage pool
699 if Present
(Pool
) then
701 -- Freeing the secondary stack is meaningless
703 if Is_RTE
(Pool
, RE_SS_Pool
) then
707 Set_Procedure_To_Call
(Free_Node
,
708 Find_Prim_Op
(Etype
(Pool
), Name_Deallocate
));
710 -- If the type is class wide, we generate an implicit type
711 -- with the right dynamic size, so that the deallocate call
712 -- gets the right size parameter computed by gigi
714 if Is_Class_Wide_Type
(Desig_T
) then
716 Acc_Type
: constant Entity_Id
:=
717 Create_Itype
(E_Access_Type
, N
);
718 Deref
: constant Node_Id
:=
719 Make_Explicit_Dereference
(Loc
,
720 Duplicate_Subexpr
(Arg
));
723 Set_Etype
(Deref
, Typ
);
724 Set_Parent
(Deref
, Free_Node
);
726 Set_Etype
(Acc_Type
, Acc_Type
);
727 Set_Size_Info
(Acc_Type
, Typ
);
728 Set_Directly_Designated_Type
729 (Acc_Type
, Entity
(Make_Subtype_From_Expr
732 Free_Arg
:= Unchecked_Convert_To
(Acc_Type
, Free_Arg
);
738 Set_Expression
(Free_Node
, Free_Arg
);
741 Lhs
: Node_Id
:= Duplicate_Subexpr
(Arg
);
744 Set_Assignment_OK
(Lhs
);
746 Make_Assignment_Statement
(Loc
,
748 Expression
=> Make_Null
(Loc
)));
751 Rewrite
(N
, Gen_Code
);
753 end Expand_Unc_Deallocation
;