This patch fixes a few minor glitches that yield small irregularities in the
expanded code handed down to gigi, for example the declaration of subprograms
before that of the type of their parameters, types that are neither regular
nor Itypes, or return types with circularities. No functional change.
Tested on x86_64-suse-linux, applied on the mainline.
2016-06-06 Eric Botcazou <ebotca...@adacore.com>
* exp_ch9.adb (Expand_N_Protected_Type_Declaration): Insert the
declaration of the corresponding record type before that of the
unprotected version of the subprograms that operate on it.
(Expand_Access_Protected_Subprogram_Type): Declare the
Equivalent_Type just before the original type.
* sem_ch3.adb (Handle_Late_Controlled_Primitive): Point the current
declaration to the newly created declaration for the primitive.
(Analyze_Subtype_Declaration): Remove obsolete code forcing the
freezing of the subtype before its declaration.
(Replace_Anonymous_Access_To_Protected_Subprogram): Insert the new
declaration in the nearest enclosing scope for formal parameters too.
(Build_Derived_Access_Type): Restore the status of the created Itype
after it is erased by Copy_Node.
* sem_ch6.adb (Exchange_Limited_Views): Remove guard on entry.
(Analyze_Subprogram_Body_Helper): Call Exchange_Limited_Views only if
the specification is present.
Move around the code changing the designated view of the return type
and save the original view. Restore it on exit.
* sem_ch13.adb (Build_Predicate_Function_Declaration): Always insert
the declaration right after that of the type.
--
Eric Botcazou
Index: exp_ch9.adb
===================================================================
--- exp_ch9.adb (revision 237088)
+++ exp_ch9.adb (working copy)
@@ -6257,7 +6257,10 @@ package body Exp_Ch9 is
Defining_Identifier => D_T2,
Type_Definition => Def1);
- Insert_After_And_Analyze (N, Decl1);
+ -- Declare the new types before the original one since the latter will
+ -- refer to them through the Equivalent_Type slot.
+
+ Insert_Before_And_Analyze (N, Decl1);
-- Associate the access to subprogram with its original access to
-- protected subprogram type. Needed by the backend to know that this
@@ -6292,7 +6295,7 @@ package body Exp_Ch9 is
Component_List =>
Make_Component_List (Loc, Component_Items => Comps)));
- Insert_After_And_Analyze (Decl1, Decl2);
+ Insert_Before_And_Analyze (N, Decl2);
Set_Equivalent_Type (T, E_T);
end Expand_Access_Protected_Subprogram_Type;
@@ -9316,6 +9319,9 @@ package body Exp_Ch9 is
pragma Assert (Present (Pdef));
+ Insert_After (Current_Node, Rec_Decl);
+ Current_Node := Rec_Decl;
+
-- Add private field components
if Present (Private_Declarations (Pdef)) then
@@ -9576,9 +9582,6 @@ package body Exp_Ch9 is
Append_To (Cdecls, Object_Comp);
end if;
- Insert_After (Current_Node, Rec_Decl);
- Current_Node := Rec_Decl;
-
-- Analyze the record declaration immediately after construction,
-- because the initialization procedure is needed for single object
-- declarations before the next entity is analyzed (the freeze call
Index: sem_ch13.adb
===================================================================
--- sem_ch13.adb (revision 237088)
+++ sem_ch13.adb (working copy)
@@ -9386,11 +9386,7 @@ package body Sem_Ch13 is
Set_Is_Predicate_Function (SId);
Set_Predicate_Function (Typ, SId);
- if Comes_From_Source (Typ) then
- Insert_After (Parent (Typ), FDecl);
- else
- Insert_After (Parent (Base_Type (Typ)), FDecl);
- end if;
+ Insert_After (Parent (Typ), FDecl);
Analyze (FDecl);
Index: sem_ch3.adb
===================================================================
--- sem_ch3.adb (revision 237088)
+++ sem_ch3.adb (working copy)
@@ -2168,7 +2168,7 @@ package body Sem_Ch3 is
-- Determine whether Body_Decl denotes the body of a late controlled
-- primitive (either Initialize, Adjust or Finalize). If this is the
-- case, add a proper spec if the body lacks one. The spec is inserted
- -- before Body_Decl and immedately analyzed.
+ -- before Body_Decl and immediately analyzed.
procedure Remove_Visible_Refinements (Spec_Id : Entity_Id);
-- Spec_Id is the entity of a package that may define abstract states.
@@ -2269,8 +2269,12 @@ package body Sem_Ch3 is
Set_Null_Present (Spec, False);
- Insert_Before_And_Analyze (Body_Decl,
- Make_Subprogram_Declaration (Loc, Specification => Spec));
+ -- Ensure that the freeze node is inserted after the declaration of
+ -- the primitive since its expansion will freeze the primitive.
+
+ Decl := Make_Subprogram_Declaration (Loc, Specification => Spec);
+
+ Insert_Before_And_Analyze (Body_Decl, Decl);
end Handle_Late_Controlled_Primitive;
--------------------------------
@@ -5246,20 +5250,6 @@ package body Sem_Ch3 is
Set_Invariant_Procedure (Id, Invariant_Procedure (T));
end if;
- -- Make sure that generic actual types are properly frozen. The subtype
- -- is marked as a generic actual type when the enclosing instance is
- -- analyzed, so here we identify the subtype from the tree structure.
-
- if Expander_Active
- and then Is_Generic_Actual_Type (Id)
- and then In_Instance
- and then not Comes_From_Source (N)
- and then Nkind (Subtype_Indication (N)) /= N_Subtype_Indication
- and then Is_Frozen (T)
- then
- Freeze_Before (N, Id);
- end if;
-
Set_Optimize_Alignment_Flags (Id);
Check_Eliminated (Id);
@@ -5851,15 +5841,20 @@ package body Sem_Ch3 is
end if;
-- Insert the new declaration in the nearest enclosing scope. If the
- -- node is a body and N is its return type, the declaration belongs in
- -- the enclosing scope.
+ -- parent is a body and N is its return type, the declaration belongs
+ -- in the enclosing scope. Likewise if N is the type of a parameter.
P := Parent (N);
- if Nkind (P) = N_Subprogram_Body
- and then Nkind (N) = N_Function_Specification
+ if Nkind (N) = N_Function_Specification
+ and then Nkind (P) = N_Subprogram_Body
then
P := Parent (P);
+ elsif Nkind (N) = N_Parameter_Specification
+ and then Nkind (P) in N_Subprogram_Specification
+ and then Nkind (Parent (P)) = N_Subprogram_Body
+ then
+ P := Parent (Parent (P));
end if;
while Present (P) and then not Has_Declarations (P) loop
@@ -5974,6 +5969,11 @@ package body Sem_Ch3 is
begin
Copy_Node (Pbase, Ibase);
+ -- Restore Itype status after Copy_Node
+
+ Set_Is_Itype (Ibase);
+ Set_Associated_Node_For_Itype (Ibase, N);
+
Set_Chars (Ibase, Svg_Chars);
Set_Next_Entity (Ibase, Svg_Next_E);
Set_Sloc (Ibase, Sloc (Derived_Type));
Index: sem_ch6.adb
===================================================================
--- sem_ch6.adb (revision 237088)
+++ sem_ch6.adb (working copy)
@@ -2149,6 +2149,7 @@ package body Sem_Ch6 is
Body_Id : Entity_Id := Defining_Entity (Body_Spec);
Prev_Id : constant Entity_Id := Current_Entity_In_Scope (Body_Id);
Exch_Views : Elist_Id := No_Elist;
+ Desig_View : Entity_Id := Empty;
Conformant : Boolean;
HSS : Node_Id;
Prot_Typ : Entity_Id := Empty;
@@ -2914,13 +2915,10 @@ package body Sem_Ch6 is
-- Start of processing for Exchange_Limited_Views
begin
- if No (Subp_Id) then
- return No_Elist;
-
-- Do not process subprogram bodies as they already use the non-
-- limited view of types.
- elsif not Ekind_In (Subp_Id, E_Function, E_Procedure) then
+ if not Ekind_In (Subp_Id, E_Function, E_Procedure) then
return No_Elist;
end if;
@@ -3665,31 +3663,6 @@ package body Sem_Ch6 is
Set_SPARK_Pragma_Inherited (Body_Id);
end if;
- -- If the return type is an anonymous access type whose designated type
- -- is the limited view of a class-wide type and the non-limited view is
- -- available, update the return type accordingly.
-
- if Ada_Version >= Ada_2005 and then Comes_From_Source (N) then
- declare
- Etyp : Entity_Id;
- Rtyp : Entity_Id;
-
- begin
- Rtyp := Etype (Current_Scope);
-
- if Ekind (Rtyp) = E_Anonymous_Access_Type then
- Etyp := Directly_Designated_Type (Rtyp);
-
- if Is_Class_Wide_Type (Etyp)
- and then From_Limited_With (Etyp)
- then
- Set_Directly_Designated_Type
- (Etype (Current_Scope), Available_View (Etyp));
- end if;
- end if;
- end;
- end if;
-
-- If this is the proper body of a stub, we must verify that the stub
-- conforms to the body, and to the previous spec if one was present.
-- We know already that the body conforms to that spec. This test is
@@ -3918,10 +3891,35 @@ package body Sem_Ch6 is
-- of a subprogram body may use the parameter and result profile of the
-- spec, swap any limited views with their non-limited counterpart.
- if Ada_Version >= Ada_2012 then
+ if Ada_Version >= Ada_2012 and then Present (Spec_Id) then
Exch_Views := Exchange_Limited_Views (Spec_Id);
end if;
+ -- If the return type is an anonymous access type whose designated type
+ -- is the limited view of a class-wide type and the non-limited view is
+ -- available, update the return type accordingly.
+
+ if Ada_Version >= Ada_2005 and then Present (Spec_Id) then
+ declare
+ Etyp : Entity_Id;
+ Rtyp : Entity_Id;
+
+ begin
+ Rtyp := Etype (Spec_Id);
+
+ if Ekind (Rtyp) = E_Anonymous_Access_Type then
+ Etyp := Directly_Designated_Type (Rtyp);
+
+ if Is_Class_Wide_Type (Etyp)
+ and then From_Limited_With (Etyp)
+ then
+ Desig_View := Etyp;
+ Set_Directly_Designated_Type (Rtyp, Available_View (Etyp));
+ end if;
+ end if;
+ end;
+ end if;
+
-- Analyze any aspect specifications that appear on the subprogram body
if Has_Aspects (N) then
@@ -4191,6 +4189,10 @@ package body Sem_Ch6 is
Restore_Limited_Views (Exch_Views);
end if;
+ if Present (Desig_View) then
+ Set_Directly_Designated_Type (Etype (Spec_Id), Desig_View);
+ end if;
+
Ghost_Mode := Save_Ghost_Mode;
end Analyze_Subprogram_Body_Helper;