]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/ada/exp_unst.adb
b3ded138ee579756b2e7691e857066bb70fe15f9
[thirdparty/gcc.git] / gcc / ada / exp_unst.adb
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-2019, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
25
26 with Atree; use Atree;
27 with Debug; use Debug;
28 with Einfo; use Einfo;
29 with Elists; use Elists;
30 with Exp_Util; use Exp_Util;
31 with Lib; use Lib;
32 with Namet; use Namet;
33 with Nlists; use Nlists;
34 with Nmake; use Nmake;
35 with Opt;
36 with Output; use Output;
37 with Rtsfind; use Rtsfind;
38 with Sem; use Sem;
39 with Sem_Aux; use Sem_Aux;
40 with Sem_Ch8; use Sem_Ch8;
41 with Sem_Mech; use Sem_Mech;
42 with Sem_Res; use Sem_Res;
43 with Sem_Util; use Sem_Util;
44 with Sinfo; use Sinfo;
45 with Sinput; use Sinput;
46 with Snames; use Snames;
47 with Stand; use Stand;
48 with Tbuild; use Tbuild;
49 with Uintp; use Uintp;
50
51 package body Exp_Unst is
52
53 -----------------------
54 -- Local Subprograms --
55 -----------------------
56
57 procedure Unnest_Subprogram
58 (Subp : Entity_Id; Subp_Body : Node_Id; For_Inline : Boolean := False);
59 -- Subp is a library-level subprogram which has nested subprograms, and
60 -- Subp_Body is the corresponding N_Subprogram_Body node. This procedure
61 -- declares the AREC types and objects, adds assignments to the AREC record
62 -- as required, defines the xxxPTR types for uplevel referenced objects,
63 -- adds the ARECP parameter to all nested subprograms which need it, and
64 -- modifies all uplevel references appropriately. If For_Inline is True,
65 -- we're unnesting this subprogram because it's on the list of inlined
66 -- subprograms and should unnest it despite it not being part of the main
67 -- unit.
68
69 -----------
70 -- Calls --
71 -----------
72
73 -- Table to record calls within the nest being analyzed. These are the
74 -- calls which may need to have an AREC actual added. This table is built
75 -- new for each subprogram nest and cleared at the end of processing each
76 -- subprogram nest.
77
78 type Call_Entry is record
79 N : Node_Id;
80 -- The actual call
81
82 Caller : Entity_Id;
83 -- Entity of the subprogram containing the call (can be at any level)
84
85 Callee : Entity_Id;
86 -- Entity of the subprogram called (always at level 2 or higher). Note
87 -- that in accordance with the basic rules of nesting, the level of To
88 -- is either less than or equal to the level of From, or one greater.
89 end record;
90
91 package Calls is new Table.Table (
92 Table_Component_Type => Call_Entry,
93 Table_Index_Type => Nat,
94 Table_Low_Bound => 1,
95 Table_Initial => 100,
96 Table_Increment => 200,
97 Table_Name => "Unnest_Calls");
98 -- Records each call within the outer subprogram and all nested subprograms
99 -- that are to other subprograms nested within the outer subprogram. These
100 -- are the calls that may need an additional parameter.
101
102 procedure Append_Unique_Call (Call : Call_Entry);
103 -- Append a call entry to the Calls table. A check is made to see if the
104 -- table already contains this entry and if so it has no effect.
105
106 ----------------------------------
107 -- Subprograms For Fat Pointers --
108 ----------------------------------
109
110 function Build_Access_Type_Decl
111 (E : Entity_Id;
112 Scop : Entity_Id) return Node_Id;
113 -- For an uplevel reference that involves an unconstrained array type,
114 -- build an access type declaration for the corresponding activation
115 -- record component. The relevant attributes of the access type are
116 -- set here to avoid a full analysis that would require a scope stack.
117
118 function Needs_Fat_Pointer (E : Entity_Id) return Boolean;
119 -- A formal parameter of an unconstrained array type that appears in an
120 -- uplevel reference requires the construction of an access type, to be
121 -- used in the corresponding component declaration.
122
123 -----------
124 -- Urefs --
125 -----------
126
127 -- Table to record explicit uplevel references to objects (variables,
128 -- constants, formal parameters). These are the references that will
129 -- need rewriting to use the activation table (AREC) pointers. Also
130 -- included are implicit and explicit uplevel references to types, but
131 -- these do not get rewritten by the front end. This table is built new
132 -- for each subprogram nest and cleared at the end of processing each
133 -- subprogram nest.
134
135 type Uref_Entry is record
136 Ref : Node_Id;
137 -- The reference itself. For objects this is always an entity reference
138 -- and the referenced entity will have its Is_Uplevel_Referenced_Entity
139 -- flag set and will appear in the Uplevel_Referenced_Entities list of
140 -- the subprogram declaring this entity.
141
142 Ent : Entity_Id;
143 -- The Entity_Id of the uplevel referenced object or type
144
145 Caller : Entity_Id;
146 -- The entity for the subprogram immediately containing this entity
147
148 Callee : Entity_Id;
149 -- The entity for the subprogram containing the referenced entity. Note
150 -- that the level of Callee must be less than the level of Caller, since
151 -- this is an uplevel reference.
152 end record;
153
154 package Urefs is new Table.Table (
155 Table_Component_Type => Uref_Entry,
156 Table_Index_Type => Nat,
157 Table_Low_Bound => 1,
158 Table_Initial => 100,
159 Table_Increment => 200,
160 Table_Name => "Unnest_Urefs");
161
162 ------------------------
163 -- Append_Unique_Call --
164 ------------------------
165
166 procedure Append_Unique_Call (Call : Call_Entry) is
167 begin
168 for J in Calls.First .. Calls.Last loop
169 if Calls.Table (J) = Call then
170 return;
171 end if;
172 end loop;
173
174 Calls.Append (Call);
175 end Append_Unique_Call;
176
177 -----------------------------
178 -- Build_Access_Type_Decl --
179 -----------------------------
180
181 function Build_Access_Type_Decl
182 (E : Entity_Id;
183 Scop : Entity_Id) return Node_Id
184 is
185 Loc : constant Source_Ptr := Sloc (E);
186 Typ : Entity_Id;
187
188 begin
189 Typ := Make_Temporary (Loc, 'S');
190 Set_Ekind (Typ, E_General_Access_Type);
191 Set_Etype (Typ, Typ);
192 Set_Scope (Typ, Scop);
193 Set_Directly_Designated_Type (Typ, Etype (E));
194
195 return
196 Make_Full_Type_Declaration (Loc,
197 Defining_Identifier => Typ,
198 Type_Definition =>
199 Make_Access_To_Object_Definition (Loc,
200 Subtype_Indication => New_Occurrence_Of (Etype (E), Loc)));
201 end Build_Access_Type_Decl;
202
203 ---------------
204 -- Get_Level --
205 ---------------
206
207 function Get_Level (Subp : Entity_Id; Sub : Entity_Id) return Nat is
208 Lev : Nat;
209 S : Entity_Id;
210
211 begin
212 Lev := 1;
213 S := Sub;
214 loop
215 if S = Subp then
216 return Lev;
217 else
218 Lev := Lev + 1;
219 S := Enclosing_Subprogram (S);
220 end if;
221 end loop;
222 end Get_Level;
223
224 --------------------------
225 -- In_Synchronized_Unit --
226 --------------------------
227
228 function In_Synchronized_Unit (Subp : Entity_Id) return Boolean is
229 S : Entity_Id := Scope (Subp);
230
231 begin
232 while Present (S) and then S /= Standard_Standard loop
233 if Is_Concurrent_Type (S) then
234 return True;
235
236 elsif Is_Private_Type (S)
237 and then Present (Full_View (S))
238 and then Is_Concurrent_Type (Full_View (S))
239 then
240 return True;
241 end if;
242
243 S := Scope (S);
244 end loop;
245
246 return False;
247 end In_Synchronized_Unit;
248
249 -----------------------
250 -- Needs_Fat_Pointer --
251 -----------------------
252
253 function Needs_Fat_Pointer (E : Entity_Id) return Boolean is
254 Typ : Entity_Id;
255 begin
256 if Is_Formal (E) then
257 Typ := Etype (E);
258 if Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
259 Typ := Full_View (Typ);
260 end if;
261
262 return Is_Array_Type (Typ) and then not Is_Constrained (Typ);
263 else
264 return False;
265 end if;
266 end Needs_Fat_Pointer;
267
268 ----------------
269 -- Subp_Index --
270 ----------------
271
272 function Subp_Index (Sub : Entity_Id) return SI_Type is
273 E : Entity_Id := Sub;
274
275 begin
276 pragma Assert (Is_Subprogram (E));
277
278 if Subps_Index (E) = Uint_0 then
279 E := Ultimate_Alias (E);
280
281 -- The body of a protected operation has a different name and
282 -- has been scanned at this point, and thus has an entry in the
283 -- subprogram table.
284
285 if E = Sub and then Convention (E) = Convention_Protected then
286 E := Protected_Body_Subprogram (E);
287 end if;
288
289 if Ekind (E) = E_Function
290 and then Rewritten_For_C (E)
291 and then Present (Corresponding_Procedure (E))
292 then
293 E := Corresponding_Procedure (E);
294 end if;
295 end if;
296
297 pragma Assert (Subps_Index (E) /= Uint_0);
298 return SI_Type (UI_To_Int (Subps_Index (E)));
299 end Subp_Index;
300
301 -----------------------
302 -- Unnest_Subprogram --
303 -----------------------
304
305 procedure Unnest_Subprogram
306 (Subp : Entity_Id; Subp_Body : Node_Id; For_Inline : Boolean := False) is
307 function AREC_Name (J : Pos; S : String) return Name_Id;
308 -- Returns name for string ARECjS, where j is the decimal value of j
309
310 function Enclosing_Subp (Subp : SI_Type) return SI_Type;
311 -- Subp is the index of a subprogram which has a Lev greater than 1.
312 -- This function returns the index of the enclosing subprogram which
313 -- will have a Lev value one less than this.
314
315 function Img_Pos (N : Pos) return String;
316 -- Return image of N without leading blank
317
318 function Upref_Name
319 (Ent : Entity_Id;
320 Index : Pos;
321 Clist : List_Id) return Name_Id;
322 -- This function returns the name to be used in the activation record to
323 -- reference the variable uplevel. Clist is the list of components that
324 -- have been created in the activation record so far. Normally the name
325 -- is just a copy of the Chars field of the entity. The exception is
326 -- when the name has already been used, in which case we suffix the name
327 -- with the index value Index to avoid duplication. This happens with
328 -- declare blocks and generic parameters at least.
329
330 ---------------
331 -- AREC_Name --
332 ---------------
333
334 function AREC_Name (J : Pos; S : String) return Name_Id is
335 begin
336 return Name_Find ("AREC" & Img_Pos (J) & S);
337 end AREC_Name;
338
339 --------------------
340 -- Enclosing_Subp --
341 --------------------
342
343 function Enclosing_Subp (Subp : SI_Type) return SI_Type is
344 STJ : Subp_Entry renames Subps.Table (Subp);
345 Ret : constant SI_Type := Subp_Index (Enclosing_Subprogram (STJ.Ent));
346 begin
347 pragma Assert (STJ.Lev > 1);
348 pragma Assert (Subps.Table (Ret).Lev = STJ.Lev - 1);
349 return Ret;
350 end Enclosing_Subp;
351
352 -------------
353 -- Img_Pos --
354 -------------
355
356 function Img_Pos (N : Pos) return String is
357 Buf : String (1 .. 20);
358 Ptr : Natural;
359 NV : Nat;
360
361 begin
362 Ptr := Buf'Last;
363 NV := N;
364 while NV /= 0 loop
365 Buf (Ptr) := Character'Val (48 + NV mod 10);
366 Ptr := Ptr - 1;
367 NV := NV / 10;
368 end loop;
369
370 return Buf (Ptr + 1 .. Buf'Last);
371 end Img_Pos;
372
373 ----------------
374 -- Upref_Name --
375 ----------------
376
377 function Upref_Name
378 (Ent : Entity_Id;
379 Index : Pos;
380 Clist : List_Id) return Name_Id
381 is
382 C : Node_Id;
383 begin
384 C := First (Clist);
385 loop
386 if No (C) then
387 return Chars (Ent);
388
389 elsif Chars (Defining_Identifier (C)) = Chars (Ent) then
390 return
391 Name_Find (Get_Name_String (Chars (Ent)) & Img_Pos (Index));
392 else
393 Next (C);
394 end if;
395 end loop;
396 end Upref_Name;
397
398 -- Start of processing for Unnest_Subprogram
399
400 begin
401 -- Nothing to do inside a generic (all processing is for instance)
402
403 if Inside_A_Generic then
404 return;
405 end if;
406
407 -- If the main unit is a package body then we need to examine the spec
408 -- to determine whether the main unit is generic (the scope stack is not
409 -- present when this is called on the main unit).
410
411 if not For_Inline
412 and then Ekind (Cunit_Entity (Main_Unit)) = E_Package_Body
413 and then Is_Generic_Unit (Spec_Entity (Cunit_Entity (Main_Unit)))
414 then
415 return;
416
417 -- Only unnest when generating code for the main source unit or if
418 -- we're unnesting for inline. But in some Annex E cases the Sloc
419 -- points to a different unit, so also make sure that the Parent
420 -- isn't in something that we know we're generating code for.
421
422 elsif not For_Inline
423 and then not In_Extended_Main_Code_Unit (Subp_Body)
424 and then not In_Extended_Main_Code_Unit (Parent (Subp_Body))
425 then
426 return;
427 end if;
428
429 -- This routine is called late, after the scope stack is gone. The
430 -- following creates a suitable dummy scope stack to be used for the
431 -- analyze/expand calls made from this routine.
432
433 Push_Scope (Subp);
434
435 -- First step, we must mark all nested subprograms that require a static
436 -- link (activation record) because either they contain explicit uplevel
437 -- references (as indicated by Is_Uplevel_Referenced_Entity being set at
438 -- this point), or they make calls to other subprograms in the same nest
439 -- that require a static link (in which case we set this flag).
440
441 -- This is a recursive definition, and to implement this, we have to
442 -- build a call graph for the set of nested subprograms, and then go
443 -- over this graph to implement recursively the invariant that if a
444 -- subprogram has a call to a subprogram requiring a static link, then
445 -- the calling subprogram requires a static link.
446
447 -- First populate the above tables
448
449 Subps_First := Subps.Last + 1;
450 Calls.Init;
451 Urefs.Init;
452
453 Build_Tables : declare
454 Current_Subprogram : Entity_Id := Empty;
455 -- When we scan a subprogram body, we set Current_Subprogram to the
456 -- corresponding entity. This gets recursively saved and restored.
457
458 function Visit_Node (N : Node_Id) return Traverse_Result;
459 -- Visit a single node in Subp
460
461 -----------
462 -- Visit --
463 -----------
464
465 procedure Visit is new Traverse_Proc (Visit_Node);
466 -- Used to traverse the body of Subp, populating the tables
467
468 ----------------
469 -- Visit_Node --
470 ----------------
471
472 function Visit_Node (N : Node_Id) return Traverse_Result is
473 Ent : Entity_Id;
474 Caller : Entity_Id;
475 Callee : Entity_Id;
476
477 procedure Check_Static_Type
478 (T : Entity_Id;
479 N : Node_Id;
480 DT : in out Boolean;
481 Check_Designated : Boolean := False);
482 -- Given a type T, checks if it is a static type defined as a type
483 -- with no dynamic bounds in sight. If so, the only action is to
484 -- set Is_Static_Type True for T. If T is not a static type, then
485 -- all types with dynamic bounds associated with T are detected,
486 -- and their bounds are marked as uplevel referenced if not at the
487 -- library level, and DT is set True. If N is specified, it's the
488 -- node that will need to be replaced. If not specified, it means
489 -- we can't do a replacement because the bound is implicit.
490
491 -- If Check_Designated is True and T or its full view is an access
492 -- type, check whether the designated type has dynamic bounds.
493
494 procedure Note_Uplevel_Ref
495 (E : Entity_Id;
496 N : Node_Id;
497 Caller : Entity_Id;
498 Callee : Entity_Id);
499 -- Called when we detect an explicit or implicit uplevel reference
500 -- from within Caller to entity E declared in Callee. E can be a
501 -- an object or a type.
502
503 procedure Register_Subprogram (E : Entity_Id; Bod : Node_Id);
504 -- Enter a subprogram whose body is visible or which is a
505 -- subprogram instance into the subprogram table.
506
507 -----------------------
508 -- Check_Static_Type --
509 -----------------------
510
511 procedure Check_Static_Type
512 (T : Entity_Id;
513 N : Node_Id;
514 DT : in out Boolean;
515 Check_Designated : Boolean := False)
516 is
517 procedure Note_Uplevel_Bound (N : Node_Id; Ref : Node_Id);
518 -- N is the bound of a dynamic type. This procedure notes that
519 -- this bound is uplevel referenced, it can handle references
520 -- to entities (typically _FIRST and _LAST entities), and also
521 -- attribute references of the form T'name (name is typically
522 -- FIRST or LAST) where T is the uplevel referenced bound.
523 -- Ref, if Present, is the location of the reference to
524 -- replace.
525
526 ------------------------
527 -- Note_Uplevel_Bound --
528 ------------------------
529
530 procedure Note_Uplevel_Bound (N : Node_Id; Ref : Node_Id) is
531 begin
532 -- Entity name case. Make sure that the entity is declared
533 -- in a subprogram. This may not be the case for a type in a
534 -- loop appearing in a precondition.
535 -- Exclude explicitly discriminants (that can appear
536 -- in bounds of discriminated components).
537
538 if Is_Entity_Name (N) then
539 if Present (Entity (N))
540 and then not Is_Type (Entity (N))
541 and then Present (Enclosing_Subprogram (Entity (N)))
542 and then Ekind (Entity (N)) /= E_Discriminant
543 then
544 Note_Uplevel_Ref
545 (E => Entity (N),
546 N => Empty,
547 Caller => Current_Subprogram,
548 Callee => Enclosing_Subprogram (Entity (N)));
549 end if;
550
551 -- Attribute or indexed component case
552
553 elsif Nkind_In (N, N_Attribute_Reference,
554 N_Indexed_Component)
555 then
556 Note_Uplevel_Bound (Prefix (N), Ref);
557
558 -- The indices of the indexed components, or the
559 -- associated expressions of an attribute reference,
560 -- may also involve uplevel references.
561
562 declare
563 Expr : Node_Id;
564
565 begin
566 Expr := First (Expressions (N));
567 while Present (Expr) loop
568 Note_Uplevel_Bound (Expr, Ref);
569 Next (Expr);
570 end loop;
571 end;
572
573 -- The type of the prefix may be have an uplevel
574 -- reference if this needs bounds.
575
576 if Nkind (N) = N_Attribute_Reference then
577 declare
578 Attr : constant Attribute_Id :=
579 Get_Attribute_Id (Attribute_Name (N));
580 DT : Boolean := False;
581
582 begin
583 if (Attr = Attribute_First
584 or else Attr = Attribute_Last
585 or else Attr = Attribute_Length)
586 and then Is_Constrained (Etype (Prefix (N)))
587 then
588 Check_Static_Type
589 (Etype (Prefix (N)), Empty, DT);
590 end if;
591 end;
592 end if;
593
594 -- Binary operator cases. These can apply to arrays for
595 -- which we may need bounds.
596
597 elsif Nkind (N) in N_Binary_Op then
598 Note_Uplevel_Bound (Left_Opnd (N), Ref);
599 Note_Uplevel_Bound (Right_Opnd (N), Ref);
600
601 -- Unary operator case
602
603 elsif Nkind (N) in N_Unary_Op then
604 Note_Uplevel_Bound (Right_Opnd (N), Ref);
605
606 -- Explicit dereference and selected component case
607
608 elsif Nkind_In (N, N_Explicit_Dereference,
609 N_Selected_Component)
610 then
611 Note_Uplevel_Bound (Prefix (N), Ref);
612
613 -- Conditional expressions
614
615 elsif Nkind (N) = N_If_Expression then
616 declare
617 Expr : Node_Id;
618
619 begin
620 Expr := First (Expressions (N));
621 while Present (Expr) loop
622 Note_Uplevel_Bound (Expr, Ref);
623 Next (Expr);
624 end loop;
625 end;
626
627 elsif Nkind (N) = N_Case_Expression then
628 declare
629 Alternative : Node_Id;
630
631 begin
632 Note_Uplevel_Bound (Expression (N), Ref);
633
634 Alternative := First (Alternatives (N));
635 while Present (Alternative) loop
636 Note_Uplevel_Bound (Expression (Alternative), Ref);
637 end loop;
638 end;
639
640 -- Conversion case
641
642 elsif Nkind (N) = N_Type_Conversion then
643 Note_Uplevel_Bound (Expression (N), Ref);
644 end if;
645 end Note_Uplevel_Bound;
646
647 -- Start of processing for Check_Static_Type
648
649 begin
650 -- If already marked static, immediate return
651
652 if Is_Static_Type (T) and then not Check_Designated then
653 return;
654 end if;
655
656 -- If the type is at library level, always consider it static,
657 -- since such uplevel references are irrelevant.
658
659 if Is_Library_Level_Entity (T) then
660 Set_Is_Static_Type (T);
661 return;
662 end if;
663
664 -- Otherwise figure out what the story is with this type
665
666 -- For a scalar type, check bounds
667
668 if Is_Scalar_Type (T) then
669
670 -- If both bounds static, then this is a static type
671
672 declare
673 LB : constant Node_Id := Type_Low_Bound (T);
674 UB : constant Node_Id := Type_High_Bound (T);
675
676 begin
677 if not Is_Static_Expression (LB) then
678 Note_Uplevel_Bound (LB, N);
679 DT := True;
680 end if;
681
682 if not Is_Static_Expression (UB) then
683 Note_Uplevel_Bound (UB, N);
684 DT := True;
685 end if;
686 end;
687
688 -- For record type, check all components and discriminant
689 -- constraints if present.
690
691 elsif Is_Record_Type (T) then
692 declare
693 C : Entity_Id;
694 D : Elmt_Id;
695
696 begin
697 C := First_Component_Or_Discriminant (T);
698 while Present (C) loop
699 Check_Static_Type (Etype (C), N, DT);
700 Next_Component_Or_Discriminant (C);
701 end loop;
702
703 if Has_Discriminants (T)
704 and then Present (Discriminant_Constraint (T))
705 then
706 D := First_Elmt (Discriminant_Constraint (T));
707 while Present (D) loop
708 if not Is_Static_Expression (Node (D)) then
709 Note_Uplevel_Bound (Node (D), N);
710 DT := True;
711 end if;
712
713 Next_Elmt (D);
714 end loop;
715 end if;
716 end;
717
718 -- For array type, check index types and component type
719
720 elsif Is_Array_Type (T) then
721 declare
722 IX : Node_Id;
723 begin
724 Check_Static_Type (Component_Type (T), N, DT);
725
726 IX := First_Index (T);
727 while Present (IX) loop
728 Check_Static_Type (Etype (IX), N, DT);
729 Next_Index (IX);
730 end loop;
731 end;
732
733 -- For private type, examine whether full view is static
734
735 elsif Is_Incomplete_Or_Private_Type (T)
736 and then Present (Full_View (T))
737 then
738 Check_Static_Type (Full_View (T), N, DT, Check_Designated);
739
740 if Is_Static_Type (Full_View (T)) then
741 Set_Is_Static_Type (T);
742 end if;
743
744 -- For access types, check designated type when required
745
746 elsif Is_Access_Type (T) and then Check_Designated then
747 Check_Static_Type (Directly_Designated_Type (T), N, DT);
748
749 -- For now, ignore other types
750
751 else
752 return;
753 end if;
754
755 if not DT then
756 Set_Is_Static_Type (T);
757 end if;
758 end Check_Static_Type;
759
760 ----------------------
761 -- Note_Uplevel_Ref --
762 ----------------------
763
764 procedure Note_Uplevel_Ref
765 (E : Entity_Id;
766 N : Node_Id;
767 Caller : Entity_Id;
768 Callee : Entity_Id)
769 is
770 Full_E : Entity_Id := E;
771 begin
772 -- Nothing to do for static type
773
774 if Is_Static_Type (E) then
775 return;
776 end if;
777
778 -- Nothing to do if Caller and Callee are the same
779
780 if Caller = Callee then
781 return;
782
783 -- Callee may be a function that returns an array, and that has
784 -- been rewritten as a procedure. If caller is that procedure,
785 -- nothing to do either.
786
787 elsif Ekind (Callee) = E_Function
788 and then Rewritten_For_C (Callee)
789 and then Corresponding_Procedure (Callee) = Caller
790 then
791 return;
792
793 elsif Ekind_In (Callee, E_Entry, E_Entry_Family) then
794 return;
795 end if;
796
797 -- We have a new uplevel referenced entity
798
799 if Ekind (E) = E_Constant and then Present (Full_View (E)) then
800 Full_E := Full_View (E);
801 end if;
802
803 -- All we do at this stage is to add the uplevel reference to
804 -- the table. It's too early to do anything else, since this
805 -- uplevel reference may come from an unreachable subprogram
806 -- in which case the entry will be deleted.
807
808 Urefs.Append ((N, Full_E, Caller, Callee));
809 end Note_Uplevel_Ref;
810
811 -------------------------
812 -- Register_Subprogram --
813 -------------------------
814
815 procedure Register_Subprogram (E : Entity_Id; Bod : Node_Id) is
816 L : constant Nat := Get_Level (Subp, E);
817
818 begin
819 -- Subprograms declared in tasks and protected types cannot be
820 -- eliminated because calls to them may be in other units, so
821 -- they must be treated as reachable.
822
823 Subps.Append
824 ((Ent => E,
825 Bod => Bod,
826 Lev => L,
827 Reachable => In_Synchronized_Unit (E)
828 or else Address_Taken (E),
829 Uplevel_Ref => L,
830 Declares_AREC => False,
831 Uents => No_Elist,
832 Last => 0,
833 ARECnF => Empty,
834 ARECn => Empty,
835 ARECnT => Empty,
836 ARECnPT => Empty,
837 ARECnP => Empty,
838 ARECnU => Empty));
839
840 Set_Subps_Index (E, UI_From_Int (Subps.Last));
841
842 -- If we marked this reachable because it's in a synchronized
843 -- unit, we have to mark all enclosing subprograms as reachable
844 -- as well. We do the same for subprograms with Address_Taken,
845 -- because otherwise we can run into problems with looking at
846 -- enclosing subprograms in Subps.Table due to their being
847 -- unreachable (the Subp_Index of unreachable subps is later
848 -- set to zero and their entry in Subps.Table is removed).
849
850 if In_Synchronized_Unit (E) or else Address_Taken (E) then
851 declare
852 S : Entity_Id := E;
853
854 begin
855 for J in reverse 1 .. L - 1 loop
856 S := Enclosing_Subprogram (S);
857 Subps.Table (Subp_Index (S)).Reachable := True;
858 end loop;
859 end;
860 end if;
861 end Register_Subprogram;
862
863 -- Start of processing for Visit_Node
864
865 begin
866 case Nkind (N) is
867
868 -- Record a subprogram call
869
870 when N_Function_Call
871 | N_Procedure_Call_Statement
872 =>
873 -- We are only interested in direct calls, not indirect
874 -- calls (where Name (N) is an explicit dereference) at
875 -- least for now!
876
877 if Nkind (Name (N)) in N_Has_Entity then
878 Ent := Entity (Name (N));
879
880 -- We are only interested in calls to subprograms nested
881 -- within Subp. Calls to Subp itself or to subprograms
882 -- outside the nested structure do not affect us.
883
884 if Scope_Within (Ent, Subp)
885 and then Is_Subprogram (Ent)
886 and then not Is_Imported (Ent)
887 then
888 Append_Unique_Call ((N, Current_Subprogram, Ent));
889 end if;
890 end if;
891
892 -- For all calls where the formal is an unconstrained array
893 -- and the actual is constrained we need to check the bounds
894 -- for uplevel references.
895
896 declare
897 Actual : Entity_Id;
898 DT : Boolean := False;
899 Formal : Node_Id;
900 Subp : Entity_Id;
901
902 begin
903 if Nkind (Name (N)) = N_Explicit_Dereference then
904 Subp := Etype (Name (N));
905 else
906 Subp := Entity (Name (N));
907 end if;
908
909 Actual := First_Actual (N);
910 Formal := First_Formal_With_Extras (Subp);
911 while Present (Actual) loop
912 if Is_Array_Type (Etype (Formal))
913 and then not Is_Constrained (Etype (Formal))
914 and then Is_Constrained (Etype (Actual))
915 then
916 Check_Static_Type (Etype (Actual), Empty, DT);
917 end if;
918
919 Next_Actual (Actual);
920 Next_Formal_With_Extras (Formal);
921 end loop;
922 end;
923
924 -- An At_End_Proc in a statement sequence indicates that there
925 -- is a call from the enclosing construct or block to that
926 -- subprogram. As above, the called entity must be local and
927 -- not imported.
928
929 when N_Handled_Sequence_Of_Statements =>
930 if Present (At_End_Proc (N))
931 and then Scope_Within (Entity (At_End_Proc (N)), Subp)
932 and then not Is_Imported (Entity (At_End_Proc (N)))
933 then
934 Append_Unique_Call
935 ((N, Current_Subprogram, Entity (At_End_Proc (N))));
936 end if;
937
938 -- Similarly, the following constructs include a semantic
939 -- attribute Procedure_To_Call that must be handled like
940 -- other calls. Likewise for attribute Storage_Pool.
941
942 when N_Allocator
943 | N_Extended_Return_Statement
944 | N_Free_Statement
945 | N_Simple_Return_Statement
946 =>
947 declare
948 Pool : constant Entity_Id := Storage_Pool (N);
949 Proc : constant Entity_Id := Procedure_To_Call (N);
950
951 begin
952 if Present (Proc)
953 and then Scope_Within (Proc, Subp)
954 and then not Is_Imported (Proc)
955 then
956 Append_Unique_Call ((N, Current_Subprogram, Proc));
957 end if;
958
959 if Present (Pool)
960 and then not Is_Library_Level_Entity (Pool)
961 and then Scope_Within_Or_Same (Scope (Pool), Subp)
962 then
963 Caller := Current_Subprogram;
964 Callee := Enclosing_Subprogram (Pool);
965
966 if Callee /= Caller then
967 Note_Uplevel_Ref (Pool, Empty, Caller, Callee);
968 end if;
969 end if;
970 end;
971
972 -- For an allocator with a qualified expression, check type
973 -- of expression being qualified. The explicit type name is
974 -- handled as an entity reference.
975
976 if Nkind (N) = N_Allocator
977 and then Nkind (Expression (N)) = N_Qualified_Expression
978 then
979 declare
980 DT : Boolean := False;
981 begin
982 Check_Static_Type
983 (Etype (Expression (Expression (N))), Empty, DT);
984 end;
985
986 -- For a Return or Free (all other nodes we handle here),
987 -- we usually need the size of the object, so we need to be
988 -- sure that any nonstatic bounds of the expression's type
989 -- that are uplevel are handled.
990
991 elsif Nkind (N) /= N_Allocator
992 and then Present (Expression (N))
993 then
994 declare
995 DT : Boolean := False;
996 begin
997 Check_Static_Type
998 (Etype (Expression (N)),
999 Empty,
1000 DT,
1001 Check_Designated => Nkind (N) = N_Free_Statement);
1002 end;
1003 end if;
1004
1005 -- A 'Access reference is a (potential) call. So is 'Address,
1006 -- in particular on imported subprograms. Other attributes
1007 -- require special handling.
1008
1009 when N_Attribute_Reference =>
1010 declare
1011 Attr : constant Attribute_Id :=
1012 Get_Attribute_Id (Attribute_Name (N));
1013 begin
1014 case Attr is
1015 when Attribute_Access
1016 | Attribute_Unchecked_Access
1017 | Attribute_Unrestricted_Access
1018 | Attribute_Address
1019 =>
1020 if Nkind (Prefix (N)) in N_Has_Entity then
1021 Ent := Entity (Prefix (N));
1022
1023 -- We only need to examine calls to subprograms
1024 -- nested within current Subp.
1025
1026 if Scope_Within (Ent, Subp) then
1027 if Is_Imported (Ent) then
1028 null;
1029
1030 elsif Is_Subprogram (Ent) then
1031 Append_Unique_Call
1032 ((N, Current_Subprogram, Ent));
1033 end if;
1034 end if;
1035 end if;
1036
1037 -- References to bounds can be uplevel references if
1038 -- the type isn't static.
1039
1040 when Attribute_First
1041 | Attribute_Last
1042 | Attribute_Length
1043 =>
1044 -- Special-case attributes of objects whose bounds
1045 -- may be uplevel references. More complex prefixes
1046 -- handled during full traversal. Note that if the
1047 -- nominal subtype of the prefix is unconstrained,
1048 -- the bound must be obtained from the object, not
1049 -- from the (possibly) uplevel reference. We call
1050 -- Get_Referenced_Object to deal with prefixes that
1051 -- are object renamings (prefixes that are types
1052 -- can be passed and will simply be returned).
1053
1054 if Is_Constrained
1055 (Etype (Get_Referenced_Object (Prefix (N))))
1056 then
1057 declare
1058 DT : Boolean := False;
1059 begin
1060 Check_Static_Type
1061 (Etype (Get_Referenced_Object (Prefix (N))),
1062 Empty,
1063 DT);
1064 end;
1065
1066 return OK;
1067 end if;
1068
1069 when others =>
1070 null;
1071 end case;
1072 end;
1073
1074 -- Component associations in aggregates are either static or
1075 -- else the aggregate will be expanded into assignments, in
1076 -- which case the expression is analyzed later and provides
1077 -- no relevant code generation.
1078
1079 when N_Component_Association =>
1080 if No (Expression (N))
1081 or else No (Etype (Expression (N)))
1082 then
1083 return Skip;
1084 end if;
1085
1086 -- Generic associations are not analyzed: the actuals are
1087 -- transferred to renaming and subtype declarations that
1088 -- are the ones that must be examined.
1089
1090 when N_Generic_Association =>
1091 return Skip;
1092
1093 -- Indexed references can be uplevel if the type isn't static
1094 -- and if the lower bound (or an inner bound for a multi-
1095 -- dimensional array) is uplevel.
1096
1097 when N_Indexed_Component
1098 | N_Slice
1099 =>
1100 if Is_Constrained (Etype (Prefix (N))) then
1101 declare
1102 DT : Boolean := False;
1103 begin
1104 Check_Static_Type (Etype (Prefix (N)), Empty, DT);
1105 end;
1106 end if;
1107
1108 -- A selected component can have an implicit up-level
1109 -- reference due to the bounds of previous fields in the
1110 -- record. We simplify the processing here by examining
1111 -- all components of the record.
1112
1113 -- Selected components appear as unit names and end labels
1114 -- for child units. Prefixes of these nodes denote parent
1115 -- units and carry no type information so they are skipped.
1116
1117 when N_Selected_Component =>
1118 if Present (Etype (Prefix (N))) then
1119 declare
1120 DT : Boolean := False;
1121 begin
1122 Check_Static_Type (Etype (Prefix (N)), Empty, DT);
1123 end;
1124 end if;
1125
1126 -- For EQ/NE comparisons, we need the type of the operands
1127 -- in order to do the comparison, which means we need the
1128 -- bounds.
1129
1130 when N_Op_Eq
1131 | N_Op_Ne
1132 =>
1133 declare
1134 DT : Boolean := False;
1135 begin
1136 Check_Static_Type (Etype (Left_Opnd (N)), Empty, DT);
1137 Check_Static_Type (Etype (Right_Opnd (N)), Empty, DT);
1138 end;
1139
1140 -- Likewise we need the sizes to compute how much to move in
1141 -- an assignment.
1142
1143 when N_Assignment_Statement =>
1144 declare
1145 DT : Boolean := False;
1146 begin
1147 Check_Static_Type (Etype (Name (N)), Empty, DT);
1148 Check_Static_Type (Etype (Expression (N)), Empty, DT);
1149 end;
1150
1151 -- Record a subprogram. We record a subprogram body that acts
1152 -- as a spec. Otherwise we record a subprogram declaration,
1153 -- providing that it has a corresponding body we can get hold
1154 -- of. The case of no corresponding body being available is
1155 -- ignored for now.
1156
1157 when N_Subprogram_Body =>
1158 Ent := Unique_Defining_Entity (N);
1159
1160 -- Ignore generic subprogram
1161
1162 if Is_Generic_Subprogram (Ent) then
1163 return Skip;
1164 end if;
1165
1166 -- Make new entry in subprogram table if not already made
1167
1168 Register_Subprogram (Ent, N);
1169
1170 -- We make a recursive call to scan the subprogram body, so
1171 -- that we can save and restore Current_Subprogram.
1172
1173 declare
1174 Save_CS : constant Entity_Id := Current_Subprogram;
1175 Decl : Node_Id;
1176
1177 begin
1178 Current_Subprogram := Ent;
1179
1180 -- Scan declarations
1181
1182 Decl := First (Declarations (N));
1183 while Present (Decl) loop
1184 Visit (Decl);
1185 Next (Decl);
1186 end loop;
1187
1188 -- Scan statements
1189
1190 Visit (Handled_Statement_Sequence (N));
1191
1192 -- Restore current subprogram setting
1193
1194 Current_Subprogram := Save_CS;
1195 end;
1196
1197 -- Now at this level, return skipping the subprogram body
1198 -- descendants, since we already took care of them!
1199
1200 return Skip;
1201
1202 -- If we have a body stub, visit the associated subunit, which
1203 -- is a semantic descendant of the stub.
1204
1205 when N_Body_Stub =>
1206 Visit (Library_Unit (N));
1207
1208 -- A declaration of a wrapper package indicates a subprogram
1209 -- instance for which there is no explicit body. Enter the
1210 -- subprogram instance in the table.
1211
1212 when N_Package_Declaration =>
1213 if Is_Wrapper_Package (Defining_Entity (N)) then
1214 Register_Subprogram
1215 (Related_Instance (Defining_Entity (N)), Empty);
1216 end if;
1217
1218 -- Skip generic declarations
1219
1220 when N_Generic_Declaration =>
1221 return Skip;
1222
1223 -- Skip generic package body
1224
1225 when N_Package_Body =>
1226 if Present (Corresponding_Spec (N))
1227 and then Ekind (Corresponding_Spec (N)) = E_Generic_Package
1228 then
1229 return Skip;
1230 end if;
1231
1232 -- Pragmas and component declarations are ignored. Quantified
1233 -- expressions are expanded into explicit loops and the
1234 -- original epression must be ignored.
1235
1236 when N_Component_Declaration
1237 | N_Pragma
1238 | N_Quantified_Expression
1239 =>
1240 return Skip;
1241
1242 -- We want to skip the function spec for a generic function
1243 -- to avoid looking at any generic types that might be in
1244 -- its formals.
1245
1246 when N_Function_Specification =>
1247 if Is_Generic_Subprogram (Unique_Defining_Entity (N)) then
1248 return Skip;
1249 end if;
1250
1251 -- Otherwise record an uplevel reference in a local identifier
1252
1253 when others =>
1254 if Nkind (N) in N_Has_Entity
1255 and then Present (Entity (N))
1256 then
1257 Ent := Entity (N);
1258
1259 -- Only interested in entities declared within our nest
1260
1261 if not Is_Library_Level_Entity (Ent)
1262 and then Scope_Within_Or_Same (Scope (Ent), Subp)
1263
1264 -- Skip entities defined in inlined subprograms
1265
1266 and then
1267 Chars (Enclosing_Subprogram (Ent)) /= Name_uParent
1268
1269 -- Constants and variables are potentially uplevel
1270 -- references to global declarations.
1271
1272 and then
1273 (Ekind_In (Ent, E_Constant,
1274 E_Loop_Parameter,
1275 E_Variable)
1276
1277 -- Formals are interesting, but not if being used
1278 -- as mere names of parameters for name notation
1279 -- calls.
1280
1281 or else
1282 (Is_Formal (Ent)
1283 and then not
1284 (Nkind (Parent (N)) = N_Parameter_Association
1285 and then Selector_Name (Parent (N)) = N))
1286
1287 -- Types other than known Is_Static types are
1288 -- potentially interesting.
1289
1290 or else
1291 (Is_Type (Ent) and then not Is_Static_Type (Ent)))
1292 then
1293 -- Here we have a potentially interesting uplevel
1294 -- reference to examine.
1295
1296 if Is_Type (Ent) then
1297 declare
1298 DT : Boolean := False;
1299
1300 begin
1301 Check_Static_Type (Ent, N, DT);
1302 return OK;
1303 end;
1304 end if;
1305
1306 Caller := Current_Subprogram;
1307 Callee := Enclosing_Subprogram (Ent);
1308
1309 if Callee /= Caller
1310 and then (not Is_Static_Type (Ent)
1311 or else Needs_Fat_Pointer (Ent))
1312 then
1313 Note_Uplevel_Ref (Ent, N, Caller, Callee);
1314
1315 -- Check the type of a formal parameter of the current
1316 -- subprogram, whose formal type may be an uplevel
1317 -- reference.
1318
1319 elsif Is_Formal (Ent)
1320 and then Scope (Ent) = Current_Subprogram
1321 then
1322 declare
1323 DT : Boolean := False;
1324
1325 begin
1326 Check_Static_Type (Etype (Ent), Empty, DT);
1327 end;
1328 end if;
1329 end if;
1330 end if;
1331 end case;
1332
1333 -- Fall through to continue scanning children of this node
1334
1335 return OK;
1336 end Visit_Node;
1337
1338 -- Start of processing for Build_Tables
1339
1340 begin
1341 -- Traverse the body to get subprograms, calls and uplevel references
1342
1343 Visit (Subp_Body);
1344 end Build_Tables;
1345
1346 -- Now do the first transitive closure which determines which
1347 -- subprograms in the nest are actually reachable.
1348
1349 Reachable_Closure : declare
1350 Modified : Boolean;
1351
1352 begin
1353 Subps.Table (Subps_First).Reachable := True;
1354
1355 -- We use a simple minded algorithm as follows (obviously this can
1356 -- be done more efficiently, using one of the standard algorithms
1357 -- for efficient transitive closure computation, but this is simple
1358 -- and most likely fast enough that its speed does not matter).
1359
1360 -- Repeatedly scan the list of calls. Any time we find a call from
1361 -- A to B, where A is reachable, but B is not, then B is reachable,
1362 -- and note that we have made a change by setting Modified True. We
1363 -- repeat this until we make a pass with no modifications.
1364
1365 Outer : loop
1366 Modified := False;
1367 Inner : for J in Calls.First .. Calls.Last loop
1368 declare
1369 CTJ : Call_Entry renames Calls.Table (J);
1370
1371 SINF : constant SI_Type := Subp_Index (CTJ.Caller);
1372 SINT : constant SI_Type := Subp_Index (CTJ.Callee);
1373
1374 SUBF : Subp_Entry renames Subps.Table (SINF);
1375 SUBT : Subp_Entry renames Subps.Table (SINT);
1376
1377 begin
1378 if SUBF.Reachable and then not SUBT.Reachable then
1379 SUBT.Reachable := True;
1380 Modified := True;
1381 end if;
1382 end;
1383 end loop Inner;
1384
1385 exit Outer when not Modified;
1386 end loop Outer;
1387 end Reachable_Closure;
1388
1389 -- Remove calls from unreachable subprograms
1390
1391 declare
1392 New_Index : Nat;
1393
1394 begin
1395 New_Index := 0;
1396 for J in Calls.First .. Calls.Last loop
1397 declare
1398 CTJ : Call_Entry renames Calls.Table (J);
1399
1400 SINF : constant SI_Type := Subp_Index (CTJ.Caller);
1401 SINT : constant SI_Type := Subp_Index (CTJ.Callee);
1402
1403 SUBF : Subp_Entry renames Subps.Table (SINF);
1404 SUBT : Subp_Entry renames Subps.Table (SINT);
1405
1406 begin
1407 if SUBF.Reachable then
1408 pragma Assert (SUBT.Reachable);
1409 New_Index := New_Index + 1;
1410 Calls.Table (New_Index) := Calls.Table (J);
1411 end if;
1412 end;
1413 end loop;
1414
1415 Calls.Set_Last (New_Index);
1416 end;
1417
1418 -- Remove uplevel references from unreachable subprograms
1419
1420 declare
1421 New_Index : Nat;
1422
1423 begin
1424 New_Index := 0;
1425 for J in Urefs.First .. Urefs.Last loop
1426 declare
1427 URJ : Uref_Entry renames Urefs.Table (J);
1428
1429 SINF : constant SI_Type := Subp_Index (URJ.Caller);
1430 SINT : constant SI_Type := Subp_Index (URJ.Callee);
1431
1432 SUBF : Subp_Entry renames Subps.Table (SINF);
1433 SUBT : Subp_Entry renames Subps.Table (SINT);
1434
1435 S : Entity_Id;
1436
1437 begin
1438 -- Keep reachable reference
1439
1440 if SUBF.Reachable then
1441 New_Index := New_Index + 1;
1442 Urefs.Table (New_Index) := Urefs.Table (J);
1443
1444 -- And since we know we are keeping this one, this is a good
1445 -- place to fill in information for a good reference.
1446
1447 -- Mark all enclosing subprograms need to declare AREC
1448
1449 S := URJ.Caller;
1450 loop
1451 S := Enclosing_Subprogram (S);
1452
1453 -- If we are at the top level, as can happen with
1454 -- references to formals in aspects of nested subprogram
1455 -- declarations, there are no further subprograms to mark
1456 -- as requiring activation records.
1457
1458 exit when No (S);
1459
1460 declare
1461 SUBI : Subp_Entry renames Subps.Table (Subp_Index (S));
1462 begin
1463 SUBI.Declares_AREC := True;
1464
1465 -- If this entity was marked reachable because it is
1466 -- in a task or protected type, there may not appear
1467 -- to be any calls to it, which would normally adjust
1468 -- the levels of the parent subprograms. So we need to
1469 -- be sure that the uplevel reference of that entity
1470 -- takes into account possible calls.
1471
1472 if In_Synchronized_Unit (SUBF.Ent)
1473 and then SUBT.Lev < SUBI.Uplevel_Ref
1474 then
1475 SUBI.Uplevel_Ref := SUBT.Lev;
1476 end if;
1477 end;
1478
1479 exit when S = URJ.Callee;
1480 end loop;
1481
1482 -- Add to list of uplevel referenced entities for Callee.
1483 -- We do not add types to this list, only actual references
1484 -- to objects that will be referenced uplevel, and we use
1485 -- the flag Is_Uplevel_Referenced_Entity to avoid making
1486 -- duplicate entries in the list. Discriminants are also
1487 -- excluded, only the enclosing object can appear in the
1488 -- list.
1489
1490 if not Is_Uplevel_Referenced_Entity (URJ.Ent)
1491 and then Ekind (URJ.Ent) /= E_Discriminant
1492 then
1493 Set_Is_Uplevel_Referenced_Entity (URJ.Ent);
1494 Append_New_Elmt (URJ.Ent, SUBT.Uents);
1495 end if;
1496
1497 -- And set uplevel indication for caller
1498
1499 if SUBT.Lev < SUBF.Uplevel_Ref then
1500 SUBF.Uplevel_Ref := SUBT.Lev;
1501 end if;
1502 end if;
1503 end;
1504 end loop;
1505
1506 Urefs.Set_Last (New_Index);
1507 end;
1508
1509 -- Remove unreachable subprograms from Subps table. Note that we do
1510 -- this after eliminating entries from the other two tables, since
1511 -- those elimination steps depend on referencing the Subps table.
1512
1513 declare
1514 New_SI : SI_Type;
1515
1516 begin
1517 New_SI := Subps_First - 1;
1518 for J in Subps_First .. Subps.Last loop
1519 declare
1520 STJ : Subp_Entry renames Subps.Table (J);
1521 Spec : Node_Id;
1522 Decl : Node_Id;
1523
1524 begin
1525 -- Subprogram is reachable, copy and reset index
1526
1527 if STJ.Reachable then
1528 New_SI := New_SI + 1;
1529 Subps.Table (New_SI) := STJ;
1530 Set_Subps_Index (STJ.Ent, UI_From_Int (New_SI));
1531
1532 -- Subprogram is not reachable
1533
1534 else
1535 -- Clear index, since no longer active
1536
1537 Set_Subps_Index (Subps.Table (J).Ent, Uint_0);
1538
1539 -- Output debug information if -gnatd.3 set
1540
1541 if Debug_Flag_Dot_3 then
1542 Write_Str ("Eliminate ");
1543 Write_Name (Chars (Subps.Table (J).Ent));
1544 Write_Str (" at ");
1545 Write_Location (Sloc (Subps.Table (J).Ent));
1546 Write_Str (" (not referenced)");
1547 Write_Eol;
1548 end if;
1549
1550 -- Rewrite declaration, body, and corresponding freeze node
1551 -- to null statements.
1552
1553 -- A subprogram instantiation does not have an explicit
1554 -- body. If unused, we could remove the corresponding
1555 -- wrapper package and its body (TBD).
1556
1557 if Present (STJ.Bod) then
1558 Spec := Corresponding_Spec (STJ.Bod);
1559
1560 if Present (Spec) then
1561 Decl := Parent (Declaration_Node (Spec));
1562 Rewrite (Decl, Make_Null_Statement (Sloc (Decl)));
1563
1564 if Present (Freeze_Node (Spec)) then
1565 Rewrite (Freeze_Node (Spec),
1566 Make_Null_Statement (Sloc (Decl)));
1567 end if;
1568 end if;
1569
1570 Rewrite (STJ.Bod, Make_Null_Statement (Sloc (STJ.Bod)));
1571 end if;
1572 end if;
1573 end;
1574 end loop;
1575
1576 Subps.Set_Last (New_SI);
1577 end;
1578
1579 -- Now it is time for the second transitive closure, which follows calls
1580 -- and makes sure that A calls B, and B has uplevel references, then A
1581 -- is also marked as having uplevel references.
1582
1583 Closure_Uplevel : declare
1584 Modified : Boolean;
1585
1586 begin
1587 -- We use a simple minded algorithm as follows (obviously this can
1588 -- be done more efficiently, using one of the standard algorithms
1589 -- for efficient transitive closure computation, but this is simple
1590 -- and most likely fast enough that its speed does not matter).
1591
1592 -- Repeatedly scan the list of calls. Any time we find a call from
1593 -- A to B, where B has uplevel references, make sure that A is marked
1594 -- as having at least the same level of uplevel referencing.
1595
1596 Outer2 : loop
1597 Modified := False;
1598 Inner2 : for J in Calls.First .. Calls.Last loop
1599 declare
1600 CTJ : Call_Entry renames Calls.Table (J);
1601 SINF : constant SI_Type := Subp_Index (CTJ.Caller);
1602 SINT : constant SI_Type := Subp_Index (CTJ.Callee);
1603 SUBF : Subp_Entry renames Subps.Table (SINF);
1604 SUBT : Subp_Entry renames Subps.Table (SINT);
1605 begin
1606 if SUBT.Lev > SUBT.Uplevel_Ref
1607 and then SUBF.Uplevel_Ref > SUBT.Uplevel_Ref
1608 then
1609 SUBF.Uplevel_Ref := SUBT.Uplevel_Ref;
1610 Modified := True;
1611 end if;
1612 end;
1613 end loop Inner2;
1614
1615 exit Outer2 when not Modified;
1616 end loop Outer2;
1617 end Closure_Uplevel;
1618
1619 -- We have one more step before the tables are complete. An uplevel
1620 -- call from subprogram A to subprogram B where subprogram B has uplevel
1621 -- references is in effect an uplevel reference, and must arrange for
1622 -- the proper activation link to be passed.
1623
1624 for J in Calls.First .. Calls.Last loop
1625 declare
1626 CTJ : Call_Entry renames Calls.Table (J);
1627
1628 SINF : constant SI_Type := Subp_Index (CTJ.Caller);
1629 SINT : constant SI_Type := Subp_Index (CTJ.Callee);
1630
1631 SUBF : Subp_Entry renames Subps.Table (SINF);
1632 SUBT : Subp_Entry renames Subps.Table (SINT);
1633
1634 A : Entity_Id;
1635
1636 begin
1637 -- If callee has uplevel references
1638
1639 if SUBT.Uplevel_Ref < SUBT.Lev
1640
1641 -- And this is an uplevel call
1642
1643 and then SUBT.Lev < SUBF.Lev
1644 then
1645 -- We need to arrange for finding the uplink
1646
1647 A := CTJ.Caller;
1648 loop
1649 A := Enclosing_Subprogram (A);
1650 Subps.Table (Subp_Index (A)).Declares_AREC := True;
1651 exit when A = CTJ.Callee;
1652
1653 -- In any case exit when we get to the outer level. This
1654 -- happens in some odd cases with generics (in particular
1655 -- sem_ch3.adb does not compile without this kludge ???).
1656
1657 exit when A = Subp;
1658 end loop;
1659 end if;
1660 end;
1661 end loop;
1662
1663 -- The tables are now complete, so we can record the last index in the
1664 -- Subps table for later reference in Cprint.
1665
1666 Subps.Table (Subps_First).Last := Subps.Last;
1667
1668 -- Next step, create the entities for code we will insert. We do this
1669 -- at the start so that all the entities are defined, regardless of the
1670 -- order in which we do the code insertions.
1671
1672 Create_Entities : for J in Subps_First .. Subps.Last loop
1673 declare
1674 STJ : Subp_Entry renames Subps.Table (J);
1675 Loc : constant Source_Ptr := Sloc (STJ.Bod);
1676
1677 begin
1678 -- First we create the ARECnF entity for the additional formal for
1679 -- all subprograms which need an activation record passed.
1680
1681 if STJ.Uplevel_Ref < STJ.Lev then
1682 STJ.ARECnF :=
1683 Make_Defining_Identifier (Loc, Chars => AREC_Name (J, "F"));
1684 end if;
1685
1686 -- Define the AREC entities for the activation record if needed
1687
1688 if STJ.Declares_AREC then
1689 STJ.ARECn :=
1690 Make_Defining_Identifier (Loc, AREC_Name (J, ""));
1691 STJ.ARECnT :=
1692 Make_Defining_Identifier (Loc, AREC_Name (J, "T"));
1693 STJ.ARECnPT :=
1694 Make_Defining_Identifier (Loc, AREC_Name (J, "PT"));
1695 STJ.ARECnP :=
1696 Make_Defining_Identifier (Loc, AREC_Name (J, "P"));
1697
1698 -- Define uplink component entity if inner nesting case
1699
1700 if Present (STJ.ARECnF) then
1701 STJ.ARECnU :=
1702 Make_Defining_Identifier (Loc, AREC_Name (J, "U"));
1703 end if;
1704 end if;
1705 end;
1706 end loop Create_Entities;
1707
1708 -- Loop through subprograms
1709
1710 Subp_Loop : declare
1711 Addr : Entity_Id := Empty;
1712
1713 begin
1714 for J in Subps_First .. Subps.Last loop
1715 declare
1716 STJ : Subp_Entry renames Subps.Table (J);
1717
1718 begin
1719 -- First add the extra formal if needed. This applies to all
1720 -- nested subprograms that require an activation record to be
1721 -- passed, as indicated by ARECnF being defined.
1722
1723 if Present (STJ.ARECnF) then
1724
1725 -- Here we need the extra formal. We do the expansion and
1726 -- analysis of this manually, since it is fairly simple,
1727 -- and it is not obvious how we can get what we want if we
1728 -- try to use the normal Analyze circuit.
1729
1730 Add_Extra_Formal : declare
1731 Encl : constant SI_Type := Enclosing_Subp (J);
1732 STJE : Subp_Entry renames Subps.Table (Encl);
1733 -- Index and Subp_Entry for enclosing routine
1734
1735 Form : constant Entity_Id := STJ.ARECnF;
1736 -- The formal to be added. Note that n here is one less
1737 -- than the level of the subprogram itself (STJ.Ent).
1738
1739 procedure Add_Form_To_Spec (F : Entity_Id; S : Node_Id);
1740 -- S is an N_Function/Procedure_Specification node, and F
1741 -- is the new entity to add to this subprogramn spec as
1742 -- the last Extra_Formal.
1743
1744 ----------------------
1745 -- Add_Form_To_Spec --
1746 ----------------------
1747
1748 procedure Add_Form_To_Spec (F : Entity_Id; S : Node_Id) is
1749 Sub : constant Entity_Id := Defining_Entity (S);
1750 Ent : Entity_Id;
1751
1752 begin
1753 -- Case of at least one Extra_Formal is present, set
1754 -- ARECnF as the new last entry in the list.
1755
1756 if Present (Extra_Formals (Sub)) then
1757 Ent := Extra_Formals (Sub);
1758 while Present (Extra_Formal (Ent)) loop
1759 Ent := Extra_Formal (Ent);
1760 end loop;
1761
1762 Set_Extra_Formal (Ent, F);
1763
1764 -- No Extra formals present
1765
1766 else
1767 Set_Extra_Formals (Sub, F);
1768 Ent := Last_Formal (Sub);
1769
1770 if Present (Ent) then
1771 Set_Extra_Formal (Ent, F);
1772 end if;
1773 end if;
1774 end Add_Form_To_Spec;
1775
1776 -- Start of processing for Add_Extra_Formal
1777
1778 begin
1779 -- Decorate the new formal entity
1780
1781 Set_Scope (Form, STJ.Ent);
1782 Set_Ekind (Form, E_In_Parameter);
1783 Set_Etype (Form, STJE.ARECnPT);
1784 Set_Mechanism (Form, By_Copy);
1785 Set_Never_Set_In_Source (Form, True);
1786 Set_Analyzed (Form, True);
1787 Set_Comes_From_Source (Form, False);
1788 Set_Is_Activation_Record (Form, True);
1789
1790 -- Case of only body present
1791
1792 if Acts_As_Spec (STJ.Bod) then
1793 Add_Form_To_Spec (Form, Specification (STJ.Bod));
1794
1795 -- Case of separate spec
1796
1797 else
1798 Add_Form_To_Spec (Form, Parent (STJ.Ent));
1799 end if;
1800 end Add_Extra_Formal;
1801 end if;
1802
1803 -- Processing for subprograms that declare an activation record
1804
1805 if Present (STJ.ARECn) then
1806
1807 -- Local declarations for one such subprogram
1808
1809 declare
1810 Loc : constant Source_Ptr := Sloc (STJ.Bod);
1811
1812 Decls : constant List_Id := New_List;
1813 -- List of new declarations we create
1814
1815 Clist : List_Id;
1816 Comp : Entity_Id;
1817
1818 Decl_Assign : Node_Id;
1819 -- Assignment to set uplink, Empty if none
1820
1821 Decl_ARECnT : Node_Id;
1822 Decl_ARECnPT : Node_Id;
1823 Decl_ARECn : Node_Id;
1824 Decl_ARECnP : Node_Id;
1825 -- Declaration nodes for the AREC entities we build
1826
1827 begin
1828 -- Build list of component declarations for ARECnT and
1829 -- load System.Address.
1830
1831 Clist := Empty_List;
1832
1833 if No (Addr) then
1834 Addr := RTE (RE_Address);
1835 end if;
1836
1837 -- If we are in a subprogram that has a static link that
1838 -- is passed in (as indicated by ARECnF being defined),
1839 -- then include ARECnU : ARECmPT where ARECmPT comes from
1840 -- the level one higher than the current level, and the
1841 -- entity ARECnPT comes from the enclosing subprogram.
1842
1843 if Present (STJ.ARECnF) then
1844 declare
1845 STJE : Subp_Entry
1846 renames Subps.Table (Enclosing_Subp (J));
1847 begin
1848 Append_To (Clist,
1849 Make_Component_Declaration (Loc,
1850 Defining_Identifier => STJ.ARECnU,
1851 Component_Definition =>
1852 Make_Component_Definition (Loc,
1853 Subtype_Indication =>
1854 New_Occurrence_Of (STJE.ARECnPT, Loc))));
1855 end;
1856 end if;
1857
1858 -- Add components for uplevel referenced entities
1859
1860 if Present (STJ.Uents) then
1861 declare
1862 Elmt : Elmt_Id;
1863 Ptr_Decl : Node_Id;
1864 Uent : Entity_Id;
1865
1866 Indx : Nat;
1867 -- 1's origin of index in list of elements. This is
1868 -- used to uniquify names if needed in Upref_Name.
1869
1870 begin
1871 Elmt := First_Elmt (STJ.Uents);
1872 Indx := 0;
1873 while Present (Elmt) loop
1874 Uent := Node (Elmt);
1875 Indx := Indx + 1;
1876
1877 Comp :=
1878 Make_Defining_Identifier (Loc,
1879 Chars => Upref_Name (Uent, Indx, Clist));
1880
1881 Set_Activation_Record_Component
1882 (Uent, Comp);
1883
1884 if Needs_Fat_Pointer (Uent) then
1885
1886 -- Build corresponding access type
1887
1888 Ptr_Decl :=
1889 Build_Access_Type_Decl
1890 (Etype (Uent), STJ.Ent);
1891 Append_To (Decls, Ptr_Decl);
1892
1893 -- And use its type in the corresponding
1894 -- component.
1895
1896 Append_To (Clist,
1897 Make_Component_Declaration (Loc,
1898 Defining_Identifier => Comp,
1899 Component_Definition =>
1900 Make_Component_Definition (Loc,
1901 Subtype_Indication =>
1902 New_Occurrence_Of
1903 (Defining_Identifier (Ptr_Decl),
1904 Loc))));
1905 else
1906 Append_To (Clist,
1907 Make_Component_Declaration (Loc,
1908 Defining_Identifier => Comp,
1909 Component_Definition =>
1910 Make_Component_Definition (Loc,
1911 Subtype_Indication =>
1912 New_Occurrence_Of (Addr, Loc))));
1913 end if;
1914 Next_Elmt (Elmt);
1915 end loop;
1916 end;
1917 end if;
1918
1919 -- Now we can insert the AREC declarations into the body
1920 -- type ARECnT is record .. end record;
1921 -- pragma Suppress_Initialization (ARECnT);
1922
1923 -- Note that we need to set the Suppress_Initialization
1924 -- flag after Decl_ARECnT has been analyzed.
1925
1926 Decl_ARECnT :=
1927 Make_Full_Type_Declaration (Loc,
1928 Defining_Identifier => STJ.ARECnT,
1929 Type_Definition =>
1930 Make_Record_Definition (Loc,
1931 Component_List =>
1932 Make_Component_List (Loc,
1933 Component_Items => Clist)));
1934 Append_To (Decls, Decl_ARECnT);
1935
1936 -- type ARECnPT is access all ARECnT;
1937
1938 Decl_ARECnPT :=
1939 Make_Full_Type_Declaration (Loc,
1940 Defining_Identifier => STJ.ARECnPT,
1941 Type_Definition =>
1942 Make_Access_To_Object_Definition (Loc,
1943 All_Present => True,
1944 Subtype_Indication =>
1945 New_Occurrence_Of (STJ.ARECnT, Loc)));
1946 Append_To (Decls, Decl_ARECnPT);
1947
1948 -- ARECn : aliased ARECnT;
1949
1950 Decl_ARECn :=
1951 Make_Object_Declaration (Loc,
1952 Defining_Identifier => STJ.ARECn,
1953 Aliased_Present => True,
1954 Object_Definition =>
1955 New_Occurrence_Of (STJ.ARECnT, Loc));
1956 Append_To (Decls, Decl_ARECn);
1957
1958 -- ARECnP : constant ARECnPT := ARECn'Access;
1959
1960 Decl_ARECnP :=
1961 Make_Object_Declaration (Loc,
1962 Defining_Identifier => STJ.ARECnP,
1963 Constant_Present => True,
1964 Object_Definition =>
1965 New_Occurrence_Of (STJ.ARECnPT, Loc),
1966 Expression =>
1967 Make_Attribute_Reference (Loc,
1968 Prefix =>
1969 New_Occurrence_Of (STJ.ARECn, Loc),
1970 Attribute_Name => Name_Access));
1971 Append_To (Decls, Decl_ARECnP);
1972
1973 -- If we are in a subprogram that has a static link that
1974 -- is passed in (as indicated by ARECnF being defined),
1975 -- then generate ARECn.ARECmU := ARECmF where m is
1976 -- one less than the current level to set the uplink.
1977
1978 if Present (STJ.ARECnF) then
1979 Decl_Assign :=
1980 Make_Assignment_Statement (Loc,
1981 Name =>
1982 Make_Selected_Component (Loc,
1983 Prefix =>
1984 New_Occurrence_Of (STJ.ARECn, Loc),
1985 Selector_Name =>
1986 New_Occurrence_Of (STJ.ARECnU, Loc)),
1987 Expression =>
1988 New_Occurrence_Of (STJ.ARECnF, Loc));
1989 Append_To (Decls, Decl_Assign);
1990
1991 else
1992 Decl_Assign := Empty;
1993 end if;
1994
1995 if No (Declarations (STJ.Bod)) then
1996 Set_Declarations (STJ.Bod, Decls);
1997 else
1998 Prepend_List_To (Declarations (STJ.Bod), Decls);
1999 end if;
2000
2001 -- Analyze the newly inserted declarations. Note that we
2002 -- do not need to establish the whole scope stack, since
2003 -- we have already set all entity fields (so there will
2004 -- be no searching of upper scopes to resolve names). But
2005 -- we do set the scope of the current subprogram, so that
2006 -- newly created entities go in the right entity chain.
2007
2008 -- We analyze with all checks suppressed (since we do
2009 -- not expect any exceptions).
2010
2011 Push_Scope (STJ.Ent);
2012 Analyze (Decl_ARECnT, Suppress => All_Checks);
2013
2014 -- Note that we need to call Set_Suppress_Initialization
2015 -- after Decl_ARECnT has been analyzed, but before
2016 -- analyzing Decl_ARECnP so that the flag is properly
2017 -- taking into account.
2018
2019 Set_Suppress_Initialization (STJ.ARECnT);
2020
2021 Analyze (Decl_ARECnPT, Suppress => All_Checks);
2022 Analyze (Decl_ARECn, Suppress => All_Checks);
2023 Analyze (Decl_ARECnP, Suppress => All_Checks);
2024
2025 if Present (Decl_Assign) then
2026 Analyze (Decl_Assign, Suppress => All_Checks);
2027 end if;
2028
2029 Pop_Scope;
2030
2031 -- Next step, for each uplevel referenced entity, add
2032 -- assignment operations to set the component in the
2033 -- activation record.
2034
2035 if Present (STJ.Uents) then
2036 declare
2037 Elmt : Elmt_Id;
2038
2039 begin
2040 Elmt := First_Elmt (STJ.Uents);
2041 while Present (Elmt) loop
2042 declare
2043 Ent : constant Entity_Id := Node (Elmt);
2044 Loc : constant Source_Ptr := Sloc (Ent);
2045 Dec : constant Node_Id :=
2046 Declaration_Node (Ent);
2047
2048 Asn : Node_Id;
2049 Attr : Name_Id;
2050 Comp : Entity_Id;
2051 Ins : Node_Id;
2052 Rhs : Node_Id;
2053
2054 begin
2055 -- For parameters, we insert the assignment
2056 -- right after the declaration of ARECnP.
2057 -- For all other entities, we insert the
2058 -- assignment immediately after the
2059 -- declaration of the entity or after the
2060 -- freeze node if present.
2061
2062 -- Note: we don't need to mark the entity
2063 -- as being aliased, because the address
2064 -- attribute will mark it as Address_Taken,
2065 -- and that is good enough.
2066
2067 if Is_Formal (Ent) then
2068 Ins := Decl_ARECnP;
2069
2070 elsif Has_Delayed_Freeze (Ent) then
2071 Ins := Freeze_Node (Ent);
2072
2073 else
2074 Ins := Dec;
2075 end if;
2076
2077 -- Build and insert the assignment:
2078 -- ARECn.nam := nam'Address
2079 -- or else 'Access for unconstrained array
2080
2081 if Needs_Fat_Pointer (Ent) then
2082 Attr := Name_Access;
2083 else
2084 Attr := Name_Address;
2085 end if;
2086
2087 Rhs :=
2088 Make_Attribute_Reference (Loc,
2089 Prefix =>
2090 New_Occurrence_Of (Ent, Loc),
2091 Attribute_Name => Attr);
2092
2093 -- If the entity is an unconstrained formal
2094 -- we wrap the attribute reference in an
2095 -- unchecked conversion to the type of the
2096 -- activation record component, to prevent
2097 -- spurious subtype conformance errors within
2098 -- instances.
2099
2100 if Is_Formal (Ent)
2101 and then not Is_Constrained (Etype (Ent))
2102 then
2103 -- Find target component and its type
2104
2105 Comp := First_Component (STJ.ARECnT);
2106 while Chars (Comp) /= Chars (Ent) loop
2107 Comp := Next_Component (Comp);
2108 end loop;
2109
2110 Rhs :=
2111 Unchecked_Convert_To (Etype (Comp), Rhs);
2112 end if;
2113
2114 Asn :=
2115 Make_Assignment_Statement (Loc,
2116 Name =>
2117 Make_Selected_Component (Loc,
2118 Prefix =>
2119 New_Occurrence_Of (STJ.ARECn, Loc),
2120 Selector_Name =>
2121 New_Occurrence_Of
2122 (Activation_Record_Component
2123 (Ent),
2124 Loc)),
2125 Expression => Rhs);
2126
2127 -- If we have a loop parameter, we have
2128 -- to insert before the first statement
2129 -- of the loop. Ins points to the
2130 -- N_Loop_Parameter_Specification or to
2131 -- an N_Iterator_Specification.
2132
2133 if Nkind_In
2134 (Ins, N_Iterator_Specification,
2135 N_Loop_Parameter_Specification)
2136 then
2137 -- Quantified expression are rewritten as
2138 -- loops during expansion.
2139
2140 if Nkind (Parent (Ins)) =
2141 N_Quantified_Expression
2142 then
2143 null;
2144
2145 else
2146 Ins :=
2147 First
2148 (Statements
2149 (Parent (Parent (Ins))));
2150 Insert_Before (Ins, Asn);
2151 end if;
2152
2153 else
2154 Insert_After (Ins, Asn);
2155 end if;
2156
2157 -- Analyze the assignment statement. We do
2158 -- not need to establish the relevant scope
2159 -- stack entries here, because we have
2160 -- already set the correct entity references,
2161 -- so no name resolution is required, and no
2162 -- new entities are created, so we don't even
2163 -- need to set the current scope.
2164
2165 -- We analyze with all checks suppressed
2166 -- (since we do not expect any exceptions).
2167
2168 Analyze (Asn, Suppress => All_Checks);
2169 end;
2170
2171 Next_Elmt (Elmt);
2172 end loop;
2173 end;
2174 end if;
2175 end;
2176 end if;
2177 end;
2178 end loop;
2179 end Subp_Loop;
2180
2181 -- Next step, process uplevel references. This has to be done in a
2182 -- separate pass, after completing the processing in Sub_Loop because we
2183 -- need all the AREC declarations generated, inserted, and analyzed so
2184 -- that the uplevel references can be successfully analyzed.
2185
2186 Uplev_Refs : for J in Urefs.First .. Urefs.Last loop
2187 declare
2188 UPJ : Uref_Entry renames Urefs.Table (J);
2189
2190 begin
2191 -- Ignore type references, these are implicit references that do
2192 -- not need rewriting (e.g. the appearence in a conversion).
2193 -- Also ignore if no reference was specified or if the rewriting
2194 -- has already been done (this can happen if the N_Identifier
2195 -- occurs more than one time in the tree). Also ignore references
2196 -- when not generating C code (in particular for the case of LLVM,
2197 -- since GNAT-LLVM will handle the processing for up-level refs).
2198
2199 if No (UPJ.Ref)
2200 or else not Is_Entity_Name (UPJ.Ref)
2201 or else not Present (Entity (UPJ.Ref))
2202 or else not Opt.Generate_C_Code
2203 then
2204 goto Continue;
2205 end if;
2206
2207 -- Rewrite one reference
2208
2209 Rewrite_One_Ref : declare
2210 Loc : constant Source_Ptr := Sloc (UPJ.Ref);
2211 -- Source location for the reference
2212
2213 Typ : constant Entity_Id := Etype (UPJ.Ent);
2214 -- The type of the referenced entity
2215
2216 Atyp : Entity_Id;
2217 -- The actual subtype of the reference
2218
2219 RS_Caller : constant SI_Type := Subp_Index (UPJ.Caller);
2220 -- Subp_Index for caller containing reference
2221
2222 STJR : Subp_Entry renames Subps.Table (RS_Caller);
2223 -- Subp_Entry for subprogram containing reference
2224
2225 RS_Callee : constant SI_Type := Subp_Index (UPJ.Callee);
2226 -- Subp_Index for subprogram containing referenced entity
2227
2228 STJE : Subp_Entry renames Subps.Table (RS_Callee);
2229 -- Subp_Entry for subprogram containing referenced entity
2230
2231 Pfx : Node_Id;
2232 Comp : Entity_Id;
2233 SI : SI_Type;
2234
2235 begin
2236 Atyp := Etype (UPJ.Ref);
2237
2238 if Ekind (Atyp) /= E_Record_Subtype then
2239 Atyp := Get_Actual_Subtype (UPJ.Ref);
2240 end if;
2241
2242 -- Ignore if no ARECnF entity for enclosing subprogram which
2243 -- probably happens as a result of not properly treating
2244 -- instance bodies. To be examined ???
2245
2246 -- If this test is omitted, then the compilation of freeze.adb
2247 -- and inline.adb fail in unnesting mode.
2248
2249 if No (STJR.ARECnF) then
2250 goto Continue;
2251 end if;
2252
2253 -- If this is a reference to a global constant, use its value
2254 -- rather than create a reference. It is more efficient and
2255 -- furthermore indispensable if the context requires a
2256 -- constant, such as a branch of a case statement.
2257
2258 if Ekind (UPJ.Ent) = E_Constant
2259 and then Is_True_Constant (UPJ.Ent)
2260 and then Present (Constant_Value (UPJ.Ent))
2261 and then Is_Static_Expression (Constant_Value (UPJ.Ent))
2262 then
2263 Rewrite (UPJ.Ref, New_Copy_Tree (Constant_Value (UPJ.Ent)));
2264 goto Continue;
2265 end if;
2266
2267 -- Push the current scope, so that the pointer type Tnn, and
2268 -- any subsidiary entities resulting from the analysis of the
2269 -- rewritten reference, go in the right entity chain.
2270
2271 Push_Scope (STJR.Ent);
2272
2273 -- Now we need to rewrite the reference. We have a reference
2274 -- from level STJR.Lev to level STJE.Lev. The general form of
2275 -- the rewritten reference for entity X is:
2276
2277 -- Typ'Deref (ARECaF.ARECbU.ARECcU.ARECdU....ARECmU.X)
2278
2279 -- where a,b,c,d .. m =
2280 -- STJR.Lev - 1, STJR.Lev - 2, .. STJE.Lev
2281
2282 pragma Assert (STJR.Lev > STJE.Lev);
2283
2284 -- Compute the prefix of X. Here are examples to make things
2285 -- clear (with parens to show groupings, the prefix is
2286 -- everything except the .X at the end).
2287
2288 -- level 2 to level 1
2289
2290 -- AREC1F.X
2291
2292 -- level 3 to level 1
2293
2294 -- (AREC2F.AREC1U).X
2295
2296 -- level 4 to level 1
2297
2298 -- ((AREC3F.AREC2U).AREC1U).X
2299
2300 -- level 6 to level 2
2301
2302 -- (((AREC5F.AREC4U).AREC3U).AREC2U).X
2303
2304 -- In the above, ARECnF and ARECnU are pointers, so there are
2305 -- explicit dereferences required for these occurrences.
2306
2307 Pfx :=
2308 Make_Explicit_Dereference (Loc,
2309 Prefix => New_Occurrence_Of (STJR.ARECnF, Loc));
2310 SI := RS_Caller;
2311 for L in STJE.Lev .. STJR.Lev - 2 loop
2312 SI := Enclosing_Subp (SI);
2313 Pfx :=
2314 Make_Explicit_Dereference (Loc,
2315 Prefix =>
2316 Make_Selected_Component (Loc,
2317 Prefix => Pfx,
2318 Selector_Name =>
2319 New_Occurrence_Of (Subps.Table (SI).ARECnU, Loc)));
2320 end loop;
2321
2322 -- Get activation record component (must exist)
2323
2324 Comp := Activation_Record_Component (UPJ.Ent);
2325 pragma Assert (Present (Comp));
2326
2327 -- Do the replacement. If the component type is an access type,
2328 -- this is an uplevel reference for an entity that requires a
2329 -- fat pointer, so dereference the component.
2330
2331 if Is_Access_Type (Etype (Comp)) then
2332 Rewrite (UPJ.Ref,
2333 Make_Explicit_Dereference (Loc,
2334 Prefix =>
2335 Make_Selected_Component (Loc,
2336 Prefix => Pfx,
2337 Selector_Name =>
2338 New_Occurrence_Of (Comp, Loc))));
2339
2340 else
2341 Rewrite (UPJ.Ref,
2342 Make_Attribute_Reference (Loc,
2343 Prefix => New_Occurrence_Of (Atyp, Loc),
2344 Attribute_Name => Name_Deref,
2345 Expressions => New_List (
2346 Make_Selected_Component (Loc,
2347 Prefix => Pfx,
2348 Selector_Name =>
2349 New_Occurrence_Of (Comp, Loc)))));
2350 end if;
2351
2352 -- Analyze and resolve the new expression. We do not need to
2353 -- establish the relevant scope stack entries here, because we
2354 -- have already set all the correct entity references, so no
2355 -- name resolution is needed. We have already set the current
2356 -- scope, so that any new entities created will be in the right
2357 -- scope.
2358
2359 -- We analyze with all checks suppressed (since we do not
2360 -- expect any exceptions)
2361
2362 Analyze_And_Resolve (UPJ.Ref, Typ, Suppress => All_Checks);
2363
2364 -- Generate an extra temporary to facilitate the C backend
2365 -- processing this dereference
2366
2367 if Opt.Modify_Tree_For_C
2368 and then Nkind_In (Parent (UPJ.Ref),
2369 N_Type_Conversion,
2370 N_Unchecked_Type_Conversion)
2371 then
2372 Force_Evaluation (UPJ.Ref, Mode => Strict);
2373 end if;
2374
2375 Pop_Scope;
2376 end Rewrite_One_Ref;
2377 end;
2378
2379 <<Continue>>
2380 null;
2381 end loop Uplev_Refs;
2382
2383 -- Finally, loop through all calls adding extra actual for the
2384 -- activation record where it is required.
2385
2386 Adjust_Calls : for J in Calls.First .. Calls.Last loop
2387
2388 -- Process a single call, we are only interested in a call to a
2389 -- subprogram that actually needs a pointer to an activation record,
2390 -- as indicated by the ARECnF entity being set. This excludes the
2391 -- top level subprogram, and any subprogram not having uplevel refs.
2392
2393 Adjust_One_Call : declare
2394 CTJ : Call_Entry renames Calls.Table (J);
2395 STF : Subp_Entry renames Subps.Table (Subp_Index (CTJ.Caller));
2396 STT : Subp_Entry renames Subps.Table (Subp_Index (CTJ.Callee));
2397
2398 Loc : constant Source_Ptr := Sloc (CTJ.N);
2399
2400 Extra : Node_Id;
2401 ExtraP : Node_Id;
2402 SubX : SI_Type;
2403 Act : Node_Id;
2404
2405 begin
2406 if Present (STT.ARECnF)
2407 and then Nkind (CTJ.N) in N_Subprogram_Call
2408 then
2409 -- CTJ.N is a call to a subprogram which may require a pointer
2410 -- to an activation record. The subprogram containing the call
2411 -- is CTJ.From and the subprogram being called is CTJ.To, so we
2412 -- have a call from level STF.Lev to level STT.Lev.
2413
2414 -- There are three possibilities:
2415
2416 -- For a call to the same level, we just pass the activation
2417 -- record passed to the calling subprogram.
2418
2419 if STF.Lev = STT.Lev then
2420 Extra := New_Occurrence_Of (STF.ARECnF, Loc);
2421
2422 -- For a call that goes down a level, we pass a pointer to the
2423 -- activation record constructed within the caller (which may
2424 -- be the outer-level subprogram, but also may be a more deeply
2425 -- nested caller).
2426
2427 elsif STT.Lev = STF.Lev + 1 then
2428 Extra := New_Occurrence_Of (STF.ARECnP, Loc);
2429
2430 -- Otherwise we must have an upcall (STT.Lev < STF.LEV),
2431 -- since it is not possible to do a downcall of more than
2432 -- one level.
2433
2434 -- For a call from level STF.Lev to level STT.Lev, we
2435 -- have to find the activation record needed by the
2436 -- callee. This is as follows:
2437
2438 -- ARECaF.ARECbU.ARECcU....ARECmU
2439
2440 -- where a,b,c .. m =
2441 -- STF.Lev - 1, STF.Lev - 2, STF.Lev - 3 .. STT.Lev
2442
2443 else
2444 pragma Assert (STT.Lev < STF.Lev);
2445
2446 Extra := New_Occurrence_Of (STF.ARECnF, Loc);
2447 SubX := Subp_Index (CTJ.Caller);
2448 for K in reverse STT.Lev .. STF.Lev - 1 loop
2449 SubX := Enclosing_Subp (SubX);
2450 Extra :=
2451 Make_Selected_Component (Loc,
2452 Prefix => Extra,
2453 Selector_Name =>
2454 New_Occurrence_Of
2455 (Subps.Table (SubX).ARECnU, Loc));
2456 end loop;
2457 end if;
2458
2459 -- Extra is the additional parameter to be added. Build a
2460 -- parameter association that we can append to the actuals.
2461
2462 ExtraP :=
2463 Make_Parameter_Association (Loc,
2464 Selector_Name =>
2465 New_Occurrence_Of (STT.ARECnF, Loc),
2466 Explicit_Actual_Parameter => Extra);
2467
2468 if No (Parameter_Associations (CTJ.N)) then
2469 Set_Parameter_Associations (CTJ.N, Empty_List);
2470 end if;
2471
2472 Append (ExtraP, Parameter_Associations (CTJ.N));
2473
2474 -- We need to deal with the actual parameter chain as well. The
2475 -- newly added parameter is always the last actual.
2476
2477 Act := First_Named_Actual (CTJ.N);
2478
2479 if No (Act) then
2480 Set_First_Named_Actual (CTJ.N, Extra);
2481
2482 -- If call has been relocated (as with an expression in
2483 -- an aggregate), set First_Named pointer in original node
2484 -- as well, because that's the parent of the parameter list.
2485
2486 Set_First_Named_Actual
2487 (Parent (List_Containing (ExtraP)), Extra);
2488
2489 -- Here we must follow the chain and append the new entry
2490
2491 else
2492 loop
2493 declare
2494 PAN : Node_Id;
2495 NNA : Node_Id;
2496
2497 begin
2498 PAN := Parent (Act);
2499 pragma Assert (Nkind (PAN) = N_Parameter_Association);
2500 NNA := Next_Named_Actual (PAN);
2501
2502 if No (NNA) then
2503 Set_Next_Named_Actual (PAN, Extra);
2504 exit;
2505 end if;
2506
2507 Act := NNA;
2508 end;
2509 end loop;
2510 end if;
2511
2512 -- Analyze and resolve the new actual. We do not need to
2513 -- establish the relevant scope stack entries here, because
2514 -- we have already set all the correct entity references, so
2515 -- no name resolution is needed.
2516
2517 -- We analyze with all checks suppressed (since we do not
2518 -- expect any exceptions, and also we temporarily turn off
2519 -- Unested_Subprogram_Mode to avoid trying to mark uplevel
2520 -- references (not needed at this stage, and in fact causes
2521 -- a bit of recursive chaos).
2522
2523 Opt.Unnest_Subprogram_Mode := False;
2524 Analyze_And_Resolve
2525 (Extra, Etype (STT.ARECnF), Suppress => All_Checks);
2526 Opt.Unnest_Subprogram_Mode := True;
2527 end if;
2528 end Adjust_One_Call;
2529 end loop Adjust_Calls;
2530
2531 return;
2532 end Unnest_Subprogram;
2533
2534 ------------------------
2535 -- Unnest_Subprograms --
2536 ------------------------
2537
2538 procedure Unnest_Subprograms (N : Node_Id) is
2539 function Search_Subprograms (N : Node_Id) return Traverse_Result;
2540 -- Tree visitor that search for outer level procedures with nested
2541 -- subprograms and invokes Unnest_Subprogram()
2542
2543 ---------------
2544 -- Do_Search --
2545 ---------------
2546
2547 procedure Do_Search is new Traverse_Proc (Search_Subprograms);
2548 -- Subtree visitor instantiation
2549
2550 ------------------------
2551 -- Search_Subprograms --
2552 ------------------------
2553
2554 function Search_Subprograms (N : Node_Id) return Traverse_Result is
2555 begin
2556 if Nkind_In (N, N_Subprogram_Body, N_Subprogram_Body_Stub) then
2557 declare
2558 Spec_Id : constant Entity_Id := Unique_Defining_Entity (N);
2559
2560 begin
2561 -- We are only interested in subprograms (not generic
2562 -- subprograms), that have nested subprograms.
2563
2564 if Is_Subprogram (Spec_Id)
2565 and then Has_Nested_Subprogram (Spec_Id)
2566 and then Is_Library_Level_Entity (Spec_Id)
2567 then
2568 Unnest_Subprogram (Spec_Id, N);
2569 end if;
2570 end;
2571
2572 -- The proper body of a stub may contain nested subprograms, and
2573 -- therefore must be visited explicitly. Nested stubs are examined
2574 -- recursively in Visit_Node.
2575
2576 elsif Nkind (N) in N_Body_Stub then
2577 Do_Search (Library_Unit (N));
2578
2579 -- Skip generic packages
2580
2581 elsif Nkind (N) = N_Package_Body
2582 and then Ekind (Corresponding_Spec (N)) = E_Generic_Package
2583 then
2584 return Skip;
2585 end if;
2586
2587 return OK;
2588 end Search_Subprograms;
2589
2590 Subp : Entity_Id;
2591 Subp_Body : Node_Id;
2592
2593 -- Start of processing for Unnest_Subprograms
2594
2595 begin
2596 if not Opt.Unnest_Subprogram_Mode or not Opt.Expander_Active then
2597 return;
2598 end if;
2599
2600 -- A specification will contain bodies if it contains instantiations so
2601 -- examine package or subprogram declaration of the main unit, when it
2602 -- is present.
2603
2604 if Nkind (Unit (N)) = N_Package_Body
2605 or else (Nkind (Unit (N)) = N_Subprogram_Body
2606 and then not Acts_As_Spec (N))
2607 then
2608 Do_Search (Library_Unit (N));
2609 end if;
2610
2611 Do_Search (N);
2612
2613 -- Unnest any subprograms passed on the list of inlined subprograms
2614
2615 Subp := First_Inlined_Subprogram (N);
2616
2617 while Present (Subp) loop
2618 Subp_Body := Parent (Declaration_Node (Subp));
2619
2620 if Nkind (Subp_Body) = N_Subprogram_Declaration
2621 and then Present (Corresponding_Body (Subp_Body))
2622 then
2623 Subp_Body := Parent (Declaration_Node
2624 (Corresponding_Body (Subp_Body)));
2625 end if;
2626
2627 Unnest_Subprogram (Subp, Subp_Body, For_Inline => True);
2628 Next_Inlined_Subprogram (Subp);
2629 end loop;
2630 end Unnest_Subprograms;
2631
2632 end Exp_Unst;