]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ada/sem_ch13.adb
2011-10-13 Tom de Vries <tom@codesourcery.com>
[thirdparty/gcc.git] / gcc / ada / sem_ch13.adb
CommitLineData
d6f39728 1------------------------------------------------------------------------------
7189d17f 2-- --
d6f39728 3-- GNAT COMPILER COMPONENTS --
4-- --
5-- S E M _ C H 1 3 --
6-- --
7-- B o d y --
8-- --
9f1130cc 9-- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
d6f39728 10-- --
11-- GNAT is free software; you can redistribute it and/or modify it under --
12-- terms of the GNU General Public License as published by the Free Soft- --
80df182a 13-- ware Foundation; either version 3, or (at your option) any later ver- --
d6f39728 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 --
80df182a 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. --
d6f39728 20-- --
21-- GNAT was originally developed by the GNAT team at New York University. --
e78e8c8e 22-- Extensive contributions were provided by Ada Core Technologies Inc. --
d6f39728 23-- --
24------------------------------------------------------------------------------
25
ae888dbd 26with Aspects; use Aspects;
d6f39728 27with Atree; use Atree;
713c00d6 28with Checks; use Checks;
d6f39728 29with Einfo; use Einfo;
d00681a7 30with Elists; use Elists;
d6f39728 31with Errout; use Errout;
d00681a7 32with Exp_Disp; use Exp_Disp;
d6f39728 33with Exp_Tss; use Exp_Tss;
34with Exp_Util; use Exp_Util;
d6f39728 35with Lib; use Lib;
83f8f0a6 36with Lib.Xref; use Lib.Xref;
15ebb600 37with Namet; use Namet;
d6f39728 38with Nlists; use Nlists;
39with Nmake; use Nmake;
40with Opt; use Opt;
e0521a36 41with Restrict; use Restrict;
42with Rident; use Rident;
d6f39728 43with Rtsfind; use Rtsfind;
44with Sem; use Sem;
d60c9ff7 45with Sem_Aux; use Sem_Aux;
40ca69b9 46with Sem_Ch3; use Sem_Ch3;
490beba6 47with Sem_Ch6; use Sem_Ch6;
d6f39728 48with Sem_Ch8; use Sem_Ch8;
49with Sem_Eval; use Sem_Eval;
50with Sem_Res; use Sem_Res;
51with Sem_Type; use Sem_Type;
52with Sem_Util; use Sem_Util;
44e4341e 53with Sem_Warn; use Sem_Warn;
1e3c4ae6 54with Sinput; use Sinput;
9dfe12ae 55with Snames; use Snames;
d6f39728 56with Stand; use Stand;
57with Sinfo; use Sinfo;
5b5df4a9 58with Stringt; use Stringt;
93735cb8 59with Targparm; use Targparm;
d6f39728 60with Ttypes; use Ttypes;
61with Tbuild; use Tbuild;
62with Urealp; use Urealp;
f42f24d7 63with Warnsw; use Warnsw;
d6f39728 64
bfa5a9d9 65with GNAT.Heap_Sort_G;
d6f39728 66
67package body Sem_Ch13 is
68
69 SSU : constant Pos := System_Storage_Unit;
70 -- Convenient short hand for commonly used constant
71
72 -----------------------
73 -- Local Subprograms --
74 -----------------------
75
1d366b32 76 procedure Alignment_Check_For_Size_Change (Typ : Entity_Id; Size : Uint);
77 -- This routine is called after setting one of the sizes of type entity
78 -- Typ to Size. The purpose is to deal with the situation of a derived
79 -- type whose inherited alignment is no longer appropriate for the new
80 -- size value. In this case, we reset the Alignment to unknown.
d6f39728 81
490beba6 82 procedure Build_Predicate_Function (Typ : Entity_Id; N : Node_Id);
9dc88aea 83 -- If Typ has predicates (indicated by Has_Predicates being set for Typ,
84 -- then either there are pragma Invariant entries on the rep chain for the
6fb3c314 85 -- type (note that Predicate aspects are converted to pragma Predicate), or
490beba6 86 -- there are inherited aspects from a parent type, or ancestor subtypes.
87 -- This procedure builds the spec and body for the Predicate function that
88 -- tests these predicates. N is the freeze node for the type. The spec of
89 -- the function is inserted before the freeze node, and the body of the
6fb3c314 90 -- function is inserted after the freeze node.
9dc88aea 91
d97beb2f 92 procedure Build_Static_Predicate
93 (Typ : Entity_Id;
94 Expr : Node_Id;
95 Nam : Name_Id);
d7c2851f 96 -- Given a predicated type Typ, where Typ is a discrete static subtype,
97 -- whose predicate expression is Expr, tests if Expr is a static predicate,
98 -- and if so, builds the predicate range list. Nam is the name of the one
99 -- argument to the predicate function. Occurrences of the type name in the
6fb3c314 100 -- predicate expression have been replaced by identifier references to this
d7c2851f 101 -- name, which is unique, so any identifier with Chars matching Nam must be
102 -- a reference to the type. If the predicate is non-static, this procedure
103 -- returns doing nothing. If the predicate is static, then the predicate
104 -- list is stored in Static_Predicate (Typ), and the Expr is rewritten as
105 -- a canonicalized membership operation.
d97beb2f 106
d6f39728 107 function Get_Alignment_Value (Expr : Node_Id) return Uint;
108 -- Given the expression for an alignment value, returns the corresponding
109 -- Uint value. If the value is inappropriate, then error messages are
110 -- posted as required, and a value of No_Uint is returned.
111
112 function Is_Operational_Item (N : Node_Id) return Boolean;
1e3c4ae6 113 -- A specification for a stream attribute is allowed before the full type
114 -- is declared, as explained in AI-00137 and the corrigendum. Attributes
115 -- that do not specify a representation characteristic are operational
116 -- attributes.
d6f39728 117
44e4341e 118 procedure New_Stream_Subprogram
d6f39728 119 (N : Node_Id;
120 Ent : Entity_Id;
121 Subp : Entity_Id;
9dfe12ae 122 Nam : TSS_Name_Type);
44e4341e 123 -- Create a subprogram renaming of a given stream attribute to the
124 -- designated subprogram and then in the tagged case, provide this as a
125 -- primitive operation, or in the non-tagged case make an appropriate TSS
126 -- entry. This is more properly an expansion activity than just semantics,
127 -- but the presence of user-defined stream functions for limited types is a
128 -- legality check, which is why this takes place here rather than in
129 -- exp_ch13, where it was previously. Nam indicates the name of the TSS
130 -- function to be generated.
9dfe12ae 131 --
f15731c4 132 -- To avoid elaboration anomalies with freeze nodes, for untagged types
133 -- we generate both a subprogram declaration and a subprogram renaming
134 -- declaration, so that the attribute specification is handled as a
135 -- renaming_as_body. For tagged types, the specification is one of the
136 -- primitive specs.
137
2072eaa9 138 generic
139 with procedure Replace_Type_Reference (N : Node_Id);
140 procedure Replace_Type_References_Generic (N : Node_Id; TName : Name_Id);
141 -- This is used to scan an expression for a predicate or invariant aspect
142 -- replacing occurrences of the name TName (the name of the subtype to
143 -- which the aspect applies) with appropriate references to the parameter
144 -- of the predicate function or invariant procedure. The procedure passed
145 -- as a generic parameter does the actual replacement of node N, which is
146 -- either a simple direct reference to TName, or a selected component that
147 -- represents an appropriately qualified occurrence of TName.
148
b77e4501 149 procedure Set_Biased
150 (E : Entity_Id;
151 N : Node_Id;
152 Msg : String;
153 Biased : Boolean := True);
154 -- If Biased is True, sets Has_Biased_Representation flag for E, and
155 -- outputs a warning message at node N if Warn_On_Biased_Representation is
156 -- is True. This warning inserts the string Msg to describe the construct
157 -- causing biasing.
158
d6f39728 159 ----------------------------------------------
160 -- Table for Validate_Unchecked_Conversions --
161 ----------------------------------------------
162
163 -- The following table collects unchecked conversions for validation.
164 -- Entries are made by Validate_Unchecked_Conversion and then the
165 -- call to Validate_Unchecked_Conversions does the actual error
166 -- checking and posting of warnings. The reason for this delayed
167 -- processing is to take advantage of back-annotations of size and
1a34e48c 168 -- alignment values performed by the back end.
d6f39728 169
299480f9 170 -- Note: the reason we store a Source_Ptr value instead of a Node_Id
171 -- is that by the time Validate_Unchecked_Conversions is called, Sprint
172 -- will already have modified all Sloc values if the -gnatD option is set.
173
d6f39728 174 type UC_Entry is record
299480f9 175 Eloc : Source_Ptr; -- node used for posting warnings
176 Source : Entity_Id; -- source type for unchecked conversion
177 Target : Entity_Id; -- target type for unchecked conversion
d6f39728 178 end record;
179
180 package Unchecked_Conversions is new Table.Table (
181 Table_Component_Type => UC_Entry,
182 Table_Index_Type => Int,
183 Table_Low_Bound => 1,
184 Table_Initial => 50,
185 Table_Increment => 200,
186 Table_Name => "Unchecked_Conversions");
187
83f8f0a6 188 ----------------------------------------
189 -- Table for Validate_Address_Clauses --
190 ----------------------------------------
191
192 -- If an address clause has the form
193
194 -- for X'Address use Expr
195
196 -- where Expr is of the form Y'Address or recursively is a reference
197 -- to a constant of either of these forms, and X and Y are entities of
198 -- objects, then if Y has a smaller alignment than X, that merits a
199 -- warning about possible bad alignment. The following table collects
200 -- address clauses of this kind. We put these in a table so that they
201 -- can be checked after the back end has completed annotation of the
202 -- alignments of objects, since we can catch more cases that way.
203
204 type Address_Clause_Check_Record is record
205 N : Node_Id;
206 -- The address clause
207
208 X : Entity_Id;
209 -- The entity of the object overlaying Y
210
211 Y : Entity_Id;
212 -- The entity of the object being overlaid
d6da7448 213
214 Off : Boolean;
6fb3c314 215 -- Whether the address is offset within Y
83f8f0a6 216 end record;
217
218 package Address_Clause_Checks is new Table.Table (
219 Table_Component_Type => Address_Clause_Check_Record,
220 Table_Index_Type => Int,
221 Table_Low_Bound => 1,
222 Table_Initial => 20,
223 Table_Increment => 200,
224 Table_Name => "Address_Clause_Checks");
225
59ac57b5 226 -----------------------------------------
227 -- Adjust_Record_For_Reverse_Bit_Order --
228 -----------------------------------------
229
230 procedure Adjust_Record_For_Reverse_Bit_Order (R : Entity_Id) is
67278d60 231 Comp : Node_Id;
232 CC : Node_Id;
59ac57b5 233
234 begin
67278d60 235 -- Processing depends on version of Ada
59ac57b5 236
6797073f 237 -- For Ada 95, we just renumber bits within a storage unit. We do the
568b0f6a 238 -- same for Ada 83 mode, since we recognize the Bit_Order attribute in
ab19a652 239 -- Ada 83, and are free to add this extension.
6797073f 240
241 if Ada_Version < Ada_2005 then
242 Comp := First_Component_Or_Discriminant (R);
243 while Present (Comp) loop
244 CC := Component_Clause (Comp);
245
246 -- If component clause is present, then deal with the non-default
247 -- bit order case for Ada 95 mode.
248
249 -- We only do this processing for the base type, and in fact that
250 -- is important, since otherwise if there are record subtypes, we
251 -- could reverse the bits once for each subtype, which is wrong.
252
253 if Present (CC)
254 and then Ekind (R) = E_Record_Type
255 then
256 declare
257 CFB : constant Uint := Component_Bit_Offset (Comp);
258 CSZ : constant Uint := Esize (Comp);
259 CLC : constant Node_Id := Component_Clause (Comp);
260 Pos : constant Node_Id := Position (CLC);
261 FB : constant Node_Id := First_Bit (CLC);
262
263 Storage_Unit_Offset : constant Uint :=
264 CFB / System_Storage_Unit;
265
266 Start_Bit : constant Uint :=
267 CFB mod System_Storage_Unit;
59ac57b5 268
6797073f 269 begin
270 -- Cases where field goes over storage unit boundary
59ac57b5 271
6797073f 272 if Start_Bit + CSZ > System_Storage_Unit then
59ac57b5 273
6797073f 274 -- Allow multi-byte field but generate warning
59ac57b5 275
6797073f 276 if Start_Bit mod System_Storage_Unit = 0
277 and then CSZ mod System_Storage_Unit = 0
278 then
279 Error_Msg_N
280 ("multi-byte field specified with non-standard"
281 & " Bit_Order?", CLC);
31486bc0 282
6797073f 283 if Bytes_Big_Endian then
31486bc0 284 Error_Msg_N
6797073f 285 ("bytes are not reversed "
286 & "(component is big-endian)?", CLC);
31486bc0 287 else
288 Error_Msg_N
6797073f 289 ("bytes are not reversed "
290 & "(component is little-endian)?", CLC);
31486bc0 291 end if;
59ac57b5 292
6797073f 293 -- Do not allow non-contiguous field
59ac57b5 294
67278d60 295 else
6797073f 296 Error_Msg_N
297 ("attempt to specify non-contiguous field "
298 & "not permitted", CLC);
299 Error_Msg_N
300 ("\caused by non-standard Bit_Order "
301 & "specified", CLC);
302 Error_Msg_N
303 ("\consider possibility of using "
304 & "Ada 2005 mode here", CLC);
305 end if;
59ac57b5 306
6797073f 307 -- Case where field fits in one storage unit
59ac57b5 308
6797073f 309 else
310 -- Give warning if suspicious component clause
59ac57b5 311
6797073f 312 if Intval (FB) >= System_Storage_Unit
313 and then Warn_On_Reverse_Bit_Order
314 then
315 Error_Msg_N
316 ("?Bit_Order clause does not affect " &
317 "byte ordering", Pos);
318 Error_Msg_Uint_1 :=
319 Intval (Pos) + Intval (FB) /
320 System_Storage_Unit;
321 Error_Msg_N
322 ("?position normalized to ^ before bit " &
323 "order interpreted", Pos);
324 end if;
59ac57b5 325
6797073f 326 -- Here is where we fix up the Component_Bit_Offset value
327 -- to account for the reverse bit order. Some examples of
328 -- what needs to be done are:
bfa5a9d9 329
6797073f 330 -- First_Bit .. Last_Bit Component_Bit_Offset
331 -- old new old new
59ac57b5 332
6797073f 333 -- 0 .. 0 7 .. 7 0 7
334 -- 0 .. 1 6 .. 7 0 6
335 -- 0 .. 2 5 .. 7 0 5
336 -- 0 .. 7 0 .. 7 0 4
59ac57b5 337
6797073f 338 -- 1 .. 1 6 .. 6 1 6
339 -- 1 .. 4 3 .. 6 1 3
340 -- 4 .. 7 0 .. 3 4 0
59ac57b5 341
6797073f 342 -- The rule is that the first bit is is obtained by
343 -- subtracting the old ending bit from storage_unit - 1.
59ac57b5 344
6797073f 345 Set_Component_Bit_Offset
346 (Comp,
347 (Storage_Unit_Offset * System_Storage_Unit) +
348 (System_Storage_Unit - 1) -
349 (Start_Bit + CSZ - 1));
59ac57b5 350
6797073f 351 Set_Normalized_First_Bit
352 (Comp,
353 Component_Bit_Offset (Comp) mod
354 System_Storage_Unit);
355 end if;
356 end;
357 end if;
358
359 Next_Component_Or_Discriminant (Comp);
360 end loop;
361
362 -- For Ada 2005, we do machine scalar processing, as fully described In
363 -- AI-133. This involves gathering all components which start at the
364 -- same byte offset and processing them together. Same approach is still
365 -- valid in later versions including Ada 2012.
366
367 else
368 declare
369 Max_Machine_Scalar_Size : constant Uint :=
370 UI_From_Int
371 (Standard_Long_Long_Integer_Size);
67278d60 372 -- We use this as the maximum machine scalar size
59ac57b5 373
6797073f 374 Num_CC : Natural;
375 SSU : constant Uint := UI_From_Int (System_Storage_Unit);
59ac57b5 376
6797073f 377 begin
378 -- This first loop through components does two things. First it
379 -- deals with the case of components with component clauses whose
380 -- length is greater than the maximum machine scalar size (either
381 -- accepting them or rejecting as needed). Second, it counts the
382 -- number of components with component clauses whose length does
383 -- not exceed this maximum for later processing.
67278d60 384
6797073f 385 Num_CC := 0;
386 Comp := First_Component_Or_Discriminant (R);
387 while Present (Comp) loop
388 CC := Component_Clause (Comp);
67278d60 389
6797073f 390 if Present (CC) then
391 declare
392 Fbit : constant Uint :=
393 Static_Integer (First_Bit (CC));
b38e4131 394 Lbit : constant Uint :=
395 Static_Integer (Last_Bit (CC));
67278d60 396
6797073f 397 begin
b38e4131 398 -- Case of component with last bit >= max machine scalar
67278d60 399
b38e4131 400 if Lbit >= Max_Machine_Scalar_Size then
67278d60 401
b38e4131 402 -- This is allowed only if first bit is zero, and
403 -- last bit + 1 is a multiple of storage unit size.
67278d60 404
b38e4131 405 if Fbit = 0 and then (Lbit + 1) mod SSU = 0 then
67278d60 406
b38e4131 407 -- This is the case to give a warning if enabled
67278d60 408
b38e4131 409 if Warn_On_Reverse_Bit_Order then
410 Error_Msg_N
411 ("multi-byte field specified with "
412 & " non-standard Bit_Order?", CC);
413
414 if Bytes_Big_Endian then
415 Error_Msg_N
416 ("\bytes are not reversed "
417 & "(component is big-endian)?", CC);
418 else
419 Error_Msg_N
420 ("\bytes are not reversed "
421 & "(component is little-endian)?", CC);
422 end if;
423 end if;
67278d60 424
b38e4131 425 -- Give error message for RM 13.4.1(10) violation
67278d60 426
b38e4131 427 else
428 Error_Msg_FE
429 ("machine scalar rules not followed for&",
430 First_Bit (CC), Comp);
67278d60 431
b38e4131 432 Error_Msg_Uint_1 := Lbit;
433 Error_Msg_Uint_2 := Max_Machine_Scalar_Size;
434 Error_Msg_F
435 ("\last bit (^) exceeds maximum machine "
436 & "scalar size (^)",
437 First_Bit (CC));
67278d60 438
b38e4131 439 if (Lbit + 1) mod SSU /= 0 then
440 Error_Msg_Uint_1 := SSU;
441 Error_Msg_F
442 ("\and is not a multiple of Storage_Unit (^) "
0cafb066 443 & "(RM 13.4.1(10))",
b38e4131 444 First_Bit (CC));
6797073f 445
6797073f 446 else
b38e4131 447 Error_Msg_Uint_1 := Fbit;
448 Error_Msg_F
449 ("\and first bit (^) is non-zero "
0cafb066 450 & "(RM 13.4.1(10))",
b38e4131 451 First_Bit (CC));
67278d60 452 end if;
6797073f 453 end if;
59ac57b5 454
b38e4131 455 -- OK case of machine scalar related component clause,
456 -- For now, just count them.
59ac57b5 457
6797073f 458 else
459 Num_CC := Num_CC + 1;
460 end if;
461 end;
462 end if;
59ac57b5 463
6797073f 464 Next_Component_Or_Discriminant (Comp);
465 end loop;
59ac57b5 466
6797073f 467 -- We need to sort the component clauses on the basis of the
468 -- Position values in the clause, so we can group clauses with
469 -- the same Position. together to determine the relevant machine
470 -- scalar size.
59ac57b5 471
6797073f 472 Sort_CC : declare
473 Comps : array (0 .. Num_CC) of Entity_Id;
474 -- Array to collect component and discriminant entities. The
475 -- data starts at index 1, the 0'th entry is for the sort
476 -- routine.
59ac57b5 477
6797073f 478 function CP_Lt (Op1, Op2 : Natural) return Boolean;
479 -- Compare routine for Sort
59ac57b5 480
6797073f 481 procedure CP_Move (From : Natural; To : Natural);
482 -- Move routine for Sort
59ac57b5 483
6797073f 484 package Sorting is new GNAT.Heap_Sort_G (CP_Move, CP_Lt);
59ac57b5 485
6797073f 486 Start : Natural;
487 Stop : Natural;
488 -- Start and stop positions in the component list of the set of
489 -- components with the same starting position (that constitute
490 -- components in a single machine scalar).
59ac57b5 491
6797073f 492 MaxL : Uint;
493 -- Maximum last bit value of any component in this set
59ac57b5 494
6797073f 495 MSS : Uint;
496 -- Corresponding machine scalar size
67278d60 497
6797073f 498 -----------
499 -- CP_Lt --
500 -----------
67278d60 501
6797073f 502 function CP_Lt (Op1, Op2 : Natural) return Boolean is
503 begin
504 return Position (Component_Clause (Comps (Op1))) <
505 Position (Component_Clause (Comps (Op2)));
506 end CP_Lt;
67278d60 507
6797073f 508 -------------
509 -- CP_Move --
510 -------------
67278d60 511
6797073f 512 procedure CP_Move (From : Natural; To : Natural) is
513 begin
514 Comps (To) := Comps (From);
515 end CP_Move;
67278d60 516
517 -- Start of processing for Sort_CC
59ac57b5 518
6797073f 519 begin
b38e4131 520 -- Collect the machine scalar relevant component clauses
59ac57b5 521
6797073f 522 Num_CC := 0;
523 Comp := First_Component_Or_Discriminant (R);
524 while Present (Comp) loop
b38e4131 525 declare
526 CC : constant Node_Id := Component_Clause (Comp);
527
528 begin
529 -- Collect only component clauses whose last bit is less
530 -- than machine scalar size. Any component clause whose
531 -- last bit exceeds this value does not take part in
532 -- machine scalar layout considerations. The test for
533 -- Error_Posted makes sure we exclude component clauses
534 -- for which we already posted an error.
535
536 if Present (CC)
537 and then not Error_Posted (Last_Bit (CC))
538 and then Static_Integer (Last_Bit (CC)) <
d64221a7 539 Max_Machine_Scalar_Size
b38e4131 540 then
541 Num_CC := Num_CC + 1;
542 Comps (Num_CC) := Comp;
543 end if;
544 end;
59ac57b5 545
6797073f 546 Next_Component_Or_Discriminant (Comp);
547 end loop;
67278d60 548
6797073f 549 -- Sort by ascending position number
67278d60 550
6797073f 551 Sorting.Sort (Num_CC);
67278d60 552
6797073f 553 -- We now have all the components whose size does not exceed
554 -- the max machine scalar value, sorted by starting position.
555 -- In this loop we gather groups of clauses starting at the
556 -- same position, to process them in accordance with AI-133.
67278d60 557
6797073f 558 Stop := 0;
559 while Stop < Num_CC loop
560 Start := Stop + 1;
561 Stop := Start;
562 MaxL :=
563 Static_Integer
564 (Last_Bit (Component_Clause (Comps (Start))));
67278d60 565 while Stop < Num_CC loop
6797073f 566 if Static_Integer
567 (Position (Component_Clause (Comps (Stop + 1)))) =
568 Static_Integer
569 (Position (Component_Clause (Comps (Stop))))
570 then
571 Stop := Stop + 1;
572 MaxL :=
573 UI_Max
574 (MaxL,
575 Static_Integer
576 (Last_Bit
577 (Component_Clause (Comps (Stop)))));
578 else
579 exit;
580 end if;
581 end loop;
67278d60 582
6797073f 583 -- Now we have a group of component clauses from Start to
584 -- Stop whose positions are identical, and MaxL is the
585 -- maximum last bit value of any of these components.
586
587 -- We need to determine the corresponding machine scalar
588 -- size. This loop assumes that machine scalar sizes are
589 -- even, and that each possible machine scalar has twice
590 -- as many bits as the next smaller one.
591
592 MSS := Max_Machine_Scalar_Size;
593 while MSS mod 2 = 0
594 and then (MSS / 2) >= SSU
595 and then (MSS / 2) > MaxL
596 loop
597 MSS := MSS / 2;
598 end loop;
67278d60 599
6797073f 600 -- Here is where we fix up the Component_Bit_Offset value
601 -- to account for the reverse bit order. Some examples of
602 -- what needs to be done for the case of a machine scalar
603 -- size of 8 are:
67278d60 604
6797073f 605 -- First_Bit .. Last_Bit Component_Bit_Offset
606 -- old new old new
67278d60 607
6797073f 608 -- 0 .. 0 7 .. 7 0 7
609 -- 0 .. 1 6 .. 7 0 6
610 -- 0 .. 2 5 .. 7 0 5
611 -- 0 .. 7 0 .. 7 0 4
67278d60 612
6797073f 613 -- 1 .. 1 6 .. 6 1 6
614 -- 1 .. 4 3 .. 6 1 3
615 -- 4 .. 7 0 .. 3 4 0
67278d60 616
6797073f 617 -- The rule is that the first bit is obtained by subtracting
618 -- the old ending bit from machine scalar size - 1.
67278d60 619
6797073f 620 for C in Start .. Stop loop
621 declare
622 Comp : constant Entity_Id := Comps (C);
623 CC : constant Node_Id :=
624 Component_Clause (Comp);
625 LB : constant Uint :=
626 Static_Integer (Last_Bit (CC));
627 NFB : constant Uint := MSS - Uint_1 - LB;
628 NLB : constant Uint := NFB + Esize (Comp) - 1;
629 Pos : constant Uint :=
630 Static_Integer (Position (CC));
67278d60 631
6797073f 632 begin
633 if Warn_On_Reverse_Bit_Order then
634 Error_Msg_Uint_1 := MSS;
635 Error_Msg_N
636 ("info: reverse bit order in machine " &
637 "scalar of length^?", First_Bit (CC));
638 Error_Msg_Uint_1 := NFB;
639 Error_Msg_Uint_2 := NLB;
640
641 if Bytes_Big_Endian then
642 Error_Msg_NE
643 ("?\info: big-endian range for "
644 & "component & is ^ .. ^",
645 First_Bit (CC), Comp);
646 else
647 Error_Msg_NE
648 ("?\info: little-endian range "
649 & "for component & is ^ .. ^",
650 First_Bit (CC), Comp);
67278d60 651 end if;
6797073f 652 end if;
67278d60 653
6797073f 654 Set_Component_Bit_Offset (Comp, Pos * SSU + NFB);
655 Set_Normalized_First_Bit (Comp, NFB mod SSU);
656 end;
67278d60 657 end loop;
6797073f 658 end loop;
659 end Sort_CC;
660 end;
661 end if;
59ac57b5 662 end Adjust_Record_For_Reverse_Bit_Order;
663
1d366b32 664 -------------------------------------
665 -- Alignment_Check_For_Size_Change --
666 -------------------------------------
d6f39728 667
1d366b32 668 procedure Alignment_Check_For_Size_Change (Typ : Entity_Id; Size : Uint) is
d6f39728 669 begin
670 -- If the alignment is known, and not set by a rep clause, and is
671 -- inconsistent with the size being set, then reset it to unknown,
672 -- we assume in this case that the size overrides the inherited
673 -- alignment, and that the alignment must be recomputed.
674
675 if Known_Alignment (Typ)
676 and then not Has_Alignment_Clause (Typ)
1d366b32 677 and then Size mod (Alignment (Typ) * SSU) /= 0
d6f39728 678 then
679 Init_Alignment (Typ);
680 end if;
1d366b32 681 end Alignment_Check_For_Size_Change;
d6f39728 682
ae888dbd 683 -----------------------------------
684 -- Analyze_Aspect_Specifications --
685 -----------------------------------
686
21ea3a4f 687 procedure Analyze_Aspect_Specifications (N : Node_Id; E : Entity_Id) is
ae888dbd 688 Aspect : Node_Id;
d74fc39a 689 Aitem : Node_Id;
ae888dbd 690 Ent : Node_Id;
ae888dbd 691
21ea3a4f 692 L : constant List_Id := Aspect_Specifications (N);
693
ae888dbd 694 Ins_Node : Node_Id := N;
f54f1dff 695 -- Insert pragmas (except Pre/Post/Invariant/Predicate) after this node
d74fc39a 696
697 -- The general processing involves building an attribute definition
13dc58a7 698 -- clause or a pragma node that corresponds to the aspect. Then one
699 -- of two things happens:
d74fc39a 700
701 -- If we are required to delay the evaluation of this aspect to the
7d20685d 702 -- freeze point, we attach the corresponding pragma/attribute definition
703 -- clause to the aspect specification node, which is then placed in the
704 -- Rep Item chain. In this case we mark the entity by setting the flag
705 -- Has_Delayed_Aspects and we evaluate the rep item at the freeze point.
d74fc39a 706
707 -- If no delay is required, we just insert the pragma or attribute
708 -- after the declaration, and it will get processed by the normal
709 -- circuit. The From_Aspect_Specification flag is set on the pragma
710 -- or attribute definition node in either case to activate special
711 -- processing (e.g. not traversing the list of homonyms for inline).
712
95bc75fa 713 Delay_Required : Boolean := False;
d74fc39a 714 -- Set True if delay is required
ae888dbd 715
716 begin
21ea3a4f 717 pragma Assert (Present (L));
718
6fb3c314 719 -- Loop through aspects
f93e7257 720
ae888dbd 721 Aspect := First (L);
21ea3a4f 722 Aspect_Loop : while Present (Aspect) loop
ae888dbd 723 declare
94153a42 724 Loc : constant Source_Ptr := Sloc (Aspect);
725 Id : constant Node_Id := Identifier (Aspect);
726 Expr : constant Node_Id := Expression (Aspect);
727 Nam : constant Name_Id := Chars (Id);
728 A_Id : constant Aspect_Id := Get_Aspect_Id (Nam);
ae888dbd 729 Anod : Node_Id;
730
39e1f22f 731 Eloc : Source_Ptr := Sloc (Expr);
732 -- Source location of expression, modified when we split PPC's
733
21ea3a4f 734 procedure Check_False_Aspect_For_Derived_Type;
735 -- This procedure checks for the case of a false aspect for a
736 -- derived type, which improperly tries to cancel an aspect
737 -- inherited from the parent;
738
739 -----------------------------------------
740 -- Check_False_Aspect_For_Derived_Type --
741 -----------------------------------------
742
743 procedure Check_False_Aspect_For_Derived_Type is
744 begin
745 -- We are only checking derived types
746
747 if not Is_Derived_Type (E) then
748 return;
749 end if;
750
751 case A_Id is
752 when Aspect_Atomic | Aspect_Shared =>
753 if not Is_Atomic (E) then
754 return;
755 end if;
756
757 when Aspect_Atomic_Components =>
758 if not Has_Atomic_Components (E) then
759 return;
760 end if;
761
762 when Aspect_Discard_Names =>
763 if not Discard_Names (E) then
764 return;
765 end if;
766
767 when Aspect_Pack =>
768 if not Is_Packed (E) then
769 return;
770 end if;
771
772 when Aspect_Unchecked_Union =>
773 if not Is_Unchecked_Union (E) then
774 return;
775 end if;
776
777 when Aspect_Volatile =>
778 if not Is_Volatile (E) then
779 return;
780 end if;
781
782 when Aspect_Volatile_Components =>
783 if not Has_Volatile_Components (E) then
784 return;
785 end if;
786
787 when others =>
788 return;
789 end case;
790
791 -- Fall through means we are canceling an inherited aspect
792
793 Error_Msg_Name_1 := Nam;
794 Error_Msg_NE
795 ("derived type& inherits aspect%, cannot cancel", Expr, E);
796 end Check_False_Aspect_For_Derived_Type;
797
798 -- Start of processing for Aspect_Loop
799
ae888dbd 800 begin
fb7f2fc4 801 -- Skip aspect if already analyzed (not clear if this is needed)
802
803 if Analyzed (Aspect) then
804 goto Continue;
805 end if;
806
d7ed83a2 807 -- Check restriction No_Implementation_Aspect_Specifications
808
809 if Impl_Defined_Aspects (A_Id) then
810 Check_Restriction
811 (No_Implementation_Aspect_Specifications, Aspect);
812 end if;
813
814 -- Check restriction No_Specification_Of_Aspect
815
816 Check_Restriction_No_Specification_Of_Aspect (Aspect);
817
818 -- Analyze this aspect
819
fb7f2fc4 820 Set_Analyzed (Aspect);
d74fc39a 821 Set_Entity (Aspect, E);
822 Ent := New_Occurrence_Of (E, Sloc (Id));
823
1e3c4ae6 824 -- Check for duplicate aspect. Note that the Comes_From_Source
825 -- test allows duplicate Pre/Post's that we generate internally
826 -- to escape being flagged here.
ae888dbd 827
6c545057 828 if No_Duplicates_Allowed (A_Id) then
829 Anod := First (L);
830 while Anod /= Aspect loop
831 if Same_Aspect
832 (A_Id, Get_Aspect_Id (Chars (Identifier (Anod))))
833 and then Comes_From_Source (Aspect)
834 then
835 Error_Msg_Name_1 := Nam;
836 Error_Msg_Sloc := Sloc (Anod);
39e1f22f 837
6c545057 838 -- Case of same aspect specified twice
39e1f22f 839
6c545057 840 if Class_Present (Anod) = Class_Present (Aspect) then
841 if not Class_Present (Anod) then
842 Error_Msg_NE
843 ("aspect% for & previously given#",
844 Id, E);
845 else
846 Error_Msg_NE
847 ("aspect `%''Class` for & previously given#",
848 Id, E);
849 end if;
39e1f22f 850
6c545057 851 -- Case of Pre and Pre'Class both specified
39e1f22f 852
6c545057 853 elsif Nam = Name_Pre then
854 if Class_Present (Aspect) then
855 Error_Msg_NE
856 ("aspect `Pre''Class` for & is not allowed here",
857 Id, E);
858 Error_Msg_NE
859 ("\since aspect `Pre` previously given#",
860 Id, E);
39e1f22f 861
6c545057 862 else
863 Error_Msg_NE
864 ("aspect `Pre` for & is not allowed here",
865 Id, E);
866 Error_Msg_NE
867 ("\since aspect `Pre''Class` previously given#",
868 Id, E);
869 end if;
39e1f22f 870 end if;
39e1f22f 871
6c545057 872 -- Allowed case of X and X'Class both specified
873 end if;
ae888dbd 874
6c545057 875 Next (Anod);
876 end loop;
877 end if;
ae888dbd 878
7d20685d 879 -- Copy expression for later processing by the procedures
880 -- Check_Aspect_At_[Freeze_Point | End_Of_Declarations]
881
882 Set_Entity (Id, New_Copy_Tree (Expr));
883
ae888dbd 884 -- Processing based on specific aspect
885
d74fc39a 886 case A_Id is
ae888dbd 887
888 -- No_Aspect should be impossible
889
890 when No_Aspect =>
891 raise Program_Error;
892
5b5df4a9 893 -- Aspects taking an optional boolean argument. For all of
21ea3a4f 894 -- these we just create a matching pragma and insert it, if
895 -- the expression is missing or set to True. If the expression
896 -- is False, we can ignore the aspect with the exception that
897 -- in the case of a derived type, we must check for an illegal
898 -- attempt to cancel an inherited aspect.
0b424e9b 899
900 when Boolean_Aspects =>
901 Set_Is_Boolean_Aspect (Aspect);
ae888dbd 902
21ea3a4f 903 if Present (Expr)
904 and then Is_False (Static_Boolean (Expr))
905 then
906 Check_False_Aspect_For_Derived_Type;
907 goto Continue;
908 end if;
909
910 -- If True, build corresponding pragma node
d74fc39a 911
912 Aitem :=
94153a42 913 Make_Pragma (Loc,
d74fc39a 914 Pragma_Argument_Associations => New_List (Ent),
915 Pragma_Identifier =>
916 Make_Identifier (Sloc (Id), Chars (Id)));
917
21ea3a4f 918 -- Never need to delay for boolean aspects
ae888dbd 919
95bc75fa 920 pragma Assert (not Delay_Required);
ae888dbd 921
ddf1337b 922 -- Library unit aspects. These are boolean aspects, but we
21ea3a4f 923 -- have to do special things with the insertion, since the
924 -- pragma belongs inside the declarations of a package.
ddf1337b 925
926 when Library_Unit_Aspects =>
927 if Present (Expr)
928 and then Is_False (Static_Boolean (Expr))
929 then
930 goto Continue;
931 end if;
932
933 -- Build corresponding pragma node
934
935 Aitem :=
936 Make_Pragma (Loc,
937 Pragma_Argument_Associations => New_List (Ent),
938 Pragma_Identifier =>
939 Make_Identifier (Sloc (Id), Chars (Id)));
940
941 -- This requires special handling in the case of a package
942 -- declaration, the pragma needs to be inserted in the list
943 -- of declarations for the associated package. There is no
944 -- issue of visibility delay for these aspects.
945
946 if Nkind (N) = N_Package_Declaration then
947 if Nkind (Parent (N)) /= N_Compilation_Unit then
948 Error_Msg_N
949 ("incorrect context for library unit aspect&", Id);
950 else
951 Prepend
952 (Aitem, Visible_Declarations (Specification (N)));
953 end if;
954
955 goto Continue;
956 end if;
957
958 -- If not package declaration, no delay is required
959
95bc75fa 960 pragma Assert (not Delay_Required);
ddf1337b 961
81b424ac 962 -- Aspects related to container iterators. These aspects denote
963 -- subprograms, and thus must be delayed.
b57530b8 964
965 when Aspect_Constant_Indexing |
b57530b8 966 Aspect_Variable_Indexing =>
81b424ac 967
968 if not Is_Type (E) or else not Is_Tagged_Type (E) then
969 Error_Msg_N ("indexing applies to a tagged type", N);
970 end if;
971
972 Aitem :=
973 Make_Attribute_Definition_Clause (Loc,
974 Name => Ent,
975 Chars => Chars (Id),
976 Expression => Relocate_Node (Expr));
977
978 Delay_Required := True;
979 Set_Is_Delayed_Aspect (Aspect);
980
981 when Aspect_Default_Iterator |
982 Aspect_Iterator_Element =>
983
984 Aitem :=
985 Make_Attribute_Definition_Clause (Loc,
986 Name => Ent,
987 Chars => Chars (Id),
988 Expression => Relocate_Node (Expr));
989
990 Delay_Required := True;
991 Set_Is_Delayed_Aspect (Aspect);
b57530b8 992
993 when Aspect_Implicit_Dereference =>
b57530b8 994 if not Is_Type (E)
995 or else not Has_Discriminants (E)
996 then
997 Error_Msg_N
998 ("Aspect must apply to a type with discriminants", N);
999 goto Continue;
1000
1001 else
1002 declare
1003 Disc : Entity_Id;
1004
1005 begin
1006 Disc := First_Discriminant (E);
1007 while Present (Disc) loop
1008 if Chars (Expr) = Chars (Disc)
1009 and then Ekind (Etype (Disc)) =
1010 E_Anonymous_Access_Type
1011 then
1012 Set_Has_Implicit_Dereference (E);
1013 Set_Has_Implicit_Dereference (Disc);
1014 goto Continue;
1015 end if;
7947a439 1016
b57530b8 1017 Next_Discriminant (Disc);
1018 end loop;
1019
1020 -- Error if no proper access discriminant.
1021
1022 Error_Msg_NE
1023 ("not an access discriminant of&", Expr, E);
1024 end;
1025
1026 goto Continue;
1027 end if;
1028
5b5df4a9 1029 -- Aspects corresponding to attribute definition clauses
ae888dbd 1030
c8969ba6 1031 when Aspect_Address |
1032 Aspect_Alignment |
ae888dbd 1033 Aspect_Bit_Order |
1034 Aspect_Component_Size |
1035 Aspect_External_Tag |
0b424e9b 1036 Aspect_Input |
ae888dbd 1037 Aspect_Machine_Radix |
1038 Aspect_Object_Size |
0b424e9b 1039 Aspect_Output |
1040 Aspect_Read |
ae888dbd 1041 Aspect_Size |
7f694ca2 1042 Aspect_Small |
ae888dbd 1043 Aspect_Storage_Pool |
1044 Aspect_Storage_Size |
1045 Aspect_Stream_Size |
0b424e9b 1046 Aspect_Value_Size |
1047 Aspect_Write =>
d74fc39a 1048
1049 -- Construct the attribute definition clause
1050
1051 Aitem :=
94153a42 1052 Make_Attribute_Definition_Clause (Loc,
d74fc39a 1053 Name => Ent,
ae888dbd 1054 Chars => Chars (Id),
1055 Expression => Relocate_Node (Expr));
1056
fb7f2fc4 1057 -- A delay is required except in the common case where
1058 -- the expression is a literal, in which case it is fine
1059 -- to take care of it right away.
d74fc39a 1060
fb7f2fc4 1061 if Nkind_In (Expr, N_Integer_Literal, N_String_Literal) then
95bc75fa 1062 pragma Assert (not Delay_Required);
1063 null;
fb7f2fc4 1064 else
1065 Delay_Required := True;
1066 Set_Is_Delayed_Aspect (Aspect);
1067 end if;
d74fc39a 1068
8398ba2c 1069 -- Aspects corresponding to pragmas with two arguments, where
1070 -- the first argument is a local name referring to the entity,
1071 -- and the second argument is the aspect definition expression
1072 -- which is an expression that does not get analyzed.
ae888dbd 1073
1074 when Aspect_Suppress |
1075 Aspect_Unsuppress =>
1076
d74fc39a 1077 -- Construct the pragma
1078
1079 Aitem :=
94153a42 1080 Make_Pragma (Loc,
ae888dbd 1081 Pragma_Argument_Associations => New_List (
231eb581 1082 New_Occurrence_Of (E, Loc),
ae888dbd 1083 Relocate_Node (Expr)),
1084 Pragma_Identifier =>
e7823792 1085 Make_Identifier (Sloc (Id), Chars (Id)));
d74fc39a 1086
1087 -- We don't have to play the delay game here, since the only
1088 -- values are check names which don't get analyzed anyway.
1089
95bc75fa 1090 pragma Assert (not Delay_Required);
ae888dbd 1091
1092 -- Aspects corresponding to pragmas with two arguments, where
1093 -- the second argument is a local name referring to the entity,
1094 -- and the first argument is the aspect definition expression.
1095
1096 when Aspect_Warnings =>
1097
d74fc39a 1098 -- Construct the pragma
1099
1100 Aitem :=
94153a42 1101 Make_Pragma (Loc,
ae888dbd 1102 Pragma_Argument_Associations => New_List (
1103 Relocate_Node (Expr),
231eb581 1104 New_Occurrence_Of (E, Loc)),
ae888dbd 1105 Pragma_Identifier =>
94153a42 1106 Make_Identifier (Sloc (Id), Chars (Id)),
1107 Class_Present => Class_Present (Aspect));
ae888dbd 1108
d74fc39a 1109 -- We don't have to play the delay game here, since the only
0b424e9b 1110 -- values are ON/OFF which don't get analyzed anyway.
d74fc39a 1111
95bc75fa 1112 pragma Assert (not Delay_Required);
d74fc39a 1113
d64221a7 1114 -- Default_Value and Default_Component_Value aspects. These
1115 -- are specially handled because they have no corresponding
1116 -- pragmas or attributes.
1117
1118 when Aspect_Default_Value | Aspect_Default_Component_Value =>
1119 Error_Msg_Name_1 := Chars (Id);
1120
1121 if not Is_Type (E) then
1122 Error_Msg_N ("aspect% can only apply to a type", Id);
1123 goto Continue;
1124
1125 elsif not Is_First_Subtype (E) then
1126 Error_Msg_N ("aspect% cannot apply to subtype", Id);
1127 goto Continue;
1128
1129 elsif A_Id = Aspect_Default_Value
1130 and then not Is_Scalar_Type (E)
1131 then
1132 Error_Msg_N
1133 ("aspect% can only be applied to scalar type", Id);
1134 goto Continue;
1135
1136 elsif A_Id = Aspect_Default_Component_Value then
1137 if not Is_Array_Type (E) then
1138 Error_Msg_N
1139 ("aspect% can only be applied to array type", Id);
1140 goto Continue;
1141 elsif not Is_Scalar_Type (Component_Type (E)) then
1142 Error_Msg_N
1143 ("aspect% requires scalar components", Id);
1144 goto Continue;
1145 end if;
1146 end if;
1147
1148 Aitem := Empty;
1149 Delay_Required := True;
1150 Set_Is_Delayed_Aspect (Aspect);
1151 Set_Has_Default_Aspect (Base_Type (Entity (Ent)));
1152
7f694ca2 1153 when Aspect_Attach_Handler =>
1154 Aitem :=
1155 Make_Pragma (Loc,
1156 Pragma_Identifier =>
1157 Make_Identifier (Sloc (Id), Name_Attach_Handler),
1158 Pragma_Argument_Associations =>
1159 New_List (Ent, Relocate_Node (Expr)));
1160
1161 Set_From_Aspect_Specification (Aitem, True);
cce84b09 1162 Set_Corresponding_Aspect (Aitem, Aspect);
7f694ca2 1163
95bc75fa 1164 pragma Assert (not Delay_Required);
1165
a7a4a7c2 1166 when Aspect_Priority |
1167 Aspect_Interrupt_Priority |
cb4c311d 1168 Aspect_Dispatching_Domain |
a8e38e1d 1169 Aspect_CPU =>
a7a4a7c2 1170 declare
1171 Pname : Name_Id;
a8e38e1d 1172
a7a4a7c2 1173 begin
1174 if A_Id = Aspect_Priority then
1175 Pname := Name_Priority;
7f694ca2 1176
a7a4a7c2 1177 elsif A_Id = Aspect_Interrupt_Priority then
1178 Pname := Name_Interrupt_Priority;
7f694ca2 1179
cb4c311d 1180 elsif A_Id = Aspect_CPU then
1181 Pname := Name_CPU;
1182
a7a4a7c2 1183 else
1184 Pname := Name_Dispatching_Domain;
1185 end if;
7f694ca2 1186
a7a4a7c2 1187 Aitem :=
1188 Make_Pragma (Loc,
1189 Pragma_Identifier =>
1190 Make_Identifier (Sloc (Id), Pname),
1191 Pragma_Argument_Associations =>
1192 New_List
1193 (Make_Pragma_Argument_Association
1194 (Sloc => Sloc (Id),
1195 Expression => Relocate_Node (Expr))));
95bc75fa 1196
a7a4a7c2 1197 Set_From_Aspect_Specification (Aitem, True);
cce84b09 1198 Set_Corresponding_Aspect (Aitem, Aspect);
a7a4a7c2 1199
1200 pragma Assert (not Delay_Required);
1201 end;
7f694ca2 1202
1e3c4ae6 1203 -- Aspects Pre/Post generate Precondition/Postcondition pragmas
1204 -- with a first argument that is the expression, and a second
1205 -- argument that is an informative message if the test fails.
1206 -- This is inserted right after the declaration, to get the
5b5df4a9 1207 -- required pragma placement. The processing for the pragmas
1208 -- takes care of the required delay.
ae888dbd 1209
ddf1337b 1210 when Pre_Post_Aspects => declare
1e3c4ae6 1211 Pname : Name_Id;
ae888dbd 1212
1e3c4ae6 1213 begin
77ae6789 1214 if A_Id = Aspect_Pre or else A_Id = Aspect_Precondition then
1e3c4ae6 1215 Pname := Name_Precondition;
1216 else
1217 Pname := Name_Postcondition;
1218 end if;
d74fc39a 1219
1e3c4ae6 1220 -- If the expressions is of the form A and then B, then
1221 -- we generate separate Pre/Post aspects for the separate
1222 -- clauses. Since we allow multiple pragmas, there is no
1223 -- problem in allowing multiple Pre/Post aspects internally.
a273015d 1224 -- These should be treated in reverse order (B first and
1225 -- A second) since they are later inserted just after N in
1226 -- the order they are treated. This way, the pragma for A
1227 -- ends up preceding the pragma for B, which may have an
1228 -- importance for the error raised (either constraint error
1229 -- or precondition error).
1e3c4ae6 1230
39e1f22f 1231 -- We do not do this for Pre'Class, since we have to put
1232 -- these conditions together in a complex OR expression
ae888dbd 1233
39e1f22f 1234 if Pname = Name_Postcondition
0b424e9b 1235 or else not Class_Present (Aspect)
39e1f22f 1236 then
1237 while Nkind (Expr) = N_And_Then loop
1238 Insert_After (Aspect,
a273015d 1239 Make_Aspect_Specification (Sloc (Left_Opnd (Expr)),
39e1f22f 1240 Identifier => Identifier (Aspect),
a273015d 1241 Expression => Relocate_Node (Left_Opnd (Expr)),
39e1f22f 1242 Class_Present => Class_Present (Aspect),
1243 Split_PPC => True));
a273015d 1244 Rewrite (Expr, Relocate_Node (Right_Opnd (Expr)));
39e1f22f 1245 Eloc := Sloc (Expr);
1246 end loop;
1247 end if;
ae888dbd 1248
39e1f22f 1249 -- Build the precondition/postcondition pragma
d74fc39a 1250
1251 Aitem :=
1e3c4ae6 1252 Make_Pragma (Loc,
ae888dbd 1253 Pragma_Identifier =>
55868293 1254 Make_Identifier (Sloc (Id), Pname),
94153a42 1255 Class_Present => Class_Present (Aspect),
39e1f22f 1256 Split_PPC => Split_PPC (Aspect),
94153a42 1257 Pragma_Argument_Associations => New_List (
1e3c4ae6 1258 Make_Pragma_Argument_Association (Eloc,
94153a42 1259 Chars => Name_Check,
39e1f22f 1260 Expression => Relocate_Node (Expr))));
1261
1262 -- Add message unless exception messages are suppressed
1263
1264 if not Opt.Exception_Locations_Suppressed then
1265 Append_To (Pragma_Argument_Associations (Aitem),
1266 Make_Pragma_Argument_Association (Eloc,
1267 Chars => Name_Message,
1268 Expression =>
1269 Make_String_Literal (Eloc,
1270 Strval => "failed "
1271 & Get_Name_String (Pname)
1272 & " from "
1273 & Build_Location_String (Eloc))));
1274 end if;
d74fc39a 1275
1e3c4ae6 1276 Set_From_Aspect_Specification (Aitem, True);
cce84b09 1277 Set_Corresponding_Aspect (Aitem, Aspect);
7d20685d 1278 Set_Is_Delayed_Aspect (Aspect);
d74fc39a 1279
1e3c4ae6 1280 -- For Pre/Post cases, insert immediately after the entity
1281 -- declaration, since that is the required pragma placement.
1282 -- Note that for these aspects, we do not have to worry
1283 -- about delay issues, since the pragmas themselves deal
1284 -- with delay of visibility for the expression analysis.
1285
d2be415f 1286 -- If the entity is a library-level subprogram, the pre/
1287 -- postconditions must be treated as late pragmas.
1288
1289 if Nkind (Parent (N)) = N_Compilation_Unit then
1290 Add_Global_Declaration (Aitem);
1291 else
1292 Insert_After (N, Aitem);
1293 end if;
1294
1e3c4ae6 1295 goto Continue;
1296 end;
ae888dbd 1297
4aed5405 1298 -- Invariant aspects generate a corresponding pragma with a
6fb3c314 1299 -- first argument that is the entity, a second argument that is
1300 -- the expression and a third argument that is an appropriate
4aed5405 1301 -- message. This is inserted right after the declaration, to
1302 -- get the required pragma placement. The pragma processing
1303 -- takes care of the required delay.
ae888dbd 1304
77ae6789 1305 when Aspect_Invariant |
1306 Aspect_Type_Invariant =>
ae888dbd 1307
a3a76ccc 1308 -- Analysis of the pragma will verify placement legality:
1309 -- an invariant must apply to a private type, or appear in
1310 -- the private part of a spec and apply to a completion.
19dde43a 1311
5b5df4a9 1312 -- Construct the pragma
1313
1314 Aitem :=
1315 Make_Pragma (Loc,
1316 Pragma_Argument_Associations =>
1317 New_List (Ent, Relocate_Node (Expr)),
1318 Class_Present => Class_Present (Aspect),
1319 Pragma_Identifier =>
4aed5405 1320 Make_Identifier (Sloc (Id), Name_Invariant));
5b5df4a9 1321
1322 -- Add message unless exception messages are suppressed
1323
1324 if not Opt.Exception_Locations_Suppressed then
1325 Append_To (Pragma_Argument_Associations (Aitem),
1326 Make_Pragma_Argument_Association (Eloc,
4aed5405 1327 Chars => Name_Message,
5b5df4a9 1328 Expression =>
1329 Make_String_Literal (Eloc,
1330 Strval => "failed invariant from "
1331 & Build_Location_String (Eloc))));
1332 end if;
1333
1334 Set_From_Aspect_Specification (Aitem, True);
cce84b09 1335 Set_Corresponding_Aspect (Aitem, Aspect);
7d20685d 1336 Set_Is_Delayed_Aspect (Aspect);
5b5df4a9 1337
4aed5405 1338 -- For Invariant case, insert immediately after the entity
1339 -- declaration. We do not have to worry about delay issues
1340 -- since the pragma processing takes care of this.
1341
1342 Insert_After (N, Aitem);
1343 goto Continue;
1344
1345 -- Predicate aspects generate a corresponding pragma with a
1346 -- first argument that is the entity, and the second argument
fb7f2fc4 1347 -- is the expression.
4aed5405 1348
ebbab42d 1349 when Aspect_Dynamic_Predicate |
1350 Aspect_Predicate |
1351 Aspect_Static_Predicate =>
4aed5405 1352
ebbab42d 1353 -- Construct the pragma (always a pragma Predicate, with
6c545057 1354 -- flags recording whether it is static/dynamic).
4aed5405 1355
1356 Aitem :=
1357 Make_Pragma (Loc,
1358 Pragma_Argument_Associations =>
1359 New_List (Ent, Relocate_Node (Expr)),
1360 Class_Present => Class_Present (Aspect),
1361 Pragma_Identifier =>
1362 Make_Identifier (Sloc (Id), Name_Predicate));
1363
1364 Set_From_Aspect_Specification (Aitem, True);
cce84b09 1365 Set_Corresponding_Aspect (Aitem, Aspect);
ebbab42d 1366
f93e7257 1367 -- Make sure we have a freeze node (it might otherwise be
1368 -- missing in cases like subtype X is Y, and we would not
1369 -- have a place to build the predicate function).
1370
fb7f2fc4 1371 Set_Has_Predicates (E);
13dc58a7 1372
1373 if Is_Private_Type (E)
1374 and then Present (Full_View (E))
1375 then
1376 Set_Has_Predicates (Full_View (E));
1377 Set_Has_Delayed_Aspects (Full_View (E));
1378 end if;
1379
f93e7257 1380 Ensure_Freeze_Node (E);
7d20685d 1381 Set_Is_Delayed_Aspect (Aspect);
fb7f2fc4 1382 Delay_Required := True;
6c545057 1383
1384 when Aspect_Test_Case => declare
1385 Args : List_Id;
1386 Comp_Expr : Node_Id;
1387 Comp_Assn : Node_Id;
1388
1389 begin
1390 Args := New_List;
1391
b0bc40fd 1392 if Nkind (Parent (N)) = N_Compilation_Unit then
1393 Error_Msg_N
1394 ("incorrect placement of aspect `Test_Case`", E);
1395 goto Continue;
1396 end if;
1397
6c545057 1398 if Nkind (Expr) /= N_Aggregate then
1399 Error_Msg_NE
1400 ("wrong syntax for aspect `Test_Case` for &", Id, E);
1401 goto Continue;
1402 end if;
1403
1404 Comp_Expr := First (Expressions (Expr));
1405 while Present (Comp_Expr) loop
1406 Append (Relocate_Node (Comp_Expr), Args);
1407 Next (Comp_Expr);
1408 end loop;
1409
1410 Comp_Assn := First (Component_Associations (Expr));
1411 while Present (Comp_Assn) loop
1412 if List_Length (Choices (Comp_Assn)) /= 1
1413 or else
1414 Nkind (First (Choices (Comp_Assn))) /= N_Identifier
1415 then
1416 Error_Msg_NE
1417 ("wrong syntax for aspect `Test_Case` for &", Id, E);
1418 goto Continue;
1419 end if;
1420
1421 Append (Make_Pragma_Argument_Association (
1422 Sloc => Sloc (Comp_Assn),
1423 Chars => Chars (First (Choices (Comp_Assn))),
1424 Expression => Relocate_Node (Expression (Comp_Assn))),
1425 Args);
1426 Next (Comp_Assn);
1427 end loop;
1428
1429 -- Build the test-case pragma
1430
1431 Aitem :=
1432 Make_Pragma (Loc,
1433 Pragma_Identifier =>
1434 Make_Identifier (Sloc (Id), Name_Test_Case),
1435 Pragma_Argument_Associations =>
1436 Args);
1437
1438 Set_From_Aspect_Specification (Aitem, True);
cce84b09 1439 Set_Corresponding_Aspect (Aitem, Aspect);
6c545057 1440 Set_Is_Delayed_Aspect (Aspect);
1441
1442 -- Insert immediately after the entity declaration
1443
1444 Insert_After (N, Aitem);
1445
1446 goto Continue;
1447 end;
ae888dbd 1448 end case;
1449
d74fc39a 1450 -- If a delay is required, we delay the freeze (not much point in
1451 -- delaying the aspect if we don't delay the freeze!). The pragma
d64221a7 1452 -- or attribute clause if there is one is then attached to the
1453 -- aspect specification which is placed in the rep item list.
d74fc39a 1454
1455 if Delay_Required then
d64221a7 1456 if Present (Aitem) then
1457 Set_From_Aspect_Specification (Aitem, True);
cce84b09 1458
1459 if Nkind (Aitem) = N_Pragma then
1460 Set_Corresponding_Aspect (Aitem, Aspect);
1461 end if;
1462
d64221a7 1463 Set_Is_Delayed_Aspect (Aitem);
1464 Set_Aspect_Rep_Item (Aspect, Aitem);
1465 end if;
1466
d74fc39a 1467 Ensure_Freeze_Node (E);
d74fc39a 1468 Set_Has_Delayed_Aspects (E);
d74fc39a 1469 Record_Rep_Item (E, Aspect);
1470
1471 -- If no delay required, insert the pragma/clause in the tree
1472
1473 else
d64221a7 1474 Set_From_Aspect_Specification (Aitem, True);
1475
cce84b09 1476 if Nkind (Aitem) = N_Pragma then
1477 Set_Corresponding_Aspect (Aitem, Aspect);
1478 end if;
1479
ddf1337b 1480 -- If this is a compilation unit, we will put the pragma in
1481 -- the Pragmas_After list of the N_Compilation_Unit_Aux node.
d74fc39a 1482
ddf1337b 1483 if Nkind (Parent (Ins_Node)) = N_Compilation_Unit then
1484 declare
1485 Aux : constant Node_Id :=
1486 Aux_Decls_Node (Parent (Ins_Node));
1487
1488 begin
1489 pragma Assert (Nkind (Aux) = N_Compilation_Unit_Aux);
1490
1491 if No (Pragmas_After (Aux)) then
1492 Set_Pragmas_After (Aux, Empty_List);
1493 end if;
1494
1495 -- For Pre_Post put at start of list, otherwise at end
1496
1497 if A_Id in Pre_Post_Aspects then
1498 Prepend (Aitem, Pragmas_After (Aux));
1499 else
1500 Append (Aitem, Pragmas_After (Aux));
1501 end if;
1502 end;
d74fc39a 1503
ddf1337b 1504 -- Here if not compilation unit case
d74fc39a 1505
1506 else
7f694ca2 1507 case A_Id is
53c179ea 1508
7f694ca2 1509 -- For Pre/Post cases, insert immediately after the
1510 -- entity declaration, since that is the required pragma
1511 -- placement.
ddf1337b 1512
7f694ca2 1513 when Pre_Post_Aspects =>
1514 Insert_After (N, Aitem);
1515
1516 -- For Priority aspects, insert into the task or
1517 -- protected definition, which we need to create if it's
cb4c311d 1518 -- not there. The same applies to CPU and
1519 -- Dispatching_Domain but only to tasks.
7f694ca2 1520
a7a4a7c2 1521 when Aspect_Priority |
1522 Aspect_Interrupt_Priority |
cb4c311d 1523 Aspect_Dispatching_Domain |
a8e38e1d 1524 Aspect_CPU =>
7f694ca2 1525 declare
1526 T : Node_Id; -- the type declaration
1527 L : List_Id; -- list of decls of task/protected
1528
1529 begin
1530 if Nkind (N) = N_Object_Declaration then
1531 T := Parent (Etype (Defining_Identifier (N)));
7f694ca2 1532 else
1533 T := N;
1534 end if;
1535
a7a4a7c2 1536 if Nkind (T) = N_Protected_Type_Declaration
1537 and then A_Id /= Aspect_Dispatching_Domain
cb4c311d 1538 and then A_Id /= Aspect_CPU
a7a4a7c2 1539 then
7f694ca2 1540 pragma Assert
1541 (Present (Protected_Definition (T)));
1542
1543 L := Visible_Declarations
1544 (Protected_Definition (T));
1545
1546 elsif Nkind (T) = N_Task_Type_Declaration then
1547 if No (Task_Definition (T)) then
1548 Set_Task_Definition
1549 (T,
1550 Make_Task_Definition
1551 (Sloc (T),
1552 Visible_Declarations => New_List,
1553 End_Label => Empty));
1554 end if;
1555
a7a4a7c2 1556 L := Visible_Declarations (Task_Definition (T));
7f694ca2 1557
1558 else
1559 raise Program_Error;
1560 end if;
1561
1562 Prepend (Aitem, To => L);
1a814552 1563
1564 -- Analyze rewritten pragma. Otherwise, its
1565 -- analysis is done too late, after the task or
1566 -- protected object has been created.
1567
1568 Analyze (Aitem);
7f694ca2 1569 end;
ddf1337b 1570
95bc75fa 1571 -- For all other cases, insert in sequence
ddf1337b 1572
7f694ca2 1573 when others =>
1574 Insert_After (Ins_Node, Aitem);
1575 Ins_Node := Aitem;
1576 end case;
d74fc39a 1577 end if;
1578 end if;
ae888dbd 1579 end;
1580
d64221a7 1581 <<Continue>>
1582 Next (Aspect);
21ea3a4f 1583 end loop Aspect_Loop;
1584 end Analyze_Aspect_Specifications;
ae888dbd 1585
d6f39728 1586 -----------------------
1587 -- Analyze_At_Clause --
1588 -----------------------
1589
1590 -- An at clause is replaced by the corresponding Address attribute
1591 -- definition clause that is the preferred approach in Ada 95.
1592
1593 procedure Analyze_At_Clause (N : Node_Id) is
177675a7 1594 CS : constant Boolean := Comes_From_Source (N);
1595
d6f39728 1596 begin
177675a7 1597 -- This is an obsolescent feature
1598
e0521a36 1599 Check_Restriction (No_Obsolescent_Features, N);
1600
9dfe12ae 1601 if Warn_On_Obsolescent_Feature then
1602 Error_Msg_N
fbc67f84 1603 ("at clause is an obsolescent feature (RM J.7(2))?", N);
9dfe12ae 1604 Error_Msg_N
d53a018a 1605 ("\use address attribute definition clause instead?", N);
9dfe12ae 1606 end if;
1607
177675a7 1608 -- Rewrite as address clause
1609
d6f39728 1610 Rewrite (N,
1611 Make_Attribute_Definition_Clause (Sloc (N),
1612 Name => Identifier (N),
1613 Chars => Name_Address,
1614 Expression => Expression (N)));
177675a7 1615
1616 -- We preserve Comes_From_Source, since logically the clause still
1617 -- comes from the source program even though it is changed in form.
1618
1619 Set_Comes_From_Source (N, CS);
1620
1621 -- Analyze rewritten clause
1622
d6f39728 1623 Analyze_Attribute_Definition_Clause (N);
1624 end Analyze_At_Clause;
1625
1626 -----------------------------------------
1627 -- Analyze_Attribute_Definition_Clause --
1628 -----------------------------------------
1629
1630 procedure Analyze_Attribute_Definition_Clause (N : Node_Id) is
1631 Loc : constant Source_Ptr := Sloc (N);
1632 Nam : constant Node_Id := Name (N);
1633 Attr : constant Name_Id := Chars (N);
1634 Expr : constant Node_Id := Expression (N);
1635 Id : constant Attribute_Id := Get_Attribute_Id (Attr);
d64221a7 1636
1637 Ent : Entity_Id;
1638 -- The entity of Nam after it is analyzed. In the case of an incomplete
1639 -- type, this is the underlying type.
1640
d6f39728 1641 U_Ent : Entity_Id;
d64221a7 1642 -- The underlying entity to which the attribute applies. Generally this
1643 -- is the Underlying_Type of Ent, except in the case where the clause
1644 -- applies to full view of incomplete type or private type in which case
1645 -- U_Ent is just a copy of Ent.
d6f39728 1646
1647 FOnly : Boolean := False;
1648 -- Reset to True for subtype specific attribute (Alignment, Size)
1649 -- and for stream attributes, i.e. those cases where in the call
1650 -- to Rep_Item_Too_Late, FOnly is set True so that only the freezing
1651 -- rules are checked. Note that the case of stream attributes is not
1652 -- clear from the RM, but see AI95-00137. Also, the RM seems to
1653 -- disallow Storage_Size for derived task types, but that is also
1654 -- clearly unintentional.
1655
9f373bb8 1656 procedure Analyze_Stream_TSS_Definition (TSS_Nam : TSS_Name_Type);
1657 -- Common processing for 'Read, 'Write, 'Input and 'Output attribute
1658 -- definition clauses.
1659
ae888dbd 1660 function Duplicate_Clause return Boolean;
1661 -- This routine checks if the aspect for U_Ent being given by attribute
1662 -- definition clause N is for an aspect that has already been specified,
1663 -- and if so gives an error message. If there is a duplicate, True is
1664 -- returned, otherwise if there is no error, False is returned.
1665
81b424ac 1666 procedure Check_Indexing_Functions;
1667 -- Check that the function in Constant_Indexing or Variable_Indexing
1668 -- attribute has the proper type structure. If the name is overloaded,
1669 -- check that all interpretations are legal.
1670
89cc7147 1671 procedure Check_Iterator_Functions;
1672 -- Check that there is a single function in Default_Iterator attribute
8df4f2a5 1673 -- has the proper type structure.
89cc7147 1674
1675 function Check_Primitive_Function (Subp : Entity_Id) return Boolean;
d03bfaa1 1676 -- Common legality check for the previous two
89cc7147 1677
177675a7 1678 -----------------------------------
1679 -- Analyze_Stream_TSS_Definition --
1680 -----------------------------------
1681
9f373bb8 1682 procedure Analyze_Stream_TSS_Definition (TSS_Nam : TSS_Name_Type) is
1683 Subp : Entity_Id := Empty;
1684 I : Interp_Index;
1685 It : Interp;
1686 Pnam : Entity_Id;
1687
1688 Is_Read : constant Boolean := (TSS_Nam = TSS_Stream_Read);
d64221a7 1689 -- True for Read attribute, false for other attributes
9f373bb8 1690
1691 function Has_Good_Profile (Subp : Entity_Id) return Boolean;
1692 -- Return true if the entity is a subprogram with an appropriate
1693 -- profile for the attribute being defined.
1694
1695 ----------------------
1696 -- Has_Good_Profile --
1697 ----------------------
1698
1699 function Has_Good_Profile (Subp : Entity_Id) return Boolean is
1700 F : Entity_Id;
1701 Is_Function : constant Boolean := (TSS_Nam = TSS_Stream_Input);
1702 Expected_Ekind : constant array (Boolean) of Entity_Kind :=
1703 (False => E_Procedure, True => E_Function);
1704 Typ : Entity_Id;
1705
1706 begin
1707 if Ekind (Subp) /= Expected_Ekind (Is_Function) then
1708 return False;
1709 end if;
1710
1711 F := First_Formal (Subp);
1712
1713 if No (F)
1714 or else Ekind (Etype (F)) /= E_Anonymous_Access_Type
1715 or else Designated_Type (Etype (F)) /=
1716 Class_Wide_Type (RTE (RE_Root_Stream_Type))
1717 then
1718 return False;
1719 end if;
1720
1721 if not Is_Function then
1722 Next_Formal (F);
1723
1724 declare
1725 Expected_Mode : constant array (Boolean) of Entity_Kind :=
1726 (False => E_In_Parameter,
1727 True => E_Out_Parameter);
1728 begin
1729 if Parameter_Mode (F) /= Expected_Mode (Is_Read) then
1730 return False;
1731 end if;
1732 end;
1733
1734 Typ := Etype (F);
1735
1736 else
1737 Typ := Etype (Subp);
1738 end if;
1739
1740 return Base_Type (Typ) = Base_Type (Ent)
1741 and then No (Next_Formal (F));
9f373bb8 1742 end Has_Good_Profile;
1743
1744 -- Start of processing for Analyze_Stream_TSS_Definition
1745
1746 begin
1747 FOnly := True;
1748
1749 if not Is_Type (U_Ent) then
1750 Error_Msg_N ("local name must be a subtype", Nam);
1751 return;
1752 end if;
1753
1754 Pnam := TSS (Base_Type (U_Ent), TSS_Nam);
1755
44e4341e 1756 -- If Pnam is present, it can be either inherited from an ancestor
1757 -- type (in which case it is legal to redefine it for this type), or
1758 -- be a previous definition of the attribute for the same type (in
1759 -- which case it is illegal).
1760
1761 -- In the first case, it will have been analyzed already, and we
1762 -- can check that its profile does not match the expected profile
1763 -- for a stream attribute of U_Ent. In the second case, either Pnam
1764 -- has been analyzed (and has the expected profile), or it has not
1765 -- been analyzed yet (case of a type that has not been frozen yet
1766 -- and for which the stream attribute has been set using Set_TSS).
1767
1768 if Present (Pnam)
1769 and then (No (First_Entity (Pnam)) or else Has_Good_Profile (Pnam))
1770 then
9f373bb8 1771 Error_Msg_Sloc := Sloc (Pnam);
1772 Error_Msg_Name_1 := Attr;
1773 Error_Msg_N ("% attribute already defined #", Nam);
1774 return;
1775 end if;
1776
1777 Analyze (Expr);
1778
1779 if Is_Entity_Name (Expr) then
1780 if not Is_Overloaded (Expr) then
1781 if Has_Good_Profile (Entity (Expr)) then
1782 Subp := Entity (Expr);
1783 end if;
1784
1785 else
1786 Get_First_Interp (Expr, I, It);
9f373bb8 1787 while Present (It.Nam) loop
1788 if Has_Good_Profile (It.Nam) then
1789 Subp := It.Nam;
1790 exit;
1791 end if;
1792
1793 Get_Next_Interp (I, It);
1794 end loop;
1795 end if;
1796 end if;
1797
1798 if Present (Subp) then
59ac57b5 1799 if Is_Abstract_Subprogram (Subp) then
9f373bb8 1800 Error_Msg_N ("stream subprogram must not be abstract", Expr);
1801 return;
1802 end if;
1803
1804 Set_Entity (Expr, Subp);
1805 Set_Etype (Expr, Etype (Subp));
1806
44e4341e 1807 New_Stream_Subprogram (N, U_Ent, Subp, TSS_Nam);
9f373bb8 1808
1809 else
1810 Error_Msg_Name_1 := Attr;
1811 Error_Msg_N ("incorrect expression for% attribute", Expr);
1812 end if;
1813 end Analyze_Stream_TSS_Definition;
1814
81b424ac 1815 ------------------------------
1816 -- Check_Indexing_Functions --
1817 ------------------------------
1818
1819 procedure Check_Indexing_Functions is
8df4f2a5 1820
81b424ac 1821 procedure Check_One_Function (Subp : Entity_Id);
1822 -- Check one possible interpretation
1823
1824 ------------------------
1825 -- Check_One_Function --
1826 ------------------------
1827
1828 procedure Check_One_Function (Subp : Entity_Id) is
1829 begin
89cc7147 1830 if not Check_Primitive_Function (Subp) then
1831 Error_Msg_NE
1832 ("aspect Indexing requires a function that applies to type&",
1833 Subp, Ent);
81b424ac 1834 end if;
1835
1836 if not Has_Implicit_Dereference (Etype (Subp)) then
1837 Error_Msg_N
1838 ("function for indexing must return a reference type", Subp);
1839 end if;
1840 end Check_One_Function;
1841
1842 -- Start of processing for Check_Indexing_Functions
1843
1844 begin
89cc7147 1845 if In_Instance then
1846 return;
1847 end if;
1848
81b424ac 1849 Analyze (Expr);
1850
1851 if not Is_Overloaded (Expr) then
1852 Check_One_Function (Entity (Expr));
1853
1854 else
1855 declare
1856 I : Interp_Index;
1857 It : Interp;
1858
1859 begin
1860 Get_First_Interp (Expr, I, It);
1861 while Present (It.Nam) loop
1862
1863 -- Note that analysis will have added the interpretation
1864 -- that corresponds to the dereference. We only check the
1865 -- subprogram itself.
1866
1867 if Is_Overloadable (It.Nam) then
1868 Check_One_Function (It.Nam);
1869 end if;
1870
1871 Get_Next_Interp (I, It);
1872 end loop;
1873 end;
1874 end if;
1875 end Check_Indexing_Functions;
1876
89cc7147 1877 ------------------------------
1878 -- Check_Iterator_Functions --
1879 ------------------------------
1880
1881 procedure Check_Iterator_Functions is
1882 Default : Entity_Id;
1883
1884 function Valid_Default_Iterator (Subp : Entity_Id) return Boolean;
8df4f2a5 1885 -- Check one possible interpretation for validity
89cc7147 1886
1887 ----------------------------
1888 -- Valid_Default_Iterator --
1889 ----------------------------
1890
1891 function Valid_Default_Iterator (Subp : Entity_Id) return Boolean is
1892 Formal : Entity_Id;
1893
1894 begin
1895 if not Check_Primitive_Function (Subp) then
1896 return False;
1897 else
1898 Formal := First_Formal (Subp);
1899 end if;
1900
8df4f2a5 1901 -- False if any subsequent formal has no default expression
89cc7147 1902
8df4f2a5 1903 Formal := Next_Formal (Formal);
1904 while Present (Formal) loop
1905 if No (Expression (Parent (Formal))) then
1906 return False;
1907 end if;
89cc7147 1908
8df4f2a5 1909 Next_Formal (Formal);
1910 end loop;
89cc7147 1911
8df4f2a5 1912 -- True if all subsequent formals have default expressions
89cc7147 1913
1914 return True;
1915 end Valid_Default_Iterator;
1916
1917 -- Start of processing for Check_Iterator_Functions
1918
1919 begin
1920 Analyze (Expr);
1921
1922 if not Is_Entity_Name (Expr) then
1923 Error_Msg_N ("aspect Iterator must be a function name", Expr);
1924 end if;
1925
1926 if not Is_Overloaded (Expr) then
1927 if not Check_Primitive_Function (Entity (Expr)) then
1928 Error_Msg_NE
1929 ("aspect Indexing requires a function that applies to type&",
1930 Entity (Expr), Ent);
1931 end if;
1932
1933 if not Valid_Default_Iterator (Entity (Expr)) then
1934 Error_Msg_N ("improper function for default iterator", Expr);
1935 end if;
1936
1937 else
1938 Default := Empty;
1939 declare
1940 I : Interp_Index;
1941 It : Interp;
1942
1943 begin
1944 Get_First_Interp (Expr, I, It);
1945 while Present (It.Nam) loop
1946 if not Check_Primitive_Function (It.Nam)
59f3e675 1947 or else not Valid_Default_Iterator (It.Nam)
89cc7147 1948 then
1949 Remove_Interp (I);
1950
1951 elsif Present (Default) then
1952 Error_Msg_N ("default iterator must be unique", Expr);
1953
1954 else
1955 Default := It.Nam;
1956 end if;
1957
1958 Get_Next_Interp (I, It);
1959 end loop;
1960 end;
1961
1962 if Present (Default) then
1963 Set_Entity (Expr, Default);
1964 Set_Is_Overloaded (Expr, False);
1965 end if;
1966 end if;
1967 end Check_Iterator_Functions;
1968
1969 -------------------------------
1970 -- Check_Primitive_Function --
1971 -------------------------------
1972
1973 function Check_Primitive_Function (Subp : Entity_Id) return Boolean is
1974 Ctrl : Entity_Id;
1975
1976 begin
1977 if Ekind (Subp) /= E_Function then
1978 return False;
1979 end if;
1980
1981 if No (First_Formal (Subp)) then
1982 return False;
1983 else
1984 Ctrl := Etype (First_Formal (Subp));
1985 end if;
1986
1987 if Ctrl = Ent
1988 or else Ctrl = Class_Wide_Type (Ent)
1989 or else
1990 (Ekind (Ctrl) = E_Anonymous_Access_Type
1991 and then
1992 (Designated_Type (Ctrl) = Ent
1993 or else Designated_Type (Ctrl) = Class_Wide_Type (Ent)))
1994 then
1995 null;
1996
1997 else
1998 return False;
1999 end if;
2000
2001 return True;
2002 end Check_Primitive_Function;
2003
ae888dbd 2004 ----------------------
2005 -- Duplicate_Clause --
2006 ----------------------
2007
2008 function Duplicate_Clause return Boolean is
d74fc39a 2009 A : Node_Id;
ae888dbd 2010
2011 begin
c8969ba6 2012 -- Nothing to do if this attribute definition clause comes from
2013 -- an aspect specification, since we could not be duplicating an
ae888dbd 2014 -- explicit clause, and we dealt with the case of duplicated aspects
2015 -- in Analyze_Aspect_Specifications.
2016
2017 if From_Aspect_Specification (N) then
2018 return False;
2019 end if;
2020
d74fc39a 2021 -- Otherwise current clause may duplicate previous clause or a
2022 -- previously given aspect specification for the same aspect.
2023
2024 A := Get_Rep_Item_For_Entity (U_Ent, Chars (N));
ae888dbd 2025
2026 if Present (A) then
2027 if Entity (A) = U_Ent then
2028 Error_Msg_Name_1 := Chars (N);
2029 Error_Msg_Sloc := Sloc (A);
39e1f22f 2030 Error_Msg_NE ("aspect% for & previously given#", N, U_Ent);
ae888dbd 2031 return True;
2032 end if;
2033 end if;
2034
2035 return False;
2036 end Duplicate_Clause;
2037
9f373bb8 2038 -- Start of processing for Analyze_Attribute_Definition_Clause
2039
d6f39728 2040 begin
d64221a7 2041 -- The following code is a defense against recursion. Not clear that
2042 -- this can happen legitimately, but perhaps some error situations
2043 -- can cause it, and we did see this recursion during testing.
2044
2045 if Analyzed (N) then
2046 return;
2047 else
2048 Set_Analyzed (N, True);
2049 end if;
2050
fe639c68 2051 -- Process Ignore_Rep_Clauses option (we also ignore rep clauses in
f84c0da6 2052 -- CodePeer mode or Alfa mode, since they are not relevant in these
8ef30a23 2053 -- contexts).
eef1ca1e 2054
f84c0da6 2055 if Ignore_Rep_Clauses or CodePeer_Mode or Alfa_Mode then
9d627c41 2056 case Id is
2057
eef1ca1e 2058 -- The following should be ignored. They do not affect legality
2059 -- and may be target dependent. The basic idea of -gnatI is to
2060 -- ignore any rep clauses that may be target dependent but do not
2061 -- affect legality (except possibly to be rejected because they
2062 -- are incompatible with the compilation target).
9d627c41 2063
2f1aac99 2064 when Attribute_Alignment |
9d627c41 2065 Attribute_Bit_Order |
2066 Attribute_Component_Size |
2067 Attribute_Machine_Radix |
2068 Attribute_Object_Size |
2069 Attribute_Size |
9d627c41 2070 Attribute_Stream_Size |
2071 Attribute_Value_Size =>
9d627c41 2072 Rewrite (N, Make_Null_Statement (Sloc (N)));
2073 return;
2074
f84c0da6 2075 -- We do not want too ignore 'Small in CodePeer_Mode or Alfa_Mode,
8ef30a23 2076 -- since it has an impact on the exact computations performed.
fe639c68 2077
2078 -- Perhaps 'Small should also not be ignored by
2079 -- Ignore_Rep_Clauses ???
2080
2081 when Attribute_Small =>
2082 if Ignore_Rep_Clauses then
2083 Rewrite (N, Make_Null_Statement (Sloc (N)));
2084 return;
2085 end if;
2086
eef1ca1e 2087 -- The following should not be ignored, because in the first place
2088 -- they are reasonably portable, and should not cause problems in
2089 -- compiling code from another target, and also they do affect
2090 -- legality, e.g. failing to provide a stream attribute for a
2091 -- type may make a program illegal.
9d627c41 2092
fe639c68 2093 when Attribute_External_Tag |
2094 Attribute_Input |
2095 Attribute_Output |
2096 Attribute_Read |
2097 Attribute_Storage_Pool |
2098 Attribute_Storage_Size |
2099 Attribute_Write =>
9d627c41 2100 null;
2101
b593a52c 2102 -- Other cases are errors ("attribute& cannot be set with
2103 -- definition clause"), which will be caught below.
9d627c41 2104
2105 when others =>
2106 null;
2107 end case;
fbc67f84 2108 end if;
2109
d6f39728 2110 Analyze (Nam);
2111 Ent := Entity (Nam);
2112
2113 if Rep_Item_Too_Early (Ent, N) then
2114 return;
2115 end if;
2116
9f373bb8 2117 -- Rep clause applies to full view of incomplete type or private type if
2118 -- we have one (if not, this is a premature use of the type). However,
2119 -- certain semantic checks need to be done on the specified entity (i.e.
2120 -- the private view), so we save it in Ent.
d6f39728 2121
2122 if Is_Private_Type (Ent)
2123 and then Is_Derived_Type (Ent)
2124 and then not Is_Tagged_Type (Ent)
2125 and then No (Full_View (Ent))
2126 then
9f373bb8 2127 -- If this is a private type whose completion is a derivation from
2128 -- another private type, there is no full view, and the attribute
2129 -- belongs to the type itself, not its underlying parent.
d6f39728 2130
2131 U_Ent := Ent;
2132
2133 elsif Ekind (Ent) = E_Incomplete_Type then
d5b349fa 2134
9f373bb8 2135 -- The attribute applies to the full view, set the entity of the
2136 -- attribute definition accordingly.
d5b349fa 2137
d6f39728 2138 Ent := Underlying_Type (Ent);
2139 U_Ent := Ent;
d5b349fa 2140 Set_Entity (Nam, Ent);
2141
d6f39728 2142 else
2143 U_Ent := Underlying_Type (Ent);
2144 end if;
2145
2146 -- Complete other routine error checks
2147
2148 if Etype (Nam) = Any_Type then
2149 return;
2150
2151 elsif Scope (Ent) /= Current_Scope then
2152 Error_Msg_N ("entity must be declared in this scope", Nam);
2153 return;
2154
f15731c4 2155 elsif No (U_Ent) then
2156 U_Ent := Ent;
2157
d6f39728 2158 elsif Is_Type (U_Ent)
2159 and then not Is_First_Subtype (U_Ent)
2160 and then Id /= Attribute_Object_Size
2161 and then Id /= Attribute_Value_Size
2162 and then not From_At_Mod (N)
2163 then
2164 Error_Msg_N ("cannot specify attribute for subtype", Nam);
2165 return;
d6f39728 2166 end if;
2167
ae888dbd 2168 Set_Entity (N, U_Ent);
2169
d6f39728 2170 -- Switch on particular attribute
2171
2172 case Id is
2173
2174 -------------
2175 -- Address --
2176 -------------
2177
2178 -- Address attribute definition clause
2179
2180 when Attribute_Address => Address : begin
177675a7 2181
2182 -- A little error check, catch for X'Address use X'Address;
2183
2184 if Nkind (Nam) = N_Identifier
2185 and then Nkind (Expr) = N_Attribute_Reference
2186 and then Attribute_Name (Expr) = Name_Address
2187 and then Nkind (Prefix (Expr)) = N_Identifier
2188 and then Chars (Nam) = Chars (Prefix (Expr))
2189 then
2190 Error_Msg_NE
2191 ("address for & is self-referencing", Prefix (Expr), Ent);
2192 return;
2193 end if;
2194
2195 -- Not that special case, carry on with analysis of expression
2196
d6f39728 2197 Analyze_And_Resolve (Expr, RTE (RE_Address));
2198
2f1aac99 2199 -- Even when ignoring rep clauses we need to indicate that the
2200 -- entity has an address clause and thus it is legal to declare
2201 -- it imported.
2202
2203 if Ignore_Rep_Clauses then
d3ef794c 2204 if Ekind_In (U_Ent, E_Variable, E_Constant) then
2f1aac99 2205 Record_Rep_Item (U_Ent, N);
2206 end if;
2207
2208 return;
2209 end if;
2210
ae888dbd 2211 if Duplicate_Clause then
2212 null;
d6f39728 2213
2214 -- Case of address clause for subprogram
2215
2216 elsif Is_Subprogram (U_Ent) then
d6f39728 2217 if Has_Homonym (U_Ent) then
2218 Error_Msg_N
2219 ("address clause cannot be given " &
2220 "for overloaded subprogram",
2221 Nam);
83f8f0a6 2222 return;
d6f39728 2223 end if;
2224
83f8f0a6 2225 -- For subprograms, all address clauses are permitted, and we
2226 -- mark the subprogram as having a deferred freeze so that Gigi
2227 -- will not elaborate it too soon.
d6f39728 2228
2229 -- Above needs more comments, what is too soon about???
2230
2231 Set_Has_Delayed_Freeze (U_Ent);
2232
2233 -- Case of address clause for entry
2234
2235 elsif Ekind (U_Ent) = E_Entry then
d6f39728 2236 if Nkind (Parent (N)) = N_Task_Body then
2237 Error_Msg_N
2238 ("entry address must be specified in task spec", Nam);
83f8f0a6 2239 return;
d6f39728 2240 end if;
2241
2242 -- For entries, we require a constant address
2243
2244 Check_Constant_Address_Clause (Expr, U_Ent);
2245
83f8f0a6 2246 -- Special checks for task types
2247
f15731c4 2248 if Is_Task_Type (Scope (U_Ent))
2249 and then Comes_From_Source (Scope (U_Ent))
2250 then
2251 Error_Msg_N
2252 ("?entry address declared for entry in task type", N);
2253 Error_Msg_N
2254 ("\?only one task can be declared of this type", N);
2255 end if;
2256
83f8f0a6 2257 -- Entry address clauses are obsolescent
2258
e0521a36 2259 Check_Restriction (No_Obsolescent_Features, N);
2260
9dfe12ae 2261 if Warn_On_Obsolescent_Feature then
2262 Error_Msg_N
2263 ("attaching interrupt to task entry is an " &
fbc67f84 2264 "obsolescent feature (RM J.7.1)?", N);
9dfe12ae 2265 Error_Msg_N
d53a018a 2266 ("\use interrupt procedure instead?", N);
9dfe12ae 2267 end if;
2268
83f8f0a6 2269 -- Case of an address clause for a controlled object which we
2270 -- consider to be erroneous.
9dfe12ae 2271
83f8f0a6 2272 elsif Is_Controlled (Etype (U_Ent))
2273 or else Has_Controlled_Component (Etype (U_Ent))
2274 then
9dfe12ae 2275 Error_Msg_NE
2276 ("?controlled object& must not be overlaid", Nam, U_Ent);
2277 Error_Msg_N
2278 ("\?Program_Error will be raised at run time", Nam);
2279 Insert_Action (Declaration_Node (U_Ent),
2280 Make_Raise_Program_Error (Loc,
2281 Reason => PE_Overlaid_Controlled_Object));
83f8f0a6 2282 return;
9dfe12ae 2283
2284 -- Case of address clause for a (non-controlled) object
d6f39728 2285
2286 elsif
2287 Ekind (U_Ent) = E_Variable
2288 or else
2289 Ekind (U_Ent) = E_Constant
2290 then
2291 declare
d6da7448 2292 Expr : constant Node_Id := Expression (N);
2293 O_Ent : Entity_Id;
2294 Off : Boolean;
d6f39728 2295
2296 begin
7ee315cc 2297 -- Exported variables cannot have an address clause, because
2298 -- this cancels the effect of the pragma Export.
d6f39728 2299
2300 if Is_Exported (U_Ent) then
2301 Error_Msg_N
2302 ("cannot export object with address clause", Nam);
83f8f0a6 2303 return;
d6da7448 2304 end if;
2305
2306 Find_Overlaid_Entity (N, O_Ent, Off);
d6f39728 2307
9dfe12ae 2308 -- Overlaying controlled objects is erroneous
2309
d6da7448 2310 if Present (O_Ent)
2311 and then (Has_Controlled_Component (Etype (O_Ent))
2312 or else Is_Controlled (Etype (O_Ent)))
9dfe12ae 2313 then
2314 Error_Msg_N
83f8f0a6 2315 ("?cannot overlay with controlled object", Expr);
9dfe12ae 2316 Error_Msg_N
2317 ("\?Program_Error will be raised at run time", Expr);
2318 Insert_Action (Declaration_Node (U_Ent),
2319 Make_Raise_Program_Error (Loc,
2320 Reason => PE_Overlaid_Controlled_Object));
83f8f0a6 2321 return;
9dfe12ae 2322
d6da7448 2323 elsif Present (O_Ent)
9dfe12ae 2324 and then Ekind (U_Ent) = E_Constant
d6da7448 2325 and then not Is_Constant_Object (O_Ent)
9dfe12ae 2326 then
2327 Error_Msg_N ("constant overlays a variable?", Expr);
2328
2329 elsif Present (Renamed_Object (U_Ent)) then
2330 Error_Msg_N
2331 ("address clause not allowed"
fbc67f84 2332 & " for a renaming declaration (RM 13.1(6))", Nam);
83f8f0a6 2333 return;
9dfe12ae 2334
d6f39728 2335 -- Imported variables can have an address clause, but then
2336 -- the import is pretty meaningless except to suppress
2337 -- initializations, so we do not need such variables to
2338 -- be statically allocated (and in fact it causes trouble
2339 -- if the address clause is a local value).
2340
2341 elsif Is_Imported (U_Ent) then
2342 Set_Is_Statically_Allocated (U_Ent, False);
2343 end if;
2344
2345 -- We mark a possible modification of a variable with an
2346 -- address clause, since it is likely aliasing is occurring.
2347
177675a7 2348 Note_Possible_Modification (Nam, Sure => False);
d6f39728 2349
83f8f0a6 2350 -- Here we are checking for explicit overlap of one variable
2351 -- by another, and if we find this then mark the overlapped
2352 -- variable as also being volatile to prevent unwanted
d6da7448 2353 -- optimizations. This is a significant pessimization so
2354 -- avoid it when there is an offset, i.e. when the object
2355 -- is composite; they cannot be optimized easily anyway.
d6f39728 2356
d6da7448 2357 if Present (O_Ent)
2358 and then Is_Object (O_Ent)
2359 and then not Off
2360 then
2361 Set_Treat_As_Volatile (O_Ent);
d6f39728 2362 end if;
2363
9dfe12ae 2364 -- Legality checks on the address clause for initialized
2365 -- objects is deferred until the freeze point, because
2366 -- a subsequent pragma might indicate that the object is
2367 -- imported and thus not initialized.
2368
2369 Set_Has_Delayed_Freeze (U_Ent);
2370
51ad5ad2 2371 -- If an initialization call has been generated for this
2372 -- object, it needs to be deferred to after the freeze node
2373 -- we have just now added, otherwise GIGI will see a
2374 -- reference to the variable (as actual to the IP call)
2375 -- before its definition.
2376
2377 declare
2378 Init_Call : constant Node_Id := Find_Init_Call (U_Ent, N);
2379 begin
2380 if Present (Init_Call) then
2381 Remove (Init_Call);
2382 Append_Freeze_Action (U_Ent, Init_Call);
2383 end if;
2384 end;
2385
d6f39728 2386 if Is_Exported (U_Ent) then
2387 Error_Msg_N
2388 ("& cannot be exported if an address clause is given",
2389 Nam);
2390 Error_Msg_N
2391 ("\define and export a variable " &
2392 "that holds its address instead",
2393 Nam);
2394 end if;
2395
44e4341e 2396 -- Entity has delayed freeze, so we will generate an
2397 -- alignment check at the freeze point unless suppressed.
d6f39728 2398
44e4341e 2399 if not Range_Checks_Suppressed (U_Ent)
2400 and then not Alignment_Checks_Suppressed (U_Ent)
2401 then
2402 Set_Check_Address_Alignment (N);
2403 end if;
d6f39728 2404
2405 -- Kill the size check code, since we are not allocating
2406 -- the variable, it is somewhere else.
2407
2408 Kill_Size_Check_Code (U_Ent);
83f8f0a6 2409
d6da7448 2410 -- If the address clause is of the form:
83f8f0a6 2411
d6da7448 2412 -- for Y'Address use X'Address
83f8f0a6 2413
d6da7448 2414 -- or
83f8f0a6 2415
d6da7448 2416 -- Const : constant Address := X'Address;
2417 -- ...
2418 -- for Y'Address use Const;
83f8f0a6 2419
d6da7448 2420 -- then we make an entry in the table for checking the size
2421 -- and alignment of the overlaying variable. We defer this
2422 -- check till after code generation to take full advantage
2423 -- of the annotation done by the back end. This entry is
2424 -- only made if the address clause comes from source.
d64221a7 2425
9474aa9c 2426 -- If the entity has a generic type, the check will be
43dd6937 2427 -- performed in the instance if the actual type justifies
2428 -- it, and we do not insert the clause in the table to
2429 -- prevent spurious warnings.
83f8f0a6 2430
d6da7448 2431 if Address_Clause_Overlay_Warnings
2432 and then Comes_From_Source (N)
2433 and then Present (O_Ent)
2434 and then Is_Object (O_Ent)
2435 then
9474aa9c 2436 if not Is_Generic_Type (Etype (U_Ent)) then
2437 Address_Clause_Checks.Append ((N, U_Ent, O_Ent, Off));
2438 end if;
177675a7 2439
d6da7448 2440 -- If variable overlays a constant view, and we are
2441 -- warning on overlays, then mark the variable as
2442 -- overlaying a constant (we will give warnings later
2443 -- if this variable is assigned).
177675a7 2444
d6da7448 2445 if Is_Constant_Object (O_Ent)
2446 and then Ekind (U_Ent) = E_Variable
2447 then
2448 Set_Overlays_Constant (U_Ent);
83f8f0a6 2449 end if;
d6da7448 2450 end if;
2451 end;
83f8f0a6 2452
d6f39728 2453 -- Not a valid entity for an address clause
2454
2455 else
2456 Error_Msg_N ("address cannot be given for &", Nam);
2457 end if;
2458 end Address;
2459
2460 ---------------
2461 -- Alignment --
2462 ---------------
2463
2464 -- Alignment attribute definition clause
2465
b47769f0 2466 when Attribute_Alignment => Alignment : declare
9dfe12ae 2467 Align : constant Uint := Get_Alignment_Value (Expr);
d6f39728 2468
2469 begin
2470 FOnly := True;
2471
2472 if not Is_Type (U_Ent)
2473 and then Ekind (U_Ent) /= E_Variable
2474 and then Ekind (U_Ent) /= E_Constant
2475 then
2476 Error_Msg_N ("alignment cannot be given for &", Nam);
2477
ae888dbd 2478 elsif Duplicate_Clause then
2479 null;
d6f39728 2480
2481 elsif Align /= No_Uint then
2482 Set_Has_Alignment_Clause (U_Ent);
2483 Set_Alignment (U_Ent, Align);
b47769f0 2484
2485 -- For an array type, U_Ent is the first subtype. In that case,
2486 -- also set the alignment of the anonymous base type so that
2487 -- other subtypes (such as the itypes for aggregates of the
2488 -- type) also receive the expected alignment.
2489
2490 if Is_Array_Type (U_Ent) then
2491 Set_Alignment (Base_Type (U_Ent), Align);
2492 end if;
d6f39728 2493 end if;
b47769f0 2494 end Alignment;
d6f39728 2495
2496 ---------------
2497 -- Bit_Order --
2498 ---------------
2499
2500 -- Bit_Order attribute definition clause
2501
2502 when Attribute_Bit_Order => Bit_Order : declare
2503 begin
2504 if not Is_Record_Type (U_Ent) then
2505 Error_Msg_N
2506 ("Bit_Order can only be defined for record type", Nam);
2507
ae888dbd 2508 elsif Duplicate_Clause then
2509 null;
2510
d6f39728 2511 else
2512 Analyze_And_Resolve (Expr, RTE (RE_Bit_Order));
2513
2514 if Etype (Expr) = Any_Type then
2515 return;
2516
2517 elsif not Is_Static_Expression (Expr) then
9dfe12ae 2518 Flag_Non_Static_Expr
2519 ("Bit_Order requires static expression!", Expr);
d6f39728 2520
2521 else
2522 if (Expr_Value (Expr) = 0) /= Bytes_Big_Endian then
2523 Set_Reverse_Bit_Order (U_Ent, True);
2524 end if;
2525 end if;
2526 end if;
2527 end Bit_Order;
2528
2529 --------------------
2530 -- Component_Size --
2531 --------------------
2532
2533 -- Component_Size attribute definition clause
2534
2535 when Attribute_Component_Size => Component_Size_Case : declare
2536 Csize : constant Uint := Static_Integer (Expr);
a0fc8c5b 2537 Ctyp : Entity_Id;
d6f39728 2538 Btype : Entity_Id;
2539 Biased : Boolean;
2540 New_Ctyp : Entity_Id;
2541 Decl : Node_Id;
2542
2543 begin
2544 if not Is_Array_Type (U_Ent) then
2545 Error_Msg_N ("component size requires array type", Nam);
2546 return;
2547 end if;
2548
2549 Btype := Base_Type (U_Ent);
a0fc8c5b 2550 Ctyp := Component_Type (Btype);
d6f39728 2551
ae888dbd 2552 if Duplicate_Clause then
2553 null;
d6f39728 2554
f3e4db96 2555 elsif Rep_Item_Too_Early (Btype, N) then
2556 null;
2557
d6f39728 2558 elsif Csize /= No_Uint then
a0fc8c5b 2559 Check_Size (Expr, Ctyp, Csize, Biased);
d6f39728 2560
d74fc39a 2561 -- For the biased case, build a declaration for a subtype that
2562 -- will be used to represent the biased subtype that reflects
2563 -- the biased representation of components. We need the subtype
2564 -- to get proper conversions on referencing elements of the
2565 -- array. Note: component size clauses are ignored in VM mode.
3062c401 2566
2567 if VM_Target = No_VM then
2568 if Biased then
2569 New_Ctyp :=
2570 Make_Defining_Identifier (Loc,
2571 Chars =>
2572 New_External_Name (Chars (U_Ent), 'C', 0, 'T'));
2573
2574 Decl :=
2575 Make_Subtype_Declaration (Loc,
2576 Defining_Identifier => New_Ctyp,
2577 Subtype_Indication =>
2578 New_Occurrence_Of (Component_Type (Btype), Loc));
2579
2580 Set_Parent (Decl, N);
2581 Analyze (Decl, Suppress => All_Checks);
2582
2583 Set_Has_Delayed_Freeze (New_Ctyp, False);
2584 Set_Esize (New_Ctyp, Csize);
2585 Set_RM_Size (New_Ctyp, Csize);
2586 Init_Alignment (New_Ctyp);
3062c401 2587 Set_Is_Itype (New_Ctyp, True);
2588 Set_Associated_Node_For_Itype (New_Ctyp, U_Ent);
2589
2590 Set_Component_Type (Btype, New_Ctyp);
b77e4501 2591 Set_Biased (New_Ctyp, N, "component size clause");
3062c401 2592 end if;
2593
2594 Set_Component_Size (Btype, Csize);
2595
2596 -- For VM case, we ignore component size clauses
2597
2598 else
2599 -- Give a warning unless we are in GNAT mode, in which case
2600 -- the warning is suppressed since it is not useful.
2601
2602 if not GNAT_Mode then
2603 Error_Msg_N
2604 ("?component size ignored in this configuration", N);
2605 end if;
d6f39728 2606 end if;
2607
a0fc8c5b 2608 -- Deal with warning on overridden size
2609
2610 if Warn_On_Overridden_Size
2611 and then Has_Size_Clause (Ctyp)
2612 and then RM_Size (Ctyp) /= Csize
2613 then
2614 Error_Msg_NE
2615 ("?component size overrides size clause for&",
2616 N, Ctyp);
2617 end if;
2618
d6f39728 2619 Set_Has_Component_Size_Clause (Btype, True);
f3e4db96 2620 Set_Has_Non_Standard_Rep (Btype, True);
d6f39728 2621 end if;
2622 end Component_Size_Case;
2623
81b424ac 2624 -----------------------
2625 -- Constant_Indexing --
2626 -----------------------
2627
2628 when Attribute_Constant_Indexing =>
2629 Check_Indexing_Functions;
2630
89cc7147 2631 ----------------------
2632 -- Default_Iterator --
2633 ----------------------
2634
2635 when Attribute_Default_Iterator => Default_Iterator : declare
2636 Func : Entity_Id;
2637
2638 begin
2639 if not Is_Tagged_Type (U_Ent) then
2640 Error_Msg_N
2641 ("aspect Default_Iterator applies to tagged type", Nam);
2642 end if;
2643
2644 Check_Iterator_Functions;
2645
2646 Analyze (Expr);
2647
2648 if not Is_Entity_Name (Expr)
2649 or else Ekind (Entity (Expr)) /= E_Function
2650 then
2651 Error_Msg_N ("aspect Iterator must be a function", Expr);
2652 else
2653 Func := Entity (Expr);
2654 end if;
2655
2656 if No (First_Formal (Func))
2657 or else Etype (First_Formal (Func)) /= U_Ent
2658 then
2659 Error_Msg_NE
2660 ("Default Iterator must be a primitive of&", Func, U_Ent);
2661 end if;
2662 end Default_Iterator;
2663
d6f39728 2664 ------------------
2665 -- External_Tag --
2666 ------------------
2667
2668 when Attribute_External_Tag => External_Tag :
2669 begin
2670 if not Is_Tagged_Type (U_Ent) then
2671 Error_Msg_N ("should be a tagged type", Nam);
2672 end if;
2673
ae888dbd 2674 if Duplicate_Clause then
2675 null;
d6f39728 2676
9af0ddc7 2677 else
ae888dbd 2678 Analyze_And_Resolve (Expr, Standard_String);
fbc67f84 2679
ae888dbd 2680 if not Is_Static_Expression (Expr) then
2681 Flag_Non_Static_Expr
2682 ("static string required for tag name!", Nam);
2683 end if;
2684
2685 if VM_Target = No_VM then
2686 Set_Has_External_Tag_Rep_Clause (U_Ent);
2687 else
2688 Error_Msg_Name_1 := Attr;
2689 Error_Msg_N
2690 ("% attribute unsupported in this configuration", Nam);
2691 end if;
2692
2693 if not Is_Library_Level_Entity (U_Ent) then
2694 Error_Msg_NE
2695 ("?non-unique external tag supplied for &", N, U_Ent);
2696 Error_Msg_N
2697 ("?\same external tag applies to all subprogram calls", N);
2698 Error_Msg_N
2699 ("?\corresponding internal tag cannot be obtained", N);
2700 end if;
fbc67f84 2701 end if;
d6f39728 2702 end External_Tag;
2703
b57530b8 2704 --------------------------
2705 -- Implicit_Dereference --
2706 --------------------------
7947a439 2707
b57530b8 2708 when Attribute_Implicit_Dereference =>
7947a439 2709
89cc7147 2710 -- Legality checks already performed at the point of
2711 -- the type declaration, aspect is not delayed.
7947a439 2712
89cc7147 2713 null;
b57530b8 2714
d6f39728 2715 -----------
2716 -- Input --
2717 -----------
2718
9f373bb8 2719 when Attribute_Input =>
2720 Analyze_Stream_TSS_Definition (TSS_Stream_Input);
2721 Set_Has_Specified_Stream_Input (Ent);
d6f39728 2722
89cc7147 2723 ----------------------
2724 -- Iterator_Element --
2725 ----------------------
2726
2727 when Attribute_Iterator_Element =>
2728 Analyze (Expr);
2729
2730 if not Is_Entity_Name (Expr)
2731 or else not Is_Type (Entity (Expr))
2732 then
2733 Error_Msg_N ("aspect Iterator_Element must be a type", Expr);
2734 end if;
2735
d6f39728 2736 -------------------
2737 -- Machine_Radix --
2738 -------------------
2739
2740 -- Machine radix attribute definition clause
2741
2742 when Attribute_Machine_Radix => Machine_Radix : declare
2743 Radix : constant Uint := Static_Integer (Expr);
2744
2745 begin
2746 if not Is_Decimal_Fixed_Point_Type (U_Ent) then
2747 Error_Msg_N ("decimal fixed-point type expected for &", Nam);
2748
ae888dbd 2749 elsif Duplicate_Clause then
2750 null;
d6f39728 2751
2752 elsif Radix /= No_Uint then
2753 Set_Has_Machine_Radix_Clause (U_Ent);
2754 Set_Has_Non_Standard_Rep (Base_Type (U_Ent));
2755
2756 if Radix = 2 then
2757 null;
2758 elsif Radix = 10 then
2759 Set_Machine_Radix_10 (U_Ent);
2760 else
2761 Error_Msg_N ("machine radix value must be 2 or 10", Expr);
2762 end if;
2763 end if;
2764 end Machine_Radix;
2765
2766 -----------------
2767 -- Object_Size --
2768 -----------------
2769
2770 -- Object_Size attribute definition clause
2771
2772 when Attribute_Object_Size => Object_Size : declare
bfa5a9d9 2773 Size : constant Uint := Static_Integer (Expr);
2774
d6f39728 2775 Biased : Boolean;
bfa5a9d9 2776 pragma Warnings (Off, Biased);
d6f39728 2777
2778 begin
2779 if not Is_Type (U_Ent) then
2780 Error_Msg_N ("Object_Size cannot be given for &", Nam);
2781
ae888dbd 2782 elsif Duplicate_Clause then
2783 null;
d6f39728 2784
2785 else
2786 Check_Size (Expr, U_Ent, Size, Biased);
2787
2788 if Size /= 8
2789 and then
2790 Size /= 16
2791 and then
2792 Size /= 32
2793 and then
2794 UI_Mod (Size, 64) /= 0
2795 then
2796 Error_Msg_N
2797 ("Object_Size must be 8, 16, 32, or multiple of 64",
2798 Expr);
2799 end if;
2800
2801 Set_Esize (U_Ent, Size);
2802 Set_Has_Object_Size_Clause (U_Ent);
1d366b32 2803 Alignment_Check_For_Size_Change (U_Ent, Size);
d6f39728 2804 end if;
2805 end Object_Size;
2806
2807 ------------
2808 -- Output --
2809 ------------
2810
9f373bb8 2811 when Attribute_Output =>
2812 Analyze_Stream_TSS_Definition (TSS_Stream_Output);
2813 Set_Has_Specified_Stream_Output (Ent);
d6f39728 2814
2815 ----------
2816 -- Read --
2817 ----------
2818
9f373bb8 2819 when Attribute_Read =>
2820 Analyze_Stream_TSS_Definition (TSS_Stream_Read);
2821 Set_Has_Specified_Stream_Read (Ent);
d6f39728 2822
2823 ----------
2824 -- Size --
2825 ----------
2826
2827 -- Size attribute definition clause
2828
2829 when Attribute_Size => Size : declare
2830 Size : constant Uint := Static_Integer (Expr);
2831 Etyp : Entity_Id;
2832 Biased : Boolean;
2833
2834 begin
2835 FOnly := True;
2836
ae888dbd 2837 if Duplicate_Clause then
2838 null;
d6f39728 2839
2840 elsif not Is_Type (U_Ent)
2841 and then Ekind (U_Ent) /= E_Variable
2842 and then Ekind (U_Ent) /= E_Constant
2843 then
2844 Error_Msg_N ("size cannot be given for &", Nam);
2845
2846 elsif Is_Array_Type (U_Ent)
2847 and then not Is_Constrained (U_Ent)
2848 then
2849 Error_Msg_N
2850 ("size cannot be given for unconstrained array", Nam);
2851
c2b89d6e 2852 elsif Size /= No_Uint then
c2b89d6e 2853 if VM_Target /= No_VM and then not GNAT_Mode then
47495553 2854
c2b89d6e 2855 -- Size clause is not handled properly on VM targets.
2856 -- Display a warning unless we are in GNAT mode, in which
2857 -- case this is useless.
47495553 2858
682fa897 2859 Error_Msg_N
2860 ("?size clauses are ignored in this configuration", N);
2861 end if;
2862
d6f39728 2863 if Is_Type (U_Ent) then
2864 Etyp := U_Ent;
2865 else
2866 Etyp := Etype (U_Ent);
2867 end if;
2868
59ac57b5 2869 -- Check size, note that Gigi is in charge of checking that the
2870 -- size of an array or record type is OK. Also we do not check
2871 -- the size in the ordinary fixed-point case, since it is too
2872 -- early to do so (there may be subsequent small clause that
2873 -- affects the size). We can check the size if a small clause
2874 -- has already been given.
d6f39728 2875
2876 if not Is_Ordinary_Fixed_Point_Type (U_Ent)
2877 or else Has_Small_Clause (U_Ent)
2878 then
2879 Check_Size (Expr, Etyp, Size, Biased);
b77e4501 2880 Set_Biased (U_Ent, N, "size clause", Biased);
d6f39728 2881 end if;
2882
2883 -- For types set RM_Size and Esize if possible
2884
2885 if Is_Type (U_Ent) then
2886 Set_RM_Size (U_Ent, Size);
2887
ada34def 2888 -- For elementary types, increase Object_Size to power of 2,
2889 -- but not less than a storage unit in any case (normally
59ac57b5 2890 -- this means it will be byte addressable).
d6f39728 2891
ada34def 2892 -- For all other types, nothing else to do, we leave Esize
2893 -- (object size) unset, the back end will set it from the
2894 -- size and alignment in an appropriate manner.
2895
1d366b32 2896 -- In both cases, we check whether the alignment must be
2897 -- reset in the wake of the size change.
2898
ada34def 2899 if Is_Elementary_Type (U_Ent) then
f15731c4 2900 if Size <= System_Storage_Unit then
2901 Init_Esize (U_Ent, System_Storage_Unit);
d6f39728 2902 elsif Size <= 16 then
2903 Init_Esize (U_Ent, 16);
2904 elsif Size <= 32 then
2905 Init_Esize (U_Ent, 32);
2906 else
2907 Set_Esize (U_Ent, (Size + 63) / 64 * 64);
2908 end if;
2909
1d366b32 2910 Alignment_Check_For_Size_Change (U_Ent, Esize (U_Ent));
2911 else
2912 Alignment_Check_For_Size_Change (U_Ent, Size);
d6f39728 2913 end if;
2914
d6f39728 2915 -- For objects, set Esize only
2916
2917 else
9dfe12ae 2918 if Is_Elementary_Type (Etyp) then
2919 if Size /= System_Storage_Unit
2920 and then
2921 Size /= System_Storage_Unit * 2
2922 and then
2923 Size /= System_Storage_Unit * 4
2924 and then
2925 Size /= System_Storage_Unit * 8
2926 then
5c99c290 2927 Error_Msg_Uint_1 := UI_From_Int (System_Storage_Unit);
87d5c1d0 2928 Error_Msg_Uint_2 := Error_Msg_Uint_1 * 8;
9dfe12ae 2929 Error_Msg_N
5c99c290 2930 ("size for primitive object must be a power of 2"
87d5c1d0 2931 & " in the range ^-^", N);
9dfe12ae 2932 end if;
2933 end if;
2934
d6f39728 2935 Set_Esize (U_Ent, Size);
2936 end if;
2937
2938 Set_Has_Size_Clause (U_Ent);
2939 end if;
2940 end Size;
2941
2942 -----------
2943 -- Small --
2944 -----------
2945
2946 -- Small attribute definition clause
2947
2948 when Attribute_Small => Small : declare
2949 Implicit_Base : constant Entity_Id := Base_Type (U_Ent);
2950 Small : Ureal;
2951
2952 begin
2953 Analyze_And_Resolve (Expr, Any_Real);
2954
2955 if Etype (Expr) = Any_Type then
2956 return;
2957
2958 elsif not Is_Static_Expression (Expr) then
9dfe12ae 2959 Flag_Non_Static_Expr
2960 ("small requires static expression!", Expr);
d6f39728 2961 return;
2962
2963 else
2964 Small := Expr_Value_R (Expr);
2965
2966 if Small <= Ureal_0 then
2967 Error_Msg_N ("small value must be greater than zero", Expr);
2968 return;
2969 end if;
2970
2971 end if;
2972
2973 if not Is_Ordinary_Fixed_Point_Type (U_Ent) then
2974 Error_Msg_N
2975 ("small requires an ordinary fixed point type", Nam);
2976
2977 elsif Has_Small_Clause (U_Ent) then
2978 Error_Msg_N ("small already given for &", Nam);
2979
2980 elsif Small > Delta_Value (U_Ent) then
2981 Error_Msg_N
2982 ("small value must not be greater then delta value", Nam);
2983
2984 else
2985 Set_Small_Value (U_Ent, Small);
2986 Set_Small_Value (Implicit_Base, Small);
2987 Set_Has_Small_Clause (U_Ent);
2988 Set_Has_Small_Clause (Implicit_Base);
2989 Set_Has_Non_Standard_Rep (Implicit_Base);
2990 end if;
2991 end Small;
2992
d6f39728 2993 ------------------
2994 -- Storage_Pool --
2995 ------------------
2996
2997 -- Storage_Pool attribute definition clause
2998
2999 when Attribute_Storage_Pool => Storage_Pool : declare
3000 Pool : Entity_Id;
6b567c71 3001 T : Entity_Id;
d6f39728 3002
3003 begin
44e4341e 3004 if Ekind (U_Ent) = E_Access_Subprogram_Type then
3005 Error_Msg_N
3006 ("storage pool cannot be given for access-to-subprogram type",
3007 Nam);
3008 return;
3009
d3ef794c 3010 elsif not
3011 Ekind_In (U_Ent, E_Access_Type, E_General_Access_Type)
d6f39728 3012 then
44e4341e 3013 Error_Msg_N
3014 ("storage pool can only be given for access types", Nam);
d6f39728 3015 return;
3016
3017 elsif Is_Derived_Type (U_Ent) then
3018 Error_Msg_N
3019 ("storage pool cannot be given for a derived access type",
3020 Nam);
3021
ae888dbd 3022 elsif Duplicate_Clause then
d6f39728 3023 return;
3024
3025 elsif Present (Associated_Storage_Pool (U_Ent)) then
3026 Error_Msg_N ("storage pool already given for &", Nam);
3027 return;
3028 end if;
3029
3030 Analyze_And_Resolve
3031 (Expr, Class_Wide_Type (RTE (RE_Root_Storage_Pool)));
3032
8c5c7277 3033 if not Denotes_Variable (Expr) then
3034 Error_Msg_N ("storage pool must be a variable", Expr);
3035 return;
3036 end if;
3037
6b567c71 3038 if Nkind (Expr) = N_Type_Conversion then
3039 T := Etype (Expression (Expr));
3040 else
3041 T := Etype (Expr);
3042 end if;
3043
3044 -- The Stack_Bounded_Pool is used internally for implementing
d64221a7 3045 -- access types with a Storage_Size. Since it only work properly
3046 -- when used on one specific type, we need to check that it is not
3047 -- hijacked improperly:
3048
6b567c71 3049 -- type T is access Integer;
3050 -- for T'Storage_Size use n;
3051 -- type Q is access Float;
3052 -- for Q'Storage_Size use T'Storage_Size; -- incorrect
3053
15ebb600 3054 if RTE_Available (RE_Stack_Bounded_Pool)
3055 and then Base_Type (T) = RTE (RE_Stack_Bounded_Pool)
3056 then
3057 Error_Msg_N ("non-shareable internal Pool", Expr);
6b567c71 3058 return;
3059 end if;
3060
d6f39728 3061 -- If the argument is a name that is not an entity name, then
3062 -- we construct a renaming operation to define an entity of
3063 -- type storage pool.
3064
3065 if not Is_Entity_Name (Expr)
3066 and then Is_Object_Reference (Expr)
3067 then
11deeeb6 3068 Pool := Make_Temporary (Loc, 'P', Expr);
d6f39728 3069
3070 declare
3071 Rnode : constant Node_Id :=
3072 Make_Object_Renaming_Declaration (Loc,
3073 Defining_Identifier => Pool,
3074 Subtype_Mark =>
3075 New_Occurrence_Of (Etype (Expr), Loc),
11deeeb6 3076 Name => Expr);
d6f39728 3077
3078 begin
3079 Insert_Before (N, Rnode);
3080 Analyze (Rnode);
3081 Set_Associated_Storage_Pool (U_Ent, Pool);
3082 end;
3083
3084 elsif Is_Entity_Name (Expr) then
3085 Pool := Entity (Expr);
3086
3087 -- If pool is a renamed object, get original one. This can
3088 -- happen with an explicit renaming, and within instances.
3089
3090 while Present (Renamed_Object (Pool))
3091 and then Is_Entity_Name (Renamed_Object (Pool))
3092 loop
3093 Pool := Entity (Renamed_Object (Pool));
3094 end loop;
3095
3096 if Present (Renamed_Object (Pool))
3097 and then Nkind (Renamed_Object (Pool)) = N_Type_Conversion
3098 and then Is_Entity_Name (Expression (Renamed_Object (Pool)))
3099 then
3100 Pool := Entity (Expression (Renamed_Object (Pool)));
3101 end if;
3102
6b567c71 3103 Set_Associated_Storage_Pool (U_Ent, Pool);
d6f39728 3104
3105 elsif Nkind (Expr) = N_Type_Conversion
3106 and then Is_Entity_Name (Expression (Expr))
3107 and then Nkind (Original_Node (Expr)) = N_Attribute_Reference
3108 then
3109 Pool := Entity (Expression (Expr));
6b567c71 3110 Set_Associated_Storage_Pool (U_Ent, Pool);
d6f39728 3111
3112 else
3113 Error_Msg_N ("incorrect reference to a Storage Pool", Expr);
3114 return;
3115 end if;
3116 end Storage_Pool;
3117
44e4341e 3118 ------------------
3119 -- Storage_Size --
3120 ------------------
3121
3122 -- Storage_Size attribute definition clause
3123
3124 when Attribute_Storage_Size => Storage_Size : declare
3125 Btype : constant Entity_Id := Base_Type (U_Ent);
3126 Sprag : Node_Id;
3127
3128 begin
3129 if Is_Task_Type (U_Ent) then
3130 Check_Restriction (No_Obsolescent_Features, N);
3131
3132 if Warn_On_Obsolescent_Feature then
3133 Error_Msg_N
3134 ("storage size clause for task is an " &
fbc67f84 3135 "obsolescent feature (RM J.9)?", N);
503f7fd3 3136 Error_Msg_N ("\use Storage_Size pragma instead?", N);
44e4341e 3137 end if;
3138
3139 FOnly := True;
3140 end if;
3141
3142 if not Is_Access_Type (U_Ent)
3143 and then Ekind (U_Ent) /= E_Task_Type
3144 then
3145 Error_Msg_N ("storage size cannot be given for &", Nam);
3146
3147 elsif Is_Access_Type (U_Ent) and Is_Derived_Type (U_Ent) then
3148 Error_Msg_N
3149 ("storage size cannot be given for a derived access type",
3150 Nam);
3151
ae888dbd 3152 elsif Duplicate_Clause then
3153 null;
44e4341e 3154
3155 else
3156 Analyze_And_Resolve (Expr, Any_Integer);
3157
3158 if Is_Access_Type (U_Ent) then
3159 if Present (Associated_Storage_Pool (U_Ent)) then
3160 Error_Msg_N ("storage pool already given for &", Nam);
3161 return;
3162 end if;
3163
5941a4e9 3164 if Is_OK_Static_Expression (Expr)
44e4341e 3165 and then Expr_Value (Expr) = 0
3166 then
3167 Set_No_Pool_Assigned (Btype);
3168 end if;
3169
3170 else -- Is_Task_Type (U_Ent)
3171 Sprag := Get_Rep_Pragma (Btype, Name_Storage_Size);
3172
3173 if Present (Sprag) then
3174 Error_Msg_Sloc := Sloc (Sprag);
3175 Error_Msg_N
3176 ("Storage_Size already specified#", Nam);
3177 return;
3178 end if;
3179 end if;
3180
3181 Set_Has_Storage_Size_Clause (Btype);
3182 end if;
3183 end Storage_Size;
3184
7189d17f 3185 -----------------
3186 -- Stream_Size --
3187 -----------------
3188
3189 when Attribute_Stream_Size => Stream_Size : declare
3190 Size : constant Uint := Static_Integer (Expr);
3191
3192 begin
15ebb600 3193 if Ada_Version <= Ada_95 then
3194 Check_Restriction (No_Implementation_Attributes, N);
3195 end if;
3196
ae888dbd 3197 if Duplicate_Clause then
3198 null;
7189d17f 3199
3200 elsif Is_Elementary_Type (U_Ent) then
3201 if Size /= System_Storage_Unit
3202 and then
3203 Size /= System_Storage_Unit * 2
3204 and then
3205 Size /= System_Storage_Unit * 4
3206 and then
3207 Size /= System_Storage_Unit * 8
3208 then
3209 Error_Msg_Uint_1 := UI_From_Int (System_Storage_Unit);
3210 Error_Msg_N
3211 ("stream size for elementary type must be a"
3212 & " power of 2 and at least ^", N);
3213
3214 elsif RM_Size (U_Ent) > Size then
3215 Error_Msg_Uint_1 := RM_Size (U_Ent);
3216 Error_Msg_N
3217 ("stream size for elementary type must be a"
3218 & " power of 2 and at least ^", N);
3219 end if;
3220
3221 Set_Has_Stream_Size_Clause (U_Ent);
3222
3223 else
3224 Error_Msg_N ("Stream_Size cannot be given for &", Nam);
3225 end if;
3226 end Stream_Size;
3227
d6f39728 3228 ----------------
3229 -- Value_Size --
3230 ----------------
3231
3232 -- Value_Size attribute definition clause
3233
3234 when Attribute_Value_Size => Value_Size : declare
3235 Size : constant Uint := Static_Integer (Expr);
3236 Biased : Boolean;
3237
3238 begin
3239 if not Is_Type (U_Ent) then
3240 Error_Msg_N ("Value_Size cannot be given for &", Nam);
3241
ae888dbd 3242 elsif Duplicate_Clause then
3243 null;
d6f39728 3244
59ac57b5 3245 elsif Is_Array_Type (U_Ent)
3246 and then not Is_Constrained (U_Ent)
3247 then
3248 Error_Msg_N
3249 ("Value_Size cannot be given for unconstrained array", Nam);
3250
d6f39728 3251 else
3252 if Is_Elementary_Type (U_Ent) then
3253 Check_Size (Expr, U_Ent, Size, Biased);
b77e4501 3254 Set_Biased (U_Ent, N, "value size clause", Biased);
d6f39728 3255 end if;
3256
3257 Set_RM_Size (U_Ent, Size);
3258 end if;
3259 end Value_Size;
3260
81b424ac 3261 -----------------------
3262 -- Variable_Indexing --
3263 -----------------------
3264
3265 when Attribute_Variable_Indexing =>
3266 Check_Indexing_Functions;
3267
d6f39728 3268 -----------
3269 -- Write --
3270 -----------
3271
9f373bb8 3272 when Attribute_Write =>
3273 Analyze_Stream_TSS_Definition (TSS_Stream_Write);
3274 Set_Has_Specified_Stream_Write (Ent);
d6f39728 3275
3276 -- All other attributes cannot be set
3277
3278 when others =>
3279 Error_Msg_N
3280 ("attribute& cannot be set with definition clause", N);
d6f39728 3281 end case;
3282
d64221a7 3283 -- The test for the type being frozen must be performed after any
3284 -- expression the clause has been analyzed since the expression itself
3285 -- might cause freezing that makes the clause illegal.
d6f39728 3286
3287 if Rep_Item_Too_Late (U_Ent, N, FOnly) then
3288 return;
3289 end if;
3290 end Analyze_Attribute_Definition_Clause;
3291
3292 ----------------------------
3293 -- Analyze_Code_Statement --
3294 ----------------------------
3295
3296 procedure Analyze_Code_Statement (N : Node_Id) is
3297 HSS : constant Node_Id := Parent (N);
3298 SBody : constant Node_Id := Parent (HSS);
3299 Subp : constant Entity_Id := Current_Scope;
3300 Stmt : Node_Id;
3301 Decl : Node_Id;
3302 StmtO : Node_Id;
3303 DeclO : Node_Id;
3304
3305 begin
3306 -- Analyze and check we get right type, note that this implements the
3307 -- requirement (RM 13.8(1)) that Machine_Code be with'ed, since that
3308 -- is the only way that Asm_Insn could possibly be visible.
3309
3310 Analyze_And_Resolve (Expression (N));
3311
3312 if Etype (Expression (N)) = Any_Type then
3313 return;
3314 elsif Etype (Expression (N)) /= RTE (RE_Asm_Insn) then
3315 Error_Msg_N ("incorrect type for code statement", N);
3316 return;
3317 end if;
3318
44e4341e 3319 Check_Code_Statement (N);
3320
d6f39728 3321 -- Make sure we appear in the handled statement sequence of a
3322 -- subprogram (RM 13.8(3)).
3323
3324 if Nkind (HSS) /= N_Handled_Sequence_Of_Statements
3325 or else Nkind (SBody) /= N_Subprogram_Body
3326 then
3327 Error_Msg_N
3328 ("code statement can only appear in body of subprogram", N);
3329 return;
3330 end if;
3331
3332 -- Do remaining checks (RM 13.8(3)) if not already done
3333
3334 if not Is_Machine_Code_Subprogram (Subp) then
3335 Set_Is_Machine_Code_Subprogram (Subp);
3336
3337 -- No exception handlers allowed
3338
3339 if Present (Exception_Handlers (HSS)) then
3340 Error_Msg_N
3341 ("exception handlers not permitted in machine code subprogram",
3342 First (Exception_Handlers (HSS)));
3343 end if;
3344
3345 -- No declarations other than use clauses and pragmas (we allow
3346 -- certain internally generated declarations as well).
3347
3348 Decl := First (Declarations (SBody));
3349 while Present (Decl) loop
3350 DeclO := Original_Node (Decl);
3351 if Comes_From_Source (DeclO)
fdd294d1 3352 and not Nkind_In (DeclO, N_Pragma,
3353 N_Use_Package_Clause,
3354 N_Use_Type_Clause,
3355 N_Implicit_Label_Declaration)
d6f39728 3356 then
3357 Error_Msg_N
3358 ("this declaration not allowed in machine code subprogram",
3359 DeclO);
3360 end if;
3361
3362 Next (Decl);
3363 end loop;
3364
3365 -- No statements other than code statements, pragmas, and labels.
3366 -- Again we allow certain internally generated statements.
3367
3368 Stmt := First (Statements (HSS));
3369 while Present (Stmt) loop
3370 StmtO := Original_Node (Stmt);
3371 if Comes_From_Source (StmtO)
fdd294d1 3372 and then not Nkind_In (StmtO, N_Pragma,
3373 N_Label,
3374 N_Code_Statement)
d6f39728 3375 then
3376 Error_Msg_N
3377 ("this statement is not allowed in machine code subprogram",
3378 StmtO);
3379 end if;
3380
3381 Next (Stmt);
3382 end loop;
3383 end if;
d6f39728 3384 end Analyze_Code_Statement;
3385
3386 -----------------------------------------------
3387 -- Analyze_Enumeration_Representation_Clause --
3388 -----------------------------------------------
3389
3390 procedure Analyze_Enumeration_Representation_Clause (N : Node_Id) is
3391 Ident : constant Node_Id := Identifier (N);
3392 Aggr : constant Node_Id := Array_Aggregate (N);
3393 Enumtype : Entity_Id;
3394 Elit : Entity_Id;
3395 Expr : Node_Id;
3396 Assoc : Node_Id;
3397 Choice : Node_Id;
3398 Val : Uint;
b3190af0 3399
3400 Err : Boolean := False;
098d3082 3401 -- Set True to avoid cascade errors and crashes on incorrect source code
d6f39728 3402
e30c7d84 3403 Lo : constant Uint := Expr_Value (Type_Low_Bound (Universal_Integer));
3404 Hi : constant Uint := Expr_Value (Type_High_Bound (Universal_Integer));
3405 -- Allowed range of universal integer (= allowed range of enum lit vals)
3406
d6f39728 3407 Min : Uint;
3408 Max : Uint;
e30c7d84 3409 -- Minimum and maximum values of entries
3410
3411 Max_Node : Node_Id;
3412 -- Pointer to node for literal providing max value
d6f39728 3413
3414 begin
ca301e17 3415 if Ignore_Rep_Clauses then
fbc67f84 3416 return;
3417 end if;
3418
d6f39728 3419 -- First some basic error checks
3420
3421 Find_Type (Ident);
3422 Enumtype := Entity (Ident);
3423
3424 if Enumtype = Any_Type
3425 or else Rep_Item_Too_Early (Enumtype, N)
3426 then
3427 return;
3428 else
3429 Enumtype := Underlying_Type (Enumtype);
3430 end if;
3431
3432 if not Is_Enumeration_Type (Enumtype) then
3433 Error_Msg_NE
3434 ("enumeration type required, found}",
3435 Ident, First_Subtype (Enumtype));
3436 return;
3437 end if;
3438
9dfe12ae 3439 -- Ignore rep clause on generic actual type. This will already have
3440 -- been flagged on the template as an error, and this is the safest
3441 -- way to ensure we don't get a junk cascaded message in the instance.
3442
3443 if Is_Generic_Actual_Type (Enumtype) then
3444 return;
3445
3446 -- Type must be in current scope
3447
3448 elsif Scope (Enumtype) /= Current_Scope then
d6f39728 3449 Error_Msg_N ("type must be declared in this scope", Ident);
3450 return;
3451
9dfe12ae 3452 -- Type must be a first subtype
3453
d6f39728 3454 elsif not Is_First_Subtype (Enumtype) then
3455 Error_Msg_N ("cannot give enumeration rep clause for subtype", N);
3456 return;
3457
9dfe12ae 3458 -- Ignore duplicate rep clause
3459
d6f39728 3460 elsif Has_Enumeration_Rep_Clause (Enumtype) then
3461 Error_Msg_N ("duplicate enumeration rep clause ignored", N);
3462 return;
3463
7189d17f 3464 -- Don't allow rep clause for standard [wide_[wide_]]character
9dfe12ae 3465
177675a7 3466 elsif Is_Standard_Character_Type (Enumtype) then
d6f39728 3467 Error_Msg_N ("enumeration rep clause not allowed for this type", N);
9dfe12ae 3468 return;
3469
d9125581 3470 -- Check that the expression is a proper aggregate (no parentheses)
3471
3472 elsif Paren_Count (Aggr) /= 0 then
3473 Error_Msg
3474 ("extra parentheses surrounding aggregate not allowed",
3475 First_Sloc (Aggr));
3476 return;
3477
9dfe12ae 3478 -- All tests passed, so set rep clause in place
d6f39728 3479
3480 else
3481 Set_Has_Enumeration_Rep_Clause (Enumtype);
3482 Set_Has_Enumeration_Rep_Clause (Base_Type (Enumtype));
3483 end if;
3484
3485 -- Now we process the aggregate. Note that we don't use the normal
3486 -- aggregate code for this purpose, because we don't want any of the
3487 -- normal expansion activities, and a number of special semantic
3488 -- rules apply (including the component type being any integer type)
3489
d6f39728 3490 Elit := First_Literal (Enumtype);
3491
3492 -- First the positional entries if any
3493
3494 if Present (Expressions (Aggr)) then
3495 Expr := First (Expressions (Aggr));
3496 while Present (Expr) loop
3497 if No (Elit) then
3498 Error_Msg_N ("too many entries in aggregate", Expr);
3499 return;
3500 end if;
3501
3502 Val := Static_Integer (Expr);
3503
d9125581 3504 -- Err signals that we found some incorrect entries processing
3505 -- the list. The final checks for completeness and ordering are
3506 -- skipped in this case.
3507
d6f39728 3508 if Val = No_Uint then
3509 Err := True;
d6f39728 3510 elsif Val < Lo or else Hi < Val then
3511 Error_Msg_N ("value outside permitted range", Expr);
3512 Err := True;
3513 end if;
3514
3515 Set_Enumeration_Rep (Elit, Val);
3516 Set_Enumeration_Rep_Expr (Elit, Expr);
3517 Next (Expr);
3518 Next (Elit);
3519 end loop;
3520 end if;
3521
3522 -- Now process the named entries if present
3523
3524 if Present (Component_Associations (Aggr)) then
3525 Assoc := First (Component_Associations (Aggr));
3526 while Present (Assoc) loop
3527 Choice := First (Choices (Assoc));
3528
3529 if Present (Next (Choice)) then
3530 Error_Msg_N
3531 ("multiple choice not allowed here", Next (Choice));
3532 Err := True;
3533 end if;
3534
3535 if Nkind (Choice) = N_Others_Choice then
3536 Error_Msg_N ("others choice not allowed here", Choice);
3537 Err := True;
3538
3539 elsif Nkind (Choice) = N_Range then
b3190af0 3540
d6f39728 3541 -- ??? should allow zero/one element range here
b3190af0 3542
d6f39728 3543 Error_Msg_N ("range not allowed here", Choice);
3544 Err := True;
3545
3546 else
3547 Analyze_And_Resolve (Choice, Enumtype);
b3190af0 3548
098d3082 3549 if Error_Posted (Choice) then
d6f39728 3550 Err := True;
098d3082 3551 end if;
d6f39728 3552
098d3082 3553 if not Err then
3554 if Is_Entity_Name (Choice)
3555 and then Is_Type (Entity (Choice))
3556 then
3557 Error_Msg_N ("subtype name not allowed here", Choice);
d6f39728 3558 Err := True;
b3190af0 3559
098d3082 3560 -- ??? should allow static subtype with zero/one entry
d6f39728 3561
098d3082 3562 elsif Etype (Choice) = Base_Type (Enumtype) then
3563 if not Is_Static_Expression (Choice) then
3564 Flag_Non_Static_Expr
3565 ("non-static expression used for choice!", Choice);
d6f39728 3566 Err := True;
d6f39728 3567
098d3082 3568 else
3569 Elit := Expr_Value_E (Choice);
3570
3571 if Present (Enumeration_Rep_Expr (Elit)) then
3572 Error_Msg_Sloc :=
3573 Sloc (Enumeration_Rep_Expr (Elit));
3574 Error_Msg_NE
3575 ("representation for& previously given#",
3576 Choice, Elit);
3577 Err := True;
3578 end if;
d6f39728 3579
098d3082 3580 Set_Enumeration_Rep_Expr (Elit, Expression (Assoc));
d6f39728 3581
098d3082 3582 Expr := Expression (Assoc);
3583 Val := Static_Integer (Expr);
d6f39728 3584
098d3082 3585 if Val = No_Uint then
3586 Err := True;
3587
3588 elsif Val < Lo or else Hi < Val then
3589 Error_Msg_N ("value outside permitted range", Expr);
3590 Err := True;
3591 end if;
d6f39728 3592
098d3082 3593 Set_Enumeration_Rep (Elit, Val);
3594 end if;
d6f39728 3595 end if;
3596 end if;
3597 end if;
3598
3599 Next (Assoc);
3600 end loop;
3601 end if;
3602
3603 -- Aggregate is fully processed. Now we check that a full set of
3604 -- representations was given, and that they are in range and in order.
3605 -- These checks are only done if no other errors occurred.
3606
3607 if not Err then
3608 Min := No_Uint;
3609 Max := No_Uint;
3610
3611 Elit := First_Literal (Enumtype);
3612 while Present (Elit) loop
3613 if No (Enumeration_Rep_Expr (Elit)) then
3614 Error_Msg_NE ("missing representation for&!", N, Elit);
3615
3616 else
3617 Val := Enumeration_Rep (Elit);
3618
3619 if Min = No_Uint then
3620 Min := Val;
3621 end if;
3622
3623 if Val /= No_Uint then
3624 if Max /= No_Uint and then Val <= Max then
3625 Error_Msg_NE
3626 ("enumeration value for& not ordered!",
e30c7d84 3627 Enumeration_Rep_Expr (Elit), Elit);
d6f39728 3628 end if;
3629
e30c7d84 3630 Max_Node := Enumeration_Rep_Expr (Elit);
d6f39728 3631 Max := Val;
3632 end if;
3633
e30c7d84 3634 -- If there is at least one literal whose representation is not
3635 -- equal to the Pos value, then note that this enumeration type
3636 -- has a non-standard representation.
d6f39728 3637
3638 if Val /= Enumeration_Pos (Elit) then
3639 Set_Has_Non_Standard_Rep (Base_Type (Enumtype));
3640 end if;
3641 end if;
3642
3643 Next (Elit);
3644 end loop;
3645
3646 -- Now set proper size information
3647
3648 declare
3649 Minsize : Uint := UI_From_Int (Minimum_Size (Enumtype));
3650
3651 begin
3652 if Has_Size_Clause (Enumtype) then
e30c7d84 3653
3654 -- All OK, if size is OK now
3655
3656 if RM_Size (Enumtype) >= Minsize then
d6f39728 3657 null;
3658
3659 else
e30c7d84 3660 -- Try if we can get by with biasing
3661
d6f39728 3662 Minsize :=
3663 UI_From_Int (Minimum_Size (Enumtype, Biased => True));
3664
e30c7d84 3665 -- Error message if even biasing does not work
3666
3667 if RM_Size (Enumtype) < Minsize then
3668 Error_Msg_Uint_1 := RM_Size (Enumtype);
3669 Error_Msg_Uint_2 := Max;
3670 Error_Msg_N
3671 ("previously given size (^) is too small "
3672 & "for this value (^)", Max_Node);
3673
3674 -- If biasing worked, indicate that we now have biased rep
d6f39728 3675
3676 else
b77e4501 3677 Set_Biased
3678 (Enumtype, Size_Clause (Enumtype), "size clause");
d6f39728 3679 end if;
3680 end if;
3681
3682 else
3683 Set_RM_Size (Enumtype, Minsize);
3684 Set_Enum_Esize (Enumtype);
3685 end if;
3686
3687 Set_RM_Size (Base_Type (Enumtype), RM_Size (Enumtype));
3688 Set_Esize (Base_Type (Enumtype), Esize (Enumtype));
3689 Set_Alignment (Base_Type (Enumtype), Alignment (Enumtype));
3690 end;
3691 end if;
3692
3693 -- We repeat the too late test in case it froze itself!
3694
3695 if Rep_Item_Too_Late (Enumtype, N) then
3696 null;
3697 end if;
d6f39728 3698 end Analyze_Enumeration_Representation_Clause;
3699
3700 ----------------------------
3701 -- Analyze_Free_Statement --
3702 ----------------------------
3703
3704 procedure Analyze_Free_Statement (N : Node_Id) is
3705 begin
3706 Analyze (Expression (N));
3707 end Analyze_Free_Statement;
3708
40ca69b9 3709 ---------------------------
3710 -- Analyze_Freeze_Entity --
3711 ---------------------------
3712
3713 procedure Analyze_Freeze_Entity (N : Node_Id) is
3714 E : constant Entity_Id := Entity (N);
3715
3716 begin
98f7db28 3717 -- Remember that we are processing a freezing entity. Required to
3718 -- ensure correct decoration of internal entities associated with
3719 -- interfaces (see New_Overloaded_Entity).
3720
3721 Inside_Freezing_Actions := Inside_Freezing_Actions + 1;
3722
40ca69b9 3723 -- For tagged types covering interfaces add internal entities that link
3724 -- the primitives of the interfaces with the primitives that cover them.
40ca69b9 3725 -- Note: These entities were originally generated only when generating
3726 -- code because their main purpose was to provide support to initialize
3727 -- the secondary dispatch tables. They are now generated also when
3728 -- compiling with no code generation to provide ASIS the relationship
c8da6114 3729 -- between interface primitives and tagged type primitives. They are
3730 -- also used to locate primitives covering interfaces when processing
3731 -- generics (see Derive_Subprograms).
40ca69b9 3732
de54c5ab 3733 if Ada_Version >= Ada_2005
40ca69b9 3734 and then Ekind (E) = E_Record_Type
3735 and then Is_Tagged_Type (E)
3736 and then not Is_Interface (E)
3737 and then Has_Interfaces (E)
3738 then
c8da6114 3739 -- This would be a good common place to call the routine that checks
3740 -- overriding of interface primitives (and thus factorize calls to
3741 -- Check_Abstract_Overriding located at different contexts in the
3742 -- compiler). However, this is not possible because it causes
3743 -- spurious errors in case of late overriding.
3744
40ca69b9 3745 Add_Internal_Interface_Entities (E);
3746 end if;
d00681a7 3747
3748 -- Check CPP types
3749
3750 if Ekind (E) = E_Record_Type
3751 and then Is_CPP_Class (E)
3752 and then Is_Tagged_Type (E)
3753 and then Tagged_Type_Expansion
3754 and then Expander_Active
3755 then
3756 if CPP_Num_Prims (E) = 0 then
3757
3758 -- If the CPP type has user defined components then it must import
3759 -- primitives from C++. This is required because if the C++ class
3760 -- has no primitives then the C++ compiler does not added the _tag
3761 -- component to the type.
3762
3763 pragma Assert (Chars (First_Entity (E)) = Name_uTag);
3764
3765 if First_Entity (E) /= Last_Entity (E) then
3766 Error_Msg_N
3767 ("?'C'P'P type must import at least one primitive from C++",
3768 E);
3769 end if;
3770 end if;
3771
3772 -- Check that all its primitives are abstract or imported from C++.
3773 -- Check also availability of the C++ constructor.
3774
3775 declare
3776 Has_Constructors : constant Boolean := Has_CPP_Constructors (E);
3777 Elmt : Elmt_Id;
3778 Error_Reported : Boolean := False;
3779 Prim : Node_Id;
3780
3781 begin
3782 Elmt := First_Elmt (Primitive_Operations (E));
3783 while Present (Elmt) loop
3784 Prim := Node (Elmt);
3785
3786 if Comes_From_Source (Prim) then
3787 if Is_Abstract_Subprogram (Prim) then
3788 null;
3789
3790 elsif not Is_Imported (Prim)
3791 or else Convention (Prim) /= Convention_CPP
3792 then
3793 Error_Msg_N
3794 ("?primitives of 'C'P'P types must be imported from C++"
3795 & " or abstract", Prim);
3796
3797 elsif not Has_Constructors
3798 and then not Error_Reported
3799 then
3800 Error_Msg_Name_1 := Chars (E);
3801 Error_Msg_N
3802 ("?'C'P'P constructor required for type %", Prim);
3803 Error_Reported := True;
3804 end if;
3805 end if;
3806
3807 Next_Elmt (Elmt);
3808 end loop;
3809 end;
3810 end if;
98f7db28 3811
3812 Inside_Freezing_Actions := Inside_Freezing_Actions - 1;
9dc88aea 3813
3814 -- If we have a type with predicates, build predicate function
3815
3816 if Is_Type (E) and then Has_Predicates (E) then
490beba6 3817 Build_Predicate_Function (E, N);
9dc88aea 3818 end if;
fb7f2fc4 3819
d64221a7 3820 -- If type has delayed aspects, this is where we do the preanalysis at
3821 -- the freeze point, as part of the consistent visibility check. Note
3822 -- that this must be done after calling Build_Predicate_Function or
3823 -- Build_Invariant_Procedure since these subprograms fix occurrences of
3824 -- the subtype name in the saved expression so that they will not cause
3825 -- trouble in the preanalysis.
fb7f2fc4 3826
3827 if Has_Delayed_Aspects (E) then
3828 declare
3829 Ritem : Node_Id;
3830
3831 begin
3832 -- Look for aspect specification entries for this entity
3833
3834 Ritem := First_Rep_Item (E);
3835 while Present (Ritem) loop
3836 if Nkind (Ritem) = N_Aspect_Specification
3837 and then Entity (Ritem) = E
3838 and then Is_Delayed_Aspect (Ritem)
89cc7147 3839 and then Scope (E) = Current_Scope
fb7f2fc4 3840 then
3841 Check_Aspect_At_Freeze_Point (Ritem);
3842 end if;
3843
3844 Next_Rep_Item (Ritem);
3845 end loop;
3846 end;
3847 end if;
40ca69b9 3848 end Analyze_Freeze_Entity;
3849
d6f39728 3850 ------------------------------------------
3851 -- Analyze_Record_Representation_Clause --
3852 ------------------------------------------
3853
67278d60 3854 -- Note: we check as much as we can here, but we can't do any checks
3855 -- based on the position values (e.g. overlap checks) until freeze time
3856 -- because especially in Ada 2005 (machine scalar mode), the processing
3857 -- for non-standard bit order can substantially change the positions.
3858 -- See procedure Check_Record_Representation_Clause (called from Freeze)
3859 -- for the remainder of this processing.
3860
d6f39728 3861 procedure Analyze_Record_Representation_Clause (N : Node_Id) is
7800b920 3862 Ident : constant Node_Id := Identifier (N);
3863 Biased : Boolean;
d6f39728 3864 CC : Node_Id;
7800b920 3865 Comp : Entity_Id;
d6f39728 3866 Fbit : Uint;
d6f39728 3867 Hbit : Uint := Uint_0;
7800b920 3868 Lbit : Uint;
d6f39728 3869 Ocomp : Entity_Id;
7800b920 3870 Posit : Uint;
3871 Rectype : Entity_Id;
d6f39728 3872
639e37b0 3873 CR_Pragma : Node_Id := Empty;
3874 -- Points to N_Pragma node if Complete_Representation pragma present
3875
d6f39728 3876 begin
fbc67f84 3877 if Ignore_Rep_Clauses then
3878 return;
3879 end if;
3880
d6f39728 3881 Find_Type (Ident);
3882 Rectype := Entity (Ident);
3883
3884 if Rectype = Any_Type
3885 or else Rep_Item_Too_Early (Rectype, N)
3886 then
3887 return;
3888 else
3889 Rectype := Underlying_Type (Rectype);
3890 end if;
3891
3892 -- First some basic error checks
3893
3894 if not Is_Record_Type (Rectype) then
3895 Error_Msg_NE
3896 ("record type required, found}", Ident, First_Subtype (Rectype));
3897 return;
3898
d6f39728 3899 elsif Scope (Rectype) /= Current_Scope then
3900 Error_Msg_N ("type must be declared in this scope", N);
3901 return;
3902
3903 elsif not Is_First_Subtype (Rectype) then
3904 Error_Msg_N ("cannot give record rep clause for subtype", N);
3905 return;
3906
3907 elsif Has_Record_Rep_Clause (Rectype) then
3908 Error_Msg_N ("duplicate record rep clause ignored", N);
3909 return;
3910
3911 elsif Rep_Item_Too_Late (Rectype, N) then
3912 return;
3913 end if;
3914
3915 if Present (Mod_Clause (N)) then
3916 declare
3917 Loc : constant Source_Ptr := Sloc (N);
3918 M : constant Node_Id := Mod_Clause (N);
3919 P : constant List_Id := Pragmas_Before (M);
d6f39728 3920 AtM_Nod : Node_Id;
3921
9dfe12ae 3922 Mod_Val : Uint;
3923 pragma Warnings (Off, Mod_Val);
3924
d6f39728 3925 begin
e0521a36 3926 Check_Restriction (No_Obsolescent_Features, Mod_Clause (N));
3927
9dfe12ae 3928 if Warn_On_Obsolescent_Feature then
3929 Error_Msg_N
fbc67f84 3930 ("mod clause is an obsolescent feature (RM J.8)?", N);
9dfe12ae 3931 Error_Msg_N
d53a018a 3932 ("\use alignment attribute definition clause instead?", N);
9dfe12ae 3933 end if;
3934
d6f39728 3935 if Present (P) then
3936 Analyze_List (P);
3937 end if;
3938
fbc67f84 3939 -- In ASIS_Mode mode, expansion is disabled, but we must convert
3940 -- the Mod clause into an alignment clause anyway, so that the
3941 -- back-end can compute and back-annotate properly the size and
3942 -- alignment of types that may include this record.
d6f39728 3943
15ebb600 3944 -- This seems dubious, this destroys the source tree in a manner
3945 -- not detectable by ASIS ???
3946
3157c4f3 3947 if Operating_Mode = Check_Semantics and then ASIS_Mode then
d6f39728 3948 AtM_Nod :=
3949 Make_Attribute_Definition_Clause (Loc,
3950 Name => New_Reference_To (Base_Type (Rectype), Loc),
3951 Chars => Name_Alignment,
3952 Expression => Relocate_Node (Expression (M)));
3953
3954 Set_From_At_Mod (AtM_Nod);
3955 Insert_After (N, AtM_Nod);
3956 Mod_Val := Get_Alignment_Value (Expression (AtM_Nod));
3957 Set_Mod_Clause (N, Empty);
3958
3959 else
3960 -- Get the alignment value to perform error checking
3961
3962 Mod_Val := Get_Alignment_Value (Expression (M));
d6f39728 3963 end if;
3964 end;
3965 end if;
3966
3062c401 3967 -- For untagged types, clear any existing component clauses for the
3968 -- type. If the type is derived, this is what allows us to override
3969 -- a rep clause for the parent. For type extensions, the representation
3970 -- of the inherited components is inherited, so we want to keep previous
3971 -- component clauses for completeness.
d6f39728 3972
3062c401 3973 if not Is_Tagged_Type (Rectype) then
3974 Comp := First_Component_Or_Discriminant (Rectype);
3975 while Present (Comp) loop
3976 Set_Component_Clause (Comp, Empty);
3977 Next_Component_Or_Discriminant (Comp);
3978 end loop;
3979 end if;
d6f39728 3980
3981 -- All done if no component clauses
3982
3983 CC := First (Component_Clauses (N));
3984
3985 if No (CC) then
3986 return;
3987 end if;
3988
f15731c4 3989 -- A representation like this applies to the base type
d6f39728 3990
3991 Set_Has_Record_Rep_Clause (Base_Type (Rectype));
3992 Set_Has_Non_Standard_Rep (Base_Type (Rectype));
3993 Set_Has_Specified_Layout (Base_Type (Rectype));
3994
d6f39728 3995 -- Process the component clauses
3996
3997 while Present (CC) loop
3998
639e37b0 3999 -- Pragma
d6f39728 4000
4001 if Nkind (CC) = N_Pragma then
4002 Analyze (CC);
4003
639e37b0 4004 -- The only pragma of interest is Complete_Representation
4005
fdd294d1 4006 if Pragma_Name (CC) = Name_Complete_Representation then
639e37b0 4007 CR_Pragma := CC;
4008 end if;
4009
d6f39728 4010 -- Processing for real component clause
4011
4012 else
d6f39728 4013 Posit := Static_Integer (Position (CC));
4014 Fbit := Static_Integer (First_Bit (CC));
4015 Lbit := Static_Integer (Last_Bit (CC));
4016
4017 if Posit /= No_Uint
4018 and then Fbit /= No_Uint
4019 and then Lbit /= No_Uint
4020 then
4021 if Posit < 0 then
4022 Error_Msg_N
4023 ("position cannot be negative", Position (CC));
4024
4025 elsif Fbit < 0 then
4026 Error_Msg_N
4027 ("first bit cannot be negative", First_Bit (CC));
4028
177675a7 4029 -- The Last_Bit specified in a component clause must not be
4030 -- less than the First_Bit minus one (RM-13.5.1(10)).
4031
4032 elsif Lbit < Fbit - 1 then
4033 Error_Msg_N
4034 ("last bit cannot be less than first bit minus one",
4035 Last_Bit (CC));
4036
d6f39728 4037 -- Values look OK, so find the corresponding record component
4038 -- Even though the syntax allows an attribute reference for
4039 -- implementation-defined components, GNAT does not allow the
4040 -- tag to get an explicit position.
4041
4042 elsif Nkind (Component_Name (CC)) = N_Attribute_Reference then
d6f39728 4043 if Attribute_Name (Component_Name (CC)) = Name_Tag then
4044 Error_Msg_N ("position of tag cannot be specified", CC);
4045 else
4046 Error_Msg_N ("illegal component name", CC);
4047 end if;
4048
4049 else
4050 Comp := First_Entity (Rectype);
4051 while Present (Comp) loop
4052 exit when Chars (Comp) = Chars (Component_Name (CC));
4053 Next_Entity (Comp);
4054 end loop;
4055
4056 if No (Comp) then
4057
4058 -- Maybe component of base type that is absent from
4059 -- statically constrained first subtype.
4060
4061 Comp := First_Entity (Base_Type (Rectype));
4062 while Present (Comp) loop
4063 exit when Chars (Comp) = Chars (Component_Name (CC));
4064 Next_Entity (Comp);
4065 end loop;
4066 end if;
4067
4068 if No (Comp) then
4069 Error_Msg_N
4070 ("component clause is for non-existent field", CC);
4071
7800b920 4072 -- Ada 2012 (AI05-0026): Any name that denotes a
4073 -- discriminant of an object of an unchecked union type
4074 -- shall not occur within a record_representation_clause.
4075
4076 -- The general restriction of using record rep clauses on
4077 -- Unchecked_Union types has now been lifted. Since it is
4078 -- possible to introduce a record rep clause which mentions
4079 -- the discriminant of an Unchecked_Union in non-Ada 2012
4080 -- code, this check is applied to all versions of the
4081 -- language.
4082
4083 elsif Ekind (Comp) = E_Discriminant
4084 and then Is_Unchecked_Union (Rectype)
4085 then
4086 Error_Msg_N
4087 ("cannot reference discriminant of Unchecked_Union",
4088 Component_Name (CC));
4089
d6f39728 4090 elsif Present (Component_Clause (Comp)) then
3062c401 4091
1a34e48c 4092 -- Diagnose duplicate rep clause, or check consistency
fdd294d1 4093 -- if this is an inherited component. In a double fault,
3062c401 4094 -- there may be a duplicate inconsistent clause for an
4095 -- inherited component.
4096
fdd294d1 4097 if Scope (Original_Record_Component (Comp)) = Rectype
4098 or else Parent (Component_Clause (Comp)) = N
3062c401 4099 then
4100 Error_Msg_Sloc := Sloc (Component_Clause (Comp));
4101 Error_Msg_N ("component clause previously given#", CC);
4102
4103 else
4104 declare
4105 Rep1 : constant Node_Id := Component_Clause (Comp);
3062c401 4106 begin
4107 if Intval (Position (Rep1)) /=
4108 Intval (Position (CC))
4109 or else Intval (First_Bit (Rep1)) /=
4110 Intval (First_Bit (CC))
4111 or else Intval (Last_Bit (Rep1)) /=
4112 Intval (Last_Bit (CC))
4113 then
4114 Error_Msg_N ("component clause inconsistent "
4115 & "with representation of ancestor", CC);
3062c401 4116 elsif Warn_On_Redundant_Constructs then
4117 Error_Msg_N ("?redundant component clause "
4118 & "for inherited component!", CC);
4119 end if;
4120 end;
4121 end if;
d6f39728 4122
d2b860b4 4123 -- Normal case where this is the first component clause we
4124 -- have seen for this entity, so set it up properly.
4125
d6f39728 4126 else
83f8f0a6 4127 -- Make reference for field in record rep clause and set
4128 -- appropriate entity field in the field identifier.
4129
4130 Generate_Reference
4131 (Comp, Component_Name (CC), Set_Ref => False);
4132 Set_Entity (Component_Name (CC), Comp);
4133
2866d595 4134 -- Update Fbit and Lbit to the actual bit number
d6f39728 4135
4136 Fbit := Fbit + UI_From_Int (SSU) * Posit;
4137 Lbit := Lbit + UI_From_Int (SSU) * Posit;
4138
d6f39728 4139 if Has_Size_Clause (Rectype)
ada34def 4140 and then RM_Size (Rectype) <= Lbit
d6f39728 4141 then
4142 Error_Msg_N
4143 ("bit number out of range of specified size",
4144 Last_Bit (CC));
4145 else
4146 Set_Component_Clause (Comp, CC);
4147 Set_Component_Bit_Offset (Comp, Fbit);
4148 Set_Esize (Comp, 1 + (Lbit - Fbit));
4149 Set_Normalized_First_Bit (Comp, Fbit mod SSU);
4150 Set_Normalized_Position (Comp, Fbit / SSU);
4151
a0fc8c5b 4152 if Warn_On_Overridden_Size
4153 and then Has_Size_Clause (Etype (Comp))
4154 and then RM_Size (Etype (Comp)) /= Esize (Comp)
4155 then
4156 Error_Msg_NE
4157 ("?component size overrides size clause for&",
4158 Component_Name (CC), Etype (Comp));
4159 end if;
4160
ea61a7ea 4161 -- This information is also set in the corresponding
4162 -- component of the base type, found by accessing the
4163 -- Original_Record_Component link if it is present.
d6f39728 4164
4165 Ocomp := Original_Record_Component (Comp);
4166
4167 if Hbit < Lbit then
4168 Hbit := Lbit;
4169 end if;
4170
4171 Check_Size
4172 (Component_Name (CC),
4173 Etype (Comp),
4174 Esize (Comp),
4175 Biased);
4176
b77e4501 4177 Set_Biased
4178 (Comp, First_Node (CC), "component clause", Biased);
cc46ff4b 4179
d6f39728 4180 if Present (Ocomp) then
4181 Set_Component_Clause (Ocomp, CC);
4182 Set_Component_Bit_Offset (Ocomp, Fbit);
4183 Set_Normalized_First_Bit (Ocomp, Fbit mod SSU);
4184 Set_Normalized_Position (Ocomp, Fbit / SSU);
4185 Set_Esize (Ocomp, 1 + (Lbit - Fbit));
4186
4187 Set_Normalized_Position_Max
4188 (Ocomp, Normalized_Position (Ocomp));
4189
b77e4501 4190 -- Note: we don't use Set_Biased here, because we
4191 -- already gave a warning above if needed, and we
4192 -- would get a duplicate for the same name here.
4193
d6f39728 4194 Set_Has_Biased_Representation
4195 (Ocomp, Has_Biased_Representation (Comp));
4196 end if;
4197
4198 if Esize (Comp) < 0 then
4199 Error_Msg_N ("component size is negative", CC);
4200 end if;
4201 end if;
4202 end if;
4203 end if;
4204 end if;
4205 end if;
4206
4207 Next (CC);
4208 end loop;
4209
67278d60 4210 -- Check missing components if Complete_Representation pragma appeared
d6f39728 4211
67278d60 4212 if Present (CR_Pragma) then
4213 Comp := First_Component_Or_Discriminant (Rectype);
4214 while Present (Comp) loop
4215 if No (Component_Clause (Comp)) then
4216 Error_Msg_NE
4217 ("missing component clause for &", CR_Pragma, Comp);
4218 end if;
d6f39728 4219
67278d60 4220 Next_Component_Or_Discriminant (Comp);
4221 end loop;
d6f39728 4222
67278d60 4223 -- If no Complete_Representation pragma, warn if missing components
15ebb600 4224
fdd294d1 4225 elsif Warn_On_Unrepped_Components then
15ebb600 4226 declare
4227 Num_Repped_Components : Nat := 0;
4228 Num_Unrepped_Components : Nat := 0;
4229
4230 begin
4231 -- First count number of repped and unrepped components
4232
4233 Comp := First_Component_Or_Discriminant (Rectype);
4234 while Present (Comp) loop
4235 if Present (Component_Clause (Comp)) then
4236 Num_Repped_Components := Num_Repped_Components + 1;
4237 else
4238 Num_Unrepped_Components := Num_Unrepped_Components + 1;
4239 end if;
4240
4241 Next_Component_Or_Discriminant (Comp);
4242 end loop;
4243
4244 -- We are only interested in the case where there is at least one
4245 -- unrepped component, and at least half the components have rep
4246 -- clauses. We figure that if less than half have them, then the
87f9eef5 4247 -- partial rep clause is really intentional. If the component
4248 -- type has no underlying type set at this point (as for a generic
4249 -- formal type), we don't know enough to give a warning on the
4250 -- component.
15ebb600 4251
4252 if Num_Unrepped_Components > 0
4253 and then Num_Unrepped_Components < Num_Repped_Components
4254 then
4255 Comp := First_Component_Or_Discriminant (Rectype);
4256 while Present (Comp) loop
83f8f0a6 4257 if No (Component_Clause (Comp))
3062c401 4258 and then Comes_From_Source (Comp)
87f9eef5 4259 and then Present (Underlying_Type (Etype (Comp)))
83f8f0a6 4260 and then (Is_Scalar_Type (Underlying_Type (Etype (Comp)))
67278d60 4261 or else Size_Known_At_Compile_Time
4262 (Underlying_Type (Etype (Comp))))
fdd294d1 4263 and then not Has_Warnings_Off (Rectype)
83f8f0a6 4264 then
15ebb600 4265 Error_Msg_Sloc := Sloc (Comp);
4266 Error_Msg_NE
4267 ("?no component clause given for & declared #",
4268 N, Comp);
4269 end if;
4270
4271 Next_Component_Or_Discriminant (Comp);
4272 end loop;
4273 end if;
4274 end;
d6f39728 4275 end if;
d6f39728 4276 end Analyze_Record_Representation_Clause;
4277
5b5df4a9 4278 -------------------------------
4279 -- Build_Invariant_Procedure --
4280 -------------------------------
4281
4282 -- The procedure that is constructed here has the form
4283
4284 -- procedure typInvariant (Ixxx : typ) is
4285 -- begin
4286 -- pragma Check (Invariant, exp, "failed invariant from xxx");
4287 -- pragma Check (Invariant, exp, "failed invariant from xxx");
4288 -- ...
4289 -- pragma Check (Invariant, exp, "failed inherited invariant from xxx");
4290 -- ...
4291 -- end typInvariant;
4292
87f3d5d3 4293 procedure Build_Invariant_Procedure (Typ : Entity_Id; N : Node_Id) is
5b5df4a9 4294 Loc : constant Source_Ptr := Sloc (Typ);
4295 Stmts : List_Id;
4296 Spec : Node_Id;
4297 SId : Entity_Id;
87f3d5d3 4298 PDecl : Node_Id;
4299 PBody : Node_Id;
4300
4301 Visible_Decls : constant List_Id := Visible_Declarations (N);
4302 Private_Decls : constant List_Id := Private_Declarations (N);
5b5df4a9 4303
4304 procedure Add_Invariants (T : Entity_Id; Inherit : Boolean);
4305 -- Appends statements to Stmts for any invariants in the rep item chain
4306 -- of the given type. If Inherit is False, then we only process entries
4307 -- on the chain for the type Typ. If Inherit is True, then we ignore any
4308 -- Invariant aspects, but we process all Invariant'Class aspects, adding
4309 -- "inherited" to the exception message and generating an informational
4310 -- message about the inheritance of an invariant.
4311
4312 Object_Name : constant Name_Id := New_Internal_Name ('I');
4313 -- Name for argument of invariant procedure
4314
87f3d5d3 4315 Object_Entity : constant Node_Id :=
4316 Make_Defining_Identifier (Loc, Object_Name);
4317 -- The procedure declaration entity for the argument
4318
5b5df4a9 4319 --------------------
4320 -- Add_Invariants --
4321 --------------------
4322
4323 procedure Add_Invariants (T : Entity_Id; Inherit : Boolean) is
4324 Ritem : Node_Id;
4325 Arg1 : Node_Id;
4326 Arg2 : Node_Id;
4327 Arg3 : Node_Id;
4328 Exp : Node_Id;
4329 Loc : Source_Ptr;
4330 Assoc : List_Id;
4331 Str : String_Id;
4332
2072eaa9 4333 procedure Replace_Type_Reference (N : Node_Id);
4334 -- Replace a single occurrence N of the subtype name with a reference
4335 -- to the formal of the predicate function. N can be an identifier
4336 -- referencing the subtype, or a selected component, representing an
4337 -- appropriately qualified occurrence of the subtype name.
5b5df4a9 4338
2072eaa9 4339 procedure Replace_Type_References is
4340 new Replace_Type_References_Generic (Replace_Type_Reference);
4341 -- Traverse an expression replacing all occurrences of the subtype
4342 -- name with appropriate references to the object that is the formal
87f3d5d3 4343 -- parameter of the predicate function. Note that we must ensure
4344 -- that the type and entity information is properly set in the
4345 -- replacement node, since we will do a Preanalyze call of this
4346 -- expression without proper visibility of the procedure argument.
5b5df4a9 4347
2072eaa9 4348 ----------------------------
4349 -- Replace_Type_Reference --
4350 ----------------------------
5b5df4a9 4351
2072eaa9 4352 procedure Replace_Type_Reference (N : Node_Id) is
5b5df4a9 4353 begin
2072eaa9 4354 -- Invariant'Class, replace with T'Class (obj)
4355
4356 if Class_Present (Ritem) then
4357 Rewrite (N,
4358 Make_Type_Conversion (Loc,
4359 Subtype_Mark =>
4360 Make_Attribute_Reference (Loc,
55868293 4361 Prefix => New_Occurrence_Of (T, Loc),
2072eaa9 4362 Attribute_Name => Name_Class),
55868293 4363 Expression => Make_Identifier (Loc, Object_Name)));
5b5df4a9 4364
87f3d5d3 4365 Set_Entity (Expression (N), Object_Entity);
4366 Set_Etype (Expression (N), Typ);
4367
2072eaa9 4368 -- Invariant, replace with obj
5b5df4a9 4369
4370 else
55868293 4371 Rewrite (N, Make_Identifier (Loc, Object_Name));
87f3d5d3 4372 Set_Entity (N, Object_Entity);
4373 Set_Etype (N, Typ);
5b5df4a9 4374 end if;
2072eaa9 4375 end Replace_Type_Reference;
5b5df4a9 4376
4377 -- Start of processing for Add_Invariants
4378
4379 begin
4380 Ritem := First_Rep_Item (T);
4381 while Present (Ritem) loop
4382 if Nkind (Ritem) = N_Pragma
4383 and then Pragma_Name (Ritem) = Name_Invariant
4384 then
4385 Arg1 := First (Pragma_Argument_Associations (Ritem));
4386 Arg2 := Next (Arg1);
4387 Arg3 := Next (Arg2);
4388
4389 Arg1 := Get_Pragma_Arg (Arg1);
4390 Arg2 := Get_Pragma_Arg (Arg2);
4391
4392 -- For Inherit case, ignore Invariant, process only Class case
4393
4394 if Inherit then
4395 if not Class_Present (Ritem) then
4396 goto Continue;
4397 end if;
4398
4399 -- For Inherit false, process only item for right type
4400
4401 else
4402 if Entity (Arg1) /= Typ then
4403 goto Continue;
4404 end if;
4405 end if;
4406
4407 if No (Stmts) then
4408 Stmts := Empty_List;
4409 end if;
4410
4411 Exp := New_Copy_Tree (Arg2);
4412 Loc := Sloc (Exp);
4413
4414 -- We need to replace any occurrences of the name of the type
4415 -- with references to the object, converted to type'Class in
2072eaa9 4416 -- the case of Invariant'Class aspects.
5b5df4a9 4417
2072eaa9 4418 Replace_Type_References (Exp, Chars (T));
5b5df4a9 4419
fb7f2fc4 4420 -- If this invariant comes from an aspect, find the aspect
4421 -- specification, and replace the saved expression because
4422 -- we need the subtype references replaced for the calls to
4423 -- Preanalyze_Spec_Expressin in Check_Aspect_At_Freeze_Point
4424 -- and Check_Aspect_At_End_Of_Declarations.
4425
4426 if From_Aspect_Specification (Ritem) then
4427 declare
4428 Aitem : Node_Id;
4429
4430 begin
4431 -- Loop to find corresponding aspect, note that this
4432 -- must be present given the pragma is marked delayed.
4433
4434 Aitem := Next_Rep_Item (Ritem);
4435 while Present (Aitem) loop
4436 if Nkind (Aitem) = N_Aspect_Specification
4437 and then Aspect_Rep_Item (Aitem) = Ritem
4438 then
4439 Set_Entity
4440 (Identifier (Aitem), New_Copy_Tree (Exp));
4441 exit;
4442 end if;
4443
4444 Aitem := Next_Rep_Item (Aitem);
4445 end loop;
4446 end;
4447 end if;
4448
87f3d5d3 4449 -- Now we need to preanalyze the expression to properly capture
4450 -- the visibility in the visible part. The expression will not
4451 -- be analyzed for real until the body is analyzed, but that is
4452 -- at the end of the private part and has the wrong visibility.
4453
4454 Set_Parent (Exp, N);
4455 Preanalyze_Spec_Expression (Exp, Standard_Boolean);
4456
5b5df4a9 4457 -- Build first two arguments for Check pragma
4458
4459 Assoc := New_List (
4460 Make_Pragma_Argument_Association (Loc,
55868293 4461 Expression => Make_Identifier (Loc, Name_Invariant)),
4462 Make_Pragma_Argument_Association (Loc, Expression => Exp));
5b5df4a9 4463
4464 -- Add message if present in Invariant pragma
4465
4466 if Present (Arg3) then
4467 Str := Strval (Get_Pragma_Arg (Arg3));
4468
4469 -- If inherited case, and message starts "failed invariant",
4470 -- change it to be "failed inherited invariant".
4471
4472 if Inherit then
4473 String_To_Name_Buffer (Str);
4474
4475 if Name_Buffer (1 .. 16) = "failed invariant" then
4476 Insert_Str_In_Name_Buffer ("inherited ", 8);
4477 Str := String_From_Name_Buffer;
4478 end if;
4479 end if;
4480
4481 Append_To (Assoc,
4482 Make_Pragma_Argument_Association (Loc,
4483 Expression => Make_String_Literal (Loc, Str)));
4484 end if;
4485
4486 -- Add Check pragma to list of statements
4487
4488 Append_To (Stmts,
4489 Make_Pragma (Loc,
4490 Pragma_Identifier =>
55868293 4491 Make_Identifier (Loc, Name_Check),
5b5df4a9 4492 Pragma_Argument_Associations => Assoc));
4493
4494 -- If Inherited case and option enabled, output info msg. Note
4495 -- that we know this is a case of Invariant'Class.
4496
4497 if Inherit and Opt.List_Inherited_Aspects then
4498 Error_Msg_Sloc := Sloc (Ritem);
4499 Error_Msg_N
4500 ("?info: & inherits `Invariant''Class` aspect from #",
4501 Typ);
4502 end if;
4503 end if;
4504
4505 <<Continue>>
4506 Next_Rep_Item (Ritem);
4507 end loop;
4508 end Add_Invariants;
4509
4510 -- Start of processing for Build_Invariant_Procedure
4511
4512 begin
4513 Stmts := No_List;
4514 PDecl := Empty;
4515 PBody := Empty;
87f3d5d3 4516 Set_Etype (Object_Entity, Typ);
5b5df4a9 4517
4518 -- Add invariants for the current type
4519
4520 Add_Invariants (Typ, Inherit => False);
4521
4522 -- Add invariants for parent types
4523
4524 declare
4525 Current_Typ : Entity_Id;
4526 Parent_Typ : Entity_Id;
4527
4528 begin
4529 Current_Typ := Typ;
4530 loop
4531 Parent_Typ := Etype (Current_Typ);
4532
4533 if Is_Private_Type (Parent_Typ)
4534 and then Present (Full_View (Base_Type (Parent_Typ)))
4535 then
4536 Parent_Typ := Full_View (Base_Type (Parent_Typ));
4537 end if;
4538
4539 exit when Parent_Typ = Current_Typ;
4540
4541 Current_Typ := Parent_Typ;
4542 Add_Invariants (Current_Typ, Inherit => True);
4543 end loop;
4544 end;
4545
5b5df4a9 4546 -- Build the procedure if we generated at least one Check pragma
4547
4548 if Stmts /= No_List then
4549
4550 -- Build procedure declaration
4551
4552 SId :=
4553 Make_Defining_Identifier (Loc,
4554 Chars => New_External_Name (Chars (Typ), "Invariant"));
f54f1dff 4555 Set_Has_Invariants (SId);
5b5df4a9 4556 Set_Invariant_Procedure (Typ, SId);
4557
4558 Spec :=
4559 Make_Procedure_Specification (Loc,
4560 Defining_Unit_Name => SId,
4561 Parameter_Specifications => New_List (
4562 Make_Parameter_Specification (Loc,
87f3d5d3 4563 Defining_Identifier => Object_Entity,
4564 Parameter_Type => New_Occurrence_Of (Typ, Loc))));
5b5df4a9 4565
87f3d5d3 4566 PDecl := Make_Subprogram_Declaration (Loc, Specification => Spec);
5b5df4a9 4567
4568 -- Build procedure body
4569
4570 SId :=
4571 Make_Defining_Identifier (Loc,
4572 Chars => New_External_Name (Chars (Typ), "Invariant"));
4573
4574 Spec :=
4575 Make_Procedure_Specification (Loc,
4576 Defining_Unit_Name => SId,
4577 Parameter_Specifications => New_List (
4578 Make_Parameter_Specification (Loc,
4579 Defining_Identifier =>
55868293 4580 Make_Defining_Identifier (Loc, Object_Name),
4581 Parameter_Type => New_Occurrence_Of (Typ, Loc))));
5b5df4a9 4582
4583 PBody :=
4584 Make_Subprogram_Body (Loc,
4585 Specification => Spec,
4586 Declarations => Empty_List,
4587 Handled_Statement_Sequence =>
4588 Make_Handled_Sequence_Of_Statements (Loc,
4589 Statements => Stmts));
87f3d5d3 4590
4591 -- Insert procedure declaration and spec at the appropriate points.
4592 -- Skip this if there are no private declarations (that's an error
4593 -- that will be diagnosed elsewhere, and there is no point in having
4594 -- an invariant procedure set if the full declaration is missing).
4595
4596 if Present (Private_Decls) then
4597
4598 -- The spec goes at the end of visible declarations, but they have
4599 -- already been analyzed, so we need to explicitly do the analyze.
4600
4601 Append_To (Visible_Decls, PDecl);
4602 Analyze (PDecl);
4603
4604 -- The body goes at the end of the private declarations, which we
4605 -- have not analyzed yet, so we do not need to perform an explicit
4606 -- analyze call. We skip this if there are no private declarations
4607 -- (this is an error that will be caught elsewhere);
4608
4609 Append_To (Private_Decls, PBody);
4610 end if;
5b5df4a9 4611 end if;
4612 end Build_Invariant_Procedure;
4613
9dc88aea 4614 ------------------------------
4615 -- Build_Predicate_Function --
4616 ------------------------------
4617
4618 -- The procedure that is constructed here has the form
4619
4620 -- function typPredicate (Ixxx : typ) return Boolean is
4621 -- begin
4622 -- return
4623 -- exp1 and then exp2 and then ...
4624 -- and then typ1Predicate (typ1 (Ixxx))
4625 -- and then typ2Predicate (typ2 (Ixxx))
4626 -- and then ...;
4627 -- end typPredicate;
4628
4629 -- Here exp1, and exp2 are expressions from Predicate pragmas. Note that
4630 -- this is the point at which these expressions get analyzed, providing the
4631 -- required delay, and typ1, typ2, are entities from which predicates are
4632 -- inherited. Note that we do NOT generate Check pragmas, that's because we
4633 -- use this function even if checks are off, e.g. for membership tests.
4634
490beba6 4635 procedure Build_Predicate_Function (Typ : Entity_Id; N : Node_Id) is
9dc88aea 4636 Loc : constant Source_Ptr := Sloc (Typ);
4637 Spec : Node_Id;
4638 SId : Entity_Id;
490beba6 4639 FDecl : Node_Id;
4640 FBody : Node_Id;
4641
9dc88aea 4642 Expr : Node_Id;
4643 -- This is the expression for the return statement in the function. It
4644 -- is build by connecting the component predicates with AND THEN.
4645
4646 procedure Add_Call (T : Entity_Id);
4647 -- Includes a call to the predicate function for type T in Expr if T
4648 -- has predicates and Predicate_Function (T) is non-empty.
4649
4650 procedure Add_Predicates;
4651 -- Appends expressions for any Predicate pragmas in the rep item chain
4652 -- Typ to Expr. Note that we look only at items for this exact entity.
4653 -- Inheritance of predicates for the parent type is done by calling the
4654 -- Predicate_Function of the parent type, using Add_Call above.
4655
9dc88aea 4656 Object_Name : constant Name_Id := New_Internal_Name ('I');
4657 -- Name for argument of Predicate procedure
4658
fb7f2fc4 4659 Object_Entity : constant Entity_Id :=
4660 Make_Defining_Identifier (Loc, Object_Name);
4661 -- The entity for the spec entity for the argument
4662
ebbab42d 4663 Dynamic_Predicate_Present : Boolean := False;
4664 -- Set True if a dynamic predicate is present, results in the entire
4665 -- predicate being considered dynamic even if it looks static
4666
4667 Static_Predicate_Present : Node_Id := Empty;
4668 -- Set to N_Pragma node for a static predicate if one is encountered.
4669
9dc88aea 4670 --------------
4671 -- Add_Call --
4672 --------------
4673
4674 procedure Add_Call (T : Entity_Id) is
4675 Exp : Node_Id;
4676
4677 begin
4678 if Present (T) and then Present (Predicate_Function (T)) then
4679 Set_Has_Predicates (Typ);
4680
4681 -- Build the call to the predicate function of T
4682
4683 Exp :=
4684 Make_Predicate_Call
55868293 4685 (T, Convert_To (T, Make_Identifier (Loc, Object_Name)));
9dc88aea 4686
4687 -- Add call to evolving expression, using AND THEN if needed
4688
4689 if No (Expr) then
4690 Expr := Exp;
4691 else
4692 Expr :=
4693 Make_And_Then (Loc,
4694 Left_Opnd => Relocate_Node (Expr),
4695 Right_Opnd => Exp);
4696 end if;
4697
2f32076c 4698 -- Output info message on inheritance if required. Note we do not
4699 -- give this information for generic actual types, since it is
55e8372b 4700 -- unwelcome noise in that case in instantiations. We also
490beba6 4701 -- generally suppress the message in instantiations, and also
4702 -- if it involves internal names.
9dc88aea 4703
2f32076c 4704 if Opt.List_Inherited_Aspects
4705 and then not Is_Generic_Actual_Type (Typ)
55e8372b 4706 and then Instantiation_Depth (Sloc (Typ)) = 0
490beba6 4707 and then not Is_Internal_Name (Chars (T))
4708 and then not Is_Internal_Name (Chars (Typ))
2f32076c 4709 then
9dc88aea 4710 Error_Msg_Sloc := Sloc (Predicate_Function (T));
4711 Error_Msg_Node_2 := T;
4712 Error_Msg_N ("?info: & inherits predicate from & #", Typ);
4713 end if;
4714 end if;
4715 end Add_Call;
4716
4717 --------------------
4718 -- Add_Predicates --
4719 --------------------
4720
4721 procedure Add_Predicates is
4722 Ritem : Node_Id;
4723 Arg1 : Node_Id;
4724 Arg2 : Node_Id;
4725
2072eaa9 4726 procedure Replace_Type_Reference (N : Node_Id);
4727 -- Replace a single occurrence N of the subtype name with a reference
4728 -- to the formal of the predicate function. N can be an identifier
4729 -- referencing the subtype, or a selected component, representing an
4730 -- appropriately qualified occurrence of the subtype name.
9dc88aea 4731
2072eaa9 4732 procedure Replace_Type_References is
4733 new Replace_Type_References_Generic (Replace_Type_Reference);
490beba6 4734 -- Traverse an expression changing every occurrence of an identifier
6fb3c314 4735 -- whose name matches the name of the subtype with a reference to
2072eaa9 4736 -- the formal parameter of the predicate function.
9dc88aea 4737
2072eaa9 4738 ----------------------------
4739 -- Replace_Type_Reference --
4740 ----------------------------
490beba6 4741
2072eaa9 4742 procedure Replace_Type_Reference (N : Node_Id) is
9dc88aea 4743 begin
55868293 4744 Rewrite (N, Make_Identifier (Loc, Object_Name));
fb7f2fc4 4745 Set_Entity (N, Object_Entity);
4746 Set_Etype (N, Typ);
2072eaa9 4747 end Replace_Type_Reference;
9dc88aea 4748
4749 -- Start of processing for Add_Predicates
4750
4751 begin
4752 Ritem := First_Rep_Item (Typ);
4753 while Present (Ritem) loop
4754 if Nkind (Ritem) = N_Pragma
4755 and then Pragma_Name (Ritem) = Name_Predicate
4756 then
cce84b09 4757 if Present (Corresponding_Aspect (Ritem)) then
4758 case Chars (Identifier (Corresponding_Aspect (Ritem))) is
4759 when Name_Dynamic_Predicate =>
4760 Dynamic_Predicate_Present := True;
4761 when Name_Static_Predicate =>
4762 Static_Predicate_Present := Ritem;
4763 when others =>
4764 null;
4765 end case;
ebbab42d 4766 end if;
4767
fb7f2fc4 4768 -- Acquire arguments
4769
9dc88aea 4770 Arg1 := First (Pragma_Argument_Associations (Ritem));
4771 Arg2 := Next (Arg1);
4772
4773 Arg1 := Get_Pragma_Arg (Arg1);
4774 Arg2 := Get_Pragma_Arg (Arg2);
4775
ffc2539e 4776 -- See if this predicate pragma is for the current type or for
4777 -- its full view. A predicate on a private completion is placed
4778 -- on the partial view beause this is the visible entity that
4779 -- is frozen.
9dc88aea 4780
13dc58a7 4781 if Entity (Arg1) = Typ
4782 or else Full_View (Entity (Arg1)) = Typ
4783 then
9dc88aea 4784
4785 -- We have a match, this entry is for our subtype
4786
fb7f2fc4 4787 -- We need to replace any occurrences of the name of the
4788 -- type with references to the object.
490beba6 4789
2072eaa9 4790 Replace_Type_References (Arg2, Chars (Typ));
9dc88aea 4791
fb7f2fc4 4792 -- If this predicate comes from an aspect, find the aspect
4793 -- specification, and replace the saved expression because
4794 -- we need the subtype references replaced for the calls to
4795 -- Preanalyze_Spec_Expressin in Check_Aspect_At_Freeze_Point
4796 -- and Check_Aspect_At_End_Of_Declarations.
4797
4798 if From_Aspect_Specification (Ritem) then
4799 declare
4800 Aitem : Node_Id;
4801
4802 begin
4803 -- Loop to find corresponding aspect, note that this
4804 -- must be present given the pragma is marked delayed.
4805
4806 Aitem := Next_Rep_Item (Ritem);
4807 loop
4808 if Nkind (Aitem) = N_Aspect_Specification
4809 and then Aspect_Rep_Item (Aitem) = Ritem
4810 then
4811 Set_Entity
4812 (Identifier (Aitem), New_Copy_Tree (Arg2));
4813 exit;
4814 end if;
4815
4816 Aitem := Next_Rep_Item (Aitem);
4817 end loop;
4818 end;
4819 end if;
4820
4821 -- Now we can add the expression
9dc88aea 4822
4823 if No (Expr) then
4824 Expr := Relocate_Node (Arg2);
4825
4826 -- There already was a predicate, so add to it
4827
4828 else
4829 Expr :=
4830 Make_And_Then (Loc,
4831 Left_Opnd => Relocate_Node (Expr),
4832 Right_Opnd => Relocate_Node (Arg2));
4833 end if;
4834 end if;
4835 end if;
4836
4837 Next_Rep_Item (Ritem);
4838 end loop;
4839 end Add_Predicates;
4840
d97beb2f 4841 -- Start of processing for Build_Predicate_Function
9dc88aea 4842
d97beb2f 4843 begin
4844 -- Initialize for construction of statement list
4845
ebbab42d 4846 Expr := Empty;
d97beb2f 4847
4848 -- Return if already built or if type does not have predicates
4849
4850 if not Has_Predicates (Typ)
4851 or else Present (Predicate_Function (Typ))
4852 then
4853 return;
4854 end if;
4855
4856 -- Add Predicates for the current type
4857
4858 Add_Predicates;
4859
4860 -- Add predicates for ancestor if present
4861
4862 declare
4863 Atyp : constant Entity_Id := Nearest_Ancestor (Typ);
4864 begin
4865 if Present (Atyp) then
4866 Add_Call (Atyp);
4867 end if;
4868 end;
4869
4870 -- If we have predicates, build the function
4871
4872 if Present (Expr) then
4873
d97beb2f 4874 -- Build function declaration
4875
4876 pragma Assert (Has_Predicates (Typ));
4877 SId :=
4878 Make_Defining_Identifier (Loc,
4879 Chars => New_External_Name (Chars (Typ), "Predicate"));
4880 Set_Has_Predicates (SId);
4881 Set_Predicate_Function (Typ, SId);
9dc88aea 4882
d97beb2f 4883 Spec :=
4884 Make_Function_Specification (Loc,
4885 Defining_Unit_Name => SId,
4886 Parameter_Specifications => New_List (
4887 Make_Parameter_Specification (Loc,
fb7f2fc4 4888 Defining_Identifier => Object_Entity,
d97beb2f 4889 Parameter_Type => New_Occurrence_Of (Typ, Loc))),
4890 Result_Definition =>
4891 New_Occurrence_Of (Standard_Boolean, Loc));
9dc88aea 4892
490beba6 4893 FDecl := Make_Subprogram_Declaration (Loc, Specification => Spec);
9dc88aea 4894
d97beb2f 4895 -- Build function body
4896
4897 SId :=
4898 Make_Defining_Identifier (Loc,
4899 Chars => New_External_Name (Chars (Typ), "Predicate"));
4900
4901 Spec :=
4902 Make_Function_Specification (Loc,
4903 Defining_Unit_Name => SId,
4904 Parameter_Specifications => New_List (
4905 Make_Parameter_Specification (Loc,
4906 Defining_Identifier =>
55868293 4907 Make_Defining_Identifier (Loc, Object_Name),
d97beb2f 4908 Parameter_Type =>
4909 New_Occurrence_Of (Typ, Loc))),
4910 Result_Definition =>
4911 New_Occurrence_Of (Standard_Boolean, Loc));
4912
4913 FBody :=
4914 Make_Subprogram_Body (Loc,
4915 Specification => Spec,
4916 Declarations => Empty_List,
4917 Handled_Statement_Sequence =>
4918 Make_Handled_Sequence_Of_Statements (Loc,
4919 Statements => New_List (
4920 Make_Simple_Return_Statement (Loc,
4921 Expression => Expr))));
490beba6 4922
4923 -- Insert declaration before freeze node and body after
4924
4925 Insert_Before_And_Analyze (N, FDecl);
4926 Insert_After_And_Analyze (N, FBody);
4927
4928 -- Deal with static predicate case
4929
4930 if Ekind_In (Typ, E_Enumeration_Subtype,
4931 E_Modular_Integer_Subtype,
4932 E_Signed_Integer_Subtype)
4933 and then Is_Static_Subtype (Typ)
ebbab42d 4934 and then not Dynamic_Predicate_Present
490beba6 4935 then
4936 Build_Static_Predicate (Typ, Expr, Object_Name);
ebbab42d 4937
4938 if Present (Static_Predicate_Present)
4939 and No (Static_Predicate (Typ))
4940 then
4941 Error_Msg_F
4942 ("expression does not have required form for "
4943 & "static predicate",
4944 Next (First (Pragma_Argument_Associations
4945 (Static_Predicate_Present))));
4946 end if;
490beba6 4947 end if;
d97beb2f 4948 end if;
4949 end Build_Predicate_Function;
4950
4951 ----------------------------
4952 -- Build_Static_Predicate --
4953 ----------------------------
4954
4955 procedure Build_Static_Predicate
4956 (Typ : Entity_Id;
4957 Expr : Node_Id;
4958 Nam : Name_Id)
4959 is
4960 Loc : constant Source_Ptr := Sloc (Expr);
4961
4962 Non_Static : exception;
4963 -- Raised if something non-static is found
4964
d7c2851f 4965 Btyp : constant Entity_Id := Base_Type (Typ);
4966
4967 BLo : constant Uint := Expr_Value (Type_Low_Bound (Btyp));
4968 BHi : constant Uint := Expr_Value (Type_High_Bound (Btyp));
4969 -- Low bound and high bound value of base type of Typ
4970
4971 TLo : constant Uint := Expr_Value (Type_Low_Bound (Typ));
4972 THi : constant Uint := Expr_Value (Type_High_Bound (Typ));
4973 -- Low bound and high bound values of static subtype Typ
d97beb2f 4974
4975 type REnt is record
9dc88aea 4976 Lo, Hi : Uint;
d97beb2f 4977 end record;
4978 -- One entry in a Rlist value, a single REnt (range entry) value
4979 -- denotes one range from Lo to Hi. To represent a single value
4980 -- range Lo = Hi = value.
4981
4982 type RList is array (Nat range <>) of REnt;
4983 -- A list of ranges. The ranges are sorted in increasing order,
4984 -- and are disjoint (there is a gap of at least one value between
d7c2851f 4985 -- each range in the table). A value is in the set of ranges in
4986 -- Rlist if it lies within one of these ranges
d97beb2f 4987
d7c2851f 4988 False_Range : constant RList :=
4989 RList'(1 .. 0 => REnt'(No_Uint, No_Uint));
4990 -- An empty set of ranges represents a range list that can never be
4991 -- satisfied, since there are no ranges in which the value could lie,
4992 -- so it does not lie in any of them. False_Range is a canonical value
4993 -- for this empty set, but general processing should test for an Rlist
4994 -- with length zero (see Is_False predicate), since other null ranges
4995 -- may appear which must be treated as False.
d97beb2f 4996
d7c2851f 4997 True_Range : constant RList := RList'(1 => REnt'(BLo, BHi));
4998 -- Range representing True, value must be in the base range
d97beb2f 4999
5000 function "and" (Left, Right : RList) return RList;
5001 -- And's together two range lists, returning a range list. This is
5002 -- a set intersection operation.
5003
5004 function "or" (Left, Right : RList) return RList;
5005 -- Or's together two range lists, returning a range list. This is a
5006 -- set union operation.
5007
5008 function "not" (Right : RList) return RList;
5009 -- Returns complement of a given range list, i.e. a range list
5010 -- representing all the values in TLo .. THi that are not in the
5011 -- input operand Right.
5012
5013 function Build_Val (V : Uint) return Node_Id;
5014 -- Return an analyzed N_Identifier node referencing this value, suitable
d7c2851f 5015 -- for use as an entry in the Static_Predicate list. This node is typed
5016 -- with the base type.
d97beb2f 5017
5018 function Build_Range (Lo, Hi : Uint) return Node_Id;
5019 -- Return an analyzed N_Range node referencing this range, suitable
d7c2851f 5020 -- for use as an entry in the Static_Predicate list. This node is typed
5021 -- with the base type.
d97beb2f 5022
5023 function Get_RList (Exp : Node_Id) return RList;
5024 -- This is a recursive routine that converts the given expression into
5025 -- a list of ranges, suitable for use in building the static predicate.
5026
d7c2851f 5027 function Is_False (R : RList) return Boolean;
5028 pragma Inline (Is_False);
5029 -- Returns True if the given range list is empty, and thus represents
6fb3c314 5030 -- a False list of ranges that can never be satisfied.
d7c2851f 5031
5032 function Is_True (R : RList) return Boolean;
5033 -- Returns True if R trivially represents the True predicate by having
5034 -- a single range from BLo to BHi.
5035
d97beb2f 5036 function Is_Type_Ref (N : Node_Id) return Boolean;
5037 pragma Inline (Is_Type_Ref);
5038 -- Returns if True if N is a reference to the type for the predicate in
5039 -- the expression (i.e. if it is an identifier whose Chars field matches
5040 -- the Nam given in the call).
5041
5042 function Lo_Val (N : Node_Id) return Uint;
5043 -- Given static expression or static range from a Static_Predicate list,
5044 -- gets expression value or low bound of range.
5045
5046 function Hi_Val (N : Node_Id) return Uint;
5047 -- Given static expression or static range from a Static_Predicate list,
5048 -- gets expression value of high bound of range.
5049
5050 function Membership_Entry (N : Node_Id) return RList;
5051 -- Given a single membership entry (range, value, or subtype), returns
5052 -- the corresponding range list. Raises Static_Error if not static.
5053
5054 function Membership_Entries (N : Node_Id) return RList;
5055 -- Given an element on an alternatives list of a membership operation,
5056 -- returns the range list corresponding to this entry and all following
5057 -- entries (i.e. returns the "or" of this list of values).
5058
5059 function Stat_Pred (Typ : Entity_Id) return RList;
5060 -- Given a type, if it has a static predicate, then return the predicate
5061 -- as a range list, otherwise raise Non_Static.
5062
5063 -----------
5064 -- "and" --
5065 -----------
5066
5067 function "and" (Left, Right : RList) return RList is
5068 FEnt : REnt;
5069 -- First range of result
5070
5071 SLeft : Nat := Left'First;
5072 -- Start of rest of left entries
5073
5074 SRight : Nat := Right'First;
5075 -- Start of rest of right entries
9dc88aea 5076
d97beb2f 5077 begin
5078 -- If either range is True, return the other
9dc88aea 5079
d7c2851f 5080 if Is_True (Left) then
d97beb2f 5081 return Right;
d7c2851f 5082 elsif Is_True (Right) then
d97beb2f 5083 return Left;
5084 end if;
9dc88aea 5085
d97beb2f 5086 -- If either range is False, return False
9dc88aea 5087
d7c2851f 5088 if Is_False (Left) or else Is_False (Right) then
d97beb2f 5089 return False_Range;
5090 end if;
9dc88aea 5091
d97beb2f 5092 -- Loop to remove entries at start that are disjoint, and thus
5093 -- just get discarded from the result entirely.
9dc88aea 5094
d97beb2f 5095 loop
5096 -- If no operands left in either operand, result is false
9dc88aea 5097
d97beb2f 5098 if SLeft > Left'Last or else SRight > Right'Last then
5099 return False_Range;
9dc88aea 5100
d97beb2f 5101 -- Discard first left operand entry if disjoint with right
9dc88aea 5102
d97beb2f 5103 elsif Left (SLeft).Hi < Right (SRight).Lo then
5104 SLeft := SLeft + 1;
9dc88aea 5105
d97beb2f 5106 -- Discard first right operand entry if disjoint with left
9dc88aea 5107
d97beb2f 5108 elsif Right (SRight).Hi < Left (SLeft).Lo then
5109 SRight := SRight + 1;
9dc88aea 5110
d97beb2f 5111 -- Otherwise we have an overlapping entry
9dc88aea 5112
d97beb2f 5113 else
5114 exit;
5115 end if;
5116 end loop;
9dc88aea 5117
d97beb2f 5118 -- Now we have two non-null operands, and first entries overlap.
5119 -- The first entry in the result will be the overlapping part of
5120 -- these two entries.
9dc88aea 5121
d97beb2f 5122 FEnt := REnt'(Lo => UI_Max (Left (SLeft).Lo, Right (SRight).Lo),
5123 Hi => UI_Min (Left (SLeft).Hi, Right (SRight).Hi));
9dc88aea 5124
d97beb2f 5125 -- Now we can remove the entry that ended at a lower value, since
5126 -- its contribution is entirely contained in Fent.
5127
5128 if Left (SLeft).Hi <= Right (SRight).Hi then
5129 SLeft := SLeft + 1;
5130 else
5131 SRight := SRight + 1;
5132 end if;
5133
d7c2851f 5134 -- Compute result by concatenating this first entry with the "and"
5135 -- of the remaining parts of the left and right operands. Note that
5136 -- if either of these is empty, "and" will yield empty, so that we
5137 -- will end up with just Fent, which is what we want in that case.
d97beb2f 5138
d7c2851f 5139 return
5140 FEnt & (Left (SLeft .. Left'Last) and Right (SRight .. Right'Last));
d97beb2f 5141 end "and";
5142
5143 -----------
5144 -- "not" --
5145 -----------
5146
5147 function "not" (Right : RList) return RList is
5148 begin
5149 -- Return True if False range
5150
d7c2851f 5151 if Is_False (Right) then
d97beb2f 5152 return True_Range;
5153 end if;
5154
5155 -- Return False if True range
5156
d7c2851f 5157 if Is_True (Right) then
d97beb2f 5158 return False_Range;
5159 end if;
5160
5161 -- Here if not trivial case
5162
5163 declare
5164 Result : RList (1 .. Right'Length + 1);
5165 -- May need one more entry for gap at beginning and end
5166
5167 Count : Nat := 0;
5168 -- Number of entries stored in Result
5169
5170 begin
5171 -- Gap at start
5172
5173 if Right (Right'First).Lo > TLo then
5174 Count := Count + 1;
5175 Result (Count) := REnt'(TLo, Right (Right'First).Lo - 1);
5176 end if;
5177
5178 -- Gaps between ranges
5179
5180 for J in Right'First .. Right'Last - 1 loop
5181 Count := Count + 1;
5182 Result (Count) :=
5183 REnt'(Right (J).Hi + 1, Right (J + 1).Lo - 1);
5184 end loop;
5185
5186 -- Gap at end
5187
5188 if Right (Right'Last).Hi < THi then
5189 Count := Count + 1;
5190 Result (Count) := REnt'(Right (Right'Last).Hi + 1, THi);
5191 end if;
5192
5193 return Result (1 .. Count);
5194 end;
5195 end "not";
5196
5197 ----------
5198 -- "or" --
5199 ----------
5200
5201 function "or" (Left, Right : RList) return RList is
d7c2851f 5202 FEnt : REnt;
5203 -- First range of result
5204
5205 SLeft : Nat := Left'First;
5206 -- Start of rest of left entries
5207
5208 SRight : Nat := Right'First;
5209 -- Start of rest of right entries
5210
d97beb2f 5211 begin
5212 -- If either range is True, return True
5213
d7c2851f 5214 if Is_True (Left) or else Is_True (Right) then
d97beb2f 5215 return True_Range;
5216 end if;
5217
d7c2851f 5218 -- If either range is False (empty), return the other
9dc88aea 5219
d7c2851f 5220 if Is_False (Left) then
d97beb2f 5221 return Right;
d7c2851f 5222 elsif Is_False (Right) then
d97beb2f 5223 return Left;
5224 end if;
5225
d7c2851f 5226 -- Initialize result first entry from left or right operand
5227 -- depending on which starts with the lower range.
d97beb2f 5228
d7c2851f 5229 if Left (SLeft).Lo < Right (SRight).Lo then
5230 FEnt := Left (SLeft);
5231 SLeft := SLeft + 1;
5232 else
5233 FEnt := Right (SRight);
5234 SRight := SRight + 1;
d97beb2f 5235 end if;
5236
d7c2851f 5237 -- This loop eats ranges from left and right operands that
5238 -- are contiguous with the first range we are gathering.
9dc88aea 5239
d7c2851f 5240 loop
5241 -- Eat first entry in left operand if contiguous or
5242 -- overlapped by gathered first operand of result.
d97beb2f 5243
d7c2851f 5244 if SLeft <= Left'Last
5245 and then Left (SLeft).Lo <= FEnt.Hi + 1
5246 then
5247 FEnt.Hi := UI_Max (FEnt.Hi, Left (SLeft).Hi);
d97beb2f 5248 SLeft := SLeft + 1;
d97beb2f 5249
5250 -- Eat first entry in right operand if contiguous or
5251 -- overlapped by gathered right operand of result.
5252
d7c2851f 5253 elsif SRight <= Right'Last
5254 and then Right (SRight).Lo <= FEnt.Hi + 1
5255 then
5256 FEnt.Hi := UI_Max (FEnt.Hi, Right (SRight).Hi);
5257 SRight := SRight + 1;
d97beb2f 5258
5259 -- All done if no more entries to eat!
5260
d97beb2f 5261 else
d7c2851f 5262 exit;
d97beb2f 5263 end if;
d7c2851f 5264 end loop;
5265
5266 -- Obtain result as the first entry we just computed, concatenated
5267 -- to the "or" of the remaining results (if one operand is empty,
5268 -- this will just concatenate with the other
5269
5270 return
5271 FEnt & (Left (SLeft .. Left'Last) or Right (SRight .. Right'Last));
d97beb2f 5272 end "or";
9dc88aea 5273
d97beb2f 5274 -----------------
5275 -- Build_Range --
5276 -----------------
9dc88aea 5277
d97beb2f 5278 function Build_Range (Lo, Hi : Uint) return Node_Id is
5279 Result : Node_Id;
5280 begin
5281 if Lo = Hi then
5282 return Build_Val (Hi);
5283 else
5284 Result :=
5285 Make_Range (Loc,
5286 Low_Bound => Build_Val (Lo),
5287 High_Bound => Build_Val (Hi));
d7c2851f 5288 Set_Etype (Result, Btyp);
d97beb2f 5289 Set_Analyzed (Result);
5290 return Result;
5291 end if;
5292 end Build_Range;
9dc88aea 5293
d97beb2f 5294 ---------------
5295 -- Build_Val --
5296 ---------------
9dc88aea 5297
d97beb2f 5298 function Build_Val (V : Uint) return Node_Id is
5299 Result : Node_Id;
5300
5301 begin
5302 if Is_Enumeration_Type (Typ) then
5303 Result := Get_Enum_Lit_From_Pos (Typ, V, Loc);
5304 else
55868293 5305 Result := Make_Integer_Literal (Loc, V);
d97beb2f 5306 end if;
9dc88aea 5307
d7c2851f 5308 Set_Etype (Result, Btyp);
d97beb2f 5309 Set_Is_Static_Expression (Result);
5310 Set_Analyzed (Result);
5311 return Result;
5312 end Build_Val;
9dc88aea 5313
d97beb2f 5314 ---------------
5315 -- Get_RList --
5316 ---------------
9dc88aea 5317
d97beb2f 5318 function Get_RList (Exp : Node_Id) return RList is
5319 Op : Node_Kind;
5320 Val : Uint;
9dc88aea 5321
d97beb2f 5322 begin
5323 -- Static expression can only be true or false
5324
5325 if Is_OK_Static_Expression (Exp) then
5326
d7c2851f 5327 -- For False
d97beb2f 5328
5329 if Expr_Value (Exp) = 0 then
5330 return False_Range;
d97beb2f 5331 else
d7c2851f 5332 return True_Range;
d97beb2f 5333 end if;
5334 end if;
5335
5336 -- Otherwise test node type
5337
5338 Op := Nkind (Exp);
5339
5340 case Op is
5341
5342 -- And
5343
5344 when N_Op_And | N_And_Then =>
5345 return Get_RList (Left_Opnd (Exp))
5346 and
5347 Get_RList (Right_Opnd (Exp));
9dc88aea 5348
d97beb2f 5349 -- Or
5350
5351 when N_Op_Or | N_Or_Else =>
5352 return Get_RList (Left_Opnd (Exp))
5353 or
5354 Get_RList (Right_Opnd (Exp));
5355
5356 -- Not
5357
5358 when N_Op_Not =>
5359 return not Get_RList (Right_Opnd (Exp));
5360
5361 -- Comparisons of type with static value
5362
5363 when N_Op_Compare =>
5364 -- Type is left operand
5365
5366 if Is_Type_Ref (Left_Opnd (Exp))
5367 and then Is_OK_Static_Expression (Right_Opnd (Exp))
5368 then
5369 Val := Expr_Value (Right_Opnd (Exp));
5370
5371 -- Typ is right operand
5372
5373 elsif Is_Type_Ref (Right_Opnd (Exp))
5374 and then Is_OK_Static_Expression (Left_Opnd (Exp))
5375 then
5376 Val := Expr_Value (Left_Opnd (Exp));
5377
5378 -- Invert sense of comparison
5379
5380 case Op is
5381 when N_Op_Gt => Op := N_Op_Lt;
5382 when N_Op_Lt => Op := N_Op_Gt;
5383 when N_Op_Ge => Op := N_Op_Le;
5384 when N_Op_Le => Op := N_Op_Ge;
5385 when others => null;
5386 end case;
5387
5388 -- Other cases are non-static
9dc88aea 5389
5390 else
d97beb2f 5391 raise Non_Static;
9dc88aea 5392 end if;
9dc88aea 5393
d97beb2f 5394 -- Construct range according to comparison operation
9dc88aea 5395
d97beb2f 5396 case Op is
5397 when N_Op_Eq =>
5398 return RList'(1 => REnt'(Val, Val));
9dc88aea 5399
d97beb2f 5400 when N_Op_Ge =>
d7c2851f 5401 return RList'(1 => REnt'(Val, BHi));
9dc88aea 5402
d97beb2f 5403 when N_Op_Gt =>
d7c2851f 5404 return RList'(1 => REnt'(Val + 1, BHi));
9dc88aea 5405
d97beb2f 5406 when N_Op_Le =>
d7c2851f 5407 return RList'(1 => REnt'(BLo, Val));
9dc88aea 5408
d97beb2f 5409 when N_Op_Lt =>
d7c2851f 5410 return RList'(1 => REnt'(BLo, Val - 1));
9dc88aea 5411
d97beb2f 5412 when N_Op_Ne =>
d7c2851f 5413 return RList'(REnt'(BLo, Val - 1),
5414 REnt'(Val + 1, BHi));
9dc88aea 5415
d97beb2f 5416 when others =>
5417 raise Program_Error;
5418 end case;
9dc88aea 5419
d97beb2f 5420 -- Membership (IN)
9dc88aea 5421
d97beb2f 5422 when N_In =>
5423 if not Is_Type_Ref (Left_Opnd (Exp)) then
5424 raise Non_Static;
5425 end if;
9dc88aea 5426
d97beb2f 5427 if Present (Right_Opnd (Exp)) then
5428 return Membership_Entry (Right_Opnd (Exp));
5429 else
5430 return Membership_Entries (First (Alternatives (Exp)));
5431 end if;
9dc88aea 5432
d97beb2f 5433 -- Negative membership (NOT IN)
9dc88aea 5434
d97beb2f 5435 when N_Not_In =>
5436 if not Is_Type_Ref (Left_Opnd (Exp)) then
5437 raise Non_Static;
5438 end if;
5439
5440 if Present (Right_Opnd (Exp)) then
5441 return not Membership_Entry (Right_Opnd (Exp));
5442 else
5443 return not Membership_Entries (First (Alternatives (Exp)));
5444 end if;
5445
5446 -- Function call, may be call to static predicate
5447
5448 when N_Function_Call =>
5449 if Is_Entity_Name (Name (Exp)) then
5450 declare
5451 Ent : constant Entity_Id := Entity (Name (Exp));
5452 begin
5453 if Has_Predicates (Ent) then
5454 return Stat_Pred (Etype (First_Formal (Ent)));
9dc88aea 5455 end if;
d97beb2f 5456 end;
5457 end if;
9dc88aea 5458
d97beb2f 5459 -- Other function call cases are non-static
9dc88aea 5460
d97beb2f 5461 raise Non_Static;
9dc88aea 5462
d97beb2f 5463 -- Qualified expression, dig out the expression
9dc88aea 5464
d97beb2f 5465 when N_Qualified_Expression =>
5466 return Get_RList (Expression (Exp));
9dc88aea 5467
d7c2851f 5468 -- Xor operator
5469
5470 when N_Op_Xor =>
5471 return (Get_RList (Left_Opnd (Exp))
5472 and not Get_RList (Right_Opnd (Exp)))
5473 or (Get_RList (Right_Opnd (Exp))
5474 and not Get_RList (Left_Opnd (Exp)));
5475
d97beb2f 5476 -- Any other node type is non-static
9dc88aea 5477
d97beb2f 5478 when others =>
5479 raise Non_Static;
5480 end case;
5481 end Get_RList;
9dc88aea 5482
d97beb2f 5483 ------------
5484 -- Hi_Val --
5485 ------------
9dc88aea 5486
d97beb2f 5487 function Hi_Val (N : Node_Id) return Uint is
9dc88aea 5488 begin
d97beb2f 5489 if Is_Static_Expression (N) then
5490 return Expr_Value (N);
5491 else
5492 pragma Assert (Nkind (N) = N_Range);
5493 return Expr_Value (High_Bound (N));
9dc88aea 5494 end if;
d97beb2f 5495 end Hi_Val;
9dc88aea 5496
d7c2851f 5497 --------------
5498 -- Is_False --
5499 --------------
5500
5501 function Is_False (R : RList) return Boolean is
5502 begin
5503 return R'Length = 0;
5504 end Is_False;
5505
5506 -------------
5507 -- Is_True --
5508 -------------
5509
5510 function Is_True (R : RList) return Boolean is
5511 begin
5512 return R'Length = 1
5513 and then R (R'First).Lo = BLo
5514 and then R (R'First).Hi = BHi;
5515 end Is_True;
5516
d97beb2f 5517 -----------------
5518 -- Is_Type_Ref --
5519 -----------------
9dc88aea 5520
d97beb2f 5521 function Is_Type_Ref (N : Node_Id) return Boolean is
5522 begin
5523 return Nkind (N) = N_Identifier and then Chars (N) = Nam;
5524 end Is_Type_Ref;
9dc88aea 5525
d97beb2f 5526 ------------
5527 -- Lo_Val --
5528 ------------
9dc88aea 5529
d97beb2f 5530 function Lo_Val (N : Node_Id) return Uint is
5531 begin
5532 if Is_Static_Expression (N) then
5533 return Expr_Value (N);
5534 else
5535 pragma Assert (Nkind (N) = N_Range);
5536 return Expr_Value (Low_Bound (N));
5537 end if;
5538 end Lo_Val;
9dc88aea 5539
d97beb2f 5540 ------------------------
5541 -- Membership_Entries --
5542 ------------------------
9dc88aea 5543
d97beb2f 5544 function Membership_Entries (N : Node_Id) return RList is
5545 begin
5546 if No (Next (N)) then
5547 return Membership_Entry (N);
9dc88aea 5548 else
d97beb2f 5549 return Membership_Entry (N) or Membership_Entries (Next (N));
9dc88aea 5550 end if;
d97beb2f 5551 end Membership_Entries;
9dc88aea 5552
d97beb2f 5553 ----------------------
5554 -- Membership_Entry --
5555 ----------------------
9dc88aea 5556
d97beb2f 5557 function Membership_Entry (N : Node_Id) return RList is
5558 Val : Uint;
5559 SLo : Uint;
5560 SHi : Uint;
9dc88aea 5561
d97beb2f 5562 begin
5563 -- Range case
5564
5565 if Nkind (N) = N_Range then
5566 if not Is_Static_Expression (Low_Bound (N))
5567 or else
5568 not Is_Static_Expression (High_Bound (N))
5569 then
5570 raise Non_Static;
5571 else
5572 SLo := Expr_Value (Low_Bound (N));
5573 SHi := Expr_Value (High_Bound (N));
5574 return RList'(1 => REnt'(SLo, SHi));
9dc88aea 5575 end if;
5576
d97beb2f 5577 -- Static expression case
9dc88aea 5578
d97beb2f 5579 elsif Is_Static_Expression (N) then
5580 Val := Expr_Value (N);
5581 return RList'(1 => REnt'(Val, Val));
9dc88aea 5582
d97beb2f 5583 -- Identifier (other than static expression) case
9dc88aea 5584
d97beb2f 5585 else pragma Assert (Nkind (N) = N_Identifier);
9dc88aea 5586
d97beb2f 5587 -- Type case
55e8372b 5588
d97beb2f 5589 if Is_Type (Entity (N)) then
55e8372b 5590
d97beb2f 5591 -- If type has predicates, process them
55e8372b 5592
d97beb2f 5593 if Has_Predicates (Entity (N)) then
5594 return Stat_Pred (Entity (N));
55e8372b 5595
d97beb2f 5596 -- For static subtype without predicates, get range
55e8372b 5597
d97beb2f 5598 elsif Is_Static_Subtype (Entity (N)) then
5599 SLo := Expr_Value (Type_Low_Bound (Entity (N)));
5600 SHi := Expr_Value (Type_High_Bound (Entity (N)));
5601 return RList'(1 => REnt'(SLo, SHi));
5602
5603 -- Any other type makes us non-static
55e8372b 5604
d97beb2f 5605 else
5606 raise Non_Static;
5607 end if;
55e8372b 5608
d97beb2f 5609 -- Any other kind of identifier in predicate (e.g. a non-static
5610 -- expression value) means this is not a static predicate.
55e8372b 5611
55e8372b 5612 else
d97beb2f 5613 raise Non_Static;
55e8372b 5614 end if;
d97beb2f 5615 end if;
5616 end Membership_Entry;
9dc88aea 5617
d97beb2f 5618 ---------------
5619 -- Stat_Pred --
5620 ---------------
9dc88aea 5621
d97beb2f 5622 function Stat_Pred (Typ : Entity_Id) return RList is
5623 begin
5624 -- Not static if type does not have static predicates
9dc88aea 5625
d97beb2f 5626 if not Has_Predicates (Typ)
5627 or else No (Static_Predicate (Typ))
5628 then
5629 raise Non_Static;
5630 end if;
9dc88aea 5631
d97beb2f 5632 -- Otherwise we convert the predicate list to a range list
9dc88aea 5633
d97beb2f 5634 declare
5635 Result : RList (1 .. List_Length (Static_Predicate (Typ)));
5636 P : Node_Id;
5637
5638 begin
5639 P := First (Static_Predicate (Typ));
5640 for J in Result'Range loop
5641 Result (J) := REnt'(Lo_Val (P), Hi_Val (P));
5642 Next (P);
5643 end loop;
5644
5645 return Result;
5646 end;
5647 end Stat_Pred;
5648
5649 -- Start of processing for Build_Static_Predicate
5650
5651 begin
d97beb2f 5652 -- Now analyze the expression to see if it is a static predicate
9dc88aea 5653
5654 declare
d97beb2f 5655 Ranges : constant RList := Get_RList (Expr);
5656 -- Range list from expression if it is static
5657
5658 Plist : List_Id;
5659
9dc88aea 5660 begin
d97beb2f 5661 -- Convert range list into a form for the static predicate. In the
5662 -- Ranges array, we just have raw ranges, these must be converted
5663 -- to properly typed and analyzed static expressions or range nodes.
9dc88aea 5664
d7c2851f 5665 -- Note: here we limit ranges to the ranges of the subtype, so that
5666 -- a predicate is always false for values outside the subtype. That
5667 -- seems fine, such values are invalid anyway, and considering them
5668 -- to fail the predicate seems allowed and friendly, and furthermore
5669 -- simplifies processing for case statements and loops.
5670
d97beb2f 5671 Plist := New_List;
9dc88aea 5672
d97beb2f 5673 for J in Ranges'Range loop
5674 declare
d7c2851f 5675 Lo : Uint := Ranges (J).Lo;
5676 Hi : Uint := Ranges (J).Hi;
9dc88aea 5677
d97beb2f 5678 begin
d7c2851f 5679 -- Ignore completely out of range entry
5680
5681 if Hi < TLo or else Lo > THi then
5682 null;
5683
5684 -- Otherwise process entry
5685
d97beb2f 5686 else
d7c2851f 5687 -- Adjust out of range value to subtype range
5688
5689 if Lo < TLo then
5690 Lo := TLo;
5691 end if;
5692
5693 if Hi > THi then
5694 Hi := THi;
5695 end if;
5696
5697 -- Convert range into required form
5698
5699 if Lo = Hi then
5700 Append_To (Plist, Build_Val (Lo));
5701 else
5702 Append_To (Plist, Build_Range (Lo, Hi));
5703 end if;
d97beb2f 5704 end if;
5705 end;
5706 end loop;
9dc88aea 5707
d97beb2f 5708 -- Processing was successful and all entries were static, so now we
5709 -- can store the result as the predicate list.
9dc88aea 5710
d97beb2f 5711 Set_Static_Predicate (Typ, Plist);
9dc88aea 5712
d97beb2f 5713 -- The processing for static predicates put the expression into
5714 -- canonical form as a series of ranges. It also eliminated
5715 -- duplicates and collapsed and combined ranges. We might as well
5716 -- replace the alternatives list of the right operand of the
5717 -- membership test with the static predicate list, which will
5718 -- usually be more efficient.
9dc88aea 5719
d97beb2f 5720 declare
5721 New_Alts : constant List_Id := New_List;
5722 Old_Node : Node_Id;
5723 New_Node : Node_Id;
9dc88aea 5724
d97beb2f 5725 begin
5726 Old_Node := First (Plist);
5727 while Present (Old_Node) loop
5728 New_Node := New_Copy (Old_Node);
9dc88aea 5729
d97beb2f 5730 if Nkind (New_Node) = N_Range then
5731 Set_Low_Bound (New_Node, New_Copy (Low_Bound (Old_Node)));
5732 Set_High_Bound (New_Node, New_Copy (High_Bound (Old_Node)));
5733 end if;
9dc88aea 5734
d97beb2f 5735 Append_To (New_Alts, New_Node);
5736 Next (Old_Node);
5737 end loop;
9dc88aea 5738
d7c2851f 5739 -- If empty list, replace by False
9dc88aea 5740
d97beb2f 5741 if Is_Empty_List (New_Alts) then
d7c2851f 5742 Rewrite (Expr, New_Occurrence_Of (Standard_False, Loc));
d97beb2f 5743
d7c2851f 5744 -- Else replace by set membership test
d97beb2f 5745
5746 else
5747 Rewrite (Expr,
5748 Make_In (Loc,
5749 Left_Opnd => Make_Identifier (Loc, Nam),
5750 Right_Opnd => Empty,
5751 Alternatives => New_Alts));
490beba6 5752
5753 -- Resolve new expression in function context
5754
5755 Install_Formals (Predicate_Function (Typ));
5756 Push_Scope (Predicate_Function (Typ));
5757 Analyze_And_Resolve (Expr, Standard_Boolean);
5758 Pop_Scope;
d97beb2f 5759 end if;
5760 end;
5761 end;
5762
5763 -- If non-static, return doing nothing
5764
5765 exception
5766 when Non_Static =>
5767 return;
5768 end Build_Static_Predicate;
9dc88aea 5769
7d20685d 5770 -----------------------------------------
5771 -- Check_Aspect_At_End_Of_Declarations --
5772 -----------------------------------------
5773
5774 procedure Check_Aspect_At_End_Of_Declarations (ASN : Node_Id) is
5775 Ent : constant Entity_Id := Entity (ASN);
5776 Ident : constant Node_Id := Identifier (ASN);
5777
5778 Freeze_Expr : constant Node_Id := Expression (ASN);
89cc7147 5779 -- Expression from call to Check_Aspect_At_Freeze_Point
7d20685d 5780
5781 End_Decl_Expr : constant Node_Id := Entity (Ident);
5782 -- Expression to be analyzed at end of declarations
5783
5784 T : constant Entity_Id := Etype (Freeze_Expr);
5785 -- Type required for preanalyze call
5786
5787 A_Id : constant Aspect_Id := Get_Aspect_Id (Chars (Ident));
5788
5789 Err : Boolean;
5790 -- Set False if error
5791
5792 -- On entry to this procedure, Entity (Ident) contains a copy of the
5793 -- original expression from the aspect, saved for this purpose, and
5794 -- but Expression (Ident) is a preanalyzed copy of the expression,
5795 -- preanalyzed just after the freeze point.
5796
5797 begin
5798 -- Case of stream attributes, just have to compare entities
5799
5800 if A_Id = Aspect_Input or else
5801 A_Id = Aspect_Output or else
5802 A_Id = Aspect_Read or else
5803 A_Id = Aspect_Write
5804 then
5805 Analyze (End_Decl_Expr);
5806 Err := Entity (End_Decl_Expr) /= Entity (Freeze_Expr);
5807
81b424ac 5808 elsif A_Id = Aspect_Variable_Indexing or else
89cc7147 5809 A_Id = Aspect_Constant_Indexing or else
5810 A_Id = Aspect_Default_Iterator or else
5811 A_Id = Aspect_Iterator_Element
81b424ac 5812 then
aabafdc2 5813 -- Make type unfrozen before analysis, to prevent spurious errors
5814 -- about late attributes.
59f3e675 5815
5816 Set_Is_Frozen (Ent, False);
81b424ac 5817 Analyze (End_Decl_Expr);
5818 Analyze (Aspect_Rep_Item (ASN));
59f3e675 5819 Set_Is_Frozen (Ent, True);
89cc7147 5820
5821 -- If the end of declarations comes before any other freeze
5822 -- point, the Freeze_Expr is not analyzed: no check needed.
5823
5824 Err :=
5825 Analyzed (Freeze_Expr)
5826 and then not In_Instance
5827 and then Entity (End_Decl_Expr) /= Entity (Freeze_Expr);
81b424ac 5828
7d20685d 5829 -- All other cases
5830
5831 else
5832 Preanalyze_Spec_Expression (End_Decl_Expr, T);
5833 Err := not Fully_Conformant_Expressions (End_Decl_Expr, Freeze_Expr);
5834 end if;
5835
5836 -- Output error message if error
5837
5838 if Err then
5839 Error_Msg_NE
5840 ("visibility of aspect for& changes after freeze point",
5841 ASN, Ent);
5842 Error_Msg_NE
5843 ("?info: & is frozen here, aspects evaluated at this point",
5844 Freeze_Node (Ent), Ent);
5845 end if;
5846 end Check_Aspect_At_End_Of_Declarations;
5847
5848 ----------------------------------
5849 -- Check_Aspect_At_Freeze_Point --
5850 ----------------------------------
5851
5852 procedure Check_Aspect_At_Freeze_Point (ASN : Node_Id) is
5853 Ident : constant Node_Id := Identifier (ASN);
5854 -- Identifier (use Entity field to save expression)
5855
5856 T : Entity_Id;
5857 -- Type required for preanalyze call
5858
5859 A_Id : constant Aspect_Id := Get_Aspect_Id (Chars (Ident));
5860
5861 begin
5862 -- On entry to this procedure, Entity (Ident) contains a copy of the
5863 -- original expression from the aspect, saved for this purpose.
5864
5865 -- On exit from this procedure Entity (Ident) is unchanged, still
5866 -- containing that copy, but Expression (Ident) is a preanalyzed copy
5867 -- of the expression, preanalyzed just after the freeze point.
5868
5869 -- Make a copy of the expression to be preanalyed
5870
5871 Set_Expression (ASN, New_Copy_Tree (Entity (Ident)));
5872
5873 -- Find type for preanalyze call
5874
5875 case A_Id is
5876
5877 -- No_Aspect should be impossible
5878
5879 when No_Aspect =>
5880 raise Program_Error;
5881
ddf1337b 5882 -- Library unit aspects should be impossible (never delayed)
5883
5884 when Library_Unit_Aspects =>
5885 raise Program_Error;
5886
8398ba2c 5887 -- Aspects taking an optional boolean argument. Should be impossible
5888 -- since these are never delayed.
7d20685d 5889
5890 when Boolean_Aspects =>
8398ba2c 5891 raise Program_Error;
5892
6c545057 5893 -- Test_Case aspect applies to entries and subprograms, hence should
5894 -- never be delayed.
5895
5896 when Aspect_Test_Case =>
5897 raise Program_Error;
5898
7f694ca2 5899 when Aspect_Attach_Handler =>
5900 T := RTE (RE_Interrupt_ID);
5901
231eb581 5902 -- Default_Value is resolved with the type entity in question
8398ba2c 5903
231eb581 5904 when Aspect_Default_Value =>
8398ba2c 5905 T := Entity (ASN);
7d20685d 5906
231eb581 5907 -- Default_Component_Value is resolved with the component type
5908
5909 when Aspect_Default_Component_Value =>
5910 T := Component_Type (Entity (ASN));
5911
7d20685d 5912 -- Aspects corresponding to attribute definition clauses
5913
8398ba2c 5914 when Aspect_Address =>
7d20685d 5915 T := RTE (RE_Address);
5916
8398ba2c 5917 when Aspect_Bit_Order =>
7d20685d 5918 T := RTE (RE_Bit_Order);
5919
cb4c311d 5920 when Aspect_CPU =>
5921 T := RTE (RE_CPU_Range);
5922
a7a4a7c2 5923 when Aspect_Dispatching_Domain =>
5924 T := RTE (RE_Dispatching_Domain);
5925
7d20685d 5926 when Aspect_External_Tag =>
5927 T := Standard_String;
5928
7f694ca2 5929 when Aspect_Priority | Aspect_Interrupt_Priority =>
5930 T := Standard_Integer;
5931
5932 when Aspect_Small =>
5933 T := Universal_Real;
5934
7d20685d 5935 when Aspect_Storage_Pool =>
5936 T := Class_Wide_Type (RTE (RE_Root_Storage_Pool));
5937
6c545057 5938 when Aspect_Alignment |
7d20685d 5939 Aspect_Component_Size |
5940 Aspect_Machine_Radix |
5941 Aspect_Object_Size |
5942 Aspect_Size |
5943 Aspect_Storage_Size |
5944 Aspect_Stream_Size |
5945 Aspect_Value_Size =>
5946 T := Any_Integer;
5947
5948 -- Stream attribute. Special case, the expression is just an entity
5949 -- that does not need any resolution, so just analyze.
5950
5951 when Aspect_Input |
5952 Aspect_Output |
5953 Aspect_Read |
5954 Aspect_Write =>
5955 Analyze (Expression (ASN));
81b424ac 5956 return;
5957
5958 -- Same for Iterator aspects, where the expression is a function
5959 -- name. Legality rules are checked separately.
5960
5961 when Aspect_Constant_Indexing |
5962 Aspect_Default_Iterator |
5963 Aspect_Iterator_Element |
5964 Aspect_Implicit_Dereference |
5965 Aspect_Variable_Indexing =>
5966 Analyze (Expression (ASN));
7d20685d 5967 return;
5968
6c545057 5969 -- Suppress/Unsuppress/Warnings should never be delayed
7d20685d 5970
5971 when Aspect_Suppress |
5972 Aspect_Unsuppress |
5973 Aspect_Warnings =>
5974 raise Program_Error;
5975
5976 -- Pre/Post/Invariant/Predicate take boolean expressions
5977
ebbab42d 5978 when Aspect_Dynamic_Predicate |
5979 Aspect_Invariant |
5980 Aspect_Pre |
77ae6789 5981 Aspect_Precondition |
ebbab42d 5982 Aspect_Post |
77ae6789 5983 Aspect_Postcondition |
ebbab42d 5984 Aspect_Predicate |
77ae6789 5985 Aspect_Static_Predicate |
5986 Aspect_Type_Invariant =>
7d20685d 5987 T := Standard_Boolean;
5988 end case;
5989
5990 -- Do the preanalyze call
5991
5992 Preanalyze_Spec_Expression (Expression (ASN), T);
5993 end Check_Aspect_At_Freeze_Point;
5994
d6f39728 5995 -----------------------------------
5996 -- Check_Constant_Address_Clause --
5997 -----------------------------------
5998
5999 procedure Check_Constant_Address_Clause
6000 (Expr : Node_Id;
6001 U_Ent : Entity_Id)
6002 is
6003 procedure Check_At_Constant_Address (Nod : Node_Id);
fdd294d1 6004 -- Checks that the given node N represents a name whose 'Address is
6005 -- constant (in the same sense as OK_Constant_Address_Clause, i.e. the
6006 -- address value is the same at the point of declaration of U_Ent and at
6007 -- the time of elaboration of the address clause.
d6f39728 6008
6009 procedure Check_Expr_Constants (Nod : Node_Id);
fdd294d1 6010 -- Checks that Nod meets the requirements for a constant address clause
6011 -- in the sense of the enclosing procedure.
d6f39728 6012
6013 procedure Check_List_Constants (Lst : List_Id);
6014 -- Check that all elements of list Lst meet the requirements for a
6015 -- constant address clause in the sense of the enclosing procedure.
6016
6017 -------------------------------
6018 -- Check_At_Constant_Address --
6019 -------------------------------
6020
6021 procedure Check_At_Constant_Address (Nod : Node_Id) is
6022 begin
6023 if Is_Entity_Name (Nod) then
6024 if Present (Address_Clause (Entity ((Nod)))) then
6025 Error_Msg_NE
6026 ("invalid address clause for initialized object &!",
6027 Nod, U_Ent);
6028 Error_Msg_NE
6029 ("address for& cannot" &
fbc67f84 6030 " depend on another address clause! (RM 13.1(22))!",
d6f39728 6031 Nod, U_Ent);
6032
6033 elsif In_Same_Source_Unit (Entity (Nod), U_Ent)
6034 and then Sloc (U_Ent) < Sloc (Entity (Nod))
6035 then
6036 Error_Msg_NE
6037 ("invalid address clause for initialized object &!",
6038 Nod, U_Ent);
2f582d72 6039 Error_Msg_Node_2 := U_Ent;
6040 Error_Msg_NE
6041 ("\& must be defined before & (RM 13.1(22))!",
6042 Nod, Entity (Nod));
d6f39728 6043 end if;
6044
6045 elsif Nkind (Nod) = N_Selected_Component then
6046 declare
6047 T : constant Entity_Id := Etype (Prefix (Nod));
6048
6049 begin
6050 if (Is_Record_Type (T)
6051 and then Has_Discriminants (T))
6052 or else
6053 (Is_Access_Type (T)
6054 and then Is_Record_Type (Designated_Type (T))
6055 and then Has_Discriminants (Designated_Type (T)))
6056 then
6057 Error_Msg_NE
6058 ("invalid address clause for initialized object &!",
6059 Nod, U_Ent);
6060 Error_Msg_N
6061 ("\address cannot depend on component" &
fbc67f84 6062 " of discriminated record (RM 13.1(22))!",
d6f39728 6063 Nod);
6064 else
6065 Check_At_Constant_Address (Prefix (Nod));
6066 end if;
6067 end;
6068
6069 elsif Nkind (Nod) = N_Indexed_Component then
6070 Check_At_Constant_Address (Prefix (Nod));
6071 Check_List_Constants (Expressions (Nod));
6072
6073 else
6074 Check_Expr_Constants (Nod);
6075 end if;
6076 end Check_At_Constant_Address;
6077
6078 --------------------------
6079 -- Check_Expr_Constants --
6080 --------------------------
6081
6082 procedure Check_Expr_Constants (Nod : Node_Id) is
e7b2d6bc 6083 Loc_U_Ent : constant Source_Ptr := Sloc (U_Ent);
6084 Ent : Entity_Id := Empty;
6085
d6f39728 6086 begin
6087 if Nkind (Nod) in N_Has_Etype
6088 and then Etype (Nod) = Any_Type
6089 then
6090 return;
6091 end if;
6092
6093 case Nkind (Nod) is
6094 when N_Empty | N_Error =>
6095 return;
6096
6097 when N_Identifier | N_Expanded_Name =>
e7b2d6bc 6098 Ent := Entity (Nod);
9dfe12ae 6099
6100 -- We need to look at the original node if it is different
6101 -- from the node, since we may have rewritten things and
6102 -- substituted an identifier representing the rewrite.
6103
6104 if Original_Node (Nod) /= Nod then
6105 Check_Expr_Constants (Original_Node (Nod));
6106
6107 -- If the node is an object declaration without initial
6108 -- value, some code has been expanded, and the expression
6109 -- is not constant, even if the constituents might be
fdd294d1 6110 -- acceptable, as in A'Address + offset.
9dfe12ae 6111
e7b2d6bc 6112 if Ekind (Ent) = E_Variable
fdd294d1 6113 and then
6114 Nkind (Declaration_Node (Ent)) = N_Object_Declaration
9dfe12ae 6115 and then
e7b2d6bc 6116 No (Expression (Declaration_Node (Ent)))
6117 then
6118 Error_Msg_NE
6119 ("invalid address clause for initialized object &!",
6120 Nod, U_Ent);
6121
6122 -- If entity is constant, it may be the result of expanding
6123 -- a check. We must verify that its declaration appears
6124 -- before the object in question, else we also reject the
6125 -- address clause.
6126
6127 elsif Ekind (Ent) = E_Constant
6128 and then In_Same_Source_Unit (Ent, U_Ent)
6129 and then Sloc (Ent) > Loc_U_Ent
9dfe12ae 6130 then
6131 Error_Msg_NE
6132 ("invalid address clause for initialized object &!",
6133 Nod, U_Ent);
6134 end if;
e7b2d6bc 6135
9dfe12ae 6136 return;
6137 end if;
6138
2866d595 6139 -- Otherwise look at the identifier and see if it is OK
9dfe12ae 6140
d3ef794c 6141 if Ekind_In (Ent, E_Named_Integer, E_Named_Real)
6142 or else Is_Type (Ent)
e7b2d6bc 6143 then
6144 return;
d6f39728 6145
e7b2d6bc 6146 elsif
6147 Ekind (Ent) = E_Constant
6148 or else
6149 Ekind (Ent) = E_In_Parameter
6150 then
fdd294d1 6151 -- This is the case where we must have Ent defined before
6152 -- U_Ent. Clearly if they are in different units this
6153 -- requirement is met since the unit containing Ent is
6154 -- already processed.
d6f39728 6155
e7b2d6bc 6156 if not In_Same_Source_Unit (Ent, U_Ent) then
6157 return;
d6f39728 6158
fdd294d1 6159 -- Otherwise location of Ent must be before the location
6160 -- of U_Ent, that's what prior defined means.
d6f39728 6161
e7b2d6bc 6162 elsif Sloc (Ent) < Loc_U_Ent then
6163 return;
d6f39728 6164
6165 else
6166 Error_Msg_NE
6167 ("invalid address clause for initialized object &!",
6168 Nod, U_Ent);
2f582d72 6169 Error_Msg_Node_2 := U_Ent;
6170 Error_Msg_NE
6171 ("\& must be defined before & (RM 13.1(22))!",
6172 Nod, Ent);
e7b2d6bc 6173 end if;
9dfe12ae 6174
e7b2d6bc 6175 elsif Nkind (Original_Node (Nod)) = N_Function_Call then
6176 Check_Expr_Constants (Original_Node (Nod));
6177
6178 else
6179 Error_Msg_NE
6180 ("invalid address clause for initialized object &!",
6181 Nod, U_Ent);
6182
6183 if Comes_From_Source (Ent) then
2f582d72 6184 Error_Msg_NE
6185 ("\reference to variable& not allowed"
6186 & " (RM 13.1(22))!", Nod, Ent);
e7b2d6bc 6187 else
6188 Error_Msg_N
6189 ("non-static expression not allowed"
fbc67f84 6190 & " (RM 13.1(22))!", Nod);
d6f39728 6191 end if;
e7b2d6bc 6192 end if;
d6f39728 6193
93735cb8 6194 when N_Integer_Literal =>
6195
6196 -- If this is a rewritten unchecked conversion, in a system
6197 -- where Address is an integer type, always use the base type
6198 -- for a literal value. This is user-friendly and prevents
6199 -- order-of-elaboration issues with instances of unchecked
6200 -- conversion.
6201
6202 if Nkind (Original_Node (Nod)) = N_Function_Call then
6203 Set_Etype (Nod, Base_Type (Etype (Nod)));
6204 end if;
6205
6206 when N_Real_Literal |
d6f39728 6207 N_String_Literal |
6208 N_Character_Literal =>
6209 return;
6210
6211 when N_Range =>
6212 Check_Expr_Constants (Low_Bound (Nod));
6213 Check_Expr_Constants (High_Bound (Nod));
6214
6215 when N_Explicit_Dereference =>
6216 Check_Expr_Constants (Prefix (Nod));
6217
6218 when N_Indexed_Component =>
6219 Check_Expr_Constants (Prefix (Nod));
6220 Check_List_Constants (Expressions (Nod));
6221
6222 when N_Slice =>
6223 Check_Expr_Constants (Prefix (Nod));
6224 Check_Expr_Constants (Discrete_Range (Nod));
6225
6226 when N_Selected_Component =>
6227 Check_Expr_Constants (Prefix (Nod));
6228
6229 when N_Attribute_Reference =>
9dfe12ae 6230 if Attribute_Name (Nod) = Name_Address
6231 or else
6232 Attribute_Name (Nod) = Name_Access
d6f39728 6233 or else
9dfe12ae 6234 Attribute_Name (Nod) = Name_Unchecked_Access
d6f39728 6235 or else
9dfe12ae 6236 Attribute_Name (Nod) = Name_Unrestricted_Access
d6f39728 6237 then
6238 Check_At_Constant_Address (Prefix (Nod));
6239
6240 else
6241 Check_Expr_Constants (Prefix (Nod));
6242 Check_List_Constants (Expressions (Nod));
6243 end if;
6244
6245 when N_Aggregate =>
6246 Check_List_Constants (Component_Associations (Nod));
6247 Check_List_Constants (Expressions (Nod));
6248
6249 when N_Component_Association =>
6250 Check_Expr_Constants (Expression (Nod));
6251
6252 when N_Extension_Aggregate =>
6253 Check_Expr_Constants (Ancestor_Part (Nod));
6254 Check_List_Constants (Component_Associations (Nod));
6255 Check_List_Constants (Expressions (Nod));
6256
6257 when N_Null =>
6258 return;
6259
e7771556 6260 when N_Binary_Op | N_Short_Circuit | N_Membership_Test =>
d6f39728 6261 Check_Expr_Constants (Left_Opnd (Nod));
6262 Check_Expr_Constants (Right_Opnd (Nod));
6263
6264 when N_Unary_Op =>
6265 Check_Expr_Constants (Right_Opnd (Nod));
6266
6267 when N_Type_Conversion |
6268 N_Qualified_Expression |
6269 N_Allocator =>
6270 Check_Expr_Constants (Expression (Nod));
6271
6272 when N_Unchecked_Type_Conversion =>
6273 Check_Expr_Constants (Expression (Nod));
6274
fdd294d1 6275 -- If this is a rewritten unchecked conversion, subtypes in
6276 -- this node are those created within the instance. To avoid
6277 -- order of elaboration issues, replace them with their base
6278 -- types. Note that address clauses can cause order of
6279 -- elaboration problems because they are elaborated by the
6280 -- back-end at the point of definition, and may mention
6281 -- entities declared in between (as long as everything is
6282 -- static). It is user-friendly to allow unchecked conversions
6283 -- in this context.
d6f39728 6284
6285 if Nkind (Original_Node (Nod)) = N_Function_Call then
6286 Set_Etype (Expression (Nod),
6287 Base_Type (Etype (Expression (Nod))));
6288 Set_Etype (Nod, Base_Type (Etype (Nod)));
6289 end if;
6290
6291 when N_Function_Call =>
6292 if not Is_Pure (Entity (Name (Nod))) then
6293 Error_Msg_NE
6294 ("invalid address clause for initialized object &!",
6295 Nod, U_Ent);
6296
6297 Error_Msg_NE
fbc67f84 6298 ("\function & is not pure (RM 13.1(22))!",
d6f39728 6299 Nod, Entity (Name (Nod)));
6300
6301 else
6302 Check_List_Constants (Parameter_Associations (Nod));
6303 end if;
6304
6305 when N_Parameter_Association =>
6306 Check_Expr_Constants (Explicit_Actual_Parameter (Nod));
6307
6308 when others =>
6309 Error_Msg_NE
6310 ("invalid address clause for initialized object &!",
6311 Nod, U_Ent);
6312 Error_Msg_NE
fbc67f84 6313 ("\must be constant defined before& (RM 13.1(22))!",
d6f39728 6314 Nod, U_Ent);
6315 end case;
6316 end Check_Expr_Constants;
6317
6318 --------------------------
6319 -- Check_List_Constants --
6320 --------------------------
6321
6322 procedure Check_List_Constants (Lst : List_Id) is
6323 Nod1 : Node_Id;
6324
6325 begin
6326 if Present (Lst) then
6327 Nod1 := First (Lst);
6328 while Present (Nod1) loop
6329 Check_Expr_Constants (Nod1);
6330 Next (Nod1);
6331 end loop;
6332 end if;
6333 end Check_List_Constants;
6334
6335 -- Start of processing for Check_Constant_Address_Clause
6336
6337 begin
01cb2726 6338 -- If rep_clauses are to be ignored, no need for legality checks. In
6339 -- particular, no need to pester user about rep clauses that violate
6340 -- the rule on constant addresses, given that these clauses will be
6341 -- removed by Freeze before they reach the back end.
6342
6343 if not Ignore_Rep_Clauses then
6344 Check_Expr_Constants (Expr);
6345 end if;
d6f39728 6346 end Check_Constant_Address_Clause;
6347
67278d60 6348 ----------------------------------------
6349 -- Check_Record_Representation_Clause --
6350 ----------------------------------------
6351
6352 procedure Check_Record_Representation_Clause (N : Node_Id) is
6353 Loc : constant Source_Ptr := Sloc (N);
6354 Ident : constant Node_Id := Identifier (N);
6355 Rectype : Entity_Id;
6356 Fent : Entity_Id;
6357 CC : Node_Id;
6358 Fbit : Uint;
6359 Lbit : Uint;
6360 Hbit : Uint := Uint_0;
6361 Comp : Entity_Id;
6362 Pcomp : Entity_Id;
6363
6364 Max_Bit_So_Far : Uint;
6365 -- Records the maximum bit position so far. If all field positions
6366 -- are monotonically increasing, then we can skip the circuit for
6367 -- checking for overlap, since no overlap is possible.
6368
6369 Tagged_Parent : Entity_Id := Empty;
6370 -- This is set in the case of a derived tagged type for which we have
6371 -- Is_Fully_Repped_Tagged_Type True (indicating that all components are
6372 -- positioned by record representation clauses). In this case we must
6373 -- check for overlap between components of this tagged type, and the
6374 -- components of its parent. Tagged_Parent will point to this parent
6375 -- type. For all other cases Tagged_Parent is left set to Empty.
6376
6377 Parent_Last_Bit : Uint;
6378 -- Relevant only if Tagged_Parent is set, Parent_Last_Bit indicates the
6379 -- last bit position for any field in the parent type. We only need to
6380 -- check overlap for fields starting below this point.
6381
6382 Overlap_Check_Required : Boolean;
6383 -- Used to keep track of whether or not an overlap check is required
6384
47495553 6385 Overlap_Detected : Boolean := False;
6386 -- Set True if an overlap is detected
6387
67278d60 6388 Ccount : Natural := 0;
6389 -- Number of component clauses in record rep clause
6390
6391 procedure Check_Component_Overlap (C1_Ent, C2_Ent : Entity_Id);
6392 -- Given two entities for record components or discriminants, checks
6393 -- if they have overlapping component clauses and issues errors if so.
6394
6395 procedure Find_Component;
6396 -- Finds component entity corresponding to current component clause (in
6397 -- CC), and sets Comp to the entity, and Fbit/Lbit to the zero origin
6398 -- start/stop bits for the field. If there is no matching component or
6399 -- if the matching component does not have a component clause, then
6400 -- that's an error and Comp is set to Empty, but no error message is
6401 -- issued, since the message was already given. Comp is also set to
6402 -- Empty if the current "component clause" is in fact a pragma.
6403
6404 -----------------------------
6405 -- Check_Component_Overlap --
6406 -----------------------------
6407
6408 procedure Check_Component_Overlap (C1_Ent, C2_Ent : Entity_Id) is
6409 CC1 : constant Node_Id := Component_Clause (C1_Ent);
6410 CC2 : constant Node_Id := Component_Clause (C2_Ent);
47495553 6411
67278d60 6412 begin
6413 if Present (CC1) and then Present (CC2) then
6414
6415 -- Exclude odd case where we have two tag fields in the same
6416 -- record, both at location zero. This seems a bit strange, but
6417 -- it seems to happen in some circumstances, perhaps on an error.
6418
6419 if Chars (C1_Ent) = Name_uTag
6420 and then
6421 Chars (C2_Ent) = Name_uTag
6422 then
6423 return;
6424 end if;
6425
6426 -- Here we check if the two fields overlap
6427
6428 declare
6429 S1 : constant Uint := Component_Bit_Offset (C1_Ent);
6430 S2 : constant Uint := Component_Bit_Offset (C2_Ent);
6431 E1 : constant Uint := S1 + Esize (C1_Ent);
6432 E2 : constant Uint := S2 + Esize (C2_Ent);
6433
6434 begin
6435 if E2 <= S1 or else E1 <= S2 then
6436 null;
6437 else
6438 Error_Msg_Node_2 := Component_Name (CC2);
6439 Error_Msg_Sloc := Sloc (Error_Msg_Node_2);
6440 Error_Msg_Node_1 := Component_Name (CC1);
6441 Error_Msg_N
6442 ("component& overlaps & #", Component_Name (CC1));
47495553 6443 Overlap_Detected := True;
67278d60 6444 end if;
6445 end;
6446 end if;
6447 end Check_Component_Overlap;
6448
6449 --------------------
6450 -- Find_Component --
6451 --------------------
6452
6453 procedure Find_Component is
6454
6455 procedure Search_Component (R : Entity_Id);
6456 -- Search components of R for a match. If found, Comp is set.
6457
6458 ----------------------
6459 -- Search_Component --
6460 ----------------------
6461
6462 procedure Search_Component (R : Entity_Id) is
6463 begin
6464 Comp := First_Component_Or_Discriminant (R);
6465 while Present (Comp) loop
6466
6467 -- Ignore error of attribute name for component name (we
6468 -- already gave an error message for this, so no need to
6469 -- complain here)
6470
6471 if Nkind (Component_Name (CC)) = N_Attribute_Reference then
6472 null;
6473 else
6474 exit when Chars (Comp) = Chars (Component_Name (CC));
6475 end if;
6476
6477 Next_Component_Or_Discriminant (Comp);
6478 end loop;
6479 end Search_Component;
6480
6481 -- Start of processing for Find_Component
6482
6483 begin
6484 -- Return with Comp set to Empty if we have a pragma
6485
6486 if Nkind (CC) = N_Pragma then
6487 Comp := Empty;
6488 return;
6489 end if;
6490
6491 -- Search current record for matching component
6492
6493 Search_Component (Rectype);
6494
6495 -- If not found, maybe component of base type that is absent from
6496 -- statically constrained first subtype.
6497
6498 if No (Comp) then
6499 Search_Component (Base_Type (Rectype));
6500 end if;
6501
6502 -- If no component, or the component does not reference the component
6503 -- clause in question, then there was some previous error for which
6504 -- we already gave a message, so just return with Comp Empty.
6505
6506 if No (Comp)
6507 or else Component_Clause (Comp) /= CC
6508 then
6509 Comp := Empty;
6510
6511 -- Normal case where we have a component clause
6512
6513 else
6514 Fbit := Component_Bit_Offset (Comp);
6515 Lbit := Fbit + Esize (Comp) - 1;
6516 end if;
6517 end Find_Component;
6518
6519 -- Start of processing for Check_Record_Representation_Clause
6520
6521 begin
6522 Find_Type (Ident);
6523 Rectype := Entity (Ident);
6524
6525 if Rectype = Any_Type then
6526 return;
6527 else
6528 Rectype := Underlying_Type (Rectype);
6529 end if;
6530
6531 -- See if we have a fully repped derived tagged type
6532
6533 declare
6534 PS : constant Entity_Id := Parent_Subtype (Rectype);
6535
6536 begin
6537 if Present (PS) and then Is_Fully_Repped_Tagged_Type (PS) then
6538 Tagged_Parent := PS;
6539
6540 -- Find maximum bit of any component of the parent type
6541
6542 Parent_Last_Bit := UI_From_Int (System_Address_Size - 1);
6543 Pcomp := First_Entity (Tagged_Parent);
6544 while Present (Pcomp) loop
6545 if Ekind_In (Pcomp, E_Discriminant, E_Component) then
6546 if Component_Bit_Offset (Pcomp) /= No_Uint
6547 and then Known_Static_Esize (Pcomp)
6548 then
6549 Parent_Last_Bit :=
6550 UI_Max
6551 (Parent_Last_Bit,
6552 Component_Bit_Offset (Pcomp) + Esize (Pcomp) - 1);
6553 end if;
6554
6555 Next_Entity (Pcomp);
6556 end if;
6557 end loop;
6558 end if;
6559 end;
6560
6561 -- All done if no component clauses
6562
6563 CC := First (Component_Clauses (N));
6564
6565 if No (CC) then
6566 return;
6567 end if;
6568
6569 -- If a tag is present, then create a component clause that places it
6570 -- at the start of the record (otherwise gigi may place it after other
6571 -- fields that have rep clauses).
6572
6573 Fent := First_Entity (Rectype);
6574
6575 if Nkind (Fent) = N_Defining_Identifier
6576 and then Chars (Fent) = Name_uTag
6577 then
6578 Set_Component_Bit_Offset (Fent, Uint_0);
6579 Set_Normalized_Position (Fent, Uint_0);
6580 Set_Normalized_First_Bit (Fent, Uint_0);
6581 Set_Normalized_Position_Max (Fent, Uint_0);
6582 Init_Esize (Fent, System_Address_Size);
6583
6584 Set_Component_Clause (Fent,
6585 Make_Component_Clause (Loc,
55868293 6586 Component_Name => Make_Identifier (Loc, Name_uTag),
67278d60 6587
55868293 6588 Position => Make_Integer_Literal (Loc, Uint_0),
6589 First_Bit => Make_Integer_Literal (Loc, Uint_0),
67278d60 6590 Last_Bit =>
6591 Make_Integer_Literal (Loc,
6592 UI_From_Int (System_Address_Size))));
6593
6594 Ccount := Ccount + 1;
6595 end if;
6596
6597 Max_Bit_So_Far := Uint_Minus_1;
6598 Overlap_Check_Required := False;
6599
6600 -- Process the component clauses
6601
6602 while Present (CC) loop
6603 Find_Component;
6604
6605 if Present (Comp) then
6606 Ccount := Ccount + 1;
6607
47495553 6608 -- We need a full overlap check if record positions non-monotonic
6609
67278d60 6610 if Fbit <= Max_Bit_So_Far then
6611 Overlap_Check_Required := True;
67278d60 6612 end if;
6613
47495553 6614 Max_Bit_So_Far := Lbit;
6615
67278d60 6616 -- Check bit position out of range of specified size
6617
6618 if Has_Size_Clause (Rectype)
ada34def 6619 and then RM_Size (Rectype) <= Lbit
67278d60 6620 then
6621 Error_Msg_N
6622 ("bit number out of range of specified size",
6623 Last_Bit (CC));
6624
6625 -- Check for overlap with tag field
6626
6627 else
6628 if Is_Tagged_Type (Rectype)
6629 and then Fbit < System_Address_Size
6630 then
6631 Error_Msg_NE
6632 ("component overlaps tag field of&",
6633 Component_Name (CC), Rectype);
47495553 6634 Overlap_Detected := True;
67278d60 6635 end if;
6636
6637 if Hbit < Lbit then
6638 Hbit := Lbit;
6639 end if;
6640 end if;
6641
6642 -- Check parent overlap if component might overlap parent field
6643
6644 if Present (Tagged_Parent)
6645 and then Fbit <= Parent_Last_Bit
6646 then
6647 Pcomp := First_Component_Or_Discriminant (Tagged_Parent);
6648 while Present (Pcomp) loop
6649 if not Is_Tag (Pcomp)
6650 and then Chars (Pcomp) /= Name_uParent
6651 then
6652 Check_Component_Overlap (Comp, Pcomp);
6653 end if;
6654
6655 Next_Component_Or_Discriminant (Pcomp);
6656 end loop;
6657 end if;
6658 end if;
6659
6660 Next (CC);
6661 end loop;
6662
6663 -- Now that we have processed all the component clauses, check for
6664 -- overlap. We have to leave this till last, since the components can
6665 -- appear in any arbitrary order in the representation clause.
6666
6667 -- We do not need this check if all specified ranges were monotonic,
6668 -- as recorded by Overlap_Check_Required being False at this stage.
6669
6670 -- This first section checks if there are any overlapping entries at
6671 -- all. It does this by sorting all entries and then seeing if there are
6672 -- any overlaps. If there are none, then that is decisive, but if there
6673 -- are overlaps, they may still be OK (they may result from fields in
6674 -- different variants).
6675
6676 if Overlap_Check_Required then
6677 Overlap_Check1 : declare
6678
6679 OC_Fbit : array (0 .. Ccount) of Uint;
6680 -- First-bit values for component clauses, the value is the offset
6681 -- of the first bit of the field from start of record. The zero
6682 -- entry is for use in sorting.
6683
6684 OC_Lbit : array (0 .. Ccount) of Uint;
6685 -- Last-bit values for component clauses, the value is the offset
6686 -- of the last bit of the field from start of record. The zero
6687 -- entry is for use in sorting.
6688
6689 OC_Count : Natural := 0;
6690 -- Count of entries in OC_Fbit and OC_Lbit
6691
6692 function OC_Lt (Op1, Op2 : Natural) return Boolean;
6693 -- Compare routine for Sort
6694
6695 procedure OC_Move (From : Natural; To : Natural);
6696 -- Move routine for Sort
6697
6698 package Sorting is new GNAT.Heap_Sort_G (OC_Move, OC_Lt);
6699
6700 -----------
6701 -- OC_Lt --
6702 -----------
6703
6704 function OC_Lt (Op1, Op2 : Natural) return Boolean is
6705 begin
6706 return OC_Fbit (Op1) < OC_Fbit (Op2);
6707 end OC_Lt;
6708
6709 -------------
6710 -- OC_Move --
6711 -------------
6712
6713 procedure OC_Move (From : Natural; To : Natural) is
6714 begin
6715 OC_Fbit (To) := OC_Fbit (From);
6716 OC_Lbit (To) := OC_Lbit (From);
6717 end OC_Move;
6718
6719 -- Start of processing for Overlap_Check
6720
6721 begin
6722 CC := First (Component_Clauses (N));
6723 while Present (CC) loop
6724
6725 -- Exclude component clause already marked in error
6726
6727 if not Error_Posted (CC) then
6728 Find_Component;
6729
6730 if Present (Comp) then
6731 OC_Count := OC_Count + 1;
6732 OC_Fbit (OC_Count) := Fbit;
6733 OC_Lbit (OC_Count) := Lbit;
6734 end if;
6735 end if;
6736
6737 Next (CC);
6738 end loop;
6739
6740 Sorting.Sort (OC_Count);
6741
6742 Overlap_Check_Required := False;
6743 for J in 1 .. OC_Count - 1 loop
6744 if OC_Lbit (J) >= OC_Fbit (J + 1) then
6745 Overlap_Check_Required := True;
6746 exit;
6747 end if;
6748 end loop;
6749 end Overlap_Check1;
6750 end if;
6751
6752 -- If Overlap_Check_Required is still True, then we have to do the full
6753 -- scale overlap check, since we have at least two fields that do
6754 -- overlap, and we need to know if that is OK since they are in
6755 -- different variant, or whether we have a definite problem.
6756
6757 if Overlap_Check_Required then
6758 Overlap_Check2 : declare
6759 C1_Ent, C2_Ent : Entity_Id;
6760 -- Entities of components being checked for overlap
6761
6762 Clist : Node_Id;
6763 -- Component_List node whose Component_Items are being checked
6764
6765 Citem : Node_Id;
6766 -- Component declaration for component being checked
6767
6768 begin
6769 C1_Ent := First_Entity (Base_Type (Rectype));
6770
6771 -- Loop through all components in record. For each component check
6772 -- for overlap with any of the preceding elements on the component
6773 -- list containing the component and also, if the component is in
6774 -- a variant, check against components outside the case structure.
6775 -- This latter test is repeated recursively up the variant tree.
6776
6777 Main_Component_Loop : while Present (C1_Ent) loop
6778 if not Ekind_In (C1_Ent, E_Component, E_Discriminant) then
6779 goto Continue_Main_Component_Loop;
6780 end if;
6781
6782 -- Skip overlap check if entity has no declaration node. This
6783 -- happens with discriminants in constrained derived types.
47495553 6784 -- Possibly we are missing some checks as a result, but that
6785 -- does not seem terribly serious.
67278d60 6786
6787 if No (Declaration_Node (C1_Ent)) then
6788 goto Continue_Main_Component_Loop;
6789 end if;
6790
6791 Clist := Parent (List_Containing (Declaration_Node (C1_Ent)));
6792
6793 -- Loop through component lists that need checking. Check the
6794 -- current component list and all lists in variants above us.
6795
6796 Component_List_Loop : loop
6797
6798 -- If derived type definition, go to full declaration
6799 -- If at outer level, check discriminants if there are any.
6800
6801 if Nkind (Clist) = N_Derived_Type_Definition then
6802 Clist := Parent (Clist);
6803 end if;
6804
6805 -- Outer level of record definition, check discriminants
6806
6807 if Nkind_In (Clist, N_Full_Type_Declaration,
6808 N_Private_Type_Declaration)
6809 then
6810 if Has_Discriminants (Defining_Identifier (Clist)) then
6811 C2_Ent :=
6812 First_Discriminant (Defining_Identifier (Clist));
6813 while Present (C2_Ent) loop
6814 exit when C1_Ent = C2_Ent;
6815 Check_Component_Overlap (C1_Ent, C2_Ent);
6816 Next_Discriminant (C2_Ent);
6817 end loop;
6818 end if;
6819
6820 -- Record extension case
6821
6822 elsif Nkind (Clist) = N_Derived_Type_Definition then
6823 Clist := Empty;
6824
6825 -- Otherwise check one component list
6826
6827 else
6828 Citem := First (Component_Items (Clist));
67278d60 6829 while Present (Citem) loop
6830 if Nkind (Citem) = N_Component_Declaration then
6831 C2_Ent := Defining_Identifier (Citem);
6832 exit when C1_Ent = C2_Ent;
6833 Check_Component_Overlap (C1_Ent, C2_Ent);
6834 end if;
6835
6836 Next (Citem);
6837 end loop;
6838 end if;
6839
6840 -- Check for variants above us (the parent of the Clist can
6841 -- be a variant, in which case its parent is a variant part,
6842 -- and the parent of the variant part is a component list
6843 -- whose components must all be checked against the current
6844 -- component for overlap).
6845
6846 if Nkind (Parent (Clist)) = N_Variant then
6847 Clist := Parent (Parent (Parent (Clist)));
6848
6849 -- Check for possible discriminant part in record, this
6850 -- is treated essentially as another level in the
6851 -- recursion. For this case the parent of the component
6852 -- list is the record definition, and its parent is the
6853 -- full type declaration containing the discriminant
6854 -- specifications.
6855
6856 elsif Nkind (Parent (Clist)) = N_Record_Definition then
6857 Clist := Parent (Parent ((Clist)));
6858
6859 -- If neither of these two cases, we are at the top of
6860 -- the tree.
6861
6862 else
6863 exit Component_List_Loop;
6864 end if;
6865 end loop Component_List_Loop;
6866
6867 <<Continue_Main_Component_Loop>>
6868 Next_Entity (C1_Ent);
6869
6870 end loop Main_Component_Loop;
6871 end Overlap_Check2;
6872 end if;
6873
47495553 6874 -- The following circuit deals with warning on record holes (gaps). We
6875 -- skip this check if overlap was detected, since it makes sense for the
6876 -- programmer to fix this illegality before worrying about warnings.
6877
6878 if not Overlap_Detected and Warn_On_Record_Holes then
6879 Record_Hole_Check : declare
6880 Decl : constant Node_Id := Declaration_Node (Base_Type (Rectype));
6881 -- Full declaration of record type
6882
6883 procedure Check_Component_List
6884 (CL : Node_Id;
6885 Sbit : Uint;
6886 DS : List_Id);
6887 -- Check component list CL for holes. The starting bit should be
6888 -- Sbit. which is zero for the main record component list and set
6889 -- appropriately for recursive calls for variants. DS is set to
6890 -- a list of discriminant specifications to be included in the
6891 -- consideration of components. It is No_List if none to consider.
6892
6893 --------------------------
6894 -- Check_Component_List --
6895 --------------------------
6896
6897 procedure Check_Component_List
6898 (CL : Node_Id;
6899 Sbit : Uint;
6900 DS : List_Id)
6901 is
6902 Compl : Integer;
6903
6904 begin
6905 Compl := Integer (List_Length (Component_Items (CL)));
6906
6907 if DS /= No_List then
6908 Compl := Compl + Integer (List_Length (DS));
6909 end if;
6910
6911 declare
6912 Comps : array (Natural range 0 .. Compl) of Entity_Id;
6913 -- Gather components (zero entry is for sort routine)
6914
6915 Ncomps : Natural := 0;
6916 -- Number of entries stored in Comps (starting at Comps (1))
6917
6918 Citem : Node_Id;
6919 -- One component item or discriminant specification
6920
6921 Nbit : Uint;
6922 -- Starting bit for next component
6923
6924 CEnt : Entity_Id;
6925 -- Component entity
6926
6927 Variant : Node_Id;
6928 -- One variant
6929
6930 function Lt (Op1, Op2 : Natural) return Boolean;
6931 -- Compare routine for Sort
6932
6933 procedure Move (From : Natural; To : Natural);
6934 -- Move routine for Sort
6935
6936 package Sorting is new GNAT.Heap_Sort_G (Move, Lt);
6937
6938 --------
6939 -- Lt --
6940 --------
6941
6942 function Lt (Op1, Op2 : Natural) return Boolean is
6943 begin
6944 return Component_Bit_Offset (Comps (Op1))
6945 <
6946 Component_Bit_Offset (Comps (Op2));
6947 end Lt;
6948
6949 ----------
6950 -- Move --
6951 ----------
6952
6953 procedure Move (From : Natural; To : Natural) is
6954 begin
6955 Comps (To) := Comps (From);
6956 end Move;
6957
6958 begin
6959 -- Gather discriminants into Comp
6960
6961 if DS /= No_List then
6962 Citem := First (DS);
6963 while Present (Citem) loop
6964 if Nkind (Citem) = N_Discriminant_Specification then
6965 declare
6966 Ent : constant Entity_Id :=
6967 Defining_Identifier (Citem);
6968 begin
6969 if Ekind (Ent) = E_Discriminant then
6970 Ncomps := Ncomps + 1;
6971 Comps (Ncomps) := Ent;
6972 end if;
6973 end;
6974 end if;
6975
6976 Next (Citem);
6977 end loop;
6978 end if;
6979
6980 -- Gather component entities into Comp
6981
6982 Citem := First (Component_Items (CL));
6983 while Present (Citem) loop
6984 if Nkind (Citem) = N_Component_Declaration then
6985 Ncomps := Ncomps + 1;
6986 Comps (Ncomps) := Defining_Identifier (Citem);
6987 end if;
6988
6989 Next (Citem);
6990 end loop;
6991
6992 -- Now sort the component entities based on the first bit.
6993 -- Note we already know there are no overlapping components.
6994
6995 Sorting.Sort (Ncomps);
6996
6997 -- Loop through entries checking for holes
6998
6999 Nbit := Sbit;
7000 for J in 1 .. Ncomps loop
7001 CEnt := Comps (J);
7002 Error_Msg_Uint_1 := Component_Bit_Offset (CEnt) - Nbit;
7003
7004 if Error_Msg_Uint_1 > 0 then
7005 Error_Msg_NE
7006 ("?^-bit gap before component&",
7007 Component_Name (Component_Clause (CEnt)), CEnt);
7008 end if;
7009
7010 Nbit := Component_Bit_Offset (CEnt) + Esize (CEnt);
7011 end loop;
7012
7013 -- Process variant parts recursively if present
7014
7015 if Present (Variant_Part (CL)) then
7016 Variant := First (Variants (Variant_Part (CL)));
7017 while Present (Variant) loop
7018 Check_Component_List
7019 (Component_List (Variant), Nbit, No_List);
7020 Next (Variant);
7021 end loop;
7022 end if;
7023 end;
7024 end Check_Component_List;
7025
7026 -- Start of processing for Record_Hole_Check
7027
7028 begin
7029 declare
7030 Sbit : Uint;
7031
7032 begin
7033 if Is_Tagged_Type (Rectype) then
7034 Sbit := UI_From_Int (System_Address_Size);
7035 else
7036 Sbit := Uint_0;
7037 end if;
7038
7039 if Nkind (Decl) = N_Full_Type_Declaration
7040 and then Nkind (Type_Definition (Decl)) = N_Record_Definition
7041 then
7042 Check_Component_List
7043 (Component_List (Type_Definition (Decl)),
7044 Sbit,
7045 Discriminant_Specifications (Decl));
7046 end if;
7047 end;
7048 end Record_Hole_Check;
7049 end if;
7050
67278d60 7051 -- For records that have component clauses for all components, and whose
7052 -- size is less than or equal to 32, we need to know the size in the
7053 -- front end to activate possible packed array processing where the
7054 -- component type is a record.
7055
7056 -- At this stage Hbit + 1 represents the first unused bit from all the
7057 -- component clauses processed, so if the component clauses are
7058 -- complete, then this is the length of the record.
7059
7060 -- For records longer than System.Storage_Unit, and for those where not
7061 -- all components have component clauses, the back end determines the
7062 -- length (it may for example be appropriate to round up the size
7063 -- to some convenient boundary, based on alignment considerations, etc).
7064
7065 if Unknown_RM_Size (Rectype) and then Hbit + 1 <= 32 then
7066
7067 -- Nothing to do if at least one component has no component clause
7068
7069 Comp := First_Component_Or_Discriminant (Rectype);
7070 while Present (Comp) loop
7071 exit when No (Component_Clause (Comp));
7072 Next_Component_Or_Discriminant (Comp);
7073 end loop;
7074
7075 -- If we fall out of loop, all components have component clauses
7076 -- and so we can set the size to the maximum value.
7077
7078 if No (Comp) then
7079 Set_RM_Size (Rectype, Hbit + 1);
7080 end if;
7081 end if;
7082 end Check_Record_Representation_Clause;
7083
d6f39728 7084 ----------------
7085 -- Check_Size --
7086 ----------------
7087
7088 procedure Check_Size
7089 (N : Node_Id;
7090 T : Entity_Id;
7091 Siz : Uint;
7092 Biased : out Boolean)
7093 is
7094 UT : constant Entity_Id := Underlying_Type (T);
7095 M : Uint;
7096
7097 begin
7098 Biased := False;
7099
ea61a7ea 7100 -- Dismiss cases for generic types or types with previous errors
d6f39728 7101
7102 if No (UT)
7103 or else UT = Any_Type
7104 or else Is_Generic_Type (UT)
7105 or else Is_Generic_Type (Root_Type (UT))
d6f39728 7106 then
7107 return;
7108
ea61a7ea 7109 -- Check case of bit packed array
7110
7111 elsif Is_Array_Type (UT)
7112 and then Known_Static_Component_Size (UT)
7113 and then Is_Bit_Packed_Array (UT)
7114 then
7115 declare
7116 Asiz : Uint;
7117 Indx : Node_Id;
7118 Ityp : Entity_Id;
7119
7120 begin
7121 Asiz := Component_Size (UT);
7122 Indx := First_Index (UT);
7123 loop
7124 Ityp := Etype (Indx);
7125
7126 -- If non-static bound, then we are not in the business of
7127 -- trying to check the length, and indeed an error will be
7128 -- issued elsewhere, since sizes of non-static array types
7129 -- cannot be set implicitly or explicitly.
7130
7131 if not Is_Static_Subtype (Ityp) then
7132 return;
7133 end if;
7134
7135 -- Otherwise accumulate next dimension
7136
7137 Asiz := Asiz * (Expr_Value (Type_High_Bound (Ityp)) -
7138 Expr_Value (Type_Low_Bound (Ityp)) +
7139 Uint_1);
7140
7141 Next_Index (Indx);
7142 exit when No (Indx);
7143 end loop;
7144
7145 if Asiz <= Siz then
7146 return;
7147 else
7148 Error_Msg_Uint_1 := Asiz;
7149 Error_Msg_NE
7150 ("size for& too small, minimum allowed is ^", N, T);
37cb33b0 7151 Set_Esize (T, Asiz);
7152 Set_RM_Size (T, Asiz);
ea61a7ea 7153 end if;
7154 end;
7155
7156 -- All other composite types are ignored
7157
7158 elsif Is_Composite_Type (UT) then
7159 return;
7160
d6f39728 7161 -- For fixed-point types, don't check minimum if type is not frozen,
ea61a7ea 7162 -- since we don't know all the characteristics of the type that can
7163 -- affect the size (e.g. a specified small) till freeze time.
d6f39728 7164
7165 elsif Is_Fixed_Point_Type (UT)
7166 and then not Is_Frozen (UT)
7167 then
7168 null;
7169
7170 -- Cases for which a minimum check is required
7171
7172 else
ea61a7ea 7173 -- Ignore if specified size is correct for the type
7174
7175 if Known_Esize (UT) and then Siz = Esize (UT) then
7176 return;
7177 end if;
7178
7179 -- Otherwise get minimum size
7180
d6f39728 7181 M := UI_From_Int (Minimum_Size (UT));
7182
7183 if Siz < M then
7184
7185 -- Size is less than minimum size, but one possibility remains
fdd294d1 7186 -- that we can manage with the new size if we bias the type.
d6f39728 7187
7188 M := UI_From_Int (Minimum_Size (UT, Biased => True));
7189
7190 if Siz < M then
7191 Error_Msg_Uint_1 := M;
7192 Error_Msg_NE
7193 ("size for& too small, minimum allowed is ^", N, T);
37cb33b0 7194 Set_Esize (T, M);
7195 Set_RM_Size (T, M);
d6f39728 7196 else
7197 Biased := True;
7198 end if;
7199 end if;
7200 end if;
7201 end Check_Size;
7202
7203 -------------------------
7204 -- Get_Alignment_Value --
7205 -------------------------
7206
7207 function Get_Alignment_Value (Expr : Node_Id) return Uint is
7208 Align : constant Uint := Static_Integer (Expr);
7209
7210 begin
7211 if Align = No_Uint then
7212 return No_Uint;
7213
7214 elsif Align <= 0 then
7215 Error_Msg_N ("alignment value must be positive", Expr);
7216 return No_Uint;
7217
7218 else
7219 for J in Int range 0 .. 64 loop
7220 declare
7221 M : constant Uint := Uint_2 ** J;
7222
7223 begin
7224 exit when M = Align;
7225
7226 if M > Align then
7227 Error_Msg_N
7228 ("alignment value must be power of 2", Expr);
7229 return No_Uint;
7230 end if;
7231 end;
7232 end loop;
7233
7234 return Align;
7235 end if;
7236 end Get_Alignment_Value;
7237
d6f39728 7238 ----------------
7239 -- Initialize --
7240 ----------------
7241
7242 procedure Initialize is
7243 begin
7717ea00 7244 Address_Clause_Checks.Init;
7245 Independence_Checks.Init;
d6f39728 7246 Unchecked_Conversions.Init;
7247 end Initialize;
7248
7249 -------------------------
7250 -- Is_Operational_Item --
7251 -------------------------
7252
7253 function Is_Operational_Item (N : Node_Id) return Boolean is
7254 begin
7255 if Nkind (N) /= N_Attribute_Definition_Clause then
7256 return False;
7257 else
7258 declare
7259 Id : constant Attribute_Id := Get_Attribute_Id (Chars (N));
d6f39728 7260 begin
fdd294d1 7261 return Id = Attribute_Input
d6f39728 7262 or else Id = Attribute_Output
7263 or else Id = Attribute_Read
f15731c4 7264 or else Id = Attribute_Write
7265 or else Id = Attribute_External_Tag;
d6f39728 7266 end;
7267 end if;
7268 end Is_Operational_Item;
7269
7270 ------------------
7271 -- Minimum_Size --
7272 ------------------
7273
7274 function Minimum_Size
7275 (T : Entity_Id;
d5b349fa 7276 Biased : Boolean := False) return Nat
d6f39728 7277 is
7278 Lo : Uint := No_Uint;
7279 Hi : Uint := No_Uint;
7280 LoR : Ureal := No_Ureal;
7281 HiR : Ureal := No_Ureal;
7282 LoSet : Boolean := False;
7283 HiSet : Boolean := False;
7284 B : Uint;
7285 S : Nat;
7286 Ancest : Entity_Id;
f15731c4 7287 R_Typ : constant Entity_Id := Root_Type (T);
d6f39728 7288
7289 begin
7290 -- If bad type, return 0
7291
7292 if T = Any_Type then
7293 return 0;
7294
7295 -- For generic types, just return zero. There cannot be any legitimate
7296 -- need to know such a size, but this routine may be called with a
7297 -- generic type as part of normal processing.
7298
f15731c4 7299 elsif Is_Generic_Type (R_Typ)
7300 or else R_Typ = Any_Type
7301 then
d6f39728 7302 return 0;
7303
93735cb8 7304 -- Access types. Normally an access type cannot have a size smaller
7305 -- than the size of System.Address. The exception is on VMS, where
7306 -- we have short and long addresses, and it is possible for an access
7307 -- type to have a short address size (and thus be less than the size
7308 -- of System.Address itself). We simply skip the check for VMS, and
fdd294d1 7309 -- leave it to the back end to do the check.
d6f39728 7310
7311 elsif Is_Access_Type (T) then
93735cb8 7312 if OpenVMS_On_Target then
7313 return 0;
7314 else
7315 return System_Address_Size;
7316 end if;
d6f39728 7317
7318 -- Floating-point types
7319
7320 elsif Is_Floating_Point_Type (T) then
f15731c4 7321 return UI_To_Int (Esize (R_Typ));
d6f39728 7322
7323 -- Discrete types
7324
7325 elsif Is_Discrete_Type (T) then
7326
fdd294d1 7327 -- The following loop is looking for the nearest compile time known
7328 -- bounds following the ancestor subtype chain. The idea is to find
7329 -- the most restrictive known bounds information.
d6f39728 7330
7331 Ancest := T;
7332 loop
7333 if Ancest = Any_Type or else Etype (Ancest) = Any_Type then
7334 return 0;
7335 end if;
7336
7337 if not LoSet then
7338 if Compile_Time_Known_Value (Type_Low_Bound (Ancest)) then
7339 Lo := Expr_Rep_Value (Type_Low_Bound (Ancest));
7340 LoSet := True;
7341 exit when HiSet;
7342 end if;
7343 end if;
7344
7345 if not HiSet then
7346 if Compile_Time_Known_Value (Type_High_Bound (Ancest)) then
7347 Hi := Expr_Rep_Value (Type_High_Bound (Ancest));
7348 HiSet := True;
7349 exit when LoSet;
7350 end if;
7351 end if;
7352
7353 Ancest := Ancestor_Subtype (Ancest);
7354
7355 if No (Ancest) then
7356 Ancest := Base_Type (T);
7357
7358 if Is_Generic_Type (Ancest) then
7359 return 0;
7360 end if;
7361 end if;
7362 end loop;
7363
7364 -- Fixed-point types. We can't simply use Expr_Value to get the
fdd294d1 7365 -- Corresponding_Integer_Value values of the bounds, since these do not
7366 -- get set till the type is frozen, and this routine can be called
7367 -- before the type is frozen. Similarly the test for bounds being static
7368 -- needs to include the case where we have unanalyzed real literals for
7369 -- the same reason.
d6f39728 7370
7371 elsif Is_Fixed_Point_Type (T) then
7372
fdd294d1 7373 -- The following loop is looking for the nearest compile time known
7374 -- bounds following the ancestor subtype chain. The idea is to find
7375 -- the most restrictive known bounds information.
d6f39728 7376
7377 Ancest := T;
7378 loop
7379 if Ancest = Any_Type or else Etype (Ancest) = Any_Type then
7380 return 0;
7381 end if;
7382
3062c401 7383 -- Note: In the following two tests for LoSet and HiSet, it may
7384 -- seem redundant to test for N_Real_Literal here since normally
7385 -- one would assume that the test for the value being known at
7386 -- compile time includes this case. However, there is a glitch.
7387 -- If the real literal comes from folding a non-static expression,
7388 -- then we don't consider any non- static expression to be known
7389 -- at compile time if we are in configurable run time mode (needed
7390 -- in some cases to give a clearer definition of what is and what
7391 -- is not accepted). So the test is indeed needed. Without it, we
7392 -- would set neither Lo_Set nor Hi_Set and get an infinite loop.
7393
d6f39728 7394 if not LoSet then
7395 if Nkind (Type_Low_Bound (Ancest)) = N_Real_Literal
7396 or else Compile_Time_Known_Value (Type_Low_Bound (Ancest))
7397 then
7398 LoR := Expr_Value_R (Type_Low_Bound (Ancest));
7399 LoSet := True;
7400 exit when HiSet;
7401 end if;
7402 end if;
7403
7404 if not HiSet then
7405 if Nkind (Type_High_Bound (Ancest)) = N_Real_Literal
7406 or else Compile_Time_Known_Value (Type_High_Bound (Ancest))
7407 then
7408 HiR := Expr_Value_R (Type_High_Bound (Ancest));
7409 HiSet := True;
7410 exit when LoSet;
7411 end if;
7412 end if;
7413
7414 Ancest := Ancestor_Subtype (Ancest);
7415
7416 if No (Ancest) then
7417 Ancest := Base_Type (T);
7418
7419 if Is_Generic_Type (Ancest) then
7420 return 0;
7421 end if;
7422 end if;
7423 end loop;
7424
7425 Lo := UR_To_Uint (LoR / Small_Value (T));
7426 Hi := UR_To_Uint (HiR / Small_Value (T));
7427
7428 -- No other types allowed
7429
7430 else
7431 raise Program_Error;
7432 end if;
7433
2866d595 7434 -- Fall through with Hi and Lo set. Deal with biased case
d6f39728 7435
cc46ff4b 7436 if (Biased
7437 and then not Is_Fixed_Point_Type (T)
7438 and then not (Is_Enumeration_Type (T)
7439 and then Has_Non_Standard_Rep (T)))
d6f39728 7440 or else Has_Biased_Representation (T)
7441 then
7442 Hi := Hi - Lo;
7443 Lo := Uint_0;
7444 end if;
7445
7446 -- Signed case. Note that we consider types like range 1 .. -1 to be
fdd294d1 7447 -- signed for the purpose of computing the size, since the bounds have
1a34e48c 7448 -- to be accommodated in the base type.
d6f39728 7449
7450 if Lo < 0 or else Hi < 0 then
7451 S := 1;
7452 B := Uint_1;
7453
da253936 7454 -- S = size, B = 2 ** (size - 1) (can accommodate -B .. +(B - 1))
7455 -- Note that we accommodate the case where the bounds cross. This
d6f39728 7456 -- can happen either because of the way the bounds are declared
7457 -- or because of the algorithm in Freeze_Fixed_Point_Type.
7458
7459 while Lo < -B
7460 or else Hi < -B
7461 or else Lo >= B
7462 or else Hi >= B
7463 loop
7464 B := Uint_2 ** S;
7465 S := S + 1;
7466 end loop;
7467
7468 -- Unsigned case
7469
7470 else
7471 -- If both bounds are positive, make sure that both are represen-
7472 -- table in the case where the bounds are crossed. This can happen
7473 -- either because of the way the bounds are declared, or because of
7474 -- the algorithm in Freeze_Fixed_Point_Type.
7475
7476 if Lo > Hi then
7477 Hi := Lo;
7478 end if;
7479
da253936 7480 -- S = size, (can accommodate 0 .. (2**size - 1))
d6f39728 7481
7482 S := 0;
7483 while Hi >= Uint_2 ** S loop
7484 S := S + 1;
7485 end loop;
7486 end if;
7487
7488 return S;
7489 end Minimum_Size;
7490
44e4341e 7491 ---------------------------
7492 -- New_Stream_Subprogram --
7493 ---------------------------
d6f39728 7494
44e4341e 7495 procedure New_Stream_Subprogram
7496 (N : Node_Id;
7497 Ent : Entity_Id;
7498 Subp : Entity_Id;
7499 Nam : TSS_Name_Type)
d6f39728 7500 is
7501 Loc : constant Source_Ptr := Sloc (N);
9dfe12ae 7502 Sname : constant Name_Id := Make_TSS_Name (Base_Type (Ent), Nam);
f15731c4 7503 Subp_Id : Entity_Id;
d6f39728 7504 Subp_Decl : Node_Id;
7505 F : Entity_Id;
7506 Etyp : Entity_Id;
7507
44e4341e 7508 Defer_Declaration : constant Boolean :=
7509 Is_Tagged_Type (Ent) or else Is_Private_Type (Ent);
7510 -- For a tagged type, there is a declaration for each stream attribute
7511 -- at the freeze point, and we must generate only a completion of this
7512 -- declaration. We do the same for private types, because the full view
7513 -- might be tagged. Otherwise we generate a declaration at the point of
7514 -- the attribute definition clause.
7515
f15731c4 7516 function Build_Spec return Node_Id;
7517 -- Used for declaration and renaming declaration, so that this is
7518 -- treated as a renaming_as_body.
7519
7520 ----------------
7521 -- Build_Spec --
7522 ----------------
7523
d5b349fa 7524 function Build_Spec return Node_Id is
44e4341e 7525 Out_P : constant Boolean := (Nam = TSS_Stream_Read);
7526 Formals : List_Id;
7527 Spec : Node_Id;
7528 T_Ref : constant Node_Id := New_Reference_To (Etyp, Loc);
7529
f15731c4 7530 begin
9dfe12ae 7531 Subp_Id := Make_Defining_Identifier (Loc, Sname);
f15731c4 7532
44e4341e 7533 -- S : access Root_Stream_Type'Class
7534
7535 Formals := New_List (
7536 Make_Parameter_Specification (Loc,
7537 Defining_Identifier =>
7538 Make_Defining_Identifier (Loc, Name_S),
7539 Parameter_Type =>
7540 Make_Access_Definition (Loc,
7541 Subtype_Mark =>
7542 New_Reference_To (
7543 Designated_Type (Etype (F)), Loc))));
7544
7545 if Nam = TSS_Stream_Input then
7546 Spec := Make_Function_Specification (Loc,
7547 Defining_Unit_Name => Subp_Id,
7548 Parameter_Specifications => Formals,
7549 Result_Definition => T_Ref);
7550 else
7551 -- V : [out] T
f15731c4 7552
44e4341e 7553 Append_To (Formals,
7554 Make_Parameter_Specification (Loc,
7555 Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
7556 Out_Present => Out_P,
7557 Parameter_Type => T_Ref));
f15731c4 7558
d3ef794c 7559 Spec :=
7560 Make_Procedure_Specification (Loc,
7561 Defining_Unit_Name => Subp_Id,
7562 Parameter_Specifications => Formals);
44e4341e 7563 end if;
f15731c4 7564
44e4341e 7565 return Spec;
7566 end Build_Spec;
d6f39728 7567
44e4341e 7568 -- Start of processing for New_Stream_Subprogram
d6f39728 7569
44e4341e 7570 begin
7571 F := First_Formal (Subp);
7572
7573 if Ekind (Subp) = E_Procedure then
7574 Etyp := Etype (Next_Formal (F));
d6f39728 7575 else
44e4341e 7576 Etyp := Etype (Subp);
d6f39728 7577 end if;
f15731c4 7578
44e4341e 7579 -- Prepare subprogram declaration and insert it as an action on the
7580 -- clause node. The visibility for this entity is used to test for
7581 -- visibility of the attribute definition clause (in the sense of
7582 -- 8.3(23) as amended by AI-195).
9dfe12ae 7583
44e4341e 7584 if not Defer_Declaration then
f15731c4 7585 Subp_Decl :=
7586 Make_Subprogram_Declaration (Loc,
7587 Specification => Build_Spec);
44e4341e 7588
7589 -- For a tagged type, there is always a visible declaration for each
15ebb600 7590 -- stream TSS (it is a predefined primitive operation), and the
44e4341e 7591 -- completion of this declaration occurs at the freeze point, which is
7592 -- not always visible at places where the attribute definition clause is
7593 -- visible. So, we create a dummy entity here for the purpose of
7594 -- tracking the visibility of the attribute definition clause itself.
7595
7596 else
7597 Subp_Id :=
55868293 7598 Make_Defining_Identifier (Loc, New_External_Name (Sname, 'V'));
44e4341e 7599 Subp_Decl :=
7600 Make_Object_Declaration (Loc,
7601 Defining_Identifier => Subp_Id,
7602 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc));
f15731c4 7603 end if;
7604
44e4341e 7605 Insert_Action (N, Subp_Decl);
7606 Set_Entity (N, Subp_Id);
7607
d6f39728 7608 Subp_Decl :=
7609 Make_Subprogram_Renaming_Declaration (Loc,
f15731c4 7610 Specification => Build_Spec,
7611 Name => New_Reference_To (Subp, Loc));
d6f39728 7612
44e4341e 7613 if Defer_Declaration then
d6f39728 7614 Set_TSS (Base_Type (Ent), Subp_Id);
7615 else
7616 Insert_Action (N, Subp_Decl);
7617 Copy_TSS (Subp_Id, Base_Type (Ent));
7618 end if;
44e4341e 7619 end New_Stream_Subprogram;
d6f39728 7620
d6f39728 7621 ------------------------
7622 -- Rep_Item_Too_Early --
7623 ------------------------
7624
80d4fec4 7625 function Rep_Item_Too_Early (T : Entity_Id; N : Node_Id) return Boolean is
d6f39728 7626 begin
44e4341e 7627 -- Cannot apply non-operational rep items to generic types
d6f39728 7628
f15731c4 7629 if Is_Operational_Item (N) then
7630 return False;
7631
7632 elsif Is_Type (T)
d6f39728 7633 and then Is_Generic_Type (Root_Type (T))
7634 then
503f7fd3 7635 Error_Msg_N ("representation item not allowed for generic type", N);
d6f39728 7636 return True;
7637 end if;
7638
fdd294d1 7639 -- Otherwise check for incomplete type
d6f39728 7640
7641 if Is_Incomplete_Or_Private_Type (T)
7642 and then No (Underlying_Type (T))
d64221a7 7643 and then
7644 (Nkind (N) /= N_Pragma
60014bc9 7645 or else Get_Pragma_Id (N) /= Pragma_Import)
d6f39728 7646 then
7647 Error_Msg_N
7648 ("representation item must be after full type declaration", N);
7649 return True;
7650
1a34e48c 7651 -- If the type has incomplete components, a representation clause is
d6f39728 7652 -- illegal but stream attributes and Convention pragmas are correct.
7653
7654 elsif Has_Private_Component (T) then
f15731c4 7655 if Nkind (N) = N_Pragma then
d6f39728 7656 return False;
7657 else
7658 Error_Msg_N
7659 ("representation item must appear after type is fully defined",
7660 N);
7661 return True;
7662 end if;
7663 else
7664 return False;
7665 end if;
7666 end Rep_Item_Too_Early;
7667
7668 -----------------------
7669 -- Rep_Item_Too_Late --
7670 -----------------------
7671
7672 function Rep_Item_Too_Late
7673 (T : Entity_Id;
7674 N : Node_Id;
d5b349fa 7675 FOnly : Boolean := False) return Boolean
d6f39728 7676 is
7677 S : Entity_Id;
7678 Parent_Type : Entity_Id;
7679
7680 procedure Too_Late;
d53a018a 7681 -- Output the too late message. Note that this is not considered a
7682 -- serious error, since the effect is simply that we ignore the
7683 -- representation clause in this case.
7684
7685 --------------
7686 -- Too_Late --
7687 --------------
d6f39728 7688
7689 procedure Too_Late is
7690 begin
d53a018a 7691 Error_Msg_N ("|representation item appears too late!", N);
d6f39728 7692 end Too_Late;
7693
7694 -- Start of processing for Rep_Item_Too_Late
7695
7696 begin
7697 -- First make sure entity is not frozen (RM 13.1(9)). Exclude imported
7698 -- types, which may be frozen if they appear in a representation clause
7699 -- for a local type.
7700
7701 if Is_Frozen (T)
7702 and then not From_With_Type (T)
7703 then
7704 Too_Late;
7705 S := First_Subtype (T);
7706
7707 if Present (Freeze_Node (S)) then
7708 Error_Msg_NE
87d5c1d0 7709 ("?no more representation items for }", Freeze_Node (S), S);
d6f39728 7710 end if;
7711
7712 return True;
7713
7714 -- Check for case of non-tagged derived type whose parent either has
7715 -- primitive operations, or is a by reference type (RM 13.1(10)).
7716
7717 elsif Is_Type (T)
7718 and then not FOnly
7719 and then Is_Derived_Type (T)
7720 and then not Is_Tagged_Type (T)
7721 then
7722 Parent_Type := Etype (Base_Type (T));
7723
7724 if Has_Primitive_Operations (Parent_Type) then
7725 Too_Late;
7726 Error_Msg_NE
7727 ("primitive operations already defined for&!", N, Parent_Type);
7728 return True;
7729
7730 elsif Is_By_Reference_Type (Parent_Type) then
7731 Too_Late;
7732 Error_Msg_NE
7733 ("parent type & is a by reference type!", N, Parent_Type);
7734 return True;
7735 end if;
7736 end if;
7737
3062c401 7738 -- No error, link item into head of chain of rep items for the entity,
7739 -- but avoid chaining if we have an overloadable entity, and the pragma
7740 -- is one that can apply to multiple overloaded entities.
7741
7742 if Is_Overloadable (T)
7743 and then Nkind (N) = N_Pragma
3062c401 7744 then
fdd294d1 7745 declare
7746 Pname : constant Name_Id := Pragma_Name (N);
7747 begin
7748 if Pname = Name_Convention or else
7749 Pname = Name_Import or else
7750 Pname = Name_Export or else
7751 Pname = Name_External or else
7752 Pname = Name_Interface
7753 then
7754 return False;
7755 end if;
7756 end;
3062c401 7757 end if;
7758
fdd294d1 7759 Record_Rep_Item (T, N);
d6f39728 7760 return False;
7761 end Rep_Item_Too_Late;
7762
2072eaa9 7763 -------------------------------------
7764 -- Replace_Type_References_Generic --
7765 -------------------------------------
7766
7767 procedure Replace_Type_References_Generic (N : Node_Id; TName : Name_Id) is
7768
7769 function Replace_Node (N : Node_Id) return Traverse_Result;
7770 -- Processes a single node in the traversal procedure below, checking
7771 -- if node N should be replaced, and if so, doing the replacement.
7772
7773 procedure Replace_Type_Refs is new Traverse_Proc (Replace_Node);
7774 -- This instantiation provides the body of Replace_Type_References
7775
7776 ------------------
7777 -- Replace_Node --
7778 ------------------
7779
7780 function Replace_Node (N : Node_Id) return Traverse_Result is
7781 S : Entity_Id;
7782 P : Node_Id;
7783
7784 begin
7785 -- Case of identifier
7786
7787 if Nkind (N) = N_Identifier then
7788
7789 -- If not the type name, all done with this node
7790
7791 if Chars (N) /= TName then
7792 return Skip;
7793
7794 -- Otherwise do the replacement and we are done with this node
7795
7796 else
7797 Replace_Type_Reference (N);
7798 return Skip;
7799 end if;
7800
7801 -- Case of selected component (which is what a qualification
7802 -- looks like in the unanalyzed tree, which is what we have.
7803
7804 elsif Nkind (N) = N_Selected_Component then
7805
7806 -- If selector name is not our type, keeping going (we might
7807 -- still have an occurrence of the type in the prefix).
7808
7809 if Nkind (Selector_Name (N)) /= N_Identifier
7810 or else Chars (Selector_Name (N)) /= TName
7811 then
7812 return OK;
7813
7814 -- Selector name is our type, check qualification
7815
7816 else
7817 -- Loop through scopes and prefixes, doing comparison
7818
7819 S := Current_Scope;
7820 P := Prefix (N);
7821 loop
7822 -- Continue if no more scopes or scope with no name
7823
7824 if No (S) or else Nkind (S) not in N_Has_Chars then
7825 return OK;
7826 end if;
7827
7828 -- Do replace if prefix is an identifier matching the
7829 -- scope that we are currently looking at.
7830
7831 if Nkind (P) = N_Identifier
7832 and then Chars (P) = Chars (S)
7833 then
7834 Replace_Type_Reference (N);
7835 return Skip;
7836 end if;
7837
7838 -- Go check scope above us if prefix is itself of the
7839 -- form of a selected component, whose selector matches
7840 -- the scope we are currently looking at.
7841
7842 if Nkind (P) = N_Selected_Component
7843 and then Nkind (Selector_Name (P)) = N_Identifier
7844 and then Chars (Selector_Name (P)) = Chars (S)
7845 then
7846 S := Scope (S);
7847 P := Prefix (P);
7848
7849 -- For anything else, we don't have a match, so keep on
7850 -- going, there are still some weird cases where we may
7851 -- still have a replacement within the prefix.
7852
7853 else
7854 return OK;
7855 end if;
7856 end loop;
7857 end if;
7858
7859 -- Continue for any other node kind
7860
7861 else
7862 return OK;
7863 end if;
7864 end Replace_Node;
7865
7866 begin
7867 Replace_Type_Refs (N);
7868 end Replace_Type_References_Generic;
7869
d6f39728 7870 -------------------------
7871 -- Same_Representation --
7872 -------------------------
7873
7874 function Same_Representation (Typ1, Typ2 : Entity_Id) return Boolean is
7875 T1 : constant Entity_Id := Underlying_Type (Typ1);
7876 T2 : constant Entity_Id := Underlying_Type (Typ2);
7877
7878 begin
7879 -- A quick check, if base types are the same, then we definitely have
7880 -- the same representation, because the subtype specific representation
7881 -- attributes (Size and Alignment) do not affect representation from
7882 -- the point of view of this test.
7883
7884 if Base_Type (T1) = Base_Type (T2) then
7885 return True;
7886
7887 elsif Is_Private_Type (Base_Type (T2))
7888 and then Base_Type (T1) = Full_View (Base_Type (T2))
7889 then
7890 return True;
7891 end if;
7892
7893 -- Tagged types never have differing representations
7894
7895 if Is_Tagged_Type (T1) then
7896 return True;
7897 end if;
7898
7899 -- Representations are definitely different if conventions differ
7900
7901 if Convention (T1) /= Convention (T2) then
7902 return False;
7903 end if;
7904
7905 -- Representations are different if component alignments differ
7906
7907 if (Is_Record_Type (T1) or else Is_Array_Type (T1))
7908 and then
7909 (Is_Record_Type (T2) or else Is_Array_Type (T2))
7910 and then Component_Alignment (T1) /= Component_Alignment (T2)
7911 then
7912 return False;
7913 end if;
7914
7915 -- For arrays, the only real issue is component size. If we know the
7916 -- component size for both arrays, and it is the same, then that's
7917 -- good enough to know we don't have a change of representation.
7918
7919 if Is_Array_Type (T1) then
7920 if Known_Component_Size (T1)
7921 and then Known_Component_Size (T2)
7922 and then Component_Size (T1) = Component_Size (T2)
7923 then
9f1130cc 7924 if VM_Target = No_VM then
7925 return True;
7926
7927 -- In VM targets the representation of arrays with aliased
7928 -- components differs from arrays with non-aliased components
7929
7930 else
7931 return Has_Aliased_Components (Base_Type (T1))
0ba3592b 7932 =
7933 Has_Aliased_Components (Base_Type (T2));
9f1130cc 7934 end if;
d6f39728 7935 end if;
7936 end if;
7937
7938 -- Types definitely have same representation if neither has non-standard
7939 -- representation since default representations are always consistent.
7940 -- If only one has non-standard representation, and the other does not,
7941 -- then we consider that they do not have the same representation. They
7942 -- might, but there is no way of telling early enough.
7943
7944 if Has_Non_Standard_Rep (T1) then
7945 if not Has_Non_Standard_Rep (T2) then
7946 return False;
7947 end if;
7948 else
7949 return not Has_Non_Standard_Rep (T2);
7950 end if;
7951
fdd294d1 7952 -- Here the two types both have non-standard representation, and we need
7953 -- to determine if they have the same non-standard representation.
d6f39728 7954
7955 -- For arrays, we simply need to test if the component sizes are the
7956 -- same. Pragma Pack is reflected in modified component sizes, so this
7957 -- check also deals with pragma Pack.
7958
7959 if Is_Array_Type (T1) then
7960 return Component_Size (T1) = Component_Size (T2);
7961
7962 -- Tagged types always have the same representation, because it is not
7963 -- possible to specify different representations for common fields.
7964
7965 elsif Is_Tagged_Type (T1) then
7966 return True;
7967
7968 -- Case of record types
7969
7970 elsif Is_Record_Type (T1) then
7971
7972 -- Packed status must conform
7973
7974 if Is_Packed (T1) /= Is_Packed (T2) then
7975 return False;
7976
7977 -- Otherwise we must check components. Typ2 maybe a constrained
7978 -- subtype with fewer components, so we compare the components
7979 -- of the base types.
7980
7981 else
7982 Record_Case : declare
7983 CD1, CD2 : Entity_Id;
7984
7985 function Same_Rep return Boolean;
7986 -- CD1 and CD2 are either components or discriminants. This
7987 -- function tests whether the two have the same representation
7988
80d4fec4 7989 --------------
7990 -- Same_Rep --
7991 --------------
7992
d6f39728 7993 function Same_Rep return Boolean is
7994 begin
7995 if No (Component_Clause (CD1)) then
7996 return No (Component_Clause (CD2));
7997
7998 else
7999 return
8000 Present (Component_Clause (CD2))
8001 and then
8002 Component_Bit_Offset (CD1) = Component_Bit_Offset (CD2)
8003 and then
8004 Esize (CD1) = Esize (CD2);
8005 end if;
8006 end Same_Rep;
8007
1e35409d 8008 -- Start of processing for Record_Case
d6f39728 8009
8010 begin
8011 if Has_Discriminants (T1) then
8012 CD1 := First_Discriminant (T1);
8013 CD2 := First_Discriminant (T2);
8014
9dfe12ae 8015 -- The number of discriminants may be different if the
8016 -- derived type has fewer (constrained by values). The
8017 -- invisible discriminants retain the representation of
8018 -- the original, so the discrepancy does not per se
8019 -- indicate a different representation.
8020
8021 while Present (CD1)
8022 and then Present (CD2)
8023 loop
d6f39728 8024 if not Same_Rep then
8025 return False;
8026 else
8027 Next_Discriminant (CD1);
8028 Next_Discriminant (CD2);
8029 end if;
8030 end loop;
8031 end if;
8032
8033 CD1 := First_Component (Underlying_Type (Base_Type (T1)));
8034 CD2 := First_Component (Underlying_Type (Base_Type (T2)));
8035
8036 while Present (CD1) loop
8037 if not Same_Rep then
8038 return False;
8039 else
8040 Next_Component (CD1);
8041 Next_Component (CD2);
8042 end if;
8043 end loop;
8044
8045 return True;
8046 end Record_Case;
8047 end if;
8048
8049 -- For enumeration types, we must check each literal to see if the
8050 -- representation is the same. Note that we do not permit enumeration
1a34e48c 8051 -- representation clauses for Character and Wide_Character, so these
d6f39728 8052 -- cases were already dealt with.
8053
8054 elsif Is_Enumeration_Type (T1) then
d6f39728 8055 Enumeration_Case : declare
8056 L1, L2 : Entity_Id;
8057
8058 begin
8059 L1 := First_Literal (T1);
8060 L2 := First_Literal (T2);
8061
8062 while Present (L1) loop
8063 if Enumeration_Rep (L1) /= Enumeration_Rep (L2) then
8064 return False;
8065 else
8066 Next_Literal (L1);
8067 Next_Literal (L2);
8068 end if;
8069 end loop;
8070
8071 return True;
8072
8073 end Enumeration_Case;
8074
8075 -- Any other types have the same representation for these purposes
8076
8077 else
8078 return True;
8079 end if;
d6f39728 8080 end Same_Representation;
8081
b77e4501 8082 ----------------
8083 -- Set_Biased --
8084 ----------------
8085
8086 procedure Set_Biased
8087 (E : Entity_Id;
8088 N : Node_Id;
8089 Msg : String;
8090 Biased : Boolean := True)
8091 is
8092 begin
8093 if Biased then
8094 Set_Has_Biased_Representation (E);
8095
8096 if Warn_On_Biased_Representation then
8097 Error_Msg_NE
8098 ("?" & Msg & " forces biased representation for&", N, E);
8099 end if;
8100 end if;
8101 end Set_Biased;
8102
d6f39728 8103 --------------------
8104 -- Set_Enum_Esize --
8105 --------------------
8106
8107 procedure Set_Enum_Esize (T : Entity_Id) is
8108 Lo : Uint;
8109 Hi : Uint;
8110 Sz : Nat;
8111
8112 begin
8113 Init_Alignment (T);
8114
8115 -- Find the minimum standard size (8,16,32,64) that fits
8116
8117 Lo := Enumeration_Rep (Entity (Type_Low_Bound (T)));
8118 Hi := Enumeration_Rep (Entity (Type_High_Bound (T)));
8119
8120 if Lo < 0 then
8121 if Lo >= -Uint_2**07 and then Hi < Uint_2**07 then
f15731c4 8122 Sz := Standard_Character_Size; -- May be > 8 on some targets
d6f39728 8123
8124 elsif Lo >= -Uint_2**15 and then Hi < Uint_2**15 then
8125 Sz := 16;
8126
8127 elsif Lo >= -Uint_2**31 and then Hi < Uint_2**31 then
8128 Sz := 32;
8129
8130 else pragma Assert (Lo >= -Uint_2**63 and then Hi < Uint_2**63);
8131 Sz := 64;
8132 end if;
8133
8134 else
8135 if Hi < Uint_2**08 then
f15731c4 8136 Sz := Standard_Character_Size; -- May be > 8 on some targets
d6f39728 8137
8138 elsif Hi < Uint_2**16 then
8139 Sz := 16;
8140
8141 elsif Hi < Uint_2**32 then
8142 Sz := 32;
8143
8144 else pragma Assert (Hi < Uint_2**63);
8145 Sz := 64;
8146 end if;
8147 end if;
8148
8149 -- That minimum is the proper size unless we have a foreign convention
8150 -- and the size required is 32 or less, in which case we bump the size
8151 -- up to 32. This is required for C and C++ and seems reasonable for
8152 -- all other foreign conventions.
8153
8154 if Has_Foreign_Convention (T)
8155 and then Esize (T) < Standard_Integer_Size
8156 then
8157 Init_Esize (T, Standard_Integer_Size);
d6f39728 8158 else
8159 Init_Esize (T, Sz);
8160 end if;
d6f39728 8161 end Set_Enum_Esize;
8162
83f8f0a6 8163 ------------------------------
8164 -- Validate_Address_Clauses --
8165 ------------------------------
8166
8167 procedure Validate_Address_Clauses is
8168 begin
8169 for J in Address_Clause_Checks.First .. Address_Clause_Checks.Last loop
8170 declare
8171 ACCR : Address_Clause_Check_Record
8172 renames Address_Clause_Checks.Table (J);
8173
d6da7448 8174 Expr : Node_Id;
8175
83f8f0a6 8176 X_Alignment : Uint;
8177 Y_Alignment : Uint;
8178
8179 X_Size : Uint;
8180 Y_Size : Uint;
8181
8182 begin
8183 -- Skip processing of this entry if warning already posted
8184
8185 if not Address_Warning_Posted (ACCR.N) then
8186
d6da7448 8187 Expr := Original_Node (Expression (ACCR.N));
83f8f0a6 8188
d6da7448 8189 -- Get alignments
83f8f0a6 8190
d6da7448 8191 X_Alignment := Alignment (ACCR.X);
8192 Y_Alignment := Alignment (ACCR.Y);
83f8f0a6 8193
8194 -- Similarly obtain sizes
8195
d6da7448 8196 X_Size := Esize (ACCR.X);
8197 Y_Size := Esize (ACCR.Y);
83f8f0a6 8198
8199 -- Check for large object overlaying smaller one
8200
8201 if Y_Size > Uint_0
8202 and then X_Size > Uint_0
8203 and then X_Size > Y_Size
8204 then
d6da7448 8205 Error_Msg_NE
8206 ("?& overlays smaller object", ACCR.N, ACCR.X);
83f8f0a6 8207 Error_Msg_N
d6da7448 8208 ("\?program execution may be erroneous", ACCR.N);
83f8f0a6 8209 Error_Msg_Uint_1 := X_Size;
8210 Error_Msg_NE
8211 ("\?size of & is ^", ACCR.N, ACCR.X);
8212 Error_Msg_Uint_1 := Y_Size;
8213 Error_Msg_NE
8214 ("\?size of & is ^", ACCR.N, ACCR.Y);
8215
d6da7448 8216 -- Check for inadequate alignment, both of the base object
8217 -- and of the offset, if any.
83f8f0a6 8218
d6da7448 8219 -- Note: we do not check the alignment if we gave a size
8220 -- warning, since it would likely be redundant.
83f8f0a6 8221
8222 elsif Y_Alignment /= Uint_0
d6da7448 8223 and then (Y_Alignment < X_Alignment
8224 or else (ACCR.Off
8225 and then
8226 Nkind (Expr) = N_Attribute_Reference
8227 and then
8228 Attribute_Name (Expr) = Name_Address
8229 and then
8230 Has_Compatible_Alignment
8231 (ACCR.X, Prefix (Expr))
8232 /= Known_Compatible))
83f8f0a6 8233 then
8234 Error_Msg_NE
8235 ("?specified address for& may be inconsistent "
8236 & "with alignment",
8237 ACCR.N, ACCR.X);
8238 Error_Msg_N
8239 ("\?program execution may be erroneous (RM 13.3(27))",
8240 ACCR.N);
8241 Error_Msg_Uint_1 := X_Alignment;
8242 Error_Msg_NE
8243 ("\?alignment of & is ^",
8244 ACCR.N, ACCR.X);
8245 Error_Msg_Uint_1 := Y_Alignment;
8246 Error_Msg_NE
8247 ("\?alignment of & is ^",
8248 ACCR.N, ACCR.Y);
d6da7448 8249 if Y_Alignment >= X_Alignment then
8250 Error_Msg_N
8251 ("\?but offset is not multiple of alignment",
8252 ACCR.N);
8253 end if;
83f8f0a6 8254 end if;
8255 end if;
8256 end;
8257 end loop;
8258 end Validate_Address_Clauses;
8259
7717ea00 8260 ---------------------------
8261 -- Validate_Independence --
8262 ---------------------------
8263
8264 procedure Validate_Independence is
8265 SU : constant Uint := UI_From_Int (System_Storage_Unit);
8266 N : Node_Id;
8267 E : Entity_Id;
8268 IC : Boolean;
8269 Comp : Entity_Id;
8270 Addr : Node_Id;
8271 P : Node_Id;
8272
8273 procedure Check_Array_Type (Atyp : Entity_Id);
8274 -- Checks if the array type Atyp has independent components, and
8275 -- if not, outputs an appropriate set of error messages.
8276
8277 procedure No_Independence;
8278 -- Output message that independence cannot be guaranteed
8279
8280 function OK_Component (C : Entity_Id) return Boolean;
8281 -- Checks one component to see if it is independently accessible, and
8282 -- if so yields True, otherwise yields False if independent access
8283 -- cannot be guaranteed. This is a conservative routine, it only
8284 -- returns True if it knows for sure, it returns False if it knows
8285 -- there is a problem, or it cannot be sure there is no problem.
8286
8287 procedure Reason_Bad_Component (C : Entity_Id);
8288 -- Outputs continuation message if a reason can be determined for
8289 -- the component C being bad.
8290
8291 ----------------------
8292 -- Check_Array_Type --
8293 ----------------------
8294
8295 procedure Check_Array_Type (Atyp : Entity_Id) is
8296 Ctyp : constant Entity_Id := Component_Type (Atyp);
8297
8298 begin
8299 -- OK if no alignment clause, no pack, and no component size
8300
8301 if not Has_Component_Size_Clause (Atyp)
8302 and then not Has_Alignment_Clause (Atyp)
8303 and then not Is_Packed (Atyp)
8304 then
8305 return;
8306 end if;
8307
8308 -- Check actual component size
8309
8310 if not Known_Component_Size (Atyp)
8311 or else not (Addressable (Component_Size (Atyp))
8312 and then Component_Size (Atyp) < 64)
8313 or else Component_Size (Atyp) mod Esize (Ctyp) /= 0
8314 then
8315 No_Independence;
8316
8317 -- Bad component size, check reason
8318
8319 if Has_Component_Size_Clause (Atyp) then
8320 P :=
8321 Get_Attribute_Definition_Clause
8322 (Atyp, Attribute_Component_Size);
8323
8324 if Present (P) then
8325 Error_Msg_Sloc := Sloc (P);
8326 Error_Msg_N ("\because of Component_Size clause#", N);
8327 return;
8328 end if;
8329 end if;
8330
8331 if Is_Packed (Atyp) then
8332 P := Get_Rep_Pragma (Atyp, Name_Pack);
8333
8334 if Present (P) then
8335 Error_Msg_Sloc := Sloc (P);
8336 Error_Msg_N ("\because of pragma Pack#", N);
8337 return;
8338 end if;
8339 end if;
8340
8341 -- No reason found, just return
8342
8343 return;
8344 end if;
8345
8346 -- Array type is OK independence-wise
8347
8348 return;
8349 end Check_Array_Type;
8350
8351 ---------------------
8352 -- No_Independence --
8353 ---------------------
8354
8355 procedure No_Independence is
8356 begin
8357 if Pragma_Name (N) = Name_Independent then
8358 Error_Msg_NE
8359 ("independence cannot be guaranteed for&", N, E);
8360 else
8361 Error_Msg_NE
8362 ("independent components cannot be guaranteed for&", N, E);
8363 end if;
8364 end No_Independence;
8365
8366 ------------------
8367 -- OK_Component --
8368 ------------------
8369
8370 function OK_Component (C : Entity_Id) return Boolean is
8371 Rec : constant Entity_Id := Scope (C);
8372 Ctyp : constant Entity_Id := Etype (C);
8373
8374 begin
8375 -- OK if no component clause, no Pack, and no alignment clause
8376
8377 if No (Component_Clause (C))
8378 and then not Is_Packed (Rec)
8379 and then not Has_Alignment_Clause (Rec)
8380 then
8381 return True;
8382 end if;
8383
8384 -- Here we look at the actual component layout. A component is
8385 -- addressable if its size is a multiple of the Esize of the
8386 -- component type, and its starting position in the record has
8387 -- appropriate alignment, and the record itself has appropriate
8388 -- alignment to guarantee the component alignment.
8389
8390 -- Make sure sizes are static, always assume the worst for any
8391 -- cases where we cannot check static values.
8392
8393 if not (Known_Static_Esize (C)
8394 and then Known_Static_Esize (Ctyp))
8395 then
8396 return False;
8397 end if;
8398
8399 -- Size of component must be addressable or greater than 64 bits
8400 -- and a multiple of bytes.
8401
8402 if not Addressable (Esize (C))
8403 and then Esize (C) < Uint_64
8404 then
8405 return False;
8406 end if;
8407
8408 -- Check size is proper multiple
8409
8410 if Esize (C) mod Esize (Ctyp) /= 0 then
8411 return False;
8412 end if;
8413
8414 -- Check alignment of component is OK
8415
8416 if not Known_Component_Bit_Offset (C)
8417 or else Component_Bit_Offset (C) < Uint_0
8418 or else Component_Bit_Offset (C) mod Esize (Ctyp) /= 0
8419 then
8420 return False;
8421 end if;
8422
8423 -- Check alignment of record type is OK
8424
8425 if not Known_Alignment (Rec)
8426 or else (Alignment (Rec) * SU) mod Esize (Ctyp) /= 0
8427 then
8428 return False;
8429 end if;
8430
8431 -- All tests passed, component is addressable
8432
8433 return True;
8434 end OK_Component;
8435
8436 --------------------------
8437 -- Reason_Bad_Component --
8438 --------------------------
8439
8440 procedure Reason_Bad_Component (C : Entity_Id) is
8441 Rec : constant Entity_Id := Scope (C);
8442 Ctyp : constant Entity_Id := Etype (C);
8443
8444 begin
8445 -- If component clause present assume that's the problem
8446
8447 if Present (Component_Clause (C)) then
8448 Error_Msg_Sloc := Sloc (Component_Clause (C));
8449 Error_Msg_N ("\because of Component_Clause#", N);
8450 return;
8451 end if;
8452
8453 -- If pragma Pack clause present, assume that's the problem
8454
8455 if Is_Packed (Rec) then
8456 P := Get_Rep_Pragma (Rec, Name_Pack);
8457
8458 if Present (P) then
8459 Error_Msg_Sloc := Sloc (P);
8460 Error_Msg_N ("\because of pragma Pack#", N);
8461 return;
8462 end if;
8463 end if;
8464
8465 -- See if record has bad alignment clause
8466
8467 if Has_Alignment_Clause (Rec)
8468 and then Known_Alignment (Rec)
8469 and then (Alignment (Rec) * SU) mod Esize (Ctyp) /= 0
8470 then
8471 P := Get_Attribute_Definition_Clause (Rec, Attribute_Alignment);
8472
8473 if Present (P) then
8474 Error_Msg_Sloc := Sloc (P);
8475 Error_Msg_N ("\because of Alignment clause#", N);
8476 end if;
8477 end if;
8478
8479 -- Couldn't find a reason, so return without a message
8480
8481 return;
8482 end Reason_Bad_Component;
8483
8484 -- Start of processing for Validate_Independence
8485
8486 begin
8487 for J in Independence_Checks.First .. Independence_Checks.Last loop
8488 N := Independence_Checks.Table (J).N;
8489 E := Independence_Checks.Table (J).E;
8490 IC := Pragma_Name (N) = Name_Independent_Components;
8491
8492 -- Deal with component case
8493
8494 if Ekind (E) = E_Discriminant or else Ekind (E) = E_Component then
8495 if not OK_Component (E) then
8496 No_Independence;
8497 Reason_Bad_Component (E);
8498 goto Continue;
8499 end if;
8500 end if;
8501
8502 -- Deal with record with Independent_Components
8503
8504 if IC and then Is_Record_Type (E) then
8505 Comp := First_Component_Or_Discriminant (E);
8506 while Present (Comp) loop
8507 if not OK_Component (Comp) then
8508 No_Independence;
8509 Reason_Bad_Component (Comp);
8510 goto Continue;
8511 end if;
8512
8513 Next_Component_Or_Discriminant (Comp);
8514 end loop;
8515 end if;
8516
8517 -- Deal with address clause case
8518
8519 if Is_Object (E) then
8520 Addr := Address_Clause (E);
8521
8522 if Present (Addr) then
8523 No_Independence;
8524 Error_Msg_Sloc := Sloc (Addr);
8525 Error_Msg_N ("\because of Address clause#", N);
8526 goto Continue;
8527 end if;
8528 end if;
8529
8530 -- Deal with independent components for array type
8531
8532 if IC and then Is_Array_Type (E) then
8533 Check_Array_Type (E);
8534 end if;
8535
8536 -- Deal with independent components for array object
8537
8538 if IC and then Is_Object (E) and then Is_Array_Type (Etype (E)) then
8539 Check_Array_Type (Etype (E));
8540 end if;
8541
8542 <<Continue>> null;
8543 end loop;
8544 end Validate_Independence;
8545
d6f39728 8546 -----------------------------------
8547 -- Validate_Unchecked_Conversion --
8548 -----------------------------------
8549
8550 procedure Validate_Unchecked_Conversion
8551 (N : Node_Id;
8552 Act_Unit : Entity_Id)
8553 is
8554 Source : Entity_Id;
8555 Target : Entity_Id;
8556 Vnode : Node_Id;
8557
8558 begin
8559 -- Obtain source and target types. Note that we call Ancestor_Subtype
8560 -- here because the processing for generic instantiation always makes
8561 -- subtypes, and we want the original frozen actual types.
8562
8563 -- If we are dealing with private types, then do the check on their
8564 -- fully declared counterparts if the full declarations have been
8565 -- encountered (they don't have to be visible, but they must exist!)
8566
8567 Source := Ancestor_Subtype (Etype (First_Formal (Act_Unit)));
8568
8569 if Is_Private_Type (Source)
8570 and then Present (Underlying_Type (Source))
8571 then
8572 Source := Underlying_Type (Source);
8573 end if;
8574
8575 Target := Ancestor_Subtype (Etype (Act_Unit));
8576
fdd294d1 8577 -- If either type is generic, the instantiation happens within a generic
8578 -- unit, and there is nothing to check. The proper check
d6f39728 8579 -- will happen when the enclosing generic is instantiated.
8580
8581 if Is_Generic_Type (Source) or else Is_Generic_Type (Target) then
8582 return;
8583 end if;
8584
8585 if Is_Private_Type (Target)
8586 and then Present (Underlying_Type (Target))
8587 then
8588 Target := Underlying_Type (Target);
8589 end if;
8590
8591 -- Source may be unconstrained array, but not target
8592
8593 if Is_Array_Type (Target)
8594 and then not Is_Constrained (Target)
8595 then
8596 Error_Msg_N
8597 ("unchecked conversion to unconstrained array not allowed", N);
8598 return;
8599 end if;
8600
fbc67f84 8601 -- Warn if conversion between two different convention pointers
8602
8603 if Is_Access_Type (Target)
8604 and then Is_Access_Type (Source)
8605 and then Convention (Target) /= Convention (Source)
8606 and then Warn_On_Unchecked_Conversion
8607 then
fdd294d1 8608 -- Give warnings for subprogram pointers only on most targets. The
8609 -- exception is VMS, where data pointers can have different lengths
8610 -- depending on the pointer convention.
8611
8612 if Is_Access_Subprogram_Type (Target)
8613 or else Is_Access_Subprogram_Type (Source)
8614 or else OpenVMS_On_Target
8615 then
8616 Error_Msg_N
8617 ("?conversion between pointers with different conventions!", N);
8618 end if;
fbc67f84 8619 end if;
8620
3062c401 8621 -- Warn if one of the operands is Ada.Calendar.Time. Do not emit a
8622 -- warning when compiling GNAT-related sources.
8623
8624 if Warn_On_Unchecked_Conversion
8625 and then not In_Predefined_Unit (N)
8626 and then RTU_Loaded (Ada_Calendar)
8627 and then
8628 (Chars (Source) = Name_Time
8629 or else
8630 Chars (Target) = Name_Time)
8631 then
8632 -- If Ada.Calendar is loaded and the name of one of the operands is
8633 -- Time, there is a good chance that this is Ada.Calendar.Time.
8634
8635 declare
8636 Calendar_Time : constant Entity_Id :=
8637 Full_View (RTE (RO_CA_Time));
8638 begin
8639 pragma Assert (Present (Calendar_Time));
8640
8641 if Source = Calendar_Time
8642 or else Target = Calendar_Time
8643 then
8644 Error_Msg_N
8645 ("?representation of 'Time values may change between " &
8646 "'G'N'A'T versions", N);
8647 end if;
8648 end;
8649 end if;
8650
fdd294d1 8651 -- Make entry in unchecked conversion table for later processing by
8652 -- Validate_Unchecked_Conversions, which will check sizes and alignments
8653 -- (using values set by the back-end where possible). This is only done
8654 -- if the appropriate warning is active.
d6f39728 8655
9dfe12ae 8656 if Warn_On_Unchecked_Conversion then
8657 Unchecked_Conversions.Append
8658 (New_Val => UC_Entry'
299480f9 8659 (Eloc => Sloc (N),
9dfe12ae 8660 Source => Source,
8661 Target => Target));
8662
8663 -- If both sizes are known statically now, then back end annotation
8664 -- is not required to do a proper check but if either size is not
8665 -- known statically, then we need the annotation.
8666
8667 if Known_Static_RM_Size (Source)
8668 and then Known_Static_RM_Size (Target)
8669 then
8670 null;
8671 else
8672 Back_Annotate_Rep_Info := True;
8673 end if;
8674 end if;
d6f39728 8675
fdd294d1 8676 -- If unchecked conversion to access type, and access type is declared
8677 -- in the same unit as the unchecked conversion, then set the
8678 -- No_Strict_Aliasing flag (no strict aliasing is implicit in this
8679 -- situation).
28ed91d4 8680
8681 if Is_Access_Type (Target) and then
8682 In_Same_Source_Unit (Target, N)
8683 then
8684 Set_No_Strict_Aliasing (Implementation_Base_Type (Target));
8685 end if;
3d875462 8686
8687 -- Generate N_Validate_Unchecked_Conversion node for back end in
8688 -- case the back end needs to perform special validation checks.
8689
fdd294d1 8690 -- Shouldn't this be in Exp_Ch13, since the check only gets done
3d875462 8691 -- if we have full expansion and the back end is called ???
8692
8693 Vnode :=
8694 Make_Validate_Unchecked_Conversion (Sloc (N));
8695 Set_Source_Type (Vnode, Source);
8696 Set_Target_Type (Vnode, Target);
8697
fdd294d1 8698 -- If the unchecked conversion node is in a list, just insert before it.
8699 -- If not we have some strange case, not worth bothering about.
3d875462 8700
8701 if Is_List_Member (N) then
d6f39728 8702 Insert_After (N, Vnode);
8703 end if;
8704 end Validate_Unchecked_Conversion;
8705
8706 ------------------------------------
8707 -- Validate_Unchecked_Conversions --
8708 ------------------------------------
8709
8710 procedure Validate_Unchecked_Conversions is
8711 begin
8712 for N in Unchecked_Conversions.First .. Unchecked_Conversions.Last loop
8713 declare
8714 T : UC_Entry renames Unchecked_Conversions.Table (N);
8715
299480f9 8716 Eloc : constant Source_Ptr := T.Eloc;
8717 Source : constant Entity_Id := T.Source;
8718 Target : constant Entity_Id := T.Target;
d6f39728 8719
8720 Source_Siz : Uint;
8721 Target_Siz : Uint;
8722
8723 begin
fdd294d1 8724 -- This validation check, which warns if we have unequal sizes for
8725 -- unchecked conversion, and thus potentially implementation
d6f39728 8726 -- dependent semantics, is one of the few occasions on which we
fdd294d1 8727 -- use the official RM size instead of Esize. See description in
8728 -- Einfo "Handling of Type'Size Values" for details.
d6f39728 8729
f15731c4 8730 if Serious_Errors_Detected = 0
d6f39728 8731 and then Known_Static_RM_Size (Source)
8732 and then Known_Static_RM_Size (Target)
f25f4252 8733
8734 -- Don't do the check if warnings off for either type, note the
8735 -- deliberate use of OR here instead of OR ELSE to get the flag
8736 -- Warnings_Off_Used set for both types if appropriate.
8737
8738 and then not (Has_Warnings_Off (Source)
8739 or
8740 Has_Warnings_Off (Target))
d6f39728 8741 then
8742 Source_Siz := RM_Size (Source);
8743 Target_Siz := RM_Size (Target);
8744
8745 if Source_Siz /= Target_Siz then
299480f9 8746 Error_Msg
fbc67f84 8747 ("?types for unchecked conversion have different sizes!",
299480f9 8748 Eloc);
d6f39728 8749
8750 if All_Errors_Mode then
8751 Error_Msg_Name_1 := Chars (Source);
8752 Error_Msg_Uint_1 := Source_Siz;
8753 Error_Msg_Name_2 := Chars (Target);
8754 Error_Msg_Uint_2 := Target_Siz;
299480f9 8755 Error_Msg ("\size of % is ^, size of % is ^?", Eloc);
d6f39728 8756
8757 Error_Msg_Uint_1 := UI_Abs (Source_Siz - Target_Siz);
8758
8759 if Is_Discrete_Type (Source)
8760 and then Is_Discrete_Type (Target)
8761 then
8762 if Source_Siz > Target_Siz then
299480f9 8763 Error_Msg
fbc67f84 8764 ("\?^ high order bits of source will be ignored!",
299480f9 8765 Eloc);
d6f39728 8766
9dfe12ae 8767 elsif Is_Unsigned_Type (Source) then
299480f9 8768 Error_Msg
fbc67f84 8769 ("\?source will be extended with ^ high order " &
299480f9 8770 "zero bits?!", Eloc);
d6f39728 8771
8772 else
299480f9 8773 Error_Msg
fbc67f84 8774 ("\?source will be extended with ^ high order " &
8775 "sign bits!",
299480f9 8776 Eloc);
d6f39728 8777 end if;
8778
8779 elsif Source_Siz < Target_Siz then
8780 if Is_Discrete_Type (Target) then
8781 if Bytes_Big_Endian then
299480f9 8782 Error_Msg
fbc67f84 8783 ("\?target value will include ^ undefined " &
8784 "low order bits!",
299480f9 8785 Eloc);
d6f39728 8786 else
299480f9 8787 Error_Msg
fbc67f84 8788 ("\?target value will include ^ undefined " &
8789 "high order bits!",
299480f9 8790 Eloc);
d6f39728 8791 end if;
8792
8793 else
299480f9 8794 Error_Msg
fbc67f84 8795 ("\?^ trailing bits of target value will be " &
299480f9 8796 "undefined!", Eloc);
d6f39728 8797 end if;
8798
8799 else pragma Assert (Source_Siz > Target_Siz);
299480f9 8800 Error_Msg
fbc67f84 8801 ("\?^ trailing bits of source will be ignored!",
299480f9 8802 Eloc);
d6f39728 8803 end if;
8804 end if;
d6f39728 8805 end if;
8806 end if;
8807
8808 -- If both types are access types, we need to check the alignment.
8809 -- If the alignment of both is specified, we can do it here.
8810
f15731c4 8811 if Serious_Errors_Detected = 0
d6f39728 8812 and then Ekind (Source) in Access_Kind
8813 and then Ekind (Target) in Access_Kind
8814 and then Target_Strict_Alignment
8815 and then Present (Designated_Type (Source))
8816 and then Present (Designated_Type (Target))
8817 then
8818 declare
8819 D_Source : constant Entity_Id := Designated_Type (Source);
8820 D_Target : constant Entity_Id := Designated_Type (Target);
8821
8822 begin
8823 if Known_Alignment (D_Source)
8824 and then Known_Alignment (D_Target)
8825 then
8826 declare
8827 Source_Align : constant Uint := Alignment (D_Source);
8828 Target_Align : constant Uint := Alignment (D_Target);
8829
8830 begin
8831 if Source_Align < Target_Align
8832 and then not Is_Tagged_Type (D_Source)
f25f4252 8833
8834 -- Suppress warning if warnings suppressed on either
8835 -- type or either designated type. Note the use of
8836 -- OR here instead of OR ELSE. That is intentional,
8837 -- we would like to set flag Warnings_Off_Used in
8838 -- all types for which warnings are suppressed.
8839
8840 and then not (Has_Warnings_Off (D_Source)
8841 or
8842 Has_Warnings_Off (D_Target)
8843 or
8844 Has_Warnings_Off (Source)
8845 or
8846 Has_Warnings_Off (Target))
d6f39728 8847 then
d6f39728 8848 Error_Msg_Uint_1 := Target_Align;
8849 Error_Msg_Uint_2 := Source_Align;
299480f9 8850 Error_Msg_Node_1 := D_Target;
d6f39728 8851 Error_Msg_Node_2 := D_Source;
299480f9 8852 Error_Msg
fbc67f84 8853 ("?alignment of & (^) is stricter than " &
299480f9 8854 "alignment of & (^)!", Eloc);
f25f4252 8855 Error_Msg
8856 ("\?resulting access value may have invalid " &
8857 "alignment!", Eloc);
d6f39728 8858 end if;
8859 end;
8860 end if;
8861 end;
8862 end if;
8863 end;
8864 end loop;
8865 end Validate_Unchecked_Conversions;
8866
d6f39728 8867end Sem_Ch13;