2014-10-10 Robert Dewar <dewar@adacore.com>
[official-gcc.git] / gcc / ada / exp_intr.adb
blobaa73839d88741873b0fca68864d8a754bfdf197a
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-2014, 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 Checks; use Checks;
28 with Einfo; use Einfo;
29 with Elists; use Elists;
30 with Expander; use Expander;
31 with Exp_Atag; use Exp_Atag;
32 with Exp_Ch4; use Exp_Ch4;
33 with Exp_Ch7; use Exp_Ch7;
34 with Exp_Ch11; use Exp_Ch11;
35 with Exp_Code; use Exp_Code;
36 with Exp_Fixd; use Exp_Fixd;
37 with Exp_Util; use Exp_Util;
38 with Freeze; use Freeze;
39 with Nmake; use Nmake;
40 with Nlists; use Nlists;
41 with Opt; use Opt;
42 with Restrict; use Restrict;
43 with Rident; use Rident;
44 with Rtsfind; use Rtsfind;
45 with Sem; use Sem;
46 with Sem_Aux; use Sem_Aux;
47 with Sem_Eval; use Sem_Eval;
48 with Sem_Res; use Sem_Res;
49 with Sem_Type; use Sem_Type;
50 with Sem_Util; use Sem_Util;
51 with Sinfo; use Sinfo;
52 with Sinput; use Sinput;
53 with Snames; use Snames;
54 with Stand; use Stand;
55 with Stringt; use Stringt;
56 with Targparm; use Targparm;
57 with Tbuild; use Tbuild;
58 with Uintp; use Uintp;
59 with Urealp; use Urealp;
61 package body Exp_Intr is
63 -----------------------
64 -- Local Subprograms --
65 -----------------------
67 procedure Expand_Binary_Operator_Call (N : Node_Id);
68 -- Expand a call to an intrinsic arithmetic operator when the operand
69 -- types or sizes are not identical.
71 procedure Expand_Is_Negative (N : Node_Id);
72 -- Expand a call to the intrinsic Is_Negative function
74 procedure Expand_Dispatching_Constructor_Call (N : Node_Id);
75 -- Expand a call to an instantiation of Generic_Dispatching_Constructor
76 -- into a dispatching call to the actual subprogram associated with the
77 -- Constructor formal subprogram, passing it the Parameters actual of
78 -- the call to the instantiation and dispatching based on call's Tag
79 -- parameter.
81 procedure Expand_Exception_Call (N : Node_Id; Ent : RE_Id);
82 -- Expand a call to Exception_Information/Message/Name. The first
83 -- parameter, N, is the node for the function call, and Ent is the
84 -- entity for the corresponding routine in the Ada.Exceptions package.
86 procedure Expand_Import_Call (N : Node_Id);
87 -- Expand a call to Import_Address/Longest_Integer/Value. The parameter
88 -- N is the node for the function call.
90 procedure Expand_Shift (N : Node_Id; E : Entity_Id; K : Node_Kind);
91 -- Expand an intrinsic shift operation, N and E are from the call to
92 -- Expand_Intrinsic_Call (call node and subprogram spec entity) and
93 -- K is the kind for the shift node
95 procedure Expand_Unc_Conversion (N : Node_Id; E : Entity_Id);
96 -- Expand a call to an instantiation of Unchecked_Conversion into a node
97 -- N_Unchecked_Type_Conversion.
99 procedure Expand_Unc_Deallocation (N : Node_Id);
100 -- Expand a call to an instantiation of Unchecked_Deallocation into a node
101 -- N_Free_Statement and appropriate context.
103 procedure Expand_To_Address (N : Node_Id);
104 procedure Expand_To_Pointer (N : Node_Id);
105 -- Expand a call to corresponding function, declared in an instance of
106 -- System.Address_To_Access_Conversions.
108 procedure Expand_Source_Info (N : Node_Id; Nam : Name_Id);
109 -- Rewrite the node by the appropriate string or positive constant.
110 -- Nam can be one of the following:
111 -- Name_File - expand string name of source file
112 -- Name_Line - expand integer line number
113 -- Name_Source_Location - expand string of form file:line
114 -- Name_Enclosing_Entity - expand string name of enclosing entity
115 -- Name_Compilation_Date - expand string with compilation date
116 -- Name_Compilation_Time - expand string with compilation time
118 procedure Write_Entity_Name (E : Entity_Id);
119 -- Recursive procedure to construct string for qualified name of enclosing
120 -- program unit. The qualification stops at an enclosing scope has no
121 -- source name (block or loop). If entity is a subprogram instance, skip
122 -- enclosing wrapper package. The name is appended to the current contents
123 -- of Name_Buffer, incrementing Name_Len.
125 ---------------------
126 -- Add_Source_Info --
127 ---------------------
129 procedure Add_Source_Info (Loc : Source_Ptr; Nam : Name_Id) is
130 Ent : Entity_Id;
132 Save_NB : constant String := Name_Buffer (1 .. Name_Len);
133 Save_NL : constant Natural := Name_Len;
134 -- Save current Name_Buffer contents
136 begin
137 Name_Len := 0;
139 -- Line
141 case Nam is
143 when Name_Line =>
144 Add_Nat_To_Name_Buffer (Nat (Get_Logical_Line_Number (Loc)));
146 when Name_File =>
147 Get_Decoded_Name_String
148 (Reference_Name (Get_Source_File_Index (Loc)));
150 when Name_Source_Location =>
151 Build_Location_String (Loc);
153 when Name_Enclosing_Entity =>
155 -- Skip enclosing blocks to reach enclosing unit
157 Ent := Current_Scope;
158 while Present (Ent) loop
159 exit when Ekind (Ent) /= E_Block
160 and then Ekind (Ent) /= E_Loop;
161 Ent := Scope (Ent);
162 end loop;
164 -- Ent now points to the relevant defining entity
166 Write_Entity_Name (Ent);
168 when Name_Compilation_Date =>
169 declare
170 subtype S13 is String (1 .. 3);
171 Months : constant array (1 .. 12) of S13 :=
172 ("Jan", "Feb", "Mar", "Apr", "May", "Jun",
173 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
175 M1 : constant Character := Opt.Compilation_Time (6);
176 M2 : constant Character := Opt.Compilation_Time (7);
178 MM : constant Natural range 1 .. 12 :=
179 (Character'Pos (M1) - Character'Pos ('0')) * 10 +
180 (Character'Pos (M2) - Character'Pos ('0'));
182 begin
183 -- Reformat ISO date into MMM DD YYYY (__DATE__) format
185 Name_Buffer (1 .. 3) := Months (MM);
186 Name_Buffer (4) := ' ';
187 Name_Buffer (5 .. 6) := Opt.Compilation_Time (9 .. 10);
188 Name_Buffer (7) := ' ';
189 Name_Buffer (8 .. 11) := Opt.Compilation_Time (1 .. 4);
190 Name_Len := 11;
191 end;
193 when Name_Compilation_Time =>
194 Name_Buffer (1 .. 8) := Opt.Compilation_Time (12 .. 19);
195 Name_Len := 8;
197 when others =>
198 raise Program_Error;
199 end case;
201 -- Prepend original Name_Buffer contents
203 Name_Buffer (Save_NL + 1 .. Save_NL + Name_Len) :=
204 Name_Buffer (1 .. Name_Len);
205 Name_Buffer (1 .. Save_NL) := Save_NB;
206 end Add_Source_Info;
208 ---------------------------------
209 -- Expand_Binary_Operator_Call --
210 ---------------------------------
212 procedure Expand_Binary_Operator_Call (N : Node_Id) is
213 T1 : constant Entity_Id := Underlying_Type (Etype (Left_Opnd (N)));
214 T2 : constant Entity_Id := Underlying_Type (Etype (Right_Opnd (N)));
215 TR : constant Entity_Id := Etype (N);
216 T3 : Entity_Id;
217 Res : Node_Id;
219 Siz : constant Uint := UI_Max (RM_Size (T1), RM_Size (T2));
220 -- Maximum of operand sizes
222 begin
223 -- Nothing to do if the operands have the same modular type
225 if Base_Type (T1) = Base_Type (T2)
226 and then Is_Modular_Integer_Type (T1)
227 then
228 return;
229 end if;
231 -- Use Unsigned_32 for sizes of 32 or below, else Unsigned_64
233 if Siz > 32 then
234 T3 := RTE (RE_Unsigned_64);
235 else
236 T3 := RTE (RE_Unsigned_32);
237 end if;
239 -- Copy operator node, and reset type and entity fields, for
240 -- subsequent reanalysis.
242 Res := New_Copy (N);
243 Set_Etype (Res, T3);
245 case Nkind (N) is
246 when N_Op_And =>
247 Set_Entity (Res, Standard_Op_And);
248 when N_Op_Or =>
249 Set_Entity (Res, Standard_Op_Or);
250 when N_Op_Xor =>
251 Set_Entity (Res, Standard_Op_Xor);
252 when others =>
253 raise Program_Error;
254 end case;
256 -- Convert operands to large enough intermediate type
258 Set_Left_Opnd (Res,
259 Unchecked_Convert_To (T3, Relocate_Node (Left_Opnd (N))));
260 Set_Right_Opnd (Res,
261 Unchecked_Convert_To (T3, Relocate_Node (Right_Opnd (N))));
263 -- Analyze and resolve result formed by conversion to target type
265 Rewrite (N, Unchecked_Convert_To (TR, Res));
266 Analyze_And_Resolve (N, TR);
267 end Expand_Binary_Operator_Call;
269 -----------------------------------------
270 -- Expand_Dispatching_Constructor_Call --
271 -----------------------------------------
273 -- Transform a call to an instantiation of Generic_Dispatching_Constructor
274 -- of the form:
276 -- GDC_Instance (The_Tag, Parameters'Access)
278 -- to a class-wide conversion of a dispatching call to the actual
279 -- associated with the formal subprogram Construct, designating The_Tag
280 -- as the controlling tag of the call:
282 -- T'Class (Construct'Actual (Params)) -- Controlling tag is The_Tag
284 -- which will eventually be expanded to the following:
286 -- T'Class (The_Tag.all (Construct'Actual'Index).all (Params))
288 -- A class-wide membership test is also generated, preceding the call, to
289 -- ensure that the controlling tag denotes a type in T'Class.
291 procedure Expand_Dispatching_Constructor_Call (N : Node_Id) is
292 Loc : constant Source_Ptr := Sloc (N);
293 Tag_Arg : constant Node_Id := First_Actual (N);
294 Param_Arg : constant Node_Id := Next_Actual (Tag_Arg);
295 Subp_Decl : constant Node_Id := Parent (Parent (Entity (Name (N))));
296 Inst_Pkg : constant Node_Id := Parent (Subp_Decl);
297 Act_Rename : Node_Id;
298 Act_Constr : Entity_Id;
299 Iface_Tag : Node_Id := Empty;
300 Cnstr_Call : Node_Id;
301 Result_Typ : Entity_Id;
303 begin
304 -- Remove side effects from tag argument early, before rewriting
305 -- the dispatching constructor call, as Remove_Side_Effects relies
306 -- on Tag_Arg's Parent link properly attached to the tree (once the
307 -- call is rewritten, the Parent is inconsistent as it points to the
308 -- rewritten node, which is not the syntactic parent of the Tag_Arg
309 -- anymore).
311 Remove_Side_Effects (Tag_Arg);
313 -- The subprogram is the third actual in the instantiation, and is
314 -- retrieved from the corresponding renaming declaration. However,
315 -- freeze nodes may appear before, so we retrieve the declaration
316 -- with an explicit loop.
318 Act_Rename := First (Visible_Declarations (Inst_Pkg));
319 while Nkind (Act_Rename) /= N_Subprogram_Renaming_Declaration loop
320 Next (Act_Rename);
321 end loop;
323 Act_Constr := Entity (Name (Act_Rename));
324 Result_Typ := Class_Wide_Type (Etype (Act_Constr));
326 if Is_Interface (Etype (Act_Constr)) then
328 -- If the result type is not known to be a parent of Tag_Arg then we
329 -- need to locate the tag of the secondary dispatch table.
331 if not Is_Ancestor (Etype (Result_Typ), Etype (Tag_Arg),
332 Use_Full_View => True)
333 and then Tagged_Type_Expansion
334 then
335 -- Obtain the reference to the Ada.Tags service before generating
336 -- the Object_Declaration node to ensure that if this service is
337 -- not available in the runtime then we generate a clear error.
339 declare
340 Fname : constant Node_Id :=
341 New_Occurrence_Of (RTE (RE_Secondary_Tag), Loc);
343 begin
344 pragma Assert (not Is_Interface (Etype (Tag_Arg)));
346 Iface_Tag :=
347 Make_Object_Declaration (Loc,
348 Defining_Identifier => Make_Temporary (Loc, 'V'),
349 Object_Definition =>
350 New_Occurrence_Of (RTE (RE_Tag), Loc),
351 Expression =>
352 Make_Function_Call (Loc,
353 Name => Fname,
354 Parameter_Associations => New_List (
355 Relocate_Node (Tag_Arg),
356 New_Occurrence_Of
357 (Node (First_Elmt (Access_Disp_Table
358 (Etype (Etype (Act_Constr))))),
359 Loc))));
360 Insert_Action (N, Iface_Tag);
361 end;
362 end if;
363 end if;
365 -- Create the call to the actual Constructor function
367 Cnstr_Call :=
368 Make_Function_Call (Loc,
369 Name => New_Occurrence_Of (Act_Constr, Loc),
370 Parameter_Associations => New_List (Relocate_Node (Param_Arg)));
372 -- Establish its controlling tag from the tag passed to the instance
373 -- The tag may be given by a function call, in which case a temporary
374 -- should be generated now, to prevent out-of-order insertions during
375 -- the expansion of that call when stack-checking is enabled.
377 if Present (Iface_Tag) then
378 Set_Controlling_Argument (Cnstr_Call,
379 New_Occurrence_Of (Defining_Identifier (Iface_Tag), Loc));
380 else
381 Set_Controlling_Argument (Cnstr_Call,
382 Relocate_Node (Tag_Arg));
383 end if;
385 -- Rewrite and analyze the call to the instance as a class-wide
386 -- conversion of the call to the actual constructor.
388 Rewrite (N, Convert_To (Result_Typ, Cnstr_Call));
389 Analyze_And_Resolve (N, Etype (Act_Constr));
391 -- Do not generate a run-time check on the built object if tag
392 -- checks are suppressed for the result type or VM_Target /= No_VM
394 if Tag_Checks_Suppressed (Etype (Result_Typ))
395 or else not Tagged_Type_Expansion
396 then
397 null;
399 -- Generate a class-wide membership test to ensure that the call's tag
400 -- argument denotes a type within the class. We must keep separate the
401 -- case in which the Result_Type of the constructor function is a tagged
402 -- type from the case in which it is an abstract interface because the
403 -- run-time subprogram required to check these cases differ (and have
404 -- one difference in their parameters profile).
406 -- Call CW_Membership if the Result_Type is a tagged type to look for
407 -- the tag in the table of ancestor tags.
409 elsif not Is_Interface (Result_Typ) then
410 declare
411 Obj_Tag_Node : Node_Id := New_Copy_Tree (Tag_Arg);
412 CW_Test_Node : Node_Id;
414 begin
415 Build_CW_Membership (Loc,
416 Obj_Tag_Node => Obj_Tag_Node,
417 Typ_Tag_Node =>
418 New_Occurrence_Of (
419 Node (First_Elmt (Access_Disp_Table (
420 Root_Type (Result_Typ)))), Loc),
421 Related_Nod => N,
422 New_Node => CW_Test_Node);
424 Insert_Action (N,
425 Make_Implicit_If_Statement (N,
426 Condition =>
427 Make_Op_Not (Loc, CW_Test_Node),
428 Then_Statements =>
429 New_List (Make_Raise_Statement (Loc,
430 New_Occurrence_Of (RTE (RE_Tag_Error), Loc)))));
431 end;
433 -- Call IW_Membership test if the Result_Type is an abstract interface
434 -- to look for the tag in the table of interface tags.
436 else
437 Insert_Action (N,
438 Make_Implicit_If_Statement (N,
439 Condition =>
440 Make_Op_Not (Loc,
441 Make_Function_Call (Loc,
442 Name => New_Occurrence_Of (RTE (RE_IW_Membership), Loc),
443 Parameter_Associations => New_List (
444 Make_Attribute_Reference (Loc,
445 Prefix => New_Copy_Tree (Tag_Arg),
446 Attribute_Name => Name_Address),
448 New_Occurrence_Of (
449 Node (First_Elmt (Access_Disp_Table (
450 Root_Type (Result_Typ)))), Loc)))),
451 Then_Statements =>
452 New_List (
453 Make_Raise_Statement (Loc,
454 Name => New_Occurrence_Of (RTE (RE_Tag_Error), Loc)))));
455 end if;
456 end Expand_Dispatching_Constructor_Call;
458 ---------------------------
459 -- Expand_Exception_Call --
460 ---------------------------
462 -- If the function call is not within an exception handler, then the call
463 -- is replaced by a null string. Otherwise the appropriate routine in
464 -- Ada.Exceptions is called passing the choice parameter specification
465 -- from the enclosing handler. If the enclosing handler lacks a choice
466 -- parameter, then one is supplied.
468 procedure Expand_Exception_Call (N : Node_Id; Ent : RE_Id) is
469 Loc : constant Source_Ptr := Sloc (N);
470 P : Node_Id;
471 E : Entity_Id;
473 begin
474 -- Climb up parents to see if we are in exception handler
476 P := Parent (N);
477 loop
478 -- Case of not in exception handler, replace by null string
480 if No (P) then
481 Rewrite (N,
482 Make_String_Literal (Loc,
483 Strval => ""));
484 exit;
486 -- Case of in exception handler
488 elsif Nkind (P) = N_Exception_Handler then
490 -- Handler cannot be used for a local raise, and furthermore, this
491 -- is a violation of the No_Exception_Propagation restriction.
493 Set_Local_Raise_Not_OK (P);
494 Check_Restriction (No_Exception_Propagation, N);
496 -- If no choice parameter present, then put one there. Note that
497 -- we do not need to put it on the entity chain, since no one will
498 -- be referencing it by normal visibility methods.
500 if No (Choice_Parameter (P)) then
501 E := Make_Temporary (Loc, 'E');
502 Set_Choice_Parameter (P, E);
503 Set_Ekind (E, E_Variable);
504 Set_Etype (E, RTE (RE_Exception_Occurrence));
505 Set_Scope (E, Current_Scope);
506 end if;
508 Rewrite (N,
509 Make_Function_Call (Loc,
510 Name => New_Occurrence_Of (RTE (Ent), Loc),
511 Parameter_Associations => New_List (
512 New_Occurrence_Of (Choice_Parameter (P), Loc))));
513 exit;
515 -- Keep climbing
517 else
518 P := Parent (P);
519 end if;
520 end loop;
522 Analyze_And_Resolve (N, Standard_String);
523 end Expand_Exception_Call;
525 ------------------------
526 -- Expand_Import_Call --
527 ------------------------
529 -- The function call must have a static string as its argument. We create
530 -- a dummy variable which uses this string as the external name in an
531 -- Import pragma. The result is then obtained as the address of this
532 -- dummy variable, converted to the appropriate target type.
534 procedure Expand_Import_Call (N : Node_Id) is
535 Loc : constant Source_Ptr := Sloc (N);
536 Ent : constant Entity_Id := Entity (Name (N));
537 Str : constant Node_Id := First_Actual (N);
538 Dum : constant Entity_Id := Make_Temporary (Loc, 'D');
540 begin
541 Insert_Actions (N, New_List (
542 Make_Object_Declaration (Loc,
543 Defining_Identifier => Dum,
544 Object_Definition =>
545 New_Occurrence_Of (Standard_Character, Loc)),
547 Make_Pragma (Loc,
548 Chars => Name_Import,
549 Pragma_Argument_Associations => New_List (
550 Make_Pragma_Argument_Association (Loc,
551 Expression => Make_Identifier (Loc, Name_Ada)),
553 Make_Pragma_Argument_Association (Loc,
554 Expression => Make_Identifier (Loc, Chars (Dum))),
556 Make_Pragma_Argument_Association (Loc,
557 Chars => Name_Link_Name,
558 Expression => Relocate_Node (Str))))));
560 Rewrite (N,
561 Unchecked_Convert_To (Etype (Ent),
562 Make_Attribute_Reference (Loc,
563 Prefix => Make_Identifier (Loc, Chars (Dum)),
564 Attribute_Name => Name_Address)));
566 Analyze_And_Resolve (N, Etype (Ent));
567 end Expand_Import_Call;
569 ---------------------------
570 -- Expand_Intrinsic_Call --
571 ---------------------------
573 procedure Expand_Intrinsic_Call (N : Node_Id; E : Entity_Id) is
574 Nam : Name_Id;
576 begin
577 -- If an external name is specified for the intrinsic, it is handled
578 -- by the back-end: leave the call node unchanged for now.
580 if Present (Interface_Name (E)) then
581 return;
582 end if;
584 -- If the intrinsic subprogram is generic, gets its original name
586 if Present (Parent (E))
587 and then Present (Generic_Parent (Parent (E)))
588 then
589 Nam := Chars (Generic_Parent (Parent (E)));
590 else
591 Nam := Chars (E);
592 end if;
594 if Nam = Name_Asm then
595 Expand_Asm_Call (N);
597 elsif Nam = Name_Divide then
598 Expand_Decimal_Divide_Call (N);
600 elsif Nam = Name_Exception_Information then
601 Expand_Exception_Call (N, RE_Exception_Information);
603 elsif Nam = Name_Exception_Message then
604 Expand_Exception_Call (N, RE_Exception_Message);
606 elsif Nam = Name_Exception_Name then
607 Expand_Exception_Call (N, RE_Exception_Name_Simple);
609 elsif Nam = Name_Generic_Dispatching_Constructor then
610 Expand_Dispatching_Constructor_Call (N);
612 elsif Nam_In (Nam, Name_Import_Address,
613 Name_Import_Largest_Value,
614 Name_Import_Value)
615 then
616 Expand_Import_Call (N);
618 elsif Nam = Name_Is_Negative then
619 Expand_Is_Negative (N);
621 elsif Nam = Name_Rotate_Left then
622 Expand_Shift (N, E, N_Op_Rotate_Left);
624 elsif Nam = Name_Rotate_Right then
625 Expand_Shift (N, E, N_Op_Rotate_Right);
627 elsif Nam = Name_Shift_Left then
628 Expand_Shift (N, E, N_Op_Shift_Left);
630 elsif Nam = Name_Shift_Right then
631 Expand_Shift (N, E, N_Op_Shift_Right);
633 elsif Nam = Name_Shift_Right_Arithmetic then
634 Expand_Shift (N, E, N_Op_Shift_Right_Arithmetic);
636 elsif Nam = Name_Unchecked_Conversion then
637 Expand_Unc_Conversion (N, E);
639 elsif Nam = Name_Unchecked_Deallocation then
640 Expand_Unc_Deallocation (N);
642 elsif Nam = Name_To_Address then
643 Expand_To_Address (N);
645 elsif Nam = Name_To_Pointer then
646 Expand_To_Pointer (N);
648 elsif Nam_In (Nam, Name_File,
649 Name_Line,
650 Name_Source_Location,
651 Name_Enclosing_Entity,
652 Name_Compilation_Date,
653 Name_Compilation_Time)
654 then
655 Expand_Source_Info (N, Nam);
657 -- If we have a renaming, expand the call to the original operation,
658 -- which must itself be intrinsic, since renaming requires matching
659 -- conventions and this has already been checked.
661 elsif Present (Alias (E)) then
662 Expand_Intrinsic_Call (N, Alias (E));
664 elsif Nkind (N) in N_Binary_Op then
665 Expand_Binary_Operator_Call (N);
667 -- The only other case is where an external name was specified, since
668 -- this is the only way that an otherwise unrecognized name could
669 -- escape the checking in Sem_Prag. Nothing needs to be done in such
670 -- a case, since we pass such a call to the back end unchanged.
672 else
673 null;
674 end if;
675 end Expand_Intrinsic_Call;
677 ------------------------
678 -- Expand_Is_Negative --
679 ------------------------
681 procedure Expand_Is_Negative (N : Node_Id) is
682 Loc : constant Source_Ptr := Sloc (N);
683 Opnd : constant Node_Id := Relocate_Node (First_Actual (N));
685 begin
687 -- We replace the function call by the following expression
689 -- if Opnd < 0.0 then
690 -- True
691 -- else
692 -- if Opnd > 0.0 then
693 -- False;
694 -- else
695 -- Float_Unsigned!(Float (Opnd)) /= 0
696 -- end if;
697 -- end if;
699 Rewrite (N,
700 Make_If_Expression (Loc,
701 Expressions => New_List (
702 Make_Op_Lt (Loc,
703 Left_Opnd => Duplicate_Subexpr (Opnd),
704 Right_Opnd => Make_Real_Literal (Loc, Ureal_0)),
706 New_Occurrence_Of (Standard_True, Loc),
708 Make_If_Expression (Loc,
709 Expressions => New_List (
710 Make_Op_Gt (Loc,
711 Left_Opnd => Duplicate_Subexpr_No_Checks (Opnd),
712 Right_Opnd => Make_Real_Literal (Loc, Ureal_0)),
714 New_Occurrence_Of (Standard_False, Loc),
716 Make_Op_Ne (Loc,
717 Left_Opnd =>
718 Unchecked_Convert_To
719 (RTE (RE_Float_Unsigned),
720 Convert_To
721 (Standard_Float,
722 Duplicate_Subexpr_No_Checks (Opnd))),
723 Right_Opnd =>
724 Make_Integer_Literal (Loc, 0)))))));
726 Analyze_And_Resolve (N, Standard_Boolean);
727 end Expand_Is_Negative;
729 ------------------
730 -- Expand_Shift --
731 ------------------
733 -- This procedure is used to convert a call to a shift function to the
734 -- corresponding operator node. This conversion is not done by the usual
735 -- circuit for converting calls to operator functions (e.g. "+"(1,2)) to
736 -- operator nodes, because shifts are not predefined operators.
738 -- As a result, whenever a shift is used in the source program, it will
739 -- remain as a call until converted by this routine to the operator node
740 -- form which the back end is expecting to see.
742 -- Note: it is possible for the expander to generate shift operator nodes
743 -- directly, which will be analyzed in the normal manner by calling Analyze
744 -- and Resolve. Such shift operator nodes will not be seen by Expand_Shift.
746 procedure Expand_Shift (N : Node_Id; E : Entity_Id; K : Node_Kind) is
747 Entyp : constant Entity_Id := Etype (E);
748 Left : constant Node_Id := First_Actual (N);
749 Loc : constant Source_Ptr := Sloc (N);
750 Right : constant Node_Id := Next_Actual (Left);
751 Ltyp : constant Node_Id := Etype (Left);
752 Rtyp : constant Node_Id := Etype (Right);
753 Typ : constant Entity_Id := Etype (N);
754 Snode : Node_Id;
756 begin
757 Snode := New_Node (K, Loc);
758 Set_Right_Opnd (Snode, Relocate_Node (Right));
759 Set_Chars (Snode, Chars (E));
760 Set_Etype (Snode, Base_Type (Entyp));
761 Set_Entity (Snode, E);
763 if Compile_Time_Known_Value (Type_High_Bound (Rtyp))
764 and then Expr_Value (Type_High_Bound (Rtyp)) < Esize (Ltyp)
765 then
766 Set_Shift_Count_OK (Snode, True);
767 end if;
769 if Typ = Entyp then
771 -- Note that we don't call Analyze and Resolve on this node, because
772 -- it already got analyzed and resolved when it was a function call.
774 Set_Left_Opnd (Snode, Relocate_Node (Left));
775 Rewrite (N, Snode);
776 Set_Analyzed (N);
778 -- However, we do call the expander, so that the expansion for
779 -- rotates and shift_right_arithmetic happens if Modify_Tree_For_C
780 -- is set.
782 if Expander_Active then
783 Expand (N);
784 end if;
786 else
787 -- If the context type is not the type of the operator, it is an
788 -- inherited operator for a derived type. Wrap the node in a
789 -- conversion so that it is type-consistent for possible further
790 -- expansion (e.g. within a lock-free protected type).
792 Set_Left_Opnd (Snode,
793 Unchecked_Convert_To (Base_Type (Entyp), Relocate_Node (Left)));
794 Rewrite (N, Unchecked_Convert_To (Typ, Snode));
796 -- Analyze and resolve result formed by conversion to target type
798 Analyze_And_Resolve (N, Typ);
799 end if;
800 end Expand_Shift;
802 ------------------------
803 -- Expand_Source_Info --
804 ------------------------
806 procedure Expand_Source_Info (N : Node_Id; Nam : Name_Id) is
807 Loc : constant Source_Ptr := Sloc (N);
808 Ent : Entity_Id;
810 begin
811 -- Integer cases
813 if Nam = Name_Line then
814 Rewrite (N,
815 Make_Integer_Literal (Loc,
816 Intval => UI_From_Int (Int (Get_Logical_Line_Number (Loc)))));
817 Analyze_And_Resolve (N, Standard_Positive);
819 -- String cases
821 else
822 Name_Len := 0;
824 case Nam is
825 when Name_File =>
826 Get_Decoded_Name_String
827 (Reference_Name (Get_Source_File_Index (Loc)));
829 when Name_Source_Location =>
830 Build_Location_String (Loc);
832 when Name_Enclosing_Entity =>
834 -- Skip enclosing blocks to reach enclosing unit
836 Ent := Current_Scope;
837 while Present (Ent) loop
838 exit when Ekind (Ent) /= E_Block
839 and then Ekind (Ent) /= E_Loop;
840 Ent := Scope (Ent);
841 end loop;
843 -- Ent now points to the relevant defining entity
845 Write_Entity_Name (Ent);
847 when Name_Compilation_Date =>
848 declare
849 subtype S13 is String (1 .. 3);
850 Months : constant array (1 .. 12) of S13 :=
851 ("Jan", "Feb", "Mar", "Apr", "May", "Jun",
852 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
854 M1 : constant Character := Opt.Compilation_Time (6);
855 M2 : constant Character := Opt.Compilation_Time (7);
857 MM : constant Natural range 1 .. 12 :=
858 (Character'Pos (M1) - Character'Pos ('0')) * 10 +
859 (Character'Pos (M2) - Character'Pos ('0'));
861 begin
862 -- Reformat ISO date into MMM DD YYYY (__DATE__) format
864 Name_Buffer (1 .. 3) := Months (MM);
865 Name_Buffer (4) := ' ';
866 Name_Buffer (5 .. 6) := Opt.Compilation_Time (9 .. 10);
867 Name_Buffer (7) := ' ';
868 Name_Buffer (8 .. 11) := Opt.Compilation_Time (1 .. 4);
869 Name_Len := 11;
870 end;
872 when Name_Compilation_Time =>
873 Name_Buffer (1 .. 8) := Opt.Compilation_Time (12 .. 19);
874 Name_Len := 8;
876 when others =>
877 raise Program_Error;
878 end case;
880 Rewrite (N,
881 Make_String_Literal (Loc,
882 Strval => String_From_Name_Buffer));
883 Analyze_And_Resolve (N, Standard_String);
884 end if;
886 Set_Is_Static_Expression (N);
887 end Expand_Source_Info;
889 ---------------------------
890 -- Expand_Unc_Conversion --
891 ---------------------------
893 procedure Expand_Unc_Conversion (N : Node_Id; E : Entity_Id) is
894 Func : constant Entity_Id := Entity (Name (N));
895 Conv : Node_Id;
896 Ftyp : Entity_Id;
897 Ttyp : Entity_Id;
899 begin
900 -- Rewrite as unchecked conversion node. Note that we must convert
901 -- the operand to the formal type of the input parameter of the
902 -- function, so that the resulting N_Unchecked_Type_Conversion
903 -- call indicates the correct types for Gigi.
905 -- Right now, we only do this if a scalar type is involved. It is
906 -- not clear if it is needed in other cases. If we do attempt to
907 -- do the conversion unconditionally, it crashes 3411-018. To be
908 -- investigated further ???
910 Conv := Relocate_Node (First_Actual (N));
911 Ftyp := Etype (First_Formal (Func));
913 if Is_Scalar_Type (Ftyp) then
914 Conv := Convert_To (Ftyp, Conv);
915 Set_Parent (Conv, N);
916 Analyze_And_Resolve (Conv);
917 end if;
919 -- The instantiation of Unchecked_Conversion creates a wrapper package,
920 -- and the target type is declared as a subtype of the actual. Recover
921 -- the actual, which is the subtype indic. in the subtype declaration
922 -- for the target type. This is semantically correct, and avoids
923 -- anomalies with access subtypes. For entities, leave type as is.
925 -- We do the analysis here, because we do not want the compiler
926 -- to try to optimize or otherwise reorganize the unchecked
927 -- conversion node.
929 Ttyp := Etype (E);
931 if Is_Entity_Name (Conv) then
932 null;
934 elsif Nkind (Parent (Ttyp)) = N_Subtype_Declaration then
935 Ttyp := Entity (Subtype_Indication (Parent (Etype (E))));
937 elsif Is_Itype (Ttyp) then
938 Ttyp :=
939 Entity (Subtype_Indication (Associated_Node_For_Itype (Ttyp)));
940 else
941 raise Program_Error;
942 end if;
944 Rewrite (N, Unchecked_Convert_To (Ttyp, Conv));
945 Set_Etype (N, Ttyp);
946 Set_Analyzed (N);
948 if Nkind (N) = N_Unchecked_Type_Conversion then
949 Expand_N_Unchecked_Type_Conversion (N);
950 end if;
951 end Expand_Unc_Conversion;
953 -----------------------------
954 -- Expand_Unc_Deallocation --
955 -----------------------------
957 -- Generate the following Code :
959 -- if Arg /= null then
960 -- <Finalize_Call> (.., T'Class(Arg.all), ..); -- for controlled types
961 -- Free (Arg);
962 -- Arg := Null;
963 -- end if;
965 -- For a task, we also generate a call to Free_Task to ensure that the
966 -- task itself is freed if it is terminated, ditto for a simple protected
967 -- object, with a call to Finalize_Protection. For composite types that
968 -- have tasks or simple protected objects as components, we traverse the
969 -- structures to find and terminate those components.
971 procedure Expand_Unc_Deallocation (N : Node_Id) is
972 Arg : constant Node_Id := First_Actual (N);
973 Loc : constant Source_Ptr := Sloc (N);
974 Typ : constant Entity_Id := Etype (Arg);
975 Desig_T : constant Entity_Id := Designated_Type (Typ);
976 Rtyp : constant Entity_Id := Underlying_Type (Root_Type (Typ));
977 Pool : constant Entity_Id := Associated_Storage_Pool (Rtyp);
978 Stmts : constant List_Id := New_List;
979 Needs_Fin : constant Boolean := Needs_Finalization (Desig_T);
981 Finalizer_Data : Finalization_Exception_Data;
983 Blk : Node_Id := Empty;
984 Blk_Id : Entity_Id;
985 Deref : Node_Id;
986 Final_Code : List_Id;
987 Free_Arg : Node_Id;
988 Free_Node : Node_Id;
989 Gen_Code : Node_Id;
991 Arg_Known_Non_Null : constant Boolean := Known_Non_Null (N);
992 -- This captures whether we know the argument to be non-null so that
993 -- we can avoid the test. The reason that we need to capture this is
994 -- that we analyze some generated statements before properly attaching
995 -- them to the tree, and that can disturb current value settings.
997 Dummy : Entity_Id;
998 -- This variable captures an unused dummy internal entity, see the
999 -- comment associated with its use.
1001 begin
1002 -- Nothing to do if we know the argument is null
1004 if Known_Null (N) then
1005 return;
1006 end if;
1008 -- Processing for pointer to controlled type
1010 if Needs_Fin then
1011 Deref :=
1012 Make_Explicit_Dereference (Loc,
1013 Prefix => Duplicate_Subexpr_No_Checks (Arg));
1015 -- If the type is tagged, then we must force dispatching on the
1016 -- finalization call because the designated type may not be the
1017 -- actual type of the object.
1019 if Is_Tagged_Type (Desig_T)
1020 and then not Is_Class_Wide_Type (Desig_T)
1021 then
1022 Deref := Unchecked_Convert_To (Class_Wide_Type (Desig_T), Deref);
1024 elsif not Is_Tagged_Type (Desig_T) then
1026 -- Set type of result, to force a conversion when needed (see
1027 -- exp_ch7, Convert_View), given that Deep_Finalize may be
1028 -- inherited from the parent type, and we need the type of the
1029 -- expression to see whether the conversion is in fact needed.
1031 Set_Etype (Deref, Desig_T);
1032 end if;
1034 -- The finalization call is expanded wrapped in a block to catch any
1035 -- possible exception. If an exception does occur, then Program_Error
1036 -- must be raised following the freeing of the object and its removal
1037 -- from the finalization collection's list. We set a flag to record
1038 -- that an exception was raised, and save its occurrence for use in
1039 -- the later raise.
1041 -- Generate:
1042 -- Abort : constant Boolean :=
1043 -- Exception_Occurrence (Get_Current_Excep.all.all) =
1044 -- Standard'Abort_Signal'Identity;
1045 -- <or>
1046 -- Abort : constant Boolean := False; -- no abort
1048 -- E : Exception_Occurrence;
1049 -- Raised : Boolean := False;
1051 -- begin
1052 -- [Deep_]Finalize (Obj);
1053 -- exception
1054 -- when others =>
1055 -- Raised := True;
1056 -- Save_Occurrence (E, Get_Current_Excep.all.all);
1057 -- end;
1059 Build_Object_Declarations (Finalizer_Data, Stmts, Loc);
1061 Final_Code := New_List (
1062 Make_Block_Statement (Loc,
1063 Handled_Statement_Sequence =>
1064 Make_Handled_Sequence_Of_Statements (Loc,
1065 Statements => New_List (
1066 Make_Final_Call (Obj_Ref => Deref, Typ => Desig_T)),
1067 Exception_Handlers => New_List (
1068 Build_Exception_Handler (Finalizer_Data)))));
1070 -- For .NET/JVM, detach the object from the containing finalization
1071 -- collection before finalizing it.
1073 if VM_Target /= No_VM and then Is_Controlled (Desig_T) then
1074 Prepend_To (Final_Code,
1075 Make_Detach_Call (New_Copy_Tree (Arg)));
1076 end if;
1078 -- If aborts are allowed, then the finalization code must be
1079 -- protected by an abort defer/undefer pair.
1081 if Abort_Allowed then
1082 Prepend_To (Final_Code, Build_Runtime_Call (Loc, RE_Abort_Defer));
1084 Blk :=
1085 Make_Block_Statement (Loc, Handled_Statement_Sequence =>
1086 Make_Handled_Sequence_Of_Statements (Loc,
1087 Statements => Final_Code,
1088 At_End_Proc =>
1089 New_Occurrence_Of (RTE (RE_Abort_Undefer_Direct), Loc)));
1090 Add_Block_Identifier (Blk, Blk_Id);
1092 Append (Blk, Stmts);
1094 else
1095 -- Generate a dummy entity to ensure that the internal symbols are
1096 -- in sync when a unit is compiled with and without aborts.
1098 Dummy := New_Internal_Entity (E_Block, Current_Scope, Loc, 'B');
1099 Append_List_To (Stmts, Final_Code);
1100 end if;
1101 end if;
1103 -- For a task type, call Free_Task before freeing the ATCB
1105 if Is_Task_Type (Desig_T) then
1107 -- We used to detect the case of Abort followed by a Free here,
1108 -- because the Free wouldn't actually free if it happens before
1109 -- the aborted task actually terminates. The warning was removed,
1110 -- because Free now works properly (the task will be freed once
1111 -- it terminates).
1113 Append_To
1114 (Stmts, Cleanup_Task (N, Duplicate_Subexpr_No_Checks (Arg)));
1116 -- For composite types that contain tasks, recurse over the structure
1117 -- to build the selectors for the task subcomponents.
1119 elsif Has_Task (Desig_T) then
1120 if Is_Record_Type (Desig_T) then
1121 Append_List_To (Stmts, Cleanup_Record (N, Arg, Desig_T));
1123 elsif Is_Array_Type (Desig_T) then
1124 Append_List_To (Stmts, Cleanup_Array (N, Arg, Desig_T));
1125 end if;
1126 end if;
1128 -- Same for simple protected types. Eventually call Finalize_Protection
1129 -- before freeing the PO for each protected component.
1131 if Is_Simple_Protected_Type (Desig_T) then
1132 Append_To (Stmts,
1133 Cleanup_Protected_Object (N, Duplicate_Subexpr_No_Checks (Arg)));
1135 elsif Has_Simple_Protected_Object (Desig_T) then
1136 if Is_Record_Type (Desig_T) then
1137 Append_List_To (Stmts, Cleanup_Record (N, Arg, Desig_T));
1138 elsif Is_Array_Type (Desig_T) then
1139 Append_List_To (Stmts, Cleanup_Array (N, Arg, Desig_T));
1140 end if;
1141 end if;
1143 -- Normal processing for non-controlled types. The argument to free is
1144 -- a renaming rather than a constant to ensure that the original context
1145 -- is always set to null after the deallocation takes place.
1147 Free_Arg := Duplicate_Subexpr_No_Checks (Arg, Renaming_Req => True);
1148 Free_Node := Make_Free_Statement (Loc, Empty);
1149 Append_To (Stmts, Free_Node);
1150 Set_Storage_Pool (Free_Node, Pool);
1152 -- Attach to tree before analysis of generated subtypes below
1154 Set_Parent (Stmts, Parent (N));
1156 -- Deal with storage pool
1158 if Present (Pool) then
1160 -- Freeing the secondary stack is meaningless
1162 if Is_RTE (Pool, RE_SS_Pool) then
1163 null;
1165 -- If the pool object is of a simple storage pool type, then attempt
1166 -- to locate the type's Deallocate procedure, if any, and set the
1167 -- free operation's procedure to call. If the type doesn't have a
1168 -- Deallocate (which is allowed), then the actual will simply be set
1169 -- to null.
1171 elsif Present (Get_Rep_Pragma
1172 (Etype (Pool), Name_Simple_Storage_Pool_Type))
1173 then
1174 declare
1175 Pool_Type : constant Entity_Id := Base_Type (Etype (Pool));
1176 Dealloc_Op : Entity_Id;
1177 begin
1178 Dealloc_Op := Get_Name_Entity_Id (Name_Deallocate);
1179 while Present (Dealloc_Op) loop
1180 if Scope (Dealloc_Op) = Scope (Pool_Type)
1181 and then Present (First_Formal (Dealloc_Op))
1182 and then Etype (First_Formal (Dealloc_Op)) = Pool_Type
1183 then
1184 Set_Procedure_To_Call (Free_Node, Dealloc_Op);
1185 exit;
1186 else
1187 Dealloc_Op := Homonym (Dealloc_Op);
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_Node, RTE (RE_Deallocate_Any));
1198 -- Case of a specific pool type: make a statically bound call
1200 else
1201 Set_Procedure_To_Call (Free_Node,
1202 Find_Prim_Op (Etype (Pool), Name_Deallocate));
1203 end if;
1204 end if;
1206 if Present (Procedure_To_Call (Free_Node)) 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_T)
1218 or else
1219 (Is_Array_Type (Desig_T)
1220 and then not Is_Constrained (Desig_T)
1221 and then Is_Packed (Desig_T))
1222 then
1223 declare
1224 Deref : constant Node_Id :=
1225 Make_Explicit_Dereference (Loc,
1226 Duplicate_Subexpr_No_Checks (Arg));
1227 D_Subtyp : Node_Id;
1228 D_Type : Entity_Id;
1230 begin
1231 -- Perform minor decoration as it is needed by the side effect
1232 -- removal mechanism.
1234 Set_Etype (Deref, Desig_T);
1235 Set_Parent (Deref, Free_Node);
1236 D_Subtyp := Make_Subtype_From_Expr (Deref, Desig_T);
1238 if Nkind (D_Subtyp) in N_Has_Entity then
1239 D_Type := Entity (D_Subtyp);
1241 else
1242 D_Type := Make_Temporary (Loc, 'A');
1243 Insert_Action (Deref,
1244 Make_Subtype_Declaration (Loc,
1245 Defining_Identifier => D_Type,
1246 Subtype_Indication => D_Subtyp));
1247 end if;
1249 -- Force freezing at the point of the dereference. For the
1250 -- class wide case, this avoids having the subtype frozen
1251 -- before the equivalent type.
1253 Freeze_Itype (D_Type, Deref);
1255 Set_Actual_Designated_Subtype (Free_Node, D_Type);
1256 end;
1258 end if;
1259 end if;
1261 -- Ada 2005 (AI-251): In case of abstract interface type we must
1262 -- displace the pointer to reference the base of the object to
1263 -- deallocate its memory, unless we're targetting a VM, in which case
1264 -- no special processing is required.
1266 -- Generate:
1267 -- free (Base_Address (Obj_Ptr))
1269 if Is_Interface (Directly_Designated_Type (Typ))
1270 and then Tagged_Type_Expansion
1271 then
1272 Set_Expression (Free_Node,
1273 Unchecked_Convert_To (Typ,
1274 Make_Function_Call (Loc,
1275 Name => New_Occurrence_Of (RTE (RE_Base_Address), Loc),
1276 Parameter_Associations => New_List (
1277 Unchecked_Convert_To (RTE (RE_Address), Free_Arg)))));
1279 -- Generate:
1280 -- free (Obj_Ptr)
1282 else
1283 Set_Expression (Free_Node, Free_Arg);
1284 end if;
1286 -- Only remaining step is to set result to null, or generate a raise of
1287 -- Constraint_Error if the target object is "not null".
1289 if Can_Never_Be_Null (Etype (Arg)) then
1290 Append_To (Stmts,
1291 Make_Raise_Constraint_Error (Loc,
1292 Reason => CE_Access_Check_Failed));
1294 else
1295 declare
1296 Lhs : constant Node_Id := Duplicate_Subexpr_No_Checks (Arg);
1297 begin
1298 Set_Assignment_OK (Lhs);
1299 Append_To (Stmts,
1300 Make_Assignment_Statement (Loc,
1301 Name => Lhs,
1302 Expression => Make_Null (Loc)));
1303 end;
1304 end if;
1306 -- Generate a test of whether any earlier finalization raised an
1307 -- exception, and in that case raise Program_Error with the previous
1308 -- exception occurrence.
1310 -- Generate:
1311 -- if Raised and then not Abort then
1312 -- raise Program_Error; -- for .NET and
1313 -- -- restricted RTS
1314 -- <or>
1315 -- Raise_From_Controlled_Operation (E); -- all other cases
1316 -- end if;
1318 if Needs_Fin then
1319 Append_To (Stmts, Build_Raise_Statement (Finalizer_Data));
1320 end if;
1322 -- If we know the argument is non-null, then make a block statement
1323 -- that contains the required statements, no need for a test.
1325 if Arg_Known_Non_Null then
1326 Gen_Code :=
1327 Make_Block_Statement (Loc,
1328 Handled_Statement_Sequence =>
1329 Make_Handled_Sequence_Of_Statements (Loc,
1330 Statements => Stmts));
1332 -- If the argument may be null, wrap the statements inside an IF that
1333 -- does an explicit test to exclude the null case.
1335 else
1336 Gen_Code :=
1337 Make_Implicit_If_Statement (N,
1338 Condition =>
1339 Make_Op_Ne (Loc,
1340 Left_Opnd => Duplicate_Subexpr (Arg),
1341 Right_Opnd => Make_Null (Loc)),
1342 Then_Statements => Stmts);
1343 end if;
1345 -- Rewrite the call
1347 Rewrite (N, Gen_Code);
1348 Analyze (N);
1350 -- If we generated a block with an At_End_Proc, expand the exception
1351 -- handler. We need to wait until after everything else is analyzed.
1353 if Present (Blk) then
1354 Expand_At_End_Handler
1355 (Handled_Statement_Sequence (Blk), Entity (Identifier (Blk)));
1356 end if;
1357 end Expand_Unc_Deallocation;
1359 -----------------------
1360 -- Expand_To_Address --
1361 -----------------------
1363 procedure Expand_To_Address (N : Node_Id) is
1364 Loc : constant Source_Ptr := Sloc (N);
1365 Arg : constant Node_Id := First_Actual (N);
1366 Obj : Node_Id;
1368 begin
1369 Remove_Side_Effects (Arg);
1371 Obj := Make_Explicit_Dereference (Loc, Relocate_Node (Arg));
1373 Rewrite (N,
1374 Make_If_Expression (Loc,
1375 Expressions => New_List (
1376 Make_Op_Eq (Loc,
1377 Left_Opnd => New_Copy_Tree (Arg),
1378 Right_Opnd => Make_Null (Loc)),
1379 New_Occurrence_Of (RTE (RE_Null_Address), Loc),
1380 Make_Attribute_Reference (Loc,
1381 Prefix => Obj,
1382 Attribute_Name => Name_Address))));
1384 Analyze_And_Resolve (N, RTE (RE_Address));
1385 end Expand_To_Address;
1387 -----------------------
1388 -- Expand_To_Pointer --
1389 -----------------------
1391 procedure Expand_To_Pointer (N : Node_Id) is
1392 Arg : constant Node_Id := First_Actual (N);
1394 begin
1395 Rewrite (N, Unchecked_Convert_To (Etype (N), Arg));
1396 Analyze (N);
1397 end Expand_To_Pointer;
1399 -----------------------
1400 -- Write_Entity_Name --
1401 -----------------------
1403 procedure Write_Entity_Name (E : Entity_Id) is
1404 SDef : Source_Ptr;
1405 TDef : constant Source_Buffer_Ptr :=
1406 Source_Text (Get_Source_File_Index (Sloc (E)));
1408 begin
1409 -- Nothing to do if at outer level
1411 if Scope (E) = Standard_Standard then
1412 null;
1414 -- If scope comes from source, write its name
1416 elsif Comes_From_Source (Scope (E)) then
1417 Write_Entity_Name (Scope (E));
1418 Add_Char_To_Name_Buffer ('.');
1420 -- If in wrapper package skip past it
1422 elsif Is_Wrapper_Package (Scope (E)) then
1423 Write_Entity_Name (Scope (Scope (E)));
1424 Add_Char_To_Name_Buffer ('.');
1426 -- Otherwise nothing to output (happens in unnamed block statements)
1428 else
1429 null;
1430 end if;
1432 -- Output the name
1434 SDef := Sloc (E);
1436 -- Check for operator name in quotes
1438 if TDef (SDef) = '"' then
1439 Add_Char_To_Name_Buffer ('"');
1441 -- Loop to output characters of operator name and terminating quote
1443 loop
1444 SDef := SDef + 1;
1445 Add_Char_To_Name_Buffer (TDef (SDef));
1446 exit when TDef (SDef) = '"';
1447 end loop;
1449 -- Normal case of identifier
1451 else
1452 -- Loop to output the name
1454 -- This is not right wrt wide char encodings ??? ()
1456 while TDef (SDef) in '0' .. '9'
1457 or else TDef (SDef) >= 'A'
1458 or else TDef (SDef) = ASCII.ESC
1459 loop
1460 Add_Char_To_Name_Buffer (TDef (SDef));
1461 SDef := SDef + 1;
1462 end loop;
1463 end if;
1464 end Write_Entity_Name;
1465 end Exp_Intr;