comparison gcc/ada/inline.adb @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
4 -- -- 4 -- --
5 -- I N L I N E -- 5 -- I N L I N E --
6 -- -- 6 -- --
7 -- B o d y -- 7 -- B o d y --
8 -- -- 8 -- --
9 -- Copyright (C) 1992-2018, Free Software Foundation, Inc. -- 9 -- Copyright (C) 1992-2019, Free Software Foundation, Inc. --
10 -- -- 10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under -- 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- -- 12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- -- 13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- 14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
21 -- GNAT was originally developed by the GNAT team at New York University. -- 21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. -- 22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- -- 23 -- --
24 ------------------------------------------------------------------------------ 24 ------------------------------------------------------------------------------
25 25
26 with Alloc;
26 with Aspects; use Aspects; 27 with Aspects; use Aspects;
27 with Atree; use Atree; 28 with Atree; use Atree;
28 with Debug; use Debug; 29 with Debug; use Debug;
29 with Einfo; use Einfo; 30 with Einfo; use Einfo;
30 with Elists; use Elists; 31 with Elists; use Elists;
49 with Sem_Util; use Sem_Util; 50 with Sem_Util; use Sem_Util;
50 with Sinfo; use Sinfo; 51 with Sinfo; use Sinfo;
51 with Sinput; use Sinput; 52 with Sinput; use Sinput;
52 with Snames; use Snames; 53 with Snames; use Snames;
53 with Stand; use Stand; 54 with Stand; use Stand;
55 with Table;
56 with Tbuild; use Tbuild;
57 with Uintp; use Uintp;
54 with Uname; use Uname; 58 with Uname; use Uname;
55 with Tbuild; use Tbuild; 59
60 with GNAT.HTable;
56 61
57 package body Inline is 62 package body Inline is
58 63
59 Check_Inlining_Restrictions : constant Boolean := True; 64 Check_Inlining_Restrictions : constant Boolean := True;
60 -- In the following cases the frontend rejects inlining because they 65 -- In the following cases the frontend rejects inlining because they
80 -- List of frontend inlined calls 85 -- List of frontend inlined calls
81 86
82 Backend_Calls : Elist_Id; 87 Backend_Calls : Elist_Id;
83 -- List of inline calls passed to the backend 88 -- List of inline calls passed to the backend
84 89
90 Backend_Instances : Elist_Id;
91 -- List of instances inlined for the backend
92
85 Backend_Inlined_Subps : Elist_Id; 93 Backend_Inlined_Subps : Elist_Id;
86 -- List of subprograms inlined by the backend 94 -- List of subprograms inlined by the backend
87 95
88 Backend_Not_Inlined_Subps : Elist_Id; 96 Backend_Not_Inlined_Subps : Elist_Id;
89 -- List of subprograms that cannot be inlined by the backend 97 -- List of subprograms that cannot be inlined by the backend
98
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;
90 166
91 -------------------- 167 --------------------
92 -- Inlined Bodies -- 168 -- Inlined Bodies --
93 -------------------- 169 --------------------
94 170
177 procedure Add_Call (Called : Entity_Id; Caller : Entity_Id := Empty); 253 procedure Add_Call (Called : Entity_Id; Caller : Entity_Id := Empty);
178 -- Make two entries in Inlined table, for an inlined subprogram being 254 -- Make two entries in Inlined table, for an inlined subprogram being
179 -- called, and for the inlined subprogram that contains the call. If 255 -- called, and for the inlined subprogram that contains the call. If
180 -- the call is in the main compilation unit, Caller is Empty. 256 -- the call is in the main compilation unit, Caller is Empty.
181 257
258 procedure Add_Inlined_Instance (E : Entity_Id);
259 -- Add instance E to the list of inlined instances for the unit
260
182 procedure Add_Inlined_Subprogram (E : Entity_Id); 261 procedure Add_Inlined_Subprogram (E : Entity_Id);
183 -- Add subprogram E to the list of inlined subprogram for the unit 262 -- Add subprogram E to the list of inlined subprograms for the unit
184 263
185 function Add_Subp (E : Entity_Id) return Subp_Index; 264 function Add_Subp (E : Entity_Id) return Subp_Index;
186 -- Make entry in Inlined table for subprogram E, or return table index 265 -- Make entry in Inlined table for subprogram E, or return table index
187 -- that already holds E. 266 -- that already holds E.
188 267
427 end loop; 506 end loop;
428 507
429 return Dont_Inline; 508 return Dont_Inline;
430 end Must_Inline; 509 end Must_Inline;
431 510
432 Level : Inline_Level_Type; 511 Inst : Entity_Id;
512 Inst_Decl : Node_Id;
513 Level : Inline_Level_Type;
433 514
434 -- Start of processing for Add_Inlined_Body 515 -- Start of processing for Add_Inlined_Body
435 516
436 begin 517 begin
437 Append_New_Elmt (N, To => Backend_Calls); 518 Append_New_Elmt (N, To => Backend_Calls);
438 519
439 -- Skip subprograms that cannot be inlined outside their unit 520 -- Skip subprograms that cannot or need not be inlined outside their
521 -- unit or parent subprogram.
440 522
441 if Is_Abstract_Subprogram (E) 523 if Is_Abstract_Subprogram (E)
442 or else Convention (E) = Convention_Protected 524 or else Convention (E) = Convention_Protected
525 or else In_Main_Unit_Or_Subunit (E)
443 or else Is_Nested (E) 526 or else Is_Nested (E)
444 then 527 then
445 return; 528 return;
446 end if; 529 end if;
447 530
453 Level := Must_Inline; 536 Level := Must_Inline;
454 537
455 if Level = Dont_Inline then 538 if Level = Dont_Inline then
456 return; 539 return;
457 end if; 540 end if;
541
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);
458 557
459 -- If the call was generated by the compiler and is to a subprogram in 558 -- If the call was generated by the compiler and is to a subprogram in
460 -- a run-time unit, we need to suppress debugging information for it, 559 -- a run-time unit, we need to suppress debugging information for it,
461 -- so that the code that is eventually inlined will not affect the 560 -- so that the code that is eventually inlined will not affect the
462 -- debugging of the program. We do not do it if the call comes from 561 -- debugging of the program. We do not do it if the call comes from
474 -- where both the spec and body are in the same context, then there is 573 -- where both the spec and body are in the same context, then there is
475 -- no need to load any package body since the body of the function is 574 -- no need to load any package body since the body of the function is
476 -- in the spec. 575 -- in the spec.
477 576
478 if Is_Non_Loading_Expression_Function (E) then 577 if Is_Non_Loading_Expression_Function (E) then
479 Set_Is_Called (E);
480 return; 578 return;
481 end if; 579 end if;
482 580
483 -- Find unit containing E, and add to list of inlined bodies if needed. 581 -- Find unit containing E, and add to list of inlined bodies if needed.
484 -- If the body is already present, no need to load any other unit. This
485 -- is the case for an initialization procedure, which appears in the
486 -- package declaration that contains the type. It is also the case if
487 -- the body has already been analyzed. Finally, if the unit enclosing
488 -- E is an instance, the instance body will be analyzed in any case,
489 -- and there is no need to add the enclosing unit (whose body might not
490 -- be available).
491
492 -- Library-level functions must be handled specially, because there is 582 -- Library-level functions must be handled specially, because there is
493 -- no enclosing package to retrieve. In this case, it is the body of 583 -- no enclosing package to retrieve. In this case, it is the body of
494 -- the function that will have to be loaded. 584 -- the function that will have to be loaded.
495 585
496 declare 586 declare
497 Pack : constant Entity_Id := Get_Code_Unit_Entity (E); 587 Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
498 588
499 begin 589 begin
500 if Pack = E then 590 if Pack = E then
501 Set_Is_Called (E);
502 Inlined_Bodies.Increment_Last; 591 Inlined_Bodies.Increment_Last;
503 Inlined_Bodies.Table (Inlined_Bodies.Last) := E; 592 Inlined_Bodies.Table (Inlined_Bodies.Last) := E;
504 593
505 elsif Ekind (Pack) = E_Package then 594 else
506 Set_Is_Called (E); 595 pragma Assert (Ekind (Pack) = E_Package);
596
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
611 Inst_Decl := Unit_Declaration_Node (Inst);
612
613 -- Do not inline the instance if the body already exists,
614 -- or the instance node is simply missing.
615
616 if Present (Corresponding_Body (Inst_Decl))
617 or else (Nkind (Parent (Inst_Decl)) /= N_Compilation_Unit
618 and then No (Next (Inst_Decl)))
619 then
620 Set_Is_Called (Inst);
621 else
622 Add_Inlined_Instance (Inst);
623 end if;
624 end if;
625 end if;
626
627 -- If the unit containing E is an instance, nothing more to do
507 628
508 if Is_Generic_Instance (Pack) then 629 if Is_Generic_Instance (Pack) then
509 null; 630 null;
510 631
511 -- Do not inline the package if the subprogram is an init proc 632 -- Do not inline the package if the subprogram is an init proc
512 -- or other internally generated subprogram, because in that 633 -- or other internally generated subprogram, because in that
513 -- case the subprogram body appears in the same unit that 634 -- case the subprogram body appears in the same unit that
514 -- declares the type, and that body is visible to the back end. 635 -- declares the type, and that body is visible to the back end.
515 -- Do not inline it either if it is in the main unit. 636 -- Do not inline it either if it is in the main unit.
516 -- Extend the -gnatn2 processing to -gnatn1 for Inline_Always 637 -- Extend the -gnatn2 processing to -gnatn1 for Inline_Always
517 -- calls if the back-end takes care of inlining the call. 638 -- calls if the back end takes care of inlining the call.
518 -- Note that Level in Inline_Package | Inline_Call here. 639 -- Note that Level is in Inline_Call | Inline_Package here.
519 640
520 elsif ((Level = Inline_Call 641 elsif ((Level = Inline_Call
521 and then Has_Pragma_Inline_Always (E) 642 and then Has_Pragma_Inline_Always (E)
522 and then Back_End_Inlining) 643 and then Back_End_Inlining)
523 or else Level = Inline_Package) 644 or else Level = Inline_Package)
536 657
537 Inline_Processing_Required := True; 658 Inline_Processing_Required := True;
538 end; 659 end;
539 end Add_Inlined_Body; 660 end Add_Inlined_Body;
540 661
662 --------------------------
663 -- Add_Inlined_Instance --
664 --------------------------
665
666 procedure Add_Inlined_Instance (E : Entity_Id) is
667 Decl_Node : constant Node_Id := Unit_Declaration_Node (E);
668 Index : Int;
669
670 begin
671 -- This machinery is only used with back-end inlining
672
673 if not Back_End_Inlining then
674 return;
675 end if;
676
677 -- Register the instance in the list
678
679 Append_New_Elmt (Decl_Node, To => Backend_Instances);
680
681 -- Retrieve the index of its corresponding pending instantiation
682 -- and mark this corresponding pending instantiation as needed.
683
684 Index := To_Pending_Instantiations.Get (Decl_Node);
685 if Index >= 0 then
686 Called_Pending_Instantiations.Append (Index);
687 else
688 pragma Assert (False);
689 null;
690 end if;
691
692 Set_Is_Called (E);
693 end Add_Inlined_Instance;
694
541 ---------------------------- 695 ----------------------------
542 -- Add_Inlined_Subprogram -- 696 -- Add_Inlined_Subprogram --
543 ---------------------------- 697 ----------------------------
544 698
545 procedure Add_Inlined_Subprogram (E : Entity_Id) is 699 procedure Add_Inlined_Subprogram (E : Entity_Id) is
572 end Register_Backend_Not_Inlined_Subprogram; 726 end Register_Backend_Not_Inlined_Subprogram;
573 727
574 -- Start of processing for Add_Inlined_Subprogram 728 -- Start of processing for Add_Inlined_Subprogram
575 729
576 begin 730 begin
577 -- If the subprogram is to be inlined, and if its unit is known to be 731 -- We can inline the subprogram if its unit is known to be inlined or is
578 -- inlined or is an instance whose body will be analyzed anyway or the 732 -- an instance whose body will be analyzed anyway or the subprogram was
579 -- subprogram was generated as a body by the compiler (for example an 733 -- generated as a body by the compiler (for example an initialization
580 -- initialization procedure) or its declaration was provided along with 734 -- procedure) or its declaration was provided along with the body (for
581 -- the body (for example an expression function), and if it is declared 735 -- example an expression function) and it does not declare types with
582 -- at the library level not in the main unit, and if it can be inlined 736 -- nontrivial initialization procedures.
583 -- by the back-end, then insert it in the list of inlined subprograms. 737
584 738 if (Is_Inlined (Pack)
585 if Is_Inlined (E) 739 or else Is_Generic_Instance (Pack)
586 and then (Is_Inlined (Pack) 740 or else Nkind (Decl) = N_Subprogram_Body
587 or else Is_Generic_Instance (Pack) 741 or else Present (Corresponding_Body (Decl)))
588 or else Nkind (Decl) = N_Subprogram_Body
589 or else Present (Corresponding_Body (Decl)))
590 and then not In_Main_Unit_Or_Subunit (E)
591 and then not Is_Nested (E)
592 and then not Has_Initialized_Type (E) 742 and then not Has_Initialized_Type (E)
593 then 743 then
594 Register_Backend_Inlined_Subprogram (E); 744 Register_Backend_Inlined_Subprogram (E);
595 745
596 if No (Last_Inlined) then 746 if No (Last_Inlined) then
603 753
604 else 754 else
605 Register_Backend_Not_Inlined_Subprogram (E); 755 Register_Backend_Not_Inlined_Subprogram (E);
606 end if; 756 end if;
607 end Add_Inlined_Subprogram; 757 end Add_Inlined_Subprogram;
758
759 --------------------------------
760 -- Add_Pending_Instantiation --
761 --------------------------------
762
763 procedure Add_Pending_Instantiation (Inst : Node_Id; Act_Decl : Node_Id) is
764 Act_Decl_Id : Entity_Id;
765 Index : Int;
766
767 begin
768 -- Here is a defense against a ludicrous number of instantiations
769 -- caused by a circular set of instantiation attempts.
770
771 if Pending_Instantiations.Last + 1 >= Maximum_Instantiations then
772 Error_Msg_Uint_1 := UI_From_Int (Maximum_Instantiations);
773 Error_Msg_N ("too many instantiations, exceeds max of^", Inst);
774 Error_Msg_N ("\limit can be changed using -gnateinn switch", Inst);
775 raise Unrecoverable_Error;
776 end if;
777
778 -- Capture the body of the generic instantiation along with its context
779 -- for later processing by Instantiate_Bodies.
780
781 Pending_Instantiations.Append
782 ((Act_Decl => Act_Decl,
783 Config_Switches => Save_Config_Switches,
784 Current_Sem_Unit => Current_Sem_Unit,
785 Expander_Status => Expander_Active,
786 Inst_Node => Inst,
787 Local_Suppress_Stack_Top => Local_Suppress_Stack_Top,
788 Scope_Suppress => Scope_Suppress,
789 Warnings => Save_Warnings));
790
791 -- With back-end inlining, also associate the index to the instantiation
792
793 if Back_End_Inlining then
794 Act_Decl_Id := Defining_Entity (Act_Decl);
795 Index := Pending_Instantiations.Last;
796
797 To_Pending_Instantiations.Set (Act_Decl, Index);
798
799 -- If an instantiation is in the main unit or subunit, or is a nested
800 -- subprogram, then its body is needed as per the analysis done in
801 -- Analyze_Package_Instantiation & Analyze_Subprogram_Instantiation.
802
803 if In_Main_Unit_Or_Subunit (Act_Decl_Id)
804 or else (Is_Subprogram (Act_Decl_Id)
805 and then Is_Nested (Act_Decl_Id))
806 then
807 Called_Pending_Instantiations.Append (Index);
808
809 Set_Is_Called (Act_Decl_Id);
810 end if;
811 end if;
812 end Add_Pending_Instantiation;
608 813
609 ------------------------ 814 ------------------------
610 -- Add_Scope_To_Clean -- 815 -- Add_Scope_To_Clean --
611 ------------------------ 816 ------------------------
612 817
1286 1491
1287 function Can_Be_Inlined_In_GNATprove_Mode 1492 function Can_Be_Inlined_In_GNATprove_Mode
1288 (Spec_Id : Entity_Id; 1493 (Spec_Id : Entity_Id;
1289 Body_Id : Entity_Id) return Boolean 1494 Body_Id : Entity_Id) return Boolean
1290 is 1495 is
1496 function Has_Formal_Or_Result_Of_Deep_Type
1497 (Id : Entity_Id) return Boolean;
1498 -- Returns true if the subprogram has at least one formal parameter or
1499 -- a return type of a deep type: either an access type or a composite
1500 -- type containing an access type.
1501
1291 function Has_Formal_With_Discriminant_Dependent_Fields 1502 function Has_Formal_With_Discriminant_Dependent_Fields
1292 (Id : Entity_Id) return Boolean; 1503 (Id : Entity_Id) return Boolean;
1293 -- Returns true if the subprogram has at least one formal parameter of 1504 -- Returns true if the subprogram has at least one formal parameter of
1294 -- an unconstrained record type with per-object constraints on component 1505 -- an unconstrained record type with per-object constraints on component
1295 -- types. 1506 -- types.
1304 -- Shouldn't this be in Sem_Aux??? 1515 -- Shouldn't this be in Sem_Aux???
1305 1516
1306 function In_Package_Spec (Id : Entity_Id) return Boolean; 1517 function In_Package_Spec (Id : Entity_Id) return Boolean;
1307 -- Return True if subprogram Id is defined in the package specification, 1518 -- Return True if subprogram Id is defined in the package specification,
1308 -- either its visible or private part. 1519 -- either its visible or private part.
1520
1521 function Maybe_Traversal_Function (Id : Entity_Id) return Boolean;
1522 -- Return True if subprogram Id could be a traversal function, as
1523 -- defined in SPARK RM 3.10. This is only a safe approximation, as the
1524 -- knowledge of the SPARK boundary is needed to determine exactly
1525 -- traversal functions.
1526
1527 ---------------------------------------
1528 -- Has_Formal_Or_Result_Of_Deep_Type --
1529 ---------------------------------------
1530
1531 function Has_Formal_Or_Result_Of_Deep_Type
1532 (Id : Entity_Id) return Boolean
1533 is
1534 function Is_Deep (Typ : Entity_Id) return Boolean;
1535 -- Return True if Typ is deep: either an access type or a composite
1536 -- type containing an access type.
1537
1538 -------------
1539 -- Is_Deep --
1540 -------------
1541
1542 function Is_Deep (Typ : Entity_Id) return Boolean is
1543 begin
1544 case Type_Kind'(Ekind (Typ)) is
1545 when Access_Kind =>
1546 return True;
1547
1548 when E_Array_Type
1549 | E_Array_Subtype
1550 =>
1551 return Is_Deep (Component_Type (Typ));
1552
1553 when Record_Kind =>
1554 declare
1555 Comp : Entity_Id := First_Component_Or_Discriminant (Typ);
1556 begin
1557 while Present (Comp) loop
1558 if Is_Deep (Etype (Comp)) then
1559 return True;
1560 end if;
1561 Next_Component_Or_Discriminant (Comp);
1562 end loop;
1563 end;
1564 return False;
1565
1566 when Scalar_Kind
1567 | E_String_Literal_Subtype
1568 | Concurrent_Kind
1569 | Incomplete_Kind
1570 | E_Exception_Type
1571 | E_Subprogram_Type
1572 =>
1573 return False;
1574
1575 when E_Private_Type
1576 | E_Private_Subtype
1577 | E_Limited_Private_Type
1578 | E_Limited_Private_Subtype
1579 =>
1580 -- Conservatively consider that the type might be deep if
1581 -- its completion has not been seen yet.
1582
1583 if No (Underlying_Type (Typ)) then
1584 return True;
1585
1586 -- Do not peek under a private type if its completion has
1587 -- SPARK_Mode Off. In such a case, a deep type is considered
1588 -- by GNATprove to be not deep.
1589
1590 elsif Present (Full_View (Typ))
1591 and then Present (SPARK_Pragma (Full_View (Typ)))
1592 and then Get_SPARK_Mode_From_Annotation
1593 (SPARK_Pragma (Full_View (Typ))) = Off
1594 then
1595 return False;
1596
1597 -- Otherwise peek under the private type.
1598
1599 else
1600 return Is_Deep (Underlying_Type (Typ));
1601 end if;
1602 end case;
1603 end Is_Deep;
1604
1605 -- Local variables
1606
1607 Subp_Id : constant Entity_Id := Ultimate_Alias (Id);
1608 Formal : Entity_Id;
1609 Formal_Typ : Entity_Id;
1610
1611 -- Start of processing for Has_Formal_Or_Result_Of_Deep_Type
1612
1613 begin
1614 -- Inspect all parameters of the subprogram looking for a formal
1615 -- of a deep type.
1616
1617 Formal := First_Formal (Subp_Id);
1618 while Present (Formal) loop
1619 Formal_Typ := Etype (Formal);
1620
1621 if Is_Deep (Formal_Typ) then
1622 return True;
1623 end if;
1624
1625 Next_Formal (Formal);
1626 end loop;
1627
1628 -- Check whether this is a function whose return type is deep
1629
1630 if Ekind (Subp_Id) = E_Function
1631 and then Is_Deep (Etype (Subp_Id))
1632 then
1633 return True;
1634 end if;
1635
1636 return False;
1637 end Has_Formal_Or_Result_Of_Deep_Type;
1309 1638
1310 --------------------------------------------------- 1639 ---------------------------------------------------
1311 -- Has_Formal_With_Discriminant_Dependent_Fields -- 1640 -- Has_Formal_With_Discriminant_Dependent_Fields --
1312 --------------------------------------------------- 1641 ---------------------------------------------------
1313 1642
1428 end if; 1757 end if;
1429 1758
1430 return Nkind (Parent (Decl)) = N_Compilation_Unit; 1759 return Nkind (Parent (Decl)) = N_Compilation_Unit;
1431 end Is_Unit_Subprogram; 1760 end Is_Unit_Subprogram;
1432 1761
1762 ------------------------------
1763 -- Maybe_Traversal_Function --
1764 ------------------------------
1765
1766 function Maybe_Traversal_Function (Id : Entity_Id) return Boolean is
1767 begin
1768 return Ekind (Id) = E_Function
1769
1770 -- Only traversal functions return an anonymous access-to-object
1771 -- type in SPARK.
1772
1773 and then Is_Anonymous_Access_Type (Etype (Id));
1774 end Maybe_Traversal_Function;
1775
1433 -- Local declarations 1776 -- Local declarations
1434 1777
1435 Id : Entity_Id; 1778 Id : Entity_Id;
1436 -- Procedure or function entity for the subprogram 1779 -- Procedure or function entity for the subprogram
1437 1780
1472 -- package spec, when analyzing one of its child packages, as otherwise 1815 -- package spec, when analyzing one of its child packages, as otherwise
1473 -- we issue spurious messages about the impossibility to inline such 1816 -- we issue spurious messages about the impossibility to inline such
1474 -- calls. 1817 -- calls.
1475 1818
1476 elsif not In_Extended_Main_Code_Unit (Id) then 1819 elsif not In_Extended_Main_Code_Unit (Id) then
1820 return False;
1821
1822 -- Do not inline dispatching operations, as only their static calls
1823 -- can be analyzed in context, and not their dispatching calls.
1824
1825 elsif Is_Dispatching_Operation (Id) then
1477 return False; 1826 return False;
1478 1827
1479 -- Do not inline subprograms marked No_Return, possibly used for 1828 -- Do not inline subprograms marked No_Return, possibly used for
1480 -- signaling errors, which GNATprove handles specially. 1829 -- signaling errors, which GNATprove handles specially.
1481 1830
1542 -- such parameters, the frontend cannot always ensure type compliance 1891 -- such parameters, the frontend cannot always ensure type compliance
1543 -- in record component accesses (in particular with records containing 1892 -- in record component accesses (in particular with records containing
1544 -- packed arrays). 1893 -- packed arrays).
1545 1894
1546 elsif Has_Formal_With_Discriminant_Dependent_Fields (Id) then 1895 elsif Has_Formal_With_Discriminant_Dependent_Fields (Id) then
1896 return False;
1897
1898 -- Do not inline subprograms with a formal parameter or return type of
1899 -- a deep type, as in that case inlining might generate code that
1900 -- violates borrow-checking rules of SPARK 3.10 even if the original
1901 -- code did not.
1902
1903 elsif Has_Formal_Or_Result_Of_Deep_Type (Id) then
1904 return False;
1905
1906 -- Do not inline subprograms which may be traversal functions. Such
1907 -- inlining introduces temporary variables of named access type for
1908 -- which assignments are move instead of borrow/observe, possibly
1909 -- leading to spurious errors when checking SPARK rules related to
1910 -- pointer usage.
1911
1912 elsif Maybe_Traversal_Function (Id) then
1547 return False; 1913 return False;
1548 1914
1549 -- Otherwise, this is a subprogram declared inside the private part of a 1915 -- Otherwise, this is a subprogram declared inside the private part of a
1550 -- package, or inside a package body, or locally in a subprogram, and it 1916 -- package, or inside a package body, or locally in a subprogram, and it
1551 -- does not have any contract. Inline it. 1917 -- does not have any contract. Inline it.
1704 is 2070 is
1705 procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id); 2071 procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id);
1706 -- Use generic machinery to build an unexpanded body for the subprogram. 2072 -- Use generic machinery to build an unexpanded body for the subprogram.
1707 -- This body is subsequently used for inline expansions at call sites. 2073 -- This body is subsequently used for inline expansions at call sites.
1708 2074
2075 procedure Build_Return_Object_Formal
2076 (Loc : Source_Ptr;
2077 Obj_Decl : Node_Id;
2078 Formals : List_Id);
2079 -- Create a formal parameter for return object declaration Obj_Decl of
2080 -- an extended return statement and add it to list Formals.
2081
1709 function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean; 2082 function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean;
1710 -- Return true if we generate code for the function body N, the function 2083 -- Return true if we generate code for the function body N, the function
1711 -- body N has no local declarations and its unique statement is a single 2084 -- body N has no local declarations and its unique statement is a single
1712 -- extended return statement with a handled statements sequence. 2085 -- extended return statement with a handled statements sequence.
2086
2087 procedure Copy_Formals
2088 (Loc : Source_Ptr;
2089 Subp_Id : Entity_Id;
2090 Formals : List_Id);
2091 -- Create new formal parameters from the formal parameters of subprogram
2092 -- Subp_Id and add them to list Formals.
2093
2094 function Copy_Return_Object (Obj_Decl : Node_Id) return Node_Id;
2095 -- Create a copy of return object declaration Obj_Decl of an extended
2096 -- return statement.
1713 2097
1714 procedure Split_Unconstrained_Function 2098 procedure Split_Unconstrained_Function
1715 (N : Node_Id; 2099 (N : Node_Id;
1716 Spec_Id : Entity_Id); 2100 Spec_Id : Entity_Id);
1717 -- N is an inlined function body that returns an unconstrained type and 2101 -- N is an inlined function body that returns an unconstrained type and
1731 Body_To_Inline : out Node_Id); 2115 Body_To_Inline : out Node_Id);
1732 -- Generate a parameterless duplicate of subprogram body N. Note that 2116 -- Generate a parameterless duplicate of subprogram body N. Note that
1733 -- occurrences of pragmas referencing the formals are removed since 2117 -- occurrences of pragmas referencing the formals are removed since
1734 -- they have no meaning when the body is inlined and the formals are 2118 -- they have no meaning when the body is inlined and the formals are
1735 -- rewritten (the analysis of the non-inlined body will handle these 2119 -- rewritten (the analysis of the non-inlined body will handle these
1736 -- pragmas). A new internal name is associated with Body_To_Inline. 2120 -- pragmas). A new internal name is associated with Body_To_Inline.
1737 2121
1738 ------------------------------ 2122 ------------------------------
1739 -- Generate_Subprogram_Body -- 2123 -- Generate_Subprogram_Body --
1740 ------------------------------ 2124 ------------------------------
1741 2125
1755 and then Scope (Current_Scope) /= Standard_Standard 2139 and then Scope (Current_Scope) /= Standard_Standard
1756 then 2140 then
1757 Body_To_Inline := 2141 Body_To_Inline :=
1758 Copy_Generic_Node (N, Empty, Instantiating => True); 2142 Copy_Generic_Node (N, Empty, Instantiating => True);
1759 else 2143 else
2144 -- ??? Shouldn't this use New_Copy_Tree? What about global
2145 -- references captured in the body to inline?
2146
1760 Body_To_Inline := Copy_Separate_Tree (N); 2147 Body_To_Inline := Copy_Separate_Tree (N);
1761 end if; 2148 end if;
1762 2149
1763 -- Remove aspects/pragmas that have no meaning in an inlined body 2150 -- Remove aspects/pragmas that have no meaning in an inlined body
1764 2151
1785 2172
1786 Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id); 2173 Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id);
1787 Original_Body : Node_Id; 2174 Original_Body : Node_Id;
1788 Body_To_Analyze : Node_Id; 2175 Body_To_Analyze : Node_Id;
1789 2176
2177 -- Start of processing for Build_Body_To_Inline
2178
1790 begin 2179 begin
1791 pragma Assert (Current_Scope = Spec_Id); 2180 pragma Assert (Current_Scope = Spec_Id);
1792 2181
1793 -- Within an instance, the body to inline must be treated as a nested 2182 -- Within an instance, the body to inline must be treated as a nested
1794 -- generic, so that the proper global references are preserved. We 2183 -- generic, so that the proper global references are preserved. We
1843 pragma Assert (No (Body_To_Inline (Decl))); 2232 pragma Assert (No (Body_To_Inline (Decl)));
1844 Set_Body_To_Inline (Decl, Original_Body); 2233 Set_Body_To_Inline (Decl, Original_Body);
1845 Set_Ekind (Defining_Entity (Original_Body), Ekind (Spec_Id)); 2234 Set_Ekind (Defining_Entity (Original_Body), Ekind (Spec_Id));
1846 end Build_Body_To_Inline; 2235 end Build_Body_To_Inline;
1847 2236
2237 --------------------------------
2238 -- Build_Return_Object_Formal --
2239 --------------------------------
2240
2241 procedure Build_Return_Object_Formal
2242 (Loc : Source_Ptr;
2243 Obj_Decl : Node_Id;
2244 Formals : List_Id)
2245 is
2246 Obj_Def : constant Node_Id := Object_Definition (Obj_Decl);
2247 Obj_Id : constant Entity_Id := Defining_Entity (Obj_Decl);
2248 Typ_Def : Node_Id;
2249
2250 begin
2251 -- Build the type definition of the formal parameter. The use of
2252 -- New_Copy_Tree ensures that global references preserved in the
2253 -- case of generics.
2254
2255 if Is_Entity_Name (Obj_Def) then
2256 Typ_Def := New_Copy_Tree (Obj_Def);
2257 else
2258 Typ_Def := New_Copy_Tree (Subtype_Mark (Obj_Def));
2259 end if;
2260
2261 -- Generate:
2262 --
2263 -- Obj_Id : [out] Typ_Def
2264
2265 -- Mode OUT should not be used when the return object is declared as
2266 -- a constant. Check the definition of the object declaration because
2267 -- the object has not been analyzed yet.
2268
2269 Append_To (Formals,
2270 Make_Parameter_Specification (Loc,
2271 Defining_Identifier =>
2272 Make_Defining_Identifier (Loc, Chars (Obj_Id)),
2273 In_Present => False,
2274 Out_Present => not Constant_Present (Obj_Decl),
2275 Null_Exclusion_Present => False,
2276 Parameter_Type => Typ_Def));
2277 end Build_Return_Object_Formal;
2278
1848 -------------------------------------- 2279 --------------------------------------
1849 -- Can_Split_Unconstrained_Function -- 2280 -- Can_Split_Unconstrained_Function --
1850 -------------------------------------- 2281 --------------------------------------
1851 2282
1852 function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean is 2283 function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean is
1853 Ret_Node : constant Node_Id := 2284 Stmt : constant Node_Id :=
1854 First (Statements (Handled_Statement_Sequence (N))); 2285 First (Statements (Handled_Statement_Sequence (N)));
1855 D : Node_Id; 2286 Decl : Node_Id;
1856 2287
1857 begin 2288 begin
1858 -- No user defined declarations allowed in the function except inside 2289 -- No user defined declarations allowed in the function except inside
1859 -- the unique return statement; implicit labels are the only allowed 2290 -- the unique return statement; implicit labels are the only allowed
1860 -- declarations. 2291 -- declarations.
1861 2292
1862 if not Is_Empty_List (Declarations (N)) then 2293 Decl := First (Declarations (N));
1863 D := First (Declarations (N)); 2294 while Present (Decl) loop
1864 while Present (D) loop 2295 if Nkind (Decl) /= N_Implicit_Label_Declaration then
1865 if Nkind (D) /= N_Implicit_Label_Declaration then 2296 return False;
1866 return False; 2297 end if;
1867 end if; 2298
1868 2299 Next (Decl);
1869 Next (D); 2300 end loop;
1870 end loop;
1871 end if;
1872 2301
1873 -- We only split the inlined function when we are generating the code 2302 -- We only split the inlined function when we are generating the code
1874 -- of its body; otherwise we leave duplicated split subprograms in 2303 -- of its body; otherwise we leave duplicated split subprograms in
1875 -- the tree which (if referenced) generate wrong references at link 2304 -- the tree which (if referenced) generate wrong references at link
1876 -- time. 2305 -- time.
1877 2306
1878 return In_Extended_Main_Code_Unit (N) 2307 return In_Extended_Main_Code_Unit (N)
1879 and then Present (Ret_Node) 2308 and then Present (Stmt)
1880 and then Nkind (Ret_Node) = N_Extended_Return_Statement 2309 and then Nkind (Stmt) = N_Extended_Return_Statement
1881 and then No (Next (Ret_Node)) 2310 and then No (Next (Stmt))
1882 and then Present (Handled_Statement_Sequence (Ret_Node)); 2311 and then Present (Handled_Statement_Sequence (Stmt));
1883 end Can_Split_Unconstrained_Function; 2312 end Can_Split_Unconstrained_Function;
2313
2314 ------------------
2315 -- Copy_Formals --
2316 ------------------
2317
2318 procedure Copy_Formals
2319 (Loc : Source_Ptr;
2320 Subp_Id : Entity_Id;
2321 Formals : List_Id)
2322 is
2323 Formal : Entity_Id;
2324 Spec : Node_Id;
2325
2326 begin
2327 Formal := First_Formal (Subp_Id);
2328 while Present (Formal) loop
2329 Spec := Parent (Formal);
2330
2331 -- Create an exact copy of the formal parameter. The use of
2332 -- New_Copy_Tree ensures that global references are preserved
2333 -- in case of generics.
2334
2335 Append_To (Formals,
2336 Make_Parameter_Specification (Loc,
2337 Defining_Identifier =>
2338 Make_Defining_Identifier (Sloc (Formal), Chars (Formal)),
2339 In_Present => In_Present (Spec),
2340 Out_Present => Out_Present (Spec),
2341 Null_Exclusion_Present => Null_Exclusion_Present (Spec),
2342 Parameter_Type =>
2343 New_Copy_Tree (Parameter_Type (Spec)),
2344 Expression => New_Copy_Tree (Expression (Spec))));
2345
2346 Next_Formal (Formal);
2347 end loop;
2348 end Copy_Formals;
2349
2350 ------------------------
2351 -- Copy_Return_Object --
2352 ------------------------
2353
2354 function Copy_Return_Object (Obj_Decl : Node_Id) return Node_Id is
2355 Obj_Id : constant Entity_Id := Defining_Entity (Obj_Decl);
2356
2357 begin
2358 -- The use of New_Copy_Tree ensures that global references are
2359 -- preserved in case of generics.
2360
2361 return
2362 Make_Object_Declaration (Sloc (Obj_Decl),
2363 Defining_Identifier =>
2364 Make_Defining_Identifier (Sloc (Obj_Id), Chars (Obj_Id)),
2365 Aliased_Present => Aliased_Present (Obj_Decl),
2366 Constant_Present => Constant_Present (Obj_Decl),
2367 Null_Exclusion_Present => Null_Exclusion_Present (Obj_Decl),
2368 Object_Definition =>
2369 New_Copy_Tree (Object_Definition (Obj_Decl)),
2370 Expression => New_Copy_Tree (Expression (Obj_Decl)));
2371 end Copy_Return_Object;
1884 2372
1885 ---------------------------------- 2373 ----------------------------------
1886 -- Split_Unconstrained_Function -- 2374 -- Split_Unconstrained_Function --
1887 ---------------------------------- 2375 ----------------------------------
1888 2376
1889 procedure Split_Unconstrained_Function 2377 procedure Split_Unconstrained_Function
1890 (N : Node_Id; 2378 (N : Node_Id;
1891 Spec_Id : Entity_Id) 2379 Spec_Id : Entity_Id)
1892 is 2380 is
1893 Loc : constant Source_Ptr := Sloc (N); 2381 Loc : constant Source_Ptr := Sloc (N);
1894 Ret_Node : constant Node_Id := 2382 Ret_Stmt : constant Node_Id :=
1895 First (Statements (Handled_Statement_Sequence (N))); 2383 First (Statements (Handled_Statement_Sequence (N)));
1896 Ret_Obj : constant Node_Id := 2384 Ret_Obj : constant Node_Id :=
1897 First (Return_Object_Declarations (Ret_Node)); 2385 First (Return_Object_Declarations (Ret_Stmt));
1898 2386
1899 procedure Build_Procedure 2387 procedure Build_Procedure
1900 (Proc_Id : out Entity_Id; 2388 (Proc_Id : out Entity_Id;
1901 Decl_List : out List_Id); 2389 Decl_List : out List_Id);
1902 -- Build a procedure containing the statements found in the extended 2390 -- Build a procedure containing the statements found in the extended
1908 2396
1909 procedure Build_Procedure 2397 procedure Build_Procedure
1910 (Proc_Id : out Entity_Id; 2398 (Proc_Id : out Entity_Id;
1911 Decl_List : out List_Id) 2399 Decl_List : out List_Id)
1912 is 2400 is
1913 Formal : Entity_Id; 2401 Formals : constant List_Id := New_List;
1914 Formal_List : constant List_Id := New_List; 2402 Subp_Name : constant Name_Id := New_Internal_Name ('F');
1915 Proc_Spec : Node_Id; 2403
1916 Proc_Body : Node_Id; 2404 Body_Decls : List_Id := No_List;
1917 Subp_Name : constant Name_Id := New_Internal_Name ('F'); 2405 Decl : Node_Id;
1918 Body_Decl_List : List_Id := No_List; 2406 Proc_Body : Node_Id;
1919 Param_Type : Node_Id; 2407 Proc_Spec : Node_Id;
1920 2408
1921 begin 2409 begin
1922 if Nkind (Object_Definition (Ret_Obj)) = N_Identifier then 2410 -- Create formal parameters for the return object and all formals
1923 Param_Type := 2411 -- of the unconstrained function in order to pass their values to
1924 New_Copy (Object_Definition (Ret_Obj)); 2412 -- the procedure.
1925 else 2413
1926 Param_Type := 2414 Build_Return_Object_Formal
1927 New_Copy (Subtype_Mark (Object_Definition (Ret_Obj))); 2415 (Loc => Loc,
1928 end if; 2416 Obj_Decl => Ret_Obj,
1929 2417 Formals => Formals);
1930 Append_To (Formal_List, 2418
1931 Make_Parameter_Specification (Loc, 2419 Copy_Formals
1932 Defining_Identifier => 2420 (Loc => Loc,
1933 Make_Defining_Identifier (Loc, 2421 Subp_Id => Spec_Id,
1934 Chars => Chars (Defining_Identifier (Ret_Obj))), 2422 Formals => Formals);
1935 In_Present => False,
1936 Out_Present => True,
1937 Null_Exclusion_Present => False,
1938 Parameter_Type => Param_Type));
1939
1940 Formal := First_Formal (Spec_Id);
1941
1942 -- Note that we copy the parameter type rather than creating
1943 -- a reference to it, because it may be a class-wide entity
1944 -- that will not be retrieved by name.
1945
1946 while Present (Formal) loop
1947 Append_To (Formal_List,
1948 Make_Parameter_Specification (Loc,
1949 Defining_Identifier =>
1950 Make_Defining_Identifier (Sloc (Formal),
1951 Chars => Chars (Formal)),
1952 In_Present => In_Present (Parent (Formal)),
1953 Out_Present => Out_Present (Parent (Formal)),
1954 Null_Exclusion_Present =>
1955 Null_Exclusion_Present (Parent (Formal)),
1956 Parameter_Type =>
1957 New_Copy_Tree (Parameter_Type (Parent (Formal))),
1958 Expression =>
1959 Copy_Separate_Tree (Expression (Parent (Formal)))));
1960
1961 Next_Formal (Formal);
1962 end loop;
1963 2423
1964 Proc_Id := Make_Defining_Identifier (Loc, Chars => Subp_Name); 2424 Proc_Id := Make_Defining_Identifier (Loc, Chars => Subp_Name);
1965 2425
1966 Proc_Spec := 2426 Proc_Spec :=
1967 Make_Procedure_Specification (Loc, 2427 Make_Procedure_Specification (Loc,
1968 Defining_Unit_Name => Proc_Id, 2428 Defining_Unit_Name => Proc_Id,
1969 Parameter_Specifications => Formal_List); 2429 Parameter_Specifications => Formals);
1970 2430
1971 Decl_List := New_List; 2431 Decl_List := New_List;
1972 2432
1973 Append_To (Decl_List, 2433 Append_To (Decl_List,
1974 Make_Subprogram_Declaration (Loc, Proc_Spec)); 2434 Make_Subprogram_Declaration (Loc, Proc_Spec));
1976 -- Can_Convert_Unconstrained_Function checked that the function 2436 -- Can_Convert_Unconstrained_Function checked that the function
1977 -- has no local declarations except implicit label declarations. 2437 -- has no local declarations except implicit label declarations.
1978 -- Copy these declarations to the built procedure. 2438 -- Copy these declarations to the built procedure.
1979 2439
1980 if Present (Declarations (N)) then 2440 if Present (Declarations (N)) then
1981 Body_Decl_List := New_List; 2441 Body_Decls := New_List;
1982 2442
1983 declare 2443 Decl := First (Declarations (N));
1984 D : Node_Id; 2444 while Present (Decl) loop
1985 New_D : Node_Id; 2445 pragma Assert (Nkind (Decl) = N_Implicit_Label_Declaration);
1986 2446
1987 begin 2447 Append_To (Body_Decls,
1988 D := First (Declarations (N)); 2448 Make_Implicit_Label_Declaration (Loc,
1989 while Present (D) loop 2449 Make_Defining_Identifier (Loc,
1990 pragma Assert (Nkind (D) = N_Implicit_Label_Declaration); 2450 Chars => Chars (Defining_Identifier (Decl))),
1991 2451 Label_Construct => Empty));
1992 New_D := 2452
1993 Make_Implicit_Label_Declaration (Loc, 2453 Next (Decl);
1994 Make_Defining_Identifier (Loc, 2454 end loop;
1995 Chars => Chars (Defining_Identifier (D))), 2455 end if;
1996 Label_Construct => Empty); 2456
1997 Append_To (Body_Decl_List, New_D); 2457 pragma Assert (Present (Handled_Statement_Sequence (Ret_Stmt)));
1998
1999 Next (D);
2000 end loop;
2001 end;
2002 end if;
2003
2004 pragma Assert (Present (Handled_Statement_Sequence (Ret_Node)));
2005 2458
2006 Proc_Body := 2459 Proc_Body :=
2007 Make_Subprogram_Body (Loc, 2460 Make_Subprogram_Body (Loc,
2008 Specification => Copy_Separate_Tree (Proc_Spec), 2461 Specification => Copy_Subprogram_Spec (Proc_Spec),
2009 Declarations => Body_Decl_List, 2462 Declarations => Body_Decls,
2010 Handled_Statement_Sequence => 2463 Handled_Statement_Sequence =>
2011 Copy_Separate_Tree (Handled_Statement_Sequence (Ret_Node))); 2464 New_Copy_Tree (Handled_Statement_Sequence (Ret_Stmt)));
2012 2465
2013 Set_Defining_Unit_Name (Specification (Proc_Body), 2466 Set_Defining_Unit_Name (Specification (Proc_Body),
2014 Make_Defining_Identifier (Loc, Subp_Name)); 2467 Make_Defining_Identifier (Loc, Subp_Name));
2015 2468
2016 Append_To (Decl_List, Proc_Body); 2469 Append_To (Decl_List, Proc_Body);
2017 end Build_Procedure; 2470 end Build_Procedure;
2018 2471
2019 -- Local variables 2472 -- Local variables
2020 2473
2021 New_Obj : constant Node_Id := Copy_Separate_Tree (Ret_Obj); 2474 New_Obj : constant Node_Id := Copy_Return_Object (Ret_Obj);
2022 Blk_Stmt : Node_Id; 2475 Blk_Stmt : Node_Id;
2476 Proc_Call : Node_Id;
2023 Proc_Id : Entity_Id; 2477 Proc_Id : Entity_Id;
2024 Proc_Call : Node_Id;
2025 2478
2026 -- Start of processing for Split_Unconstrained_Function 2479 -- Start of processing for Split_Unconstrained_Function
2027 2480
2028 begin 2481 begin
2029 -- Build the associated procedure, analyze it and insert it before 2482 -- Build the associated procedure, analyze it and insert it before
2087 Make_Simple_Return_Statement (Loc, 2540 Make_Simple_Return_Statement (Loc,
2088 Expression => 2541 Expression =>
2089 New_Occurrence_Of 2542 New_Occurrence_Of
2090 (Defining_Identifier (New_Obj), Loc))))); 2543 (Defining_Identifier (New_Obj), Loc)))));
2091 2544
2092 Rewrite (Ret_Node, Blk_Stmt); 2545 Rewrite (Ret_Stmt, Blk_Stmt);
2093 end Split_Unconstrained_Function; 2546 end Split_Unconstrained_Function;
2094 2547
2095 -- Local variables 2548 -- Local variables
2096 2549
2097 Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id); 2550 Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id);
2126 -- Cannot build the body to inline if the attribute is already set. 2579 -- Cannot build the body to inline if the attribute is already set.
2127 -- This attribute may have been set if this is a subprogram renaming 2580 -- This attribute may have been set if this is a subprogram renaming
2128 -- declarations (see Freeze.Build_Renamed_Body). 2581 -- declarations (see Freeze.Build_Renamed_Body).
2129 2582
2130 elsif Present (Body_To_Inline (Decl)) then 2583 elsif Present (Body_To_Inline (Decl)) then
2584 return;
2585
2586 -- Do not generate a body to inline for protected functions, because the
2587 -- transformation generates a call to a protected procedure, causing
2588 -- spurious errors. We don't inline protected operations anyway, so
2589 -- this is no loss. We might as well ignore intrinsics and foreign
2590 -- conventions as well -- just allow Ada conventions.
2591
2592 elsif not (Convention (Spec_Id) = Convention_Ada
2593 or else Convention (Spec_Id) = Convention_Ada_Pass_By_Copy
2594 or else Convention (Spec_Id) = Convention_Ada_Pass_By_Reference)
2595 then
2131 return; 2596 return;
2132 2597
2133 -- Check excluded declarations 2598 -- Check excluded declarations
2134 2599
2135 elsif Present (Declarations (N)) 2600 elsif Present (Declarations (N))
2384 procedure Make_Exit_Label; 2849 procedure Make_Exit_Label;
2385 -- Build declaration for exit label to be used in Return statements, 2850 -- Build declaration for exit label to be used in Return statements,
2386 -- sets Exit_Lab (the label node) and Lab_Decl (corresponding implicit 2851 -- sets Exit_Lab (the label node) and Lab_Decl (corresponding implicit
2387 -- declaration). Does nothing if Exit_Lab already set. 2852 -- declaration). Does nothing if Exit_Lab already set.
2388 2853
2854 procedure Make_Loop_Labels_Unique (HSS : Node_Id);
2855 -- When compiling for CCG and performing front-end inlining, replace
2856 -- loop names and references to them so that they do not conflict with
2857 -- homographs in the current subprogram.
2858
2389 function Process_Formals (N : Node_Id) return Traverse_Result; 2859 function Process_Formals (N : Node_Id) return Traverse_Result;
2390 -- Replace occurrence of a formal with the corresponding actual, or the 2860 -- Replace occurrence of a formal with the corresponding actual, or the
2391 -- thunk generated for it. Replace a return statement with an assignment 2861 -- thunk generated for it. Replace a return statement with an assignment
2392 -- to the target of the call, with appropriate conversions if needed. 2862 -- to the target of the call, with appropriate conversions if needed.
2863
2864 function Process_Formals_In_Aspects (N : Node_Id) return Traverse_Result;
2865 -- Because aspects are linked indirectly to the rest of the tree,
2866 -- replacement of formals appearing in aspect specifications must
2867 -- be performed in a separate pass, using an instantiation of the
2868 -- previous subprogram over aspect specifications reachable from N.
2393 2869
2394 function Process_Sloc (Nod : Node_Id) return Traverse_Result; 2870 function Process_Sloc (Nod : Node_Id) return Traverse_Result;
2395 -- If the call being expanded is that of an internal subprogram, set the 2871 -- If the call being expanded is that of an internal subprogram, set the
2396 -- sloc of the generated block to that of the call itself, so that the 2872 -- sloc of the generated block to that of the call itself, so that the
2397 -- expansion is skipped by the "next" command in gdb. Same processing 2873 -- expansion is skipped by the "next" command in gdb. Same processing
2472 Defining_Identifier => Lab_Ent, 2948 Defining_Identifier => Lab_Ent,
2473 Label_Construct => Exit_Lab); 2949 Label_Construct => Exit_Lab);
2474 end if; 2950 end if;
2475 end Make_Exit_Label; 2951 end Make_Exit_Label;
2476 2952
2953 -----------------------------
2954 -- Make_Loop_Labels_Unique --
2955 -----------------------------
2956
2957 procedure Make_Loop_Labels_Unique (HSS : Node_Id) is
2958 function Process_Loop (N : Node_Id) return Traverse_Result;
2959
2960 ------------------
2961 -- Process_Loop --
2962 ------------------
2963
2964 function Process_Loop (N : Node_Id) return Traverse_Result is
2965 Id : Entity_Id;
2966
2967 begin
2968 if Nkind (N) = N_Loop_Statement
2969 and then Present (Identifier (N))
2970 then
2971 -- Create new external name for loop and update the
2972 -- corresponding entity.
2973
2974 Id := Entity (Identifier (N));
2975 Set_Chars (Id, New_External_Name (Chars (Id), 'L', -1));
2976 Set_Chars (Identifier (N), Chars (Id));
2977
2978 elsif Nkind (N) = N_Exit_Statement
2979 and then Present (Name (N))
2980 then
2981 -- The exit statement must name an enclosing loop, whose name
2982 -- has already been updated.
2983
2984 Set_Chars (Name (N), Chars (Entity (Name (N))));
2985 end if;
2986
2987 return OK;
2988 end Process_Loop;
2989
2990 procedure Update_Loop_Names is new Traverse_Proc (Process_Loop);
2991
2992 -- Local variables
2993
2994 Stmt : Node_Id;
2995
2996 -- Start of processing for Make_Loop_Labels_Unique
2997
2998 begin
2999 if Modify_Tree_For_C then
3000 Stmt := First (Statements (HSS));
3001 while Present (Stmt) loop
3002 Update_Loop_Names (Stmt);
3003 Next (Stmt);
3004 end loop;
3005 end if;
3006 end Make_Loop_Labels_Unique;
3007
2477 --------------------- 3008 ---------------------
2478 -- Process_Formals -- 3009 -- Process_Formals --
2479 --------------------- 3010 ---------------------
2480 3011
2481 function Process_Formals (N : Node_Id) return Traverse_Result is 3012 function Process_Formals (N : Node_Id) return Traverse_Result is
2674 end if; 3205 end if;
2675 end Process_Formals; 3206 end Process_Formals;
2676 3207
2677 procedure Replace_Formals is new Traverse_Proc (Process_Formals); 3208 procedure Replace_Formals is new Traverse_Proc (Process_Formals);
2678 3209
3210 --------------------------------
3211 -- Process_Formals_In_Aspects --
3212 --------------------------------
3213
3214 function Process_Formals_In_Aspects
3215 (N : Node_Id) return Traverse_Result
3216 is
3217 A : Node_Id;
3218
3219 begin
3220 if Has_Aspects (N) then
3221 A := First (Aspect_Specifications (N));
3222 while Present (A) loop
3223 Replace_Formals (Expression (A));
3224
3225 Next (A);
3226 end loop;
3227 end if;
3228 return OK;
3229 end Process_Formals_In_Aspects;
3230
3231 procedure Replace_Formals_In_Aspects is
3232 new Traverse_Proc (Process_Formals_In_Aspects);
3233
2679 ------------------ 3234 ------------------
2680 -- Process_Sloc -- 3235 -- Process_Sloc --
2681 ------------------ 3236 ------------------
2682 3237
2683 function Process_Sloc (Nod : Node_Id) return Traverse_Result is 3238 function Process_Sloc (Nod : Node_Id) return Traverse_Result is
2740 procedure Rewrite_Function_Call (N : Node_Id; Blk : Node_Id) is 3295 procedure Rewrite_Function_Call (N : Node_Id; Blk : Node_Id) is
2741 HSS : constant Node_Id := Handled_Statement_Sequence (Blk); 3296 HSS : constant Node_Id := Handled_Statement_Sequence (Blk);
2742 Fst : constant Node_Id := First (Statements (HSS)); 3297 Fst : constant Node_Id := First (Statements (HSS));
2743 3298
2744 begin 3299 begin
3300 Make_Loop_Labels_Unique (HSS);
3301
2745 -- Optimize simple case: function body is a single return statement, 3302 -- Optimize simple case: function body is a single return statement,
2746 -- which has been expanded into an assignment. 3303 -- which has been expanded into an assignment.
2747 3304
2748 if Is_Empty_List (Declarations (Blk)) 3305 if Is_Empty_List (Declarations (Blk))
2749 and then Nkind (Fst) = N_Assignment_Statement 3306 and then Nkind (Fst) = N_Assignment_Statement
2827 3384
2828 procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id) is 3385 procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id) is
2829 HSS : constant Node_Id := Handled_Statement_Sequence (Blk); 3386 HSS : constant Node_Id := Handled_Statement_Sequence (Blk);
2830 3387
2831 begin 3388 begin
3389 Make_Loop_Labels_Unique (HSS);
3390
2832 -- If there is a transient scope for N, this will be the scope of the 3391 -- If there is a transient scope for N, this will be the scope of the
2833 -- actions for N, and the statements in Blk need to be within this 3392 -- actions for N, and the statements in Blk need to be within this
2834 -- scope. For example, they need to have visibility on the constant 3393 -- scope. For example, they need to have visibility on the constant
2835 -- declarations created for the formals. 3394 -- declarations created for the formals.
2836 3395
3482 4041
3483 -- Traverse the tree and replace formals with actuals or their thunks. 4042 -- Traverse the tree and replace formals with actuals or their thunks.
3484 -- Attach block to tree before analysis and rewriting. 4043 -- Attach block to tree before analysis and rewriting.
3485 4044
3486 Replace_Formals (Blk); 4045 Replace_Formals (Blk);
4046 Replace_Formals_In_Aspects (Blk);
3487 Set_Parent (Blk, N); 4047 Set_Parent (Blk, N);
3488 4048
3489 if GNATprove_Mode then 4049 if GNATprove_Mode then
3490 null; 4050 null;
3491 4051
4011 -- Initialize -- 4571 -- Initialize --
4012 ---------------- 4572 ----------------
4013 4573
4014 procedure Initialize is 4574 procedure Initialize is
4015 begin 4575 begin
4016 Pending_Descriptor.Init;
4017 Pending_Instantiations.Init; 4576 Pending_Instantiations.Init;
4577 Called_Pending_Instantiations.Init;
4018 Inlined_Bodies.Init; 4578 Inlined_Bodies.Init;
4019 Successors.Init; 4579 Successors.Init;
4020 Inlined.Init; 4580 Inlined.Init;
4021 4581
4022 for J in Hash_Headers'Range loop 4582 for J in Hash_Headers'Range loop
4023 Hash_Headers (J) := No_Subp; 4583 Hash_Headers (J) := No_Subp;
4024 end loop; 4584 end loop;
4025 4585
4026 Inlined_Calls := No_Elist; 4586 Inlined_Calls := No_Elist;
4027 Backend_Calls := No_Elist; 4587 Backend_Calls := No_Elist;
4588 Backend_Instances := No_Elist;
4028 Backend_Inlined_Subps := No_Elist; 4589 Backend_Inlined_Subps := No_Elist;
4029 Backend_Not_Inlined_Subps := No_Elist; 4590 Backend_Not_Inlined_Subps := No_Elist;
4030 end Initialize; 4591 end Initialize;
4031 4592
4032 ------------------------ 4593 ------------------------
4039 -- Generic associations have verified that the contract model is 4600 -- Generic associations have verified that the contract model is
4040 -- satisfied, so that any error that may occur in the analysis of 4601 -- satisfied, so that any error that may occur in the analysis of
4041 -- the body is an internal error. 4602 -- the body is an internal error.
4042 4603
4043 procedure Instantiate_Bodies is 4604 procedure Instantiate_Bodies is
4044 J : Nat; 4605
4606 procedure Instantiate_Body (Info : Pending_Body_Info);
4607 -- Instantiate a pending body
4608
4609 ------------------------
4610 -- Instantiate_Body --
4611 ------------------------
4612
4613 procedure Instantiate_Body (Info : Pending_Body_Info) is
4614 begin
4615 -- If the instantiation node is absent, it has been removed as part
4616 -- of unreachable code.
4617
4618 if No (Info.Inst_Node) then
4619 null;
4620
4621 -- If the instantiation node is a package body, this means that the
4622 -- instance is a compilation unit and the instantiation has already
4623 -- been performed by Build_Instance_Compilation_Unit_Nodes.
4624
4625 elsif Nkind (Info.Inst_Node) = N_Package_Body then
4626 null;
4627
4628 elsif Nkind (Info.Act_Decl) = N_Package_Declaration then
4629 Instantiate_Package_Body (Info);
4630 Add_Scope_To_Clean (Defining_Entity (Info.Act_Decl));
4631
4632 else
4633 Instantiate_Subprogram_Body (Info);
4634 end if;
4635 end Instantiate_Body;
4636
4637 J, K : Nat;
4045 Info : Pending_Body_Info; 4638 Info : Pending_Body_Info;
4639
4640 -- Start of processing for Instantiate_Bodies
4046 4641
4047 begin 4642 begin
4048 if Serious_Errors_Detected = 0 then 4643 if Serious_Errors_Detected = 0 then
4049 Expander_Active := (Operating_Mode = Opt.Generate_Code); 4644 Expander_Active := (Operating_Mode = Opt.Generate_Code);
4050 Push_Scope (Standard_Standard); 4645 Push_Scope (Standard_Standard);
4054 Start_Generic; 4649 Start_Generic;
4055 end if; 4650 end if;
4056 4651
4057 -- A body instantiation may generate additional instantiations, so 4652 -- A body instantiation may generate additional instantiations, so
4058 -- the following loop must scan to the end of a possibly expanding 4653 -- the following loop must scan to the end of a possibly expanding
4059 -- set (that's why we can't simply use a FOR loop here). 4654 -- set (that's why we cannot simply use a FOR loop here). We must
4655 -- also capture the element lest the set be entirely reallocated.
4060 4656
4061 J := 0; 4657 J := 0;
4062 while J <= Pending_Instantiations.Last 4658 if Back_End_Inlining then
4063 and then Serious_Errors_Detected = 0 4659 while J <= Called_Pending_Instantiations.Last
4064 loop 4660 and then Serious_Errors_Detected = 0
4065 Info := Pending_Instantiations.Table (J); 4661 loop
4066 4662 K := Called_Pending_Instantiations.Table (J);
4067 -- If the instantiation node is absent, it has been removed 4663 Info := Pending_Instantiations.Table (K);
4068 -- as part of unreachable code. 4664 Instantiate_Body (Info);
4069 4665
4070 if No (Info.Inst_Node) then 4666 J := J + 1;
4071 null; 4667 end loop;
4072 4668
4073 elsif Nkind (Info.Act_Decl) = N_Package_Declaration then 4669 else
4074 Instantiate_Package_Body (Info); 4670 while J <= Pending_Instantiations.Last
4075 Add_Scope_To_Clean (Defining_Entity (Info.Act_Decl)); 4671 and then Serious_Errors_Detected = 0
4076 4672 loop
4077 else 4673 Info := Pending_Instantiations.Table (J);
4078 Instantiate_Subprogram_Body (Info); 4674 Instantiate_Body (Info);
4079 end if; 4675
4080 4676 J := J + 1;
4081 J := J + 1; 4677 end loop;
4082 end loop; 4678 end if;
4083 4679
4084 -- Reset the table of instantiations. Additional instantiations 4680 -- Reset the table of instantiations. Additional instantiations
4085 -- may be added through inlining, when additional bodies are 4681 -- may be added through inlining, when additional bodies are
4086 -- analyzed. 4682 -- analyzed.
4087 4683
4088 Pending_Instantiations.Init; 4684 if Back_End_Inlining then
4685 Called_Pending_Instantiations.Init;
4686 else
4687 Pending_Instantiations.Init;
4688 end if;
4089 4689
4090 -- We can now complete the cleanup actions of scopes that contain 4690 -- We can now complete the cleanup actions of scopes that contain
4091 -- pending instantiations (skipped for generic units, since we 4691 -- pending instantiations (skipped for generic units, since we
4092 -- never need any cleanups in generic units). 4692 -- never need any cleanups in generic units).
4093 4693
4111 Scop : Entity_Id; 4711 Scop : Entity_Id;
4112 4712
4113 begin 4713 begin
4114 Scop := Scope (E); 4714 Scop := Scope (E);
4115 while Scop /= Standard_Standard loop 4715 while Scop /= Standard_Standard loop
4116 if Ekind (Scop) in Subprogram_Kind then 4716 if Is_Subprogram (Scop) then
4117 return True; 4717 return True;
4118 4718
4119 elsif Ekind (Scop) = E_Task_Type 4719 elsif Ekind (Scop) = E_Task_Type
4120 or else Ekind (Scop) = E_Entry 4720 or else Ekind (Scop) = E_Entry
4121 or else Ekind (Scop) = E_Entry_Family 4721 or else Ekind (Scop) = E_Entry_Family
4149 Count := 0; 4749 Count := 0;
4150 Elmt := First_Elmt (Inlined_Calls); 4750 Elmt := First_Elmt (Inlined_Calls);
4151 while Present (Elmt) loop 4751 while Present (Elmt) loop
4152 Nod := Node (Elmt); 4752 Nod := Node (Elmt);
4153 4753
4154 if In_Extended_Main_Code_Unit (Nod) then 4754 if not In_Internal_Unit (Nod) then
4155 Count := Count + 1; 4755 Count := Count + 1;
4156 4756
4157 if Count = 1 then 4757 if Count = 1 then
4158 Write_Str ("List of calls inlined by the frontend"); 4758 Write_Str ("List of calls inlined by the frontend");
4159 Write_Eol; 4759 Write_Eol;
4178 4778
4179 Elmt := First_Elmt (Backend_Calls); 4779 Elmt := First_Elmt (Backend_Calls);
4180 while Present (Elmt) loop 4780 while Present (Elmt) loop
4181 Nod := Node (Elmt); 4781 Nod := Node (Elmt);
4182 4782
4183 if In_Extended_Main_Code_Unit (Nod) then 4783 if not In_Internal_Unit (Nod) then
4184 Count := Count + 1; 4784 Count := Count + 1;
4185 4785
4186 if Count = 1 then 4786 if Count = 1 then
4187 Write_Str ("List of inlined calls passed to the backend"); 4787 Write_Str ("List of inlined calls passed to the backend");
4188 Write_Eol; 4788 Write_Eol;
4197 4797
4198 Next_Elmt (Elmt); 4798 Next_Elmt (Elmt);
4199 end loop; 4799 end loop;
4200 end if; 4800 end if;
4201 4801
4802 -- Generate listing of instances inlined for the backend
4803
4804 if Present (Backend_Instances) then
4805 Count := 0;
4806
4807 Elmt := First_Elmt (Backend_Instances);
4808 while Present (Elmt) loop
4809 Nod := Node (Elmt);
4810
4811 if not In_Internal_Unit (Nod) then
4812 Count := Count + 1;
4813
4814 if Count = 1 then
4815 Write_Str ("List of instances inlined for the backend");
4816 Write_Eol;
4817 end if;
4818
4819 Write_Str (" ");
4820 Write_Int (Count);
4821 Write_Str (":");
4822 Write_Location (Sloc (Nod));
4823 Output.Write_Eol;
4824 end if;
4825
4826 Next_Elmt (Elmt);
4827 end loop;
4828 end if;
4829
4202 -- Generate listing of subprograms passed to the backend 4830 -- Generate listing of subprograms passed to the backend
4203 4831
4204 if Present (Backend_Inlined_Subps) and then Back_End_Inlining then 4832 if Present (Backend_Inlined_Subps) and then Back_End_Inlining then
4205 Count := 0; 4833 Count := 0;
4206 4834
4207 Elmt := First_Elmt (Backend_Inlined_Subps); 4835 Elmt := First_Elmt (Backend_Inlined_Subps);
4208 while Present (Elmt) loop 4836 while Present (Elmt) loop
4209 Nod := Node (Elmt); 4837 Nod := Node (Elmt);
4210 4838
4211 Count := Count + 1; 4839 if not In_Internal_Unit (Nod) then
4212 4840 Count := Count + 1;
4213 if Count = 1 then 4841
4214 Write_Str 4842 if Count = 1 then
4215 ("List of inlined subprograms passed to the backend"); 4843 Write_Str
4216 Write_Eol; 4844 ("List of inlined subprograms passed to the backend");
4217 end if; 4845 Write_Eol;
4218 4846 end if;
4219 Write_Str (" "); 4847
4220 Write_Int (Count); 4848 Write_Str (" ");
4221 Write_Str (":"); 4849 Write_Int (Count);
4222 Write_Name (Chars (Nod)); 4850 Write_Str (":");
4223 Write_Str (" ("); 4851 Write_Name (Chars (Nod));
4224 Write_Location (Sloc (Nod)); 4852 Write_Str (" (");
4225 Write_Str (")"); 4853 Write_Location (Sloc (Nod));
4226 Output.Write_Eol; 4854 Write_Str (")");
4855 Output.Write_Eol;
4856 end if;
4227 4857
4228 Next_Elmt (Elmt); 4858 Next_Elmt (Elmt);
4229 end loop; 4859 end loop;
4230 end if; 4860 end if;
4231 4861
4236 4866
4237 Elmt := First_Elmt (Backend_Not_Inlined_Subps); 4867 Elmt := First_Elmt (Backend_Not_Inlined_Subps);
4238 while Present (Elmt) loop 4868 while Present (Elmt) loop
4239 Nod := Node (Elmt); 4869 Nod := Node (Elmt);
4240 4870
4241 Count := Count + 1; 4871 if not In_Internal_Unit (Nod) then
4242 4872 Count := Count + 1;
4243 if Count = 1 then 4873
4244 Write_Str 4874 if Count = 1 then
4245 ("List of subprograms that cannot be inlined by the backend"); 4875 Write_Str
4246 Write_Eol; 4876 ("List of subprograms that cannot be inlined by backend");
4247 end if; 4877 Write_Eol;
4248 4878 end if;
4249 Write_Str (" "); 4879
4250 Write_Int (Count); 4880 Write_Str (" ");
4251 Write_Str (":"); 4881 Write_Int (Count);
4252 Write_Name (Chars (Nod)); 4882 Write_Str (":");
4253 Write_Str (" ("); 4883 Write_Name (Chars (Nod));
4254 Write_Location (Sloc (Nod)); 4884 Write_Str (" (");
4255 Write_Str (")"); 4885 Write_Location (Sloc (Nod));
4256 Output.Write_Eol; 4886 Write_Str (")");
4887 Output.Write_Eol;
4888 end if;
4257 4889
4258 Next_Elmt (Elmt); 4890 Next_Elmt (Elmt);
4259 end loop; 4891 end loop;
4260 end if; 4892 end if;
4261 end List_Inlining_Info; 4893 end List_Inlining_Info;
4266 4898
4267 procedure Lock is 4899 procedure Lock is
4268 begin 4900 begin
4269 Pending_Instantiations.Release; 4901 Pending_Instantiations.Release;
4270 Pending_Instantiations.Locked := True; 4902 Pending_Instantiations.Locked := True;
4903 Called_Pending_Instantiations.Release;
4904 Called_Pending_Instantiations.Locked := True;
4271 Inlined_Bodies.Release; 4905 Inlined_Bodies.Release;
4272 Inlined_Bodies.Locked := True; 4906 Inlined_Bodies.Locked := True;
4273 Successors.Release; 4907 Successors.Release;
4274 Successors.Locked := True; 4908 Successors.Locked := True;
4275 Inlined.Release; 4909 Inlined.Release;