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
+ Proc_Decl : constant Node_Id := Prev (Unit_Declaration_Node (Func_Id));
+ -- It is assumed that the node before the declaration of the
-- corresponding subprogram spec is the declaration of the procedure
-- form.
Prot_Bod : Node_Id;
Prot_Decl : Node_Id;
Prot_Id : Entity_Id;
+ Typ : Entity_Id;
begin
-- Deal with case of protected subprogram. Do not generate protected
-- are not needed by the C generator (and this also produces cleaner
-- output).
+ Typ := Get_Fullest_View (Etype (Subp));
+
if Transform_Function_Array
and then Nkind (Specification (N)) = N_Function_Specification
- and then Is_Array_Type (Etype (Subp))
- and then Is_Constrained (Etype (Subp))
+ and then Is_Array_Type (Typ)
+ and then Is_Constrained (Typ)
and then not Is_Unchecked_Conversion_Instance (Subp)
then
Build_Procedure_Form (N);
-----------------------
function Needs_Fat_Pointer (E : Entity_Id) return Boolean is
- Typ : Entity_Id := Etype (E);
-
+ Typ : constant Entity_Id := Get_Fullest_View (Etype (E));
begin
- if Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
- Typ := Full_View (Typ);
- end if;
-
return Is_Array_Type (Typ) and then not Is_Constrained (Typ);
end Needs_Fat_Pointer;
DT : Boolean := False;
Formal : Node_Id;
Subp : Entity_Id;
+ F_Type : Entity_Id;
+ A_Type : Entity_Id;
begin
if Nkind (Name (N)) = N_Explicit_Dereference then
Actual := First_Actual (N);
Formal := First_Formal_With_Extras (Subp);
+
while Present (Actual) loop
- if Is_Array_Type (Etype (Formal))
- and then not Is_Constrained (Etype (Formal))
- and then Is_Constrained (Etype (Actual))
+ F_Type := Get_Fullest_View (Etype (Formal));
+ A_Type := Get_Fullest_View (Etype (Actual));
+
+ if Is_Array_Type (F_Type)
+ and then not Is_Constrained (F_Type)
+ and then Is_Constrained (A_Type)
then
- Check_Static_Type (Etype (Actual), Empty, DT);
+ Check_Static_Type (A_Type, Empty, DT);
end if;
Next_Actual (Actual);
Out_Present => True,
Parameter_Type => New_Occurrence_Of (Etype (Subp), Loc)));
- -- The new procedure declaration is inserted immediately after the
- -- function declaration. The processing in Build_Procedure_Body_Form
- -- relies on this order.
+ -- The new procedure declaration is inserted before the function
+ -- declaration. The processing in Build_Procedure_Body_Form relies on
+ -- this order. Note that we insert before because in the case of a
+ -- function body with no separate spec, we do not want to insert the
+ -- new spec after the body which will later get rewritten.
Proc_Decl :=
Make_Subprogram_Declaration (Loc,
Make_Defining_Identifier (Loc, Chars (Subp)),
Parameter_Specifications => Proc_Formals));
- Insert_After_And_Analyze (Unit_Declaration_Node (Subp), Proc_Decl);
+ Insert_Before_And_Analyze (Unit_Declaration_Node (Subp), Proc_Decl);
-- Entity of procedure must remain invisible so that it does not
-- overload subsequent references to the original function.
Check_Overriding_Indicator (E, Empty, Is_Primitive (E));
end if;
+ Retype := Get_Fullest_View (Etype (E));
+
if Transform_Function_Array
and then Nkind (Parent (E)) = N_Function_Specification
- and then Is_Array_Type (Etype (E))
- and then Is_Constrained (Etype (E))
+ and then Is_Array_Type (Retype)
+ and then Is_Constrained (Retype)
and then not Is_Unchecked_Conversion_Instance (E)
and then not Rewritten_For_C (E)
then
if Expander_Active
and then Transform_Function_Array
- and then Present (Spec_Id)
- and then Ekind (Spec_Id) = E_Function
and then Nkind (N) /= N_Subprogram_Body_Stub
- and then Rewritten_For_C (Spec_Id)
then
- Set_Has_Completion (Spec_Id);
+ declare
+ S : constant Entity_Id :=
+ (if Present (Spec_Id)
+ then Spec_Id
+ else Defining_Unit_Name (Specification (N)));
+ Proc_Body : Node_Id;
- Rewrite (N, Build_Procedure_Body_Form (Spec_Id, N));
- Analyze (N);
+ begin
+ if Ekind (S) = E_Function and then Rewritten_For_C (S) then
+ Set_Has_Completion (S);
+ Proc_Body := Build_Procedure_Body_Form (S, N);
- -- The entity for the created procedure must remain invisible, so it
- -- does not participate in resolution of subsequent references to the
- -- function.
+ if Present (Spec_Id) then
+ Rewrite (N, Proc_Body);
+ Analyze (N);
- Set_Is_Immediately_Visible (Corresponding_Spec (N), False);
- goto Leave;
+ -- The entity for the created procedure must remain
+ -- invisible, so it does not participate in resolution of
+ -- subsequent references to the function.
+
+ Set_Is_Immediately_Visible (Corresponding_Spec (N), False);
+
+ -- If we do not have a separate spec for N, build one and
+ -- insert the new body right after.
+
+ else
+ Rewrite (N,
+ Make_Subprogram_Declaration (Loc,
+ Specification => Relocate_Node (Specification (N))));
+ Analyze (N);
+ Insert_After_And_Analyze (N, Proc_Body);
+ Set_Is_Immediately_Visible
+ (Corresponding_Spec (Proc_Body), False);
+ end if;
+
+ goto Leave;
+ end if;
+ end;
end if;
-- If a separate spec is present, then deal with freezing issues
function Get_Fullest_View
(E : Entity_Id; Include_PAT : Boolean := True) return Entity_Id is
begin
+ -- Prevent cascaded errors
+
+ if No (E) then
+ return E;
+ end if;
+
-- Strictly speaking, the recursion below isn't necessary, but
-- it's both simplest and safest.