Fix typo in t-dimode
[official-gcc.git] / gcc / ada / inline.adb
blob08c454d366e62ebf84cb4ae7fcb8c1a49bbd48da
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- I N L I N E --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2021, 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 Alloc;
27 with Aspects; use Aspects;
28 with Atree; use Atree;
29 with Debug; use Debug;
30 with Einfo; use Einfo;
31 with Einfo.Entities; use Einfo.Entities;
32 with Einfo.Utils; use Einfo.Utils;
33 with Elists; use Elists;
34 with Errout; use Errout;
35 with Expander; use Expander;
36 with Exp_Ch6; use Exp_Ch6;
37 with Exp_Ch7; use Exp_Ch7;
38 with Exp_Tss; use Exp_Tss;
39 with Exp_Util; use Exp_Util;
40 with Fname; use Fname;
41 with Fname.UF; use Fname.UF;
42 with Lib; use Lib;
43 with Namet; use Namet;
44 with Nmake; use Nmake;
45 with Nlists; use Nlists;
46 with Output; use Output;
47 with Sem_Aux; use Sem_Aux;
48 with Sem_Ch8; use Sem_Ch8;
49 with Sem_Ch10; use Sem_Ch10;
50 with Sem_Ch12; use Sem_Ch12;
51 with Sem_Prag; use Sem_Prag;
52 with Sem_Res; use Sem_Res;
53 with Sem_Util; use Sem_Util;
54 with Sinfo; use Sinfo;
55 with Sinfo.Nodes; use Sinfo.Nodes;
56 with Sinfo.Utils; use Sinfo.Utils;
57 with Sinput; use Sinput;
58 with Snames; use Snames;
59 with Stand; use Stand;
60 with Table;
61 with Tbuild; use Tbuild;
62 with Uintp; use Uintp;
63 with Uname; use Uname;
65 with GNAT.HTable;
67 package body Inline is
69 Check_Inlining_Restrictions : constant Boolean := True;
70 -- In the following cases the frontend rejects inlining because they
71 -- are not handled well by the backend. This variable facilitates
72 -- disabling these restrictions to evaluate future versions of the
73 -- GCC backend in which some of the restrictions may be supported.
75 -- - subprograms that have:
76 -- - nested subprograms
77 -- - instantiations
78 -- - package declarations
79 -- - task or protected object declarations
80 -- - some of the following statements:
81 -- - abort
82 -- - asynchronous-select
83 -- - conditional-entry-call
84 -- - delay-relative
85 -- - delay-until
86 -- - selective-accept
87 -- - timed-entry-call
89 Inlined_Calls : Elist_Id;
90 -- List of frontend inlined calls
92 Backend_Calls : Elist_Id;
93 -- List of inline calls passed to the backend
95 Backend_Instances : Elist_Id;
96 -- List of instances inlined for the backend
98 Backend_Inlined_Subps : Elist_Id;
99 -- List of subprograms inlined by the backend
101 Backend_Not_Inlined_Subps : Elist_Id;
102 -- List of subprograms that cannot be inlined by the backend
104 -----------------------------
105 -- Pending_Instantiations --
106 -----------------------------
108 -- We make entries in this table for the pending instantiations of generic
109 -- bodies that are created during semantic analysis. After the analysis is
110 -- complete, calling Instantiate_Bodies performs the actual instantiations.
112 package Pending_Instantiations is new Table.Table (
113 Table_Component_Type => Pending_Body_Info,
114 Table_Index_Type => Int,
115 Table_Low_Bound => 0,
116 Table_Initial => Alloc.Pending_Instantiations_Initial,
117 Table_Increment => Alloc.Pending_Instantiations_Increment,
118 Table_Name => "Pending_Instantiations");
120 -------------------------------------
121 -- Called_Pending_Instantiations --
122 -------------------------------------
124 -- With back-end inlining, the pending instantiations that are not in the
125 -- main unit or subunit are performed only after a call to the subprogram
126 -- instance, or to a subprogram within the package instance, is inlined.
127 -- Since such a call can be within a subsequent pending instantiation,
128 -- we make entries in this table that stores the index of these "called"
129 -- pending instantiations and perform them when the table is populated.
131 package Called_Pending_Instantiations is new Table.Table (
132 Table_Component_Type => Int,
133 Table_Index_Type => Int,
134 Table_Low_Bound => 0,
135 Table_Initial => Alloc.Pending_Instantiations_Initial,
136 Table_Increment => Alloc.Pending_Instantiations_Increment,
137 Table_Name => "Called_Pending_Instantiations");
139 ---------------------------------
140 -- To_Pending_Instantiations --
141 ---------------------------------
143 -- With back-end inlining, we also need to have a map from the pending
144 -- instantiations to their index in the Pending_Instantiations table.
146 Node_Table_Size : constant := 257;
147 -- Number of headers in hash table
149 subtype Node_Header_Num is Integer range 0 .. Node_Table_Size - 1;
150 -- Range of headers in hash table
152 function Node_Hash (Id : Node_Id) return Node_Header_Num;
153 -- Simple hash function for Node_Ids
155 package To_Pending_Instantiations is new GNAT.Htable.Simple_HTable
156 (Header_Num => Node_Header_Num,
157 Element => Int,
158 No_Element => -1,
159 Key => Node_Id,
160 Hash => Node_Hash,
161 Equal => "=");
163 -----------------
164 -- Node_Hash --
165 -----------------
167 function Node_Hash (Id : Node_Id) return Node_Header_Num is
168 begin
169 return Node_Header_Num (Id mod Node_Table_Size);
170 end Node_Hash;
172 --------------------
173 -- Inlined Bodies --
174 --------------------
176 -- Inlined functions are actually placed in line by the backend if the
177 -- corresponding bodies are available (i.e. compiled). Whenever we find
178 -- a call to an inlined subprogram, we add the name of the enclosing
179 -- compilation unit to a worklist. After all compilation, and after
180 -- expansion of generic bodies, we traverse the list of pending bodies
181 -- and compile them as well.
183 package Inlined_Bodies is new Table.Table (
184 Table_Component_Type => Entity_Id,
185 Table_Index_Type => Int,
186 Table_Low_Bound => 0,
187 Table_Initial => Alloc.Inlined_Bodies_Initial,
188 Table_Increment => Alloc.Inlined_Bodies_Increment,
189 Table_Name => "Inlined_Bodies");
191 -----------------------
192 -- Inline Processing --
193 -----------------------
195 -- For each call to an inlined subprogram, we make entries in a table
196 -- that stores caller and callee, and indicates the call direction from
197 -- one to the other. We also record the compilation unit that contains
198 -- the callee. After analyzing the bodies of all such compilation units,
199 -- we compute the transitive closure of inlined subprograms called from
200 -- the main compilation unit and make it available to the code generator
201 -- in no particular order, thus allowing cycles in the call graph.
203 Last_Inlined : Entity_Id := Empty;
205 -- For each entry in the table we keep a list of successors in topological
206 -- order, i.e. callers of the current subprogram.
208 type Subp_Index is new Nat;
209 No_Subp : constant Subp_Index := 0;
211 -- The subprogram entities are hashed into the Inlined table
213 Num_Hash_Headers : constant := 512;
215 Hash_Headers : array (Subp_Index range 0 .. Num_Hash_Headers - 1)
216 of Subp_Index;
218 type Succ_Index is new Nat;
219 No_Succ : constant Succ_Index := 0;
221 type Succ_Info is record
222 Subp : Subp_Index;
223 Next : Succ_Index;
224 end record;
226 -- The following table stores list elements for the successor lists. These
227 -- lists cannot be chained directly through entries in the Inlined table,
228 -- because a given subprogram can appear in several such lists.
230 package Successors is new Table.Table (
231 Table_Component_Type => Succ_Info,
232 Table_Index_Type => Succ_Index,
233 Table_Low_Bound => 1,
234 Table_Initial => Alloc.Successors_Initial,
235 Table_Increment => Alloc.Successors_Increment,
236 Table_Name => "Successors");
238 type Subp_Info is record
239 Name : Entity_Id := Empty;
240 Next : Subp_Index := No_Subp;
241 First_Succ : Succ_Index := No_Succ;
242 Main_Call : Boolean := False;
243 Processed : Boolean := False;
244 end record;
246 package Inlined is new Table.Table (
247 Table_Component_Type => Subp_Info,
248 Table_Index_Type => Subp_Index,
249 Table_Low_Bound => 1,
250 Table_Initial => Alloc.Inlined_Initial,
251 Table_Increment => Alloc.Inlined_Increment,
252 Table_Name => "Inlined");
254 -----------------------
255 -- Local Subprograms --
256 -----------------------
258 procedure Add_Call (Called : Entity_Id; Caller : Entity_Id := Empty);
259 -- Make two entries in Inlined table, for an inlined subprogram being
260 -- called, and for the inlined subprogram that contains the call. If
261 -- the call is in the main compilation unit, Caller is Empty.
263 procedure Add_Inlined_Instance (E : Entity_Id);
264 -- Add instance E to the list of inlined instances for the unit
266 procedure Add_Inlined_Subprogram (E : Entity_Id);
267 -- Add subprogram E to the list of inlined subprograms for the unit
269 function Add_Subp (E : Entity_Id) return Subp_Index;
270 -- Make entry in Inlined table for subprogram E, or return table index
271 -- that already holds E.
273 procedure Establish_Actual_Mapping_For_Inlined_Call
274 (N : Node_Id;
275 Subp : Entity_Id;
276 Decls : List_Id;
277 Body_Or_Expr_To_Check : Node_Id);
278 -- Establish a mapping from formals to actuals in the call N for the target
279 -- subprogram Subp, and create temporaries or renamings when needed for the
280 -- actuals that are expressions (except for actuals given by simple entity
281 -- names or literals) or that are scalars that require copying to preserve
282 -- semantics. Any temporary objects that are created are inserted in Decls.
283 -- Body_Or_Expr_To_Check indicates the target body (or possibly expression
284 -- of an expression function), which may be traversed to count formal uses.
286 function Get_Code_Unit_Entity (E : Entity_Id) return Entity_Id;
287 pragma Inline (Get_Code_Unit_Entity);
288 -- Return the entity node for the unit containing E. Always return the spec
289 -- for a package.
291 function Has_Initialized_Type (E : Entity_Id) return Boolean;
292 -- If a candidate for inlining contains type declarations for types with
293 -- nontrivial initialization procedures, they are not worth inlining.
295 function Has_Single_Return (N : Node_Id) return Boolean;
296 -- In general we cannot inline functions that return unconstrained type.
297 -- However, we can handle such functions if all return statements return
298 -- a local variable that is the first declaration in the body of the
299 -- function. In that case the call can be replaced by that local
300 -- variable as is done for other inlined calls.
302 function In_Main_Unit_Or_Subunit (E : Entity_Id) return Boolean;
303 -- Return True if E is in the main unit or its spec or in a subunit
305 function Is_Nested (E : Entity_Id) return Boolean;
306 -- If the function is nested inside some other function, it will always
307 -- be compiled if that function is, so don't add it to the inline list.
308 -- We cannot compile a nested function outside the scope of the containing
309 -- function anyway. This is also the case if the function is defined in a
310 -- task body or within an entry (for example, an initialization procedure).
312 procedure Remove_Aspects_And_Pragmas (Body_Decl : Node_Id);
313 -- Remove all aspects and/or pragmas that have no meaning in inlined body
314 -- Body_Decl. The analysis of these items is performed on the non-inlined
315 -- body. The items currently removed are:
316 -- Contract_Cases
317 -- Global
318 -- Depends
319 -- Postcondition
320 -- Precondition
321 -- Refined_Global
322 -- Refined_Depends
323 -- Refined_Post
324 -- Subprogram_Variant
325 -- Test_Case
326 -- Unmodified
327 -- Unreferenced
329 procedure Reset_Actual_Mapping_For_Inlined_Call (Subp : Entity_Id);
330 -- Reset the Renamed_Object field to Empty on all formals of Subp, which
331 -- can be set by a call to Establish_Actual_Mapping_For_Inlined_Call.
333 ------------------------------
334 -- Deferred Cleanup Actions --
335 ------------------------------
337 -- The cleanup actions for scopes that contain instantiations is delayed
338 -- until after expansion of those instantiations, because they may contain
339 -- finalizable objects or tasks that affect the cleanup code. A scope
340 -- that contains instantiations only needs to be finalized once, even
341 -- if it contains more than one instance. We keep a list of scopes
342 -- that must still be finalized, and call cleanup_actions after all
343 -- the instantiations have been completed.
345 To_Clean : Elist_Id;
347 procedure Add_Scope_To_Clean (Inst : Entity_Id);
348 -- Build set of scopes on which cleanup actions must be performed
350 procedure Cleanup_Scopes;
351 -- Complete cleanup actions on scopes that need it
353 --------------
354 -- Add_Call --
355 --------------
357 procedure Add_Call (Called : Entity_Id; Caller : Entity_Id := Empty) is
358 P1 : constant Subp_Index := Add_Subp (Called);
359 P2 : Subp_Index;
360 J : Succ_Index;
362 begin
363 if Present (Caller) then
364 P2 := Add_Subp (Caller);
366 -- Add P1 to the list of successors of P2, if not already there.
367 -- Note that P2 may contain more than one call to P1, and only
368 -- one needs to be recorded.
370 J := Inlined.Table (P2).First_Succ;
371 while J /= No_Succ loop
372 if Successors.Table (J).Subp = P1 then
373 return;
374 end if;
376 J := Successors.Table (J).Next;
377 end loop;
379 -- On exit, make a successor entry for P1
381 Successors.Increment_Last;
382 Successors.Table (Successors.Last).Subp := P1;
383 Successors.Table (Successors.Last).Next :=
384 Inlined.Table (P2).First_Succ;
385 Inlined.Table (P2).First_Succ := Successors.Last;
386 else
387 Inlined.Table (P1).Main_Call := True;
388 end if;
389 end Add_Call;
391 ----------------------
392 -- Add_Inlined_Body --
393 ----------------------
395 procedure Add_Inlined_Body (E : Entity_Id; N : Node_Id) is
397 type Inline_Level_Type is (Dont_Inline, Inline_Call, Inline_Package);
398 -- Level of inlining for the call: Dont_Inline means no inlining,
399 -- Inline_Call means that only the call is considered for inlining,
400 -- Inline_Package means that the call is considered for inlining and
401 -- its package compiled and scanned for more inlining opportunities.
403 function Is_Non_Loading_Expression_Function
404 (Id : Entity_Id) return Boolean;
405 -- Determine whether arbitrary entity Id denotes a subprogram which is
406 -- either
408 -- * An expression function
410 -- * A function completed by an expression function where both the
411 -- spec and body are in the same context.
413 function Must_Inline return Inline_Level_Type;
414 -- Inlining is only done if the call statement N is in the main unit,
415 -- or within the body of another inlined subprogram.
417 ----------------------------------------
418 -- Is_Non_Loading_Expression_Function --
419 ----------------------------------------
421 function Is_Non_Loading_Expression_Function
422 (Id : Entity_Id) return Boolean
424 Body_Decl : Node_Id;
425 Body_Id : Entity_Id;
426 Spec_Decl : Node_Id;
428 begin
429 -- A stand-alone expression function is transformed into a spec-body
430 -- pair in-place. Since both the spec and body are in the same list,
431 -- the inlining of such an expression function does not need to load
432 -- anything extra.
434 if Is_Expression_Function (Id) then
435 return True;
437 -- A function may be completed by an expression function
439 elsif Ekind (Id) = E_Function then
440 Spec_Decl := Unit_Declaration_Node (Id);
442 if Nkind (Spec_Decl) = N_Subprogram_Declaration then
443 Body_Id := Corresponding_Body (Spec_Decl);
445 if Present (Body_Id) then
446 Body_Decl := Unit_Declaration_Node (Body_Id);
448 -- The inlining of a completing expression function does
449 -- not need to load anything extra when both the spec and
450 -- body are in the same context.
452 return
453 Was_Expression_Function (Body_Decl)
454 and then Parent (Spec_Decl) = Parent (Body_Decl);
455 end if;
456 end if;
457 end if;
459 return False;
460 end Is_Non_Loading_Expression_Function;
462 -----------------
463 -- Must_Inline --
464 -----------------
466 function Must_Inline return Inline_Level_Type is
467 Scop : Entity_Id;
468 Comp : Node_Id;
470 begin
471 -- Check if call is in main unit
473 Scop := Current_Scope;
475 -- Do not try to inline if scope is standard. This could happen, for
476 -- example, for a call to Add_Global_Declaration, and it causes
477 -- trouble to try to inline at this level.
479 if Scop = Standard_Standard then
480 return Dont_Inline;
481 end if;
483 -- Otherwise lookup scope stack to outer scope
485 while Scope (Scop) /= Standard_Standard
486 and then not Is_Child_Unit (Scop)
487 loop
488 Scop := Scope (Scop);
489 end loop;
491 Comp := Parent (Scop);
492 while Nkind (Comp) /= N_Compilation_Unit loop
493 Comp := Parent (Comp);
494 end loop;
496 -- If the call is in the main unit, inline the call and compile the
497 -- package of the subprogram to find more calls to be inlined.
499 if Comp = Cunit (Main_Unit)
500 or else Comp = Library_Unit (Cunit (Main_Unit))
501 then
502 Add_Call (E);
503 return Inline_Package;
504 end if;
506 -- The call is not in the main unit. See if it is in some subprogram
507 -- that can be inlined outside its unit. If so, inline the call and,
508 -- if the inlining level is set to 1, stop there; otherwise also
509 -- compile the package as above.
511 Scop := Current_Scope;
512 while Scope (Scop) /= Standard_Standard
513 and then not Is_Child_Unit (Scop)
514 loop
515 if Is_Overloadable (Scop)
516 and then Is_Inlined (Scop)
517 and then not Is_Nested (Scop)
518 then
519 Add_Call (E, Scop);
521 if Inline_Level = 1 then
522 return Inline_Call;
523 else
524 return Inline_Package;
525 end if;
526 end if;
528 Scop := Scope (Scop);
529 end loop;
531 return Dont_Inline;
532 end Must_Inline;
534 Inst : Entity_Id;
535 Inst_Decl : Node_Id;
536 Level : Inline_Level_Type;
538 -- Start of processing for Add_Inlined_Body
540 begin
541 Append_New_Elmt (N, To => Backend_Calls);
543 -- Skip subprograms that cannot or need not be inlined outside their
544 -- unit or parent subprogram.
546 if Is_Abstract_Subprogram (E)
547 or else Convention (E) = Convention_Protected
548 or else In_Main_Unit_Or_Subunit (E)
549 or else Is_Nested (E)
550 then
551 return;
552 end if;
554 -- Find out whether the call must be inlined. Unless the result is
555 -- Dont_Inline, Must_Inline also creates an edge for the call in the
556 -- callgraph; however, it will not be activated until after Is_Called
557 -- is set on the subprogram.
559 Level := Must_Inline;
561 if Level = Dont_Inline then
562 return;
563 end if;
565 -- If a previous call to the subprogram has been inlined, nothing to do
567 if Is_Called (E) then
568 return;
569 end if;
571 -- If the subprogram is an instance, then inline the instance
573 if Is_Generic_Instance (E) then
574 Add_Inlined_Instance (E);
575 end if;
577 -- Mark the subprogram as called
579 Set_Is_Called (E);
581 -- If the call was generated by the compiler and is to a subprogram in
582 -- a run-time unit, we need to suppress debugging information for it,
583 -- so that the code that is eventually inlined will not affect the
584 -- debugging of the program. We do not do it if the call comes from
585 -- source because, even if the call is inlined, the user may expect it
586 -- to be present in the debugging information.
588 if not Comes_From_Source (N)
589 and then In_Extended_Main_Source_Unit (N)
590 and then Is_Predefined_Unit (Get_Source_Unit (E))
591 then
592 Set_Needs_Debug_Info (E, False);
593 end if;
595 -- If the subprogram is an expression function, or is completed by one
596 -- where both the spec and body are in the same context, then there is
597 -- no need to load any package body since the body of the function is
598 -- in the spec.
600 if Is_Non_Loading_Expression_Function (E) then
601 return;
602 end if;
604 -- Find unit containing E, and add to list of inlined bodies if needed.
605 -- Library-level functions must be handled specially, because there is
606 -- no enclosing package to retrieve. In this case, it is the body of
607 -- the function that will have to be loaded.
609 declare
610 Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
612 begin
613 if Pack = E then
614 Inlined_Bodies.Increment_Last;
615 Inlined_Bodies.Table (Inlined_Bodies.Last) := E;
617 else
618 pragma Assert (Ekind (Pack) = E_Package);
620 -- If the subprogram is within an instance, inline the instance
622 if Comes_From_Source (E) then
623 Inst := Scope (E);
625 while Present (Inst) and then Inst /= Standard_Standard loop
626 exit when Is_Generic_Instance (Inst);
627 Inst := Scope (Inst);
628 end loop;
630 if Present (Inst)
631 and then Is_Generic_Instance (Inst)
632 and then not Is_Called (Inst)
633 then
634 Inst_Decl := Unit_Declaration_Node (Inst);
636 -- Do not inline the instance if the body already exists,
637 -- or the instance node is simply missing.
639 if Present (Corresponding_Body (Inst_Decl))
640 or else (Nkind (Parent (Inst_Decl)) /= N_Compilation_Unit
641 and then No (Next (Inst_Decl)))
642 then
643 Set_Is_Called (Inst);
644 else
645 Add_Inlined_Instance (Inst);
646 end if;
647 end if;
648 end if;
650 -- If the unit containing E is an instance, nothing more to do
652 if Is_Generic_Instance (Pack) then
653 null;
655 -- Do not inline the package if the subprogram is an init proc
656 -- or other internally generated subprogram, because in that
657 -- case the subprogram body appears in the same unit that
658 -- declares the type, and that body is visible to the back end.
659 -- Do not inline it either if it is in the main unit.
660 -- Extend the -gnatn2 processing to -gnatn1 for Inline_Always
661 -- calls if the back end takes care of inlining the call.
662 -- Note that Level is in Inline_Call | Inline_Package here.
664 elsif ((Level = Inline_Call
665 and then Has_Pragma_Inline_Always (E)
666 and then Back_End_Inlining)
667 or else Level = Inline_Package)
668 and then not Is_Inlined (Pack)
669 and then not Is_Internal (E)
670 and then not In_Main_Unit_Or_Subunit (Pack)
671 then
672 Set_Is_Inlined (Pack);
673 Inlined_Bodies.Increment_Last;
674 Inlined_Bodies.Table (Inlined_Bodies.Last) := Pack;
675 end if;
676 end if;
678 -- Ensure that Analyze_Inlined_Bodies will be invoked after
679 -- completing the analysis of the current unit.
681 Inline_Processing_Required := True;
682 end;
683 end Add_Inlined_Body;
685 --------------------------
686 -- Add_Inlined_Instance --
687 --------------------------
689 procedure Add_Inlined_Instance (E : Entity_Id) is
690 Decl_Node : constant Node_Id := Unit_Declaration_Node (E);
691 Index : Int;
693 begin
694 -- This machinery is only used with back-end inlining
696 if not Back_End_Inlining then
697 return;
698 end if;
700 -- Register the instance in the list
702 Append_New_Elmt (Decl_Node, To => Backend_Instances);
704 -- Retrieve the index of its corresponding pending instantiation
705 -- and mark this corresponding pending instantiation as needed.
707 Index := To_Pending_Instantiations.Get (Decl_Node);
708 if Index >= 0 then
709 Called_Pending_Instantiations.Append (Index);
710 else
711 pragma Assert (False);
712 null;
713 end if;
715 Set_Is_Called (E);
716 end Add_Inlined_Instance;
718 ----------------------------
719 -- Add_Inlined_Subprogram --
720 ----------------------------
722 procedure Add_Inlined_Subprogram (E : Entity_Id) is
723 Decl : constant Node_Id := Parent (Declaration_Node (E));
724 Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
726 procedure Register_Backend_Inlined_Subprogram (Subp : Entity_Id);
727 -- Append Subp to the list of subprograms inlined by the backend
729 procedure Register_Backend_Not_Inlined_Subprogram (Subp : Entity_Id);
730 -- Append Subp to the list of subprograms that cannot be inlined by
731 -- the backend.
733 -----------------------------------------
734 -- Register_Backend_Inlined_Subprogram --
735 -----------------------------------------
737 procedure Register_Backend_Inlined_Subprogram (Subp : Entity_Id) is
738 begin
739 Append_New_Elmt (Subp, To => Backend_Inlined_Subps);
740 end Register_Backend_Inlined_Subprogram;
742 ---------------------------------------------
743 -- Register_Backend_Not_Inlined_Subprogram --
744 ---------------------------------------------
746 procedure Register_Backend_Not_Inlined_Subprogram (Subp : Entity_Id) is
747 begin
748 Append_New_Elmt (Subp, To => Backend_Not_Inlined_Subps);
749 end Register_Backend_Not_Inlined_Subprogram;
751 -- Start of processing for Add_Inlined_Subprogram
753 begin
754 -- We can inline the subprogram if its unit is known to be inlined or is
755 -- an instance whose body will be analyzed anyway or the subprogram was
756 -- generated as a body by the compiler (for example an initialization
757 -- procedure) or its declaration was provided along with the body (for
758 -- example an expression function) and it does not declare types with
759 -- nontrivial initialization procedures.
761 if (Is_Inlined (Pack)
762 or else Is_Generic_Instance (Pack)
763 or else Nkind (Decl) = N_Subprogram_Body
764 or else Present (Corresponding_Body (Decl)))
765 and then not Has_Initialized_Type (E)
766 then
767 Register_Backend_Inlined_Subprogram (E);
769 if No (Last_Inlined) then
770 Set_First_Inlined_Subprogram (Cunit (Main_Unit), E);
771 else
772 Set_Next_Inlined_Subprogram (Last_Inlined, E);
773 end if;
775 Last_Inlined := E;
777 else
778 Register_Backend_Not_Inlined_Subprogram (E);
779 end if;
780 end Add_Inlined_Subprogram;
782 --------------------------------
783 -- Add_Pending_Instantiation --
784 --------------------------------
786 procedure Add_Pending_Instantiation (Inst : Node_Id; Act_Decl : Node_Id) is
787 Act_Decl_Id : Entity_Id;
788 Index : Int;
790 begin
791 -- Here is a defense against a ludicrous number of instantiations
792 -- caused by a circular set of instantiation attempts.
794 if Pending_Instantiations.Last + 1 >= Maximum_Instantiations then
795 Error_Msg_Uint_1 := UI_From_Int (Maximum_Instantiations);
796 Error_Msg_N ("too many instantiations, exceeds max of^", Inst);
797 Error_Msg_N ("\limit can be changed using -gnateinn switch", Inst);
798 raise Unrecoverable_Error;
799 end if;
801 -- Capture the body of the generic instantiation along with its context
802 -- for later processing by Instantiate_Bodies.
804 Pending_Instantiations.Append
805 ((Act_Decl => Act_Decl,
806 Config_Switches => Save_Config_Switches,
807 Current_Sem_Unit => Current_Sem_Unit,
808 Expander_Status => Expander_Active,
809 Inst_Node => Inst,
810 Local_Suppress_Stack_Top => Local_Suppress_Stack_Top,
811 Scope_Suppress => Scope_Suppress,
812 Warnings => Save_Warnings));
814 -- With back-end inlining, also associate the index to the instantiation
816 if Back_End_Inlining then
817 Act_Decl_Id := Defining_Entity (Act_Decl);
818 Index := Pending_Instantiations.Last;
820 To_Pending_Instantiations.Set (Act_Decl, Index);
822 -- If an instantiation is in the main unit or subunit, or is a nested
823 -- subprogram, then its body is needed as per the analysis done in
824 -- Analyze_Package_Instantiation & Analyze_Subprogram_Instantiation.
826 if In_Main_Unit_Or_Subunit (Act_Decl_Id)
827 or else (Is_Subprogram (Act_Decl_Id)
828 and then Is_Nested (Act_Decl_Id))
829 then
830 Called_Pending_Instantiations.Append (Index);
832 Set_Is_Called (Act_Decl_Id);
833 end if;
834 end if;
835 end Add_Pending_Instantiation;
837 ------------------------
838 -- Add_Scope_To_Clean --
839 ------------------------
841 procedure Add_Scope_To_Clean (Inst : Entity_Id) is
842 Scop : constant Entity_Id := Enclosing_Dynamic_Scope (Inst);
843 Elmt : Elmt_Id;
845 begin
846 -- If the instance appears in a library-level package declaration,
847 -- all finalization is global, and nothing needs doing here.
849 if Scop = Standard_Standard then
850 return;
851 end if;
853 -- If the instance is within a generic unit, no finalization code
854 -- can be generated. Note that at this point all bodies have been
855 -- analyzed, and the scope stack itself is not present, and the flag
856 -- Inside_A_Generic is not set.
858 declare
859 S : Entity_Id;
861 begin
862 S := Scope (Inst);
863 while Present (S) and then S /= Standard_Standard loop
864 if Is_Generic_Unit (S) then
865 return;
866 end if;
868 S := Scope (S);
869 end loop;
870 end;
872 Elmt := First_Elmt (To_Clean);
873 while Present (Elmt) loop
874 if Node (Elmt) = Scop then
875 return;
876 end if;
878 Next_Elmt (Elmt);
879 end loop;
881 Append_Elmt (Scop, To_Clean);
882 end Add_Scope_To_Clean;
884 --------------
885 -- Add_Subp --
886 --------------
888 function Add_Subp (E : Entity_Id) return Subp_Index is
889 Index : Subp_Index := Subp_Index (E) mod Num_Hash_Headers;
890 J : Subp_Index;
892 procedure New_Entry;
893 -- Initialize entry in Inlined table
895 procedure New_Entry is
896 begin
897 Inlined.Increment_Last;
898 Inlined.Table (Inlined.Last).Name := E;
899 Inlined.Table (Inlined.Last).Next := No_Subp;
900 Inlined.Table (Inlined.Last).First_Succ := No_Succ;
901 Inlined.Table (Inlined.Last).Main_Call := False;
902 Inlined.Table (Inlined.Last).Processed := False;
903 end New_Entry;
905 -- Start of processing for Add_Subp
907 begin
908 if Hash_Headers (Index) = No_Subp then
909 New_Entry;
910 Hash_Headers (Index) := Inlined.Last;
911 return Inlined.Last;
913 else
914 J := Hash_Headers (Index);
915 while J /= No_Subp loop
916 if Inlined.Table (J).Name = E then
917 return J;
918 else
919 Index := J;
920 J := Inlined.Table (J).Next;
921 end if;
922 end loop;
924 -- On exit, subprogram was not found. Enter in table. Index is
925 -- the current last entry on the hash chain.
927 New_Entry;
928 Inlined.Table (Index).Next := Inlined.Last;
929 return Inlined.Last;
930 end if;
931 end Add_Subp;
933 ----------------------------
934 -- Analyze_Inlined_Bodies --
935 ----------------------------
937 procedure Analyze_Inlined_Bodies is
938 Comp_Unit : Node_Id;
939 J : Int;
940 Pack : Entity_Id;
941 Subp : Subp_Index;
942 S : Succ_Index;
944 type Pending_Index is new Nat;
946 package Pending_Inlined is new Table.Table (
947 Table_Component_Type => Subp_Index,
948 Table_Index_Type => Pending_Index,
949 Table_Low_Bound => 1,
950 Table_Initial => Alloc.Inlined_Initial,
951 Table_Increment => Alloc.Inlined_Increment,
952 Table_Name => "Pending_Inlined");
953 -- The workpile used to compute the transitive closure
955 -- Start of processing for Analyze_Inlined_Bodies
957 begin
958 if Serious_Errors_Detected = 0 then
959 Push_Scope (Standard_Standard);
961 J := 0;
962 while J <= Inlined_Bodies.Last
963 and then Serious_Errors_Detected = 0
964 loop
965 Pack := Inlined_Bodies.Table (J);
966 while Present (Pack)
967 and then Scope (Pack) /= Standard_Standard
968 and then not Is_Child_Unit (Pack)
969 loop
970 Pack := Scope (Pack);
971 end loop;
973 Comp_Unit := Parent (Pack);
974 while Present (Comp_Unit)
975 and then Nkind (Comp_Unit) /= N_Compilation_Unit
976 loop
977 Comp_Unit := Parent (Comp_Unit);
978 end loop;
980 -- Load the body if it exists and contains inlineable entities,
981 -- unless it is the main unit, or is an instance whose body has
982 -- already been analyzed.
984 if Present (Comp_Unit)
985 and then Comp_Unit /= Cunit (Main_Unit)
986 and then Body_Required (Comp_Unit)
987 and then
988 (Nkind (Unit (Comp_Unit)) /= N_Package_Declaration
989 or else
990 (No (Corresponding_Body (Unit (Comp_Unit)))
991 and then Body_Needed_For_Inlining
992 (Defining_Entity (Unit (Comp_Unit)))))
993 then
994 declare
995 Bname : constant Unit_Name_Type :=
996 Get_Body_Name (Get_Unit_Name (Unit (Comp_Unit)));
998 OK : Boolean;
1000 begin
1001 if not Is_Loaded (Bname) then
1002 Style_Check := False;
1003 Load_Needed_Body (Comp_Unit, OK);
1005 if not OK then
1007 -- Warn that a body was not available for inlining
1008 -- by the back-end.
1010 Error_Msg_Unit_1 := Bname;
1011 Error_Msg_N
1012 ("one or more inlined subprograms accessed in $!??",
1013 Comp_Unit);
1014 Error_Msg_File_1 :=
1015 Get_File_Name (Bname, Subunit => False);
1016 Error_Msg_N ("\but file{ was not found!??", Comp_Unit);
1017 end if;
1018 end if;
1019 end;
1020 end if;
1022 J := J + 1;
1024 if J > Inlined_Bodies.Last then
1026 -- The analysis of required bodies may have produced additional
1027 -- generic instantiations. To obtain further inlining, we need
1028 -- to perform another round of generic body instantiations.
1030 Instantiate_Bodies;
1032 -- Symmetrically, the instantiation of required generic bodies
1033 -- may have caused additional bodies to be inlined. To obtain
1034 -- further inlining, we keep looping over the inlined bodies.
1035 end if;
1036 end loop;
1038 -- The list of inlined subprograms is an overestimate, because it
1039 -- includes inlined functions called from functions that are compiled
1040 -- as part of an inlined package, but are not themselves called. An
1041 -- accurate computation of just those subprograms that are needed
1042 -- requires that we perform a transitive closure over the call graph,
1043 -- starting from calls in the main compilation unit.
1045 for Index in Inlined.First .. Inlined.Last loop
1046 if not Is_Called (Inlined.Table (Index).Name) then
1048 -- This means that Add_Inlined_Body added the subprogram to the
1049 -- table but wasn't able to handle its code unit. Do nothing.
1051 Inlined.Table (Index).Processed := True;
1053 elsif Inlined.Table (Index).Main_Call then
1054 Pending_Inlined.Increment_Last;
1055 Pending_Inlined.Table (Pending_Inlined.Last) := Index;
1056 Inlined.Table (Index).Processed := True;
1058 else
1059 Set_Is_Called (Inlined.Table (Index).Name, False);
1060 end if;
1061 end loop;
1063 -- Iterate over the workpile until it is emptied, propagating the
1064 -- Is_Called flag to the successors of the processed subprogram.
1066 while Pending_Inlined.Last >= Pending_Inlined.First loop
1067 Subp := Pending_Inlined.Table (Pending_Inlined.Last);
1068 Pending_Inlined.Decrement_Last;
1070 S := Inlined.Table (Subp).First_Succ;
1072 while S /= No_Succ loop
1073 Subp := Successors.Table (S).Subp;
1075 if not Inlined.Table (Subp).Processed then
1076 Set_Is_Called (Inlined.Table (Subp).Name);
1077 Pending_Inlined.Increment_Last;
1078 Pending_Inlined.Table (Pending_Inlined.Last) := Subp;
1079 Inlined.Table (Subp).Processed := True;
1080 end if;
1082 S := Successors.Table (S).Next;
1083 end loop;
1084 end loop;
1086 -- Finally add the called subprograms to the list of inlined
1087 -- subprograms for the unit.
1089 for Index in Inlined.First .. Inlined.Last loop
1090 if Is_Called (Inlined.Table (Index).Name) then
1091 Add_Inlined_Subprogram (Inlined.Table (Index).Name);
1092 end if;
1093 end loop;
1095 Pop_Scope;
1096 end if;
1097 end Analyze_Inlined_Bodies;
1099 --------------------------
1100 -- Build_Body_To_Inline --
1101 --------------------------
1103 procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id) is
1104 Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id);
1105 Analysis_Status : constant Boolean := Full_Analysis;
1106 Original_Body : Node_Id;
1107 Body_To_Analyze : Node_Id;
1108 Max_Size : constant := 10;
1110 function Has_Extended_Return return Boolean;
1111 -- This function returns True if the subprogram has an extended return
1112 -- statement.
1114 function Has_Pending_Instantiation return Boolean;
1115 -- If some enclosing body contains instantiations that appear before
1116 -- the corresponding generic body, the enclosing body has a freeze node
1117 -- so that it can be elaborated after the generic itself. This might
1118 -- conflict with subsequent inlinings, so that it is unsafe to try to
1119 -- inline in such a case.
1121 function Has_Single_Return_In_GNATprove_Mode return Boolean;
1122 -- This function is called only in GNATprove mode, and it returns
1123 -- True if the subprogram has no return statement or a single return
1124 -- statement as last statement. It returns False for subprogram with
1125 -- a single return as last statement inside one or more blocks, as
1126 -- inlining would generate gotos in that case as well (although the
1127 -- goto is useless in that case).
1129 function Uses_Secondary_Stack (Bod : Node_Id) return Boolean;
1130 -- If the body of the subprogram includes a call that returns an
1131 -- unconstrained type, the secondary stack is involved, and it is
1132 -- not worth inlining.
1134 -------------------------
1135 -- Has_Extended_Return --
1136 -------------------------
1138 function Has_Extended_Return return Boolean is
1139 Body_To_Inline : constant Node_Id := N;
1141 function Check_Return (N : Node_Id) return Traverse_Result;
1142 -- Returns OK on node N if this is not an extended return statement
1144 ------------------
1145 -- Check_Return --
1146 ------------------
1148 function Check_Return (N : Node_Id) return Traverse_Result is
1149 begin
1150 case Nkind (N) is
1151 when N_Extended_Return_Statement =>
1152 return Abandon;
1154 -- Skip locally declared subprogram bodies inside the body to
1155 -- inline, as the return statements inside those do not count.
1157 when N_Subprogram_Body =>
1158 if N = Body_To_Inline then
1159 return OK;
1160 else
1161 return Skip;
1162 end if;
1164 when others =>
1165 return OK;
1166 end case;
1167 end Check_Return;
1169 function Check_All_Returns is new Traverse_Func (Check_Return);
1171 -- Start of processing for Has_Extended_Return
1173 begin
1174 return Check_All_Returns (N) /= OK;
1175 end Has_Extended_Return;
1177 -------------------------------
1178 -- Has_Pending_Instantiation --
1179 -------------------------------
1181 function Has_Pending_Instantiation return Boolean is
1182 S : Entity_Id;
1184 begin
1185 S := Current_Scope;
1186 while Present (S) loop
1187 if Is_Compilation_Unit (S)
1188 or else Is_Child_Unit (S)
1189 then
1190 return False;
1192 elsif Ekind (S) = E_Package
1193 and then Has_Forward_Instantiation (S)
1194 then
1195 return True;
1196 end if;
1198 S := Scope (S);
1199 end loop;
1201 return False;
1202 end Has_Pending_Instantiation;
1204 -----------------------------------------
1205 -- Has_Single_Return_In_GNATprove_Mode --
1206 -----------------------------------------
1208 function Has_Single_Return_In_GNATprove_Mode return Boolean is
1209 Body_To_Inline : constant Node_Id := N;
1210 Last_Statement : Node_Id := Empty;
1212 function Check_Return (N : Node_Id) return Traverse_Result;
1213 -- Returns OK on node N if this is not a return statement different
1214 -- from the last statement in the subprogram.
1216 ------------------
1217 -- Check_Return --
1218 ------------------
1220 function Check_Return (N : Node_Id) return Traverse_Result is
1221 begin
1222 case Nkind (N) is
1223 when N_Extended_Return_Statement
1224 | N_Simple_Return_Statement
1226 if N = Last_Statement then
1227 return OK;
1228 else
1229 return Abandon;
1230 end if;
1232 -- Skip locally declared subprogram bodies inside the body to
1233 -- inline, as the return statements inside those do not count.
1235 when N_Subprogram_Body =>
1236 if N = Body_To_Inline then
1237 return OK;
1238 else
1239 return Skip;
1240 end if;
1242 when others =>
1243 return OK;
1244 end case;
1245 end Check_Return;
1247 function Check_All_Returns is new Traverse_Func (Check_Return);
1249 -- Start of processing for Has_Single_Return_In_GNATprove_Mode
1251 begin
1252 -- Retrieve the last statement
1254 Last_Statement := Last (Statements (Handled_Statement_Sequence (N)));
1256 -- Check that the last statement is the only possible return
1257 -- statement in the subprogram.
1259 return Check_All_Returns (N) = OK;
1260 end Has_Single_Return_In_GNATprove_Mode;
1262 --------------------------
1263 -- Uses_Secondary_Stack --
1264 --------------------------
1266 function Uses_Secondary_Stack (Bod : Node_Id) return Boolean is
1267 function Check_Call (N : Node_Id) return Traverse_Result;
1268 -- Look for function calls that return an unconstrained type
1270 ----------------
1271 -- Check_Call --
1272 ----------------
1274 function Check_Call (N : Node_Id) return Traverse_Result is
1275 begin
1276 if Nkind (N) = N_Function_Call
1277 and then Is_Entity_Name (Name (N))
1278 and then Is_Composite_Type (Etype (Entity (Name (N))))
1279 and then not Is_Constrained (Etype (Entity (Name (N))))
1280 then
1281 Cannot_Inline
1282 ("cannot inline & (call returns unconstrained type)?",
1283 N, Spec_Id);
1284 return Abandon;
1285 else
1286 return OK;
1287 end if;
1288 end Check_Call;
1290 function Check_Calls is new Traverse_Func (Check_Call);
1292 begin
1293 return Check_Calls (Bod) = Abandon;
1294 end Uses_Secondary_Stack;
1296 -- Start of processing for Build_Body_To_Inline
1298 begin
1299 -- Return immediately if done already
1301 if Nkind (Decl) = N_Subprogram_Declaration
1302 and then Present (Body_To_Inline (Decl))
1303 then
1304 return;
1306 -- Subprograms that have return statements in the middle of the body are
1307 -- inlined with gotos. GNATprove does not currently support gotos, so
1308 -- we prevent such inlining.
1310 elsif GNATprove_Mode
1311 and then not Has_Single_Return_In_GNATprove_Mode
1312 then
1313 Cannot_Inline ("cannot inline & (multiple returns)?", N, Spec_Id);
1314 return;
1316 -- Functions that return controlled types cannot currently be inlined
1317 -- because they require secondary stack handling; controlled actions
1318 -- may also interfere in complex ways with inlining.
1320 elsif Ekind (Spec_Id) = E_Function
1321 and then Needs_Finalization (Etype (Spec_Id))
1322 then
1323 Cannot_Inline
1324 ("cannot inline & (controlled return type)?", N, Spec_Id);
1325 return;
1326 end if;
1328 if Present (Declarations (N))
1329 and then Has_Excluded_Declaration (Spec_Id, Declarations (N))
1330 then
1331 return;
1332 end if;
1334 if Present (Handled_Statement_Sequence (N)) then
1335 if Present (Exception_Handlers (Handled_Statement_Sequence (N))) then
1336 Cannot_Inline
1337 ("cannot inline& (exception handler)?",
1338 First (Exception_Handlers (Handled_Statement_Sequence (N))),
1339 Spec_Id);
1340 return;
1342 elsif Has_Excluded_Statement
1343 (Spec_Id, Statements (Handled_Statement_Sequence (N)))
1344 then
1345 return;
1346 end if;
1347 end if;
1349 -- We do not inline a subprogram that is too large, unless it is marked
1350 -- Inline_Always or we are in GNATprove mode. This pragma does not
1351 -- suppress the other checks on inlining (forbidden declarations,
1352 -- handlers, etc).
1354 if not (Has_Pragma_Inline_Always (Spec_Id) or else GNATprove_Mode)
1355 and then List_Length
1356 (Statements (Handled_Statement_Sequence (N))) > Max_Size
1357 then
1358 Cannot_Inline ("cannot inline& (body too large)?", N, Spec_Id);
1359 return;
1360 end if;
1362 if Has_Pending_Instantiation then
1363 Cannot_Inline
1364 ("cannot inline& (forward instance within enclosing body)?",
1365 N, Spec_Id);
1366 return;
1367 end if;
1369 -- Within an instance, the body to inline must be treated as a nested
1370 -- generic, so that the proper global references are preserved.
1372 -- Note that we do not do this at the library level, because it is not
1373 -- needed, and furthermore this causes trouble if front-end inlining
1374 -- is activated (-gnatN).
1376 if In_Instance and then Scope (Current_Scope) /= Standard_Standard then
1377 Save_Env (Scope (Current_Scope), Scope (Current_Scope));
1378 Original_Body := Copy_Generic_Node (N, Empty, Instantiating => True);
1379 else
1380 Original_Body := Copy_Separate_Tree (N);
1381 end if;
1383 -- We need to capture references to the formals in order to substitute
1384 -- the actuals at the point of inlining, i.e. instantiation. To treat
1385 -- the formals as globals to the body to inline, we nest it within a
1386 -- dummy parameterless subprogram, declared within the real one. To
1387 -- avoid generating an internal name (which is never public, and which
1388 -- affects serial numbers of other generated names), we use an internal
1389 -- symbol that cannot conflict with user declarations.
1391 Set_Parameter_Specifications (Specification (Original_Body), No_List);
1392 Set_Defining_Unit_Name
1393 (Specification (Original_Body),
1394 Make_Defining_Identifier (Sloc (N), Name_uParent));
1395 Set_Corresponding_Spec (Original_Body, Empty);
1397 -- Remove all aspects/pragmas that have no meaning in an inlined body
1399 Remove_Aspects_And_Pragmas (Original_Body);
1401 Body_To_Analyze :=
1402 Copy_Generic_Node (Original_Body, Empty, Instantiating => False);
1404 -- Set return type of function, which is also global and does not need
1405 -- to be resolved.
1407 if Ekind (Spec_Id) = E_Function then
1408 Set_Result_Definition
1409 (Specification (Body_To_Analyze),
1410 New_Occurrence_Of (Etype (Spec_Id), Sloc (N)));
1411 end if;
1413 if No (Declarations (N)) then
1414 Set_Declarations (N, New_List (Body_To_Analyze));
1415 else
1416 Append (Body_To_Analyze, Declarations (N));
1417 end if;
1419 -- The body to inline is preanalyzed. In GNATprove mode we must disable
1420 -- full analysis as well so that light expansion does not take place
1421 -- either, and name resolution is unaffected.
1423 Expander_Mode_Save_And_Set (False);
1424 Full_Analysis := False;
1426 Analyze (Body_To_Analyze);
1427 Push_Scope (Defining_Entity (Body_To_Analyze));
1428 Save_Global_References (Original_Body);
1429 End_Scope;
1430 Remove (Body_To_Analyze);
1432 Expander_Mode_Restore;
1433 Full_Analysis := Analysis_Status;
1435 -- Restore environment if previously saved
1437 if In_Instance and then Scope (Current_Scope) /= Standard_Standard then
1438 Restore_Env;
1439 end if;
1441 -- Functions that return unconstrained composite types require
1442 -- secondary stack handling, and cannot currently be inlined, unless
1443 -- all return statements return a local variable that is the first
1444 -- local declaration in the body. We had to delay this check until
1445 -- the body of the function is analyzed since Has_Single_Return()
1446 -- requires a minimum decoration.
1448 if Ekind (Spec_Id) = E_Function
1449 and then not Is_Scalar_Type (Etype (Spec_Id))
1450 and then not Is_Access_Type (Etype (Spec_Id))
1451 and then not Is_Constrained (Etype (Spec_Id))
1452 then
1453 if not Has_Single_Return (Body_To_Analyze)
1455 -- Skip inlining if the function returns an unconstrained type
1456 -- using an extended return statement, since this part of the
1457 -- new inlining model is not yet supported by the current
1458 -- implementation.
1460 or else (Returns_Unconstrained_Type (Spec_Id)
1461 and then Has_Extended_Return)
1462 then
1463 Cannot_Inline
1464 ("cannot inline & (unconstrained return type)?", N, Spec_Id);
1465 return;
1466 end if;
1468 -- If secondary stack is used, there is no point in inlining. We have
1469 -- already issued the warning in this case, so nothing to do.
1471 elsif Uses_Secondary_Stack (Body_To_Analyze) then
1472 return;
1473 end if;
1475 Set_Body_To_Inline (Decl, Original_Body);
1476 Mutate_Ekind (Defining_Entity (Original_Body), Ekind (Spec_Id));
1477 Set_Is_Inlined (Spec_Id);
1478 end Build_Body_To_Inline;
1480 -------------------------------------------
1481 -- Call_Can_Be_Inlined_In_GNATprove_Mode --
1482 -------------------------------------------
1484 function Call_Can_Be_Inlined_In_GNATprove_Mode
1485 (N : Node_Id;
1486 Subp : Entity_Id) return Boolean
1488 F : Entity_Id;
1489 A : Node_Id;
1491 begin
1492 F := First_Formal (Subp);
1493 A := First_Actual (N);
1494 while Present (F) loop
1495 if Ekind (F) /= E_Out_Parameter
1496 and then not Same_Type (Etype (F), Etype (A))
1497 and then
1498 (Is_By_Reference_Type (Etype (A))
1499 or else Is_Limited_Type (Etype (A)))
1500 then
1501 return False;
1502 end if;
1504 Next_Formal (F);
1505 Next_Actual (A);
1506 end loop;
1508 return True;
1509 end Call_Can_Be_Inlined_In_GNATprove_Mode;
1511 --------------------------------------
1512 -- Can_Be_Inlined_In_GNATprove_Mode --
1513 --------------------------------------
1515 function Can_Be_Inlined_In_GNATprove_Mode
1516 (Spec_Id : Entity_Id;
1517 Body_Id : Entity_Id) return Boolean
1519 function Has_Formal_Or_Result_Of_Deep_Type
1520 (Id : Entity_Id) return Boolean;
1521 -- Returns true if the subprogram has at least one formal parameter or
1522 -- a return type of a deep type: either an access type or a composite
1523 -- type containing an access type.
1525 function Has_Formal_With_Discriminant_Dependent_Fields
1526 (Id : Entity_Id) return Boolean;
1527 -- Returns true if the subprogram has at least one formal parameter of
1528 -- an unconstrained record type with per-object constraints on component
1529 -- types.
1531 function Has_Some_Contract (Id : Entity_Id) return Boolean;
1532 -- Return True if subprogram Id has any contract. The presence of
1533 -- Extensions_Visible or Volatile_Function is also considered as a
1534 -- contract here.
1536 function Is_Unit_Subprogram (Id : Entity_Id) return Boolean;
1537 -- Return True if subprogram Id defines a compilation unit
1539 function In_Package_Spec (Id : Entity_Id) return Boolean;
1540 -- Return True if subprogram Id is defined in the package specification,
1541 -- either its visible or private part.
1543 function Maybe_Traversal_Function (Id : Entity_Id) return Boolean;
1544 -- Return True if subprogram Id could be a traversal function, as
1545 -- defined in SPARK RM 3.10. This is only a safe approximation, as the
1546 -- knowledge of the SPARK boundary is needed to determine exactly
1547 -- traversal functions.
1549 ---------------------------------------
1550 -- Has_Formal_Or_Result_Of_Deep_Type --
1551 ---------------------------------------
1553 function Has_Formal_Or_Result_Of_Deep_Type
1554 (Id : Entity_Id) return Boolean
1556 function Is_Deep (Typ : Entity_Id) return Boolean;
1557 -- Return True if Typ is deep: either an access type or a composite
1558 -- type containing an access type.
1560 -------------
1561 -- Is_Deep --
1562 -------------
1564 function Is_Deep (Typ : Entity_Id) return Boolean is
1565 begin
1566 case Type_Kind'(Ekind (Typ)) is
1567 when Access_Kind =>
1568 return True;
1570 when E_Array_Type
1571 | E_Array_Subtype
1573 return Is_Deep (Component_Type (Typ));
1575 when Record_Kind =>
1576 declare
1577 Comp : Entity_Id := First_Component_Or_Discriminant (Typ);
1578 begin
1579 while Present (Comp) loop
1580 if Is_Deep (Etype (Comp)) then
1581 return True;
1582 end if;
1583 Next_Component_Or_Discriminant (Comp);
1584 end loop;
1585 end;
1586 return False;
1588 when Scalar_Kind
1589 | E_String_Literal_Subtype
1590 | Concurrent_Kind
1591 | Incomplete_Kind
1592 | E_Exception_Type
1593 | E_Subprogram_Type
1595 return False;
1597 when E_Private_Type
1598 | E_Private_Subtype
1599 | E_Limited_Private_Type
1600 | E_Limited_Private_Subtype
1602 -- Conservatively consider that the type might be deep if
1603 -- its completion has not been seen yet.
1605 if No (Underlying_Type (Typ)) then
1606 return True;
1608 -- Do not peek under a private type if its completion has
1609 -- SPARK_Mode Off. In such a case, a deep type is considered
1610 -- by GNATprove to be not deep.
1612 elsif Present (Full_View (Typ))
1613 and then Present (SPARK_Pragma (Full_View (Typ)))
1614 and then Get_SPARK_Mode_From_Annotation
1615 (SPARK_Pragma (Full_View (Typ))) = Off
1616 then
1617 return False;
1619 -- Otherwise peek under the private type.
1621 else
1622 return Is_Deep (Underlying_Type (Typ));
1623 end if;
1624 end case;
1625 end Is_Deep;
1627 -- Local variables
1629 Subp_Id : constant Entity_Id := Ultimate_Alias (Id);
1630 Formal : Entity_Id;
1631 Formal_Typ : Entity_Id;
1633 -- Start of processing for Has_Formal_Or_Result_Of_Deep_Type
1635 begin
1636 -- Inspect all parameters of the subprogram looking for a formal
1637 -- of a deep type.
1639 Formal := First_Formal (Subp_Id);
1640 while Present (Formal) loop
1641 Formal_Typ := Etype (Formal);
1643 if Is_Deep (Formal_Typ) then
1644 return True;
1645 end if;
1647 Next_Formal (Formal);
1648 end loop;
1650 -- Check whether this is a function whose return type is deep
1652 if Ekind (Subp_Id) = E_Function
1653 and then Is_Deep (Etype (Subp_Id))
1654 then
1655 return True;
1656 end if;
1658 return False;
1659 end Has_Formal_Or_Result_Of_Deep_Type;
1661 ---------------------------------------------------
1662 -- Has_Formal_With_Discriminant_Dependent_Fields --
1663 ---------------------------------------------------
1665 function Has_Formal_With_Discriminant_Dependent_Fields
1666 (Id : Entity_Id) return Boolean
1668 function Has_Discriminant_Dependent_Component
1669 (Typ : Entity_Id) return Boolean;
1670 -- Determine whether unconstrained record type Typ has at least one
1671 -- component that depends on a discriminant.
1673 ------------------------------------------
1674 -- Has_Discriminant_Dependent_Component --
1675 ------------------------------------------
1677 function Has_Discriminant_Dependent_Component
1678 (Typ : Entity_Id) return Boolean
1680 Comp : Entity_Id;
1682 begin
1683 -- Inspect all components of the record type looking for one that
1684 -- depends on a discriminant.
1686 Comp := First_Component (Typ);
1687 while Present (Comp) loop
1688 if Has_Discriminant_Dependent_Constraint (Comp) then
1689 return True;
1690 end if;
1692 Next_Component (Comp);
1693 end loop;
1695 return False;
1696 end Has_Discriminant_Dependent_Component;
1698 -- Local variables
1700 Subp_Id : constant Entity_Id := Ultimate_Alias (Id);
1701 Formal : Entity_Id;
1702 Formal_Typ : Entity_Id;
1704 -- Start of processing for
1705 -- Has_Formal_With_Discriminant_Dependent_Fields
1707 begin
1708 -- Inspect all parameters of the subprogram looking for a formal
1709 -- of an unconstrained record type with at least one discriminant
1710 -- dependent component.
1712 Formal := First_Formal (Subp_Id);
1713 while Present (Formal) loop
1714 Formal_Typ := Etype (Formal);
1716 if Is_Record_Type (Formal_Typ)
1717 and then not Is_Constrained (Formal_Typ)
1718 and then Has_Discriminant_Dependent_Component (Formal_Typ)
1719 then
1720 return True;
1721 end if;
1723 Next_Formal (Formal);
1724 end loop;
1726 return False;
1727 end Has_Formal_With_Discriminant_Dependent_Fields;
1729 -----------------------
1730 -- Has_Some_Contract --
1731 -----------------------
1733 function Has_Some_Contract (Id : Entity_Id) return Boolean is
1734 Items : Node_Id;
1736 begin
1737 -- A call to an expression function may precede the actual body which
1738 -- is inserted at the end of the enclosing declarations. Ensure that
1739 -- the related entity is decorated before inspecting the contract.
1741 if Is_Subprogram_Or_Generic_Subprogram (Id) then
1742 Items := Contract (Id);
1744 -- Note that Classifications is not Empty when Extensions_Visible
1745 -- or Volatile_Function is present, which causes such subprograms
1746 -- to be considered to have a contract here. This is fine as we
1747 -- want to avoid inlining these too.
1749 return Present (Items)
1750 and then (Present (Pre_Post_Conditions (Items)) or else
1751 Present (Contract_Test_Cases (Items)) or else
1752 Present (Classifications (Items)));
1753 end if;
1755 return False;
1756 end Has_Some_Contract;
1758 ---------------------
1759 -- In_Package_Spec --
1760 ---------------------
1762 function In_Package_Spec (Id : Entity_Id) return Boolean is
1763 P : constant Node_Id := Parent (Subprogram_Spec (Id));
1764 -- Parent of the subprogram's declaration
1766 begin
1767 return Nkind (Enclosing_Declaration (P)) = N_Package_Declaration;
1768 end In_Package_Spec;
1770 ------------------------
1771 -- Is_Unit_Subprogram --
1772 ------------------------
1774 function Is_Unit_Subprogram (Id : Entity_Id) return Boolean is
1775 Decl : Node_Id := Parent (Parent (Id));
1776 begin
1777 if Nkind (Parent (Id)) = N_Defining_Program_Unit_Name then
1778 Decl := Parent (Decl);
1779 end if;
1781 return Nkind (Parent (Decl)) = N_Compilation_Unit;
1782 end Is_Unit_Subprogram;
1784 ------------------------------
1785 -- Maybe_Traversal_Function --
1786 ------------------------------
1788 function Maybe_Traversal_Function (Id : Entity_Id) return Boolean is
1789 begin
1790 return Ekind (Id) = E_Function
1792 -- Only traversal functions return an anonymous access-to-object
1793 -- type in SPARK.
1795 and then Is_Anonymous_Access_Type (Etype (Id));
1796 end Maybe_Traversal_Function;
1798 -- Local declarations
1800 Id : Entity_Id;
1801 -- Procedure or function entity for the subprogram
1803 -- Start of processing for Can_Be_Inlined_In_GNATprove_Mode
1805 begin
1806 pragma Assert (Present (Spec_Id) or else Present (Body_Id));
1808 if Present (Spec_Id) then
1809 Id := Spec_Id;
1810 else
1811 Id := Body_Id;
1812 end if;
1814 -- Only local subprograms without contracts are inlined in GNATprove
1815 -- mode, as these are the subprograms which a user is not interested in
1816 -- analyzing in isolation, but rather in the context of their call. This
1817 -- is a convenient convention, that could be changed for an explicit
1818 -- pragma/aspect one day.
1820 -- In a number of special cases, inlining is not desirable or not
1821 -- possible, see below.
1823 -- Do not inline unit-level subprograms
1825 if Is_Unit_Subprogram (Id) then
1826 return False;
1828 -- Do not inline subprograms declared in package specs, because they are
1829 -- not local, i.e. can be called either from anywhere (if declared in
1830 -- visible part) or from the child units (if declared in private part).
1832 elsif In_Package_Spec (Id) then
1833 return False;
1835 -- Do not inline subprograms declared in other units. This is important
1836 -- in particular for subprograms defined in the private part of a
1837 -- package spec, when analyzing one of its child packages, as otherwise
1838 -- we issue spurious messages about the impossibility to inline such
1839 -- calls.
1841 elsif not In_Extended_Main_Code_Unit (Id) then
1842 return False;
1844 -- Do not inline dispatching operations, as only their static calls
1845 -- can be analyzed in context, and not their dispatching calls.
1847 elsif Is_Dispatching_Operation (Id) then
1848 return False;
1850 -- Do not inline subprograms marked No_Return, possibly used for
1851 -- signaling errors, which GNATprove handles specially.
1853 elsif No_Return (Id) then
1854 return False;
1856 -- Do not inline subprograms that have a contract on the spec or the
1857 -- body. Use the contract(s) instead in GNATprove. This also prevents
1858 -- inlining of subprograms with Extensions_Visible or Volatile_Function.
1860 elsif (Present (Spec_Id) and then Has_Some_Contract (Spec_Id))
1861 or else
1862 (Present (Body_Id) and then Has_Some_Contract (Body_Id))
1863 then
1864 return False;
1866 -- Do not inline expression functions, which are directly inlined at the
1867 -- prover level.
1869 elsif (Present (Spec_Id) and then Is_Expression_Function (Spec_Id))
1870 or else
1871 (Present (Body_Id) and then Is_Expression_Function (Body_Id))
1872 then
1873 return False;
1875 -- Do not inline generic subprogram instances. The visibility rules of
1876 -- generic instances plays badly with inlining.
1878 elsif Is_Generic_Instance (Spec_Id) then
1879 return False;
1881 -- Only inline subprograms whose spec is marked SPARK_Mode On. For
1882 -- the subprogram body, a similar check is performed after the body
1883 -- is analyzed, as this is where a pragma SPARK_Mode might be inserted.
1885 elsif Present (Spec_Id)
1886 and then
1887 (No (SPARK_Pragma (Spec_Id))
1888 or else
1889 Get_SPARK_Mode_From_Annotation (SPARK_Pragma (Spec_Id)) /= On)
1890 then
1891 return False;
1893 -- Subprograms in generic instances are currently not inlined, to avoid
1894 -- problems with inlining of standard library subprograms.
1896 elsif Instantiation_Location (Sloc (Id)) /= No_Location then
1897 return False;
1899 -- Do not inline subprograms and entries defined inside protected types,
1900 -- which typically are not helper subprograms, which also avoids getting
1901 -- spurious messages on calls that cannot be inlined.
1903 elsif Within_Protected_Type (Id) then
1904 return False;
1906 -- Do not inline predicate functions (treated specially by GNATprove)
1908 elsif Is_Predicate_Function (Id) then
1909 return False;
1911 -- Do not inline subprograms with a parameter of an unconstrained
1912 -- record type if it has discrimiant dependent fields. Indeed, with
1913 -- such parameters, the frontend cannot always ensure type compliance
1914 -- in record component accesses (in particular with records containing
1915 -- packed arrays).
1917 elsif Has_Formal_With_Discriminant_Dependent_Fields (Id) then
1918 return False;
1920 -- Do not inline subprograms with a formal parameter or return type of
1921 -- a deep type, as in that case inlining might generate code that
1922 -- violates borrow-checking rules of SPARK 3.10 even if the original
1923 -- code did not.
1925 elsif Has_Formal_Or_Result_Of_Deep_Type (Id) then
1926 return False;
1928 -- Do not inline subprograms which may be traversal functions. Such
1929 -- inlining introduces temporary variables of named access type for
1930 -- which assignments are move instead of borrow/observe, possibly
1931 -- leading to spurious errors when checking SPARK rules related to
1932 -- pointer usage.
1934 elsif Maybe_Traversal_Function (Id) then
1935 return False;
1937 -- Otherwise, this is a subprogram declared inside the private part of a
1938 -- package, or inside a package body, or locally in a subprogram, and it
1939 -- does not have any contract. Inline it.
1941 else
1942 return True;
1943 end if;
1944 end Can_Be_Inlined_In_GNATprove_Mode;
1946 -------------------
1947 -- Cannot_Inline --
1948 -------------------
1950 procedure Cannot_Inline
1951 (Msg : String;
1952 N : Node_Id;
1953 Subp : Entity_Id;
1954 Is_Serious : Boolean := False;
1955 Suppress_Info : Boolean := False)
1957 begin
1958 -- In GNATprove mode, inlining is the technical means by which the
1959 -- higher-level goal of contextual analysis is reached, so issue
1960 -- messages about failure to apply contextual analysis to a
1961 -- subprogram, rather than failure to inline it.
1963 if GNATprove_Mode
1964 and then Msg (Msg'First .. Msg'First + 12) = "cannot inline"
1965 then
1966 declare
1967 Len1 : constant Positive :=
1968 String (String'("cannot inline"))'Length;
1969 Len2 : constant Positive :=
1970 String (String'("info: no contextual analysis of"))'Length;
1972 New_Msg : String (1 .. Msg'Length + Len2 - Len1);
1974 begin
1975 New_Msg (1 .. Len2) := "info: no contextual analysis of";
1976 New_Msg (Len2 + 1 .. Msg'Length + Len2 - Len1) :=
1977 Msg (Msg'First + Len1 .. Msg'Last);
1978 Cannot_Inline (New_Msg, N, Subp, Is_Serious, Suppress_Info);
1979 return;
1980 end;
1981 end if;
1983 pragma Assert (Msg (Msg'Last) = '?');
1985 -- Legacy front-end inlining model
1987 if not Back_End_Inlining then
1989 -- Do not emit warning if this is a predefined unit which is not
1990 -- the main unit. With validity checks enabled, some predefined
1991 -- subprograms may contain nested subprograms and become ineligible
1992 -- for inlining.
1994 if Is_Predefined_Unit (Get_Source_Unit (Subp))
1995 and then not In_Extended_Main_Source_Unit (Subp)
1996 then
1997 null;
1999 -- In GNATprove mode, issue an info message when -gnatd_f is set and
2000 -- Suppress_Info is False, and indicate that the subprogram is not
2001 -- always inlined by setting flag Is_Inlined_Always to False.
2003 elsif GNATprove_Mode then
2004 Set_Is_Inlined_Always (Subp, False);
2006 if Debug_Flag_Underscore_F and not Suppress_Info then
2007 Error_Msg_NE (Msg, N, Subp);
2008 end if;
2010 elsif Has_Pragma_Inline_Always (Subp) then
2012 -- Remove last character (question mark) to make this into an
2013 -- error, because the Inline_Always pragma cannot be obeyed.
2015 Error_Msg_NE (Msg (Msg'First .. Msg'Last - 1), N, Subp);
2017 elsif Ineffective_Inline_Warnings then
2018 Error_Msg_NE (Msg & "p?", N, Subp);
2019 end if;
2021 -- New semantics relying on back-end inlining
2023 elsif Is_Serious then
2025 -- Remove last character (question mark) to make this into an error.
2027 Error_Msg_NE (Msg (Msg'First .. Msg'Last - 1), N, Subp);
2029 -- In GNATprove mode, issue an info message when -gnatd_f is set and
2030 -- Suppress_Info is False, and indicate that the subprogram is not
2031 -- always inlined by setting flag Is_Inlined_Always to False.
2033 elsif GNATprove_Mode then
2034 Set_Is_Inlined_Always (Subp, False);
2036 if Debug_Flag_Underscore_F and not Suppress_Info then
2037 Error_Msg_NE (Msg, N, Subp);
2038 end if;
2040 else
2042 -- Do not emit warning if this is a predefined unit which is not
2043 -- the main unit. This behavior is currently provided for backward
2044 -- compatibility but it will be removed when we enforce the
2045 -- strictness of the new rules.
2047 if Is_Predefined_Unit (Get_Source_Unit (Subp))
2048 and then not In_Extended_Main_Source_Unit (Subp)
2049 then
2050 null;
2052 elsif Has_Pragma_Inline_Always (Subp) then
2054 -- Emit a warning if this is a call to a runtime subprogram
2055 -- which is located inside a generic. Previously this call
2056 -- was silently skipped.
2058 if Is_Generic_Instance (Subp) then
2059 declare
2060 Gen_P : constant Entity_Id := Generic_Parent (Parent (Subp));
2061 begin
2062 if Is_Predefined_Unit (Get_Source_Unit (Gen_P)) then
2063 Set_Is_Inlined (Subp, False);
2064 Error_Msg_NE (Msg & "p?", N, Subp);
2065 return;
2066 end if;
2067 end;
2068 end if;
2070 -- Remove last character (question mark) to make this into an
2071 -- error, because the Inline_Always pragma cannot be obeyed.
2073 Error_Msg_NE (Msg (Msg'First .. Msg'Last - 1), N, Subp);
2075 else
2076 Set_Is_Inlined (Subp, False);
2078 if Ineffective_Inline_Warnings then
2079 Error_Msg_NE (Msg & "p?", N, Subp);
2080 end if;
2081 end if;
2082 end if;
2083 end Cannot_Inline;
2085 --------------------------------------------
2086 -- Check_And_Split_Unconstrained_Function --
2087 --------------------------------------------
2089 procedure Check_And_Split_Unconstrained_Function
2090 (N : Node_Id;
2091 Spec_Id : Entity_Id;
2092 Body_Id : Entity_Id)
2094 procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id);
2095 -- Use generic machinery to build an unexpanded body for the subprogram.
2096 -- This body is subsequently used for inline expansions at call sites.
2098 procedure Build_Return_Object_Formal
2099 (Loc : Source_Ptr;
2100 Obj_Decl : Node_Id;
2101 Formals : List_Id);
2102 -- Create a formal parameter for return object declaration Obj_Decl of
2103 -- an extended return statement and add it to list Formals.
2105 function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean;
2106 -- Return true if we generate code for the function body N, the function
2107 -- body N has no local declarations and its unique statement is a single
2108 -- extended return statement with a handled statements sequence.
2110 procedure Copy_Formals
2111 (Loc : Source_Ptr;
2112 Subp_Id : Entity_Id;
2113 Formals : List_Id);
2114 -- Create new formal parameters from the formal parameters of subprogram
2115 -- Subp_Id and add them to list Formals.
2117 function Copy_Return_Object (Obj_Decl : Node_Id) return Node_Id;
2118 -- Create a copy of return object declaration Obj_Decl of an extended
2119 -- return statement.
2121 procedure Split_Unconstrained_Function
2122 (N : Node_Id;
2123 Spec_Id : Entity_Id);
2124 -- N is an inlined function body that returns an unconstrained type and
2125 -- has a single extended return statement. Split N in two subprograms:
2126 -- a procedure P' and a function F'. The formals of P' duplicate the
2127 -- formals of N plus an extra formal which is used to return a value;
2128 -- its body is composed by the declarations and list of statements
2129 -- of the extended return statement of N.
2131 --------------------------
2132 -- Build_Body_To_Inline --
2133 --------------------------
2135 procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id) is
2136 procedure Generate_Subprogram_Body
2137 (N : Node_Id;
2138 Body_To_Inline : out Node_Id);
2139 -- Generate a parameterless duplicate of subprogram body N. Note that
2140 -- occurrences of pragmas referencing the formals are removed since
2141 -- they have no meaning when the body is inlined and the formals are
2142 -- rewritten (the analysis of the non-inlined body will handle these
2143 -- pragmas). A new internal name is associated with Body_To_Inline.
2145 ------------------------------
2146 -- Generate_Subprogram_Body --
2147 ------------------------------
2149 procedure Generate_Subprogram_Body
2150 (N : Node_Id;
2151 Body_To_Inline : out Node_Id)
2153 begin
2154 -- Within an instance, the body to inline must be treated as a
2155 -- nested generic so that proper global references are preserved.
2157 -- Note that we do not do this at the library level, because it
2158 -- is not needed, and furthermore this causes trouble if front
2159 -- end inlining is activated (-gnatN).
2161 if In_Instance
2162 and then Scope (Current_Scope) /= Standard_Standard
2163 then
2164 Body_To_Inline :=
2165 Copy_Generic_Node (N, Empty, Instantiating => True);
2166 else
2167 Body_To_Inline := New_Copy_Tree (N);
2168 end if;
2170 -- Remove aspects/pragmas that have no meaning in an inlined body
2172 Remove_Aspects_And_Pragmas (Body_To_Inline);
2174 -- We need to capture references to the formals in order
2175 -- to substitute the actuals at the point of inlining, i.e.
2176 -- instantiation. To treat the formals as globals to the body to
2177 -- inline, we nest it within a dummy parameterless subprogram,
2178 -- declared within the real one.
2180 Set_Parameter_Specifications
2181 (Specification (Body_To_Inline), No_List);
2183 -- A new internal name is associated with Body_To_Inline to avoid
2184 -- conflicts when the non-inlined body N is analyzed.
2186 Set_Defining_Unit_Name (Specification (Body_To_Inline),
2187 Make_Defining_Identifier (Sloc (N), New_Internal_Name ('P')));
2188 Set_Corresponding_Spec (Body_To_Inline, Empty);
2189 end Generate_Subprogram_Body;
2191 -- Local variables
2193 Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id);
2194 Original_Body : Node_Id;
2195 Body_To_Analyze : Node_Id;
2197 -- Start of processing for Build_Body_To_Inline
2199 begin
2200 pragma Assert (Current_Scope = Spec_Id);
2202 -- Within an instance, the body to inline must be treated as a nested
2203 -- generic, so that the proper global references are preserved. We
2204 -- do not do this at the library level, because it is not needed, and
2205 -- furthermore this causes trouble if front-end inlining is activated
2206 -- (-gnatN).
2208 if In_Instance
2209 and then Scope (Current_Scope) /= Standard_Standard
2210 then
2211 Save_Env (Scope (Current_Scope), Scope (Current_Scope));
2212 end if;
2214 -- Capture references to formals in order to substitute the actuals
2215 -- at the point of inlining or instantiation. To treat the formals
2216 -- as globals to the body to inline, nest the body within a dummy
2217 -- parameterless subprogram, declared within the real one.
2219 Generate_Subprogram_Body (N, Original_Body);
2220 Body_To_Analyze :=
2221 Copy_Generic_Node (Original_Body, Empty, Instantiating => False);
2223 -- Set return type of function, which is also global and does not
2224 -- need to be resolved.
2226 if Ekind (Spec_Id) = E_Function then
2227 Set_Result_Definition (Specification (Body_To_Analyze),
2228 New_Occurrence_Of (Etype (Spec_Id), Sloc (N)));
2229 end if;
2231 if No (Declarations (N)) then
2232 Set_Declarations (N, New_List (Body_To_Analyze));
2233 else
2234 Append_To (Declarations (N), Body_To_Analyze);
2235 end if;
2237 Preanalyze (Body_To_Analyze);
2239 Push_Scope (Defining_Entity (Body_To_Analyze));
2240 Save_Global_References (Original_Body);
2241 End_Scope;
2242 Remove (Body_To_Analyze);
2244 -- Restore environment if previously saved
2246 if In_Instance
2247 and then Scope (Current_Scope) /= Standard_Standard
2248 then
2249 Restore_Env;
2250 end if;
2252 pragma Assert (No (Body_To_Inline (Decl)));
2253 Set_Body_To_Inline (Decl, Original_Body);
2254 Mutate_Ekind (Defining_Entity (Original_Body), Ekind (Spec_Id));
2255 end Build_Body_To_Inline;
2257 --------------------------------
2258 -- Build_Return_Object_Formal --
2259 --------------------------------
2261 procedure Build_Return_Object_Formal
2262 (Loc : Source_Ptr;
2263 Obj_Decl : Node_Id;
2264 Formals : List_Id)
2266 Obj_Def : constant Node_Id := Object_Definition (Obj_Decl);
2267 Obj_Id : constant Entity_Id := Defining_Entity (Obj_Decl);
2268 Typ_Def : Node_Id;
2270 begin
2271 -- Build the type definition of the formal parameter. The use of
2272 -- New_Copy_Tree ensures that global references preserved in the
2273 -- case of generics.
2275 if Is_Entity_Name (Obj_Def) then
2276 Typ_Def := New_Copy_Tree (Obj_Def);
2277 else
2278 Typ_Def := New_Copy_Tree (Subtype_Mark (Obj_Def));
2279 end if;
2281 -- Generate:
2283 -- Obj_Id : [out] Typ_Def
2285 -- Mode OUT should not be used when the return object is declared as
2286 -- a constant. Check the definition of the object declaration because
2287 -- the object has not been analyzed yet.
2289 Append_To (Formals,
2290 Make_Parameter_Specification (Loc,
2291 Defining_Identifier =>
2292 Make_Defining_Identifier (Loc, Chars (Obj_Id)),
2293 In_Present => False,
2294 Out_Present => not Constant_Present (Obj_Decl),
2295 Null_Exclusion_Present => False,
2296 Parameter_Type => Typ_Def));
2297 end Build_Return_Object_Formal;
2299 --------------------------------------
2300 -- Can_Split_Unconstrained_Function --
2301 --------------------------------------
2303 function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean is
2304 Stmt : constant Node_Id :=
2305 First (Statements (Handled_Statement_Sequence (N)));
2306 Decl : Node_Id;
2308 begin
2309 -- No user defined declarations allowed in the function except inside
2310 -- the unique return statement; implicit labels are the only allowed
2311 -- declarations.
2313 Decl := First (Declarations (N));
2314 while Present (Decl) loop
2315 if Nkind (Decl) /= N_Implicit_Label_Declaration then
2316 return False;
2317 end if;
2319 Next (Decl);
2320 end loop;
2322 -- We only split the inlined function when we are generating the code
2323 -- of its body; otherwise we leave duplicated split subprograms in
2324 -- the tree which (if referenced) generate wrong references at link
2325 -- time.
2327 return In_Extended_Main_Code_Unit (N)
2328 and then Present (Stmt)
2329 and then Nkind (Stmt) = N_Extended_Return_Statement
2330 and then No (Next (Stmt))
2331 and then Present (Handled_Statement_Sequence (Stmt));
2332 end Can_Split_Unconstrained_Function;
2334 ------------------
2335 -- Copy_Formals --
2336 ------------------
2338 procedure Copy_Formals
2339 (Loc : Source_Ptr;
2340 Subp_Id : Entity_Id;
2341 Formals : List_Id)
2343 Formal : Entity_Id;
2344 Spec : Node_Id;
2346 begin
2347 Formal := First_Formal (Subp_Id);
2348 while Present (Formal) loop
2349 Spec := Parent (Formal);
2351 -- Create an exact copy of the formal parameter. The use of
2352 -- New_Copy_Tree ensures that global references are preserved
2353 -- in case of generics.
2355 Append_To (Formals,
2356 Make_Parameter_Specification (Loc,
2357 Defining_Identifier =>
2358 Make_Defining_Identifier (Sloc (Formal), Chars (Formal)),
2359 In_Present => In_Present (Spec),
2360 Out_Present => Out_Present (Spec),
2361 Null_Exclusion_Present => Null_Exclusion_Present (Spec),
2362 Parameter_Type =>
2363 New_Copy_Tree (Parameter_Type (Spec)),
2364 Expression => New_Copy_Tree (Expression (Spec))));
2366 Next_Formal (Formal);
2367 end loop;
2368 end Copy_Formals;
2370 ------------------------
2371 -- Copy_Return_Object --
2372 ------------------------
2374 function Copy_Return_Object (Obj_Decl : Node_Id) return Node_Id is
2375 Obj_Id : constant Entity_Id := Defining_Entity (Obj_Decl);
2377 begin
2378 -- The use of New_Copy_Tree ensures that global references are
2379 -- preserved in case of generics.
2381 return
2382 Make_Object_Declaration (Sloc (Obj_Decl),
2383 Defining_Identifier =>
2384 Make_Defining_Identifier (Sloc (Obj_Id), Chars (Obj_Id)),
2385 Aliased_Present => Aliased_Present (Obj_Decl),
2386 Constant_Present => Constant_Present (Obj_Decl),
2387 Null_Exclusion_Present => Null_Exclusion_Present (Obj_Decl),
2388 Object_Definition =>
2389 New_Copy_Tree (Object_Definition (Obj_Decl)),
2390 Expression => New_Copy_Tree (Expression (Obj_Decl)));
2391 end Copy_Return_Object;
2393 ----------------------------------
2394 -- Split_Unconstrained_Function --
2395 ----------------------------------
2397 procedure Split_Unconstrained_Function
2398 (N : Node_Id;
2399 Spec_Id : Entity_Id)
2401 Loc : constant Source_Ptr := Sloc (N);
2402 Ret_Stmt : constant Node_Id :=
2403 First (Statements (Handled_Statement_Sequence (N)));
2404 Ret_Obj : constant Node_Id :=
2405 First (Return_Object_Declarations (Ret_Stmt));
2407 procedure Build_Procedure
2408 (Proc_Id : out Entity_Id;
2409 Decl_List : out List_Id);
2410 -- Build a procedure containing the statements found in the extended
2411 -- return statement of the unconstrained function body N.
2413 ---------------------
2414 -- Build_Procedure --
2415 ---------------------
2417 procedure Build_Procedure
2418 (Proc_Id : out Entity_Id;
2419 Decl_List : out List_Id)
2421 Formals : constant List_Id := New_List;
2422 Subp_Name : constant Name_Id := New_Internal_Name ('F');
2424 Body_Decls : List_Id := No_List;
2425 Decl : Node_Id;
2426 Proc_Body : Node_Id;
2427 Proc_Spec : Node_Id;
2429 begin
2430 -- Create formal parameters for the return object and all formals
2431 -- of the unconstrained function in order to pass their values to
2432 -- the procedure.
2434 Build_Return_Object_Formal
2435 (Loc => Loc,
2436 Obj_Decl => Ret_Obj,
2437 Formals => Formals);
2439 Copy_Formals
2440 (Loc => Loc,
2441 Subp_Id => Spec_Id,
2442 Formals => Formals);
2444 Proc_Id := Make_Defining_Identifier (Loc, Chars => Subp_Name);
2446 Proc_Spec :=
2447 Make_Procedure_Specification (Loc,
2448 Defining_Unit_Name => Proc_Id,
2449 Parameter_Specifications => Formals);
2451 Decl_List := New_List;
2453 Append_To (Decl_List,
2454 Make_Subprogram_Declaration (Loc, Proc_Spec));
2456 -- Can_Convert_Unconstrained_Function checked that the function
2457 -- has no local declarations except implicit label declarations.
2458 -- Copy these declarations to the built procedure.
2460 if Present (Declarations (N)) then
2461 Body_Decls := New_List;
2463 Decl := First (Declarations (N));
2464 while Present (Decl) loop
2465 pragma Assert (Nkind (Decl) = N_Implicit_Label_Declaration);
2467 Append_To (Body_Decls,
2468 Make_Implicit_Label_Declaration (Loc,
2469 Make_Defining_Identifier (Loc,
2470 Chars => Chars (Defining_Identifier (Decl))),
2471 Label_Construct => Empty));
2473 Next (Decl);
2474 end loop;
2475 end if;
2477 pragma Assert (Present (Handled_Statement_Sequence (Ret_Stmt)));
2479 Proc_Body :=
2480 Make_Subprogram_Body (Loc,
2481 Specification => Copy_Subprogram_Spec (Proc_Spec),
2482 Declarations => Body_Decls,
2483 Handled_Statement_Sequence =>
2484 New_Copy_Tree (Handled_Statement_Sequence (Ret_Stmt)));
2486 Set_Defining_Unit_Name (Specification (Proc_Body),
2487 Make_Defining_Identifier (Loc, Subp_Name));
2489 Append_To (Decl_List, Proc_Body);
2490 end Build_Procedure;
2492 -- Local variables
2494 New_Obj : constant Node_Id := Copy_Return_Object (Ret_Obj);
2495 Blk_Stmt : Node_Id;
2496 Proc_Call : Node_Id;
2497 Proc_Id : Entity_Id;
2499 -- Start of processing for Split_Unconstrained_Function
2501 begin
2502 -- Build the associated procedure, analyze it and insert it before
2503 -- the function body N.
2505 declare
2506 Scope : constant Entity_Id := Current_Scope;
2507 Decl_List : List_Id;
2508 begin
2509 Pop_Scope;
2510 Build_Procedure (Proc_Id, Decl_List);
2511 Insert_Actions (N, Decl_List);
2512 Set_Is_Inlined (Proc_Id);
2513 Push_Scope (Scope);
2514 end;
2516 -- Build the call to the generated procedure
2518 declare
2519 Actual_List : constant List_Id := New_List;
2520 Formal : Entity_Id;
2522 begin
2523 Append_To (Actual_List,
2524 New_Occurrence_Of (Defining_Identifier (New_Obj), Loc));
2526 Formal := First_Formal (Spec_Id);
2527 while Present (Formal) loop
2528 Append_To (Actual_List, New_Occurrence_Of (Formal, Loc));
2530 -- Avoid spurious warning on unreferenced formals
2532 Set_Referenced (Formal);
2533 Next_Formal (Formal);
2534 end loop;
2536 Proc_Call :=
2537 Make_Procedure_Call_Statement (Loc,
2538 Name => New_Occurrence_Of (Proc_Id, Loc),
2539 Parameter_Associations => Actual_List);
2540 end;
2542 -- Generate:
2544 -- declare
2545 -- New_Obj : ...
2546 -- begin
2547 -- Proc (New_Obj, ...);
2548 -- return New_Obj;
2549 -- end;
2551 Blk_Stmt :=
2552 Make_Block_Statement (Loc,
2553 Declarations => New_List (New_Obj),
2554 Handled_Statement_Sequence =>
2555 Make_Handled_Sequence_Of_Statements (Loc,
2556 Statements => New_List (
2558 Proc_Call,
2560 Make_Simple_Return_Statement (Loc,
2561 Expression =>
2562 New_Occurrence_Of
2563 (Defining_Identifier (New_Obj), Loc)))));
2565 Rewrite (Ret_Stmt, Blk_Stmt);
2566 end Split_Unconstrained_Function;
2568 -- Local variables
2570 Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id);
2572 -- Start of processing for Check_And_Split_Unconstrained_Function
2574 begin
2575 pragma Assert (Back_End_Inlining
2576 and then Ekind (Spec_Id) = E_Function
2577 and then Returns_Unconstrained_Type (Spec_Id)
2578 and then Comes_From_Source (Body_Id)
2579 and then (Has_Pragma_Inline_Always (Spec_Id)
2580 or else Optimization_Level > 0));
2582 -- This routine must not be used in GNATprove mode since GNATprove
2583 -- relies on frontend inlining
2585 pragma Assert (not GNATprove_Mode);
2587 -- No need to split the function if we cannot generate the code
2589 if Serious_Errors_Detected /= 0 then
2590 return;
2591 end if;
2593 -- No action needed in stubs since the attribute Body_To_Inline
2594 -- is not available
2596 if Nkind (Decl) = N_Subprogram_Body_Stub then
2597 return;
2599 -- Cannot build the body to inline if the attribute is already set.
2600 -- This attribute may have been set if this is a subprogram renaming
2601 -- declarations (see Freeze.Build_Renamed_Body).
2603 elsif Present (Body_To_Inline (Decl)) then
2604 return;
2606 -- Do not generate a body to inline for protected functions, because the
2607 -- transformation generates a call to a protected procedure, causing
2608 -- spurious errors. We don't inline protected operations anyway, so
2609 -- this is no loss. We might as well ignore intrinsics and foreign
2610 -- conventions as well -- just allow Ada conventions.
2612 elsif not (Convention (Spec_Id) = Convention_Ada
2613 or else Convention (Spec_Id) = Convention_Ada_Pass_By_Copy
2614 or else Convention (Spec_Id) = Convention_Ada_Pass_By_Reference)
2615 then
2616 return;
2618 -- Check excluded declarations
2620 elsif Present (Declarations (N))
2621 and then Has_Excluded_Declaration (Spec_Id, Declarations (N))
2622 then
2623 return;
2625 -- Check excluded statements. There is no need to protect us against
2626 -- exception handlers since they are supported by the GCC backend.
2628 elsif Present (Handled_Statement_Sequence (N))
2629 and then Has_Excluded_Statement
2630 (Spec_Id, Statements (Handled_Statement_Sequence (N)))
2631 then
2632 return;
2633 end if;
2635 -- Build the body to inline only if really needed
2637 if Can_Split_Unconstrained_Function (N) then
2638 Split_Unconstrained_Function (N, Spec_Id);
2639 Build_Body_To_Inline (N, Spec_Id);
2640 Set_Is_Inlined (Spec_Id);
2641 end if;
2642 end Check_And_Split_Unconstrained_Function;
2644 -------------------------------------
2645 -- Check_Package_Body_For_Inlining --
2646 -------------------------------------
2648 procedure Check_Package_Body_For_Inlining (N : Node_Id; P : Entity_Id) is
2649 Bname : Unit_Name_Type;
2650 E : Entity_Id;
2651 OK : Boolean;
2653 begin
2654 -- Legacy implementation (relying on frontend inlining)
2656 if not Back_End_Inlining
2657 and then Is_Compilation_Unit (P)
2658 and then not Is_Generic_Instance (P)
2659 then
2660 Bname := Get_Body_Name (Get_Unit_Name (Unit (N)));
2662 E := First_Entity (P);
2663 while Present (E) loop
2664 if Has_Pragma_Inline_Always (E)
2665 or else (Has_Pragma_Inline (E) and Front_End_Inlining)
2666 then
2667 if not Is_Loaded (Bname) then
2668 Load_Needed_Body (N, OK);
2670 if OK then
2672 -- Check we are not trying to inline a parent whose body
2673 -- depends on a child, when we are compiling the body of
2674 -- the child. Otherwise we have a potential elaboration
2675 -- circularity with inlined subprograms and with
2676 -- Taft-Amendment types.
2678 declare
2679 Comp : Node_Id; -- Body just compiled
2680 Child_Spec : Entity_Id; -- Spec of main unit
2681 Ent : Entity_Id; -- For iteration
2682 With_Clause : Node_Id; -- Context of body.
2684 begin
2685 if Nkind (Unit (Cunit (Main_Unit))) = N_Package_Body
2686 and then Present (Body_Entity (P))
2687 then
2688 Child_Spec :=
2689 Defining_Entity
2690 ((Unit (Library_Unit (Cunit (Main_Unit)))));
2692 Comp :=
2693 Parent (Unit_Declaration_Node (Body_Entity (P)));
2695 -- Check whether the context of the body just
2696 -- compiled includes a child of itself, and that
2697 -- child is the spec of the main compilation.
2699 With_Clause := First (Context_Items (Comp));
2700 while Present (With_Clause) loop
2701 if Nkind (With_Clause) = N_With_Clause
2702 and then
2703 Scope (Entity (Name (With_Clause))) = P
2704 and then
2705 Entity (Name (With_Clause)) = Child_Spec
2706 then
2707 Error_Msg_Node_2 := Child_Spec;
2708 Error_Msg_NE
2709 ("body of & depends on child unit&??",
2710 With_Clause, P);
2711 Error_Msg_N
2712 ("\subprograms in body cannot be inlined??",
2713 With_Clause);
2715 -- Disable further inlining from this unit,
2716 -- and keep Taft-amendment types incomplete.
2718 Ent := First_Entity (P);
2719 while Present (Ent) loop
2720 if Is_Type (Ent)
2721 and then Has_Completion_In_Body (Ent)
2722 then
2723 Set_Full_View (Ent, Empty);
2725 elsif Is_Subprogram (Ent) then
2726 Set_Is_Inlined (Ent, False);
2727 end if;
2729 Next_Entity (Ent);
2730 end loop;
2732 return;
2733 end if;
2735 Next (With_Clause);
2736 end loop;
2737 end if;
2738 end;
2740 elsif Ineffective_Inline_Warnings then
2741 Error_Msg_Unit_1 := Bname;
2742 Error_Msg_N
2743 ("unable to inline subprograms defined in $??", P);
2744 Error_Msg_N ("\body not found??", P);
2745 return;
2746 end if;
2747 end if;
2749 return;
2750 end if;
2752 Next_Entity (E);
2753 end loop;
2754 end if;
2755 end Check_Package_Body_For_Inlining;
2757 --------------------
2758 -- Cleanup_Scopes --
2759 --------------------
2761 procedure Cleanup_Scopes is
2762 Elmt : Elmt_Id;
2763 Decl : Node_Id;
2764 Scop : Entity_Id;
2766 begin
2767 Elmt := First_Elmt (To_Clean);
2768 while Present (Elmt) loop
2769 Scop := Node (Elmt);
2771 if Ekind (Scop) = E_Entry then
2772 Scop := Protected_Body_Subprogram (Scop);
2774 elsif Is_Subprogram (Scop)
2775 and then Is_Protected_Type (Scope (Scop))
2776 and then Present (Protected_Body_Subprogram (Scop))
2777 then
2778 -- If a protected operation contains an instance, its cleanup
2779 -- operations have been delayed, and the subprogram has been
2780 -- rewritten in the expansion of the enclosing protected body. It
2781 -- is the corresponding subprogram that may require the cleanup
2782 -- operations, so propagate the information that triggers cleanup
2783 -- activity.
2785 Set_Uses_Sec_Stack
2786 (Protected_Body_Subprogram (Scop),
2787 Uses_Sec_Stack (Scop));
2789 Scop := Protected_Body_Subprogram (Scop);
2790 end if;
2792 if Ekind (Scop) = E_Block then
2793 Decl := Parent (Block_Node (Scop));
2795 else
2796 Decl := Unit_Declaration_Node (Scop);
2798 if Nkind (Decl) in N_Subprogram_Declaration
2799 | N_Task_Type_Declaration
2800 | N_Subprogram_Body_Stub
2801 then
2802 Decl := Unit_Declaration_Node (Corresponding_Body (Decl));
2803 end if;
2804 end if;
2806 Push_Scope (Scop);
2807 Expand_Cleanup_Actions (Decl);
2808 End_Scope;
2810 Next_Elmt (Elmt);
2811 end loop;
2812 end Cleanup_Scopes;
2814 procedure Establish_Actual_Mapping_For_Inlined_Call
2815 (N : Node_Id;
2816 Subp : Entity_Id;
2817 Decls : List_Id;
2818 Body_Or_Expr_To_Check : Node_Id)
2821 function Formal_Is_Used_Once (Formal : Entity_Id) return Boolean;
2822 -- Determine whether a formal parameter is used only once in
2823 -- Body_Or_Expr_To_Check.
2825 -------------------------
2826 -- Formal_Is_Used_Once --
2827 -------------------------
2829 function Formal_Is_Used_Once (Formal : Entity_Id) return Boolean is
2830 Use_Counter : Nat := 0;
2832 function Count_Uses (N : Node_Id) return Traverse_Result;
2833 -- Traverse the tree and count the uses of the formal parameter.
2834 -- In this case, for optimization purposes, we do not need to
2835 -- continue the traversal once more than one use is encountered.
2837 ----------------
2838 -- Count_Uses --
2839 ----------------
2841 function Count_Uses (N : Node_Id) return Traverse_Result is
2842 begin
2843 -- The original node is an identifier
2845 if Nkind (N) = N_Identifier
2846 and then Present (Entity (N))
2848 -- Original node's entity points to the one in the copied body
2850 and then Nkind (Entity (N)) = N_Identifier
2851 and then Present (Entity (Entity (N)))
2853 -- The entity of the copied node is the formal parameter
2855 and then Entity (Entity (N)) = Formal
2856 then
2857 Use_Counter := Use_Counter + 1;
2859 -- If this is a second use then abandon the traversal
2861 if Use_Counter > 1 then
2862 return Abandon;
2863 end if;
2864 end if;
2866 return OK;
2867 end Count_Uses;
2869 procedure Count_Formal_Uses is new Traverse_Proc (Count_Uses);
2871 -- Start of processing for Formal_Is_Used_Once
2873 begin
2874 Count_Formal_Uses (Body_Or_Expr_To_Check);
2875 return Use_Counter = 1;
2876 end Formal_Is_Used_Once;
2878 -- Local Data --
2880 F : Entity_Id;
2881 A : Node_Id;
2882 Decl : Node_Id;
2883 Loc : constant Source_Ptr := Sloc (N);
2884 New_A : Node_Id;
2885 Temp : Entity_Id;
2886 Temp_Typ : Entity_Id;
2888 -- Start of processing for Establish_Actual_Mapping_For_Inlined_Call
2890 begin
2891 F := First_Formal (Subp);
2892 A := First_Actual (N);
2893 while Present (F) loop
2894 if Present (Renamed_Object (F)) then
2896 -- If expander is active, it is an error to try to inline a
2897 -- recursive subprogram. In GNATprove mode, just indicate that the
2898 -- inlining will not happen, and mark the subprogram as not always
2899 -- inlined.
2901 if GNATprove_Mode then
2902 Cannot_Inline
2903 ("cannot inline call to recursive subprogram?", N, Subp);
2904 Set_Is_Inlined_Always (Subp, False);
2905 else
2906 Error_Msg_N
2907 ("cannot inline call to recursive subprogram", N);
2908 end if;
2910 return;
2911 end if;
2913 -- Reset Last_Assignment for any parameters of mode out or in out, to
2914 -- prevent spurious warnings about overwriting for assignments to the
2915 -- formal in the inlined code.
2917 if Is_Entity_Name (A) and then Ekind (F) /= E_In_Parameter then
2919 -- In GNATprove mode a protected component acting as an actual
2920 -- subprogram parameter will appear as inlined-for-proof. However,
2921 -- its E_Component entity is not an assignable object, so the
2922 -- assertion in Set_Last_Assignment will fail. We just omit the
2923 -- call to Set_Last_Assignment, because GNATprove flags useless
2924 -- assignments with its own flow analysis.
2926 -- In GNAT mode such a problem does not occur, because protected
2927 -- components are inlined via object renamings whose entity kind
2928 -- E_Variable is assignable.
2930 if Is_Assignable (Entity (A)) then
2931 Set_Last_Assignment (Entity (A), Empty);
2932 else
2933 pragma Assert
2934 (GNATprove_Mode and then Is_Protected_Component (Entity (A)));
2935 end if;
2936 end if;
2938 -- If the argument may be a controlling argument in a call within
2939 -- the inlined body, we must preserve its class-wide nature to ensure
2940 -- that dynamic dispatching will take place subsequently. If the
2941 -- formal has a constraint, then it must be preserved to retain the
2942 -- semantics of the body.
2944 if Is_Class_Wide_Type (Etype (F))
2945 or else (Is_Access_Type (Etype (F))
2946 and then Is_Class_Wide_Type (Designated_Type (Etype (F))))
2947 then
2948 Temp_Typ := Etype (F);
2950 elsif Base_Type (Etype (F)) = Base_Type (Etype (A))
2951 and then Etype (F) /= Base_Type (Etype (F))
2952 and then Is_Constrained (Etype (F))
2953 then
2954 Temp_Typ := Etype (F);
2956 else
2957 Temp_Typ := Etype (A);
2958 end if;
2960 -- If the actual is a simple name or a literal, no need to
2961 -- create a temporary, object can be used directly.
2963 -- If the actual is a literal and the formal has its address taken,
2964 -- we cannot pass the literal itself as an argument, so its value
2965 -- must be captured in a temporary. Skip this optimization in
2966 -- GNATprove mode, to make sure any check on a type conversion
2967 -- will be issued.
2969 if (Is_Entity_Name (A)
2970 and then
2971 (not Is_Scalar_Type (Etype (A))
2972 or else Ekind (Entity (A)) = E_Enumeration_Literal)
2973 and then not GNATprove_Mode)
2975 -- When the actual is an identifier and the corresponding formal is
2976 -- used only once in the original body, the formal can be substituted
2977 -- directly with the actual parameter. Skip this optimization in
2978 -- GNATprove mode, to make sure any check on a type conversion
2979 -- will be issued.
2981 or else
2982 (Nkind (A) = N_Identifier
2983 and then Formal_Is_Used_Once (F)
2984 and then not GNATprove_Mode)
2986 or else
2987 (Nkind (A) in
2988 N_Real_Literal | N_Integer_Literal | N_Character_Literal
2989 and then not Address_Taken (F))
2990 then
2991 if Etype (F) /= Etype (A) then
2992 Set_Renamed_Object
2993 (F, Unchecked_Convert_To (Etype (F), Relocate_Node (A)));
2994 else
2995 Set_Renamed_Object (F, A);
2996 end if;
2998 else
2999 Temp := Make_Temporary (Loc, 'C');
3001 -- If the actual for an in/in-out parameter is a view conversion,
3002 -- make it into an unchecked conversion, given that an untagged
3003 -- type conversion is not a proper object for a renaming.
3005 -- In-out conversions that involve real conversions have already
3006 -- been transformed in Expand_Actuals.
3008 if Nkind (A) = N_Type_Conversion
3009 and then Ekind (F) /= E_In_Parameter
3010 then
3011 New_A := Unchecked_Convert_To (Etype (F), Expression (A));
3013 -- In GNATprove mode, keep the most precise type of the actual for
3014 -- the temporary variable, when the formal type is unconstrained.
3015 -- Otherwise, the AST may contain unexpected assignment statements
3016 -- to a temporary variable of unconstrained type renaming a local
3017 -- variable of constrained type, which is not expected by
3018 -- GNATprove.
3020 elsif Etype (F) /= Etype (A)
3021 and then (not GNATprove_Mode or else Is_Constrained (Etype (F)))
3022 then
3023 New_A := Unchecked_Convert_To (Etype (F), Relocate_Node (A));
3024 Temp_Typ := Etype (F);
3026 else
3027 New_A := Relocate_Node (A);
3028 end if;
3030 Set_Sloc (New_A, Sloc (N));
3032 -- If the actual has a by-reference type, it cannot be copied,
3033 -- so its value is captured in a renaming declaration. Otherwise
3034 -- declare a local constant initialized with the actual.
3036 -- We also use a renaming declaration for expressions of an array
3037 -- type that is not bit-packed, both for efficiency reasons and to
3038 -- respect the semantics of the call: in most cases the original
3039 -- call will pass the parameter by reference, and thus the inlined
3040 -- code will have the same semantics.
3042 -- Finally, we need a renaming declaration in the case of limited
3043 -- types for which initialization cannot be by copy either.
3045 if Ekind (F) = E_In_Parameter
3046 and then not Is_By_Reference_Type (Etype (A))
3047 and then not Is_Limited_Type (Etype (A))
3048 and then
3049 (not Is_Array_Type (Etype (A))
3050 or else not Is_Object_Reference (A)
3051 or else Is_Bit_Packed_Array (Etype (A)))
3052 then
3053 Decl :=
3054 Make_Object_Declaration (Loc,
3055 Defining_Identifier => Temp,
3056 Constant_Present => True,
3057 Object_Definition => New_Occurrence_Of (Temp_Typ, Loc),
3058 Expression => New_A);
3060 else
3061 -- In GNATprove mode, make an explicit copy of input
3062 -- parameters when formal and actual types differ, to make
3063 -- sure any check on the type conversion will be issued.
3064 -- The legality of the copy is ensured by calling first
3065 -- Call_Can_Be_Inlined_In_GNATprove_Mode.
3067 if GNATprove_Mode
3068 and then Ekind (F) /= E_Out_Parameter
3069 and then not Same_Type (Etype (F), Etype (A))
3070 then
3071 pragma Assert (not Is_By_Reference_Type (Etype (A)));
3072 pragma Assert (not Is_Limited_Type (Etype (A)));
3074 Append_To (Decls,
3075 Make_Object_Declaration (Loc,
3076 Defining_Identifier => Make_Temporary (Loc, 'C'),
3077 Constant_Present => True,
3078 Object_Definition => New_Occurrence_Of (Temp_Typ, Loc),
3079 Expression => New_Copy_Tree (New_A)));
3080 end if;
3082 Decl :=
3083 Make_Object_Renaming_Declaration (Loc,
3084 Defining_Identifier => Temp,
3085 Subtype_Mark => New_Occurrence_Of (Temp_Typ, Loc),
3086 Name => New_A);
3087 end if;
3089 Append (Decl, Decls);
3090 Set_Renamed_Object (F, Temp);
3091 end if;
3093 Next_Formal (F);
3094 Next_Actual (A);
3095 end loop;
3096 end Establish_Actual_Mapping_For_Inlined_Call;
3098 -------------------------
3099 -- Expand_Inlined_Call --
3100 -------------------------
3102 procedure Expand_Inlined_Call
3103 (N : Node_Id;
3104 Subp : Entity_Id;
3105 Orig_Subp : Entity_Id)
3107 Decls : constant List_Id := New_List;
3108 Is_Predef : constant Boolean :=
3109 Is_Predefined_Unit (Get_Source_Unit (Subp));
3110 Loc : constant Source_Ptr := Sloc (N);
3111 Orig_Bod : constant Node_Id :=
3112 Body_To_Inline (Unit_Declaration_Node (Subp));
3114 Uses_Back_End : constant Boolean :=
3115 Back_End_Inlining and then Optimization_Level > 0;
3116 -- The back-end expansion is used if the target supports back-end
3117 -- inlining and some level of optimixation is required; otherwise
3118 -- the inlining takes place fully as a tree expansion.
3120 Blk : Node_Id;
3121 Decl : Node_Id;
3122 Exit_Lab : Entity_Id := Empty;
3123 Lab_Decl : Node_Id := Empty;
3124 Lab_Id : Node_Id;
3125 Num_Ret : Nat := 0;
3126 Ret_Type : Entity_Id;
3127 Temp : Entity_Id;
3129 Is_Unc : Boolean;
3130 Is_Unc_Decl : Boolean;
3131 -- If the type returned by the function is unconstrained and the call
3132 -- can be inlined, special processing is required.
3134 Return_Object : Entity_Id := Empty;
3135 -- Entity in declaration in an extended_return_statement
3137 Targ : Node_Id := Empty;
3138 -- The target of the call. If context is an assignment statement then
3139 -- this is the left-hand side of the assignment, else it is a temporary
3140 -- to which the return value is assigned prior to rewriting the call.
3142 Targ1 : Node_Id := Empty;
3143 -- A separate target used when the return type is unconstrained
3145 procedure Declare_Postconditions_Result;
3146 -- When generating C code, declare _Result, which may be used in the
3147 -- inlined _Postconditions procedure to verify the return value.
3149 procedure Make_Exit_Label;
3150 -- Build declaration for exit label to be used in Return statements,
3151 -- sets Exit_Lab (the label node) and Lab_Decl (corresponding implicit
3152 -- declaration). Does nothing if Exit_Lab already set.
3154 procedure Make_Loop_Labels_Unique (HSS : Node_Id);
3155 -- When compiling for CCG and performing front-end inlining, replace
3156 -- loop names and references to them so that they do not conflict with
3157 -- homographs in the current subprogram.
3159 function Process_Formals (N : Node_Id) return Traverse_Result;
3160 -- Replace occurrence of a formal with the corresponding actual, or the
3161 -- thunk generated for it. Replace a return statement with an assignment
3162 -- to the target of the call, with appropriate conversions if needed.
3164 function Process_Formals_In_Aspects (N : Node_Id) return Traverse_Result;
3165 -- Because aspects are linked indirectly to the rest of the tree,
3166 -- replacement of formals appearing in aspect specifications must
3167 -- be performed in a separate pass, using an instantiation of the
3168 -- previous subprogram over aspect specifications reachable from N.
3170 function Process_Sloc (Nod : Node_Id) return Traverse_Result;
3171 -- If the call being expanded is that of an internal subprogram, set the
3172 -- sloc of the generated block to that of the call itself, so that the
3173 -- expansion is skipped by the "next" command in gdb. Same processing
3174 -- for a subprogram in a predefined file, e.g. Ada.Tags. If
3175 -- Debug_Generated_Code is true, suppress this change to simplify our
3176 -- own development. Same in GNATprove mode, to ensure that warnings and
3177 -- diagnostics point to the proper location.
3179 procedure Reset_Dispatching_Calls (N : Node_Id);
3180 -- In subtree N search for occurrences of dispatching calls that use the
3181 -- Ada 2005 Object.Operation notation and the object is a formal of the
3182 -- inlined subprogram. Reset the entity associated with Operation in all
3183 -- the found occurrences.
3185 procedure Rewrite_Function_Call (N : Node_Id; Blk : Node_Id);
3186 -- If the function body is a single expression, replace call with
3187 -- expression, else insert block appropriately.
3189 procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id);
3190 -- If procedure body has no local variables, inline body without
3191 -- creating block, otherwise rewrite call with block.
3193 -----------------------------------
3194 -- Declare_Postconditions_Result --
3195 -----------------------------------
3197 procedure Declare_Postconditions_Result is
3198 Enclosing_Subp : constant Entity_Id := Scope (Subp);
3200 begin
3201 pragma Assert
3202 (Modify_Tree_For_C
3203 and then Is_Subprogram (Enclosing_Subp)
3204 and then Present (Postconditions_Proc (Enclosing_Subp)));
3206 if Ekind (Enclosing_Subp) = E_Function then
3207 if Nkind (First (Parameter_Associations (N))) in
3208 N_Numeric_Or_String_Literal
3209 then
3210 Append_To (Declarations (Blk),
3211 Make_Object_Declaration (Loc,
3212 Defining_Identifier =>
3213 Make_Defining_Identifier (Loc, Name_uResult),
3214 Constant_Present => True,
3215 Object_Definition =>
3216 New_Occurrence_Of (Etype (Enclosing_Subp), Loc),
3217 Expression =>
3218 New_Copy_Tree (First (Parameter_Associations (N)))));
3219 else
3220 Append_To (Declarations (Blk),
3221 Make_Object_Renaming_Declaration (Loc,
3222 Defining_Identifier =>
3223 Make_Defining_Identifier (Loc, Name_uResult),
3224 Subtype_Mark =>
3225 New_Occurrence_Of (Etype (Enclosing_Subp), Loc),
3226 Name =>
3227 New_Copy_Tree (First (Parameter_Associations (N)))));
3228 end if;
3229 end if;
3230 end Declare_Postconditions_Result;
3232 ---------------------
3233 -- Make_Exit_Label --
3234 ---------------------
3236 procedure Make_Exit_Label is
3237 Lab_Ent : Entity_Id;
3238 begin
3239 if No (Exit_Lab) then
3240 Lab_Ent := Make_Temporary (Loc, 'L');
3241 Lab_Id := New_Occurrence_Of (Lab_Ent, Loc);
3242 Exit_Lab := Make_Label (Loc, Lab_Id);
3243 Lab_Decl :=
3244 Make_Implicit_Label_Declaration (Loc,
3245 Defining_Identifier => Lab_Ent,
3246 Label_Construct => Exit_Lab);
3247 end if;
3248 end Make_Exit_Label;
3250 -----------------------------
3251 -- Make_Loop_Labels_Unique --
3252 -----------------------------
3254 procedure Make_Loop_Labels_Unique (HSS : Node_Id) is
3255 function Process_Loop (N : Node_Id) return Traverse_Result;
3257 ------------------
3258 -- Process_Loop --
3259 ------------------
3261 function Process_Loop (N : Node_Id) return Traverse_Result is
3262 Id : Entity_Id;
3264 begin
3265 if Nkind (N) = N_Loop_Statement
3266 and then Present (Identifier (N))
3267 then
3268 -- Create new external name for loop and update the
3269 -- corresponding entity.
3271 Id := Entity (Identifier (N));
3272 Set_Chars (Id, New_External_Name (Chars (Id), 'L', -1));
3273 Set_Chars (Identifier (N), Chars (Id));
3275 elsif Nkind (N) = N_Exit_Statement
3276 and then Present (Name (N))
3277 then
3278 -- The exit statement must name an enclosing loop, whose name
3279 -- has already been updated.
3281 Set_Chars (Name (N), Chars (Entity (Name (N))));
3282 end if;
3284 return OK;
3285 end Process_Loop;
3287 procedure Update_Loop_Names is new Traverse_Proc (Process_Loop);
3289 -- Local variables
3291 Stmt : Node_Id;
3293 -- Start of processing for Make_Loop_Labels_Unique
3295 begin
3296 if Modify_Tree_For_C then
3297 Stmt := First (Statements (HSS));
3298 while Present (Stmt) loop
3299 Update_Loop_Names (Stmt);
3300 Next (Stmt);
3301 end loop;
3302 end if;
3303 end Make_Loop_Labels_Unique;
3305 ---------------------
3306 -- Process_Formals --
3307 ---------------------
3309 function Process_Formals (N : Node_Id) return Traverse_Result is
3310 A : Entity_Id;
3311 E : Entity_Id;
3312 Ret : Node_Id;
3314 begin
3315 if Is_Entity_Name (N) and then Present (Entity (N)) then
3316 E := Entity (N);
3318 if Is_Formal (E) and then Scope (E) = Subp then
3319 A := Renamed_Object (E);
3321 -- Rewrite the occurrence of the formal into an occurrence of
3322 -- the actual. Also establish visibility on the proper view of
3323 -- the actual's subtype for the body's context (if the actual's
3324 -- subtype is private at the call point but its full view is
3325 -- visible to the body, then the inlined tree here must be
3326 -- analyzed with the full view).
3328 if Is_Entity_Name (A) then
3329 Rewrite (N, New_Occurrence_Of (Entity (A), Sloc (N)));
3330 Check_Private_View (N);
3332 elsif Nkind (A) = N_Defining_Identifier then
3333 Rewrite (N, New_Occurrence_Of (A, Sloc (N)));
3334 Check_Private_View (N);
3336 -- Numeric literal
3338 else
3339 Rewrite (N, New_Copy (A));
3340 end if;
3341 end if;
3343 return Skip;
3345 elsif Is_Entity_Name (N)
3346 and then Present (Return_Object)
3347 and then Chars (N) = Chars (Return_Object)
3348 then
3349 -- Occurrence within an extended return statement. The return
3350 -- object is local to the body been inlined, and thus the generic
3351 -- copy is not analyzed yet, so we match by name, and replace it
3352 -- with target of call.
3354 if Nkind (Targ) = N_Defining_Identifier then
3355 Rewrite (N, New_Occurrence_Of (Targ, Loc));
3356 else
3357 Rewrite (N, New_Copy_Tree (Targ));
3358 end if;
3360 return Skip;
3362 elsif Nkind (N) = N_Simple_Return_Statement then
3363 if No (Expression (N)) then
3364 Num_Ret := Num_Ret + 1;
3365 Make_Exit_Label;
3366 Rewrite (N,
3367 Make_Goto_Statement (Loc, Name => New_Copy (Lab_Id)));
3369 else
3370 if Nkind (Parent (N)) = N_Handled_Sequence_Of_Statements
3371 and then Nkind (Parent (Parent (N))) = N_Subprogram_Body
3372 then
3373 -- Function body is a single expression. No need for
3374 -- exit label.
3376 null;
3378 else
3379 Num_Ret := Num_Ret + 1;
3380 Make_Exit_Label;
3381 end if;
3383 -- Because of the presence of private types, the views of the
3384 -- expression and the context may be different, so place
3385 -- a type conversion to the context type to avoid spurious
3386 -- errors, e.g. when the expression is a numeric literal and
3387 -- the context is private. If the expression is an aggregate,
3388 -- use a qualified expression, because an aggregate is not a
3389 -- legal argument of a conversion. Ditto for numeric, character
3390 -- and string literals, and attributes that yield a universal
3391 -- type, because those must be resolved to a specific type.
3393 if Nkind (Expression (N)) in N_Aggregate
3394 | N_Character_Literal
3395 | N_Null
3396 | N_String_Literal
3397 or else Yields_Universal_Type (Expression (N))
3398 then
3399 Ret :=
3400 Make_Qualified_Expression (Sloc (N),
3401 Subtype_Mark => New_Occurrence_Of (Ret_Type, Sloc (N)),
3402 Expression => Relocate_Node (Expression (N)));
3404 -- Use an unchecked type conversion between access types, for
3405 -- which a type conversion would not always be valid, as no
3406 -- check may result from the conversion.
3408 elsif Is_Access_Type (Ret_Type) then
3409 Ret :=
3410 Unchecked_Convert_To
3411 (Ret_Type, Relocate_Node (Expression (N)));
3413 -- Otherwise use a type conversion, which may trigger a check
3415 else
3416 Ret :=
3417 Make_Type_Conversion (Sloc (N),
3418 Subtype_Mark => New_Occurrence_Of (Ret_Type, Sloc (N)),
3419 Expression => Relocate_Node (Expression (N)));
3420 end if;
3422 if Nkind (Targ) = N_Defining_Identifier then
3423 Rewrite (N,
3424 Make_Assignment_Statement (Loc,
3425 Name => New_Occurrence_Of (Targ, Loc),
3426 Expression => Ret));
3427 else
3428 Rewrite (N,
3429 Make_Assignment_Statement (Loc,
3430 Name => New_Copy (Targ),
3431 Expression => Ret));
3432 end if;
3434 Set_Assignment_OK (Name (N));
3436 if Present (Exit_Lab) then
3437 Insert_After (N,
3438 Make_Goto_Statement (Loc, Name => New_Copy (Lab_Id)));
3439 end if;
3440 end if;
3442 return OK;
3444 -- An extended return becomes a block whose first statement is the
3445 -- assignment of the initial expression of the return object to the
3446 -- target of the call itself.
3448 elsif Nkind (N) = N_Extended_Return_Statement then
3449 declare
3450 Return_Decl : constant Entity_Id :=
3451 First (Return_Object_Declarations (N));
3452 Assign : Node_Id;
3454 begin
3455 Return_Object := Defining_Identifier (Return_Decl);
3457 if Present (Expression (Return_Decl)) then
3458 if Nkind (Targ) = N_Defining_Identifier then
3459 Assign :=
3460 Make_Assignment_Statement (Loc,
3461 Name => New_Occurrence_Of (Targ, Loc),
3462 Expression => Expression (Return_Decl));
3463 else
3464 Assign :=
3465 Make_Assignment_Statement (Loc,
3466 Name => New_Copy (Targ),
3467 Expression => Expression (Return_Decl));
3468 end if;
3470 Set_Assignment_OK (Name (Assign));
3472 if No (Handled_Statement_Sequence (N)) then
3473 Set_Handled_Statement_Sequence (N,
3474 Make_Handled_Sequence_Of_Statements (Loc,
3475 Statements => New_List));
3476 end if;
3478 Prepend (Assign,
3479 Statements (Handled_Statement_Sequence (N)));
3480 end if;
3482 Rewrite (N,
3483 Make_Block_Statement (Loc,
3484 Handled_Statement_Sequence =>
3485 Handled_Statement_Sequence (N)));
3487 return OK;
3488 end;
3490 -- Remove pragma Unreferenced since it may refer to formals that
3491 -- are not visible in the inlined body, and in any case we will
3492 -- not be posting warnings on the inlined body so it is unneeded.
3494 elsif Nkind (N) = N_Pragma
3495 and then Pragma_Name (N) = Name_Unreferenced
3496 then
3497 Rewrite (N, Make_Null_Statement (Sloc (N)));
3498 return OK;
3500 else
3501 return OK;
3502 end if;
3503 end Process_Formals;
3505 procedure Replace_Formals is new Traverse_Proc (Process_Formals);
3507 --------------------------------
3508 -- Process_Formals_In_Aspects --
3509 --------------------------------
3511 function Process_Formals_In_Aspects
3512 (N : Node_Id) return Traverse_Result
3514 A : Node_Id;
3516 begin
3517 if Has_Aspects (N) then
3518 A := First (Aspect_Specifications (N));
3519 while Present (A) loop
3520 Replace_Formals (Expression (A));
3522 Next (A);
3523 end loop;
3524 end if;
3525 return OK;
3526 end Process_Formals_In_Aspects;
3528 procedure Replace_Formals_In_Aspects is
3529 new Traverse_Proc (Process_Formals_In_Aspects);
3531 ------------------
3532 -- Process_Sloc --
3533 ------------------
3535 function Process_Sloc (Nod : Node_Id) return Traverse_Result is
3536 begin
3537 if not Debug_Generated_Code then
3538 Set_Sloc (Nod, Sloc (N));
3539 Set_Comes_From_Source (Nod, False);
3540 end if;
3542 return OK;
3543 end Process_Sloc;
3545 procedure Reset_Slocs is new Traverse_Proc (Process_Sloc);
3547 ------------------------------
3548 -- Reset_Dispatching_Calls --
3549 ------------------------------
3551 procedure Reset_Dispatching_Calls (N : Node_Id) is
3553 function Do_Reset (N : Node_Id) return Traverse_Result;
3555 --------------
3556 -- Do_Reset --
3557 --------------
3559 function Do_Reset (N : Node_Id) return Traverse_Result is
3560 begin
3561 if Nkind (N) = N_Procedure_Call_Statement
3562 and then Nkind (Name (N)) = N_Selected_Component
3563 and then Nkind (Prefix (Name (N))) = N_Identifier
3564 and then Is_Formal (Entity (Prefix (Name (N))))
3565 and then Is_Dispatching_Operation
3566 (Entity (Selector_Name (Name (N))))
3567 then
3568 Set_Entity (Selector_Name (Name (N)), Empty);
3569 end if;
3571 return OK;
3572 end Do_Reset;
3574 procedure Do_Reset_Calls is new Traverse_Proc (Do_Reset);
3576 begin
3577 Do_Reset_Calls (N);
3578 end Reset_Dispatching_Calls;
3580 ---------------------------
3581 -- Rewrite_Function_Call --
3582 ---------------------------
3584 procedure Rewrite_Function_Call (N : Node_Id; Blk : Node_Id) is
3585 HSS : constant Node_Id := Handled_Statement_Sequence (Blk);
3586 Fst : constant Node_Id := First (Statements (HSS));
3588 begin
3589 Make_Loop_Labels_Unique (HSS);
3591 -- Optimize simple case: function body is a single return statement,
3592 -- which has been expanded into an assignment.
3594 if Is_Empty_List (Declarations (Blk))
3595 and then Nkind (Fst) = N_Assignment_Statement
3596 and then No (Next (Fst))
3597 then
3598 -- The function call may have been rewritten as the temporary
3599 -- that holds the result of the call, in which case remove the
3600 -- now useless declaration.
3602 if Nkind (N) = N_Identifier
3603 and then Nkind (Parent (Entity (N))) = N_Object_Declaration
3604 then
3605 Rewrite (Parent (Entity (N)), Make_Null_Statement (Loc));
3606 end if;
3608 Rewrite (N, Expression (Fst));
3610 elsif Nkind (N) = N_Identifier
3611 and then Nkind (Parent (Entity (N))) = N_Object_Declaration
3612 then
3613 -- The block assigns the result of the call to the temporary
3615 Insert_After (Parent (Entity (N)), Blk);
3617 -- If the context is an assignment, and the left-hand side is free of
3618 -- side-effects, the replacement is also safe.
3620 elsif Nkind (Parent (N)) = N_Assignment_Statement
3621 and then
3622 (Is_Entity_Name (Name (Parent (N)))
3623 or else
3624 (Nkind (Name (Parent (N))) = N_Explicit_Dereference
3625 and then Is_Entity_Name (Prefix (Name (Parent (N)))))
3627 or else
3628 (Nkind (Name (Parent (N))) = N_Selected_Component
3629 and then Is_Entity_Name (Prefix (Name (Parent (N))))))
3630 then
3631 -- Replace assignment with the block
3633 declare
3634 Original_Assignment : constant Node_Id := Parent (N);
3636 begin
3637 -- Preserve the original assignment node to keep the complete
3638 -- assignment subtree consistent enough for Analyze_Assignment
3639 -- to proceed (specifically, the original Lhs node must still
3640 -- have an assignment statement as its parent).
3642 -- We cannot rely on Original_Node to go back from the block
3643 -- node to the assignment node, because the assignment might
3644 -- already be a rewrite substitution.
3646 Discard_Node (Relocate_Node (Original_Assignment));
3647 Rewrite (Original_Assignment, Blk);
3648 end;
3650 elsif Nkind (Parent (N)) = N_Object_Declaration then
3652 -- A call to a function which returns an unconstrained type
3653 -- found in the expression initializing an object-declaration is
3654 -- expanded into a procedure call which must be added after the
3655 -- object declaration.
3657 if Is_Unc_Decl and Back_End_Inlining then
3658 Insert_Action_After (Parent (N), Blk);
3659 else
3660 Set_Expression (Parent (N), Empty);
3661 Insert_After (Parent (N), Blk);
3662 end if;
3664 elsif Is_Unc and then not Back_End_Inlining then
3665 Insert_Before (Parent (N), Blk);
3666 end if;
3667 end Rewrite_Function_Call;
3669 ----------------------------
3670 -- Rewrite_Procedure_Call --
3671 ----------------------------
3673 procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id) is
3674 HSS : constant Node_Id := Handled_Statement_Sequence (Blk);
3676 begin
3677 Make_Loop_Labels_Unique (HSS);
3679 -- If there is a transient scope for N, this will be the scope of the
3680 -- actions for N, and the statements in Blk need to be within this
3681 -- scope. For example, they need to have visibility on the constant
3682 -- declarations created for the formals.
3684 -- If N needs no transient scope, and if there are no declarations in
3685 -- the inlined body, we can do a little optimization and insert the
3686 -- statements for the body directly after N, and rewrite N to a
3687 -- null statement, instead of rewriting N into a full-blown block
3688 -- statement.
3690 if not Scope_Is_Transient
3691 and then Is_Empty_List (Declarations (Blk))
3692 then
3693 Insert_List_After (N, Statements (HSS));
3694 Rewrite (N, Make_Null_Statement (Loc));
3695 else
3696 Rewrite (N, Blk);
3697 end if;
3698 end Rewrite_Procedure_Call;
3700 -- Start of processing for Expand_Inlined_Call
3702 begin
3703 -- Initializations for old/new semantics
3705 if not Uses_Back_End then
3706 Is_Unc := Is_Array_Type (Etype (Subp))
3707 and then not Is_Constrained (Etype (Subp));
3708 Is_Unc_Decl := False;
3709 else
3710 Is_Unc := Returns_Unconstrained_Type (Subp)
3711 and then Optimization_Level > 0;
3712 Is_Unc_Decl := Nkind (Parent (N)) = N_Object_Declaration
3713 and then Is_Unc;
3714 end if;
3716 -- Check for an illegal attempt to inline a recursive procedure. If the
3717 -- subprogram has parameters this is detected when trying to supply a
3718 -- binding for parameters that already have one. For parameterless
3719 -- subprograms this must be done explicitly.
3721 if In_Open_Scopes (Subp) then
3722 Cannot_Inline
3723 ("cannot inline call to recursive subprogram?", N, Subp);
3724 Set_Is_Inlined (Subp, False);
3725 return;
3727 -- Skip inlining if this is not a true inlining since the attribute
3728 -- Body_To_Inline is also set for renamings (see sinfo.ads). For a
3729 -- true inlining, Orig_Bod has code rather than being an entity.
3731 elsif Nkind (Orig_Bod) in N_Entity then
3732 return;
3733 end if;
3735 if Nkind (Orig_Bod) in N_Defining_Identifier
3736 | N_Defining_Operator_Symbol
3737 then
3738 -- Subprogram is renaming_as_body. Calls occurring after the renaming
3739 -- can be replaced with calls to the renamed entity directly, because
3740 -- the subprograms are subtype conformant. If the renamed subprogram
3741 -- is an inherited operation, we must redo the expansion because
3742 -- implicit conversions may be needed. Similarly, if the renamed
3743 -- entity is inlined, expand the call for further optimizations.
3745 Set_Name (N, New_Occurrence_Of (Orig_Bod, Loc));
3747 if Present (Alias (Orig_Bod)) or else Is_Inlined (Orig_Bod) then
3748 Expand_Call (N);
3749 end if;
3751 return;
3752 end if;
3754 -- Register the call in the list of inlined calls
3756 Append_New_Elmt (N, To => Inlined_Calls);
3758 -- Use generic machinery to copy body of inlined subprogram, as if it
3759 -- were an instantiation, resetting source locations appropriately, so
3760 -- that nested inlined calls appear in the main unit.
3762 Save_Env (Subp, Empty);
3763 Set_Copied_Sloc_For_Inlined_Body (N, Defining_Entity (Orig_Bod));
3765 -- Old semantics
3767 if not Uses_Back_End then
3768 declare
3769 Bod : Node_Id;
3771 begin
3772 Bod := Copy_Generic_Node (Orig_Bod, Empty, Instantiating => True);
3773 Blk :=
3774 Make_Block_Statement (Loc,
3775 Declarations => Declarations (Bod),
3776 Handled_Statement_Sequence =>
3777 Handled_Statement_Sequence (Bod));
3779 if No (Declarations (Bod)) then
3780 Set_Declarations (Blk, New_List);
3781 end if;
3783 -- When generating C code, declare _Result, which may be used to
3784 -- verify the return value.
3786 if Modify_Tree_For_C
3787 and then Nkind (N) = N_Procedure_Call_Statement
3788 and then Chars (Name (N)) = Name_uPostconditions
3789 then
3790 Declare_Postconditions_Result;
3791 end if;
3793 -- For the unconstrained case, capture the name of the local
3794 -- variable that holds the result. This must be the first
3795 -- declaration in the block, because its bounds cannot depend
3796 -- on local variables. Otherwise there is no way to declare the
3797 -- result outside of the block. Needless to say, in general the
3798 -- bounds will depend on the actuals in the call.
3800 -- If the context is an assignment statement, as is the case
3801 -- for the expansion of an extended return, the left-hand side
3802 -- provides bounds even if the return type is unconstrained.
3804 if Is_Unc then
3805 declare
3806 First_Decl : Node_Id;
3808 begin
3809 First_Decl := First (Declarations (Blk));
3811 -- If the body is a single extended return statement,the
3812 -- resulting block is a nested block.
3814 if No (First_Decl) then
3815 First_Decl :=
3816 First (Statements (Handled_Statement_Sequence (Blk)));
3818 if Nkind (First_Decl) = N_Block_Statement then
3819 First_Decl := First (Declarations (First_Decl));
3820 end if;
3821 end if;
3823 -- No front-end inlining possible
3825 if Nkind (First_Decl) /= N_Object_Declaration then
3826 return;
3827 end if;
3829 if Nkind (Parent (N)) /= N_Assignment_Statement then
3830 Targ1 := Defining_Identifier (First_Decl);
3831 else
3832 Targ1 := Name (Parent (N));
3833 end if;
3834 end;
3835 end if;
3836 end;
3838 -- New semantics
3840 else
3841 declare
3842 Bod : Node_Id;
3844 begin
3845 -- General case
3847 if not Is_Unc then
3848 Bod :=
3849 Copy_Generic_Node (Orig_Bod, Empty, Instantiating => True);
3850 Blk :=
3851 Make_Block_Statement (Loc,
3852 Declarations => Declarations (Bod),
3853 Handled_Statement_Sequence =>
3854 Handled_Statement_Sequence (Bod));
3856 -- Inline a call to a function that returns an unconstrained type.
3857 -- The semantic analyzer checked that frontend-inlined functions
3858 -- returning unconstrained types have no declarations and have
3859 -- a single extended return statement. As part of its processing
3860 -- the function was split into two subprograms: a procedure P' and
3861 -- a function F' that has a block with a call to procedure P' (see
3862 -- Split_Unconstrained_Function).
3864 else
3865 pragma Assert
3866 (Nkind
3867 (First
3868 (Statements (Handled_Statement_Sequence (Orig_Bod)))) =
3869 N_Block_Statement);
3871 declare
3872 Blk_Stmt : constant Node_Id :=
3873 First (Statements (Handled_Statement_Sequence (Orig_Bod)));
3874 First_Stmt : constant Node_Id :=
3875 First (Statements (Handled_Statement_Sequence (Blk_Stmt)));
3876 Second_Stmt : constant Node_Id := Next (First_Stmt);
3878 begin
3879 pragma Assert
3880 (Nkind (First_Stmt) = N_Procedure_Call_Statement
3881 and then Nkind (Second_Stmt) = N_Simple_Return_Statement
3882 and then No (Next (Second_Stmt)));
3884 Bod :=
3885 Copy_Generic_Node
3886 (First
3887 (Statements (Handled_Statement_Sequence (Orig_Bod))),
3888 Empty, Instantiating => True);
3889 Blk := Bod;
3891 -- Capture the name of the local variable that holds the
3892 -- result. This must be the first declaration in the block,
3893 -- because its bounds cannot depend on local variables.
3894 -- Otherwise there is no way to declare the result outside
3895 -- of the block. Needless to say, in general the bounds will
3896 -- depend on the actuals in the call.
3898 if Nkind (Parent (N)) /= N_Assignment_Statement then
3899 Targ1 := Defining_Identifier (First (Declarations (Blk)));
3901 -- If the context is an assignment statement, as is the case
3902 -- for the expansion of an extended return, the left-hand
3903 -- side provides bounds even if the return type is
3904 -- unconstrained.
3906 else
3907 Targ1 := Name (Parent (N));
3908 end if;
3909 end;
3910 end if;
3912 if No (Declarations (Bod)) then
3913 Set_Declarations (Blk, New_List);
3914 end if;
3915 end;
3916 end if;
3918 -- If this is a derived function, establish the proper return type
3920 if Present (Orig_Subp) and then Orig_Subp /= Subp then
3921 Ret_Type := Etype (Orig_Subp);
3922 else
3923 Ret_Type := Etype (Subp);
3924 end if;
3926 -- Create temporaries for the actuals that are expressions, or that are
3927 -- scalars and require copying to preserve semantics.
3929 Establish_Actual_Mapping_For_Inlined_Call (N, Subp, Decls, Orig_Bod);
3931 -- Establish target of function call. If context is not assignment or
3932 -- declaration, create a temporary as a target. The declaration for the
3933 -- temporary may be subsequently optimized away if the body is a single
3934 -- expression, or if the left-hand side of the assignment is simple
3935 -- enough, i.e. an entity or an explicit dereference of one.
3937 if Ekind (Subp) = E_Function then
3938 if Nkind (Parent (N)) = N_Assignment_Statement
3939 and then Is_Entity_Name (Name (Parent (N)))
3940 then
3941 Targ := Name (Parent (N));
3943 elsif Nkind (Parent (N)) = N_Assignment_Statement
3944 and then Nkind (Name (Parent (N))) = N_Explicit_Dereference
3945 and then Is_Entity_Name (Prefix (Name (Parent (N))))
3946 then
3947 Targ := Name (Parent (N));
3949 elsif Nkind (Parent (N)) = N_Assignment_Statement
3950 and then Nkind (Name (Parent (N))) = N_Selected_Component
3951 and then Is_Entity_Name (Prefix (Name (Parent (N))))
3952 then
3953 Targ := New_Copy_Tree (Name (Parent (N)));
3955 elsif Nkind (Parent (N)) = N_Object_Declaration
3956 and then Is_Limited_Type (Etype (Subp))
3957 then
3958 Targ := Defining_Identifier (Parent (N));
3960 -- New semantics: In an object declaration avoid an extra copy
3961 -- of the result of a call to an inlined function that returns
3962 -- an unconstrained type
3964 elsif Uses_Back_End
3965 and then Nkind (Parent (N)) = N_Object_Declaration
3966 and then Is_Unc
3967 then
3968 Targ := Defining_Identifier (Parent (N));
3970 else
3971 -- Replace call with temporary and create its declaration
3973 Temp := Make_Temporary (Loc, 'C');
3974 Set_Is_Internal (Temp);
3976 -- For the unconstrained case, the generated temporary has the
3977 -- same constrained declaration as the result variable. It may
3978 -- eventually be possible to remove that temporary and use the
3979 -- result variable directly.
3981 if Is_Unc and then Nkind (Parent (N)) /= N_Assignment_Statement
3982 then
3983 Decl :=
3984 Make_Object_Declaration (Loc,
3985 Defining_Identifier => Temp,
3986 Object_Definition =>
3987 New_Copy_Tree (Object_Definition (Parent (Targ1))));
3989 Replace_Formals (Decl);
3991 else
3992 Decl :=
3993 Make_Object_Declaration (Loc,
3994 Defining_Identifier => Temp,
3995 Object_Definition => New_Occurrence_Of (Ret_Type, Loc));
3997 Set_Etype (Temp, Ret_Type);
3998 end if;
4000 Set_No_Initialization (Decl);
4001 Append (Decl, Decls);
4002 Rewrite (N, New_Occurrence_Of (Temp, Loc));
4003 Targ := Temp;
4004 end if;
4005 end if;
4007 Insert_Actions (N, Decls);
4009 if Is_Unc_Decl then
4011 -- Special management for inlining a call to a function that returns
4012 -- an unconstrained type and initializes an object declaration: we
4013 -- avoid generating undesired extra calls and goto statements.
4015 -- Given:
4016 -- function Func (...) return String is
4017 -- begin
4018 -- declare
4019 -- Result : String (1 .. 4);
4020 -- begin
4021 -- Proc (Result, ...);
4022 -- return Result;
4023 -- end;
4024 -- end Func;
4026 -- Result : String := Func (...);
4028 -- Replace this object declaration by:
4030 -- Result : String (1 .. 4);
4031 -- Proc (Result, ...);
4033 Remove_Homonym (Targ);
4035 Decl :=
4036 Make_Object_Declaration
4037 (Loc,
4038 Defining_Identifier => Targ,
4039 Object_Definition =>
4040 New_Copy_Tree (Object_Definition (Parent (Targ1))));
4041 Replace_Formals (Decl);
4042 Rewrite (Parent (N), Decl);
4043 Analyze (Parent (N));
4045 -- Avoid spurious warnings since we know that this declaration is
4046 -- referenced by the procedure call.
4048 Set_Never_Set_In_Source (Targ, False);
4050 -- Remove the local declaration of the extended return stmt from the
4051 -- inlined code
4053 Remove (Parent (Targ1));
4055 -- Update the reference to the result (since we have rewriten the
4056 -- object declaration)
4058 declare
4059 Blk_Call_Stmt : Node_Id;
4061 begin
4062 -- Capture the call to the procedure
4064 Blk_Call_Stmt :=
4065 First (Statements (Handled_Statement_Sequence (Blk)));
4066 pragma Assert
4067 (Nkind (Blk_Call_Stmt) = N_Procedure_Call_Statement);
4069 Remove (First (Parameter_Associations (Blk_Call_Stmt)));
4070 Prepend_To (Parameter_Associations (Blk_Call_Stmt),
4071 New_Occurrence_Of (Targ, Loc));
4072 end;
4074 -- Remove the return statement
4076 pragma Assert
4077 (Nkind (Last (Statements (Handled_Statement_Sequence (Blk)))) =
4078 N_Simple_Return_Statement);
4080 Remove (Last (Statements (Handled_Statement_Sequence (Blk))));
4081 end if;
4083 -- Traverse the tree and replace formals with actuals or their thunks.
4084 -- Attach block to tree before analysis and rewriting.
4086 Replace_Formals (Blk);
4087 Replace_Formals_In_Aspects (Blk);
4088 Set_Parent (Blk, N);
4090 if GNATprove_Mode then
4091 null;
4093 elsif not Comes_From_Source (Subp) or else Is_Predef then
4094 Reset_Slocs (Blk);
4095 end if;
4097 if Is_Unc_Decl then
4099 -- No action needed since return statement has been already removed
4101 null;
4103 elsif Present (Exit_Lab) then
4105 -- If there's a single return statement at the end of the subprogram,
4106 -- the corresponding goto statement and the corresponding label are
4107 -- useless.
4109 if Num_Ret = 1
4110 and then
4111 Nkind (Last (Statements (Handled_Statement_Sequence (Blk)))) =
4112 N_Goto_Statement
4113 then
4114 Remove (Last (Statements (Handled_Statement_Sequence (Blk))));
4115 else
4116 Append (Lab_Decl, (Declarations (Blk)));
4117 Append (Exit_Lab, Statements (Handled_Statement_Sequence (Blk)));
4118 end if;
4119 end if;
4121 -- Analyze Blk with In_Inlined_Body set, to avoid spurious errors
4122 -- on conflicting private views that Gigi would ignore. If this is a
4123 -- predefined unit, analyze with checks off, as is done in the non-
4124 -- inlined run-time units.
4126 declare
4127 I_Flag : constant Boolean := In_Inlined_Body;
4129 begin
4130 In_Inlined_Body := True;
4132 if Is_Predef then
4133 declare
4134 Style : constant Boolean := Style_Check;
4136 begin
4137 Style_Check := False;
4139 -- Search for dispatching calls that use the Object.Operation
4140 -- notation using an Object that is a parameter of the inlined
4141 -- function. We reset the decoration of Operation to force
4142 -- the reanalysis of the inlined dispatching call because
4143 -- the actual object has been inlined.
4145 Reset_Dispatching_Calls (Blk);
4147 -- In GNATprove mode, always consider checks on, even for
4148 -- predefined units.
4150 if GNATprove_Mode then
4151 Analyze (Blk);
4152 else
4153 Analyze (Blk, Suppress => All_Checks);
4154 end if;
4156 Style_Check := Style;
4157 end;
4159 else
4160 Analyze (Blk);
4161 end if;
4163 In_Inlined_Body := I_Flag;
4164 end;
4166 if Ekind (Subp) = E_Procedure then
4167 Rewrite_Procedure_Call (N, Blk);
4169 else
4170 Rewrite_Function_Call (N, Blk);
4172 if Is_Unc_Decl then
4173 null;
4175 -- For the unconstrained case, the replacement of the call has been
4176 -- made prior to the complete analysis of the generated declarations.
4177 -- Propagate the proper type now.
4179 elsif Is_Unc then
4180 if Nkind (N) = N_Identifier then
4181 Set_Etype (N, Etype (Entity (N)));
4182 else
4183 Set_Etype (N, Etype (Targ1));
4184 end if;
4185 end if;
4186 end if;
4188 Restore_Env;
4190 -- Cleanup mapping between formals and actuals for other expansions
4192 Reset_Actual_Mapping_For_Inlined_Call (Subp);
4193 end Expand_Inlined_Call;
4195 --------------------------
4196 -- Get_Code_Unit_Entity --
4197 --------------------------
4199 function Get_Code_Unit_Entity (E : Entity_Id) return Entity_Id is
4200 Unit : Entity_Id := Cunit_Entity (Get_Code_Unit (E));
4202 begin
4203 if Ekind (Unit) = E_Package_Body then
4204 Unit := Spec_Entity (Unit);
4205 end if;
4207 return Unit;
4208 end Get_Code_Unit_Entity;
4210 ------------------------------
4211 -- Has_Excluded_Declaration --
4212 ------------------------------
4214 function Has_Excluded_Declaration
4215 (Subp : Entity_Id;
4216 Decls : List_Id) return Boolean
4218 function Is_Unchecked_Conversion (D : Node_Id) return Boolean;
4219 -- Nested subprograms make a given body ineligible for inlining, but
4220 -- we make an exception for instantiations of unchecked conversion.
4221 -- The body has not been analyzed yet, so check the name, and verify
4222 -- that the visible entity with that name is the predefined unit.
4224 -----------------------------
4225 -- Is_Unchecked_Conversion --
4226 -----------------------------
4228 function Is_Unchecked_Conversion (D : Node_Id) return Boolean is
4229 Id : constant Node_Id := Name (D);
4230 Conv : Entity_Id;
4232 begin
4233 if Nkind (Id) = N_Identifier
4234 and then Chars (Id) = Name_Unchecked_Conversion
4235 then
4236 Conv := Current_Entity (Id);
4238 elsif Nkind (Id) in N_Selected_Component | N_Expanded_Name
4239 and then Chars (Selector_Name (Id)) = Name_Unchecked_Conversion
4240 then
4241 Conv := Current_Entity (Selector_Name (Id));
4242 else
4243 return False;
4244 end if;
4246 return Present (Conv)
4247 and then Is_Predefined_Unit (Get_Source_Unit (Conv))
4248 and then Is_Intrinsic_Subprogram (Conv);
4249 end Is_Unchecked_Conversion;
4251 -- Local variables
4253 Decl : Node_Id;
4255 -- Start of processing for Has_Excluded_Declaration
4257 begin
4258 -- No action needed if the check is not needed
4260 if not Check_Inlining_Restrictions then
4261 return False;
4262 end if;
4264 Decl := First (Decls);
4265 while Present (Decl) loop
4267 -- First declarations universally excluded
4269 if Nkind (Decl) = N_Package_Declaration then
4270 Cannot_Inline
4271 ("cannot inline & (nested package declaration)?", Decl, Subp);
4272 return True;
4274 elsif Nkind (Decl) = N_Package_Instantiation then
4275 Cannot_Inline
4276 ("cannot inline & (nested package instantiation)?", Decl, Subp);
4277 return True;
4278 end if;
4280 -- Then declarations excluded only for front-end inlining
4282 if Back_End_Inlining then
4283 null;
4285 elsif Nkind (Decl) = N_Task_Type_Declaration
4286 or else Nkind (Decl) = N_Single_Task_Declaration
4287 then
4288 Cannot_Inline
4289 ("cannot inline & (nested task type declaration)?", Decl, Subp);
4290 return True;
4292 elsif Nkind (Decl) in N_Protected_Type_Declaration
4293 | N_Single_Protected_Declaration
4294 then
4295 Cannot_Inline
4296 ("cannot inline & (nested protected type declaration)?",
4297 Decl, Subp);
4298 return True;
4300 elsif Nkind (Decl) = N_Subprogram_Body then
4301 Cannot_Inline
4302 ("cannot inline & (nested subprogram)?", Decl, Subp);
4303 return True;
4305 elsif Nkind (Decl) = N_Function_Instantiation
4306 and then not Is_Unchecked_Conversion (Decl)
4307 then
4308 Cannot_Inline
4309 ("cannot inline & (nested function instantiation)?", Decl, Subp);
4310 return True;
4312 elsif Nkind (Decl) = N_Procedure_Instantiation then
4313 Cannot_Inline
4314 ("cannot inline & (nested procedure instantiation)?",
4315 Decl, Subp);
4316 return True;
4318 -- Subtype declarations with predicates will generate predicate
4319 -- functions, i.e. nested subprogram bodies, so inlining is not
4320 -- possible.
4322 elsif Nkind (Decl) = N_Subtype_Declaration then
4323 declare
4324 A : Node_Id;
4325 A_Id : Aspect_Id;
4327 begin
4328 A := First (Aspect_Specifications (Decl));
4329 while Present (A) loop
4330 A_Id := Get_Aspect_Id (Chars (Identifier (A)));
4332 if A_Id = Aspect_Predicate
4333 or else A_Id = Aspect_Static_Predicate
4334 or else A_Id = Aspect_Dynamic_Predicate
4335 then
4336 Cannot_Inline
4337 ("cannot inline & (subtype declaration with "
4338 & "predicate)?", Decl, Subp);
4339 return True;
4340 end if;
4342 Next (A);
4343 end loop;
4344 end;
4345 end if;
4347 Next (Decl);
4348 end loop;
4350 return False;
4351 end Has_Excluded_Declaration;
4353 ----------------------------
4354 -- Has_Excluded_Statement --
4355 ----------------------------
4357 function Has_Excluded_Statement
4358 (Subp : Entity_Id;
4359 Stats : List_Id) return Boolean
4361 S : Node_Id;
4362 E : Node_Id;
4364 begin
4365 -- No action needed if the check is not needed
4367 if not Check_Inlining_Restrictions then
4368 return False;
4369 end if;
4371 S := First (Stats);
4372 while Present (S) loop
4373 if Nkind (S) in N_Abort_Statement
4374 | N_Asynchronous_Select
4375 | N_Conditional_Entry_Call
4376 | N_Delay_Relative_Statement
4377 | N_Delay_Until_Statement
4378 | N_Selective_Accept
4379 | N_Timed_Entry_Call
4380 then
4381 Cannot_Inline
4382 ("cannot inline & (non-allowed statement)?", S, Subp);
4383 return True;
4385 elsif Nkind (S) = N_Block_Statement then
4386 if Present (Declarations (S))
4387 and then Has_Excluded_Declaration (Subp, Declarations (S))
4388 then
4389 return True;
4391 elsif Present (Handled_Statement_Sequence (S)) then
4392 if not Back_End_Inlining
4393 and then
4394 Present
4395 (Exception_Handlers (Handled_Statement_Sequence (S)))
4396 then
4397 Cannot_Inline
4398 ("cannot inline& (exception handler)?",
4399 First (Exception_Handlers
4400 (Handled_Statement_Sequence (S))),
4401 Subp);
4402 return True;
4404 elsif Has_Excluded_Statement
4405 (Subp, Statements (Handled_Statement_Sequence (S)))
4406 then
4407 return True;
4408 end if;
4409 end if;
4411 elsif Nkind (S) = N_Case_Statement then
4412 E := First (Alternatives (S));
4413 while Present (E) loop
4414 if Has_Excluded_Statement (Subp, Statements (E)) then
4415 return True;
4416 end if;
4418 Next (E);
4419 end loop;
4421 elsif Nkind (S) = N_If_Statement then
4422 if Has_Excluded_Statement (Subp, Then_Statements (S)) then
4423 return True;
4424 end if;
4426 if Present (Elsif_Parts (S)) then
4427 E := First (Elsif_Parts (S));
4428 while Present (E) loop
4429 if Has_Excluded_Statement (Subp, Then_Statements (E)) then
4430 return True;
4431 end if;
4433 Next (E);
4434 end loop;
4435 end if;
4437 if Present (Else_Statements (S))
4438 and then Has_Excluded_Statement (Subp, Else_Statements (S))
4439 then
4440 return True;
4441 end if;
4443 elsif Nkind (S) = N_Loop_Statement
4444 and then Has_Excluded_Statement (Subp, Statements (S))
4445 then
4446 return True;
4448 elsif Nkind (S) = N_Extended_Return_Statement then
4449 if Present (Handled_Statement_Sequence (S))
4450 and then
4451 Has_Excluded_Statement
4452 (Subp, Statements (Handled_Statement_Sequence (S)))
4453 then
4454 return True;
4456 elsif not Back_End_Inlining
4457 and then Present (Handled_Statement_Sequence (S))
4458 and then
4459 Present (Exception_Handlers
4460 (Handled_Statement_Sequence (S)))
4461 then
4462 Cannot_Inline
4463 ("cannot inline& (exception handler)?",
4464 First (Exception_Handlers (Handled_Statement_Sequence (S))),
4465 Subp);
4466 return True;
4467 end if;
4468 end if;
4470 Next (S);
4471 end loop;
4473 return False;
4474 end Has_Excluded_Statement;
4476 --------------------------
4477 -- Has_Initialized_Type --
4478 --------------------------
4480 function Has_Initialized_Type (E : Entity_Id) return Boolean is
4481 E_Body : constant Node_Id := Subprogram_Body (E);
4482 Decl : Node_Id;
4484 begin
4485 if No (E_Body) then -- imported subprogram
4486 return False;
4488 else
4489 Decl := First (Declarations (E_Body));
4490 while Present (Decl) loop
4491 if Nkind (Decl) = N_Full_Type_Declaration
4492 and then Present (Init_Proc (Defining_Identifier (Decl)))
4493 then
4494 return True;
4495 end if;
4497 Next (Decl);
4498 end loop;
4499 end if;
4501 return False;
4502 end Has_Initialized_Type;
4504 -----------------------
4505 -- Has_Single_Return --
4506 -----------------------
4508 function Has_Single_Return (N : Node_Id) return Boolean is
4509 Return_Statement : Node_Id := Empty;
4511 function Check_Return (N : Node_Id) return Traverse_Result;
4513 ------------------
4514 -- Check_Return --
4515 ------------------
4517 function Check_Return (N : Node_Id) return Traverse_Result is
4518 begin
4519 if Nkind (N) = N_Simple_Return_Statement then
4520 if Present (Expression (N))
4521 and then Is_Entity_Name (Expression (N))
4522 then
4523 pragma Assert (Present (Entity (Expression (N))));
4525 if No (Return_Statement) then
4526 Return_Statement := N;
4527 return OK;
4529 else
4530 pragma Assert
4531 (Present (Entity (Expression (Return_Statement))));
4533 if Entity (Expression (N)) =
4534 Entity (Expression (Return_Statement))
4535 then
4536 return OK;
4537 else
4538 return Abandon;
4539 end if;
4540 end if;
4542 -- A return statement within an extended return is a noop after
4543 -- inlining.
4545 elsif No (Expression (N))
4546 and then Nkind (Parent (Parent (N))) =
4547 N_Extended_Return_Statement
4548 then
4549 return OK;
4551 else
4552 -- Expression has wrong form
4554 return Abandon;
4555 end if;
4557 -- We can only inline a build-in-place function if it has a single
4558 -- extended return.
4560 elsif Nkind (N) = N_Extended_Return_Statement then
4561 if No (Return_Statement) then
4562 Return_Statement := N;
4563 return OK;
4565 else
4566 return Abandon;
4567 end if;
4569 else
4570 return OK;
4571 end if;
4572 end Check_Return;
4574 function Check_All_Returns is new Traverse_Func (Check_Return);
4576 -- Start of processing for Has_Single_Return
4578 begin
4579 if Check_All_Returns (N) /= OK then
4580 return False;
4582 elsif Nkind (Return_Statement) = N_Extended_Return_Statement then
4583 return True;
4585 else
4586 return
4587 Present (Declarations (N))
4588 and then Present (First (Declarations (N)))
4589 and then Entity (Expression (Return_Statement)) =
4590 Defining_Identifier (First (Declarations (N)));
4591 end if;
4592 end Has_Single_Return;
4594 -----------------------------
4595 -- In_Main_Unit_Or_Subunit --
4596 -----------------------------
4598 function In_Main_Unit_Or_Subunit (E : Entity_Id) return Boolean is
4599 Comp : Node_Id := Cunit (Get_Code_Unit (E));
4601 begin
4602 -- Check whether the subprogram or package to inline is within the main
4603 -- unit or its spec or within a subunit. In either case there are no
4604 -- additional bodies to process. If the subprogram appears in a parent
4605 -- of the current unit, the check on whether inlining is possible is
4606 -- done in Analyze_Inlined_Bodies.
4608 while Nkind (Unit (Comp)) = N_Subunit loop
4609 Comp := Library_Unit (Comp);
4610 end loop;
4612 return Comp = Cunit (Main_Unit)
4613 or else Comp = Library_Unit (Cunit (Main_Unit));
4614 end In_Main_Unit_Or_Subunit;
4616 ----------------
4617 -- Initialize --
4618 ----------------
4620 procedure Initialize is
4621 begin
4622 Pending_Instantiations.Init;
4623 Called_Pending_Instantiations.Init;
4624 Inlined_Bodies.Init;
4625 Successors.Init;
4626 Inlined.Init;
4628 for J in Hash_Headers'Range loop
4629 Hash_Headers (J) := No_Subp;
4630 end loop;
4632 Inlined_Calls := No_Elist;
4633 Backend_Calls := No_Elist;
4634 Backend_Instances := No_Elist;
4635 Backend_Inlined_Subps := No_Elist;
4636 Backend_Not_Inlined_Subps := No_Elist;
4637 end Initialize;
4639 ---------------------------------
4640 -- Inline_Static_Function_Call --
4641 ---------------------------------
4643 procedure Inline_Static_Function_Call (N : Node_Id; Subp : Entity_Id) is
4645 function Replace_Formal (N : Node_Id) return Traverse_Result;
4646 -- Replace each occurrence of a formal with the corresponding actual,
4647 -- using the mapping created by Establish_Mapping_For_Inlined_Call.
4649 function Reset_Sloc (Nod : Node_Id) return Traverse_Result;
4650 -- Reset the Sloc of a node to that of the call itself, so that errors
4651 -- will be flagged on the call to the static expression function itself
4652 -- rather than on the expression of the function's declaration.
4654 --------------------
4655 -- Replace_Formal --
4656 --------------------
4658 function Replace_Formal (N : Node_Id) return Traverse_Result is
4659 A : Entity_Id;
4660 E : Entity_Id;
4662 begin
4663 if Is_Entity_Name (N) and then Present (Entity (N)) then
4664 E := Entity (N);
4666 if Is_Formal (E) and then Scope (E) = Subp then
4667 A := Renamed_Object (E);
4669 if Nkind (A) = N_Defining_Identifier then
4670 Rewrite (N, New_Occurrence_Of (A, Sloc (N)));
4672 -- Literal cases
4674 else
4675 Rewrite (N, New_Copy (A));
4676 end if;
4677 end if;
4679 return Skip;
4681 else
4682 return OK;
4683 end if;
4684 end Replace_Formal;
4686 procedure Replace_Formals is new Traverse_Proc (Replace_Formal);
4688 ------------------
4689 -- Process_Sloc --
4690 ------------------
4692 function Reset_Sloc (Nod : Node_Id) return Traverse_Result is
4693 begin
4694 Set_Sloc (Nod, Sloc (N));
4695 Set_Comes_From_Source (Nod, False);
4697 return OK;
4698 end Reset_Sloc;
4700 procedure Reset_Slocs is new Traverse_Proc (Reset_Sloc);
4702 -- Start of processing for Inline_Static_Function_Call
4704 begin
4705 pragma Assert (Is_Static_Function_Call (N));
4707 declare
4708 Decls : constant List_Id := New_List;
4709 Func_Expr : constant Node_Id :=
4710 Expression_Of_Expression_Function (Subp);
4711 Expr_Copy : constant Node_Id := New_Copy_Tree (Func_Expr);
4713 begin
4714 -- Create a mapping from formals to actuals, also creating temps in
4715 -- Decls, when needed, to hold the actuals.
4717 Establish_Actual_Mapping_For_Inlined_Call (N, Subp, Decls, Func_Expr);
4719 -- Ensure that the copy has the same parent as the call (this seems
4720 -- to matter when GNATprove_Mode is set and there are nested static
4721 -- calls; prevents blowups in Insert_Actions, though it's not clear
4722 -- exactly why this is needed???).
4724 Set_Parent (Expr_Copy, Parent (N));
4726 Insert_Actions (N, Decls);
4728 -- Now substitute actuals for their corresponding formal references
4729 -- within the expression.
4731 Replace_Formals (Expr_Copy);
4733 Reset_Slocs (Expr_Copy);
4735 -- Apply a qualified expression with the function's result subtype,
4736 -- to ensure that we check the expression against any constraint
4737 -- or predicate, which will cause the call to be illegal if the
4738 -- folded expression doesn't satisfy them. (The predicate case
4739 -- might not get checked if the subtype hasn't been frozen yet,
4740 -- which can happen if this static expression happens to be what
4741 -- causes the freezing, because Has_Static_Predicate doesn't get
4742 -- set on the subtype until it's frozen and Build_Predicates is
4743 -- called. It's not clear how to address this case. ???)
4745 Rewrite (Expr_Copy,
4746 Make_Qualified_Expression (Sloc (Expr_Copy),
4747 Subtype_Mark =>
4748 New_Occurrence_Of (Etype (N), Sloc (Expr_Copy)),
4749 Expression =>
4750 Relocate_Node (Expr_Copy)));
4752 Set_Etype (Expr_Copy, Etype (N));
4754 Analyze_And_Resolve (Expr_Copy, Etype (N));
4756 -- Finally rewrite the function call as the folded static result
4758 Rewrite (N, Expr_Copy);
4760 -- Cleanup mapping between formals and actuals for other expansions
4762 Reset_Actual_Mapping_For_Inlined_Call (Subp);
4763 end;
4764 end Inline_Static_Function_Call;
4766 ------------------------
4767 -- Instantiate_Bodies --
4768 ------------------------
4770 -- Generic bodies contain all the non-local references, so an
4771 -- instantiation does not need any more context than Standard
4772 -- itself, even if the instantiation appears in an inner scope.
4773 -- Generic associations have verified that the contract model is
4774 -- satisfied, so that any error that may occur in the analysis of
4775 -- the body is an internal error.
4777 procedure Instantiate_Bodies is
4779 procedure Instantiate_Body (Info : Pending_Body_Info);
4780 -- Instantiate a pending body
4782 ------------------------
4783 -- Instantiate_Body --
4784 ------------------------
4786 procedure Instantiate_Body (Info : Pending_Body_Info) is
4787 begin
4788 -- If the instantiation node is absent, it has been removed as part
4789 -- of unreachable code.
4791 if No (Info.Inst_Node) then
4792 null;
4794 -- If the instantiation node is a package body, this means that the
4795 -- instance is a compilation unit and the instantiation has already
4796 -- been performed by Build_Instance_Compilation_Unit_Nodes.
4798 elsif Nkind (Info.Inst_Node) = N_Package_Body then
4799 null;
4801 elsif Nkind (Info.Act_Decl) = N_Package_Declaration then
4802 Instantiate_Package_Body (Info);
4803 Add_Scope_To_Clean (Defining_Entity (Info.Act_Decl));
4805 else
4806 Instantiate_Subprogram_Body (Info);
4807 end if;
4808 end Instantiate_Body;
4810 J, K : Nat;
4811 Info : Pending_Body_Info;
4813 -- Start of processing for Instantiate_Bodies
4815 begin
4816 if Serious_Errors_Detected = 0 then
4817 Expander_Active := (Operating_Mode = Opt.Generate_Code);
4818 Push_Scope (Standard_Standard);
4819 To_Clean := New_Elmt_List;
4821 if Is_Generic_Unit (Cunit_Entity (Main_Unit)) then
4822 Start_Generic;
4823 end if;
4825 -- A body instantiation may generate additional instantiations, so
4826 -- the following loop must scan to the end of a possibly expanding
4827 -- set (that's why we cannot simply use a FOR loop here). We must
4828 -- also capture the element lest the set be entirely reallocated.
4830 J := 0;
4831 if Back_End_Inlining then
4832 while J <= Called_Pending_Instantiations.Last
4833 and then Serious_Errors_Detected = 0
4834 loop
4835 K := Called_Pending_Instantiations.Table (J);
4836 Info := Pending_Instantiations.Table (K);
4837 Instantiate_Body (Info);
4839 J := J + 1;
4840 end loop;
4842 else
4843 while J <= Pending_Instantiations.Last
4844 and then Serious_Errors_Detected = 0
4845 loop
4846 Info := Pending_Instantiations.Table (J);
4847 Instantiate_Body (Info);
4849 J := J + 1;
4850 end loop;
4851 end if;
4853 -- Reset the table of instantiations. Additional instantiations
4854 -- may be added through inlining, when additional bodies are
4855 -- analyzed.
4857 if Back_End_Inlining then
4858 Called_Pending_Instantiations.Init;
4859 else
4860 Pending_Instantiations.Init;
4861 end if;
4863 -- We can now complete the cleanup actions of scopes that contain
4864 -- pending instantiations (skipped for generic units, since we
4865 -- never need any cleanups in generic units).
4867 if Expander_Active
4868 and then not Is_Generic_Unit (Main_Unit_Entity)
4869 then
4870 Cleanup_Scopes;
4871 elsif Is_Generic_Unit (Cunit_Entity (Main_Unit)) then
4872 End_Generic;
4873 end if;
4875 Pop_Scope;
4876 end if;
4877 end Instantiate_Bodies;
4879 ---------------
4880 -- Is_Nested --
4881 ---------------
4883 function Is_Nested (E : Entity_Id) return Boolean is
4884 Scop : Entity_Id;
4886 begin
4887 Scop := Scope (E);
4888 while Scop /= Standard_Standard loop
4889 if Is_Subprogram (Scop) then
4890 return True;
4892 elsif Ekind (Scop) = E_Task_Type
4893 or else Ekind (Scop) = E_Entry
4894 or else Ekind (Scop) = E_Entry_Family
4895 then
4896 return True;
4897 end if;
4899 Scop := Scope (Scop);
4900 end loop;
4902 return False;
4903 end Is_Nested;
4905 ------------------------
4906 -- List_Inlining_Info --
4907 ------------------------
4909 procedure List_Inlining_Info is
4910 Elmt : Elmt_Id;
4911 Nod : Node_Id;
4912 Count : Nat;
4914 begin
4915 if not Debug_Flag_Dot_J then
4916 return;
4917 end if;
4919 -- Generate listing of calls inlined by the frontend
4921 if Present (Inlined_Calls) then
4922 Count := 0;
4923 Elmt := First_Elmt (Inlined_Calls);
4924 while Present (Elmt) loop
4925 Nod := Node (Elmt);
4927 if not In_Internal_Unit (Nod) then
4928 Count := Count + 1;
4930 if Count = 1 then
4931 Write_Str ("List of calls inlined by the frontend");
4932 Write_Eol;
4933 end if;
4935 Write_Str (" ");
4936 Write_Int (Count);
4937 Write_Str (":");
4938 Write_Location (Sloc (Nod));
4939 Write_Str (":");
4940 Output.Write_Eol;
4941 end if;
4943 Next_Elmt (Elmt);
4944 end loop;
4945 end if;
4947 -- Generate listing of calls passed to the backend
4949 if Present (Backend_Calls) then
4950 Count := 0;
4952 Elmt := First_Elmt (Backend_Calls);
4953 while Present (Elmt) loop
4954 Nod := Node (Elmt);
4956 if not In_Internal_Unit (Nod) then
4957 Count := Count + 1;
4959 if Count = 1 then
4960 Write_Str ("List of inlined calls passed to the backend");
4961 Write_Eol;
4962 end if;
4964 Write_Str (" ");
4965 Write_Int (Count);
4966 Write_Str (":");
4967 Write_Location (Sloc (Nod));
4968 Output.Write_Eol;
4969 end if;
4971 Next_Elmt (Elmt);
4972 end loop;
4973 end if;
4975 -- Generate listing of instances inlined for the backend
4977 if Present (Backend_Instances) then
4978 Count := 0;
4980 Elmt := First_Elmt (Backend_Instances);
4981 while Present (Elmt) loop
4982 Nod := Node (Elmt);
4984 if not In_Internal_Unit (Nod) then
4985 Count := Count + 1;
4987 if Count = 1 then
4988 Write_Str ("List of instances inlined for the backend");
4989 Write_Eol;
4990 end if;
4992 Write_Str (" ");
4993 Write_Int (Count);
4994 Write_Str (":");
4995 Write_Location (Sloc (Nod));
4996 Output.Write_Eol;
4997 end if;
4999 Next_Elmt (Elmt);
5000 end loop;
5001 end if;
5003 -- Generate listing of subprograms passed to the backend
5005 if Present (Backend_Inlined_Subps) and then Back_End_Inlining then
5006 Count := 0;
5008 Elmt := First_Elmt (Backend_Inlined_Subps);
5009 while Present (Elmt) loop
5010 Nod := Node (Elmt);
5012 if not In_Internal_Unit (Nod) then
5013 Count := Count + 1;
5015 if Count = 1 then
5016 Write_Str
5017 ("List of inlined subprograms passed to the backend");
5018 Write_Eol;
5019 end if;
5021 Write_Str (" ");
5022 Write_Int (Count);
5023 Write_Str (":");
5024 Write_Name (Chars (Nod));
5025 Write_Str (" (");
5026 Write_Location (Sloc (Nod));
5027 Write_Str (")");
5028 Output.Write_Eol;
5029 end if;
5031 Next_Elmt (Elmt);
5032 end loop;
5033 end if;
5035 -- Generate listing of subprograms that cannot be inlined by the backend
5037 if Present (Backend_Not_Inlined_Subps) and then Back_End_Inlining then
5038 Count := 0;
5040 Elmt := First_Elmt (Backend_Not_Inlined_Subps);
5041 while Present (Elmt) loop
5042 Nod := Node (Elmt);
5044 if not In_Internal_Unit (Nod) then
5045 Count := Count + 1;
5047 if Count = 1 then
5048 Write_Str
5049 ("List of subprograms that cannot be inlined by backend");
5050 Write_Eol;
5051 end if;
5053 Write_Str (" ");
5054 Write_Int (Count);
5055 Write_Str (":");
5056 Write_Name (Chars (Nod));
5057 Write_Str (" (");
5058 Write_Location (Sloc (Nod));
5059 Write_Str (")");
5060 Output.Write_Eol;
5061 end if;
5063 Next_Elmt (Elmt);
5064 end loop;
5065 end if;
5066 end List_Inlining_Info;
5068 ----------
5069 -- Lock --
5070 ----------
5072 procedure Lock is
5073 begin
5074 Pending_Instantiations.Release;
5075 Pending_Instantiations.Locked := True;
5076 Called_Pending_Instantiations.Release;
5077 Called_Pending_Instantiations.Locked := True;
5078 Inlined_Bodies.Release;
5079 Inlined_Bodies.Locked := True;
5080 Successors.Release;
5081 Successors.Locked := True;
5082 Inlined.Release;
5083 Inlined.Locked := True;
5084 end Lock;
5086 --------------------------------
5087 -- Remove_Aspects_And_Pragmas --
5088 --------------------------------
5090 procedure Remove_Aspects_And_Pragmas (Body_Decl : Node_Id) is
5091 procedure Remove_Items (List : List_Id);
5092 -- Remove all useless aspects/pragmas from a particular list
5094 ------------------
5095 -- Remove_Items --
5096 ------------------
5098 procedure Remove_Items (List : List_Id) is
5099 Item : Node_Id;
5100 Item_Id : Node_Id;
5101 Next_Item : Node_Id;
5103 begin
5104 -- Traverse the list looking for an aspect specification or a pragma
5106 Item := First (List);
5107 while Present (Item) loop
5108 Next_Item := Next (Item);
5110 if Nkind (Item) = N_Aspect_Specification then
5111 Item_Id := Identifier (Item);
5112 elsif Nkind (Item) = N_Pragma then
5113 Item_Id := Pragma_Identifier (Item);
5114 else
5115 Item_Id := Empty;
5116 end if;
5118 if Present (Item_Id)
5119 and then Chars (Item_Id) in Name_Contract_Cases
5120 | Name_Global
5121 | Name_Depends
5122 | Name_Postcondition
5123 | Name_Precondition
5124 | Name_Refined_Global
5125 | Name_Refined_Depends
5126 | Name_Refined_Post
5127 | Name_Subprogram_Variant
5128 | Name_Test_Case
5129 | Name_Unmodified
5130 | Name_Unreferenced
5131 | Name_Unused
5132 then
5133 Remove (Item);
5134 end if;
5136 Item := Next_Item;
5137 end loop;
5138 end Remove_Items;
5140 -- Start of processing for Remove_Aspects_And_Pragmas
5142 begin
5143 Remove_Items (Aspect_Specifications (Body_Decl));
5144 Remove_Items (Declarations (Body_Decl));
5146 -- Pragmas Unmodified, Unreferenced, and Unused may additionally appear
5147 -- in the body of the subprogram.
5149 Remove_Items (Statements (Handled_Statement_Sequence (Body_Decl)));
5150 end Remove_Aspects_And_Pragmas;
5152 --------------------------
5153 -- Remove_Dead_Instance --
5154 --------------------------
5156 procedure Remove_Dead_Instance (N : Node_Id) is
5157 begin
5158 for J in 0 .. Pending_Instantiations.Last loop
5159 if Pending_Instantiations.Table (J).Inst_Node = N then
5160 Pending_Instantiations.Table (J).Inst_Node := Empty;
5161 return;
5162 end if;
5163 end loop;
5164 end Remove_Dead_Instance;
5166 -------------------------------------------
5167 -- Reset_Actual_Mapping_For_Inlined_Call --
5168 -------------------------------------------
5170 procedure Reset_Actual_Mapping_For_Inlined_Call (Subp : Entity_Id) is
5171 F : Entity_Id := First_Formal (Subp);
5173 begin
5174 while Present (F) loop
5175 Set_Renamed_Object (F, Empty);
5176 Next_Formal (F);
5177 end loop;
5178 end Reset_Actual_Mapping_For_Inlined_Call;
5180 end Inline;