aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/exp_util.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/exp_util.adb')
-rw-r--r--gcc/ada/exp_util.adb183
1 files changed, 81 insertions, 102 deletions
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 807afb2..7c36666 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -1270,11 +1270,10 @@ package body Exp_Util is
---------------------------------
procedure Build_Class_Wide_Expression
- (Prag : Node_Id;
- Subp : Entity_Id;
- Par_Subp : Entity_Id;
- Adjust_Sloc : Boolean;
- Needs_Wrapper : out Boolean)
+ (Pragma_Or_Expr : Node_Id;
+ Subp : Entity_Id;
+ Par_Subp : Entity_Id;
+ Adjust_Sloc : Boolean)
is
function Replace_Entity (N : Node_Id) return Traverse_Result;
-- Replace reference to formal of inherited operation or to primitive
@@ -1319,84 +1318,6 @@ package body Exp_Util is
if Present (New_E) then
Rewrite (N, New_Occurrence_Of (New_E, Sloc (N)));
-
- -- AI12-0166: a precondition for a protected operation
- -- cannot include an internal call to a protected function
- -- of the type. In the case of an inherited condition for an
- -- overriding operation, both the operation and the function
- -- are given by primitive wrappers.
- -- Move this check to sem???
-
- if Ekind (New_E) = E_Function
- and then Is_Primitive_Wrapper (New_E)
- and then Is_Primitive_Wrapper (Subp)
- and then Scope (Subp) = Scope (New_E)
- and then Chars (Pragma_Identifier (Prag)) = Name_Precondition
- then
- Error_Msg_Node_2 := Wrapped_Entity (Subp);
- Error_Msg_NE
- ("internal call to& cannot appear in inherited "
- & "precondition of protected operation&",
- N, Wrapped_Entity (New_E));
- end if;
-
- -- If the entity is an overridden primitive and we are not
- -- in GNATprove mode, we must build a wrapper for the current
- -- inherited operation. If the reference is the prefix of an
- -- attribute such as 'Result (or others ???) there is no need
- -- for a wrapper: the condition is just rewritten in terms of
- -- the inherited subprogram.
-
- if Is_Subprogram (New_E)
- and then Nkind (Parent (N)) /= N_Attribute_Reference
- and then not GNATprove_Mode
- then
- Needs_Wrapper := True;
- end if;
- end if;
-
- -- Check that there are no calls left to abstract operations if
- -- the current subprogram is not abstract.
- -- Move this check to sem???
-
- if Nkind (Parent (N)) = N_Function_Call
- and then N = Name (Parent (N))
- then
- if not Is_Abstract_Subprogram (Subp)
- and then Is_Abstract_Subprogram (Entity (N))
- then
- Error_Msg_Sloc := Sloc (Current_Scope);
- Error_Msg_Node_2 := Subp;
- if Comes_From_Source (Subp) then
- Error_Msg_NE
- ("cannot call abstract subprogram & in inherited "
- & "condition for&#", Subp, Entity (N));
- else
- Error_Msg_NE
- ("cannot call abstract subprogram & in inherited "
- & "condition for inherited&#", Subp, Entity (N));
- end if;
-
- -- In SPARK mode, reject an inherited condition for an
- -- inherited operation if it contains a call to an overriding
- -- operation, because this implies that the pre/postconditions
- -- of the inherited operation have changed silently.
-
- elsif SPARK_Mode = On
- and then Warn_On_Suspicious_Contract
- and then Present (Alias (Subp))
- and then Present (New_E)
- and then Comes_From_Source (New_E)
- then
- Error_Msg_N
- ("cannot modify inherited condition (SPARK RM 6.1.1(1))",
- Parent (Subp));
- Error_Msg_Sloc := Sloc (New_E);
- Error_Msg_Node_2 := Subp;
- Error_Msg_NE
- ("\overriding of&# forces overriding of&",
- Parent (Subp), New_E);
- end if;
end if;
-- Update type of function call node, which should be the same as
@@ -1422,26 +1343,17 @@ package body Exp_Util is
-- Local variables
- Par_Formal : Entity_Id;
- Subp_Formal : Entity_Id;
+ Par_Typ : constant Entity_Id := Find_Dispatching_Type (Par_Subp);
+ Subp_Typ : constant Entity_Id := Find_Dispatching_Type (Subp);
-- Start of processing for Build_Class_Wide_Expression
begin
- Needs_Wrapper := False;
-
- -- Add mapping from old formals to new formals
+ pragma Assert (Par_Typ /= Subp_Typ);
- Par_Formal := First_Formal (Par_Subp);
- Subp_Formal := First_Formal (Subp);
-
- while Present (Par_Formal) and then Present (Subp_Formal) loop
- Type_Map.Set (Par_Formal, Subp_Formal);
- Next_Formal (Par_Formal);
- Next_Formal (Subp_Formal);
- end loop;
-
- Replace_Condition_Entities (Prag);
+ Update_Primitives_Mapping (Par_Subp, Subp);
+ Map_Formals (Par_Subp, Subp);
+ Replace_Condition_Entities (Pragma_Or_Expr);
end Build_Class_Wide_Expression;
--------------------
@@ -1895,7 +1807,33 @@ package body Exp_Util is
Priv_Typ : Entity_Id;
-- The partial view of Par_Typ
+ Op_Node : Elmt_Id;
+ Par_Prim : Entity_Id;
+ Prim : Entity_Id;
+
begin
+ -- Map the overridden primitive to the overriding one; required by
+ -- Replace_References (called by Add_Inherited_DICs) to handle calls
+ -- to parent primitives.
+
+ Op_Node := First_Elmt (Primitive_Operations (T));
+ while Present (Op_Node) loop
+ Prim := Node (Op_Node);
+
+ if Present (Overridden_Operation (Prim))
+ and then Comes_From_Source (Prim)
+ then
+ Par_Prim := Overridden_Operation (Prim);
+
+ -- Create a mapping of the form:
+ -- parent type primitive -> derived type primitive
+
+ Type_Map.Set (Par_Prim, Prim);
+ end if;
+
+ Next_Elmt (Op_Node);
+ end loop;
+
-- Climb the parent type chain
Curr_Typ := T;
@@ -7073,6 +7011,15 @@ package body Exp_Util is
return Etype (Indx);
end Get_Index_Subtype;
+ -----------------------
+ -- Get_Mapped_Entity --
+ -----------------------
+
+ function Get_Mapped_Entity (E : Entity_Id) return Entity_Id is
+ begin
+ return Type_Map.Get (E);
+ end Get_Mapped_Entity;
+
---------------------
-- Get_Stream_Size --
---------------------
@@ -10350,6 +10297,36 @@ package body Exp_Util is
end if;
end Make_Variant_Comparison;
+ -----------------
+ -- Map_Formals --
+ -----------------
+
+ procedure Map_Formals
+ (Parent_Subp : Entity_Id;
+ Derived_Subp : Entity_Id;
+ Force_Update : Boolean := False)
+ is
+ Par_Formal : Entity_Id := First_Formal (Parent_Subp);
+ Subp_Formal : Entity_Id := First_Formal (Derived_Subp);
+
+ begin
+ if Force_Update then
+ Type_Map.Set (Parent_Subp, Derived_Subp);
+ end if;
+
+ -- At this stage either we are under regular processing and the caller
+ -- has previously ensured that these primitives are already mapped (by
+ -- means of calling previously to Update_Primitives_Mapping), or we are
+ -- processing a late-overriding primitive and Force_Update updated above
+ -- the mapping of these primitives.
+
+ while Present (Par_Formal) and then Present (Subp_Formal) loop
+ Type_Map.Set (Par_Formal, Subp_Formal);
+ Next_Formal (Par_Formal);
+ Next_Formal (Subp_Formal);
+ end loop;
+ end Map_Formals;
+
---------------
-- Map_Types --
---------------
@@ -10861,7 +10838,7 @@ package body Exp_Util is
-- they relate to the primitives of the parent type. If there is a
-- meaningful relation, create a mapping of the form:
- -- parent type primitive -> perived type primitive
+ -- parent type primitive -> derived type primitive
if Present (Direct_Primitive_Operations (Deriv_Typ)) then
Prim_Elmt := First_Elmt (Direct_Primitive_Operations (Deriv_Typ));
@@ -14123,10 +14100,12 @@ package body Exp_Util is
(Inher_Id : Entity_Id;
Subp_Id : Entity_Id)
is
+ Parent_Type : constant Entity_Id := Find_Dispatching_Type (Inher_Id);
+ Derived_Type : constant Entity_Id := Find_Dispatching_Type (Subp_Id);
+
begin
- Map_Types
- (Parent_Type => Find_Dispatching_Type (Inher_Id),
- Derived_Type => Find_Dispatching_Type (Subp_Id));
+ pragma Assert (Parent_Type /= Derived_Type);
+ Map_Types (Parent_Type, Derived_Type);
end Update_Primitives_Mapping;
----------------------------------