[multiple changes]
[platform/upstream/gcc.git] / gcc / ada / inline.adb
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-2014, Free Software Foundation, Inc.         --
10 --                                                                          --
11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
12 -- terms of the  GNU General Public License as published  by the Free Soft- --
13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license.          --
20 --                                                                          --
21 -- GNAT was originally developed  by the GNAT team at  New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
23 --                                                                          --
24 ------------------------------------------------------------------------------
25
26 with Aspects;  use Aspects;
27 with Atree;    use Atree;
28 with Debug;    use Debug;
29 with Einfo;    use Einfo;
30 with Elists;   use Elists;
31 with Errout;   use Errout;
32 with Expander; use Expander;
33 with Exp_Ch6;  use Exp_Ch6;
34 with Exp_Ch7;  use Exp_Ch7;
35 with Exp_Tss;  use Exp_Tss;
36 with Exp_Util; use Exp_Util;
37 with Fname;    use Fname;
38 with Fname.UF; use Fname.UF;
39 with Lib;      use Lib;
40 with Namet;    use Namet;
41 with Nmake;    use Nmake;
42 with Nlists;   use Nlists;
43 with Output;   use Output;
44 with Sem_Aux;  use Sem_Aux;
45 with Sem_Ch8;  use Sem_Ch8;
46 with Sem_Ch10; use Sem_Ch10;
47 with Sem_Ch12; use Sem_Ch12;
48 with Sem_Prag; use Sem_Prag;
49 with Sem_Util; use Sem_Util;
50 with Sinfo;    use Sinfo;
51 with Sinput;   use Sinput;
52 with Snames;   use Snames;
53 with Stand;    use Stand;
54 with Uname;    use Uname;
55 with Tbuild;   use Tbuild;
56
57 package body Inline is
58
59    Check_Inlining_Restrictions : constant Boolean := True;
60    --  In the following cases the frontend rejects inlining because they
61    --  are not handled well by the backend. This variable facilitates
62    --  disabling these restrictions to evaluate future versions of the
63    --  GCC backend in which some of the restrictions may be supported.
64    --
65    --   - subprograms that have:
66    --      - nested subprograms
67    --      - instantiations
68    --      - package declarations
69    --      - task or protected object declarations
70    --      - some of the following statements:
71    --          - abort
72    --          - asynchronous-select
73    --          - conditional-entry-call
74    --          - delay-relative
75    --          - delay-until
76    --          - selective-accept
77    --          - timed-entry-call
78
79    Inlined_Calls : Elist_Id;
80    --  List of frontend inlined calls
81
82    Backend_Calls : Elist_Id;
83    --  List of inline calls passed to the backend
84
85    Backend_Inlined_Subps : Elist_Id;
86    --  List of subprograms inlined by the backend
87
88    Backend_Not_Inlined_Subps : Elist_Id;
89    --  List of subprograms that cannot be inlined by the backend
90
91    --------------------
92    -- Inlined Bodies --
93    --------------------
94
95    --  Inlined functions are actually placed in line by the backend if the
96    --  corresponding bodies are available (i.e. compiled). Whenever we find
97    --  a call to an inlined subprogram, we add the name of the enclosing
98    --  compilation unit to a worklist. After all compilation, and after
99    --  expansion of generic bodies, we traverse the list of pending bodies
100    --  and compile them as well.
101
102    package Inlined_Bodies is new Table.Table (
103      Table_Component_Type => Entity_Id,
104      Table_Index_Type     => Int,
105      Table_Low_Bound      => 0,
106      Table_Initial        => Alloc.Inlined_Bodies_Initial,
107      Table_Increment      => Alloc.Inlined_Bodies_Increment,
108      Table_Name           => "Inlined_Bodies");
109
110    -----------------------
111    -- Inline Processing --
112    -----------------------
113
114    --  For each call to an inlined subprogram, we make entries in a table
115    --  that stores caller and callee, and indicates the call direction from
116    --  one to the other. We also record the compilation unit that contains
117    --  the callee. After analyzing the bodies of all such compilation units,
118    --  we compute the transitive closure of inlined subprograms called from
119    --  the main compilation unit and make it available to the code generator
120    --  in no particular order, thus allowing cycles in the call graph.
121
122    Last_Inlined : Entity_Id := Empty;
123
124    --  For each entry in the table we keep a list of successors in topological
125    --  order, i.e. callers of the current subprogram.
126
127    type Subp_Index is new Nat;
128    No_Subp : constant Subp_Index := 0;
129
130    --  The subprogram entities are hashed into the Inlined table
131
132    Num_Hash_Headers : constant := 512;
133
134    Hash_Headers : array (Subp_Index range 0 .. Num_Hash_Headers - 1)
135                                                           of Subp_Index;
136
137    type Succ_Index is new Nat;
138    No_Succ : constant Succ_Index := 0;
139
140    type Succ_Info is record
141       Subp : Subp_Index;
142       Next : Succ_Index;
143    end record;
144
145    --  The following table stores list elements for the successor lists. These
146    --  lists cannot be chained directly through entries in the Inlined table,
147    --  because a given subprogram can appear in several such lists.
148
149    package Successors is new Table.Table (
150       Table_Component_Type => Succ_Info,
151       Table_Index_Type     => Succ_Index,
152       Table_Low_Bound      => 1,
153       Table_Initial        => Alloc.Successors_Initial,
154       Table_Increment      => Alloc.Successors_Increment,
155       Table_Name           => "Successors");
156
157    type Subp_Info is record
158       Name        : Entity_Id  := Empty;
159       Next        : Subp_Index := No_Subp;
160       First_Succ  : Succ_Index := No_Succ;
161       Listed      : Boolean    := False;
162       Main_Call   : Boolean    := False;
163       Processed   : Boolean    := False;
164    end record;
165
166    package Inlined is new Table.Table (
167       Table_Component_Type => Subp_Info,
168       Table_Index_Type     => Subp_Index,
169       Table_Low_Bound      => 1,
170       Table_Initial        => Alloc.Inlined_Initial,
171       Table_Increment      => Alloc.Inlined_Increment,
172       Table_Name           => "Inlined");
173
174    -----------------------
175    -- Local Subprograms --
176    -----------------------
177
178    procedure Add_Call (Called : Entity_Id; Caller : Entity_Id := Empty);
179    --  Make two entries in Inlined table, for an inlined subprogram being
180    --  called, and for the inlined subprogram that contains the call. If
181    --  the call is in the main compilation unit, Caller is Empty.
182
183    procedure Add_Inlined_Subprogram (Index : Subp_Index);
184    --  Add the subprogram to the list of inlined subprogram for the unit
185
186    function Add_Subp (E : Entity_Id) return Subp_Index;
187    --  Make entry in Inlined table for subprogram E, or return table index
188    --  that already holds E.
189
190    function Get_Code_Unit_Entity (E : Entity_Id) return Entity_Id;
191    pragma Inline (Get_Code_Unit_Entity);
192    --  Return the entity node for the unit containing E. Always return the spec
193    --  for a package.
194
195    function Has_Initialized_Type (E : Entity_Id) return Boolean;
196    --  If a candidate for inlining contains type declarations for types with
197    --  non-trivial initialization procedures, they are not worth inlining.
198
199    function Has_Single_Return (N : Node_Id) return Boolean;
200    --  In general we cannot inline functions that return unconstrained type.
201    --  However, we can handle such functions if all return statements return a
202    --  local variable that is the only declaration in the body of the function.
203    --  In that case the call can be replaced by that local variable as is done
204    --  for other inlined calls.
205
206    function In_Main_Unit_Or_Subunit (E : Entity_Id) return Boolean;
207    --  Return True if E is in the main unit or its spec or in a subunit
208
209    function Is_Nested (E : Entity_Id) return Boolean;
210    --  If the function is nested inside some other function, it will always
211    --  be compiled if that function is, so don't add it to the inline list.
212    --  We cannot compile a nested function outside the scope of the containing
213    --  function anyway. This is also the case if the function is defined in a
214    --  task body or within an entry (for example, an initialization procedure).
215
216    procedure Remove_Aspects_And_Pragmas (Body_Decl : Node_Id);
217    --  Remove all aspects and/or pragmas that have no meaning in inlined body
218    --  Body_Decl. The analysis of these items is performed on the non-inlined
219    --  body. The items currently removed are:
220    --    Contract_Cases
221    --    Global
222    --    Depends
223    --    Postcondition
224    --    Precondition
225    --    Refined_Global
226    --    Refined_Depends
227    --    Refined_Post
228    --    Test_Case
229    --    Unmodified
230    --    Unreferenced
231
232    ------------------------------
233    -- Deferred Cleanup Actions --
234    ------------------------------
235
236    --  The cleanup actions for scopes that contain instantiations is delayed
237    --  until after expansion of those instantiations, because they may contain
238    --  finalizable objects or tasks that affect the cleanup code. A scope
239    --  that contains instantiations only needs to be finalized once, even
240    --  if it contains more than one instance. We keep a list of scopes
241    --  that must still be finalized, and call cleanup_actions after all
242    --  the instantiations have been completed.
243
244    To_Clean : Elist_Id;
245
246    procedure Add_Scope_To_Clean (Inst : Entity_Id);
247    --  Build set of scopes on which cleanup actions must be performed
248
249    procedure Cleanup_Scopes;
250    --  Complete cleanup actions on scopes that need it
251
252    --------------
253    -- Add_Call --
254    --------------
255
256    procedure Add_Call (Called : Entity_Id; Caller : Entity_Id := Empty) is
257       P1 : constant Subp_Index := Add_Subp (Called);
258       P2 : Subp_Index;
259       J  : Succ_Index;
260
261    begin
262       if Present (Caller) then
263          P2 := Add_Subp (Caller);
264
265          --  Add P1 to the list of successors of P2, if not already there.
266          --  Note that P2 may contain more than one call to P1, and only
267          --  one needs to be recorded.
268
269          J := Inlined.Table (P2).First_Succ;
270          while J /= No_Succ loop
271             if Successors.Table (J).Subp = P1 then
272                return;
273             end if;
274
275             J := Successors.Table (J).Next;
276          end loop;
277
278          --  On exit, make a successor entry for P1
279
280          Successors.Increment_Last;
281          Successors.Table (Successors.Last).Subp := P1;
282          Successors.Table (Successors.Last).Next :=
283                              Inlined.Table (P2).First_Succ;
284          Inlined.Table (P2).First_Succ := Successors.Last;
285       else
286          Inlined.Table (P1).Main_Call := True;
287       end if;
288    end Add_Call;
289
290    ----------------------
291    -- Add_Inlined_Body --
292    ----------------------
293
294    procedure Add_Inlined_Body (E : Entity_Id) is
295
296       type Inline_Level_Type is (Dont_Inline, Inline_Call, Inline_Package);
297       --  Level of inlining for the call: Dont_Inline means no inlining,
298       --  Inline_Call means that only the call is considered for inlining,
299       --  Inline_Package means that the call is considered for inlining and
300       --  its package compiled and scanned for more inlining opportunities.
301
302       function Must_Inline return Inline_Level_Type;
303       --  Inlining is only done if the call statement N is in the main unit,
304       --  or within the body of another inlined subprogram.
305
306       -----------------
307       -- Must_Inline --
308       -----------------
309
310       function Must_Inline return Inline_Level_Type is
311          Scop : Entity_Id;
312          Comp : Node_Id;
313
314       begin
315          --  Check if call is in main unit
316
317          Scop := Current_Scope;
318
319          --  Do not try to inline if scope is standard. This could happen, for
320          --  example, for a call to Add_Global_Declaration, and it causes
321          --  trouble to try to inline at this level.
322
323          if Scop = Standard_Standard then
324             return Dont_Inline;
325          end if;
326
327          --  Otherwise lookup scope stack to outer scope
328
329          while Scope (Scop) /= Standard_Standard
330            and then not Is_Child_Unit (Scop)
331          loop
332             Scop := Scope (Scop);
333          end loop;
334
335          Comp := Parent (Scop);
336          while Nkind (Comp) /= N_Compilation_Unit loop
337             Comp := Parent (Comp);
338          end loop;
339
340          --  If the call is in the main unit, inline the call and compile the
341          --  package of the subprogram to find more calls to be inlined.
342
343          if Comp = Cunit (Main_Unit)
344            or else Comp = Library_Unit (Cunit (Main_Unit))
345          then
346             Add_Call (E);
347             return Inline_Package;
348          end if;
349
350          --  The call is not in the main unit. See if it is in some inlined
351          --  subprogram. If so, inline the call and, if the inlining level is
352          --  set to 1, stop there; otherwise also compile the package as above.
353
354          Scop := Current_Scope;
355          while Scope (Scop) /= Standard_Standard
356            and then not Is_Child_Unit (Scop)
357          loop
358             if Is_Overloadable (Scop) and then Is_Inlined (Scop) then
359                Add_Call (E, Scop);
360
361                if Inline_Level = 1 then
362                   return Inline_Call;
363                else
364                   return Inline_Package;
365                end if;
366             end if;
367
368             Scop := Scope (Scop);
369          end loop;
370
371          return Dont_Inline;
372       end Must_Inline;
373
374       Level : Inline_Level_Type;
375
376    --  Start of processing for Add_Inlined_Body
377
378    begin
379       --  Find unit containing E, and add to list of inlined bodies if needed.
380       --  If the body is already present, no need to load any other unit. This
381       --  is the case for an initialization procedure, which appears in the
382       --  package declaration that contains the type. It is also the case if
383       --  the body has already been analyzed. Finally, if the unit enclosing
384       --  E is an instance, the instance body will be analyzed in any case,
385       --  and there is no need to add the enclosing unit (whose body might not
386       --  be available).
387
388       --  Library-level functions must be handled specially, because there is
389       --  no enclosing package to retrieve. In this case, it is the body of
390       --  the function that will have to be loaded.
391
392       if Is_Abstract_Subprogram (E)
393         or else Is_Nested (E)
394         or else Convention (E) = Convention_Protected
395       then
396          return;
397       end if;
398
399       Level := Must_Inline;
400       if Level /= Dont_Inline then
401          declare
402             Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
403
404          begin
405             if Pack = E then
406
407                --  Library-level inlined function. Add function itself to
408                --  list of needed units.
409
410                Set_Is_Called (E);
411                Inlined_Bodies.Increment_Last;
412                Inlined_Bodies.Table (Inlined_Bodies.Last) := E;
413
414             elsif Ekind (Pack) = E_Package then
415                Set_Is_Called (E);
416
417                if Is_Generic_Instance (Pack) then
418                   null;
419
420                --  Do not inline the package if the subprogram is an init proc
421                --  or other internally generated subprogram, because in that
422                --  case the subprogram body appears in the same unit that
423                --  declares the type, and that body is visible to the back end.
424                --  Do not inline it either if it is in the main unit.
425
426                elsif Level = Inline_Package
427                  and then not Is_Inlined (Pack)
428                  and then not Is_Internal (E)
429                  and then not In_Main_Unit_Or_Subunit (Pack)
430                then
431                   Set_Is_Inlined (Pack);
432                   Inlined_Bodies.Increment_Last;
433                   Inlined_Bodies.Table (Inlined_Bodies.Last) := Pack;
434
435                --  Extend the -gnatn2 processing to -gnatn1 for Inline_Always
436                --  calls if the back-end takes care of inlining the call.
437
438                elsif Level = Inline_Call
439                  and then Has_Pragma_Inline_Always (E)
440                  and then Back_End_Inlining
441                then
442                   Set_Is_Inlined (Pack);
443                   Inlined_Bodies.Increment_Last;
444                   Inlined_Bodies.Table (Inlined_Bodies.Last) := Pack;
445                end if;
446             end if;
447          end;
448       end if;
449    end Add_Inlined_Body;
450
451    ----------------------------
452    -- Add_Inlined_Subprogram --
453    ----------------------------
454
455    procedure Add_Inlined_Subprogram (Index : Subp_Index) is
456       E    : constant Entity_Id := Inlined.Table (Index).Name;
457       Decl : constant Node_Id   := Parent (Declaration_Node (E));
458       Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
459
460       procedure Register_Backend_Inlined_Subprogram (Subp : Entity_Id);
461       --  Append Subp to the list of subprograms inlined by the backend
462
463       procedure Register_Backend_Not_Inlined_Subprogram (Subp : Entity_Id);
464       --  Append Subp to the list of subprograms that cannot be inlined by
465       --  the backend.
466
467       -----------------------------------------
468       -- Register_Backend_Inlined_Subprogram --
469       -----------------------------------------
470
471       procedure Register_Backend_Inlined_Subprogram (Subp : Entity_Id) is
472       begin
473          Append_New_Elmt (Subp, To => Backend_Inlined_Subps);
474       end Register_Backend_Inlined_Subprogram;
475
476       ---------------------------------------------
477       -- Register_Backend_Not_Inlined_Subprogram --
478       ---------------------------------------------
479
480       procedure Register_Backend_Not_Inlined_Subprogram (Subp : Entity_Id) is
481       begin
482          Append_New_Elmt (Subp, To => Backend_Not_Inlined_Subps);
483       end Register_Backend_Not_Inlined_Subprogram;
484
485    --  Start of processing for Add_Inlined_Subprogram
486
487    begin
488       --  If the subprogram is to be inlined, and if its unit is known to be
489       --  inlined or is an instance whose body will be analyzed anyway or the
490       --  subprogram was generated as a body by the compiler (for example an
491       --  initialization procedure) or its declaration was provided along with
492       --  the body (for example an expression function), and if it is declared
493       --  at the library level not in the main unit, and if it can be inlined
494       --  by the back-end, then insert it in the list of inlined subprograms.
495
496       if Is_Inlined (E)
497         and then (Is_Inlined (Pack)
498                    or else Is_Generic_Instance (Pack)
499                    or else Nkind (Decl) = N_Subprogram_Body
500                    or else Present (Corresponding_Body (Decl)))
501         and then not In_Main_Unit_Or_Subunit (E)
502         and then not Is_Nested (E)
503         and then not Has_Initialized_Type (E)
504       then
505          Register_Backend_Inlined_Subprogram (E);
506
507          if No (Last_Inlined) then
508             Set_First_Inlined_Subprogram (Cunit (Main_Unit), E);
509          else
510             Set_Next_Inlined_Subprogram (Last_Inlined, E);
511          end if;
512
513          Last_Inlined := E;
514
515       else
516          Register_Backend_Not_Inlined_Subprogram (E);
517       end if;
518
519       Inlined.Table (Index).Listed := True;
520    end Add_Inlined_Subprogram;
521
522    ------------------------
523    -- Add_Scope_To_Clean --
524    ------------------------
525
526    procedure Add_Scope_To_Clean (Inst : Entity_Id) is
527       Scop : constant Entity_Id := Enclosing_Dynamic_Scope (Inst);
528       Elmt : Elmt_Id;
529
530    begin
531       --  If the instance appears in a library-level package declaration,
532       --  all finalization is global, and nothing needs doing here.
533
534       if Scop = Standard_Standard then
535          return;
536       end if;
537
538       --  If the instance is within a generic unit, no finalization code
539       --  can be generated. Note that at this point all bodies have been
540       --  analyzed, and the scope stack itself is not present, and the flag
541       --  Inside_A_Generic is not set.
542
543       declare
544          S : Entity_Id;
545
546       begin
547          S := Scope (Inst);
548          while Present (S) and then S /= Standard_Standard loop
549             if Is_Generic_Unit (S) then
550                return;
551             end if;
552
553             S := Scope (S);
554          end loop;
555       end;
556
557       Elmt := First_Elmt (To_Clean);
558       while Present (Elmt) loop
559          if Node (Elmt) = Scop then
560             return;
561          end if;
562
563          Elmt := Next_Elmt (Elmt);
564       end loop;
565
566       Append_Elmt (Scop, To_Clean);
567    end Add_Scope_To_Clean;
568
569    --------------
570    -- Add_Subp --
571    --------------
572
573    function Add_Subp (E : Entity_Id) return Subp_Index is
574       Index : Subp_Index := Subp_Index (E) mod Num_Hash_Headers;
575       J     : Subp_Index;
576
577       procedure New_Entry;
578       --  Initialize entry in Inlined table
579
580       procedure New_Entry is
581       begin
582          Inlined.Increment_Last;
583          Inlined.Table (Inlined.Last).Name        := E;
584          Inlined.Table (Inlined.Last).Next        := No_Subp;
585          Inlined.Table (Inlined.Last).First_Succ  := No_Succ;
586          Inlined.Table (Inlined.Last).Listed      := False;
587          Inlined.Table (Inlined.Last).Main_Call   := False;
588          Inlined.Table (Inlined.Last).Processed   := False;
589       end New_Entry;
590
591    --  Start of processing for Add_Subp
592
593    begin
594       if Hash_Headers (Index) = No_Subp then
595          New_Entry;
596          Hash_Headers (Index) := Inlined.Last;
597          return Inlined.Last;
598
599       else
600          J := Hash_Headers (Index);
601          while J /= No_Subp loop
602             if Inlined.Table (J).Name = E then
603                return J;
604             else
605                Index := J;
606                J := Inlined.Table (J).Next;
607             end if;
608          end loop;
609
610          --  On exit, subprogram was not found. Enter in table. Index is
611          --  the current last entry on the hash chain.
612
613          New_Entry;
614          Inlined.Table (Index).Next := Inlined.Last;
615          return Inlined.Last;
616       end if;
617    end Add_Subp;
618
619    ----------------------------
620    -- Analyze_Inlined_Bodies --
621    ----------------------------
622
623    procedure Analyze_Inlined_Bodies is
624       Comp_Unit : Node_Id;
625       J         : Int;
626       Pack      : Entity_Id;
627       Subp      : Subp_Index;
628       S         : Succ_Index;
629
630       type Pending_Index is new Nat;
631
632       package Pending_Inlined is new Table.Table (
633          Table_Component_Type => Subp_Index,
634          Table_Index_Type     => Pending_Index,
635          Table_Low_Bound      => 1,
636          Table_Initial        => Alloc.Inlined_Initial,
637          Table_Increment      => Alloc.Inlined_Increment,
638          Table_Name           => "Pending_Inlined");
639       --  The workpile used to compute the transitive closure
640
641       function Is_Ancestor_Of_Main
642         (U_Name : Entity_Id;
643          Nam    : Node_Id) return Boolean;
644       --  Determine whether the unit whose body is loaded is an ancestor of
645       --  the main unit, and has a with_clause on it. The body is not
646       --  analyzed yet, so the check is purely lexical: the name of the with
647       --  clause is a selected component, and names of ancestors must match.
648
649       -------------------------
650       -- Is_Ancestor_Of_Main --
651       -------------------------
652
653       function Is_Ancestor_Of_Main
654         (U_Name : Entity_Id;
655          Nam    : Node_Id) return Boolean
656       is
657          Pref : Node_Id;
658
659       begin
660          if Nkind (Nam) /= N_Selected_Component then
661             return False;
662
663          else
664             if Chars (Selector_Name (Nam)) /=
665                Chars (Cunit_Entity (Main_Unit))
666             then
667                return False;
668             end if;
669
670             Pref := Prefix (Nam);
671             if Nkind (Pref) = N_Identifier then
672
673                --  Par is an ancestor of Par.Child.
674
675                return Chars (Pref) = Chars (U_Name);
676
677             elsif Nkind (Pref) = N_Selected_Component
678               and then Chars (Selector_Name (Pref)) = Chars (U_Name)
679             then
680                --  Par.Child is an ancestor of Par.Child.Grand.
681
682                return True;   --  should check that ancestor match
683
684             else
685                --  A is an ancestor of A.B.C if it is an ancestor of A.B
686
687                return Is_Ancestor_Of_Main (U_Name, Pref);
688             end if;
689          end if;
690       end Is_Ancestor_Of_Main;
691
692    --  Start of processing for Analyze_Inlined_Bodies
693
694    begin
695       if Serious_Errors_Detected = 0 then
696          Push_Scope (Standard_Standard);
697
698          J := 0;
699          while J <= Inlined_Bodies.Last
700            and then Serious_Errors_Detected = 0
701          loop
702             Pack := Inlined_Bodies.Table (J);
703             while Present (Pack)
704               and then Scope (Pack) /= Standard_Standard
705               and then not Is_Child_Unit (Pack)
706             loop
707                Pack := Scope (Pack);
708             end loop;
709
710             Comp_Unit := Parent (Pack);
711             while Present (Comp_Unit)
712               and then Nkind (Comp_Unit) /= N_Compilation_Unit
713             loop
714                Comp_Unit := Parent (Comp_Unit);
715             end loop;
716
717             --  Load the body, unless it is the main unit, or is an instance
718             --  whose body has already been analyzed.
719
720             if Present (Comp_Unit)
721               and then Comp_Unit /= Cunit (Main_Unit)
722               and then Body_Required (Comp_Unit)
723               and then (Nkind (Unit (Comp_Unit)) /= N_Package_Declaration
724                          or else No (Corresponding_Body (Unit (Comp_Unit))))
725             then
726                declare
727                   Bname : constant Unit_Name_Type :=
728                             Get_Body_Name (Get_Unit_Name (Unit (Comp_Unit)));
729
730                   OK : Boolean;
731
732                begin
733                   if not Is_Loaded (Bname) then
734                      Style_Check := False;
735                      Load_Needed_Body (Comp_Unit, OK, Do_Analyze => False);
736
737                      if not OK then
738
739                         --  Warn that a body was not available for inlining
740                         --  by the back-end.
741
742                         Error_Msg_Unit_1 := Bname;
743                         Error_Msg_N
744                           ("one or more inlined subprograms accessed in $!??",
745                            Comp_Unit);
746                         Error_Msg_File_1 :=
747                           Get_File_Name (Bname, Subunit => False);
748                         Error_Msg_N ("\but file{ was not found!??", Comp_Unit);
749
750                      else
751                         --  If the package to be inlined is an ancestor unit of
752                         --  the main unit, and it has a semantic dependence on
753                         --  it, the inlining cannot take place to prevent an
754                         --  elaboration circularity. The desired body is not
755                         --  analyzed yet, to prevent the completion of Taft
756                         --  amendment types that would lead to elaboration
757                         --  circularities in gigi.
758
759                         declare
760                            U_Id      : constant Entity_Id :=
761                                          Defining_Entity (Unit (Comp_Unit));
762                            Body_Unit : constant Node_Id :=
763                                          Library_Unit (Comp_Unit);
764                            Item      : Node_Id;
765
766                         begin
767                            Item := First (Context_Items (Body_Unit));
768                            while Present (Item) loop
769                               if Nkind (Item) = N_With_Clause
770                                 and then
771                                   Is_Ancestor_Of_Main (U_Id, Name (Item))
772                               then
773                                  Set_Is_Inlined (U_Id, False);
774                                  exit;
775                               end if;
776
777                               Next (Item);
778                            end loop;
779
780                            --  If no suspicious with_clauses, analyze the body.
781
782                            if Is_Inlined (U_Id) then
783                               Semantics (Body_Unit);
784                            end if;
785                         end;
786                      end if;
787                   end if;
788                end;
789             end if;
790
791             J := J + 1;
792
793             if J > Inlined_Bodies.Last then
794
795                --  The analysis of required bodies may have produced additional
796                --  generic instantiations. To obtain further inlining, we need
797                --  to perform another round of generic body instantiations.
798
799                Instantiate_Bodies;
800
801                --  Symmetrically, the instantiation of required generic bodies
802                --  may have caused additional bodies to be inlined. To obtain
803                --  further inlining, we keep looping over the inlined bodies.
804             end if;
805          end loop;
806
807          --  The list of inlined subprograms is an overestimate, because it
808          --  includes inlined functions called from functions that are compiled
809          --  as part of an inlined package, but are not themselves called. An
810          --  accurate computation of just those subprograms that are needed
811          --  requires that we perform a transitive closure over the call graph,
812          --  starting from calls in the main program.
813
814          for Index in Inlined.First .. Inlined.Last loop
815             if not Is_Called (Inlined.Table (Index).Name) then
816
817                --  This means that Add_Inlined_Body added the subprogram to the
818                --  table but wasn't able to handle its code unit. Do nothing.
819
820                Inlined.Table (Index).Processed := True;
821
822             elsif Inlined.Table (Index).Main_Call then
823                Pending_Inlined.Increment_Last;
824                Pending_Inlined.Table (Pending_Inlined.Last) := Index;
825                Inlined.Table (Index).Processed := True;
826
827             else
828                Set_Is_Called (Inlined.Table (Index).Name, False);
829             end if;
830          end loop;
831
832          --  Iterate over the workpile until it is emptied, propagating the
833          --  Is_Called flag to the successors of the processed subprogram.
834
835          while Pending_Inlined.Last >= Pending_Inlined.First loop
836             Subp := Pending_Inlined.Table (Pending_Inlined.Last);
837             Pending_Inlined.Decrement_Last;
838
839             S := Inlined.Table (Subp).First_Succ;
840
841             while S /= No_Succ loop
842                Subp := Successors.Table (S).Subp;
843
844                if not Inlined.Table (Subp).Processed then
845                   Set_Is_Called (Inlined.Table (Subp).Name);
846                   Pending_Inlined.Increment_Last;
847                   Pending_Inlined.Table (Pending_Inlined.Last) := Subp;
848                   Inlined.Table (Subp).Processed := True;
849                end if;
850
851                S := Successors.Table (S).Next;
852             end loop;
853          end loop;
854
855          --  Finally add the called subprograms to the list of inlined
856          --  subprograms for the unit.
857
858          for Index in Inlined.First .. Inlined.Last loop
859             if Is_Called (Inlined.Table (Index).Name)
860               and then not Inlined.Table (Index).Listed
861             then
862                Add_Inlined_Subprogram (Index);
863             end if;
864          end loop;
865
866          Pop_Scope;
867       end if;
868    end Analyze_Inlined_Bodies;
869
870    --------------------------
871    -- Build_Body_To_Inline --
872    --------------------------
873
874    procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id) is
875       Decl            : constant Node_Id := Unit_Declaration_Node (Spec_Id);
876       Analysis_Status : constant Boolean := Full_Analysis;
877       Original_Body   : Node_Id;
878       Body_To_Analyze : Node_Id;
879       Max_Size        : constant := 10;
880
881       function Has_Pending_Instantiation return Boolean;
882       --  If some enclosing body contains instantiations that appear before
883       --  the corresponding generic body, the enclosing body has a freeze node
884       --  so that it can be elaborated after the generic itself. This might
885       --  conflict with subsequent inlinings, so that it is unsafe to try to
886       --  inline in such a case.
887
888       function Has_Single_Return_In_GNATprove_Mode return Boolean;
889       --  This function is called only in GNATprove mode, and it returns
890       --  True if the subprogram has no return statement or a single return
891       --  statement as last statement. It returns False for subprogram with
892       --  a single return as last statement inside one or more blocks, as
893       --  inlining would generate gotos in that case as well (although the
894       --  goto is useless in that case).
895
896       function Uses_Secondary_Stack (Bod : Node_Id) return Boolean;
897       --  If the body of the subprogram includes a call that returns an
898       --  unconstrained type, the secondary stack is involved, and it
899       --  is not worth inlining.
900
901       -------------------------------
902       -- Has_Pending_Instantiation --
903       -------------------------------
904
905       function Has_Pending_Instantiation return Boolean is
906          S : Entity_Id;
907
908       begin
909          S := Current_Scope;
910          while Present (S) loop
911             if Is_Compilation_Unit (S)
912               or else Is_Child_Unit (S)
913             then
914                return False;
915
916             elsif Ekind (S) = E_Package
917               and then Has_Forward_Instantiation (S)
918             then
919                return True;
920             end if;
921
922             S := Scope (S);
923          end loop;
924
925          return False;
926       end Has_Pending_Instantiation;
927
928       -----------------------------------------
929       -- Has_Single_Return_In_GNATprove_Mode --
930       -----------------------------------------
931
932       function Has_Single_Return_In_GNATprove_Mode return Boolean is
933          Last_Statement : Node_Id := Empty;
934
935          function Check_Return (N : Node_Id) return Traverse_Result;
936          --  Returns OK on node N if this is not a return statement different
937          --  from the last statement in the subprogram.
938
939          ------------------
940          -- Check_Return --
941          ------------------
942
943          function Check_Return (N : Node_Id) return Traverse_Result is
944          begin
945             if Nkind_In (N, N_Simple_Return_Statement,
946                             N_Extended_Return_Statement)
947             then
948                if N = Last_Statement then
949                   return OK;
950                else
951                   return Abandon;
952                end if;
953
954             else
955                return OK;
956             end if;
957          end Check_Return;
958
959          function Check_All_Returns is new Traverse_Func (Check_Return);
960
961       --  Start of processing for Has_Single_Return_In_GNATprove_Mode
962
963       begin
964          --  Retrieve the last statement
965
966          Last_Statement := Last (Statements (Handled_Statement_Sequence (N)));
967
968          --  Check that the last statement is the only possible return
969          --  statement in the subprogram.
970
971          return Check_All_Returns (N) = OK;
972       end Has_Single_Return_In_GNATprove_Mode;
973
974       --------------------------
975       -- Uses_Secondary_Stack --
976       --------------------------
977
978       function Uses_Secondary_Stack (Bod : Node_Id) return Boolean is
979          function Check_Call (N : Node_Id) return Traverse_Result;
980          --  Look for function calls that return an unconstrained type
981
982          ----------------
983          -- Check_Call --
984          ----------------
985
986          function Check_Call (N : Node_Id) return Traverse_Result is
987          begin
988             if Nkind (N) = N_Function_Call
989               and then Is_Entity_Name (Name (N))
990               and then Is_Composite_Type (Etype (Entity (Name (N))))
991               and then not Is_Constrained (Etype (Entity (Name (N))))
992             then
993                Cannot_Inline
994                  ("cannot inline & (call returns unconstrained type)?",
995                   N, Spec_Id);
996                return Abandon;
997             else
998                return OK;
999             end if;
1000          end Check_Call;
1001
1002          function Check_Calls is new Traverse_Func (Check_Call);
1003
1004       begin
1005          return Check_Calls (Bod) = Abandon;
1006       end Uses_Secondary_Stack;
1007
1008    --  Start of processing for Build_Body_To_Inline
1009
1010    begin
1011       --  Return immediately if done already
1012
1013       if Nkind (Decl) = N_Subprogram_Declaration
1014         and then Present (Body_To_Inline (Decl))
1015       then
1016          return;
1017
1018       --  Subprograms that have return statements in the middle of the body are
1019       --  inlined with gotos. GNATprove does not currently support gotos, so
1020       --  we prevent such inlining.
1021
1022       elsif GNATprove_Mode
1023         and then not Has_Single_Return_In_GNATprove_Mode
1024       then
1025          Cannot_Inline ("cannot inline & (multiple returns)?", N, Spec_Id);
1026          return;
1027
1028       --  Functions that return unconstrained composite types require
1029       --  secondary stack handling, and cannot currently be inlined, unless
1030       --  all return statements return a local variable that is the first
1031       --  local declaration in the body.
1032
1033       elsif Ekind (Spec_Id) = E_Function
1034         and then not Is_Scalar_Type (Etype (Spec_Id))
1035         and then not Is_Access_Type (Etype (Spec_Id))
1036         and then not Is_Constrained (Etype (Spec_Id))
1037       then
1038          if not Has_Single_Return (N) then
1039             Cannot_Inline
1040               ("cannot inline & (unconstrained return type)?", N, Spec_Id);
1041             return;
1042          end if;
1043
1044       --  Ditto for functions that return controlled types, where controlled
1045       --  actions interfere in complex ways with inlining.
1046
1047       elsif Ekind (Spec_Id) = E_Function
1048         and then Needs_Finalization (Etype (Spec_Id))
1049       then
1050          Cannot_Inline
1051            ("cannot inline & (controlled return type)?", N, Spec_Id);
1052          return;
1053       end if;
1054
1055       if Present (Declarations (N))
1056         and then Has_Excluded_Declaration (Spec_Id, Declarations (N))
1057       then
1058          return;
1059       end if;
1060
1061       if Present (Handled_Statement_Sequence (N)) then
1062          if Present (Exception_Handlers (Handled_Statement_Sequence (N))) then
1063             Cannot_Inline
1064               ("cannot inline& (exception handler)?",
1065                First (Exception_Handlers (Handled_Statement_Sequence (N))),
1066                Spec_Id);
1067             return;
1068
1069          elsif Has_Excluded_Statement
1070                  (Spec_Id, Statements (Handled_Statement_Sequence (N)))
1071          then
1072             return;
1073          end if;
1074       end if;
1075
1076       --  We do not inline a subprogram that is too large, unless it is marked
1077       --  Inline_Always or we are in GNATprove mode. This pragma does not
1078       --  suppress the other checks on inlining (forbidden declarations,
1079       --  handlers, etc).
1080
1081       if not (Has_Pragma_Inline_Always (Spec_Id) or else GNATprove_Mode)
1082         and then List_Length
1083                    (Statements (Handled_Statement_Sequence (N))) > Max_Size
1084       then
1085          Cannot_Inline ("cannot inline& (body too large)?", N, Spec_Id);
1086          return;
1087       end if;
1088
1089       if Has_Pending_Instantiation then
1090          Cannot_Inline
1091            ("cannot inline& (forward instance within enclosing body)?",
1092              N, Spec_Id);
1093          return;
1094       end if;
1095
1096       --  Within an instance, the body to inline must be treated as a nested
1097       --  generic, so that the proper global references are preserved.
1098
1099       --  Note that we do not do this at the library level, because it is not
1100       --  needed, and furthermore this causes trouble if front end inlining
1101       --  is activated (-gnatN).
1102
1103       if In_Instance and then Scope (Current_Scope) /= Standard_Standard then
1104          Save_Env (Scope (Current_Scope), Scope (Current_Scope));
1105          Original_Body := Copy_Generic_Node (N, Empty, True);
1106       else
1107          Original_Body := Copy_Separate_Tree (N);
1108       end if;
1109
1110       --  We need to capture references to the formals in order to substitute
1111       --  the actuals at the point of inlining, i.e. instantiation. To treat
1112       --  the formals as globals to the body to inline, we nest it within a
1113       --  dummy parameterless subprogram, declared within the real one. To
1114       --  avoid generating an internal name (which is never public, and which
1115       --  affects serial numbers of other generated names), we use an internal
1116       --  symbol that cannot conflict with user declarations.
1117
1118       Set_Parameter_Specifications (Specification (Original_Body), No_List);
1119       Set_Defining_Unit_Name
1120         (Specification (Original_Body),
1121          Make_Defining_Identifier (Sloc (N), Name_uParent));
1122       Set_Corresponding_Spec (Original_Body, Empty);
1123
1124       --  Remove all aspects/pragmas that have no meaining in an inlined body
1125
1126       Remove_Aspects_And_Pragmas (Original_Body);
1127
1128       Body_To_Analyze := Copy_Generic_Node (Original_Body, Empty, False);
1129
1130       --  Set return type of function, which is also global and does not need
1131       --  to be resolved.
1132
1133       if Ekind (Spec_Id) = E_Function then
1134          Set_Result_Definition
1135            (Specification (Body_To_Analyze),
1136             New_Occurrence_Of (Etype (Spec_Id), Sloc (N)));
1137       end if;
1138
1139       if No (Declarations (N)) then
1140          Set_Declarations (N, New_List (Body_To_Analyze));
1141       else
1142          Append (Body_To_Analyze, Declarations (N));
1143       end if;
1144
1145       --  The body to inline is pre-analyzed. In GNATprove mode we must disable
1146       --  full analysis as well so that light expansion does not take place
1147       --  either, and name resolution is unaffected.
1148
1149       Expander_Mode_Save_And_Set (False);
1150       Full_Analysis := False;
1151
1152       Analyze (Body_To_Analyze);
1153       Push_Scope (Defining_Entity (Body_To_Analyze));
1154       Save_Global_References (Original_Body);
1155       End_Scope;
1156       Remove (Body_To_Analyze);
1157
1158       Expander_Mode_Restore;
1159       Full_Analysis := Analysis_Status;
1160
1161       --  Restore environment if previously saved
1162
1163       if In_Instance and then Scope (Current_Scope) /= Standard_Standard then
1164          Restore_Env;
1165       end if;
1166
1167       --  If secondary stack is used, there is no point in inlining. We have
1168       --  already issued the warning in this case, so nothing to do.
1169
1170       if Uses_Secondary_Stack (Body_To_Analyze) then
1171          return;
1172       end if;
1173
1174       Set_Body_To_Inline (Decl, Original_Body);
1175       Set_Ekind (Defining_Entity (Original_Body), Ekind (Spec_Id));
1176       Set_Is_Inlined (Spec_Id);
1177    end Build_Body_To_Inline;
1178
1179    -------------------
1180    -- Cannot_Inline --
1181    -------------------
1182
1183    procedure Cannot_Inline
1184      (Msg        : String;
1185       N          : Node_Id;
1186       Subp       : Entity_Id;
1187       Is_Serious : Boolean := False)
1188    is
1189    begin
1190       --  In GNATprove mode, inlining is the technical means by which the
1191       --  higher-level goal of contextual analysis is reached, so issue
1192       --  messages about failure to apply contextual analysis to a
1193       --  subprogram, rather than failure to inline it.
1194
1195       if GNATprove_Mode
1196         and then Msg (Msg'First .. Msg'First + 12) = "cannot inline"
1197       then
1198          declare
1199             Len1 : constant Positive :=
1200               String (String'("cannot inline"))'Length;
1201             Len2 : constant Positive :=
1202               String (String'("info: no contextual analysis of"))'Length;
1203
1204             New_Msg : String (1 .. Msg'Length + Len2 - Len1);
1205
1206          begin
1207             New_Msg (1 .. Len2) := "info: no contextual analysis of";
1208             New_Msg (Len2 + 1 .. Msg'Length + Len2 - Len1) :=
1209               Msg (Msg'First + Len1 .. Msg'Last);
1210             Cannot_Inline (New_Msg, N, Subp, Is_Serious);
1211             return;
1212          end;
1213       end if;
1214
1215       pragma Assert (Msg (Msg'Last) = '?');
1216
1217       --  Legacy front end inlining model
1218
1219       if not Back_End_Inlining then
1220
1221          --  Do not emit warning if this is a predefined unit which is not
1222          --  the main unit. With validity checks enabled, some predefined
1223          --  subprograms may contain nested subprograms and become ineligible
1224          --  for inlining.
1225
1226          if Is_Predefined_File_Name (Unit_File_Name (Get_Source_Unit (Subp)))
1227            and then not In_Extended_Main_Source_Unit (Subp)
1228          then
1229             null;
1230
1231          --  In GNATprove mode, issue a warning, and indicate that the
1232          --  subprogram is not always inlined by setting flag Is_Inlined_Always
1233          --  to False.
1234
1235          elsif GNATprove_Mode then
1236             Set_Is_Inlined_Always (Subp, False);
1237             Error_Msg_NE (Msg & "p?", N, Subp);
1238
1239          elsif Has_Pragma_Inline_Always (Subp) then
1240
1241             --  Remove last character (question mark) to make this into an
1242             --  error, because the Inline_Always pragma cannot be obeyed.
1243
1244             Error_Msg_NE (Msg (Msg'First .. Msg'Last - 1), N, Subp);
1245
1246          elsif Ineffective_Inline_Warnings then
1247             Error_Msg_NE (Msg & "p?", N, Subp);
1248          end if;
1249
1250       --  New semantics relying on back end inlining
1251
1252       elsif Is_Serious then
1253
1254          --  Remove last character (question mark) to make this into an error.
1255
1256          Error_Msg_NE (Msg (Msg'First .. Msg'Last - 1), N, Subp);
1257
1258       --  In GNATprove mode, issue a warning, and indicate that the subprogram
1259       --  is not always inlined by setting flag Is_Inlined_Always to False.
1260
1261       elsif GNATprove_Mode then
1262          Set_Is_Inlined_Always (Subp, False);
1263          Error_Msg_NE (Msg & "p?", N, Subp);
1264
1265       else
1266
1267          --  Do not emit warning if this is a predefined unit which is not
1268          --  the main unit. This behavior is currently provided for backward
1269          --  compatibility but it will be removed when we enforce the
1270          --  strictness of the new rules.
1271
1272          if Is_Predefined_File_Name (Unit_File_Name (Get_Source_Unit (Subp)))
1273            and then not In_Extended_Main_Source_Unit (Subp)
1274          then
1275             null;
1276
1277          elsif Has_Pragma_Inline_Always (Subp) then
1278
1279             --  Emit a warning if this is a call to a runtime subprogram
1280             --  which is located inside a generic. Previously this call
1281             --  was silently skipped.
1282
1283             if Is_Generic_Instance (Subp) then
1284                declare
1285                   Gen_P : constant Entity_Id := Generic_Parent (Parent (Subp));
1286                begin
1287                   if Is_Predefined_File_Name
1288                        (Unit_File_Name (Get_Source_Unit (Gen_P)))
1289                   then
1290                      Set_Is_Inlined (Subp, False);
1291                      Error_Msg_NE (Msg & "p?", N, Subp);
1292                      return;
1293                   end if;
1294                end;
1295             end if;
1296
1297             --  Remove last character (question mark) to make this into an
1298             --  error, because the Inline_Always pragma cannot be obeyed.
1299
1300             Error_Msg_NE (Msg (Msg'First .. Msg'Last - 1), N, Subp);
1301
1302          else
1303             Set_Is_Inlined (Subp, False);
1304
1305             if Ineffective_Inline_Warnings then
1306                Error_Msg_NE (Msg & "p?", N, Subp);
1307             end if;
1308          end if;
1309       end if;
1310    end Cannot_Inline;
1311
1312    --------------------------------------
1313    -- Can_Be_Inlined_In_GNATprove_Mode --
1314    --------------------------------------
1315
1316    function Can_Be_Inlined_In_GNATprove_Mode
1317      (Spec_Id : Entity_Id;
1318       Body_Id : Entity_Id) return Boolean
1319    is
1320       function Has_Some_Contract (Id : Entity_Id) return Boolean;
1321       --  Returns True if subprogram Id has any contract (Pre, Post, Global,
1322       --  Depends, etc.)
1323
1324       function Is_Unit_Subprogram (Id : Entity_Id) return Boolean;
1325       --  Returns True if subprogram Id defines a compilation unit
1326       --  Shouldn't this be in Sem_Aux???
1327
1328       function In_Package_Visible_Spec (Id : Node_Id) return Boolean;
1329       --  Returns True if subprogram Id is defined in the visible part of a
1330       --  package specification.
1331
1332       function Is_Expression_Function (Id : Entity_Id) return Boolean;
1333       --  Returns True if subprogram Id was defined originally as an expression
1334       --  function.
1335
1336       -----------------------
1337       -- Has_Some_Contract --
1338       -----------------------
1339
1340       function Has_Some_Contract (Id : Entity_Id) return Boolean is
1341          Items : Node_Id;
1342
1343       begin
1344          --  A call to an expression function may precede the actual body which
1345          --  is inserted at the end of the enclosing declarations. Ensure that
1346          --  the related entity is decorated before inspecting the contract.
1347
1348          if Is_Subprogram_Or_Generic_Subprogram (Id) then
1349             Items := Contract (Id);
1350
1351             return Present (Items)
1352               and then (Present (Pre_Post_Conditions (Items)) or else
1353                         Present (Contract_Test_Cases (Items)) or else
1354                         Present (Classifications     (Items)));
1355          end if;
1356
1357          return False;
1358       end Has_Some_Contract;
1359
1360       -----------------------------
1361       -- In_Package_Visible_Spec --
1362       -----------------------------
1363
1364       function In_Package_Visible_Spec  (Id : Node_Id) return Boolean is
1365          Decl : Node_Id := Parent (Parent (Id));
1366          P    : Node_Id;
1367
1368       begin
1369          if Nkind (Parent (Id)) = N_Defining_Program_Unit_Name then
1370             Decl := Parent (Decl);
1371          end if;
1372
1373          P := Parent (Decl);
1374
1375          return Nkind (P) = N_Package_Specification
1376            and then List_Containing (Decl) = Visible_Declarations (P);
1377       end In_Package_Visible_Spec;
1378
1379       ----------------------------
1380       -- Is_Expression_Function --
1381       ----------------------------
1382
1383       function Is_Expression_Function (Id : Entity_Id) return Boolean is
1384          Decl : Node_Id := Parent (Parent (Id));
1385       begin
1386          if Nkind (Parent (Id)) = N_Defining_Program_Unit_Name then
1387             Decl := Parent (Decl);
1388          end if;
1389
1390          return Nkind (Original_Node (Decl)) = N_Expression_Function;
1391       end Is_Expression_Function;
1392
1393       ------------------------
1394       -- Is_Unit_Subprogram --
1395       ------------------------
1396
1397       function Is_Unit_Subprogram (Id : Entity_Id) return Boolean is
1398          Decl : Node_Id := Parent (Parent (Id));
1399       begin
1400          if Nkind (Parent (Id)) = N_Defining_Program_Unit_Name then
1401             Decl := Parent (Decl);
1402          end if;
1403
1404          return Nkind (Parent (Decl)) = N_Compilation_Unit;
1405       end Is_Unit_Subprogram;
1406
1407       --  Local declarations
1408
1409       Id : Entity_Id;  --  Procedure or function entity for the subprogram
1410
1411    --  Start of Can_Be_Inlined_In_GNATprove_Mode
1412
1413    begin
1414       pragma Assert (Present (Spec_Id) or else Present (Body_Id));
1415
1416       if Present (Spec_Id) then
1417          Id := Spec_Id;
1418       else
1419          Id := Body_Id;
1420       end if;
1421
1422       --  Only local subprograms without contracts are inlined in GNATprove
1423       --  mode, as these are the subprograms which a user is not interested in
1424       --  analyzing in isolation, but rather in the context of their call. This
1425       --  is a convenient convention, that could be changed for an explicit
1426       --  pragma/aspect one day.
1427
1428       --  In a number of special cases, inlining is not desirable or not
1429       --  possible, see below.
1430
1431       --  Do not inline unit-level subprograms
1432
1433       if Is_Unit_Subprogram (Id) then
1434          return False;
1435
1436       --  Do not inline subprograms declared in the visible part of a package
1437
1438       elsif In_Package_Visible_Spec (Id) then
1439          return False;
1440
1441       --  Do not inline subprograms that have a contract on the spec or the
1442       --  body. Use the contract(s) instead in GNATprove.
1443
1444       elsif (Present (Spec_Id) and then Has_Some_Contract (Spec_Id))
1445                or else
1446             (Present (Body_Id) and then Has_Some_Contract (Body_Id))
1447       then
1448          return False;
1449
1450       --  Do not inline expression functions, which are directly inlined at the
1451       --  prover level.
1452
1453       elsif (Present (Spec_Id) and then Is_Expression_Function (Spec_Id))
1454               or else
1455             (Present (Body_Id) and then Is_Expression_Function (Body_Id))
1456       then
1457          return False;
1458
1459       --  Do not inline generic subprogram instances. The visibility rules of
1460       --  generic instances plays badly with inlining.
1461
1462       elsif Is_Generic_Instance (Spec_Id) then
1463          return False;
1464
1465       --  Only inline subprograms whose spec is marked SPARK_Mode On. For
1466       --  the subprogram body, a similar check is performed after the body
1467       --  is analyzed, as this is where a pragma SPARK_Mode might be inserted.
1468
1469       elsif Present (Spec_Id)
1470         and then
1471           (No (SPARK_Pragma (Spec_Id))
1472             or else Get_SPARK_Mode_From_Pragma (SPARK_Pragma (Spec_Id)) /= On)
1473       then
1474          return False;
1475
1476       --  Subprograms in generic instances are currently not inlined, to avoid
1477       --  problems with inlining of standard library subprograms.
1478
1479       elsif Instantiation_Location (Sloc (Id)) /= No_Location then
1480          return False;
1481
1482       --  Don't inline predicate functions (treated specially by GNATprove)
1483
1484       elsif Is_Predicate_Function (Id) then
1485          return False;
1486
1487       --  Otherwise, this is a subprogram declared inside the private part of a
1488       --  package, or inside a package body, or locally in a subprogram, and it
1489       --  does not have any contract. Inline it.
1490
1491       else
1492          return True;
1493       end if;
1494    end Can_Be_Inlined_In_GNATprove_Mode;
1495
1496    --------------------------------------------
1497    -- Check_And_Split_Unconstrained_Function --
1498    --------------------------------------------
1499
1500    procedure Check_And_Split_Unconstrained_Function
1501      (N       : Node_Id;
1502       Spec_Id : Entity_Id;
1503       Body_Id : Entity_Id)
1504    is
1505       procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id);
1506       --  Use generic machinery to build an unexpanded body for the subprogram.
1507       --  This body is subsequently used for inline expansions at call sites.
1508
1509       function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean;
1510       --  Return true if we generate code for the function body N, the function
1511       --  body N has no local declarations and its unique statement is a single
1512       --  extended return statement with a handled statements sequence.
1513
1514       procedure Generate_Subprogram_Body
1515         (N              : Node_Id;
1516          Body_To_Inline : out Node_Id);
1517       --  Generate a parameterless duplicate of subprogram body N. Occurrences
1518       --  of pragmas referencing the formals are removed since they have no
1519       --  meaning when the body is inlined and the formals are rewritten (the
1520       --  analysis of the non-inlined body will handle these pragmas properly).
1521       --  A new internal name is associated with Body_To_Inline.
1522
1523       procedure Split_Unconstrained_Function
1524         (N       : Node_Id;
1525          Spec_Id : Entity_Id);
1526       --  N is an inlined function body that returns an unconstrained type and
1527       --  has a single extended return statement. Split N in two subprograms:
1528       --  a procedure P' and a function F'. The formals of P' duplicate the
1529       --  formals of N plus an extra formal which is used return a value;
1530       --  its body is composed by the declarations and list of statements
1531       --  of the extended return statement of N.
1532
1533       --------------------------
1534       -- Build_Body_To_Inline --
1535       --------------------------
1536
1537       procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id) is
1538          Decl            : constant Node_Id := Unit_Declaration_Node (Spec_Id);
1539          Original_Body   : Node_Id;
1540          Body_To_Analyze : Node_Id;
1541
1542       begin
1543          pragma Assert (Current_Scope = Spec_Id);
1544
1545          --  Within an instance, the body to inline must be treated as a nested
1546          --  generic, so that the proper global references are preserved. We
1547          --  do not do this at the library level, because it is not needed, and
1548          --  furthermore this causes trouble if front end inlining is activated
1549          --  (-gnatN).
1550
1551          if In_Instance
1552            and then Scope (Current_Scope) /= Standard_Standard
1553          then
1554             Save_Env (Scope (Current_Scope), Scope (Current_Scope));
1555          end if;
1556
1557          --  We need to capture references to the formals in order
1558          --  to substitute the actuals at the point of inlining, i.e.
1559          --  instantiation. To treat the formals as globals to the body to
1560          --  inline, we nest it within a dummy parameterless subprogram,
1561          --  declared within the real one.
1562
1563          Generate_Subprogram_Body (N, Original_Body);
1564          Body_To_Analyze := Copy_Generic_Node (Original_Body, Empty, False);
1565
1566          --  Set return type of function, which is also global and does not
1567          --  need to be resolved.
1568
1569          if Ekind (Spec_Id) = E_Function then
1570             Set_Result_Definition (Specification (Body_To_Analyze),
1571               New_Occurrence_Of (Etype (Spec_Id), Sloc (N)));
1572          end if;
1573
1574          if No (Declarations (N)) then
1575             Set_Declarations (N, New_List (Body_To_Analyze));
1576          else
1577             Append_To (Declarations (N), Body_To_Analyze);
1578          end if;
1579
1580          Preanalyze (Body_To_Analyze);
1581
1582          Push_Scope (Defining_Entity (Body_To_Analyze));
1583          Save_Global_References (Original_Body);
1584          End_Scope;
1585          Remove (Body_To_Analyze);
1586
1587          --  Restore environment if previously saved
1588
1589          if In_Instance
1590            and then Scope (Current_Scope) /= Standard_Standard
1591          then
1592             Restore_Env;
1593          end if;
1594
1595          pragma Assert (No (Body_To_Inline (Decl)));
1596          Set_Body_To_Inline (Decl, Original_Body);
1597          Set_Ekind (Defining_Entity (Original_Body), Ekind (Spec_Id));
1598       end Build_Body_To_Inline;
1599
1600       --------------------------------------
1601       -- Can_Split_Unconstrained_Function --
1602       --------------------------------------
1603
1604       function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean
1605       is
1606          Ret_Node : constant Node_Id :=
1607                       First (Statements (Handled_Statement_Sequence (N)));
1608          D : Node_Id;
1609
1610       begin
1611          --  No user defined declarations allowed in the function except inside
1612          --  the unique return statement; implicit labels are the only allowed
1613          --  declarations.
1614
1615          if not Is_Empty_List (Declarations (N)) then
1616             D := First (Declarations (N));
1617             while Present (D) loop
1618                if Nkind (D) /= N_Implicit_Label_Declaration then
1619                   return False;
1620                end if;
1621
1622                Next (D);
1623             end loop;
1624          end if;
1625
1626          --  We only split the inlined function when we are generating the code
1627          --  of its body; otherwise we leave duplicated split subprograms in
1628          --  the tree which (if referenced) generate wrong references at link
1629          --  time.
1630
1631          return In_Extended_Main_Code_Unit (N)
1632            and then Present (Ret_Node)
1633            and then Nkind (Ret_Node) = N_Extended_Return_Statement
1634            and then No (Next (Ret_Node))
1635            and then Present (Handled_Statement_Sequence (Ret_Node));
1636       end Can_Split_Unconstrained_Function;
1637
1638       -----------------------------
1639       -- Generate_Body_To_Inline --
1640       -----------------------------
1641
1642       procedure Generate_Subprogram_Body
1643         (N              : Node_Id;
1644          Body_To_Inline : out Node_Id)
1645       is
1646       begin
1647          --  Within an instance, the body to inline must be treated as a nested
1648          --  generic, so that the proper global references are preserved.
1649
1650          --  Note that we do not do this at the library level, because it
1651          --  is not needed, and furthermore this causes trouble if front
1652          --  end inlining is activated (-gnatN).
1653
1654          if In_Instance
1655            and then Scope (Current_Scope) /= Standard_Standard
1656          then
1657             Body_To_Inline := Copy_Generic_Node (N, Empty, True);
1658          else
1659             Body_To_Inline := Copy_Separate_Tree (N);
1660          end if;
1661
1662          --  Remove all aspects/pragmas that have no meaning in an inlined body
1663
1664          Remove_Aspects_And_Pragmas (Body_To_Inline);
1665
1666          --  We need to capture references to the formals in order
1667          --  to substitute the actuals at the point of inlining, i.e.
1668          --  instantiation. To treat the formals as globals to the body to
1669          --  inline, we nest it within a dummy parameterless subprogram,
1670          --  declared within the real one.
1671
1672          Set_Parameter_Specifications
1673            (Specification (Body_To_Inline), No_List);
1674
1675          --  A new internal name is associated with Body_To_Inline to avoid
1676          --  conflicts when the non-inlined body N is analyzed.
1677
1678          Set_Defining_Unit_Name (Specification (Body_To_Inline),
1679             Make_Defining_Identifier (Sloc (N), New_Internal_Name ('P')));
1680          Set_Corresponding_Spec (Body_To_Inline, Empty);
1681       end Generate_Subprogram_Body;
1682
1683       ----------------------------------
1684       -- Split_Unconstrained_Function --
1685       ----------------------------------
1686
1687       procedure Split_Unconstrained_Function
1688         (N        : Node_Id;
1689          Spec_Id  : Entity_Id)
1690       is
1691          Loc      : constant Source_Ptr := Sloc (N);
1692          Ret_Node : constant Node_Id :=
1693                       First (Statements (Handled_Statement_Sequence (N)));
1694          Ret_Obj  : constant Node_Id :=
1695                       First (Return_Object_Declarations (Ret_Node));
1696
1697          procedure Build_Procedure
1698            (Proc_Id   : out Entity_Id;
1699             Decl_List : out List_Id);
1700          --  Build a procedure containing the statements found in the extended
1701          --  return statement of the unconstrained function body N.
1702
1703          ---------------------
1704          -- Build_Procedure --
1705          ---------------------
1706
1707          procedure Build_Procedure
1708            (Proc_Id   : out Entity_Id;
1709             Decl_List : out List_Id)
1710          is
1711             Formal         : Entity_Id;
1712             Formal_List    : constant List_Id := New_List;
1713             Proc_Spec      : Node_Id;
1714             Proc_Body      : Node_Id;
1715             Subp_Name      : constant Name_Id := New_Internal_Name ('F');
1716             Body_Decl_List : List_Id := No_List;
1717             Param_Type     : Node_Id;
1718
1719          begin
1720             if Nkind (Object_Definition (Ret_Obj)) = N_Identifier then
1721                Param_Type :=
1722                  New_Copy (Object_Definition (Ret_Obj));
1723             else
1724                Param_Type :=
1725                  New_Copy (Subtype_Mark (Object_Definition (Ret_Obj)));
1726             end if;
1727
1728             Append_To (Formal_List,
1729               Make_Parameter_Specification (Loc,
1730                 Defining_Identifier    =>
1731                   Make_Defining_Identifier (Loc,
1732                     Chars => Chars (Defining_Identifier (Ret_Obj))),
1733                 In_Present             => False,
1734                 Out_Present            => True,
1735                 Null_Exclusion_Present => False,
1736                 Parameter_Type         => Param_Type));
1737
1738             Formal := First_Formal (Spec_Id);
1739
1740             --  Note that we copy the parameter type rather than creating
1741             --  a reference to it, because it may be a class-wide entity
1742             --  that will not be retrieved by name.
1743
1744             while Present (Formal) loop
1745                Append_To (Formal_List,
1746                  Make_Parameter_Specification (Loc,
1747                    Defining_Identifier    =>
1748                      Make_Defining_Identifier (Sloc (Formal),
1749                        Chars => Chars (Formal)),
1750                    In_Present             => In_Present (Parent (Formal)),
1751                    Out_Present            => Out_Present (Parent (Formal)),
1752                    Null_Exclusion_Present =>
1753                      Null_Exclusion_Present (Parent (Formal)),
1754                    Parameter_Type         =>
1755                      New_Copy_Tree (Parameter_Type (Parent (Formal))),
1756                    Expression             =>
1757                      Copy_Separate_Tree (Expression (Parent (Formal)))));
1758
1759                Next_Formal (Formal);
1760             end loop;
1761
1762             Proc_Id := Make_Defining_Identifier (Loc, Chars => Subp_Name);
1763
1764             Proc_Spec :=
1765               Make_Procedure_Specification (Loc,
1766                 Defining_Unit_Name       => Proc_Id,
1767                 Parameter_Specifications => Formal_List);
1768
1769             Decl_List := New_List;
1770
1771             Append_To (Decl_List,
1772               Make_Subprogram_Declaration (Loc, Proc_Spec));
1773
1774             --  Can_Convert_Unconstrained_Function checked that the function
1775             --  has no local declarations except implicit label declarations.
1776             --  Copy these declarations to the built procedure.
1777
1778             if Present (Declarations (N)) then
1779                Body_Decl_List := New_List;
1780
1781                declare
1782                   D     : Node_Id;
1783                   New_D : Node_Id;
1784
1785                begin
1786                   D := First (Declarations (N));
1787                   while Present (D) loop
1788                      pragma Assert (Nkind (D) = N_Implicit_Label_Declaration);
1789
1790                      New_D :=
1791                        Make_Implicit_Label_Declaration (Loc,
1792                          Make_Defining_Identifier (Loc,
1793                            Chars => Chars (Defining_Identifier (D))),
1794                          Label_Construct => Empty);
1795                      Append_To (Body_Decl_List, New_D);
1796
1797                      Next (D);
1798                   end loop;
1799                end;
1800             end if;
1801
1802             pragma Assert (Present (Handled_Statement_Sequence (Ret_Node)));
1803
1804             Proc_Body :=
1805               Make_Subprogram_Body (Loc,
1806                 Specification => Copy_Separate_Tree (Proc_Spec),
1807                 Declarations  => Body_Decl_List,
1808                 Handled_Statement_Sequence =>
1809                   Copy_Separate_Tree (Handled_Statement_Sequence (Ret_Node)));
1810
1811             Set_Defining_Unit_Name (Specification (Proc_Body),
1812                Make_Defining_Identifier (Loc, Subp_Name));
1813
1814             Append_To (Decl_List, Proc_Body);
1815          end Build_Procedure;
1816
1817          --  Local variables
1818
1819          New_Obj   : constant Node_Id := Copy_Separate_Tree (Ret_Obj);
1820          Blk_Stmt  : Node_Id;
1821          Proc_Id   : Entity_Id;
1822          Proc_Call : Node_Id;
1823
1824       --  Start of processing for Split_Unconstrained_Function
1825
1826       begin
1827          --  Build the associated procedure, analyze it and insert it before
1828          --  the function body N.
1829
1830          declare
1831             Scope     : constant Entity_Id := Current_Scope;
1832             Decl_List : List_Id;
1833          begin
1834             Pop_Scope;
1835             Build_Procedure (Proc_Id, Decl_List);
1836             Insert_Actions (N, Decl_List);
1837             Push_Scope (Scope);
1838          end;
1839
1840          --  Build the call to the generated procedure
1841
1842          declare
1843             Actual_List : constant List_Id := New_List;
1844             Formal      : Entity_Id;
1845
1846          begin
1847             Append_To (Actual_List,
1848               New_Occurrence_Of (Defining_Identifier (New_Obj), Loc));
1849
1850             Formal := First_Formal (Spec_Id);
1851             while Present (Formal) loop
1852                Append_To (Actual_List, New_Occurrence_Of (Formal, Loc));
1853
1854                --  Avoid spurious warning on unreferenced formals
1855
1856                Set_Referenced (Formal);
1857                Next_Formal (Formal);
1858             end loop;
1859
1860             Proc_Call :=
1861               Make_Procedure_Call_Statement (Loc,
1862                 Name                   => New_Occurrence_Of (Proc_Id, Loc),
1863                 Parameter_Associations => Actual_List);
1864          end;
1865
1866          --  Generate
1867
1868          --    declare
1869          --       New_Obj : ...
1870          --    begin
1871          --       main_1__F1b (New_Obj, ...);
1872          --       return Obj;
1873          --    end B10b;
1874
1875          Blk_Stmt :=
1876            Make_Block_Statement (Loc,
1877              Declarations               => New_List (New_Obj),
1878              Handled_Statement_Sequence =>
1879                Make_Handled_Sequence_Of_Statements (Loc,
1880                  Statements => New_List (
1881
1882                    Proc_Call,
1883
1884                    Make_Simple_Return_Statement (Loc,
1885                      Expression =>
1886                        New_Occurrence_Of
1887                          (Defining_Identifier (New_Obj), Loc)))));
1888
1889          Rewrite (Ret_Node, Blk_Stmt);
1890       end Split_Unconstrained_Function;
1891
1892       --  Local variables
1893
1894       Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id);
1895
1896    --  Start of processing for Check_And_Split_Unconstrained_Function
1897
1898    begin
1899       pragma Assert (Back_End_Inlining
1900         and then Ekind (Spec_Id) = E_Function
1901         and then Returns_Unconstrained_Type (Spec_Id)
1902         and then Comes_From_Source (Body_Id)
1903         and then (Has_Pragma_Inline_Always (Spec_Id)
1904                     or else Optimization_Level > 0));
1905
1906       --  This routine must not be used in GNATprove mode since GNATprove
1907       --  relies on frontend inlining
1908
1909       pragma Assert (not GNATprove_Mode);
1910
1911       --  No need to split the function if we cannot generate the code
1912
1913       if Serious_Errors_Detected /= 0 then
1914          return;
1915       end if;
1916
1917       --  No action needed in stubs since the attribute Body_To_Inline
1918       --  is not available
1919
1920       if Nkind (Decl) = N_Subprogram_Body_Stub then
1921          return;
1922
1923       --  Cannot build the body to inline if the attribute is already set.
1924       --  This attribute may have been set if this is a subprogram renaming
1925       --  declarations (see Freeze.Build_Renamed_Body).
1926
1927       elsif Present (Body_To_Inline (Decl)) then
1928          return;
1929
1930       --  Check excluded declarations
1931
1932       elsif Present (Declarations (N))
1933         and then Has_Excluded_Declaration (Spec_Id, Declarations (N))
1934       then
1935          return;
1936
1937       --  Check excluded statements. There is no need to protect us against
1938       --  exception handlers since they are supported by the GCC backend.
1939
1940       elsif Present (Handled_Statement_Sequence (N))
1941         and then Has_Excluded_Statement
1942                    (Spec_Id, Statements (Handled_Statement_Sequence (N)))
1943       then
1944          return;
1945       end if;
1946
1947       --  Build the body to inline only if really needed
1948
1949       if Can_Split_Unconstrained_Function (N) then
1950          Split_Unconstrained_Function (N, Spec_Id);
1951          Build_Body_To_Inline (N, Spec_Id);
1952          Set_Is_Inlined (Spec_Id);
1953       end if;
1954    end Check_And_Split_Unconstrained_Function;
1955
1956    -------------------------------------
1957    -- Check_Package_Body_For_Inlining --
1958    -------------------------------------
1959
1960    procedure Check_Package_Body_For_Inlining (N : Node_Id; P : Entity_Id) is
1961       Bname : Unit_Name_Type;
1962       E     : Entity_Id;
1963       OK    : Boolean;
1964
1965    begin
1966       --  Legacy implementation (relying on frontend inlining)
1967
1968       if not Back_End_Inlining
1969         and then Is_Compilation_Unit (P)
1970         and then not Is_Generic_Instance (P)
1971       then
1972          Bname := Get_Body_Name (Get_Unit_Name (Unit (N)));
1973
1974          E := First_Entity (P);
1975          while Present (E) loop
1976             if Has_Pragma_Inline_Always (E)
1977               or else (Has_Pragma_Inline (E) and Front_End_Inlining)
1978             then
1979                if not Is_Loaded (Bname) then
1980                   Load_Needed_Body (N, OK);
1981
1982                   if OK then
1983
1984                      --  Check we are not trying to inline a parent whose body
1985                      --  depends on a child, when we are compiling the body of
1986                      --  the child. Otherwise we have a potential elaboration
1987                      --  circularity with inlined subprograms and with
1988                      --  Taft-Amendment types.
1989
1990                      declare
1991                         Comp        : Node_Id;      --  Body just compiled
1992                         Child_Spec  : Entity_Id;    --  Spec of main unit
1993                         Ent         : Entity_Id;    --  For iteration
1994                         With_Clause : Node_Id;      --  Context of body.
1995
1996                      begin
1997                         if Nkind (Unit (Cunit (Main_Unit))) = N_Package_Body
1998                           and then Present (Body_Entity (P))
1999                         then
2000                            Child_Spec :=
2001                              Defining_Entity
2002                                ((Unit (Library_Unit (Cunit (Main_Unit)))));
2003
2004                            Comp :=
2005                              Parent (Unit_Declaration_Node (Body_Entity (P)));
2006
2007                            --  Check whether the context of the body just
2008                            --  compiled includes a child of itself, and that
2009                            --  child is the spec of the main compilation.
2010
2011                            With_Clause := First (Context_Items (Comp));
2012                            while Present (With_Clause) loop
2013                               if Nkind (With_Clause) = N_With_Clause
2014                                 and then
2015                                   Scope (Entity (Name (With_Clause))) = P
2016                                 and then
2017                                   Entity (Name (With_Clause)) = Child_Spec
2018                               then
2019                                  Error_Msg_Node_2 := Child_Spec;
2020                                  Error_Msg_NE
2021                                    ("body of & depends on child unit&??",
2022                                     With_Clause, P);
2023                                  Error_Msg_N
2024                                    ("\subprograms in body cannot be inlined??",
2025                                     With_Clause);
2026
2027                                  --  Disable further inlining from this unit,
2028                                  --  and keep Taft-amendment types incomplete.
2029
2030                                  Ent := First_Entity (P);
2031                                  while Present (Ent) loop
2032                                     if Is_Type (Ent)
2033                                       and then Has_Completion_In_Body (Ent)
2034                                     then
2035                                        Set_Full_View (Ent, Empty);
2036
2037                                     elsif Is_Subprogram (Ent) then
2038                                        Set_Is_Inlined (Ent, False);
2039                                     end if;
2040
2041                                     Next_Entity (Ent);
2042                                  end loop;
2043
2044                                  return;
2045                               end if;
2046
2047                               Next (With_Clause);
2048                            end loop;
2049                         end if;
2050                      end;
2051
2052                   elsif Ineffective_Inline_Warnings then
2053                      Error_Msg_Unit_1 := Bname;
2054                      Error_Msg_N
2055                        ("unable to inline subprograms defined in $??", P);
2056                      Error_Msg_N ("\body not found??", P);
2057                      return;
2058                   end if;
2059                end if;
2060
2061                return;
2062             end if;
2063
2064             Next_Entity (E);
2065          end loop;
2066       end if;
2067    end Check_Package_Body_For_Inlining;
2068
2069    --------------------
2070    -- Cleanup_Scopes --
2071    --------------------
2072
2073    procedure Cleanup_Scopes is
2074       Elmt : Elmt_Id;
2075       Decl : Node_Id;
2076       Scop : Entity_Id;
2077
2078    begin
2079       Elmt := First_Elmt (To_Clean);
2080       while Present (Elmt) loop
2081          Scop := Node (Elmt);
2082
2083          if Ekind (Scop) = E_Entry then
2084             Scop := Protected_Body_Subprogram (Scop);
2085
2086          elsif Is_Subprogram (Scop)
2087            and then Is_Protected_Type (Scope (Scop))
2088            and then Present (Protected_Body_Subprogram (Scop))
2089          then
2090             --  If a protected operation contains an instance, its cleanup
2091             --  operations have been delayed, and the subprogram has been
2092             --  rewritten in the expansion of the enclosing protected body. It
2093             --  is the corresponding subprogram that may require the cleanup
2094             --  operations, so propagate the information that triggers cleanup
2095             --  activity.
2096
2097             Set_Uses_Sec_Stack
2098               (Protected_Body_Subprogram (Scop),
2099                 Uses_Sec_Stack (Scop));
2100
2101             Scop := Protected_Body_Subprogram (Scop);
2102          end if;
2103
2104          if Ekind (Scop) = E_Block then
2105             Decl := Parent (Block_Node (Scop));
2106
2107          else
2108             Decl := Unit_Declaration_Node (Scop);
2109
2110             if Nkind_In (Decl, N_Subprogram_Declaration,
2111                                N_Task_Type_Declaration,
2112                                N_Subprogram_Body_Stub)
2113             then
2114                Decl := Unit_Declaration_Node (Corresponding_Body (Decl));
2115             end if;
2116          end if;
2117
2118          Push_Scope (Scop);
2119          Expand_Cleanup_Actions (Decl);
2120          End_Scope;
2121
2122          Elmt := Next_Elmt (Elmt);
2123       end loop;
2124    end Cleanup_Scopes;
2125
2126    -------------------------
2127    -- Expand_Inlined_Call --
2128    -------------------------
2129
2130    procedure Expand_Inlined_Call
2131     (N         : Node_Id;
2132      Subp      : Entity_Id;
2133      Orig_Subp : Entity_Id)
2134    is
2135       Loc       : constant Source_Ptr := Sloc (N);
2136       Is_Predef : constant Boolean :=
2137                     Is_Predefined_File_Name
2138                       (Unit_File_Name (Get_Source_Unit (Subp)));
2139       Orig_Bod  : constant Node_Id :=
2140                     Body_To_Inline (Unit_Declaration_Node (Subp));
2141
2142       Blk      : Node_Id;
2143       Decl     : Node_Id;
2144       Decls    : constant List_Id := New_List;
2145       Exit_Lab : Entity_Id        := Empty;
2146       F        : Entity_Id;
2147       A        : Node_Id;
2148       Lab_Decl : Node_Id;
2149       Lab_Id   : Node_Id;
2150       New_A    : Node_Id;
2151       Num_Ret  : Int := 0;
2152       Ret_Type : Entity_Id;
2153
2154       Targ : Node_Id;
2155       --  The target of the call. If context is an assignment statement then
2156       --  this is the left-hand side of the assignment, else it is a temporary
2157       --  to which the return value is assigned prior to rewriting the call.
2158
2159       Targ1 : Node_Id;
2160       --  A separate target used when the return type is unconstrained
2161
2162       Temp     : Entity_Id;
2163       Temp_Typ : Entity_Id;
2164
2165       Return_Object : Entity_Id := Empty;
2166       --  Entity in declaration in an extended_return_statement
2167
2168       Is_Unc      : Boolean;
2169       Is_Unc_Decl : Boolean;
2170       --  If the type returned by the function is unconstrained and the call
2171       --  can be inlined, special processing is required.
2172
2173       procedure Make_Exit_Label;
2174       --  Build declaration for exit label to be used in Return statements,
2175       --  sets Exit_Lab (the label node) and Lab_Decl (corresponding implicit
2176       --  declaration). Does nothing if Exit_Lab already set.
2177
2178       function Process_Formals (N : Node_Id) return Traverse_Result;
2179       --  Replace occurrence of a formal with the corresponding actual, or the
2180       --  thunk generated for it. Replace a return statement with an assignment
2181       --  to the target of the call, with appropriate conversions if needed.
2182
2183       function Process_Sloc (Nod : Node_Id) return Traverse_Result;
2184       --  If the call being expanded is that of an internal subprogram, set the
2185       --  sloc of the generated block to that of the call itself, so that the
2186       --  expansion is skipped by the "next" command in gdb. Same processing
2187       --  for a subprogram in a predefined file, e.g. Ada.Tags. If
2188       --  Debug_Generated_Code is true, suppress this change to simplify our
2189       --  own development. Same in GNATprove mode, to ensure that warnings and
2190       --  diagnostics point to the proper location.
2191
2192       procedure Reset_Dispatching_Calls (N : Node_Id);
2193       --  In subtree N search for occurrences of dispatching calls that use the
2194       --  Ada 2005 Object.Operation notation and the object is a formal of the
2195       --  inlined subprogram. Reset the entity associated with Operation in all
2196       --  the found occurrences.
2197
2198       procedure Rewrite_Function_Call (N : Node_Id; Blk : Node_Id);
2199       --  If the function body is a single expression, replace call with
2200       --  expression, else insert block appropriately.
2201
2202       procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id);
2203       --  If procedure body has no local variables, inline body without
2204       --  creating block, otherwise rewrite call with block.
2205
2206       function Formal_Is_Used_Once (Formal : Entity_Id) return Boolean;
2207       --  Determine whether a formal parameter is used only once in Orig_Bod
2208
2209       ---------------------
2210       -- Make_Exit_Label --
2211       ---------------------
2212
2213       procedure Make_Exit_Label is
2214          Lab_Ent : Entity_Id;
2215       begin
2216          if No (Exit_Lab) then
2217             Lab_Ent := Make_Temporary (Loc, 'L');
2218             Lab_Id  := New_Occurrence_Of (Lab_Ent, Loc);
2219             Exit_Lab := Make_Label (Loc, Lab_Id);
2220             Lab_Decl :=
2221               Make_Implicit_Label_Declaration (Loc,
2222                 Defining_Identifier => Lab_Ent,
2223                 Label_Construct     => Exit_Lab);
2224          end if;
2225       end Make_Exit_Label;
2226
2227       ---------------------
2228       -- Process_Formals --
2229       ---------------------
2230
2231       function Process_Formals (N : Node_Id) return Traverse_Result is
2232          A   : Entity_Id;
2233          E   : Entity_Id;
2234          Ret : Node_Id;
2235
2236       begin
2237          if Is_Entity_Name (N) and then Present (Entity (N)) then
2238             E := Entity (N);
2239
2240             if Is_Formal (E) and then Scope (E) = Subp then
2241                A := Renamed_Object (E);
2242
2243                --  Rewrite the occurrence of the formal into an occurrence of
2244                --  the actual. Also establish visibility on the proper view of
2245                --  the actual's subtype for the body's context (if the actual's
2246                --  subtype is private at the call point but its full view is
2247                --  visible to the body, then the inlined tree here must be
2248                --  analyzed with the full view).
2249
2250                if Is_Entity_Name (A) then
2251                   Rewrite (N, New_Occurrence_Of (Entity (A), Loc));
2252                   Check_Private_View (N);
2253
2254                elsif Nkind (A) = N_Defining_Identifier then
2255                   Rewrite (N, New_Occurrence_Of (A, Loc));
2256                   Check_Private_View (N);
2257
2258                --  Numeric literal
2259
2260                else
2261                   Rewrite (N, New_Copy (A));
2262                end if;
2263             end if;
2264
2265             return Skip;
2266
2267          elsif Is_Entity_Name (N)
2268            and then Present (Return_Object)
2269            and then Chars (N) = Chars (Return_Object)
2270          then
2271             --  Occurrence within an extended return statement. The return
2272             --  object is local to the body been inlined, and thus the generic
2273             --  copy is not analyzed yet, so we match by name, and replace it
2274             --  with target of call.
2275
2276             if Nkind (Targ) = N_Defining_Identifier then
2277                Rewrite (N, New_Occurrence_Of (Targ, Loc));
2278             else
2279                Rewrite (N, New_Copy_Tree (Targ));
2280             end if;
2281
2282             return Skip;
2283
2284          elsif Nkind (N) = N_Simple_Return_Statement then
2285             if No (Expression (N)) then
2286                Make_Exit_Label;
2287                Rewrite (N,
2288                  Make_Goto_Statement (Loc, Name => New_Copy (Lab_Id)));
2289
2290             else
2291                if Nkind (Parent (N)) = N_Handled_Sequence_Of_Statements
2292                  and then Nkind (Parent (Parent (N))) = N_Subprogram_Body
2293                then
2294                   --  Function body is a single expression. No need for
2295                   --  exit label.
2296
2297                   null;
2298
2299                else
2300                   Num_Ret := Num_Ret + 1;
2301                   Make_Exit_Label;
2302                end if;
2303
2304                --  Because of the presence of private types, the views of the
2305                --  expression and the context may be different, so place an
2306                --  unchecked conversion to the context type to avoid spurious
2307                --  errors, e.g. when the expression is a numeric literal and
2308                --  the context is private. If the expression is an aggregate,
2309                --  use a qualified expression, because an aggregate is not a
2310                --  legal argument of a conversion. Ditto for numeric literals,
2311                --  which must be resolved to a specific type.
2312
2313                if Nkind_In (Expression (N), N_Aggregate,
2314                                             N_Null,
2315                                             N_Real_Literal,
2316                                             N_Integer_Literal)
2317                then
2318                   Ret :=
2319                     Make_Qualified_Expression (Sloc (N),
2320                       Subtype_Mark => New_Occurrence_Of (Ret_Type, Sloc (N)),
2321                       Expression   => Relocate_Node (Expression (N)));
2322                else
2323                   Ret :=
2324                     Unchecked_Convert_To
2325                       (Ret_Type, Relocate_Node (Expression (N)));
2326                end if;
2327
2328                if Nkind (Targ) = N_Defining_Identifier then
2329                   Rewrite (N,
2330                     Make_Assignment_Statement (Loc,
2331                       Name       => New_Occurrence_Of (Targ, Loc),
2332                       Expression => Ret));
2333                else
2334                   Rewrite (N,
2335                     Make_Assignment_Statement (Loc,
2336                       Name       => New_Copy (Targ),
2337                       Expression => Ret));
2338                end if;
2339
2340                Set_Assignment_OK (Name (N));
2341
2342                if Present (Exit_Lab) then
2343                   Insert_After (N,
2344                     Make_Goto_Statement (Loc, Name => New_Copy (Lab_Id)));
2345                end if;
2346             end if;
2347
2348             return OK;
2349
2350          --  An extended return becomes a block whose first statement is the
2351          --  assignment of the initial expression of the return object to the
2352          --  target of the call itself.
2353
2354          elsif Nkind (N) = N_Extended_Return_Statement then
2355             declare
2356                Return_Decl : constant Entity_Id :=
2357                                First (Return_Object_Declarations (N));
2358                Assign      : Node_Id;
2359
2360             begin
2361                Return_Object := Defining_Identifier (Return_Decl);
2362
2363                if Present (Expression (Return_Decl)) then
2364                   if Nkind (Targ) = N_Defining_Identifier then
2365                      Assign :=
2366                        Make_Assignment_Statement (Loc,
2367                          Name       => New_Occurrence_Of (Targ, Loc),
2368                          Expression => Expression (Return_Decl));
2369                   else
2370                      Assign :=
2371                        Make_Assignment_Statement (Loc,
2372                          Name       => New_Copy (Targ),
2373                          Expression => Expression (Return_Decl));
2374                   end if;
2375
2376                   Set_Assignment_OK (Name (Assign));
2377
2378                   if No (Handled_Statement_Sequence (N)) then
2379                      Set_Handled_Statement_Sequence (N,
2380                        Make_Handled_Sequence_Of_Statements (Loc,
2381                          Statements => New_List));
2382                   end if;
2383
2384                   Prepend (Assign,
2385                     Statements (Handled_Statement_Sequence (N)));
2386                end if;
2387
2388                Rewrite (N,
2389                  Make_Block_Statement (Loc,
2390                     Handled_Statement_Sequence =>
2391                       Handled_Statement_Sequence (N)));
2392
2393                return OK;
2394             end;
2395
2396          --  Remove pragma Unreferenced since it may refer to formals that
2397          --  are not visible in the inlined body, and in any case we will
2398          --  not be posting warnings on the inlined body so it is unneeded.
2399
2400          elsif Nkind (N) = N_Pragma
2401            and then Pragma_Name (N) = Name_Unreferenced
2402          then
2403             Rewrite (N, Make_Null_Statement (Sloc (N)));
2404             return OK;
2405
2406          else
2407             return OK;
2408          end if;
2409       end Process_Formals;
2410
2411       procedure Replace_Formals is new Traverse_Proc (Process_Formals);
2412
2413       ------------------
2414       -- Process_Sloc --
2415       ------------------
2416
2417       function Process_Sloc (Nod : Node_Id) return Traverse_Result is
2418       begin
2419          if not Debug_Generated_Code then
2420             Set_Sloc (Nod, Sloc (N));
2421             Set_Comes_From_Source (Nod, False);
2422          end if;
2423
2424          return OK;
2425       end Process_Sloc;
2426
2427       procedure Reset_Slocs is new Traverse_Proc (Process_Sloc);
2428
2429       ------------------------------
2430       --  Reset_Dispatching_Calls --
2431       ------------------------------
2432
2433       procedure Reset_Dispatching_Calls (N : Node_Id) is
2434
2435          function Do_Reset (N : Node_Id) return Traverse_Result;
2436          --  Comment required ???
2437
2438          --------------
2439          -- Do_Reset --
2440          --------------
2441
2442          function Do_Reset (N : Node_Id) return Traverse_Result is
2443          begin
2444             if Nkind (N) = N_Procedure_Call_Statement
2445               and then Nkind (Name (N)) = N_Selected_Component
2446               and then Nkind (Prefix (Name (N))) = N_Identifier
2447               and then Is_Formal (Entity (Prefix (Name (N))))
2448               and then Is_Dispatching_Operation
2449                          (Entity (Selector_Name (Name (N))))
2450             then
2451                Set_Entity (Selector_Name (Name (N)), Empty);
2452             end if;
2453
2454             return OK;
2455          end Do_Reset;
2456
2457          function Do_Reset_Calls is new Traverse_Func (Do_Reset);
2458
2459          --  Local variables
2460
2461          Dummy : constant Traverse_Result := Do_Reset_Calls (N);
2462          pragma Unreferenced (Dummy);
2463
2464          --  Start of processing for Reset_Dispatching_Calls
2465
2466       begin
2467          null;
2468       end Reset_Dispatching_Calls;
2469
2470       ---------------------------
2471       -- Rewrite_Function_Call --
2472       ---------------------------
2473
2474       procedure Rewrite_Function_Call (N : Node_Id; Blk : Node_Id) is
2475          HSS : constant Node_Id := Handled_Statement_Sequence (Blk);
2476          Fst : constant Node_Id := First (Statements (HSS));
2477
2478       begin
2479          --  Optimize simple case: function body is a single return statement,
2480          --  which has been expanded into an assignment.
2481
2482          if Is_Empty_List (Declarations (Blk))
2483            and then Nkind (Fst) = N_Assignment_Statement
2484            and then No (Next (Fst))
2485          then
2486             --  The function call may have been rewritten as the temporary
2487             --  that holds the result of the call, in which case remove the
2488             --  now useless declaration.
2489
2490             if Nkind (N) = N_Identifier
2491               and then Nkind (Parent (Entity (N))) = N_Object_Declaration
2492             then
2493                Rewrite (Parent (Entity (N)), Make_Null_Statement (Loc));
2494             end if;
2495
2496             Rewrite (N, Expression (Fst));
2497
2498          elsif Nkind (N) = N_Identifier
2499            and then Nkind (Parent (Entity (N))) = N_Object_Declaration
2500          then
2501             --  The block assigns the result of the call to the temporary
2502
2503             Insert_After (Parent (Entity (N)), Blk);
2504
2505          --  If the context is an assignment, and the left-hand side is free of
2506          --  side-effects, the replacement is also safe.
2507          --  Can this be generalized further???
2508
2509          elsif Nkind (Parent (N)) = N_Assignment_Statement
2510            and then
2511             (Is_Entity_Name (Name (Parent (N)))
2512               or else
2513                 (Nkind (Name (Parent (N))) = N_Explicit_Dereference
2514                   and then Is_Entity_Name (Prefix (Name (Parent (N)))))
2515
2516               or else
2517                 (Nkind (Name (Parent (N))) = N_Selected_Component
2518                   and then Is_Entity_Name (Prefix (Name (Parent (N))))))
2519          then
2520             --  Replace assignment with the block
2521
2522             declare
2523                Original_Assignment : constant Node_Id := Parent (N);
2524
2525             begin
2526                --  Preserve the original assignment node to keep the complete
2527                --  assignment subtree consistent enough for Analyze_Assignment
2528                --  to proceed (specifically, the original Lhs node must still
2529                --  have an assignment statement as its parent).
2530
2531                --  We cannot rely on Original_Node to go back from the block
2532                --  node to the assignment node, because the assignment might
2533                --  already be a rewrite substitution.
2534
2535                Discard_Node (Relocate_Node (Original_Assignment));
2536                Rewrite (Original_Assignment, Blk);
2537             end;
2538
2539          elsif Nkind (Parent (N)) = N_Object_Declaration then
2540
2541             --  A call to a function which returns an unconstrained type
2542             --  found in the expression initializing an object-declaration is
2543             --  expanded into a procedure call which must be added after the
2544             --  object declaration.
2545
2546             if Is_Unc_Decl and Back_End_Inlining then
2547                Insert_Action_After (Parent (N), Blk);
2548             else
2549                Set_Expression (Parent (N), Empty);
2550                Insert_After (Parent (N), Blk);
2551             end if;
2552
2553          elsif Is_Unc and then not Back_End_Inlining then
2554             Insert_Before (Parent (N), Blk);
2555          end if;
2556       end Rewrite_Function_Call;
2557
2558       ----------------------------
2559       -- Rewrite_Procedure_Call --
2560       ----------------------------
2561
2562       procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id) is
2563          HSS  : constant Node_Id := Handled_Statement_Sequence (Blk);
2564
2565       begin
2566          --  If there is a transient scope for N, this will be the scope of the
2567          --  actions for N, and the statements in Blk need to be within this
2568          --  scope. For example, they need to have visibility on the constant
2569          --  declarations created for the formals.
2570
2571          --  If N needs no transient scope, and if there are no declarations in
2572          --  the inlined body, we can do a little optimization and insert the
2573          --  statements for the body directly after N, and rewrite N to a
2574          --  null statement, instead of rewriting N into a full-blown block
2575          --  statement.
2576
2577          if not Scope_Is_Transient
2578            and then Is_Empty_List (Declarations (Blk))
2579          then
2580             Insert_List_After (N, Statements (HSS));
2581             Rewrite (N, Make_Null_Statement (Loc));
2582          else
2583             Rewrite (N, Blk);
2584          end if;
2585       end Rewrite_Procedure_Call;
2586
2587       -------------------------
2588       -- Formal_Is_Used_Once --
2589       -------------------------
2590
2591       function Formal_Is_Used_Once (Formal : Entity_Id) return Boolean is
2592          Use_Counter : Int := 0;
2593
2594          function Count_Uses (N : Node_Id) return Traverse_Result;
2595          --  Traverse the tree and count the uses of the formal parameter.
2596          --  In this case, for optimization purposes, we do not need to
2597          --  continue the traversal once more than one use is encountered.
2598
2599          ----------------
2600          -- Count_Uses --
2601          ----------------
2602
2603          function Count_Uses (N : Node_Id) return Traverse_Result is
2604          begin
2605             --  The original node is an identifier
2606
2607             if Nkind (N) = N_Identifier
2608               and then Present (Entity (N))
2609
2610                --  Original node's entity points to the one in the copied body
2611
2612               and then Nkind (Entity (N)) = N_Identifier
2613               and then Present (Entity (Entity (N)))
2614
2615                --  The entity of the copied node is the formal parameter
2616
2617               and then Entity (Entity (N)) = Formal
2618             then
2619                Use_Counter := Use_Counter + 1;
2620
2621                if Use_Counter > 1 then
2622
2623                   --  Denote more than one use and abandon the traversal
2624
2625                   Use_Counter := 2;
2626                   return Abandon;
2627
2628                end if;
2629             end if;
2630
2631             return OK;
2632          end Count_Uses;
2633
2634          procedure Count_Formal_Uses is new Traverse_Proc (Count_Uses);
2635
2636       --  Start of processing for Formal_Is_Used_Once
2637
2638       begin
2639          Count_Formal_Uses (Orig_Bod);
2640          return Use_Counter = 1;
2641       end Formal_Is_Used_Once;
2642
2643    --  Start of processing for Expand_Inlined_Call
2644
2645    begin
2646       --  Initializations for old/new semantics
2647
2648       if not Back_End_Inlining then
2649          Is_Unc      := Is_Array_Type (Etype (Subp))
2650                           and then not Is_Constrained (Etype (Subp));
2651          Is_Unc_Decl := False;
2652       else
2653          Is_Unc      := Returns_Unconstrained_Type (Subp)
2654                           and then Optimization_Level > 0;
2655          Is_Unc_Decl := Nkind (Parent (N)) = N_Object_Declaration
2656                           and then Is_Unc;
2657       end if;
2658
2659       --  Check for an illegal attempt to inline a recursive procedure. If the
2660       --  subprogram has parameters this is detected when trying to supply a
2661       --  binding for parameters that already have one. For parameterless
2662       --  subprograms this must be done explicitly.
2663
2664       if In_Open_Scopes (Subp) then
2665          Error_Msg_N ("call to recursive subprogram cannot be inlined??", N);
2666          Set_Is_Inlined (Subp, False);
2667
2668          --  In GNATprove mode, issue a warning, and indicate that the
2669          --  subprogram is not always inlined by setting flag Is_Inlined_Always
2670          --  to False.
2671
2672          if GNATprove_Mode then
2673             Set_Is_Inlined_Always (Subp, False);
2674          end if;
2675
2676          return;
2677
2678       --  Skip inlining if this is not a true inlining since the attribute
2679       --  Body_To_Inline is also set for renamings (see sinfo.ads)
2680
2681       elsif Nkind (Orig_Bod) in N_Entity then
2682          if not Has_Pragma_Inline (Subp) then
2683             return;
2684          end if;
2685
2686       --  Skip inlining if the function returns an unconstrained type using
2687       --  an extended return statement since this part of the new inlining
2688       --  model which is not yet supported by the current implementation. ???
2689
2690       elsif Is_Unc
2691         and then
2692           Nkind (First (Statements (Handled_Statement_Sequence (Orig_Bod))))
2693             = N_Extended_Return_Statement
2694         and then not Back_End_Inlining
2695       then
2696          return;
2697       end if;
2698
2699       if Nkind (Orig_Bod) = N_Defining_Identifier
2700         or else Nkind (Orig_Bod) = N_Defining_Operator_Symbol
2701       then
2702          --  Subprogram is renaming_as_body. Calls occurring after the renaming
2703          --  can be replaced with calls to the renamed entity directly, because
2704          --  the subprograms are subtype conformant. If the renamed subprogram
2705          --  is an inherited operation, we must redo the expansion because
2706          --  implicit conversions may be needed. Similarly, if the renamed
2707          --  entity is inlined, expand the call for further optimizations.
2708
2709          Set_Name (N, New_Occurrence_Of (Orig_Bod, Loc));
2710
2711          if Present (Alias (Orig_Bod)) or else Is_Inlined (Orig_Bod) then
2712             Expand_Call (N);
2713          end if;
2714
2715          return;
2716       end if;
2717
2718       --  Register the call in the list of inlined calls
2719
2720       Append_New_Elmt (N, To => Inlined_Calls);
2721
2722       --  Use generic machinery to copy body of inlined subprogram, as if it
2723       --  were an instantiation, resetting source locations appropriately, so
2724       --  that nested inlined calls appear in the main unit.
2725
2726       Save_Env (Subp, Empty);
2727       Set_Copied_Sloc_For_Inlined_Body (N, Defining_Entity (Orig_Bod));
2728
2729       --  Old semantics
2730
2731       if not Back_End_Inlining then
2732          declare
2733             Bod : Node_Id;
2734
2735          begin
2736             Bod := Copy_Generic_Node (Orig_Bod, Empty, Instantiating => True);
2737             Blk :=
2738               Make_Block_Statement (Loc,
2739                 Declarations               => Declarations (Bod),
2740                 Handled_Statement_Sequence =>
2741                   Handled_Statement_Sequence (Bod));
2742
2743             if No (Declarations (Bod)) then
2744                Set_Declarations (Blk, New_List);
2745             end if;
2746
2747             --  For the unconstrained case, capture the name of the local
2748             --  variable that holds the result. This must be the first
2749             --  declaration in the block, because its bounds cannot depend
2750             --  on local variables. Otherwise there is no way to declare the
2751             --  result outside of the block. Needless to say, in general the
2752             --  bounds will depend on the actuals in the call.
2753
2754             --  If the context is an assignment statement, as is the case
2755             --  for the expansion of an extended return, the left-hand side
2756             --  provides bounds even if the return type is unconstrained.
2757
2758             if Is_Unc then
2759                declare
2760                   First_Decl : Node_Id;
2761
2762                begin
2763                   First_Decl := First (Declarations (Blk));
2764
2765                   if Nkind (First_Decl) /= N_Object_Declaration then
2766                      return;
2767                   end if;
2768
2769                   if Nkind (Parent (N)) /= N_Assignment_Statement then
2770                      Targ1 := Defining_Identifier (First_Decl);
2771                   else
2772                      Targ1 := Name (Parent (N));
2773                   end if;
2774                end;
2775             end if;
2776          end;
2777
2778       --  New semantics
2779
2780       else
2781          declare
2782             Bod : Node_Id;
2783
2784          begin
2785             --  General case
2786
2787             if not Is_Unc then
2788                Bod :=
2789                  Copy_Generic_Node (Orig_Bod, Empty, Instantiating => True);
2790                Blk :=
2791                  Make_Block_Statement (Loc,
2792                    Declarations               => Declarations (Bod),
2793                    Handled_Statement_Sequence =>
2794                      Handled_Statement_Sequence (Bod));
2795
2796             --  Inline a call to a function that returns an unconstrained type.
2797             --  The semantic analyzer checked that frontend-inlined functions
2798             --  returning unconstrained types have no declarations and have
2799             --  a single extended return statement. As part of its processing
2800             --  the function was split in two subprograms: a procedure P and
2801             --  a function F that has a block with a call to procedure P (see
2802             --  Split_Unconstrained_Function).
2803
2804             else
2805                pragma Assert
2806                  (Nkind
2807                    (First
2808                      (Statements (Handled_Statement_Sequence (Orig_Bod)))) =
2809                                                          N_Block_Statement);
2810
2811                declare
2812                   Blk_Stmt    : constant Node_Id :=
2813                     First (Statements (Handled_Statement_Sequence (Orig_Bod)));
2814                   First_Stmt  : constant Node_Id :=
2815                     First (Statements (Handled_Statement_Sequence (Blk_Stmt)));
2816                   Second_Stmt : constant Node_Id := Next (First_Stmt);
2817
2818                begin
2819                   pragma Assert
2820                     (Nkind (First_Stmt) = N_Procedure_Call_Statement
2821                       and then Nkind (Second_Stmt) = N_Simple_Return_Statement
2822                       and then No (Next (Second_Stmt)));
2823
2824                   Bod :=
2825                     Copy_Generic_Node
2826                       (First
2827                         (Statements (Handled_Statement_Sequence (Orig_Bod))),
2828                        Empty, Instantiating => True);
2829                   Blk := Bod;
2830
2831                   --  Capture the name of the local variable that holds the
2832                   --  result. This must be the first declaration in the block,
2833                   --  because its bounds cannot depend on local variables.
2834                   --  Otherwise there is no way to declare the result outside
2835                   --  of the block. Needless to say, in general the bounds will
2836                   --  depend on the actuals in the call.
2837
2838                   if Nkind (Parent (N)) /= N_Assignment_Statement then
2839                      Targ1 := Defining_Identifier (First (Declarations (Blk)));
2840
2841                   --  If the context is an assignment statement, as is the case
2842                   --  for the expansion of an extended return, the left-hand
2843                   --  side provides bounds even if the return type is
2844                   --  unconstrained.
2845
2846                   else
2847                      Targ1 := Name (Parent (N));
2848                   end if;
2849                end;
2850             end if;
2851
2852             if No (Declarations (Bod)) then
2853                Set_Declarations (Blk, New_List);
2854             end if;
2855          end;
2856       end if;
2857
2858       --  If this is a derived function, establish the proper return type
2859
2860       if Present (Orig_Subp) and then Orig_Subp /= Subp then
2861          Ret_Type := Etype (Orig_Subp);
2862       else
2863          Ret_Type := Etype (Subp);
2864       end if;
2865
2866       --  Create temporaries for the actuals that are expressions, or that are
2867       --  scalars and require copying to preserve semantics.
2868
2869       F := First_Formal (Subp);
2870       A := First_Actual (N);
2871       while Present (F) loop
2872          if Present (Renamed_Object (F)) then
2873
2874             --  If expander is active, it is an error to try to inline a
2875             --  recursive program. In GNATprove mode, just indicate that the
2876             --  inlining will not happen, and mark the subprogram as not always
2877             --  inlined.
2878
2879             if GNATprove_Mode then
2880                Cannot_Inline
2881                  ("cannot inline call to recursive subprogram?", N, Subp);
2882                Set_Is_Inlined_Always (Subp, False);
2883             else
2884                Error_Msg_N
2885                  ("cannot inline call to recursive subprogram", N);
2886             end if;
2887
2888             return;
2889          end if;
2890
2891          --  Reset Last_Assignment for any parameters of mode out or in out, to
2892          --  prevent spurious warnings about overwriting for assignments to the
2893          --  formal in the inlined code.
2894
2895          if Is_Entity_Name (A) and then Ekind (F) /= E_In_Parameter then
2896             Set_Last_Assignment (Entity (A), Empty);
2897          end if;
2898
2899          --  If the argument may be a controlling argument in a call within
2900          --  the inlined body, we must preserve its classwide nature to insure
2901          --  that dynamic dispatching take place subsequently. If the formal
2902          --  has a constraint it must be preserved to retain the semantics of
2903          --  the body.
2904
2905          if Is_Class_Wide_Type (Etype (F))
2906            or else (Is_Access_Type (Etype (F))
2907                      and then Is_Class_Wide_Type (Designated_Type (Etype (F))))
2908          then
2909             Temp_Typ := Etype (F);
2910
2911          elsif Base_Type (Etype (F)) = Base_Type (Etype (A))
2912            and then Etype (F) /= Base_Type (Etype (F))
2913          then
2914             Temp_Typ := Etype (F);
2915          else
2916             Temp_Typ := Etype (A);
2917          end if;
2918
2919          --  If the actual is a simple name or a literal, no need to
2920          --  create a temporary, object can be used directly.
2921
2922          --  If the actual is a literal and the formal has its address taken,
2923          --  we cannot pass the literal itself as an argument, so its value
2924          --  must be captured in a temporary.
2925
2926          if (Is_Entity_Name (A)
2927               and then
2928                (not Is_Scalar_Type (Etype (A))
2929                  or else Ekind (Entity (A)) = E_Enumeration_Literal))
2930
2931          --  When the actual is an identifier and the corresponding formal is
2932          --  used only once in the original body, the formal can be substituted
2933          --  directly with the actual parameter.
2934
2935            or else (Nkind (A) = N_Identifier
2936              and then Formal_Is_Used_Once (F))
2937
2938            or else
2939              (Nkind_In (A, N_Real_Literal,
2940                            N_Integer_Literal,
2941                            N_Character_Literal)
2942                and then not Address_Taken (F))
2943          then
2944             if Etype (F) /= Etype (A) then
2945                Set_Renamed_Object
2946                  (F, Unchecked_Convert_To (Etype (F), Relocate_Node (A)));
2947             else
2948                Set_Renamed_Object (F, A);
2949             end if;
2950
2951          else
2952             Temp := Make_Temporary (Loc, 'C');
2953
2954             --  If the actual for an in/in-out parameter is a view conversion,
2955             --  make it into an unchecked conversion, given that an untagged
2956             --  type conversion is not a proper object for a renaming.
2957
2958             --  In-out conversions that involve real conversions have already
2959             --  been transformed in Expand_Actuals.
2960
2961             if Nkind (A) = N_Type_Conversion
2962               and then Ekind (F) /= E_In_Parameter
2963             then
2964                New_A :=
2965                  Make_Unchecked_Type_Conversion (Loc,
2966                    Subtype_Mark => New_Occurrence_Of (Etype (F), Loc),
2967                    Expression   => Relocate_Node (Expression (A)));
2968
2969             elsif Etype (F) /= Etype (A) then
2970                New_A := Unchecked_Convert_To (Etype (F), Relocate_Node (A));
2971                Temp_Typ := Etype (F);
2972
2973             else
2974                New_A := Relocate_Node (A);
2975             end if;
2976
2977             Set_Sloc (New_A, Sloc (N));
2978
2979             --  If the actual has a by-reference type, it cannot be copied,
2980             --  so its value is captured in a renaming declaration. Otherwise
2981             --  declare a local constant initialized with the actual.
2982
2983             --  We also use a renaming declaration for expressions of an array
2984             --  type that is not bit-packed, both for efficiency reasons and to
2985             --  respect the semantics of the call: in most cases the original
2986             --  call will pass the parameter by reference, and thus the inlined
2987             --  code will have the same semantics.
2988
2989             --  Finally, we need a renaming declaration in the case of limited
2990             --  types for which initialization cannot be by copy either.
2991
2992             if Ekind (F) = E_In_Parameter
2993               and then not Is_By_Reference_Type (Etype (A))
2994               and then not Is_Limited_Type (Etype (A))
2995               and then
2996                 (not Is_Array_Type (Etype (A))
2997                   or else not Is_Object_Reference (A)
2998                   or else Is_Bit_Packed_Array (Etype (A)))
2999             then
3000                Decl :=
3001                  Make_Object_Declaration (Loc,
3002                    Defining_Identifier => Temp,
3003                    Constant_Present    => True,
3004                    Object_Definition   => New_Occurrence_Of (Temp_Typ, Loc),
3005                    Expression          => New_A);
3006             else
3007                Decl :=
3008                  Make_Object_Renaming_Declaration (Loc,
3009                    Defining_Identifier => Temp,
3010                    Subtype_Mark        => New_Occurrence_Of (Temp_Typ, Loc),
3011                    Name                => New_A);
3012             end if;
3013
3014             Append (Decl, Decls);
3015             Set_Renamed_Object (F, Temp);
3016          end if;
3017
3018          Next_Formal (F);
3019          Next_Actual (A);
3020       end loop;
3021
3022       --  Establish target of function call. If context is not assignment or
3023       --  declaration, create a temporary as a target. The declaration for the
3024       --  temporary may be subsequently optimized away if the body is a single
3025       --  expression, or if the left-hand side of the assignment is simple
3026       --  enough, i.e. an entity or an explicit dereference of one.
3027
3028       if Ekind (Subp) = E_Function then
3029          if Nkind (Parent (N)) = N_Assignment_Statement
3030            and then Is_Entity_Name (Name (Parent (N)))
3031          then
3032             Targ := Name (Parent (N));
3033
3034          elsif Nkind (Parent (N)) = N_Assignment_Statement
3035            and then Nkind (Name (Parent (N))) = N_Explicit_Dereference
3036            and then Is_Entity_Name (Prefix (Name (Parent (N))))
3037          then
3038             Targ := Name (Parent (N));
3039
3040          elsif Nkind (Parent (N)) = N_Assignment_Statement
3041            and then Nkind (Name (Parent (N))) = N_Selected_Component
3042            and then Is_Entity_Name (Prefix (Name (Parent (N))))
3043          then
3044             Targ := New_Copy_Tree (Name (Parent (N)));
3045
3046          elsif Nkind (Parent (N)) = N_Object_Declaration
3047            and then Is_Limited_Type (Etype (Subp))
3048          then
3049             Targ := Defining_Identifier (Parent (N));
3050
3051          --  New semantics: In an object declaration avoid an extra copy
3052          --  of the result of a call to an inlined function that returns
3053          --  an unconstrained type
3054
3055          elsif Back_End_Inlining
3056            and then Nkind (Parent (N)) = N_Object_Declaration
3057            and then Is_Unc
3058          then
3059             Targ := Defining_Identifier (Parent (N));
3060
3061          else
3062             --  Replace call with temporary and create its declaration
3063
3064             Temp := Make_Temporary (Loc, 'C');
3065             Set_Is_Internal (Temp);
3066
3067             --  For the unconstrained case, the generated temporary has the
3068             --  same constrained declaration as the result variable. It may
3069             --  eventually be possible to remove that temporary and use the
3070             --  result variable directly.
3071
3072             if Is_Unc and then Nkind (Parent (N)) /= N_Assignment_Statement
3073             then
3074                Decl :=
3075                  Make_Object_Declaration (Loc,
3076                    Defining_Identifier => Temp,
3077                    Object_Definition   =>
3078                      New_Copy_Tree (Object_Definition (Parent (Targ1))));
3079
3080                Replace_Formals (Decl);
3081
3082             else
3083                Decl :=
3084                  Make_Object_Declaration (Loc,
3085                    Defining_Identifier => Temp,
3086                    Object_Definition   => New_Occurrence_Of (Ret_Type, Loc));
3087
3088                Set_Etype (Temp, Ret_Type);
3089             end if;
3090
3091             Set_No_Initialization (Decl);
3092             Append (Decl, Decls);
3093             Rewrite (N, New_Occurrence_Of (Temp, Loc));
3094             Targ := Temp;
3095          end if;
3096       end if;
3097
3098       Insert_Actions (N, Decls);
3099
3100       if Is_Unc_Decl then
3101
3102          --  Special management for inlining a call to a function that returns
3103          --  an unconstrained type and initializes an object declaration: we
3104          --  avoid generating undesired extra calls and goto statements.
3105
3106          --     Given:
3107          --                 function Func (...) return ...
3108          --                 begin
3109          --                    declare
3110          --                       Result : String (1 .. 4);
3111          --                    begin
3112          --                       Proc (Result, ...);
3113          --                       return Result;
3114          --                    end;
3115          --                 end F;
3116
3117          --                 Result : String := Func (...);
3118
3119          --     Replace this object declaration by:
3120
3121          --                 Result : String (1 .. 4);
3122          --                 Proc (Result, ...);
3123
3124          Remove_Homonym (Targ);
3125
3126          Decl :=
3127            Make_Object_Declaration
3128              (Loc,
3129               Defining_Identifier => Targ,
3130               Object_Definition   =>
3131                 New_Copy_Tree (Object_Definition (Parent (Targ1))));
3132          Replace_Formals (Decl);
3133          Rewrite (Parent (N), Decl);
3134          Analyze (Parent (N));
3135
3136          --  Avoid spurious warnings since we know that this declaration is
3137          --  referenced by the procedure call.
3138
3139          Set_Never_Set_In_Source (Targ, False);
3140
3141          --  Remove the local declaration of the extended return stmt from the
3142          --  inlined code
3143
3144          Remove (Parent (Targ1));
3145
3146          --  Update the reference to the result (since we have rewriten the
3147          --  object declaration)
3148
3149          declare
3150             Blk_Call_Stmt : Node_Id;
3151
3152          begin
3153             --  Capture the call to the procedure
3154
3155             Blk_Call_Stmt :=
3156               First (Statements (Handled_Statement_Sequence (Blk)));
3157             pragma Assert
3158               (Nkind (Blk_Call_Stmt) = N_Procedure_Call_Statement);
3159
3160             Remove (First (Parameter_Associations (Blk_Call_Stmt)));
3161             Prepend_To (Parameter_Associations (Blk_Call_Stmt),
3162               New_Occurrence_Of (Targ, Loc));
3163          end;
3164
3165          --  Remove the return statement
3166
3167          pragma Assert
3168            (Nkind (Last (Statements (Handled_Statement_Sequence (Blk)))) =
3169                                                    N_Simple_Return_Statement);
3170
3171          Remove (Last (Statements (Handled_Statement_Sequence (Blk))));
3172       end if;
3173
3174       --  Traverse the tree and replace formals with actuals or their thunks.
3175       --  Attach block to tree before analysis and rewriting.
3176
3177       Replace_Formals (Blk);
3178       Set_Parent (Blk, N);
3179
3180       if GNATprove_Mode then
3181          null;
3182
3183       elsif not Comes_From_Source (Subp) or else Is_Predef then
3184          Reset_Slocs (Blk);
3185       end if;
3186
3187       if Is_Unc_Decl then
3188
3189          --  No action needed since return statement has been already removed
3190
3191          null;
3192
3193       elsif Present (Exit_Lab) then
3194
3195          --  If the body was a single expression, the single return statement
3196          --  and the corresponding label are useless.
3197
3198          if Num_Ret = 1
3199            and then
3200              Nkind (Last (Statements (Handled_Statement_Sequence (Blk)))) =
3201                                                             N_Goto_Statement
3202          then
3203             Remove (Last (Statements (Handled_Statement_Sequence (Blk))));
3204          else
3205             Append (Lab_Decl, (Declarations (Blk)));
3206             Append (Exit_Lab, Statements (Handled_Statement_Sequence (Blk)));
3207          end if;
3208       end if;
3209
3210       --  Analyze Blk with In_Inlined_Body set, to avoid spurious errors
3211       --  on conflicting private views that Gigi would ignore. If this is a
3212       --  predefined unit, analyze with checks off, as is done in the non-
3213       --  inlined run-time units.
3214
3215       declare
3216          I_Flag : constant Boolean := In_Inlined_Body;
3217
3218       begin
3219          In_Inlined_Body := True;
3220
3221          if Is_Predef then
3222             declare
3223                Style : constant Boolean := Style_Check;
3224
3225             begin
3226                Style_Check := False;
3227
3228                --  Search for dispatching calls that use the Object.Operation
3229                --  notation using an Object that is a parameter of the inlined
3230                --  function. We reset the decoration of Operation to force
3231                --  the reanalysis of the inlined dispatching call because
3232                --  the actual object has been inlined.
3233
3234                Reset_Dispatching_Calls (Blk);
3235
3236                Analyze (Blk, Suppress => All_Checks);
3237                Style_Check := Style;
3238             end;
3239
3240          else
3241             Analyze (Blk);
3242          end if;
3243
3244          In_Inlined_Body := I_Flag;
3245       end;
3246
3247       if Ekind (Subp) = E_Procedure then
3248          Rewrite_Procedure_Call (N, Blk);
3249
3250       else
3251          Rewrite_Function_Call (N, Blk);
3252
3253          if Is_Unc_Decl then
3254             null;
3255
3256          --  For the unconstrained case, the replacement of the call has been
3257          --  made prior to the complete analysis of the generated declarations.
3258          --  Propagate the proper type now.
3259
3260          elsif Is_Unc then
3261             if Nkind (N) = N_Identifier then
3262                Set_Etype (N, Etype (Entity (N)));
3263             else
3264                Set_Etype (N, Etype (Targ1));
3265             end if;
3266          end if;
3267       end if;
3268
3269       Restore_Env;
3270
3271       --  Cleanup mapping between formals and actuals for other expansions
3272
3273       F := First_Formal (Subp);
3274       while Present (F) loop
3275          Set_Renamed_Object (F, Empty);
3276          Next_Formal (F);
3277       end loop;
3278    end Expand_Inlined_Call;
3279
3280    --------------------------
3281    -- Get_Code_Unit_Entity --
3282    --------------------------
3283
3284    function Get_Code_Unit_Entity (E : Entity_Id) return Entity_Id is
3285       Unit : Entity_Id := Cunit_Entity (Get_Code_Unit (E));
3286
3287    begin
3288       if Ekind (Unit) = E_Package_Body then
3289          Unit := Spec_Entity (Unit);
3290       end if;
3291
3292       return Unit;
3293    end Get_Code_Unit_Entity;
3294
3295    ------------------------------
3296    -- Has_Excluded_Declaration --
3297    ------------------------------
3298
3299    function Has_Excluded_Declaration
3300      (Subp  : Entity_Id;
3301       Decls : List_Id) return Boolean
3302    is
3303       D : Node_Id;
3304
3305       function Is_Unchecked_Conversion (D : Node_Id) return Boolean;
3306       --  Nested subprograms make a given body ineligible for inlining, but
3307       --  we make an exception for instantiations of unchecked conversion.
3308       --  The body has not been analyzed yet, so check the name, and verify
3309       --  that the visible entity with that name is the predefined unit.
3310
3311       -----------------------------
3312       -- Is_Unchecked_Conversion --
3313       -----------------------------
3314
3315       function Is_Unchecked_Conversion (D : Node_Id) return Boolean is
3316          Id   : constant Node_Id := Name (D);
3317          Conv : Entity_Id;
3318
3319       begin
3320          if Nkind (Id) = N_Identifier
3321            and then Chars (Id) = Name_Unchecked_Conversion
3322          then
3323             Conv := Current_Entity (Id);
3324
3325          elsif Nkind_In (Id, N_Selected_Component, N_Expanded_Name)
3326            and then Chars (Selector_Name (Id)) = Name_Unchecked_Conversion
3327          then
3328             Conv := Current_Entity (Selector_Name (Id));
3329          else
3330             return False;
3331          end if;
3332
3333          return Present (Conv)
3334            and then Is_Predefined_File_Name
3335                       (Unit_File_Name (Get_Source_Unit (Conv)))
3336            and then Is_Intrinsic_Subprogram (Conv);
3337       end Is_Unchecked_Conversion;
3338
3339    --  Start of processing for Has_Excluded_Declaration
3340
3341    begin
3342       --  No action needed if the check is not needed
3343
3344       if not Check_Inlining_Restrictions then
3345          return False;
3346       end if;
3347
3348       D := First (Decls);
3349       while Present (D) loop
3350
3351          --  First declarations universally excluded
3352
3353          if Nkind (D) = N_Package_Declaration then
3354             Cannot_Inline
3355               ("cannot inline & (nested package declaration)?",
3356                D, Subp);
3357             return True;
3358
3359          elsif Nkind (D) = N_Package_Instantiation then
3360             Cannot_Inline
3361               ("cannot inline & (nested package instantiation)?",
3362                D, Subp);
3363             return True;
3364          end if;
3365
3366          --  Then declarations excluded only for front end inlining
3367
3368          if Back_End_Inlining then
3369             null;
3370
3371          elsif Nkind (D) = N_Task_Type_Declaration
3372            or else Nkind (D) = N_Single_Task_Declaration
3373          then
3374             Cannot_Inline
3375               ("cannot inline & (nested task type declaration)?",
3376                D, Subp);
3377             return True;
3378
3379          elsif Nkind (D) = N_Protected_Type_Declaration
3380            or else Nkind (D) = N_Single_Protected_Declaration
3381          then
3382             Cannot_Inline
3383               ("cannot inline & (nested protected type declaration)?",
3384                D, Subp);
3385             return True;
3386
3387          elsif Nkind (D) = N_Subprogram_Body then
3388             Cannot_Inline
3389               ("cannot inline & (nested subprogram)?",
3390                D, Subp);
3391             return True;
3392
3393          elsif Nkind (D) = N_Function_Instantiation
3394            and then not Is_Unchecked_Conversion (D)
3395          then
3396             Cannot_Inline
3397               ("cannot inline & (nested function instantiation)?",
3398                D, Subp);
3399             return True;
3400
3401          elsif Nkind (D) = N_Procedure_Instantiation then
3402             Cannot_Inline
3403               ("cannot inline & (nested procedure instantiation)?",
3404                D, Subp);
3405             return True;
3406          end if;
3407
3408          Next (D);
3409       end loop;
3410
3411       return False;
3412    end Has_Excluded_Declaration;
3413
3414    ----------------------------
3415    -- Has_Excluded_Statement --
3416    ----------------------------
3417
3418    function Has_Excluded_Statement
3419      (Subp  : Entity_Id;
3420       Stats : List_Id) return Boolean
3421    is
3422       S : Node_Id;
3423       E : Node_Id;
3424
3425    begin
3426       --  No action needed if the check is not needed
3427
3428       if not Check_Inlining_Restrictions then
3429          return False;
3430       end if;
3431
3432       S := First (Stats);
3433       while Present (S) loop
3434          if Nkind_In (S, N_Abort_Statement,
3435                          N_Asynchronous_Select,
3436                          N_Conditional_Entry_Call,
3437                          N_Delay_Relative_Statement,
3438                          N_Delay_Until_Statement,
3439                          N_Selective_Accept,
3440                          N_Timed_Entry_Call)
3441          then
3442             Cannot_Inline
3443               ("cannot inline & (non-allowed statement)?", S, Subp);
3444             return True;
3445
3446          elsif Nkind (S) = N_Block_Statement then
3447             if Present (Declarations (S))
3448               and then Has_Excluded_Declaration (Subp, Declarations (S))
3449             then
3450                return True;
3451
3452             elsif Present (Handled_Statement_Sequence (S)) then
3453                if not Back_End_Inlining
3454                  and then
3455                    Present
3456                      (Exception_Handlers (Handled_Statement_Sequence (S)))
3457                then
3458                   Cannot_Inline
3459                     ("cannot inline& (exception handler)?",
3460                      First (Exception_Handlers
3461                               (Handled_Statement_Sequence (S))),
3462                      Subp);
3463                   return True;
3464
3465                elsif Has_Excluded_Statement
3466                        (Subp, Statements (Handled_Statement_Sequence (S)))
3467                then
3468                   return True;
3469                end if;
3470             end if;
3471
3472          elsif Nkind (S) = N_Case_Statement then
3473             E := First (Alternatives (S));
3474             while Present (E) loop
3475                if Has_Excluded_Statement (Subp, Statements (E)) then
3476                   return True;
3477                end if;
3478
3479                Next (E);
3480             end loop;
3481
3482          elsif Nkind (S) = N_If_Statement then
3483             if Has_Excluded_Statement (Subp, Then_Statements (S)) then
3484                return True;
3485             end if;
3486
3487             if Present (Elsif_Parts (S)) then
3488                E := First (Elsif_Parts (S));
3489                while Present (E) loop
3490                   if Has_Excluded_Statement (Subp, Then_Statements (E)) then
3491                      return True;
3492                   end if;
3493
3494                   Next (E);
3495                end loop;
3496             end if;
3497
3498             if Present (Else_Statements (S))
3499               and then Has_Excluded_Statement (Subp, Else_Statements (S))
3500             then
3501                return True;
3502             end if;
3503
3504          elsif Nkind (S) = N_Loop_Statement
3505            and then Has_Excluded_Statement (Subp, Statements (S))
3506          then
3507             return True;
3508
3509          elsif Nkind (S) = N_Extended_Return_Statement then
3510             if Present (Handled_Statement_Sequence (S))
3511               and then
3512                 Has_Excluded_Statement
3513                   (Subp, Statements (Handled_Statement_Sequence (S)))
3514             then
3515                return True;
3516
3517             elsif not Back_End_Inlining
3518               and then Present (Handled_Statement_Sequence (S))
3519               and then
3520                 Present (Exception_Handlers
3521                           (Handled_Statement_Sequence (S)))
3522             then
3523                Cannot_Inline
3524                  ("cannot inline& (exception handler)?",
3525                   First (Exception_Handlers (Handled_Statement_Sequence (S))),
3526                   Subp);
3527                return True;
3528             end if;
3529          end if;
3530
3531          Next (S);
3532       end loop;
3533
3534       return False;
3535    end Has_Excluded_Statement;
3536
3537    --------------------------
3538    -- Has_Initialized_Type --
3539    --------------------------
3540
3541    function Has_Initialized_Type (E : Entity_Id) return Boolean is
3542       E_Body : constant Node_Id := Get_Subprogram_Body (E);
3543       Decl   : Node_Id;
3544
3545    begin
3546       if No (E_Body) then        --  imported subprogram
3547          return False;
3548
3549       else
3550          Decl := First (Declarations (E_Body));
3551          while Present (Decl) loop
3552             if Nkind (Decl) = N_Full_Type_Declaration
3553               and then Present (Init_Proc (Defining_Identifier (Decl)))
3554             then
3555                return True;
3556             end if;
3557
3558             Next (Decl);
3559          end loop;
3560       end if;
3561
3562       return False;
3563    end Has_Initialized_Type;
3564
3565    -----------------------
3566    -- Has_Single_Return --
3567    -----------------------
3568
3569    function Has_Single_Return (N : Node_Id) return Boolean is
3570       Return_Statement : Node_Id := Empty;
3571
3572       function Check_Return (N : Node_Id) return Traverse_Result;
3573
3574       ------------------
3575       -- Check_Return --
3576       ------------------
3577
3578       function Check_Return (N : Node_Id) return Traverse_Result is
3579       begin
3580          if Nkind (N) = N_Simple_Return_Statement then
3581             if Present (Expression (N))
3582               and then Is_Entity_Name (Expression (N))
3583             then
3584                if No (Return_Statement) then
3585                   Return_Statement := N;
3586                   return OK;
3587
3588                elsif Chars (Expression (N)) =
3589                      Chars (Expression (Return_Statement))
3590                then
3591                   return OK;
3592
3593                else
3594                   return Abandon;
3595                end if;
3596
3597             --  A return statement within an extended return is a noop
3598             --  after inlining.
3599
3600             elsif No (Expression (N))
3601               and then
3602                 Nkind (Parent (Parent (N))) = N_Extended_Return_Statement
3603             then
3604                return OK;
3605
3606             else
3607                --  Expression has wrong form
3608
3609                return Abandon;
3610             end if;
3611
3612          --  We can only inline a build-in-place function if it has a single
3613          --  extended return.
3614
3615          elsif Nkind (N) = N_Extended_Return_Statement then
3616             if No (Return_Statement) then
3617                Return_Statement := N;
3618                return OK;
3619
3620             else
3621                return Abandon;
3622             end if;
3623
3624          else
3625             return OK;
3626          end if;
3627       end Check_Return;
3628
3629       function Check_All_Returns is new Traverse_Func (Check_Return);
3630
3631    --  Start of processing for Has_Single_Return
3632
3633    begin
3634       if Check_All_Returns (N) /= OK then
3635          return False;
3636
3637       elsif Nkind (Return_Statement) = N_Extended_Return_Statement then
3638          return True;
3639
3640       else
3641          return Present (Declarations (N))
3642            and then Present (First (Declarations (N)))
3643            and then Chars (Expression (Return_Statement)) =
3644                     Chars (Defining_Identifier (First (Declarations (N))));
3645       end if;
3646    end Has_Single_Return;
3647
3648    -----------------------------
3649    -- In_Main_Unit_Or_Subunit --
3650    -----------------------------
3651
3652    function In_Main_Unit_Or_Subunit (E : Entity_Id) return Boolean is
3653       Comp : Node_Id := Cunit (Get_Code_Unit (E));
3654
3655    begin
3656       --  Check whether the subprogram or package to inline is within the main
3657       --  unit or its spec or within a subunit. In either case there are no
3658       --  additional bodies to process. If the subprogram appears in a parent
3659       --  of the current unit, the check on whether inlining is possible is
3660       --  done in Analyze_Inlined_Bodies.
3661
3662       while Nkind (Unit (Comp)) = N_Subunit loop
3663          Comp := Library_Unit (Comp);
3664       end loop;
3665
3666       return Comp = Cunit (Main_Unit)
3667         or else Comp = Library_Unit (Cunit (Main_Unit));
3668    end In_Main_Unit_Or_Subunit;
3669
3670    ----------------
3671    -- Initialize --
3672    ----------------
3673
3674    procedure Initialize is
3675    begin
3676       Pending_Descriptor.Init;
3677       Pending_Instantiations.Init;
3678       Inlined_Bodies.Init;
3679       Successors.Init;
3680       Inlined.Init;
3681
3682       for J in Hash_Headers'Range loop
3683          Hash_Headers (J) := No_Subp;
3684       end loop;
3685
3686       Inlined_Calls := No_Elist;
3687       Backend_Calls := No_Elist;
3688       Backend_Inlined_Subps := No_Elist;
3689       Backend_Not_Inlined_Subps := No_Elist;
3690    end Initialize;
3691
3692    ------------------------
3693    -- Instantiate_Bodies --
3694    ------------------------
3695
3696    --  Generic bodies contain all the non-local references, so an
3697    --  instantiation does not need any more context than Standard
3698    --  itself, even if the instantiation appears in an inner scope.
3699    --  Generic associations have verified that the contract model is
3700    --  satisfied, so that any error that may occur in the analysis of
3701    --  the body is an internal error.
3702
3703    procedure Instantiate_Bodies is
3704       J    : Int;
3705       Info : Pending_Body_Info;
3706
3707    begin
3708       if Serious_Errors_Detected = 0 then
3709          Expander_Active := (Operating_Mode = Opt.Generate_Code);
3710          Push_Scope (Standard_Standard);
3711          To_Clean := New_Elmt_List;
3712
3713          if Is_Generic_Unit (Cunit_Entity (Main_Unit)) then
3714             Start_Generic;
3715          end if;
3716
3717          --  A body instantiation may generate additional instantiations, so
3718          --  the following loop must scan to the end of a possibly expanding
3719          --  set (that's why we can't simply use a FOR loop here).
3720
3721          J := 0;
3722          while J <= Pending_Instantiations.Last
3723            and then Serious_Errors_Detected = 0
3724          loop
3725             Info := Pending_Instantiations.Table (J);
3726
3727             --  If the instantiation node is absent, it has been removed
3728             --  as part of unreachable code.
3729
3730             if No (Info.Inst_Node) then
3731                null;
3732
3733             elsif Nkind (Info.Act_Decl) = N_Package_Declaration then
3734                Instantiate_Package_Body (Info);
3735                Add_Scope_To_Clean (Defining_Entity (Info.Act_Decl));
3736
3737             else
3738                Instantiate_Subprogram_Body (Info);
3739             end if;
3740
3741             J := J + 1;
3742          end loop;
3743
3744          --  Reset the table of instantiations. Additional instantiations
3745          --  may be added through inlining, when additional bodies are
3746          --  analyzed.
3747
3748          Pending_Instantiations.Init;
3749
3750          --  We can now complete the cleanup actions of scopes that contain
3751          --  pending instantiations (skipped for generic units, since we
3752          --  never need any cleanups in generic units).
3753          --  pending instantiations.
3754
3755          if Expander_Active
3756            and then not Is_Generic_Unit (Main_Unit_Entity)
3757          then
3758             Cleanup_Scopes;
3759          elsif Is_Generic_Unit (Cunit_Entity (Main_Unit)) then
3760             End_Generic;
3761          end if;
3762
3763          Pop_Scope;
3764       end if;
3765    end Instantiate_Bodies;
3766
3767    ---------------
3768    -- Is_Nested --
3769    ---------------
3770
3771    function Is_Nested (E : Entity_Id) return Boolean is
3772       Scop : Entity_Id;
3773
3774    begin
3775       Scop := Scope (E);
3776       while Scop /= Standard_Standard loop
3777          if Ekind (Scop) in Subprogram_Kind then
3778             return True;
3779
3780          elsif Ekind (Scop) = E_Task_Type
3781            or else Ekind (Scop) = E_Entry
3782            or else Ekind (Scop) = E_Entry_Family
3783          then
3784             return True;
3785          end if;
3786
3787          Scop := Scope (Scop);
3788       end loop;
3789
3790       return False;
3791    end Is_Nested;
3792
3793    ------------------------
3794    -- List_Inlining_Info --
3795    ------------------------
3796
3797    procedure List_Inlining_Info is
3798       Elmt  : Elmt_Id;
3799       Nod   : Node_Id;
3800       Count : Nat;
3801
3802    begin
3803       if not Debug_Flag_Dot_J then
3804          return;
3805       end if;
3806
3807       --  Generate listing of calls inlined by the frontend
3808
3809       if Present (Inlined_Calls) then
3810          Count := 0;
3811          Elmt  := First_Elmt (Inlined_Calls);
3812          while Present (Elmt) loop
3813             Nod := Node (Elmt);
3814
3815             if In_Extended_Main_Code_Unit (Nod) then
3816                Count := Count + 1;
3817
3818                if Count = 1 then
3819                   Write_Str ("List of calls inlined by the frontend");
3820                   Write_Eol;
3821                end if;
3822
3823                Write_Str ("  ");
3824                Write_Int (Count);
3825                Write_Str (":");
3826                Write_Location (Sloc (Nod));
3827                Write_Str (":");
3828                Output.Write_Eol;
3829             end if;
3830
3831             Next_Elmt (Elmt);
3832          end loop;
3833       end if;
3834
3835       --  Generate listing of calls passed to the backend
3836
3837       if Present (Backend_Calls) then
3838          Count := 0;
3839
3840          Elmt := First_Elmt (Backend_Calls);
3841          while Present (Elmt) loop
3842             Nod := Node (Elmt);
3843
3844             if In_Extended_Main_Code_Unit (Nod) then
3845                Count := Count + 1;
3846
3847                if Count = 1 then
3848                   Write_Str ("List of inlined calls passed to the backend");
3849                   Write_Eol;
3850                end if;
3851
3852                Write_Str ("  ");
3853                Write_Int (Count);
3854                Write_Str (":");
3855                Write_Location (Sloc (Nod));
3856                Output.Write_Eol;
3857             end if;
3858
3859             Next_Elmt (Elmt);
3860          end loop;
3861       end if;
3862
3863       --  Generate listing of subprograms passed to the backend
3864
3865       if Present (Backend_Inlined_Subps) and then Back_End_Inlining then
3866          Count := 0;
3867
3868          Elmt := First_Elmt (Backend_Inlined_Subps);
3869          while Present (Elmt) loop
3870             Nod := Node (Elmt);
3871
3872             Count := Count + 1;
3873
3874             if Count = 1 then
3875                Write_Str
3876                  ("List of inlined subprograms passed to the backend");
3877                Write_Eol;
3878             end if;
3879
3880             Write_Str ("  ");
3881             Write_Int (Count);
3882             Write_Str (":");
3883             Write_Name (Chars (Nod));
3884             Write_Str (" (");
3885             Write_Location (Sloc (Nod));
3886             Write_Str (")");
3887             Output.Write_Eol;
3888
3889             Next_Elmt (Elmt);
3890          end loop;
3891       end if;
3892
3893       --  Generate listing of subprograms that cannot be inlined by the backend
3894
3895       if Present (Backend_Not_Inlined_Subps) and then Back_End_Inlining then
3896          Count := 0;
3897
3898          Elmt := First_Elmt (Backend_Not_Inlined_Subps);
3899          while Present (Elmt) loop
3900             Nod := Node (Elmt);
3901
3902             Count := Count + 1;
3903
3904             if Count = 1 then
3905                Write_Str
3906                  ("List of subprograms that cannot be inlined by the backend");
3907                Write_Eol;
3908             end if;
3909
3910             Write_Str ("  ");
3911             Write_Int (Count);
3912             Write_Str (":");
3913             Write_Name (Chars (Nod));
3914             Write_Str (" (");
3915             Write_Location (Sloc (Nod));
3916             Write_Str (")");
3917             Output.Write_Eol;
3918
3919             Next_Elmt (Elmt);
3920          end loop;
3921       end if;
3922    end List_Inlining_Info;
3923
3924    ----------
3925    -- Lock --
3926    ----------
3927
3928    procedure Lock is
3929    begin
3930       Pending_Instantiations.Locked := True;
3931       Inlined_Bodies.Locked := True;
3932       Successors.Locked := True;
3933       Inlined.Locked := True;
3934       Pending_Instantiations.Release;
3935       Inlined_Bodies.Release;
3936       Successors.Release;
3937       Inlined.Release;
3938    end Lock;
3939
3940    ---------------------------
3941    -- Register_Backend_Call --
3942    ---------------------------
3943
3944    procedure Register_Backend_Call (N : Node_Id) is
3945    begin
3946       Append_New_Elmt (N, To => Backend_Calls);
3947    end Register_Backend_Call;
3948
3949    --------------------------------
3950    -- Remove_Aspects_And_Pragmas --
3951    --------------------------------
3952
3953    procedure Remove_Aspects_And_Pragmas (Body_Decl : Node_Id) is
3954       procedure Remove_Items (List : List_Id);
3955       --  Remove all useless aspects/pragmas from a particular list
3956
3957       ------------------
3958       -- Remove_Items --
3959       ------------------
3960
3961       procedure Remove_Items (List : List_Id) is
3962          Item      : Node_Id;
3963          Item_Id   : Node_Id;
3964          Next_Item : Node_Id;
3965
3966       begin
3967          --  Traverse the list looking for an aspect specification or a pragma
3968
3969          Item := First (List);
3970          while Present (Item) loop
3971             Next_Item := Next (Item);
3972
3973             if Nkind (Item) = N_Aspect_Specification then
3974                Item_Id := Identifier (Item);
3975             elsif Nkind (Item) = N_Pragma then
3976                Item_Id := Pragma_Identifier (Item);
3977             else
3978                Item_Id := Empty;
3979             end if;
3980
3981             if Present (Item_Id)
3982               and then Nam_In (Chars (Item_Id), Name_Contract_Cases,
3983                                                 Name_Global,
3984                                                 Name_Depends,
3985                                                 Name_Postcondition,
3986                                                 Name_Precondition,
3987                                                 Name_Refined_Global,
3988                                                 Name_Refined_Depends,
3989                                                 Name_Refined_Post,
3990                                                 Name_Test_Case,
3991                                                 Name_Unmodified,
3992                                                 Name_Unreferenced)
3993             then
3994                Remove (Item);
3995             end if;
3996
3997             Item := Next_Item;
3998          end loop;
3999       end Remove_Items;
4000
4001    --  Start of processing for Remove_Aspects_And_Pragmas
4002
4003    begin
4004       Remove_Items (Aspect_Specifications (Body_Decl));
4005       Remove_Items (Declarations          (Body_Decl));
4006    end Remove_Aspects_And_Pragmas;
4007
4008    --------------------------
4009    -- Remove_Dead_Instance --
4010    --------------------------
4011
4012    procedure Remove_Dead_Instance (N : Node_Id) is
4013       J : Int;
4014
4015    begin
4016       J := 0;
4017       while J <= Pending_Instantiations.Last loop
4018          if Pending_Instantiations.Table (J).Inst_Node = N then
4019             Pending_Instantiations.Table (J).Inst_Node := Empty;
4020             return;
4021          end if;
4022
4023          J := J + 1;
4024       end loop;
4025    end Remove_Dead_Instance;
4026
4027 end Inline;