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