]> 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
1228 return;
1229
1230 -- New semantics
1231
1232 elsif Is_Serious then
1233
1234 -- Remove last character (question mark) to make this into an error.
1235
1236 Error_Msg_NE (Msg (Msg'First .. Msg'Last - 1), N, Subp);
1237
7b2888e6 1238 -- In GNATprove mode, issue a warning, and indicate that the subprogram
4bd4bb7f 1239 -- is not always inlined by setting flag Is_Inlined_Always to False.
7b2888e6
AC
1240
1241 elsif GNATprove_Mode then
4bd4bb7f 1242 Set_Is_Inlined_Always (Subp, False);
7b2888e6
AC
1243 Error_Msg_NE (Msg & "p?", N, Subp);
1244
1245 -- Do not issue errors/warnings when compiling with optimizations
cc6f5d75 1246
7b2888e6 1247 elsif Optimization_Level = 0 then
540d8610
ES
1248
1249 -- Do not emit warning if this is a predefined unit which is not
1250 -- the main unit. This behavior is currently provided for backward
1251 -- compatibility but it will be removed when we enforce the
1252 -- strictness of the new rules.
1253
1254 if Is_Predefined_File_Name (Unit_File_Name (Get_Source_Unit (Subp)))
1255 and then not In_Extended_Main_Source_Unit (Subp)
1256 then
1257 null;
1258
1259 elsif Has_Pragma_Inline_Always (Subp) then
1260
1261 -- Emit a warning if this is a call to a runtime subprogram
1262 -- which is located inside a generic. Previously this call
1263 -- was silently skipped.
1264
1265 if Is_Generic_Instance (Subp) then
1266 declare
1267 Gen_P : constant Entity_Id := Generic_Parent (Parent (Subp));
1268 begin
1269 if Is_Predefined_File_Name
3f80a182 1270 (Unit_File_Name (Get_Source_Unit (Gen_P)))
540d8610
ES
1271 then
1272 Set_Is_Inlined (Subp, False);
1273 Error_Msg_NE (Msg & "p?", N, Subp);
1274 return;
1275 end if;
1276 end;
1277 end if;
1278
1279 -- Remove last character (question mark) to make this into an
1280 -- error, because the Inline_Always pragma cannot be obeyed.
1281
1282 Error_Msg_NE (Msg (Msg'First .. Msg'Last - 1), N, Subp);
1283
7b2888e6 1284 else pragma Assert (Front_End_Inlining);
540d8610
ES
1285 Set_Is_Inlined (Subp, False);
1286
1287 -- When inlining cannot take place we must issue an error.
1288 -- For backward compatibility we still report a warning.
1289
1290 if Ineffective_Inline_Warnings then
1291 Error_Msg_NE (Msg & "p?", N, Subp);
1292 end if;
1293 end if;
1294
1295 -- Compiling with optimizations enabled it is too early to report
1296 -- problems since the backend may still perform inlining. In order
1297 -- to report unhandled inlinings the program must be compiled with
1298 -- -Winline and the error is reported by the backend.
1299
1300 else
1301 null;
1302 end if;
1303 end Cannot_Inline;
1304
2d180af1
YM
1305 --------------------------------------
1306 -- Can_Be_Inlined_In_GNATprove_Mode --
1307 --------------------------------------
1308
1309 function Can_Be_Inlined_In_GNATprove_Mode
1310 (Spec_Id : Entity_Id;
1311 Body_Id : Entity_Id) return Boolean
1312 is
1313 function Has_Some_Contract (Id : Entity_Id) return Boolean;
1314 -- Returns True if subprogram Id has any contract (Pre, Post, Global,
1315 -- Depends, etc.)
1316
82701811
AC
1317 function Is_Unit_Subprogram (Id : Entity_Id) return Boolean;
1318 -- Returns True if subprogram Id defines a compilation unit
2e1295ad 1319 -- Shouldn't this be in Sem_Aux???
82701811 1320
1e3689bd
AC
1321 function In_Package_Visible_Spec (Id : Node_Id) return Boolean;
1322 -- Returns True if subprogram Id is defined in the visible part of a
1323 -- package specification.
2d180af1
YM
1324
1325 function Is_Expression_Function (Id : Entity_Id) return Boolean;
1326 -- Returns True if subprogram Id was defined originally as an expression
1327 -- function.
1328
1329 -----------------------
1330 -- Has_Some_Contract --
1331 -----------------------
1332
1333 function Has_Some_Contract (Id : Entity_Id) return Boolean is
1334 Items : constant Node_Id := Contract (Id);
1335 begin
1336 return Present (Items)
1399d355
AC
1337 and then (Present (Pre_Post_Conditions (Items)) or else
1338 Present (Contract_Test_Cases (Items)) or else
1339 Present (Classifications (Items)));
2d180af1
YM
1340 end Has_Some_Contract;
1341
1e3689bd
AC
1342 -----------------------------
1343 -- In_Package_Visible_Spec --
1344 -----------------------------
2d180af1 1345
1e3689bd
AC
1346 function In_Package_Visible_Spec (Id : Node_Id) return Boolean is
1347 Decl : Node_Id := Parent (Parent (Id));
1348 P : Node_Id;
fc27e20e 1349
2d180af1 1350 begin
1e3689bd
AC
1351 if Nkind (Parent (Id)) = N_Defining_Program_Unit_Name then
1352 Decl := Parent (Decl);
1353 end if;
2d180af1 1354
1e3689bd 1355 P := Parent (Decl);
2d180af1 1356
1e3689bd
AC
1357 return Nkind (P) = N_Package_Specification
1358 and then List_Containing (Decl) = Visible_Declarations (P);
1359 end In_Package_Visible_Spec;
2d180af1
YM
1360
1361 ----------------------------
1362 -- Is_Expression_Function --
1363 ----------------------------
1364
1365 function Is_Expression_Function (Id : Entity_Id) return Boolean is
1e3689bd 1366 Decl : Node_Id := Parent (Parent (Id));
2d180af1 1367 begin
1e3689bd
AC
1368 if Nkind (Parent (Id)) = N_Defining_Program_Unit_Name then
1369 Decl := Parent (Decl);
1370 end if;
1371
2d180af1
YM
1372 return Nkind (Original_Node (Decl)) = N_Expression_Function;
1373 end Is_Expression_Function;
1374
82701811
AC
1375 ------------------------
1376 -- Is_Unit_Subprogram --
1377 ------------------------
1378
1379 function Is_Unit_Subprogram (Id : Entity_Id) return Boolean is
1380 Decl : Node_Id := Parent (Parent (Id));
1381 begin
1382 if Nkind (Parent (Id)) = N_Defining_Program_Unit_Name then
1383 Decl := Parent (Decl);
1384 end if;
1385
1386 return Nkind (Parent (Decl)) = N_Compilation_Unit;
1387 end Is_Unit_Subprogram;
1388
fc27e20e
RD
1389 -- Local declarations
1390
2d180af1
YM
1391 Id : Entity_Id; -- Procedure or function entity for the subprogram
1392
1393 -- Start of Can_Be_Inlined_In_GNATprove_Mode
1394
1395 begin
4bd4bb7f
AC
1396 pragma Assert (Present (Spec_Id) or else Present (Body_Id));
1397
2d180af1
YM
1398 if Present (Spec_Id) then
1399 Id := Spec_Id;
1400 else
1401 Id := Body_Id;
1402 end if;
1403
52c1498c
YM
1404 -- Only local subprograms without contracts are inlined in GNATprove
1405 -- mode, as these are the subprograms which a user is not interested in
1406 -- analyzing in isolation, but rather in the context of their call. This
1407 -- is a convenient convention, that could be changed for an explicit
1408 -- pragma/aspect one day.
1409
1410 -- In a number of special cases, inlining is not desirable or not
1411 -- possible, see below.
1399d355 1412
2d180af1
YM
1413 -- Do not inline unit-level subprograms
1414
82701811 1415 if Is_Unit_Subprogram (Id) then
2d180af1
YM
1416 return False;
1417
1e3689bd 1418 -- Do not inline subprograms declared in the visible part of a package
2d180af1 1419
1e3689bd 1420 elsif In_Package_Visible_Spec (Id) then
2d180af1
YM
1421 return False;
1422
1423 -- Do not inline subprograms that have a contract on the spec or the
1424 -- body. Use the contract(s) instead in GNATprove.
1425
1426 elsif (Present (Spec_Id) and then Has_Some_Contract (Spec_Id))
4bd4bb7f
AC
1427 or else
1428 (Present (Body_Id) and then Has_Some_Contract (Body_Id))
2d180af1
YM
1429 then
1430 return False;
1431
52c1498c
YM
1432 -- Do not inline expression functions, which are directly inlined at the
1433 -- prover level.
2d180af1
YM
1434
1435 elsif (Present (Spec_Id) and then Is_Expression_Function (Spec_Id))
4bd4bb7f
AC
1436 or else
1437 (Present (Body_Id) and then Is_Expression_Function (Body_Id))
2d180af1
YM
1438 then
1439 return False;
1440
52c1498c
YM
1441 -- Do not inline generic subprogram instances. The visibility rules of
1442 -- generic instances plays badly with inlining.
1399d355 1443
ac072cb2
AC
1444 elsif Is_Generic_Instance (Spec_Id) then
1445 return False;
1446
2178830b
AC
1447 -- Only inline subprograms whose spec is marked SPARK_Mode On. For
1448 -- the subprogram body, a similar check is performed after the body
1449 -- is analyzed, as this is where a pragma SPARK_Mode might be inserted.
1450
1451 elsif Present (Spec_Id)
eb1ee757
AC
1452 and then
1453 (No (SPARK_Pragma (Spec_Id))
1454 or else Get_SPARK_Mode_From_Pragma (SPARK_Pragma (Spec_Id)) /= On)
2d180af1
YM
1455 then
1456 return False;
1457
1458 -- Subprograms in generic instances are currently not inlined, to avoid
1459 -- problems with inlining of standard library subprograms.
1460
1461 elsif Instantiation_Location (Sloc (Id)) /= No_Location then
1462 return False;
1463
eb1ee757 1464 -- Don't inline predicate functions (treated specially by GNATprove)
2178830b
AC
1465
1466 elsif Is_Predicate_Function (Id) then
1467 return False;
1468
2d180af1
YM
1469 -- Otherwise, this is a subprogram declared inside the private part of a
1470 -- package, or inside a package body, or locally in a subprogram, and it
1471 -- does not have any contract. Inline it.
1472
1473 else
1474 return True;
1475 end if;
1476 end Can_Be_Inlined_In_GNATprove_Mode;
1477
16b10ccc
AC
1478 --------------------------------------------
1479 -- Check_And_Split_Unconstrained_Function --
1480 --------------------------------------------
540d8610 1481
16b10ccc 1482 procedure Check_And_Split_Unconstrained_Function
540d8610
ES
1483 (N : Node_Id;
1484 Spec_Id : Entity_Id;
1485 Body_Id : Entity_Id)
1486 is
1487 procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id);
1488 -- Use generic machinery to build an unexpanded body for the subprogram.
1489 -- This body is subsequently used for inline expansions at call sites.
1490
1491 function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean;
1492 -- Return true if we generate code for the function body N, the function
1493 -- body N has no local declarations and its unique statement is a single
1494 -- extended return statement with a handled statements sequence.
1495
16b10ccc 1496 procedure Generate_Subprogram_Body
540d8610
ES
1497 (N : Node_Id;
1498 Body_To_Inline : out Node_Id);
1499 -- Generate a parameterless duplicate of subprogram body N. Occurrences
1500 -- of pragmas referencing the formals are removed since they have no
1501 -- meaning when the body is inlined and the formals are rewritten (the
1502 -- analysis of the non-inlined body will handle these pragmas properly).
1503 -- A new internal name is associated with Body_To_Inline.
1504
1505 procedure Split_Unconstrained_Function
1506 (N : Node_Id;
1507 Spec_Id : Entity_Id);
1508 -- N is an inlined function body that returns an unconstrained type and
1509 -- has a single extended return statement. Split N in two subprograms:
1510 -- a procedure P' and a function F'. The formals of P' duplicate the
1511 -- formals of N plus an extra formal which is used return a value;
1512 -- its body is composed by the declarations and list of statements
1513 -- of the extended return statement of N.
1514
1515 --------------------------
1516 -- Build_Body_To_Inline --
1517 --------------------------
1518
1519 procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id) is
1520 Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id);
1521 Original_Body : Node_Id;
1522 Body_To_Analyze : Node_Id;
1523
1524 begin
1525 pragma Assert (Current_Scope = Spec_Id);
1526
1527 -- Within an instance, the body to inline must be treated as a nested
1528 -- generic, so that the proper global references are preserved. We
1529 -- do not do this at the library level, because it is not needed, and
1530 -- furthermore this causes trouble if front end inlining is activated
1531 -- (-gnatN).
1532
1533 if In_Instance
1534 and then Scope (Current_Scope) /= Standard_Standard
1535 then
1536 Save_Env (Scope (Current_Scope), Scope (Current_Scope));
1537 end if;
1538
1539 -- We need to capture references to the formals in order
1540 -- to substitute the actuals at the point of inlining, i.e.
1541 -- instantiation. To treat the formals as globals to the body to
1542 -- inline, we nest it within a dummy parameterless subprogram,
1543 -- declared within the real one.
1544
16b10ccc 1545 Generate_Subprogram_Body (N, Original_Body);
540d8610
ES
1546 Body_To_Analyze := Copy_Generic_Node (Original_Body, Empty, False);
1547
1548 -- Set return type of function, which is also global and does not
1549 -- need to be resolved.
1550
1551 if Ekind (Spec_Id) = E_Function then
1552 Set_Result_Definition (Specification (Body_To_Analyze),
1553 New_Occurrence_Of (Etype (Spec_Id), Sloc (N)));
1554 end if;
1555
1556 if No (Declarations (N)) then
1557 Set_Declarations (N, New_List (Body_To_Analyze));
1558 else
1559 Append_To (Declarations (N), Body_To_Analyze);
1560 end if;
1561
1562 Preanalyze (Body_To_Analyze);
1563
1564 Push_Scope (Defining_Entity (Body_To_Analyze));
1565 Save_Global_References (Original_Body);
1566 End_Scope;
1567 Remove (Body_To_Analyze);
1568
1569 -- Restore environment if previously saved
1570
1571 if In_Instance
1572 and then Scope (Current_Scope) /= Standard_Standard
1573 then
1574 Restore_Env;
1575 end if;
1576
1577 pragma Assert (No (Body_To_Inline (Decl)));
1578 Set_Body_To_Inline (Decl, Original_Body);
1579 Set_Ekind (Defining_Entity (Original_Body), Ekind (Spec_Id));
1580 end Build_Body_To_Inline;
1581
540d8610
ES
1582 --------------------------------------
1583 -- Can_Split_Unconstrained_Function --
1584 --------------------------------------
1585
1586 function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean
1587 is
1588 Ret_Node : constant Node_Id :=
1589 First (Statements (Handled_Statement_Sequence (N)));
1590 D : Node_Id;
1591
1592 begin
1593 -- No user defined declarations allowed in the function except inside
1594 -- the unique return statement; implicit labels are the only allowed
1595 -- declarations.
1596
1597 if not Is_Empty_List (Declarations (N)) then
1598 D := First (Declarations (N));
1599 while Present (D) loop
1600 if Nkind (D) /= N_Implicit_Label_Declaration then
1601 return False;
1602 end if;
1603
1604 Next (D);
1605 end loop;
1606 end if;
1607
1608 -- We only split the inlined function when we are generating the code
1609 -- of its body; otherwise we leave duplicated split subprograms in
1610 -- the tree which (if referenced) generate wrong references at link
1611 -- time.
1612
1613 return In_Extended_Main_Code_Unit (N)
1614 and then Present (Ret_Node)
1615 and then Nkind (Ret_Node) = N_Extended_Return_Statement
1616 and then No (Next (Ret_Node))
1617 and then Present (Handled_Statement_Sequence (Ret_Node));
1618 end Can_Split_Unconstrained_Function;
1619
1620 -----------------------------
1621 -- Generate_Body_To_Inline --
1622 -----------------------------
1623
16b10ccc 1624 procedure Generate_Subprogram_Body
540d8610
ES
1625 (N : Node_Id;
1626 Body_To_Inline : out Node_Id)
1627 is
540d8610
ES
1628 begin
1629 -- Within an instance, the body to inline must be treated as a nested
1630 -- generic, so that the proper global references are preserved.
1631
1632 -- Note that we do not do this at the library level, because it
1633 -- is not needed, and furthermore this causes trouble if front
1634 -- end inlining is activated (-gnatN).
1635
1636 if In_Instance
1637 and then Scope (Current_Scope) /= Standard_Standard
1638 then
1639 Body_To_Inline := Copy_Generic_Node (N, Empty, True);
1640 else
1641 Body_To_Inline := Copy_Separate_Tree (N);
1642 end if;
1643
1644 -- A pragma Unreferenced or pragma Unmodified that mentions a formal
1645 -- parameter has no meaning when the body is inlined and the formals
1646 -- are rewritten. Remove it from body to inline. The analysis of the
1647 -- non-inlined body will handle the pragma properly.
1648
1649 Remove_Pragmas (Body_To_Inline);
1650
1651 -- We need to capture references to the formals in order
1652 -- to substitute the actuals at the point of inlining, i.e.
1653 -- instantiation. To treat the formals as globals to the body to
1654 -- inline, we nest it within a dummy parameterless subprogram,
1655 -- declared within the real one.
1656
1657 Set_Parameter_Specifications
1658 (Specification (Body_To_Inline), No_List);
1659
1660 -- A new internal name is associated with Body_To_Inline to avoid
1661 -- conflicts when the non-inlined body N is analyzed.
1662
1663 Set_Defining_Unit_Name (Specification (Body_To_Inline),
1664 Make_Defining_Identifier (Sloc (N), New_Internal_Name ('P')));
1665 Set_Corresponding_Spec (Body_To_Inline, Empty);
16b10ccc 1666 end Generate_Subprogram_Body;
540d8610
ES
1667
1668 ----------------------------------
1669 -- Split_Unconstrained_Function --
1670 ----------------------------------
1671
1672 procedure Split_Unconstrained_Function
1673 (N : Node_Id;
1674 Spec_Id : Entity_Id)
1675 is
1676 Loc : constant Source_Ptr := Sloc (N);
1677 Ret_Node : constant Node_Id :=
1678 First (Statements (Handled_Statement_Sequence (N)));
1679 Ret_Obj : constant Node_Id :=
1680 First (Return_Object_Declarations (Ret_Node));
1681
1682 procedure Build_Procedure
1683 (Proc_Id : out Entity_Id;
1684 Decl_List : out List_Id);
1685 -- Build a procedure containing the statements found in the extended
1686 -- return statement of the unconstrained function body N.
1687
3f80a182
AC
1688 ---------------------
1689 -- Build_Procedure --
1690 ---------------------
1691
540d8610
ES
1692 procedure Build_Procedure
1693 (Proc_Id : out Entity_Id;
1694 Decl_List : out List_Id)
1695 is
3f80a182
AC
1696 Formal : Entity_Id;
1697 Formal_List : constant List_Id := New_List;
1698 Proc_Spec : Node_Id;
1699 Proc_Body : Node_Id;
1700 Subp_Name : constant Name_Id := New_Internal_Name ('F');
540d8610 1701 Body_Decl_List : List_Id := No_List;
3f80a182 1702 Param_Type : Node_Id;
540d8610
ES
1703
1704 begin
1705 if Nkind (Object_Definition (Ret_Obj)) = N_Identifier then
3f80a182
AC
1706 Param_Type :=
1707 New_Copy (Object_Definition (Ret_Obj));
540d8610
ES
1708 else
1709 Param_Type :=
1710 New_Copy (Subtype_Mark (Object_Definition (Ret_Obj)));
1711 end if;
1712
1713 Append_To (Formal_List,
1714 Make_Parameter_Specification (Loc,
3f80a182 1715 Defining_Identifier =>
540d8610
ES
1716 Make_Defining_Identifier (Loc,
1717 Chars => Chars (Defining_Identifier (Ret_Obj))),
3f80a182
AC
1718 In_Present => False,
1719 Out_Present => True,
540d8610 1720 Null_Exclusion_Present => False,
3f80a182 1721 Parameter_Type => Param_Type));
540d8610
ES
1722
1723 Formal := First_Formal (Spec_Id);
1724 while Present (Formal) loop
1725 Append_To (Formal_List,
1726 Make_Parameter_Specification (Loc,
3f80a182 1727 Defining_Identifier =>
540d8610
ES
1728 Make_Defining_Identifier (Sloc (Formal),
1729 Chars => Chars (Formal)),
3f80a182
AC
1730 In_Present => In_Present (Parent (Formal)),
1731 Out_Present => Out_Present (Parent (Formal)),
540d8610
ES
1732 Null_Exclusion_Present =>
1733 Null_Exclusion_Present (Parent (Formal)),
3f80a182 1734 Parameter_Type =>
540d8610 1735 New_Occurrence_Of (Etype (Formal), Loc),
3f80a182 1736 Expression =>
540d8610
ES
1737 Copy_Separate_Tree (Expression (Parent (Formal)))));
1738
1739 Next_Formal (Formal);
1740 end loop;
1741
3f80a182 1742 Proc_Id := Make_Defining_Identifier (Loc, Chars => Subp_Name);
540d8610
ES
1743
1744 Proc_Spec :=
1745 Make_Procedure_Specification (Loc,
3f80a182 1746 Defining_Unit_Name => Proc_Id,
540d8610
ES
1747 Parameter_Specifications => Formal_List);
1748
1749 Decl_List := New_List;
1750
1751 Append_To (Decl_List,
1752 Make_Subprogram_Declaration (Loc, Proc_Spec));
1753
1754 -- Can_Convert_Unconstrained_Function checked that the function
1755 -- has no local declarations except implicit label declarations.
1756 -- Copy these declarations to the built procedure.
1757
1758 if Present (Declarations (N)) then
1759 Body_Decl_List := New_List;
1760
1761 declare
1762 D : Node_Id;
1763 New_D : Node_Id;
1764
1765 begin
1766 D := First (Declarations (N));
1767 while Present (D) loop
1768 pragma Assert (Nkind (D) = N_Implicit_Label_Declaration);
1769
1770 New_D :=
1771 Make_Implicit_Label_Declaration (Loc,
1772 Make_Defining_Identifier (Loc,
1773 Chars => Chars (Defining_Identifier (D))),
1774 Label_Construct => Empty);
1775 Append_To (Body_Decl_List, New_D);
1776
1777 Next (D);
1778 end loop;
1779 end;
1780 end if;
1781
1782 pragma Assert (Present (Handled_Statement_Sequence (Ret_Node)));
1783
1784 Proc_Body :=
1785 Make_Subprogram_Body (Loc,
1786 Specification => Copy_Separate_Tree (Proc_Spec),
1787 Declarations => Body_Decl_List,
1788 Handled_Statement_Sequence =>
1789 Copy_Separate_Tree (Handled_Statement_Sequence (Ret_Node)));
1790
1791 Set_Defining_Unit_Name (Specification (Proc_Body),
1792 Make_Defining_Identifier (Loc, Subp_Name));
1793
1794 Append_To (Decl_List, Proc_Body);
1795 end Build_Procedure;
1796
1797 -- Local variables
1798
1799 New_Obj : constant Node_Id := Copy_Separate_Tree (Ret_Obj);
1800 Blk_Stmt : Node_Id;
1801 Proc_Id : Entity_Id;
1802 Proc_Call : Node_Id;
1803
1804 -- Start of processing for Split_Unconstrained_Function
1805
1806 begin
1807 -- Build the associated procedure, analyze it and insert it before
3f80a182 1808 -- the function body N.
540d8610
ES
1809
1810 declare
1811 Scope : constant Entity_Id := Current_Scope;
1812 Decl_List : List_Id;
1813 begin
1814 Pop_Scope;
1815 Build_Procedure (Proc_Id, Decl_List);
1816 Insert_Actions (N, Decl_List);
1817 Push_Scope (Scope);
1818 end;
1819
1820 -- Build the call to the generated procedure
1821
1822 declare
1823 Actual_List : constant List_Id := New_List;
1824 Formal : Entity_Id;
1825
1826 begin
1827 Append_To (Actual_List,
1828 New_Occurrence_Of (Defining_Identifier (New_Obj), Loc));
1829
1830 Formal := First_Formal (Spec_Id);
1831 while Present (Formal) loop
1832 Append_To (Actual_List, New_Occurrence_Of (Formal, Loc));
1833
1834 -- Avoid spurious warning on unreferenced formals
1835
1836 Set_Referenced (Formal);
1837 Next_Formal (Formal);
1838 end loop;
1839
1840 Proc_Call :=
1841 Make_Procedure_Call_Statement (Loc,
3f80a182 1842 Name => New_Occurrence_Of (Proc_Id, Loc),
540d8610
ES
1843 Parameter_Associations => Actual_List);
1844 end;
1845
1846 -- Generate
1847
1848 -- declare
1849 -- New_Obj : ...
1850 -- begin
1851 -- main_1__F1b (New_Obj, ...);
1852 -- return Obj;
1853 -- end B10b;
1854
1855 Blk_Stmt :=
1856 Make_Block_Statement (Loc,
3f80a182 1857 Declarations => New_List (New_Obj),
540d8610
ES
1858 Handled_Statement_Sequence =>
1859 Make_Handled_Sequence_Of_Statements (Loc,
1860 Statements => New_List (
1861
1862 Proc_Call,
1863
1864 Make_Simple_Return_Statement (Loc,
1865 Expression =>
1866 New_Occurrence_Of
1867 (Defining_Identifier (New_Obj), Loc)))));
1868
1869 Rewrite (Ret_Node, Blk_Stmt);
1870 end Split_Unconstrained_Function;
1871
16b10ccc
AC
1872 -- Local variables
1873
1874 Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id);
1875
1876 -- Start of processing for Check_And_Split_Unconstrained_Function
540d8610
ES
1877
1878 begin
16b10ccc
AC
1879 pragma Assert (Back_End_Inlining
1880 and then Ekind (Spec_Id) = E_Function
1881 and then Returns_Unconstrained_Type (Spec_Id)
1882 and then Comes_From_Source (Body_Id)
1883 and then (Has_Pragma_Inline_Always (Spec_Id)
1884 or else Optimization_Level > 0));
1885
1886 -- This routine must not be used in GNATprove mode since GNATprove
1887 -- relies on frontend inlining
1888
1889 pragma Assert (not GNATprove_Mode);
1890
1891 -- No need to split the function if we cannot generate the code
1892
1893 if Serious_Errors_Detected /= 0 then
1894 return;
1895 end if;
1896
16b10ccc
AC
1897 -- No action needed in stubs since the attribute Body_To_Inline
1898 -- is not available
4bd4bb7f 1899
16b10ccc
AC
1900 if Nkind (Decl) = N_Subprogram_Body_Stub then
1901 return;
1902
1903 -- Cannot build the body to inline if the attribute is already set.
1904 -- This attribute may have been set if this is a subprogram renaming
1905 -- declarations (see Freeze.Build_Renamed_Body).
1906
1907 elsif Present (Body_To_Inline (Decl)) then
1908 return;
1909
1910 -- Check excluded declarations
1911
1912 elsif Present (Declarations (N))
1913 and then Has_Excluded_Declaration (Spec_Id, Declarations (N))
1914 then
1915 return;
1916
1917 -- Check excluded statements. There is no need to protect us against
1918 -- exception handlers since they are supported by the GCC backend.
1919
1920 elsif Present (Handled_Statement_Sequence (N))
1921 and then Has_Excluded_Statement
1922 (Spec_Id, Statements (Handled_Statement_Sequence (N)))
1923 then
1924 return;
540d8610
ES
1925 end if;
1926
1927 -- Build the body to inline only if really needed
1928
16b10ccc
AC
1929 if Can_Split_Unconstrained_Function (N) then
1930 Split_Unconstrained_Function (N, Spec_Id);
1931 Build_Body_To_Inline (N, Spec_Id);
1932 Set_Is_Inlined (Spec_Id);
540d8610 1933 end if;
16b10ccc 1934 end Check_And_Split_Unconstrained_Function;
3f80a182 1935
1773d80b
AC
1936 -------------------------------------
1937 -- Check_Package_Body_For_Inlining --
1938 -------------------------------------
540d8610 1939
1773d80b 1940 procedure Check_Package_Body_For_Inlining (N : Node_Id; P : Entity_Id) is
540d8610
ES
1941 Bname : Unit_Name_Type;
1942 E : Entity_Id;
1943 OK : Boolean;
1944
1945 begin
88f7d2d1
AC
1946 -- Legacy implementation (relying on frontend inlining)
1947
1948 if not Back_End_Inlining
039538bc 1949 and then Is_Compilation_Unit (P)
540d8610
ES
1950 and then not Is_Generic_Instance (P)
1951 then
1952 Bname := Get_Body_Name (Get_Unit_Name (Unit (N)));
1953
1954 E := First_Entity (P);
1955 while Present (E) loop
88f7d2d1
AC
1956 if Has_Pragma_Inline_Always (E)
1957 or else (Has_Pragma_Inline (E) and Front_End_Inlining)
1958 then
540d8610
ES
1959 if not Is_Loaded (Bname) then
1960 Load_Needed_Body (N, OK);
1961
1962 if OK then
1963
1964 -- Check we are not trying to inline a parent whose body
1965 -- depends on a child, when we are compiling the body of
1966 -- the child. Otherwise we have a potential elaboration
1967 -- circularity with inlined subprograms and with
1968 -- Taft-Amendment types.
1969
1970 declare
1971 Comp : Node_Id; -- Body just compiled
1972 Child_Spec : Entity_Id; -- Spec of main unit
1973 Ent : Entity_Id; -- For iteration
1974 With_Clause : Node_Id; -- Context of body.
1975
1976 begin
1977 if Nkind (Unit (Cunit (Main_Unit))) = N_Package_Body
1978 and then Present (Body_Entity (P))
1979 then
1980 Child_Spec :=
1981 Defining_Entity
1982 ((Unit (Library_Unit (Cunit (Main_Unit)))));
1983
1984 Comp :=
1985 Parent (Unit_Declaration_Node (Body_Entity (P)));
1986
1987 -- Check whether the context of the body just
1988 -- compiled includes a child of itself, and that
1989 -- child is the spec of the main compilation.
1990
1991 With_Clause := First (Context_Items (Comp));
1992 while Present (With_Clause) loop
1993 if Nkind (With_Clause) = N_With_Clause
1994 and then
1995 Scope (Entity (Name (With_Clause))) = P
1996 and then
1997 Entity (Name (With_Clause)) = Child_Spec
1998 then
1999 Error_Msg_Node_2 := Child_Spec;
2000 Error_Msg_NE
2001 ("body of & depends on child unit&??",
2002 With_Clause, P);
2003 Error_Msg_N
2004 ("\subprograms in body cannot be inlined??",
2005 With_Clause);
2006
2007 -- Disable further inlining from this unit,
2008 -- and keep Taft-amendment types incomplete.
2009
2010 Ent := First_Entity (P);
2011 while Present (Ent) loop
2012 if Is_Type (Ent)
3f80a182 2013 and then Has_Completion_In_Body (Ent)
540d8610
ES
2014 then
2015 Set_Full_View (Ent, Empty);
2016
2017 elsif Is_Subprogram (Ent) then
2018 Set_Is_Inlined (Ent, False);
2019 end if;
2020
2021 Next_Entity (Ent);
2022 end loop;
2023
2024 return;
2025 end if;
2026
2027 Next (With_Clause);
2028 end loop;
2029 end if;
2030 end;
2031
2032 elsif Ineffective_Inline_Warnings then
2033 Error_Msg_Unit_1 := Bname;
2034 Error_Msg_N
2035 ("unable to inline subprograms defined in $??", P);
2036 Error_Msg_N ("\body not found??", P);
2037 return;
2038 end if;
2039 end if;
2040
2041 return;
2042 end if;
2043
2044 Next_Entity (E);
2045 end loop;
2046 end if;
1773d80b 2047 end Check_Package_Body_For_Inlining;
540d8610
ES
2048
2049 --------------------
2050 -- Cleanup_Scopes --
2051 --------------------
2052
2053 procedure Cleanup_Scopes is
2054 Elmt : Elmt_Id;
2055 Decl : Node_Id;
2056 Scop : Entity_Id;
2057
2058 begin
2059 Elmt := First_Elmt (To_Clean);
2060 while Present (Elmt) loop
2061 Scop := Node (Elmt);
2062
2063 if Ekind (Scop) = E_Entry then
2064 Scop := Protected_Body_Subprogram (Scop);
2065
2066 elsif Is_Subprogram (Scop)
2067 and then Is_Protected_Type (Scope (Scop))
2068 and then Present (Protected_Body_Subprogram (Scop))
2069 then
3f80a182
AC
2070 -- If a protected operation contains an instance, its cleanup
2071 -- operations have been delayed, and the subprogram has been
2072 -- rewritten in the expansion of the enclosing protected body. It
2073 -- is the corresponding subprogram that may require the cleanup
2074 -- operations, so propagate the information that triggers cleanup
2075 -- activity.
540d8610
ES
2076
2077 Set_Uses_Sec_Stack
2078 (Protected_Body_Subprogram (Scop),
2079 Uses_Sec_Stack (Scop));
2080
2081 Scop := Protected_Body_Subprogram (Scop);
2082 end if;
2083
2084 if Ekind (Scop) = E_Block then
2085 Decl := Parent (Block_Node (Scop));
2086
2087 else
2088 Decl := Unit_Declaration_Node (Scop);
2089
3f80a182
AC
2090 if Nkind_In (Decl, N_Subprogram_Declaration,
2091 N_Task_Type_Declaration,
2092 N_Subprogram_Body_Stub)
540d8610
ES
2093 then
2094 Decl := Unit_Declaration_Node (Corresponding_Body (Decl));
2095 end if;
2096 end if;
2097
2098 Push_Scope (Scop);
2099 Expand_Cleanup_Actions (Decl);
2100 End_Scope;
2101
2102 Elmt := Next_Elmt (Elmt);
2103 end loop;
2104 end Cleanup_Scopes;
2105
2106 -------------------------
2107 -- Expand_Inlined_Call --
2108 -------------------------
2109
2110 procedure Expand_Inlined_Call
2111 (N : Node_Id;
2112 Subp : Entity_Id;
2113 Orig_Subp : Entity_Id)
2114 is
2115 Loc : constant Source_Ptr := Sloc (N);
2116 Is_Predef : constant Boolean :=
3f80a182
AC
2117 Is_Predefined_File_Name
2118 (Unit_File_Name (Get_Source_Unit (Subp)));
540d8610
ES
2119 Orig_Bod : constant Node_Id :=
2120 Body_To_Inline (Unit_Declaration_Node (Subp));
2121
2122 Blk : Node_Id;
2123 Decl : Node_Id;
2124 Decls : constant List_Id := New_List;
3f80a182 2125 Exit_Lab : Entity_Id := Empty;
540d8610
ES
2126 F : Entity_Id;
2127 A : Node_Id;
2128 Lab_Decl : Node_Id;
2129 Lab_Id : Node_Id;
2130 New_A : Node_Id;
2131 Num_Ret : Int := 0;
2132 Ret_Type : Entity_Id;
2133
2134 Targ : Node_Id;
2135 -- The target of the call. If context is an assignment statement then
2136 -- this is the left-hand side of the assignment, else it is a temporary
2137 -- to which the return value is assigned prior to rewriting the call.
2138
2139 Targ1 : Node_Id;
2140 -- A separate target used when the return type is unconstrained
2141
2142 Temp : Entity_Id;
2143 Temp_Typ : Entity_Id;
2144
2145 Return_Object : Entity_Id := Empty;
2146 -- Entity in declaration in an extended_return_statement
2147
2148 Is_Unc : Boolean;
2149 Is_Unc_Decl : Boolean;
2150 -- If the type returned by the function is unconstrained and the call
2151 -- can be inlined, special processing is required.
2152
2153 procedure Make_Exit_Label;
2154 -- Build declaration for exit label to be used in Return statements,
2155 -- sets Exit_Lab (the label node) and Lab_Decl (corresponding implicit
2156 -- declaration). Does nothing if Exit_Lab already set.
2157
2158 function Process_Formals (N : Node_Id) return Traverse_Result;
2159 -- Replace occurrence of a formal with the corresponding actual, or the
2160 -- thunk generated for it. Replace a return statement with an assignment
2161 -- to the target of the call, with appropriate conversions if needed.
2162
2163 function Process_Sloc (Nod : Node_Id) return Traverse_Result;
2164 -- If the call being expanded is that of an internal subprogram, set the
2165 -- sloc of the generated block to that of the call itself, so that the
52c1498c
YM
2166 -- expansion is skipped by the "next" command in gdb. Same processing
2167 -- for a subprogram in a predefined file, e.g. Ada.Tags. If
2168 -- Debug_Generated_Code is true, suppress this change to simplify our
2169 -- own development. Same in GNATprove mode, to ensure that warnings and
2170 -- diagnostics point to the proper location.
540d8610
ES
2171
2172 procedure Reset_Dispatching_Calls (N : Node_Id);
2173 -- In subtree N search for occurrences of dispatching calls that use the
2174 -- Ada 2005 Object.Operation notation and the object is a formal of the
2175 -- inlined subprogram. Reset the entity associated with Operation in all
2176 -- the found occurrences.
2177
2178 procedure Rewrite_Function_Call (N : Node_Id; Blk : Node_Id);
2179 -- If the function body is a single expression, replace call with
2180 -- expression, else insert block appropriately.
2181
2182 procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id);
2183 -- If procedure body has no local variables, inline body without
2184 -- creating block, otherwise rewrite call with block.
2185
2186 function Formal_Is_Used_Once (Formal : Entity_Id) return Boolean;
2187 -- Determine whether a formal parameter is used only once in Orig_Bod
2188
2189 ---------------------
2190 -- Make_Exit_Label --
2191 ---------------------
2192
2193 procedure Make_Exit_Label is
2194 Lab_Ent : Entity_Id;
2195 begin
2196 if No (Exit_Lab) then
2197 Lab_Ent := Make_Temporary (Loc, 'L');
2198 Lab_Id := New_Occurrence_Of (Lab_Ent, Loc);
2199 Exit_Lab := Make_Label (Loc, Lab_Id);
2200 Lab_Decl :=
2201 Make_Implicit_Label_Declaration (Loc,
3f80a182
AC
2202 Defining_Identifier => Lab_Ent,
2203 Label_Construct => Exit_Lab);
540d8610
ES
2204 end if;
2205 end Make_Exit_Label;
2206
2207 ---------------------
2208 -- Process_Formals --
2209 ---------------------
2210
2211 function Process_Formals (N : Node_Id) return Traverse_Result is
2212 A : Entity_Id;
2213 E : Entity_Id;
2214 Ret : Node_Id;
2215
2216 begin
2217 if Is_Entity_Name (N) and then Present (Entity (N)) then
2218 E := Entity (N);
2219
2220 if Is_Formal (E) and then Scope (E) = Subp then
2221 A := Renamed_Object (E);
2222
2223 -- Rewrite the occurrence of the formal into an occurrence of
2224 -- the actual. Also establish visibility on the proper view of
2225 -- the actual's subtype for the body's context (if the actual's
2226 -- subtype is private at the call point but its full view is
2227 -- visible to the body, then the inlined tree here must be
2228 -- analyzed with the full view).
2229
2230 if Is_Entity_Name (A) then
2231 Rewrite (N, New_Occurrence_Of (Entity (A), Loc));
2232 Check_Private_View (N);
2233
2234 elsif Nkind (A) = N_Defining_Identifier then
2235 Rewrite (N, New_Occurrence_Of (A, Loc));
2236 Check_Private_View (N);
2237
2238 -- Numeric literal
2239
2240 else
2241 Rewrite (N, New_Copy (A));
2242 end if;
2243 end if;
2244
2245 return Skip;
2246
2247 elsif Is_Entity_Name (N)
2248 and then Present (Return_Object)
2249 and then Chars (N) = Chars (Return_Object)
2250 then
2251 -- Occurrence within an extended return statement. The return
2252 -- object is local to the body been inlined, and thus the generic
2253 -- copy is not analyzed yet, so we match by name, and replace it
2254 -- with target of call.
2255
2256 if Nkind (Targ) = N_Defining_Identifier then
2257 Rewrite (N, New_Occurrence_Of (Targ, Loc));
2258 else
2259 Rewrite (N, New_Copy_Tree (Targ));
2260 end if;
2261
2262 return Skip;
2263
2264 elsif Nkind (N) = N_Simple_Return_Statement then
2265 if No (Expression (N)) then
2266 Make_Exit_Label;
2267 Rewrite (N,
2268 Make_Goto_Statement (Loc, Name => New_Copy (Lab_Id)));
2269
2270 else
2271 if Nkind (Parent (N)) = N_Handled_Sequence_Of_Statements
2272 and then Nkind (Parent (Parent (N))) = N_Subprogram_Body
2273 then
2274 -- Function body is a single expression. No need for
2275 -- exit label.
2276
2277 null;
2278
2279 else
2280 Num_Ret := Num_Ret + 1;
2281 Make_Exit_Label;
2282 end if;
2283
2284 -- Because of the presence of private types, the views of the
2285 -- expression and the context may be different, so place an
2286 -- unchecked conversion to the context type to avoid spurious
2287 -- errors, e.g. when the expression is a numeric literal and
2288 -- the context is private. If the expression is an aggregate,
2289 -- use a qualified expression, because an aggregate is not a
2290 -- legal argument of a conversion. Ditto for numeric literals,
2291 -- which must be resolved to a specific type.
2292
2293 if Nkind_In (Expression (N), N_Aggregate,
2294 N_Null,
2295 N_Real_Literal,
2296 N_Integer_Literal)
2297 then
2298 Ret :=
2299 Make_Qualified_Expression (Sloc (N),
2300 Subtype_Mark => New_Occurrence_Of (Ret_Type, Sloc (N)),
3f80a182 2301 Expression => Relocate_Node (Expression (N)));
540d8610
ES
2302 else
2303 Ret :=
2304 Unchecked_Convert_To
2305 (Ret_Type, Relocate_Node (Expression (N)));
2306 end if;
2307
2308 if Nkind (Targ) = N_Defining_Identifier then
2309 Rewrite (N,
2310 Make_Assignment_Statement (Loc,
2311 Name => New_Occurrence_Of (Targ, Loc),
2312 Expression => Ret));
2313 else
2314 Rewrite (N,
2315 Make_Assignment_Statement (Loc,
2316 Name => New_Copy (Targ),
2317 Expression => Ret));
2318 end if;
2319
2320 Set_Assignment_OK (Name (N));
2321
2322 if Present (Exit_Lab) then
2323 Insert_After (N,
2324 Make_Goto_Statement (Loc, Name => New_Copy (Lab_Id)));
2325 end if;
2326 end if;
2327
2328 return OK;
2329
2330 -- An extended return becomes a block whose first statement is the
2331 -- assignment of the initial expression of the return object to the
2332 -- target of the call itself.
2333
2334 elsif Nkind (N) = N_Extended_Return_Statement then
2335 declare
2336 Return_Decl : constant Entity_Id :=
2337 First (Return_Object_Declarations (N));
2338 Assign : Node_Id;
2339
2340 begin
2341 Return_Object := Defining_Identifier (Return_Decl);
2342
2343 if Present (Expression (Return_Decl)) then
2344 if Nkind (Targ) = N_Defining_Identifier then
2345 Assign :=
2346 Make_Assignment_Statement (Loc,
2347 Name => New_Occurrence_Of (Targ, Loc),
2348 Expression => Expression (Return_Decl));
2349 else
2350 Assign :=
2351 Make_Assignment_Statement (Loc,
2352 Name => New_Copy (Targ),
2353 Expression => Expression (Return_Decl));
2354 end if;
2355
2356 Set_Assignment_OK (Name (Assign));
2357
2358 if No (Handled_Statement_Sequence (N)) then
2359 Set_Handled_Statement_Sequence (N,
2360 Make_Handled_Sequence_Of_Statements (Loc,
2361 Statements => New_List));
2362 end if;
2363
2364 Prepend (Assign,
2365 Statements (Handled_Statement_Sequence (N)));
2366 end if;
2367
2368 Rewrite (N,
2369 Make_Block_Statement (Loc,
2370 Handled_Statement_Sequence =>
2371 Handled_Statement_Sequence (N)));
2372
2373 return OK;
2374 end;
2375
2376 -- Remove pragma Unreferenced since it may refer to formals that
2377 -- are not visible in the inlined body, and in any case we will
2378 -- not be posting warnings on the inlined body so it is unneeded.
2379
2380 elsif Nkind (N) = N_Pragma
2381 and then Pragma_Name (N) = Name_Unreferenced
2382 then
2383 Rewrite (N, Make_Null_Statement (Sloc (N)));
2384 return OK;
2385
2386 else
2387 return OK;
2388 end if;
2389 end Process_Formals;
2390
2391 procedure Replace_Formals is new Traverse_Proc (Process_Formals);
2392
2393 ------------------
2394 -- Process_Sloc --
2395 ------------------
2396
2397 function Process_Sloc (Nod : Node_Id) return Traverse_Result is
2398 begin
2399 if not Debug_Generated_Code then
2400 Set_Sloc (Nod, Sloc (N));
2401 Set_Comes_From_Source (Nod, False);
2402 end if;
2403
2404 return OK;
2405 end Process_Sloc;
2406
2407 procedure Reset_Slocs is new Traverse_Proc (Process_Sloc);
2408
2409 ------------------------------
2410 -- Reset_Dispatching_Calls --
2411 ------------------------------
2412
2413 procedure Reset_Dispatching_Calls (N : Node_Id) is
2414
2415 function Do_Reset (N : Node_Id) return Traverse_Result;
2416 -- Comment required ???
2417
2418 --------------
2419 -- Do_Reset --
2420 --------------
2421
2422 function Do_Reset (N : Node_Id) return Traverse_Result is
2423 begin
2424 if Nkind (N) = N_Procedure_Call_Statement
2425 and then Nkind (Name (N)) = N_Selected_Component
2426 and then Nkind (Prefix (Name (N))) = N_Identifier
2427 and then Is_Formal (Entity (Prefix (Name (N))))
2428 and then Is_Dispatching_Operation
2429 (Entity (Selector_Name (Name (N))))
2430 then
2431 Set_Entity (Selector_Name (Name (N)), Empty);
2432 end if;
2433
2434 return OK;
2435 end Do_Reset;
2436
2437 function Do_Reset_Calls is new Traverse_Func (Do_Reset);
2438
2439 -- Local variables
2440
2441 Dummy : constant Traverse_Result := Do_Reset_Calls (N);
2442 pragma Unreferenced (Dummy);
2443
2444 -- Start of processing for Reset_Dispatching_Calls
2445
2446 begin
2447 null;
2448 end Reset_Dispatching_Calls;
2449
2450 ---------------------------
2451 -- Rewrite_Function_Call --
2452 ---------------------------
2453
2454 procedure Rewrite_Function_Call (N : Node_Id; Blk : Node_Id) is
2455 HSS : constant Node_Id := Handled_Statement_Sequence (Blk);
2456 Fst : constant Node_Id := First (Statements (HSS));
2457
2458 begin
2459 -- Optimize simple case: function body is a single return statement,
2460 -- which has been expanded into an assignment.
2461
2462 if Is_Empty_List (Declarations (Blk))
2463 and then Nkind (Fst) = N_Assignment_Statement
2464 and then No (Next (Fst))
2465 then
2466 -- The function call may have been rewritten as the temporary
2467 -- that holds the result of the call, in which case remove the
2468 -- now useless declaration.
2469
2470 if Nkind (N) = N_Identifier
2471 and then Nkind (Parent (Entity (N))) = N_Object_Declaration
2472 then
2473 Rewrite (Parent (Entity (N)), Make_Null_Statement (Loc));
2474 end if;
2475
2476 Rewrite (N, Expression (Fst));
2477
2478 elsif Nkind (N) = N_Identifier
2479 and then Nkind (Parent (Entity (N))) = N_Object_Declaration
2480 then
2481 -- The block assigns the result of the call to the temporary
2482
2483 Insert_After (Parent (Entity (N)), Blk);
2484
2485 -- If the context is an assignment, and the left-hand side is free of
2486 -- side-effects, the replacement is also safe.
2487 -- Can this be generalized further???
2488
2489 elsif Nkind (Parent (N)) = N_Assignment_Statement
2490 and then
2491 (Is_Entity_Name (Name (Parent (N)))
2492 or else
2493 (Nkind (Name (Parent (N))) = N_Explicit_Dereference
2494 and then Is_Entity_Name (Prefix (Name (Parent (N)))))
2495
2496 or else
2497 (Nkind (Name (Parent (N))) = N_Selected_Component
2498 and then Is_Entity_Name (Prefix (Name (Parent (N))))))
2499 then
2500 -- Replace assignment with the block
2501
2502 declare
2503 Original_Assignment : constant Node_Id := Parent (N);
2504
2505 begin
2506 -- Preserve the original assignment node to keep the complete
2507 -- assignment subtree consistent enough for Analyze_Assignment
2508 -- to proceed (specifically, the original Lhs node must still
2509 -- have an assignment statement as its parent).
2510
2511 -- We cannot rely on Original_Node to go back from the block
2512 -- node to the assignment node, because the assignment might
2513 -- already be a rewrite substitution.
2514
2515 Discard_Node (Relocate_Node (Original_Assignment));
2516 Rewrite (Original_Assignment, Blk);
2517 end;
2518
2519 elsif Nkind (Parent (N)) = N_Object_Declaration then
2520
2521 -- A call to a function which returns an unconstrained type
2522 -- found in the expression initializing an object-declaration is
2523 -- expanded into a procedure call which must be added after the
2524 -- object declaration.
2525
ea0c8cfb 2526 if Is_Unc_Decl and Back_End_Inlining then
540d8610
ES
2527 Insert_Action_After (Parent (N), Blk);
2528 else
2529 Set_Expression (Parent (N), Empty);
2530 Insert_After (Parent (N), Blk);
2531 end if;
2532
6c26bac2 2533 elsif Is_Unc and then not Back_End_Inlining then
540d8610
ES
2534 Insert_Before (Parent (N), Blk);
2535 end if;
2536 end Rewrite_Function_Call;
2537
2538 ----------------------------
2539 -- Rewrite_Procedure_Call --
2540 ----------------------------
2541
2542 procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id) is
2543 HSS : constant Node_Id := Handled_Statement_Sequence (Blk);
2544
2545 begin
2546 -- If there is a transient scope for N, this will be the scope of the
2547 -- actions for N, and the statements in Blk need to be within this
2548 -- scope. For example, they need to have visibility on the constant
2549 -- declarations created for the formals.
2550
2551 -- If N needs no transient scope, and if there are no declarations in
2552 -- the inlined body, we can do a little optimization and insert the
2553 -- statements for the body directly after N, and rewrite N to a
2554 -- null statement, instead of rewriting N into a full-blown block
2555 -- statement.
2556
2557 if not Scope_Is_Transient
2558 and then Is_Empty_List (Declarations (Blk))
2559 then
2560 Insert_List_After (N, Statements (HSS));
2561 Rewrite (N, Make_Null_Statement (Loc));
2562 else
2563 Rewrite (N, Blk);
2564 end if;
2565 end Rewrite_Procedure_Call;
2566
2567 -------------------------
2568 -- Formal_Is_Used_Once --
2569 -------------------------
2570
2571 function Formal_Is_Used_Once (Formal : Entity_Id) return Boolean is
2572 Use_Counter : Int := 0;
2573
2574 function Count_Uses (N : Node_Id) return Traverse_Result;
2575 -- Traverse the tree and count the uses of the formal parameter.
2576 -- In this case, for optimization purposes, we do not need to
2577 -- continue the traversal once more than one use is encountered.
2578
2579 ----------------
2580 -- Count_Uses --
2581 ----------------
2582
2583 function Count_Uses (N : Node_Id) return Traverse_Result is
2584 begin
2585 -- The original node is an identifier
2586
2587 if Nkind (N) = N_Identifier
2588 and then Present (Entity (N))
2589
2590 -- Original node's entity points to the one in the copied body
2591
2592 and then Nkind (Entity (N)) = N_Identifier
2593 and then Present (Entity (Entity (N)))
2594
2595 -- The entity of the copied node is the formal parameter
2596
2597 and then Entity (Entity (N)) = Formal
2598 then
2599 Use_Counter := Use_Counter + 1;
2600
2601 if Use_Counter > 1 then
2602
2603 -- Denote more than one use and abandon the traversal
2604
2605 Use_Counter := 2;
2606 return Abandon;
2607
2608 end if;
2609 end if;
2610
2611 return OK;
2612 end Count_Uses;
2613
2614 procedure Count_Formal_Uses is new Traverse_Proc (Count_Uses);
2615
2616 -- Start of processing for Formal_Is_Used_Once
2617
2618 begin
2619 Count_Formal_Uses (Orig_Bod);
2620 return Use_Counter = 1;
2621 end Formal_Is_Used_Once;
2622
2623 -- Start of processing for Expand_Inlined_Call
2624
2625 begin
2626 -- Initializations for old/new semantics
2627
6c26bac2 2628 if not Back_End_Inlining then
540d8610
ES
2629 Is_Unc := Is_Array_Type (Etype (Subp))
2630 and then not Is_Constrained (Etype (Subp));
2631 Is_Unc_Decl := False;
2632 else
2633 Is_Unc := Returns_Unconstrained_Type (Subp)
2634 and then Optimization_Level > 0;
2635 Is_Unc_Decl := Nkind (Parent (N)) = N_Object_Declaration
2636 and then Is_Unc;
2637 end if;
2638
2639 -- Check for an illegal attempt to inline a recursive procedure. If the
2640 -- subprogram has parameters this is detected when trying to supply a
2641 -- binding for parameters that already have one. For parameterless
2642 -- subprograms this must be done explicitly.
2643
2644 if In_Open_Scopes (Subp) then
2645 Error_Msg_N ("call to recursive subprogram cannot be inlined??", N);
2646 Set_Is_Inlined (Subp, False);
4bd4bb7f
AC
2647
2648 -- In GNATprove mode, issue a warning, and indicate that the
2649 -- subprogram is not always inlined by setting flag Is_Inlined_Always
2650 -- to False.
2651
2652 if GNATprove_Mode then
2653 Set_Is_Inlined_Always (Subp, False);
2654 end if;
2655
540d8610
ES
2656 return;
2657
2658 -- Skip inlining if this is not a true inlining since the attribute
2659 -- Body_To_Inline is also set for renamings (see sinfo.ads)
2660
2661 elsif Nkind (Orig_Bod) in N_Entity then
d99565f8
AC
2662 if not Has_Pragma_Inline (Subp) then
2663 return;
2664 end if;
540d8610
ES
2665
2666 -- Skip inlining if the function returns an unconstrained type using
2667 -- an extended return statement since this part of the new inlining
2668 -- model which is not yet supported by the current implementation. ???
2669
2670 elsif Is_Unc
2671 and then
2672 Nkind (First (Statements (Handled_Statement_Sequence (Orig_Bod))))
2673 = N_Extended_Return_Statement
6c26bac2 2674 and then not Back_End_Inlining
540d8610
ES
2675 then
2676 return;
2677 end if;
2678
2679 if Nkind (Orig_Bod) = N_Defining_Identifier
2680 or else Nkind (Orig_Bod) = N_Defining_Operator_Symbol
2681 then
2682 -- Subprogram is renaming_as_body. Calls occurring after the renaming
2683 -- can be replaced with calls to the renamed entity directly, because
2684 -- the subprograms are subtype conformant. If the renamed subprogram
2685 -- is an inherited operation, we must redo the expansion because
2686 -- implicit conversions may be needed. Similarly, if the renamed
2687 -- entity is inlined, expand the call for further optimizations.
2688
2689 Set_Name (N, New_Occurrence_Of (Orig_Bod, Loc));
2690
2691 if Present (Alias (Orig_Bod)) or else Is_Inlined (Orig_Bod) then
2692 Expand_Call (N);
2693 end if;
2694
2695 return;
2696 end if;
2697
2698 -- Register the call in the list of inlined calls
2699
21c51f53 2700 Append_New_Elmt (N, To => Inlined_Calls);
540d8610
ES
2701
2702 -- Use generic machinery to copy body of inlined subprogram, as if it
2703 -- were an instantiation, resetting source locations appropriately, so
2704 -- that nested inlined calls appear in the main unit.
2705
2706 Save_Env (Subp, Empty);
2707 Set_Copied_Sloc_For_Inlined_Body (N, Defining_Entity (Orig_Bod));
2708
2709 -- Old semantics
2710
6c26bac2 2711 if not Back_End_Inlining then
540d8610
ES
2712 declare
2713 Bod : Node_Id;
2714
2715 begin
2716 Bod := Copy_Generic_Node (Orig_Bod, Empty, Instantiating => True);
2717 Blk :=
2718 Make_Block_Statement (Loc,
3f80a182 2719 Declarations => Declarations (Bod),
540d8610
ES
2720 Handled_Statement_Sequence =>
2721 Handled_Statement_Sequence (Bod));
2722
2723 if No (Declarations (Bod)) then
2724 Set_Declarations (Blk, New_List);
2725 end if;
2726
2727 -- For the unconstrained case, capture the name of the local
2728 -- variable that holds the result. This must be the first
2729 -- declaration in the block, because its bounds cannot depend
2730 -- on local variables. Otherwise there is no way to declare the
2731 -- result outside of the block. Needless to say, in general the
2732 -- bounds will depend on the actuals in the call.
2733
2734 -- If the context is an assignment statement, as is the case
2735 -- for the expansion of an extended return, the left-hand side
2736 -- provides bounds even if the return type is unconstrained.
2737
2738 if Is_Unc then
2739 declare
2740 First_Decl : Node_Id;
2741
2742 begin
2743 First_Decl := First (Declarations (Blk));
2744
2745 if Nkind (First_Decl) /= N_Object_Declaration then
2746 return;
2747 end if;
2748
2749 if Nkind (Parent (N)) /= N_Assignment_Statement then
2750 Targ1 := Defining_Identifier (First_Decl);
2751 else
2752 Targ1 := Name (Parent (N));
2753 end if;
2754 end;
2755 end if;
2756 end;
2757
2758 -- New semantics
2759
2760 else
2761 declare
2762 Bod : Node_Id;
2763
2764 begin
2765 -- General case
2766
2767 if not Is_Unc then
2768 Bod :=
2769 Copy_Generic_Node (Orig_Bod, Empty, Instantiating => True);
2770 Blk :=
2771 Make_Block_Statement (Loc,
3f80a182
AC
2772 Declarations => Declarations (Bod),
2773 Handled_Statement_Sequence =>
2774 Handled_Statement_Sequence (Bod));
540d8610
ES
2775
2776 -- Inline a call to a function that returns an unconstrained type.
2777 -- The semantic analyzer checked that frontend-inlined functions
2778 -- returning unconstrained types have no declarations and have
2779 -- a single extended return statement. As part of its processing
2780 -- the function was split in two subprograms: a procedure P and
2781 -- a function F that has a block with a call to procedure P (see
2782 -- Split_Unconstrained_Function).
2783
2784 else
2785 pragma Assert
2786 (Nkind
2787 (First
3f80a182
AC
2788 (Statements (Handled_Statement_Sequence (Orig_Bod)))) =
2789 N_Block_Statement);
540d8610
ES
2790
2791 declare
2792 Blk_Stmt : constant Node_Id :=
3f80a182 2793 First (Statements (Handled_Statement_Sequence (Orig_Bod)));
540d8610 2794 First_Stmt : constant Node_Id :=
3f80a182 2795 First (Statements (Handled_Statement_Sequence (Blk_Stmt)));
540d8610
ES
2796 Second_Stmt : constant Node_Id := Next (First_Stmt);
2797
2798 begin
2799 pragma Assert
2800 (Nkind (First_Stmt) = N_Procedure_Call_Statement
2801 and then Nkind (Second_Stmt) = N_Simple_Return_Statement
2802 and then No (Next (Second_Stmt)));
2803
2804 Bod :=
2805 Copy_Generic_Node
2806 (First
2807 (Statements (Handled_Statement_Sequence (Orig_Bod))),
2808 Empty, Instantiating => True);
2809 Blk := Bod;
2810
2811 -- Capture the name of the local variable that holds the
2812 -- result. This must be the first declaration in the block,
2813 -- because its bounds cannot depend on local variables.
2814 -- Otherwise there is no way to declare the result outside
2815 -- of the block. Needless to say, in general the bounds will
2816 -- depend on the actuals in the call.
2817
2818 if Nkind (Parent (N)) /= N_Assignment_Statement then
2819 Targ1 := Defining_Identifier (First (Declarations (Blk)));
2820
2821 -- If the context is an assignment statement, as is the case
2822 -- for the expansion of an extended return, the left-hand
2823 -- side provides bounds even if the return type is
2824 -- unconstrained.
2825
2826 else
2827 Targ1 := Name (Parent (N));
2828 end if;
2829 end;
2830 end if;
2831
2832 if No (Declarations (Bod)) then
2833 Set_Declarations (Blk, New_List);
2834 end if;
2835 end;
2836 end if;
2837
2838 -- If this is a derived function, establish the proper return type
2839
2840 if Present (Orig_Subp) and then Orig_Subp /= Subp then
2841 Ret_Type := Etype (Orig_Subp);
2842 else
2843 Ret_Type := Etype (Subp);
2844 end if;
2845
2846 -- Create temporaries for the actuals that are expressions, or that are
2847 -- scalars and require copying to preserve semantics.
2848
2849 F := First_Formal (Subp);
2850 A := First_Actual (N);
2851 while Present (F) loop
2852 if Present (Renamed_Object (F)) then
4e6768ab 2853
662c2ad4 2854 -- If expander is active, it is an error to try to inline a
52c1498c
YM
2855 -- recursive program. In GNATprove mode, just indicate that the
2856 -- inlining will not happen, and mark the subprogram as not always
2857 -- inlined.
4e6768ab 2858
4bd4bb7f 2859 if GNATprove_Mode then
4e6768ab
AC
2860 Cannot_Inline
2861 ("cannot inline call to recursive subprogram?", N, Subp);
4bd4bb7f
AC
2862 Set_Is_Inlined_Always (Subp, False);
2863 else
2864 Error_Msg_N
2865 ("cannot inline call to recursive subprogram", N);
4e6768ab
AC
2866 end if;
2867
540d8610
ES
2868 return;
2869 end if;
2870
2871 -- Reset Last_Assignment for any parameters of mode out or in out, to
2872 -- prevent spurious warnings about overwriting for assignments to the
2873 -- formal in the inlined code.
2874
2875 if Is_Entity_Name (A) and then Ekind (F) /= E_In_Parameter then
2876 Set_Last_Assignment (Entity (A), Empty);
2877 end if;
2878
2879 -- If the argument may be a controlling argument in a call within
2880 -- the inlined body, we must preserve its classwide nature to insure
2881 -- that dynamic dispatching take place subsequently. If the formal
2882 -- has a constraint it must be preserved to retain the semantics of
2883 -- the body.
2884
2885 if Is_Class_Wide_Type (Etype (F))
2886 or else (Is_Access_Type (Etype (F))
2887 and then Is_Class_Wide_Type (Designated_Type (Etype (F))))
2888 then
2889 Temp_Typ := Etype (F);
2890
2891 elsif Base_Type (Etype (F)) = Base_Type (Etype (A))
2892 and then Etype (F) /= Base_Type (Etype (F))
2893 then
2894 Temp_Typ := Etype (F);
2895 else
2896 Temp_Typ := Etype (A);
2897 end if;
2898
2899 -- If the actual is a simple name or a literal, no need to
2900 -- create a temporary, object can be used directly.
2901
2902 -- If the actual is a literal and the formal has its address taken,
2903 -- we cannot pass the literal itself as an argument, so its value
2904 -- must be captured in a temporary.
2905
2906 if (Is_Entity_Name (A)
2907 and then
2908 (not Is_Scalar_Type (Etype (A))
2909 or else Ekind (Entity (A)) = E_Enumeration_Literal))
2910
2911 -- When the actual is an identifier and the corresponding formal is
2912 -- used only once in the original body, the formal can be substituted
2913 -- directly with the actual parameter.
2914
2915 or else (Nkind (A) = N_Identifier
2916 and then Formal_Is_Used_Once (F))
2917
2918 or else
2919 (Nkind_In (A, N_Real_Literal,
2920 N_Integer_Literal,
2921 N_Character_Literal)
2922 and then not Address_Taken (F))
2923 then
2924 if Etype (F) /= Etype (A) then
2925 Set_Renamed_Object
2926 (F, Unchecked_Convert_To (Etype (F), Relocate_Node (A)));
2927 else
2928 Set_Renamed_Object (F, A);
2929 end if;
2930
2931 else
2932 Temp := Make_Temporary (Loc, 'C');
2933
2934 -- If the actual for an in/in-out parameter is a view conversion,
2935 -- make it into an unchecked conversion, given that an untagged
2936 -- type conversion is not a proper object for a renaming.
2937
2938 -- In-out conversions that involve real conversions have already
2939 -- been transformed in Expand_Actuals.
2940
2941 if Nkind (A) = N_Type_Conversion
2942 and then Ekind (F) /= E_In_Parameter
2943 then
2944 New_A :=
2945 Make_Unchecked_Type_Conversion (Loc,
2946 Subtype_Mark => New_Occurrence_Of (Etype (F), Loc),
2947 Expression => Relocate_Node (Expression (A)));
2948
2949 elsif Etype (F) /= Etype (A) then
2950 New_A := Unchecked_Convert_To (Etype (F), Relocate_Node (A));
2951 Temp_Typ := Etype (F);
2952
2953 else
2954 New_A := Relocate_Node (A);
2955 end if;
2956
2957 Set_Sloc (New_A, Sloc (N));
2958
2959 -- If the actual has a by-reference type, it cannot be copied,
2960 -- so its value is captured in a renaming declaration. Otherwise
2961 -- declare a local constant initialized with the actual.
2962
2963 -- We also use a renaming declaration for expressions of an array
2964 -- type that is not bit-packed, both for efficiency reasons and to
2965 -- respect the semantics of the call: in most cases the original
2966 -- call will pass the parameter by reference, and thus the inlined
2967 -- code will have the same semantics.
2968
36428cc4
AC
2969 -- Finally, we need a renaming declaration in the case of limited
2970 -- types for which initialization cannot be by copy either.
2971
540d8610
ES
2972 if Ekind (F) = E_In_Parameter
2973 and then not Is_By_Reference_Type (Etype (A))
36428cc4 2974 and then not Is_Limited_Type (Etype (A))
540d8610
ES
2975 and then
2976 (not Is_Array_Type (Etype (A))
2977 or else not Is_Object_Reference (A)
2978 or else Is_Bit_Packed_Array (Etype (A)))
2979 then
2980 Decl :=
2981 Make_Object_Declaration (Loc,
2982 Defining_Identifier => Temp,
2983 Constant_Present => True,
2984 Object_Definition => New_Occurrence_Of (Temp_Typ, Loc),
2985 Expression => New_A);
2986 else
2987 Decl :=
2988 Make_Object_Renaming_Declaration (Loc,
2989 Defining_Identifier => Temp,
2990 Subtype_Mark => New_Occurrence_Of (Temp_Typ, Loc),
2991 Name => New_A);
2992 end if;
2993
2994 Append (Decl, Decls);
2995 Set_Renamed_Object (F, Temp);
2996 end if;
2997
2998 Next_Formal (F);
2999 Next_Actual (A);
3000 end loop;
3001
3002 -- Establish target of function call. If context is not assignment or
3003 -- declaration, create a temporary as a target. The declaration for the
3004 -- temporary may be subsequently optimized away if the body is a single
3005 -- expression, or if the left-hand side of the assignment is simple
3006 -- enough, i.e. an entity or an explicit dereference of one.
3007
3008 if Ekind (Subp) = E_Function then
3009 if Nkind (Parent (N)) = N_Assignment_Statement
3010 and then Is_Entity_Name (Name (Parent (N)))
3011 then
3012 Targ := Name (Parent (N));
3013
3014 elsif Nkind (Parent (N)) = N_Assignment_Statement
3015 and then Nkind (Name (Parent (N))) = N_Explicit_Dereference
3016 and then Is_Entity_Name (Prefix (Name (Parent (N))))
3017 then
3018 Targ := Name (Parent (N));
3019
3020 elsif Nkind (Parent (N)) = N_Assignment_Statement
3021 and then Nkind (Name (Parent (N))) = N_Selected_Component
3022 and then Is_Entity_Name (Prefix (Name (Parent (N))))
3023 then
3024 Targ := New_Copy_Tree (Name (Parent (N)));
3025
3026 elsif Nkind (Parent (N)) = N_Object_Declaration
3027 and then Is_Limited_Type (Etype (Subp))
3028 then
3029 Targ := Defining_Identifier (Parent (N));
3030
3031 -- New semantics: In an object declaration avoid an extra copy
3032 -- of the result of a call to an inlined function that returns
3033 -- an unconstrained type
3034
6c26bac2 3035 elsif Back_End_Inlining
540d8610
ES
3036 and then Nkind (Parent (N)) = N_Object_Declaration
3037 and then Is_Unc
3038 then
3039 Targ := Defining_Identifier (Parent (N));
3040
3041 else
3042 -- Replace call with temporary and create its declaration
3043
3044 Temp := Make_Temporary (Loc, 'C');
3045 Set_Is_Internal (Temp);
3046
3047 -- For the unconstrained case, the generated temporary has the
3048 -- same constrained declaration as the result variable. It may
3049 -- eventually be possible to remove that temporary and use the
3050 -- result variable directly.
3051
3f80a182 3052 if Is_Unc and then Nkind (Parent (N)) /= N_Assignment_Statement
540d8610
ES
3053 then
3054 Decl :=
3055 Make_Object_Declaration (Loc,
3056 Defining_Identifier => Temp,
3057 Object_Definition =>
3058 New_Copy_Tree (Object_Definition (Parent (Targ1))));
3059
3060 Replace_Formals (Decl);
3061
3062 else
3063 Decl :=
3064 Make_Object_Declaration (Loc,
3065 Defining_Identifier => Temp,
3066 Object_Definition => New_Occurrence_Of (Ret_Type, Loc));
3067
3068 Set_Etype (Temp, Ret_Type);
3069 end if;
3070
3071 Set_No_Initialization (Decl);
3072 Append (Decl, Decls);
3073 Rewrite (N, New_Occurrence_Of (Temp, Loc));
3074 Targ := Temp;
3075 end if;
3076 end if;
3077
3078 Insert_Actions (N, Decls);
3079
3080 if Is_Unc_Decl then
3081
3082 -- Special management for inlining a call to a function that returns
3083 -- an unconstrained type and initializes an object declaration: we
3084 -- avoid generating undesired extra calls and goto statements.
3085
3086 -- Given:
3087 -- function Func (...) return ...
3088 -- begin
3089 -- declare
3090 -- Result : String (1 .. 4);
3091 -- begin
3092 -- Proc (Result, ...);
3093 -- return Result;
3094 -- end;
3095 -- end F;
3096
3097 -- Result : String := Func (...);
3098
3099 -- Replace this object declaration by:
3100
3101 -- Result : String (1 .. 4);
3102 -- Proc (Result, ...);
3103
3104 Remove_Homonym (Targ);
3105
3106 Decl :=
3107 Make_Object_Declaration
3108 (Loc,
3109 Defining_Identifier => Targ,
3110 Object_Definition =>
3111 New_Copy_Tree (Object_Definition (Parent (Targ1))));
3112 Replace_Formals (Decl);
3113 Rewrite (Parent (N), Decl);
3114 Analyze (Parent (N));
3115
3116 -- Avoid spurious warnings since we know that this declaration is
3117 -- referenced by the procedure call.
3118
3119 Set_Never_Set_In_Source (Targ, False);
3120
3121 -- Remove the local declaration of the extended return stmt from the
3122 -- inlined code
3123
3124 Remove (Parent (Targ1));
3125
3126 -- Update the reference to the result (since we have rewriten the
3127 -- object declaration)
3128
3129 declare
3130 Blk_Call_Stmt : Node_Id;
3131
3132 begin
3133 -- Capture the call to the procedure
3134
3135 Blk_Call_Stmt :=
3136 First (Statements (Handled_Statement_Sequence (Blk)));
3137 pragma Assert
3138 (Nkind (Blk_Call_Stmt) = N_Procedure_Call_Statement);
3139
3140 Remove (First (Parameter_Associations (Blk_Call_Stmt)));
3141 Prepend_To (Parameter_Associations (Blk_Call_Stmt),
3142 New_Occurrence_Of (Targ, Loc));
3143 end;
3144
3145 -- Remove the return statement
3146
3147 pragma Assert
3148 (Nkind (Last (Statements (Handled_Statement_Sequence (Blk)))) =
3149 N_Simple_Return_Statement);
3150
3151 Remove (Last (Statements (Handled_Statement_Sequence (Blk))));
3152 end if;
3153
3154 -- Traverse the tree and replace formals with actuals or their thunks.
3155 -- Attach block to tree before analysis and rewriting.
3156
3157 Replace_Formals (Blk);
3158 Set_Parent (Blk, N);
3159
e5c4e2bc
AC
3160 if GNATprove_Mode then
3161 null;
3162
3163 elsif not Comes_From_Source (Subp) or else Is_Predef then
540d8610
ES
3164 Reset_Slocs (Blk);
3165 end if;
3166
3167 if Is_Unc_Decl then
3168
3169 -- No action needed since return statement has been already removed
3170
3171 null;
3172
3173 elsif Present (Exit_Lab) then
3174
3175 -- If the body was a single expression, the single return statement
3176 -- and the corresponding label are useless.
3177
3178 if Num_Ret = 1
3179 and then
3180 Nkind (Last (Statements (Handled_Statement_Sequence (Blk)))) =
3181 N_Goto_Statement
3182 then
3183 Remove (Last (Statements (Handled_Statement_Sequence (Blk))));
3184 else
3185 Append (Lab_Decl, (Declarations (Blk)));
3186 Append (Exit_Lab, Statements (Handled_Statement_Sequence (Blk)));
3187 end if;
3188 end if;
3189
3190 -- Analyze Blk with In_Inlined_Body set, to avoid spurious errors
3191 -- on conflicting private views that Gigi would ignore. If this is a
3192 -- predefined unit, analyze with checks off, as is done in the non-
3193 -- inlined run-time units.
3194
3195 declare
3196 I_Flag : constant Boolean := In_Inlined_Body;
3197
3198 begin
3199 In_Inlined_Body := True;
3200
3201 if Is_Predef then
3202 declare
3203 Style : constant Boolean := Style_Check;
3204
3205 begin
3206 Style_Check := False;
3207
3208 -- Search for dispatching calls that use the Object.Operation
3209 -- notation using an Object that is a parameter of the inlined
3210 -- function. We reset the decoration of Operation to force
3211 -- the reanalysis of the inlined dispatching call because
3212 -- the actual object has been inlined.
3213
3214 Reset_Dispatching_Calls (Blk);
3215
3216 Analyze (Blk, Suppress => All_Checks);
3217 Style_Check := Style;
3218 end;
3219
3220 else
3221 Analyze (Blk);
3222 end if;
3223
3224 In_Inlined_Body := I_Flag;
3225 end;
3226
3227 if Ekind (Subp) = E_Procedure then
3228 Rewrite_Procedure_Call (N, Blk);
3229
3230 else
3231 Rewrite_Function_Call (N, Blk);
3232
3233 if Is_Unc_Decl then
3234 null;
3235
3236 -- For the unconstrained case, the replacement of the call has been
3237 -- made prior to the complete analysis of the generated declarations.
3238 -- Propagate the proper type now.
3239
3240 elsif Is_Unc then
3241 if Nkind (N) = N_Identifier then
3242 Set_Etype (N, Etype (Entity (N)));
3243 else
3244 Set_Etype (N, Etype (Targ1));
3245 end if;
3246 end if;
3247 end if;
3248
3249 Restore_Env;
3250
3251 -- Cleanup mapping between formals and actuals for other expansions
3252
3253 F := First_Formal (Subp);
3254 while Present (F) loop
3255 Set_Renamed_Object (F, Empty);
3256 Next_Formal (F);
3257 end loop;
3258 end Expand_Inlined_Call;
3f80a182 3259
70c34e1c
AC
3260 --------------------------
3261 -- Get_Code_Unit_Entity --
3262 --------------------------
3263
3264 function Get_Code_Unit_Entity (E : Entity_Id) return Entity_Id is
8a49a499 3265 Unit : Entity_Id := Cunit_Entity (Get_Code_Unit (E));
5b5b27ad 3266
70c34e1c 3267 begin
8a49a499
AC
3268 if Ekind (Unit) = E_Package_Body then
3269 Unit := Spec_Entity (Unit);
3270 end if;
5b5b27ad 3271
8a49a499 3272 return Unit;
70c34e1c
AC
3273 end Get_Code_Unit_Entity;
3274
6c26bac2
AC
3275 ------------------------------
3276 -- Has_Excluded_Declaration --
3277 ------------------------------
3278
3279 function Has_Excluded_Declaration
3280 (Subp : Entity_Id;
3281 Decls : List_Id) return Boolean
3282 is
3283 D : Node_Id;
3284
3285 function Is_Unchecked_Conversion (D : Node_Id) return Boolean;
3286 -- Nested subprograms make a given body ineligible for inlining, but
3287 -- we make an exception for instantiations of unchecked conversion.
3288 -- The body has not been analyzed yet, so check the name, and verify
3289 -- that the visible entity with that name is the predefined unit.
3290
3291 -----------------------------
3292 -- Is_Unchecked_Conversion --
3293 -----------------------------
3294
3295 function Is_Unchecked_Conversion (D : Node_Id) return Boolean is
3296 Id : constant Node_Id := Name (D);
3297 Conv : Entity_Id;
3298
3299 begin
3300 if Nkind (Id) = N_Identifier
3301 and then Chars (Id) = Name_Unchecked_Conversion
3302 then
3303 Conv := Current_Entity (Id);
3304
3305 elsif Nkind_In (Id, N_Selected_Component, N_Expanded_Name)
3306 and then Chars (Selector_Name (Id)) = Name_Unchecked_Conversion
3307 then
3308 Conv := Current_Entity (Selector_Name (Id));
3309 else
3310 return False;
3311 end if;
3312
3313 return Present (Conv)
3314 and then Is_Predefined_File_Name
3315 (Unit_File_Name (Get_Source_Unit (Conv)))
3316 and then Is_Intrinsic_Subprogram (Conv);
3317 end Is_Unchecked_Conversion;
3318
3319 -- Start of processing for Has_Excluded_Declaration
3320
3321 begin
16b10ccc
AC
3322 -- No action needed if the check is not needed
3323
3324 if not Check_Inlining_Restrictions then
3325 return False;
3326 end if;
3327
6c26bac2
AC
3328 D := First (Decls);
3329 while Present (D) loop
3330 if Nkind (D) = N_Subprogram_Body then
3331 Cannot_Inline
3332 ("cannot inline & (nested subprogram)?",
3333 D, Subp);
3334 return True;
3335
3336 elsif Nkind (D) = N_Task_Type_Declaration
3337 or else Nkind (D) = N_Single_Task_Declaration
3338 then
3339 Cannot_Inline
3340 ("cannot inline & (nested task type declaration)?",
3341 D, Subp);
3342 return True;
3343
3344 elsif Nkind (D) = N_Protected_Type_Declaration
3345 or else Nkind (D) = N_Single_Protected_Declaration
3346 then
3347 Cannot_Inline
3348 ("cannot inline & (nested protected type declaration)?",
3349 D, Subp);
3350 return True;
3351
3352 elsif Nkind (D) = N_Package_Declaration then
3353 Cannot_Inline
3354 ("cannot inline & (nested package declaration)?",
3355 D, Subp);
3356 return True;
3357
3358 elsif Nkind (D) = N_Function_Instantiation
3359 and then not Is_Unchecked_Conversion (D)
3360 then
3361 Cannot_Inline
3362 ("cannot inline & (nested function instantiation)?",
3363 D, Subp);
3364 return True;
3365
3366 elsif Nkind (D) = N_Procedure_Instantiation then
3367 Cannot_Inline
3368 ("cannot inline & (nested procedure instantiation)?",
3369 D, Subp);
3370 return True;
3371
3372 elsif Nkind (D) = N_Package_Instantiation then
3373 Cannot_Inline
3374 ("cannot inline & (nested package instantiation)?",
3375 D, Subp);
3376 return True;
3377 end if;
3378
3379 Next (D);
3380 end loop;
3381
3382 return False;
3383 end Has_Excluded_Declaration;
3384
3385 ----------------------------
3386 -- Has_Excluded_Statement --
3387 ----------------------------
3388
3389 function Has_Excluded_Statement
3390 (Subp : Entity_Id;
3391 Stats : List_Id) return Boolean
3392 is
3393 S : Node_Id;
3394 E : Node_Id;
3395
3396 begin
16b10ccc
AC
3397 -- No action needed if the check is not needed
3398
3399 if not Check_Inlining_Restrictions then
3400 return False;
3401 end if;
3402
6c26bac2
AC
3403 S := First (Stats);
3404 while Present (S) loop
3405 if Nkind_In (S, N_Abort_Statement,
3406 N_Asynchronous_Select,
3407 N_Conditional_Entry_Call,
3408 N_Delay_Relative_Statement,
3409 N_Delay_Until_Statement,
3410 N_Selective_Accept,
3411 N_Timed_Entry_Call)
3412 then
3413 Cannot_Inline
3414 ("cannot inline & (non-allowed statement)?", S, Subp);
3415 return True;
3416
3417 elsif Nkind (S) = N_Block_Statement then
3418 if Present (Declarations (S))
3419 and then Has_Excluded_Declaration (Subp, Declarations (S))
3420 then
3421 return True;
3422
3423 elsif Present (Handled_Statement_Sequence (S)) then
16b10ccc
AC
3424 if not Back_End_Inlining
3425 and then
3426 Present
3427 (Exception_Handlers (Handled_Statement_Sequence (S)))
6c26bac2
AC
3428 then
3429 Cannot_Inline
3430 ("cannot inline& (exception handler)?",
3431 First (Exception_Handlers
3432 (Handled_Statement_Sequence (S))),
3433 Subp);
3434 return True;
3435
3436 elsif Has_Excluded_Statement
3437 (Subp, Statements (Handled_Statement_Sequence (S)))
3438 then
3439 return True;
3440 end if;
3441 end if;
3442
3443 elsif Nkind (S) = N_Case_Statement then
3444 E := First (Alternatives (S));
3445 while Present (E) loop
3446 if Has_Excluded_Statement (Subp, Statements (E)) then
3447 return True;
3448 end if;
3449
3450 Next (E);
3451 end loop;
3452
3453 elsif Nkind (S) = N_If_Statement then
3454 if Has_Excluded_Statement (Subp, Then_Statements (S)) then
3455 return True;
3456 end if;
3457
3458 if Present (Elsif_Parts (S)) then
3459 E := First (Elsif_Parts (S));
3460 while Present (E) loop
3461 if Has_Excluded_Statement (Subp, Then_Statements (E)) then
3462 return True;
3463 end if;
3464
3465 Next (E);
3466 end loop;
3467 end if;
3468
3469 if Present (Else_Statements (S))
3470 and then Has_Excluded_Statement (Subp, Else_Statements (S))
3471 then
3472 return True;
3473 end if;
3474
3475 elsif Nkind (S) = N_Loop_Statement
3476 and then Has_Excluded_Statement (Subp, Statements (S))
3477 then
3478 return True;
3479
3480 elsif Nkind (S) = N_Extended_Return_Statement then
3481 if Present (Handled_Statement_Sequence (S))
3482 and then
3483 Has_Excluded_Statement
3484 (Subp, Statements (Handled_Statement_Sequence (S)))
3485 then
3486 return True;
3487
16b10ccc
AC
3488 elsif not Back_End_Inlining
3489 and then Present (Handled_Statement_Sequence (S))
6c26bac2
AC
3490 and then
3491 Present (Exception_Handlers
3492 (Handled_Statement_Sequence (S)))
3493 then
3494 Cannot_Inline
3495 ("cannot inline& (exception handler)?",
3496 First (Exception_Handlers (Handled_Statement_Sequence (S))),
3497 Subp);
3498 return True;
3499 end if;
3500 end if;
3501
3502 Next (S);
3503 end loop;
3504
3505 return False;
3506 end Has_Excluded_Statement;
3507
38cbfe40
RK
3508 --------------------------
3509 -- Has_Initialized_Type --
3510 --------------------------
3511
3512 function Has_Initialized_Type (E : Entity_Id) return Boolean is
3513 E_Body : constant Node_Id := Get_Subprogram_Body (E);
3514 Decl : Node_Id;
3515
3516 begin
3517 if No (E_Body) then -- imported subprogram
3518 return False;
3519
3520 else
3521 Decl := First (Declarations (E_Body));
38cbfe40 3522 while Present (Decl) loop
38cbfe40
RK
3523 if Nkind (Decl) = N_Full_Type_Declaration
3524 and then Present (Init_Proc (Defining_Identifier (Decl)))
3525 then
3526 return True;
3527 end if;
3528
3529 Next (Decl);
3530 end loop;
3531 end if;
3532
3533 return False;
3534 end Has_Initialized_Type;
3535
ea0c8cfb
RD
3536 -----------------------
3537 -- Has_Single_Return --
3538 -----------------------
6c26bac2
AC
3539
3540 function Has_Single_Return (N : Node_Id) return Boolean is
3541 Return_Statement : Node_Id := Empty;
3542
3543 function Check_Return (N : Node_Id) return Traverse_Result;
3544
3545 ------------------
3546 -- Check_Return --
3547 ------------------
3548
3549 function Check_Return (N : Node_Id) return Traverse_Result is
3550 begin
3551 if Nkind (N) = N_Simple_Return_Statement then
3552 if Present (Expression (N))
3553 and then Is_Entity_Name (Expression (N))
3554 then
3555 if No (Return_Statement) then
3556 Return_Statement := N;
3557 return OK;
3558
3559 elsif Chars (Expression (N)) =
3560 Chars (Expression (Return_Statement))
3561 then
3562 return OK;
3563
3564 else
3565 return Abandon;
3566 end if;
3567
3568 -- A return statement within an extended return is a noop
3569 -- after inlining.
3570
3571 elsif No (Expression (N))
3572 and then
3573 Nkind (Parent (Parent (N))) = N_Extended_Return_Statement
3574 then
3575 return OK;
3576
3577 else
3578 -- Expression has wrong form
3579
3580 return Abandon;
3581 end if;
3582
ea0c8cfb
RD
3583 -- We can only inline a build-in-place function if it has a single
3584 -- extended return.
6c26bac2
AC
3585
3586 elsif Nkind (N) = N_Extended_Return_Statement then
3587 if No (Return_Statement) then
3588 Return_Statement := N;
3589 return OK;
3590
3591 else
3592 return Abandon;
3593 end if;
3594
3595 else
3596 return OK;
3597 end if;
3598 end Check_Return;
3599
3600 function Check_All_Returns is new Traverse_Func (Check_Return);
3601
3602 -- Start of processing for Has_Single_Return
3603
3604 begin
3605 if Check_All_Returns (N) /= OK then
3606 return False;
3607
3608 elsif Nkind (Return_Statement) = N_Extended_Return_Statement then
3609 return True;
3610
3611 else
3612 return Present (Declarations (N))
3613 and then Present (First (Declarations (N)))
3614 and then Chars (Expression (Return_Statement)) =
3615 Chars (Defining_Identifier (First (Declarations (N))));
3616 end if;
3617 end Has_Single_Return;
3618
5b5b27ad
AC
3619 -----------------------------
3620 -- In_Main_Unit_Or_Subunit --
3621 -----------------------------
3622
3623 function In_Main_Unit_Or_Subunit (E : Entity_Id) return Boolean is
3624 Comp : Node_Id := Cunit (Get_Code_Unit (E));
3625
3626 begin
3627 -- Check whether the subprogram or package to inline is within the main
3628 -- unit or its spec or within a subunit. In either case there are no
3629 -- additional bodies to process. If the subprogram appears in a parent
3630 -- of the current unit, the check on whether inlining is possible is
3631 -- done in Analyze_Inlined_Bodies.
3632
3633 while Nkind (Unit (Comp)) = N_Subunit loop
3634 Comp := Library_Unit (Comp);
3635 end loop;
3636
3637 return Comp = Cunit (Main_Unit)
3638 or else Comp = Library_Unit (Cunit (Main_Unit));
3639 end In_Main_Unit_Or_Subunit;
3640
38cbfe40
RK
3641 ----------------
3642 -- Initialize --
3643 ----------------
3644
3645 procedure Initialize is
3646 begin
38cbfe40
RK
3647 Pending_Descriptor.Init;
3648 Pending_Instantiations.Init;
3649 Inlined_Bodies.Init;
3650 Successors.Init;
3651 Inlined.Init;
3652
3653 for J in Hash_Headers'Range loop
3654 Hash_Headers (J) := No_Subp;
3655 end loop;
16b10ccc
AC
3656
3657 Inlined_Calls := No_Elist;
3658 Backend_Calls := No_Elist;
3659 Backend_Inlined_Subps := No_Elist;
3660 Backend_Not_Inlined_Subps := No_Elist;
38cbfe40
RK
3661 end Initialize;
3662
3663 ------------------------
3664 -- Instantiate_Bodies --
3665 ------------------------
3666
3667 -- Generic bodies contain all the non-local references, so an
3668 -- instantiation does not need any more context than Standard
3669 -- itself, even if the instantiation appears in an inner scope.
3670 -- Generic associations have verified that the contract model is
3671 -- satisfied, so that any error that may occur in the analysis of
3672 -- the body is an internal error.
3673
3674 procedure Instantiate_Bodies is
3675 J : Int;
3676 Info : Pending_Body_Info;
3677
3678 begin
07fc65c4 3679 if Serious_Errors_Detected = 0 then
fbf5a39b 3680 Expander_Active := (Operating_Mode = Opt.Generate_Code);
a99ada67 3681 Push_Scope (Standard_Standard);
38cbfe40
RK
3682 To_Clean := New_Elmt_List;
3683
3684 if Is_Generic_Unit (Cunit_Entity (Main_Unit)) then
3685 Start_Generic;
3686 end if;
3687
3688 -- A body instantiation may generate additional instantiations, so
3689 -- the following loop must scan to the end of a possibly expanding
3690 -- set (that's why we can't simply use a FOR loop here).
3691
3692 J := 0;
38cbfe40 3693 while J <= Pending_Instantiations.Last
07fc65c4 3694 and then Serious_Errors_Detected = 0
38cbfe40 3695 loop
38cbfe40
RK
3696 Info := Pending_Instantiations.Table (J);
3697
fbf5a39b 3698 -- If the instantiation node is absent, it has been removed
38cbfe40
RK
3699 -- as part of unreachable code.
3700
3701 if No (Info.Inst_Node) then
3702 null;
3703
fbf5a39b 3704 elsif Nkind (Info.Act_Decl) = N_Package_Declaration then
38cbfe40
RK
3705 Instantiate_Package_Body (Info);
3706 Add_Scope_To_Clean (Defining_Entity (Info.Act_Decl));
3707
3708 else
3709 Instantiate_Subprogram_Body (Info);
3710 end if;
3711
3712 J := J + 1;
3713 end loop;
3714
3715 -- Reset the table of instantiations. Additional instantiations
3716 -- may be added through inlining, when additional bodies are
3717 -- analyzed.
3718
3719 Pending_Instantiations.Init;
3720
3721 -- We can now complete the cleanup actions of scopes that contain
3722 -- pending instantiations (skipped for generic units, since we
3723 -- never need any cleanups in generic units).
3724 -- pending instantiations.
3725
3726 if Expander_Active
3727 and then not Is_Generic_Unit (Main_Unit_Entity)
3728 then
3729 Cleanup_Scopes;
38cbfe40
RK
3730 elsif Is_Generic_Unit (Cunit_Entity (Main_Unit)) then
3731 End_Generic;
3732 end if;
3733
3734 Pop_Scope;
3735 end if;
3736 end Instantiate_Bodies;
3737
3738 ---------------
3739 -- Is_Nested --
3740 ---------------
3741
3742 function Is_Nested (E : Entity_Id) return Boolean is
5132708f 3743 Scop : Entity_Id;
38cbfe40
RK
3744
3745 begin
5132708f 3746 Scop := Scope (E);
38cbfe40
RK
3747 while Scop /= Standard_Standard loop
3748 if Ekind (Scop) in Subprogram_Kind then
3749 return True;
3750
3751 elsif Ekind (Scop) = E_Task_Type
3752 or else Ekind (Scop) = E_Entry
0b7f0f0e
AC
3753 or else Ekind (Scop) = E_Entry_Family
3754 then
38cbfe40
RK
3755 return True;
3756 end if;
3757
3758 Scop := Scope (Scop);
3759 end loop;
3760
3761 return False;
3762 end Is_Nested;
3763
16b10ccc
AC
3764 ------------------------
3765 -- List_Inlining_Info --
3766 ------------------------
3767
3768 procedure List_Inlining_Info is
3769 Elmt : Elmt_Id;
3770 Nod : Node_Id;
3771 Count : Nat;
3772
3773 begin
3774 if not Debug_Flag_Dot_J then
3775 return;
3776 end if;
3777
3778 -- Generate listing of calls inlined by the frontend
3779
3780 if Present (Inlined_Calls) then
3781 Count := 0;
3782 Elmt := First_Elmt (Inlined_Calls);
3783 while Present (Elmt) loop
3784 Nod := Node (Elmt);
3785
3786 if In_Extended_Main_Code_Unit (Nod) then
3787 Count := Count + 1;
3788
3789 if Count = 1 then
1725676d 3790 Write_Str ("List of calls inlined by the frontend");
16b10ccc
AC
3791 Write_Eol;
3792 end if;
3793
3794 Write_Str (" ");
3795 Write_Int (Count);
3796 Write_Str (":");
3797 Write_Location (Sloc (Nod));
3798 Write_Str (":");
3799 Output.Write_Eol;
3800 end if;
3801
3802 Next_Elmt (Elmt);
3803 end loop;
3804 end if;
3805
3806 -- Generate listing of calls passed to the backend
3807
3808 if Present (Backend_Calls) then
3809 Count := 0;
3810
3811 Elmt := First_Elmt (Backend_Calls);
3812 while Present (Elmt) loop
3813 Nod := Node (Elmt);
3814
3815 if In_Extended_Main_Code_Unit (Nod) then
3816 Count := Count + 1;
3817
3818 if Count = 1 then
1725676d 3819 Write_Str ("List of inlined calls passed to the backend");
16b10ccc
AC
3820 Write_Eol;
3821 end if;
3822
3823 Write_Str (" ");
3824 Write_Int (Count);
3825 Write_Str (":");
3826 Write_Location (Sloc (Nod));
3827 Output.Write_Eol;
3828 end if;
3829
3830 Next_Elmt (Elmt);
3831 end loop;
3832 end if;
3833
3834 -- Generate listing of subprograms passed to the backend
3835
3836 if Present (Backend_Inlined_Subps)
3837 and then Back_End_Inlining
3838 then
3839 Count := 0;
3840
3841 Elmt := First_Elmt (Backend_Inlined_Subps);
3842 while Present (Elmt) loop
3843 Nod := Node (Elmt);
3844
3845 Count := Count + 1;
3846
3847 if Count = 1 then
3848 Write_Str
1725676d 3849 ("List of inlined subprograms passed to the backend");
16b10ccc
AC
3850 Write_Eol;
3851 end if;
3852
3853 Write_Str (" ");
3854 Write_Int (Count);
3855 Write_Str (":");
3856 Write_Name (Chars (Nod));
3857 Write_Str (" (");
3858 Write_Location (Sloc (Nod));
3859 Write_Str (")");
3860 Output.Write_Eol;
3861
3862 Next_Elmt (Elmt);
3863 end loop;
3864 end if;
3865
1725676d 3866 -- Generate listing of subprograms that cannot be inlined by the backend
16b10ccc
AC
3867
3868 if Present (Backend_Not_Inlined_Subps)
3869 and then Back_End_Inlining
3870 then
3871 Count := 0;
3872
3873 Elmt := First_Elmt (Backend_Not_Inlined_Subps);
3874 while Present (Elmt) loop
3875 Nod := Node (Elmt);
3876
3877 Count := Count + 1;
3878
3879 if Count = 1 then
3880 Write_Str
1725676d 3881 ("List of subprograms that cannot be inlined by the backend");
16b10ccc
AC
3882 Write_Eol;
3883 end if;
3884
3885 Write_Str (" ");
3886 Write_Int (Count);
3887 Write_Str (":");
3888 Write_Name (Chars (Nod));
3889 Write_Str (" (");
3890 Write_Location (Sloc (Nod));
3891 Write_Str (")");
3892 Output.Write_Eol;
3893
3894 Next_Elmt (Elmt);
3895 end loop;
3896 end if;
3897 end List_Inlining_Info;
3898
38cbfe40
RK
3899 ----------
3900 -- Lock --
3901 ----------
3902
3903 procedure Lock is
3904 begin
3905 Pending_Instantiations.Locked := True;
3906 Inlined_Bodies.Locked := True;
3907 Successors.Locked := True;
3908 Inlined.Locked := True;
3909 Pending_Instantiations.Release;
3910 Inlined_Bodies.Release;
3911 Successors.Release;
3912 Inlined.Release;
3913 end Lock;
3914
f087ea44
AC
3915 ---------------------------
3916 -- Register_Backend_Call --
3917 ---------------------------
3918
3919 procedure Register_Backend_Call (N : Node_Id) is
3920 begin
21c51f53 3921 Append_New_Elmt (N, To => Backend_Calls);
f087ea44
AC
3922 end Register_Backend_Call;
3923
38cbfe40
RK
3924 --------------------------
3925 -- Remove_Dead_Instance --
3926 --------------------------
3927
3928 procedure Remove_Dead_Instance (N : Node_Id) is
5132708f 3929 J : Int;
38cbfe40
RK
3930
3931 begin
3932 J := 0;
38cbfe40 3933 while J <= Pending_Instantiations.Last loop
38cbfe40
RK
3934 if Pending_Instantiations.Table (J).Inst_Node = N then
3935 Pending_Instantiations.Table (J).Inst_Node := Empty;
3936 return;
3937 end if;
3938
3939 J := J + 1;
3940 end loop;
3941 end Remove_Dead_Instance;
3942
16b10ccc
AC
3943 --------------------
3944 -- Remove_Pragmas --
3945 --------------------
3946
3947 procedure Remove_Pragmas (Bod : Node_Id) is
3948 Decl : Node_Id;
3949 Nxt : Node_Id;
3950
3951 begin
3952 Decl := First (Declarations (Bod));
3953 while Present (Decl) loop
3954 Nxt := Next (Decl);
3955
3956 if Nkind (Decl) = N_Pragma
3957 and then Nam_In (Pragma_Name (Decl), Name_Contract_Cases,
3958 Name_Precondition,
3959 Name_Postcondition,
3960 Name_Unreferenced,
3961 Name_Unmodified)
3962 then
3963 Remove (Decl);
3964 end if;
3965
3966 Decl := Nxt;
3967 end loop;
3968 end Remove_Pragmas;
3969
38cbfe40 3970end Inline;