PR c/79855: add full stop to store merging param descriptions
[official-gcc.git] / gcc / ada / ghost.adb
blobec4c1d646c427a4b3bd24ea332e154e94e1c7aed
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- G H O S T --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2014-2016, Free Software Foundation, Inc. --
10 -- --
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. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
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;
32 with Lib; use Lib;
33 with Namet; use Namet;
34 with Nlists; use Nlists;
35 with Nmake; use Nmake;
36 with Sem; use Sem;
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;
45 with Table;
47 package body Ghost is
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
52 -- units.
54 package Ignored_Ghost_Units is new Table.Table (
55 Table_Component_Type => Node_Id,
56 Table_Index_Type => Int,
57 Table_Low_Bound => 0,
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
68 -- is no such entity.
70 procedure Install_Ghost_Mode (Mode : Name_Id);
71 -- Install a specific Ghost mode denoted by Mode by setting global variable
72 -- Ghost_Mode.
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"
78 -- of N.
80 procedure Mark_Ghost_Declaration_Or_Body
81 (N : Node_Id;
82 Mode : Name_Id);
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
85 -- body.
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
97 begin
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
106 loop
107 -- If the unit is already present in the table, do not add it again
109 if Unit = Ignored_Ghost_Units.Table (Index) then
110 return;
111 end if;
112 end loop;
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);
129 begin
130 -- Nothing to do if one of the views is missing
132 if No (Prev_Id) or else No (Compl_Id) then
133 null;
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
140 then
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
149 then
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);
155 end if;
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
213 -- body.
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);
222 begin
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.
227 return
228 (Nkind (N) = N_Parameter_Specification
229 or else
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;
235 -- Local variables
237 Subp_Decl : Node_Id;
238 Subp_Id : Entity_Id;
240 -- Start of processing for Is_OK_Declaration
242 begin
243 if Is_Ghost_Declaration (Decl) then
244 return True;
246 -- Special cases
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
254 return True;
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)
264 then
265 return True;
267 -- References to Ghost entities may be relocated in internally
268 -- generated bodies.
270 elsif Nkind (Decl) = N_Subprogram_Body
271 and then not Comes_From_Source (Decl)
272 then
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
282 return True;
284 else
285 Subp_Decl :=
286 Original_Node (Unit_Declaration_Node (Subp_Id));
288 -- The original context is an expression function that
289 -- has been split into a spec and a body. The context is
290 -- OK as long as the initial declaration is Ghost.
292 if Nkind (Subp_Decl) = N_Expression_Function then
293 return Is_Ghost_Declaration (Subp_Decl);
294 end if;
295 end if;
297 -- Otherwise this is either an internal body or an internal
298 -- completion. Both are OK because the real check was done
299 -- before expansion activities.
301 else
302 return True;
303 end if;
304 end if;
306 return False;
307 end Is_OK_Declaration;
309 ------------------
310 -- Is_OK_Pragma --
311 ------------------
313 function Is_OK_Pragma (Prag : Node_Id) return Boolean is
314 procedure Check_Policies (Prag_Nam : Name_Id);
315 -- Verify that the Ghost policy in effect is the same as the
316 -- assertion policy for pragma name Prag_Nam. Emit an error if
317 -- this is not the case.
319 --------------------
320 -- Check_Policies --
321 --------------------
323 procedure Check_Policies (Prag_Nam : Name_Id) is
324 AP : constant Name_Id := Check_Kind (Prag_Nam);
325 GP : constant Name_Id := Policy_In_Effect (Name_Ghost);
327 begin
328 -- If the Ghost policy in effect at the point of a Ghost entity
329 -- reference is Ignore, then the assertion policy of the pragma
330 -- must be Ignore (SPARK RM 6.9(18)).
332 if GP = Name_Ignore and then AP /= Name_Ignore then
333 Error_Msg_N
334 ("incompatible ghost policies in effect",
335 Ghost_Ref);
336 Error_Msg_NE
337 ("\ghost entity & has policy `Ignore`",
338 Ghost_Ref, Ghost_Id);
340 Error_Msg_Name_1 := AP;
341 Error_Msg_N
342 ("\assertion expression has policy %", Ghost_Ref);
343 end if;
344 end Check_Policies;
346 -- Local variables
348 Prag_Id : Pragma_Id;
349 Prag_Nam : Name_Id;
351 -- Start of processing for Is_OK_Pragma
353 begin
354 if Nkind (Prag) = N_Pragma then
355 Prag_Id := Get_Pragma_Id (Prag);
356 Prag_Nam := Original_Aspect_Pragma_Name (Prag);
358 -- A pragma that applies to a Ghost construct or specifies an
359 -- aspect of a Ghost entity is a Ghost pragma (SPARK RM 6.9(3))
361 if Is_Ghost_Pragma (Prag) then
362 return True;
364 -- An assertion expression pragma is Ghost when it contains a
365 -- reference to a Ghost entity (SPARK RM 6.9(10)).
367 elsif Assertion_Expression_Pragma (Prag_Id) then
369 -- Ensure that the assertion policy and the Ghost policy are
370 -- compatible (SPARK RM 6.9(18)).
372 Check_Policies (Prag_Nam);
373 return True;
375 -- Several pragmas that may apply to a non-Ghost entity are
376 -- treated as Ghost when they contain a reference to a Ghost
377 -- entity (SPARK RM 6.9(11)).
379 elsif Nam_In (Prag_Nam, Name_Global,
380 Name_Depends,
381 Name_Initializes,
382 Name_Refined_Global,
383 Name_Refined_Depends,
384 Name_Refined_State)
385 then
386 return True;
387 end if;
388 end if;
390 return False;
391 end Is_OK_Pragma;
393 ---------------------
394 -- Is_OK_Statement --
395 ---------------------
397 function Is_OK_Statement (Stmt : Node_Id) return Boolean is
398 begin
399 -- An assignment statement is Ghost when the target is a Ghost
400 -- entity.
402 if Nkind (Stmt) = N_Assignment_Statement then
403 return Is_Ghost_Assignment (Stmt);
405 -- A procedure call is Ghost when it calls a Ghost procedure
407 elsif Nkind (Stmt) = N_Procedure_Call_Statement then
408 return Is_Ghost_Procedure_Call (Stmt);
410 -- Special cases
412 -- An if statement is a suitable context for a Ghost entity if it
413 -- is the byproduct of assertion expression expansion. Note that
414 -- the assertion expression may not be related to a Ghost entity,
415 -- but it may still contain references to Ghost entities.
417 elsif Nkind (Stmt) = N_If_Statement
418 and then Nkind (Original_Node (Stmt)) = N_Pragma
419 and then Assertion_Expression_Pragma
420 (Get_Pragma_Id (Original_Node (Stmt)))
421 then
422 return True;
423 end if;
425 return False;
426 end Is_OK_Statement;
428 -- Local variables
430 Par : Node_Id;
432 -- Start of processing for Is_OK_Ghost_Context
434 begin
435 -- The context is Ghost when it appears within a Ghost package or
436 -- subprogram.
438 if Ghost_Mode > None then
439 return True;
441 -- A Ghost type may be referenced in a use_type clause
442 -- (SPARK RM 6.9.10).
444 elsif Present (Parent (Context))
445 and then Nkind (Parent (Context)) = N_Use_Type_Clause
446 then
447 return True;
449 -- Routine Expand_Record_Extension creates a parent subtype without
450 -- inserting it into the tree. There is no good way of recognizing
451 -- this special case as there is no parent. Try to approximate the
452 -- context.
454 elsif No (Parent (Context)) and then Is_Tagged_Type (Ghost_Id) then
455 return True;
457 -- Otherwise climb the parent chain looking for a suitable Ghost
458 -- context.
460 else
461 Par := Context;
462 while Present (Par) loop
463 if Is_Ignored_Ghost_Node (Par) then
464 return True;
466 -- A reference to a Ghost entity can appear within an aspect
467 -- specification (SPARK RM 6.9(10)).
469 elsif Nkind (Par) = N_Aspect_Specification then
470 return True;
472 elsif Is_OK_Declaration (Par) then
473 return True;
475 elsif Is_OK_Pragma (Par) then
476 return True;
478 elsif Is_OK_Statement (Par) then
479 return True;
481 -- Prevent the search from going too far
483 elsif Is_Body_Or_Package_Declaration (Par) then
484 exit;
485 end if;
487 Par := Parent (Par);
488 end loop;
490 -- The expansion of assertion expression pragmas and attribute Old
491 -- may cause a legal Ghost entity reference to become illegal due
492 -- to node relocation. Check the In_Assertion_Expr counter as last
493 -- resort to try and infer the original legal context.
495 if In_Assertion_Expr > 0 then
496 return True;
498 -- Otherwise the context is not suitable for a reference to a
499 -- Ghost entity.
501 else
502 return False;
503 end if;
504 end if;
505 end Is_OK_Ghost_Context;
507 ------------------------
508 -- Check_Ghost_Policy --
509 ------------------------
511 procedure Check_Ghost_Policy (Id : Entity_Id; Ref : Node_Id) is
512 Policy : constant Name_Id := Policy_In_Effect (Name_Ghost);
514 begin
515 -- The Ghost policy in effect a the point of declaration and at the
516 -- point of use must match (SPARK RM 6.9(13)).
518 if Is_Checked_Ghost_Entity (Id)
519 and then Policy = Name_Ignore
520 and then May_Be_Lvalue (Ref)
521 then
522 Error_Msg_Sloc := Sloc (Ref);
524 Error_Msg_N ("incompatible ghost policies in effect", Ref);
525 Error_Msg_NE ("\& declared with ghost policy `Check`", Ref, Id);
526 Error_Msg_NE ("\& used # with ghost policy `Ignore`", Ref, Id);
528 elsif Is_Ignored_Ghost_Entity (Id) and then Policy = Name_Check then
529 Error_Msg_Sloc := Sloc (Ref);
531 Error_Msg_N ("incompatible ghost policies in effect", Ref);
532 Error_Msg_NE ("\& declared with ghost policy `Ignore`", Ref, Id);
533 Error_Msg_NE ("\& used # with ghost policy `Check`", Ref, Id);
534 end if;
535 end Check_Ghost_Policy;
537 -- Start of processing for Check_Ghost_Context
539 begin
540 -- Once it has been established that the reference to the Ghost entity
541 -- is within a suitable context, ensure that the policy at the point of
542 -- declaration and at the point of use match.
544 if Is_OK_Ghost_Context (Ghost_Ref) then
545 Check_Ghost_Policy (Ghost_Id, Ghost_Ref);
547 -- Otherwise the Ghost entity appears in a non-Ghost context and affects
548 -- its behavior or value (SPARK RM 6.9(10,11)).
550 else
551 Error_Msg_N ("ghost entity cannot appear in this context", Ghost_Ref);
552 end if;
553 end Check_Ghost_Context;
555 ----------------------------
556 -- Check_Ghost_Overriding --
557 ----------------------------
559 procedure Check_Ghost_Overriding
560 (Subp : Entity_Id;
561 Overridden_Subp : Entity_Id)
563 Deriv_Typ : Entity_Id;
564 Over_Subp : Entity_Id;
566 begin
567 if Present (Subp) and then Present (Overridden_Subp) then
568 Over_Subp := Ultimate_Alias (Overridden_Subp);
569 Deriv_Typ := Find_Dispatching_Type (Subp);
571 -- A Ghost primitive of a non-Ghost type extension cannot override an
572 -- inherited non-Ghost primitive (SPARK RM 6.9(8)).
574 if Is_Ghost_Entity (Subp)
575 and then Present (Deriv_Typ)
576 and then not Is_Ghost_Entity (Deriv_Typ)
577 and then not Is_Ghost_Entity (Over_Subp)
578 and then not Is_Abstract_Subprogram (Over_Subp)
579 then
580 Error_Msg_N ("incompatible overriding in effect", Subp);
582 Error_Msg_Sloc := Sloc (Over_Subp);
583 Error_Msg_N ("\& declared # as non-ghost subprogram", Subp);
585 Error_Msg_Sloc := Sloc (Subp);
586 Error_Msg_N ("\overridden # with ghost subprogram", Subp);
587 end if;
589 -- A non-Ghost primitive of a type extension cannot override an
590 -- inherited Ghost primitive (SPARK RM 6.9(8)).
592 if Is_Ghost_Entity (Over_Subp)
593 and then not Is_Ghost_Entity (Subp)
594 and then not Is_Abstract_Subprogram (Subp)
595 then
596 Error_Msg_N ("incompatible overriding in effect", Subp);
598 Error_Msg_Sloc := Sloc (Over_Subp);
599 Error_Msg_N ("\& declared # as ghost subprogram", Subp);
601 Error_Msg_Sloc := Sloc (Subp);
602 Error_Msg_N ("\overridden # with non-ghost subprogram", Subp);
603 end if;
605 if Present (Deriv_Typ)
606 and then not Is_Ignored_Ghost_Entity (Deriv_Typ)
607 then
608 -- When a tagged type is either non-Ghost or checked Ghost and
609 -- one of its primitives overrides an inherited operation, the
610 -- overridden operation of the ancestor type must be ignored Ghost
611 -- if the primitive is ignored Ghost (SPARK RM 6.9(17)).
613 if Is_Ignored_Ghost_Entity (Subp) then
615 -- Both the parent subprogram and overriding subprogram are
616 -- ignored Ghost.
618 if Is_Ignored_Ghost_Entity (Over_Subp) then
619 null;
621 -- The parent subprogram carries policy Check
623 elsif Is_Checked_Ghost_Entity (Over_Subp) then
624 Error_Msg_N
625 ("incompatible ghost policies in effect", Subp);
627 Error_Msg_Sloc := Sloc (Over_Subp);
628 Error_Msg_N
629 ("\& declared # with ghost policy `Check`", Subp);
631 Error_Msg_Sloc := Sloc (Subp);
632 Error_Msg_N
633 ("\overridden # with ghost policy `Ignore`", Subp);
635 -- The parent subprogram is non-Ghost
637 else
638 Error_Msg_N
639 ("incompatible ghost policies in effect", Subp);
641 Error_Msg_Sloc := Sloc (Over_Subp);
642 Error_Msg_N ("\& declared # as non-ghost subprogram", Subp);
644 Error_Msg_Sloc := Sloc (Subp);
645 Error_Msg_N
646 ("\overridden # with ghost policy `Ignore`", Subp);
647 end if;
649 -- When a tagged type is either non-Ghost or checked Ghost and
650 -- one of its primitives overrides an inherited operation, the
651 -- the primitive of the tagged type must be ignored Ghost if the
652 -- overridden operation is ignored Ghost (SPARK RM 6.9(17)).
654 elsif Is_Ignored_Ghost_Entity (Over_Subp) then
656 -- Both the parent subprogram and the overriding subprogram are
657 -- ignored Ghost.
659 if Is_Ignored_Ghost_Entity (Subp) then
660 null;
662 -- The overriding subprogram carries policy Check
664 elsif Is_Checked_Ghost_Entity (Subp) then
665 Error_Msg_N
666 ("incompatible ghost policies in effect", Subp);
668 Error_Msg_Sloc := Sloc (Over_Subp);
669 Error_Msg_N
670 ("\& declared # with ghost policy `Ignore`", Subp);
672 Error_Msg_Sloc := Sloc (Subp);
673 Error_Msg_N
674 ("\overridden # with Ghost policy `Check`", Subp);
676 -- The overriding subprogram is non-Ghost
678 else
679 Error_Msg_N
680 ("incompatible ghost policies in effect", Subp);
682 Error_Msg_Sloc := Sloc (Over_Subp);
683 Error_Msg_N
684 ("\& declared # with ghost policy `Ignore`", Subp);
686 Error_Msg_Sloc := Sloc (Subp);
687 Error_Msg_N
688 ("\overridden # with non-ghost subprogram", Subp);
689 end if;
690 end if;
691 end if;
692 end if;
693 end Check_Ghost_Overriding;
695 ---------------------------
696 -- Check_Ghost_Primitive --
697 ---------------------------
699 procedure Check_Ghost_Primitive (Prim : Entity_Id; Typ : Entity_Id) is
700 begin
701 -- The Ghost policy in effect at the point of declaration of a primitive
702 -- operation and a tagged type must match (SPARK RM 6.9(16)).
704 if Is_Tagged_Type (Typ) then
705 if Is_Checked_Ghost_Entity (Prim)
706 and then Is_Ignored_Ghost_Entity (Typ)
707 then
708 Error_Msg_N ("incompatible ghost policies in effect", Prim);
710 Error_Msg_Sloc := Sloc (Typ);
711 Error_Msg_NE
712 ("\tagged type & declared # with ghost policy `Ignore`",
713 Prim, Typ);
715 Error_Msg_Sloc := Sloc (Prim);
716 Error_Msg_N
717 ("\primitive subprogram & declared # with ghost policy `Check`",
718 Prim);
720 elsif Is_Ignored_Ghost_Entity (Prim)
721 and then Is_Checked_Ghost_Entity (Typ)
722 then
723 Error_Msg_N ("incompatible ghost policies in effect", Prim);
725 Error_Msg_Sloc := Sloc (Typ);
726 Error_Msg_NE
727 ("\tagged type & declared # with ghost policy `Check`",
728 Prim, Typ);
730 Error_Msg_Sloc := Sloc (Prim);
731 Error_Msg_N
732 ("\primitive subprogram & declared # with ghost policy `Ignore`",
733 Prim);
734 end if;
735 end if;
736 end Check_Ghost_Primitive;
738 ----------------------------
739 -- Check_Ghost_Refinement --
740 ----------------------------
742 procedure Check_Ghost_Refinement
743 (State : Node_Id;
744 State_Id : Entity_Id;
745 Constit : Node_Id;
746 Constit_Id : Entity_Id)
748 begin
749 if Is_Ghost_Entity (State_Id) then
750 if Is_Ghost_Entity (Constit_Id) then
752 -- The Ghost policy in effect at the point of abstract state
753 -- declaration and constituent must match (SPARK RM 6.9(15)).
755 if Is_Checked_Ghost_Entity (State_Id)
756 and then Is_Ignored_Ghost_Entity (Constit_Id)
757 then
758 Error_Msg_Sloc := Sloc (Constit);
759 SPARK_Msg_N ("incompatible ghost policies in effect", State);
761 SPARK_Msg_NE
762 ("\abstract state & declared with ghost policy `Check`",
763 State, State_Id);
764 SPARK_Msg_NE
765 ("\constituent & declared # with ghost policy `Ignore`",
766 State, Constit_Id);
768 elsif Is_Ignored_Ghost_Entity (State_Id)
769 and then Is_Checked_Ghost_Entity (Constit_Id)
770 then
771 Error_Msg_Sloc := Sloc (Constit);
772 SPARK_Msg_N ("incompatible ghost policies in effect", State);
774 SPARK_Msg_NE
775 ("\abstract state & declared with ghost policy `Ignore`",
776 State, State_Id);
777 SPARK_Msg_NE
778 ("\constituent & declared # with ghost policy `Check`",
779 State, Constit_Id);
780 end if;
782 -- A constituent of a Ghost abstract state must be a Ghost entity
783 -- (SPARK RM 7.2.2(12)).
785 else
786 SPARK_Msg_NE
787 ("constituent of ghost state & must be ghost",
788 Constit, State_Id);
789 end if;
790 end if;
791 end Check_Ghost_Refinement;
793 ------------------
794 -- Ghost_Entity --
795 ------------------
797 function Ghost_Entity (N : Node_Id) return Entity_Id is
798 Ref : Node_Id;
800 begin
801 -- When the reference denotes a subcomponent, recover the related
802 -- object (SPARK RM 6.9(1)).
804 Ref := N;
805 while Nkind_In (Ref, N_Explicit_Dereference,
806 N_Indexed_Component,
807 N_Selected_Component,
808 N_Slice)
809 loop
810 Ref := Prefix (Ref);
811 end loop;
813 if Is_Entity_Name (Ref) then
814 return Entity (Ref);
815 else
816 return Empty;
817 end if;
818 end Ghost_Entity;
820 --------------------------------
821 -- Implements_Ghost_Interface --
822 --------------------------------
824 function Implements_Ghost_Interface (Typ : Entity_Id) return Boolean is
825 Iface_Elmt : Elmt_Id;
827 begin
828 -- Traverse the list of interfaces looking for a Ghost interface
830 if Is_Tagged_Type (Typ) and then Present (Interfaces (Typ)) then
831 Iface_Elmt := First_Elmt (Interfaces (Typ));
832 while Present (Iface_Elmt) loop
833 if Is_Ghost_Entity (Node (Iface_Elmt)) then
834 return True;
835 end if;
837 Next_Elmt (Iface_Elmt);
838 end loop;
839 end if;
841 return False;
842 end Implements_Ghost_Interface;
844 ----------------
845 -- Initialize --
846 ----------------
848 procedure Initialize is
849 begin
850 Ignored_Ghost_Units.Init;
851 end Initialize;
853 ------------------------
854 -- Install_Ghost_Mode --
855 ------------------------
857 procedure Install_Ghost_Mode (Mode : Ghost_Mode_Type) is
858 begin
859 Ghost_Mode := Mode;
860 end Install_Ghost_Mode;
862 procedure Install_Ghost_Mode (Mode : Name_Id) is
863 begin
864 if Mode = Name_Check then
865 Ghost_Mode := Check;
867 elsif Mode = Name_Ignore then
868 Ghost_Mode := Ignore;
870 elsif Mode = Name_None then
871 Ghost_Mode := None;
872 end if;
873 end Install_Ghost_Mode;
875 -------------------------
876 -- Is_Ghost_Assignment --
877 -------------------------
879 function Is_Ghost_Assignment (N : Node_Id) return Boolean is
880 Id : Entity_Id;
882 begin
883 -- An assignment statement is Ghost when its target denotes a Ghost
884 -- entity.
886 if Nkind (N) = N_Assignment_Statement then
887 Id := Ghost_Entity (Name (N));
889 return Present (Id) and then Is_Ghost_Entity (Id);
890 end if;
892 return False;
893 end Is_Ghost_Assignment;
895 --------------------------
896 -- Is_Ghost_Declaration --
897 --------------------------
899 function Is_Ghost_Declaration (N : Node_Id) return Boolean is
900 Id : Entity_Id;
902 begin
903 -- A declaration is Ghost when it elaborates a Ghost entity or is
904 -- subject to pragma Ghost.
906 if Is_Declaration (N) then
907 Id := Defining_Entity (N);
909 return Is_Ghost_Entity (Id) or else Is_Subject_To_Ghost (N);
910 end if;
912 return False;
913 end Is_Ghost_Declaration;
915 ---------------------
916 -- Is_Ghost_Pragma --
917 ---------------------
919 function Is_Ghost_Pragma (N : Node_Id) return Boolean is
920 begin
921 return Is_Checked_Ghost_Pragma (N) or else Is_Ignored_Ghost_Pragma (N);
922 end Is_Ghost_Pragma;
924 -----------------------------
925 -- Is_Ghost_Procedure_Call --
926 -----------------------------
928 function Is_Ghost_Procedure_Call (N : Node_Id) return Boolean is
929 Id : Entity_Id;
931 begin
932 -- A procedure call is Ghost when it invokes a Ghost procedure
934 if Nkind (N) = N_Procedure_Call_Statement then
935 Id := Ghost_Entity (Name (N));
937 return Present (Id) and then Is_Ghost_Entity (Id);
938 end if;
940 return False;
941 end Is_Ghost_Procedure_Call;
943 ---------------------------
944 -- Is_Ignored_Ghost_Unit --
945 ---------------------------
947 function Is_Ignored_Ghost_Unit (N : Node_Id) return Boolean is
948 begin
949 -- Inspect the original node of the unit in case removal of ignored
950 -- Ghost code has already taken place.
952 return
953 Nkind (N) = N_Compilation_Unit
954 and then Is_Ignored_Ghost_Entity
955 (Defining_Entity (Original_Node (Unit (N))));
956 end Is_Ignored_Ghost_Unit;
958 -------------------------
959 -- Is_Subject_To_Ghost --
960 -------------------------
962 function Is_Subject_To_Ghost (N : Node_Id) return Boolean is
963 function Enables_Ghostness (Arg : Node_Id) return Boolean;
964 -- Determine whether aspect or pragma argument Arg enables "ghostness"
966 -----------------------
967 -- Enables_Ghostness --
968 -----------------------
970 function Enables_Ghostness (Arg : Node_Id) return Boolean is
971 Expr : Node_Id;
973 begin
974 Expr := Arg;
976 if Nkind (Expr) = N_Pragma_Argument_Association then
977 Expr := Get_Pragma_Arg (Expr);
978 end if;
980 -- Determine whether the expression of the aspect or pragma is static
981 -- and denotes True.
983 if Present (Expr) then
984 Preanalyze_And_Resolve (Expr);
986 return
987 Is_OK_Static_Expression (Expr)
988 and then Is_True (Expr_Value (Expr));
990 -- Otherwise Ghost defaults to True
992 else
993 return True;
994 end if;
995 end Enables_Ghostness;
997 -- Local variables
999 Id : constant Entity_Id := Defining_Entity (N);
1000 Asp : Node_Id;
1001 Decl : Node_Id;
1002 Prev_Id : Entity_Id;
1004 -- Start of processing for Is_Subject_To_Ghost
1006 begin
1007 -- The related entity of the declaration has not been analyzed yet, do
1008 -- not inspect its attributes.
1010 if Ekind (Id) = E_Void then
1011 null;
1013 elsif Is_Ghost_Entity (Id) then
1014 return True;
1016 -- The completion of a type or a constant is not fully analyzed when the
1017 -- reference to the Ghost entity is resolved. Because the completion is
1018 -- not marked as Ghost yet, inspect the partial view.
1020 elsif Is_Record_Type (Id)
1021 or else Ekind (Id) = E_Constant
1022 or else (Nkind (N) = N_Object_Declaration
1023 and then Constant_Present (N))
1024 then
1025 Prev_Id := Incomplete_Or_Partial_View (Id);
1027 if Present (Prev_Id) and then Is_Ghost_Entity (Prev_Id) then
1028 return True;
1029 end if;
1030 end if;
1032 -- Examine the aspect specifications (if any) looking for aspect Ghost
1034 if Permits_Aspect_Specifications (N) then
1035 Asp := First (Aspect_Specifications (N));
1036 while Present (Asp) loop
1037 if Chars (Identifier (Asp)) = Name_Ghost then
1038 return Enables_Ghostness (Expression (Asp));
1039 end if;
1041 Next (Asp);
1042 end loop;
1043 end if;
1045 Decl := Empty;
1047 -- When the context is a [generic] package declaration, pragma Ghost
1048 -- resides in the visible declarations.
1050 if Nkind_In (N, N_Generic_Package_Declaration,
1051 N_Package_Declaration)
1052 then
1053 Decl := First (Visible_Declarations (Specification (N)));
1055 -- When the context is a package or a subprogram body, pragma Ghost
1056 -- resides in the declarative part.
1058 elsif Nkind_In (N, N_Package_Body, N_Subprogram_Body) then
1059 Decl := First (Declarations (N));
1061 -- Otherwise pragma Ghost appears in the declarations following N
1063 elsif Is_List_Member (N) then
1064 Decl := Next (N);
1065 end if;
1067 while Present (Decl) loop
1068 if Nkind (Decl) = N_Pragma
1069 and then Pragma_Name (Decl) = Name_Ghost
1070 then
1071 return
1072 Enables_Ghostness (First (Pragma_Argument_Associations (Decl)));
1074 -- A source construct ends the region where pragma Ghost may appear,
1075 -- stop the traversal. Check the original node as source constructs
1076 -- may be rewritten into something else by expansion.
1078 elsif Comes_From_Source (Original_Node (Decl)) then
1079 exit;
1080 end if;
1082 Next (Decl);
1083 end loop;
1085 return False;
1086 end Is_Subject_To_Ghost;
1088 ----------
1089 -- Lock --
1090 ----------
1092 procedure Lock is
1093 begin
1094 Ignored_Ghost_Units.Locked := True;
1095 Ignored_Ghost_Units.Release;
1096 end Lock;
1098 -----------------------------------
1099 -- Mark_And_Set_Ghost_Assignment --
1100 -----------------------------------
1102 procedure Mark_And_Set_Ghost_Assignment
1103 (N : Node_Id;
1104 Mode : out Ghost_Mode_Type)
1106 Id : Entity_Id;
1108 begin
1109 -- Save the previous Ghost mode in effect
1111 Mode := Ghost_Mode;
1113 -- An assignment statement becomes Ghost when its target denotes a Ghost
1114 -- object. Install the Ghost mode of the target.
1116 Id := Ghost_Entity (Name (N));
1118 if Present (Id) then
1119 if Is_Checked_Ghost_Entity (Id) then
1120 Install_Ghost_Mode (Check);
1122 elsif Is_Ignored_Ghost_Entity (Id) then
1123 Install_Ghost_Mode (Ignore);
1125 Set_Is_Ignored_Ghost_Node (N);
1126 Propagate_Ignored_Ghost_Code (N);
1127 end if;
1128 end if;
1129 end Mark_And_Set_Ghost_Assignment;
1131 -----------------------------
1132 -- Mark_And_Set_Ghost_Body --
1133 -----------------------------
1135 procedure Mark_And_Set_Ghost_Body
1136 (N : Node_Id;
1137 Spec_Id : Entity_Id;
1138 Mode : out Ghost_Mode_Type)
1140 Body_Id : constant Entity_Id := Defining_Entity (N);
1141 Policy : Name_Id := No_Name;
1143 begin
1144 -- Save the previous Ghost mode in effect
1146 Mode := Ghost_Mode;
1148 -- A body becomes Ghost when it is subject to aspect or pragma Ghost
1150 if Is_Subject_To_Ghost (N) then
1151 Policy := Policy_In_Effect (Name_Ghost);
1153 -- A body declared within a Ghost region is automatically Ghost
1154 -- (SPARK RM 6.9(2)).
1156 elsif Ghost_Mode = Check then
1157 Policy := Name_Check;
1159 elsif Ghost_Mode = Ignore then
1160 Policy := Name_Ignore;
1162 -- Inherit the "ghostness" of the previous declaration when the body
1163 -- acts as a completion.
1165 elsif Present (Spec_Id) then
1166 if Is_Checked_Ghost_Entity (Spec_Id) then
1167 Policy := Name_Check;
1169 elsif Is_Ignored_Ghost_Entity (Spec_Id) then
1170 Policy := Name_Ignore;
1171 end if;
1172 end if;
1174 -- The Ghost policy in effect at the point of declaration and at the
1175 -- point of completion must match (SPARK RM 6.9(14)).
1177 Check_Ghost_Completion
1178 (Prev_Id => Spec_Id,
1179 Compl_Id => Body_Id);
1181 -- Mark the body as its formals as Ghost
1183 Mark_Ghost_Declaration_Or_Body (N, Policy);
1185 -- Install the appropriate Ghost mode
1187 Install_Ghost_Mode (Policy);
1188 end Mark_And_Set_Ghost_Body;
1190 -----------------------------------
1191 -- Mark_And_Set_Ghost_Completion --
1192 -----------------------------------
1194 procedure Mark_And_Set_Ghost_Completion
1195 (N : Node_Id;
1196 Prev_Id : Entity_Id;
1197 Mode : out Ghost_Mode_Type)
1199 Compl_Id : constant Entity_Id := Defining_Entity (N);
1200 Policy : Name_Id := No_Name;
1202 begin
1203 -- Save the previous Ghost mode in effect
1205 Mode := Ghost_Mode;
1207 -- A completion elaborated in a Ghost region is automatically Ghost
1208 -- (SPARK RM 6.9(2)).
1210 if Ghost_Mode = Check then
1211 Policy := Name_Check;
1213 elsif Ghost_Mode = Ignore then
1214 Policy := Name_Ignore;
1216 -- The completion becomes Ghost when its initial declaration is also
1217 -- Ghost.
1219 elsif Is_Checked_Ghost_Entity (Prev_Id) then
1220 Policy := Name_Check;
1222 elsif Is_Ignored_Ghost_Entity (Prev_Id) then
1223 Policy := Name_Ignore;
1224 end if;
1226 -- The Ghost policy in effect at the point of declaration and at the
1227 -- point of completion must match (SPARK RM 6.9(14)).
1229 Check_Ghost_Completion
1230 (Prev_Id => Prev_Id,
1231 Compl_Id => Compl_Id);
1233 -- Mark the completion as Ghost
1235 Mark_Ghost_Declaration_Or_Body (N, Policy);
1237 -- Install the appropriate Ghost mode
1239 Install_Ghost_Mode (Policy);
1240 end Mark_And_Set_Ghost_Completion;
1242 ------------------------------------
1243 -- Mark_And_Set_Ghost_Declaration --
1244 ------------------------------------
1246 procedure Mark_And_Set_Ghost_Declaration
1247 (N : Node_Id;
1248 Mode : out Ghost_Mode_Type)
1250 Par_Id : Entity_Id;
1251 Policy : Name_Id := No_Name;
1253 begin
1254 -- Save the previous Ghost mode in effect
1256 Mode := Ghost_Mode;
1258 -- A declaration becomes Ghost when it is subject to aspect or pragma
1259 -- Ghost.
1261 if Is_Subject_To_Ghost (N) then
1262 Policy := Policy_In_Effect (Name_Ghost);
1264 -- A declaration elaborated in a Ghost region is automatically Ghost
1265 -- (SPARK RM 6.9(2)).
1267 elsif Ghost_Mode = Check then
1268 Policy := Name_Check;
1270 elsif Ghost_Mode = Ignore then
1271 Policy := Name_Ignore;
1273 -- A child package or subprogram declaration becomes Ghost when its
1274 -- parent is Ghost (SPARK RM 6.9(2)).
1276 elsif Nkind_In (N, N_Generic_Function_Renaming_Declaration,
1277 N_Generic_Package_Declaration,
1278 N_Generic_Package_Renaming_Declaration,
1279 N_Generic_Procedure_Renaming_Declaration,
1280 N_Generic_Subprogram_Declaration,
1281 N_Package_Declaration,
1282 N_Package_Renaming_Declaration,
1283 N_Subprogram_Declaration,
1284 N_Subprogram_Renaming_Declaration)
1285 and then Present (Parent_Spec (N))
1286 then
1287 Par_Id := Defining_Entity (Unit (Parent_Spec (N)));
1289 if Is_Checked_Ghost_Entity (Par_Id) then
1290 Policy := Name_Check;
1292 elsif Is_Ignored_Ghost_Entity (Par_Id) then
1293 Policy := Name_Ignore;
1294 end if;
1295 end if;
1297 -- Mark the declaration and its formals as Ghost
1299 Mark_Ghost_Declaration_Or_Body (N, Policy);
1301 -- Install the appropriate Ghost mode
1303 Install_Ghost_Mode (Policy);
1304 end Mark_And_Set_Ghost_Declaration;
1306 --------------------------------------
1307 -- Mark_And_Set_Ghost_Instantiation --
1308 --------------------------------------
1310 procedure Mark_And_Set_Ghost_Instantiation
1311 (N : Node_Id;
1312 Gen_Id : Entity_Id;
1313 Mode : out Ghost_Mode_Type)
1315 Policy : Name_Id := No_Name;
1317 begin
1318 -- Save the previous Ghost mode in effect
1320 Mode := Ghost_Mode;
1322 -- An instantiation becomes Ghost when it is subject to pragma Ghost
1324 if Is_Subject_To_Ghost (N) then
1325 Policy := Policy_In_Effect (Name_Ghost);
1327 -- An instantiation declaration within a Ghost region is automatically
1328 -- Ghost (SPARK RM 6.9(2)).
1330 elsif Ghost_Mode = Check then
1331 Policy := Name_Check;
1333 elsif Ghost_Mode = Ignore then
1334 Policy := Name_Ignore;
1336 -- Inherit the "ghostness" of the generic unit
1338 elsif Is_Checked_Ghost_Entity (Gen_Id) then
1339 Policy := Name_Check;
1341 elsif Is_Ignored_Ghost_Entity (Gen_Id) then
1342 Policy := Name_Ignore;
1343 end if;
1345 -- Mark the instantiation as Ghost
1347 Mark_Ghost_Declaration_Or_Body (N, Policy);
1349 -- Install the appropriate Ghost mode
1351 Install_Ghost_Mode (Policy);
1352 end Mark_And_Set_Ghost_Instantiation;
1354 ---------------------------------------
1355 -- Mark_And_Set_Ghost_Procedure_Call --
1356 ---------------------------------------
1358 procedure Mark_And_Set_Ghost_Procedure_Call
1359 (N : Node_Id;
1360 Mode : out Ghost_Mode_Type)
1362 Id : Entity_Id;
1364 begin
1365 -- Save the previous Ghost mode in effect
1367 Mode := Ghost_Mode;
1369 -- A procedure call becomes Ghost when the procedure being invoked is
1370 -- Ghost. Install the Ghost mode of the procedure.
1372 Id := Ghost_Entity (Name (N));
1374 if Present (Id) then
1375 if Is_Checked_Ghost_Entity (Id) then
1376 Install_Ghost_Mode (Check);
1378 elsif Is_Ignored_Ghost_Entity (Id) then
1379 Install_Ghost_Mode (Ignore);
1381 Set_Is_Ignored_Ghost_Node (N);
1382 Propagate_Ignored_Ghost_Code (N);
1383 end if;
1384 end if;
1385 end Mark_And_Set_Ghost_Procedure_Call;
1387 ------------------------------------
1388 -- Mark_Ghost_Declaration_Or_Body --
1389 ------------------------------------
1391 procedure Mark_Ghost_Declaration_Or_Body
1392 (N : Node_Id;
1393 Mode : Name_Id)
1395 Id : constant Entity_Id := Defining_Entity (N);
1397 Mark_Formals : Boolean := False;
1398 Param : Node_Id;
1399 Param_Id : Entity_Id;
1401 begin
1402 -- Mark the related node and its entity
1404 if Mode = Name_Check then
1405 Mark_Formals := True;
1406 Set_Is_Checked_Ghost_Entity (Id);
1408 elsif Mode = Name_Ignore then
1409 Mark_Formals := True;
1410 Set_Is_Ignored_Ghost_Entity (Id);
1411 Set_Is_Ignored_Ghost_Node (N);
1412 Propagate_Ignored_Ghost_Code (N);
1413 end if;
1415 -- Mark all formal parameters when the related node denotes a subprogram
1416 -- or a body. The traversal is performed via the specification because
1417 -- the related subprogram or body may be unanalyzed.
1419 -- ??? could extra formal parameters cause a Ghost leak?
1421 if Mark_Formals
1422 and then Nkind_In (N, N_Abstract_Subprogram_Declaration,
1423 N_Formal_Abstract_Subprogram_Declaration,
1424 N_Formal_Concrete_Subprogram_Declaration,
1425 N_Generic_Subprogram_Declaration,
1426 N_Subprogram_Body,
1427 N_Subprogram_Body_Stub,
1428 N_Subprogram_Declaration,
1429 N_Subprogram_Renaming_Declaration)
1430 then
1431 Param := First (Parameter_Specifications (Specification (N)));
1432 while Present (Param) loop
1433 Param_Id := Defining_Entity (Param);
1435 if Mode = Name_Check then
1436 Set_Is_Checked_Ghost_Entity (Param_Id);
1438 elsif Mode = Name_Ignore then
1439 Set_Is_Ignored_Ghost_Entity (Param_Id);
1440 end if;
1442 Next (Param);
1443 end loop;
1444 end if;
1445 end Mark_Ghost_Declaration_Or_Body;
1447 -----------------------
1448 -- Mark_Ghost_Clause --
1449 -----------------------
1451 procedure Mark_Ghost_Clause (N : Node_Id) is
1452 Nam : Node_Id := Empty;
1454 begin
1455 if Nkind (N) = N_Use_Package_Clause then
1456 Nam := First (Names (N));
1458 elsif Nkind (N) = N_Use_Type_Clause then
1459 Nam := First (Subtype_Marks (N));
1461 elsif Nkind (N) = N_With_Clause then
1462 Nam := Name (N);
1463 end if;
1465 if Present (Nam)
1466 and then Is_Entity_Name (Nam)
1467 and then Present (Entity (Nam))
1468 and then Is_Ignored_Ghost_Entity (Entity (Nam))
1469 then
1470 Set_Is_Ignored_Ghost_Node (N);
1471 Propagate_Ignored_Ghost_Code (N);
1472 end if;
1473 end Mark_Ghost_Clause;
1475 -----------------------
1476 -- Mark_Ghost_Pragma --
1477 -----------------------
1479 procedure Mark_Ghost_Pragma
1480 (N : Node_Id;
1481 Id : Entity_Id)
1483 begin
1484 -- A pragma becomes Ghost when it encloses a Ghost entity or relates to
1485 -- a Ghost entity.
1487 if Is_Checked_Ghost_Entity (Id) then
1488 Set_Is_Checked_Ghost_Pragma (N);
1490 elsif Is_Ignored_Ghost_Entity (Id) then
1491 Set_Is_Ignored_Ghost_Pragma (N);
1492 Set_Is_Ignored_Ghost_Node (N);
1493 Propagate_Ignored_Ghost_Code (N);
1494 end if;
1495 end Mark_Ghost_Pragma;
1497 -------------------------
1498 -- Mark_Ghost_Renaming --
1499 -------------------------
1501 procedure Mark_Ghost_Renaming
1502 (N : Node_Id;
1503 Id : Entity_Id)
1505 Policy : Name_Id := No_Name;
1507 begin
1508 -- A renaming becomes Ghost when it renames a Ghost entity
1510 if Is_Checked_Ghost_Entity (Id) then
1511 Policy := Name_Check;
1513 elsif Is_Ignored_Ghost_Entity (Id) then
1514 Policy := Name_Ignore;
1515 end if;
1517 Mark_Ghost_Declaration_Or_Body (N, Policy);
1518 end Mark_Ghost_Renaming;
1520 ----------------------------------
1521 -- Propagate_Ignored_Ghost_Code --
1522 ----------------------------------
1524 procedure Propagate_Ignored_Ghost_Code (N : Node_Id) is
1525 Nod : Node_Id;
1526 Scop : Entity_Id;
1528 begin
1529 -- Traverse the parent chain looking for blocks, packages, and
1530 -- subprograms or their respective bodies.
1532 Nod := Parent (N);
1533 while Present (Nod) loop
1534 Scop := Empty;
1536 if Nkind (Nod) = N_Block_Statement
1537 and then Present (Identifier (Nod))
1538 then
1539 Scop := Entity (Identifier (Nod));
1541 elsif Nkind_In (Nod, N_Package_Body,
1542 N_Package_Declaration,
1543 N_Subprogram_Body,
1544 N_Subprogram_Declaration)
1545 then
1546 Scop := Defining_Entity (Nod);
1547 end if;
1549 -- The current node denotes a scoping construct
1551 if Present (Scop) then
1553 -- Stop the traversal when the scope already contains ignored
1554 -- Ghost code as all enclosing scopes have already been marked.
1556 if Contains_Ignored_Ghost_Code (Scop) then
1557 exit;
1559 -- Otherwise mark this scope and keep climbing
1561 else
1562 Set_Contains_Ignored_Ghost_Code (Scop);
1563 end if;
1564 end if;
1566 Nod := Parent (Nod);
1567 end loop;
1569 -- The unit containing the ignored Ghost code must be post processed
1570 -- before invoking the back end.
1572 Add_Ignored_Ghost_Unit (Cunit (Get_Code_Unit (N)));
1573 end Propagate_Ignored_Ghost_Code;
1575 -------------------------------
1576 -- Remove_Ignored_Ghost_Code --
1577 -------------------------------
1579 procedure Remove_Ignored_Ghost_Code is
1580 procedure Prune_Tree (Root : Node_Id);
1581 -- Remove all code marked as ignored Ghost from the tree of denoted by
1582 -- Root.
1584 ----------------
1585 -- Prune_Tree --
1586 ----------------
1588 procedure Prune_Tree (Root : Node_Id) is
1589 procedure Prune (N : Node_Id);
1590 -- Remove a given node from the tree by rewriting it into null
1592 function Prune_Node (N : Node_Id) return Traverse_Result;
1593 -- Determine whether node N denotes an ignored Ghost construct. If
1594 -- this is the case, rewrite N as a null statement. See the body for
1595 -- special cases.
1597 -----------
1598 -- Prune --
1599 -----------
1601 procedure Prune (N : Node_Id) is
1602 begin
1603 -- Destroy any aspects that may be associated with the node
1605 if Permits_Aspect_Specifications (N) and then Has_Aspects (N) then
1606 Remove_Aspects (N);
1607 end if;
1609 Rewrite (N, Make_Null_Statement (Sloc (N)));
1610 end Prune;
1612 ----------------
1613 -- Prune_Node --
1614 ----------------
1616 function Prune_Node (N : Node_Id) return Traverse_Result is
1617 Id : Entity_Id;
1619 begin
1620 -- Do not prune compilation unit nodes because many mechanisms
1621 -- depend on their presence. Note that context items are still
1622 -- being processed.
1624 if Nkind (N) = N_Compilation_Unit then
1625 return OK;
1627 -- The node is either declared as ignored Ghost or is a byproduct
1628 -- of expansion. Destroy it and stop the traversal on this branch.
1630 elsif Is_Ignored_Ghost_Node (N) then
1631 Prune (N);
1632 return Skip;
1634 -- Scoping constructs such as blocks, packages, subprograms and
1635 -- bodies offer some flexibility with respect to pruning.
1637 elsif Nkind_In (N, N_Block_Statement,
1638 N_Package_Body,
1639 N_Package_Declaration,
1640 N_Subprogram_Body,
1641 N_Subprogram_Declaration)
1642 then
1643 if Nkind (N) = N_Block_Statement then
1644 Id := Entity (Identifier (N));
1645 else
1646 Id := Defining_Entity (N);
1647 end if;
1649 -- The scoping construct contains both living and ignored Ghost
1650 -- code, let the traversal prune all relevant nodes.
1652 if Contains_Ignored_Ghost_Code (Id) then
1653 return OK;
1655 -- Otherwise the construct contains only living code and should
1656 -- not be pruned.
1658 else
1659 return Skip;
1660 end if;
1662 -- Otherwise keep searching for ignored Ghost nodes
1664 else
1665 return OK;
1666 end if;
1667 end Prune_Node;
1669 procedure Prune_Nodes is new Traverse_Proc (Prune_Node);
1671 -- Start of processing for Prune_Tree
1673 begin
1674 Prune_Nodes (Root);
1675 end Prune_Tree;
1677 -- Start of processing for Remove_Ignored_Ghost_Code
1679 begin
1680 for Index in Ignored_Ghost_Units.First .. Ignored_Ghost_Units.Last loop
1681 Prune_Tree (Ignored_Ghost_Units.Table (Index));
1682 end loop;
1683 end Remove_Ignored_Ghost_Code;
1685 ------------------------
1686 -- Restore_Ghost_Mode --
1687 ------------------------
1689 procedure Restore_Ghost_Mode (Mode : Ghost_Mode_Type) is
1690 begin
1691 Ghost_Mode := Mode;
1692 end Restore_Ghost_Mode;
1694 --------------------
1695 -- Set_Ghost_Mode --
1696 --------------------
1698 procedure Set_Ghost_Mode
1699 (N : Node_Or_Entity_Id;
1700 Mode : out Ghost_Mode_Type)
1702 procedure Set_Ghost_Mode_From_Entity (Id : Entity_Id);
1703 -- Install the Ghost mode of entity Id
1705 --------------------------------
1706 -- Set_Ghost_Mode_From_Entity --
1707 --------------------------------
1709 procedure Set_Ghost_Mode_From_Entity (Id : Entity_Id) is
1710 begin
1711 if Is_Checked_Ghost_Entity (Id) then
1712 Install_Ghost_Mode (Check);
1713 elsif Is_Ignored_Ghost_Entity (Id) then
1714 Install_Ghost_Mode (Ignore);
1715 else
1716 Install_Ghost_Mode (None);
1717 end if;
1718 end Set_Ghost_Mode_From_Entity;
1720 -- Local variables
1722 Id : Entity_Id;
1724 -- Start of processing for Set_Ghost_Mode
1726 begin
1727 -- Save the previous Ghost mode in effect
1729 Mode := Ghost_Mode;
1731 -- The Ghost mode of an assignment statement depends on the Ghost mode
1732 -- of the target.
1734 if Nkind (N) = N_Assignment_Statement then
1735 Id := Ghost_Entity (Name (N));
1737 if Present (Id) then
1738 Set_Ghost_Mode_From_Entity (Id);
1739 end if;
1741 -- The Ghost mode of a body or a declaration depends on the Ghost mode
1742 -- of its defining entity.
1744 elsif Is_Body (N) or else Is_Declaration (N) then
1745 Set_Ghost_Mode_From_Entity (Defining_Entity (N));
1747 -- The Ghost mode of an entity depends on the entity itself
1749 elsif Nkind (N) in N_Entity then
1750 Set_Ghost_Mode_From_Entity (N);
1752 -- The Ghost mode of a [generic] freeze node depends on the Ghost mode
1753 -- of the entity being frozen.
1755 elsif Nkind_In (N, N_Freeze_Entity, N_Freeze_Generic_Entity) then
1756 Set_Ghost_Mode_From_Entity (Entity (N));
1758 -- The Ghost mode of a pragma depends on the associated entity. The
1759 -- property is encoded in the pragma itself.
1761 elsif Nkind (N) = N_Pragma then
1762 if Is_Checked_Ghost_Pragma (N) then
1763 Install_Ghost_Mode (Check);
1764 elsif Is_Ignored_Ghost_Pragma (N) then
1765 Install_Ghost_Mode (Ignore);
1766 else
1767 Install_Ghost_Mode (None);
1768 end if;
1770 -- The Ghost mode of a procedure call depends on the Ghost mode of the
1771 -- procedure being invoked.
1773 elsif Nkind (N) = N_Procedure_Call_Statement then
1774 Id := Ghost_Entity (Name (N));
1776 if Present (Id) then
1777 Set_Ghost_Mode_From_Entity (Id);
1778 end if;
1779 end if;
1780 end Set_Ghost_Mode;
1782 -------------------------
1783 -- Set_Is_Ghost_Entity --
1784 -------------------------
1786 procedure Set_Is_Ghost_Entity (Id : Entity_Id) is
1787 Policy : constant Name_Id := Policy_In_Effect (Name_Ghost);
1788 begin
1789 if Policy = Name_Check then
1790 Set_Is_Checked_Ghost_Entity (Id);
1791 elsif Policy = Name_Ignore then
1792 Set_Is_Ignored_Ghost_Entity (Id);
1793 end if;
1794 end Set_Is_Ghost_Entity;
1796 end Ghost;