[Ada] Minor reformatting
[official-gcc.git] / gcc / ada / exp_unst.adb
blob12cb9bd656e17a37d3df7571b1a0c1b0f9a7f1ea
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 if Ekind (E) = E_Function
263 and then Rewritten_For_C (E)
264 and then Present (Corresponding_Procedure (E))
265 then
266 E := Corresponding_Procedure (E);
267 end if;
268 end if;
270 pragma Assert (Subps_Index (E) /= Uint_0);
271 return SI_Type (UI_To_Int (Subps_Index (E)));
272 end Subp_Index;
274 -----------------------
275 -- Unnest_Subprogram --
276 -----------------------
278 procedure Unnest_Subprogram (Subp : Entity_Id; Subp_Body : Node_Id) is
279 function AREC_Name (J : Pos; S : String) return Name_Id;
280 -- Returns name for string ARECjS, where j is the decimal value of j
282 function Enclosing_Subp (Subp : SI_Type) return SI_Type;
283 -- Subp is the index of a subprogram which has a Lev greater than 1.
284 -- This function returns the index of the enclosing subprogram which
285 -- will have a Lev value one less than this.
287 function Img_Pos (N : Pos) return String;
288 -- Return image of N without leading blank
290 function Upref_Name
291 (Ent : Entity_Id;
292 Index : Pos;
293 Clist : List_Id) return Name_Id;
294 -- This function returns the name to be used in the activation record to
295 -- reference the variable uplevel. Clist is the list of components that
296 -- have been created in the activation record so far. Normally the name
297 -- is just a copy of the Chars field of the entity. The exception is
298 -- when the name has already been used, in which case we suffix the name
299 -- with the index value Index to avoid duplication. This happens with
300 -- declare blocks and generic parameters at least.
302 ---------------
303 -- AREC_Name --
304 ---------------
306 function AREC_Name (J : Pos; S : String) return Name_Id is
307 begin
308 return Name_Find ("AREC" & Img_Pos (J) & S);
309 end AREC_Name;
311 --------------------
312 -- Enclosing_Subp --
313 --------------------
315 function Enclosing_Subp (Subp : SI_Type) return SI_Type is
316 STJ : Subp_Entry renames Subps.Table (Subp);
317 Ret : constant SI_Type := Subp_Index (Enclosing_Subprogram (STJ.Ent));
318 begin
319 pragma Assert (STJ.Lev > 1);
320 pragma Assert (Subps.Table (Ret).Lev = STJ.Lev - 1);
321 return Ret;
322 end Enclosing_Subp;
324 -------------
325 -- Img_Pos --
326 -------------
328 function Img_Pos (N : Pos) return String is
329 Buf : String (1 .. 20);
330 Ptr : Natural;
331 NV : Nat;
333 begin
334 Ptr := Buf'Last;
335 NV := N;
336 while NV /= 0 loop
337 Buf (Ptr) := Character'Val (48 + NV mod 10);
338 Ptr := Ptr - 1;
339 NV := NV / 10;
340 end loop;
342 return Buf (Ptr + 1 .. Buf'Last);
343 end Img_Pos;
345 ----------------
346 -- Upref_Name --
347 ----------------
349 function Upref_Name
350 (Ent : Entity_Id;
351 Index : Pos;
352 Clist : List_Id) return Name_Id
354 C : Node_Id;
355 begin
356 C := First (Clist);
357 loop
358 if No (C) then
359 return Chars (Ent);
361 elsif Chars (Defining_Identifier (C)) = Chars (Ent) then
362 return
363 Name_Find (Get_Name_String (Chars (Ent)) & Img_Pos (Index));
364 else
365 Next (C);
366 end if;
367 end loop;
368 end Upref_Name;
370 -- Start of processing for Unnest_Subprogram
372 begin
373 -- Nothing to do inside a generic (all processing is for instance)
375 if Inside_A_Generic then
376 return;
377 end if;
379 -- If the main unit is a package body then we need to examine the spec
380 -- to determine whether the main unit is generic (the scope stack is not
381 -- present when this is called on the main unit).
383 if Ekind (Cunit_Entity (Main_Unit)) = E_Package_Body
384 and then Is_Generic_Unit (Spec_Entity (Cunit_Entity (Main_Unit)))
385 then
386 return;
387 end if;
389 -- Only unnest when generating code for the main source unit
391 if not In_Extended_Main_Code_Unit (Subp_Body) then
392 return;
393 end if;
395 -- This routine is called late, after the scope stack is gone. The
396 -- following creates a suitable dummy scope stack to be used for the
397 -- analyze/expand calls made from this routine.
399 Push_Scope (Subp);
401 -- First step, we must mark all nested subprograms that require a static
402 -- link (activation record) because either they contain explicit uplevel
403 -- references (as indicated by Is_Uplevel_Referenced_Entity being set at
404 -- this point), or they make calls to other subprograms in the same nest
405 -- that require a static link (in which case we set this flag).
407 -- This is a recursive definition, and to implement this, we have to
408 -- build a call graph for the set of nested subprograms, and then go
409 -- over this graph to implement recursively the invariant that if a
410 -- subprogram has a call to a subprogram requiring a static link, then
411 -- the calling subprogram requires a static link.
413 -- First populate the above tables
415 Subps_First := Subps.Last + 1;
416 Calls.Init;
417 Urefs.Init;
419 Build_Tables : declare
420 Current_Subprogram : Entity_Id;
421 -- When we scan a subprogram body, we set Current_Subprogram to the
422 -- corresponding entity. This gets recursively saved and restored.
424 function Visit_Node (N : Node_Id) return Traverse_Result;
425 -- Visit a single node in Subp
427 -----------
428 -- Visit --
429 -----------
431 procedure Visit is new Traverse_Proc (Visit_Node);
432 -- Used to traverse the body of Subp, populating the tables
434 ----------------
435 -- Visit_Node --
436 ----------------
438 function Visit_Node (N : Node_Id) return Traverse_Result is
439 Ent : Entity_Id;
440 Caller : Entity_Id;
441 Callee : Entity_Id;
443 procedure Check_Static_Type
444 (T : Entity_Id; N : Node_Id; DT : in out Boolean);
445 -- Given a type T, checks if it is a static type defined as a type
446 -- with no dynamic bounds in sight. If so, the only action is to
447 -- set Is_Static_Type True for T. If T is not a static type, then
448 -- all types with dynamic bounds associated with T are detected,
449 -- and their bounds are marked as uplevel referenced if not at the
450 -- library level, and DT is set True. If N is specified, it's the
451 -- node that will need to be replaced. If not specified, it means
452 -- we can't do a replacement because the bound is implicit.
454 procedure Note_Uplevel_Ref
455 (E : Entity_Id;
456 N : Node_Id;
457 Caller : Entity_Id;
458 Callee : Entity_Id);
459 -- Called when we detect an explicit or implicit uplevel reference
460 -- from within Caller to entity E declared in Callee. E can be a
461 -- an object or a type.
463 procedure Register_Subprogram (E : Entity_Id; Bod : Node_Id);
464 -- Enter a subprogram whose body is visible or which is a
465 -- subprogram instance into the subprogram table.
467 -----------------------
468 -- Check_Static_Type --
469 -----------------------
471 procedure Check_Static_Type
472 (T : Entity_Id; N : Node_Id; DT : in out Boolean)
474 procedure Note_Uplevel_Bound (N : Node_Id; Ref : Node_Id);
475 -- N is the bound of a dynamic type. This procedure notes that
476 -- this bound is uplevel referenced, it can handle references
477 -- to entities (typically _FIRST and _LAST entities), and also
478 -- attribute references of the form T'name (name is typically
479 -- FIRST or LAST) where T is the uplevel referenced bound.
480 -- Ref, if Present, is the location of the reference to
481 -- replace.
483 ------------------------
484 -- Note_Uplevel_Bound --
485 ------------------------
487 procedure Note_Uplevel_Bound (N : Node_Id; Ref : Node_Id) is
488 begin
489 -- Entity name case. Make sure that the entity is declared
490 -- in a subprogram. This may not be the case for for a type
491 -- in a loop appearing in a precondition.
492 -- Exclude explicitly discriminants (that can appear
493 -- in bounds of discriminated components).
495 if Is_Entity_Name (N) then
496 if Present (Entity (N))
497 and then Present (Enclosing_Subprogram (Entity (N)))
498 and then Ekind (Entity (N)) /= E_Discriminant
499 then
500 Note_Uplevel_Ref
501 (E => Entity (N),
502 N => Ref,
503 Caller => Current_Subprogram,
504 Callee => Enclosing_Subprogram (Entity (N)));
505 end if;
507 -- Attribute or indexed component case
509 elsif Nkind_In (N, N_Attribute_Reference,
510 N_Indexed_Component)
511 then
512 Note_Uplevel_Bound (Prefix (N), Ref);
514 -- The indices of the indexed components, or the
515 -- associated expressions of an attribute reference,
516 -- may also involve uplevel references.
518 declare
519 Expr : Node_Id;
521 begin
522 Expr := First (Expressions (N));
523 while Present (Expr) loop
524 Note_Uplevel_Bound (Expr, Ref);
525 Next (Expr);
526 end loop;
527 end;
529 -- Binary operator cases. These can apply to arrays for
530 -- which we may need bounds.
532 elsif Nkind (N) in N_Binary_Op then
533 Note_Uplevel_Bound (Left_Opnd (N), Ref);
534 Note_Uplevel_Bound (Right_Opnd (N), Ref);
536 -- Unary operator case
538 elsif Nkind (N) in N_Unary_Op then
539 Note_Uplevel_Bound (Right_Opnd (N), Ref);
541 -- Explicit dereference case
543 elsif Nkind (N) = N_Explicit_Dereference then
544 Note_Uplevel_Bound (Prefix (N), Ref);
546 -- Conversion case
548 elsif Nkind (N) = N_Type_Conversion then
549 Note_Uplevel_Bound (Expression (N), Ref);
550 end if;
551 end Note_Uplevel_Bound;
553 -- Start of processing for Check_Static_Type
555 begin
556 -- If already marked static, immediate return
558 if Is_Static_Type (T) then
559 return;
560 end if;
562 -- If the type is at library level, always consider it static,
563 -- since such uplevel references are irrelevant.
565 if Is_Library_Level_Entity (T) then
566 Set_Is_Static_Type (T);
567 return;
568 end if;
570 -- Otherwise figure out what the story is with this type
572 -- For a scalar type, check bounds
574 if Is_Scalar_Type (T) then
576 -- If both bounds static, then this is a static type
578 declare
579 LB : constant Node_Id := Type_Low_Bound (T);
580 UB : constant Node_Id := Type_High_Bound (T);
582 begin
583 if not Is_Static_Expression (LB) then
584 Note_Uplevel_Bound (LB, N);
585 DT := True;
586 end if;
588 if not Is_Static_Expression (UB) then
589 Note_Uplevel_Bound (UB, N);
590 DT := True;
591 end if;
592 end;
594 -- For record type, check all components and discriminant
595 -- constraints if present.
597 elsif Is_Record_Type (T) then
598 declare
599 C : Entity_Id;
600 D : Elmt_Id;
602 begin
603 C := First_Component_Or_Discriminant (T);
604 while Present (C) loop
605 Check_Static_Type (Etype (C), N, DT);
606 Next_Component_Or_Discriminant (C);
607 end loop;
609 if Has_Discriminants (T)
610 and then Present (Discriminant_Constraint (T))
611 then
612 D := First_Elmt (Discriminant_Constraint (T));
613 while Present (D) loop
614 if not Is_Static_Expression (Node (D)) then
615 Note_Uplevel_Bound (Node (D), N);
616 DT := True;
617 end if;
619 Next_Elmt (D);
620 end loop;
621 end if;
622 end;
624 -- For array type, check index types and component type
626 elsif Is_Array_Type (T) then
627 declare
628 IX : Node_Id;
629 begin
630 Check_Static_Type (Component_Type (T), N, DT);
632 IX := First_Index (T);
633 while Present (IX) loop
634 Check_Static_Type (Etype (IX), N, DT);
635 Next_Index (IX);
636 end loop;
637 end;
639 -- For private type, examine whether full view is static
641 elsif Is_Private_Type (T) and then Present (Full_View (T)) then
642 Check_Static_Type (Full_View (T), N, DT);
644 if Is_Static_Type (Full_View (T)) then
645 Set_Is_Static_Type (T);
646 end if;
648 -- For now, ignore other types
650 else
651 return;
652 end if;
654 if not DT then
655 Set_Is_Static_Type (T);
656 end if;
657 end Check_Static_Type;
659 ----------------------
660 -- Note_Uplevel_Ref --
661 ----------------------
663 procedure Note_Uplevel_Ref
664 (E : Entity_Id;
665 N : Node_Id;
666 Caller : Entity_Id;
667 Callee : Entity_Id)
669 Full_E : Entity_Id := E;
670 begin
671 -- Nothing to do for static type
673 if Is_Static_Type (E) then
674 return;
675 end if;
677 -- Nothing to do if Caller and Callee are the same
679 if Caller = Callee then
680 return;
682 -- Callee may be a function that returns an array, and that has
683 -- been rewritten as a procedure. If caller is that procedure,
684 -- nothing to do either.
686 elsif Ekind (Callee) = E_Function
687 and then Rewritten_For_C (Callee)
688 and then Corresponding_Procedure (Callee) = Caller
689 then
690 return;
691 end if;
693 -- We have a new uplevel referenced entity
695 if Ekind (E) = E_Constant and then Present (Full_View (E)) then
696 Full_E := Full_View (E);
697 end if;
699 -- All we do at this stage is to add the uplevel reference to
700 -- the table. It's too early to do anything else, since this
701 -- uplevel reference may come from an unreachable subprogram
702 -- in which case the entry will be deleted.
704 Urefs.Append ((N, Full_E, Caller, Callee));
705 end Note_Uplevel_Ref;
707 -------------------------
708 -- Register_Subprogram --
709 -------------------------
711 procedure Register_Subprogram (E : Entity_Id; Bod : Node_Id) is
712 L : constant Nat := Get_Level (Subp, E);
714 -- Subprograms declared in tasks and protected types cannot
715 -- be eliminated because calls to them may be in other units,
716 -- so they must be treated as reachable.
718 begin
719 Subps.Append
720 ((Ent => E,
721 Bod => Bod,
722 Lev => L,
723 Reachable => In_Synchronized_Unit (E),
724 Uplevel_Ref => L,
725 Declares_AREC => False,
726 Uents => No_Elist,
727 Last => 0,
728 ARECnF => Empty,
729 ARECn => Empty,
730 ARECnT => Empty,
731 ARECnPT => Empty,
732 ARECnP => Empty,
733 ARECnU => Empty));
735 Set_Subps_Index (E, UI_From_Int (Subps.Last));
736 end Register_Subprogram;
738 -- Start of processing for Visit_Node
740 begin
741 case Nkind (N) is
743 -- Record a subprogram call
745 when N_Function_Call
746 | N_Procedure_Call_Statement
748 -- We are only interested in direct calls, not indirect
749 -- calls (where Name (N) is an explicit dereference) at
750 -- least for now!
752 if Nkind (Name (N)) in N_Has_Entity then
753 Ent := Entity (Name (N));
755 -- We are only interested in calls to subprograms nested
756 -- within Subp. Calls to Subp itself or to subprograms
757 -- outside the nested structure do not affect us.
759 if Scope_Within (Ent, Subp)
760 and then Is_Subprogram (Ent)
761 and then not Is_Imported (Ent)
762 then
763 Append_Unique_Call ((N, Current_Subprogram, Ent));
764 end if;
765 end if;
767 -- For all calls where the formal is an unconstrained array
768 -- and the actual is constrained we need to check the bounds
769 -- for uplevel references.
771 declare
772 Actual : Entity_Id;
773 DT : Boolean := False;
774 Formal : Node_Id;
775 Subp : Entity_Id;
777 begin
778 if Nkind (Name (N)) = N_Explicit_Dereference then
779 Subp := Etype (Name (N));
780 else
781 Subp := Entity (Name (N));
782 end if;
784 Actual := First_Actual (N);
785 Formal := First_Formal_With_Extras (Subp);
786 while Present (Actual) loop
787 if Is_Array_Type (Etype (Formal))
788 and then not Is_Constrained (Etype (Formal))
789 and then Is_Constrained (Etype (Actual))
790 then
791 Check_Static_Type (Etype (Actual), Empty, DT);
792 end if;
794 Next_Actual (Actual);
795 Next_Formal_With_Extras (Formal);
796 end loop;
797 end;
799 -- An At_End_Proc in a statement sequence indicates that there
800 -- is a call from the enclosing construct or block to that
801 -- subprogram. As above, the called entity must be local and
802 -- not imported.
804 when N_Handled_Sequence_Of_Statements =>
805 if Present (At_End_Proc (N))
806 and then Scope_Within (Entity (At_End_Proc (N)), Subp)
807 and then not Is_Imported (Entity (At_End_Proc (N)))
808 then
809 Append_Unique_Call
810 ((N, Current_Subprogram, Entity (At_End_Proc (N))));
811 end if;
813 -- Similarly, the following constructs include a semantic
814 -- attribute Procedure_To_Call that must be handled like
815 -- other calls. Likewise for attribute Storage_Pool.
817 when N_Allocator
818 | N_Extended_Return_Statement
819 | N_Free_Statement
820 | N_Simple_Return_Statement
822 declare
823 Pool : constant Entity_Id := Storage_Pool (N);
824 Proc : constant Entity_Id := Procedure_To_Call (N);
826 begin
827 if Present (Proc)
828 and then Scope_Within (Proc, Subp)
829 and then not Is_Imported (Proc)
830 then
831 Append_Unique_Call ((N, Current_Subprogram, Proc));
832 end if;
834 if Present (Pool)
835 and then not Is_Library_Level_Entity (Pool)
836 and then Scope_Within_Or_Same (Scope (Pool), Subp)
837 then
838 Caller := Current_Subprogram;
839 Callee := Enclosing_Subprogram (Pool);
841 if Callee /= Caller then
842 Note_Uplevel_Ref (Pool, Empty, Caller, Callee);
843 end if;
844 end if;
845 end;
847 -- For an allocator with a qualified expression, check type
848 -- of expression being qualified. The explicit type name is
849 -- handled as an entity reference.
851 if Nkind (N) = N_Allocator
852 and then Nkind (Expression (N)) = N_Qualified_Expression
853 then
854 declare
855 DT : Boolean := False;
856 begin
857 Check_Static_Type
858 (Etype (Expression (Expression (N))), Empty, DT);
859 end;
860 end if;
862 -- A 'Access reference is a (potential) call. So is 'Address,
863 -- in particular on imported subprograms. Other attributes
864 -- require special handling.
866 when N_Attribute_Reference =>
867 declare
868 Attr : constant Attribute_Id :=
869 Get_Attribute_Id (Attribute_Name (N));
870 begin
871 case Attr is
872 when Attribute_Access
873 | Attribute_Unchecked_Access
874 | Attribute_Unrestricted_Access
875 | Attribute_Address
877 if Nkind (Prefix (N)) in N_Has_Entity then
878 Ent := Entity (Prefix (N));
880 -- We only need to examine calls to subprograms
881 -- nested within current Subp.
883 if Scope_Within (Ent, Subp) then
884 if Is_Imported (Ent) then
885 null;
887 elsif Is_Subprogram (Ent) then
888 Append_Unique_Call
889 ((N, Current_Subprogram, Ent));
890 end if;
891 end if;
892 end if;
894 -- References to bounds can be uplevel references if
895 -- the type isn't static.
897 when Attribute_First
898 | Attribute_Last
899 | Attribute_Length
901 -- Special-case attributes of objects whose bounds
902 -- may be uplevel references. More complex prefixes
903 -- handled during full traversal. Note that if the
904 -- nominal subtype of the prefix is unconstrained,
905 -- the bound must be obtained from the object, not
906 -- from the (possibly) uplevel reference.
908 if Is_Constrained (Etype (Prefix (N))) then
909 declare
910 DT : Boolean := False;
911 begin
912 Check_Static_Type
913 (Etype (Prefix (N)), Empty, DT);
914 end;
916 return OK;
917 end if;
919 when others =>
920 null;
921 end case;
922 end;
924 -- Component associations in aggregates are either static or
925 -- else the aggregate will be expanded into assignments, in
926 -- which case the expression is analyzed later and provides
927 -- no relevant code generation.
929 when N_Component_Association =>
930 if No (Expression (N))
931 or else No (Etype (Expression (N)))
932 then
933 return Skip;
934 end if;
936 -- Generic associations are not analyzed: the actuals are
937 -- transferred to renaming and subtype declarations that
938 -- are the ones that must be examined.
940 when N_Generic_Association =>
941 return Skip;
943 -- Indexed references can be uplevel if the type isn't static
944 -- and if the lower bound (or an inner bound for a multi-
945 -- dimensional array) is uplevel.
947 when N_Indexed_Component
948 | N_Slice
950 if Is_Constrained (Etype (Prefix (N))) then
951 declare
952 DT : Boolean := False;
953 begin
954 Check_Static_Type (Etype (Prefix (N)), Empty, DT);
955 end;
956 end if;
958 -- A selected component can have an implicit up-level
959 -- reference due to the bounds of previous fields in the
960 -- record. We simplify the processing here by examining
961 -- all components of the record.
963 -- Selected components appear as unit names and end labels
964 -- for child units. Prefixes of these nodes denote parent
965 -- units and carry no type information so they are skipped.
967 when N_Selected_Component =>
968 if Present (Etype (Prefix (N))) then
969 declare
970 DT : Boolean := False;
971 begin
972 Check_Static_Type (Etype (Prefix (N)), Empty, DT);
973 end;
974 end if;
976 -- For EQ/NE comparisons, we need the type of the operands
977 -- in order to do the comparison, which means we need the
978 -- bounds.
980 when N_Op_Eq
981 | N_Op_Ne
983 declare
984 DT : Boolean := False;
985 begin
986 Check_Static_Type (Etype (Left_Opnd (N)), Empty, DT);
987 Check_Static_Type (Etype (Right_Opnd (N)), Empty, DT);
988 end;
990 -- Likewise we need the sizes to compute how much to move in
991 -- an assignment.
993 when N_Assignment_Statement =>
994 declare
995 DT : Boolean := False;
996 begin
997 Check_Static_Type (Etype (Name (N)), Empty, DT);
998 Check_Static_Type (Etype (Expression (N)), Empty, DT);
999 end;
1001 -- Record a subprogram. We record a subprogram body that acts
1002 -- as a spec. Otherwise we record a subprogram declaration,
1003 -- providing that it has a corresponding body we can get hold
1004 -- of. The case of no corresponding body being available is
1005 -- ignored for now.
1007 when N_Subprogram_Body =>
1008 Ent := Unique_Defining_Entity (N);
1010 -- Ignore generic subprogram
1012 if Is_Generic_Subprogram (Ent) then
1013 return Skip;
1014 end if;
1016 -- Make new entry in subprogram table if not already made
1018 Register_Subprogram (Ent, N);
1020 -- We make a recursive call to scan the subprogram body, so
1021 -- that we can save and restore Current_Subprogram.
1023 declare
1024 Save_CS : constant Entity_Id := Current_Subprogram;
1025 Decl : Node_Id;
1027 begin
1028 Current_Subprogram := Ent;
1030 -- Scan declarations
1032 Decl := First (Declarations (N));
1033 while Present (Decl) loop
1034 Visit (Decl);
1035 Next (Decl);
1036 end loop;
1038 -- Scan statements
1040 Visit (Handled_Statement_Sequence (N));
1042 -- Restore current subprogram setting
1044 Current_Subprogram := Save_CS;
1045 end;
1047 -- Now at this level, return skipping the subprogram body
1048 -- descendants, since we already took care of them!
1050 return Skip;
1052 -- If we have a body stub, visit the associated subunit, which
1053 -- is a semantic descendant of the stub.
1055 when N_Body_Stub =>
1056 Visit (Library_Unit (N));
1058 -- A declaration of a wrapper package indicates a subprogram
1059 -- instance for which there is no explicit body. Enter the
1060 -- subprogram instance in the table.
1062 when N_Package_Declaration =>
1063 if Is_Wrapper_Package (Defining_Entity (N)) then
1064 Register_Subprogram
1065 (Related_Instance (Defining_Entity (N)), Empty);
1066 end if;
1068 -- Skip generic declarations
1070 when N_Generic_Declaration =>
1071 return Skip;
1073 -- Skip generic package body
1075 when N_Package_Body =>
1076 if Present (Corresponding_Spec (N))
1077 and then Ekind (Corresponding_Spec (N)) = E_Generic_Package
1078 then
1079 return Skip;
1080 end if;
1082 -- Pragmas and component declarations can be ignored
1084 when N_Component_Declaration
1085 | N_Pragma
1087 return Skip;
1089 -- Otherwise record an uplevel reference in a local identifier
1091 when others =>
1092 if Nkind (N) in N_Has_Entity
1093 and then Present (Entity (N))
1094 then
1095 Ent := Entity (N);
1097 -- Only interested in entities declared within our nest
1099 if not Is_Library_Level_Entity (Ent)
1100 and then Scope_Within_Or_Same (Scope (Ent), Subp)
1102 -- Skip entities defined in inlined subprograms
1104 and then
1105 Chars (Enclosing_Subprogram (Ent)) /= Name_uParent
1107 -- Constants and variables are potentially uplevel
1108 -- references to global declarations.
1110 and then
1111 (Ekind_In (Ent, E_Constant,
1112 E_Loop_Parameter,
1113 E_Variable)
1115 -- Formals are interesting, but not if being used
1116 -- as mere names of parameters for name notation
1117 -- calls.
1119 or else
1120 (Is_Formal (Ent)
1121 and then not
1122 (Nkind (Parent (N)) = N_Parameter_Association
1123 and then Selector_Name (Parent (N)) = N))
1125 -- Types other than known Is_Static types are
1126 -- potentially interesting.
1128 or else
1129 (Is_Type (Ent) and then not Is_Static_Type (Ent)))
1130 then
1131 -- Here we have a potentially interesting uplevel
1132 -- reference to examine.
1134 if Is_Type (Ent) then
1135 declare
1136 DT : Boolean := False;
1138 begin
1139 Check_Static_Type (Ent, N, DT);
1141 if Is_Static_Type (Ent) then
1142 return OK;
1143 end if;
1144 end;
1145 end if;
1147 Caller := Current_Subprogram;
1148 Callee := Enclosing_Subprogram (Ent);
1150 if Callee /= Caller
1151 and then (not Is_Static_Type (Ent)
1152 or else Needs_Fat_Pointer (Ent))
1153 then
1154 Note_Uplevel_Ref (Ent, N, Caller, Callee);
1156 -- Check the type of a formal parameter of the current
1157 -- subprogram, whose formal type may be an uplevel
1158 -- reference.
1160 elsif Is_Formal (Ent)
1161 and then Scope (Ent) = Current_Subprogram
1162 then
1163 declare
1164 DT : Boolean := False;
1166 begin
1167 Check_Static_Type (Etype (Ent), Empty, DT);
1168 end;
1169 end if;
1170 end if;
1171 end if;
1172 end case;
1174 -- Fall through to continue scanning children of this node
1176 return OK;
1177 end Visit_Node;
1179 -- Start of processing for Build_Tables
1181 begin
1182 -- Traverse the body to get subprograms, calls and uplevel references
1184 Visit (Subp_Body);
1185 end Build_Tables;
1187 -- Now do the first transitive closure which determines which
1188 -- subprograms in the nest are actually reachable.
1190 Reachable_Closure : declare
1191 Modified : Boolean;
1193 begin
1194 Subps.Table (Subps_First).Reachable := True;
1196 -- We use a simple minded algorithm as follows (obviously this can
1197 -- be done more efficiently, using one of the standard algorithms
1198 -- for efficient transitive closure computation, but this is simple
1199 -- and most likely fast enough that its speed does not matter).
1201 -- Repeatedly scan the list of calls. Any time we find a call from
1202 -- A to B, where A is reachable, but B is not, then B is reachable,
1203 -- and note that we have made a change by setting Modified True. We
1204 -- repeat this until we make a pass with no modifications.
1206 Outer : loop
1207 Modified := False;
1208 Inner : for J in Calls.First .. Calls.Last loop
1209 declare
1210 CTJ : Call_Entry renames Calls.Table (J);
1212 SINF : constant SI_Type := Subp_Index (CTJ.Caller);
1213 SINT : constant SI_Type := Subp_Index (CTJ.Callee);
1215 SUBF : Subp_Entry renames Subps.Table (SINF);
1216 SUBT : Subp_Entry renames Subps.Table (SINT);
1218 begin
1219 if SUBF.Reachable and then not SUBT.Reachable then
1220 SUBT.Reachable := True;
1221 Modified := True;
1222 end if;
1223 end;
1224 end loop Inner;
1226 exit Outer when not Modified;
1227 end loop Outer;
1228 end Reachable_Closure;
1230 -- Remove calls from unreachable subprograms
1232 declare
1233 New_Index : Nat;
1235 begin
1236 New_Index := 0;
1237 for J in Calls.First .. Calls.Last loop
1238 declare
1239 CTJ : Call_Entry renames Calls.Table (J);
1241 SINF : constant SI_Type := Subp_Index (CTJ.Caller);
1242 SINT : constant SI_Type := Subp_Index (CTJ.Callee);
1244 SUBF : Subp_Entry renames Subps.Table (SINF);
1245 SUBT : Subp_Entry renames Subps.Table (SINT);
1247 begin
1248 if SUBF.Reachable then
1249 pragma Assert (SUBT.Reachable);
1250 New_Index := New_Index + 1;
1251 Calls.Table (New_Index) := Calls.Table (J);
1252 end if;
1253 end;
1254 end loop;
1256 Calls.Set_Last (New_Index);
1257 end;
1259 -- Remove uplevel references from unreachable subprograms
1261 declare
1262 New_Index : Nat;
1264 begin
1265 New_Index := 0;
1266 for J in Urefs.First .. Urefs.Last loop
1267 declare
1268 URJ : Uref_Entry renames Urefs.Table (J);
1270 SINF : constant SI_Type := Subp_Index (URJ.Caller);
1271 SINT : constant SI_Type := Subp_Index (URJ.Callee);
1273 SUBF : Subp_Entry renames Subps.Table (SINF);
1274 SUBT : Subp_Entry renames Subps.Table (SINT);
1276 S : Entity_Id;
1278 begin
1279 -- Keep reachable reference
1281 if SUBF.Reachable then
1282 New_Index := New_Index + 1;
1283 Urefs.Table (New_Index) := Urefs.Table (J);
1285 -- And since we know we are keeping this one, this is a good
1286 -- place to fill in information for a good reference.
1288 -- Mark all enclosing subprograms need to declare AREC
1290 S := URJ.Caller;
1291 loop
1292 S := Enclosing_Subprogram (S);
1294 -- If we are at the top level, as can happen with
1295 -- references to formals in aspects of nested subprogram
1296 -- declarations, there are no further subprograms to mark
1297 -- as requiring activation records.
1299 exit when No (S);
1301 declare
1302 SUBI : Subp_Entry renames Subps.Table (Subp_Index (S));
1303 begin
1304 SUBI.Declares_AREC := True;
1306 -- If this entity was marked reachable because it is
1307 -- in a task or protected type, there may not appear
1308 -- to be any calls to it, which would normally adjust
1309 -- the levels of the parent subprograms. So we need to
1310 -- be sure that the uplevel reference of that entity
1311 -- takes into account possible calls.
1313 if In_Synchronized_Unit (SUBF.Ent)
1314 and then SUBT.Lev < SUBI.Uplevel_Ref
1315 then
1316 SUBI.Uplevel_Ref := SUBT.Lev;
1317 end if;
1318 end;
1320 exit when S = URJ.Callee;
1321 end loop;
1323 -- Add to list of uplevel referenced entities for Callee.
1324 -- We do not add types to this list, only actual references
1325 -- to objects that will be referenced uplevel, and we use
1326 -- the flag Is_Uplevel_Referenced_Entity to avoid making
1327 -- duplicate entries in the list.
1328 -- Discriminants are also excluded, only the enclosing
1329 -- object can appear in the list.
1331 if not Is_Uplevel_Referenced_Entity (URJ.Ent)
1332 and then Ekind (URJ.Ent) /= E_Discriminant
1333 then
1334 Set_Is_Uplevel_Referenced_Entity (URJ.Ent);
1336 if not Is_Type (URJ.Ent) then
1337 Append_New_Elmt (URJ.Ent, SUBT.Uents);
1338 end if;
1339 end if;
1341 -- And set uplevel indication for caller
1343 if SUBT.Lev < SUBF.Uplevel_Ref then
1344 SUBF.Uplevel_Ref := SUBT.Lev;
1345 end if;
1346 end if;
1347 end;
1348 end loop;
1350 Urefs.Set_Last (New_Index);
1351 end;
1353 -- Remove unreachable subprograms from Subps table. Note that we do
1354 -- this after eliminating entries from the other two tables, since
1355 -- those elimination steps depend on referencing the Subps table.
1357 declare
1358 New_SI : SI_Type;
1360 begin
1361 New_SI := Subps_First - 1;
1362 for J in Subps_First .. Subps.Last loop
1363 declare
1364 STJ : Subp_Entry renames Subps.Table (J);
1365 Spec : Node_Id;
1366 Decl : Node_Id;
1368 begin
1369 -- Subprogram is reachable, copy and reset index
1371 if STJ.Reachable then
1372 New_SI := New_SI + 1;
1373 Subps.Table (New_SI) := STJ;
1374 Set_Subps_Index (STJ.Ent, UI_From_Int (New_SI));
1376 -- Subprogram is not reachable
1378 else
1379 -- Clear index, since no longer active
1381 Set_Subps_Index (Subps.Table (J).Ent, Uint_0);
1383 -- Output debug information if -gnatd.3 set
1385 if Debug_Flag_Dot_3 then
1386 Write_Str ("Eliminate ");
1387 Write_Name (Chars (Subps.Table (J).Ent));
1388 Write_Str (" at ");
1389 Write_Location (Sloc (Subps.Table (J).Ent));
1390 Write_Str (" (not referenced)");
1391 Write_Eol;
1392 end if;
1394 -- Rewrite declaration and body to null statements
1396 -- A subprogram instantiation does not have an explicit
1397 -- body. If unused, we could remove the corresponding
1398 -- wrapper package and its body (TBD).
1400 if Present (STJ.Bod) then
1401 Spec := Corresponding_Spec (STJ.Bod);
1403 if Present (Spec) then
1404 Decl := Parent (Declaration_Node (Spec));
1405 Rewrite (Decl, Make_Null_Statement (Sloc (Decl)));
1406 end if;
1408 Rewrite (STJ.Bod, Make_Null_Statement (Sloc (STJ.Bod)));
1409 end if;
1410 end if;
1411 end;
1412 end loop;
1414 Subps.Set_Last (New_SI);
1415 end;
1417 -- Now it is time for the second transitive closure, which follows calls
1418 -- and makes sure that A calls B, and B has uplevel references, then A
1419 -- is also marked as having uplevel references.
1421 Closure_Uplevel : declare
1422 Modified : Boolean;
1424 begin
1425 -- We use a simple minded algorithm as follows (obviously this can
1426 -- be done more efficiently, using one of the standard algorithms
1427 -- for efficient transitive closure computation, but this is simple
1428 -- and most likely fast enough that its speed does not matter).
1430 -- Repeatedly scan the list of calls. Any time we find a call from
1431 -- A to B, where B has uplevel references, make sure that A is marked
1432 -- as having at least the same level of uplevel referencing.
1434 Outer2 : loop
1435 Modified := False;
1436 Inner2 : for J in Calls.First .. Calls.Last loop
1437 declare
1438 CTJ : Call_Entry renames Calls.Table (J);
1439 SINF : constant SI_Type := Subp_Index (CTJ.Caller);
1440 SINT : constant SI_Type := Subp_Index (CTJ.Callee);
1441 SUBF : Subp_Entry renames Subps.Table (SINF);
1442 SUBT : Subp_Entry renames Subps.Table (SINT);
1443 begin
1444 if SUBT.Lev > SUBT.Uplevel_Ref
1445 and then SUBF.Uplevel_Ref > SUBT.Uplevel_Ref
1446 then
1447 SUBF.Uplevel_Ref := SUBT.Uplevel_Ref;
1448 Modified := True;
1449 end if;
1450 end;
1451 end loop Inner2;
1453 exit Outer2 when not Modified;
1454 end loop Outer2;
1455 end Closure_Uplevel;
1457 -- We have one more step before the tables are complete. An uplevel
1458 -- call from subprogram A to subprogram B where subprogram B has uplevel
1459 -- references is in effect an uplevel reference, and must arrange for
1460 -- the proper activation link to be passed.
1462 for J in Calls.First .. Calls.Last loop
1463 declare
1464 CTJ : Call_Entry renames Calls.Table (J);
1466 SINF : constant SI_Type := Subp_Index (CTJ.Caller);
1467 SINT : constant SI_Type := Subp_Index (CTJ.Callee);
1469 SUBF : Subp_Entry renames Subps.Table (SINF);
1470 SUBT : Subp_Entry renames Subps.Table (SINT);
1472 A : Entity_Id;
1474 begin
1475 -- If callee has uplevel references
1477 if SUBT.Uplevel_Ref < SUBT.Lev
1479 -- And this is an uplevel call
1481 and then SUBT.Lev < SUBF.Lev
1482 then
1483 -- We need to arrange for finding the uplink
1485 A := CTJ.Caller;
1486 loop
1487 A := Enclosing_Subprogram (A);
1488 Subps.Table (Subp_Index (A)).Declares_AREC := True;
1489 exit when A = CTJ.Callee;
1491 -- In any case exit when we get to the outer level. This
1492 -- happens in some odd cases with generics (in particular
1493 -- sem_ch3.adb does not compile without this kludge ???).
1495 exit when A = Subp;
1496 end loop;
1497 end if;
1498 end;
1499 end loop;
1501 -- The tables are now complete, so we can record the last index in the
1502 -- Subps table for later reference in Cprint.
1504 Subps.Table (Subps_First).Last := Subps.Last;
1506 -- Next step, create the entities for code we will insert. We do this
1507 -- at the start so that all the entities are defined, regardless of the
1508 -- order in which we do the code insertions.
1510 Create_Entities : for J in Subps_First .. Subps.Last loop
1511 declare
1512 STJ : Subp_Entry renames Subps.Table (J);
1513 Loc : constant Source_Ptr := Sloc (STJ.Bod);
1515 begin
1516 -- First we create the ARECnF entity for the additional formal for
1517 -- all subprograms which need an activation record passed.
1519 if STJ.Uplevel_Ref < STJ.Lev then
1520 STJ.ARECnF :=
1521 Make_Defining_Identifier (Loc, Chars => AREC_Name (J, "F"));
1522 end if;
1524 -- Define the AREC entities for the activation record if needed
1526 if STJ.Declares_AREC then
1527 STJ.ARECn :=
1528 Make_Defining_Identifier (Loc, AREC_Name (J, ""));
1529 STJ.ARECnT :=
1530 Make_Defining_Identifier (Loc, AREC_Name (J, "T"));
1531 STJ.ARECnPT :=
1532 Make_Defining_Identifier (Loc, AREC_Name (J, "PT"));
1533 STJ.ARECnP :=
1534 Make_Defining_Identifier (Loc, AREC_Name (J, "P"));
1536 -- Define uplink component entity if inner nesting case
1538 if Present (STJ.ARECnF) then
1539 STJ.ARECnU :=
1540 Make_Defining_Identifier (Loc, AREC_Name (J, "U"));
1541 end if;
1542 end if;
1543 end;
1544 end loop Create_Entities;
1546 -- Loop through subprograms
1548 Subp_Loop : declare
1549 Addr : constant Entity_Id := RTE (RE_Address);
1551 begin
1552 for J in Subps_First .. Subps.Last loop
1553 declare
1554 STJ : Subp_Entry renames Subps.Table (J);
1556 begin
1557 -- First add the extra formal if needed. This applies to all
1558 -- nested subprograms that require an activation record to be
1559 -- passed, as indicated by ARECnF being defined.
1561 if Present (STJ.ARECnF) then
1563 -- Here we need the extra formal. We do the expansion and
1564 -- analysis of this manually, since it is fairly simple,
1565 -- and it is not obvious how we can get what we want if we
1566 -- try to use the normal Analyze circuit.
1568 Add_Extra_Formal : declare
1569 Encl : constant SI_Type := Enclosing_Subp (J);
1570 STJE : Subp_Entry renames Subps.Table (Encl);
1571 -- Index and Subp_Entry for enclosing routine
1573 Form : constant Entity_Id := STJ.ARECnF;
1574 -- The formal to be added. Note that n here is one less
1575 -- than the level of the subprogram itself (STJ.Ent).
1577 procedure Add_Form_To_Spec (F : Entity_Id; S : Node_Id);
1578 -- S is an N_Function/Procedure_Specification node, and F
1579 -- is the new entity to add to this subprogramn spec as
1580 -- the last Extra_Formal.
1582 ----------------------
1583 -- Add_Form_To_Spec --
1584 ----------------------
1586 procedure Add_Form_To_Spec (F : Entity_Id; S : Node_Id) is
1587 Sub : constant Entity_Id := Defining_Entity (S);
1588 Ent : Entity_Id;
1590 begin
1591 -- Case of at least one Extra_Formal is present, set
1592 -- ARECnF as the new last entry in the list.
1594 if Present (Extra_Formals (Sub)) then
1595 Ent := Extra_Formals (Sub);
1596 while Present (Extra_Formal (Ent)) loop
1597 Ent := Extra_Formal (Ent);
1598 end loop;
1600 Set_Extra_Formal (Ent, F);
1602 -- No Extra formals present
1604 else
1605 Set_Extra_Formals (Sub, F);
1606 Ent := Last_Formal (Sub);
1608 if Present (Ent) then
1609 Set_Extra_Formal (Ent, F);
1610 end if;
1611 end if;
1612 end Add_Form_To_Spec;
1614 -- Start of processing for Add_Extra_Formal
1616 begin
1617 -- Decorate the new formal entity
1619 Set_Scope (Form, STJ.Ent);
1620 Set_Ekind (Form, E_In_Parameter);
1621 Set_Etype (Form, STJE.ARECnPT);
1622 Set_Mechanism (Form, By_Copy);
1623 Set_Never_Set_In_Source (Form, True);
1624 Set_Analyzed (Form, True);
1625 Set_Comes_From_Source (Form, False);
1626 Set_Is_Activation_Record (Form, True);
1628 -- Case of only body present
1630 if Acts_As_Spec (STJ.Bod) then
1631 Add_Form_To_Spec (Form, Specification (STJ.Bod));
1633 -- Case of separate spec
1635 else
1636 Add_Form_To_Spec (Form, Parent (STJ.Ent));
1637 end if;
1638 end Add_Extra_Formal;
1639 end if;
1641 -- Processing for subprograms that declare an activation record
1643 if Present (STJ.ARECn) then
1645 -- Local declarations for one such subprogram
1647 declare
1648 Loc : constant Source_Ptr := Sloc (STJ.Bod);
1650 Decls : constant List_Id := New_List;
1651 -- List of new declarations we create
1653 Clist : List_Id;
1654 Comp : Entity_Id;
1656 Decl_Assign : Node_Id;
1657 -- Assigment to set uplink, Empty if none
1659 Decl_ARECnT : Node_Id;
1660 Decl_ARECnPT : Node_Id;
1661 Decl_ARECn : Node_Id;
1662 Decl_ARECnP : Node_Id;
1663 -- Declaration nodes for the AREC entities we build
1665 begin
1666 -- Build list of component declarations for ARECnT
1668 Clist := Empty_List;
1670 -- If we are in a subprogram that has a static link that
1671 -- is passed in (as indicated by ARECnF being defined),
1672 -- then include ARECnU : ARECmPT where ARECmPT comes from
1673 -- the level one higher than the current level, and the
1674 -- entity ARECnPT comes from the enclosing subprogram.
1676 if Present (STJ.ARECnF) then
1677 declare
1678 STJE : Subp_Entry
1679 renames Subps.Table (Enclosing_Subp (J));
1680 begin
1681 Append_To (Clist,
1682 Make_Component_Declaration (Loc,
1683 Defining_Identifier => STJ.ARECnU,
1684 Component_Definition =>
1685 Make_Component_Definition (Loc,
1686 Subtype_Indication =>
1687 New_Occurrence_Of (STJE.ARECnPT, Loc))));
1688 end;
1689 end if;
1691 -- Add components for uplevel referenced entities
1693 if Present (STJ.Uents) then
1694 declare
1695 Elmt : Elmt_Id;
1696 Ptr_Decl : Node_Id;
1697 Uent : Entity_Id;
1699 Indx : Nat;
1700 -- 1's origin of index in list of elements. This is
1701 -- used to uniquify names if needed in Upref_Name.
1703 begin
1704 Elmt := First_Elmt (STJ.Uents);
1705 Indx := 0;
1706 while Present (Elmt) loop
1707 Uent := Node (Elmt);
1708 Indx := Indx + 1;
1710 Comp :=
1711 Make_Defining_Identifier (Loc,
1712 Chars => Upref_Name (Uent, Indx, Clist));
1714 Set_Activation_Record_Component
1715 (Uent, Comp);
1717 if Needs_Fat_Pointer (Uent) then
1719 -- Build corresponding access type
1721 Ptr_Decl :=
1722 Build_Access_Type_Decl
1723 (Etype (Uent), STJ.Ent);
1724 Append_To (Decls, Ptr_Decl);
1726 -- And use its type in the corresponding
1727 -- component.
1729 Append_To (Clist,
1730 Make_Component_Declaration (Loc,
1731 Defining_Identifier => Comp,
1732 Component_Definition =>
1733 Make_Component_Definition (Loc,
1734 Subtype_Indication =>
1735 New_Occurrence_Of
1736 (Defining_Identifier (Ptr_Decl),
1737 Loc))));
1738 else
1739 Append_To (Clist,
1740 Make_Component_Declaration (Loc,
1741 Defining_Identifier => Comp,
1742 Component_Definition =>
1743 Make_Component_Definition (Loc,
1744 Subtype_Indication =>
1745 New_Occurrence_Of (Addr, Loc))));
1746 end if;
1747 Next_Elmt (Elmt);
1748 end loop;
1749 end;
1750 end if;
1752 -- Now we can insert the AREC declarations into the body
1753 -- type ARECnT is record .. end record;
1754 -- pragma Suppress_Initialization (ARECnT);
1756 -- Note that we need to set the Suppress_Initialization
1757 -- flag after Decl_ARECnT has been analyzed.
1759 Decl_ARECnT :=
1760 Make_Full_Type_Declaration (Loc,
1761 Defining_Identifier => STJ.ARECnT,
1762 Type_Definition =>
1763 Make_Record_Definition (Loc,
1764 Component_List =>
1765 Make_Component_List (Loc,
1766 Component_Items => Clist)));
1767 Append_To (Decls, Decl_ARECnT);
1769 -- type ARECnPT is access all ARECnT;
1771 Decl_ARECnPT :=
1772 Make_Full_Type_Declaration (Loc,
1773 Defining_Identifier => STJ.ARECnPT,
1774 Type_Definition =>
1775 Make_Access_To_Object_Definition (Loc,
1776 All_Present => True,
1777 Subtype_Indication =>
1778 New_Occurrence_Of (STJ.ARECnT, Loc)));
1779 Append_To (Decls, Decl_ARECnPT);
1781 -- ARECn : aliased ARECnT;
1783 Decl_ARECn :=
1784 Make_Object_Declaration (Loc,
1785 Defining_Identifier => STJ.ARECn,
1786 Aliased_Present => True,
1787 Object_Definition =>
1788 New_Occurrence_Of (STJ.ARECnT, Loc));
1789 Append_To (Decls, Decl_ARECn);
1791 -- ARECnP : constant ARECnPT := ARECn'Access;
1793 Decl_ARECnP :=
1794 Make_Object_Declaration (Loc,
1795 Defining_Identifier => STJ.ARECnP,
1796 Constant_Present => True,
1797 Object_Definition =>
1798 New_Occurrence_Of (STJ.ARECnPT, Loc),
1799 Expression =>
1800 Make_Attribute_Reference (Loc,
1801 Prefix =>
1802 New_Occurrence_Of (STJ.ARECn, Loc),
1803 Attribute_Name => Name_Access));
1804 Append_To (Decls, Decl_ARECnP);
1806 -- If we are in a subprogram that has a static link that
1807 -- is passed in (as indicated by ARECnF being defined),
1808 -- then generate ARECn.ARECmU := ARECmF where m is
1809 -- one less than the current level to set the uplink.
1811 if Present (STJ.ARECnF) then
1812 Decl_Assign :=
1813 Make_Assignment_Statement (Loc,
1814 Name =>
1815 Make_Selected_Component (Loc,
1816 Prefix =>
1817 New_Occurrence_Of (STJ.ARECn, Loc),
1818 Selector_Name =>
1819 New_Occurrence_Of (STJ.ARECnU, Loc)),
1820 Expression =>
1821 New_Occurrence_Of (STJ.ARECnF, Loc));
1822 Append_To (Decls, Decl_Assign);
1824 else
1825 Decl_Assign := Empty;
1826 end if;
1828 Prepend_List_To (Declarations (STJ.Bod), Decls);
1830 -- Analyze the newly inserted declarations. Note that we
1831 -- do not need to establish the whole scope stack, since
1832 -- we have already set all entity fields (so there will
1833 -- be no searching of upper scopes to resolve names). But
1834 -- we do set the scope of the current subprogram, so that
1835 -- newly created entities go in the right entity chain.
1837 -- We analyze with all checks suppressed (since we do
1838 -- not expect any exceptions).
1840 Push_Scope (STJ.Ent);
1841 Analyze (Decl_ARECnT, Suppress => All_Checks);
1843 -- Note that we need to call Set_Suppress_Initialization
1844 -- after Decl_ARECnT has been analyzed, but before
1845 -- analyzing Decl_ARECnP so that the flag is properly
1846 -- taking into account.
1848 Set_Suppress_Initialization (STJ.ARECnT);
1850 Analyze (Decl_ARECnPT, Suppress => All_Checks);
1851 Analyze (Decl_ARECn, Suppress => All_Checks);
1852 Analyze (Decl_ARECnP, Suppress => All_Checks);
1854 if Present (Decl_Assign) then
1855 Analyze (Decl_Assign, Suppress => All_Checks);
1856 end if;
1858 Pop_Scope;
1860 -- Next step, for each uplevel referenced entity, add
1861 -- assignment operations to set the component in the
1862 -- activation record.
1864 if Present (STJ.Uents) then
1865 declare
1866 Elmt : Elmt_Id;
1868 begin
1869 Elmt := First_Elmt (STJ.Uents);
1870 while Present (Elmt) loop
1871 declare
1872 Ent : constant Entity_Id := Node (Elmt);
1873 Loc : constant Source_Ptr := Sloc (Ent);
1874 Dec : constant Node_Id :=
1875 Declaration_Node (Ent);
1877 Asn : Node_Id;
1878 Attr : Name_Id;
1879 Ins : Node_Id;
1881 begin
1882 -- For parameters, we insert the assignment
1883 -- right after the declaration of ARECnP.
1884 -- For all other entities, we insert the
1885 -- assignment immediately after the
1886 -- declaration of the entity or after the
1887 -- freeze node if present.
1889 -- Note: we don't need to mark the entity
1890 -- as being aliased, because the address
1891 -- attribute will mark it as Address_Taken,
1892 -- and that is good enough.
1894 if Is_Formal (Ent) then
1895 Ins := Decl_ARECnP;
1897 elsif Has_Delayed_Freeze (Ent) then
1898 Ins := Freeze_Node (Ent);
1900 else
1901 Ins := Dec;
1902 end if;
1904 -- Build and insert the assignment:
1905 -- ARECn.nam := nam'Address
1906 -- or else 'Access for unconstrained array
1908 if Needs_Fat_Pointer (Ent) then
1909 Attr := Name_Access;
1910 else
1911 Attr := Name_Address;
1912 end if;
1914 Asn :=
1915 Make_Assignment_Statement (Loc,
1916 Name =>
1917 Make_Selected_Component (Loc,
1918 Prefix =>
1919 New_Occurrence_Of (STJ.ARECn, Loc),
1920 Selector_Name =>
1921 New_Occurrence_Of
1922 (Activation_Record_Component
1923 (Ent),
1924 Loc)),
1926 Expression =>
1927 Make_Attribute_Reference (Loc,
1928 Prefix =>
1929 New_Occurrence_Of (Ent, Loc),
1930 Attribute_Name => Attr));
1932 -- If we have a loop parameter, we have
1933 -- to insert before the first statement
1934 -- of the loop. Ins points to the
1935 -- N_Loop_Parametrer_Specification.
1937 if Ekind (Ent) = E_Loop_Parameter then
1938 Ins :=
1939 First
1940 (Statements (Parent (Parent (Ins))));
1941 Insert_Before (Ins, Asn);
1943 else
1944 Insert_After (Ins, Asn);
1945 end if;
1947 -- Analyze the assignment statement. We do
1948 -- not need to establish the relevant scope
1949 -- stack entries here, because we have
1950 -- already set the correct entity references,
1951 -- so no name resolution is required, and no
1952 -- new entities are created, so we don't even
1953 -- need to set the current scope.
1955 -- We analyze with all checks suppressed
1956 -- (since we do not expect any exceptions).
1958 Analyze (Asn, Suppress => All_Checks);
1959 end;
1961 Next_Elmt (Elmt);
1962 end loop;
1963 end;
1964 end if;
1965 end;
1966 end if;
1967 end;
1968 end loop;
1969 end Subp_Loop;
1971 -- Next step, process uplevel references. This has to be done in a
1972 -- separate pass, after completing the processing in Sub_Loop because we
1973 -- need all the AREC declarations generated, inserted, and analyzed so
1974 -- that the uplevel references can be successfully analyzed.
1976 Uplev_Refs : for J in Urefs.First .. Urefs.Last loop
1977 declare
1978 UPJ : Uref_Entry renames Urefs.Table (J);
1980 begin
1981 -- Ignore type references, these are implicit references that do
1982 -- not need rewriting (e.g. the appearence in a conversion).
1983 -- Also ignore if no reference was specified.
1985 if Is_Type (UPJ.Ent) or else No (UPJ.Ref) then
1986 goto Continue;
1987 end if;
1989 -- Also ignore uplevel references to bounds of types that come
1990 -- from the original type reference.
1992 if Is_Entity_Name (UPJ.Ref)
1993 and then Present (Entity (UPJ.Ref))
1994 and then Is_Type (Entity (UPJ.Ref))
1995 then
1996 goto Continue;
1997 end if;
1999 -- Rewrite one reference
2001 Rewrite_One_Ref : declare
2002 Loc : constant Source_Ptr := Sloc (UPJ.Ref);
2003 -- Source location for the reference
2005 Typ : constant Entity_Id := Etype (UPJ.Ent);
2006 -- The type of the referenced entity
2008 Atyp : constant Entity_Id := Get_Actual_Subtype (UPJ.Ref);
2009 -- The actual subtype of the reference
2011 RS_Caller : constant SI_Type := Subp_Index (UPJ.Caller);
2012 -- Subp_Index for caller containing reference
2014 STJR : Subp_Entry renames Subps.Table (RS_Caller);
2015 -- Subp_Entry for subprogram containing reference
2017 RS_Callee : constant SI_Type := Subp_Index (UPJ.Callee);
2018 -- Subp_Index for subprogram containing referenced entity
2020 STJE : Subp_Entry renames Subps.Table (RS_Callee);
2021 -- Subp_Entry for subprogram containing referenced entity
2023 Pfx : Node_Id;
2024 Comp : Entity_Id;
2025 SI : SI_Type;
2027 begin
2028 -- Ignore if no ARECnF entity for enclosing subprogram which
2029 -- probably happens as a result of not properly treating
2030 -- instance bodies. To be examined ???
2032 -- If this test is omitted, then the compilation of freeze.adb
2033 -- and inline.adb fail in unnesting mode.
2035 if No (STJR.ARECnF) then
2036 goto Continue;
2037 end if;
2039 -- Push the current scope, so that the pointer type Tnn, and
2040 -- any subsidiary entities resulting from the analysis of the
2041 -- rewritten reference, go in the right entity chain.
2043 Push_Scope (STJR.Ent);
2045 -- Now we need to rewrite the reference. We have a reference
2046 -- from level STJR.Lev to level STJE.Lev. The general form of
2047 -- the rewritten reference for entity X is:
2049 -- Typ'Deref (ARECaF.ARECbU.ARECcU.ARECdU....ARECmU.X)
2051 -- where a,b,c,d .. m =
2052 -- STJR.Lev - 1, STJR.Lev - 2, .. STJE.Lev
2054 pragma Assert (STJR.Lev > STJE.Lev);
2056 -- Compute the prefix of X. Here are examples to make things
2057 -- clear (with parens to show groupings, the prefix is
2058 -- everything except the .X at the end).
2060 -- level 2 to level 1
2062 -- AREC1F.X
2064 -- level 3 to level 1
2066 -- (AREC2F.AREC1U).X
2068 -- level 4 to level 1
2070 -- ((AREC3F.AREC2U).AREC1U).X
2072 -- level 6 to level 2
2074 -- (((AREC5F.AREC4U).AREC3U).AREC2U).X
2076 -- In the above, ARECnF and ARECnU are pointers, so there are
2077 -- explicit dereferences required for these occurrences.
2079 Pfx :=
2080 Make_Explicit_Dereference (Loc,
2081 Prefix => New_Occurrence_Of (STJR.ARECnF, Loc));
2082 SI := RS_Caller;
2083 for L in STJE.Lev .. STJR.Lev - 2 loop
2084 SI := Enclosing_Subp (SI);
2085 Pfx :=
2086 Make_Explicit_Dereference (Loc,
2087 Prefix =>
2088 Make_Selected_Component (Loc,
2089 Prefix => Pfx,
2090 Selector_Name =>
2091 New_Occurrence_Of (Subps.Table (SI).ARECnU, Loc)));
2092 end loop;
2094 -- Get activation record component (must exist)
2096 Comp := Activation_Record_Component (UPJ.Ent);
2097 pragma Assert (Present (Comp));
2099 -- Do the replacement. If the component type is an access type,
2100 -- this is an uplevel reference for an entity that requires a
2101 -- fat pointer, so dereference the component.
2103 if Is_Access_Type (Etype (Comp)) then
2104 Rewrite (UPJ.Ref,
2105 Make_Explicit_Dereference (Loc,
2106 Prefix =>
2107 Make_Selected_Component (Loc,
2108 Prefix => Pfx,
2109 Selector_Name =>
2110 New_Occurrence_Of (Comp, Loc))));
2112 else
2113 Rewrite (UPJ.Ref,
2114 Make_Attribute_Reference (Loc,
2115 Prefix => New_Occurrence_Of (Atyp, Loc),
2116 Attribute_Name => Name_Deref,
2117 Expressions => New_List (
2118 Make_Selected_Component (Loc,
2119 Prefix => Pfx,
2120 Selector_Name =>
2121 New_Occurrence_Of (Comp, Loc)))));
2122 end if;
2124 -- Analyze and resolve the new expression. We do not need to
2125 -- establish the relevant scope stack entries here, because we
2126 -- have already set all the correct entity references, so no
2127 -- name resolution is needed. We have already set the current
2128 -- scope, so that any new entities created will be in the right
2129 -- scope.
2131 -- We analyze with all checks suppressed (since we do not
2132 -- expect any exceptions)
2134 Analyze_And_Resolve (UPJ.Ref, Typ, Suppress => All_Checks);
2135 Pop_Scope;
2136 end Rewrite_One_Ref;
2137 end;
2139 <<Continue>>
2140 null;
2141 end loop Uplev_Refs;
2143 -- Finally, loop through all calls adding extra actual for the
2144 -- activation record where it is required.
2146 Adjust_Calls : for J in Calls.First .. Calls.Last loop
2148 -- Process a single call, we are only interested in a call to a
2149 -- subprogram that actually needs a pointer to an activation record,
2150 -- as indicated by the ARECnF entity being set. This excludes the
2151 -- top level subprogram, and any subprogram not having uplevel refs.
2153 Adjust_One_Call : declare
2154 CTJ : Call_Entry renames Calls.Table (J);
2155 STF : Subp_Entry renames Subps.Table (Subp_Index (CTJ.Caller));
2156 STT : Subp_Entry renames Subps.Table (Subp_Index (CTJ.Callee));
2158 Loc : constant Source_Ptr := Sloc (CTJ.N);
2160 Extra : Node_Id;
2161 ExtraP : Node_Id;
2162 SubX : SI_Type;
2163 Act : Node_Id;
2165 begin
2166 if Present (STT.ARECnF)
2167 and then Nkind (CTJ.N) in N_Subprogram_Call
2168 then
2169 -- CTJ.N is a call to a subprogram which may require a pointer
2170 -- to an activation record. The subprogram containing the call
2171 -- is CTJ.From and the subprogram being called is CTJ.To, so we
2172 -- have a call from level STF.Lev to level STT.Lev.
2174 -- There are three possibilities:
2176 -- For a call to the same level, we just pass the activation
2177 -- record passed to the calling subprogram.
2179 if STF.Lev = STT.Lev then
2180 Extra := New_Occurrence_Of (STF.ARECnF, Loc);
2182 -- For a call that goes down a level, we pass a pointer to the
2183 -- activation record constructed within the caller (which may
2184 -- be the outer-level subprogram, but also may be a more deeply
2185 -- nested caller).
2187 elsif STT.Lev = STF.Lev + 1 then
2188 Extra := New_Occurrence_Of (STF.ARECnP, Loc);
2190 -- Otherwise we must have an upcall (STT.Lev < STF.LEV),
2191 -- since it is not possible to do a downcall of more than
2192 -- one level.
2194 -- For a call from level STF.Lev to level STT.Lev, we
2195 -- have to find the activation record needed by the
2196 -- callee. This is as follows:
2198 -- ARECaF.ARECbU.ARECcU....ARECmU
2200 -- where a,b,c .. m =
2201 -- STF.Lev - 1, STF.Lev - 2, STF.Lev - 3 .. STT.Lev
2203 else
2204 pragma Assert (STT.Lev < STF.Lev);
2206 Extra := New_Occurrence_Of (STF.ARECnF, Loc);
2207 SubX := Subp_Index (CTJ.Caller);
2208 for K in reverse STT.Lev .. STF.Lev - 1 loop
2209 SubX := Enclosing_Subp (SubX);
2210 Extra :=
2211 Make_Selected_Component (Loc,
2212 Prefix => Extra,
2213 Selector_Name =>
2214 New_Occurrence_Of
2215 (Subps.Table (SubX).ARECnU, Loc));
2216 end loop;
2217 end if;
2219 -- Extra is the additional parameter to be added. Build a
2220 -- parameter association that we can append to the actuals.
2222 ExtraP :=
2223 Make_Parameter_Association (Loc,
2224 Selector_Name =>
2225 New_Occurrence_Of (STT.ARECnF, Loc),
2226 Explicit_Actual_Parameter => Extra);
2228 if No (Parameter_Associations (CTJ.N)) then
2229 Set_Parameter_Associations (CTJ.N, Empty_List);
2230 end if;
2232 Append (ExtraP, Parameter_Associations (CTJ.N));
2234 -- We need to deal with the actual parameter chain as well. The
2235 -- newly added parameter is always the last actual.
2237 Act := First_Named_Actual (CTJ.N);
2239 if No (Act) then
2240 Set_First_Named_Actual (CTJ.N, Extra);
2242 -- If call has been relocated (as with an expression in
2243 -- an aggregate), set First_Named pointer in original node
2244 -- as well, because that's the parent of the parameter list.
2246 Set_First_Named_Actual
2247 (Parent (List_Containing (ExtraP)), Extra);
2249 -- Here we must follow the chain and append the new entry
2251 else
2252 loop
2253 declare
2254 PAN : Node_Id;
2255 NNA : Node_Id;
2257 begin
2258 PAN := Parent (Act);
2259 pragma Assert (Nkind (PAN) = N_Parameter_Association);
2260 NNA := Next_Named_Actual (PAN);
2262 if No (NNA) then
2263 Set_Next_Named_Actual (PAN, Extra);
2264 exit;
2265 end if;
2267 Act := NNA;
2268 end;
2269 end loop;
2270 end if;
2272 -- Analyze and resolve the new actual. We do not need to
2273 -- establish the relevant scope stack entries here, because
2274 -- we have already set all the correct entity references, so
2275 -- no name resolution is needed.
2277 -- We analyze with all checks suppressed (since we do not
2278 -- expect any exceptions, and also we temporarily turn off
2279 -- Unested_Subprogram_Mode to avoid trying to mark uplevel
2280 -- references (not needed at this stage, and in fact causes
2281 -- a bit of recursive chaos).
2283 Opt.Unnest_Subprogram_Mode := False;
2284 Analyze_And_Resolve
2285 (Extra, Etype (STT.ARECnF), Suppress => All_Checks);
2286 Opt.Unnest_Subprogram_Mode := True;
2287 end if;
2288 end Adjust_One_Call;
2289 end loop Adjust_Calls;
2291 return;
2292 end Unnest_Subprogram;
2294 ------------------------
2295 -- Unnest_Subprograms --
2296 ------------------------
2298 procedure Unnest_Subprograms (N : Node_Id) is
2299 function Search_Subprograms (N : Node_Id) return Traverse_Result;
2300 -- Tree visitor that search for outer level procedures with nested
2301 -- subprograms and invokes Unnest_Subprogram()
2303 ---------------
2304 -- Do_Search --
2305 ---------------
2307 procedure Do_Search is new Traverse_Proc (Search_Subprograms);
2308 -- Subtree visitor instantiation
2310 ------------------------
2311 -- Search_Subprograms --
2312 ------------------------
2314 function Search_Subprograms (N : Node_Id) return Traverse_Result is
2315 begin
2316 if Nkind_In (N, N_Subprogram_Body, N_Subprogram_Body_Stub) then
2317 declare
2318 Spec_Id : constant Entity_Id := Unique_Defining_Entity (N);
2320 begin
2321 -- We are only interested in subprograms (not generic
2322 -- subprograms), that have nested subprograms.
2324 if Is_Subprogram (Spec_Id)
2325 and then Has_Nested_Subprogram (Spec_Id)
2326 and then Is_Library_Level_Entity (Spec_Id)
2327 then
2328 Unnest_Subprogram (Spec_Id, N);
2329 end if;
2330 end;
2331 end if;
2333 -- The proper body of a stub may contain nested subprograms, and
2334 -- therefore must be visited explicitly. Nested stubs are examined
2335 -- recursively in Visit_Node.
2337 if Nkind (N) in N_Body_Stub then
2338 Do_Search (Library_Unit (N));
2339 end if;
2341 return OK;
2342 end Search_Subprograms;
2344 -- Start of processing for Unnest_Subprograms
2346 begin
2347 if not Opt.Unnest_Subprogram_Mode then
2348 return;
2349 end if;
2351 -- A specification will contain bodies if it contains instantiations so
2352 -- examine package or subprogram declaration of the main unit, when it
2353 -- is present.
2355 if Nkind (Unit (N)) = N_Package_Body
2356 or else (Nkind (Unit (N)) = N_Subprogram_Body
2357 and then not Acts_As_Spec (N))
2358 then
2359 Do_Search (Library_Unit (N));
2360 end if;
2362 Do_Search (N);
2363 end Unnest_Subprograms;
2365 end Exp_Unst;