Fix failure when -fno-rtti test is run in C++17 or later
[official-gcc.git] / gcc / ada / exp_unst.adb
blobd688157e768ca78d712356c3ebc6feb96ea5b8ab
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ U N S T --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2014-2018, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
26 with Atree; use Atree;
27 with Debug; use Debug;
28 with Einfo; use Einfo;
29 with Elists; use Elists;
30 with Lib; use Lib;
31 with Namet; use Namet;
32 with Nlists; use Nlists;
33 with Nmake; use Nmake;
34 with Opt;
35 with Output; use Output;
36 with Rtsfind; use Rtsfind;
37 with Sem; use Sem;
38 with Sem_Aux; use Sem_Aux;
39 with Sem_Ch8; use Sem_Ch8;
40 with Sem_Mech; use Sem_Mech;
41 with Sem_Res; use Sem_Res;
42 with Sem_Util; use Sem_Util;
43 with Sinfo; use Sinfo;
44 with Sinput; use Sinput;
45 with Snames; use Snames;
46 with Stand; use Stand;
47 with Tbuild; use Tbuild;
48 with Uintp; use Uintp;
50 package body Exp_Unst is
52 -----------------------
53 -- Local Subprograms --
54 -----------------------
56 procedure Unnest_Subprogram (Subp : Entity_Id; Subp_Body : Node_Id);
57 -- Subp is a library-level subprogram which has nested subprograms, and
58 -- Subp_Body is the corresponding N_Subprogram_Body node. This procedure
59 -- declares the AREC types and objects, adds assignments to the AREC record
60 -- as required, defines the xxxPTR types for uplevel referenced objects,
61 -- adds the ARECP parameter to all nested subprograms which need it, and
62 -- modifies all uplevel references appropriately.
64 -----------
65 -- Calls --
66 -----------
68 -- Table to record calls within the nest being analyzed. These are the
69 -- calls which may need to have an AREC actual added. This table is built
70 -- new for each subprogram nest and cleared at the end of processing each
71 -- subprogram nest.
73 type Call_Entry is record
74 N : Node_Id;
75 -- The actual call
77 Caller : Entity_Id;
78 -- Entity of the subprogram containing the call (can be at any level)
80 Callee : Entity_Id;
81 -- Entity of the subprogram called (always at level 2 or higher). Note
82 -- that in accordance with the basic rules of nesting, the level of To
83 -- is either less than or equal to the level of From, or one greater.
84 end record;
86 package Calls is new Table.Table (
87 Table_Component_Type => Call_Entry,
88 Table_Index_Type => Nat,
89 Table_Low_Bound => 1,
90 Table_Initial => 100,
91 Table_Increment => 200,
92 Table_Name => "Unnest_Calls");
93 -- Records each call within the outer subprogram and all nested subprograms
94 -- that are to other subprograms nested within the outer subprogram. These
95 -- are the calls that may need an additional parameter.
97 procedure Append_Unique_Call (Call : Call_Entry);
98 -- Append a call entry to the Calls table. A check is made to see if the
99 -- table already contains this entry and if so it has no effect.
101 ----------------------------------
102 -- Subprograms For Fat Pointers --
103 ----------------------------------
105 function Build_Access_Type_Decl
106 (E : Entity_Id;
107 Scop : Entity_Id) return Node_Id;
108 -- For an uplevel reference that involves an unconstrained array type,
109 -- build an access type declaration for the corresponding activation
110 -- record component. The relevant attributes of the access type are
111 -- set here to avoid a full analysis that would require a scope stack.
113 function Needs_Fat_Pointer (E : Entity_Id) return Boolean;
114 -- A formal parameter of an unconstrained array type that appears in an
115 -- uplevel reference requires the construction of an access type, to be
116 -- used in the corresponding component declaration.
118 -----------
119 -- Urefs --
120 -----------
122 -- Table to record explicit uplevel references to objects (variables,
123 -- constants, formal parameters). These are the references that will
124 -- need rewriting to use the activation table (AREC) pointers. Also
125 -- included are implicit and explicit uplevel references to types, but
126 -- these do not get rewritten by the front end. This table is built new
127 -- for each subprogram nest and cleared at the end of processing each
128 -- subprogram nest.
130 type Uref_Entry is record
131 Ref : Node_Id;
132 -- The reference itself. For objects this is always an entity reference
133 -- and the referenced entity will have its Is_Uplevel_Referenced_Entity
134 -- flag set and will appear in the Uplevel_Referenced_Entities list of
135 -- the subprogram declaring this entity.
137 Ent : Entity_Id;
138 -- The Entity_Id of the uplevel referenced object or type
140 Caller : Entity_Id;
141 -- The entity for the subprogram immediately containing this entity
143 Callee : Entity_Id;
144 -- The entity for the subprogram containing the referenced entity. Note
145 -- that the level of Callee must be less than the level of Caller, since
146 -- this is an uplevel reference.
147 end record;
149 package Urefs is new Table.Table (
150 Table_Component_Type => Uref_Entry,
151 Table_Index_Type => Nat,
152 Table_Low_Bound => 1,
153 Table_Initial => 100,
154 Table_Increment => 200,
155 Table_Name => "Unnest_Urefs");
157 ------------------------
158 -- Append_Unique_Call --
159 ------------------------
161 procedure Append_Unique_Call (Call : Call_Entry) is
162 begin
163 for J in Calls.First .. Calls.Last loop
164 if Calls.Table (J) = Call then
165 return;
166 end if;
167 end loop;
169 Calls.Append (Call);
170 end Append_Unique_Call;
172 -----------------------------
173 -- Build_Access_Type_Decl --
174 -----------------------------
176 function Build_Access_Type_Decl
177 (E : Entity_Id;
178 Scop : Entity_Id) return Node_Id
180 Loc : constant Source_Ptr := Sloc (E);
181 Typ : Entity_Id;
183 begin
184 Typ := Make_Temporary (Loc, 'S');
185 Set_Ekind (Typ, E_General_Access_Type);
186 Set_Etype (Typ, Typ);
187 Set_Scope (Typ, Scop);
188 Set_Directly_Designated_Type (Typ, Etype (E));
190 return
191 Make_Full_Type_Declaration (Loc,
192 Defining_Identifier => Typ,
193 Type_Definition =>
194 Make_Access_To_Object_Definition (Loc,
195 Subtype_Indication => New_Occurrence_Of (Etype (E), Loc)));
196 end Build_Access_Type_Decl;
198 ---------------
199 -- Get_Level --
200 ---------------
202 function Get_Level (Subp : Entity_Id; Sub : Entity_Id) return Nat is
203 Lev : Nat;
204 S : Entity_Id;
206 begin
207 Lev := 1;
208 S := Sub;
209 loop
210 if S = Subp then
211 return Lev;
212 else
213 Lev := Lev + 1;
214 S := Enclosing_Subprogram (S);
215 end if;
216 end loop;
217 end Get_Level;
219 --------------------------
220 -- In_Synchronized_Unit --
221 --------------------------
223 function In_Synchronized_Unit (Subp : Entity_Id) return Boolean is
224 S : Entity_Id := Scope (Subp);
226 begin
227 while Present (S) and then S /= Standard_Standard loop
228 if Is_Concurrent_Type (S) then
229 return True;
230 end if;
232 S := Scope (S);
233 end loop;
235 return False;
236 end In_Synchronized_Unit;
238 -----------------------
239 -- Needs_Fat_Pointer --
240 -----------------------
242 function Needs_Fat_Pointer (E : Entity_Id) return Boolean is
243 begin
244 return Is_Formal (E)
245 and then Is_Array_Type (Etype (E))
246 and then not Is_Constrained (Etype (E));
247 end Needs_Fat_Pointer;
249 ----------------
250 -- Subp_Index --
251 ----------------
253 function Subp_Index (Sub : Entity_Id) return SI_Type is
254 E : Entity_Id := Sub;
256 begin
257 pragma Assert (Is_Subprogram (E));
259 if Subps_Index (E) = Uint_0 then
260 E := Ultimate_Alias (E);
262 -- The body of a protected operation has a different name and
263 -- has been scanned at this point, and thus has an entry in the
264 -- subprogram table.
266 if E = Sub and then Convention (E) = Convention_Protected then
267 E := Protected_Body_Subprogram (E);
268 end if;
270 if Ekind (E) = E_Function
271 and then Rewritten_For_C (E)
272 and then Present (Corresponding_Procedure (E))
273 then
274 E := Corresponding_Procedure (E);
275 end if;
276 end if;
278 pragma Assert (Subps_Index (E) /= Uint_0);
279 return SI_Type (UI_To_Int (Subps_Index (E)));
280 end Subp_Index;
282 -----------------------
283 -- Unnest_Subprogram --
284 -----------------------
286 procedure Unnest_Subprogram (Subp : Entity_Id; Subp_Body : Node_Id) is
287 function AREC_Name (J : Pos; S : String) return Name_Id;
288 -- Returns name for string ARECjS, where j is the decimal value of j
290 function Enclosing_Subp (Subp : SI_Type) return SI_Type;
291 -- Subp is the index of a subprogram which has a Lev greater than 1.
292 -- This function returns the index of the enclosing subprogram which
293 -- will have a Lev value one less than this.
295 function Img_Pos (N : Pos) return String;
296 -- Return image of N without leading blank
298 function Upref_Name
299 (Ent : Entity_Id;
300 Index : Pos;
301 Clist : List_Id) return Name_Id;
302 -- This function returns the name to be used in the activation record to
303 -- reference the variable uplevel. Clist is the list of components that
304 -- have been created in the activation record so far. Normally the name
305 -- is just a copy of the Chars field of the entity. The exception is
306 -- when the name has already been used, in which case we suffix the name
307 -- with the index value Index to avoid duplication. This happens with
308 -- declare blocks and generic parameters at least.
310 ---------------
311 -- AREC_Name --
312 ---------------
314 function AREC_Name (J : Pos; S : String) return Name_Id is
315 begin
316 return Name_Find ("AREC" & Img_Pos (J) & S);
317 end AREC_Name;
319 --------------------
320 -- Enclosing_Subp --
321 --------------------
323 function Enclosing_Subp (Subp : SI_Type) return SI_Type is
324 STJ : Subp_Entry renames Subps.Table (Subp);
325 Ret : constant SI_Type := Subp_Index (Enclosing_Subprogram (STJ.Ent));
326 begin
327 pragma Assert (STJ.Lev > 1);
328 pragma Assert (Subps.Table (Ret).Lev = STJ.Lev - 1);
329 return Ret;
330 end Enclosing_Subp;
332 -------------
333 -- Img_Pos --
334 -------------
336 function Img_Pos (N : Pos) return String is
337 Buf : String (1 .. 20);
338 Ptr : Natural;
339 NV : Nat;
341 begin
342 Ptr := Buf'Last;
343 NV := N;
344 while NV /= 0 loop
345 Buf (Ptr) := Character'Val (48 + NV mod 10);
346 Ptr := Ptr - 1;
347 NV := NV / 10;
348 end loop;
350 return Buf (Ptr + 1 .. Buf'Last);
351 end Img_Pos;
353 ----------------
354 -- Upref_Name --
355 ----------------
357 function Upref_Name
358 (Ent : Entity_Id;
359 Index : Pos;
360 Clist : List_Id) return Name_Id
362 C : Node_Id;
363 begin
364 C := First (Clist);
365 loop
366 if No (C) then
367 return Chars (Ent);
369 elsif Chars (Defining_Identifier (C)) = Chars (Ent) then
370 return
371 Name_Find (Get_Name_String (Chars (Ent)) & Img_Pos (Index));
372 else
373 Next (C);
374 end if;
375 end loop;
376 end Upref_Name;
378 -- Start of processing for Unnest_Subprogram
380 begin
381 -- Nothing to do inside a generic (all processing is for instance)
383 if Inside_A_Generic then
384 return;
385 end if;
387 -- If the main unit is a package body then we need to examine the spec
388 -- to determine whether the main unit is generic (the scope stack is not
389 -- present when this is called on the main unit).
391 if Ekind (Cunit_Entity (Main_Unit)) = E_Package_Body
392 and then Is_Generic_Unit (Spec_Entity (Cunit_Entity (Main_Unit)))
393 then
394 return;
395 end if;
397 -- Only unnest when generating code for the main source unit
399 if not In_Extended_Main_Code_Unit (Subp_Body) then
400 return;
401 end if;
403 -- This routine is called late, after the scope stack is gone. The
404 -- following creates a suitable dummy scope stack to be used for the
405 -- analyze/expand calls made from this routine.
407 Push_Scope (Subp);
409 -- First step, we must mark all nested subprograms that require a static
410 -- link (activation record) because either they contain explicit uplevel
411 -- references (as indicated by Is_Uplevel_Referenced_Entity being set at
412 -- this point), or they make calls to other subprograms in the same nest
413 -- that require a static link (in which case we set this flag).
415 -- This is a recursive definition, and to implement this, we have to
416 -- build a call graph for the set of nested subprograms, and then go
417 -- over this graph to implement recursively the invariant that if a
418 -- subprogram has a call to a subprogram requiring a static link, then
419 -- the calling subprogram requires a static link.
421 -- First populate the above tables
423 Subps_First := Subps.Last + 1;
424 Calls.Init;
425 Urefs.Init;
427 Build_Tables : declare
428 Current_Subprogram : Entity_Id;
429 -- When we scan a subprogram body, we set Current_Subprogram to the
430 -- corresponding entity. This gets recursively saved and restored.
432 function Visit_Node (N : Node_Id) return Traverse_Result;
433 -- Visit a single node in Subp
435 -----------
436 -- Visit --
437 -----------
439 procedure Visit is new Traverse_Proc (Visit_Node);
440 -- Used to traverse the body of Subp, populating the tables
442 ----------------
443 -- Visit_Node --
444 ----------------
446 function Visit_Node (N : Node_Id) return Traverse_Result is
447 Ent : Entity_Id;
448 Caller : Entity_Id;
449 Callee : Entity_Id;
451 procedure Check_Static_Type
452 (T : Entity_Id; N : Node_Id; DT : in out Boolean);
453 -- Given a type T, checks if it is a static type defined as a type
454 -- with no dynamic bounds in sight. If so, the only action is to
455 -- set Is_Static_Type True for T. If T is not a static type, then
456 -- all types with dynamic bounds associated with T are detected,
457 -- and their bounds are marked as uplevel referenced if not at the
458 -- library level, and DT is set True. If N is specified, it's the
459 -- node that will need to be replaced. If not specified, it means
460 -- we can't do a replacement because the bound is implicit.
462 procedure Note_Uplevel_Ref
463 (E : Entity_Id;
464 N : Node_Id;
465 Caller : Entity_Id;
466 Callee : Entity_Id);
467 -- Called when we detect an explicit or implicit uplevel reference
468 -- from within Caller to entity E declared in Callee. E can be a
469 -- an object or a type.
471 procedure Register_Subprogram (E : Entity_Id; Bod : Node_Id);
472 -- Enter a subprogram whose body is visible or which is a
473 -- subprogram instance into the subprogram table.
475 -----------------------
476 -- Check_Static_Type --
477 -----------------------
479 procedure Check_Static_Type
480 (T : Entity_Id; N : Node_Id; DT : in out Boolean)
482 procedure Note_Uplevel_Bound (N : Node_Id; Ref : Node_Id);
483 -- N is the bound of a dynamic type. This procedure notes that
484 -- this bound is uplevel referenced, it can handle references
485 -- to entities (typically _FIRST and _LAST entities), and also
486 -- attribute references of the form T'name (name is typically
487 -- FIRST or LAST) where T is the uplevel referenced bound.
488 -- Ref, if Present, is the location of the reference to
489 -- replace.
491 ------------------------
492 -- Note_Uplevel_Bound --
493 ------------------------
495 procedure Note_Uplevel_Bound (N : Node_Id; Ref : Node_Id) is
496 begin
497 -- Entity name case. Make sure that the entity is declared
498 -- in a subprogram. This may not be the case for for a type
499 -- in a loop appearing in a precondition.
500 -- Exclude explicitly discriminants (that can appear
501 -- in bounds of discriminated components).
503 if Is_Entity_Name (N) then
504 if Present (Entity (N))
505 and then not Is_Type (Entity (N))
506 and then Present (Enclosing_Subprogram (Entity (N)))
507 and then Ekind (Entity (N)) /= E_Discriminant
508 then
509 Note_Uplevel_Ref
510 (E => Entity (N),
511 N => Empty,
512 Caller => Current_Subprogram,
513 Callee => Enclosing_Subprogram (Entity (N)));
514 end if;
516 -- Attribute or indexed component case
518 elsif Nkind_In (N, N_Attribute_Reference,
519 N_Indexed_Component)
520 then
521 Note_Uplevel_Bound (Prefix (N), Ref);
523 -- The indices of the indexed components, or the
524 -- associated expressions of an attribute reference,
525 -- may also involve uplevel references.
527 declare
528 Expr : Node_Id;
530 begin
531 Expr := First (Expressions (N));
532 while Present (Expr) loop
533 Note_Uplevel_Bound (Expr, Ref);
534 Next (Expr);
535 end loop;
536 end;
538 -- Binary operator cases. These can apply to arrays for
539 -- which we may need bounds.
541 elsif Nkind (N) in N_Binary_Op then
542 Note_Uplevel_Bound (Left_Opnd (N), Ref);
543 Note_Uplevel_Bound (Right_Opnd (N), Ref);
545 -- Unary operator case
547 elsif Nkind (N) in N_Unary_Op then
548 Note_Uplevel_Bound (Right_Opnd (N), Ref);
550 -- Explicit dereference and selected component case
552 elsif Nkind_In (N, N_Explicit_Dereference,
553 N_Selected_Component)
554 then
555 Note_Uplevel_Bound (Prefix (N), Ref);
557 -- Conversion case
559 elsif Nkind (N) = N_Type_Conversion then
560 Note_Uplevel_Bound (Expression (N), Ref);
561 end if;
562 end Note_Uplevel_Bound;
564 -- Start of processing for Check_Static_Type
566 begin
567 -- If already marked static, immediate return
569 if Is_Static_Type (T) then
570 return;
571 end if;
573 -- If the type is at library level, always consider it static,
574 -- since such uplevel references are irrelevant.
576 if Is_Library_Level_Entity (T) then
577 Set_Is_Static_Type (T);
578 return;
579 end if;
581 -- Otherwise figure out what the story is with this type
583 -- For a scalar type, check bounds
585 if Is_Scalar_Type (T) then
587 -- If both bounds static, then this is a static type
589 declare
590 LB : constant Node_Id := Type_Low_Bound (T);
591 UB : constant Node_Id := Type_High_Bound (T);
593 begin
594 if not Is_Static_Expression (LB) then
595 Note_Uplevel_Bound (LB, N);
596 DT := True;
597 end if;
599 if not Is_Static_Expression (UB) then
600 Note_Uplevel_Bound (UB, N);
601 DT := True;
602 end if;
603 end;
605 -- For record type, check all components and discriminant
606 -- constraints if present.
608 elsif Is_Record_Type (T) then
609 declare
610 C : Entity_Id;
611 D : Elmt_Id;
613 begin
614 C := First_Component_Or_Discriminant (T);
615 while Present (C) loop
616 Check_Static_Type (Etype (C), N, DT);
617 Next_Component_Or_Discriminant (C);
618 end loop;
620 if Has_Discriminants (T)
621 and then Present (Discriminant_Constraint (T))
622 then
623 D := First_Elmt (Discriminant_Constraint (T));
624 while Present (D) loop
625 if not Is_Static_Expression (Node (D)) then
626 Note_Uplevel_Bound (Node (D), N);
627 DT := True;
628 end if;
630 Next_Elmt (D);
631 end loop;
632 end if;
633 end;
635 -- For array type, check index types and component type
637 elsif Is_Array_Type (T) then
638 declare
639 IX : Node_Id;
640 begin
641 Check_Static_Type (Component_Type (T), N, DT);
643 IX := First_Index (T);
644 while Present (IX) loop
645 Check_Static_Type (Etype (IX), N, DT);
646 Next_Index (IX);
647 end loop;
648 end;
650 -- For private type, examine whether full view is static
652 elsif Is_Private_Type (T) and then Present (Full_View (T)) then
653 Check_Static_Type (Full_View (T), N, DT);
655 if Is_Static_Type (Full_View (T)) then
656 Set_Is_Static_Type (T);
657 end if;
659 -- For now, ignore other types
661 else
662 return;
663 end if;
665 if not DT then
666 Set_Is_Static_Type (T);
667 end if;
668 end Check_Static_Type;
670 ----------------------
671 -- Note_Uplevel_Ref --
672 ----------------------
674 procedure Note_Uplevel_Ref
675 (E : Entity_Id;
676 N : Node_Id;
677 Caller : Entity_Id;
678 Callee : Entity_Id)
680 Full_E : Entity_Id := E;
681 begin
682 -- Nothing to do for static type
684 if Is_Static_Type (E) then
685 return;
686 end if;
688 -- Nothing to do if Caller and Callee are the same
690 if Caller = Callee then
691 return;
693 -- Callee may be a function that returns an array, and that has
694 -- been rewritten as a procedure. If caller is that procedure,
695 -- nothing to do either.
697 elsif Ekind (Callee) = E_Function
698 and then Rewritten_For_C (Callee)
699 and then Corresponding_Procedure (Callee) = Caller
700 then
701 return;
702 end if;
704 -- We have a new uplevel referenced entity
706 if Ekind (E) = E_Constant and then Present (Full_View (E)) then
707 Full_E := Full_View (E);
708 end if;
710 -- All we do at this stage is to add the uplevel reference to
711 -- the table. It's too early to do anything else, since this
712 -- uplevel reference may come from an unreachable subprogram
713 -- in which case the entry will be deleted.
715 Urefs.Append ((N, Full_E, Caller, Callee));
716 end Note_Uplevel_Ref;
718 -------------------------
719 -- Register_Subprogram --
720 -------------------------
722 procedure Register_Subprogram (E : Entity_Id; Bod : Node_Id) is
723 L : constant Nat := Get_Level (Subp, E);
725 begin
726 -- Subprograms declared in tasks and protected types cannot
727 -- be eliminated because calls to them may be in other units,
728 -- so they must be treated as reachable.
730 Subps.Append
731 ((Ent => E,
732 Bod => Bod,
733 Lev => L,
734 Reachable => In_Synchronized_Unit (E),
736 -- Subprograms declared in tasks and protected types are
737 -- reachable and cannot be eliminated.
739 Uplevel_Ref => L,
740 Declares_AREC => False,
741 Uents => No_Elist,
742 Last => 0,
743 ARECnF => Empty,
744 ARECn => Empty,
745 ARECnT => Empty,
746 ARECnPT => Empty,
747 ARECnP => Empty,
748 ARECnU => Empty));
750 Set_Subps_Index (E, UI_From_Int (Subps.Last));
751 end Register_Subprogram;
753 -- Start of processing for Visit_Node
755 begin
756 case Nkind (N) is
758 -- Record a subprogram call
760 when N_Function_Call
761 | N_Procedure_Call_Statement
763 -- We are only interested in direct calls, not indirect
764 -- calls (where Name (N) is an explicit dereference) at
765 -- least for now!
767 if Nkind (Name (N)) in N_Has_Entity then
768 Ent := Entity (Name (N));
770 -- We are only interested in calls to subprograms nested
771 -- within Subp. Calls to Subp itself or to subprograms
772 -- outside the nested structure do not affect us.
774 if Scope_Within (Ent, Subp)
775 and then Is_Subprogram (Ent)
776 and then not Is_Imported (Ent)
777 then
778 Append_Unique_Call ((N, Current_Subprogram, Ent));
779 end if;
780 end if;
782 -- For all calls where the formal is an unconstrained array
783 -- and the actual is constrained we need to check the bounds
784 -- for uplevel references.
786 declare
787 Actual : Entity_Id;
788 DT : Boolean := False;
789 Formal : Node_Id;
790 Subp : Entity_Id;
792 begin
793 if Nkind (Name (N)) = N_Explicit_Dereference then
794 Subp := Etype (Name (N));
795 else
796 Subp := Entity (Name (N));
797 end if;
799 Actual := First_Actual (N);
800 Formal := First_Formal_With_Extras (Subp);
801 while Present (Actual) loop
802 if Is_Array_Type (Etype (Formal))
803 and then not Is_Constrained (Etype (Formal))
804 and then Is_Constrained (Etype (Actual))
805 then
806 Check_Static_Type (Etype (Actual), Empty, DT);
807 end if;
809 Next_Actual (Actual);
810 Next_Formal_With_Extras (Formal);
811 end loop;
812 end;
814 -- An At_End_Proc in a statement sequence indicates that there
815 -- is a call from the enclosing construct or block to that
816 -- subprogram. As above, the called entity must be local and
817 -- not imported.
819 when N_Handled_Sequence_Of_Statements =>
820 if Present (At_End_Proc (N))
821 and then Scope_Within (Entity (At_End_Proc (N)), Subp)
822 and then not Is_Imported (Entity (At_End_Proc (N)))
823 then
824 Append_Unique_Call
825 ((N, Current_Subprogram, Entity (At_End_Proc (N))));
826 end if;
828 -- Similarly, the following constructs include a semantic
829 -- attribute Procedure_To_Call that must be handled like
830 -- other calls. Likewise for attribute Storage_Pool.
832 when N_Allocator
833 | N_Extended_Return_Statement
834 | N_Free_Statement
835 | N_Simple_Return_Statement
837 declare
838 Pool : constant Entity_Id := Storage_Pool (N);
839 Proc : constant Entity_Id := Procedure_To_Call (N);
841 begin
842 if Present (Proc)
843 and then Scope_Within (Proc, Subp)
844 and then not Is_Imported (Proc)
845 then
846 Append_Unique_Call ((N, Current_Subprogram, Proc));
847 end if;
849 if Present (Pool)
850 and then not Is_Library_Level_Entity (Pool)
851 and then Scope_Within_Or_Same (Scope (Pool), Subp)
852 then
853 Caller := Current_Subprogram;
854 Callee := Enclosing_Subprogram (Pool);
856 if Callee /= Caller then
857 Note_Uplevel_Ref (Pool, Empty, Caller, Callee);
858 end if;
859 end if;
860 end;
862 -- For an allocator with a qualified expression, check type
863 -- of expression being qualified. The explicit type name is
864 -- handled as an entity reference.
866 if Nkind (N) = N_Allocator
867 and then Nkind (Expression (N)) = N_Qualified_Expression
868 then
869 declare
870 DT : Boolean := False;
871 begin
872 Check_Static_Type
873 (Etype (Expression (Expression (N))), Empty, DT);
874 end;
876 -- For a Return or Free (all other nodes we handle here),
877 -- we usually need the size of the object, so we need to be
878 -- sure that any nonstatic bounds of the expression's type
879 -- that are uplevel are handled.
881 elsif Nkind (N) /= N_Allocator
882 and then Present (Expression (N))
883 then
884 declare
885 DT : Boolean := False;
886 begin
887 Check_Static_Type (Etype (Expression (N)), Empty, DT);
888 end;
889 end if;
891 -- A 'Access reference is a (potential) call. So is 'Address,
892 -- in particular on imported subprograms. Other attributes
893 -- require special handling.
895 when N_Attribute_Reference =>
896 declare
897 Attr : constant Attribute_Id :=
898 Get_Attribute_Id (Attribute_Name (N));
899 begin
900 case Attr is
901 when Attribute_Access
902 | Attribute_Unchecked_Access
903 | Attribute_Unrestricted_Access
904 | Attribute_Address
906 if Nkind (Prefix (N)) in N_Has_Entity then
907 Ent := Entity (Prefix (N));
909 -- We only need to examine calls to subprograms
910 -- nested within current Subp.
912 if Scope_Within (Ent, Subp) then
913 if Is_Imported (Ent) then
914 null;
916 elsif Is_Subprogram (Ent) then
917 Append_Unique_Call
918 ((N, Current_Subprogram, Ent));
919 end if;
920 end if;
921 end if;
923 -- References to bounds can be uplevel references if
924 -- the type isn't static.
926 when Attribute_First
927 | Attribute_Last
928 | Attribute_Length
930 -- Special-case attributes of objects whose bounds
931 -- may be uplevel references. More complex prefixes
932 -- handled during full traversal. Note that if the
933 -- nominal subtype of the prefix is unconstrained,
934 -- the bound must be obtained from the object, not
935 -- from the (possibly) uplevel reference.
937 if Is_Constrained (Etype (Prefix (N))) then
938 declare
939 DT : Boolean := False;
940 begin
941 Check_Static_Type
942 (Etype (Prefix (N)), Empty, DT);
943 end;
945 return OK;
946 end if;
948 when others =>
949 null;
950 end case;
951 end;
953 -- Component associations in aggregates are either static or
954 -- else the aggregate will be expanded into assignments, in
955 -- which case the expression is analyzed later and provides
956 -- no relevant code generation.
958 when N_Component_Association =>
959 if No (Expression (N))
960 or else No (Etype (Expression (N)))
961 then
962 return Skip;
963 end if;
965 -- Generic associations are not analyzed: the actuals are
966 -- transferred to renaming and subtype declarations that
967 -- are the ones that must be examined.
969 when N_Generic_Association =>
970 return Skip;
972 -- Indexed references can be uplevel if the type isn't static
973 -- and if the lower bound (or an inner bound for a multi-
974 -- dimensional array) is uplevel.
976 when N_Indexed_Component
977 | N_Slice
979 if Is_Constrained (Etype (Prefix (N))) then
980 declare
981 DT : Boolean := False;
982 begin
983 Check_Static_Type (Etype (Prefix (N)), Empty, DT);
984 end;
985 end if;
987 -- A selected component can have an implicit up-level
988 -- reference due to the bounds of previous fields in the
989 -- record. We simplify the processing here by examining
990 -- all components of the record.
992 -- Selected components appear as unit names and end labels
993 -- for child units. Prefixes of these nodes denote parent
994 -- units and carry no type information so they are skipped.
996 when N_Selected_Component =>
997 if Present (Etype (Prefix (N))) then
998 declare
999 DT : Boolean := False;
1000 begin
1001 Check_Static_Type (Etype (Prefix (N)), Empty, DT);
1002 end;
1003 end if;
1005 -- For EQ/NE comparisons, we need the type of the operands
1006 -- in order to do the comparison, which means we need the
1007 -- bounds.
1009 when N_Op_Eq
1010 | N_Op_Ne
1012 declare
1013 DT : Boolean := False;
1014 begin
1015 Check_Static_Type (Etype (Left_Opnd (N)), Empty, DT);
1016 Check_Static_Type (Etype (Right_Opnd (N)), Empty, DT);
1017 end;
1019 -- Likewise we need the sizes to compute how much to move in
1020 -- an assignment.
1022 when N_Assignment_Statement =>
1023 declare
1024 DT : Boolean := False;
1025 begin
1026 Check_Static_Type (Etype (Name (N)), Empty, DT);
1027 Check_Static_Type (Etype (Expression (N)), Empty, DT);
1028 end;
1030 -- Record a subprogram. We record a subprogram body that acts
1031 -- as a spec. Otherwise we record a subprogram declaration,
1032 -- providing that it has a corresponding body we can get hold
1033 -- of. The case of no corresponding body being available is
1034 -- ignored for now.
1036 when N_Subprogram_Body =>
1037 Ent := Unique_Defining_Entity (N);
1039 -- Ignore generic subprogram
1041 if Is_Generic_Subprogram (Ent) then
1042 return Skip;
1043 end if;
1045 -- Make new entry in subprogram table if not already made
1047 Register_Subprogram (Ent, N);
1049 -- We make a recursive call to scan the subprogram body, so
1050 -- that we can save and restore Current_Subprogram.
1052 declare
1053 Save_CS : constant Entity_Id := Current_Subprogram;
1054 Decl : Node_Id;
1056 begin
1057 Current_Subprogram := Ent;
1059 -- Scan declarations
1061 Decl := First (Declarations (N));
1062 while Present (Decl) loop
1063 Visit (Decl);
1064 Next (Decl);
1065 end loop;
1067 -- Scan statements
1069 Visit (Handled_Statement_Sequence (N));
1071 -- Restore current subprogram setting
1073 Current_Subprogram := Save_CS;
1074 end;
1076 -- Now at this level, return skipping the subprogram body
1077 -- descendants, since we already took care of them!
1079 return Skip;
1081 -- If we have a body stub, visit the associated subunit, which
1082 -- is a semantic descendant of the stub.
1084 when N_Body_Stub =>
1085 Visit (Library_Unit (N));
1087 -- A declaration of a wrapper package indicates a subprogram
1088 -- instance for which there is no explicit body. Enter the
1089 -- subprogram instance in the table.
1091 when N_Package_Declaration =>
1092 if Is_Wrapper_Package (Defining_Entity (N)) then
1093 Register_Subprogram
1094 (Related_Instance (Defining_Entity (N)), Empty);
1095 end if;
1097 -- Skip generic declarations
1099 when N_Generic_Declaration =>
1100 return Skip;
1102 -- Skip generic package body
1104 when N_Package_Body =>
1105 if Present (Corresponding_Spec (N))
1106 and then Ekind (Corresponding_Spec (N)) = E_Generic_Package
1107 then
1108 return Skip;
1109 end if;
1111 -- Pragmas and component declarations can be ignored
1113 when N_Component_Declaration
1114 | N_Pragma
1116 return Skip;
1118 -- Otherwise record an uplevel reference in a local identifier
1120 when others =>
1121 if Nkind (N) in N_Has_Entity
1122 and then Present (Entity (N))
1123 then
1124 Ent := Entity (N);
1126 -- Only interested in entities declared within our nest
1128 if not Is_Library_Level_Entity (Ent)
1129 and then Scope_Within_Or_Same (Scope (Ent), Subp)
1131 -- Skip entities defined in inlined subprograms
1133 and then
1134 Chars (Enclosing_Subprogram (Ent)) /= Name_uParent
1136 -- Constants and variables are potentially uplevel
1137 -- references to global declarations.
1139 and then
1140 (Ekind_In (Ent, E_Constant,
1141 E_Loop_Parameter,
1142 E_Variable)
1144 -- Formals are interesting, but not if being used
1145 -- as mere names of parameters for name notation
1146 -- calls.
1148 or else
1149 (Is_Formal (Ent)
1150 and then not
1151 (Nkind (Parent (N)) = N_Parameter_Association
1152 and then Selector_Name (Parent (N)) = N))
1154 -- Types other than known Is_Static types are
1155 -- potentially interesting.
1157 or else
1158 (Is_Type (Ent) and then not Is_Static_Type (Ent)))
1159 then
1160 -- Here we have a potentially interesting uplevel
1161 -- reference to examine.
1163 if Is_Type (Ent) then
1164 declare
1165 DT : Boolean := False;
1167 begin
1168 Check_Static_Type (Ent, N, DT);
1169 return OK;
1170 end;
1171 end if;
1173 Caller := Current_Subprogram;
1174 Callee := Enclosing_Subprogram (Ent);
1176 if Callee /= Caller
1177 and then (not Is_Static_Type (Ent)
1178 or else Needs_Fat_Pointer (Ent))
1179 then
1180 Note_Uplevel_Ref (Ent, N, Caller, Callee);
1182 -- Check the type of a formal parameter of the current
1183 -- subprogram, whose formal type may be an uplevel
1184 -- reference.
1186 elsif Is_Formal (Ent)
1187 and then Scope (Ent) = Current_Subprogram
1188 then
1189 declare
1190 DT : Boolean := False;
1192 begin
1193 Check_Static_Type (Etype (Ent), Empty, DT);
1194 end;
1195 end if;
1196 end if;
1197 end if;
1198 end case;
1200 -- Fall through to continue scanning children of this node
1202 return OK;
1203 end Visit_Node;
1205 -- Start of processing for Build_Tables
1207 begin
1208 -- Traverse the body to get subprograms, calls and uplevel references
1210 Visit (Subp_Body);
1211 end Build_Tables;
1213 -- Now do the first transitive closure which determines which
1214 -- subprograms in the nest are actually reachable.
1216 Reachable_Closure : declare
1217 Modified : Boolean;
1219 begin
1220 Subps.Table (Subps_First).Reachable := True;
1222 -- We use a simple minded algorithm as follows (obviously this can
1223 -- be done more efficiently, using one of the standard algorithms
1224 -- for efficient transitive closure computation, but this is simple
1225 -- and most likely fast enough that its speed does not matter).
1227 -- Repeatedly scan the list of calls. Any time we find a call from
1228 -- A to B, where A is reachable, but B is not, then B is reachable,
1229 -- and note that we have made a change by setting Modified True. We
1230 -- repeat this until we make a pass with no modifications.
1232 Outer : loop
1233 Modified := False;
1234 Inner : for J in Calls.First .. Calls.Last loop
1235 declare
1236 CTJ : Call_Entry renames Calls.Table (J);
1238 SINF : constant SI_Type := Subp_Index (CTJ.Caller);
1239 SINT : constant SI_Type := Subp_Index (CTJ.Callee);
1241 SUBF : Subp_Entry renames Subps.Table (SINF);
1242 SUBT : Subp_Entry renames Subps.Table (SINT);
1244 begin
1245 if SUBF.Reachable and then not SUBT.Reachable then
1246 SUBT.Reachable := True;
1247 Modified := True;
1248 end if;
1249 end;
1250 end loop Inner;
1252 exit Outer when not Modified;
1253 end loop Outer;
1254 end Reachable_Closure;
1256 -- Remove calls from unreachable subprograms
1258 declare
1259 New_Index : Nat;
1261 begin
1262 New_Index := 0;
1263 for J in Calls.First .. Calls.Last loop
1264 declare
1265 CTJ : Call_Entry renames Calls.Table (J);
1267 SINF : constant SI_Type := Subp_Index (CTJ.Caller);
1268 SINT : constant SI_Type := Subp_Index (CTJ.Callee);
1270 SUBF : Subp_Entry renames Subps.Table (SINF);
1271 SUBT : Subp_Entry renames Subps.Table (SINT);
1273 begin
1274 if SUBF.Reachable then
1275 pragma Assert (SUBT.Reachable);
1276 New_Index := New_Index + 1;
1277 Calls.Table (New_Index) := Calls.Table (J);
1278 end if;
1279 end;
1280 end loop;
1282 Calls.Set_Last (New_Index);
1283 end;
1285 -- Remove uplevel references from unreachable subprograms
1287 declare
1288 New_Index : Nat;
1290 begin
1291 New_Index := 0;
1292 for J in Urefs.First .. Urefs.Last loop
1293 declare
1294 URJ : Uref_Entry renames Urefs.Table (J);
1296 SINF : constant SI_Type := Subp_Index (URJ.Caller);
1297 SINT : constant SI_Type := Subp_Index (URJ.Callee);
1299 SUBF : Subp_Entry renames Subps.Table (SINF);
1300 SUBT : Subp_Entry renames Subps.Table (SINT);
1302 S : Entity_Id;
1304 begin
1305 -- Keep reachable reference
1307 if SUBF.Reachable then
1308 New_Index := New_Index + 1;
1309 Urefs.Table (New_Index) := Urefs.Table (J);
1311 -- And since we know we are keeping this one, this is a good
1312 -- place to fill in information for a good reference.
1314 -- Mark all enclosing subprograms need to declare AREC
1316 S := URJ.Caller;
1317 loop
1318 S := Enclosing_Subprogram (S);
1320 -- If we are at the top level, as can happen with
1321 -- references to formals in aspects of nested subprogram
1322 -- declarations, there are no further subprograms to mark
1323 -- as requiring activation records.
1325 exit when No (S);
1327 declare
1328 SUBI : Subp_Entry renames Subps.Table (Subp_Index (S));
1329 begin
1330 SUBI.Declares_AREC := True;
1332 -- If this entity was marked reachable because it is
1333 -- in a task or protected type, there may not appear
1334 -- to be any calls to it, which would normally adjust
1335 -- the levels of the parent subprograms. So we need to
1336 -- be sure that the uplevel reference of that entity
1337 -- takes into account possible calls.
1339 if In_Synchronized_Unit (SUBF.Ent)
1340 and then SUBT.Lev < SUBI.Uplevel_Ref
1341 then
1342 SUBI.Uplevel_Ref := SUBT.Lev;
1343 end if;
1344 end;
1346 exit when S = URJ.Callee;
1347 end loop;
1349 -- Add to list of uplevel referenced entities for Callee.
1350 -- We do not add types to this list, only actual references
1351 -- to objects that will be referenced uplevel, and we use
1352 -- the flag Is_Uplevel_Referenced_Entity to avoid making
1353 -- duplicate entries in the list.
1354 -- Discriminants are also excluded, only the enclosing
1355 -- object can appear in the list.
1357 if not Is_Uplevel_Referenced_Entity (URJ.Ent)
1358 and then Ekind (URJ.Ent) /= E_Discriminant
1359 then
1360 Set_Is_Uplevel_Referenced_Entity (URJ.Ent);
1361 Append_New_Elmt (URJ.Ent, SUBT.Uents);
1362 end if;
1364 -- And set uplevel indication for caller
1366 if SUBT.Lev < SUBF.Uplevel_Ref then
1367 SUBF.Uplevel_Ref := SUBT.Lev;
1368 end if;
1369 end if;
1370 end;
1371 end loop;
1373 Urefs.Set_Last (New_Index);
1374 end;
1376 -- Remove unreachable subprograms from Subps table. Note that we do
1377 -- this after eliminating entries from the other two tables, since
1378 -- those elimination steps depend on referencing the Subps table.
1380 declare
1381 New_SI : SI_Type;
1383 begin
1384 New_SI := Subps_First - 1;
1385 for J in Subps_First .. Subps.Last loop
1386 declare
1387 STJ : Subp_Entry renames Subps.Table (J);
1388 Spec : Node_Id;
1389 Decl : Node_Id;
1391 begin
1392 -- Subprogram is reachable, copy and reset index
1394 if STJ.Reachable then
1395 New_SI := New_SI + 1;
1396 Subps.Table (New_SI) := STJ;
1397 Set_Subps_Index (STJ.Ent, UI_From_Int (New_SI));
1399 -- Subprogram is not reachable
1401 else
1402 -- Clear index, since no longer active
1404 Set_Subps_Index (Subps.Table (J).Ent, Uint_0);
1406 -- Output debug information if -gnatd.3 set
1408 if Debug_Flag_Dot_3 then
1409 Write_Str ("Eliminate ");
1410 Write_Name (Chars (Subps.Table (J).Ent));
1411 Write_Str (" at ");
1412 Write_Location (Sloc (Subps.Table (J).Ent));
1413 Write_Str (" (not referenced)");
1414 Write_Eol;
1415 end if;
1417 -- Rewrite declaration, body, and corresponding freeze node
1418 -- to null statements.
1420 -- A subprogram instantiation does not have an explicit
1421 -- body. If unused, we could remove the corresponding
1422 -- wrapper package and its body (TBD).
1424 if Present (STJ.Bod) then
1425 Spec := Corresponding_Spec (STJ.Bod);
1427 if Present (Spec) then
1428 Decl := Parent (Declaration_Node (Spec));
1429 Rewrite (Decl, Make_Null_Statement (Sloc (Decl)));
1431 if Present (Freeze_Node (Spec)) then
1432 Rewrite (Freeze_Node (Spec),
1433 Make_Null_Statement (Sloc (Decl)));
1434 end if;
1435 end if;
1437 Rewrite (STJ.Bod, Make_Null_Statement (Sloc (STJ.Bod)));
1438 end if;
1439 end if;
1440 end;
1441 end loop;
1443 Subps.Set_Last (New_SI);
1444 end;
1446 -- Now it is time for the second transitive closure, which follows calls
1447 -- and makes sure that A calls B, and B has uplevel references, then A
1448 -- is also marked as having uplevel references.
1450 Closure_Uplevel : declare
1451 Modified : Boolean;
1453 begin
1454 -- We use a simple minded algorithm as follows (obviously this can
1455 -- be done more efficiently, using one of the standard algorithms
1456 -- for efficient transitive closure computation, but this is simple
1457 -- and most likely fast enough that its speed does not matter).
1459 -- Repeatedly scan the list of calls. Any time we find a call from
1460 -- A to B, where B has uplevel references, make sure that A is marked
1461 -- as having at least the same level of uplevel referencing.
1463 Outer2 : loop
1464 Modified := False;
1465 Inner2 : for J in Calls.First .. Calls.Last loop
1466 declare
1467 CTJ : Call_Entry renames Calls.Table (J);
1468 SINF : constant SI_Type := Subp_Index (CTJ.Caller);
1469 SINT : constant SI_Type := Subp_Index (CTJ.Callee);
1470 SUBF : Subp_Entry renames Subps.Table (SINF);
1471 SUBT : Subp_Entry renames Subps.Table (SINT);
1472 begin
1473 if SUBT.Lev > SUBT.Uplevel_Ref
1474 and then SUBF.Uplevel_Ref > SUBT.Uplevel_Ref
1475 then
1476 SUBF.Uplevel_Ref := SUBT.Uplevel_Ref;
1477 Modified := True;
1478 end if;
1479 end;
1480 end loop Inner2;
1482 exit Outer2 when not Modified;
1483 end loop Outer2;
1484 end Closure_Uplevel;
1486 -- We have one more step before the tables are complete. An uplevel
1487 -- call from subprogram A to subprogram B where subprogram B has uplevel
1488 -- references is in effect an uplevel reference, and must arrange for
1489 -- the proper activation link to be passed.
1491 for J in Calls.First .. Calls.Last loop
1492 declare
1493 CTJ : Call_Entry renames Calls.Table (J);
1495 SINF : constant SI_Type := Subp_Index (CTJ.Caller);
1496 SINT : constant SI_Type := Subp_Index (CTJ.Callee);
1498 SUBF : Subp_Entry renames Subps.Table (SINF);
1499 SUBT : Subp_Entry renames Subps.Table (SINT);
1501 A : Entity_Id;
1503 begin
1504 -- If callee has uplevel references
1506 if SUBT.Uplevel_Ref < SUBT.Lev
1508 -- And this is an uplevel call
1510 and then SUBT.Lev < SUBF.Lev
1511 then
1512 -- We need to arrange for finding the uplink
1514 A := CTJ.Caller;
1515 loop
1516 A := Enclosing_Subprogram (A);
1517 Subps.Table (Subp_Index (A)).Declares_AREC := True;
1518 exit when A = CTJ.Callee;
1520 -- In any case exit when we get to the outer level. This
1521 -- happens in some odd cases with generics (in particular
1522 -- sem_ch3.adb does not compile without this kludge ???).
1524 exit when A = Subp;
1525 end loop;
1526 end if;
1527 end;
1528 end loop;
1530 -- The tables are now complete, so we can record the last index in the
1531 -- Subps table for later reference in Cprint.
1533 Subps.Table (Subps_First).Last := Subps.Last;
1535 -- Next step, create the entities for code we will insert. We do this
1536 -- at the start so that all the entities are defined, regardless of the
1537 -- order in which we do the code insertions.
1539 Create_Entities : for J in Subps_First .. Subps.Last loop
1540 declare
1541 STJ : Subp_Entry renames Subps.Table (J);
1542 Loc : constant Source_Ptr := Sloc (STJ.Bod);
1544 begin
1545 -- First we create the ARECnF entity for the additional formal for
1546 -- all subprograms which need an activation record passed.
1548 if STJ.Uplevel_Ref < STJ.Lev then
1549 STJ.ARECnF :=
1550 Make_Defining_Identifier (Loc, Chars => AREC_Name (J, "F"));
1551 end if;
1553 -- Define the AREC entities for the activation record if needed
1555 if STJ.Declares_AREC then
1556 STJ.ARECn :=
1557 Make_Defining_Identifier (Loc, AREC_Name (J, ""));
1558 STJ.ARECnT :=
1559 Make_Defining_Identifier (Loc, AREC_Name (J, "T"));
1560 STJ.ARECnPT :=
1561 Make_Defining_Identifier (Loc, AREC_Name (J, "PT"));
1562 STJ.ARECnP :=
1563 Make_Defining_Identifier (Loc, AREC_Name (J, "P"));
1565 -- Define uplink component entity if inner nesting case
1567 if Present (STJ.ARECnF) then
1568 STJ.ARECnU :=
1569 Make_Defining_Identifier (Loc, AREC_Name (J, "U"));
1570 end if;
1571 end if;
1572 end;
1573 end loop Create_Entities;
1575 -- Loop through subprograms
1577 Subp_Loop : declare
1578 Addr : constant Entity_Id := RTE (RE_Address);
1580 begin
1581 for J in Subps_First .. Subps.Last loop
1582 declare
1583 STJ : Subp_Entry renames Subps.Table (J);
1585 begin
1586 -- First add the extra formal if needed. This applies to all
1587 -- nested subprograms that require an activation record to be
1588 -- passed, as indicated by ARECnF being defined.
1590 if Present (STJ.ARECnF) then
1592 -- Here we need the extra formal. We do the expansion and
1593 -- analysis of this manually, since it is fairly simple,
1594 -- and it is not obvious how we can get what we want if we
1595 -- try to use the normal Analyze circuit.
1597 Add_Extra_Formal : declare
1598 Encl : constant SI_Type := Enclosing_Subp (J);
1599 STJE : Subp_Entry renames Subps.Table (Encl);
1600 -- Index and Subp_Entry for enclosing routine
1602 Form : constant Entity_Id := STJ.ARECnF;
1603 -- The formal to be added. Note that n here is one less
1604 -- than the level of the subprogram itself (STJ.Ent).
1606 procedure Add_Form_To_Spec (F : Entity_Id; S : Node_Id);
1607 -- S is an N_Function/Procedure_Specification node, and F
1608 -- is the new entity to add to this subprogramn spec as
1609 -- the last Extra_Formal.
1611 ----------------------
1612 -- Add_Form_To_Spec --
1613 ----------------------
1615 procedure Add_Form_To_Spec (F : Entity_Id; S : Node_Id) is
1616 Sub : constant Entity_Id := Defining_Entity (S);
1617 Ent : Entity_Id;
1619 begin
1620 -- Case of at least one Extra_Formal is present, set
1621 -- ARECnF as the new last entry in the list.
1623 if Present (Extra_Formals (Sub)) then
1624 Ent := Extra_Formals (Sub);
1625 while Present (Extra_Formal (Ent)) loop
1626 Ent := Extra_Formal (Ent);
1627 end loop;
1629 Set_Extra_Formal (Ent, F);
1631 -- No Extra formals present
1633 else
1634 Set_Extra_Formals (Sub, F);
1635 Ent := Last_Formal (Sub);
1637 if Present (Ent) then
1638 Set_Extra_Formal (Ent, F);
1639 end if;
1640 end if;
1641 end Add_Form_To_Spec;
1643 -- Start of processing for Add_Extra_Formal
1645 begin
1646 -- Decorate the new formal entity
1648 Set_Scope (Form, STJ.Ent);
1649 Set_Ekind (Form, E_In_Parameter);
1650 Set_Etype (Form, STJE.ARECnPT);
1651 Set_Mechanism (Form, By_Copy);
1652 Set_Never_Set_In_Source (Form, True);
1653 Set_Analyzed (Form, True);
1654 Set_Comes_From_Source (Form, False);
1655 Set_Is_Activation_Record (Form, True);
1657 -- Case of only body present
1659 if Acts_As_Spec (STJ.Bod) then
1660 Add_Form_To_Spec (Form, Specification (STJ.Bod));
1662 -- Case of separate spec
1664 else
1665 Add_Form_To_Spec (Form, Parent (STJ.Ent));
1666 end if;
1667 end Add_Extra_Formal;
1668 end if;
1670 -- Processing for subprograms that declare an activation record
1672 if Present (STJ.ARECn) then
1674 -- Local declarations for one such subprogram
1676 declare
1677 Loc : constant Source_Ptr := Sloc (STJ.Bod);
1679 Decls : constant List_Id := New_List;
1680 -- List of new declarations we create
1682 Clist : List_Id;
1683 Comp : Entity_Id;
1685 Decl_Assign : Node_Id;
1686 -- Assigment to set uplink, Empty if none
1688 Decl_ARECnT : Node_Id;
1689 Decl_ARECnPT : Node_Id;
1690 Decl_ARECn : Node_Id;
1691 Decl_ARECnP : Node_Id;
1692 -- Declaration nodes for the AREC entities we build
1694 begin
1695 -- Build list of component declarations for ARECnT
1697 Clist := Empty_List;
1699 -- If we are in a subprogram that has a static link that
1700 -- is passed in (as indicated by ARECnF being defined),
1701 -- then include ARECnU : ARECmPT where ARECmPT comes from
1702 -- the level one higher than the current level, and the
1703 -- entity ARECnPT comes from the enclosing subprogram.
1705 if Present (STJ.ARECnF) then
1706 declare
1707 STJE : Subp_Entry
1708 renames Subps.Table (Enclosing_Subp (J));
1709 begin
1710 Append_To (Clist,
1711 Make_Component_Declaration (Loc,
1712 Defining_Identifier => STJ.ARECnU,
1713 Component_Definition =>
1714 Make_Component_Definition (Loc,
1715 Subtype_Indication =>
1716 New_Occurrence_Of (STJE.ARECnPT, Loc))));
1717 end;
1718 end if;
1720 -- Add components for uplevel referenced entities
1722 if Present (STJ.Uents) then
1723 declare
1724 Elmt : Elmt_Id;
1725 Ptr_Decl : Node_Id;
1726 Uent : Entity_Id;
1728 Indx : Nat;
1729 -- 1's origin of index in list of elements. This is
1730 -- used to uniquify names if needed in Upref_Name.
1732 begin
1733 Elmt := First_Elmt (STJ.Uents);
1734 Indx := 0;
1735 while Present (Elmt) loop
1736 Uent := Node (Elmt);
1737 Indx := Indx + 1;
1739 Comp :=
1740 Make_Defining_Identifier (Loc,
1741 Chars => Upref_Name (Uent, Indx, Clist));
1743 Set_Activation_Record_Component
1744 (Uent, Comp);
1746 if Needs_Fat_Pointer (Uent) then
1748 -- Build corresponding access type
1750 Ptr_Decl :=
1751 Build_Access_Type_Decl
1752 (Etype (Uent), STJ.Ent);
1753 Append_To (Decls, Ptr_Decl);
1755 -- And use its type in the corresponding
1756 -- component.
1758 Append_To (Clist,
1759 Make_Component_Declaration (Loc,
1760 Defining_Identifier => Comp,
1761 Component_Definition =>
1762 Make_Component_Definition (Loc,
1763 Subtype_Indication =>
1764 New_Occurrence_Of
1765 (Defining_Identifier (Ptr_Decl),
1766 Loc))));
1767 else
1768 Append_To (Clist,
1769 Make_Component_Declaration (Loc,
1770 Defining_Identifier => Comp,
1771 Component_Definition =>
1772 Make_Component_Definition (Loc,
1773 Subtype_Indication =>
1774 New_Occurrence_Of (Addr, Loc))));
1775 end if;
1776 Next_Elmt (Elmt);
1777 end loop;
1778 end;
1779 end if;
1781 -- Now we can insert the AREC declarations into the body
1782 -- type ARECnT is record .. end record;
1783 -- pragma Suppress_Initialization (ARECnT);
1785 -- Note that we need to set the Suppress_Initialization
1786 -- flag after Decl_ARECnT has been analyzed.
1788 Decl_ARECnT :=
1789 Make_Full_Type_Declaration (Loc,
1790 Defining_Identifier => STJ.ARECnT,
1791 Type_Definition =>
1792 Make_Record_Definition (Loc,
1793 Component_List =>
1794 Make_Component_List (Loc,
1795 Component_Items => Clist)));
1796 Append_To (Decls, Decl_ARECnT);
1798 -- type ARECnPT is access all ARECnT;
1800 Decl_ARECnPT :=
1801 Make_Full_Type_Declaration (Loc,
1802 Defining_Identifier => STJ.ARECnPT,
1803 Type_Definition =>
1804 Make_Access_To_Object_Definition (Loc,
1805 All_Present => True,
1806 Subtype_Indication =>
1807 New_Occurrence_Of (STJ.ARECnT, Loc)));
1808 Append_To (Decls, Decl_ARECnPT);
1810 -- ARECn : aliased ARECnT;
1812 Decl_ARECn :=
1813 Make_Object_Declaration (Loc,
1814 Defining_Identifier => STJ.ARECn,
1815 Aliased_Present => True,
1816 Object_Definition =>
1817 New_Occurrence_Of (STJ.ARECnT, Loc));
1818 Append_To (Decls, Decl_ARECn);
1820 -- ARECnP : constant ARECnPT := ARECn'Access;
1822 Decl_ARECnP :=
1823 Make_Object_Declaration (Loc,
1824 Defining_Identifier => STJ.ARECnP,
1825 Constant_Present => True,
1826 Object_Definition =>
1827 New_Occurrence_Of (STJ.ARECnPT, Loc),
1828 Expression =>
1829 Make_Attribute_Reference (Loc,
1830 Prefix =>
1831 New_Occurrence_Of (STJ.ARECn, Loc),
1832 Attribute_Name => Name_Access));
1833 Append_To (Decls, Decl_ARECnP);
1835 -- If we are in a subprogram that has a static link that
1836 -- is passed in (as indicated by ARECnF being defined),
1837 -- then generate ARECn.ARECmU := ARECmF where m is
1838 -- one less than the current level to set the uplink.
1840 if Present (STJ.ARECnF) then
1841 Decl_Assign :=
1842 Make_Assignment_Statement (Loc,
1843 Name =>
1844 Make_Selected_Component (Loc,
1845 Prefix =>
1846 New_Occurrence_Of (STJ.ARECn, Loc),
1847 Selector_Name =>
1848 New_Occurrence_Of (STJ.ARECnU, Loc)),
1849 Expression =>
1850 New_Occurrence_Of (STJ.ARECnF, Loc));
1851 Append_To (Decls, Decl_Assign);
1853 else
1854 Decl_Assign := Empty;
1855 end if;
1857 if No (Declarations (STJ.Bod)) then
1858 Set_Declarations (STJ.Bod, Decls);
1859 else
1860 Prepend_List_To (Declarations (STJ.Bod), Decls);
1861 end if;
1863 -- Analyze the newly inserted declarations. Note that we
1864 -- do not need to establish the whole scope stack, since
1865 -- we have already set all entity fields (so there will
1866 -- be no searching of upper scopes to resolve names). But
1867 -- we do set the scope of the current subprogram, so that
1868 -- newly created entities go in the right entity chain.
1870 -- We analyze with all checks suppressed (since we do
1871 -- not expect any exceptions).
1873 Push_Scope (STJ.Ent);
1874 Analyze (Decl_ARECnT, Suppress => All_Checks);
1876 -- Note that we need to call Set_Suppress_Initialization
1877 -- after Decl_ARECnT has been analyzed, but before
1878 -- analyzing Decl_ARECnP so that the flag is properly
1879 -- taking into account.
1881 Set_Suppress_Initialization (STJ.ARECnT);
1883 Analyze (Decl_ARECnPT, Suppress => All_Checks);
1884 Analyze (Decl_ARECn, Suppress => All_Checks);
1885 Analyze (Decl_ARECnP, Suppress => All_Checks);
1887 if Present (Decl_Assign) then
1888 Analyze (Decl_Assign, Suppress => All_Checks);
1889 end if;
1891 Pop_Scope;
1893 -- Next step, for each uplevel referenced entity, add
1894 -- assignment operations to set the component in the
1895 -- activation record.
1897 if Present (STJ.Uents) then
1898 declare
1899 Elmt : Elmt_Id;
1901 begin
1902 Elmt := First_Elmt (STJ.Uents);
1903 while Present (Elmt) loop
1904 declare
1905 Ent : constant Entity_Id := Node (Elmt);
1906 Loc : constant Source_Ptr := Sloc (Ent);
1907 Dec : constant Node_Id :=
1908 Declaration_Node (Ent);
1910 Asn : Node_Id;
1911 Attr : Name_Id;
1912 Ins : Node_Id;
1914 begin
1915 -- For parameters, we insert the assignment
1916 -- right after the declaration of ARECnP.
1917 -- For all other entities, we insert the
1918 -- assignment immediately after the
1919 -- declaration of the entity or after the
1920 -- freeze node if present.
1922 -- Note: we don't need to mark the entity
1923 -- as being aliased, because the address
1924 -- attribute will mark it as Address_Taken,
1925 -- and that is good enough.
1927 if Is_Formal (Ent) then
1928 Ins := Decl_ARECnP;
1930 elsif Has_Delayed_Freeze (Ent) then
1931 Ins := Freeze_Node (Ent);
1933 else
1934 Ins := Dec;
1935 end if;
1937 -- Build and insert the assignment:
1938 -- ARECn.nam := nam'Address
1939 -- or else 'Access for unconstrained array
1941 if Needs_Fat_Pointer (Ent) then
1942 Attr := Name_Access;
1943 else
1944 Attr := Name_Address;
1945 end if;
1947 Asn :=
1948 Make_Assignment_Statement (Loc,
1949 Name =>
1950 Make_Selected_Component (Loc,
1951 Prefix =>
1952 New_Occurrence_Of (STJ.ARECn, Loc),
1953 Selector_Name =>
1954 New_Occurrence_Of
1955 (Activation_Record_Component
1956 (Ent),
1957 Loc)),
1959 Expression =>
1960 Make_Attribute_Reference (Loc,
1961 Prefix =>
1962 New_Occurrence_Of (Ent, Loc),
1963 Attribute_Name => Attr));
1965 -- If we have a loop parameter, we have
1966 -- to insert before the first statement
1967 -- of the loop. Ins points to the
1968 -- N_Loop_Parameter_Specification.
1970 if Ekind (Ent) = E_Loop_Parameter then
1971 Ins :=
1972 First
1973 (Statements (Parent (Parent (Ins))));
1974 Insert_Before (Ins, Asn);
1976 else
1977 Insert_After (Ins, Asn);
1978 end if;
1980 -- Analyze the assignment statement. We do
1981 -- not need to establish the relevant scope
1982 -- stack entries here, because we have
1983 -- already set the correct entity references,
1984 -- so no name resolution is required, and no
1985 -- new entities are created, so we don't even
1986 -- need to set the current scope.
1988 -- We analyze with all checks suppressed
1989 -- (since we do not expect any exceptions).
1991 Analyze (Asn, Suppress => All_Checks);
1992 end;
1994 Next_Elmt (Elmt);
1995 end loop;
1996 end;
1997 end if;
1998 end;
1999 end if;
2000 end;
2001 end loop;
2002 end Subp_Loop;
2004 -- Next step, process uplevel references. This has to be done in a
2005 -- separate pass, after completing the processing in Sub_Loop because we
2006 -- need all the AREC declarations generated, inserted, and analyzed so
2007 -- that the uplevel references can be successfully analyzed.
2009 Uplev_Refs : for J in Urefs.First .. Urefs.Last loop
2010 declare
2011 UPJ : Uref_Entry renames Urefs.Table (J);
2013 begin
2014 -- Ignore type references, these are implicit references that do
2015 -- not need rewriting (e.g. the appearence in a conversion).
2016 -- Also ignore if no reference was specified or if the rewriting
2017 -- has already been done (this can happen if the N_Identifier
2018 -- occurs more than one time in the tree).
2020 if No (UPJ.Ref)
2021 or else not Is_Entity_Name (UPJ.Ref)
2022 or else not Present (Entity (UPJ.Ref))
2023 then
2024 goto Continue;
2025 end if;
2027 -- Rewrite one reference
2029 Rewrite_One_Ref : declare
2030 Loc : constant Source_Ptr := Sloc (UPJ.Ref);
2031 -- Source location for the reference
2033 Typ : constant Entity_Id := Etype (UPJ.Ent);
2034 -- The type of the referenced entity
2036 Atyp : Entity_Id;
2037 -- The actual subtype of the reference
2039 RS_Caller : constant SI_Type := Subp_Index (UPJ.Caller);
2040 -- Subp_Index for caller containing reference
2042 STJR : Subp_Entry renames Subps.Table (RS_Caller);
2043 -- Subp_Entry for subprogram containing reference
2045 RS_Callee : constant SI_Type := Subp_Index (UPJ.Callee);
2046 -- Subp_Index for subprogram containing referenced entity
2048 STJE : Subp_Entry renames Subps.Table (RS_Callee);
2049 -- Subp_Entry for subprogram containing referenced entity
2051 Pfx : Node_Id;
2052 Comp : Entity_Id;
2053 SI : SI_Type;
2055 begin
2056 Atyp := Etype (UPJ.Ref);
2058 if Ekind (Atyp) /= E_Record_Subtype then
2059 Atyp := Get_Actual_Subtype (UPJ.Ref);
2060 end if;
2062 -- Ignore if no ARECnF entity for enclosing subprogram which
2063 -- probably happens as a result of not properly treating
2064 -- instance bodies. To be examined ???
2066 -- If this test is omitted, then the compilation of freeze.adb
2067 -- and inline.adb fail in unnesting mode.
2069 if No (STJR.ARECnF) then
2070 goto Continue;
2071 end if;
2073 -- Push the current scope, so that the pointer type Tnn, and
2074 -- any subsidiary entities resulting from the analysis of the
2075 -- rewritten reference, go in the right entity chain.
2077 Push_Scope (STJR.Ent);
2079 -- Now we need to rewrite the reference. We have a reference
2080 -- from level STJR.Lev to level STJE.Lev. The general form of
2081 -- the rewritten reference for entity X is:
2083 -- Typ'Deref (ARECaF.ARECbU.ARECcU.ARECdU....ARECmU.X)
2085 -- where a,b,c,d .. m =
2086 -- STJR.Lev - 1, STJR.Lev - 2, .. STJE.Lev
2088 pragma Assert (STJR.Lev > STJE.Lev);
2090 -- Compute the prefix of X. Here are examples to make things
2091 -- clear (with parens to show groupings, the prefix is
2092 -- everything except the .X at the end).
2094 -- level 2 to level 1
2096 -- AREC1F.X
2098 -- level 3 to level 1
2100 -- (AREC2F.AREC1U).X
2102 -- level 4 to level 1
2104 -- ((AREC3F.AREC2U).AREC1U).X
2106 -- level 6 to level 2
2108 -- (((AREC5F.AREC4U).AREC3U).AREC2U).X
2110 -- In the above, ARECnF and ARECnU are pointers, so there are
2111 -- explicit dereferences required for these occurrences.
2113 Pfx :=
2114 Make_Explicit_Dereference (Loc,
2115 Prefix => New_Occurrence_Of (STJR.ARECnF, Loc));
2116 SI := RS_Caller;
2117 for L in STJE.Lev .. STJR.Lev - 2 loop
2118 SI := Enclosing_Subp (SI);
2119 Pfx :=
2120 Make_Explicit_Dereference (Loc,
2121 Prefix =>
2122 Make_Selected_Component (Loc,
2123 Prefix => Pfx,
2124 Selector_Name =>
2125 New_Occurrence_Of (Subps.Table (SI).ARECnU, Loc)));
2126 end loop;
2128 -- Get activation record component (must exist)
2130 Comp := Activation_Record_Component (UPJ.Ent);
2131 pragma Assert (Present (Comp));
2133 -- Do the replacement. If the component type is an access type,
2134 -- this is an uplevel reference for an entity that requires a
2135 -- fat pointer, so dereference the component.
2137 if Is_Access_Type (Etype (Comp)) then
2138 Rewrite (UPJ.Ref,
2139 Make_Explicit_Dereference (Loc,
2140 Prefix =>
2141 Make_Selected_Component (Loc,
2142 Prefix => Pfx,
2143 Selector_Name =>
2144 New_Occurrence_Of (Comp, Loc))));
2146 else
2147 Rewrite (UPJ.Ref,
2148 Make_Attribute_Reference (Loc,
2149 Prefix => New_Occurrence_Of (Atyp, Loc),
2150 Attribute_Name => Name_Deref,
2151 Expressions => New_List (
2152 Make_Selected_Component (Loc,
2153 Prefix => Pfx,
2154 Selector_Name =>
2155 New_Occurrence_Of (Comp, Loc)))));
2156 end if;
2158 -- Analyze and resolve the new expression. We do not need to
2159 -- establish the relevant scope stack entries here, because we
2160 -- have already set all the correct entity references, so no
2161 -- name resolution is needed. We have already set the current
2162 -- scope, so that any new entities created will be in the right
2163 -- scope.
2165 -- We analyze with all checks suppressed (since we do not
2166 -- expect any exceptions)
2168 Analyze_And_Resolve (UPJ.Ref, Typ, Suppress => All_Checks);
2169 Pop_Scope;
2170 end Rewrite_One_Ref;
2171 end;
2173 <<Continue>>
2174 null;
2175 end loop Uplev_Refs;
2177 -- Finally, loop through all calls adding extra actual for the
2178 -- activation record where it is required.
2180 Adjust_Calls : for J in Calls.First .. Calls.Last loop
2182 -- Process a single call, we are only interested in a call to a
2183 -- subprogram that actually needs a pointer to an activation record,
2184 -- as indicated by the ARECnF entity being set. This excludes the
2185 -- top level subprogram, and any subprogram not having uplevel refs.
2187 Adjust_One_Call : declare
2188 CTJ : Call_Entry renames Calls.Table (J);
2189 STF : Subp_Entry renames Subps.Table (Subp_Index (CTJ.Caller));
2190 STT : Subp_Entry renames Subps.Table (Subp_Index (CTJ.Callee));
2192 Loc : constant Source_Ptr := Sloc (CTJ.N);
2194 Extra : Node_Id;
2195 ExtraP : Node_Id;
2196 SubX : SI_Type;
2197 Act : Node_Id;
2199 begin
2200 if Present (STT.ARECnF)
2201 and then Nkind (CTJ.N) in N_Subprogram_Call
2202 then
2203 -- CTJ.N is a call to a subprogram which may require a pointer
2204 -- to an activation record. The subprogram containing the call
2205 -- is CTJ.From and the subprogram being called is CTJ.To, so we
2206 -- have a call from level STF.Lev to level STT.Lev.
2208 -- There are three possibilities:
2210 -- For a call to the same level, we just pass the activation
2211 -- record passed to the calling subprogram.
2213 if STF.Lev = STT.Lev then
2214 Extra := New_Occurrence_Of (STF.ARECnF, Loc);
2216 -- For a call that goes down a level, we pass a pointer to the
2217 -- activation record constructed within the caller (which may
2218 -- be the outer-level subprogram, but also may be a more deeply
2219 -- nested caller).
2221 elsif STT.Lev = STF.Lev + 1 then
2222 Extra := New_Occurrence_Of (STF.ARECnP, Loc);
2224 -- Otherwise we must have an upcall (STT.Lev < STF.LEV),
2225 -- since it is not possible to do a downcall of more than
2226 -- one level.
2228 -- For a call from level STF.Lev to level STT.Lev, we
2229 -- have to find the activation record needed by the
2230 -- callee. This is as follows:
2232 -- ARECaF.ARECbU.ARECcU....ARECmU
2234 -- where a,b,c .. m =
2235 -- STF.Lev - 1, STF.Lev - 2, STF.Lev - 3 .. STT.Lev
2237 else
2238 pragma Assert (STT.Lev < STF.Lev);
2240 Extra := New_Occurrence_Of (STF.ARECnF, Loc);
2241 SubX := Subp_Index (CTJ.Caller);
2242 for K in reverse STT.Lev .. STF.Lev - 1 loop
2243 SubX := Enclosing_Subp (SubX);
2244 Extra :=
2245 Make_Selected_Component (Loc,
2246 Prefix => Extra,
2247 Selector_Name =>
2248 New_Occurrence_Of
2249 (Subps.Table (SubX).ARECnU, Loc));
2250 end loop;
2251 end if;
2253 -- Extra is the additional parameter to be added. Build a
2254 -- parameter association that we can append to the actuals.
2256 ExtraP :=
2257 Make_Parameter_Association (Loc,
2258 Selector_Name =>
2259 New_Occurrence_Of (STT.ARECnF, Loc),
2260 Explicit_Actual_Parameter => Extra);
2262 if No (Parameter_Associations (CTJ.N)) then
2263 Set_Parameter_Associations (CTJ.N, Empty_List);
2264 end if;
2266 Append (ExtraP, Parameter_Associations (CTJ.N));
2268 -- We need to deal with the actual parameter chain as well. The
2269 -- newly added parameter is always the last actual.
2271 Act := First_Named_Actual (CTJ.N);
2273 if No (Act) then
2274 Set_First_Named_Actual (CTJ.N, Extra);
2276 -- If call has been relocated (as with an expression in
2277 -- an aggregate), set First_Named pointer in original node
2278 -- as well, because that's the parent of the parameter list.
2280 Set_First_Named_Actual
2281 (Parent (List_Containing (ExtraP)), Extra);
2283 -- Here we must follow the chain and append the new entry
2285 else
2286 loop
2287 declare
2288 PAN : Node_Id;
2289 NNA : Node_Id;
2291 begin
2292 PAN := Parent (Act);
2293 pragma Assert (Nkind (PAN) = N_Parameter_Association);
2294 NNA := Next_Named_Actual (PAN);
2296 if No (NNA) then
2297 Set_Next_Named_Actual (PAN, Extra);
2298 exit;
2299 end if;
2301 Act := NNA;
2302 end;
2303 end loop;
2304 end if;
2306 -- Analyze and resolve the new actual. We do not need to
2307 -- establish the relevant scope stack entries here, because
2308 -- we have already set all the correct entity references, so
2309 -- no name resolution is needed.
2311 -- We analyze with all checks suppressed (since we do not
2312 -- expect any exceptions, and also we temporarily turn off
2313 -- Unested_Subprogram_Mode to avoid trying to mark uplevel
2314 -- references (not needed at this stage, and in fact causes
2315 -- a bit of recursive chaos).
2317 Opt.Unnest_Subprogram_Mode := False;
2318 Analyze_And_Resolve
2319 (Extra, Etype (STT.ARECnF), Suppress => All_Checks);
2320 Opt.Unnest_Subprogram_Mode := True;
2321 end if;
2322 end Adjust_One_Call;
2323 end loop Adjust_Calls;
2325 return;
2326 end Unnest_Subprogram;
2328 ------------------------
2329 -- Unnest_Subprograms --
2330 ------------------------
2332 procedure Unnest_Subprograms (N : Node_Id) is
2333 function Search_Subprograms (N : Node_Id) return Traverse_Result;
2334 -- Tree visitor that search for outer level procedures with nested
2335 -- subprograms and invokes Unnest_Subprogram()
2337 ---------------
2338 -- Do_Search --
2339 ---------------
2341 procedure Do_Search is new Traverse_Proc (Search_Subprograms);
2342 -- Subtree visitor instantiation
2344 ------------------------
2345 -- Search_Subprograms --
2346 ------------------------
2348 function Search_Subprograms (N : Node_Id) return Traverse_Result is
2349 begin
2350 if Nkind_In (N, N_Subprogram_Body, N_Subprogram_Body_Stub) then
2351 declare
2352 Spec_Id : constant Entity_Id := Unique_Defining_Entity (N);
2354 begin
2355 -- We are only interested in subprograms (not generic
2356 -- subprograms), that have nested subprograms.
2358 if Is_Subprogram (Spec_Id)
2359 and then Has_Nested_Subprogram (Spec_Id)
2360 and then Is_Library_Level_Entity (Spec_Id)
2361 then
2362 Unnest_Subprogram (Spec_Id, N);
2363 end if;
2364 end;
2366 -- The proper body of a stub may contain nested subprograms, and
2367 -- therefore must be visited explicitly. Nested stubs are examined
2368 -- recursively in Visit_Node.
2370 elsif Nkind (N) in N_Body_Stub then
2371 Do_Search (Library_Unit (N));
2372 end if;
2374 return OK;
2375 end Search_Subprograms;
2377 -- Start of processing for Unnest_Subprograms
2379 begin
2380 if not Opt.Unnest_Subprogram_Mode or not Opt.Expander_Active then
2381 return;
2382 end if;
2384 -- A specification will contain bodies if it contains instantiations so
2385 -- examine package or subprogram declaration of the main unit, when it
2386 -- is present.
2388 if Nkind (Unit (N)) = N_Package_Body
2389 or else (Nkind (Unit (N)) = N_Subprogram_Body
2390 and then not Acts_As_Spec (N))
2391 then
2392 Do_Search (Library_Unit (N));
2393 end if;
2395 Do_Search (N);
2396 end Unnest_Subprograms;
2398 end Exp_Unst;