-- Local subprograms --
-----------------------
- function Whole_Object_Ref (Ref : Node_Id) return Node_Id;
- -- For a name that denotes an object, returns a name that denotes the whole
- -- object, declared by an object declaration, formal parameter declaration,
- -- etc. For example, for P.X.Comp (J), if P is a package X is a record
- -- object, this returns P.X.
-
function Ghost_Entity (Ref : Node_Id) return Entity_Id;
pragma Inline (Ghost_Entity);
-- Obtain the entity of a Ghost entity from reference Ref. Return Empty if
Formal : Entity_Id;
Is_Default : Boolean := False)
is
- Actual_Obj : constant Entity_Id := Get_Enclosing_Deep_Object (Actual);
+ Actual_Obj : constant Entity_Id := Get_Enclosing_Ghost_Object (Actual);
begin
if not Is_Ghost_Entity (Formal) then
return;
-- entity.
if Nkind (N) = N_Assignment_Statement then
- Id := Ghost_Entity (Name (N));
+ Id := Get_Enclosing_Ghost_Object (Name (N));
return Present (Id) and then Is_Ghost_Entity (Id);
end if;
end if;
declare
- Whole : constant Node_Id := Whole_Object_Ref (Lhs);
- Id : Entity_Id;
+ Id : constant Entity_Id := Get_Enclosing_Ghost_Object (Lhs);
begin
- if Is_Entity_Name (Whole) then
- Id := Entity (Whole);
+ if Present (Id) then
+ -- Left-hand side denotes a Checked ghost entity, so install
+ -- the region.
- if Present (Id) then
- -- Left-hand side denotes a Checked ghost entity, so
- -- install the region.
+ if Is_Checked_Ghost_Entity (Id) then
+ Install_Ghost_Region (Check, N);
- if Is_Checked_Ghost_Entity (Id) then
- Install_Ghost_Region (Check, N);
+ -- Left-hand side denotes an Ignored ghost entity, so
+ -- install the region, and mark the assignment statement as
+ -- an ignored ghost assignment, so it will be removed later.
- -- Left-hand side denotes an Ignored ghost entity, so
- -- install the region, and mark the assignment statement
- -- as an ignored ghost assignment, so it will be removed
- -- later.
-
- elsif Is_Ignored_Ghost_Entity (Id) then
- Install_Ghost_Region (Ignore, N);
- Set_Is_Ignored_Ghost_Node (N);
- Record_Ignored_Ghost_Node (N);
- end if;
+ elsif Is_Ignored_Ghost_Entity (Id) then
+ Install_Ghost_Region (Ignore, N);
+ Set_Is_Ignored_Ghost_Node (N);
+ Record_Ignored_Ghost_Node (N);
end if;
end if;
end;
end if;
end Set_Is_Ghost_Entity;
- ----------------------
- -- Whole_Object_Ref --
- ----------------------
-
- function Whole_Object_Ref (Ref : Node_Id) return Node_Id is
- begin
- if Nkind (Ref) in N_Indexed_Component | N_Slice
- or else (Nkind (Ref) = N_Selected_Component
- and then Is_Object_Reference (Prefix (Ref)))
- then
- if Is_Access_Type (Etype (Prefix (Ref))) then
- return Ref;
- else
- return Whole_Object_Ref (Prefix (Ref));
- end if;
- else
- return Ref;
- end if;
- end Whole_Object_Ref;
-
end Ghost;
end if;
end Get_Enclosing_Object;
- -------------------------------
- -- Get_Enclosing_Deep_Object --
- -------------------------------
+ --------------------------------
+ -- Get_Enclosing_Ghost_Object --
+ --------------------------------
- function Get_Enclosing_Deep_Object (N : Node_Id) return Entity_Id is
+ function Get_Enclosing_Ghost_Object (N : Node_Id) return Entity_Id is
begin
if Is_Entity_Name (N) then
return Entity (N);
else
case Nkind (N) is
- when N_Explicit_Dereference
+ when N_Attribute_Reference
+ | N_Explicit_Dereference
| N_Indexed_Component
| N_Selected_Component
| N_Slice
=>
- return Get_Enclosing_Deep_Object (Prefix (N));
+ return Get_Enclosing_Ghost_Object (Prefix (N));
- when N_Type_Conversion =>
- return Get_Enclosing_Deep_Object (Expression (N));
+ when N_Function_Call =>
+ return Get_Called_Entity (N);
+
+ -- We are interested in the target type, because if it is ghost,
+ -- then the object is ghost as well and if it is non-ghost, then
+ -- its expression can't be ghost.
+
+ when N_Qualified_Expression
+ | N_Type_Conversion
+ | N_Unchecked_Type_Conversion
+ =>
+ return Entity (Subtype_Mark (N));
when others =>
return Empty;
end case;
end if;
- end Get_Enclosing_Deep_Object;
+ end Get_Enclosing_Ghost_Object;
---------------------------
-- Get_Enum_Lit_From_Pos --
-- If expression N references a part of an object, return this object.
-- Otherwise return Empty. Expression N should have been resolved already.
- function Get_Enclosing_Deep_Object (N : Node_Id) return Entity_Id;
+ function Get_Enclosing_Ghost_Object (N : Node_Id) return Entity_Id;
-- If expression N references a reachable part of an object (as defined in
-- SPARK RM 6.9), return this object. Otherwise return Empty. It is similar
-- to Get_Enclosing_Object, but treats pointer dereference like component
- -- selection. Expression N should have been resolved already.
+ -- selection. Also, it handles function results and type conversions like
+ -- objects. Expression N should have been resolved already.
function Get_Generic_Entity (N : Node_Id) return Entity_Id;
-- Returns the true generic entity in an instantiation. If the name in the