1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2014-2015, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with Alloc
; use Alloc
;
27 with Aspects
; use Aspects
;
28 with Atree
; use Atree
;
29 with Einfo
; use Einfo
;
30 with Elists
; use Elists
;
31 with Errout
; use Errout
;
33 with Namet
; use Namet
;
34 with Nlists
; use Nlists
;
35 with Nmake
; use Nmake
;
38 with Sem_Aux
; use Sem_Aux
;
39 with Sem_Eval
; use Sem_Eval
;
40 with Sem_Res
; use Sem_Res
;
41 with Sem_Util
; use Sem_Util
;
42 with Sinfo
; use Sinfo
;
43 with Snames
; use Snames
;
48 -- The following table contains the N_Compilation_Unit node for a unit that
49 -- is either subject to pragma Ghost with policy Ignore or contains ignored
50 -- Ghost code. The table is used in the removal of ignored Ghost code from
53 package Ignored_Ghost_Units
is new Table
.Table
(
54 Table_Component_Type
=> Node_Id
,
55 Table_Index_Type
=> Int
,
57 Table_Initial
=> Alloc
.Ignored_Ghost_Units_Initial
,
58 Table_Increment
=> Alloc
.Ignored_Ghost_Units_Increment
,
59 Table_Name
=> "Ignored_Ghost_Units");
61 -----------------------
62 -- Local Subprograms --
63 -----------------------
65 procedure Propagate_Ignored_Ghost_Code
(N
: Node_Id
);
66 -- Subsidiary to Set_Ghost_Mode_xxx. Signal all enclosing scopes that they
67 -- now contain ignored Ghost code. Add the compilation unit containing N to
68 -- table Ignored_Ghost_Units for post processing.
70 ----------------------------
71 -- Add_Ignored_Ghost_Unit --
72 ----------------------------
74 procedure Add_Ignored_Ghost_Unit
(Unit
: Node_Id
) is
76 pragma Assert
(Nkind
(Unit
) = N_Compilation_Unit
);
78 -- Avoid duplicates in the table as pruning the same unit more than once
79 -- is wasteful. Since ignored Ghost code tends to be grouped up, check
80 -- the contents of the table in reverse.
82 for Index
in reverse Ignored_Ghost_Units
.First
..
83 Ignored_Ghost_Units
.Last
85 -- If the unit is already present in the table, do not add it again
87 if Unit
= Ignored_Ghost_Units
.Table
(Index
) then
92 -- If we get here, then this is the first time the unit is being added
94 Ignored_Ghost_Units
.Append
(Unit
);
95 end Add_Ignored_Ghost_Unit
;
97 ----------------------------
98 -- Check_Ghost_Completion --
99 ----------------------------
101 procedure Check_Ghost_Completion
102 (Partial_View
: Entity_Id
;
103 Full_View
: Entity_Id
)
105 Policy
: constant Name_Id
:= Policy_In_Effect
(Name_Ghost
);
108 -- The Ghost policy in effect at the point of declaration and at the
109 -- point of completion must match (SPARK RM 6.9(15)).
111 if Is_Checked_Ghost_Entity
(Partial_View
)
112 and then Policy
= Name_Ignore
114 Error_Msg_Sloc
:= Sloc
(Full_View
);
116 Error_Msg_N
("incompatible ghost policies in effect", Partial_View
);
117 Error_Msg_N
("\& declared with ghost policy Check", Partial_View
);
118 Error_Msg_N
("\& completed # with ghost policy Ignore", Partial_View
);
120 elsif Is_Ignored_Ghost_Entity
(Partial_View
)
121 and then Policy
= Name_Check
123 Error_Msg_Sloc
:= Sloc
(Full_View
);
125 Error_Msg_N
("incompatible ghost policies in effect", Partial_View
);
126 Error_Msg_N
("\& declared with ghost policy Ignore", Partial_View
);
127 Error_Msg_N
("\& completed # with ghost policy Check", Partial_View
);
129 end Check_Ghost_Completion
;
131 -------------------------
132 -- Check_Ghost_Context --
133 -------------------------
135 procedure Check_Ghost_Context
(Ghost_Id
: Entity_Id
; Ghost_Ref
: Node_Id
) is
136 procedure Check_Ghost_Policy
(Id
: Entity_Id
; Err_N
: Node_Id
);
137 -- Verify that the Ghost policy at the point of declaration of entity Id
138 -- matches the policy at the point of reference. If this is not the case
139 -- emit an error at Err_N.
141 function Is_OK_Ghost_Context
(Context
: Node_Id
) return Boolean;
142 -- Determine whether node Context denotes a Ghost-friendly context where
143 -- a Ghost entity can safely reside.
145 -------------------------
146 -- Is_OK_Ghost_Context --
147 -------------------------
149 function Is_OK_Ghost_Context
(Context
: Node_Id
) return Boolean is
150 function Is_Ghost_Declaration
(Decl
: Node_Id
) return Boolean;
151 -- Determine whether node Decl is a Ghost declaration or appears
152 -- within a Ghost declaration.
154 function Is_Ghost_Statement_Or_Pragma
(N
: Node_Id
) return Boolean;
155 -- Determine whether statement or pragma N is Ghost or appears within
156 -- a Ghost statement or pragma. To qualify as such, N must either
157 -- 1) Occur within a ghost subprogram or package
158 -- 2) Denote a call to a ghost procedure
159 -- 3) Denote an assignment statement whose target is a ghost
161 -- 4) Denote a pragma that mentions a ghost entity
163 --------------------------
164 -- Is_Ghost_Declaration --
165 --------------------------
167 function Is_Ghost_Declaration
(Decl
: Node_Id
) return Boolean is
173 -- Climb the parent chain looking for an object declaration
176 while Present
(Par
) loop
177 if Is_Declaration
(Par
) then
179 -- A declaration is Ghost when it appears within a Ghost
180 -- package or subprogram.
182 if Ghost_Mode
> None
then
185 -- Otherwise the declaration may not have been analyzed yet,
186 -- determine whether it is subject to aspect/pragma Ghost.
189 return Is_Subject_To_Ghost
(Par
);
194 -- A reference to a Ghost entity may appear as the default
195 -- expression of a formal parameter of a subprogram body. This
196 -- context must be treated as suitable because the relation
197 -- between the spec and the body has not been established and
198 -- the body is not marked as Ghost yet. The real check was
199 -- performed on the spec.
201 elsif Nkind
(Par
) = N_Parameter_Specification
202 and then Nkind
(Parent
(Parent
(Par
))) = N_Subprogram_Body
206 -- References to Ghost entities may be relocated in internally
209 elsif Nkind
(Par
) = N_Subprogram_Body
210 and then not Comes_From_Source
(Par
)
212 Subp_Id
:= Corresponding_Spec
(Par
);
214 -- The original context is an expression function that has
215 -- been split into a spec and a body. The context is OK as
216 -- long as the the initial declaration is Ghost.
218 if Present
(Subp_Id
) then
220 Original_Node
(Unit_Declaration_Node
(Subp_Id
));
222 if Nkind
(Subp_Decl
) = N_Expression_Function
then
223 return Is_Subject_To_Ghost
(Subp_Decl
);
227 -- Otherwise this is either an internal body or an internal
228 -- completion. Both are OK because the real check was done
229 -- before expansion activities.
234 -- Prevent the search from going too far
236 if Is_Body_Or_Package_Declaration
(Par
) then
244 end Is_Ghost_Declaration
;
246 ----------------------------------
247 -- Is_Ghost_Statement_Or_Pragma --
248 ----------------------------------
250 function Is_Ghost_Statement_Or_Pragma
(N
: Node_Id
) return Boolean is
251 function Is_Ghost_Entity_Reference
(N
: Node_Id
) return Boolean;
252 -- Determine whether an arbitrary node denotes a reference to a
255 -------------------------------
256 -- Is_Ghost_Entity_Reference --
257 -------------------------------
259 function Is_Ghost_Entity_Reference
(N
: Node_Id
) return Boolean is
263 -- When the reference extracts a subcomponent, recover the
264 -- related object (SPARK RM 6.9(1)).
267 while Nkind_In
(Ref
, N_Explicit_Dereference
,
269 N_Selected_Component
,
277 and then Present
(Entity
(Ref
))
278 and then Is_Ghost_Entity
(Entity
(Ref
));
279 end Is_Ghost_Entity_Reference
;
286 -- Start of processing for Is_Ghost_Statement_Or_Pragma
289 if Nkind
(N
) = N_Pragma
then
291 -- A pragma is Ghost when it appears within a Ghost package or
294 if Ghost_Mode
> None
then
298 -- A pragma is Ghost when it mentions a Ghost entity
300 Arg
:= First
(Pragma_Argument_Associations
(N
));
301 while Present
(Arg
) loop
302 if Is_Ghost_Entity_Reference
(Get_Pragma_Arg
(Arg
)) then
311 while Present
(Stmt
) loop
312 if Is_Statement
(Stmt
) then
314 -- A statement is Ghost when it appears within a Ghost
315 -- package or subprogram.
317 if Ghost_Mode
> None
then
320 -- An assignment statement or a procedure call is Ghost when
321 -- the name denotes a Ghost entity.
323 elsif Nkind_In
(Stmt
, N_Assignment_Statement
,
324 N_Procedure_Call_Statement
)
326 return Is_Ghost_Entity_Reference
(Name
(Stmt
));
329 -- Prevent the search from going too far
331 elsif Is_Body_Or_Package_Declaration
(Stmt
) then
335 Stmt
:= Parent
(Stmt
);
339 end Is_Ghost_Statement_Or_Pragma
;
341 -- Start of processing for Is_OK_Ghost_Context
344 -- The Ghost entity appears within an assertion expression
346 if In_Assertion_Expr
> 0 then
349 -- The Ghost entity is part of a declaration or its completion
351 elsif Is_Ghost_Declaration
(Context
) then
354 -- The Ghost entity is referenced within a Ghost statement
356 elsif Is_Ghost_Statement_Or_Pragma
(Context
) then
359 -- Routine Expand_Record_Extension creates a parent subtype without
360 -- inserting it into the tree. There is no good way of recognizing
361 -- this special case as there is no parent. Try to approximate the
364 elsif No
(Parent
(Context
)) and then Is_Tagged_Type
(Ghost_Id
) then
370 end Is_OK_Ghost_Context
;
372 ------------------------
373 -- Check_Ghost_Policy --
374 ------------------------
376 procedure Check_Ghost_Policy
(Id
: Entity_Id
; Err_N
: Node_Id
) is
377 Policy
: constant Name_Id
:= Policy_In_Effect
(Name_Ghost
);
380 -- The Ghost policy in effect a the point of declaration and at the
381 -- point of use must match (SPARK RM 6.9(14)).
383 if Is_Checked_Ghost_Entity
(Id
) and then Policy
= Name_Ignore
then
384 Error_Msg_Sloc
:= Sloc
(Err_N
);
386 Error_Msg_N
("incompatible ghost policies in effect", Err_N
);
387 Error_Msg_NE
("\& declared with ghost policy Check", Err_N
, Id
);
388 Error_Msg_NE
("\& used # with ghost policy Ignore", Err_N
, Id
);
390 elsif Is_Ignored_Ghost_Entity
(Id
) and then Policy
= Name_Check
then
391 Error_Msg_Sloc
:= Sloc
(Err_N
);
393 Error_Msg_N
("incompatible ghost policies in effect", Err_N
);
394 Error_Msg_NE
("\& declared with ghost policy Ignore", Err_N
, Id
);
395 Error_Msg_NE
("\& used # with ghost policy Check", Err_N
, Id
);
397 end Check_Ghost_Policy
;
399 -- Start of processing for Check_Ghost_Context
402 -- Once it has been established that the reference to the Ghost entity
403 -- is within a suitable context, ensure that the policy at the point of
404 -- declaration and at the point of use match.
406 if Is_OK_Ghost_Context
(Ghost_Ref
) then
407 Check_Ghost_Policy
(Ghost_Id
, Ghost_Ref
);
409 -- Otherwise the Ghost entity appears in a non-Ghost context and affects
410 -- its behavior or value.
414 ("ghost entity cannot appear in this context (SPARK RM 6.9(12))",
417 end Check_Ghost_Context
;
419 ----------------------------
420 -- Check_Ghost_Derivation --
421 ----------------------------
423 procedure Check_Ghost_Derivation
(Typ
: Entity_Id
) is
424 Parent_Typ
: constant Entity_Id
:= Etype
(Typ
);
426 Iface_Elmt
: Elmt_Id
;
429 -- Allow untagged derivations from predefined types such as Integer as
430 -- those are not Ghost by definition.
432 if Is_Scalar_Type
(Typ
) and then Parent_Typ
= Base_Type
(Typ
) then
435 -- The parent type of a Ghost type extension must be Ghost
437 elsif not Is_Ghost_Entity
(Parent_Typ
) then
438 Error_Msg_N
("type extension & cannot be ghost", Typ
);
439 Error_Msg_NE
("\parent type & is not ghost", Typ
, Parent_Typ
);
443 -- All progenitors (if any) must be Ghost as well
445 if Is_Tagged_Type
(Typ
) and then Present
(Interfaces
(Typ
)) then
446 Iface_Elmt
:= First_Elmt
(Interfaces
(Typ
));
447 while Present
(Iface_Elmt
) loop
448 Iface
:= Node
(Iface_Elmt
);
450 if not Is_Ghost_Entity
(Iface
) then
451 Error_Msg_N
("type extension & cannot be ghost", Typ
);
452 Error_Msg_NE
("\interface type & is not ghost", Typ
, Iface
);
456 Next_Elmt
(Iface_Elmt
);
459 end Check_Ghost_Derivation
;
461 --------------------------------
462 -- Implements_Ghost_Interface --
463 --------------------------------
465 function Implements_Ghost_Interface
(Typ
: Entity_Id
) return Boolean is
466 Iface_Elmt
: Elmt_Id
;
469 -- Traverse the list of interfaces looking for a Ghost interface
471 if Is_Tagged_Type
(Typ
) and then Present
(Interfaces
(Typ
)) then
472 Iface_Elmt
:= First_Elmt
(Interfaces
(Typ
));
473 while Present
(Iface_Elmt
) loop
474 if Is_Ghost_Entity
(Node
(Iface_Elmt
)) then
478 Next_Elmt
(Iface_Elmt
);
483 end Implements_Ghost_Interface
;
489 procedure Initialize
is
491 Ignored_Ghost_Units
.Init
;
494 ---------------------
495 -- Is_Ghost_Entity --
496 ---------------------
498 function Is_Ghost_Entity
(Id
: Entity_Id
) return Boolean is
500 return Is_Checked_Ghost_Entity
(Id
) or else Is_Ignored_Ghost_Entity
(Id
);
503 -------------------------
504 -- Is_Subject_To_Ghost --
505 -------------------------
507 function Is_Subject_To_Ghost
(N
: Node_Id
) return Boolean is
508 function Enables_Ghostness
(Arg
: Node_Id
) return Boolean;
509 -- Determine whether aspect or pragma argument Arg enables "ghostness"
511 -----------------------
512 -- Enables_Ghostness --
513 -----------------------
515 function Enables_Ghostness
(Arg
: Node_Id
) return Boolean is
521 if Nkind
(Expr
) = N_Pragma_Argument_Association
then
522 Expr
:= Get_Pragma_Arg
(Expr
);
525 -- Determine whether the expression of the aspect is static and
528 if Present
(Expr
) then
529 Preanalyze_And_Resolve
(Expr
);
532 Is_OK_Static_Expression
(Expr
)
533 and then Is_True
(Expr_Value
(Expr
));
535 -- Otherwise Ghost defaults to True
540 end Enables_Ghostness
;
544 Id
: constant Entity_Id
:= Defining_Entity
(N
);
549 -- Start of processing for Is_Subject_To_Ghost
552 -- The related entity of the declaration has not been analyzed yet, do
553 -- not inspect its attributes.
555 if Ekind
(Id
) = E_Void
then
558 elsif Is_Ghost_Entity
(Id
) then
561 -- The completion of a type or a constant is not fully analyzed when the
562 -- reference to the Ghost entity is resolved. Because the completion is
563 -- not marked as Ghost yet, inspect the partial view.
565 elsif Is_Record_Type
(Id
)
566 or else Ekind
(Id
) = E_Constant
567 or else (Nkind
(N
) = N_Object_Declaration
568 and then Constant_Present
(N
))
570 Prev_Id
:= Incomplete_Or_Partial_View
(Id
);
572 if Present
(Prev_Id
) and then Is_Ghost_Entity
(Prev_Id
) then
577 -- Examine the aspect specifications (if any) looking for aspect Ghost
579 if Permits_Aspect_Specifications
(N
) then
580 Asp
:= First
(Aspect_Specifications
(N
));
581 while Present
(Asp
) loop
582 if Chars
(Identifier
(Asp
)) = Name_Ghost
then
583 return Enables_Ghostness
(Expression
(Asp
));
592 -- When the context is a [generic] package declaration, pragma Ghost
593 -- resides in the visible declarations.
595 if Nkind_In
(N
, N_Generic_Package_Declaration
,
596 N_Package_Declaration
)
598 Decl
:= First
(Visible_Declarations
(Specification
(N
)));
600 -- When the context is a package or a subprogram body, pragma Ghost
601 -- resides in the declarative part.
603 elsif Nkind_In
(N
, N_Package_Body
, N_Subprogram_Body
) then
604 Decl
:= First
(Declarations
(N
));
606 -- Otherwise pragma Ghost appears in the declarations following N
608 elsif Is_List_Member
(N
) then
612 while Present
(Decl
) loop
613 if Nkind
(Decl
) = N_Pragma
614 and then Pragma_Name
(Decl
) = Name_Ghost
617 Enables_Ghostness
(First
(Pragma_Argument_Associations
(Decl
)));
619 -- A source construct ends the region where pragma Ghost may appear,
620 -- stop the traversal.
622 elsif Comes_From_Source
(Decl
) then
630 end Is_Subject_To_Ghost
;
638 Ignored_Ghost_Units
.Locked
:= True;
639 Ignored_Ghost_Units
.Release
;
642 ----------------------------------
643 -- Propagate_Ignored_Ghost_Code --
644 ----------------------------------
646 procedure Propagate_Ignored_Ghost_Code
(N
: Node_Id
) is
651 -- Traverse the parent chain looking for blocks, packages and
652 -- subprograms or their respective bodies.
655 while Present
(Nod
) loop
658 if Nkind
(Nod
) = N_Block_Statement
then
659 Scop
:= Entity
(Identifier
(Nod
));
661 elsif Nkind_In
(Nod
, N_Package_Body
,
662 N_Package_Declaration
,
664 N_Subprogram_Declaration
)
666 Scop
:= Defining_Entity
(Nod
);
669 -- The current node denotes a scoping construct
671 if Present
(Scop
) then
673 -- Stop the traversal when the scope already contains ignored
674 -- Ghost code as all enclosing scopes have already been marked.
676 if Contains_Ignored_Ghost_Code
(Scop
) then
679 -- Otherwise mark this scope and keep climbing
682 Set_Contains_Ignored_Ghost_Code
(Scop
);
689 -- The unit containing the ignored Ghost code must be post processed
690 -- before invoking the back end.
692 Add_Ignored_Ghost_Unit
(Cunit
(Get_Code_Unit
(N
)));
693 end Propagate_Ignored_Ghost_Code
;
695 -------------------------------
696 -- Remove_Ignored_Ghost_Code --
697 -------------------------------
699 procedure Remove_Ignored_Ghost_Code
is
700 procedure Prune_Tree
(Root
: Node_Id
);
701 -- Remove all code marked as ignored Ghost from the tree of denoted by
708 procedure Prune_Tree
(Root
: Node_Id
) is
709 procedure Prune
(N
: Node_Id
);
710 -- Remove a given node from the tree by rewriting it into null
712 function Prune_Node
(N
: Node_Id
) return Traverse_Result
;
713 -- Determine whether node N denotes an ignored Ghost construct. If
714 -- this is the case, rewrite N as a null statement. See the body for
721 procedure Prune
(N
: Node_Id
) is
723 -- Destroy any aspects that may be associated with the node
725 if Permits_Aspect_Specifications
(N
) and then Has_Aspects
(N
) then
729 Rewrite
(N
, Make_Null_Statement
(Sloc
(N
)));
736 function Prune_Node
(N
: Node_Id
) return Traverse_Result
is
740 -- The node is either declared as ignored Ghost or is a byproduct
741 -- of expansion. Destroy it and stop the traversal on this branch.
743 if Is_Ignored_Ghost_Node
(N
) then
747 -- Scoping constructs such as blocks, packages, subprograms and
748 -- bodies offer some flexibility with respect to pruning.
750 elsif Nkind_In
(N
, N_Block_Statement
,
752 N_Package_Declaration
,
754 N_Subprogram_Declaration
)
756 if Nkind
(N
) = N_Block_Statement
then
757 Id
:= Entity
(Identifier
(N
));
759 Id
:= Defining_Entity
(N
);
762 -- The scoping construct contains both living and ignored Ghost
763 -- code, let the traversal prune all relevant nodes.
765 if Contains_Ignored_Ghost_Code
(Id
) then
768 -- Otherwise the construct contains only living code and should
775 -- Otherwise keep searching for ignored Ghost nodes
782 procedure Prune_Nodes
is new Traverse_Proc
(Prune_Node
);
784 -- Start of processing for Prune_Tree
790 -- Start of processing for Remove_Ignored_Ghost_Code
793 for Index
in Ignored_Ghost_Units
.First
.. Ignored_Ghost_Units
.Last
loop
794 Prune_Tree
(Unit
(Ignored_Ghost_Units
.Table
(Index
)));
796 end Remove_Ignored_Ghost_Code
;
802 procedure Set_Ghost_Mode
(N
: Node_Id
; Prev_Id
: Entity_Id
:= Empty
) is
803 procedure Set_Ghost_Mode_From_Entity
(Id
: Entity_Id
);
804 -- Set the value of global variable Ghost_Mode depending on the mode of
807 procedure Set_Ghost_Mode_From_Policy
;
808 -- Set the value of global variable Ghost_Mode depending on the current
809 -- Ghost policy in effect.
811 --------------------------------
812 -- Set_Ghost_Mode_From_Entity --
813 --------------------------------
815 procedure Set_Ghost_Mode_From_Entity
(Id
: Entity_Id
) is
817 if Is_Checked_Ghost_Entity
(Id
) then
820 elsif Is_Ignored_Ghost_Entity
(Id
) then
821 Ghost_Mode
:= Ignore
;
823 Set_Is_Ignored_Ghost_Node
(N
);
824 Propagate_Ignored_Ghost_Code
(N
);
826 end Set_Ghost_Mode_From_Entity
;
828 --------------------------------
829 -- Set_Ghost_Mode_From_Policy --
830 --------------------------------
832 procedure Set_Ghost_Mode_From_Policy
is
833 Policy
: constant Name_Id
:= Policy_In_Effect
(Name_Ghost
);
836 if Policy
= Name_Check
then
839 elsif Policy
= Name_Ignore
then
840 Ghost_Mode
:= Ignore
;
842 Set_Is_Ignored_Ghost_Node
(N
);
843 Propagate_Ignored_Ghost_Code
(N
);
845 end Set_Ghost_Mode_From_Policy
;
851 -- Start of processing for Set_Ghost_Mode
854 -- The input node denotes one of the many declaration kinds that may be
855 -- subject to pragma Ghost.
857 if Is_Declaration
(N
) then
858 if Is_Subject_To_Ghost
(N
) then
859 Set_Ghost_Mode_From_Policy
;
861 -- The declaration denotes the completion of a deferred constant,
862 -- pragma Ghost appears on the partial declaration.
864 elsif Nkind
(N
) = N_Object_Declaration
865 and then Constant_Present
(N
)
866 and then Present
(Prev_Id
)
868 Set_Ghost_Mode_From_Entity
(Prev_Id
);
870 -- The declaration denotes the full view of a private type, pragma
871 -- Ghost appears on the partial declaration.
873 elsif Nkind
(N
) = N_Full_Type_Declaration
874 and then Is_Private_Type
(Defining_Entity
(N
))
875 and then Present
(Prev_Id
)
877 Set_Ghost_Mode_From_Entity
(Prev_Id
);
880 -- The input denotes an assignment or a procedure call. In this case
881 -- the Ghost mode is dictated by the name of the construct.
883 elsif Nkind_In
(N
, N_Assignment_Statement
,
884 N_Procedure_Call_Statement
)
886 -- When the reference extracts a subcomponent, recover the related
887 -- object (SPARK RM 6.9(1)).
890 while Nkind_In
(Nam
, N_Explicit_Dereference
,
892 N_Selected_Component
,
898 if Is_Entity_Name
(Nam
)
899 and then Present
(Entity
(Nam
))
901 Set_Ghost_Mode_From_Entity
(Entity
(Nam
));
904 -- The input denotes a package or subprogram body
906 elsif Nkind_In
(N
, N_Package_Body
, N_Subprogram_Body
) then
907 if (Present
(Prev_Id
) and then Is_Ghost_Entity
(Prev_Id
))
908 or else Is_Subject_To_Ghost
(N
)
910 Set_Ghost_Mode_From_Policy
;
915 -------------------------------
916 -- Set_Ghost_Mode_For_Freeze --
917 -------------------------------
919 procedure Set_Ghost_Mode_For_Freeze
(Id
: Entity_Id
; N
: Node_Id
) is
921 if Is_Checked_Ghost_Entity
(Id
) then
923 elsif Is_Ignored_Ghost_Entity
(Id
) then
924 Ghost_Mode
:= Ignore
;
925 Propagate_Ignored_Ghost_Code
(N
);
927 end Set_Ghost_Mode_For_Freeze
;
929 -------------------------
930 -- Set_Is_Ghost_Entity --
931 -------------------------
933 procedure Set_Is_Ghost_Entity
(Id
: Entity_Id
) is
934 Policy
: constant Name_Id
:= Policy_In_Effect
(Name_Ghost
);
936 if Policy
= Name_Check
then
937 Set_Is_Checked_Ghost_Entity
(Id
);
938 elsif Policy
= Name_Ignore
then
939 Set_Is_Ignored_Ghost_Entity
(Id
);
941 end Set_Is_Ghost_Entity
;