libstdc++: Define __glibcxx_assert_fail for non-verbose build [PR115585]
[official-gcc.git] / gcc / ada / exp_unst.ads
blobda91bf9d5326711f69649a630938c97aacc0c03b
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ U N S T --
6 -- --
7 -- S p e c --
8 -- --
9 -- Copyright (C) 2014-2024, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
26 -- Expand routines for unnesting subprograms
28 with Table;
29 with Types; use Types;
31 package Exp_Unst is
33 -- -----------------
34 -- -- The Problem --
35 -- -----------------
37 -- Normally, nested subprograms in the source result in corresponding
38 -- nested subprograms in the resulting tree. We then expect the back end
39 -- to handle such nested subprograms, including all cases of uplevel
40 -- references. For example, the GCC back end can do this relatively easily
41 -- since GNU C (as an extension) allows nested functions with uplevel
42 -- references, and implements an appropriate static chain approach to
43 -- dealing with such uplevel references.
45 -- However, we also want to be able to interface with back ends that do not
46 -- easily handle such uplevel references. One example is the LLVM back end.
48 -- We could imagine simply handling such references in the appropriate
49 -- back end. For example the back end that generates C could recognize
50 -- nested subprograms and rig up some way of translating them, e.g. by
51 -- making a static-link source level visible.
53 -- Rather than take that approach, we prefer to do a semantics-preserving
54 -- transformation on the GNAT tree, that eliminates the problem before we
55 -- hand the tree over to the back end. There are two reasons for preferring
56 -- this approach:
58 -- First: the work needs only to be done once for all affected back ends
59 -- and we can remain within the semantics of the tree. The front end is
60 -- full of tree transformations, so we have all the infrastructure for
61 -- doing transformations of this type.
63 -- Second: given that the transformation will be semantics-preserving,
64 -- we can still use the standard GCC back end to build code from it.
65 -- This means we can easily run our full test suite to verify that the
66 -- transformations are indeed semantics preserving. It is a lot more
67 -- work to thoroughly test the output of specialized back ends.
69 -- Looking at the problem, we have three situations to deal with. Note
70 -- that in these examples, we use all lower case, since that is the way
71 -- the internal tree is cased.
73 -- First, cases where there are no uplevel references, for example
75 -- procedure case1 is
76 -- function max (m, n : Integer) return integer is
77 -- begin
78 -- return integer'max (m, n);
79 -- end max;
80 -- ...
81 -- end case1;
83 -- Second, cases where there are explicit uplevel references.
85 -- procedure case2 (b : integer) is
86 -- procedure Inner (bb : integer);
88 -- procedure inner2 is
89 -- begin
90 -- inner(5);
91 -- end;
93 -- x : integer := 77;
94 -- y : constant integer := 15 * 16;
95 -- rv : integer := 10;
97 -- procedure inner (bb : integer) is
98 -- begin
99 -- x := rv + y + bb + b;
100 -- end;
102 -- begin
103 -- inner2;
104 -- end case2;
106 -- In this second example, B, X, RV are uplevel referenced. Y is not
107 -- considered as an uplevel reference since it is a static constant
108 -- where references are replaced by the value at compile time.
110 -- Third, cases where there are implicit uplevel references via types
111 -- whose bounds depend on locally declared constants or variables:
113 -- function case3 (x, y : integer) return boolean is
114 -- subtype dynam is integer range x .. y + 3;
115 -- subtype static is integer range 42 .. 73;
116 -- xx : dynam := y;
118 -- type darr is array (dynam) of Integer;
119 -- type darec is record
120 -- A : darr;
121 -- B : integer;
122 -- end record;
123 -- darecv : darec;
125 -- function inner (b : integer) return boolean is
126 -- begin
127 -- return b in dynam and then darecv.b in static;
128 -- end inner;
130 -- begin
131 -- return inner (42) and then inner (xx * 3 - y * 2);
132 -- end case3;
134 -- In this third example, the membership test implicitly references the
135 -- the bounds of Dynam, which both involve uplevel references.
137 -- ------------------
138 -- -- The Solution --
139 -- ------------------
141 -- Looking at the three cases above, the first case poses no problem at
142 -- all. Indeed the subprogram could have been declared at the outer level
143 -- (perhaps changing the name). But this style is quite common as a way
144 -- of limiting the scope of a local procedure called only within the outer
145 -- procedure. We could move it to the outer level (with a name change if
146 -- needed), but we don't bother. We leave it nested, and the back end just
147 -- translates it as though it were not nested.
149 -- In general we leave nested procedures nested, rather than trying to move
150 -- them to the outer level (the back end may do that, e.g. as part of the
151 -- translation to C, but we don't do it in the tree itself). This saves a
152 -- LOT of trouble in terms of visibility and semantics.
154 -- But of course we have to deal with the uplevel references. The idea is
155 -- to rewrite these nested subprograms so that they no longer have any such
156 -- uplevel references, so by the time they reach the back end, they all are
157 -- case 1 (no uplevel references) and thus easily handled.
159 -- To deal with explicit uplevel references (case 2 above), we proceed with
160 -- the following steps:
162 -- All entities marked as being uplevel referenced are marked as aliased
163 -- since they will be accessed indirectly via an activation record as
164 -- described below.
166 -- An activation record is created containing system address values
167 -- for each uplevel referenced entity in a given scope. In the example
168 -- given before, we would have:
170 -- type AREC1T is record
171 -- b : Address;
172 -- x : Address;
173 -- rv : Address;
174 -- end record;
176 -- type AREC1PT is access all AREC1T;
178 -- AREC1 : aliased AREC1T;
179 -- AREC1P : constant AREC1PT := AREC1'Access;
181 -- The fields of AREC1 are set at the point the corresponding entity
182 -- is declared (immediately for parameters).
184 -- Note: the 1 in all these names is a unique index number. Different
185 -- scopes requiring different ARECnT declarations will have different
186 -- values of n to ensure uniqueness.
188 -- Note: normally the field names in the activation record match the
189 -- name of the entity. An exception is when the entity is declared in
190 -- a declare block, in which case we append the entity number, to avoid
191 -- clashes between the same name declared in different declare blocks.
193 -- For all subprograms nested immediately within the corresponding scope,
194 -- a parameter AREC1F is passed, and all calls to these routines have
195 -- AREC1P added as an additional formal.
197 -- Now within the nested procedures, any reference to an uplevel entity
198 -- xxx is replaced by typ'Deref(AREC1.xxx) where typ is the type of the
199 -- reference.
201 -- Note: the reason that we use Address as the component type in the
202 -- declaration of AREC1T is that we may create this type before we see
203 -- the declaration of this type.
205 -- The following shows example 2 above after this translation:
207 -- procedure case2x (b : aliased Integer) is
208 -- type AREC1T is record
209 -- b : Address;
210 -- x : Address;
211 -- rv : Address;
212 -- end record;
214 -- type AREC1PT is access all AREC1T;
216 -- AREC1 : aliased AREC1T;
217 -- AREC1P : constant AREC1PT := AREC1'Access;
219 -- AREC1.b := b'Address;
221 -- procedure inner (bb : integer; AREC1F : AREC1PT);
223 -- procedure inner2 (AREC1F : AREC1PT) is
224 -- begin
225 -- inner(5, AREC1F);
226 -- end;
228 -- x : aliased integer := 77;
229 -- AREC1.x := X'Address;
231 -- y : constant Integer := 15 * 16;
233 -- rv : aliased Integer;
234 -- AREC1.rv := rv'Address;
236 -- procedure inner (bb : integer; AREC1F : AREC1PT) is
237 -- begin
238 -- Integer'Deref(AREC1F.x) :=
239 -- Integer'Deref(AREC1F.rv) + y + b + Integer'Deref(AREC1F.b);
240 -- end;
242 -- begin
243 -- inner2 (AREC1P);
244 -- end case2x;
246 -- And now the inner procedures INNER2 and INNER have no uplevel references
247 -- so they have been reduced to case 1, which is the case easily handled by
248 -- the back end. Note that the generated code is not strictly legal Ada
249 -- because of the assignments to AREC1 in the declarative sequence, but the
250 -- GNAT tree always allows such mixing of declarations and statements, so
251 -- the back end must be prepared to handle this in any case.
253 -- Case 3 where we have uplevel references to types is a bit more complex.
254 -- That would especially be the case if we did a full transformation that
255 -- completely eliminated such uplevel references as we did for case 2. But
256 -- instead of trying to do that, we rewrite the subprogram so that the code
257 -- generator can easily detect and deal with these uplevel type references.
259 -- First we distinguish two cases
261 -- Static types are one of the two following cases:
263 -- Discrete types whose bounds are known at compile time. This is not
264 -- quite the same as what is tested by Is_OK_Static_Subtype, in that
265 -- it allows compile time known values that are not static expressions.
267 -- Composite types, whose components are (recursively) static types.
269 -- Dynamic types are one of the two following cases:
271 -- Discrete types with at least one bound not known at compile time.
273 -- Composite types with at least one component that is (recursively)
274 -- a dynamic type.
276 -- Uplevel references to static types are not a problem, the front end
277 -- or the code generator fetches the bounds as required, and since they
278 -- are compile time known values, this value can just be extracted and
279 -- no actual uplevel reference is required.
281 -- Uplevel references to dynamic types are a potential problem, since
282 -- such references may involve an implicit access to a dynamic bound,
283 -- and this reference is an implicit uplevel access.
285 -- To fully unnest such references would be messy, since we would have
286 -- to create local copies of the dynamic types involved, so that the
287 -- front end or code generator could generate an explicit uplevel
288 -- reference to the bound involved. Rather than do that, we set things
289 -- up so that this situation can be easily detected and dealt with when
290 -- there is an implicit reference to the bounds.
292 -- What we do is to always generate a local constant for any dynamic
293 -- bound in a dynamic subtype xx with name xx_FIRST or xx_LAST. The one
294 -- case where we can skip this is where the bound is already a constant.
295 -- E.g. in the third example above, subtype dynam is expanded as
297 -- dynam_LAST : constant Integer := y + 3;
298 -- subtype dynam is integer range x .. dynam_LAST;
300 -- Now if type dynam is uplevel referenced (as it is in this case), then
301 -- the bounds x and dynam_LAST are marked as uplevel references
302 -- so that appropriate entries are made in the activation record. Any
303 -- explicit reference to such a bound in the front end generated code
304 -- will be handled by the normal uplevel reference mechanism which we
305 -- described above for case 2. For implicit references by a back end
306 -- that needs to unnest things, any such implicit reference to one of
307 -- these bounds can be replaced by an appropriate reference to the entry
308 -- in the activation record for xx_FIRST or xx_LAST. Thus the back end
309 -- can eliminate the problematical uplevel reference without the need to
310 -- do the heavy tree modification to do that at the code expansion level.
312 -- Looking at case 3 again, here is the normal -gnatG expanded code
314 -- function case3 (x : integer; y : integer) return boolean is
315 -- dynam_LAST : constant integer := y {+} 3;
316 -- subtype dynam is integer range x .. dynam_LAST;
317 -- subtype static is integer range 42 .. 73;
319 -- [constraint_error when
320 -- not (y in x .. dynam_LAST)
321 -- "range check failed"]
323 -- xx : dynam := y;
325 -- type darr is array (x .. dynam_LAST) of integer;
326 -- type darec is record
327 -- a : darr;
328 -- b : integer;
329 -- end record;
330 -- [type TdarrB is array (x .. dynam_LAST range <>) of integer]
331 -- freeze TdarrB []
332 -- darecv : darec;
334 -- function inner (b : integer) return boolean is
335 -- begin
336 -- return b in x .. dynam_LAST and then darecv.b in 42 .. 73;
337 -- end inner;
338 -- begin
339 -- return inner (42) and then inner (xx {*} 3 {-} y {*} 2);
340 -- end case3;
342 -- Note: the actual expanded code has fully qualified names so for
343 -- example function inner is actually function case3__inner. For now
344 -- we ignore that detail to clarify the examples.
346 -- Here we see that some of the bounds references are expanded by the
347 -- front end, so that we get explicit references to y or dynam_Last. These
348 -- cases are handled by the normal uplevel reference mechanism described
349 -- above for case 2. This is the case for the constraint check for the
350 -- initialization of xx, and the range check in function inner.
352 -- But the reference darecv.b in the return statement of function
353 -- inner has an implicit reference to the bounds of dynam, since to
354 -- compute the location of b in the record, we need the length of a.
356 -- Here is the full translation of the third example:
358 -- function case3x (x, y : integer) return boolean is
359 -- type AREC1T is record
360 -- x : Address;
361 -- dynam_LAST : Address;
362 -- end record;
364 -- type AREC1PT is access all AREC1T;
366 -- AREC1 : aliased AREC1T;
367 -- AREC1P : constant AREC1PT := AREC1'Access;
369 -- AREC1.x := x'Address;
371 -- dynam_LAST : constant integer := y {+} 3;
372 -- AREC1.dynam_LAST := dynam_LAST'Address;
373 -- subtype dynam is integer range x .. dynam_LAST;
374 -- xx : dynam := y;
376 -- [constraint_error when
377 -- not (y in x .. dynam_LAST)
378 -- "range check failed"]
380 -- subtype static is integer range 42 .. 73;
382 -- type darr is array (x .. dynam_LAST) of Integer;
383 -- type darec is record
384 -- A : darr;
385 -- B : integer;
386 -- end record;
387 -- darecv : darec;
389 -- function inner (b : integer; AREC1F : AREC1PT) return boolean is
390 -- begin
391 -- return b in x .. Integer'Deref(AREC1F.dynam_LAST)
392 -- and then darecv.b in 42 .. 73;
393 -- end inner;
395 -- begin
396 -- return inner (42, AREC1P) and then inner (xx * 3, AREC1P);
397 -- end case3x;
399 -- And now the back end when it processes darecv.b will access the bounds
400 -- of darecv.a by referencing the d and dynam_LAST fields of AREC1P.
402 -----------------------------
403 -- Multiple Nesting Levels --
404 -----------------------------
406 -- In our examples so far, we have only nested to a single level, but the
407 -- scheme generalizes to multiple levels of nesting and in this section we
408 -- discuss how this generalization works.
410 -- Consider this example with two nesting levels
412 -- To deal with elimination of uplevel references, we follow the same basic
413 -- approach described above for case 2, except that we need an activation
414 -- record at each nested level. Basically the rule is that any procedure
415 -- that has nested procedures needs an activation record. When we do this,
416 -- the inner activation records have a pointer (uplink) to the immediately
417 -- enclosing activation record, the normal arrangement of static links. The
418 -- following shows the full translation of this fourth case.
420 -- function case4x (x : integer) return integer is
421 -- type AREC1T is record
422 -- v1 : Address;
423 -- end record;
425 -- type AREC1PT is access all AREC1T;
427 -- AREC1 : aliased AREC1T;
428 -- AREC1P : constant AREC1PT := AREC1'Access;
430 -- v1 : integer := x;
431 -- AREC1.v1 := v1'Address;
433 -- function inner1 (y : integer; AREC1F : AREC1PT) return integer is
434 -- type AREC2T is record
435 -- AREC1U : AREC1PT;
436 -- v2 : Address;
437 -- end record;
439 -- type AREC2PT is access all AREC2T;
441 -- AREC2 : aliased AREC2T;
442 -- AREC2P : constant AREC2PT := AREC2'Access;
444 -- AREC2.AREC1U := AREC1F;
446 -- v2 : integer := Integer'Deref (AREC1F.v1) {+} 1;
447 -- AREC2.v2 := v2'Address;
449 -- function inner2
450 -- (z : integer; AREC2F : AREC2PT) return integer
451 -- is
452 -- begin
453 -- return integer(z {+}
454 -- Integer'Deref (AREC2F.AREC1U.v1) {+}
455 -- Integer'Deref (AREC2F.v2).all);
456 -- end inner2;
457 -- begin
458 -- return integer(y {+}
459 -- inner2 (Integer'Deref (AREC1F.v1), AREC2P));
460 -- end inner1;
461 -- begin
462 -- return inner1 (x, AREC1P);
463 -- end case4x;
465 -- As can be seen in this example, the index numbers following AREC in the
466 -- generated names avoid confusion between AREC names at different levels.
468 -------------------------
469 -- Name Disambiguation --
470 -------------------------
472 -- As described above, the translation scheme would raise issues when the
473 -- code generator did the actual unnesting if identically named nested
474 -- subprograms exist. Similarly overloading would cause a naming issue.
476 -- In fact, the expanded code includes qualified names which eliminate this
477 -- problem. We omitted the qualification from the expanded examples above
478 -- for simplicity. But to see this in action, consider this example:
480 -- function Mnames return Boolean is
481 -- procedure Inner is
482 -- procedure Inner is
483 -- begin
484 -- null;
485 -- end;
486 -- begin
487 -- Inner;
488 -- end;
489 -- function F (A : Boolean) return Boolean is
490 -- begin
491 -- return not A;
492 -- end;
493 -- function F (A : Integer) return Boolean is
494 -- begin
495 -- return A > 42;
496 -- end;
497 -- begin
498 -- Inner;
499 -- return F (42) or F (True);
500 -- end;
502 -- The expanded code actually looks like:
504 -- function mnames return boolean is
505 -- procedure mnames__inner is
506 -- procedure mnames__inner__inner is
507 -- begin
508 -- null;
509 -- return;
510 -- end mnames__inner__inner;
511 -- begin
512 -- mnames__inner__inner;
513 -- return;
514 -- end mnames__inner;
515 -- function mnames__f (a : boolean) return boolean is
516 -- begin
517 -- return not a;
518 -- end mnames__f;
519 -- function mnames__f__2 (a : integer) return boolean is
520 -- begin
521 -- return a > 42;
522 -- end mnames__f__2;
523 -- begin
524 -- mnames__inner;
525 -- return mnames__f__2 (42) or mnames__f (true);
526 -- end mnames;
528 -- As can be seen from studying this example, the qualification deals both
529 -- with the issue of clashing names (mnames__inner, mnames__inner__inner),
530 -- and with overloading (mnames__f, mnames__f__2).
532 -- In addition, the declarations of ARECnT and ARECnPT get moved to the
533 -- outer level when we actually generate C code, so we suffix these names
534 -- with the corresponding entity name to make sure they are unique.
536 ---------------------------
537 -- Terminology for Calls --
538 ---------------------------
540 -- The level of a subprogram in the nest being analyzed is defined to be
541 -- the level of nesting, so the outer level subprogram (the one passed to
542 -- Unnest_Subprogram) is 1, subprograms immediately nested within this
543 -- outer level subprogram have a level of 2, etc.
545 -- Calls within the nest being analyzed are of three types:
547 -- Downward call: this is a call from a subprogram to a subprogram that
548 -- is immediately nested with in the caller, and thus has a level that
549 -- is one greater than the caller. It is a fundamental property of the
550 -- nesting structure and visibility that it is not possible to make a
551 -- call from level N to level M, where M is greater than N + 1.
553 -- Parallel call: this is a call from a nested subprogram to another
554 -- nested subprogram that is at the same level.
556 -- Upward call: this is a call from a subprogram to a subprogram that
557 -- encloses the caller. The level of the callee is less than the level
558 -- of the caller, and there is no limit on the difference, e.g. for an
559 -- uplevel call, a subprogram at level 5 can call one at level 2 or even
560 -- the outer level subprogram at level 1.
562 -------------------------------------
563 -- Handling of unconstrained types --
564 -------------------------------------
566 -- Objects whose nominal subtype is an unconstrained array type present
567 -- additional complications for translation into LLVM. The address
568 -- attribute of such objects points to the first component of the
569 -- array, and the bounds are found elsewhere, typically ahead of the
570 -- components. In many cases the bounds of an object are stored ahead
571 -- of the components and can be retrieved from it. However, if the
572 -- object is an expression (e.g. a slice) the bounds are not adjacent
573 -- and thus must be conveyed explicitly by means of a so-called
574 -- fat pointer. This leads to the following enhancements to the
575 -- handling of uplevel references described so far. This applies only
576 -- to uplevel references to unconstrained formals of enclosing
577 -- subprograms:
579 -- a) Uplevel references are detected as before during the tree traversal
580 -- in Visit_Node. For reference to uplevel formals, we include those with
581 -- an unconstrained array type (e.g. String) even if such a type has
582 -- static bounds.
584 -- b) references to unconstrained formals are recognized in the Subp
585 -- table by means of the predicate Needs_Fat_Pointer.
587 -- c) When constructing the required activation record we also construct
588 -- a named access type whose designated type is the unconstrained array
589 -- type. The activation record of a subprogram that contains such an
590 -- uplevel reference includes a component of this access type. The
591 -- declaration for that access type is introduced and analyzed before
592 -- that of the activation record, so it appears in the subprogram that
593 -- has that formal.
595 -- d) The uplevel reference is rewritten as an explicit dereference (.all)
596 -- of the corresponding pointer component.
598 -----------
599 -- Subps --
600 -----------
602 -- Table to record subprograms within the nest being currently analyzed.
603 -- Entries in this table are made for each subprogram expanded, and do not
604 -- get cleared as we complete the expansion, since we want the table info
605 -- around in Cprint for the actual unnesting operation. Subps_First in this
606 -- unit records the starting entry in the table for the entries for Subp
607 -- and this is also recorded in the Subps_Index field of the outer level
608 -- subprogram in the nest. The last subps index for the nest can be found
609 -- in the Subp_Entry Last field of this first entry.
611 subtype SI_Type is Nat;
612 -- Index type for the table
614 Subps_First : SI_Type;
615 -- Record starting index for entries in the current nest (this is the table
616 -- index of the entry for Subp itself, and is recorded in the Subps_Index
617 -- field of the entity for this subprogram).
619 type Subp_Entry is record
620 Ent : Entity_Id;
621 -- Entity of the subprogram
623 Bod : Node_Id;
624 -- Subprogram_Body node for this subprogram
626 Lev : Nat;
627 -- Subprogram level (1 = outer subprogram (Subp argument), 2 = nested
628 -- immediately within this outer subprogram etc.)
630 Reachable : Boolean;
631 -- This flag is set True if there is a call path from the outer level
632 -- subprogram to this subprogram. If Reachable is False, it means that
633 -- the subprogram is declared but not actually referenced. We remove
634 -- such subprograms from the tree, which simplifies our task, because
635 -- we don't have to worry about e.g. uplevel references from such an
636 -- unreferenced subprogram, which might require (useless) activation
637 -- records to be created. This is computed by setting the outer level
638 -- subprogram (Subp itself) as reachable, and then doing a transitive
639 -- closure following all calls.
641 Uplevel_Ref : Nat;
642 -- The outermost level which defines entities which this subprogram
643 -- references either directly or indirectly via a call. This cannot
644 -- be greater than Lev. If it is equal to Lev, then it means that the
645 -- subprogram does not make any uplevel references and that thus it
646 -- does not need an activation record pointer passed. If it is less than
647 -- Lev, then an activation record pointer is needed, since there is at
648 -- least one uplevel reference. This is computed by initially setting
649 -- Uplevel_Ref to Lev for all subprograms. Then on the initial tree
650 -- traversal, decreasing Uplevel_Ref for an explicit uplevel reference,
651 -- and finally by doing a transitive closure that follows calls (if A
652 -- calls B and B has an uplevel reference to level X, then A references
653 -- level X indirectly).
655 Declares_AREC : Boolean;
656 -- This is set True for a subprogram which include the declarations
657 -- for a local activation record to be passed on downward calls. It
658 -- is set True for the target level of an uplevel reference, and for
659 -- all intervening nested subprograms. For example, if a subprogram X
660 -- at level 5 makes an uplevel reference to an entity declared in a
661 -- level 2 subprogram, then the subprograms at levels 4,3,2 enclosing
662 -- the level 5 subprogram will have this flag set True.
664 Uents : Elist_Id;
665 -- This is a list of entities declared in this subprogram which are
666 -- uplevel referenced. It contains both objects (which will be put in
667 -- the corresponding AREC activation record), and types. The types are
668 -- not put in the AREC activation record, but referenced bounds (i.e.
669 -- generated _FIRST and _LAST entities, and formal parameters) will be
670 -- in the list in their own right.
672 Last : SI_Type;
673 -- This field is set only in the entry for the outer level subprogram
674 -- in a nest, and records the last index in the Subp table for all the
675 -- entries for subprograms in this nest.
677 ARECnF : Entity_Id;
678 -- This entity is defined for all subprograms which need an extra formal
679 -- that contains a pointer to the activation record needed for uplevel
680 -- references. ARECnF must be defined for any subprogram which has a
681 -- direct or indirect uplevel reference (i.e. Reference_Level < Lev).
683 ARECn : Entity_Id;
684 ARECnT : Entity_Id;
685 ARECnPT : Entity_Id;
686 ARECnP : Entity_Id;
687 -- These AREC entities are defined only for subprograms for which we
688 -- generate an activation record declaration, i.e. for subprograms for
689 -- which the Declares_AREC flag is set True.
691 ARECnU : Entity_Id;
692 -- This AREC entity is the uplink component. It is other than Empty only
693 -- for nested subprograms that declare an activation record as indicated
694 -- by Declares_AREC being True, and which have uplevel references (Lev
695 -- greater than Uplevel_Ref). It is the additional component in the
696 -- activation record that references the ARECnF pointer (which points
697 -- the activation record one level higher, thus forming the chain).
699 end record;
701 package Subps is new Table.Table (
702 Table_Component_Type => Subp_Entry,
703 Table_Index_Type => SI_Type,
704 Table_Low_Bound => 1,
705 Table_Initial => 1000,
706 Table_Increment => 200,
707 Table_Name => "Unnest_Subps");
708 -- Records the subprograms in the nest whose outer subprogram is Subp
710 -----------------
711 -- Subprograms --
712 -----------------
714 function Get_Level (Subp : Entity_Id; Sub : Entity_Id) return Nat;
715 -- Sub is either Subp itself, or a subprogram nested within Subp. This
716 -- function returns the level of nesting (Subp = 1, subprograms that
717 -- are immediately nested within Subp = 2, etc.).
719 function In_Synchronized_Unit (Subp : Entity_Id) return Boolean;
720 -- Predicate to identify subprograms declared in task and protected types.
721 -- These subprograms are called from outside the compilation and therefore
722 -- must be considered reachable (and cannot be eliminated) because we must
723 -- generate code for them.
725 function Subp_Index (Sub : Entity_Id) return SI_Type;
726 -- Given the entity for a subprogram, return corresponding Subp's index
728 procedure Unnest_Subprograms (N : Node_Id);
729 -- Called to unnest subprograms. If we are in unnest subprogram mode, this
730 -- is the call that traverses the tree N and locates all the library-level
731 -- subprograms with nested subprograms to process them.
733 end Exp_Unst;