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