Mercurial > hg > CbC > CbC_gcc
comparison gcc/ada/sem_elab.adb @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 ------------------------------------------------------------------------------ | |
2 -- -- | |
3 -- GNAT COMPILER COMPONENTS -- | |
4 -- -- | |
5 -- S E M _ E L A B -- | |
6 -- -- | |
7 -- B o d y -- | |
8 -- -- | |
9 -- Copyright (C) 1997-2017, 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 ------------------------------------------------------------------------------ | |
25 | |
26 with Atree; use Atree; | |
27 with Debug; use Debug; | |
28 with Einfo; use Einfo; | |
29 with Errout; use Errout; | |
30 with Exp_Ch11; use Exp_Ch11; | |
31 with Exp_Tss; use Exp_Tss; | |
32 with Exp_Util; use Exp_Util; | |
33 with Lib; use Lib; | |
34 with Lib.Load; use Lib.Load; | |
35 with Namet; use Namet; | |
36 with Nlists; use Nlists; | |
37 with Nmake; use Nmake; | |
38 with Opt; use Opt; | |
39 with Restrict; use Restrict; | |
40 with Rident; use Rident; | |
41 with Rtsfind; use Rtsfind; | |
42 with Sem; use Sem; | |
43 with Sem_Aux; use Sem_Aux; | |
44 with Sem_Ch7; use Sem_Ch7; | |
45 with Sem_Ch8; use Sem_Ch8; | |
46 with Sem_Prag; use Sem_Prag; | |
47 with Sem_Util; use Sem_Util; | |
48 with Sinfo; use Sinfo; | |
49 with Snames; use Snames; | |
50 with Stand; use Stand; | |
51 with Table; | |
52 with Tbuild; use Tbuild; | |
53 with Uintp; use Uintp; | |
54 with Uname; use Uname; | |
55 | |
56 with GNAT.HTable; use GNAT.HTable; | |
57 | |
58 package body Sem_Elab is | |
59 | |
60 ----------------------------------------- | |
61 -- Access-before-elaboration mechanism -- | |
62 ----------------------------------------- | |
63 | |
64 -- The access-before-elaboration (ABE) mechanism implemented in this unit | |
65 -- has the following objectives: | |
66 -- | |
67 -- * Diagnose at compile-time or install run-time checks to prevent ABE | |
68 -- access to data and behaviour. | |
69 -- | |
70 -- The high level idea is to accurately diagnose ABE issues within a | |
71 -- single unit because the ABE mechanism can inspect the whole unit. | |
72 -- As soon as the elaboration graph extends to an external unit, the | |
73 -- diagnostics stop because the body of the unit may not be available. | |
74 -- Due to control and data flow, the ABE mechanism cannot accurately | |
75 -- determine whether a particular scenario will be elaborated or not. | |
76 -- Conditional ABE checks are therefore used to verify the elaboration | |
77 -- status of a local and external target at run time. | |
78 -- | |
79 -- * Supply elaboration dependencies for a unit to binde | |
80 -- | |
81 -- The ABE mechanism registers each outgoing elaboration edge for the | |
82 -- main unit in its ALI file. GNATbind and binde can then reconstruct | |
83 -- the full elaboration graph and determine the proper elaboration | |
84 -- order for all units in the compilation. | |
85 -- | |
86 -- The ABE mechanism supports three models of elaboration: | |
87 -- | |
88 -- * Dynamic model - This is the most permissive of the three models. | |
89 -- When the dynamic model is in effect, the mechanism performs very | |
90 -- little diagnostics and generates run-time checks to detect ABE | |
91 -- issues. The behaviour of this model is identical to that specified | |
92 -- by the Ada RM. This model is enabled with switch -gnatE. | |
93 -- | |
94 -- * Static model - This is the middle ground of the three models. When | |
95 -- the static model is in effect, the mechanism diagnoses and installs | |
96 -- run-time checks to detect ABE issues in the main unit. In addition, | |
97 -- the mechanism generates implicit Elaborate or Elaborate_All pragmas | |
98 -- to ensure the prior elaboration of withed units. The model employs | |
99 -- textual order, with clause context, and elaboration-related source | |
100 -- pragmas. This is the default model. | |
101 -- | |
102 -- * SPARK model - This is the most conservative of the three models and | |
103 -- impelements the semantics defined in SPARK RM 7.7. The SPARK model | |
104 -- is in effect only when a context resides in a SPARK_Mode On region, | |
105 -- otherwise the mechanism falls back to one of the previous models. | |
106 -- | |
107 -- The ABE mechanism consists of a "recording" phase and a "processing" | |
108 -- phase. | |
109 | |
110 ----------------- | |
111 -- Terminology -- | |
112 ----------------- | |
113 | |
114 -- * Bridge target - A type of target. A bridge target is a link between | |
115 -- scenarios. It is usually a byproduct of expansion and does not have | |
116 -- any direct ABE ramifications. | |
117 -- | |
118 -- * Call marker - A special node used to indicate the presence of a call | |
119 -- in the tree in case expansion transforms or eliminates the original | |
120 -- call. N_Call_Marker nodes do not have static and run-time semantics. | |
121 -- | |
122 -- * Conditional ABE - A type of ABE. A conditional ABE occurs when the | |
123 -- elaboration or invocation of a target by a scenario within the main | |
124 -- unit causes an ABE, but does not cause an ABE for another scenarios | |
125 -- within the main unit. | |
126 -- | |
127 -- * Declaration level - A type of enclosing level. A scenario or target is | |
128 -- at the declaration level when it appears within the declarations of a | |
129 -- block statement, entry body, subprogram body, or task body, ignoring | |
130 -- enclosing packges. | |
131 -- | |
132 -- * Generic library level - A type of enclosing level. A scenario or | |
133 -- target is at the generic library level if it appears in a generic | |
134 -- package library unit, ignoring enclosing packages. | |
135 -- | |
136 -- * Guaranteed ABE - A type of ABE. A guaranteed ABE occurs when the | |
137 -- elaboration or invocation of a target by all scenarios within the | |
138 -- main unit causes an ABE. | |
139 -- | |
140 -- * Instantiation library level - A type of enclosing level. A scenario | |
141 -- or target is at the instantiation library level if it appears in an | |
142 -- instantiation library unit, ignoring enclosing packages. | |
143 -- | |
144 -- * Library level - A type of enclosing level. A scenario or target is at | |
145 -- the library level if it appears in a package library unit, ignoring | |
146 -- enclosng packages. | |
147 -- | |
148 -- * Non-library level encapsulator - A construct that cannot be elaborated | |
149 -- on its own and requires elaboration by a top level scenario. | |
150 -- | |
151 -- * Scenario - A construct or context which may be elaborated or executed | |
152 -- by elaboration code. The scenarios recognized by the ABE mechanism are | |
153 -- as follows: | |
154 -- | |
155 -- - '[Unrestricted_]Access of entries, operators, and subprograms | |
156 -- | |
157 -- - Assignments to variables | |
158 -- | |
159 -- - Calls to entries, operators, and subprograms | |
160 -- | |
161 -- - Instantiations | |
162 -- | |
163 -- - Reads of variables | |
164 -- | |
165 -- - Task activation | |
166 -- | |
167 -- * Target - A construct referenced by a scenario. The targets recognized | |
168 -- by the ABE mechanism are as follows: | |
169 -- | |
170 -- - For '[Unrestricted_]Access of entries, operators, and subprograms, | |
171 -- the target is the entry, operator, or subprogram. | |
172 -- | |
173 -- - For assignments to variables, the target is the variable | |
174 -- | |
175 -- - For calls, the target is the entry, operator, or subprogram | |
176 -- | |
177 -- - For instantiations, the target is the generic template | |
178 -- | |
179 -- - For reads of variables, the target is the variable | |
180 -- | |
181 -- - For task activation, the target is the task body | |
182 -- | |
183 -- * Top level scenario - A scenario which appears in a non-generic main | |
184 -- unit. Depending on the elaboration model is in effect, the following | |
185 -- addotional restrictions apply: | |
186 -- | |
187 -- - Dynamic model - No restrictions | |
188 -- | |
189 -- - SPARK model - Falls back to either the dynamic or static model | |
190 -- | |
191 -- - Static model - The scenario must be at the library level | |
192 | |
193 --------------------- | |
194 -- Recording phase -- | |
195 --------------------- | |
196 | |
197 -- The Recording phase coincides with the analysis/resolution phase of the | |
198 -- compiler. It has the following objectives: | |
199 -- | |
200 -- * Record all top level scenarios for examination by the Processing | |
201 -- phase. | |
202 -- | |
203 -- Saving only a certain number of nodes improves the performance of | |
204 -- the ABE mechanism. This eliminates the need to examine the whole | |
205 -- tree in a separate pass. | |
206 -- | |
207 -- * Detect and diagnose calls in preelaborable or pure units, including | |
208 -- generic bodies. | |
209 -- | |
210 -- This diagnostic is carried out during the Recording phase because it | |
211 -- does not need the heavy recursive traversal done by the Processing | |
212 -- phase. | |
213 -- | |
214 -- * Detect and diagnose guaranteed ABEs caused by instantiations, | |
215 -- calls, and task activation. | |
216 -- | |
217 -- The issues detected by the ABE mechanism are reported as warnings | |
218 -- because they do not violate Ada semantics. Forward instantiations | |
219 -- may thus reach gigi, however gigi cannot handle certain kinds of | |
220 -- premature instantiations and may crash. To avoid this limitation, | |
221 -- the ABE mechanism must identify forward instantiations as early as | |
222 -- possible and suppress their bodies. Calls and task activations are | |
223 -- included in this category for completeness. | |
224 | |
225 ---------------------- | |
226 -- Processing phase -- | |
227 ---------------------- | |
228 | |
229 -- The Processing phase is a separate pass which starts after instantiating | |
230 -- and/or inlining of bodies, but before the removal of Ghost code. It has | |
231 -- the following objectives: | |
232 -- | |
233 -- * Examine all top level scenarios saved during the Recording phase | |
234 -- | |
235 -- The top level scenarios act as roots for depth-first traversal of | |
236 -- the call/instantiation/task activation graph. The traversal stops | |
237 -- when an outgoing edge leaves the main unit. | |
238 -- | |
239 -- * Depending on the elaboration model in effect, perform the following | |
240 -- actions: | |
241 -- | |
242 -- - Dynamic model - Diagnose guaranteed ABEs and install run-time | |
243 -- conditional ABE checks. | |
244 -- | |
245 -- - SPARK model - Enforce the SPARK elaboration rules | |
246 -- | |
247 -- - Static model - Diagnose conditional/guaranteed ABEs, install | |
248 -- run-time conditional ABE checks, and guarantee the elaboration | |
249 -- of external units. | |
250 -- | |
251 -- * Examine nested scenarios | |
252 -- | |
253 -- Nested scenarios discovered during the depth-first traversal are | |
254 -- in turn subjected to the same actions outlined above and examined | |
255 -- for the next level of nested scenarios. | |
256 | |
257 ------------------ | |
258 -- Architecture -- | |
259 ------------------ | |
260 | |
261 -- +------------------------ Recording phase ---------------------------+ | |
262 -- | | | |
263 -- | Record_Elaboration_Scenario | | |
264 -- | | | | |
265 -- | +--> Check_Preelaborated_Call | | |
266 -- | | | | |
267 -- | +--> Process_Guaranteed_ABE | | |
268 -- | | | | |
269 -- +------------------------- | --------------------------------------+ | |
270 -- | | |
271 -- | | |
272 -- v | |
273 -- Top_Level_Scenarios | |
274 -- +-----------+-----------+ .. +-----------+ | |
275 -- | Scenario1 | Scenario2 | .. | ScenarioN | | |
276 -- +-----------+-----------+ .. +-----------+ | |
277 -- | | |
278 -- | | |
279 -- +------------------------- | --------------------------------------+ | |
280 -- | | | | |
281 -- | Check_Elaboration_Scenarios | | |
282 -- | | | | |
283 -- | v | | |
284 -- | +----------- Process_Scenario <-----------+ | | |
285 -- | | | | | |
286 -- | +--> Process_Access Is_Suitable_Scenario | | |
287 -- | | ^ | | |
288 -- | +--> Process_Activation_Call --+ | | | |
289 -- | | +---> Traverse_Body | | |
290 -- | +--> Process_Call -------------+ | | |
291 -- | | | | |
292 -- | +--> Process_Instantiation | | |
293 -- | | | | |
294 -- | +--> Process_Variable_Assignment | | |
295 -- | | | | |
296 -- | +--> Process_Variable_Read | | |
297 -- | | | |
298 -- +------------------------- Processing phase -------------------------+ | |
299 | |
300 ---------------------- | |
301 -- Important points -- | |
302 ---------------------- | |
303 | |
304 -- The Processing phase starts after the analysis, resolution, expansion | |
305 -- phase has completed. As a result, no current semantic information is | |
306 -- available. The scope stack is empty, global flags such as In_Instance | |
307 -- or Inside_A_Generic become useless. To remedy this, the ABE mechanism | |
308 -- must either save or recompute semantic information. | |
309 | |
310 -- Expansion heavily transforms calls and to some extent instantiations. To | |
311 -- remedy this, the ABE mechanism generates N_Call_Marker nodes in order to | |
312 -- capture the target and relevant attributes of the original call. | |
313 | |
314 -- The diagnostics of the ABE mechanism depend on accurate source locations | |
315 -- to determine the spacial relation of nodes. | |
316 | |
317 -------------- | |
318 -- Switches -- | |
319 -------------- | |
320 | |
321 -- The following switches may be used to control the behavior of the ABE | |
322 -- mechanism. | |
323 -- | |
324 -- -gnatdE elaboration checks on predefined units | |
325 -- | |
326 -- The ABE mechanism considers scenarios which appear in internal | |
327 -- units (Ada, GNAT, Interfaces, System). | |
328 -- | |
329 -- -gnatd.G ignore calls through generic formal parameters for elaboration | |
330 -- | |
331 -- The ABE mechanism does not generate N_Call_Marker nodes for | |
332 -- calls which occur in expanded instances, and invoke generic | |
333 -- actual subprograms through generic formal subprograms. As a | |
334 -- result, the calls are not recorded or processed. | |
335 -- | |
336 -- If switches -gnatd.G and -gnatdL are used together, then the | |
337 -- ABE mechanism effectively ignores all calls which cause the | |
338 -- elaboration flow to "leave" the instance. | |
339 -- | |
340 -- -gnatdL ignore external calls from instances for elaboration | |
341 -- | |
342 -- The ABE mechanism does not generate N_Call_Marker nodes for | |
343 -- calls which occur in expanded instances, do not invoke generic | |
344 -- actual subprograms through formal subprograms, and the target | |
345 -- is external to the instance. As a result, the calls are not | |
346 -- recorded or processed. | |
347 -- | |
348 -- If switches -gnatd.G and -gnatdL are used together, then the | |
349 -- ABE mechanism effectively ignores all calls which cause the | |
350 -- elaboration flow to "leave" the instance. | |
351 -- | |
352 -- -gnatd.o conservative elaboration order for indirect calls | |
353 -- | |
354 -- The ABE mechanism treats '[Unrestricted_]Access of an entry, | |
355 -- operator, or subprogram as an immediate invocation of the | |
356 -- target. As a result, it performs ABE checks and diagnostics on | |
357 -- the immediate call. | |
358 -- | |
359 -- -gnatd.U ignore indirect calls for static elaboration | |
360 -- | |
361 -- The ABE mechanism does not consider '[Unrestricted_]Access of | |
362 -- entries, operators, and subprograms. As a result, the scenarios | |
363 -- are not recorder or processed. | |
364 -- | |
365 -- -gnatd.v enforce SPARK elaboration rules in SPARK code | |
366 -- | |
367 -- The ABE mechanism applies some of the SPARK elaboration rules | |
368 -- defined in the SPARK reference manual, chapter 7.7. Note that | |
369 -- certain rules are always enforced, regardless of whether the | |
370 -- switch is active. | |
371 -- | |
372 -- -gnatd.y disable implicit pragma Elaborate_All on task bodies | |
373 -- | |
374 -- The ABE mechanism does not generate implicit Elaborate_All when | |
375 -- the need for the pragma came from a task body. | |
376 -- | |
377 -- -gnatE dynamic elaboration checking mode enabled | |
378 -- | |
379 -- The ABE mechanism assumes that any scenario is elaborated or | |
380 -- invoked by elaboration code. The ABE mechanism performs very | |
381 -- little diagnostics and generates condintional ABE checks to | |
382 -- detect ABE issues at run-time. | |
383 -- | |
384 -- -gnatel turn on info messages on generated Elaborate[_All] pragmas | |
385 -- | |
386 -- The ABE mechanism produces information messages on generated | |
387 -- implicit Elabote[_All] pragmas along with traceback showing | |
388 -- why the pragma was generated. In addition, the ABE mechanism | |
389 -- produces information messages for each scenario elaborated or | |
390 -- invoked by elaboration code. | |
391 -- | |
392 -- -gnateL turn off info messages on generated Elaborate[_All] pragmas | |
393 -- | |
394 -- The complimentary switch for -gnatel. | |
395 -- | |
396 -- -gnatwl turn on warnings for elaboration problems | |
397 -- | |
398 -- The ABE mechanism produces warnings on detected ABEs along with | |
399 -- traceback showing the graph of the ABE. | |
400 -- | |
401 -- -gnatwL turn off warnings for elaboration problems | |
402 -- | |
403 -- The complimentary switch for -gnatwl. | |
404 -- | |
405 -- -gnatw.f turn on warnings for suspicious Subp'Access | |
406 -- | |
407 -- The ABE mechanism treats '[Unrestricted_]Access of an entry, | |
408 -- operator, or subprogram as a pseudo invocation of the target. | |
409 -- As a result, it performs ABE diagnostics on the pseudo call. | |
410 -- | |
411 -- -gnatw.F turn off warnings for suspicious Subp'Access | |
412 -- | |
413 -- The complimentary switch for -gnatw.f. | |
414 | |
415 --------------------------- | |
416 -- Adding a new scenario -- | |
417 --------------------------- | |
418 | |
419 -- The following steps describe how to add a new elaboration scenario and | |
420 -- preserve the existing architecture. | |
421 -- | |
422 -- 1) If necessary, update predicates Is_Check_Emitting_Scenario and | |
423 -- Is_Scenario. | |
424 -- | |
425 -- 2) Add predicate Is_Suitable_xxx. Include a call to it in predicate | |
426 -- Is_Suitable_Scenario. | |
427 -- | |
428 -- 3) Update routine Record_Elaboration_Scenario | |
429 -- | |
430 -- 4) Add routine Process_xxx. Include a call to it in Process_Scenario. | |
431 -- | |
432 -- 5) Add routine Info_xxx. Include a call to it in Process_xxx. | |
433 -- | |
434 -- 6) Add routine Output_xxx. Include a call to it in routine | |
435 -- Output_Active_Scenarios. | |
436 -- | |
437 -- 7) If necessary, add a new Extract_xxx_Attributes routine | |
438 -- | |
439 -- 8) If necessary, update routine Is_Potential_Scenario | |
440 | |
441 ------------------------- | |
442 -- Adding a new target -- | |
443 ------------------------- | |
444 | |
445 -- The following steps describe how to add a new elaboration target and | |
446 -- preserve the existing architecture. | |
447 -- | |
448 -- 1) Add predicate Is_xxx. | |
449 -- | |
450 -- 2) Update predicates Is_Ada_Semantic_Target, Is_Bridge_Target, or | |
451 -- Is_SPARK_Semantic_Target. If necessary, create a new category. | |
452 -- | |
453 -- 3) Update the appropriate Info_xxx routine. | |
454 -- | |
455 -- 4) Update the appropriate Output_xxx routine. | |
456 -- | |
457 -- 5) Update routine Extract_Target_Attributes. If necessary, create a | |
458 -- new Extract_xxx routine. | |
459 | |
460 -------------------------- | |
461 -- Debugging ABE issues -- | |
462 -------------------------- | |
463 | |
464 -- * If the issue involves a call, ensure that the call is eligible for ABE | |
465 -- processing and receives a corresponding call marker. The routines of | |
466 -- interest are | |
467 -- | |
468 -- Build_Call_Marker | |
469 -- Record_Elaboration_Scenario | |
470 | |
471 -- * If the issue involves an arbitrary scenario, ensure that the scenario | |
472 -- is either recorded, or is successfully recognized while traversing a | |
473 -- body. The routines of interest are | |
474 -- | |
475 -- Record_Elaboration_Scenario | |
476 -- Process_Scenario | |
477 -- Traverse_Body | |
478 | |
479 -- * If the issue involves a circularity in the elaboration order, examine | |
480 -- the ALI files and look for the following encodings next to units: | |
481 -- | |
482 -- E indicates a source Elaborate | |
483 -- | |
484 -- EA indicates a source Elaborate_All | |
485 -- | |
486 -- AD indicates an implicit Elaborate_All | |
487 -- | |
488 -- ED indicates an implicit Elaborate | |
489 -- | |
490 -- If possible, compare these encodings with those generated by the old | |
491 -- ABE mechanism. The routines of interest are | |
492 -- | |
493 -- Ensure_Prior_Elaboration | |
494 | |
495 ---------------- | |
496 -- Attributes -- | |
497 ---------------- | |
498 | |
499 -- The following type captures relevant attributes which pertain to a call | |
500 | |
501 type Call_Attributes is record | |
502 Elab_Checks_OK : Boolean; | |
503 -- This flag is set when the call has elaboration checks enabled | |
504 | |
505 From_Source : Boolean; | |
506 -- This flag is set when the call comes from source | |
507 | |
508 Ghost_Mode_Ignore : Boolean; | |
509 -- This flag is set when the call appears in a region subject to pragma | |
510 -- Ghost with policy Ignore. | |
511 | |
512 In_Declarations : Boolean; | |
513 -- This flag is set when the call appears at the declaration level | |
514 | |
515 Is_Dispatching : Boolean; | |
516 -- This flag is set when the call is dispatching | |
517 | |
518 SPARK_Mode_On : Boolean; | |
519 -- This flag is set when the call appears in a region subject to pragma | |
520 -- SPARK_Mode with value On. | |
521 end record; | |
522 | |
523 -- The following type captures relevant attributes which pertain to the | |
524 -- prior elaboration of a unit. This type is coupled together with a unit | |
525 -- to form a key -> value relationship. | |
526 | |
527 type Elaboration_Attributes is record | |
528 Source_Pragma : Node_Id; | |
529 -- This attribute denotes a source Elaborate or Elaborate_All pragma | |
530 -- which guarantees the prior elaboration of some unit with respect | |
531 -- to the main unit. The pragma may come from the following contexts: | |
532 | |
533 -- * The main unit | |
534 -- * The spec of the main unit (if applicable) | |
535 -- * Any parent spec of the main unit (if applicable) | |
536 -- * Any parent subunit of the main unit (if applicable) | |
537 | |
538 -- The attribute remains Empty if no such pragma is available. Source | |
539 -- pragmas play a role in satisfying SPARK elaboration requirements. | |
540 | |
541 With_Clause : Node_Id; | |
542 -- This attribute denotes an internally generated or source with clause | |
543 -- for some unit withed by the main unit. With clauses carry flags which | |
544 -- represent implicit Elaborate or Elaborate_All pragmas. These clauses | |
545 -- play a role in supplying the elaboration dependencies to binde. | |
546 end record; | |
547 | |
548 No_Elaboration_Attributes : constant Elaboration_Attributes := | |
549 (Source_Pragma => Empty, | |
550 With_Clause => Empty); | |
551 | |
552 -- The following type captures relevant attributes which pertain to an | |
553 -- instantiation. | |
554 | |
555 type Instantiation_Attributes is record | |
556 Elab_Checks_OK : Boolean; | |
557 -- This flag is set when the instantiation has elaboration checks | |
558 -- enabled. | |
559 | |
560 Ghost_Mode_Ignore : Boolean; | |
561 -- This flag is set when the instantiation appears in a region subject | |
562 -- to pragma Ghost with policy ignore, or starts one such region. | |
563 | |
564 In_Declarations : Boolean; | |
565 -- This flag is set when the instantiation appears at the declaration | |
566 -- level. | |
567 | |
568 SPARK_Mode_On : Boolean; | |
569 -- This flag is set when the instantiation appears in a region subject | |
570 -- to pragma SPARK_Mode with value On, or starts one such region. | |
571 end record; | |
572 | |
573 -- The following type captures relevant attributes which pertain to a | |
574 -- target. | |
575 | |
576 type Target_Attributes is record | |
577 Elab_Checks_OK : Boolean; | |
578 -- This flag is set when the target has elaboration checks enabled | |
579 | |
580 From_Source : Boolean; | |
581 -- This flag is set when the target comes from source | |
582 | |
583 Ghost_Mode_Ignore : Boolean; | |
584 -- This flag is set when the target appears in a region subject to | |
585 -- pragma Ghost with policy ignore, or starts one such region. | |
586 | |
587 SPARK_Mode_On : Boolean; | |
588 -- This flag is set when the target appears in a region subject to | |
589 -- pragma SPARK_Mode with value On, or starts one such region. | |
590 | |
591 Spec_Decl : Node_Id; | |
592 -- This attribute denotes the declaration of Spec_Id | |
593 | |
594 Unit_Id : Entity_Id; | |
595 -- This attribute denotes the top unit where Spec_Id resides | |
596 | |
597 -- The semantics of the following attributes depend on the target | |
598 | |
599 Body_Barf : Node_Id; | |
600 Body_Decl : Node_Id; | |
601 Spec_Id : Entity_Id; | |
602 | |
603 -- The target is a generic package or a subprogram | |
604 -- | |
605 -- * Body_Barf - Empty | |
606 -- | |
607 -- * Body_Decl - This attribute denotes the generic or subprogram | |
608 -- body. | |
609 -- | |
610 -- * Spec_Id - This attribute denotes the entity of the generic | |
611 -- package or subprogram. | |
612 | |
613 -- The target is a protected entry | |
614 -- | |
615 -- * Body_Barf - This attribute denotes the body of the barrier | |
616 -- function if expansion took place, otherwise it is Empty. | |
617 -- | |
618 -- * Body_Decl - This attribute denotes the body of the procedure | |
619 -- which emulates the entry if expansion took place, otherwise it | |
620 -- denotes the body of the protected entry. | |
621 -- | |
622 -- * Spec_Id - This attribute denotes the entity of the procedure | |
623 -- which emulates the entry if expansion took place, otherwise it | |
624 -- denotes the protected entry. | |
625 | |
626 -- The target is a protected subprogram | |
627 -- | |
628 -- * Body_Barf - Empty | |
629 -- | |
630 -- * Body_Decl - This attribute denotes the body of the protected or | |
631 -- unprotected version of the protected subprogram if expansion took | |
632 -- place, otherwise it denotes the body of the protected subprogram. | |
633 -- | |
634 -- * Spec_Id - This attribute denotes the entity of the protected or | |
635 -- unprotected version of the protected subprogram if expansion took | |
636 -- place, otherwise it is the entity of the protected subprogram. | |
637 | |
638 -- The target is a task entry | |
639 -- | |
640 -- * Body_Barf - Empty | |
641 -- | |
642 -- * Body_Decl - This attribute denotes the body of the procedure | |
643 -- which emulates the task body if expansion took place, otherwise | |
644 -- it denotes the body of the task type. | |
645 -- | |
646 -- * Spec_Id - This attribute denotes the entity of the procedure | |
647 -- which emulates the task body if expansion took place, otherwise | |
648 -- it denotes the entity of the task type. | |
649 end record; | |
650 | |
651 -- The following type captures relevant attributes which pertain to a task | |
652 -- type. | |
653 | |
654 type Task_Attributes is record | |
655 Body_Decl : Node_Id; | |
656 -- This attribute denotes the declaration of the procedure body which | |
657 -- emulates the behaviour of the task body. | |
658 | |
659 Elab_Checks_OK : Boolean; | |
660 -- This flag is set when the task type has elaboration checks enabled | |
661 | |
662 Ghost_Mode_Ignore : Boolean; | |
663 -- This flag is set when the task type appears in a region subject to | |
664 -- pragma Ghost with policy ignore, or starts one such region. | |
665 | |
666 SPARK_Mode_On : Boolean; | |
667 -- This flag is set when the task type appears in a region subject to | |
668 -- pragma SPARK_Mode with value On, or starts one such region. | |
669 | |
670 Spec_Id : Entity_Id; | |
671 -- This attribute denotes the entity of the initial declaration of the | |
672 -- procedure body which emulates the behaviour of the task body. | |
673 | |
674 Task_Decl : Node_Id; | |
675 -- This attribute denotes the declaration of the task type | |
676 | |
677 Unit_Id : Entity_Id; | |
678 -- This attribute denotes the entity of the compilation unit where the | |
679 -- task type resides. | |
680 end record; | |
681 | |
682 -- The following type captures relevant attributes which pertain to a | |
683 -- variable. | |
684 | |
685 type Variable_Attributes is record | |
686 SPARK_Mode_On : Boolean; | |
687 -- This flag is set when the variable appears in a region subject to | |
688 -- pragma SPARK_Mode with value On, or starts one such region. | |
689 | |
690 Unit_Id : Entity_Id; | |
691 -- This attribute denotes the entity of the compilation unit where the | |
692 -- variable resides. | |
693 end record; | |
694 | |
695 --------------------- | |
696 -- Data structures -- | |
697 --------------------- | |
698 | |
699 -- The following table stores the elaboration status of all units withed by | |
700 -- the main unit. | |
701 | |
702 Elaboration_Context_Max : constant := 1009; | |
703 | |
704 type Elaboration_Context_Index is range 0 .. Elaboration_Context_Max - 1; | |
705 | |
706 function Elaboration_Context_Hash | |
707 (Key : Entity_Id) return Elaboration_Context_Index; | |
708 -- Obtain the hash value of entity Key | |
709 | |
710 package Elaboration_Context is new Simple_HTable | |
711 (Header_Num => Elaboration_Context_Index, | |
712 Element => Elaboration_Attributes, | |
713 No_Element => No_Elaboration_Attributes, | |
714 Key => Entity_Id, | |
715 Hash => Elaboration_Context_Hash, | |
716 Equal => "="); | |
717 | |
718 -- The following table stores all active scenarios in a recursive traversal | |
719 -- starting from a top level scenario. This table must be maintained in a | |
720 -- FIFO fashion. | |
721 | |
722 package Scenario_Stack is new Table.Table | |
723 (Table_Component_Type => Node_Id, | |
724 Table_Index_Type => Int, | |
725 Table_Low_Bound => 1, | |
726 Table_Initial => 50, | |
727 Table_Increment => 100, | |
728 Table_Name => "Scenario_Stack"); | |
729 | |
730 -- The following table stores all top level scenario saved during the | |
731 -- Recording phase. The contents of this table act as traversal roots | |
732 -- later in the Processing phase. This table must be maintained in a | |
733 -- LIFO fashion. | |
734 | |
735 package Top_Level_Scenarios is new Table.Table | |
736 (Table_Component_Type => Node_Id, | |
737 Table_Index_Type => Int, | |
738 Table_Low_Bound => 1, | |
739 Table_Initial => 1000, | |
740 Table_Increment => 100, | |
741 Table_Name => "Top_Level_Scenarios"); | |
742 | |
743 -- The following table stores the bodies of all eligible scenarios visited | |
744 -- during a traversal starting from a top level scenario. The contents of | |
745 -- this table must be reset upon each new traversal. | |
746 | |
747 Visited_Bodies_Max : constant := 511; | |
748 | |
749 type Visited_Bodies_Index is range 0 .. Visited_Bodies_Max - 1; | |
750 | |
751 function Visited_Bodies_Hash (Key : Node_Id) return Visited_Bodies_Index; | |
752 -- Obtain the hash value of node Key | |
753 | |
754 package Visited_Bodies is new Simple_HTable | |
755 (Header_Num => Visited_Bodies_Index, | |
756 Element => Boolean, | |
757 No_Element => False, | |
758 Key => Node_Id, | |
759 Hash => Visited_Bodies_Hash, | |
760 Equal => "="); | |
761 | |
762 ----------------------- | |
763 -- Local subprograms -- | |
764 ----------------------- | |
765 | |
766 procedure Check_Preelaborated_Call (Call : Node_Id); | |
767 -- Determine whether entry, operator, or subprogram call Call appears at | |
768 -- the library level of a preelaborated unit. Emit an error if this is the | |
769 -- case. | |
770 | |
771 function Compilation_Unit (Unit_Id : Entity_Id) return Node_Id; | |
772 pragma Inline (Compilation_Unit); | |
773 -- Return the N_Compilation_Unit node of unit Unit_Id | |
774 | |
775 procedure Elab_Msg_NE | |
776 (Msg : String; | |
777 N : Node_Id; | |
778 Id : Entity_Id; | |
779 Info_Msg : Boolean; | |
780 In_SPARK : Boolean); | |
781 pragma Inline (Elab_Msg_NE); | |
782 -- Wrapper around Error_Msg_NE. Emit message Msg concerning arbitrary node | |
783 -- N and entity. If flag Info_Msg is set, the routine emits an information | |
784 -- message, otherwise it emits an error. If flag In_SPARK is set, then | |
785 -- string " in SPARK" is added to the end of the message. | |
786 | |
787 procedure Ensure_Prior_Elaboration | |
788 (N : Node_Id; | |
789 Unit_Id : Entity_Id; | |
790 In_Task_Body : Boolean); | |
791 -- Guarantee the elaboration of unit Unit_Id with respect to the main unit. | |
792 -- N denotes the related scenario. Flag In_Task_Body should be set when the | |
793 -- need for elaboration is initiated from a task body. | |
794 | |
795 procedure Ensure_Prior_Elaboration_Dynamic | |
796 (N : Node_Id; | |
797 Unit_Id : Entity_Id; | |
798 Prag_Nam : Name_Id); | |
799 -- Guarantee the elaboration of unit Unit_Id with respect to the main unit | |
800 -- by suggesting the use of Elaborate[_All] with name Prag_Nam. N denotes | |
801 -- the related scenario. | |
802 | |
803 procedure Ensure_Prior_Elaboration_Static | |
804 (N : Node_Id; | |
805 Unit_Id : Entity_Id; | |
806 Prag_Nam : Name_Id); | |
807 -- Guarantee the elaboration of unit Unit_Id with respect to the main unit | |
808 -- by installing an implicit Elaborate[_All] pragma with name Prag_Nam. N | |
809 -- denotes the related scenario. | |
810 | |
811 function Extract_Assignment_Name (Asmt : Node_Id) return Node_Id; | |
812 pragma Inline (Extract_Assignment_Name); | |
813 -- Obtain the Name attribute of assignment statement Asmt | |
814 | |
815 procedure Extract_Call_Attributes | |
816 (Call : Node_Id; | |
817 Target_Id : out Entity_Id; | |
818 Attrs : out Call_Attributes); | |
819 pragma Inline (Extract_Call_Attributes); | |
820 -- Obtain attributes Attrs associated with call Call. Target_Id is the | |
821 -- entity of the call target. | |
822 | |
823 function Extract_Call_Name (Call : Node_Id) return Node_Id; | |
824 pragma Inline (Extract_Call_Name); | |
825 -- Obtain the Name attribute of entry or subprogram call Call | |
826 | |
827 procedure Extract_Instance_Attributes | |
828 (Exp_Inst : Node_Id; | |
829 Inst_Body : out Node_Id; | |
830 Inst_Decl : out Node_Id); | |
831 pragma Inline (Extract_Instance_Attributes); | |
832 -- Obtain body Inst_Body and spec Inst_Decl of expanded instance Exp_Inst | |
833 | |
834 procedure Extract_Instantiation_Attributes | |
835 (Exp_Inst : Node_Id; | |
836 Inst : out Node_Id; | |
837 Inst_Id : out Entity_Id; | |
838 Gen_Id : out Entity_Id; | |
839 Attrs : out Instantiation_Attributes); | |
840 pragma Inline (Extract_Instantiation_Attributes); | |
841 -- Obtain attributes Attrs associated with expanded instantiation Exp_Inst. | |
842 -- Inst is the instantiation. Inst_Id is the entity of the instance. Gen_Id | |
843 -- is the entity of the generic unit being instantiated. | |
844 | |
845 procedure Extract_Target_Attributes | |
846 (Target_Id : Entity_Id; | |
847 Attrs : out Target_Attributes); | |
848 -- Obtain attributes Attrs associated with an entry, package, or subprogram | |
849 -- denoted by Target_Id. | |
850 | |
851 procedure Extract_Task_Attributes | |
852 (Typ : Entity_Id; | |
853 Attrs : out Task_Attributes); | |
854 pragma Inline (Extract_Task_Attributes); | |
855 -- Obtain attributes Attrs associated with task type Typ | |
856 | |
857 procedure Extract_Variable_Reference_Attributes | |
858 (Ref : Node_Id; | |
859 Var_Id : out Entity_Id; | |
860 Attrs : out Variable_Attributes); | |
861 pragma Inline (Extract_Variable_Reference_Attributes); | |
862 -- Obtain attributes Attrs associated with reference Ref that mentions | |
863 -- variable Var_Id. | |
864 | |
865 function Find_Code_Unit (N : Node_Or_Entity_Id) return Entity_Id; | |
866 pragma Inline (Find_Code_Unit); | |
867 -- Return the code unit which contains arbitrary node or entity N. This | |
868 -- is the unit of the file which physically contains the related construct | |
869 -- denoted by N except when N is within an instantiation. In that case the | |
870 -- unit is that of the top level instantiation. | |
871 | |
872 procedure Find_Elaborated_Units; | |
873 -- Populate table Elaboration_Context with all units which have prior | |
874 -- elaboration with respect to the main unit. | |
875 | |
876 function Find_Enclosing_Instance (N : Node_Id) return Node_Id; | |
877 pragma Inline (Find_Enclosing_Instance); | |
878 -- Find the declaration or body of the nearest expanded instance which | |
879 -- encloses arbitrary node N. Return Empty if no such instance exists. | |
880 | |
881 function Find_Top_Unit (N : Node_Or_Entity_Id) return Entity_Id; | |
882 pragma Inline (Find_Top_Unit); | |
883 -- Return the top unit which contains arbitrary node or entity N. The unit | |
884 -- is obtained by logically unwinding instantiations and subunits when N | |
885 -- resides within one. | |
886 | |
887 function Find_Unit_Entity (N : Node_Id) return Entity_Id; | |
888 pragma Inline (Find_Unit_Entity); | |
889 -- Return the entity of unit N | |
890 | |
891 function First_Formal_Type (Subp_Id : Entity_Id) return Entity_Id; | |
892 pragma Inline (First_Formal_Type); | |
893 -- Return the type of subprogram Subp_Id's first formal parameter. If the | |
894 -- subprogram lacks formal parameters, return Empty. | |
895 | |
896 function Has_Body (Pack_Decl : Node_Id) return Boolean; | |
897 -- Determine whether package declaration Pack_Decl has a corresponding body | |
898 -- or would eventually have one. | |
899 | |
900 function Has_Prior_Elaboration | |
901 (Unit_Id : Entity_Id; | |
902 Context_OK : Boolean := False; | |
903 Elab_Body_OK : Boolean := False; | |
904 Same_Unit_OK : Boolean := False) return Boolean; | |
905 pragma Inline (Has_Prior_Elaboration); | |
906 -- Determine whether unit Unit_Id is elaborated prior to the main unit. | |
907 -- If flag Context_OK is set, the routine considers the following case | |
908 -- as valid prior elaboration: | |
909 -- | |
910 -- * Unit_Id is in the elaboration context of the main unit | |
911 -- | |
912 -- If flag Elab_Body_OK is set, the routine considers the following case | |
913 -- as valid prior elaboration: | |
914 -- | |
915 -- * Unit_Id has pragma Elaborate_Body and is not the main unit | |
916 -- | |
917 -- If flag Same_Unit_OK is set, the routine considers the following cases | |
918 -- as valid prior elaboration: | |
919 -- | |
920 -- * Unit_Id is the main unit | |
921 -- | |
922 -- * Unit_Id denotes the spec of the main unit body | |
923 | |
924 function In_External_Instance | |
925 (N : Node_Id; | |
926 Target_Decl : Node_Id) return Boolean; | |
927 pragma Inline (In_External_Instance); | |
928 -- Determine whether a target desctibed by its declaration Target_Decl | |
929 -- resides in a package instance which is external to scenario N. | |
930 | |
931 function In_Main_Context (N : Node_Id) return Boolean; | |
932 pragma Inline (In_Main_Context); | |
933 -- Determine whether arbitrary node N appears within the main compilation | |
934 -- unit. | |
935 | |
936 function In_Same_Context | |
937 (N1 : Node_Id; | |
938 N2 : Node_Id; | |
939 Nested_OK : Boolean := False) return Boolean; | |
940 -- Determine whether two arbitrary nodes N1 and N2 appear within the same | |
941 -- context ignoring enclosing library levels. Nested_OK should be set when | |
942 -- the context of N1 can enclose that of N2. | |
943 | |
944 procedure Info_Call | |
945 (Call : Node_Id; | |
946 Target_Id : Entity_Id; | |
947 Info_Msg : Boolean; | |
948 In_SPARK : Boolean); | |
949 -- Output information concerning call Call which invokes target Target_Id. | |
950 -- If flag Info_Msg is set, the routine emits an information message, | |
951 -- otherwise it emits an error. If flag In_SPARK is set, then the string | |
952 -- " in SPARK" is added to the end of the message. | |
953 | |
954 procedure Info_Instantiation | |
955 (Inst : Node_Id; | |
956 Gen_Id : Entity_Id; | |
957 Info_Msg : Boolean; | |
958 In_SPARK : Boolean); | |
959 pragma Inline (Info_Instantiation); | |
960 -- Output information concerning instantiation Inst which instantiates | |
961 -- generic unit Gen_Id. If flag Info_Msg is set, the routine emits an | |
962 -- information message, otherwise it emits an error. If flag In_SPARK | |
963 -- is set, then string " in SPARK" is added to the end of the message. | |
964 | |
965 procedure Info_Variable_Read | |
966 (Ref : Node_Id; | |
967 Var_Id : Entity_Id; | |
968 Info_Msg : Boolean; | |
969 In_SPARK : Boolean); | |
970 pragma Inline (Info_Variable_Read); | |
971 -- Output information concerning reference Ref which reads variable Var_Id. | |
972 -- If flag Info_Msg is set, the routine emits an information message, | |
973 -- otherwise it emits an error. If flag In_SPARK is set, then string " in | |
974 -- SPARK" is added to the end of the message. | |
975 | |
976 function Insertion_Node (N : Node_Id; Ins_Nod : Node_Id) return Node_Id; | |
977 pragma Inline (Insertion_Node); | |
978 -- Obtain the proper insertion node of an ABE check or failure for scenario | |
979 -- N and candidate insertion node Ins_Nod. | |
980 | |
981 procedure Install_ABE_Check | |
982 (N : Node_Id; | |
983 Id : Entity_Id; | |
984 Ins_Nod : Node_Id); | |
985 -- Insert a run-time ABE check for elaboration scenario N which verifies | |
986 -- whether arbitrary entity Id is elaborated. The check in inserted prior | |
987 -- to node Ins_Nod. | |
988 | |
989 procedure Install_ABE_Check | |
990 (N : Node_Id; | |
991 Target_Id : Entity_Id; | |
992 Target_Decl : Node_Id; | |
993 Target_Body : Node_Id; | |
994 Ins_Nod : Node_Id); | |
995 -- Insert a run-time ABE check for elaboration scenario N which verifies | |
996 -- whether target Target_Id with initial declaration Target_Decl and body | |
997 -- Target_Body is elaborated. The check is inserted prior to node Ins_Nod. | |
998 | |
999 procedure Install_ABE_Failure (N : Node_Id; Ins_Nod : Node_Id); | |
1000 -- Insert a Program_Error concerning a guaranteed ABE for elaboration | |
1001 -- scenario N. The failure is inserted prior to node Node_Id. | |
1002 | |
1003 function Is_Accept_Alternative_Proc (Id : Entity_Id) return Boolean; | |
1004 pragma Inline (Is_Accept_Alternative_Proc); | |
1005 -- Determine whether arbitrary entity Id denotes an internally generated | |
1006 -- procedure which encapsulates the statements of an accept alternative. | |
1007 | |
1008 function Is_Activation_Proc (Id : Entity_Id) return Boolean; | |
1009 pragma Inline (Is_Activation_Proc); | |
1010 -- Determine whether arbitrary entity Id denotes a runtime procedure in | |
1011 -- charge with activating tasks. | |
1012 | |
1013 function Is_Ada_Semantic_Target (Id : Entity_Id) return Boolean; | |
1014 pragma Inline (Is_Ada_Semantic_Target); | |
1015 -- Determine whether arbitrary entity Id nodes a source or internally | |
1016 -- generated subprogram which emulates Ada semantics. | |
1017 | |
1018 function Is_Bodiless_Subprogram (Subp_Id : Entity_Id) return Boolean; | |
1019 pragma Inline (Is_Bodiless_Subprogram); | |
1020 -- Determine whether subprogram Subp_Id will never have a body | |
1021 | |
1022 function Is_Check_Emitting_Scenario (N : Node_Id) return Boolean; | |
1023 pragma Inline (Is_Check_Emitting_Scenario); | |
1024 -- Determine whether arbitrary node N denotes a scenario which may emit a | |
1025 -- conditional ABE check. | |
1026 | |
1027 function Is_Controlled_Proc | |
1028 (Subp_Id : Entity_Id; | |
1029 Subp_Nam : Name_Id) return Boolean; | |
1030 pragma Inline (Is_Controlled_Proc); | |
1031 -- Determine whether subprogram Subp_Id denotes controlled type primitives | |
1032 -- Adjust, Finalize, or Initialize as denoted by name Subp_Nam. | |
1033 | |
1034 function Is_Default_Initial_Condition_Proc (Id : Entity_Id) return Boolean; | |
1035 pragma Inline (Is_Default_Initial_Condition_Proc); | |
1036 -- Determine whether arbitrary entity Id denotes internally generated | |
1037 -- routine Default_Initial_Condition. | |
1038 | |
1039 function Is_Finalizer_Proc (Id : Entity_Id) return Boolean; | |
1040 pragma Inline (Is_Finalizer_Proc); | |
1041 -- Determine whether arbitrary entity Id denotes internally generated | |
1042 -- routine _Finalizer. | |
1043 | |
1044 function Is_Guaranteed_ABE | |
1045 (N : Node_Id; | |
1046 Target_Decl : Node_Id; | |
1047 Target_Body : Node_Id) return Boolean; | |
1048 pragma Inline (Is_Guaranteed_ABE); | |
1049 -- Determine whether scenario N with a target described by its initial | |
1050 -- declaration Target_Decl and body Target_Decl results in a guaranteed | |
1051 -- ABE. | |
1052 | |
1053 function Is_Initial_Condition_Proc (Id : Entity_Id) return Boolean; | |
1054 pragma Inline (Is_Initial_Condition_Proc); | |
1055 -- Determine whether arbitrary entity Id denotes internally generated | |
1056 -- routine Initial_Condition. | |
1057 | |
1058 function Is_Initialized (Obj_Decl : Node_Id) return Boolean; | |
1059 pragma Inline (Is_Initialized); | |
1060 -- Determine whether object declaration Obj_Decl is initialized | |
1061 | |
1062 function Is_Invariant_Proc (Id : Entity_Id) return Boolean; | |
1063 pragma Inline (Is_Invariant_Proc); | |
1064 -- Determine whether arbitrary entity Id denotes an invariant procedure | |
1065 | |
1066 function Is_Non_Library_Level_Encapsulator (N : Node_Id) return Boolean; | |
1067 pragma Inline (Is_Non_Library_Level_Encapsulator); | |
1068 -- Determine whether arbitrary node N is a non-library encapsulator | |
1069 | |
1070 function Is_Partial_Invariant_Proc (Id : Entity_Id) return Boolean; | |
1071 pragma Inline (Is_Partial_Invariant_Proc); | |
1072 -- Determine whether arbitrary entity Id denotes a partial invariant | |
1073 -- procedure. | |
1074 | |
1075 function Is_Postconditions_Proc (Id : Entity_Id) return Boolean; | |
1076 pragma Inline (Is_Postconditions_Proc); | |
1077 -- Determine whether arbitrary entity Id denotes internally generated | |
1078 -- routine _Postconditions. | |
1079 | |
1080 function Is_Preelaborated_Unit (Id : Entity_Id) return Boolean; | |
1081 pragma Inline (Is_Preelaborated_Unit); | |
1082 -- Determine whether arbitrary entity Id denotes a unit which is subject to | |
1083 -- one of the following pragmas: | |
1084 -- | |
1085 -- * Preelaborable | |
1086 -- * Pure | |
1087 -- * Remote_Call_Interface | |
1088 -- * Remote_Types | |
1089 -- * Shared_Passive | |
1090 | |
1091 function Is_Protected_Entry (Id : Entity_Id) return Boolean; | |
1092 pragma Inline (Is_Protected_Entry); | |
1093 -- Determine whether arbitrary entity Id denotes a protected entry | |
1094 | |
1095 function Is_Protected_Subp (Id : Entity_Id) return Boolean; | |
1096 pragma Inline (Is_Protected_Subp); | |
1097 -- Determine whether entity Id denotes a protected subprogram | |
1098 | |
1099 function Is_Protected_Body_Subp (Id : Entity_Id) return Boolean; | |
1100 pragma Inline (Is_Protected_Body_Subp); | |
1101 -- Determine whether entity Id denotes the protected or unprotected version | |
1102 -- of a protected subprogram. | |
1103 | |
1104 function Is_Safe_Activation | |
1105 (Call : Node_Id; | |
1106 Task_Decl : Node_Id) return Boolean; | |
1107 pragma Inline (Is_Safe_Activation); | |
1108 -- Determine whether call Call which activates a task object described by | |
1109 -- declaration Task_Decl is always ABE-safe. | |
1110 | |
1111 function Is_Safe_Call | |
1112 (Call : Node_Id; | |
1113 Target_Attrs : Target_Attributes) return Boolean; | |
1114 pragma Inline (Is_Safe_Call); | |
1115 -- Determine whether call Call which invokes a target described by | |
1116 -- attributes Target_Attrs is always ABE-safe. | |
1117 | |
1118 function Is_Safe_Instantiation | |
1119 (Inst : Node_Id; | |
1120 Gen_Attrs : Target_Attributes) return Boolean; | |
1121 pragma Inline (Is_Safe_Instantiation); | |
1122 -- Determine whether instance Inst which instantiates a generic unit | |
1123 -- described by attributes Gen_Attrs is always ABE-safe. | |
1124 | |
1125 function Is_Same_Unit | |
1126 (Unit_1 : Entity_Id; | |
1127 Unit_2 : Entity_Id) return Boolean; | |
1128 pragma Inline (Is_Same_Unit); | |
1129 -- Determine whether entities Unit_1 and Unit_2 denote the same unit | |
1130 | |
1131 function Is_Scenario (N : Node_Id) return Boolean; | |
1132 pragma Inline (Is_Scenario); | |
1133 -- Determine whether attribute node N denotes a scenario. The scenario may | |
1134 -- not necessarily be eligible for ABE processing. | |
1135 | |
1136 function Is_SPARK_Semantic_Target (Id : Entity_Id) return Boolean; | |
1137 pragma Inline (Is_SPARK_Semantic_Target); | |
1138 -- Determine whether arbitrary entity Id nodes a source or internally | |
1139 -- generated subprogram which emulates SPARK semantics. | |
1140 | |
1141 function Is_Suitable_Access (N : Node_Id) return Boolean; | |
1142 pragma Inline (Is_Suitable_Access); | |
1143 -- Determine whether arbitrary node N denotes a suitable attribute for ABE | |
1144 -- processing. | |
1145 | |
1146 function Is_Suitable_Call (N : Node_Id) return Boolean; | |
1147 pragma Inline (Is_Suitable_Call); | |
1148 -- Determine whether arbitrary node N denotes a suitable call for ABE | |
1149 -- processing. | |
1150 | |
1151 function Is_Suitable_Instantiation (N : Node_Id) return Boolean; | |
1152 pragma Inline (Is_Suitable_Instantiation); | |
1153 -- Determine whether arbitrary node N is a suitable instantiation for ABE | |
1154 -- processing. | |
1155 | |
1156 function Is_Suitable_Scenario (N : Node_Id) return Boolean; | |
1157 pragma Inline (Is_Suitable_Scenario); | |
1158 -- Determine whether arbitrary node N is a suitable scenario for ABE | |
1159 -- processing. | |
1160 | |
1161 function Is_Suitable_Variable_Assignment (N : Node_Id) return Boolean; | |
1162 pragma Inline (Is_Suitable_Variable_Assignment); | |
1163 -- Determine whether arbitrary node N denotes a suitable assignment for ABE | |
1164 -- processing. | |
1165 | |
1166 function Is_Suitable_Variable_Read (N : Node_Id) return Boolean; | |
1167 pragma Inline (Is_Suitable_Variable_Read); | |
1168 -- Determine whether arbitrary node N is a suitable variable read for ABE | |
1169 -- processing. | |
1170 | |
1171 function Is_Task_Entry (Id : Entity_Id) return Boolean; | |
1172 pragma Inline (Is_Task_Entry); | |
1173 -- Determine whether arbitrary entity Id denotes a task entry | |
1174 | |
1175 function Is_Up_Level_Target (Target_Decl : Node_Id) return Boolean; | |
1176 pragma Inline (Is_Up_Level_Target); | |
1177 -- Determine whether the current root resides at the declaration level. If | |
1178 -- this is the case, determine whether a target described by declaration | |
1179 -- Target_Decl is within a context which encloses the current root or is in | |
1180 -- a different unit. | |
1181 | |
1182 procedure Meet_Elaboration_Requirement | |
1183 (N : Node_Id; | |
1184 Target_Id : Entity_Id; | |
1185 Req_Nam : Name_Id); | |
1186 -- Determine whether elaboration requirement Req_Nam for scenario N with | |
1187 -- target Target_Id is met by the context of the main unit using the SPARK | |
1188 -- rules. Req_Nam must denote either Elaborate or Elaborate_All. Emit an | |
1189 -- error if this is not the case. | |
1190 | |
1191 function Non_Private_View (Typ : Entity_Id) return Entity_Id; | |
1192 pragma Inline (Non_Private_View); | |
1193 -- Return the full view of private type Typ if available, otherwise return | |
1194 -- type Typ. | |
1195 | |
1196 procedure Output_Active_Scenarios (Error_Nod : Node_Id); | |
1197 -- Output the contents of the active scenario stack from earliest to latest | |
1198 -- to supplement an earlier error emitted for node Error_Nod. | |
1199 | |
1200 procedure Pop_Active_Scenario (N : Node_Id); | |
1201 pragma Inline (Pop_Active_Scenario); | |
1202 -- Pop the top of the scenario stack. A check is made to ensure that the | |
1203 -- scenario being removed is the same as N. | |
1204 | |
1205 procedure Process_Access (Attr : Node_Id; In_Task_Body : Boolean); | |
1206 -- Perform ABE checks and diagnostics for 'Access to entry, operator, or | |
1207 -- subprogram denoted by Attr. Flag In_Task_Body should be set when the | |
1208 -- processing is initiated from a task body. | |
1209 | |
1210 generic | |
1211 with procedure Process_Single_Activation | |
1212 (Call : Node_Id; | |
1213 Call_Attrs : Call_Attributes; | |
1214 Obj_Id : Entity_Id; | |
1215 Task_Attrs : Task_Attributes; | |
1216 In_Task_Body : Boolean); | |
1217 -- Perform ABE checks and diagnostics for task activation call Call | |
1218 -- which activates task Obj_Id. Call_Attrs are the attributes of the | |
1219 -- activation call. Task_Attrs are the attributes of the task type. | |
1220 -- Flag In_Task_Body should be set when the processing is initiated | |
1221 -- from a task body. | |
1222 | |
1223 procedure Process_Activation_Call | |
1224 (Call : Node_Id; | |
1225 Call_Attrs : Call_Attributes; | |
1226 In_Task_Body : Boolean); | |
1227 -- Perform ABE checks and diagnostics for activation call Call by invoking | |
1228 -- routine Process_Single_Activation on each task object being activated. | |
1229 -- Call_Attrs are the attributes of the activation call. Flag In_Task_Body | |
1230 -- should be set when the processing is initiated from a task body. | |
1231 | |
1232 procedure Process_Activation_Conditional_ABE_Impl | |
1233 (Call : Node_Id; | |
1234 Call_Attrs : Call_Attributes; | |
1235 Obj_Id : Entity_Id; | |
1236 Task_Attrs : Task_Attributes; | |
1237 In_Task_Body : Boolean); | |
1238 -- Perform common conditional ABE checks and diagnostics for call Call | |
1239 -- which activates task Obj_Id ignoring the Ada or SPARK rules. CAll_Attrs | |
1240 -- are the attributes of the activation call. Task_Attrs are the attributes | |
1241 -- of the task type. Flag In_Task_Body should be set when the processing is | |
1242 -- initiated from a task body. | |
1243 | |
1244 procedure Process_Activation_Guaranteed_ABE_Impl | |
1245 (Call : Node_Id; | |
1246 Call_Attrs : Call_Attributes; | |
1247 Obj_Id : Entity_Id; | |
1248 Task_Attrs : Task_Attributes; | |
1249 In_Task_Body : Boolean); | |
1250 -- Perform common guaranteed ABE checks and diagnostics for call Call | |
1251 -- which activates task Obj_Id ignoring the Ada or SPARK rules. CAll_Attrs | |
1252 -- are the attributes of the activation call. Task_Attrs are the attributes | |
1253 -- of the task type. Flag In_Task_Body should be set when the processing is | |
1254 -- initiated from a task body. | |
1255 | |
1256 procedure Process_Call | |
1257 (Call : Node_Id; | |
1258 Call_Attrs : Call_Attributes; | |
1259 Target_Id : Entity_Id; | |
1260 In_Task_Body : Boolean); | |
1261 -- Top-level dispatcher for processing of calls. Perform ABE checks and | |
1262 -- diagnostics for call Call which invokes target Target_Id. Call_Attrs | |
1263 -- are the attributes of the call. Flag In_Task_Body should be set when | |
1264 -- the processing is initiated from a task body. | |
1265 | |
1266 procedure Process_Call_Ada | |
1267 (Call : Node_Id; | |
1268 Call_Attrs : Call_Attributes; | |
1269 Target_Id : Entity_Id; | |
1270 Target_Attrs : Target_Attributes; | |
1271 In_Task_Body : Boolean); | |
1272 -- Perform ABE checks and diagnostics for call Call which invokes target | |
1273 -- Target_Id using the Ada rules. Call_Attrs are the attributes of the | |
1274 -- call. Target_Attrs are attributes of the target. Flag In_Task_Body | |
1275 -- should be set when the processing is initiated from a task body. | |
1276 | |
1277 procedure Process_Call_Conditional_ABE | |
1278 (Call : Node_Id; | |
1279 Call_Attrs : Call_Attributes; | |
1280 Target_Id : Entity_Id; | |
1281 Target_Attrs : Target_Attributes); | |
1282 -- Perform common conditional ABE checks and diagnostics for call Call that | |
1283 -- invokes target Target_Id ignoring the Ada or SPARK rules. Call_Attrs are | |
1284 -- the attributes of the call. Target_Attrs are attributes of the target. | |
1285 | |
1286 procedure Process_Call_Guaranteed_ABE | |
1287 (Call : Node_Id; | |
1288 Call_Attrs : Call_Attributes; | |
1289 Target_Id : Entity_Id); | |
1290 -- Perform common guaranteed ABE checks and diagnostics for call Call which | |
1291 -- invokes target Target_Id ignoring the Ada or SPARK rules. Call_Attrs are | |
1292 -- the attributes of the call. | |
1293 | |
1294 procedure Process_Call_SPARK | |
1295 (Call : Node_Id; | |
1296 Call_Attrs : Call_Attributes; | |
1297 Target_Id : Entity_Id; | |
1298 Target_Attrs : Target_Attributes); | |
1299 -- Perform ABE checks and diagnostics for call Call which invokes target | |
1300 -- Target_Id using the SPARK rules. Call_Attrs are the attributes of the | |
1301 -- call. Target_Attrs are attributes of the target. | |
1302 | |
1303 procedure Process_Guaranteed_ABE (N : Node_Id); | |
1304 -- Top level dispatcher for processing of scenarios which result in a | |
1305 -- guaranteed ABE. | |
1306 | |
1307 procedure Process_Instantiation | |
1308 (Exp_Inst : Node_Id; | |
1309 In_Task_Body : Boolean); | |
1310 -- Top level dispatcher for processing of instantiations. Perform ABE | |
1311 -- checks and diagnostics for expanded instantiation Exp_Inst. Flag | |
1312 -- In_Task_Body should be set when the processing is initiated from a | |
1313 -- task body. | |
1314 | |
1315 procedure Process_Instantiation_Ada | |
1316 (Exp_Inst : Node_Id; | |
1317 Inst : Node_Id; | |
1318 Inst_Attrs : Instantiation_Attributes; | |
1319 Gen_Id : Entity_Id; | |
1320 Gen_Attrs : Target_Attributes; | |
1321 In_Task_Body : Boolean); | |
1322 -- Perform ABE checks and diagnostics for expanded instantiation Exp_Inst | |
1323 -- of generic Gen_Id using the Ada rules. Inst is the instantiation node. | |
1324 -- Inst_Attrs are the attributes of the instance. Gen_Attrs are the | |
1325 -- attributes of the generic. Flag In_Task_Body should be set when the | |
1326 -- processing is initiated from a task body. | |
1327 | |
1328 procedure Process_Instantiation_Conditional_ABE | |
1329 (Exp_Inst : Node_Id; | |
1330 Inst : Node_Id; | |
1331 Inst_Attrs : Instantiation_Attributes; | |
1332 Gen_Id : Entity_Id; | |
1333 Gen_Attrs : Target_Attributes); | |
1334 -- Perform common conditional ABE checks and diagnostics for expanded | |
1335 -- instantiation Exp_Inst of generic Gen_Id ignoring the Ada or SPARK | |
1336 -- rules. Inst is the instantiation node. Inst_Attrs are the attributes | |
1337 -- of the instance. Gen_Attrs are the attributes of the generic. | |
1338 | |
1339 procedure Process_Instantiation_Guaranteed_ABE (Exp_Inst : Node_Id); | |
1340 -- Perform common guaranteed ABE checks and diagnostics for expanded | |
1341 -- instantiation Exp_Inst of generic Gen_Id ignoring the Ada or SPARK | |
1342 -- rules. | |
1343 | |
1344 procedure Process_Instantiation_SPARK | |
1345 (Exp_Inst : Node_Id; | |
1346 Inst : Node_Id; | |
1347 Inst_Attrs : Instantiation_Attributes; | |
1348 Gen_Id : Entity_Id; | |
1349 Gen_Attrs : Target_Attributes); | |
1350 -- Perform ABE checks and diagnostics for expanded instantiation Exp_Inst | |
1351 -- of generic Gen_Id using the SPARK rules. Inst is the instantiation node. | |
1352 -- Inst_Attrs are the attributes of the instance. Gen_Attrs are the | |
1353 -- attributes of the generic. | |
1354 | |
1355 procedure Process_Scenario (N : Node_Id; In_Task_Body : Boolean := False); | |
1356 -- Top level dispatcher for processing of various elaboration scenarios. | |
1357 -- Perform ABE checks and diagnostics for scenario N. Flag In_Task_Body | |
1358 -- should be set when the processing is initiated from a task body. | |
1359 | |
1360 procedure Process_Variable_Assignment (Asmt : Node_Id); | |
1361 -- Top level dispatcher for processing of variable assignments. Perform ABE | |
1362 -- checks and diagnostics for assignment statement Asmt. | |
1363 | |
1364 procedure Process_Variable_Assignment_Ada | |
1365 (Asmt : Node_Id; | |
1366 Var_Id : Entity_Id); | |
1367 -- Perform ABE checks and diagnostics for assignment statement Asmt that | |
1368 -- updates the value of variable Var_Id using the Ada rules. | |
1369 | |
1370 procedure Process_Variable_Assignment_SPARK | |
1371 (Asmt : Node_Id; | |
1372 Var_Id : Entity_Id); | |
1373 -- Perform ABE checks and diagnostics for assignment statement Asmt that | |
1374 -- updates the value of variable Var_Id using the SPARK rules. | |
1375 | |
1376 procedure Process_Variable_Read (Ref : Node_Id); | |
1377 -- Perform ABE checks and diagnostics for reference Ref that reads a | |
1378 -- variable. | |
1379 | |
1380 procedure Push_Active_Scenario (N : Node_Id); | |
1381 pragma Inline (Push_Active_Scenario); | |
1382 -- Push scenario N on top of the scenario stack | |
1383 | |
1384 function Root_Scenario return Node_Id; | |
1385 pragma Inline (Root_Scenario); | |
1386 -- Return the top level scenario which started a recursive search for other | |
1387 -- scenarios. It is assumed that there is a valid top level scenario on the | |
1388 -- active scenario stack. | |
1389 | |
1390 function Static_Elaboration_Checks return Boolean; | |
1391 pragma Inline (Static_Elaboration_Checks); | |
1392 -- Determine whether the static model is in effect | |
1393 | |
1394 procedure Traverse_Body (N : Node_Id; In_Task_Body : Boolean); | |
1395 -- Inspect the declarations and statements of subprogram body N for | |
1396 -- suitable elaboration scenarios and process them. Flag In_Task_Body | |
1397 -- should be set when the traversal is initiated from a task body. | |
1398 | |
1399 procedure Update_Elaboration_Scenario (New_N : Node_Id; Old_N : Node_Id); | |
1400 pragma Inline (Update_Elaboration_Scenario); | |
1401 -- Update all relevant internal data structures when scenario Old_N is | |
1402 -- transformed into scenario New_N by Atree.Rewrite. | |
1403 | |
1404 ----------------------- | |
1405 -- Build_Call_Marker -- | |
1406 ----------------------- | |
1407 | |
1408 procedure Build_Call_Marker (N : Node_Id) is | |
1409 function In_External_Context | |
1410 (Call : Node_Id; | |
1411 Target_Id : Entity_Id) return Boolean; | |
1412 pragma Inline (In_External_Context); | |
1413 -- Determine whether target Target_Id is external to call N which must | |
1414 -- reside within an instance. | |
1415 | |
1416 function In_Premature_Context (Call : Node_Id) return Boolean; | |
1417 -- Determine whether call Call appears within a premature context | |
1418 | |
1419 function Is_Bridge_Target (Id : Entity_Id) return Boolean; | |
1420 pragma Inline (Is_Bridge_Target); | |
1421 -- Determine whether arbitrary entity Id denotes a bridge target | |
1422 | |
1423 function Is_Default_Expression (Call : Node_Id) return Boolean; | |
1424 pragma Inline (Is_Default_Expression); | |
1425 -- Determine whether call Call acts as the expression of a defaulted | |
1426 -- parameter within a source call. | |
1427 | |
1428 function Is_Generic_Formal_Subp (Subp_Id : Entity_Id) return Boolean; | |
1429 pragma Inline (Is_Generic_Formal_Subp); | |
1430 -- Determine whether subprogram Subp_Id denotes a generic formal | |
1431 -- subprogram which appears in the "prologue" of an instantiation. | |
1432 | |
1433 ------------------------- | |
1434 -- In_External_Context -- | |
1435 ------------------------- | |
1436 | |
1437 function In_External_Context | |
1438 (Call : Node_Id; | |
1439 Target_Id : Entity_Id) return Boolean | |
1440 is | |
1441 Target_Decl : constant Node_Id := Unit_Declaration_Node (Target_Id); | |
1442 | |
1443 Inst : Node_Id; | |
1444 Inst_Body : Node_Id; | |
1445 Inst_Decl : Node_Id; | |
1446 | |
1447 begin | |
1448 -- Performance note: parent traversal | |
1449 | |
1450 Inst := Find_Enclosing_Instance (Call); | |
1451 | |
1452 -- The call appears within an instance | |
1453 | |
1454 if Present (Inst) then | |
1455 | |
1456 -- The call comes from the main unit and the target does not | |
1457 | |
1458 if In_Extended_Main_Code_Unit (Call) | |
1459 and then not In_Extended_Main_Code_Unit (Target_Decl) | |
1460 then | |
1461 return True; | |
1462 | |
1463 -- Otherwise the target declaration must not appear within the | |
1464 -- instance spec or body. | |
1465 | |
1466 else | |
1467 Extract_Instance_Attributes | |
1468 (Exp_Inst => Inst, | |
1469 Inst_Decl => Inst_Decl, | |
1470 Inst_Body => Inst_Body); | |
1471 | |
1472 -- Performance note: parent traversal | |
1473 | |
1474 return not In_Subtree | |
1475 (N => Target_Decl, | |
1476 Root1 => Inst_Decl, | |
1477 Root2 => Inst_Body); | |
1478 end if; | |
1479 end if; | |
1480 | |
1481 return False; | |
1482 end In_External_Context; | |
1483 | |
1484 -------------------------- | |
1485 -- In_Premature_Context -- | |
1486 -------------------------- | |
1487 | |
1488 function In_Premature_Context (Call : Node_Id) return Boolean is | |
1489 Par : Node_Id; | |
1490 | |
1491 begin | |
1492 -- Climb the parent chain looking for premature contexts | |
1493 | |
1494 Par := Parent (Call); | |
1495 while Present (Par) loop | |
1496 | |
1497 -- Aspect specifications and generic associations are premature | |
1498 -- contexts because nested calls has not been relocated to their | |
1499 -- final context. | |
1500 | |
1501 if Nkind_In (Par, N_Aspect_Specification, | |
1502 N_Generic_Association) | |
1503 then | |
1504 return True; | |
1505 | |
1506 -- Prevent the search from going too far | |
1507 | |
1508 elsif Is_Body_Or_Package_Declaration (Par) then | |
1509 exit; | |
1510 end if; | |
1511 | |
1512 Par := Parent (Par); | |
1513 end loop; | |
1514 | |
1515 return False; | |
1516 end In_Premature_Context; | |
1517 | |
1518 ---------------------- | |
1519 -- Is_Bridge_Target -- | |
1520 ---------------------- | |
1521 | |
1522 function Is_Bridge_Target (Id : Entity_Id) return Boolean is | |
1523 begin | |
1524 return | |
1525 Is_Accept_Alternative_Proc (Id) | |
1526 or else Is_Finalizer_Proc (Id) | |
1527 or else Is_Partial_Invariant_Proc (Id) | |
1528 or else Is_Postconditions_Proc (Id) | |
1529 or else Is_TSS (Id, TSS_Deep_Adjust) | |
1530 or else Is_TSS (Id, TSS_Deep_Finalize) | |
1531 or else Is_TSS (Id, TSS_Deep_Initialize); | |
1532 end Is_Bridge_Target; | |
1533 | |
1534 --------------------------- | |
1535 -- Is_Default_Expression -- | |
1536 --------------------------- | |
1537 | |
1538 function Is_Default_Expression (Call : Node_Id) return Boolean is | |
1539 Outer_Call : constant Node_Id := Parent (Call); | |
1540 Outer_Nam : Node_Id; | |
1541 | |
1542 begin | |
1543 -- To qualify, the node must appear immediately within a source call | |
1544 -- which invokes a source target. | |
1545 | |
1546 if Nkind_In (Outer_Call, N_Entry_Call_Statement, | |
1547 N_Function_Call, | |
1548 N_Procedure_Call_Statement) | |
1549 and then Comes_From_Source (Outer_Call) | |
1550 then | |
1551 Outer_Nam := Extract_Call_Name (Outer_Call); | |
1552 | |
1553 return | |
1554 Is_Entity_Name (Outer_Nam) | |
1555 and then Present (Entity (Outer_Nam)) | |
1556 and then Is_Subprogram_Or_Entry (Entity (Outer_Nam)) | |
1557 and then Comes_From_Source (Entity (Outer_Nam)); | |
1558 end if; | |
1559 | |
1560 return False; | |
1561 end Is_Default_Expression; | |
1562 | |
1563 ---------------------------- | |
1564 -- Is_Generic_Formal_Subp -- | |
1565 ---------------------------- | |
1566 | |
1567 function Is_Generic_Formal_Subp (Subp_Id : Entity_Id) return Boolean is | |
1568 Subp_Decl : constant Node_Id := Unit_Declaration_Node (Subp_Id); | |
1569 Context : constant Node_Id := Parent (Subp_Decl); | |
1570 | |
1571 begin | |
1572 -- To qualify, the subprogram must rename a generic actual subprogram | |
1573 -- where the enclosing context is an instantiation. | |
1574 | |
1575 return | |
1576 Nkind (Subp_Decl) = N_Subprogram_Renaming_Declaration | |
1577 and then not Comes_From_Source (Subp_Decl) | |
1578 and then Nkind_In (Context, N_Function_Specification, | |
1579 N_Package_Specification, | |
1580 N_Procedure_Specification) | |
1581 and then Present (Generic_Parent (Context)); | |
1582 end Is_Generic_Formal_Subp; | |
1583 | |
1584 -- Local variables | |
1585 | |
1586 Call_Attrs : Call_Attributes; | |
1587 Call_Nam : Node_Id; | |
1588 Marker : Node_Id; | |
1589 Target_Id : Entity_Id; | |
1590 | |
1591 -- Start of processing for Build_Call_Marker | |
1592 | |
1593 begin | |
1594 -- Nothing to do for ASIS. As a result, ABE checks and diagnostics are | |
1595 -- not performed in this mode. | |
1596 | |
1597 if ASIS_Mode then | |
1598 return; | |
1599 | |
1600 -- Nothing to do when the input does not denote a call or a requeue | |
1601 | |
1602 elsif not Nkind_In (N, N_Entry_Call_Statement, | |
1603 N_Function_Call, | |
1604 N_Procedure_Call_Statement, | |
1605 N_Requeue_Statement) | |
1606 then | |
1607 return; | |
1608 | |
1609 -- Nothing to do when the call is being preanalyzed as the marker will | |
1610 -- be inserted in the wrong place. | |
1611 | |
1612 elsif Preanalysis_Active then | |
1613 return; | |
1614 | |
1615 -- Nothing to do when the call is analyzed/resolved too early within an | |
1616 -- intermediate context. | |
1617 | |
1618 -- Performance note: parent traversal | |
1619 | |
1620 elsif In_Premature_Context (N) then | |
1621 return; | |
1622 end if; | |
1623 | |
1624 Call_Nam := Extract_Call_Name (N); | |
1625 | |
1626 -- Nothing to do when the call is erroneous or left in a bad state | |
1627 | |
1628 if not (Is_Entity_Name (Call_Nam) | |
1629 and then Present (Entity (Call_Nam)) | |
1630 and then Is_Subprogram_Or_Entry (Entity (Call_Nam))) | |
1631 then | |
1632 return; | |
1633 | |
1634 -- Nothing to do when the call invokes a generic formal subprogram and | |
1635 -- switch -gnatd.G (ignore calls through generic formal parameters for | |
1636 -- elaboration) is in effect. This check must be performed with the | |
1637 -- direct target of the call to avoid the side effects of mapping | |
1638 -- actuals to formals using renamings. | |
1639 | |
1640 elsif Debug_Flag_Dot_GG | |
1641 and then Is_Generic_Formal_Subp (Entity (Call_Nam)) | |
1642 then | |
1643 return; | |
1644 end if; | |
1645 | |
1646 Extract_Call_Attributes | |
1647 (Call => N, | |
1648 Target_Id => Target_Id, | |
1649 Attrs => Call_Attrs); | |
1650 | |
1651 -- Nothing to do when the call appears within the expanded spec or | |
1652 -- body of an instantiated generic, the call does not invoke a generic | |
1653 -- formal subprogram, the target is external to the instance, and switch | |
1654 -- -gnatdL (ignore external calls from instances for elaboration) is in | |
1655 -- effect. This behaviour approximates that of the old ABE mechanism. | |
1656 | |
1657 if Debug_Flag_LL | |
1658 and then not Is_Generic_Formal_Subp (Entity (Call_Nam)) | |
1659 | |
1660 -- Performance note: parent traversal | |
1661 | |
1662 and then In_External_Context | |
1663 (Call => N, | |
1664 Target_Id => Target_Id) | |
1665 then | |
1666 return; | |
1667 | |
1668 -- Source calls to source targets are always considered because they | |
1669 -- reflect the original call graph. | |
1670 | |
1671 elsif Comes_From_Source (Target_Id) and then Call_Attrs.From_Source then | |
1672 null; | |
1673 | |
1674 -- A call to a source function which acts as the default expression in | |
1675 -- another call requires special detection. | |
1676 | |
1677 elsif Comes_From_Source (Target_Id) | |
1678 and then Nkind (N) = N_Function_Call | |
1679 and then Is_Default_Expression (N) | |
1680 then | |
1681 null; | |
1682 | |
1683 -- The target emulates Ada semantics | |
1684 | |
1685 elsif Is_Ada_Semantic_Target (Target_Id) then | |
1686 null; | |
1687 | |
1688 -- The target acts as a link between scenarios | |
1689 | |
1690 elsif Is_Bridge_Target (Target_Id) then | |
1691 null; | |
1692 | |
1693 -- The target emulates SPARK semantics | |
1694 | |
1695 elsif Is_SPARK_Semantic_Target (Target_Id) then | |
1696 null; | |
1697 | |
1698 -- Otherwise the call is not suitable for ABE processing. This prevents | |
1699 -- the generation of call markers which will never play a role in ABE | |
1700 -- diagnostics. | |
1701 | |
1702 else | |
1703 return; | |
1704 end if; | |
1705 | |
1706 -- At this point it is known that the call will play some role in ABE | |
1707 -- checks and diagnostics. Create a corresponding call marker in case | |
1708 -- the original call is heavily transformed by expansion later on. | |
1709 | |
1710 Marker := Make_Call_Marker (Sloc (N)); | |
1711 | |
1712 -- Inherit the attributes of the original call | |
1713 | |
1714 Set_Target (Marker, Target_Id); | |
1715 Set_Is_Elaboration_Checks_OK_Node (Marker, Call_Attrs.Elab_Checks_OK); | |
1716 Set_Is_Declaration_Level_Node (Marker, Call_Attrs.In_Declarations); | |
1717 Set_Is_Dispatching_Call (Marker, Call_Attrs.Is_Dispatching); | |
1718 Set_Is_Ignored_Ghost_Node (Marker, Call_Attrs.Ghost_Mode_Ignore); | |
1719 Set_Is_Source_Call (Marker, Call_Attrs.From_Source); | |
1720 Set_Is_SPARK_Mode_On_Node (Marker, Call_Attrs.SPARK_Mode_On); | |
1721 | |
1722 -- The marker is inserted prior to the original call. This placement has | |
1723 -- several desirable effects: | |
1724 | |
1725 -- 1) The marker appears in the same context, in close proximity to | |
1726 -- the call. | |
1727 | |
1728 -- <marker> | |
1729 -- <call> | |
1730 | |
1731 -- 2) Inserting the marker prior to the call ensures that an ABE check | |
1732 -- will take effect prior to the call. | |
1733 | |
1734 -- <ABE check> | |
1735 -- <marker> | |
1736 -- <call> | |
1737 | |
1738 -- 3) The above two properties are preserved even when the call is a | |
1739 -- function which is subsequently relocated in order to capture its | |
1740 -- result. Note that if the call is relocated to a new context, the | |
1741 -- relocated call will receive a marker of its own. | |
1742 | |
1743 -- <ABE check> | |
1744 -- <maker> | |
1745 -- Temp : ... := Func_Call ...; | |
1746 -- ... Temp ... | |
1747 | |
1748 -- The insertion must take place even when the call does not occur in | |
1749 -- the main unit to keep the tree symmetric. This ensures that internal | |
1750 -- name serialization is consistent in case the call marker causes the | |
1751 -- tree to transform in some way. | |
1752 | |
1753 Insert_Action (N, Marker); | |
1754 | |
1755 -- The marker becomes the "corresponding" scenario for the call. Save | |
1756 -- the marker for later processing by the ABE phase. | |
1757 | |
1758 Record_Elaboration_Scenario (Marker); | |
1759 end Build_Call_Marker; | |
1760 | |
1761 --------------------------------- | |
1762 -- Check_Elaboration_Scenarios -- | |
1763 --------------------------------- | |
1764 | |
1765 procedure Check_Elaboration_Scenarios is | |
1766 begin | |
1767 -- Nothing to do for ASIS. As a result, no ABE checks and diagnostics | |
1768 -- are performed in this mode. | |
1769 | |
1770 if ASIS_Mode then | |
1771 return; | |
1772 end if; | |
1773 | |
1774 -- Examine the context of the main unit and record all units with prior | |
1775 -- elaboration with respect to it. | |
1776 | |
1777 Find_Elaborated_Units; | |
1778 | |
1779 -- Examine each top level scenario saved during the Recording phase and | |
1780 -- perform various actions depending on the elaboration model in effect. | |
1781 | |
1782 for Index in Top_Level_Scenarios.First .. Top_Level_Scenarios.Last loop | |
1783 | |
1784 -- Clear the table of visited scenario bodies for each new top level | |
1785 -- scenario. | |
1786 | |
1787 Visited_Bodies.Reset; | |
1788 | |
1789 Process_Scenario (Top_Level_Scenarios.Table (Index)); | |
1790 end loop; | |
1791 end Check_Elaboration_Scenarios; | |
1792 | |
1793 ------------------------------ | |
1794 -- Check_Preelaborated_Call -- | |
1795 ------------------------------ | |
1796 | |
1797 procedure Check_Preelaborated_Call (Call : Node_Id) is | |
1798 function In_Preelaborated_Context (N : Node_Id) return Boolean; | |
1799 -- Determine whether arbitrary node appears in a preelaborated context | |
1800 | |
1801 ------------------------------ | |
1802 -- In_Preelaborated_Context -- | |
1803 ------------------------------ | |
1804 | |
1805 function In_Preelaborated_Context (N : Node_Id) return Boolean is | |
1806 Body_Id : constant Entity_Id := Find_Code_Unit (N); | |
1807 Spec_Id : constant Entity_Id := Unique_Entity (Body_Id); | |
1808 | |
1809 begin | |
1810 -- The node appears within a package body whose corresponding spec is | |
1811 -- subject to pragma Remote_Call_Interface or Remote_Types. This does | |
1812 -- not result in a preelaborated context because the package body may | |
1813 -- be on another machine. | |
1814 | |
1815 if Ekind (Body_Id) = E_Package_Body | |
1816 and then Ekind_In (Spec_Id, E_Generic_Package, E_Package) | |
1817 and then (Is_Remote_Call_Interface (Spec_Id) | |
1818 or else Is_Remote_Types (Spec_Id)) | |
1819 then | |
1820 return False; | |
1821 | |
1822 -- Otherwise the node appears within a preelaborated context when the | |
1823 -- associated unit is preelaborated. | |
1824 | |
1825 else | |
1826 return Is_Preelaborated_Unit (Spec_Id); | |
1827 end if; | |
1828 end In_Preelaborated_Context; | |
1829 | |
1830 -- Local variables | |
1831 | |
1832 Call_Attrs : Call_Attributes; | |
1833 Level : Enclosing_Level_Kind; | |
1834 Target_Id : Entity_Id; | |
1835 | |
1836 -- Start of processing for Check_Preelaborated_Call | |
1837 | |
1838 begin | |
1839 Extract_Call_Attributes | |
1840 (Call => Call, | |
1841 Target_Id => Target_Id, | |
1842 Attrs => Call_Attrs); | |
1843 | |
1844 -- Nothing to do when the call is internally generated because it is | |
1845 -- assumed that it will never violate preelaboration. | |
1846 | |
1847 if not Call_Attrs.From_Source then | |
1848 return; | |
1849 end if; | |
1850 | |
1851 -- Performance note: parent traversal | |
1852 | |
1853 Level := Find_Enclosing_Level (Call); | |
1854 | |
1855 -- Library level calls are always considered because they are part of | |
1856 -- the associated unit's elaboration actions. | |
1857 | |
1858 if Level in Library_Level then | |
1859 null; | |
1860 | |
1861 -- Calls at the library level of a generic package body must be checked | |
1862 -- because they would render an instantiation illegal if the template is | |
1863 -- marked as preelaborated. Note that this does not apply to calls at | |
1864 -- the library level of a generic package spec. | |
1865 | |
1866 elsif Level = Generic_Package_Body then | |
1867 null; | |
1868 | |
1869 -- Otherwise the call does not appear at the proper level and must not | |
1870 -- be considered for this check. | |
1871 | |
1872 else | |
1873 return; | |
1874 end if; | |
1875 | |
1876 -- The call appears within a preelaborated unit. Emit a warning only for | |
1877 -- internal uses, otherwise this is an error. | |
1878 | |
1879 if In_Preelaborated_Context (Call) then | |
1880 Error_Msg_Warn := GNAT_Mode; | |
1881 Error_Msg_N | |
1882 ("<<non-static call not allowed in preelaborated unit", Call); | |
1883 end if; | |
1884 end Check_Preelaborated_Call; | |
1885 | |
1886 ---------------------- | |
1887 -- Compilation_Unit -- | |
1888 ---------------------- | |
1889 | |
1890 function Compilation_Unit (Unit_Id : Entity_Id) return Node_Id is | |
1891 Comp_Unit : Node_Id; | |
1892 | |
1893 begin | |
1894 Comp_Unit := Parent (Unit_Id); | |
1895 | |
1896 -- Handle the case where a concurrent subunit is rewritten as a null | |
1897 -- statement due to expansion activities. | |
1898 | |
1899 if Nkind (Comp_Unit) = N_Null_Statement | |
1900 and then Nkind_In (Original_Node (Comp_Unit), N_Protected_Body, | |
1901 N_Task_Body) | |
1902 then | |
1903 Comp_Unit := Parent (Comp_Unit); | |
1904 pragma Assert (Nkind (Comp_Unit) = N_Subunit); | |
1905 | |
1906 -- Otherwise use the declaration node of the unit | |
1907 | |
1908 else | |
1909 Comp_Unit := Parent (Unit_Declaration_Node (Unit_Id)); | |
1910 end if; | |
1911 | |
1912 -- Handle the case where a subprogram instantiation which acts as a | |
1913 -- compilation unit is expanded into an anonymous package that wraps | |
1914 -- the instantiated subprogram. | |
1915 | |
1916 if Nkind (Comp_Unit) = N_Package_Specification | |
1917 and then Nkind_In (Original_Node (Parent (Comp_Unit)), | |
1918 N_Function_Instantiation, | |
1919 N_Procedure_Instantiation) | |
1920 then | |
1921 Comp_Unit := Parent (Parent (Comp_Unit)); | |
1922 | |
1923 -- Handle the case where the compilation unit is a subunit | |
1924 | |
1925 elsif Nkind (Comp_Unit) = N_Subunit then | |
1926 Comp_Unit := Parent (Comp_Unit); | |
1927 end if; | |
1928 | |
1929 pragma Assert (Nkind (Comp_Unit) = N_Compilation_Unit); | |
1930 | |
1931 return Comp_Unit; | |
1932 end Compilation_Unit; | |
1933 | |
1934 ----------------- | |
1935 -- Elab_Msg_NE -- | |
1936 ----------------- | |
1937 | |
1938 procedure Elab_Msg_NE | |
1939 (Msg : String; | |
1940 N : Node_Id; | |
1941 Id : Entity_Id; | |
1942 Info_Msg : Boolean; | |
1943 In_SPARK : Boolean) | |
1944 is | |
1945 function Prefix return String; | |
1946 -- Obtain the prefix of the message | |
1947 | |
1948 function Suffix return String; | |
1949 -- Obtain the suffix of the message | |
1950 | |
1951 ------------ | |
1952 -- Prefix -- | |
1953 ------------ | |
1954 | |
1955 function Prefix return String is | |
1956 begin | |
1957 if Info_Msg then | |
1958 return "info: "; | |
1959 else | |
1960 return ""; | |
1961 end if; | |
1962 end Prefix; | |
1963 | |
1964 ------------ | |
1965 -- Suffix -- | |
1966 ------------ | |
1967 | |
1968 function Suffix return String is | |
1969 begin | |
1970 if In_SPARK then | |
1971 return " in SPARK"; | |
1972 else | |
1973 return ""; | |
1974 end if; | |
1975 end Suffix; | |
1976 | |
1977 -- Start of processing for Elab_Msg_NE | |
1978 | |
1979 begin | |
1980 Error_Msg_NE (Prefix & Msg & Suffix, N, Id); | |
1981 end Elab_Msg_NE; | |
1982 | |
1983 ------------------------------ | |
1984 -- Elaboration_Context_Hash -- | |
1985 ------------------------------ | |
1986 | |
1987 function Elaboration_Context_Hash | |
1988 (Key : Entity_Id) return Elaboration_Context_Index | |
1989 is | |
1990 begin | |
1991 return Elaboration_Context_Index (Key mod Elaboration_Context_Max); | |
1992 end Elaboration_Context_Hash; | |
1993 | |
1994 ------------------------------ | |
1995 -- Ensure_Prior_Elaboration -- | |
1996 ------------------------------ | |
1997 | |
1998 procedure Ensure_Prior_Elaboration | |
1999 (N : Node_Id; | |
2000 Unit_Id : Entity_Id; | |
2001 In_Task_Body : Boolean) | |
2002 is | |
2003 Prag_Nam : Name_Id; | |
2004 | |
2005 begin | |
2006 -- Instantiating an external generic unit requires an implicit Elaborate | |
2007 -- because Elaborate_All is too strong and could introduce non-existent | |
2008 -- elaboration cycles. | |
2009 | |
2010 -- package External is | |
2011 -- function Func ...; | |
2012 -- end External; | |
2013 | |
2014 -- with External; | |
2015 -- generic | |
2016 -- package Gen is | |
2017 -- X : ... := External.Func; | |
2018 -- end Gen; | |
2019 | |
2020 -- [with External;] -- implicit with for External | |
2021 -- [pragma Elaborate_All (External);] -- Elaborate_All for External | |
2022 -- with Gen; | |
2023 -- [pragma Elaborate (Gen);] -- Elaborate for generic | |
2024 -- procedure Main is | |
2025 -- package Inst is new Gen; -- calls External.Func | |
2026 -- ... | |
2027 -- end Main; | |
2028 | |
2029 if Nkind (N) in N_Generic_Instantiation then | |
2030 Prag_Nam := Name_Elaborate; | |
2031 | |
2032 -- Otherwise generate an implicit Elaborate_All | |
2033 | |
2034 else | |
2035 Prag_Nam := Name_Elaborate_All; | |
2036 end if; | |
2037 | |
2038 -- Nothing to do when the need for prior elaboration came from a task | |
2039 -- body and switch -gnatd.y (disable implicit pragma Elaborate_All on | |
2040 -- task bodies) is in effect. | |
2041 | |
2042 if Debug_Flag_Dot_Y and then In_Task_Body then | |
2043 return; | |
2044 | |
2045 -- Nothing to do when the unit is elaborated prior to the main unit. | |
2046 -- This check must also consider the following cases: | |
2047 | |
2048 -- * No check is made against the context of the main unit because this | |
2049 -- is specific to the elaboration model in effect and requires custom | |
2050 -- handling (see Ensure_xxx_Prior_Elaboration). | |
2051 | |
2052 -- * Unit_Id is subject to pragma Elaborate_Body. An implicit pragma | |
2053 -- Elaborate[_All] MUST be generated even though Unit_Id is always | |
2054 -- elaborated prior to the main unit. This is a conservative strategy | |
2055 -- which ensures that other units withed by Unit_Id will not lead to | |
2056 -- an ABE. | |
2057 | |
2058 -- package A is package body A is | |
2059 -- procedure ABE; procedure ABE is ... end ABE; | |
2060 -- end A; end A; | |
2061 | |
2062 -- with A; | |
2063 -- package B is package body B is | |
2064 -- pragma Elaborate_Body; procedure Proc is | |
2065 -- begin | |
2066 -- procedure Proc; A.ABE; | |
2067 -- package B; end Proc; | |
2068 -- end B; | |
2069 | |
2070 -- with B; | |
2071 -- package C is package body C is | |
2072 -- ... ... | |
2073 -- end C; begin | |
2074 -- B.Proc; | |
2075 -- end C; | |
2076 | |
2077 -- In the example above, the elaboration of C invokes B.Proc. B is | |
2078 -- subject to pragma Elaborate_Body. If no pragma Elaborate[_All] is | |
2079 -- generated for B in C, then the following elaboratio order will lead | |
2080 -- to an ABE: | |
2081 | |
2082 -- spec of A elaborated | |
2083 -- spec of B elaborated | |
2084 -- body of B elaborated | |
2085 -- spec of C elaborated | |
2086 -- body of C elaborated <-- calls B.Proc which calls A.ABE | |
2087 -- body of A elaborated <-- problem | |
2088 | |
2089 -- The generation of an implicit pragma Elaborate_All (B) ensures that | |
2090 -- the elaboration order mechanism will not pick the above order. | |
2091 | |
2092 -- An implicit Elaborate is NOT generated when the unit is subject to | |
2093 -- Elaborate_Body because both pragmas have the exact same effect. | |
2094 | |
2095 -- * Unit_Id is the main unit. An implicit pragma Elaborate[_All] MUST | |
2096 -- NOT be generated in this case because a unit cannot depend on its | |
2097 -- own elaboration. This case is therefore treated as valid prior | |
2098 -- elaboration. | |
2099 | |
2100 elsif Has_Prior_Elaboration | |
2101 (Unit_Id => Unit_Id, | |
2102 Same_Unit_OK => True, | |
2103 Elab_Body_OK => Prag_Nam = Name_Elaborate) | |
2104 then | |
2105 return; | |
2106 | |
2107 -- Suggest the use of pragma Prag_Nam when the dynamic model is in | |
2108 -- effect. | |
2109 | |
2110 elsif Dynamic_Elaboration_Checks then | |
2111 Ensure_Prior_Elaboration_Dynamic | |
2112 (N => N, | |
2113 Unit_Id => Unit_Id, | |
2114 Prag_Nam => Prag_Nam); | |
2115 | |
2116 -- Install an implicit pragma Prag_Nam when the static model is in | |
2117 -- effect. | |
2118 | |
2119 else | |
2120 pragma Assert (Static_Elaboration_Checks); | |
2121 | |
2122 Ensure_Prior_Elaboration_Static | |
2123 (N => N, | |
2124 Unit_Id => Unit_Id, | |
2125 Prag_Nam => Prag_Nam); | |
2126 end if; | |
2127 end Ensure_Prior_Elaboration; | |
2128 | |
2129 -------------------------------------- | |
2130 -- Ensure_Prior_Elaboration_Dynamic -- | |
2131 -------------------------------------- | |
2132 | |
2133 procedure Ensure_Prior_Elaboration_Dynamic | |
2134 (N : Node_Id; | |
2135 Unit_Id : Entity_Id; | |
2136 Prag_Nam : Name_Id) | |
2137 is | |
2138 procedure Info_Missing_Pragma; | |
2139 pragma Inline (Info_Missing_Pragma); | |
2140 -- Output information concerning missing Elaborate or Elaborate_All | |
2141 -- pragma with name Prag_Nam for scenario N, which would ensure the | |
2142 -- prior elaboration of Unit_Id. | |
2143 | |
2144 ------------------------- | |
2145 -- Info_Missing_Pragma -- | |
2146 ------------------------- | |
2147 | |
2148 procedure Info_Missing_Pragma is | |
2149 begin | |
2150 -- Internal units are ignored as they cause unnecessary noise | |
2151 | |
2152 if not In_Internal_Unit (Unit_Id) then | |
2153 | |
2154 -- The name of the unit subjected to the elaboration pragma is | |
2155 -- fully qualified to improve the clarity of the info message. | |
2156 | |
2157 Error_Msg_Name_1 := Prag_Nam; | |
2158 Error_Msg_Qual_Level := Nat'Last; | |
2159 | |
2160 Error_Msg_NE ("info: missing pragma % for unit &", N, Unit_Id); | |
2161 Error_Msg_Qual_Level := 0; | |
2162 end if; | |
2163 end Info_Missing_Pragma; | |
2164 | |
2165 -- Local variables | |
2166 | |
2167 Elab_Attrs : Elaboration_Attributes; | |
2168 Level : Enclosing_Level_Kind; | |
2169 | |
2170 -- Start of processing for Ensure_Prior_Elaboration_Dynamic | |
2171 | |
2172 begin | |
2173 Elab_Attrs := Elaboration_Context.Get (Unit_Id); | |
2174 | |
2175 -- Nothing to do when the unit is guaranteed prior elaboration by means | |
2176 -- of a source Elaborate[_All] pragma. | |
2177 | |
2178 if Present (Elab_Attrs.Source_Pragma) then | |
2179 return; | |
2180 end if; | |
2181 | |
2182 -- Output extra information on a missing Elaborate[_All] pragma when | |
2183 -- switch -gnatel (info messages on implicit Elaborate[_All] pragmas | |
2184 -- is in effect. | |
2185 | |
2186 if Elab_Info_Messages then | |
2187 | |
2188 -- Performance note: parent traversal | |
2189 | |
2190 Level := Find_Enclosing_Level (N); | |
2191 | |
2192 -- Declaration-level scenario | |
2193 | |
2194 if (Is_Suitable_Call (N) or else Is_Suitable_Instantiation (N)) | |
2195 and then Level = Declaration_Level | |
2196 then | |
2197 null; | |
2198 | |
2199 -- Library-level scenario | |
2200 | |
2201 elsif Level in Library_Level then | |
2202 null; | |
2203 | |
2204 -- Instantiation library-level scenario | |
2205 | |
2206 elsif Level = Instantiation then | |
2207 null; | |
2208 | |
2209 -- Otherwise the scenario does not appear at the proper level and | |
2210 -- cannot possibly act as a top-level scenario. | |
2211 | |
2212 else | |
2213 return; | |
2214 end if; | |
2215 | |
2216 Info_Missing_Pragma; | |
2217 end if; | |
2218 end Ensure_Prior_Elaboration_Dynamic; | |
2219 | |
2220 ------------------------------------- | |
2221 -- Ensure_Prior_Elaboration_Static -- | |
2222 ------------------------------------- | |
2223 | |
2224 procedure Ensure_Prior_Elaboration_Static | |
2225 (N : Node_Id; | |
2226 Unit_Id : Entity_Id; | |
2227 Prag_Nam : Name_Id) | |
2228 is | |
2229 function Find_With_Clause | |
2230 (Items : List_Id; | |
2231 Withed_Id : Entity_Id) return Node_Id; | |
2232 pragma Inline (Find_With_Clause); | |
2233 -- Find a nonlimited with clause in the list of context items Items | |
2234 -- that withs unit Withed_Id. Return Empty if no such clause is found. | |
2235 | |
2236 procedure Info_Implicit_Pragma; | |
2237 pragma Inline (Info_Implicit_Pragma); | |
2238 -- Output information concerning an implicitly generated Elaborate or | |
2239 -- Elaborate_All pragma with name Prag_Nam for scenario N which ensures | |
2240 -- the prior elaboration of unit Unit_Id. | |
2241 | |
2242 ---------------------- | |
2243 -- Find_With_Clause -- | |
2244 ---------------------- | |
2245 | |
2246 function Find_With_Clause | |
2247 (Items : List_Id; | |
2248 Withed_Id : Entity_Id) return Node_Id | |
2249 is | |
2250 Item : Node_Id; | |
2251 | |
2252 begin | |
2253 -- Examine the context clauses looking for a suitable with. Note that | |
2254 -- limited clauses do not affect the elaboration order. | |
2255 | |
2256 Item := First (Items); | |
2257 while Present (Item) loop | |
2258 if Nkind (Item) = N_With_Clause | |
2259 and then not Error_Posted (Item) | |
2260 and then not Limited_Present (Item) | |
2261 and then Entity (Name (Item)) = Withed_Id | |
2262 then | |
2263 return Item; | |
2264 end if; | |
2265 | |
2266 Next (Item); | |
2267 end loop; | |
2268 | |
2269 return Empty; | |
2270 end Find_With_Clause; | |
2271 | |
2272 -------------------------- | |
2273 -- Info_Implicit_Pragma -- | |
2274 -------------------------- | |
2275 | |
2276 procedure Info_Implicit_Pragma is | |
2277 begin | |
2278 -- Internal units are ignored as they cause unnecessary noise | |
2279 | |
2280 if not In_Internal_Unit (Unit_Id) then | |
2281 | |
2282 -- The name of the unit subjected to the elaboration pragma is | |
2283 -- fully qualified to improve the clarity of the info message. | |
2284 | |
2285 Error_Msg_Name_1 := Prag_Nam; | |
2286 Error_Msg_Qual_Level := Nat'Last; | |
2287 | |
2288 Error_Msg_NE | |
2289 ("info: implicit pragma % generated for unit &", N, Unit_Id); | |
2290 | |
2291 Error_Msg_Qual_Level := 0; | |
2292 Output_Active_Scenarios (N); | |
2293 end if; | |
2294 end Info_Implicit_Pragma; | |
2295 | |
2296 -- Local variables | |
2297 | |
2298 Main_Cunit : constant Node_Id := Cunit (Main_Unit); | |
2299 Loc : constant Source_Ptr := Sloc (Main_Cunit); | |
2300 Unit_Cunit : constant Node_Id := Compilation_Unit (Unit_Id); | |
2301 | |
2302 Is_Instantiation : constant Boolean := | |
2303 Nkind (N) in N_Generic_Instantiation; | |
2304 | |
2305 Clause : Node_Id; | |
2306 Elab_Attrs : Elaboration_Attributes; | |
2307 Items : List_Id; | |
2308 | |
2309 -- Start of processing for Ensure_Prior_Elaboration_Static | |
2310 | |
2311 begin | |
2312 Elab_Attrs := Elaboration_Context.Get (Unit_Id); | |
2313 | |
2314 -- Nothing to do when the unit is guaranteed prior elaboration by means | |
2315 -- of a source Elaborate[_All] pragma. | |
2316 | |
2317 if Present (Elab_Attrs.Source_Pragma) then | |
2318 return; | |
2319 | |
2320 -- Nothing to do when the unit has an existing implicit Elaborate[_All] | |
2321 -- pragma installed by a previous scenario. | |
2322 | |
2323 elsif Present (Elab_Attrs.With_Clause) then | |
2324 | |
2325 -- The unit is already guaranteed prior elaboration by means of an | |
2326 -- implicit Elaborate pragma, however the current scenario imposes | |
2327 -- a stronger requirement of Elaborate_All. "Upgrade" the existing | |
2328 -- pragma to match this new requirement. | |
2329 | |
2330 if Elaborate_Desirable (Elab_Attrs.With_Clause) | |
2331 and then Prag_Nam = Name_Elaborate_All | |
2332 then | |
2333 Set_Elaborate_All_Desirable (Elab_Attrs.With_Clause); | |
2334 Set_Elaborate_Desirable (Elab_Attrs.With_Clause, False); | |
2335 end if; | |
2336 | |
2337 return; | |
2338 end if; | |
2339 | |
2340 -- At this point it is known that the unit has no prior elaboration | |
2341 -- according to pragmas and hierarchical relationships. | |
2342 | |
2343 Items := Context_Items (Main_Cunit); | |
2344 | |
2345 if No (Items) then | |
2346 Items := New_List; | |
2347 Set_Context_Items (Main_Cunit, Items); | |
2348 end if; | |
2349 | |
2350 -- Locate the with clause for the unit. Note that there may not be a | |
2351 -- clause if the unit is visible through a subunit-body, body-spec, or | |
2352 -- spec-parent relationship. | |
2353 | |
2354 Clause := | |
2355 Find_With_Clause | |
2356 (Items => Items, | |
2357 Withed_Id => Unit_Id); | |
2358 | |
2359 -- Generate: | |
2360 -- with Id; | |
2361 | |
2362 -- Note that adding implicit with clauses is safe because analysis, | |
2363 -- resolution, and expansion have already taken place and it is not | |
2364 -- possible to interfere with visibility. | |
2365 | |
2366 if No (Clause) then | |
2367 Clause := | |
2368 Make_With_Clause (Loc, | |
2369 Name => New_Occurrence_Of (Unit_Id, Loc)); | |
2370 | |
2371 Set_Implicit_With (Clause); | |
2372 Set_Library_Unit (Clause, Unit_Cunit); | |
2373 | |
2374 Append_To (Items, Clause); | |
2375 end if; | |
2376 | |
2377 -- Instantiations require an implicit Elaborate because Elaborate_All is | |
2378 -- too conservative and may introduce non-existent elaboration cycles. | |
2379 | |
2380 if Is_Instantiation then | |
2381 Set_Elaborate_Desirable (Clause); | |
2382 | |
2383 -- Otherwise generate an implicit Elaborate_All | |
2384 | |
2385 else | |
2386 Set_Elaborate_All_Desirable (Clause); | |
2387 end if; | |
2388 | |
2389 -- The implicit Elaborate[_All] ensures the prior elaboration of the | |
2390 -- unit. Include the unit in the elaboration context of the main unit. | |
2391 | |
2392 Elaboration_Context.Set (Unit_Id, | |
2393 Elaboration_Attributes'(Source_Pragma => Empty, | |
2394 With_Clause => Clause)); | |
2395 | |
2396 -- Output extra information on an implicit Elaborate[_All] pragma when | |
2397 -- switch -gnatel (info messages on implicit Elaborate[_All] pragmas is | |
2398 -- in effect. | |
2399 | |
2400 if Elab_Info_Messages then | |
2401 Info_Implicit_Pragma; | |
2402 end if; | |
2403 end Ensure_Prior_Elaboration_Static; | |
2404 | |
2405 ----------------------------- | |
2406 -- Extract_Assignment_Name -- | |
2407 ----------------------------- | |
2408 | |
2409 function Extract_Assignment_Name (Asmt : Node_Id) return Node_Id is | |
2410 Nam : Node_Id; | |
2411 | |
2412 begin | |
2413 Nam := Name (Asmt); | |
2414 | |
2415 -- When the name denotes an array or record component, find the whole | |
2416 -- object. | |
2417 | |
2418 while Nkind_In (Nam, N_Explicit_Dereference, | |
2419 N_Indexed_Component, | |
2420 N_Selected_Component, | |
2421 N_Slice) | |
2422 loop | |
2423 Nam := Prefix (Nam); | |
2424 end loop; | |
2425 | |
2426 return Nam; | |
2427 end Extract_Assignment_Name; | |
2428 | |
2429 ----------------------------- | |
2430 -- Extract_Call_Attributes -- | |
2431 ----------------------------- | |
2432 | |
2433 procedure Extract_Call_Attributes | |
2434 (Call : Node_Id; | |
2435 Target_Id : out Entity_Id; | |
2436 Attrs : out Call_Attributes) | |
2437 is | |
2438 From_Source : Boolean; | |
2439 In_Declarations : Boolean; | |
2440 Is_Dispatching : Boolean; | |
2441 | |
2442 begin | |
2443 -- Extraction for call markers | |
2444 | |
2445 if Nkind (Call) = N_Call_Marker then | |
2446 Target_Id := Target (Call); | |
2447 From_Source := Is_Source_Call (Call); | |
2448 In_Declarations := Is_Declaration_Level_Node (Call); | |
2449 Is_Dispatching := Is_Dispatching_Call (Call); | |
2450 | |
2451 -- Extraction for entry calls, requeue, and subprogram calls | |
2452 | |
2453 else | |
2454 pragma Assert (Nkind_In (Call, N_Entry_Call_Statement, | |
2455 N_Function_Call, | |
2456 N_Procedure_Call_Statement, | |
2457 N_Requeue_Statement)); | |
2458 | |
2459 Target_Id := Entity (Extract_Call_Name (Call)); | |
2460 From_Source := Comes_From_Source (Call); | |
2461 | |
2462 -- Performance note: parent traversal | |
2463 | |
2464 In_Declarations := Find_Enclosing_Level (Call) = Declaration_Level; | |
2465 Is_Dispatching := | |
2466 Nkind_In (Call, N_Function_Call, N_Procedure_Call_Statement) | |
2467 and then Present (Controlling_Argument (Call)); | |
2468 end if; | |
2469 | |
2470 -- Obtain the original entry or subprogram which the target may rename | |
2471 -- except when the target is an instantiation. In this case the alias | |
2472 -- is the internally generated subprogram which appears within the the | |
2473 -- anonymous package created for the instantiation. Such an alias is not | |
2474 -- a suitable target. | |
2475 | |
2476 if not (Is_Subprogram (Target_Id) | |
2477 and then Is_Generic_Instance (Target_Id)) | |
2478 then | |
2479 Target_Id := Get_Renamed_Entity (Target_Id); | |
2480 end if; | |
2481 | |
2482 -- Set all attributes | |
2483 | |
2484 Attrs.Elab_Checks_OK := Is_Elaboration_Checks_OK_Node (Call); | |
2485 Attrs.From_Source := From_Source; | |
2486 Attrs.Ghost_Mode_Ignore := Is_Ignored_Ghost_Node (Call); | |
2487 Attrs.In_Declarations := In_Declarations; | |
2488 Attrs.Is_Dispatching := Is_Dispatching; | |
2489 Attrs.SPARK_Mode_On := Is_SPARK_Mode_On_Node (Call); | |
2490 end Extract_Call_Attributes; | |
2491 | |
2492 ----------------------- | |
2493 -- Extract_Call_Name -- | |
2494 ----------------------- | |
2495 | |
2496 function Extract_Call_Name (Call : Node_Id) return Node_Id is | |
2497 Nam : Node_Id; | |
2498 | |
2499 begin | |
2500 Nam := Name (Call); | |
2501 | |
2502 -- When the call invokes an entry family, the name appears as an indexed | |
2503 -- component. | |
2504 | |
2505 if Nkind (Nam) = N_Indexed_Component then | |
2506 Nam := Prefix (Nam); | |
2507 end if; | |
2508 | |
2509 -- When the call employs the object.operation form, the name appears as | |
2510 -- a selected component. | |
2511 | |
2512 if Nkind (Nam) = N_Selected_Component then | |
2513 Nam := Selector_Name (Nam); | |
2514 end if; | |
2515 | |
2516 return Nam; | |
2517 end Extract_Call_Name; | |
2518 | |
2519 --------------------------------- | |
2520 -- Extract_Instance_Attributes -- | |
2521 --------------------------------- | |
2522 | |
2523 procedure Extract_Instance_Attributes | |
2524 (Exp_Inst : Node_Id; | |
2525 Inst_Body : out Node_Id; | |
2526 Inst_Decl : out Node_Id) | |
2527 is | |
2528 Body_Id : Entity_Id; | |
2529 | |
2530 begin | |
2531 -- Assume that the attributes are unavailable | |
2532 | |
2533 Inst_Body := Empty; | |
2534 Inst_Decl := Empty; | |
2535 | |
2536 -- Generic package or subprogram spec | |
2537 | |
2538 if Nkind_In (Exp_Inst, N_Package_Declaration, | |
2539 N_Subprogram_Declaration) | |
2540 then | |
2541 Inst_Decl := Exp_Inst; | |
2542 Body_Id := Corresponding_Body (Inst_Decl); | |
2543 | |
2544 if Present (Body_Id) then | |
2545 Inst_Body := Unit_Declaration_Node (Body_Id); | |
2546 end if; | |
2547 | |
2548 -- Generic package or subprogram body | |
2549 | |
2550 else | |
2551 pragma Assert | |
2552 (Nkind_In (Exp_Inst, N_Package_Body, N_Subprogram_Body)); | |
2553 | |
2554 Inst_Body := Exp_Inst; | |
2555 Inst_Decl := Unit_Declaration_Node (Corresponding_Spec (Inst_Body)); | |
2556 end if; | |
2557 end Extract_Instance_Attributes; | |
2558 | |
2559 -------------------------------------- | |
2560 -- Extract_Instantiation_Attributes -- | |
2561 -------------------------------------- | |
2562 | |
2563 procedure Extract_Instantiation_Attributes | |
2564 (Exp_Inst : Node_Id; | |
2565 Inst : out Node_Id; | |
2566 Inst_Id : out Entity_Id; | |
2567 Gen_Id : out Entity_Id; | |
2568 Attrs : out Instantiation_Attributes) | |
2569 is | |
2570 begin | |
2571 Inst := Original_Node (Exp_Inst); | |
2572 Inst_Id := Defining_Entity (Inst); | |
2573 | |
2574 -- Traverse a possible chain of renamings to obtain the original generic | |
2575 -- being instantiatied. | |
2576 | |
2577 Gen_Id := Get_Renamed_Entity (Entity (Name (Inst))); | |
2578 | |
2579 -- Set all attributes | |
2580 | |
2581 Attrs.Elab_Checks_OK := Is_Elaboration_Checks_OK_Node (Inst); | |
2582 Attrs.Ghost_Mode_Ignore := Is_Ignored_Ghost_Node (Inst); | |
2583 Attrs.In_Declarations := Is_Declaration_Level_Node (Inst); | |
2584 Attrs.SPARK_Mode_On := Is_SPARK_Mode_On_Node (Inst); | |
2585 end Extract_Instantiation_Attributes; | |
2586 | |
2587 ------------------------------- | |
2588 -- Extract_Target_Attributes -- | |
2589 ------------------------------- | |
2590 | |
2591 procedure Extract_Target_Attributes | |
2592 (Target_Id : Entity_Id; | |
2593 Attrs : out Target_Attributes) | |
2594 is | |
2595 procedure Extract_Package_Or_Subprogram_Attributes | |
2596 (Spec_Id : out Entity_Id; | |
2597 Body_Decl : out Node_Id); | |
2598 -- Obtain the attributes associated with a package or a subprogram. | |
2599 -- Spec_Id is the package or subprogram. Body_Decl is the declaration | |
2600 -- of the corresponding package or subprogram body. | |
2601 | |
2602 procedure Extract_Protected_Entry_Attributes | |
2603 (Spec_Id : out Entity_Id; | |
2604 Body_Decl : out Node_Id; | |
2605 Body_Barf : out Node_Id); | |
2606 -- Obtain the attributes associated with a protected entry [family]. | |
2607 -- Spec_Id is the entity of the protected body subprogram. Body_Decl | |
2608 -- is the declaration of Spec_Id's corresponding body. Body_Barf is | |
2609 -- the declaration of the barrier function body. | |
2610 | |
2611 procedure Extract_Protected_Subprogram_Attributes | |
2612 (Spec_Id : out Entity_Id; | |
2613 Body_Decl : out Node_Id); | |
2614 -- Obtain the attributes associated with a protected subprogram. Formal | |
2615 -- Spec_Id is the entity of the protected body subprogram. Body_Decl is | |
2616 -- the declaration of Spec_Id's corresponding body. | |
2617 | |
2618 procedure Extract_Task_Entry_Attributes | |
2619 (Spec_Id : out Entity_Id; | |
2620 Body_Decl : out Node_Id); | |
2621 -- Obtain the attributes associated with a task entry [family]. Formal | |
2622 -- Spec_Id is the entity of the task body procedure. Body_Decl is the | |
2623 -- declaration of Spec_Id's corresponding body. | |
2624 | |
2625 ---------------------------------------------- | |
2626 -- Extract_Package_Or_Subprogram_Attributes -- | |
2627 ---------------------------------------------- | |
2628 | |
2629 procedure Extract_Package_Or_Subprogram_Attributes | |
2630 (Spec_Id : out Entity_Id; | |
2631 Body_Decl : out Node_Id) | |
2632 is | |
2633 Body_Id : Entity_Id; | |
2634 Init_Id : Entity_Id; | |
2635 Spec_Decl : Node_Id; | |
2636 | |
2637 begin | |
2638 -- Assume that the body is not available | |
2639 | |
2640 Body_Decl := Empty; | |
2641 Spec_Id := Target_Id; | |
2642 | |
2643 -- For body retrieval purposes, the entity of the initial declaration | |
2644 -- is that of the spec. | |
2645 | |
2646 Init_Id := Spec_Id; | |
2647 | |
2648 -- The only exception to the above is a function which returns a | |
2649 -- constrained array type in a SPARK-to-C compilation. In this case | |
2650 -- the function receives a corresponding procedure which has an out | |
2651 -- parameter. The proper body for ABE checks and diagnostics is that | |
2652 -- of the procedure. | |
2653 | |
2654 if Ekind (Init_Id) = E_Function | |
2655 and then Rewritten_For_C (Init_Id) | |
2656 then | |
2657 Init_Id := Corresponding_Procedure (Init_Id); | |
2658 end if; | |
2659 | |
2660 -- Extract the attributes of the body | |
2661 | |
2662 Spec_Decl := Unit_Declaration_Node (Init_Id); | |
2663 | |
2664 -- The initial declaration is a stand alone subprogram body | |
2665 | |
2666 if Nkind (Spec_Decl) = N_Subprogram_Body then | |
2667 Body_Decl := Spec_Decl; | |
2668 | |
2669 -- Otherwise the package or subprogram has a spec and a completing | |
2670 -- body. | |
2671 | |
2672 elsif Nkind_In (Spec_Decl, N_Generic_Package_Declaration, | |
2673 N_Generic_Subprogram_Declaration, | |
2674 N_Package_Declaration, | |
2675 N_Subprogram_Body_Stub, | |
2676 N_Subprogram_Declaration) | |
2677 then | |
2678 Body_Id := Corresponding_Body (Spec_Decl); | |
2679 | |
2680 if Present (Body_Id) then | |
2681 Body_Decl := Unit_Declaration_Node (Body_Id); | |
2682 end if; | |
2683 end if; | |
2684 end Extract_Package_Or_Subprogram_Attributes; | |
2685 | |
2686 ---------------------------------------- | |
2687 -- Extract_Protected_Entry_Attributes -- | |
2688 ---------------------------------------- | |
2689 | |
2690 procedure Extract_Protected_Entry_Attributes | |
2691 (Spec_Id : out Entity_Id; | |
2692 Body_Decl : out Node_Id; | |
2693 Body_Barf : out Node_Id) | |
2694 is | |
2695 Barf_Id : Entity_Id; | |
2696 Body_Id : Entity_Id; | |
2697 | |
2698 begin | |
2699 -- Assume that the bodies are not available | |
2700 | |
2701 Body_Barf := Empty; | |
2702 Body_Decl := Empty; | |
2703 | |
2704 -- When the entry [family] has already been expanded, it carries both | |
2705 -- the procedure which emulates the behavior of the entry [family] as | |
2706 -- well as the barrier function. | |
2707 | |
2708 if Present (Protected_Body_Subprogram (Target_Id)) then | |
2709 Spec_Id := Protected_Body_Subprogram (Target_Id); | |
2710 | |
2711 -- Extract the attributes of the barrier function | |
2712 | |
2713 Barf_Id := | |
2714 Corresponding_Body | |
2715 (Unit_Declaration_Node (Barrier_Function (Target_Id))); | |
2716 | |
2717 if Present (Barf_Id) then | |
2718 Body_Barf := Unit_Declaration_Node (Barf_Id); | |
2719 end if; | |
2720 | |
2721 -- Otherwise no expansion took place | |
2722 | |
2723 else | |
2724 Spec_Id := Target_Id; | |
2725 end if; | |
2726 | |
2727 -- Extract the attributes of the entry body | |
2728 | |
2729 Body_Id := Corresponding_Body (Unit_Declaration_Node (Spec_Id)); | |
2730 | |
2731 if Present (Body_Id) then | |
2732 Body_Decl := Unit_Declaration_Node (Body_Id); | |
2733 end if; | |
2734 end Extract_Protected_Entry_Attributes; | |
2735 | |
2736 --------------------------------------------- | |
2737 -- Extract_Protected_Subprogram_Attributes -- | |
2738 --------------------------------------------- | |
2739 | |
2740 procedure Extract_Protected_Subprogram_Attributes | |
2741 (Spec_Id : out Entity_Id; | |
2742 Body_Decl : out Node_Id) | |
2743 is | |
2744 Body_Id : Entity_Id; | |
2745 | |
2746 begin | |
2747 -- Assume that the body is not available | |
2748 | |
2749 Body_Decl := Empty; | |
2750 | |
2751 -- When the protected subprogram has already been expanded, it | |
2752 -- carries the subprogram which seizes the lock and invokes the | |
2753 -- original statements. | |
2754 | |
2755 if Present (Protected_Subprogram (Target_Id)) then | |
2756 Spec_Id := | |
2757 Protected_Body_Subprogram (Protected_Subprogram (Target_Id)); | |
2758 | |
2759 -- Otherwise no expansion took place | |
2760 | |
2761 else | |
2762 Spec_Id := Target_Id; | |
2763 end if; | |
2764 | |
2765 -- Extract the attributes of the body | |
2766 | |
2767 Body_Id := Corresponding_Body (Unit_Declaration_Node (Spec_Id)); | |
2768 | |
2769 if Present (Body_Id) then | |
2770 Body_Decl := Unit_Declaration_Node (Body_Id); | |
2771 end if; | |
2772 end Extract_Protected_Subprogram_Attributes; | |
2773 | |
2774 ----------------------------------- | |
2775 -- Extract_Task_Entry_Attributes -- | |
2776 ----------------------------------- | |
2777 | |
2778 procedure Extract_Task_Entry_Attributes | |
2779 (Spec_Id : out Entity_Id; | |
2780 Body_Decl : out Node_Id) | |
2781 is | |
2782 Task_Typ : constant Entity_Id := Non_Private_View (Scope (Target_Id)); | |
2783 Body_Id : Entity_Id; | |
2784 | |
2785 begin | |
2786 -- Assume that the body is not available | |
2787 | |
2788 Body_Decl := Empty; | |
2789 | |
2790 -- The the task type has already been expanded, it carries the | |
2791 -- procedure which emulates the behavior of the task body. | |
2792 | |
2793 if Present (Task_Body_Procedure (Task_Typ)) then | |
2794 Spec_Id := Task_Body_Procedure (Task_Typ); | |
2795 | |
2796 -- Otherwise no expansion took place | |
2797 | |
2798 else | |
2799 Spec_Id := Task_Typ; | |
2800 end if; | |
2801 | |
2802 -- Extract the attributes of the body | |
2803 | |
2804 Body_Id := Corresponding_Body (Unit_Declaration_Node (Spec_Id)); | |
2805 | |
2806 if Present (Body_Id) then | |
2807 Body_Decl := Unit_Declaration_Node (Body_Id); | |
2808 end if; | |
2809 end Extract_Task_Entry_Attributes; | |
2810 | |
2811 -- Local variables | |
2812 | |
2813 Prag : constant Node_Id := SPARK_Pragma (Target_Id); | |
2814 Body_Barf : Node_Id; | |
2815 Body_Decl : Node_Id; | |
2816 Spec_Id : Entity_Id; | |
2817 | |
2818 -- Start of processing for Extract_Target_Attributes | |
2819 | |
2820 begin | |
2821 -- Assume that the body of the barrier function is not available | |
2822 | |
2823 Body_Barf := Empty; | |
2824 | |
2825 -- The target is a protected entry [family] | |
2826 | |
2827 if Is_Protected_Entry (Target_Id) then | |
2828 Extract_Protected_Entry_Attributes | |
2829 (Spec_Id => Spec_Id, | |
2830 Body_Decl => Body_Decl, | |
2831 Body_Barf => Body_Barf); | |
2832 | |
2833 -- The target is a protected subprogram | |
2834 | |
2835 elsif Is_Protected_Subp (Target_Id) | |
2836 or else Is_Protected_Body_Subp (Target_Id) | |
2837 then | |
2838 Extract_Protected_Subprogram_Attributes | |
2839 (Spec_Id => Spec_Id, | |
2840 Body_Decl => Body_Decl); | |
2841 | |
2842 -- The target is a task entry [family] | |
2843 | |
2844 elsif Is_Task_Entry (Target_Id) then | |
2845 Extract_Task_Entry_Attributes | |
2846 (Spec_Id => Spec_Id, | |
2847 Body_Decl => Body_Decl); | |
2848 | |
2849 -- Otherwise the target is a package or a subprogram | |
2850 | |
2851 else | |
2852 Extract_Package_Or_Subprogram_Attributes | |
2853 (Spec_Id => Spec_Id, | |
2854 Body_Decl => Body_Decl); | |
2855 end if; | |
2856 | |
2857 -- Set all attributes | |
2858 | |
2859 Attrs.Body_Barf := Body_Barf; | |
2860 Attrs.Body_Decl := Body_Decl; | |
2861 Attrs.Elab_Checks_OK := Is_Elaboration_Checks_OK_Id (Target_Id); | |
2862 Attrs.From_Source := Comes_From_Source (Target_Id); | |
2863 Attrs.Ghost_Mode_Ignore := Is_Ignored_Ghost_Entity (Target_Id); | |
2864 Attrs.SPARK_Mode_On := | |
2865 Present (Prag) and then Get_SPARK_Mode_From_Annotation (Prag) = On; | |
2866 Attrs.Spec_Decl := Unit_Declaration_Node (Spec_Id); | |
2867 Attrs.Spec_Id := Spec_Id; | |
2868 Attrs.Unit_Id := Find_Top_Unit (Target_Id); | |
2869 | |
2870 -- At this point certain attributes should always be available | |
2871 | |
2872 pragma Assert (Present (Attrs.Spec_Decl)); | |
2873 pragma Assert (Present (Attrs.Spec_Id)); | |
2874 pragma Assert (Present (Attrs.Unit_Id)); | |
2875 end Extract_Target_Attributes; | |
2876 | |
2877 ----------------------------- | |
2878 -- Extract_Task_Attributes -- | |
2879 ----------------------------- | |
2880 | |
2881 procedure Extract_Task_Attributes | |
2882 (Typ : Entity_Id; | |
2883 Attrs : out Task_Attributes) | |
2884 is | |
2885 Task_Typ : constant Entity_Id := Non_Private_View (Typ); | |
2886 | |
2887 Body_Decl : Node_Id; | |
2888 Body_Id : Entity_Id; | |
2889 Prag : Node_Id; | |
2890 Spec_Id : Entity_Id; | |
2891 | |
2892 begin | |
2893 -- Assume that the body of the task procedure is not available | |
2894 | |
2895 Body_Decl := Empty; | |
2896 | |
2897 -- The initial declaration is that of the task body procedure | |
2898 | |
2899 Spec_Id := Get_Task_Body_Procedure (Task_Typ); | |
2900 Body_Id := Corresponding_Body (Unit_Declaration_Node (Spec_Id)); | |
2901 | |
2902 if Present (Body_Id) then | |
2903 Body_Decl := Unit_Declaration_Node (Body_Id); | |
2904 end if; | |
2905 | |
2906 Prag := SPARK_Pragma (Task_Typ); | |
2907 | |
2908 -- Set all attributes | |
2909 | |
2910 Attrs.Body_Decl := Body_Decl; | |
2911 Attrs.Elab_Checks_OK := Is_Elaboration_Checks_OK_Id (Task_Typ); | |
2912 Attrs.Ghost_Mode_Ignore := Is_Ignored_Ghost_Entity (Task_Typ); | |
2913 Attrs.SPARK_Mode_On := | |
2914 Present (Prag) and then Get_SPARK_Mode_From_Annotation (Prag) = On; | |
2915 Attrs.Spec_Id := Spec_Id; | |
2916 Attrs.Task_Decl := Declaration_Node (Task_Typ); | |
2917 Attrs.Unit_Id := Find_Top_Unit (Task_Typ); | |
2918 | |
2919 -- At this point certain attributes should always be available | |
2920 | |
2921 pragma Assert (Present (Attrs.Spec_Id)); | |
2922 pragma Assert (Present (Attrs.Task_Decl)); | |
2923 pragma Assert (Present (Attrs.Unit_Id)); | |
2924 end Extract_Task_Attributes; | |
2925 | |
2926 ------------------------------------------- | |
2927 -- Extract_Variable_Reference_Attributes -- | |
2928 ------------------------------------------- | |
2929 | |
2930 procedure Extract_Variable_Reference_Attributes | |
2931 (Ref : Node_Id; | |
2932 Var_Id : out Entity_Id; | |
2933 Attrs : out Variable_Attributes) | |
2934 is | |
2935 begin | |
2936 -- Traverse a possible chain of renamings to obtain the original | |
2937 -- variable being referenced. | |
2938 | |
2939 Var_Id := Get_Renamed_Entity (Entity (Ref)); | |
2940 | |
2941 Attrs.SPARK_Mode_On := Is_SPARK_Mode_On_Node (Ref); | |
2942 Attrs.Unit_Id := Find_Top_Unit (Var_Id); | |
2943 | |
2944 -- At this point certain attributes should always be available | |
2945 | |
2946 pragma Assert (Present (Attrs.Unit_Id)); | |
2947 end Extract_Variable_Reference_Attributes; | |
2948 | |
2949 -------------------- | |
2950 -- Find_Code_Unit -- | |
2951 -------------------- | |
2952 | |
2953 function Find_Code_Unit (N : Node_Or_Entity_Id) return Entity_Id is | |
2954 begin | |
2955 return Find_Unit_Entity (Unit (Cunit (Get_Code_Unit (N)))); | |
2956 end Find_Code_Unit; | |
2957 | |
2958 --------------------------- | |
2959 -- Find_Elaborated_Units -- | |
2960 --------------------------- | |
2961 | |
2962 procedure Find_Elaborated_Units is | |
2963 procedure Add_Pragma (Prag : Node_Id); | |
2964 -- Determine whether pragma Prag denotes a legal Elaborate[_All] pragma. | |
2965 -- If this is the case, add the related unit to the elaboration context. | |
2966 -- For pragma Elaborate_All, include recursively all units withed by the | |
2967 -- related unit. | |
2968 | |
2969 procedure Add_Unit | |
2970 (Unit_Id : Entity_Id; | |
2971 Prag : Node_Id; | |
2972 Full_Context : Boolean); | |
2973 -- Add unit Unit_Id to the elaboration context. Prag denotes the pragma | |
2974 -- which prompted the inclusion of the unit to the elaboration context. | |
2975 -- If flag Full_Context is set, examine the nonlimited clauses of unit | |
2976 -- Unit_Id and add each withed unit to the context. | |
2977 | |
2978 procedure Find_Elaboration_Context (Comp_Unit : Node_Id); | |
2979 -- Examine the context items of compilation unit Comp_Unit for suitable | |
2980 -- elaboration-related pragmas and add all related units to the context. | |
2981 | |
2982 ---------------- | |
2983 -- Add_Pragma -- | |
2984 ---------------- | |
2985 | |
2986 procedure Add_Pragma (Prag : Node_Id) is | |
2987 Prag_Args : constant List_Id := Pragma_Argument_Associations (Prag); | |
2988 Prag_Nam : constant Name_Id := Pragma_Name (Prag); | |
2989 Unit_Arg : Node_Id; | |
2990 | |
2991 begin | |
2992 -- Nothing to do if the pragma is not related to elaboration | |
2993 | |
2994 if not Nam_In (Prag_Nam, Name_Elaborate, Name_Elaborate_All) then | |
2995 return; | |
2996 | |
2997 -- Nothing to do when the pragma is illegal | |
2998 | |
2999 elsif Error_Posted (Prag) then | |
3000 return; | |
3001 end if; | |
3002 | |
3003 Unit_Arg := Get_Pragma_Arg (First (Prag_Args)); | |
3004 | |
3005 -- The argument of the pragma may appear in package.package form | |
3006 | |
3007 if Nkind (Unit_Arg) = N_Selected_Component then | |
3008 Unit_Arg := Selector_Name (Unit_Arg); | |
3009 end if; | |
3010 | |
3011 Add_Unit | |
3012 (Unit_Id => Entity (Unit_Arg), | |
3013 Prag => Prag, | |
3014 Full_Context => Prag_Nam = Name_Elaborate_All); | |
3015 end Add_Pragma; | |
3016 | |
3017 -------------- | |
3018 -- Add_Unit -- | |
3019 -------------- | |
3020 | |
3021 procedure Add_Unit | |
3022 (Unit_Id : Entity_Id; | |
3023 Prag : Node_Id; | |
3024 Full_Context : Boolean) | |
3025 is | |
3026 Clause : Node_Id; | |
3027 Elab_Attrs : Elaboration_Attributes; | |
3028 | |
3029 begin | |
3030 -- Nothing to do when some previous error left a with clause or a | |
3031 -- pragma in a bad state. | |
3032 | |
3033 if No (Unit_Id) then | |
3034 return; | |
3035 end if; | |
3036 | |
3037 Elab_Attrs := Elaboration_Context.Get (Unit_Id); | |
3038 | |
3039 -- The current unit is not part of the context. Prepare a new set of | |
3040 -- attributes. | |
3041 | |
3042 if Elab_Attrs = No_Elaboration_Attributes then | |
3043 Elab_Attrs := | |
3044 Elaboration_Attributes'(Source_Pragma => Prag, | |
3045 With_Clause => Empty); | |
3046 | |
3047 -- The unit is already included in the context by means of pragma | |
3048 -- Elaborate. "Upgrage" the existing attributes when the unit is | |
3049 -- subject to Elaborate_All because the new pragma covers a larger | |
3050 -- set of units. All other properties remain the same. | |
3051 | |
3052 elsif Pragma_Name (Elab_Attrs.Source_Pragma) = Name_Elaborate | |
3053 and then Pragma_Name (Prag) = Name_Elaborate_All | |
3054 then | |
3055 Elab_Attrs.Source_Pragma := Prag; | |
3056 | |
3057 -- Otherwise the unit is already included in the context | |
3058 | |
3059 else | |
3060 return; | |
3061 end if; | |
3062 | |
3063 -- Add or update the attributes of the unit | |
3064 | |
3065 Elaboration_Context.Set (Unit_Id, Elab_Attrs); | |
3066 | |
3067 -- Includes all units withed by the current one when computing the | |
3068 -- full context. | |
3069 | |
3070 if Full_Context then | |
3071 | |
3072 -- Process all nonlimited with clauses found in the context of | |
3073 -- the current unit. Note that limited clauses do not impose an | |
3074 -- elaboration order. | |
3075 | |
3076 Clause := First (Context_Items (Compilation_Unit (Unit_Id))); | |
3077 while Present (Clause) loop | |
3078 if Nkind (Clause) = N_With_Clause | |
3079 and then not Error_Posted (Clause) | |
3080 and then not Limited_Present (Clause) | |
3081 then | |
3082 Add_Unit | |
3083 (Unit_Id => Entity (Name (Clause)), | |
3084 Prag => Prag, | |
3085 Full_Context => Full_Context); | |
3086 end if; | |
3087 | |
3088 Next (Clause); | |
3089 end loop; | |
3090 end if; | |
3091 end Add_Unit; | |
3092 | |
3093 ------------------------------ | |
3094 -- Find_Elaboration_Context -- | |
3095 ------------------------------ | |
3096 | |
3097 procedure Find_Elaboration_Context (Comp_Unit : Node_Id) is | |
3098 Prag : Node_Id; | |
3099 | |
3100 begin | |
3101 pragma Assert (Nkind (Comp_Unit) = N_Compilation_Unit); | |
3102 | |
3103 -- Process all elaboration-related pragmas found in the context of | |
3104 -- the compilation unit. | |
3105 | |
3106 Prag := First (Context_Items (Comp_Unit)); | |
3107 while Present (Prag) loop | |
3108 if Nkind (Prag) = N_Pragma then | |
3109 Add_Pragma (Prag); | |
3110 end if; | |
3111 | |
3112 Next (Prag); | |
3113 end loop; | |
3114 end Find_Elaboration_Context; | |
3115 | |
3116 -- Local variables | |
3117 | |
3118 Par_Id : Entity_Id; | |
3119 Unt : Node_Id; | |
3120 | |
3121 -- Start of processing for Find_Elaborated_Units | |
3122 | |
3123 begin | |
3124 -- Perform a traversal which examines the context of the main unit and | |
3125 -- populates the Elaboration_Context table with all units elaborated | |
3126 -- prior to the main unit. The traversal performs the following jumps: | |
3127 | |
3128 -- subunit -> parent subunit | |
3129 -- parent subunit -> body | |
3130 -- body -> spec | |
3131 -- spec -> parent spec | |
3132 -- parent spec -> grandparent spec and so on | |
3133 | |
3134 -- The traversal relies on units rather than scopes because the scope of | |
3135 -- a subunit is some spec, while this traversal must process the body as | |
3136 -- well. Given that protected and task bodies can also be subunits, this | |
3137 -- complicates the scope approach even further. | |
3138 | |
3139 Unt := Unit (Cunit (Main_Unit)); | |
3140 | |
3141 -- Perform the following traversals when the main unit is a subunit | |
3142 | |
3143 -- subunit -> parent subunit | |
3144 -- parent subunit -> body | |
3145 | |
3146 while Present (Unt) and then Nkind (Unt) = N_Subunit loop | |
3147 Find_Elaboration_Context (Parent (Unt)); | |
3148 | |
3149 -- Continue the traversal by going to the unit which contains the | |
3150 -- corresponding stub. | |
3151 | |
3152 if Present (Corresponding_Stub (Unt)) then | |
3153 Unt := Unit (Cunit (Get_Source_Unit (Corresponding_Stub (Unt)))); | |
3154 | |
3155 -- Otherwise the subunit may be erroneous or left in a bad state | |
3156 | |
3157 else | |
3158 exit; | |
3159 end if; | |
3160 end loop; | |
3161 | |
3162 -- Perform the following traversal now that subunits have been taken | |
3163 -- care of, or the main unit is a body. | |
3164 | |
3165 -- body -> spec | |
3166 | |
3167 if Present (Unt) | |
3168 and then Nkind_In (Unt, N_Package_Body, N_Subprogram_Body) | |
3169 then | |
3170 Find_Elaboration_Context (Parent (Unt)); | |
3171 | |
3172 -- Continue the traversal by going to the unit which contains the | |
3173 -- corresponding spec. | |
3174 | |
3175 if Present (Corresponding_Spec (Unt)) then | |
3176 Unt := Unit (Cunit (Get_Source_Unit (Corresponding_Spec (Unt)))); | |
3177 end if; | |
3178 end if; | |
3179 | |
3180 -- Perform the following traversals now that the body has been taken | |
3181 -- care of, or the main unit is a spec. | |
3182 | |
3183 -- spec -> parent spec | |
3184 -- parent spec -> grandparent spec and so on | |
3185 | |
3186 if Present (Unt) | |
3187 and then Nkind_In (Unt, N_Generic_Package_Declaration, | |
3188 N_Generic_Subprogram_Declaration, | |
3189 N_Package_Declaration, | |
3190 N_Subprogram_Declaration) | |
3191 then | |
3192 Find_Elaboration_Context (Parent (Unt)); | |
3193 | |
3194 -- Process a potential chain of parent units which ends with the | |
3195 -- main unit spec. The traversal can now safely rely on the scope | |
3196 -- chain. | |
3197 | |
3198 Par_Id := Scope (Defining_Entity (Unt)); | |
3199 while Present (Par_Id) and then Par_Id /= Standard_Standard loop | |
3200 Find_Elaboration_Context (Compilation_Unit (Par_Id)); | |
3201 | |
3202 Par_Id := Scope (Par_Id); | |
3203 end loop; | |
3204 end if; | |
3205 end Find_Elaborated_Units; | |
3206 | |
3207 ----------------------------- | |
3208 -- Find_Enclosing_Instance -- | |
3209 ----------------------------- | |
3210 | |
3211 function Find_Enclosing_Instance (N : Node_Id) return Node_Id is | |
3212 Par : Node_Id; | |
3213 Spec_Id : Entity_Id; | |
3214 | |
3215 begin | |
3216 -- Climb the parent chain looking for an enclosing instance spec or body | |
3217 | |
3218 Par := N; | |
3219 while Present (Par) loop | |
3220 | |
3221 -- Generic package or subprogram spec | |
3222 | |
3223 if Nkind_In (Par, N_Package_Declaration, | |
3224 N_Subprogram_Declaration) | |
3225 and then Is_Generic_Instance (Defining_Entity (Par)) | |
3226 then | |
3227 return Par; | |
3228 | |
3229 -- Generic package or subprogram body | |
3230 | |
3231 elsif Nkind_In (Par, N_Package_Body, N_Subprogram_Body) then | |
3232 Spec_Id := Corresponding_Spec (Par); | |
3233 | |
3234 if Present (Spec_Id) and then Is_Generic_Instance (Spec_Id) then | |
3235 return Par; | |
3236 end if; | |
3237 end if; | |
3238 | |
3239 Par := Parent (Par); | |
3240 end loop; | |
3241 | |
3242 return Empty; | |
3243 end Find_Enclosing_Instance; | |
3244 | |
3245 -------------------------- | |
3246 -- Find_Enclosing_Level -- | |
3247 -------------------------- | |
3248 | |
3249 function Find_Enclosing_Level (N : Node_Id) return Enclosing_Level_Kind is | |
3250 function Level_Of (Unit : Node_Id) return Enclosing_Level_Kind; | |
3251 -- Obtain the corresponding level of unit Unit | |
3252 | |
3253 -------------- | |
3254 -- Level_Of -- | |
3255 -------------- | |
3256 | |
3257 function Level_Of (Unit : Node_Id) return Enclosing_Level_Kind is | |
3258 Spec_Id : Entity_Id; | |
3259 | |
3260 begin | |
3261 if Nkind (Unit) in N_Generic_Instantiation then | |
3262 return Instantiation; | |
3263 | |
3264 elsif Nkind (Unit) = N_Generic_Package_Declaration then | |
3265 return Generic_Package_Spec; | |
3266 | |
3267 elsif Nkind (Unit) = N_Package_Declaration then | |
3268 return Package_Spec; | |
3269 | |
3270 elsif Nkind (Unit) = N_Package_Body then | |
3271 Spec_Id := Corresponding_Spec (Unit); | |
3272 | |
3273 -- The body belongs to a generic package | |
3274 | |
3275 if Present (Spec_Id) | |
3276 and then Ekind (Spec_Id) = E_Generic_Package | |
3277 then | |
3278 return Generic_Package_Body; | |
3279 | |
3280 -- Otherwise the body belongs to a non-generic package. This also | |
3281 -- treats an illegal package body without a corresponding spec as | |
3282 -- a non-generic package body. | |
3283 | |
3284 else | |
3285 return Package_Body; | |
3286 end if; | |
3287 end if; | |
3288 | |
3289 return No_Level; | |
3290 end Level_Of; | |
3291 | |
3292 -- Local variables | |
3293 | |
3294 Context : Node_Id; | |
3295 Curr : Node_Id; | |
3296 Prev : Node_Id; | |
3297 | |
3298 -- Start of processing for Find_Enclosing_Level | |
3299 | |
3300 begin | |
3301 -- Call markers and instantiations which appear at the declaration level | |
3302 -- but are later relocated in a different context retain their original | |
3303 -- declaration level. | |
3304 | |
3305 if Nkind_In (N, N_Call_Marker, | |
3306 N_Function_Instantiation, | |
3307 N_Package_Instantiation, | |
3308 N_Procedure_Instantiation) | |
3309 and then Is_Declaration_Level_Node (N) | |
3310 then | |
3311 return Declaration_Level; | |
3312 end if; | |
3313 | |
3314 -- Climb the parent chain looking at the enclosing levels | |
3315 | |
3316 Prev := N; | |
3317 Curr := Parent (Prev); | |
3318 while Present (Curr) loop | |
3319 | |
3320 -- A traversal from a subunit continues via the corresponding stub | |
3321 | |
3322 if Nkind (Curr) = N_Subunit then | |
3323 Curr := Corresponding_Stub (Curr); | |
3324 | |
3325 -- The current construct is a package. Packages are ignored because | |
3326 -- they are always elaborated when the enclosing context is invoked | |
3327 -- or elaborated. | |
3328 | |
3329 elsif Nkind_In (Curr, N_Package_Body, N_Package_Declaration) then | |
3330 null; | |
3331 | |
3332 -- The current construct is a block statement | |
3333 | |
3334 elsif Nkind (Curr) = N_Block_Statement then | |
3335 | |
3336 -- Ignore internally generated blocks created by the expander for | |
3337 -- various purposes such as abort defer/undefer. | |
3338 | |
3339 if not Comes_From_Source (Curr) then | |
3340 null; | |
3341 | |
3342 -- If the traversal came from the handled sequence of statments, | |
3343 -- then the node appears at the level of the enclosing construct. | |
3344 -- This is a more reliable test because transients scopes within | |
3345 -- the declarative region of the encapsulator are hard to detect. | |
3346 | |
3347 elsif Nkind (Prev) = N_Handled_Sequence_Of_Statements | |
3348 and then Handled_Statement_Sequence (Curr) = Prev | |
3349 then | |
3350 return Find_Enclosing_Level (Parent (Curr)); | |
3351 | |
3352 -- Otherwise the traversal came from the declarations, the node is | |
3353 -- at the declaration level. | |
3354 | |
3355 else | |
3356 return Declaration_Level; | |
3357 end if; | |
3358 | |
3359 -- The current construct is a declaration level encapsulator | |
3360 | |
3361 elsif Nkind_In (Curr, N_Entry_Body, | |
3362 N_Subprogram_Body, | |
3363 N_Task_Body) | |
3364 then | |
3365 -- If the traversal came from the handled sequence of statments, | |
3366 -- then the node cannot possibly appear at any level. This is | |
3367 -- a more reliable test because transients scopes within the | |
3368 -- declarative region of the encapsulator are hard to detect. | |
3369 | |
3370 if Nkind (Prev) = N_Handled_Sequence_Of_Statements | |
3371 and then Handled_Statement_Sequence (Curr) = Prev | |
3372 then | |
3373 return No_Level; | |
3374 | |
3375 -- Otherwise the traversal came from the declarations, the node is | |
3376 -- at the declaration level. | |
3377 | |
3378 else | |
3379 return Declaration_Level; | |
3380 end if; | |
3381 | |
3382 -- The current construct is a non-library level encapsulator which | |
3383 -- indicates that the node cannot possibly appear at any level. | |
3384 -- Note that this check must come after the declaration level check | |
3385 -- because both predicates share certain nodes. | |
3386 | |
3387 elsif Is_Non_Library_Level_Encapsulator (Curr) then | |
3388 Context := Parent (Curr); | |
3389 | |
3390 -- The sole exception is when the encapsulator is the compilation | |
3391 -- utit itself because the compilation unit node requires special | |
3392 -- processing (see below). | |
3393 | |
3394 if Present (Context) | |
3395 and then Nkind (Context) = N_Compilation_Unit | |
3396 then | |
3397 null; | |
3398 | |
3399 -- Otherwise the node is not at any level | |
3400 | |
3401 else | |
3402 return No_Level; | |
3403 end if; | |
3404 | |
3405 -- The current construct is a compilation unit. The node appears at | |
3406 -- the [generic] library level when the unit is a [generic] package. | |
3407 | |
3408 elsif Nkind (Curr) = N_Compilation_Unit then | |
3409 return Level_Of (Unit (Curr)); | |
3410 end if; | |
3411 | |
3412 Prev := Curr; | |
3413 Curr := Parent (Prev); | |
3414 end loop; | |
3415 | |
3416 return No_Level; | |
3417 end Find_Enclosing_Level; | |
3418 | |
3419 ------------------- | |
3420 -- Find_Top_Unit -- | |
3421 ------------------- | |
3422 | |
3423 function Find_Top_Unit (N : Node_Or_Entity_Id) return Entity_Id is | |
3424 begin | |
3425 return Find_Unit_Entity (Unit (Cunit (Get_Top_Level_Code_Unit (N)))); | |
3426 end Find_Top_Unit; | |
3427 | |
3428 ---------------------- | |
3429 -- Find_Unit_Entity -- | |
3430 ---------------------- | |
3431 | |
3432 function Find_Unit_Entity (N : Node_Id) return Entity_Id is | |
3433 Context : constant Node_Id := Parent (N); | |
3434 Orig_N : constant Node_Id := Original_Node (N); | |
3435 | |
3436 begin | |
3437 -- The unit denotes a package body of an instantiation which acts as | |
3438 -- a compilation unit. The proper entity is that of the package spec. | |
3439 | |
3440 if Nkind (N) = N_Package_Body | |
3441 and then Nkind (Orig_N) = N_Package_Instantiation | |
3442 and then Nkind (Context) = N_Compilation_Unit | |
3443 then | |
3444 return Corresponding_Spec (N); | |
3445 | |
3446 -- The unit denotes an anonymous package created to wrap a subprogram | |
3447 -- instantiation which acts as a compilation unit. The proper entity is | |
3448 -- that of the "related instance". | |
3449 | |
3450 elsif Nkind (N) = N_Package_Declaration | |
3451 and then Nkind_In (Orig_N, N_Function_Instantiation, | |
3452 N_Procedure_Instantiation) | |
3453 and then Nkind (Context) = N_Compilation_Unit | |
3454 then | |
3455 return | |
3456 Related_Instance (Defining_Entity (N, Concurrent_Subunit => True)); | |
3457 | |
3458 -- Otherwise the proper entity is the defining entity | |
3459 | |
3460 else | |
3461 return Defining_Entity (N, Concurrent_Subunit => True); | |
3462 end if; | |
3463 end Find_Unit_Entity; | |
3464 | |
3465 ----------------------- | |
3466 -- First_Formal_Type -- | |
3467 ----------------------- | |
3468 | |
3469 function First_Formal_Type (Subp_Id : Entity_Id) return Entity_Id is | |
3470 Formal_Id : constant Entity_Id := First_Formal (Subp_Id); | |
3471 Typ : Entity_Id; | |
3472 | |
3473 begin | |
3474 if Present (Formal_Id) then | |
3475 Typ := Etype (Formal_Id); | |
3476 | |
3477 -- Handle various combinations of concurrent and private types | |
3478 | |
3479 loop | |
3480 if Ekind_In (Typ, E_Protected_Type, E_Task_Type) | |
3481 and then Present (Anonymous_Object (Typ)) | |
3482 then | |
3483 Typ := Anonymous_Object (Typ); | |
3484 | |
3485 elsif Is_Concurrent_Record_Type (Typ) then | |
3486 Typ := Corresponding_Concurrent_Type (Typ); | |
3487 | |
3488 elsif Is_Private_Type (Typ) and then Present (Full_View (Typ)) then | |
3489 Typ := Full_View (Typ); | |
3490 | |
3491 else | |
3492 exit; | |
3493 end if; | |
3494 end loop; | |
3495 | |
3496 return Typ; | |
3497 end if; | |
3498 | |
3499 return Empty; | |
3500 end First_Formal_Type; | |
3501 | |
3502 -------------- | |
3503 -- Has_Body -- | |
3504 -------------- | |
3505 | |
3506 function Has_Body (Pack_Decl : Node_Id) return Boolean is | |
3507 function Find_Corresponding_Body (Spec_Id : Entity_Id) return Node_Id; | |
3508 -- Try to locate the corresponding body of spec Spec_Id. If no body is | |
3509 -- found, return Empty. | |
3510 | |
3511 function Find_Body | |
3512 (Spec_Id : Entity_Id; | |
3513 From : Node_Id) return Node_Id; | |
3514 -- Try to locate the corresponding body of spec Spec_Id in the node list | |
3515 -- which follows arbitrary node From. If no body is found, return Empty. | |
3516 | |
3517 function Load_Package_Body (Unit_Nam : Unit_Name_Type) return Node_Id; | |
3518 -- Attempt to load the body of unit Unit_Nam. If the load failed, return | |
3519 -- Empty. If the compilation will not generate code, return Empty. | |
3520 | |
3521 ----------------------------- | |
3522 -- Find_Corresponding_Body -- | |
3523 ----------------------------- | |
3524 | |
3525 function Find_Corresponding_Body (Spec_Id : Entity_Id) return Node_Id is | |
3526 Context : constant Entity_Id := Scope (Spec_Id); | |
3527 Spec_Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id); | |
3528 Body_Decl : Node_Id; | |
3529 Body_Id : Entity_Id; | |
3530 | |
3531 begin | |
3532 if Is_Compilation_Unit (Spec_Id) then | |
3533 Body_Id := Corresponding_Body (Spec_Decl); | |
3534 | |
3535 if Present (Body_Id) then | |
3536 return Unit_Declaration_Node (Body_Id); | |
3537 | |
3538 -- The package is at the library and requires a body. Load the | |
3539 -- corresponding body because the optional body may be declared | |
3540 -- there. | |
3541 | |
3542 elsif Unit_Requires_Body (Spec_Id) then | |
3543 return | |
3544 Load_Package_Body | |
3545 (Get_Body_Name (Unit_Name (Get_Source_Unit (Spec_Decl)))); | |
3546 | |
3547 -- Otherwise there is no optional body | |
3548 | |
3549 else | |
3550 return Empty; | |
3551 end if; | |
3552 | |
3553 -- The immediate context is a package. The optional body may be | |
3554 -- within the body of that package. | |
3555 | |
3556 -- procedure Proc is | |
3557 -- package Nested_1 is | |
3558 -- package Nested_2 is | |
3559 -- generic | |
3560 -- package Pack is | |
3561 -- end Pack; | |
3562 -- end Nested_2; | |
3563 -- end Nested_1; | |
3564 | |
3565 -- package body Nested_1 is | |
3566 -- package body Nested_2 is separate; | |
3567 -- end Nested_1; | |
3568 | |
3569 -- separate (Proc.Nested_1.Nested_2) | |
3570 -- package body Nested_2 is | |
3571 -- package body Pack is -- optional body | |
3572 -- ... | |
3573 -- end Pack; | |
3574 -- end Nested_2; | |
3575 | |
3576 elsif Is_Package_Or_Generic_Package (Context) then | |
3577 Body_Decl := Find_Corresponding_Body (Context); | |
3578 | |
3579 -- The optional body is within the body of the enclosing package | |
3580 | |
3581 if Present (Body_Decl) then | |
3582 return | |
3583 Find_Body | |
3584 (Spec_Id => Spec_Id, | |
3585 From => First (Declarations (Body_Decl))); | |
3586 | |
3587 -- Otherwise the enclosing package does not have a body. This may | |
3588 -- be the result of an error or a genuine lack of a body. | |
3589 | |
3590 else | |
3591 return Empty; | |
3592 end if; | |
3593 | |
3594 -- Otherwise the immediate context is a body. The optional body may | |
3595 -- be within the same list as the spec. | |
3596 | |
3597 -- procedure Proc is | |
3598 -- generic | |
3599 -- package Pack is | |
3600 -- end Pack; | |
3601 | |
3602 -- package body Pack is -- optional body | |
3603 -- ... | |
3604 -- end Pack; | |
3605 | |
3606 else | |
3607 return | |
3608 Find_Body | |
3609 (Spec_Id => Spec_Id, | |
3610 From => Next (Spec_Decl)); | |
3611 end if; | |
3612 end Find_Corresponding_Body; | |
3613 | |
3614 --------------- | |
3615 -- Find_Body -- | |
3616 --------------- | |
3617 | |
3618 function Find_Body | |
3619 (Spec_Id : Entity_Id; | |
3620 From : Node_Id) return Node_Id | |
3621 is | |
3622 Spec_Nam : constant Name_Id := Chars (Spec_Id); | |
3623 Item : Node_Id; | |
3624 Lib_Unit : Node_Id; | |
3625 | |
3626 begin | |
3627 Item := From; | |
3628 while Present (Item) loop | |
3629 | |
3630 -- The current item denotes the optional body | |
3631 | |
3632 if Nkind (Item) = N_Package_Body | |
3633 and then Chars (Defining_Entity (Item)) = Spec_Nam | |
3634 then | |
3635 return Item; | |
3636 | |
3637 -- The current item denotes a stub, the optional body may be in | |
3638 -- the subunit. | |
3639 | |
3640 elsif Nkind (Item) = N_Package_Body_Stub | |
3641 and then Chars (Defining_Entity (Item)) = Spec_Nam | |
3642 then | |
3643 Lib_Unit := Library_Unit (Item); | |
3644 | |
3645 -- The corresponding subunit was previously loaded | |
3646 | |
3647 if Present (Lib_Unit) then | |
3648 return Lib_Unit; | |
3649 | |
3650 -- Otherwise attempt to load the corresponding subunit | |
3651 | |
3652 else | |
3653 return Load_Package_Body (Get_Unit_Name (Item)); | |
3654 end if; | |
3655 end if; | |
3656 | |
3657 Next (Item); | |
3658 end loop; | |
3659 | |
3660 return Empty; | |
3661 end Find_Body; | |
3662 | |
3663 ----------------------- | |
3664 -- Load_Package_Body -- | |
3665 ----------------------- | |
3666 | |
3667 function Load_Package_Body (Unit_Nam : Unit_Name_Type) return Node_Id is | |
3668 Body_Decl : Node_Id; | |
3669 Unit_Num : Unit_Number_Type; | |
3670 | |
3671 begin | |
3672 -- The load is performed only when the compilation will generate code | |
3673 | |
3674 if Operating_Mode = Generate_Code then | |
3675 Unit_Num := | |
3676 Load_Unit | |
3677 (Load_Name => Unit_Nam, | |
3678 Required => False, | |
3679 Subunit => False, | |
3680 Error_Node => Pack_Decl); | |
3681 | |
3682 -- The load failed most likely because the physical file is | |
3683 -- missing. | |
3684 | |
3685 if Unit_Num = No_Unit then | |
3686 return Empty; | |
3687 | |
3688 -- Otherwise the load was successful, return the body of the unit | |
3689 | |
3690 else | |
3691 Body_Decl := Unit (Cunit (Unit_Num)); | |
3692 | |
3693 -- If the unit is a subunit with an available proper body, | |
3694 -- return the proper body. | |
3695 | |
3696 if Nkind (Body_Decl) = N_Subunit | |
3697 and then Present (Proper_Body (Body_Decl)) | |
3698 then | |
3699 Body_Decl := Proper_Body (Body_Decl); | |
3700 end if; | |
3701 | |
3702 return Body_Decl; | |
3703 end if; | |
3704 end if; | |
3705 | |
3706 return Empty; | |
3707 end Load_Package_Body; | |
3708 | |
3709 -- Local variables | |
3710 | |
3711 Pack_Id : constant Entity_Id := Defining_Entity (Pack_Decl); | |
3712 | |
3713 -- Start of processing for Has_Body | |
3714 | |
3715 begin | |
3716 -- The body is available | |
3717 | |
3718 if Present (Corresponding_Body (Pack_Decl)) then | |
3719 return True; | |
3720 | |
3721 -- The body is required if the package spec contains a construct which | |
3722 -- requires a completion in a body. | |
3723 | |
3724 elsif Unit_Requires_Body (Pack_Id) then | |
3725 return True; | |
3726 | |
3727 -- The body may be optional | |
3728 | |
3729 else | |
3730 return Present (Find_Corresponding_Body (Pack_Id)); | |
3731 end if; | |
3732 end Has_Body; | |
3733 | |
3734 --------------------------- | |
3735 -- Has_Prior_Elaboration -- | |
3736 --------------------------- | |
3737 | |
3738 function Has_Prior_Elaboration | |
3739 (Unit_Id : Entity_Id; | |
3740 Context_OK : Boolean := False; | |
3741 Elab_Body_OK : Boolean := False; | |
3742 Same_Unit_OK : Boolean := False) return Boolean | |
3743 is | |
3744 Main_Id : constant Entity_Id := Cunit_Entity (Main_Unit); | |
3745 | |
3746 begin | |
3747 -- A preelaborated unit is always elaborated prior to the main unit | |
3748 | |
3749 if Is_Preelaborated_Unit (Unit_Id) then | |
3750 return True; | |
3751 | |
3752 -- An internal unit is always elaborated prior to a non-internal main | |
3753 -- unit. | |
3754 | |
3755 elsif In_Internal_Unit (Unit_Id) | |
3756 and then not In_Internal_Unit (Main_Id) | |
3757 then | |
3758 return True; | |
3759 | |
3760 -- A unit has prior elaboration if it appears within the context of the | |
3761 -- main unit. Consider this case only when requested by the caller. | |
3762 | |
3763 elsif Context_OK | |
3764 and then Elaboration_Context.Get (Unit_Id) /= No_Elaboration_Attributes | |
3765 then | |
3766 return True; | |
3767 | |
3768 -- A unit whose body is elaborated together with its spec has prior | |
3769 -- elaboration except with respect to itself. Consider this case only | |
3770 -- when requested by the caller. | |
3771 | |
3772 elsif Elab_Body_OK | |
3773 and then Has_Pragma_Elaborate_Body (Unit_Id) | |
3774 and then not Is_Same_Unit (Unit_Id, Main_Id) | |
3775 then | |
3776 return True; | |
3777 | |
3778 -- A unit has no prior elaboration with respect to itself, but does not | |
3779 -- require any means of ensuring its own elaboration either. Treat this | |
3780 -- case as valid prior elaboration only when requested by the caller. | |
3781 | |
3782 elsif Same_Unit_OK and then Is_Same_Unit (Unit_Id, Main_Id) then | |
3783 return True; | |
3784 end if; | |
3785 | |
3786 return False; | |
3787 end Has_Prior_Elaboration; | |
3788 | |
3789 -------------------------- | |
3790 -- In_External_Instance -- | |
3791 -------------------------- | |
3792 | |
3793 function In_External_Instance | |
3794 (N : Node_Id; | |
3795 Target_Decl : Node_Id) return Boolean | |
3796 is | |
3797 Dummy : Node_Id; | |
3798 Inst_Body : Node_Id; | |
3799 Inst_Decl : Node_Id; | |
3800 | |
3801 begin | |
3802 -- Performance note: parent traversal | |
3803 | |
3804 Inst_Decl := Find_Enclosing_Instance (Target_Decl); | |
3805 | |
3806 -- The target declaration appears within an instance spec. Visibility is | |
3807 -- ignored because internally generated primitives for private types may | |
3808 -- reside in the private declarations and still be invoked from outside. | |
3809 | |
3810 if Present (Inst_Decl) | |
3811 and then Nkind (Inst_Decl) = N_Package_Declaration | |
3812 then | |
3813 -- The scenario comes from the main unit and the instance does not | |
3814 | |
3815 if In_Extended_Main_Code_Unit (N) | |
3816 and then not In_Extended_Main_Code_Unit (Inst_Decl) | |
3817 then | |
3818 return True; | |
3819 | |
3820 -- Otherwise the scenario must not appear within the instance spec or | |
3821 -- body. | |
3822 | |
3823 else | |
3824 Extract_Instance_Attributes | |
3825 (Exp_Inst => Inst_Decl, | |
3826 Inst_Body => Inst_Body, | |
3827 Inst_Decl => Dummy); | |
3828 | |
3829 -- Performance note: parent traversal | |
3830 | |
3831 return not In_Subtree | |
3832 (N => N, | |
3833 Root1 => Inst_Decl, | |
3834 Root2 => Inst_Body); | |
3835 end if; | |
3836 end if; | |
3837 | |
3838 return False; | |
3839 end In_External_Instance; | |
3840 | |
3841 --------------------- | |
3842 -- In_Main_Context -- | |
3843 --------------------- | |
3844 | |
3845 function In_Main_Context (N : Node_Id) return Boolean is | |
3846 begin | |
3847 -- Scenarios outside the main unit are not considered because the ALI | |
3848 -- information supplied to binde is for the main unit only. | |
3849 | |
3850 if not In_Extended_Main_Code_Unit (N) then | |
3851 return False; | |
3852 | |
3853 -- Scenarios within internal units are not considered unless switch | |
3854 -- -gnatdE (elaboration checks on predefined units) is in effect. | |
3855 | |
3856 elsif not Debug_Flag_EE and then In_Internal_Unit (N) then | |
3857 return False; | |
3858 end if; | |
3859 | |
3860 return True; | |
3861 end In_Main_Context; | |
3862 | |
3863 --------------------- | |
3864 -- In_Same_Context -- | |
3865 --------------------- | |
3866 | |
3867 function In_Same_Context | |
3868 (N1 : Node_Id; | |
3869 N2 : Node_Id; | |
3870 Nested_OK : Boolean := False) return Boolean | |
3871 is | |
3872 function Find_Enclosing_Context (N : Node_Id) return Node_Id; | |
3873 -- Return the nearest enclosing non-library level or compilation unit | |
3874 -- node which which encapsulates arbitrary node N. Return Empty is no | |
3875 -- such context is available. | |
3876 | |
3877 function In_Nested_Context | |
3878 (Outer : Node_Id; | |
3879 Inner : Node_Id) return Boolean; | |
3880 -- Determine whether arbitrary node Outer encapsulates arbitrary node | |
3881 -- Inner. | |
3882 | |
3883 ---------------------------- | |
3884 -- Find_Enclosing_Context -- | |
3885 ---------------------------- | |
3886 | |
3887 function Find_Enclosing_Context (N : Node_Id) return Node_Id is | |
3888 Context : Node_Id; | |
3889 Par : Node_Id; | |
3890 | |
3891 begin | |
3892 Par := Parent (N); | |
3893 while Present (Par) loop | |
3894 | |
3895 -- A traversal from a subunit continues via the corresponding stub | |
3896 | |
3897 if Nkind (Par) = N_Subunit then | |
3898 Par := Corresponding_Stub (Par); | |
3899 | |
3900 -- Stop the traversal when the nearest enclosing non-library level | |
3901 -- encapsulator has been reached. | |
3902 | |
3903 elsif Is_Non_Library_Level_Encapsulator (Par) then | |
3904 Context := Parent (Par); | |
3905 | |
3906 -- The sole exception is when the encapsulator is the unit of | |
3907 -- compilation because this case requires special processing | |
3908 -- (see below). | |
3909 | |
3910 if Present (Context) | |
3911 and then Nkind (Context) = N_Compilation_Unit | |
3912 then | |
3913 null; | |
3914 | |
3915 else | |
3916 return Par; | |
3917 end if; | |
3918 | |
3919 -- Reaching a compilation unit node without hitting a non-library | |
3920 -- level encapsulator indicates that N is at the library level in | |
3921 -- which case the compilation unit is the context. | |
3922 | |
3923 elsif Nkind (Par) = N_Compilation_Unit then | |
3924 return Par; | |
3925 end if; | |
3926 | |
3927 Par := Parent (Par); | |
3928 end loop; | |
3929 | |
3930 return Empty; | |
3931 end Find_Enclosing_Context; | |
3932 | |
3933 ----------------------- | |
3934 -- In_Nested_Context -- | |
3935 ----------------------- | |
3936 | |
3937 function In_Nested_Context | |
3938 (Outer : Node_Id; | |
3939 Inner : Node_Id) return Boolean | |
3940 is | |
3941 Par : Node_Id; | |
3942 | |
3943 begin | |
3944 Par := Inner; | |
3945 while Present (Par) loop | |
3946 | |
3947 -- A traversal from a subunit continues via the corresponding stub | |
3948 | |
3949 if Nkind (Par) = N_Subunit then | |
3950 Par := Corresponding_Stub (Par); | |
3951 | |
3952 elsif Par = Outer then | |
3953 return True; | |
3954 end if; | |
3955 | |
3956 Par := Parent (Par); | |
3957 end loop; | |
3958 | |
3959 return False; | |
3960 end In_Nested_Context; | |
3961 | |
3962 -- Local variables | |
3963 | |
3964 Context_1 : constant Node_Id := Find_Enclosing_Context (N1); | |
3965 Context_2 : constant Node_Id := Find_Enclosing_Context (N2); | |
3966 | |
3967 -- Start of processing for In_Same_Context | |
3968 | |
3969 begin | |
3970 -- Both nodes appear within the same context | |
3971 | |
3972 if Context_1 = Context_2 then | |
3973 return True; | |
3974 | |
3975 -- Both nodes appear in compilation units. Determine whether one unit | |
3976 -- is the body of the other. | |
3977 | |
3978 elsif Nkind (Context_1) = N_Compilation_Unit | |
3979 and then Nkind (Context_2) = N_Compilation_Unit | |
3980 then | |
3981 return | |
3982 Is_Same_Unit | |
3983 (Unit_1 => Defining_Entity (Unit (Context_1)), | |
3984 Unit_2 => Defining_Entity (Unit (Context_2))); | |
3985 | |
3986 -- The context of N1 encloses the context of N2 | |
3987 | |
3988 elsif Nested_OK and then In_Nested_Context (Context_1, Context_2) then | |
3989 return True; | |
3990 end if; | |
3991 | |
3992 return False; | |
3993 end In_Same_Context; | |
3994 | |
3995 ---------------- | |
3996 -- Initialize -- | |
3997 ---------------- | |
3998 | |
3999 procedure Initialize is | |
4000 begin | |
4001 -- Set the soft link which enables Atree.Rewrite to update a top level | |
4002 -- scenario each time it is transformed into another node. | |
4003 | |
4004 Set_Rewriting_Proc (Update_Elaboration_Scenario'Access); | |
4005 end Initialize; | |
4006 | |
4007 --------------- | |
4008 -- Info_Call -- | |
4009 --------------- | |
4010 | |
4011 procedure Info_Call | |
4012 (Call : Node_Id; | |
4013 Target_Id : Entity_Id; | |
4014 Info_Msg : Boolean; | |
4015 In_SPARK : Boolean) | |
4016 is | |
4017 procedure Info_Accept_Alternative; | |
4018 pragma Inline (Info_Accept_Alternative); | |
4019 -- Output information concerning an accept alternative | |
4020 | |
4021 procedure Info_Simple_Call; | |
4022 pragma Inline (Info_Simple_Call); | |
4023 -- Output information concerning the call | |
4024 | |
4025 procedure Info_Type_Actions (Action : String); | |
4026 pragma Inline (Info_Type_Actions); | |
4027 -- Output information concerning action Action of a type | |
4028 | |
4029 procedure Info_Verification_Call | |
4030 (Pred : String; | |
4031 Id : Entity_Id; | |
4032 Id_Kind : String); | |
4033 pragma Inline (Info_Verification_Call); | |
4034 -- Output information concerning the verification of predicate Pred | |
4035 -- applied to related entity Id with kind Id_Kind. | |
4036 | |
4037 ----------------------------- | |
4038 -- Info_Accept_Alternative -- | |
4039 ----------------------------- | |
4040 | |
4041 procedure Info_Accept_Alternative is | |
4042 Entry_Id : constant Entity_Id := Receiving_Entry (Target_Id); | |
4043 | |
4044 begin | |
4045 pragma Assert (Present (Entry_Id)); | |
4046 | |
4047 Elab_Msg_NE | |
4048 (Msg => "accept for entry & during elaboration", | |
4049 N => Call, | |
4050 Id => Entry_Id, | |
4051 Info_Msg => Info_Msg, | |
4052 In_SPARK => In_SPARK); | |
4053 end Info_Accept_Alternative; | |
4054 | |
4055 ---------------------- | |
4056 -- Info_Simple_Call -- | |
4057 ---------------------- | |
4058 | |
4059 procedure Info_Simple_Call is | |
4060 begin | |
4061 Elab_Msg_NE | |
4062 (Msg => "call to & during elaboration", | |
4063 N => Call, | |
4064 Id => Target_Id, | |
4065 Info_Msg => Info_Msg, | |
4066 In_SPARK => In_SPARK); | |
4067 end Info_Simple_Call; | |
4068 | |
4069 ----------------------- | |
4070 -- Info_Type_Actions -- | |
4071 ----------------------- | |
4072 | |
4073 procedure Info_Type_Actions (Action : String) is | |
4074 Typ : constant Entity_Id := First_Formal_Type (Target_Id); | |
4075 | |
4076 begin | |
4077 pragma Assert (Present (Typ)); | |
4078 | |
4079 Elab_Msg_NE | |
4080 (Msg => Action & " actions for type & during elaboration", | |
4081 N => Call, | |
4082 Id => Typ, | |
4083 Info_Msg => Info_Msg, | |
4084 In_SPARK => In_SPARK); | |
4085 end Info_Type_Actions; | |
4086 | |
4087 ---------------------------- | |
4088 -- Info_Verification_Call -- | |
4089 ---------------------------- | |
4090 | |
4091 procedure Info_Verification_Call | |
4092 (Pred : String; | |
4093 Id : Entity_Id; | |
4094 Id_Kind : String) | |
4095 is | |
4096 begin | |
4097 pragma Assert (Present (Id)); | |
4098 | |
4099 Elab_Msg_NE | |
4100 (Msg => | |
4101 "verification of " & Pred & " of " & Id_Kind & " & during " | |
4102 & "elaboration", | |
4103 N => Call, | |
4104 Id => Id, | |
4105 Info_Msg => Info_Msg, | |
4106 In_SPARK => In_SPARK); | |
4107 end Info_Verification_Call; | |
4108 | |
4109 -- Start of processing for Info_Call | |
4110 | |
4111 begin | |
4112 -- Do not output anything for targets defined in internal units because | |
4113 -- this creates noise. | |
4114 | |
4115 if not In_Internal_Unit (Target_Id) then | |
4116 | |
4117 -- Accept alternative | |
4118 | |
4119 if Is_Accept_Alternative_Proc (Target_Id) then | |
4120 Info_Accept_Alternative; | |
4121 | |
4122 -- Adjustment | |
4123 | |
4124 elsif Is_TSS (Target_Id, TSS_Deep_Adjust) then | |
4125 Info_Type_Actions ("adjustment"); | |
4126 | |
4127 -- Default_Initial_Condition | |
4128 | |
4129 elsif Is_Default_Initial_Condition_Proc (Target_Id) then | |
4130 Info_Verification_Call | |
4131 (Pred => "Default_Initial_Condition", | |
4132 Id => First_Formal_Type (Target_Id), | |
4133 Id_Kind => "type"); | |
4134 | |
4135 -- Entries | |
4136 | |
4137 elsif Is_Protected_Entry (Target_Id) then | |
4138 Info_Simple_Call; | |
4139 | |
4140 -- Task entry calls are never processed because the entry being | |
4141 -- invoked does not have a corresponding "body", it has a select. | |
4142 | |
4143 elsif Is_Task_Entry (Target_Id) then | |
4144 null; | |
4145 | |
4146 -- Finalization | |
4147 | |
4148 elsif Is_TSS (Target_Id, TSS_Deep_Finalize) then | |
4149 Info_Type_Actions ("finalization"); | |
4150 | |
4151 -- Calls to _Finalizer procedures must not appear in the output | |
4152 -- because this creates confusing noise. | |
4153 | |
4154 elsif Is_Finalizer_Proc (Target_Id) then | |
4155 null; | |
4156 | |
4157 -- Initial_Condition | |
4158 | |
4159 elsif Is_Initial_Condition_Proc (Target_Id) then | |
4160 Info_Verification_Call | |
4161 (Pred => "Initial_Condition", | |
4162 Id => Find_Enclosing_Scope (Call), | |
4163 Id_Kind => "package"); | |
4164 | |
4165 -- Initialization | |
4166 | |
4167 elsif Is_Init_Proc (Target_Id) | |
4168 or else Is_TSS (Target_Id, TSS_Deep_Initialize) | |
4169 then | |
4170 Info_Type_Actions ("initialization"); | |
4171 | |
4172 -- Invariant | |
4173 | |
4174 elsif Is_Invariant_Proc (Target_Id) then | |
4175 Info_Verification_Call | |
4176 (Pred => "invariants", | |
4177 Id => First_Formal_Type (Target_Id), | |
4178 Id_Kind => "type"); | |
4179 | |
4180 -- Partial invariant calls must not appear in the output because this | |
4181 -- creates confusing noise. | |
4182 | |
4183 elsif Is_Partial_Invariant_Proc (Target_Id) then | |
4184 null; | |
4185 | |
4186 -- _Postconditions | |
4187 | |
4188 elsif Is_Postconditions_Proc (Target_Id) then | |
4189 Info_Verification_Call | |
4190 (Pred => "postconditions", | |
4191 Id => Find_Enclosing_Scope (Call), | |
4192 Id_Kind => "subprogram"); | |
4193 | |
4194 -- Subprograms must come last because some of the previous cases fall | |
4195 -- under this category. | |
4196 | |
4197 elsif Ekind (Target_Id) = E_Function then | |
4198 Info_Simple_Call; | |
4199 | |
4200 elsif Ekind (Target_Id) = E_Procedure then | |
4201 Info_Simple_Call; | |
4202 | |
4203 else | |
4204 pragma Assert (False); | |
4205 null; | |
4206 end if; | |
4207 end if; | |
4208 end Info_Call; | |
4209 | |
4210 ------------------------ | |
4211 -- Info_Instantiation -- | |
4212 ------------------------ | |
4213 | |
4214 procedure Info_Instantiation | |
4215 (Inst : Node_Id; | |
4216 Gen_Id : Entity_Id; | |
4217 Info_Msg : Boolean; | |
4218 In_SPARK : Boolean) | |
4219 is | |
4220 begin | |
4221 Elab_Msg_NE | |
4222 (Msg => "instantiation of & during elaboration", | |
4223 N => Inst, | |
4224 Id => Gen_Id, | |
4225 Info_Msg => Info_Msg, | |
4226 In_SPARK => In_SPARK); | |
4227 end Info_Instantiation; | |
4228 | |
4229 ------------------------ | |
4230 -- Info_Variable_Read -- | |
4231 ------------------------ | |
4232 | |
4233 procedure Info_Variable_Read | |
4234 (Ref : Node_Id; | |
4235 Var_Id : Entity_Id; | |
4236 Info_Msg : Boolean; | |
4237 In_SPARK : Boolean) | |
4238 is | |
4239 begin | |
4240 Elab_Msg_NE | |
4241 (Msg => "read of variable & during elaboration", | |
4242 N => Ref, | |
4243 Id => Var_Id, | |
4244 Info_Msg => Info_Msg, | |
4245 In_SPARK => In_SPARK); | |
4246 end Info_Variable_Read; | |
4247 | |
4248 -------------------- | |
4249 -- Insertion_Node -- | |
4250 -------------------- | |
4251 | |
4252 function Insertion_Node (N : Node_Id; Ins_Nod : Node_Id) return Node_Id is | |
4253 begin | |
4254 -- When the scenario denotes an instantiation, the proper insertion node | |
4255 -- is the instance spec. This ensures that the generic actuals will not | |
4256 -- be evaluated prior to a potential ABE. | |
4257 | |
4258 if Nkind (N) in N_Generic_Instantiation | |
4259 and then Present (Instance_Spec (N)) | |
4260 then | |
4261 return Instance_Spec (N); | |
4262 | |
4263 -- Otherwise the proper insertion node is the candidate insertion node | |
4264 | |
4265 else | |
4266 return Ins_Nod; | |
4267 end if; | |
4268 end Insertion_Node; | |
4269 | |
4270 ----------------------- | |
4271 -- Install_ABE_Check -- | |
4272 ----------------------- | |
4273 | |
4274 procedure Install_ABE_Check | |
4275 (N : Node_Id; | |
4276 Id : Entity_Id; | |
4277 Ins_Nod : Node_Id) | |
4278 is | |
4279 Check_Ins_Nod : constant Node_Id := Insertion_Node (N, Ins_Nod); | |
4280 -- Insert the check prior to this node | |
4281 | |
4282 Loc : constant Source_Ptr := Sloc (N); | |
4283 Spec_Id : constant Entity_Id := Unique_Entity (Id); | |
4284 Unit_Id : constant Entity_Id := Find_Top_Unit (Id); | |
4285 Scop_Id : Entity_Id; | |
4286 | |
4287 begin | |
4288 -- Nothing to do when compiling for GNATprove because raise statements | |
4289 -- are not supported. | |
4290 | |
4291 if GNATprove_Mode then | |
4292 return; | |
4293 | |
4294 -- Nothing to do when the compilation will not produce an executable | |
4295 | |
4296 elsif Serious_Errors_Detected > 0 then | |
4297 return; | |
4298 | |
4299 -- Nothing to do for a compilation unit because there is no executable | |
4300 -- environment at that level. | |
4301 | |
4302 elsif Nkind (Parent (Check_Ins_Nod)) = N_Compilation_Unit then | |
4303 return; | |
4304 | |
4305 -- Nothing to do when the unit is elaborated prior to the main unit. | |
4306 -- This check must also consider the following cases: | |
4307 | |
4308 -- * Id's unit appears in the context of the main unit | |
4309 | |
4310 -- * Id's unit is subject to pragma Elaborate_Body. An ABE check MUST | |
4311 -- NOT be generated because Id's unit is always elaborated prior to | |
4312 -- the main unit. | |
4313 | |
4314 -- * Id's unit is the main unit. An ABE check MUST be generated in this | |
4315 -- case because a conditional ABE may be raised depending on the flow | |
4316 -- of execution within the main unit (flag Same_Unit_OK is False). | |
4317 | |
4318 elsif Has_Prior_Elaboration | |
4319 (Unit_Id => Unit_Id, | |
4320 Context_OK => True, | |
4321 Elab_Body_OK => True) | |
4322 then | |
4323 return; | |
4324 end if; | |
4325 | |
4326 -- Prevent multiple scenarios from installing the same ABE check | |
4327 | |
4328 Set_Is_Elaboration_Checks_OK_Node (N, False); | |
4329 | |
4330 -- Install the nearest enclosing scope of the scenario as there must be | |
4331 -- something on the scope stack. | |
4332 | |
4333 -- Performance note: parent traversal | |
4334 | |
4335 Scop_Id := Find_Enclosing_Scope (Check_Ins_Nod); | |
4336 pragma Assert (Present (Scop_Id)); | |
4337 | |
4338 Push_Scope (Scop_Id); | |
4339 | |
4340 -- Generate: | |
4341 -- if not Spec_Id'Elaborated then | |
4342 -- raise Program_Error with "access before elaboration"; | |
4343 -- end if; | |
4344 | |
4345 Insert_Action (Check_Ins_Nod, | |
4346 Make_Raise_Program_Error (Loc, | |
4347 Condition => | |
4348 Make_Op_Not (Loc, | |
4349 Right_Opnd => | |
4350 Make_Attribute_Reference (Loc, | |
4351 Prefix => New_Occurrence_Of (Spec_Id, Loc), | |
4352 Attribute_Name => Name_Elaborated)), | |
4353 Reason => PE_Access_Before_Elaboration)); | |
4354 | |
4355 Pop_Scope; | |
4356 end Install_ABE_Check; | |
4357 | |
4358 ----------------------- | |
4359 -- Install_ABE_Check -- | |
4360 ----------------------- | |
4361 | |
4362 procedure Install_ABE_Check | |
4363 (N : Node_Id; | |
4364 Target_Id : Entity_Id; | |
4365 Target_Decl : Node_Id; | |
4366 Target_Body : Node_Id; | |
4367 Ins_Nod : Node_Id) | |
4368 is | |
4369 procedure Build_Elaboration_Entity; | |
4370 pragma Inline (Build_Elaboration_Entity); | |
4371 -- Create a new elaboration flag for Target_Id, insert it prior to | |
4372 -- Target_Decl, and set it after Body_Decl. | |
4373 | |
4374 ------------------------------ | |
4375 -- Build_Elaboration_Entity -- | |
4376 ------------------------------ | |
4377 | |
4378 procedure Build_Elaboration_Entity is | |
4379 Loc : constant Source_Ptr := Sloc (Target_Id); | |
4380 Flag_Id : Entity_Id; | |
4381 | |
4382 begin | |
4383 -- Create the declaration of the elaboration flag. The name carries a | |
4384 -- unique counter in case of name overloading. | |
4385 | |
4386 Flag_Id := | |
4387 Make_Defining_Identifier (Loc, | |
4388 Chars => New_External_Name (Chars (Target_Id), 'E', -1)); | |
4389 | |
4390 Set_Elaboration_Entity (Target_Id, Flag_Id); | |
4391 Set_Elaboration_Entity_Required (Target_Id); | |
4392 | |
4393 Push_Scope (Scope (Target_Id)); | |
4394 | |
4395 -- Generate: | |
4396 -- Enn : Short_Integer := 0; | |
4397 | |
4398 Insert_Action (Target_Decl, | |
4399 Make_Object_Declaration (Loc, | |
4400 Defining_Identifier => Flag_Id, | |
4401 Object_Definition => | |
4402 New_Occurrence_Of (Standard_Short_Integer, Loc), | |
4403 Expression => Make_Integer_Literal (Loc, Uint_0))); | |
4404 | |
4405 -- Generate: | |
4406 -- Enn := 1; | |
4407 | |
4408 Set_Elaboration_Flag (Target_Body, Target_Id); | |
4409 | |
4410 Pop_Scope; | |
4411 end Build_Elaboration_Entity; | |
4412 | |
4413 -- Local variables | |
4414 | |
4415 Target_Unit_Id : constant Entity_Id := Find_Top_Unit (Target_Id); | |
4416 | |
4417 -- Start for processing for Install_ABE_Check | |
4418 | |
4419 begin | |
4420 -- Nothing to do when compiling for GNATprove because raise statements | |
4421 -- are not supported. | |
4422 | |
4423 if GNATprove_Mode then | |
4424 return; | |
4425 | |
4426 -- Nothing to do when the compilation will not produce an executable | |
4427 | |
4428 elsif Serious_Errors_Detected > 0 then | |
4429 return; | |
4430 | |
4431 -- Nothing to do when the target is a protected subprogram because the | |
4432 -- check is associated with the protected body subprogram. | |
4433 | |
4434 elsif Is_Protected_Subp (Target_Id) then | |
4435 return; | |
4436 | |
4437 -- Nothing to do when the target is elaborated prior to the main unit. | |
4438 -- This check must also consider the following cases: | |
4439 | |
4440 -- * The unit of the target appears in the context of the main unit | |
4441 | |
4442 -- * The unit of the target is subject to pragma Elaborate_Body. An ABE | |
4443 -- check MUST NOT be generated because the unit is always elaborated | |
4444 -- prior to the main unit. | |
4445 | |
4446 -- * The unit of the target is the main unit. An ABE check MUST be added | |
4447 -- in this case because a conditional ABE may be raised depending on | |
4448 -- the flow of execution within the main unit (flag Same_Unit_OK is | |
4449 -- False). | |
4450 | |
4451 elsif Has_Prior_Elaboration | |
4452 (Unit_Id => Target_Unit_Id, | |
4453 Context_OK => True, | |
4454 Elab_Body_OK => True) | |
4455 then | |
4456 return; | |
4457 | |
4458 -- Create an elaboration flag for the target when it does not have one | |
4459 | |
4460 elsif No (Elaboration_Entity (Target_Id)) then | |
4461 Build_Elaboration_Entity; | |
4462 end if; | |
4463 | |
4464 Install_ABE_Check | |
4465 (N => N, | |
4466 Ins_Nod => Ins_Nod, | |
4467 Id => Target_Id); | |
4468 end Install_ABE_Check; | |
4469 | |
4470 ------------------------- | |
4471 -- Install_ABE_Failure -- | |
4472 ------------------------- | |
4473 | |
4474 procedure Install_ABE_Failure (N : Node_Id; Ins_Nod : Node_Id) is | |
4475 Fail_Ins_Nod : constant Node_Id := Insertion_Node (N, Ins_Nod); | |
4476 -- Insert the failure prior to this node | |
4477 | |
4478 Loc : constant Source_Ptr := Sloc (N); | |
4479 Scop_Id : Entity_Id; | |
4480 | |
4481 begin | |
4482 -- Nothing to do when compiling for GNATprove because raise statements | |
4483 -- are not supported. | |
4484 | |
4485 if GNATprove_Mode then | |
4486 return; | |
4487 | |
4488 -- Nothing to do when the compilation will not produce an executable | |
4489 | |
4490 elsif Serious_Errors_Detected > 0 then | |
4491 return; | |
4492 | |
4493 -- Do not install an ABE check for a compilation unit because there is | |
4494 -- no executable environment at that level. | |
4495 | |
4496 elsif Nkind (Parent (Fail_Ins_Nod)) = N_Compilation_Unit then | |
4497 return; | |
4498 end if; | |
4499 | |
4500 -- Prevent multiple scenarios from installing the same ABE failure | |
4501 | |
4502 Set_Is_Elaboration_Checks_OK_Node (N, False); | |
4503 | |
4504 -- Install the nearest enclosing scope of the scenario as there must be | |
4505 -- something on the scope stack. | |
4506 | |
4507 -- Performance note: parent traversal | |
4508 | |
4509 Scop_Id := Find_Enclosing_Scope (Fail_Ins_Nod); | |
4510 pragma Assert (Present (Scop_Id)); | |
4511 | |
4512 Push_Scope (Scop_Id); | |
4513 | |
4514 -- Generate: | |
4515 -- raise Program_Error with "access before elaboration"; | |
4516 | |
4517 Insert_Action (Fail_Ins_Nod, | |
4518 Make_Raise_Program_Error (Loc, | |
4519 Reason => PE_Access_Before_Elaboration)); | |
4520 | |
4521 Pop_Scope; | |
4522 end Install_ABE_Failure; | |
4523 | |
4524 -------------------------------- | |
4525 -- Is_Accept_Alternative_Proc -- | |
4526 -------------------------------- | |
4527 | |
4528 function Is_Accept_Alternative_Proc (Id : Entity_Id) return Boolean is | |
4529 begin | |
4530 -- To qualify, the entity must denote a procedure with a receiving entry | |
4531 | |
4532 return Ekind (Id) = E_Procedure and then Present (Receiving_Entry (Id)); | |
4533 end Is_Accept_Alternative_Proc; | |
4534 | |
4535 ------------------------ | |
4536 -- Is_Activation_Proc -- | |
4537 ------------------------ | |
4538 | |
4539 function Is_Activation_Proc (Id : Entity_Id) return Boolean is | |
4540 begin | |
4541 -- To qualify, the entity must denote one of the runtime procedures in | |
4542 -- charge of task activation. | |
4543 | |
4544 if Ekind (Id) = E_Procedure then | |
4545 if Restricted_Profile then | |
4546 return Is_RTE (Id, RE_Activate_Restricted_Tasks); | |
4547 else | |
4548 return Is_RTE (Id, RE_Activate_Tasks); | |
4549 end if; | |
4550 end if; | |
4551 | |
4552 return False; | |
4553 end Is_Activation_Proc; | |
4554 | |
4555 ---------------------------- | |
4556 -- Is_Ada_Semantic_Target -- | |
4557 ---------------------------- | |
4558 | |
4559 function Is_Ada_Semantic_Target (Id : Entity_Id) return Boolean is | |
4560 begin | |
4561 return | |
4562 Is_Activation_Proc (Id) | |
4563 or else Is_Controlled_Proc (Id, Name_Adjust) | |
4564 or else Is_Controlled_Proc (Id, Name_Finalize) | |
4565 or else Is_Controlled_Proc (Id, Name_Initialize) | |
4566 or else Is_Init_Proc (Id) | |
4567 or else Is_Invariant_Proc (Id) | |
4568 or else Is_Protected_Entry (Id) | |
4569 or else Is_Protected_Subp (Id) | |
4570 or else Is_Protected_Body_Subp (Id) | |
4571 or else Is_Task_Entry (Id); | |
4572 end Is_Ada_Semantic_Target; | |
4573 | |
4574 ---------------------------- | |
4575 -- Is_Bodiless_Subprogram -- | |
4576 ---------------------------- | |
4577 | |
4578 function Is_Bodiless_Subprogram (Subp_Id : Entity_Id) return Boolean is | |
4579 begin | |
4580 -- An abstract subprogram does not have a body | |
4581 | |
4582 if Ekind_In (Subp_Id, E_Function, | |
4583 E_Operator, | |
4584 E_Procedure) | |
4585 and then Is_Abstract_Subprogram (Subp_Id) | |
4586 then | |
4587 return True; | |
4588 | |
4589 -- A formal subprogram does not have a body | |
4590 | |
4591 elsif Is_Formal_Subprogram (Subp_Id) then | |
4592 return True; | |
4593 | |
4594 -- An imported subprogram may have a body, however it is not known at | |
4595 -- compile or bind time where the body resides and whether it will be | |
4596 -- elaborated on time. | |
4597 | |
4598 elsif Is_Imported (Subp_Id) then | |
4599 return True; | |
4600 end if; | |
4601 | |
4602 return False; | |
4603 end Is_Bodiless_Subprogram; | |
4604 | |
4605 -------------------------------- | |
4606 -- Is_Check_Emitting_Scenario -- | |
4607 -------------------------------- | |
4608 | |
4609 function Is_Check_Emitting_Scenario (N : Node_Id) return Boolean is | |
4610 begin | |
4611 return | |
4612 Nkind_In (N, N_Call_Marker, | |
4613 N_Function_Instantiation, | |
4614 N_Package_Instantiation, | |
4615 N_Procedure_Instantiation); | |
4616 end Is_Check_Emitting_Scenario; | |
4617 | |
4618 ------------------------ | |
4619 -- Is_Controlled_Proc -- | |
4620 ------------------------ | |
4621 | |
4622 function Is_Controlled_Proc | |
4623 (Subp_Id : Entity_Id; | |
4624 Subp_Nam : Name_Id) return Boolean | |
4625 is | |
4626 Formal_Id : Entity_Id; | |
4627 | |
4628 begin | |
4629 pragma Assert (Nam_In (Subp_Nam, Name_Adjust, | |
4630 Name_Finalize, | |
4631 Name_Initialize)); | |
4632 | |
4633 -- To qualify, the subprogram must denote a source procedure with name | |
4634 -- Adjust, Finalize, or Initialize where the sole formal is controlled. | |
4635 | |
4636 if Comes_From_Source (Subp_Id) | |
4637 and then Ekind (Subp_Id) = E_Procedure | |
4638 and then Chars (Subp_Id) = Subp_Nam | |
4639 then | |
4640 Formal_Id := First_Formal (Subp_Id); | |
4641 | |
4642 return | |
4643 Present (Formal_Id) | |
4644 and then Is_Controlled (Etype (Formal_Id)) | |
4645 and then No (Next_Formal (Formal_Id)); | |
4646 end if; | |
4647 | |
4648 return False; | |
4649 end Is_Controlled_Proc; | |
4650 | |
4651 --------------------------------------- | |
4652 -- Is_Default_Initial_Condition_Proc -- | |
4653 --------------------------------------- | |
4654 | |
4655 function Is_Default_Initial_Condition_Proc | |
4656 (Id : Entity_Id) return Boolean | |
4657 is | |
4658 begin | |
4659 -- To qualify, the entity must denote a Default_Initial_Condition | |
4660 -- procedure. | |
4661 | |
4662 return Ekind (Id) = E_Procedure and then Is_DIC_Procedure (Id); | |
4663 end Is_Default_Initial_Condition_Proc; | |
4664 | |
4665 ----------------------- | |
4666 -- Is_Finalizer_Proc -- | |
4667 ----------------------- | |
4668 | |
4669 function Is_Finalizer_Proc (Id : Entity_Id) return Boolean is | |
4670 begin | |
4671 -- To qualify, the entity must denote a _Finalizer procedure | |
4672 | |
4673 return Ekind (Id) = E_Procedure and then Chars (Id) = Name_uFinalizer; | |
4674 end Is_Finalizer_Proc; | |
4675 | |
4676 ----------------------- | |
4677 -- Is_Guaranteed_ABE -- | |
4678 ----------------------- | |
4679 | |
4680 function Is_Guaranteed_ABE | |
4681 (N : Node_Id; | |
4682 Target_Decl : Node_Id; | |
4683 Target_Body : Node_Id) return Boolean | |
4684 is | |
4685 begin | |
4686 -- Avoid cascaded errors if there were previous serious infractions. | |
4687 -- As a result the scenario will not be treated as a guaranteed ABE. | |
4688 -- This behaviour parallels that of the old ABE mechanism. | |
4689 | |
4690 if Serious_Errors_Detected > 0 then | |
4691 return False; | |
4692 | |
4693 -- The scenario and the target appear within the same context ignoring | |
4694 -- enclosing library levels. | |
4695 | |
4696 -- Performance note: parent traversal | |
4697 | |
4698 elsif In_Same_Context (N, Target_Decl) then | |
4699 | |
4700 -- The target body has already been encountered. The scenario results | |
4701 -- in a guaranteed ABE if it appears prior to the body. | |
4702 | |
4703 if Present (Target_Body) then | |
4704 return Earlier_In_Extended_Unit (N, Target_Body); | |
4705 | |
4706 -- Otherwise the body has not been encountered yet. The scenario is | |
4707 -- a guaranteed ABE since the body will appear later. It is assumed | |
4708 -- that the caller has already checked whether the scenario is ABE- | |
4709 -- safe as optional bodies are not considered here. | |
4710 | |
4711 else | |
4712 return True; | |
4713 end if; | |
4714 end if; | |
4715 | |
4716 return False; | |
4717 end Is_Guaranteed_ABE; | |
4718 | |
4719 ------------------------------- | |
4720 -- Is_Initial_Condition_Proc -- | |
4721 ------------------------------- | |
4722 | |
4723 function Is_Initial_Condition_Proc (Id : Entity_Id) return Boolean is | |
4724 begin | |
4725 -- To qualify, the entity must denote an Initial_Condition procedure | |
4726 | |
4727 return | |
4728 Ekind (Id) = E_Procedure and then Is_Initial_Condition_Procedure (Id); | |
4729 end Is_Initial_Condition_Proc; | |
4730 | |
4731 -------------------- | |
4732 -- Is_Initialized -- | |
4733 -------------------- | |
4734 | |
4735 function Is_Initialized (Obj_Decl : Node_Id) return Boolean is | |
4736 begin | |
4737 -- To qualify, the object declaration must have an expression | |
4738 | |
4739 return | |
4740 Present (Expression (Obj_Decl)) or else Has_Init_Expression (Obj_Decl); | |
4741 end Is_Initialized; | |
4742 | |
4743 ----------------------- | |
4744 -- Is_Invariant_Proc -- | |
4745 ----------------------- | |
4746 | |
4747 function Is_Invariant_Proc (Id : Entity_Id) return Boolean is | |
4748 begin | |
4749 -- To qualify, the entity must denote the "full" invariant procedure | |
4750 | |
4751 return Ekind (Id) = E_Procedure and then Is_Invariant_Procedure (Id); | |
4752 end Is_Invariant_Proc; | |
4753 | |
4754 --------------------------------------- | |
4755 -- Is_Non_Library_Level_Encapsulator -- | |
4756 --------------------------------------- | |
4757 | |
4758 function Is_Non_Library_Level_Encapsulator (N : Node_Id) return Boolean is | |
4759 begin | |
4760 case Nkind (N) is | |
4761 when N_Abstract_Subprogram_Declaration | |
4762 | N_Aspect_Specification | |
4763 | N_Component_Declaration | |
4764 | N_Entry_Body | |
4765 | N_Entry_Declaration | |
4766 | N_Expression_Function | |
4767 | N_Formal_Abstract_Subprogram_Declaration | |
4768 | N_Formal_Concrete_Subprogram_Declaration | |
4769 | N_Formal_Object_Declaration | |
4770 | N_Formal_Package_Declaration | |
4771 | N_Formal_Type_Declaration | |
4772 | N_Generic_Association | |
4773 | N_Implicit_Label_Declaration | |
4774 | N_Incomplete_Type_Declaration | |
4775 | N_Private_Extension_Declaration | |
4776 | N_Private_Type_Declaration | |
4777 | N_Protected_Body | |
4778 | N_Protected_Type_Declaration | |
4779 | N_Single_Protected_Declaration | |
4780 | N_Single_Task_Declaration | |
4781 | N_Subprogram_Body | |
4782 | N_Subprogram_Declaration | |
4783 | N_Task_Body | |
4784 | N_Task_Type_Declaration | |
4785 => | |
4786 return True; | |
4787 | |
4788 when others => | |
4789 return Is_Generic_Declaration_Or_Body (N); | |
4790 end case; | |
4791 end Is_Non_Library_Level_Encapsulator; | |
4792 | |
4793 ------------------------------- | |
4794 -- Is_Partial_Invariant_Proc -- | |
4795 ------------------------------- | |
4796 | |
4797 function Is_Partial_Invariant_Proc (Id : Entity_Id) return Boolean is | |
4798 begin | |
4799 -- To qualify, the entity must denote the "partial" invariant procedure | |
4800 | |
4801 return | |
4802 Ekind (Id) = E_Procedure and then Is_Partial_Invariant_Procedure (Id); | |
4803 end Is_Partial_Invariant_Proc; | |
4804 | |
4805 ---------------------------- | |
4806 -- Is_Postconditions_Proc -- | |
4807 ---------------------------- | |
4808 | |
4809 function Is_Postconditions_Proc (Id : Entity_Id) return Boolean is | |
4810 begin | |
4811 -- To qualify, the entity must denote a _Postconditions procedure | |
4812 | |
4813 return | |
4814 Ekind (Id) = E_Procedure and then Chars (Id) = Name_uPostconditions; | |
4815 end Is_Postconditions_Proc; | |
4816 | |
4817 --------------------------- | |
4818 -- Is_Preelaborated_Unit -- | |
4819 --------------------------- | |
4820 | |
4821 function Is_Preelaborated_Unit (Id : Entity_Id) return Boolean is | |
4822 begin | |
4823 return | |
4824 Is_Preelaborated (Id) | |
4825 or else Is_Pure (Id) | |
4826 or else Is_Remote_Call_Interface (Id) | |
4827 or else Is_Remote_Types (Id) | |
4828 or else Is_Shared_Passive (Id); | |
4829 end Is_Preelaborated_Unit; | |
4830 | |
4831 ------------------------ | |
4832 -- Is_Protected_Entry -- | |
4833 ------------------------ | |
4834 | |
4835 function Is_Protected_Entry (Id : Entity_Id) return Boolean is | |
4836 begin | |
4837 -- To qualify, the entity must denote an entry defined in a protected | |
4838 -- type. | |
4839 | |
4840 return | |
4841 Is_Entry (Id) | |
4842 and then Is_Protected_Type (Non_Private_View (Scope (Id))); | |
4843 end Is_Protected_Entry; | |
4844 | |
4845 ----------------------- | |
4846 -- Is_Protected_Subp -- | |
4847 ----------------------- | |
4848 | |
4849 function Is_Protected_Subp (Id : Entity_Id) return Boolean is | |
4850 begin | |
4851 -- To qualify, the entity must denote a subprogram defined within a | |
4852 -- protected type. | |
4853 | |
4854 return | |
4855 Ekind_In (Id, E_Function, E_Procedure) | |
4856 and then Is_Protected_Type (Non_Private_View (Scope (Id))); | |
4857 end Is_Protected_Subp; | |
4858 | |
4859 ---------------------------- | |
4860 -- Is_Protected_Body_Subp -- | |
4861 ---------------------------- | |
4862 | |
4863 function Is_Protected_Body_Subp (Id : Entity_Id) return Boolean is | |
4864 begin | |
4865 -- To qualify, the entity must denote a subprogram with attribute | |
4866 -- Protected_Subprogram set. | |
4867 | |
4868 return | |
4869 Ekind_In (Id, E_Function, E_Procedure) | |
4870 and then Present (Protected_Subprogram (Id)); | |
4871 end Is_Protected_Body_Subp; | |
4872 | |
4873 ------------------------ | |
4874 -- Is_Safe_Activation -- | |
4875 ------------------------ | |
4876 | |
4877 function Is_Safe_Activation | |
4878 (Call : Node_Id; | |
4879 Task_Decl : Node_Id) return Boolean | |
4880 is | |
4881 begin | |
4882 -- The activation of a task coming from an external instance cannot | |
4883 -- cause an ABE because the generic was already instantiated. Note | |
4884 -- that the instantiation itself may lead to an ABE. | |
4885 | |
4886 return | |
4887 In_External_Instance | |
4888 (N => Call, | |
4889 Target_Decl => Task_Decl); | |
4890 end Is_Safe_Activation; | |
4891 | |
4892 ------------------ | |
4893 -- Is_Safe_Call -- | |
4894 ------------------ | |
4895 | |
4896 function Is_Safe_Call | |
4897 (Call : Node_Id; | |
4898 Target_Attrs : Target_Attributes) return Boolean | |
4899 is | |
4900 begin | |
4901 -- The target is either an abstract subprogram, formal subprogram, or | |
4902 -- imported, in which case it does not have a body at compile or bind | |
4903 -- time. Assume that the call is ABE-safe. | |
4904 | |
4905 if Is_Bodiless_Subprogram (Target_Attrs.Spec_Id) then | |
4906 return True; | |
4907 | |
4908 -- The target is an instantiation of a generic subprogram. The call | |
4909 -- cannot cause an ABE because the generic was already instantiated. | |
4910 -- Note that the instantiation itself may lead to an ABE. | |
4911 | |
4912 elsif Is_Generic_Instance (Target_Attrs.Spec_Id) then | |
4913 return True; | |
4914 | |
4915 -- The invocation of a target coming from an external instance cannot | |
4916 -- cause an ABE because the generic was already instantiated. Note that | |
4917 -- the instantiation itself may lead to an ABE. | |
4918 | |
4919 elsif In_External_Instance | |
4920 (N => Call, | |
4921 Target_Decl => Target_Attrs.Spec_Decl) | |
4922 then | |
4923 return True; | |
4924 | |
4925 -- The target is a subprogram body without a previous declaration. The | |
4926 -- call cannot cause an ABE because the body has already been seen. | |
4927 | |
4928 elsif Nkind (Target_Attrs.Spec_Decl) = N_Subprogram_Body | |
4929 and then No (Corresponding_Spec (Target_Attrs.Spec_Decl)) | |
4930 then | |
4931 return True; | |
4932 | |
4933 -- The target is a subprogram body stub without a prior declaration. | |
4934 -- The call cannot cause an ABE because the proper body substitutes | |
4935 -- the stub. | |
4936 | |
4937 elsif Nkind (Target_Attrs.Spec_Decl) = N_Subprogram_Body_Stub | |
4938 and then No (Corresponding_Spec_Of_Stub (Target_Attrs.Spec_Decl)) | |
4939 then | |
4940 return True; | |
4941 | |
4942 -- Subprogram bodies which wrap attribute references used as actuals | |
4943 -- in instantiations are always ABE-safe. These bodies are artifacts | |
4944 -- of expansion. | |
4945 | |
4946 elsif Present (Target_Attrs.Body_Decl) | |
4947 and then Nkind (Target_Attrs.Body_Decl) = N_Subprogram_Body | |
4948 and then Was_Attribute_Reference (Target_Attrs.Body_Decl) | |
4949 then | |
4950 return True; | |
4951 end if; | |
4952 | |
4953 return False; | |
4954 end Is_Safe_Call; | |
4955 | |
4956 --------------------------- | |
4957 -- Is_Safe_Instantiation -- | |
4958 --------------------------- | |
4959 | |
4960 function Is_Safe_Instantiation | |
4961 (Inst : Node_Id; | |
4962 Gen_Attrs : Target_Attributes) return Boolean | |
4963 is | |
4964 begin | |
4965 -- The generic is an intrinsic subprogram in which case it does not | |
4966 -- have a body at compile or bind time. Assume that the instantiation | |
4967 -- is ABE-safe. | |
4968 | |
4969 if Is_Bodiless_Subprogram (Gen_Attrs.Spec_Id) then | |
4970 return True; | |
4971 | |
4972 -- The instantiation of an external nested generic cannot cause an ABE | |
4973 -- if the outer generic was already instantiated. Note that the instance | |
4974 -- of the outer generic may lead to an ABE. | |
4975 | |
4976 elsif In_External_Instance | |
4977 (N => Inst, | |
4978 Target_Decl => Gen_Attrs.Spec_Decl) | |
4979 then | |
4980 return True; | |
4981 | |
4982 -- The generic is a package. The instantiation cannot cause an ABE when | |
4983 -- the package has no body. | |
4984 | |
4985 elsif Ekind (Gen_Attrs.Spec_Id) = E_Generic_Package | |
4986 and then not Has_Body (Gen_Attrs.Spec_Decl) | |
4987 then | |
4988 return True; | |
4989 end if; | |
4990 | |
4991 return False; | |
4992 end Is_Safe_Instantiation; | |
4993 | |
4994 ------------------ | |
4995 -- Is_Same_Unit -- | |
4996 ------------------ | |
4997 | |
4998 function Is_Same_Unit | |
4999 (Unit_1 : Entity_Id; | |
5000 Unit_2 : Entity_Id) return Boolean | |
5001 is | |
5002 function Is_Subunit (Unit_Id : Entity_Id) return Boolean; | |
5003 pragma Inline (Is_Subunit); | |
5004 -- Determine whether unit Unit_Id is a subunit | |
5005 | |
5006 function Normalize_Unit (Unit_Id : Entity_Id) return Entity_Id; | |
5007 -- Strip a potential subunit chain ending with unit Unit_Id and return | |
5008 -- the corresponding spec. | |
5009 | |
5010 ---------------- | |
5011 -- Is_Subunit -- | |
5012 ---------------- | |
5013 | |
5014 function Is_Subunit (Unit_Id : Entity_Id) return Boolean is | |
5015 begin | |
5016 return Nkind (Parent (Unit_Declaration_Node (Unit_Id))) = N_Subunit; | |
5017 end Is_Subunit; | |
5018 | |
5019 -------------------- | |
5020 -- Normalize_Unit -- | |
5021 -------------------- | |
5022 | |
5023 function Normalize_Unit (Unit_Id : Entity_Id) return Entity_Id is | |
5024 Result : Entity_Id; | |
5025 | |
5026 begin | |
5027 -- Eliminate a potential chain of subunits to reach to proper body | |
5028 | |
5029 Result := Unit_Id; | |
5030 while Present (Result) | |
5031 and then Result /= Standard_Standard | |
5032 and then Is_Subunit (Result) | |
5033 loop | |
5034 Result := Scope (Result); | |
5035 end loop; | |
5036 | |
5037 -- Obtain the entity of the corresponding spec (if any) | |
5038 | |
5039 return Unique_Entity (Result); | |
5040 end Normalize_Unit; | |
5041 | |
5042 -- Start of processing for Is_Same_Unit | |
5043 | |
5044 begin | |
5045 return Normalize_Unit (Unit_1) = Normalize_Unit (Unit_2); | |
5046 end Is_Same_Unit; | |
5047 | |
5048 ----------------- | |
5049 -- Is_Scenario -- | |
5050 ----------------- | |
5051 | |
5052 function Is_Scenario (N : Node_Id) return Boolean is | |
5053 begin | |
5054 case Nkind (N) is | |
5055 when N_Assignment_Statement | |
5056 | N_Attribute_Reference | |
5057 | N_Call_Marker | |
5058 | N_Entry_Call_Statement | |
5059 | N_Expanded_Name | |
5060 | N_Function_Call | |
5061 | N_Function_Instantiation | |
5062 | N_Identifier | |
5063 | N_Package_Instantiation | |
5064 | N_Procedure_Call_Statement | |
5065 | N_Procedure_Instantiation | |
5066 | N_Requeue_Statement | |
5067 => | |
5068 return True; | |
5069 | |
5070 when others => | |
5071 return False; | |
5072 end case; | |
5073 end Is_Scenario; | |
5074 | |
5075 ------------------------------ | |
5076 -- Is_SPARK_Semantic_Target -- | |
5077 ------------------------------ | |
5078 | |
5079 function Is_SPARK_Semantic_Target (Id : Entity_Id) return Boolean is | |
5080 begin | |
5081 return | |
5082 Is_Default_Initial_Condition_Proc (Id) | |
5083 or else Is_Initial_Condition_Proc (Id); | |
5084 end Is_SPARK_Semantic_Target; | |
5085 | |
5086 ------------------------ | |
5087 -- Is_Suitable_Access -- | |
5088 ------------------------ | |
5089 | |
5090 function Is_Suitable_Access (N : Node_Id) return Boolean is | |
5091 Nam : Name_Id; | |
5092 Pref : Node_Id; | |
5093 Subp_Id : Entity_Id; | |
5094 | |
5095 begin | |
5096 -- This scenario is relevant only when the static model is in effect | |
5097 -- because it is graph-dependent and does not involve any run-time | |
5098 -- checks. Allowing it in the dynamic model would create confusing | |
5099 -- noise. | |
5100 | |
5101 if not Static_Elaboration_Checks then | |
5102 return False; | |
5103 | |
5104 -- Nothing to do when switch -gnatd.U (ignore 'Access) is in effect | |
5105 | |
5106 elsif Debug_Flag_Dot_UU then | |
5107 return False; | |
5108 | |
5109 -- Nothing to do when the scenario is not an attribute reference | |
5110 | |
5111 elsif Nkind (N) /= N_Attribute_Reference then | |
5112 return False; | |
5113 | |
5114 -- Nothing to do for internally-generated attributes because they are | |
5115 -- assumed to be ABE safe. | |
5116 | |
5117 elsif not Comes_From_Source (N) then | |
5118 return False; | |
5119 end if; | |
5120 | |
5121 Nam := Attribute_Name (N); | |
5122 Pref := Prefix (N); | |
5123 | |
5124 -- Sanitize the prefix of the attribute | |
5125 | |
5126 if not Is_Entity_Name (Pref) then | |
5127 return False; | |
5128 | |
5129 elsif No (Entity (Pref)) then | |
5130 return False; | |
5131 end if; | |
5132 | |
5133 Subp_Id := Entity (Pref); | |
5134 | |
5135 if not Is_Subprogram_Or_Entry (Subp_Id) then | |
5136 return False; | |
5137 end if; | |
5138 | |
5139 -- Traverse a possible chain of renamings to obtain the original entry | |
5140 -- or subprogram which the prefix may rename. | |
5141 | |
5142 Subp_Id := Get_Renamed_Entity (Subp_Id); | |
5143 | |
5144 -- To qualify, the attribute must meet the following prerequisites: | |
5145 | |
5146 return | |
5147 | |
5148 -- The prefix must denote a source entry, operator, or subprogram | |
5149 -- which is not imported. | |
5150 | |
5151 Comes_From_Source (Subp_Id) | |
5152 and then Is_Subprogram_Or_Entry (Subp_Id) | |
5153 and then not Is_Bodiless_Subprogram (Subp_Id) | |
5154 | |
5155 -- The attribute name must be one of the 'Access forms. Note that | |
5156 -- 'Unchecked_Access cannot apply to a subprogram. | |
5157 | |
5158 and then Nam_In (Nam, Name_Access, Name_Unrestricted_Access); | |
5159 end Is_Suitable_Access; | |
5160 | |
5161 ---------------------- | |
5162 -- Is_Suitable_Call -- | |
5163 ---------------------- | |
5164 | |
5165 function Is_Suitable_Call (N : Node_Id) return Boolean is | |
5166 begin | |
5167 -- Entry and subprogram calls are intentionally ignored because they | |
5168 -- may undergo expansion depending on the compilation mode, previous | |
5169 -- errors, generic context, etc. Call markers play the role of calls | |
5170 -- and provide a uniform foundation for ABE processing. | |
5171 | |
5172 return Nkind (N) = N_Call_Marker; | |
5173 end Is_Suitable_Call; | |
5174 | |
5175 ------------------------------- | |
5176 -- Is_Suitable_Instantiation -- | |
5177 ------------------------------- | |
5178 | |
5179 function Is_Suitable_Instantiation (N : Node_Id) return Boolean is | |
5180 Orig_N : constant Node_Id := Original_Node (N); | |
5181 -- Use the original node in case an instantiation library unit is | |
5182 -- rewritten as a package or subprogram. | |
5183 | |
5184 begin | |
5185 -- To qualify, the instantiation must come from source | |
5186 | |
5187 return | |
5188 Comes_From_Source (Orig_N) | |
5189 and then Nkind (Orig_N) in N_Generic_Instantiation; | |
5190 end Is_Suitable_Instantiation; | |
5191 | |
5192 -------------------------- | |
5193 -- Is_Suitable_Scenario -- | |
5194 -------------------------- | |
5195 | |
5196 function Is_Suitable_Scenario (N : Node_Id) return Boolean is | |
5197 begin | |
5198 return | |
5199 Is_Suitable_Access (N) | |
5200 or else Is_Suitable_Call (N) | |
5201 or else Is_Suitable_Instantiation (N) | |
5202 or else Is_Suitable_Variable_Assignment (N) | |
5203 or else Is_Suitable_Variable_Read (N); | |
5204 end Is_Suitable_Scenario; | |
5205 | |
5206 ------------------------------------- | |
5207 -- Is_Suitable_Variable_Assignment -- | |
5208 ------------------------------------- | |
5209 | |
5210 function Is_Suitable_Variable_Assignment (N : Node_Id) return Boolean is | |
5211 N_Unit : Node_Id; | |
5212 N_Unit_Id : Entity_Id; | |
5213 Nam : Node_Id; | |
5214 Var_Decl : Node_Id; | |
5215 Var_Id : Entity_Id; | |
5216 Var_Unit : Node_Id; | |
5217 Var_Unit_Id : Entity_Id; | |
5218 | |
5219 begin | |
5220 -- This scenario is relevant only when the static model is in effect | |
5221 -- because it is graph-dependent and does not involve any run-time | |
5222 -- checks. Allowing it in the dynamic model would create confusing | |
5223 -- noise. | |
5224 | |
5225 if not Static_Elaboration_Checks then | |
5226 return False; | |
5227 | |
5228 -- Nothing to do when the scenario is not an assignment | |
5229 | |
5230 elsif Nkind (N) /= N_Assignment_Statement then | |
5231 return False; | |
5232 | |
5233 -- Nothing to do for internally-generated assignments because they are | |
5234 -- assumed to be ABE safe. | |
5235 | |
5236 elsif not Comes_From_Source (N) then | |
5237 return False; | |
5238 | |
5239 -- Assignments are ignored in GNAT mode on the assumption that they are | |
5240 -- ABE-safe. This behaviour parallels that of the old ABE mechanism. | |
5241 | |
5242 elsif GNAT_Mode then | |
5243 return False; | |
5244 end if; | |
5245 | |
5246 Nam := Extract_Assignment_Name (N); | |
5247 | |
5248 -- Sanitize the left hand side of the assignment | |
5249 | |
5250 if not Is_Entity_Name (Nam) then | |
5251 return False; | |
5252 | |
5253 elsif No (Entity (Nam)) then | |
5254 return False; | |
5255 end if; | |
5256 | |
5257 Var_Id := Entity (Nam); | |
5258 | |
5259 -- Sanitize the variable | |
5260 | |
5261 if Var_Id = Any_Id then | |
5262 return False; | |
5263 | |
5264 elsif Ekind (Var_Id) /= E_Variable then | |
5265 return False; | |
5266 end if; | |
5267 | |
5268 Var_Decl := Declaration_Node (Var_Id); | |
5269 | |
5270 if Nkind (Var_Decl) /= N_Object_Declaration then | |
5271 return False; | |
5272 end if; | |
5273 | |
5274 N_Unit_Id := Find_Top_Unit (N); | |
5275 N_Unit := Unit_Declaration_Node (N_Unit_Id); | |
5276 | |
5277 Var_Unit_Id := Find_Top_Unit (Var_Decl); | |
5278 Var_Unit := Unit_Declaration_Node (Var_Unit_Id); | |
5279 | |
5280 -- To qualify, the assignment must meet the following prerequisites: | |
5281 | |
5282 return | |
5283 Comes_From_Source (Var_Id) | |
5284 | |
5285 -- The variable must be declared in the spec of compilation unit U | |
5286 | |
5287 and then Nkind (Var_Unit) = N_Package_Declaration | |
5288 | |
5289 -- Performance note: parent traversal | |
5290 | |
5291 and then Find_Enclosing_Level (Var_Decl) = Package_Spec | |
5292 | |
5293 -- The assignment must occur in the body of compilation unit U | |
5294 | |
5295 and then Nkind (N_Unit) = N_Package_Body | |
5296 and then Present (Corresponding_Body (Var_Unit)) | |
5297 and then Corresponding_Body (Var_Unit) = N_Unit_Id; | |
5298 end Is_Suitable_Variable_Assignment; | |
5299 | |
5300 ------------------------------- | |
5301 -- Is_Suitable_Variable_Read -- | |
5302 ------------------------------- | |
5303 | |
5304 function Is_Suitable_Variable_Read (N : Node_Id) return Boolean is | |
5305 function In_Pragma (Nod : Node_Id) return Boolean; | |
5306 -- Determine whether arbitrary node Nod appears within a pragma | |
5307 | |
5308 function Is_Variable_Read (Ref : Node_Id) return Boolean; | |
5309 -- Determine whether variable reference Ref constitutes a read | |
5310 | |
5311 --------------- | |
5312 -- In_Pragma -- | |
5313 --------------- | |
5314 | |
5315 function In_Pragma (Nod : Node_Id) return Boolean is | |
5316 Par : Node_Id; | |
5317 | |
5318 begin | |
5319 Par := Nod; | |
5320 while Present (Par) loop | |
5321 if Nkind (Par) = N_Pragma then | |
5322 return True; | |
5323 | |
5324 -- Prevent the search from going too far | |
5325 | |
5326 elsif Is_Body_Or_Package_Declaration (Par) then | |
5327 exit; | |
5328 end if; | |
5329 | |
5330 Par := Parent (Par); | |
5331 end loop; | |
5332 | |
5333 return False; | |
5334 end In_Pragma; | |
5335 | |
5336 ---------------------- | |
5337 -- Is_Variable_Read -- | |
5338 ---------------------- | |
5339 | |
5340 function Is_Variable_Read (Ref : Node_Id) return Boolean is | |
5341 function Is_Out_Actual (Call : Node_Id) return Boolean; | |
5342 -- Determine whether the corresponding formal of actual Ref which | |
5343 -- appears in call Call has mode OUT. | |
5344 | |
5345 ------------------- | |
5346 -- Is_Out_Actual -- | |
5347 ------------------- | |
5348 | |
5349 function Is_Out_Actual (Call : Node_Id) return Boolean is | |
5350 Actual : Node_Id; | |
5351 Call_Attrs : Call_Attributes; | |
5352 Formal : Entity_Id; | |
5353 Target_Id : Entity_Id; | |
5354 | |
5355 begin | |
5356 Extract_Call_Attributes | |
5357 (Call => Call, | |
5358 Target_Id => Target_Id, | |
5359 Attrs => Call_Attrs); | |
5360 | |
5361 -- Inspect the actual and formal parameters, trying to find the | |
5362 -- corresponding formal for Ref. | |
5363 | |
5364 Actual := First_Actual (Call); | |
5365 Formal := First_Formal (Target_Id); | |
5366 while Present (Actual) and then Present (Formal) loop | |
5367 if Actual = Ref then | |
5368 return Ekind (Formal) = E_Out_Parameter; | |
5369 end if; | |
5370 | |
5371 Next_Actual (Actual); | |
5372 Next_Formal (Formal); | |
5373 end loop; | |
5374 | |
5375 return False; | |
5376 end Is_Out_Actual; | |
5377 | |
5378 -- Local variables | |
5379 | |
5380 Context : constant Node_Id := Parent (Ref); | |
5381 | |
5382 -- Start of processing for Is_Variable_Read | |
5383 | |
5384 begin | |
5385 -- The majority of variable references are reads, and they can appear | |
5386 -- in a great number of contexts. To determine whether a reference is | |
5387 -- a read, it is more practical to find out whether it is a write. | |
5388 | |
5389 -- A reference is a write when it appears immediately on the left- | |
5390 -- hand side of an assignment. | |
5391 | |
5392 if Nkind (Context) = N_Assignment_Statement | |
5393 and then Name (Context) = Ref | |
5394 then | |
5395 return False; | |
5396 | |
5397 -- A reference is a write when it acts as an actual in a subprogram | |
5398 -- call and the corresponding formal has mode OUT. | |
5399 | |
5400 elsif Nkind_In (Context, N_Function_Call, | |
5401 N_Procedure_Call_Statement) | |
5402 and then Is_Out_Actual (Context) | |
5403 then | |
5404 return False; | |
5405 end if; | |
5406 | |
5407 -- Any other reference is a read | |
5408 | |
5409 return True; | |
5410 end Is_Variable_Read; | |
5411 | |
5412 -- Local variables | |
5413 | |
5414 Prag : Node_Id; | |
5415 Var_Id : Entity_Id; | |
5416 | |
5417 -- Start of processing for Is_Suitable_Variable_Read | |
5418 | |
5419 begin | |
5420 -- This scenario is relevant only when the static model is in effect | |
5421 -- because it is graph-dependent and does not involve any run-time | |
5422 -- checks. Allowing it in the dynamic model would create confusing | |
5423 -- noise. | |
5424 | |
5425 if not Static_Elaboration_Checks then | |
5426 return False; | |
5427 | |
5428 -- Attributes and operator sumbols are not considered to be suitable | |
5429 -- references even though they are part of predicate Is_Entity_Name. | |
5430 | |
5431 elsif not Nkind_In (N, N_Expanded_Name, N_Identifier) then | |
5432 return False; | |
5433 | |
5434 -- Nothing to do for internally-generated references because they are | |
5435 -- assumed to be ABE safe. | |
5436 | |
5437 elsif not Comes_From_Source (N) then | |
5438 return False; | |
5439 end if; | |
5440 | |
5441 -- Sanitize the reference | |
5442 | |
5443 Var_Id := Entity (N); | |
5444 | |
5445 if No (Var_Id) then | |
5446 return False; | |
5447 | |
5448 elsif Var_Id = Any_Id then | |
5449 return False; | |
5450 | |
5451 elsif Ekind (Var_Id) /= E_Variable then | |
5452 return False; | |
5453 end if; | |
5454 | |
5455 Prag := SPARK_Pragma (Var_Id); | |
5456 | |
5457 -- To qualify, the reference must meet the following prerequisites: | |
5458 | |
5459 return | |
5460 Comes_From_Source (Var_Id) | |
5461 | |
5462 -- Both the variable and the reference must appear in SPARK_Mode On | |
5463 -- regions because this scenario falls under the SPARK rules. | |
5464 | |
5465 and then Present (Prag) | |
5466 and then Get_SPARK_Mode_From_Annotation (Prag) = On | |
5467 and then Is_SPARK_Mode_On_Node (N) | |
5468 | |
5469 -- The reference must denote a variable read | |
5470 | |
5471 and then Is_Variable_Read (N) | |
5472 | |
5473 -- The reference must not be considered when it appears in a pragma. | |
5474 -- If the pragma has run-time semantics, then the reference will be | |
5475 -- reconsidered once the pragma is expanded. | |
5476 | |
5477 -- Performance note: parent traversal | |
5478 | |
5479 and then not In_Pragma (N); | |
5480 end Is_Suitable_Variable_Read; | |
5481 | |
5482 ------------------- | |
5483 -- Is_Task_Entry -- | |
5484 ------------------- | |
5485 | |
5486 function Is_Task_Entry (Id : Entity_Id) return Boolean is | |
5487 begin | |
5488 -- To qualify, the entity must denote an entry defined in a task type | |
5489 | |
5490 return | |
5491 Is_Entry (Id) and then Is_Task_Type (Non_Private_View (Scope (Id))); | |
5492 end Is_Task_Entry; | |
5493 | |
5494 ------------------------ | |
5495 -- Is_Up_Level_Target -- | |
5496 ------------------------ | |
5497 | |
5498 function Is_Up_Level_Target (Target_Decl : Node_Id) return Boolean is | |
5499 Root : constant Node_Id := Root_Scenario; | |
5500 | |
5501 begin | |
5502 -- The root appears within the declaratons of a block statement, entry | |
5503 -- body, subprogram body, or task body ignoring enclosing packages. The | |
5504 -- root is always within the main unit. An up level target is a notion | |
5505 -- applicable only to the static model because scenarios are reached by | |
5506 -- means of graph traversal started from a fixed declarative or library | |
5507 -- level. | |
5508 | |
5509 -- Performance note: parent traversal | |
5510 | |
5511 if Static_Elaboration_Checks | |
5512 and then Find_Enclosing_Level (Root) = Declaration_Level | |
5513 then | |
5514 -- The target is within the main unit. It acts as an up level target | |
5515 -- when it appears within a context which encloses the root. | |
5516 | |
5517 -- package body Main_Unit is | |
5518 -- function Func ...; -- target | |
5519 | |
5520 -- procedure Proc is | |
5521 -- X : ... := Func; -- root scenario | |
5522 | |
5523 if In_Extended_Main_Code_Unit (Target_Decl) then | |
5524 | |
5525 -- Performance note: parent traversal | |
5526 | |
5527 return not In_Same_Context (Root, Target_Decl, Nested_OK => True); | |
5528 | |
5529 -- Otherwise the target is external to the main unit which makes it | |
5530 -- an up level target. | |
5531 | |
5532 else | |
5533 return True; | |
5534 end if; | |
5535 end if; | |
5536 | |
5537 return False; | |
5538 end Is_Up_Level_Target; | |
5539 | |
5540 ------------------------------- | |
5541 -- Kill_Elaboration_Scenario -- | |
5542 ------------------------------- | |
5543 | |
5544 procedure Kill_Elaboration_Scenario (N : Node_Id) is | |
5545 begin | |
5546 -- Eliminate the scenario by suppressing the generation of conditional | |
5547 -- ABE checks or guaranteed ABE failures. Note that other diagnostics | |
5548 -- must be carried out ignoring the fact that the scenario is within | |
5549 -- dead code. | |
5550 | |
5551 if Is_Scenario (N) then | |
5552 Set_Is_Elaboration_Checks_OK_Node (N, False); | |
5553 end if; | |
5554 end Kill_Elaboration_Scenario; | |
5555 | |
5556 ---------------------------------- | |
5557 -- Meet_Elaboration_Requirement -- | |
5558 ---------------------------------- | |
5559 | |
5560 procedure Meet_Elaboration_Requirement | |
5561 (N : Node_Id; | |
5562 Target_Id : Entity_Id; | |
5563 Req_Nam : Name_Id) | |
5564 is | |
5565 Main_Id : constant Entity_Id := Cunit_Entity (Main_Unit); | |
5566 Unit_Id : constant Entity_Id := Find_Top_Unit (Target_Id); | |
5567 | |
5568 function Find_Preelaboration_Pragma | |
5569 (Prag_Nam : Name_Id) return Node_Id; | |
5570 pragma Inline (Find_Preelaboration_Pragma); | |
5571 -- Traverse the visible declarations of unit Unit_Id and locate a source | |
5572 -- preelaboration-related pragma with name Prag_Nam. | |
5573 | |
5574 procedure Info_Requirement_Met (Prag : Node_Id); | |
5575 pragma Inline (Info_Requirement_Met); | |
5576 -- Output information concerning pragma Prag which meets requirement | |
5577 -- Req_Nam. | |
5578 | |
5579 procedure Info_Scenario; | |
5580 pragma Inline (Info_Scenario); | |
5581 -- Output information concerning scenario N | |
5582 | |
5583 -------------------------------- | |
5584 -- Find_Preelaboration_Pragma -- | |
5585 -------------------------------- | |
5586 | |
5587 function Find_Preelaboration_Pragma | |
5588 (Prag_Nam : Name_Id) return Node_Id | |
5589 is | |
5590 Spec : constant Node_Id := Parent (Unit_Id); | |
5591 Decl : Node_Id; | |
5592 | |
5593 begin | |
5594 -- A preelaboration-related pragma comes from source and appears at | |
5595 -- the top of the visible declarations of a package. | |
5596 | |
5597 if Nkind (Spec) = N_Package_Specification then | |
5598 Decl := First (Visible_Declarations (Spec)); | |
5599 while Present (Decl) loop | |
5600 if Comes_From_Source (Decl) then | |
5601 if Nkind (Decl) = N_Pragma | |
5602 and then Pragma_Name (Decl) = Prag_Nam | |
5603 then | |
5604 return Decl; | |
5605 | |
5606 -- Otherwise the construct terminates the region where the | |
5607 -- preelabortion-related pragma may appear. | |
5608 | |
5609 else | |
5610 exit; | |
5611 end if; | |
5612 end if; | |
5613 | |
5614 Next (Decl); | |
5615 end loop; | |
5616 end if; | |
5617 | |
5618 return Empty; | |
5619 end Find_Preelaboration_Pragma; | |
5620 | |
5621 -------------------------- | |
5622 -- Info_Requirement_Met -- | |
5623 -------------------------- | |
5624 | |
5625 procedure Info_Requirement_Met (Prag : Node_Id) is | |
5626 begin | |
5627 pragma Assert (Present (Prag)); | |
5628 | |
5629 Error_Msg_Name_1 := Req_Nam; | |
5630 Error_Msg_Sloc := Sloc (Prag); | |
5631 Error_Msg_NE | |
5632 ("\\% requirement for unit & met by pragma #", N, Unit_Id); | |
5633 end Info_Requirement_Met; | |
5634 | |
5635 ------------------- | |
5636 -- Info_Scenario -- | |
5637 ------------------- | |
5638 | |
5639 procedure Info_Scenario is | |
5640 begin | |
5641 if Is_Suitable_Call (N) then | |
5642 Info_Call | |
5643 (Call => N, | |
5644 Target_Id => Target_Id, | |
5645 Info_Msg => False, | |
5646 In_SPARK => True); | |
5647 | |
5648 elsif Is_Suitable_Instantiation (N) then | |
5649 Info_Instantiation | |
5650 (Inst => N, | |
5651 Gen_Id => Target_Id, | |
5652 Info_Msg => False, | |
5653 In_SPARK => True); | |
5654 | |
5655 elsif Is_Suitable_Variable_Read (N) then | |
5656 Info_Variable_Read | |
5657 (Ref => N, | |
5658 Var_Id => Target_Id, | |
5659 Info_Msg => False, | |
5660 In_SPARK => True); | |
5661 | |
5662 -- No other scenario may impose a requirement on the context of the | |
5663 -- main unit. | |
5664 | |
5665 else | |
5666 pragma Assert (False); | |
5667 null; | |
5668 end if; | |
5669 end Info_Scenario; | |
5670 | |
5671 -- Local variables | |
5672 | |
5673 Elab_Attrs : Elaboration_Attributes; | |
5674 Elab_Nam : Name_Id; | |
5675 Req_Met : Boolean; | |
5676 | |
5677 -- Start of processing for Meet_Elaboration_Requirement | |
5678 | |
5679 begin | |
5680 pragma Assert (Nam_In (Req_Nam, Name_Elaborate, Name_Elaborate_All)); | |
5681 | |
5682 -- Assume that the requirement has not been met | |
5683 | |
5684 Req_Met := False; | |
5685 | |
5686 -- Elaboration requirements are verified only when the static model is | |
5687 -- in effect because this diagnostic is graph-dependent. | |
5688 | |
5689 if not Static_Elaboration_Checks then | |
5690 return; | |
5691 | |
5692 -- If the target is within the main unit, either at the source level or | |
5693 -- through an instantiation, then there is no real requirement to meet | |
5694 -- because the main unit cannot force its own elaboration by means of an | |
5695 -- Elaborate[_All] pragma. Treat this case as valid coverage. | |
5696 | |
5697 elsif In_Extended_Main_Code_Unit (Target_Id) then | |
5698 Req_Met := True; | |
5699 | |
5700 -- Otherwise the target resides in an external unit | |
5701 | |
5702 -- The requirement is met when the target comes from an internal unit | |
5703 -- because such a unit is elaborated prior to a non-internal unit. | |
5704 | |
5705 elsif In_Internal_Unit (Unit_Id) | |
5706 and then not In_Internal_Unit (Main_Id) | |
5707 then | |
5708 Req_Met := True; | |
5709 | |
5710 -- The requirement is met when the target comes from a preelaborated | |
5711 -- unit. This portion must parallel predicate Is_Preelaborated_Unit. | |
5712 | |
5713 elsif Is_Preelaborated_Unit (Unit_Id) then | |
5714 Req_Met := True; | |
5715 | |
5716 -- Output extra information when switch -gnatel (info messages on | |
5717 -- implicit Elaborate[_All] pragmas. | |
5718 | |
5719 if Elab_Info_Messages then | |
5720 if Is_Preelaborated (Unit_Id) then | |
5721 Elab_Nam := Name_Preelaborate; | |
5722 | |
5723 elsif Is_Pure (Unit_Id) then | |
5724 Elab_Nam := Name_Pure; | |
5725 | |
5726 elsif Is_Remote_Call_Interface (Unit_Id) then | |
5727 Elab_Nam := Name_Remote_Call_Interface; | |
5728 | |
5729 elsif Is_Remote_Types (Unit_Id) then | |
5730 Elab_Nam := Name_Remote_Types; | |
5731 | |
5732 else | |
5733 pragma Assert (Is_Shared_Passive (Unit_Id)); | |
5734 Elab_Nam := Name_Shared_Passive; | |
5735 end if; | |
5736 | |
5737 Info_Requirement_Met (Find_Preelaboration_Pragma (Elab_Nam)); | |
5738 end if; | |
5739 | |
5740 -- Determine whether the context of the main unit has a pragma strong | |
5741 -- enough to meet the requirement. | |
5742 | |
5743 else | |
5744 Elab_Attrs := Elaboration_Context.Get (Unit_Id); | |
5745 | |
5746 -- The pragma must be either Elaborate_All or be as strong as the | |
5747 -- requirement. | |
5748 | |
5749 if Present (Elab_Attrs.Source_Pragma) | |
5750 and then Nam_In (Pragma_Name (Elab_Attrs.Source_Pragma), | |
5751 Name_Elaborate_All, | |
5752 Req_Nam) | |
5753 then | |
5754 Req_Met := True; | |
5755 | |
5756 -- Output extra information when switch -gnatel (info messages on | |
5757 -- implicit Elaborate[_All] pragmas. | |
5758 | |
5759 if Elab_Info_Messages then | |
5760 Info_Requirement_Met (Elab_Attrs.Source_Pragma); | |
5761 end if; | |
5762 end if; | |
5763 end if; | |
5764 | |
5765 -- The requirement was not met by the context of the main unit, issue an | |
5766 -- error. | |
5767 | |
5768 if not Req_Met then | |
5769 Info_Scenario; | |
5770 | |
5771 Error_Msg_Name_1 := Req_Nam; | |
5772 Error_Msg_Node_2 := Unit_Id; | |
5773 Error_Msg_NE ("\\unit & requires pragma % for &", N, Main_Id); | |
5774 | |
5775 Output_Active_Scenarios (N); | |
5776 end if; | |
5777 end Meet_Elaboration_Requirement; | |
5778 | |
5779 ---------------------- | |
5780 -- Non_Private_View -- | |
5781 ---------------------- | |
5782 | |
5783 function Non_Private_View (Typ : Entity_Id) return Entity_Id is | |
5784 Result : Entity_Id; | |
5785 | |
5786 begin | |
5787 Result := Typ; | |
5788 | |
5789 if Is_Private_Type (Result) and then Present (Full_View (Result)) then | |
5790 Result := Full_View (Result); | |
5791 end if; | |
5792 | |
5793 return Result; | |
5794 end Non_Private_View; | |
5795 | |
5796 ----------------------------- | |
5797 -- Output_Active_Scenarios -- | |
5798 ----------------------------- | |
5799 | |
5800 procedure Output_Active_Scenarios (Error_Nod : Node_Id) is | |
5801 procedure Output_Access (N : Node_Id); | |
5802 -- Emit a specific diagnostic message for 'Access denote by N | |
5803 | |
5804 procedure Output_Activation_Call (N : Node_Id); | |
5805 -- Emit a specific diagnostic message for task activation N | |
5806 | |
5807 procedure Output_Call (N : Node_Id; Target_Id : Entity_Id); | |
5808 -- Emit a specific diagnostic message for call N which invokes target | |
5809 -- Target_Id. | |
5810 | |
5811 procedure Output_Header; | |
5812 -- Emit a specific diagnostic message for the unit of the root scenario | |
5813 | |
5814 procedure Output_Instantiation (N : Node_Id); | |
5815 -- Emit a specific diagnostic message for instantiation N | |
5816 | |
5817 procedure Output_Variable_Assignment (N : Node_Id); | |
5818 -- Emit a specific diagnostic message for assignment statement N | |
5819 | |
5820 procedure Output_Variable_Read (N : Node_Id); | |
5821 -- Emit a specific diagnostic message for reference N which reads a | |
5822 -- variable. | |
5823 | |
5824 ------------------- | |
5825 -- Output_Access -- | |
5826 ------------------- | |
5827 | |
5828 procedure Output_Access (N : Node_Id) is | |
5829 Subp_Id : constant Entity_Id := Entity (Prefix (N)); | |
5830 | |
5831 begin | |
5832 Error_Msg_Name_1 := Attribute_Name (N); | |
5833 Error_Msg_Sloc := Sloc (N); | |
5834 Error_Msg_NE ("\\ % of & taken #", Error_Nod, Subp_Id); | |
5835 end Output_Access; | |
5836 | |
5837 ---------------------------- | |
5838 -- Output_Activation_Call -- | |
5839 ---------------------------- | |
5840 | |
5841 procedure Output_Activation_Call (N : Node_Id) is | |
5842 function Find_Activator (Call : Node_Id) return Entity_Id; | |
5843 -- Find the nearest enclosing construct which houses call Call | |
5844 | |
5845 -------------------- | |
5846 -- Find_Activator -- | |
5847 -------------------- | |
5848 | |
5849 function Find_Activator (Call : Node_Id) return Entity_Id is | |
5850 Par : Node_Id; | |
5851 | |
5852 begin | |
5853 -- Climb the parent chain looking for a package [body] or a | |
5854 -- construct with a statement sequence. | |
5855 | |
5856 Par := Parent (Call); | |
5857 while Present (Par) loop | |
5858 if Nkind_In (Par, N_Package_Body, N_Package_Declaration) then | |
5859 return Defining_Entity (Par); | |
5860 | |
5861 elsif Nkind (Par) = N_Handled_Sequence_Of_Statements then | |
5862 return Defining_Entity (Parent (Par)); | |
5863 end if; | |
5864 | |
5865 Par := Parent (Par); | |
5866 end loop; | |
5867 | |
5868 return Empty; | |
5869 end Find_Activator; | |
5870 | |
5871 -- Local variables | |
5872 | |
5873 Activator : constant Entity_Id := Find_Activator (N); | |
5874 | |
5875 -- Start of processing for Output_Activation_Call | |
5876 | |
5877 begin | |
5878 pragma Assert (Present (Activator)); | |
5879 | |
5880 Error_Msg_NE ("\\ local tasks of & activated", Error_Nod, Activator); | |
5881 end Output_Activation_Call; | |
5882 | |
5883 ----------------- | |
5884 -- Output_Call -- | |
5885 ----------------- | |
5886 | |
5887 procedure Output_Call (N : Node_Id; Target_Id : Entity_Id) is | |
5888 procedure Output_Accept_Alternative; | |
5889 pragma Inline (Output_Accept_Alternative); | |
5890 -- Emit a specific diagnostic message concerning an accept | |
5891 -- alternative. | |
5892 | |
5893 procedure Output_Call (Kind : String); | |
5894 pragma Inline (Output_Call); | |
5895 -- Emit a specific diagnostic message concerning a call of kind Kind | |
5896 | |
5897 procedure Output_Type_Actions (Action : String); | |
5898 pragma Inline (Output_Type_Actions); | |
5899 -- Emit a specific diagnostic message concerning action Action of a | |
5900 -- type. | |
5901 | |
5902 procedure Output_Verification_Call | |
5903 (Pred : String; | |
5904 Id : Entity_Id; | |
5905 Id_Kind : String); | |
5906 pragma Inline (Output_Verification_Call); | |
5907 -- Emit a specific diagnostic message concerning the verification of | |
5908 -- predicate Pred applied to related entity Id with kind Id_Kind. | |
5909 | |
5910 ------------------------------- | |
5911 -- Output_Accept_Alternative -- | |
5912 ------------------------------- | |
5913 | |
5914 procedure Output_Accept_Alternative is | |
5915 Entry_Id : constant Entity_Id := Receiving_Entry (Target_Id); | |
5916 | |
5917 begin | |
5918 pragma Assert (Present (Entry_Id)); | |
5919 | |
5920 Error_Msg_NE ("\\ entry & selected #", Error_Nod, Entry_Id); | |
5921 end Output_Accept_Alternative; | |
5922 | |
5923 ----------------- | |
5924 -- Output_Call -- | |
5925 ----------------- | |
5926 | |
5927 procedure Output_Call (Kind : String) is | |
5928 begin | |
5929 Error_Msg_NE ("\\ " & Kind & " & called #", Error_Nod, Target_Id); | |
5930 end Output_Call; | |
5931 | |
5932 ------------------------- | |
5933 -- Output_Type_Actions -- | |
5934 ------------------------- | |
5935 | |
5936 procedure Output_Type_Actions (Action : String) is | |
5937 Typ : constant Entity_Id := First_Formal_Type (Target_Id); | |
5938 | |
5939 begin | |
5940 pragma Assert (Present (Typ)); | |
5941 | |
5942 Error_Msg_NE | |
5943 ("\\ " & Action & " actions for type & #", Error_Nod, Typ); | |
5944 end Output_Type_Actions; | |
5945 | |
5946 ------------------------------ | |
5947 -- Output_Verification_Call -- | |
5948 ------------------------------ | |
5949 | |
5950 procedure Output_Verification_Call | |
5951 (Pred : String; | |
5952 Id : Entity_Id; | |
5953 Id_Kind : String) | |
5954 is | |
5955 begin | |
5956 pragma Assert (Present (Id)); | |
5957 | |
5958 Error_Msg_NE | |
5959 ("\\ " & Pred & " of " & Id_Kind & " & verified #", | |
5960 Error_Nod, Id); | |
5961 end Output_Verification_Call; | |
5962 | |
5963 -- Start of processing for Output_Call | |
5964 | |
5965 begin | |
5966 Error_Msg_Sloc := Sloc (N); | |
5967 | |
5968 -- Accept alternative | |
5969 | |
5970 if Is_Accept_Alternative_Proc (Target_Id) then | |
5971 Output_Accept_Alternative; | |
5972 | |
5973 -- Adjustment | |
5974 | |
5975 elsif Is_TSS (Target_Id, TSS_Deep_Adjust) then | |
5976 Output_Type_Actions ("adjustment"); | |
5977 | |
5978 -- Default_Initial_Condition | |
5979 | |
5980 elsif Is_Default_Initial_Condition_Proc (Target_Id) then | |
5981 Output_Verification_Call | |
5982 (Pred => "Default_Initial_Condition", | |
5983 Id => First_Formal_Type (Target_Id), | |
5984 Id_Kind => "type"); | |
5985 | |
5986 -- Entries | |
5987 | |
5988 elsif Is_Protected_Entry (Target_Id) then | |
5989 Output_Call ("entry"); | |
5990 | |
5991 -- Task entry calls are never processed because the entry being | |
5992 -- invoked does not have a corresponding "body", it has a select. A | |
5993 -- task entry call appears in the stack of active scenarios for the | |
5994 -- sole purpose of checking No_Entry_Calls_In_Elaboration_Code and | |
5995 -- nothing more. | |
5996 | |
5997 elsif Is_Task_Entry (Target_Id) then | |
5998 null; | |
5999 | |
6000 -- Finalization | |
6001 | |
6002 elsif Is_TSS (Target_Id, TSS_Deep_Finalize) then | |
6003 Output_Type_Actions ("finalization"); | |
6004 | |
6005 -- Calls to _Finalizer procedures must not appear in the output | |
6006 -- because this creates confusing noise. | |
6007 | |
6008 elsif Is_Finalizer_Proc (Target_Id) then | |
6009 null; | |
6010 | |
6011 -- Initial_Condition | |
6012 | |
6013 elsif Is_Initial_Condition_Proc (Target_Id) then | |
6014 Output_Verification_Call | |
6015 (Pred => "Initial_Condition", | |
6016 Id => Find_Enclosing_Scope (N), | |
6017 Id_Kind => "package"); | |
6018 | |
6019 -- Initialization | |
6020 | |
6021 elsif Is_Init_Proc (Target_Id) | |
6022 or else Is_TSS (Target_Id, TSS_Deep_Initialize) | |
6023 then | |
6024 Output_Type_Actions ("initialization"); | |
6025 | |
6026 -- Invariant | |
6027 | |
6028 elsif Is_Invariant_Proc (Target_Id) then | |
6029 Output_Verification_Call | |
6030 (Pred => "invariants", | |
6031 Id => First_Formal_Type (Target_Id), | |
6032 Id_Kind => "type"); | |
6033 | |
6034 -- Partial invariant calls must not appear in the output because this | |
6035 -- creates confusing noise. Note that a partial invariant is always | |
6036 -- invoked by the "full" invariant which is already placed on the | |
6037 -- stack. | |
6038 | |
6039 elsif Is_Partial_Invariant_Proc (Target_Id) then | |
6040 null; | |
6041 | |
6042 -- _Postconditions | |
6043 | |
6044 elsif Is_Postconditions_Proc (Target_Id) then | |
6045 Output_Verification_Call | |
6046 (Pred => "postconditions", | |
6047 Id => Find_Enclosing_Scope (N), | |
6048 Id_Kind => "subprogram"); | |
6049 | |
6050 -- Subprograms must come last because some of the previous cases fall | |
6051 -- under this category. | |
6052 | |
6053 elsif Ekind (Target_Id) = E_Function then | |
6054 Output_Call ("function"); | |
6055 | |
6056 elsif Ekind (Target_Id) = E_Procedure then | |
6057 Output_Call ("procedure"); | |
6058 | |
6059 else | |
6060 pragma Assert (False); | |
6061 null; | |
6062 end if; | |
6063 end Output_Call; | |
6064 | |
6065 ------------------- | |
6066 -- Output_Header -- | |
6067 ------------------- | |
6068 | |
6069 procedure Output_Header is | |
6070 Unit_Id : constant Entity_Id := Find_Top_Unit (Root_Scenario); | |
6071 | |
6072 begin | |
6073 if Ekind (Unit_Id) = E_Package then | |
6074 Error_Msg_NE ("\\ spec of unit & elaborated", Error_Nod, Unit_Id); | |
6075 | |
6076 elsif Ekind (Unit_Id) = E_Package_Body then | |
6077 Error_Msg_NE ("\\ body of unit & elaborated", Error_Nod, Unit_Id); | |
6078 | |
6079 else | |
6080 Error_Msg_NE ("\\ in body of unit &", Error_Nod, Unit_Id); | |
6081 end if; | |
6082 end Output_Header; | |
6083 | |
6084 -------------------------- | |
6085 -- Output_Instantiation -- | |
6086 -------------------------- | |
6087 | |
6088 procedure Output_Instantiation (N : Node_Id) is | |
6089 procedure Output_Instantiation (Gen_Id : Entity_Id; Kind : String); | |
6090 pragma Inline (Output_Instantiation); | |
6091 -- Emit a specific diagnostic message concerning an instantiation of | |
6092 -- generic unit Gen_Id. Kind denotes the kind of the instantiation. | |
6093 | |
6094 -------------------------- | |
6095 -- Output_Instantiation -- | |
6096 -------------------------- | |
6097 | |
6098 procedure Output_Instantiation (Gen_Id : Entity_Id; Kind : String) is | |
6099 begin | |
6100 Error_Msg_NE | |
6101 ("\\ " & Kind & " & instantiated as & #", Error_Nod, Gen_Id); | |
6102 end Output_Instantiation; | |
6103 | |
6104 -- Local variables | |
6105 | |
6106 Inst : Node_Id; | |
6107 Inst_Attrs : Instantiation_Attributes; | |
6108 Inst_Id : Entity_Id; | |
6109 Gen_Id : Entity_Id; | |
6110 | |
6111 -- Start of processing for Output_Instantiation | |
6112 | |
6113 begin | |
6114 Extract_Instantiation_Attributes | |
6115 (Exp_Inst => N, | |
6116 Inst => Inst, | |
6117 Inst_Id => Inst_Id, | |
6118 Gen_Id => Gen_Id, | |
6119 Attrs => Inst_Attrs); | |
6120 | |
6121 Error_Msg_Node_2 := Inst_Id; | |
6122 Error_Msg_Sloc := Sloc (Inst); | |
6123 | |
6124 if Nkind (Inst) = N_Function_Instantiation then | |
6125 Output_Instantiation (Gen_Id, "function"); | |
6126 | |
6127 elsif Nkind (Inst) = N_Package_Instantiation then | |
6128 Output_Instantiation (Gen_Id, "package"); | |
6129 | |
6130 elsif Nkind (Inst) = N_Procedure_Instantiation then | |
6131 Output_Instantiation (Gen_Id, "procedure"); | |
6132 | |
6133 else | |
6134 pragma Assert (False); | |
6135 null; | |
6136 end if; | |
6137 end Output_Instantiation; | |
6138 | |
6139 -------------------------------- | |
6140 -- Output_Variable_Assignment -- | |
6141 -------------------------------- | |
6142 | |
6143 procedure Output_Variable_Assignment (N : Node_Id) is | |
6144 Var_Id : constant Entity_Id := Entity (Extract_Assignment_Name (N)); | |
6145 | |
6146 begin | |
6147 Error_Msg_Sloc := Sloc (N); | |
6148 Error_Msg_NE ("\\ variable & assigned #", Error_Nod, Var_Id); | |
6149 end Output_Variable_Assignment; | |
6150 | |
6151 -------------------------- | |
6152 -- Output_Variable_Read -- | |
6153 -------------------------- | |
6154 | |
6155 procedure Output_Variable_Read (N : Node_Id) is | |
6156 Dummy : Variable_Attributes; | |
6157 Var_Id : Entity_Id; | |
6158 | |
6159 begin | |
6160 Extract_Variable_Reference_Attributes | |
6161 (Ref => N, | |
6162 Var_Id => Var_Id, | |
6163 Attrs => Dummy); | |
6164 | |
6165 Error_Msg_Sloc := Sloc (N); | |
6166 Error_Msg_NE ("\\ variable & read #", Error_Nod, Var_Id); | |
6167 end Output_Variable_Read; | |
6168 | |
6169 -- Local variables | |
6170 | |
6171 package Stack renames Scenario_Stack; | |
6172 | |
6173 Dummy : Call_Attributes; | |
6174 N : Node_Id; | |
6175 Posted : Boolean; | |
6176 Target_Id : Entity_Id; | |
6177 | |
6178 -- Start of processing for Output_Active_Scenarios | |
6179 | |
6180 begin | |
6181 -- Active scenarios are emitted only when the static model is in effect | |
6182 -- because there is an inherent order by which all these scenarios were | |
6183 -- reached from the declaration or library level. | |
6184 | |
6185 if not Static_Elaboration_Checks then | |
6186 return; | |
6187 end if; | |
6188 | |
6189 Posted := False; | |
6190 | |
6191 for Index in Stack.First .. Stack.Last loop | |
6192 N := Stack.Table (Index); | |
6193 | |
6194 if not Posted then | |
6195 Posted := True; | |
6196 Output_Header; | |
6197 end if; | |
6198 | |
6199 -- 'Access | |
6200 | |
6201 if Nkind (N) = N_Attribute_Reference then | |
6202 Output_Access (N); | |
6203 | |
6204 -- Calls | |
6205 | |
6206 elsif Is_Suitable_Call (N) then | |
6207 Extract_Call_Attributes | |
6208 (Call => N, | |
6209 Target_Id => Target_Id, | |
6210 Attrs => Dummy); | |
6211 | |
6212 if Is_Activation_Proc (Target_Id) then | |
6213 Output_Activation_Call (N); | |
6214 else | |
6215 Output_Call (N, Target_Id); | |
6216 end if; | |
6217 | |
6218 -- Instantiations | |
6219 | |
6220 elsif Is_Suitable_Instantiation (N) then | |
6221 Output_Instantiation (N); | |
6222 | |
6223 -- Variable assignments | |
6224 | |
6225 elsif Nkind (N) = N_Assignment_Statement then | |
6226 Output_Variable_Assignment (N); | |
6227 | |
6228 -- Variable read | |
6229 | |
6230 elsif Is_Suitable_Variable_Read (N) then | |
6231 Output_Variable_Read (N); | |
6232 | |
6233 else | |
6234 pragma Assert (False); | |
6235 null; | |
6236 end if; | |
6237 end loop; | |
6238 end Output_Active_Scenarios; | |
6239 | |
6240 ------------------------- | |
6241 -- Pop_Active_Scenario -- | |
6242 ------------------------- | |
6243 | |
6244 procedure Pop_Active_Scenario (N : Node_Id) is | |
6245 Top : Node_Id renames Scenario_Stack.Table (Scenario_Stack.Last); | |
6246 | |
6247 begin | |
6248 pragma Assert (Top = N); | |
6249 Scenario_Stack.Decrement_Last; | |
6250 end Pop_Active_Scenario; | |
6251 | |
6252 -------------------- | |
6253 -- Process_Access -- | |
6254 -------------------- | |
6255 | |
6256 procedure Process_Access (Attr : Node_Id; In_Task_Body : Boolean) is | |
6257 function Build_Access_Marker (Target_Id : Entity_Id) return Node_Id; | |
6258 pragma Inline (Build_Access_Marker); | |
6259 -- Create a suitable call marker which invokes target Target_Id | |
6260 | |
6261 ------------------------- | |
6262 -- Build_Access_Marker -- | |
6263 ------------------------- | |
6264 | |
6265 function Build_Access_Marker (Target_Id : Entity_Id) return Node_Id is | |
6266 Marker : Node_Id; | |
6267 | |
6268 begin | |
6269 Marker := Make_Call_Marker (Sloc (Attr)); | |
6270 | |
6271 -- Inherit relevant attributes from the attribute | |
6272 | |
6273 -- Performance note: parent traversal | |
6274 | |
6275 Set_Target (Marker, Target_Id); | |
6276 Set_Is_Declaration_Level_Node | |
6277 (Marker, Find_Enclosing_Level (Attr) = Declaration_Level); | |
6278 Set_Is_Dispatching_Call | |
6279 (Marker, False); | |
6280 Set_Is_Elaboration_Checks_OK_Node | |
6281 (Marker, Is_Elaboration_Checks_OK_Node (Attr)); | |
6282 Set_Is_Source_Call | |
6283 (Marker, Comes_From_Source (Attr)); | |
6284 Set_Is_SPARK_Mode_On_Node | |
6285 (Marker, Is_SPARK_Mode_On_Node (Attr)); | |
6286 | |
6287 -- Partially insert the call marker into the tree by setting its | |
6288 -- parent pointer. | |
6289 | |
6290 Set_Parent (Marker, Attr); | |
6291 | |
6292 return Marker; | |
6293 end Build_Access_Marker; | |
6294 | |
6295 -- Local variables | |
6296 | |
6297 Root : constant Node_Id := Root_Scenario; | |
6298 Target_Id : constant Entity_Id := Entity (Prefix (Attr)); | |
6299 | |
6300 Target_Attrs : Target_Attributes; | |
6301 | |
6302 -- Start of processing for Process_Access | |
6303 | |
6304 begin | |
6305 -- Output relevant information when switch -gnatel (info messages on | |
6306 -- implicit Elaborate[_All] pragmas) is in effect. | |
6307 | |
6308 if Elab_Info_Messages then | |
6309 Error_Msg_NE | |
6310 ("info: access to & during elaboration", Attr, Target_Id); | |
6311 end if; | |
6312 | |
6313 Extract_Target_Attributes | |
6314 (Target_Id => Target_Id, | |
6315 Attrs => Target_Attrs); | |
6316 | |
6317 -- Both the attribute and the corresponding body are in the same unit. | |
6318 -- The corresponding body must appear prior to the root scenario which | |
6319 -- started the recursive search. If this is not the case, then there is | |
6320 -- a potential ABE if the access value is used to call the subprogram. | |
6321 -- Emit a warning only when switch -gnatw.f (warnings on suspucious | |
6322 -- 'Access) is in effect. | |
6323 | |
6324 if Warn_On_Elab_Access | |
6325 and then Present (Target_Attrs.Body_Decl) | |
6326 and then In_Extended_Main_Code_Unit (Target_Attrs.Body_Decl) | |
6327 and then Earlier_In_Extended_Unit (Root, Target_Attrs.Body_Decl) | |
6328 then | |
6329 Error_Msg_Name_1 := Attribute_Name (Attr); | |
6330 Error_Msg_NE ("??% attribute of & before body seen", Attr, Target_Id); | |
6331 Error_Msg_N ("\possible Program_Error on later references", Attr); | |
6332 | |
6333 Output_Active_Scenarios (Attr); | |
6334 end if; | |
6335 | |
6336 -- Treat the attribute as an immediate invocation of the target when | |
6337 -- switch -gnatd.o (conservative elaboration order for indirect calls) | |
6338 -- is in effect. Note that the prior elaboration of the unit containing | |
6339 -- the target is ensured processing the corresponding call marker. | |
6340 | |
6341 if Debug_Flag_Dot_O then | |
6342 Process_Scenario | |
6343 (N => Build_Access_Marker (Target_Id), | |
6344 In_Task_Body => In_Task_Body); | |
6345 | |
6346 -- Otherwise ensure that the unit with the corresponding body is | |
6347 -- elaborated prior to the main unit. | |
6348 | |
6349 else | |
6350 Ensure_Prior_Elaboration | |
6351 (N => Attr, | |
6352 Unit_Id => Target_Attrs.Unit_Id, | |
6353 In_Task_Body => In_Task_Body); | |
6354 end if; | |
6355 end Process_Access; | |
6356 | |
6357 ----------------------------- | |
6358 -- Process_Activation_Call -- | |
6359 ----------------------------- | |
6360 | |
6361 procedure Process_Activation_Call | |
6362 (Call : Node_Id; | |
6363 Call_Attrs : Call_Attributes; | |
6364 In_Task_Body : Boolean) | |
6365 is | |
6366 procedure Process_Task_Object (Obj_Id : Entity_Id; Typ : Entity_Id); | |
6367 -- Perform ABE checks and diagnostics for object Obj_Id with type Typ. | |
6368 -- Typ may be a task type or a composite type with at least one task | |
6369 -- component. | |
6370 | |
6371 procedure Process_Task_Objects (List : List_Id); | |
6372 -- Perform ABE checks and diagnostics for all task objects found in | |
6373 -- the list List. | |
6374 | |
6375 ------------------------- | |
6376 -- Process_Task_Object -- | |
6377 ------------------------- | |
6378 | |
6379 procedure Process_Task_Object (Obj_Id : Entity_Id; Typ : Entity_Id) is | |
6380 Base_Typ : constant Entity_Id := Base_Type (Typ); | |
6381 | |
6382 Comp_Id : Entity_Id; | |
6383 Task_Attrs : Task_Attributes; | |
6384 | |
6385 begin | |
6386 if Is_Task_Type (Typ) then | |
6387 Extract_Task_Attributes | |
6388 (Typ => Base_Typ, | |
6389 Attrs => Task_Attrs); | |
6390 | |
6391 Process_Single_Activation | |
6392 (Call => Call, | |
6393 Call_Attrs => Call_Attrs, | |
6394 Obj_Id => Obj_Id, | |
6395 Task_Attrs => Task_Attrs, | |
6396 In_Task_Body => In_Task_Body); | |
6397 | |
6398 -- Examine the component type when the object is an array | |
6399 | |
6400 elsif Is_Array_Type (Typ) and then Has_Task (Base_Typ) then | |
6401 Process_Task_Object (Obj_Id, Component_Type (Typ)); | |
6402 | |
6403 -- Examine individual component types when the object is a record | |
6404 | |
6405 elsif Is_Record_Type (Typ) and then Has_Task (Base_Typ) then | |
6406 Comp_Id := First_Component (Typ); | |
6407 while Present (Comp_Id) loop | |
6408 Process_Task_Object (Obj_Id, Etype (Comp_Id)); | |
6409 Next_Component (Comp_Id); | |
6410 end loop; | |
6411 end if; | |
6412 end Process_Task_Object; | |
6413 | |
6414 -------------------------- | |
6415 -- Process_Task_Objects -- | |
6416 -------------------------- | |
6417 | |
6418 procedure Process_Task_Objects (List : List_Id) is | |
6419 Item : Node_Id; | |
6420 Item_Id : Entity_Id; | |
6421 Item_Typ : Entity_Id; | |
6422 | |
6423 begin | |
6424 -- Examine the contents of the list looking for an object declaration | |
6425 -- of a task type or one that contains a task within. | |
6426 | |
6427 Item := First (List); | |
6428 while Present (Item) loop | |
6429 if Nkind (Item) = N_Object_Declaration then | |
6430 Item_Id := Defining_Entity (Item); | |
6431 Item_Typ := Etype (Item_Id); | |
6432 | |
6433 if Has_Task (Item_Typ) then | |
6434 Process_Task_Object (Item_Id, Item_Typ); | |
6435 end if; | |
6436 end if; | |
6437 | |
6438 Next (Item); | |
6439 end loop; | |
6440 end Process_Task_Objects; | |
6441 | |
6442 -- Local variables | |
6443 | |
6444 Context : Node_Id; | |
6445 Spec : Node_Id; | |
6446 | |
6447 -- Start of processing for Process_Activation_Call | |
6448 | |
6449 begin | |
6450 -- Nothing to do when the activation is a guaranteed ABE | |
6451 | |
6452 if Is_Known_Guaranteed_ABE (Call) then | |
6453 return; | |
6454 end if; | |
6455 | |
6456 -- Find the proper context of the activation call where all task objects | |
6457 -- being activated are declared. This is usually the immediate parent of | |
6458 -- the call. | |
6459 | |
6460 Context := Parent (Call); | |
6461 | |
6462 -- In the case of package bodies, the activation call is in the handled | |
6463 -- sequence of statements, but the task objects are in the declaration | |
6464 -- list of the body. | |
6465 | |
6466 if Nkind (Context) = N_Handled_Sequence_Of_Statements | |
6467 and then Nkind (Parent (Context)) = N_Package_Body | |
6468 then | |
6469 Context := Parent (Context); | |
6470 end if; | |
6471 | |
6472 -- Process all task objects defined in both the spec and body when the | |
6473 -- activation call precedes the "begin" of a package body. | |
6474 | |
6475 if Nkind (Context) = N_Package_Body then | |
6476 Spec := | |
6477 Specification | |
6478 (Unit_Declaration_Node (Corresponding_Spec (Context))); | |
6479 | |
6480 Process_Task_Objects (Visible_Declarations (Spec)); | |
6481 Process_Task_Objects (Private_Declarations (Spec)); | |
6482 Process_Task_Objects (Declarations (Context)); | |
6483 | |
6484 -- Process all task objects defined in the spec when the activation call | |
6485 -- appears at the end of a package spec. | |
6486 | |
6487 elsif Nkind (Context) = N_Package_Specification then | |
6488 Process_Task_Objects (Visible_Declarations (Context)); | |
6489 Process_Task_Objects (Private_Declarations (Context)); | |
6490 | |
6491 -- Otherwise the context of the activation is some construct with a | |
6492 -- declarative part. Note that the corresponding record type of a task | |
6493 -- type is controlled. Because of this, the finalization machinery must | |
6494 -- relocate the task object to the handled statements of the construct | |
6495 -- to perform proper finalization in case of an exception. Examine the | |
6496 -- statements of the construct rather than the declarations. | |
6497 | |
6498 else | |
6499 pragma Assert (Nkind (Context) = N_Handled_Sequence_Of_Statements); | |
6500 | |
6501 Process_Task_Objects (Statements (Context)); | |
6502 end if; | |
6503 end Process_Activation_Call; | |
6504 | |
6505 --------------------------------------------- | |
6506 -- Process_Activation_Conditional_ABE_Impl -- | |
6507 --------------------------------------------- | |
6508 | |
6509 procedure Process_Activation_Conditional_ABE_Impl | |
6510 (Call : Node_Id; | |
6511 Call_Attrs : Call_Attributes; | |
6512 Obj_Id : Entity_Id; | |
6513 Task_Attrs : Task_Attributes; | |
6514 In_Task_Body : Boolean) | |
6515 is | |
6516 Check_OK : constant Boolean := | |
6517 not Is_Ignored_Ghost_Entity (Obj_Id) | |
6518 and then not Task_Attrs.Ghost_Mode_Ignore | |
6519 and then Is_Elaboration_Checks_OK_Id (Obj_Id) | |
6520 and then Task_Attrs.Elab_Checks_OK; | |
6521 -- A run-time ABE check may be installed only when the object and the | |
6522 -- task type have active elaboration checks, and both are not ignored | |
6523 -- Ghost constructs. | |
6524 | |
6525 Root : constant Node_Id := Root_Scenario; | |
6526 | |
6527 begin | |
6528 -- Output relevant information when switch -gnatel (info messages on | |
6529 -- implicit Elaborate[_All] pragmas) is in effect. | |
6530 | |
6531 if Elab_Info_Messages then | |
6532 Error_Msg_NE | |
6533 ("info: activation of & during elaboration", Call, Obj_Id); | |
6534 end if; | |
6535 | |
6536 -- Nothing to do when the activation is a guaranteed ABE | |
6537 | |
6538 if Is_Known_Guaranteed_ABE (Call) then | |
6539 return; | |
6540 | |
6541 -- Nothing to do when the root scenario appears at the declaration | |
6542 -- level and the task is in the same unit, but outside this context. | |
6543 | |
6544 -- task type Task_Typ; -- task declaration | |
6545 | |
6546 -- procedure Proc is | |
6547 -- function A ... is | |
6548 -- begin | |
6549 -- if Some_Condition then | |
6550 -- declare | |
6551 -- T : Task_Typ; | |
6552 -- begin | |
6553 -- <activation call> -- activation site | |
6554 -- end; | |
6555 -- ... | |
6556 -- end A; | |
6557 | |
6558 -- X : ... := A; -- root scenario | |
6559 -- ... | |
6560 | |
6561 -- task body Task_Typ is | |
6562 -- ... | |
6563 -- end Task_Typ; | |
6564 | |
6565 -- In the example above, the context of X is the declarative list of | |
6566 -- Proc. The "elaboration" of X may reach the activation of T whose body | |
6567 -- is defined outside of X's context. The task body is relevant only | |
6568 -- when Proc is invoked, but this happens only in "normal" elaboration, | |
6569 -- therefore the task body must not be considered if this is not the | |
6570 -- case. | |
6571 | |
6572 -- Performance note: parent traversal | |
6573 | |
6574 elsif Is_Up_Level_Target (Task_Attrs.Task_Decl) then | |
6575 return; | |
6576 | |
6577 -- Nothing to do when the activation is ABE-safe | |
6578 | |
6579 -- generic | |
6580 -- package Gen is | |
6581 -- task type Task_Typ; | |
6582 -- end Gen; | |
6583 | |
6584 -- package body Gen is | |
6585 -- task body Task_Typ is | |
6586 -- begin | |
6587 -- ... | |
6588 -- end Task_Typ; | |
6589 -- end Gen; | |
6590 | |
6591 -- with Gen; | |
6592 -- procedure Main is | |
6593 -- package Nested is | |
6594 -- ... | |
6595 -- end Nested; | |
6596 | |
6597 -- package body Nested is | |
6598 -- package Inst is new Gen; | |
6599 -- T : Inst.Task_Typ; | |
6600 -- [begin] | |
6601 -- <activation call> -- safe activation | |
6602 -- end Nested; | |
6603 -- ... | |
6604 | |
6605 elsif Is_Safe_Activation (Call, Task_Attrs.Task_Decl) then | |
6606 | |
6607 -- Note that the task body must still be examined for any nested | |
6608 -- scenarios. | |
6609 | |
6610 null; | |
6611 | |
6612 -- The activation call and the task body are both in the main unit | |
6613 | |
6614 elsif Present (Task_Attrs.Body_Decl) | |
6615 and then In_Extended_Main_Code_Unit (Task_Attrs.Body_Decl) | |
6616 then | |
6617 -- If the root scenario appears prior to the task body, then this is | |
6618 -- a possible ABE with respect to the root scenario. | |
6619 | |
6620 -- task type Task_Typ; | |
6621 | |
6622 -- function A ... is | |
6623 -- begin | |
6624 -- if Some_Condition then | |
6625 -- declare | |
6626 -- package Pack is | |
6627 -- ... | |
6628 -- end Pack; | |
6629 | |
6630 -- package body Pack is | |
6631 -- T : Task_Typ; | |
6632 -- [begin] | |
6633 -- <activation call> -- activation of T | |
6634 -- end Pack; | |
6635 -- ... | |
6636 -- end A; | |
6637 | |
6638 -- X : ... := A; -- root scenario | |
6639 | |
6640 -- task body Task_Typ is -- task body | |
6641 -- ... | |
6642 -- end Task_Typ; | |
6643 | |
6644 -- Y : ... := A; -- root scenario | |
6645 | |
6646 -- IMPORTANT: The activation of T is a possible ABE for X, but | |
6647 -- not for Y. Intalling an unconditional ABE raise prior to the | |
6648 -- activation call would be wrong as it will fail for Y as well | |
6649 -- but in Y's case the activation of T is never an ABE. | |
6650 | |
6651 if Earlier_In_Extended_Unit (Root, Task_Attrs.Body_Decl) then | |
6652 | |
6653 -- ABE diagnostics are emitted only in the static model because | |
6654 -- there is a well-defined order to visiting scenarios. Without | |
6655 -- this order diagnostics appear jumbled and result in unwanted | |
6656 -- noise. | |
6657 | |
6658 if Static_Elaboration_Checks then | |
6659 Error_Msg_Sloc := Sloc (Call); | |
6660 Error_Msg_N | |
6661 ("??task & will be activated # before elaboration of its " | |
6662 & "body", Obj_Id); | |
6663 Error_Msg_N | |
6664 ("\Program_Error may be raised at run time", Obj_Id); | |
6665 | |
6666 Output_Active_Scenarios (Obj_Id); | |
6667 end if; | |
6668 | |
6669 -- Install a conditional run-time ABE check to verify that the | |
6670 -- task body has been elaborated prior to the activation call. | |
6671 | |
6672 if Check_OK then | |
6673 Install_ABE_Check | |
6674 (N => Call, | |
6675 Ins_Nod => Call, | |
6676 Target_Id => Task_Attrs.Spec_Id, | |
6677 Target_Decl => Task_Attrs.Task_Decl, | |
6678 Target_Body => Task_Attrs.Body_Decl); | |
6679 end if; | |
6680 end if; | |
6681 | |
6682 -- Otherwise the task body is not available in this compilation or it | |
6683 -- resides in an external unit. Install a run-time ABE check to verify | |
6684 -- that the task body has been elaborated prior to the activation call | |
6685 -- when the dynamic model is in effect. | |
6686 | |
6687 elsif Dynamic_Elaboration_Checks and then Check_OK then | |
6688 Install_ABE_Check | |
6689 (N => Call, | |
6690 Ins_Nod => Call, | |
6691 Id => Task_Attrs.Unit_Id); | |
6692 end if; | |
6693 | |
6694 -- Both the activation call and task type are subject to SPARK_Mode | |
6695 -- On, this triggers the SPARK rules for task activation. Compared to | |
6696 -- calls and instantiations, task activation in SPARK does not require | |
6697 -- the presence of Elaborate[_All] pragmas in case the task type is | |
6698 -- defined outside the main unit. This is because SPARK utilizes a | |
6699 -- special policy which activates all tasks after the main unit has | |
6700 -- finished its elaboration. | |
6701 | |
6702 if Call_Attrs.SPARK_Mode_On and Task_Attrs.SPARK_Mode_On then | |
6703 null; | |
6704 | |
6705 -- Otherwise the Ada rules are in effect. Ensure that the unit with the | |
6706 -- task body is elaborated prior to the main unit. | |
6707 | |
6708 else | |
6709 Ensure_Prior_Elaboration | |
6710 (N => Call, | |
6711 Unit_Id => Task_Attrs.Unit_Id, | |
6712 In_Task_Body => In_Task_Body); | |
6713 end if; | |
6714 | |
6715 Traverse_Body (Task_Attrs.Body_Decl, In_Task_Body => True); | |
6716 end Process_Activation_Conditional_ABE_Impl; | |
6717 | |
6718 procedure Process_Activation_Conditional_ABE is | |
6719 new Process_Activation_Call (Process_Activation_Conditional_ABE_Impl); | |
6720 | |
6721 -------------------------------------------- | |
6722 -- Process_Activation_Guaranteed_ABE_Impl -- | |
6723 -------------------------------------------- | |
6724 | |
6725 procedure Process_Activation_Guaranteed_ABE_Impl | |
6726 (Call : Node_Id; | |
6727 Call_Attrs : Call_Attributes; | |
6728 Obj_Id : Entity_Id; | |
6729 Task_Attrs : Task_Attributes; | |
6730 In_Task_Body : Boolean) | |
6731 is | |
6732 pragma Unreferenced (Call_Attrs); | |
6733 pragma Unreferenced (In_Task_Body); | |
6734 | |
6735 Check_OK : constant Boolean := | |
6736 not Is_Ignored_Ghost_Entity (Obj_Id) | |
6737 and then not Task_Attrs.Ghost_Mode_Ignore | |
6738 and then Is_Elaboration_Checks_OK_Id (Obj_Id) | |
6739 and then Task_Attrs.Elab_Checks_OK; | |
6740 -- A run-time ABE check may be installed only when the object and the | |
6741 -- task type have active elaboration checks, and both are not ignored | |
6742 -- Ghost constructs. | |
6743 | |
6744 begin | |
6745 -- Nothing to do when the root scenario appears at the declaration | |
6746 -- level and the task is in the same unit, but outside this context. | |
6747 | |
6748 -- task type Task_Typ; -- task declaration | |
6749 | |
6750 -- procedure Proc is | |
6751 -- function A ... is | |
6752 -- begin | |
6753 -- if Some_Condition then | |
6754 -- declare | |
6755 -- T : Task_Typ; | |
6756 -- begin | |
6757 -- <activation call> -- activation site | |
6758 -- end; | |
6759 -- ... | |
6760 -- end A; | |
6761 | |
6762 -- X : ... := A; -- root scenario | |
6763 -- ... | |
6764 | |
6765 -- task body Task_Typ is | |
6766 -- ... | |
6767 -- end Task_Typ; | |
6768 | |
6769 -- In the example above, the context of X is the declarative list of | |
6770 -- Proc. The "elaboration" of X may reach the activation of T whose body | |
6771 -- is defined outside of X's context. The task body is relevant only | |
6772 -- when Proc is invoked, but this happens only in "normal" elaboration, | |
6773 -- therefore the task body must not be considered if this is not the | |
6774 -- case. | |
6775 | |
6776 -- Performance note: parent traversal | |
6777 | |
6778 if Is_Up_Level_Target (Task_Attrs.Task_Decl) then | |
6779 return; | |
6780 | |
6781 -- Nothing to do when the activation is ABE-safe | |
6782 | |
6783 -- generic | |
6784 -- package Gen is | |
6785 -- task type Task_Typ; | |
6786 -- end Gen; | |
6787 | |
6788 -- package body Gen is | |
6789 -- task body Task_Typ is | |
6790 -- begin | |
6791 -- ... | |
6792 -- end Task_Typ; | |
6793 -- end Gen; | |
6794 | |
6795 -- with Gen; | |
6796 -- procedure Main is | |
6797 -- package Nested is | |
6798 -- ... | |
6799 -- end Nested; | |
6800 | |
6801 -- package body Nested is | |
6802 -- package Inst is new Gen; | |
6803 -- T : Inst.Task_Typ; | |
6804 -- [begin] | |
6805 -- <activation call> -- safe activation | |
6806 -- end Nested; | |
6807 -- ... | |
6808 | |
6809 elsif Is_Safe_Activation (Call, Task_Attrs.Task_Decl) then | |
6810 return; | |
6811 | |
6812 -- An activation call leads to a guaranteed ABE when the activation | |
6813 -- call and the task appear within the same context ignoring library | |
6814 -- levels, and the body of the task has not been seen yet or appears | |
6815 -- after the activation call. | |
6816 | |
6817 -- procedure Guaranteed_ABE is | |
6818 -- task type Task_Typ; | |
6819 | |
6820 -- package Nested is | |
6821 -- ... | |
6822 -- end Nested; | |
6823 | |
6824 -- package body Nested is | |
6825 -- T : Task_Typ; | |
6826 -- [begin] | |
6827 -- <activation call> -- guaranteed ABE | |
6828 -- end Nested; | |
6829 | |
6830 -- task body Task_Typ is | |
6831 -- ... | |
6832 -- end Task_Typ; | |
6833 -- ... | |
6834 | |
6835 -- Performance note: parent traversal | |
6836 | |
6837 elsif Is_Guaranteed_ABE | |
6838 (N => Call, | |
6839 Target_Decl => Task_Attrs.Task_Decl, | |
6840 Target_Body => Task_Attrs.Body_Decl) | |
6841 then | |
6842 Error_Msg_Sloc := Sloc (Call); | |
6843 Error_Msg_N | |
6844 ("??task & will be activated # before elaboration of its body", | |
6845 Obj_Id); | |
6846 Error_Msg_N ("\Program_Error will be raised at run time", Obj_Id); | |
6847 | |
6848 -- Mark the activation call as a guaranteed ABE | |
6849 | |
6850 Set_Is_Known_Guaranteed_ABE (Call); | |
6851 | |
6852 -- Install a run-time ABE failue because this activation call will | |
6853 -- always result in an ABE. | |
6854 | |
6855 if Check_OK then | |
6856 Install_ABE_Failure | |
6857 (N => Call, | |
6858 Ins_Nod => Call); | |
6859 end if; | |
6860 end if; | |
6861 end Process_Activation_Guaranteed_ABE_Impl; | |
6862 | |
6863 procedure Process_Activation_Guaranteed_ABE is | |
6864 new Process_Activation_Call (Process_Activation_Guaranteed_ABE_Impl); | |
6865 | |
6866 ------------------ | |
6867 -- Process_Call -- | |
6868 ------------------ | |
6869 | |
6870 procedure Process_Call | |
6871 (Call : Node_Id; | |
6872 Call_Attrs : Call_Attributes; | |
6873 Target_Id : Entity_Id; | |
6874 In_Task_Body : Boolean) | |
6875 is | |
6876 SPARK_Rules_On : Boolean; | |
6877 Target_Attrs : Target_Attributes; | |
6878 | |
6879 begin | |
6880 Extract_Target_Attributes | |
6881 (Target_Id => Target_Id, | |
6882 Attrs => Target_Attrs); | |
6883 | |
6884 -- The SPARK rules are in effect when both the call and target are | |
6885 -- subject to SPARK_Mode On. | |
6886 | |
6887 SPARK_Rules_On := | |
6888 Call_Attrs.SPARK_Mode_On and Target_Attrs.SPARK_Mode_On; | |
6889 | |
6890 -- Output relevant information when switch -gnatel (info messages on | |
6891 -- implicit Elaborate[_All] pragmas) is in effect. | |
6892 | |
6893 if Elab_Info_Messages then | |
6894 Info_Call | |
6895 (Call => Call, | |
6896 Target_Id => Target_Id, | |
6897 Info_Msg => True, | |
6898 In_SPARK => SPARK_Rules_On); | |
6899 end if; | |
6900 | |
6901 -- Check whether the invocation of an entry clashes with an existing | |
6902 -- restriction. | |
6903 | |
6904 if Is_Protected_Entry (Target_Id) then | |
6905 Check_Restriction (No_Entry_Calls_In_Elaboration_Code, Call); | |
6906 | |
6907 elsif Is_Task_Entry (Target_Id) then | |
6908 Check_Restriction (No_Entry_Calls_In_Elaboration_Code, Call); | |
6909 | |
6910 -- Task entry calls are never processed because the entry being | |
6911 -- invoked does not have a corresponding "body", it has a select. | |
6912 | |
6913 return; | |
6914 end if; | |
6915 | |
6916 -- Nothing to do when the call is a guaranteed ABE | |
6917 | |
6918 if Is_Known_Guaranteed_ABE (Call) then | |
6919 return; | |
6920 | |
6921 -- Nothing to do when the root scenario appears at the declaration level | |
6922 -- and the target is in the same unit, but outside this context. | |
6923 | |
6924 -- function B ...; -- target declaration | |
6925 | |
6926 -- procedure Proc is | |
6927 -- function A ... is | |
6928 -- begin | |
6929 -- if Some_Condition then | |
6930 -- return B; -- call site | |
6931 -- ... | |
6932 -- end A; | |
6933 | |
6934 -- X : ... := A; -- root scenario | |
6935 -- ... | |
6936 | |
6937 -- function B ... is | |
6938 -- ... | |
6939 -- end B; | |
6940 | |
6941 -- In the example above, the context of X is the declarative region of | |
6942 -- Proc. The "elaboration" of X may eventually reach B which is defined | |
6943 -- outside of X's context. B is relevant only when Proc is invoked, but | |
6944 -- this happens only by means of "normal" elaboration, therefore B must | |
6945 -- not be considered if this is not the case. | |
6946 | |
6947 -- Performance note: parent traversal | |
6948 | |
6949 elsif Is_Up_Level_Target (Target_Attrs.Spec_Decl) then | |
6950 return; | |
6951 | |
6952 -- The SPARK rules are verified only when -gnatd.v (enforce SPARK | |
6953 -- elaboration rules in SPARK code) is in effect. | |
6954 | |
6955 elsif SPARK_Rules_On and Debug_Flag_Dot_V then | |
6956 Process_Call_SPARK | |
6957 (Call => Call, | |
6958 Call_Attrs => Call_Attrs, | |
6959 Target_Id => Target_Id, | |
6960 Target_Attrs => Target_Attrs); | |
6961 | |
6962 -- Otherwise the Ada rules are in effect, or SPARK code is allowed to | |
6963 -- violate the SPARK rules. | |
6964 | |
6965 else | |
6966 Process_Call_Ada | |
6967 (Call => Call, | |
6968 Call_Attrs => Call_Attrs, | |
6969 Target_Id => Target_Id, | |
6970 Target_Attrs => Target_Attrs, | |
6971 In_Task_Body => In_Task_Body); | |
6972 end if; | |
6973 | |
6974 -- Inspect the target body (and barried function) for other suitable | |
6975 -- elaboration scenarios. | |
6976 | |
6977 Traverse_Body (Target_Attrs.Body_Barf, In_Task_Body); | |
6978 Traverse_Body (Target_Attrs.Body_Decl, In_Task_Body); | |
6979 end Process_Call; | |
6980 | |
6981 ---------------------- | |
6982 -- Process_Call_Ada -- | |
6983 ---------------------- | |
6984 | |
6985 procedure Process_Call_Ada | |
6986 (Call : Node_Id; | |
6987 Call_Attrs : Call_Attributes; | |
6988 Target_Id : Entity_Id; | |
6989 Target_Attrs : Target_Attributes; | |
6990 In_Task_Body : Boolean) | |
6991 is | |
6992 function In_Initialization_Context (N : Node_Id) return Boolean; | |
6993 -- Determine whether arbitrary node N appears within a type init proc or | |
6994 -- primitive [Deep_]Initialize. | |
6995 | |
6996 ------------------------------- | |
6997 -- In_Initialization_Context -- | |
6998 ------------------------------- | |
6999 | |
7000 function In_Initialization_Context (N : Node_Id) return Boolean is | |
7001 Par : Node_Id; | |
7002 Spec_Id : Entity_Id; | |
7003 | |
7004 begin | |
7005 -- Climb the parent chain looking for initialization actions | |
7006 | |
7007 Par := Parent (N); | |
7008 while Present (Par) loop | |
7009 | |
7010 -- A block may be part of the initialization actions of a default | |
7011 -- initialized object. | |
7012 | |
7013 if Nkind (Par) = N_Block_Statement | |
7014 and then Is_Initialization_Block (Par) | |
7015 then | |
7016 return True; | |
7017 | |
7018 -- A subprogram body may denote an initialization routine | |
7019 | |
7020 elsif Nkind (Par) = N_Subprogram_Body then | |
7021 Spec_Id := Unique_Defining_Entity (Par); | |
7022 | |
7023 -- The current subprogram body denotes a type init proc or | |
7024 -- primitive [Deep_]Initialize. | |
7025 | |
7026 if Is_Init_Proc (Spec_Id) | |
7027 or else Is_Controlled_Proc (Spec_Id, Name_Initialize) | |
7028 or else Is_TSS (Spec_Id, TSS_Deep_Initialize) | |
7029 then | |
7030 return True; | |
7031 end if; | |
7032 | |
7033 -- Prevent the search from going too far | |
7034 | |
7035 elsif Is_Body_Or_Package_Declaration (Par) then | |
7036 exit; | |
7037 end if; | |
7038 | |
7039 Par := Parent (Par); | |
7040 end loop; | |
7041 | |
7042 return False; | |
7043 end In_Initialization_Context; | |
7044 | |
7045 -- Local variables | |
7046 | |
7047 Check_OK : constant Boolean := | |
7048 not Call_Attrs.Ghost_Mode_Ignore | |
7049 and then not Target_Attrs.Ghost_Mode_Ignore | |
7050 and then Call_Attrs.Elab_Checks_OK | |
7051 and then Target_Attrs.Elab_Checks_OK; | |
7052 -- A run-time ABE check may be installed only when both the call and the | |
7053 -- target have active elaboration checks, and both are not ignored Ghost | |
7054 -- constructs. | |
7055 | |
7056 -- Start of processing for Process_Call_Ada | |
7057 | |
7058 begin | |
7059 -- Nothing to do for an Ada dispatching call because there are no ABE | |
7060 -- diagnostics for either models. ABE checks for the dynamic model are | |
7061 -- handled by Install_Primitive_Elaboration_Check. | |
7062 | |
7063 if Call_Attrs.Is_Dispatching then | |
7064 return; | |
7065 | |
7066 -- Nothing to do when the call is ABE-safe | |
7067 | |
7068 -- generic | |
7069 -- function Gen ...; | |
7070 | |
7071 -- function Gen ... is | |
7072 -- begin | |
7073 -- ... | |
7074 -- end Gen; | |
7075 | |
7076 -- with Gen; | |
7077 -- procedure Main is | |
7078 -- function Inst is new Gen; | |
7079 -- X : ... := Inst; -- safe call | |
7080 -- ... | |
7081 | |
7082 elsif Is_Safe_Call (Call, Target_Attrs) then | |
7083 return; | |
7084 | |
7085 -- The call and the target body are both in the main unit | |
7086 | |
7087 elsif Present (Target_Attrs.Body_Decl) | |
7088 and then In_Extended_Main_Code_Unit (Target_Attrs.Body_Decl) | |
7089 then | |
7090 Process_Call_Conditional_ABE | |
7091 (Call => Call, | |
7092 Call_Attrs => Call_Attrs, | |
7093 Target_Id => Target_Id, | |
7094 Target_Attrs => Target_Attrs); | |
7095 | |
7096 -- Otherwise the target body is not available in this compilation or it | |
7097 -- resides in an external unit. Install a run-time ABE check to verify | |
7098 -- that the target body has been elaborated prior to the call site when | |
7099 -- the dynamic model is in effect. | |
7100 | |
7101 elsif Dynamic_Elaboration_Checks and then Check_OK then | |
7102 Install_ABE_Check | |
7103 (N => Call, | |
7104 Ins_Nod => Call, | |
7105 Id => Target_Attrs.Unit_Id); | |
7106 end if; | |
7107 | |
7108 -- No implicit pragma Elaborate[_All] is generated when the call has | |
7109 -- elaboration checks suppressed. This behaviour parallels that of the | |
7110 -- old ABE mechanism. | |
7111 | |
7112 if not Call_Attrs.Elab_Checks_OK then | |
7113 null; | |
7114 | |
7115 -- No implicit pragma Elaborate[_All] is generated for finalization | |
7116 -- actions when primitive [Deep_]Finalize is not defined in the main | |
7117 -- unit and the call appears within some initialization actions. This | |
7118 -- behaviour parallels that of the old ABE mechanism. | |
7119 | |
7120 -- Performance note: parent traversal | |
7121 | |
7122 elsif (Is_Controlled_Proc (Target_Id, Name_Finalize) | |
7123 or else Is_TSS (Target_Id, TSS_Deep_Finalize)) | |
7124 and then not In_Extended_Main_Code_Unit (Target_Attrs.Spec_Decl) | |
7125 and then In_Initialization_Context (Call) | |
7126 then | |
7127 null; | |
7128 | |
7129 -- Otherwise ensure that the unit with the target body is elaborated | |
7130 -- prior to the main unit. | |
7131 | |
7132 else | |
7133 Ensure_Prior_Elaboration | |
7134 (N => Call, | |
7135 Unit_Id => Target_Attrs.Unit_Id, | |
7136 In_Task_Body => In_Task_Body); | |
7137 end if; | |
7138 end Process_Call_Ada; | |
7139 | |
7140 ---------------------------------- | |
7141 -- Process_Call_Conditional_ABE -- | |
7142 ---------------------------------- | |
7143 | |
7144 procedure Process_Call_Conditional_ABE | |
7145 (Call : Node_Id; | |
7146 Call_Attrs : Call_Attributes; | |
7147 Target_Id : Entity_Id; | |
7148 Target_Attrs : Target_Attributes) | |
7149 is | |
7150 Check_OK : constant Boolean := | |
7151 not Call_Attrs.Ghost_Mode_Ignore | |
7152 and then not Target_Attrs.Ghost_Mode_Ignore | |
7153 and then Call_Attrs.Elab_Checks_OK | |
7154 and then Target_Attrs.Elab_Checks_OK; | |
7155 -- A run-time ABE check may be installed only when both the call and the | |
7156 -- target have active elaboration checks, and both are not ignored Ghost | |
7157 -- constructs. | |
7158 | |
7159 Root : constant Node_Id := Root_Scenario; | |
7160 | |
7161 begin | |
7162 -- If the root scenario appears prior to the target body, then this is a | |
7163 -- possible ABE with respect to the root scenario. | |
7164 | |
7165 -- function B ...; | |
7166 | |
7167 -- function A ... is | |
7168 -- begin | |
7169 -- if Some_Condition then | |
7170 -- return B; -- call site | |
7171 -- ... | |
7172 -- end A; | |
7173 | |
7174 -- X : ... := A; -- root scenario | |
7175 | |
7176 -- function B ... is -- target body | |
7177 -- ... | |
7178 -- end B; | |
7179 | |
7180 -- Y : ... := A; -- root scenario | |
7181 | |
7182 -- IMPORTANT: The call to B from A is a possible ABE for X, but not for | |
7183 -- Y. Installing an unconditional ABE raise prior to the call to B would | |
7184 -- be wrong as it will fail for Y as well, but in Y's case the call to B | |
7185 -- is never an ABE. | |
7186 | |
7187 if Earlier_In_Extended_Unit (Root, Target_Attrs.Body_Decl) then | |
7188 | |
7189 -- ABE diagnostics are emitted only in the static model because there | |
7190 -- is a well-defined order to visiting scenarios. Without this order | |
7191 -- diagnostics appear jumbled and result in unwanted noise. | |
7192 | |
7193 if Static_Elaboration_Checks then | |
7194 Error_Msg_NE ("??cannot call & before body seen", Call, Target_Id); | |
7195 Error_Msg_N ("\Program_Error may be raised at run time", Call); | |
7196 | |
7197 Output_Active_Scenarios (Call); | |
7198 end if; | |
7199 | |
7200 -- Install a conditional run-time ABE check to verify that the target | |
7201 -- body has been elaborated prior to the call. | |
7202 | |
7203 if Check_OK then | |
7204 Install_ABE_Check | |
7205 (N => Call, | |
7206 Ins_Nod => Call, | |
7207 Target_Id => Target_Attrs.Spec_Id, | |
7208 Target_Decl => Target_Attrs.Spec_Decl, | |
7209 Target_Body => Target_Attrs.Body_Decl); | |
7210 end if; | |
7211 end if; | |
7212 end Process_Call_Conditional_ABE; | |
7213 | |
7214 --------------------------------- | |
7215 -- Process_Call_Guaranteed_ABE -- | |
7216 --------------------------------- | |
7217 | |
7218 procedure Process_Call_Guaranteed_ABE | |
7219 (Call : Node_Id; | |
7220 Call_Attrs : Call_Attributes; | |
7221 Target_Id : Entity_Id) | |
7222 is | |
7223 Target_Attrs : Target_Attributes; | |
7224 | |
7225 begin | |
7226 Extract_Target_Attributes | |
7227 (Target_Id => Target_Id, | |
7228 Attrs => Target_Attrs); | |
7229 | |
7230 -- Nothing to do when the root scenario appears at the declaration level | |
7231 -- and the target is in the same unit, but outside this context. | |
7232 | |
7233 -- function B ...; -- target declaration | |
7234 | |
7235 -- procedure Proc is | |
7236 -- function A ... is | |
7237 -- begin | |
7238 -- if Some_Condition then | |
7239 -- return B; -- call site | |
7240 -- ... | |
7241 -- end A; | |
7242 | |
7243 -- X : ... := A; -- root scenario | |
7244 -- ... | |
7245 | |
7246 -- function B ... is | |
7247 -- ... | |
7248 -- end B; | |
7249 | |
7250 -- In the example above, the context of X is the declarative region of | |
7251 -- Proc. The "elaboration" of X may eventually reach B which is defined | |
7252 -- outside of X's context. B is relevant only when Proc is invoked, but | |
7253 -- this happens only by means of "normal" elaboration, therefore B must | |
7254 -- not be considered if this is not the case. | |
7255 | |
7256 -- Performance note: parent traversal | |
7257 | |
7258 if Is_Up_Level_Target (Target_Attrs.Spec_Decl) then | |
7259 return; | |
7260 | |
7261 -- Nothing to do when the call is ABE-safe | |
7262 | |
7263 -- generic | |
7264 -- function Gen ...; | |
7265 | |
7266 -- function Gen ... is | |
7267 -- begin | |
7268 -- ... | |
7269 -- end Gen; | |
7270 | |
7271 -- with Gen; | |
7272 -- procedure Main is | |
7273 -- function Inst is new Gen; | |
7274 -- X : ... := Inst; -- safe call | |
7275 -- ... | |
7276 | |
7277 elsif Is_Safe_Call (Call, Target_Attrs) then | |
7278 return; | |
7279 | |
7280 -- A call leads to a guaranteed ABE when the call and the target appear | |
7281 -- within the same context ignoring library levels, and the body of the | |
7282 -- target has not been seen yet or appears after the call. | |
7283 | |
7284 -- procedure Guaranteed_ABE is | |
7285 -- function Func ...; | |
7286 | |
7287 -- package Nested is | |
7288 -- Obj : ... := Func; -- guaranteed ABE | |
7289 -- end Nested; | |
7290 | |
7291 -- function Func ... is | |
7292 -- ... | |
7293 -- end Func; | |
7294 -- ... | |
7295 | |
7296 -- Performance note: parent traversal | |
7297 | |
7298 elsif Is_Guaranteed_ABE | |
7299 (N => Call, | |
7300 Target_Decl => Target_Attrs.Spec_Decl, | |
7301 Target_Body => Target_Attrs.Body_Decl) | |
7302 then | |
7303 Error_Msg_NE ("??cannot call & before body seen", Call, Target_Id); | |
7304 Error_Msg_N ("\Program_Error will be raised at run time", Call); | |
7305 | |
7306 -- Mark the call as a guarnateed ABE | |
7307 | |
7308 Set_Is_Known_Guaranteed_ABE (Call); | |
7309 | |
7310 -- Install a run-time ABE failure because the call will always result | |
7311 -- in an ABE. The failure is installed when both the call and target | |
7312 -- have enabled elaboration checks, and both are not ignored Ghost | |
7313 -- constructs. | |
7314 | |
7315 if Call_Attrs.Elab_Checks_OK | |
7316 and then Target_Attrs.Elab_Checks_OK | |
7317 and then not Call_Attrs.Ghost_Mode_Ignore | |
7318 and then not Target_Attrs.Ghost_Mode_Ignore | |
7319 then | |
7320 Install_ABE_Failure | |
7321 (N => Call, | |
7322 Ins_Nod => Call); | |
7323 end if; | |
7324 end if; | |
7325 end Process_Call_Guaranteed_ABE; | |
7326 | |
7327 ------------------------ | |
7328 -- Process_Call_SPARK -- | |
7329 ------------------------ | |
7330 | |
7331 procedure Process_Call_SPARK | |
7332 (Call : Node_Id; | |
7333 Call_Attrs : Call_Attributes; | |
7334 Target_Id : Entity_Id; | |
7335 Target_Attrs : Target_Attributes) | |
7336 is | |
7337 begin | |
7338 -- A call to a source target or to a target which emulates Ada or SPARK | |
7339 -- semantics imposes an Elaborate_All requirement on the context of the | |
7340 -- main unit. Determine whether the context has a pragma strong enough | |
7341 -- to meet the requirement. The check is orthogonal to the ABE effects | |
7342 -- of the call. | |
7343 | |
7344 if Target_Attrs.From_Source | |
7345 or else Is_Ada_Semantic_Target (Target_Id) | |
7346 or else Is_SPARK_Semantic_Target (Target_Id) | |
7347 then | |
7348 Meet_Elaboration_Requirement | |
7349 (N => Call, | |
7350 Target_Id => Target_Id, | |
7351 Req_Nam => Name_Elaborate_All); | |
7352 end if; | |
7353 | |
7354 -- Nothing to do when the call is ABE-safe | |
7355 | |
7356 -- generic | |
7357 -- function Gen ...; | |
7358 | |
7359 -- function Gen ... is | |
7360 -- begin | |
7361 -- ... | |
7362 -- end Gen; | |
7363 | |
7364 -- with Gen; | |
7365 -- procedure Main is | |
7366 -- function Inst is new Gen; | |
7367 -- X : ... := Inst; -- safe call | |
7368 -- ... | |
7369 | |
7370 if Is_Safe_Call (Call, Target_Attrs) then | |
7371 return; | |
7372 | |
7373 -- The call and the target body are both in the main unit | |
7374 | |
7375 elsif Present (Target_Attrs.Body_Decl) | |
7376 and then In_Extended_Main_Code_Unit (Target_Attrs.Body_Decl) | |
7377 then | |
7378 Process_Call_Conditional_ABE | |
7379 (Call => Call, | |
7380 Call_Attrs => Call_Attrs, | |
7381 Target_Id => Target_Id, | |
7382 Target_Attrs => Target_Attrs); | |
7383 | |
7384 -- Otherwise the target body is not available in this compilation or it | |
7385 -- resides in an external unit. There is no need to guarantee the prior | |
7386 -- elaboration of the unit with the target body because either the main | |
7387 -- unit meets the Elaborate_All requirement imposed by the call, or the | |
7388 -- program is illegal. | |
7389 | |
7390 else | |
7391 null; | |
7392 end if; | |
7393 end Process_Call_SPARK; | |
7394 | |
7395 ---------------------------- | |
7396 -- Process_Guaranteed_ABE -- | |
7397 ---------------------------- | |
7398 | |
7399 procedure Process_Guaranteed_ABE (N : Node_Id) is | |
7400 Call_Attrs : Call_Attributes; | |
7401 Target_Id : Entity_Id; | |
7402 | |
7403 begin | |
7404 -- Add the current scenario to the stack of active scenarios | |
7405 | |
7406 Push_Active_Scenario (N); | |
7407 | |
7408 -- Only calls, instantiations, and task activations may result in a | |
7409 -- guaranteed ABE. | |
7410 | |
7411 if Is_Suitable_Call (N) then | |
7412 Extract_Call_Attributes | |
7413 (Call => N, | |
7414 Target_Id => Target_Id, | |
7415 Attrs => Call_Attrs); | |
7416 | |
7417 if Is_Activation_Proc (Target_Id) then | |
7418 Process_Activation_Guaranteed_ABE | |
7419 (Call => N, | |
7420 Call_Attrs => Call_Attrs, | |
7421 In_Task_Body => False); | |
7422 | |
7423 else | |
7424 Process_Call_Guaranteed_ABE | |
7425 (Call => N, | |
7426 Call_Attrs => Call_Attrs, | |
7427 Target_Id => Target_Id); | |
7428 end if; | |
7429 | |
7430 elsif Is_Suitable_Instantiation (N) then | |
7431 Process_Instantiation_Guaranteed_ABE (N); | |
7432 end if; | |
7433 | |
7434 -- Remove the current scenario from the stack of active scenarios once | |
7435 -- all ABE diagnostics and checks have been performed. | |
7436 | |
7437 Pop_Active_Scenario (N); | |
7438 end Process_Guaranteed_ABE; | |
7439 | |
7440 --------------------------- | |
7441 -- Process_Instantiation -- | |
7442 --------------------------- | |
7443 | |
7444 procedure Process_Instantiation | |
7445 (Exp_Inst : Node_Id; | |
7446 In_Task_Body : Boolean) | |
7447 is | |
7448 Gen_Attrs : Target_Attributes; | |
7449 Gen_Id : Entity_Id; | |
7450 Inst : Node_Id; | |
7451 Inst_Attrs : Instantiation_Attributes; | |
7452 Inst_Id : Entity_Id; | |
7453 | |
7454 SPARK_Rules_On : Boolean; | |
7455 -- This flag is set when the SPARK rules are in effect | |
7456 | |
7457 begin | |
7458 Extract_Instantiation_Attributes | |
7459 (Exp_Inst => Exp_Inst, | |
7460 Inst => Inst, | |
7461 Inst_Id => Inst_Id, | |
7462 Gen_Id => Gen_Id, | |
7463 Attrs => Inst_Attrs); | |
7464 | |
7465 Extract_Target_Attributes (Gen_Id, Gen_Attrs); | |
7466 | |
7467 -- The SPARK rules are in effect when both the instantiation and generic | |
7468 -- are subject to SPARK_Mode On. | |
7469 | |
7470 SPARK_Rules_On := Inst_Attrs.SPARK_Mode_On and Gen_Attrs.SPARK_Mode_On; | |
7471 | |
7472 -- Output relevant information when switch -gnatel (info messages on | |
7473 -- implicit Elaborate[_All] pragmas) is in effect. | |
7474 | |
7475 if Elab_Info_Messages then | |
7476 Info_Instantiation | |
7477 (Inst => Inst, | |
7478 Gen_Id => Gen_Id, | |
7479 Info_Msg => True, | |
7480 In_SPARK => SPARK_Rules_On); | |
7481 end if; | |
7482 | |
7483 -- Nothing to do when the instantiation is a guaranteed ABE | |
7484 | |
7485 if Is_Known_Guaranteed_ABE (Inst) then | |
7486 return; | |
7487 | |
7488 -- Nothing to do when the root scenario appears at the declaration level | |
7489 -- and the generic is in the same unit, but outside this context. | |
7490 | |
7491 -- generic | |
7492 -- procedure Gen is ...; -- generic declaration | |
7493 | |
7494 -- procedure Proc is | |
7495 -- function A ... is | |
7496 -- begin | |
7497 -- if Some_Condition then | |
7498 -- declare | |
7499 -- procedure I is new Gen; -- instantiation site | |
7500 -- ... | |
7501 -- ... | |
7502 -- end A; | |
7503 | |
7504 -- X : ... := A; -- root scenario | |
7505 -- ... | |
7506 | |
7507 -- procedure Gen is | |
7508 -- ... | |
7509 -- end Gen; | |
7510 | |
7511 -- In the example above, the context of X is the declarative region of | |
7512 -- Proc. The "elaboration" of X may eventually reach Gen which appears | |
7513 -- outside of X's context. Gen is relevant only when Proc is invoked, | |
7514 -- but this happens only by means of "normal" elaboration, therefore | |
7515 -- Gen must not be considered if this is not the case. | |
7516 | |
7517 -- Performance note: parent traversal | |
7518 | |
7519 elsif Is_Up_Level_Target (Gen_Attrs.Spec_Decl) then | |
7520 return; | |
7521 | |
7522 -- The SPARK rules are verified only when -gnatd.v (enforce SPARK | |
7523 -- elaboration rules in SPARK code) is in effect. | |
7524 | |
7525 elsif SPARK_Rules_On and Debug_Flag_Dot_V then | |
7526 Process_Instantiation_SPARK | |
7527 (Exp_Inst => Exp_Inst, | |
7528 Inst => Inst, | |
7529 Inst_Attrs => Inst_Attrs, | |
7530 Gen_Id => Gen_Id, | |
7531 Gen_Attrs => Gen_Attrs); | |
7532 | |
7533 -- Otherwise the Ada rules are in effect, or SPARK code is allowed to | |
7534 -- violate the SPARK rules. | |
7535 | |
7536 else | |
7537 Process_Instantiation_Ada | |
7538 (Exp_Inst => Exp_Inst, | |
7539 Inst => Inst, | |
7540 Inst_Attrs => Inst_Attrs, | |
7541 Gen_Id => Gen_Id, | |
7542 Gen_Attrs => Gen_Attrs, | |
7543 In_Task_Body => In_Task_Body); | |
7544 end if; | |
7545 end Process_Instantiation; | |
7546 | |
7547 ------------------------------- | |
7548 -- Process_Instantiation_Ada -- | |
7549 ------------------------------- | |
7550 | |
7551 procedure Process_Instantiation_Ada | |
7552 (Exp_Inst : Node_Id; | |
7553 Inst : Node_Id; | |
7554 Inst_Attrs : Instantiation_Attributes; | |
7555 Gen_Id : Entity_Id; | |
7556 Gen_Attrs : Target_Attributes; | |
7557 In_Task_Body : Boolean) | |
7558 is | |
7559 Check_OK : constant Boolean := | |
7560 not Inst_Attrs.Ghost_Mode_Ignore | |
7561 and then not Gen_Attrs.Ghost_Mode_Ignore | |
7562 and then Inst_Attrs.Elab_Checks_OK | |
7563 and then Gen_Attrs.Elab_Checks_OK; | |
7564 -- A run-time ABE check may be installed only when both the instance and | |
7565 -- the generic have active elaboration checks and both are not ignored | |
7566 -- Ghost constructs. | |
7567 | |
7568 begin | |
7569 -- Nothing to do when the instantiation is ABE-safe | |
7570 | |
7571 -- generic | |
7572 -- package Gen is | |
7573 -- ... | |
7574 -- end Gen; | |
7575 | |
7576 -- package body Gen is | |
7577 -- ... | |
7578 -- end Gen; | |
7579 | |
7580 -- with Gen; | |
7581 -- procedure Main is | |
7582 -- package Inst is new Gen (ABE); -- safe instantiation | |
7583 -- ... | |
7584 | |
7585 if Is_Safe_Instantiation (Inst, Gen_Attrs) then | |
7586 return; | |
7587 | |
7588 -- The instantiation and the generic body are both in the main unit | |
7589 | |
7590 elsif Present (Gen_Attrs.Body_Decl) | |
7591 and then In_Extended_Main_Code_Unit (Gen_Attrs.Body_Decl) | |
7592 then | |
7593 Process_Instantiation_Conditional_ABE | |
7594 (Exp_Inst => Exp_Inst, | |
7595 Inst => Inst, | |
7596 Inst_Attrs => Inst_Attrs, | |
7597 Gen_Id => Gen_Id, | |
7598 Gen_Attrs => Gen_Attrs); | |
7599 | |
7600 -- Otherwise the generic body is not available in this compilation or it | |
7601 -- resides in an external unit. Install a run-time ABE check to verify | |
7602 -- that the generic body has been elaborated prior to the instantiation | |
7603 -- when the dynamic model is in effect. | |
7604 | |
7605 elsif Dynamic_Elaboration_Checks and then Check_OK then | |
7606 Install_ABE_Check | |
7607 (N => Inst, | |
7608 Ins_Nod => Exp_Inst, | |
7609 Id => Gen_Attrs.Unit_Id); | |
7610 end if; | |
7611 | |
7612 -- Ensure that the unit with the generic body is elaborated prior to | |
7613 -- the main unit. No implicit pragma Elaborate[_All] is generated if | |
7614 -- the instantiation has elaboration checks suppressed. This behaviour | |
7615 -- parallels that of the old ABE mechanism. | |
7616 | |
7617 if Inst_Attrs.Elab_Checks_OK then | |
7618 Ensure_Prior_Elaboration | |
7619 (N => Inst, | |
7620 Unit_Id => Gen_Attrs.Unit_Id, | |
7621 In_Task_Body => In_Task_Body); | |
7622 end if; | |
7623 end Process_Instantiation_Ada; | |
7624 | |
7625 ------------------------------------------- | |
7626 -- Process_Instantiation_Conditional_ABE -- | |
7627 ------------------------------------------- | |
7628 | |
7629 procedure Process_Instantiation_Conditional_ABE | |
7630 (Exp_Inst : Node_Id; | |
7631 Inst : Node_Id; | |
7632 Inst_Attrs : Instantiation_Attributes; | |
7633 Gen_Id : Entity_Id; | |
7634 Gen_Attrs : Target_Attributes) | |
7635 is | |
7636 Check_OK : constant Boolean := | |
7637 not Inst_Attrs.Ghost_Mode_Ignore | |
7638 and then not Gen_Attrs.Ghost_Mode_Ignore | |
7639 and then Inst_Attrs.Elab_Checks_OK | |
7640 and then Gen_Attrs.Elab_Checks_OK; | |
7641 -- A run-time ABE check may be installed only when both the instance and | |
7642 -- the generic have active elaboration checks and both are not ignored | |
7643 -- Ghost constructs. | |
7644 | |
7645 Root : constant Node_Id := Root_Scenario; | |
7646 | |
7647 begin | |
7648 -- If the root scenario appears prior to the generic body, then this is | |
7649 -- a possible ABE with respect to the root scenario. | |
7650 | |
7651 -- generic | |
7652 -- package Gen is | |
7653 -- ... | |
7654 -- end Gen; | |
7655 | |
7656 -- function A ... is | |
7657 -- begin | |
7658 -- if Some_Condition then | |
7659 -- declare | |
7660 -- package Inst is new Gen; -- instantiation site | |
7661 -- ... | |
7662 -- end A; | |
7663 | |
7664 -- X : ... := A; -- root scenario | |
7665 | |
7666 -- package body Gen is -- generic body | |
7667 -- ... | |
7668 -- end Gen; | |
7669 | |
7670 -- Y : ... := A; -- root scenario | |
7671 | |
7672 -- IMPORTANT: The instantiation of Gen is a possible ABE for X, but not | |
7673 -- for Y. Installing an unconditional ABE raise prior to the instance | |
7674 -- site would be wrong as it will fail for Y as well, but in Y's case | |
7675 -- the instantiation of Gen is never an ABE. | |
7676 | |
7677 if Earlier_In_Extended_Unit (Root, Gen_Attrs.Body_Decl) then | |
7678 | |
7679 -- ABE diagnostics are emitted only in the static model because there | |
7680 -- is a well-defined order to visiting scenarios. Without this order | |
7681 -- diagnostics appear jumbled and result in unwanted noise. | |
7682 | |
7683 if Static_Elaboration_Checks then | |
7684 Error_Msg_NE | |
7685 ("??cannot instantiate & before body seen", Inst, Gen_Id); | |
7686 Error_Msg_N ("\Program_Error may be raised at run time", Inst); | |
7687 | |
7688 Output_Active_Scenarios (Inst); | |
7689 end if; | |
7690 | |
7691 -- Install a conditional run-time ABE check to verify that the | |
7692 -- generic body has been elaborated prior to the instantiation. | |
7693 | |
7694 if Check_OK then | |
7695 Install_ABE_Check | |
7696 (N => Inst, | |
7697 Ins_Nod => Exp_Inst, | |
7698 Target_Id => Gen_Attrs.Spec_Id, | |
7699 Target_Decl => Gen_Attrs.Spec_Decl, | |
7700 Target_Body => Gen_Attrs.Body_Decl); | |
7701 end if; | |
7702 end if; | |
7703 end Process_Instantiation_Conditional_ABE; | |
7704 | |
7705 ------------------------------------------ | |
7706 -- Process_Instantiation_Guaranteed_ABE -- | |
7707 ------------------------------------------ | |
7708 | |
7709 procedure Process_Instantiation_Guaranteed_ABE (Exp_Inst : Node_Id) is | |
7710 Gen_Attrs : Target_Attributes; | |
7711 Gen_Id : Entity_Id; | |
7712 Inst : Node_Id; | |
7713 Inst_Attrs : Instantiation_Attributes; | |
7714 Inst_Id : Entity_Id; | |
7715 | |
7716 begin | |
7717 Extract_Instantiation_Attributes | |
7718 (Exp_Inst => Exp_Inst, | |
7719 Inst => Inst, | |
7720 Inst_Id => Inst_Id, | |
7721 Gen_Id => Gen_Id, | |
7722 Attrs => Inst_Attrs); | |
7723 | |
7724 Extract_Target_Attributes (Gen_Id, Gen_Attrs); | |
7725 | |
7726 -- Nothing to do when the root scenario appears at the declaration level | |
7727 -- and the generic is in the same unit, but outside this context. | |
7728 | |
7729 -- generic | |
7730 -- procedure Gen is ...; -- generic declaration | |
7731 | |
7732 -- procedure Proc is | |
7733 -- function A ... is | |
7734 -- begin | |
7735 -- if Some_Condition then | |
7736 -- declare | |
7737 -- procedure I is new Gen; -- instantiation site | |
7738 -- ... | |
7739 -- ... | |
7740 -- end A; | |
7741 | |
7742 -- X : ... := A; -- root scenario | |
7743 -- ... | |
7744 | |
7745 -- procedure Gen is | |
7746 -- ... | |
7747 -- end Gen; | |
7748 | |
7749 -- In the example above, the context of X is the declarative region of | |
7750 -- Proc. The "elaboration" of X may eventually reach Gen which appears | |
7751 -- outside of X's context. Gen is relevant only when Proc is invoked, | |
7752 -- but this happens only by means of "normal" elaboration, therefore | |
7753 -- Gen must not be considered if this is not the case. | |
7754 | |
7755 -- Performance note: parent traversal | |
7756 | |
7757 if Is_Up_Level_Target (Gen_Attrs.Spec_Decl) then | |
7758 return; | |
7759 | |
7760 -- Nothing to do when the instantiation is ABE-safe | |
7761 | |
7762 -- generic | |
7763 -- package Gen is | |
7764 -- ... | |
7765 -- end Gen; | |
7766 | |
7767 -- package body Gen is | |
7768 -- ... | |
7769 -- end Gen; | |
7770 | |
7771 -- with Gen; | |
7772 -- procedure Main is | |
7773 -- package Inst is new Gen (ABE); -- safe instantiation | |
7774 -- ... | |
7775 | |
7776 elsif Is_Safe_Instantiation (Inst, Gen_Attrs) then | |
7777 return; | |
7778 | |
7779 -- An instantiation leads to a guaranteed ABE when the instantiation and | |
7780 -- the generic appear within the same context ignoring library levels, | |
7781 -- and the body of the generic has not been seen yet or appears after | |
7782 -- the instantiation. | |
7783 | |
7784 -- procedure Guaranteed_ABE is | |
7785 -- generic | |
7786 -- procedure Gen; | |
7787 | |
7788 -- package Nested is | |
7789 -- procedure Inst is new Gen; -- guaranteed ABE | |
7790 -- end Nested; | |
7791 | |
7792 -- procedure Gen is | |
7793 -- ... | |
7794 -- end Gen; | |
7795 -- ... | |
7796 | |
7797 -- Performance note: parent traversal | |
7798 | |
7799 elsif Is_Guaranteed_ABE | |
7800 (N => Inst, | |
7801 Target_Decl => Gen_Attrs.Spec_Decl, | |
7802 Target_Body => Gen_Attrs.Body_Decl) | |
7803 then | |
7804 Error_Msg_NE | |
7805 ("??cannot instantiate & before body seen", Inst, Gen_Id); | |
7806 Error_Msg_N ("\Program_Error will be raised at run time", Inst); | |
7807 | |
7808 -- Mark the instantiation as a guarantee ABE. This automatically | |
7809 -- suppresses the instantiation of the generic body. | |
7810 | |
7811 Set_Is_Known_Guaranteed_ABE (Inst); | |
7812 | |
7813 -- Install a run-time ABE failure because the instantiation will | |
7814 -- always result in an ABE. The failure is installed when both the | |
7815 -- instance and the generic have enabled elaboration checks, and both | |
7816 -- are not ignored Ghost constructs. | |
7817 | |
7818 if Inst_Attrs.Elab_Checks_OK | |
7819 and then Gen_Attrs.Elab_Checks_OK | |
7820 and then not Inst_Attrs.Ghost_Mode_Ignore | |
7821 and then not Gen_Attrs.Ghost_Mode_Ignore | |
7822 then | |
7823 Install_ABE_Failure | |
7824 (N => Inst, | |
7825 Ins_Nod => Exp_Inst); | |
7826 end if; | |
7827 end if; | |
7828 end Process_Instantiation_Guaranteed_ABE; | |
7829 | |
7830 --------------------------------- | |
7831 -- Process_Instantiation_SPARK -- | |
7832 --------------------------------- | |
7833 | |
7834 procedure Process_Instantiation_SPARK | |
7835 (Exp_Inst : Node_Id; | |
7836 Inst : Node_Id; | |
7837 Inst_Attrs : Instantiation_Attributes; | |
7838 Gen_Id : Entity_Id; | |
7839 Gen_Attrs : Target_Attributes) | |
7840 is | |
7841 Req_Nam : Name_Id; | |
7842 | |
7843 begin | |
7844 -- A source instantiation imposes an Elaborate[_All] requirement on the | |
7845 -- context of the main unit. Determine whether the context has a pragma | |
7846 -- strong enough to meet the requirement. The check is orthogonal to the | |
7847 -- ABE ramifications of the instantiation. | |
7848 | |
7849 if Nkind (Inst) = N_Package_Instantiation then | |
7850 Req_Nam := Name_Elaborate_All; | |
7851 else | |
7852 Req_Nam := Name_Elaborate; | |
7853 end if; | |
7854 | |
7855 Meet_Elaboration_Requirement | |
7856 (N => Inst, | |
7857 Target_Id => Gen_Id, | |
7858 Req_Nam => Req_Nam); | |
7859 | |
7860 -- Nothing to do when the instantiation is ABE-safe | |
7861 | |
7862 -- generic | |
7863 -- package Gen is | |
7864 -- ... | |
7865 -- end Gen; | |
7866 | |
7867 -- package body Gen is | |
7868 -- ... | |
7869 -- end Gen; | |
7870 | |
7871 -- with Gen; | |
7872 -- procedure Main is | |
7873 -- package Inst is new Gen (ABE); -- safe instantiation | |
7874 -- ... | |
7875 | |
7876 if Is_Safe_Instantiation (Inst, Gen_Attrs) then | |
7877 return; | |
7878 | |
7879 -- The instantiation and the generic body are both in the main unit | |
7880 | |
7881 elsif Present (Gen_Attrs.Body_Decl) | |
7882 and then In_Extended_Main_Code_Unit (Gen_Attrs.Body_Decl) | |
7883 then | |
7884 Process_Instantiation_Conditional_ABE | |
7885 (Exp_Inst => Exp_Inst, | |
7886 Inst => Inst, | |
7887 Inst_Attrs => Inst_Attrs, | |
7888 Gen_Id => Gen_Id, | |
7889 Gen_Attrs => Gen_Attrs); | |
7890 | |
7891 -- Otherwise the generic body is not available in this compilation or | |
7892 -- it resides in an external unit. There is no need to guarantee the | |
7893 -- prior elaboration of the unit with the generic body because either | |
7894 -- the main unit meets the Elaborate[_All] requirement imposed by the | |
7895 -- instantiation, or the program is illegal. | |
7896 | |
7897 else | |
7898 null; | |
7899 end if; | |
7900 end Process_Instantiation_SPARK; | |
7901 | |
7902 --------------------------------- | |
7903 -- Process_Variable_Assignment -- | |
7904 --------------------------------- | |
7905 | |
7906 procedure Process_Variable_Assignment (Asmt : Node_Id) is | |
7907 Var_Id : constant Entity_Id := Entity (Extract_Assignment_Name (Asmt)); | |
7908 Prag : constant Node_Id := SPARK_Pragma (Var_Id); | |
7909 | |
7910 SPARK_Rules_On : Boolean; | |
7911 -- This flag is set when the SPARK rules are in effect | |
7912 | |
7913 begin | |
7914 -- The SPARK rules are in effect when both the assignment and the | |
7915 -- variable are subject to SPARK_Mode On. | |
7916 | |
7917 SPARK_Rules_On := | |
7918 Present (Prag) | |
7919 and then Get_SPARK_Mode_From_Annotation (Prag) = On | |
7920 and then Is_SPARK_Mode_On_Node (Asmt); | |
7921 | |
7922 -- Output relevant information when switch -gnatel (info messages on | |
7923 -- implicit Elaborate[_All] pragmas) is in effect. | |
7924 | |
7925 if Elab_Info_Messages then | |
7926 Elab_Msg_NE | |
7927 (Msg => "assignment to & during elaboration", | |
7928 N => Asmt, | |
7929 Id => Var_Id, | |
7930 Info_Msg => True, | |
7931 In_SPARK => SPARK_Rules_On); | |
7932 end if; | |
7933 | |
7934 -- The SPARK rules are in effect. These rules are applied regardless of | |
7935 -- whether -gnatd.v (enforce SPARK elaboration rules in SPARK code) is | |
7936 -- in effect because the static model cannot ensure safe assignment of | |
7937 -- variables. | |
7938 | |
7939 if SPARK_Rules_On then | |
7940 Process_Variable_Assignment_SPARK | |
7941 (Asmt => Asmt, | |
7942 Var_Id => Var_Id); | |
7943 | |
7944 -- Otherwise the Ada rules are in effect | |
7945 | |
7946 else | |
7947 Process_Variable_Assignment_Ada | |
7948 (Asmt => Asmt, | |
7949 Var_Id => Var_Id); | |
7950 end if; | |
7951 end Process_Variable_Assignment; | |
7952 | |
7953 ------------------------------------- | |
7954 -- Process_Variable_Assignment_Ada -- | |
7955 ------------------------------------- | |
7956 | |
7957 procedure Process_Variable_Assignment_Ada | |
7958 (Asmt : Node_Id; | |
7959 Var_Id : Entity_Id) | |
7960 is | |
7961 Var_Decl : constant Node_Id := Declaration_Node (Var_Id); | |
7962 Spec_Id : constant Entity_Id := Find_Top_Unit (Var_Decl); | |
7963 | |
7964 begin | |
7965 -- Emit a warning when an uninitialized variable declared in a package | |
7966 -- spec without a pragma Elaborate_Body is initialized by elaboration | |
7967 -- code within the corresponding body. | |
7968 | |
7969 if not Warnings_Off (Var_Id) | |
7970 and then not Is_Initialized (Var_Decl) | |
7971 and then not Has_Pragma_Elaborate_Body (Spec_Id) | |
7972 then | |
7973 -- Generate an implicit Elaborate_Body in the spec | |
7974 | |
7975 Set_Elaborate_Body_Desirable (Spec_Id); | |
7976 | |
7977 Error_Msg_NE | |
7978 ("??variable & can be accessed by clients before this " | |
7979 & "initialization", Asmt, Var_Id); | |
7980 | |
7981 Error_Msg_NE | |
7982 ("\add pragma ""Elaborate_Body"" to spec & to ensure proper " | |
7983 & "initialization", Asmt, Spec_Id); | |
7984 | |
7985 Output_Active_Scenarios (Asmt); | |
7986 end if; | |
7987 end Process_Variable_Assignment_Ada; | |
7988 | |
7989 --------------------------------------- | |
7990 -- Process_Variable_Assignment_SPARK -- | |
7991 --------------------------------------- | |
7992 | |
7993 procedure Process_Variable_Assignment_SPARK | |
7994 (Asmt : Node_Id; | |
7995 Var_Id : Entity_Id) | |
7996 is | |
7997 Var_Decl : constant Node_Id := Declaration_Node (Var_Id); | |
7998 Spec_Id : constant Entity_Id := Find_Top_Unit (Var_Decl); | |
7999 | |
8000 begin | |
8001 -- Emit an error when an initialized variable declared in a package spec | |
8002 -- without pragma Elaborate_Body is further modified by elaboration code | |
8003 -- within the corresponding body. | |
8004 | |
8005 if Is_Initialized (Var_Decl) | |
8006 and then not Has_Pragma_Elaborate_Body (Spec_Id) | |
8007 then | |
8008 Error_Msg_NE | |
8009 ("variable & modified by elaboration code in package body", | |
8010 Asmt, Var_Id); | |
8011 | |
8012 Error_Msg_NE | |
8013 ("\add pragma ""Elaborate_Body"" to spec & to ensure full " | |
8014 & "initialization", Asmt, Spec_Id); | |
8015 | |
8016 Output_Active_Scenarios (Asmt); | |
8017 end if; | |
8018 end Process_Variable_Assignment_SPARK; | |
8019 | |
8020 --------------------------- | |
8021 -- Process_Variable_Read -- | |
8022 --------------------------- | |
8023 | |
8024 procedure Process_Variable_Read (Ref : Node_Id) is | |
8025 Var_Attrs : Variable_Attributes; | |
8026 Var_Id : Entity_Id; | |
8027 | |
8028 begin | |
8029 Extract_Variable_Reference_Attributes | |
8030 (Ref => Ref, | |
8031 Var_Id => Var_Id, | |
8032 Attrs => Var_Attrs); | |
8033 | |
8034 -- Output relevant information when switch -gnatel (info messages on | |
8035 -- implicit Elaborate[_All] pragmas) is in effect. | |
8036 | |
8037 if Elab_Info_Messages then | |
8038 Elab_Msg_NE | |
8039 (Msg => "read of variable & during elaboration", | |
8040 N => Ref, | |
8041 Id => Var_Id, | |
8042 Info_Msg => True, | |
8043 In_SPARK => True); | |
8044 end if; | |
8045 | |
8046 -- Nothing to do when the variable appears within the main unit because | |
8047 -- diagnostics on reads are relevant only for external variables. | |
8048 | |
8049 if Is_Same_Unit (Var_Attrs.Unit_Id, Cunit_Entity (Main_Unit)) then | |
8050 null; | |
8051 | |
8052 -- Nothing to do when the variable is already initialized. Note that the | |
8053 -- variable may be further modified by the external unit. | |
8054 | |
8055 elsif Is_Initialized (Declaration_Node (Var_Id)) then | |
8056 null; | |
8057 | |
8058 -- Nothing to do when the external unit guarantees the initialization of | |
8059 -- the variable by means of pragma Elaborate_Body. | |
8060 | |
8061 elsif Has_Pragma_Elaborate_Body (Var_Attrs.Unit_Id) then | |
8062 null; | |
8063 | |
8064 -- A variable read imposes an Elaborate requirement on the context of | |
8065 -- the main unit. Determine whether the context has a pragma strong | |
8066 -- enough to meet the requirement. | |
8067 | |
8068 else | |
8069 Meet_Elaboration_Requirement | |
8070 (N => Ref, | |
8071 Target_Id => Var_Id, | |
8072 Req_Nam => Name_Elaborate); | |
8073 end if; | |
8074 end Process_Variable_Read; | |
8075 | |
8076 -------------------------- | |
8077 -- Push_Active_Scenario -- | |
8078 -------------------------- | |
8079 | |
8080 procedure Push_Active_Scenario (N : Node_Id) is | |
8081 begin | |
8082 Scenario_Stack.Append (N); | |
8083 end Push_Active_Scenario; | |
8084 | |
8085 ---------------------- | |
8086 -- Process_Scenario -- | |
8087 ---------------------- | |
8088 | |
8089 procedure Process_Scenario (N : Node_Id; In_Task_Body : Boolean := False) is | |
8090 Call_Attrs : Call_Attributes; | |
8091 Target_Id : Entity_Id; | |
8092 | |
8093 begin | |
8094 -- Add the current scenario to the stack of active scenarios | |
8095 | |
8096 Push_Active_Scenario (N); | |
8097 | |
8098 -- 'Access | |
8099 | |
8100 if Is_Suitable_Access (N) then | |
8101 Process_Access (N, In_Task_Body); | |
8102 | |
8103 -- Calls | |
8104 | |
8105 elsif Is_Suitable_Call (N) then | |
8106 | |
8107 -- In general, only calls found within the main unit are processed | |
8108 -- because the ALI information supplied to binde is for the main | |
8109 -- unit only. However, to preserve the consistency of the tree and | |
8110 -- ensure proper serialization of internal names, external calls | |
8111 -- also receive corresponding call markers (see Build_Call_Marker). | |
8112 -- Regardless of the reason, external calls must not be processed. | |
8113 | |
8114 if In_Main_Context (N) then | |
8115 Extract_Call_Attributes | |
8116 (Call => N, | |
8117 Target_Id => Target_Id, | |
8118 Attrs => Call_Attrs); | |
8119 | |
8120 if Is_Activation_Proc (Target_Id) then | |
8121 Process_Activation_Conditional_ABE | |
8122 (Call => N, | |
8123 Call_Attrs => Call_Attrs, | |
8124 In_Task_Body => In_Task_Body); | |
8125 | |
8126 else | |
8127 Process_Call | |
8128 (Call => N, | |
8129 Call_Attrs => Call_Attrs, | |
8130 Target_Id => Target_Id, | |
8131 In_Task_Body => In_Task_Body); | |
8132 end if; | |
8133 end if; | |
8134 | |
8135 -- Instantiations | |
8136 | |
8137 elsif Is_Suitable_Instantiation (N) then | |
8138 Process_Instantiation (N, In_Task_Body); | |
8139 | |
8140 -- Variable assignments | |
8141 | |
8142 elsif Is_Suitable_Variable_Assignment (N) then | |
8143 Process_Variable_Assignment (N); | |
8144 | |
8145 -- Variable read | |
8146 | |
8147 elsif Is_Suitable_Variable_Read (N) then | |
8148 Process_Variable_Read (N); | |
8149 end if; | |
8150 | |
8151 -- Remove the current scenario from the stack of active scenarios once | |
8152 -- all ABE diagnostics and checks have been performed. | |
8153 | |
8154 Pop_Active_Scenario (N); | |
8155 end Process_Scenario; | |
8156 | |
8157 --------------------------------- | |
8158 -- Record_Elaboration_Scenario -- | |
8159 --------------------------------- | |
8160 | |
8161 procedure Record_Elaboration_Scenario (N : Node_Id) is | |
8162 Level : Enclosing_Level_Kind; | |
8163 | |
8164 Declaration_Level_OK : Boolean; | |
8165 -- This flag is set when a particular scenario is allowed to appear at | |
8166 -- the declaration level. | |
8167 | |
8168 begin | |
8169 -- Assume that the scenario must not appear at the declaration level | |
8170 | |
8171 Declaration_Level_OK := False; | |
8172 | |
8173 -- Nothing to do for ASIS. As a result, no ABE checks and diagnostics | |
8174 -- are performed in this mode. | |
8175 | |
8176 if ASIS_Mode then | |
8177 return; | |
8178 | |
8179 -- Nothing to do when the scenario is being preanalyzed | |
8180 | |
8181 elsif Preanalysis_Active then | |
8182 return; | |
8183 end if; | |
8184 | |
8185 -- Ensure that a library level call does not appear in a preelaborated | |
8186 -- unit. The check must come before ignoring scenarios within external | |
8187 -- units or inside generics because calls in those context must also be | |
8188 -- verified. | |
8189 | |
8190 if Is_Suitable_Call (N) then | |
8191 Check_Preelaborated_Call (N); | |
8192 end if; | |
8193 | |
8194 -- Nothing to do when the scenario does not appear within the main unit | |
8195 | |
8196 if not In_Main_Context (N) then | |
8197 return; | |
8198 | |
8199 -- Scenarios within a generic unit are never considered because generics | |
8200 -- cannot be elaborated. | |
8201 | |
8202 elsif Inside_A_Generic then | |
8203 return; | |
8204 | |
8205 -- Scenarios which do not fall in one of the elaboration categories | |
8206 -- listed below are not considered. The categories are: | |
8207 | |
8208 -- 'Access for entries, operators, and subprograms | |
8209 -- Assignments to variables | |
8210 -- Calls (includes task activation) | |
8211 -- Instantiations | |
8212 -- Reads of variables | |
8213 | |
8214 elsif Is_Suitable_Access (N) then | |
8215 | |
8216 -- Signal any enclosing local exception handlers that the 'Access may | |
8217 -- raise Program_Error due to a failed ABE check when switch -gnatd.o | |
8218 -- (conservative elaboration order for indirect calls) is in effect. | |
8219 -- Marking the exception handlers ensures proper expansion by both | |
8220 -- the front and back end restriction when No_Exception_Propagation | |
8221 -- is in effect. | |
8222 | |
8223 if Debug_Flag_Dot_O then | |
8224 Possible_Local_Raise (N, Standard_Program_Error); | |
8225 end if; | |
8226 | |
8227 elsif Is_Suitable_Call (N) or else Is_Suitable_Instantiation (N) then | |
8228 Declaration_Level_OK := True; | |
8229 | |
8230 -- Signal any enclosing local exception handlers that the call or | |
8231 -- instantiation may raise Program_Error due to a failed ABE check. | |
8232 -- Marking the exception handlers ensures proper expansion by both | |
8233 -- the front and back end restriction when No_Exception_Propagation | |
8234 -- is in effect. | |
8235 | |
8236 Possible_Local_Raise (N, Standard_Program_Error); | |
8237 | |
8238 elsif Is_Suitable_Variable_Assignment (N) | |
8239 or else Is_Suitable_Variable_Read (N) | |
8240 then | |
8241 null; | |
8242 | |
8243 -- Otherwise the input does not denote a suitable scenario | |
8244 | |
8245 else | |
8246 return; | |
8247 end if; | |
8248 | |
8249 -- The static model imposes additional restrictions on the placement of | |
8250 -- scenarios. In contrast, the dynamic model assumes that every scenario | |
8251 -- will be elaborated or invoked at some point. | |
8252 | |
8253 if Static_Elaboration_Checks then | |
8254 | |
8255 -- Performance note: parent traversal | |
8256 | |
8257 Level := Find_Enclosing_Level (N); | |
8258 | |
8259 -- Declaration level scenario | |
8260 | |
8261 if Declaration_Level_OK and then Level = Declaration_Level then | |
8262 null; | |
8263 | |
8264 -- Library level scenario | |
8265 | |
8266 elsif Level in Library_Level then | |
8267 null; | |
8268 | |
8269 -- Instantiation library level scenario | |
8270 | |
8271 elsif Level = Instantiation then | |
8272 null; | |
8273 | |
8274 -- Otherwise the scenario does not appear at the proper level and | |
8275 -- cannot possibly act as a top level scenario. | |
8276 | |
8277 else | |
8278 return; | |
8279 end if; | |
8280 end if; | |
8281 | |
8282 -- Perform early detection of guaranteed ABEs in order to suppress the | |
8283 -- instantiation of generic bodies as gigi cannot handle certain types | |
8284 -- of premature instantiations. | |
8285 | |
8286 Process_Guaranteed_ABE (N); | |
8287 | |
8288 -- At this point all checks have been performed. Record the scenario for | |
8289 -- later processing by the ABE phase. | |
8290 | |
8291 Top_Level_Scenarios.Append (N); | |
8292 | |
8293 -- Mark a scenario which may produce run-time conditional ABE checks or | |
8294 -- guaranteed ABE failures as recorded. The flag ensures that scenario | |
8295 -- rewriting performed by Atree.Rewrite will be properly reflected in | |
8296 -- all relevant internal data structures. | |
8297 | |
8298 if Is_Check_Emitting_Scenario (N) then | |
8299 Set_Is_Recorded_Scenario (N); | |
8300 end if; | |
8301 end Record_Elaboration_Scenario; | |
8302 | |
8303 ------------------- | |
8304 -- Root_Scenario -- | |
8305 ------------------- | |
8306 | |
8307 function Root_Scenario return Node_Id is | |
8308 package Stack renames Scenario_Stack; | |
8309 | |
8310 begin | |
8311 -- Ensure that the scenario stack has at least one active scenario in | |
8312 -- it. The one at the bottom (index First) is the root scenario. | |
8313 | |
8314 pragma Assert (Stack.Last >= Stack.First); | |
8315 return Stack.Table (Stack.First); | |
8316 end Root_Scenario; | |
8317 | |
8318 ------------------------------- | |
8319 -- Static_Elaboration_Checks -- | |
8320 ------------------------------- | |
8321 | |
8322 function Static_Elaboration_Checks return Boolean is | |
8323 begin | |
8324 return not Dynamic_Elaboration_Checks; | |
8325 end Static_Elaboration_Checks; | |
8326 | |
8327 ------------------- | |
8328 -- Traverse_Body -- | |
8329 ------------------- | |
8330 | |
8331 procedure Traverse_Body (N : Node_Id; In_Task_Body : Boolean) is | |
8332 function Is_Potential_Scenario (Nod : Node_Id) return Traverse_Result; | |
8333 -- Determine whether arbitrary node Nod denotes a suitable scenario and | |
8334 -- if so, process it. | |
8335 | |
8336 procedure Traverse_Potential_Scenarios is | |
8337 new Traverse_Proc (Is_Potential_Scenario); | |
8338 | |
8339 procedure Traverse_List (List : List_Id); | |
8340 -- Inspect list List for suitable elaboration scenarios and process them | |
8341 | |
8342 --------------------------- | |
8343 -- Is_Potential_Scenario -- | |
8344 --------------------------- | |
8345 | |
8346 function Is_Potential_Scenario (Nod : Node_Id) return Traverse_Result is | |
8347 begin | |
8348 -- Special cases | |
8349 | |
8350 -- Skip constructs which do not have elaboration of their own and | |
8351 -- need to be elaborated by other means such as invocation, task | |
8352 -- activation, etc. | |
8353 | |
8354 if Is_Non_Library_Level_Encapsulator (Nod) then | |
8355 return Skip; | |
8356 | |
8357 -- Terminate the traversal of a task body with an accept statement | |
8358 -- when no entry calls in elaboration are allowed because the task | |
8359 -- will block at run-time and none of the remaining statements will | |
8360 -- be executed. | |
8361 | |
8362 elsif Nkind_In (Original_Node (Nod), N_Accept_Statement, | |
8363 N_Selective_Accept) | |
8364 and then Restriction_Active (No_Entry_Calls_In_Elaboration_Code) | |
8365 then | |
8366 return Abandon; | |
8367 | |
8368 -- Certain nodes carry semantic lists which act as repositories until | |
8369 -- expansion transforms the node and relocates the contents. Examine | |
8370 -- these lists in case expansion is disabled. | |
8371 | |
8372 elsif Nkind_In (Nod, N_And_Then, N_Or_Else) then | |
8373 Traverse_List (Actions (Nod)); | |
8374 | |
8375 elsif Nkind_In (Nod, N_Elsif_Part, N_Iteration_Scheme) then | |
8376 Traverse_List (Condition_Actions (Nod)); | |
8377 | |
8378 elsif Nkind (Nod) = N_If_Expression then | |
8379 Traverse_List (Then_Actions (Nod)); | |
8380 Traverse_List (Else_Actions (Nod)); | |
8381 | |
8382 elsif Nkind_In (Nod, N_Component_Association, | |
8383 N_Iterated_Component_Association) | |
8384 then | |
8385 Traverse_List (Loop_Actions (Nod)); | |
8386 | |
8387 -- General case | |
8388 | |
8389 elsif Is_Suitable_Scenario (Nod) then | |
8390 Process_Scenario (Nod, In_Task_Body); | |
8391 end if; | |
8392 | |
8393 return OK; | |
8394 end Is_Potential_Scenario; | |
8395 | |
8396 ------------------- | |
8397 -- Traverse_List -- | |
8398 ------------------- | |
8399 | |
8400 procedure Traverse_List (List : List_Id) is | |
8401 Item : Node_Id; | |
8402 | |
8403 begin | |
8404 Item := First (List); | |
8405 while Present (Item) loop | |
8406 Traverse_Potential_Scenarios (Item); | |
8407 Next (Item); | |
8408 end loop; | |
8409 end Traverse_List; | |
8410 | |
8411 -- Start of processing for Traverse_Body | |
8412 | |
8413 begin | |
8414 -- Nothing to do when there is no body | |
8415 | |
8416 if No (N) then | |
8417 return; | |
8418 | |
8419 elsif Nkind (N) /= N_Subprogram_Body then | |
8420 return; | |
8421 end if; | |
8422 | |
8423 -- Nothing to do if the body was already traversed during the processing | |
8424 -- of the same top level scenario. | |
8425 | |
8426 if Visited_Bodies.Get (N) then | |
8427 return; | |
8428 | |
8429 -- Otherwise mark the body as traversed | |
8430 | |
8431 else | |
8432 Visited_Bodies.Set (N, True); | |
8433 end if; | |
8434 | |
8435 -- Examine the declarations for suitable scenarios | |
8436 | |
8437 Traverse_List (Declarations (N)); | |
8438 | |
8439 -- Examine the handled sequence of statements. This also includes any | |
8440 -- exceptions handlers. | |
8441 | |
8442 Traverse_Potential_Scenarios (Handled_Statement_Sequence (N)); | |
8443 end Traverse_Body; | |
8444 | |
8445 --------------------------------- | |
8446 -- Update_Elaboration_Scenario -- | |
8447 --------------------------------- | |
8448 | |
8449 procedure Update_Elaboration_Scenario (New_N : Node_Id; Old_N : Node_Id) is | |
8450 package Scenarios renames Top_Level_Scenarios; | |
8451 | |
8452 begin | |
8453 -- A scenario is being transformed by Atree.Rewrite. Update all relevant | |
8454 -- internal data structures to reflect this change. This ensures that a | |
8455 -- potential run-time conditional ABE check or a guaranteed ABE failure | |
8456 -- is inserted at the proper place in the tree. | |
8457 | |
8458 if Is_Check_Emitting_Scenario (Old_N) | |
8459 and then Is_Recorded_Scenario (Old_N) | |
8460 and then Old_N /= New_N | |
8461 then | |
8462 -- Performance note: list traversal | |
8463 | |
8464 for Index in Scenarios.First .. Scenarios.Last loop | |
8465 if Scenarios.Table (Index) = Old_N then | |
8466 Scenarios.Table (Index) := New_N; | |
8467 | |
8468 Set_Is_Recorded_Scenario (Old_N, False); | |
8469 Set_Is_Recorded_Scenario (New_N); | |
8470 return; | |
8471 end if; | |
8472 end loop; | |
8473 | |
8474 -- A recorded scenario must be in the table of recorded scenarios | |
8475 | |
8476 pragma Assert (False); | |
8477 end if; | |
8478 end Update_Elaboration_Scenario; | |
8479 | |
8480 ------------------------- | |
8481 -- Visited_Bodies_Hash -- | |
8482 ------------------------- | |
8483 | |
8484 function Visited_Bodies_Hash (Key : Node_Id) return Visited_Bodies_Index is | |
8485 begin | |
8486 return Visited_Bodies_Index (Key mod Visited_Bodies_Max); | |
8487 end Visited_Bodies_Hash; | |
8488 | |
8489 end Sem_Elab; |