aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/exp_ch6.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/exp_ch6.adb')
-rw-r--r--gcc/ada/exp_ch6.adb261
1 files changed, 126 insertions, 135 deletions
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index f95841e..fb91924 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -674,6 +674,131 @@ package body Exp_Ch6 is
return Extra_Formal;
end Build_In_Place_Formal;
+ -------------------------------
+ -- Build_Procedure_Body_Form --
+ -------------------------------
+
+ function Build_Procedure_Body_Form
+ (Func_Id : Entity_Id;
+ Func_Body : Node_Id) return Node_Id
+ is
+ Loc : constant Source_Ptr := Sloc (Func_Body);
+
+ Proc_Decl : constant Node_Id :=
+ Next (Unit_Declaration_Node (Func_Id));
+ -- It is assumed that the next node following the declaration of the
+ -- corresponding subprogram spec is the declaration of the procedure
+ -- form.
+
+ Proc_Id : constant Entity_Id := Defining_Entity (Proc_Decl);
+
+ procedure Replace_Returns (Param_Id : Entity_Id; Stmts : List_Id);
+ -- Replace each return statement found in the list Stmts with an
+ -- assignment of the return expression to parameter Param_Id.
+
+ ---------------------
+ -- Replace_Returns --
+ ---------------------
+
+ procedure Replace_Returns (Param_Id : Entity_Id; Stmts : List_Id) is
+ Stmt : Node_Id;
+
+ begin
+ Stmt := First (Stmts);
+ while Present (Stmt) loop
+ if Nkind (Stmt) = N_Block_Statement then
+ Replace_Returns (Param_Id, Statements (Stmt));
+
+ elsif Nkind (Stmt) = N_Case_Statement then
+ declare
+ Alt : Node_Id;
+ begin
+ Alt := First (Alternatives (Stmt));
+ while Present (Alt) loop
+ Replace_Returns (Param_Id, Statements (Alt));
+ Next (Alt);
+ end loop;
+ end;
+
+ elsif Nkind (Stmt) = N_If_Statement then
+ Replace_Returns (Param_Id, Then_Statements (Stmt));
+ Replace_Returns (Param_Id, Else_Statements (Stmt));
+
+ declare
+ Part : Node_Id;
+ begin
+ Part := First (Elsif_Parts (Stmt));
+ while Present (Part) loop
+ Replace_Returns (Part, Then_Statements (Part));
+ Next (Part);
+ end loop;
+ end;
+
+ elsif Nkind (Stmt) = N_Loop_Statement then
+ Replace_Returns (Param_Id, Statements (Stmt));
+
+ elsif Nkind (Stmt) = N_Simple_Return_Statement then
+
+ -- Generate:
+ -- Param := Expr;
+ -- return;
+
+ Rewrite (Stmt,
+ Make_Assignment_Statement (Sloc (Stmt),
+ Name => New_Occurrence_Of (Param_Id, Loc),
+ Expression => Relocate_Node (Expression (Stmt))));
+
+ Insert_After (Stmt, Make_Simple_Return_Statement (Loc));
+
+ -- Skip the added return
+
+ Next (Stmt);
+ end if;
+
+ Next (Stmt);
+ end loop;
+ end Replace_Returns;
+
+ -- Local variables
+
+ Stmts : List_Id;
+ New_Body : Node_Id;
+
+ -- Start of processing for Build_Procedure_Body_Form
+
+ begin
+ -- This routine replaces the original function body:
+
+ -- function F (...) return Array_Typ is
+ -- begin
+ -- ...
+ -- return Something;
+ -- end F;
+
+ -- with the following:
+
+ -- procedure P (..., Result : out Array_Typ) is
+ -- begin
+ -- ...
+ -- Result := Something;
+ -- end P;
+
+ Stmts :=
+ Statements (Handled_Statement_Sequence (Func_Body));
+ Replace_Returns (Last_Entity (Proc_Id), Stmts);
+
+ New_Body :=
+ Make_Subprogram_Body (Loc,
+ Specification =>
+ Copy_Subprogram_Spec (Specification (Proc_Decl)),
+ Declarations => Declarations (Func_Body),
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => Stmts));
+
+ return New_Body;
+ end Build_Procedure_Body_Form;
+
--------------------------------
-- Check_Overriding_Operation --
--------------------------------
@@ -4959,11 +5084,6 @@ package body Exp_Ch6 is
-- returns, since they get eliminated anyway later on. Spec_Id denotes
-- the corresponding spec of the subprogram body.
- procedure Build_Procedure_Body_Form (Func_Id : Entity_Id);
- -- Create a procedure body which emulates the behavior of function
- -- Func_Id. This body replaces the original function body, which is
- -- not needed for the C program.
-
----------------
-- Add_Return --
----------------
@@ -5036,125 +5156,7 @@ package body Exp_Ch6 is
end if;
end Add_Return;
- -------------------------------
- -- Build_Procedure_Body_Form --
- -------------------------------
-
- procedure Build_Procedure_Body_Form (Func_Id : Entity_Id) is
- Proc_Decl : constant Node_Id :=
- Next (Unit_Declaration_Node (Func_Id));
- -- It is assumed that the next node following the declaration of the
- -- corresponding subprogram spec is the declaration of the procedure
- -- form.
-
- Proc_Id : constant Entity_Id := Defining_Entity (Proc_Decl);
-
- procedure Replace_Returns (Param_Id : Entity_Id; Stmts : List_Id);
- -- Replace each return statement found in the list Stmts with an
- -- assignment of the return expression to parameter Param_Id.
-
- ---------------------
- -- Replace_Returns --
- ---------------------
-
- procedure Replace_Returns (Param_Id : Entity_Id; Stmts : List_Id) is
- Stmt : Node_Id;
-
- begin
- Stmt := First (Stmts);
- while Present (Stmt) loop
- if Nkind (Stmt) = N_Block_Statement then
- Replace_Returns (Param_Id, Statements (Stmt));
-
- elsif Nkind (Stmt) = N_Case_Statement then
- declare
- Alt : Node_Id;
- begin
- Alt := First (Alternatives (Stmt));
- while Present (Alt) loop
- Replace_Returns (Param_Id, Statements (Alt));
- Next (Alt);
- end loop;
- end;
-
- elsif Nkind (Stmt) = N_If_Statement then
- Replace_Returns (Param_Id, Then_Statements (Stmt));
- Replace_Returns (Param_Id, Else_Statements (Stmt));
-
- declare
- Part : Node_Id;
- begin
- Part := First (Elsif_Parts (Stmt));
- while Present (Part) loop
- Replace_Returns (Part, Then_Statements (Part));
- Next (Part);
- end loop;
- end;
-
- elsif Nkind (Stmt) = N_Loop_Statement then
- Replace_Returns (Param_Id, Statements (Stmt));
-
- elsif Nkind (Stmt) = N_Simple_Return_Statement then
-
- -- Generate:
- -- Param := Expr;
- -- return;
-
- Rewrite (Stmt,
- Make_Assignment_Statement (Sloc (Stmt),
- Name => New_Occurrence_Of (Param_Id, Loc),
- Expression => Relocate_Node (Expression (Stmt))));
-
- Insert_After (Stmt, Make_Simple_Return_Statement (Loc));
-
- -- Skip the added return
-
- Next (Stmt);
- end if;
-
- Next (Stmt);
- end loop;
- end Replace_Returns;
-
- -- Local variables
-
- Stmts : List_Id;
-
- -- Start of processing for Build_Procedure_Body_Form
-
- begin
- -- This routine replaces the original function body:
-
- -- function F (...) return Array_Typ is
- -- begin
- -- ...
- -- return Something;
- -- end F;
-
- -- with the following:
-
- -- procedure P (..., Result : out Array_Typ) is
- -- begin
- -- ...
- -- Result := Something;
- -- end P;
-
- Stmts := Statements (HSS);
- Replace_Returns (Last_Entity (Proc_Id), Stmts);
-
- Replace (N,
- Make_Subprogram_Body (Loc,
- Specification =>
- Copy_Subprogram_Spec (Specification (Proc_Decl)),
- Declarations => Declarations (N),
- Handled_Statement_Sequence =>
- Make_Handled_Sequence_Of_Statements (Loc,
- Statements => Stmts)));
-
- Analyze (N);
- end Build_Procedure_Body_Form;
-
- -- Local varaibles
+ -- Local variables
Save_Ghost_Mode : constant Ghost_Mode_Type := Ghost_Mode;
@@ -5452,17 +5454,6 @@ package body Exp_Ch6 is
Unest_Bodies.Append ((Spec_Id, N));
end if;
- -- When generating C code, transform a function that returns a
- -- constrained array type into a procedure with an out parameter
- -- that carries the return value.
-
- if Modify_Tree_For_C
- and then Ekind (Spec_Id) = E_Function
- and then Rewritten_For_C (Spec_Id)
- then
- Build_Procedure_Body_Form (Spec_Id);
- end if;
-
Ghost_Mode := Save_Ghost_Mode;
end Expand_N_Subprogram_Body;