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