]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ada/sem_ch13.adb
2013-10-14 Hristian Kirtchev <kirtchev@adacore.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-- --
57cd943b 9-- Copyright (C) 1992-2013, 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;
175a6969 29with Debug; use Debug;
d6f39728 30with Einfo; use Einfo;
d00681a7 31with Elists; use Elists;
d6f39728 32with Errout; use Errout;
d00681a7 33with Exp_Disp; use Exp_Disp;
d6f39728 34with Exp_Tss; use Exp_Tss;
35with Exp_Util; use Exp_Util;
d6f39728 36with Lib; use Lib;
83f8f0a6 37with Lib.Xref; use Lib.Xref;
15ebb600 38with Namet; use Namet;
d6f39728 39with Nlists; use Nlists;
40with Nmake; use Nmake;
41with Opt; use Opt;
e0521a36 42with Restrict; use Restrict;
43with Rident; use Rident;
d6f39728 44with Rtsfind; use Rtsfind;
45with Sem; use Sem;
d60c9ff7 46with Sem_Aux; use Sem_Aux;
be9124d0 47with Sem_Case; use Sem_Case;
40ca69b9 48with Sem_Ch3; use Sem_Ch3;
490beba6 49with Sem_Ch6; use Sem_Ch6;
d6f39728 50with Sem_Ch8; use Sem_Ch8;
89f1e35c 51with Sem_Ch9; use Sem_Ch9;
85696508 52with Sem_Dim; use Sem_Dim;
85377c9b 53with Sem_Disp; use Sem_Disp;
d6f39728 54with Sem_Eval; use Sem_Eval;
51ea9c94 55with Sem_Prag; use Sem_Prag;
d6f39728 56with Sem_Res; use Sem_Res;
57with Sem_Type; use Sem_Type;
58with Sem_Util; use Sem_Util;
44e4341e 59with Sem_Warn; use Sem_Warn;
1e3c4ae6 60with Sinput; use Sinput;
9dfe12ae 61with Snames; use Snames;
d6f39728 62with Stand; use Stand;
63with Sinfo; use Sinfo;
5b5df4a9 64with Stringt; use Stringt;
93735cb8 65with Targparm; use Targparm;
d6f39728 66with Ttypes; use Ttypes;
67with Tbuild; use Tbuild;
68with Urealp; use Urealp;
f42f24d7 69with Warnsw; use Warnsw;
d6f39728 70
bfa5a9d9 71with GNAT.Heap_Sort_G;
d6f39728 72
73package body Sem_Ch13 is
74
75 SSU : constant Pos := System_Storage_Unit;
76 -- Convenient short hand for commonly used constant
77
78 -----------------------
79 -- Local Subprograms --
80 -----------------------
81
1d366b32 82 procedure Alignment_Check_For_Size_Change (Typ : Entity_Id; Size : Uint);
83 -- This routine is called after setting one of the sizes of type entity
84 -- Typ to Size. The purpose is to deal with the situation of a derived
85 -- type whose inherited alignment is no longer appropriate for the new
86 -- size value. In this case, we reset the Alignment to unknown.
d6f39728 87
84c8f0b8 88 procedure Build_Predicate_Functions (Typ : Entity_Id; N : Node_Id);
9dc88aea 89 -- If Typ has predicates (indicated by Has_Predicates being set for Typ,
9f727ad2 90 -- then either there are pragma Predicate entries on the rep chain for the
6fb3c314 91 -- type (note that Predicate aspects are converted to pragma Predicate), or
490beba6 92 -- there are inherited aspects from a parent type, or ancestor subtypes.
93 -- This procedure builds the spec and body for the Predicate function that
94 -- tests these predicates. N is the freeze node for the type. The spec of
95 -- the function is inserted before the freeze node, and the body of the
84c8f0b8 96 -- function is inserted after the freeze node. If the predicate expression
97 -- has at least one Raise_Expression, then this procedure also builds the
726fd56a 98 -- M version of the predicate function for use in membership tests.
9dc88aea 99
d97beb2f 100 procedure Build_Static_Predicate
101 (Typ : Entity_Id;
102 Expr : Node_Id;
103 Nam : Name_Id);
d7c2851f 104 -- Given a predicated type Typ, where Typ is a discrete static subtype,
105 -- whose predicate expression is Expr, tests if Expr is a static predicate,
106 -- and if so, builds the predicate range list. Nam is the name of the one
107 -- argument to the predicate function. Occurrences of the type name in the
6fb3c314 108 -- predicate expression have been replaced by identifier references to this
d7c2851f 109 -- name, which is unique, so any identifier with Chars matching Nam must be
110 -- a reference to the type. If the predicate is non-static, this procedure
111 -- returns doing nothing. If the predicate is static, then the predicate
112 -- list is stored in Static_Predicate (Typ), and the Expr is rewritten as
113 -- a canonicalized membership operation.
d97beb2f 114
d9f6a4ee 115 procedure Freeze_Entity_Checks (N : Node_Id);
116 -- Called from Analyze_Freeze_Entity and Analyze_Generic_Freeze Entity
117 -- to generate appropriate semantic checks that are delayed until this
118 -- point (they had to be delayed this long for cases of delayed aspects,
119 -- e.g. analysis of statically predicated subtypes in choices, for which
120 -- we have to be sure the subtypes in question are frozen before checking.
121
d6f39728 122 function Get_Alignment_Value (Expr : Node_Id) return Uint;
123 -- Given the expression for an alignment value, returns the corresponding
124 -- Uint value. If the value is inappropriate, then error messages are
125 -- posted as required, and a value of No_Uint is returned.
126
127 function Is_Operational_Item (N : Node_Id) return Boolean;
1e3c4ae6 128 -- A specification for a stream attribute is allowed before the full type
129 -- is declared, as explained in AI-00137 and the corrigendum. Attributes
130 -- that do not specify a representation characteristic are operational
131 -- attributes.
d6f39728 132
44e4341e 133 procedure New_Stream_Subprogram
d6f39728 134 (N : Node_Id;
135 Ent : Entity_Id;
136 Subp : Entity_Id;
9dfe12ae 137 Nam : TSS_Name_Type);
44e4341e 138 -- Create a subprogram renaming of a given stream attribute to the
139 -- designated subprogram and then in the tagged case, provide this as a
140 -- primitive operation, or in the non-tagged case make an appropriate TSS
141 -- entry. This is more properly an expansion activity than just semantics,
142 -- but the presence of user-defined stream functions for limited types is a
143 -- legality check, which is why this takes place here rather than in
144 -- exp_ch13, where it was previously. Nam indicates the name of the TSS
145 -- function to be generated.
9dfe12ae 146 --
f15731c4 147 -- To avoid elaboration anomalies with freeze nodes, for untagged types
148 -- we generate both a subprogram declaration and a subprogram renaming
149 -- declaration, so that the attribute specification is handled as a
150 -- renaming_as_body. For tagged types, the specification is one of the
151 -- primitive specs.
152
2072eaa9 153 generic
154 with procedure Replace_Type_Reference (N : Node_Id);
155 procedure Replace_Type_References_Generic (N : Node_Id; TName : Name_Id);
156 -- This is used to scan an expression for a predicate or invariant aspect
157 -- replacing occurrences of the name TName (the name of the subtype to
158 -- which the aspect applies) with appropriate references to the parameter
159 -- of the predicate function or invariant procedure. The procedure passed
160 -- as a generic parameter does the actual replacement of node N, which is
161 -- either a simple direct reference to TName, or a selected component that
162 -- represents an appropriately qualified occurrence of TName.
163
b77e4501 164 procedure Set_Biased
165 (E : Entity_Id;
166 N : Node_Id;
167 Msg : String;
168 Biased : Boolean := True);
169 -- If Biased is True, sets Has_Biased_Representation flag for E, and
170 -- outputs a warning message at node N if Warn_On_Biased_Representation is
171 -- is True. This warning inserts the string Msg to describe the construct
172 -- causing biasing.
173
d6f39728 174 ----------------------------------------------
175 -- Table for Validate_Unchecked_Conversions --
176 ----------------------------------------------
177
178 -- The following table collects unchecked conversions for validation.
95deda50 179 -- Entries are made by Validate_Unchecked_Conversion and then the call
180 -- to Validate_Unchecked_Conversions does the actual error checking and
181 -- posting of warnings. The reason for this delayed processing is to take
182 -- advantage of back-annotations of size and alignment values performed by
183 -- the back end.
d6f39728 184
95deda50 185 -- Note: the reason we store a Source_Ptr value instead of a Node_Id is
186 -- that by the time Validate_Unchecked_Conversions is called, Sprint will
187 -- already have modified all Sloc values if the -gnatD option is set.
299480f9 188
d6f39728 189 type UC_Entry is record
299480f9 190 Eloc : Source_Ptr; -- node used for posting warnings
191 Source : Entity_Id; -- source type for unchecked conversion
192 Target : Entity_Id; -- target type for unchecked conversion
d6f39728 193 end record;
194
195 package Unchecked_Conversions is new Table.Table (
196 Table_Component_Type => UC_Entry,
197 Table_Index_Type => Int,
198 Table_Low_Bound => 1,
199 Table_Initial => 50,
200 Table_Increment => 200,
201 Table_Name => "Unchecked_Conversions");
202
83f8f0a6 203 ----------------------------------------
204 -- Table for Validate_Address_Clauses --
205 ----------------------------------------
206
207 -- If an address clause has the form
208
209 -- for X'Address use Expr
210
95deda50 211 -- where Expr is of the form Y'Address or recursively is a reference to a
212 -- constant of either of these forms, and X and Y are entities of objects,
213 -- then if Y has a smaller alignment than X, that merits a warning about
214 -- possible bad alignment. The following table collects address clauses of
215 -- this kind. We put these in a table so that they can be checked after the
216 -- back end has completed annotation of the alignments of objects, since we
217 -- can catch more cases that way.
83f8f0a6 218
219 type Address_Clause_Check_Record is record
220 N : Node_Id;
221 -- The address clause
222
223 X : Entity_Id;
224 -- The entity of the object overlaying Y
225
226 Y : Entity_Id;
227 -- The entity of the object being overlaid
d6da7448 228
229 Off : Boolean;
6fb3c314 230 -- Whether the address is offset within Y
83f8f0a6 231 end record;
232
233 package Address_Clause_Checks is new Table.Table (
234 Table_Component_Type => Address_Clause_Check_Record,
235 Table_Index_Type => Int,
236 Table_Low_Bound => 1,
237 Table_Initial => 20,
238 Table_Increment => 200,
239 Table_Name => "Address_Clause_Checks");
240
59ac57b5 241 -----------------------------------------
242 -- Adjust_Record_For_Reverse_Bit_Order --
243 -----------------------------------------
244
245 procedure Adjust_Record_For_Reverse_Bit_Order (R : Entity_Id) is
67278d60 246 Comp : Node_Id;
247 CC : Node_Id;
59ac57b5 248
249 begin
67278d60 250 -- Processing depends on version of Ada
59ac57b5 251
6797073f 252 -- For Ada 95, we just renumber bits within a storage unit. We do the
568b0f6a 253 -- same for Ada 83 mode, since we recognize the Bit_Order attribute in
ab19a652 254 -- Ada 83, and are free to add this extension.
6797073f 255
256 if Ada_Version < Ada_2005 then
257 Comp := First_Component_Or_Discriminant (R);
258 while Present (Comp) loop
259 CC := Component_Clause (Comp);
260
261 -- If component clause is present, then deal with the non-default
262 -- bit order case for Ada 95 mode.
263
264 -- We only do this processing for the base type, and in fact that
265 -- is important, since otherwise if there are record subtypes, we
266 -- could reverse the bits once for each subtype, which is wrong.
267
b9e61b2a 268 if Present (CC) and then Ekind (R) = E_Record_Type then
6797073f 269 declare
270 CFB : constant Uint := Component_Bit_Offset (Comp);
271 CSZ : constant Uint := Esize (Comp);
272 CLC : constant Node_Id := Component_Clause (Comp);
273 Pos : constant Node_Id := Position (CLC);
274 FB : constant Node_Id := First_Bit (CLC);
275
276 Storage_Unit_Offset : constant Uint :=
277 CFB / System_Storage_Unit;
278
279 Start_Bit : constant Uint :=
280 CFB mod System_Storage_Unit;
59ac57b5 281
6797073f 282 begin
283 -- Cases where field goes over storage unit boundary
59ac57b5 284
6797073f 285 if Start_Bit + CSZ > System_Storage_Unit then
59ac57b5 286
6797073f 287 -- Allow multi-byte field but generate warning
59ac57b5 288
6797073f 289 if Start_Bit mod System_Storage_Unit = 0
290 and then CSZ mod System_Storage_Unit = 0
291 then
292 Error_Msg_N
293 ("multi-byte field specified with non-standard"
1e3532e7 294 & " Bit_Order??", CLC);
31486bc0 295
6797073f 296 if Bytes_Big_Endian then
31486bc0 297 Error_Msg_N
6797073f 298 ("bytes are not reversed "
1e3532e7 299 & "(component is big-endian)??", CLC);
31486bc0 300 else
301 Error_Msg_N
6797073f 302 ("bytes are not reversed "
1e3532e7 303 & "(component is little-endian)??", CLC);
31486bc0 304 end if;
59ac57b5 305
6797073f 306 -- Do not allow non-contiguous field
59ac57b5 307
67278d60 308 else
6797073f 309 Error_Msg_N
310 ("attempt to specify non-contiguous field "
311 & "not permitted", CLC);
312 Error_Msg_N
313 ("\caused by non-standard Bit_Order "
314 & "specified", CLC);
315 Error_Msg_N
316 ("\consider possibility of using "
317 & "Ada 2005 mode here", CLC);
318 end if;
59ac57b5 319
6797073f 320 -- Case where field fits in one storage unit
59ac57b5 321
6797073f 322 else
323 -- Give warning if suspicious component clause
59ac57b5 324
6797073f 325 if Intval (FB) >= System_Storage_Unit
326 and then Warn_On_Reverse_Bit_Order
327 then
328 Error_Msg_N
1e3532e7 329 ("Bit_Order clause does not affect " &
330 "byte ordering?V?", Pos);
6797073f 331 Error_Msg_Uint_1 :=
332 Intval (Pos) + Intval (FB) /
333 System_Storage_Unit;
334 Error_Msg_N
1e3532e7 335 ("position normalized to ^ before bit " &
336 "order interpreted?V?", Pos);
6797073f 337 end if;
59ac57b5 338
6797073f 339 -- Here is where we fix up the Component_Bit_Offset value
340 -- to account for the reverse bit order. Some examples of
341 -- what needs to be done are:
bfa5a9d9 342
6797073f 343 -- First_Bit .. Last_Bit Component_Bit_Offset
344 -- old new old new
59ac57b5 345
6797073f 346 -- 0 .. 0 7 .. 7 0 7
347 -- 0 .. 1 6 .. 7 0 6
348 -- 0 .. 2 5 .. 7 0 5
349 -- 0 .. 7 0 .. 7 0 4
59ac57b5 350
6797073f 351 -- 1 .. 1 6 .. 6 1 6
352 -- 1 .. 4 3 .. 6 1 3
353 -- 4 .. 7 0 .. 3 4 0
59ac57b5 354
6797073f 355 -- The rule is that the first bit is is obtained by
356 -- subtracting the old ending bit from storage_unit - 1.
59ac57b5 357
6797073f 358 Set_Component_Bit_Offset
359 (Comp,
360 (Storage_Unit_Offset * System_Storage_Unit) +
361 (System_Storage_Unit - 1) -
362 (Start_Bit + CSZ - 1));
59ac57b5 363
6797073f 364 Set_Normalized_First_Bit
365 (Comp,
366 Component_Bit_Offset (Comp) mod
367 System_Storage_Unit);
368 end if;
369 end;
370 end if;
371
372 Next_Component_Or_Discriminant (Comp);
373 end loop;
374
375 -- For Ada 2005, we do machine scalar processing, as fully described In
376 -- AI-133. This involves gathering all components which start at the
377 -- same byte offset and processing them together. Same approach is still
378 -- valid in later versions including Ada 2012.
379
380 else
381 declare
382 Max_Machine_Scalar_Size : constant Uint :=
383 UI_From_Int
384 (Standard_Long_Long_Integer_Size);
67278d60 385 -- We use this as the maximum machine scalar size
59ac57b5 386
6797073f 387 Num_CC : Natural;
388 SSU : constant Uint := UI_From_Int (System_Storage_Unit);
59ac57b5 389
6797073f 390 begin
391 -- This first loop through components does two things. First it
392 -- deals with the case of components with component clauses whose
393 -- length is greater than the maximum machine scalar size (either
394 -- accepting them or rejecting as needed). Second, it counts the
395 -- number of components with component clauses whose length does
396 -- not exceed this maximum for later processing.
67278d60 397
6797073f 398 Num_CC := 0;
399 Comp := First_Component_Or_Discriminant (R);
400 while Present (Comp) loop
401 CC := Component_Clause (Comp);
67278d60 402
6797073f 403 if Present (CC) then
404 declare
1e3532e7 405 Fbit : constant Uint := Static_Integer (First_Bit (CC));
406 Lbit : constant Uint := Static_Integer (Last_Bit (CC));
67278d60 407
6797073f 408 begin
b38e4131 409 -- Case of component with last bit >= max machine scalar
67278d60 410
b38e4131 411 if Lbit >= Max_Machine_Scalar_Size then
67278d60 412
b38e4131 413 -- This is allowed only if first bit is zero, and
414 -- last bit + 1 is a multiple of storage unit size.
67278d60 415
b38e4131 416 if Fbit = 0 and then (Lbit + 1) mod SSU = 0 then
67278d60 417
b38e4131 418 -- This is the case to give a warning if enabled
67278d60 419
b38e4131 420 if Warn_On_Reverse_Bit_Order then
421 Error_Msg_N
422 ("multi-byte field specified with "
1e3532e7 423 & " non-standard Bit_Order?V?", CC);
b38e4131 424
425 if Bytes_Big_Endian then
426 Error_Msg_N
427 ("\bytes are not reversed "
1e3532e7 428 & "(component is big-endian)?V?", CC);
b38e4131 429 else
430 Error_Msg_N
431 ("\bytes are not reversed "
1e3532e7 432 & "(component is little-endian)?V?", CC);
b38e4131 433 end if;
434 end if;
67278d60 435
7eb0e22f 436 -- Give error message for RM 13.5.1(10) violation
67278d60 437
b38e4131 438 else
439 Error_Msg_FE
440 ("machine scalar rules not followed for&",
441 First_Bit (CC), Comp);
67278d60 442
b38e4131 443 Error_Msg_Uint_1 := Lbit;
444 Error_Msg_Uint_2 := Max_Machine_Scalar_Size;
445 Error_Msg_F
446 ("\last bit (^) exceeds maximum machine "
447 & "scalar size (^)",
448 First_Bit (CC));
67278d60 449
b38e4131 450 if (Lbit + 1) mod SSU /= 0 then
451 Error_Msg_Uint_1 := SSU;
452 Error_Msg_F
453 ("\and is not a multiple of Storage_Unit (^) "
0cafb066 454 & "(RM 13.4.1(10))",
b38e4131 455 First_Bit (CC));
6797073f 456
6797073f 457 else
b38e4131 458 Error_Msg_Uint_1 := Fbit;
459 Error_Msg_F
460 ("\and first bit (^) is non-zero "
0cafb066 461 & "(RM 13.4.1(10))",
b38e4131 462 First_Bit (CC));
67278d60 463 end if;
6797073f 464 end if;
59ac57b5 465
b38e4131 466 -- OK case of machine scalar related component clause,
467 -- For now, just count them.
59ac57b5 468
6797073f 469 else
470 Num_CC := Num_CC + 1;
471 end if;
472 end;
473 end if;
59ac57b5 474
6797073f 475 Next_Component_Or_Discriminant (Comp);
476 end loop;
59ac57b5 477
6797073f 478 -- We need to sort the component clauses on the basis of the
479 -- Position values in the clause, so we can group clauses with
480 -- the same Position. together to determine the relevant machine
481 -- scalar size.
59ac57b5 482
6797073f 483 Sort_CC : declare
484 Comps : array (0 .. Num_CC) of Entity_Id;
485 -- Array to collect component and discriminant entities. The
486 -- data starts at index 1, the 0'th entry is for the sort
487 -- routine.
59ac57b5 488
6797073f 489 function CP_Lt (Op1, Op2 : Natural) return Boolean;
490 -- Compare routine for Sort
59ac57b5 491
6797073f 492 procedure CP_Move (From : Natural; To : Natural);
493 -- Move routine for Sort
59ac57b5 494
6797073f 495 package Sorting is new GNAT.Heap_Sort_G (CP_Move, CP_Lt);
59ac57b5 496
6797073f 497 Start : Natural;
498 Stop : Natural;
499 -- Start and stop positions in the component list of the set of
500 -- components with the same starting position (that constitute
501 -- components in a single machine scalar).
59ac57b5 502
6797073f 503 MaxL : Uint;
504 -- Maximum last bit value of any component in this set
59ac57b5 505
6797073f 506 MSS : Uint;
507 -- Corresponding machine scalar size
67278d60 508
6797073f 509 -----------
510 -- CP_Lt --
511 -----------
67278d60 512
6797073f 513 function CP_Lt (Op1, Op2 : Natural) return Boolean is
514 begin
515 return Position (Component_Clause (Comps (Op1))) <
516 Position (Component_Clause (Comps (Op2)));
517 end CP_Lt;
67278d60 518
6797073f 519 -------------
520 -- CP_Move --
521 -------------
67278d60 522
6797073f 523 procedure CP_Move (From : Natural; To : Natural) is
524 begin
525 Comps (To) := Comps (From);
526 end CP_Move;
67278d60 527
528 -- Start of processing for Sort_CC
59ac57b5 529
6797073f 530 begin
b38e4131 531 -- Collect the machine scalar relevant component clauses
59ac57b5 532
6797073f 533 Num_CC := 0;
534 Comp := First_Component_Or_Discriminant (R);
535 while Present (Comp) loop
b38e4131 536 declare
537 CC : constant Node_Id := Component_Clause (Comp);
538
539 begin
540 -- Collect only component clauses whose last bit is less
541 -- than machine scalar size. Any component clause whose
542 -- last bit exceeds this value does not take part in
543 -- machine scalar layout considerations. The test for
544 -- Error_Posted makes sure we exclude component clauses
545 -- for which we already posted an error.
546
547 if Present (CC)
548 and then not Error_Posted (Last_Bit (CC))
549 and then Static_Integer (Last_Bit (CC)) <
d64221a7 550 Max_Machine_Scalar_Size
b38e4131 551 then
552 Num_CC := Num_CC + 1;
553 Comps (Num_CC) := Comp;
554 end if;
555 end;
59ac57b5 556
6797073f 557 Next_Component_Or_Discriminant (Comp);
558 end loop;
67278d60 559
6797073f 560 -- Sort by ascending position number
67278d60 561
6797073f 562 Sorting.Sort (Num_CC);
67278d60 563
6797073f 564 -- We now have all the components whose size does not exceed
565 -- the max machine scalar value, sorted by starting position.
566 -- In this loop we gather groups of clauses starting at the
567 -- same position, to process them in accordance with AI-133.
67278d60 568
6797073f 569 Stop := 0;
570 while Stop < Num_CC loop
571 Start := Stop + 1;
572 Stop := Start;
573 MaxL :=
574 Static_Integer
575 (Last_Bit (Component_Clause (Comps (Start))));
67278d60 576 while Stop < Num_CC loop
6797073f 577 if Static_Integer
578 (Position (Component_Clause (Comps (Stop + 1)))) =
579 Static_Integer
580 (Position (Component_Clause (Comps (Stop))))
581 then
582 Stop := Stop + 1;
583 MaxL :=
584 UI_Max
585 (MaxL,
586 Static_Integer
587 (Last_Bit
588 (Component_Clause (Comps (Stop)))));
589 else
590 exit;
591 end if;
592 end loop;
67278d60 593
6797073f 594 -- Now we have a group of component clauses from Start to
595 -- Stop whose positions are identical, and MaxL is the
596 -- maximum last bit value of any of these components.
597
598 -- We need to determine the corresponding machine scalar
599 -- size. This loop assumes that machine scalar sizes are
600 -- even, and that each possible machine scalar has twice
601 -- as many bits as the next smaller one.
602
603 MSS := Max_Machine_Scalar_Size;
604 while MSS mod 2 = 0
605 and then (MSS / 2) >= SSU
606 and then (MSS / 2) > MaxL
607 loop
608 MSS := MSS / 2;
609 end loop;
67278d60 610
6797073f 611 -- Here is where we fix up the Component_Bit_Offset value
612 -- to account for the reverse bit order. Some examples of
613 -- what needs to be done for the case of a machine scalar
614 -- size of 8 are:
67278d60 615
6797073f 616 -- First_Bit .. Last_Bit Component_Bit_Offset
617 -- old new old new
67278d60 618
6797073f 619 -- 0 .. 0 7 .. 7 0 7
620 -- 0 .. 1 6 .. 7 0 6
621 -- 0 .. 2 5 .. 7 0 5
622 -- 0 .. 7 0 .. 7 0 4
67278d60 623
6797073f 624 -- 1 .. 1 6 .. 6 1 6
625 -- 1 .. 4 3 .. 6 1 3
626 -- 4 .. 7 0 .. 3 4 0
67278d60 627
6797073f 628 -- The rule is that the first bit is obtained by subtracting
629 -- the old ending bit from machine scalar size - 1.
67278d60 630
6797073f 631 for C in Start .. Stop loop
632 declare
633 Comp : constant Entity_Id := Comps (C);
b9e61b2a 634 CC : constant Node_Id := Component_Clause (Comp);
635
636 LB : constant Uint := Static_Integer (Last_Bit (CC));
6797073f 637 NFB : constant Uint := MSS - Uint_1 - LB;
638 NLB : constant Uint := NFB + Esize (Comp) - 1;
b9e61b2a 639 Pos : constant Uint := Static_Integer (Position (CC));
67278d60 640
6797073f 641 begin
642 if Warn_On_Reverse_Bit_Order then
643 Error_Msg_Uint_1 := MSS;
644 Error_Msg_N
645 ("info: reverse bit order in machine " &
1e3532e7 646 "scalar of length^?V?", First_Bit (CC));
6797073f 647 Error_Msg_Uint_1 := NFB;
648 Error_Msg_Uint_2 := NLB;
649
650 if Bytes_Big_Endian then
651 Error_Msg_NE
1e3532e7 652 ("\info: big-endian range for "
653 & "component & is ^ .. ^?V?",
6797073f 654 First_Bit (CC), Comp);
655 else
656 Error_Msg_NE
1e3532e7 657 ("\info: little-endian range "
658 & "for component & is ^ .. ^?V?",
6797073f 659 First_Bit (CC), Comp);
67278d60 660 end if;
6797073f 661 end if;
67278d60 662
6797073f 663 Set_Component_Bit_Offset (Comp, Pos * SSU + NFB);
664 Set_Normalized_First_Bit (Comp, NFB mod SSU);
665 end;
67278d60 666 end loop;
6797073f 667 end loop;
668 end Sort_CC;
669 end;
670 end if;
59ac57b5 671 end Adjust_Record_For_Reverse_Bit_Order;
672
1d366b32 673 -------------------------------------
674 -- Alignment_Check_For_Size_Change --
675 -------------------------------------
d6f39728 676
1d366b32 677 procedure Alignment_Check_For_Size_Change (Typ : Entity_Id; Size : Uint) is
d6f39728 678 begin
679 -- If the alignment is known, and not set by a rep clause, and is
680 -- inconsistent with the size being set, then reset it to unknown,
681 -- we assume in this case that the size overrides the inherited
682 -- alignment, and that the alignment must be recomputed.
683
684 if Known_Alignment (Typ)
685 and then not Has_Alignment_Clause (Typ)
1d366b32 686 and then Size mod (Alignment (Typ) * SSU) /= 0
d6f39728 687 then
688 Init_Alignment (Typ);
689 end if;
1d366b32 690 end Alignment_Check_For_Size_Change;
d6f39728 691
06ef5f86 692 -------------------------------------
693 -- Analyze_Aspects_At_Freeze_Point --
694 -------------------------------------
695
696 procedure Analyze_Aspects_At_Freeze_Point (E : Entity_Id) is
697 ASN : Node_Id;
698 A_Id : Aspect_Id;
699 Ritem : Node_Id;
700
701 procedure Analyze_Aspect_Default_Value (ASN : Node_Id);
702 -- This routine analyzes an Aspect_Default_[Component_]Value denoted by
703 -- the aspect specification node ASN.
704
37c6e44c 705 procedure Inherit_Delayed_Rep_Aspects (ASN : Node_Id);
706 -- As discussed in the spec of Aspects (see Aspect_Delay declaration),
707 -- a derived type can inherit aspects from its parent which have been
708 -- specified at the time of the derivation using an aspect, as in:
709 --
710 -- type A is range 1 .. 10
711 -- with Size => Not_Defined_Yet;
712 -- ..
713 -- type B is new A;
714 -- ..
715 -- Not_Defined_Yet : constant := 64;
716 --
717 -- In this example, the Size of A is considered to be specified prior
718 -- to the derivation, and thus inherited, even though the value is not
719 -- known at the time of derivation. To deal with this, we use two entity
720 -- flags. The flag Has_Derived_Rep_Aspects is set in the parent type (A
721 -- here), and then the flag May_Inherit_Delayed_Rep_Aspects is set in
722 -- the derived type (B here). If this flag is set when the derived type
723 -- is frozen, then this procedure is called to ensure proper inheritance
b21edad9 724 -- of all delayed aspects from the parent type. The derived type is E,
37c6e44c 725 -- the argument to Analyze_Aspects_At_Freeze_Point. ASN is the first
726 -- aspect specification node in the Rep_Item chain for the parent type.
727
06ef5f86 728 procedure Make_Pragma_From_Boolean_Aspect (ASN : Node_Id);
729 -- Given an aspect specification node ASN whose expression is an
730 -- optional Boolean, this routines creates the corresponding pragma
731 -- at the freezing point.
732
733 ----------------------------------
734 -- Analyze_Aspect_Default_Value --
735 ----------------------------------
736
737 procedure Analyze_Aspect_Default_Value (ASN : Node_Id) is
738 Ent : constant Entity_Id := Entity (ASN);
739 Expr : constant Node_Id := Expression (ASN);
740 Id : constant Node_Id := Identifier (ASN);
741
742 begin
743 Error_Msg_Name_1 := Chars (Id);
744
745 if not Is_Type (Ent) then
746 Error_Msg_N ("aspect% can only apply to a type", Id);
747 return;
748
749 elsif not Is_First_Subtype (Ent) then
750 Error_Msg_N ("aspect% cannot apply to subtype", Id);
751 return;
752
753 elsif A_Id = Aspect_Default_Value
754 and then not Is_Scalar_Type (Ent)
755 then
756 Error_Msg_N ("aspect% can only be applied to scalar type", Id);
757 return;
758
759 elsif A_Id = Aspect_Default_Component_Value then
760 if not Is_Array_Type (Ent) then
761 Error_Msg_N ("aspect% can only be applied to array type", Id);
762 return;
763
764 elsif not Is_Scalar_Type (Component_Type (Ent)) then
765 Error_Msg_N ("aspect% requires scalar components", Id);
766 return;
767 end if;
768 end if;
769
770 Set_Has_Default_Aspect (Base_Type (Ent));
771
772 if Is_Scalar_Type (Ent) then
773 Set_Default_Aspect_Value (Ent, Expr);
9f36e3fb 774
775 -- Place default value of base type as well, because that is
776 -- the semantics of the aspect. It is convenient to link the
777 -- aspect to both the (possibly anonymous) base type and to
778 -- the given first subtype.
779
780 Set_Default_Aspect_Value (Base_Type (Ent), Expr);
781
06ef5f86 782 else
783 Set_Default_Aspect_Component_Value (Ent, Expr);
784 end if;
785 end Analyze_Aspect_Default_Value;
786
37c6e44c 787 ---------------------------------
788 -- Inherit_Delayed_Rep_Aspects --
789 ---------------------------------
790
791 procedure Inherit_Delayed_Rep_Aspects (ASN : Node_Id) is
792 P : constant Entity_Id := Entity (ASN);
793 -- Entithy for parent type
794
795 N : Node_Id;
796 -- Item from Rep_Item chain
797
798 A : Aspect_Id;
799
800 begin
801 -- Loop through delayed aspects for the parent type
802
803 N := ASN;
804 while Present (N) loop
805 if Nkind (N) = N_Aspect_Specification then
806 exit when Entity (N) /= P;
807
808 if Is_Delayed_Aspect (N) then
809 A := Get_Aspect_Id (Chars (Identifier (N)));
810
811 -- Process delayed rep aspect. For Boolean attributes it is
812 -- not possible to cancel an attribute once set (the attempt
813 -- to use an aspect with xxx => False is an error) for a
814 -- derived type. So for those cases, we do not have to check
815 -- if a clause has been given for the derived type, since it
816 -- is harmless to set it again if it is already set.
817
818 case A is
819
820 -- Alignment
821
822 when Aspect_Alignment =>
823 if not Has_Alignment_Clause (E) then
824 Set_Alignment (E, Alignment (P));
825 end if;
826
827 -- Atomic
828
829 when Aspect_Atomic =>
830 if Is_Atomic (P) then
831 Set_Is_Atomic (E);
832 end if;
833
834 -- Atomic_Components
835
836 when Aspect_Atomic_Components =>
837 if Has_Atomic_Components (P) then
838 Set_Has_Atomic_Components (Base_Type (E));
839 end if;
840
841 -- Bit_Order
842
843 when Aspect_Bit_Order =>
844 if Is_Record_Type (E)
845 and then No (Get_Attribute_Definition_Clause
846 (E, Attribute_Bit_Order))
847 and then Reverse_Bit_Order (P)
848 then
849 Set_Reverse_Bit_Order (Base_Type (E));
850 end if;
851
852 -- Component_Size
853
854 when Aspect_Component_Size =>
855 if Is_Array_Type (E)
856 and then not Has_Component_Size_Clause (E)
857 then
858 Set_Component_Size
859 (Base_Type (E), Component_Size (P));
860 end if;
861
862 -- Machine_Radix
863
864 when Aspect_Machine_Radix =>
865 if Is_Decimal_Fixed_Point_Type (E)
866 and then not Has_Machine_Radix_Clause (E)
867 then
868 Set_Machine_Radix_10 (E, Machine_Radix_10 (P));
869 end if;
870
871 -- Object_Size (also Size which also sets Object_Size)
872
873 when Aspect_Object_Size | Aspect_Size =>
874 if not Has_Size_Clause (E)
875 and then
876 No (Get_Attribute_Definition_Clause
877 (E, Attribute_Object_Size))
878 then
879 Set_Esize (E, Esize (P));
880 end if;
881
882 -- Pack
883
884 when Aspect_Pack =>
885 if not Is_Packed (E) then
886 Set_Is_Packed (Base_Type (E));
887
888 if Is_Bit_Packed_Array (P) then
889 Set_Is_Bit_Packed_Array (Base_Type (E));
890 Set_Packed_Array_Type (E, Packed_Array_Type (P));
891 end if;
892 end if;
893
894 -- Scalar_Storage_Order
895
896 when Aspect_Scalar_Storage_Order =>
897 if (Is_Record_Type (E) or else Is_Array_Type (E))
898 and then No (Get_Attribute_Definition_Clause
e163cac8 899 (E, Attribute_Scalar_Storage_Order))
37c6e44c 900 and then Reverse_Storage_Order (P)
901 then
902 Set_Reverse_Storage_Order (Base_Type (E));
903 end if;
904
905 -- Small
906
907 when Aspect_Small =>
908 if Is_Fixed_Point_Type (E)
909 and then not Has_Small_Clause (E)
910 then
911 Set_Small_Value (E, Small_Value (P));
912 end if;
913
914 -- Storage_Size
915
916 when Aspect_Storage_Size =>
917 if (Is_Access_Type (E) or else Is_Task_Type (E))
918 and then not Has_Storage_Size_Clause (E)
919 then
920 Set_Storage_Size_Variable
921 (Base_Type (E), Storage_Size_Variable (P));
922 end if;
923
924 -- Value_Size
925
926 when Aspect_Value_Size =>
927
928 -- Value_Size is never inherited, it is either set by
929 -- default, or it is explicitly set for the derived
930 -- type. So nothing to do here.
931
932 null;
933
934 -- Volatile
935
936 when Aspect_Volatile =>
937 if Is_Volatile (P) then
938 Set_Is_Volatile (E);
939 end if;
940
941 -- Volatile_Components
942
943 when Aspect_Volatile_Components =>
944 if Has_Volatile_Components (P) then
945 Set_Has_Volatile_Components (Base_Type (E));
946 end if;
947
948 -- That should be all the Rep Aspects
949
950 when others =>
951 pragma Assert (Aspect_Delay (A_Id) /= Rep_Aspect);
952 null;
953
954 end case;
955 end if;
956 end if;
957
958 N := Next_Rep_Item (N);
959 end loop;
960 end Inherit_Delayed_Rep_Aspects;
961
06ef5f86 962 -------------------------------------
963 -- Make_Pragma_From_Boolean_Aspect --
964 -------------------------------------
965
966 procedure Make_Pragma_From_Boolean_Aspect (ASN : Node_Id) is
967 Ident : constant Node_Id := Identifier (ASN);
968 A_Name : constant Name_Id := Chars (Ident);
969 A_Id : constant Aspect_Id := Get_Aspect_Id (A_Name);
970 Ent : constant Entity_Id := Entity (ASN);
971 Expr : constant Node_Id := Expression (ASN);
972 Loc : constant Source_Ptr := Sloc (ASN);
973
974 Prag : Node_Id;
975
976 procedure Check_False_Aspect_For_Derived_Type;
977 -- This procedure checks for the case of a false aspect for a derived
978 -- type, which improperly tries to cancel an aspect inherited from
979 -- the parent.
980
981 -----------------------------------------
982 -- Check_False_Aspect_For_Derived_Type --
983 -----------------------------------------
984
985 procedure Check_False_Aspect_For_Derived_Type is
986 Par : Node_Id;
987
988 begin
989 -- We are only checking derived types
990
991 if not Is_Derived_Type (E) then
992 return;
993 end if;
994
995 Par := Nearest_Ancestor (E);
996
997 case A_Id is
998 when Aspect_Atomic | Aspect_Shared =>
999 if not Is_Atomic (Par) then
1000 return;
1001 end if;
1002
1003 when Aspect_Atomic_Components =>
1004 if not Has_Atomic_Components (Par) then
1005 return;
1006 end if;
1007
1008 when Aspect_Discard_Names =>
1009 if not Discard_Names (Par) then
1010 return;
1011 end if;
1012
1013 when Aspect_Pack =>
1014 if not Is_Packed (Par) then
1015 return;
1016 end if;
1017
1018 when Aspect_Unchecked_Union =>
1019 if not Is_Unchecked_Union (Par) then
1020 return;
1021 end if;
1022
1023 when Aspect_Volatile =>
1024 if not Is_Volatile (Par) then
1025 return;
1026 end if;
1027
1028 when Aspect_Volatile_Components =>
1029 if not Has_Volatile_Components (Par) then
1030 return;
1031 end if;
1032
1033 when others =>
1034 return;
1035 end case;
1036
1037 -- Fall through means we are canceling an inherited aspect
1038
1039 Error_Msg_Name_1 := A_Name;
37c6e44c 1040 Error_Msg_NE
1041 ("derived type& inherits aspect%, cannot cancel", Expr, E);
06ef5f86 1042
1043 end Check_False_Aspect_For_Derived_Type;
1044
1045 -- Start of processing for Make_Pragma_From_Boolean_Aspect
1046
1047 begin
37c6e44c 1048 -- Note that we know Expr is present, because for a missing Expr
1049 -- argument, we knew it was True and did not need to delay the
1050 -- evaluation to the freeze point.
1051
06ef5f86 1052 if Is_False (Static_Boolean (Expr)) then
1053 Check_False_Aspect_For_Derived_Type;
1054
1055 else
1056 Prag :=
1057 Make_Pragma (Loc,
1058 Pragma_Argument_Associations => New_List (
57cd943b 1059 Make_Pragma_Argument_Association (Sloc (Ident),
1060 Expression => New_Occurrence_Of (Ent, Sloc (Ident)))),
1061
06ef5f86 1062 Pragma_Identifier =>
1063 Make_Identifier (Sloc (Ident), Chars (Ident)));
1064
1065 Set_From_Aspect_Specification (Prag, True);
1066 Set_Corresponding_Aspect (Prag, ASN);
1067 Set_Aspect_Rep_Item (ASN, Prag);
1068 Set_Is_Delayed_Aspect (Prag);
1069 Set_Parent (Prag, ASN);
1070 end if;
06ef5f86 1071 end Make_Pragma_From_Boolean_Aspect;
1072
1073 -- Start of processing for Analyze_Aspects_At_Freeze_Point
1074
1075 begin
29a9d4be 1076 -- Must be visible in current scope
06ef5f86 1077
ace3389d 1078 if not Scope_Within_Or_Same (Current_Scope, Scope (E)) then
06ef5f86 1079 return;
1080 end if;
1081
1082 -- Look for aspect specification entries for this entity
1083
1084 ASN := First_Rep_Item (E);
06ef5f86 1085 while Present (ASN) loop
37c6e44c 1086 if Nkind (ASN) = N_Aspect_Specification then
1087 exit when Entity (ASN) /= E;
06ef5f86 1088
37c6e44c 1089 if Is_Delayed_Aspect (ASN) then
1090 A_Id := Get_Aspect_Id (ASN);
1091
1092 case A_Id is
e4c87fa5 1093
37c6e44c 1094 -- For aspects whose expression is an optional Boolean, make
1095 -- the corresponding pragma at the freezing point.
06ef5f86 1096
1097 when Boolean_Aspects |
1098 Library_Unit_Aspects =>
1099 Make_Pragma_From_Boolean_Aspect (ASN);
1100
37c6e44c 1101 -- Special handling for aspects that don't correspond to
1102 -- pragmas/attributes.
06ef5f86 1103
1104 when Aspect_Default_Value |
1105 Aspect_Default_Component_Value =>
1106 Analyze_Aspect_Default_Value (ASN);
1107
37c6e44c 1108 -- Ditto for iterator aspects, because the corresponding
1109 -- attributes may not have been analyzed yet.
af9fed8f 1110
1111 when Aspect_Constant_Indexing |
1112 Aspect_Variable_Indexing |
1113 Aspect_Default_Iterator |
1114 Aspect_Iterator_Element =>
1115 Analyze (Expression (ASN));
1116
e4c87fa5 1117 when others =>
1118 null;
37c6e44c 1119 end case;
06ef5f86 1120
37c6e44c 1121 Ritem := Aspect_Rep_Item (ASN);
06ef5f86 1122
37c6e44c 1123 if Present (Ritem) then
1124 Analyze (Ritem);
1125 end if;
06ef5f86 1126 end if;
1127 end if;
1128
1129 Next_Rep_Item (ASN);
1130 end loop;
37c6e44c 1131
1132 -- This is where we inherit delayed rep aspects from our parent. Note
1133 -- that if we fell out of the above loop with ASN non-empty, it means
1134 -- we hit an aspect for an entity other than E, and it must be the
1135 -- type from which we were derived.
1136
1137 if May_Inherit_Delayed_Rep_Aspects (E) then
1138 Inherit_Delayed_Rep_Aspects (ASN);
1139 end if;
06ef5f86 1140 end Analyze_Aspects_At_Freeze_Point;
1141
ae888dbd 1142 -----------------------------------
1143 -- Analyze_Aspect_Specifications --
1144 -----------------------------------
1145
21ea3a4f 1146 procedure Analyze_Aspect_Specifications (N : Node_Id; E : Entity_Id) is
5ddd846b 1147 procedure Decorate_Delayed_Aspect_And_Pragma
1148 (Asp : Node_Id;
1149 Prag : Node_Id);
1150 -- Establish the linkages between a delayed aspect and its corresponding
1151 -- pragma. Set all delay-related flags on both constructs.
1152
c1006d6d 1153 procedure Insert_Delayed_Pragma (Prag : Node_Id);
1154 -- Insert a postcondition-like pragma into the tree depending on the
5ddd846b 1155 -- context. Prag must denote one of the following: Pre, Post, Depends,
1156 -- Global or Contract_Cases.
1157
1158 ----------------------------------------
1159 -- Decorate_Delayed_Aspect_And_Pragma --
1160 ----------------------------------------
c1006d6d 1161
5ddd846b 1162 procedure Decorate_Delayed_Aspect_And_Pragma
1163 (Asp : Node_Id;
1164 Prag : Node_Id)
1165 is
1166 begin
1167 Set_Aspect_Rep_Item (Asp, Prag);
1168 Set_Corresponding_Aspect (Prag, Asp);
1169 Set_From_Aspect_Specification (Prag);
1170 Set_Is_Delayed_Aspect (Prag);
1171 Set_Is_Delayed_Aspect (Asp);
1172 Set_Parent (Prag, Asp);
1173 end Decorate_Delayed_Aspect_And_Pragma;
f0813d71 1174
c1006d6d 1175 ---------------------------
1176 -- Insert_Delayed_Pragma --
1177 ---------------------------
1178
1179 procedure Insert_Delayed_Pragma (Prag : Node_Id) is
1180 Aux : Node_Id;
1181
1182 begin
1183 -- When the context is a library unit, the pragma is added to the
1184 -- Pragmas_After list.
1185
1186 if Nkind (Parent (N)) = N_Compilation_Unit then
1187 Aux := Aux_Decls_Node (Parent (N));
1188
1189 if No (Pragmas_After (Aux)) then
1190 Set_Pragmas_After (Aux, New_List);
1191 end if;
1192
1193 Prepend (Prag, Pragmas_After (Aux));
1194
1195 -- Pragmas associated with subprogram bodies are inserted in the
1196 -- declarative part.
1197
1198 elsif Nkind (N) = N_Subprogram_Body then
1199 if No (Declarations (N)) then
d324c418 1200 Set_Declarations (N, New_List (Prag));
1201 else
1202 declare
1203 D : Node_Id;
1204 begin
c1006d6d 1205
d324c418 1206 -- There may be several aspects associated with the body;
1207 -- preserve the ordering of the corresponding pragmas.
1208
1209 D := First (Declarations (N));
1210 while Present (D) loop
1211 exit when Nkind (D) /= N_Pragma
1212 or else not From_Aspect_Specification (D);
1213 Next (D);
1214 end loop;
1215
1216 if No (D) then
1217 Append (Prag, Declarations (N));
1218 else
1219 Insert_Before (D, Prag);
1220 end if;
1221 end;
1222 end if;
c1006d6d 1223
1224 -- Default
1225
1226 else
1227 Insert_After (N, Prag);
1228
1229 -- Analyze the pragma before analyzing the proper body of a stub.
1230 -- This ensures that the pragma will appear on the proper contract
1231 -- list (see N_Contract).
1232
1233 if Nkind (N) = N_Subprogram_Body_Stub then
1234 Analyze (Prag);
1235 end if;
1236 end if;
1237 end Insert_Delayed_Pragma;
1238
1239 -- Local variables
1240
ae888dbd 1241 Aspect : Node_Id;
d74fc39a 1242 Aitem : Node_Id;
ae888dbd 1243 Ent : Node_Id;
ae888dbd 1244
21ea3a4f 1245 L : constant List_Id := Aspect_Specifications (N);
1246
ae888dbd 1247 Ins_Node : Node_Id := N;
89f1e35c 1248 -- Insert pragmas/attribute definition clause after this node when no
1249 -- delayed analysis is required.
d74fc39a 1250
f0813d71 1251 -- Start of processing for Analyze_Aspect_Specifications
1252
d74fc39a 1253 -- The general processing involves building an attribute definition
89f1e35c 1254 -- clause or a pragma node that corresponds to the aspect. Then in order
1255 -- to delay the evaluation of this aspect to the freeze point, we attach
1256 -- the corresponding pragma/attribute definition clause to the aspect
1257 -- specification node, which is then placed in the Rep Item chain. In
1258 -- this case we mark the entity by setting the flag Has_Delayed_Aspects
1259 -- and we evaluate the rep item at the freeze point. When the aspect
1260 -- doesn't have a corresponding pragma/attribute definition clause, then
1261 -- its analysis is simply delayed at the freeze point.
1262
1263 -- Some special cases don't require delay analysis, thus the aspect is
1264 -- analyzed right now.
1265
51ea9c94 1266 -- Note that there is a special handling for Pre, Post, Test_Case,
e66f4e2a 1267 -- Contract_Cases aspects. In these cases, we do not have to worry
51ea9c94 1268 -- about delay issues, since the pragmas themselves deal with delay
1269 -- of visibility for the expression analysis. Thus, we just insert
1270 -- the pragma after the node N.
ae888dbd 1271
1272 begin
21ea3a4f 1273 pragma Assert (Present (L));
1274
6fb3c314 1275 -- Loop through aspects
f93e7257 1276
ae888dbd 1277 Aspect := First (L);
21ea3a4f 1278 Aspect_Loop : while Present (Aspect) loop
0fd13d32 1279 Analyze_One_Aspect : declare
94153a42 1280 Expr : constant Node_Id := Expression (Aspect);
89f1e35c 1281 Id : constant Node_Id := Identifier (Aspect);
1282 Loc : constant Source_Ptr := Sloc (Aspect);
94153a42 1283 Nam : constant Name_Id := Chars (Id);
1284 A_Id : constant Aspect_Id := Get_Aspect_Id (Nam);
ae888dbd 1285 Anod : Node_Id;
1286
37c6e44c 1287 Delay_Required : Boolean;
89f1e35c 1288 -- Set False if delay is not required
1289
c0793fff 1290 Eloc : Source_Ptr := No_Location;
1291 -- Source location of expression, modified when we split PPC's. It
1292 -- is set below when Expr is present.
39e1f22f 1293
89f1e35c 1294 procedure Analyze_Aspect_External_Or_Link_Name;
0fd13d32 1295 -- Perform analysis of the External_Name or Link_Name aspects
21ea3a4f 1296
89f1e35c 1297 procedure Analyze_Aspect_Implicit_Dereference;
9ab32fe9 1298 -- Perform analysis of the Implicit_Dereference aspects
0fd13d32 1299
1300 procedure Make_Aitem_Pragma
1301 (Pragma_Argument_Associations : List_Id;
1302 Pragma_Name : Name_Id);
1303 -- This is a wrapper for Make_Pragma used for converting aspects
1304 -- to pragmas. It takes care of Sloc (set from Loc) and building
1305 -- the pragma identifier from the given name. In addition the
1306 -- flags Class_Present and Split_PPC are set from the aspect
1307 -- node, as well as Is_Ignored. This routine also sets the
1308 -- From_Aspect_Specification in the resulting pragma node to
1309 -- True, and sets Corresponding_Aspect to point to the aspect.
1310 -- The resulting pragma is assigned to Aitem.
21ea3a4f 1311
89f1e35c 1312 ------------------------------------------
1313 -- Analyze_Aspect_External_Or_Link_Name --
1314 ------------------------------------------
1315
1316 procedure Analyze_Aspect_External_Or_Link_Name is
21ea3a4f 1317 begin
89f1e35c 1318 -- Verify that there is an Import/Export aspect defined for the
1319 -- entity. The processing of that aspect in turn checks that
1320 -- there is a Convention aspect declared. The pragma is
1321 -- constructed when processing the Convention aspect.
21ea3a4f 1322
89f1e35c 1323 declare
1324 A : Node_Id;
21ea3a4f 1325
89f1e35c 1326 begin
1327 A := First (L);
89f1e35c 1328 while Present (A) loop
18393965 1329 exit when Nam_In (Chars (Identifier (A)), Name_Export,
1330 Name_Import);
89f1e35c 1331 Next (A);
1332 end loop;
21ea3a4f 1333
89f1e35c 1334 if No (A) then
1335 Error_Msg_N
51ea9c94 1336 ("missing Import/Export for Link/External name",
89f1e35c 1337 Aspect);
1338 end if;
1339 end;
1340 end Analyze_Aspect_External_Or_Link_Name;
21ea3a4f 1341
89f1e35c 1342 -----------------------------------------
1343 -- Analyze_Aspect_Implicit_Dereference --
1344 -----------------------------------------
21ea3a4f 1345
89f1e35c 1346 procedure Analyze_Aspect_Implicit_Dereference is
1347 begin
b9e61b2a 1348 if not Is_Type (E) or else not Has_Discriminants (E) then
89f1e35c 1349 Error_Msg_N
51ea9c94 1350 ("aspect must apply to a type with discriminants", N);
21ea3a4f 1351
89f1e35c 1352 else
1353 declare
1354 Disc : Entity_Id;
21ea3a4f 1355
89f1e35c 1356 begin
1357 Disc := First_Discriminant (E);
89f1e35c 1358 while Present (Disc) loop
1359 if Chars (Expr) = Chars (Disc)
1360 and then Ekind (Etype (Disc)) =
1361 E_Anonymous_Access_Type
1362 then
1363 Set_Has_Implicit_Dereference (E);
1364 Set_Has_Implicit_Dereference (Disc);
1365 return;
1366 end if;
21ea3a4f 1367
89f1e35c 1368 Next_Discriminant (Disc);
1369 end loop;
21ea3a4f 1370
89f1e35c 1371 -- Error if no proper access discriminant.
21ea3a4f 1372
89f1e35c 1373 Error_Msg_NE
1374 ("not an access discriminant of&", Expr, E);
1375 end;
1376 end if;
1377 end Analyze_Aspect_Implicit_Dereference;
21ea3a4f 1378
0fd13d32 1379 -----------------------
1380 -- Make_Aitem_Pragma --
1381 -----------------------
1382
1383 procedure Make_Aitem_Pragma
1384 (Pragma_Argument_Associations : List_Id;
1385 Pragma_Name : Name_Id)
1386 is
b855559d 1387 Args : List_Id := Pragma_Argument_Associations;
1388
0fd13d32 1389 begin
1390 -- We should never get here if aspect was disabled
1391
1392 pragma Assert (not Is_Disabled (Aspect));
1393
056dc987 1394 -- Certain aspects allow for an optional name or expression. Do
1395 -- not generate a pragma with empty argument association list.
b855559d 1396
1397 if No (Args) or else No (Expression (First (Args))) then
1398 Args := No_List;
1399 end if;
1400
0fd13d32 1401 -- Build the pragma
1402
1403 Aitem :=
1404 Make_Pragma (Loc,
b855559d 1405 Pragma_Argument_Associations => Args,
0fd13d32 1406 Pragma_Identifier =>
1407 Make_Identifier (Sloc (Id), Pragma_Name),
9ab32fe9 1408 Class_Present => Class_Present (Aspect),
1409 Split_PPC => Split_PPC (Aspect));
0fd13d32 1410
1411 -- Set additional semantic fields
1412
1413 if Is_Ignored (Aspect) then
1414 Set_Is_Ignored (Aitem);
57d8d1f3 1415 elsif Is_Checked (Aspect) then
a5109493 1416 Set_Is_Checked (Aitem);
0fd13d32 1417 end if;
1418
1419 Set_Corresponding_Aspect (Aitem, Aspect);
1420 Set_From_Aspect_Specification (Aitem, True);
1421 end Make_Aitem_Pragma;
1422
1423 -- Start of processing for Analyze_One_Aspect
1424
ae888dbd 1425 begin
fb7f2fc4 1426 -- Skip aspect if already analyzed (not clear if this is needed)
1427
1428 if Analyzed (Aspect) then
1429 goto Continue;
1430 end if;
1431
ef957022 1432 -- Skip looking at aspect if it is totally disabled. Just mark it
1433 -- as such for later reference in the tree. This also sets the
1434 -- Is_Ignored and Is_Checked flags appropriately.
51ea9c94 1435
1436 Check_Applicable_Policy (Aspect);
1437
1438 if Is_Disabled (Aspect) then
1439 goto Continue;
1440 end if;
1441
c0793fff 1442 -- Set the source location of expression, used in the case of
1443 -- a failed precondition/postcondition or invariant. Note that
1444 -- the source location of the expression is not usually the best
1445 -- choice here. For example, it gets located on the last AND
1446 -- keyword in a chain of boolean expressiond AND'ed together.
1447 -- It is best to put the message on the first character of the
1448 -- assertion, which is the effect of the First_Node call here.
1449
1450 if Present (Expr) then
1451 Eloc := Sloc (First_Node (Expr));
1452 end if;
1453
d7ed83a2 1454 -- Check restriction No_Implementation_Aspect_Specifications
1455
c171e1be 1456 if Implementation_Defined_Aspect (A_Id) then
d7ed83a2 1457 Check_Restriction
1458 (No_Implementation_Aspect_Specifications, Aspect);
1459 end if;
1460
1461 -- Check restriction No_Specification_Of_Aspect
1462
1463 Check_Restriction_No_Specification_Of_Aspect (Aspect);
1464
51ea9c94 1465 -- Analyze this aspect (actual analysis is delayed till later)
d7ed83a2 1466
fb7f2fc4 1467 Set_Analyzed (Aspect);
d74fc39a 1468 Set_Entity (Aspect, E);
1469 Ent := New_Occurrence_Of (E, Sloc (Id));
1470
1e3c4ae6 1471 -- Check for duplicate aspect. Note that the Comes_From_Source
1472 -- test allows duplicate Pre/Post's that we generate internally
1473 -- to escape being flagged here.
ae888dbd 1474
6c545057 1475 if No_Duplicates_Allowed (A_Id) then
1476 Anod := First (L);
1477 while Anod /= Aspect loop
c171e1be 1478 if Comes_From_Source (Aspect)
1479 and then Same_Aspect (A_Id, Get_Aspect_Id (Anod))
6c545057 1480 then
1481 Error_Msg_Name_1 := Nam;
1482 Error_Msg_Sloc := Sloc (Anod);
39e1f22f 1483
6c545057 1484 -- Case of same aspect specified twice
39e1f22f 1485
6c545057 1486 if Class_Present (Anod) = Class_Present (Aspect) then
1487 if not Class_Present (Anod) then
1488 Error_Msg_NE
1489 ("aspect% for & previously given#",
1490 Id, E);
1491 else
1492 Error_Msg_NE
1493 ("aspect `%''Class` for & previously given#",
1494 Id, E);
1495 end if;
39e1f22f 1496 end if;
6c545057 1497 end if;
ae888dbd 1498
6c545057 1499 Next (Anod);
1500 end loop;
1501 end if;
ae888dbd 1502
4db325e6 1503 -- Check some general restrictions on language defined aspects
1504
c171e1be 1505 if not Implementation_Defined_Aspect (A_Id) then
4db325e6 1506 Error_Msg_Name_1 := Nam;
1507
1508 -- Not allowed for renaming declarations
1509
1510 if Nkind (N) in N_Renaming_Declaration then
1511 Error_Msg_N
1512 ("aspect % not allowed for renaming declaration",
1513 Aspect);
1514 end if;
1515
1516 -- Not allowed for formal type declarations
1517
1518 if Nkind (N) = N_Formal_Type_Declaration then
1519 Error_Msg_N
1520 ("aspect % not allowed for formal type declaration",
1521 Aspect);
1522 end if;
1523 end if;
1524
7d20685d 1525 -- Copy expression for later processing by the procedures
1526 -- Check_Aspect_At_[Freeze_Point | End_Of_Declarations]
1527
1528 Set_Entity (Id, New_Copy_Tree (Expr));
1529
37c6e44c 1530 -- Set Delay_Required as appropriate to aspect
1531
1532 case Aspect_Delay (A_Id) is
1533 when Always_Delay =>
1534 Delay_Required := True;
1535
1536 when Never_Delay =>
1537 Delay_Required := False;
1538
1539 when Rep_Aspect =>
1540
1541 -- If expression has the form of an integer literal, then
1542 -- do not delay, since we know the value cannot change.
1543 -- This optimization catches most rep clause cases.
1544
1545 if (Present (Expr) and then Nkind (Expr) = N_Integer_Literal)
1546 or else (A_Id in Boolean_Aspects and then No (Expr))
1547 then
1548 Delay_Required := False;
1549 else
1550 Delay_Required := True;
1551 Set_Has_Delayed_Rep_Aspects (E);
1552 end if;
1553 end case;
1554
ae888dbd 1555 -- Processing based on specific aspect
1556
d74fc39a 1557 case A_Id is
ae888dbd 1558
1559 -- No_Aspect should be impossible
1560
1561 when No_Aspect =>
1562 raise Program_Error;
1563
89f1e35c 1564 -- Case 1: Aspects corresponding to attribute definition
1565 -- clauses.
ae888dbd 1566
b7b74740 1567 when Aspect_Address |
1568 Aspect_Alignment |
1569 Aspect_Bit_Order |
1570 Aspect_Component_Size |
89f1e35c 1571 Aspect_Constant_Indexing |
89f1e35c 1572 Aspect_Default_Iterator |
1573 Aspect_Dispatching_Domain |
b7b74740 1574 Aspect_External_Tag |
1575 Aspect_Input |
89f1e35c 1576 Aspect_Iterator_Element |
b7b74740 1577 Aspect_Machine_Radix |
1578 Aspect_Object_Size |
1579 Aspect_Output |
1580 Aspect_Read |
1581 Aspect_Scalar_Storage_Order |
1582 Aspect_Size |
1583 Aspect_Small |
1584 Aspect_Simple_Storage_Pool |
1585 Aspect_Storage_Pool |
b7b74740 1586 Aspect_Stream_Size |
1587 Aspect_Value_Size |
89f1e35c 1588 Aspect_Variable_Indexing |
b7b74740 1589 Aspect_Write =>
d74fc39a 1590
89f1e35c 1591 -- Indexing aspects apply only to tagged type
1592
1593 if (A_Id = Aspect_Constant_Indexing
37c6e44c 1594 or else
1595 A_Id = Aspect_Variable_Indexing)
89f1e35c 1596 and then not (Is_Type (E)
1597 and then Is_Tagged_Type (E))
1598 then
1599 Error_Msg_N ("indexing applies to a tagged type", N);
1600 goto Continue;
1601 end if;
1602
588e7f97 1603 -- For case of address aspect, we don't consider that we
1604 -- know the entity is never set in the source, since it is
1605 -- is likely aliasing is occurring.
1606
1607 -- Note: one might think that the analysis of the resulting
1608 -- attribute definition clause would take care of that, but
1609 -- that's not the case since it won't be from source.
1610
1611 if A_Id = Aspect_Address then
1612 Set_Never_Set_In_Source (E, False);
1613 end if;
1614
d74fc39a 1615 -- Construct the attribute definition clause
1616
1617 Aitem :=
94153a42 1618 Make_Attribute_Definition_Clause (Loc,
d74fc39a 1619 Name => Ent,
ae888dbd 1620 Chars => Chars (Id),
1621 Expression => Relocate_Node (Expr));
1622
af9a0cc3 1623 -- If the address is specified, then we treat the entity as
41f06abf 1624 -- referenced, to avoid spurious warnings. This is analogous
1625 -- to what is done with an attribute definition clause, but
1626 -- here we don't want to generate a reference because this
1627 -- is the point of definition of the entity.
1628
1629 if A_Id = Aspect_Address then
1630 Set_Referenced (E);
1631 end if;
1632
51ea9c94 1633 -- Case 2: Aspects corresponding to pragmas
d74fc39a 1634
89f1e35c 1635 -- Case 2a: Aspects corresponding to pragmas with two
1636 -- arguments, where the first argument is a local name
1637 -- referring to the entity, and the second argument is the
1638 -- aspect definition expression.
ae888dbd 1639
0fd13d32 1640 -- Suppress/Unsuppress
1641
ae888dbd 1642 when Aspect_Suppress |
1643 Aspect_Unsuppress =>
1644
0fd13d32 1645 Make_Aitem_Pragma
1646 (Pragma_Argument_Associations => New_List (
1647 Make_Pragma_Argument_Association (Loc,
1648 Expression => New_Occurrence_Of (E, Loc)),
1649 Make_Pragma_Argument_Association (Sloc (Expr),
1650 Expression => Relocate_Node (Expr))),
1651 Pragma_Name => Chars (Id));
57cd943b 1652
0fd13d32 1653 -- Synchronization
d74fc39a 1654
0fd13d32 1655 -- Corresponds to pragma Implemented, construct the pragma
49213728 1656
5bbfbad2 1657 when Aspect_Synchronization =>
57cd943b 1658
0fd13d32 1659 Make_Aitem_Pragma
1660 (Pragma_Argument_Associations => New_List (
1661 Make_Pragma_Argument_Association (Loc,
1662 Expression => New_Occurrence_Of (E, Loc)),
1663 Make_Pragma_Argument_Association (Sloc (Expr),
1664 Expression => Relocate_Node (Expr))),
1665 Pragma_Name => Name_Implemented);
49213728 1666
0fd13d32 1667 -- Attach Handler
1668
89f1e35c 1669 when Aspect_Attach_Handler =>
0fd13d32 1670 Make_Aitem_Pragma
1671 (Pragma_Argument_Associations => New_List (
1672 Make_Pragma_Argument_Association (Sloc (Ent),
1673 Expression => Ent),
1674 Make_Pragma_Argument_Association (Sloc (Expr),
1675 Expression => Relocate_Node (Expr))),
1676 Pragma_Name => Name_Attach_Handler);
1677
1678 -- Dynamic_Predicate, Predicate, Static_Predicate
89f1e35c 1679
1680 when Aspect_Dynamic_Predicate |
1681 Aspect_Predicate |
1682 Aspect_Static_Predicate =>
1683
1684 -- Construct the pragma (always a pragma Predicate, with
51ea9c94 1685 -- flags recording whether it is static/dynamic). We also
1686 -- set flags recording this in the type itself.
89f1e35c 1687
0fd13d32 1688 Make_Aitem_Pragma
1689 (Pragma_Argument_Associations => New_List (
1690 Make_Pragma_Argument_Association (Sloc (Ent),
1691 Expression => Ent),
1692 Make_Pragma_Argument_Association (Sloc (Expr),
1693 Expression => Relocate_Node (Expr))),
1694 Pragma_Name => Name_Predicate);
89f1e35c 1695
51ea9c94 1696 -- Mark type has predicates, and remember what kind of
1697 -- aspect lead to this predicate (we need this to access
1698 -- the right set of check policies later on).
1699
1700 Set_Has_Predicates (E);
1701
1702 if A_Id = Aspect_Dynamic_Predicate then
1703 Set_Has_Dynamic_Predicate_Aspect (E);
1704 elsif A_Id = Aspect_Static_Predicate then
1705 Set_Has_Static_Predicate_Aspect (E);
1706 end if;
1707
89f1e35c 1708 -- If the type is private, indicate that its completion
1709 -- has a freeze node, because that is the one that will be
1710 -- visible at freeze time.
1711
0fd13d32 1712 if Is_Private_Type (E) and then Present (Full_View (E)) then
89f1e35c 1713 Set_Has_Predicates (Full_View (E));
51ea9c94 1714
1715 if A_Id = Aspect_Dynamic_Predicate then
1716 Set_Has_Dynamic_Predicate_Aspect (Full_View (E));
1717 elsif A_Id = Aspect_Static_Predicate then
1718 Set_Has_Static_Predicate_Aspect (Full_View (E));
1719 end if;
1720
89f1e35c 1721 Set_Has_Delayed_Aspects (Full_View (E));
1722 Ensure_Freeze_Node (Full_View (E));
1723 end if;
1724
1725 -- Case 2b: Aspects corresponding to pragmas with two
1726 -- arguments, where the second argument is a local name
1727 -- referring to the entity, and the first argument is the
1728 -- aspect definition expression.
ae888dbd 1729
0fd13d32 1730 -- Convention
1731
a5a64273 1732 when Aspect_Convention =>
1733
1734 -- The aspect may be part of the specification of an import
1735 -- or export pragma. Scan the aspect list to gather the
1736 -- other components, if any. The name of the generated
1737 -- pragma is one of Convention/Import/Export.
1738
1739 declare
1740 P_Name : Name_Id;
1741 A_Name : Name_Id;
1742 A : Node_Id;
1743 Arg_List : List_Id;
1744 Found : Boolean;
1745 L_Assoc : Node_Id;
1746 E_Assoc : Node_Id;
1747
1748 begin
1749 P_Name := Chars (Id);
1750 Found := False;
1751 Arg_List := New_List;
1752 L_Assoc := Empty;
1753 E_Assoc := Empty;
1754
1755 A := First (L);
1756 while Present (A) loop
1757 A_Name := Chars (Identifier (A));
1758
18393965 1759 if Nam_In (A_Name, Name_Import, Name_Export) then
a5a64273 1760 if Found then
89f1e35c 1761 Error_Msg_N ("conflicting", A);
a5a64273 1762 else
1763 Found := True;
1764 end if;
1765
1766 P_Name := A_Name;
1767
1768 elsif A_Name = Name_Link_Name then
4bba0a8d 1769 L_Assoc :=
1770 Make_Pragma_Argument_Association (Loc,
1771 Chars => A_Name,
1772 Expression => Relocate_Node (Expression (A)));
a5a64273 1773
1774 elsif A_Name = Name_External_Name then
4bba0a8d 1775 E_Assoc :=
1776 Make_Pragma_Argument_Association (Loc,
1777 Chars => A_Name,
1778 Expression => Relocate_Node (Expression (A)));
a5a64273 1779 end if;
1780
1781 Next (A);
1782 end loop;
1783
57cd943b 1784 Arg_List := New_List (
1785 Make_Pragma_Argument_Association (Sloc (Expr),
1786 Expression => Relocate_Node (Expr)),
1787 Make_Pragma_Argument_Association (Sloc (Ent),
1788 Expression => Ent));
b9e61b2a 1789
a5a64273 1790 if Present (L_Assoc) then
1791 Append_To (Arg_List, L_Assoc);
1792 end if;
1793
1794 if Present (E_Assoc) then
1795 Append_To (Arg_List, E_Assoc);
1796 end if;
1797
0fd13d32 1798 Make_Aitem_Pragma
1799 (Pragma_Argument_Associations => Arg_List,
1800 Pragma_Name => P_Name);
a5a64273 1801 end;
e1cedbae 1802
0fd13d32 1803 -- CPU, Interrupt_Priority, Priority
1804
1805 -- These three aspects can be specified for a subprogram body,
1806 -- in which case we generate pragmas for them and insert them
1807 -- ahead of local declarations, rather than after the body.
3a72f9c3 1808
1809 when Aspect_CPU |
1810 Aspect_Interrupt_Priority |
1811 Aspect_Priority =>
51ea9c94 1812
3a72f9c3 1813 if Nkind (N) = N_Subprogram_Body then
0fd13d32 1814 Make_Aitem_Pragma
1815 (Pragma_Argument_Associations => New_List (
1816 Make_Pragma_Argument_Association (Sloc (Expr),
1817 Expression => Relocate_Node (Expr))),
1818 Pragma_Name => Chars (Id));
1819
3a72f9c3 1820 else
1821 Aitem :=
1822 Make_Attribute_Definition_Clause (Loc,
1823 Name => Ent,
1824 Chars => Chars (Id),
1825 Expression => Relocate_Node (Expr));
1826 end if;
1827
0fd13d32 1828 -- Warnings
1829
ae888dbd 1830 when Aspect_Warnings =>
0fd13d32 1831 Make_Aitem_Pragma
1832 (Pragma_Argument_Associations => New_List (
1833 Make_Pragma_Argument_Association (Sloc (Expr),
1834 Expression => Relocate_Node (Expr)),
1835 Make_Pragma_Argument_Association (Loc,
1836 Expression => New_Occurrence_Of (E, Loc))),
1837 Pragma_Name => Chars (Id));
ae888dbd 1838
89f1e35c 1839 -- Case 2c: Aspects corresponding to pragmas with three
1840 -- arguments.
d64221a7 1841
89f1e35c 1842 -- Invariant aspects have a first argument that references the
1843 -- entity, a second argument that is the expression and a third
1844 -- argument that is an appropriate message.
d64221a7 1845
0fd13d32 1846 -- Invariant, Type_Invariant
1847
89f1e35c 1848 when Aspect_Invariant |
1849 Aspect_Type_Invariant =>
d64221a7 1850
89f1e35c 1851 -- Analysis of the pragma will verify placement legality:
1852 -- an invariant must apply to a private type, or appear in
1853 -- the private part of a spec and apply to a completion.
d64221a7 1854
0fd13d32 1855 Make_Aitem_Pragma
1856 (Pragma_Argument_Associations => New_List (
1857 Make_Pragma_Argument_Association (Sloc (Ent),
1858 Expression => Ent),
1859 Make_Pragma_Argument_Association (Sloc (Expr),
1860 Expression => Relocate_Node (Expr))),
1861 Pragma_Name => Name_Invariant);
89f1e35c 1862
1863 -- Add message unless exception messages are suppressed
1864
1865 if not Opt.Exception_Locations_Suppressed then
1866 Append_To (Pragma_Argument_Associations (Aitem),
1867 Make_Pragma_Argument_Association (Eloc,
1868 Chars => Name_Message,
1869 Expression =>
1870 Make_String_Literal (Eloc,
1871 Strval => "failed invariant from "
1872 & Build_Location_String (Eloc))));
d64221a7 1873 end if;
1874
89f1e35c 1875 -- For Invariant case, insert immediately after the entity
1876 -- declaration. We do not have to worry about delay issues
1877 -- since the pragma processing takes care of this.
1878
89f1e35c 1879 Delay_Required := False;
d64221a7 1880
47a46747 1881 -- Case 2d : Aspects that correspond to a pragma with one
1882 -- argument.
1883
0fd13d32 1884 -- Abstract_State
115f7b08 1885
d4e369ad 1886 -- Aspect Abstract_State introduces implicit declarations for
1887 -- all state abstraction entities it defines. To emulate this
1888 -- behavior, insert the pragma at the beginning of the visible
1889 -- declarations of the related package so that it is analyzed
1890 -- immediately.
1891
9129c28f 1892 when Aspect_Abstract_State => Abstract_State : declare
1893 Decls : List_Id;
9129c28f 1894
1895 begin
9129c28f 1896 if Nkind_In (N, N_Generic_Package_Declaration,
1897 N_Package_Declaration)
1898 then
d4e369ad 1899 Decls := Visible_Declarations (Specification (N));
9129c28f 1900
1901 Make_Aitem_Pragma
1902 (Pragma_Argument_Associations => New_List (
1903 Make_Pragma_Argument_Association (Loc,
1904 Expression => Relocate_Node (Expr))),
1905 Pragma_Name => Name_Abstract_State);
1906 Decorate_Delayed_Aspect_And_Pragma (Aspect, Aitem);
1907
1908 if No (Decls) then
1909 Decls := New_List;
1910 Set_Visible_Declarations (N, Decls);
1911 end if;
1912
1913 Prepend_To (Decls, Aitem);
1914
1915 else
1916 Error_Msg_NE
1917 ("aspect & must apply to a package declaration",
1918 Aspect, Id);
1919 end if;
1920
1921 goto Continue;
1922 end Abstract_State;
115f7b08 1923
0fd13d32 1924 -- Depends
1925
6144c105 1926 -- Aspect Depends must be delayed because it mentions names
1927 -- of inputs and output that are classified by aspect Global.
c1006d6d 1928 -- The aspect and pragma are treated the same way as a post
1929 -- condition.
6144c105 1930
12334c57 1931 when Aspect_Depends =>
0fd13d32 1932 Make_Aitem_Pragma
1933 (Pragma_Argument_Associations => New_List (
1934 Make_Pragma_Argument_Association (Loc,
1935 Expression => Relocate_Node (Expr))),
1936 Pragma_Name => Name_Depends);
1937
5ddd846b 1938 Decorate_Delayed_Aspect_And_Pragma (Aspect, Aitem);
c1006d6d 1939 Insert_Delayed_Pragma (Aitem);
1940 goto Continue;
1941
0fd13d32 1942 -- Global
12334c57 1943
3cdbaa5a 1944 -- Aspect Global must be delayed because it can mention names
1945 -- and benefit from the forward visibility rules applicable to
c1006d6d 1946 -- aspects of subprograms. The aspect and pragma are treated
1947 -- the same way as a post condition.
3cdbaa5a 1948
1949 when Aspect_Global =>
0fd13d32 1950 Make_Aitem_Pragma
1951 (Pragma_Argument_Associations => New_List (
1952 Make_Pragma_Argument_Association (Loc,
1953 Expression => Relocate_Node (Expr))),
1954 Pragma_Name => Name_Global);
1955
5ddd846b 1956 Decorate_Delayed_Aspect_And_Pragma (Aspect, Aitem);
c1006d6d 1957 Insert_Delayed_Pragma (Aitem);
1958 goto Continue;
1959
d4e369ad 1960 -- Initializes
1961
1962 -- Aspect Initializes coverts the visible declarations of a
1963 -- package. As such, it must be evaluated at the end of the
1964 -- said declarations.
1965
1966 when Aspect_Initializes => Initializes : declare
1967 Decls : List_Id;
1968
1969 begin
1970 if Nkind_In (N, N_Generic_Package_Declaration,
1971 N_Package_Declaration)
1972 then
1973 Decls := Visible_Declarations (Specification (N));
1974
1975 Make_Aitem_Pragma
1976 (Pragma_Argument_Associations => New_List (
1977 Make_Pragma_Argument_Association (Loc,
1978 Expression => Relocate_Node (Expr))),
1979 Pragma_Name => Name_Initializes);
1980 Decorate_Delayed_Aspect_And_Pragma (Aspect, Aitem);
1981
1982 if No (Decls) then
1983 Decls := New_List;
1984 Set_Visible_Declarations (N, Decls);
1985 end if;
1986
1987 Prepend_To (Decls, Aitem);
1988
1989 else
1990 Error_Msg_NE
1991 ("aspect & must apply to a package declaration",
1992 Aspect, Id);
1993 end if;
1994
1995 goto Continue;
1996 end Initializes;
1997
5dd93a61 1998 -- SPARK_Mode
1999
2000 when Aspect_SPARK_Mode =>
2001 Make_Aitem_Pragma
2002 (Pragma_Argument_Associations => New_List (
2003 Make_Pragma_Argument_Association (Loc,
2004 Expression => Relocate_Node (Expr))),
2005 Pragma_Name => Name_SPARK_Mode);
5dd93a61 2006
4befb1a0 2007 -- Refined_Depends
2008
2009 -- ??? To be implemented
2010
2011 when Aspect_Refined_Depends =>
2012 null;
2013
2014 -- Refined_Global
2015
28ff117f 2016 -- Aspect Refined_Global must be delayed because it can mention
2017 -- state refinements introduced by aspect Refined_State. Since
2018 -- Refined_State is already delayed due to forward references,
2019 -- so is Refined_Global.
4befb1a0 2020
2021 when Aspect_Refined_Global =>
28ff117f 2022 Make_Aitem_Pragma
2023 (Pragma_Argument_Associations => New_List (
2024 Make_Pragma_Argument_Association (Loc,
2025 Expression => Relocate_Node (Expr))),
2026 Pragma_Name => Name_Refined_Global);
2027
2028 Decorate_Delayed_Aspect_And_Pragma (Aspect, Aitem);
2029 Insert_Delayed_Pragma (Aitem);
2030 goto Continue;
4befb1a0 2031
63b65b2d 2032 -- Refined_Post
2033
2034 when Aspect_Refined_Post =>
2035 Make_Aitem_Pragma
2036 (Pragma_Argument_Associations => New_List (
2037 Make_Pragma_Argument_Association (Loc,
2038 Expression => Relocate_Node (Expr))),
2039 Pragma_Name => Name_Refined_Post);
2040
7179006e 2041 -- Refined_Pre
2042
2043 when Aspect_Refined_Pre =>
2044 Make_Aitem_Pragma
2045 (Pragma_Argument_Associations => New_List (
2046 Make_Pragma_Argument_Association (Loc,
2047 Expression => Relocate_Node (Expr))),
2048 Pragma_Name => Name_Refined_Pre);
2049
9129c28f 2050 -- Refined_State
2051
2052 when Aspect_Refined_State => Refined_State : declare
2053 Decls : List_Id;
2054
2055 begin
2056 -- The corresponding pragma for Refined_State is inserted in
2057 -- the declarations of the related package body. This action
2058 -- synchronizes both the source and from-aspect versions of
2059 -- the pragma.
2060
2061 if Nkind (N) = N_Package_Body then
2062 Decls := Declarations (N);
2063
2064 Make_Aitem_Pragma
2065 (Pragma_Argument_Associations => New_List (
2066 Make_Pragma_Argument_Association (Loc,
2067 Expression => Relocate_Node (Expr))),
2068 Pragma_Name => Name_Refined_State);
2069 Decorate_Delayed_Aspect_And_Pragma (Aspect, Aitem);
2070
2071 if No (Decls) then
2072 Decls := New_List;
2073 Set_Declarations (N, Decls);
2074 end if;
2075
2076 Prepend_To (Decls, Aitem);
2077
2078 else
2079 Error_Msg_NE
2080 ("aspect & must apply to a package body", Aspect, Id);
2081 end if;
2082
2083 goto Continue;
2084 end Refined_State;
2085
0fd13d32 2086 -- Relative_Deadline
3cdbaa5a 2087
2088 when Aspect_Relative_Deadline =>
0fd13d32 2089 Make_Aitem_Pragma
2090 (Pragma_Argument_Associations => New_List (
2091 Make_Pragma_Argument_Association (Loc,
2092 Expression => Relocate_Node (Expr))),
2093 Pragma_Name => Name_Relative_Deadline);
47a46747 2094
2095 -- If the aspect applies to a task, the corresponding pragma
2096 -- must appear within its declarations, not after.
2097
2098 if Nkind (N) = N_Task_Type_Declaration then
2099 declare
2100 Def : Node_Id;
2101 V : List_Id;
2102
2103 begin
2104 if No (Task_Definition (N)) then
2105 Set_Task_Definition (N,
2106 Make_Task_Definition (Loc,
2107 Visible_Declarations => New_List,
2108 End_Label => Empty));
2109 end if;
2110
2111 Def := Task_Definition (N);
2112 V := Visible_Declarations (Def);
2113 if not Is_Empty_List (V) then
2114 Insert_Before (First (V), Aitem);
2115
2116 else
2117 Set_Visible_Declarations (Def, New_List (Aitem));
2118 end if;
2119
2120 goto Continue;
2121 end;
2122 end if;
2123
89f1e35c 2124 -- Case 3 : Aspects that don't correspond to pragma/attribute
2125 -- definition clause.
7b9b2f05 2126
89f1e35c 2127 -- Case 3a: The aspects listed below don't correspond to
2128 -- pragmas/attributes but do require delayed analysis.
7f694ca2 2129
0fd13d32 2130 -- Default_Value, Default_Component_Value
2131
89f1e35c 2132 when Aspect_Default_Value |
2133 Aspect_Default_Component_Value =>
2134 Aitem := Empty;
7f694ca2 2135
89f1e35c 2136 -- Case 3b: The aspects listed below don't correspond to
2137 -- pragmas/attributes and don't need delayed analysis.
95bc75fa 2138
0fd13d32 2139 -- Implicit_Dereference
2140
89f1e35c 2141 -- For Implicit_Dereference, External_Name and Link_Name, only
2142 -- the legality checks are done during the analysis, thus no
2143 -- delay is required.
a8e38e1d 2144
89f1e35c 2145 when Aspect_Implicit_Dereference =>
2146 Analyze_Aspect_Implicit_Dereference;
2147 goto Continue;
7f694ca2 2148
0fd13d32 2149 -- External_Name, Link_Name
2150
89f1e35c 2151 when Aspect_External_Name |
2152 Aspect_Link_Name =>
2153 Analyze_Aspect_External_Or_Link_Name;
2154 goto Continue;
7f694ca2 2155
0fd13d32 2156 -- Dimension
2157
89f1e35c 2158 when Aspect_Dimension =>
2159 Analyze_Aspect_Dimension (N, Id, Expr);
2160 goto Continue;
cb4c311d 2161
0fd13d32 2162 -- Dimension_System
2163
89f1e35c 2164 when Aspect_Dimension_System =>
2165 Analyze_Aspect_Dimension_System (N, Id, Expr);
2166 goto Continue;
7f694ca2 2167
ceec4f7c 2168 -- Case 4: Aspects requiring special handling
51ea9c94 2169
e66f4e2a 2170 -- Pre/Post/Test_Case/Contract_Cases whose corresponding
2171 -- pragmas take care of the delay.
7f694ca2 2172
0fd13d32 2173 -- Pre/Post
2174
1e3c4ae6 2175 -- Aspects Pre/Post generate Precondition/Postcondition pragmas
2176 -- with a first argument that is the expression, and a second
2177 -- argument that is an informative message if the test fails.
2178 -- This is inserted right after the declaration, to get the
5b5df4a9 2179 -- required pragma placement. The processing for the pragmas
2180 -- takes care of the required delay.
ae888dbd 2181
5ddd846b 2182 when Pre_Post_Aspects => Pre_Post : declare
1e3c4ae6 2183 Pname : Name_Id;
ae888dbd 2184
1e3c4ae6 2185 begin
77ae6789 2186 if A_Id = Aspect_Pre or else A_Id = Aspect_Precondition then
1e3c4ae6 2187 Pname := Name_Precondition;
2188 else
2189 Pname := Name_Postcondition;
2190 end if;
d74fc39a 2191
1e3c4ae6 2192 -- If the expressions is of the form A and then B, then
2193 -- we generate separate Pre/Post aspects for the separate
2194 -- clauses. Since we allow multiple pragmas, there is no
2195 -- problem in allowing multiple Pre/Post aspects internally.
a273015d 2196 -- These should be treated in reverse order (B first and
2197 -- A second) since they are later inserted just after N in
2198 -- the order they are treated. This way, the pragma for A
2199 -- ends up preceding the pragma for B, which may have an
2200 -- importance for the error raised (either constraint error
2201 -- or precondition error).
1e3c4ae6 2202
39e1f22f 2203 -- We do not do this for Pre'Class, since we have to put
2204 -- these conditions together in a complex OR expression
ae888dbd 2205
4282d342 2206 -- We do not do this in ASIS mode, as ASIS relies on the
2207 -- original node representing the complete expression, when
2208 -- retrieving it through the source aspect table.
2209
2210 if not ASIS_Mode
2211 and then (Pname = Name_Postcondition
2212 or else not Class_Present (Aspect))
39e1f22f 2213 then
2214 while Nkind (Expr) = N_And_Then loop
2215 Insert_After (Aspect,
a273015d 2216 Make_Aspect_Specification (Sloc (Left_Opnd (Expr)),
39e1f22f 2217 Identifier => Identifier (Aspect),
a273015d 2218 Expression => Relocate_Node (Left_Opnd (Expr)),
39e1f22f 2219 Class_Present => Class_Present (Aspect),
2220 Split_PPC => True));
a273015d 2221 Rewrite (Expr, Relocate_Node (Right_Opnd (Expr)));
39e1f22f 2222 Eloc := Sloc (Expr);
2223 end loop;
2224 end if;
ae888dbd 2225
48d6f069 2226 -- Build the precondition/postcondition pragma
2227
2228 -- Add note about why we do NOT need Copy_Tree here ???
d74fc39a 2229
0fd13d32 2230 Make_Aitem_Pragma
2231 (Pragma_Argument_Associations => New_List (
2232 Make_Pragma_Argument_Association (Eloc,
2233 Chars => Name_Check,
a19e1763 2234 Expression => Relocate_Node (Expr))),
0fd13d32 2235 Pragma_Name => Pname);
39e1f22f 2236
2237 -- Add message unless exception messages are suppressed
2238
2239 if not Opt.Exception_Locations_Suppressed then
2240 Append_To (Pragma_Argument_Associations (Aitem),
2241 Make_Pragma_Argument_Association (Eloc,
2242 Chars => Name_Message,
2243 Expression =>
2244 Make_String_Literal (Eloc,
2245 Strval => "failed "
2246 & Get_Name_String (Pname)
2247 & " from "
2248 & Build_Location_String (Eloc))));
2249 end if;
d74fc39a 2250
7d20685d 2251 Set_Is_Delayed_Aspect (Aspect);
d74fc39a 2252
1e3c4ae6 2253 -- For Pre/Post cases, insert immediately after the entity
2254 -- declaration, since that is the required pragma placement.
2255 -- Note that for these aspects, we do not have to worry
2256 -- about delay issues, since the pragmas themselves deal
2257 -- with delay of visibility for the expression analysis.
2258
c1006d6d 2259 Insert_Delayed_Pragma (Aitem);
1e3c4ae6 2260 goto Continue;
5ddd846b 2261 end Pre_Post;
ae888dbd 2262
0fd13d32 2263 -- Test_Case
2264
e66f4e2a 2265 when Aspect_Test_Case => Test_Case : declare
2266 Args : List_Id;
2267 Comp_Expr : Node_Id;
2268 Comp_Assn : Node_Id;
2269 New_Expr : Node_Id;
57cd943b 2270
e66f4e2a 2271 begin
2272 Args := New_List;
b0bc40fd 2273
e66f4e2a 2274 if Nkind (Parent (N)) = N_Compilation_Unit then
2275 Error_Msg_Name_1 := Nam;
2276 Error_Msg_N ("incorrect placement of aspect `%`", E);
2277 goto Continue;
2278 end if;
6c545057 2279
e66f4e2a 2280 if Nkind (Expr) /= N_Aggregate then
2281 Error_Msg_Name_1 := Nam;
2282 Error_Msg_NE
2283 ("wrong syntax for aspect `%` for &", Id, E);
2284 goto Continue;
2285 end if;
6c545057 2286
e66f4e2a 2287 -- Make pragma expressions refer to the original aspect
2288 -- expressions through the Original_Node link. This is
2289 -- used in semantic analysis for ASIS mode, so that the
2290 -- original expression also gets analyzed.
2291
2292 Comp_Expr := First (Expressions (Expr));
2293 while Present (Comp_Expr) loop
2294 New_Expr := Relocate_Node (Comp_Expr);
2295 Set_Original_Node (New_Expr, Comp_Expr);
2296 Append_To (Args,
2297 Make_Pragma_Argument_Association (Sloc (Comp_Expr),
2298 Expression => New_Expr));
2299 Next (Comp_Expr);
2300 end loop;
2301
2302 Comp_Assn := First (Component_Associations (Expr));
2303 while Present (Comp_Assn) loop
2304 if List_Length (Choices (Comp_Assn)) /= 1
2305 or else
2306 Nkind (First (Choices (Comp_Assn))) /= N_Identifier
2307 then
fad014fe 2308 Error_Msg_Name_1 := Nam;
6c545057 2309 Error_Msg_NE
fad014fe 2310 ("wrong syntax for aspect `%` for &", Id, E);
6c545057 2311 goto Continue;
2312 end if;
2313
e66f4e2a 2314 New_Expr := Relocate_Node (Expression (Comp_Assn));
2315 Set_Original_Node (New_Expr, Expression (Comp_Assn));
2316 Append_To (Args,
2317 Make_Pragma_Argument_Association (Sloc (Comp_Assn),
2318 Chars => Chars (First (Choices (Comp_Assn))),
2319 Expression => New_Expr));
2320 Next (Comp_Assn);
2321 end loop;
6c545057 2322
e66f4e2a 2323 -- Build the test-case pragma
6c545057 2324
0fd13d32 2325 Make_Aitem_Pragma
2326 (Pragma_Argument_Associations => Args,
2327 Pragma_Name => Nam);
e66f4e2a 2328 end Test_Case;
85696508 2329
0fd13d32 2330 -- Contract_Cases
2331
5ddd846b 2332 when Aspect_Contract_Cases =>
0fd13d32 2333 Make_Aitem_Pragma
2334 (Pragma_Argument_Associations => New_List (
2335 Make_Pragma_Argument_Association (Loc,
2336 Expression => Relocate_Node (Expr))),
2337 Pragma_Name => Nam);
3a128918 2338
5ddd846b 2339 Decorate_Delayed_Aspect_And_Pragma (Aspect, Aitem);
2340 Insert_Delayed_Pragma (Aitem);
2341 goto Continue;
3a128918 2342
89f1e35c 2343 -- Case 5: Special handling for aspects with an optional
2344 -- boolean argument.
85696508 2345
89f1e35c 2346 -- In the general case, the corresponding pragma cannot be
0fd13d32 2347 -- generated yet because the evaluation of the boolean needs
2348 -- to be delayed till the freeze point.
2349
89f1e35c 2350 when Boolean_Aspects |
2351 Library_Unit_Aspects =>
a5a64273 2352
89f1e35c 2353 Set_Is_Boolean_Aspect (Aspect);
a5a64273 2354
89f1e35c 2355 -- Lock_Free aspect only apply to protected objects
e1cedbae 2356
89f1e35c 2357 if A_Id = Aspect_Lock_Free then
2358 if Ekind (E) /= E_Protected_Type then
99a2d5bd 2359 Error_Msg_Name_1 := Nam;
a5a64273 2360 Error_Msg_N
89f1e35c 2361 ("aspect % only applies to a protected object",
2362 Aspect);
2363
2364 else
2365 -- Set the Uses_Lock_Free flag to True if there is no
37c6e44c 2366 -- expression or if the expression is True. The
89f1e35c 2367 -- evaluation of this aspect should be delayed to the
37c6e44c 2368 -- freeze point (why???)
89f1e35c 2369
2370 if No (Expr)
2371 or else Is_True (Static_Boolean (Expr))
2372 then
2373 Set_Uses_Lock_Free (E);
2374 end if;
caf125ce 2375
2376 Record_Rep_Item (E, Aspect);
a5a64273 2377 end if;
e1cedbae 2378
89f1e35c 2379 goto Continue;
ae888dbd 2380
17631aa0 2381 elsif A_Id = Aspect_Import or else A_Id = Aspect_Export then
d74fc39a 2382
89f1e35c 2383 -- Verify that there is an aspect Convention that will
2384 -- incorporate the Import/Export aspect, and eventual
2385 -- Link/External names.
cce84b09 2386
89f1e35c 2387 declare
2388 A : Node_Id;
cce84b09 2389
89f1e35c 2390 begin
2391 A := First (L);
2392 while Present (A) loop
2393 exit when Chars (Identifier (A)) = Name_Convention;
2394 Next (A);
2395 end loop;
d64221a7 2396
e163cac8 2397 -- It is legal to specify Import for a variable, in
2398 -- order to suppress initialization for it, without
2399 -- specifying explicitly its convention. However this
2400 -- is only legal if the convention of the object type
2401 -- is Ada or similar.
2402
89f1e35c 2403 if No (A) then
e163cac8 2404 if Ekind (E) = E_Variable
2405 and then A_Id = Aspect_Import
2406 then
2407 declare
2408 C : constant Convention_Id :=
2409 Convention (Etype (E));
2410 begin
2411 if C = Convention_Ada or else
2412 C = Convention_Ada_Pass_By_Copy or else
2413 C = Convention_Ada_Pass_By_Reference
2414 then
2415 goto Continue;
2416 end if;
2417 end;
2418 end if;
2419
d324c418 2420 -- Otherwise, Convention must be specified
2421
89f1e35c 2422 Error_Msg_N
2423 ("missing Convention aspect for Export/Import",
37c6e44c 2424 Aspect);
89f1e35c 2425 end if;
2426 end;
d74fc39a 2427
89f1e35c 2428 goto Continue;
2429 end if;
d74fc39a 2430
37c6e44c 2431 -- Library unit aspects require special handling in the case
2432 -- of a package declaration, the pragma needs to be inserted
2433 -- in the list of declarations for the associated package.
2434 -- There is no issue of visibility delay for these aspects.
d64221a7 2435
89f1e35c 2436 if A_Id in Library_Unit_Aspects
178fec9b 2437 and then
2438 Nkind_In (N, N_Package_Declaration,
2439 N_Generic_Package_Declaration)
89f1e35c 2440 and then Nkind (Parent (N)) /= N_Compilation_Unit
2441 then
2442 Error_Msg_N
2443 ("incorrect context for library unit aspect&", Id);
2444 goto Continue;
2445 end if;
cce84b09 2446
37c6e44c 2447 -- Cases where we do not delay, includes all cases where
2448 -- the expression is missing other than the above cases.
d74fc39a 2449
37c6e44c 2450 if not Delay_Required or else No (Expr) then
0fd13d32 2451 Make_Aitem_Pragma
2452 (Pragma_Argument_Associations => New_List (
2453 Make_Pragma_Argument_Association (Sloc (Ent),
2454 Expression => Ent)),
2455 Pragma_Name => Chars (Id));
89f1e35c 2456 Delay_Required := False;
ddf1337b 2457
89f1e35c 2458 -- In general cases, the corresponding pragma/attribute
2459 -- definition clause will be inserted later at the freezing
37c6e44c 2460 -- point, and we do not need to build it now
ddf1337b 2461
89f1e35c 2462 else
2463 Aitem := Empty;
2464 end if;
ceec4f7c 2465
2466 -- Storage_Size
2467
2468 -- This is special because for access types we need to generate
2469 -- an attribute definition clause. This also works for single
2470 -- task declarations, but it does not work for task type
2471 -- declarations, because we have the case where the expression
2472 -- references a discriminant of the task type. That can't use
2473 -- an attribute definition clause because we would not have
2474 -- visibility on the discriminant. For that case we must
2475 -- generate a pragma in the task definition.
2476
2477 when Aspect_Storage_Size =>
2478
2479 -- Task type case
2480
2481 if Ekind (E) = E_Task_Type then
2482 declare
2483 Decl : constant Node_Id := Declaration_Node (E);
2484
2485 begin
2486 pragma Assert (Nkind (Decl) = N_Task_Type_Declaration);
2487
2488 -- If no task definition, create one
2489
2490 if No (Task_Definition (Decl)) then
2491 Set_Task_Definition (Decl,
2492 Make_Task_Definition (Loc,
2493 Visible_Declarations => Empty_List,
2494 End_Label => Empty));
2495 end if;
2496
2497 -- Create a pragma and put it at the start of the
2498 -- task definition for the task type declaration.
2499
2500 Make_Aitem_Pragma
2501 (Pragma_Argument_Associations => New_List (
2502 Make_Pragma_Argument_Association (Loc,
2503 Expression => Relocate_Node (Expr))),
2504 Pragma_Name => Name_Storage_Size);
2505
2506 Prepend
2507 (Aitem,
2508 Visible_Declarations (Task_Definition (Decl)));
2509 goto Continue;
2510 end;
2511
2512 -- All other cases, generate attribute definition
2513
2514 else
2515 Aitem :=
2516 Make_Attribute_Definition_Clause (Loc,
2517 Name => Ent,
2518 Chars => Chars (Id),
2519 Expression => Relocate_Node (Expr));
2520 end if;
89f1e35c 2521 end case;
ddf1337b 2522
89f1e35c 2523 -- Attach the corresponding pragma/attribute definition clause to
2524 -- the aspect specification node.
d74fc39a 2525
89f1e35c 2526 if Present (Aitem) then
2527 Set_From_Aspect_Specification (Aitem, True);
89f1e35c 2528 end if;
53c179ea 2529
89f1e35c 2530 -- In the context of a compilation unit, we directly put the
0fd13d32 2531 -- pragma in the Pragmas_After list of the N_Compilation_Unit_Aux
2532 -- node (no delay is required here) except for aspects on a
178fec9b 2533 -- subprogram body (see below) and a generic package, for which
2534 -- we need to introduce the pragma before building the generic
df8b0dae 2535 -- copy (see sem_ch12), and for package instantiations, where
2536 -- the library unit pragmas are better handled early.
ddf1337b 2537
9129c28f 2538 if Nkind (Parent (N)) = N_Compilation_Unit
89f1e35c 2539 and then (Present (Aitem) or else Is_Boolean_Aspect (Aspect))
2540 then
2541 declare
2542 Aux : constant Node_Id := Aux_Decls_Node (Parent (N));
7f694ca2 2543
89f1e35c 2544 begin
2545 pragma Assert (Nkind (Aux) = N_Compilation_Unit_Aux);
7f694ca2 2546
89f1e35c 2547 -- For a Boolean aspect, create the corresponding pragma if
2548 -- no expression or if the value is True.
7f694ca2 2549
b9e61b2a 2550 if Is_Boolean_Aspect (Aspect) and then No (Aitem) then
89f1e35c 2551 if Is_True (Static_Boolean (Expr)) then
0fd13d32 2552 Make_Aitem_Pragma
2553 (Pragma_Argument_Associations => New_List (
2554 Make_Pragma_Argument_Association (Sloc (Ent),
2555 Expression => Ent)),
2556 Pragma_Name => Chars (Id));
7f694ca2 2557
89f1e35c 2558 Set_From_Aspect_Specification (Aitem, True);
2559 Set_Corresponding_Aspect (Aitem, Aspect);
2560
2561 else
2562 goto Continue;
2563 end if;
2564 end if;
7f694ca2 2565
3a72f9c3 2566 -- If the aspect is on a subprogram body (relevant aspects
2567 -- are Inline and Priority), add the pragma in front of
2568 -- the declarations.
2569
2570 if Nkind (N) = N_Subprogram_Body then
2571 if No (Declarations (N)) then
2572 Set_Declarations (N, New_List);
2573 end if;
2574
2575 Prepend (Aitem, Declarations (N));
2576
178fec9b 2577 elsif Nkind (N) = N_Generic_Package_Declaration then
2578 if No (Visible_Declarations (Specification (N))) then
2579 Set_Visible_Declarations (Specification (N), New_List);
2580 end if;
2581
2582 Prepend (Aitem,
2583 Visible_Declarations (Specification (N)));
2584
df8b0dae 2585 elsif Nkind (N) = N_Package_Instantiation then
2586 declare
2587 Spec : constant Node_Id :=
2588 Specification (Instance_Spec (N));
2589 begin
2590 if No (Visible_Declarations (Spec)) then
2591 Set_Visible_Declarations (Spec, New_List);
2592 end if;
2593
2594 Prepend (Aitem, Visible_Declarations (Spec));
2595 end;
2596
3a72f9c3 2597 else
2598 if No (Pragmas_After (Aux)) then
d4596fbe 2599 Set_Pragmas_After (Aux, New_List);
3a72f9c3 2600 end if;
2601
2602 Append (Aitem, Pragmas_After (Aux));
89f1e35c 2603 end if;
7f694ca2 2604
89f1e35c 2605 goto Continue;
2606 end;
2607 end if;
7f694ca2 2608
89f1e35c 2609 -- The evaluation of the aspect is delayed to the freezing point.
2610 -- The pragma or attribute clause if there is one is then attached
37c6e44c 2611 -- to the aspect specification which is put in the rep item list.
1a814552 2612
89f1e35c 2613 if Delay_Required then
2614 if Present (Aitem) then
2615 Set_Is_Delayed_Aspect (Aitem);
2616 Set_Aspect_Rep_Item (Aspect, Aitem);
2617 Set_Parent (Aitem, Aspect);
2618 end if;
1a814552 2619
89f1e35c 2620 Set_Is_Delayed_Aspect (Aspect);
9f36e3fb 2621
cba2ae82 2622 -- In the case of Default_Value, link the aspect to base type
2623 -- as well, even though it appears on a first subtype. This is
2624 -- mandated by the semantics of the aspect. Do not establish
2625 -- the link when processing the base type itself as this leads
2626 -- to a rep item circularity. Verify that we are dealing with
2627 -- a scalar type to prevent cascaded errors.
2628
2629 if A_Id = Aspect_Default_Value
2630 and then Is_Scalar_Type (E)
2631 and then Base_Type (E) /= E
2632 then
9f36e3fb 2633 Set_Has_Delayed_Aspects (Base_Type (E));
2634 Record_Rep_Item (Base_Type (E), Aspect);
2635 end if;
2636
89f1e35c 2637 Set_Has_Delayed_Aspects (E);
2638 Record_Rep_Item (E, Aspect);
ddf1337b 2639
b855559d 2640 -- When delay is not required and the context is a package or a
2641 -- subprogram body, insert the pragma in the body declarations.
f55ce169 2642
b855559d 2643 elsif Nkind_In (N, N_Package_Body, N_Subprogram_Body) then
f55ce169 2644 if No (Declarations (N)) then
2645 Set_Declarations (N, New_List);
2646 end if;
2647
2648 -- The pragma is added before source declarations
2649
2650 Prepend_To (Declarations (N), Aitem);
2651
89f1e35c 2652 -- When delay is not required and the context is not a compilation
2653 -- unit, we simply insert the pragma/attribute definition clause
2654 -- in sequence.
ddf1337b 2655
89f1e35c 2656 else
2657 Insert_After (Ins_Node, Aitem);
2658 Ins_Node := Aitem;
d74fc39a 2659 end if;
0fd13d32 2660 end Analyze_One_Aspect;
ae888dbd 2661
d64221a7 2662 <<Continue>>
2663 Next (Aspect);
21ea3a4f 2664 end loop Aspect_Loop;
89f1e35c 2665
2666 if Has_Delayed_Aspects (E) then
2667 Ensure_Freeze_Node (E);
2668 end if;
21ea3a4f 2669 end Analyze_Aspect_Specifications;
ae888dbd 2670
d6f39728 2671 -----------------------
2672 -- Analyze_At_Clause --
2673 -----------------------
2674
2675 -- An at clause is replaced by the corresponding Address attribute
2676 -- definition clause that is the preferred approach in Ada 95.
2677
2678 procedure Analyze_At_Clause (N : Node_Id) is
177675a7 2679 CS : constant Boolean := Comes_From_Source (N);
2680
d6f39728 2681 begin
177675a7 2682 -- This is an obsolescent feature
2683
e0521a36 2684 Check_Restriction (No_Obsolescent_Features, N);
2685
9dfe12ae 2686 if Warn_On_Obsolescent_Feature then
2687 Error_Msg_N
b174444e 2688 ("?j?at clause is an obsolescent feature (RM J.7(2))", N);
9dfe12ae 2689 Error_Msg_N
b174444e 2690 ("\?j?use address attribute definition clause instead", N);
9dfe12ae 2691 end if;
2692
177675a7 2693 -- Rewrite as address clause
2694
d6f39728 2695 Rewrite (N,
2696 Make_Attribute_Definition_Clause (Sloc (N),
935e86e0 2697 Name => Identifier (N),
2698 Chars => Name_Address,
d6f39728 2699 Expression => Expression (N)));
177675a7 2700
2beb22b1 2701 -- We preserve Comes_From_Source, since logically the clause still comes
2702 -- from the source program even though it is changed in form.
177675a7 2703
2704 Set_Comes_From_Source (N, CS);
2705
2706 -- Analyze rewritten clause
2707
d6f39728 2708 Analyze_Attribute_Definition_Clause (N);
2709 end Analyze_At_Clause;
2710
2711 -----------------------------------------
2712 -- Analyze_Attribute_Definition_Clause --
2713 -----------------------------------------
2714
2715 procedure Analyze_Attribute_Definition_Clause (N : Node_Id) is
2716 Loc : constant Source_Ptr := Sloc (N);
2717 Nam : constant Node_Id := Name (N);
2718 Attr : constant Name_Id := Chars (N);
2719 Expr : constant Node_Id := Expression (N);
2720 Id : constant Attribute_Id := Get_Attribute_Id (Attr);
d64221a7 2721
2722 Ent : Entity_Id;
2723 -- The entity of Nam after it is analyzed. In the case of an incomplete
2724 -- type, this is the underlying type.
2725
d6f39728 2726 U_Ent : Entity_Id;
d64221a7 2727 -- The underlying entity to which the attribute applies. Generally this
2728 -- is the Underlying_Type of Ent, except in the case where the clause
2729 -- applies to full view of incomplete type or private type in which case
2730 -- U_Ent is just a copy of Ent.
d6f39728 2731
2732 FOnly : Boolean := False;
2733 -- Reset to True for subtype specific attribute (Alignment, Size)
2734 -- and for stream attributes, i.e. those cases where in the call
2735 -- to Rep_Item_Too_Late, FOnly is set True so that only the freezing
2736 -- rules are checked. Note that the case of stream attributes is not
2737 -- clear from the RM, but see AI95-00137. Also, the RM seems to
2738 -- disallow Storage_Size for derived task types, but that is also
2739 -- clearly unintentional.
2740
9f373bb8 2741 procedure Analyze_Stream_TSS_Definition (TSS_Nam : TSS_Name_Type);
2742 -- Common processing for 'Read, 'Write, 'Input and 'Output attribute
2743 -- definition clauses.
2744
ae888dbd 2745 function Duplicate_Clause return Boolean;
2746 -- This routine checks if the aspect for U_Ent being given by attribute
2747 -- definition clause N is for an aspect that has already been specified,
2748 -- and if so gives an error message. If there is a duplicate, True is
2749 -- returned, otherwise if there is no error, False is returned.
2750
81b424ac 2751 procedure Check_Indexing_Functions;
2752 -- Check that the function in Constant_Indexing or Variable_Indexing
2753 -- attribute has the proper type structure. If the name is overloaded,
cac18f71 2754 -- check that some interpretation is legal.
81b424ac 2755
89cc7147 2756 procedure Check_Iterator_Functions;
2757 -- Check that there is a single function in Default_Iterator attribute
8df4f2a5 2758 -- has the proper type structure.
89cc7147 2759
2760 function Check_Primitive_Function (Subp : Entity_Id) return Boolean;
d03bfaa1 2761 -- Common legality check for the previous two
89cc7147 2762
177675a7 2763 -----------------------------------
2764 -- Analyze_Stream_TSS_Definition --
2765 -----------------------------------
2766
9f373bb8 2767 procedure Analyze_Stream_TSS_Definition (TSS_Nam : TSS_Name_Type) is
2768 Subp : Entity_Id := Empty;
2769 I : Interp_Index;
2770 It : Interp;
2771 Pnam : Entity_Id;
2772
2773 Is_Read : constant Boolean := (TSS_Nam = TSS_Stream_Read);
d64221a7 2774 -- True for Read attribute, false for other attributes
9f373bb8 2775
2776 function Has_Good_Profile (Subp : Entity_Id) return Boolean;
2777 -- Return true if the entity is a subprogram with an appropriate
2778 -- profile for the attribute being defined.
2779
2780 ----------------------
2781 -- Has_Good_Profile --
2782 ----------------------
2783
2784 function Has_Good_Profile (Subp : Entity_Id) return Boolean is
2785 F : Entity_Id;
2786 Is_Function : constant Boolean := (TSS_Nam = TSS_Stream_Input);
2787 Expected_Ekind : constant array (Boolean) of Entity_Kind :=
2788 (False => E_Procedure, True => E_Function);
2789 Typ : Entity_Id;
2790
2791 begin
2792 if Ekind (Subp) /= Expected_Ekind (Is_Function) then
2793 return False;
2794 end if;
2795
2796 F := First_Formal (Subp);
2797
2798 if No (F)
2799 or else Ekind (Etype (F)) /= E_Anonymous_Access_Type
2800 or else Designated_Type (Etype (F)) /=
2801 Class_Wide_Type (RTE (RE_Root_Stream_Type))
2802 then
2803 return False;
2804 end if;
2805
2806 if not Is_Function then
2807 Next_Formal (F);
2808
2809 declare
2810 Expected_Mode : constant array (Boolean) of Entity_Kind :=
2811 (False => E_In_Parameter,
2812 True => E_Out_Parameter);
2813 begin
2814 if Parameter_Mode (F) /= Expected_Mode (Is_Read) then
2815 return False;
2816 end if;
2817 end;
2818
2819 Typ := Etype (F);
2820
2821 else
2822 Typ := Etype (Subp);
2823 end if;
2824
2825 return Base_Type (Typ) = Base_Type (Ent)
2826 and then No (Next_Formal (F));
9f373bb8 2827 end Has_Good_Profile;
2828
2829 -- Start of processing for Analyze_Stream_TSS_Definition
2830
2831 begin
2832 FOnly := True;
2833
2834 if not Is_Type (U_Ent) then
2835 Error_Msg_N ("local name must be a subtype", Nam);
2836 return;
2837 end if;
2838
2839 Pnam := TSS (Base_Type (U_Ent), TSS_Nam);
2840
44e4341e 2841 -- If Pnam is present, it can be either inherited from an ancestor
2842 -- type (in which case it is legal to redefine it for this type), or
2843 -- be a previous definition of the attribute for the same type (in
2844 -- which case it is illegal).
2845
2846 -- In the first case, it will have been analyzed already, and we
2847 -- can check that its profile does not match the expected profile
2848 -- for a stream attribute of U_Ent. In the second case, either Pnam
2849 -- has been analyzed (and has the expected profile), or it has not
2850 -- been analyzed yet (case of a type that has not been frozen yet
2851 -- and for which the stream attribute has been set using Set_TSS).
2852
2853 if Present (Pnam)
2854 and then (No (First_Entity (Pnam)) or else Has_Good_Profile (Pnam))
2855 then
9f373bb8 2856 Error_Msg_Sloc := Sloc (Pnam);
2857 Error_Msg_Name_1 := Attr;
2858 Error_Msg_N ("% attribute already defined #", Nam);
2859 return;
2860 end if;
2861
2862 Analyze (Expr);
2863
2864 if Is_Entity_Name (Expr) then
2865 if not Is_Overloaded (Expr) then
2866 if Has_Good_Profile (Entity (Expr)) then
2867 Subp := Entity (Expr);
2868 end if;
2869
2870 else
2871 Get_First_Interp (Expr, I, It);
9f373bb8 2872 while Present (It.Nam) loop
2873 if Has_Good_Profile (It.Nam) then
2874 Subp := It.Nam;
2875 exit;
2876 end if;
2877
2878 Get_Next_Interp (I, It);
2879 end loop;
2880 end if;
2881 end if;
2882
2883 if Present (Subp) then
59ac57b5 2884 if Is_Abstract_Subprogram (Subp) then
9f373bb8 2885 Error_Msg_N ("stream subprogram must not be abstract", Expr);
2886 return;
2887 end if;
2888
2889 Set_Entity (Expr, Subp);
2890 Set_Etype (Expr, Etype (Subp));
2891
44e4341e 2892 New_Stream_Subprogram (N, U_Ent, Subp, TSS_Nam);
9f373bb8 2893
2894 else
2895 Error_Msg_Name_1 := Attr;
2896 Error_Msg_N ("incorrect expression for% attribute", Expr);
2897 end if;
2898 end Analyze_Stream_TSS_Definition;
2899
81b424ac 2900 ------------------------------
2901 -- Check_Indexing_Functions --
2902 ------------------------------
2903
2904 procedure Check_Indexing_Functions is
cac18f71 2905 Indexing_Found : Boolean;
8df4f2a5 2906
81b424ac 2907 procedure Check_One_Function (Subp : Entity_Id);
a45d946f 2908 -- Check one possible interpretation. Sets Indexing_Found True if an
2909 -- indexing function is found.
81b424ac 2910
2911 ------------------------
2912 -- Check_One_Function --
2913 ------------------------
2914
2915 procedure Check_One_Function (Subp : Entity_Id) is
1b7510f9 2916 Default_Element : constant Node_Id :=
5bbfbad2 2917 Find_Value_Of_Aspect
2c5754de 2918 (Etype (First_Formal (Subp)),
2919 Aspect_Iterator_Element);
1b7510f9 2920
81b424ac 2921 begin
cac18f71 2922 if not Check_Primitive_Function (Subp)
2923 and then not Is_Overloaded (Expr)
2924 then
89cc7147 2925 Error_Msg_NE
2926 ("aspect Indexing requires a function that applies to type&",
cac18f71 2927 Subp, Ent);
81b424ac 2928 end if;
2929
1b7510f9 2930 -- An indexing function must return either the default element of
cac18f71 2931 -- the container, or a reference type. For variable indexing it
a45d946f 2932 -- must be the latter.
1b7510f9 2933
2934 if Present (Default_Element) then
2935 Analyze (Default_Element);
a45d946f 2936
1b7510f9 2937 if Is_Entity_Name (Default_Element)
2c5754de 2938 and then Covers (Entity (Default_Element), Etype (Subp))
1b7510f9 2939 then
cac18f71 2940 Indexing_Found := True;
1b7510f9 2941 return;
2942 end if;
2943 end if;
2944
a45d946f 2945 -- For variable_indexing the return type must be a reference type
1b7510f9 2946
cac18f71 2947 if Attr = Name_Variable_Indexing
2948 and then not Has_Implicit_Dereference (Etype (Subp))
2949 then
81b424ac 2950 Error_Msg_N
2951 ("function for indexing must return a reference type", Subp);
cac18f71 2952
2953 else
2954 Indexing_Found := True;
81b424ac 2955 end if;
2956 end Check_One_Function;
2957
2958 -- Start of processing for Check_Indexing_Functions
2959
2960 begin
89cc7147 2961 if In_Instance then
2962 return;
2963 end if;
2964
81b424ac 2965 Analyze (Expr);
2966
2967 if not Is_Overloaded (Expr) then
2968 Check_One_Function (Entity (Expr));
2969
2970 else
2971 declare
2c5754de 2972 I : Interp_Index;
81b424ac 2973 It : Interp;
2974
2975 begin
cac18f71 2976 Indexing_Found := False;
81b424ac 2977 Get_First_Interp (Expr, I, It);
2978 while Present (It.Nam) loop
2979
2980 -- Note that analysis will have added the interpretation
2981 -- that corresponds to the dereference. We only check the
2982 -- subprogram itself.
2983
2984 if Is_Overloadable (It.Nam) then
2985 Check_One_Function (It.Nam);
2986 end if;
2987
2988 Get_Next_Interp (I, It);
2989 end loop;
a45d946f 2990
cac18f71 2991 if not Indexing_Found then
a45d946f 2992 Error_Msg_NE
2993 ("aspect Indexing requires a function that "
2994 & "applies to type&", Expr, Ent);
cac18f71 2995 end if;
81b424ac 2996 end;
2997 end if;
2998 end Check_Indexing_Functions;
2999
89cc7147 3000 ------------------------------
3001 -- Check_Iterator_Functions --
3002 ------------------------------
3003
3004 procedure Check_Iterator_Functions is
3005 Default : Entity_Id;
3006
3007 function Valid_Default_Iterator (Subp : Entity_Id) return Boolean;
8df4f2a5 3008 -- Check one possible interpretation for validity
89cc7147 3009
3010 ----------------------------
3011 -- Valid_Default_Iterator --
3012 ----------------------------
3013
3014 function Valid_Default_Iterator (Subp : Entity_Id) return Boolean is
3015 Formal : Entity_Id;
3016
3017 begin
3018 if not Check_Primitive_Function (Subp) then
3019 return False;
3020 else
3021 Formal := First_Formal (Subp);
3022 end if;
3023
8df4f2a5 3024 -- False if any subsequent formal has no default expression
89cc7147 3025
8df4f2a5 3026 Formal := Next_Formal (Formal);
3027 while Present (Formal) loop
3028 if No (Expression (Parent (Formal))) then
3029 return False;
3030 end if;
89cc7147 3031
8df4f2a5 3032 Next_Formal (Formal);
3033 end loop;
89cc7147 3034
8df4f2a5 3035 -- True if all subsequent formals have default expressions
89cc7147 3036
3037 return True;
3038 end Valid_Default_Iterator;
3039
3040 -- Start of processing for Check_Iterator_Functions
3041
3042 begin
3043 Analyze (Expr);
3044
3045 if not Is_Entity_Name (Expr) then
3046 Error_Msg_N ("aspect Iterator must be a function name", Expr);
3047 end if;
3048
3049 if not Is_Overloaded (Expr) then
3050 if not Check_Primitive_Function (Entity (Expr)) then
3051 Error_Msg_NE
3052 ("aspect Indexing requires a function that applies to type&",
3053 Entity (Expr), Ent);
3054 end if;
3055
3056 if not Valid_Default_Iterator (Entity (Expr)) then
3057 Error_Msg_N ("improper function for default iterator", Expr);
3058 end if;
3059
3060 else
3061 Default := Empty;
3062 declare
3063 I : Interp_Index;
3064 It : Interp;
3065
3066 begin
3067 Get_First_Interp (Expr, I, It);
3068 while Present (It.Nam) loop
3069 if not Check_Primitive_Function (It.Nam)
59f3e675 3070 or else not Valid_Default_Iterator (It.Nam)
89cc7147 3071 then
3072 Remove_Interp (I);
3073
3074 elsif Present (Default) then
3075 Error_Msg_N ("default iterator must be unique", Expr);
3076
3077 else
3078 Default := It.Nam;
3079 end if;
3080
3081 Get_Next_Interp (I, It);
3082 end loop;
3083 end;
3084
3085 if Present (Default) then
3086 Set_Entity (Expr, Default);
3087 Set_Is_Overloaded (Expr, False);
3088 end if;
3089 end if;
3090 end Check_Iterator_Functions;
3091
3092 -------------------------------
3093 -- Check_Primitive_Function --
3094 -------------------------------
3095
3096 function Check_Primitive_Function (Subp : Entity_Id) return Boolean is
3097 Ctrl : Entity_Id;
3098
3099 begin
3100 if Ekind (Subp) /= E_Function then
3101 return False;
3102 end if;
3103
3104 if No (First_Formal (Subp)) then
3105 return False;
3106 else
3107 Ctrl := Etype (First_Formal (Subp));
3108 end if;
3109
3110 if Ctrl = Ent
3111 or else Ctrl = Class_Wide_Type (Ent)
3112 or else
3113 (Ekind (Ctrl) = E_Anonymous_Access_Type
3114 and then
3115 (Designated_Type (Ctrl) = Ent
3116 or else Designated_Type (Ctrl) = Class_Wide_Type (Ent)))
3117 then
3118 null;
3119
3120 else
3121 return False;
3122 end if;
3123
3124 return True;
3125 end Check_Primitive_Function;
3126
ae888dbd 3127 ----------------------
3128 -- Duplicate_Clause --
3129 ----------------------
3130
3131 function Duplicate_Clause return Boolean is
d74fc39a 3132 A : Node_Id;
ae888dbd 3133
3134 begin
c8969ba6 3135 -- Nothing to do if this attribute definition clause comes from
3136 -- an aspect specification, since we could not be duplicating an
ae888dbd 3137 -- explicit clause, and we dealt with the case of duplicated aspects
3138 -- in Analyze_Aspect_Specifications.
3139
3140 if From_Aspect_Specification (N) then
3141 return False;
3142 end if;
3143
89f1e35c 3144 -- Otherwise current clause may duplicate previous clause, or a
3145 -- previously given pragma or aspect specification for the same
3146 -- aspect.
d74fc39a 3147
89b3b365 3148 A := Get_Rep_Item (U_Ent, Chars (N), Check_Parents => False);
ae888dbd 3149
3150 if Present (A) then
89f1e35c 3151 Error_Msg_Name_1 := Chars (N);
3152 Error_Msg_Sloc := Sloc (A);
3153
89b3b365 3154 Error_Msg_NE ("aspect% for & previously given#", N, U_Ent);
89f1e35c 3155 return True;
ae888dbd 3156 end if;
3157
3158 return False;
3159 end Duplicate_Clause;
3160
9f373bb8 3161 -- Start of processing for Analyze_Attribute_Definition_Clause
3162
d6f39728 3163 begin
d64221a7 3164 -- The following code is a defense against recursion. Not clear that
3165 -- this can happen legitimately, but perhaps some error situations
3166 -- can cause it, and we did see this recursion during testing.
3167
3168 if Analyzed (N) then
3169 return;
3170 else
3171 Set_Analyzed (N, True);
3172 end if;
3173
a29bc1d9 3174 -- Ignore some selected attributes in CodePeer mode since they are not
3175 -- relevant in this context.
3176
3177 if CodePeer_Mode then
3178 case Id is
3179
3180 -- Ignore Component_Size in CodePeer mode, to avoid changing the
3181 -- internal representation of types by implicitly packing them.
3182
3183 when Attribute_Component_Size =>
3184 Rewrite (N, Make_Null_Statement (Sloc (N)));
3185 return;
3186
3187 when others =>
3188 null;
3189 end case;
3190 end if;
3191
d8ba53a8 3192 -- Process Ignore_Rep_Clauses option
eef1ca1e 3193
d8ba53a8 3194 if Ignore_Rep_Clauses then
9d627c41 3195 case Id is
3196
eef1ca1e 3197 -- The following should be ignored. They do not affect legality
3198 -- and may be target dependent. The basic idea of -gnatI is to
3199 -- ignore any rep clauses that may be target dependent but do not
3200 -- affect legality (except possibly to be rejected because they
3201 -- are incompatible with the compilation target).
9d627c41 3202
2f1aac99 3203 when Attribute_Alignment |
9d627c41 3204 Attribute_Bit_Order |
3205 Attribute_Component_Size |
3206 Attribute_Machine_Radix |
3207 Attribute_Object_Size |
3208 Attribute_Size |
9d627c41 3209 Attribute_Stream_Size |
3210 Attribute_Value_Size =>
9d627c41 3211 Rewrite (N, Make_Null_Statement (Sloc (N)));
3212 return;
3213
d8ba53a8 3214 -- Perhaps 'Small should not be ignored by Ignore_Rep_Clauses ???
fe639c68 3215
3216 when Attribute_Small =>
3217 if Ignore_Rep_Clauses then
3218 Rewrite (N, Make_Null_Statement (Sloc (N)));
3219 return;
3220 end if;
3221
eef1ca1e 3222 -- The following should not be ignored, because in the first place
3223 -- they are reasonably portable, and should not cause problems in
3224 -- compiling code from another target, and also they do affect
3225 -- legality, e.g. failing to provide a stream attribute for a
3226 -- type may make a program illegal.
9d627c41 3227
b55f7641 3228 when Attribute_External_Tag |
3229 Attribute_Input |
3230 Attribute_Output |
3231 Attribute_Read |
3232 Attribute_Simple_Storage_Pool |
3233 Attribute_Storage_Pool |
3234 Attribute_Storage_Size |
3235 Attribute_Write =>
9d627c41 3236 null;
3237
b593a52c 3238 -- Other cases are errors ("attribute& cannot be set with
3239 -- definition clause"), which will be caught below.
9d627c41 3240
3241 when others =>
3242 null;
3243 end case;
fbc67f84 3244 end if;
3245
d6f39728 3246 Analyze (Nam);
3247 Ent := Entity (Nam);
3248
3249 if Rep_Item_Too_Early (Ent, N) then
3250 return;
3251 end if;
3252
9f373bb8 3253 -- Rep clause applies to full view of incomplete type or private type if
3254 -- we have one (if not, this is a premature use of the type). However,
3255 -- certain semantic checks need to be done on the specified entity (i.e.
3256 -- the private view), so we save it in Ent.
d6f39728 3257
3258 if Is_Private_Type (Ent)
3259 and then Is_Derived_Type (Ent)
3260 and then not Is_Tagged_Type (Ent)
3261 and then No (Full_View (Ent))
3262 then
9f373bb8 3263 -- If this is a private type whose completion is a derivation from
3264 -- another private type, there is no full view, and the attribute
3265 -- belongs to the type itself, not its underlying parent.
d6f39728 3266
3267 U_Ent := Ent;
3268
3269 elsif Ekind (Ent) = E_Incomplete_Type then
d5b349fa 3270
9f373bb8 3271 -- The attribute applies to the full view, set the entity of the
3272 -- attribute definition accordingly.
d5b349fa 3273
d6f39728 3274 Ent := Underlying_Type (Ent);
3275 U_Ent := Ent;
d5b349fa 3276 Set_Entity (Nam, Ent);
3277
d6f39728 3278 else
3279 U_Ent := Underlying_Type (Ent);
3280 end if;
3281
44705307 3282 -- Avoid cascaded error
d6f39728 3283
3284 if Etype (Nam) = Any_Type then
3285 return;
3286
89f1e35c 3287 -- Must be declared in current scope or in case of an aspect
ace3389d 3288 -- specification, must be visible in current scope.
44705307 3289
89f1e35c 3290 elsif Scope (Ent) /= Current_Scope
ace3389d 3291 and then
3292 not (From_Aspect_Specification (N)
3293 and then Scope_Within_Or_Same (Current_Scope, Scope (Ent)))
89f1e35c 3294 then
d6f39728 3295 Error_Msg_N ("entity must be declared in this scope", Nam);
3296 return;
3297
44705307 3298 -- Must not be a source renaming (we do have some cases where the
3299 -- expander generates a renaming, and those cases are OK, in such
a3248fc4 3300 -- cases any attribute applies to the renamed object as well).
44705307 3301
3302 elsif Is_Object (Ent)
3303 and then Present (Renamed_Object (Ent))
44705307 3304 then
a3248fc4 3305 -- Case of renamed object from source, this is an error
3306
3307 if Comes_From_Source (Renamed_Object (Ent)) then
3308 Get_Name_String (Chars (N));
3309 Error_Msg_Strlen := Name_Len;
3310 Error_Msg_String (1 .. Name_Len) := Name_Buffer (1 .. Name_Len);
3311 Error_Msg_N
3312 ("~ clause not allowed for a renaming declaration "
3313 & "(RM 13.1(6))", Nam);
3314 return;
3315
3316 -- For the case of a compiler generated renaming, the attribute
3317 -- definition clause applies to the renamed object created by the
3318 -- expander. The easiest general way to handle this is to create a
3319 -- copy of the attribute definition clause for this object.
3320
3321 else
3322 Insert_Action (N,
3323 Make_Attribute_Definition_Clause (Loc,
3324 Name =>
3325 New_Occurrence_Of (Entity (Renamed_Object (Ent)), Loc),
3326 Chars => Chars (N),
3327 Expression => Duplicate_Subexpr (Expression (N))));
3328 end if;
44705307 3329
3330 -- If no underlying entity, use entity itself, applies to some
3331 -- previously detected error cases ???
3332
f15731c4 3333 elsif No (U_Ent) then
3334 U_Ent := Ent;
3335
44705307 3336 -- Cannot specify for a subtype (exception Object/Value_Size)
3337
d6f39728 3338 elsif Is_Type (U_Ent)
3339 and then not Is_First_Subtype (U_Ent)
3340 and then Id /= Attribute_Object_Size
3341 and then Id /= Attribute_Value_Size
3342 and then not From_At_Mod (N)
3343 then
3344 Error_Msg_N ("cannot specify attribute for subtype", Nam);
3345 return;
d6f39728 3346 end if;
3347
ae888dbd 3348 Set_Entity (N, U_Ent);
25e23a77 3349 Check_Restriction_No_Use_Of_Attribute (N);
ae888dbd 3350
d6f39728 3351 -- Switch on particular attribute
3352
3353 case Id is
3354
3355 -------------
3356 -- Address --
3357 -------------
3358
3359 -- Address attribute definition clause
3360
3361 when Attribute_Address => Address : begin
177675a7 3362
3363 -- A little error check, catch for X'Address use X'Address;
3364
3365 if Nkind (Nam) = N_Identifier
3366 and then Nkind (Expr) = N_Attribute_Reference
3367 and then Attribute_Name (Expr) = Name_Address
3368 and then Nkind (Prefix (Expr)) = N_Identifier
3369 and then Chars (Nam) = Chars (Prefix (Expr))
3370 then
3371 Error_Msg_NE
3372 ("address for & is self-referencing", Prefix (Expr), Ent);
3373 return;
3374 end if;
3375
3376 -- Not that special case, carry on with analysis of expression
3377
d6f39728 3378 Analyze_And_Resolve (Expr, RTE (RE_Address));
3379
2f1aac99 3380 -- Even when ignoring rep clauses we need to indicate that the
3381 -- entity has an address clause and thus it is legal to declare
3382 -- it imported.
3383
3384 if Ignore_Rep_Clauses then
d3ef794c 3385 if Ekind_In (U_Ent, E_Variable, E_Constant) then
2f1aac99 3386 Record_Rep_Item (U_Ent, N);
3387 end if;
3388
3389 return;
3390 end if;
3391
ae888dbd 3392 if Duplicate_Clause then
3393 null;
d6f39728 3394
3395 -- Case of address clause for subprogram
3396
3397 elsif Is_Subprogram (U_Ent) then
d6f39728 3398 if Has_Homonym (U_Ent) then
3399 Error_Msg_N
3400 ("address clause cannot be given " &
3401 "for overloaded subprogram",
3402 Nam);
83f8f0a6 3403 return;
d6f39728 3404 end if;
3405
83f8f0a6 3406 -- For subprograms, all address clauses are permitted, and we
3407 -- mark the subprogram as having a deferred freeze so that Gigi
3408 -- will not elaborate it too soon.
d6f39728 3409
3410 -- Above needs more comments, what is too soon about???
3411
3412 Set_Has_Delayed_Freeze (U_Ent);
3413
3414 -- Case of address clause for entry
3415
3416 elsif Ekind (U_Ent) = E_Entry then
d6f39728 3417 if Nkind (Parent (N)) = N_Task_Body then
3418 Error_Msg_N
3419 ("entry address must be specified in task spec", Nam);
83f8f0a6 3420 return;
d6f39728 3421 end if;
3422
3423 -- For entries, we require a constant address
3424
3425 Check_Constant_Address_Clause (Expr, U_Ent);
3426
83f8f0a6 3427 -- Special checks for task types
3428
f15731c4 3429 if Is_Task_Type (Scope (U_Ent))
3430 and then Comes_From_Source (Scope (U_Ent))
3431 then
3432 Error_Msg_N
1e3532e7 3433 ("??entry address declared for entry in task type", N);
f15731c4 3434 Error_Msg_N
1e3532e7 3435 ("\??only one task can be declared of this type", N);
f15731c4 3436 end if;
3437
83f8f0a6 3438 -- Entry address clauses are obsolescent
3439
e0521a36 3440 Check_Restriction (No_Obsolescent_Features, N);
3441
9dfe12ae 3442 if Warn_On_Obsolescent_Feature then
3443 Error_Msg_N
1e3532e7 3444 ("?j?attaching interrupt to task entry is an " &
3445 "obsolescent feature (RM J.7.1)", N);
9dfe12ae 3446 Error_Msg_N
1e3532e7 3447 ("\?j?use interrupt procedure instead", N);
9dfe12ae 3448 end if;
3449
83f8f0a6 3450 -- Case of an address clause for a controlled object which we
3451 -- consider to be erroneous.
9dfe12ae 3452
83f8f0a6 3453 elsif Is_Controlled (Etype (U_Ent))
3454 or else Has_Controlled_Component (Etype (U_Ent))
3455 then
9dfe12ae 3456 Error_Msg_NE
1e3532e7 3457 ("??controlled object& must not be overlaid", Nam, U_Ent);
9dfe12ae 3458 Error_Msg_N
1e3532e7 3459 ("\??Program_Error will be raised at run time", Nam);
9dfe12ae 3460 Insert_Action (Declaration_Node (U_Ent),
3461 Make_Raise_Program_Error (Loc,
3462 Reason => PE_Overlaid_Controlled_Object));
83f8f0a6 3463 return;
9dfe12ae 3464
3465 -- Case of address clause for a (non-controlled) object
d6f39728 3466
3467 elsif
3468 Ekind (U_Ent) = E_Variable
3469 or else
3470 Ekind (U_Ent) = E_Constant
3471 then
3472 declare
d6da7448 3473 Expr : constant Node_Id := Expression (N);
3474 O_Ent : Entity_Id;
3475 Off : Boolean;
d6f39728 3476
3477 begin
7ee315cc 3478 -- Exported variables cannot have an address clause, because
3479 -- this cancels the effect of the pragma Export.
d6f39728 3480
3481 if Is_Exported (U_Ent) then
3482 Error_Msg_N
3483 ("cannot export object with address clause", Nam);
83f8f0a6 3484 return;
d6da7448 3485 end if;
3486
3487 Find_Overlaid_Entity (N, O_Ent, Off);
d6f39728 3488
9dfe12ae 3489 -- Overlaying controlled objects is erroneous
3490
d6da7448 3491 if Present (O_Ent)
3492 and then (Has_Controlled_Component (Etype (O_Ent))
3493 or else Is_Controlled (Etype (O_Ent)))
9dfe12ae 3494 then
3495 Error_Msg_N
1e3532e7 3496 ("??cannot overlay with controlled object", Expr);
9dfe12ae 3497 Error_Msg_N
1e3532e7 3498 ("\??Program_Error will be raised at run time", Expr);
9dfe12ae 3499 Insert_Action (Declaration_Node (U_Ent),
3500 Make_Raise_Program_Error (Loc,
3501 Reason => PE_Overlaid_Controlled_Object));
83f8f0a6 3502 return;
9dfe12ae 3503
d6da7448 3504 elsif Present (O_Ent)
9dfe12ae 3505 and then Ekind (U_Ent) = E_Constant
d6da7448 3506 and then not Is_Constant_Object (O_Ent)
9dfe12ae 3507 then
1e3532e7 3508 Error_Msg_N ("??constant overlays a variable", Expr);
9dfe12ae 3509
d6f39728 3510 -- Imported variables can have an address clause, but then
3511 -- the import is pretty meaningless except to suppress
3512 -- initializations, so we do not need such variables to
3513 -- be statically allocated (and in fact it causes trouble
3514 -- if the address clause is a local value).
3515
3516 elsif Is_Imported (U_Ent) then
3517 Set_Is_Statically_Allocated (U_Ent, False);
3518 end if;
3519
3520 -- We mark a possible modification of a variable with an
3521 -- address clause, since it is likely aliasing is occurring.
3522
177675a7 3523 Note_Possible_Modification (Nam, Sure => False);
d6f39728 3524
83f8f0a6 3525 -- Here we are checking for explicit overlap of one variable
3526 -- by another, and if we find this then mark the overlapped
3527 -- variable as also being volatile to prevent unwanted
d6da7448 3528 -- optimizations. This is a significant pessimization so
3529 -- avoid it when there is an offset, i.e. when the object
3530 -- is composite; they cannot be optimized easily anyway.
d6f39728 3531
d6da7448 3532 if Present (O_Ent)
3533 and then Is_Object (O_Ent)
3534 and then not Off
ba5efa21 3535
3536 -- The following test is an expedient solution to what
3537 -- is really a problem in CodePeer. Suppressing the
3538 -- Set_Treat_As_Volatile call here prevents later
3539 -- generation (in some cases) of trees that CodePeer
3540 -- should, but currently does not, handle correctly.
3541 -- This test should probably be removed when CodePeer
3542 -- is improved, just because we want the tree CodePeer
3543 -- analyzes to match the tree for which we generate code
3544 -- as closely as is practical. ???
3545
3546 and then not CodePeer_Mode
d6da7448 3547 then
ba5efa21 3548 -- ??? O_Ent might not be in current unit
3549
d6da7448 3550 Set_Treat_As_Volatile (O_Ent);
d6f39728 3551 end if;
3552
9dfe12ae 3553 -- Legality checks on the address clause for initialized
3554 -- objects is deferred until the freeze point, because
2beb22b1 3555 -- a subsequent pragma might indicate that the object
42e09e36 3556 -- is imported and thus not initialized. Also, the address
3557 -- clause might involve entities that have yet to be
3558 -- elaborated.
9dfe12ae 3559
3560 Set_Has_Delayed_Freeze (U_Ent);
3561
51ad5ad2 3562 -- If an initialization call has been generated for this
3563 -- object, it needs to be deferred to after the freeze node
3564 -- we have just now added, otherwise GIGI will see a
3565 -- reference to the variable (as actual to the IP call)
3566 -- before its definition.
3567
3568 declare
df9fba45 3569 Init_Call : constant Node_Id :=
3570 Remove_Init_Call (U_Ent, N);
4bba0a8d 3571
51ad5ad2 3572 begin
3573 if Present (Init_Call) then
df9fba45 3574
3575 -- If the init call is an expression with actions with
3576 -- null expression, just extract the actions.
3577
3578 if Nkind (Init_Call) = N_Expression_With_Actions
4bba0a8d 3579 and then
3580 Nkind (Expression (Init_Call)) = N_Null_Statement
df9fba45 3581 then
3582 Append_Freeze_Actions (U_Ent, Actions (Init_Call));
3583
3584 -- General case: move Init_Call to freeze actions
3585
3586 else
3587 Append_Freeze_Action (U_Ent, Init_Call);
3588 end if;
51ad5ad2 3589 end if;
3590 end;
3591
d6f39728 3592 if Is_Exported (U_Ent) then
3593 Error_Msg_N
3594 ("& cannot be exported if an address clause is given",
3595 Nam);
3596 Error_Msg_N
4bba0a8d 3597 ("\define and export a variable "
3598 & "that holds its address instead", Nam);
d6f39728 3599 end if;
3600
44e4341e 3601 -- Entity has delayed freeze, so we will generate an
3602 -- alignment check at the freeze point unless suppressed.
d6f39728 3603
44e4341e 3604 if not Range_Checks_Suppressed (U_Ent)
3605 and then not Alignment_Checks_Suppressed (U_Ent)
3606 then
3607 Set_Check_Address_Alignment (N);
3608 end if;
d6f39728 3609
3610 -- Kill the size check code, since we are not allocating
3611 -- the variable, it is somewhere else.
3612
3613 Kill_Size_Check_Code (U_Ent);
83f8f0a6 3614
d6da7448 3615 -- If the address clause is of the form:
83f8f0a6 3616
d6da7448 3617 -- for Y'Address use X'Address
83f8f0a6 3618
d6da7448 3619 -- or
83f8f0a6 3620
d6da7448 3621 -- Const : constant Address := X'Address;
3622 -- ...
3623 -- for Y'Address use Const;
83f8f0a6 3624
d6da7448 3625 -- then we make an entry in the table for checking the size
3626 -- and alignment of the overlaying variable. We defer this
3627 -- check till after code generation to take full advantage
f4623c89 3628 -- of the annotation done by the back end.
d64221a7 3629
9474aa9c 3630 -- If the entity has a generic type, the check will be
43dd6937 3631 -- performed in the instance if the actual type justifies
3632 -- it, and we do not insert the clause in the table to
3633 -- prevent spurious warnings.
83f8f0a6 3634
f4623c89 3635 -- Note: we used to test Comes_From_Source and only give
3636 -- this warning for source entities, but we have removed
3637 -- this test. It really seems bogus to generate overlays
3638 -- that would trigger this warning in generated code.
3639 -- Furthermore, by removing the test, we handle the
3640 -- aspect case properly.
3641
d6da7448 3642 if Address_Clause_Overlay_Warnings
d6da7448 3643 and then Present (O_Ent)
3644 and then Is_Object (O_Ent)
3645 then
9474aa9c 3646 if not Is_Generic_Type (Etype (U_Ent)) then
3647 Address_Clause_Checks.Append ((N, U_Ent, O_Ent, Off));
3648 end if;
177675a7 3649
d6da7448 3650 -- If variable overlays a constant view, and we are
3651 -- warning on overlays, then mark the variable as
3652 -- overlaying a constant (we will give warnings later
3653 -- if this variable is assigned).
177675a7 3654
d6da7448 3655 if Is_Constant_Object (O_Ent)
3656 and then Ekind (U_Ent) = E_Variable
3657 then
3658 Set_Overlays_Constant (U_Ent);
83f8f0a6 3659 end if;
d6da7448 3660 end if;
3661 end;
83f8f0a6 3662
d6f39728 3663 -- Not a valid entity for an address clause
3664
3665 else
3666 Error_Msg_N ("address cannot be given for &", Nam);
3667 end if;
3668 end Address;
3669
3670 ---------------
3671 -- Alignment --
3672 ---------------
3673
3674 -- Alignment attribute definition clause
3675
b47769f0 3676 when Attribute_Alignment => Alignment : declare
208fd589 3677 Align : constant Uint := Get_Alignment_Value (Expr);
3678 Max_Align : constant Uint := UI_From_Int (Maximum_Alignment);
41331dcf 3679
d6f39728 3680 begin
3681 FOnly := True;
3682
3683 if not Is_Type (U_Ent)
3684 and then Ekind (U_Ent) /= E_Variable
3685 and then Ekind (U_Ent) /= E_Constant
3686 then
3687 Error_Msg_N ("alignment cannot be given for &", Nam);
3688
ae888dbd 3689 elsif Duplicate_Clause then
3690 null;
d6f39728 3691
3692 elsif Align /= No_Uint then
3693 Set_Has_Alignment_Clause (U_Ent);
208fd589 3694
44705307 3695 -- Tagged type case, check for attempt to set alignment to a
3696 -- value greater than Max_Align, and reset if so.
3697
41331dcf 3698 if Is_Tagged_Type (U_Ent) and then Align > Max_Align then
208fd589 3699 Error_Msg_N
1e3532e7 3700 ("alignment for & set to Maximum_Aligment??", Nam);
44705307 3701 Set_Alignment (U_Ent, Max_Align);
3702
3703 -- All other cases
3704
208fd589 3705 else
3706 Set_Alignment (U_Ent, Align);
3707 end if;
b47769f0 3708
3709 -- For an array type, U_Ent is the first subtype. In that case,
3710 -- also set the alignment of the anonymous base type so that
3711 -- other subtypes (such as the itypes for aggregates of the
3712 -- type) also receive the expected alignment.
3713
3714 if Is_Array_Type (U_Ent) then
3715 Set_Alignment (Base_Type (U_Ent), Align);
3716 end if;
d6f39728 3717 end if;
b47769f0 3718 end Alignment;
d6f39728 3719
3720 ---------------
3721 -- Bit_Order --
3722 ---------------
3723
3724 -- Bit_Order attribute definition clause
3725
3726 when Attribute_Bit_Order => Bit_Order : declare
3727 begin
3728 if not Is_Record_Type (U_Ent) then
3729 Error_Msg_N
3730 ("Bit_Order can only be defined for record type", Nam);
3731
ae888dbd 3732 elsif Duplicate_Clause then
3733 null;
3734
d6f39728 3735 else
3736 Analyze_And_Resolve (Expr, RTE (RE_Bit_Order));
3737
3738 if Etype (Expr) = Any_Type then
3739 return;
3740
3741 elsif not Is_Static_Expression (Expr) then
9dfe12ae 3742 Flag_Non_Static_Expr
3743 ("Bit_Order requires static expression!", Expr);
d6f39728 3744
3745 else
3746 if (Expr_Value (Expr) = 0) /= Bytes_Big_Endian then
3747 Set_Reverse_Bit_Order (U_Ent, True);
3748 end if;
3749 end if;
3750 end if;
3751 end Bit_Order;
3752
3753 --------------------
3754 -- Component_Size --
3755 --------------------
3756
3757 -- Component_Size attribute definition clause
3758
3759 when Attribute_Component_Size => Component_Size_Case : declare
3760 Csize : constant Uint := Static_Integer (Expr);
a0fc8c5b 3761 Ctyp : Entity_Id;
d6f39728 3762 Btype : Entity_Id;
3763 Biased : Boolean;
3764 New_Ctyp : Entity_Id;
3765 Decl : Node_Id;
3766
3767 begin
3768 if not Is_Array_Type (U_Ent) then
3769 Error_Msg_N ("component size requires array type", Nam);
3770 return;
3771 end if;
3772
3773 Btype := Base_Type (U_Ent);
a0fc8c5b 3774 Ctyp := Component_Type (Btype);
d6f39728 3775
ae888dbd 3776 if Duplicate_Clause then
3777 null;
d6f39728 3778
f3e4db96 3779 elsif Rep_Item_Too_Early (Btype, N) then
3780 null;
3781
d6f39728 3782 elsif Csize /= No_Uint then
a0fc8c5b 3783 Check_Size (Expr, Ctyp, Csize, Biased);
d6f39728 3784
d74fc39a 3785 -- For the biased case, build a declaration for a subtype that
3786 -- will be used to represent the biased subtype that reflects
3787 -- the biased representation of components. We need the subtype
3788 -- to get proper conversions on referencing elements of the
3789 -- array. Note: component size clauses are ignored in VM mode.
3062c401 3790
3791 if VM_Target = No_VM then
3792 if Biased then
3793 New_Ctyp :=
3794 Make_Defining_Identifier (Loc,
3795 Chars =>
3796 New_External_Name (Chars (U_Ent), 'C', 0, 'T'));
3797
3798 Decl :=
3799 Make_Subtype_Declaration (Loc,
3800 Defining_Identifier => New_Ctyp,
3801 Subtype_Indication =>
3802 New_Occurrence_Of (Component_Type (Btype), Loc));
3803
3804 Set_Parent (Decl, N);
3805 Analyze (Decl, Suppress => All_Checks);
3806
3807 Set_Has_Delayed_Freeze (New_Ctyp, False);
3808 Set_Esize (New_Ctyp, Csize);
3809 Set_RM_Size (New_Ctyp, Csize);
3810 Init_Alignment (New_Ctyp);
3062c401 3811 Set_Is_Itype (New_Ctyp, True);
3812 Set_Associated_Node_For_Itype (New_Ctyp, U_Ent);
3813
3814 Set_Component_Type (Btype, New_Ctyp);
b77e4501 3815 Set_Biased (New_Ctyp, N, "component size clause");
3062c401 3816 end if;
3817
3818 Set_Component_Size (Btype, Csize);
3819
3820 -- For VM case, we ignore component size clauses
3821
3822 else
3823 -- Give a warning unless we are in GNAT mode, in which case
3824 -- the warning is suppressed since it is not useful.
3825
3826 if not GNAT_Mode then
3827 Error_Msg_N
1e3532e7 3828 ("component size ignored in this configuration??", N);
3062c401 3829 end if;
d6f39728 3830 end if;
3831
a0fc8c5b 3832 -- Deal with warning on overridden size
3833
3834 if Warn_On_Overridden_Size
3835 and then Has_Size_Clause (Ctyp)
3836 and then RM_Size (Ctyp) /= Csize
3837 then
3838 Error_Msg_NE
1e3532e7 3839 ("component size overrides size clause for&?S?", N, Ctyp);
a0fc8c5b 3840 end if;
3841
d6f39728 3842 Set_Has_Component_Size_Clause (Btype, True);
f3e4db96 3843 Set_Has_Non_Standard_Rep (Btype, True);
d6f39728 3844 end if;
3845 end Component_Size_Case;
3846
81b424ac 3847 -----------------------
3848 -- Constant_Indexing --
3849 -----------------------
3850
3851 when Attribute_Constant_Indexing =>
3852 Check_Indexing_Functions;
3853
89f1e35c 3854 ---------
3855 -- CPU --
3856 ---------
3857
3858 when Attribute_CPU => CPU :
3859 begin
3860 -- CPU attribute definition clause not allowed except from aspect
3861 -- specification.
3862
3863 if From_Aspect_Specification (N) then
3864 if not Is_Task_Type (U_Ent) then
3865 Error_Msg_N ("CPU can only be defined for task", Nam);
3866
3867 elsif Duplicate_Clause then
3868 null;
3869
3870 else
3871 -- The expression must be analyzed in the special manner
3872 -- described in "Handling of Default and Per-Object
3873 -- Expressions" in sem.ads.
3874
3875 -- The visibility to the discriminants must be restored
3876
3877 Push_Scope_And_Install_Discriminants (U_Ent);
3878 Preanalyze_Spec_Expression (Expr, RTE (RE_CPU_Range));
3879 Uninstall_Discriminants_And_Pop_Scope (U_Ent);
3880
3881 if not Is_Static_Expression (Expr) then
3882 Check_Restriction (Static_Priorities, Expr);
3883 end if;
3884 end if;
3885
3886 else
3887 Error_Msg_N
3888 ("attribute& cannot be set with definition clause", N);
3889 end if;
3890 end CPU;
3891
89cc7147 3892 ----------------------
3893 -- Default_Iterator --
3894 ----------------------
3895
3896 when Attribute_Default_Iterator => Default_Iterator : declare
3897 Func : Entity_Id;
3898
3899 begin
3900 if not Is_Tagged_Type (U_Ent) then
3901 Error_Msg_N
3902 ("aspect Default_Iterator applies to tagged type", Nam);
3903 end if;
3904
3905 Check_Iterator_Functions;
3906
3907 Analyze (Expr);
3908
3909 if not Is_Entity_Name (Expr)
3910 or else Ekind (Entity (Expr)) /= E_Function
3911 then
3912 Error_Msg_N ("aspect Iterator must be a function", Expr);
3913 else
3914 Func := Entity (Expr);
3915 end if;
3916
3917 if No (First_Formal (Func))
3918 or else Etype (First_Formal (Func)) /= U_Ent
3919 then
3920 Error_Msg_NE
3921 ("Default Iterator must be a primitive of&", Func, U_Ent);
3922 end if;
3923 end Default_Iterator;
3924
89f1e35c 3925 ------------------------
3926 -- Dispatching_Domain --
3927 ------------------------
3928
3929 when Attribute_Dispatching_Domain => Dispatching_Domain :
3930 begin
3931 -- Dispatching_Domain attribute definition clause not allowed
3932 -- except from aspect specification.
3933
3934 if From_Aspect_Specification (N) then
3935 if not Is_Task_Type (U_Ent) then
3936 Error_Msg_N ("Dispatching_Domain can only be defined" &
3937 "for task",
3938 Nam);
3939
3940 elsif Duplicate_Clause then
3941 null;
3942
3943 else
3944 -- The expression must be analyzed in the special manner
3945 -- described in "Handling of Default and Per-Object
3946 -- Expressions" in sem.ads.
3947
3948 -- The visibility to the discriminants must be restored
3949
3950 Push_Scope_And_Install_Discriminants (U_Ent);
3951
3952 Preanalyze_Spec_Expression
3953 (Expr, RTE (RE_Dispatching_Domain));
3954
3955 Uninstall_Discriminants_And_Pop_Scope (U_Ent);
3956 end if;
3957
3958 else
3959 Error_Msg_N
3960 ("attribute& cannot be set with definition clause", N);
3961 end if;
3962 end Dispatching_Domain;
3963
d6f39728 3964 ------------------
3965 -- External_Tag --
3966 ------------------
3967
3968 when Attribute_External_Tag => External_Tag :
3969 begin
3970 if not Is_Tagged_Type (U_Ent) then
3971 Error_Msg_N ("should be a tagged type", Nam);
3972 end if;
3973
ae888dbd 3974 if Duplicate_Clause then
3975 null;
d6f39728 3976
9af0ddc7 3977 else
ae888dbd 3978 Analyze_And_Resolve (Expr, Standard_String);
fbc67f84 3979
ae888dbd 3980 if not Is_Static_Expression (Expr) then
3981 Flag_Non_Static_Expr
3982 ("static string required for tag name!", Nam);
3983 end if;
3984
3985 if VM_Target = No_VM then
3986 Set_Has_External_Tag_Rep_Clause (U_Ent);
3987 else
3988 Error_Msg_Name_1 := Attr;
3989 Error_Msg_N
3990 ("% attribute unsupported in this configuration", Nam);
3991 end if;
3992
3993 if not Is_Library_Level_Entity (U_Ent) then
3994 Error_Msg_NE
1e3532e7 3995 ("??non-unique external tag supplied for &", N, U_Ent);
ae888dbd 3996 Error_Msg_N
1e3532e7 3997 ("\??same external tag applies to all "
3998 & "subprogram calls", N);
ae888dbd 3999 Error_Msg_N
1e3532e7 4000 ("\??corresponding internal tag cannot be obtained", N);
ae888dbd 4001 end if;
fbc67f84 4002 end if;
d6f39728 4003 end External_Tag;
4004
b57530b8 4005 --------------------------
4006 -- Implicit_Dereference --
4007 --------------------------
7947a439 4008
b57530b8 4009 when Attribute_Implicit_Dereference =>
7947a439 4010
2beb22b1 4011 -- Legality checks already performed at the point of the type
4012 -- declaration, aspect is not delayed.
7947a439 4013
89cc7147 4014 null;
b57530b8 4015
d6f39728 4016 -----------
4017 -- Input --
4018 -----------
4019
9f373bb8 4020 when Attribute_Input =>
4021 Analyze_Stream_TSS_Definition (TSS_Stream_Input);
4022 Set_Has_Specified_Stream_Input (Ent);
d6f39728 4023
89f1e35c 4024 ------------------------
4025 -- Interrupt_Priority --
4026 ------------------------
4027
4028 when Attribute_Interrupt_Priority => Interrupt_Priority :
4029 begin
4030 -- Interrupt_Priority attribute definition clause not allowed
4031 -- except from aspect specification.
4032
4033 if From_Aspect_Specification (N) then
4034 if not (Is_Protected_Type (U_Ent)
4035 or else Is_Task_Type (U_Ent))
4036 then
4037 Error_Msg_N
4038 ("Interrupt_Priority can only be defined for task" &
4039 "and protected object",
4040 Nam);
4041
4042 elsif Duplicate_Clause then
4043 null;
4044
4045 else
4046 -- The expression must be analyzed in the special manner
4047 -- described in "Handling of Default and Per-Object
4048 -- Expressions" in sem.ads.
4049
4050 -- The visibility to the discriminants must be restored
4051
4052 Push_Scope_And_Install_Discriminants (U_Ent);
4053
4054 Preanalyze_Spec_Expression
4055 (Expr, RTE (RE_Interrupt_Priority));
4056
4057 Uninstall_Discriminants_And_Pop_Scope (U_Ent);
4058 end if;
4059
4060 else
4061 Error_Msg_N
4062 ("attribute& cannot be set with definition clause", N);
4063 end if;
4064 end Interrupt_Priority;
4065
89cc7147 4066 ----------------------
4067 -- Iterator_Element --
4068 ----------------------
4069
4070 when Attribute_Iterator_Element =>
4071 Analyze (Expr);
4072
4073 if not Is_Entity_Name (Expr)
4074 or else not Is_Type (Entity (Expr))
4075 then
4076 Error_Msg_N ("aspect Iterator_Element must be a type", Expr);
4077 end if;
4078
d6f39728 4079 -------------------
4080 -- Machine_Radix --
4081 -------------------
4082
4083 -- Machine radix attribute definition clause
4084
4085 when Attribute_Machine_Radix => Machine_Radix : declare
4086 Radix : constant Uint := Static_Integer (Expr);
4087
4088 begin
4089 if not Is_Decimal_Fixed_Point_Type (U_Ent) then
4090 Error_Msg_N ("decimal fixed-point type expected for &", Nam);
4091
ae888dbd 4092 elsif Duplicate_Clause then
4093 null;
d6f39728 4094
4095 elsif Radix /= No_Uint then
4096 Set_Has_Machine_Radix_Clause (U_Ent);
4097 Set_Has_Non_Standard_Rep (Base_Type (U_Ent));
4098
4099 if Radix = 2 then
4100 null;
4101 elsif Radix = 10 then
4102 Set_Machine_Radix_10 (U_Ent);
4103 else
4104 Error_Msg_N ("machine radix value must be 2 or 10", Expr);
4105 end if;
4106 end if;
4107 end Machine_Radix;
4108
4109 -----------------
4110 -- Object_Size --
4111 -----------------
4112
4113 -- Object_Size attribute definition clause
4114
4115 when Attribute_Object_Size => Object_Size : declare
bfa5a9d9 4116 Size : constant Uint := Static_Integer (Expr);
4117
d6f39728 4118 Biased : Boolean;
bfa5a9d9 4119 pragma Warnings (Off, Biased);
d6f39728 4120
4121 begin
4122 if not Is_Type (U_Ent) then
4123 Error_Msg_N ("Object_Size cannot be given for &", Nam);
4124
ae888dbd 4125 elsif Duplicate_Clause then
4126 null;
d6f39728 4127
4128 else
4129 Check_Size (Expr, U_Ent, Size, Biased);
4130
4131 if Size /= 8
4132 and then
4133 Size /= 16
4134 and then
4135 Size /= 32
4136 and then
4137 UI_Mod (Size, 64) /= 0
4138 then
4139 Error_Msg_N
4140 ("Object_Size must be 8, 16, 32, or multiple of 64",
4141 Expr);
4142 end if;
4143
4144 Set_Esize (U_Ent, Size);
4145 Set_Has_Object_Size_Clause (U_Ent);
1d366b32 4146 Alignment_Check_For_Size_Change (U_Ent, Size);
d6f39728 4147 end if;
4148 end Object_Size;
4149
4150 ------------
4151 -- Output --
4152 ------------
4153
9f373bb8 4154 when Attribute_Output =>
4155 Analyze_Stream_TSS_Definition (TSS_Stream_Output);
4156 Set_Has_Specified_Stream_Output (Ent);
d6f39728 4157
89f1e35c 4158 --------------
4159 -- Priority --
4160 --------------
4161
4162 when Attribute_Priority => Priority :
4163 begin
4164 -- Priority attribute definition clause not allowed except from
4165 -- aspect specification.
4166
4167 if From_Aspect_Specification (N) then
4168 if not (Is_Protected_Type (U_Ent)
3a72f9c3 4169 or else Is_Task_Type (U_Ent)
4170 or else Ekind (U_Ent) = E_Procedure)
89f1e35c 4171 then
4172 Error_Msg_N
3a72f9c3 4173 ("Priority can only be defined for task and protected " &
89f1e35c 4174 "object",
4175 Nam);
4176
4177 elsif Duplicate_Clause then
4178 null;
4179
4180 else
4181 -- The expression must be analyzed in the special manner
4182 -- described in "Handling of Default and Per-Object
4183 -- Expressions" in sem.ads.
4184
4185 -- The visibility to the discriminants must be restored
4186
4187 Push_Scope_And_Install_Discriminants (U_Ent);
4188 Preanalyze_Spec_Expression (Expr, Standard_Integer);
4189 Uninstall_Discriminants_And_Pop_Scope (U_Ent);
4190
4191 if not Is_Static_Expression (Expr) then
4192 Check_Restriction (Static_Priorities, Expr);
4193 end if;
4194 end if;
4195
4196 else
4197 Error_Msg_N
4198 ("attribute& cannot be set with definition clause", N);
4199 end if;
4200 end Priority;
4201
d6f39728 4202 ----------
4203 -- Read --
4204 ----------
4205
9f373bb8 4206 when Attribute_Read =>
4207 Analyze_Stream_TSS_Definition (TSS_Stream_Read);
4208 Set_Has_Specified_Stream_Read (Ent);
d6f39728 4209
b7b74740 4210 --------------------------
4211 -- Scalar_Storage_Order --
4212 --------------------------
4213
4214 -- Scalar_Storage_Order attribute definition clause
4215
4216 when Attribute_Scalar_Storage_Order => Scalar_Storage_Order : declare
4217 begin
b43a5770 4218 if not (Is_Record_Type (U_Ent) or else Is_Array_Type (U_Ent)) then
b7b74740 4219 Error_Msg_N
b43a5770 4220 ("Scalar_Storage_Order can only be defined for "
4221 & "record or array type", Nam);
b7b74740 4222
4223 elsif Duplicate_Clause then
4224 null;
4225
4226 else
4227 Analyze_And_Resolve (Expr, RTE (RE_Bit_Order));
4228
4229 if Etype (Expr) = Any_Type then
4230 return;
4231
4232 elsif not Is_Static_Expression (Expr) then
4233 Flag_Non_Static_Expr
4234 ("Scalar_Storage_Order requires static expression!", Expr);
4235
c0912570 4236 elsif (Expr_Value (Expr) = 0) /= Bytes_Big_Endian then
4237
4238 -- Here for the case of a non-default (i.e. non-confirming)
4239 -- Scalar_Storage_Order attribute definition.
4240
4241 if Support_Nondefault_SSO_On_Target then
d0a9ea3b 4242 Set_Reverse_Storage_Order (Base_Type (U_Ent), True);
c0912570 4243 else
4244 Error_Msg_N
4245 ("non-default Scalar_Storage_Order "
4246 & "not supported on target", Expr);
b7b74740 4247 end if;
4248 end if;
4249 end if;
4250 end Scalar_Storage_Order;
4251
d6f39728 4252 ----------
4253 -- Size --
4254 ----------
4255
4256 -- Size attribute definition clause
4257
4258 when Attribute_Size => Size : declare
4259 Size : constant Uint := Static_Integer (Expr);
4260 Etyp : Entity_Id;
4261 Biased : Boolean;
4262
4263 begin
4264 FOnly := True;
4265
ae888dbd 4266 if Duplicate_Clause then
4267 null;
d6f39728 4268
4269 elsif not Is_Type (U_Ent)
4270 and then Ekind (U_Ent) /= E_Variable
4271 and then Ekind (U_Ent) /= E_Constant
4272 then
4273 Error_Msg_N ("size cannot be given for &", Nam);
4274
4275 elsif Is_Array_Type (U_Ent)
4276 and then not Is_Constrained (U_Ent)
4277 then
4278 Error_Msg_N
4279 ("size cannot be given for unconstrained array", Nam);
4280
c2b89d6e 4281 elsif Size /= No_Uint then
c2b89d6e 4282 if VM_Target /= No_VM and then not GNAT_Mode then
47495553 4283
c2b89d6e 4284 -- Size clause is not handled properly on VM targets.
4285 -- Display a warning unless we are in GNAT mode, in which
4286 -- case this is useless.
47495553 4287
682fa897 4288 Error_Msg_N
1e3532e7 4289 ("size clauses are ignored in this configuration??", N);
682fa897 4290 end if;
4291
d6f39728 4292 if Is_Type (U_Ent) then
4293 Etyp := U_Ent;
4294 else
4295 Etyp := Etype (U_Ent);
4296 end if;
4297
59ac57b5 4298 -- Check size, note that Gigi is in charge of checking that the
4299 -- size of an array or record type is OK. Also we do not check
4300 -- the size in the ordinary fixed-point case, since it is too
4301 -- early to do so (there may be subsequent small clause that
4302 -- affects the size). We can check the size if a small clause
4303 -- has already been given.
d6f39728 4304
4305 if not Is_Ordinary_Fixed_Point_Type (U_Ent)
4306 or else Has_Small_Clause (U_Ent)
4307 then
4308 Check_Size (Expr, Etyp, Size, Biased);
b77e4501 4309 Set_Biased (U_Ent, N, "size clause", Biased);
d6f39728 4310 end if;
4311
4312 -- For types set RM_Size and Esize if possible
4313
4314 if Is_Type (U_Ent) then
4315 Set_RM_Size (U_Ent, Size);
4316
ada34def 4317 -- For elementary types, increase Object_Size to power of 2,
4318 -- but not less than a storage unit in any case (normally
59ac57b5 4319 -- this means it will be byte addressable).
d6f39728 4320
ada34def 4321 -- For all other types, nothing else to do, we leave Esize
4322 -- (object size) unset, the back end will set it from the
4323 -- size and alignment in an appropriate manner.
4324
1d366b32 4325 -- In both cases, we check whether the alignment must be
4326 -- reset in the wake of the size change.
4327
ada34def 4328 if Is_Elementary_Type (U_Ent) then
f15731c4 4329 if Size <= System_Storage_Unit then
4330 Init_Esize (U_Ent, System_Storage_Unit);
d6f39728 4331 elsif Size <= 16 then
4332 Init_Esize (U_Ent, 16);
4333 elsif Size <= 32 then
4334 Init_Esize (U_Ent, 32);
4335 else
4336 Set_Esize (U_Ent, (Size + 63) / 64 * 64);
4337 end if;
4338
1d366b32 4339 Alignment_Check_For_Size_Change (U_Ent, Esize (U_Ent));
4340 else
4341 Alignment_Check_For_Size_Change (U_Ent, Size);
d6f39728 4342 end if;
4343
d6f39728 4344 -- For objects, set Esize only
4345
4346 else
9dfe12ae 4347 if Is_Elementary_Type (Etyp) then
4348 if Size /= System_Storage_Unit
4349 and then
4350 Size /= System_Storage_Unit * 2
4351 and then
4352 Size /= System_Storage_Unit * 4
4353 and then
4354 Size /= System_Storage_Unit * 8
4355 then
5c99c290 4356 Error_Msg_Uint_1 := UI_From_Int (System_Storage_Unit);
87d5c1d0 4357 Error_Msg_Uint_2 := Error_Msg_Uint_1 * 8;
9dfe12ae 4358 Error_Msg_N
5c99c290 4359 ("size for primitive object must be a power of 2"
87d5c1d0 4360 & " in the range ^-^", N);
9dfe12ae 4361 end if;
4362 end if;
4363
d6f39728 4364 Set_Esize (U_Ent, Size);
4365 end if;
4366
4367 Set_Has_Size_Clause (U_Ent);
4368 end if;
4369 end Size;
4370
4371 -----------
4372 -- Small --
4373 -----------
4374
4375 -- Small attribute definition clause
4376
4377 when Attribute_Small => Small : declare
4378 Implicit_Base : constant Entity_Id := Base_Type (U_Ent);
4379 Small : Ureal;
4380
4381 begin
4382 Analyze_And_Resolve (Expr, Any_Real);
4383
4384 if Etype (Expr) = Any_Type then
4385 return;
4386
4387 elsif not Is_Static_Expression (Expr) then
9dfe12ae 4388 Flag_Non_Static_Expr
4389 ("small requires static expression!", Expr);
d6f39728 4390 return;
4391
4392 else
4393 Small := Expr_Value_R (Expr);
4394
4395 if Small <= Ureal_0 then
4396 Error_Msg_N ("small value must be greater than zero", Expr);
4397 return;
4398 end if;
4399
4400 end if;
4401
4402 if not Is_Ordinary_Fixed_Point_Type (U_Ent) then
4403 Error_Msg_N
4404 ("small requires an ordinary fixed point type", Nam);
4405
4406 elsif Has_Small_Clause (U_Ent) then
4407 Error_Msg_N ("small already given for &", Nam);
4408
4409 elsif Small > Delta_Value (U_Ent) then
4410 Error_Msg_N
ce3e25d6 4411 ("small value must not be greater than delta value", Nam);
d6f39728 4412
4413 else
4414 Set_Small_Value (U_Ent, Small);
4415 Set_Small_Value (Implicit_Base, Small);
4416 Set_Has_Small_Clause (U_Ent);
4417 Set_Has_Small_Clause (Implicit_Base);
4418 Set_Has_Non_Standard_Rep (Implicit_Base);
4419 end if;
4420 end Small;
4421
d6f39728 4422 ------------------
4423 -- Storage_Pool --
4424 ------------------
4425
4426 -- Storage_Pool attribute definition clause
4427
b55f7641 4428 when Attribute_Storage_Pool | Attribute_Simple_Storage_Pool => declare
d6f39728 4429 Pool : Entity_Id;
6b567c71 4430 T : Entity_Id;
d6f39728 4431
4432 begin
44e4341e 4433 if Ekind (U_Ent) = E_Access_Subprogram_Type then
4434 Error_Msg_N
4435 ("storage pool cannot be given for access-to-subprogram type",
4436 Nam);
4437 return;
4438
d3ef794c 4439 elsif not
4440 Ekind_In (U_Ent, E_Access_Type, E_General_Access_Type)
d6f39728 4441 then
44e4341e 4442 Error_Msg_N
4443 ("storage pool can only be given for access types", Nam);
d6f39728 4444 return;
4445
4446 elsif Is_Derived_Type (U_Ent) then
4447 Error_Msg_N
4448 ("storage pool cannot be given for a derived access type",
4449 Nam);
4450
ae888dbd 4451 elsif Duplicate_Clause then
d6f39728 4452 return;
4453
4454 elsif Present (Associated_Storage_Pool (U_Ent)) then
4455 Error_Msg_N ("storage pool already given for &", Nam);
4456 return;
4457 end if;
4458
b55f7641 4459 if Id = Attribute_Storage_Pool then
4460 Analyze_And_Resolve
4461 (Expr, Class_Wide_Type (RTE (RE_Root_Storage_Pool)));
4462
4463 -- In the Simple_Storage_Pool case, we allow a variable of any
b15003c3 4464 -- simple storage pool type, so we Resolve without imposing an
b55f7641 4465 -- expected type.
4466
4467 else
4468 Analyze_And_Resolve (Expr);
4469
4470 if not Present (Get_Rep_Pragma
b15003c3 4471 (Etype (Expr), Name_Simple_Storage_Pool_Type))
b55f7641 4472 then
4473 Error_Msg_N
4474 ("expression must be of a simple storage pool type", Expr);
4475 end if;
4476 end if;
d6f39728 4477
8c5c7277 4478 if not Denotes_Variable (Expr) then
4479 Error_Msg_N ("storage pool must be a variable", Expr);
4480 return;
4481 end if;
4482
6b567c71 4483 if Nkind (Expr) = N_Type_Conversion then
4484 T := Etype (Expression (Expr));
4485 else
4486 T := Etype (Expr);
4487 end if;
4488
4489 -- The Stack_Bounded_Pool is used internally for implementing
d64221a7 4490 -- access types with a Storage_Size. Since it only work properly
4491 -- when used on one specific type, we need to check that it is not
4492 -- hijacked improperly:
4493
6b567c71 4494 -- type T is access Integer;
4495 -- for T'Storage_Size use n;
4496 -- type Q is access Float;
4497 -- for Q'Storage_Size use T'Storage_Size; -- incorrect
4498
15ebb600 4499 if RTE_Available (RE_Stack_Bounded_Pool)
4500 and then Base_Type (T) = RTE (RE_Stack_Bounded_Pool)
4501 then
4502 Error_Msg_N ("non-shareable internal Pool", Expr);
6b567c71 4503 return;
4504 end if;
4505
d6f39728 4506 -- If the argument is a name that is not an entity name, then
4507 -- we construct a renaming operation to define an entity of
4508 -- type storage pool.
4509
4510 if not Is_Entity_Name (Expr)
4511 and then Is_Object_Reference (Expr)
4512 then
11deeeb6 4513 Pool := Make_Temporary (Loc, 'P', Expr);
d6f39728 4514
4515 declare
4516 Rnode : constant Node_Id :=
4517 Make_Object_Renaming_Declaration (Loc,
4518 Defining_Identifier => Pool,
4519 Subtype_Mark =>
4520 New_Occurrence_Of (Etype (Expr), Loc),
11deeeb6 4521 Name => Expr);
d6f39728 4522
4523 begin
f65f7fdf 4524 -- If the attribute definition clause comes from an aspect
4525 -- clause, then insert the renaming before the associated
4526 -- entity's declaration, since the attribute clause has
4527 -- not yet been appended to the declaration list.
4528
4529 if From_Aspect_Specification (N) then
4530 Insert_Before (Parent (Entity (N)), Rnode);
4531 else
4532 Insert_Before (N, Rnode);
4533 end if;
4534
d6f39728 4535 Analyze (Rnode);
4536 Set_Associated_Storage_Pool (U_Ent, Pool);
4537 end;
4538
4539 elsif Is_Entity_Name (Expr) then
4540 Pool := Entity (Expr);
4541
4542 -- If pool is a renamed object, get original one. This can
4543 -- happen with an explicit renaming, and within instances.
4544
4545 while Present (Renamed_Object (Pool))
4546 and then Is_Entity_Name (Renamed_Object (Pool))
4547 loop
4548 Pool := Entity (Renamed_Object (Pool));
4549 end loop;
4550
4551 if Present (Renamed_Object (Pool))
4552 and then Nkind (Renamed_Object (Pool)) = N_Type_Conversion
4553 and then Is_Entity_Name (Expression (Renamed_Object (Pool)))
4554 then
4555 Pool := Entity (Expression (Renamed_Object (Pool)));
4556 end if;
4557
6b567c71 4558 Set_Associated_Storage_Pool (U_Ent, Pool);
d6f39728 4559
4560 elsif Nkind (Expr) = N_Type_Conversion
4561 and then Is_Entity_Name (Expression (Expr))
4562 and then Nkind (Original_Node (Expr)) = N_Attribute_Reference
4563 then
4564 Pool := Entity (Expression (Expr));
6b567c71 4565 Set_Associated_Storage_Pool (U_Ent, Pool);
d6f39728 4566
4567 else
4568 Error_Msg_N ("incorrect reference to a Storage Pool", Expr);
4569 return;
4570 end if;
b55f7641 4571 end;
d6f39728 4572
44e4341e 4573 ------------------
4574 -- Storage_Size --
4575 ------------------
4576
4577 -- Storage_Size attribute definition clause
4578
4579 when Attribute_Storage_Size => Storage_Size : declare
4580 Btype : constant Entity_Id := Base_Type (U_Ent);
44e4341e 4581
4582 begin
4583 if Is_Task_Type (U_Ent) then
44e4341e 4584
ceec4f7c 4585 -- Check obsolescent (but never obsolescent if from aspect!)
4586
4587 if not From_Aspect_Specification (N) then
4588 Check_Restriction (No_Obsolescent_Features, N);
4589
4590 if Warn_On_Obsolescent_Feature then
4591 Error_Msg_N
4592 ("?j?storage size clause for task is an " &
4593 "obsolescent feature (RM J.9)", N);
4594 Error_Msg_N ("\?j?use Storage_Size pragma instead", N);
4595 end if;
44e4341e 4596 end if;
4597
4598 FOnly := True;
4599 end if;
4600
4601 if not Is_Access_Type (U_Ent)
4602 and then Ekind (U_Ent) /= E_Task_Type
4603 then
4604 Error_Msg_N ("storage size cannot be given for &", Nam);
4605
4606 elsif Is_Access_Type (U_Ent) and Is_Derived_Type (U_Ent) then
4607 Error_Msg_N
4608 ("storage size cannot be given for a derived access type",
4609 Nam);
4610
ae888dbd 4611 elsif Duplicate_Clause then
4612 null;
44e4341e 4613
4614 else
4615 Analyze_And_Resolve (Expr, Any_Integer);
4616
4617 if Is_Access_Type (U_Ent) then
4618 if Present (Associated_Storage_Pool (U_Ent)) then
4619 Error_Msg_N ("storage pool already given for &", Nam);
4620 return;
4621 end if;
4622
5941a4e9 4623 if Is_OK_Static_Expression (Expr)
44e4341e 4624 and then Expr_Value (Expr) = 0
4625 then
4626 Set_No_Pool_Assigned (Btype);
4627 end if;
44e4341e 4628 end if;
4629
4630 Set_Has_Storage_Size_Clause (Btype);
4631 end if;
4632 end Storage_Size;
4633
7189d17f 4634 -----------------
4635 -- Stream_Size --
4636 -----------------
4637
4638 when Attribute_Stream_Size => Stream_Size : declare
4639 Size : constant Uint := Static_Integer (Expr);
4640
4641 begin
15ebb600 4642 if Ada_Version <= Ada_95 then
4643 Check_Restriction (No_Implementation_Attributes, N);
4644 end if;
4645
ae888dbd 4646 if Duplicate_Clause then
4647 null;
7189d17f 4648
4649 elsif Is_Elementary_Type (U_Ent) then
4650 if Size /= System_Storage_Unit
4651 and then
4652 Size /= System_Storage_Unit * 2
4653 and then
4654 Size /= System_Storage_Unit * 4
4655 and then
4656 Size /= System_Storage_Unit * 8
4657 then
4658 Error_Msg_Uint_1 := UI_From_Int (System_Storage_Unit);
4659 Error_Msg_N
4660 ("stream size for elementary type must be a"
4661 & " power of 2 and at least ^", N);
4662
4663 elsif RM_Size (U_Ent) > Size then
4664 Error_Msg_Uint_1 := RM_Size (U_Ent);
4665 Error_Msg_N
4666 ("stream size for elementary type must be a"
4667 & " power of 2 and at least ^", N);
4668 end if;
4669
4670 Set_Has_Stream_Size_Clause (U_Ent);
4671
4672 else
4673 Error_Msg_N ("Stream_Size cannot be given for &", Nam);
4674 end if;
4675 end Stream_Size;
4676
d6f39728 4677 ----------------
4678 -- Value_Size --
4679 ----------------
4680
4681 -- Value_Size attribute definition clause
4682
4683 when Attribute_Value_Size => Value_Size : declare
4684 Size : constant Uint := Static_Integer (Expr);
4685 Biased : Boolean;
4686
4687 begin
4688 if not Is_Type (U_Ent) then
4689 Error_Msg_N ("Value_Size cannot be given for &", Nam);
4690
ae888dbd 4691 elsif Duplicate_Clause then
4692 null;
d6f39728 4693
59ac57b5 4694 elsif Is_Array_Type (U_Ent)
4695 and then not Is_Constrained (U_Ent)
4696 then
4697 Error_Msg_N
4698 ("Value_Size cannot be given for unconstrained array", Nam);
4699
d6f39728 4700 else
4701 if Is_Elementary_Type (U_Ent) then
4702 Check_Size (Expr, U_Ent, Size, Biased);
b77e4501 4703 Set_Biased (U_Ent, N, "value size clause", Biased);
d6f39728 4704 end if;
4705
4706 Set_RM_Size (U_Ent, Size);
4707 end if;
4708 end Value_Size;
4709
81b424ac 4710 -----------------------
4711 -- Variable_Indexing --
4712 -----------------------
4713
4714 when Attribute_Variable_Indexing =>
4715 Check_Indexing_Functions;
4716
d6f39728 4717 -----------
4718 -- Write --
4719 -----------
4720
9f373bb8 4721 when Attribute_Write =>
4722 Analyze_Stream_TSS_Definition (TSS_Stream_Write);
4723 Set_Has_Specified_Stream_Write (Ent);
d6f39728 4724
4725 -- All other attributes cannot be set
4726
4727 when others =>
4728 Error_Msg_N
4729 ("attribute& cannot be set with definition clause", N);
d6f39728 4730 end case;
4731
d64221a7 4732 -- The test for the type being frozen must be performed after any
4733 -- expression the clause has been analyzed since the expression itself
4734 -- might cause freezing that makes the clause illegal.
d6f39728 4735
4736 if Rep_Item_Too_Late (U_Ent, N, FOnly) then
4737 return;
4738 end if;
4739 end Analyze_Attribute_Definition_Clause;
4740
4741 ----------------------------
4742 -- Analyze_Code_Statement --
4743 ----------------------------
4744
4745 procedure Analyze_Code_Statement (N : Node_Id) is
4746 HSS : constant Node_Id := Parent (N);
4747 SBody : constant Node_Id := Parent (HSS);
4748 Subp : constant Entity_Id := Current_Scope;
4749 Stmt : Node_Id;
4750 Decl : Node_Id;
4751 StmtO : Node_Id;
4752 DeclO : Node_Id;
4753
4754 begin
4755 -- Analyze and check we get right type, note that this implements the
4756 -- requirement (RM 13.8(1)) that Machine_Code be with'ed, since that
4757 -- is the only way that Asm_Insn could possibly be visible.
4758
4759 Analyze_And_Resolve (Expression (N));
4760
4761 if Etype (Expression (N)) = Any_Type then
4762 return;
4763 elsif Etype (Expression (N)) /= RTE (RE_Asm_Insn) then
4764 Error_Msg_N ("incorrect type for code statement", N);
4765 return;
4766 end if;
4767
44e4341e 4768 Check_Code_Statement (N);
4769
d6f39728 4770 -- Make sure we appear in the handled statement sequence of a
4771 -- subprogram (RM 13.8(3)).
4772
4773 if Nkind (HSS) /= N_Handled_Sequence_Of_Statements
4774 or else Nkind (SBody) /= N_Subprogram_Body
4775 then
4776 Error_Msg_N
4777 ("code statement can only appear in body of subprogram", N);
4778 return;
4779 end if;
4780
4781 -- Do remaining checks (RM 13.8(3)) if not already done
4782
4783 if not Is_Machine_Code_Subprogram (Subp) then
4784 Set_Is_Machine_Code_Subprogram (Subp);
4785
4786 -- No exception handlers allowed
4787
4788 if Present (Exception_Handlers (HSS)) then
4789 Error_Msg_N
4790 ("exception handlers not permitted in machine code subprogram",
4791 First (Exception_Handlers (HSS)));
4792 end if;
4793
4794 -- No declarations other than use clauses and pragmas (we allow
4795 -- certain internally generated declarations as well).
4796
4797 Decl := First (Declarations (SBody));
4798 while Present (Decl) loop
4799 DeclO := Original_Node (Decl);
4800 if Comes_From_Source (DeclO)
fdd294d1 4801 and not Nkind_In (DeclO, N_Pragma,
4802 N_Use_Package_Clause,
4803 N_Use_Type_Clause,
4804 N_Implicit_Label_Declaration)
d6f39728 4805 then
4806 Error_Msg_N
4807 ("this declaration not allowed in machine code subprogram",
4808 DeclO);
4809 end if;
4810
4811 Next (Decl);
4812 end loop;
4813
4814 -- No statements other than code statements, pragmas, and labels.
4815 -- Again we allow certain internally generated statements.
3ab42ff7 4816
c3107527 4817 -- In Ada 2012, qualified expressions are names, and the code
4818 -- statement is initially parsed as a procedure call.
d6f39728 4819
4820 Stmt := First (Statements (HSS));
4821 while Present (Stmt) loop
4822 StmtO := Original_Node (Stmt);
c3107527 4823
59f2fcab 4824 -- A procedure call transformed into a code statement is OK.
4825
c3107527 4826 if Ada_Version >= Ada_2012
4827 and then Nkind (StmtO) = N_Procedure_Call_Statement
59f2fcab 4828 and then Nkind (Name (StmtO)) = N_Qualified_Expression
c3107527 4829 then
4830 null;
4831
4832 elsif Comes_From_Source (StmtO)
fdd294d1 4833 and then not Nkind_In (StmtO, N_Pragma,
4834 N_Label,
4835 N_Code_Statement)
d6f39728 4836 then
4837 Error_Msg_N
4838 ("this statement is not allowed in machine code subprogram",
4839 StmtO);
4840 end if;
4841
4842 Next (Stmt);
4843 end loop;
4844 end if;
d6f39728 4845 end Analyze_Code_Statement;
4846
4847 -----------------------------------------------
4848 -- Analyze_Enumeration_Representation_Clause --
4849 -----------------------------------------------
4850
4851 procedure Analyze_Enumeration_Representation_Clause (N : Node_Id) is
4852 Ident : constant Node_Id := Identifier (N);
4853 Aggr : constant Node_Id := Array_Aggregate (N);
4854 Enumtype : Entity_Id;
4855 Elit : Entity_Id;
4856 Expr : Node_Id;
4857 Assoc : Node_Id;
4858 Choice : Node_Id;
4859 Val : Uint;
b3190af0 4860
4861 Err : Boolean := False;
098d3082 4862 -- Set True to avoid cascade errors and crashes on incorrect source code
d6f39728 4863
e30c7d84 4864 Lo : constant Uint := Expr_Value (Type_Low_Bound (Universal_Integer));
4865 Hi : constant Uint := Expr_Value (Type_High_Bound (Universal_Integer));
4866 -- Allowed range of universal integer (= allowed range of enum lit vals)
4867
d6f39728 4868 Min : Uint;
4869 Max : Uint;
e30c7d84 4870 -- Minimum and maximum values of entries
4871
4872 Max_Node : Node_Id;
4873 -- Pointer to node for literal providing max value
d6f39728 4874
4875 begin
ca301e17 4876 if Ignore_Rep_Clauses then
fbc67f84 4877 return;
4878 end if;
4879
175a6969 4880 -- Ignore enumeration rep clauses by default in CodePeer mode,
4881 -- unless -gnatd.I is specified, as a work around for potential false
4882 -- positive messages.
4883
4884 if CodePeer_Mode and not Debug_Flag_Dot_II then
4885 return;
4886 end if;
4887
d6f39728 4888 -- First some basic error checks
4889
4890 Find_Type (Ident);
4891 Enumtype := Entity (Ident);
4892
4893 if Enumtype = Any_Type
4894 or else Rep_Item_Too_Early (Enumtype, N)
4895 then
4896 return;
4897 else
4898 Enumtype := Underlying_Type (Enumtype);
4899 end if;
4900
4901 if not Is_Enumeration_Type (Enumtype) then
4902 Error_Msg_NE
4903 ("enumeration type required, found}",
4904 Ident, First_Subtype (Enumtype));
4905 return;
4906 end if;
4907
9dfe12ae 4908 -- Ignore rep clause on generic actual type. This will already have
4909 -- been flagged on the template as an error, and this is the safest
4910 -- way to ensure we don't get a junk cascaded message in the instance.
4911
4912 if Is_Generic_Actual_Type (Enumtype) then
4913 return;
4914
4915 -- Type must be in current scope
4916
4917 elsif Scope (Enumtype) /= Current_Scope then
d6f39728 4918 Error_Msg_N ("type must be declared in this scope", Ident);
4919 return;
4920
9dfe12ae 4921 -- Type must be a first subtype
4922
d6f39728 4923 elsif not Is_First_Subtype (Enumtype) then
4924 Error_Msg_N ("cannot give enumeration rep clause for subtype", N);
4925 return;
4926
9dfe12ae 4927 -- Ignore duplicate rep clause
4928
d6f39728 4929 elsif Has_Enumeration_Rep_Clause (Enumtype) then
4930 Error_Msg_N ("duplicate enumeration rep clause ignored", N);
4931 return;
4932
7189d17f 4933 -- Don't allow rep clause for standard [wide_[wide_]]character
9dfe12ae 4934
177675a7 4935 elsif Is_Standard_Character_Type (Enumtype) then
d6f39728 4936 Error_Msg_N ("enumeration rep clause not allowed for this type", N);
9dfe12ae 4937 return;
4938
d9125581 4939 -- Check that the expression is a proper aggregate (no parentheses)
4940
4941 elsif Paren_Count (Aggr) /= 0 then
4942 Error_Msg
4943 ("extra parentheses surrounding aggregate not allowed",
4944 First_Sloc (Aggr));
4945 return;
4946
9dfe12ae 4947 -- All tests passed, so set rep clause in place
d6f39728 4948
4949 else
4950 Set_Has_Enumeration_Rep_Clause (Enumtype);
4951 Set_Has_Enumeration_Rep_Clause (Base_Type (Enumtype));
4952 end if;
4953
4954 -- Now we process the aggregate. Note that we don't use the normal
4955 -- aggregate code for this purpose, because we don't want any of the
4956 -- normal expansion activities, and a number of special semantic
4957 -- rules apply (including the component type being any integer type)
4958
d6f39728 4959 Elit := First_Literal (Enumtype);
4960
4961 -- First the positional entries if any
4962
4963 if Present (Expressions (Aggr)) then
4964 Expr := First (Expressions (Aggr));
4965 while Present (Expr) loop
4966 if No (Elit) then
4967 Error_Msg_N ("too many entries in aggregate", Expr);
4968 return;
4969 end if;
4970
4971 Val := Static_Integer (Expr);
4972
d9125581 4973 -- Err signals that we found some incorrect entries processing
4974 -- the list. The final checks for completeness and ordering are
4975 -- skipped in this case.
4976
d6f39728 4977 if Val = No_Uint then
4978 Err := True;
d6f39728 4979 elsif Val < Lo or else Hi < Val then
4980 Error_Msg_N ("value outside permitted range", Expr);
4981 Err := True;
4982 end if;
4983
4984 Set_Enumeration_Rep (Elit, Val);
4985 Set_Enumeration_Rep_Expr (Elit, Expr);
4986 Next (Expr);
4987 Next (Elit);
4988 end loop;
4989 end if;
4990
4991 -- Now process the named entries if present
4992
4993 if Present (Component_Associations (Aggr)) then
4994 Assoc := First (Component_Associations (Aggr));
4995 while Present (Assoc) loop
4996 Choice := First (Choices (Assoc));
4997
4998 if Present (Next (Choice)) then
4999 Error_Msg_N
5000 ("multiple choice not allowed here", Next (Choice));
5001 Err := True;
5002 end if;
5003
5004 if Nkind (Choice) = N_Others_Choice then
5005 Error_Msg_N ("others choice not allowed here", Choice);
5006 Err := True;
5007
5008 elsif Nkind (Choice) = N_Range then
b3190af0 5009
d6f39728 5010 -- ??? should allow zero/one element range here
b3190af0 5011
d6f39728 5012 Error_Msg_N ("range not allowed here", Choice);
5013 Err := True;
5014
5015 else
5016 Analyze_And_Resolve (Choice, Enumtype);
b3190af0 5017
098d3082 5018 if Error_Posted (Choice) then
d6f39728 5019 Err := True;
098d3082 5020 end if;
d6f39728 5021
098d3082 5022 if not Err then
5023 if Is_Entity_Name (Choice)
5024 and then Is_Type (Entity (Choice))
5025 then
5026 Error_Msg_N ("subtype name not allowed here", Choice);
d6f39728 5027 Err := True;
b3190af0 5028
098d3082 5029 -- ??? should allow static subtype with zero/one entry
d6f39728 5030
098d3082 5031 elsif Etype (Choice) = Base_Type (Enumtype) then
5032 if not Is_Static_Expression (Choice) then
5033 Flag_Non_Static_Expr
5034 ("non-static expression used for choice!", Choice);
d6f39728 5035 Err := True;
d6f39728 5036
098d3082 5037 else
5038 Elit := Expr_Value_E (Choice);
5039
5040 if Present (Enumeration_Rep_Expr (Elit)) then
5041 Error_Msg_Sloc :=
5042 Sloc (Enumeration_Rep_Expr (Elit));
5043 Error_Msg_NE
5044 ("representation for& previously given#",
5045 Choice, Elit);
5046 Err := True;
5047 end if;
d6f39728 5048
098d3082 5049 Set_Enumeration_Rep_Expr (Elit, Expression (Assoc));
d6f39728 5050
098d3082 5051 Expr := Expression (Assoc);
5052 Val := Static_Integer (Expr);
d6f39728 5053
098d3082 5054 if Val = No_Uint then
5055 Err := True;
5056
5057 elsif Val < Lo or else Hi < Val then
5058 Error_Msg_N ("value outside permitted range", Expr);
5059 Err := True;
5060 end if;
d6f39728 5061
098d3082 5062 Set_Enumeration_Rep (Elit, Val);
5063 end if;
d6f39728 5064 end if;
5065 end if;
5066 end if;
5067
5068 Next (Assoc);
5069 end loop;
5070 end if;
5071
5072 -- Aggregate is fully processed. Now we check that a full set of
5073 -- representations was given, and that they are in range and in order.
5074 -- These checks are only done if no other errors occurred.
5075
5076 if not Err then
5077 Min := No_Uint;
5078 Max := No_Uint;
5079
5080 Elit := First_Literal (Enumtype);
5081 while Present (Elit) loop
5082 if No (Enumeration_Rep_Expr (Elit)) then
5083 Error_Msg_NE ("missing representation for&!", N, Elit);
5084
5085 else
5086 Val := Enumeration_Rep (Elit);
5087
5088 if Min = No_Uint then
5089 Min := Val;
5090 end if;
5091
5092 if Val /= No_Uint then
5093 if Max /= No_Uint and then Val <= Max then
5094 Error_Msg_NE
5095 ("enumeration value for& not ordered!",
e30c7d84 5096 Enumeration_Rep_Expr (Elit), Elit);
d6f39728 5097 end if;
5098
e30c7d84 5099 Max_Node := Enumeration_Rep_Expr (Elit);
d6f39728 5100 Max := Val;
5101 end if;
5102
e30c7d84 5103 -- If there is at least one literal whose representation is not
5104 -- equal to the Pos value, then note that this enumeration type
5105 -- has a non-standard representation.
d6f39728 5106
5107 if Val /= Enumeration_Pos (Elit) then
5108 Set_Has_Non_Standard_Rep (Base_Type (Enumtype));
5109 end if;
5110 end if;
5111
5112 Next (Elit);
5113 end loop;
5114
5115 -- Now set proper size information
5116
5117 declare
5118 Minsize : Uint := UI_From_Int (Minimum_Size (Enumtype));
5119
5120 begin
5121 if Has_Size_Clause (Enumtype) then
e30c7d84 5122
5123 -- All OK, if size is OK now
5124
5125 if RM_Size (Enumtype) >= Minsize then
d6f39728 5126 null;
5127
5128 else
e30c7d84 5129 -- Try if we can get by with biasing
5130
d6f39728 5131 Minsize :=
5132 UI_From_Int (Minimum_Size (Enumtype, Biased => True));
5133
e30c7d84 5134 -- Error message if even biasing does not work
5135
5136 if RM_Size (Enumtype) < Minsize then
5137 Error_Msg_Uint_1 := RM_Size (Enumtype);
5138 Error_Msg_Uint_2 := Max;
5139 Error_Msg_N
5140 ("previously given size (^) is too small "
5141 & "for this value (^)", Max_Node);
5142
5143 -- If biasing worked, indicate that we now have biased rep
d6f39728 5144
5145 else
b77e4501 5146 Set_Biased
5147 (Enumtype, Size_Clause (Enumtype), "size clause");
d6f39728 5148 end if;
5149 end if;
5150
5151 else
5152 Set_RM_Size (Enumtype, Minsize);
5153 Set_Enum_Esize (Enumtype);
5154 end if;
5155
5156 Set_RM_Size (Base_Type (Enumtype), RM_Size (Enumtype));
5157 Set_Esize (Base_Type (Enumtype), Esize (Enumtype));
5158 Set_Alignment (Base_Type (Enumtype), Alignment (Enumtype));
5159 end;
5160 end if;
5161
5162 -- We repeat the too late test in case it froze itself!
5163
5164 if Rep_Item_Too_Late (Enumtype, N) then
5165 null;
5166 end if;
d6f39728 5167 end Analyze_Enumeration_Representation_Clause;
5168
5169 ----------------------------
5170 -- Analyze_Free_Statement --
5171 ----------------------------
5172
5173 procedure Analyze_Free_Statement (N : Node_Id) is
5174 begin
5175 Analyze (Expression (N));
5176 end Analyze_Free_Statement;
5177
40ca69b9 5178 ---------------------------
5179 -- Analyze_Freeze_Entity --
5180 ---------------------------
5181
5182 procedure Analyze_Freeze_Entity (N : Node_Id) is
40ca69b9 5183 begin
d9f6a4ee 5184 Freeze_Entity_Checks (N);
5185 end Analyze_Freeze_Entity;
98f7db28 5186
d9f6a4ee 5187 -----------------------------------
5188 -- Analyze_Freeze_Generic_Entity --
5189 -----------------------------------
98f7db28 5190
d9f6a4ee 5191 procedure Analyze_Freeze_Generic_Entity (N : Node_Id) is
5192 begin
5193 Freeze_Entity_Checks (N);
5194 end Analyze_Freeze_Generic_Entity;
40ca69b9 5195
d9f6a4ee 5196 ------------------------------------------
5197 -- Analyze_Record_Representation_Clause --
5198 ------------------------------------------
c8da6114 5199
d9f6a4ee 5200 -- Note: we check as much as we can here, but we can't do any checks
5201 -- based on the position values (e.g. overlap checks) until freeze time
5202 -- because especially in Ada 2005 (machine scalar mode), the processing
5203 -- for non-standard bit order can substantially change the positions.
5204 -- See procedure Check_Record_Representation_Clause (called from Freeze)
5205 -- for the remainder of this processing.
d00681a7 5206
d9f6a4ee 5207 procedure Analyze_Record_Representation_Clause (N : Node_Id) is
5208 Ident : constant Node_Id := Identifier (N);
5209 Biased : Boolean;
5210 CC : Node_Id;
5211 Comp : Entity_Id;
5212 Fbit : Uint;
5213 Hbit : Uint := Uint_0;
5214 Lbit : Uint;
5215 Ocomp : Entity_Id;
5216 Posit : Uint;
5217 Rectype : Entity_Id;
5218 Recdef : Node_Id;
d00681a7 5219
d9f6a4ee 5220 function Is_Inherited (Comp : Entity_Id) return Boolean;
5221 -- True if Comp is an inherited component in a record extension
d00681a7 5222
d9f6a4ee 5223 ------------------
5224 -- Is_Inherited --
5225 ------------------
d00681a7 5226
d9f6a4ee 5227 function Is_Inherited (Comp : Entity_Id) return Boolean is
5228 Comp_Base : Entity_Id;
d00681a7 5229
d9f6a4ee 5230 begin
5231 if Ekind (Rectype) = E_Record_Subtype then
5232 Comp_Base := Original_Record_Component (Comp);
5233 else
5234 Comp_Base := Comp;
d00681a7 5235 end if;
5236
d9f6a4ee 5237 return Comp_Base /= Original_Record_Component (Comp_Base);
5238 end Is_Inherited;
d00681a7 5239
d9f6a4ee 5240 -- Local variables
d00681a7 5241
d9f6a4ee 5242 Is_Record_Extension : Boolean;
5243 -- True if Rectype is a record extension
d00681a7 5244
d9f6a4ee 5245 CR_Pragma : Node_Id := Empty;
5246 -- Points to N_Pragma node if Complete_Representation pragma present
d00681a7 5247
d9f6a4ee 5248 -- Start of processing for Analyze_Record_Representation_Clause
d00681a7 5249
d9f6a4ee 5250 begin
5251 if Ignore_Rep_Clauses then
5252 return;
d00681a7 5253 end if;
98f7db28 5254
d9f6a4ee 5255 Find_Type (Ident);
5256 Rectype := Entity (Ident);
85377c9b 5257
d9f6a4ee 5258 if Rectype = Any_Type or else Rep_Item_Too_Early (Rectype, N) then
5259 return;
5260 else
5261 Rectype := Underlying_Type (Rectype);
5262 end if;
85377c9b 5263
d9f6a4ee 5264 -- First some basic error checks
85377c9b 5265
d9f6a4ee 5266 if not Is_Record_Type (Rectype) then
5267 Error_Msg_NE
5268 ("record type required, found}", Ident, First_Subtype (Rectype));
5269 return;
85377c9b 5270
d9f6a4ee 5271 elsif Scope (Rectype) /= Current_Scope then
5272 Error_Msg_N ("type must be declared in this scope", N);
5273 return;
85377c9b 5274
d9f6a4ee 5275 elsif not Is_First_Subtype (Rectype) then
5276 Error_Msg_N ("cannot give record rep clause for subtype", N);
5277 return;
9dc88aea 5278
d9f6a4ee 5279 elsif Has_Record_Rep_Clause (Rectype) then
5280 Error_Msg_N ("duplicate record rep clause ignored", N);
5281 return;
9dc88aea 5282
d9f6a4ee 5283 elsif Rep_Item_Too_Late (Rectype, N) then
5284 return;
9dc88aea 5285 end if;
fb7f2fc4 5286
d9f6a4ee 5287 -- We know we have a first subtype, now possibly go the the anonymous
5288 -- base type to determine whether Rectype is a record extension.
89f1e35c 5289
d9f6a4ee 5290 Recdef := Type_Definition (Declaration_Node (Base_Type (Rectype)));
5291 Is_Record_Extension :=
5292 Nkind (Recdef) = N_Derived_Type_Definition
5293 and then Present (Record_Extension_Part (Recdef));
89f1e35c 5294
d9f6a4ee 5295 if Present (Mod_Clause (N)) then
fb7f2fc4 5296 declare
d9f6a4ee 5297 Loc : constant Source_Ptr := Sloc (N);
5298 M : constant Node_Id := Mod_Clause (N);
5299 P : constant List_Id := Pragmas_Before (M);
5300 AtM_Nod : Node_Id;
5301
5302 Mod_Val : Uint;
5303 pragma Warnings (Off, Mod_Val);
fb7f2fc4 5304
5305 begin
d9f6a4ee 5306 Check_Restriction (No_Obsolescent_Features, Mod_Clause (N));
fb7f2fc4 5307
d9f6a4ee 5308 if Warn_On_Obsolescent_Feature then
5309 Error_Msg_N
5310 ("?j?mod clause is an obsolescent feature (RM J.8)", N);
5311 Error_Msg_N
5312 ("\?j?use alignment attribute definition clause instead", N);
5313 end if;
fb7f2fc4 5314
d9f6a4ee 5315 if Present (P) then
5316 Analyze_List (P);
5317 end if;
89f1e35c 5318
d9f6a4ee 5319 -- In ASIS_Mode mode, expansion is disabled, but we must convert
5320 -- the Mod clause into an alignment clause anyway, so that the
5321 -- back-end can compute and back-annotate properly the size and
5322 -- alignment of types that may include this record.
be9124d0 5323
d9f6a4ee 5324 -- This seems dubious, this destroys the source tree in a manner
5325 -- not detectable by ASIS ???
be9124d0 5326
d9f6a4ee 5327 if Operating_Mode = Check_Semantics and then ASIS_Mode then
5328 AtM_Nod :=
5329 Make_Attribute_Definition_Clause (Loc,
5330 Name => New_Reference_To (Base_Type (Rectype), Loc),
5331 Chars => Name_Alignment,
5332 Expression => Relocate_Node (Expression (M)));
be9124d0 5333
d9f6a4ee 5334 Set_From_At_Mod (AtM_Nod);
5335 Insert_After (N, AtM_Nod);
5336 Mod_Val := Get_Alignment_Value (Expression (AtM_Nod));
5337 Set_Mod_Clause (N, Empty);
be9124d0 5338
d9f6a4ee 5339 else
5340 -- Get the alignment value to perform error checking
be9124d0 5341
d9f6a4ee 5342 Mod_Val := Get_Alignment_Value (Expression (M));
5343 end if;
5344 end;
5345 end if;
be9124d0 5346
d9f6a4ee 5347 -- For untagged types, clear any existing component clauses for the
5348 -- type. If the type is derived, this is what allows us to override
5349 -- a rep clause for the parent. For type extensions, the representation
5350 -- of the inherited components is inherited, so we want to keep previous
5351 -- component clauses for completeness.
be9124d0 5352
d9f6a4ee 5353 if not Is_Tagged_Type (Rectype) then
5354 Comp := First_Component_Or_Discriminant (Rectype);
5355 while Present (Comp) loop
5356 Set_Component_Clause (Comp, Empty);
5357 Next_Component_Or_Discriminant (Comp);
5358 end loop;
5359 end if;
be9124d0 5360
d9f6a4ee 5361 -- All done if no component clauses
be9124d0 5362
d9f6a4ee 5363 CC := First (Component_Clauses (N));
be9124d0 5364
d9f6a4ee 5365 if No (CC) then
5366 return;
5367 end if;
be9124d0 5368
d9f6a4ee 5369 -- A representation like this applies to the base type
be9124d0 5370
d9f6a4ee 5371 Set_Has_Record_Rep_Clause (Base_Type (Rectype));
5372 Set_Has_Non_Standard_Rep (Base_Type (Rectype));
5373 Set_Has_Specified_Layout (Base_Type (Rectype));
be9124d0 5374
d9f6a4ee 5375 -- Process the component clauses
be9124d0 5376
d9f6a4ee 5377 while Present (CC) loop
be9124d0 5378
d9f6a4ee 5379 -- Pragma
be9124d0 5380
d9f6a4ee 5381 if Nkind (CC) = N_Pragma then
5382 Analyze (CC);
be9124d0 5383
d9f6a4ee 5384 -- The only pragma of interest is Complete_Representation
be9124d0 5385
d9f6a4ee 5386 if Pragma_Name (CC) = Name_Complete_Representation then
5387 CR_Pragma := CC;
5388 end if;
be9124d0 5389
d9f6a4ee 5390 -- Processing for real component clause
be9124d0 5391
d9f6a4ee 5392 else
5393 Posit := Static_Integer (Position (CC));
5394 Fbit := Static_Integer (First_Bit (CC));
5395 Lbit := Static_Integer (Last_Bit (CC));
be9124d0 5396
d9f6a4ee 5397 if Posit /= No_Uint
5398 and then Fbit /= No_Uint
5399 and then Lbit /= No_Uint
5400 then
5401 if Posit < 0 then
5402 Error_Msg_N
5403 ("position cannot be negative", Position (CC));
be9124d0 5404
d9f6a4ee 5405 elsif Fbit < 0 then
5406 Error_Msg_N
5407 ("first bit cannot be negative", First_Bit (CC));
be9124d0 5408
d9f6a4ee 5409 -- The Last_Bit specified in a component clause must not be
5410 -- less than the First_Bit minus one (RM-13.5.1(10)).
be9124d0 5411
d9f6a4ee 5412 elsif Lbit < Fbit - 1 then
5413 Error_Msg_N
5414 ("last bit cannot be less than first bit minus one",
5415 Last_Bit (CC));
be9124d0 5416
d9f6a4ee 5417 -- Values look OK, so find the corresponding record component
5418 -- Even though the syntax allows an attribute reference for
5419 -- implementation-defined components, GNAT does not allow the
5420 -- tag to get an explicit position.
be9124d0 5421
d9f6a4ee 5422 elsif Nkind (Component_Name (CC)) = N_Attribute_Reference then
5423 if Attribute_Name (Component_Name (CC)) = Name_Tag then
5424 Error_Msg_N ("position of tag cannot be specified", CC);
5425 else
5426 Error_Msg_N ("illegal component name", CC);
5427 end if;
be9124d0 5428
d9f6a4ee 5429 else
5430 Comp := First_Entity (Rectype);
5431 while Present (Comp) loop
5432 exit when Chars (Comp) = Chars (Component_Name (CC));
5433 Next_Entity (Comp);
5434 end loop;
be9124d0 5435
d9f6a4ee 5436 if No (Comp) then
be9124d0 5437
d9f6a4ee 5438 -- Maybe component of base type that is absent from
5439 -- statically constrained first subtype.
be9124d0 5440
d9f6a4ee 5441 Comp := First_Entity (Base_Type (Rectype));
5442 while Present (Comp) loop
5443 exit when Chars (Comp) = Chars (Component_Name (CC));
5444 Next_Entity (Comp);
5445 end loop;
5446 end if;
be9124d0 5447
d9f6a4ee 5448 if No (Comp) then
5449 Error_Msg_N
5450 ("component clause is for non-existent field", CC);
be9124d0 5451
d9f6a4ee 5452 -- Ada 2012 (AI05-0026): Any name that denotes a
5453 -- discriminant of an object of an unchecked union type
5454 -- shall not occur within a record_representation_clause.
be9124d0 5455
d9f6a4ee 5456 -- The general restriction of using record rep clauses on
5457 -- Unchecked_Union types has now been lifted. Since it is
5458 -- possible to introduce a record rep clause which mentions
5459 -- the discriminant of an Unchecked_Union in non-Ada 2012
5460 -- code, this check is applied to all versions of the
5461 -- language.
be9124d0 5462
d9f6a4ee 5463 elsif Ekind (Comp) = E_Discriminant
5464 and then Is_Unchecked_Union (Rectype)
5465 then
5466 Error_Msg_N
5467 ("cannot reference discriminant of unchecked union",
5468 Component_Name (CC));
be9124d0 5469
d9f6a4ee 5470 elsif Is_Record_Extension and then Is_Inherited (Comp) then
5471 Error_Msg_NE
5472 ("component clause not allowed for inherited "
5473 & "component&", CC, Comp);
40ca69b9 5474
d9f6a4ee 5475 elsif Present (Component_Clause (Comp)) then
462a079f 5476
d9f6a4ee 5477 -- Diagnose duplicate rep clause, or check consistency
5478 -- if this is an inherited component. In a double fault,
5479 -- there may be a duplicate inconsistent clause for an
5480 -- inherited component.
462a079f 5481
d9f6a4ee 5482 if Scope (Original_Record_Component (Comp)) = Rectype
5483 or else Parent (Component_Clause (Comp)) = N
5484 then
5485 Error_Msg_Sloc := Sloc (Component_Clause (Comp));
5486 Error_Msg_N ("component clause previously given#", CC);
3062c401 5487
5488 else
5489 declare
5490 Rep1 : constant Node_Id := Component_Clause (Comp);
3062c401 5491 begin
5492 if Intval (Position (Rep1)) /=
5493 Intval (Position (CC))
5494 or else Intval (First_Bit (Rep1)) /=
5495 Intval (First_Bit (CC))
5496 or else Intval (Last_Bit (Rep1)) /=
5497 Intval (Last_Bit (CC))
5498 then
b9e61b2a 5499 Error_Msg_N
5500 ("component clause inconsistent "
5501 & "with representation of ancestor", CC);
6a06584c 5502
3062c401 5503 elsif Warn_On_Redundant_Constructs then
b9e61b2a 5504 Error_Msg_N
6a06584c 5505 ("?r?redundant confirming component clause "
5506 & "for component!", CC);
3062c401 5507 end if;
5508 end;
5509 end if;
d6f39728 5510
d2b860b4 5511 -- Normal case where this is the first component clause we
5512 -- have seen for this entity, so set it up properly.
5513
d6f39728 5514 else
83f8f0a6 5515 -- Make reference for field in record rep clause and set
5516 -- appropriate entity field in the field identifier.
5517
5518 Generate_Reference
5519 (Comp, Component_Name (CC), Set_Ref => False);
5520 Set_Entity (Component_Name (CC), Comp);
5521
2866d595 5522 -- Update Fbit and Lbit to the actual bit number
d6f39728 5523
5524 Fbit := Fbit + UI_From_Int (SSU) * Posit;
5525 Lbit := Lbit + UI_From_Int (SSU) * Posit;
5526
d6f39728 5527 if Has_Size_Clause (Rectype)
ada34def 5528 and then RM_Size (Rectype) <= Lbit
d6f39728 5529 then
5530 Error_Msg_N
5531 ("bit number out of range of specified size",
5532 Last_Bit (CC));
5533 else
5534 Set_Component_Clause (Comp, CC);
5535 Set_Component_Bit_Offset (Comp, Fbit);
5536 Set_Esize (Comp, 1 + (Lbit - Fbit));
5537 Set_Normalized_First_Bit (Comp, Fbit mod SSU);
5538 Set_Normalized_Position (Comp, Fbit / SSU);
5539
a0fc8c5b 5540 if Warn_On_Overridden_Size
5541 and then Has_Size_Clause (Etype (Comp))
5542 and then RM_Size (Etype (Comp)) /= Esize (Comp)
5543 then
5544 Error_Msg_NE
1e3532e7 5545 ("?S?component size overrides size clause for&",
a0fc8c5b 5546 Component_Name (CC), Etype (Comp));
5547 end if;
5548
ea61a7ea 5549 -- This information is also set in the corresponding
5550 -- component of the base type, found by accessing the
5551 -- Original_Record_Component link if it is present.
d6f39728 5552
5553 Ocomp := Original_Record_Component (Comp);
5554
5555 if Hbit < Lbit then
5556 Hbit := Lbit;
5557 end if;
5558
5559 Check_Size
5560 (Component_Name (CC),
5561 Etype (Comp),
5562 Esize (Comp),
5563 Biased);
5564
b77e4501 5565 Set_Biased
5566 (Comp, First_Node (CC), "component clause", Biased);
cc46ff4b 5567
d6f39728 5568 if Present (Ocomp) then
5569 Set_Component_Clause (Ocomp, CC);
5570 Set_Component_Bit_Offset (Ocomp, Fbit);
5571 Set_Normalized_First_Bit (Ocomp, Fbit mod SSU);
5572 Set_Normalized_Position (Ocomp, Fbit / SSU);
5573 Set_Esize (Ocomp, 1 + (Lbit - Fbit));
5574
5575 Set_Normalized_Position_Max
5576 (Ocomp, Normalized_Position (Ocomp));
5577
b77e4501 5578 -- Note: we don't use Set_Biased here, because we
5579 -- already gave a warning above if needed, and we
5580 -- would get a duplicate for the same name here.
5581
d6f39728 5582 Set_Has_Biased_Representation
5583 (Ocomp, Has_Biased_Representation (Comp));
5584 end if;
5585
5586 if Esize (Comp) < 0 then
5587 Error_Msg_N ("component size is negative", CC);
5588 end if;
5589 end if;
5590 end if;
5591 end if;
5592 end if;
5593 end if;
5594
5595 Next (CC);
5596 end loop;
5597
67278d60 5598 -- Check missing components if Complete_Representation pragma appeared
d6f39728 5599
67278d60 5600 if Present (CR_Pragma) then
5601 Comp := First_Component_Or_Discriminant (Rectype);
5602 while Present (Comp) loop
5603 if No (Component_Clause (Comp)) then
5604 Error_Msg_NE
5605 ("missing component clause for &", CR_Pragma, Comp);
5606 end if;
d6f39728 5607
67278d60 5608 Next_Component_Or_Discriminant (Comp);
5609 end loop;
d6f39728 5610
1e3532e7 5611 -- Give missing components warning if required
15ebb600 5612
fdd294d1 5613 elsif Warn_On_Unrepped_Components then
15ebb600 5614 declare
5615 Num_Repped_Components : Nat := 0;
5616 Num_Unrepped_Components : Nat := 0;
5617
5618 begin
5619 -- First count number of repped and unrepped components
5620
5621 Comp := First_Component_Or_Discriminant (Rectype);
5622 while Present (Comp) loop
5623 if Present (Component_Clause (Comp)) then
5624 Num_Repped_Components := Num_Repped_Components + 1;
5625 else
5626 Num_Unrepped_Components := Num_Unrepped_Components + 1;
5627 end if;
5628
5629 Next_Component_Or_Discriminant (Comp);
5630 end loop;
5631
5632 -- We are only interested in the case where there is at least one
5633 -- unrepped component, and at least half the components have rep
5634 -- clauses. We figure that if less than half have them, then the
87f9eef5 5635 -- partial rep clause is really intentional. If the component
5636 -- type has no underlying type set at this point (as for a generic
5637 -- formal type), we don't know enough to give a warning on the
5638 -- component.
15ebb600 5639
5640 if Num_Unrepped_Components > 0
5641 and then Num_Unrepped_Components < Num_Repped_Components
5642 then
5643 Comp := First_Component_Or_Discriminant (Rectype);
5644 while Present (Comp) loop
83f8f0a6 5645 if No (Component_Clause (Comp))
3062c401 5646 and then Comes_From_Source (Comp)
87f9eef5 5647 and then Present (Underlying_Type (Etype (Comp)))
83f8f0a6 5648 and then (Is_Scalar_Type (Underlying_Type (Etype (Comp)))
67278d60 5649 or else Size_Known_At_Compile_Time
5650 (Underlying_Type (Etype (Comp))))
fdd294d1 5651 and then not Has_Warnings_Off (Rectype)
83f8f0a6 5652 then
15ebb600 5653 Error_Msg_Sloc := Sloc (Comp);
5654 Error_Msg_NE
1e3532e7 5655 ("?C?no component clause given for & declared #",
15ebb600 5656 N, Comp);
5657 end if;
5658
5659 Next_Component_Or_Discriminant (Comp);
5660 end loop;
5661 end if;
5662 end;
d6f39728 5663 end if;
d6f39728 5664 end Analyze_Record_Representation_Clause;
5665
9ea61fdd 5666 -------------------------------------------
5667 -- Build_Invariant_Procedure_Declaration --
5668 -------------------------------------------
5669
5670 function Build_Invariant_Procedure_Declaration
5671 (Typ : Entity_Id) return Node_Id
5672 is
5673 Loc : constant Source_Ptr := Sloc (Typ);
5674 Object_Entity : constant Entity_Id :=
5675 Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
5676 Spec : Node_Id;
5677 SId : Entity_Id;
5678
5679 begin
5680 Set_Etype (Object_Entity, Typ);
5681
5682 -- Check for duplicate definiations.
5683
1e3532e7 5684 if Has_Invariants (Typ) and then Present (Invariant_Procedure (Typ)) then
9ea61fdd 5685 return Empty;
5686 end if;
5687
4bba0a8d 5688 SId :=
5689 Make_Defining_Identifier (Loc,
5690 Chars => New_External_Name (Chars (Typ), "Invariant"));
9ea61fdd 5691 Set_Has_Invariants (Typ);
5692 Set_Ekind (SId, E_Procedure);
84c8f0b8 5693 Set_Is_Invariant_Procedure (SId);
9ea61fdd 5694 Set_Invariant_Procedure (Typ, SId);
5695
5696 Spec :=
5697 Make_Procedure_Specification (Loc,
5698 Defining_Unit_Name => SId,
5699 Parameter_Specifications => New_List (
5700 Make_Parameter_Specification (Loc,
5701 Defining_Identifier => Object_Entity,
5702 Parameter_Type => New_Occurrence_Of (Typ, Loc))));
5703
5704 return Make_Subprogram_Declaration (Loc, Specification => Spec);
5705 end Build_Invariant_Procedure_Declaration;
5706
5b5df4a9 5707 -------------------------------
5708 -- Build_Invariant_Procedure --
5709 -------------------------------
5710
5711 -- The procedure that is constructed here has the form
5712
5713 -- procedure typInvariant (Ixxx : typ) is
5714 -- begin
5715 -- pragma Check (Invariant, exp, "failed invariant from xxx");
5716 -- pragma Check (Invariant, exp, "failed invariant from xxx");
5717 -- ...
5718 -- pragma Check (Invariant, exp, "failed inherited invariant from xxx");
5719 -- ...
5720 -- end typInvariant;
5721
87f3d5d3 5722 procedure Build_Invariant_Procedure (Typ : Entity_Id; N : Node_Id) is
5b5df4a9 5723 Loc : constant Source_Ptr := Sloc (Typ);
5724 Stmts : List_Id;
5725 Spec : Node_Id;
5726 SId : Entity_Id;
87f3d5d3 5727 PDecl : Node_Id;
5728 PBody : Node_Id;
5729
5730 Visible_Decls : constant List_Id := Visible_Declarations (N);
5731 Private_Decls : constant List_Id := Private_Declarations (N);
5b5df4a9 5732
5733 procedure Add_Invariants (T : Entity_Id; Inherit : Boolean);
5734 -- Appends statements to Stmts for any invariants in the rep item chain
5735 -- of the given type. If Inherit is False, then we only process entries
5736 -- on the chain for the type Typ. If Inherit is True, then we ignore any
5737 -- Invariant aspects, but we process all Invariant'Class aspects, adding
5738 -- "inherited" to the exception message and generating an informational
5739 -- message about the inheritance of an invariant.
5740
9ea61fdd 5741 Object_Name : Name_Id;
5b5df4a9 5742 -- Name for argument of invariant procedure
5743
9ea61fdd 5744 Object_Entity : Node_Id;
5745 -- The entity of the formal for the procedure
87f3d5d3 5746
5b5df4a9 5747 --------------------
5748 -- Add_Invariants --
5749 --------------------
5750
5751 procedure Add_Invariants (T : Entity_Id; Inherit : Boolean) is
5752 Ritem : Node_Id;
5753 Arg1 : Node_Id;
5754 Arg2 : Node_Id;
5755 Arg3 : Node_Id;
5756 Exp : Node_Id;
5757 Loc : Source_Ptr;
5758 Assoc : List_Id;
5759 Str : String_Id;
5760
2072eaa9 5761 procedure Replace_Type_Reference (N : Node_Id);
5762 -- Replace a single occurrence N of the subtype name with a reference
5763 -- to the formal of the predicate function. N can be an identifier
5764 -- referencing the subtype, or a selected component, representing an
5765 -- appropriately qualified occurrence of the subtype name.
5b5df4a9 5766
2072eaa9 5767 procedure Replace_Type_References is
5768 new Replace_Type_References_Generic (Replace_Type_Reference);
5769 -- Traverse an expression replacing all occurrences of the subtype
5770 -- name with appropriate references to the object that is the formal
87f3d5d3 5771 -- parameter of the predicate function. Note that we must ensure
5772 -- that the type and entity information is properly set in the
5773 -- replacement node, since we will do a Preanalyze call of this
5774 -- expression without proper visibility of the procedure argument.
5b5df4a9 5775
2072eaa9 5776 ----------------------------
5777 -- Replace_Type_Reference --
5778 ----------------------------
5b5df4a9 5779
b9e61b2a 5780 -- Note: See comments in Add_Predicates.Replace_Type_Reference
5781 -- regarding handling of Sloc and Comes_From_Source.
5782
2072eaa9 5783 procedure Replace_Type_Reference (N : Node_Id) is
5b5df4a9 5784 begin
2072eaa9 5785 -- Invariant'Class, replace with T'Class (obj)
5786
5787 if Class_Present (Ritem) then
5788 Rewrite (N,
c92e878b 5789 Make_Type_Conversion (Sloc (N),
2072eaa9 5790 Subtype_Mark =>
c92e878b 5791 Make_Attribute_Reference (Sloc (N),
5792 Prefix => New_Occurrence_Of (T, Sloc (N)),
2072eaa9 5793 Attribute_Name => Name_Class),
c92e878b 5794 Expression => Make_Identifier (Sloc (N), Object_Name)));
5b5df4a9 5795
87f3d5d3 5796 Set_Entity (Expression (N), Object_Entity);
5797 Set_Etype (Expression (N), Typ);
5798
2072eaa9 5799 -- Invariant, replace with obj
5b5df4a9 5800
5801 else
c92e878b 5802 Rewrite (N, Make_Identifier (Sloc (N), Object_Name));
87f3d5d3 5803 Set_Entity (N, Object_Entity);
5804 Set_Etype (N, Typ);
5b5df4a9 5805 end if;
4c1fd062 5806
5807 Set_Comes_From_Source (N, True);
2072eaa9 5808 end Replace_Type_Reference;
5b5df4a9 5809
5810 -- Start of processing for Add_Invariants
5811
5812 begin
5813 Ritem := First_Rep_Item (T);
5814 while Present (Ritem) loop
5815 if Nkind (Ritem) = N_Pragma
5816 and then Pragma_Name (Ritem) = Name_Invariant
5817 then
5818 Arg1 := First (Pragma_Argument_Associations (Ritem));
5819 Arg2 := Next (Arg1);
5820 Arg3 := Next (Arg2);
5821
5822 Arg1 := Get_Pragma_Arg (Arg1);
5823 Arg2 := Get_Pragma_Arg (Arg2);
5824
5825 -- For Inherit case, ignore Invariant, process only Class case
5826
5827 if Inherit then
5828 if not Class_Present (Ritem) then
5829 goto Continue;
5830 end if;
5831
5832 -- For Inherit false, process only item for right type
5833
5834 else
5835 if Entity (Arg1) /= Typ then
5836 goto Continue;
5837 end if;
5838 end if;
5839
5840 if No (Stmts) then
5841 Stmts := Empty_List;
5842 end if;
5843
5844 Exp := New_Copy_Tree (Arg2);
47a46747 5845
88254da4 5846 -- Preserve sloc of original pragma Invariant
47a46747 5847
5848 Loc := Sloc (Ritem);
5b5df4a9 5849
5850 -- We need to replace any occurrences of the name of the type
5851 -- with references to the object, converted to type'Class in
2072eaa9 5852 -- the case of Invariant'Class aspects.
5b5df4a9 5853
2072eaa9 5854 Replace_Type_References (Exp, Chars (T));
5b5df4a9 5855
fb7f2fc4 5856 -- If this invariant comes from an aspect, find the aspect
5857 -- specification, and replace the saved expression because
5858 -- we need the subtype references replaced for the calls to
5859 -- Preanalyze_Spec_Expressin in Check_Aspect_At_Freeze_Point
5860 -- and Check_Aspect_At_End_Of_Declarations.
5861
5862 if From_Aspect_Specification (Ritem) then
5863 declare
5864 Aitem : Node_Id;
5865
5866 begin
5867 -- Loop to find corresponding aspect, note that this
5868 -- must be present given the pragma is marked delayed.
5869
5870 Aitem := Next_Rep_Item (Ritem);
5871 while Present (Aitem) loop
5872 if Nkind (Aitem) = N_Aspect_Specification
5873 and then Aspect_Rep_Item (Aitem) = Ritem
5874 then
5875 Set_Entity
5876 (Identifier (Aitem), New_Copy_Tree (Exp));
5877 exit;
5878 end if;
5879
5880 Aitem := Next_Rep_Item (Aitem);
5881 end loop;
5882 end;
5883 end if;
5884
87f3d5d3 5885 -- Now we need to preanalyze the expression to properly capture
5886 -- the visibility in the visible part. The expression will not
5887 -- be analyzed for real until the body is analyzed, but that is
5888 -- at the end of the private part and has the wrong visibility.
5889
5890 Set_Parent (Exp, N);
d513339a 5891 Preanalyze_Assert_Expression (Exp, Standard_Boolean);
87f3d5d3 5892
5b5df4a9 5893 -- Build first two arguments for Check pragma
5894
5895 Assoc := New_List (
5896 Make_Pragma_Argument_Association (Loc,
55868293 5897 Expression => Make_Identifier (Loc, Name_Invariant)),
b9e61b2a 5898 Make_Pragma_Argument_Association (Loc,
5899 Expression => Exp));
5b5df4a9 5900
5901 -- Add message if present in Invariant pragma
5902
5903 if Present (Arg3) then
5904 Str := Strval (Get_Pragma_Arg (Arg3));
5905
5906 -- If inherited case, and message starts "failed invariant",
5907 -- change it to be "failed inherited invariant".
5908
5909 if Inherit then
5910 String_To_Name_Buffer (Str);
5911
5912 if Name_Buffer (1 .. 16) = "failed invariant" then
5913 Insert_Str_In_Name_Buffer ("inherited ", 8);
5914 Str := String_From_Name_Buffer;
5915 end if;
5916 end if;
5917
5918 Append_To (Assoc,
5919 Make_Pragma_Argument_Association (Loc,
5920 Expression => Make_String_Literal (Loc, Str)));
5921 end if;
5922
5923 -- Add Check pragma to list of statements
5924
5925 Append_To (Stmts,
5926 Make_Pragma (Loc,
5927 Pragma_Identifier =>
55868293 5928 Make_Identifier (Loc, Name_Check),
5b5df4a9 5929 Pragma_Argument_Associations => Assoc));
5930
5931 -- If Inherited case and option enabled, output info msg. Note
5932 -- that we know this is a case of Invariant'Class.
5933
5934 if Inherit and Opt.List_Inherited_Aspects then
5935 Error_Msg_Sloc := Sloc (Ritem);
5936 Error_Msg_N
cb97ae5c 5937 ("?L?info: & inherits `Invariant''Class` aspect from #",
5b5df4a9 5938 Typ);
5939 end if;
5940 end if;
5941
5942 <<Continue>>
5943 Next_Rep_Item (Ritem);
5944 end loop;
5945 end Add_Invariants;
5946
5947 -- Start of processing for Build_Invariant_Procedure
5948
5949 begin
5950 Stmts := No_List;
5951 PDecl := Empty;
5952 PBody := Empty;
9ea61fdd 5953 SId := Empty;
5954
5955 -- If the aspect specification exists for some view of the type, the
5956 -- declaration for the procedure has been created.
5957
5958 if Has_Invariants (Typ) then
5959 SId := Invariant_Procedure (Typ);
5960 end if;
5961
5962 if Present (SId) then
5963 PDecl := Unit_Declaration_Node (SId);
9ea61fdd 5964 else
5965 PDecl := Build_Invariant_Procedure_Declaration (Typ);
5966 end if;
5967
5968 -- Recover formal of procedure, for use in the calls to invariant
5969 -- functions (including inherited ones).
5970
5971 Object_Entity :=
5972 Defining_Identifier
5973 (First (Parameter_Specifications (Specification (PDecl))));
5974 Object_Name := Chars (Object_Entity);
5b5df4a9 5975
5976 -- Add invariants for the current type
5977
5978 Add_Invariants (Typ, Inherit => False);
5979
5980 -- Add invariants for parent types
5981
5982 declare
5983 Current_Typ : Entity_Id;
5984 Parent_Typ : Entity_Id;
5985
5986 begin
5987 Current_Typ := Typ;
5988 loop
5989 Parent_Typ := Etype (Current_Typ);
5990
5991 if Is_Private_Type (Parent_Typ)
5992 and then Present (Full_View (Base_Type (Parent_Typ)))
5993 then
5994 Parent_Typ := Full_View (Base_Type (Parent_Typ));
5995 end if;
5996
5997 exit when Parent_Typ = Current_Typ;
5998
5999 Current_Typ := Parent_Typ;
6000 Add_Invariants (Current_Typ, Inherit => True);
6001 end loop;
6002 end;
6003
5b5df4a9 6004 -- Build the procedure if we generated at least one Check pragma
6005
6006 if Stmts /= No_List then
9ea61fdd 6007 Spec := Copy_Separate_Tree (Specification (PDecl));
5b5df4a9 6008
6009 PBody :=
6010 Make_Subprogram_Body (Loc,
6011 Specification => Spec,
6012 Declarations => Empty_List,
6013 Handled_Statement_Sequence =>
6014 Make_Handled_Sequence_Of_Statements (Loc,
6015 Statements => Stmts));
87f3d5d3 6016
6017 -- Insert procedure declaration and spec at the appropriate points.
9ea61fdd 6018 -- If declaration is already analyzed, it was processed by the
6019 -- generated pragma.
87f3d5d3 6020
6021 if Present (Private_Decls) then
6022
6023 -- The spec goes at the end of visible declarations, but they have
6024 -- already been analyzed, so we need to explicitly do the analyze.
6025
9ea61fdd 6026 if not Analyzed (PDecl) then
6027 Append_To (Visible_Decls, PDecl);
6028 Analyze (PDecl);
6029 end if;
87f3d5d3 6030
6031 -- The body goes at the end of the private declarations, which we
6032 -- have not analyzed yet, so we do not need to perform an explicit
6033 -- analyze call. We skip this if there are no private declarations
6034 -- (this is an error that will be caught elsewhere);
6035
6036 Append_To (Private_Decls, PBody);
192b8dab 6037
6038 -- If the invariant appears on the full view of a type, the
6039 -- analysis of the private part is complete, and we must
6040 -- analyze the new body explicitly.
6041
6042 if In_Private_Part (Current_Scope) then
6043 Analyze (PBody);
6044 end if;
5d3fb947 6045
6046 -- If there are no private declarations this may be an error that
6047 -- will be diagnosed elsewhere. However, if this is a non-private
6048 -- type that inherits invariants, it needs no completion and there
6049 -- may be no private part. In this case insert invariant procedure
6050 -- at end of current declarative list, and analyze at once, given
6051 -- that the type is about to be frozen.
6052
6053 elsif not Is_Private_Type (Typ) then
6054 Append_To (Visible_Decls, PDecl);
6055 Append_To (Visible_Decls, PBody);
6056 Analyze (PDecl);
6057 Analyze (PBody);
87f3d5d3 6058 end if;
5b5df4a9 6059 end if;
6060 end Build_Invariant_Procedure;
6061
84c8f0b8 6062 -------------------------------
6063 -- Build_Predicate_Functions --
6064 -------------------------------
9dc88aea 6065
9ab32fe9 6066 -- The procedures that are constructed here have the form:
7c443ae8 6067
6068 -- function typPredicate (Ixxx : typ) return Boolean is
6069 -- begin
6070 -- return
6071 -- exp1 and then exp2 and then ...
6072 -- and then typ1Predicate (typ1 (Ixxx))
6073 -- and then typ2Predicate (typ2 (Ixxx))
6074 -- and then ...;
6075 -- end typPredicate;
9dc88aea 6076
6077 -- Here exp1, and exp2 are expressions from Predicate pragmas. Note that
6078 -- this is the point at which these expressions get analyzed, providing the
6079 -- required delay, and typ1, typ2, are entities from which predicates are
6080 -- inherited. Note that we do NOT generate Check pragmas, that's because we
6081 -- use this function even if checks are off, e.g. for membership tests.
6082
84c8f0b8 6083 -- If the expression has at least one Raise_Expression, then we also build
9ab32fe9 6084 -- the typPredicateM version of the function, in which any occurrence of a
6085 -- Raise_Expression is converted to "return False".
84c8f0b8 6086
6087 procedure Build_Predicate_Functions (Typ : Entity_Id; N : Node_Id) is
6088 Loc : constant Source_Ptr := Sloc (Typ);
490beba6 6089
9dc88aea 6090 Expr : Node_Id;
84c8f0b8 6091 -- This is the expression for the result of the function. It is
9dc88aea 6092 -- is build by connecting the component predicates with AND THEN.
6093
84c8f0b8 6094 Expr_M : Node_Id;
6095 -- This is the corresponding return expression for the Predicate_M
6096 -- function. It differs in that raise expressions are marked for
6097 -- special expansion (see Process_REs).
6098
6099 Object_Name : constant Name_Id := New_Internal_Name ('I');
6100 -- Name for argument of Predicate procedure. Note that we use the same
6101 -- name for both predicate procedure. That way the reference within the
6102 -- predicate expression is the same in both functions.
6103
6104 Object_Entity : constant Entity_Id :=
6105 Make_Defining_Identifier (Loc, Chars => Object_Name);
6106 -- Entity for argument of Predicate procedure
6107
6108 Object_Entity_M : constant Entity_Id :=
6109 Make_Defining_Identifier (Loc, Chars => Object_Name);
6110 -- Entity for argument of Predicate_M procedure
6111
6112 Raise_Expression_Present : Boolean := False;
6113 -- Set True if Expr has at least one Raise_Expression
6114
34d045d3 6115 Static_Predic : Node_Id := Empty;
6116 -- Set to N_Pragma node for a static predicate if one is encountered
6117
9dc88aea 6118 procedure Add_Call (T : Entity_Id);
6119 -- Includes a call to the predicate function for type T in Expr if T
6120 -- has predicates and Predicate_Function (T) is non-empty.
6121
6122 procedure Add_Predicates;
6123 -- Appends expressions for any Predicate pragmas in the rep item chain
6124 -- Typ to Expr. Note that we look only at items for this exact entity.
6125 -- Inheritance of predicates for the parent type is done by calling the
6126 -- Predicate_Function of the parent type, using Add_Call above.
6127
84c8f0b8 6128 function Test_RE (N : Node_Id) return Traverse_Result;
6129 -- Used in Test_REs, tests one node for being a raise expression, and if
6130 -- so sets Raise_Expression_Present True.
9dc88aea 6131
84c8f0b8 6132 procedure Test_REs is new Traverse_Proc (Test_RE);
6133 -- Tests to see if Expr contains any raise expressions
6134
6135 function Process_RE (N : Node_Id) return Traverse_Result;
6136 -- Used in Process REs, tests if node N is a raise expression, and if
6137 -- so, marks it to be converted to return False.
6138
6139 procedure Process_REs is new Traverse_Proc (Process_RE);
6140 -- Marks any raise expressions in Expr_M to return False
fb7f2fc4 6141
9dc88aea 6142 --------------
6143 -- Add_Call --
6144 --------------
6145
6146 procedure Add_Call (T : Entity_Id) is
6147 Exp : Node_Id;
6148
6149 begin
6150 if Present (T) and then Present (Predicate_Function (T)) then
6151 Set_Has_Predicates (Typ);
6152
6153 -- Build the call to the predicate function of T
6154
6155 Exp :=
6156 Make_Predicate_Call
55868293 6157 (T, Convert_To (T, Make_Identifier (Loc, Object_Name)));
9dc88aea 6158
6159 -- Add call to evolving expression, using AND THEN if needed
6160
6161 if No (Expr) then
6162 Expr := Exp;
6163 else
6164 Expr :=
6165 Make_And_Then (Loc,
6166 Left_Opnd => Relocate_Node (Expr),
6167 Right_Opnd => Exp);
6168 end if;
6169
2f32076c 6170 -- Output info message on inheritance if required. Note we do not
6171 -- give this information for generic actual types, since it is
55e8372b 6172 -- unwelcome noise in that case in instantiations. We also
490beba6 6173 -- generally suppress the message in instantiations, and also
6174 -- if it involves internal names.
9dc88aea 6175
2f32076c 6176 if Opt.List_Inherited_Aspects
6177 and then not Is_Generic_Actual_Type (Typ)
55e8372b 6178 and then Instantiation_Depth (Sloc (Typ)) = 0
490beba6 6179 and then not Is_Internal_Name (Chars (T))
6180 and then not Is_Internal_Name (Chars (Typ))
2f32076c 6181 then
9dc88aea 6182 Error_Msg_Sloc := Sloc (Predicate_Function (T));
6183 Error_Msg_Node_2 := T;
cb97ae5c 6184 Error_Msg_N ("info: & inherits predicate from & #?L?", Typ);
9dc88aea 6185 end if;
6186 end if;
6187 end Add_Call;
6188
6189 --------------------
6190 -- Add_Predicates --
6191 --------------------
6192
6193 procedure Add_Predicates is
6194 Ritem : Node_Id;
6195 Arg1 : Node_Id;
6196 Arg2 : Node_Id;
6197
2072eaa9 6198 procedure Replace_Type_Reference (N : Node_Id);
6199 -- Replace a single occurrence N of the subtype name with a reference
6200 -- to the formal of the predicate function. N can be an identifier
6201 -- referencing the subtype, or a selected component, representing an
6202 -- appropriately qualified occurrence of the subtype name.
9dc88aea 6203
2072eaa9 6204 procedure Replace_Type_References is
6205 new Replace_Type_References_Generic (Replace_Type_Reference);
490beba6 6206 -- Traverse an expression changing every occurrence of an identifier
6fb3c314 6207 -- whose name matches the name of the subtype with a reference to
2072eaa9 6208 -- the formal parameter of the predicate function.
9dc88aea 6209
2072eaa9 6210 ----------------------------
6211 -- Replace_Type_Reference --
6212 ----------------------------
490beba6 6213
2072eaa9 6214 procedure Replace_Type_Reference (N : Node_Id) is
9dc88aea 6215 begin
c92e878b 6216 Rewrite (N, Make_Identifier (Sloc (N), Object_Name));
6217 -- Use the Sloc of the usage name, not the defining name
6218
fb7f2fc4 6219 Set_Etype (N, Typ);
84c8f0b8 6220 Set_Entity (N, Object_Entity);
4c1fd062 6221
6222 -- We want to treat the node as if it comes from source, so that
6223 -- ASIS will not ignore it
6224
6225 Set_Comes_From_Source (N, True);
2072eaa9 6226 end Replace_Type_Reference;
9dc88aea 6227
6228 -- Start of processing for Add_Predicates
6229
6230 begin
6231 Ritem := First_Rep_Item (Typ);
6232 while Present (Ritem) loop
6233 if Nkind (Ritem) = N_Pragma
6234 and then Pragma_Name (Ritem) = Name_Predicate
6235 then
34d045d3 6236 -- Save the static predicate of the type for diagnostics and
6237 -- error reporting purposes.
6238
6239 if Present (Corresponding_Aspect (Ritem))
6240 and then Chars (Identifier (Corresponding_Aspect (Ritem))) =
6241 Name_Static_Predicate
6242 then
6243 Static_Predic := Ritem;
ebbab42d 6244 end if;
6245
fb7f2fc4 6246 -- Acquire arguments
6247
9dc88aea 6248 Arg1 := First (Pragma_Argument_Associations (Ritem));
6249 Arg2 := Next (Arg1);
6250
6251 Arg1 := Get_Pragma_Arg (Arg1);
6252 Arg2 := Get_Pragma_Arg (Arg2);
6253
ffc2539e 6254 -- See if this predicate pragma is for the current type or for
6255 -- its full view. A predicate on a private completion is placed
6256 -- on the partial view beause this is the visible entity that
6257 -- is frozen.
9dc88aea 6258
13dc58a7 6259 if Entity (Arg1) = Typ
6260 or else Full_View (Entity (Arg1)) = Typ
6261 then
9dc88aea 6262 -- We have a match, this entry is for our subtype
6263
fb7f2fc4 6264 -- We need to replace any occurrences of the name of the
6265 -- type with references to the object.
490beba6 6266
2072eaa9 6267 Replace_Type_References (Arg2, Chars (Typ));
9dc88aea 6268
fb7f2fc4 6269 -- If this predicate comes from an aspect, find the aspect
6270 -- specification, and replace the saved expression because
6271 -- we need the subtype references replaced for the calls to
6272 -- Preanalyze_Spec_Expressin in Check_Aspect_At_Freeze_Point
6273 -- and Check_Aspect_At_End_Of_Declarations.
6274
6275 if From_Aspect_Specification (Ritem) then
6276 declare
6277 Aitem : Node_Id;
6278
6279 begin
6280 -- Loop to find corresponding aspect, note that this
6281 -- must be present given the pragma is marked delayed.
6282
6283 Aitem := Next_Rep_Item (Ritem);
6284 loop
6285 if Nkind (Aitem) = N_Aspect_Specification
6286 and then Aspect_Rep_Item (Aitem) = Ritem
6287 then
6288 Set_Entity
6289 (Identifier (Aitem), New_Copy_Tree (Arg2));
6290 exit;
6291 end if;
6292
6293 Aitem := Next_Rep_Item (Aitem);
6294 end loop;
6295 end;
6296 end if;
6297
6298 -- Now we can add the expression
9dc88aea 6299
6300 if No (Expr) then
6301 Expr := Relocate_Node (Arg2);
6302
6303 -- There already was a predicate, so add to it
6304
6305 else
6306 Expr :=
6307 Make_And_Then (Loc,
6308 Left_Opnd => Relocate_Node (Expr),
6309 Right_Opnd => Relocate_Node (Arg2));
6310 end if;
6311 end if;
6312 end if;
6313
6314 Next_Rep_Item (Ritem);
6315 end loop;
6316 end Add_Predicates;
6317
84c8f0b8 6318 ----------------
6319 -- Process_RE --
6320 ----------------
9dc88aea 6321
84c8f0b8 6322 function Process_RE (N : Node_Id) return Traverse_Result is
6323 begin
6324 if Nkind (N) = N_Raise_Expression then
6325 Set_Convert_To_Return_False (N);
6326 return Skip;
6327 else
6328 return OK;
6329 end if;
6330 end Process_RE;
d97beb2f 6331
84c8f0b8 6332 -------------
6333 -- Test_RE --
6334 -------------
d97beb2f 6335
84c8f0b8 6336 function Test_RE (N : Node_Id) return Traverse_Result is
6337 begin
6338 if Nkind (N) = N_Raise_Expression then
6339 Raise_Expression_Present := True;
6340 return Abandon;
6341 else
6342 return OK;
6343 end if;
6344 end Test_RE;
6345
6346 -- Start of processing for Build_Predicate_Functions
6347
6348 begin
d97beb2f 6349 -- Return if already built or if type does not have predicates
6350
6351 if not Has_Predicates (Typ)
6352 or else Present (Predicate_Function (Typ))
6353 then
6354 return;
6355 end if;
6356
84c8f0b8 6357 -- Prepare to construct predicate expression
6358
6359 Expr := Empty;
6360
d97beb2f 6361 -- Add Predicates for the current type
6362
6363 Add_Predicates;
6364
6365 -- Add predicates for ancestor if present
6366
6367 declare
6368 Atyp : constant Entity_Id := Nearest_Ancestor (Typ);
6369 begin
6370 if Present (Atyp) then
6371 Add_Call (Atyp);
6372 end if;
6373 end;
6374
84c8f0b8 6375 -- Case where predicates are present
d97beb2f 6376
6377 if Present (Expr) then
6378
84c8f0b8 6379 -- Test for raise expression present
d97beb2f 6380
84c8f0b8 6381 Test_REs (Expr);
9dc88aea 6382
84c8f0b8 6383 -- If raise expression is present, capture a copy of Expr for use
6384 -- in building the predicateM function version later on. For this
6385 -- copy we replace references to Object_Entity by Object_Entity_M.
9f269bd8 6386
84c8f0b8 6387 if Raise_Expression_Present then
6388 declare
6389 Map : constant Elist_Id := New_Elmt_List;
6390 begin
6391 Append_Elmt (Object_Entity, Map);
6392 Append_Elmt (Object_Entity_M, Map);
6393 Expr_M := New_Copy_Tree (Expr, Map => Map);
6394 end;
9f269bd8 6395 end if;
6396
84c8f0b8 6397 -- Build the main predicate function
6398
6399 declare
6400 SId : constant Entity_Id :=
6401 Make_Defining_Identifier (Loc,
6402 Chars => New_External_Name (Chars (Typ), "Predicate"));
6403 -- The entity for the the function spec
6404
6405 SIdB : constant Entity_Id :=
6406 Make_Defining_Identifier (Loc,
6407 Chars => New_External_Name (Chars (Typ), "Predicate"));
6408 -- The entity for the function body
6409
6410 Spec : Node_Id;
6411 FDecl : Node_Id;
6412 FBody : Node_Id;
6413
6414 begin
6415 -- Build function declaration
6416
6417 Set_Ekind (SId, E_Function);
6418 Set_Is_Predicate_Function (SId);
6419 Set_Predicate_Function (Typ, SId);
6420
6421 -- The predicate function is shared between views of a type
6422
6423 if Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
6424 Set_Predicate_Function (Full_View (Typ), SId);
6425 end if;
6426
6427 Spec :=
6428 Make_Function_Specification (Loc,
6429 Defining_Unit_Name => SId,
6430 Parameter_Specifications => New_List (
6431 Make_Parameter_Specification (Loc,
6432 Defining_Identifier => Object_Entity,
6433 Parameter_Type => New_Occurrence_Of (Typ, Loc))),
6434 Result_Definition =>
6435 New_Occurrence_Of (Standard_Boolean, Loc));
6436
6437 FDecl :=
6438 Make_Subprogram_Declaration (Loc,
6439 Specification => Spec);
6440
6441 -- Build function body
6442
6443 Spec :=
6444 Make_Function_Specification (Loc,
6445 Defining_Unit_Name => SIdB,
6446 Parameter_Specifications => New_List (
6447 Make_Parameter_Specification (Loc,
6448 Defining_Identifier =>
6449 Make_Defining_Identifier (Loc, Object_Name),
6450 Parameter_Type =>
6451 New_Occurrence_Of (Typ, Loc))),
6452 Result_Definition =>
6453 New_Occurrence_Of (Standard_Boolean, Loc));
6454
6455 FBody :=
6456 Make_Subprogram_Body (Loc,
6457 Specification => Spec,
6458 Declarations => Empty_List,
6459 Handled_Statement_Sequence =>
6460 Make_Handled_Sequence_Of_Statements (Loc,
6461 Statements => New_List (
6462 Make_Simple_Return_Statement (Loc,
6463 Expression => Expr))));
6464
6465 -- Insert declaration before freeze node and body after
6466
6467 Insert_Before_And_Analyze (N, FDecl);
6468 Insert_After_And_Analyze (N, FBody);
6469 end;
6470
6471 -- Test for raise expressions present and if so build M version
6472
6473 if Raise_Expression_Present then
6474 declare
6475 SId : constant Entity_Id :=
6476 Make_Defining_Identifier (Loc,
6477 Chars => New_External_Name (Chars (Typ), "PredicateM"));
6478 -- The entity for the the function spec
6479
6480 SIdB : constant Entity_Id :=
6481 Make_Defining_Identifier (Loc,
6482 Chars => New_External_Name (Chars (Typ), "PredicateM"));
6483 -- The entity for the function body
6484
6485 Spec : Node_Id;
6486 FDecl : Node_Id;
6487 FBody : Node_Id;
6488 BTemp : Entity_Id;
6489
6490 begin
6491 -- Mark any raise expressions for special expansion
6492
6493 Process_REs (Expr_M);
490beba6 6494
84c8f0b8 6495 -- Build function declaration
490beba6 6496
84c8f0b8 6497 Set_Ekind (SId, E_Function);
6498 Set_Is_Predicate_Function_M (SId);
6499 Set_Predicate_Function_M (Typ, SId);
6500
6501 -- The predicate function is shared between views of a type
6502
6503 if Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
6504 Set_Predicate_Function_M (Full_View (Typ), SId);
6505 end if;
6506
6507 Spec :=
6508 Make_Function_Specification (Loc,
6509 Defining_Unit_Name => SId,
6510 Parameter_Specifications => New_List (
6511 Make_Parameter_Specification (Loc,
6512 Defining_Identifier => Object_Entity_M,
6513 Parameter_Type => New_Occurrence_Of (Typ, Loc))),
6514 Result_Definition =>
6515 New_Occurrence_Of (Standard_Boolean, Loc));
6516
6517 FDecl :=
6518 Make_Subprogram_Declaration (Loc,
6519 Specification => Spec);
6520
6521 -- Build function body
6522
6523 Spec :=
6524 Make_Function_Specification (Loc,
6525 Defining_Unit_Name => SIdB,
6526 Parameter_Specifications => New_List (
6527 Make_Parameter_Specification (Loc,
6528 Defining_Identifier =>
6529 Make_Defining_Identifier (Loc, Object_Name),
6530 Parameter_Type =>
6531 New_Occurrence_Of (Typ, Loc))),
6532 Result_Definition =>
6533 New_Occurrence_Of (Standard_Boolean, Loc));
6534
6535 -- Build the body, we declare the boolean expression before
6536 -- doing the return, because we are not really confident of
6537 -- what happens if a return appears within a return!
6538
6539 BTemp :=
6540 Make_Defining_Identifier (Loc,
6541 Chars => New_Internal_Name ('B'));
6542
6543 FBody :=
6544 Make_Subprogram_Body (Loc,
6545 Specification => Spec,
6546
6547 Declarations => New_List (
6548 Make_Object_Declaration (Loc,
6549 Defining_Identifier => BTemp,
6550 Constant_Present => True,
6551 Object_Definition =>
6552 New_Reference_To (Standard_Boolean, Loc),
6553 Expression => Expr_M)),
6554
6555 Handled_Statement_Sequence =>
6556 Make_Handled_Sequence_Of_Statements (Loc,
6557 Statements => New_List (
6558 Make_Simple_Return_Statement (Loc,
6559 Expression => New_Reference_To (BTemp, Loc)))));
6560
6561 -- Insert declaration before freeze node and body after
6562
6563 Insert_Before_And_Analyze (N, FDecl);
6564 Insert_After_And_Analyze (N, FBody);
6565 end;
6566 end if;
490beba6 6567
64cc9e5d 6568 if Is_Scalar_Type (Typ) then
490beba6 6569
64cc9e5d 6570 -- Attempt to build a static predicate for a discrete or a real
6571 -- subtype. This action may fail because the actual expression may
34d045d3 6572 -- not be static. Note that the presence of an inherited or
6573 -- explicitly declared dynamic predicate is orthogonal to this
6574 -- check because we are only interested in the static predicate.
9ab32fe9 6575
64cc9e5d 6576 if Ekind_In (Typ, E_Decimal_Fixed_Point_Subtype,
6577 E_Enumeration_Subtype,
6578 E_Floating_Point_Subtype,
9ab32fe9 6579 E_Modular_Integer_Subtype,
64cc9e5d 6580 E_Ordinary_Fixed_Point_Subtype,
9ab32fe9 6581 E_Signed_Integer_Subtype)
ebbab42d 6582 then
9ab32fe9 6583 Build_Static_Predicate (Typ, Expr, Object_Name);
6584
34d045d3 6585 -- Emit an error when the predicate is categorized as static
6586 -- but its expression is dynamic.
64cc9e5d 6587
34d045d3 6588 if Present (Static_Predic)
64cc9e5d 6589 and then No (Static_Predicate (Typ))
9ab32fe9 6590 then
6591 Error_Msg_F
6592 ("expression does not have required form for "
6593 & "static predicate",
6594 Next (First (Pragma_Argument_Associations
34d045d3 6595 (Static_Predic))));
9ab32fe9 6596 end if;
6597 end if;
6598
34d045d3 6599 -- If a static predicate applies on other types, that's an error:
9ab32fe9 6600 -- either the type is scalar but non-static, or it's not even a
e5a341eb 6601 -- scalar type. We do not issue an error on generated types, as
6602 -- these may be duplicates of the same error on a source type.
9ab32fe9 6603
34d045d3 6604 elsif Present (Static_Predic) and then Comes_From_Source (Typ) then
9ab32fe9 6605 if Is_Scalar_Type (Typ) then
6606 Error_Msg_FE
6607 ("static predicate not allowed for non-static type&",
6608 Typ, Typ);
6609 else
6610 Error_Msg_FE
6611 ("static predicate not allowed for non-scalar type&",
6612 Typ, Typ);
ebbab42d 6613 end if;
490beba6 6614 end if;
d97beb2f 6615 end if;
84c8f0b8 6616 end Build_Predicate_Functions;
d97beb2f 6617
6618 ----------------------------
6619 -- Build_Static_Predicate --
6620 ----------------------------
6621
6622 procedure Build_Static_Predicate
6623 (Typ : Entity_Id;
6624 Expr : Node_Id;
6625 Nam : Name_Id)
6626 is
6627 Loc : constant Source_Ptr := Sloc (Expr);
6628
6629 Non_Static : exception;
6630 -- Raised if something non-static is found
6631
d7c2851f 6632 Btyp : constant Entity_Id := Base_Type (Typ);
6633
6634 BLo : constant Uint := Expr_Value (Type_Low_Bound (Btyp));
6635 BHi : constant Uint := Expr_Value (Type_High_Bound (Btyp));
6636 -- Low bound and high bound value of base type of Typ
6637
6638 TLo : constant Uint := Expr_Value (Type_Low_Bound (Typ));
6639 THi : constant Uint := Expr_Value (Type_High_Bound (Typ));
6640 -- Low bound and high bound values of static subtype Typ
d97beb2f 6641
6642 type REnt is record
9dc88aea 6643 Lo, Hi : Uint;
d97beb2f 6644 end record;
726fd56a 6645 -- One entry in a Rlist value, a single REnt (range entry) value denotes
6646 -- one range from Lo to Hi. To represent a single value range Lo = Hi =
6647 -- value.
d97beb2f 6648
6649 type RList is array (Nat range <>) of REnt;
726fd56a 6650 -- A list of ranges. The ranges are sorted in increasing order, and are
6651 -- disjoint (there is a gap of at least one value between each range in
6652 -- the table). A value is in the set of ranges in Rlist if it lies
6653 -- within one of these ranges.
d97beb2f 6654
d7c2851f 6655 False_Range : constant RList :=
6656 RList'(1 .. 0 => REnt'(No_Uint, No_Uint));
6657 -- An empty set of ranges represents a range list that can never be
6658 -- satisfied, since there are no ranges in which the value could lie,
6659 -- so it does not lie in any of them. False_Range is a canonical value
6660 -- for this empty set, but general processing should test for an Rlist
6661 -- with length zero (see Is_False predicate), since other null ranges
6662 -- may appear which must be treated as False.
d97beb2f 6663
d7c2851f 6664 True_Range : constant RList := RList'(1 => REnt'(BLo, BHi));
6665 -- Range representing True, value must be in the base range
d97beb2f 6666
726fd56a 6667 function "and" (Left : RList; Right : RList) return RList;
6668 -- And's together two range lists, returning a range list. This is a set
6669 -- intersection operation.
d97beb2f 6670
726fd56a 6671 function "or" (Left : RList; Right : RList) return RList;
6672 -- Or's together two range lists, returning a range list. This is a set
6673 -- union operation.
d97beb2f 6674
6675 function "not" (Right : RList) return RList;
6676 -- Returns complement of a given range list, i.e. a range list
726fd56a 6677 -- representing all the values in TLo .. THi that are not in the input
6678 -- operand Right.
d97beb2f 6679
6680 function Build_Val (V : Uint) return Node_Id;
6681 -- Return an analyzed N_Identifier node referencing this value, suitable
d7c2851f 6682 -- for use as an entry in the Static_Predicate list. This node is typed
6683 -- with the base type.
d97beb2f 6684
726fd56a 6685 function Build_Range (Lo : Uint; Hi : Uint) return Node_Id;
6686 -- Return an analyzed N_Range node referencing this range, suitable for
6687 -- use as an entry in the Static_Predicate list. This node is typed with
6688 -- the base type.
d97beb2f 6689
6690 function Get_RList (Exp : Node_Id) return RList;
726fd56a 6691 -- This is a recursive routine that converts the given expression into a
6692 -- list of ranges, suitable for use in building the static predicate.
d97beb2f 6693
d7c2851f 6694 function Is_False (R : RList) return Boolean;
6695 pragma Inline (Is_False);
726fd56a 6696 -- Returns True if the given range list is empty, and thus represents a
6697 -- False list of ranges that can never be satisfied.
d7c2851f 6698
6699 function Is_True (R : RList) return Boolean;
726fd56a 6700 -- Returns True if R trivially represents the True predicate by having a
6701 -- single range from BLo to BHi.
d7c2851f 6702
d97beb2f 6703 function Is_Type_Ref (N : Node_Id) return Boolean;
6704 pragma Inline (Is_Type_Ref);
6705 -- Returns if True if N is a reference to the type for the predicate in
6706 -- the expression (i.e. if it is an identifier whose Chars field matches
6707 -- the Nam given in the call).
6708
d9f6a4ee 6709 function Lo_Val (N : Node_Id) return Uint;
6710 -- Given static expression or static range from a Static_Predicate list,
6711 -- gets expression value or low bound of range.
6712
6713 function Hi_Val (N : Node_Id) return Uint;
6714 -- Given static expression or static range from a Static_Predicate list,
6715 -- gets expression value of high bound of range.
6716
6717 function Membership_Entry (N : Node_Id) return RList;
6718 -- Given a single membership entry (range, value, or subtype), returns
6719 -- the corresponding range list. Raises Static_Error if not static.
6720
6721 function Membership_Entries (N : Node_Id) return RList;
6722 -- Given an element on an alternatives list of a membership operation,
6723 -- returns the range list corresponding to this entry and all following
6724 -- entries (i.e. returns the "or" of this list of values).
6725
6726 function Stat_Pred (Typ : Entity_Id) return RList;
6727 -- Given a type, if it has a static predicate, then return the predicate
6728 -- as a range list, otherwise raise Non_Static.
6729
6730 -----------
6731 -- "and" --
6732 -----------
6733
6734 function "and" (Left : RList; Right : RList) return RList is
6735 FEnt : REnt;
6736 -- First range of result
6737
6738 SLeft : Nat := Left'First;
6739 -- Start of rest of left entries
6740
6741 SRight : Nat := Right'First;
6742 -- Start of rest of right entries
6743
6744 begin
6745 -- If either range is True, return the other
6746
6747 if Is_True (Left) then
6748 return Right;
6749 elsif Is_True (Right) then
6750 return Left;
6751 end if;
6752
6753 -- If either range is False, return False
6754
6755 if Is_False (Left) or else Is_False (Right) then
6756 return False_Range;
6757 end if;
6758
6759 -- Loop to remove entries at start that are disjoint, and thus just
6760 -- get discarded from the result entirely.
6761
6762 loop
6763 -- If no operands left in either operand, result is false
6764
6765 if SLeft > Left'Last or else SRight > Right'Last then
6766 return False_Range;
6767
6768 -- Discard first left operand entry if disjoint with right
6769
6770 elsif Left (SLeft).Hi < Right (SRight).Lo then
6771 SLeft := SLeft + 1;
6772
6773 -- Discard first right operand entry if disjoint with left
6774
6775 elsif Right (SRight).Hi < Left (SLeft).Lo then
6776 SRight := SRight + 1;
6777
6778 -- Otherwise we have an overlapping entry
6779
6780 else
6781 exit;
6782 end if;
6783 end loop;
6784
6785 -- Now we have two non-null operands, and first entries overlap. The
6786 -- first entry in the result will be the overlapping part of these
6787 -- two entries.
6788
6789 FEnt := REnt'(Lo => UI_Max (Left (SLeft).Lo, Right (SRight).Lo),
6790 Hi => UI_Min (Left (SLeft).Hi, Right (SRight).Hi));
6791
6792 -- Now we can remove the entry that ended at a lower value, since its
6793 -- contribution is entirely contained in Fent.
6794
6795 if Left (SLeft).Hi <= Right (SRight).Hi then
6796 SLeft := SLeft + 1;
6797 else
6798 SRight := SRight + 1;
6799 end if;
6800
6801 -- Compute result by concatenating this first entry with the "and" of
6802 -- the remaining parts of the left and right operands. Note that if
6803 -- either of these is empty, "and" will yield empty, so that we will
6804 -- end up with just Fent, which is what we want in that case.
6805
6806 return
6807 FEnt & (Left (SLeft .. Left'Last) and Right (SRight .. Right'Last));
6808 end "and";
6809
6810 -----------
6811 -- "not" --
6812 -----------
6813
6814 function "not" (Right : RList) return RList is
6815 begin
6816 -- Return True if False range
6817
6818 if Is_False (Right) then
6819 return True_Range;
6820 end if;
6821
6822 -- Return False if True range
6823
6824 if Is_True (Right) then
6825 return False_Range;
6826 end if;
6827
6828 -- Here if not trivial case
6829
6830 declare
6831 Result : RList (1 .. Right'Length + 1);
6832 -- May need one more entry for gap at beginning and end
6833
6834 Count : Nat := 0;
6835 -- Number of entries stored in Result
6836
6837 begin
6838 -- Gap at start
6839
6840 if Right (Right'First).Lo > TLo then
6841 Count := Count + 1;
6842 Result (Count) := REnt'(TLo, Right (Right'First).Lo - 1);
6843 end if;
6844
6845 -- Gaps between ranges
d97beb2f 6846
d9f6a4ee 6847 for J in Right'First .. Right'Last - 1 loop
6848 Count := Count + 1;
6849 Result (Count) :=
6850 REnt'(Right (J).Hi + 1, Right (J + 1).Lo - 1);
6851 end loop;
d97beb2f 6852
d9f6a4ee 6853 -- Gap at end
d97beb2f 6854
d9f6a4ee 6855 if Right (Right'Last).Hi < THi then
6856 Count := Count + 1;
6857 Result (Count) := REnt'(Right (Right'Last).Hi + 1, THi);
6858 end if;
d97beb2f 6859
d9f6a4ee 6860 return Result (1 .. Count);
6861 end;
6862 end "not";
d97beb2f 6863
d9f6a4ee 6864 ----------
6865 -- "or" --
6866 ----------
d97beb2f 6867
d9f6a4ee 6868 function "or" (Left : RList; Right : RList) return RList is
d97beb2f 6869 FEnt : REnt;
6870 -- First range of result
6871
6872 SLeft : Nat := Left'First;
6873 -- Start of rest of left entries
6874
6875 SRight : Nat := Right'First;
6876 -- Start of rest of right entries
9dc88aea 6877
d97beb2f 6878 begin
d9f6a4ee 6879 -- If either range is True, return True
9dc88aea 6880
d9f6a4ee 6881 if Is_True (Left) or else Is_True (Right) then
6882 return True_Range;
6883 end if;
6884
6885 -- If either range is False (empty), return the other
6886
6887 if Is_False (Left) then
d97beb2f 6888 return Right;
d9f6a4ee 6889 elsif Is_False (Right) then
d97beb2f 6890 return Left;
6891 end if;
9dc88aea 6892
d9f6a4ee 6893 -- Initialize result first entry from left or right operand depending
6894 -- on which starts with the lower range.
9dc88aea 6895
d9f6a4ee 6896 if Left (SLeft).Lo < Right (SRight).Lo then
6897 FEnt := Left (SLeft);
6898 SLeft := SLeft + 1;
6899 else
6900 FEnt := Right (SRight);
6901 SRight := SRight + 1;
d97beb2f 6902 end if;
9dc88aea 6903
d9f6a4ee 6904 -- This loop eats ranges from left and right operands that are
6905 -- contiguous with the first range we are gathering.
9dc88aea 6906
d97beb2f 6907 loop
d9f6a4ee 6908 -- Eat first entry in left operand if contiguous or overlapped by
6909 -- gathered first operand of result.
9dc88aea 6910
d9f6a4ee 6911 if SLeft <= Left'Last
6912 and then Left (SLeft).Lo <= FEnt.Hi + 1
6913 then
6914 FEnt.Hi := UI_Max (FEnt.Hi, Left (SLeft).Hi);
d97beb2f 6915 SLeft := SLeft + 1;
9dc88aea 6916
d9f6a4ee 6917 -- Eat first entry in right operand if contiguous or overlapped by
6918 -- gathered right operand of result.
9dc88aea 6919
d9f6a4ee 6920 elsif SRight <= Right'Last
6921 and then Right (SRight).Lo <= FEnt.Hi + 1
6922 then
6923 FEnt.Hi := UI_Max (FEnt.Hi, Right (SRight).Hi);
d97beb2f 6924 SRight := SRight + 1;
9dc88aea 6925
d9f6a4ee 6926 -- All done if no more entries to eat
9dc88aea 6927
d97beb2f 6928 else
6929 exit;
6930 end if;
6931 end loop;
9dc88aea 6932
d9f6a4ee 6933 -- Obtain result as the first entry we just computed, concatenated
6934 -- to the "or" of the remaining results (if one operand is empty,
6935 -- this will just concatenate with the other
9dc88aea 6936
d9f6a4ee 6937 return
6938 FEnt & (Left (SLeft .. Left'Last) or Right (SRight .. Right'Last));
6939 end "or";
9dc88aea 6940
d9f6a4ee 6941 -----------------
6942 -- Build_Range --
6943 -----------------
d97beb2f 6944
d9f6a4ee 6945 function Build_Range (Lo : Uint; Hi : Uint) return Node_Id is
6946 Result : Node_Id;
6947
6948 begin
6949 Result :=
6950 Make_Range (Loc,
6951 Low_Bound => Build_Val (Lo),
6952 High_Bound => Build_Val (Hi));
6953 Set_Etype (Result, Btyp);
6954 Set_Analyzed (Result);
6955
6956 return Result;
6957 end Build_Range;
6958
6959 ---------------
6960 -- Build_Val --
6961 ---------------
6962
6963 function Build_Val (V : Uint) return Node_Id is
6964 Result : Node_Id;
6965
6966 begin
6967 if Is_Enumeration_Type (Typ) then
6968 Result := Get_Enum_Lit_From_Pos (Typ, V, Loc);
d97beb2f 6969 else
d9f6a4ee 6970 Result := Make_Integer_Literal (Loc, V);
d97beb2f 6971 end if;
6972
d9f6a4ee 6973 Set_Etype (Result, Btyp);
6974 Set_Is_Static_Expression (Result);
6975 Set_Analyzed (Result);
6976 return Result;
6977 end Build_Val;
d97beb2f 6978
d9f6a4ee 6979 ---------------
6980 -- Get_RList --
6981 ---------------
6982
6983 function Get_RList (Exp : Node_Id) return RList is
6984 Op : Node_Kind;
6985 Val : Uint;
6986
6987 begin
6988 -- Static expression can only be true or false
6989
6990 if Is_OK_Static_Expression (Exp) then
6991
6992 -- For False
6993
6994 if Expr_Value (Exp) = 0 then
6995 return False_Range;
6996 else
6997 return True_Range;
6998 end if;
6999 end if;
7000
7001 -- Otherwise test node type
7002
7003 Op := Nkind (Exp);
7004
7005 case Op is
7006
7007 -- And
7008
7009 when N_Op_And | N_And_Then =>
7010 return Get_RList (Left_Opnd (Exp))
7011 and
7012 Get_RList (Right_Opnd (Exp));
7013
7014 -- Or
7015
7016 when N_Op_Or | N_Or_Else =>
7017 return Get_RList (Left_Opnd (Exp))
7018 or
7019 Get_RList (Right_Opnd (Exp));
7020
7021 -- Not
7022
7023 when N_Op_Not =>
7024 return not Get_RList (Right_Opnd (Exp));
7025
7026 -- Comparisons of type with static value
7027
7028 when N_Op_Compare =>
7029
7030 -- Type is left operand
7031
7032 if Is_Type_Ref (Left_Opnd (Exp))
7033 and then Is_OK_Static_Expression (Right_Opnd (Exp))
7034 then
7035 Val := Expr_Value (Right_Opnd (Exp));
7036
7037 -- Typ is right operand
7038
7039 elsif Is_Type_Ref (Right_Opnd (Exp))
7040 and then Is_OK_Static_Expression (Left_Opnd (Exp))
7041 then
7042 Val := Expr_Value (Left_Opnd (Exp));
7043
7044 -- Invert sense of comparison
7045
7046 case Op is
7047 when N_Op_Gt => Op := N_Op_Lt;
7048 when N_Op_Lt => Op := N_Op_Gt;
7049 when N_Op_Ge => Op := N_Op_Le;
7050 when N_Op_Le => Op := N_Op_Ge;
7051 when others => null;
7052 end case;
7053
7054 -- Other cases are non-static
7055
7056 else
7057 raise Non_Static;
7058 end if;
7059
7060 -- Construct range according to comparison operation
7061
7062 case Op is
7063 when N_Op_Eq =>
7064 return RList'(1 => REnt'(Val, Val));
7065
7066 when N_Op_Ge =>
7067 return RList'(1 => REnt'(Val, BHi));
7068
7069 when N_Op_Gt =>
7070 return RList'(1 => REnt'(Val + 1, BHi));
7071
7072 when N_Op_Le =>
7073 return RList'(1 => REnt'(BLo, Val));
7074
7075 when N_Op_Lt =>
7076 return RList'(1 => REnt'(BLo, Val - 1));
7077
7078 when N_Op_Ne =>
7079 return RList'(REnt'(BLo, Val - 1),
7080 REnt'(Val + 1, BHi));
7081
7082 when others =>
7083 raise Program_Error;
7084 end case;
7085
7086 -- Membership (IN)
7087
7088 when N_In =>
7089 if not Is_Type_Ref (Left_Opnd (Exp)) then
7090 raise Non_Static;
7091 end if;
d97beb2f 7092
d9f6a4ee 7093 if Present (Right_Opnd (Exp)) then
7094 return Membership_Entry (Right_Opnd (Exp));
7095 else
7096 return Membership_Entries (First (Alternatives (Exp)));
7097 end if;
d97beb2f 7098
d9f6a4ee 7099 -- Negative membership (NOT IN)
d97beb2f 7100
d9f6a4ee 7101 when N_Not_In =>
7102 if not Is_Type_Ref (Left_Opnd (Exp)) then
7103 raise Non_Static;
7104 end if;
d97beb2f 7105
d9f6a4ee 7106 if Present (Right_Opnd (Exp)) then
7107 return not Membership_Entry (Right_Opnd (Exp));
7108 else
7109 return not Membership_Entries (First (Alternatives (Exp)));
7110 end if;
d97beb2f 7111
d9f6a4ee 7112 -- Function call, may be call to static predicate
d97beb2f 7113
d9f6a4ee 7114 when N_Function_Call =>
7115 if Is_Entity_Name (Name (Exp)) then
7116 declare
7117 Ent : constant Entity_Id := Entity (Name (Exp));
7118 begin
7119 if Is_Predicate_Function (Ent)
7120 or else
7121 Is_Predicate_Function_M (Ent)
7122 then
7123 return Stat_Pred (Etype (First_Formal (Ent)));
7124 end if;
7125 end;
7126 end if;
d97beb2f 7127
d9f6a4ee 7128 -- Other function call cases are non-static
d97beb2f 7129
d9f6a4ee 7130 raise Non_Static;
d97beb2f 7131
d9f6a4ee 7132 -- Qualified expression, dig out the expression
d97beb2f 7133
d9f6a4ee 7134 when N_Qualified_Expression =>
7135 return Get_RList (Expression (Exp));
d97beb2f 7136
d9f6a4ee 7137 -- Xor operator
d97beb2f 7138
d9f6a4ee 7139 when N_Op_Xor =>
7140 return (Get_RList (Left_Opnd (Exp))
7141 and not Get_RList (Right_Opnd (Exp)))
7142 or (Get_RList (Right_Opnd (Exp))
7143 and not Get_RList (Left_Opnd (Exp)));
d97beb2f 7144
d9f6a4ee 7145 -- Any other node type is non-static
d97beb2f 7146
d9f6a4ee 7147 when others =>
7148 raise Non_Static;
7149 end case;
7150 end Get_RList;
d97beb2f 7151
d9f6a4ee 7152 ------------
7153 -- Hi_Val --
7154 ------------
d97beb2f 7155
d9f6a4ee 7156 function Hi_Val (N : Node_Id) return Uint is
7157 begin
7158 if Is_Static_Expression (N) then
7159 return Expr_Value (N);
7160 else
7161 pragma Assert (Nkind (N) = N_Range);
7162 return Expr_Value (High_Bound (N));
7163 end if;
7164 end Hi_Val;
d97beb2f 7165
d9f6a4ee 7166 --------------
7167 -- Is_False --
7168 --------------
d7c2851f 7169
d9f6a4ee 7170 function Is_False (R : RList) return Boolean is
7171 begin
7172 return R'Length = 0;
7173 end Is_False;
d7c2851f 7174
d9f6a4ee 7175 -------------
7176 -- Is_True --
7177 -------------
d7c2851f 7178
d9f6a4ee 7179 function Is_True (R : RList) return Boolean is
d97beb2f 7180 begin
d9f6a4ee 7181 return R'Length = 1
7182 and then R (R'First).Lo = BLo
7183 and then R (R'First).Hi = BHi;
7184 end Is_True;
d97beb2f 7185
d9f6a4ee 7186 -----------------
7187 -- Is_Type_Ref --
7188 -----------------
d97beb2f 7189
d9f6a4ee 7190 function Is_Type_Ref (N : Node_Id) return Boolean is
7191 begin
7192 return Nkind (N) = N_Identifier and then Chars (N) = Nam;
7193 end Is_Type_Ref;
9dc88aea 7194
d9f6a4ee 7195 ------------
7196 -- Lo_Val --
7197 ------------
7198
7199 function Lo_Val (N : Node_Id) return Uint is
7200 begin
7201 if Is_Static_Expression (N) then
7202 return Expr_Value (N);
7203 else
7204 pragma Assert (Nkind (N) = N_Range);
7205 return Expr_Value (Low_Bound (N));
d97beb2f 7206 end if;
d9f6a4ee 7207 end Lo_Val;
d97beb2f 7208
d9f6a4ee 7209 ------------------------
7210 -- Membership_Entries --
7211 ------------------------
d97beb2f 7212
d9f6a4ee 7213 function Membership_Entries (N : Node_Id) return RList is
7214 begin
7215 if No (Next (N)) then
7216 return Membership_Entry (N);
d7c2851f 7217 else
d9f6a4ee 7218 return Membership_Entry (N) or Membership_Entries (Next (N));
d97beb2f 7219 end if;
d9f6a4ee 7220 end Membership_Entries;
d97beb2f 7221
d9f6a4ee 7222 ----------------------
7223 -- Membership_Entry --
7224 ----------------------
d97beb2f 7225
d9f6a4ee 7226 function Membership_Entry (N : Node_Id) return RList is
7227 Val : Uint;
7228 SLo : Uint;
7229 SHi : Uint;
d97beb2f 7230
d9f6a4ee 7231 begin
7232 -- Range case
d97beb2f 7233
d9f6a4ee 7234 if Nkind (N) = N_Range then
7235 if not Is_Static_Expression (Low_Bound (N))
7236 or else
7237 not Is_Static_Expression (High_Bound (N))
d7c2851f 7238 then
d9f6a4ee 7239 raise Non_Static;
d97beb2f 7240 else
d9f6a4ee 7241 SLo := Expr_Value (Low_Bound (N));
7242 SHi := Expr_Value (High_Bound (N));
7243 return RList'(1 => REnt'(SLo, SHi));
d97beb2f 7244 end if;
9dc88aea 7245
d9f6a4ee 7246 -- Static expression case
9dc88aea 7247
d9f6a4ee 7248 elsif Is_Static_Expression (N) then
7249 Val := Expr_Value (N);
7250 return RList'(1 => REnt'(Val, Val));
726fd56a 7251
d9f6a4ee 7252 -- Identifier (other than static expression) case
726fd56a 7253
d9f6a4ee 7254 else pragma Assert (Nkind (N) = N_Identifier);
9dc88aea 7255
d9f6a4ee 7256 -- Type case
9dc88aea 7257
d9f6a4ee 7258 if Is_Type (Entity (N)) then
d97beb2f 7259
d9f6a4ee 7260 -- If type has predicates, process them
9dc88aea 7261
d9f6a4ee 7262 if Has_Predicates (Entity (N)) then
7263 return Stat_Pred (Entity (N));
9dc88aea 7264
d9f6a4ee 7265 -- For static subtype without predicates, get range
9dc88aea 7266
d9f6a4ee 7267 elsif Is_Static_Subtype (Entity (N)) then
7268 SLo := Expr_Value (Type_Low_Bound (Entity (N)));
7269 SHi := Expr_Value (Type_High_Bound (Entity (N)));
7270 return RList'(1 => REnt'(SLo, SHi));
9dc88aea 7271
d9f6a4ee 7272 -- Any other type makes us non-static
d97beb2f 7273
d9f6a4ee 7274 else
7275 raise Non_Static;
7276 end if;
d97beb2f 7277
d9f6a4ee 7278 -- Any other kind of identifier in predicate (e.g. a non-static
7279 -- expression value) means this is not a static predicate.
d97beb2f 7280
d97beb2f 7281 else
d9f6a4ee 7282 raise Non_Static;
d97beb2f 7283 end if;
7284 end if;
d9f6a4ee 7285 end Membership_Entry;
d97beb2f 7286
d9f6a4ee 7287 ---------------
7288 -- Stat_Pred --
7289 ---------------
d97beb2f 7290
d9f6a4ee 7291 function Stat_Pred (Typ : Entity_Id) return RList is
7292 begin
7293 -- Not static if type does not have static predicates
d97beb2f 7294
d9f6a4ee 7295 if not Has_Predicates (Typ) or else No (Static_Predicate (Typ)) then
7296 raise Non_Static;
7297 end if;
d97beb2f 7298
d9f6a4ee 7299 -- Otherwise we convert the predicate list to a range list
d97beb2f 7300
d9f6a4ee 7301 declare
7302 Result : RList (1 .. List_Length (Static_Predicate (Typ)));
7303 P : Node_Id;
9dc88aea 7304
d9f6a4ee 7305 begin
7306 P := First (Static_Predicate (Typ));
7307 for J in Result'Range loop
7308 Result (J) := REnt'(Lo_Val (P), Hi_Val (P));
7309 Next (P);
7310 end loop;
d97beb2f 7311
d9f6a4ee 7312 return Result;
7313 end;
7314 end Stat_Pred;
d97beb2f 7315
d9f6a4ee 7316 -- Start of processing for Build_Static_Predicate
d97beb2f 7317
d9f6a4ee 7318 begin
7319 -- Now analyze the expression to see if it is a static predicate
d97beb2f 7320
d9f6a4ee 7321 declare
7322 Ranges : constant RList := Get_RList (Expr);
7323 -- Range list from expression if it is static
d97beb2f 7324
d9f6a4ee 7325 Plist : List_Id;
b9e61b2a 7326
d9f6a4ee 7327 begin
7328 -- Convert range list into a form for the static predicate. In the
7329 -- Ranges array, we just have raw ranges, these must be converted
7330 -- to properly typed and analyzed static expressions or range nodes.
d97beb2f 7331
d9f6a4ee 7332 -- Note: here we limit ranges to the ranges of the subtype, so that
7333 -- a predicate is always false for values outside the subtype. That
7334 -- seems fine, such values are invalid anyway, and considering them
7335 -- to fail the predicate seems allowed and friendly, and furthermore
7336 -- simplifies processing for case statements and loops.
d97beb2f 7337
d9f6a4ee 7338 Plist := New_List;
d97beb2f 7339
d9f6a4ee 7340 for J in Ranges'Range loop
7341 declare
7342 Lo : Uint := Ranges (J).Lo;
7343 Hi : Uint := Ranges (J).Hi;
d97beb2f 7344
d9f6a4ee 7345 begin
7346 -- Ignore completely out of range entry
d97beb2f 7347
d9f6a4ee 7348 if Hi < TLo or else Lo > THi then
7349 null;
d97beb2f 7350
d9f6a4ee 7351 -- Otherwise process entry
9dc88aea 7352
7353 else
d9f6a4ee 7354 -- Adjust out of range value to subtype range
9dc88aea 7355
d9f6a4ee 7356 if Lo < TLo then
7357 Lo := TLo;
7358 end if;
9dc88aea 7359
d9f6a4ee 7360 if Hi > THi then
7361 Hi := THi;
7362 end if;
9dc88aea 7363
d9f6a4ee 7364 -- Convert range into required form
9dc88aea 7365
d9f6a4ee 7366 Append_To (Plist, Build_Range (Lo, Hi));
d97beb2f 7367 end if;
d9f6a4ee 7368 end;
7369 end loop;
9dc88aea 7370
d9f6a4ee 7371 -- Processing was successful and all entries were static, so now we
7372 -- can store the result as the predicate list.
9dc88aea 7373
d9f6a4ee 7374 Set_Static_Predicate (Typ, Plist);
9dc88aea 7375
d9f6a4ee 7376 -- The processing for static predicates put the expression into
7377 -- canonical form as a series of ranges. It also eliminated
7378 -- duplicates and collapsed and combined ranges. We might as well
7379 -- replace the alternatives list of the right operand of the
7380 -- membership test with the static predicate list, which will
7381 -- usually be more efficient.
d97beb2f 7382
d9f6a4ee 7383 declare
7384 New_Alts : constant List_Id := New_List;
7385 Old_Node : Node_Id;
7386 New_Node : Node_Id;
d97beb2f 7387
d9f6a4ee 7388 begin
7389 Old_Node := First (Plist);
7390 while Present (Old_Node) loop
7391 New_Node := New_Copy (Old_Node);
d97beb2f 7392
d9f6a4ee 7393 if Nkind (New_Node) = N_Range then
7394 Set_Low_Bound (New_Node, New_Copy (Low_Bound (Old_Node)));
7395 Set_High_Bound (New_Node, New_Copy (High_Bound (Old_Node)));
d97beb2f 7396 end if;
9dc88aea 7397
d9f6a4ee 7398 Append_To (New_Alts, New_Node);
7399 Next (Old_Node);
7400 end loop;
9dc88aea 7401
d9f6a4ee 7402 -- If empty list, replace by False
9dc88aea 7403
d9f6a4ee 7404 if Is_Empty_List (New_Alts) then
7405 Rewrite (Expr, New_Occurrence_Of (Standard_False, Loc));
9dc88aea 7406
d9f6a4ee 7407 -- Else replace by set membership test
9dc88aea 7408
d9f6a4ee 7409 else
7410 Rewrite (Expr,
7411 Make_In (Loc,
7412 Left_Opnd => Make_Identifier (Loc, Nam),
7413 Right_Opnd => Empty,
7414 Alternatives => New_Alts));
d7c2851f 7415
d9f6a4ee 7416 -- Resolve new expression in function context
d7c2851f 7417
d9f6a4ee 7418 Install_Formals (Predicate_Function (Typ));
7419 Push_Scope (Predicate_Function (Typ));
7420 Analyze_And_Resolve (Expr, Standard_Boolean);
7421 Pop_Scope;
7422 end if;
7423 end;
7424 end;
9dc88aea 7425
d9f6a4ee 7426 -- If non-static, return doing nothing
9dc88aea 7427
d9f6a4ee 7428 exception
7429 when Non_Static =>
7430 return;
7431 end Build_Static_Predicate;
9dc88aea 7432
d9f6a4ee 7433 -----------------------------------------
7434 -- Check_Aspect_At_End_Of_Declarations --
7435 -----------------------------------------
9dc88aea 7436
d9f6a4ee 7437 procedure Check_Aspect_At_End_Of_Declarations (ASN : Node_Id) is
7438 Ent : constant Entity_Id := Entity (ASN);
7439 Ident : constant Node_Id := Identifier (ASN);
7440 A_Id : constant Aspect_Id := Get_Aspect_Id (Chars (Ident));
d7c2851f 7441
d9f6a4ee 7442 End_Decl_Expr : constant Node_Id := Entity (Ident);
7443 -- Expression to be analyzed at end of declarations
d7c2851f 7444
d9f6a4ee 7445 Freeze_Expr : constant Node_Id := Expression (ASN);
7446 -- Expression from call to Check_Aspect_At_Freeze_Point
d7c2851f 7447
d9f6a4ee 7448 T : constant Entity_Id := Etype (Freeze_Expr);
7449 -- Type required for preanalyze call
d7c2851f 7450
d9f6a4ee 7451 Err : Boolean;
7452 -- Set False if error
9dc88aea 7453
d9f6a4ee 7454 -- On entry to this procedure, Entity (Ident) contains a copy of the
7455 -- original expression from the aspect, saved for this purpose, and
7456 -- but Expression (Ident) is a preanalyzed copy of the expression,
7457 -- preanalyzed just after the freeze point.
9dc88aea 7458
d9f6a4ee 7459 procedure Check_Overloaded_Name;
7460 -- For aspects whose expression is simply a name, this routine checks if
7461 -- the name is overloaded or not. If so, it verifies there is an
7462 -- interpretation that matches the entity obtained at the freeze point,
7463 -- otherwise the compiler complains.
9dc88aea 7464
d9f6a4ee 7465 ---------------------------
7466 -- Check_Overloaded_Name --
7467 ---------------------------
7468
7469 procedure Check_Overloaded_Name is
d97beb2f 7470 begin
d9f6a4ee 7471 if not Is_Overloaded (End_Decl_Expr) then
7472 Err := Entity (End_Decl_Expr) /= Entity (Freeze_Expr);
7473
d97beb2f 7474 else
d9f6a4ee 7475 Err := True;
9dc88aea 7476
d9f6a4ee 7477 declare
7478 Index : Interp_Index;
7479 It : Interp;
9dc88aea 7480
d9f6a4ee 7481 begin
7482 Get_First_Interp (End_Decl_Expr, Index, It);
7483 while Present (It.Typ) loop
7484 if It.Nam = Entity (Freeze_Expr) then
7485 Err := False;
7486 exit;
7487 end if;
7488
7489 Get_Next_Interp (Index, It);
7490 end loop;
7491 end;
9dc88aea 7492 end if;
d9f6a4ee 7493 end Check_Overloaded_Name;
9dc88aea 7494
d9f6a4ee 7495 -- Start of processing for Check_Aspect_At_End_Of_Declarations
9dc88aea 7496
d9f6a4ee 7497 begin
7498 -- Case of aspects Dimension, Dimension_System and Synchronization
9dc88aea 7499
d9f6a4ee 7500 if A_Id = Aspect_Synchronization then
7501 return;
d97beb2f 7502
d9f6a4ee 7503 -- Case of stream attributes, just have to compare entities. However,
7504 -- the expression is just a name (possibly overloaded), and there may
7505 -- be stream operations declared for unrelated types, so we just need
7506 -- to verify that one of these interpretations is the one available at
7507 -- at the freeze point.
9dc88aea 7508
d9f6a4ee 7509 elsif A_Id = Aspect_Input or else
7510 A_Id = Aspect_Output or else
7511 A_Id = Aspect_Read or else
7512 A_Id = Aspect_Write
7513 then
7514 Analyze (End_Decl_Expr);
7515 Check_Overloaded_Name;
9dc88aea 7516
d9f6a4ee 7517 elsif A_Id = Aspect_Variable_Indexing or else
7518 A_Id = Aspect_Constant_Indexing or else
7519 A_Id = Aspect_Default_Iterator or else
7520 A_Id = Aspect_Iterator_Element
7521 then
7522 -- Make type unfrozen before analysis, to prevent spurious errors
7523 -- about late attributes.
9dc88aea 7524
d9f6a4ee 7525 Set_Is_Frozen (Ent, False);
7526 Analyze (End_Decl_Expr);
7527 Set_Is_Frozen (Ent, True);
9dc88aea 7528
d9f6a4ee 7529 -- If the end of declarations comes before any other freeze
7530 -- point, the Freeze_Expr is not analyzed: no check needed.
9dc88aea 7531
d9f6a4ee 7532 if Analyzed (Freeze_Expr) and then not In_Instance then
7533 Check_Overloaded_Name;
7534 else
7535 Err := False;
7536 end if;
55e8372b 7537
d9f6a4ee 7538 -- All other cases
55e8372b 7539
d9f6a4ee 7540 else
7541 -- In a generic context the aspect expressions have not been
7542 -- preanalyzed, so do it now. There are no conformance checks
7543 -- to perform in this case.
55e8372b 7544
d9f6a4ee 7545 if No (T) then
7546 Check_Aspect_At_Freeze_Point (ASN);
7547 return;
55e8372b 7548
d9f6a4ee 7549 -- The default values attributes may be defined in the private part,
7550 -- and the analysis of the expression may take place when only the
7551 -- partial view is visible. The expression must be scalar, so use
7552 -- the full view to resolve.
55e8372b 7553
d9f6a4ee 7554 elsif (A_Id = Aspect_Default_Value
7555 or else
7556 A_Id = Aspect_Default_Component_Value)
7557 and then Is_Private_Type (T)
7558 then
7559 Preanalyze_Spec_Expression (End_Decl_Expr, Full_View (T));
7560 else
7561 Preanalyze_Spec_Expression (End_Decl_Expr, T);
7562 end if;
d97beb2f 7563
d9f6a4ee 7564 Err := not Fully_Conformant_Expressions (End_Decl_Expr, Freeze_Expr);
7565 end if;
55e8372b 7566
d9f6a4ee 7567 -- Output error message if error
55e8372b 7568
d9f6a4ee 7569 if Err then
7570 Error_Msg_NE
7571 ("visibility of aspect for& changes after freeze point",
7572 ASN, Ent);
7573 Error_Msg_NE
7574 ("info: & is frozen here, aspects evaluated at this point??",
7575 Freeze_Node (Ent), Ent);
7576 end if;
7577 end Check_Aspect_At_End_Of_Declarations;
55e8372b 7578
d9f6a4ee 7579 ----------------------------------
7580 -- Check_Aspect_At_Freeze_Point --
7581 ----------------------------------
9dc88aea 7582
d9f6a4ee 7583 procedure Check_Aspect_At_Freeze_Point (ASN : Node_Id) is
7584 Ident : constant Node_Id := Identifier (ASN);
7585 -- Identifier (use Entity field to save expression)
9dc88aea 7586
d9f6a4ee 7587 A_Id : constant Aspect_Id := Get_Aspect_Id (Chars (Ident));
9dc88aea 7588
d9f6a4ee 7589 T : Entity_Id := Empty;
7590 -- Type required for preanalyze call
9dc88aea 7591
d9f6a4ee 7592 begin
7593 -- On entry to this procedure, Entity (Ident) contains a copy of the
7594 -- original expression from the aspect, saved for this purpose.
9dc88aea 7595
d9f6a4ee 7596 -- On exit from this procedure Entity (Ident) is unchanged, still
7597 -- containing that copy, but Expression (Ident) is a preanalyzed copy
7598 -- of the expression, preanalyzed just after the freeze point.
d97beb2f 7599
d9f6a4ee 7600 -- Make a copy of the expression to be preanalyzed
d97beb2f 7601
d9f6a4ee 7602 Set_Expression (ASN, New_Copy_Tree (Entity (Ident)));
d97beb2f 7603
d9f6a4ee 7604 -- Find type for preanalyze call
d97beb2f 7605
d9f6a4ee 7606 case A_Id is
9dc88aea 7607
d9f6a4ee 7608 -- No_Aspect should be impossible
d97beb2f 7609
d9f6a4ee 7610 when No_Aspect =>
7611 raise Program_Error;
7612
7613 -- Aspects taking an optional boolean argument
d97beb2f 7614
d9f6a4ee 7615 when Boolean_Aspects |
7616 Library_Unit_Aspects =>
9dc88aea 7617
d9f6a4ee 7618 T := Standard_Boolean;
d7c2851f 7619
d9f6a4ee 7620 -- Aspects corresponding to attribute definition clauses
9dc88aea 7621
d9f6a4ee 7622 when Aspect_Address =>
7623 T := RTE (RE_Address);
9dc88aea 7624
d9f6a4ee 7625 when Aspect_Attach_Handler =>
7626 T := RTE (RE_Interrupt_ID);
d7c2851f 7627
d9f6a4ee 7628 when Aspect_Bit_Order | Aspect_Scalar_Storage_Order =>
7629 T := RTE (RE_Bit_Order);
d7c2851f 7630
d9f6a4ee 7631 when Aspect_Convention =>
7632 return;
d7c2851f 7633
d9f6a4ee 7634 when Aspect_CPU =>
7635 T := RTE (RE_CPU_Range);
d7c2851f 7636
d9f6a4ee 7637 -- Default_Component_Value is resolved with the component type
d7c2851f 7638
d9f6a4ee 7639 when Aspect_Default_Component_Value =>
7640 T := Component_Type (Entity (ASN));
d7c2851f 7641
d9f6a4ee 7642 -- Default_Value is resolved with the type entity in question
d7c2851f 7643
d9f6a4ee 7644 when Aspect_Default_Value =>
7645 T := Entity (ASN);
9dc88aea 7646
d9f6a4ee 7647 -- Depends is a delayed aspect because it mentiones names first
7648 -- introduced by aspect Global which is already delayed. There is
7649 -- no action to be taken with respect to the aspect itself as the
7650 -- analysis is done by the corresponding pragma.
9dc88aea 7651
d9f6a4ee 7652 when Aspect_Depends =>
7653 return;
9dc88aea 7654
d9f6a4ee 7655 when Aspect_Dispatching_Domain =>
7656 T := RTE (RE_Dispatching_Domain);
9dc88aea 7657
d9f6a4ee 7658 when Aspect_External_Tag =>
7659 T := Standard_String;
9dc88aea 7660
d9f6a4ee 7661 when Aspect_External_Name =>
7662 T := Standard_String;
9dc88aea 7663
d9f6a4ee 7664 -- Global is a delayed aspect because it may reference names that
7665 -- have not been declared yet. There is no action to be taken with
7666 -- respect to the aspect itself as the reference checking is done
7667 -- on the corresponding pragma.
9dc88aea 7668
d9f6a4ee 7669 when Aspect_Global =>
7670 return;
9dc88aea 7671
d9f6a4ee 7672 when Aspect_Link_Name =>
7673 T := Standard_String;
9dc88aea 7674
d9f6a4ee 7675 when Aspect_Priority | Aspect_Interrupt_Priority =>
7676 T := Standard_Integer;
d97beb2f 7677
d9f6a4ee 7678 when Aspect_Relative_Deadline =>
7679 T := RTE (RE_Time_Span);
d97beb2f 7680
d9f6a4ee 7681 when Aspect_Small =>
7682 T := Universal_Real;
490beba6 7683
d9f6a4ee 7684 -- For a simple storage pool, we have to retrieve the type of the
7685 -- pool object associated with the aspect's corresponding attribute
7686 -- definition clause.
490beba6 7687
d9f6a4ee 7688 when Aspect_Simple_Storage_Pool =>
7689 T := Etype (Expression (Aspect_Rep_Item (ASN)));
d97beb2f 7690
d9f6a4ee 7691 when Aspect_Storage_Pool =>
7692 T := Class_Wide_Type (RTE (RE_Root_Storage_Pool));
d97beb2f 7693
d9f6a4ee 7694 when Aspect_Alignment |
7695 Aspect_Component_Size |
7696 Aspect_Machine_Radix |
7697 Aspect_Object_Size |
7698 Aspect_Size |
7699 Aspect_Storage_Size |
7700 Aspect_Stream_Size |
7701 Aspect_Value_Size =>
7702 T := Any_Integer;
9dc88aea 7703
d9f6a4ee 7704 when Aspect_Synchronization =>
7705 return;
7d20685d 7706
d9f6a4ee 7707 -- Special case, the expression of these aspects is just an entity
7708 -- that does not need any resolution, so just analyze.
7d20685d 7709
d9f6a4ee 7710 when Aspect_Input |
7711 Aspect_Output |
7712 Aspect_Read |
7713 Aspect_Suppress |
7714 Aspect_Unsuppress |
7715 Aspect_Warnings |
7716 Aspect_Write =>
7717 Analyze (Expression (ASN));
7718 return;
7d20685d 7719
d9f6a4ee 7720 -- Same for Iterator aspects, where the expression is a function
7721 -- name. Legality rules are checked separately.
89f1e35c 7722
d9f6a4ee 7723 when Aspect_Constant_Indexing |
7724 Aspect_Default_Iterator |
7725 Aspect_Iterator_Element |
7726 Aspect_Variable_Indexing =>
7727 Analyze (Expression (ASN));
7728 return;
7d20685d 7729
d9f6a4ee 7730 -- Invariant/Predicate take boolean expressions
7d20685d 7731
d9f6a4ee 7732 when Aspect_Dynamic_Predicate |
7733 Aspect_Invariant |
7734 Aspect_Predicate |
7735 Aspect_Static_Predicate |
7736 Aspect_Type_Invariant =>
7737 T := Standard_Boolean;
7d20685d 7738
d9f6a4ee 7739 -- Here is the list of aspects that don't require delay analysis
89f1e35c 7740
d9f6a4ee 7741 when Aspect_Abstract_State |
7742 Aspect_Contract_Cases |
7743 Aspect_Dimension |
7744 Aspect_Dimension_System |
7745 Aspect_Implicit_Dereference |
d4e369ad 7746 Aspect_Initializes |
d9f6a4ee 7747 Aspect_Post |
7748 Aspect_Postcondition |
7749 Aspect_Pre |
7750 Aspect_Precondition |
7751 Aspect_Refined_Depends |
7752 Aspect_Refined_Global |
7753 Aspect_Refined_Post |
7754 Aspect_Refined_Pre |
9129c28f 7755 Aspect_Refined_State |
d9f6a4ee 7756 Aspect_SPARK_Mode |
7757 Aspect_Test_Case =>
7758 raise Program_Error;
2b184b2f 7759
d9f6a4ee 7760 end case;
2b184b2f 7761
d9f6a4ee 7762 -- Do the preanalyze call
2b184b2f 7763
d9f6a4ee 7764 Preanalyze_Spec_Expression (Expression (ASN), T);
7765 end Check_Aspect_At_Freeze_Point;
2b184b2f 7766
d9f6a4ee 7767 -----------------------------------
7768 -- Check_Constant_Address_Clause --
7769 -----------------------------------
2b184b2f 7770
d9f6a4ee 7771 procedure Check_Constant_Address_Clause
7772 (Expr : Node_Id;
7773 U_Ent : Entity_Id)
7774 is
7775 procedure Check_At_Constant_Address (Nod : Node_Id);
7776 -- Checks that the given node N represents a name whose 'Address is
7777 -- constant (in the same sense as OK_Constant_Address_Clause, i.e. the
7778 -- address value is the same at the point of declaration of U_Ent and at
7779 -- the time of elaboration of the address clause.
84ed7523 7780
d9f6a4ee 7781 procedure Check_Expr_Constants (Nod : Node_Id);
7782 -- Checks that Nod meets the requirements for a constant address clause
7783 -- in the sense of the enclosing procedure.
84ed7523 7784
d9f6a4ee 7785 procedure Check_List_Constants (Lst : List_Id);
7786 -- Check that all elements of list Lst meet the requirements for a
7787 -- constant address clause in the sense of the enclosing procedure.
84ed7523 7788
d9f6a4ee 7789 -------------------------------
7790 -- Check_At_Constant_Address --
7791 -------------------------------
84ed7523 7792
d9f6a4ee 7793 procedure Check_At_Constant_Address (Nod : Node_Id) is
7794 begin
7795 if Is_Entity_Name (Nod) then
7796 if Present (Address_Clause (Entity ((Nod)))) then
7797 Error_Msg_NE
7798 ("invalid address clause for initialized object &!",
7799 Nod, U_Ent);
7800 Error_Msg_NE
7801 ("address for& cannot" &
7802 " depend on another address clause! (RM 13.1(22))!",
7803 Nod, U_Ent);
84ed7523 7804
d9f6a4ee 7805 elsif In_Same_Source_Unit (Entity (Nod), U_Ent)
7806 and then Sloc (U_Ent) < Sloc (Entity (Nod))
7807 then
7808 Error_Msg_NE
7809 ("invalid address clause for initialized object &!",
7810 Nod, U_Ent);
7811 Error_Msg_Node_2 := U_Ent;
7812 Error_Msg_NE
7813 ("\& must be defined before & (RM 13.1(22))!",
7814 Nod, Entity (Nod));
7815 end if;
7d20685d 7816
d9f6a4ee 7817 elsif Nkind (Nod) = N_Selected_Component then
7818 declare
7819 T : constant Entity_Id := Etype (Prefix (Nod));
59f3e675 7820
d9f6a4ee 7821 begin
7822 if (Is_Record_Type (T)
7823 and then Has_Discriminants (T))
7824 or else
7825 (Is_Access_Type (T)
7826 and then Is_Record_Type (Designated_Type (T))
7827 and then Has_Discriminants (Designated_Type (T)))
7828 then
7829 Error_Msg_NE
7830 ("invalid address clause for initialized object &!",
7831 Nod, U_Ent);
7832 Error_Msg_N
7833 ("\address cannot depend on component" &
7834 " of discriminated record (RM 13.1(22))!",
7835 Nod);
7836 else
7837 Check_At_Constant_Address (Prefix (Nod));
7838 end if;
7839 end;
89cc7147 7840
d9f6a4ee 7841 elsif Nkind (Nod) = N_Indexed_Component then
7842 Check_At_Constant_Address (Prefix (Nod));
7843 Check_List_Constants (Expressions (Nod));
89cc7147 7844
84ed7523 7845 else
d9f6a4ee 7846 Check_Expr_Constants (Nod);
84ed7523 7847 end if;
d9f6a4ee 7848 end Check_At_Constant_Address;
81b424ac 7849
d9f6a4ee 7850 --------------------------
7851 -- Check_Expr_Constants --
7852 --------------------------
7b9b2f05 7853
d9f6a4ee 7854 procedure Check_Expr_Constants (Nod : Node_Id) is
7855 Loc_U_Ent : constant Source_Ptr := Sloc (U_Ent);
7856 Ent : Entity_Id := Empty;
7b9b2f05 7857
d9f6a4ee 7858 begin
7859 if Nkind (Nod) in N_Has_Etype
7860 and then Etype (Nod) = Any_Type
7b9b2f05 7861 then
d9f6a4ee 7862 return;
309c3053 7863 end if;
7864
d9f6a4ee 7865 case Nkind (Nod) is
7866 when N_Empty | N_Error =>
7867 return;
7d20685d 7868
d9f6a4ee 7869 when N_Identifier | N_Expanded_Name =>
7870 Ent := Entity (Nod);
7d20685d 7871
d9f6a4ee 7872 -- We need to look at the original node if it is different
7873 -- from the node, since we may have rewritten things and
7874 -- substituted an identifier representing the rewrite.
7d20685d 7875
d9f6a4ee 7876 if Original_Node (Nod) /= Nod then
7877 Check_Expr_Constants (Original_Node (Nod));
7d20685d 7878
d9f6a4ee 7879 -- If the node is an object declaration without initial
7880 -- value, some code has been expanded, and the expression
7881 -- is not constant, even if the constituents might be
7882 -- acceptable, as in A'Address + offset.
7d20685d 7883
d9f6a4ee 7884 if Ekind (Ent) = E_Variable
7885 and then
7886 Nkind (Declaration_Node (Ent)) = N_Object_Declaration
7887 and then
7888 No (Expression (Declaration_Node (Ent)))
7889 then
7890 Error_Msg_NE
7891 ("invalid address clause for initialized object &!",
7892 Nod, U_Ent);
89f1e35c 7893
d9f6a4ee 7894 -- If entity is constant, it may be the result of expanding
7895 -- a check. We must verify that its declaration appears
7896 -- before the object in question, else we also reject the
7897 -- address clause.
7d20685d 7898
d9f6a4ee 7899 elsif Ekind (Ent) = E_Constant
7900 and then In_Same_Source_Unit (Ent, U_Ent)
7901 and then Sloc (Ent) > Loc_U_Ent
7902 then
7903 Error_Msg_NE
7904 ("invalid address clause for initialized object &!",
7905 Nod, U_Ent);
7906 end if;
7d20685d 7907
d9f6a4ee 7908 return;
7909 end if;
7d20685d 7910
d9f6a4ee 7911 -- Otherwise look at the identifier and see if it is OK
7d20685d 7912
d9f6a4ee 7913 if Ekind_In (Ent, E_Named_Integer, E_Named_Real)
7914 or else Is_Type (Ent)
7915 then
7916 return;
7d20685d 7917
d9f6a4ee 7918 elsif
7919 Ekind (Ent) = E_Constant
7920 or else
7921 Ekind (Ent) = E_In_Parameter
7922 then
7923 -- This is the case where we must have Ent defined before
7924 -- U_Ent. Clearly if they are in different units this
7925 -- requirement is met since the unit containing Ent is
7926 -- already processed.
7d20685d 7927
d9f6a4ee 7928 if not In_Same_Source_Unit (Ent, U_Ent) then
7929 return;
7d20685d 7930
d9f6a4ee 7931 -- Otherwise location of Ent must be before the location
7932 -- of U_Ent, that's what prior defined means.
7d20685d 7933
d9f6a4ee 7934 elsif Sloc (Ent) < Loc_U_Ent then
7935 return;
6c545057 7936
d9f6a4ee 7937 else
7938 Error_Msg_NE
7939 ("invalid address clause for initialized object &!",
7940 Nod, U_Ent);
7941 Error_Msg_Node_2 := U_Ent;
7942 Error_Msg_NE
7943 ("\& must be defined before & (RM 13.1(22))!",
7944 Nod, Ent);
7945 end if;
37c6e44c 7946
d9f6a4ee 7947 elsif Nkind (Original_Node (Nod)) = N_Function_Call then
7948 Check_Expr_Constants (Original_Node (Nod));
6c545057 7949
d9f6a4ee 7950 else
7951 Error_Msg_NE
7952 ("invalid address clause for initialized object &!",
7953 Nod, U_Ent);
3cdbaa5a 7954
d9f6a4ee 7955 if Comes_From_Source (Ent) then
7956 Error_Msg_NE
7957 ("\reference to variable& not allowed"
7958 & " (RM 13.1(22))!", Nod, Ent);
7959 else
7960 Error_Msg_N
7961 ("non-static expression not allowed"
7962 & " (RM 13.1(22))!", Nod);
7963 end if;
7964 end if;
3cdbaa5a 7965
d9f6a4ee 7966 when N_Integer_Literal =>
7f694ca2 7967
d9f6a4ee 7968 -- If this is a rewritten unchecked conversion, in a system
7969 -- where Address is an integer type, always use the base type
7970 -- for a literal value. This is user-friendly and prevents
7971 -- order-of-elaboration issues with instances of unchecked
7972 -- conversion.
3cdbaa5a 7973
d9f6a4ee 7974 if Nkind (Original_Node (Nod)) = N_Function_Call then
7975 Set_Etype (Nod, Base_Type (Etype (Nod)));
7976 end if;
e1cedbae 7977
d9f6a4ee 7978 when N_Real_Literal |
7979 N_String_Literal |
7980 N_Character_Literal =>
7981 return;
7d20685d 7982
d9f6a4ee 7983 when N_Range =>
7984 Check_Expr_Constants (Low_Bound (Nod));
7985 Check_Expr_Constants (High_Bound (Nod));
231eb581 7986
d9f6a4ee 7987 when N_Explicit_Dereference =>
7988 Check_Expr_Constants (Prefix (Nod));
231eb581 7989
d9f6a4ee 7990 when N_Indexed_Component =>
7991 Check_Expr_Constants (Prefix (Nod));
7992 Check_List_Constants (Expressions (Nod));
7d20685d 7993
d9f6a4ee 7994 when N_Slice =>
7995 Check_Expr_Constants (Prefix (Nod));
7996 Check_Expr_Constants (Discrete_Range (Nod));
cb4c311d 7997
d9f6a4ee 7998 when N_Selected_Component =>
7999 Check_Expr_Constants (Prefix (Nod));
6144c105 8000
d9f6a4ee 8001 when N_Attribute_Reference =>
8002 if Nam_In (Attribute_Name (Nod), Name_Address,
8003 Name_Access,
8004 Name_Unchecked_Access,
8005 Name_Unrestricted_Access)
8006 then
8007 Check_At_Constant_Address (Prefix (Nod));
6144c105 8008
d9f6a4ee 8009 else
8010 Check_Expr_Constants (Prefix (Nod));
8011 Check_List_Constants (Expressions (Nod));
8012 end if;
a7a4a7c2 8013
d9f6a4ee 8014 when N_Aggregate =>
8015 Check_List_Constants (Component_Associations (Nod));
8016 Check_List_Constants (Expressions (Nod));
7d20685d 8017
d9f6a4ee 8018 when N_Component_Association =>
8019 Check_Expr_Constants (Expression (Nod));
e1cedbae 8020
d9f6a4ee 8021 when N_Extension_Aggregate =>
8022 Check_Expr_Constants (Ancestor_Part (Nod));
8023 Check_List_Constants (Component_Associations (Nod));
8024 Check_List_Constants (Expressions (Nod));
3cdbaa5a 8025
d9f6a4ee 8026 when N_Null =>
8027 return;
3cdbaa5a 8028
d9f6a4ee 8029 when N_Binary_Op | N_Short_Circuit | N_Membership_Test =>
8030 Check_Expr_Constants (Left_Opnd (Nod));
8031 Check_Expr_Constants (Right_Opnd (Nod));
e1cedbae 8032
d9f6a4ee 8033 when N_Unary_Op =>
8034 Check_Expr_Constants (Right_Opnd (Nod));
7f694ca2 8035
d9f6a4ee 8036 when N_Type_Conversion |
8037 N_Qualified_Expression |
8038 N_Allocator |
8039 N_Unchecked_Type_Conversion =>
8040 Check_Expr_Constants (Expression (Nod));
47a46747 8041
d9f6a4ee 8042 when N_Function_Call =>
8043 if not Is_Pure (Entity (Name (Nod))) then
8044 Error_Msg_NE
8045 ("invalid address clause for initialized object &!",
8046 Nod, U_Ent);
7f694ca2 8047
d9f6a4ee 8048 Error_Msg_NE
8049 ("\function & is not pure (RM 13.1(22))!",
8050 Nod, Entity (Name (Nod)));
b55f7641 8051
d9f6a4ee 8052 else
8053 Check_List_Constants (Parameter_Associations (Nod));
8054 end if;
b55f7641 8055
d9f6a4ee 8056 when N_Parameter_Association =>
8057 Check_Expr_Constants (Explicit_Actual_Parameter (Nod));
7d20685d 8058
d9f6a4ee 8059 when others =>
8060 Error_Msg_NE
8061 ("invalid address clause for initialized object &!",
8062 Nod, U_Ent);
8063 Error_Msg_NE
8064 ("\must be constant defined before& (RM 13.1(22))!",
8065 Nod, U_Ent);
8066 end case;
8067 end Check_Expr_Constants;
7d20685d 8068
d9f6a4ee 8069 --------------------------
8070 -- Check_List_Constants --
8071 --------------------------
89f1e35c 8072
d9f6a4ee 8073 procedure Check_List_Constants (Lst : List_Id) is
8074 Nod1 : Node_Id;
7d20685d 8075
d9f6a4ee 8076 begin
8077 if Present (Lst) then
8078 Nod1 := First (Lst);
8079 while Present (Nod1) loop
8080 Check_Expr_Constants (Nod1);
8081 Next (Nod1);
8082 end loop;
8083 end if;
8084 end Check_List_Constants;
81b424ac 8085
d9f6a4ee 8086 -- Start of processing for Check_Constant_Address_Clause
81b424ac 8087
d9f6a4ee 8088 begin
8089 -- If rep_clauses are to be ignored, no need for legality checks. In
8090 -- particular, no need to pester user about rep clauses that violate
8091 -- the rule on constant addresses, given that these clauses will be
8092 -- removed by Freeze before they reach the back end.
7d20685d 8093
d9f6a4ee 8094 if not Ignore_Rep_Clauses then
8095 Check_Expr_Constants (Expr);
8096 end if;
8097 end Check_Constant_Address_Clause;
7d20685d 8098
d9f6a4ee 8099 ----------------------------------------
8100 -- Check_Record_Representation_Clause --
8101 ----------------------------------------
85696508 8102
d9f6a4ee 8103 procedure Check_Record_Representation_Clause (N : Node_Id) is
8104 Loc : constant Source_Ptr := Sloc (N);
8105 Ident : constant Node_Id := Identifier (N);
8106 Rectype : Entity_Id;
8107 Fent : Entity_Id;
8108 CC : Node_Id;
8109 Fbit : Uint;
8110 Lbit : Uint;
8111 Hbit : Uint := Uint_0;
8112 Comp : Entity_Id;
8113 Pcomp : Entity_Id;
89f1e35c 8114
d9f6a4ee 8115 Max_Bit_So_Far : Uint;
8116 -- Records the maximum bit position so far. If all field positions
8117 -- are monotonically increasing, then we can skip the circuit for
8118 -- checking for overlap, since no overlap is possible.
85696508 8119
d9f6a4ee 8120 Tagged_Parent : Entity_Id := Empty;
8121 -- This is set in the case of a derived tagged type for which we have
8122 -- Is_Fully_Repped_Tagged_Type True (indicating that all components are
8123 -- positioned by record representation clauses). In this case we must
8124 -- check for overlap between components of this tagged type, and the
8125 -- components of its parent. Tagged_Parent will point to this parent
8126 -- type. For all other cases Tagged_Parent is left set to Empty.
7d20685d 8127
d9f6a4ee 8128 Parent_Last_Bit : Uint;
8129 -- Relevant only if Tagged_Parent is set, Parent_Last_Bit indicates the
8130 -- last bit position for any field in the parent type. We only need to
8131 -- check overlap for fields starting below this point.
7d20685d 8132
d9f6a4ee 8133 Overlap_Check_Required : Boolean;
8134 -- Used to keep track of whether or not an overlap check is required
7d20685d 8135
d9f6a4ee 8136 Overlap_Detected : Boolean := False;
8137 -- Set True if an overlap is detected
d6f39728 8138
d9f6a4ee 8139 Ccount : Natural := 0;
8140 -- Number of component clauses in record rep clause
d6f39728 8141
d9f6a4ee 8142 procedure Check_Component_Overlap (C1_Ent, C2_Ent : Entity_Id);
8143 -- Given two entities for record components or discriminants, checks
8144 -- if they have overlapping component clauses and issues errors if so.
d6f39728 8145
d9f6a4ee 8146 procedure Find_Component;
8147 -- Finds component entity corresponding to current component clause (in
8148 -- CC), and sets Comp to the entity, and Fbit/Lbit to the zero origin
8149 -- start/stop bits for the field. If there is no matching component or
8150 -- if the matching component does not have a component clause, then
8151 -- that's an error and Comp is set to Empty, but no error message is
8152 -- issued, since the message was already given. Comp is also set to
8153 -- Empty if the current "component clause" is in fact a pragma.
d6f39728 8154
d9f6a4ee 8155 -----------------------------
8156 -- Check_Component_Overlap --
8157 -----------------------------
8158
8159 procedure Check_Component_Overlap (C1_Ent, C2_Ent : Entity_Id) is
8160 CC1 : constant Node_Id := Component_Clause (C1_Ent);
8161 CC2 : constant Node_Id := Component_Clause (C2_Ent);
d6f39728 8162
d6f39728 8163 begin
d9f6a4ee 8164 if Present (CC1) and then Present (CC2) then
d6f39728 8165
d9f6a4ee 8166 -- Exclude odd case where we have two tag components in the same
8167 -- record, both at location zero. This seems a bit strange, but
8168 -- it seems to happen in some circumstances, perhaps on an error.
8169
8170 if Nam_In (Chars (C1_Ent), Name_uTag, Name_uTag) then
8171 return;
d6f39728 8172 end if;
8173
d9f6a4ee 8174 -- Here we check if the two fields overlap
8175
d6f39728 8176 declare
d9f6a4ee 8177 S1 : constant Uint := Component_Bit_Offset (C1_Ent);
8178 S2 : constant Uint := Component_Bit_Offset (C2_Ent);
8179 E1 : constant Uint := S1 + Esize (C1_Ent);
8180 E2 : constant Uint := S2 + Esize (C2_Ent);
d6f39728 8181
8182 begin
d9f6a4ee 8183 if E2 <= S1 or else E1 <= S2 then
8184 null;
d6f39728 8185 else
d9f6a4ee 8186 Error_Msg_Node_2 := Component_Name (CC2);
8187 Error_Msg_Sloc := Sloc (Error_Msg_Node_2);
8188 Error_Msg_Node_1 := Component_Name (CC1);
8189 Error_Msg_N
8190 ("component& overlaps & #", Component_Name (CC1));
8191 Overlap_Detected := True;
d6f39728 8192 end if;
8193 end;
d6f39728 8194 end if;
d9f6a4ee 8195 end Check_Component_Overlap;
d6f39728 8196
d9f6a4ee 8197 --------------------
8198 -- Find_Component --
8199 --------------------
9dfe12ae 8200
d9f6a4ee 8201 procedure Find_Component is
9dfe12ae 8202
d9f6a4ee 8203 procedure Search_Component (R : Entity_Id);
8204 -- Search components of R for a match. If found, Comp is set
9dfe12ae 8205
d9f6a4ee 8206 ----------------------
8207 -- Search_Component --
8208 ----------------------
e7b2d6bc 8209
d9f6a4ee 8210 procedure Search_Component (R : Entity_Id) is
8211 begin
8212 Comp := First_Component_Or_Discriminant (R);
8213 while Present (Comp) loop
e7b2d6bc 8214
d9f6a4ee 8215 -- Ignore error of attribute name for component name (we
8216 -- already gave an error message for this, so no need to
8217 -- complain here)
e7b2d6bc 8218
d9f6a4ee 8219 if Nkind (Component_Name (CC)) = N_Attribute_Reference then
8220 null;
8221 else
8222 exit when Chars (Comp) = Chars (Component_Name (CC));
9dfe12ae 8223 end if;
8224
d9f6a4ee 8225 Next_Component_Or_Discriminant (Comp);
8226 end loop;
8227 end Search_Component;
d6f39728 8228
d9f6a4ee 8229 -- Start of processing for Find_Component
d6f39728 8230
d9f6a4ee 8231 begin
8232 -- Return with Comp set to Empty if we have a pragma
d6f39728 8233
d9f6a4ee 8234 if Nkind (CC) = N_Pragma then
8235 Comp := Empty;
8236 return;
8237 end if;
d6f39728 8238
d9f6a4ee 8239 -- Search current record for matching component
d6f39728 8240
d9f6a4ee 8241 Search_Component (Rectype);
9dfe12ae 8242
d9f6a4ee 8243 -- If not found, maybe component of base type discriminant that is
8244 -- absent from statically constrained first subtype.
e7b2d6bc 8245
d9f6a4ee 8246 if No (Comp) then
8247 Search_Component (Base_Type (Rectype));
8248 end if;
e7b2d6bc 8249
d9f6a4ee 8250 -- If no component, or the component does not reference the component
8251 -- clause in question, then there was some previous error for which
8252 -- we already gave a message, so just return with Comp Empty.
d6f39728 8253
d9f6a4ee 8254 if No (Comp) or else Component_Clause (Comp) /= CC then
8255 Check_Error_Detected;
8256 Comp := Empty;
93735cb8 8257
d9f6a4ee 8258 -- Normal case where we have a component clause
93735cb8 8259
d9f6a4ee 8260 else
8261 Fbit := Component_Bit_Offset (Comp);
8262 Lbit := Fbit + Esize (Comp) - 1;
8263 end if;
8264 end Find_Component;
93735cb8 8265
d9f6a4ee 8266 -- Start of processing for Check_Record_Representation_Clause
d6f39728 8267
d9f6a4ee 8268 begin
8269 Find_Type (Ident);
8270 Rectype := Entity (Ident);
d6f39728 8271
d9f6a4ee 8272 if Rectype = Any_Type then
8273 return;
8274 else
8275 Rectype := Underlying_Type (Rectype);
8276 end if;
d6f39728 8277
d9f6a4ee 8278 -- See if we have a fully repped derived tagged type
d6f39728 8279
d9f6a4ee 8280 declare
8281 PS : constant Entity_Id := Parent_Subtype (Rectype);
d6f39728 8282
d9f6a4ee 8283 begin
8284 if Present (PS) and then Is_Fully_Repped_Tagged_Type (PS) then
8285 Tagged_Parent := PS;
d6f39728 8286
d9f6a4ee 8287 -- Find maximum bit of any component of the parent type
d6f39728 8288
d9f6a4ee 8289 Parent_Last_Bit := UI_From_Int (System_Address_Size - 1);
8290 Pcomp := First_Entity (Tagged_Parent);
8291 while Present (Pcomp) loop
8292 if Ekind_In (Pcomp, E_Discriminant, E_Component) then
8293 if Component_Bit_Offset (Pcomp) /= No_Uint
8294 and then Known_Static_Esize (Pcomp)
8295 then
8296 Parent_Last_Bit :=
8297 UI_Max
8298 (Parent_Last_Bit,
8299 Component_Bit_Offset (Pcomp) + Esize (Pcomp) - 1);
8300 end if;
8301
8302 Next_Entity (Pcomp);
d6f39728 8303 end if;
d9f6a4ee 8304 end loop;
8305 end if;
8306 end;
d6f39728 8307
d9f6a4ee 8308 -- All done if no component clauses
d6f39728 8309
d9f6a4ee 8310 CC := First (Component_Clauses (N));
d6f39728 8311
d9f6a4ee 8312 if No (CC) then
8313 return;
8314 end if;
d6f39728 8315
d9f6a4ee 8316 -- If a tag is present, then create a component clause that places it
8317 -- at the start of the record (otherwise gigi may place it after other
8318 -- fields that have rep clauses).
d6f39728 8319
d9f6a4ee 8320 Fent := First_Entity (Rectype);
d6f39728 8321
d9f6a4ee 8322 if Nkind (Fent) = N_Defining_Identifier
8323 and then Chars (Fent) = Name_uTag
8324 then
8325 Set_Component_Bit_Offset (Fent, Uint_0);
8326 Set_Normalized_Position (Fent, Uint_0);
8327 Set_Normalized_First_Bit (Fent, Uint_0);
8328 Set_Normalized_Position_Max (Fent, Uint_0);
8329 Init_Esize (Fent, System_Address_Size);
d6f39728 8330
d9f6a4ee 8331 Set_Component_Clause (Fent,
8332 Make_Component_Clause (Loc,
8333 Component_Name => Make_Identifier (Loc, Name_uTag),
d6f39728 8334
d9f6a4ee 8335 Position => Make_Integer_Literal (Loc, Uint_0),
8336 First_Bit => Make_Integer_Literal (Loc, Uint_0),
8337 Last_Bit =>
8338 Make_Integer_Literal (Loc,
8339 UI_From_Int (System_Address_Size))));
d6f39728 8340
d9f6a4ee 8341 Ccount := Ccount + 1;
8342 end if;
d6f39728 8343
d9f6a4ee 8344 Max_Bit_So_Far := Uint_Minus_1;
8345 Overlap_Check_Required := False;
d6f39728 8346
d9f6a4ee 8347 -- Process the component clauses
d6f39728 8348
d9f6a4ee 8349 while Present (CC) loop
8350 Find_Component;
d6f39728 8351
d9f6a4ee 8352 if Present (Comp) then
8353 Ccount := Ccount + 1;
d6f39728 8354
d9f6a4ee 8355 -- We need a full overlap check if record positions non-monotonic
d6f39728 8356
d9f6a4ee 8357 if Fbit <= Max_Bit_So_Far then
8358 Overlap_Check_Required := True;
8359 end if;
d6f39728 8360
d9f6a4ee 8361 Max_Bit_So_Far := Lbit;
d6f39728 8362
d9f6a4ee 8363 -- Check bit position out of range of specified size
01cb2726 8364
d9f6a4ee 8365 if Has_Size_Clause (Rectype)
8366 and then RM_Size (Rectype) <= Lbit
8367 then
8368 Error_Msg_N
8369 ("bit number out of range of specified size",
8370 Last_Bit (CC));
d6f39728 8371
d9f6a4ee 8372 -- Check for overlap with tag component
67278d60 8373
d9f6a4ee 8374 else
8375 if Is_Tagged_Type (Rectype)
8376 and then Fbit < System_Address_Size
8377 then
8378 Error_Msg_NE
8379 ("component overlaps tag field of&",
8380 Component_Name (CC), Rectype);
8381 Overlap_Detected := True;
8382 end if;
67278d60 8383
d9f6a4ee 8384 if Hbit < Lbit then
8385 Hbit := Lbit;
8386 end if;
8387 end if;
67278d60 8388
d9f6a4ee 8389 -- Check parent overlap if component might overlap parent field
67278d60 8390
d9f6a4ee 8391 if Present (Tagged_Parent) and then Fbit <= Parent_Last_Bit then
8392 Pcomp := First_Component_Or_Discriminant (Tagged_Parent);
8393 while Present (Pcomp) loop
8394 if not Is_Tag (Pcomp)
8395 and then Chars (Pcomp) /= Name_uParent
8396 then
8397 Check_Component_Overlap (Comp, Pcomp);
8398 end if;
67278d60 8399
d9f6a4ee 8400 Next_Component_Or_Discriminant (Pcomp);
8401 end loop;
8402 end if;
8403 end if;
67278d60 8404
d9f6a4ee 8405 Next (CC);
8406 end loop;
47495553 8407
d9f6a4ee 8408 -- Now that we have processed all the component clauses, check for
8409 -- overlap. We have to leave this till last, since the components can
8410 -- appear in any arbitrary order in the representation clause.
67278d60 8411
d9f6a4ee 8412 -- We do not need this check if all specified ranges were monotonic,
8413 -- as recorded by Overlap_Check_Required being False at this stage.
67278d60 8414
d9f6a4ee 8415 -- This first section checks if there are any overlapping entries at
8416 -- all. It does this by sorting all entries and then seeing if there are
8417 -- any overlaps. If there are none, then that is decisive, but if there
8418 -- are overlaps, they may still be OK (they may result from fields in
8419 -- different variants).
67278d60 8420
d9f6a4ee 8421 if Overlap_Check_Required then
8422 Overlap_Check1 : declare
67278d60 8423
d9f6a4ee 8424 OC_Fbit : array (0 .. Ccount) of Uint;
8425 -- First-bit values for component clauses, the value is the offset
8426 -- of the first bit of the field from start of record. The zero
8427 -- entry is for use in sorting.
47495553 8428
d9f6a4ee 8429 OC_Lbit : array (0 .. Ccount) of Uint;
8430 -- Last-bit values for component clauses, the value is the offset
8431 -- of the last bit of the field from start of record. The zero
8432 -- entry is for use in sorting.
8433
8434 OC_Count : Natural := 0;
8435 -- Count of entries in OC_Fbit and OC_Lbit
67278d60 8436
d9f6a4ee 8437 function OC_Lt (Op1, Op2 : Natural) return Boolean;
8438 -- Compare routine for Sort
67278d60 8439
d9f6a4ee 8440 procedure OC_Move (From : Natural; To : Natural);
8441 -- Move routine for Sort
67278d60 8442
d9f6a4ee 8443 package Sorting is new GNAT.Heap_Sort_G (OC_Move, OC_Lt);
67278d60 8444
d9f6a4ee 8445 -----------
8446 -- OC_Lt --
8447 -----------
67278d60 8448
d9f6a4ee 8449 function OC_Lt (Op1, Op2 : Natural) return Boolean is
67278d60 8450 begin
d9f6a4ee 8451 return OC_Fbit (Op1) < OC_Fbit (Op2);
8452 end OC_Lt;
67278d60 8453
d9f6a4ee 8454 -------------
8455 -- OC_Move --
8456 -------------
67278d60 8457
d9f6a4ee 8458 procedure OC_Move (From : Natural; To : Natural) is
8459 begin
8460 OC_Fbit (To) := OC_Fbit (From);
8461 OC_Lbit (To) := OC_Lbit (From);
8462 end OC_Move;
67278d60 8463
d9f6a4ee 8464 -- Start of processing for Overlap_Check
67278d60 8465
67278d60 8466 begin
d9f6a4ee 8467 CC := First (Component_Clauses (N));
8468 while Present (CC) loop
67278d60 8469
d9f6a4ee 8470 -- Exclude component clause already marked in error
67278d60 8471
d9f6a4ee 8472 if not Error_Posted (CC) then
8473 Find_Component;
8474
8475 if Present (Comp) then
8476 OC_Count := OC_Count + 1;
8477 OC_Fbit (OC_Count) := Fbit;
8478 OC_Lbit (OC_Count) := Lbit;
8479 end if;
67278d60 8480 end if;
8481
d9f6a4ee 8482 Next (CC);
67278d60 8483 end loop;
67278d60 8484
d9f6a4ee 8485 Sorting.Sort (OC_Count);
67278d60 8486
d9f6a4ee 8487 Overlap_Check_Required := False;
8488 for J in 1 .. OC_Count - 1 loop
8489 if OC_Lbit (J) >= OC_Fbit (J + 1) then
8490 Overlap_Check_Required := True;
8491 exit;
8492 end if;
8493 end loop;
8494 end Overlap_Check1;
8495 end if;
67278d60 8496
d9f6a4ee 8497 -- If Overlap_Check_Required is still True, then we have to do the full
8498 -- scale overlap check, since we have at least two fields that do
8499 -- overlap, and we need to know if that is OK since they are in
8500 -- different variant, or whether we have a definite problem.
67278d60 8501
d9f6a4ee 8502 if Overlap_Check_Required then
8503 Overlap_Check2 : declare
8504 C1_Ent, C2_Ent : Entity_Id;
8505 -- Entities of components being checked for overlap
67278d60 8506
d9f6a4ee 8507 Clist : Node_Id;
8508 -- Component_List node whose Component_Items are being checked
67278d60 8509
d9f6a4ee 8510 Citem : Node_Id;
8511 -- Component declaration for component being checked
67278d60 8512
d9f6a4ee 8513 begin
8514 C1_Ent := First_Entity (Base_Type (Rectype));
67278d60 8515
d9f6a4ee 8516 -- Loop through all components in record. For each component check
8517 -- for overlap with any of the preceding elements on the component
8518 -- list containing the component and also, if the component is in
8519 -- a variant, check against components outside the case structure.
8520 -- This latter test is repeated recursively up the variant tree.
67278d60 8521
d9f6a4ee 8522 Main_Component_Loop : while Present (C1_Ent) loop
8523 if not Ekind_In (C1_Ent, E_Component, E_Discriminant) then
8524 goto Continue_Main_Component_Loop;
8525 end if;
67278d60 8526
d9f6a4ee 8527 -- Skip overlap check if entity has no declaration node. This
8528 -- happens with discriminants in constrained derived types.
8529 -- Possibly we are missing some checks as a result, but that
8530 -- does not seem terribly serious.
67278d60 8531
d9f6a4ee 8532 if No (Declaration_Node (C1_Ent)) then
8533 goto Continue_Main_Component_Loop;
8534 end if;
67278d60 8535
d9f6a4ee 8536 Clist := Parent (List_Containing (Declaration_Node (C1_Ent)));
67278d60 8537
d9f6a4ee 8538 -- Loop through component lists that need checking. Check the
8539 -- current component list and all lists in variants above us.
67278d60 8540
d9f6a4ee 8541 Component_List_Loop : loop
67278d60 8542
d9f6a4ee 8543 -- If derived type definition, go to full declaration
8544 -- If at outer level, check discriminants if there are any.
67278d60 8545
d9f6a4ee 8546 if Nkind (Clist) = N_Derived_Type_Definition then
8547 Clist := Parent (Clist);
8548 end if;
67278d60 8549
d9f6a4ee 8550 -- Outer level of record definition, check discriminants
67278d60 8551
d9f6a4ee 8552 if Nkind_In (Clist, N_Full_Type_Declaration,
8553 N_Private_Type_Declaration)
67278d60 8554 then
d9f6a4ee 8555 if Has_Discriminants (Defining_Identifier (Clist)) then
8556 C2_Ent :=
8557 First_Discriminant (Defining_Identifier (Clist));
8558 while Present (C2_Ent) loop
8559 exit when C1_Ent = C2_Ent;
8560 Check_Component_Overlap (C1_Ent, C2_Ent);
8561 Next_Discriminant (C2_Ent);
8562 end loop;
8563 end if;
67278d60 8564
d9f6a4ee 8565 -- Record extension case
67278d60 8566
d9f6a4ee 8567 elsif Nkind (Clist) = N_Derived_Type_Definition then
8568 Clist := Empty;
67278d60 8569
d9f6a4ee 8570 -- Otherwise check one component list
67278d60 8571
d9f6a4ee 8572 else
8573 Citem := First (Component_Items (Clist));
8574 while Present (Citem) loop
8575 if Nkind (Citem) = N_Component_Declaration then
8576 C2_Ent := Defining_Identifier (Citem);
8577 exit when C1_Ent = C2_Ent;
8578 Check_Component_Overlap (C1_Ent, C2_Ent);
8579 end if;
67278d60 8580
d9f6a4ee 8581 Next (Citem);
8582 end loop;
8583 end if;
67278d60 8584
d9f6a4ee 8585 -- Check for variants above us (the parent of the Clist can
8586 -- be a variant, in which case its parent is a variant part,
8587 -- and the parent of the variant part is a component list
8588 -- whose components must all be checked against the current
8589 -- component for overlap).
67278d60 8590
d9f6a4ee 8591 if Nkind (Parent (Clist)) = N_Variant then
8592 Clist := Parent (Parent (Parent (Clist)));
67278d60 8593
d9f6a4ee 8594 -- Check for possible discriminant part in record, this
8595 -- is treated essentially as another level in the
8596 -- recursion. For this case the parent of the component
8597 -- list is the record definition, and its parent is the
8598 -- full type declaration containing the discriminant
8599 -- specifications.
8600
8601 elsif Nkind (Parent (Clist)) = N_Record_Definition then
8602 Clist := Parent (Parent ((Clist)));
8603
8604 -- If neither of these two cases, we are at the top of
8605 -- the tree.
8606
8607 else
8608 exit Component_List_Loop;
8609 end if;
8610 end loop Component_List_Loop;
67278d60 8611
d9f6a4ee 8612 <<Continue_Main_Component_Loop>>
8613 Next_Entity (C1_Ent);
67278d60 8614
d9f6a4ee 8615 end loop Main_Component_Loop;
8616 end Overlap_Check2;
67278d60 8617 end if;
8618
d9f6a4ee 8619 -- The following circuit deals with warning on record holes (gaps). We
8620 -- skip this check if overlap was detected, since it makes sense for the
8621 -- programmer to fix this illegality before worrying about warnings.
67278d60 8622
d9f6a4ee 8623 if not Overlap_Detected and Warn_On_Record_Holes then
8624 Record_Hole_Check : declare
8625 Decl : constant Node_Id := Declaration_Node (Base_Type (Rectype));
8626 -- Full declaration of record type
67278d60 8627
d9f6a4ee 8628 procedure Check_Component_List
8629 (CL : Node_Id;
8630 Sbit : Uint;
8631 DS : List_Id);
8632 -- Check component list CL for holes. The starting bit should be
8633 -- Sbit. which is zero for the main record component list and set
8634 -- appropriately for recursive calls for variants. DS is set to
8635 -- a list of discriminant specifications to be included in the
8636 -- consideration of components. It is No_List if none to consider.
67278d60 8637
d9f6a4ee 8638 --------------------------
8639 -- Check_Component_List --
8640 --------------------------
47495553 8641
d9f6a4ee 8642 procedure Check_Component_List
8643 (CL : Node_Id;
8644 Sbit : Uint;
8645 DS : List_Id)
8646 is
8647 Compl : Integer;
67278d60 8648
d9f6a4ee 8649 begin
8650 Compl := Integer (List_Length (Component_Items (CL)));
47495553 8651
d9f6a4ee 8652 if DS /= No_List then
8653 Compl := Compl + Integer (List_Length (DS));
8654 end if;
67278d60 8655
d9f6a4ee 8656 declare
8657 Comps : array (Natural range 0 .. Compl) of Entity_Id;
8658 -- Gather components (zero entry is for sort routine)
67278d60 8659
d9f6a4ee 8660 Ncomps : Natural := 0;
8661 -- Number of entries stored in Comps (starting at Comps (1))
67278d60 8662
d9f6a4ee 8663 Citem : Node_Id;
8664 -- One component item or discriminant specification
67278d60 8665
d9f6a4ee 8666 Nbit : Uint;
8667 -- Starting bit for next component
67278d60 8668
d9f6a4ee 8669 CEnt : Entity_Id;
8670 -- Component entity
67278d60 8671
d9f6a4ee 8672 Variant : Node_Id;
8673 -- One variant
67278d60 8674
d9f6a4ee 8675 function Lt (Op1, Op2 : Natural) return Boolean;
8676 -- Compare routine for Sort
67278d60 8677
d9f6a4ee 8678 procedure Move (From : Natural; To : Natural);
8679 -- Move routine for Sort
67278d60 8680
d9f6a4ee 8681 package Sorting is new GNAT.Heap_Sort_G (Move, Lt);
67278d60 8682
d9f6a4ee 8683 --------
8684 -- Lt --
8685 --------
67278d60 8686
d9f6a4ee 8687 function Lt (Op1, Op2 : Natural) return Boolean is
8688 begin
8689 return Component_Bit_Offset (Comps (Op1))
8690 <
8691 Component_Bit_Offset (Comps (Op2));
8692 end Lt;
67278d60 8693
d9f6a4ee 8694 ----------
8695 -- Move --
8696 ----------
67278d60 8697
d9f6a4ee 8698 procedure Move (From : Natural; To : Natural) is
8699 begin
8700 Comps (To) := Comps (From);
8701 end Move;
67278d60 8702
d9f6a4ee 8703 begin
8704 -- Gather discriminants into Comp
67278d60 8705
d9f6a4ee 8706 if DS /= No_List then
8707 Citem := First (DS);
8708 while Present (Citem) loop
8709 if Nkind (Citem) = N_Discriminant_Specification then
8710 declare
8711 Ent : constant Entity_Id :=
8712 Defining_Identifier (Citem);
8713 begin
8714 if Ekind (Ent) = E_Discriminant then
8715 Ncomps := Ncomps + 1;
8716 Comps (Ncomps) := Ent;
8717 end if;
8718 end;
8719 end if;
67278d60 8720
d9f6a4ee 8721 Next (Citem);
8722 end loop;
8723 end if;
67278d60 8724
d9f6a4ee 8725 -- Gather component entities into Comp
67278d60 8726
d9f6a4ee 8727 Citem := First (Component_Items (CL));
8728 while Present (Citem) loop
8729 if Nkind (Citem) = N_Component_Declaration then
8730 Ncomps := Ncomps + 1;
8731 Comps (Ncomps) := Defining_Identifier (Citem);
8732 end if;
67278d60 8733
d9f6a4ee 8734 Next (Citem);
8735 end loop;
67278d60 8736
d9f6a4ee 8737 -- Now sort the component entities based on the first bit.
8738 -- Note we already know there are no overlapping components.
67278d60 8739
d9f6a4ee 8740 Sorting.Sort (Ncomps);
67278d60 8741
d9f6a4ee 8742 -- Loop through entries checking for holes
67278d60 8743
d9f6a4ee 8744 Nbit := Sbit;
8745 for J in 1 .. Ncomps loop
8746 CEnt := Comps (J);
8747 Error_Msg_Uint_1 := Component_Bit_Offset (CEnt) - Nbit;
67278d60 8748
d9f6a4ee 8749 if Error_Msg_Uint_1 > 0 then
8750 Error_Msg_NE
8751 ("?H?^-bit gap before component&",
8752 Component_Name (Component_Clause (CEnt)), CEnt);
8753 end if;
67278d60 8754
d9f6a4ee 8755 Nbit := Component_Bit_Offset (CEnt) + Esize (CEnt);
8756 end loop;
67278d60 8757
d9f6a4ee 8758 -- Process variant parts recursively if present
67278d60 8759
d9f6a4ee 8760 if Present (Variant_Part (CL)) then
8761 Variant := First (Variants (Variant_Part (CL)));
8762 while Present (Variant) loop
8763 Check_Component_List
8764 (Component_List (Variant), Nbit, No_List);
8765 Next (Variant);
8766 end loop;
67278d60 8767 end if;
d9f6a4ee 8768 end;
8769 end Check_Component_List;
67278d60 8770
d9f6a4ee 8771 -- Start of processing for Record_Hole_Check
67278d60 8772
d9f6a4ee 8773 begin
8774 declare
8775 Sbit : Uint;
67278d60 8776
d9f6a4ee 8777 begin
8778 if Is_Tagged_Type (Rectype) then
8779 Sbit := UI_From_Int (System_Address_Size);
8780 else
8781 Sbit := Uint_0;
8782 end if;
8783
8784 if Nkind (Decl) = N_Full_Type_Declaration
8785 and then Nkind (Type_Definition (Decl)) = N_Record_Definition
8786 then
8787 Check_Component_List
8788 (Component_List (Type_Definition (Decl)),
8789 Sbit,
8790 Discriminant_Specifications (Decl));
67278d60 8791 end if;
d9f6a4ee 8792 end;
8793 end Record_Hole_Check;
67278d60 8794 end if;
8795
d9f6a4ee 8796 -- For records that have component clauses for all components, and whose
8797 -- size is less than or equal to 32, we need to know the size in the
8798 -- front end to activate possible packed array processing where the
8799 -- component type is a record.
67278d60 8800
d9f6a4ee 8801 -- At this stage Hbit + 1 represents the first unused bit from all the
8802 -- component clauses processed, so if the component clauses are
8803 -- complete, then this is the length of the record.
67278d60 8804
d9f6a4ee 8805 -- For records longer than System.Storage_Unit, and for those where not
8806 -- all components have component clauses, the back end determines the
8807 -- length (it may for example be appropriate to round up the size
8808 -- to some convenient boundary, based on alignment considerations, etc).
67278d60 8809
d9f6a4ee 8810 if Unknown_RM_Size (Rectype) and then Hbit + 1 <= 32 then
67278d60 8811
d9f6a4ee 8812 -- Nothing to do if at least one component has no component clause
67278d60 8813
d9f6a4ee 8814 Comp := First_Component_Or_Discriminant (Rectype);
8815 while Present (Comp) loop
8816 exit when No (Component_Clause (Comp));
8817 Next_Component_Or_Discriminant (Comp);
8818 end loop;
67278d60 8819
d9f6a4ee 8820 -- If we fall out of loop, all components have component clauses
8821 -- and so we can set the size to the maximum value.
67278d60 8822
d9f6a4ee 8823 if No (Comp) then
8824 Set_RM_Size (Rectype, Hbit + 1);
8825 end if;
8826 end if;
8827 end Check_Record_Representation_Clause;
67278d60 8828
d9f6a4ee 8829 ----------------
8830 -- Check_Size --
8831 ----------------
67278d60 8832
d9f6a4ee 8833 procedure Check_Size
8834 (N : Node_Id;
8835 T : Entity_Id;
8836 Siz : Uint;
8837 Biased : out Boolean)
8838 is
8839 UT : constant Entity_Id := Underlying_Type (T);
8840 M : Uint;
67278d60 8841
d9f6a4ee 8842 begin
8843 Biased := False;
67278d60 8844
d9f6a4ee 8845 -- Reject patently improper size values.
67278d60 8846
d9f6a4ee 8847 if Is_Elementary_Type (T)
8848 and then Siz > UI_From_Int (Int'Last)
8849 then
8850 Error_Msg_N ("Size value too large for elementary type", N);
67278d60 8851
d9f6a4ee 8852 if Nkind (Original_Node (N)) = N_Op_Expon then
8853 Error_Msg_N
8854 ("\maybe '* was meant, rather than '*'*", Original_Node (N));
8855 end if;
8856 end if;
67278d60 8857
d9f6a4ee 8858 -- Dismiss generic types
67278d60 8859
d9f6a4ee 8860 if Is_Generic_Type (T)
8861 or else
8862 Is_Generic_Type (UT)
8863 or else
8864 Is_Generic_Type (Root_Type (UT))
8865 then
8866 return;
67278d60 8867
d9f6a4ee 8868 -- Guard against previous errors
67278d60 8869
d9f6a4ee 8870 elsif No (UT) or else UT = Any_Type then
8871 Check_Error_Detected;
8872 return;
67278d60 8873
d9f6a4ee 8874 -- Check case of bit packed array
67278d60 8875
d9f6a4ee 8876 elsif Is_Array_Type (UT)
8877 and then Known_Static_Component_Size (UT)
8878 and then Is_Bit_Packed_Array (UT)
8879 then
8880 declare
8881 Asiz : Uint;
8882 Indx : Node_Id;
8883 Ityp : Entity_Id;
67278d60 8884
d9f6a4ee 8885 begin
8886 Asiz := Component_Size (UT);
8887 Indx := First_Index (UT);
8888 loop
8889 Ityp := Etype (Indx);
67278d60 8890
d9f6a4ee 8891 -- If non-static bound, then we are not in the business of
8892 -- trying to check the length, and indeed an error will be
8893 -- issued elsewhere, since sizes of non-static array types
8894 -- cannot be set implicitly or explicitly.
67278d60 8895
d9f6a4ee 8896 if not Is_Static_Subtype (Ityp) then
8897 return;
8898 end if;
67278d60 8899
d9f6a4ee 8900 -- Otherwise accumulate next dimension
67278d60 8901
d9f6a4ee 8902 Asiz := Asiz * (Expr_Value (Type_High_Bound (Ityp)) -
8903 Expr_Value (Type_Low_Bound (Ityp)) +
8904 Uint_1);
67278d60 8905
d9f6a4ee 8906 Next_Index (Indx);
8907 exit when No (Indx);
8908 end loop;
67278d60 8909
d9f6a4ee 8910 if Asiz <= Siz then
8911 return;
67278d60 8912
d9f6a4ee 8913 else
8914 Error_Msg_Uint_1 := Asiz;
8915 Error_Msg_NE
8916 ("size for& too small, minimum allowed is ^", N, T);
8917 Set_Esize (T, Asiz);
8918 Set_RM_Size (T, Asiz);
8919 end if;
8920 end;
67278d60 8921
d9f6a4ee 8922 -- All other composite types are ignored
67278d60 8923
d9f6a4ee 8924 elsif Is_Composite_Type (UT) then
8925 return;
47495553 8926
d9f6a4ee 8927 -- For fixed-point types, don't check minimum if type is not frozen,
8928 -- since we don't know all the characteristics of the type that can
8929 -- affect the size (e.g. a specified small) till freeze time.
47495553 8930
d9f6a4ee 8931 elsif Is_Fixed_Point_Type (UT)
8932 and then not Is_Frozen (UT)
8933 then
8934 null;
47495553 8935
d9f6a4ee 8936 -- Cases for which a minimum check is required
47495553 8937
d9f6a4ee 8938 else
8939 -- Ignore if specified size is correct for the type
47495553 8940
d9f6a4ee 8941 if Known_Esize (UT) and then Siz = Esize (UT) then
8942 return;
8943 end if;
47495553 8944
d9f6a4ee 8945 -- Otherwise get minimum size
47495553 8946
d9f6a4ee 8947 M := UI_From_Int (Minimum_Size (UT));
47495553 8948
d9f6a4ee 8949 if Siz < M then
47495553 8950
d9f6a4ee 8951 -- Size is less than minimum size, but one possibility remains
8952 -- that we can manage with the new size if we bias the type.
47495553 8953
d9f6a4ee 8954 M := UI_From_Int (Minimum_Size (UT, Biased => True));
47495553 8955
d9f6a4ee 8956 if Siz < M then
8957 Error_Msg_Uint_1 := M;
8958 Error_Msg_NE
8959 ("size for& too small, minimum allowed is ^", N, T);
8960 Set_Esize (T, M);
8961 Set_RM_Size (T, M);
8962 else
8963 Biased := True;
8964 end if;
8965 end if;
8966 end if;
8967 end Check_Size;
47495553 8968
d9f6a4ee 8969 --------------------------
8970 -- Freeze_Entity_Checks --
8971 --------------------------
47495553 8972
d9f6a4ee 8973 procedure Freeze_Entity_Checks (N : Node_Id) is
8974 E : constant Entity_Id := Entity (N);
47495553 8975
d9f6a4ee 8976 Non_Generic_Case : constant Boolean := Nkind (N) = N_Freeze_Entity;
8977 -- True in non-generic case. Some of the processing here is skipped
8978 -- for the generic case since it is not needed. Basically in the
8979 -- generic case, we only need to do stuff that might generate error
8980 -- messages or warnings.
8981 begin
8982 -- Remember that we are processing a freezing entity. Required to
8983 -- ensure correct decoration of internal entities associated with
8984 -- interfaces (see New_Overloaded_Entity).
47495553 8985
d9f6a4ee 8986 Inside_Freezing_Actions := Inside_Freezing_Actions + 1;
47495553 8987
d9f6a4ee 8988 -- For tagged types covering interfaces add internal entities that link
8989 -- the primitives of the interfaces with the primitives that cover them.
8990 -- Note: These entities were originally generated only when generating
8991 -- code because their main purpose was to provide support to initialize
8992 -- the secondary dispatch tables. They are now generated also when
8993 -- compiling with no code generation to provide ASIS the relationship
8994 -- between interface primitives and tagged type primitives. They are
8995 -- also used to locate primitives covering interfaces when processing
8996 -- generics (see Derive_Subprograms).
47495553 8997
d9f6a4ee 8998 -- This is not needed in the generic case
47495553 8999
d9f6a4ee 9000 if Ada_Version >= Ada_2005
9001 and then Non_Generic_Case
9002 and then Ekind (E) = E_Record_Type
9003 and then Is_Tagged_Type (E)
9004 and then not Is_Interface (E)
9005 and then Has_Interfaces (E)
9006 then
9007 -- This would be a good common place to call the routine that checks
9008 -- overriding of interface primitives (and thus factorize calls to
9009 -- Check_Abstract_Overriding located at different contexts in the
9010 -- compiler). However, this is not possible because it causes
9011 -- spurious errors in case of late overriding.
47495553 9012
d9f6a4ee 9013 Add_Internal_Interface_Entities (E);
9014 end if;
47495553 9015
d9f6a4ee 9016 -- Check CPP types
47495553 9017
d9f6a4ee 9018 if Ekind (E) = E_Record_Type
9019 and then Is_CPP_Class (E)
9020 and then Is_Tagged_Type (E)
9021 and then Tagged_Type_Expansion
d9f6a4ee 9022 then
9023 if CPP_Num_Prims (E) = 0 then
47495553 9024
d9f6a4ee 9025 -- If the CPP type has user defined components then it must import
9026 -- primitives from C++. This is required because if the C++ class
9027 -- has no primitives then the C++ compiler does not added the _tag
9028 -- component to the type.
47495553 9029
d9f6a4ee 9030 if First_Entity (E) /= Last_Entity (E) then
9031 Error_Msg_N
9032 ("'C'P'P type must import at least one primitive from C++??",
9033 E);
9034 end if;
9035 end if;
47495553 9036
d9f6a4ee 9037 -- Check that all its primitives are abstract or imported from C++.
9038 -- Check also availability of the C++ constructor.
47495553 9039
d9f6a4ee 9040 declare
9041 Has_Constructors : constant Boolean := Has_CPP_Constructors (E);
9042 Elmt : Elmt_Id;
9043 Error_Reported : Boolean := False;
9044 Prim : Node_Id;
47495553 9045
d9f6a4ee 9046 begin
9047 Elmt := First_Elmt (Primitive_Operations (E));
9048 while Present (Elmt) loop
9049 Prim := Node (Elmt);
47495553 9050
d9f6a4ee 9051 if Comes_From_Source (Prim) then
9052 if Is_Abstract_Subprogram (Prim) then
9053 null;
47495553 9054
d9f6a4ee 9055 elsif not Is_Imported (Prim)
9056 or else Convention (Prim) /= Convention_CPP
9057 then
9058 Error_Msg_N
9059 ("primitives of 'C'P'P types must be imported from C++ "
9060 & "or abstract??", Prim);
47495553 9061
d9f6a4ee 9062 elsif not Has_Constructors
9063 and then not Error_Reported
9064 then
9065 Error_Msg_Name_1 := Chars (E);
9066 Error_Msg_N
9067 ("??'C'P'P constructor required for type %", Prim);
9068 Error_Reported := True;
9069 end if;
9070 end if;
47495553 9071
d9f6a4ee 9072 Next_Elmt (Elmt);
9073 end loop;
9074 end;
9075 end if;
47495553 9076
d9f6a4ee 9077 -- Check Ada derivation of CPP type
47495553 9078
d9f6a4ee 9079 if Expander_Active -- why? losing errors in -gnatc mode???
9080 and then Tagged_Type_Expansion
9081 and then Ekind (E) = E_Record_Type
9082 and then Etype (E) /= E
9083 and then Is_CPP_Class (Etype (E))
9084 and then CPP_Num_Prims (Etype (E)) > 0
9085 and then not Is_CPP_Class (E)
9086 and then not Has_CPP_Constructors (Etype (E))
9087 then
9088 -- If the parent has C++ primitives but it has no constructor then
9089 -- check that all the primitives are overridden in this derivation;
9090 -- otherwise the constructor of the parent is needed to build the
9091 -- dispatch table.
47495553 9092
d9f6a4ee 9093 declare
9094 Elmt : Elmt_Id;
9095 Prim : Node_Id;
47495553 9096
9097 begin
d9f6a4ee 9098 Elmt := First_Elmt (Primitive_Operations (E));
9099 while Present (Elmt) loop
9100 Prim := Node (Elmt);
47495553 9101
d9f6a4ee 9102 if not Is_Abstract_Subprogram (Prim)
9103 and then No (Interface_Alias (Prim))
9104 and then Find_Dispatching_Type (Ultimate_Alias (Prim)) /= E
47495553 9105 then
d9f6a4ee 9106 Error_Msg_Name_1 := Chars (Etype (E));
9107 Error_Msg_N
9108 ("'C'P'P constructor required for parent type %", E);
9109 exit;
47495553 9110 end if;
d9f6a4ee 9111
9112 Next_Elmt (Elmt);
9113 end loop;
9114 end;
47495553 9115 end if;
9116
d9f6a4ee 9117 Inside_Freezing_Actions := Inside_Freezing_Actions - 1;
67278d60 9118
d9f6a4ee 9119 -- If we have a type with predicates, build predicate function. This
9120 -- is not needed in the generic casee
67278d60 9121
d9f6a4ee 9122 if Non_Generic_Case and then Is_Type (E) and then Has_Predicates (E) then
9123 Build_Predicate_Functions (E, N);
9124 end if;
67278d60 9125
d9f6a4ee 9126 -- If type has delayed aspects, this is where we do the preanalysis at
9127 -- the freeze point, as part of the consistent visibility check. Note
9128 -- that this must be done after calling Build_Predicate_Functions or
9129 -- Build_Invariant_Procedure since these subprograms fix occurrences of
9130 -- the subtype name in the saved expression so that they will not cause
9131 -- trouble in the preanalysis.
67278d60 9132
d9f6a4ee 9133 -- This is also not needed in the generic case
9134
9135 if Non_Generic_Case
9136 and then Has_Delayed_Aspects (E)
9137 and then Scope (E) = Current_Scope
9138 then
9139 -- Retrieve the visibility to the discriminants in order to properly
9140 -- analyze the aspects.
9141
9142 Push_Scope_And_Install_Discriminants (E);
9143
9144 declare
9145 Ritem : Node_Id;
9146
9147 begin
9148 -- Look for aspect specification entries for this entity
67278d60 9149
d9f6a4ee 9150 Ritem := First_Rep_Item (E);
9151 while Present (Ritem) loop
9152 if Nkind (Ritem) = N_Aspect_Specification
9153 and then Entity (Ritem) = E
9154 and then Is_Delayed_Aspect (Ritem)
9155 then
9156 Check_Aspect_At_Freeze_Point (Ritem);
9157 end if;
67278d60 9158
d9f6a4ee 9159 Next_Rep_Item (Ritem);
9160 end loop;
9161 end;
67278d60 9162
d9f6a4ee 9163 Uninstall_Discriminants_And_Pop_Scope (E);
67278d60 9164 end if;
67278d60 9165
d9f6a4ee 9166 -- For a record type, deal with variant parts. This has to be delayed
9167 -- to this point, because of the issue of statically precicated
9168 -- subtypes, which we have to ensure are frozen before checking
9169 -- choices, since we need to have the static choice list set.
d6f39728 9170
d9f6a4ee 9171 if Is_Record_Type (E) then
9172 Check_Variant_Part : declare
9173 D : constant Node_Id := Declaration_Node (E);
9174 T : Node_Id;
9175 C : Node_Id;
9176 VP : Node_Id;
d6f39728 9177
d9f6a4ee 9178 Others_Present : Boolean;
9179 pragma Warnings (Off, Others_Present);
9180 -- Indicates others present, not used in this case
d6f39728 9181
d9f6a4ee 9182 procedure Non_Static_Choice_Error (Choice : Node_Id);
9183 -- Error routine invoked by the generic instantiation below when
9184 -- the variant part has a non static choice.
f117057b 9185
d9f6a4ee 9186 procedure Process_Declarations (Variant : Node_Id);
9187 -- Processes declarations associated with a variant. We analyzed
9188 -- the declarations earlier (in Sem_Ch3.Analyze_Variant_Part),
9189 -- but we still need the recursive call to Check_Choices for any
9190 -- nested variant to get its choices properly processed. This is
9191 -- also where we expand out the choices if expansion is active.
1f526845 9192
d9f6a4ee 9193 package Variant_Choices_Processing is new
9194 Generic_Check_Choices
9195 (Process_Empty_Choice => No_OP,
9196 Process_Non_Static_Choice => Non_Static_Choice_Error,
9197 Process_Associated_Node => Process_Declarations);
9198 use Variant_Choices_Processing;
f117057b 9199
d9f6a4ee 9200 -----------------------------
9201 -- Non_Static_Choice_Error --
9202 -----------------------------
d6f39728 9203
d9f6a4ee 9204 procedure Non_Static_Choice_Error (Choice : Node_Id) is
9205 begin
9206 Flag_Non_Static_Expr
9207 ("choice given in variant part is not static!", Choice);
9208 end Non_Static_Choice_Error;
d6f39728 9209
d9f6a4ee 9210 --------------------------
9211 -- Process_Declarations --
9212 --------------------------
dba36b60 9213
d9f6a4ee 9214 procedure Process_Declarations (Variant : Node_Id) is
9215 CL : constant Node_Id := Component_List (Variant);
9216 VP : Node_Id;
dba36b60 9217
d9f6a4ee 9218 begin
9219 -- Check for static predicate present in this variant
ea61a7ea 9220
d9f6a4ee 9221 if Has_SP_Choice (Variant) then
ea61a7ea 9222
d9f6a4ee 9223 -- Here we expand. You might expect to find this call in
9224 -- Expand_N_Variant_Part, but that is called when we first
9225 -- see the variant part, and we cannot do this expansion
9226 -- earlier than the freeze point, since for statically
9227 -- predicated subtypes, the predicate is not known till
9228 -- the freeze point.
ea61a7ea 9229
d9f6a4ee 9230 -- Furthermore, we do this expansion even if the expander
9231 -- is not active, because other semantic processing, e.g.
9232 -- for aggregates, requires the expanded list of choices.
ea61a7ea 9233
d9f6a4ee 9234 -- If the expander is not active, then we can't just clobber
9235 -- the list since it would invalidate the ASIS -gnatct tree.
9236 -- So we have to rewrite the variant part with a Rewrite
9237 -- call that replaces it with a copy and clobber the copy.
9238
9239 if not Expander_Active then
9240 declare
9241 NewV : constant Node_Id := New_Copy (Variant);
9242 begin
9243 Set_Discrete_Choices
9244 (NewV, New_Copy_List (Discrete_Choices (Variant)));
9245 Rewrite (Variant, NewV);
9246 end;
9247 end if;
9248
9249 Expand_Static_Predicates_In_Choices (Variant);
ea61a7ea 9250 end if;
9251
d9f6a4ee 9252 -- We don't need to worry about the declarations in the variant
9253 -- (since they were analyzed by Analyze_Choices when we first
9254 -- encountered the variant), but we do need to take care of
9255 -- expansion of any nested variants.
ea61a7ea 9256
d9f6a4ee 9257 if not Null_Present (CL) then
9258 VP := Variant_Part (CL);
ea61a7ea 9259
d9f6a4ee 9260 if Present (VP) then
9261 Check_Choices
9262 (VP, Variants (VP), Etype (Name (VP)), Others_Present);
9263 end if;
9264 end if;
9265 end Process_Declarations;
ea61a7ea 9266
d9f6a4ee 9267 -- Start of processing for Check_Variant_Part
b9e61b2a 9268
d9f6a4ee 9269 begin
9270 -- Find component list
ea61a7ea 9271
d9f6a4ee 9272 C := Empty;
ea61a7ea 9273
d9f6a4ee 9274 if Nkind (D) = N_Full_Type_Declaration then
9275 T := Type_Definition (D);
ea61a7ea 9276
d9f6a4ee 9277 if Nkind (T) = N_Record_Definition then
9278 C := Component_List (T);
d6f39728 9279
d9f6a4ee 9280 elsif Nkind (T) = N_Derived_Type_Definition
9281 and then Present (Record_Extension_Part (T))
9282 then
9283 C := Component_List (Record_Extension_Part (T));
9284 end if;
9285 end if;
d6f39728 9286
d9f6a4ee 9287 -- Case of variant part present
d6f39728 9288
d9f6a4ee 9289 if Present (C) and then Present (Variant_Part (C)) then
9290 VP := Variant_Part (C);
ea61a7ea 9291
d9f6a4ee 9292 -- Check choices
ea61a7ea 9293
d9f6a4ee 9294 Check_Choices
9295 (VP, Variants (VP), Etype (Name (VP)), Others_Present);
ea61a7ea 9296
d9f6a4ee 9297 -- If the last variant does not contain the Others choice,
9298 -- replace it with an N_Others_Choice node since Gigi always
9299 -- wants an Others. Note that we do not bother to call Analyze
9300 -- on the modified variant part, since its only effect would be
9301 -- to compute the Others_Discrete_Choices node laboriously, and
9302 -- of course we already know the list of choices corresponding
9303 -- to the others choice (it's the list we're replacing!)
d6f39728 9304
d9f6a4ee 9305 -- We only want to do this if the expander is active, since
9306 -- we do not want to clobber the ASIS tree!
d6f39728 9307
d9f6a4ee 9308 if Expander_Active then
9309 declare
9310 Last_Var : constant Node_Id :=
9311 Last_Non_Pragma (Variants (VP));
d6f39728 9312
d9f6a4ee 9313 Others_Node : Node_Id;
d6f39728 9314
d9f6a4ee 9315 begin
9316 if Nkind (First (Discrete_Choices (Last_Var))) /=
9317 N_Others_Choice
9318 then
9319 Others_Node := Make_Others_Choice (Sloc (Last_Var));
9320 Set_Others_Discrete_Choices
9321 (Others_Node, Discrete_Choices (Last_Var));
9322 Set_Discrete_Choices
9323 (Last_Var, New_List (Others_Node));
9324 end if;
9325 end;
9326 end if;
d6f39728 9327 end if;
d9f6a4ee 9328 end Check_Variant_Part;
d6f39728 9329 end if;
d9f6a4ee 9330 end Freeze_Entity_Checks;
d6f39728 9331
9332 -------------------------
9333 -- Get_Alignment_Value --
9334 -------------------------
9335
9336 function Get_Alignment_Value (Expr : Node_Id) return Uint is
9337 Align : constant Uint := Static_Integer (Expr);
9338
9339 begin
9340 if Align = No_Uint then
9341 return No_Uint;
9342
9343 elsif Align <= 0 then
9344 Error_Msg_N ("alignment value must be positive", Expr);
9345 return No_Uint;
9346
9347 else
9348 for J in Int range 0 .. 64 loop
9349 declare
9350 M : constant Uint := Uint_2 ** J;
9351
9352 begin
9353 exit when M = Align;
9354
9355 if M > Align then
9356 Error_Msg_N
9357 ("alignment value must be power of 2", Expr);
9358 return No_Uint;
9359 end if;
9360 end;
9361 end loop;
9362
9363 return Align;
9364 end if;
9365 end Get_Alignment_Value;
9366
99a2d5bd 9367 -------------------------------------
9368 -- Inherit_Aspects_At_Freeze_Point --
9369 -------------------------------------
9370
9371 procedure Inherit_Aspects_At_Freeze_Point (Typ : Entity_Id) is
37c6e44c 9372
99a2d5bd 9373 function Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
9374 (Rep_Item : Node_Id) return Boolean;
9375 -- This routine checks if Rep_Item is either a pragma or an aspect
9376 -- specification node whose correponding pragma (if any) is present in
9377 -- the Rep Item chain of the entity it has been specified to.
9378
9379 --------------------------------------------------
9380 -- Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item --
9381 --------------------------------------------------
9382
9383 function Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
9384 (Rep_Item : Node_Id) return Boolean
9385 is
9386 begin
9387 return Nkind (Rep_Item) = N_Pragma
9388 or else Present_In_Rep_Item
9389 (Entity (Rep_Item), Aspect_Rep_Item (Rep_Item));
9390 end Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item;
9391
29a9d4be 9392 -- Start of processing for Inherit_Aspects_At_Freeze_Point
9393
99a2d5bd 9394 begin
9395 -- A representation item is either subtype-specific (Size and Alignment
9396 -- clauses) or type-related (all others). Subtype-specific aspects may
29a9d4be 9397 -- differ for different subtypes of the same type (RM 13.1.8).
99a2d5bd 9398
9399 -- A derived type inherits each type-related representation aspect of
9400 -- its parent type that was directly specified before the declaration of
29a9d4be 9401 -- the derived type (RM 13.1.15).
99a2d5bd 9402
9403 -- A derived subtype inherits each subtype-specific representation
9404 -- aspect of its parent subtype that was directly specified before the
29a9d4be 9405 -- declaration of the derived type (RM 13.1.15).
99a2d5bd 9406
9407 -- The general processing involves inheriting a representation aspect
9408 -- from a parent type whenever the first rep item (aspect specification,
9409 -- attribute definition clause, pragma) corresponding to the given
9410 -- representation aspect in the rep item chain of Typ, if any, isn't
9411 -- directly specified to Typ but to one of its parents.
9412
9413 -- ??? Note that, for now, just a limited number of representation
29a9d4be 9414 -- aspects have been inherited here so far. Many of them are
9415 -- still inherited in Sem_Ch3. This will be fixed soon. Here is
9416 -- a non- exhaustive list of aspects that likely also need to
9417 -- be moved to this routine: Alignment, Component_Alignment,
9418 -- Component_Size, Machine_Radix, Object_Size, Pack, Predicates,
99a2d5bd 9419 -- Preelaborable_Initialization, RM_Size and Small.
9420
9421 if Nkind (Parent (Typ)) = N_Private_Extension_Declaration then
9422 return;
9423 end if;
9424
9425 -- Ada_05/Ada_2005
9426
9427 if not Has_Rep_Item (Typ, Name_Ada_05, Name_Ada_2005, False)
9428 and then Has_Rep_Item (Typ, Name_Ada_05, Name_Ada_2005)
9429 and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
9430 (Get_Rep_Item (Typ, Name_Ada_05, Name_Ada_2005))
9431 then
9432 Set_Is_Ada_2005_Only (Typ);
9433 end if;
9434
9435 -- Ada_12/Ada_2012
9436
9437 if not Has_Rep_Item (Typ, Name_Ada_12, Name_Ada_2012, False)
9438 and then Has_Rep_Item (Typ, Name_Ada_12, Name_Ada_2012)
9439 and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
9440 (Get_Rep_Item (Typ, Name_Ada_12, Name_Ada_2012))
9441 then
9442 Set_Is_Ada_2012_Only (Typ);
9443 end if;
9444
9445 -- Atomic/Shared
9446
9447 if not Has_Rep_Item (Typ, Name_Atomic, Name_Shared, False)
9448 and then Has_Rep_Pragma (Typ, Name_Atomic, Name_Shared)
9449 and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
9450 (Get_Rep_Item (Typ, Name_Atomic, Name_Shared))
9451 then
9452 Set_Is_Atomic (Typ);
9453 Set_Treat_As_Volatile (Typ);
9454 Set_Is_Volatile (Typ);
9455 end if;
9456
29a9d4be 9457 -- Default_Component_Value
99a2d5bd 9458
9459 if Is_Array_Type (Typ)
9460 and then Has_Rep_Item (Typ, Name_Default_Component_Value, False)
9461 and then Has_Rep_Item (Typ, Name_Default_Component_Value)
9462 then
9463 Set_Default_Aspect_Component_Value (Typ,
9464 Default_Aspect_Component_Value
9465 (Entity (Get_Rep_Item (Typ, Name_Default_Component_Value))));
9466 end if;
9467
29a9d4be 9468 -- Default_Value
99a2d5bd 9469
9470 if Is_Scalar_Type (Typ)
9471 and then Has_Rep_Item (Typ, Name_Default_Value, False)
9472 and then Has_Rep_Item (Typ, Name_Default_Value)
9473 then
9474 Set_Default_Aspect_Value (Typ,
9475 Default_Aspect_Value
9476 (Entity (Get_Rep_Item (Typ, Name_Default_Value))));
9477 end if;
9478
9479 -- Discard_Names
9480
9481 if not Has_Rep_Item (Typ, Name_Discard_Names, False)
9482 and then Has_Rep_Item (Typ, Name_Discard_Names)
9483 and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
9484 (Get_Rep_Item (Typ, Name_Discard_Names))
9485 then
9486 Set_Discard_Names (Typ);
9487 end if;
9488
9489 -- Invariants
9490
9491 if not Has_Rep_Item (Typ, Name_Invariant, False)
9492 and then Has_Rep_Item (Typ, Name_Invariant)
9493 and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
9494 (Get_Rep_Item (Typ, Name_Invariant))
9495 then
9496 Set_Has_Invariants (Typ);
9497
9498 if Class_Present (Get_Rep_Item (Typ, Name_Invariant)) then
9499 Set_Has_Inheritable_Invariants (Typ);
9500 end if;
9501 end if;
9502
9503 -- Volatile
9504
9505 if not Has_Rep_Item (Typ, Name_Volatile, False)
9506 and then Has_Rep_Item (Typ, Name_Volatile)
9507 and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
9508 (Get_Rep_Item (Typ, Name_Volatile))
9509 then
9510 Set_Treat_As_Volatile (Typ);
9511 Set_Is_Volatile (Typ);
9512 end if;
9513
9514 -- Inheritance for derived types only
9515
9516 if Is_Derived_Type (Typ) then
9517 declare
9518 Bas_Typ : constant Entity_Id := Base_Type (Typ);
9519 Imp_Bas_Typ : constant Entity_Id := Implementation_Base_Type (Typ);
9520
9521 begin
9522 -- Atomic_Components
9523
9524 if not Has_Rep_Item (Typ, Name_Atomic_Components, False)
9525 and then Has_Rep_Item (Typ, Name_Atomic_Components)
9526 and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
9527 (Get_Rep_Item (Typ, Name_Atomic_Components))
9528 then
9529 Set_Has_Atomic_Components (Imp_Bas_Typ);
9530 end if;
9531
9532 -- Volatile_Components
9533
9534 if not Has_Rep_Item (Typ, Name_Volatile_Components, False)
9535 and then Has_Rep_Item (Typ, Name_Volatile_Components)
9536 and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
9537 (Get_Rep_Item (Typ, Name_Volatile_Components))
9538 then
9539 Set_Has_Volatile_Components (Imp_Bas_Typ);
9540 end if;
9541
9542 -- Finalize_Storage_Only.
9543
9544 if not Has_Rep_Pragma (Typ, Name_Finalize_Storage_Only, False)
9545 and then Has_Rep_Pragma (Typ, Name_Finalize_Storage_Only)
9546 then
9547 Set_Finalize_Storage_Only (Bas_Typ);
9548 end if;
9549
9550 -- Universal_Aliasing
9551
9552 if not Has_Rep_Item (Typ, Name_Universal_Aliasing, False)
9553 and then Has_Rep_Item (Typ, Name_Universal_Aliasing)
9554 and then Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item
9555 (Get_Rep_Item (Typ, Name_Universal_Aliasing))
9556 then
9557 Set_Universal_Aliasing (Imp_Bas_Typ);
9558 end if;
9559
9560 -- Record type specific aspects
9561
9562 if Is_Record_Type (Typ) then
29a9d4be 9563
99a2d5bd 9564 -- Bit_Order
9565
9566 if not Has_Rep_Item (Typ, Name_Bit_Order, False)
9567 and then Has_Rep_Item (Typ, Name_Bit_Order)
9568 then
9569 Set_Reverse_Bit_Order (Bas_Typ,
9570 Reverse_Bit_Order (Entity (Name
9571 (Get_Rep_Item (Typ, Name_Bit_Order)))));
9572 end if;
9573
9574 -- Scalar_Storage_Order
9575
9576 if not Has_Rep_Item (Typ, Name_Scalar_Storage_Order, False)
9577 and then Has_Rep_Item (Typ, Name_Scalar_Storage_Order)
9578 then
9579 Set_Reverse_Storage_Order (Bas_Typ,
9580 Reverse_Storage_Order (Entity (Name
9581 (Get_Rep_Item (Typ, Name_Scalar_Storage_Order)))));
9582 end if;
9583 end if;
9584 end;
9585 end if;
9586 end Inherit_Aspects_At_Freeze_Point;
9587
d6f39728 9588 ----------------
9589 -- Initialize --
9590 ----------------
9591
9592 procedure Initialize is
9593 begin
7717ea00 9594 Address_Clause_Checks.Init;
9595 Independence_Checks.Init;
d6f39728 9596 Unchecked_Conversions.Init;
9597 end Initialize;
9598
9599 -------------------------
9600 -- Is_Operational_Item --
9601 -------------------------
9602
9603 function Is_Operational_Item (N : Node_Id) return Boolean is
9604 begin
9605 if Nkind (N) /= N_Attribute_Definition_Clause then
9606 return False;
b9e61b2a 9607
d6f39728 9608 else
9609 declare
b9e61b2a 9610 Id : constant Attribute_Id := Get_Attribute_Id (Chars (N));
d6f39728 9611 begin
b9e61b2a 9612 return Id = Attribute_Input
d6f39728 9613 or else Id = Attribute_Output
9614 or else Id = Attribute_Read
f15731c4 9615 or else Id = Attribute_Write
9616 or else Id = Attribute_External_Tag;
d6f39728 9617 end;
9618 end if;
9619 end Is_Operational_Item;
9620
9621 ------------------
9622 -- Minimum_Size --
9623 ------------------
9624
9625 function Minimum_Size
9626 (T : Entity_Id;
d5b349fa 9627 Biased : Boolean := False) return Nat
d6f39728 9628 is
9629 Lo : Uint := No_Uint;
9630 Hi : Uint := No_Uint;
9631 LoR : Ureal := No_Ureal;
9632 HiR : Ureal := No_Ureal;
9633 LoSet : Boolean := False;
9634 HiSet : Boolean := False;
9635 B : Uint;
9636 S : Nat;
9637 Ancest : Entity_Id;
f15731c4 9638 R_Typ : constant Entity_Id := Root_Type (T);
d6f39728 9639
9640 begin
9641 -- If bad type, return 0
9642
9643 if T = Any_Type then
9644 return 0;
9645
9646 -- For generic types, just return zero. There cannot be any legitimate
9647 -- need to know such a size, but this routine may be called with a
9648 -- generic type as part of normal processing.
9649
f15731c4 9650 elsif Is_Generic_Type (R_Typ)
9651 or else R_Typ = Any_Type
9652 then
d6f39728 9653 return 0;
9654
93735cb8 9655 -- Access types. Normally an access type cannot have a size smaller
9656 -- than the size of System.Address. The exception is on VMS, where
9657 -- we have short and long addresses, and it is possible for an access
9658 -- type to have a short address size (and thus be less than the size
9659 -- of System.Address itself). We simply skip the check for VMS, and
fdd294d1 9660 -- leave it to the back end to do the check.
d6f39728 9661
9662 elsif Is_Access_Type (T) then
93735cb8 9663 if OpenVMS_On_Target then
9664 return 0;
9665 else
9666 return System_Address_Size;
9667 end if;
d6f39728 9668
9669 -- Floating-point types
9670
9671 elsif Is_Floating_Point_Type (T) then
f15731c4 9672 return UI_To_Int (Esize (R_Typ));
d6f39728 9673
9674 -- Discrete types
9675
9676 elsif Is_Discrete_Type (T) then
9677
fdd294d1 9678 -- The following loop is looking for the nearest compile time known
9679 -- bounds following the ancestor subtype chain. The idea is to find
9680 -- the most restrictive known bounds information.
d6f39728 9681
9682 Ancest := T;
9683 loop
9684 if Ancest = Any_Type or else Etype (Ancest) = Any_Type then
9685 return 0;
9686 end if;
9687
9688 if not LoSet then
9689 if Compile_Time_Known_Value (Type_Low_Bound (Ancest)) then
9690 Lo := Expr_Rep_Value (Type_Low_Bound (Ancest));
9691 LoSet := True;
9692 exit when HiSet;
9693 end if;
9694 end if;
9695
9696 if not HiSet then
9697 if Compile_Time_Known_Value (Type_High_Bound (Ancest)) then
9698 Hi := Expr_Rep_Value (Type_High_Bound (Ancest));
9699 HiSet := True;
9700 exit when LoSet;
9701 end if;
9702 end if;
9703
9704 Ancest := Ancestor_Subtype (Ancest);
9705
9706 if No (Ancest) then
9707 Ancest := Base_Type (T);
9708
9709 if Is_Generic_Type (Ancest) then
9710 return 0;
9711 end if;
9712 end if;
9713 end loop;
9714
9715 -- Fixed-point types. We can't simply use Expr_Value to get the
fdd294d1 9716 -- Corresponding_Integer_Value values of the bounds, since these do not
9717 -- get set till the type is frozen, and this routine can be called
9718 -- before the type is frozen. Similarly the test for bounds being static
9719 -- needs to include the case where we have unanalyzed real literals for
9720 -- the same reason.
d6f39728 9721
9722 elsif Is_Fixed_Point_Type (T) then
9723
fdd294d1 9724 -- The following loop is looking for the nearest compile time known
9725 -- bounds following the ancestor subtype chain. The idea is to find
9726 -- the most restrictive known bounds information.
d6f39728 9727
9728 Ancest := T;
9729 loop
9730 if Ancest = Any_Type or else Etype (Ancest) = Any_Type then
9731 return 0;
9732 end if;
9733
3062c401 9734 -- Note: In the following two tests for LoSet and HiSet, it may
9735 -- seem redundant to test for N_Real_Literal here since normally
9736 -- one would assume that the test for the value being known at
9737 -- compile time includes this case. However, there is a glitch.
9738 -- If the real literal comes from folding a non-static expression,
9739 -- then we don't consider any non- static expression to be known
9740 -- at compile time if we are in configurable run time mode (needed
9741 -- in some cases to give a clearer definition of what is and what
9742 -- is not accepted). So the test is indeed needed. Without it, we
9743 -- would set neither Lo_Set nor Hi_Set and get an infinite loop.
9744
d6f39728 9745 if not LoSet then
9746 if Nkind (Type_Low_Bound (Ancest)) = N_Real_Literal
9747 or else Compile_Time_Known_Value (Type_Low_Bound (Ancest))
9748 then
9749 LoR := Expr_Value_R (Type_Low_Bound (Ancest));
9750 LoSet := True;
9751 exit when HiSet;
9752 end if;
9753 end if;
9754
9755 if not HiSet then
9756 if Nkind (Type_High_Bound (Ancest)) = N_Real_Literal
9757 or else Compile_Time_Known_Value (Type_High_Bound (Ancest))
9758 then
9759 HiR := Expr_Value_R (Type_High_Bound (Ancest));
9760 HiSet := True;
9761 exit when LoSet;
9762 end if;
9763 end if;
9764
9765 Ancest := Ancestor_Subtype (Ancest);
9766
9767 if No (Ancest) then
9768 Ancest := Base_Type (T);
9769
9770 if Is_Generic_Type (Ancest) then
9771 return 0;
9772 end if;
9773 end if;
9774 end loop;
9775
9776 Lo := UR_To_Uint (LoR / Small_Value (T));
9777 Hi := UR_To_Uint (HiR / Small_Value (T));
9778
9779 -- No other types allowed
9780
9781 else
9782 raise Program_Error;
9783 end if;
9784
2866d595 9785 -- Fall through with Hi and Lo set. Deal with biased case
d6f39728 9786
cc46ff4b 9787 if (Biased
9788 and then not Is_Fixed_Point_Type (T)
9789 and then not (Is_Enumeration_Type (T)
9790 and then Has_Non_Standard_Rep (T)))
d6f39728 9791 or else Has_Biased_Representation (T)
9792 then
9793 Hi := Hi - Lo;
9794 Lo := Uint_0;
9795 end if;
9796
9797 -- Signed case. Note that we consider types like range 1 .. -1 to be
fdd294d1 9798 -- signed for the purpose of computing the size, since the bounds have
1a34e48c 9799 -- to be accommodated in the base type.
d6f39728 9800
9801 if Lo < 0 or else Hi < 0 then
9802 S := 1;
9803 B := Uint_1;
9804
da253936 9805 -- S = size, B = 2 ** (size - 1) (can accommodate -B .. +(B - 1))
9806 -- Note that we accommodate the case where the bounds cross. This
d6f39728 9807 -- can happen either because of the way the bounds are declared
9808 -- or because of the algorithm in Freeze_Fixed_Point_Type.
9809
9810 while Lo < -B
9811 or else Hi < -B
9812 or else Lo >= B
9813 or else Hi >= B
9814 loop
9815 B := Uint_2 ** S;
9816 S := S + 1;
9817 end loop;
9818
9819 -- Unsigned case
9820
9821 else
9822 -- If both bounds are positive, make sure that both are represen-
9823 -- table in the case where the bounds are crossed. This can happen
9824 -- either because of the way the bounds are declared, or because of
9825 -- the algorithm in Freeze_Fixed_Point_Type.
9826
9827 if Lo > Hi then
9828 Hi := Lo;
9829 end if;
9830
da253936 9831 -- S = size, (can accommodate 0 .. (2**size - 1))
d6f39728 9832
9833 S := 0;
9834 while Hi >= Uint_2 ** S loop
9835 S := S + 1;
9836 end loop;
9837 end if;
9838
9839 return S;
9840 end Minimum_Size;
9841
44e4341e 9842 ---------------------------
9843 -- New_Stream_Subprogram --
9844 ---------------------------
d6f39728 9845
44e4341e 9846 procedure New_Stream_Subprogram
9847 (N : Node_Id;
9848 Ent : Entity_Id;
9849 Subp : Entity_Id;
9850 Nam : TSS_Name_Type)
d6f39728 9851 is
9852 Loc : constant Source_Ptr := Sloc (N);
9dfe12ae 9853 Sname : constant Name_Id := Make_TSS_Name (Base_Type (Ent), Nam);
f15731c4 9854 Subp_Id : Entity_Id;
d6f39728 9855 Subp_Decl : Node_Id;
9856 F : Entity_Id;
9857 Etyp : Entity_Id;
9858
44e4341e 9859 Defer_Declaration : constant Boolean :=
9860 Is_Tagged_Type (Ent) or else Is_Private_Type (Ent);
9861 -- For a tagged type, there is a declaration for each stream attribute
9862 -- at the freeze point, and we must generate only a completion of this
9863 -- declaration. We do the same for private types, because the full view
9864 -- might be tagged. Otherwise we generate a declaration at the point of
9865 -- the attribute definition clause.
9866
f15731c4 9867 function Build_Spec return Node_Id;
9868 -- Used for declaration and renaming declaration, so that this is
9869 -- treated as a renaming_as_body.
9870
9871 ----------------
9872 -- Build_Spec --
9873 ----------------
9874
d5b349fa 9875 function Build_Spec return Node_Id is
44e4341e 9876 Out_P : constant Boolean := (Nam = TSS_Stream_Read);
9877 Formals : List_Id;
9878 Spec : Node_Id;
9879 T_Ref : constant Node_Id := New_Reference_To (Etyp, Loc);
9880
f15731c4 9881 begin
9dfe12ae 9882 Subp_Id := Make_Defining_Identifier (Loc, Sname);
f15731c4 9883
44e4341e 9884 -- S : access Root_Stream_Type'Class
9885
9886 Formals := New_List (
9887 Make_Parameter_Specification (Loc,
9888 Defining_Identifier =>
9889 Make_Defining_Identifier (Loc, Name_S),
9890 Parameter_Type =>
9891 Make_Access_Definition (Loc,
9892 Subtype_Mark =>
9893 New_Reference_To (
9894 Designated_Type (Etype (F)), Loc))));
9895
9896 if Nam = TSS_Stream_Input then
4bba0a8d 9897 Spec :=
9898 Make_Function_Specification (Loc,
9899 Defining_Unit_Name => Subp_Id,
9900 Parameter_Specifications => Formals,
9901 Result_Definition => T_Ref);
44e4341e 9902 else
9903 -- V : [out] T
f15731c4 9904
44e4341e 9905 Append_To (Formals,
9906 Make_Parameter_Specification (Loc,
9907 Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
9908 Out_Present => Out_P,
9909 Parameter_Type => T_Ref));
f15731c4 9910
d3ef794c 9911 Spec :=
9912 Make_Procedure_Specification (Loc,
9913 Defining_Unit_Name => Subp_Id,
9914 Parameter_Specifications => Formals);
44e4341e 9915 end if;
f15731c4 9916
44e4341e 9917 return Spec;
9918 end Build_Spec;
d6f39728 9919
44e4341e 9920 -- Start of processing for New_Stream_Subprogram
d6f39728 9921
44e4341e 9922 begin
9923 F := First_Formal (Subp);
9924
9925 if Ekind (Subp) = E_Procedure then
9926 Etyp := Etype (Next_Formal (F));
d6f39728 9927 else
44e4341e 9928 Etyp := Etype (Subp);
d6f39728 9929 end if;
f15731c4 9930
44e4341e 9931 -- Prepare subprogram declaration and insert it as an action on the
9932 -- clause node. The visibility for this entity is used to test for
9933 -- visibility of the attribute definition clause (in the sense of
9934 -- 8.3(23) as amended by AI-195).
9dfe12ae 9935
44e4341e 9936 if not Defer_Declaration then
f15731c4 9937 Subp_Decl :=
9938 Make_Subprogram_Declaration (Loc,
9939 Specification => Build_Spec);
44e4341e 9940
9941 -- For a tagged type, there is always a visible declaration for each
15ebb600 9942 -- stream TSS (it is a predefined primitive operation), and the
44e4341e 9943 -- completion of this declaration occurs at the freeze point, which is
9944 -- not always visible at places where the attribute definition clause is
9945 -- visible. So, we create a dummy entity here for the purpose of
9946 -- tracking the visibility of the attribute definition clause itself.
9947
9948 else
9949 Subp_Id :=
55868293 9950 Make_Defining_Identifier (Loc, New_External_Name (Sname, 'V'));
44e4341e 9951 Subp_Decl :=
9952 Make_Object_Declaration (Loc,
9953 Defining_Identifier => Subp_Id,
9954 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc));
f15731c4 9955 end if;
9956
44e4341e 9957 Insert_Action (N, Subp_Decl);
9958 Set_Entity (N, Subp_Id);
9959
d6f39728 9960 Subp_Decl :=
9961 Make_Subprogram_Renaming_Declaration (Loc,
f15731c4 9962 Specification => Build_Spec,
9963 Name => New_Reference_To (Subp, Loc));
d6f39728 9964
44e4341e 9965 if Defer_Declaration then
d6f39728 9966 Set_TSS (Base_Type (Ent), Subp_Id);
9967 else
9968 Insert_Action (N, Subp_Decl);
9969 Copy_TSS (Subp_Id, Base_Type (Ent));
9970 end if;
44e4341e 9971 end New_Stream_Subprogram;
d6f39728 9972
d6f39728 9973 ------------------------
9974 -- Rep_Item_Too_Early --
9975 ------------------------
9976
80d4fec4 9977 function Rep_Item_Too_Early (T : Entity_Id; N : Node_Id) return Boolean is
d6f39728 9978 begin
44e4341e 9979 -- Cannot apply non-operational rep items to generic types
d6f39728 9980
f15731c4 9981 if Is_Operational_Item (N) then
9982 return False;
9983
9984 elsif Is_Type (T)
d6f39728 9985 and then Is_Generic_Type (Root_Type (T))
9986 then
503f7fd3 9987 Error_Msg_N ("representation item not allowed for generic type", N);
d6f39728 9988 return True;
9989 end if;
9990
fdd294d1 9991 -- Otherwise check for incomplete type
d6f39728 9992
9993 if Is_Incomplete_Or_Private_Type (T)
9994 and then No (Underlying_Type (T))
d64221a7 9995 and then
9996 (Nkind (N) /= N_Pragma
60014bc9 9997 or else Get_Pragma_Id (N) /= Pragma_Import)
d6f39728 9998 then
9999 Error_Msg_N
10000 ("representation item must be after full type declaration", N);
10001 return True;
10002
1a34e48c 10003 -- If the type has incomplete components, a representation clause is
d6f39728 10004 -- illegal but stream attributes and Convention pragmas are correct.
10005
10006 elsif Has_Private_Component (T) then
f15731c4 10007 if Nkind (N) = N_Pragma then
d6f39728 10008 return False;
b9e61b2a 10009
d6f39728 10010 else
10011 Error_Msg_N
10012 ("representation item must appear after type is fully defined",
10013 N);
10014 return True;
10015 end if;
10016 else
10017 return False;
10018 end if;
10019 end Rep_Item_Too_Early;
10020
10021 -----------------------
10022 -- Rep_Item_Too_Late --
10023 -----------------------
10024
10025 function Rep_Item_Too_Late
10026 (T : Entity_Id;
10027 N : Node_Id;
d5b349fa 10028 FOnly : Boolean := False) return Boolean
d6f39728 10029 is
10030 S : Entity_Id;
10031 Parent_Type : Entity_Id;
10032
10033 procedure Too_Late;
d53a018a 10034 -- Output the too late message. Note that this is not considered a
10035 -- serious error, since the effect is simply that we ignore the
10036 -- representation clause in this case.
10037
10038 --------------
10039 -- Too_Late --
10040 --------------
d6f39728 10041
10042 procedure Too_Late is
10043 begin
ce4da1ed 10044 -- Other compilers seem more relaxed about rep items appearing too
10045 -- late. Since analysis tools typically don't care about rep items
10046 -- anyway, no reason to be too strict about this.
10047
a9cd517c 10048 if not Relaxed_RM_Semantics then
10049 Error_Msg_N ("|representation item appears too late!", N);
10050 end if;
d6f39728 10051 end Too_Late;
10052
10053 -- Start of processing for Rep_Item_Too_Late
10054
10055 begin
a3248fc4 10056 -- First make sure entity is not frozen (RM 13.1(9))
d6f39728 10057
10058 if Is_Frozen (T)
a3248fc4 10059
10060 -- Exclude imported types, which may be frozen if they appear in a
10061 -- representation clause for a local type.
10062
d6f39728 10063 and then not From_With_Type (T)
a3248fc4 10064
a9cd517c 10065 -- Exclude generated entities (not coming from source). The common
a3248fc4 10066 -- case is when we generate a renaming which prematurely freezes the
10067 -- renamed internal entity, but we still want to be able to set copies
10068 -- of attribute values such as Size/Alignment.
10069
10070 and then Comes_From_Source (T)
d6f39728 10071 then
10072 Too_Late;
10073 S := First_Subtype (T);
10074
10075 if Present (Freeze_Node (S)) then
10076 Error_Msg_NE
1e3532e7 10077 ("??no more representation items for }", Freeze_Node (S), S);
d6f39728 10078 end if;
10079
10080 return True;
10081
10082 -- Check for case of non-tagged derived type whose parent either has
10083 -- primitive operations, or is a by reference type (RM 13.1(10)).
10084
10085 elsif Is_Type (T)
10086 and then not FOnly
10087 and then Is_Derived_Type (T)
10088 and then not Is_Tagged_Type (T)
10089 then
10090 Parent_Type := Etype (Base_Type (T));
10091
10092 if Has_Primitive_Operations (Parent_Type) then
10093 Too_Late;
10094 Error_Msg_NE
10095 ("primitive operations already defined for&!", N, Parent_Type);
10096 return True;
10097
10098 elsif Is_By_Reference_Type (Parent_Type) then
10099 Too_Late;
10100 Error_Msg_NE
10101 ("parent type & is a by reference type!", N, Parent_Type);
10102 return True;
10103 end if;
10104 end if;
10105
3062c401 10106 -- No error, link item into head of chain of rep items for the entity,
10107 -- but avoid chaining if we have an overloadable entity, and the pragma
10108 -- is one that can apply to multiple overloaded entities.
10109
b9e61b2a 10110 if Is_Overloadable (T) and then Nkind (N) = N_Pragma then
fdd294d1 10111 declare
10112 Pname : constant Name_Id := Pragma_Name (N);
10113 begin
18393965 10114 if Nam_In (Pname, Name_Convention, Name_Import, Name_Export,
10115 Name_External, Name_Interface)
fdd294d1 10116 then
10117 return False;
10118 end if;
10119 end;
3062c401 10120 end if;
10121
fdd294d1 10122 Record_Rep_Item (T, N);
d6f39728 10123 return False;
10124 end Rep_Item_Too_Late;
10125
2072eaa9 10126 -------------------------------------
10127 -- Replace_Type_References_Generic --
10128 -------------------------------------
10129
10130 procedure Replace_Type_References_Generic (N : Node_Id; TName : Name_Id) is
10131
10132 function Replace_Node (N : Node_Id) return Traverse_Result;
10133 -- Processes a single node in the traversal procedure below, checking
10134 -- if node N should be replaced, and if so, doing the replacement.
10135
10136 procedure Replace_Type_Refs is new Traverse_Proc (Replace_Node);
10137 -- This instantiation provides the body of Replace_Type_References
10138
10139 ------------------
10140 -- Replace_Node --
10141 ------------------
10142
10143 function Replace_Node (N : Node_Id) return Traverse_Result is
10144 S : Entity_Id;
10145 P : Node_Id;
10146
10147 begin
10148 -- Case of identifier
10149
10150 if Nkind (N) = N_Identifier then
10151
10152 -- If not the type name, all done with this node
10153
10154 if Chars (N) /= TName then
10155 return Skip;
10156
10157 -- Otherwise do the replacement and we are done with this node
10158
10159 else
10160 Replace_Type_Reference (N);
10161 return Skip;
10162 end if;
10163
10164 -- Case of selected component (which is what a qualification
10165 -- looks like in the unanalyzed tree, which is what we have.
10166
10167 elsif Nkind (N) = N_Selected_Component then
10168
10169 -- If selector name is not our type, keeping going (we might
10170 -- still have an occurrence of the type in the prefix).
10171
10172 if Nkind (Selector_Name (N)) /= N_Identifier
10173 or else Chars (Selector_Name (N)) /= TName
10174 then
10175 return OK;
10176
10177 -- Selector name is our type, check qualification
10178
10179 else
10180 -- Loop through scopes and prefixes, doing comparison
10181
10182 S := Current_Scope;
10183 P := Prefix (N);
10184 loop
10185 -- Continue if no more scopes or scope with no name
10186
10187 if No (S) or else Nkind (S) not in N_Has_Chars then
10188 return OK;
10189 end if;
10190
10191 -- Do replace if prefix is an identifier matching the
10192 -- scope that we are currently looking at.
10193
10194 if Nkind (P) = N_Identifier
10195 and then Chars (P) = Chars (S)
10196 then
10197 Replace_Type_Reference (N);
10198 return Skip;
10199 end if;
10200
10201 -- Go check scope above us if prefix is itself of the
10202 -- form of a selected component, whose selector matches
10203 -- the scope we are currently looking at.
10204
10205 if Nkind (P) = N_Selected_Component
10206 and then Nkind (Selector_Name (P)) = N_Identifier
10207 and then Chars (Selector_Name (P)) = Chars (S)
10208 then
10209 S := Scope (S);
10210 P := Prefix (P);
10211
10212 -- For anything else, we don't have a match, so keep on
10213 -- going, there are still some weird cases where we may
10214 -- still have a replacement within the prefix.
10215
10216 else
10217 return OK;
10218 end if;
10219 end loop;
10220 end if;
10221
10222 -- Continue for any other node kind
10223
10224 else
10225 return OK;
10226 end if;
10227 end Replace_Node;
10228
10229 begin
10230 Replace_Type_Refs (N);
10231 end Replace_Type_References_Generic;
10232
d6f39728 10233 -------------------------
10234 -- Same_Representation --
10235 -------------------------
10236
10237 function Same_Representation (Typ1, Typ2 : Entity_Id) return Boolean is
10238 T1 : constant Entity_Id := Underlying_Type (Typ1);
10239 T2 : constant Entity_Id := Underlying_Type (Typ2);
10240
10241 begin
10242 -- A quick check, if base types are the same, then we definitely have
10243 -- the same representation, because the subtype specific representation
10244 -- attributes (Size and Alignment) do not affect representation from
10245 -- the point of view of this test.
10246
10247 if Base_Type (T1) = Base_Type (T2) then
10248 return True;
10249
10250 elsif Is_Private_Type (Base_Type (T2))
10251 and then Base_Type (T1) = Full_View (Base_Type (T2))
10252 then
10253 return True;
10254 end if;
10255
10256 -- Tagged types never have differing representations
10257
10258 if Is_Tagged_Type (T1) then
10259 return True;
10260 end if;
10261
10262 -- Representations are definitely different if conventions differ
10263
10264 if Convention (T1) /= Convention (T2) then
10265 return False;
10266 end if;
10267
ef0772bc 10268 -- Representations are different if component alignments or scalar
10269 -- storage orders differ.
d6f39728 10270
10271 if (Is_Record_Type (T1) or else Is_Array_Type (T1))
726fd56a 10272 and then
d6f39728 10273 (Is_Record_Type (T2) or else Is_Array_Type (T2))
ef0772bc 10274 and then
10275 (Component_Alignment (T1) /= Component_Alignment (T2)
10276 or else
726fd56a 10277 Reverse_Storage_Order (T1) /= Reverse_Storage_Order (T2))
d6f39728 10278 then
10279 return False;
10280 end if;
10281
10282 -- For arrays, the only real issue is component size. If we know the
10283 -- component size for both arrays, and it is the same, then that's
10284 -- good enough to know we don't have a change of representation.
10285
10286 if Is_Array_Type (T1) then
10287 if Known_Component_Size (T1)
10288 and then Known_Component_Size (T2)
10289 and then Component_Size (T1) = Component_Size (T2)
10290 then
9f1130cc 10291 if VM_Target = No_VM then
10292 return True;
10293
10294 -- In VM targets the representation of arrays with aliased
10295 -- components differs from arrays with non-aliased components
10296
10297 else
10298 return Has_Aliased_Components (Base_Type (T1))
0ba3592b 10299 =
10300 Has_Aliased_Components (Base_Type (T2));
9f1130cc 10301 end if;
d6f39728 10302 end if;
10303 end if;
10304
10305 -- Types definitely have same representation if neither has non-standard
10306 -- representation since default representations are always consistent.
10307 -- If only one has non-standard representation, and the other does not,
10308 -- then we consider that they do not have the same representation. They
10309 -- might, but there is no way of telling early enough.
10310
10311 if Has_Non_Standard_Rep (T1) then
10312 if not Has_Non_Standard_Rep (T2) then
10313 return False;
10314 end if;
10315 else
10316 return not Has_Non_Standard_Rep (T2);
10317 end if;
10318
fdd294d1 10319 -- Here the two types both have non-standard representation, and we need
10320 -- to determine if they have the same non-standard representation.
d6f39728 10321
10322 -- For arrays, we simply need to test if the component sizes are the
10323 -- same. Pragma Pack is reflected in modified component sizes, so this
10324 -- check also deals with pragma Pack.
10325
10326 if Is_Array_Type (T1) then
10327 return Component_Size (T1) = Component_Size (T2);
10328
10329 -- Tagged types always have the same representation, because it is not
10330 -- possible to specify different representations for common fields.
10331
10332 elsif Is_Tagged_Type (T1) then
10333 return True;
10334
10335 -- Case of record types
10336
10337 elsif Is_Record_Type (T1) then
10338
10339 -- Packed status must conform
10340
10341 if Is_Packed (T1) /= Is_Packed (T2) then
10342 return False;
10343
10344 -- Otherwise we must check components. Typ2 maybe a constrained
10345 -- subtype with fewer components, so we compare the components
10346 -- of the base types.
10347
10348 else
10349 Record_Case : declare
10350 CD1, CD2 : Entity_Id;
10351
10352 function Same_Rep return Boolean;
10353 -- CD1 and CD2 are either components or discriminants. This
ef0772bc 10354 -- function tests whether they have the same representation.
d6f39728 10355
80d4fec4 10356 --------------
10357 -- Same_Rep --
10358 --------------
10359
d6f39728 10360 function Same_Rep return Boolean is
10361 begin
10362 if No (Component_Clause (CD1)) then
10363 return No (Component_Clause (CD2));
d6f39728 10364 else
ef0772bc 10365 -- Note: at this point, component clauses have been
10366 -- normalized to the default bit order, so that the
10367 -- comparison of Component_Bit_Offsets is meaningful.
10368
d6f39728 10369 return
10370 Present (Component_Clause (CD2))
10371 and then
10372 Component_Bit_Offset (CD1) = Component_Bit_Offset (CD2)
10373 and then
10374 Esize (CD1) = Esize (CD2);
10375 end if;
10376 end Same_Rep;
10377
1e35409d 10378 -- Start of processing for Record_Case
d6f39728 10379
10380 begin
10381 if Has_Discriminants (T1) then
d6f39728 10382
9dfe12ae 10383 -- The number of discriminants may be different if the
10384 -- derived type has fewer (constrained by values). The
10385 -- invisible discriminants retain the representation of
10386 -- the original, so the discrepancy does not per se
10387 -- indicate a different representation.
10388
b9e61b2a 10389 CD1 := First_Discriminant (T1);
10390 CD2 := First_Discriminant (T2);
10391 while Present (CD1) and then Present (CD2) loop
d6f39728 10392 if not Same_Rep then
10393 return False;
10394 else
10395 Next_Discriminant (CD1);
10396 Next_Discriminant (CD2);
10397 end if;
10398 end loop;
10399 end if;
10400
10401 CD1 := First_Component (Underlying_Type (Base_Type (T1)));
10402 CD2 := First_Component (Underlying_Type (Base_Type (T2)));
d6f39728 10403 while Present (CD1) loop
10404 if not Same_Rep then
10405 return False;
10406 else
10407 Next_Component (CD1);
10408 Next_Component (CD2);
10409 end if;
10410 end loop;
10411
10412 return True;
10413 end Record_Case;
10414 end if;
10415
10416 -- For enumeration types, we must check each literal to see if the
10417 -- representation is the same. Note that we do not permit enumeration
1a34e48c 10418 -- representation clauses for Character and Wide_Character, so these
d6f39728 10419 -- cases were already dealt with.
10420
10421 elsif Is_Enumeration_Type (T1) then
d6f39728 10422 Enumeration_Case : declare
10423 L1, L2 : Entity_Id;
10424
10425 begin
10426 L1 := First_Literal (T1);
10427 L2 := First_Literal (T2);
d6f39728 10428 while Present (L1) loop
10429 if Enumeration_Rep (L1) /= Enumeration_Rep (L2) then
10430 return False;
10431 else
10432 Next_Literal (L1);
10433 Next_Literal (L2);
10434 end if;
10435 end loop;
10436
10437 return True;
d6f39728 10438 end Enumeration_Case;
10439
10440 -- Any other types have the same representation for these purposes
10441
10442 else
10443 return True;
10444 end if;
d6f39728 10445 end Same_Representation;
10446
b77e4501 10447 ----------------
10448 -- Set_Biased --
10449 ----------------
10450
10451 procedure Set_Biased
10452 (E : Entity_Id;
10453 N : Node_Id;
10454 Msg : String;
10455 Biased : Boolean := True)
10456 is
10457 begin
10458 if Biased then
10459 Set_Has_Biased_Representation (E);
10460
10461 if Warn_On_Biased_Representation then
10462 Error_Msg_NE
1e3532e7 10463 ("?B?" & Msg & " forces biased representation for&", N, E);
b77e4501 10464 end if;
10465 end if;
10466 end Set_Biased;
10467
d6f39728 10468 --------------------
10469 -- Set_Enum_Esize --
10470 --------------------
10471
10472 procedure Set_Enum_Esize (T : Entity_Id) is
10473 Lo : Uint;
10474 Hi : Uint;
10475 Sz : Nat;
10476
10477 begin
10478 Init_Alignment (T);
10479
10480 -- Find the minimum standard size (8,16,32,64) that fits
10481
10482 Lo := Enumeration_Rep (Entity (Type_Low_Bound (T)));
10483 Hi := Enumeration_Rep (Entity (Type_High_Bound (T)));
10484
10485 if Lo < 0 then
10486 if Lo >= -Uint_2**07 and then Hi < Uint_2**07 then
f15731c4 10487 Sz := Standard_Character_Size; -- May be > 8 on some targets
d6f39728 10488
10489 elsif Lo >= -Uint_2**15 and then Hi < Uint_2**15 then
10490 Sz := 16;
10491
10492 elsif Lo >= -Uint_2**31 and then Hi < Uint_2**31 then
10493 Sz := 32;
10494
10495 else pragma Assert (Lo >= -Uint_2**63 and then Hi < Uint_2**63);
10496 Sz := 64;
10497 end if;
10498
10499 else
10500 if Hi < Uint_2**08 then
f15731c4 10501 Sz := Standard_Character_Size; -- May be > 8 on some targets
d6f39728 10502
10503 elsif Hi < Uint_2**16 then
10504 Sz := 16;
10505
10506 elsif Hi < Uint_2**32 then
10507 Sz := 32;
10508
10509 else pragma Assert (Hi < Uint_2**63);
10510 Sz := 64;
10511 end if;
10512 end if;
10513
10514 -- That minimum is the proper size unless we have a foreign convention
10515 -- and the size required is 32 or less, in which case we bump the size
10516 -- up to 32. This is required for C and C++ and seems reasonable for
10517 -- all other foreign conventions.
10518
10519 if Has_Foreign_Convention (T)
10520 and then Esize (T) < Standard_Integer_Size
10521 then
10522 Init_Esize (T, Standard_Integer_Size);
d6f39728 10523 else
10524 Init_Esize (T, Sz);
10525 end if;
d6f39728 10526 end Set_Enum_Esize;
10527
83f8f0a6 10528 ------------------------------
10529 -- Validate_Address_Clauses --
10530 ------------------------------
10531
10532 procedure Validate_Address_Clauses is
10533 begin
10534 for J in Address_Clause_Checks.First .. Address_Clause_Checks.Last loop
10535 declare
10536 ACCR : Address_Clause_Check_Record
10537 renames Address_Clause_Checks.Table (J);
10538
d6da7448 10539 Expr : Node_Id;
10540
83f8f0a6 10541 X_Alignment : Uint;
10542 Y_Alignment : Uint;
10543
10544 X_Size : Uint;
10545 Y_Size : Uint;
10546
10547 begin
10548 -- Skip processing of this entry if warning already posted
10549
10550 if not Address_Warning_Posted (ACCR.N) then
d6da7448 10551 Expr := Original_Node (Expression (ACCR.N));
83f8f0a6 10552
d6da7448 10553 -- Get alignments
83f8f0a6 10554
d6da7448 10555 X_Alignment := Alignment (ACCR.X);
10556 Y_Alignment := Alignment (ACCR.Y);
83f8f0a6 10557
10558 -- Similarly obtain sizes
10559
d6da7448 10560 X_Size := Esize (ACCR.X);
10561 Y_Size := Esize (ACCR.Y);
83f8f0a6 10562
10563 -- Check for large object overlaying smaller one
10564
10565 if Y_Size > Uint_0
10566 and then X_Size > Uint_0
10567 and then X_Size > Y_Size
10568 then
d6da7448 10569 Error_Msg_NE
10570 ("?& overlays smaller object", ACCR.N, ACCR.X);
83f8f0a6 10571 Error_Msg_N
1e3532e7 10572 ("\??program execution may be erroneous", ACCR.N);
83f8f0a6 10573 Error_Msg_Uint_1 := X_Size;
10574 Error_Msg_NE
1e3532e7 10575 ("\??size of & is ^", ACCR.N, ACCR.X);
83f8f0a6 10576 Error_Msg_Uint_1 := Y_Size;
10577 Error_Msg_NE
1e3532e7 10578 ("\??size of & is ^", ACCR.N, ACCR.Y);
83f8f0a6 10579
d6da7448 10580 -- Check for inadequate alignment, both of the base object
10581 -- and of the offset, if any.
83f8f0a6 10582
d6da7448 10583 -- Note: we do not check the alignment if we gave a size
10584 -- warning, since it would likely be redundant.
83f8f0a6 10585
10586 elsif Y_Alignment /= Uint_0
d6da7448 10587 and then (Y_Alignment < X_Alignment
10588 or else (ACCR.Off
10589 and then
10590 Nkind (Expr) = N_Attribute_Reference
10591 and then
10592 Attribute_Name (Expr) = Name_Address
10593 and then
10594 Has_Compatible_Alignment
10595 (ACCR.X, Prefix (Expr))
10596 /= Known_Compatible))
83f8f0a6 10597 then
10598 Error_Msg_NE
1e3532e7 10599 ("??specified address for& may be inconsistent "
10600 & "with alignment", ACCR.N, ACCR.X);
83f8f0a6 10601 Error_Msg_N
1e3532e7 10602 ("\??program execution may be erroneous (RM 13.3(27))",
83f8f0a6 10603 ACCR.N);
10604 Error_Msg_Uint_1 := X_Alignment;
10605 Error_Msg_NE
1e3532e7 10606 ("\??alignment of & is ^", ACCR.N, ACCR.X);
83f8f0a6 10607 Error_Msg_Uint_1 := Y_Alignment;
10608 Error_Msg_NE
1e3532e7 10609 ("\??alignment of & is ^", ACCR.N, ACCR.Y);
d6da7448 10610 if Y_Alignment >= X_Alignment then
10611 Error_Msg_N
1e3532e7 10612 ("\??but offset is not multiple of alignment", ACCR.N);
d6da7448 10613 end if;
83f8f0a6 10614 end if;
10615 end if;
10616 end;
10617 end loop;
10618 end Validate_Address_Clauses;
10619
7717ea00 10620 ---------------------------
10621 -- Validate_Independence --
10622 ---------------------------
10623
10624 procedure Validate_Independence is
10625 SU : constant Uint := UI_From_Int (System_Storage_Unit);
10626 N : Node_Id;
10627 E : Entity_Id;
10628 IC : Boolean;
10629 Comp : Entity_Id;
10630 Addr : Node_Id;
10631 P : Node_Id;
10632
10633 procedure Check_Array_Type (Atyp : Entity_Id);
10634 -- Checks if the array type Atyp has independent components, and
10635 -- if not, outputs an appropriate set of error messages.
10636
10637 procedure No_Independence;
10638 -- Output message that independence cannot be guaranteed
10639
10640 function OK_Component (C : Entity_Id) return Boolean;
10641 -- Checks one component to see if it is independently accessible, and
10642 -- if so yields True, otherwise yields False if independent access
10643 -- cannot be guaranteed. This is a conservative routine, it only
10644 -- returns True if it knows for sure, it returns False if it knows
10645 -- there is a problem, or it cannot be sure there is no problem.
10646
10647 procedure Reason_Bad_Component (C : Entity_Id);
10648 -- Outputs continuation message if a reason can be determined for
10649 -- the component C being bad.
10650
10651 ----------------------
10652 -- Check_Array_Type --
10653 ----------------------
10654
10655 procedure Check_Array_Type (Atyp : Entity_Id) is
10656 Ctyp : constant Entity_Id := Component_Type (Atyp);
10657
10658 begin
10659 -- OK if no alignment clause, no pack, and no component size
10660
10661 if not Has_Component_Size_Clause (Atyp)
10662 and then not Has_Alignment_Clause (Atyp)
10663 and then not Is_Packed (Atyp)
10664 then
10665 return;
10666 end if;
10667
10668 -- Check actual component size
10669
10670 if not Known_Component_Size (Atyp)
10671 or else not (Addressable (Component_Size (Atyp))
10672 and then Component_Size (Atyp) < 64)
10673 or else Component_Size (Atyp) mod Esize (Ctyp) /= 0
10674 then
10675 No_Independence;
10676
10677 -- Bad component size, check reason
10678
10679 if Has_Component_Size_Clause (Atyp) then
b9e61b2a 10680 P := Get_Attribute_Definition_Clause
10681 (Atyp, Attribute_Component_Size);
7717ea00 10682
10683 if Present (P) then
10684 Error_Msg_Sloc := Sloc (P);
10685 Error_Msg_N ("\because of Component_Size clause#", N);
10686 return;
10687 end if;
10688 end if;
10689
10690 if Is_Packed (Atyp) then
10691 P := Get_Rep_Pragma (Atyp, Name_Pack);
10692
10693 if Present (P) then
10694 Error_Msg_Sloc := Sloc (P);
10695 Error_Msg_N ("\because of pragma Pack#", N);
10696 return;
10697 end if;
10698 end if;
10699
10700 -- No reason found, just return
10701
10702 return;
10703 end if;
10704
10705 -- Array type is OK independence-wise
10706
10707 return;
10708 end Check_Array_Type;
10709
10710 ---------------------
10711 -- No_Independence --
10712 ---------------------
10713
10714 procedure No_Independence is
10715 begin
10716 if Pragma_Name (N) = Name_Independent then
18393965 10717 Error_Msg_NE ("independence cannot be guaranteed for&", N, E);
7717ea00 10718 else
10719 Error_Msg_NE
10720 ("independent components cannot be guaranteed for&", N, E);
10721 end if;
10722 end No_Independence;
10723
10724 ------------------
10725 -- OK_Component --
10726 ------------------
10727
10728 function OK_Component (C : Entity_Id) return Boolean is
10729 Rec : constant Entity_Id := Scope (C);
10730 Ctyp : constant Entity_Id := Etype (C);
10731
10732 begin
10733 -- OK if no component clause, no Pack, and no alignment clause
10734
10735 if No (Component_Clause (C))
10736 and then not Is_Packed (Rec)
10737 and then not Has_Alignment_Clause (Rec)
10738 then
10739 return True;
10740 end if;
10741
10742 -- Here we look at the actual component layout. A component is
10743 -- addressable if its size is a multiple of the Esize of the
10744 -- component type, and its starting position in the record has
10745 -- appropriate alignment, and the record itself has appropriate
10746 -- alignment to guarantee the component alignment.
10747
10748 -- Make sure sizes are static, always assume the worst for any
10749 -- cases where we cannot check static values.
10750
10751 if not (Known_Static_Esize (C)
b9e61b2a 10752 and then
10753 Known_Static_Esize (Ctyp))
7717ea00 10754 then
10755 return False;
10756 end if;
10757
10758 -- Size of component must be addressable or greater than 64 bits
10759 -- and a multiple of bytes.
10760
b9e61b2a 10761 if not Addressable (Esize (C)) and then Esize (C) < Uint_64 then
7717ea00 10762 return False;
10763 end if;
10764
10765 -- Check size is proper multiple
10766
10767 if Esize (C) mod Esize (Ctyp) /= 0 then
10768 return False;
10769 end if;
10770
10771 -- Check alignment of component is OK
10772
10773 if not Known_Component_Bit_Offset (C)
10774 or else Component_Bit_Offset (C) < Uint_0
10775 or else Component_Bit_Offset (C) mod Esize (Ctyp) /= 0
10776 then
10777 return False;
10778 end if;
10779
10780 -- Check alignment of record type is OK
10781
10782 if not Known_Alignment (Rec)
10783 or else (Alignment (Rec) * SU) mod Esize (Ctyp) /= 0
10784 then
10785 return False;
10786 end if;
10787
10788 -- All tests passed, component is addressable
10789
10790 return True;
10791 end OK_Component;
10792
10793 --------------------------
10794 -- Reason_Bad_Component --
10795 --------------------------
10796
10797 procedure Reason_Bad_Component (C : Entity_Id) is
10798 Rec : constant Entity_Id := Scope (C);
10799 Ctyp : constant Entity_Id := Etype (C);
10800
10801 begin
10802 -- If component clause present assume that's the problem
10803
10804 if Present (Component_Clause (C)) then
10805 Error_Msg_Sloc := Sloc (Component_Clause (C));
10806 Error_Msg_N ("\because of Component_Clause#", N);
10807 return;
10808 end if;
10809
10810 -- If pragma Pack clause present, assume that's the problem
10811
10812 if Is_Packed (Rec) then
10813 P := Get_Rep_Pragma (Rec, Name_Pack);
10814
10815 if Present (P) then
10816 Error_Msg_Sloc := Sloc (P);
10817 Error_Msg_N ("\because of pragma Pack#", N);
10818 return;
10819 end if;
10820 end if;
10821
10822 -- See if record has bad alignment clause
10823
10824 if Has_Alignment_Clause (Rec)
10825 and then Known_Alignment (Rec)
10826 and then (Alignment (Rec) * SU) mod Esize (Ctyp) /= 0
10827 then
10828 P := Get_Attribute_Definition_Clause (Rec, Attribute_Alignment);
10829
10830 if Present (P) then
10831 Error_Msg_Sloc := Sloc (P);
10832 Error_Msg_N ("\because of Alignment clause#", N);
10833 end if;
10834 end if;
10835
10836 -- Couldn't find a reason, so return without a message
10837
10838 return;
10839 end Reason_Bad_Component;
10840
10841 -- Start of processing for Validate_Independence
10842
10843 begin
10844 for J in Independence_Checks.First .. Independence_Checks.Last loop
10845 N := Independence_Checks.Table (J).N;
10846 E := Independence_Checks.Table (J).E;
10847 IC := Pragma_Name (N) = Name_Independent_Components;
10848
10849 -- Deal with component case
10850
10851 if Ekind (E) = E_Discriminant or else Ekind (E) = E_Component then
10852 if not OK_Component (E) then
10853 No_Independence;
10854 Reason_Bad_Component (E);
10855 goto Continue;
10856 end if;
10857 end if;
10858
10859 -- Deal with record with Independent_Components
10860
10861 if IC and then Is_Record_Type (E) then
10862 Comp := First_Component_Or_Discriminant (E);
10863 while Present (Comp) loop
10864 if not OK_Component (Comp) then
10865 No_Independence;
10866 Reason_Bad_Component (Comp);
10867 goto Continue;
10868 end if;
10869
10870 Next_Component_Or_Discriminant (Comp);
10871 end loop;
10872 end if;
10873
10874 -- Deal with address clause case
10875
10876 if Is_Object (E) then
10877 Addr := Address_Clause (E);
10878
10879 if Present (Addr) then
10880 No_Independence;
10881 Error_Msg_Sloc := Sloc (Addr);
10882 Error_Msg_N ("\because of Address clause#", N);
10883 goto Continue;
10884 end if;
10885 end if;
10886
10887 -- Deal with independent components for array type
10888
10889 if IC and then Is_Array_Type (E) then
10890 Check_Array_Type (E);
10891 end if;
10892
10893 -- Deal with independent components for array object
10894
10895 if IC and then Is_Object (E) and then Is_Array_Type (Etype (E)) then
10896 Check_Array_Type (Etype (E));
10897 end if;
10898
10899 <<Continue>> null;
10900 end loop;
10901 end Validate_Independence;
10902
d6f39728 10903 -----------------------------------
10904 -- Validate_Unchecked_Conversion --
10905 -----------------------------------
10906
10907 procedure Validate_Unchecked_Conversion
10908 (N : Node_Id;
10909 Act_Unit : Entity_Id)
10910 is
10911 Source : Entity_Id;
10912 Target : Entity_Id;
10913 Vnode : Node_Id;
10914
10915 begin
10916 -- Obtain source and target types. Note that we call Ancestor_Subtype
10917 -- here because the processing for generic instantiation always makes
10918 -- subtypes, and we want the original frozen actual types.
10919
10920 -- If we are dealing with private types, then do the check on their
10921 -- fully declared counterparts if the full declarations have been
10922 -- encountered (they don't have to be visible, but they must exist!)
10923
10924 Source := Ancestor_Subtype (Etype (First_Formal (Act_Unit)));
10925
10926 if Is_Private_Type (Source)
10927 and then Present (Underlying_Type (Source))
10928 then
10929 Source := Underlying_Type (Source);
10930 end if;
10931
10932 Target := Ancestor_Subtype (Etype (Act_Unit));
10933
fdd294d1 10934 -- If either type is generic, the instantiation happens within a generic
95deda50 10935 -- unit, and there is nothing to check. The proper check will happen
10936 -- when the enclosing generic is instantiated.
d6f39728 10937
10938 if Is_Generic_Type (Source) or else Is_Generic_Type (Target) then
10939 return;
10940 end if;
10941
10942 if Is_Private_Type (Target)
10943 and then Present (Underlying_Type (Target))
10944 then
10945 Target := Underlying_Type (Target);
10946 end if;
10947
10948 -- Source may be unconstrained array, but not target
10949
b9e61b2a 10950 if Is_Array_Type (Target) and then not Is_Constrained (Target) then
d6f39728 10951 Error_Msg_N
10952 ("unchecked conversion to unconstrained array not allowed", N);
10953 return;
10954 end if;
10955
fbc67f84 10956 -- Warn if conversion between two different convention pointers
10957
10958 if Is_Access_Type (Target)
10959 and then Is_Access_Type (Source)
10960 and then Convention (Target) /= Convention (Source)
10961 and then Warn_On_Unchecked_Conversion
10962 then
fdd294d1 10963 -- Give warnings for subprogram pointers only on most targets. The
10964 -- exception is VMS, where data pointers can have different lengths
10965 -- depending on the pointer convention.
10966
10967 if Is_Access_Subprogram_Type (Target)
10968 or else Is_Access_Subprogram_Type (Source)
10969 or else OpenVMS_On_Target
10970 then
10971 Error_Msg_N
cb97ae5c 10972 ("?z?conversion between pointers with different conventions!",
1e3532e7 10973 N);
fdd294d1 10974 end if;
fbc67f84 10975 end if;
10976
3062c401 10977 -- Warn if one of the operands is Ada.Calendar.Time. Do not emit a
10978 -- warning when compiling GNAT-related sources.
10979
10980 if Warn_On_Unchecked_Conversion
10981 and then not In_Predefined_Unit (N)
10982 and then RTU_Loaded (Ada_Calendar)
10983 and then
10984 (Chars (Source) = Name_Time
10985 or else
10986 Chars (Target) = Name_Time)
10987 then
10988 -- If Ada.Calendar is loaded and the name of one of the operands is
10989 -- Time, there is a good chance that this is Ada.Calendar.Time.
10990
10991 declare
10992 Calendar_Time : constant Entity_Id :=
10993 Full_View (RTE (RO_CA_Time));
10994 begin
10995 pragma Assert (Present (Calendar_Time));
10996
b9e61b2a 10997 if Source = Calendar_Time or else Target = Calendar_Time then
3062c401 10998 Error_Msg_N
cb97ae5c 10999 ("?z?representation of 'Time values may change between " &
3062c401 11000 "'G'N'A'T versions", N);
11001 end if;
11002 end;
11003 end if;
11004
fdd294d1 11005 -- Make entry in unchecked conversion table for later processing by
11006 -- Validate_Unchecked_Conversions, which will check sizes and alignments
11007 -- (using values set by the back-end where possible). This is only done
11008 -- if the appropriate warning is active.
d6f39728 11009
9dfe12ae 11010 if Warn_On_Unchecked_Conversion then
11011 Unchecked_Conversions.Append
b9e61b2a 11012 (New_Val => UC_Entry'(Eloc => Sloc (N),
11013 Source => Source,
11014 Target => Target));
9dfe12ae 11015
11016 -- If both sizes are known statically now, then back end annotation
11017 -- is not required to do a proper check but if either size is not
11018 -- known statically, then we need the annotation.
11019
11020 if Known_Static_RM_Size (Source)
1e3532e7 11021 and then
11022 Known_Static_RM_Size (Target)
9dfe12ae 11023 then
11024 null;
11025 else
11026 Back_Annotate_Rep_Info := True;
11027 end if;
11028 end if;
d6f39728 11029
fdd294d1 11030 -- If unchecked conversion to access type, and access type is declared
95deda50 11031 -- in the same unit as the unchecked conversion, then set the flag
11032 -- No_Strict_Aliasing (no strict aliasing is implicit here)
28ed91d4 11033
11034 if Is_Access_Type (Target) and then
11035 In_Same_Source_Unit (Target, N)
11036 then
11037 Set_No_Strict_Aliasing (Implementation_Base_Type (Target));
11038 end if;
3d875462 11039
95deda50 11040 -- Generate N_Validate_Unchecked_Conversion node for back end in case
11041 -- the back end needs to perform special validation checks.
3d875462 11042
95deda50 11043 -- Shouldn't this be in Exp_Ch13, since the check only gets done if we
11044 -- have full expansion and the back end is called ???
3d875462 11045
11046 Vnode :=
11047 Make_Validate_Unchecked_Conversion (Sloc (N));
11048 Set_Source_Type (Vnode, Source);
11049 Set_Target_Type (Vnode, Target);
11050
fdd294d1 11051 -- If the unchecked conversion node is in a list, just insert before it.
11052 -- If not we have some strange case, not worth bothering about.
3d875462 11053
11054 if Is_List_Member (N) then
d6f39728 11055 Insert_After (N, Vnode);
11056 end if;
11057 end Validate_Unchecked_Conversion;
11058
11059 ------------------------------------
11060 -- Validate_Unchecked_Conversions --
11061 ------------------------------------
11062
11063 procedure Validate_Unchecked_Conversions is
11064 begin
11065 for N in Unchecked_Conversions.First .. Unchecked_Conversions.Last loop
11066 declare
11067 T : UC_Entry renames Unchecked_Conversions.Table (N);
11068
299480f9 11069 Eloc : constant Source_Ptr := T.Eloc;
11070 Source : constant Entity_Id := T.Source;
11071 Target : constant Entity_Id := T.Target;
d6f39728 11072
44705307 11073 Source_Siz : Uint;
11074 Target_Siz : Uint;
d6f39728 11075
11076 begin
fdd294d1 11077 -- This validation check, which warns if we have unequal sizes for
11078 -- unchecked conversion, and thus potentially implementation
d6f39728 11079 -- dependent semantics, is one of the few occasions on which we
fdd294d1 11080 -- use the official RM size instead of Esize. See description in
11081 -- Einfo "Handling of Type'Size Values" for details.
d6f39728 11082
f15731c4 11083 if Serious_Errors_Detected = 0
d6f39728 11084 and then Known_Static_RM_Size (Source)
11085 and then Known_Static_RM_Size (Target)
f25f4252 11086
11087 -- Don't do the check if warnings off for either type, note the
11088 -- deliberate use of OR here instead of OR ELSE to get the flag
11089 -- Warnings_Off_Used set for both types if appropriate.
11090
11091 and then not (Has_Warnings_Off (Source)
11092 or
11093 Has_Warnings_Off (Target))
d6f39728 11094 then
11095 Source_Siz := RM_Size (Source);
11096 Target_Siz := RM_Size (Target);
11097
11098 if Source_Siz /= Target_Siz then
299480f9 11099 Error_Msg
cb97ae5c 11100 ("?z?types for unchecked conversion have different sizes!",
299480f9 11101 Eloc);
d6f39728 11102
11103 if All_Errors_Mode then
11104 Error_Msg_Name_1 := Chars (Source);
11105 Error_Msg_Uint_1 := Source_Siz;
11106 Error_Msg_Name_2 := Chars (Target);
11107 Error_Msg_Uint_2 := Target_Siz;
cb97ae5c 11108 Error_Msg ("\size of % is ^, size of % is ^?z?", Eloc);
d6f39728 11109
11110 Error_Msg_Uint_1 := UI_Abs (Source_Siz - Target_Siz);
11111
11112 if Is_Discrete_Type (Source)
b9e61b2a 11113 and then
11114 Is_Discrete_Type (Target)
d6f39728 11115 then
11116 if Source_Siz > Target_Siz then
299480f9 11117 Error_Msg
cb97ae5c 11118 ("\?z?^ high order bits of source will "
1e3532e7 11119 & "be ignored!", Eloc);
d6f39728 11120
9dfe12ae 11121 elsif Is_Unsigned_Type (Source) then
299480f9 11122 Error_Msg
cb97ae5c 11123 ("\?z?source will be extended with ^ high order "
1e3532e7 11124 & "zero bits?!", Eloc);
d6f39728 11125
11126 else
299480f9 11127 Error_Msg
cb97ae5c 11128 ("\?z?source will be extended with ^ high order "
1e3532e7 11129 & "sign bits!", Eloc);
d6f39728 11130 end if;
11131
11132 elsif Source_Siz < Target_Siz then
11133 if Is_Discrete_Type (Target) then
11134 if Bytes_Big_Endian then
299480f9 11135 Error_Msg
cb97ae5c 11136 ("\?z?target value will include ^ undefined "
1e3532e7 11137 & "low order bits!", Eloc);
d6f39728 11138 else
299480f9 11139 Error_Msg
cb97ae5c 11140 ("\?z?target value will include ^ undefined "
1e3532e7 11141 & "high order bits!", Eloc);
d6f39728 11142 end if;
11143
11144 else
299480f9 11145 Error_Msg
cb97ae5c 11146 ("\?z?^ trailing bits of target value will be "
1e3532e7 11147 & "undefined!", Eloc);
d6f39728 11148 end if;
11149
11150 else pragma Assert (Source_Siz > Target_Siz);
299480f9 11151 Error_Msg
cb97ae5c 11152 ("\?z?^ trailing bits of source will be ignored!",
299480f9 11153 Eloc);
d6f39728 11154 end if;
11155 end if;
d6f39728 11156 end if;
11157 end if;
11158
11159 -- If both types are access types, we need to check the alignment.
11160 -- If the alignment of both is specified, we can do it here.
11161
f15731c4 11162 if Serious_Errors_Detected = 0
d6f39728 11163 and then Ekind (Source) in Access_Kind
11164 and then Ekind (Target) in Access_Kind
11165 and then Target_Strict_Alignment
11166 and then Present (Designated_Type (Source))
11167 and then Present (Designated_Type (Target))
11168 then
11169 declare
11170 D_Source : constant Entity_Id := Designated_Type (Source);
11171 D_Target : constant Entity_Id := Designated_Type (Target);
11172
11173 begin
11174 if Known_Alignment (D_Source)
b9e61b2a 11175 and then
11176 Known_Alignment (D_Target)
d6f39728 11177 then
11178 declare
11179 Source_Align : constant Uint := Alignment (D_Source);
11180 Target_Align : constant Uint := Alignment (D_Target);
11181
11182 begin
11183 if Source_Align < Target_Align
11184 and then not Is_Tagged_Type (D_Source)
f25f4252 11185
11186 -- Suppress warning if warnings suppressed on either
11187 -- type or either designated type. Note the use of
11188 -- OR here instead of OR ELSE. That is intentional,
11189 -- we would like to set flag Warnings_Off_Used in
11190 -- all types for which warnings are suppressed.
11191
11192 and then not (Has_Warnings_Off (D_Source)
11193 or
11194 Has_Warnings_Off (D_Target)
11195 or
11196 Has_Warnings_Off (Source)
11197 or
11198 Has_Warnings_Off (Target))
d6f39728 11199 then
d6f39728 11200 Error_Msg_Uint_1 := Target_Align;
11201 Error_Msg_Uint_2 := Source_Align;
299480f9 11202 Error_Msg_Node_1 := D_Target;
d6f39728 11203 Error_Msg_Node_2 := D_Source;
299480f9 11204 Error_Msg
cb97ae5c 11205 ("?z?alignment of & (^) is stricter than "
1e3532e7 11206 & "alignment of & (^)!", Eloc);
f25f4252 11207 Error_Msg
cb97ae5c 11208 ("\?z?resulting access value may have invalid "
1e3532e7 11209 & "alignment!", Eloc);
d6f39728 11210 end if;
11211 end;
11212 end if;
11213 end;
11214 end if;
11215 end;
11216 end loop;
11217 end Validate_Unchecked_Conversions;
11218
d6f39728 11219end Sem_Ch13;