]>
Commit | Line | Data |
---|---|---|
07fc65c4 | 1 | ------------------------------------------------------------------------------ |
996ae0b0 RK |
2 | -- -- |
3 | -- GNAT COMPILER COMPONENTS -- | |
4 | -- -- | |
5 | -- S E M _ U T I L -- | |
6 | -- -- | |
7 | -- B o d y -- | |
8 | -- -- | |
e3c4580e | 9 | -- Copyright (C) 1992-2011, Free Software Foundation, Inc. -- |
996ae0b0 RK |
10 | -- -- |
11 | -- GNAT is free software; you can redistribute it and/or modify it under -- | |
bd434b3f | 12 | -- terms of the GNU General Public License as published by the Free Soft- -- |
b5c84c3c | 13 | -- ware Foundation; either version 3, or (at your option) any later ver- -- |
996ae0b0 RK |
14 | -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- |
15 | -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- | |
16 | -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- | |
17 | -- for more details. You should have received a copy of the GNU General -- | |
b5c84c3c RD |
18 | -- Public License distributed with GNAT; see file COPYING3. If not, go to -- |
19 | -- http://www.gnu.org/licenses for a complete copy of the license. -- | |
996ae0b0 RK |
20 | -- -- |
21 | -- GNAT was originally developed by the GNAT team at New York University. -- | |
71ff80dc | 22 | -- Extensive contributions were provided by Ada Core Technologies Inc. -- |
996ae0b0 RK |
23 | -- -- |
24 | ------------------------------------------------------------------------------ | |
25 | ||
26 | with Atree; use Atree; | |
27 | with Casing; use Casing; | |
fbf5a39b | 28 | with Checks; use Checks; |
996ae0b0 RK |
29 | with Debug; use Debug; |
30 | with Errout; use Errout; | |
31 | with Elists; use Elists; | |
3f92c93b | 32 | with Exp_Ch11; use Exp_Ch11; |
ce2b6ba5 | 33 | with Exp_Disp; use Exp_Disp; |
996ae0b0 | 34 | with Exp_Util; use Exp_Util; |
fbf5a39b | 35 | with Fname; use Fname; |
996ae0b0 RK |
36 | with Freeze; use Freeze; |
37 | with Lib; use Lib; | |
38 | with Lib.Xref; use Lib.Xref; | |
996ae0b0 | 39 | with Nlists; use Nlists; |
996ae0b0 RK |
40 | with Output; use Output; |
41 | with Opt; use Opt; | |
bd65a2d7 | 42 | with Restrict; use Restrict; |
23685ae6 | 43 | with Rident; use Rident; |
5453d5bd | 44 | with Rtsfind; use Rtsfind; |
996ae0b0 | 45 | with Sem; use Sem; |
a4100e55 | 46 | with Sem_Aux; use Sem_Aux; |
f377c995 | 47 | with Sem_Attr; use Sem_Attr; |
996ae0b0 | 48 | with Sem_Ch8; use Sem_Ch8; |
4755cce9 | 49 | with Sem_Disp; use Sem_Disp; |
996ae0b0 RK |
50 | with Sem_Eval; use Sem_Eval; |
51 | with Sem_Res; use Sem_Res; | |
52 | with Sem_Type; use Sem_Type; | |
53 | with Sinfo; use Sinfo; | |
54 | with Sinput; use Sinput; | |
996ae0b0 RK |
55 | with Stand; use Stand; |
56 | with Style; | |
57 | with Stringt; use Stringt; | |
e771c085 | 58 | with Table; |
996ae0b0 RK |
59 | with Targparm; use Targparm; |
60 | with Tbuild; use Tbuild; | |
61 | with Ttypes; use Ttypes; | |
1735e55d | 62 | with Uname; use Uname; |
996ae0b0 | 63 | |
f3b01cd9 | 64 | with GNAT.HTable; use GNAT.HTable; |
7c4b480f | 65 | |
996ae0b0 RK |
66 | package body Sem_Util is |
67 | ||
f3b01cd9 AC |
68 | ---------------------------------------- |
69 | -- Global_Variables for New_Copy_Tree -- | |
70 | ---------------------------------------- | |
71 | ||
72 | -- These global variables are used by New_Copy_Tree. See description | |
73 | -- of the body of this subprogram for details. Global variables can be | |
74 | -- safely used by New_Copy_Tree, since there is no case of a recursive | |
75 | -- call from the processing inside New_Copy_Tree. | |
76 | ||
308e6f3a | 77 | NCT_Hash_Threshold : constant := 20; |
f3b01cd9 AC |
78 | -- If there are more than this number of pairs of entries in the |
79 | -- map, then Hash_Tables_Used will be set, and the hash tables will | |
80 | -- be initialized and used for the searches. | |
81 | ||
82 | NCT_Hash_Tables_Used : Boolean := False; | |
83 | -- Set to True if hash tables are in use | |
84 | ||
85 | NCT_Table_Entries : Nat; | |
308e6f3a | 86 | -- Count entries in table to see if threshold is reached |
f3b01cd9 AC |
87 | |
88 | NCT_Hash_Table_Setup : Boolean := False; | |
89 | -- Set to True if hash table contains data. We set this True if we | |
90 | -- setup the hash table with data, and leave it set permanently | |
91 | -- from then on, this is a signal that second and subsequent users | |
92 | -- of the hash table must clear the old entries before reuse. | |
93 | ||
94 | subtype NCT_Header_Num is Int range 0 .. 511; | |
95 | -- Defines range of headers in hash tables (512 headers) | |
96 | ||
7c4b480f AC |
97 | ---------------------------------- |
98 | -- Order Dependence (AI05-0144) -- | |
99 | ---------------------------------- | |
e771c085 | 100 | |
7c4b480f AC |
101 | -- Each actual in a call is entered into the table below. A flag indicates |
102 | -- whether the corresponding formal is OUT or IN OUT. Each top-level call | |
103 | -- (procedure call, condition, assignment) examines all the actuals for a | |
104 | -- possible order dependence. The table is reset after each such check. | |
1e194575 AC |
105 | -- The actuals to be checked in a call to Check_Order_Dependence are at |
106 | -- positions 1 .. Last. | |
e771c085 AC |
107 | |
108 | type Actual_Name is record | |
7c4b480f | 109 | Act : Node_Id; |
e771c085 AC |
110 | Is_Writable : Boolean; |
111 | end record; | |
112 | ||
113 | package Actuals_In_Call is new Table.Table ( | |
114 | Table_Component_Type => Actual_Name, | |
115 | Table_Index_Type => Int, | |
116 | Table_Low_Bound => 0, | |
117 | Table_Initial => 10, | |
87dc09cb | 118 | Table_Increment => 100, |
e771c085 AC |
119 | Table_Name => "Actuals"); |
120 | ||
996ae0b0 RK |
121 | ----------------------- |
122 | -- Local Subprograms -- | |
123 | ----------------------- | |
124 | ||
125 | function Build_Component_Subtype | |
fbf5a39b AC |
126 | (C : List_Id; |
127 | Loc : Source_Ptr; | |
128 | T : Entity_Id) return Node_Id; | |
996ae0b0 RK |
129 | -- This function builds the subtype for Build_Actual_Subtype_Of_Component |
130 | -- and Build_Discriminal_Subtype_Of_Component. C is a list of constraints, | |
131 | -- Loc is the source location, T is the original subtype. | |
132 | ||
fbf5a39b AC |
133 | function Is_Fully_Initialized_Variant (Typ : Entity_Id) return Boolean; |
134 | -- Subsidiary to Is_Fully_Initialized_Type. For an unconstrained type | |
135 | -- with discriminants whose default values are static, examine only the | |
136 | -- components in the selected variant to determine whether all of them | |
137 | -- have a default. | |
138 | ||
139 | function Has_Null_Extension (T : Entity_Id) return Boolean; | |
140 | -- T is a derived tagged type. Check whether the type extension is null. | |
141 | -- If the parent type is fully initialized, T can be treated as such. | |
142 | ||
9e87a68d ES |
143 | ------------------------------ |
144 | -- Abstract_Interface_List -- | |
145 | ------------------------------ | |
146 | ||
147 | function Abstract_Interface_List (Typ : Entity_Id) return List_Id is | |
148 | Nod : Node_Id; | |
149 | ||
150 | begin | |
151 | if Is_Concurrent_Type (Typ) then | |
1b6c95c4 RD |
152 | |
153 | -- If we are dealing with a synchronized subtype, go to the base | |
154 | -- type, whose declaration has the interface list. | |
155 | ||
156 | -- Shouldn't this be Declaration_Node??? | |
157 | ||
158 | Nod := Parent (Base_Type (Typ)); | |
9e87a68d | 159 | |
26ff8ede JM |
160 | if Nkind (Nod) = N_Full_Type_Declaration then |
161 | return Empty_List; | |
162 | end if; | |
163 | ||
9e87a68d ES |
164 | elsif Ekind (Typ) = E_Record_Type_With_Private then |
165 | if Nkind (Parent (Typ)) = N_Full_Type_Declaration then | |
166 | Nod := Type_Definition (Parent (Typ)); | |
167 | ||
168 | elsif Nkind (Parent (Typ)) = N_Private_Type_Declaration then | |
d8b3ccb9 AC |
169 | if Present (Full_View (Typ)) |
170 | and then Nkind (Parent (Full_View (Typ))) | |
171 | = N_Full_Type_Declaration | |
172 | then | |
9e87a68d ES |
173 | Nod := Type_Definition (Parent (Full_View (Typ))); |
174 | ||
31b5873d GD |
175 | -- If the full-view is not available we cannot do anything else |
176 | -- here (the source has errors). | |
9e87a68d ES |
177 | |
178 | else | |
179 | return Empty_List; | |
180 | end if; | |
181 | ||
31b5873d | 182 | -- Support for generic formals with interfaces is still missing ??? |
9e87a68d ES |
183 | |
184 | elsif Nkind (Parent (Typ)) = N_Formal_Type_Declaration then | |
185 | return Empty_List; | |
186 | ||
187 | else | |
188 | pragma Assert | |
189 | (Nkind (Parent (Typ)) = N_Private_Extension_Declaration); | |
190 | Nod := Parent (Typ); | |
191 | end if; | |
192 | ||
193 | elsif Ekind (Typ) = E_Record_Subtype then | |
194 | Nod := Type_Definition (Parent (Etype (Typ))); | |
195 | ||
f377c995 HK |
196 | elsif Ekind (Typ) = E_Record_Subtype_With_Private then |
197 | ||
7f0e4cdb BD |
198 | -- Recurse, because parent may still be a private extension. Also |
199 | -- note that the full view of the subtype or the full view of its | |
200 | -- base type may (both) be unavailable. | |
f377c995 | 201 | |
7f0e4cdb | 202 | return Abstract_Interface_List (Etype (Typ)); |
f377c995 | 203 | |
9e87a68d ES |
204 | else pragma Assert ((Ekind (Typ)) = E_Record_Type); |
205 | if Nkind (Parent (Typ)) = N_Formal_Type_Declaration then | |
206 | Nod := Formal_Type_Definition (Parent (Typ)); | |
207 | else | |
208 | Nod := Type_Definition (Parent (Typ)); | |
209 | end if; | |
210 | end if; | |
211 | ||
212 | return Interface_List (Nod); | |
213 | end Abstract_Interface_List; | |
214 | ||
996ae0b0 RK |
215 | -------------------------------- |
216 | -- Add_Access_Type_To_Process -- | |
217 | -------------------------------- | |
218 | ||
fbf5a39b | 219 | procedure Add_Access_Type_To_Process (E : Entity_Id; A : Entity_Id) is |
996ae0b0 | 220 | L : Elist_Id; |
fbf5a39b | 221 | |
996ae0b0 RK |
222 | begin |
223 | Ensure_Freeze_Node (E); | |
224 | L := Access_Types_To_Process (Freeze_Node (E)); | |
225 | ||
226 | if No (L) then | |
227 | L := New_Elmt_List; | |
228 | Set_Access_Types_To_Process (Freeze_Node (E), L); | |
229 | end if; | |
230 | ||
231 | Append_Elmt (A, L); | |
232 | end Add_Access_Type_To_Process; | |
233 | ||
f377c995 HK |
234 | ---------------------------- |
235 | -- Add_Global_Declaration -- | |
236 | ---------------------------- | |
237 | ||
238 | procedure Add_Global_Declaration (N : Node_Id) is | |
239 | Aux_Node : constant Node_Id := Aux_Decls_Node (Cunit (Current_Sem_Unit)); | |
240 | ||
241 | begin | |
242 | if No (Declarations (Aux_Node)) then | |
243 | Set_Declarations (Aux_Node, New_List); | |
244 | end if; | |
245 | ||
246 | Append_To (Declarations (Aux_Node), N); | |
247 | Analyze (N); | |
248 | end Add_Global_Declaration; | |
249 | ||
094cefda AC |
250 | ----------------- |
251 | -- Addressable -- | |
252 | ----------------- | |
253 | ||
254 | -- For now, just 8/16/32/64. but analyze later if AAMP is special??? | |
255 | ||
256 | function Addressable (V : Uint) return Boolean is | |
257 | begin | |
258 | return V = Uint_8 or else | |
259 | V = Uint_16 or else | |
260 | V = Uint_32 or else | |
261 | V = Uint_64; | |
262 | end Addressable; | |
263 | ||
264 | function Addressable (V : Int) return Boolean is | |
265 | begin | |
266 | return V = 8 or else | |
267 | V = 16 or else | |
268 | V = 32 or else | |
269 | V = 64; | |
270 | end Addressable; | |
271 | ||
996ae0b0 RK |
272 | ----------------------- |
273 | -- Alignment_In_Bits -- | |
274 | ----------------------- | |
275 | ||
276 | function Alignment_In_Bits (E : Entity_Id) return Uint is | |
277 | begin | |
278 | return Alignment (E) * System_Storage_Unit; | |
279 | end Alignment_In_Bits; | |
280 | ||
281 | ----------------------------------------- | |
282 | -- Apply_Compile_Time_Constraint_Error -- | |
283 | ----------------------------------------- | |
284 | ||
285 | procedure Apply_Compile_Time_Constraint_Error | |
07fc65c4 GB |
286 | (N : Node_Id; |
287 | Msg : String; | |
288 | Reason : RT_Exception_Code; | |
289 | Ent : Entity_Id := Empty; | |
290 | Typ : Entity_Id := Empty; | |
291 | Loc : Source_Ptr := No_Location; | |
fbf5a39b AC |
292 | Rep : Boolean := True; |
293 | Warn : Boolean := False) | |
996ae0b0 | 294 | is |
ce4a6e84 RD |
295 | Stat : constant Boolean := Is_Static_Expression (N); |
296 | R_Stat : constant Node_Id := | |
297 | Make_Raise_Constraint_Error (Sloc (N), Reason => Reason); | |
298 | Rtyp : Entity_Id; | |
996ae0b0 RK |
299 | |
300 | begin | |
301 | if No (Typ) then | |
302 | Rtyp := Etype (N); | |
303 | else | |
304 | Rtyp := Typ; | |
305 | end if; | |
306 | ||
b8dc622e JM |
307 | Discard_Node |
308 | (Compile_Time_Constraint_Error (N, Msg, Ent, Loc, Warn => Warn)); | |
5950a3ac AC |
309 | |
310 | if not Rep then | |
996ae0b0 RK |
311 | return; |
312 | end if; | |
313 | ||
314 | -- Now we replace the node by an N_Raise_Constraint_Error node | |
315 | -- This does not need reanalyzing, so set it as analyzed now. | |
316 | ||
ce4a6e84 | 317 | Rewrite (N, R_Stat); |
996ae0b0 | 318 | Set_Analyzed (N, True); |
ce4a6e84 | 319 | |
996ae0b0 RK |
320 | Set_Etype (N, Rtyp); |
321 | Set_Raises_Constraint_Error (N); | |
322 | ||
3f92c93b AC |
323 | -- Now deal with possible local raise handling |
324 | ||
325 | Possible_Local_Raise (N, Standard_Constraint_Error); | |
326 | ||
996ae0b0 RK |
327 | -- If the original expression was marked as static, the result is |
328 | -- still marked as static, but the Raises_Constraint_Error flag is | |
329 | -- always set so that further static evaluation is not attempted. | |
330 | ||
331 | if Stat then | |
332 | Set_Is_Static_Expression (N); | |
333 | end if; | |
334 | end Apply_Compile_Time_Constraint_Error; | |
335 | ||
86200f66 RD |
336 | -------------------------------- |
337 | -- Bad_Predicated_Subtype_Use -- | |
338 | -------------------------------- | |
339 | ||
340 | procedure Bad_Predicated_Subtype_Use | |
ed00f472 | 341 | (Msg : String; |
86200f66 | 342 | N : Node_Id; |
ed00f472 | 343 | Typ : Entity_Id) |
86200f66 RD |
344 | is |
345 | begin | |
346 | if Has_Predicates (Typ) then | |
347 | if Is_Generic_Actual_Type (Typ) then | |
ed00f472 RD |
348 | Error_Msg_FE (Msg & '?', N, Typ); |
349 | Error_Msg_F ("\Program_Error will be raised at run time?", N); | |
86200f66 RD |
350 | Insert_Action (N, |
351 | Make_Raise_Program_Error (Sloc (N), | |
352 | Reason => PE_Bad_Predicated_Generic_Type)); | |
353 | ||
354 | else | |
ed00f472 | 355 | Error_Msg_FE (Msg, N, Typ); |
86200f66 RD |
356 | end if; |
357 | end if; | |
358 | end Bad_Predicated_Subtype_Use; | |
359 | ||
996ae0b0 RK |
360 | -------------------------- |
361 | -- Build_Actual_Subtype -- | |
362 | -------------------------- | |
363 | ||
364 | function Build_Actual_Subtype | |
fbf5a39b AC |
365 | (T : Entity_Id; |
366 | N : Node_Or_Entity_Id) return Node_Id | |
996ae0b0 | 367 | is |
1b6c95c4 RD |
368 | Loc : Source_Ptr; |
369 | -- Normally Sloc (N), but may point to corresponding body in some cases | |
370 | ||
996ae0b0 RK |
371 | Constraints : List_Id; |
372 | Decl : Node_Id; | |
373 | Discr : Entity_Id; | |
374 | Hi : Node_Id; | |
375 | Lo : Node_Id; | |
376 | Subt : Entity_Id; | |
377 | Disc_Type : Entity_Id; | |
9b0986f8 | 378 | Obj : Node_Id; |
996ae0b0 RK |
379 | |
380 | begin | |
1b6c95c4 RD |
381 | Loc := Sloc (N); |
382 | ||
996ae0b0 RK |
383 | if Nkind (N) = N_Defining_Identifier then |
384 | Obj := New_Reference_To (N, Loc); | |
1b6c95c4 RD |
385 | |
386 | -- If this is a formal parameter of a subprogram declaration, and | |
387 | -- we are compiling the body, we want the declaration for the | |
388 | -- actual subtype to carry the source position of the body, to | |
389 | -- prevent anomalies in gdb when stepping through the code. | |
390 | ||
391 | if Is_Formal (N) then | |
392 | declare | |
393 | Decl : constant Node_Id := Unit_Declaration_Node (Scope (N)); | |
394 | begin | |
395 | if Nkind (Decl) = N_Subprogram_Declaration | |
396 | and then Present (Corresponding_Body (Decl)) | |
397 | then | |
398 | Loc := Sloc (Corresponding_Body (Decl)); | |
399 | end if; | |
400 | end; | |
401 | end if; | |
402 | ||
996ae0b0 RK |
403 | else |
404 | Obj := N; | |
405 | end if; | |
406 | ||
407 | if Is_Array_Type (T) then | |
408 | Constraints := New_List; | |
996ae0b0 RK |
409 | for J in 1 .. Number_Dimensions (T) loop |
410 | ||
9b0986f8 RD |
411 | -- Build an array subtype declaration with the nominal subtype and |
412 | -- the bounds of the actual. Add the declaration in front of the | |
413 | -- local declarations for the subprogram, for analysis before any | |
414 | -- reference to the formal in the body. | |
996ae0b0 RK |
415 | |
416 | Lo := | |
417 | Make_Attribute_Reference (Loc, | |
8cbb664e MG |
418 | Prefix => |
419 | Duplicate_Subexpr_No_Checks (Obj, Name_Req => True), | |
996ae0b0 RK |
420 | Attribute_Name => Name_First, |
421 | Expressions => New_List ( | |
422 | Make_Integer_Literal (Loc, J))); | |
423 | ||
424 | Hi := | |
425 | Make_Attribute_Reference (Loc, | |
8cbb664e MG |
426 | Prefix => |
427 | Duplicate_Subexpr_No_Checks (Obj, Name_Req => True), | |
996ae0b0 RK |
428 | Attribute_Name => Name_Last, |
429 | Expressions => New_List ( | |
430 | Make_Integer_Literal (Loc, J))); | |
431 | ||
432 | Append (Make_Range (Loc, Lo, Hi), Constraints); | |
433 | end loop; | |
434 | ||
435 | -- If the type has unknown discriminants there is no constrained | |
fbf5a39b AC |
436 | -- subtype to build. This is never called for a formal or for a |
437 | -- lhs, so returning the type is ok ??? | |
996ae0b0 RK |
438 | |
439 | elsif Has_Unknown_Discriminants (T) then | |
440 | return T; | |
441 | ||
442 | else | |
443 | Constraints := New_List; | |
444 | ||
7f0e4cdb BD |
445 | -- Type T is a generic derived type, inherit the discriminants from |
446 | -- the parent type. | |
447 | ||
448 | if Is_Private_Type (T) | |
449 | and then No (Full_View (T)) | |
996ae0b0 | 450 | |
7f0e4cdb BD |
451 | -- T was flagged as an error if it was declared as a formal |
452 | -- derived type with known discriminants. In this case there | |
453 | -- is no need to look at the parent type since T already carries | |
454 | -- its own discriminants. | |
996ae0b0 | 455 | |
7f0e4cdb BD |
456 | and then not Error_Posted (T) |
457 | then | |
996ae0b0 RK |
458 | Disc_Type := Etype (Base_Type (T)); |
459 | else | |
460 | Disc_Type := T; | |
461 | end if; | |
462 | ||
463 | Discr := First_Discriminant (Disc_Type); | |
996ae0b0 RK |
464 | while Present (Discr) loop |
465 | Append_To (Constraints, | |
466 | Make_Selected_Component (Loc, | |
8cbb664e MG |
467 | Prefix => |
468 | Duplicate_Subexpr_No_Checks (Obj), | |
996ae0b0 RK |
469 | Selector_Name => New_Occurrence_Of (Discr, Loc))); |
470 | Next_Discriminant (Discr); | |
471 | end loop; | |
472 | end if; | |
473 | ||
cf49bd32 | 474 | Subt := Make_Temporary (Loc, 'S', Related_Node => N); |
996ae0b0 RK |
475 | Set_Is_Internal (Subt); |
476 | ||
477 | Decl := | |
478 | Make_Subtype_Declaration (Loc, | |
479 | Defining_Identifier => Subt, | |
480 | Subtype_Indication => | |
481 | Make_Subtype_Indication (Loc, | |
482 | Subtype_Mark => New_Reference_To (T, Loc), | |
483 | Constraint => | |
484 | Make_Index_Or_Discriminant_Constraint (Loc, | |
485 | Constraints => Constraints))); | |
486 | ||
487 | Mark_Rewrite_Insertion (Decl); | |
488 | return Decl; | |
489 | end Build_Actual_Subtype; | |
490 | ||
491 | --------------------------------------- | |
492 | -- Build_Actual_Subtype_Of_Component -- | |
493 | --------------------------------------- | |
494 | ||
495 | function Build_Actual_Subtype_Of_Component | |
fbf5a39b AC |
496 | (T : Entity_Id; |
497 | N : Node_Id) return Node_Id | |
996ae0b0 RK |
498 | is |
499 | Loc : constant Source_Ptr := Sloc (N); | |
500 | P : constant Node_Id := Prefix (N); | |
501 | D : Elmt_Id; | |
502 | Id : Node_Id; | |
df3e68b1 | 503 | Index_Typ : Entity_Id; |
996ae0b0 | 504 | |
df3e68b1 | 505 | Desig_Typ : Entity_Id; |
996ae0b0 RK |
506 | -- This is either a copy of T, or if T is an access type, then it is |
507 | -- the directly designated type of this access type. | |
508 | ||
509 | function Build_Actual_Array_Constraint return List_Id; | |
510 | -- If one or more of the bounds of the component depends on | |
511 | -- discriminants, build actual constraint using the discriminants | |
512 | -- of the prefix. | |
513 | ||
514 | function Build_Actual_Record_Constraint return List_Id; | |
515 | -- Similar to previous one, for discriminated components constrained | |
516 | -- by the discriminant of the enclosing object. | |
517 | ||
518 | ----------------------------------- | |
519 | -- Build_Actual_Array_Constraint -- | |
520 | ----------------------------------- | |
521 | ||
522 | function Build_Actual_Array_Constraint return List_Id is | |
fbf5a39b | 523 | Constraints : constant List_Id := New_List; |
996ae0b0 RK |
524 | Indx : Node_Id; |
525 | Hi : Node_Id; | |
526 | Lo : Node_Id; | |
527 | Old_Hi : Node_Id; | |
528 | Old_Lo : Node_Id; | |
529 | ||
530 | begin | |
df3e68b1 | 531 | Indx := First_Index (Desig_Typ); |
996ae0b0 RK |
532 | while Present (Indx) loop |
533 | Old_Lo := Type_Low_Bound (Etype (Indx)); | |
534 | Old_Hi := Type_High_Bound (Etype (Indx)); | |
535 | ||
536 | if Denotes_Discriminant (Old_Lo) then | |
537 | Lo := | |
538 | Make_Selected_Component (Loc, | |
539 | Prefix => New_Copy_Tree (P), | |
540 | Selector_Name => New_Occurrence_Of (Entity (Old_Lo), Loc)); | |
541 | ||
542 | else | |
543 | Lo := New_Copy_Tree (Old_Lo); | |
544 | ||
545 | -- The new bound will be reanalyzed in the enclosing | |
546 | -- declaration. For literal bounds that come from a type | |
547 | -- declaration, the type of the context must be imposed, so | |
548 | -- insure that analysis will take place. For non-universal | |
549 | -- types this is not strictly necessary. | |
550 | ||
551 | Set_Analyzed (Lo, False); | |
552 | end if; | |
553 | ||
554 | if Denotes_Discriminant (Old_Hi) then | |
555 | Hi := | |
556 | Make_Selected_Component (Loc, | |
557 | Prefix => New_Copy_Tree (P), | |
558 | Selector_Name => New_Occurrence_Of (Entity (Old_Hi), Loc)); | |
559 | ||
560 | else | |
561 | Hi := New_Copy_Tree (Old_Hi); | |
562 | Set_Analyzed (Hi, False); | |
563 | end if; | |
564 | ||
565 | Append (Make_Range (Loc, Lo, Hi), Constraints); | |
566 | Next_Index (Indx); | |
567 | end loop; | |
568 | ||
569 | return Constraints; | |
570 | end Build_Actual_Array_Constraint; | |
571 | ||
572 | ------------------------------------ | |
573 | -- Build_Actual_Record_Constraint -- | |
574 | ------------------------------------ | |
575 | ||
576 | function Build_Actual_Record_Constraint return List_Id is | |
fbf5a39b | 577 | Constraints : constant List_Id := New_List; |
996ae0b0 RK |
578 | D : Elmt_Id; |
579 | D_Val : Node_Id; | |
580 | ||
581 | begin | |
df3e68b1 | 582 | D := First_Elmt (Discriminant_Constraint (Desig_Typ)); |
996ae0b0 | 583 | while Present (D) loop |
996ae0b0 RK |
584 | if Denotes_Discriminant (Node (D)) then |
585 | D_Val := Make_Selected_Component (Loc, | |
586 | Prefix => New_Copy_Tree (P), | |
587 | Selector_Name => New_Occurrence_Of (Entity (Node (D)), Loc)); | |
588 | ||
589 | else | |
590 | D_Val := New_Copy_Tree (Node (D)); | |
591 | end if; | |
592 | ||
593 | Append (D_Val, Constraints); | |
594 | Next_Elmt (D); | |
595 | end loop; | |
596 | ||
597 | return Constraints; | |
598 | end Build_Actual_Record_Constraint; | |
599 | ||
600 | -- Start of processing for Build_Actual_Subtype_Of_Component | |
601 | ||
602 | begin | |
ce4a6e84 RD |
603 | -- Why the test for Spec_Expression mode here??? |
604 | ||
605 | if In_Spec_Expression then | |
fbf5a39b AC |
606 | return Empty; |
607 | ||
f3d0f304 | 608 | -- More comments for the rest of this body would be good ??? |
ce4a6e84 | 609 | |
fbf5a39b | 610 | elsif Nkind (N) = N_Explicit_Dereference then |
996ae0b0 RK |
611 | if Is_Composite_Type (T) |
612 | and then not Is_Constrained (T) | |
613 | and then not (Is_Class_Wide_Type (T) | |
614 | and then Is_Constrained (Root_Type (T))) | |
615 | and then not Has_Unknown_Discriminants (T) | |
616 | then | |
a50d5785 AC |
617 | -- If the type of the dereference is already constrained, it is an |
618 | -- actual subtype. | |
996ae0b0 RK |
619 | |
620 | if Is_Array_Type (Etype (N)) | |
621 | and then Is_Constrained (Etype (N)) | |
622 | then | |
623 | return Empty; | |
624 | else | |
625 | Remove_Side_Effects (P); | |
626 | return Build_Actual_Subtype (T, N); | |
627 | end if; | |
628 | else | |
629 | return Empty; | |
630 | end if; | |
631 | end if; | |
632 | ||
633 | if Ekind (T) = E_Access_Subtype then | |
df3e68b1 | 634 | Desig_Typ := Designated_Type (T); |
996ae0b0 | 635 | else |
df3e68b1 | 636 | Desig_Typ := T; |
996ae0b0 RK |
637 | end if; |
638 | ||
df3e68b1 HK |
639 | if Ekind (Desig_Typ) = E_Array_Subtype then |
640 | Id := First_Index (Desig_Typ); | |
996ae0b0 | 641 | while Present (Id) loop |
df3e68b1 | 642 | Index_Typ := Underlying_Type (Etype (Id)); |
996ae0b0 | 643 | |
df3e68b1 | 644 | if Denotes_Discriminant (Type_Low_Bound (Index_Typ)) |
7f0e4cdb | 645 | or else |
df3e68b1 | 646 | Denotes_Discriminant (Type_High_Bound (Index_Typ)) |
996ae0b0 RK |
647 | then |
648 | Remove_Side_Effects (P); | |
649 | return | |
7f0e4cdb BD |
650 | Build_Component_Subtype |
651 | (Build_Actual_Array_Constraint, Loc, Base_Type (T)); | |
996ae0b0 RK |
652 | end if; |
653 | ||
654 | Next_Index (Id); | |
655 | end loop; | |
656 | ||
df3e68b1 HK |
657 | elsif Is_Composite_Type (Desig_Typ) |
658 | and then Has_Discriminants (Desig_Typ) | |
659 | and then not Has_Unknown_Discriminants (Desig_Typ) | |
996ae0b0 | 660 | then |
df3e68b1 HK |
661 | if Is_Private_Type (Desig_Typ) |
662 | and then No (Discriminant_Constraint (Desig_Typ)) | |
663 | then | |
664 | Desig_Typ := Full_View (Desig_Typ); | |
665 | end if; | |
666 | ||
667 | D := First_Elmt (Discriminant_Constraint (Desig_Typ)); | |
996ae0b0 | 668 | while Present (D) loop |
996ae0b0 RK |
669 | if Denotes_Discriminant (Node (D)) then |
670 | Remove_Side_Effects (P); | |
671 | return | |
672 | Build_Component_Subtype ( | |
673 | Build_Actual_Record_Constraint, Loc, Base_Type (T)); | |
674 | end if; | |
675 | ||
676 | Next_Elmt (D); | |
677 | end loop; | |
678 | end if; | |
679 | ||
130c236a | 680 | -- If none of the above, the actual and nominal subtypes are the same |
996ae0b0 RK |
681 | |
682 | return Empty; | |
996ae0b0 RK |
683 | end Build_Actual_Subtype_Of_Component; |
684 | ||
685 | ----------------------------- | |
686 | -- Build_Component_Subtype -- | |
687 | ----------------------------- | |
688 | ||
689 | function Build_Component_Subtype | |
fbf5a39b AC |
690 | (C : List_Id; |
691 | Loc : Source_Ptr; | |
692 | T : Entity_Id) return Node_Id | |
996ae0b0 RK |
693 | is |
694 | Subt : Entity_Id; | |
695 | Decl : Node_Id; | |
696 | ||
697 | begin | |
5d09245e AC |
698 | -- Unchecked_Union components do not require component subtypes |
699 | ||
700 | if Is_Unchecked_Union (T) then | |
701 | return Empty; | |
702 | end if; | |
703 | ||
092ef350 | 704 | Subt := Make_Temporary (Loc, 'S'); |
996ae0b0 RK |
705 | Set_Is_Internal (Subt); |
706 | ||
707 | Decl := | |
708 | Make_Subtype_Declaration (Loc, | |
709 | Defining_Identifier => Subt, | |
710 | Subtype_Indication => | |
711 | Make_Subtype_Indication (Loc, | |
712 | Subtype_Mark => New_Reference_To (Base_Type (T), Loc), | |
713 | Constraint => | |
714 | Make_Index_Or_Discriminant_Constraint (Loc, | |
715 | Constraints => C))); | |
716 | ||
717 | Mark_Rewrite_Insertion (Decl); | |
718 | return Decl; | |
719 | end Build_Component_Subtype; | |
720 | ||
9b0986f8 RD |
721 | --------------------------- |
722 | -- Build_Default_Subtype -- | |
723 | --------------------------- | |
724 | ||
725 | function Build_Default_Subtype | |
726 | (T : Entity_Id; | |
727 | N : Node_Id) return Entity_Id | |
728 | is | |
729 | Loc : constant Source_Ptr := Sloc (N); | |
730 | Disc : Entity_Id; | |
731 | ||
732 | begin | |
733 | if not Has_Discriminants (T) or else Is_Constrained (T) then | |
734 | return T; | |
735 | end if; | |
736 | ||
737 | Disc := First_Discriminant (T); | |
738 | ||
739 | if No (Discriminant_Default_Value (Disc)) then | |
740 | return T; | |
741 | end if; | |
742 | ||
743 | declare | |
092ef350 | 744 | Act : constant Entity_Id := Make_Temporary (Loc, 'S'); |
9b0986f8 RD |
745 | Constraints : constant List_Id := New_List; |
746 | Decl : Node_Id; | |
747 | ||
748 | begin | |
749 | while Present (Disc) loop | |
750 | Append_To (Constraints, | |
751 | New_Copy_Tree (Discriminant_Default_Value (Disc))); | |
752 | Next_Discriminant (Disc); | |
753 | end loop; | |
754 | ||
755 | Decl := | |
756 | Make_Subtype_Declaration (Loc, | |
757 | Defining_Identifier => Act, | |
758 | Subtype_Indication => | |
759 | Make_Subtype_Indication (Loc, | |
760 | Subtype_Mark => New_Occurrence_Of (T, Loc), | |
761 | Constraint => | |
762 | Make_Index_Or_Discriminant_Constraint (Loc, | |
763 | Constraints => Constraints))); | |
764 | ||
765 | Insert_Action (N, Decl); | |
766 | Analyze (Decl); | |
767 | return Act; | |
768 | end; | |
769 | end Build_Default_Subtype; | |
770 | ||
996ae0b0 RK |
771 | -------------------------------------------- |
772 | -- Build_Discriminal_Subtype_Of_Component -- | |
773 | -------------------------------------------- | |
774 | ||
775 | function Build_Discriminal_Subtype_Of_Component | |
fbf5a39b | 776 | (T : Entity_Id) return Node_Id |
996ae0b0 RK |
777 | is |
778 | Loc : constant Source_Ptr := Sloc (T); | |
779 | D : Elmt_Id; | |
780 | Id : Node_Id; | |
781 | ||
782 | function Build_Discriminal_Array_Constraint return List_Id; | |
783 | -- If one or more of the bounds of the component depends on | |
784 | -- discriminants, build actual constraint using the discriminants | |
785 | -- of the prefix. | |
786 | ||
787 | function Build_Discriminal_Record_Constraint return List_Id; | |
788 | -- Similar to previous one, for discriminated components constrained | |
789 | -- by the discriminant of the enclosing object. | |
790 | ||
791 | ---------------------------------------- | |
792 | -- Build_Discriminal_Array_Constraint -- | |
793 | ---------------------------------------- | |
794 | ||
795 | function Build_Discriminal_Array_Constraint return List_Id is | |
fbf5a39b | 796 | Constraints : constant List_Id := New_List; |
996ae0b0 RK |
797 | Indx : Node_Id; |
798 | Hi : Node_Id; | |
799 | Lo : Node_Id; | |
800 | Old_Hi : Node_Id; | |
801 | Old_Lo : Node_Id; | |
802 | ||
803 | begin | |
804 | Indx := First_Index (T); | |
805 | while Present (Indx) loop | |
806 | Old_Lo := Type_Low_Bound (Etype (Indx)); | |
807 | Old_Hi := Type_High_Bound (Etype (Indx)); | |
808 | ||
809 | if Denotes_Discriminant (Old_Lo) then | |
810 | Lo := New_Occurrence_Of (Discriminal (Entity (Old_Lo)), Loc); | |
811 | ||
812 | else | |
813 | Lo := New_Copy_Tree (Old_Lo); | |
814 | end if; | |
815 | ||
816 | if Denotes_Discriminant (Old_Hi) then | |
817 | Hi := New_Occurrence_Of (Discriminal (Entity (Old_Hi)), Loc); | |
818 | ||
819 | else | |
820 | Hi := New_Copy_Tree (Old_Hi); | |
821 | end if; | |
822 | ||
823 | Append (Make_Range (Loc, Lo, Hi), Constraints); | |
824 | Next_Index (Indx); | |
825 | end loop; | |
826 | ||
827 | return Constraints; | |
828 | end Build_Discriminal_Array_Constraint; | |
829 | ||
830 | ----------------------------------------- | |
831 | -- Build_Discriminal_Record_Constraint -- | |
832 | ----------------------------------------- | |
833 | ||
834 | function Build_Discriminal_Record_Constraint return List_Id is | |
fbf5a39b AC |
835 | Constraints : constant List_Id := New_List; |
836 | D : Elmt_Id; | |
837 | D_Val : Node_Id; | |
996ae0b0 RK |
838 | |
839 | begin | |
840 | D := First_Elmt (Discriminant_Constraint (T)); | |
841 | while Present (D) loop | |
996ae0b0 RK |
842 | if Denotes_Discriminant (Node (D)) then |
843 | D_Val := | |
844 | New_Occurrence_Of (Discriminal (Entity (Node (D))), Loc); | |
845 | ||
846 | else | |
847 | D_Val := New_Copy_Tree (Node (D)); | |
848 | end if; | |
849 | ||
850 | Append (D_Val, Constraints); | |
851 | Next_Elmt (D); | |
852 | end loop; | |
853 | ||
854 | return Constraints; | |
855 | end Build_Discriminal_Record_Constraint; | |
856 | ||
857 | -- Start of processing for Build_Discriminal_Subtype_Of_Component | |
858 | ||
859 | begin | |
860 | if Ekind (T) = E_Array_Subtype then | |
996ae0b0 | 861 | Id := First_Index (T); |
996ae0b0 | 862 | while Present (Id) loop |
996ae0b0 RK |
863 | if Denotes_Discriminant (Type_Low_Bound (Etype (Id))) or else |
864 | Denotes_Discriminant (Type_High_Bound (Etype (Id))) | |
865 | then | |
866 | return Build_Component_Subtype | |
867 | (Build_Discriminal_Array_Constraint, Loc, T); | |
868 | end if; | |
869 | ||
870 | Next_Index (Id); | |
871 | end loop; | |
872 | ||
873 | elsif Ekind (T) = E_Record_Subtype | |
874 | and then Has_Discriminants (T) | |
875 | and then not Has_Unknown_Discriminants (T) | |
876 | then | |
877 | D := First_Elmt (Discriminant_Constraint (T)); | |
878 | while Present (D) loop | |
996ae0b0 RK |
879 | if Denotes_Discriminant (Node (D)) then |
880 | return Build_Component_Subtype | |
881 | (Build_Discriminal_Record_Constraint, Loc, T); | |
882 | end if; | |
883 | ||
884 | Next_Elmt (D); | |
885 | end loop; | |
886 | end if; | |
887 | ||
130c236a | 888 | -- If none of the above, the actual and nominal subtypes are the same |
996ae0b0 RK |
889 | |
890 | return Empty; | |
996ae0b0 RK |
891 | end Build_Discriminal_Subtype_Of_Component; |
892 | ||
893 | ------------------------------ | |
894 | -- Build_Elaboration_Entity -- | |
895 | ------------------------------ | |
896 | ||
897 | procedure Build_Elaboration_Entity (N : Node_Id; Spec_Id : Entity_Id) is | |
f377c995 HK |
898 | Loc : constant Source_Ptr := Sloc (N); |
899 | Decl : Node_Id; | |
900 | Elab_Ent : Entity_Id; | |
901 | ||
902 | procedure Set_Package_Name (Ent : Entity_Id); | |
903 | -- Given an entity, sets the fully qualified name of the entity in | |
904 | -- Name_Buffer, with components separated by double underscores. This | |
905 | -- is a recursive routine that climbs the scope chain to Standard. | |
906 | ||
907 | ---------------------- | |
908 | -- Set_Package_Name -- | |
909 | ---------------------- | |
910 | ||
911 | procedure Set_Package_Name (Ent : Entity_Id) is | |
912 | begin | |
913 | if Scope (Ent) /= Standard_Standard then | |
914 | Set_Package_Name (Scope (Ent)); | |
915 | ||
916 | declare | |
917 | Nam : constant String := Get_Name_String (Chars (Ent)); | |
918 | begin | |
919 | Name_Buffer (Name_Len + 1) := '_'; | |
920 | Name_Buffer (Name_Len + 2) := '_'; | |
921 | Name_Buffer (Name_Len + 3 .. Name_Len + Nam'Length + 2) := Nam; | |
922 | Name_Len := Name_Len + Nam'Length + 2; | |
923 | end; | |
924 | ||
925 | else | |
926 | Get_Name_String (Chars (Ent)); | |
927 | end if; | |
928 | end Set_Package_Name; | |
929 | ||
930 | -- Start of processing for Build_Elaboration_Entity | |
996ae0b0 RK |
931 | |
932 | begin | |
933 | -- Ignore if already constructed | |
934 | ||
935 | if Present (Elaboration_Entity (Spec_Id)) then | |
936 | return; | |
937 | end if; | |
938 | ||
f377c995 HK |
939 | -- Construct name of elaboration entity as xxx_E, where xxx is the unit |
940 | -- name with dots replaced by double underscore. We have to manually | |
941 | -- construct this name, since it will be elaborated in the outer scope, | |
942 | -- and thus will not have the unit name automatically prepended. | |
996ae0b0 | 943 | |
f377c995 | 944 | Set_Package_Name (Spec_Id); |
996ae0b0 | 945 | |
f377c995 | 946 | -- Append _E |
996ae0b0 | 947 | |
f377c995 HK |
948 | Name_Buffer (Name_Len + 1) := '_'; |
949 | Name_Buffer (Name_Len + 2) := 'E'; | |
950 | Name_Len := Name_Len + 2; | |
996ae0b0 | 951 | |
01f0729a | 952 | -- Create elaboration counter |
996ae0b0 | 953 | |
2c1b72d7 | 954 | Elab_Ent := Make_Defining_Identifier (Loc, Chars => Name_Find); |
996ae0b0 RK |
955 | Set_Elaboration_Entity (Spec_Id, Elab_Ent); |
956 | ||
996ae0b0 | 957 | Decl := |
2c1b72d7 AC |
958 | Make_Object_Declaration (Loc, |
959 | Defining_Identifier => Elab_Ent, | |
01f0729a AC |
960 | Object_Definition => |
961 | New_Occurrence_Of (Standard_Short_Integer, Loc), | |
cfae2bed | 962 | Expression => Make_Integer_Literal (Loc, Uint_0)); |
996ae0b0 | 963 | |
f377c995 HK |
964 | Push_Scope (Standard_Standard); |
965 | Add_Global_Declaration (Decl); | |
966 | Pop_Scope; | |
996ae0b0 | 967 | |
9b0986f8 RD |
968 | -- Reset True_Constant indication, since we will indeed assign a value |
969 | -- to the variable in the binder main. We also kill the Current_Value | |
970 | -- and Last_Assignment fields for the same reason. | |
996ae0b0 RK |
971 | |
972 | Set_Is_True_Constant (Elab_Ent, False); | |
fbf5a39b | 973 | Set_Current_Value (Elab_Ent, Empty); |
9b0986f8 | 974 | Set_Last_Assignment (Elab_Ent, Empty); |
996ae0b0 RK |
975 | |
976 | -- We do not want any further qualification of the name (if we did | |
977 | -- not do this, we would pick up the name of the generic package | |
978 | -- in the case of a library level generic instantiation). | |
979 | ||
980 | Set_Has_Qualified_Name (Elab_Ent); | |
981 | Set_Has_Fully_Qualified_Name (Elab_Ent); | |
982 | end Build_Elaboration_Entity; | |
983 | ||
3e24afaa AC |
984 | -------------------------------- |
985 | -- Build_Explicit_Dereference -- | |
986 | -------------------------------- | |
987 | ||
988 | procedure Build_Explicit_Dereference | |
989 | (Expr : Node_Id; | |
990 | Disc : Entity_Id) | |
991 | is | |
992 | Loc : constant Source_Ptr := Sloc (Expr); | |
3e24afaa AC |
993 | begin |
994 | Set_Is_Overloaded (Expr, False); | |
995 | Rewrite (Expr, | |
996 | Make_Explicit_Dereference (Loc, | |
997 | Prefix => | |
998 | Make_Selected_Component (Loc, | |
690943fc RD |
999 | Prefix => Relocate_Node (Expr), |
1000 | Selector_Name => New_Occurrence_Of (Disc, Loc)))); | |
3e24afaa AC |
1001 | Set_Etype (Prefix (Expr), Etype (Disc)); |
1002 | Set_Etype (Expr, Designated_Type (Etype (Disc))); | |
1003 | end Build_Explicit_Dereference; | |
1004 | ||
07fc65c4 GB |
1005 | ----------------------------------- |
1006 | -- Cannot_Raise_Constraint_Error -- | |
1007 | ----------------------------------- | |
1008 | ||
1009 | function Cannot_Raise_Constraint_Error (Expr : Node_Id) return Boolean is | |
1010 | begin | |
1011 | if Compile_Time_Known_Value (Expr) then | |
1012 | return True; | |
1013 | ||
1014 | elsif Do_Range_Check (Expr) then | |
1015 | return False; | |
1016 | ||
1017 | elsif Raises_Constraint_Error (Expr) then | |
1018 | return False; | |
1019 | ||
1020 | else | |
1021 | case Nkind (Expr) is | |
1022 | when N_Identifier => | |
1023 | return True; | |
1024 | ||
1025 | when N_Expanded_Name => | |
1026 | return True; | |
1027 | ||
1028 | when N_Selected_Component => | |
1029 | return not Do_Discriminant_Check (Expr); | |
1030 | ||
1031 | when N_Attribute_Reference => | |
fbf5a39b | 1032 | if Do_Overflow_Check (Expr) then |
07fc65c4 GB |
1033 | return False; |
1034 | ||
1035 | elsif No (Expressions (Expr)) then | |
1036 | return True; | |
1037 | ||
1038 | else | |
1039 | declare | |
9b0986f8 | 1040 | N : Node_Id; |
07fc65c4 GB |
1041 | |
1042 | begin | |
9b0986f8 | 1043 | N := First (Expressions (Expr)); |
07fc65c4 GB |
1044 | while Present (N) loop |
1045 | if Cannot_Raise_Constraint_Error (N) then | |
1046 | Next (N); | |
1047 | else | |
1048 | return False; | |
1049 | end if; | |
1050 | end loop; | |
1051 | ||
1052 | return True; | |
1053 | end; | |
1054 | end if; | |
1055 | ||
1056 | when N_Type_Conversion => | |
1057 | if Do_Overflow_Check (Expr) | |
1058 | or else Do_Length_Check (Expr) | |
1059 | or else Do_Tag_Check (Expr) | |
1060 | then | |
1061 | return False; | |
1062 | else | |
1063 | return | |
1064 | Cannot_Raise_Constraint_Error (Expression (Expr)); | |
1065 | end if; | |
1066 | ||
1067 | when N_Unchecked_Type_Conversion => | |
1068 | return Cannot_Raise_Constraint_Error (Expression (Expr)); | |
1069 | ||
1070 | when N_Unary_Op => | |
1071 | if Do_Overflow_Check (Expr) then | |
1072 | return False; | |
1073 | else | |
1074 | return | |
1075 | Cannot_Raise_Constraint_Error (Right_Opnd (Expr)); | |
1076 | end if; | |
1077 | ||
1078 | when N_Op_Divide | | |
1079 | N_Op_Mod | | |
1080 | N_Op_Rem | |
1081 | => | |
1082 | if Do_Division_Check (Expr) | |
1083 | or else Do_Overflow_Check (Expr) | |
1084 | then | |
1085 | return False; | |
1086 | else | |
1087 | return | |
1088 | Cannot_Raise_Constraint_Error (Left_Opnd (Expr)) | |
1089 | and then | |
1090 | Cannot_Raise_Constraint_Error (Right_Opnd (Expr)); | |
1091 | end if; | |
1092 | ||
1093 | when N_Op_Add | | |
1094 | N_Op_And | | |
1095 | N_Op_Concat | | |
1096 | N_Op_Eq | | |
1097 | N_Op_Expon | | |
1098 | N_Op_Ge | | |
1099 | N_Op_Gt | | |
1100 | N_Op_Le | | |
1101 | N_Op_Lt | | |
1102 | N_Op_Multiply | | |
1103 | N_Op_Ne | | |
1104 | N_Op_Or | | |
1105 | N_Op_Rotate_Left | | |
1106 | N_Op_Rotate_Right | | |
1107 | N_Op_Shift_Left | | |
1108 | N_Op_Shift_Right | | |
1109 | N_Op_Shift_Right_Arithmetic | | |
1110 | N_Op_Subtract | | |
1111 | N_Op_Xor | |
1112 | => | |
1113 | if Do_Overflow_Check (Expr) then | |
1114 | return False; | |
1115 | else | |
1116 | return | |
1117 | Cannot_Raise_Constraint_Error (Left_Opnd (Expr)) | |
1118 | and then | |
1119 | Cannot_Raise_Constraint_Error (Right_Opnd (Expr)); | |
1120 | end if; | |
1121 | ||
1122 | when others => | |
1123 | return False; | |
1124 | end case; | |
1125 | end if; | |
1126 | end Cannot_Raise_Constraint_Error; | |
1127 | ||
44a10091 AC |
1128 | -------------------------------- |
1129 | -- Check_Implicit_Dereference -- | |
1130 | -------------------------------- | |
1131 | ||
1132 | procedure Check_Implicit_Dereference (Nam : Node_Id; Typ : Entity_Id) | |
1133 | is | |
1134 | Disc : Entity_Id; | |
1135 | Desig : Entity_Id; | |
1136 | ||
1137 | begin | |
1138 | if Ada_Version < Ada_2012 | |
1139 | or else not Has_Implicit_Dereference (Base_Type (Typ)) | |
1140 | then | |
1141 | return; | |
1142 | ||
1143 | elsif not Comes_From_Source (Nam) then | |
1144 | return; | |
1145 | ||
1146 | elsif Is_Entity_Name (Nam) | |
1147 | and then Is_Type (Entity (Nam)) | |
1148 | then | |
1149 | null; | |
1150 | ||
1151 | else | |
1152 | Disc := First_Discriminant (Typ); | |
1153 | while Present (Disc) loop | |
1154 | if Has_Implicit_Dereference (Disc) then | |
1155 | Desig := Designated_Type (Etype (Disc)); | |
1156 | Add_One_Interp (Nam, Disc, Desig); | |
1157 | exit; | |
1158 | end if; | |
1159 | ||
1160 | Next_Discriminant (Disc); | |
1161 | end loop; | |
1162 | end if; | |
1163 | end Check_Implicit_Dereference; | |
1164 | ||
23685ae6 AC |
1165 | --------------------------------------- |
1166 | -- Check_Later_Vs_Basic_Declarations -- | |
1167 | --------------------------------------- | |
1168 | ||
1169 | procedure Check_Later_Vs_Basic_Declarations | |
1170 | (Decls : List_Id; | |
1171 | During_Parsing : Boolean) | |
1172 | is | |
1173 | Body_Sloc : Source_Ptr; | |
1174 | Decl : Node_Id; | |
db72f10a AC |
1175 | |
1176 | function Is_Later_Declarative_Item (Decl : Node_Id) return Boolean; | |
1177 | -- Return whether Decl is considered as a declarative item. | |
1178 | -- When During_Parsing is True, the semantics of Ada 83 is followed. | |
1179 | -- When During_Parsing is False, the semantics of SPARK is followed. | |
1180 | ||
1181 | ------------------------------- | |
1182 | -- Is_Later_Declarative_Item -- | |
1183 | ------------------------------- | |
1184 | ||
1185 | function Is_Later_Declarative_Item (Decl : Node_Id) return Boolean is | |
1186 | begin | |
1187 | if Nkind (Decl) in N_Later_Decl_Item then | |
1188 | return True; | |
1189 | ||
1190 | elsif Nkind (Decl) = N_Pragma then | |
1191 | return True; | |
1192 | ||
1193 | elsif During_Parsing then | |
1194 | return False; | |
1195 | ||
1196 | -- In SPARK, a package declaration is not considered as a later | |
1197 | -- declarative item. | |
1198 | ||
1199 | elsif Nkind (Decl) = N_Package_Declaration then | |
1200 | return False; | |
1201 | ||
1202 | -- In SPARK, a renaming is considered as a later declarative item | |
1203 | ||
1204 | elsif Nkind (Decl) in N_Renaming_Declaration then | |
1205 | return True; | |
1206 | ||
1207 | else | |
1208 | return False; | |
1209 | end if; | |
1210 | end Is_Later_Declarative_Item; | |
1211 | ||
1212 | -- Start of Check_Later_Vs_Basic_Declarations | |
1213 | ||
23685ae6 AC |
1214 | begin |
1215 | Decl := First (Decls); | |
1216 | ||
1217 | -- Loop through sequence of basic declarative items | |
1218 | ||
1219 | Outer : while Present (Decl) loop | |
1220 | if Nkind (Decl) /= N_Subprogram_Body | |
1221 | and then Nkind (Decl) /= N_Package_Body | |
1222 | and then Nkind (Decl) /= N_Task_Body | |
1223 | and then Nkind (Decl) not in N_Body_Stub | |
1224 | then | |
1225 | Next (Decl); | |
1226 | ||
1227 | -- Once a body is encountered, we only allow later declarative | |
1228 | -- items. The inner loop checks the rest of the list. | |
1229 | ||
1230 | else | |
1231 | Body_Sloc := Sloc (Decl); | |
1232 | ||
1233 | Inner : while Present (Decl) loop | |
db72f10a | 1234 | if not Is_Later_Declarative_Item (Decl) then |
23685ae6 AC |
1235 | if During_Parsing then |
1236 | if Ada_Version = Ada_83 then | |
1237 | Error_Msg_Sloc := Body_Sloc; | |
1238 | Error_Msg_N | |
1239 | ("(Ada 83) decl cannot appear after body#", Decl); | |
1240 | end if; | |
1241 | else | |
1242 | Error_Msg_Sloc := Body_Sloc; | |
2ba431e5 | 1243 | Check_SPARK_Restriction |
23685ae6 AC |
1244 | ("decl cannot appear after body#", Decl); |
1245 | end if; | |
1246 | end if; | |
1247 | ||
1248 | Next (Decl); | |
1249 | end loop Inner; | |
1250 | end if; | |
1251 | end loop Outer; | |
1252 | end Check_Later_Vs_Basic_Declarations; | |
1253 | ||
4755cce9 JM |
1254 | ----------------------------------------- |
1255 | -- Check_Dynamically_Tagged_Expression -- | |
1256 | ----------------------------------------- | |
1257 | ||
1258 | procedure Check_Dynamically_Tagged_Expression | |
1259 | (Expr : Node_Id; | |
1260 | Typ : Entity_Id; | |
1261 | Related_Nod : Node_Id) | |
1262 | is | |
1263 | begin | |
1264 | pragma Assert (Is_Tagged_Type (Typ)); | |
1265 | ||
9d0c3761 | 1266 | -- In order to avoid spurious errors when analyzing the expanded code, |
f6256631 | 1267 | -- this check is done only for nodes that come from source and for |
9d0c3761 | 1268 | -- actuals of generic instantiations. |
f6256631 AC |
1269 | |
1270 | if (Comes_From_Source (Related_Nod) | |
1271 | or else In_Generic_Actual (Expr)) | |
4755cce9 JM |
1272 | and then (Is_Class_Wide_Type (Etype (Expr)) |
1273 | or else Is_Dynamically_Tagged (Expr)) | |
1274 | and then Is_Tagged_Type (Typ) | |
1275 | and then not Is_Class_Wide_Type (Typ) | |
1276 | then | |
1277 | Error_Msg_N ("dynamically tagged expression not allowed!", Expr); | |
1278 | end if; | |
1279 | end Check_Dynamically_Tagged_Expression; | |
1280 | ||
996ae0b0 RK |
1281 | -------------------------- |
1282 | -- Check_Fully_Declared -- | |
1283 | -------------------------- | |
1284 | ||
1285 | procedure Check_Fully_Declared (T : Entity_Id; N : Node_Id) is | |
1286 | begin | |
1287 | if Ekind (T) = E_Incomplete_Type then | |
fbf5a39b | 1288 | |
0ab80019 | 1289 | -- Ada 2005 (AI-50217): If the type is available through a limited |
19f0526a | 1290 | -- with_clause, verify that its full view has been analyzed. |
fbf5a39b AC |
1291 | |
1292 | if From_With_Type (T) | |
1293 | and then Present (Non_Limited_View (T)) | |
1294 | and then Ekind (Non_Limited_View (T)) /= E_Incomplete_Type | |
1295 | then | |
1296 | -- The non-limited view is fully declared | |
1297 | null; | |
1298 | ||
1299 | else | |
1300 | Error_Msg_NE | |
1301 | ("premature usage of incomplete}", N, First_Subtype (T)); | |
1302 | end if; | |
996ae0b0 | 1303 | |
ce4a6e84 RD |
1304 | -- Need comments for these tests ??? |
1305 | ||
996ae0b0 RK |
1306 | elsif Has_Private_Component (T) |
1307 | and then not Is_Generic_Type (Root_Type (T)) | |
ce4a6e84 | 1308 | and then not In_Spec_Expression |
996ae0b0 | 1309 | then |
fbf5a39b AC |
1310 | -- Special case: if T is the anonymous type created for a single |
1311 | -- task or protected object, use the name of the source object. | |
1312 | ||
1313 | if Is_Concurrent_Type (T) | |
1314 | and then not Comes_From_Source (T) | |
1315 | and then Nkind (N) = N_Object_Declaration | |
1316 | then | |
1317 | Error_Msg_NE ("type of& has incomplete component", N, | |
1318 | Defining_Identifier (N)); | |
1319 | ||
1320 | else | |
1321 | Error_Msg_NE | |
1322 | ("premature usage of incomplete}", N, First_Subtype (T)); | |
1323 | end if; | |
996ae0b0 RK |
1324 | end if; |
1325 | end Check_Fully_Declared; | |
1326 | ||
f377c995 HK |
1327 | ------------------------- |
1328 | -- Check_Nested_Access -- | |
1329 | ------------------------- | |
1330 | ||
1331 | procedure Check_Nested_Access (Ent : Entity_Id) is | |
1332 | Scop : constant Entity_Id := Current_Scope; | |
1333 | Current_Subp : Entity_Id; | |
7f0e4cdb | 1334 | Enclosing : Entity_Id; |
f377c995 HK |
1335 | |
1336 | begin | |
1337 | -- Currently only enabled for VM back-ends for efficiency, should we | |
1338 | -- enable it more systematically ??? | |
1339 | ||
ce4a6e84 RD |
1340 | -- Check for Is_Imported needs commenting below ??? |
1341 | ||
f377c995 HK |
1342 | if VM_Target /= No_VM |
1343 | and then (Ekind (Ent) = E_Variable | |
1344 | or else | |
1345 | Ekind (Ent) = E_Constant | |
1346 | or else | |
1347 | Ekind (Ent) = E_Loop_Parameter) | |
1348 | and then Scope (Ent) /= Empty | |
1349 | and then not Is_Library_Level_Entity (Ent) | |
ce4a6e84 | 1350 | and then not Is_Imported (Ent) |
f377c995 HK |
1351 | then |
1352 | if Is_Subprogram (Scop) | |
1353 | or else Is_Generic_Subprogram (Scop) | |
1354 | or else Is_Entry (Scop) | |
1355 | then | |
1356 | Current_Subp := Scop; | |
1357 | else | |
1358 | Current_Subp := Current_Subprogram; | |
1359 | end if; | |
1360 | ||
7f0e4cdb BD |
1361 | Enclosing := Enclosing_Subprogram (Ent); |
1362 | ||
1363 | if Enclosing /= Empty | |
1364 | and then Enclosing /= Current_Subp | |
1365 | then | |
f377c995 HK |
1366 | Set_Has_Up_Level_Access (Ent, True); |
1367 | end if; | |
1368 | end if; | |
1369 | end Check_Nested_Access; | |
1370 | ||
7c4b480f AC |
1371 | ---------------------------- |
1372 | -- Check_Order_Dependence -- | |
1373 | ---------------------------- | |
1374 | ||
1375 | procedure Check_Order_Dependence is | |
87dc09cb AC |
1376 | Act1 : Node_Id; |
1377 | Act2 : Node_Id; | |
1378 | ||
7c4b480f | 1379 | begin |
1e194575 AC |
1380 | if Ada_Version < Ada_2012 then |
1381 | return; | |
1382 | end if; | |
87dc09cb | 1383 | |
9b20e59b | 1384 | -- Ada 2012 AI05-0144-2: Dangerous order dependence. Actuals in nested |
66150d01 AC |
1385 | -- calls within a construct have been collected. If one of them is |
1386 | -- writable and overlaps with another one, evaluation of the enclosing | |
1387 | -- construct is nondeterministic. This is illegal in Ada 2012, but is | |
1388 | -- treated as a warning for now. | |
1e194575 AC |
1389 | |
1390 | for J in 1 .. Actuals_In_Call.Last loop | |
7c4b480f AC |
1391 | if Actuals_In_Call.Table (J).Is_Writable then |
1392 | Act1 := Actuals_In_Call.Table (J).Act; | |
1393 | ||
1394 | if Nkind (Act1) = N_Attribute_Reference then | |
1395 | Act1 := Prefix (Act1); | |
1396 | end if; | |
1397 | ||
1e194575 | 1398 | for K in 1 .. Actuals_In_Call.Last loop |
7c4b480f AC |
1399 | if K /= J then |
1400 | Act2 := Actuals_In_Call.Table (K).Act; | |
87dc09cb | 1401 | |
7c4b480f AC |
1402 | if Nkind (Act2) = N_Attribute_Reference then |
1403 | Act2 := Prefix (Act2); | |
1404 | end if; | |
1405 | ||
1406 | if Actuals_In_Call.Table (K).Is_Writable | |
1407 | and then K < J | |
1408 | then | |
1409 | -- Already checked | |
1410 | ||
1411 | null; | |
1412 | ||
1413 | elsif Denotes_Same_Object (Act1, Act2) | |
1e194575 | 1414 | and then Parent (Act1) /= Parent (Act2) |
7c4b480f | 1415 | then |
66150d01 AC |
1416 | Error_Msg_N |
1417 | ("result may differ if evaluated " | |
1418 | & "after other actual in expression?", Act1); | |
7c4b480f AC |
1419 | end if; |
1420 | end if; | |
1421 | end loop; | |
1422 | end if; | |
1423 | end loop; | |
1424 | ||
66150d01 | 1425 | -- Remove checked actuals from table |
1e194575 | 1426 | |
7c4b480f AC |
1427 | Actuals_In_Call.Set_Last (0); |
1428 | end Check_Order_Dependence; | |
1429 | ||
996ae0b0 RK |
1430 | ------------------------------------------ |
1431 | -- Check_Potentially_Blocking_Operation -- | |
1432 | ------------------------------------------ | |
1433 | ||
1434 | procedure Check_Potentially_Blocking_Operation (N : Node_Id) is | |
f377c995 | 1435 | S : Entity_Id; |
f6b5dc8e | 1436 | |
996ae0b0 | 1437 | begin |
c885d7a1 AC |
1438 | -- N is one of the potentially blocking operations listed in 9.5.1(8). |
1439 | -- When pragma Detect_Blocking is active, the run time will raise | |
1440 | -- Program_Error. Here we only issue a warning, since we generally | |
1441 | -- support the use of potentially blocking operations in the absence | |
1442 | -- of the pragma. | |
996ae0b0 | 1443 | |
c885d7a1 AC |
1444 | -- Indirect blocking through a subprogram call cannot be diagnosed |
1445 | -- statically without interprocedural analysis, so we do not attempt | |
1446 | -- to do it here. | |
996ae0b0 | 1447 | |
c885d7a1 | 1448 | S := Scope (Current_Scope); |
996ae0b0 RK |
1449 | while Present (S) and then S /= Standard_Standard loop |
1450 | if Is_Protected_Type (S) then | |
c885d7a1 AC |
1451 | Error_Msg_N |
1452 | ("potentially blocking operation in protected operation?", N); | |
996ae0b0 RK |
1453 | return; |
1454 | end if; | |
1455 | ||
1456 | S := Scope (S); | |
1457 | end loop; | |
1458 | end Check_Potentially_Blocking_Operation; | |
1459 | ||
ce4a6e84 RD |
1460 | ------------------------------ |
1461 | -- Check_Unprotected_Access -- | |
1462 | ------------------------------ | |
1463 | ||
1464 | procedure Check_Unprotected_Access | |
1465 | (Context : Node_Id; | |
1466 | Expr : Node_Id) | |
1467 | is | |
1468 | Cont_Encl_Typ : Entity_Id; | |
1469 | Pref_Encl_Typ : Entity_Id; | |
1470 | ||
1471 | function Enclosing_Protected_Type (Obj : Node_Id) return Entity_Id; | |
1472 | -- Check whether Obj is a private component of a protected object. | |
1473 | -- Return the protected type where the component resides, Empty | |
1474 | -- otherwise. | |
1475 | ||
1476 | function Is_Public_Operation return Boolean; | |
1477 | -- Verify that the enclosing operation is callable from outside the | |
1478 | -- protected object, to minimize false positives. | |
1479 | ||
1480 | ------------------------------ | |
1481 | -- Enclosing_Protected_Type -- | |
1482 | ------------------------------ | |
1483 | ||
1484 | function Enclosing_Protected_Type (Obj : Node_Id) return Entity_Id is | |
1485 | begin | |
1486 | if Is_Entity_Name (Obj) then | |
1487 | declare | |
1488 | Ent : Entity_Id := Entity (Obj); | |
1489 | ||
1490 | begin | |
1491 | -- The object can be a renaming of a private component, use | |
1492 | -- the original record component. | |
1493 | ||
1494 | if Is_Prival (Ent) then | |
1495 | Ent := Prival_Link (Ent); | |
1496 | end if; | |
1497 | ||
1498 | if Is_Protected_Type (Scope (Ent)) then | |
1499 | return Scope (Ent); | |
1500 | end if; | |
1501 | end; | |
1502 | end if; | |
1503 | ||
1504 | -- For indexed and selected components, recursively check the prefix | |
1505 | ||
1506 | if Nkind_In (Obj, N_Indexed_Component, N_Selected_Component) then | |
1507 | return Enclosing_Protected_Type (Prefix (Obj)); | |
1508 | ||
1509 | -- The object does not denote a protected component | |
1510 | ||
1511 | else | |
1512 | return Empty; | |
1513 | end if; | |
1514 | end Enclosing_Protected_Type; | |
1515 | ||
1516 | ------------------------- | |
1517 | -- Is_Public_Operation -- | |
1518 | ------------------------- | |
1519 | ||
1520 | function Is_Public_Operation return Boolean is | |
1521 | S : Entity_Id; | |
1522 | E : Entity_Id; | |
1523 | ||
1524 | begin | |
1525 | S := Current_Scope; | |
1526 | while Present (S) | |
1527 | and then S /= Pref_Encl_Typ | |
1528 | loop | |
1529 | if Scope (S) = Pref_Encl_Typ then | |
1530 | E := First_Entity (Pref_Encl_Typ); | |
1531 | while Present (E) | |
1532 | and then E /= First_Private_Entity (Pref_Encl_Typ) | |
1533 | loop | |
1534 | if E = S then | |
1535 | return True; | |
1536 | end if; | |
1537 | Next_Entity (E); | |
1538 | end loop; | |
1539 | end if; | |
1540 | ||
1541 | S := Scope (S); | |
1542 | end loop; | |
1543 | ||
1544 | return False; | |
1545 | end Is_Public_Operation; | |
1546 | ||
1547 | -- Start of processing for Check_Unprotected_Access | |
1548 | ||
1549 | begin | |
1550 | if Nkind (Expr) = N_Attribute_Reference | |
1551 | and then Attribute_Name (Expr) = Name_Unchecked_Access | |
1552 | then | |
1553 | Cont_Encl_Typ := Enclosing_Protected_Type (Context); | |
1554 | Pref_Encl_Typ := Enclosing_Protected_Type (Prefix (Expr)); | |
1555 | ||
1556 | -- Check whether we are trying to export a protected component to a | |
1557 | -- context with an equal or lower access level. | |
1558 | ||
1559 | if Present (Pref_Encl_Typ) | |
1560 | and then No (Cont_Encl_Typ) | |
1561 | and then Is_Public_Operation | |
1562 | and then Scope_Depth (Pref_Encl_Typ) >= | |
1563 | Object_Access_Level (Context) | |
1564 | then | |
1565 | Error_Msg_N | |
1566 | ("?possible unprotected access to protected data", Expr); | |
1567 | end if; | |
1568 | end if; | |
1569 | end Check_Unprotected_Access; | |
1570 | ||
996ae0b0 RK |
1571 | --------------- |
1572 | -- Check_VMS -- | |
1573 | --------------- | |
1574 | ||
1575 | procedure Check_VMS (Construct : Node_Id) is | |
1576 | begin | |
1577 | if not OpenVMS_On_Target then | |
1578 | Error_Msg_N | |
1579 | ("this construct is allowed only in Open'V'M'S", Construct); | |
1580 | end if; | |
1581 | end Check_VMS; | |
1582 | ||
ce2b6ba5 JM |
1583 | ------------------------ |
1584 | -- Collect_Interfaces -- | |
1585 | ------------------------ | |
9b0986f8 | 1586 | |
ce2b6ba5 JM |
1587 | procedure Collect_Interfaces |
1588 | (T : Entity_Id; | |
1589 | Ifaces_List : out Elist_Id; | |
1590 | Exclude_Parents : Boolean := False; | |
1591 | Use_Full_View : Boolean := True) | |
9b0986f8 | 1592 | is |
9b0986f8 RD |
1593 | procedure Collect (Typ : Entity_Id); |
1594 | -- Subsidiary subprogram used to traverse the whole list | |
1595 | -- of directly and indirectly implemented interfaces | |
1596 | ||
9b0986f8 RD |
1597 | ------------- |
1598 | -- Collect -- | |
1599 | ------------- | |
1600 | ||
1601 | procedure Collect (Typ : Entity_Id) is | |
9e87a68d | 1602 | Ancestor : Entity_Id; |
1b6c95c4 | 1603 | Full_T : Entity_Id; |
9e87a68d ES |
1604 | Id : Node_Id; |
1605 | Iface : Entity_Id; | |
9b0986f8 RD |
1606 | |
1607 | begin | |
1b6c95c4 RD |
1608 | Full_T := Typ; |
1609 | ||
1610 | -- Handle private types | |
1611 | ||
1612 | if Use_Full_View | |
1613 | and then Is_Private_Type (Typ) | |
1614 | and then Present (Full_View (Typ)) | |
1615 | then | |
1616 | Full_T := Full_View (Typ); | |
1617 | end if; | |
1618 | ||
9e87a68d ES |
1619 | -- Include the ancestor if we are generating the whole list of |
1620 | -- abstract interfaces. | |
9b0986f8 | 1621 | |
ce2b6ba5 | 1622 | if Etype (Full_T) /= Typ |
9b0986f8 RD |
1623 | |
1624 | -- Protect the frontend against wrong sources. For example: | |
1625 | ||
1626 | -- package P is | |
1627 | -- type A is tagged null record; | |
1628 | -- type B is new A with private; | |
1629 | -- type C is new A with private; | |
1630 | -- private | |
1631 | -- type B is new C with null record; | |
1632 | -- type C is new B with null record; | |
1633 | -- end P; | |
1634 | ||
1b6c95c4 | 1635 | and then Etype (Full_T) /= T |
9b0986f8 | 1636 | then |
1b6c95c4 | 1637 | Ancestor := Etype (Full_T); |
9b0986f8 RD |
1638 | Collect (Ancestor); |
1639 | ||
1640 | if Is_Interface (Ancestor) | |
ce2b6ba5 | 1641 | and then not Exclude_Parents |
9b0986f8 | 1642 | then |
ce2b6ba5 | 1643 | Append_Unique_Elmt (Ancestor, Ifaces_List); |
9b0986f8 RD |
1644 | end if; |
1645 | end if; | |
1646 | ||
1647 | -- Traverse the graph of ancestor interfaces | |
1648 | ||
ce2b6ba5 JM |
1649 | if Is_Non_Empty_List (Abstract_Interface_List (Full_T)) then |
1650 | Id := First (Abstract_Interface_List (Full_T)); | |
9b0986f8 RD |
1651 | while Present (Id) loop |
1652 | Iface := Etype (Id); | |
1653 | ||
1654 | -- Protect against wrong uses. For example: | |
1655 | -- type I is interface; | |
1656 | -- type O is tagged null record; | |
1657 | -- type Wrong is new I and O with null record; -- ERROR | |
1658 | ||
1659 | if Is_Interface (Iface) then | |
ce2b6ba5 JM |
1660 | if Exclude_Parents |
1661 | and then Etype (T) /= T | |
1662 | and then Interface_Present_In_Ancestor (Etype (T), Iface) | |
9b0986f8 RD |
1663 | then |
1664 | null; | |
1665 | else | |
ce2b6ba5 JM |
1666 | Collect (Iface); |
1667 | Append_Unique_Elmt (Iface, Ifaces_List); | |
9b0986f8 RD |
1668 | end if; |
1669 | end if; | |
1670 | ||
1671 | Next (Id); | |
1672 | end loop; | |
1673 | end if; | |
1674 | end Collect; | |
1675 | ||
ce2b6ba5 | 1676 | -- Start of processing for Collect_Interfaces |
9b0986f8 RD |
1677 | |
1678 | begin | |
9e87a68d | 1679 | pragma Assert (Is_Tagged_Type (T) or else Is_Concurrent_Type (T)); |
9b0986f8 RD |
1680 | Ifaces_List := New_Elmt_List; |
1681 | Collect (T); | |
ce2b6ba5 | 1682 | end Collect_Interfaces; |
9b0986f8 | 1683 | |
f377c995 HK |
1684 | ---------------------------------- |
1685 | -- Collect_Interface_Components -- | |
1686 | ---------------------------------- | |
1687 | ||
1688 | procedure Collect_Interface_Components | |
1689 | (Tagged_Type : Entity_Id; | |
1690 | Components_List : out Elist_Id) | |
1691 | is | |
1692 | procedure Collect (Typ : Entity_Id); | |
1693 | -- Subsidiary subprogram used to climb to the parents | |
1694 | ||
1695 | ------------- | |
1696 | -- Collect -- | |
1697 | ------------- | |
1698 | ||
1699 | procedure Collect (Typ : Entity_Id) is | |
b16d9747 JM |
1700 | Tag_Comp : Entity_Id; |
1701 | Parent_Typ : Entity_Id; | |
f377c995 HK |
1702 | |
1703 | begin | |
b16d9747 JM |
1704 | -- Handle private types |
1705 | ||
1706 | if Present (Full_View (Etype (Typ))) then | |
1707 | Parent_Typ := Full_View (Etype (Typ)); | |
1708 | else | |
1709 | Parent_Typ := Etype (Typ); | |
1710 | end if; | |
1711 | ||
1712 | if Parent_Typ /= Typ | |
f377c995 HK |
1713 | |
1714 | -- Protect the frontend against wrong sources. For example: | |
1715 | ||
1716 | -- package P is | |
1717 | -- type A is tagged null record; | |
1718 | -- type B is new A with private; | |
1719 | -- type C is new A with private; | |
1720 | -- private | |
1721 | -- type B is new C with null record; | |
1722 | -- type C is new B with null record; | |
1723 | -- end P; | |
1724 | ||
b16d9747 | 1725 | and then Parent_Typ /= Tagged_Type |
f377c995 | 1726 | then |
b16d9747 | 1727 | Collect (Parent_Typ); |
f377c995 HK |
1728 | end if; |
1729 | ||
1730 | -- Collect the components containing tags of secondary dispatch | |
1731 | -- tables. | |
1732 | ||
1733 | Tag_Comp := Next_Tag_Component (First_Tag_Component (Typ)); | |
1734 | while Present (Tag_Comp) loop | |
7f0e4cdb | 1735 | pragma Assert (Present (Related_Type (Tag_Comp))); |
f377c995 HK |
1736 | Append_Elmt (Tag_Comp, Components_List); |
1737 | ||
1738 | Tag_Comp := Next_Tag_Component (Tag_Comp); | |
1739 | end loop; | |
1740 | end Collect; | |
1741 | ||
1742 | -- Start of processing for Collect_Interface_Components | |
1743 | ||
1744 | begin | |
1745 | pragma Assert (Ekind (Tagged_Type) = E_Record_Type | |
1746 | and then Is_Tagged_Type (Tagged_Type)); | |
1747 | ||
1748 | Components_List := New_Elmt_List; | |
1749 | Collect (Tagged_Type); | |
1750 | end Collect_Interface_Components; | |
1751 | ||
1b6c95c4 RD |
1752 | ----------------------------- |
1753 | -- Collect_Interfaces_Info -- | |
1754 | ----------------------------- | |
1755 | ||
1756 | procedure Collect_Interfaces_Info | |
1757 | (T : Entity_Id; | |
1758 | Ifaces_List : out Elist_Id; | |
1759 | Components_List : out Elist_Id; | |
1760 | Tags_List : out Elist_Id) | |
1761 | is | |
1762 | Comps_List : Elist_Id; | |
1763 | Comp_Elmt : Elmt_Id; | |
1764 | Comp_Iface : Entity_Id; | |
1765 | Iface_Elmt : Elmt_Id; | |
1766 | Iface : Entity_Id; | |
1767 | ||
1768 | function Search_Tag (Iface : Entity_Id) return Entity_Id; | |
1769 | -- Search for the secondary tag associated with the interface type | |
1770 | -- Iface that is implemented by T. | |
1771 | ||
1772 | ---------------- | |
1773 | -- Search_Tag -- | |
1774 | ---------------- | |
1775 | ||
1776 | function Search_Tag (Iface : Entity_Id) return Entity_Id is | |
1777 | ADT : Elmt_Id; | |
1b6c95c4 | 1778 | begin |
cefce34c JM |
1779 | if not Is_CPP_Class (T) then |
1780 | ADT := Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (T)))); | |
1781 | else | |
1782 | ADT := Next_Elmt (First_Elmt (Access_Disp_Table (T))); | |
1783 | end if; | |
1784 | ||
1b6c95c4 | 1785 | while Present (ADT) |
cefce34c | 1786 | and then Is_Tag (Node (ADT)) |
7f0e4cdb | 1787 | and then Related_Type (Node (ADT)) /= Iface |
1b6c95c4 | 1788 | loop |
cefce34c JM |
1789 | -- Skip secondary dispatch table referencing thunks to user |
1790 | -- defined primitives covered by this interface. | |
1923d2d6 | 1791 | |
cefce34c | 1792 | pragma Assert (Has_Suffix (Node (ADT), 'P')); |
1923d2d6 | 1793 | Next_Elmt (ADT); |
cefce34c JM |
1794 | |
1795 | -- Skip secondary dispatch tables of Ada types | |
1796 | ||
1797 | if not Is_CPP_Class (T) then | |
1798 | ||
1799 | -- Skip secondary dispatch table referencing thunks to | |
1800 | -- predefined primitives. | |
1801 | ||
1802 | pragma Assert (Has_Suffix (Node (ADT), 'Y')); | |
1803 | Next_Elmt (ADT); | |
1804 | ||
1805 | -- Skip secondary dispatch table referencing user-defined | |
1806 | -- primitives covered by this interface. | |
1807 | ||
1808 | pragma Assert (Has_Suffix (Node (ADT), 'D')); | |
1809 | Next_Elmt (ADT); | |
1810 | ||
1811 | -- Skip secondary dispatch table referencing predefined | |
67536dcb | 1812 | -- primitives. |
cefce34c JM |
1813 | |
1814 | pragma Assert (Has_Suffix (Node (ADT), 'Z')); | |
1815 | Next_Elmt (ADT); | |
1816 | end if; | |
1b6c95c4 RD |
1817 | end loop; |
1818 | ||
cefce34c | 1819 | pragma Assert (Is_Tag (Node (ADT))); |
1b6c95c4 RD |
1820 | return Node (ADT); |
1821 | end Search_Tag; | |
1822 | ||
1823 | -- Start of processing for Collect_Interfaces_Info | |
1824 | ||
1825 | begin | |
38b181d6 | 1826 | Collect_Interfaces (T, Ifaces_List); |
1b6c95c4 RD |
1827 | Collect_Interface_Components (T, Comps_List); |
1828 | ||
1829 | -- Search for the record component and tag associated with each | |
1830 | -- interface type of T. | |
1831 | ||
1832 | Components_List := New_Elmt_List; | |
1833 | Tags_List := New_Elmt_List; | |
1834 | ||
1835 | Iface_Elmt := First_Elmt (Ifaces_List); | |
1836 | while Present (Iface_Elmt) loop | |
1837 | Iface := Node (Iface_Elmt); | |
1838 | ||
1839 | -- Associate the primary tag component and the primary dispatch table | |
1840 | -- with all the interfaces that are parents of T | |
1841 | ||
4ac2477e | 1842 | if Is_Ancestor (Iface, T, Use_Full_View => True) then |
1b6c95c4 RD |
1843 | Append_Elmt (First_Tag_Component (T), Components_List); |
1844 | Append_Elmt (Node (First_Elmt (Access_Disp_Table (T))), Tags_List); | |
1845 | ||
1846 | -- Otherwise search for the tag component and secondary dispatch | |
1847 | -- table of Iface | |
1848 | ||
1849 | else | |
1850 | Comp_Elmt := First_Elmt (Comps_List); | |
1851 | while Present (Comp_Elmt) loop | |
7f0e4cdb | 1852 | Comp_Iface := Related_Type (Node (Comp_Elmt)); |
1b6c95c4 RD |
1853 | |
1854 | if Comp_Iface = Iface | |
4ac2477e | 1855 | or else Is_Ancestor (Iface, Comp_Iface, Use_Full_View => True) |
1b6c95c4 RD |
1856 | then |
1857 | Append_Elmt (Node (Comp_Elmt), Components_List); | |
1858 | Append_Elmt (Search_Tag (Comp_Iface), Tags_List); | |
1859 | exit; | |
1860 | end if; | |
1861 | ||
1862 | Next_Elmt (Comp_Elmt); | |
1863 | end loop; | |
1864 | pragma Assert (Present (Comp_Elmt)); | |
1865 | end if; | |
1866 | ||
1867 | Next_Elmt (Iface_Elmt); | |
1868 | end loop; | |
1869 | end Collect_Interfaces_Info; | |
1870 | ||
ea034236 AC |
1871 | --------------------- |
1872 | -- Collect_Parents -- | |
1873 | --------------------- | |
1874 | ||
1875 | procedure Collect_Parents | |
1876 | (T : Entity_Id; | |
1877 | List : out Elist_Id; | |
1878 | Use_Full_View : Boolean := True) | |
1879 | is | |
1880 | Current_Typ : Entity_Id := T; | |
1881 | Parent_Typ : Entity_Id; | |
1882 | ||
1883 | begin | |
1884 | List := New_Elmt_List; | |
1885 | ||
1886 | -- No action if the if the type has no parents | |
1887 | ||
1888 | if T = Etype (T) then | |
1889 | return; | |
1890 | end if; | |
1891 | ||
1892 | loop | |
1893 | Parent_Typ := Etype (Current_Typ); | |
1894 | ||
1895 | if Is_Private_Type (Parent_Typ) | |
1896 | and then Present (Full_View (Parent_Typ)) | |
1897 | and then Use_Full_View | |
1898 | then | |
1899 | Parent_Typ := Full_View (Base_Type (Parent_Typ)); | |
1900 | end if; | |
1901 | ||
1902 | Append_Elmt (Parent_Typ, List); | |
1903 | ||
1904 | exit when Parent_Typ = Current_Typ; | |
1905 | Current_Typ := Parent_Typ; | |
1906 | end loop; | |
1907 | end Collect_Parents; | |
1908 | ||
996ae0b0 RK |
1909 | ---------------------------------- |
1910 | -- Collect_Primitive_Operations -- | |
1911 | ---------------------------------- | |
1912 | ||
1913 | function Collect_Primitive_Operations (T : Entity_Id) return Elist_Id is | |
1914 | B_Type : constant Entity_Id := Base_Type (T); | |
1915 | B_Decl : constant Node_Id := Original_Node (Parent (B_Type)); | |
1916 | B_Scope : Entity_Id := Scope (B_Type); | |
1917 | Op_List : Elist_Id; | |
1918 | Formal : Entity_Id; | |
1919 | Is_Prim : Boolean; | |
1920 | Formal_Derived : Boolean := False; | |
1921 | Id : Entity_Id; | |
1922 | ||
4adf3c50 AC |
1923 | function Match (E : Entity_Id) return Boolean; |
1924 | -- True if E's base type is B_Type, or E is of an anonymous access type | |
1925 | -- and the base type of its designated type is B_Type. | |
1926 | ||
1927 | ----------- | |
1928 | -- Match -- | |
1929 | ----------- | |
1930 | ||
1931 | function Match (E : Entity_Id) return Boolean is | |
1932 | Etyp : Entity_Id := Etype (E); | |
1933 | ||
1934 | begin | |
1935 | if Ekind (Etyp) = E_Anonymous_Access_Type then | |
1936 | Etyp := Designated_Type (Etyp); | |
1937 | end if; | |
1938 | ||
1939 | return Base_Type (Etyp) = B_Type; | |
1940 | end Match; | |
1941 | ||
1942 | -- Start of processing for Collect_Primitive_Operations | |
1943 | ||
996ae0b0 RK |
1944 | begin |
1945 | -- For tagged types, the primitive operations are collected as they | |
1946 | -- are declared, and held in an explicit list which is simply returned. | |
1947 | ||
1948 | if Is_Tagged_Type (B_Type) then | |
1949 | return Primitive_Operations (B_Type); | |
1950 | ||
1951 | -- An untagged generic type that is a derived type inherits the | |
1952 | -- primitive operations of its parent type. Other formal types only | |
1953 | -- have predefined operators, which are not explicitly represented. | |
1954 | ||
1955 | elsif Is_Generic_Type (B_Type) then | |
1956 | if Nkind (B_Decl) = N_Formal_Type_Declaration | |
1957 | and then Nkind (Formal_Type_Definition (B_Decl)) | |
1958 | = N_Formal_Derived_Type_Definition | |
1959 | then | |
1960 | Formal_Derived := True; | |
1961 | else | |
1962 | return New_Elmt_List; | |
1963 | end if; | |
1964 | end if; | |
1965 | ||
1966 | Op_List := New_Elmt_List; | |
1967 | ||
1968 | if B_Scope = Standard_Standard then | |
1969 | if B_Type = Standard_String then | |
1970 | Append_Elmt (Standard_Op_Concat, Op_List); | |
1971 | ||
1972 | elsif B_Type = Standard_Wide_String then | |
1973 | Append_Elmt (Standard_Op_Concatw, Op_List); | |
1974 | ||
1975 | else | |
1976 | null; | |
1977 | end if; | |
1978 | ||
21024a39 RD |
1979 | elsif (Is_Package_Or_Generic_Package (B_Scope) |
1980 | and then | |
1981 | Nkind (Parent (Declaration_Node (First_Subtype (T)))) /= | |
1982 | N_Package_Body) | |
996ae0b0 RK |
1983 | or else Is_Derived_Type (B_Type) |
1984 | then | |
1985 | -- The primitive operations appear after the base type, except | |
1986 | -- if the derivation happens within the private part of B_Scope | |
1987 | -- and the type is a private type, in which case both the type | |
1988 | -- and some primitive operations may appear before the base | |
1989 | -- type, and the list of candidates starts after the type. | |
1990 | ||
1991 | if In_Open_Scopes (B_Scope) | |
1992 | and then Scope (T) = B_Scope | |
1993 | and then In_Private_Part (B_Scope) | |
1994 | then | |
1995 | Id := Next_Entity (T); | |
1996 | else | |
1997 | Id := Next_Entity (B_Type); | |
1998 | end if; | |
1999 | ||
2000 | while Present (Id) loop | |
2001 | ||
2002 | -- Note that generic formal subprograms are not | |
2003 | -- considered to be primitive operations and thus | |
2004 | -- are never inherited. | |
2005 | ||
2006 | if Is_Overloadable (Id) | |
2007 | and then Nkind (Parent (Parent (Id))) | |
82c80734 | 2008 | not in N_Formal_Subprogram_Declaration |
996ae0b0 RK |
2009 | then |
2010 | Is_Prim := False; | |
2011 | ||
4adf3c50 | 2012 | if Match (Id) then |
996ae0b0 | 2013 | Is_Prim := True; |
4adf3c50 | 2014 | |
996ae0b0 RK |
2015 | else |
2016 | Formal := First_Formal (Id); | |
2017 | while Present (Formal) loop | |
4adf3c50 | 2018 | if Match (Formal) then |
996ae0b0 RK |
2019 | Is_Prim := True; |
2020 | exit; | |
2021 | end if; | |
2022 | ||
2023 | Next_Formal (Formal); | |
2024 | end loop; | |
2025 | end if; | |
2026 | ||
2027 | -- For a formal derived type, the only primitives are the | |
2028 | -- ones inherited from the parent type. Operations appearing | |
2029 | -- in the package declaration are not primitive for it. | |
2030 | ||
2031 | if Is_Prim | |
2032 | and then (not Formal_Derived | |
2033 | or else Present (Alias (Id))) | |
2034 | then | |
30537990 AC |
2035 | -- In the special case of an equality operator aliased to |
2036 | -- an overriding dispatching equality belonging to the same | |
2037 | -- type, we don't include it in the list of primitives. | |
2038 | -- This avoids inheriting multiple equality operators when | |
2039 | -- deriving from untagged private types whose full type is | |
2040 | -- tagged, which can otherwise cause ambiguities. Note that | |
2041 | -- this should only happen for this kind of untagged parent | |
2042 | -- type, since normally dispatching operations are inherited | |
2043 | -- using the type's Primitive_Operations list. | |
2044 | ||
2045 | if Chars (Id) = Name_Op_Eq | |
2046 | and then Is_Dispatching_Operation (Id) | |
2047 | and then Present (Alias (Id)) | |
038140ed | 2048 | and then Present (Overridden_Operation (Alias (Id))) |
30537990 AC |
2049 | and then Base_Type (Etype (First_Entity (Id))) = |
2050 | Base_Type (Etype (First_Entity (Alias (Id)))) | |
2051 | then | |
2052 | null; | |
2053 | ||
2054 | -- Include the subprogram in the list of primitives | |
2055 | ||
2056 | else | |
2057 | Append_Elmt (Id, Op_List); | |
2058 | end if; | |
996ae0b0 RK |
2059 | end if; |
2060 | end if; | |
2061 | ||
2062 | Next_Entity (Id); | |
2063 | ||
7a78fa97 AC |
2064 | -- For a type declared in System, some of its operations may |
2065 | -- appear in the target-specific extension to System. | |
996ae0b0 RK |
2066 | |
2067 | if No (Id) | |
9a0ddeee | 2068 | and then B_Scope = RTU_Entity (System) |
996ae0b0 RK |
2069 | and then Present_System_Aux |
2070 | then | |
2071 | B_Scope := System_Aux_Id; | |
2072 | Id := First_Entity (System_Aux_Id); | |
2073 | end if; | |
996ae0b0 | 2074 | end loop; |
996ae0b0 RK |
2075 | end if; |
2076 | ||
2077 | return Op_List; | |
2078 | end Collect_Primitive_Operations; | |
2079 | ||
2080 | ----------------------------------- | |
2081 | -- Compile_Time_Constraint_Error -- | |
2082 | ----------------------------------- | |
2083 | ||
2084 | function Compile_Time_Constraint_Error | |
2085 | (N : Node_Id; | |
2086 | Msg : String; | |
2087 | Ent : Entity_Id := Empty; | |
fbf5a39b | 2088 | Loc : Source_Ptr := No_Location; |
9b0986f8 | 2089 | Warn : Boolean := False) return Node_Id |
996ae0b0 RK |
2090 | is |
2091 | Msgc : String (1 .. Msg'Length + 2); | |
1b6c95c4 RD |
2092 | -- Copy of message, with room for possible ? and ! at end |
2093 | ||
996ae0b0 | 2094 | Msgl : Natural; |
fbf5a39b | 2095 | Wmsg : Boolean; |
996ae0b0 | 2096 | P : Node_Id; |
b8dc622e | 2097 | OldP : Node_Id; |
996ae0b0 | 2098 | Msgs : Boolean; |
07fc65c4 | 2099 | Eloc : Source_Ptr; |
996ae0b0 RK |
2100 | |
2101 | begin | |
2102 | -- A static constraint error in an instance body is not a fatal error. | |
2103 | -- we choose to inhibit the message altogether, because there is no | |
2104 | -- obvious node (for now) on which to post it. On the other hand the | |
2105 | -- offending node must be replaced with a constraint_error in any case. | |
2106 | ||
2107 | -- No messages are generated if we already posted an error on this node | |
2108 | ||
2109 | if not Error_Posted (N) then | |
07fc65c4 GB |
2110 | if Loc /= No_Location then |
2111 | Eloc := Loc; | |
2112 | else | |
2113 | Eloc := Sloc (N); | |
2114 | end if; | |
996ae0b0 | 2115 | |
996ae0b0 | 2116 | Msgc (1 .. Msg'Length) := Msg; |
1b6c95c4 | 2117 | Msgl := Msg'Length; |
996ae0b0 RK |
2118 | |
2119 | -- Message is a warning, even in Ada 95 case | |
2120 | ||
9b0986f8 | 2121 | if Msg (Msg'Last) = '?' then |
fbf5a39b | 2122 | Wmsg := True; |
996ae0b0 RK |
2123 | |
2124 | -- In Ada 83, all messages are warnings. In the private part and | |
2125 | -- the body of an instance, constraint_checks are only warnings. | |
fbf5a39b | 2126 | -- We also make this a warning if the Warn parameter is set. |
996ae0b0 | 2127 | |
0ab80019 AC |
2128 | elsif Warn |
2129 | or else (Ada_Version = Ada_83 and then Comes_From_Source (N)) | |
2130 | then | |
996ae0b0 RK |
2131 | Msgl := Msgl + 1; |
2132 | Msgc (Msgl) := '?'; | |
fbf5a39b | 2133 | Wmsg := True; |
996ae0b0 RK |
2134 | |
2135 | elsif In_Instance_Not_Visible then | |
996ae0b0 RK |
2136 | Msgl := Msgl + 1; |
2137 | Msgc (Msgl) := '?'; | |
fbf5a39b | 2138 | Wmsg := True; |
996ae0b0 RK |
2139 | |
2140 | -- Otherwise we have a real error message (Ada 95 static case) | |
1b6c95c4 RD |
2141 | -- and we make this an unconditional message. Note that in the |
2142 | -- warning case we do not make the message unconditional, it seems | |
2143 | -- quite reasonable to delete messages like this (about exceptions | |
2144 | -- that will be raised) in dead code. | |
996ae0b0 RK |
2145 | |
2146 | else | |
fbf5a39b | 2147 | Wmsg := False; |
1b6c95c4 RD |
2148 | Msgl := Msgl + 1; |
2149 | Msgc (Msgl) := '!'; | |
996ae0b0 RK |
2150 | end if; |
2151 | ||
2152 | -- Should we generate a warning? The answer is not quite yes. The | |
2153 | -- very annoying exception occurs in the case of a short circuit | |
2154 | -- operator where the left operand is static and decisive. Climb | |
b8dc622e JM |
2155 | -- parents to see if that is the case we have here. Conditional |
2156 | -- expressions with decisive conditions are a similar situation. | |
996ae0b0 RK |
2157 | |
2158 | Msgs := True; | |
2159 | P := N; | |
996ae0b0 | 2160 | loop |
b8dc622e | 2161 | OldP := P; |
996ae0b0 RK |
2162 | P := Parent (P); |
2163 | ||
b8dc622e JM |
2164 | -- And then with False as left operand |
2165 | ||
2166 | if Nkind (P) = N_And_Then | |
2167 | and then Compile_Time_Known_Value (Left_Opnd (P)) | |
2168 | and then Is_False (Expr_Value (Left_Opnd (P))) | |
996ae0b0 RK |
2169 | then |
2170 | Msgs := False; | |
2171 | exit; | |
2172 | ||
b8dc622e JM |
2173 | -- OR ELSE with True as left operand |
2174 | ||
2175 | elsif Nkind (P) = N_Or_Else | |
2176 | and then Compile_Time_Known_Value (Left_Opnd (P)) | |
2177 | and then Is_True (Expr_Value (Left_Opnd (P))) | |
2178 | then | |
2179 | Msgs := False; | |
2180 | exit; | |
2181 | ||
2182 | -- Conditional expression | |
2183 | ||
2184 | elsif Nkind (P) = N_Conditional_Expression then | |
2185 | declare | |
2186 | Cond : constant Node_Id := First (Expressions (P)); | |
2187 | Texp : constant Node_Id := Next (Cond); | |
2188 | Fexp : constant Node_Id := Next (Texp); | |
2189 | ||
2190 | begin | |
2191 | if Compile_Time_Known_Value (Cond) then | |
2192 | ||
2193 | -- Condition is True and we are in the right operand | |
2194 | ||
2195 | if Is_True (Expr_Value (Cond)) | |
2196 | and then OldP = Fexp | |
2197 | then | |
2198 | Msgs := False; | |
2199 | exit; | |
2200 | ||
2201 | -- Condition is False and we are in the left operand | |
2202 | ||
2203 | elsif Is_False (Expr_Value (Cond)) | |
2204 | and then OldP = Texp | |
2205 | then | |
2206 | Msgs := False; | |
2207 | exit; | |
2208 | end if; | |
2209 | end if; | |
2210 | end; | |
2211 | ||
2212 | -- Special case for component association in aggregates, where | |
2213 | -- we want to keep climbing up to the parent aggregate. | |
2214 | ||
996ae0b0 RK |
2215 | elsif Nkind (P) = N_Component_Association |
2216 | and then Nkind (Parent (P)) = N_Aggregate | |
2217 | then | |
b8dc622e JM |
2218 | null; |
2219 | ||
2220 | -- Keep going if within subexpression | |
996ae0b0 RK |
2221 | |
2222 | else | |
2223 | exit when Nkind (P) not in N_Subexpr; | |
2224 | end if; | |
2225 | end loop; | |
2226 | ||
2227 | if Msgs then | |
2228 | if Present (Ent) then | |
07fc65c4 | 2229 | Error_Msg_NEL (Msgc (1 .. Msgl), N, Ent, Eloc); |
996ae0b0 | 2230 | else |
07fc65c4 | 2231 | Error_Msg_NEL (Msgc (1 .. Msgl), N, Etype (N), Eloc); |
996ae0b0 RK |
2232 | end if; |
2233 | ||
fbf5a39b | 2234 | if Wmsg then |
996ae0b0 | 2235 | if Inside_Init_Proc then |
07fc65c4 | 2236 | Error_Msg_NEL |
b8dc622e | 2237 | ("\?& will be raised for objects of this type", |
07fc65c4 | 2238 | N, Standard_Constraint_Error, Eloc); |
996ae0b0 | 2239 | else |
07fc65c4 | 2240 | Error_Msg_NEL |
b8dc622e | 2241 | ("\?& will be raised at run time", |
07fc65c4 | 2242 | N, Standard_Constraint_Error, Eloc); |
996ae0b0 | 2243 | end if; |
9b0986f8 | 2244 | |
996ae0b0 | 2245 | else |
9b0986f8 RD |
2246 | Error_Msg |
2247 | ("\static expression fails Constraint_Check", Eloc); | |
2248 | Set_Error_Posted (N); | |
996ae0b0 RK |
2249 | end if; |
2250 | end if; | |
2251 | end if; | |
2252 | ||
2253 | return N; | |
2254 | end Compile_Time_Constraint_Error; | |
2255 | ||
2256 | ----------------------- | |
2257 | -- Conditional_Delay -- | |
2258 | ----------------------- | |
2259 | ||
2260 | procedure Conditional_Delay (New_Ent, Old_Ent : Entity_Id) is | |
2261 | begin | |
2262 | if Has_Delayed_Freeze (Old_Ent) and then not Is_Frozen (Old_Ent) then | |
2263 | Set_Has_Delayed_Freeze (New_Ent); | |
2264 | end if; | |
2265 | end Conditional_Delay; | |
2266 | ||
ce4a6e84 RD |
2267 | ------------------------- |
2268 | -- Copy_Parameter_List -- | |
2269 | ------------------------- | |
2270 | ||
2271 | function Copy_Parameter_List (Subp_Id : Entity_Id) return List_Id is | |
2272 | Loc : constant Source_Ptr := Sloc (Subp_Id); | |
2273 | Plist : List_Id; | |
2274 | Formal : Entity_Id; | |
2275 | ||
2276 | begin | |
2277 | if No (First_Formal (Subp_Id)) then | |
2278 | return No_List; | |
2279 | else | |
2280 | Plist := New_List; | |
2281 | Formal := First_Formal (Subp_Id); | |
2282 | while Present (Formal) loop | |
2283 | Append | |
2284 | (Make_Parameter_Specification (Loc, | |
2285 | Defining_Identifier => | |
2286 | Make_Defining_Identifier (Sloc (Formal), | |
2287 | Chars => Chars (Formal)), | |
2288 | In_Present => In_Present (Parent (Formal)), | |
2289 | Out_Present => Out_Present (Parent (Formal)), | |
2290 | Parameter_Type => | |
2291 | New_Reference_To (Etype (Formal), Loc), | |
2292 | Expression => | |
2293 | New_Copy_Tree (Expression (Parent (Formal)))), | |
2294 | Plist); | |
2295 | ||
2296 | Next_Formal (Formal); | |
2297 | end loop; | |
2298 | end if; | |
2299 | ||
2300 | return Plist; | |
2301 | end Copy_Parameter_List; | |
2302 | ||
996ae0b0 RK |
2303 | -------------------- |
2304 | -- Current_Entity -- | |
2305 | -------------------- | |
2306 | ||
2307 | -- The currently visible definition for a given identifier is the | |
2308 | -- one most chained at the start of the visibility chain, i.e. the | |
2309 | -- one that is referenced by the Node_Id value of the name of the | |
2310 | -- given identifier. | |
2311 | ||
2312 | function Current_Entity (N : Node_Id) return Entity_Id is | |
2313 | begin | |
2314 | return Get_Name_Entity_Id (Chars (N)); | |
2315 | end Current_Entity; | |
2316 | ||
2317 | ----------------------------- | |
2318 | -- Current_Entity_In_Scope -- | |
2319 | ----------------------------- | |
2320 | ||
2321 | function Current_Entity_In_Scope (N : Node_Id) return Entity_Id is | |
2322 | E : Entity_Id; | |
2323 | CS : constant Entity_Id := Current_Scope; | |
2324 | ||
2325 | Transient_Case : constant Boolean := Scope_Is_Transient; | |
2326 | ||
2327 | begin | |
2328 | E := Get_Name_Entity_Id (Chars (N)); | |
996ae0b0 RK |
2329 | while Present (E) |
2330 | and then Scope (E) /= CS | |
2331 | and then (not Transient_Case or else Scope (E) /= Scope (CS)) | |
2332 | loop | |
2333 | E := Homonym (E); | |
2334 | end loop; | |
2335 | ||
2336 | return E; | |
2337 | end Current_Entity_In_Scope; | |
2338 | ||
2339 | ------------------- | |
2340 | -- Current_Scope -- | |
2341 | ------------------- | |
2342 | ||
2343 | function Current_Scope return Entity_Id is | |
2344 | begin | |
2345 | if Scope_Stack.Last = -1 then | |
2346 | return Standard_Standard; | |
2347 | else | |
2348 | declare | |
2349 | C : constant Entity_Id := | |
2350 | Scope_Stack.Table (Scope_Stack.Last).Entity; | |
2351 | begin | |
2352 | if Present (C) then | |
2353 | return C; | |
2354 | else | |
2355 | return Standard_Standard; | |
2356 | end if; | |
2357 | end; | |
2358 | end if; | |
2359 | end Current_Scope; | |
2360 | ||
2361 | ------------------------ | |
2362 | -- Current_Subprogram -- | |
2363 | ------------------------ | |
2364 | ||
2365 | function Current_Subprogram return Entity_Id is | |
2366 | Scop : constant Entity_Id := Current_Scope; | |
996ae0b0 | 2367 | begin |
fbf5a39b | 2368 | if Is_Subprogram (Scop) or else Is_Generic_Subprogram (Scop) then |
996ae0b0 | 2369 | return Scop; |
996ae0b0 RK |
2370 | else |
2371 | return Enclosing_Subprogram (Scop); | |
2372 | end if; | |
2373 | end Current_Subprogram; | |
2374 | ||
2375 | --------------------- | |
2376 | -- Defining_Entity -- | |
2377 | --------------------- | |
2378 | ||
2379 | function Defining_Entity (N : Node_Id) return Entity_Id is | |
5a15af62 ES |
2380 | K : constant Node_Kind := Nkind (N); |
2381 | Err : Entity_Id := Empty; | |
996ae0b0 RK |
2382 | |
2383 | begin | |
2384 | case K is | |
2385 | when | |
2386 | N_Subprogram_Declaration | | |
2387 | N_Abstract_Subprogram_Declaration | | |
2388 | N_Subprogram_Body | | |
2389 | N_Package_Declaration | | |
2390 | N_Subprogram_Renaming_Declaration | | |
2391 | N_Subprogram_Body_Stub | | |
2392 | N_Generic_Subprogram_Declaration | | |
2393 | N_Generic_Package_Declaration | | |
2394 | N_Formal_Subprogram_Declaration | |
2395 | => | |
2396 | return Defining_Entity (Specification (N)); | |
2397 | ||
2398 | when | |
2399 | N_Component_Declaration | | |
2400 | N_Defining_Program_Unit_Name | | |
2401 | N_Discriminant_Specification | | |
2402 | N_Entry_Body | | |
2403 | N_Entry_Declaration | | |
2404 | N_Entry_Index_Specification | | |
2405 | N_Exception_Declaration | | |
2406 | N_Exception_Renaming_Declaration | | |
2407 | N_Formal_Object_Declaration | | |
2408 | N_Formal_Package_Declaration | | |
2409 | N_Formal_Type_Declaration | | |
2410 | N_Full_Type_Declaration | | |
2411 | N_Implicit_Label_Declaration | | |
2412 | N_Incomplete_Type_Declaration | | |
2413 | N_Loop_Parameter_Specification | | |
2414 | N_Number_Declaration | | |
2415 | N_Object_Declaration | | |
2416 | N_Object_Renaming_Declaration | | |
2417 | N_Package_Body_Stub | | |
2418 | N_Parameter_Specification | | |
2419 | N_Private_Extension_Declaration | | |
2420 | N_Private_Type_Declaration | | |
2421 | N_Protected_Body | | |
2422 | N_Protected_Body_Stub | | |
2423 | N_Protected_Type_Declaration | | |
2424 | N_Single_Protected_Declaration | | |
2425 | N_Single_Task_Declaration | | |
2426 | N_Subtype_Declaration | | |
2427 | N_Task_Body | | |
2428 | N_Task_Body_Stub | | |
2429 | N_Task_Type_Declaration | |
2430 | => | |
2431 | return Defining_Identifier (N); | |
2432 | ||
2433 | when N_Subunit => | |
2434 | return Defining_Entity (Proper_Body (N)); | |
2435 | ||
2436 | when | |
2437 | N_Function_Instantiation | | |
2438 | N_Function_Specification | | |
2439 | N_Generic_Function_Renaming_Declaration | | |
2440 | N_Generic_Package_Renaming_Declaration | | |
2441 | N_Generic_Procedure_Renaming_Declaration | | |
2442 | N_Package_Body | | |
2443 | N_Package_Instantiation | | |
2444 | N_Package_Renaming_Declaration | | |
2445 | N_Package_Specification | | |
2446 | N_Procedure_Instantiation | | |
2447 | N_Procedure_Specification | |
2448 | => | |
2449 | declare | |
2450 | Nam : constant Node_Id := Defining_Unit_Name (N); | |
2451 | ||
2452 | begin | |
2453 | if Nkind (Nam) in N_Entity then | |
2454 | return Nam; | |
2b881d53 | 2455 | |
5a15af62 ES |
2456 | -- For Error, make up a name and attach to declaration |
2457 | -- so we can continue semantic analysis | |
2b881d53 RD |
2458 | |
2459 | elsif Nam = Error then | |
092ef350 | 2460 | Err := Make_Temporary (Sloc (N), 'T'); |
5a15af62 | 2461 | Set_Defining_Unit_Name (N, Err); |
2b881d53 | 2462 | |
5a15af62 | 2463 | return Err; |
2b881d53 RD |
2464 | -- If not an entity, get defining identifier |
2465 | ||
996ae0b0 RK |
2466 | else |
2467 | return Defining_Identifier (Nam); | |
2468 | end if; | |
2469 | end; | |
2470 | ||
2471 | when N_Block_Statement => | |
2472 | return Entity (Identifier (N)); | |
2473 | ||
2474 | when others => | |
2475 | raise Program_Error; | |
2476 | ||
2477 | end case; | |
2478 | end Defining_Entity; | |
2479 | ||
2480 | -------------------------- | |
2481 | -- Denotes_Discriminant -- | |
2482 | -------------------------- | |
2483 | ||
fbf5a39b | 2484 | function Denotes_Discriminant |
9b0986f8 RD |
2485 | (N : Node_Id; |
2486 | Check_Concurrent : Boolean := False) return Boolean | |
fbf5a39b AC |
2487 | is |
2488 | E : Entity_Id; | |
996ae0b0 | 2489 | begin |
fbf5a39b AC |
2490 | if not Is_Entity_Name (N) |
2491 | or else No (Entity (N)) | |
2492 | then | |
2493 | return False; | |
2494 | else | |
2495 | E := Entity (N); | |
2496 | end if; | |
2497 | ||
2498 | -- If we are checking for a protected type, the discriminant may have | |
2499 | -- been rewritten as the corresponding discriminal of the original type | |
2500 | -- or of the corresponding concurrent record, depending on whether we | |
2501 | -- are in the spec or body of the protected type. | |
2502 | ||
2503 | return Ekind (E) = E_Discriminant | |
2504 | or else | |
9b0986f8 | 2505 | (Check_Concurrent |
fbf5a39b AC |
2506 | and then Ekind (E) = E_In_Parameter |
2507 | and then Present (Discriminal_Link (E)) | |
2508 | and then | |
9b0986f8 | 2509 | (Is_Concurrent_Type (Scope (Discriminal_Link (E))) |
fbf5a39b AC |
2510 | or else |
2511 | Is_Concurrent_Record_Type (Scope (Discriminal_Link (E))))); | |
2512 | ||
996ae0b0 RK |
2513 | end Denotes_Discriminant; |
2514 | ||
76b84bf0 AC |
2515 | ------------------------- |
2516 | -- Denotes_Same_Object -- | |
2517 | ------------------------- | |
2518 | ||
2519 | function Denotes_Same_Object (A1, A2 : Node_Id) return Boolean is | |
1e194575 AC |
2520 | Obj1 : Node_Id := A1; |
2521 | Obj2 : Node_Id := A2; | |
2522 | ||
2523 | procedure Check_Renaming (Obj : in out Node_Id); | |
66150d01 AC |
2524 | -- If an object is a renaming, examine renamed object. If it is a |
2525 | -- dereference of a variable, or an indexed expression with non-constant | |
2526 | -- indexes, no overlap check can be reported. | |
2527 | ||
2528 | -------------------- | |
2529 | -- Check_Renaming -- | |
2530 | -------------------- | |
1e194575 AC |
2531 | |
2532 | procedure Check_Renaming (Obj : in out Node_Id) is | |
2533 | begin | |
2534 | if Is_Entity_Name (Obj) | |
2535 | and then Present (Renamed_Entity (Entity (Obj))) | |
2536 | then | |
2537 | Obj := Renamed_Entity (Entity (Obj)); | |
2538 | if Nkind (Obj) = N_Explicit_Dereference | |
2539 | and then Is_Variable (Prefix (Obj)) | |
2540 | then | |
2541 | Obj := Empty; | |
2542 | ||
2543 | elsif Nkind (Obj) = N_Indexed_Component then | |
2544 | declare | |
2545 | Indx : Node_Id; | |
2546 | ||
2547 | begin | |
2548 | Indx := First (Expressions (Obj)); | |
2549 | while Present (Indx) loop | |
2550 | if not Is_OK_Static_Expression (Indx) then | |
2551 | Obj := Empty; | |
2552 | exit; | |
2553 | end if; | |
2554 | ||
2555 | Next_Index (Indx); | |
2556 | end loop; | |
2557 | end; | |
2558 | end if; | |
2559 | end if; | |
2560 | end Check_Renaming; | |
2561 | ||
66150d01 AC |
2562 | -- Start of processing for Denotes_Same_Object |
2563 | ||
76b84bf0 | 2564 | begin |
1e194575 AC |
2565 | Check_Renaming (Obj1); |
2566 | Check_Renaming (Obj2); | |
2567 | ||
2568 | if No (Obj1) | |
2569 | or else No (Obj2) | |
2570 | then | |
2571 | return False; | |
2572 | end if; | |
2573 | ||
27cdc66a RD |
2574 | -- If we have entity names, then must be same entity |
2575 | ||
1e194575 AC |
2576 | if Is_Entity_Name (Obj1) then |
2577 | if Is_Entity_Name (Obj2) then | |
2578 | return Entity (Obj1) = Entity (Obj2); | |
76b84bf0 AC |
2579 | else |
2580 | return False; | |
2581 | end if; | |
2582 | ||
27cdc66a RD |
2583 | -- No match if not same node kind |
2584 | ||
1e194575 | 2585 | elsif Nkind (Obj1) /= Nkind (Obj2) then |
76b84bf0 AC |
2586 | return False; |
2587 | ||
27cdc66a RD |
2588 | -- For selected components, must have same prefix and selector |
2589 | ||
1e194575 AC |
2590 | elsif Nkind (Obj1) = N_Selected_Component then |
2591 | return Denotes_Same_Object (Prefix (Obj1), Prefix (Obj2)) | |
76b84bf0 | 2592 | and then |
1e194575 | 2593 | Entity (Selector_Name (Obj1)) = Entity (Selector_Name (Obj2)); |
76b84bf0 | 2594 | |
27cdc66a RD |
2595 | -- For explicit dereferences, prefixes must be same |
2596 | ||
1e194575 AC |
2597 | elsif Nkind (Obj1) = N_Explicit_Dereference then |
2598 | return Denotes_Same_Object (Prefix (Obj1), Prefix (Obj2)); | |
76b84bf0 | 2599 | |
27cdc66a RD |
2600 | -- For indexed components, prefixes and all subscripts must be the same |
2601 | ||
1e194575 AC |
2602 | elsif Nkind (Obj1) = N_Indexed_Component then |
2603 | if Denotes_Same_Object (Prefix (Obj1), Prefix (Obj2)) then | |
76b84bf0 AC |
2604 | declare |
2605 | Indx1 : Node_Id; | |
2606 | Indx2 : Node_Id; | |
2607 | ||
2608 | begin | |
1e194575 AC |
2609 | Indx1 := First (Expressions (Obj1)); |
2610 | Indx2 := First (Expressions (Obj2)); | |
76b84bf0 | 2611 | while Present (Indx1) loop |
27cdc66a | 2612 | |
66150d01 | 2613 | -- Indexes must denote the same static value or same object |
1e194575 AC |
2614 | |
2615 | if Is_OK_Static_Expression (Indx1) then | |
2616 | if not Is_OK_Static_Expression (Indx2) then | |
2617 | return False; | |
27cdc66a | 2618 | |
1e194575 AC |
2619 | elsif Expr_Value (Indx1) /= Expr_Value (Indx2) then |
2620 | return False; | |
2621 | end if; | |
2622 | ||
2623 | elsif not Denotes_Same_Object (Indx1, Indx2) then | |
76b84bf0 AC |
2624 | return False; |
2625 | end if; | |
2626 | ||
2627 | Next (Indx1); | |
2628 | Next (Indx2); | |
2629 | end loop; | |
2630 | ||
2631 | return True; | |
2632 | end; | |
2633 | else | |
2634 | return False; | |
2635 | end if; | |
2636 | ||
27cdc66a RD |
2637 | -- For slices, prefixes must match and bounds must match |
2638 | ||
1e194575 AC |
2639 | elsif Nkind (Obj1) = N_Slice |
2640 | and then Denotes_Same_Object (Prefix (Obj1), Prefix (Obj2)) | |
76b84bf0 AC |
2641 | then |
2642 | declare | |
2643 | Lo1, Lo2, Hi1, Hi2 : Node_Id; | |
2644 | ||
2645 | begin | |
1e194575 AC |
2646 | Get_Index_Bounds (Etype (Obj1), Lo1, Hi1); |
2647 | Get_Index_Bounds (Etype (Obj2), Lo2, Hi2); | |
76b84bf0 | 2648 | |
27cdc66a RD |
2649 | -- Check whether bounds are statically identical. There is no |
2650 | -- attempt to detect partial overlap of slices. | |
2651 | ||
76b84bf0 AC |
2652 | return Denotes_Same_Object (Lo1, Lo2) |
2653 | and then Denotes_Same_Object (Hi1, Hi2); | |
2654 | end; | |
2655 | ||
3b42c566 | 2656 | -- Literals will appear as indexes. Isn't this where we should check |
27cdc66a | 2657 | -- Known_At_Compile_Time at least if we are generating warnings ??? |
76b84bf0 | 2658 | |
1e194575 AC |
2659 | elsif Nkind (Obj1) = N_Integer_Literal then |
2660 | return Intval (Obj1) = Intval (Obj2); | |
76b84bf0 AC |
2661 | |
2662 | else | |
2663 | return False; | |
2664 | end if; | |
2665 | end Denotes_Same_Object; | |
2666 | ||
2667 | ------------------------- | |
2668 | -- Denotes_Same_Prefix -- | |
2669 | ------------------------- | |
2670 | ||
2671 | function Denotes_Same_Prefix (A1, A2 : Node_Id) return Boolean is | |
2672 | ||
2673 | begin | |
2674 | if Is_Entity_Name (A1) then | |
e771c085 AC |
2675 | if Nkind_In (A2, N_Selected_Component, N_Indexed_Component) |
2676 | and then not Is_Access_Type (Etype (A1)) | |
2677 | then | |
76b84bf0 AC |
2678 | return Denotes_Same_Object (A1, Prefix (A2)) |
2679 | or else Denotes_Same_Prefix (A1, Prefix (A2)); | |
2680 | else | |
2681 | return False; | |
2682 | end if; | |
2683 | ||
2684 | elsif Is_Entity_Name (A2) then | |
2685 | return Denotes_Same_Prefix (A2, A1); | |
2686 | ||
2687 | elsif Nkind_In (A1, N_Selected_Component, N_Indexed_Component, N_Slice) | |
65a07a30 RD |
2688 | and then |
2689 | Nkind_In (A2, N_Selected_Component, N_Indexed_Component, N_Slice) | |
76b84bf0 AC |
2690 | then |
2691 | declare | |
2692 | Root1, Root2 : Node_Id; | |
2693 | Depth1, Depth2 : Int := 0; | |
2694 | ||
2695 | begin | |
2696 | Root1 := Prefix (A1); | |
2697 | while not Is_Entity_Name (Root1) loop | |
2698 | if not Nkind_In | |
2699 | (Root1, N_Selected_Component, N_Indexed_Component) | |
2700 | then | |
2701 | return False; | |
2702 | else | |
2703 | Root1 := Prefix (Root1); | |
2704 | end if; | |
2705 | ||
2706 | Depth1 := Depth1 + 1; | |
2707 | end loop; | |
2708 | ||
2709 | Root2 := Prefix (A2); | |
2710 | while not Is_Entity_Name (Root2) loop | |
2711 | if not Nkind_In | |
2712 | (Root2, N_Selected_Component, N_Indexed_Component) | |
2713 | then | |
2714 | return False; | |
2715 | else | |
2716 | Root2 := Prefix (Root2); | |
2717 | end if; | |
2718 | ||
2719 | Depth2 := Depth2 + 1; | |
2720 | end loop; | |
2721 | ||
2722 | -- If both have the same depth and they do not denote the same | |
2723 | -- object, they are disjoint and not warning is needed. | |
2724 | ||
2725 | if Depth1 = Depth2 then | |
2726 | return False; | |
2727 | ||
2728 | elsif Depth1 > Depth2 then | |
2729 | Root1 := Prefix (A1); | |
2730 | for I in 1 .. Depth1 - Depth2 - 1 loop | |
2731 | Root1 := Prefix (Root1); | |
2732 | end loop; | |
2733 | ||
2734 | return Denotes_Same_Object (Root1, A2); | |
2735 | ||
2736 | else | |
2737 | Root2 := Prefix (A2); | |
2738 | for I in 1 .. Depth2 - Depth1 - 1 loop | |
2739 | Root2 := Prefix (Root2); | |
2740 | end loop; | |
2741 | ||
2742 | return Denotes_Same_Object (A1, Root2); | |
2743 | end if; | |
2744 | end; | |
2745 | ||
2746 | else | |
2747 | return False; | |
2748 | end if; | |
2749 | end Denotes_Same_Prefix; | |
2750 | ||
cb572b75 ST |
2751 | ---------------------- |
2752 | -- Denotes_Variable -- | |
2753 | ---------------------- | |
2754 | ||
2755 | function Denotes_Variable (N : Node_Id) return Boolean is | |
2756 | begin | |
2757 | return Is_Variable (N) and then Paren_Count (N) = 0; | |
2758 | end Denotes_Variable; | |
2759 | ||
996ae0b0 RK |
2760 | ----------------------------- |
2761 | -- Depends_On_Discriminant -- | |
2762 | ----------------------------- | |
2763 | ||
2764 | function Depends_On_Discriminant (N : Node_Id) return Boolean is | |
2765 | L : Node_Id; | |
2766 | H : Node_Id; | |
2767 | ||
2768 | begin | |
2769 | Get_Index_Bounds (N, L, H); | |
2770 | return Denotes_Discriminant (L) or else Denotes_Discriminant (H); | |
2771 | end Depends_On_Discriminant; | |
2772 | ||
2773 | ------------------------- | |
2774 | -- Designate_Same_Unit -- | |
2775 | ------------------------- | |
2776 | ||
2777 | function Designate_Same_Unit | |
2778 | (Name1 : Node_Id; | |
fbf5a39b | 2779 | Name2 : Node_Id) return Boolean |
996ae0b0 | 2780 | is |
fbf5a39b AC |
2781 | K1 : constant Node_Kind := Nkind (Name1); |
2782 | K2 : constant Node_Kind := Nkind (Name2); | |
996ae0b0 RK |
2783 | |
2784 | function Prefix_Node (N : Node_Id) return Node_Id; | |
2785 | -- Returns the parent unit name node of a defining program unit name | |
2786 | -- or the prefix if N is a selected component or an expanded name. | |
2787 | ||
2788 | function Select_Node (N : Node_Id) return Node_Id; | |
2789 | -- Returns the defining identifier node of a defining program unit | |
2790 | -- name or the selector node if N is a selected component or an | |
2791 | -- expanded name. | |
2792 | ||
fbf5a39b AC |
2793 | ----------------- |
2794 | -- Prefix_Node -- | |
2795 | ----------------- | |
2796 | ||
996ae0b0 RK |
2797 | function Prefix_Node (N : Node_Id) return Node_Id is |
2798 | begin | |
2799 | if Nkind (N) = N_Defining_Program_Unit_Name then | |
2800 | return Name (N); | |
2801 | ||
2802 | else | |
2803 | return Prefix (N); | |
2804 | end if; | |
2805 | end Prefix_Node; | |
2806 | ||
fbf5a39b AC |
2807 | ----------------- |
2808 | -- Select_Node -- | |
2809 | ----------------- | |
2810 | ||
996ae0b0 RK |
2811 | function Select_Node (N : Node_Id) return Node_Id is |
2812 | begin | |
2813 | if Nkind (N) = N_Defining_Program_Unit_Name then | |
2814 | return Defining_Identifier (N); | |
2815 | ||
2816 | else | |
2817 | return Selector_Name (N); | |
2818 | end if; | |
2819 | end Select_Node; | |
2820 | ||
2821 | -- Start of processing for Designate_Next_Unit | |
2822 | ||
2823 | begin | |
2824 | if (K1 = N_Identifier or else | |
2825 | K1 = N_Defining_Identifier) | |
2826 | and then | |
2827 | (K2 = N_Identifier or else | |
2828 | K2 = N_Defining_Identifier) | |
2829 | then | |
2830 | return Chars (Name1) = Chars (Name2); | |
2831 | ||
2832 | elsif | |
2833 | (K1 = N_Expanded_Name or else | |
2834 | K1 = N_Selected_Component or else | |
2835 | K1 = N_Defining_Program_Unit_Name) | |
2836 | and then | |
2837 | (K2 = N_Expanded_Name or else | |
2838 | K2 = N_Selected_Component or else | |
2839 | K2 = N_Defining_Program_Unit_Name) | |
2840 | then | |
2841 | return | |
2842 | (Chars (Select_Node (Name1)) = Chars (Select_Node (Name2))) | |
2843 | and then | |
2844 | Designate_Same_Unit (Prefix_Node (Name1), Prefix_Node (Name2)); | |
2845 | ||
2846 | else | |
2847 | return False; | |
2848 | end if; | |
2849 | end Designate_Same_Unit; | |
2850 | ||
cefce34c JM |
2851 | -------------------------- |
2852 | -- Enclosing_CPP_Parent -- | |
2853 | -------------------------- | |
2854 | ||
2855 | function Enclosing_CPP_Parent (Typ : Entity_Id) return Entity_Id is | |
2856 | Parent_Typ : Entity_Id := Typ; | |
2857 | ||
2858 | begin | |
2859 | while not Is_CPP_Class (Parent_Typ) | |
2860 | and then Etype (Parent_Typ) /= Parent_Typ | |
2861 | loop | |
2862 | Parent_Typ := Etype (Parent_Typ); | |
2863 | ||
2864 | if Is_Private_Type (Parent_Typ) then | |
2865 | Parent_Typ := Full_View (Base_Type (Parent_Typ)); | |
2866 | end if; | |
2867 | end loop; | |
2868 | ||
2869 | pragma Assert (Is_CPP_Class (Parent_Typ)); | |
2870 | return Parent_Typ; | |
2871 | end Enclosing_CPP_Parent; | |
2872 | ||
996ae0b0 RK |
2873 | ---------------------------- |
2874 | -- Enclosing_Generic_Body -- | |
2875 | ---------------------------- | |
2876 | ||
2877 | function Enclosing_Generic_Body | |
b8dc622e | 2878 | (N : Node_Id) return Node_Id |
996ae0b0 RK |
2879 | is |
2880 | P : Node_Id; | |
2881 | Decl : Node_Id; | |
2882 | Spec : Node_Id; | |
2883 | ||
2884 | begin | |
b8dc622e | 2885 | P := Parent (N); |
996ae0b0 RK |
2886 | while Present (P) loop |
2887 | if Nkind (P) = N_Package_Body | |
2888 | or else Nkind (P) = N_Subprogram_Body | |
2889 | then | |
2890 | Spec := Corresponding_Spec (P); | |
2891 | ||
2892 | if Present (Spec) then | |
2893 | Decl := Unit_Declaration_Node (Spec); | |
2894 | ||
2895 | if Nkind (Decl) = N_Generic_Package_Declaration | |
2896 | or else Nkind (Decl) = N_Generic_Subprogram_Declaration | |
2897 | then | |
2898 | return P; | |
2899 | end if; | |
2900 | end if; | |
2901 | end if; | |
2902 | ||
2903 | P := Parent (P); | |
2904 | end loop; | |
2905 | ||
2906 | return Empty; | |
2907 | end Enclosing_Generic_Body; | |
2908 | ||
b8dc622e JM |
2909 | ---------------------------- |
2910 | -- Enclosing_Generic_Unit -- | |
2911 | ---------------------------- | |
2912 | ||
2913 | function Enclosing_Generic_Unit | |
2914 | (N : Node_Id) return Node_Id | |
2915 | is | |
2916 | P : Node_Id; | |
2917 | Decl : Node_Id; | |
2918 | Spec : Node_Id; | |
2919 | ||
2920 | begin | |
2921 | P := Parent (N); | |
2922 | while Present (P) loop | |
2923 | if Nkind (P) = N_Generic_Package_Declaration | |
2924 | or else Nkind (P) = N_Generic_Subprogram_Declaration | |
2925 | then | |
2926 | return P; | |
2927 | ||
2928 | elsif Nkind (P) = N_Package_Body | |
2929 | or else Nkind (P) = N_Subprogram_Body | |
2930 | then | |
2931 | Spec := Corresponding_Spec (P); | |
2932 | ||
2933 | if Present (Spec) then | |
2934 | Decl := Unit_Declaration_Node (Spec); | |
2935 | ||
2936 | if Nkind (Decl) = N_Generic_Package_Declaration | |
2937 | or else Nkind (Decl) = N_Generic_Subprogram_Declaration | |
2938 | then | |
2939 | return Decl; | |
2940 | end if; | |
2941 | end if; | |
2942 | end if; | |
2943 | ||
2944 | P := Parent (P); | |
2945 | end loop; | |
2946 | ||
2947 | return Empty; | |
2948 | end Enclosing_Generic_Unit; | |
2949 | ||
996ae0b0 RK |
2950 | ------------------------------- |
2951 | -- Enclosing_Lib_Unit_Entity -- | |
2952 | ------------------------------- | |
2953 | ||
2954 | function Enclosing_Lib_Unit_Entity return Entity_Id is | |
9b0986f8 | 2955 | Unit_Entity : Entity_Id; |
996ae0b0 RK |
2956 | |
2957 | begin | |
2958 | -- Look for enclosing library unit entity by following scope links. | |
2959 | -- Equivalent to, but faster than indexing through the scope stack. | |
2960 | ||
9b0986f8 | 2961 | Unit_Entity := Current_Scope; |
996ae0b0 RK |
2962 | while (Present (Scope (Unit_Entity)) |
2963 | and then Scope (Unit_Entity) /= Standard_Standard) | |
2964 | and not Is_Child_Unit (Unit_Entity) | |
2965 | loop | |
2966 | Unit_Entity := Scope (Unit_Entity); | |
2967 | end loop; | |
2968 | ||
2969 | return Unit_Entity; | |
2970 | end Enclosing_Lib_Unit_Entity; | |
2971 | ||
2972 | ----------------------------- | |
2973 | -- Enclosing_Lib_Unit_Node -- | |
2974 | ----------------------------- | |
2975 | ||
2976 | function Enclosing_Lib_Unit_Node (N : Node_Id) return Node_Id is | |
9b0986f8 | 2977 | Current_Node : Node_Id; |
996ae0b0 RK |
2978 | |
2979 | begin | |
9b0986f8 | 2980 | Current_Node := N; |
996ae0b0 RK |
2981 | while Present (Current_Node) |
2982 | and then Nkind (Current_Node) /= N_Compilation_Unit | |
2983 | loop | |
2984 | Current_Node := Parent (Current_Node); | |
2985 | end loop; | |
2986 | ||
2987 | if Nkind (Current_Node) /= N_Compilation_Unit then | |
2988 | return Empty; | |
2989 | end if; | |
2990 | ||
2991 | return Current_Node; | |
2992 | end Enclosing_Lib_Unit_Node; | |
2993 | ||
db72f10a AC |
2994 | ----------------------- |
2995 | -- Enclosing_Package -- | |
2996 | ----------------------- | |
2997 | ||
2998 | function Enclosing_Package (E : Entity_Id) return Entity_Id is | |
2999 | Dynamic_Scope : constant Entity_Id := Enclosing_Dynamic_Scope (E); | |
3000 | ||
3001 | begin | |
3002 | if Dynamic_Scope = Standard_Standard then | |
3003 | return Standard_Standard; | |
3004 | ||
3005 | elsif Dynamic_Scope = Empty then | |
3006 | return Empty; | |
3007 | ||
3008 | elsif Ekind_In (Dynamic_Scope, E_Package, E_Package_Body, | |
3009 | E_Generic_Package) | |
3010 | then | |
3011 | return Dynamic_Scope; | |
3012 | ||
3013 | else | |
3014 | return Enclosing_Package (Dynamic_Scope); | |
3015 | end if; | |
3016 | end Enclosing_Package; | |
3017 | ||
996ae0b0 RK |
3018 | -------------------------- |
3019 | -- Enclosing_Subprogram -- | |
3020 | -------------------------- | |
3021 | ||
3022 | function Enclosing_Subprogram (E : Entity_Id) return Entity_Id is | |
3023 | Dynamic_Scope : constant Entity_Id := Enclosing_Dynamic_Scope (E); | |
3024 | ||
3025 | begin | |
3026 | if Dynamic_Scope = Standard_Standard then | |
3027 | return Empty; | |
3028 | ||
67ce0d7e RD |
3029 | elsif Dynamic_Scope = Empty then |
3030 | return Empty; | |
3031 | ||
996ae0b0 RK |
3032 | elsif Ekind (Dynamic_Scope) = E_Subprogram_Body then |
3033 | return Corresponding_Spec (Parent (Parent (Dynamic_Scope))); | |
3034 | ||
9e87a68d ES |
3035 | elsif Ekind (Dynamic_Scope) = E_Block |
3036 | or else Ekind (Dynamic_Scope) = E_Return_Statement | |
3037 | then | |
996ae0b0 RK |
3038 | return Enclosing_Subprogram (Dynamic_Scope); |
3039 | ||
3040 | elsif Ekind (Dynamic_Scope) = E_Task_Type then | |
3041 | return Get_Task_Body_Procedure (Dynamic_Scope); | |
3042 | ||
a780db15 AC |
3043 | elsif Ekind (Dynamic_Scope) = E_Limited_Private_Type |
3044 | and then Present (Full_View (Dynamic_Scope)) | |
3045 | and then Ekind (Full_View (Dynamic_Scope)) = E_Task_Type | |
3046 | then | |
3047 | return Get_Task_Body_Procedure (Full_View (Dynamic_Scope)); | |
3048 | ||
4519314c AC |
3049 | -- No body is generated if the protected operation is eliminated |
3050 | ||
3051 | elsif Convention (Dynamic_Scope) = Convention_Protected | |
3052 | and then not Is_Eliminated (Dynamic_Scope) | |
3053 | and then Present (Protected_Body_Subprogram (Dynamic_Scope)) | |
3054 | then | |
996ae0b0 RK |
3055 | return Protected_Body_Subprogram (Dynamic_Scope); |
3056 | ||
3057 | else | |
3058 | return Dynamic_Scope; | |
3059 | end if; | |
3060 | end Enclosing_Subprogram; | |
3061 | ||
3062 | ------------------------ | |
3063 | -- Ensure_Freeze_Node -- | |
3064 | ------------------------ | |
3065 | ||
3066 | procedure Ensure_Freeze_Node (E : Entity_Id) is | |
3067 | FN : Node_Id; | |
3068 | ||
3069 | begin | |
3070 | if No (Freeze_Node (E)) then | |
3071 | FN := Make_Freeze_Entity (Sloc (E)); | |
3072 | Set_Has_Delayed_Freeze (E); | |
3073 | Set_Freeze_Node (E, FN); | |
3074 | Set_Access_Types_To_Process (FN, No_Elist); | |
3075 | Set_TSS_Elist (FN, No_Elist); | |
3076 | Set_Entity (FN, E); | |
3077 | end if; | |
3078 | end Ensure_Freeze_Node; | |
3079 | ||
3080 | ---------------- | |
3081 | -- Enter_Name -- | |
3082 | ---------------- | |
3083 | ||
b8dc622e | 3084 | procedure Enter_Name (Def_Id : Entity_Id) is |
996ae0b0 RK |
3085 | C : constant Entity_Id := Current_Entity (Def_Id); |
3086 | E : constant Entity_Id := Current_Entity_In_Scope (Def_Id); | |
3087 | S : constant Entity_Id := Current_Scope; | |
3088 | ||
3089 | begin | |
3090 | Generate_Definition (Def_Id); | |
3091 | ||
3092 | -- Add new name to current scope declarations. Check for duplicate | |
3093 | -- declaration, which may or may not be a genuine error. | |
3094 | ||
3095 | if Present (E) then | |
3096 | ||
3097 | -- Case of previous entity entered because of a missing declaration | |
3098 | -- or else a bad subtype indication. Best is to use the new entity, | |
3099 | -- and make the previous one invisible. | |
3100 | ||
3101 | if Etype (E) = Any_Type then | |
3102 | Set_Is_Immediately_Visible (E, False); | |
3103 | ||
3104 | -- Case of renaming declaration constructed for package instances. | |
3105 | -- if there is an explicit declaration with the same identifier, | |
3106 | -- the renaming is not immediately visible any longer, but remains | |
3107 | -- visible through selected component notation. | |
3108 | ||
3109 | elsif Nkind (Parent (E)) = N_Package_Renaming_Declaration | |
3110 | and then not Comes_From_Source (E) | |
3111 | then | |
3112 | Set_Is_Immediately_Visible (E, False); | |
3113 | ||
3114 | -- The new entity may be the package renaming, which has the same | |
3115 | -- same name as a generic formal which has been seen already. | |
3116 | ||
3117 | elsif Nkind (Parent (Def_Id)) = N_Package_Renaming_Declaration | |
3118 | and then not Comes_From_Source (Def_Id) | |
3119 | then | |
3120 | Set_Is_Immediately_Visible (E, False); | |
3121 | ||
3122 | -- For a fat pointer corresponding to a remote access to subprogram, | |
3123 | -- we use the same identifier as the RAS type, so that the proper | |
3124 | -- name appears in the stub. This type is only retrieved through | |
3125 | -- the RAS type and never by visibility, and is not added to the | |
3126 | -- visibility list (see below). | |
3127 | ||
3128 | elsif Nkind (Parent (Def_Id)) = N_Full_Type_Declaration | |
3129 | and then Present (Corresponding_Remote_Type (Def_Id)) | |
3130 | then | |
3131 | null; | |
3132 | ||
996ae0b0 RK |
3133 | -- Case of an implicit operation or derived literal. The new entity |
3134 | -- hides the implicit one, which is removed from all visibility, | |
3135 | -- i.e. the entity list of its scope, and homonym chain of its name. | |
3136 | ||
246d2ceb | 3137 | elsif (Is_Overloadable (E) and then Is_Inherited_Operation (E)) |
996ae0b0 | 3138 | or else Is_Internal (E) |
996ae0b0 RK |
3139 | then |
3140 | declare | |
3141 | Prev : Entity_Id; | |
3142 | Prev_Vis : Entity_Id; | |
fbf5a39b | 3143 | Decl : constant Node_Id := Parent (E); |
996ae0b0 RK |
3144 | |
3145 | begin | |
3146 | -- If E is an implicit declaration, it cannot be the first | |
3147 | -- entity in the scope. | |
3148 | ||
3149 | Prev := First_Entity (Current_Scope); | |
fbf5a39b AC |
3150 | while Present (Prev) |
3151 | and then Next_Entity (Prev) /= E | |
3152 | loop | |
996ae0b0 RK |
3153 | Next_Entity (Prev); |
3154 | end loop; | |
3155 | ||
fbf5a39b | 3156 | if No (Prev) then |
996ae0b0 | 3157 | |
fbf5a39b AC |
3158 | -- If E is not on the entity chain of the current scope, |
3159 | -- it is an implicit declaration in the generic formal | |
3160 | -- part of a generic subprogram. When analyzing the body, | |
3161 | -- the generic formals are visible but not on the entity | |
3162 | -- chain of the subprogram. The new entity will become | |
3163 | -- the visible one in the body. | |
3164 | ||
3165 | pragma Assert | |
3166 | (Nkind (Parent (Decl)) = N_Generic_Subprogram_Declaration); | |
3167 | null; | |
996ae0b0 | 3168 | |
996ae0b0 | 3169 | else |
fbf5a39b | 3170 | Set_Next_Entity (Prev, Next_Entity (E)); |
996ae0b0 | 3171 | |
fbf5a39b AC |
3172 | if No (Next_Entity (Prev)) then |
3173 | Set_Last_Entity (Current_Scope, Prev); | |
3174 | end if; | |
3175 | ||
3176 | if E = Current_Entity (E) then | |
3177 | Prev_Vis := Empty; | |
3178 | ||
3179 | else | |
3180 | Prev_Vis := Current_Entity (E); | |
3181 | while Homonym (Prev_Vis) /= E loop | |
3182 | Prev_Vis := Homonym (Prev_Vis); | |
3183 | end loop; | |
3184 | end if; | |
996ae0b0 | 3185 | |
fbf5a39b | 3186 | if Present (Prev_Vis) then |
996ae0b0 | 3187 | |
fbf5a39b | 3188 | -- Skip E in the visibility chain |
996ae0b0 | 3189 | |
fbf5a39b AC |
3190 | Set_Homonym (Prev_Vis, Homonym (E)); |
3191 | ||
3192 | else | |
3193 | Set_Name_Entity_Id (Chars (E), Homonym (E)); | |
3194 | end if; | |
996ae0b0 RK |
3195 | end if; |
3196 | end; | |
3197 | ||
3198 | -- This section of code could use a comment ??? | |
3199 | ||
3200 | elsif Present (Etype (E)) | |
3201 | and then Is_Concurrent_Type (Etype (E)) | |
3202 | and then E = Def_Id | |
3203 | then | |
3204 | return; | |
3205 | ||
ce4a6e84 RD |
3206 | -- If the homograph is a protected component renaming, it should not |
3207 | -- be hiding the current entity. Such renamings are treated as weak | |
3208 | -- declarations. | |
3209 | ||
3210 | elsif Is_Prival (E) then | |
3211 | Set_Is_Immediately_Visible (E, False); | |
3212 | ||
3213 | -- In this case the current entity is a protected component renaming. | |
3214 | -- Perform minimal decoration by setting the scope and return since | |
3215 | -- the prival should not be hiding other visible entities. | |
3216 | ||
3217 | elsif Is_Prival (Def_Id) then | |
3218 | Set_Scope (Def_Id, Current_Scope); | |
3219 | return; | |
3220 | ||
ff2efe85 AC |
3221 | -- Analogous to privals, the discriminal generated for an entry index |
3222 | -- parameter acts as a weak declaration. Perform minimal decoration | |
3223 | -- to avoid bogus errors. | |
ce4a6e84 RD |
3224 | |
3225 | elsif Is_Discriminal (Def_Id) | |
3226 | and then Ekind (Discriminal_Link (Def_Id)) = E_Entry_Index_Parameter | |
3227 | then | |
3228 | Set_Scope (Def_Id, Current_Scope); | |
21024a39 RD |
3229 | return; |
3230 | ||
ff2efe85 AC |
3231 | -- In the body or private part of an instance, a type extension may |
3232 | -- introduce a component with the same name as that of an actual. The | |
3233 | -- legality rule is not enforced, but the semantics of the full type | |
3234 | -- with two components of same name are not clear at this point??? | |
996ae0b0 | 3235 | |
ce4a6e84 | 3236 | elsif In_Instance_Not_Visible then |
996ae0b0 RK |
3237 | null; |
3238 | ||
3239 | -- When compiling a package body, some child units may have become | |
3240 | -- visible. They cannot conflict with local entities that hide them. | |
3241 | ||
3242 | elsif Is_Child_Unit (E) | |
3243 | and then In_Open_Scopes (Scope (E)) | |
3244 | and then not Is_Immediately_Visible (E) | |
3245 | then | |
3246 | null; | |
3247 | ||
ff2efe85 AC |
3248 | -- Conversely, with front-end inlining we may compile the parent body |
3249 | -- first, and a child unit subsequently. The context is now the | |
3250 | -- parent spec, and body entities are not visible. | |
996ae0b0 RK |
3251 | |
3252 | elsif Is_Child_Unit (Def_Id) | |
3253 | and then Is_Package_Body_Entity (E) | |
3254 | and then not In_Package_Body (Current_Scope) | |
3255 | then | |
3256 | null; | |
3257 | ||
3258 | -- Case of genuine duplicate declaration | |
3259 | ||
3260 | else | |
3261 | Error_Msg_Sloc := Sloc (E); | |
3262 | ||
3263 | -- If the previous declaration is an incomplete type declaration | |
ff2efe85 AC |
3264 | -- this may be an attempt to complete it with a private type. The |
3265 | -- following avoids confusing cascaded errors. | |
996ae0b0 RK |
3266 | |
3267 | if Nkind (Parent (E)) = N_Incomplete_Type_Declaration | |
3268 | and then Nkind (Parent (Def_Id)) = N_Private_Type_Declaration | |
3269 | then | |
3270 | Error_Msg_N | |
ce4a6e84 RD |
3271 | ("incomplete type cannot be completed with a private " & |
3272 | "declaration", Parent (Def_Id)); | |
996ae0b0 RK |
3273 | Set_Is_Immediately_Visible (E, False); |
3274 | Set_Full_View (E, Def_Id); | |
3275 | ||
ce4a6e84 RD |
3276 | -- An inherited component of a record conflicts with a new |
3277 | -- discriminant. The discriminant is inserted first in the scope, | |
3278 | -- but the error should be posted on it, not on the component. | |
3279 | ||
996ae0b0 RK |
3280 | elsif Ekind (E) = E_Discriminant |
3281 | and then Present (Scope (Def_Id)) | |
3282 | and then Scope (Def_Id) /= Current_Scope | |
3283 | then | |
996ae0b0 RK |
3284 | Error_Msg_Sloc := Sloc (Def_Id); |
3285 | Error_Msg_N ("& conflicts with declaration#", E); | |
3286 | return; | |
3287 | ||
ff2efe85 AC |
3288 | -- If the name of the unit appears in its own context clause, a |
3289 | -- dummy package with the name has already been created, and the | |
3290 | -- error emitted. Try to continue quietly. | |
dfc69d80 ES |
3291 | |
3292 | elsif Error_Posted (E) | |
3293 | and then Sloc (E) = No_Location | |
3294 | and then Nkind (Parent (E)) = N_Package_Specification | |
3295 | and then Current_Scope = Standard_Standard | |
3296 | then | |
3297 | Set_Scope (Def_Id, Current_Scope); | |
3298 | return; | |
3299 | ||
996ae0b0 RK |
3300 | else |
3301 | Error_Msg_N ("& conflicts with declaration#", Def_Id); | |
3302 | ||
3303 | -- Avoid cascaded messages with duplicate components in | |
3304 | -- derived types. | |
3305 | ||
8a95f4e8 | 3306 | if Ekind_In (E, E_Component, E_Discriminant) then |
996ae0b0 RK |
3307 | return; |
3308 | end if; | |
3309 | end if; | |
3310 | ||
ce4a6e84 RD |
3311 | if Nkind (Parent (Parent (Def_Id))) = |
3312 | N_Generic_Subprogram_Declaration | |
996ae0b0 RK |
3313 | and then Def_Id = |
3314 | Defining_Entity (Specification (Parent (Parent (Def_Id)))) | |
3315 | then | |
3316 | Error_Msg_N ("\generic units cannot be overloaded", Def_Id); | |
3317 | end if; | |
3318 | ||
ff2efe85 AC |
3319 | -- If entity is in standard, then we are in trouble, because it |
3320 | -- means that we have a library package with a duplicated name. | |
3321 | -- That's hard to recover from, so abort! | |
996ae0b0 RK |
3322 | |
3323 | if S = Standard_Standard then | |
3324 | raise Unrecoverable_Error; | |
3325 | ||
3326 | -- Otherwise we continue with the declaration. Having two | |
3327 | -- identical declarations should not cause us too much trouble! | |
3328 | ||
3329 | else | |
3330 | null; | |
3331 | end if; | |
3332 | end if; | |
3333 | end if; | |
3334 | ||
ff2efe85 | 3335 | -- If we fall through, declaration is OK, at least OK enough to continue |
996ae0b0 | 3336 | |
ff2efe85 AC |
3337 | -- If Def_Id is a discriminant or a record component we are in the midst |
3338 | -- of inheriting components in a derived record definition. Preserve | |
3339 | -- their Ekind and Etype. | |
996ae0b0 | 3340 | |
8a95f4e8 | 3341 | if Ekind_In (Def_Id, E_Discriminant, E_Component) then |
996ae0b0 RK |
3342 | null; |
3343 | ||
ff2efe85 AC |
3344 | -- If a type is already set, leave it alone (happens when a type |
3345 | -- declaration is reanalyzed following a call to the optimizer). | |
996ae0b0 RK |
3346 | |
3347 | elsif Present (Etype (Def_Id)) then | |
3348 | null; | |
3349 | ||
3350 | -- Otherwise, the kind E_Void insures that premature uses of the entity | |
3351 | -- will be detected. Any_Type insures that no cascaded errors will occur | |
3352 | ||
3353 | else | |
3354 | Set_Ekind (Def_Id, E_Void); | |
3355 | Set_Etype (Def_Id, Any_Type); | |
3356 | end if; | |
3357 | ||
3358 | -- Inherited discriminants and components in derived record types are | |
3359 | -- immediately visible. Itypes are not. | |
3360 | ||
8a95f4e8 | 3361 | if Ekind_In (Def_Id, E_Discriminant, E_Component) |
996ae0b0 RK |
3362 | or else (No (Corresponding_Remote_Type (Def_Id)) |
3363 | and then not Is_Itype (Def_Id)) | |
3364 | then | |
3365 | Set_Is_Immediately_Visible (Def_Id); | |
3366 | Set_Current_Entity (Def_Id); | |
3367 | end if; | |
3368 | ||
3369 | Set_Homonym (Def_Id, C); | |
3370 | Append_Entity (Def_Id, S); | |
3371 | Set_Public_Status (Def_Id); | |
3372 | ||
2ba431e5 | 3373 | -- Declaring a homonym is not allowed in SPARK ... |
0d53d36b | 3374 | |
fe5d3068 | 3375 | if Present (C) |
2ba431e5 | 3376 | and then Restriction_Check_Required (SPARK) |
db72f10a | 3377 | then |
0d53d36b | 3378 | |
db72f10a AC |
3379 | declare |
3380 | Enclosing_Subp : constant Node_Id := Enclosing_Subprogram (Def_Id); | |
3381 | Enclosing_Pack : constant Node_Id := Enclosing_Package (Def_Id); | |
3382 | Other_Scope : constant Node_Id := Enclosing_Dynamic_Scope (C); | |
3383 | begin | |
0d53d36b | 3384 | |
db72f10a AC |
3385 | -- ... unless the new declaration is in a subprogram, and the |
3386 | -- visible declaration is a variable declaration or a parameter | |
3387 | -- specification outside that subprogram. | |
0d53d36b | 3388 | |
db72f10a AC |
3389 | if Present (Enclosing_Subp) |
3390 | and then Nkind_In (Parent (C), N_Object_Declaration, | |
3391 | N_Parameter_Specification) | |
3392 | and then not Scope_Within_Or_Same (Other_Scope, Enclosing_Subp) | |
3393 | then | |
3394 | null; | |
0d53d36b | 3395 | |
db72f10a AC |
3396 | -- ... or the new declaration is in a package, and the visible |
3397 | -- declaration occurs outside that package. | |
0d53d36b | 3398 | |
db72f10a AC |
3399 | elsif Present (Enclosing_Pack) |
3400 | and then not Scope_Within_Or_Same (Other_Scope, Enclosing_Pack) | |
3401 | then | |
3402 | null; | |
0d53d36b | 3403 | |
db72f10a AC |
3404 | -- ... or the new declaration is a component declaration in a |
3405 | -- record type definition. | |
0d53d36b | 3406 | |
db72f10a AC |
3407 | elsif Nkind (Parent (Def_Id)) = N_Component_Declaration then |
3408 | null; | |
0d53d36b | 3409 | |
db72f10a AC |
3410 | -- Don't issue error for non-source entities |
3411 | ||
3412 | elsif Comes_From_Source (Def_Id) | |
3413 | and then Comes_From_Source (C) | |
3414 | then | |
3415 | Error_Msg_Sloc := Sloc (C); | |
2ba431e5 | 3416 | Check_SPARK_Restriction |
db72f10a AC |
3417 | ("redeclaration of identifier &#", Def_Id); |
3418 | end if; | |
3419 | end; | |
0d53d36b AC |
3420 | end if; |
3421 | ||
996ae0b0 RK |
3422 | -- Warn if new entity hides an old one |
3423 | ||
9b0986f8 RD |
3424 | if Warn_On_Hiding and then Present (C) |
3425 | ||
9e87a68d ES |
3426 | -- Don't warn for record components since they always have a well |
3427 | -- defined scope which does not confuse other uses. Note that in | |
3428 | -- some cases, Ekind has not been set yet. | |
3429 | ||
3430 | and then Ekind (C) /= E_Component | |
3431 | and then Ekind (C) /= E_Discriminant | |
3432 | and then Nkind (Parent (C)) /= N_Component_Declaration | |
3433 | and then Ekind (Def_Id) /= E_Component | |
3434 | and then Ekind (Def_Id) /= E_Discriminant | |
3435 | and then Nkind (Parent (Def_Id)) /= N_Component_Declaration | |
3436 | ||
9b0986f8 RD |
3437 | -- Don't warn for one character variables. It is too common to use |
3438 | -- such variables as locals and will just cause too many false hits. | |
3439 | ||
3440 | and then Length_Of_Name (Chars (C)) /= 1 | |
3441 | ||
f3d57416 | 3442 | -- Don't warn for non-source entities |
9b0986f8 RD |
3443 | |
3444 | and then Comes_From_Source (C) | |
3445 | and then Comes_From_Source (Def_Id) | |
3446 | ||
3447 | -- Don't warn unless entity in question is in extended main source | |
3448 | ||
3449 | and then In_Extended_Main_Source_Unit (Def_Id) | |
3450 | ||
ff2efe85 AC |
3451 | -- Finally, the hidden entity must be either immediately visible or |
3452 | -- use visible (i.e. from a used package). | |
9b0986f8 RD |
3453 | |
3454 | and then | |
3455 | (Is_Immediately_Visible (C) | |
3456 | or else | |
3457 | Is_Potentially_Use_Visible (C)) | |
996ae0b0 RK |
3458 | then |
3459 | Error_Msg_Sloc := Sloc (C); | |
3460 | Error_Msg_N ("declaration hides &#?", Def_Id); | |
3461 | end if; | |
996ae0b0 RK |
3462 | end Enter_Name; |
3463 | ||
fbf5a39b AC |
3464 | -------------------------- |
3465 | -- Explain_Limited_Type -- | |
3466 | -------------------------- | |
3467 | ||
3468 | procedure Explain_Limited_Type (T : Entity_Id; N : Node_Id) is | |
3469 | C : Entity_Id; | |
3470 | ||
3471 | begin | |
3472 | -- For array, component type must be limited | |
3473 | ||
3474 | if Is_Array_Type (T) then | |
3475 | Error_Msg_Node_2 := T; | |
3476 | Error_Msg_NE | |
9b0986f8 | 3477 | ("\component type& of type& is limited", N, Component_Type (T)); |
fbf5a39b AC |
3478 | Explain_Limited_Type (Component_Type (T), N); |
3479 | ||
3480 | elsif Is_Record_Type (T) then | |
3481 | ||
3482 | -- No need for extra messages if explicit limited record | |
3483 | ||
3484 | if Is_Limited_Record (Base_Type (T)) then | |
3485 | return; | |
3486 | end if; | |
3487 | ||
130c236a TQ |
3488 | -- Otherwise find a limited component. Check only components that |
3489 | -- come from source, or inherited components that appear in the | |
3490 | -- source of the ancestor. | |
fbf5a39b AC |
3491 | |
3492 | C := First_Component (T); | |
3493 | while Present (C) loop | |
1c6c6771 | 3494 | if Is_Limited_Type (Etype (C)) |
130c236a TQ |
3495 | and then |
3496 | (Comes_From_Source (C) | |
3497 | or else | |
3498 | (Present (Original_Record_Component (C)) | |
3499 | and then | |
3500 | Comes_From_Source (Original_Record_Component (C)))) | |
1c6c6771 | 3501 | then |
fbf5a39b AC |
3502 | Error_Msg_Node_2 := T; |
3503 | Error_Msg_NE ("\component& of type& has limited type", N, C); | |
3504 | Explain_Limited_Type (Etype (C), N); | |
3505 | return; | |
3506 | end if; | |
3507 | ||
3508 | Next_Component (C); | |
3509 | end loop; | |
3510 | ||
1c6c6771 ES |
3511 | -- The type may be declared explicitly limited, even if no component |
3512 | -- of it is limited, in which case we fall out of the loop. | |
fbf5a39b AC |
3513 | return; |
3514 | end if; | |
3515 | end Explain_Limited_Type; | |
3516 | ||
7f0e4cdb BD |
3517 | ----------------- |
3518 | -- Find_Actual -- | |
3519 | ----------------- | |
67ce0d7e | 3520 | |
7f0e4cdb BD |
3521 | procedure Find_Actual |
3522 | (N : Node_Id; | |
3523 | Formal : out Entity_Id; | |
3524 | Call : out Node_Id) | |
67ce0d7e RD |
3525 | is |
3526 | Parnt : constant Node_Id := Parent (N); | |
67ce0d7e RD |
3527 | Actual : Node_Id; |
3528 | ||
3529 | begin | |
3530 | if (Nkind (Parnt) = N_Indexed_Component | |
3531 | or else | |
3532 | Nkind (Parnt) = N_Selected_Component) | |
3533 | and then N = Prefix (Parnt) | |
3534 | then | |
7f0e4cdb | 3535 | Find_Actual (Parnt, Formal, Call); |
67ce0d7e RD |
3536 | return; |
3537 | ||
3538 | elsif Nkind (Parnt) = N_Parameter_Association | |
3539 | and then N = Explicit_Actual_Parameter (Parnt) | |
3540 | then | |
3541 | Call := Parent (Parnt); | |
3542 | ||
e24329cd | 3543 | elsif Nkind_In (Parnt, N_Procedure_Call_Statement, N_Function_Call) then |
67ce0d7e RD |
3544 | Call := Parnt; |
3545 | ||
3546 | else | |
7f0e4cdb BD |
3547 | Formal := Empty; |
3548 | Call := Empty; | |
67ce0d7e RD |
3549 | return; |
3550 | end if; | |
3551 | ||
7f0e4cdb BD |
3552 | -- If we have a call to a subprogram look for the parameter. Note that |
3553 | -- we exclude overloaded calls, since we don't know enough to be sure | |
3554 | -- of giving the right answer in this case. | |
67ce0d7e RD |
3555 | |
3556 | if Is_Entity_Name (Name (Call)) | |
3557 | and then Present (Entity (Name (Call))) | |
3558 | and then Is_Overloadable (Entity (Name (Call))) | |
7f0e4cdb | 3559 | and then not Is_Overloaded (Name (Call)) |
67ce0d7e RD |
3560 | then |
3561 | -- Fall here if we are definitely a parameter | |
3562 | ||
3563 | Actual := First_Actual (Call); | |
3564 | Formal := First_Formal (Entity (Name (Call))); | |
3565 | while Present (Formal) and then Present (Actual) loop | |
3566 | if Actual = N then | |
67ce0d7e RD |
3567 | return; |
3568 | else | |
3569 | Actual := Next_Actual (Actual); | |
3570 | Formal := Next_Formal (Formal); | |
3571 | end if; | |
3572 | end loop; | |
3573 | end if; | |
3574 | ||
3575 | -- Fall through here if we did not find matching actual | |
3576 | ||
7f0e4cdb BD |
3577 | Formal := Empty; |
3578 | Call := Empty; | |
3579 | end Find_Actual; | |
67ce0d7e | 3580 | |
5a153b27 AC |
3581 | --------------------------- |
3582 | -- Find_Body_Discriminal -- | |
3583 | --------------------------- | |
3584 | ||
3585 | function Find_Body_Discriminal | |
3586 | (Spec_Discriminant : Entity_Id) return Entity_Id | |
3587 | is | |
3588 | pragma Assert (Is_Concurrent_Record_Type (Scope (Spec_Discriminant))); | |
6ca9ec9c | 3589 | |
5a153b27 AC |
3590 | Tsk : constant Entity_Id := |
3591 | Corresponding_Concurrent_Type (Scope (Spec_Discriminant)); | |
3592 | Disc : Entity_Id; | |
6ca9ec9c | 3593 | |
5a153b27 AC |
3594 | begin |
3595 | -- Find discriminant of original concurrent type, and use its current | |
3596 | -- discriminal, which is the renaming within the task/protected body. | |
3597 | ||
3598 | Disc := First_Discriminant (Tsk); | |
3599 | while Present (Disc) loop | |
3600 | if Chars (Disc) = Chars (Spec_Discriminant) then | |
5a153b27 AC |
3601 | return Discriminal (Disc); |
3602 | end if; | |
3603 | ||
3604 | Next_Discriminant (Disc); | |
3605 | end loop; | |
3606 | ||
3607 | -- That loop should always succeed in finding a matching entry and | |
3608 | -- returning. Fatal error if not. | |
3609 | ||
3610 | raise Program_Error; | |
3611 | end Find_Body_Discriminal; | |
3612 | ||
996ae0b0 RK |
3613 | ------------------------------------- |
3614 | -- Find_Corresponding_Discriminant -- | |
3615 | ------------------------------------- | |
3616 | ||
3617 | function Find_Corresponding_Discriminant | |
fbf5a39b AC |
3618 | (Id : Node_Id; |
3619 | Typ : Entity_Id) return Entity_Id | |
996ae0b0 RK |
3620 | is |
3621 | Par_Disc : Entity_Id; | |
3622 | Old_Disc : Entity_Id; | |
3623 | New_Disc : Entity_Id; | |
3624 | ||
3625 | begin | |
3626 | Par_Disc := Original_Record_Component (Original_Discriminant (Id)); | |
0c644933 AC |
3627 | |
3628 | -- The original type may currently be private, and the discriminant | |
3629 | -- only appear on its full view. | |
3630 | ||
3631 | if Is_Private_Type (Scope (Par_Disc)) | |
3632 | and then not Has_Discriminants (Scope (Par_Disc)) | |
3633 | and then Present (Full_View (Scope (Par_Disc))) | |
3634 | then | |
3635 | Old_Disc := First_Discriminant (Full_View (Scope (Par_Disc))); | |
3636 | else | |
3637 | Old_Disc := First_Discriminant (Scope (Par_Disc)); | |
3638 | end if; | |
996ae0b0 RK |
3639 | |
3640 | if Is_Class_Wide_Type (Typ) then | |
3641 | New_Disc := First_Discriminant (Root_Type (Typ)); | |
3642 | else | |
3643 | New_Disc := First_Discriminant (Typ); | |
3644 | end if; | |
3645 | ||
3646 | while Present (Old_Disc) and then Present (New_Disc) loop | |
3647 | if Old_Disc = Par_Disc then | |
3648 | return New_Disc; | |
3649 | else | |
3650 | Next_Discriminant (Old_Disc); | |
3651 | Next_Discriminant (New_Disc); | |
3652 | end if; | |
3653 | end loop; | |
3654 | ||
3655 | -- Should always find it | |
3656 | ||
3657 | raise Program_Error; | |
3658 | end Find_Corresponding_Discriminant; | |
3659 | ||
31b5873d | 3660 | -------------------------- |
f4cd2542 | 3661 | -- Find_Overlaid_Entity -- |
31b5873d GD |
3662 | -------------------------- |
3663 | ||
f4cd2542 | 3664 | procedure Find_Overlaid_Entity |
ef76538f | 3665 | (N : Node_Id; |
f4cd2542 EB |
3666 | Ent : out Entity_Id; |
3667 | Off : out Boolean) | |
3668 | is | |
3669 | Expr : Node_Id; | |
31b5873d GD |
3670 | |
3671 | begin | |
3672 | -- We are looking for one of the two following forms: | |
3673 | ||
3674 | -- for X'Address use Y'Address | |
3675 | ||
3676 | -- or | |
3677 | ||
3678 | -- Const : constant Address := expr; | |
3679 | -- ... | |
3680 | -- for X'Address use Const; | |
3681 | ||
3682 | -- In the second case, the expr is either Y'Address, or recursively a | |
3683 | -- constant that eventually references Y'Address. | |
3684 | ||
f4cd2542 EB |
3685 | Ent := Empty; |
3686 | Off := False; | |
3687 | ||
31b5873d GD |
3688 | if Nkind (N) = N_Attribute_Definition_Clause |
3689 | and then Chars (N) = Name_Address | |
3690 | then | |
31b5873d | 3691 | Expr := Expression (N); |
f4cd2542 EB |
3692 | |
3693 | -- This loop checks the form of the expression for Y'Address, | |
3694 | -- using recursion to deal with intermediate constants. | |
3695 | ||
31b5873d | 3696 | loop |
f4cd2542 | 3697 | -- Check for Y'Address |
31b5873d GD |
3698 | |
3699 | if Nkind (Expr) = N_Attribute_Reference | |
3700 | and then Attribute_Name (Expr) = Name_Address | |
31b5873d | 3701 | then |
f4cd2542 EB |
3702 | Expr := Prefix (Expr); |
3703 | exit; | |
31b5873d GD |
3704 | |
3705 | -- Check for Const where Const is a constant entity | |
3706 | ||
3707 | elsif Is_Entity_Name (Expr) | |
3708 | and then Ekind (Entity (Expr)) = E_Constant | |
3709 | then | |
3710 | Expr := Constant_Value (Entity (Expr)); | |
3711 | ||
3712 | -- Anything else does not need checking | |
3713 | ||
3714 | else | |
f4cd2542 | 3715 | return; |
31b5873d GD |
3716 | end if; |
3717 | end loop; | |
31b5873d | 3718 | |
f4cd2542 EB |
3719 | -- This loop checks the form of the prefix for an entity, |
3720 | -- using recursion to deal with intermediate components. | |
3721 | ||
3722 | loop | |
3723 | -- Check for Y where Y is an entity | |
3724 | ||
3725 | if Is_Entity_Name (Expr) then | |
3726 | Ent := Entity (Expr); | |
3727 | return; | |
3728 | ||
3729 | -- Check for components | |
3730 | ||
3731 | elsif | |
3732 | Nkind_In (Expr, N_Selected_Component, N_Indexed_Component) then | |
3733 | ||
3734 | Expr := Prefix (Expr); | |
3735 | Off := True; | |
3736 | ||
3737 | -- Anything else does not need checking | |
3738 | ||
3739 | else | |
3740 | return; | |
3741 | end if; | |
3742 | end loop; | |
3743 | end if; | |
3744 | end Find_Overlaid_Entity; | |
31b5873d | 3745 | |
7f0e4cdb BD |
3746 | ------------------------- |
3747 | -- Find_Parameter_Type -- | |
3748 | ------------------------- | |
3749 | ||
3750 | function Find_Parameter_Type (Param : Node_Id) return Entity_Id is | |
3751 | begin | |
3752 | if Nkind (Param) /= N_Parameter_Specification then | |
3753 | return Empty; | |
3754 | ||
ce4a6e84 RD |
3755 | -- For an access parameter, obtain the type from the formal entity |
3756 | -- itself, because access to subprogram nodes do not carry a type. | |
3757 | -- Shouldn't we always use the formal entity ??? | |
3758 | ||
7f0e4cdb | 3759 | elsif Nkind (Parameter_Type (Param)) = N_Access_Definition then |
ce4a6e84 | 3760 | return Etype (Defining_Identifier (Param)); |
7f0e4cdb BD |
3761 | |
3762 | else | |
3763 | return Etype (Parameter_Type (Param)); | |
3764 | end if; | |
3765 | end Find_Parameter_Type; | |
3766 | ||
fbf5a39b AC |
3767 | ----------------------------- |
3768 | -- Find_Static_Alternative -- | |
3769 | ----------------------------- | |
3770 | ||
3771 | function Find_Static_Alternative (N : Node_Id) return Node_Id is | |
3772 | Expr : constant Node_Id := Expression (N); | |
3773 | Val : constant Uint := Expr_Value (Expr); | |
3774 | Alt : Node_Id; | |
3775 | Choice : Node_Id; | |
3776 | ||
3777 | begin | |
3778 | Alt := First (Alternatives (N)); | |
3779 | ||
3780 | Search : loop | |
3781 | if Nkind (Alt) /= N_Pragma then | |
3782 | Choice := First (Discrete_Choices (Alt)); | |
fbf5a39b AC |
3783 | while Present (Choice) loop |
3784 | ||
3785 | -- Others choice, always matches | |
3786 | ||
3787 | if Nkind (Choice) = N_Others_Choice then | |
3788 | exit Search; | |
3789 | ||
3790 | -- Range, check if value is in the range | |
3791 | ||
3792 | elsif Nkind (Choice) = N_Range then | |
3793 | exit Search when | |
3794 | Val >= Expr_Value (Low_Bound (Choice)) | |
3795 | and then | |
3796 | Val <= Expr_Value (High_Bound (Choice)); | |
3797 | ||
3798 | -- Choice is a subtype name. Note that we know it must | |
3799 | -- be a static subtype, since otherwise it would have | |
3800 | -- been diagnosed as illegal. | |
3801 | ||
3802 | elsif Is_Entity_Name (Choice) | |
3803 | and then Is_Type (Entity (Choice)) | |
3804 | then | |
c800f862 RD |
3805 | exit Search when Is_In_Range (Expr, Etype (Choice), |
3806 | Assume_Valid => False); | |
fbf5a39b AC |
3807 | |
3808 | -- Choice is a subtype indication | |
3809 | ||
3810 | elsif Nkind (Choice) = N_Subtype_Indication then | |
3811 | declare | |
3812 | C : constant Node_Id := Constraint (Choice); | |
3813 | R : constant Node_Id := Range_Expression (C); | |
3814 | ||
3815 | begin | |
3816 | exit Search when | |
3817 | Val >= Expr_Value (Low_Bound (R)) | |
3818 | and then | |
3819 | Val <= Expr_Value (High_Bound (R)); | |
3820 | end; | |
3821 | ||
3822 | -- Choice is a simple expression | |
3823 | ||
3824 | else | |
3825 | exit Search when Val = Expr_Value (Choice); | |
3826 | end if; | |
3827 | ||
3828 | Next (Choice); | |
3829 | end loop; | |
3830 | end if; | |
3831 | ||
3832 | Next (Alt); | |
3833 | pragma Assert (Present (Alt)); | |
3834 | end loop Search; | |
3835 | ||
3836 | -- The above loop *must* terminate by finding a match, since | |
3837 | -- we know the case statement is valid, and the value of the | |
3838 | -- expression is known at compile time. When we fall out of | |
3839 | -- the loop, Alt points to the alternative that we know will | |
3840 | -- be selected at run time. | |
3841 | ||
3842 | return Alt; | |
3843 | end Find_Static_Alternative; | |
3844 | ||
996ae0b0 RK |
3845 | ------------------ |
3846 | -- First_Actual -- | |
3847 | ------------------ | |
3848 | ||
3849 | function First_Actual (Node : Node_Id) return Node_Id is | |
3850 | N : Node_Id; | |
3851 | ||
3852 | begin | |
3853 | if No (Parameter_Associations (Node)) then | |
3854 | return Empty; | |
3855 | end if; | |
3856 | ||
3857 | N := First (Parameter_Associations (Node)); | |
3858 | ||
3859 | if Nkind (N) = N_Parameter_Association then | |
3860 | return First_Named_Actual (Node); | |
3861 | else | |
3862 | return N; | |
3863 | end if; | |
3864 | end First_Actual; | |
3865 | ||
996ae0b0 RK |
3866 | ----------------------- |
3867 | -- Gather_Components -- | |
3868 | ----------------------- | |
3869 | ||
3870 | procedure Gather_Components | |
3871 | (Typ : Entity_Id; | |
3872 | Comp_List : Node_Id; | |
3873 | Governed_By : List_Id; | |
3874 | Into : Elist_Id; | |
3875 | Report_Errors : out Boolean) | |
3876 | is | |
3877 | Assoc : Node_Id; | |
3878 | Variant : Node_Id; | |
3879 | Discrete_Choice : Node_Id; | |
3880 | Comp_Item : Node_Id; | |
3881 | ||
3882 | Discrim : Entity_Id; | |
3883 | Discrim_Name : Node_Id; | |
3884 | Discrim_Value : Node_Id; | |
3885 | ||
3886 | begin | |
3887 | Report_Errors := False; | |
3888 | ||
3889 | if No (Comp_List) or else Null_Present (Comp_List) then | |
3890 | return; | |
3891 | ||
3892 | elsif Present (Component_Items (Comp_List)) then | |
3893 | Comp_Item := First (Component_Items (Comp_List)); | |
3894 | ||
3895 | else | |
3896 | Comp_Item := Empty; | |
3897 | end if; | |
3898 | ||
3899 | while Present (Comp_Item) loop | |
3900 | ||
2c867f5a ES |
3901 | -- Skip the tag of a tagged record, the interface tags, as well |
3902 | -- as all items that are not user components (anonymous types, | |
3903 | -- rep clauses, Parent field, controller field). | |
3904 | ||
3905 | if Nkind (Comp_Item) = N_Component_Declaration then | |
3906 | declare | |
3907 | Comp : constant Entity_Id := Defining_Identifier (Comp_Item); | |
3908 | begin | |
3909 | if not Is_Tag (Comp) | |
3910 | and then Chars (Comp) /= Name_uParent | |
2c867f5a ES |
3911 | then |
3912 | Append_Elmt (Comp, Into); | |
3913 | end if; | |
3914 | end; | |
996ae0b0 RK |
3915 | end if; |
3916 | ||
3917 | Next (Comp_Item); | |
3918 | end loop; | |
3919 | ||
3920 | if No (Variant_Part (Comp_List)) then | |
3921 | return; | |
3922 | else | |
3923 | Discrim_Name := Name (Variant_Part (Comp_List)); | |
3924 | Variant := First_Non_Pragma (Variants (Variant_Part (Comp_List))); | |
3925 | end if; | |
3926 | ||
3927 | -- Look for the discriminant that governs this variant part. | |
3928 | -- The discriminant *must* be in the Governed_By List | |
3929 | ||
3930 | Assoc := First (Governed_By); | |
3931 | Find_Constraint : loop | |
3932 | Discrim := First (Choices (Assoc)); | |
3933 | exit Find_Constraint when Chars (Discrim_Name) = Chars (Discrim) | |
3934 | or else (Present (Corresponding_Discriminant (Entity (Discrim))) | |
3935 | and then | |
3936 | Chars (Corresponding_Discriminant (Entity (Discrim))) | |
3937 | = Chars (Discrim_Name)) | |
3938 | or else Chars (Original_Record_Component (Entity (Discrim))) | |
3939 | = Chars (Discrim_Name); | |
3940 | ||
3941 | if No (Next (Assoc)) then | |
3942 | if not Is_Constrained (Typ) | |
3943 | and then Is_Derived_Type (Typ) | |
fbf5a39b | 3944 | and then Present (Stored_Constraint (Typ)) |
996ae0b0 | 3945 | then |
996ae0b0 | 3946 | -- If the type is a tagged type with inherited discriminants, |
fbf5a39b | 3947 | -- use the stored constraint on the parent in order to find |
996ae0b0 RK |
3948 | -- the values of discriminants that are otherwise hidden by an |
3949 | -- explicit constraint. Renamed discriminants are handled in | |
3950 | -- the code above. | |
3951 | ||
fbf5a39b AC |
3952 | -- If several parent discriminants are renamed by a single |
3953 | -- discriminant of the derived type, the call to obtain the | |
3954 | -- Corresponding_Discriminant field only retrieves the last | |
3955 | -- of them. We recover the constraint on the others from the | |
3956 | -- Stored_Constraint as well. | |
3957 | ||
996ae0b0 RK |
3958 | declare |
3959 | D : Entity_Id; | |
3960 | C : Elmt_Id; | |
3961 | ||
3962 | begin | |
3963 | D := First_Discriminant (Etype (Typ)); | |
fbf5a39b | 3964 | C := First_Elmt (Stored_Constraint (Typ)); |
9b0986f8 | 3965 | while Present (D) and then Present (C) loop |
996ae0b0 | 3966 | if Chars (Discrim_Name) = Chars (D) then |
fbf5a39b AC |
3967 | if Is_Entity_Name (Node (C)) |
3968 | and then Entity (Node (C)) = Entity (Discrim) | |
3969 | then | |
9b0986f8 RD |
3970 | -- D is renamed by Discrim, whose value is given in |
3971 | -- Assoc. | |
fbf5a39b AC |
3972 | |
3973 | null; | |
3974 | ||
3975 | else | |
3976 | Assoc := | |
3977 | Make_Component_Association (Sloc (Typ), | |
3978 | New_List | |
3979 | (New_Occurrence_Of (D, Sloc (Typ))), | |
3980 | Duplicate_Subexpr_No_Checks (Node (C))); | |
3981 | end if; | |
996ae0b0 RK |
3982 | exit Find_Constraint; |
3983 | end if; | |
3984 | ||
9b0986f8 | 3985 | Next_Discriminant (D); |
996ae0b0 RK |
3986 | Next_Elmt (C); |
3987 | end loop; | |
3988 | end; | |
3989 | end if; | |
3990 | end if; | |
3991 | ||
3992 | if No (Next (Assoc)) then | |
3993 | Error_Msg_NE (" missing value for discriminant&", | |
3994 | First (Governed_By), Discrim_Name); | |
3995 | Report_Errors := True; | |
3996 | return; | |
3997 | end if; | |
3998 | ||
3999 | Next (Assoc); | |
4000 | end loop Find_Constraint; | |
4001 | ||
4002 | Discrim_Value := Expression (Assoc); | |
4003 | ||
4004 | if not Is_OK_Static_Expression (Discrim_Value) then | |
fbf5a39b AC |
4005 | Error_Msg_FE |
4006 | ("value for discriminant & must be static!", | |
4007 | Discrim_Value, Discrim); | |
4008 | Why_Not_Static (Discrim_Value); | |
996ae0b0 RK |
4009 | Report_Errors := True; |
4010 | return; | |
4011 | end if; | |
4012 | ||
4013 | Search_For_Discriminant_Value : declare | |
4014 | Low : Node_Id; | |
4015 | High : Node_Id; | |
4016 | ||
4017 | UI_High : Uint; | |
4018 | UI_Low : Uint; | |
4019 | UI_Discrim_Value : constant Uint := Expr_Value (Discrim_Value); | |
4020 | ||
4021 | begin | |
4022 | Find_Discrete_Value : while Present (Variant) loop | |
4023 | Discrete_Choice := First (Discrete_Choices (Variant)); | |
4024 | while Present (Discrete_Choice) loop | |
4025 | ||
4026 | exit Find_Discrete_Value when | |
4027 | Nkind (Discrete_Choice) = N_Others_Choice; | |
4028 | ||
4029 | Get_Index_Bounds (Discrete_Choice, Low, High); | |
4030 | ||
4031 | UI_Low := Expr_Value (Low); | |
4032 | UI_High := Expr_Value (High); | |
4033 | ||
4034 | exit Find_Discrete_Value when | |
4035 | UI_Low <= UI_Discrim_Value | |
4036 | and then | |
4037 | UI_High >= UI_Discrim_Value; | |
4038 | ||
4039 | Next (Discrete_Choice); | |
4040 | end loop; | |
4041 | ||
4042 | Next_Non_Pragma (Variant); | |
4043 | end loop Find_Discrete_Value; | |
4044 | end Search_For_Discriminant_Value; | |
4045 | ||
4046 | if No (Variant) then | |
4047 | Error_Msg_NE | |
4048 | ("value of discriminant & is out of range", Discrim_Value, Discrim); | |
4049 | Report_Errors := True; | |
4050 | return; | |
4051 | end if; | |
4052 | ||
4053 | -- If we have found the corresponding choice, recursively add its | |
4054 | -- components to the Into list. | |
4055 | ||
4056 | Gather_Components (Empty, | |
4057 | Component_List (Variant), Governed_By, Into, Report_Errors); | |
4058 | end Gather_Components; | |
4059 | ||
4060 | ------------------------ | |
4061 | -- Get_Actual_Subtype -- | |
4062 | ------------------------ | |
4063 | ||
4064 | function Get_Actual_Subtype (N : Node_Id) return Entity_Id is | |
4065 | Typ : constant Entity_Id := Etype (N); | |
4066 | Utyp : Entity_Id := Underlying_Type (Typ); | |
4067 | Decl : Node_Id; | |
4068 | Atyp : Entity_Id; | |
4069 | ||
4070 | begin | |
b8dc622e | 4071 | if No (Utyp) then |
996ae0b0 RK |
4072 | Utyp := Typ; |
4073 | end if; | |
4074 | ||
4075 | -- If what we have is an identifier that references a subprogram | |
4076 | -- formal, or a variable or constant object, then we get the actual | |
4077 | -- subtype from the referenced entity if one has been built. | |
4078 | ||
4079 | if Nkind (N) = N_Identifier | |
4080 | and then | |
4081 | (Is_Formal (Entity (N)) | |
4082 | or else Ekind (Entity (N)) = E_Constant | |
4083 | or else Ekind (Entity (N)) = E_Variable) | |
4084 | and then Present (Actual_Subtype (Entity (N))) | |
4085 | then | |
4086 | return Actual_Subtype (Entity (N)); | |
4087 | ||
4088 | -- Actual subtype of unchecked union is always itself. We never need | |
4089 | -- the "real" actual subtype. If we did, we couldn't get it anyway | |
4090 | -- because the discriminant is not available. The restrictions on | |
4091 | -- Unchecked_Union are designed to make sure that this is OK. | |
4092 | ||
5d09245e | 4093 | elsif Is_Unchecked_Union (Base_Type (Utyp)) then |
996ae0b0 RK |
4094 | return Typ; |
4095 | ||
4096 | -- Here for the unconstrained case, we must find actual subtype | |
4097 | -- No actual subtype is available, so we must build it on the fly. | |
4098 | ||
4099 | -- Checking the type, not the underlying type, for constrainedness | |
4100 | -- seems to be necessary. Maybe all the tests should be on the type??? | |
4101 | ||
4102 | elsif (not Is_Constrained (Typ)) | |
4103 | and then (Is_Array_Type (Utyp) | |
4104 | or else (Is_Record_Type (Utyp) | |
4105 | and then Has_Discriminants (Utyp))) | |
4106 | and then not Has_Unknown_Discriminants (Utyp) | |
4107 | and then not (Ekind (Utyp) = E_String_Literal_Subtype) | |
4108 | then | |
ce4a6e84 | 4109 | -- Nothing to do if in spec expression (why not???) |
996ae0b0 | 4110 | |
ce4a6e84 | 4111 | if In_Spec_Expression then |
996ae0b0 RK |
4112 | return Typ; |
4113 | ||
fbf5a39b AC |
4114 | elsif Is_Private_Type (Typ) |
4115 | and then not Has_Discriminants (Typ) | |
4116 | then | |
4117 | -- If the type has no discriminants, there is no subtype to | |
4118 | -- build, even if the underlying type is discriminated. | |
4119 | ||
4120 | return Typ; | |
4121 | ||
996ae0b0 RK |
4122 | -- Else build the actual subtype |
4123 | ||
4124 | else | |
4125 | Decl := Build_Actual_Subtype (Typ, N); | |
4126 | Atyp := Defining_Identifier (Decl); | |
4127 | ||
4128 | -- If Build_Actual_Subtype generated a new declaration then use it | |
4129 | ||
4130 | if Atyp /= Typ then | |
4131 | ||
4132 | -- The actual subtype is an Itype, so analyze the declaration, | |
4133 | -- but do not attach it to the tree, to get the type defined. | |
4134 | ||
4135 | Set_Parent (Decl, N); | |
4136 | Set_Is_Itype (Atyp); | |
4137 | Analyze (Decl, Suppress => All_Checks); | |
4138 | Set_Associated_Node_For_Itype (Atyp, N); | |
4139 | Set_Has_Delayed_Freeze (Atyp, False); | |
4140 | ||
4141 | -- We need to freeze the actual subtype immediately. This is | |
4142 | -- needed, because otherwise this Itype will not get frozen | |
4143 | -- at all, and it is always safe to freeze on creation because | |
4144 | -- any associated types must be frozen at this point. | |
4145 | ||
4146 | Freeze_Itype (Atyp, N); | |
4147 | return Atyp; | |
4148 | ||
4149 | -- Otherwise we did not build a declaration, so return original | |
4150 | ||
4151 | else | |
4152 | return Typ; | |
4153 | end if; | |
4154 | end if; | |
4155 | ||
4156 | -- For all remaining cases, the actual subtype is the same as | |
4157 | -- the nominal type. | |
4158 | ||
4159 | else | |
4160 | return Typ; | |
4161 | end if; | |
4162 | end Get_Actual_Subtype; | |
4163 | ||
4164 | ------------------------------------- | |
4165 | -- Get_Actual_Subtype_If_Available -- | |
4166 | ------------------------------------- | |
4167 | ||
4168 | function Get_Actual_Subtype_If_Available (N : Node_Id) return Entity_Id is | |
4169 | Typ : constant Entity_Id := Etype (N); | |
4170 | ||
4171 | begin | |
4172 | -- If what we have is an identifier that references a subprogram | |
4173 | -- formal, or a variable or constant object, then we get the actual | |
4174 | -- subtype from the referenced entity if one has been built. | |
4175 | ||
4176 | if Nkind (N) = N_Identifier | |
4177 | and then | |
4178 | (Is_Formal (Entity (N)) | |
4179 | or else Ekind (Entity (N)) = E_Constant | |
4180 | or else Ekind (Entity (N)) = E_Variable) | |
4181 | and then Present (Actual_Subtype (Entity (N))) | |
4182 | then | |
4183 | return Actual_Subtype (Entity (N)); | |
4184 | ||
4185 | -- Otherwise the Etype of N is returned unchanged | |
4186 | ||
4187 | else | |
4188 | return Typ; | |
4189 | end if; | |
4190 | end Get_Actual_Subtype_If_Available; | |
4191 | ||
60370fb1 AC |
4192 | ------------------------ |
4193 | -- Get_Body_From_Stub -- | |
4194 | ------------------------ | |
4195 | ||
4196 | function Get_Body_From_Stub (N : Node_Id) return Node_Id is | |
4197 | begin | |
4198 | return Proper_Body (Unit (Library_Unit (N))); | |
4199 | end Get_Body_From_Stub; | |
4200 | ||
996ae0b0 RK |
4201 | ------------------------------- |
4202 | -- Get_Default_External_Name -- | |
4203 | ------------------------------- | |
4204 | ||
4205 | function Get_Default_External_Name (E : Node_Or_Entity_Id) return Node_Id is | |
4206 | begin | |
4207 | Get_Decoded_Name_String (Chars (E)); | |
4208 | ||
4209 | if Opt.External_Name_Imp_Casing = Uppercase then | |
4210 | Set_Casing (All_Upper_Case); | |
4211 | else | |
4212 | Set_Casing (All_Lower_Case); | |
4213 | end if; | |
4214 | ||
4215 | return | |
4216 | Make_String_Literal (Sloc (E), | |
4217 | Strval => String_From_Name_Buffer); | |
996ae0b0 RK |
4218 | end Get_Default_External_Name; |
4219 | ||
c2db4b32 AC |
4220 | -------------------------- |
4221 | -- Get_Enclosing_Object -- | |
4222 | -------------------------- | |
4223 | ||
4224 | function Get_Enclosing_Object (N : Node_Id) return Entity_Id is | |
4225 | begin | |
4226 | if Is_Entity_Name (N) then | |
4227 | return Entity (N); | |
4228 | else | |
4229 | case Nkind (N) is | |
4230 | when N_Indexed_Component | | |
4231 | N_Slice | | |
4232 | N_Selected_Component => | |
4233 | ||
4234 | -- If not generating code, a dereference may be left implicit. | |
4235 | -- In thoses cases, return Empty. | |
4236 | ||
4237 | if Is_Access_Type (Etype (Prefix (N))) then | |
4238 | return Empty; | |
4239 | else | |
4240 | return Get_Enclosing_Object (Prefix (N)); | |
4241 | end if; | |
4242 | ||
4243 | when N_Type_Conversion => | |
4244 | return Get_Enclosing_Object (Expression (N)); | |
4245 | ||
4246 | when others => | |
4247 | return Empty; | |
4248 | end case; | |
4249 | end if; | |
4250 | end Get_Enclosing_Object; | |
4251 | ||
996ae0b0 RK |
4252 | --------------------------- |
4253 | -- Get_Enum_Lit_From_Pos -- | |
4254 | --------------------------- | |
4255 | ||
4256 | function Get_Enum_Lit_From_Pos | |
fbf5a39b AC |
4257 | (T : Entity_Id; |
4258 | Pos : Uint; | |
4259 | Loc : Source_Ptr) return Node_Id | |
996ae0b0 RK |
4260 | is |
4261 | Lit : Node_Id; | |
996ae0b0 RK |
4262 | |
4263 | begin | |
82c80734 RD |
4264 | -- In the case where the literal is of type Character, Wide_Character |
4265 | -- or Wide_Wide_Character or of a type derived from them, there needs | |
4266 | -- to be some special handling since there is no explicit chain of | |
4267 | -- literals to search. Instead, an N_Character_Literal node is created | |
4268 | -- with the appropriate Char_Code and Chars fields. | |
996ae0b0 | 4269 | |
ce4a6e84 | 4270 | if Is_Standard_Character_Type (T) then |
82c80734 | 4271 | Set_Character_Literal_Name (UI_To_CC (Pos)); |
996ae0b0 RK |
4272 | return |
4273 | Make_Character_Literal (Loc, | |
82c80734 RD |
4274 | Chars => Name_Find, |
4275 | Char_Literal_Value => Pos); | |
996ae0b0 RK |
4276 | |
4277 | -- For all other cases, we have a complete table of literals, and | |
4278 | -- we simply iterate through the chain of literal until the one | |
4279 | -- with the desired position value is found. | |
4280 | -- | |
4281 | ||
4282 | else | |
4283 | Lit := First_Literal (Base_Type (T)); | |
82c80734 | 4284 | for J in 1 .. UI_To_Int (Pos) loop |
996ae0b0 RK |
4285 | Next_Literal (Lit); |
4286 | end loop; | |
4287 | ||
4288 | return New_Occurrence_Of (Lit, Loc); | |
4289 | end if; | |
4290 | end Get_Enum_Lit_From_Pos; | |
4291 | ||
dac3bede YM |
4292 | --------------------------------------- |
4293 | -- Get_Ensures_From_Test_Case_Pragma -- | |
4294 | --------------------------------------- | |
4295 | ||
4296 | function Get_Ensures_From_Test_Case_Pragma (N : Node_Id) return Node_Id is | |
4297 | Args : constant List_Id := Pragma_Argument_Associations (N); | |
3ddd922e | 4298 | Res : Node_Id; |
dac3bede YM |
4299 | |
4300 | begin | |
4301 | if List_Length (Args) = 4 then | |
4302 | Res := Pick (Args, 4); | |
4303 | ||
e0296583 | 4304 | elsif List_Length (Args) = 3 then |
dac3bede | 4305 | Res := Pick (Args, 3); |
3ddd922e | 4306 | |
dac3bede YM |
4307 | if Chars (Res) /= Name_Ensures then |
4308 | Res := Empty; | |
4309 | end if; | |
3ddd922e AC |
4310 | |
4311 | else | |
4312 | Res := Empty; | |
dac3bede YM |
4313 | end if; |
4314 | ||
4315 | return Res; | |
4316 | end Get_Ensures_From_Test_Case_Pragma; | |
4317 | ||
07fc65c4 GB |
4318 | ------------------------ |
4319 | -- Get_Generic_Entity -- | |
4320 | ------------------------ | |
4321 | ||
4322 | function Get_Generic_Entity (N : Node_Id) return Entity_Id is | |
4323 | Ent : constant Entity_Id := Entity (Name (N)); | |
07fc65c4 GB |
4324 | begin |
4325 | if Present (Renamed_Object (Ent)) then | |
4326 | return Renamed_Object (Ent); | |
4327 | else | |
4328 | return Ent; | |
4329 | end if; | |
4330 | end Get_Generic_Entity; | |
4331 | ||
996ae0b0 RK |
4332 | ---------------------- |
4333 | -- Get_Index_Bounds -- | |
4334 | ---------------------- | |
4335 | ||
4336 | procedure Get_Index_Bounds (N : Node_Id; L, H : out Node_Id) is | |
4337 | Kind : constant Node_Kind := Nkind (N); | |
ce9e9122 | 4338 | R : Node_Id; |
996ae0b0 RK |
4339 | |
4340 | begin | |
4341 | if Kind = N_Range then | |
4342 | L := Low_Bound (N); | |
4343 | H := High_Bound (N); | |
4344 | ||
4345 | elsif Kind = N_Subtype_Indication then | |
ce9e9122 RD |
4346 | R := Range_Expression (Constraint (N)); |
4347 | ||
4348 | if R = Error then | |
4349 | L := Error; | |
4350 | H := Error; | |
4351 | return; | |
4352 | ||
4353 | else | |
4354 | L := Low_Bound (Range_Expression (Constraint (N))); | |
4355 | H := High_Bound (Range_Expression (Constraint (N))); | |
4356 | end if; | |
996ae0b0 RK |
4357 | |
4358 | elsif Is_Entity_Name (N) and then Is_Type (Entity (N)) then | |
4359 | if Error_Posted (Scalar_Range (Entity (N))) then | |
4360 | L := Error; | |
4361 | H := Error; | |
4362 | ||
4363 | elsif Nkind (Scalar_Range (Entity (N))) = N_Subtype_Indication then | |
4364 | Get_Index_Bounds (Scalar_Range (Entity (N)), L, H); | |
4365 | ||
4366 | else | |
4367 | L := Low_Bound (Scalar_Range (Entity (N))); | |
4368 | H := High_Bound (Scalar_Range (Entity (N))); | |
4369 | end if; | |
4370 | ||
4371 | else | |
130c236a | 4372 | -- N is an expression, indicating a range with one value |
996ae0b0 RK |
4373 | |
4374 | L := N; | |
4375 | H := N; | |
4376 | end if; | |
996ae0b0 RK |
4377 | end Get_Index_Bounds; |
4378 | ||
1735e55d AC |
4379 | ---------------------------------- |
4380 | -- Get_Library_Unit_Name_string -- | |
4381 | ---------------------------------- | |
4382 | ||
4383 | procedure Get_Library_Unit_Name_String (Decl_Node : Node_Id) is | |
4384 | Unit_Name_Id : constant Unit_Name_Type := Get_Unit_Name (Decl_Node); | |
4385 | ||
4386 | begin | |
4387 | Get_Unit_Name_String (Unit_Name_Id); | |
4388 | ||
2717634d | 4389 | -- Remove seven last character (" (spec)" or " (body)") |
1735e55d AC |
4390 | |
4391 | Name_Len := Name_Len - 7; | |
4392 | pragma Assert (Name_Buffer (Name_Len + 1) = ' '); | |
4393 | end Get_Library_Unit_Name_String; | |
4394 | ||
996ae0b0 RK |
4395 | ------------------------ |
4396 | -- Get_Name_Entity_Id -- | |
4397 | ------------------------ | |
4398 | ||
4399 | function Get_Name_Entity_Id (Id : Name_Id) return Entity_Id is | |
4400 | begin | |
4401 | return Entity_Id (Get_Name_Table_Info (Id)); | |
4402 | end Get_Name_Entity_Id; | |
4403 | ||
1bf773bb AC |
4404 | ------------------------------------ |
4405 | -- Get_Name_From_Test_Case_Pragma -- | |
4406 | ------------------------------------ | |
4407 | ||
4408 | function Get_Name_From_Test_Case_Pragma (N : Node_Id) return String_Id is | |
1f9939b5 AC |
4409 | Arg : constant Node_Id := |
4410 | Get_Pragma_Arg (First (Pragma_Argument_Associations (N))); | |
1bf773bb | 4411 | begin |
1f9939b5 | 4412 | return Strval (Expr_Value_S (Arg)); |
1bf773bb AC |
4413 | end Get_Name_From_Test_Case_Pragma; |
4414 | ||
1923d2d6 JM |
4415 | ------------------- |
4416 | -- Get_Pragma_Id -- | |
4417 | ------------------- | |
4418 | ||
4419 | function Get_Pragma_Id (N : Node_Id) return Pragma_Id is | |
4420 | begin | |
4421 | return Get_Pragma_Id (Pragma_Name (N)); | |
4422 | end Get_Pragma_Id; | |
4423 | ||
996ae0b0 RK |
4424 | --------------------------- |
4425 | -- Get_Referenced_Object -- | |
4426 | --------------------------- | |
4427 | ||
4428 | function Get_Referenced_Object (N : Node_Id) return Node_Id is | |
9b0986f8 | 4429 | R : Node_Id; |
996ae0b0 RK |
4430 | |
4431 | begin | |
9b0986f8 | 4432 | R := N; |
996ae0b0 RK |
4433 | while Is_Entity_Name (R) |
4434 | and then Present (Renamed_Object (Entity (R))) | |
4435 | loop | |
4436 | R := Renamed_Object (Entity (R)); | |
4437 | end loop; | |
4438 | ||
4439 | return R; | |
4440 | end Get_Referenced_Object; | |
4441 | ||
f377c995 HK |
4442 | ------------------------ |
4443 | -- Get_Renamed_Entity -- | |
4444 | ------------------------ | |
4445 | ||
4446 | function Get_Renamed_Entity (E : Entity_Id) return Entity_Id is | |
4447 | R : Entity_Id; | |
4448 | ||
4449 | begin | |
4450 | R := E; | |
4451 | while Present (Renamed_Entity (R)) loop | |
4452 | R := Renamed_Entity (R); | |
4453 | end loop; | |
4454 | ||
4455 | return R; | |
4456 | end Get_Renamed_Entity; | |
4457 | ||
dac3bede YM |
4458 | ---------------------------------------- |
4459 | -- Get_Requires_From_Test_Case_Pragma -- | |
4460 | ---------------------------------------- | |
4461 | ||
4462 | function Get_Requires_From_Test_Case_Pragma (N : Node_Id) return Node_Id is | |
4463 | Args : constant List_Id := Pragma_Argument_Associations (N); | |
3ddd922e | 4464 | Res : Node_Id; |
dac3bede YM |
4465 | |
4466 | begin | |
e0296583 AC |
4467 | if List_Length (Args) >= 3 then |
4468 | Res := Pick (Args, 3); | |
3ddd922e | 4469 | |
e0296583 AC |
4470 | if Chars (Res) /= Name_Requires then |
4471 | Res := Empty; | |
4472 | end if; | |
3ddd922e AC |
4473 | |
4474 | else | |
4475 | Res := Empty; | |
dac3bede YM |
4476 | end if; |
4477 | ||
4478 | return Res; | |
4479 | end Get_Requires_From_Test_Case_Pragma; | |
4480 | ||
996ae0b0 RK |
4481 | ------------------------- |
4482 | -- Get_Subprogram_Body -- | |
4483 | ------------------------- | |
4484 | ||
4485 | function Get_Subprogram_Body (E : Entity_Id) return Node_Id is | |
4486 | Decl : Node_Id; | |
4487 | ||
4488 | begin | |
4489 | Decl := Unit_Declaration_Node (E); | |
4490 | ||
4491 | if Nkind (Decl) = N_Subprogram_Body then | |
4492 | return Decl; | |
4493 | ||
15ce9ca2 AC |
4494 | -- The below comment is bad, because it is possible for |
4495 | -- Nkind (Decl) to be an N_Subprogram_Body_Stub ??? | |
4496 | ||
996ae0b0 RK |
4497 | else -- Nkind (Decl) = N_Subprogram_Declaration |
4498 | ||
f377c995 HK |
4499 | if Present (Corresponding_Body (Decl)) then |
4500 | return Unit_Declaration_Node (Corresponding_Body (Decl)); | |
4501 | ||
4502 | -- Imported subprogram case | |
4503 | ||
4504 | else | |
4505 | return Empty; | |
4506 | end if; | |
4507 | end if; | |
4508 | end Get_Subprogram_Body; | |
4509 | ||
4510 | --------------------------- | |
4511 | -- Get_Subprogram_Entity -- | |
4512 | --------------------------- | |
4513 | ||
4514 | function Get_Subprogram_Entity (Nod : Node_Id) return Entity_Id is | |
4515 | Nam : Node_Id; | |
4516 | Proc : Entity_Id; | |
4517 | ||
4518 | begin | |
4519 | if Nkind (Nod) = N_Accept_Statement then | |
4520 | Nam := Entry_Direct_Name (Nod); | |
4521 | ||
4522 | -- For an entry call, the prefix of the call is a selected component. | |
4523 | -- Need additional code for internal calls ??? | |
4524 | ||
4525 | elsif Nkind (Nod) = N_Entry_Call_Statement then | |
4526 | if Nkind (Name (Nod)) = N_Selected_Component then | |
4527 | Nam := Entity (Selector_Name (Name (Nod))); | |
4528 | else | |
4529 | Nam := Empty; | |
4530 | end if; | |
4531 | ||
4532 | else | |
4533 | Nam := Name (Nod); | |
4534 | end if; | |
4535 | ||
4536 | if Nkind (Nam) = N_Explicit_Dereference then | |
4537 | Proc := Etype (Prefix (Nam)); | |
4538 | elsif Is_Entity_Name (Nam) then | |
4539 | Proc := Entity (Nam); | |
4540 | else | |
4541 | return Empty; | |
4542 | end if; | |
4543 | ||
4544 | if Is_Object (Proc) then | |
4545 | Proc := Etype (Proc); | |
4546 | end if; | |
996ae0b0 | 4547 | |
f377c995 HK |
4548 | if Ekind (Proc) = E_Access_Subprogram_Type then |
4549 | Proc := Directly_Designated_Type (Proc); | |
4550 | end if; | |
15ce9ca2 | 4551 | |
f377c995 HK |
4552 | if not Is_Subprogram (Proc) |
4553 | and then Ekind (Proc) /= E_Subprogram_Type | |
4554 | then | |
4555 | return Empty; | |
4556 | else | |
4557 | return Proc; | |
996ae0b0 | 4558 | end if; |
f377c995 | 4559 | end Get_Subprogram_Entity; |
996ae0b0 RK |
4560 | |
4561 | ----------------------------- | |
4562 | -- Get_Task_Body_Procedure -- | |
4563 | ----------------------------- | |
4564 | ||
4565 | function Get_Task_Body_Procedure (E : Entity_Id) return Node_Id is | |
4566 | begin | |
482a63fb | 4567 | -- Note: A task type may be the completion of a private type with |
ce4a6e84 | 4568 | -- discriminants. When performing elaboration checks on a task |
482a63fb ES |
4569 | -- declaration, the current view of the type may be the private one, |
4570 | -- and the procedure that holds the body of the task is held in its | |
4571 | -- underlying type. | |
4572 | ||
9b0986f8 RD |
4573 | -- This is an odd function, why not have Task_Body_Procedure do |
4574 | -- the following digging??? | |
4575 | ||
482a63fb | 4576 | return Task_Body_Procedure (Underlying_Type (Root_Type (E))); |
996ae0b0 RK |
4577 | end Get_Task_Body_Procedure; |
4578 | ||
15ce9ca2 AC |
4579 | ----------------------- |
4580 | -- Has_Access_Values -- | |
4581 | ----------------------- | |
4582 | ||
4583 | function Has_Access_Values (T : Entity_Id) return Boolean is | |
4584 | Typ : constant Entity_Id := Underlying_Type (T); | |
4585 | ||
4586 | begin | |
4587 | -- Case of a private type which is not completed yet. This can only | |
4588 | -- happen in the case of a generic format type appearing directly, or | |
4589 | -- as a component of the type to which this function is being applied | |
4590 | -- at the top level. Return False in this case, since we certainly do | |
4591 | -- not know that the type contains access types. | |
4592 | ||
4593 | if No (Typ) then | |
4594 | return False; | |
4595 | ||
4596 | elsif Is_Access_Type (Typ) then | |
4597 | return True; | |
4598 | ||
4599 | elsif Is_Array_Type (Typ) then | |
4600 | return Has_Access_Values (Component_Type (Typ)); | |
4601 | ||
4602 | elsif Is_Record_Type (Typ) then | |
4603 | declare | |
4604 | Comp : Entity_Id; | |
4605 | ||
4606 | begin | |
ce4a6e84 RD |
4607 | -- Loop to Check components |
4608 | ||
9e87a68d | 4609 | Comp := First_Component_Or_Discriminant (Typ); |
15ce9ca2 | 4610 | while Present (Comp) loop |
ce4a6e84 RD |
4611 | |
4612 | -- Check for access component, tag field does not count, even | |
4613 | -- though it is implemented internally using an access type. | |
4614 | ||
4615 | if Has_Access_Values (Etype (Comp)) | |
4616 | and then Chars (Comp) /= Name_uTag | |
4617 | then | |
15ce9ca2 AC |
4618 | return True; |
4619 | end if; | |
4620 | ||
9e87a68d | 4621 | Next_Component_Or_Discriminant (Comp); |
15ce9ca2 AC |
4622 | end loop; |
4623 | end; | |
4624 | ||
4625 | return False; | |
4626 | ||
4627 | else | |
4628 | return False; | |
4629 | end if; | |
4630 | end Has_Access_Values; | |
4631 | ||
9b0986f8 RD |
4632 | ------------------------------ |
4633 | -- Has_Compatible_Alignment -- | |
4634 | ------------------------------ | |
7324bf49 | 4635 | |
9b0986f8 RD |
4636 | function Has_Compatible_Alignment |
4637 | (Obj : Entity_Id; | |
4638 | Expr : Node_Id) return Alignment_Result | |
4639 | is | |
4640 | function Has_Compatible_Alignment_Internal | |
4641 | (Obj : Entity_Id; | |
4642 | Expr : Node_Id; | |
4643 | Default : Alignment_Result) return Alignment_Result; | |
4644 | -- This is the internal recursive function that actually does the work. | |
4645 | -- There is one additional parameter, which says what the result should | |
4646 | -- be if no alignment information is found, and there is no definite | |
4647 | -- indication of compatible alignments. At the outer level, this is set | |
4648 | -- to Unknown, but for internal recursive calls in the case where types | |
4649 | -- are known to be correct, it is set to Known_Compatible. | |
4650 | ||
4651 | --------------------------------------- | |
4652 | -- Has_Compatible_Alignment_Internal -- | |
4653 | --------------------------------------- | |
4654 | ||
4655 | function Has_Compatible_Alignment_Internal | |
4656 | (Obj : Entity_Id; | |
4657 | Expr : Node_Id; | |
4658 | Default : Alignment_Result) return Alignment_Result | |
4659 | is | |
4660 | Result : Alignment_Result := Known_Compatible; | |
f4cd2542 EB |
4661 | -- Holds the current status of the result. Note that once a value of |
4662 | -- Known_Incompatible is set, it is sticky and does not get changed | |
4663 | -- to Unknown (the value in Result only gets worse as we go along, | |
4664 | -- never better). | |
9b0986f8 | 4665 | |
f4cd2542 EB |
4666 | Offs : Uint := No_Uint; |
4667 | -- Set to a factor of the offset from the base object when Expr is a | |
4668 | -- selected or indexed component, based on Component_Bit_Offset and | |
4669 | -- Component_Size respectively. A negative value is used to represent | |
4670 | -- a value which is not known at compile time. | |
9b0986f8 RD |
4671 | |
4672 | procedure Check_Prefix; | |
4673 | -- Checks the prefix recursively in the case where the expression | |
4674 | -- is an indexed or selected component. | |
4675 | ||
4676 | procedure Set_Result (R : Alignment_Result); | |
4677 | -- If R represents a worse outcome (unknown instead of known | |
4678 | -- compatible, or known incompatible), then set Result to R. | |
4679 | ||
9b0986f8 RD |
4680 | ------------------ |
4681 | -- Check_Prefix -- | |
4682 | ------------------ | |
4683 | ||
4684 | procedure Check_Prefix is | |
4685 | begin | |
4686 | -- The subtlety here is that in doing a recursive call to check | |
4687 | -- the prefix, we have to decide what to do in the case where we | |
4688 | -- don't find any specific indication of an alignment problem. | |
4689 | ||
4690 | -- At the outer level, we normally set Unknown as the result in | |
4691 | -- this case, since we can only set Known_Compatible if we really | |
4692 | -- know that the alignment value is OK, but for the recursive | |
4693 | -- call, in the case where the types match, and we have not | |
4694 | -- specified a peculiar alignment for the object, we are only | |
4695 | -- concerned about suspicious rep clauses, the default case does | |
4696 | -- not affect us, since the compiler will, in the absence of such | |
4697 | -- rep clauses, ensure that the alignment is correct. | |
4698 | ||
4699 | if Default = Known_Compatible | |
4700 | or else | |
4701 | (Etype (Obj) = Etype (Expr) | |
4702 | and then (Unknown_Alignment (Obj) | |
4703 | or else | |
4704 | Alignment (Obj) = Alignment (Etype (Obj)))) | |
4705 | then | |
4706 | Set_Result | |
4707 | (Has_Compatible_Alignment_Internal | |
4708 | (Obj, Prefix (Expr), Known_Compatible)); | |
4709 | ||
4710 | -- In all other cases, we need a full check on the prefix | |
4711 | ||
4712 | else | |
4713 | Set_Result | |
4714 | (Has_Compatible_Alignment_Internal | |
4715 | (Obj, Prefix (Expr), Unknown)); | |
4716 | end if; | |
4717 | end Check_Prefix; | |
4718 | ||
4719 | ---------------- | |
4720 | -- Set_Result -- | |
4721 | ---------------- | |
4722 | ||
4723 | procedure Set_Result (R : Alignment_Result) is | |
4724 | begin | |
4725 | if R > Result then | |
4726 | Result := R; | |
4727 | end if; | |
4728 | end Set_Result; | |
4729 | ||
4730 | -- Start of processing for Has_Compatible_Alignment_Internal | |
4731 | ||
4732 | begin | |
4733 | -- If Expr is a selected component, we must make sure there is no | |
4734 | -- potentially troublesome component clause, and that the record is | |
4735 | -- not packed. | |
4736 | ||
4737 | if Nkind (Expr) = N_Selected_Component then | |
4738 | ||
4739 | -- Packed record always generate unknown alignment | |
4740 | ||
4741 | if Is_Packed (Etype (Prefix (Expr))) then | |
4742 | Set_Result (Unknown); | |
4743 | end if; | |
4744 | ||
f4cd2542 | 4745 | -- Check prefix and component offset |
9b0986f8 | 4746 | |
9b0986f8 | 4747 | Check_Prefix; |
f4cd2542 | 4748 | Offs := Component_Bit_Offset (Entity (Selector_Name (Expr))); |
9b0986f8 RD |
4749 | |
4750 | -- If Expr is an indexed component, we must make sure there is no | |
4751 | -- potentially troublesome Component_Size clause and that the array | |
4752 | -- is not bit-packed. | |
4753 | ||
4754 | elsif Nkind (Expr) = N_Indexed_Component then | |
f4cd2542 EB |
4755 | declare |
4756 | Typ : constant Entity_Id := Etype (Prefix (Expr)); | |
ef76538f AC |
4757 | Ind : constant Node_Id := First_Index (Typ); |
4758 | ||
f4cd2542 EB |
4759 | begin |
4760 | -- Bit packed array always generates unknown alignment | |
9b0986f8 | 4761 | |
f4cd2542 EB |
4762 | if Is_Bit_Packed_Array (Typ) then |
4763 | Set_Result (Unknown); | |
4764 | end if; | |
9b0986f8 | 4765 | |
f4cd2542 | 4766 | -- Check prefix and component offset |
9b0986f8 | 4767 | |
f4cd2542 EB |
4768 | Check_Prefix; |
4769 | Offs := Component_Size (Typ); | |
9b0986f8 | 4770 | |
f4cd2542 EB |
4771 | -- Small optimization: compute the full offset when possible |
4772 | ||
4773 | if Offs /= No_Uint | |
4774 | and then Offs > Uint_0 | |
4775 | and then Present (Ind) | |
4776 | and then Nkind (Ind) = N_Range | |
4777 | and then Compile_Time_Known_Value (Low_Bound (Ind)) | |
4778 | and then Compile_Time_Known_Value (First (Expressions (Expr))) | |
4779 | then | |
4780 | Offs := Offs * (Expr_Value (First (Expressions (Expr))) | |
4781 | - Expr_Value (Low_Bound ((Ind)))); | |
4782 | end if; | |
4783 | end; | |
9b0986f8 RD |
4784 | end if; |
4785 | ||
f4cd2542 EB |
4786 | -- If we have a null offset, the result is entirely determined by |
4787 | -- the base object and has already been computed recursively. | |
4788 | ||
4789 | if Offs = Uint_0 then | |
4790 | null; | |
4791 | ||
9b0986f8 RD |
4792 | -- Case where we know the alignment of the object |
4793 | ||
f4cd2542 | 4794 | elsif Known_Alignment (Obj) then |
9b0986f8 RD |
4795 | declare |
4796 | ObjA : constant Uint := Alignment (Obj); | |
ef76538f AC |
4797 | ExpA : Uint := No_Uint; |
4798 | SizA : Uint := No_Uint; | |
9b0986f8 RD |
4799 | |
4800 | begin | |
4801 | -- If alignment of Obj is 1, then we are always OK | |
4802 | ||
4803 | if ObjA = 1 then | |
4804 | Set_Result (Known_Compatible); | |
4805 | ||
4806 | -- Alignment of Obj is greater than 1, so we need to check | |
4807 | ||
4808 | else | |
f4cd2542 | 4809 | -- If we have an offset, see if it is compatible |
9b0986f8 | 4810 | |
f4cd2542 EB |
4811 | if Offs /= No_Uint and Offs > Uint_0 then |
4812 | if Offs mod (System_Storage_Unit * ObjA) /= 0 then | |
4813 | Set_Result (Known_Incompatible); | |
4814 | end if; | |
4815 | ||
4816 | -- See if Expr is an object with known alignment | |
4817 | ||
4818 | elsif Is_Entity_Name (Expr) | |
9b0986f8 RD |
4819 | and then Known_Alignment (Entity (Expr)) |
4820 | then | |
4821 | ExpA := Alignment (Entity (Expr)); | |
4822 | ||
4823 | -- Otherwise, we can use the alignment of the type of | |
4824 | -- Expr given that we already checked for | |
4825 | -- discombobulating rep clauses for the cases of indexed | |
4826 | -- and selected components above. | |
4827 | ||
4828 | elsif Known_Alignment (Etype (Expr)) then | |
4829 | ExpA := Alignment (Etype (Expr)); | |
f4cd2542 EB |
4830 | |
4831 | -- Otherwise the alignment is unknown | |
4832 | ||
4833 | else | |
4834 | Set_Result (Default); | |
9b0986f8 RD |
4835 | end if; |
4836 | ||
4837 | -- If we got an alignment, see if it is acceptable | |
4838 | ||
f4cd2542 EB |
4839 | if ExpA /= No_Uint and then ExpA < ObjA then |
4840 | Set_Result (Known_Incompatible); | |
4841 | end if; | |
9b0986f8 | 4842 | |
f4cd2542 EB |
4843 | -- If Expr is not a piece of a larger object, see if size |
4844 | -- is given. If so, check that it is not too small for the | |
4845 | -- required alignment. | |
9b0986f8 | 4846 | |
f4cd2542 EB |
4847 | if Offs /= No_Uint then |
4848 | null; | |
9b0986f8 | 4849 | |
f4cd2542 | 4850 | -- See if Expr is an object with known size |
9b0986f8 | 4851 | |
f4cd2542 | 4852 | elsif Is_Entity_Name (Expr) |
9b0986f8 RD |
4853 | and then Known_Static_Esize (Entity (Expr)) |
4854 | then | |
4855 | SizA := Esize (Entity (Expr)); | |
4856 | ||
4857 | -- Otherwise, we check the object size of the Expr type | |
4858 | ||
4859 | elsif Known_Static_Esize (Etype (Expr)) then | |
4860 | SizA := Esize (Etype (Expr)); | |
4861 | end if; | |
4862 | ||
4863 | -- If we got a size, see if it is a multiple of the Obj | |
4864 | -- alignment, if not, then the alignment cannot be | |
4865 | -- acceptable, since the size is always a multiple of the | |
4866 | -- alignment. | |
4867 | ||
4868 | if SizA /= No_Uint then | |
4869 | if SizA mod (ObjA * Ttypes.System_Storage_Unit) /= 0 then | |
4870 | Set_Result (Known_Incompatible); | |
4871 | end if; | |
4872 | end if; | |
4873 | end if; | |
4874 | end; | |
4875 | ||
ef76538f AC |
4876 | -- If we do not know required alignment, any non-zero offset is a |
4877 | -- potential problem (but certainly may be OK, so result is unknown). | |
f4cd2542 EB |
4878 | |
4879 | elsif Offs /= No_Uint then | |
4880 | Set_Result (Unknown); | |
4881 | ||
9b0986f8 RD |
4882 | -- If we can't find the result by direct comparison of alignment |
4883 | -- values, then there is still one case that we can determine known | |
4884 | -- result, and that is when we can determine that the types are the | |
4885 | -- same, and no alignments are specified. Then we known that the | |
4886 | -- alignments are compatible, even if we don't know the alignment | |
4887 | -- value in the front end. | |
4888 | ||
4889 | elsif Etype (Obj) = Etype (Expr) then | |
4890 | ||
4891 | -- Types are the same, but we have to check for possible size | |
4892 | -- and alignments on the Expr object that may make the alignment | |
4893 | -- different, even though the types are the same. | |
4894 | ||
4895 | if Is_Entity_Name (Expr) then | |
4896 | ||
4897 | -- First check alignment of the Expr object. Any alignment less | |
4898 | -- than Maximum_Alignment is worrisome since this is the case | |
4899 | -- where we do not know the alignment of Obj. | |
4900 | ||
4901 | if Known_Alignment (Entity (Expr)) | |
4902 | and then | |
ef76538f AC |
4903 | UI_To_Int (Alignment (Entity (Expr))) < |
4904 | Ttypes.Maximum_Alignment | |
9b0986f8 RD |
4905 | then |
4906 | Set_Result (Unknown); | |
4907 | ||
4908 | -- Now check size of Expr object. Any size that is not an | |
f3d57416 | 4909 | -- even multiple of Maximum_Alignment is also worrisome |
9b0986f8 RD |
4910 | -- since it may cause the alignment of the object to be less |
4911 | -- than the alignment of the type. | |
4912 | ||
4913 | elsif Known_Static_Esize (Entity (Expr)) | |
4914 | and then | |
4915 | (UI_To_Int (Esize (Entity (Expr))) mod | |
4916 | (Ttypes.Maximum_Alignment * Ttypes.System_Storage_Unit)) | |
ef76538f | 4917 | /= 0 |
9b0986f8 RD |
4918 | then |
4919 | Set_Result (Unknown); | |
4920 | ||
4921 | -- Otherwise same type is decisive | |
4922 | ||
4923 | else | |
4924 | Set_Result (Known_Compatible); | |
4925 | end if; | |
4926 | end if; | |
4927 | ||
4928 | -- Another case to deal with is when there is an explicit size or | |
4929 | -- alignment clause when the types are not the same. If so, then the | |
4930 | -- result is Unknown. We don't need to do this test if the Default is | |
4931 | -- Unknown, since that result will be set in any case. | |
4932 | ||
4933 | elsif Default /= Unknown | |
ef76538f | 4934 | and then (Has_Size_Clause (Etype (Expr)) |
9b0986f8 RD |
4935 | or else |
4936 | Has_Alignment_Clause (Etype (Expr))) | |
4937 | then | |
4938 | Set_Result (Unknown); | |
4939 | ||
4940 | -- If no indication found, set default | |
4941 | ||
4942 | else | |
4943 | Set_Result (Default); | |
4944 | end if; | |
4945 | ||
4946 | -- Return worst result found | |
4947 | ||
4948 | return Result; | |
4949 | end Has_Compatible_Alignment_Internal; | |
4950 | ||
4951 | -- Start of processing for Has_Compatible_Alignment | |
4952 | ||
4953 | begin | |
4954 | -- If Obj has no specified alignment, then set alignment from the type | |
4955 | -- alignment. Perhaps we should always do this, but for sure we should | |
4956 | -- do it when there is an address clause since we can do more if the | |
4957 | -- alignment is known. | |
4958 | ||
4959 | if Unknown_Alignment (Obj) then | |
4960 | Set_Alignment (Obj, Alignment (Etype (Obj))); | |
4961 | end if; | |
4962 | ||
4963 | -- Now do the internal call that does all the work | |
4964 | ||
4965 | return Has_Compatible_Alignment_Internal (Obj, Expr, Unknown); | |
4966 | end Has_Compatible_Alignment; | |
4967 | ||
4968 | ---------------------- | |
4969 | -- Has_Declarations -- | |
4970 | ---------------------- | |
4971 | ||
4972 | function Has_Declarations (N : Node_Id) return Boolean is | |
9b0986f8 | 4973 | begin |
ef76538f AC |
4974 | return Nkind_In (Nkind (N), N_Accept_Statement, |
4975 | N_Block_Statement, | |
4976 | N_Compilation_Unit_Aux, | |
4977 | N_Entry_Body, | |
4978 | N_Package_Body, | |
4979 | N_Protected_Body, | |
4980 | N_Subprogram_Body, | |
4981 | N_Task_Body, | |
4982 | N_Package_Specification); | |
9b0986f8 RD |
4983 | end Has_Declarations; |
4984 | ||
4985 | ------------------------------------------- | |
4986 | -- Has_Discriminant_Dependent_Constraint -- | |
4987 | ------------------------------------------- | |
4988 | ||
4989 | function Has_Discriminant_Dependent_Constraint | |
4990 | (Comp : Entity_Id) return Boolean | |
4991 | is | |
4992 | Comp_Decl : constant Node_Id := Parent (Comp); | |
4993 | Subt_Indic : constant Node_Id := | |
4994 | Subtype_Indication (Component_Definition (Comp_Decl)); | |
4995 | Constr : Node_Id; | |
4996 | Assn : Node_Id; | |
4997 | ||
4998 | begin | |
4999 | if Nkind (Subt_Indic) = N_Subtype_Indication then | |
5000 | Constr := Constraint (Subt_Indic); | |
5001 | ||
5002 | if Nkind (Constr) = N_Index_Or_Discriminant_Constraint then | |
5003 | Assn := First (Constraints (Constr)); | |
5004 | while Present (Assn) loop | |
5005 | case Nkind (Assn) is | |
5006 | when N_Subtype_Indication | | |
5007 | N_Range | | |
5008 | N_Identifier | |
edd63e9b ES |
5009 | => |
5010 | if Depends_On_Discriminant (Assn) then | |
5011 | return True; | |
5012 | end if; | |
5013 | ||
5014 | when N_Discriminant_Association => | |
5015 | if Depends_On_Discriminant (Expression (Assn)) then | |
5016 | return True; | |
5017 | end if; | |
5018 | ||
5019 | when others => | |
5020 | null; | |
5021 | ||
5022 | end case; | |
5023 | ||
5024 | Next (Assn); | |
5025 | end loop; | |
5026 | end if; | |
5027 | end if; | |
5028 | ||
5029 | return False; | |
5030 | end Has_Discriminant_Dependent_Constraint; | |
5031 | ||
996ae0b0 RK |
5032 | -------------------- |
5033 | -- Has_Infinities -- | |
5034 | -------------------- | |
5035 | ||
5036 | function Has_Infinities (E : Entity_Id) return Boolean is | |
5037 | begin | |
5038 | return | |
5039 | Is_Floating_Point_Type (E) | |
5040 | and then Nkind (Scalar_Range (E)) = N_Range | |
5041 | and then Includes_Infinities (Scalar_Range (E)); | |
5042 | end Has_Infinities; | |
5043 | ||
ce2b6ba5 JM |
5044 | -------------------- |
5045 | -- Has_Interfaces -- | |
5046 | -------------------- | |
5047 | ||
5048 | function Has_Interfaces | |
5049 | (T : Entity_Id; | |
5050 | Use_Full_View : Boolean := True) return Boolean | |
5051 | is | |
b4d7b435 | 5052 | Typ : Entity_Id := Base_Type (T); |
ce2b6ba5 JM |
5053 | |
5054 | begin | |
5055 | -- Handle concurrent types | |
5056 | ||
b4d7b435 AC |
5057 | if Is_Concurrent_Type (Typ) then |
5058 | Typ := Corresponding_Record_Type (Typ); | |
ce2b6ba5 JM |
5059 | end if; |
5060 | ||
5061 | if not Present (Typ) | |
5062 | or else not Is_Record_Type (Typ) | |
5063 | or else not Is_Tagged_Type (Typ) | |
5064 | then | |
5065 | return False; | |
5066 | end if; | |
5067 | ||
5068 | -- Handle private types | |
5069 | ||
5070 | if Use_Full_View | |
5071 | and then Present (Full_View (Typ)) | |
5072 | then | |
5073 | Typ := Full_View (Typ); | |
5074 | end if; | |
5075 | ||
5076 | -- Handle concurrent record types | |
5077 | ||
5078 | if Is_Concurrent_Record_Type (Typ) | |
5079 | and then Is_Non_Empty_List (Abstract_Interface_List (Typ)) | |
5080 | then | |
5081 | return True; | |
5082 | end if; | |
5083 | ||
5084 | loop | |
5085 | if Is_Interface (Typ) | |
5086 | or else | |
5087 | (Is_Record_Type (Typ) | |
5088 | and then Present (Interfaces (Typ)) | |
5089 | and then not Is_Empty_Elmt_List (Interfaces (Typ))) | |
5090 | then | |
5091 | return True; | |
5092 | end if; | |
5093 | ||
5094 | exit when Etype (Typ) = Typ | |
5095 | ||
5096 | -- Handle private types | |
5097 | ||
5098 | or else (Present (Full_View (Etype (Typ))) | |
5099 | and then Full_View (Etype (Typ)) = Typ) | |
5100 | ||
5101 | -- Protect the frontend against wrong source with cyclic | |
5102 | -- derivations | |
5103 | ||
5104 | or else Etype (Typ) = T; | |
5105 | ||
5106 | -- Climb to the ancestor type handling private types | |
5107 | ||
5108 | if Present (Full_View (Etype (Typ))) then | |
5109 | Typ := Full_View (Etype (Typ)); | |
5110 | else | |
5111 | Typ := Etype (Typ); | |
5112 | end if; | |
5113 | end loop; | |
5114 | ||
5115 | return False; | |
5116 | end Has_Interfaces; | |
5117 | ||
9b0986f8 RD |
5118 | ------------------------ |
5119 | -- Has_Null_Exclusion -- | |
5120 | ------------------------ | |
5121 | ||
5122 | function Has_Null_Exclusion (N : Node_Id) return Boolean is | |
5123 | begin | |
5124 | case Nkind (N) is | |
5125 | when N_Access_Definition | | |
5126 | N_Access_Function_Definition | | |
5127 | N_Access_Procedure_Definition | | |
5128 | N_Access_To_Object_Definition | | |
5129 | N_Allocator | | |
5130 | N_Derived_Type_Definition | | |
5131 | N_Function_Specification | | |
5132 | N_Subtype_Declaration => | |
5133 | return Null_Exclusion_Present (N); | |
5134 | ||
5135 | when N_Component_Definition | | |
5136 | N_Formal_Object_Declaration | | |
5137 | N_Object_Renaming_Declaration => | |
5138 | if Present (Subtype_Mark (N)) then | |
5139 | return Null_Exclusion_Present (N); | |
5140 | else pragma Assert (Present (Access_Definition (N))); | |
5141 | return Null_Exclusion_Present (Access_Definition (N)); | |
5142 | end if; | |
5143 | ||
5144 | when N_Discriminant_Specification => | |
5145 | if Nkind (Discriminant_Type (N)) = N_Access_Definition then | |
5146 | return Null_Exclusion_Present (Discriminant_Type (N)); | |
5147 | else | |
5148 | return Null_Exclusion_Present (N); | |
5149 | end if; | |
5150 | ||
5151 | when N_Object_Declaration => | |
5152 | if Nkind (Object_Definition (N)) = N_Access_Definition then | |
5153 | return Null_Exclusion_Present (Object_Definition (N)); | |
5154 | else | |
5155 | return Null_Exclusion_Present (N); | |
5156 | end if; | |
5157 | ||
5158 | when N_Parameter_Specification => | |
5159 | if Nkind (Parameter_Type (N)) = N_Access_Definition then | |
5160 | return Null_Exclusion_Present (Parameter_Type (N)); | |
5161 | else | |
5162 | return Null_Exclusion_Present (N); | |
5163 | end if; | |
5164 | ||
5165 | when others => | |
5166 | return False; | |
5167 | ||
5168 | end case; | |
5169 | end Has_Null_Exclusion; | |
5170 | ||
fbf5a39b AC |
5171 | ------------------------ |
5172 | -- Has_Null_Extension -- | |
5173 | ------------------------ | |
5174 | ||
5175 | function Has_Null_Extension (T : Entity_Id) return Boolean is | |
5176 | B : constant Entity_Id := Base_Type (T); | |
5177 | Comps : Node_Id; | |
5178 | Ext : Node_Id; | |
5179 | ||
5180 | begin | |
5181 | if Nkind (Parent (B)) = N_Full_Type_Declaration | |
5182 | and then Present (Record_Extension_Part (Type_Definition (Parent (B)))) | |
5183 | then | |
5184 | Ext := Record_Extension_Part (Type_Definition (Parent (B))); | |
5185 | ||
5186 | if Present (Ext) then | |
5187 | if Null_Present (Ext) then | |
5188 | return True; | |
5189 | else | |
5190 | Comps := Component_List (Ext); | |
5191 | ||
5192 | -- The null component list is rewritten during analysis to | |
5193 | -- include the parent component. Any other component indicates | |
5194 | -- that the extension was not originally null. | |
5195 | ||
5196 | return Null_Present (Comps) | |
5197 | or else No (Next (First (Component_Items (Comps)))); | |
5198 | end if; | |
5199 | else | |
5200 | return False; | |
5201 | end if; | |
5202 | ||
5203 | else | |
5204 | return False; | |
5205 | end if; | |
5206 | end Has_Null_Extension; | |
5207 | ||
ce4a6e84 RD |
5208 | ------------------------------- |
5209 | -- Has_Overriding_Initialize -- | |
5210 | ------------------------------- | |
5211 | ||
5212 | function Has_Overriding_Initialize (T : Entity_Id) return Boolean is | |
5213 | BT : constant Entity_Id := Base_Type (T); | |
ce4a6e84 RD |
5214 | P : Elmt_Id; |
5215 | ||
5216 | begin | |
5217 | if Is_Controlled (BT) then | |
c228a069 AC |
5218 | if Is_RTU (Scope (BT), Ada_Finalization) then |
5219 | return False; | |
ce4a6e84 RD |
5220 | |
5221 | elsif Present (Primitive_Operations (BT)) then | |
5222 | P := First_Elmt (Primitive_Operations (BT)); | |
5223 | while Present (P) loop | |
c228a069 AC |
5224 | declare |
5225 | Init : constant Entity_Id := Node (P); | |
5226 | Formal : constant Entity_Id := First_Formal (Init); | |
5227 | begin | |
5228 | if Ekind (Init) = E_Procedure | |
5229 | and then Chars (Init) = Name_Initialize | |
5230 | and then Comes_From_Source (Init) | |
5231 | and then Present (Formal) | |
5232 | and then Etype (Formal) = BT | |
5233 | and then No (Next_Formal (Formal)) | |
5234 | and then (Ada_Version < Ada_2012 | |
5235 | or else not Null_Present (Parent (Init))) | |
5236 | then | |
5237 | return True; | |
5238 | end if; | |
5239 | end; | |
ce4a6e84 RD |
5240 | |
5241 | Next_Elmt (P); | |
5242 | end loop; | |
5243 | end if; | |
5244 | ||
c228a069 AC |
5245 | -- Here if type itself does not have a non-null Initialize operation: |
5246 | -- check immediate ancestor. | |
ce4a6e84 | 5247 | |
c228a069 AC |
5248 | if Is_Derived_Type (BT) |
5249 | and then Has_Overriding_Initialize (Etype (BT)) | |
5250 | then | |
5251 | return True; | |
5252 | end if; | |
ce4a6e84 | 5253 | end if; |
c228a069 AC |
5254 | |
5255 | return False; | |
ce4a6e84 RD |
5256 | end Has_Overriding_Initialize; |
5257 | ||
9b0986f8 RD |
5258 | -------------------------------------- |
5259 | -- Has_Preelaborable_Initialization -- | |
5260 | -------------------------------------- | |
5261 | ||
5262 | function Has_Preelaborable_Initialization (E : Entity_Id) return Boolean is | |
5263 | Has_PE : Boolean; | |
5264 | ||
5265 | procedure Check_Components (E : Entity_Id); | |
5266 | -- Check component/discriminant chain, sets Has_PE False if a component | |
5267 | -- or discriminant does not meet the preelaborable initialization rules. | |
5268 | ||
5269 | ---------------------- | |
5270 | -- Check_Components -- | |
5271 | ---------------------- | |
5272 | ||
5273 | procedure Check_Components (E : Entity_Id) is | |
5274 | Ent : Entity_Id; | |
5275 | Exp : Node_Id; | |
5276 | ||
31b5873d GD |
5277 | function Is_Preelaborable_Expression (N : Node_Id) return Boolean; |
5278 | -- Returns True if and only if the expression denoted by N does not | |
5279 | -- violate restrictions on preelaborable constructs (RM-10.2.1(5-9)). | |
5280 | ||
5281 | --------------------------------- | |
5282 | -- Is_Preelaborable_Expression -- | |
5283 | --------------------------------- | |
5284 | ||
5285 | function Is_Preelaborable_Expression (N : Node_Id) return Boolean is | |
5286 | Exp : Node_Id; | |
5287 | Assn : Node_Id; | |
5288 | Choice : Node_Id; | |
5289 | Comp_Type : Entity_Id; | |
5290 | Is_Array_Aggr : Boolean; | |
5291 | ||
5292 | begin | |
5293 | if Is_Static_Expression (N) then | |
5294 | return True; | |
5295 | ||
5296 | elsif Nkind (N) = N_Null then | |
5297 | return True; | |
5298 | ||
7f0e4cdb BD |
5299 | -- Attributes are allowed in general, even if their prefix is a |
5300 | -- formal type. (It seems that certain attributes known not to be | |
5301 | -- static might not be allowed, but there are no rules to prevent | |
5302 | -- them.) | |
5303 | ||
5304 | elsif Nkind (N) = N_Attribute_Reference then | |
5305 | return True; | |
5306 | ||
5307 | -- The name of a discriminant evaluated within its parent type is | |
5308 | -- defined to be preelaborable (10.2.1(8)). Note that we test for | |
5309 | -- names that denote discriminals as well as discriminants to | |
5310 | -- catch references occurring within init procs. | |
5311 | ||
5312 | elsif Is_Entity_Name (N) | |
31b5873d | 5313 | and then |
7f0e4cdb BD |
5314 | (Ekind (Entity (N)) = E_Discriminant |
5315 | or else | |
5316 | ((Ekind (Entity (N)) = E_Constant | |
5317 | or else Ekind (Entity (N)) = E_In_Parameter) | |
5318 | and then Present (Discriminal_Link (Entity (N))))) | |
31b5873d GD |
5319 | then |
5320 | return True; | |
5321 | ||
5322 | elsif Nkind (N) = N_Qualified_Expression then | |
5323 | return Is_Preelaborable_Expression (Expression (N)); | |
5324 | ||
5325 | -- For aggregates we have to check that each of the associations | |
5326 | -- is preelaborable. | |
5327 | ||
5328 | elsif Nkind (N) = N_Aggregate | |
5329 | or else Nkind (N) = N_Extension_Aggregate | |
5330 | then | |
5331 | Is_Array_Aggr := Is_Array_Type (Etype (N)); | |
5332 | ||
5333 | if Is_Array_Aggr then | |
5334 | Comp_Type := Component_Type (Etype (N)); | |
5335 | end if; | |
5336 | ||
5337 | -- Check the ancestor part of extension aggregates, which must | |
5338 | -- be either the name of a type that has preelaborable init or | |
5339 | -- an expression that is preelaborable. | |
5340 | ||
5341 | if Nkind (N) = N_Extension_Aggregate then | |
5342 | declare | |
5343 | Anc_Part : constant Node_Id := Ancestor_Part (N); | |
5344 | ||
5345 | begin | |
5346 | if Is_Entity_Name (Anc_Part) | |
5347 | and then Is_Type (Entity (Anc_Part)) | |
5348 | then | |
5349 | if not Has_Preelaborable_Initialization | |
5350 | (Entity (Anc_Part)) | |
5351 | then | |
5352 | return False; | |
5353 | end if; | |
5354 | ||
5355 | elsif not Is_Preelaborable_Expression (Anc_Part) then | |
5356 | return False; | |
5357 | end if; | |
5358 | end; | |
5359 | end if; | |
5360 | ||
5361 | -- Check positional associations | |
5362 | ||
5363 | Exp := First (Expressions (N)); | |
5364 | while Present (Exp) loop | |
5365 | if not Is_Preelaborable_Expression (Exp) then | |
5366 | return False; | |
5367 | end if; | |
5368 | ||
5369 | Next (Exp); | |
5370 | end loop; | |
5371 | ||
5372 | -- Check named associations | |
5373 | ||
5374 | Assn := First (Component_Associations (N)); | |
5375 | while Present (Assn) loop | |
5376 | Choice := First (Choices (Assn)); | |
5377 | while Present (Choice) loop | |
5378 | if Is_Array_Aggr then | |
5379 | if Nkind (Choice) = N_Others_Choice then | |
5380 | null; | |
5381 | ||
5382 | elsif Nkind (Choice) = N_Range then | |
5383 | if not Is_Static_Range (Choice) then | |
5384 | return False; | |
5385 | end if; | |
5386 | ||
5387 | elsif not Is_Static_Expression (Choice) then | |
5388 | return False; | |
5389 | end if; | |
5390 | ||
5391 | else | |
5392 | Comp_Type := Etype (Choice); | |
5393 | end if; | |
5394 | ||
5395 | Next (Choice); | |
5396 | end loop; | |
5397 | ||
5398 | -- If the association has a <> at this point, then we have | |
5399 | -- to check whether the component's type has preelaborable | |
5400 | -- initialization. Note that this only occurs when the | |
5401 | -- association's corresponding component does not have a | |
5402 | -- default expression, the latter case having already been | |
5403 | -- expanded as an expression for the association. | |
5404 | ||
5405 | if Box_Present (Assn) then | |
5406 | if not Has_Preelaborable_Initialization (Comp_Type) then | |
5407 | return False; | |
5408 | end if; | |
5409 | ||
5410 | -- In the expression case we check whether the expression | |
5411 | -- is preelaborable. | |
5412 | ||
5413 | elsif | |
5414 | not Is_Preelaborable_Expression (Expression (Assn)) | |
5415 | then | |
5416 | return False; | |
5417 | end if; | |
5418 | ||
5419 | Next (Assn); | |
5420 | end loop; | |
5421 | ||
5422 | -- If we get here then aggregate as a whole is preelaborable | |
5423 | ||
5424 | return True; | |
5425 | ||
5426 | -- All other cases are not preelaborable | |
5427 | ||
5428 | else | |
5429 | return False; | |
5430 | end if; | |
5431 | end Is_Preelaborable_Expression; | |
5432 | ||
5433 | -- Start of processing for Check_Components | |
5434 | ||
9b0986f8 RD |
5435 | begin |
5436 | -- Loop through entities of record or protected type | |
5437 | ||
5438 | Ent := E; | |
5439 | while Present (Ent) loop | |
5440 | ||
5441 | -- We are interested only in components and discriminants | |
5442 | ||
23b86353 | 5443 | Exp := Empty; |
3e5daac4 | 5444 | |
23b86353 AC |
5445 | case Ekind (Ent) is |
5446 | when E_Component => | |
8a95f4e8 | 5447 | |
23b86353 AC |
5448 | -- Get default expression if any. If there is no declaration |
5449 | -- node, it means we have an internal entity. The parent and | |
5450 | -- tag fields are examples of such entities. For such cases, | |
5451 | -- we just test the type of the entity. | |
9b0986f8 | 5452 | |
23b86353 AC |
5453 | if Present (Declaration_Node (Ent)) then |
5454 | Exp := Expression (Declaration_Node (Ent)); | |
5455 | end if; | |
9b0986f8 | 5456 | |
23b86353 | 5457 | when E_Discriminant => |
9b0986f8 | 5458 | |
23b86353 AC |
5459 | -- Note: for a renamed discriminant, the Declaration_Node |
5460 | -- may point to the one from the ancestor, and have a | |
5461 | -- different expression, so use the proper attribute to | |
5462 | -- retrieve the expression from the derived constraint. | |
5463 | ||
5464 | Exp := Discriminant_Default_Value (Ent); | |
9b0986f8 | 5465 | |
23b86353 AC |
5466 | when others => |
5467 | goto Check_Next_Entity; | |
23b86353 AC |
5468 | end case; |
5469 | ||
5470 | -- A component has PI if it has no default expression and the | |
5471 | -- component type has PI. | |
5472 | ||
5473 | if No (Exp) then | |
5474 | if not Has_Preelaborable_Initialization (Etype (Ent)) then | |
9b0986f8 RD |
5475 | Has_PE := False; |
5476 | exit; | |
5477 | end if; | |
23b86353 AC |
5478 | |
5479 | -- Require the default expression to be preelaborable | |
5480 | ||
5481 | elsif not Is_Preelaborable_Expression (Exp) then | |
5482 | Has_PE := False; | |
5483 | exit; | |
9b0986f8 RD |
5484 | end if; |
5485 | ||
23b86353 | 5486 | <<Check_Next_Entity>> |
9b0986f8 RD |
5487 | Next_Entity (Ent); |
5488 | end loop; | |
5489 | end Check_Components; | |
5490 | ||
5491 | -- Start of processing for Has_Preelaborable_Initialization | |
5492 | ||
5493 | begin | |
f377c995 HK |
5494 | -- Immediate return if already marked as known preelaborable init. This |
5495 | -- covers types for which this function has already been called once | |
5496 | -- and returned True (in which case the result is cached), and also | |
5497 | -- types to which a pragma Preelaborable_Initialization applies. | |
9b0986f8 RD |
5498 | |
5499 | if Known_To_Have_Preelab_Init (E) then | |
5500 | return True; | |
5501 | end if; | |
5502 | ||
31b5873d GD |
5503 | -- If the type is a subtype representing a generic actual type, then |
5504 | -- test whether its base type has preelaborable initialization since | |
5505 | -- the subtype representing the actual does not inherit this attribute | |
5506 | -- from the actual or formal. (but maybe it should???) | |
5507 | ||
5508 | if Is_Generic_Actual_Type (E) then | |
5509 | return Has_Preelaborable_Initialization (Base_Type (E)); | |
5510 | end if; | |
5511 | ||
9b0986f8 RD |
5512 | -- All elementary types have preelaborable initialization |
5513 | ||
5514 | if Is_Elementary_Type (E) then | |
5515 | Has_PE := True; | |
5516 | ||
5517 | -- Array types have PI if the component type has PI | |
5518 | ||
5519 | elsif Is_Array_Type (E) then | |
5520 | Has_PE := Has_Preelaborable_Initialization (Component_Type (E)); | |
5521 | ||
f377c995 HK |
5522 | -- A derived type has preelaborable initialization if its parent type |
5523 | -- has preelaborable initialization and (in the case of a derived record | |
5524 | -- extension) if the non-inherited components all have preelaborable | |
5525 | -- initialization. However, a user-defined controlled type with an | |
5526 | -- overriding Initialize procedure does not have preelaborable | |
5527 | -- initialization. | |
9b0986f8 | 5528 | |
f377c995 HK |
5529 | elsif Is_Derived_Type (E) then |
5530 | ||
9f4e4881 GD |
5531 | -- If the derived type is a private extension then it doesn't have |
5532 | -- preelaborable initialization. | |
5533 | ||
5534 | if Ekind (Base_Type (E)) = E_Record_Type_With_Private then | |
5535 | return False; | |
5536 | end if; | |
5537 | ||
f377c995 HK |
5538 | -- First check whether ancestor type has preelaborable initialization |
5539 | ||
5540 | Has_PE := Has_Preelaborable_Initialization (Etype (Base_Type (E))); | |
5541 | ||
5542 | -- If OK, check extension components (if any) | |
5543 | ||
5544 | if Has_PE and then Is_Record_Type (E) then | |
5545 | Check_Components (First_Entity (E)); | |
5546 | end if; | |
9b0986f8 | 5547 | |
f377c995 HK |
5548 | -- Check specifically for 10.2.1(11.4/2) exception: a controlled type |
5549 | -- with a user defined Initialize procedure does not have PI. | |
9b0986f8 | 5550 | |
f377c995 HK |
5551 | if Has_PE |
5552 | and then Is_Controlled (E) | |
ce4a6e84 | 5553 | and then Has_Overriding_Initialize (E) |
9b0986f8 | 5554 | then |
ce4a6e84 | 5555 | Has_PE := False; |
9b0986f8 RD |
5556 | end if; |
5557 | ||
9f4e4881 GD |
5558 | -- Private types not derived from a type having preelaborable init and |
5559 | -- that are not marked with pragma Preelaborable_Initialization do not | |
5560 | -- have preelaborable initialization. | |
5561 | ||
5562 | elsif Is_Private_Type (E) then | |
5563 | return False; | |
5564 | ||
f377c995 HK |
5565 | -- Record type has PI if it is non private and all components have PI |
5566 | ||
5567 | elsif Is_Record_Type (E) then | |
5568 | Has_PE := True; | |
5569 | Check_Components (First_Entity (E)); | |
5570 | ||
5571 | -- Protected types must not have entries, and components must meet | |
9b0986f8 RD |
5572 | -- same set of rules as for record components. |
5573 | ||
5574 | elsif Is_Protected_Type (E) then | |
5575 | if Has_Entries (E) then | |
5576 | Has_PE := False; | |
5577 | else | |
5578 | Has_PE := True; | |
5579 | Check_Components (First_Entity (E)); | |
5580 | Check_Components (First_Private_Entity (E)); | |
5581 | end if; | |
5582 | ||
9b0986f8 RD |
5583 | -- Type System.Address always has preelaborable initialization |
5584 | ||
5585 | elsif Is_RTE (E, RE_Address) then | |
5586 | Has_PE := True; | |
5587 | ||
f377c995 | 5588 | -- In all other cases, type does not have preelaborable initialization |
9b0986f8 RD |
5589 | |
5590 | else | |
5591 | return False; | |
5592 | end if; | |
5593 | ||
f377c995 HK |
5594 | -- If type has preelaborable initialization, cache result |
5595 | ||
9b0986f8 RD |
5596 | if Has_PE then |
5597 | Set_Known_To_Have_Preelab_Init (E); | |
5598 | end if; | |
5599 | ||
5600 | return Has_PE; | |
5601 | end Has_Preelaborable_Initialization; | |
5602 | ||
996ae0b0 RK |
5603 | --------------------------- |
5604 | -- Has_Private_Component -- | |
5605 | --------------------------- | |
5606 | ||
5607 | function Has_Private_Component (Type_Id : Entity_Id) return Boolean is | |
5608 | Btype : Entity_Id := Base_Type (Type_Id); | |
5609 | Component : Entity_Id; | |
5610 | ||
5611 | begin | |
5612 | if Error_Posted (Type_Id) | |
5613 | or else Error_Posted (Btype) | |
5614 | then | |
5615 | return False; | |
5616 | end if; | |
5617 | ||
5618 | if Is_Class_Wide_Type (Btype) then | |
5619 | Btype := Root_Type (Btype); | |
5620 | end if; | |
5621 | ||
5622 | if Is_Private_Type (Btype) then | |
5623 | declare | |
5624 | UT : constant Entity_Id := Underlying_Type (Btype); | |
5625 | begin | |
5626 | if No (UT) then | |
996ae0b0 RK |
5627 | if No (Full_View (Btype)) then |
5628 | return not Is_Generic_Type (Btype) | |
5629 | and then not Is_Generic_Type (Root_Type (Btype)); | |
996ae0b0 RK |
5630 | else |
5631 | return not Is_Generic_Type (Root_Type (Full_View (Btype))); | |
5632 | end if; | |
996ae0b0 RK |
5633 | else |
5634 | return not Is_Frozen (UT) and then Has_Private_Component (UT); | |
5635 | end if; | |
5636 | end; | |
31b5873d | 5637 | |
996ae0b0 RK |
5638 | elsif Is_Array_Type (Btype) then |
5639 | return Has_Private_Component (Component_Type (Btype)); | |
5640 | ||
5641 | elsif Is_Record_Type (Btype) then | |
996ae0b0 RK |
5642 | Component := First_Component (Btype); |
5643 | while Present (Component) loop | |
996ae0b0 RK |
5644 | if Has_Private_Component (Etype (Component)) then |
5645 | return True; | |
5646 | end if; | |
5647 | ||
5648 | Next_Component (Component); | |
5649 | end loop; | |
5650 | ||
5651 | return False; | |
5652 | ||
5653 | elsif Is_Protected_Type (Btype) | |
5654 | and then Present (Corresponding_Record_Type (Btype)) | |
5655 | then | |
5656 | return Has_Private_Component (Corresponding_Record_Type (Btype)); | |
5657 | ||
5658 | else | |
5659 | return False; | |
5660 | end if; | |
5661 | end Has_Private_Component; | |
5662 | ||
e280f981 AC |
5663 | ----------------------------- |
5664 | -- Has_Static_Array_Bounds -- | |
5665 | ----------------------------- | |
5666 | ||
5667 | function Has_Static_Array_Bounds (Typ : Node_Id) return Boolean is | |
5668 | Ndims : constant Nat := Number_Dimensions (Typ); | |
5669 | ||
5670 | Index : Node_Id; | |
5671 | Low : Node_Id; | |
5672 | High : Node_Id; | |
5673 | ||
5674 | begin | |
5675 | -- Unconstrained types do not have static bounds | |
5676 | ||
5677 | if not Is_Constrained (Typ) then | |
5678 | return False; | |
5679 | end if; | |
5680 | ||
2c1b72d7 | 5681 | -- First treat string literals specially, as the lower bound and length |
e280f981 AC |
5682 | -- of string literals are not stored like those of arrays. |
5683 | ||
5684 | -- A string literal always has static bounds | |
5685 | ||
5686 | if Ekind (Typ) = E_String_Literal_Subtype then | |
5687 | return True; | |
5688 | end if; | |
5689 | ||
5690 | -- Treat all dimensions in turn | |
5691 | ||
5692 | Index := First_Index (Typ); | |
5693 | for Indx in 1 .. Ndims loop | |
5694 | ||
5695 | -- In case of an erroneous index which is not a discrete type, return | |
5696 | -- that the type is not static. | |
5697 | ||
5698 | if not Is_Discrete_Type (Etype (Index)) | |
5699 | or else Etype (Index) = Any_Type | |
5700 | then | |
5701 | return False; | |
5702 | end if; | |
5703 | ||
5704 | Get_Index_Bounds (Index, Low, High); | |
5705 | ||
5706 | if Error_Posted (Low) or else Error_Posted (High) then | |
5707 | return False; | |
5708 | end if; | |
5709 | ||
2c1b72d7 AC |
5710 | if Is_OK_Static_Expression (Low) |
5711 | and then | |
5712 | Is_OK_Static_Expression (High) | |
e280f981 AC |
5713 | then |
5714 | null; | |
5715 | else | |
5716 | return False; | |
5717 | end if; | |
5718 | ||
5719 | Next (Index); | |
5720 | end loop; | |
5721 | ||
5722 | -- If we fall through the loop, all indexes matched | |
5723 | ||
5724 | return True; | |
5725 | end Has_Static_Array_Bounds; | |
5726 | ||
1735e55d AC |
5727 | ---------------- |
5728 | -- Has_Stream -- | |
5729 | ---------------- | |
5730 | ||
5731 | function Has_Stream (T : Entity_Id) return Boolean is | |
5732 | E : Entity_Id; | |
5733 | ||
5734 | begin | |
5735 | if No (T) then | |
5736 | return False; | |
5737 | ||
5738 | elsif Is_RTE (Root_Type (T), RE_Root_Stream_Type) then | |
5739 | return True; | |
5740 | ||
5741 | elsif Is_Array_Type (T) then | |
5742 | return Has_Stream (Component_Type (T)); | |
5743 | ||
5744 | elsif Is_Record_Type (T) then | |
5745 | E := First_Component (T); | |
5746 | while Present (E) loop | |
5747 | if Has_Stream (Etype (E)) then | |
5748 | return True; | |
5749 | else | |
5750 | Next_Component (E); | |
5751 | end if; | |
5752 | end loop; | |
5753 | ||
5754 | return False; | |
5755 | ||
5756 | elsif Is_Private_Type (T) then | |
5757 | return Has_Stream (Underlying_Type (T)); | |
5758 | ||
5759 | else | |
5760 | return False; | |
5761 | end if; | |
5762 | end Has_Stream; | |
5763 | ||
cefce34c JM |
5764 | ---------------- |
5765 | -- Has_Suffix -- | |
5766 | ---------------- | |
5767 | ||
5768 | function Has_Suffix (E : Entity_Id; Suffix : Character) return Boolean is | |
5769 | begin | |
5770 | Get_Name_String (Chars (E)); | |
5771 | return Name_Buffer (Name_Len) = Suffix; | |
5772 | end Has_Suffix; | |
5773 | ||
996ae0b0 RK |
5774 | -------------------------- |
5775 | -- Has_Tagged_Component -- | |
5776 | -------------------------- | |
5777 | ||
5778 | function Has_Tagged_Component (Typ : Entity_Id) return Boolean is | |
5779 | Comp : Entity_Id; | |
5780 | ||
5781 | begin | |
5782 | if Is_Private_Type (Typ) | |
5783 | and then Present (Underlying_Type (Typ)) | |
5784 | then | |
5785 | return Has_Tagged_Component (Underlying_Type (Typ)); | |
5786 | ||
5787 | elsif Is_Array_Type (Typ) then | |
5788 | return Has_Tagged_Component (Component_Type (Typ)); | |
5789 | ||
5790 | elsif Is_Tagged_Type (Typ) then | |
5791 | return True; | |
5792 | ||
5793 | elsif Is_Record_Type (Typ) then | |
5794 | Comp := First_Component (Typ); | |
996ae0b0 RK |
5795 | while Present (Comp) loop |
5796 | if Has_Tagged_Component (Etype (Comp)) then | |
5797 | return True; | |
5798 | end if; | |
5799 | ||
f16d05d9 | 5800 | Next_Component (Comp); |
996ae0b0 RK |
5801 | end loop; |
5802 | ||
5803 | return False; | |
5804 | ||
5805 | else | |
5806 | return False; | |
5807 | end if; | |
5808 | end Has_Tagged_Component; | |
5809 | ||
bfae1846 AC |
5810 | ------------------------- |
5811 | -- Implementation_Kind -- | |
5812 | ------------------------- | |
5813 | ||
5814 | function Implementation_Kind (Subp : Entity_Id) return Name_Id is | |
5815 | Impl_Prag : constant Node_Id := Get_Rep_Pragma (Subp, Name_Implemented); | |
bfae1846 AC |
5816 | begin |
5817 | pragma Assert (Present (Impl_Prag)); | |
bfae1846 AC |
5818 | return |
5819 | Chars (Expression (Last (Pragma_Argument_Associations (Impl_Prag)))); | |
5820 | end Implementation_Kind; | |
5821 | ||
ce2b6ba5 JM |
5822 | -------------------------- |
5823 | -- Implements_Interface -- | |
5824 | -------------------------- | |
5825 | ||
5826 | function Implements_Interface | |
5827 | (Typ_Ent : Entity_Id; | |
5828 | Iface_Ent : Entity_Id; | |
5829 | Exclude_Parents : Boolean := False) return Boolean | |
5830 | is | |
5831 | Ifaces_List : Elist_Id; | |
5832 | Elmt : Elmt_Id; | |
0e41a941 AC |
5833 | Iface : Entity_Id := Base_Type (Iface_Ent); |
5834 | Typ : Entity_Id := Base_Type (Typ_Ent); | |
ce2b6ba5 JM |
5835 | |
5836 | begin | |
0e41a941 AC |
5837 | if Is_Class_Wide_Type (Typ) then |
5838 | Typ := Root_Type (Typ); | |
ce2b6ba5 JM |
5839 | end if; |
5840 | ||
5841 | if not Has_Interfaces (Typ) then | |
5842 | return False; | |
5843 | end if; | |
5844 | ||
0e41a941 AC |
5845 | if Is_Class_Wide_Type (Iface) then |
5846 | Iface := Root_Type (Iface); | |
5847 | end if; | |
5848 | ||
ce2b6ba5 JM |
5849 | Collect_Interfaces (Typ, Ifaces_List); |
5850 | ||
5851 | Elmt := First_Elmt (Ifaces_List); | |
5852 | while Present (Elmt) loop | |
4ac2477e | 5853 | if Is_Ancestor (Node (Elmt), Typ, Use_Full_View => True) |
ce2b6ba5 JM |
5854 | and then Exclude_Parents |
5855 | then | |
5856 | null; | |
5857 | ||
5858 | elsif Node (Elmt) = Iface then | |
5859 | return True; | |
5860 | end if; | |
5861 | ||
5862 | Next_Elmt (Elmt); | |
5863 | end loop; | |
5864 | ||
5865 | return False; | |
5866 | end Implements_Interface; | |
5867 | ||
996ae0b0 RK |
5868 | ----------------- |
5869 | -- In_Instance -- | |
5870 | ----------------- | |
5871 | ||
5872 | function In_Instance return Boolean is | |
9b0986f8 RD |
5873 | Curr_Unit : constant Entity_Id := Cunit_Entity (Current_Sem_Unit); |
5874 | S : Entity_Id; | |
996ae0b0 RK |
5875 | |
5876 | begin | |
9b0986f8 | 5877 | S := Current_Scope; |
996ae0b0 RK |
5878 | while Present (S) |
5879 | and then S /= Standard_Standard | |
5880 | loop | |
5881 | if (Ekind (S) = E_Function | |
5882 | or else Ekind (S) = E_Package | |
5883 | or else Ekind (S) = E_Procedure) | |
5884 | and then Is_Generic_Instance (S) | |
5885 | then | |
9b0986f8 RD |
5886 | -- A child instance is always compiled in the context of a parent |
5887 | -- instance. Nevertheless, the actuals are not analyzed in an | |
5888 | -- instance context. We detect this case by examining the current | |
5889 | -- compilation unit, which must be a child instance, and checking | |
5890 | -- that it is not currently on the scope stack. | |
5891 | ||
5892 | if Is_Child_Unit (Curr_Unit) | |
5893 | and then | |
5894 | Nkind (Unit (Cunit (Current_Sem_Unit))) | |
5895 | = N_Package_Instantiation | |
5896 | and then not In_Open_Scopes (Curr_Unit) | |
5897 | then | |
5898 | return False; | |
5899 | else | |
5900 | return True; | |
5901 | end if; | |
996ae0b0 RK |
5902 | end if; |
5903 | ||
5904 | S := Scope (S); | |
5905 | end loop; | |
5906 | ||
5907 | return False; | |
5908 | end In_Instance; | |
5909 | ||
5910 | ---------------------- | |
5911 | -- In_Instance_Body -- | |
5912 | ---------------------- | |
5913 | ||
5914 | function In_Instance_Body return Boolean is | |
9b0986f8 | 5915 | S : Entity_Id; |
996ae0b0 RK |
5916 | |
5917 | begin | |
9b0986f8 | 5918 | S := Current_Scope; |
996ae0b0 RK |
5919 | while Present (S) |
5920 | and then S /= Standard_Standard | |
5921 | loop | |
5922 | if (Ekind (S) = E_Function | |
5923 | or else Ekind (S) = E_Procedure) | |
5924 | and then Is_Generic_Instance (S) | |
5925 | then | |
5926 | return True; | |
5927 | ||
5928 | elsif Ekind (S) = E_Package | |
5929 | and then In_Package_Body (S) | |
5930 | and then Is_Generic_Instance (S) | |
5931 | then | |
5932 | return True; | |
5933 | end if; | |
5934 | ||
5935 | S := Scope (S); | |
5936 | end loop; | |
5937 | ||
5938 | return False; | |
5939 | end In_Instance_Body; | |
5940 | ||
5941 | ----------------------------- | |
5942 | -- In_Instance_Not_Visible -- | |
5943 | ----------------------------- | |
5944 | ||
5945 | function In_Instance_Not_Visible return Boolean is | |
9b0986f8 | 5946 | S : Entity_Id; |
996ae0b0 RK |
5947 | |
5948 | begin | |
9b0986f8 | 5949 | S := Current_Scope; |
996ae0b0 RK |
5950 | while Present (S) |
5951 | and then S /= Standard_Standard | |
5952 | loop | |
5953 | if (Ekind (S) = E_Function | |
5954 | or else Ekind (S) = E_Procedure) | |
5955 | and then Is_Generic_Instance (S) | |
5956 | then | |
5957 | return True; | |
5958 | ||
5959 | elsif Ekind (S) = E_Package | |
5960 | and then (In_Package_Body (S) or else In_Private_Part (S)) | |
5961 | and then Is_Generic_Instance (S) | |
5962 | then | |
5963 | return True; | |
5964 | end if; | |
5965 | ||
5966 | S := Scope (S); | |
5967 | end loop; | |
5968 | ||
5969 | return False; | |
5970 | end In_Instance_Not_Visible; | |
5971 | ||
5972 | ------------------------------ | |
5973 | -- In_Instance_Visible_Part -- | |
5974 | ------------------------------ | |
5975 | ||
5976 | function In_Instance_Visible_Part return Boolean is | |
9b0986f8 | 5977 | S : Entity_Id; |
996ae0b0 RK |
5978 | |
5979 | begin | |
9b0986f8 | 5980 | S := Current_Scope; |
996ae0b0 RK |
5981 | while Present (S) |
5982 | and then S /= Standard_Standard | |
5983 | loop | |
5984 | if Ekind (S) = E_Package | |
5985 | and then Is_Generic_Instance (S) | |
5986 | and then not In_Package_Body (S) | |
5987 | and then not In_Private_Part (S) | |
5988 | then | |
5989 | return True; | |
5990 | end if; | |
5991 | ||
5992 | S := Scope (S); | |
5993 | end loop; | |
5994 | ||
5995 | return False; | |
5996 | end In_Instance_Visible_Part; | |
5997 | ||
f3d57416 RW |
5998 | --------------------- |
5999 | -- In_Package_Body -- | |
6000 | --------------------- | |
fbf5a39b AC |
6001 | |
6002 | function In_Package_Body return Boolean is | |
9b0986f8 | 6003 | S : Entity_Id; |
fbf5a39b AC |
6004 | |
6005 | begin | |
9b0986f8 | 6006 | S := Current_Scope; |
fbf5a39b AC |
6007 | while Present (S) |
6008 | and then S /= Standard_Standard | |
6009 | loop | |
6010 | if Ekind (S) = E_Package | |
6011 | and then In_Package_Body (S) | |
6012 | then | |
6013 | return True; | |
6014 | else | |
6015 | S := Scope (S); | |
6016 | end if; | |
6017 | end loop; | |
6018 | ||
6019 | return False; | |
6020 | end In_Package_Body; | |
6021 | ||
eaa2f8c7 ST |
6022 | -------------------------------- |
6023 | -- In_Parameter_Specification -- | |
6024 | -------------------------------- | |
6025 | ||
6026 | function In_Parameter_Specification (N : Node_Id) return Boolean is | |
6027 | PN : Node_Id; | |
6028 | ||
6029 | begin | |
6030 | PN := Parent (N); | |
6031 | while Present (PN) loop | |
6032 | if Nkind (PN) = N_Parameter_Specification then | |
6033 | return True; | |
6034 | end if; | |
6035 | ||
6036 | PN := Parent (PN); | |
6037 | end loop; | |
6038 | ||
6039 | return False; | |
6040 | end In_Parameter_Specification; | |
6041 | ||
996ae0b0 RK |
6042 | -------------------------------------- |
6043 | -- In_Subprogram_Or_Concurrent_Unit -- | |
6044 | -------------------------------------- | |
6045 | ||
6046 | function In_Subprogram_Or_Concurrent_Unit return Boolean is | |
6047 | E : Entity_Id; | |
6048 | K : Entity_Kind; | |
6049 | ||
6050 | begin | |
6051 | -- Use scope chain to check successively outer scopes | |
6052 | ||
6053 | E := Current_Scope; | |
6054 | loop | |
6055 | K := Ekind (E); | |
6056 | ||
6057 | if K in Subprogram_Kind | |
6058 | or else K in Concurrent_Kind | |
fbf5a39b | 6059 | or else K in Generic_Subprogram_Kind |
996ae0b0 RK |
6060 | then |
6061 | return True; | |
6062 | ||
6063 | elsif E = Standard_Standard then | |
6064 | return False; | |
6065 | end if; | |
6066 | ||
6067 | E := Scope (E); | |
6068 | end loop; | |
996ae0b0 RK |
6069 | end In_Subprogram_Or_Concurrent_Unit; |
6070 | ||
6071 | --------------------- | |
6072 | -- In_Visible_Part -- | |
6073 | --------------------- | |
6074 | ||
6075 | function In_Visible_Part (Scope_Id : Entity_Id) return Boolean is | |
6076 | begin | |
6077 | return | |
21024a39 | 6078 | Is_Package_Or_Generic_Package (Scope_Id) |
996ae0b0 RK |
6079 | and then In_Open_Scopes (Scope_Id) |
6080 | and then not In_Package_Body (Scope_Id) | |
6081 | and then not In_Private_Part (Scope_Id); | |
6082 | end In_Visible_Part; | |
6083 | ||
df3e68b1 HK |
6084 | -------------------------------- |
6085 | -- Incomplete_Or_Private_View -- | |
6086 | -------------------------------- | |
6087 | ||
6088 | function Incomplete_Or_Private_View (Typ : Entity_Id) return Entity_Id is | |
6089 | function Inspect_Decls | |
6090 | (Decls : List_Id; | |
6091 | Taft : Boolean := False) return Entity_Id; | |
6092 | -- Check whether a declarative region contains the incomplete or private | |
6093 | -- view of Typ. | |
6094 | ||
6095 | ------------------- | |
6096 | -- Inspect_Decls -- | |
6097 | ------------------- | |
6098 | ||
6099 | function Inspect_Decls | |
6100 | (Decls : List_Id; | |
6101 | Taft : Boolean := False) return Entity_Id | |
6102 | is | |
6103 | Decl : Node_Id; | |
6104 | Match : Node_Id; | |
6105 | ||
6106 | begin | |
6107 | Decl := First (Decls); | |
6108 | while Present (Decl) loop | |
6109 | Match := Empty; | |
6110 | ||
6111 | if Taft then | |
6112 | if Nkind (Decl) = N_Incomplete_Type_Declaration then | |
6113 | Match := Defining_Identifier (Decl); | |
6114 | end if; | |
2c1b72d7 | 6115 | |
df3e68b1 HK |
6116 | else |
6117 | if Nkind_In (Decl, N_Private_Extension_Declaration, | |
6118 | N_Private_Type_Declaration) | |
6119 | then | |
6120 | Match := Defining_Identifier (Decl); | |
6121 | end if; | |
6122 | end if; | |
6123 | ||
6124 | if Present (Match) | |
6125 | and then Present (Full_View (Match)) | |
6126 | and then Full_View (Match) = Typ | |
6127 | then | |
6128 | return Match; | |
6129 | end if; | |
6130 | ||
6131 | Next (Decl); | |
6132 | end loop; | |
6133 | ||
6134 | return Empty; | |
6135 | end Inspect_Decls; | |
6136 | ||
2c1b72d7 AC |
6137 | -- Local variables |
6138 | ||
df3e68b1 HK |
6139 | Prev : Entity_Id; |
6140 | ||
6141 | -- Start of processing for Incomplete_Or_Partial_View | |
6142 | ||
6143 | begin | |
6144 | -- Incomplete type case | |
6145 | ||
6146 | Prev := Current_Entity_In_Scope (Typ); | |
6147 | ||
6148 | if Present (Prev) | |
6149 | and then Is_Incomplete_Type (Prev) | |
6150 | and then Present (Full_View (Prev)) | |
6151 | and then Full_View (Prev) = Typ | |
6152 | then | |
6153 | return Prev; | |
6154 | end if; | |
6155 | ||
6156 | -- Private or Taft amendment type case | |
6157 | ||
6158 | declare | |
6159 | Pkg : constant Entity_Id := Scope (Typ); | |
6160 | Pkg_Decl : Node_Id := Pkg; | |
6161 | ||
6162 | begin | |
6163 | if Ekind (Pkg) = E_Package then | |
6164 | while Nkind (Pkg_Decl) /= N_Package_Specification loop | |
6165 | Pkg_Decl := Parent (Pkg_Decl); | |
6166 | end loop; | |
6167 | ||
6168 | -- It is knows that Typ has a private view, look for it in the | |
6169 | -- visible declarations of the enclosing scope. A special case | |
6170 | -- of this is when the two views have been exchanged - the full | |
6171 | -- appears earlier than the private. | |
6172 | ||
6173 | if Has_Private_Declaration (Typ) then | |
6174 | Prev := Inspect_Decls (Visible_Declarations (Pkg_Decl)); | |
6175 | ||
6176 | -- Exchanged view case, look in the private declarations | |
6177 | ||
6178 | if No (Prev) then | |
6179 | Prev := Inspect_Decls (Private_Declarations (Pkg_Decl)); | |
6180 | end if; | |
6181 | ||
6182 | return Prev; | |
6183 | ||
6184 | -- Otherwise if this is the package body, then Typ is a potential | |
6185 | -- Taft amendment type. The incomplete view should be located in | |
6186 | -- the private declarations of the enclosing scope. | |
6187 | ||
6188 | elsif In_Package_Body (Pkg) then | |
6189 | return Inspect_Decls (Private_Declarations (Pkg_Decl), True); | |
6190 | end if; | |
6191 | end if; | |
6192 | end; | |
6193 | ||
6194 | -- The type has no incomplete or private view | |
6195 | ||
6196 | return Empty; | |
6197 | end Incomplete_Or_Private_View; | |
6198 | ||
fbf5a39b AC |
6199 | --------------------------------- |
6200 | -- Insert_Explicit_Dereference -- | |
6201 | --------------------------------- | |
6202 | ||
6203 | procedure Insert_Explicit_Dereference (N : Node_Id) is | |
6204 | New_Prefix : constant Node_Id := Relocate_Node (N); | |
2717634d | 6205 | Ent : Entity_Id := Empty; |
482a63fb | 6206 | Pref : Node_Id; |
fbf5a39b AC |
6207 | I : Interp_Index; |
6208 | It : Interp; | |
6209 | T : Entity_Id; | |
6210 | ||
6211 | begin | |
6212 | Save_Interps (N, New_Prefix); | |
327503f1 | 6213 | |
437f8c1e | 6214 | Rewrite (N, |
90c63b09 AC |
6215 | Make_Explicit_Dereference (Sloc (Parent (N)), |
6216 | Prefix => New_Prefix)); | |
fbf5a39b AC |
6217 | |
6218 | Set_Etype (N, Designated_Type (Etype (New_Prefix))); | |
6219 | ||
6220 | if Is_Overloaded (New_Prefix) then | |
6221 | ||
09494c32 AC |
6222 | -- The dereference is also overloaded, and its interpretations are |
6223 | -- the designated types of the interpretations of the original node. | |
fbf5a39b AC |
6224 | |
6225 | Set_Etype (N, Any_Type); | |
fbf5a39b | 6226 | |
9b0986f8 | 6227 | Get_First_Interp (New_Prefix, I, It); |
fbf5a39b AC |
6228 | while Present (It.Nam) loop |
6229 | T := It.Typ; | |
6230 | ||
6231 | if Is_Access_Type (T) then | |
6232 | Add_One_Interp (N, Designated_Type (T), Designated_Type (T)); | |
6233 | end if; | |
6234 | ||
6235 | Get_Next_Interp (I, It); | |
6236 | end loop; | |
6237 | ||
6238 | End_Interp_List; | |
2717634d AC |
6239 | |
6240 | else | |
6241 | -- Prefix is unambiguous: mark the original prefix (which might | |
6242 | -- Come_From_Source) as a reference, since the new (relocated) one | |
6243 | -- won't be taken into account. | |
6244 | ||
6245 | if Is_Entity_Name (New_Prefix) then | |
6246 | Ent := Entity (New_Prefix); | |
468ee96a | 6247 | Pref := New_Prefix; |
482a63fb ES |
6248 | |
6249 | -- For a retrieval of a subcomponent of some composite object, | |
6250 | -- retrieve the ultimate entity if there is one. | |
6251 | ||
6252 | elsif Nkind (New_Prefix) = N_Selected_Component | |
6253 | or else Nkind (New_Prefix) = N_Indexed_Component | |
6254 | then | |
6255 | Pref := Prefix (New_Prefix); | |
482a63fb ES |
6256 | while Present (Pref) |
6257 | and then | |
6258 | (Nkind (Pref) = N_Selected_Component | |
6259 | or else Nkind (Pref) = N_Indexed_Component) | |
6260 | loop | |
6261 | Pref := Prefix (Pref); | |
6262 | end loop; | |
6263 | ||
6264 | if Present (Pref) and then Is_Entity_Name (Pref) then | |
6265 | Ent := Entity (Pref); | |
6266 | end if; | |
2717634d AC |
6267 | end if; |
6268 | ||
90c63b09 | 6269 | -- Place the reference on the entity node |
468ee96a | 6270 | |
2717634d | 6271 | if Present (Ent) then |
468ee96a | 6272 | Generate_Reference (Ent, Pref); |
2717634d | 6273 | end if; |
fbf5a39b AC |
6274 | end if; |
6275 | end Insert_Explicit_Dereference; | |
6276 | ||
de5cd98e TQ |
6277 | ------------------------------------------ |
6278 | -- Inspect_Deferred_Constant_Completion -- | |
6279 | ------------------------------------------ | |
6280 | ||
6281 | procedure Inspect_Deferred_Constant_Completion (Decls : List_Id) is | |
6282 | Decl : Node_Id; | |
6283 | ||
6284 | begin | |
6285 | Decl := First (Decls); | |
6286 | while Present (Decl) loop | |
6287 | ||
6288 | -- Deferred constant signature | |
6289 | ||
6290 | if Nkind (Decl) = N_Object_Declaration | |
6291 | and then Constant_Present (Decl) | |
6292 | and then No (Expression (Decl)) | |
6293 | ||
6294 | -- No need to check internally generated constants | |
6295 | ||
6296 | and then Comes_From_Source (Decl) | |
6297 | ||
90c63b09 AC |
6298 | -- The constant is not completed. A full object declaration or a |
6299 | -- pragma Import complete a deferred constant. | |
de5cd98e TQ |
6300 | |
6301 | and then not Has_Completion (Defining_Identifier (Decl)) | |
6302 | then | |
6303 | Error_Msg_N | |
6304 | ("constant declaration requires initialization expression", | |
6305 | Defining_Identifier (Decl)); | |
6306 | end if; | |
6307 | ||
6308 | Decl := Next (Decl); | |
6309 | end loop; | |
6310 | end Inspect_Deferred_Constant_Completion; | |
6311 | ||
75ba322d AC |
6312 | ----------------------------- |
6313 | -- Is_Actual_Out_Parameter -- | |
6314 | ----------------------------- | |
6315 | ||
6316 | function Is_Actual_Out_Parameter (N : Node_Id) return Boolean is | |
6317 | Formal : Entity_Id; | |
6318 | Call : Node_Id; | |
6319 | begin | |
6320 | Find_Actual (N, Formal, Call); | |
90c63b09 | 6321 | return Present (Formal) and then Ekind (Formal) = E_Out_Parameter; |
75ba322d AC |
6322 | end Is_Actual_Out_Parameter; |
6323 | ||
996ae0b0 RK |
6324 | ------------------------- |
6325 | -- Is_Actual_Parameter -- | |
6326 | ------------------------- | |
6327 | ||
6328 | function Is_Actual_Parameter (N : Node_Id) return Boolean is | |
6329 | PK : constant Node_Kind := Nkind (Parent (N)); | |
6330 | ||
6331 | begin | |
6332 | case PK is | |
6333 | when N_Parameter_Association => | |
6334 | return N = Explicit_Actual_Parameter (Parent (N)); | |
6335 | ||
6336 | when N_Function_Call | N_Procedure_Call_Statement => | |
6337 | return Is_List_Member (N) | |
6338 | and then | |
6339 | List_Containing (N) = Parameter_Associations (Parent (N)); | |
6340 | ||
6341 | when others => | |
6342 | return False; | |
6343 | end case; | |
6344 | end Is_Actual_Parameter; | |
6345 | ||
e24329cd YM |
6346 | -------------------------------- |
6347 | -- Is_Actual_Tagged_Parameter -- | |
6348 | -------------------------------- | |
6349 | ||
6350 | function Is_Actual_Tagged_Parameter (N : Node_Id) return Boolean is | |
6351 | Formal : Entity_Id; | |
6352 | Call : Node_Id; | |
6353 | begin | |
6354 | Find_Actual (N, Formal, Call); | |
6355 | return Present (Formal) and then Is_Tagged_Type (Etype (Formal)); | |
6356 | end Is_Actual_Tagged_Parameter; | |
6357 | ||
996ae0b0 RK |
6358 | --------------------- |
6359 | -- Is_Aliased_View -- | |
6360 | --------------------- | |
6361 | ||
6362 | function Is_Aliased_View (Obj : Node_Id) return Boolean is | |
6363 | E : Entity_Id; | |
6364 | ||
6365 | begin | |
6366 | if Is_Entity_Name (Obj) then | |
6367 | ||
996ae0b0 RK |
6368 | E := Entity (Obj); |
6369 | ||
130c236a TQ |
6370 | return |
6371 | (Is_Object (E) | |
6372 | and then | |
6373 | (Is_Aliased (E) | |
6374 | or else (Present (Renamed_Object (E)) | |
6375 | and then Is_Aliased_View (Renamed_Object (E))))) | |
996ae0b0 RK |
6376 | |
6377 | or else ((Is_Formal (E) | |
6378 | or else Ekind (E) = E_Generic_In_Out_Parameter | |
6379 | or else Ekind (E) = E_Generic_In_Parameter) | |
6380 | and then Is_Tagged_Type (Etype (E))) | |
6381 | ||
9e87a68d ES |
6382 | or else (Is_Concurrent_Type (E) |
6383 | and then In_Open_Scopes (E)) | |
996ae0b0 | 6384 | |
9b0986f8 RD |
6385 | -- Current instance of type, either directly or as rewritten |
6386 | -- reference to the current object. | |
6387 | ||
6388 | or else (Is_Entity_Name (Original_Node (Obj)) | |
6389 | and then Present (Entity (Original_Node (Obj))) | |
6390 | and then Is_Type (Entity (Original_Node (Obj)))) | |
996ae0b0 RK |
6391 | |
6392 | or else (Is_Type (E) and then E = Current_Scope) | |
9e87a68d | 6393 | |
996ae0b0 RK |
6394 | or else (Is_Incomplete_Or_Private_Type (E) |
6395 | and then Full_View (E) = Current_Scope); | |
6396 | ||
6397 | elsif Nkind (Obj) = N_Selected_Component then | |
6398 | return Is_Aliased (Entity (Selector_Name (Obj))); | |
6399 | ||
6400 | elsif Nkind (Obj) = N_Indexed_Component then | |
6401 | return Has_Aliased_Components (Etype (Prefix (Obj))) | |
6402 | or else | |
6403 | (Is_Access_Type (Etype (Prefix (Obj))) | |
6404 | and then | |
6405 | Has_Aliased_Components | |
6406 | (Designated_Type (Etype (Prefix (Obj))))); | |
6407 | ||
6408 | elsif Nkind (Obj) = N_Unchecked_Type_Conversion | |
6409 | or else Nkind (Obj) = N_Type_Conversion | |
6410 | then | |
6411 | return Is_Tagged_Type (Etype (Obj)) | |
fbf5a39b | 6412 | and then Is_Aliased_View (Expression (Obj)); |
996ae0b0 RK |
6413 | |
6414 | elsif Nkind (Obj) = N_Explicit_Dereference then | |
6415 | return Nkind (Original_Node (Obj)) /= N_Function_Call; | |
6416 | ||
6417 | else | |
6418 | return False; | |
6419 | end if; | |
6420 | end Is_Aliased_View; | |
6421 | ||
9bc856dd AC |
6422 | ------------------------- |
6423 | -- Is_Ancestor_Package -- | |
6424 | ------------------------- | |
6425 | ||
6426 | function Is_Ancestor_Package | |
31b5873d GD |
6427 | (E1 : Entity_Id; |
6428 | E2 : Entity_Id) return Boolean | |
9bc856dd AC |
6429 | is |
6430 | Par : Entity_Id; | |
6431 | ||
6432 | begin | |
6433 | Par := E2; | |
6434 | while Present (Par) | |
6435 | and then Par /= Standard_Standard | |
6436 | loop | |
6437 | if Par = E1 then | |
6438 | return True; | |
6439 | end if; | |
6440 | ||
6441 | Par := Scope (Par); | |
6442 | end loop; | |
6443 | ||
6444 | return False; | |
6445 | end Is_Ancestor_Package; | |
6446 | ||
996ae0b0 RK |
6447 | ---------------------- |
6448 | -- Is_Atomic_Object -- | |
6449 | ---------------------- | |
6450 | ||
6451 | function Is_Atomic_Object (N : Node_Id) return Boolean is | |
6452 | ||
6453 | function Object_Has_Atomic_Components (N : Node_Id) return Boolean; | |
6454 | -- Determines if given object has atomic components | |
6455 | ||
6456 | function Is_Atomic_Prefix (N : Node_Id) return Boolean; | |
130c236a | 6457 | -- If prefix is an implicit dereference, examine designated type |
996ae0b0 | 6458 | |
31b5873d GD |
6459 | ---------------------- |
6460 | -- Is_Atomic_Prefix -- | |
6461 | ---------------------- | |
6462 | ||
996ae0b0 RK |
6463 | function Is_Atomic_Prefix (N : Node_Id) return Boolean is |
6464 | begin | |
6465 | if Is_Access_Type (Etype (N)) then | |
6466 | return | |
6467 | Has_Atomic_Components (Designated_Type (Etype (N))); | |
6468 | else | |
6469 | return Object_Has_Atomic_Components (N); | |
6470 | end if; | |
6471 | end Is_Atomic_Prefix; | |
6472 | ||
31b5873d GD |
6473 | ---------------------------------- |
6474 | -- Object_Has_Atomic_Components -- | |
6475 | ---------------------------------- | |
6476 | ||
996ae0b0 RK |
6477 | function Object_Has_Atomic_Components (N : Node_Id) return Boolean is |
6478 | begin | |
6479 | if Has_Atomic_Components (Etype (N)) | |
6480 | or else Is_Atomic (Etype (N)) | |
6481 | then | |
6482 | return True; | |
6483 | ||
6484 | elsif Is_Entity_Name (N) | |
6485 | and then (Has_Atomic_Components (Entity (N)) | |
6486 | or else Is_Atomic (Entity (N))) | |
6487 | then | |
6488 | return True; | |
6489 | ||
6490 | elsif Nkind (N) = N_Indexed_Component | |
6491 | or else Nkind (N) = N_Selected_Component | |
6492 | then | |
6493 | return Is_Atomic_Prefix (Prefix (N)); | |
6494 | ||
6495 | else | |
6496 | return False; | |
6497 | end if; | |
6498 | end Object_Has_Atomic_Components; | |
6499 | ||
6500 | -- Start of processing for Is_Atomic_Object | |
6501 | ||
6502 | begin | |
9cbfc269 AC |
6503 | -- Predicate is not relevant to subprograms |
6504 | ||
90c63b09 | 6505 | if Is_Entity_Name (N) and then Is_Overloadable (Entity (N)) then |
9cbfc269 AC |
6506 | return False; |
6507 | ||
6508 | elsif Is_Atomic (Etype (N)) | |
996ae0b0 RK |
6509 | or else (Is_Entity_Name (N) and then Is_Atomic (Entity (N))) |
6510 | then | |
6511 | return True; | |
6512 | ||
6513 | elsif Nkind (N) = N_Indexed_Component | |
6514 | or else Nkind (N) = N_Selected_Component | |
6515 | then | |
6516 | return Is_Atomic_Prefix (Prefix (N)); | |
6517 | ||
6518 | else | |
6519 | return False; | |
6520 | end if; | |
6521 | end Is_Atomic_Object; | |
6522 | ||
7f0e4cdb BD |
6523 | ----------------------------- |
6524 | -- Is_Concurrent_Interface -- | |
6525 | ----------------------------- | |
6526 | ||
6527 | function Is_Concurrent_Interface (T : Entity_Id) return Boolean is | |
6528 | begin | |
6529 | return | |
6530 | Is_Interface (T) | |
6531 | and then | |
6532 | (Is_Protected_Interface (T) | |
6533 | or else Is_Synchronized_Interface (T) | |
6534 | or else Is_Task_Interface (T)); | |
6535 | end Is_Concurrent_Interface; | |
6536 | ||
2c867f5a ES |
6537 | -------------------------------------- |
6538 | -- Is_Controlling_Limited_Procedure -- | |
6539 | -------------------------------------- | |
6540 | ||
6541 | function Is_Controlling_Limited_Procedure | |
6542 | (Proc_Nam : Entity_Id) return Boolean | |
6543 | is | |
21024a39 | 6544 | Param_Typ : Entity_Id := Empty; |
2c867f5a ES |
6545 | |
6546 | begin | |
21024a39 RD |
6547 | if Ekind (Proc_Nam) = E_Procedure |
6548 | and then Present (Parameter_Specifications (Parent (Proc_Nam))) | |
6549 | then | |
6550 | Param_Typ := Etype (Parameter_Type (First ( | |
6551 | Parameter_Specifications (Parent (Proc_Nam))))); | |
2c867f5a ES |
6552 | |
6553 | -- In this case where an Itype was created, the procedure call has been | |
6554 | -- rewritten. | |
6555 | ||
6556 | elsif Present (Associated_Node_For_Itype (Proc_Nam)) | |
6557 | and then Present (Original_Node (Associated_Node_For_Itype (Proc_Nam))) | |
21024a39 RD |
6558 | and then |
6559 | Present (Parameter_Associations | |
6560 | (Associated_Node_For_Itype (Proc_Nam))) | |
2c867f5a | 6561 | then |
21024a39 RD |
6562 | Param_Typ := |
6563 | Etype (First (Parameter_Associations | |
6564 | (Associated_Node_For_Itype (Proc_Nam)))); | |
6565 | end if; | |
6566 | ||
6567 | if Present (Param_Typ) then | |
2c867f5a ES |
6568 | return |
6569 | Is_Interface (Param_Typ) | |
6570 | and then Is_Limited_Record (Param_Typ); | |
6571 | end if; | |
6572 | ||
6573 | return False; | |
6574 | end Is_Controlling_Limited_Procedure; | |
6575 | ||
236fecbf JM |
6576 | ----------------------------- |
6577 | -- Is_CPP_Constructor_Call -- | |
6578 | ----------------------------- | |
6579 | ||
6580 | function Is_CPP_Constructor_Call (N : Node_Id) return Boolean is | |
6581 | begin | |
6582 | return Nkind (N) = N_Function_Call | |
236fecbf JM |
6583 | and then Is_CPP_Class (Etype (Etype (N))) |
6584 | and then Is_Constructor (Entity (Name (N))) | |
6585 | and then Is_Imported (Entity (Name (N))); | |
6586 | end Is_CPP_Constructor_Call; | |
6587 | ||
7ec8363d RD |
6588 | ----------------- |
6589 | -- Is_Delegate -- | |
6590 | ----------------- | |
6591 | ||
6592 | function Is_Delegate (T : Entity_Id) return Boolean is | |
6593 | Desig_Type : Entity_Id; | |
6594 | ||
6595 | begin | |
6596 | if VM_Target /= CLI_Target then | |
6597 | return False; | |
6598 | end if; | |
6599 | ||
6600 | -- Access-to-subprograms are delegates in CIL | |
6601 | ||
6602 | if Ekind (T) = E_Access_Subprogram_Type then | |
6603 | return True; | |
6604 | end if; | |
6605 | ||
6606 | if Ekind (T) not in Access_Kind then | |
6607 | ||
6608 | -- A delegate is a managed pointer. If no designated type is defined | |
6609 | -- it means that it's not a delegate. | |
6610 | ||
6611 | return False; | |
6612 | end if; | |
6613 | ||
6614 | Desig_Type := Etype (Directly_Designated_Type (T)); | |
6615 | ||
6616 | if not Is_Tagged_Type (Desig_Type) then | |
6617 | return False; | |
6618 | end if; | |
6619 | ||
6620 | -- Test if the type is inherited from [mscorlib]System.Delegate | |
6621 | ||
6622 | while Etype (Desig_Type) /= Desig_Type loop | |
6623 | if Chars (Scope (Desig_Type)) /= No_Name | |
6624 | and then Is_Imported (Scope (Desig_Type)) | |
6625 | and then Get_Name_String (Chars (Scope (Desig_Type))) = "delegate" | |
6626 | then | |
6627 | return True; | |
6628 | end if; | |
6629 | ||
6630 | Desig_Type := Etype (Desig_Type); | |
6631 | end loop; | |
6632 | ||
6633 | return False; | |
6634 | end Is_Delegate; | |
6635 | ||
996ae0b0 RK |
6636 | ---------------------------------------------- |
6637 | -- Is_Dependent_Component_Of_Mutable_Object -- | |
6638 | ---------------------------------------------- | |
6639 | ||
6640 | function Is_Dependent_Component_Of_Mutable_Object | |
90c63b09 | 6641 | (Object : Node_Id) return Boolean |
996ae0b0 RK |
6642 | is |
6643 | P : Node_Id; | |
6644 | Prefix_Type : Entity_Id; | |
6645 | P_Aliased : Boolean := False; | |
6646 | Comp : Entity_Id; | |
6647 | ||
996ae0b0 | 6648 | function Is_Declared_Within_Variant (Comp : Entity_Id) return Boolean; |
130c236a | 6649 | -- Returns True if and only if Comp is declared within a variant part |
996ae0b0 | 6650 | |
996ae0b0 RK |
6651 | -------------------------------- |
6652 | -- Is_Declared_Within_Variant -- | |
6653 | -------------------------------- | |
6654 | ||
6655 | function Is_Declared_Within_Variant (Comp : Entity_Id) return Boolean is | |
6656 | Comp_Decl : constant Node_Id := Parent (Comp); | |
6657 | Comp_List : constant Node_Id := Parent (Comp_Decl); | |
996ae0b0 RK |
6658 | begin |
6659 | return Nkind (Parent (Comp_List)) = N_Variant; | |
6660 | end Is_Declared_Within_Variant; | |
6661 | ||
6662 | -- Start of processing for Is_Dependent_Component_Of_Mutable_Object | |
6663 | ||
6664 | begin | |
6665 | if Is_Variable (Object) then | |
6666 | ||
6667 | if Nkind (Object) = N_Selected_Component then | |
6668 | P := Prefix (Object); | |
6669 | Prefix_Type := Etype (P); | |
6670 | ||
6671 | if Is_Entity_Name (P) then | |
6672 | ||
6673 | if Ekind (Entity (P)) = E_Generic_In_Out_Parameter then | |
6674 | Prefix_Type := Base_Type (Prefix_Type); | |
6675 | end if; | |
6676 | ||
6677 | if Is_Aliased (Entity (P)) then | |
6678 | P_Aliased := True; | |
6679 | end if; | |
6680 | ||
90c63b09 AC |
6681 | -- A discriminant check on a selected component may be expanded |
6682 | -- into a dereference when removing side-effects. Recover the | |
6683 | -- original node and its type, which may be unconstrained. | |
5950a3ac AC |
6684 | |
6685 | elsif Nkind (P) = N_Explicit_Dereference | |
6686 | and then not (Comes_From_Source (P)) | |
6687 | then | |
6688 | P := Original_Node (P); | |
6689 | Prefix_Type := Etype (P); | |
6690 | ||
996ae0b0 | 6691 | else |
90c63b09 AC |
6692 | -- Check for prefix being an aliased component??? |
6693 | ||
996ae0b0 | 6694 | null; |
5950a3ac | 6695 | |
996ae0b0 RK |
6696 | end if; |
6697 | ||
edd63e9b ES |
6698 | -- A heap object is constrained by its initial value |
6699 | ||
9b0986f8 RD |
6700 | -- Ada 2005 (AI-363): Always assume the object could be mutable in |
6701 | -- the dereferenced case, since the access value might denote an | |
6702 | -- unconstrained aliased object, whereas in Ada 95 the designated | |
6703 | -- object is guaranteed to be constrained. A worst-case assumption | |
6704 | -- has to apply in Ada 2005 because we can't tell at compile time | |
6705 | -- whether the object is "constrained by its initial value" | |
6706 | -- (despite the fact that 3.10.2(26/2) and 8.5.1(5/2) are | |
6707 | -- semantic rules -- these rules are acknowledged to need fixing). | |
6708 | ||
0791fbe9 | 6709 | if Ada_Version < Ada_2005 then |
9b0986f8 RD |
6710 | if Is_Access_Type (Prefix_Type) |
6711 | or else Nkind (P) = N_Explicit_Dereference | |
6712 | then | |
6713 | return False; | |
6714 | end if; | |
edd63e9b | 6715 | |
0791fbe9 | 6716 | elsif Ada_Version >= Ada_2005 then |
9b0986f8 | 6717 | if Is_Access_Type (Prefix_Type) then |
7f0e4cdb BD |
6718 | |
6719 | -- If the access type is pool-specific, and there is no | |
6720 | -- constrained partial view of the designated type, then the | |
6721 | -- designated object is known to be constrained. | |
6722 | ||
6723 | if Ekind (Prefix_Type) = E_Access_Type | |
6724 | and then not Has_Constrained_Partial_View | |
6725 | (Designated_Type (Prefix_Type)) | |
6726 | then | |
6727 | return False; | |
6728 | ||
6729 | -- Otherwise (general access type, or there is a constrained | |
6730 | -- partial view of the designated type), we need to check | |
6731 | -- based on the designated type. | |
6732 | ||
6733 | else | |
6734 | Prefix_Type := Designated_Type (Prefix_Type); | |
6735 | end if; | |
9b0986f8 | 6736 | end if; |
996ae0b0 RK |
6737 | end if; |
6738 | ||
6739 | Comp := | |
6740 | Original_Record_Component (Entity (Selector_Name (Object))); | |
6741 | ||
90c63b09 AC |
6742 | -- As per AI-0017, the renaming is illegal in a generic body, even |
6743 | -- if the subtype is indefinite. | |
07fc65c4 | 6744 | |
9b0986f8 RD |
6745 | -- Ada 2005 (AI-363): In Ada 2005 an aliased object can be mutable |
6746 | ||
996ae0b0 | 6747 | if not Is_Constrained (Prefix_Type) |
07fc65c4 GB |
6748 | and then (not Is_Indefinite_Subtype (Prefix_Type) |
6749 | or else | |
6750 | (Is_Generic_Type (Prefix_Type) | |
6751 | and then Ekind (Current_Scope) = E_Generic_Package | |
6752 | and then In_Package_Body (Current_Scope))) | |
6753 | ||
996ae0b0 | 6754 | and then (Is_Declared_Within_Variant (Comp) |
edd63e9b | 6755 | or else Has_Discriminant_Dependent_Constraint (Comp)) |
0791fbe9 | 6756 | and then (not P_Aliased or else Ada_Version >= Ada_2005) |
996ae0b0 RK |
6757 | then |
6758 | return True; | |
6759 | ||
6760 | else | |
6761 | return | |
6762 | Is_Dependent_Component_Of_Mutable_Object (Prefix (Object)); | |
6763 | ||
6764 | end if; | |
6765 | ||
6766 | elsif Nkind (Object) = N_Indexed_Component | |
6767 | or else Nkind (Object) = N_Slice | |
6768 | then | |
6769 | return Is_Dependent_Component_Of_Mutable_Object (Prefix (Object)); | |
6d11af89 | 6770 | |
2820d220 AC |
6771 | -- A type conversion that Is_Variable is a view conversion: |
6772 | -- go back to the denoted object. | |
6d11af89 | 6773 | |
2820d220 AC |
6774 | elsif Nkind (Object) = N_Type_Conversion then |
6775 | return | |
6776 | Is_Dependent_Component_Of_Mutable_Object (Expression (Object)); | |
996ae0b0 RK |
6777 | end if; |
6778 | end if; | |
6779 | ||
6780 | return False; | |
6781 | end Is_Dependent_Component_Of_Mutable_Object; | |
6782 | ||
fbf5a39b AC |
6783 | --------------------- |
6784 | -- Is_Dereferenced -- | |
6785 | --------------------- | |
6786 | ||
6787 | function Is_Dereferenced (N : Node_Id) return Boolean is | |
6788 | P : constant Node_Id := Parent (N); | |
fbf5a39b AC |
6789 | begin |
6790 | return | |
6791 | (Nkind (P) = N_Selected_Component | |
6792 | or else | |
6793 | Nkind (P) = N_Explicit_Dereference | |
6794 | or else | |
6795 | Nkind (P) = N_Indexed_Component | |
6796 | or else | |
6797 | Nkind (P) = N_Slice) | |
6798 | and then Prefix (P) = N; | |
6799 | end Is_Dereferenced; | |
6800 | ||
9f4fd324 AC |
6801 | ---------------------- |
6802 | -- Is_Descendent_Of -- | |
6803 | ---------------------- | |
6804 | ||
6805 | function Is_Descendent_Of (T1 : Entity_Id; T2 : Entity_Id) return Boolean is | |
6806 | T : Entity_Id; | |
6807 | Etyp : Entity_Id; | |
6808 | ||
6809 | begin | |
6810 | pragma Assert (Nkind (T1) in N_Entity); | |
6811 | pragma Assert (Nkind (T2) in N_Entity); | |
6812 | ||
6813 | T := Base_Type (T1); | |
6814 | ||
6815 | -- Immediate return if the types match | |
6816 | ||
6817 | if T = T2 then | |
6818 | return True; | |
6819 | ||
6820 | -- Comment needed here ??? | |
6821 | ||
6822 | elsif Ekind (T) = E_Class_Wide_Type then | |
6823 | return Etype (T) = T2; | |
6824 | ||
6825 | -- All other cases | |
6826 | ||
6827 | else | |
6828 | loop | |
6829 | Etyp := Etype (T); | |
6830 | ||
6831 | -- Done if we found the type we are looking for | |
6832 | ||
6833 | if Etyp = T2 then | |
6834 | return True; | |
6835 | ||
6836 | -- Done if no more derivations to check | |
6837 | ||
8a36a0cc AC |
6838 | elsif T = T1 |
6839 | or else T = Etyp | |
6840 | then | |
9f4fd324 AC |
6841 | return False; |
6842 | ||
6843 | -- Following test catches error cases resulting from prev errors | |
6844 | ||
6845 | elsif No (Etyp) then | |
6846 | return False; | |
6847 | ||
6848 | elsif Is_Private_Type (T) and then Etyp = Full_View (T) then | |
6849 | return False; | |
6850 | ||
6851 | elsif Is_Private_Type (Etyp) and then Full_View (Etyp) = T then | |
6852 | return False; | |
6853 | end if; | |
6854 | ||
8a36a0cc | 6855 | T := Base_Type (Etyp); |
9f4fd324 AC |
6856 | end loop; |
6857 | end if; | |
9f4fd324 AC |
6858 | end Is_Descendent_Of; |
6859 | ||
d2b10647 ES |
6860 | ---------------------------- |
6861 | -- Is_Expression_Function -- | |
6862 | ---------------------------- | |
6863 | ||
6864 | function Is_Expression_Function (Subp : Entity_Id) return Boolean is | |
6865 | Decl : constant Node_Id := Unit_Declaration_Node (Subp); | |
6866 | ||
6867 | begin | |
6868 | return Ekind (Subp) = E_Function | |
6869 | and then Nkind (Decl) = N_Subprogram_Declaration | |
6870 | and then | |
6871 | (Nkind (Original_Node (Decl)) = N_Expression_Function | |
6872 | or else | |
6873 | (Present (Corresponding_Body (Decl)) | |
6874 | and then | |
6875 | Nkind (Original_Node | |
6876 | (Unit_Declaration_Node (Corresponding_Body (Decl)))) | |
6877 | = N_Expression_Function)); | |
6878 | end Is_Expression_Function; | |
6879 | ||
996ae0b0 RK |
6880 | -------------- |
6881 | -- Is_False -- | |
6882 | -------------- | |
6883 | ||
6884 | function Is_False (U : Uint) return Boolean is | |
6885 | begin | |
6886 | return (U = 0); | |
6887 | end Is_False; | |
6888 | ||
6889 | --------------------------- | |
6890 | -- Is_Fixed_Model_Number -- | |
6891 | --------------------------- | |
6892 | ||
6893 | function Is_Fixed_Model_Number (U : Ureal; T : Entity_Id) return Boolean is | |
6894 | S : constant Ureal := Small_Value (T); | |
6895 | M : Urealp.Save_Mark; | |
6896 | R : Boolean; | |
996ae0b0 RK |
6897 | begin |
6898 | M := Urealp.Mark; | |
6899 | R := (U = UR_Trunc (U / S) * S); | |
6900 | Urealp.Release (M); | |
6901 | return R; | |
6902 | end Is_Fixed_Model_Number; | |
6903 | ||
6904 | ------------------------------- | |
6905 | -- Is_Fully_Initialized_Type -- | |
6906 | ------------------------------- | |
6907 | ||
6908 | function Is_Fully_Initialized_Type (Typ : Entity_Id) return Boolean is | |
6909 | begin | |
6910 | if Is_Scalar_Type (Typ) then | |
6911 | return False; | |
6912 | ||
6913 | elsif Is_Access_Type (Typ) then | |
6914 | return True; | |
6915 | ||
6916 | elsif Is_Array_Type (Typ) then | |
6917 | if Is_Fully_Initialized_Type (Component_Type (Typ)) then | |
6918 | return True; | |
6919 | end if; | |
6920 | ||
6921 | -- An interesting case, if we have a constrained type one of whose | |
6922 | -- bounds is known to be null, then there are no elements to be | |
6923 | -- initialized, so all the elements are initialized! | |
6924 | ||
6925 | if Is_Constrained (Typ) then | |
6926 | declare | |
6927 | Indx : Node_Id; | |
6928 | Indx_Typ : Entity_Id; | |
6929 | Lbd, Hbd : Node_Id; | |
6930 | ||
6931 | begin | |
6932 | Indx := First_Index (Typ); | |
6933 | while Present (Indx) loop | |
996ae0b0 RK |
6934 | if Etype (Indx) = Any_Type then |
6935 | return False; | |
6936 | ||
130c236a | 6937 | -- If index is a range, use directly |
996ae0b0 RK |
6938 | |
6939 | elsif Nkind (Indx) = N_Range then | |
6940 | Lbd := Low_Bound (Indx); | |
6941 | Hbd := High_Bound (Indx); | |
6942 | ||
6943 | else | |
6944 | Indx_Typ := Etype (Indx); | |
6945 | ||
6946 | if Is_Private_Type (Indx_Typ) then | |
6947 | Indx_Typ := Full_View (Indx_Typ); | |
6948 | end if; | |
6949 | ||
1b6c95c4 | 6950 | if No (Indx_Typ) or else Etype (Indx_Typ) = Any_Type then |
996ae0b0 RK |
6951 | return False; |
6952 | else | |
6953 | Lbd := Type_Low_Bound (Indx_Typ); | |
6954 | Hbd := Type_High_Bound (Indx_Typ); | |
6955 | end if; | |
6956 | end if; | |
6957 | ||
6958 | if Compile_Time_Known_Value (Lbd) | |
6959 | and then Compile_Time_Known_Value (Hbd) | |
6960 | then | |
6961 | if Expr_Value (Hbd) < Expr_Value (Lbd) then | |
6962 | return True; | |
6963 | end if; | |
6964 | end if; | |
6965 | ||
6966 | Next_Index (Indx); | |
6967 | end loop; | |
6968 | end; | |
6969 | end if; | |
6970 | ||
07fc65c4 GB |
6971 | -- If no null indexes, then type is not fully initialized |
6972 | ||
996ae0b0 RK |
6973 | return False; |
6974 | ||
fbf5a39b AC |
6975 | -- Record types |
6976 | ||
996ae0b0 | 6977 | elsif Is_Record_Type (Typ) then |
fbf5a39b AC |
6978 | if Has_Discriminants (Typ) |
6979 | and then | |
6980 | Present (Discriminant_Default_Value (First_Discriminant (Typ))) | |
6981 | and then Is_Fully_Initialized_Variant (Typ) | |
6982 | then | |
6983 | return True; | |
6984 | end if; | |
6985 | ||
6986 | -- Controlled records are considered to be fully initialized if | |
6987 | -- there is a user defined Initialize routine. This may not be | |
6988 | -- entirely correct, but as the spec notes, we are guessing here | |
6989 | -- what is best from the point of view of issuing warnings. | |
6990 | ||
6991 | if Is_Controlled (Typ) then | |
6992 | declare | |
6993 | Utyp : constant Entity_Id := Underlying_Type (Typ); | |
6994 | ||
6995 | begin | |
6996 | if Present (Utyp) then | |
6997 | declare | |
6998 | Init : constant Entity_Id := | |
6999 | (Find_Prim_Op | |
7000 | (Underlying_Type (Typ), Name_Initialize)); | |
7001 | ||
7002 | begin | |
7003 | if Present (Init) | |
7004 | and then Comes_From_Source (Init) | |
7005 | and then not | |
7006 | Is_Predefined_File_Name | |
7007 | (File_Name (Get_Source_File_Index (Sloc (Init)))) | |
7008 | then | |
7009 | return True; | |
7010 | ||
7011 | elsif Has_Null_Extension (Typ) | |
7012 | and then | |
7013 | Is_Fully_Initialized_Type | |
7014 | (Etype (Base_Type (Typ))) | |
7015 | then | |
7016 | return True; | |
7017 | end if; | |
7018 | end; | |
7019 | end if; | |
7020 | end; | |
7021 | end if; | |
7022 | ||
7023 | -- Otherwise see if all record components are initialized | |
7024 | ||
996ae0b0 RK |
7025 | declare |
7026 | Ent : Entity_Id; | |
7027 | ||
7028 | begin | |
7029 | Ent := First_Entity (Typ); | |
996ae0b0 | 7030 | while Present (Ent) loop |
df3e68b1 | 7031 | if Ekind (Ent) = E_Component |
996ae0b0 RK |
7032 | and then (No (Parent (Ent)) |
7033 | or else No (Expression (Parent (Ent)))) | |
7034 | and then not Is_Fully_Initialized_Type (Etype (Ent)) | |
1b6c95c4 | 7035 | |
ce4a6e84 RD |
7036 | -- Special VM case for tag components, which need to be |
7037 | -- defined in this case, but are never initialized as VMs | |
1b6c95c4 | 7038 | -- are using other dispatching mechanisms. Ignore this |
ce4a6e84 RD |
7039 | -- uninitialized case. Note that this applies both to the |
7040 | -- uTag entry and the main vtable pointer (CPP_Class case). | |
1b6c95c4 | 7041 | |
1f110335 | 7042 | and then (Tagged_Type_Expansion or else not Is_Tag (Ent)) |
996ae0b0 RK |
7043 | then |
7044 | return False; | |
7045 | end if; | |
7046 | ||
7047 | Next_Entity (Ent); | |
7048 | end loop; | |
7049 | end; | |
7050 | ||
07fc65c4 GB |
7051 | -- No uninitialized components, so type is fully initialized. |
7052 | -- Note that this catches the case of no components as well. | |
7053 | ||
996ae0b0 RK |
7054 | return True; |
7055 | ||
7056 | elsif Is_Concurrent_Type (Typ) then | |
7057 | return True; | |
7058 | ||
7059 | elsif Is_Private_Type (Typ) then | |
7060 | declare | |
7061 | U : constant Entity_Id := Underlying_Type (Typ); | |
7062 | ||
7063 | begin | |
7064 | if No (U) then | |
7065 | return False; | |
7066 | else | |
7067 | return Is_Fully_Initialized_Type (U); | |
7068 | end if; | |
7069 | end; | |
7070 | ||
7071 | else | |
7072 | return False; | |
7073 | end if; | |
7074 | end Is_Fully_Initialized_Type; | |
7075 | ||
fbf5a39b AC |
7076 | ---------------------------------- |
7077 | -- Is_Fully_Initialized_Variant -- | |
7078 | ---------------------------------- | |
7079 | ||
7080 | function Is_Fully_Initialized_Variant (Typ : Entity_Id) return Boolean is | |
7081 | Loc : constant Source_Ptr := Sloc (Typ); | |
91b1417d AC |
7082 | Constraints : constant List_Id := New_List; |
7083 | Components : constant Elist_Id := New_Elmt_List; | |
fbf5a39b AC |
7084 | Comp_Elmt : Elmt_Id; |
7085 | Comp_Id : Node_Id; | |
7086 | Comp_List : Node_Id; | |
7087 | Discr : Entity_Id; | |
7088 | Discr_Val : Node_Id; | |
67ce0d7e | 7089 | |
fbf5a39b | 7090 | Report_Errors : Boolean; |
67ce0d7e | 7091 | pragma Warnings (Off, Report_Errors); |
fbf5a39b AC |
7092 | |
7093 | begin | |
7094 | if Serious_Errors_Detected > 0 then | |
7095 | return False; | |
7096 | end if; | |
7097 | ||
7098 | if Is_Record_Type (Typ) | |
7099 | and then Nkind (Parent (Typ)) = N_Full_Type_Declaration | |
7100 | and then Nkind (Type_Definition (Parent (Typ))) = N_Record_Definition | |
7101 | then | |
7102 | Comp_List := Component_List (Type_Definition (Parent (Typ))); | |
fbf5a39b | 7103 | |
9b0986f8 | 7104 | Discr := First_Discriminant (Typ); |
fbf5a39b AC |
7105 | while Present (Discr) loop |
7106 | if Nkind (Parent (Discr)) = N_Discriminant_Specification then | |
7107 | Discr_Val := Expression (Parent (Discr)); | |
1c6c6771 ES |
7108 | |
7109 | if Present (Discr_Val) | |
7110 | and then Is_OK_Static_Expression (Discr_Val) | |
7111 | then | |
fbf5a39b AC |
7112 | Append_To (Constraints, |
7113 | Make_Component_Association (Loc, | |
7114 | Choices => New_List (New_Occurrence_Of (Discr, Loc)), | |
7115 | Expression => New_Copy (Discr_Val))); | |
1c6c6771 ES |
7116 | else |
7117 | return False; | |
fbf5a39b AC |
7118 | end if; |
7119 | else | |
7120 | return False; | |
7121 | end if; | |
7122 | ||
7123 | Next_Discriminant (Discr); | |
7124 | end loop; | |
7125 | ||
7126 | Gather_Components | |
7127 | (Typ => Typ, | |
7128 | Comp_List => Comp_List, | |
7129 | Governed_By => Constraints, | |
7130 | Into => Components, | |
7131 | Report_Errors => Report_Errors); | |
7132 | ||
130c236a | 7133 | -- Check that each component present is fully initialized |
fbf5a39b AC |
7134 | |
7135 | Comp_Elmt := First_Elmt (Components); | |
fbf5a39b AC |
7136 | while Present (Comp_Elmt) loop |
7137 | Comp_Id := Node (Comp_Elmt); | |
7138 | ||
7139 | if Ekind (Comp_Id) = E_Component | |
7140 | and then (No (Parent (Comp_Id)) | |
7141 | or else No (Expression (Parent (Comp_Id)))) | |
7142 | and then not Is_Fully_Initialized_Type (Etype (Comp_Id)) | |
7143 | then | |
7144 | return False; | |
7145 | end if; | |
7146 | ||
7147 | Next_Elmt (Comp_Elmt); | |
7148 | end loop; | |
7149 | ||
7150 | return True; | |
7151 | ||
7152 | elsif Is_Private_Type (Typ) then | |
7153 | declare | |
7154 | U : constant Entity_Id := Underlying_Type (Typ); | |
7155 | ||
7156 | begin | |
7157 | if No (U) then | |
7158 | return False; | |
7159 | else | |
7160 | return Is_Fully_Initialized_Variant (U); | |
7161 | end if; | |
7162 | end; | |
7163 | else | |
7164 | return False; | |
7165 | end if; | |
7166 | end Is_Fully_Initialized_Variant; | |
7167 | ||
3e24afaa AC |
7168 | ----------------- |
7169 | -- Is_Iterator -- | |
7170 | ----------------- | |
7171 | ||
7172 | function Is_Iterator (Typ : Entity_Id) return Boolean is | |
7173 | Ifaces_List : Elist_Id; | |
7174 | Iface_Elmt : Elmt_Id; | |
7175 | Iface : Entity_Id; | |
7176 | ||
7177 | begin | |
14848f57 AC |
7178 | if Is_Class_Wide_Type (Typ) |
7179 | and then | |
7180 | (Chars (Etype (Typ)) = Name_Forward_Iterator | |
833eaa8a AC |
7181 | or else |
7182 | Chars (Etype (Typ)) = Name_Reversible_Iterator) | |
14848f57 AC |
7183 | and then |
7184 | Is_Predefined_File_Name | |
7185 | (Unit_File_Name (Get_Source_Unit (Etype (Typ)))) | |
7186 | then | |
7187 | return True; | |
7188 | ||
833eaa8a | 7189 | elsif not Is_Tagged_Type (Typ) or else not Is_Derived_Type (Typ) then |
3e24afaa AC |
7190 | return False; |
7191 | ||
7192 | else | |
7193 | Collect_Interfaces (Typ, Ifaces_List); | |
7194 | ||
7195 | Iface_Elmt := First_Elmt (Ifaces_List); | |
7196 | while Present (Iface_Elmt) loop | |
7197 | Iface := Node (Iface_Elmt); | |
7198 | if Chars (Iface) = Name_Forward_Iterator | |
7199 | and then | |
7200 | Is_Predefined_File_Name | |
7201 | (Unit_File_Name (Get_Source_Unit (Iface))) | |
7202 | then | |
7203 | return True; | |
7204 | end if; | |
7205 | ||
7206 | Next_Elmt (Iface_Elmt); | |
7207 | end loop; | |
7208 | ||
7209 | return False; | |
7210 | end if; | |
3e24afaa | 7211 | end Is_Iterator; |
14848f57 | 7212 | |
75ba322d AC |
7213 | ------------ |
7214 | -- Is_LHS -- | |
7215 | ------------ | |
7216 | ||
9337aa0a AC |
7217 | -- We seem to have a lot of overlapping functions that do similar things |
7218 | -- (testing for left hand sides or lvalues???). Anyway, since this one is | |
7219 | -- purely syntactic, it should be in Sem_Aux I would think??? | |
7220 | ||
75ba322d | 7221 | function Is_LHS (N : Node_Id) return Boolean is |
9337aa0a | 7222 | P : constant Node_Id := Parent (N); |
61c161b2 | 7223 | |
75ba322d | 7224 | begin |
84df40f7 AC |
7225 | if Nkind (P) = N_Assignment_Statement then |
7226 | return Name (P) = N; | |
7227 | ||
7228 | elsif | |
7229 | Nkind_In (P, N_Indexed_Component, N_Selected_Component, N_Slice) | |
7230 | then | |
7231 | return N = Prefix (P) and then Is_LHS (P); | |
7232 | ||
7233 | else | |
7234 | return False; | |
7235 | end if; | |
75ba322d AC |
7236 | end Is_LHS; |
7237 | ||
996ae0b0 RK |
7238 | ---------------------------- |
7239 | -- Is_Inherited_Operation -- | |
7240 | ---------------------------- | |
7241 | ||
7242 | function Is_Inherited_Operation (E : Entity_Id) return Boolean is | |
7243 | Kind : constant Node_Kind := Nkind (Parent (E)); | |
996ae0b0 RK |
7244 | begin |
7245 | pragma Assert (Is_Overloadable (E)); | |
7246 | return Kind = N_Full_Type_Declaration | |
7247 | or else Kind = N_Private_Extension_Declaration | |
7248 | or else Kind = N_Subtype_Declaration | |
7249 | or else (Ekind (E) = E_Enumeration_Literal | |
7250 | and then Is_Derived_Type (Etype (E))); | |
7251 | end Is_Inherited_Operation; | |
7252 | ||
12f0c50c AC |
7253 | ------------------------------------- |
7254 | -- Is_Inherited_Operation_For_Type -- | |
7255 | ------------------------------------- | |
7256 | ||
7257 | function Is_Inherited_Operation_For_Type | |
ded8909b | 7258 | (E : Entity_Id; Typ : Entity_Id) return Boolean |
12f0c50c AC |
7259 | is |
7260 | begin | |
7261 | return Is_Inherited_Operation (E) | |
7262 | and then Etype (Parent (E)) = Typ; | |
7263 | end Is_Inherited_Operation_For_Type; | |
7264 | ||
996ae0b0 RK |
7265 | ----------------------------- |
7266 | -- Is_Library_Level_Entity -- | |
7267 | ----------------------------- | |
7268 | ||
7269 | function Is_Library_Level_Entity (E : Entity_Id) return Boolean is | |
7270 | begin | |
1b6c95c4 RD |
7271 | -- The following is a small optimization, and it also properly handles |
7272 | -- discriminals, which in task bodies might appear in expressions before | |
7273 | -- the corresponding procedure has been created, and which therefore do | |
7274 | -- not have an assigned scope. | |
fbf5a39b | 7275 | |
099ace5e | 7276 | if Is_Formal (E) then |
fbf5a39b AC |
7277 | return False; |
7278 | end if; | |
7279 | ||
7280 | -- Normal test is simply that the enclosing dynamic scope is Standard | |
7281 | ||
996ae0b0 RK |
7282 | return Enclosing_Dynamic_Scope (E) = Standard_Standard; |
7283 | end Is_Library_Level_Entity; | |
7284 | ||
7285 | --------------------------------- | |
7286 | -- Is_Local_Variable_Reference -- | |
7287 | --------------------------------- | |
7288 | ||
7289 | function Is_Local_Variable_Reference (Expr : Node_Id) return Boolean is | |
7290 | begin | |
7291 | if not Is_Entity_Name (Expr) then | |
7292 | return False; | |
7293 | ||
7294 | else | |
7295 | declare | |
7296 | Ent : constant Entity_Id := Entity (Expr); | |
7297 | Sub : constant Entity_Id := Enclosing_Subprogram (Ent); | |
996ae0b0 | 7298 | begin |
8a95f4e8 | 7299 | if not Ekind_In (Ent, E_Variable, E_In_Out_Parameter) then |
996ae0b0 | 7300 | return False; |
996ae0b0 RK |
7301 | else |
7302 | return Present (Sub) and then Sub = Current_Subprogram; | |
7303 | end if; | |
7304 | end; | |
7305 | end if; | |
7306 | end Is_Local_Variable_Reference; | |
7307 | ||
7308 | ------------------------- | |
7309 | -- Is_Object_Reference -- | |
7310 | ------------------------- | |
7311 | ||
7312 | function Is_Object_Reference (N : Node_Id) return Boolean is | |
7313 | begin | |
7314 | if Is_Entity_Name (N) then | |
1b6c95c4 | 7315 | return Present (Entity (N)) and then Is_Object (Entity (N)); |
996ae0b0 RK |
7316 | |
7317 | else | |
7318 | case Nkind (N) is | |
7319 | when N_Indexed_Component | N_Slice => | |
ac0ed726 ES |
7320 | return |
7321 | Is_Object_Reference (Prefix (N)) | |
7322 | or else Is_Access_Type (Etype (Prefix (N))); | |
996ae0b0 | 7323 | |
2c867f5a ES |
7324 | -- In Ada95, a function call is a constant object; a procedure |
7325 | -- call is not. | |
996ae0b0 RK |
7326 | |
7327 | when N_Function_Call => | |
2c867f5a | 7328 | return Etype (N) /= Standard_Void_Type; |
996ae0b0 | 7329 | |
fbf5a39b | 7330 | -- A reference to the stream attribute Input is a function call |
07fc65c4 GB |
7331 | |
7332 | when N_Attribute_Reference => | |
7333 | return Attribute_Name (N) = Name_Input; | |
7334 | ||
996ae0b0 | 7335 | when N_Selected_Component => |
8a36a0cc AC |
7336 | return |
7337 | Is_Object_Reference (Selector_Name (N)) | |
ac0ed726 ES |
7338 | and then |
7339 | (Is_Object_Reference (Prefix (N)) | |
7340 | or else Is_Access_Type (Etype (Prefix (N)))); | |
996ae0b0 RK |
7341 | |
7342 | when N_Explicit_Dereference => | |
7343 | return True; | |
7344 | ||
130c236a | 7345 | -- A view conversion of a tagged object is an object reference |
24105bab AC |
7346 | |
7347 | when N_Type_Conversion => | |
7348 | return Is_Tagged_Type (Etype (Subtype_Mark (N))) | |
7349 | and then Is_Tagged_Type (Etype (Expression (N))) | |
7350 | and then Is_Object_Reference (Expression (N)); | |
7351 | ||
996ae0b0 RK |
7352 | -- An unchecked type conversion is considered to be an object if |
7353 | -- the operand is an object (this construction arises only as a | |
7354 | -- result of expansion activities). | |
7355 | ||
7356 | when N_Unchecked_Type_Conversion => | |
7357 | return True; | |
7358 | ||
7359 | when others => | |
7360 | return False; | |
7361 | end case; | |
7362 | end if; | |
7363 | end Is_Object_Reference; | |
7364 | ||
7365 | ----------------------------------- | |
7366 | -- Is_OK_Variable_For_Out_Formal -- | |
7367 | ----------------------------------- | |
7368 | ||
7369 | function Is_OK_Variable_For_Out_Formal (AV : Node_Id) return Boolean is | |
7370 | begin | |
ce4a6e84 | 7371 | Note_Possible_Modification (AV, Sure => True); |
996ae0b0 RK |
7372 | |
7373 | -- We must reject parenthesized variable names. The check for | |
7374 | -- Comes_From_Source is present because there are currently | |
7375 | -- cases where the compiler violates this rule (e.g. passing | |
7376 | -- a task object to its controlled Initialize routine). | |
7377 | ||
7378 | if Paren_Count (AV) > 0 and then Comes_From_Source (AV) then | |
7379 | return False; | |
7380 | ||
7381 | -- A variable is always allowed | |
7382 | ||
7383 | elsif Is_Variable (AV) then | |
7384 | return True; | |
7385 | ||
7386 | -- Unchecked conversions are allowed only if they come from the | |
21024a39 RD |
7387 | -- generated code, which sometimes uses unchecked conversions for out |
7388 | -- parameters in cases where code generation is unaffected. We tell | |
7389 | -- source unchecked conversions by seeing if they are rewrites of an | |
7390 | -- original Unchecked_Conversion function call, or of an explicit | |
996ae0b0 RK |
7391 | -- conversion of a function call. |
7392 | ||
7393 | elsif Nkind (AV) = N_Unchecked_Type_Conversion then | |
7394 | if Nkind (Original_Node (AV)) = N_Function_Call then | |
7395 | return False; | |
7396 | ||
7397 | elsif Comes_From_Source (AV) | |
7398 | and then Nkind (Original_Node (Expression (AV))) = N_Function_Call | |
7399 | then | |
7400 | return False; | |
7401 | ||
615cbd95 AC |
7402 | elsif Nkind (Original_Node (AV)) = N_Type_Conversion then |
7403 | return Is_OK_Variable_For_Out_Formal (Expression (AV)); | |
7404 | ||
996ae0b0 RK |
7405 | else |
7406 | return True; | |
7407 | end if; | |
7408 | ||
7409 | -- Normal type conversions are allowed if argument is a variable | |
7410 | ||
7411 | elsif Nkind (AV) = N_Type_Conversion then | |
7412 | if Is_Variable (Expression (AV)) | |
7413 | and then Paren_Count (Expression (AV)) = 0 | |
7414 | then | |
ce4a6e84 | 7415 | Note_Possible_Modification (Expression (AV), Sure => True); |
996ae0b0 RK |
7416 | return True; |
7417 | ||
7418 | -- We also allow a non-parenthesized expression that raises | |
7419 | -- constraint error if it rewrites what used to be a variable | |
7420 | ||
7421 | elsif Raises_Constraint_Error (Expression (AV)) | |
7422 | and then Paren_Count (Expression (AV)) = 0 | |
7423 | and then Is_Variable (Original_Node (Expression (AV))) | |
7424 | then | |
7425 | return True; | |
7426 | ||
7427 | -- Type conversion of something other than a variable | |
7428 | ||
7429 | else | |
7430 | return False; | |
7431 | end if; | |
7432 | ||
7433 | -- If this node is rewritten, then test the original form, if that is | |
7434 | -- OK, then we consider the rewritten node OK (for example, if the | |
7435 | -- original node is a conversion, then Is_Variable will not be true | |
fbf5a39b | 7436 | -- but we still want to allow the conversion if it converts a variable). |
996ae0b0 RK |
7437 | |
7438 | elsif Original_Node (AV) /= AV then | |
690943fc RD |
7439 | |
7440 | -- In Ada2012, the explicit dereference may be a rewritten call to a | |
7441 | -- Reference function. | |
7442 | ||
3e24afaa AC |
7443 | if Ada_Version >= Ada_2012 |
7444 | and then Nkind (Original_Node (AV)) = N_Function_Call | |
7445 | and then | |
690943fc | 7446 | Has_Implicit_Dereference (Etype (Name (Original_Node (AV)))) |
3e24afaa AC |
7447 | then |
7448 | return True; | |
7449 | ||
7450 | else | |
7451 | return Is_OK_Variable_For_Out_Formal (Original_Node (AV)); | |
7452 | end if; | |
996ae0b0 RK |
7453 | |
7454 | -- All other non-variables are rejected | |
7455 | ||
7456 | else | |
7457 | return False; | |
7458 | end if; | |
7459 | end Is_OK_Variable_For_Out_Formal; | |
7460 | ||
07fc65c4 GB |
7461 | ----------------------------------- |
7462 | -- Is_Partially_Initialized_Type -- | |
7463 | ----------------------------------- | |
7464 | ||
b4ca2d2c | 7465 | function Is_Partially_Initialized_Type |
f2acf80c AC |
7466 | (Typ : Entity_Id; |
7467 | Include_Implicit : Boolean := True) return Boolean | |
b4ca2d2c | 7468 | is |
07fc65c4 GB |
7469 | begin |
7470 | if Is_Scalar_Type (Typ) then | |
7471 | return False; | |
7472 | ||
7473 | elsif Is_Access_Type (Typ) then | |
f2acf80c | 7474 | return Include_Implicit; |
07fc65c4 GB |
7475 | |
7476 | elsif Is_Array_Type (Typ) then | |
7477 | ||
7478 | -- If component type is partially initialized, so is array type | |
7479 | ||
b4ca2d2c | 7480 | if Is_Partially_Initialized_Type |
f2acf80c | 7481 | (Component_Type (Typ), Include_Implicit) |
b4ca2d2c | 7482 | then |
07fc65c4 GB |
7483 | return True; |
7484 | ||
7485 | -- Otherwise we are only partially initialized if we are fully | |
7486 | -- initialized (this is the empty array case, no point in us | |
7487 | -- duplicating that code here). | |
7488 | ||
7489 | else | |
7490 | return Is_Fully_Initialized_Type (Typ); | |
7491 | end if; | |
7492 | ||
7493 | elsif Is_Record_Type (Typ) then | |
7494 | ||
f2acf80c AC |
7495 | -- A discriminated type is always partially initialized if in |
7496 | -- all mode | |
07fc65c4 | 7497 | |
f2acf80c | 7498 | if Has_Discriminants (Typ) and then Include_Implicit then |
07fc65c4 GB |
7499 | return True; |
7500 | ||
7501 | -- A tagged type is always partially initialized | |
7502 | ||
7503 | elsif Is_Tagged_Type (Typ) then | |
7504 | return True; | |
7505 | ||
7506 | -- Case of non-discriminated record | |
7507 | ||
7508 | else | |
7509 | declare | |
7510 | Ent : Entity_Id; | |
7511 | ||
7512 | Component_Present : Boolean := False; | |
7513 | -- Set True if at least one component is present. If no | |
7514 | -- components are present, then record type is fully | |
7515 | -- initialized (another odd case, like the null array). | |
7516 | ||
7517 | begin | |
7518 | -- Loop through components | |
7519 | ||
7520 | Ent := First_Entity (Typ); | |
7521 | while Present (Ent) loop | |
7522 | if Ekind (Ent) = E_Component then | |
7523 | Component_Present := True; | |
7524 | ||
7525 | -- If a component has an initialization expression then | |
7526 | -- the enclosing record type is partially initialized | |
7527 | ||
7528 | if Present (Parent (Ent)) | |
7529 | and then Present (Expression (Parent (Ent))) | |
7530 | then | |
7531 | return True; | |
7532 | ||
7533 | -- If a component is of a type which is itself partially | |
7534 | -- initialized, then the enclosing record type is also. | |
7535 | ||
b4ca2d2c | 7536 | elsif Is_Partially_Initialized_Type |
f2acf80c | 7537 | (Etype (Ent), Include_Implicit) |
b4ca2d2c | 7538 | then |
07fc65c4 GB |
7539 | return True; |
7540 | end if; | |
7541 | end if; | |
7542 | ||
7543 | Next_Entity (Ent); | |
7544 | end loop; | |
7545 | ||
7546 | -- No initialized components found. If we found any components | |
7547 | -- they were all uninitialized so the result is false. | |
7548 | ||
7549 | if Component_Present then | |
7550 | return False; | |
7551 | ||
7552 | -- But if we found no components, then all the components are | |
7553 | -- initialized so we consider the type to be initialized. | |
7554 | ||
7555 | else | |
7556 | return True; | |
7557 | end if; | |
7558 | end; | |
7559 | end if; | |
7560 | ||
7561 | -- Concurrent types are always fully initialized | |
7562 | ||
7563 | elsif Is_Concurrent_Type (Typ) then | |
7564 | return True; | |
7565 | ||
7566 | -- For a private type, go to underlying type. If there is no underlying | |
7567 | -- type then just assume this partially initialized. Not clear if this | |
7568 | -- can happen in a non-error case, but no harm in testing for this. | |
7569 | ||
7570 | elsif Is_Private_Type (Typ) then | |
7571 | declare | |
7572 | U : constant Entity_Id := Underlying_Type (Typ); | |
07fc65c4 GB |
7573 | begin |
7574 | if No (U) then | |
7575 | return True; | |
7576 | else | |
f2acf80c | 7577 | return Is_Partially_Initialized_Type (U, Include_Implicit); |
07fc65c4 GB |
7578 | end if; |
7579 | end; | |
7580 | ||
7581 | -- For any other type (are there any?) assume partially initialized | |
7582 | ||
7583 | else | |
7584 | return True; | |
7585 | end if; | |
7586 | end Is_Partially_Initialized_Type; | |
7587 | ||
edd63e9b ES |
7588 | ------------------------------------ |
7589 | -- Is_Potentially_Persistent_Type -- | |
7590 | ------------------------------------ | |
7591 | ||
7592 | function Is_Potentially_Persistent_Type (T : Entity_Id) return Boolean is | |
7593 | Comp : Entity_Id; | |
7594 | Indx : Node_Id; | |
7595 | ||
7596 | begin | |
f3d57416 | 7597 | -- For private type, test corresponding full type |
edd63e9b ES |
7598 | |
7599 | if Is_Private_Type (T) then | |
7600 | return Is_Potentially_Persistent_Type (Full_View (T)); | |
7601 | ||
7602 | -- Scalar types are potentially persistent | |
7603 | ||
7604 | elsif Is_Scalar_Type (T) then | |
7605 | return True; | |
7606 | ||
7607 | -- Record type is potentially persistent if not tagged and the types of | |
7608 | -- all it components are potentially persistent, and no component has | |
7609 | -- an initialization expression. | |
7610 | ||
7611 | elsif Is_Record_Type (T) | |
7612 | and then not Is_Tagged_Type (T) | |
7613 | and then not Is_Partially_Initialized_Type (T) | |
7614 | then | |
7615 | Comp := First_Component (T); | |
7616 | while Present (Comp) loop | |
7617 | if not Is_Potentially_Persistent_Type (Etype (Comp)) then | |
7618 | return False; | |
7619 | else | |
7620 | Next_Entity (Comp); | |
7621 | end if; | |
7622 | end loop; | |
7623 | ||
7624 | return True; | |
7625 | ||
7626 | -- Array type is potentially persistent if its component type is | |
7627 | -- potentially persistent and if all its constraints are static. | |
7628 | ||
7629 | elsif Is_Array_Type (T) then | |
7630 | if not Is_Potentially_Persistent_Type (Component_Type (T)) then | |
7631 | return False; | |
7632 | end if; | |
7633 | ||
7634 | Indx := First_Index (T); | |
7635 | while Present (Indx) loop | |
7636 | if not Is_OK_Static_Subtype (Etype (Indx)) then | |
7637 | return False; | |
7638 | else | |
7639 | Next_Index (Indx); | |
7640 | end if; | |
7641 | end loop; | |
7642 | ||
7643 | return True; | |
7644 | ||
7645 | -- All other types are not potentially persistent | |
7646 | ||
7647 | else | |
7648 | return False; | |
7649 | end if; | |
7650 | end Is_Potentially_Persistent_Type; | |
7651 | ||
2d14501c ST |
7652 | --------------------------------- |
7653 | -- Is_Protected_Self_Reference -- | |
7654 | --------------------------------- | |
7655 | ||
ae8c7d87 RD |
7656 | function Is_Protected_Self_Reference (N : Node_Id) return Boolean is |
7657 | ||
2d14501c ST |
7658 | function In_Access_Definition (N : Node_Id) return Boolean; |
7659 | -- Returns true if N belongs to an access definition | |
7660 | ||
7661 | -------------------------- | |
7662 | -- In_Access_Definition -- | |
7663 | -------------------------- | |
7664 | ||
ae8c7d87 RD |
7665 | function In_Access_Definition (N : Node_Id) return Boolean is |
7666 | P : Node_Id; | |
7667 | ||
2d14501c | 7668 | begin |
ae8c7d87 | 7669 | P := Parent (N); |
2d14501c ST |
7670 | while Present (P) loop |
7671 | if Nkind (P) = N_Access_Definition then | |
7672 | return True; | |
7673 | end if; | |
ae8c7d87 | 7674 | |
2d14501c ST |
7675 | P := Parent (P); |
7676 | end loop; | |
ae8c7d87 | 7677 | |
2d14501c ST |
7678 | return False; |
7679 | end In_Access_Definition; | |
7680 | ||
7681 | -- Start of processing for Is_Protected_Self_Reference | |
7682 | ||
7683 | begin | |
ed57136d | 7684 | -- Verify that prefix is analyzed and has the proper form. Note that |
0bfc9a64 AC |
7685 | -- the attributes Elab_Spec, Elab_Body, Elab_Subp_Body and UET_Address, |
7686 | -- which also produce the address of an entity, do not analyze their | |
7687 | -- prefix because they denote entities that are not necessarily visible. | |
ed57136d AC |
7688 | -- Neither of them can apply to a protected type. |
7689 | ||
0791fbe9 | 7690 | return Ada_Version >= Ada_2005 |
2d14501c | 7691 | and then Is_Entity_Name (N) |
ed57136d | 7692 | and then Present (Entity (N)) |
2d14501c ST |
7693 | and then Is_Protected_Type (Entity (N)) |
7694 | and then In_Open_Scopes (Entity (N)) | |
7695 | and then not In_Access_Definition (N); | |
7696 | end Is_Protected_Self_Reference; | |
7697 | ||
996ae0b0 RK |
7698 | ----------------------------- |
7699 | -- Is_RCI_Pkg_Spec_Or_Body -- | |
7700 | ----------------------------- | |
7701 | ||
7702 | function Is_RCI_Pkg_Spec_Or_Body (Cunit : Node_Id) return Boolean is | |
7703 | ||
7704 | function Is_RCI_Pkg_Decl_Cunit (Cunit : Node_Id) return Boolean; | |
7705 | -- Return True if the unit of Cunit is an RCI package declaration | |
7706 | ||
7707 | --------------------------- | |
7708 | -- Is_RCI_Pkg_Decl_Cunit -- | |
7709 | --------------------------- | |
7710 | ||
7711 | function Is_RCI_Pkg_Decl_Cunit (Cunit : Node_Id) return Boolean is | |
7712 | The_Unit : constant Node_Id := Unit (Cunit); | |
7713 | ||
7714 | begin | |
7715 | if Nkind (The_Unit) /= N_Package_Declaration then | |
7716 | return False; | |
7717 | end if; | |
21024a39 | 7718 | |
996ae0b0 RK |
7719 | return Is_Remote_Call_Interface (Defining_Entity (The_Unit)); |
7720 | end Is_RCI_Pkg_Decl_Cunit; | |
7721 | ||
7722 | -- Start of processing for Is_RCI_Pkg_Spec_Or_Body | |
7723 | ||
7724 | begin | |
7725 | return Is_RCI_Pkg_Decl_Cunit (Cunit) | |
7726 | or else | |
7727 | (Nkind (Unit (Cunit)) = N_Package_Body | |
7728 | and then Is_RCI_Pkg_Decl_Cunit (Library_Unit (Cunit))); | |
7729 | end Is_RCI_Pkg_Spec_Or_Body; | |
7730 | ||
7731 | ----------------------------------------- | |
7732 | -- Is_Remote_Access_To_Class_Wide_Type -- | |
7733 | ----------------------------------------- | |
7734 | ||
7735 | function Is_Remote_Access_To_Class_Wide_Type | |
fbf5a39b | 7736 | (E : Entity_Id) return Boolean |
996ae0b0 | 7737 | is |
996ae0b0 | 7738 | begin |
de5cd98e TQ |
7739 | -- A remote access to class-wide type is a general access to object type |
7740 | -- declared in the visible part of a Remote_Types or Remote_Call_ | |
7741 | -- Interface unit. | |
996ae0b0 | 7742 | |
de5cd98e TQ |
7743 | return Ekind (E) = E_General_Access_Type |
7744 | and then (Is_Remote_Call_Interface (E) or else Is_Remote_Types (E)); | |
996ae0b0 RK |
7745 | end Is_Remote_Access_To_Class_Wide_Type; |
7746 | ||
7747 | ----------------------------------------- | |
7748 | -- Is_Remote_Access_To_Subprogram_Type -- | |
7749 | ----------------------------------------- | |
7750 | ||
7751 | function Is_Remote_Access_To_Subprogram_Type | |
fbf5a39b | 7752 | (E : Entity_Id) return Boolean |
996ae0b0 RK |
7753 | is |
7754 | begin | |
7755 | return (Ekind (E) = E_Access_Subprogram_Type | |
7756 | or else (Ekind (E) = E_Record_Type | |
7757 | and then Present (Corresponding_Remote_Type (E)))) | |
de5cd98e | 7758 | and then (Is_Remote_Call_Interface (E) or else Is_Remote_Types (E)); |
996ae0b0 RK |
7759 | end Is_Remote_Access_To_Subprogram_Type; |
7760 | ||
7761 | -------------------- | |
7762 | -- Is_Remote_Call -- | |
7763 | -------------------- | |
7764 | ||
7765 | function Is_Remote_Call (N : Node_Id) return Boolean is | |
7766 | begin | |
7767 | if Nkind (N) /= N_Procedure_Call_Statement | |
7768 | and then Nkind (N) /= N_Function_Call | |
7769 | then | |
7770 | -- An entry call cannot be remote | |
7771 | ||
7772 | return False; | |
7773 | ||
7774 | elsif Nkind (Name (N)) in N_Has_Entity | |
7775 | and then Is_Remote_Call_Interface (Entity (Name (N))) | |
7776 | then | |
7777 | -- A subprogram declared in the spec of a RCI package is remote | |
7778 | ||
7779 | return True; | |
7780 | ||
7781 | elsif Nkind (Name (N)) = N_Explicit_Dereference | |
7782 | and then Is_Remote_Access_To_Subprogram_Type | |
482a63fb | 7783 | (Etype (Prefix (Name (N)))) |
996ae0b0 RK |
7784 | then |
7785 | -- The dereference of a RAS is a remote call | |
7786 | ||
7787 | return True; | |
7788 | ||
7789 | elsif Present (Controlling_Argument (N)) | |
7790 | and then Is_Remote_Access_To_Class_Wide_Type | |
7791 | (Etype (Controlling_Argument (N))) | |
7792 | then | |
7793 | -- Any primitive operation call with a controlling argument of | |
7794 | -- a RACW type is a remote call. | |
7795 | ||
7796 | return True; | |
7797 | end if; | |
7798 | ||
7799 | -- All other calls are local calls | |
7800 | ||
7801 | return False; | |
7802 | end Is_Remote_Call; | |
7803 | ||
2c867f5a ES |
7804 | ---------------------- |
7805 | -- Is_Renamed_Entry -- | |
7806 | ---------------------- | |
7807 | ||
7808 | function Is_Renamed_Entry (Proc_Nam : Entity_Id) return Boolean is | |
7809 | Orig_Node : Node_Id := Empty; | |
7810 | Subp_Decl : Node_Id := Parent (Parent (Proc_Nam)); | |
7811 | ||
7812 | function Is_Entry (Nam : Node_Id) return Boolean; | |
de5cd98e TQ |
7813 | -- Determine whether Nam is an entry. Traverse selectors if there are |
7814 | -- nested selected components. | |
2c867f5a ES |
7815 | |
7816 | -------------- | |
7817 | -- Is_Entry -- | |
7818 | -------------- | |
7819 | ||
7820 | function Is_Entry (Nam : Node_Id) return Boolean is | |
7821 | begin | |
7822 | if Nkind (Nam) = N_Selected_Component then | |
7823 | return Is_Entry (Selector_Name (Nam)); | |
7824 | end if; | |
7825 | ||
7826 | return Ekind (Entity (Nam)) = E_Entry; | |
7827 | end Is_Entry; | |
7828 | ||
7829 | -- Start of processing for Is_Renamed_Entry | |
7830 | ||
7831 | begin | |
7832 | if Present (Alias (Proc_Nam)) then | |
7833 | Subp_Decl := Parent (Parent (Alias (Proc_Nam))); | |
7834 | end if; | |
7835 | ||
7836 | -- Look for a rewritten subprogram renaming declaration | |
7837 | ||
7838 | if Nkind (Subp_Decl) = N_Subprogram_Declaration | |
7839 | and then Present (Original_Node (Subp_Decl)) | |
7840 | then | |
7841 | Orig_Node := Original_Node (Subp_Decl); | |
7842 | end if; | |
7843 | ||
7844 | -- The rewritten subprogram is actually an entry | |
7845 | ||
7846 | if Present (Orig_Node) | |
7847 | and then Nkind (Orig_Node) = N_Subprogram_Renaming_Declaration | |
7848 | and then Is_Entry (Name (Orig_Node)) | |
7849 | then | |
7850 | return True; | |
7851 | end if; | |
7852 | ||
7853 | return False; | |
7854 | end Is_Renamed_Entry; | |
7855 | ||
833eaa8a AC |
7856 | ---------------------------- |
7857 | -- Is_Reversible_Iterator -- | |
7858 | ---------------------------- | |
7859 | ||
7860 | function Is_Reversible_Iterator (Typ : Entity_Id) return Boolean is | |
7861 | Ifaces_List : Elist_Id; | |
7862 | Iface_Elmt : Elmt_Id; | |
7863 | Iface : Entity_Id; | |
7864 | ||
7865 | begin | |
7866 | if Is_Class_Wide_Type (Typ) | |
7867 | and then Chars (Etype (Typ)) = Name_Reversible_Iterator | |
7868 | and then | |
7869 | Is_Predefined_File_Name | |
7870 | (Unit_File_Name (Get_Source_Unit (Etype (Typ)))) | |
7871 | then | |
7872 | return True; | |
7873 | ||
7874 | elsif not Is_Tagged_Type (Typ) | |
7875 | or else not Is_Derived_Type (Typ) | |
7876 | then | |
7877 | return False; | |
7878 | ||
7879 | else | |
7880 | Collect_Interfaces (Typ, Ifaces_List); | |
7881 | ||
7882 | Iface_Elmt := First_Elmt (Ifaces_List); | |
7883 | while Present (Iface_Elmt) loop | |
7884 | Iface := Node (Iface_Elmt); | |
7885 | if Chars (Iface) = Name_Reversible_Iterator | |
7886 | and then | |
7887 | Is_Predefined_File_Name | |
7888 | (Unit_File_Name (Get_Source_Unit (Iface))) | |
7889 | then | |
7890 | return True; | |
7891 | end if; | |
7892 | ||
7893 | Next_Elmt (Iface_Elmt); | |
7894 | end loop; | |
7895 | end if; | |
7896 | ||
7897 | return False; | |
7898 | end Is_Reversible_Iterator; | |
7899 | ||
996ae0b0 RK |
7900 | ---------------------- |
7901 | -- Is_Selector_Name -- | |
7902 | ---------------------- | |
7903 | ||
7904 | function Is_Selector_Name (N : Node_Id) return Boolean is | |
996ae0b0 RK |
7905 | begin |
7906 | if not Is_List_Member (N) then | |
7907 | declare | |
7908 | P : constant Node_Id := Parent (N); | |
7909 | K : constant Node_Kind := Nkind (P); | |
996ae0b0 RK |
7910 | begin |
7911 | return | |
7912 | (K = N_Expanded_Name or else | |
7913 | K = N_Generic_Association or else | |
7914 | K = N_Parameter_Association or else | |
7915 | K = N_Selected_Component) | |
7916 | and then Selector_Name (P) = N; | |
7917 | end; | |
7918 | ||
7919 | else | |
7920 | declare | |
7921 | L : constant List_Id := List_Containing (N); | |
7922 | P : constant Node_Id := Parent (L); | |
996ae0b0 RK |
7923 | begin |
7924 | return (Nkind (P) = N_Discriminant_Association | |
7925 | and then Selector_Names (P) = L) | |
7926 | or else | |
7927 | (Nkind (P) = N_Component_Association | |
7928 | and then Choices (P) = L); | |
7929 | end; | |
7930 | end if; | |
7931 | end Is_Selector_Name; | |
7932 | ||
aa1e353a AC |
7933 | ---------------------------------- |
7934 | -- Is_SPARK_Initialization_Expr -- | |
7935 | ---------------------------------- | |
7936 | ||
7937 | function Is_SPARK_Initialization_Expr (N : Node_Id) return Boolean is | |
ded8909b AC |
7938 | Is_Ok : Boolean; |
7939 | Expr : Node_Id; | |
7940 | Comp_Assn : Node_Id; | |
f5afb270 | 7941 | Orig_N : constant Node_Id := Original_Node (N); |
aa1e353a | 7942 | |
aa1e353a AC |
7943 | begin |
7944 | Is_Ok := True; | |
7945 | ||
f5afb270 | 7946 | if not Comes_From_Source (Orig_N) then |
db72f10a AC |
7947 | goto Done; |
7948 | end if; | |
7949 | ||
f5afb270 | 7950 | pragma Assert (Nkind (Orig_N) in N_Subexpr); |
aa1e353a | 7951 | |
f5afb270 | 7952 | case Nkind (Orig_N) is |
aa1e353a AC |
7953 | when N_Character_Literal | |
7954 | N_Integer_Literal | | |
7955 | N_Real_Literal | | |
db72f10a | 7956 | N_String_Literal => |
aa1e353a AC |
7957 | null; |
7958 | ||
db72f10a AC |
7959 | when N_Identifier | |
7960 | N_Expanded_Name => | |
f5afb270 AC |
7961 | if Is_Entity_Name (Orig_N) |
7962 | and then Present (Entity (Orig_N)) -- needed in some cases | |
aa1e353a | 7963 | then |
f5afb270 | 7964 | case Ekind (Entity (Orig_N)) is |
aa1e353a AC |
7965 | when E_Constant | |
7966 | E_Enumeration_Literal | | |
7967 | E_Named_Integer | | |
7968 | E_Named_Real => | |
7969 | null; | |
7970 | when others => | |
f5afb270 | 7971 | if Is_Type (Entity (Orig_N)) then |
db72f10a AC |
7972 | null; |
7973 | else | |
7974 | Is_Ok := False; | |
7975 | end if; | |
aa1e353a AC |
7976 | end case; |
7977 | end if; | |
7978 | ||
7979 | when N_Qualified_Expression | | |
7980 | N_Type_Conversion => | |
f5afb270 | 7981 | Is_Ok := Is_SPARK_Initialization_Expr (Expression (Orig_N)); |
aa1e353a AC |
7982 | |
7983 | when N_Unary_Op => | |
f5afb270 | 7984 | Is_Ok := Is_SPARK_Initialization_Expr (Right_Opnd (Orig_N)); |
aa1e353a | 7985 | |
db72f10a AC |
7986 | when N_Binary_Op | |
7987 | N_Short_Circuit | | |
7988 | N_Membership_Test => | |
f5afb270 AC |
7989 | Is_Ok := Is_SPARK_Initialization_Expr (Left_Opnd (Orig_N)) |
7990 | and then Is_SPARK_Initialization_Expr (Right_Opnd (Orig_N)); | |
aa1e353a AC |
7991 | |
7992 | when N_Aggregate | | |
7993 | N_Extension_Aggregate => | |
f5afb270 AC |
7994 | if Nkind (Orig_N) = N_Extension_Aggregate then |
7995 | Is_Ok := Is_SPARK_Initialization_Expr (Ancestor_Part (Orig_N)); | |
aa1e353a AC |
7996 | end if; |
7997 | ||
f5afb270 | 7998 | Expr := First (Expressions (Orig_N)); |
aa1e353a AC |
7999 | while Present (Expr) loop |
8000 | if not Is_SPARK_Initialization_Expr (Expr) then | |
8001 | Is_Ok := False; | |
8002 | goto Done; | |
8003 | end if; | |
8004 | ||
8005 | Next (Expr); | |
8006 | end loop; | |
8007 | ||
f5afb270 | 8008 | Comp_Assn := First (Component_Associations (Orig_N)); |
aa1e353a | 8009 | while Present (Comp_Assn) loop |
aa1e353a AC |
8010 | Expr := Expression (Comp_Assn); |
8011 | if Present (Expr) -- needed for box association | |
8012 | and then not Is_SPARK_Initialization_Expr (Expr) | |
8013 | then | |
8014 | Is_Ok := False; | |
8015 | goto Done; | |
8016 | end if; | |
8017 | ||
8018 | Next (Comp_Assn); | |
8019 | end loop; | |
8020 | ||
8021 | when N_Attribute_Reference => | |
f5afb270 AC |
8022 | if Nkind (Prefix (Orig_N)) in N_Subexpr then |
8023 | Is_Ok := Is_SPARK_Initialization_Expr (Prefix (Orig_N)); | |
aa1e353a AC |
8024 | end if; |
8025 | ||
f5afb270 | 8026 | Expr := First (Expressions (Orig_N)); |
aa1e353a AC |
8027 | while Present (Expr) loop |
8028 | if not Is_SPARK_Initialization_Expr (Expr) then | |
8029 | Is_Ok := False; | |
8030 | goto Done; | |
8031 | end if; | |
8032 | ||
8033 | Next (Expr); | |
8034 | end loop; | |
8035 | ||
db72f10a AC |
8036 | -- Selected components might be expanded named not yet resolved, so |
8037 | -- default on the safe side. (Eg on sparklex.ads) | |
8038 | ||
8039 | when N_Selected_Component => | |
8040 | null; | |
8041 | ||
aa1e353a AC |
8042 | when others => |
8043 | Is_Ok := False; | |
8044 | end case; | |
8045 | ||
ded8909b | 8046 | <<Done>> |
aa1e353a AC |
8047 | return Is_Ok; |
8048 | end Is_SPARK_Initialization_Expr; | |
8049 | ||
12f0c50c AC |
8050 | ------------------------------- |
8051 | -- Is_SPARK_Object_Reference -- | |
8052 | ------------------------------- | |
8053 | ||
8054 | function Is_SPARK_Object_Reference (N : Node_Id) return Boolean is | |
8055 | begin | |
8056 | if Is_Entity_Name (N) then | |
8057 | return Present (Entity (N)) | |
8058 | and then | |
8059 | (Ekind_In (Entity (N), E_Constant, E_Variable) | |
8060 | or else Ekind (Entity (N)) in Formal_Kind); | |
8061 | ||
8062 | else | |
8063 | case Nkind (N) is | |
8064 | when N_Selected_Component => | |
8065 | return Is_SPARK_Object_Reference (Prefix (N)); | |
8066 | ||
8067 | when others => | |
8068 | return False; | |
8069 | end case; | |
8070 | end if; | |
8071 | end Is_SPARK_Object_Reference; | |
8072 | ||
996ae0b0 RK |
8073 | ------------------ |
8074 | -- Is_Statement -- | |
8075 | ------------------ | |
8076 | ||
8077 | function Is_Statement (N : Node_Id) return Boolean is | |
8078 | begin | |
8079 | return | |
8080 | Nkind (N) in N_Statement_Other_Than_Procedure_Call | |
8081 | or else Nkind (N) = N_Procedure_Call_Statement; | |
8082 | end Is_Statement; | |
8083 | ||
60370fb1 AC |
8084 | -------------------------------------------------- |
8085 | -- Is_Subprogram_Stub_Without_Prior_Declaration -- | |
8086 | -------------------------------------------------- | |
8087 | ||
8088 | function Is_Subprogram_Stub_Without_Prior_Declaration | |
59e6b23c AC |
8089 | (N : Node_Id) return Boolean |
8090 | is | |
60370fb1 AC |
8091 | begin |
8092 | -- A subprogram stub without prior declaration serves as declaration for | |
8093 | -- the actual subprogram body. As such, it has an attached defining | |
8094 | -- entity of E_[Generic_]Function or E_[Generic_]Procedure. | |
8095 | ||
8096 | return Nkind (N) = N_Subprogram_Body_Stub | |
8097 | and then Ekind (Defining_Entity (N)) /= E_Subprogram_Body; | |
8098 | end Is_Subprogram_Stub_Without_Prior_Declaration; | |
8099 | ||
1b6c95c4 RD |
8100 | --------------------------------- |
8101 | -- Is_Synchronized_Tagged_Type -- | |
8102 | --------------------------------- | |
8103 | ||
8104 | function Is_Synchronized_Tagged_Type (E : Entity_Id) return Boolean is | |
8105 | Kind : constant Entity_Kind := Ekind (Base_Type (E)); | |
8106 | ||
8107 | begin | |
8108 | -- A task or protected type derived from an interface is a tagged type. | |
8109 | -- Such a tagged type is called a synchronized tagged type, as are | |
8110 | -- synchronized interfaces and private extensions whose declaration | |
8111 | -- includes the reserved word synchronized. | |
8112 | ||
8113 | return (Is_Tagged_Type (E) | |
8114 | and then (Kind = E_Task_Type | |
8115 | or else Kind = E_Protected_Type)) | |
8116 | or else | |
8117 | (Is_Interface (E) | |
8118 | and then Is_Synchronized_Interface (E)) | |
8119 | or else | |
8120 | (Ekind (E) = E_Record_Type_With_Private | |
d8b3ccb9 | 8121 | and then Nkind (Parent (E)) = N_Private_Extension_Declaration |
1b6c95c4 RD |
8122 | and then (Synchronized_Present (Parent (E)) |
8123 | or else Is_Synchronized_Interface (Etype (E)))); | |
8124 | end Is_Synchronized_Tagged_Type; | |
8125 | ||
996ae0b0 RK |
8126 | ----------------- |
8127 | -- Is_Transfer -- | |
8128 | ----------------- | |
8129 | ||
8130 | function Is_Transfer (N : Node_Id) return Boolean is | |
8131 | Kind : constant Node_Kind := Nkind (N); | |
8132 | ||
8133 | begin | |
1b6c95c4 | 8134 | if Kind = N_Simple_Return_Statement |
996ae0b0 | 8135 | or else |
9b0986f8 RD |
8136 | Kind = N_Extended_Return_Statement |
8137 | or else | |
996ae0b0 RK |
8138 | Kind = N_Goto_Statement |
8139 | or else | |
8140 | Kind = N_Raise_Statement | |
8141 | or else | |
8142 | Kind = N_Requeue_Statement | |
8143 | then | |
8144 | return True; | |
8145 | ||
8146 | elsif (Kind = N_Exit_Statement or else Kind in N_Raise_xxx_Error) | |
8147 | and then No (Condition (N)) | |
8148 | then | |
8149 | return True; | |
8150 | ||
8151 | elsif Kind = N_Procedure_Call_Statement | |
8152 | and then Is_Entity_Name (Name (N)) | |
8153 | and then Present (Entity (Name (N))) | |
8154 | and then No_Return (Entity (Name (N))) | |
8155 | then | |
8156 | return True; | |
8157 | ||
8158 | elsif Nkind (Original_Node (N)) = N_Raise_Statement then | |
8159 | return True; | |
8160 | ||
8161 | else | |
8162 | return False; | |
8163 | end if; | |
8164 | end Is_Transfer; | |
8165 | ||
8166 | ------------- | |
8167 | -- Is_True -- | |
8168 | ------------- | |
8169 | ||
8170 | function Is_True (U : Uint) return Boolean is | |
8171 | begin | |
8172 | return (U /= 0); | |
8173 | end Is_True; | |
8174 | ||
d7567964 TQ |
8175 | ------------------------------- |
8176 | -- Is_Universal_Numeric_Type -- | |
8177 | ------------------------------- | |
8178 | ||
8179 | function Is_Universal_Numeric_Type (T : Entity_Id) return Boolean is | |
8180 | begin | |
8181 | return T = Universal_Integer or else T = Universal_Real; | |
8182 | end Is_Universal_Numeric_Type; | |
8183 | ||
f377c995 HK |
8184 | ------------------- |
8185 | -- Is_Value_Type -- | |
8186 | ------------------- | |
8187 | ||
8188 | function Is_Value_Type (T : Entity_Id) return Boolean is | |
8189 | begin | |
8190 | return VM_Target = CLI_Target | |
226e989e | 8191 | and then Nkind (T) in N_Has_Chars |
f377c995 HK |
8192 | and then Chars (T) /= No_Name |
8193 | and then Get_Name_String (Chars (T)) = "valuetype"; | |
8194 | end Is_Value_Type; | |
8195 | ||
001c7783 AC |
8196 | --------------------- |
8197 | -- Is_VMS_Operator -- | |
8198 | --------------------- | |
8199 | ||
8200 | function Is_VMS_Operator (Op : Entity_Id) return Boolean is | |
8201 | begin | |
e2cc5258 AC |
8202 | -- The VMS operators are declared in a child of System that is loaded |
8203 | -- through pragma Extend_System. In some rare cases a program is run | |
8204 | -- with this extension but without indicating that the target is VMS. | |
8205 | ||
001c7783 AC |
8206 | return Ekind (Op) = E_Function |
8207 | and then Is_Intrinsic_Subprogram (Op) | |
bb481772 AC |
8208 | and then |
8209 | ((Present_System_Aux | |
8210 | and then Scope (Op) = System_Aux_Id) | |
8211 | or else | |
8212 | (True_VMS_Target | |
9a0ddeee | 8213 | and then Scope (Scope (Op)) = RTU_Entity (System))); |
001c7783 AC |
8214 | end Is_VMS_Operator; |
8215 | ||
226e989e | 8216 | ----------------- |
996ae0b0 RK |
8217 | -- Is_Variable -- |
8218 | ----------------- | |
8219 | ||
62be5d0a JM |
8220 | function Is_Variable |
8221 | (N : Node_Id; | |
8222 | Use_Original_Node : Boolean := True) return Boolean | |
8223 | is | |
8224 | Orig_Node : Node_Id; | |
996ae0b0 RK |
8225 | |
8226 | function In_Protected_Function (E : Entity_Id) return Boolean; | |
e2cc5258 AC |
8227 | -- Within a protected function, the private components of the enclosing |
8228 | -- protected type are constants. A function nested within a (protected) | |
8229 | -- procedure is not itself protected. | |
996ae0b0 RK |
8230 | |
8231 | function Is_Variable_Prefix (P : Node_Id) return Boolean; | |
e2cc5258 AC |
8232 | -- Prefixes can involve implicit dereferences, in which case we must |
8233 | -- test for the case of a reference of a constant access type, which can | |
8234 | -- can never be a variable. | |
996ae0b0 | 8235 | |
fbf5a39b AC |
8236 | --------------------------- |
8237 | -- In_Protected_Function -- | |
8238 | --------------------------- | |
8239 | ||
996ae0b0 RK |
8240 | function In_Protected_Function (E : Entity_Id) return Boolean is |
8241 | Prot : constant Entity_Id := Scope (E); | |
8242 | S : Entity_Id; | |
8243 | ||
8244 | begin | |
8245 | if not Is_Protected_Type (Prot) then | |
8246 | return False; | |
8247 | else | |
8248 | S := Current_Scope; | |
996ae0b0 | 8249 | while Present (S) and then S /= Prot loop |
e2cc5258 | 8250 | if Ekind (S) = E_Function and then Scope (S) = Prot then |
996ae0b0 RK |
8251 | return True; |
8252 | end if; | |
8253 | ||
8254 | S := Scope (S); | |
8255 | end loop; | |
8256 | ||
8257 | return False; | |
8258 | end if; | |
8259 | end In_Protected_Function; | |
8260 | ||
fbf5a39b AC |
8261 | ------------------------ |
8262 | -- Is_Variable_Prefix -- | |
8263 | ------------------------ | |
8264 | ||
996ae0b0 RK |
8265 | function Is_Variable_Prefix (P : Node_Id) return Boolean is |
8266 | begin | |
8267 | if Is_Access_Type (Etype (P)) then | |
8268 | return not Is_Access_Constant (Root_Type (Etype (P))); | |
82c80734 RD |
8269 | |
8270 | -- For the case of an indexed component whose prefix has a packed | |
8271 | -- array type, the prefix has been rewritten into a type conversion. | |
8272 | -- Determine variable-ness from the converted expression. | |
8273 | ||
8274 | elsif Nkind (P) = N_Type_Conversion | |
8275 | and then not Comes_From_Source (P) | |
8276 | and then Is_Array_Type (Etype (P)) | |
8277 | and then Is_Packed (Etype (P)) | |
8278 | then | |
8279 | return Is_Variable (Expression (P)); | |
8280 | ||
996ae0b0 RK |
8281 | else |
8282 | return Is_Variable (P); | |
8283 | end if; | |
8284 | end Is_Variable_Prefix; | |
8285 | ||
8286 | -- Start of processing for Is_Variable | |
8287 | ||
8288 | begin | |
62be5d0a JM |
8289 | -- Check if we perform the test on the original node since this may be a |
8290 | -- test of syntactic categories which must not be disturbed by whatever | |
8291 | -- rewriting might have occurred. For example, an aggregate, which is | |
8292 | -- certainly NOT a variable, could be turned into a variable by | |
8293 | -- expansion. | |
8294 | ||
8295 | if Use_Original_Node then | |
8296 | Orig_Node := Original_Node (N); | |
8297 | else | |
8298 | Orig_Node := N; | |
8299 | end if; | |
8300 | ||
996ae0b0 RK |
8301 | -- Definitely OK if Assignment_OK is set. Since this is something that |
8302 | -- only gets set for expanded nodes, the test is on N, not Orig_Node. | |
8303 | ||
8304 | if Nkind (N) in N_Subexpr and then Assignment_OK (N) then | |
8305 | return True; | |
8306 | ||
e2cc5258 AC |
8307 | -- Normally we go to the original node, but there is one exception where |
8308 | -- we use the rewritten node, namely when it is an explicit dereference. | |
8309 | -- The generated code may rewrite a prefix which is an access type with | |
8310 | -- an explicit dereference. The dereference is a variable, even though | |
8311 | -- the original node may not be (since it could be a constant of the | |
8312 | -- access type). | |
996ae0b0 | 8313 | |
e2cc5258 AC |
8314 | -- In Ada 2005 we have a further case to consider: the prefix may be a |
8315 | -- function call given in prefix notation. The original node appears to | |
8316 | -- be a selected component, but we need to examine the call. | |
1b6c95c4 | 8317 | |
996ae0b0 RK |
8318 | elsif Nkind (N) = N_Explicit_Dereference |
8319 | and then Nkind (Orig_Node) /= N_Explicit_Dereference | |
f377c995 | 8320 | and then Present (Etype (Orig_Node)) |
996ae0b0 RK |
8321 | and then Is_Access_Type (Etype (Orig_Node)) |
8322 | then | |
ff69f95a RD |
8323 | -- Note that if the prefix is an explicit dereference that does not |
8324 | -- come from source, we must check for a rewritten function call in | |
8325 | -- prefixed notation before other forms of rewriting, to prevent a | |
8326 | -- compiler crash. | |
8327 | ||
2db15b1d AC |
8328 | return |
8329 | (Nkind (Orig_Node) = N_Function_Call | |
8330 | and then not Is_Access_Constant (Etype (Prefix (N)))) | |
1b6c95c4 | 8331 | or else |
2db15b1d | 8332 | Is_Variable_Prefix (Original_Node (Prefix (N))); |
996ae0b0 | 8333 | |
482a63fb ES |
8334 | -- A function call is never a variable |
8335 | ||
8336 | elsif Nkind (N) = N_Function_Call then | |
8337 | return False; | |
8338 | ||
996ae0b0 RK |
8339 | -- All remaining checks use the original node |
8340 | ||
1b6c95c4 RD |
8341 | elsif Is_Entity_Name (Orig_Node) |
8342 | and then Present (Entity (Orig_Node)) | |
8343 | then | |
996ae0b0 RK |
8344 | declare |
8345 | E : constant Entity_Id := Entity (Orig_Node); | |
8346 | K : constant Entity_Kind := Ekind (E); | |
8347 | ||
8348 | begin | |
8349 | return (K = E_Variable | |
8350 | and then Nkind (Parent (E)) /= N_Exception_Handler) | |
8351 | or else (K = E_Component | |
8352 | and then not In_Protected_Function (E)) | |
8353 | or else K = E_Out_Parameter | |
8354 | or else K = E_In_Out_Parameter | |
8355 | or else K = E_Generic_In_Out_Parameter | |
8356 | ||
8357 | -- Current instance of type: | |
8358 | ||
8359 | or else (Is_Type (E) and then In_Open_Scopes (E)) | |
8360 | or else (Is_Incomplete_Or_Private_Type (E) | |
8361 | and then In_Open_Scopes (Full_View (E))); | |
8362 | end; | |
8363 | ||
8364 | else | |
8365 | case Nkind (Orig_Node) is | |
8366 | when N_Indexed_Component | N_Slice => | |
8367 | return Is_Variable_Prefix (Prefix (Orig_Node)); | |
8368 | ||
8369 | when N_Selected_Component => | |
8370 | return Is_Variable_Prefix (Prefix (Orig_Node)) | |
8371 | and then Is_Variable (Selector_Name (Orig_Node)); | |
8372 | ||
fbf5a39b AC |
8373 | -- For an explicit dereference, the type of the prefix cannot |
8374 | -- be an access to constant or an access to subprogram. | |
996ae0b0 RK |
8375 | |
8376 | when N_Explicit_Dereference => | |
fbf5a39b AC |
8377 | declare |
8378 | Typ : constant Entity_Id := Etype (Prefix (Orig_Node)); | |
fbf5a39b AC |
8379 | begin |
8380 | return Is_Access_Type (Typ) | |
8381 | and then not Is_Access_Constant (Root_Type (Typ)) | |
8382 | and then Ekind (Typ) /= E_Access_Subprogram_Type; | |
8383 | end; | |
996ae0b0 RK |
8384 | |
8385 | -- The type conversion is the case where we do not deal with the | |
8386 | -- context dependent special case of an actual parameter. Thus | |
8387 | -- the type conversion is only considered a variable for the | |
8388 | -- purposes of this routine if the target type is tagged. However, | |
8389 | -- a type conversion is considered to be a variable if it does not | |
8390 | -- come from source (this deals for example with the conversions | |
8391 | -- of expressions to their actual subtypes). | |
8392 | ||
8393 | when N_Type_Conversion => | |
8394 | return Is_Variable (Expression (Orig_Node)) | |
8395 | and then | |
8396 | (not Comes_From_Source (Orig_Node) | |
8397 | or else | |
8398 | (Is_Tagged_Type (Etype (Subtype_Mark (Orig_Node))) | |
8399 | and then | |
8400 | Is_Tagged_Type (Etype (Expression (Orig_Node))))); | |
8401 | ||
8402 | -- GNAT allows an unchecked type conversion as a variable. This | |
8403 | -- only affects the generation of internal expanded code, since | |
8404 | -- calls to instantiations of Unchecked_Conversion are never | |
8405 | -- considered variables (since they are function calls). | |
8406 | -- This is also true for expression actions. | |
8407 | ||
8408 | when N_Unchecked_Type_Conversion => | |
8409 | return Is_Variable (Expression (Orig_Node)); | |
8410 | ||
8411 | when others => | |
8412 | return False; | |
8413 | end case; | |
8414 | end if; | |
8415 | end Is_Variable; | |
8416 | ||
fd0d899b AC |
8417 | --------------------------- |
8418 | -- Is_Visibly_Controlled -- | |
8419 | --------------------------- | |
8420 | ||
8421 | function Is_Visibly_Controlled (T : Entity_Id) return Boolean is | |
8422 | Root : constant Entity_Id := Root_Type (T); | |
8423 | begin | |
8424 | return Chars (Scope (Root)) = Name_Finalization | |
8425 | and then Chars (Scope (Scope (Root))) = Name_Ada | |
8426 | and then Scope (Scope (Scope (Root))) = Standard_Standard; | |
8427 | end Is_Visibly_Controlled; | |
8428 | ||
996ae0b0 RK |
8429 | ------------------------ |
8430 | -- Is_Volatile_Object -- | |
8431 | ------------------------ | |
8432 | ||
8433 | function Is_Volatile_Object (N : Node_Id) return Boolean is | |
8434 | ||
8435 | function Object_Has_Volatile_Components (N : Node_Id) return Boolean; | |
8436 | -- Determines if given object has volatile components | |
8437 | ||
8438 | function Is_Volatile_Prefix (N : Node_Id) return Boolean; | |
130c236a | 8439 | -- If prefix is an implicit dereference, examine designated type |
996ae0b0 | 8440 | |
fbf5a39b AC |
8441 | ------------------------ |
8442 | -- Is_Volatile_Prefix -- | |
8443 | ------------------------ | |
8444 | ||
996ae0b0 | 8445 | function Is_Volatile_Prefix (N : Node_Id) return Boolean is |
fbf5a39b AC |
8446 | Typ : constant Entity_Id := Etype (N); |
8447 | ||
996ae0b0 | 8448 | begin |
fbf5a39b AC |
8449 | if Is_Access_Type (Typ) then |
8450 | declare | |
8451 | Dtyp : constant Entity_Id := Designated_Type (Typ); | |
8452 | ||
8453 | begin | |
8454 | return Is_Volatile (Dtyp) | |
8455 | or else Has_Volatile_Components (Dtyp); | |
8456 | end; | |
8457 | ||
996ae0b0 RK |
8458 | else |
8459 | return Object_Has_Volatile_Components (N); | |
8460 | end if; | |
8461 | end Is_Volatile_Prefix; | |
8462 | ||
fbf5a39b AC |
8463 | ------------------------------------ |
8464 | -- Object_Has_Volatile_Components -- | |
8465 | ------------------------------------ | |
8466 | ||
996ae0b0 | 8467 | function Object_Has_Volatile_Components (N : Node_Id) return Boolean is |
fbf5a39b AC |
8468 | Typ : constant Entity_Id := Etype (N); |
8469 | ||
996ae0b0 | 8470 | begin |
fbf5a39b AC |
8471 | if Is_Volatile (Typ) |
8472 | or else Has_Volatile_Components (Typ) | |
996ae0b0 RK |
8473 | then |
8474 | return True; | |
8475 | ||
8476 | elsif Is_Entity_Name (N) | |
8477 | and then (Has_Volatile_Components (Entity (N)) | |
8478 | or else Is_Volatile (Entity (N))) | |
8479 | then | |
8480 | return True; | |
8481 | ||
9b0986f8 RD |
8482 | elsif Nkind (N) = N_Indexed_Component |
8483 | or else Nkind (N) = N_Selected_Component | |
8484 | then | |
8485 | return Is_Volatile_Prefix (Prefix (N)); | |
8486 | ||
8487 | else | |
8488 | return False; | |
8489 | end if; | |
8490 | end Object_Has_Volatile_Components; | |
8491 | ||
8492 | -- Start of processing for Is_Volatile_Object | |
8493 | ||
8494 | begin | |
8495 | if Is_Volatile (Etype (N)) | |
8496 | or else (Is_Entity_Name (N) and then Is_Volatile (Entity (N))) | |
8497 | then | |
8498 | return True; | |
8499 | ||
8500 | elsif Nkind (N) = N_Indexed_Component | |
8501 | or else Nkind (N) = N_Selected_Component | |
8502 | then | |
8503 | return Is_Volatile_Prefix (Prefix (N)); | |
8504 | ||
8505 | else | |
8506 | return False; | |
8507 | end if; | |
8508 | end Is_Volatile_Object; | |
8509 | ||
9fd9d2be AC |
8510 | --------------------------- |
8511 | -- Itype_Has_Declaration -- | |
8512 | --------------------------- | |
8513 | ||
8514 | function Itype_Has_Declaration (Id : Entity_Id) return Boolean is | |
8515 | begin | |
8516 | pragma Assert (Is_Itype (Id)); | |
8517 | return Present (Parent (Id)) | |
c54796e0 AC |
8518 | and then Nkind_In (Parent (Id), N_Full_Type_Declaration, |
8519 | N_Subtype_Declaration) | |
9fd9d2be AC |
8520 | and then Defining_Entity (Parent (Id)) = Id; |
8521 | end Itype_Has_Declaration; | |
8522 | ||
9b0986f8 RD |
8523 | ------------------------- |
8524 | -- Kill_Current_Values -- | |
8525 | ------------------------- | |
8526 | ||
67ce0d7e RD |
8527 | procedure Kill_Current_Values |
8528 | (Ent : Entity_Id; | |
8529 | Last_Assignment_Only : Boolean := False) | |
8530 | is | |
9b0986f8 | 8531 | begin |
cff7cd9b AC |
8532 | -- ??? do we have to worry about clearing cached checks? |
8533 | ||
67ce0d7e RD |
8534 | if Is_Assignable (Ent) then |
8535 | Set_Last_Assignment (Ent, Empty); | |
8536 | end if; | |
8537 | ||
cff7cd9b AC |
8538 | if Is_Object (Ent) then |
8539 | if not Last_Assignment_Only then | |
8540 | Kill_Checks (Ent); | |
8541 | Set_Current_Value (Ent, Empty); | |
9b0986f8 | 8542 | |
cff7cd9b AC |
8543 | if not Can_Never_Be_Null (Ent) then |
8544 | Set_Is_Known_Non_Null (Ent, False); | |
8545 | end if; | |
8546 | ||
8547 | Set_Is_Known_Null (Ent, False); | |
9b0986f8 | 8548 | |
cff7cd9b AC |
8549 | -- Reset Is_Known_Valid unless type is always valid, or if we have |
8550 | -- a loop parameter (loop parameters are always valid, since their | |
8551 | -- bounds are defined by the bounds given in the loop header). | |
8552 | ||
8553 | if not Is_Known_Valid (Etype (Ent)) | |
8554 | and then Ekind (Ent) /= E_Loop_Parameter | |
8555 | then | |
8556 | Set_Is_Known_Valid (Ent, False); | |
8557 | end if; | |
8558 | end if; | |
9b0986f8 RD |
8559 | end if; |
8560 | end Kill_Current_Values; | |
8561 | ||
67ce0d7e | 8562 | procedure Kill_Current_Values (Last_Assignment_Only : Boolean := False) is |
9b0986f8 RD |
8563 | S : Entity_Id; |
8564 | ||
8565 | procedure Kill_Current_Values_For_Entity_Chain (E : Entity_Id); | |
8566 | -- Clear current value for entity E and all entities chained to E | |
8567 | ||
8568 | ------------------------------------------ | |
8569 | -- Kill_Current_Values_For_Entity_Chain -- | |
8570 | ------------------------------------------ | |
8571 | ||
8572 | procedure Kill_Current_Values_For_Entity_Chain (E : Entity_Id) is | |
8573 | Ent : Entity_Id; | |
8574 | begin | |
8575 | Ent := E; | |
8576 | while Present (Ent) loop | |
67ce0d7e | 8577 | Kill_Current_Values (Ent, Last_Assignment_Only); |
9b0986f8 RD |
8578 | Next_Entity (Ent); |
8579 | end loop; | |
8580 | end Kill_Current_Values_For_Entity_Chain; | |
8581 | ||
8582 | -- Start of processing for Kill_Current_Values | |
8583 | ||
8584 | begin | |
8585 | -- Kill all saved checks, a special case of killing saved values | |
8586 | ||
67ce0d7e RD |
8587 | if not Last_Assignment_Only then |
8588 | Kill_All_Checks; | |
8589 | end if; | |
9b0986f8 RD |
8590 | |
8591 | -- Loop through relevant scopes, which includes the current scope and | |
8592 | -- any parent scopes if the current scope is a block or a package. | |
8593 | ||
8594 | S := Current_Scope; | |
8595 | Scope_Loop : loop | |
8596 | ||
8597 | -- Clear current values of all entities in current scope | |
8598 | ||
8599 | Kill_Current_Values_For_Entity_Chain (First_Entity (S)); | |
8600 | ||
8601 | -- If scope is a package, also clear current values of all | |
8602 | -- private entities in the scope. | |
8603 | ||
b9b2405f ST |
8604 | if Is_Package_Or_Generic_Package (S) |
8605 | or else Is_Concurrent_Type (S) | |
9b0986f8 RD |
8606 | then |
8607 | Kill_Current_Values_For_Entity_Chain (First_Private_Entity (S)); | |
8608 | end if; | |
8609 | ||
8610 | -- If this is a not a subprogram, deal with parents | |
8611 | ||
8612 | if not Is_Subprogram (S) then | |
8613 | S := Scope (S); | |
8614 | exit Scope_Loop when S = Standard_Standard; | |
8615 | else | |
8616 | exit Scope_Loop; | |
8617 | end if; | |
8618 | end loop Scope_Loop; | |
8619 | end Kill_Current_Values; | |
8620 | ||
8621 | -------------------------- | |
8622 | -- Kill_Size_Check_Code -- | |
8623 | -------------------------- | |
8624 | ||
8625 | procedure Kill_Size_Check_Code (E : Entity_Id) is | |
8626 | begin | |
8627 | if (Ekind (E) = E_Constant or else Ekind (E) = E_Variable) | |
8628 | and then Present (Size_Check_Code (E)) | |
8629 | then | |
8630 | Remove (Size_Check_Code (E)); | |
8631 | Set_Size_Check_Code (E, Empty); | |
8632 | end if; | |
8633 | end Kill_Size_Check_Code; | |
8634 | ||
8635 | -------------------------- | |
8636 | -- Known_To_Be_Assigned -- | |
8637 | -------------------------- | |
8638 | ||
8639 | function Known_To_Be_Assigned (N : Node_Id) return Boolean is | |
8640 | P : constant Node_Id := Parent (N); | |
8641 | ||
8642 | begin | |
8643 | case Nkind (P) is | |
8644 | ||
8645 | -- Test left side of assignment | |
8646 | ||
8647 | when N_Assignment_Statement => | |
8648 | return N = Name (P); | |
8649 | ||
b0159fbe | 8650 | -- Function call arguments are never lvalues |
9b0986f8 RD |
8651 | |
8652 | when N_Function_Call => | |
8653 | return False; | |
8654 | ||
8655 | -- Positional parameter for procedure or accept call | |
8656 | ||
8657 | when N_Procedure_Call_Statement | | |
8658 | N_Accept_Statement | |
8659 | => | |
8660 | declare | |
8661 | Proc : Entity_Id; | |
8662 | Form : Entity_Id; | |
8663 | Act : Node_Id; | |
8664 | ||
8665 | begin | |
8666 | Proc := Get_Subprogram_Entity (P); | |
8667 | ||
8668 | if No (Proc) then | |
8669 | return False; | |
8670 | end if; | |
8671 | ||
8672 | -- If we are not a list member, something is strange, so | |
8673 | -- be conservative and return False. | |
8674 | ||
8675 | if not Is_List_Member (N) then | |
8676 | return False; | |
8677 | end if; | |
8678 | ||
8679 | -- We are going to find the right formal by stepping forward | |
8680 | -- through the formals, as we step backwards in the actuals. | |
8681 | ||
8682 | Form := First_Formal (Proc); | |
8683 | Act := N; | |
8684 | loop | |
8685 | -- If no formal, something is weird, so be conservative | |
8686 | -- and return False. | |
8687 | ||
8688 | if No (Form) then | |
8689 | return False; | |
8690 | end if; | |
8691 | ||
8692 | Prev (Act); | |
8693 | exit when No (Act); | |
8694 | Next_Formal (Form); | |
8695 | end loop; | |
8696 | ||
8697 | return Ekind (Form) /= E_In_Parameter; | |
8698 | end; | |
8699 | ||
8700 | -- Named parameter for procedure or accept call | |
8701 | ||
8702 | when N_Parameter_Association => | |
8703 | declare | |
8704 | Proc : Entity_Id; | |
8705 | Form : Entity_Id; | |
8706 | ||
8707 | begin | |
8708 | Proc := Get_Subprogram_Entity (Parent (P)); | |
8709 | ||
8710 | if No (Proc) then | |
8711 | return False; | |
8712 | end if; | |
8713 | ||
8714 | -- Loop through formals to find the one that matches | |
8715 | ||
8716 | Form := First_Formal (Proc); | |
8717 | loop | |
8718 | -- If no matching formal, that's peculiar, some kind of | |
8719 | -- previous error, so return False to be conservative. | |
8720 | ||
8721 | if No (Form) then | |
8722 | return False; | |
8723 | end if; | |
8724 | ||
8725 | -- Else test for match | |
8726 | ||
8727 | if Chars (Form) = Chars (Selector_Name (P)) then | |
8728 | return Ekind (Form) /= E_In_Parameter; | |
8729 | end if; | |
8730 | ||
8731 | Next_Formal (Form); | |
8732 | end loop; | |
8733 | end; | |
8734 | ||
8735 | -- Test for appearing in a conversion that itself appears | |
b0159fbe | 8736 | -- in an lvalue context, since this should be an lvalue. |
9b0986f8 RD |
8737 | |
8738 | when N_Type_Conversion => | |
8739 | return Known_To_Be_Assigned (P); | |
8740 | ||
f3d57416 | 8741 | -- All other references are definitely not known to be modifications |
9b0986f8 RD |
8742 | |
8743 | when others => | |
8744 | return False; | |
8745 | ||
8746 | end case; | |
8747 | end Known_To_Be_Assigned; | |
8748 | ||
2933b16c RD |
8749 | --------------------------- |
8750 | -- Last_Source_Statement -- | |
8751 | --------------------------- | |
1d801f21 | 8752 | |
2933b16c | 8753 | function Last_Source_Statement (HSS : Node_Id) return Node_Id is |
05dbd302 AC |
8754 | N : Node_Id; |
8755 | ||
1d801f21 | 8756 | begin |
2933b16c | 8757 | N := Last (Statements (HSS)); |
1d801f21 AC |
8758 | while Present (N) loop |
8759 | exit when Comes_From_Source (N); | |
2933b16c | 8760 | Prev (N); |
1d801f21 AC |
8761 | end loop; |
8762 | ||
8763 | return N; | |
2933b16c | 8764 | end Last_Source_Statement; |
1d801f21 | 8765 | |
780d052e RD |
8766 | ---------------------------------- |
8767 | -- Matching_Static_Array_Bounds -- | |
8768 | ---------------------------------- | |
8769 | ||
8770 | function Matching_Static_Array_Bounds | |
8771 | (L_Typ : Node_Id; | |
8772 | R_Typ : Node_Id) return Boolean | |
8773 | is | |
8774 | L_Ndims : constant Nat := Number_Dimensions (L_Typ); | |
8775 | R_Ndims : constant Nat := Number_Dimensions (R_Typ); | |
8776 | ||
8777 | L_Index : Node_Id; | |
8778 | R_Index : Node_Id; | |
8779 | L_Low : Node_Id; | |
8780 | L_High : Node_Id; | |
bd434b3f | 8781 | L_Len : Uint; |
780d052e RD |
8782 | R_Low : Node_Id; |
8783 | R_High : Node_Id; | |
bd434b3f | 8784 | R_Len : Uint; |
780d052e RD |
8785 | |
8786 | begin | |
8787 | if L_Ndims /= R_Ndims then | |
8788 | return False; | |
8789 | end if; | |
8790 | ||
8791 | -- Unconstrained types do not have static bounds | |
8792 | ||
8793 | if not Is_Constrained (L_Typ) or else not Is_Constrained (R_Typ) then | |
8794 | return False; | |
8795 | end if; | |
8796 | ||
bd434b3f YM |
8797 | -- First treat specially the first dimension, as the lower bound and |
8798 | -- length of string literals are not stored like those of arrays. | |
780d052e | 8799 | |
bd434b3f YM |
8800 | if Ekind (L_Typ) = E_String_Literal_Subtype then |
8801 | L_Low := String_Literal_Low_Bound (L_Typ); | |
8802 | L_Len := String_Literal_Length (L_Typ); | |
8803 | else | |
8804 | L_Index := First_Index (L_Typ); | |
8805 | Get_Index_Bounds (L_Index, L_Low, L_High); | |
8806 | ||
8807 | if Is_OK_Static_Expression (L_Low) | |
8808 | and then Is_OK_Static_Expression (L_High) | |
8809 | then | |
8810 | if Expr_Value (L_High) < Expr_Value (L_Low) then | |
8811 | L_Len := Uint_0; | |
8812 | else | |
8813 | L_Len := (Expr_Value (L_High) - Expr_Value (L_Low)) + 1; | |
8814 | end if; | |
8815 | else | |
8816 | return False; | |
8817 | end if; | |
8818 | end if; | |
fe5d3068 | 8819 | |
bd434b3f YM |
8820 | if Ekind (R_Typ) = E_String_Literal_Subtype then |
8821 | R_Low := String_Literal_Low_Bound (R_Typ); | |
8822 | R_Len := String_Literal_Length (R_Typ); | |
8823 | else | |
8824 | R_Index := First_Index (R_Typ); | |
8825 | Get_Index_Bounds (R_Index, R_Low, R_High); | |
8826 | ||
8827 | if Is_OK_Static_Expression (R_Low) | |
8828 | and then Is_OK_Static_Expression (R_High) | |
8829 | then | |
8830 | if Expr_Value (R_High) < Expr_Value (R_Low) then | |
8831 | R_Len := Uint_0; | |
8832 | else | |
8833 | R_Len := (Expr_Value (R_High) - Expr_Value (R_Low)) + 1; | |
8834 | end if; | |
8835 | else | |
8836 | return False; | |
8837 | end if; | |
8838 | end if; | |
8839 | ||
8840 | if Is_OK_Static_Expression (L_Low) | |
8841 | and then Is_OK_Static_Expression (R_Low) | |
8842 | and then Expr_Value (L_Low) = Expr_Value (R_Low) | |
8843 | and then L_Len = R_Len | |
8844 | then | |
8845 | null; | |
8846 | else | |
fe5d3068 YM |
8847 | return False; |
8848 | end if; | |
8849 | ||
bd434b3f YM |
8850 | -- Then treat all other dimensions |
8851 | ||
8852 | for Indx in 2 .. L_Ndims loop | |
8853 | Next (L_Index); | |
8854 | Next (R_Index); | |
8855 | ||
780d052e RD |
8856 | Get_Index_Bounds (L_Index, L_Low, L_High); |
8857 | Get_Index_Bounds (R_Index, R_Low, R_High); | |
8858 | ||
8859 | if Is_OK_Static_Expression (L_Low) | |
8860 | and then Is_OK_Static_Expression (L_High) | |
8861 | and then Is_OK_Static_Expression (R_Low) | |
8862 | and then Is_OK_Static_Expression (R_High) | |
8863 | and then Expr_Value (L_Low) = Expr_Value (R_Low) | |
8864 | and then Expr_Value (L_High) = Expr_Value (R_High) | |
8865 | then | |
bd434b3f | 8866 | null; |
780d052e RD |
8867 | else |
8868 | return False; | |
8869 | end if; | |
8870 | end loop; | |
8871 | ||
8872 | -- If we fall through the loop, all indexes matched | |
8873 | ||
8874 | return True; | |
8875 | end Matching_Static_Array_Bounds; | |
8876 | ||
9b0986f8 RD |
8877 | ------------------- |
8878 | -- May_Be_Lvalue -- | |
8879 | ------------------- | |
8880 | ||
8881 | function May_Be_Lvalue (N : Node_Id) return Boolean is | |
8882 | P : constant Node_Id := Parent (N); | |
8883 | ||
8884 | begin | |
8885 | case Nkind (P) is | |
8886 | ||
8887 | -- Test left side of assignment | |
8888 | ||
8889 | when N_Assignment_Statement => | |
8890 | return N = Name (P); | |
8891 | ||
8a912a6e AC |
8892 | -- Test prefix of component or attribute. Note that the prefix of an |
8893 | -- explicit or implicit dereference cannot be an l-value. | |
9b0986f8 | 8894 | |
f377c995 HK |
8895 | when N_Attribute_Reference => |
8896 | return N = Prefix (P) | |
1b6c95c4 | 8897 | and then Name_Implies_Lvalue_Prefix (Attribute_Name (P)); |
f377c995 | 8898 | |
b0159fbe AC |
8899 | -- For an expanded name, the name is an lvalue if the expanded name |
8900 | -- is an lvalue, but the prefix is never an lvalue, since it is just | |
3b4ebfc3 RD |
8901 | -- the scope where the name is found. |
8902 | ||
8903 | when N_Expanded_Name => | |
8904 | if N = Prefix (P) then | |
8905 | return May_Be_Lvalue (P); | |
8906 | else | |
8907 | return False; | |
8908 | end if; | |
8909 | ||
b0159fbe AC |
8910 | -- For a selected component A.B, A is certainly an lvalue if A.B is. |
8911 | -- B is a little interesting, if we have A.B := 3, there is some | |
8912 | -- discussion as to whether B is an lvalue or not, we choose to say | |
8913 | -- it is. Note however that A is not an lvalue if it is of an access | |
8914 | -- type since this is an implicit dereference. | |
3b4ebfc3 RD |
8915 | |
8916 | when N_Selected_Component => | |
8917 | if N = Prefix (P) | |
8918 | and then Present (Etype (N)) | |
8919 | and then Is_Access_Type (Etype (N)) | |
8920 | then | |
8921 | return False; | |
8a912a6e | 8922 | else |
3b4ebfc3 | 8923 | return May_Be_Lvalue (P); |
8a912a6e AC |
8924 | end if; |
8925 | ||
3b4ebfc3 | 8926 | -- For an indexed component or slice, the index or slice bounds is |
b0159fbe AC |
8927 | -- never an lvalue. The prefix is an lvalue if the indexed component |
8928 | -- or slice is an lvalue, except if it is an access type, where we | |
3b4ebfc3 RD |
8929 | -- have an implicit dereference. |
8930 | ||
8931 | when N_Indexed_Component => | |
8932 | if N /= Prefix (P) | |
8933 | or else (Present (Etype (N)) and then Is_Access_Type (Etype (N))) | |
8934 | then | |
8935 | return False; | |
8936 | else | |
8937 | return May_Be_Lvalue (P); | |
8938 | end if; | |
8939 | ||
b0159fbe | 8940 | -- Prefix of a reference is an lvalue if the reference is an lvalue |
3b4ebfc3 | 8941 | |
8a912a6e | 8942 | when N_Reference => |
3b4ebfc3 RD |
8943 | return May_Be_Lvalue (P); |
8944 | ||
b0159fbe | 8945 | -- Prefix of explicit dereference is never an lvalue |
8a912a6e AC |
8946 | |
8947 | when N_Explicit_Dereference => | |
8948 | return False; | |
9b0986f8 | 8949 | |
229db351 AC |
8950 | -- Positional parameter for subprogram, entry, or accept call. |
8951 | -- In older versions of Ada function call arguments are never | |
66150d01 | 8952 | -- lvalues. In Ada 2012 functions can have in-out parameters. |
996ae0b0 | 8953 | |
229db351 AC |
8954 | when N_Function_Call | |
8955 | N_Procedure_Call_Statement | | |
f377c995 | 8956 | N_Entry_Call_Statement | |
9b0986f8 | 8957 | N_Accept_Statement |
f377c995 | 8958 | => |
229db351 AC |
8959 | if Nkind (P) = N_Function_Call |
8960 | and then Ada_Version < Ada_2012 | |
8961 | then | |
8962 | return False; | |
8963 | end if; | |
8964 | ||
8965 | -- The following mechanism is clumsy and fragile. A single | |
8966 | -- flag set in Resolve_Actuals would be preferable ??? | |
8967 | ||
9b0986f8 RD |
8968 | declare |
8969 | Proc : Entity_Id; | |
8970 | Form : Entity_Id; | |
8971 | Act : Node_Id; | |
996ae0b0 | 8972 | |
9b0986f8 RD |
8973 | begin |
8974 | Proc := Get_Subprogram_Entity (P); | |
996ae0b0 | 8975 | |
9b0986f8 RD |
8976 | if No (Proc) then |
8977 | return True; | |
8978 | end if; | |
996ae0b0 | 8979 | |
9b0986f8 RD |
8980 | -- If we are not a list member, something is strange, so |
8981 | -- be conservative and return True. | |
fbf5a39b | 8982 | |
9b0986f8 RD |
8983 | if not Is_List_Member (N) then |
8984 | return True; | |
8985 | end if; | |
b8dc622e | 8986 | |
9b0986f8 RD |
8987 | -- We are going to find the right formal by stepping forward |
8988 | -- through the formals, as we step backwards in the actuals. | |
b8dc622e | 8989 | |
9b0986f8 RD |
8990 | Form := First_Formal (Proc); |
8991 | Act := N; | |
8992 | loop | |
8993 | -- If no formal, something is weird, so be conservative | |
8994 | -- and return True. | |
b8dc622e | 8995 | |
9b0986f8 RD |
8996 | if No (Form) then |
8997 | return True; | |
8998 | end if; | |
fbf5a39b | 8999 | |
9b0986f8 RD |
9000 | Prev (Act); |
9001 | exit when No (Act); | |
9002 | Next_Formal (Form); | |
9003 | end loop; | |
fbf5a39b | 9004 | |
9b0986f8 RD |
9005 | return Ekind (Form) /= E_In_Parameter; |
9006 | end; | |
fbf5a39b | 9007 | |
9b0986f8 | 9008 | -- Named parameter for procedure or accept call |
fbf5a39b | 9009 | |
9b0986f8 RD |
9010 | when N_Parameter_Association => |
9011 | declare | |
9012 | Proc : Entity_Id; | |
9013 | Form : Entity_Id; | |
fbf5a39b | 9014 | |
9b0986f8 RD |
9015 | begin |
9016 | Proc := Get_Subprogram_Entity (Parent (P)); | |
fbf5a39b | 9017 | |
9b0986f8 RD |
9018 | if No (Proc) then |
9019 | return True; | |
9020 | end if; | |
fbf5a39b | 9021 | |
9b0986f8 | 9022 | -- Loop through formals to find the one that matches |
fbf5a39b | 9023 | |
9b0986f8 RD |
9024 | Form := First_Formal (Proc); |
9025 | loop | |
9026 | -- If no matching formal, that's peculiar, some kind of | |
9027 | -- previous error, so return True to be conservative. | |
fbf5a39b | 9028 | |
9b0986f8 RD |
9029 | if No (Form) then |
9030 | return True; | |
9031 | end if; | |
fbf5a39b | 9032 | |
9b0986f8 | 9033 | -- Else test for match |
fbf5a39b | 9034 | |
9b0986f8 RD |
9035 | if Chars (Form) = Chars (Selector_Name (P)) then |
9036 | return Ekind (Form) /= E_In_Parameter; | |
9037 | end if; | |
fbf5a39b | 9038 | |
9b0986f8 RD |
9039 | Next_Formal (Form); |
9040 | end loop; | |
9041 | end; | |
fbf5a39b | 9042 | |
7f0e4cdb | 9043 | -- Test for appearing in a conversion that itself appears in an |
b0159fbe | 9044 | -- lvalue context, since this should be an lvalue. |
fbf5a39b | 9045 | |
9b0986f8 RD |
9046 | when N_Type_Conversion => |
9047 | return May_Be_Lvalue (P); | |
fbf5a39b | 9048 | |
f3d57416 | 9049 | -- Test for appearance in object renaming declaration |
996ae0b0 | 9050 | |
9b0986f8 RD |
9051 | when N_Object_Renaming_Declaration => |
9052 | return True; | |
9053 | ||
b0159fbe | 9054 | -- All other references are definitely not lvalues |
9b0986f8 RD |
9055 | |
9056 | when others => | |
9057 | return False; | |
9058 | ||
9059 | end case; | |
9060 | end May_Be_Lvalue; | |
996ae0b0 | 9061 | |
1b6c95c4 RD |
9062 | ----------------------- |
9063 | -- Mark_Coextensions -- | |
9064 | ----------------------- | |
9065 | ||
9066 | procedure Mark_Coextensions (Context_Nod : Node_Id; Root_Nod : Node_Id) is | |
9d77af56 RD |
9067 | Is_Dynamic : Boolean; |
9068 | -- Indicates whether the context causes nested coextensions to be | |
9069 | -- dynamic or static | |
f377c995 | 9070 | |
f377c995 | 9071 | function Mark_Allocator (N : Node_Id) return Traverse_Result; |
1b6c95c4 | 9072 | -- Recognize an allocator node and label it as a dynamic coextension |
f377c995 HK |
9073 | |
9074 | -------------------- | |
9075 | -- Mark_Allocator -- | |
9076 | -------------------- | |
9077 | ||
9078 | function Mark_Allocator (N : Node_Id) return Traverse_Result is | |
9079 | begin | |
9080 | if Nkind (N) = N_Allocator then | |
1b6c95c4 RD |
9081 | if Is_Dynamic then |
9082 | Set_Is_Dynamic_Coextension (N); | |
e771c085 | 9083 | |
74853971 AC |
9084 | -- If the allocator expression is potentially dynamic, it may |
9085 | -- be expanded out of order and require dynamic allocation | |
9086 | -- anyway, so we treat the coextension itself as dynamic. | |
9087 | -- Potential optimization ??? | |
9088 | ||
9089 | elsif Nkind (Expression (N)) = N_Qualified_Expression | |
9090 | and then Nkind (Expression (Expression (N))) = N_Op_Concat | |
9091 | then | |
9092 | Set_Is_Dynamic_Coextension (N); | |
9093 | ||
1b6c95c4 RD |
9094 | else |
9095 | Set_Is_Static_Coextension (N); | |
9096 | end if; | |
f377c995 HK |
9097 | end if; |
9098 | ||
9099 | return OK; | |
9100 | end Mark_Allocator; | |
9101 | ||
9102 | procedure Mark_Allocators is new Traverse_Proc (Mark_Allocator); | |
9103 | ||
1b6c95c4 | 9104 | -- Start of processing Mark_Coextensions |
f377c995 HK |
9105 | |
9106 | begin | |
1b6c95c4 RD |
9107 | case Nkind (Context_Nod) is |
9108 | when N_Assignment_Statement | | |
9109 | N_Simple_Return_Statement => | |
9110 | Is_Dynamic := Nkind (Expression (Context_Nod)) = N_Allocator; | |
f377c995 | 9111 | |
1b6c95c4 RD |
9112 | when N_Object_Declaration => |
9113 | Is_Dynamic := Nkind (Root_Nod) = N_Allocator; | |
9114 | ||
9115 | -- This routine should not be called for constructs which may not | |
9116 | -- contain coextensions. | |
9117 | ||
9118 | when others => | |
9119 | raise Program_Error; | |
9120 | end case; | |
9121 | ||
9122 | Mark_Allocators (Root_Nod); | |
9123 | end Mark_Coextensions; | |
f377c995 | 9124 | |
9e87a68d ES |
9125 | ---------------------- |
9126 | -- Needs_One_Actual -- | |
9127 | ---------------------- | |
9128 | ||
9129 | function Needs_One_Actual (E : Entity_Id) return Boolean is | |
9130 | Formal : Entity_Id; | |
9131 | ||
9132 | begin | |
0791fbe9 | 9133 | if Ada_Version >= Ada_2005 |
9e87a68d ES |
9134 | and then Present (First_Formal (E)) |
9135 | then | |
9136 | Formal := Next_Formal (First_Formal (E)); | |
9137 | while Present (Formal) loop | |
9138 | if No (Default_Value (Formal)) then | |
9139 | return False; | |
9140 | end if; | |
9141 | ||
9142 | Next_Formal (Formal); | |
9143 | end loop; | |
9144 | ||
9145 | return True; | |
9146 | ||
9147 | else | |
9148 | return False; | |
9149 | end if; | |
9150 | end Needs_One_Actual; | |
9151 | ||
f3b01cd9 AC |
9152 | ------------------------ |
9153 | -- New_Copy_List_Tree -- | |
9154 | ------------------------ | |
9155 | ||
9156 | function New_Copy_List_Tree (List : List_Id) return List_Id is | |
9157 | NL : List_Id; | |
9158 | E : Node_Id; | |
9159 | ||
9160 | begin | |
9161 | if List = No_List then | |
9162 | return No_List; | |
9163 | ||
9164 | else | |
9165 | NL := New_List; | |
9166 | E := First (List); | |
9167 | ||
9168 | while Present (E) loop | |
9169 | Append (New_Copy_Tree (E), NL); | |
9170 | E := Next (E); | |
9171 | end loop; | |
9172 | ||
9173 | return NL; | |
9174 | end if; | |
9175 | end New_Copy_List_Tree; | |
9176 | ||
9177 | ------------------- | |
9178 | -- New_Copy_Tree -- | |
9179 | ------------------- | |
9180 | ||
9181 | use Atree.Unchecked_Access; | |
9182 | use Atree_Private_Part; | |
9183 | ||
9184 | -- Our approach here requires a two pass traversal of the tree. The | |
9185 | -- first pass visits all nodes that eventually will be copied looking | |
9186 | -- for defining Itypes. If any defining Itypes are found, then they are | |
9187 | -- copied, and an entry is added to the replacement map. In the second | |
9188 | -- phase, the tree is copied, using the replacement map to replace any | |
9189 | -- Itype references within the copied tree. | |
9190 | ||
9191 | -- The following hash tables are used if the Map supplied has more | |
308e6f3a | 9192 | -- than hash threshold entries to speed up access to the map. If |
f3b01cd9 AC |
9193 | -- there are fewer entries, then the map is searched sequentially |
9194 | -- (because setting up a hash table for only a few entries takes | |
9195 | -- more time than it saves. | |
9196 | ||
9197 | function New_Copy_Hash (E : Entity_Id) return NCT_Header_Num; | |
9198 | -- Hash function used for hash operations | |
9199 | ||
9200 | ------------------- | |
9201 | -- New_Copy_Hash -- | |
9202 | ------------------- | |
9203 | ||
9204 | function New_Copy_Hash (E : Entity_Id) return NCT_Header_Num is | |
9205 | begin | |
9206 | return Nat (E) mod (NCT_Header_Num'Last + 1); | |
9207 | end New_Copy_Hash; | |
9208 | ||
9209 | --------------- | |
9210 | -- NCT_Assoc -- | |
9211 | --------------- | |
9212 | ||
9213 | -- The hash table NCT_Assoc associates old entities in the table | |
9214 | -- with their corresponding new entities (i.e. the pairs of entries | |
9215 | -- presented in the original Map argument are Key-Element pairs). | |
9216 | ||
9217 | package NCT_Assoc is new Simple_HTable ( | |
9218 | Header_Num => NCT_Header_Num, | |
9219 | Element => Entity_Id, | |
9220 | No_Element => Empty, | |
9221 | Key => Entity_Id, | |
9222 | Hash => New_Copy_Hash, | |
9223 | Equal => Types."="); | |
9224 | ||
9225 | --------------------- | |
9226 | -- NCT_Itype_Assoc -- | |
9227 | --------------------- | |
9228 | ||
9229 | -- The hash table NCT_Itype_Assoc contains entries only for those | |
9230 | -- old nodes which have a non-empty Associated_Node_For_Itype set. | |
9231 | -- The key is the associated node, and the element is the new node | |
9232 | -- itself (NOT the associated node for the new node). | |
9233 | ||
9234 | package NCT_Itype_Assoc is new Simple_HTable ( | |
9235 | Header_Num => NCT_Header_Num, | |
9236 | Element => Entity_Id, | |
9237 | No_Element => Empty, | |
9238 | Key => Entity_Id, | |
9239 | Hash => New_Copy_Hash, | |
9240 | Equal => Types."="); | |
9241 | ||
9242 | -- Start of processing for New_Copy_Tree function | |
9243 | ||
9244 | function New_Copy_Tree | |
9245 | (Source : Node_Id; | |
9246 | Map : Elist_Id := No_Elist; | |
9247 | New_Sloc : Source_Ptr := No_Location; | |
9248 | New_Scope : Entity_Id := Empty) return Node_Id | |
9249 | is | |
9250 | Actual_Map : Elist_Id := Map; | |
9251 | -- This is the actual map for the copy. It is initialized with the | |
9252 | -- given elements, and then enlarged as required for Itypes that are | |
9253 | -- copied during the first phase of the copy operation. The visit | |
9254 | -- procedures add elements to this map as Itypes are encountered. | |
9255 | -- The reason we cannot use Map directly, is that it may well be | |
9256 | -- (and normally is) initialized to No_Elist, and if we have mapped | |
9257 | -- entities, we have to reset it to point to a real Elist. | |
9258 | ||
9259 | function Assoc (N : Node_Or_Entity_Id) return Node_Id; | |
9260 | -- Called during second phase to map entities into their corresponding | |
9261 | -- copies using Actual_Map. If the argument is not an entity, or is not | |
9262 | -- in Actual_Map, then it is returned unchanged. | |
9263 | ||
9264 | procedure Build_NCT_Hash_Tables; | |
9265 | -- Builds hash tables (number of elements >= threshold value) | |
9266 | ||
9267 | function Copy_Elist_With_Replacement | |
9268 | (Old_Elist : Elist_Id) return Elist_Id; | |
9269 | -- Called during second phase to copy element list doing replacements | |
9270 | ||
9271 | procedure Copy_Itype_With_Replacement (New_Itype : Entity_Id); | |
9272 | -- Called during the second phase to process a copied Itype. The actual | |
9273 | -- copy happened during the first phase (so that we could make the entry | |
9274 | -- in the mapping), but we still have to deal with the descendents of | |
9275 | -- the copied Itype and copy them where necessary. | |
9276 | ||
9277 | function Copy_List_With_Replacement (Old_List : List_Id) return List_Id; | |
9278 | -- Called during second phase to copy list doing replacements | |
9279 | ||
9280 | function Copy_Node_With_Replacement (Old_Node : Node_Id) return Node_Id; | |
9281 | -- Called during second phase to copy node doing replacements | |
9282 | ||
9283 | procedure Visit_Elist (E : Elist_Id); | |
9284 | -- Called during first phase to visit all elements of an Elist | |
9285 | ||
9286 | procedure Visit_Field (F : Union_Id; N : Node_Id); | |
9287 | -- Visit a single field, recursing to call Visit_Node or Visit_List | |
9288 | -- if the field is a syntactic descendent of the current node (i.e. | |
9289 | -- its parent is Node N). | |
9290 | ||
9291 | procedure Visit_Itype (Old_Itype : Entity_Id); | |
9292 | -- Called during first phase to visit subsidiary fields of a defining | |
9293 | -- Itype, and also create a copy and make an entry in the replacement | |
9294 | -- map for the new copy. | |
9295 | ||
9296 | procedure Visit_List (L : List_Id); | |
9297 | -- Called during first phase to visit all elements of a List | |
9298 | ||
9299 | procedure Visit_Node (N : Node_Or_Entity_Id); | |
9300 | -- Called during first phase to visit a node and all its subtrees | |
9301 | ||
9302 | ----------- | |
9303 | -- Assoc -- | |
9304 | ----------- | |
9305 | ||
9306 | function Assoc (N : Node_Or_Entity_Id) return Node_Id is | |
9307 | E : Elmt_Id; | |
9308 | Ent : Entity_Id; | |
9309 | ||
9310 | begin | |
9311 | if not Has_Extension (N) or else No (Actual_Map) then | |
9312 | return N; | |
9313 | ||
9314 | elsif NCT_Hash_Tables_Used then | |
9315 | Ent := NCT_Assoc.Get (Entity_Id (N)); | |
9316 | ||
9317 | if Present (Ent) then | |
9318 | return Ent; | |
9319 | else | |
9320 | return N; | |
9321 | end if; | |
9322 | ||
9323 | -- No hash table used, do serial search | |
9324 | ||
9325 | else | |
9326 | E := First_Elmt (Actual_Map); | |
9327 | while Present (E) loop | |
9328 | if Node (E) = N then | |
9329 | return Node (Next_Elmt (E)); | |
9330 | else | |
9331 | E := Next_Elmt (Next_Elmt (E)); | |
9332 | end if; | |
9333 | end loop; | |
9334 | end if; | |
9335 | ||
9336 | return N; | |
9337 | end Assoc; | |
9338 | ||
9339 | --------------------------- | |
9340 | -- Build_NCT_Hash_Tables -- | |
9341 | --------------------------- | |
9342 | ||
9343 | procedure Build_NCT_Hash_Tables is | |
9344 | Elmt : Elmt_Id; | |
9345 | Ent : Entity_Id; | |
9346 | begin | |
9347 | if NCT_Hash_Table_Setup then | |
9348 | NCT_Assoc.Reset; | |
9349 | NCT_Itype_Assoc.Reset; | |
9350 | end if; | |
9351 | ||
9352 | Elmt := First_Elmt (Actual_Map); | |
9353 | while Present (Elmt) loop | |
9354 | Ent := Node (Elmt); | |
9355 | ||
9356 | -- Get new entity, and associate old and new | |
9357 | ||
9358 | Next_Elmt (Elmt); | |
9359 | NCT_Assoc.Set (Ent, Node (Elmt)); | |
9360 | ||
9361 | if Is_Type (Ent) then | |
9362 | declare | |
9363 | Anode : constant Entity_Id := | |
9364 | Associated_Node_For_Itype (Ent); | |
9365 | ||
9366 | begin | |
9367 | if Present (Anode) then | |
9368 | ||
9369 | -- Enter a link between the associated node of the | |
9370 | -- old Itype and the new Itype, for updating later | |
9371 | -- when node is copied. | |
9372 | ||
9373 | NCT_Itype_Assoc.Set (Anode, Node (Elmt)); | |
9374 | end if; | |
9375 | end; | |
9376 | end if; | |
9377 | ||
9378 | Next_Elmt (Elmt); | |
9379 | end loop; | |
9380 | ||
9381 | NCT_Hash_Tables_Used := True; | |
9382 | NCT_Hash_Table_Setup := True; | |
9383 | end Build_NCT_Hash_Tables; | |
9384 | ||
9385 | --------------------------------- | |
9386 | -- Copy_Elist_With_Replacement -- | |
9387 | --------------------------------- | |
9388 | ||
9389 | function Copy_Elist_With_Replacement | |
9390 | (Old_Elist : Elist_Id) return Elist_Id | |
9391 | is | |
9392 | M : Elmt_Id; | |
9393 | New_Elist : Elist_Id; | |
9394 | ||
9395 | begin | |
9396 | if No (Old_Elist) then | |
9397 | return No_Elist; | |
9398 | ||
9399 | else | |
9400 | New_Elist := New_Elmt_List; | |
9401 | ||
9402 | M := First_Elmt (Old_Elist); | |
9403 | while Present (M) loop | |
9404 | Append_Elmt (Copy_Node_With_Replacement (Node (M)), New_Elist); | |
9405 | Next_Elmt (M); | |
9406 | end loop; | |
9407 | end if; | |
9408 | ||
9409 | return New_Elist; | |
9410 | end Copy_Elist_With_Replacement; | |
9411 | ||
9412 | --------------------------------- | |
9413 | -- Copy_Itype_With_Replacement -- | |
9414 | --------------------------------- | |
9415 | ||
9416 | -- This routine exactly parallels its phase one analog Visit_Itype, | |
9417 | ||
9418 | procedure Copy_Itype_With_Replacement (New_Itype : Entity_Id) is | |
9419 | begin | |
9420 | -- Translate Next_Entity, Scope and Etype fields, in case they | |
9421 | -- reference entities that have been mapped into copies. | |
9422 | ||
9423 | Set_Next_Entity (New_Itype, Assoc (Next_Entity (New_Itype))); | |
9424 | Set_Etype (New_Itype, Assoc (Etype (New_Itype))); | |
9425 | ||
9426 | if Present (New_Scope) then | |
9427 | Set_Scope (New_Itype, New_Scope); | |
9428 | else | |
9429 | Set_Scope (New_Itype, Assoc (Scope (New_Itype))); | |
9430 | end if; | |
9431 | ||
9432 | -- Copy referenced fields | |
9433 | ||
9434 | if Is_Discrete_Type (New_Itype) then | |
9435 | Set_Scalar_Range (New_Itype, | |
9436 | Copy_Node_With_Replacement (Scalar_Range (New_Itype))); | |
9437 | ||
9438 | elsif Has_Discriminants (Base_Type (New_Itype)) then | |
9439 | Set_Discriminant_Constraint (New_Itype, | |
9440 | Copy_Elist_With_Replacement | |
9441 | (Discriminant_Constraint (New_Itype))); | |
9442 | ||
9443 | elsif Is_Array_Type (New_Itype) then | |
9444 | if Present (First_Index (New_Itype)) then | |
9445 | Set_First_Index (New_Itype, | |
9446 | First (Copy_List_With_Replacement | |
9447 | (List_Containing (First_Index (New_Itype))))); | |
9448 | end if; | |
9449 | ||
9450 | if Is_Packed (New_Itype) then | |
9451 | Set_Packed_Array_Type (New_Itype, | |
9452 | Copy_Node_With_Replacement | |
9453 | (Packed_Array_Type (New_Itype))); | |
9454 | end if; | |
9455 | end if; | |
9456 | end Copy_Itype_With_Replacement; | |
9457 | ||
9458 | -------------------------------- | |
9459 | -- Copy_List_With_Replacement -- | |
9460 | -------------------------------- | |
9461 | ||
9462 | function Copy_List_With_Replacement | |
9463 | (Old_List : List_Id) return List_Id | |
9464 | is | |
9465 | New_List : List_Id; | |
9466 | E : Node_Id; | |
9467 | ||
9468 | begin | |
9469 | if Old_List = No_List then | |
9470 | return No_List; | |
9471 | ||
9472 | else | |
9473 | New_List := Empty_List; | |
9474 | ||
9475 | E := First (Old_List); | |
9476 | while Present (E) loop | |
9477 | Append (Copy_Node_With_Replacement (E), New_List); | |
9478 | Next (E); | |
9479 | end loop; | |
9480 | ||
9481 | return New_List; | |
9482 | end if; | |
9483 | end Copy_List_With_Replacement; | |
9484 | ||
9485 | -------------------------------- | |
9486 | -- Copy_Node_With_Replacement -- | |
9487 | -------------------------------- | |
9488 | ||
9489 | function Copy_Node_With_Replacement | |
9490 | (Old_Node : Node_Id) return Node_Id | |
9491 | is | |
9492 | New_Node : Node_Id; | |
9493 | ||
9494 | procedure Adjust_Named_Associations | |
9495 | (Old_Node : Node_Id; | |
9496 | New_Node : Node_Id); | |
9497 | -- If a call node has named associations, these are chained through | |
9498 | -- the First_Named_Actual, Next_Named_Actual links. These must be | |
9499 | -- propagated separately to the new parameter list, because these | |
9500 | -- are not syntactic fields. | |
9501 | ||
9502 | function Copy_Field_With_Replacement | |
9503 | (Field : Union_Id) return Union_Id; | |
9504 | -- Given Field, which is a field of Old_Node, return a copy of it | |
9505 | -- if it is a syntactic field (i.e. its parent is Node), setting | |
9506 | -- the parent of the copy to poit to New_Node. Otherwise returns | |
9507 | -- the field (possibly mapped if it is an entity). | |
9508 | ||
9509 | ------------------------------- | |
9510 | -- Adjust_Named_Associations -- | |
9511 | ------------------------------- | |
9512 | ||
9513 | procedure Adjust_Named_Associations | |
9514 | (Old_Node : Node_Id; | |
9515 | New_Node : Node_Id) | |
9516 | is | |
9517 | Old_E : Node_Id; | |
9518 | New_E : Node_Id; | |
9519 | ||
9520 | Old_Next : Node_Id; | |
9521 | New_Next : Node_Id; | |
9522 | ||
9523 | begin | |
9524 | Old_E := First (Parameter_Associations (Old_Node)); | |
9525 | New_E := First (Parameter_Associations (New_Node)); | |
9526 | while Present (Old_E) loop | |
9527 | if Nkind (Old_E) = N_Parameter_Association | |
9528 | and then Present (Next_Named_Actual (Old_E)) | |
9529 | then | |
9530 | if First_Named_Actual (Old_Node) | |
9531 | = Explicit_Actual_Parameter (Old_E) | |
9532 | then | |
9533 | Set_First_Named_Actual | |
9534 | (New_Node, Explicit_Actual_Parameter (New_E)); | |
9535 | end if; | |
9536 | ||
9537 | -- Now scan parameter list from the beginning,to locate | |
9538 | -- next named actual, which can be out of order. | |
9539 | ||
9540 | Old_Next := First (Parameter_Associations (Old_Node)); | |
9541 | New_Next := First (Parameter_Associations (New_Node)); | |
9542 | ||
9543 | while Nkind (Old_Next) /= N_Parameter_Association | |
9544 | or else Explicit_Actual_Parameter (Old_Next) | |
9545 | /= Next_Named_Actual (Old_E) | |
9546 | loop | |
9547 | Next (Old_Next); | |
9548 | Next (New_Next); | |
9549 | end loop; | |
9550 | ||
9551 | Set_Next_Named_Actual | |
9552 | (New_E, Explicit_Actual_Parameter (New_Next)); | |
9553 | end if; | |
9554 | ||
9555 | Next (Old_E); | |
9556 | Next (New_E); | |
9557 | end loop; | |
9558 | end Adjust_Named_Associations; | |
9559 | ||
9560 | --------------------------------- | |
9561 | -- Copy_Field_With_Replacement -- | |
9562 | --------------------------------- | |
9563 | ||
9564 | function Copy_Field_With_Replacement | |
9565 | (Field : Union_Id) return Union_Id | |
9566 | is | |
9567 | begin | |
9568 | if Field = Union_Id (Empty) then | |
9569 | return Field; | |
9570 | ||
9571 | elsif Field in Node_Range then | |
9572 | declare | |
9573 | Old_N : constant Node_Id := Node_Id (Field); | |
9574 | New_N : Node_Id; | |
9575 | ||
9576 | begin | |
9577 | -- If syntactic field, as indicated by the parent pointer | |
9578 | -- being set, then copy the referenced node recursively. | |
9579 | ||
9580 | if Parent (Old_N) = Old_Node then | |
9581 | New_N := Copy_Node_With_Replacement (Old_N); | |
9582 | ||
9583 | if New_N /= Old_N then | |
9584 | Set_Parent (New_N, New_Node); | |
9585 | end if; | |
9586 | ||
9587 | -- For semantic fields, update possible entity reference | |
9588 | -- from the replacement map. | |
9589 | ||
9590 | else | |
9591 | New_N := Assoc (Old_N); | |
9592 | end if; | |
9593 | ||
9594 | return Union_Id (New_N); | |
9595 | end; | |
9596 | ||
9597 | elsif Field in List_Range then | |
9598 | declare | |
9599 | Old_L : constant List_Id := List_Id (Field); | |
9600 | New_L : List_Id; | |
9601 | ||
9602 | begin | |
9603 | -- If syntactic field, as indicated by the parent pointer, | |
9604 | -- then recursively copy the entire referenced list. | |
9605 | ||
9606 | if Parent (Old_L) = Old_Node then | |
9607 | New_L := Copy_List_With_Replacement (Old_L); | |
9608 | Set_Parent (New_L, New_Node); | |
9609 | ||
9610 | -- For semantic list, just returned unchanged | |
9611 | ||
9612 | else | |
9613 | New_L := Old_L; | |
9614 | end if; | |
9615 | ||
9616 | return Union_Id (New_L); | |
9617 | end; | |
9618 | ||
9619 | -- Anything other than a list or a node is returned unchanged | |
9620 | ||
9621 | else | |
9622 | return Field; | |
9623 | end if; | |
9624 | end Copy_Field_With_Replacement; | |
9625 | ||
9626 | -- Start of processing for Copy_Node_With_Replacement | |
9627 | ||
9628 | begin | |
9629 | if Old_Node <= Empty_Or_Error then | |
9630 | return Old_Node; | |
9631 | ||
9632 | elsif Has_Extension (Old_Node) then | |
9633 | return Assoc (Old_Node); | |
9634 | ||
9635 | else | |
9636 | New_Node := New_Copy (Old_Node); | |
9637 | ||
9638 | -- If the node we are copying is the associated node of a | |
9639 | -- previously copied Itype, then adjust the associated node | |
9640 | -- of the copy of that Itype accordingly. | |
9641 | ||
9642 | if Present (Actual_Map) then | |
9643 | declare | |
9644 | E : Elmt_Id; | |
9645 | Ent : Entity_Id; | |
9646 | ||
9647 | begin | |
9648 | -- Case of hash table used | |
9649 | ||
9650 | if NCT_Hash_Tables_Used then | |
9651 | Ent := NCT_Itype_Assoc.Get (Old_Node); | |
9652 | ||
9653 | if Present (Ent) then | |
9654 | Set_Associated_Node_For_Itype (Ent, New_Node); | |
9655 | end if; | |
9656 | ||
9657 | -- Case of no hash table used | |
9658 | ||
9659 | else | |
9660 | E := First_Elmt (Actual_Map); | |
9661 | while Present (E) loop | |
9662 | if Is_Itype (Node (E)) | |
9663 | and then | |
9664 | Old_Node = Associated_Node_For_Itype (Node (E)) | |
9665 | then | |
9666 | Set_Associated_Node_For_Itype | |
9667 | (Node (Next_Elmt (E)), New_Node); | |
9668 | end if; | |
9669 | ||
9670 | E := Next_Elmt (Next_Elmt (E)); | |
9671 | end loop; | |
9672 | end if; | |
9673 | end; | |
9674 | end if; | |
9675 | ||
9676 | -- Recursively copy descendents | |
9677 | ||
9678 | Set_Field1 | |
9679 | (New_Node, Copy_Field_With_Replacement (Field1 (New_Node))); | |
9680 | Set_Field2 | |
9681 | (New_Node, Copy_Field_With_Replacement (Field2 (New_Node))); | |
9682 | Set_Field3 | |
9683 | (New_Node, Copy_Field_With_Replacement (Field3 (New_Node))); | |
9684 | Set_Field4 | |
9685 | (New_Node, Copy_Field_With_Replacement (Field4 (New_Node))); | |
9686 | Set_Field5 | |
9687 | (New_Node, Copy_Field_With_Replacement (Field5 (New_Node))); | |
9688 | ||
9689 | -- Adjust Sloc of new node if necessary | |
9690 | ||
9691 | if New_Sloc /= No_Location then | |
9692 | Set_Sloc (New_Node, New_Sloc); | |
9693 | ||
9694 | -- If we adjust the Sloc, then we are essentially making | |
9695 | -- a completely new node, so the Comes_From_Source flag | |
9696 | -- should be reset to the proper default value. | |
9697 | ||
9698 | Nodes.Table (New_Node).Comes_From_Source := | |
9699 | Default_Node.Comes_From_Source; | |
9700 | end if; | |
9701 | ||
9702 | -- If the node is call and has named associations, | |
9703 | -- set the corresponding links in the copy. | |
9704 | ||
9705 | if (Nkind (Old_Node) = N_Function_Call | |
9706 | or else Nkind (Old_Node) = N_Entry_Call_Statement | |
9707 | or else | |
9708 | Nkind (Old_Node) = N_Procedure_Call_Statement) | |
9709 | and then Present (First_Named_Actual (Old_Node)) | |
9710 | then | |
9711 | Adjust_Named_Associations (Old_Node, New_Node); | |
9712 | end if; | |
9713 | ||
9714 | -- Reset First_Real_Statement for Handled_Sequence_Of_Statements. | |
9715 | -- The replacement mechanism applies to entities, and is not used | |
9716 | -- here. Eventually we may need a more general graph-copying | |
9717 | -- routine. For now, do a sequential search to find desired node. | |
9718 | ||
9719 | if Nkind (Old_Node) = N_Handled_Sequence_Of_Statements | |
9720 | and then Present (First_Real_Statement (Old_Node)) | |
9721 | then | |
9722 | declare | |
9723 | Old_F : constant Node_Id := First_Real_Statement (Old_Node); | |
9724 | N1, N2 : Node_Id; | |
9725 | ||
9726 | begin | |
9727 | N1 := First (Statements (Old_Node)); | |
9728 | N2 := First (Statements (New_Node)); | |
9729 | ||
9730 | while N1 /= Old_F loop | |
9731 | Next (N1); | |
9732 | Next (N2); | |
9733 | end loop; | |
9734 | ||
9735 | Set_First_Real_Statement (New_Node, N2); | |
9736 | end; | |
9737 | end if; | |
9738 | end if; | |
9739 | ||
9740 | -- All done, return copied node | |
9741 | ||
9742 | return New_Node; | |
9743 | end Copy_Node_With_Replacement; | |
9744 | ||
9745 | ----------------- | |
9746 | -- Visit_Elist -- | |
9747 | ----------------- | |
9748 | ||
9749 | procedure Visit_Elist (E : Elist_Id) is | |
9750 | Elmt : Elmt_Id; | |
9751 | begin | |
9752 | if Present (E) then | |
9753 | Elmt := First_Elmt (E); | |
9754 | ||
9755 | while Elmt /= No_Elmt loop | |
9756 | Visit_Node (Node (Elmt)); | |
9757 | Next_Elmt (Elmt); | |
9758 | end loop; | |
9759 | end if; | |
9760 | end Visit_Elist; | |
9761 | ||
9762 | ----------------- | |
9763 | -- Visit_Field -- | |
9764 | ----------------- | |
9765 | ||
9766 | procedure Visit_Field (F : Union_Id; N : Node_Id) is | |
9767 | begin | |
9768 | if F = Union_Id (Empty) then | |
9769 | return; | |
9770 | ||
9771 | elsif F in Node_Range then | |
9772 | ||
9773 | -- Copy node if it is syntactic, i.e. its parent pointer is | |
9774 | -- set to point to the field that referenced it (certain | |
9775 | -- Itypes will also meet this criterion, which is fine, since | |
9776 | -- these are clearly Itypes that do need to be copied, since | |
9777 | -- we are copying their parent.) | |
9778 | ||
9779 | if Parent (Node_Id (F)) = N then | |
9780 | Visit_Node (Node_Id (F)); | |
9781 | return; | |
9782 | ||
9783 | -- Another case, if we are pointing to an Itype, then we want | |
9784 | -- to copy it if its associated node is somewhere in the tree | |
9785 | -- being copied. | |
9786 | ||
9787 | -- Note: the exclusion of self-referential copies is just an | |
9788 | -- optimization, since the search of the already copied list | |
9789 | -- would catch it, but it is a common case (Etype pointing | |
9790 | -- to itself for an Itype that is a base type). | |
9791 | ||
9792 | elsif Has_Extension (Node_Id (F)) | |
9793 | and then Is_Itype (Entity_Id (F)) | |
9794 | and then Node_Id (F) /= N | |
9795 | then | |
9796 | declare | |
9797 | P : Node_Id; | |
9798 | ||
9799 | begin | |
9800 | P := Associated_Node_For_Itype (Node_Id (F)); | |
9801 | while Present (P) loop | |
9802 | if P = Source then | |
9803 | Visit_Node (Node_Id (F)); | |
9804 | return; | |
9805 | else | |
9806 | P := Parent (P); | |
9807 | end if; | |
9808 | end loop; | |
9809 | ||
9810 | -- An Itype whose parent is not being copied definitely | |
9811 | -- should NOT be copied, since it does not belong in any | |
9812 | -- sense to the copied subtree. | |
9813 | ||
9814 | return; | |
9815 | end; | |
9816 | end if; | |
9817 | ||
9818 | elsif F in List_Range | |
9819 | and then Parent (List_Id (F)) = N | |
9820 | then | |
9821 | Visit_List (List_Id (F)); | |
9822 | return; | |
9823 | end if; | |
9824 | end Visit_Field; | |
9825 | ||
9826 | ----------------- | |
9827 | -- Visit_Itype -- | |
9828 | ----------------- | |
9829 | ||
9830 | procedure Visit_Itype (Old_Itype : Entity_Id) is | |
9831 | New_Itype : Entity_Id; | |
9832 | E : Elmt_Id; | |
9833 | Ent : Entity_Id; | |
9834 | ||
9835 | begin | |
9836 | -- Itypes that describe the designated type of access to subprograms | |
9837 | -- have the structure of subprogram declarations, with signatures, | |
9838 | -- etc. Either we duplicate the signatures completely, or choose to | |
9839 | -- share such itypes, which is fine because their elaboration will | |
9840 | -- have no side effects. | |
9841 | ||
9842 | if Ekind (Old_Itype) = E_Subprogram_Type then | |
9843 | return; | |
9844 | end if; | |
9845 | ||
9846 | New_Itype := New_Copy (Old_Itype); | |
9847 | ||
9848 | -- The new Itype has all the attributes of the old one, and | |
9849 | -- we just copy the contents of the entity. However, the back-end | |
9850 | -- needs different names for debugging purposes, so we create a | |
9851 | -- new internal name for it in all cases. | |
9852 | ||
9853 | Set_Chars (New_Itype, New_Internal_Name ('T')); | |
9854 | ||
9855 | -- If our associated node is an entity that has already been copied, | |
9856 | -- then set the associated node of the copy to point to the right | |
9857 | -- copy. If we have copied an Itype that is itself the associated | |
9858 | -- node of some previously copied Itype, then we set the right | |
9859 | -- pointer in the other direction. | |
9860 | ||
9861 | if Present (Actual_Map) then | |
9862 | ||
9863 | -- Case of hash tables used | |
9864 | ||
9865 | if NCT_Hash_Tables_Used then | |
9866 | ||
9867 | Ent := NCT_Assoc.Get (Associated_Node_For_Itype (Old_Itype)); | |
9868 | ||
9869 | if Present (Ent) then | |
9870 | Set_Associated_Node_For_Itype (New_Itype, Ent); | |
9871 | end if; | |
9872 | ||
9873 | Ent := NCT_Itype_Assoc.Get (Old_Itype); | |
9874 | if Present (Ent) then | |
9875 | Set_Associated_Node_For_Itype (Ent, New_Itype); | |
9876 | ||
9877 | -- If the hash table has no association for this Itype and | |
9878 | -- its associated node, enter one now. | |
9879 | ||
9880 | else | |
9881 | NCT_Itype_Assoc.Set | |
9882 | (Associated_Node_For_Itype (Old_Itype), New_Itype); | |
9883 | end if; | |
9884 | ||
9885 | -- Case of hash tables not used | |
9886 | ||
9887 | else | |
9888 | E := First_Elmt (Actual_Map); | |
9889 | while Present (E) loop | |
9890 | if Associated_Node_For_Itype (Old_Itype) = Node (E) then | |
9891 | Set_Associated_Node_For_Itype | |
9892 | (New_Itype, Node (Next_Elmt (E))); | |
9893 | end if; | |
9894 | ||
9895 | if Is_Type (Node (E)) | |
9896 | and then | |
9897 | Old_Itype = Associated_Node_For_Itype (Node (E)) | |
9898 | then | |
9899 | Set_Associated_Node_For_Itype | |
9900 | (Node (Next_Elmt (E)), New_Itype); | |
9901 | end if; | |
9902 | ||
9903 | E := Next_Elmt (Next_Elmt (E)); | |
9904 | end loop; | |
9905 | end if; | |
9906 | end if; | |
9907 | ||
9908 | if Present (Freeze_Node (New_Itype)) then | |
9909 | Set_Is_Frozen (New_Itype, False); | |
9910 | Set_Freeze_Node (New_Itype, Empty); | |
9911 | end if; | |
9912 | ||
9913 | -- Add new association to map | |
9914 | ||
9915 | if No (Actual_Map) then | |
9916 | Actual_Map := New_Elmt_List; | |
9917 | end if; | |
9918 | ||
9919 | Append_Elmt (Old_Itype, Actual_Map); | |
9920 | Append_Elmt (New_Itype, Actual_Map); | |
9921 | ||
9922 | if NCT_Hash_Tables_Used then | |
9923 | NCT_Assoc.Set (Old_Itype, New_Itype); | |
9924 | ||
9925 | else | |
9926 | NCT_Table_Entries := NCT_Table_Entries + 1; | |
9927 | ||
308e6f3a | 9928 | if NCT_Table_Entries > NCT_Hash_Threshold then |
f3b01cd9 AC |
9929 | Build_NCT_Hash_Tables; |
9930 | end if; | |
9931 | end if; | |
9932 | ||
9933 | -- If a record subtype is simply copied, the entity list will be | |
9934 | -- shared. Thus cloned_Subtype must be set to indicate the sharing. | |
9935 | ||
8a95f4e8 | 9936 | if Ekind_In (Old_Itype, E_Record_Subtype, E_Class_Wide_Subtype) then |
f3b01cd9 AC |
9937 | Set_Cloned_Subtype (New_Itype, Old_Itype); |
9938 | end if; | |
9939 | ||
9940 | -- Visit descendents that eventually get copied | |
9941 | ||
9942 | Visit_Field (Union_Id (Etype (Old_Itype)), Old_Itype); | |
9943 | ||
9944 | if Is_Discrete_Type (Old_Itype) then | |
9945 | Visit_Field (Union_Id (Scalar_Range (Old_Itype)), Old_Itype); | |
9946 | ||
9947 | elsif Has_Discriminants (Base_Type (Old_Itype)) then | |
9948 | -- ??? This should involve call to Visit_Field | |
9949 | Visit_Elist (Discriminant_Constraint (Old_Itype)); | |
9950 | ||
9951 | elsif Is_Array_Type (Old_Itype) then | |
9952 | if Present (First_Index (Old_Itype)) then | |
9953 | Visit_Field (Union_Id (List_Containing | |
9954 | (First_Index (Old_Itype))), | |
9955 | Old_Itype); | |
9956 | end if; | |
9957 | ||
9958 | if Is_Packed (Old_Itype) then | |
9959 | Visit_Field (Union_Id (Packed_Array_Type (Old_Itype)), | |
9960 | Old_Itype); | |
9961 | end if; | |
9962 | end if; | |
9963 | end Visit_Itype; | |
9964 | ||
9965 | ---------------- | |
9966 | -- Visit_List -- | |
9967 | ---------------- | |
9968 | ||
9969 | procedure Visit_List (L : List_Id) is | |
9970 | N : Node_Id; | |
9971 | begin | |
9972 | if L /= No_List then | |
9973 | N := First (L); | |
9974 | ||
9975 | while Present (N) loop | |
9976 | Visit_Node (N); | |
9977 | Next (N); | |
9978 | end loop; | |
9979 | end if; | |
9980 | end Visit_List; | |
9981 | ||
9982 | ---------------- | |
9983 | -- Visit_Node -- | |
9984 | ---------------- | |
9985 | ||
9986 | procedure Visit_Node (N : Node_Or_Entity_Id) is | |
9987 | ||
9988 | -- Start of processing for Visit_Node | |
9989 | ||
9990 | begin | |
9991 | -- Handle case of an Itype, which must be copied | |
9992 | ||
9993 | if Has_Extension (N) | |
9994 | and then Is_Itype (N) | |
9995 | then | |
9996 | -- Nothing to do if already in the list. This can happen with an | |
9997 | -- Itype entity that appears more than once in the tree. | |
9998 | -- Note that we do not want to visit descendents in this case. | |
9999 | ||
10000 | -- Test for already in list when hash table is used | |
10001 | ||
10002 | if NCT_Hash_Tables_Used then | |
10003 | if Present (NCT_Assoc.Get (Entity_Id (N))) then | |
10004 | return; | |
10005 | end if; | |
10006 | ||
10007 | -- Test for already in list when hash table not used | |
10008 | ||
10009 | else | |
10010 | declare | |
10011 | E : Elmt_Id; | |
10012 | begin | |
10013 | if Present (Actual_Map) then | |
10014 | E := First_Elmt (Actual_Map); | |
10015 | while Present (E) loop | |
10016 | if Node (E) = N then | |
10017 | return; | |
10018 | else | |
10019 | E := Next_Elmt (Next_Elmt (E)); | |
10020 | end if; | |
10021 | end loop; | |
10022 | end if; | |
10023 | end; | |
10024 | end if; | |
10025 | ||
10026 | Visit_Itype (N); | |
10027 | end if; | |
10028 | ||
10029 | -- Visit descendents | |
10030 | ||
10031 | Visit_Field (Field1 (N), N); | |
10032 | Visit_Field (Field2 (N), N); | |
10033 | Visit_Field (Field3 (N), N); | |
10034 | Visit_Field (Field4 (N), N); | |
10035 | Visit_Field (Field5 (N), N); | |
10036 | end Visit_Node; | |
10037 | ||
10038 | -- Start of processing for New_Copy_Tree | |
10039 | ||
10040 | begin | |
10041 | Actual_Map := Map; | |
10042 | ||
10043 | -- See if we should use hash table | |
10044 | ||
10045 | if No (Actual_Map) then | |
10046 | NCT_Hash_Tables_Used := False; | |
10047 | ||
10048 | else | |
10049 | declare | |
10050 | Elmt : Elmt_Id; | |
10051 | ||
10052 | begin | |
10053 | NCT_Table_Entries := 0; | |
10054 | ||
10055 | Elmt := First_Elmt (Actual_Map); | |
10056 | while Present (Elmt) loop | |
10057 | NCT_Table_Entries := NCT_Table_Entries + 1; | |
10058 | Next_Elmt (Elmt); | |
10059 | Next_Elmt (Elmt); | |
10060 | end loop; | |
10061 | ||
308e6f3a | 10062 | if NCT_Table_Entries > NCT_Hash_Threshold then |
f3b01cd9 AC |
10063 | Build_NCT_Hash_Tables; |
10064 | else | |
10065 | NCT_Hash_Tables_Used := False; | |
10066 | end if; | |
10067 | end; | |
10068 | end if; | |
10069 | ||
10070 | -- Hash table set up if required, now start phase one by visiting | |
10071 | -- top node (we will recursively visit the descendents). | |
10072 | ||
10073 | Visit_Node (Source); | |
10074 | ||
10075 | -- Now the second phase of the copy can start. First we process | |
10076 | -- all the mapped entities, copying their descendents. | |
10077 | ||
10078 | if Present (Actual_Map) then | |
10079 | declare | |
10080 | Elmt : Elmt_Id; | |
10081 | New_Itype : Entity_Id; | |
10082 | begin | |
10083 | Elmt := First_Elmt (Actual_Map); | |
10084 | while Present (Elmt) loop | |
10085 | Next_Elmt (Elmt); | |
10086 | New_Itype := Node (Elmt); | |
10087 | Copy_Itype_With_Replacement (New_Itype); | |
10088 | Next_Elmt (Elmt); | |
10089 | end loop; | |
10090 | end; | |
10091 | end if; | |
10092 | ||
10093 | -- Now we can copy the actual tree | |
10094 | ||
10095 | return Copy_Node_With_Replacement (Source); | |
10096 | end New_Copy_Tree; | |
10097 | ||
996ae0b0 RK |
10098 | ------------------------- |
10099 | -- New_External_Entity -- | |
10100 | ------------------------- | |
10101 | ||
10102 | function New_External_Entity | |
10103 | (Kind : Entity_Kind; | |
10104 | Scope_Id : Entity_Id; | |
10105 | Sloc_Value : Source_Ptr; | |
10106 | Related_Id : Entity_Id; | |
10107 | Suffix : Character; | |
10108 | Suffix_Index : Nat := 0; | |
fbf5a39b | 10109 | Prefix : Character := ' ') return Entity_Id |
996ae0b0 RK |
10110 | is |
10111 | N : constant Entity_Id := | |
10112 | Make_Defining_Identifier (Sloc_Value, | |
10113 | New_External_Name | |
10114 | (Chars (Related_Id), Suffix, Suffix_Index, Prefix)); | |
10115 | ||
10116 | begin | |
10117 | Set_Ekind (N, Kind); | |
10118 | Set_Is_Internal (N, True); | |
10119 | Append_Entity (N, Scope_Id); | |
10120 | Set_Public_Status (N); | |
10121 | ||
10122 | if Kind in Type_Kind then | |
10123 | Init_Size_Align (N); | |
10124 | end if; | |
10125 | ||
10126 | return N; | |
10127 | end New_External_Entity; | |
10128 | ||
10129 | ------------------------- | |
10130 | -- New_Internal_Entity -- | |
10131 | ------------------------- | |
10132 | ||
10133 | function New_Internal_Entity | |
10134 | (Kind : Entity_Kind; | |
10135 | Scope_Id : Entity_Id; | |
10136 | Sloc_Value : Source_Ptr; | |
fbf5a39b | 10137 | Id_Char : Character) return Entity_Id |
996ae0b0 | 10138 | is |
092ef350 | 10139 | N : constant Entity_Id := Make_Temporary (Sloc_Value, Id_Char); |
996ae0b0 RK |
10140 | |
10141 | begin | |
10142 | Set_Ekind (N, Kind); | |
10143 | Set_Is_Internal (N, True); | |
10144 | Append_Entity (N, Scope_Id); | |
10145 | ||
10146 | if Kind in Type_Kind then | |
10147 | Init_Size_Align (N); | |
10148 | end if; | |
10149 | ||
10150 | return N; | |
10151 | end New_Internal_Entity; | |
10152 | ||
10153 | ----------------- | |
10154 | -- Next_Actual -- | |
10155 | ----------------- | |
10156 | ||
10157 | function Next_Actual (Actual_Id : Node_Id) return Node_Id is | |
10158 | N : Node_Id; | |
10159 | ||
10160 | begin | |
7f0e4cdb BD |
10161 | -- If we are pointing at a positional parameter, it is a member of a |
10162 | -- node list (the list of parameters), and the next parameter is the | |
10163 | -- next node on the list, unless we hit a parameter association, then | |
10164 | -- we shift to using the chain whose head is the First_Named_Actual in | |
10165 | -- the parent, and then is threaded using the Next_Named_Actual of the | |
10166 | -- Parameter_Association. All this fiddling is because the original node | |
10167 | -- list is in the textual call order, and what we need is the | |
10168 | -- declaration order. | |
996ae0b0 RK |
10169 | |
10170 | if Is_List_Member (Actual_Id) then | |
10171 | N := Next (Actual_Id); | |
10172 | ||
10173 | if Nkind (N) = N_Parameter_Association then | |
10174 | return First_Named_Actual (Parent (Actual_Id)); | |
10175 | else | |
10176 | return N; | |
10177 | end if; | |
10178 | ||
10179 | else | |
10180 | return Next_Named_Actual (Parent (Actual_Id)); | |
10181 | end if; | |
10182 | end Next_Actual; | |
10183 | ||
10184 | procedure Next_Actual (Actual_Id : in out Node_Id) is | |
10185 | begin | |
10186 | Actual_Id := Next_Actual (Actual_Id); | |
10187 | end Next_Actual; | |
10188 | ||
10189 | ----------------------- | |
10190 | -- Normalize_Actuals -- | |
10191 | ----------------------- | |
10192 | ||
195b0505 RD |
10193 | -- Chain actuals according to formals of subprogram. If there are no named |
10194 | -- associations, the chain is simply the list of Parameter Associations, | |
10195 | -- since the order is the same as the declaration order. If there are named | |
10196 | -- associations, then the First_Named_Actual field in the N_Function_Call | |
10197 | -- or N_Procedure_Call_Statement node points to the Parameter_Association | |
10198 | -- node for the parameter that comes first in declaration order. The | |
10199 | -- remaining named parameters are then chained in declaration order using | |
10200 | -- Next_Named_Actual. | |
996ae0b0 | 10201 | |
195b0505 RD |
10202 | -- This routine also verifies that the number of actuals is compatible with |
10203 | -- the number and default values of formals, but performs no type checking | |
10204 | -- (type checking is done by the caller). | |
996ae0b0 | 10205 | |
195b0505 RD |
10206 | -- If the matching succeeds, Success is set to True and the caller proceeds |
10207 | -- with type-checking. If the match is unsuccessful, then Success is set to | |
10208 | -- False, and the caller attempts a different interpretation, if there is | |
10209 | -- one. | |
996ae0b0 | 10210 | |
195b0505 RD |
10211 | -- If the flag Report is on, the call is not overloaded, and a failure to |
10212 | -- match can be reported here, rather than in the caller. | |
996ae0b0 RK |
10213 | |
10214 | procedure Normalize_Actuals | |
10215 | (N : Node_Id; | |
10216 | S : Entity_Id; | |
10217 | Report : Boolean; | |
10218 | Success : out Boolean) | |
10219 | is | |
10220 | Actuals : constant List_Id := Parameter_Associations (N); | |
1b6c95c4 | 10221 | Actual : Node_Id := Empty; |
996ae0b0 RK |
10222 | Formal : Entity_Id; |
10223 | Last : Node_Id := Empty; | |
10224 | First_Named : Node_Id := Empty; | |
10225 | Found : Boolean; | |
10226 | ||
10227 | Formals_To_Match : Integer := 0; | |
10228 | Actuals_To_Match : Integer := 0; | |
10229 | ||
10230 | procedure Chain (A : Node_Id); | |
10231 | -- Add named actual at the proper place in the list, using the | |
10232 | -- Next_Named_Actual link. | |
10233 | ||
10234 | function Reporting return Boolean; | |
10235 | -- Determines if an error is to be reported. To report an error, we | |
10236 | -- need Report to be True, and also we do not report errors caused | |
fbf5a39b | 10237 | -- by calls to init procs that occur within other init procs. Such |
996ae0b0 RK |
10238 | -- errors must always be cascaded errors, since if all the types are |
10239 | -- declared correctly, the compiler will certainly build decent calls! | |
10240 | ||
fbf5a39b AC |
10241 | ----------- |
10242 | -- Chain -- | |
10243 | ----------- | |
10244 | ||
996ae0b0 RK |
10245 | procedure Chain (A : Node_Id) is |
10246 | begin | |
10247 | if No (Last) then | |
10248 | ||
130c236a | 10249 | -- Call node points to first actual in list |
996ae0b0 RK |
10250 | |
10251 | Set_First_Named_Actual (N, Explicit_Actual_Parameter (A)); | |
10252 | ||
10253 | else | |
10254 | Set_Next_Named_Actual (Last, Explicit_Actual_Parameter (A)); | |
10255 | end if; | |
10256 | ||
10257 | Last := A; | |
10258 | Set_Next_Named_Actual (Last, Empty); | |
10259 | end Chain; | |
10260 | ||
fbf5a39b AC |
10261 | --------------- |
10262 | -- Reporting -- | |
10263 | --------------- | |
10264 | ||
996ae0b0 RK |
10265 | function Reporting return Boolean is |
10266 | begin | |
10267 | if not Report then | |
10268 | return False; | |
10269 | ||
10270 | elsif not Within_Init_Proc then | |
10271 | return True; | |
10272 | ||
fbf5a39b | 10273 | elsif Is_Init_Proc (Entity (Name (N))) then |
996ae0b0 RK |
10274 | return False; |
10275 | ||
10276 | else | |
10277 | return True; | |
10278 | end if; | |
10279 | end Reporting; | |
10280 | ||
10281 | -- Start of processing for Normalize_Actuals | |
10282 | ||
10283 | begin | |
10284 | if Is_Access_Type (S) then | |
10285 | ||
10286 | -- The name in the call is a function call that returns an access | |
10287 | -- to subprogram. The designated type has the list of formals. | |
10288 | ||
10289 | Formal := First_Formal (Designated_Type (S)); | |
10290 | else | |
10291 | Formal := First_Formal (S); | |
10292 | end if; | |
10293 | ||
10294 | while Present (Formal) loop | |
10295 | Formals_To_Match := Formals_To_Match + 1; | |
10296 | Next_Formal (Formal); | |
10297 | end loop; | |
10298 | ||
10299 | -- Find if there is a named association, and verify that no positional | |
10300 | -- associations appear after named ones. | |
10301 | ||
10302 | if Present (Actuals) then | |
10303 | Actual := First (Actuals); | |
10304 | end if; | |
10305 | ||
10306 | while Present (Actual) | |
10307 | and then Nkind (Actual) /= N_Parameter_Association | |
10308 | loop | |
10309 | Actuals_To_Match := Actuals_To_Match + 1; | |
10310 | Next (Actual); | |
10311 | end loop; | |
10312 | ||
10313 | if No (Actual) and Actuals_To_Match = Formals_To_Match then | |
10314 | ||
10315 | -- Most common case: positional notation, no defaults | |
10316 | ||
10317 | Success := True; | |
10318 | return; | |
10319 | ||
10320 | elsif Actuals_To_Match > Formals_To_Match then | |
10321 | ||
130c236a | 10322 | -- Too many actuals: will not work |
996ae0b0 RK |
10323 | |
10324 | if Reporting then | |
fbf5a39b AC |
10325 | if Is_Entity_Name (Name (N)) then |
10326 | Error_Msg_N ("too many arguments in call to&", Name (N)); | |
10327 | else | |
10328 | Error_Msg_N ("too many arguments in call", N); | |
10329 | end if; | |
996ae0b0 RK |
10330 | end if; |
10331 | ||
10332 | Success := False; | |
10333 | return; | |
10334 | end if; | |
10335 | ||
10336 | First_Named := Actual; | |
10337 | ||
10338 | while Present (Actual) loop | |
10339 | if Nkind (Actual) /= N_Parameter_Association then | |
10340 | Error_Msg_N | |
10341 | ("positional parameters not allowed after named ones", Actual); | |
10342 | Success := False; | |
10343 | return; | |
10344 | ||
10345 | else | |
10346 | Actuals_To_Match := Actuals_To_Match + 1; | |
10347 | end if; | |
10348 | ||
10349 | Next (Actual); | |
10350 | end loop; | |
10351 | ||
10352 | if Present (Actuals) then | |
10353 | Actual := First (Actuals); | |
10354 | end if; | |
10355 | ||
10356 | Formal := First_Formal (S); | |
996ae0b0 RK |
10357 | while Present (Formal) loop |
10358 | ||
7f0e4cdb BD |
10359 | -- Match the formals in order. If the corresponding actual is |
10360 | -- positional, nothing to do. Else scan the list of named actuals | |
10361 | -- to find the one with the right name. | |
996ae0b0 RK |
10362 | |
10363 | if Present (Actual) | |
10364 | and then Nkind (Actual) /= N_Parameter_Association | |
10365 | then | |
10366 | Next (Actual); | |
10367 | Actuals_To_Match := Actuals_To_Match - 1; | |
10368 | Formals_To_Match := Formals_To_Match - 1; | |
10369 | ||
10370 | else | |
10371 | -- For named parameters, search the list of actuals to find | |
10372 | -- one that matches the next formal name. | |
10373 | ||
10374 | Actual := First_Named; | |
10375 | Found := False; | |
996ae0b0 RK |
10376 | while Present (Actual) loop |
10377 | if Chars (Selector_Name (Actual)) = Chars (Formal) then | |
10378 | Found := True; | |
10379 | Chain (Actual); | |
10380 | Actuals_To_Match := Actuals_To_Match - 1; | |
10381 | Formals_To_Match := Formals_To_Match - 1; | |
10382 | exit; | |
10383 | end if; | |
10384 | ||
10385 | Next (Actual); | |
10386 | end loop; | |
10387 | ||
10388 | if not Found then | |
10389 | if Ekind (Formal) /= E_In_Parameter | |
10390 | or else No (Default_Value (Formal)) | |
10391 | then | |
10392 | if Reporting then | |
fbf5a39b AC |
10393 | if (Comes_From_Source (S) |
10394 | or else Sloc (S) = Standard_Location) | |
996ae0b0 RK |
10395 | and then Is_Overloadable (S) |
10396 | then | |
18c0ecbe AC |
10397 | if No (Actuals) |
10398 | and then | |
10399 | (Nkind (Parent (N)) = N_Procedure_Call_Statement | |
10400 | or else | |
10401 | (Nkind (Parent (N)) = N_Function_Call | |
10402 | or else | |
523456db AC |
10403 | Nkind (Parent (N)) = N_Parameter_Association)) |
10404 | and then Ekind (S) /= E_Function | |
18c0ecbe AC |
10405 | then |
10406 | Set_Etype (N, Etype (S)); | |
10407 | else | |
10408 | Error_Msg_Name_1 := Chars (S); | |
10409 | Error_Msg_Sloc := Sloc (S); | |
10410 | Error_Msg_NE | |
10411 | ("missing argument for parameter & " & | |
10412 | "in call to % declared #", N, Formal); | |
10413 | end if; | |
fbf5a39b AC |
10414 | |
10415 | elsif Is_Overloadable (S) then | |
10416 | Error_Msg_Name_1 := Chars (S); | |
10417 | ||
18c0ecbe AC |
10418 | -- Point to type derivation that generated the |
10419 | -- operation. | |
fbf5a39b AC |
10420 | |
10421 | Error_Msg_Sloc := Sloc (Parent (S)); | |
10422 | ||
10423 | Error_Msg_NE | |
10424 | ("missing argument for parameter & " & | |
10425 | "in call to % (inherited) #", N, Formal); | |
10426 | ||
996ae0b0 RK |
10427 | else |
10428 | Error_Msg_NE | |
10429 | ("missing argument for parameter &", N, Formal); | |
10430 | end if; | |
10431 | end if; | |
10432 | ||
10433 | Success := False; | |
10434 | return; | |
10435 | ||
10436 | else | |
10437 | Formals_To_Match := Formals_To_Match - 1; | |
10438 | end if; | |
10439 | end if; | |
10440 | end if; | |
10441 | ||
10442 | Next_Formal (Formal); | |
10443 | end loop; | |
10444 | ||
195b0505 | 10445 | if Formals_To_Match = 0 and then Actuals_To_Match = 0 then |
996ae0b0 RK |
10446 | Success := True; |
10447 | return; | |
10448 | ||
10449 | else | |
10450 | if Reporting then | |
10451 | ||
10452 | -- Find some superfluous named actual that did not get | |
10453 | -- attached to the list of associations. | |
10454 | ||
10455 | Actual := First (Actuals); | |
996ae0b0 | 10456 | while Present (Actual) loop |
996ae0b0 RK |
10457 | if Nkind (Actual) = N_Parameter_Association |
10458 | and then Actual /= Last | |
10459 | and then No (Next_Named_Actual (Actual)) | |
10460 | then | |
fbf5a39b AC |
10461 | Error_Msg_N ("unmatched actual & in call", |
10462 | Selector_Name (Actual)); | |
996ae0b0 RK |
10463 | exit; |
10464 | end if; | |
10465 | ||
10466 | Next (Actual); | |
10467 | end loop; | |
10468 | end if; | |
10469 | ||
10470 | Success := False; | |
10471 | return; | |
10472 | end if; | |
10473 | end Normalize_Actuals; | |
10474 | ||
10475 | -------------------------------- | |
10476 | -- Note_Possible_Modification -- | |
10477 | -------------------------------- | |
10478 | ||
ce4a6e84 | 10479 | procedure Note_Possible_Modification (N : Node_Id; Sure : Boolean) is |
30c20106 AC |
10480 | Modification_Comes_From_Source : constant Boolean := |
10481 | Comes_From_Source (Parent (N)); | |
10482 | ||
996ae0b0 RK |
10483 | Ent : Entity_Id; |
10484 | Exp : Node_Id; | |
10485 | ||
996ae0b0 RK |
10486 | begin |
10487 | -- Loop to find referenced entity, if there is one | |
10488 | ||
10489 | Exp := N; | |
10490 | loop | |
af152989 | 10491 | <<Continue>> |
30c20106 AC |
10492 | Ent := Empty; |
10493 | ||
10494 | if Is_Entity_Name (Exp) then | |
10495 | Ent := Entity (Exp); | |
10496 | ||
482a63fb ES |
10497 | -- If the entity is missing, it is an undeclared identifier, |
10498 | -- and there is nothing to annotate. | |
10499 | ||
10500 | if No (Ent) then | |
10501 | return; | |
10502 | end if; | |
10503 | ||
30c20106 AC |
10504 | elsif Nkind (Exp) = N_Explicit_Dereference then |
10505 | declare | |
10506 | P : constant Node_Id := Prefix (Exp); | |
10507 | ||
10508 | begin | |
10509 | if Nkind (P) = N_Selected_Component | |
10510 | and then Present ( | |
10511 | Entry_Formal (Entity (Selector_Name (P)))) | |
10512 | then | |
10513 | -- Case of a reference to an entry formal | |
10514 | ||
10515 | Ent := Entry_Formal (Entity (Selector_Name (P))); | |
10516 | ||
10517 | elsif Nkind (P) = N_Identifier | |
10518 | and then Nkind (Parent (Entity (P))) = N_Object_Declaration | |
10519 | and then Present (Expression (Parent (Entity (P)))) | |
10520 | and then Nkind (Expression (Parent (Entity (P)))) | |
10521 | = N_Reference | |
10522 | then | |
67ce0d7e RD |
10523 | -- Case of a reference to a value on which side effects have |
10524 | -- been removed. | |
30c20106 AC |
10525 | |
10526 | Exp := Prefix (Expression (Parent (Entity (P)))); | |
b8dc622e | 10527 | goto Continue; |
30c20106 AC |
10528 | |
10529 | else | |
10530 | return; | |
10531 | ||
10532 | end if; | |
10533 | end; | |
10534 | ||
10535 | elsif Nkind (Exp) = N_Type_Conversion | |
10536 | or else Nkind (Exp) = N_Unchecked_Type_Conversion | |
10537 | then | |
10538 | Exp := Expression (Exp); | |
b8dc622e | 10539 | goto Continue; |
996ae0b0 | 10540 | |
30c20106 AC |
10541 | elsif Nkind (Exp) = N_Slice |
10542 | or else Nkind (Exp) = N_Indexed_Component | |
10543 | or else Nkind (Exp) = N_Selected_Component | |
996ae0b0 | 10544 | then |
30c20106 | 10545 | Exp := Prefix (Exp); |
b8dc622e | 10546 | goto Continue; |
30c20106 AC |
10547 | |
10548 | else | |
10549 | return; | |
fbf5a39b | 10550 | end if; |
996ae0b0 | 10551 | |
fbf5a39b AC |
10552 | -- Now look for entity being referenced |
10553 | ||
30c20106 | 10554 | if Present (Ent) then |
af152989 AC |
10555 | if Is_Object (Ent) then |
10556 | if Comes_From_Source (Exp) | |
10557 | or else Modification_Comes_From_Source | |
10558 | then | |
0877856b AC |
10559 | -- Give warning if pragma unmodified given and we are |
10560 | -- sure this is a modification. | |
10561 | ||
10562 | if Has_Pragma_Unmodified (Ent) and then Sure then | |
ed2233dc | 10563 | Error_Msg_NE ("?pragma Unmodified given for &!", N, Ent); |
9d77af56 RD |
10564 | end if; |
10565 | ||
af152989 AC |
10566 | Set_Never_Set_In_Source (Ent, False); |
10567 | end if; | |
10568 | ||
b8dc622e JM |
10569 | Set_Is_True_Constant (Ent, False); |
10570 | Set_Current_Value (Ent, Empty); | |
10571 | Set_Is_Known_Null (Ent, False); | |
fbf5a39b AC |
10572 | |
10573 | if not Can_Never_Be_Null (Ent) then | |
10574 | Set_Is_Known_Non_Null (Ent, False); | |
10575 | end if; | |
10576 | ||
b8dc622e JM |
10577 | -- Follow renaming chain |
10578 | ||
af152989 AC |
10579 | if (Ekind (Ent) = E_Variable or else Ekind (Ent) = E_Constant) |
10580 | and then Present (Renamed_Object (Ent)) | |
10581 | then | |
10582 | Exp := Renamed_Object (Ent); | |
10583 | goto Continue; | |
10584 | end if; | |
996ae0b0 | 10585 | |
1735e55d AC |
10586 | -- Generate a reference only if the assignment comes from |
10587 | -- source. This excludes, for example, calls to a dispatching | |
10588 | -- assignment operation when the left-hand side is tagged. | |
10589 | ||
10590 | if Modification_Comes_From_Source then | |
10591 | Generate_Reference (Ent, Exp, 'm'); | |
d347f572 AC |
10592 | |
10593 | -- If the target of the assignment is the bound variable | |
10594 | -- in an iterator, indicate that the corresponding array | |
10595 | -- or container is also modified. | |
10596 | ||
10597 | if Ada_Version >= Ada_2012 | |
10598 | and then | |
10599 | Nkind (Parent (Ent)) = N_Iterator_Specification | |
10600 | then | |
10601 | declare | |
10602 | Domain : constant Node_Id := Name (Parent (Ent)); | |
10603 | ||
10604 | begin | |
10605 | -- TBD : in the full version of the construct, the | |
10606 | -- domain of iteration can be given by an expression. | |
10607 | ||
10608 | if Is_Entity_Name (Domain) then | |
10609 | Generate_Reference (Entity (Domain), Exp, 'm'); | |
10610 | Set_Is_True_Constant (Entity (Domain), False); | |
10611 | Set_Never_Set_In_Source (Entity (Domain), False); | |
10612 | end if; | |
10613 | end; | |
10614 | end if; | |
1735e55d | 10615 | end if; |
f377c995 HK |
10616 | |
10617 | Check_Nested_Access (Ent); | |
996ae0b0 | 10618 | end if; |
af152989 AC |
10619 | |
10620 | Kill_Checks (Ent); | |
ce4a6e84 RD |
10621 | |
10622 | -- If we are sure this is a modification from source, and we know | |
10623 | -- this modifies a constant, then give an appropriate warning. | |
10624 | ||
10625 | if Overlays_Constant (Ent) | |
10626 | and then Modification_Comes_From_Source | |
10627 | and then Sure | |
10628 | then | |
10629 | declare | |
10630 | A : constant Node_Id := Address_Clause (Ent); | |
10631 | begin | |
10632 | if Present (A) then | |
10633 | declare | |
10634 | Exp : constant Node_Id := Expression (A); | |
10635 | begin | |
10636 | if Nkind (Exp) = N_Attribute_Reference | |
10637 | and then Attribute_Name (Exp) = Name_Address | |
10638 | and then Is_Entity_Name (Prefix (Exp)) | |
10639 | then | |
10640 | Error_Msg_Sloc := Sloc (A); | |
ed2233dc | 10641 | Error_Msg_NE |
ce4a6e84 RD |
10642 | ("constant& may be modified via address clause#?", |
10643 | N, Entity (Prefix (Exp))); | |
10644 | end if; | |
10645 | end; | |
10646 | end if; | |
10647 | end; | |
10648 | end if; | |
10649 | ||
af152989 | 10650 | return; |
996ae0b0 RK |
10651 | end if; |
10652 | end loop; | |
10653 | end Note_Possible_Modification; | |
10654 | ||
10655 | ------------------------- | |
10656 | -- Object_Access_Level -- | |
10657 | ------------------------- | |
10658 | ||
10659 | function Object_Access_Level (Obj : Node_Id) return Uint is | |
10660 | E : Entity_Id; | |
10661 | ||
7f0e4cdb BD |
10662 | -- Returns the static accessibility level of the view denoted by Obj. Note |
10663 | -- that the value returned is the result of a call to Scope_Depth. Only | |
10664 | -- scope depths associated with dynamic scopes can actually be returned. | |
10665 | -- Since only relative levels matter for accessibility checking, the fact | |
10666 | -- that the distance between successive levels of accessibility is not | |
10667 | -- always one is immaterial (invariant: if level(E2) is deeper than | |
10668 | -- level(E1), then Scope_Depth(E1) < Scope_Depth(E2)). | |
996ae0b0 | 10669 | |
9e87a68d | 10670 | function Reference_To (Obj : Node_Id) return Node_Id; |
7f0e4cdb BD |
10671 | -- An explicit dereference is created when removing side-effects from |
10672 | -- expressions for constraint checking purposes. In this case a local | |
10673 | -- access type is created for it. The correct access level is that of | |
10674 | -- the original source node. We detect this case by noting that the | |
10675 | -- prefix of the dereference is created by an object declaration whose | |
10676 | -- initial expression is a reference. | |
9e87a68d ES |
10677 | |
10678 | ------------------ | |
10679 | -- Reference_To -- | |
10680 | ------------------ | |
10681 | ||
10682 | function Reference_To (Obj : Node_Id) return Node_Id is | |
10683 | Pref : constant Node_Id := Prefix (Obj); | |
10684 | begin | |
10685 | if Is_Entity_Name (Pref) | |
10686 | and then Nkind (Parent (Entity (Pref))) = N_Object_Declaration | |
10687 | and then Present (Expression (Parent (Entity (Pref)))) | |
10688 | and then Nkind (Expression (Parent (Entity (Pref)))) = N_Reference | |
10689 | then | |
10690 | return (Prefix (Expression (Parent (Entity (Pref))))); | |
10691 | else | |
10692 | return Empty; | |
10693 | end if; | |
10694 | end Reference_To; | |
10695 | ||
10696 | -- Start of processing for Object_Access_Level | |
10697 | ||
996ae0b0 | 10698 | begin |
dfbcb149 HK |
10699 | if Nkind (Obj) = N_Defining_Identifier |
10700 | or else Is_Entity_Name (Obj) | |
10701 | then | |
10702 | if Nkind (Obj) = N_Defining_Identifier then | |
10703 | E := Obj; | |
10704 | else | |
10705 | E := Entity (Obj); | |
10706 | end if; | |
996ae0b0 | 10707 | |
ce4a6e84 RD |
10708 | if Is_Prival (E) then |
10709 | E := Prival_Link (E); | |
10710 | end if; | |
10711 | ||
7f0e4cdb BD |
10712 | -- If E is a type then it denotes a current instance. For this case |
10713 | -- we add one to the normal accessibility level of the type to ensure | |
10714 | -- that current instances are treated as always being deeper than | |
10715 | -- than the level of any visible named access type (see 3.10.2(21)). | |
996ae0b0 RK |
10716 | |
10717 | if Is_Type (E) then | |
10718 | return Type_Access_Level (E) + 1; | |
10719 | ||
10720 | elsif Present (Renamed_Object (E)) then | |
10721 | return Object_Access_Level (Renamed_Object (E)); | |
10722 | ||
10723 | -- Similarly, if E is a component of the current instance of a | |
10724 | -- protected type, any instance of it is assumed to be at a deeper | |
10725 | -- level than the type. For a protected object (whose type is an | |
10726 | -- anonymous protected type) its components are at the same level | |
10727 | -- as the type itself. | |
10728 | ||
10729 | elsif not Is_Overloadable (E) | |
10730 | and then Ekind (Scope (E)) = E_Protected_Type | |
10731 | and then Comes_From_Source (Scope (E)) | |
10732 | then | |
10733 | return Type_Access_Level (Scope (E)) + 1; | |
10734 | ||
10735 | else | |
10736 | return Scope_Depth (Enclosing_Dynamic_Scope (E)); | |
10737 | end if; | |
10738 | ||
10739 | elsif Nkind (Obj) = N_Selected_Component then | |
10740 | if Is_Access_Type (Etype (Prefix (Obj))) then | |
10741 | return Type_Access_Level (Etype (Prefix (Obj))); | |
10742 | else | |
10743 | return Object_Access_Level (Prefix (Obj)); | |
10744 | end if; | |
10745 | ||
10746 | elsif Nkind (Obj) = N_Indexed_Component then | |
10747 | if Is_Access_Type (Etype (Prefix (Obj))) then | |
10748 | return Type_Access_Level (Etype (Prefix (Obj))); | |
10749 | else | |
10750 | return Object_Access_Level (Prefix (Obj)); | |
10751 | end if; | |
10752 | ||
10753 | elsif Nkind (Obj) = N_Explicit_Dereference then | |
10754 | ||
7f0e4cdb BD |
10755 | -- If the prefix is a selected access discriminant then we make a |
10756 | -- recursive call on the prefix, which will in turn check the level | |
10757 | -- of the prefix object of the selected discriminant. | |
996ae0b0 RK |
10758 | |
10759 | if Nkind (Prefix (Obj)) = N_Selected_Component | |
10760 | and then Ekind (Etype (Prefix (Obj))) = E_Anonymous_Access_Type | |
10761 | and then | |
10762 | Ekind (Entity (Selector_Name (Prefix (Obj)))) = E_Discriminant | |
10763 | then | |
10764 | return Object_Access_Level (Prefix (Obj)); | |
9e87a68d ES |
10765 | |
10766 | elsif not (Comes_From_Source (Obj)) then | |
10767 | declare | |
10768 | Ref : constant Node_Id := Reference_To (Obj); | |
10769 | begin | |
10770 | if Present (Ref) then | |
10771 | return Object_Access_Level (Ref); | |
10772 | else | |
10773 | return Type_Access_Level (Etype (Prefix (Obj))); | |
10774 | end if; | |
10775 | end; | |
10776 | ||
996ae0b0 RK |
10777 | else |
10778 | return Type_Access_Level (Etype (Prefix (Obj))); | |
10779 | end if; | |
10780 | ||
fbf5a39b AC |
10781 | elsif Nkind (Obj) = N_Type_Conversion |
10782 | or else Nkind (Obj) = N_Unchecked_Type_Conversion | |
10783 | then | |
996ae0b0 RK |
10784 | return Object_Access_Level (Expression (Obj)); |
10785 | ||
996ae0b0 | 10786 | elsif Nkind (Obj) = N_Function_Call then |
9f5b6c7f AC |
10787 | |
10788 | -- Function results are objects, so we get either the access level of | |
10789 | -- the function or, in the case of an indirect call, the level of the | |
10790 | -- access-to-subprogram type. (This code is used for Ada 95, but it | |
10791 | -- looks wrong, because it seems that we should be checking the level | |
10792 | -- of the call itself, even for Ada 95. However, using the Ada 2005 | |
10793 | -- version of the code causes regressions in several tests that are | |
10794 | -- compiled with -gnat95. ???) | |
10795 | ||
0791fbe9 | 10796 | if Ada_Version < Ada_2005 then |
9f5b6c7f AC |
10797 | if Is_Entity_Name (Name (Obj)) then |
10798 | return Subprogram_Access_Level (Entity (Name (Obj))); | |
10799 | else | |
10800 | return Type_Access_Level (Etype (Prefix (Name (Obj)))); | |
10801 | end if; | |
10802 | ||
10803 | -- For Ada 2005, the level of the result object of a function call is | |
10804 | -- defined to be the level of the call's innermost enclosing master. | |
10805 | -- We determine that by querying the depth of the innermost enclosing | |
10806 | -- dynamic scope. | |
10807 | ||
996ae0b0 | 10808 | else |
9f5b6c7f AC |
10809 | Return_Master_Scope_Depth_Of_Call : declare |
10810 | ||
10811 | function Innermost_Master_Scope_Depth | |
10812 | (N : Node_Id) return Uint; | |
10813 | -- Returns the scope depth of the given node's innermost | |
10814 | -- enclosing dynamic scope (effectively the accessibility | |
10815 | -- level of the innermost enclosing master). | |
10816 | ||
10817 | ---------------------------------- | |
10818 | -- Innermost_Master_Scope_Depth -- | |
10819 | ---------------------------------- | |
10820 | ||
10821 | function Innermost_Master_Scope_Depth | |
10822 | (N : Node_Id) return Uint | |
10823 | is | |
10824 | Node_Par : Node_Id := Parent (N); | |
10825 | ||
10826 | begin | |
10827 | -- Locate the nearest enclosing node (by traversing Parents) | |
10828 | -- that Defining_Entity can be applied to, and return the | |
10829 | -- depth of that entity's nearest enclosing dynamic scope. | |
10830 | ||
10831 | while Present (Node_Par) loop | |
10832 | case Nkind (Node_Par) is | |
10833 | when N_Component_Declaration | | |
10834 | N_Entry_Declaration | | |
10835 | N_Formal_Object_Declaration | | |
10836 | N_Formal_Type_Declaration | | |
10837 | N_Full_Type_Declaration | | |
10838 | N_Incomplete_Type_Declaration | | |
10839 | N_Loop_Parameter_Specification | | |
10840 | N_Object_Declaration | | |
10841 | N_Protected_Type_Declaration | | |
10842 | N_Private_Extension_Declaration | | |
10843 | N_Private_Type_Declaration | | |
10844 | N_Subtype_Declaration | | |
10845 | N_Function_Specification | | |
10846 | N_Procedure_Specification | | |
10847 | N_Task_Type_Declaration | | |
10848 | N_Body_Stub | | |
10849 | N_Generic_Instantiation | | |
10850 | N_Proper_Body | | |
10851 | N_Implicit_Label_Declaration | | |
10852 | N_Package_Declaration | | |
10853 | N_Single_Task_Declaration | | |
10854 | N_Subprogram_Declaration | | |
10855 | N_Generic_Declaration | | |
10856 | N_Renaming_Declaration | | |
10857 | N_Block_Statement | | |
10858 | N_Formal_Subprogram_Declaration | | |
10859 | N_Abstract_Subprogram_Declaration | | |
10860 | N_Entry_Body | | |
10861 | N_Exception_Declaration | | |
10862 | N_Formal_Package_Declaration | | |
10863 | N_Number_Declaration | | |
10864 | N_Package_Specification | | |
10865 | N_Parameter_Specification | | |
10866 | N_Single_Protected_Declaration | | |
10867 | N_Subunit => | |
10868 | ||
10869 | return Scope_Depth | |
10870 | (Nearest_Dynamic_Scope | |
10871 | (Defining_Entity (Node_Par))); | |
10872 | ||
10873 | when others => | |
10874 | null; | |
10875 | end case; | |
10876 | ||
10877 | Node_Par := Parent (Node_Par); | |
10878 | end loop; | |
10879 | ||
10880 | pragma Assert (False); | |
10881 | ||
10882 | -- Should never reach the following return | |
10883 | ||
10884 | return Scope_Depth (Current_Scope) + 1; | |
10885 | end Innermost_Master_Scope_Depth; | |
10886 | ||
10887 | -- Start of processing for Return_Master_Scope_Depth_Of_Call | |
10888 | ||
10889 | begin | |
10890 | return Innermost_Master_Scope_Depth (Obj); | |
10891 | end Return_Master_Scope_Depth_Of_Call; | |
996ae0b0 RK |
10892 | end if; |
10893 | ||
10894 | -- For convenience we handle qualified expressions, even though | |
10895 | -- they aren't technically object names. | |
10896 | ||
10897 | elsif Nkind (Obj) = N_Qualified_Expression then | |
10898 | return Object_Access_Level (Expression (Obj)); | |
10899 | ||
10900 | -- Otherwise return the scope level of Standard. | |
10901 | -- (If there are cases that fall through | |
10902 | -- to this point they will be treated as | |
10903 | -- having global accessibility for now. ???) | |
10904 | ||
10905 | else | |
10906 | return Scope_Depth (Standard_Standard); | |
10907 | end if; | |
10908 | end Object_Access_Level; | |
10909 | ||
ea034236 AC |
10910 | -------------------------------------- |
10911 | -- Original_Corresponding_Operation -- | |
10912 | -------------------------------------- | |
10913 | ||
10914 | function Original_Corresponding_Operation (S : Entity_Id) return Entity_Id | |
10915 | is | |
10916 | Typ : constant Entity_Id := Find_Dispatching_Type (S); | |
10917 | ||
10918 | begin | |
10919 | -- If S is an inherited primitive S2 the original corresponding | |
10920 | -- operation of S is the original corresponding operation of S2 | |
10921 | ||
10922 | if Present (Alias (S)) | |
10923 | and then Find_Dispatching_Type (Alias (S)) /= Typ | |
10924 | then | |
10925 | return Original_Corresponding_Operation (Alias (S)); | |
10926 | ||
308e6f3a | 10927 | -- If S overrides an inherited subprogram S2 the original corresponding |
ea034236 AC |
10928 | -- operation of S is the original corresponding operation of S2 |
10929 | ||
038140ed | 10930 | elsif Present (Overridden_Operation (S)) then |
ea034236 AC |
10931 | return Original_Corresponding_Operation (Overridden_Operation (S)); |
10932 | ||
10933 | -- otherwise it is S itself | |
10934 | ||
10935 | else | |
10936 | return S; | |
10937 | end if; | |
10938 | end Original_Corresponding_Operation; | |
10939 | ||
996ae0b0 RK |
10940 | ----------------------- |
10941 | -- Private_Component -- | |
10942 | ----------------------- | |
10943 | ||
10944 | function Private_Component (Type_Id : Entity_Id) return Entity_Id is | |
10945 | Ancestor : constant Entity_Id := Base_Type (Type_Id); | |
10946 | ||
10947 | function Trace_Components | |
10948 | (T : Entity_Id; | |
fbf5a39b | 10949 | Check : Boolean) return Entity_Id; |
996ae0b0 RK |
10950 | -- Recursive function that does the work, and checks against circular |
10951 | -- definition for each subcomponent type. | |
10952 | ||
10953 | ---------------------- | |
10954 | -- Trace_Components -- | |
10955 | ---------------------- | |
10956 | ||
10957 | function Trace_Components | |
10958 | (T : Entity_Id; | |
10959 | Check : Boolean) return Entity_Id | |
10960 | is | |
10961 | Btype : constant Entity_Id := Base_Type (T); | |
10962 | Component : Entity_Id; | |
10963 | P : Entity_Id; | |
10964 | Candidate : Entity_Id := Empty; | |
10965 | ||
10966 | begin | |
10967 | if Check and then Btype = Ancestor then | |
10968 | Error_Msg_N ("circular type definition", Type_Id); | |
10969 | return Any_Type; | |
10970 | end if; | |
10971 | ||
10972 | if Is_Private_Type (Btype) | |
10973 | and then not Is_Generic_Type (Btype) | |
10974 | then | |
246d2ceb AC |
10975 | if Present (Full_View (Btype)) |
10976 | and then Is_Record_Type (Full_View (Btype)) | |
10977 | and then not Is_Frozen (Btype) | |
10978 | then | |
7f0e4cdb BD |
10979 | -- To indicate that the ancestor depends on a private type, the |
10980 | -- current Btype is sufficient. However, to check for circular | |
10981 | -- definition we must recurse on the full view. | |
246d2ceb AC |
10982 | |
10983 | Candidate := Trace_Components (Full_View (Btype), True); | |
10984 | ||
10985 | if Candidate = Any_Type then | |
10986 | return Any_Type; | |
10987 | else | |
10988 | return Btype; | |
10989 | end if; | |
10990 | ||
10991 | else | |
10992 | return Btype; | |
10993 | end if; | |
996ae0b0 RK |
10994 | |
10995 | elsif Is_Array_Type (Btype) then | |
10996 | return Trace_Components (Component_Type (Btype), True); | |
10997 | ||
10998 | elsif Is_Record_Type (Btype) then | |
10999 | Component := First_Entity (Btype); | |
276e7ed0 AC |
11000 | while Present (Component) |
11001 | and then Comes_From_Source (Component) | |
11002 | loop | |
130c236a | 11003 | -- Skip anonymous types generated by constrained components |
996ae0b0 RK |
11004 | |
11005 | if not Is_Type (Component) then | |
11006 | P := Trace_Components (Etype (Component), True); | |
11007 | ||
11008 | if Present (P) then | |
11009 | if P = Any_Type then | |
11010 | return P; | |
11011 | else | |
11012 | Candidate := P; | |
11013 | end if; | |
11014 | end if; | |
11015 | end if; | |
11016 | ||
11017 | Next_Entity (Component); | |
11018 | end loop; | |
11019 | ||
11020 | return Candidate; | |
11021 | ||
11022 | else | |
11023 | return Empty; | |
11024 | end if; | |
11025 | end Trace_Components; | |
11026 | ||
11027 | -- Start of processing for Private_Component | |
11028 | ||
11029 | begin | |
11030 | return Trace_Components (Type_Id, False); | |
11031 | end Private_Component; | |
11032 | ||
ce2b6ba5 JM |
11033 | --------------------------- |
11034 | -- Primitive_Names_Match -- | |
11035 | --------------------------- | |
11036 | ||
11037 | function Primitive_Names_Match (E1, E2 : Entity_Id) return Boolean is | |
11038 | ||
11039 | function Non_Internal_Name (E : Entity_Id) return Name_Id; | |
11040 | -- Given an internal name, returns the corresponding non-internal name | |
11041 | ||
11042 | ------------------------ | |
11043 | -- Non_Internal_Name -- | |
11044 | ------------------------ | |
11045 | ||
11046 | function Non_Internal_Name (E : Entity_Id) return Name_Id is | |
11047 | begin | |
11048 | Get_Name_String (Chars (E)); | |
11049 | Name_Len := Name_Len - 1; | |
11050 | return Name_Find; | |
11051 | end Non_Internal_Name; | |
11052 | ||
11053 | -- Start of processing for Primitive_Names_Match | |
11054 | ||
11055 | begin | |
11056 | pragma Assert (Present (E1) and then Present (E2)); | |
11057 | ||
11058 | return Chars (E1) = Chars (E2) | |
11059 | or else | |
11060 | (not Is_Internal_Name (Chars (E1)) | |
11061 | and then Is_Internal_Name (Chars (E2)) | |
11062 | and then Non_Internal_Name (E2) = Chars (E1)) | |
11063 | or else | |
11064 | (not Is_Internal_Name (Chars (E2)) | |
11065 | and then Is_Internal_Name (Chars (E1)) | |
11066 | and then Non_Internal_Name (E1) = Chars (E2)) | |
11067 | or else | |
11068 | (Is_Predefined_Dispatching_Operation (E1) | |
11069 | and then Is_Predefined_Dispatching_Operation (E2) | |
11070 | and then Same_TSS (E1, E2)) | |
11071 | or else | |
11072 | (Is_Init_Proc (E1) and then Is_Init_Proc (E2)); | |
11073 | end Primitive_Names_Match; | |
11074 | ||
996ae0b0 RK |
11075 | ----------------------- |
11076 | -- Process_End_Label -- | |
11077 | ----------------------- | |
11078 | ||
07fc65c4 GB |
11079 | procedure Process_End_Label |
11080 | (N : Node_Id; | |
11081 | Typ : Character; | |
23685ae6 | 11082 | Ent : Entity_Id) |
07fc65c4 | 11083 | is |
996ae0b0 RK |
11084 | Loc : Source_Ptr; |
11085 | Nam : Node_Id; | |
7f0e4cdb | 11086 | Scop : Entity_Id; |
996ae0b0 RK |
11087 | |
11088 | Label_Ref : Boolean; | |
11089 | -- Set True if reference to end label itself is required | |
11090 | ||
11091 | Endl : Node_Id; | |
7f0e4cdb BD |
11092 | -- Gets set to the operator symbol or identifier that references the |
11093 | -- entity Ent. For the child unit case, this is the identifier from the | |
11094 | -- designator. For other cases, this is simply Endl. | |
996ae0b0 | 11095 | |
7f0e4cdb BD |
11096 | procedure Generate_Parent_Ref (N : Node_Id; E : Entity_Id); |
11097 | -- N is an identifier node that appears as a parent unit reference in | |
11098 | -- the case where Ent is a child unit. This procedure generates an | |
11099 | -- appropriate cross-reference entry. E is the corresponding entity. | |
996ae0b0 | 11100 | |
07fc65c4 GB |
11101 | ------------------------- |
11102 | -- Generate_Parent_Ref -- | |
11103 | ------------------------- | |
11104 | ||
7f0e4cdb | 11105 | procedure Generate_Parent_Ref (N : Node_Id; E : Entity_Id) is |
996ae0b0 | 11106 | begin |
7f0e4cdb | 11107 | -- If names do not match, something weird, skip reference |
996ae0b0 | 11108 | |
7f0e4cdb | 11109 | if Chars (E) = Chars (N) then |
996ae0b0 | 11110 | |
7f0e4cdb BD |
11111 | -- Generate the reference. We do NOT consider this as a reference |
11112 | -- for unreferenced symbol purposes. | |
996ae0b0 | 11113 | |
7f0e4cdb BD |
11114 | Generate_Reference (E, N, 'r', Set_Ref => False, Force => True); |
11115 | ||
11116 | if Style_Check then | |
11117 | Style.Check_Identifier (N, E); | |
11118 | end if; | |
11119 | end if; | |
996ae0b0 RK |
11120 | end Generate_Parent_Ref; |
11121 | ||
11122 | -- Start of processing for Process_End_Label | |
11123 | ||
11124 | begin | |
7f0e4cdb BD |
11125 | -- If no node, ignore. This happens in some error situations, and |
11126 | -- also for some internally generated structures where no end label | |
11127 | -- references are required in any case. | |
996ae0b0 RK |
11128 | |
11129 | if No (N) then | |
11130 | return; | |
11131 | end if; | |
11132 | ||
11133 | -- Nothing to do if no End_Label, happens for internally generated | |
7f0e4cdb BD |
11134 | -- constructs where we don't want an end label reference anyway. Also |
11135 | -- nothing to do if Endl is a string literal, which means there was | |
11136 | -- some prior error (bad operator symbol) | |
996ae0b0 RK |
11137 | |
11138 | Endl := End_Label (N); | |
11139 | ||
2b881d53 | 11140 | if No (Endl) or else Nkind (Endl) = N_String_Literal then |
996ae0b0 RK |
11141 | return; |
11142 | end if; | |
11143 | ||
11144 | -- Reference node is not in extended main source unit | |
11145 | ||
11146 | if not In_Extended_Main_Source_Unit (N) then | |
11147 | ||
7f0e4cdb BD |
11148 | -- Generally we do not collect references except for the extended |
11149 | -- main source unit. The one exception is the 'e' entry for a | |
11150 | -- package spec, where it is useful for a client to have the | |
11151 | -- ending information to define scopes. | |
996ae0b0 RK |
11152 | |
11153 | if Typ /= 'e' then | |
11154 | return; | |
11155 | ||
11156 | else | |
11157 | Label_Ref := False; | |
11158 | ||
7f0e4cdb BD |
11159 | -- For this case, we can ignore any parent references, but we |
11160 | -- need the package name itself for the 'e' entry. | |
996ae0b0 RK |
11161 | |
11162 | if Nkind (Endl) = N_Designator then | |
11163 | Endl := Identifier (Endl); | |
11164 | end if; | |
11165 | end if; | |
11166 | ||
11167 | -- Reference is in extended main source unit | |
11168 | ||
11169 | else | |
11170 | Label_Ref := True; | |
11171 | ||
11172 | -- For designator, generate references for the parent entries | |
11173 | ||
11174 | if Nkind (Endl) = N_Designator then | |
11175 | ||
7f0e4cdb BD |
11176 | -- Generate references for the prefix if the END line comes from |
11177 | -- source (otherwise we do not need these references) We climb the | |
11178 | -- scope stack to find the expected entities. | |
996ae0b0 RK |
11179 | |
11180 | if Comes_From_Source (Endl) then | |
7f0e4cdb BD |
11181 | Nam := Name (Endl); |
11182 | Scop := Current_Scope; | |
996ae0b0 | 11183 | while Nkind (Nam) = N_Selected_Component loop |
7f0e4cdb BD |
11184 | Scop := Scope (Scop); |
11185 | exit when No (Scop); | |
11186 | Generate_Parent_Ref (Selector_Name (Nam), Scop); | |
996ae0b0 RK |
11187 | Nam := Prefix (Nam); |
11188 | end loop; | |
11189 | ||
7f0e4cdb BD |
11190 | if Present (Scop) then |
11191 | Generate_Parent_Ref (Nam, Scope (Scop)); | |
11192 | end if; | |
996ae0b0 RK |
11193 | end if; |
11194 | ||
11195 | Endl := Identifier (Endl); | |
11196 | end if; | |
11197 | end if; | |
11198 | ||
07fc65c4 GB |
11199 | -- If the end label is not for the given entity, then either we have |
11200 | -- some previous error, or this is a generic instantiation for which | |
11201 | -- we do not need to make a cross-reference in this case anyway. In | |
11202 | -- either case we simply ignore the call. | |
996ae0b0 | 11203 | |
07fc65c4 GB |
11204 | if Chars (Ent) /= Chars (Endl) then |
11205 | return; | |
996ae0b0 RK |
11206 | end if; |
11207 | ||
7f0e4cdb BD |
11208 | -- If label was really there, then generate a normal reference and then |
11209 | -- adjust the location in the end label to point past the name (which | |
11210 | -- should almost always be the semicolon). | |
996ae0b0 RK |
11211 | |
11212 | Loc := Sloc (Endl); | |
11213 | ||
11214 | if Comes_From_Source (Endl) then | |
11215 | ||
7f0e4cdb BD |
11216 | -- If a label reference is required, then do the style check and |
11217 | -- generate an l-type cross-reference entry for the label | |
996ae0b0 RK |
11218 | |
11219 | if Label_Ref then | |
fbf5a39b AC |
11220 | if Style_Check then |
11221 | Style.Check_Identifier (Endl, Ent); | |
11222 | end if; | |
7f0e4cdb | 11223 | |
07fc65c4 | 11224 | Generate_Reference (Ent, Endl, 'l', Set_Ref => False); |
996ae0b0 RK |
11225 | end if; |
11226 | ||
11227 | -- Set the location to point past the label (normally this will | |
11228 | -- mean the semicolon immediately following the label). This is | |
11229 | -- done for the sake of the 'e' or 't' entry generated below. | |
11230 | ||
11231 | Get_Decoded_Name_String (Chars (Endl)); | |
11232 | Set_Sloc (Endl, Sloc (Endl) + Source_Ptr (Name_Len)); | |
23685ae6 AC |
11233 | |
11234 | else | |
11235 | -- In SPARK mode, no missing label is allowed for packages and | |
11236 | -- subprogram bodies. Detect those cases by testing whether | |
11237 | -- Process_End_Label was called for a body (Typ = 't') or a package. | |
11238 | ||
24558db8 | 11239 | if Restriction_Check_Required (SPARK) |
23685ae6 AC |
11240 | and then (Typ = 't' or else Ekind (Ent) = E_Package) |
11241 | then | |
11242 | Error_Msg_Node_1 := Endl; | |
2ba431e5 | 11243 | Check_SPARK_Restriction ("`END &` required", Endl, Force => True); |
23685ae6 | 11244 | end if; |
996ae0b0 RK |
11245 | end if; |
11246 | ||
11247 | -- Now generate the e/t reference | |
11248 | ||
11249 | Generate_Reference (Ent, Endl, Typ, Set_Ref => False, Force => True); | |
11250 | ||
11251 | -- Restore Sloc, in case modified above, since we have an identifier | |
11252 | -- and the normal Sloc should be left set in the tree. | |
11253 | ||
11254 | Set_Sloc (Endl, Loc); | |
11255 | end Process_End_Label; | |
11256 | ||
93c3fca7 AC |
11257 | ------------------------------------ |
11258 | -- References_Generic_Formal_Type -- | |
11259 | ------------------------------------ | |
11260 | ||
11261 | function References_Generic_Formal_Type (N : Node_Id) return Boolean is | |
11262 | ||
11263 | function Process (N : Node_Id) return Traverse_Result; | |
11264 | -- Process one node in search for generic formal type | |
11265 | ||
11266 | ------------- | |
11267 | -- Process -- | |
11268 | ------------- | |
11269 | ||
11270 | function Process (N : Node_Id) return Traverse_Result is | |
11271 | begin | |
11272 | if Nkind (N) in N_Has_Entity then | |
11273 | declare | |
11274 | E : constant Entity_Id := Entity (N); | |
11275 | begin | |
11276 | if Present (E) then | |
11277 | if Is_Generic_Type (E) then | |
11278 | return Abandon; | |
11279 | elsif Present (Etype (E)) | |
11280 | and then Is_Generic_Type (Etype (E)) | |
11281 | then | |
11282 | return Abandon; | |
11283 | end if; | |
11284 | end if; | |
11285 | end; | |
11286 | end if; | |
11287 | ||
11288 | return Atree.OK; | |
11289 | end Process; | |
11290 | ||
11291 | function Traverse is new Traverse_Func (Process); | |
11292 | -- Traverse tree to look for generic type | |
11293 | ||
11294 | begin | |
11295 | if Inside_A_Generic then | |
11296 | return Traverse (N) = Abandon; | |
11297 | else | |
11298 | return False; | |
11299 | end if; | |
11300 | end References_Generic_Formal_Type; | |
11301 | ||
ce2b6ba5 JM |
11302 | -------------------- |
11303 | -- Remove_Homonym -- | |
11304 | -------------------- | |
11305 | ||
11306 | procedure Remove_Homonym (E : Entity_Id) is | |
11307 | Prev : Entity_Id := Empty; | |
11308 | H : Entity_Id; | |
11309 | ||
11310 | begin | |
11311 | if E = Current_Entity (E) then | |
11312 | if Present (Homonym (E)) then | |
11313 | Set_Current_Entity (Homonym (E)); | |
11314 | else | |
11315 | Set_Name_Entity_Id (Chars (E), Empty); | |
11316 | end if; | |
11317 | else | |
11318 | H := Current_Entity (E); | |
11319 | while Present (H) and then H /= E loop | |
11320 | Prev := H; | |
11321 | H := Homonym (H); | |
11322 | end loop; | |
11323 | ||
11324 | Set_Homonym (Prev, Homonym (E)); | |
11325 | end if; | |
11326 | end Remove_Homonym; | |
11327 | ||
fbf5a39b AC |
11328 | --------------------- |
11329 | -- Rep_To_Pos_Flag -- | |
11330 | --------------------- | |
11331 | ||
11332 | function Rep_To_Pos_Flag (E : Entity_Id; Loc : Source_Ptr) return Node_Id is | |
11333 | begin | |
aa720a54 AC |
11334 | return New_Occurrence_Of |
11335 | (Boolean_Literals (not Range_Checks_Suppressed (E)), Loc); | |
fbf5a39b AC |
11336 | end Rep_To_Pos_Flag; |
11337 | ||
11338 | -------------------- | |
11339 | -- Require_Entity -- | |
11340 | -------------------- | |
11341 | ||
11342 | procedure Require_Entity (N : Node_Id) is | |
11343 | begin | |
11344 | if Is_Entity_Name (N) and then No (Entity (N)) then | |
11345 | if Total_Errors_Detected /= 0 then | |
11346 | Set_Entity (N, Any_Id); | |
11347 | else | |
11348 | raise Program_Error; | |
11349 | end if; | |
11350 | end if; | |
11351 | end Require_Entity; | |
11352 | ||
996ae0b0 RK |
11353 | ------------------------------ |
11354 | -- Requires_Transient_Scope -- | |
11355 | ------------------------------ | |
11356 | ||
11357 | -- A transient scope is required when variable-sized temporaries are | |
11358 | -- allocated in the primary or secondary stack, or when finalization | |
15ce9ca2 | 11359 | -- actions must be generated before the next instruction. |
996ae0b0 RK |
11360 | |
11361 | function Requires_Transient_Scope (Id : Entity_Id) return Boolean is | |
11362 | Typ : constant Entity_Id := Underlying_Type (Id); | |
11363 | ||
15ce9ca2 AC |
11364 | -- Start of processing for Requires_Transient_Scope |
11365 | ||
996ae0b0 RK |
11366 | begin |
11367 | -- This is a private type which is not completed yet. This can only | |
11368 | -- happen in a default expression (of a formal parameter or of a | |
11369 | -- record component). Do not expand transient scope in this case | |
11370 | ||
11371 | if No (Typ) then | |
11372 | return False; | |
11373 | ||
15ce9ca2 AC |
11374 | -- Do not expand transient scope for non-existent procedure return |
11375 | ||
996ae0b0 RK |
11376 | elsif Typ = Standard_Void_Type then |
11377 | return False; | |
11378 | ||
15ce9ca2 | 11379 | -- Elementary types do not require a transient scope |
996ae0b0 | 11380 | |
15ce9ca2 AC |
11381 | elsif Is_Elementary_Type (Typ) then |
11382 | return False; | |
996ae0b0 | 11383 | |
15ce9ca2 AC |
11384 | -- Generally, indefinite subtypes require a transient scope, since the |
11385 | -- back end cannot generate temporaries, since this is not a valid type | |
11386 | -- for declaring an object. It might be possible to relax this in the | |
11387 | -- future, e.g. by declaring the maximum possible space for the type. | |
996ae0b0 | 11388 | |
15ce9ca2 | 11389 | elsif Is_Indefinite_Subtype (Typ) then |
996ae0b0 RK |
11390 | return True; |
11391 | ||
11392 | -- Functions returning tagged types may dispatch on result so their | |
11393 | -- returned value is allocated on the secondary stack. Controlled | |
11394 | -- type temporaries need finalization. | |
11395 | ||
11396 | elsif Is_Tagged_Type (Typ) | |
11397 | or else Has_Controlled_Component (Typ) | |
11398 | then | |
f377c995 | 11399 | return not Is_Value_Type (Typ); |
996ae0b0 | 11400 | |
523456db | 11401 | -- Record type |
15ce9ca2 AC |
11402 | |
11403 | elsif Is_Record_Type (Typ) then | |
f377c995 HK |
11404 | declare |
11405 | Comp : Entity_Id; | |
11406 | begin | |
11407 | Comp := First_Entity (Typ); | |
11408 | while Present (Comp) loop | |
11409 | if Ekind (Comp) = E_Component | |
11410 | and then Requires_Transient_Scope (Etype (Comp)) | |
11411 | then | |
11412 | return True; | |
11413 | else | |
11414 | Next_Entity (Comp); | |
11415 | end if; | |
11416 | end loop; | |
11417 | end; | |
523456db | 11418 | |
f377c995 | 11419 | return False; |
15ce9ca2 AC |
11420 | |
11421 | -- String literal types never require transient scope | |
11422 | ||
11423 | elsif Ekind (Typ) = E_String_Literal_Subtype then | |
11424 | return False; | |
11425 | ||
11426 | -- Array type. Note that we already know that this is a constrained | |
11427 | -- array, since unconstrained arrays will fail the indefinite test. | |
996ae0b0 RK |
11428 | |
11429 | elsif Is_Array_Type (Typ) then | |
996ae0b0 | 11430 | |
15ce9ca2 AC |
11431 | -- If component type requires a transient scope, the array does too |
11432 | ||
11433 | if Requires_Transient_Scope (Component_Type (Typ)) then | |
11434 | return True; | |
11435 | ||
e3c4580e EB |
11436 | -- Otherwise, we only need a transient scope if the size depends on |
11437 | -- the value of one or more discriminants. | |
15ce9ca2 AC |
11438 | |
11439 | else | |
e3c4580e | 11440 | return Size_Depends_On_Discriminant (Typ); |
15ce9ca2 AC |
11441 | end if; |
11442 | ||
11443 | -- All other cases do not require a transient scope | |
11444 | ||
11445 | else | |
11446 | return False; | |
11447 | end if; | |
996ae0b0 RK |
11448 | end Requires_Transient_Scope; |
11449 | ||
11450 | -------------------------- | |
11451 | -- Reset_Analyzed_Flags -- | |
11452 | -------------------------- | |
11453 | ||
11454 | procedure Reset_Analyzed_Flags (N : Node_Id) is | |
11455 | ||
9b0986f8 | 11456 | function Clear_Analyzed (N : Node_Id) return Traverse_Result; |
996ae0b0 RK |
11457 | -- Function used to reset Analyzed flags in tree. Note that we do |
11458 | -- not reset Analyzed flags in entities, since there is no need to | |
f3d57416 | 11459 | -- reanalyze entities, and indeed, it is wrong to do so, since it |
996ae0b0 RK |
11460 | -- can result in generating auxiliary stuff more than once. |
11461 | ||
fbf5a39b AC |
11462 | -------------------- |
11463 | -- Clear_Analyzed -- | |
11464 | -------------------- | |
11465 | ||
9b0986f8 | 11466 | function Clear_Analyzed (N : Node_Id) return Traverse_Result is |
996ae0b0 RK |
11467 | begin |
11468 | if not Has_Extension (N) then | |
11469 | Set_Analyzed (N, False); | |
11470 | end if; | |
11471 | ||
11472 | return OK; | |
11473 | end Clear_Analyzed; | |
11474 | ||
9d77af56 | 11475 | procedure Reset_Analyzed is new Traverse_Proc (Clear_Analyzed); |
996ae0b0 RK |
11476 | |
11477 | -- Start of processing for Reset_Analyzed_Flags | |
11478 | ||
11479 | begin | |
9d77af56 | 11480 | Reset_Analyzed (N); |
996ae0b0 RK |
11481 | end Reset_Analyzed_Flags; |
11482 | ||
fbf5a39b AC |
11483 | --------------------------- |
11484 | -- Safe_To_Capture_Value -- | |
11485 | --------------------------- | |
11486 | ||
11487 | function Safe_To_Capture_Value | |
9b0986f8 RD |
11488 | (N : Node_Id; |
11489 | Ent : Entity_Id; | |
11490 | Cond : Boolean := False) return Boolean | |
fbf5a39b AC |
11491 | is |
11492 | begin | |
1b6c95c4 RD |
11493 | -- The only entities for which we track constant values are variables |
11494 | -- which are not renamings, constants, out parameters, and in out | |
11495 | -- parameters, so check if we have this case. | |
11496 | ||
11497 | -- Note: it may seem odd to track constant values for constants, but in | |
11498 | -- fact this routine is used for other purposes than simply capturing | |
11499 | -- the value. In particular, the setting of Known[_Non]_Null. | |
fbf5a39b | 11500 | |
9b0986f8 | 11501 | if (Ekind (Ent) = E_Variable and then No (Renamed_Object (Ent))) |
1b6c95c4 RD |
11502 | or else |
11503 | Ekind (Ent) = E_Constant | |
11504 | or else | |
11505 | Ekind (Ent) = E_Out_Parameter | |
11506 | or else | |
11507 | Ekind (Ent) = E_In_Out_Parameter | |
9b0986f8 RD |
11508 | then |
11509 | null; | |
11510 | ||
1b6c95c4 RD |
11511 | -- For conditionals, we also allow loop parameters and all formals, |
11512 | -- including in parameters. | |
9b0986f8 RD |
11513 | |
11514 | elsif Cond | |
11515 | and then | |
1b6c95c4 | 11516 | (Ekind (Ent) = E_Loop_Parameter |
9b0986f8 RD |
11517 | or else |
11518 | Ekind (Ent) = E_In_Parameter) | |
fbf5a39b | 11519 | then |
9b0986f8 RD |
11520 | null; |
11521 | ||
11522 | -- For all other cases, not just unsafe, but impossible to capture | |
11523 | -- Current_Value, since the above are the only entities which have | |
11524 | -- Current_Value fields. | |
11525 | ||
11526 | else | |
fbf5a39b AC |
11527 | return False; |
11528 | end if; | |
11529 | ||
1b6c95c4 RD |
11530 | -- Skip if volatile or aliased, since funny things might be going on in |
11531 | -- these cases which we cannot necessarily track. Also skip any variable | |
403fd939 RD |
11532 | -- for which an address clause is given, or whose address is taken. Also |
11533 | -- never capture value of library level variables (an attempt to do so | |
11534 | -- can occur in the case of package elaboration code). | |
2c867f5a | 11535 | |
2c867f5a ES |
11536 | if Treat_As_Volatile (Ent) |
11537 | or else Is_Aliased (Ent) | |
11538 | or else Present (Address_Clause (Ent)) | |
f377c995 | 11539 | or else Address_Taken (Ent) |
403fd939 RD |
11540 | or else (Is_Library_Level_Entity (Ent) |
11541 | and then Ekind (Ent) = E_Variable) | |
2c867f5a | 11542 | then |
fbf5a39b AC |
11543 | return False; |
11544 | end if; | |
11545 | ||
1b6c95c4 RD |
11546 | -- OK, all above conditions are met. We also require that the scope of |
11547 | -- the reference be the same as the scope of the entity, not counting | |
11548 | -- packages and blocks and loops. | |
fbf5a39b AC |
11549 | |
11550 | declare | |
11551 | E_Scope : constant Entity_Id := Scope (Ent); | |
11552 | R_Scope : Entity_Id; | |
11553 | ||
11554 | begin | |
11555 | R_Scope := Current_Scope; | |
11556 | while R_Scope /= Standard_Standard loop | |
11557 | exit when R_Scope = E_Scope; | |
11558 | ||
8a95f4e8 | 11559 | if not Ekind_In (R_Scope, E_Package, E_Block, E_Loop) then |
fbf5a39b AC |
11560 | return False; |
11561 | else | |
11562 | R_Scope := Scope (R_Scope); | |
11563 | end if; | |
11564 | end loop; | |
11565 | end; | |
11566 | ||
11567 | -- We also require that the reference does not appear in a context | |
11568 | -- where it is not sure to be executed (i.e. a conditional context | |
9b0986f8 RD |
11569 | -- or an exception handler). We skip this if Cond is True, since the |
11570 | -- capturing of values from conditional tests handles this ok. | |
11571 | ||
11572 | if Cond then | |
11573 | return True; | |
11574 | end if; | |
fbf5a39b AC |
11575 | |
11576 | declare | |
2c867f5a ES |
11577 | Desc : Node_Id; |
11578 | P : Node_Id; | |
fbf5a39b AC |
11579 | |
11580 | begin | |
2c867f5a | 11581 | Desc := N; |
9b0986f8 RD |
11582 | |
11583 | P := Parent (N); | |
fbf5a39b | 11584 | while Present (P) loop |
ac7120ce | 11585 | if Nkind (P) = N_If_Statement |
2c867f5a | 11586 | or else Nkind (P) = N_Case_Statement |
ac7120ce RD |
11587 | or else (Nkind (P) in N_Short_Circuit |
11588 | and then Desc = Right_Opnd (P)) | |
11589 | or else (Nkind (P) = N_Conditional_Expression | |
11590 | and then Desc /= First (Expressions (P))) | |
2c867f5a ES |
11591 | or else Nkind (P) = N_Exception_Handler |
11592 | or else Nkind (P) = N_Selective_Accept | |
11593 | or else Nkind (P) = N_Conditional_Entry_Call | |
11594 | or else Nkind (P) = N_Timed_Entry_Call | |
11595 | or else Nkind (P) = N_Asynchronous_Select | |
fbf5a39b AC |
11596 | then |
11597 | return False; | |
11598 | else | |
2c867f5a ES |
11599 | Desc := P; |
11600 | P := Parent (P); | |
fbf5a39b AC |
11601 | end if; |
11602 | end loop; | |
11603 | end; | |
11604 | ||
11605 | -- OK, looks safe to set value | |
11606 | ||
11607 | return True; | |
11608 | end Safe_To_Capture_Value; | |
11609 | ||
996ae0b0 RK |
11610 | --------------- |
11611 | -- Same_Name -- | |
11612 | --------------- | |
11613 | ||
11614 | function Same_Name (N1, N2 : Node_Id) return Boolean is | |
11615 | K1 : constant Node_Kind := Nkind (N1); | |
11616 | K2 : constant Node_Kind := Nkind (N2); | |
11617 | ||
11618 | begin | |
11619 | if (K1 = N_Identifier or else K1 = N_Defining_Identifier) | |
11620 | and then (K2 = N_Identifier or else K2 = N_Defining_Identifier) | |
11621 | then | |
11622 | return Chars (N1) = Chars (N2); | |
11623 | ||
11624 | elsif (K1 = N_Selected_Component or else K1 = N_Expanded_Name) | |
11625 | and then (K2 = N_Selected_Component or else K2 = N_Expanded_Name) | |
11626 | then | |
11627 | return Same_Name (Selector_Name (N1), Selector_Name (N2)) | |
11628 | and then Same_Name (Prefix (N1), Prefix (N2)); | |
11629 | ||
11630 | else | |
11631 | return False; | |
11632 | end if; | |
11633 | end Same_Name; | |
11634 | ||
1b6c95c4 RD |
11635 | ----------------- |
11636 | -- Same_Object -- | |
11637 | ----------------- | |
11638 | ||
11639 | function Same_Object (Node1, Node2 : Node_Id) return Boolean is | |
11640 | N1 : constant Node_Id := Original_Node (Node1); | |
11641 | N2 : constant Node_Id := Original_Node (Node2); | |
11642 | -- We do the tests on original nodes, since we are most interested | |
11643 | -- in the original source, not any expansion that got in the way. | |
11644 | ||
11645 | K1 : constant Node_Kind := Nkind (N1); | |
11646 | K2 : constant Node_Kind := Nkind (N2); | |
11647 | ||
11648 | begin | |
11649 | -- First case, both are entities with same entity | |
11650 | ||
099ace5e AC |
11651 | if K1 in N_Has_Entity and then K2 in N_Has_Entity then |
11652 | declare | |
11653 | EN1 : constant Entity_Id := Entity (N1); | |
11654 | EN2 : constant Entity_Id := Entity (N2); | |
11655 | begin | |
11656 | if Present (EN1) and then Present (EN2) | |
11657 | and then (Ekind_In (EN1, E_Variable, E_Constant) | |
11658 | or else Is_Formal (EN1)) | |
11659 | and then EN1 = EN2 | |
11660 | then | |
11661 | return True; | |
11662 | end if; | |
11663 | end; | |
11664 | end if; | |
1b6c95c4 RD |
11665 | |
11666 | -- Second case, selected component with same selector, same record | |
11667 | ||
099ace5e | 11668 | if K1 = N_Selected_Component |
1b6c95c4 RD |
11669 | and then K2 = N_Selected_Component |
11670 | and then Chars (Selector_Name (N1)) = Chars (Selector_Name (N2)) | |
11671 | then | |
11672 | return Same_Object (Prefix (N1), Prefix (N2)); | |
11673 | ||
11674 | -- Third case, indexed component with same subscripts, same array | |
11675 | ||
11676 | elsif K1 = N_Indexed_Component | |
11677 | and then K2 = N_Indexed_Component | |
11678 | and then Same_Object (Prefix (N1), Prefix (N2)) | |
11679 | then | |
11680 | declare | |
11681 | E1, E2 : Node_Id; | |
11682 | begin | |
11683 | E1 := First (Expressions (N1)); | |
11684 | E2 := First (Expressions (N2)); | |
11685 | while Present (E1) loop | |
11686 | if not Same_Value (E1, E2) then | |
11687 | return False; | |
11688 | else | |
11689 | Next (E1); | |
11690 | Next (E2); | |
11691 | end if; | |
11692 | end loop; | |
11693 | ||
11694 | return True; | |
11695 | end; | |
11696 | ||
11697 | -- Fourth case, slice of same array with same bounds | |
11698 | ||
11699 | elsif K1 = N_Slice | |
11700 | and then K2 = N_Slice | |
11701 | and then Nkind (Discrete_Range (N1)) = N_Range | |
11702 | and then Nkind (Discrete_Range (N2)) = N_Range | |
11703 | and then Same_Value (Low_Bound (Discrete_Range (N1)), | |
11704 | Low_Bound (Discrete_Range (N2))) | |
11705 | and then Same_Value (High_Bound (Discrete_Range (N1)), | |
11706 | High_Bound (Discrete_Range (N2))) | |
11707 | then | |
11708 | return Same_Name (Prefix (N1), Prefix (N2)); | |
11709 | ||
11710 | -- All other cases, not clearly the same object | |
11711 | ||
11712 | else | |
11713 | return False; | |
11714 | end if; | |
11715 | end Same_Object; | |
11716 | ||
996ae0b0 RK |
11717 | --------------- |
11718 | -- Same_Type -- | |
11719 | --------------- | |
11720 | ||
11721 | function Same_Type (T1, T2 : Entity_Id) return Boolean is | |
11722 | begin | |
11723 | if T1 = T2 then | |
11724 | return True; | |
11725 | ||
11726 | elsif not Is_Constrained (T1) | |
11727 | and then not Is_Constrained (T2) | |
11728 | and then Base_Type (T1) = Base_Type (T2) | |
11729 | then | |
11730 | return True; | |
11731 | ||
11732 | -- For now don't bother with case of identical constraints, to be | |
11733 | -- fiddled with later on perhaps (this is only used for optimization | |
11734 | -- purposes, so it is not critical to do a best possible job) | |
11735 | ||
11736 | else | |
11737 | return False; | |
11738 | end if; | |
11739 | end Same_Type; | |
11740 | ||
1b6c95c4 RD |
11741 | ---------------- |
11742 | -- Same_Value -- | |
11743 | ---------------- | |
11744 | ||
11745 | function Same_Value (Node1, Node2 : Node_Id) return Boolean is | |
11746 | begin | |
11747 | if Compile_Time_Known_Value (Node1) | |
11748 | and then Compile_Time_Known_Value (Node2) | |
11749 | and then Expr_Value (Node1) = Expr_Value (Node2) | |
11750 | then | |
11751 | return True; | |
11752 | elsif Same_Object (Node1, Node2) then | |
11753 | return True; | |
11754 | else | |
11755 | return False; | |
11756 | end if; | |
11757 | end Same_Value; | |
11758 | ||
7c4b480f AC |
11759 | ----------------- |
11760 | -- Save_Actual -- | |
11761 | ----------------- | |
11762 | ||
11763 | procedure Save_Actual (N : Node_Id; Writable : Boolean := False) is | |
11764 | begin | |
1e194575 AC |
11765 | if Ada_Version < Ada_2012 then |
11766 | return; | |
11767 | ||
11768 | elsif Is_Entity_Name (N) | |
87dc09cb AC |
11769 | or else |
11770 | Nkind_In (N, N_Indexed_Component, N_Selected_Component, N_Slice) | |
11771 | or else | |
11772 | (Nkind (N) = N_Attribute_Reference | |
11773 | and then Attribute_Name (N) = Name_Access) | |
7c4b480f AC |
11774 | |
11775 | then | |
11776 | -- We are only interested in IN OUT parameters of inner calls | |
11777 | ||
11778 | if not Writable | |
11779 | or else Nkind (Parent (N)) = N_Function_Call | |
11780 | or else Nkind (Parent (N)) in N_Op | |
11781 | then | |
11782 | Actuals_In_Call.Increment_Last; | |
11783 | Actuals_In_Call.Table (Actuals_In_Call.Last) := (N, Writable); | |
11784 | end if; | |
11785 | end if; | |
11786 | end Save_Actual; | |
11787 | ||
996ae0b0 RK |
11788 | ------------------------ |
11789 | -- Scope_Is_Transient -- | |
11790 | ------------------------ | |
11791 | ||
ce4a6e84 | 11792 | function Scope_Is_Transient return Boolean is |
996ae0b0 RK |
11793 | begin |
11794 | return Scope_Stack.Table (Scope_Stack.Last).Is_Transient; | |
11795 | end Scope_Is_Transient; | |
11796 | ||
11797 | ------------------ | |
11798 | -- Scope_Within -- | |
11799 | ------------------ | |
11800 | ||
11801 | function Scope_Within (Scope1, Scope2 : Entity_Id) return Boolean is | |
11802 | Scop : Entity_Id; | |
11803 | ||
11804 | begin | |
11805 | Scop := Scope1; | |
11806 | while Scop /= Standard_Standard loop | |
11807 | Scop := Scope (Scop); | |
11808 | ||
11809 | if Scop = Scope2 then | |
11810 | return True; | |
11811 | end if; | |
11812 | end loop; | |
11813 | ||
11814 | return False; | |
11815 | end Scope_Within; | |
11816 | ||
11817 | -------------------------- | |
11818 | -- Scope_Within_Or_Same -- | |
11819 | -------------------------- | |
11820 | ||
11821 | function Scope_Within_Or_Same (Scope1, Scope2 : Entity_Id) return Boolean is | |
11822 | Scop : Entity_Id; | |
11823 | ||
11824 | begin | |
11825 | Scop := Scope1; | |
11826 | while Scop /= Standard_Standard loop | |
11827 | if Scop = Scope2 then | |
11828 | return True; | |
11829 | else | |
11830 | Scop := Scope (Scop); | |
11831 | end if; | |
11832 | end loop; | |
11833 | ||
11834 | return False; | |
11835 | end Scope_Within_Or_Same; | |
11836 | ||
7f0e4cdb BD |
11837 | -------------------- |
11838 | -- Set_Convention -- | |
11839 | -------------------- | |
11840 | ||
11841 | procedure Set_Convention (E : Entity_Id; Val : Snames.Convention_Id) is | |
11842 | begin | |
11843 | Basic_Set_Convention (E, Val); | |
1923d2d6 | 11844 | |
7f0e4cdb | 11845 | if Is_Type (E) |
1923d2d6 | 11846 | and then Is_Access_Subprogram_Type (Base_Type (E)) |
7f0e4cdb BD |
11847 | and then Has_Foreign_Convention (E) |
11848 | then | |
11849 | Set_Can_Use_Internal_Rep (E, False); | |
11850 | end if; | |
11851 | end Set_Convention; | |
11852 | ||
996ae0b0 RK |
11853 | ------------------------ |
11854 | -- Set_Current_Entity -- | |
11855 | ------------------------ | |
11856 | ||
9b20e59b AC |
11857 | -- The given entity is to be set as the currently visible definition of its |
11858 | -- associated name (i.e. the Node_Id associated with its name). All we have | |
11859 | -- to do is to get the name from the identifier, and then set the | |
11860 | -- associated Node_Id to point to the given entity. | |
996ae0b0 RK |
11861 | |
11862 | procedure Set_Current_Entity (E : Entity_Id) is | |
11863 | begin | |
11864 | Set_Name_Entity_Id (Chars (E), E); | |
11865 | end Set_Current_Entity; | |
11866 | ||
1923d2d6 JM |
11867 | --------------------------- |
11868 | -- Set_Debug_Info_Needed -- | |
11869 | --------------------------- | |
11870 | ||
11871 | procedure Set_Debug_Info_Needed (T : Entity_Id) is | |
11872 | ||
11873 | procedure Set_Debug_Info_Needed_If_Not_Set (E : Entity_Id); | |
11874 | pragma Inline (Set_Debug_Info_Needed_If_Not_Set); | |
11875 | -- Used to set debug info in a related node if not set already | |
11876 | ||
11877 | -------------------------------------- | |
11878 | -- Set_Debug_Info_Needed_If_Not_Set -- | |
11879 | -------------------------------------- | |
11880 | ||
11881 | procedure Set_Debug_Info_Needed_If_Not_Set (E : Entity_Id) is | |
11882 | begin | |
11883 | if Present (E) | |
11884 | and then not Needs_Debug_Info (E) | |
11885 | then | |
11886 | Set_Debug_Info_Needed (E); | |
c3db4df1 ES |
11887 | |
11888 | -- For a private type, indicate that the full view also needs | |
11889 | -- debug information. | |
11890 | ||
11891 | if Is_Type (E) | |
11892 | and then Is_Private_Type (E) | |
11893 | and then Present (Full_View (E)) | |
11894 | then | |
11895 | Set_Debug_Info_Needed (Full_View (E)); | |
11896 | end if; | |
1923d2d6 JM |
11897 | end if; |
11898 | end Set_Debug_Info_Needed_If_Not_Set; | |
11899 | ||
11900 | -- Start of processing for Set_Debug_Info_Needed | |
11901 | ||
11902 | begin | |
11903 | -- Nothing to do if argument is Empty or has Debug_Info_Off set, which | |
11904 | -- indicates that Debug_Info_Needed is never required for the entity. | |
11905 | ||
11906 | if No (T) | |
11907 | or else Debug_Info_Off (T) | |
11908 | then | |
11909 | return; | |
11910 | end if; | |
11911 | ||
11912 | -- Set flag in entity itself. Note that we will go through the following | |
11913 | -- circuitry even if the flag is already set on T. That's intentional, | |
11914 | -- it makes sure that the flag will be set in subsidiary entities. | |
11915 | ||
11916 | Set_Needs_Debug_Info (T); | |
11917 | ||
11918 | -- Set flag on subsidiary entities if not set already | |
11919 | ||
11920 | if Is_Object (T) then | |
11921 | Set_Debug_Info_Needed_If_Not_Set (Etype (T)); | |
11922 | ||
11923 | elsif Is_Type (T) then | |
11924 | Set_Debug_Info_Needed_If_Not_Set (Etype (T)); | |
11925 | ||
11926 | if Is_Record_Type (T) then | |
11927 | declare | |
11928 | Ent : Entity_Id := First_Entity (T); | |
11929 | begin | |
11930 | while Present (Ent) loop | |
11931 | Set_Debug_Info_Needed_If_Not_Set (Ent); | |
11932 | Next_Entity (Ent); | |
11933 | end loop; | |
11934 | end; | |
11935 | ||
66919db5 AC |
11936 | -- For a class wide subtype, we also need debug information |
11937 | -- for the equivalent type. | |
11938 | ||
032d1b71 EB |
11939 | if Ekind (T) = E_Class_Wide_Subtype then |
11940 | Set_Debug_Info_Needed_If_Not_Set (Equivalent_Type (T)); | |
11941 | end if; | |
11942 | ||
1923d2d6 JM |
11943 | elsif Is_Array_Type (T) then |
11944 | Set_Debug_Info_Needed_If_Not_Set (Component_Type (T)); | |
11945 | ||
11946 | declare | |
11947 | Indx : Node_Id := First_Index (T); | |
11948 | begin | |
11949 | while Present (Indx) loop | |
11950 | Set_Debug_Info_Needed_If_Not_Set (Etype (Indx)); | |
11951 | Indx := Next_Index (Indx); | |
11952 | end loop; | |
11953 | end; | |
11954 | ||
11955 | if Is_Packed (T) then | |
11956 | Set_Debug_Info_Needed_If_Not_Set (Packed_Array_Type (T)); | |
11957 | end if; | |
11958 | ||
11959 | elsif Is_Access_Type (T) then | |
11960 | Set_Debug_Info_Needed_If_Not_Set (Directly_Designated_Type (T)); | |
11961 | ||
11962 | elsif Is_Private_Type (T) then | |
11963 | Set_Debug_Info_Needed_If_Not_Set (Full_View (T)); | |
11964 | ||
11965 | elsif Is_Protected_Type (T) then | |
11966 | Set_Debug_Info_Needed_If_Not_Set (Corresponding_Record_Type (T)); | |
11967 | end if; | |
11968 | end if; | |
11969 | end Set_Debug_Info_Needed; | |
11970 | ||
996ae0b0 RK |
11971 | --------------------------------- |
11972 | -- Set_Entity_With_Style_Check -- | |
11973 | --------------------------------- | |
11974 | ||
11975 | procedure Set_Entity_With_Style_Check (N : Node_Id; Val : Entity_Id) is | |
11976 | Val_Actual : Entity_Id; | |
11977 | Nod : Node_Id; | |
11978 | ||
11979 | begin | |
11980 | Set_Entity (N, Val); | |
11981 | ||
11982 | if Style_Check | |
11983 | and then not Suppress_Style_Checks (Val) | |
11984 | and then not In_Instance | |
11985 | then | |
11986 | if Nkind (N) = N_Identifier then | |
11987 | Nod := N; | |
996ae0b0 RK |
11988 | elsif Nkind (N) = N_Expanded_Name then |
11989 | Nod := Selector_Name (N); | |
996ae0b0 RK |
11990 | else |
11991 | return; | |
11992 | end if; | |
11993 | ||
996ae0b0 RK |
11994 | -- A special situation arises for derived operations, where we want |
11995 | -- to do the check against the parent (since the Sloc of the derived | |
11996 | -- operation points to the derived type declaration itself). | |
11997 | ||
2c867f5a | 11998 | Val_Actual := Val; |
996ae0b0 RK |
11999 | while not Comes_From_Source (Val_Actual) |
12000 | and then Nkind (Val_Actual) in N_Entity | |
12001 | and then (Ekind (Val_Actual) = E_Enumeration_Literal | |
fbf5a39b AC |
12002 | or else Is_Subprogram (Val_Actual) |
12003 | or else Is_Generic_Subprogram (Val_Actual)) | |
996ae0b0 RK |
12004 | and then Present (Alias (Val_Actual)) |
12005 | loop | |
12006 | Val_Actual := Alias (Val_Actual); | |
12007 | end loop; | |
12008 | ||
12009 | -- Renaming declarations for generic actuals do not come from source, | |
12010 | -- and have a different name from that of the entity they rename, so | |
12011 | -- there is no style check to perform here. | |
12012 | ||
12013 | if Chars (Nod) = Chars (Val_Actual) then | |
12014 | Style.Check_Identifier (Nod, Val_Actual); | |
12015 | end if; | |
996ae0b0 RK |
12016 | end if; |
12017 | ||
12018 | Set_Entity (N, Val); | |
12019 | end Set_Entity_With_Style_Check; | |
12020 | ||
12021 | ------------------------ | |
12022 | -- Set_Name_Entity_Id -- | |
12023 | ------------------------ | |
12024 | ||
12025 | procedure Set_Name_Entity_Id (Id : Name_Id; Val : Entity_Id) is | |
12026 | begin | |
12027 | Set_Name_Table_Info (Id, Int (Val)); | |
12028 | end Set_Name_Entity_Id; | |
12029 | ||
12030 | --------------------- | |
12031 | -- Set_Next_Actual -- | |
12032 | --------------------- | |
12033 | ||
12034 | procedure Set_Next_Actual (Ass1_Id : Node_Id; Ass2_Id : Node_Id) is | |
12035 | begin | |
12036 | if Nkind (Parent (Ass1_Id)) = N_Parameter_Association then | |
12037 | Set_First_Named_Actual (Parent (Ass1_Id), Ass2_Id); | |
12038 | end if; | |
12039 | end Set_Next_Actual; | |
12040 | ||
ce4a6e84 RD |
12041 | ---------------------------------- |
12042 | -- Set_Optimize_Alignment_Flags -- | |
12043 | ---------------------------------- | |
12044 | ||
12045 | procedure Set_Optimize_Alignment_Flags (E : Entity_Id) is | |
12046 | begin | |
12047 | if Optimize_Alignment = 'S' then | |
12048 | Set_Optimize_Alignment_Space (E); | |
12049 | elsif Optimize_Alignment = 'T' then | |
12050 | Set_Optimize_Alignment_Time (E); | |
12051 | end if; | |
12052 | end Set_Optimize_Alignment_Flags; | |
12053 | ||
996ae0b0 RK |
12054 | ----------------------- |
12055 | -- Set_Public_Status -- | |
12056 | ----------------------- | |
12057 | ||
12058 | procedure Set_Public_Status (Id : Entity_Id) is | |
12059 | S : constant Entity_Id := Current_Scope; | |
12060 | ||
ce4a6e84 RD |
12061 | function Within_HSS_Or_If (E : Entity_Id) return Boolean; |
12062 | -- Determines if E is defined within handled statement sequence or | |
12063 | -- an if statement, returns True if so, False otherwise. | |
12064 | ||
12065 | ---------------------- | |
12066 | -- Within_HSS_Or_If -- | |
12067 | ---------------------- | |
12068 | ||
12069 | function Within_HSS_Or_If (E : Entity_Id) return Boolean is | |
12070 | N : Node_Id; | |
12071 | begin | |
12072 | N := Declaration_Node (E); | |
12073 | loop | |
12074 | N := Parent (N); | |
12075 | ||
12076 | if No (N) then | |
12077 | return False; | |
12078 | ||
12079 | elsif Nkind_In (N, N_Handled_Sequence_Of_Statements, | |
12080 | N_If_Statement) | |
12081 | then | |
12082 | return True; | |
12083 | end if; | |
12084 | end loop; | |
12085 | end Within_HSS_Or_If; | |
12086 | ||
12087 | -- Start of processing for Set_Public_Status | |
12088 | ||
996ae0b0 | 12089 | begin |
21024a39 RD |
12090 | -- Everything in the scope of Standard is public |
12091 | ||
12092 | if S = Standard_Standard then | |
12093 | Set_Is_Public (Id); | |
12094 | ||
12095 | -- Entity is definitely not public if enclosing scope is not public | |
12096 | ||
12097 | elsif not Is_Public (S) then | |
12098 | return; | |
12099 | ||
ce4a6e84 RD |
12100 | -- An object or function declaration that occurs in a handled sequence |
12101 | -- of statements or within an if statement is the declaration for a | |
12102 | -- temporary object or local subprogram generated by the expander. It | |
12103 | -- never needs to be made public and furthermore, making it public can | |
12104 | -- cause back end problems. | |
21024a39 | 12105 | |
ce4a6e84 RD |
12106 | elsif Nkind_In (Parent (Id), N_Object_Declaration, |
12107 | N_Function_Specification) | |
12108 | and then Within_HSS_Or_If (Id) | |
996ae0b0 | 12109 | then |
21024a39 RD |
12110 | return; |
12111 | ||
12112 | -- Entities in public packages or records are public | |
12113 | ||
12114 | elsif Ekind (S) = E_Package or Is_Record_Type (S) then | |
996ae0b0 RK |
12115 | Set_Is_Public (Id); |
12116 | ||
12117 | -- The bounds of an entry family declaration can generate object | |
12118 | -- declarations that are visible to the back-end, e.g. in the | |
12119 | -- the declaration of a composite type that contains tasks. | |
12120 | ||
21024a39 | 12121 | elsif Is_Concurrent_Type (S) |
996ae0b0 RK |
12122 | and then not Has_Completion (S) |
12123 | and then Nkind (Parent (Id)) = N_Object_Declaration | |
12124 | then | |
12125 | Set_Is_Public (Id); | |
12126 | end if; | |
12127 | end Set_Public_Status; | |
12128 | ||
7f0e4cdb BD |
12129 | ----------------------------- |
12130 | -- Set_Referenced_Modified -- | |
12131 | ----------------------------- | |
12132 | ||
12133 | procedure Set_Referenced_Modified (N : Node_Id; Out_Param : Boolean) is | |
12134 | Pref : Node_Id; | |
12135 | ||
12136 | begin | |
12137 | -- Deal with indexed or selected component where prefix is modified | |
12138 | ||
8d12c865 | 12139 | if Nkind_In (N, N_Indexed_Component, N_Selected_Component) then |
7f0e4cdb BD |
12140 | Pref := Prefix (N); |
12141 | ||
12142 | -- If prefix is access type, then it is the designated object that is | |
12143 | -- being modified, which means we have no entity to set the flag on. | |
12144 | ||
12145 | if No (Etype (Pref)) or else Is_Access_Type (Etype (Pref)) then | |
12146 | return; | |
12147 | ||
12148 | -- Otherwise chase the prefix | |
12149 | ||
12150 | else | |
12151 | Set_Referenced_Modified (Pref, Out_Param); | |
12152 | end if; | |
12153 | ||
12154 | -- Otherwise see if we have an entity name (only other case to process) | |
12155 | ||
12156 | elsif Is_Entity_Name (N) and then Present (Entity (N)) then | |
12157 | Set_Referenced_As_LHS (Entity (N), not Out_Param); | |
12158 | Set_Referenced_As_Out_Parameter (Entity (N), Out_Param); | |
12159 | end if; | |
12160 | end Set_Referenced_Modified; | |
12161 | ||
996ae0b0 RK |
12162 | ---------------------------- |
12163 | -- Set_Scope_Is_Transient -- | |
12164 | ---------------------------- | |
12165 | ||
12166 | procedure Set_Scope_Is_Transient (V : Boolean := True) is | |
12167 | begin | |
12168 | Scope_Stack.Table (Scope_Stack.Last).Is_Transient := V; | |
12169 | end Set_Scope_Is_Transient; | |
12170 | ||
12171 | ------------------- | |
12172 | -- Set_Size_Info -- | |
12173 | ------------------- | |
12174 | ||
12175 | procedure Set_Size_Info (T1, T2 : Entity_Id) is | |
12176 | begin | |
12177 | -- We copy Esize, but not RM_Size, since in general RM_Size is | |
12178 | -- subtype specific and does not get inherited by all subtypes. | |
12179 | ||
12180 | Set_Esize (T1, Esize (T2)); | |
12181 | Set_Has_Biased_Representation (T1, Has_Biased_Representation (T2)); | |
12182 | ||
12183 | if Is_Discrete_Or_Fixed_Point_Type (T1) | |
12184 | and then | |
12185 | Is_Discrete_Or_Fixed_Point_Type (T2) | |
12186 | then | |
12187 | Set_Is_Unsigned_Type (T1, Is_Unsigned_Type (T2)); | |
12188 | end if; | |
9e87a68d | 12189 | |
996ae0b0 RK |
12190 | Set_Alignment (T1, Alignment (T2)); |
12191 | end Set_Size_Info; | |
12192 | ||
1c54829e AC |
12193 | -------------------- |
12194 | -- Static_Boolean -- | |
12195 | -------------------- | |
12196 | ||
12197 | function Static_Boolean (N : Node_Id) return Uint is | |
12198 | begin | |
12199 | Analyze_And_Resolve (N, Standard_Boolean); | |
12200 | ||
12201 | if N = Error | |
12202 | or else Error_Posted (N) | |
12203 | or else Etype (N) = Any_Type | |
12204 | then | |
12205 | return No_Uint; | |
12206 | end if; | |
12207 | ||
12208 | if Is_Static_Expression (N) then | |
12209 | if not Raises_Constraint_Error (N) then | |
12210 | return Expr_Value (N); | |
12211 | else | |
12212 | return No_Uint; | |
12213 | end if; | |
12214 | ||
12215 | elsif Etype (N) = Any_Type then | |
12216 | return No_Uint; | |
12217 | ||
12218 | else | |
12219 | Flag_Non_Static_Expr | |
12220 | ("static boolean expression required here", N); | |
12221 | return No_Uint; | |
12222 | end if; | |
12223 | end Static_Boolean; | |
12224 | ||
996ae0b0 RK |
12225 | -------------------- |
12226 | -- Static_Integer -- | |
12227 | -------------------- | |
12228 | ||
12229 | function Static_Integer (N : Node_Id) return Uint is | |
12230 | begin | |
12231 | Analyze_And_Resolve (N, Any_Integer); | |
12232 | ||
12233 | if N = Error | |
12234 | or else Error_Posted (N) | |
12235 | or else Etype (N) = Any_Type | |
12236 | then | |
12237 | return No_Uint; | |
12238 | end if; | |
12239 | ||
12240 | if Is_Static_Expression (N) then | |
12241 | if not Raises_Constraint_Error (N) then | |
12242 | return Expr_Value (N); | |
12243 | else | |
12244 | return No_Uint; | |
12245 | end if; | |
12246 | ||
12247 | elsif Etype (N) = Any_Type then | |
12248 | return No_Uint; | |
12249 | ||
12250 | else | |
fbf5a39b AC |
12251 | Flag_Non_Static_Expr |
12252 | ("static integer expression required here", N); | |
996ae0b0 RK |
12253 | return No_Uint; |
12254 | end if; | |
12255 | end Static_Integer; | |
12256 | ||
12257 | -------------------------- | |
12258 | -- Statically_Different -- | |
12259 | -------------------------- | |
12260 | ||
12261 | function Statically_Different (E1, E2 : Node_Id) return Boolean is | |
12262 | R1 : constant Node_Id := Get_Referenced_Object (E1); | |
12263 | R2 : constant Node_Id := Get_Referenced_Object (E2); | |
996ae0b0 RK |
12264 | begin |
12265 | return Is_Entity_Name (R1) | |
12266 | and then Is_Entity_Name (R2) | |
12267 | and then Entity (R1) /= Entity (R2) | |
12268 | and then not Is_Formal (Entity (R1)) | |
12269 | and then not Is_Formal (Entity (R2)); | |
12270 | end Statically_Different; | |
12271 | ||
12272 | ----------------------------- | |
12273 | -- Subprogram_Access_Level -- | |
12274 | ----------------------------- | |
12275 | ||
12276 | function Subprogram_Access_Level (Subp : Entity_Id) return Uint is | |
12277 | begin | |
12278 | if Present (Alias (Subp)) then | |
12279 | return Subprogram_Access_Level (Alias (Subp)); | |
12280 | else | |
12281 | return Scope_Depth (Enclosing_Dynamic_Scope (Subp)); | |
12282 | end if; | |
12283 | end Subprogram_Access_Level; | |
12284 | ||
12285 | ----------------- | |
12286 | -- Trace_Scope -- | |
12287 | ----------------- | |
12288 | ||
12289 | procedure Trace_Scope (N : Node_Id; E : Entity_Id; Msg : String) is | |
12290 | begin | |
12291 | if Debug_Flag_W then | |
12292 | for J in 0 .. Scope_Stack.Last loop | |
12293 | Write_Str (" "); | |
12294 | end loop; | |
12295 | ||
12296 | Write_Str (Msg); | |
12297 | Write_Name (Chars (E)); | |
7f0e4cdb BD |
12298 | Write_Str (" from "); |
12299 | Write_Location (Sloc (N)); | |
996ae0b0 RK |
12300 | Write_Eol; |
12301 | end if; | |
12302 | end Trace_Scope; | |
12303 | ||
12304 | ----------------------- | |
12305 | -- Transfer_Entities -- | |
12306 | ----------------------- | |
12307 | ||
12308 | procedure Transfer_Entities (From : Entity_Id; To : Entity_Id) is | |
2c867f5a | 12309 | Ent : Entity_Id := First_Entity (From); |
996ae0b0 RK |
12310 | |
12311 | begin | |
12312 | if No (Ent) then | |
12313 | return; | |
12314 | end if; | |
12315 | ||
12316 | if (Last_Entity (To)) = Empty then | |
12317 | Set_First_Entity (To, Ent); | |
12318 | else | |
12319 | Set_Next_Entity (Last_Entity (To), Ent); | |
12320 | end if; | |
12321 | ||
12322 | Set_Last_Entity (To, Last_Entity (From)); | |
12323 | ||
12324 | while Present (Ent) loop | |
12325 | Set_Scope (Ent, To); | |
12326 | ||
12327 | if not Is_Public (Ent) then | |
12328 | Set_Public_Status (Ent); | |
12329 | ||
12330 | if Is_Public (Ent) | |
12331 | and then Ekind (Ent) = E_Record_Subtype | |
12332 | ||
12333 | then | |
12334 | -- The components of the propagated Itype must be public | |
12335 | -- as well. | |
12336 | ||
12337 | declare | |
12338 | Comp : Entity_Id; | |
996ae0b0 RK |
12339 | begin |
12340 | Comp := First_Entity (Ent); | |
996ae0b0 RK |
12341 | while Present (Comp) loop |
12342 | Set_Is_Public (Comp); | |
12343 | Next_Entity (Comp); | |
12344 | end loop; | |
12345 | end; | |
12346 | end if; | |
12347 | end if; | |
12348 | ||
12349 | Next_Entity (Ent); | |
12350 | end loop; | |
12351 | ||
12352 | Set_First_Entity (From, Empty); | |
12353 | Set_Last_Entity (From, Empty); | |
12354 | end Transfer_Entities; | |
12355 | ||
12356 | ----------------------- | |
12357 | -- Type_Access_Level -- | |
12358 | ----------------------- | |
12359 | ||
12360 | function Type_Access_Level (Typ : Entity_Id) return Uint is | |
91b1417d | 12361 | Btyp : Entity_Id; |
996ae0b0 RK |
12362 | |
12363 | begin | |
91b1417d | 12364 | Btyp := Base_Type (Typ); |
edd63e9b | 12365 | |
f377c995 HK |
12366 | -- Ada 2005 (AI-230): For most cases of anonymous access types, we |
12367 | -- simply use the level where the type is declared. This is true for | |
12368 | -- stand-alone object declarations, and for anonymous access types | |
12369 | -- associated with components the level is the same as that of the | |
12370 | -- enclosing composite type. However, special treatment is needed for | |
12371 | -- the cases of access parameters, return objects of an anonymous access | |
12372 | -- type, and, in Ada 95, access discriminants of limited types. | |
12373 | ||
996ae0b0 | 12374 | if Ekind (Btyp) in Access_Kind then |
f377c995 HK |
12375 | if Ekind (Btyp) = E_Anonymous_Access_Type then |
12376 | ||
12377 | -- If the type is a nonlocal anonymous access type (such as for | |
12378 | -- an access parameter) we treat it as being declared at the | |
12379 | -- library level to ensure that names such as X.all'access don't | |
12380 | -- fail static accessibility checks. | |
12381 | ||
12382 | if not Is_Local_Anonymous_Access (Typ) then | |
12383 | return Scope_Depth (Standard_Standard); | |
9b0986f8 | 12384 | |
f377c995 HK |
12385 | -- If this is a return object, the accessibility level is that of |
12386 | -- the result subtype of the enclosing function. The test here is | |
12387 | -- little complicated, because we have to account for extended | |
12388 | -- return statements that have been rewritten as blocks, in which | |
12389 | -- case we have to find and the Is_Return_Object attribute of the | |
12390 | -- itype's associated object. It would be nice to find a way to | |
12391 | -- simplify this test, but it doesn't seem worthwhile to add a new | |
12392 | -- flag just for purposes of this test. ??? | |
9b0986f8 | 12393 | |
f377c995 HK |
12394 | elsif Ekind (Scope (Btyp)) = E_Return_Statement |
12395 | or else | |
12396 | (Is_Itype (Btyp) | |
12397 | and then Nkind (Associated_Node_For_Itype (Btyp)) = | |
12398 | N_Object_Declaration | |
12399 | and then Is_Return_Object | |
12400 | (Defining_Identifier | |
12401 | (Associated_Node_For_Itype (Btyp)))) | |
12402 | then | |
9b0986f8 RD |
12403 | declare |
12404 | Scop : Entity_Id; | |
f377c995 | 12405 | |
9b0986f8 RD |
12406 | begin |
12407 | Scop := Scope (Scope (Btyp)); | |
12408 | while Present (Scop) loop | |
12409 | exit when Ekind (Scop) = E_Function; | |
12410 | Scop := Scope (Scop); | |
12411 | end loop; | |
12412 | ||
f377c995 HK |
12413 | -- Treat the return object's type as having the level of the |
12414 | -- function's result subtype (as per RM05-6.5(5.3/2)). | |
9b0986f8 | 12415 | |
f377c995 HK |
12416 | return Type_Access_Level (Etype (Scop)); |
12417 | end; | |
9b0986f8 | 12418 | end if; |
996ae0b0 RK |
12419 | end if; |
12420 | ||
12421 | Btyp := Root_Type (Btyp); | |
b8dc622e | 12422 | |
f3d57416 | 12423 | -- The accessibility level of anonymous access types associated with |
b8dc622e JM |
12424 | -- discriminants is that of the current instance of the type, and |
12425 | -- that's deeper than the type itself (AARM 3.10.2 (12.3.21)). | |
12426 | ||
9b0986f8 | 12427 | -- AI-402: access discriminants have accessibility based on the |
f377c995 HK |
12428 | -- object rather than the type in Ada 2005, so the above paragraph |
12429 | -- doesn't apply. | |
9b0986f8 RD |
12430 | |
12431 | -- ??? Needs completion with rules from AI-416 | |
12432 | ||
12433 | if Ada_Version <= Ada_95 | |
12434 | and then Ekind (Typ) = E_Anonymous_Access_Type | |
b8dc622e JM |
12435 | and then Present (Associated_Node_For_Itype (Typ)) |
12436 | and then Nkind (Associated_Node_For_Itype (Typ)) = | |
12437 | N_Discriminant_Specification | |
12438 | then | |
12439 | return Scope_Depth (Enclosing_Dynamic_Scope (Btyp)) + 1; | |
12440 | end if; | |
996ae0b0 RK |
12441 | end if; |
12442 | ||
12443 | return Scope_Depth (Enclosing_Dynamic_Scope (Btyp)); | |
12444 | end Type_Access_Level; | |
12445 | ||
276e7ed0 AC |
12446 | ------------------------------------ |
12447 | -- Type_Without_Stream_Operation -- | |
12448 | ------------------------------------ | |
12449 | ||
12450 | function Type_Without_Stream_Operation | |
9aff36e9 RD |
12451 | (T : Entity_Id; |
12452 | Op : TSS_Name_Type := TSS_Null) return Entity_Id | |
276e7ed0 | 12453 | is |
9aff36e9 | 12454 | BT : constant Entity_Id := Base_Type (T); |
276e7ed0 | 12455 | Op_Missing : Boolean; |
9aff36e9 | 12456 | |
276e7ed0 AC |
12457 | begin |
12458 | if not Restriction_Active (No_Default_Stream_Attributes) then | |
12459 | return Empty; | |
12460 | end if; | |
12461 | ||
12462 | if Is_Elementary_Type (T) then | |
12463 | if Op = TSS_Null then | |
12464 | Op_Missing := | |
9aff36e9 RD |
12465 | No (TSS (BT, TSS_Stream_Read)) |
12466 | or else No (TSS (BT, TSS_Stream_Write)); | |
276e7ed0 AC |
12467 | |
12468 | else | |
12469 | Op_Missing := No (TSS (BT, Op)); | |
12470 | end if; | |
12471 | ||
12472 | if Op_Missing then | |
12473 | return T; | |
276e7ed0 AC |
12474 | else |
12475 | return Empty; | |
12476 | end if; | |
12477 | ||
12478 | elsif Is_Array_Type (T) then | |
12479 | return Type_Without_Stream_Operation (Component_Type (T), Op); | |
12480 | ||
12481 | elsif Is_Record_Type (T) then | |
12482 | declare | |
12483 | Comp : Entity_Id; | |
12484 | C_Typ : Entity_Id; | |
12485 | ||
12486 | begin | |
12487 | Comp := First_Component (T); | |
12488 | while Present (Comp) loop | |
12489 | C_Typ := Type_Without_Stream_Operation (Etype (Comp), Op); | |
9aff36e9 | 12490 | |
276e7ed0 AC |
12491 | if Present (C_Typ) then |
12492 | return C_Typ; | |
12493 | end if; | |
12494 | ||
12495 | Next_Component (Comp); | |
12496 | end loop; | |
12497 | ||
12498 | return Empty; | |
12499 | end; | |
12500 | ||
12501 | elsif Is_Private_Type (T) | |
12502 | and then Present (Full_View (T)) | |
12503 | then | |
12504 | return Type_Without_Stream_Operation (Full_View (T), Op); | |
276e7ed0 AC |
12505 | else |
12506 | return Empty; | |
12507 | end if; | |
12508 | end Type_Without_Stream_Operation; | |
12509 | ||
d9b056ea AC |
12510 | ---------------------------- |
12511 | -- Unique_Defining_Entity -- | |
12512 | ---------------------------- | |
12513 | ||
12514 | function Unique_Defining_Entity (N : Node_Id) return Entity_Id is | |
12515 | begin | |
57a8057a AC |
12516 | return Unique_Entity (Defining_Entity (N)); |
12517 | end Unique_Defining_Entity; | |
12518 | ||
12519 | ------------------- | |
12520 | -- Unique_Entity -- | |
12521 | ------------------- | |
12522 | ||
12523 | function Unique_Entity (E : Entity_Id) return Entity_Id is | |
12524 | U : Entity_Id := E; | |
12525 | P : Node_Id; | |
12526 | ||
12527 | begin | |
12528 | case Ekind (E) is | |
12529 | when Type_Kind => | |
12530 | if Present (Full_View (E)) then | |
12531 | U := Full_View (E); | |
12532 | end if; | |
12533 | ||
12534 | when E_Package_Body => | |
12535 | P := Parent (E); | |
12536 | ||
12537 | if Nkind (P) = N_Defining_Program_Unit_Name then | |
12538 | P := Parent (P); | |
12539 | end if; | |
12540 | ||
12541 | U := Corresponding_Spec (P); | |
12542 | ||
12543 | when E_Subprogram_Body => | |
12544 | P := Parent (E); | |
d9b056ea | 12545 | |
57a8057a AC |
12546 | if Nkind (P) = N_Defining_Program_Unit_Name then |
12547 | P := Parent (P); | |
12548 | end if; | |
12549 | ||
12550 | P := Parent (P); | |
12551 | ||
12552 | if Nkind (P) = N_Subprogram_Body_Stub then | |
12553 | if Present (Library_Unit (P)) then | |
12554 | U := Get_Body_From_Stub (P); | |
12555 | end if; | |
d9b056ea | 12556 | else |
57a8057a | 12557 | U := Corresponding_Spec (P); |
d9b056ea AC |
12558 | end if; |
12559 | ||
12560 | when others => | |
57a8057a | 12561 | null; |
d9b056ea | 12562 | end case; |
57a8057a AC |
12563 | |
12564 | return U; | |
12565 | end Unique_Entity; | |
d9b056ea | 12566 | |
6a2e5d0f AC |
12567 | ----------------- |
12568 | -- Unique_Name -- | |
12569 | ----------------- | |
12570 | ||
12571 | function Unique_Name (E : Entity_Id) return String is | |
993f8920 AC |
12572 | |
12573 | function Get_Scoped_Name (E : Entity_Id) return String; | |
12574 | -- Return the name of E prefixed by all the names of the scopes to which | |
12575 | -- E belongs, except for Standard. | |
12576 | ||
12577 | --------------------- | |
12578 | -- Get_Scoped_Name -- | |
12579 | --------------------- | |
12580 | ||
12581 | function Get_Scoped_Name (E : Entity_Id) return String is | |
12582 | Name : constant String := Get_Name_String (Chars (E)); | |
12583 | begin | |
12584 | if Has_Fully_Qualified_Name (E) | |
12585 | or else Scope (E) = Standard_Standard | |
12586 | then | |
12587 | return Name; | |
12588 | else | |
12589 | return Get_Scoped_Name (Scope (E)) & "__" & Name; | |
12590 | end if; | |
12591 | end Get_Scoped_Name; | |
12592 | ||
9b20e59b AC |
12593 | -- Start of processing for Unique_Name |
12594 | ||
6a2e5d0f | 12595 | begin |
993f8920 AC |
12596 | if E = Standard_Standard then |
12597 | return Get_Name_String (Name_Standard); | |
12598 | ||
76af4137 AC |
12599 | elsif Scope (E) = Standard_Standard |
12600 | and then not (Ekind (E) = E_Package or else Is_Subprogram (E)) | |
12601 | then | |
993f8920 AC |
12602 | return Get_Name_String (Name_Standard) & "__" & |
12603 | Get_Name_String (Chars (E)); | |
12604 | ||
6a2e5d0f | 12605 | else |
993f8920 | 12606 | return Get_Scoped_Name (E); |
6a2e5d0f AC |
12607 | end if; |
12608 | end Unique_Name; | |
12609 | ||
996ae0b0 RK |
12610 | -------------------------- |
12611 | -- Unit_Declaration_Node -- | |
12612 | -------------------------- | |
12613 | ||
12614 | function Unit_Declaration_Node (Unit_Id : Entity_Id) return Node_Id is | |
12615 | N : Node_Id := Parent (Unit_Id); | |
12616 | ||
12617 | begin | |
130c236a | 12618 | -- Predefined operators do not have a full function declaration |
996ae0b0 RK |
12619 | |
12620 | if Ekind (Unit_Id) = E_Operator then | |
12621 | return N; | |
12622 | end if; | |
12623 | ||
9b0986f8 RD |
12624 | -- Isn't there some better way to express the following ??? |
12625 | ||
996ae0b0 RK |
12626 | while Nkind (N) /= N_Abstract_Subprogram_Declaration |
12627 | and then Nkind (N) /= N_Formal_Package_Declaration | |
996ae0b0 RK |
12628 | and then Nkind (N) /= N_Function_Instantiation |
12629 | and then Nkind (N) /= N_Generic_Package_Declaration | |
12630 | and then Nkind (N) /= N_Generic_Subprogram_Declaration | |
12631 | and then Nkind (N) /= N_Package_Declaration | |
12632 | and then Nkind (N) /= N_Package_Body | |
12633 | and then Nkind (N) /= N_Package_Instantiation | |
12634 | and then Nkind (N) /= N_Package_Renaming_Declaration | |
12635 | and then Nkind (N) /= N_Procedure_Instantiation | |
fbf5a39b | 12636 | and then Nkind (N) /= N_Protected_Body |
996ae0b0 RK |
12637 | and then Nkind (N) /= N_Subprogram_Declaration |
12638 | and then Nkind (N) /= N_Subprogram_Body | |
12639 | and then Nkind (N) /= N_Subprogram_Body_Stub | |
12640 | and then Nkind (N) /= N_Subprogram_Renaming_Declaration | |
12641 | and then Nkind (N) /= N_Task_Body | |
12642 | and then Nkind (N) /= N_Task_Type_Declaration | |
82c80734 | 12643 | and then Nkind (N) not in N_Formal_Subprogram_Declaration |
996ae0b0 RK |
12644 | and then Nkind (N) not in N_Generic_Renaming_Declaration |
12645 | loop | |
12646 | N := Parent (N); | |
1df4f514 AC |
12647 | |
12648 | -- We don't use Assert here, because that causes an infinite loop | |
12649 | -- when assertions are turned off. Better to crash. | |
12650 | ||
12651 | if No (N) then | |
12652 | raise Program_Error; | |
12653 | end if; | |
996ae0b0 RK |
12654 | end loop; |
12655 | ||
12656 | return N; | |
12657 | end Unit_Declaration_Node; | |
12658 | ||
4561baf7 ES |
12659 | --------------------- |
12660 | -- Unit_Is_Visible -- | |
12661 | --------------------- | |
12662 | ||
12663 | function Unit_Is_Visible (U : Entity_Id) return Boolean is | |
12664 | Curr : constant Node_Id := Cunit (Current_Sem_Unit); | |
12665 | Curr_Entity : constant Entity_Id := Cunit_Entity (Current_Sem_Unit); | |
12666 | ||
12667 | function Unit_In_Parent_Context (Par_Unit : Node_Id) return Boolean; | |
12668 | -- For a child unit, check whether unit appears in a with_clause | |
12669 | -- of a parent. | |
12670 | ||
12671 | function Unit_In_Context (Comp_Unit : Node_Id) return Boolean; | |
12672 | -- Scan the context clause of one compilation unit looking for a | |
12673 | -- with_clause for the unit in question. | |
12674 | ||
12675 | ---------------------------- | |
12676 | -- Unit_In_Parent_Context -- | |
12677 | ---------------------------- | |
12678 | ||
6a2e4f0b | 12679 | function Unit_In_Parent_Context (Par_Unit : Node_Id) return Boolean is |
4561baf7 ES |
12680 | begin |
12681 | if Unit_In_Context (Par_Unit) then | |
12682 | return True; | |
12683 | ||
12684 | elsif Is_Child_Unit (Defining_Entity (Unit (Par_Unit))) then | |
12685 | return Unit_In_Parent_Context (Parent_Spec (Unit (Par_Unit))); | |
12686 | ||
12687 | else | |
12688 | return False; | |
12689 | end if; | |
12690 | end Unit_In_Parent_Context; | |
12691 | ||
12692 | --------------------- | |
12693 | -- Unit_In_Context -- | |
12694 | --------------------- | |
12695 | ||
12696 | function Unit_In_Context (Comp_Unit : Node_Id) return Boolean is | |
12697 | Clause : Node_Id; | |
12698 | ||
12699 | begin | |
12700 | Clause := First (Context_Items (Comp_Unit)); | |
12701 | while Present (Clause) loop | |
12702 | if Nkind (Clause) = N_With_Clause then | |
12703 | if Library_Unit (Clause) = U then | |
12704 | return True; | |
12705 | ||
12706 | -- The with_clause may denote a renaming of the unit we are | |
12707 | -- looking for, eg. Text_IO which renames Ada.Text_IO. | |
12708 | ||
12709 | elsif | |
6a2e4f0b AC |
12710 | Renamed_Entity (Entity (Name (Clause))) = |
12711 | Defining_Entity (Unit (U)) | |
4561baf7 ES |
12712 | then |
12713 | return True; | |
12714 | end if; | |
12715 | end if; | |
12716 | ||
12717 | Next (Clause); | |
12718 | end loop; | |
6a2e4f0b | 12719 | |
4561baf7 ES |
12720 | return False; |
12721 | end Unit_In_Context; | |
12722 | ||
6a2e4f0b | 12723 | -- Start of processing for Unit_Is_Visible |
4561baf7 | 12724 | |
6a2e4f0b | 12725 | begin |
993f8920 | 12726 | -- The currrent unit is directly visible |
4561baf7 ES |
12727 | |
12728 | if Curr = U then | |
12729 | return True; | |
12730 | ||
12731 | elsif Unit_In_Context (Curr) then | |
12732 | return True; | |
12733 | ||
993f8920 | 12734 | -- If the current unit is a body, check the context of the spec |
4561baf7 ES |
12735 | |
12736 | elsif Nkind (Unit (Curr)) = N_Package_Body | |
12737 | or else | |
12738 | (Nkind (Unit (Curr)) = N_Subprogram_Body | |
12739 | and then not Acts_As_Spec (Unit (Curr))) | |
12740 | then | |
4561baf7 ES |
12741 | if Unit_In_Context (Library_Unit (Curr)) then |
12742 | return True; | |
12743 | end if; | |
12744 | end if; | |
12745 | ||
993f8920 | 12746 | -- If the spec is a child unit, examine the parents |
4561baf7 ES |
12747 | |
12748 | if Is_Child_Unit (Curr_Entity) then | |
12749 | if Nkind (Unit (Curr)) in N_Unit_Body then | |
12750 | return | |
12751 | Unit_In_Parent_Context | |
12752 | (Parent_Spec (Unit (Library_Unit (Curr)))); | |
12753 | else | |
12754 | return Unit_In_Parent_Context (Parent_Spec (Unit (Curr))); | |
12755 | end if; | |
12756 | ||
12757 | else | |
12758 | return False; | |
12759 | end if; | |
12760 | end Unit_Is_Visible; | |
12761 | ||
fbf5a39b AC |
12762 | ------------------------------ |
12763 | -- Universal_Interpretation -- | |
12764 | ------------------------------ | |
12765 | ||
12766 | function Universal_Interpretation (Opnd : Node_Id) return Entity_Id is | |
12767 | Index : Interp_Index; | |
12768 | It : Interp; | |
12769 | ||
12770 | begin | |
12771 | -- The argument may be a formal parameter of an operator or subprogram | |
12772 | -- with multiple interpretations, or else an expression for an actual. | |
12773 | ||
12774 | if Nkind (Opnd) = N_Defining_Identifier | |
12775 | or else not Is_Overloaded (Opnd) | |
12776 | then | |
12777 | if Etype (Opnd) = Universal_Integer | |
12778 | or else Etype (Opnd) = Universal_Real | |
12779 | then | |
12780 | return Etype (Opnd); | |
12781 | else | |
12782 | return Empty; | |
12783 | end if; | |
12784 | ||
12785 | else | |
12786 | Get_First_Interp (Opnd, Index, It); | |
fbf5a39b | 12787 | while Present (It.Typ) loop |
fbf5a39b AC |
12788 | if It.Typ = Universal_Integer |
12789 | or else It.Typ = Universal_Real | |
12790 | then | |
12791 | return It.Typ; | |
12792 | end if; | |
12793 | ||
12794 | Get_Next_Interp (Index, It); | |
12795 | end loop; | |
12796 | ||
12797 | return Empty; | |
12798 | end if; | |
12799 | end Universal_Interpretation; | |
12800 | ||
9b0986f8 RD |
12801 | --------------- |
12802 | -- Unqualify -- | |
12803 | --------------- | |
12804 | ||
12805 | function Unqualify (Expr : Node_Id) return Node_Id is | |
12806 | begin | |
12807 | -- Recurse to handle unlikely case of multiple levels of qualification | |
12808 | ||
12809 | if Nkind (Expr) = N_Qualified_Expression then | |
12810 | return Unqualify (Expression (Expr)); | |
12811 | ||
12812 | -- Normal case, not a qualified expression | |
12813 | ||
12814 | else | |
12815 | return Expr; | |
12816 | end if; | |
12817 | end Unqualify; | |
12818 | ||
ea034236 AC |
12819 | ----------------------- |
12820 | -- Visible_Ancestors -- | |
12821 | ----------------------- | |
12822 | ||
12823 | function Visible_Ancestors (Typ : Entity_Id) return Elist_Id is | |
12824 | List_1 : Elist_Id; | |
12825 | List_2 : Elist_Id; | |
12826 | Elmt : Elmt_Id; | |
12827 | ||
12828 | begin | |
12829 | pragma Assert (Is_Record_Type (Typ) | |
12830 | and then Is_Tagged_Type (Typ)); | |
12831 | ||
12832 | -- Collect all the parents and progenitors of Typ. If the full-view of | |
12833 | -- private parents and progenitors is available then it is used to | |
12834 | -- generate the list of visible ancestors; otherwise their partial | |
12835 | -- view is added to the resulting list. | |
12836 | ||
12837 | Collect_Parents | |
12838 | (T => Typ, | |
12839 | List => List_1, | |
12840 | Use_Full_View => True); | |
12841 | ||
12842 | Collect_Interfaces | |
12843 | (T => Typ, | |
12844 | Ifaces_List => List_2, | |
12845 | Exclude_Parents => True, | |
12846 | Use_Full_View => True); | |
12847 | ||
12848 | -- Join the two lists. Avoid duplications because an interface may | |
12849 | -- simultaneously be parent and progenitor of a type. | |
12850 | ||
12851 | Elmt := First_Elmt (List_2); | |
12852 | while Present (Elmt) loop | |
12853 | Append_Unique_Elmt (Node (Elmt), List_1); | |
12854 | Next_Elmt (Elmt); | |
12855 | end loop; | |
12856 | ||
12857 | return List_1; | |
12858 | end Visible_Ancestors; | |
12859 | ||
996ae0b0 RK |
12860 | ---------------------- |
12861 | -- Within_Init_Proc -- | |
12862 | ---------------------- | |
12863 | ||
12864 | function Within_Init_Proc return Boolean is | |
12865 | S : Entity_Id; | |
12866 | ||
12867 | begin | |
12868 | S := Current_Scope; | |
12869 | while not Is_Overloadable (S) loop | |
12870 | if S = Standard_Standard then | |
12871 | return False; | |
12872 | else | |
12873 | S := Scope (S); | |
12874 | end if; | |
12875 | end loop; | |
12876 | ||
fbf5a39b | 12877 | return Is_Init_Proc (S); |
996ae0b0 RK |
12878 | end Within_Init_Proc; |
12879 | ||
12880 | ---------------- | |
12881 | -- Wrong_Type -- | |
12882 | ---------------- | |
12883 | ||
12884 | procedure Wrong_Type (Expr : Node_Id; Expected_Type : Entity_Id) is | |
4fdebd93 AC |
12885 | Found_Type : constant Entity_Id := First_Subtype (Etype (Expr)); |
12886 | Expec_Type : constant Entity_Id := First_Subtype (Expected_Type); | |
35a1c212 AC |
12887 | |
12888 | Matching_Field : Entity_Id; | |
12889 | -- Entity to give a more precise suggestion on how to write a one- | |
12890 | -- element positional aggregate. | |
996ae0b0 RK |
12891 | |
12892 | function Has_One_Matching_Field return Boolean; | |
482a63fb ES |
12893 | -- Determines if Expec_Type is a record type with a single component or |
12894 | -- discriminant whose type matches the found type or is one dimensional | |
12895 | -- array whose component type matches the found type. | |
12896 | ||
12897 | ---------------------------- | |
12898 | -- Has_One_Matching_Field -- | |
12899 | ---------------------------- | |
996ae0b0 RK |
12900 | |
12901 | function Has_One_Matching_Field return Boolean is | |
12902 | E : Entity_Id; | |
12903 | ||
12904 | begin | |
35a1c212 AC |
12905 | Matching_Field := Empty; |
12906 | ||
996ae0b0 RK |
12907 | if Is_Array_Type (Expec_Type) |
12908 | and then Number_Dimensions (Expec_Type) = 1 | |
12909 | and then | |
12910 | Covers (Etype (Component_Type (Expec_Type)), Found_Type) | |
12911 | then | |
35a1c212 AC |
12912 | -- Use type name if available. This excludes multidimensional |
12913 | -- arrays and anonymous arrays. | |
12914 | ||
12915 | if Comes_From_Source (Expec_Type) then | |
12916 | Matching_Field := Expec_Type; | |
12917 | ||
993f8920 | 12918 | -- For an assignment, use name of target |
35a1c212 AC |
12919 | |
12920 | elsif Nkind (Parent (Expr)) = N_Assignment_Statement | |
12921 | and then Is_Entity_Name (Name (Parent (Expr))) | |
12922 | then | |
12923 | Matching_Field := Entity (Name (Parent (Expr))); | |
12924 | end if; | |
12925 | ||
996ae0b0 RK |
12926 | return True; |
12927 | ||
12928 | elsif not Is_Record_Type (Expec_Type) then | |
12929 | return False; | |
12930 | ||
12931 | else | |
12932 | E := First_Entity (Expec_Type); | |
996ae0b0 RK |
12933 | loop |
12934 | if No (E) then | |
12935 | return False; | |
12936 | ||
12937 | elsif (Ekind (E) /= E_Discriminant | |
12938 | and then Ekind (E) /= E_Component) | |
12939 | or else (Chars (E) = Name_uTag | |
12940 | or else Chars (E) = Name_uParent) | |
12941 | then | |
12942 | Next_Entity (E); | |
12943 | ||
12944 | else | |
12945 | exit; | |
12946 | end if; | |
12947 | end loop; | |
12948 | ||
12949 | if not Covers (Etype (E), Found_Type) then | |
12950 | return False; | |
12951 | ||
12952 | elsif Present (Next_Entity (E)) then | |
12953 | return False; | |
12954 | ||
12955 | else | |
35a1c212 | 12956 | Matching_Field := E; |
996ae0b0 RK |
12957 | return True; |
12958 | end if; | |
12959 | end if; | |
12960 | end Has_One_Matching_Field; | |
12961 | ||
12962 | -- Start of processing for Wrong_Type | |
12963 | ||
12964 | begin | |
12965 | -- Don't output message if either type is Any_Type, or if a message | |
12966 | -- has already been posted for this node. We need to do the latter | |
12967 | -- check explicitly (it is ordinarily done in Errout), because we | |
12968 | -- are using ! to force the output of the error messages. | |
12969 | ||
12970 | if Expec_Type = Any_Type | |
12971 | or else Found_Type = Any_Type | |
12972 | or else Error_Posted (Expr) | |
12973 | then | |
12974 | return; | |
12975 | ||
12976 | -- In an instance, there is an ongoing problem with completion of | |
12977 | -- type derived from private types. Their structure is what Gigi | |
12978 | -- expects, but the Etype is the parent type rather than the | |
12979 | -- derived private type itself. Do not flag error in this case. The | |
12980 | -- private completion is an entity without a parent, like an Itype. | |
12981 | -- Similarly, full and partial views may be incorrect in the instance. | |
12982 | -- There is no simple way to insure that it is consistent ??? | |
12983 | ||
12984 | elsif In_Instance then | |
996ae0b0 | 12985 | if Etype (Etype (Expr)) = Etype (Expected_Type) |
fbf5a39b AC |
12986 | and then |
12987 | (Has_Private_Declaration (Expected_Type) | |
12988 | or else Has_Private_Declaration (Etype (Expr))) | |
996ae0b0 RK |
12989 | and then No (Parent (Expected_Type)) |
12990 | then | |
12991 | return; | |
12992 | end if; | |
12993 | end if; | |
12994 | ||
12995 | -- An interesting special check. If the expression is parenthesized | |
12996 | -- and its type corresponds to the type of the sole component of the | |
12997 | -- expected record type, or to the component type of the expected one | |
12998 | -- dimensional array type, then assume we have a bad aggregate attempt. | |
12999 | ||
13000 | if Nkind (Expr) in N_Subexpr | |
13001 | and then Paren_Count (Expr) /= 0 | |
13002 | and then Has_One_Matching_Field | |
13003 | then | |
13004 | Error_Msg_N ("positional aggregate cannot have one component", Expr); | |
35a1c212 AC |
13005 | if Present (Matching_Field) then |
13006 | if Is_Array_Type (Expec_Type) then | |
13007 | Error_Msg_NE | |
13008 | ("\write instead `&''First ='> ...`", Expr, Matching_Field); | |
13009 | ||
13010 | else | |
13011 | Error_Msg_NE | |
13012 | ("\write instead `& ='> ...`", Expr, Matching_Field); | |
13013 | end if; | |
13014 | end if; | |
996ae0b0 RK |
13015 | |
13016 | -- Another special check, if we are looking for a pool-specific access | |
13017 | -- type and we found an E_Access_Attribute_Type, then we have the case | |
13018 | -- of an Access attribute being used in a context which needs a pool- | |
13019 | -- specific type, which is never allowed. The one extra check we make | |
13020 | -- is that the expected designated type covers the Found_Type. | |
13021 | ||
13022 | elsif Is_Access_Type (Expec_Type) | |
13023 | and then Ekind (Found_Type) = E_Access_Attribute_Type | |
13024 | and then Ekind (Base_Type (Expec_Type)) /= E_General_Access_Type | |
13025 | and then Ekind (Base_Type (Expec_Type)) /= E_Anonymous_Access_Type | |
13026 | and then Covers | |
13027 | (Designated_Type (Expec_Type), Designated_Type (Found_Type)) | |
13028 | then | |
9f5b6c7f AC |
13029 | Error_Msg_N -- CODEFIX |
13030 | ("result must be general access type!", Expr); | |
13031 | Error_Msg_NE -- CODEFIX | |
13032 | ("add ALL to }!", Expr, Expec_Type); | |
996ae0b0 | 13033 | |
1b6c95c4 RD |
13034 | -- Another special check, if the expected type is an integer type, |
13035 | -- but the expression is of type System.Address, and the parent is | |
13036 | -- an addition or subtraction operation whose left operand is the | |
13037 | -- expression in question and whose right operand is of an integral | |
13038 | -- type, then this is an attempt at address arithmetic, so give | |
13039 | -- appropriate message. | |
13040 | ||
13041 | elsif Is_Integer_Type (Expec_Type) | |
13042 | and then Is_RTE (Found_Type, RE_Address) | |
13043 | and then (Nkind (Parent (Expr)) = N_Op_Add | |
13044 | or else | |
13045 | Nkind (Parent (Expr)) = N_Op_Subtract) | |
13046 | and then Expr = Left_Opnd (Parent (Expr)) | |
13047 | and then Is_Integer_Type (Etype (Right_Opnd (Parent (Expr)))) | |
13048 | then | |
13049 | Error_Msg_N | |
13050 | ("address arithmetic not predefined in package System", | |
13051 | Parent (Expr)); | |
ed2233dc | 13052 | Error_Msg_N |
1b6c95c4 RD |
13053 | ("\possible missing with/use of System.Storage_Elements", |
13054 | Parent (Expr)); | |
13055 | return; | |
13056 | ||
996ae0b0 RK |
13057 | -- If the expected type is an anonymous access type, as for access |
13058 | -- parameters and discriminants, the error is on the designated types. | |
13059 | ||
13060 | elsif Ekind (Expec_Type) = E_Anonymous_Access_Type then | |
13061 | if Comes_From_Source (Expec_Type) then | |
13062 | Error_Msg_NE ("expected}!", Expr, Expec_Type); | |
13063 | else | |
13064 | Error_Msg_NE | |
13065 | ("expected an access type with designated}", | |
13066 | Expr, Designated_Type (Expec_Type)); | |
13067 | end if; | |
13068 | ||
13069 | if Is_Access_Type (Found_Type) | |
13070 | and then not Comes_From_Source (Found_Type) | |
13071 | then | |
13072 | Error_Msg_NE | |
9b0986f8 | 13073 | ("\\found an access type with designated}!", |
996ae0b0 RK |
13074 | Expr, Designated_Type (Found_Type)); |
13075 | else | |
13076 | if From_With_Type (Found_Type) then | |
9b0986f8 | 13077 | Error_Msg_NE ("\\found incomplete}!", Expr, Found_Type); |
9e87a68d | 13078 | Error_Msg_Qual_Level := 99; |
9f5b6c7f AC |
13079 | Error_Msg_NE -- CODEFIX |
13080 | ("\\missing `WITH &;", Expr, Scope (Found_Type)); | |
9e87a68d | 13081 | Error_Msg_Qual_Level := 0; |
996ae0b0 RK |
13082 | else |
13083 | Error_Msg_NE ("found}!", Expr, Found_Type); | |
13084 | end if; | |
13085 | end if; | |
13086 | ||
13087 | -- Normal case of one type found, some other type expected | |
13088 | ||
13089 | else | |
9b0986f8 RD |
13090 | -- If the names of the two types are the same, see if some number |
13091 | -- of levels of qualification will help. Don't try more than three | |
13092 | -- levels, and if we get to standard, it's no use (and probably | |
13093 | -- represents an error in the compiler) Also do not bother with | |
13094 | -- internal scope names. | |
996ae0b0 RK |
13095 | |
13096 | declare | |
13097 | Expec_Scope : Entity_Id; | |
13098 | Found_Scope : Entity_Id; | |
13099 | ||
13100 | begin | |
13101 | Expec_Scope := Expec_Type; | |
13102 | Found_Scope := Found_Type; | |
13103 | ||
13104 | for Levels in Int range 0 .. 3 loop | |
13105 | if Chars (Expec_Scope) /= Chars (Found_Scope) then | |
13106 | Error_Msg_Qual_Level := Levels; | |
13107 | exit; | |
13108 | end if; | |
13109 | ||
13110 | Expec_Scope := Scope (Expec_Scope); | |
13111 | Found_Scope := Scope (Found_Scope); | |
13112 | ||
13113 | exit when Expec_Scope = Standard_Standard | |
6332d842 TQ |
13114 | or else Found_Scope = Standard_Standard |
13115 | or else not Comes_From_Source (Expec_Scope) | |
13116 | or else not Comes_From_Source (Found_Scope); | |
996ae0b0 RK |
13117 | end loop; |
13118 | end; | |
13119 | ||
6332d842 TQ |
13120 | if Is_Record_Type (Expec_Type) |
13121 | and then Present (Corresponding_Remote_Type (Expec_Type)) | |
13122 | then | |
13123 | Error_Msg_NE ("expected}!", Expr, | |
13124 | Corresponding_Remote_Type (Expec_Type)); | |
13125 | else | |
13126 | Error_Msg_NE ("expected}!", Expr, Expec_Type); | |
13127 | end if; | |
996ae0b0 RK |
13128 | |
13129 | if Is_Entity_Name (Expr) | |
21024a39 | 13130 | and then Is_Package_Or_Generic_Package (Entity (Expr)) |
996ae0b0 | 13131 | then |
9b0986f8 | 13132 | Error_Msg_N ("\\found package name!", Expr); |
996ae0b0 RK |
13133 | |
13134 | elsif Is_Entity_Name (Expr) | |
13135 | and then | |
13136 | (Ekind (Entity (Expr)) = E_Procedure | |
13137 | or else | |
13138 | Ekind (Entity (Expr)) = E_Generic_Procedure) | |
13139 | then | |
18c0ecbe | 13140 | if Ekind (Expec_Type) = E_Access_Subprogram_Type then |
ed2233dc | 13141 | Error_Msg_N |
18c0ecbe AC |
13142 | ("found procedure name, possibly missing Access attribute!", |
13143 | Expr); | |
13144 | else | |
9b0986f8 RD |
13145 | Error_Msg_N |
13146 | ("\\found procedure name instead of function!", Expr); | |
18c0ecbe AC |
13147 | end if; |
13148 | ||
13149 | elsif Nkind (Expr) = N_Function_Call | |
13150 | and then Ekind (Expec_Type) = E_Access_Subprogram_Type | |
13151 | and then Etype (Designated_Type (Expec_Type)) = Etype (Expr) | |
13152 | and then No (Parameter_Associations (Expr)) | |
13153 | then | |
ed2233dc | 13154 | Error_Msg_N |
482a63fb ES |
13155 | ("found function name, possibly missing Access attribute!", |
13156 | Expr); | |
996ae0b0 | 13157 | |
15ce9ca2 | 13158 | -- Catch common error: a prefix or infix operator which is not |
996ae0b0 RK |
13159 | -- directly visible because the type isn't. |
13160 | ||
13161 | elsif Nkind (Expr) in N_Op | |
13162 | and then Is_Overloaded (Expr) | |
13163 | and then not Is_Immediately_Visible (Expec_Type) | |
13164 | and then not Is_Potentially_Use_Visible (Expec_Type) | |
13165 | and then not In_Use (Expec_Type) | |
13166 | and then Has_Compatible_Type (Right_Opnd (Expr), Expec_Type) | |
13167 | then | |
ed2233dc | 13168 | Error_Msg_N |
482a63fb | 13169 | ("operator of the type is not directly visible!", Expr); |
996ae0b0 | 13170 | |
a9f4e3d2 AC |
13171 | elsif Ekind (Found_Type) = E_Void |
13172 | and then Present (Parent (Found_Type)) | |
13173 | and then Nkind (Parent (Found_Type)) = N_Full_Type_Declaration | |
13174 | then | |
9b0986f8 | 13175 | Error_Msg_NE ("\\found premature usage of}!", Expr, Found_Type); |
c45b6ae0 | 13176 | |
996ae0b0 | 13177 | else |
9b0986f8 | 13178 | Error_Msg_NE ("\\found}!", Expr, Found_Type); |
996ae0b0 RK |
13179 | end if; |
13180 | ||
3ac48943 RD |
13181 | -- A special check for cases like M1 and M2 = 0 where M1 and M2 are |
13182 | -- of the same modular type, and (M1 and M2) = 0 was intended. | |
13183 | ||
13184 | if Expec_Type = Standard_Boolean | |
13185 | and then Is_Modular_Integer_Type (Found_Type) | |
13186 | and then Nkind_In (Parent (Expr), N_Op_And, N_Op_Or, N_Op_Xor) | |
13187 | and then Nkind (Right_Opnd (Parent (Expr))) in N_Op_Compare | |
13188 | then | |
13189 | declare | |
13190 | Op : constant Node_Id := Right_Opnd (Parent (Expr)); | |
13191 | L : constant Node_Id := Left_Opnd (Op); | |
13192 | R : constant Node_Id := Right_Opnd (Op); | |
13193 | begin | |
3acdda2d AC |
13194 | -- The case for the message is when the left operand of the |
13195 | -- comparison is the same modular type, or when it is an | |
13196 | -- integer literal (or other universal integer expression), | |
13197 | -- which would have been typed as the modular type if the | |
13198 | -- parens had been there. | |
13199 | ||
13200 | if (Etype (L) = Found_Type | |
13201 | or else | |
13202 | Etype (L) = Universal_Integer) | |
3ac48943 RD |
13203 | and then Is_Integer_Type (Etype (R)) |
13204 | then | |
13205 | Error_Msg_N | |
13206 | ("\\possible missing parens for modular operation", Expr); | |
13207 | end if; | |
13208 | end; | |
13209 | end if; | |
13210 | ||
13211 | -- Reset error message qualification indication | |
13212 | ||
996ae0b0 RK |
13213 | Error_Msg_Qual_Level := 0; |
13214 | end if; | |
13215 | end Wrong_Type; | |
13216 | ||
13217 | end Sem_Util; |