1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2014-2017, 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 ------------------------------------------------------------------------------
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
;
37 with Sem_Aux
; use Sem_Aux
;
38 with Sem_Disp
; use Sem_Disp
;
39 with Sem_Eval
; use Sem_Eval
;
40 with Sem_Prag
; use Sem_Prag
;
41 with Sem_Res
; use Sem_Res
;
42 with Sem_Util
; use Sem_Util
;
43 with Sinfo
; use Sinfo
;
44 with Snames
; use Snames
;
49 -- The following table contains the N_Compilation_Unit node for a unit that
50 -- is either subject to pragma Ghost with policy Ignore or contains ignored
51 -- Ghost code. The table is used in the removal of ignored Ghost code from
54 package Ignored_Ghost_Units
is new Table
.Table
(
55 Table_Component_Type
=> Node_Id
,
56 Table_Index_Type
=> Int
,
58 Table_Initial
=> Alloc
.Ignored_Ghost_Units_Initial
,
59 Table_Increment
=> Alloc
.Ignored_Ghost_Units_Increment
,
60 Table_Name
=> "Ignored_Ghost_Units");
62 -----------------------
63 -- Local Subprograms --
64 -----------------------
66 function Ghost_Entity
(N
: Node_Id
) return Entity_Id
;
67 -- Find the entity of a reference to a Ghost entity. Return Empty if there
70 procedure Install_Ghost_Mode
(Mode
: Name_Id
);
71 -- Install a specific Ghost mode denoted by Mode by setting global variable
74 function Is_Subject_To_Ghost
(N
: Node_Id
) return Boolean;
75 -- Determine whether declaration or body N is subject to aspect or pragma
76 -- Ghost. This routine must be used in cases where pragma Ghost has not
77 -- been analyzed yet, but the context needs to establish the "ghostness"
80 procedure Mark_Ghost_Declaration_Or_Body
83 -- Mark the defining entity of declaration or body N as Ghost depending on
84 -- mode Mode. Mark all formals parameters when N denotes a subprogram or a
87 procedure Propagate_Ignored_Ghost_Code
(N
: Node_Id
);
88 -- Signal all enclosing scopes that they now contain at least one ignored
89 -- Ghost node denoted by N. Add the compilation unit containing N to table
90 -- Ignored_Ghost_Units for post processing.
92 ----------------------------
93 -- Add_Ignored_Ghost_Unit --
94 ----------------------------
96 procedure Add_Ignored_Ghost_Unit
(Unit
: Node_Id
) is
98 pragma Assert
(Nkind
(Unit
) = N_Compilation_Unit
);
100 -- Avoid duplicates in the table as pruning the same unit more than once
101 -- is wasteful. Since ignored Ghost code tends to be grouped up, check
102 -- the contents of the table in reverse.
104 for Index
in reverse Ignored_Ghost_Units
.First
..
105 Ignored_Ghost_Units
.Last
107 -- If the unit is already present in the table, do not add it again
109 if Unit
= Ignored_Ghost_Units
.Table
(Index
) then
114 -- If we get here, then this is the first time the unit is being added
116 Ignored_Ghost_Units
.Append
(Unit
);
117 end Add_Ignored_Ghost_Unit
;
119 ----------------------------
120 -- Check_Ghost_Completion --
121 ----------------------------
123 procedure Check_Ghost_Completion
124 (Prev_Id
: Entity_Id
;
125 Compl_Id
: Entity_Id
)
127 Policy
: constant Name_Id
:= Policy_In_Effect
(Name_Ghost
);
130 -- Nothing to do if one of the views is missing
132 if No
(Prev_Id
) or else No
(Compl_Id
) then
135 -- The Ghost policy in effect at the point of declaration and at the
136 -- point of completion must match (SPARK RM 6.9(14)).
138 elsif Is_Checked_Ghost_Entity
(Prev_Id
)
139 and then Policy
= Name_Ignore
141 Error_Msg_Sloc
:= Sloc
(Compl_Id
);
143 Error_Msg_N
("incompatible ghost policies in effect", Prev_Id
);
144 Error_Msg_N
("\& declared with ghost policy `Check`", Prev_Id
);
145 Error_Msg_N
("\& completed # with ghost policy `Ignore`", Prev_Id
);
147 elsif Is_Ignored_Ghost_Entity
(Prev_Id
)
148 and then Policy
= Name_Check
150 Error_Msg_Sloc
:= Sloc
(Compl_Id
);
152 Error_Msg_N
("incompatible ghost policies in effect", Prev_Id
);
153 Error_Msg_N
("\& declared with ghost policy `Ignore`", Prev_Id
);
154 Error_Msg_N
("\& completed # with ghost policy `Check`", Prev_Id
);
156 end Check_Ghost_Completion
;
158 -------------------------
159 -- Check_Ghost_Context --
160 -------------------------
162 procedure Check_Ghost_Context
(Ghost_Id
: Entity_Id
; Ghost_Ref
: Node_Id
) is
163 procedure Check_Ghost_Policy
(Id
: Entity_Id
; Ref
: Node_Id
);
164 -- Verify that the Ghost policy at the point of declaration of entity Id
165 -- matches the policy at the point of reference Ref. If this is not the
166 -- case emit an error at Ref.
168 function Is_OK_Ghost_Context
(Context
: Node_Id
) return Boolean;
169 -- Determine whether node Context denotes a Ghost-friendly context where
170 -- a Ghost entity can safely reside (SPARK RM 6.9(10)).
172 -------------------------
173 -- Is_OK_Ghost_Context --
174 -------------------------
176 function Is_OK_Ghost_Context
(Context
: Node_Id
) return Boolean is
177 function Is_OK_Declaration
(Decl
: Node_Id
) return Boolean;
178 -- Determine whether node Decl is a suitable context for a reference
179 -- to a Ghost entity. To qualify as such, Decl must either
181 -- * Define a Ghost entity
183 -- * Be subject to pragma Ghost
185 function Is_OK_Pragma
(Prag
: Node_Id
) return Boolean;
186 -- Determine whether node Prag is a suitable context for a reference
187 -- to a Ghost entity. To qualify as such, Prag must either
189 -- * Be an assertion expression pragma
191 -- * Denote pragma Global, Depends, Initializes, Refined_Global,
192 -- Refined_Depends or Refined_State.
194 -- * Specify an aspect of a Ghost entity
196 -- * Contain a reference to a Ghost entity
198 function Is_OK_Statement
(Stmt
: Node_Id
) return Boolean;
199 -- Determine whether node Stmt is a suitable context for a reference
200 -- to a Ghost entity. To qualify as such, Stmt must either
202 -- * Denote a procedure call to a Ghost procedure
204 -- * Denote an assignment statement whose target is Ghost
206 -----------------------
207 -- Is_OK_Declaration --
208 -----------------------
210 function Is_OK_Declaration
(Decl
: Node_Id
) return Boolean is
211 function In_Subprogram_Body_Profile
(N
: Node_Id
) return Boolean;
212 -- Determine whether node N appears in the profile of a subprogram
215 --------------------------------
216 -- In_Subprogram_Body_Profile --
217 --------------------------------
219 function In_Subprogram_Body_Profile
(N
: Node_Id
) return Boolean is
220 Spec
: constant Node_Id
:= Parent
(N
);
223 -- The node appears in a parameter specification in which case
224 -- it is either the parameter type or the default expression or
225 -- the node appears as the result definition of a function.
228 (Nkind
(N
) = N_Parameter_Specification
230 (Nkind
(Spec
) = N_Function_Specification
231 and then N
= Result_Definition
(Spec
)))
232 and then Nkind
(Parent
(Spec
)) = N_Subprogram_Body
;
233 end In_Subprogram_Body_Profile
;
240 -- Start of processing for Is_OK_Declaration
243 if Is_Ghost_Declaration
(Decl
) then
248 -- A reference to a Ghost entity may appear within the profile of
249 -- a subprogram body. This context is treated as suitable because
250 -- it duplicates the context of the corresponding spec. The real
251 -- check was already performed during the analysis of the spec.
253 elsif In_Subprogram_Body_Profile
(Decl
) then
256 -- A reference to a Ghost entity may appear within an expression
257 -- function which is still being analyzed. This context is treated
258 -- as suitable because it is not yet known whether the expression
259 -- function is an initial declaration or a completion. The real
260 -- check is performed when the expression function is expanded.
262 elsif Nkind
(Decl
) = N_Expression_Function
263 and then not Analyzed
(Decl
)
267 -- References to Ghost entities may be relocated in internally
270 elsif Nkind
(Decl
) = N_Subprogram_Body
271 and then not Comes_From_Source
(Decl
)
273 Subp_Id
:= Corresponding_Spec
(Decl
);
275 if Present
(Subp_Id
) then
277 -- The context is the internally built _Postconditions
278 -- procedure, which is OK because the real check was done
279 -- before expansion activities.
281 if Chars
(Subp_Id
) = Name_uPostconditions
then
284 -- The context is the internally built predicate function,
285 -- which is OK because the real check was done before the
286 -- predicate function was generated.
288 elsif Is_Predicate_Function
(Subp_Id
) then
293 Original_Node
(Unit_Declaration_Node
(Subp_Id
));
295 -- The original context is an expression function that
296 -- has been split into a spec and a body. The context is
297 -- OK as long as the initial declaration is Ghost.
299 if Nkind
(Subp_Decl
) = N_Expression_Function
then
300 return Is_Ghost_Declaration
(Subp_Decl
);
304 -- Otherwise this is either an internal body or an internal
305 -- completion. Both are OK because the real check was done
306 -- before expansion activities.
314 end Is_OK_Declaration
;
320 function Is_OK_Pragma
(Prag
: Node_Id
) return Boolean is
321 procedure Check_Policies
(Prag_Nam
: Name_Id
);
322 -- Verify that the Ghost policy in effect is the same as the
323 -- assertion policy for pragma name Prag_Nam. Emit an error if
324 -- this is not the case.
330 procedure Check_Policies
(Prag_Nam
: Name_Id
) is
331 AP
: constant Name_Id
:= Check_Kind
(Prag_Nam
);
332 GP
: constant Name_Id
:= Policy_In_Effect
(Name_Ghost
);
335 -- If the Ghost policy in effect at the point of a Ghost entity
336 -- reference is Ignore, then the assertion policy of the pragma
337 -- must be Ignore (SPARK RM 6.9(18)).
339 if GP
= Name_Ignore
and then AP
/= Name_Ignore
then
341 ("incompatible ghost policies in effect",
344 ("\ghost entity & has policy `Ignore`",
345 Ghost_Ref
, Ghost_Id
);
347 Error_Msg_Name_1
:= AP
;
349 ("\assertion expression has policy %", Ghost_Ref
);
358 -- Start of processing for Is_OK_Pragma
361 if Nkind
(Prag
) = N_Pragma
then
362 Prag_Id
:= Get_Pragma_Id
(Prag
);
363 Prag_Nam
:= Original_Aspect_Pragma_Name
(Prag
);
365 -- A pragma that applies to a Ghost construct or specifies an
366 -- aspect of a Ghost entity is a Ghost pragma (SPARK RM 6.9(3))
368 if Is_Ghost_Pragma
(Prag
) then
371 -- An assertion expression pragma is Ghost when it contains a
372 -- reference to a Ghost entity (SPARK RM 6.9(10)), except for
373 -- predicate pragmas (SPARK RM 6.9(11)).
375 elsif Assertion_Expression_Pragma
(Prag_Id
)
376 and then Prag_Id
/= Pragma_Predicate
378 -- Ensure that the assertion policy and the Ghost policy are
379 -- compatible (SPARK RM 6.9(18)).
381 Check_Policies
(Prag_Nam
);
384 -- Several pragmas that may apply to a non-Ghost entity are
385 -- treated as Ghost when they contain a reference to a Ghost
386 -- entity (SPARK RM 6.9(11)).
388 elsif Nam_In
(Prag_Nam
, Name_Global
,
392 Name_Refined_Depends
,
402 ---------------------
403 -- Is_OK_Statement --
404 ---------------------
406 function Is_OK_Statement
(Stmt
: Node_Id
) return Boolean is
408 -- An assignment statement is Ghost when the target is a Ghost
411 if Nkind
(Stmt
) = N_Assignment_Statement
then
412 return Is_Ghost_Assignment
(Stmt
);
414 -- A procedure call is Ghost when it calls a Ghost procedure
416 elsif Nkind
(Stmt
) = N_Procedure_Call_Statement
then
417 return Is_Ghost_Procedure_Call
(Stmt
);
421 -- An if statement is a suitable context for a Ghost entity if it
422 -- is the byproduct of assertion expression expansion. Note that
423 -- the assertion expression may not be related to a Ghost entity,
424 -- but it may still contain references to Ghost entities.
426 elsif Nkind
(Stmt
) = N_If_Statement
427 and then Nkind
(Original_Node
(Stmt
)) = N_Pragma
428 and then Assertion_Expression_Pragma
429 (Get_Pragma_Id
(Original_Node
(Stmt
)))
441 -- Start of processing for Is_OK_Ghost_Context
444 -- The context is Ghost when it appears within a Ghost package or
447 if Ghost_Mode
> None
then
450 -- A Ghost type may be referenced in a use_type clause
451 -- (SPARK RM 6.9.10).
453 elsif Present
(Parent
(Context
))
454 and then Nkind
(Parent
(Context
)) = N_Use_Type_Clause
458 -- Routine Expand_Record_Extension creates a parent subtype without
459 -- inserting it into the tree. There is no good way of recognizing
460 -- this special case as there is no parent. Try to approximate the
463 elsif No
(Parent
(Context
)) and then Is_Tagged_Type
(Ghost_Id
) then
466 -- Otherwise climb the parent chain looking for a suitable Ghost
471 while Present
(Par
) loop
472 if Is_Ignored_Ghost_Node
(Par
) then
475 -- A reference to a Ghost entity can appear within an aspect
476 -- specification (SPARK RM 6.9(10)). The precise checking will
477 -- occur when analyzing the corresponding pragma. We make an
478 -- exception for predicate aspects that only allow referencing
479 -- a Ghost entity when the corresponding type declaration is
480 -- Ghost (SPARK RM 6.9(11)).
482 elsif Nkind
(Par
) = N_Aspect_Specification
483 and then not Same_Aspect
484 (Get_Aspect_Id
(Par
), Aspect_Predicate
)
488 elsif Is_OK_Declaration
(Par
) then
491 elsif Is_OK_Pragma
(Par
) then
494 elsif Is_OK_Statement
(Par
) then
497 -- Prevent the search from going too far
499 elsif Is_Body_Or_Package_Declaration
(Par
) then
506 -- The expansion of assertion expression pragmas and attribute Old
507 -- may cause a legal Ghost entity reference to become illegal due
508 -- to node relocation. Check the In_Assertion_Expr counter as last
509 -- resort to try and infer the original legal context.
511 if In_Assertion_Expr
> 0 then
514 -- Otherwise the context is not suitable for a reference to a
521 end Is_OK_Ghost_Context
;
523 ------------------------
524 -- Check_Ghost_Policy --
525 ------------------------
527 procedure Check_Ghost_Policy
(Id
: Entity_Id
; Ref
: Node_Id
) is
528 Policy
: constant Name_Id
:= Policy_In_Effect
(Name_Ghost
);
531 -- The Ghost policy in effect a the point of declaration and at the
532 -- point of use must match (SPARK RM 6.9(13)).
534 if Is_Checked_Ghost_Entity
(Id
)
535 and then Policy
= Name_Ignore
536 and then May_Be_Lvalue
(Ref
)
538 Error_Msg_Sloc
:= Sloc
(Ref
);
540 Error_Msg_N
("incompatible ghost policies in effect", Ref
);
541 Error_Msg_NE
("\& declared with ghost policy `Check`", Ref
, Id
);
542 Error_Msg_NE
("\& used # with ghost policy `Ignore`", Ref
, Id
);
544 elsif Is_Ignored_Ghost_Entity
(Id
) and then Policy
= Name_Check
then
545 Error_Msg_Sloc
:= Sloc
(Ref
);
547 Error_Msg_N
("incompatible ghost policies in effect", Ref
);
548 Error_Msg_NE
("\& declared with ghost policy `Ignore`", Ref
, Id
);
549 Error_Msg_NE
("\& used # with ghost policy `Check`", Ref
, Id
);
551 end Check_Ghost_Policy
;
553 -- Start of processing for Check_Ghost_Context
556 -- Once it has been established that the reference to the Ghost entity
557 -- is within a suitable context, ensure that the policy at the point of
558 -- declaration and at the point of use match.
560 if Is_OK_Ghost_Context
(Ghost_Ref
) then
561 Check_Ghost_Policy
(Ghost_Id
, Ghost_Ref
);
563 -- Otherwise the Ghost entity appears in a non-Ghost context and affects
564 -- its behavior or value (SPARK RM 6.9(10,11)).
567 Error_Msg_N
("ghost entity cannot appear in this context", Ghost_Ref
);
569 end Check_Ghost_Context
;
571 ----------------------------
572 -- Check_Ghost_Overriding --
573 ----------------------------
575 procedure Check_Ghost_Overriding
577 Overridden_Subp
: Entity_Id
)
579 Deriv_Typ
: Entity_Id
;
580 Over_Subp
: Entity_Id
;
583 if Present
(Subp
) and then Present
(Overridden_Subp
) then
584 Over_Subp
:= Ultimate_Alias
(Overridden_Subp
);
585 Deriv_Typ
:= Find_Dispatching_Type
(Subp
);
587 -- A Ghost primitive of a non-Ghost type extension cannot override an
588 -- inherited non-Ghost primitive (SPARK RM 6.9(8)).
590 if Is_Ghost_Entity
(Subp
)
591 and then Present
(Deriv_Typ
)
592 and then not Is_Ghost_Entity
(Deriv_Typ
)
593 and then not Is_Ghost_Entity
(Over_Subp
)
594 and then not Is_Abstract_Subprogram
(Over_Subp
)
596 Error_Msg_N
("incompatible overriding in effect", Subp
);
598 Error_Msg_Sloc
:= Sloc
(Over_Subp
);
599 Error_Msg_N
("\& declared # as non-ghost subprogram", Subp
);
601 Error_Msg_Sloc
:= Sloc
(Subp
);
602 Error_Msg_N
("\overridden # with ghost subprogram", Subp
);
605 -- A non-Ghost primitive of a type extension cannot override an
606 -- inherited Ghost primitive (SPARK RM 6.9(8)).
608 if Is_Ghost_Entity
(Over_Subp
)
609 and then not Is_Ghost_Entity
(Subp
)
610 and then not Is_Abstract_Subprogram
(Subp
)
612 Error_Msg_N
("incompatible overriding in effect", Subp
);
614 Error_Msg_Sloc
:= Sloc
(Over_Subp
);
615 Error_Msg_N
("\& declared # as ghost subprogram", Subp
);
617 Error_Msg_Sloc
:= Sloc
(Subp
);
618 Error_Msg_N
("\overridden # with non-ghost subprogram", Subp
);
621 if Present
(Deriv_Typ
)
622 and then not Is_Ignored_Ghost_Entity
(Deriv_Typ
)
624 -- When a tagged type is either non-Ghost or checked Ghost and
625 -- one of its primitives overrides an inherited operation, the
626 -- overridden operation of the ancestor type must be ignored Ghost
627 -- if the primitive is ignored Ghost (SPARK RM 6.9(17)).
629 if Is_Ignored_Ghost_Entity
(Subp
) then
631 -- Both the parent subprogram and overriding subprogram are
634 if Is_Ignored_Ghost_Entity
(Over_Subp
) then
637 -- The parent subprogram carries policy Check
639 elsif Is_Checked_Ghost_Entity
(Over_Subp
) then
641 ("incompatible ghost policies in effect", Subp
);
643 Error_Msg_Sloc
:= Sloc
(Over_Subp
);
645 ("\& declared # with ghost policy `Check`", Subp
);
647 Error_Msg_Sloc
:= Sloc
(Subp
);
649 ("\overridden # with ghost policy `Ignore`", Subp
);
651 -- The parent subprogram is non-Ghost
655 ("incompatible ghost policies in effect", Subp
);
657 Error_Msg_Sloc
:= Sloc
(Over_Subp
);
658 Error_Msg_N
("\& declared # as non-ghost subprogram", Subp
);
660 Error_Msg_Sloc
:= Sloc
(Subp
);
662 ("\overridden # with ghost policy `Ignore`", Subp
);
665 -- When a tagged type is either non-Ghost or checked Ghost and
666 -- one of its primitives overrides an inherited operation, the
667 -- the primitive of the tagged type must be ignored Ghost if the
668 -- overridden operation is ignored Ghost (SPARK RM 6.9(17)).
670 elsif Is_Ignored_Ghost_Entity
(Over_Subp
) then
672 -- Both the parent subprogram and the overriding subprogram are
675 if Is_Ignored_Ghost_Entity
(Subp
) then
678 -- The overriding subprogram carries policy Check
680 elsif Is_Checked_Ghost_Entity
(Subp
) then
682 ("incompatible ghost policies in effect", Subp
);
684 Error_Msg_Sloc
:= Sloc
(Over_Subp
);
686 ("\& declared # with ghost policy `Ignore`", Subp
);
688 Error_Msg_Sloc
:= Sloc
(Subp
);
690 ("\overridden # with Ghost policy `Check`", Subp
);
692 -- The overriding subprogram is non-Ghost
696 ("incompatible ghost policies in effect", Subp
);
698 Error_Msg_Sloc
:= Sloc
(Over_Subp
);
700 ("\& declared # with ghost policy `Ignore`", Subp
);
702 Error_Msg_Sloc
:= Sloc
(Subp
);
704 ("\overridden # with non-ghost subprogram", Subp
);
709 end Check_Ghost_Overriding
;
711 ---------------------------
712 -- Check_Ghost_Primitive --
713 ---------------------------
715 procedure Check_Ghost_Primitive
(Prim
: Entity_Id
; Typ
: Entity_Id
) is
717 -- The Ghost policy in effect at the point of declaration of a primitive
718 -- operation and a tagged type must match (SPARK RM 6.9(16)).
720 if Is_Tagged_Type
(Typ
) then
721 if Is_Checked_Ghost_Entity
(Prim
)
722 and then Is_Ignored_Ghost_Entity
(Typ
)
724 Error_Msg_N
("incompatible ghost policies in effect", Prim
);
726 Error_Msg_Sloc
:= Sloc
(Typ
);
728 ("\tagged type & declared # with ghost policy `Ignore`",
731 Error_Msg_Sloc
:= Sloc
(Prim
);
733 ("\primitive subprogram & declared # with ghost policy `Check`",
736 elsif Is_Ignored_Ghost_Entity
(Prim
)
737 and then Is_Checked_Ghost_Entity
(Typ
)
739 Error_Msg_N
("incompatible ghost policies in effect", Prim
);
741 Error_Msg_Sloc
:= Sloc
(Typ
);
743 ("\tagged type & declared # with ghost policy `Check`",
746 Error_Msg_Sloc
:= Sloc
(Prim
);
748 ("\primitive subprogram & declared # with ghost policy `Ignore`",
752 end Check_Ghost_Primitive
;
754 ----------------------------
755 -- Check_Ghost_Refinement --
756 ----------------------------
758 procedure Check_Ghost_Refinement
760 State_Id
: Entity_Id
;
762 Constit_Id
: Entity_Id
)
765 if Is_Ghost_Entity
(State_Id
) then
766 if Is_Ghost_Entity
(Constit_Id
) then
768 -- The Ghost policy in effect at the point of abstract state
769 -- declaration and constituent must match (SPARK RM 6.9(15)).
771 if Is_Checked_Ghost_Entity
(State_Id
)
772 and then Is_Ignored_Ghost_Entity
(Constit_Id
)
774 Error_Msg_Sloc
:= Sloc
(Constit
);
775 SPARK_Msg_N
("incompatible ghost policies in effect", State
);
778 ("\abstract state & declared with ghost policy `Check`",
781 ("\constituent & declared # with ghost policy `Ignore`",
784 elsif Is_Ignored_Ghost_Entity
(State_Id
)
785 and then Is_Checked_Ghost_Entity
(Constit_Id
)
787 Error_Msg_Sloc
:= Sloc
(Constit
);
788 SPARK_Msg_N
("incompatible ghost policies in effect", State
);
791 ("\abstract state & declared with ghost policy `Ignore`",
794 ("\constituent & declared # with ghost policy `Check`",
798 -- A constituent of a Ghost abstract state must be a Ghost entity
799 -- (SPARK RM 7.2.2(12)).
803 ("constituent of ghost state & must be ghost",
807 end Check_Ghost_Refinement
;
813 function Ghost_Entity
(N
: Node_Id
) return Entity_Id
is
817 -- When the reference denotes a subcomponent, recover the related
818 -- object (SPARK RM 6.9(1)).
821 while Nkind_In
(Ref
, N_Explicit_Dereference
,
823 N_Selected_Component
,
829 if Is_Entity_Name
(Ref
) then
836 --------------------------------
837 -- Implements_Ghost_Interface --
838 --------------------------------
840 function Implements_Ghost_Interface
(Typ
: Entity_Id
) return Boolean is
841 Iface_Elmt
: Elmt_Id
;
844 -- Traverse the list of interfaces looking for a Ghost interface
846 if Is_Tagged_Type
(Typ
) and then Present
(Interfaces
(Typ
)) then
847 Iface_Elmt
:= First_Elmt
(Interfaces
(Typ
));
848 while Present
(Iface_Elmt
) loop
849 if Is_Ghost_Entity
(Node
(Iface_Elmt
)) then
853 Next_Elmt
(Iface_Elmt
);
858 end Implements_Ghost_Interface
;
864 procedure Initialize
is
866 Ignored_Ghost_Units
.Init
;
869 ------------------------
870 -- Install_Ghost_Mode --
871 ------------------------
873 procedure Install_Ghost_Mode
(Mode
: Ghost_Mode_Type
) is
876 end Install_Ghost_Mode
;
878 procedure Install_Ghost_Mode
(Mode
: Name_Id
) is
880 if Mode
= Name_Check
then
883 elsif Mode
= Name_Ignore
then
884 Ghost_Mode
:= Ignore
;
886 elsif Mode
= Name_None
then
889 end Install_Ghost_Mode
;
891 -------------------------
892 -- Is_Ghost_Assignment --
893 -------------------------
895 function Is_Ghost_Assignment
(N
: Node_Id
) return Boolean is
899 -- An assignment statement is Ghost when its target denotes a Ghost
902 if Nkind
(N
) = N_Assignment_Statement
then
903 Id
:= Ghost_Entity
(Name
(N
));
905 return Present
(Id
) and then Is_Ghost_Entity
(Id
);
909 end Is_Ghost_Assignment
;
911 --------------------------
912 -- Is_Ghost_Declaration --
913 --------------------------
915 function Is_Ghost_Declaration
(N
: Node_Id
) return Boolean is
919 -- A declaration is Ghost when it elaborates a Ghost entity or is
920 -- subject to pragma Ghost.
922 if Is_Declaration
(N
) then
923 Id
:= Defining_Entity
(N
);
925 return Is_Ghost_Entity
(Id
) or else Is_Subject_To_Ghost
(N
);
929 end Is_Ghost_Declaration
;
931 ---------------------
932 -- Is_Ghost_Pragma --
933 ---------------------
935 function Is_Ghost_Pragma
(N
: Node_Id
) return Boolean is
937 return Is_Checked_Ghost_Pragma
(N
) or else Is_Ignored_Ghost_Pragma
(N
);
940 -----------------------------
941 -- Is_Ghost_Procedure_Call --
942 -----------------------------
944 function Is_Ghost_Procedure_Call
(N
: Node_Id
) return Boolean is
948 -- A procedure call is Ghost when it invokes a Ghost procedure
950 if Nkind
(N
) = N_Procedure_Call_Statement
then
951 Id
:= Ghost_Entity
(Name
(N
));
953 return Present
(Id
) and then Is_Ghost_Entity
(Id
);
957 end Is_Ghost_Procedure_Call
;
959 ---------------------------
960 -- Is_Ignored_Ghost_Unit --
961 ---------------------------
963 function Is_Ignored_Ghost_Unit
(N
: Node_Id
) return Boolean is
965 -- Inspect the original node of the unit in case removal of ignored
966 -- Ghost code has already taken place.
969 Nkind
(N
) = N_Compilation_Unit
970 and then Is_Ignored_Ghost_Entity
971 (Defining_Entity
(Original_Node
(Unit
(N
))));
972 end Is_Ignored_Ghost_Unit
;
974 -------------------------
975 -- Is_Subject_To_Ghost --
976 -------------------------
978 function Is_Subject_To_Ghost
(N
: Node_Id
) return Boolean is
979 function Enables_Ghostness
(Arg
: Node_Id
) return Boolean;
980 -- Determine whether aspect or pragma argument Arg enables "ghostness"
982 -----------------------
983 -- Enables_Ghostness --
984 -----------------------
986 function Enables_Ghostness
(Arg
: Node_Id
) return Boolean is
992 if Nkind
(Expr
) = N_Pragma_Argument_Association
then
993 Expr
:= Get_Pragma_Arg
(Expr
);
996 -- Determine whether the expression of the aspect or pragma is static
999 if Present
(Expr
) then
1000 Preanalyze_And_Resolve
(Expr
);
1003 Is_OK_Static_Expression
(Expr
)
1004 and then Is_True
(Expr_Value
(Expr
));
1006 -- Otherwise Ghost defaults to True
1011 end Enables_Ghostness
;
1015 Id
: constant Entity_Id
:= Defining_Entity
(N
);
1018 Prev_Id
: Entity_Id
;
1020 -- Start of processing for Is_Subject_To_Ghost
1023 -- The related entity of the declaration has not been analyzed yet, do
1024 -- not inspect its attributes.
1026 if Ekind
(Id
) = E_Void
then
1029 elsif Is_Ghost_Entity
(Id
) then
1032 -- The completion of a type or a constant is not fully analyzed when the
1033 -- reference to the Ghost entity is resolved. Because the completion is
1034 -- not marked as Ghost yet, inspect the partial view.
1036 elsif Is_Record_Type
(Id
)
1037 or else Ekind
(Id
) = E_Constant
1038 or else (Nkind
(N
) = N_Object_Declaration
1039 and then Constant_Present
(N
))
1041 Prev_Id
:= Incomplete_Or_Partial_View
(Id
);
1043 if Present
(Prev_Id
) and then Is_Ghost_Entity
(Prev_Id
) then
1048 -- Examine the aspect specifications (if any) looking for aspect Ghost
1050 if Permits_Aspect_Specifications
(N
) then
1051 Asp
:= First
(Aspect_Specifications
(N
));
1052 while Present
(Asp
) loop
1053 if Chars
(Identifier
(Asp
)) = Name_Ghost
then
1054 return Enables_Ghostness
(Expression
(Asp
));
1063 -- When the context is a [generic] package declaration, pragma Ghost
1064 -- resides in the visible declarations.
1066 if Nkind_In
(N
, N_Generic_Package_Declaration
,
1067 N_Package_Declaration
)
1069 Decl
:= First
(Visible_Declarations
(Specification
(N
)));
1071 -- When the context is a package or a subprogram body, pragma Ghost
1072 -- resides in the declarative part.
1074 elsif Nkind_In
(N
, N_Package_Body
, N_Subprogram_Body
) then
1075 Decl
:= First
(Declarations
(N
));
1077 -- Otherwise pragma Ghost appears in the declarations following N
1079 elsif Is_List_Member
(N
) then
1083 while Present
(Decl
) loop
1084 if Nkind
(Decl
) = N_Pragma
1085 and then Pragma_Name
(Decl
) = Name_Ghost
1088 Enables_Ghostness
(First
(Pragma_Argument_Associations
(Decl
)));
1090 -- A source construct ends the region where pragma Ghost may appear,
1091 -- stop the traversal. Check the original node as source constructs
1092 -- may be rewritten into something else by expansion.
1094 elsif Comes_From_Source
(Original_Node
(Decl
)) then
1102 end Is_Subject_To_Ghost
;
1110 Ignored_Ghost_Units
.Release
;
1111 Ignored_Ghost_Units
.Locked
:= True;
1114 -----------------------------------
1115 -- Mark_And_Set_Ghost_Assignment --
1116 -----------------------------------
1118 procedure Mark_And_Set_Ghost_Assignment
(N
: Node_Id
) is
1122 -- An assignment statement becomes Ghost when its target denotes a Ghost
1123 -- object. Install the Ghost mode of the target.
1125 Id
:= Ghost_Entity
(Name
(N
));
1127 if Present
(Id
) then
1128 if Is_Checked_Ghost_Entity
(Id
) then
1129 Install_Ghost_Mode
(Check
);
1131 elsif Is_Ignored_Ghost_Entity
(Id
) then
1132 Install_Ghost_Mode
(Ignore
);
1134 Set_Is_Ignored_Ghost_Node
(N
);
1135 Propagate_Ignored_Ghost_Code
(N
);
1138 end Mark_And_Set_Ghost_Assignment
;
1140 -----------------------------
1141 -- Mark_And_Set_Ghost_Body --
1142 -----------------------------
1144 procedure Mark_And_Set_Ghost_Body
1146 Spec_Id
: Entity_Id
)
1148 Body_Id
: constant Entity_Id
:= Defining_Entity
(N
);
1149 Policy
: Name_Id
:= No_Name
;
1152 -- A body becomes Ghost when it is subject to aspect or pragma Ghost
1154 if Is_Subject_To_Ghost
(N
) then
1155 Policy
:= Policy_In_Effect
(Name_Ghost
);
1157 -- A body declared within a Ghost region is automatically Ghost
1158 -- (SPARK RM 6.9(2)).
1160 elsif Ghost_Mode
= Check
then
1161 Policy
:= Name_Check
;
1163 elsif Ghost_Mode
= Ignore
then
1164 Policy
:= Name_Ignore
;
1166 -- Inherit the "ghostness" of the previous declaration when the body
1167 -- acts as a completion.
1169 elsif Present
(Spec_Id
) then
1170 if Is_Checked_Ghost_Entity
(Spec_Id
) then
1171 Policy
:= Name_Check
;
1173 elsif Is_Ignored_Ghost_Entity
(Spec_Id
) then
1174 Policy
:= Name_Ignore
;
1178 -- The Ghost policy in effect at the point of declaration and at the
1179 -- point of completion must match (SPARK RM 6.9(14)).
1181 Check_Ghost_Completion
1182 (Prev_Id
=> Spec_Id
,
1183 Compl_Id
=> Body_Id
);
1185 -- Mark the body as its formals as Ghost
1187 Mark_Ghost_Declaration_Or_Body
(N
, Policy
);
1189 -- Install the appropriate Ghost mode
1191 Install_Ghost_Mode
(Policy
);
1192 end Mark_And_Set_Ghost_Body
;
1194 -----------------------------------
1195 -- Mark_And_Set_Ghost_Completion --
1196 -----------------------------------
1198 procedure Mark_And_Set_Ghost_Completion
1200 Prev_Id
: Entity_Id
)
1202 Compl_Id
: constant Entity_Id
:= Defining_Entity
(N
);
1203 Policy
: Name_Id
:= No_Name
;
1206 -- A completion elaborated in a Ghost region is automatically Ghost
1207 -- (SPARK RM 6.9(2)).
1209 if Ghost_Mode
= Check
then
1210 Policy
:= Name_Check
;
1212 elsif Ghost_Mode
= Ignore
then
1213 Policy
:= Name_Ignore
;
1215 -- The completion becomes Ghost when its initial declaration is also
1218 elsif Is_Checked_Ghost_Entity
(Prev_Id
) then
1219 Policy
:= Name_Check
;
1221 elsif Is_Ignored_Ghost_Entity
(Prev_Id
) then
1222 Policy
:= Name_Ignore
;
1225 -- The Ghost policy in effect at the point of declaration and at the
1226 -- point of completion must match (SPARK RM 6.9(14)).
1228 Check_Ghost_Completion
1229 (Prev_Id
=> Prev_Id
,
1230 Compl_Id
=> Compl_Id
);
1232 -- Mark the completion as Ghost
1234 Mark_Ghost_Declaration_Or_Body
(N
, Policy
);
1236 -- Install the appropriate Ghost mode
1238 Install_Ghost_Mode
(Policy
);
1239 end Mark_And_Set_Ghost_Completion
;
1241 ------------------------------------
1242 -- Mark_And_Set_Ghost_Declaration --
1243 ------------------------------------
1245 procedure Mark_And_Set_Ghost_Declaration
(N
: Node_Id
) is
1247 Policy
: Name_Id
:= No_Name
;
1250 -- A declaration becomes Ghost when it is subject to aspect or pragma
1253 if Is_Subject_To_Ghost
(N
) then
1254 Policy
:= Policy_In_Effect
(Name_Ghost
);
1256 -- A declaration elaborated in a Ghost region is automatically Ghost
1257 -- (SPARK RM 6.9(2)).
1259 elsif Ghost_Mode
= Check
then
1260 Policy
:= Name_Check
;
1262 elsif Ghost_Mode
= Ignore
then
1263 Policy
:= Name_Ignore
;
1265 -- A child package or subprogram declaration becomes Ghost when its
1266 -- parent is Ghost (SPARK RM 6.9(2)).
1268 elsif Nkind_In
(N
, N_Generic_Function_Renaming_Declaration
,
1269 N_Generic_Package_Declaration
,
1270 N_Generic_Package_Renaming_Declaration
,
1271 N_Generic_Procedure_Renaming_Declaration
,
1272 N_Generic_Subprogram_Declaration
,
1273 N_Package_Declaration
,
1274 N_Package_Renaming_Declaration
,
1275 N_Subprogram_Declaration
,
1276 N_Subprogram_Renaming_Declaration
)
1277 and then Present
(Parent_Spec
(N
))
1279 Par_Id
:= Defining_Entity
(Unit
(Parent_Spec
(N
)));
1281 if Is_Checked_Ghost_Entity
(Par_Id
) then
1282 Policy
:= Name_Check
;
1284 elsif Is_Ignored_Ghost_Entity
(Par_Id
) then
1285 Policy
:= Name_Ignore
;
1289 -- Mark the declaration and its formals as Ghost
1291 Mark_Ghost_Declaration_Or_Body
(N
, Policy
);
1293 -- Install the appropriate Ghost mode
1295 Install_Ghost_Mode
(Policy
);
1296 end Mark_And_Set_Ghost_Declaration
;
1298 --------------------------------------
1299 -- Mark_And_Set_Ghost_Instantiation --
1300 --------------------------------------
1302 procedure Mark_And_Set_Ghost_Instantiation
1306 procedure Check_Ghost_Actuals
;
1307 -- Check the context of ghost actuals
1309 -------------------------
1310 -- Check_Ghost_Actuals --
1311 -------------------------
1313 procedure Check_Ghost_Actuals
is
1314 Assoc
: Node_Id
:= First
(Generic_Associations
(N
));
1318 while Present
(Assoc
) loop
1319 if Nkind
(Assoc
) /= N_Others_Choice
then
1320 Act
:= Explicit_Generic_Actual_Parameter
(Assoc
);
1322 -- Within a nested instantiation, a defaulted actual is an
1323 -- empty association, so nothing to check.
1328 elsif Comes_From_Source
(Act
)
1329 and then Nkind
(Act
) in N_Has_Etype
1330 and then Present
(Etype
(Act
))
1331 and then Is_Ghost_Entity
(Etype
(Act
))
1333 Check_Ghost_Context
(Etype
(Act
), Act
);
1339 end Check_Ghost_Actuals
;
1343 Policy
: Name_Id
:= No_Name
;
1346 -- An instantiation becomes Ghost when it is subject to pragma Ghost
1348 if Is_Subject_To_Ghost
(N
) then
1349 Policy
:= Policy_In_Effect
(Name_Ghost
);
1351 -- An instantiation declaration within a Ghost region is automatically
1352 -- Ghost (SPARK RM 6.9(2)).
1354 elsif Ghost_Mode
= Check
then
1355 Policy
:= Name_Check
;
1357 elsif Ghost_Mode
= Ignore
then
1358 Policy
:= Name_Ignore
;
1360 -- Inherit the "ghostness" of the generic unit
1362 elsif Is_Checked_Ghost_Entity
(Gen_Id
) then
1363 Policy
:= Name_Check
;
1365 elsif Is_Ignored_Ghost_Entity
(Gen_Id
) then
1366 Policy
:= Name_Ignore
;
1369 -- Mark the instantiation as Ghost
1371 Mark_Ghost_Declaration_Or_Body
(N
, Policy
);
1373 -- Install the appropriate Ghost mode
1375 Install_Ghost_Mode
(Policy
);
1377 -- Check ghost actuals. Given that this routine is unconditionally
1378 -- invoked with subprogram and package instantiations, this check
1379 -- verifies the context of all the ghost entities passed in generic
1382 Check_Ghost_Actuals
;
1383 end Mark_And_Set_Ghost_Instantiation
;
1385 ---------------------------------------
1386 -- Mark_And_Set_Ghost_Procedure_Call --
1387 ---------------------------------------
1389 procedure Mark_And_Set_Ghost_Procedure_Call
(N
: Node_Id
) is
1393 -- A procedure call becomes Ghost when the procedure being invoked is
1394 -- Ghost. Install the Ghost mode of the procedure.
1396 Id
:= Ghost_Entity
(Name
(N
));
1398 if Present
(Id
) then
1399 if Is_Checked_Ghost_Entity
(Id
) then
1400 Install_Ghost_Mode
(Check
);
1402 elsif Is_Ignored_Ghost_Entity
(Id
) then
1403 Install_Ghost_Mode
(Ignore
);
1405 Set_Is_Ignored_Ghost_Node
(N
);
1406 Propagate_Ignored_Ghost_Code
(N
);
1409 end Mark_And_Set_Ghost_Procedure_Call
;
1411 ------------------------------------
1412 -- Mark_Ghost_Declaration_Or_Body --
1413 ------------------------------------
1415 procedure Mark_Ghost_Declaration_Or_Body
1419 Id
: constant Entity_Id
:= Defining_Entity
(N
);
1421 Mark_Formals
: Boolean := False;
1423 Param_Id
: Entity_Id
;
1426 -- Mark the related node and its entity
1428 if Mode
= Name_Check
then
1429 Mark_Formals
:= True;
1430 Set_Is_Checked_Ghost_Entity
(Id
);
1432 elsif Mode
= Name_Ignore
then
1433 Mark_Formals
:= True;
1434 Set_Is_Ignored_Ghost_Entity
(Id
);
1435 Set_Is_Ignored_Ghost_Node
(N
);
1436 Propagate_Ignored_Ghost_Code
(N
);
1439 -- Mark all formal parameters when the related node denotes a subprogram
1440 -- or a body. The traversal is performed via the specification because
1441 -- the related subprogram or body may be unanalyzed.
1443 -- ??? could extra formal parameters cause a Ghost leak?
1446 and then Nkind_In
(N
, N_Abstract_Subprogram_Declaration
,
1447 N_Formal_Abstract_Subprogram_Declaration
,
1448 N_Formal_Concrete_Subprogram_Declaration
,
1449 N_Generic_Subprogram_Declaration
,
1451 N_Subprogram_Body_Stub
,
1452 N_Subprogram_Declaration
,
1453 N_Subprogram_Renaming_Declaration
)
1455 Param
:= First
(Parameter_Specifications
(Specification
(N
)));
1456 while Present
(Param
) loop
1457 Param_Id
:= Defining_Entity
(Param
);
1459 if Mode
= Name_Check
then
1460 Set_Is_Checked_Ghost_Entity
(Param_Id
);
1462 elsif Mode
= Name_Ignore
then
1463 Set_Is_Ignored_Ghost_Entity
(Param_Id
);
1469 end Mark_Ghost_Declaration_Or_Body
;
1471 -----------------------
1472 -- Mark_Ghost_Clause --
1473 -----------------------
1475 procedure Mark_Ghost_Clause
(N
: Node_Id
) is
1476 Nam
: Node_Id
:= Empty
;
1479 if Nkind
(N
) = N_Use_Package_Clause
then
1482 elsif Nkind
(N
) = N_Use_Type_Clause
then
1483 Nam
:= Subtype_Mark
(N
);
1485 elsif Nkind
(N
) = N_With_Clause
then
1490 and then Is_Entity_Name
(Nam
)
1491 and then Present
(Entity
(Nam
))
1492 and then Is_Ignored_Ghost_Entity
(Entity
(Nam
))
1494 Set_Is_Ignored_Ghost_Node
(N
);
1495 Propagate_Ignored_Ghost_Code
(N
);
1497 end Mark_Ghost_Clause
;
1499 -----------------------
1500 -- Mark_Ghost_Pragma --
1501 -----------------------
1503 procedure Mark_Ghost_Pragma
1508 -- A pragma becomes Ghost when it encloses a Ghost entity or relates to
1511 if Is_Checked_Ghost_Entity
(Id
) then
1512 Set_Is_Checked_Ghost_Pragma
(N
);
1514 elsif Is_Ignored_Ghost_Entity
(Id
) then
1515 Set_Is_Ignored_Ghost_Pragma
(N
);
1516 Set_Is_Ignored_Ghost_Node
(N
);
1517 Propagate_Ignored_Ghost_Code
(N
);
1519 end Mark_Ghost_Pragma
;
1521 -------------------------
1522 -- Mark_Ghost_Renaming --
1523 -------------------------
1525 procedure Mark_Ghost_Renaming
1529 Policy
: Name_Id
:= No_Name
;
1532 -- A renaming becomes Ghost when it renames a Ghost entity
1534 if Is_Checked_Ghost_Entity
(Id
) then
1535 Policy
:= Name_Check
;
1537 elsif Is_Ignored_Ghost_Entity
(Id
) then
1538 Policy
:= Name_Ignore
;
1541 Mark_Ghost_Declaration_Or_Body
(N
, Policy
);
1542 end Mark_Ghost_Renaming
;
1544 ----------------------------------
1545 -- Propagate_Ignored_Ghost_Code --
1546 ----------------------------------
1548 procedure Propagate_Ignored_Ghost_Code
(N
: Node_Id
) is
1553 -- Traverse the parent chain looking for blocks, packages, and
1554 -- subprograms or their respective bodies.
1557 while Present
(Nod
) loop
1560 if Nkind
(Nod
) = N_Block_Statement
1561 and then Present
(Identifier
(Nod
))
1563 Scop
:= Entity
(Identifier
(Nod
));
1565 elsif Nkind_In
(Nod
, N_Package_Body
,
1566 N_Package_Declaration
,
1568 N_Subprogram_Declaration
)
1570 Scop
:= Defining_Entity
(Nod
);
1573 -- The current node denotes a scoping construct
1575 if Present
(Scop
) then
1577 -- Stop the traversal when the scope already contains ignored
1578 -- Ghost code as all enclosing scopes have already been marked.
1580 if Contains_Ignored_Ghost_Code
(Scop
) then
1583 -- Otherwise mark this scope and keep climbing
1586 Set_Contains_Ignored_Ghost_Code
(Scop
);
1590 Nod
:= Parent
(Nod
);
1593 -- The unit containing the ignored Ghost code must be post processed
1594 -- before invoking the back end.
1596 Add_Ignored_Ghost_Unit
(Cunit
(Get_Code_Unit
(N
)));
1597 end Propagate_Ignored_Ghost_Code
;
1599 -------------------------------
1600 -- Remove_Ignored_Ghost_Code --
1601 -------------------------------
1603 procedure Remove_Ignored_Ghost_Code
is
1604 procedure Prune_Tree
(Root
: Node_Id
);
1605 -- Remove all code marked as ignored Ghost from the tree of denoted by
1612 procedure Prune_Tree
(Root
: Node_Id
) is
1613 procedure Prune
(N
: Node_Id
);
1614 -- Remove a given node from the tree by rewriting it into null
1616 function Prune_Node
(N
: Node_Id
) return Traverse_Result
;
1617 -- Determine whether node N denotes an ignored Ghost construct. If
1618 -- this is the case, rewrite N as a null statement. See the body for
1625 procedure Prune
(N
: Node_Id
) is
1627 -- Destroy any aspects that may be associated with the node
1629 if Permits_Aspect_Specifications
(N
) and then Has_Aspects
(N
) then
1633 Rewrite
(N
, Make_Null_Statement
(Sloc
(N
)));
1640 function Prune_Node
(N
: Node_Id
) return Traverse_Result
is
1644 -- Do not prune compilation unit nodes because many mechanisms
1645 -- depend on their presence. Note that context items are still
1648 if Nkind
(N
) = N_Compilation_Unit
then
1651 -- The node is either declared as ignored Ghost or is a byproduct
1652 -- of expansion. Destroy it and stop the traversal on this branch.
1654 elsif Is_Ignored_Ghost_Node
(N
) then
1658 -- Scoping constructs such as blocks, packages, subprograms and
1659 -- bodies offer some flexibility with respect to pruning.
1661 elsif Nkind_In
(N
, N_Block_Statement
,
1663 N_Package_Declaration
,
1665 N_Subprogram_Declaration
)
1667 if Nkind
(N
) = N_Block_Statement
then
1668 Id
:= Entity
(Identifier
(N
));
1670 Id
:= Defining_Entity
(N
);
1673 -- The scoping construct contains both living and ignored Ghost
1674 -- code, let the traversal prune all relevant nodes.
1676 if Contains_Ignored_Ghost_Code
(Id
) then
1679 -- Otherwise the construct contains only living code and should
1686 -- Otherwise keep searching for ignored Ghost nodes
1693 procedure Prune_Nodes
is new Traverse_Proc
(Prune_Node
);
1695 -- Start of processing for Prune_Tree
1701 -- Start of processing for Remove_Ignored_Ghost_Code
1704 for Index
in Ignored_Ghost_Units
.First
.. Ignored_Ghost_Units
.Last
loop
1705 Prune_Tree
(Ignored_Ghost_Units
.Table
(Index
));
1707 end Remove_Ignored_Ghost_Code
;
1709 ------------------------
1710 -- Restore_Ghost_Mode --
1711 ------------------------
1713 procedure Restore_Ghost_Mode
(Mode
: Ghost_Mode_Type
) is
1716 end Restore_Ghost_Mode
;
1718 --------------------
1719 -- Set_Ghost_Mode --
1720 --------------------
1722 procedure Set_Ghost_Mode
(N
: Node_Or_Entity_Id
) is
1723 procedure Set_Ghost_Mode_From_Entity
(Id
: Entity_Id
);
1724 -- Install the Ghost mode of entity Id
1726 --------------------------------
1727 -- Set_Ghost_Mode_From_Entity --
1728 --------------------------------
1730 procedure Set_Ghost_Mode_From_Entity
(Id
: Entity_Id
) is
1732 if Is_Checked_Ghost_Entity
(Id
) then
1733 Install_Ghost_Mode
(Check
);
1734 elsif Is_Ignored_Ghost_Entity
(Id
) then
1735 Install_Ghost_Mode
(Ignore
);
1737 Install_Ghost_Mode
(None
);
1739 end Set_Ghost_Mode_From_Entity
;
1745 -- Start of processing for Set_Ghost_Mode
1748 -- The Ghost mode of an assignment statement depends on the Ghost mode
1751 if Nkind
(N
) = N_Assignment_Statement
then
1752 Id
:= Ghost_Entity
(Name
(N
));
1754 if Present
(Id
) then
1755 Set_Ghost_Mode_From_Entity
(Id
);
1758 -- The Ghost mode of a body or a declaration depends on the Ghost mode
1759 -- of its defining entity.
1761 elsif Is_Body
(N
) or else Is_Declaration
(N
) then
1762 Set_Ghost_Mode_From_Entity
(Defining_Entity
(N
));
1764 -- The Ghost mode of an entity depends on the entity itself
1766 elsif Nkind
(N
) in N_Entity
then
1767 Set_Ghost_Mode_From_Entity
(N
);
1769 -- The Ghost mode of a [generic] freeze node depends on the Ghost mode
1770 -- of the entity being frozen.
1772 elsif Nkind_In
(N
, N_Freeze_Entity
, N_Freeze_Generic_Entity
) then
1773 Set_Ghost_Mode_From_Entity
(Entity
(N
));
1775 -- The Ghost mode of a pragma depends on the associated entity. The
1776 -- property is encoded in the pragma itself.
1778 elsif Nkind
(N
) = N_Pragma
then
1779 if Is_Checked_Ghost_Pragma
(N
) then
1780 Install_Ghost_Mode
(Check
);
1781 elsif Is_Ignored_Ghost_Pragma
(N
) then
1782 Install_Ghost_Mode
(Ignore
);
1784 Install_Ghost_Mode
(None
);
1787 -- The Ghost mode of a procedure call depends on the Ghost mode of the
1788 -- procedure being invoked.
1790 elsif Nkind
(N
) = N_Procedure_Call_Statement
then
1791 Id
:= Ghost_Entity
(Name
(N
));
1793 if Present
(Id
) then
1794 Set_Ghost_Mode_From_Entity
(Id
);
1799 -------------------------
1800 -- Set_Is_Ghost_Entity --
1801 -------------------------
1803 procedure Set_Is_Ghost_Entity
(Id
: Entity_Id
) is
1804 Policy
: constant Name_Id
:= Policy_In_Effect
(Name_Ghost
);
1806 if Policy
= Name_Check
then
1807 Set_Is_Checked_Ghost_Entity
(Id
);
1808 elsif Policy
= Name_Ignore
then
1809 Set_Is_Ignored_Ghost_Entity
(Id
);
1811 end Set_Is_Ghost_Entity
;