ada: Update copyright notice
[official-gcc.git] / gcc / ada / exp_intr.adb
bloba1e55882391ee2628aae0ec3d5e779ce71badeb6
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ I N T R --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2023, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
26 with Atree; use Atree;
27 with Aspects; use Aspects;
28 with Checks; use Checks;
29 with Einfo; use Einfo;
30 with Einfo.Entities; use Einfo.Entities;
31 with Einfo.Utils; use Einfo.Utils;
32 with Elists; use Elists;
33 with Errout; use Errout;
34 with Expander; use Expander;
35 with Exp_Atag; use Exp_Atag;
36 with Exp_Ch6; use Exp_Ch6;
37 with Exp_Ch7; use Exp_Ch7;
38 with Exp_Ch11; use Exp_Ch11;
39 with Exp_Code; use Exp_Code;
40 with Exp_Fixd; use Exp_Fixd;
41 with Exp_Util; use Exp_Util;
42 with Freeze; use Freeze;
43 with Inline; use Inline;
44 with Nmake; use Nmake;
45 with Nlists; use Nlists;
46 with Opt; use Opt;
47 with Restrict; use Restrict;
48 with Rident; use Rident;
49 with Rtsfind; use Rtsfind;
50 with Sem; use Sem;
51 with Sem_Aux; use Sem_Aux;
52 with Sem_Eval; use Sem_Eval;
53 with Sem_Res; use Sem_Res;
54 with Sem_Type; use Sem_Type;
55 with Sem_Util; use Sem_Util;
56 with Sinfo; use Sinfo;
57 with Sinfo.Nodes; use Sinfo.Nodes;
58 with Sinfo.Utils; use Sinfo.Utils;
59 with Sinput; use Sinput;
60 with Snames; use Snames;
61 with Stand; use Stand;
62 with Tbuild; use Tbuild;
63 with Uintp; use Uintp;
65 package body Exp_Intr is
67 -----------------------
68 -- Local Subprograms --
69 -----------------------
71 procedure Expand_Binary_Operator_Call (N : Node_Id);
72 -- Expand a call to an intrinsic arithmetic operator when the operand
73 -- types or sizes are not identical.
75 procedure Expand_Dispatching_Constructor_Call (N : Node_Id);
76 -- Expand a call to an instantiation of Generic_Dispatching_Constructor
77 -- into a dispatching call to the actual subprogram associated with the
78 -- Constructor formal subprogram, passing it the Parameters actual of
79 -- the call to the instantiation and dispatching based on call's Tag
80 -- parameter.
82 procedure Expand_Exception_Call (N : Node_Id; Ent : RE_Id);
83 -- Expand a call to Exception_Information/Message/Name. The first
84 -- parameter, N, is the node for the function call, and Ent is the
85 -- entity for the corresponding routine in the Ada.Exceptions package.
87 procedure Expand_Import_Call (N : Node_Id);
88 -- Expand a call to Import_Address/Longest_Integer/Value. The parameter
89 -- N is the node for the function call.
91 procedure Expand_Shift (N : Node_Id; E : Entity_Id; K : Node_Kind);
92 -- Expand an intrinsic shift operation, N and E are from the call to
93 -- Expand_Intrinsic_Call (call node and subprogram spec entity) and
94 -- K is the kind for the shift node
96 procedure Expand_Unc_Conversion (N : Node_Id; E : Entity_Id);
97 -- Expand a call to an instantiation of Unchecked_Conversion into a node
98 -- N_Unchecked_Type_Conversion.
100 procedure Expand_Unc_Deallocation (N : Node_Id);
101 -- Expand a call to an instantiation of Unchecked_Deallocation into a node
102 -- N_Free_Statement and appropriate context.
104 procedure Expand_To_Address (N : Node_Id);
105 procedure Expand_To_Pointer (N : Node_Id);
106 -- Expand a call to corresponding function, declared in an instance of
107 -- System.Address_To_Access_Conversions.
109 procedure Expand_Source_Info (N : Node_Id; Nam : Name_Id);
110 -- Rewrite the node as the appropriate string literal or positive
111 -- constant. Nam is the name of one of the intrinsics declared in
112 -- GNAT.Source_Info; see g-souinf.ads for documentation of these
113 -- intrinsics.
115 ---------------------
116 -- Add_Source_Info --
117 ---------------------
119 procedure Add_Source_Info
120 (Buf : in out Bounded_String;
121 Loc : Source_Ptr;
122 Nam : Name_Id)
124 begin
125 case Nam is
126 when Name_Line =>
127 Append (Buf, Nat (Get_Logical_Line_Number (Loc)));
129 when Name_File =>
130 Append (Buf, Reference_Name (Get_Source_File_Index (Loc)));
132 when Name_Source_Location =>
133 Build_Location_String (Buf, Loc);
135 when Name_Enclosing_Entity =>
137 -- Skip enclosing blocks to reach enclosing unit
139 declare
140 Ent : Entity_Id := Current_Scope;
141 begin
142 while Present (Ent) loop
143 exit when Ekind (Ent) not in E_Block | E_Loop;
144 Ent := Scope (Ent);
145 end loop;
147 -- Ent now points to the relevant defining entity
149 Append_Entity_Name (Buf, Ent);
150 end;
152 when Name_Compilation_ISO_Date =>
153 Append (Buf, Opt.Compilation_Time (1 .. 10));
155 when Name_Compilation_Date =>
156 declare
157 subtype S13 is String (1 .. 3);
158 Months : constant array (1 .. 12) of S13 :=
159 ("Jan", "Feb", "Mar", "Apr", "May", "Jun",
160 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
162 M1 : constant Character := Opt.Compilation_Time (6);
163 M2 : constant Character := Opt.Compilation_Time (7);
165 MM : constant Natural range 1 .. 12 :=
166 (Character'Pos (M1) - Character'Pos ('0')) * 10 +
167 (Character'Pos (M2) - Character'Pos ('0'));
169 begin
170 -- Reformat ISO date into MMM DD YYYY (__DATE__) format
172 Append (Buf, Months (MM));
173 Append (Buf, ' ');
174 Append (Buf, Opt.Compilation_Time (9 .. 10));
175 Append (Buf, ' ');
176 Append (Buf, Opt.Compilation_Time (1 .. 4));
177 end;
179 when Name_Compilation_Time =>
180 Append (Buf, Opt.Compilation_Time (12 .. 19));
182 when others =>
183 raise Program_Error;
184 end case;
185 end Add_Source_Info;
187 ---------------------------------
188 -- Expand_Binary_Operator_Call --
189 ---------------------------------
191 procedure Expand_Binary_Operator_Call (N : Node_Id) is
192 T1 : constant Entity_Id := Underlying_Type (Etype (Left_Opnd (N)));
193 T2 : constant Entity_Id := Underlying_Type (Etype (Right_Opnd (N)));
194 TR : constant Entity_Id := Etype (N);
195 T3 : Entity_Id;
196 Res : Node_Id;
198 Siz : constant Uint := UI_Max (RM_Size (T1), RM_Size (T2));
199 -- Maximum of operand sizes
201 begin
202 -- Nothing to do if the operands have the same modular type
204 if Base_Type (T1) = Base_Type (T2)
205 and then Is_Modular_Integer_Type (T1)
206 then
207 return;
208 end if;
210 -- Use the appropriate type for the size
212 if Siz <= 32 then
213 T3 := RTE (RE_Unsigned_32);
215 elsif Siz <= 64 then
216 T3 := RTE (RE_Unsigned_64);
218 else pragma Assert (Siz <= 128);
219 T3 := RTE (RE_Unsigned_128);
220 end if;
222 -- Copy operator node, and reset type and entity fields, for
223 -- subsequent reanalysis.
225 Res := New_Copy (N);
226 Set_Etype (Res, T3);
228 case Nkind (N) is
229 when N_Op_And => Set_Entity (Res, Standard_Op_And);
230 when N_Op_Or => Set_Entity (Res, Standard_Op_Or);
231 when N_Op_Xor => Set_Entity (Res, Standard_Op_Xor);
232 when others => raise Program_Error;
233 end case;
235 -- Convert operands to large enough intermediate type
237 Set_Left_Opnd (Res,
238 Unchecked_Convert_To (T3, Relocate_Node (Left_Opnd (N))));
239 Set_Right_Opnd (Res,
240 Unchecked_Convert_To (T3, Relocate_Node (Right_Opnd (N))));
242 -- Analyze and resolve result formed by conversion to target type
244 Rewrite (N, Unchecked_Convert_To (TR, Res));
245 Analyze_And_Resolve (N, TR);
246 end Expand_Binary_Operator_Call;
248 -----------------------------------------
249 -- Expand_Dispatching_Constructor_Call --
250 -----------------------------------------
252 -- Transform a call to an instantiation of Generic_Dispatching_Constructor
253 -- of the form:
255 -- GDC_Instance (The_Tag, Parameters'Access)
257 -- to a class-wide conversion of a dispatching call to the actual
258 -- associated with the formal subprogram Construct, designating The_Tag
259 -- as the controlling tag of the call:
261 -- T'Class (Construct'Actual (Params)) -- Controlling tag is The_Tag
263 -- which will eventually be expanded to the following:
265 -- T'Class (The_Tag.all (Construct'Actual'Index).all (Params))
267 -- A class-wide membership test is also generated, preceding the call, to
268 -- ensure that the controlling tag denotes a type in T'Class.
270 procedure Expand_Dispatching_Constructor_Call (N : Node_Id) is
271 Loc : constant Source_Ptr := Sloc (N);
272 Tag_Arg : constant Node_Id := First_Actual (N);
273 Param_Arg : constant Node_Id := Next_Actual (Tag_Arg);
274 Subp_Decl : constant Node_Id := Parent (Parent (Entity (Name (N))));
275 Inst_Pkg : constant Node_Id := Parent (Subp_Decl);
276 Act_Rename : Node_Id;
277 Act_Constr : Entity_Id;
278 Iface_Tag : Node_Id := Empty;
279 Cnstr_Call : Node_Id;
280 Result_Typ : Entity_Id;
282 begin
283 pragma Assert (Is_Class_Wide_Type (Etype (Entity (Name (N)))));
285 -- Report case where we know that the generated code is wrong; that
286 -- is a dispatching constructor call whose controlling type has tasks
287 -- but its root type does not have tasks. In such case the constructor
288 -- subprogram of the root type does not have extra formals but the
289 -- constructor of the derivation must have extra formals.
291 if not Global_No_Tasking
292 and then not No_Run_Time_Mode
293 and then Is_Build_In_Place_Function (Entity (Name (N)))
294 and then not Has_Task (Root_Type (Etype (Entity (Name (N)))))
295 and then not Has_Aspect (Root_Type (Etype (Entity (Name (N)))),
296 Aspect_No_Task_Parts)
297 then
298 -- Case 1: Explicit tag reference (which allows static check)
300 if Nkind (Tag_Arg) = N_Identifier
301 and then Present (Entity (Tag_Arg))
302 and then Is_Tag (Entity (Tag_Arg))
303 then
304 if Has_Task (Related_Type (Entity (Tag_Arg))) then
305 Error_Msg_N ("unsupported dispatching constructor call", N);
306 Error_Msg_NE
307 ("\work around this problem by defining task component "
308 & "type& using access-to-task-type",
309 N, Related_Type (Entity (Tag_Arg)));
310 end if;
312 -- Case 2: Dynamic tag which may fail at run time
314 else
315 Error_Msg_N
316 ("unsupported dispatching constructor call if the type "
317 & "of the built object has task components??", N);
319 Error_Msg_Sloc := Sloc (Root_Type (Etype (Entity (Name (N)))));
320 Error_Msg_NE
321 ("\work around this by adding ''with no_task_parts'' to "
322 & "the declaration of the root type& defined#???",
323 N, Root_Type (Etype (Entity (Name (N)))));
324 end if;
325 end if;
327 -- Remove side effects from tag argument early, before rewriting
328 -- the dispatching constructor call, as Remove_Side_Effects relies
329 -- on Tag_Arg's Parent link properly attached to the tree (once the
330 -- call is rewritten, the Parent is inconsistent as it points to the
331 -- rewritten node, which is not the syntactic parent of the Tag_Arg
332 -- anymore).
334 Remove_Side_Effects (Tag_Arg);
336 -- Check that we have a proper tag
338 Insert_Action (N,
339 Make_Implicit_If_Statement (N,
340 Condition => Make_Op_Eq (Loc,
341 Left_Opnd => New_Copy_Tree (Tag_Arg),
342 Right_Opnd => New_Occurrence_Of (RTE (RE_No_Tag), Loc)),
344 Then_Statements => New_List (
345 Make_Raise_Statement (Loc,
346 New_Occurrence_Of (RTE (RE_Tag_Error), Loc)))));
348 -- Check that it is not the tag of an abstract type
350 Insert_Action (N,
351 Make_Implicit_If_Statement (N,
352 Condition => Make_Function_Call (Loc,
353 Name =>
354 New_Occurrence_Of (RTE (RE_Is_Abstract), Loc),
355 Parameter_Associations => New_List (New_Copy_Tree (Tag_Arg))),
357 Then_Statements => New_List (
358 Make_Raise_Statement (Loc,
359 New_Occurrence_Of (RTE (RE_Tag_Error), Loc)))));
361 -- The subprogram is the third actual in the instantiation, and is
362 -- retrieved from the corresponding renaming declaration. However,
363 -- freeze nodes may appear before, so we retrieve the declaration
364 -- with an explicit loop.
366 Act_Rename := First (Visible_Declarations (Inst_Pkg));
367 while Nkind (Act_Rename) /= N_Subprogram_Renaming_Declaration loop
368 Next (Act_Rename);
369 end loop;
371 Act_Constr := Entity (Name (Act_Rename));
372 Result_Typ := Class_Wide_Type (Etype (Act_Constr));
374 -- Check that the accessibility level of the tag is no deeper than that
375 -- of the constructor function (unless CodePeer_Mode).
377 if not CodePeer_Mode then
378 Insert_Action (N,
379 Make_Implicit_If_Statement (N,
380 Condition =>
381 Make_Op_Gt (Loc,
382 Left_Opnd =>
383 Build_Get_Access_Level (Loc, New_Copy_Tree (Tag_Arg)),
384 Right_Opnd =>
385 Make_Integer_Literal
386 (Loc, Scope_Depth_Default_0 (Act_Constr))),
388 Then_Statements => New_List (
389 Make_Raise_Statement (Loc,
390 New_Occurrence_Of (RTE (RE_Tag_Error), Loc)))));
391 end if;
393 if Is_Interface (Etype (Act_Constr)) then
395 -- If the result type is not known to be a parent of Tag_Arg then we
396 -- need to locate the tag of the secondary dispatch table.
398 if not Is_Ancestor (Etype (Result_Typ), Etype (Tag_Arg),
399 Use_Full_View => True)
400 and then Tagged_Type_Expansion
401 then
402 -- Obtain the reference to the Ada.Tags service before generating
403 -- the Object_Declaration node to ensure that if this service is
404 -- not available in the runtime then we generate a clear error.
406 declare
407 Fname : constant Node_Id :=
408 New_Occurrence_Of (RTE (RE_Secondary_Tag), Loc);
410 begin
411 pragma Assert (not Is_Interface (Etype (Tag_Arg)));
413 -- The tag is the first entry in the dispatch table of the
414 -- return type of the constructor.
416 Iface_Tag :=
417 Make_Object_Declaration (Loc,
418 Defining_Identifier => Make_Temporary (Loc, 'V'),
419 Object_Definition =>
420 New_Occurrence_Of (RTE (RE_Tag), Loc),
421 Expression =>
422 Make_Function_Call (Loc,
423 Name => Fname,
424 Parameter_Associations => New_List (
425 Relocate_Node (Tag_Arg),
426 New_Occurrence_Of
427 (Node (First_Elmt
428 (Access_Disp_Table (Etype (Act_Constr)))),
429 Loc))));
430 Insert_Action (N, Iface_Tag);
431 end;
432 end if;
433 end if;
435 -- Create the call to the actual Constructor function
437 Cnstr_Call :=
438 Make_Function_Call (Loc,
439 Name => New_Occurrence_Of (Act_Constr, Loc),
440 Parameter_Associations => New_List (Relocate_Node (Param_Arg)));
442 -- Establish its controlling tag from the tag passed to the instance
443 -- The tag may be given by a function call, in which case a temporary
444 -- should be generated now, to prevent out-of-order insertions during
445 -- the expansion of that call when stack-checking is enabled.
447 if Present (Iface_Tag) then
448 Set_Controlling_Argument (Cnstr_Call,
449 New_Occurrence_Of (Defining_Identifier (Iface_Tag), Loc));
450 else
451 Set_Controlling_Argument (Cnstr_Call,
452 Relocate_Node (Tag_Arg));
453 end if;
455 -- Rewrite and analyze the call to the instance as a class-wide
456 -- conversion of the call to the actual constructor. When the result
457 -- type is a class-wide interface type this conversion is required to
458 -- force the displacement of the pointer to the object to reference the
459 -- corresponding dispatch table.
461 Rewrite (N, Convert_To (Result_Typ, Cnstr_Call));
463 -- Do not generate a run-time check on the built object if tag
464 -- checks are suppressed for the result type or tagged type expansion
465 -- is disabled or if CodePeer_Mode.
467 if Tag_Checks_Suppressed (Etype (Result_Typ))
468 or else not Tagged_Type_Expansion
469 or else CodePeer_Mode
470 then
471 null;
473 -- Generate a class-wide membership test to ensure that the call's tag
474 -- argument denotes a type within the class. We must keep separate the
475 -- case in which the Result_Type of the constructor function is a tagged
476 -- type from the case in which it is an abstract interface because the
477 -- run-time subprogram required to check these cases differ (and have
478 -- one difference in their parameters profile).
480 -- Call CW_Membership if the Result_Type is a tagged type to look for
481 -- the tag in the table of ancestor tags.
483 elsif not Is_Interface (Result_Typ) then
484 Insert_Action (N,
485 Make_Implicit_If_Statement (N,
486 Condition =>
487 Make_Op_Not (Loc,
488 Make_Function_Call (Loc,
489 Name => New_Occurrence_Of (RTE (RE_CW_Membership), Loc),
490 Parameter_Associations => New_List (
491 New_Copy_Tree (Tag_Arg),
492 New_Occurrence_Of (
493 Node (First_Elmt (Access_Disp_Table (
494 Root_Type (Result_Typ)))), Loc)))),
495 Then_Statements =>
496 New_List (
497 Make_Raise_Statement (Loc,
498 Name => New_Occurrence_Of (RTE (RE_Tag_Error), Loc)))));
500 -- Call IW_Membership test if the Result_Type is an abstract interface
501 -- to look for the tag in the table of interface tags.
503 else
504 Insert_Action (N,
505 Make_Implicit_If_Statement (N,
506 Condition =>
507 Make_Op_Not (Loc,
508 Make_Function_Call (Loc,
509 Name => New_Occurrence_Of (RTE (RE_IW_Membership), Loc),
510 Parameter_Associations => New_List (
511 Make_Attribute_Reference (Loc,
512 Prefix => New_Copy_Tree (Tag_Arg),
513 Attribute_Name => Name_Address),
515 New_Occurrence_Of (
516 Node (First_Elmt (Access_Disp_Table (
517 Root_Type (Result_Typ)))), Loc)))),
518 Then_Statements =>
519 New_List (
520 Make_Raise_Statement (Loc,
521 Name => New_Occurrence_Of (RTE (RE_Tag_Error), Loc)))));
522 end if;
524 Analyze_And_Resolve (N, Etype (Act_Constr));
525 end Expand_Dispatching_Constructor_Call;
527 ---------------------------
528 -- Expand_Exception_Call --
529 ---------------------------
531 -- If the function call is not within an exception handler, then the call
532 -- is replaced by a null string. Otherwise the appropriate routine in
533 -- Ada.Exceptions is called passing the choice parameter specification
534 -- from the enclosing handler. If the enclosing handler lacks a choice
535 -- parameter, then one is supplied.
537 procedure Expand_Exception_Call (N : Node_Id; Ent : RE_Id) is
538 Loc : constant Source_Ptr := Sloc (N);
539 P : Node_Id;
540 E : Entity_Id;
542 begin
543 -- Climb up parents to see if we are in exception handler
545 P := Parent (N);
546 loop
547 -- Case of not in exception handler, replace by null string
549 if No (P) then
550 Rewrite (N,
551 Make_String_Literal (Loc,
552 Strval => ""));
553 exit;
555 -- Case of in exception handler
557 elsif Nkind (P) = N_Exception_Handler then
559 -- Handler cannot be used for a local raise, and furthermore, this
560 -- is a violation of the No_Exception_Propagation restriction.
562 Set_Local_Raise_Not_OK (P);
563 Check_Restriction (No_Exception_Propagation, N);
565 -- If no choice parameter present, then put one there. Note that
566 -- we do not need to put it on the entity chain, since no one will
567 -- be referencing it by normal visibility methods.
569 if No (Choice_Parameter (P)) then
570 E := Make_Temporary (Loc, 'E');
571 Set_Choice_Parameter (P, E);
572 Mutate_Ekind (E, E_Variable);
573 Set_Etype (E, RTE (RE_Exception_Occurrence));
574 Set_Scope (E, Current_Scope);
575 end if;
577 Rewrite (N,
578 Make_Function_Call (Loc,
579 Name => New_Occurrence_Of (RTE (Ent), Loc),
580 Parameter_Associations => New_List (
581 New_Occurrence_Of (Choice_Parameter (P), Loc))));
582 exit;
584 -- Keep climbing
586 else
587 P := Parent (P);
588 end if;
589 end loop;
591 Analyze_And_Resolve (N, Standard_String);
592 end Expand_Exception_Call;
594 ------------------------
595 -- Expand_Import_Call --
596 ------------------------
598 -- The function call must have a static string as its argument. We create
599 -- a dummy variable which uses this string as the external name in an
600 -- Import pragma. The result is then obtained as the address of this
601 -- dummy variable, converted to the appropriate target type.
603 procedure Expand_Import_Call (N : Node_Id) is
604 Loc : constant Source_Ptr := Sloc (N);
605 Ent : constant Entity_Id := Entity (Name (N));
606 Str : constant Node_Id := First_Actual (N);
607 Dum : constant Entity_Id := Make_Temporary (Loc, 'D');
609 begin
610 Insert_Actions (N, New_List (
611 Make_Object_Declaration (Loc,
612 Defining_Identifier => Dum,
613 Object_Definition =>
614 New_Occurrence_Of (Standard_Character, Loc)),
616 Make_Pragma (Loc,
617 Chars => Name_Import,
618 Pragma_Argument_Associations => New_List (
619 Make_Pragma_Argument_Association (Loc,
620 Expression => Make_Identifier (Loc, Name_Ada)),
622 Make_Pragma_Argument_Association (Loc,
623 Expression => Make_Identifier (Loc, Chars (Dum))),
625 Make_Pragma_Argument_Association (Loc,
626 Chars => Name_Link_Name,
627 Expression => Relocate_Node (Str))))));
629 Rewrite (N,
630 Unchecked_Convert_To (Etype (Ent),
631 Make_Attribute_Reference (Loc,
632 Prefix => Make_Identifier (Loc, Chars (Dum)),
633 Attribute_Name => Name_Address)));
635 Analyze_And_Resolve (N, Etype (Ent));
636 end Expand_Import_Call;
638 ---------------------------
639 -- Expand_Intrinsic_Call --
640 ---------------------------
642 procedure Expand_Intrinsic_Call (N : Node_Id; E : Entity_Id) is
643 Nam : Name_Id;
645 begin
646 -- If an external name is specified for the intrinsic, it is handled
647 -- by the back-end: leave the call node unchanged for now.
649 if Present (Interface_Name (E)) then
650 return;
651 end if;
653 -- If the intrinsic subprogram is generic, gets its original name
655 if Present (Parent (E))
656 and then Present (Generic_Parent (Parent (E)))
657 then
658 Nam := Chars (Generic_Parent (Parent (E)));
659 else
660 Nam := Chars (E);
661 end if;
663 if Nam = Name_Asm then
664 Expand_Asm_Call (N);
666 elsif Nam = Name_Divide then
667 Expand_Decimal_Divide_Call (N);
669 elsif Nam = Name_Exception_Information then
670 Expand_Exception_Call (N, RE_Exception_Information);
672 elsif Nam = Name_Exception_Message then
673 Expand_Exception_Call (N, RE_Exception_Message);
675 elsif Nam = Name_Exception_Name then
676 Expand_Exception_Call (N, RE_Exception_Name_Simple);
678 elsif Nam = Name_Generic_Dispatching_Constructor then
679 Expand_Dispatching_Constructor_Call (N);
681 elsif Nam in Name_Import_Address
682 | Name_Import_Largest_Value
683 | Name_Import_Value
684 then
685 Expand_Import_Call (N);
687 elsif Nam = Name_Rotate_Left then
688 Expand_Shift (N, E, N_Op_Rotate_Left);
690 elsif Nam = Name_Rotate_Right then
691 Expand_Shift (N, E, N_Op_Rotate_Right);
693 elsif Nam = Name_Shift_Left then
694 Expand_Shift (N, E, N_Op_Shift_Left);
696 elsif Nam = Name_Shift_Right then
697 Expand_Shift (N, E, N_Op_Shift_Right);
699 elsif Nam = Name_Shift_Right_Arithmetic then
700 Expand_Shift (N, E, N_Op_Shift_Right_Arithmetic);
702 elsif Nam = Name_Unchecked_Conversion then
703 Expand_Unc_Conversion (N, E);
705 elsif Nam = Name_Unchecked_Deallocation then
706 Expand_Unc_Deallocation (N);
708 elsif Nam = Name_To_Address then
709 Expand_To_Address (N);
711 elsif Nam = Name_To_Pointer then
712 Expand_To_Pointer (N);
714 elsif Nam in Name_File
715 | Name_Line
716 | Name_Source_Location
717 | Name_Enclosing_Entity
718 | Name_Compilation_ISO_Date
719 | Name_Compilation_Date
720 | Name_Compilation_Time
721 then
722 Expand_Source_Info (N, Nam);
724 -- If we have a renaming, expand the call to the original operation,
725 -- which must itself be intrinsic, since renaming requires matching
726 -- conventions and this has already been checked.
728 elsif Present (Alias (E)) then
729 Expand_Intrinsic_Call (N, Alias (E));
731 elsif Nkind (N) in N_Binary_Op then
732 Expand_Binary_Operator_Call (N);
734 -- The only other case is where an external name was specified, since
735 -- this is the only way that an otherwise unrecognized name could
736 -- escape the checking in Sem_Prag. Nothing needs to be done in such
737 -- a case, since we pass such a call to the back end unchanged.
739 else
740 null;
741 end if;
742 end Expand_Intrinsic_Call;
744 ------------------
745 -- Expand_Shift --
746 ------------------
748 -- This procedure is used to convert a call to a shift function to the
749 -- corresponding operator node. This conversion is not done by the usual
750 -- circuit for converting calls to operator functions (e.g. "+"(1,2)) to
751 -- operator nodes, because shifts are not predefined operators.
753 -- As a result, whenever a shift is used in the source program, it will
754 -- remain as a call until converted by this routine to the operator node
755 -- form which the back end is expecting to see.
757 -- Note: it is possible for the expander to generate shift operator nodes
758 -- directly, which will be analyzed in the normal manner by calling Analyze
759 -- and Resolve. Such shift operator nodes will not be seen by Expand_Shift.
761 procedure Expand_Shift (N : Node_Id; E : Entity_Id; K : Node_Kind) is
762 Entyp : constant Entity_Id := Etype (E);
763 Left : constant Node_Id := First_Actual (N);
764 Loc : constant Source_Ptr := Sloc (N);
765 Right : constant Node_Id := Next_Actual (Left);
766 Ltyp : constant Node_Id := Etype (Left);
767 Rtyp : constant Node_Id := Etype (Right);
768 Typ : constant Entity_Id := Etype (N);
769 Snode : Node_Id;
771 begin
772 Snode := New_Node (K, Loc);
773 Set_Right_Opnd (Snode, Relocate_Node (Right));
774 Set_Chars (Snode, Chars (E));
775 Set_Etype (Snode, Base_Type (Entyp));
776 Set_Entity (Snode, E);
778 if Compile_Time_Known_Value (Type_High_Bound (Rtyp))
779 and then Expr_Value (Type_High_Bound (Rtyp)) < Esize (Ltyp)
780 then
781 Set_Shift_Count_OK (Snode, True);
782 end if;
784 if Typ = Entyp then
786 -- Note that we don't call Analyze and Resolve on this node, because
787 -- it already got analyzed and resolved when it was a function call.
789 Set_Left_Opnd (Snode, Relocate_Node (Left));
790 Rewrite (N, Snode);
791 Set_Analyzed (N);
793 -- However, we do call the expander, so that the expansion for
794 -- rotates and shift_right_arithmetic happens if Modify_Tree_For_C
795 -- is set.
797 if Expander_Active then
798 Expand (N);
799 end if;
801 else
802 -- If the context type is not the type of the operator, it is an
803 -- inherited operator for a derived type. Wrap the node in a
804 -- conversion so that it is type-consistent for possible further
805 -- expansion (e.g. within a lock-free protected type).
807 Set_Left_Opnd (Snode,
808 Unchecked_Convert_To (Base_Type (Entyp), Relocate_Node (Left)));
809 Rewrite (N, Unchecked_Convert_To (Typ, Snode));
811 -- Analyze and resolve result formed by conversion to target type
813 Analyze_And_Resolve (N, Typ);
814 end if;
815 end Expand_Shift;
817 ------------------------
818 -- Expand_Source_Info --
819 ------------------------
821 procedure Expand_Source_Info (N : Node_Id; Nam : Name_Id) is
822 Loc : constant Source_Ptr := Sloc (N);
823 begin
824 -- Integer cases
826 if Nam = Name_Line then
827 Rewrite (N,
828 Make_Integer_Literal (Loc,
829 Intval => UI_From_Int (Int (Get_Logical_Line_Number (Loc)))));
830 Analyze_And_Resolve (N, Standard_Positive);
832 -- String cases
834 else
835 declare
836 Buf : Bounded_String;
837 begin
838 Add_Source_Info (Buf, Loc, Nam);
839 Rewrite (N, Make_String_Literal (Loc, Strval => +Buf));
840 Analyze_And_Resolve (N, Standard_String);
841 end;
842 end if;
844 Set_Is_Static_Expression (N);
845 end Expand_Source_Info;
847 ---------------------------
848 -- Expand_Unc_Conversion --
849 ---------------------------
851 procedure Expand_Unc_Conversion (N : Node_Id; E : Entity_Id) is
852 Func : constant Entity_Id := Entity (Name (N));
853 Conv : Node_Id;
854 Ftyp : Entity_Id;
855 Ttyp : Entity_Id;
857 begin
858 -- Rewrite as unchecked conversion node. Note that we must convert
859 -- the operand to the formal type of the input parameter of the
860 -- function, so that the resulting N_Unchecked_Type_Conversion
861 -- call indicates the correct types for Gigi.
863 -- Right now, we only do this if a scalar type is involved. It is
864 -- not clear if it is needed in other cases. If we do attempt to
865 -- do the conversion unconditionally, it crashes 3411-018. To be
866 -- investigated further ???
868 Conv := Relocate_Node (First_Actual (N));
869 Ftyp := Etype (First_Formal (Func));
871 if Is_Scalar_Type (Ftyp) then
872 Conv := Convert_To (Ftyp, Conv);
873 Set_Parent (Conv, N);
874 Analyze_And_Resolve (Conv);
875 end if;
877 -- The instantiation of Unchecked_Conversion creates a wrapper package,
878 -- and the target type is declared as a subtype of the actual. Recover
879 -- the actual, which is the subtype indic. in the subtype declaration
880 -- for the target type. This is semantically correct, and avoids
881 -- anomalies with access subtypes. For entities, leave type as is.
883 -- We do the analysis here, because we do not want the compiler
884 -- to try to optimize or otherwise reorganize the unchecked
885 -- conversion node.
887 Ttyp := Etype (E);
889 if Is_Entity_Name (Conv) then
890 null;
892 elsif Nkind (Parent (Ttyp)) = N_Subtype_Declaration then
893 Ttyp := Entity (Subtype_Indication (Parent (Etype (E))));
895 elsif Is_Itype (Ttyp) then
896 Ttyp :=
897 Entity (Subtype_Indication (Associated_Node_For_Itype (Ttyp)));
898 else
899 raise Program_Error;
900 end if;
902 Rewrite (N, Unchecked_Convert_To (Ttyp, Conv));
903 Analyze_And_Resolve (N, Ttyp);
904 end Expand_Unc_Conversion;
906 -----------------------------
907 -- Expand_Unc_Deallocation --
908 -----------------------------
910 procedure Expand_Unc_Deallocation (N : Node_Id) is
911 Arg : constant Node_Id := First_Actual (N);
912 Loc : constant Source_Ptr := Sloc (N);
913 Typ : constant Entity_Id := Etype (Arg);
914 Desig_Typ : constant Entity_Id :=
915 Available_View (Designated_Type (Typ));
916 Needs_Fin : constant Boolean := Needs_Finalization (Desig_Typ);
917 Root_Typ : constant Entity_Id := Underlying_Type (Root_Type (Typ));
918 Pool : constant Entity_Id := Associated_Storage_Pool (Root_Typ);
919 Stmts : constant List_Id := New_List;
921 Arg_Known_Non_Null : constant Boolean := Known_Non_Null (N);
922 -- This captures whether we know the argument to be non-null so that
923 -- we can avoid the test. The reason that we need to capture this is
924 -- that we analyze some generated statements before properly attaching
925 -- them to the tree, and that can disturb current value settings.
927 Exceptions_OK : constant Boolean :=
928 not Restriction_Active (No_Exception_Propagation);
930 Abrt_Blk : Node_Id := Empty;
931 Abrt_Blk_Id : Entity_Id;
932 Abrt_HSS : Node_Id;
933 AUD : Entity_Id;
934 Fin_Blk : Node_Id;
935 Fin_Call : Node_Id;
936 Fin_Data : Finalization_Exception_Data;
937 Free_Arg : Node_Id;
938 Free_Nod : Node_Id;
939 Gen_Code : Node_Id;
940 Obj_Ref : Node_Id;
942 begin
943 -- Nothing to do if we know the argument is null
945 if Known_Null (N) then
946 return;
947 end if;
949 -- Processing for pointer to controlled types. Generate:
951 -- Abrt : constant Boolean := ...;
952 -- Ex : Exception_Occurrence;
953 -- Raised : Boolean := False;
955 -- begin
956 -- Abort_Defer;
958 -- begin
959 -- [Deep_]Finalize (Obj_Ref);
961 -- exception
962 -- when others =>
963 -- if not Raised then
964 -- Raised := True;
965 -- Save_Occurrence (Ex, Get_Current_Excep.all.all);
966 -- end;
967 -- at end
968 -- Abort_Undefer_Direct;
969 -- end;
971 -- Depending on whether exception propagation is enabled and/or aborts
972 -- are allowed, the generated code may lack block statements.
974 if Needs_Fin then
976 -- Ada 2005 (AI-251): In case of abstract interface type we displace
977 -- the pointer to reference the base of the object to deallocate its
978 -- memory, unless we're targetting a VM, in which case no special
979 -- processing is required.
981 if Is_Interface (Directly_Designated_Type (Typ))
982 and then Tagged_Type_Expansion
983 then
984 Obj_Ref :=
985 Make_Explicit_Dereference (Loc,
986 Prefix =>
987 Unchecked_Convert_To (Typ,
988 Make_Function_Call (Loc,
989 Name =>
990 New_Occurrence_Of (RTE (RE_Base_Address), Loc),
991 Parameter_Associations => New_List (
992 Unchecked_Convert_To (RTE (RE_Address),
993 Duplicate_Subexpr_No_Checks (Arg))))));
995 else
996 Obj_Ref :=
997 Make_Explicit_Dereference (Loc,
998 Prefix => Duplicate_Subexpr_No_Checks (Arg));
999 end if;
1001 -- If the designated type is tagged, the finalization call must
1002 -- dispatch because the designated type may not be the actual type
1003 -- of the object. If the type is synchronized, the deallocation
1004 -- applies to the corresponding record type.
1006 if Is_Tagged_Type (Desig_Typ) then
1007 if Is_Concurrent_Type (Desig_Typ) then
1008 Obj_Ref :=
1009 Unchecked_Convert_To
1010 (Class_Wide_Type (Corresponding_Record_Type (Desig_Typ)),
1011 Obj_Ref);
1013 elsif not Is_Class_Wide_Type (Desig_Typ) then
1014 Obj_Ref :=
1015 Unchecked_Convert_To (Class_Wide_Type (Desig_Typ), Obj_Ref);
1016 end if;
1018 -- Otherwise the designated type is untagged. Set the type of the
1019 -- dereference explicitly to force a conversion when needed given
1020 -- that [Deep_]Finalize may be inherited from a parent type.
1022 else
1023 Set_Etype (Obj_Ref, Desig_Typ);
1024 end if;
1026 -- Generate:
1027 -- [Deep_]Finalize (Obj_Ref);
1029 Fin_Call := Make_Final_Call (Obj_Ref => Obj_Ref, Typ => Desig_Typ);
1031 -- Generate:
1032 -- Abrt : constant Boolean := ...;
1033 -- Ex : Exception_Occurrence;
1034 -- Raised : Boolean := False;
1036 -- begin
1037 -- <Fin_Call>
1039 -- exception
1040 -- when others =>
1041 -- if not Raised then
1042 -- Raised := True;
1043 -- Save_Occurrence (Ex, Get_Current_Excep.all.all);
1044 -- end;
1046 if Exceptions_OK then
1047 Build_Object_Declarations (Fin_Data, Stmts, Loc);
1049 Fin_Blk :=
1050 Make_Block_Statement (Loc,
1051 Handled_Statement_Sequence =>
1052 Make_Handled_Sequence_Of_Statements (Loc,
1053 Statements => New_List (Fin_Call),
1054 Exception_Handlers => New_List (
1055 Build_Exception_Handler (Fin_Data))));
1057 -- Otherwise exception propagation is not allowed
1059 else
1060 Fin_Blk := Fin_Call;
1061 end if;
1063 -- The finalization action must be protected by an abort defer and
1064 -- undefer pair when aborts are allowed. Generate:
1066 -- begin
1067 -- Abort_Defer;
1068 -- <Fin_Blk>
1069 -- at end
1070 -- Abort_Undefer_Direct;
1071 -- end;
1073 if Abort_Allowed then
1074 AUD := RTE (RE_Abort_Undefer_Direct);
1076 Abrt_HSS :=
1077 Make_Handled_Sequence_Of_Statements (Loc,
1078 Statements => New_List (
1079 Build_Runtime_Call (Loc, RE_Abort_Defer),
1080 Fin_Blk),
1081 At_End_Proc => New_Occurrence_Of (AUD, Loc));
1083 Abrt_Blk :=
1084 Make_Block_Statement (Loc,
1085 Handled_Statement_Sequence => Abrt_HSS);
1087 Add_Block_Identifier (Abrt_Blk, Abrt_Blk_Id);
1088 Expand_At_End_Handler (Abrt_HSS, Abrt_Blk_Id);
1090 -- Present the Abort_Undefer_Direct function to the backend so
1091 -- that it can inline the call to the function.
1093 Add_Inlined_Body (AUD, N);
1095 -- Otherwise aborts are not allowed
1097 else
1098 Abrt_Blk := Fin_Blk;
1099 end if;
1101 Append_To (Stmts, Abrt_Blk);
1102 end if;
1104 -- For a task type, call Free_Task before freeing the ATCB. We used to
1105 -- detect the case of Abort followed by a Free here, because the Free
1106 -- wouldn't actually free if it happens before the aborted task actually
1107 -- terminates. The warning was removed, because Free now works properly
1108 -- (the task will be freed once it terminates).
1110 if Is_Task_Type (Desig_Typ) then
1111 Append_To (Stmts,
1112 Cleanup_Task (N, Duplicate_Subexpr_No_Checks (Arg)));
1114 -- For composite types that contain tasks, recurse over the structure
1115 -- to build the selectors for the task subcomponents.
1117 elsif Has_Task (Desig_Typ) then
1118 if Is_Array_Type (Desig_Typ) then
1119 Append_List_To (Stmts, Cleanup_Array (N, Arg, Desig_Typ));
1121 elsif Is_Record_Type (Desig_Typ) then
1122 Append_List_To (Stmts, Cleanup_Record (N, Arg, Desig_Typ));
1123 end if;
1124 end if;
1126 -- Same for simple protected types. Eventually call Finalize_Protection
1127 -- before freeing the PO for each protected component.
1129 if Is_Simple_Protected_Type (Desig_Typ) then
1130 Append_To (Stmts,
1131 Cleanup_Protected_Object (N, Duplicate_Subexpr_No_Checks (Arg)));
1133 elsif Has_Simple_Protected_Object (Desig_Typ) then
1134 if Is_Array_Type (Desig_Typ) then
1135 Append_List_To (Stmts, Cleanup_Array (N, Arg, Desig_Typ));
1137 elsif Is_Record_Type (Desig_Typ) then
1138 Append_List_To (Stmts, Cleanup_Record (N, Arg, Desig_Typ));
1139 end if;
1140 end if;
1142 -- Normal processing for non-controlled types. The argument to free is
1143 -- a renaming rather than a constant to ensure that the original context
1144 -- is always set to null after the deallocation takes place.
1146 Free_Arg := Duplicate_Subexpr_No_Checks (Arg, Renaming_Req => True);
1147 Free_Nod := Make_Free_Statement (Loc, Empty);
1148 Append_To (Stmts, Free_Nod);
1149 Set_Storage_Pool (Free_Nod, Pool);
1151 -- Attach to tree before analysis of generated subtypes below
1153 Set_Parent (Stmts, Parent (N));
1155 -- Deal with storage pool
1157 if Present (Pool) then
1159 -- Freeing the secondary stack is meaningless
1161 if Is_RTE (Pool, RE_SS_Pool) then
1162 null;
1164 -- If the pool object is of a simple storage pool type, then attempt
1165 -- to locate the type's Deallocate procedure, if any, and set the
1166 -- free operation's procedure to call. If the type doesn't have a
1167 -- Deallocate (which is allowed), then the actual will simply be set
1168 -- to null.
1170 elsif Present
1171 (Get_Rep_Pragma (Etype (Pool), Name_Simple_Storage_Pool_Type))
1172 then
1173 declare
1174 Pool_Typ : constant Entity_Id := Base_Type (Etype (Pool));
1175 Dealloc : Entity_Id;
1177 begin
1178 Dealloc := Get_Name_Entity_Id (Name_Deallocate);
1179 while Present (Dealloc) loop
1180 if Scope (Dealloc) = Scope (Pool_Typ)
1181 and then Present (First_Formal (Dealloc))
1182 and then Etype (First_Formal (Dealloc)) = Pool_Typ
1183 then
1184 Set_Procedure_To_Call (Free_Nod, Dealloc);
1185 exit;
1186 else
1187 Dealloc := Homonym (Dealloc);
1188 end if;
1189 end loop;
1190 end;
1192 -- Case of a class-wide pool type: make a dispatching call to
1193 -- Deallocate through the class-wide Deallocate_Any.
1195 elsif Is_Class_Wide_Type (Etype (Pool)) then
1196 Set_Procedure_To_Call (Free_Nod, RTE (RE_Deallocate_Any));
1198 -- Case of a specific pool type: make a statically bound call
1200 else
1201 Set_Procedure_To_Call
1202 (Free_Nod, Find_Storage_Op (Etype (Pool), Name_Deallocate));
1203 end if;
1204 end if;
1206 if Present (Procedure_To_Call (Free_Nod)) then
1208 -- For all cases of a Deallocate call, the back-end needs to be able
1209 -- to compute the size of the object being freed. This may require
1210 -- some adjustments for objects of dynamic size.
1212 -- If the type is class wide, we generate an implicit type with the
1213 -- right dynamic size, so that the deallocate call gets the right
1214 -- size parameter computed by GIGI. Same for an access to
1215 -- unconstrained packed array.
1217 if Is_Class_Wide_Type (Desig_Typ)
1218 or else
1219 (Is_Packed_Array (Desig_Typ)
1220 and then not Is_Constrained (Desig_Typ))
1221 then
1222 declare
1223 Deref : constant Node_Id :=
1224 Make_Explicit_Dereference (Loc,
1225 Duplicate_Subexpr_No_Checks (Arg));
1226 D_Subtyp : Node_Id;
1227 D_Type : Entity_Id;
1229 begin
1230 -- Perform minor decoration as it is needed by the side effect
1231 -- removal mechanism.
1233 Set_Etype (Deref, Desig_Typ);
1234 Set_Parent (Deref, Free_Nod);
1235 D_Subtyp := Make_Subtype_From_Expr (Deref, Desig_Typ);
1237 if Nkind (D_Subtyp) in N_Has_Entity then
1238 D_Type := Entity (D_Subtyp);
1240 else
1241 D_Type := Make_Temporary (Loc, 'A');
1242 Insert_Action (Deref,
1243 Make_Subtype_Declaration (Loc,
1244 Defining_Identifier => D_Type,
1245 Subtype_Indication => D_Subtyp));
1246 end if;
1248 -- Force freezing at the point of the dereference. For the
1249 -- class wide case, this avoids having the subtype frozen
1250 -- before the equivalent type.
1252 Freeze_Itype (D_Type, Deref);
1254 Set_Actual_Designated_Subtype (Free_Nod, D_Type);
1255 end;
1256 end if;
1257 end if;
1259 -- Ada 2005 (AI-251): In case of abstract interface type we must
1260 -- displace the pointer to reference the base of the object to
1261 -- deallocate its memory, unless we're targetting a VM, in which case
1262 -- no special processing is required.
1264 -- Generate:
1265 -- free (Base_Address (Obj_Ptr))
1267 if Is_Interface (Directly_Designated_Type (Typ))
1268 and then Tagged_Type_Expansion
1269 then
1270 Set_Expression (Free_Nod,
1271 Unchecked_Convert_To (Typ,
1272 Make_Function_Call (Loc,
1273 Name =>
1274 New_Occurrence_Of (RTE (RE_Base_Address), Loc),
1275 Parameter_Associations => New_List (
1276 Unchecked_Convert_To (RTE (RE_Address), Free_Arg)))));
1278 -- Generate:
1279 -- free (Obj_Ptr)
1281 else
1282 Set_Expression (Free_Nod, Free_Arg);
1283 end if;
1285 -- Only remaining step is to set result to null, or generate a raise of
1286 -- Constraint_Error if the target object is "not null".
1288 if Can_Never_Be_Null (Etype (Arg)) then
1289 Append_To (Stmts,
1290 Make_Raise_Constraint_Error (Loc,
1291 Reason => CE_Access_Check_Failed));
1293 else
1294 declare
1295 Lhs : constant Node_Id := Duplicate_Subexpr_No_Checks (Arg);
1296 begin
1297 Set_Assignment_OK (Lhs);
1298 Append_To (Stmts,
1299 Make_Assignment_Statement (Loc,
1300 Name => Lhs,
1301 Expression => Make_Null (Loc)));
1302 end;
1303 end if;
1305 -- Generate a test of whether any earlier finalization raised an
1306 -- exception, and in that case raise Program_Error with the previous
1307 -- exception occurrence.
1309 -- Generate:
1310 -- if Raised and then not Abrt then
1311 -- raise Program_Error; -- for restricted RTS
1312 -- <or>
1313 -- Raise_From_Controlled_Operation (E); -- all other cases
1314 -- end if;
1316 if Needs_Fin and then Exceptions_OK then
1317 Append_To (Stmts, Build_Raise_Statement (Fin_Data));
1318 end if;
1320 -- If we know the argument is non-null, then make a block statement
1321 -- that contains the required statements, no need for a test.
1323 if Arg_Known_Non_Null then
1324 Gen_Code :=
1325 Make_Block_Statement (Loc,
1326 Handled_Statement_Sequence =>
1327 Make_Handled_Sequence_Of_Statements (Loc,
1328 Statements => Stmts));
1330 -- If the argument may be null, wrap the statements inside an IF that
1331 -- does an explicit test to exclude the null case.
1333 else
1334 Gen_Code :=
1335 Make_Implicit_If_Statement (N,
1336 Condition =>
1337 Make_Op_Ne (Loc,
1338 Left_Opnd => Duplicate_Subexpr (Arg),
1339 Right_Opnd => Make_Null (Loc)),
1340 Then_Statements => Stmts);
1341 end if;
1343 -- Rewrite the call
1345 Rewrite (N, Gen_Code);
1346 Analyze (N);
1347 end Expand_Unc_Deallocation;
1349 -----------------------
1350 -- Expand_To_Address --
1351 -----------------------
1353 procedure Expand_To_Address (N : Node_Id) is
1354 Loc : constant Source_Ptr := Sloc (N);
1355 Arg : constant Node_Id := First_Actual (N);
1356 Obj : Node_Id;
1358 begin
1359 Remove_Side_Effects (Arg);
1361 Obj := Make_Explicit_Dereference (Loc, Relocate_Node (Arg));
1363 Rewrite (N,
1364 Make_If_Expression (Loc,
1365 Expressions => New_List (
1366 Make_Op_Eq (Loc,
1367 Left_Opnd => New_Copy_Tree (Arg),
1368 Right_Opnd => Make_Null (Loc)),
1369 New_Occurrence_Of (RTE (RE_Null_Address), Loc),
1370 Make_Attribute_Reference (Loc,
1371 Prefix => Obj,
1372 Attribute_Name => Name_Address))));
1374 Analyze_And_Resolve (N, RTE (RE_Address));
1375 end Expand_To_Address;
1377 -----------------------
1378 -- Expand_To_Pointer --
1379 -----------------------
1381 procedure Expand_To_Pointer (N : Node_Id) is
1382 Arg : constant Node_Id := First_Actual (N);
1384 begin
1385 Rewrite (N, Unchecked_Convert_To (Etype (N), Arg));
1386 Analyze (N);
1387 end Expand_To_Pointer;
1389 end Exp_Intr;