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