Daily bump.
[official-gcc.git] / gcc / ada / exp_intr.adb
blob53be18f7e39d37a1751a77b021c4396ceeb8e58a
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ I N T R --
6 -- --
7 -- B o d y --
8 -- --
9 -- $Revision: 1.76 $
10 -- --
11 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
12 -- --
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. --
23 -- --
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). --
26 -- --
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;
45 with Sem; use Sem;
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);
109 P : Node_Id;
110 E : Entity_Id;
111 S : String_Id;
113 begin
114 -- Climb up parents to see if we are in exception handler
116 P := Parent (N);
117 loop
118 -- Case of not in exception handler
120 if No (P) then
121 Start_String;
122 S := End_String;
123 Rewrite (N,
124 Make_String_Literal (Loc,
125 Strval => S));
126 exit;
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);
142 end if;
144 Rewrite (N,
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))));
149 exit;
151 -- Keep climbing!
153 else
154 P := Parent (P);
155 end if;
156 end loop;
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);
174 Dum : Entity_Id;
176 begin
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,
182 Object_Definition =>
183 New_Occurrence_Of (Standard_Character, Loc)),
185 Make_Pragma (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))))));
198 Rewrite (N,
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
212 Nam : Name_Id;
214 begin
215 -- If the intrinsic subprogram is generic, gets its original name.
217 if Present (Parent (E))
218 and then Present (Generic_Parent (Parent (E)))
219 then
220 Nam := Chars (Generic_Parent (Parent (E)));
221 else
222 Nam := Chars (E);
223 end if;
225 if Nam = Name_Asm then
226 Expand_Asm_Call (N);
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
241 or else
242 Nam = Name_Import_Largest_Value
243 or else
244 Nam = Name_Import_Value
245 then
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
276 then
277 Expand_Source_Info (N, E, Nam);
279 else
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));
285 end if;
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));
297 begin
299 -- We replace the function call by the following expression
301 -- if Opnd < 0.0 then
302 -- True
303 -- else
304 -- if Opnd > 0.0 then
305 -- False;
306 -- else
307 -- Float_Unsigned!(Float (Opnd)) /= 0
308 -- end if;
309 -- end if;
311 Rewrite (N,
312 Make_Conditional_Expression (Loc,
313 Expressions => New_List (
314 Make_Op_Lt (Loc,
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 (
322 Make_Op_Gt (Loc,
323 Left_Opnd => Duplicate_Subexpr (Opnd),
324 Right_Opnd => Make_Real_Literal (Loc, Ureal_0)),
326 New_Occurrence_Of (Standard_False, Loc),
328 Make_Op_Ne (Loc,
329 Left_Opnd =>
330 Unchecked_Convert_To (RTE (RE_Float_Unsigned),
331 Convert_To (Standard_Float,
332 Duplicate_Subexpr (Opnd))),
333 Right_Opnd =>
334 Make_Integer_Literal (Loc, 0)))))));
336 Analyze_And_Resolve (N, Standard_Boolean);
337 end Expand_Is_Negative;
339 ------------------
340 -- Expand_Shift --
341 ------------------
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);
363 Snode : Node_Id;
365 begin
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)
375 then
376 Set_Shift_Count_OK (Snode, True);
377 end if;
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!
383 Rewrite (N, Snode);
384 Set_Analyzed (N);
386 end Expand_Shift;
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);
394 Ent : Entity_Id;
396 begin
397 -- Integer cases
399 if Nam = Name_Line then
400 Rewrite (N,
401 Make_Integer_Literal (Loc,
402 Intval => UI_From_Int (Int (Get_Logical_Line_Number (Loc)))));
403 Analyze_And_Resolve (N, Standard_Positive);
405 -- String cases
407 else
408 case Nam is
409 when Name_File =>
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 =>
417 Name_Len := 0;
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;
426 Ent := Scope (Ent);
427 end loop;
429 -- Ent now points to the relevant defining entity
431 declare
432 SDef : Source_Ptr := Sloc (Ent);
433 TDef : Source_Buffer_Ptr;
435 begin
436 TDef := Source_Text (Get_Source_File_Index (SDef));
437 Name_Len := 0;
439 while TDef (SDef) in '0' .. '9'
440 or else TDef (SDef) >= 'A'
441 or else TDef (SDef) = ASCII.ESC
442 loop
443 Add_Char_To_Name_Buffer (TDef (SDef));
444 SDef := SDef + 1;
445 end loop;
446 end;
448 when others =>
449 raise Program_Error;
450 end case;
452 Rewrite (N,
453 Make_String_Literal (Loc, Strval => String_From_Name_Buffer));
454 Analyze_And_Resolve (N, Standard_String);
455 end if;
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));
466 Conv : Node_Id;
467 Ftyp : Entity_Id;
469 begin
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);
487 end if;
489 -- We do the analysis here, because we do not want the compiler
490 -- to try to optimize or otherwise reorganize the unchecked
491 -- conversion node.
493 Rewrite (N, Unchecked_Convert_To (Etype (E), Conv));
494 Set_Etype (N, Etype (E));
495 Set_Analyzed (N);
497 if Nkind (N) = N_Unchecked_Type_Conversion then
498 Expand_N_Unchecked_Type_Conversion (N);
499 end if;
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
510 -- Free (Arg);
511 -- Arg := Null;
512 -- end if;
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);
527 Gen_Code : Node_Id;
528 Free_Node : Node_Id;
529 Deref : Node_Id;
530 Free_Arg : Node_Id;
531 Free_Cod : List_Id;
532 Blk : Node_Id;
534 begin
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)
545 then
546 Deref := Unchecked_Convert_To (Class_Wide_Type (Desig_T), Deref);
547 end if;
549 Free_Cod :=
550 Make_Final_Call
551 (Ref => Deref,
552 Typ => Desig_T,
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));
559 Blk :=
560 Make_Block_Statement (Loc, Handled_Statement_Sequence =>
561 Make_Handled_Sequence_Of_Statements (Loc,
562 Statements => Free_Cod,
563 At_End_Proc =>
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
568 -- to the tree yet.
570 Set_Parent (Blk, N);
571 Analyze (Blk);
572 Expand_At_End_Handler
573 (Handled_Statement_Sequence (Blk), Entity (Identifier (Blk)));
574 Append (Blk, Stmts);
576 else
577 Append_List_To (Stmts, Free_Cod);
578 end if;
579 end if;
581 -- For a task type, call Free_Task before freeing the ATCB.
583 if Is_Task_Type (Desig_T) then
585 declare
586 Stat : Node_Id := Prev (N);
587 Nam1 : Node_Id;
588 Nam2 : Node_Id;
590 begin
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.
595 while Present (Stat)
596 and then not Comes_From_Source (Original_Node (Stat))
597 loop
598 Prev (Stat);
599 end loop;
601 if Present (Stat)
602 and then Nkind (Original_Node (Stat)) = N_Abort_Statement
603 then
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)
612 then
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);
616 end if;
617 end if;
618 end;
620 Append_To (Stmts,
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)))));
625 end if;
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
631 Append_To (Stmts,
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)))));
636 end if;
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.
654 declare
655 Test_Needed : Boolean := True;
656 P : constant Node_Id := Parent (N);
657 C : Node_Id;
659 begin
660 if Nkind (Arg) = N_Identifier
661 and then Nkind (P) = N_If_Statement
662 and then First (Then_Statements (P)) = N
663 then
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
671 then
672 Test_Needed := False;
673 end if;
674 end if;
675 end if;
677 -- Generate If_Statement if needed
679 if Test_Needed then
680 Gen_Code :=
681 Make_Implicit_If_Statement (N,
682 Condition =>
683 Make_Op_Ne (Loc,
684 Left_Opnd => Duplicate_Subexpr (Arg),
685 Right_Opnd => Make_Null (Loc)),
686 Then_Statements => Stmts);
688 else
689 Gen_Code :=
690 Make_Block_Statement (Loc,
691 Handled_Statement_Sequence =>
692 Make_Handled_Sequence_Of_Statements (Loc,
693 Statements => Stmts));
694 end if;
695 end;
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
704 null;
706 else
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
715 declare
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));
722 begin
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
730 (Deref, Desig_T)));
732 Free_Arg := Unchecked_Convert_To (Acc_Type, Free_Arg);
733 end;
734 end if;
735 end if;
736 end if;
738 Set_Expression (Free_Node, Free_Arg);
740 declare
741 Lhs : Node_Id := Duplicate_Subexpr (Arg);
743 begin
744 Set_Assignment_OK (Lhs);
745 Append_To (Stmts,
746 Make_Assignment_Statement (Loc,
747 Name => Lhs,
748 Expression => Make_Null (Loc)));
749 end;
751 Rewrite (N, Gen_Code);
752 Analyze (N);
753 end Expand_Unc_Deallocation;
755 end Exp_Intr;