From: Ronan Desplanques <[email protected]>
This extracts part of the statement sequence of the
Build_And_Insert_Type_Attr_Subp procedure into a helper function. The
intent is to make it easier to tell when the objects declared inside the
procedure are mutated.
gcc/ada/ChangeLog:
* exp_attr.adb (Skip_Non_Source_Subps): Move before local object
declarations and add formals.
(Build): Move before local object declarations.
(Find_Insertion_Point_For_Ancestor): New local function.
(Build_And_Insert_Type_Attr_Subp): Use new function.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/ada/exp_attr.adb | 114 +++++++++++++++++++++++++++----------------
1 file changed, 73 insertions(+), 41 deletions(-)
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 1cd7a325937..aa395999bb0 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -2082,17 +2082,20 @@ package body Exp_Attr is
Subp : out Entity_Id;
Attr_Ref : Node_Id)
is
- Ancestor : Node_Id := Attr_Ref;
- Insertion_Scope : Entity_Id := Empty;
- Insertion_Point : Node_Id := Empty;
- Insert_Before : Boolean := False;
- First_Typ : constant Entity_Id := First_Subtype (Typ);
- Typ_Comp_Unit : Node_Id := Enclosing_Comp_Unit_Node (First_Typ);
procedure Build;
-- Call Build_Type_Attr_Subprogram with appropriate parameters.
- procedure Skip_Non_Source_Subps;
+ function Find_Insertion_Point_For_Ancestor
+ (Ancestor, Previous_Insertion_Point : Node_Id) return Node_Id;
+ -- Return the most appropriate insertion point that's at the same
+ -- depth as Ancestor, if one exists. Otherwise return Empty. Ancestor
+ -- is an ancestor node of the node we want to call the subprogram
+ -- from. Previous_Insertion_Point is the latest insertion point we
+ -- found walking up the tree.
+
+ procedure Skip_Non_Source_Subps
+ (Cursor : in out Node_Id; Ancestor : Node_Id);
-- Refine Insertion_Point choice (see comment inside procedure).
procedure Build is
@@ -2103,7 +2106,45 @@ package body Exp_Attr is
Subp => Subp);
end Build;
- procedure Skip_Non_Source_Subps is
+ function Find_Insertion_Point_For_Ancestor
+ (Ancestor, Previous_Insertion_Point : Node_Id) return Node_Id
+ is
+ Cursor : Node_Id := Empty;
+ begin
+ if Is_List_Member (Ancestor) then
+ Cursor := First (List_Containing (Ancestor));
+ Skip_Non_Source_Subps (Cursor, Ancestor);
+
+ -- A subprogram body usually occurs in a declaration list
+ -- (so we will take the preceding Is_List_Member = True path),
+ -- but not always. For a library unit subprogram, we want an
+ -- insertion point in the subprogram's declaration list
+ -- because later on we may need to see the inserted
+ -- declaration from within the declaration list. In the
+ -- preceding non-library-unit case, this visibility issue is
+ -- dealt with by choosing an insertion point outside of the
+ -- subprogram body, but that's not an option here. So if
+ -- Previous_Insertion_Point is a member of, for example, the
+ -- subprogram's statement list then it needs to be corrected.
+
+ elsif Nkind (Ancestor) = N_Subprogram_Body
+ and then Present (Declarations (Ancestor))
+ and then
+ (No (Previous_Insertion_Point)
+ or else List_Containing (Previous_Insertion_Point) /=
+ Declarations (Ancestor))
+ and then Nkind (Parent (Ancestor)) /= N_Subunit
+ then
+ Cursor := First (Declarations (Ancestor));
+ Skip_Non_Source_Subps (Cursor, Ancestor);
+ end if;
+
+ return Cursor;
+ end Find_Insertion_Point_For_Ancestor;
+
+ procedure Skip_Non_Source_Subps
+ (Cursor : in out Node_Id; Ancestor : Node_Id)
+ is
-- A hazard to avoid is use-before-definition
-- errors that can result when we have two of these
-- subprograms where one calls the other (e.g., given
@@ -2134,16 +2175,25 @@ package body Exp_Attr is
-- sharing and less duplication have been observed, so this
-- is just speculation.
begin
- while Insertion_Point /= Ancestor
- and then Nkind (Insertion_Point) = N_Subprogram_Body
- and then not Comes_From_Source (Insertion_Point)
- and then Present (Next (Insertion_Point))
+ while Cursor /= Ancestor
+ and then Nkind (Cursor) = N_Subprogram_Body
+ and then not Comes_From_Source (Cursor)
+ and then Present (Next (Cursor))
loop
- Next (Insertion_Point);
+ Next (Cursor);
end loop;
- pragma Assert (Present (Insertion_Point));
+ pragma Assert (Present (Cursor));
end Skip_Non_Source_Subps;
+ -- Local variables
+
+ Ancestor : Node_Id := Attr_Ref;
+ Insertion_Scope : Entity_Id := Empty;
+ Insertion_Point : Node_Id := Empty;
+ Insert_Before : Boolean := False;
+ First_Typ : constant Entity_Id := First_Subtype (Typ);
+ Typ_Comp_Unit : Node_Id := Enclosing_Comp_Unit_Node (First_Typ);
+
-- Start of processing for Build_And_Insert_Type_Attr_Subp
begin
@@ -2175,33 +2225,15 @@ package body Exp_Attr is
pragma Assert (Is_Library_Level_Entity (First_Typ));
while Present (Ancestor) loop
- if Is_List_Member (Ancestor) then
- Insertion_Point := First (List_Containing (Ancestor));
- Skip_Non_Source_Subps;
-
- -- A subprogram body usually occurs in a declaration list
- -- (so we will take the preceding Is_List_Member = True path),
- -- but not always. For a library unit subprogram, we want an
- -- insertion point in the subprogram's declaration list
- -- because later on we may need to see the inserted
- -- declaration from within the declaration list. In the
- -- preceding non-library-unit case, this visibility issue is
- -- dealt with by choosing an insertion point outside of the
- -- subprogram body, but that's not an option here. So if
- -- Insertion_Point is currently a member of, for example, the
- -- subprogram's statement list then it needs to be corrected.
-
- elsif Nkind (Ancestor) = N_Subprogram_Body
- and then Present (Declarations (Ancestor))
- and then
- (No (Insertion_Point)
- or else List_Containing (Insertion_Point) /=
- Declarations (Ancestor))
- and then Nkind (Parent (Ancestor)) /= N_Subunit
- then
- Insertion_Point := First (Declarations (Ancestor));
- Skip_Non_Source_Subps;
- end if;
+ declare
+ Res : constant Node_Id :=
+ Find_Insertion_Point_For_Ancestor
+ (Ancestor, Insertion_Point);
+ begin
+ if Present (Res) then
+ Insertion_Point := Res;
+ end if;
+ end;
if Nkind (Ancestor) = N_Subunit then
Ancestor := Corresponding_Stub (Ancestor);
--
2.53.0