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