annotate gcc/ada/exp_unst.adb @ 158:494b0b89df80 default tip

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