]> gcc.gnu.org Git - gcc.git/blame - gcc/ada/exp_attr.adb
[Ada] Crash in task body reference to discriminant
[gcc.git] / gcc / ada / exp_attr.adb
CommitLineData
70482933
RK
1------------------------------------------------------------------------------
2-- --
3-- GNAT COMPILER COMPONENTS --
4-- --
5-- E X P _ A T T R --
6-- --
7-- B o d y --
8-- --
bc0b26b9 9-- Copyright (C) 1992-2022, Free Software Foundation, Inc. --
70482933
RK
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- --
748086b7 13-- ware Foundation; either version 3, or (at your option) any later ver- --
70482933
RK
14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
9eea4346
GB
16-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17-- for more details. You should have received a copy of the GNU General --
18-- Public License distributed with GNAT; see file COPYING3. If not, go to --
19-- http://www.gnu.org/licenses for a complete copy of the license. --
70482933
RK
20-- --
21-- GNAT was originally developed by the GNAT team at New York University. --
71ff80dc 22-- Extensive contributions were provided by Ada Core Technologies Inc. --
70482933
RK
23-- --
24------------------------------------------------------------------------------
25
104f58db
BD
26with Aspects; use Aspects;
27with Atree; use Atree;
28with Checks; use Checks;
29with Einfo; use Einfo;
76f9c7f4 30with Einfo.Entities; use Einfo.Entities;
104f58db
BD
31with Einfo.Utils; use Einfo.Utils;
32with Elists; use Elists;
33with Exp_Atag; use Exp_Atag;
34with Exp_Ch3; use Exp_Ch3;
35with Exp_Ch6; use Exp_Ch6;
36with Exp_Ch9; use Exp_Ch9;
37with Exp_Dist; use Exp_Dist;
38with Exp_Imgv; use Exp_Imgv;
39with Exp_Pakd; use Exp_Pakd;
40with Exp_Strm; use Exp_Strm;
110d0820 41with Exp_Put_Image;
104f58db
BD
42with Exp_Tss; use Exp_Tss;
43with Exp_Util; use Exp_Util;
44with Expander; use Expander;
45with Freeze; use Freeze;
46with Gnatvsn; use Gnatvsn;
47with Itypes; use Itypes;
48with Lib; use Lib;
49with Namet; use Namet;
50with Nmake; use Nmake;
51with Nlists; use Nlists;
52with Opt; use Opt;
53with Restrict; use Restrict;
54with Rident; use Rident;
55with Rtsfind; use Rtsfind;
56with Sem; use Sem;
57with Sem_Aux; use Sem_Aux;
58with Sem_Ch6; use Sem_Ch6;
59with Sem_Ch7; use Sem_Ch7;
60with Sem_Ch8; use Sem_Ch8;
61with Sem_Eval; use Sem_Eval;
62with Sem_Res; use Sem_Res;
63with Sem_Util; use Sem_Util;
64with Sinfo; use Sinfo;
65with Sinfo.Nodes; use Sinfo.Nodes;
66with Sinfo.Utils; use Sinfo.Utils;
67with Snames; use Snames;
68with Stand; use Stand;
69with Stringt; use Stringt;
d235950e 70with Strub; use Strub;
104f58db
BD
71with Tbuild; use Tbuild;
72with Ttypes; use Ttypes;
73with Uintp; use Uintp;
74with Uname; use Uname;
75with Urealp; use Urealp;
76with Validsw; use Validsw;
70482933
RK
77
78package body Exp_Attr is
79
80 -----------------------
81 -- Local Subprograms --
82 -----------------------
83
99fc068e 84 function Build_Array_VS_Func
f16cb8df
HK
85 (Attr : Node_Id;
86 Formal_Typ : Entity_Id;
a4dafb8b 87 Array_Typ : Entity_Id) return Entity_Id;
f16cb8df
HK
88 -- Validate the components of an array type by means of a function. Return
89 -- the entity of the validation function. The parameters are as follows:
90 --
91 -- * Attr - the 'Valid_Scalars attribute for which the function is
92 -- generated.
93 --
94 -- * Formal_Typ - the type of the generated function's only formal
95 -- parameter.
96 --
97 -- * Array_Typ - the array type whose components are to be validated
99fc068e 98
99bba92c
AC
99 function Build_Disp_Get_Task_Id_Call (Actual : Node_Id) return Node_Id;
100 -- Build a call to Disp_Get_Task_Id, passing Actual as actual parameter
101
45ec05e1 102 function Build_Record_VS_Func
f16cb8df
HK
103 (Attr : Node_Id;
104 Formal_Typ : Entity_Id;
105 Rec_Typ : Entity_Id) return Entity_Id;
106 -- Validate the components, discriminants, and variants of a record type by
107 -- means of a function. Return the entity of the validation function. The
108 -- parameters are as follows:
109 --
110 -- * Attr - the 'Valid_Scalars attribute for which the function is
111 -- generated.
112 --
113 -- * Formal_Typ - the type of the generated function's only formal
114 -- parameter.
115 --
116 -- * Rec_Typ - the record type whose internals are to be validated
45ec05e1 117
70482933
RK
118 procedure Compile_Stream_Body_In_Scope
119 (N : Node_Id;
120 Decl : Node_Id;
fb632ef5 121 Arr : Entity_Id);
70482933
RK
122 -- The body for a stream subprogram may be generated outside of the scope
123 -- of the type. If the type is fully private, it may depend on the full
3b42c566 124 -- view of other types (e.g. indexes) that are currently private as well.
70482933
RK
125 -- We install the declarations of the package in which the type is declared
126 -- before compiling the body in what is its proper environment. The Check
127 -- parameter indicates if checks are to be suppressed for the stream body.
128 -- We suppress checks for array/record reads, since the rule is that these
129 -- are like assignments, out of range values due to uninitialized storage,
130 -- or other invalid values do NOT cause a Constraint_Error to be raised.
3dddb11e
ES
131 -- If we are within an instance body all visibility has been established
132 -- already and there is no need to install the package.
70482933 133
73f05f9f
ES
134 -- This mechanism is now extended to the component types of the array type,
135 -- when the component type is not in scope and is private, to handle
136 -- properly the case when the full view has defaulted discriminants.
137
138 -- This special processing is ultimately caused by the fact that the
139 -- compiler lacks a well-defined phase when full views are visible
140 -- everywhere. Having such a separate pass would remove much of the
141 -- special-case code that shuffles partial and full views in the middle
142 -- of semantic analysis and expansion.
143
29f2d76c
SB
144 function Default_Streaming_Unavailable (Typ : Entity_Id) return Boolean;
145 --
146 -- In most cases, references to unavailable streaming attributes
147 -- are rejected at compile time. In some obscure cases involving
148 -- generics and formal derived types, the problem is dealt with at runtime.
149
7ce611e2
ES
150 procedure Expand_Access_To_Protected_Op
151 (N : Node_Id;
152 Pref : Node_Id;
153 Typ : Entity_Id);
7ce611e2
ES
154 -- An attribute reference to a protected subprogram is transformed into
155 -- a pair of pointers: one to the object, and one to the operations.
156 -- This expansion is performed for 'Access and for 'Unrestricted_Access.
157
70482933 158 procedure Expand_Fpt_Attribute
fbf5a39b 159 (N : Node_Id;
65f01153 160 Pkg : RE_Id;
fbf5a39b 161 Nam : Name_Id;
70482933
RK
162 Args : List_Id);
163 -- This procedure expands a call to a floating-point attribute function.
164 -- N is the attribute reference node, and Args is a list of arguments to
65f01153
RD
165 -- be passed to the function call. Pkg identifies the package containing
166 -- the appropriate instantiation of System.Fat_Gen. Float arguments in Args
167 -- have already been converted to the floating-point type for which Pkg was
168 -- instantiated. The Nam argument is the relevant attribute processing
c46dffc6 169 -- routine to be called. This is the same as the attribute name.
70482933
RK
170
171 procedure Expand_Fpt_Attribute_R (N : Node_Id);
172 -- This procedure expands a call to a floating-point attribute function
fbf5a39b
AC
173 -- that takes a single floating-point argument. The function to be called
174 -- is always the same as the attribute name.
70482933
RK
175
176 procedure Expand_Fpt_Attribute_RI (N : Node_Id);
177 -- This procedure expands a call to a floating-point attribute function
fbf5a39b
AC
178 -- that takes one floating-point argument and one integer argument. The
179 -- function to be called is always the same as the attribute name.
70482933
RK
180
181 procedure Expand_Fpt_Attribute_RR (N : Node_Id);
182 -- This procedure expands a call to a floating-point attribute function
fbf5a39b
AC
183 -- that takes two floating-point arguments. The function to be called
184 -- is always the same as the attribute name.
70482933 185
aa9b151a 186 procedure Expand_Loop_Entry_Attribute (N : Node_Id);
d436b30d
AC
187 -- Handle the expansion of attribute 'Loop_Entry. As a result, the related
188 -- loop may be converted into a conditional block. See body for details.
189
e0f63680
AC
190 procedure Expand_Min_Max_Attribute (N : Node_Id);
191 -- Handle the expansion of attributes 'Max and 'Min, including expanding
192 -- then out if we are in Modify_Tree_For_C mode.
193
aa9b151a 194 procedure Expand_Pred_Succ_Attribute (N : Node_Id);
70482933
RK
195 -- Handles expansion of Pred or Succ attributes for case of non-real
196 -- operand with overflow checking required.
197
18a2ad5d
AC
198 procedure Expand_Update_Attribute (N : Node_Id);
199 -- Handle the expansion of attribute Update
200
65f01153
RD
201 procedure Find_Fat_Info
202 (T : Entity_Id;
203 Fat_Type : out Entity_Id;
204 Fat_Pkg : out RE_Id);
205 -- Given a floating-point type T, identifies the package containing the
206 -- attributes for this type (returned in Fat_Pkg), and the corresponding
207 -- type for which this package was instantiated from Fat_Gen. Error if T
208 -- is not a floating-point type.
209
fbf5a39b
AC
210 function Find_Stream_Subprogram
211 (Typ : Entity_Id;
212 Nam : TSS_Name_Type) return Entity_Id;
213 -- Returns the stream-oriented subprogram attribute for Typ. For tagged
214 -- types, the corresponding primitive operation is looked up, else the
215 -- appropriate TSS from the type itself, or from its closest ancestor
216 -- defining it, is returned. In both cases, inheritance of representation
217 -- aspects is thus taken into account.
70482933 218
96d2756f
AC
219 function Full_Base (T : Entity_Id) return Entity_Id;
220 -- The stream functions need to examine the underlying representation of
221 -- composite types. In some cases T may be non-private but its base type
222 -- is, in which case the function returns the corresponding full view.
223
1d571f3b
AC
224 function Get_Stream_Convert_Pragma (T : Entity_Id) return Node_Id;
225 -- Given a type, find a corresponding stream convert pragma that applies to
226 -- the implementation base type of this type (Typ). If found, return the
227 -- pragma node, otherwise return Empty if no pragma is found.
228
70482933
RK
229 function Is_Constrained_Packed_Array (Typ : Entity_Id) return Boolean;
230 -- Utility for array attributes, returns true on packed constrained
231 -- arrays, and on access to same.
232
0669bebe
GB
233 function Is_Inline_Floating_Point_Attribute (N : Node_Id) return Boolean;
234 -- Returns true iff the given node refers to an attribute call that
235 -- can be expanded directly by the back end and does not need front end
236 -- expansion. Typically used for rounding and truncation attributes that
237 -- appear directly inside a conversion to integer.
238
99fc068e
RD
239 -------------------------
240 -- Build_Array_VS_Func --
241 -------------------------
242
243 function Build_Array_VS_Func
f16cb8df
HK
244 (Attr : Node_Id;
245 Formal_Typ : Entity_Id;
a4dafb8b 246 Array_Typ : Entity_Id) return Entity_Id
99fc068e 247 is
a4dafb8b
PT
248 Loc : constant Source_Ptr := Sloc (Attr);
249 Comp_Typ : constant Entity_Id :=
7aaf6620 250 Validated_View (Component_Type (Array_Typ));
f16cb8df
HK
251
252 function Validate_Component
253 (Obj_Id : Entity_Id;
254 Indexes : List_Id) return Node_Id;
255 -- Process a single component denoted by indexes Indexes. Obj_Id denotes
256 -- the entity of the validation parameter. Return the check associated
257 -- with the component.
258
259 function Validate_Dimension
260 (Obj_Id : Entity_Id;
261 Dim : Int;
262 Indexes : List_Id) return Node_Id;
263 -- Process dimension Dim of the array type. Obj_Id denotes the entity
264 -- of the validation parameter. Indexes is a list where each dimension
265 -- deposits its loop variable, which will later identify a component.
266 -- Return the loop associated with the current dimension.
99fc068e 267
f16cb8df
HK
268 ------------------------
269 -- Validate_Component --
270 ------------------------
99fc068e 271
f16cb8df
HK
272 function Validate_Component
273 (Obj_Id : Entity_Id;
274 Indexes : List_Id) return Node_Id
275 is
276 Attr_Nam : Name_Id;
99fc068e
RD
277
278 begin
f16cb8df
HK
279 if Is_Scalar_Type (Comp_Typ) then
280 Attr_Nam := Name_Valid;
99fc068e 281 else
f16cb8df 282 Attr_Nam := Name_Valid_Scalars;
99fc068e
RD
283 end if;
284
f16cb8df
HK
285 -- Generate:
286 -- if not Array_Typ (Obj_Id) (Indexes)'Valid[_Scalars] then
287 -- return False;
288 -- end if;
289
290 return
99fc068e
RD
291 Make_If_Statement (Loc,
292 Condition =>
293 Make_Op_Not (Loc,
294 Right_Opnd =>
295 Make_Attribute_Reference (Loc,
f16cb8df
HK
296 Prefix =>
297 Make_Indexed_Component (Loc,
298 Prefix =>
299 Unchecked_Convert_To (Array_Typ,
300 New_Occurrence_Of (Obj_Id, Loc)),
301 Expressions => Indexes),
302 Attribute_Name => Attr_Nam)),
303
99fc068e
RD
304 Then_Statements => New_List (
305 Make_Simple_Return_Statement (Loc,
f16cb8df
HK
306 Expression => New_Occurrence_Of (Standard_False, Loc))));
307 end Validate_Component;
99fc068e
RD
308
309 ------------------------
f16cb8df 310 -- Validate_Dimension --
99fc068e
RD
311 ------------------------
312
f16cb8df
HK
313 function Validate_Dimension
314 (Obj_Id : Entity_Id;
315 Dim : Int;
316 Indexes : List_Id) return Node_Id
317 is
99fc068e
RD
318 Index : Entity_Id;
319
320 begin
f16cb8df
HK
321 -- Validate the component once all dimensions have produced their
322 -- individual loops.
99fc068e 323
f16cb8df
HK
324 if Dim > Number_Dimensions (Array_Typ) then
325 return Validate_Component (Obj_Id, Indexes);
99fc068e 326
f16cb8df 327 -- Process the current dimension
99fc068e
RD
328
329 else
330 Index :=
f16cb8df 331 Make_Defining_Identifier (Loc, New_External_Name ('J', Dim));
99fc068e 332
f16cb8df 333 Append_To (Indexes, New_Occurrence_Of (Index, Loc));
99fc068e 334
f16cb8df
HK
335 -- Generate:
336 -- for J1 in Array_Typ (Obj_Id)'Range (1) loop
337 -- for JN in Array_Typ (Obj_Id)'Range (N) loop
338 -- if not Array_Typ (Obj_Id) (Indexes)'Valid[_Scalars]
339 -- then
340 -- return False;
341 -- end if;
342 -- end loop;
343 -- end loop;
344
345 return
346 Make_Implicit_Loop_Statement (Attr,
347 Identifier => Empty,
99fc068e
RD
348 Iteration_Scheme =>
349 Make_Iteration_Scheme (Loc,
350 Loop_Parameter_Specification =>
351 Make_Loop_Parameter_Specification (Loc,
f16cb8df 352 Defining_Identifier => Index,
99fc068e
RD
353 Discrete_Subtype_Definition =>
354 Make_Attribute_Reference (Loc,
f16cb8df
HK
355 Prefix =>
356 Unchecked_Convert_To (Array_Typ,
357 New_Occurrence_Of (Obj_Id, Loc)),
99fc068e
RD
358 Attribute_Name => Name_Range,
359 Expressions => New_List (
f16cb8df
HK
360 Make_Integer_Literal (Loc, Dim))))),
361 Statements => New_List (
362 Validate_Dimension (Obj_Id, Dim + 1, Indexes)));
99fc068e 363 end if;
f16cb8df
HK
364 end Validate_Dimension;
365
366 -- Local variables
367
368 Func_Id : constant Entity_Id := Make_Temporary (Loc, 'V');
369 Indexes : constant List_Id := New_List;
370 Obj_Id : constant Entity_Id := Make_Temporary (Loc, 'A');
371 Stmts : List_Id;
99fc068e
RD
372
373 -- Start of processing for Build_Array_VS_Func
374
375 begin
f16cb8df 376 Stmts := New_List (Validate_Dimension (Obj_Id, 1, Indexes));
99fc068e 377
f16cb8df
HK
378 -- Generate:
379 -- return True;
99fc068e 380
f16cb8df
HK
381 Append_To (Stmts,
382 Make_Simple_Return_Statement (Loc,
383 Expression => New_Occurrence_Of (Standard_True, Loc)));
99fc068e 384
f16cb8df
HK
385 -- Generate:
386 -- function Func_Id (Obj_Id : Formal_Typ) return Boolean is
387 -- begin
388 -- Stmts
389 -- end Func_Id;
99fc068e 390
2e02ab86 391 Mutate_Ekind (Func_Id, E_Function);
99fc068e 392 Set_Is_Internal (Func_Id);
f16cb8df
HK
393 Set_Is_Pure (Func_Id);
394
395 if not Debug_Generated_Code then
396 Set_Debug_Info_Off (Func_Id);
397 end if;
99fc068e 398
f16cb8df 399 Insert_Action (Attr,
99fc068e
RD
400 Make_Subprogram_Body (Loc,
401 Specification =>
402 Make_Function_Specification (Loc,
403 Defining_Unit_Name => Func_Id,
f16cb8df
HK
404 Parameter_Specifications => New_List (
405 Make_Parameter_Specification (Loc,
406 Defining_Identifier => Obj_Id,
f16cb8df
HK
407 Parameter_Type => New_Occurrence_Of (Formal_Typ, Loc))),
408 Result_Definition =>
409 New_Occurrence_Of (Standard_Boolean, Loc)),
99fc068e
RD
410 Declarations => New_List,
411 Handled_Statement_Sequence =>
412 Make_Handled_Sequence_Of_Statements (Loc,
f16cb8df 413 Statements => Stmts)));
99fc068e 414
99fc068e
RD
415 return Func_Id;
416 end Build_Array_VS_Func;
417
99bba92c
AC
418 ---------------------------------
419 -- Build_Disp_Get_Task_Id_Call --
420 ---------------------------------
421
422 function Build_Disp_Get_Task_Id_Call (Actual : Node_Id) return Node_Id is
c0e938d0
AC
423 Loc : constant Source_Ptr := Sloc (Actual);
424 Typ : constant Entity_Id := Etype (Actual);
425 Subp : constant Entity_Id := Find_Prim_Op (Typ, Name_uDisp_Get_Task_Id);
426
99bba92c 427 begin
c0e938d0
AC
428 -- Generate:
429 -- _Disp_Get_Task_Id (Actual)
430
431 return
432 Make_Function_Call (Loc,
433 Name => New_Occurrence_Of (Subp, Loc),
434 Parameter_Associations => New_List (Actual));
99bba92c
AC
435 end Build_Disp_Get_Task_Id_Call;
436
45ec05e1
RD
437 --------------------------
438 -- Build_Record_VS_Func --
439 --------------------------
440
45ec05e1 441 function Build_Record_VS_Func
f16cb8df
HK
442 (Attr : Node_Id;
443 Formal_Typ : Entity_Id;
444 Rec_Typ : Entity_Id) return Entity_Id
45ec05e1 445 is
f16cb8df
HK
446 -- NOTE: The logic of Build_Record_VS_Func is intentionally passive.
447 -- It generates code only when there are components, discriminants,
448 -- or variant parts to validate.
449
450 -- NOTE: The routines within Build_Record_VS_Func are intentionally
451 -- unnested to avoid deep indentation of code.
452
453 Loc : constant Source_Ptr := Sloc (Attr);
454
455 procedure Validate_Component_List
456 (Obj_Id : Entity_Id;
457 Comp_List : Node_Id;
458 Stmts : in out List_Id);
459 -- Process all components and variant parts of component list Comp_List.
460 -- Obj_Id denotes the entity of the validation parameter. All new code
461 -- is added to list Stmts.
462
463 procedure Validate_Field
464 (Obj_Id : Entity_Id;
465 Field : Node_Id;
466 Cond : in out Node_Id);
467 -- Process component declaration or discriminant specification Field.
468 -- Obj_Id denotes the entity of the validation parameter. Cond denotes
469 -- an "or else" conditional expression which contains the new code (if
470 -- any).
471
472 procedure Validate_Fields
473 (Obj_Id : Entity_Id;
474 Fields : List_Id;
475 Stmts : in out List_Id);
476 -- Process component declarations or discriminant specifications in list
477 -- Fields. Obj_Id denotes the entity of the validation parameter. All
478 -- new code is added to list Stmts.
479
480 procedure Validate_Variant
481 (Obj_Id : Entity_Id;
482 Var : Node_Id;
483 Alts : in out List_Id);
484 -- Process variant Var. Obj_Id denotes the entity of the validation
485 -- parameter. Alts denotes a list of case statement alternatives which
486 -- contains the new code (if any).
487
488 procedure Validate_Variant_Part
489 (Obj_Id : Entity_Id;
490 Var_Part : Node_Id;
491 Stmts : in out List_Id);
492 -- Process variant part Var_Part. Obj_Id denotes the entity of the
493 -- validation parameter. All new code is added to list Stmts.
45ec05e1 494
f16cb8df
HK
495 -----------------------------
496 -- Validate_Component_List --
497 -----------------------------
45ec05e1 498
f16cb8df
HK
499 procedure Validate_Component_List
500 (Obj_Id : Entity_Id;
501 Comp_List : Node_Id;
502 Stmts : in out List_Id)
503 is
504 Var_Part : constant Node_Id := Variant_Part (Comp_List);
45ec05e1 505
f16cb8df
HK
506 begin
507 -- Validate all components
508
509 Validate_Fields
510 (Obj_Id => Obj_Id,
511 Fields => Component_Items (Comp_List),
512 Stmts => Stmts);
513
514 -- Validate the variant part
515
516 if Present (Var_Part) then
517 Validate_Variant_Part
518 (Obj_Id => Obj_Id,
519 Var_Part => Var_Part,
520 Stmts => Stmts);
521 end if;
522 end Validate_Component_List;
45ec05e1 523
f16cb8df
HK
524 --------------------
525 -- Validate_Field --
526 --------------------
527
528 procedure Validate_Field
529 (Obj_Id : Entity_Id;
530 Field : Node_Id;
531 Cond : in out Node_Id)
45ec05e1 532 is
f16cb8df
HK
533 Field_Id : constant Entity_Id := Defining_Entity (Field);
534 Field_Nam : constant Name_Id := Chars (Field_Id);
7aaf6620 535 Field_Typ : constant Entity_Id := Validated_View (Etype (Field_Id));
f16cb8df 536 Attr_Nam : Name_Id;
45ec05e1
RD
537
538 begin
f16cb8df
HK
539 -- Do not process internally-generated fields. Note that checking for
540 -- Comes_From_Source is not correct because this will eliminate the
541 -- components within the corresponding record of a protected type.
45ec05e1 542
4a08c95c 543 if Field_Nam in Name_uObject | Name_uParent | Name_uTag then
f16cb8df 544 null;
45ec05e1 545
f16cb8df 546 -- Do not process fields without any scalar components
45ec05e1 547
f16cb8df
HK
548 elsif not Scalar_Part_Present (Field_Typ) then
549 null;
550
551 -- Otherwise the field needs to be validated. Use Make_Identifier
552 -- rather than New_Occurrence_Of to identify the field because the
553 -- wrong entity may be picked up when private types are involved.
554
555 -- Generate:
556 -- [or else] not Rec_Typ (Obj_Id).Item_Nam'Valid[_Scalars]
557
558 else
559 if Is_Scalar_Type (Field_Typ) then
560 Attr_Nam := Name_Valid;
561 else
562 Attr_Nam := Name_Valid_Scalars;
563 end if;
564
565 Evolve_Or_Else (Cond,
566 Make_Op_Not (Loc,
567 Right_Opnd =>
568 Make_Attribute_Reference (Loc,
569 Prefix =>
570 Make_Selected_Component (Loc,
571 Prefix =>
572 Unchecked_Convert_To (Rec_Typ,
573 New_Occurrence_Of (Obj_Id, Loc)),
574 Selector_Name => Make_Identifier (Loc, Field_Nam)),
575 Attribute_Name => Attr_Nam)));
45ec05e1 576 end if;
f16cb8df 577 end Validate_Field;
45ec05e1 578
f16cb8df
HK
579 ---------------------
580 -- Validate_Fields --
581 ---------------------
45ec05e1 582
f16cb8df
HK
583 procedure Validate_Fields
584 (Obj_Id : Entity_Id;
585 Fields : List_Id;
586 Stmts : in out List_Id)
587 is
588 Cond : Node_Id;
589 Field : Node_Id;
45ec05e1 590
f16cb8df
HK
591 begin
592 -- Assume that none of the fields are eligible for verification
45ec05e1 593
f16cb8df 594 Cond := Empty;
45ec05e1 595
f16cb8df 596 -- Validate all fields
45ec05e1 597
f16cb8df
HK
598 Field := First_Non_Pragma (Fields);
599 while Present (Field) loop
600 Validate_Field
601 (Obj_Id => Obj_Id,
602 Field => Field,
603 Cond => Cond);
45ec05e1 604
f16cb8df
HK
605 Next_Non_Pragma (Field);
606 end loop;
45ec05e1 607
f16cb8df
HK
608 -- Generate:
609 -- if not Rec_Typ (Obj_Id).Item_Nam_1'Valid[_Scalars]
610 -- or else not Rec_Typ (Obj_Id).Item_Nam_N'Valid[_Scalars]
611 -- then
612 -- return False;
613 -- end if;
45ec05e1 614
f16cb8df
HK
615 if Present (Cond) then
616 Append_New_To (Stmts,
617 Make_Implicit_If_Statement (Attr,
618 Condition => Cond,
619 Then_Statements => New_List (
620 Make_Simple_Return_Statement (Loc,
621 Expression => New_Occurrence_Of (Standard_False, Loc)))));
622 end if;
623 end Validate_Fields;
45ec05e1 624
f16cb8df
HK
625 ----------------------
626 -- Validate_Variant --
627 ----------------------
45ec05e1 628
f16cb8df
HK
629 procedure Validate_Variant
630 (Obj_Id : Entity_Id;
631 Var : Node_Id;
632 Alts : in out List_Id)
633 is
634 Stmts : List_Id;
45ec05e1 635
f16cb8df
HK
636 begin
637 -- Assume that none of the components and variants are eligible for
638 -- verification.
45ec05e1 639
f16cb8df 640 Stmts := No_List;
45ec05e1 641
b108c2ed 642 -- Validate components
45ec05e1 643
f16cb8df
HK
644 Validate_Component_List
645 (Obj_Id => Obj_Id,
646 Comp_List => Component_List (Var),
647 Stmts => Stmts);
648
649 -- Generate a null statement in case none of the components were
650 -- verified because this will otherwise eliminate an alternative
651 -- from the variant case statement and render the generated code
652 -- illegal.
45ec05e1 653
f16cb8df
HK
654 if No (Stmts) then
655 Append_New_To (Stmts, Make_Null_Statement (Loc));
656 end if;
45ec05e1 657
f16cb8df
HK
658 -- Generate:
659 -- when Discrete_Choices =>
660 -- Stmts
661
662 Append_New_To (Alts,
663 Make_Case_Statement_Alternative (Loc,
664 Discrete_Choices =>
665 New_Copy_List_Tree (Discrete_Choices (Var)),
666 Statements => Stmts));
667 end Validate_Variant;
668
669 ---------------------------
670 -- Validate_Variant_Part --
671 ---------------------------
672
673 procedure Validate_Variant_Part
674 (Obj_Id : Entity_Id;
675 Var_Part : Node_Id;
676 Stmts : in out List_Id)
677 is
678 Vars : constant List_Id := Variants (Var_Part);
679 Alts : List_Id;
680 Var : Node_Id;
45ec05e1 681
f16cb8df
HK
682 begin
683 -- Assume that none of the variants are eligible for verification
c468e1fb 684
f16cb8df 685 Alts := No_List;
45ec05e1 686
f16cb8df 687 -- Validate variants
45ec05e1 688
f16cb8df
HK
689 Var := First_Non_Pragma (Vars);
690 while Present (Var) loop
691 Validate_Variant
692 (Obj_Id => Obj_Id,
693 Var => Var,
694 Alts => Alts);
45ec05e1 695
f16cb8df
HK
696 Next_Non_Pragma (Var);
697 end loop;
45ec05e1 698
f16cb8df
HK
699 -- Even though individual variants may lack eligible components, the
700 -- alternatives must still be generated.
45ec05e1 701
f16cb8df 702 pragma Assert (Present (Alts));
45ec05e1 703
f16cb8df
HK
704 -- Generate:
705 -- case Rec_Typ (Obj_Id).Discriminant is
706 -- when Discrete_Choices_1 =>
707 -- Stmts_1
708 -- when Discrete_Choices_N =>
709 -- Stmts_N
710 -- end case;
711
712 Append_New_To (Stmts,
713 Make_Case_Statement (Loc,
714 Expression =>
715 Make_Selected_Component (Loc,
716 Prefix =>
717 Unchecked_Convert_To (Rec_Typ,
718 New_Occurrence_Of (Obj_Id, Loc)),
719 Selector_Name => New_Copy_Tree (Name (Var_Part))),
720 Alternatives => Alts));
721 end Validate_Variant_Part;
45ec05e1 722
bbe008b6 723 -- Local variables
45ec05e1 724
f16cb8df
HK
725 Func_Id : constant Entity_Id := Make_Temporary (Loc, 'V');
726 Obj_Id : constant Entity_Id := Make_Temporary (Loc, 'R');
f2f9cdad 727 Comps : Node_Id;
f16cb8df 728 Stmts : List_Id;
f2f9cdad
HK
729 Typ : Entity_Id;
730 Typ_Decl : Node_Id;
731 Typ_Def : Node_Id;
732 Typ_Ext : Node_Id;
45ec05e1 733
bbe008b6
HK
734 -- Start of processing for Build_Record_VS_Func
735
45ec05e1 736 begin
ce32ccfc 737 Typ := Validated_View (Rec_Typ);
f2f9cdad
HK
738
739 -- Use the root type when dealing with a class-wide type
740
741 if Is_Class_Wide_Type (Typ) then
66bd7af5 742 Typ := Validated_View (Root_Type (Typ));
f2f9cdad
HK
743 end if;
744
745 Typ_Decl := Declaration_Node (Typ);
746 Typ_Def := Type_Definition (Typ_Decl);
747
748 -- The components of a derived type are located in the extension part
749
750 if Nkind (Typ_Def) = N_Derived_Type_Definition then
751 Typ_Ext := Record_Extension_Part (Typ_Def);
752
753 if Present (Typ_Ext) then
754 Comps := Component_List (Typ_Ext);
755 else
756 Comps := Empty;
757 end if;
758
759 -- Otherwise the components are available in the definition
760
761 else
762 Comps := Component_List (Typ_Def);
763 end if;
764
f16cb8df
HK
765 -- The code generated by this routine is as follows:
766 --
767 -- function Func_Id (Obj_Id : Formal_Typ) return Boolean is
768 -- begin
769 -- if not Rec_Typ (Obj_Id).Discriminant_1'Valid[_Scalars]
770 -- or else not Rec_Typ (Obj_Id).Discriminant_N'Valid[_Scalars]
771 -- then
772 -- return False;
773 -- end if;
774 --
775 -- if not Rec_Typ (Obj_Id).Component_1'Valid[_Scalars]
776 -- or else not Rec_Typ (Obj_Id).Component_N'Valid[_Scalars]
777 -- then
778 -- return False;
779 -- end if;
780 --
781 -- case Discriminant_1 is
782 -- when Choice_1 =>
783 -- if not Rec_Typ (Obj_Id).Component_1'Valid[_Scalars]
784 -- or else not Rec_Typ (Obj_Id).Component_N'Valid[_Scalars]
785 -- then
786 -- return False;
787 -- end if;
788 --
789 -- case Discriminant_N is
790 -- ...
791 -- when Choice_N =>
792 -- ...
793 -- end case;
794 --
795 -- return True;
796 -- end Func_Id;
797
798 -- Assume that the record type lacks eligible components, discriminants,
799 -- and variant parts.
800
801 Stmts := No_List;
802
803 -- Validate the discriminants
804
805 if not Is_Unchecked_Union (Rec_Typ) then
806 Validate_Fields
807 (Obj_Id => Obj_Id,
f2f9cdad 808 Fields => Discriminant_Specifications (Typ_Decl),
f16cb8df
HK
809 Stmts => Stmts);
810 end if;
45ec05e1 811
f16cb8df 812 -- Validate the components and variant parts
45ec05e1 813
f16cb8df
HK
814 Validate_Component_List
815 (Obj_Id => Obj_Id,
f2f9cdad 816 Comp_List => Comps,
f16cb8df
HK
817 Stmts => Stmts);
818
819 -- Generate:
820 -- return True;
821
822 Append_New_To (Stmts,
45ec05e1
RD
823 Make_Simple_Return_Statement (Loc,
824 Expression => New_Occurrence_Of (Standard_True, Loc)));
825
f16cb8df
HK
826 -- Generate:
827 -- function Func_Id (Obj_Id : Formal_Typ) return Boolean is
828 -- begin
829 -- Stmts
830 -- end Func_Id;
831
2e02ab86 832 Mutate_Ekind (Func_Id, E_Function);
f16cb8df
HK
833 Set_Is_Internal (Func_Id);
834 Set_Is_Pure (Func_Id);
835
836 if not Debug_Generated_Code then
837 Set_Debug_Info_Off (Func_Id);
838 end if;
839
840 Insert_Action (Attr,
45ec05e1
RD
841 Make_Subprogram_Body (Loc,
842 Specification =>
843 Make_Function_Specification (Loc,
844 Defining_Unit_Name => Func_Id,
f16cb8df
HK
845 Parameter_Specifications => New_List (
846 Make_Parameter_Specification (Loc,
847 Defining_Identifier => Obj_Id,
848 Parameter_Type => New_Occurrence_Of (Formal_Typ, Loc))),
849 Result_Definition =>
850 New_Occurrence_Of (Standard_Boolean, Loc)),
45ec05e1
RD
851 Declarations => New_List,
852 Handled_Statement_Sequence =>
f16cb8df
HK
853 Make_Handled_Sequence_Of_Statements (Loc,
854 Statements => Stmts)),
45ec05e1
RD
855 Suppress => Discriminant_Check);
856
45ec05e1
RD
857 return Func_Id;
858 end Build_Record_VS_Func;
859
70482933
RK
860 ----------------------------------
861 -- Compile_Stream_Body_In_Scope --
862 ----------------------------------
863
864 procedure Compile_Stream_Body_In_Scope
865 (N : Node_Id;
866 Decl : Node_Id;
fb632ef5 867 Arr : Entity_Id)
70482933 868 is
d6dffa66
HK
869 C_Type : constant Entity_Id := Base_Type (Component_Type (Arr));
870 Curr : constant Entity_Id := Current_Scope;
871 Install : Boolean := False;
872 Scop : Entity_Id := Scope (Arr);
73f05f9f 873
70482933
RK
874 begin
875 if Is_Hidden (Arr)
876 and then not In_Open_Scopes (Scop)
877 and then Ekind (Scop) = E_Package
73f05f9f
ES
878 then
879 Install := True;
73f05f9f 880
d6dffa66
HK
881 else
882 -- The component type may be private, in which case we install its
883 -- full view to compile the subprogram.
3dddb11e 884
e3f94155
AC
885 -- The component type may be private, in which case we install its
886 -- full view to compile the subprogram. We do not do this if the
887 -- type has a Stream_Convert pragma, which indicates that there are
888 -- special stream-processing operations for that type (for example
889 -- Unbounded_String and its wide varieties).
890
09cca56d
ES
891 -- We don't install the package either if array type and element
892 -- type come from the same package, and the original array type is
893 -- private, because in this case the underlying type Arr is
894 -- itself a full view, which carries the full view of the component.
895
73f05f9f 896 Scop := Scope (C_Type);
3dddb11e 897
73f05f9f
ES
898 if Is_Private_Type (C_Type)
899 and then Present (Full_View (C_Type))
900 and then not In_Open_Scopes (Scop)
901 and then Ekind (Scop) = E_Package
e3f94155 902 and then No (Get_Stream_Convert_Pragma (C_Type))
73f05f9f 903 then
09cca56d
ES
904 if Scope (Arr) = Scope (C_Type)
905 and then Is_Private_Type (Etype (Prefix (N)))
906 and then Full_View (Etype (Prefix (N))) = Arr
907 then
908 null;
909
910 else
911 Install := True;
912 end if;
73f05f9f
ES
913 end if;
914 end if;
915
916 -- If we are within an instance body, then all visibility has been
917 -- established already and there is no need to install the package.
918
d6dffa66 919 if Install and then not In_Instance_Body then
31104818 920 Push_Scope (Scop);
70482933
RK
921 Install_Visible_Declarations (Scop);
922 Install_Private_Declarations (Scop);
70482933
RK
923
924 -- The entities in the package are now visible, but the generated
925 -- stream entity must appear in the current scope (usually an
926 -- enclosing stream function) so that itypes all have their proper
927 -- scopes.
928
31104818 929 Push_Scope (Curr);
73f05f9f
ES
930 else
931 Install := False;
70482933
RK
932 end if;
933
fb632ef5 934 Insert_Action (N, Decl);
70482933 935
73f05f9f 936 if Install then
70482933
RK
937
938 -- Remove extra copy of current scope, and package itself
939
940 Pop_Scope;
941 End_Package_Scope (Scop);
942 end if;
943 end Compile_Stream_Body_In_Scope;
944
29f2d76c
SB
945 -----------------------------------
946 -- Default_Streaming_Unavailable --
947 -----------------------------------
948
949 function Default_Streaming_Unavailable (Typ : Entity_Id) return Boolean is
950 Btyp : constant Entity_Id := Implementation_Base_Type (Typ);
951 begin
952 if Is_Immutably_Limited_Type (Btyp)
953 and then not Is_Tagged_Type (Btyp)
954 and then not (Ekind (Btyp) = E_Record_Type
955 and then Present (Corresponding_Concurrent_Type (Btyp)))
956 then
957 pragma Assert (In_Instance_Body);
958 return True;
959 end if;
960 return False;
961 end Default_Streaming_Unavailable;
962
7ce611e2
ES
963 -----------------------------------
964 -- Expand_Access_To_Protected_Op --
965 -----------------------------------
966
967 procedure Expand_Access_To_Protected_Op
968 (N : Node_Id;
969 Pref : Node_Id;
970 Typ : Entity_Id)
971 is
972 -- The value of the attribute_reference is a record containing two
973 -- fields: an access to the protected object, and an access to the
d9206abb
JM
974 -- subprogram itself. The prefix is an identifier or a selected
975 -- component.
976
977 function Has_By_Protected_Procedure_Prefixed_View return Boolean;
978 -- Determine whether Pref denotes the prefixed class-wide interface
979 -- view of a procedure with synchronization kind By_Protected_Procedure.
980
981 ----------------------------------------------
982 -- Has_By_Protected_Procedure_Prefixed_View --
983 ----------------------------------------------
984
985 function Has_By_Protected_Procedure_Prefixed_View return Boolean is
986 begin
987 return Nkind (Pref) = N_Selected_Component
988 and then Nkind (Prefix (Pref)) in N_Has_Entity
989 and then Present (Entity (Prefix (Pref)))
990 and then Is_Class_Wide_Type (Etype (Entity (Prefix (Pref))))
991 and then (Is_Synchronized_Interface (Etype (Entity (Prefix (Pref))))
992 or else
993 Is_Protected_Interface (Etype (Entity (Prefix (Pref)))))
994 and then Is_By_Protected_Procedure (Entity (Selector_Name (Pref)));
995 end Has_By_Protected_Procedure_Prefixed_View;
996
997 -- Local variables
7ce611e2
ES
998
999 Loc : constant Source_Ptr := Sloc (N);
1000 Agg : Node_Id;
1001 Btyp : constant Entity_Id := Base_Type (Typ);
aab8cf8b 1002 Sub : Entity_Id := Empty;
e657b693 1003 Sub_Ref : Node_Id;
7ce611e2
ES
1004 E_T : constant Entity_Id := Equivalent_Type (Btyp);
1005 Acc : constant Entity_Id :=
1006 Etype (Next_Component (First_Component (E_T)));
1007 Obj_Ref : Node_Id;
1008 Curr : Entity_Id;
1009
7ce611e2
ES
1010 -- Start of processing for Expand_Access_To_Protected_Op
1011
1012 begin
6e1ee5c3
AC
1013 -- Within the body of the protected type, the prefix designates a local
1014 -- operation, and the object is the first parameter of the corresponding
1015 -- protected body of the current enclosing operation.
7ce611e2
ES
1016
1017 if Is_Entity_Name (Pref) then
2290a0fe
AC
1018 -- All indirect calls are external calls, so must do locking and
1019 -- barrier reevaluation, even if the 'Access occurs within the
1020 -- protected body. Hence the call to External_Subprogram, as opposed
1021 -- to Protected_Body_Subprogram, below. See RM-9.5(5). This means
1022 -- that indirect calls from within the same protected body will
1023 -- deadlock, as allowed by RM-9.5.1(8,15,17).
1024
1025 Sub := New_Occurrence_Of (External_Subprogram (Entity (Pref)), Loc);
7ce611e2 1026
21d27997
RD
1027 -- Don't traverse the scopes when the attribute occurs within an init
1028 -- proc, because we directly use the _init formal of the init proc in
1029 -- that case.
1030
7ce611e2 1031 Curr := Current_Scope;
21d27997
RD
1032 if not Is_Init_Proc (Curr) then
1033 pragma Assert (In_Open_Scopes (Scope (Entity (Pref))));
1034
1035 while Scope (Curr) /= Scope (Entity (Pref)) loop
1036 Curr := Scope (Curr);
1037 end loop;
1038 end if;
7ce611e2
ES
1039
1040 -- In case of protected entries the first formal of its Protected_
1041 -- Body_Subprogram is the address of the object.
1042
1043 if Ekind (Curr) = E_Entry then
1044 Obj_Ref :=
1045 New_Occurrence_Of
1046 (First_Formal
1047 (Protected_Body_Subprogram (Curr)), Loc);
1048
21d27997
RD
1049 -- If the current scope is an init proc, then use the address of the
1050 -- _init formal as the object reference.
1051
1052 elsif Is_Init_Proc (Curr) then
1053 Obj_Ref :=
1054 Make_Attribute_Reference (Loc,
1055 Prefix => New_Occurrence_Of (First_Formal (Curr), Loc),
1056 Attribute_Name => Name_Address);
1057
7ce611e2
ES
1058 -- In case of protected subprograms the first formal of its
1059 -- Protected_Body_Subprogram is the object and we get its address.
1060
1061 else
1062 Obj_Ref :=
1063 Make_Attribute_Reference (Loc,
1064 Prefix =>
1065 New_Occurrence_Of
1066 (First_Formal
1067 (Protected_Body_Subprogram (Curr)), Loc),
1068 Attribute_Name => Name_Address);
1069 end if;
1070
d9206abb
JM
1071 elsif Has_By_Protected_Procedure_Prefixed_View then
1072 Obj_Ref :=
1073 Make_Attribute_Reference (Loc,
1074 Prefix => Relocate_Node (Prefix (Pref)),
1075 Attribute_Name => Name_Address);
1076
1077 -- Analyze the object address with expansion disabled. Required
1078 -- because its expansion would displace the pointer to the object,
1079 -- which is not correct at this stage since the object type is a
1080 -- class-wide interface type and we are dispatching a call to a
1081 -- thunk (which would erroneously displace the pointer again).
1082
1083 Expander_Mode_Save_And_Set (False);
1084 Analyze (Obj_Ref);
1085 Set_Analyzed (Obj_Ref);
1086 Expander_Mode_Restore;
1087
7ce611e2
ES
1088 -- Case where the prefix is not an entity name. Find the
1089 -- version of the protected operation to be called from
1090 -- outside the protected object.
1091
1092 else
1093 Sub :=
1094 New_Occurrence_Of
1095 (External_Subprogram
1096 (Entity (Selector_Name (Pref))), Loc);
1097
1098 Obj_Ref :=
1099 Make_Attribute_Reference (Loc,
1100 Prefix => Relocate_Node (Prefix (Pref)),
1101 Attribute_Name => Name_Address);
1102 end if;
1103
d9206abb
JM
1104 if Has_By_Protected_Procedure_Prefixed_View then
1105 declare
1106 Ctrl_Tag : Node_Id := Duplicate_Subexpr (Prefix (Pref));
1107 Prim_Addr : Node_Id;
1108 Subp : constant Entity_Id := Entity (Selector_Name (Pref));
1109 Typ : constant Entity_Id :=
1110 Etype (Etype (Entity (Prefix (Pref))));
1111 begin
1112 -- The target subprogram is a thunk; retrieve its address from
1113 -- its secondary dispatch table slot.
1114
1115 Build_Get_Prim_Op_Address (Loc,
1116 Typ => Typ,
1117 Tag_Node => Ctrl_Tag,
1118 Position => DT_Position (Subp),
1119 New_Node => Prim_Addr);
1120
1121 -- Mark the access to the target subprogram as an access to the
1122 -- dispatch table and perform an unchecked type conversion to such
1123 -- access type. This is required to allow the backend to properly
1124 -- identify and handle the access to the dispatch table slot on
1125 -- targets where the dispatch table contains descriptors (instead
1126 -- of pointers).
1127
1128 Set_Is_Dispatch_Table_Entity (Acc);
1129 Sub_Ref := Unchecked_Convert_To (Acc, Prim_Addr);
1130 Analyze (Sub_Ref);
1131
1132 Agg :=
1133 Make_Aggregate (Loc,
1134 Expressions => New_List (Obj_Ref, Sub_Ref));
1135 end;
1136
1137 -- Common case
e657b693 1138
d9206abb
JM
1139 else
1140 Sub_Ref :=
1141 Make_Attribute_Reference (Loc,
1142 Prefix => Sub,
1143 Attribute_Name => Name_Access);
e657b693 1144
d9206abb
JM
1145 -- We set the type of the access reference to the already generated
1146 -- access_to_subprogram type, and declare the reference analyzed,
1147 -- to prevent further expansion when the enclosing aggregate is
1148 -- analyzed.
e657b693 1149
d9206abb
JM
1150 Set_Etype (Sub_Ref, Acc);
1151 Set_Analyzed (Sub_Ref);
7ce611e2 1152
d9206abb
JM
1153 Agg :=
1154 Make_Aggregate (Loc,
1155 Expressions => New_List (Obj_Ref, Sub_Ref));
1f92d7f2 1156
d9206abb
JM
1157 -- Sub_Ref has been marked as analyzed, but we still need to make
1158 -- sure Sub is correctly frozen.
1159
1160 Freeze_Before (N, Entity (Sub));
1161 end if;
1f92d7f2 1162
7ce611e2 1163 Rewrite (N, Agg);
7ce611e2
ES
1164 Analyze_And_Resolve (N, E_T);
1165
f7e71125
AC
1166 -- For subsequent analysis, the node must retain its type. The backend
1167 -- will replace it with the equivalent type where needed.
7ce611e2
ES
1168
1169 Set_Etype (N, Typ);
1170 end Expand_Access_To_Protected_Op;
1171
70482933
RK
1172 --------------------------
1173 -- Expand_Fpt_Attribute --
1174 --------------------------
1175
1176 procedure Expand_Fpt_Attribute
1177 (N : Node_Id;
65f01153 1178 Pkg : RE_Id;
fbf5a39b 1179 Nam : Name_Id;
70482933
RK
1180 Args : List_Id)
1181 is
1182 Loc : constant Source_Ptr := Sloc (N);
1183 Typ : constant Entity_Id := Etype (N);
70482933
RK
1184 Fnm : Node_Id;
1185
1186 begin
65f01153
RD
1187 -- The function name is the selected component Attr_xxx.yyy where
1188 -- Attr_xxx is the package name, and yyy is the argument Nam.
70482933
RK
1189
1190 -- Note: it would be more usual to have separate RE entries for each
1191 -- of the entities in the Fat packages, but first they have identical
1192 -- names (so we would have to have lots of renaming declarations to
1193 -- meet the normal RE rule of separate names for all runtime entities),
a90bd866 1194 -- and second there would be an awful lot of them.
70482933 1195
70482933
RK
1196 Fnm :=
1197 Make_Selected_Component (Loc,
e4494292 1198 Prefix => New_Occurrence_Of (RTE (Pkg), Loc),
fbf5a39b 1199 Selector_Name => Make_Identifier (Loc, Nam));
70482933
RK
1200
1201 -- The generated call is given the provided set of parameters, and then
6a987d78 1202 -- wrapped in a conversion which converts the result to the target type.
70482933
RK
1203
1204 Rewrite (N,
6a987d78 1205 Convert_To (Typ,
70482933 1206 Make_Function_Call (Loc,
65f01153 1207 Name => Fnm,
70482933
RK
1208 Parameter_Associations => Args)));
1209
1210 Analyze_And_Resolve (N, Typ);
70482933
RK
1211 end Expand_Fpt_Attribute;
1212
1213 ----------------------------
1214 -- Expand_Fpt_Attribute_R --
1215 ----------------------------
1216
1217 -- The single argument is converted to its root type to call the
1218 -- appropriate runtime function, with the actual call being built
1219 -- by Expand_Fpt_Attribute
1220
1221 procedure Expand_Fpt_Attribute_R (N : Node_Id) is
90cb252f 1222 E1 : constant Node_Id := First (Expressions (N));
65f01153
RD
1223 Ftp : Entity_Id;
1224 Pkg : RE_Id;
70482933 1225 begin
65f01153 1226 Find_Fat_Info (Etype (E1), Ftp, Pkg);
fbf5a39b 1227 Expand_Fpt_Attribute
65f01153
RD
1228 (N, Pkg, Attribute_Name (N),
1229 New_List (Unchecked_Convert_To (Ftp, Relocate_Node (E1))));
70482933
RK
1230 end Expand_Fpt_Attribute_R;
1231
1232 -----------------------------
1233 -- Expand_Fpt_Attribute_RI --
1234 -----------------------------
1235
1236 -- The first argument is converted to its root type and the second
1237 -- argument is converted to standard long long integer to call the
1238 -- appropriate runtime function, with the actual call being built
1239 -- by Expand_Fpt_Attribute
1240
1241 procedure Expand_Fpt_Attribute_RI (N : Node_Id) is
90cb252f
PT
1242 E1 : constant Node_Id := First (Expressions (N));
1243 E2 : constant Node_Id := Next (E1);
65f01153
RD
1244 Ftp : Entity_Id;
1245 Pkg : RE_Id;
70482933 1246 begin
65f01153 1247 Find_Fat_Info (Etype (E1), Ftp, Pkg);
fbf5a39b 1248 Expand_Fpt_Attribute
65f01153 1249 (N, Pkg, Attribute_Name (N),
fbf5a39b 1250 New_List (
65f01153 1251 Unchecked_Convert_To (Ftp, Relocate_Node (E1)),
fbf5a39b 1252 Unchecked_Convert_To (Standard_Integer, Relocate_Node (E2))));
70482933
RK
1253 end Expand_Fpt_Attribute_RI;
1254
1255 -----------------------------
1256 -- Expand_Fpt_Attribute_RR --
1257 -----------------------------
1258
0669bebe 1259 -- The two arguments are converted to their root types to call the
70482933
RK
1260 -- appropriate runtime function, with the actual call being built
1261 -- by Expand_Fpt_Attribute
1262
1263 procedure Expand_Fpt_Attribute_RR (N : Node_Id) is
d436b30d
AC
1264 E1 : constant Node_Id := First (Expressions (N));
1265 E2 : constant Node_Id := Next (E1);
65f01153
RD
1266 Ftp : Entity_Id;
1267 Pkg : RE_Id;
d436b30d 1268
70482933 1269 begin
65f01153 1270 Find_Fat_Info (Etype (E1), Ftp, Pkg);
fbf5a39b 1271 Expand_Fpt_Attribute
65f01153 1272 (N, Pkg, Attribute_Name (N),
fbf5a39b 1273 New_List (
65f01153
RD
1274 Unchecked_Convert_To (Ftp, Relocate_Node (E1)),
1275 Unchecked_Convert_To (Ftp, Relocate_Node (E2))));
70482933
RK
1276 end Expand_Fpt_Attribute_RR;
1277
d436b30d
AC
1278 ---------------------------------
1279 -- Expand_Loop_Entry_Attribute --
1280 ---------------------------------
1281
aa9b151a 1282 procedure Expand_Loop_Entry_Attribute (N : Node_Id) is
d436b30d
AC
1283 procedure Build_Conditional_Block
1284 (Loc : Source_Ptr;
1285 Cond : Node_Id;
1286 Loop_Stmt : Node_Id;
1287 If_Stmt : out Node_Id;
1288 Blk_Stmt : out Node_Id);
1289 -- Create a block Blk_Stmt with an empty declarative list and a single
1290 -- loop Loop_Stmt. The block is encased in an if statement If_Stmt with
1291 -- condition Cond. If_Stmt is Empty when there is no condition provided.
1292
1293 function Is_Array_Iteration (N : Node_Id) return Boolean;
1294 -- Determine whether loop statement N denotes an Ada 2012 iteration over
1295 -- an array object.
1296
1297 -----------------------------
1298 -- Build_Conditional_Block --
1299 -----------------------------
1300
1301 procedure Build_Conditional_Block
1302 (Loc : Source_Ptr;
1303 Cond : Node_Id;
1304 Loop_Stmt : Node_Id;
1305 If_Stmt : out Node_Id;
1306 Blk_Stmt : out Node_Id)
1307 is
1308 begin
1309 -- Do not reanalyze the original loop statement because it is simply
1310 -- being relocated.
1311
1312 Set_Analyzed (Loop_Stmt);
1313
1314 Blk_Stmt :=
1315 Make_Block_Statement (Loc,
1316 Declarations => New_List,
1317 Handled_Statement_Sequence =>
1318 Make_Handled_Sequence_Of_Statements (Loc,
1319 Statements => New_List (Loop_Stmt)));
1320
1321 if Present (Cond) then
1322 If_Stmt :=
1323 Make_If_Statement (Loc,
1324 Condition => Cond,
1325 Then_Statements => New_List (Blk_Stmt));
1326 else
1327 If_Stmt := Empty;
1328 end if;
1329 end Build_Conditional_Block;
1330
1331 ------------------------
1332 -- Is_Array_Iteration --
1333 ------------------------
1334
1335 function Is_Array_Iteration (N : Node_Id) return Boolean is
1336 Stmt : constant Node_Id := Original_Node (N);
1337 Iter : Node_Id;
1338
1339 begin
1340 if Nkind (Stmt) = N_Loop_Statement
1341 and then Present (Iteration_Scheme (Stmt))
1342 and then Present (Iterator_Specification (Iteration_Scheme (Stmt)))
1343 then
1344 Iter := Iterator_Specification (Iteration_Scheme (Stmt));
1345
1346 return
1347 Of_Present (Iter) and then Is_Array_Type (Etype (Name (Iter)));
1348 end if;
1349
1350 return False;
1351 end Is_Array_Iteration;
1352
1353 -- Local variables
1354
aa9b151a 1355 Pref : constant Node_Id := Prefix (N);
0f83b044
AC
1356 Base_Typ : constant Entity_Id := Base_Type (Etype (Pref));
1357 Exprs : constant List_Id := Expressions (N);
1358 Aux_Decl : Node_Id;
dcd5fd67 1359 Blk : Node_Id := Empty;
d436b30d
AC
1360 Decls : List_Id;
1361 Installed : Boolean;
1362 Loc : Source_Ptr;
1363 Loop_Id : Entity_Id;
1364 Loop_Stmt : Node_Id;
31e358e1 1365 Result : Node_Id := Empty;
d436b30d
AC
1366 Scheme : Node_Id;
1367 Temp_Decl : Node_Id;
1368 Temp_Id : Entity_Id;
1369
1370 -- Start of processing for Expand_Loop_Entry_Attribute
1371
1372 begin
1373 -- Step 1: Find the related loop
1374
1375 -- The loop label variant of attribute 'Loop_Entry already has all the
1376 -- information in its expression.
1377
1378 if Present (Exprs) then
1379 Loop_Id := Entity (First (Exprs));
1380 Loop_Stmt := Label_Construct (Parent (Loop_Id));
1381
0f83b044
AC
1382 -- Climb the parent chain to find the nearest enclosing loop. Skip
1383 -- all internally generated loops for quantified expressions and for
1384 -- element iterators over multidimensional arrays because the pragma
1385 -- applies to source loop.
d436b30d
AC
1386
1387 else
aa9b151a 1388 Loop_Stmt := N;
d436b30d
AC
1389 while Present (Loop_Stmt) loop
1390 if Nkind (Loop_Stmt) = N_Loop_Statement
ae5115dd
AC
1391 and then Nkind (Original_Node (Loop_Stmt)) = N_Loop_Statement
1392 and then Comes_From_Source (Original_Node (Loop_Stmt))
d436b30d
AC
1393 then
1394 exit;
1395 end if;
1396
1397 Loop_Stmt := Parent (Loop_Stmt);
1398 end loop;
1399
1400 Loop_Id := Entity (Identifier (Loop_Stmt));
1401 end if;
1402
1403 Loc := Sloc (Loop_Stmt);
1404
1405 -- Step 2: Transform the loop
1406
1407 -- The loop has already been transformed during the expansion of a prior
1408 -- 'Loop_Entry attribute. Retrieve the declarative list of the block.
1409
1410 if Has_Loop_Entry_Attributes (Loop_Id) then
3d67b239
AC
1411
1412 -- When the related loop name appears as the argument of attribute
1413 -- Loop_Entry, the corresponding label construct is the generated
0d5fbf52 1414 -- block statement. This is because the expander reuses the label.
3d67b239 1415
24778dbb
AC
1416 if Nkind (Loop_Stmt) = N_Block_Statement then
1417 Decls := Declarations (Loop_Stmt);
3d67b239
AC
1418
1419 -- In all other cases, the loop must appear in the handled sequence
1420 -- of statements of the generated block.
1421
24778dbb 1422 else
3d67b239
AC
1423 pragma Assert
1424 (Nkind (Parent (Loop_Stmt)) = N_Handled_Sequence_Of_Statements
fc999c5d
RD
1425 and then
1426 Nkind (Parent (Parent (Loop_Stmt))) = N_Block_Statement);
24778dbb
AC
1427
1428 Decls := Declarations (Parent (Parent (Loop_Stmt)));
1429 end if;
1430
d436b30d
AC
1431 -- Transform the loop into a conditional block
1432
1433 else
1434 Set_Has_Loop_Entry_Attributes (Loop_Id);
1435 Scheme := Iteration_Scheme (Loop_Stmt);
1436
3d67b239
AC
1437 -- Infinite loops are transformed into:
1438
1439 -- declare
1440 -- Temp1 : constant <type of Pref1> := <Pref1>;
1441 -- . . .
1442 -- TempN : constant <type of PrefN> := <PrefN>;
1443 -- begin
1444 -- loop
1445 -- <original source statements with attribute rewrites>
1446 -- end loop;
1447 -- end;
1448
1449 if No (Scheme) then
1450 Build_Conditional_Block (Loc,
1451 Cond => Empty,
1452 Loop_Stmt => Relocate_Node (Loop_Stmt),
1453 If_Stmt => Result,
1454 Blk_Stmt => Blk);
1455
1456 Result := Blk;
1457
d436b30d
AC
1458 -- While loops are transformed into:
1459
fd7215d7
AC
1460 -- function Fnn return Boolean is
1461 -- begin
1462 -- <condition actions>
1463 -- return <condition>;
1464 -- end Fnn;
1465
1466 -- if Fnn then
d436b30d
AC
1467 -- declare
1468 -- Temp1 : constant <type of Pref1> := <Pref1>;
1469 -- . . .
1470 -- TempN : constant <type of PrefN> := <PrefN>;
1471 -- begin
1472 -- loop
1473 -- <original source statements with attribute rewrites>
fd7215d7 1474 -- exit when not Fnn;
d436b30d
AC
1475 -- end loop;
1476 -- end;
1477 -- end if;
1478
1479 -- Note that loops over iterators and containers are already
1480 -- converted into while loops.
1481
3d67b239 1482 elsif Present (Condition (Scheme)) then
d436b30d 1483 declare
fd7215d7
AC
1484 Func_Decl : Node_Id;
1485 Func_Id : Entity_Id;
1486 Stmts : List_Id;
d436b30d
AC
1487
1488 begin
c961d820
EB
1489 Func_Id := Make_Temporary (Loc, 'F');
1490
fd7215d7
AC
1491 -- Wrap the condition of the while loop in a Boolean function.
1492 -- This avoids the duplication of the same code which may lead
1493 -- to gigi issues with respect to multiple declaration of the
1494 -- same entity in the presence of side effects or checks. Note
75f6bfce
EB
1495 -- that the condition actions must also be relocated into the
1496 -- wrapping function because they may contain itypes, e.g. in
1497 -- the case of a comparison involving slices.
fd7215d7
AC
1498
1499 -- Generate:
1500 -- <condition actions>
1501 -- return <condition>;
1502
1503 if Present (Condition_Actions (Scheme)) then
1504 Stmts := Condition_Actions (Scheme);
1505 else
1506 Stmts := New_List;
1507 end if;
1508
1509 Append_To (Stmts,
1510 Make_Simple_Return_Statement (Loc,
c961d820
EB
1511 Expression =>
1512 New_Copy_Tree (Condition (Scheme),
1513 New_Scope => Func_Id)));
fd7215d7
AC
1514
1515 -- Generate:
1516 -- function Fnn return Boolean is
1517 -- begin
1518 -- <Stmts>
1519 -- end Fnn;
1520
fd7215d7
AC
1521 Func_Decl :=
1522 Make_Subprogram_Body (Loc,
1523 Specification =>
1524 Make_Function_Specification (Loc,
1525 Defining_Unit_Name => Func_Id,
1526 Result_Definition =>
1527 New_Occurrence_Of (Standard_Boolean, Loc)),
1528 Declarations => Empty_List,
1529 Handled_Statement_Sequence =>
1530 Make_Handled_Sequence_Of_Statements (Loc,
1531 Statements => Stmts));
1532
1533 -- The function is inserted before the related loop. Make sure
1534 -- to analyze it in the context of the loop's enclosing scope.
1535
1536 Push_Scope (Scope (Loop_Id));
1537 Insert_Action (Loop_Stmt, Func_Decl);
1538 Pop_Scope;
1539
07511699
GD
1540 -- The analysis of the condition may have generated entities
1541 -- (such as itypes) that are now used within the function.
1542 -- Adjust their scopes accordingly so that their use appears
1543 -- in their scope of definition.
b6b011dd
ES
1544
1545 declare
07511699 1546 Ent : Entity_Id;
b6b011dd
ES
1547
1548 begin
07511699
GD
1549 Ent := First_Entity (Loop_Id);
1550
1551 while Present (Ent) loop
1552 -- Various entities that now occur within the function
1553 -- need to have their scope reset, but not all entities
1554 -- associated with Loop_Id are now inside the function.
1555 -- The function entity itself and loop parameters can
1556 -- be outside the function, and there may be others.
1557 -- It's not clear how the determination of what entity
1558 -- scopes need to be adjusted can be made accurately.
1559 -- Perhaps it will be necessary to traverse the function
1560 -- body to find the exact entities whose scopes need to
1561 -- be reset to the function's Entity_Id. ???
1562
1563 if Ekind (Ent) /= E_Loop_Parameter
1564 and then Ent /= Func_Id
1565 then
1566 Set_Scope (Ent, Func_Id);
b6b011dd 1567 end if;
07511699
GD
1568
1569 Next_Entity (Ent);
b6b011dd
ES
1570 end loop;
1571 end;
1572
d436b30d
AC
1573 -- Transform the original while loop into an infinite loop
1574 -- where the last statement checks the negated condition. This
1575 -- placement ensures that the condition will not be evaluated
1576 -- twice on the first iteration.
1577
fd7215d7
AC
1578 Set_Iteration_Scheme (Loop_Stmt, Empty);
1579 Scheme := Empty;
1580
d436b30d 1581 -- Generate:
fd7215d7 1582 -- exit when not Fnn;
d436b30d
AC
1583
1584 Append_To (Statements (Loop_Stmt),
1585 Make_Exit_Statement (Loc,
fd7215d7
AC
1586 Condition =>
1587 Make_Op_Not (Loc,
1588 Right_Opnd =>
1589 Make_Function_Call (Loc,
1590 Name => New_Occurrence_Of (Func_Id, Loc)))));
d436b30d
AC
1591
1592 Build_Conditional_Block (Loc,
fd7215d7
AC
1593 Cond =>
1594 Make_Function_Call (Loc,
1595 Name => New_Occurrence_Of (Func_Id, Loc)),
d436b30d
AC
1596 Loop_Stmt => Relocate_Node (Loop_Stmt),
1597 If_Stmt => Result,
1598 Blk_Stmt => Blk);
1599 end;
1600
1601 -- Ada 2012 iteration over an array is transformed into:
1602
1603 -- if <Array_Nam>'Length (1) > 0
1604 -- and then <Array_Nam>'Length (N) > 0
1605 -- then
1606 -- declare
1607 -- Temp1 : constant <type of Pref1> := <Pref1>;
1608 -- . . .
1609 -- TempN : constant <type of PrefN> := <PrefN>;
1610 -- begin
1611 -- for X in ... loop -- multiple loops depending on dims
1612 -- <original source statements with attribute rewrites>
1613 -- end loop;
1614 -- end;
1615 -- end if;
1616
1617 elsif Is_Array_Iteration (Loop_Stmt) then
1618 declare
1619 Array_Nam : constant Entity_Id :=
1620 Entity (Name (Iterator_Specification
1621 (Iteration_Scheme (Original_Node (Loop_Stmt)))));
1622 Num_Dims : constant Pos :=
1623 Number_Dimensions (Etype (Array_Nam));
1624 Cond : Node_Id := Empty;
1625 Check : Node_Id;
1626
1627 begin
1628 -- Generate a check which determines whether all dimensions of
1629 -- the array are non-null.
1630
1631 for Dim in 1 .. Num_Dims loop
1632 Check :=
1633 Make_Op_Gt (Loc,
1634 Left_Opnd =>
1635 Make_Attribute_Reference (Loc,
e4494292 1636 Prefix => New_Occurrence_Of (Array_Nam, Loc),
d436b30d
AC
1637 Attribute_Name => Name_Length,
1638 Expressions => New_List (
1639 Make_Integer_Literal (Loc, Dim))),
1640 Right_Opnd =>
1641 Make_Integer_Literal (Loc, 0));
1642
1643 if No (Cond) then
1644 Cond := Check;
1645 else
1646 Cond :=
1647 Make_And_Then (Loc,
1648 Left_Opnd => Cond,
1649 Right_Opnd => Check);
1650 end if;
1651 end loop;
1652
1653 Build_Conditional_Block (Loc,
1654 Cond => Cond,
1655 Loop_Stmt => Relocate_Node (Loop_Stmt),
1656 If_Stmt => Result,
1657 Blk_Stmt => Blk);
1658 end;
1659
1660 -- For loops are transformed into:
1661
1662 -- if <Low> <= <High> then
1663 -- declare
1664 -- Temp1 : constant <type of Pref1> := <Pref1>;
1665 -- . . .
1666 -- TempN : constant <type of PrefN> := <PrefN>;
1667 -- begin
1668 -- for <Def_Id> in <Low> .. <High> loop
1669 -- <original source statements with attribute rewrites>
1670 -- end loop;
1671 -- end;
1672 -- end if;
1673
1674 elsif Present (Loop_Parameter_Specification (Scheme)) then
1675 declare
1676 Loop_Spec : constant Node_Id :=
1677 Loop_Parameter_Specification (Scheme);
1678 Cond : Node_Id;
1679 Subt_Def : Node_Id;
1680
1681 begin
1682 Subt_Def := Discrete_Subtype_Definition (Loop_Spec);
1683
1684 -- When the loop iterates over a subtype indication with a
1685 -- range, use the low and high bounds of the subtype itself.
1686
1687 if Nkind (Subt_Def) = N_Subtype_Indication then
1688 Subt_Def := Scalar_Range (Etype (Subt_Def));
1689 end if;
1690
1691 pragma Assert (Nkind (Subt_Def) = N_Range);
1692
1693 -- Generate
1694 -- Low <= High
1695
1696 Cond :=
1697 Make_Op_Le (Loc,
1698 Left_Opnd => New_Copy_Tree (Low_Bound (Subt_Def)),
1699 Right_Opnd => New_Copy_Tree (High_Bound (Subt_Def)));
1700
1701 Build_Conditional_Block (Loc,
1702 Cond => Cond,
1703 Loop_Stmt => Relocate_Node (Loop_Stmt),
1704 If_Stmt => Result,
1705 Blk_Stmt => Blk);
1706 end;
d436b30d
AC
1707 end if;
1708
1709 Decls := Declarations (Blk);
1710 end if;
1711
1712 -- Step 3: Create a constant to capture the value of the prefix at the
1713 -- entry point into the loop.
1714
d436b30d
AC
1715 Temp_Id := Make_Temporary (Loc, 'P');
1716
6c802906
AC
1717 -- Preserve the tag of the prefix by offering a specific view of the
1718 -- class-wide version of the prefix.
1719
0f83b044
AC
1720 if Is_Tagged_Type (Base_Typ) then
1721 Tagged_Case : declare
1722 CW_Temp : Entity_Id;
1723 CW_Typ : Entity_Id;
1724
1725 begin
1726 -- Generate:
1727 -- CW_Temp : constant Base_Typ'Class := Base_Typ'Class (Pref);
1728
1729 CW_Temp := Make_Temporary (Loc, 'T');
1730 CW_Typ := Class_Wide_Type (Base_Typ);
1731
1732 Aux_Decl :=
1733 Make_Object_Declaration (Loc,
1734 Defining_Identifier => CW_Temp,
1735 Constant_Present => True,
1736 Object_Definition => New_Occurrence_Of (CW_Typ, Loc),
1737 Expression =>
1738 Convert_To (CW_Typ, Relocate_Node (Pref)));
1739 Append_To (Decls, Aux_Decl);
1740
1741 -- Generate:
1742 -- Temp : Base_Typ renames Base_Typ (CW_Temp);
1743
1744 Temp_Decl :=
1745 Make_Object_Renaming_Declaration (Loc,
1746 Defining_Identifier => Temp_Id,
1747 Subtype_Mark => New_Occurrence_Of (Base_Typ, Loc),
1748 Name =>
1749 Convert_To (Base_Typ, New_Occurrence_Of (CW_Temp, Loc)));
1750 Append_To (Decls, Temp_Decl);
1751 end Tagged_Case;
1752
1753 -- Untagged case
6c802906
AC
1754
1755 else
0f83b044
AC
1756 Untagged_Case : declare
1757 Temp_Expr : Node_Id;
1758
1759 begin
1760 Aux_Decl := Empty;
1761
1762 -- Generate a nominal type for the constant when the prefix is of
1763 -- a constrained type. This is achieved by setting the Etype of
1764 -- the relocated prefix to its base type. Since the prefix is now
1765 -- the initialization expression of the constant, its freezing
1766 -- will produce a proper nominal type.
1767
1768 Temp_Expr := Relocate_Node (Pref);
1769 Set_Etype (Temp_Expr, Base_Typ);
1770
1771 -- Generate:
1772 -- Temp : constant Base_Typ := Pref;
1773
1774 Temp_Decl :=
1775 Make_Object_Declaration (Loc,
1776 Defining_Identifier => Temp_Id,
1777 Constant_Present => True,
1778 Object_Definition => New_Occurrence_Of (Base_Typ, Loc),
1779 Expression => Temp_Expr);
1780 Append_To (Decls, Temp_Decl);
1781 end Untagged_Case;
6c802906 1782 end if;
d436b30d
AC
1783
1784 -- Step 4: Analyze all bits
1785
3d67b239 1786 Installed := Current_Scope = Scope (Loop_Id);
d436b30d 1787
327b1ba4
AC
1788 -- Depending on the pracement of attribute 'Loop_Entry relative to the
1789 -- associated loop, ensure the proper visibility for analysis.
1790
d436b30d
AC
1791 if not Installed then
1792 Push_Scope (Scope (Loop_Id));
1793 end if;
1794
327b1ba4
AC
1795 -- The analysis of the conditional block takes care of the constant
1796 -- declaration.
1797
d436b30d
AC
1798 if Present (Result) then
1799 Rewrite (Loop_Stmt, Result);
1800 Analyze (Loop_Stmt);
327b1ba4
AC
1801
1802 -- The conditional block was analyzed when a previous 'Loop_Entry was
1803 -- expanded. There is no point in reanalyzing the block, simply analyze
1804 -- the declaration of the constant.
1805
d436b30d 1806 else
0f83b044
AC
1807 if Present (Aux_Decl) then
1808 Analyze (Aux_Decl);
6c802906
AC
1809 end if;
1810
d436b30d
AC
1811 Analyze (Temp_Decl);
1812 end if;
1813
fd7215d7 1814 Rewrite (N, New_Occurrence_Of (Temp_Id, Loc));
aa9b151a 1815 Analyze (N);
d436b30d 1816
d436b30d
AC
1817 if not Installed then
1818 Pop_Scope;
1819 end if;
1820 end Expand_Loop_Entry_Attribute;
1821
e0f63680
AC
1822 ------------------------------
1823 -- Expand_Min_Max_Attribute --
1824 ------------------------------
1825
1826 procedure Expand_Min_Max_Attribute (N : Node_Id) is
1827 begin
1828 -- Min and Max are handled by the back end (except that static cases
1829 -- have already been evaluated during semantic processing, although the
1830 -- back end should not count on this). The one bit of special processing
1831 -- required in the normal case is that these two attributes typically
1832 -- generate conditionals in the code, so check the relevant restriction.
1833
1834 Check_Restriction (No_Implicit_Conditionals, N);
e0f63680
AC
1835 end Expand_Min_Max_Attribute;
1836
70482933
RK
1837 ----------------------------------
1838 -- Expand_N_Attribute_Reference --
1839 ----------------------------------
1840
1841 procedure Expand_N_Attribute_Reference (N : Node_Id) is
23a9215f
PT
1842 Loc : constant Source_Ptr := Sloc (N);
1843 Pref : constant Node_Id := Prefix (N);
1844 Exprs : constant List_Id := Expressions (N);
70482933 1845
f193b29e
EB
1846 function Get_Integer_Type (Typ : Entity_Id) return Entity_Id;
1847 -- Return a small integer type appropriate for the enumeration type
1848
110d0820
BD
1849 procedure Rewrite_Attribute_Proc_Call (Pname : Entity_Id);
1850 -- Rewrites an attribute for Read, Write, Output, or Put_Image with a
1851 -- call to the appropriate TSS procedure. Pname is the entity for the
1852 -- procedure to call.
70482933 1853
f193b29e
EB
1854 ----------------------
1855 -- Get_Integer_Type --
1856 ----------------------
1857
1858 function Get_Integer_Type (Typ : Entity_Id) return Entity_Id is
cdf4576b 1859 Siz : constant Uint := Esize (Base_Type (Typ));
f193b29e
EB
1860
1861 begin
25a11453 1862 -- We need to accommodate invalid values of the base type since we
cdf4576b 1863 -- accept them for Enum_Rep and Pos, so we reason on the Esize.
f193b29e 1864
cdf4576b 1865 return Small_Integer_Type_For (Siz, Uns => Is_Unsigned_Type (Typ));
f193b29e
EB
1866 end Get_Integer_Type;
1867
110d0820
BD
1868 ---------------------------------
1869 -- Rewrite_Attribute_Proc_Call --
1870 ---------------------------------
70482933 1871
110d0820 1872 procedure Rewrite_Attribute_Proc_Call (Pname : Entity_Id) is
70482933 1873 Item : constant Node_Id := Next (First (Exprs));
ed3fe8cc 1874 Item_Typ : constant Entity_Id := Etype (Item);
fbf5a39b
AC
1875 Formal : constant Entity_Id := Next_Formal (First_Formal (Pname));
1876 Formal_Typ : constant Entity_Id := Etype (Formal);
ed3fe8cc 1877 Is_Written : constant Boolean := Ekind (Formal) /= E_In_Parameter;
70482933
RK
1878
1879 begin
fbf5a39b
AC
1880 -- The expansion depends on Item, the second actual, which is
1881 -- the object being streamed in or out.
1882
1883 -- If the item is a component of a packed array type, and
1884 -- a conversion is needed on exit, we introduce a temporary to
1885 -- hold the value, because otherwise the packed reference will
1886 -- not be properly expanded.
1887
1888 if Nkind (Item) = N_Indexed_Component
1889 and then Is_Packed (Base_Type (Etype (Prefix (Item))))
ed3fe8cc 1890 and then Base_Type (Item_Typ) /= Base_Type (Formal_Typ)
fbf5a39b
AC
1891 and then Is_Written
1892 then
1893 declare
191fcb3a 1894 Temp : constant Entity_Id := Make_Temporary (Loc, 'V');
fbf5a39b
AC
1895 Decl : Node_Id;
1896 Assn : Node_Id;
1897
1898 begin
1899 Decl :=
1900 Make_Object_Declaration (Loc,
1901 Defining_Identifier => Temp,
ed3fe8cc 1902 Object_Definition => New_Occurrence_Of (Formal_Typ, Loc));
fbf5a39b
AC
1903 Set_Etype (Temp, Formal_Typ);
1904
1905 Assn :=
1906 Make_Assignment_Statement (Loc,
ed3fe8cc 1907 Name => New_Copy_Tree (Item),
fbf5a39b
AC
1908 Expression =>
1909 Unchecked_Convert_To
ed3fe8cc 1910 (Item_Typ, New_Occurrence_Of (Temp, Loc)));
fbf5a39b
AC
1911
1912 Rewrite (Item, New_Occurrence_Of (Temp, Loc));
1913 Insert_Actions (N,
1914 New_List (
1915 Decl,
1916 Make_Procedure_Call_Statement (Loc,
ed3fe8cc 1917 Name => New_Occurrence_Of (Pname, Loc),
fbf5a39b
AC
1918 Parameter_Associations => Exprs),
1919 Assn));
1920
1921 Rewrite (N, Make_Null_Statement (Loc));
1922 return;
1923 end;
1924 end if;
70482933
RK
1925
1926 -- For the class-wide dispatching cases, and for cases in which
1927 -- the base type of the second argument matches the base type of
fbf5a39b
AC
1928 -- the corresponding formal parameter (that is to say the stream
1929 -- operation is not inherited), we are all set, and can use the
1930 -- argument unchanged.
70482933 1931
70482933 1932 if not Is_Class_Wide_Type (Entity (Pref))
fbf5a39b 1933 and then not Is_Class_Wide_Type (Etype (Item))
ed3fe8cc 1934 and then Base_Type (Item_Typ) /= Base_Type (Formal_Typ)
70482933 1935 then
ed3fe8cc
AC
1936 -- Perform a view conversion when either the argument or the
1937 -- formal parameter are of a private type.
1938
b5360737
AC
1939 if Is_Private_Type (Base_Type (Formal_Typ))
1940 or else Is_Private_Type (Base_Type (Item_Typ))
ed3fe8cc
AC
1941 then
1942 Rewrite (Item,
1943 Unchecked_Convert_To (Formal_Typ, Relocate_Node (Item)));
1944
1945 -- Otherwise perform a regular type conversion to ensure that all
1946 -- relevant checks are installed.
1947
1948 else
1949 Rewrite (Item, Convert_To (Formal_Typ, Relocate_Node (Item)));
1950 end if;
70482933
RK
1951
1952 -- For untagged derived types set Assignment_OK, to prevent
1953 -- copies from being created when the unchecked conversion
1954 -- is expanded (which would happen in Remove_Side_Effects
1955 -- if Expand_N_Unchecked_Conversion were allowed to call
365c8496
RD
1956 -- Force_Evaluation). The copy could violate Ada semantics in
1957 -- cases such as an actual that is an out parameter. Note that
1958 -- this approach is also used in exp_ch7 for calls to controlled
1959 -- type operations to prevent problems with actuals wrapped in
1960 -- unchecked conversions.
70482933
RK
1961
1962 if Is_Untagged_Derivation (Etype (Expression (Item))) then
1963 Set_Assignment_OK (Item);
1964 end if;
1965 end if;
1966
110d0820
BD
1967 -- The stream operation to call might be a renaming created by an
1968 -- attribute definition clause, and might not be frozen yet. Ensure
365c8496 1969 -- that it has the necessary extra formals.
99269cf5
ES
1970
1971 if not Is_Frozen (Pname) then
1972 Create_Extra_Formals (Pname);
1973 end if;
1974
70482933
RK
1975 -- And now rewrite the call
1976
1977 Rewrite (N,
1978 Make_Procedure_Call_Statement (Loc,
ed3fe8cc 1979 Name => New_Occurrence_Of (Pname, Loc),
70482933
RK
1980 Parameter_Associations => Exprs));
1981
1982 Analyze (N);
110d0820
BD
1983 end Rewrite_Attribute_Proc_Call;
1984
23a9215f
PT
1985 Typ : constant Entity_Id := Etype (N);
1986 Btyp : constant Entity_Id := Base_Type (Typ);
1987 Ptyp : constant Entity_Id := Etype (Pref);
1988 Id : constant Attribute_Id := Get_Attribute_Id (Attribute_Name (N));
70482933
RK
1989
1990 -- Start of processing for Expand_N_Attribute_Reference
1991
1992 begin
82c80734
RD
1993 -- Do required validity checking, if enabled. Do not apply check to
1994 -- output parameters of an Asm instruction, since the value of this
1dcdbfab
AC
1995 -- is not set till after the attribute has been elaborated, and do
1996 -- not apply the check to the arguments of a 'Read or 'Input attribute
1997 -- reference since the scalar argument is an OUT scalar.
70482933 1998
82c80734
RD
1999 if Validity_Checks_On and then Validity_Check_Operands
2000 and then Id /= Attribute_Asm_Output
1dcdbfab
AC
2001 and then Id /= Attribute_Read
2002 and then Id /= Attribute_Input
82c80734 2003 then
70482933
RK
2004 declare
2005 Expr : Node_Id;
70482933
RK
2006 begin
2007 Expr := First (Expressions (N));
2008 while Present (Expr) loop
2009 Ensure_Valid (Expr);
2010 Next (Expr);
2011 end loop;
2012 end;
2013 end if;
2014
21d27997
RD
2015 -- Ada 2005 (AI-318-02): If attribute prefix is a call to a build-in-
2016 -- place function, then a temporary return object needs to be created
d4dfb005 2017 -- and access to it must be passed to the function.
21d27997 2018
d4dfb005 2019 if Is_Build_In_Place_Function_Call (Pref) then
fb9dd1c7
PMR
2020
2021 -- If attribute is 'Old, the context is a postcondition, and
2022 -- the temporary must go in the corresponding subprogram, not
2023 -- the postcondition function or any created blocks, as when
2024 -- the attribute appears in a quantified expression. This is
2025 -- handled below in the expansion of the attribute.
2026
2027 if Attribute_Name (Parent (Pref)) = Name_Old then
2028 null;
fb9dd1c7
PMR
2029 else
2030 Make_Build_In_Place_Call_In_Anonymous_Context (Pref);
2031 end if;
4ac62786
AC
2032
2033 -- Ada 2005 (AI-318-02): Specialization of the previous case for prefix
2034 -- containing build-in-place function calls whose returned object covers
2035 -- interface types.
2036
d4dfb005 2037 elsif Present (Unqual_BIP_Iface_Function_Call (Pref)) then
4ac62786 2038 Make_Build_In_Place_Iface_Call_In_Anonymous_Context (Pref);
21d27997
RD
2039 end if;
2040
5f3f175d
AC
2041 -- If prefix is a protected type name, this is a reference to the
2042 -- current instance of the type. For a component definition, nothing
2043 -- to do (expansion will occur in the init proc). In other contexts,
2044 -- rewrite into reference to current instance.
2045
2046 if Is_Protected_Self_Reference (Pref)
1e4b91fc 2047 and then not
4a08c95c
AC
2048 (Nkind (Parent (N)) in N_Index_Or_Discriminant_Constraint
2049 | N_Discriminant_Association
8926d369 2050 and then Nkind (Parent (Parent (Parent (Parent (N))))) =
69ba91ed 2051 N_Component_Definition)
1e4b91fc
AC
2052
2053 -- No action needed for these attributes since the current instance
2054 -- will be rewritten to be the name of the _object parameter
2055 -- associated with the enclosing protected subprogram (see below).
2056
2057 and then Id /= Attribute_Access
2058 and then Id /= Attribute_Unchecked_Access
2059 and then Id /= Attribute_Unrestricted_Access
5f3f175d 2060 then
2d14501c
ST
2061 Rewrite (Pref, Concurrent_Ref (Pref));
2062 Analyze (Pref);
2063 end if;
2064
70482933
RK
2065 -- Remaining processing depends on specific attribute
2066
2eef7403
AC
2067 -- Note: individual sections of the following case statement are
2068 -- allowed to assume there is no code after the case statement, and
2069 -- are legitimately allowed to execute return statements if they have
2070 -- nothing more to do.
2071
70482933
RK
2072 case Id is
2073
82d4f390 2074 -- Attributes related to Ada 2012 iterators
0da80d7d 2075
d8f43ee6
HK
2076 when Attribute_Constant_Indexing
2077 | Attribute_Default_Iterator
2078 | Attribute_Implicit_Dereference
2079 | Attribute_Iterable
2080 | Attribute_Iterator_Element
2081 | Attribute_Variable_Indexing
2082 =>
d48f3dca 2083 null;
b98e2969 2084
d27f3ff4
AC
2085 -- Internal attributes used to deal with Ada 2012 delayed aspects. These
2086 -- were already rejected by the parser. Thus they shouldn't appear here.
b98e2969 2087
c1107fa3 2088 when Internal_Attribute_Id =>
d48f3dca 2089 raise Program_Error;
0da80d7d 2090
70482933
RK
2091 ------------
2092 -- Access --
2093 ------------
2094
d8f43ee6
HK
2095 when Attribute_Access
2096 | Attribute_Unchecked_Access
2097 | Attribute_Unrestricted_Access
2098 =>
3192631e 2099 Access_Cases : declare
3192631e 2100 Ref_Object : constant Node_Id := Get_Referenced_Object (Pref);
0d4aed99 2101 Btyp_DDT : Entity_Id;
70482933 2102
01aef5ad
GD
2103 function Enclosing_Object (N : Node_Id) return Node_Id;
2104 -- If N denotes a compound name (selected component, indexed
69ba91ed
AC
2105 -- component, or slice), returns the name of the outermost such
2106 -- enclosing object. Otherwise returns N. If the object is a
2107 -- renaming, then the renamed object is returned.
01aef5ad
GD
2108
2109 ----------------------
2110 -- Enclosing_Object --
2111 ----------------------
2112
2113 function Enclosing_Object (N : Node_Id) return Node_Id is
2114 Obj_Name : Node_Id;
2115
2116 begin
2117 Obj_Name := N;
4a08c95c
AC
2118 while Nkind (Obj_Name) in N_Selected_Component
2119 | N_Indexed_Component
2120 | N_Slice
01aef5ad
GD
2121 loop
2122 Obj_Name := Prefix (Obj_Name);
2123 end loop;
2124
2125 return Get_Referenced_Object (Obj_Name);
2126 end Enclosing_Object;
2127
2128 -- Local declarations
2129
2130 Enc_Object : constant Node_Id := Enclosing_Object (Ref_Object);
2131
2132 -- Start of processing for Access_Cases
2133
3192631e 2134 begin
0d4aed99
AC
2135 Btyp_DDT := Designated_Type (Btyp);
2136
2137 -- Handle designated types that come from the limited view
2138
47346923
AC
2139 if From_Limited_With (Btyp_DDT)
2140 and then Has_Non_Limited_View (Btyp_DDT)
0d4aed99
AC
2141 then
2142 Btyp_DDT := Non_Limited_View (Btyp_DDT);
0d4aed99
AC
2143 end if;
2144
e10dab7f
JM
2145 -- In order to improve the text of error messages, the designated
2146 -- type of access-to-subprogram itypes is set by the semantics as
2147 -- the associated subprogram entity (see sem_attr). Now we replace
2148 -- such node with the proper E_Subprogram_Type itype.
2149
2150 if Id = Attribute_Unrestricted_Access
2151 and then Is_Subprogram (Directly_Designated_Type (Typ))
2152 then
21d27997 2153 -- The following conditions ensure that this special management
e10dab7f
JM
2154 -- is done only for "Address!(Prim'Unrestricted_Access)" nodes.
2155 -- At this stage other cases in which the designated type is
2156 -- still a subprogram (instead of an E_Subprogram_Type) are
e14c931f 2157 -- wrong because the semantics must have overridden the type of
e10dab7f
JM
2158 -- the node with the type imposed by the context.
2159
21d27997 2160 if Nkind (Parent (N)) = N_Unchecked_Type_Conversion
3477e0b2 2161 and then Is_RTE (Etype (Parent (N)), RE_Prim_Ptr)
21d27997
RD
2162 then
2163 Set_Etype (N, RTE (RE_Prim_Ptr));
e10dab7f 2164
21d27997
RD
2165 else
2166 declare
2167 Subp : constant Entity_Id :=
2168 Directly_Designated_Type (Typ);
2169 Etyp : Entity_Id;
2170 Extra : Entity_Id := Empty;
2171 New_Formal : Entity_Id;
2172 Old_Formal : Entity_Id := First_Formal (Subp);
2173 Subp_Typ : Entity_Id;
e10dab7f 2174
21d27997
RD
2175 begin
2176 Subp_Typ := Create_Itype (E_Subprogram_Type, N);
d235950e 2177 Copy_Strub_Mode (Subp_Typ, Subp);
21d27997
RD
2178 Set_Etype (Subp_Typ, Etype (Subp));
2179 Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
e10dab7f 2180
21d27997
RD
2181 if Present (Old_Formal) then
2182 New_Formal := New_Copy (Old_Formal);
2183 Set_First_Entity (Subp_Typ, New_Formal);
e10dab7f 2184
21d27997
RD
2185 loop
2186 Set_Scope (New_Formal, Subp_Typ);
2187 Etyp := Etype (New_Formal);
e10dab7f 2188
21d27997
RD
2189 -- Handle itypes. There is no need to duplicate
2190 -- here the itypes associated with record types
2191 -- (i.e the implicit full view of private types).
e10dab7f 2192
21d27997
RD
2193 if Is_Itype (Etyp)
2194 and then Ekind (Base_Type (Etyp)) /= E_Record_Type
e10dab7f 2195 then
21d27997
RD
2196 Extra := New_Copy (Etyp);
2197 Set_Parent (Extra, New_Formal);
2198 Set_Etype (New_Formal, Extra);
2199 Set_Scope (Extra, Subp_Typ);
e10dab7f
JM
2200 end if;
2201
21d27997
RD
2202 Extra := New_Formal;
2203 Next_Formal (Old_Formal);
2204 exit when No (Old_Formal);
e10dab7f 2205
3f6d1daa
JS
2206 Link_Entities (New_Formal, New_Copy (Old_Formal));
2207 Next_Entity (New_Formal);
21d27997 2208 end loop;
e10dab7f 2209
3f6d1daa 2210 Unlink_Next_Entity (New_Formal);
21d27997
RD
2211 Set_Last_Entity (Subp_Typ, Extra);
2212 end if;
e10dab7f 2213
21d27997
RD
2214 -- Now that the explicit formals have been duplicated,
2215 -- any extra formals needed by the subprogram must be
2216 -- created.
e10dab7f 2217
21d27997
RD
2218 if Present (Extra) then
2219 Set_Extra_Formal (Extra, Empty);
2220 end if;
e10dab7f 2221
21d27997
RD
2222 Create_Extra_Formals (Subp_Typ);
2223 Set_Directly_Designated_Type (Typ, Subp_Typ);
2224 end;
2225 end if;
e10dab7f
JM
2226 end if;
2227
3192631e
JM
2228 if Is_Access_Protected_Subprogram_Type (Btyp) then
2229 Expand_Access_To_Protected_Op (N, Pref, Typ);
2230
475e1d24
JM
2231 -- If prefix is a subprogram that has class-wide preconditions and
2232 -- an indirect-call wrapper (ICW) of such subprogram is available
2233 -- then replace the prefix by the ICW.
2234
2235 elsif Is_Access_Subprogram_Type (Btyp)
2236 and then Is_Entity_Name (Pref)
2237 and then Present (Class_Preconditions (Entity (Pref)))
2238 and then Present (Indirect_Call_Wrapper (Entity (Pref)))
2239 then
2240 Rewrite (Pref,
2241 New_Occurrence_Of
2242 (Indirect_Call_Wrapper (Entity (Pref)), Loc));
2243 Analyze_And_Resolve (N, Typ);
2244
3192631e
JM
2245 -- If prefix is a type name, this is a reference to the current
2246 -- instance of the type, within its initialization procedure.
2247
2248 elsif Is_Entity_Name (Pref)
2249 and then Is_Type (Entity (Pref))
2250 then
2251 declare
2252 Par : Node_Id;
2253 Formal : Entity_Id;
2254
2255 begin
2256 -- If the current instance name denotes a task type, then
2257 -- the access attribute is rewritten to be the name of the
2258 -- "_task" parameter associated with the task type's task
2259 -- procedure. An unchecked conversion is applied to ensure
2260 -- a type match in cases of expander-generated calls (e.g.
2261 -- init procs).
2262
2263 if Is_Task_Type (Entity (Pref)) then
2264 Formal :=
2265 First_Entity (Get_Task_Body_Procedure (Entity (Pref)));
2266 while Present (Formal) loop
2267 exit when Chars (Formal) = Name_uTask;
2268 Next_Entity (Formal);
2269 end loop;
2270
2271 pragma Assert (Present (Formal));
3e8ee849 2272
3192631e
JM
2273 Rewrite (N,
2274 Unchecked_Convert_To (Typ,
2275 New_Occurrence_Of (Formal, Loc)));
2276 Set_Etype (N, Typ);
3e8ee849 2277
1e4b91fc
AC
2278 elsif Is_Protected_Type (Entity (Pref)) then
2279
2280 -- No action needed for current instance located in a
2281 -- component definition (expansion will occur in the
2282 -- init proc)
2283
2284 if Is_Protected_Type (Current_Scope) then
2285 null;
2286
2287 -- If the current instance reference is located in a
2288 -- protected subprogram or entry then rewrite the access
2289 -- attribute to be the name of the "_object" parameter.
2290 -- An unchecked conversion is applied to ensure a type
2291 -- match in cases of expander-generated calls (e.g. init
2292 -- procs).
2293
289a994b
AC
2294 -- The code may be nested in a block, so find enclosing
2295 -- scope that is a protected operation.
2296
1e4b91fc 2297 else
289a994b
AC
2298 declare
2299 Subp : Entity_Id;
2300
2301 begin
2302 Subp := Current_Scope;
4a08c95c 2303 while Ekind (Subp) in E_Loop | E_Block loop
289a994b
AC
2304 Subp := Scope (Subp);
2305 end loop;
2306
2307 Formal :=
2308 First_Entity
2309 (Protected_Body_Subprogram (Subp));
2310
2311 -- For a protected subprogram the _Object parameter
2312 -- is the protected record, so we create an access
2313 -- to it. The _Object parameter of an entry is an
2314 -- address.
2315
2316 if Ekind (Subp) = E_Entry then
2317 Rewrite (N,
2318 Unchecked_Convert_To (Typ,
2319 New_Occurrence_Of (Formal, Loc)));
2320 Set_Etype (N, Typ);
2321
2322 else
2323 Rewrite (N,
2324 Unchecked_Convert_To (Typ,
2325 Make_Attribute_Reference (Loc,
2326 Attribute_Name => Name_Unrestricted_Access,
59fad002
AC
2327 Prefix =>
2328 New_Occurrence_Of (Formal, Loc))));
289a994b
AC
2329 Analyze_And_Resolve (N);
2330 end if;
2331 end;
1e4b91fc
AC
2332 end if;
2333
2334 -- The expression must appear in a default expression,
2335 -- (which in the initialization procedure is the right-hand
2336 -- side of an assignment), and not in a discriminant
2337 -- constraint.
3e8ee849 2338
3192631e
JM
2339 else
2340 Par := Parent (N);
2341 while Present (Par) loop
2342 exit when Nkind (Par) = N_Assignment_Statement;
3e8ee849 2343
3192631e
JM
2344 if Nkind (Par) = N_Component_Declaration then
2345 return;
2346 end if;
3e8ee849 2347
3192631e
JM
2348 Par := Parent (Par);
2349 end loop;
3e8ee849 2350
3192631e
JM
2351 if Present (Par) then
2352 Rewrite (N,
2353 Make_Attribute_Reference (Loc,
2354 Prefix => Make_Identifier (Loc, Name_uInit),
2355 Attribute_Name => Attribute_Name (N)));
3e8ee849 2356
3192631e
JM
2357 Analyze_And_Resolve (N, Typ);
2358 end if;
3e8ee849 2359 end if;
3192631e
JM
2360 end;
2361
2362 -- If the prefix of an Access attribute is a dereference of an
01aef5ad
GD
2363 -- access parameter (or a renaming of such a dereference, or a
2364 -- subcomponent of such a dereference) and the context is a
ae8c7d87
RD
2365 -- general access type (including the type of an object or
2366 -- component with an access_definition, but not the anonymous
2367 -- type of an access parameter or access discriminant), then
01aef5ad
GD
2368 -- apply an accessibility check to the access parameter. We used
2369 -- to rewrite the access parameter as a type conversion, but that
2370 -- could only be done if the immediate prefix of the Access
2371 -- attribute was the dereference, and didn't handle cases where
2372 -- the attribute is applied to a subcomponent of the dereference,
2373 -- since there's generally no available, appropriate access type
e84e11ba
GD
2374 -- to convert to in that case. The attribute is passed as the
2375 -- point to insert the check, because the access parameter may
2376 -- come from a renaming, possibly in a different scope, and the
2377 -- check must be associated with the attribute itself.
01aef5ad
GD
2378
2379 elsif Id = Attribute_Access
2380 and then Nkind (Enc_Object) = N_Explicit_Dereference
2381 and then Is_Entity_Name (Prefix (Enc_Object))
ae8c7d87
RD
2382 and then (Ekind (Btyp) = E_General_Access_Type
2383 or else Is_Local_Anonymous_Access (Btyp))
b21732c5 2384 and then Is_Formal (Entity (Prefix (Enc_Object)))
01aef5ad 2385 and then Ekind (Etype (Entity (Prefix (Enc_Object))))
3192631e
JM
2386 = E_Anonymous_Access_Type
2387 and then Present (Extra_Accessibility
01aef5ad 2388 (Entity (Prefix (Enc_Object))))
bcb8c3bb 2389 and then not No_Dynamic_Accessibility_Checks_Enabled (Enc_Object)
3192631e 2390 then
e84e11ba 2391 Apply_Accessibility_Check (Prefix (Enc_Object), Typ, N);
3192631e
JM
2392
2393 -- Ada 2005 (AI-251): If the designated type is an interface we
2394 -- add an implicit conversion to force the displacement of the
2395 -- pointer to reference the secondary dispatch table.
2396
2397 elsif Is_Interface (Btyp_DDT)
2398 and then (Comes_From_Source (N)
2399 or else Comes_From_Source (Ref_Object)
2400 or else (Nkind (Ref_Object) in N_Has_Chars
2401 and then Chars (Ref_Object) = Name_uInit))
2402 then
2403 if Nkind (Ref_Object) /= N_Explicit_Dereference then
2404
bea993f9
AC
2405 -- No implicit conversion required if types match, or if
2406 -- the prefix is the class_wide_type of the interface. In
2407 -- either case passing an object of the interface type has
2408 -- already set the pointer correctly.
2409
2410 if Btyp_DDT = Etype (Ref_Object)
2411 or else (Is_Class_Wide_Type (Etype (Ref_Object))
2412 and then
2413 Class_Wide_Type (Btyp_DDT) = Etype (Ref_Object))
2414 then
2415 null;
3192631e 2416
bea993f9 2417 else
3192631e 2418 Rewrite (Prefix (N),
0d4aed99 2419 Convert_To (Btyp_DDT,
3192631e
JM
2420 New_Copy_Tree (Prefix (N))));
2421
0d4aed99 2422 Analyze_And_Resolve (Prefix (N), Btyp_DDT);
70482933 2423 end if;
758c442c 2424
3192631e
JM
2425 -- When the object is an explicit dereference, convert the
2426 -- dereference's prefix.
3e8ee849 2427
3192631e
JM
2428 else
2429 declare
2430 Obj_DDT : constant Entity_Id :=
2431 Base_Type
2432 (Directly_Designated_Type
2433 (Etype (Prefix (Ref_Object))));
2434 begin
2435 -- No implicit conversion required if designated types
904a2ae4 2436 -- match.
3192631e
JM
2437
2438 if Obj_DDT /= Btyp_DDT
2439 and then not (Is_Class_Wide_Type (Obj_DDT)
3b59004a 2440 and then Etype (Obj_DDT) = Btyp_DDT)
3192631e
JM
2441 then
2442 Rewrite (N,
2443 Convert_To (Typ,
2444 New_Copy_Tree (Prefix (Ref_Object))));
2445 Analyze_And_Resolve (N, Typ);
2446 end if;
2447 end;
70482933 2448 end if;
3192631e
JM
2449 end if;
2450 end Access_Cases;
70482933
RK
2451
2452 --------------
2453 -- Adjacent --
2454 --------------
2455
2456 -- Transforms 'Adjacent into a call to the floating-point attribute
2457 -- function Adjacent in Fat_xxx (where xxx is the root type)
2458
2459 when Attribute_Adjacent =>
2460 Expand_Fpt_Attribute_RR (N);
2461
2462 -------------
2463 -- Address --
2464 -------------
2465
2466 when Attribute_Address => Address : declare
2467 Task_Proc : Entity_Id;
2468
47997d25
GD
2469 function Is_Unnested_Component_Init (N : Node_Id) return Boolean;
2470 -- Returns True if N is being used to initialize a component of
2471 -- an activation record object where the component corresponds to
2472 -- the object denoted by the prefix of the attribute N.
2473
2474 function Is_Unnested_Component_Init (N : Node_Id) return Boolean is
2475 begin
2476 return Present (Parent (N))
2477 and then Nkind (Parent (N)) = N_Assignment_Statement
2478 and then Is_Entity_Name (Pref)
2479 and then Present (Activation_Record_Component (Entity (Pref)))
2480 and then Nkind (Name (Parent (N))) = N_Selected_Component
2481 and then Entity (Selector_Name (Name (Parent (N)))) =
2482 Activation_Record_Component (Entity (Pref));
2483 end Is_Unnested_Component_Init;
2484
2485 -- Start of processing for Address
2486
70482933 2487 begin
3e8ee849
RD
2488 -- If the prefix is a task or a task type, the useful address is that
2489 -- of the procedure for the task body, i.e. the actual program unit.
2490 -- We replace the original entity with that of the procedure.
70482933
RK
2491
2492 if Is_Entity_Name (Pref)
2493 and then Is_Task_Type (Entity (Pref))
2494 then
21d27997 2495 Task_Proc := Next_Entity (Root_Type (Ptyp));
70482933
RK
2496
2497 while Present (Task_Proc) loop
2498 exit when Ekind (Task_Proc) = E_Procedure
2499 and then Etype (First_Formal (Task_Proc)) =
21d27997 2500 Corresponding_Record_Type (Ptyp);
70482933
RK
2501 Next_Entity (Task_Proc);
2502 end loop;
2503
2504 if Present (Task_Proc) then
2505 Set_Entity (Pref, Task_Proc);
2506 Set_Etype (Pref, Etype (Task_Proc));
2507 end if;
2508
2509 -- Similarly, the address of a protected operation is the address
2510 -- of the corresponding protected body, regardless of the protected
2511 -- object from which it is selected.
2512
2513 elsif Nkind (Pref) = N_Selected_Component
2514 and then Is_Subprogram (Entity (Selector_Name (Pref)))
2515 and then Is_Protected_Type (Scope (Entity (Selector_Name (Pref))))
2516 then
2517 Rewrite (Pref,
2518 New_Occurrence_Of (
2519 External_Subprogram (Entity (Selector_Name (Pref))), Loc));
2520
2521 elsif Nkind (Pref) = N_Explicit_Dereference
21d27997
RD
2522 and then Ekind (Ptyp) = E_Subprogram_Type
2523 and then Convention (Ptyp) = Convention_Protected
70482933
RK
2524 then
2525 -- The prefix is be a dereference of an access_to_protected_
2526 -- subprogram. The desired address is the second component of
2527 -- the record that represents the access.
2528
2529 declare
2530 Addr : constant Entity_Id := Etype (N);
2531 Ptr : constant Node_Id := Prefix (Pref);
2532 T : constant Entity_Id :=
2533 Equivalent_Type (Base_Type (Etype (Ptr)));
2534
2535 begin
2536 Rewrite (N,
2537 Unchecked_Convert_To (Addr,
2538 Make_Selected_Component (Loc,
2539 Prefix => Unchecked_Convert_To (T, Ptr),
2540 Selector_Name => New_Occurrence_Of (
2541 Next_Entity (First_Entity (T)), Loc))));
2542
2543 Analyze_And_Resolve (N, Addr);
2544 end;
0669bebe
GB
2545
2546 -- Ada 2005 (AI-251): Class-wide interface objects are always
2547 -- "displaced" to reference the tag associated with the interface
2548 -- type. In order to obtain the real address of such objects we
2549 -- generate a call to a run-time subprogram that returns the base
47997d25
GD
2550 -- address of the object. This call is not generated in cases where
2551 -- the attribute is being used to initialize a component of an
2552 -- activation record object where the component corresponds to
2553 -- prefix of the attribute (for back ends that require "unnesting"
2554 -- of nested subprograms), since the address needs to be assigned
2555 -- as-is to such components.
0669bebe 2556
21d27997 2557 elsif Is_Class_Wide_Type (Ptyp)
63a5b3dc 2558 and then Is_Interface (Underlying_Type (Ptyp))
1f110335 2559 and then Tagged_Type_Expansion
31104818
HK
2560 and then not (Nkind (Pref) in N_Has_Entity
2561 and then Is_Subprogram (Entity (Pref)))
47997d25 2562 and then not Is_Unnested_Component_Init (N)
0669bebe
GB
2563 then
2564 Rewrite (N,
2565 Make_Function_Call (Loc,
e4494292 2566 Name => New_Occurrence_Of (RTE (RE_Base_Address), Loc),
0669bebe
GB
2567 Parameter_Associations => New_List (
2568 Relocate_Node (N))));
2569 Analyze (N);
2570 return;
70482933
RK
2571 end if;
2572
21d27997
RD
2573 -- Deal with packed array reference, other cases are handled by
2574 -- the back end.
70482933
RK
2575
2576 if Involves_Packed_Array_Reference (Pref) then
2577 Expand_Packed_Address_Reference (N);
2578 end if;
2579 end Address;
2580
fbf5a39b
AC
2581 ---------------
2582 -- Alignment --
2583 ---------------
2584
2585 when Attribute_Alignment => Alignment : declare
fbf5a39b
AC
2586 New_Node : Node_Id;
2587
2588 begin
2589 -- For class-wide types, X'Class'Alignment is transformed into a
2590 -- direct reference to the Alignment of the class type, so that the
2591 -- back end does not have to deal with the X'Class'Alignment
2592 -- reference.
2593
2594 if Is_Entity_Name (Pref)
2595 and then Is_Class_Wide_Type (Entity (Pref))
2596 then
2597 Rewrite (Prefix (N), New_Occurrence_Of (Entity (Pref), Loc));
2598 return;
2599
2600 -- For x'Alignment applied to an object of a class wide type,
2601 -- transform X'Alignment into a call to the predefined primitive
2602 -- operation _Alignment applied to X.
2603
2604 elsif Is_Class_Wide_Type (Ptyp) then
2605 New_Node :=
d9937d1b
AC
2606 Make_Attribute_Reference (Loc,
2607 Prefix => Pref,
2608 Attribute_Name => Name_Tag);
2609
535a8637 2610 New_Node := Build_Get_Alignment (Loc, New_Node);
fbf5a39b 2611
445514c0
EB
2612 -- Case where the context is an unchecked conversion to a specific
2613 -- integer type. We directly convert from the alignment's type.
2614
2615 if Nkind (Parent (N)) = N_Unchecked_Type_Conversion then
2616 Rewrite (N, New_Node);
2617 Analyze_And_Resolve (N);
2618 return;
2619
033eaf85 2620 -- Case where the context is a specific integer type with which
33b9e989
EB
2621 -- the original attribute was compatible. But the alignment has a
2622 -- specific type in a-tags.ads (Standard.Natural) so, in order to
2623 -- preserve type compatibility, we must convert explicitly.
fbf5a39b 2624
445514c0 2625 elsif Typ /= Standard_Natural then
fbf5a39b
AC
2626 New_Node := Convert_To (Typ, New_Node);
2627 end if;
2628
2629 Rewrite (N, New_Node);
2630 Analyze_And_Resolve (N, Typ);
2631 return;
2632
2633 -- For all other cases, we just have to deal with the case of
2634 -- the fact that the result can be universal.
2635
2636 else
2637 Apply_Universal_Integer_Attribute_Checks (N);
2638 end if;
2639 end Alignment;
2640
3874e79d
EB
2641 ---------------------------
2642 -- Asm_Input, Asm_Output --
2643 ---------------------------
2644
2645 -- The Asm_Input and Asm_Output attributes are not expanded at this
2646 -- stage, but will be eliminated in the expansion of the Asm call,
2647 -- see Exp_Intr for details. So the back end will never see them.
2648
2649 when Attribute_Asm_Input
2650 | Attribute_Asm_Output
2651 =>
2652 null;
2653
47d3b920
AC
2654 ---------
2655 -- Bit --
2656 ---------
2657
2658 -- We compute this if a packed array reference was present, otherwise we
2659 -- leave the computation up to the back end.
2660
2661 when Attribute_Bit =>
2662 if Involves_Packed_Array_Reference (Pref) then
2663 Expand_Packed_Bit_Reference (N);
2664 else
2665 Apply_Universal_Integer_Attribute_Checks (N);
2666 end if;
2667
70482933
RK
2668 ------------------
2669 -- Bit_Position --
2670 ------------------
2671
12be130c
EB
2672 -- We leave the computation up to the back end, since we don't know what
2673 -- layout will be chosen if no component clause was specified.
70482933 2674
12be130c
EB
2675 when Attribute_Bit_Position =>
2676 Apply_Universal_Integer_Attribute_Checks (N);
70482933
RK
2677
2678 ------------------
2679 -- Body_Version --
2680 ------------------
2681
2682 -- A reference to P'Body_Version or P'Version is expanded to
2683
2684 -- Vnn : Unsigned;
69a0c174 2685 -- pragma Import (C, Vnn, "uuuuT");
70482933
RK
2686 -- ...
2687 -- Get_Version_String (Vnn)
2688
2689 -- where uuuu is the unit name (dots replaced by double underscore)
2690 -- and T is B for the cases of Body_Version, or Version applied to a
2691 -- subprogram acting as its own spec, and S for Version applied to a
2692 -- subprogram spec or package. This sequence of code references the
308e6f3a 2693 -- unsigned constant created in the main program by the binder.
70482933 2694
5c52bf3b
AC
2695 -- A special exception occurs for Standard, where the string returned
2696 -- is a copy of the library string in gnatvsn.ads.
70482933 2697
d8f43ee6
HK
2698 when Attribute_Body_Version
2699 | Attribute_Version
2700 =>
2701 Version : declare
2702 E : constant Entity_Id := Make_Temporary (Loc, 'V');
2703 Pent : Entity_Id;
2704 S : String_Id;
70482933 2705
d8f43ee6
HK
2706 begin
2707 -- If not library unit, get to containing library unit
2708
2709 Pent := Entity (Pref);
2710 while Pent /= Standard_Standard
2711 and then Scope (Pent) /= Standard_Standard
2712 and then not Is_Child_Unit (Pent)
2713 loop
2714 Pent := Scope (Pent);
2715 end loop;
70482933 2716
d8f43ee6 2717 -- Special case Standard and Standard.ASCII
70482933 2718
d8f43ee6
HK
2719 if Pent = Standard_Standard or else Pent = Standard_ASCII then
2720 Rewrite (N,
2721 Make_String_Literal (Loc,
2722 Strval => Verbose_Library_Version));
70482933 2723
d8f43ee6 2724 -- All other cases
70482933 2725
d8f43ee6
HK
2726 else
2727 -- Build required string constant
70482933 2728
d8f43ee6 2729 Get_Name_String (Get_Unit_Name (Pent));
70482933 2730
d8f43ee6
HK
2731 Start_String;
2732 for J in 1 .. Name_Len - 2 loop
2733 if Name_Buffer (J) = '.' then
2734 Store_String_Chars ("__");
2735 else
2736 Store_String_Char (Get_Char_Code (Name_Buffer (J)));
2737 end if;
2738 end loop;
70482933 2739
d8f43ee6 2740 -- Case of subprogram acting as its own spec, always use body
70482933 2741
d8f43ee6
HK
2742 if Nkind (Declaration_Node (Pent)) in N_Subprogram_Specification
2743 and then Nkind (Parent (Declaration_Node (Pent))) =
2744 N_Subprogram_Body
2745 and then Acts_As_Spec (Parent (Declaration_Node (Pent)))
2746 then
2747 Store_String_Chars ("B");
70482933 2748
d8f43ee6 2749 -- Case of no body present, always use spec
70482933 2750
d8f43ee6
HK
2751 elsif not Unit_Requires_Body (Pent) then
2752 Store_String_Chars ("S");
70482933 2753
d8f43ee6 2754 -- Otherwise use B for Body_Version, S for spec
70482933 2755
d8f43ee6
HK
2756 elsif Id = Attribute_Body_Version then
2757 Store_String_Chars ("B");
2758 else
2759 Store_String_Chars ("S");
2760 end if;
70482933 2761
d8f43ee6
HK
2762 S := End_String;
2763 Lib.Version_Referenced (S);
70482933 2764
d8f43ee6 2765 -- Insert the object declaration
70482933 2766
d8f43ee6
HK
2767 Insert_Actions (N, New_List (
2768 Make_Object_Declaration (Loc,
2769 Defining_Identifier => E,
2770 Object_Definition =>
2771 New_Occurrence_Of (RTE (RE_Unsigned), Loc))));
70482933 2772
d8f43ee6 2773 -- Set entity as imported with correct external name
70482933 2774
d8f43ee6
HK
2775 Set_Is_Imported (E);
2776 Set_Interface_Name (E, Make_String_Literal (Loc, S));
70482933 2777
d8f43ee6
HK
2778 -- Set entity as internal to ensure proper Sprint output of its
2779 -- implicit importation.
3e8ee849 2780
d8f43ee6 2781 Set_Is_Internal (E);
3e8ee849 2782
d8f43ee6 2783 -- And now rewrite original reference
70482933 2784
d8f43ee6
HK
2785 Rewrite (N,
2786 Make_Function_Call (Loc,
2787 Name =>
2788 New_Occurrence_Of (RTE (RE_Get_Version_String), Loc),
2789 Parameter_Associations => New_List (
2790 New_Occurrence_Of (E, Loc))));
2791 end if;
70482933 2792
d8f43ee6
HK
2793 Analyze_And_Resolve (N, RTE (RE_Version_String));
2794 end Version;
70482933
RK
2795
2796 -------------
2797 -- Ceiling --
2798 -------------
2799
2800 -- Transforms 'Ceiling into a call to the floating-point attribute
2801 -- function Ceiling in Fat_xxx (where xxx is the root type)
2802
2803 when Attribute_Ceiling =>
2804 Expand_Fpt_Attribute_R (N);
2805
2806 --------------
2807 -- Callable --
2808 --------------
2809
758c442c 2810 -- Transforms 'Callable attribute into a call to the Callable function
70482933 2811
d8f43ee6 2812 when Attribute_Callable =>
99bba92c 2813
65f01153
RD
2814 -- We have an object of a task interface class-wide type as a prefix
2815 -- to Callable. Generate:
31104818 2816 -- callable (Task_Id (Pref._disp_get_task_id));
65f01153 2817
0791fbe9 2818 if Ada_Version >= Ada_2005
21d27997
RD
2819 and then Ekind (Ptyp) = E_Class_Wide_Type
2820 and then Is_Interface (Ptyp)
2821 and then Is_Task_Interface (Ptyp)
65f01153 2822 then
99bba92c
AC
2823 Rewrite (N,
2824 Make_Function_Call (Loc,
c0e938d0 2825 Name =>
99bba92c
AC
2826 New_Occurrence_Of (RTE (RE_Callable), Loc),
2827 Parameter_Associations => New_List (
738a0e8d
BD
2828 Unchecked_Convert_To
2829 (RTE (RO_ST_Task_Id),
2830 Build_Disp_Get_Task_Id_Call (Pref)))));
31104818 2831
65f01153 2832 else
99bba92c 2833 Rewrite (N, Build_Call_With_Task (Pref, RTE (RE_Callable)));
65f01153
RD
2834 end if;
2835
70482933 2836 Analyze_And_Resolve (N, Standard_Boolean);
70482933
RK
2837
2838 ------------
2839 -- Caller --
2840 ------------
2841
2842 -- Transforms 'Caller attribute into a call to either the
2843 -- Task_Entry_Caller or the Protected_Entry_Caller function.
2844
2845 when Attribute_Caller => Caller : declare
b5e792e2 2846 Id_Kind : constant Entity_Id := RTE (RO_AT_Task_Id);
fbf5a39b
AC
2847 Ent : constant Entity_Id := Entity (Pref);
2848 Conctype : constant Entity_Id := Scope (Ent);
97a26d19 2849 Nest_Depth : Nat := 0;
70482933
RK
2850 Name : Node_Id;
2851 S : Entity_Id;
2852
2853 begin
2854 -- Protected case
2855
2856 if Is_Protected_Type (Conctype) then
e10dab7f
JM
2857 case Corresponding_Runtime_Package (Conctype) is
2858 when System_Tasking_Protected_Objects_Entries =>
2859 Name :=
e4494292 2860 New_Occurrence_Of
e10dab7f
JM
2861 (RTE (RE_Protected_Entry_Caller), Loc);
2862
2863 when System_Tasking_Protected_Objects_Single_Entry =>
2864 Name :=
e4494292 2865 New_Occurrence_Of
e10dab7f
JM
2866 (RTE (RE_Protected_Single_Entry_Caller), Loc);
2867
2868 when others =>
2869 raise Program_Error;
2870 end case;
70482933
RK
2871
2872 Rewrite (N,
2873 Unchecked_Convert_To (Id_Kind,
2874 Make_Function_Call (Loc,
2875 Name => Name,
21d27997 2876 Parameter_Associations => New_List (
e4494292 2877 New_Occurrence_Of
21d27997 2878 (Find_Protection_Object (Current_Scope), Loc)))));
70482933
RK
2879
2880 -- Task case
2881
2882 else
2883 -- Determine the nesting depth of the E'Caller attribute, that
2884 -- is, how many accept statements are nested within the accept
2885 -- statement for E at the point of E'Caller. The runtime uses
2886 -- this depth to find the specified entry call.
2887
2888 for J in reverse 0 .. Scope_Stack.Last loop
2889 S := Scope_Stack.Table (J).Entity;
2890
2891 -- We should not reach the scope of the entry, as it should
2892 -- already have been checked in Sem_Attr that this attribute
2893 -- reference is within a matching accept statement.
2894
2895 pragma Assert (S /= Conctype);
2896
2897 if S = Ent then
2898 exit;
2899
2900 elsif Is_Entry (S) then
2901 Nest_Depth := Nest_Depth + 1;
2902 end if;
2903 end loop;
2904
2905 Rewrite (N,
2906 Unchecked_Convert_To (Id_Kind,
2907 Make_Function_Call (Loc,
21d27997 2908 Name =>
e4494292 2909 New_Occurrence_Of (RTE (RE_Task_Entry_Caller), Loc),
70482933
RK
2910 Parameter_Associations => New_List (
2911 Make_Integer_Literal (Loc,
97a26d19 2912 Intval => Nest_Depth)))));
70482933
RK
2913 end if;
2914
2915 Analyze_And_Resolve (N, Id_Kind);
2916 end Caller;
2917
3874e79d
EB
2918 --------------------
2919 -- Component_Size --
2920 --------------------
2921
2922 -- Component_Size is handled by the back end
2923
2924 when Attribute_Component_Size =>
2925 Apply_Universal_Integer_Attribute_Checks (N);
2926
70482933
RK
2927 -------------
2928 -- Compose --
2929 -------------
2930
2931 -- Transforms 'Compose into a call to the floating-point attribute
2932 -- function Compose in Fat_xxx (where xxx is the root type)
2933
2934 -- Note: we strictly should have special code here to deal with the
2935 -- case of absurdly negative arguments (less than Integer'First)
2936 -- which will return a (signed) zero value, but it hardly seems
2937 -- worth the effort. Absurdly large positive arguments will raise
2938 -- constraint error which is fine.
2939
2940 when Attribute_Compose =>
2941 Expand_Fpt_Attribute_RI (N);
2942
2943 -----------------
2944 -- Constrained --
2945 -----------------
2946
2947 when Attribute_Constrained => Constrained : declare
2948 Formal_Ent : constant Entity_Id := Param_Entity (Pref);
2949
2950 begin
2951 -- Reference to a parameter where the value is passed as an extra
2952 -- actual, corresponding to the extra formal referenced by the
fbf5a39b
AC
2953 -- Extra_Constrained field of the corresponding formal. If this
2954 -- is an entry in-parameter, it is replaced by a constant renaming
2955 -- for which Extra_Constrained is never created.
70482933
RK
2956
2957 if Present (Formal_Ent)
fbf5a39b 2958 and then Ekind (Formal_Ent) /= E_Constant
70482933
RK
2959 and then Present (Extra_Constrained (Formal_Ent))
2960 then
2961 Rewrite (N,
2962 New_Occurrence_Of
3a6fa9a8 2963 (Extra_Constrained (Formal_Ent), Loc));
70482933 2964
ed323421
AC
2965 -- If the prefix is an access to object, the attribute applies to
2966 -- the designated object, so rewrite with an explicit dereference.
2967
10e168cd 2968 elsif Is_Access_Type (Ptyp)
ed323421
AC
2969 and then
2970 (not Is_Entity_Name (Pref) or else Is_Object (Entity (Pref)))
2971 then
2972 Rewrite (Pref,
2973 Make_Explicit_Dereference (Loc, Relocate_Node (Pref)));
ed323421 2974
70482933
RK
2975 -- For variables with a Extra_Constrained field, we use the
2976 -- corresponding entity.
2977
2978 elsif Nkind (Pref) = N_Identifier
2979 and then Ekind (Entity (Pref)) = E_Variable
2980 and then Present (Extra_Constrained (Entity (Pref)))
2981 then
2982 Rewrite (N,
2983 New_Occurrence_Of
3a6fa9a8 2984 (Extra_Constrained (Entity (Pref)), Loc));
70482933 2985
d2880e69 2986 -- For all other cases, we can tell at compile time
be42aa71 2987
d2880e69
CD
2988 else
2989 -- For access type, apply access check as needed
70482933 2990
d2880e69
CD
2991 if Is_Entity_Name (Pref)
2992 and then not Is_Type (Entity (Pref))
2993 and then Is_Access_Type (Ptyp)
2994 then
2995 Apply_Access_Check (N);
2996 end if;
70482933 2997
aa720a54 2998 Rewrite (N,
d2880e69
CD
2999 New_Occurrence_Of
3000 (Boolean_Literals
3a6fa9a8 3001 (Exp_Util.Attribute_Constrained_Static_Value (Pref)), Loc));
70482933
RK
3002 end if;
3003
3004 Analyze_And_Resolve (N, Standard_Boolean);
3005 end Constrained;
3006
3007 ---------------
3008 -- Copy_Sign --
3009 ---------------
3010
3011 -- Transforms 'Copy_Sign into a call to the floating-point attribute
90cb252f 3012 -- function Copy_Sign in Fat_xxx (where xxx is the root type).
70482933
RK
3013
3014 when Attribute_Copy_Sign =>
3015 Expand_Fpt_Attribute_RR (N);
3016
3017 -----------
3018 -- Count --
3019 -----------
3020
3021 -- Transforms 'Count attribute into a call to the Count function
3022
21d27997
RD
3023 when Attribute_Count => Count : declare
3024 Call : Node_Id;
3025 Conctyp : Entity_Id;
3026 Entnam : Node_Id;
3027 Entry_Id : Entity_Id;
3028 Index : Node_Id;
3029 Name : Node_Id;
70482933
RK
3030
3031 begin
3032 -- If the prefix is a member of an entry family, retrieve both
3033 -- entry name and index. For a simple entry there is no index.
3034
3035 if Nkind (Pref) = N_Indexed_Component then
3036 Entnam := Prefix (Pref);
3037 Index := First (Expressions (Pref));
3038 else
3039 Entnam := Pref;
3040 Index := Empty;
3041 end if;
3042
21d27997
RD
3043 Entry_Id := Entity (Entnam);
3044
70482933
RK
3045 -- Find the concurrent type in which this attribute is referenced
3046 -- (there had better be one).
3047
3048 Conctyp := Current_Scope;
3049 while not Is_Concurrent_Type (Conctyp) loop
3050 Conctyp := Scope (Conctyp);
3051 end loop;
3052
3053 -- Protected case
3054
3055 if Is_Protected_Type (Conctyp) then
97710dc7
JM
3056
3057 -- No need to transform 'Count into a function call if the current
3058 -- scope has been eliminated. In this case such transformation is
3059 -- also not viable because the enclosing protected object is not
3060 -- available.
3061
3062 if Is_Eliminated (Current_Scope) then
3063 return;
3064 end if;
3065
e10dab7f
JM
3066 case Corresponding_Runtime_Package (Conctyp) is
3067 when System_Tasking_Protected_Objects_Entries =>
e4494292 3068 Name := New_Occurrence_Of (RTE (RE_Protected_Count), Loc);
e10dab7f
JM
3069
3070 Call :=
3071 Make_Function_Call (Loc,
d8f43ee6 3072 Name => Name,
e10dab7f 3073 Parameter_Associations => New_List (
e4494292 3074 New_Occurrence_Of
21d27997
RD
3075 (Find_Protection_Object (Current_Scope), Loc),
3076 Entry_Index_Expression
3077 (Loc, Entry_Id, Index, Scope (Entry_Id))));
e10dab7f
JM
3078
3079 when System_Tasking_Protected_Objects_Single_Entry =>
21d27997 3080 Name :=
e4494292 3081 New_Occurrence_Of (RTE (RE_Protected_Count_Entry), Loc);
e10dab7f
JM
3082
3083 Call :=
3084 Make_Function_Call (Loc,
d8f43ee6 3085 Name => Name,
e10dab7f 3086 Parameter_Associations => New_List (
e4494292 3087 New_Occurrence_Of
21d27997
RD
3088 (Find_Protection_Object (Current_Scope), Loc)));
3089
e10dab7f
JM
3090 when others =>
3091 raise Program_Error;
e10dab7f 3092 end case;
70482933
RK
3093
3094 -- Task case
3095
3096 else
3097 Call :=
3098 Make_Function_Call (Loc,
e4494292 3099 Name => New_Occurrence_Of (RTE (RE_Task_Count), Loc),
70482933 3100 Parameter_Associations => New_List (
21d27997
RD
3101 Entry_Index_Expression (Loc,
3102 Entry_Id, Index, Scope (Entry_Id))));
70482933
RK
3103 end if;
3104
3105 -- The call returns type Natural but the context is universal integer
3106 -- so any integer type is allowed. The attribute was already resolved
3107 -- so its Etype is the required result type. If the base type of the
3108 -- context type is other than Standard.Integer we put in a conversion
3109 -- to the required type. This can be a normal typed conversion since
3110 -- both input and output types of the conversion are integer types
3111
3112 if Base_Type (Typ) /= Base_Type (Standard_Integer) then
3113 Rewrite (N, Convert_To (Typ, Call));
3114 else
3115 Rewrite (N, Call);
3116 end if;
3117
3118 Analyze_And_Resolve (N, Typ);
3119 end Count;
3120
203ddcea
AC
3121 ---------------------
3122 -- Descriptor_Size --
3123 ---------------------
3124
3874e79d 3125 -- Descriptor_Size is handled by the back end
cb3d8731 3126
12be130c
EB
3127 when Attribute_Descriptor_Size =>
3128 Apply_Universal_Integer_Attribute_Checks (N);
203ddcea 3129
70482933
RK
3130 ---------------
3131 -- Elab_Body --
3132 ---------------
3133
3134 -- This processing is shared by Elab_Spec
3135
3136 -- What we do is to insert the following declarations
3137
3138 -- procedure tnn;
3139 -- pragma Import (C, enn, "name___elabb/s");
3140
3141 -- and then the Elab_Body/Spec attribute is replaced by a reference
3142 -- to this defining identifier.
3143
d8f43ee6
HK
3144 when Attribute_Elab_Body
3145 | Attribute_Elab_Spec
3146 =>
3f5a8fee 3147 -- Leave attribute unexpanded in CodePeer mode: the gnat2scil
2c1a2cf3 3148 -- back-end knows how to handle these attributes directly.
3f5a8fee 3149
2c1a2cf3 3150 if CodePeer_Mode then
3f5a8fee
AC
3151 return;
3152 end if;
3153
70482933 3154 Elab_Body : declare
191fcb3a 3155 Ent : constant Entity_Id := Make_Temporary (Loc, 'E');
70482933
RK
3156 Str : String_Id;
3157 Lang : Node_Id;
3158
3159 procedure Make_Elab_String (Nod : Node_Id);
3160 -- Given Nod, an identifier, or a selected component, put the
3161 -- image into the current string literal, with double underline
3162 -- between components.
3163
7ce611e2
ES
3164 ----------------------
3165 -- Make_Elab_String --
3166 ----------------------
3167
70482933
RK
3168 procedure Make_Elab_String (Nod : Node_Id) is
3169 begin
3170 if Nkind (Nod) = N_Selected_Component then
3171 Make_Elab_String (Prefix (Nod));
535a8637
AC
3172 Store_String_Char ('_');
3173 Store_String_Char ('_');
70482933
RK
3174 Get_Name_String (Chars (Selector_Name (Nod)));
3175
3176 else
3177 pragma Assert (Nkind (Nod) = N_Identifier);
3178 Get_Name_String (Chars (Nod));
3179 end if;
3180
3181 Store_String_Chars (Name_Buffer (1 .. Name_Len));
3182 end Make_Elab_String;
3183
3184 -- Start of processing for Elab_Body/Elab_Spec
3185
3186 begin
3187 -- First we need to prepare the string literal for the name of
3188 -- the elaboration routine to be referenced.
3189
3190 Start_String;
3191 Make_Elab_String (Pref);
535a8637
AC
3192 Store_String_Chars ("___elab");
3193 Lang := Make_Identifier (Loc, Name_C);
70482933
RK
3194
3195 if Id = Attribute_Elab_Body then
3196 Store_String_Char ('b');
3197 else
3198 Store_String_Char ('s');
3199 end if;
3200
3201 Str := End_String;
3202
3203 Insert_Actions (N, New_List (
3204 Make_Subprogram_Declaration (Loc,
3205 Specification =>
3206 Make_Procedure_Specification (Loc,
3207 Defining_Unit_Name => Ent)),
3208
3209 Make_Pragma (Loc,
3860d469 3210 Chars => Name_Import,
70482933 3211 Pragma_Argument_Associations => New_List (
7675ad4f 3212 Make_Pragma_Argument_Association (Loc, Expression => Lang),
70482933
RK
3213
3214 Make_Pragma_Argument_Association (Loc,
7675ad4f 3215 Expression => Make_Identifier (Loc, Chars (Ent))),
70482933
RK
3216
3217 Make_Pragma_Argument_Association (Loc,
7675ad4f 3218 Expression => Make_String_Literal (Loc, Str))))));
70482933
RK
3219
3220 Set_Entity (N, Ent);
3221 Rewrite (N, New_Occurrence_Of (Ent, Loc));
3222 end Elab_Body;
3223
2c1a2cf3
RD
3224 --------------------
3225 -- Elab_Subp_Body --
3226 --------------------
3227
3228 -- Always ignored. In CodePeer mode, gnat2scil knows how to handle
3229 -- this attribute directly, and if we are not in CodePeer mode it is
3230 -- entirely ignored ???
3231
3232 when Attribute_Elab_Subp_Body =>
3233 return;
3234
70482933
RK
3235 ----------------
3236 -- Elaborated --
3237 ----------------
3238
21d27997
RD
3239 -- Elaborated is always True for preelaborated units, predefined units,
3240 -- pure units and units which have Elaborate_Body pragmas. These units
3241 -- have no elaboration entity.
70482933 3242
21d27997 3243 -- Note: The Elaborated attribute is never passed to the back end
70482933
RK
3244
3245 when Attribute_Elaborated => Elaborated : declare
7327f5c2 3246 Elab_Id : constant Entity_Id := Elaboration_Entity (Entity (Pref));
70482933
RK
3247
3248 begin
7327f5c2 3249 if Present (Elab_Id) then
70482933 3250 Rewrite (N,
824e9320 3251 Make_Op_Ne (Loc,
7327f5c2
AC
3252 Left_Opnd => New_Occurrence_Of (Elab_Id, Loc),
3253 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)));
3254
824e9320 3255 Analyze_And_Resolve (N, Typ);
70482933
RK
3256 else
3257 Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
3258 end if;
3259 end Elaborated;
3260
3261 --------------
3262 -- Enum_Rep --
3263 --------------
3264
1956beb8
BD
3265 when Attribute_Enum_Rep => Enum_Rep : declare
3266 Expr : Node_Id;
75e4e36d 3267
70482933 3268 begin
75e4e36d
AC
3269 -- Get the expression, which is X for Enum_Type'Enum_Rep (X) or
3270 -- X'Enum_Rep.
70482933
RK
3271
3272 if Is_Non_Empty_List (Exprs) then
1956beb8
BD
3273 Expr := First (Exprs);
3274 else
3275 Expr := Pref;
3276 end if;
70482933 3277
c64ac479
PT
3278 -- If not constant-folded, Enum_Type'Enum_Rep (X) or X'Enum_Rep
3279 -- expands to
fbf5a39b 3280
bd55fa10 3281 -- target-type!(X)
1956beb8 3282
bd55fa10
EB
3283 -- This is an unchecked conversion from the enumeration type to the
3284 -- target integer type, which is treated by the back end as a normal
3285 -- integer conversion, treating the enumeration type as an integer,
3286 -- which is exactly what we want. Unlike for the Pos attribute, we
3287 -- cannot use a regular conversion since the associated check would
3288 -- involve comparing the converted bounds, i.e. would involve the use
3289 -- of 'Pos instead 'Enum_Rep for these bounds.
70482933 3290
10e168cd
EB
3291 -- However the target type is universal integer in most cases, which
3292 -- is a very large type, so in the case of an enumeration type, we
3293 -- first convert to a small signed integer type in order not to lose
3294 -- the size information.
3295
c64ac479 3296 if Is_Enumeration_Type (Ptyp) then
bd55fa10 3297 Rewrite (N, Unchecked_Convert_To (Get_Integer_Type (Ptyp), Expr));
10e168cd
EB
3298 Convert_To_And_Rewrite (Typ, N);
3299
bd55fa10
EB
3300 -- Deal with integer types (replace by conversion)
3301
70482933 3302 else
bd55fa10 3303 Rewrite (N, Convert_To (Typ, Expr));
70482933
RK
3304 end if;
3305
70482933 3306 Analyze_And_Resolve (N, Typ);
70482933
RK
3307 end Enum_Rep;
3308
21d27997
RD
3309 --------------
3310 -- Enum_Val --
3311 --------------
3312
3313 when Attribute_Enum_Val => Enum_Val : declare
3314 Expr : Node_Id;
3315 Btyp : constant Entity_Id := Base_Type (Ptyp);
3316
3317 begin
3318 -- X'Enum_Val (Y) expands to
3319
3320 -- [constraint_error when _rep_to_pos (Y, False) = -1, msg]
3321 -- X!(Y);
3322
3323 Expr := Unchecked_Convert_To (Ptyp, First (Exprs));
3324
fd90c808
EB
3325 -- Ensure that the expression is not truncated since the "bad" bits
3326 -- are desired.
3327
3328 if Nkind (Expr) = N_Unchecked_Type_Conversion then
3329 Set_No_Truncation (Expr);
3330 end if;
3331
21d27997
RD
3332 Insert_Action (N,
3333 Make_Raise_Constraint_Error (Loc,
3334 Condition =>
3335 Make_Op_Eq (Loc,
3336 Left_Opnd =>
3337 Make_Function_Call (Loc,
3338 Name =>
e4494292 3339 New_Occurrence_Of (TSS (Btyp, TSS_Rep_To_Pos), Loc),
21d27997
RD
3340 Parameter_Associations => New_List (
3341 Relocate_Node (Duplicate_Subexpr (Expr)),
3342 New_Occurrence_Of (Standard_False, Loc))),
3343
3344 Right_Opnd => Make_Integer_Literal (Loc, -1)),
3345 Reason => CE_Range_Check_Failed));
3346
3347 Rewrite (N, Expr);
3348 Analyze_And_Resolve (N, Ptyp);
3349 end Enum_Val;
3350
70482933
RK
3351 --------------
3352 -- Exponent --
3353 --------------
3354
3355 -- Transforms 'Exponent into a call to the floating-point attribute
3356 -- function Exponent in Fat_xxx (where xxx is the root type)
3357
3358 when Attribute_Exponent =>
3359 Expand_Fpt_Attribute_R (N);
3360
3361 ------------------
3362 -- External_Tag --
3363 ------------------
3364
3365 -- transforme X'External_Tag into Ada.Tags.External_Tag (X'tag)
3366
d8f43ee6 3367 when Attribute_External_Tag =>
70482933
RK
3368 Rewrite (N,
3369 Make_Function_Call (Loc,
d8f43ee6
HK
3370 Name =>
3371 New_Occurrence_Of (RTE (RE_External_Tag), Loc),
70482933
RK
3372 Parameter_Associations => New_List (
3373 Make_Attribute_Reference (Loc,
3374 Attribute_Name => Name_Tag,
d8f43ee6 3375 Prefix => Prefix (N)))));
70482933
RK
3376
3377 Analyze_And_Resolve (N, Standard_String);
70482933 3378
f68d3344
JS
3379 -----------------------
3380 -- Finalization_Size --
3381 -----------------------
3382
3383 when Attribute_Finalization_Size => Finalization_Size : declare
f68d3344 3384 function Calculate_Header_Size return Node_Id;
d9c59db4
AC
3385 -- Generate a runtime call to calculate the size of the hidden header
3386 -- along with any added padding which would precede a heap-allocated
3387 -- object of the prefix type.
f68d3344
JS
3388
3389 ---------------------------
3390 -- Calculate_Header_Size --
3391 ---------------------------
3392
3393 function Calculate_Header_Size return Node_Id is
3394 begin
3395 -- Generate:
10e168cd 3396 -- Typ (Header_Size_With_Padding (Pref'Alignment))
f68d3344
JS
3397
3398 return
10e168cd 3399 Convert_To (Typ,
f68d3344
JS
3400 Make_Function_Call (Loc,
3401 Name =>
d9c59db4
AC
3402 New_Occurrence_Of (RTE (RE_Header_Size_With_Padding), Loc),
3403
f68d3344
JS
3404 Parameter_Associations => New_List (
3405 Make_Attribute_Reference (Loc,
d9c59db4 3406 Prefix => New_Copy_Tree (Pref),
f68d3344
JS
3407 Attribute_Name => Name_Alignment))));
3408 end Calculate_Header_Size;
3409
d9c59db4 3410 -- Local variables
f68d3344 3411
d9c59db4 3412 Size : Entity_Id;
f68d3344 3413
90cb252f 3414 -- Start of processing for Finalization_Size
f68d3344
JS
3415
3416 begin
d9c59db4 3417 -- An object of a class-wide type first requires a runtime check to
f68d3344
JS
3418 -- determine whether it is actually controlled or not. Depending on
3419 -- the outcome of this check, the Finalization_Size of the object
3420 -- may be zero or some positive value.
3421 --
d9c59db4 3422 -- In this scenario, Pref'Finalization_Size is expanded into
f68d3344 3423 --
d9c59db4 3424 -- Size : Integer := 0;
f68d3344 3425 --
d9c59db4 3426 -- if Needs_Finalization (Pref'Tag) then
10e168cd 3427 -- Size := Integer (Header_Size_With_Padding (Pref'Alignment));
d9c59db4 3428 -- end if;
f68d3344
JS
3429 --
3430 -- and the attribute reference is replaced with a reference to Size.
3431
3432 if Is_Class_Wide_Type (Ptyp) then
d9c59db4
AC
3433 Size := Make_Temporary (Loc, 'S');
3434
f68d3344
JS
3435 Insert_Actions (N, New_List (
3436
3437 -- Generate:
3438 -- Size : Integer := 0;
3439
3440 Make_Object_Declaration (Loc,
3441 Defining_Identifier => Size,
3442 Object_Definition =>
3443 New_Occurrence_Of (Standard_Integer, Loc),
3444 Expression => Make_Integer_Literal (Loc, 0)),
3445
3446 -- Generate:
3447 -- if Needs_Finalization (Pref'Tag) then
d9c59db4 3448 -- Size :=
10e168cd 3449 -- Integer (Header_Size_With_Padding (Pref'Alignment));
f68d3344
JS
3450 -- end if;
3451
3452 Make_If_Statement (Loc,
3453 Condition =>
3454 Make_Function_Call (Loc,
3455 Name =>
d9c59db4
AC
3456 New_Occurrence_Of (RTE (RE_Needs_Finalization), Loc),
3457
f68d3344
JS
3458 Parameter_Associations => New_List (
3459 Make_Attribute_Reference (Loc,
d9c59db4
AC
3460 Prefix => New_Copy_Tree (Pref),
3461 Attribute_Name => Name_Tag))),
3462
f68d3344
JS
3463 Then_Statements => New_List (
3464 Make_Assignment_Statement (Loc,
3465 Name => New_Occurrence_Of (Size, Loc),
10e168cd
EB
3466 Expression =>
3467 Convert_To
3468 (Standard_Integer, Calculate_Header_Size))))));
f68d3344
JS
3469
3470 Rewrite (N, New_Occurrence_Of (Size, Loc));
3471
d9c59db4
AC
3472 -- The prefix is known to be controlled at compile time. Calculate
3473 -- Finalization_Size by calling function Header_Size_With_Padding.
f68d3344
JS
3474
3475 elsif Needs_Finalization (Ptyp) then
3476 Rewrite (N, Calculate_Header_Size);
3477
d9c59db4
AC
3478 -- The prefix is not an object with controlled parts, so its
3479 -- Finalization_Size is zero.
f68d3344
JS
3480
3481 else
3482 Rewrite (N, Make_Integer_Literal (Loc, 0));
3483 end if;
3484
5f325af2
AC
3485 -- Due to cases where the entity type of the attribute is already
3486 -- resolved the rewritten N must get re-resolved to its appropriate
3487 -- type.
3488
3489 Analyze_And_Resolve (N, Typ);
f68d3344
JS
3490 end Finalization_Size;
3491
ac8806c4
EB
3492 -----------------
3493 -- First, Last --
3494 -----------------
70482933 3495
ac8806c4
EB
3496 when Attribute_First
3497 | Attribute_Last
3498 =>
70482933 3499 -- If the prefix type is a constrained packed array type which
8ca597af 3500 -- already has a Packed_Array_Impl_Type representation defined, then
ac8806c4
EB
3501 -- replace this attribute with a direct reference to the attribute of
3502 -- the appropriate index subtype (since otherwise the back end will
3503 -- try to give us the value of 'First for this implementation type).
08b0a5e2
GL
3504 -- Do not do this if Ptyp depends on a discriminant as its bounds
3505 -- are only available through N.
70482933 3506
08b0a5e2
GL
3507 if Is_Constrained_Packed_Array (Ptyp)
3508 and then not Size_Depends_On_Discriminant (Ptyp)
3509 then
70482933
RK
3510 Rewrite (N,
3511 Make_Attribute_Reference (Loc,
ac8806c4 3512 Attribute_Name => Attribute_Name (N),
41a58113
RD
3513 Prefix =>
3514 New_Occurrence_Of (Get_Index_Subtype (N), Loc)));
70482933
RK
3515 Analyze_And_Resolve (N, Typ);
3516
ac8806c4
EB
3517 -- For a constrained array type, if the bound is a reference to an
3518 -- entity which is not a discriminant, just replace with a direct
3519 -- reference. Note that this must be in keeping with what is done
3520 -- for scalar types in order for range checks to be elided in loops.
3521
d27ec3f6
EB
3522 -- However, avoid doing it if the array type is public because, in
3523 -- this case, we effectively rely on the back end to create public
3524 -- symbols with consistent names across units for the array bounds.
3525
3526 elsif Is_Array_Type (Ptyp)
3527 and then Is_Constrained (Ptyp)
3528 and then not Is_Public (Ptyp)
3529 then
ac8806c4
EB
3530 declare
3531 Bnd : Node_Id;
3532
3533 begin
3534 if Id = Attribute_First then
3535 Bnd := Type_Low_Bound (Get_Index_Subtype (N));
3536 else
3537 Bnd := Type_High_Bound (Get_Index_Subtype (N));
3538 end if;
3539
3540 if Is_Entity_Name (Bnd)
3541 and then Ekind (Entity (Bnd)) /= E_Discriminant
3542 then
3543 Rewrite (N, New_Occurrence_Of (Entity (Bnd), Loc));
3544 end if;
3545 end;
3546
41a58113
RD
3547 -- For access type, apply access check as needed
3548
70482933
RK
3549 elsif Is_Access_Type (Ptyp) then
3550 Apply_Access_Check (N);
41a58113 3551
ac8806c4 3552 -- For scalar type, if the bound is a reference to an entity, just
41a58113
RD
3553 -- replace with a direct reference. Note that we can only have a
3554 -- reference to a constant entity at this stage, anything else would
8e888920 3555 -- have already been rewritten.
41a58113 3556
8e888920 3557 elsif Is_Scalar_Type (Ptyp) then
41a58113 3558 declare
ac8806c4
EB
3559 Bnd : Node_Id;
3560
41a58113 3561 begin
ac8806c4
EB
3562 if Id = Attribute_First then
3563 Bnd := Type_Low_Bound (Ptyp);
3564 else
3565 Bnd := Type_High_Bound (Ptyp);
3566 end if;
3567
cb52e9fe 3568 if Is_Entity_Name (Bnd) then
ac8806c4 3569 Rewrite (N, New_Occurrence_Of (Entity (Bnd), Loc));
41a58113
RD
3570 end if;
3571 end;
70482933 3572 end if;
70482933
RK
3573
3574 ---------------
3575 -- First_Bit --
3576 ---------------
3577
12be130c
EB
3578 -- We leave the computation up to the back end, since we don't know what
3579 -- layout will be chosen if no component clause was specified.
70482933 3580
12be130c
EB
3581 when Attribute_First_Bit =>
3582 Apply_Universal_Integer_Attribute_Checks (N);
70482933 3583
304757d2
AC
3584 --------------------------------
3585 -- Fixed_Value, Integer_Value --
3586 --------------------------------
70482933 3587
304757d2 3588 -- We transform
70482933
RK
3589
3590 -- fixtype'Fixed_Value (integer-value)
8113b0c7 3591 -- inttype'Integer_Value (fixed-value)
70482933
RK
3592
3593 -- into
3594
304757d2
AC
3595 -- fixtype (integer-value)
3596 -- inttype (fixed-value)
3597
3598 -- respectively.
70482933 3599
8113b0c7
EB
3600 -- We set Conversion_OK on the conversion because we do not want it
3601 -- to go through the fixed-point conversion circuits.
70482933 3602
304757d2
AC
3603 when Attribute_Fixed_Value
3604 | Attribute_Integer_Value
3605 =>
8113b0c7 3606 Rewrite (N, OK_Convert_To (Entity (Pref), First (Exprs)));
fbf5a39b 3607
8113b0c7 3608 -- Note that it might appear that a properly analyzed unchecked
d8f43ee6 3609 -- conversion would be just fine here, but that's not the case,
8113b0c7 3610 -- since the full range checks performed by the following calls
d8f43ee6 3611 -- are critical.
fbf5a39b 3612
8113b0c7
EB
3613 Apply_Type_Conversion_Checks (N);
3614
3615 -- Note that Apply_Type_Conversion_Checks only deals with the
3616 -- overflow checks on conversions involving fixed-point types
3617 -- so we must apply range checks manually on them and expand.
3618
3619 Apply_Scalar_Range_Check
3620 (Expression (N), Etype (N), Fixed_Int => True);
3621
3622 Set_Analyzed (N);
3623 Expand (N);
70482933
RK
3624
3625 -----------
3626 -- Floor --
3627 -----------
3628
3629 -- Transforms 'Floor into a call to the floating-point attribute
3630 -- function Floor in Fat_xxx (where xxx is the root type)
3631
3632 when Attribute_Floor =>
3633 Expand_Fpt_Attribute_R (N);
3634
3635 ----------
3636 -- Fore --
3637 ----------
3638
3639 -- For the fixed-point type Typ:
3640
3641 -- Typ'Fore
3642
3643 -- expands into
3644
8d87bb8f
EB
3645 -- System.Fore_xx (ftyp (Typ'First), ftyp (Typ'Last) [,pm])
3646
3647 -- For decimal fixed-point types
3648 -- xx = Decimal{32,64,128}
3649 -- ftyp = Integer_{32,64,128}
3650 -- pm = Typ'Scale
3651
3652 -- For the most common ordinary fixed-point types
3653 -- xx = Fixed{32,64,128}
3654 -- ftyp = Integer_{32,64,128}
2bf891fa
EB
3655 -- pm = numerator of Typ'Small
3656 -- denominator of Typ'Small
3657 -- min (scale of Typ'Small, 0)
8d87bb8f
EB
3658
3659 -- For other ordinary fixed-point types
ec80b416
EB
3660 -- xx = Fixed
3661 -- ftyp = Long_Float
8d87bb8f 3662 -- pm = none
70482933 3663
d39f6b24 3664 -- Note that we know that the type is a nonstatic subtype, or Fore would
8d87bb8f 3665 -- have been computed statically in Eval_Attribute.
70482933 3666
d8f43ee6 3667 when Attribute_Fore =>
8d87bb8f
EB
3668 declare
3669 Arg_List : List_Id;
3670 Fid : RE_Id;
3671 Ftyp : Entity_Id;
70482933 3672
8d87bb8f
EB
3673 begin
3674 if Is_Decimal_Fixed_Point_Type (Ptyp) then
3675 if Esize (Ptyp) <= 32 then
3676 Fid := RE_Fore_Decimal32;
3677 Ftyp := RTE (RE_Integer_32);
3678 elsif Esize (Ptyp) <= 64 then
3679 Fid := RE_Fore_Decimal64;
3680 Ftyp := RTE (RE_Integer_64);
3681 else
3682 Fid := RE_Fore_Decimal128;
3683 Ftyp := RTE (RE_Integer_128);
3684 end if;
70482933 3685
8d87bb8f
EB
3686 else
3687 declare
3688 Num : constant Uint := Norm_Num (Small_Value (Ptyp));
3689 Den : constant Uint := Norm_Den (Small_Value (Ptyp));
3690 Max : constant Uint := UI_Max (Num, Den);
3691 Min : constant Uint := UI_Min (Num, Den);
3692 Siz : constant Uint := Esize (Ptyp);
70482933 3693
8d87bb8f
EB
3694 begin
3695 if Siz <= 32
8d87bb8f 3696 and then Max <= Uint_2 ** 31
2bf891fa
EB
3697 and then (Min = Uint_1
3698 or else Num < Den
3699 or else Num < Uint_10 ** 8)
8d87bb8f
EB
3700 then
3701 Fid := RE_Fore_Fixed32;
3702 Ftyp := RTE (RE_Integer_32);
3703 elsif Siz <= 64
8d87bb8f 3704 and then Max <= Uint_2 ** 63
2bf891fa
EB
3705 and then (Min = Uint_1
3706 or else Num < Den
3707 or else Num < Uint_10 ** 17)
8d87bb8f
EB
3708 then
3709 Fid := RE_Fore_Fixed64;
3710 Ftyp := RTE (RE_Integer_64);
3711 elsif System_Max_Integer_Size = 128
8d87bb8f 3712 and then Max <= Uint_2 ** 127
2bf891fa
EB
3713 and then (Min = Uint_1
3714 or else Num < Den
3715 or else Num < Uint_10 ** 37)
8d87bb8f
EB
3716 then
3717 Fid := RE_Fore_Fixed128;
3718 Ftyp := RTE (RE_Integer_128);
3719 else
ec80b416
EB
3720 Fid := RE_Fore_Fixed;
3721 Ftyp := Standard_Long_Float;
8d87bb8f
EB
3722 end if;
3723 end;
3724 end if;
3725
3726 Arg_List := New_List (
3727 Convert_To (Ftyp,
3728 Make_Attribute_Reference (Loc,
3729 Prefix => New_Occurrence_Of (Ptyp, Loc),
3730 Attribute_Name => Name_First)));
3731
3732 Append_To (Arg_List,
3733 Convert_To (Ftyp,
3734 Make_Attribute_Reference (Loc,
3735 Prefix => New_Occurrence_Of (Ptyp, Loc),
3736 Attribute_Name => Name_Last)));
3737
3738 -- For decimal, append Scale and also set to do literal conversion
3739
3740 if Is_Decimal_Fixed_Point_Type (Ptyp) then
3741 Set_Conversion_OK (First (Arg_List));
3742 Set_Conversion_OK (Next (First (Arg_List)));
3743
3744 Append_To (Arg_List,
3745 Make_Integer_Literal (Loc, Scale_Value (Ptyp)));
3746
2bf891fa
EB
3747 -- For ordinary fixed-point types, append Num, Den and Scale
3748 -- parameters and also set to do literal conversion
8d87bb8f 3749
ec80b416 3750 elsif Fid /= RE_Fore_Fixed then
8d87bb8f
EB
3751 Set_Conversion_OK (First (Arg_List));
3752 Set_Conversion_OK (Next (First (Arg_List)));
3753
3754 Append_To (Arg_List,
3755 Make_Integer_Literal (Loc, -Norm_Num (Small_Value (Ptyp))));
3756
3757 Append_To (Arg_List,
3758 Make_Integer_Literal (Loc, -Norm_Den (Small_Value (Ptyp))));
2bf891fa
EB
3759
3760 declare
3761 Val : Ureal := Small_Value (Ptyp);
3762 Scale : Int := 0;
3763
3764 begin
3765 while Val >= Ureal_10 loop
3766 Val := Val / Ureal_10;
3767 Scale := Scale - 1;
3768 end loop;
3769
3770 Append_To (Arg_List,
3771 Make_Integer_Literal (Loc, UI_From_Int (Scale)));
3772 end;
8d87bb8f
EB
3773 end if;
3774
3775 Rewrite (N,
3776 Convert_To (Typ,
3777 Make_Function_Call (Loc,
3778 Name =>
3779 New_Occurrence_Of (RTE (Fid), Loc),
3780 Parameter_Associations => Arg_List)));
3781
3782 Analyze_And_Resolve (N, Typ);
3783 end;
70482933
RK
3784
3785 --------------
3786 -- Fraction --
3787 --------------
3788
3789 -- Transforms 'Fraction into a call to the floating-point attribute
3790 -- function Fraction in Fat_xxx (where xxx is the root type)
3791
3792 when Attribute_Fraction =>
3793 Expand_Fpt_Attribute_R (N);
3794
54838d1f
AC
3795 --------------
3796 -- From_Any --
3797 --------------
3798
3799 when Attribute_From_Any => From_Any : declare
fb8e3581 3800 Decls : constant List_Id := New_List;
d8f43ee6 3801
54838d1f
AC
3802 begin
3803 Rewrite (N,
10e168cd 3804 Build_From_Any_Call (Ptyp,
54838d1f
AC
3805 Relocate_Node (First (Exprs)),
3806 Decls));
3807 Insert_Actions (N, Decls);
10e168cd 3808 Analyze_And_Resolve (N, Ptyp);
54838d1f
AC
3809 end From_Any;
3810
ea70f3d0
RD
3811 ----------------------
3812 -- Has_Same_Storage --
3813 ----------------------
3814
3815 when Attribute_Has_Same_Storage => Has_Same_Storage : declare
d8f43ee6 3816 Loc : constant Source_Ptr := Sloc (N);
ea70f3d0 3817
d8f43ee6
HK
3818 X : constant Node_Id := Prefix (N);
3819 Y : constant Node_Id := First (Expressions (N));
3820 -- The arguments
ea70f3d0 3821
d8f43ee6
HK
3822 X_Addr : Node_Id;
3823 Y_Addr : Node_Id;
3824 -- Rhe expressions for their addresses
ea70f3d0 3825
d8f43ee6
HK
3826 X_Size : Node_Id;
3827 Y_Size : Node_Id;
3828 -- Rhe expressions for their sizes
ea70f3d0
RD
3829
3830 begin
3831 -- The attribute is expanded as:
3832
3833 -- (X'address = Y'address)
3834 -- and then (X'Size = Y'Size)
36cf595c 3835 -- and then (X'Size /= 0) (AI12-0077)
ea70f3d0
RD
3836
3837 -- If both arguments have the same Etype the second conjunct can be
3838 -- omitted.
3839
3840 X_Addr :=
3841 Make_Attribute_Reference (Loc,
d8f43ee6
HK
3842 Attribute_Name => Name_Address,
3843 Prefix => New_Copy_Tree (X));
ea70f3d0
RD
3844
3845 Y_Addr :=
3846 Make_Attribute_Reference (Loc,
d8f43ee6
HK
3847 Attribute_Name => Name_Address,
3848 Prefix => New_Copy_Tree (Y));
ea70f3d0
RD
3849
3850 X_Size :=
3851 Make_Attribute_Reference (Loc,
d8f43ee6
HK
3852 Attribute_Name => Name_Size,
3853 Prefix => New_Copy_Tree (X));
ea70f3d0 3854
ea70f3d0
RD
3855 if Etype (X) = Etype (Y) then
3856 Rewrite (N,
36cf595c
EB
3857 Make_And_Then (Loc,
3858 Left_Opnd =>
3859 Make_Op_Eq (Loc,
3860 Left_Opnd => X_Addr,
3861 Right_Opnd => Y_Addr),
3862 Right_Opnd =>
3863 Make_Op_Ne (Loc,
3864 Left_Opnd => X_Size,
3865 Right_Opnd => Make_Integer_Literal (Loc, 0))));
ea70f3d0 3866 else
36cf595c
EB
3867 Y_Size :=
3868 Make_Attribute_Reference (Loc,
3869 Attribute_Name => Name_Size,
3870 Prefix => New_Copy_Tree (Y));
3871
ea70f3d0 3872 Rewrite (N,
36cf595c 3873 Make_And_Then (Loc,
d8f43ee6
HK
3874 Left_Opnd =>
3875 Make_Op_Eq (Loc,
3876 Left_Opnd => X_Addr,
3877 Right_Opnd => Y_Addr),
3878 Right_Opnd =>
36cf595c
EB
3879 Make_And_Then (Loc,
3880 Left_Opnd =>
3881 Make_Op_Eq (Loc,
3882 Left_Opnd => X_Size,
3883 Right_Opnd => Y_Size),
3884 Right_Opnd =>
3885 Make_Op_Ne (Loc,
3886 Left_Opnd => New_Copy_Tree (X_Size),
3887 Right_Opnd => Make_Integer_Literal (Loc, 0)))));
ea70f3d0
RD
3888 end if;
3889
3890 Analyze_And_Resolve (N, Standard_Boolean);
3891 end Has_Same_Storage;
3892
70482933
RK
3893 --------------
3894 -- Identity --
3895 --------------
3896
3897 -- For an exception returns a reference to the exception data:
3898 -- Exception_Id!(Prefix'Reference)
3899
3900 -- For a task it returns a reference to the _task_id component of
3901 -- corresponding record:
3902
b5e792e2 3903 -- taskV!(Prefix)._Task_Id, converted to the type Task_Id defined
70482933 3904
758c442c 3905 -- in Ada.Task_Identification
70482933
RK
3906
3907 when Attribute_Identity => Identity : declare
3908 Id_Kind : Entity_Id;
3909
3910 begin
21d27997 3911 if Ptyp = Standard_Exception_Type then
70482933
RK
3912 Id_Kind := RTE (RE_Exception_Id);
3913
19e7eae5
BD
3914 if Present (Renamed_Entity (Entity (Pref))) then
3915 Set_Entity (Pref, Renamed_Entity (Entity (Pref)));
70482933
RK
3916 end if;
3917
3918 Rewrite (N,
3919 Unchecked_Convert_To (Id_Kind, Make_Reference (Loc, Pref)));
3920 else
b5e792e2 3921 Id_Kind := RTE (RO_AT_Task_Id);
70482933 3922
470cd9e9
RD
3923 -- If the prefix is a task interface, the Task_Id is obtained
3924 -- dynamically through a dispatching call, as for other task
3925 -- attributes applied to interfaces.
3926
0791fbe9 3927 if Ada_Version >= Ada_2005
21d27997
RD
3928 and then Ekind (Ptyp) = E_Class_Wide_Type
3929 and then Is_Interface (Ptyp)
3930 and then Is_Task_Interface (Ptyp)
470cd9e9 3931 then
c0e938d0
AC
3932 Rewrite (N,
3933 Unchecked_Convert_To
3934 (Id_Kind, Build_Disp_Get_Task_Id_Call (Pref)));
470cd9e9
RD
3935
3936 else
3937 Rewrite (N,
3938 Unchecked_Convert_To (Id_Kind, Concurrent_Ref (Pref)));
3939 end if;
70482933
RK
3940 end if;
3941
3942 Analyze_And_Resolve (N, Id_Kind);
3943 end Identity;
3944
3945 -----------
3946 -- Image --
3947 -----------
3948
70482933 3949 when Attribute_Image =>
643827e9 3950
b63d61f7
AC
3951 -- Leave attribute unexpanded in CodePeer mode: the gnat2scil
3952 -- back-end knows how to handle this attribute directly.
3953
3954 if CodePeer_Mode then
3955 return;
3956 end if;
3957
e0fd1b9c 3958 Exp_Imgv.Expand_Image_Attribute (N);
70482933
RK
3959
3960 ---------
3961 -- Img --
3962 ---------
3963
3964 -- X'Img is expanded to typ'Image (X), where typ is the type of X
3965
d8f43ee6 3966 when Attribute_Img =>
e0fd1b9c 3967 Exp_Imgv.Expand_Image_Attribute (N);
70482933 3968
e577151d
PT
3969 -----------------
3970 -- Initialized --
3971 -----------------
3972
3973 -- For execution, we could either implement an approximation of this
3974 -- aspect, or use Valid_Scalars as a first approximation. For now we do
3975 -- the latter.
3976
3977 when Attribute_Initialized =>
8b6d722d
BY
3978
3979 -- Do not expand 'Initialized in CodePeer mode, it will be handled
3980 -- by the back-end directly.
3981
3982 if CodePeer_Mode then
3983 return;
3984 end if;
3985
e577151d
PT
3986 Rewrite
3987 (N,
3988 Make_Attribute_Reference
3989 (Sloc => Loc,
3990 Prefix => Pref,
3991 Attribute_Name => Name_Valid_Scalars,
3992 Expressions => Exprs));
3993
3994 Analyze_And_Resolve (N);
3995
70482933
RK
3996 -----------
3997 -- Input --
3998 -----------
3999
4000 when Attribute_Input => Input : declare
4001 P_Type : constant Entity_Id := Entity (Pref);
4002 B_Type : constant Entity_Id := Base_Type (P_Type);
4003 U_Type : constant Entity_Id := Underlying_Type (P_Type);
4004 Strm : constant Node_Id := First (Exprs);
4005 Fname : Entity_Id;
4006 Decl : Node_Id;
4007 Call : Node_Id;
4008 Prag : Node_Id;
4009 Arg2 : Node_Id;
4010 Rfunc : Node_Id;
4011
4012 Cntrl : Node_Id := Empty;
4013 -- Value for controlling argument in call. Always Empty except in
4014 -- the dispatching (class-wide type) case, where it is a reference
4015 -- to the dummy object initialized to the right internal tag.
4016
1c6c6771
ES
4017 procedure Freeze_Stream_Subprogram (F : Entity_Id);
4018 -- The expansion of the attribute reference may generate a call to
4019 -- a user-defined stream subprogram that is frozen by the call. This
4020 -- can lead to access-before-elaboration problem if the reference
4021 -- appears in an object declaration and the subprogram body has not
4022 -- been seen. The freezing of the subprogram requires special code
4023 -- because it appears in an expanded context where expressions do
4024 -- not freeze their constituents.
4025
4026 ------------------------------
4027 -- Freeze_Stream_Subprogram --
4028 ------------------------------
4029
4030 procedure Freeze_Stream_Subprogram (F : Entity_Id) is
4031 Decl : constant Node_Id := Unit_Declaration_Node (F);
4032 Bod : Node_Id;
4033
4034 begin
4035 -- If this is user-defined subprogram, the corresponding
4036 -- stream function appears as a renaming-as-body, and the
4037 -- user subprogram must be retrieved by tree traversal.
4038
4039 if Present (Decl)
4040 and then Nkind (Decl) = N_Subprogram_Declaration
4041 and then Present (Corresponding_Body (Decl))
4042 then
4043 Bod := Corresponding_Body (Decl);
4044
4045 if Nkind (Unit_Declaration_Node (Bod)) =
4046 N_Subprogram_Renaming_Declaration
4047 then
4048 Set_Is_Frozen (Entity (Name (Unit_Declaration_Node (Bod))));
4049 end if;
4050 end if;
4051 end Freeze_Stream_Subprogram;
4052
4053 -- Start of processing for Input
4054
70482933
RK
4055 begin
4056 -- If no underlying type, we have an error that will be diagnosed
4057 -- elsewhere, so here we just completely ignore the expansion.
4058
4059 if No (U_Type) then
4060 return;
4061 end if;
4062
baa571ab
AC
4063 -- Stream operations can appear in user code even if the restriction
4064 -- No_Streams is active (for example, when instantiating a predefined
4065 -- container). In that case rewrite the attribute as a Raise to
4066 -- prevent any run-time use.
4067
4068 if Restriction_Active (No_Streams) then
4069 Rewrite (N,
4070 Make_Raise_Program_Error (Sloc (N),
b8b2d982 4071 Reason => PE_Stream_Operation_Not_Allowed));
baa571ab
AC
4072 Set_Etype (N, B_Type);
4073 return;
4074 end if;
4075
70482933
RK
4076 -- If there is a TSS for Input, just call it
4077
fbf5a39b 4078 Fname := Find_Stream_Subprogram (P_Type, TSS_Stream_Input);
70482933
RK
4079
4080 if Present (Fname) then
4081 null;
4082
4083 else
4084 -- If there is a Stream_Convert pragma, use it, we rewrite
4085
4086 -- sourcetyp'Input (stream)
4087
4088 -- as
4089
4090 -- sourcetyp (streamread (strmtyp'Input (stream)));
4091
f3d0f304 4092 -- where streamread is the given Read function that converts an
21d27997
RD
4093 -- argument of type strmtyp to type sourcetyp or a type from which
4094 -- it is derived (extra conversion required for the derived case).
70482933 4095
1d571f3b 4096 Prag := Get_Stream_Convert_Pragma (P_Type);
70482933
RK
4097
4098 if Present (Prag) then
4099 Arg2 := Next (First (Pragma_Argument_Associations (Prag)));
4100 Rfunc := Entity (Expression (Arg2));
4101
4102 Rewrite (N,
4103 Convert_To (B_Type,
4104 Make_Function_Call (Loc,
4105 Name => New_Occurrence_Of (Rfunc, Loc),
4106 Parameter_Associations => New_List (
4107 Make_Attribute_Reference (Loc,
4108 Prefix =>
4109 New_Occurrence_Of
4110 (Etype (First_Formal (Rfunc)), Loc),
4111 Attribute_Name => Name_Input,
4112 Expressions => Exprs)))));
4113
4114 Analyze_And_Resolve (N, B_Type);
4115 return;
4116
29f2d76c
SB
4117 -- Limited types
4118
4119 elsif Default_Streaming_Unavailable (U_Type) then
4120 -- Do the same thing here as is done above in the
4121 -- case where a No_Streams restriction is active.
4122
4123 Rewrite (N,
4124 Make_Raise_Program_Error (Sloc (N),
4125 Reason => PE_Stream_Operation_Not_Allowed));
4126 Set_Etype (N, B_Type);
4127 return;
4128
70482933
RK
4129 -- Elementary types
4130
4131 elsif Is_Elementary_Type (U_Type) then
4132
4133 -- A special case arises if we have a defined _Read routine,
4134 -- since in this case we are required to call this routine.
4135
a3fbecee
EB
4136 if Present (Find_Inherited_TSS (P_Type, TSS_Stream_Read)) then
4137 Build_Record_Or_Elementary_Input_Function
4138 (Loc, P_Type, Decl, Fname);
4139 Insert_Action (N, Decl);
70482933 4140
a3fbecee 4141 -- For normal cases, we call the I_xxx routine directly
70482933 4142
a3fbecee
EB
4143 else
4144 Rewrite (N, Build_Elementary_Input_Call (N));
4145 Analyze_And_Resolve (N, P_Type);
4146 return;
4147 end if;
70482933
RK
4148
4149 -- Array type case
4150
4151 elsif Is_Array_Type (U_Type) then
4152 Build_Array_Input_Function (Loc, U_Type, Decl, Fname);
fb632ef5 4153 Compile_Stream_Body_In_Scope (N, Decl, U_Type);
70482933
RK
4154
4155 -- Dispatching case with class-wide type
4156
4157 elsif Is_Class_Wide_Type (P_Type) then
4158
0669bebe
GB
4159 -- No need to do anything else compiling under restriction
4160 -- No_Dispatching_Calls. During the semantic analysis we
4161 -- already notified such violation.
4162
4163 if Restriction_Active (No_Dispatching_Calls) then
4164 return;
4165 end if;
4166
70482933
RK
4167 declare
4168 Rtyp : constant Entity_Id := Root_Type (P_Type);
6d0289b1
HK
4169
4170 Expr : Node_Id; -- call to Descendant_Tag
8e28429a 4171 Get_Tag : Node_Id; -- expression to read the 'Tag
70482933
RK
4172
4173 begin
4174 -- Read the internal tag (RM 13.13.2(34)) and use it to
8e28429a
BD
4175 -- initialize a dummy tag value. We used to unconditionally
4176 -- generate:
6a237c45 4177 --
c9d70ab1 4178 -- Descendant_Tag (String'Input (Strm), P_Type);
6a237c45
AC
4179 --
4180 -- which turns into a call to String_Input_Blk_IO. However,
4181 -- if the input is malformed, that could try to read an
4182 -- enormous String, causing chaos. So instead we call
4183 -- String_Input_Tag, which does the same thing as
4184 -- String_Input_Blk_IO, except that if the String is
4185 -- absurdly long, it raises an exception.
4186 --
8e28429a
BD
4187 -- However, if the No_Stream_Optimizations restriction
4188 -- is active, we disable this unnecessary attempt at
4189 -- robustness; we really need to read the string
4190 -- character-by-character.
4191 --
c9d70ab1 4192 -- This value is used only to provide a controlling
758c442c
GD
4193 -- argument for the eventual _Input call. Descendant_Tag is
4194 -- called rather than Internal_Tag to ensure that we have a
4195 -- tag for a type that is descended from the prefix type and
4196 -- declared at the same accessibility level (the exception
4197 -- Tag_Error will be raised otherwise). The level check is
4198 -- required for Ada 2005 because tagged types can be
4199 -- extended in nested scopes (AI-344).
70482933 4200
c9d70ab1
AC
4201 -- Note: we used to generate an explicit declaration of a
4202 -- constant Ada.Tags.Tag object, and use an occurrence of
4203 -- this constant in Cntrl, but this caused a secondary stack
4204 -- leak.
4205
8e28429a
BD
4206 if Restriction_Active (No_Stream_Optimizations) then
4207 Get_Tag :=
4208 Make_Attribute_Reference (Loc,
4209 Prefix =>
4210 New_Occurrence_Of (Standard_String, Loc),
4211 Attribute_Name => Name_Input,
4212 Expressions => New_List (
4213 Relocate_Node (Duplicate_Subexpr (Strm))));
4214 else
4215 Get_Tag :=
4216 Make_Function_Call (Loc,
4217 Name =>
4218 New_Occurrence_Of
4219 (RTE (RE_String_Input_Tag), Loc),
4220 Parameter_Associations => New_List (
4221 Relocate_Node (Duplicate_Subexpr (Strm))));
4222 end if;
4223
191fcb3a
RD
4224 Expr :=
4225 Make_Function_Call (Loc,
e0c23ac7 4226 Name =>
191fcb3a
RD
4227 New_Occurrence_Of (RTE (RE_Descendant_Tag), Loc),
4228 Parameter_Associations => New_List (
8e28429a 4229 Get_Tag,
191fcb3a 4230 Make_Attribute_Reference (Loc,
e0c23ac7 4231 Prefix => New_Occurrence_Of (P_Type, Loc),
191fcb3a 4232 Attribute_Name => Name_Tag)));
683af98c 4233
c9d70ab1 4234 Set_Etype (Expr, RTE (RE_Tag));
70482933
RK
4235
4236 -- Now we need to get the entity for the call, and construct
4237 -- a function call node, where we preset a reference to Dnn
758c442c
GD
4238 -- as the controlling argument (doing an unchecked convert
4239 -- to the class-wide tagged type to make it look like a real
4240 -- tagged object).
70482933 4241
fbf5a39b 4242 Fname := Find_Prim_Op (Rtyp, TSS_Stream_Input);
c9d70ab1 4243 Cntrl := Unchecked_Convert_To (P_Type, Expr);
fbf5a39b 4244 Set_Etype (Cntrl, P_Type);
70482933
RK
4245 Set_Parent (Cntrl, N);
4246 end;
4247
4248 -- For tagged types, use the primitive Input function
4249
4250 elsif Is_Tagged_Type (U_Type) then
fbf5a39b 4251 Fname := Find_Prim_Op (U_Type, TSS_Stream_Input);
70482933 4252
758c442c
GD
4253 -- All other record type cases, including protected records. The
4254 -- latter only arise for expander generated code for handling
4255 -- shared passive partition access.
70482933
RK
4256
4257 else
4258 pragma Assert
4259 (Is_Record_Type (U_Type) or else Is_Protected_Type (U_Type));
4260
21d27997
RD
4261 -- Ada 2005 (AI-216): Program_Error is raised executing default
4262 -- implementation of the Input attribute of an unchecked union
4263 -- type if the type lacks default discriminant values.
5d09245e
AC
4264
4265 if Is_Unchecked_Union (Base_Type (U_Type))
d24ef4e6
PT
4266 and then
4267 No (Discriminant_Default_Value (First_Discriminant (U_Type)))
5d09245e 4268 then
d24ef4e6 4269 Rewrite (N,
5d09245e
AC
4270 Make_Raise_Program_Error (Loc,
4271 Reason => PE_Unchecked_Union_Restriction));
d24ef4e6 4272 Set_Etype (N, B_Type);
5d09245e
AC
4273 return;
4274 end if;
4275
f2404867
AC
4276 -- Build the type's Input function, passing the subtype rather
4277 -- than its base type, because checks are needed in the case of
4278 -- constrained discriminants (see Ada 2012 AI05-0192).
4279
70482933 4280 Build_Record_Or_Elementary_Input_Function
f2404867 4281 (Loc, U_Type, Decl, Fname);
70482933 4282 Insert_Action (N, Decl);
1c6c6771
ES
4283
4284 if Nkind (Parent (N)) = N_Object_Declaration
4285 and then Is_Record_Type (U_Type)
4286 then
4287 -- The stream function may contain calls to user-defined
4288 -- Read procedures for individual components.
4289
4290 declare
4291 Comp : Entity_Id;
4292 Func : Entity_Id;
4293
4294 begin
4295 Comp := First_Component (U_Type);
4296 while Present (Comp) loop
4297 Func :=
4298 Find_Stream_Subprogram
4299 (Etype (Comp), TSS_Stream_Read);
4300
4301 if Present (Func) then
4302 Freeze_Stream_Subprogram (Func);
4303 end if;
4304
4305 Next_Component (Comp);
4306 end loop;
4307 end;
4308 end if;
70482933
RK
4309 end if;
4310 end if;
4311
758c442c
GD
4312 -- If we fall through, Fname is the function to be called. The result
4313 -- is obtained by calling the appropriate function, then converting
4314 -- the result. The conversion does a subtype check.
70482933
RK
4315
4316 Call :=
4317 Make_Function_Call (Loc,
4318 Name => New_Occurrence_Of (Fname, Loc),
4319 Parameter_Associations => New_List (
4320 Relocate_Node (Strm)));
4321
4322 Set_Controlling_Argument (Call, Cntrl);
4323 Rewrite (N, Unchecked_Convert_To (P_Type, Call));
4324 Analyze_And_Resolve (N, P_Type);
1c6c6771
ES
4325
4326 if Nkind (Parent (N)) = N_Object_Declaration then
4327 Freeze_Stream_Subprogram (Fname);
4328 end if;
70482933
RK
4329 end Input;
4330
21d27997
RD
4331 -------------------
4332 -- Invalid_Value --
4333 -------------------
4334
4335 when Attribute_Invalid_Value =>
4336 Rewrite (N, Get_Simple_Init_Val (Ptyp, N));
4337
68f27c97
HK
4338 -- The value produced may be a conversion of a literal, which must be
4339 -- resolved to establish its proper type.
6a04c943
ES
4340
4341 Analyze_And_Resolve (N);
4342
70482933
RK
4343 --------------
4344 -- Last_Bit --
4345 --------------
4346
12be130c
EB
4347 -- We leave the computation up to the back end, since we don't know what
4348 -- layout will be chosen if no component clause was specified.
be482a8c 4349
12be130c
EB
4350 when Attribute_Last_Bit =>
4351 Apply_Universal_Integer_Attribute_Checks (N);
70482933
RK
4352
4353 ------------------
4354 -- Leading_Part --
4355 ------------------
4356
4357 -- Transforms 'Leading_Part into a call to the floating-point attribute
4358 -- function Leading_Part in Fat_xxx (where xxx is the root type)
4359
21d27997 4360 -- Note: strictly, we should generate special case code to deal with
758c442c
GD
4361 -- absurdly large positive arguments (greater than Integer'Last), which
4362 -- result in returning the first argument unchanged, but it hardly seems
4363 -- worth the effort. We raise constraint error for absurdly negative
4364 -- arguments which is fine.
70482933
RK
4365
4366 when Attribute_Leading_Part =>
4367 Expand_Fpt_Attribute_RI (N);
4368
4369 ------------
4370 -- Length --
4371 ------------
4372
150ac76e 4373 when Attribute_Length => Length : declare
70482933
RK
4374 Ityp : Entity_Id;
4375 Xnum : Uint;
4376
4377 begin
4378 -- Processing for packed array types
4379
bfe5f951 4380 if Is_Packed_Array (Ptyp) then
70482933
RK
4381 Ityp := Get_Index_Subtype (N);
4382
21d27997
RD
4383 -- If the index type, Ityp, is an enumeration type with holes,
4384 -- then we calculate X'Length explicitly using
70482933
RK
4385
4386 -- Typ'Max
4387 -- (0, Ityp'Pos (X'Last (N)) -
4388 -- Ityp'Pos (X'First (N)) + 1);
4389
21d27997
RD
4390 -- Since the bounds in the template are the representation values
4391 -- and the back end would get the wrong value.
70482933
RK
4392
4393 if Is_Enumeration_Type (Ityp)
4394 and then Present (Enum_Pos_To_Rep (Base_Type (Ityp)))
4395 then
4396 if No (Exprs) then
4397 Xnum := Uint_1;
4398 else
4399 Xnum := Expr_Value (First (Expressions (N)));
4400 end if;
4401
4402 Rewrite (N,
4403 Make_Attribute_Reference (Loc,
4404 Prefix => New_Occurrence_Of (Typ, Loc),
4405 Attribute_Name => Name_Max,
4406 Expressions => New_List
4407 (Make_Integer_Literal (Loc, 0),
4408
4409 Make_Op_Add (Loc,
4410 Left_Opnd =>
4411 Make_Op_Subtract (Loc,
4412 Left_Opnd =>
4413 Make_Attribute_Reference (Loc,
4414 Prefix => New_Occurrence_Of (Ityp, Loc),
4415 Attribute_Name => Name_Pos,
4416
4417 Expressions => New_List (
4418 Make_Attribute_Reference (Loc,
4419 Prefix => Duplicate_Subexpr (Pref),
4420 Attribute_Name => Name_Last,
4421 Expressions => New_List (
4422 Make_Integer_Literal (Loc, Xnum))))),
4423
4424 Right_Opnd =>
4425 Make_Attribute_Reference (Loc,
4426 Prefix => New_Occurrence_Of (Ityp, Loc),
4427 Attribute_Name => Name_Pos,
4428
4429 Expressions => New_List (
4430 Make_Attribute_Reference (Loc,
fbf5a39b
AC
4431 Prefix =>
4432 Duplicate_Subexpr_No_Checks (Pref),
70482933
RK
4433 Attribute_Name => Name_First,
4434 Expressions => New_List (
4435 Make_Integer_Literal (Loc, Xnum)))))),
4436
4437 Right_Opnd => Make_Integer_Literal (Loc, 1)))));
4438
4439 Analyze_And_Resolve (N, Typ, Suppress => All_Checks);
4440 return;
4441
4442 -- If the prefix type is a constrained packed array type which
8ca597af
RD
4443 -- already has a Packed_Array_Impl_Type representation defined,
4444 -- then replace this attribute with a reference to 'Range_Length
4445 -- of the appropriate index subtype (since otherwise the
4446 -- back end will try to give us the value of 'Length for
4447 -- this implementation type).s
70482933
RK
4448
4449 elsif Is_Constrained (Ptyp) then
4450 Rewrite (N,
4451 Make_Attribute_Reference (Loc,
4452 Attribute_Name => Name_Range_Length,
e4494292 4453 Prefix => New_Occurrence_Of (Ityp, Loc)));
70482933
RK
4454 Analyze_And_Resolve (N, Typ);
4455 end if;
4456
70482933
RK
4457 -- Access type case
4458
4459 elsif Is_Access_Type (Ptyp) then
4460 Apply_Access_Check (N);
4461
21d27997
RD
4462 -- If the designated type is a packed array type, then we convert
4463 -- the reference to:
70482933
RK
4464
4465 -- typ'Max (0, 1 +
4466 -- xtyp'Pos (Pref'Last (Expr)) -
4467 -- xtyp'Pos (Pref'First (Expr)));
4468
21d27997
RD
4469 -- This is a bit complex, but it is the easiest thing to do that
4470 -- works in all cases including enum types with holes xtyp here
4471 -- is the appropriate index type.
70482933
RK
4472
4473 declare
4474 Dtyp : constant Entity_Id := Designated_Type (Ptyp);
4475 Xtyp : Entity_Id;
4476
4477 begin
bfe5f951 4478 if Is_Packed_Array (Dtyp) then
70482933
RK
4479 Xtyp := Get_Index_Subtype (N);
4480
4481 Rewrite (N,
4482 Make_Attribute_Reference (Loc,
4483 Prefix => New_Occurrence_Of (Typ, Loc),
4484 Attribute_Name => Name_Max,
4485 Expressions => New_List (
4486 Make_Integer_Literal (Loc, 0),
4487
4488 Make_Op_Add (Loc,
4489 Make_Integer_Literal (Loc, 1),
4490 Make_Op_Subtract (Loc,
4491 Left_Opnd =>
4492 Make_Attribute_Reference (Loc,
4493 Prefix => New_Occurrence_Of (Xtyp, Loc),
4494 Attribute_Name => Name_Pos,
4495 Expressions => New_List (
4496 Make_Attribute_Reference (Loc,
4497 Prefix => Duplicate_Subexpr (Pref),
4498 Attribute_Name => Name_Last,
4499 Expressions =>
4500 New_Copy_List (Exprs)))),
4501
4502 Right_Opnd =>
4503 Make_Attribute_Reference (Loc,
4504 Prefix => New_Occurrence_Of (Xtyp, Loc),
4505 Attribute_Name => Name_Pos,
4506 Expressions => New_List (
4507 Make_Attribute_Reference (Loc,
fbf5a39b
AC
4508 Prefix =>
4509 Duplicate_Subexpr_No_Checks (Pref),
70482933
RK
4510 Attribute_Name => Name_First,
4511 Expressions =>
4512 New_Copy_List (Exprs)))))))));
4513
4514 Analyze_And_Resolve (N, Typ);
4515 end if;
4516 end;
4517
21d27997 4518 -- Otherwise leave it to the back end
70482933
RK
4519
4520 else
4521 Apply_Universal_Integer_Attribute_Checks (N);
4522 end if;
150ac76e
AC
4523 end Length;
4524
d436b30d
AC
4525 -- Attribute Loop_Entry is replaced with a reference to a constant value
4526 -- which captures the prefix at the entry point of the related loop. The
4527 -- loop itself may be transformed into a conditional block.
150ac76e
AC
4528
4529 when Attribute_Loop_Entry =>
d436b30d 4530 Expand_Loop_Entry_Attribute (N);
70482933
RK
4531
4532 -------------
4533 -- Machine --
4534 -------------
4535
4536 -- Transforms 'Machine into a call to the floating-point attribute
24228312
AC
4537 -- function Machine in Fat_xxx (where xxx is the root type).
4538 -- Expansion is avoided for cases the back end can handle directly.
70482933
RK
4539
4540 when Attribute_Machine =>
24228312
AC
4541 if not Is_Inline_Floating_Point_Attribute (N) then
4542 Expand_Fpt_Attribute_R (N);
4543 end if;
70482933 4544
65f01153
RD
4545 ----------------------
4546 -- Machine_Rounding --
4547 ----------------------
4548
4549 -- Transforms 'Machine_Rounding into a call to the floating-point
4550 -- attribute function Machine_Rounding in Fat_xxx (where xxx is the root
0669bebe
GB
4551 -- type). Expansion is avoided for cases the back end can handle
4552 -- directly.
65f01153
RD
4553
4554 when Attribute_Machine_Rounding =>
0669bebe
GB
4555 if not Is_Inline_Floating_Point_Attribute (N) then
4556 Expand_Fpt_Attribute_R (N);
4557 end if;
65f01153 4558
70482933
RK
4559 ------------------
4560 -- Machine_Size --
4561 ------------------
4562
4563 -- Machine_Size is equivalent to Object_Size, so transform it into
21d27997 4564 -- Object_Size and that way the back end never sees Machine_Size.
70482933
RK
4565
4566 when Attribute_Machine_Size =>
4567 Rewrite (N,
4568 Make_Attribute_Reference (Loc,
4569 Prefix => Prefix (N),
4570 Attribute_Name => Name_Object_Size));
4571
4572 Analyze_And_Resolve (N, Typ);
4573
4574 --------------
4575 -- Mantissa --
4576 --------------
4577
758c442c 4578 -- The only case that can get this far is the dynamic case of the old
21d27997
RD
4579 -- Ada 83 Mantissa attribute for the fixed-point case. For this case,
4580 -- we expand:
70482933
RK
4581
4582 -- typ'Mantissa
4583
4584 -- into
4585
4586 -- ityp (System.Mantissa.Mantissa_Value
4587 -- (Integer'Integer_Value (typ'First),
4588 -- Integer'Integer_Value (typ'Last)));
4589
d8f43ee6 4590 when Attribute_Mantissa =>
70482933
RK
4591 Rewrite (N,
4592 Convert_To (Typ,
4593 Make_Function_Call (Loc,
d8f43ee6
HK
4594 Name =>
4595 New_Occurrence_Of (RTE (RE_Mantissa_Value), Loc),
70482933
RK
4596
4597 Parameter_Associations => New_List (
70482933 4598 Make_Attribute_Reference (Loc,
d8f43ee6 4599 Prefix => New_Occurrence_Of (Standard_Integer, Loc),
70482933 4600 Attribute_Name => Name_Integer_Value,
d8f43ee6 4601 Expressions => New_List (
70482933 4602 Make_Attribute_Reference (Loc,
d8f43ee6 4603 Prefix => New_Occurrence_Of (Ptyp, Loc),
70482933
RK
4604 Attribute_Name => Name_First))),
4605
4606 Make_Attribute_Reference (Loc,
d8f43ee6 4607 Prefix => New_Occurrence_Of (Standard_Integer, Loc),
70482933 4608 Attribute_Name => Name_Integer_Value,
d8f43ee6 4609 Expressions => New_List (
70482933 4610 Make_Attribute_Reference (Loc,
d8f43ee6 4611 Prefix => New_Occurrence_Of (Ptyp, Loc),
70482933
RK
4612 Attribute_Name => Name_Last)))))));
4613
4614 Analyze_And_Resolve (N, Typ);
70482933 4615
aa9b151a
AC
4616 ---------
4617 -- Max --
4618 ---------
4619
4620 when Attribute_Max =>
e0f63680 4621 Expand_Min_Max_Attribute (N);
aa9b151a 4622
ca20a08e
AC
4623 ----------------------------------
4624 -- Max_Size_In_Storage_Elements --
4625 ----------------------------------
4626
24cb156d 4627 when Attribute_Max_Size_In_Storage_Elements => declare
2e8ee0a3 4628 Typ : constant Entity_Id := Etype (N);
24cb156d
AC
4629
4630 begin
d85badc7
BD
4631 -- If the prefix is X'Class, we transform it into a direct reference
4632 -- to the class-wide type, because the back end must not see a 'Class
4633 -- reference. See also 'Size.
4634
4635 if Is_Entity_Name (Pref)
4636 and then Is_Class_Wide_Type (Entity (Pref))
4637 then
4638 Rewrite (Prefix (N), New_Occurrence_Of (Entity (Pref), Loc));
4639 return;
4640 end if;
4641
ca20a08e
AC
4642 -- Heap-allocated controlled objects contain two extra pointers which
4643 -- are not part of the actual type. Transform the attribute reference
4644 -- into a runtime expression to add the size of the hidden header.
4645
2e8ee0a3
EB
4646 if Needs_Finalization (Ptyp) and then not Header_Size_Added (N) then
4647 Set_Header_Size_Added (N);
10e168cd 4648
ca20a08e
AC
4649 -- Generate:
4650 -- P'Max_Size_In_Storage_Elements +
2e8ee0a3 4651 -- Typ (Header_Size_With_Padding (Ptyp'Alignment))
ca20a08e 4652
2e8ee0a3 4653 Rewrite (N,
ca20a08e 4654 Make_Op_Add (Loc,
2e8ee0a3 4655 Left_Opnd => Relocate_Node (N),
ca20a08e 4656 Right_Opnd =>
2e8ee0a3 4657 Convert_To (Typ,
ca20a08e
AC
4658 Make_Function_Call (Loc,
4659 Name =>
e4494292 4660 New_Occurrence_Of
ca20a08e
AC
4661 (RTE (RE_Header_Size_With_Padding), Loc),
4662
4663 Parameter_Associations => New_List (
4664 Make_Attribute_Reference (Loc,
4665 Prefix =>
e4494292 4666 New_Occurrence_Of (Ptyp, Loc),
ca20a08e
AC
4667 Attribute_Name => Name_Alignment))))));
4668
2e8ee0a3 4669 Analyze_And_Resolve (N, Typ);
ca20a08e
AC
4670 return;
4671 end if;
2e8ee0a3
EB
4672
4673 -- In the other cases apply the required checks
4674
4675 Apply_Universal_Integer_Attribute_Checks (N);
24cb156d 4676 end;
ca20a08e 4677
80d4224f
RD
4678 --------------------
4679 -- Mechanism_Code --
4680 --------------------
4681
4682 when Attribute_Mechanism_Code =>
4683
d8f43ee6 4684 -- We must replace the prefix in the renamed case
80d4224f
RD
4685
4686 if Is_Entity_Name (Pref)
4687 and then Present (Alias (Entity (Pref)))
4688 then
4689 Set_Renamed_Subprogram (Pref, Alias (Entity (Pref)));
4690 end if;
4691
aa9b151a
AC
4692 ---------
4693 -- Min --
4694 ---------
4695
4696 when Attribute_Min =>
e0f63680 4697 Expand_Min_Max_Attribute (N);
aa9b151a 4698
5f3ab6fb
AC
4699 ---------
4700 -- Mod --
4701 ---------
4702
4703 when Attribute_Mod => Mod_Case : declare
4704 Arg : constant Node_Id := Relocate_Node (First (Exprs));
779bf182 4705 Hi : constant Node_Id := Type_High_Bound (Base_Type (Etype (Arg)));
5f3ab6fb
AC
4706 Modv : constant Uint := Modulus (Btyp);
4707
4708 begin
4709
4710 -- This is not so simple. The issue is what type to use for the
779bf182
ES
4711 -- computation of the modular value. In addition we need to use
4712 -- the base type as above to retrieve a static bound for the
4713 -- comparisons that follow.
5f3ab6fb
AC
4714
4715 -- The easy case is when the modulus value is within the bounds
4716 -- of the signed integer type of the argument. In this case we can
4717 -- just do the computation in that signed integer type, and then
4718 -- do an ordinary conversion to the target type.
4719
4720 if Modv <= Expr_Value (Hi) then
4721 Rewrite (N,
4722 Convert_To (Btyp,
4723 Make_Op_Mod (Loc,
4724 Left_Opnd => Arg,
4725 Right_Opnd => Make_Integer_Literal (Loc, Modv))));
4726
4727 -- Here we know that the modulus is larger than type'Last of the
3b641023 4728 -- integer type. There are two cases to consider:
5f3ab6fb
AC
4729
4730 -- a) The integer value is non-negative. In this case, it is
4731 -- returned as the result (since it is less than the modulus).
4732
758c442c
GD
4733 -- b) The integer value is negative. In this case, we know that the
4734 -- result is modulus + value, where the value might be as small as
4735 -- -modulus. The trouble is what type do we use to do the subtract.
a5476382 4736 -- No type will do, since modulus can be as big as 2**128, and no
f3d0f304 4737 -- integer type accommodates this value. Let's do bit of algebra
5f3ab6fb
AC
4738
4739 -- modulus + value
4740 -- = modulus - (-value)
4741 -- = (modulus - 1) - (-value - 1)
4742
4743 -- Now modulus - 1 is certainly in range of the modular type.
4744 -- -value is in the range 1 .. modulus, so -value -1 is in the
4745 -- range 0 .. modulus-1 which is in range of the modular type.
4746 -- Furthermore, (-value - 1) can be expressed as -(value + 1)
4747 -- which we can compute using the integer base type.
4748
9b16cb57
RD
4749 -- Once this is done we analyze the if expression without range
4750 -- checks, because we know everything is in range, and we want
4751 -- to prevent spurious warnings on either branch.
3b641023 4752
5f3ab6fb
AC
4753 else
4754 Rewrite (N,
9b16cb57 4755 Make_If_Expression (Loc,
5f3ab6fb
AC
4756 Expressions => New_List (
4757 Make_Op_Ge (Loc,
4758 Left_Opnd => Duplicate_Subexpr (Arg),
4759 Right_Opnd => Make_Integer_Literal (Loc, 0)),
4760
4761 Convert_To (Btyp,
4762 Duplicate_Subexpr_No_Checks (Arg)),
4763
4764 Make_Op_Subtract (Loc,
4765 Left_Opnd =>
4766 Make_Integer_Literal (Loc,
4767 Intval => Modv - 1),
4768 Right_Opnd =>
4769 Convert_To (Btyp,
4770 Make_Op_Minus (Loc,
4771 Right_Opnd =>
4772 Make_Op_Add (Loc,
4773 Left_Opnd => Duplicate_Subexpr_No_Checks (Arg),
4774 Right_Opnd =>
4775 Make_Integer_Literal (Loc,
4776 Intval => 1))))))));
4777
5f3ab6fb
AC
4778 end if;
4779
65f01153 4780 Analyze_And_Resolve (N, Btyp, Suppress => All_Checks);
5f3ab6fb
AC
4781 end Mod_Case;
4782
70482933
RK
4783 -----------
4784 -- Model --
4785 -----------
4786
4787 -- Transforms 'Model into a call to the floating-point attribute
24228312
AC
4788 -- function Model in Fat_xxx (where xxx is the root type).
4789 -- Expansion is avoided for cases the back end can handle directly.
70482933
RK
4790
4791 when Attribute_Model =>
24228312
AC
4792 if not Is_Inline_Floating_Point_Attribute (N) then
4793 Expand_Fpt_Attribute_R (N);
4794 end if;
70482933
RK
4795
4796 -----------------
4797 -- Object_Size --
4798 -----------------
4799
4800 -- The processing for Object_Size shares the processing for Size
4801
e10dab7f
JM
4802 ---------
4803 -- Old --
4804 ---------
4805
4806 when Attribute_Old => Old : declare
6c802906
AC
4807 Typ : constant Entity_Id := Etype (N);
4808 CW_Temp : Entity_Id;
4809 CW_Typ : Entity_Id;
d48bb126 4810 Decl : Node_Id;
64f5d139 4811 Ins_Nod : Node_Id;
8e1e62e3
AC
4812 Subp : Node_Id;
4813 Temp : Entity_Id;
e10dab7f 4814
4c5e9870
SB
4815 use Old_Attr_Util.Conditional_Evaluation;
4816 use Old_Attr_Util.Indirect_Temps;
e10dab7f 4817 begin
64f5d139
JM
4818 -- Generating C code we don't need to expand this attribute when
4819 -- we are analyzing the internally built nested postconditions
4820 -- procedure since it will be expanded inline (and later it will
4821 -- be removed by Expand_N_Subprogram_Body). It this expansion is
4822 -- performed in such case then the compiler generates unreferenced
4823 -- extra temporaries.
4824
4825 if Modify_Tree_For_C
4826 and then Chars (Current_Scope) = Name_uPostconditions
4827 then
4828 return;
4829 end if;
4830
8e1e62e3 4831 -- Climb the parent chain looking for subprogram _Postconditions
21d27997 4832
e10dab7f 4833 Subp := N;
8e1e62e3 4834 while Present (Subp) loop
21d27997 4835 exit when Nkind (Subp) = N_Subprogram_Body
8e1e62e3
AC
4836 and then Chars (Defining_Entity (Subp)) = Name_uPostconditions;
4837
4de10025
AC
4838 -- If assertions are disabled, no need to create the declaration
4839 -- that preserves the value. The postcondition pragma in which
4840 -- 'Old appears will be checked or disabled according to the
4841 -- current policy in effect.
4842
890f1954 4843 if Nkind (Subp) = N_Pragma and then not Is_Checked (Subp) then
4de10025
AC
4844 return;
4845 end if;
4846
8e1e62e3 4847 Subp := Parent (Subp);
e10dab7f
JM
4848 end loop;
4849
8e1e62e3 4850 -- 'Old can only appear in a postcondition, the generated body of
64f5d139
JM
4851 -- _Postconditions must be in the tree (or inlined if we are
4852 -- generating C code).
8e1e62e3 4853
fb757f7d
AC
4854 pragma Assert
4855 (Present (Subp)
4856 or else (Modify_Tree_For_C and then In_Inlined_Body));
8e1e62e3 4857
6c802906 4858 Temp := Make_Temporary (Loc, 'T', Pref);
21d27997 4859
6c802906
AC
4860 -- Set the entity kind now in order to mark the temporary as a
4861 -- handler of attribute 'Old's prefix.
4862
2e02ab86 4863 Mutate_Ekind (Temp, E_Constant);
6c802906 4864 Set_Stores_Attribute_Old_Prefix (Temp);
e10dab7f 4865
8e1e62e3
AC
4866 -- Push the scope of the related subprogram where _Postcondition
4867 -- resides as this ensures that the object will be analyzed in the
4868 -- proper context.
7425962b 4869
64f5d139
JM
4870 if Present (Subp) then
4871 Push_Scope (Scope (Defining_Entity (Subp)));
4872
4873 -- No need to push the scope when generating C code since the
4874 -- _Postcondition procedure has been inlined.
4875
4876 else pragma Assert (Modify_Tree_For_C);
4877 pragma Assert (In_Inlined_Body);
4878 null;
4879 end if;
4880
4881 -- Locate the insertion place of the internal temporary that saves
4882 -- the 'Old value.
4883
4884 if Present (Subp) then
4885 Ins_Nod := Subp;
4886
4887 -- Generating C, the postcondition procedure has been inlined and the
4888 -- temporary is added before the first declaration of the enclosing
4889 -- subprogram.
4890
4891 else pragma Assert (Modify_Tree_For_C);
4892 Ins_Nod := N;
4893 while Nkind (Ins_Nod) /= N_Subprogram_Body loop
4894 Ins_Nod := Parent (Ins_Nod);
4895 end loop;
4896
4897 Ins_Nod := First (Declarations (Ins_Nod));
4898 end if;
7425962b 4899
4c5e9870
SB
4900 if Eligible_For_Conditional_Evaluation (N) then
4901 declare
4902 Eval_Stmts : constant List_Id := New_List;
4903
4904 procedure Append_For_Indirect_Temp
4905 (N : Node_Id; Is_Eval_Stmt : Boolean);
4906 -- Append either a declaration (which is to be elaborated
4907 -- unconditionally) or an evaluation statement (which is
4908 -- to be executed conditionally).
4909
4910 -------------------------------
4911 -- Append_For_Indirect_Temp --
4912 -------------------------------
4913
4914 procedure Append_For_Indirect_Temp
4915 (N : Node_Id; Is_Eval_Stmt : Boolean)
4916 is
4917 begin
4918 if Is_Eval_Stmt then
4919 Append_To (Eval_Stmts, N);
4920 else
4921 Insert_Before_And_Analyze (Ins_Nod, N);
4922 end if;
4923 end Append_For_Indirect_Temp;
4924
4925 procedure Declare_Indirect_Temporary is new
4926 Declare_Indirect_Temp
4927 (Append_Item => Append_For_Indirect_Temp);
4928 begin
4929 Declare_Indirect_Temporary
4930 (Attr_Prefix => Pref, Indirect_Temp => Temp);
4931
4932 Insert_Before_And_Analyze (
4933 Ins_Nod,
4934 Make_If_Statement
4935 (Sloc => Loc,
4936 Condition => Conditional_Evaluation_Condition (N),
4937 Then_Statements => Eval_Stmts));
4938
4939 Rewrite (N, Indirect_Temp_Value
4940 (Temp => Temp,
4941 Typ => Etype (Pref),
4942 Loc => Loc));
4943
4944 if Present (Subp) then
4945 Pop_Scope;
4946 end if;
4947 return;
4948 end;
4949
6c802906
AC
4950 -- Preserve the tag of the prefix by offering a specific view of the
4951 -- class-wide version of the prefix.
4952
4c5e9870 4953 elsif Is_Tagged_Type (Typ) then
6c802906
AC
4954
4955 -- Generate:
4956 -- CW_Temp : constant Typ'Class := Typ'Class (Pref);
4957
4958 CW_Temp := Make_Temporary (Loc, 'T');
4959 CW_Typ := Class_Wide_Type (Typ);
4960
d48bb126 4961 Decl :=
6c802906
AC
4962 Make_Object_Declaration (Loc,
4963 Defining_Identifier => CW_Temp,
4964 Constant_Present => True,
4965 Object_Definition => New_Occurrence_Of (CW_Typ, Loc),
4966 Expression =>
d48bb126
PT
4967 Convert_To (CW_Typ, Relocate_Node (Pref)));
4968
4969 Insert_Before_And_Analyze (Ins_Nod, Decl);
6c802906
AC
4970
4971 -- Generate:
4972 -- Temp : Typ renames Typ (CW_Temp);
4973
64f5d139 4974 Insert_Before_And_Analyze (Ins_Nod,
6c802906
AC
4975 Make_Object_Renaming_Declaration (Loc,
4976 Defining_Identifier => Temp,
4977 Subtype_Mark => New_Occurrence_Of (Typ, Loc),
4978 Name =>
4979 Convert_To (Typ, New_Occurrence_Of (CW_Temp, Loc))));
4980
c0ffadd6
JS
4981 Set_Stores_Attribute_Old_Prefix (CW_Temp);
4982
6c802906
AC
4983 -- Non-tagged case
4984
4985 else
4986 -- Generate:
4987 -- Temp : constant Typ := Pref;
4988
d48bb126 4989 Decl :=
6c802906
AC
4990 Make_Object_Declaration (Loc,
4991 Defining_Identifier => Temp,
4992 Constant_Present => True,
4993 Object_Definition => New_Occurrence_Of (Typ, Loc),
d48bb126
PT
4994 Expression => Relocate_Node (Pref));
4995
4996 Insert_Before_And_Analyze (Ins_Nod, Decl);
4997
6c802906 4998 end if;
8e1e62e3 4999
64f5d139
JM
5000 if Present (Subp) then
5001 Pop_Scope;
5002 end if;
e10dab7f 5003
2838fa93
AC
5004 -- Ensure that the prefix of attribute 'Old is valid. The check must
5005 -- be inserted after the expansion of the attribute has taken place
5006 -- to reflect the new placement of the prefix.
5007
5008 if Validity_Checks_On and then Validity_Check_Operands then
d48bb126 5009 Ensure_Valid (Expression (Decl));
2838fa93
AC
5010 end if;
5011
8e1e62e3 5012 Rewrite (N, New_Occurrence_Of (Temp, Loc));
e10dab7f
JM
5013 end Old;
5014
2d42e881
ES
5015 ----------------------
5016 -- Overlaps_Storage --
5017 ----------------------
5018
5019 when Attribute_Overlaps_Storage => Overlaps_Storage : declare
5020 Loc : constant Source_Ptr := Sloc (N);
d4fd4637
JS
5021 X : constant Node_Id := Prefix (N);
5022 Y : constant Node_Id := First (Expressions (N));
2d42e881 5023
90b510e4 5024 -- The arguments
2d42e881
ES
5025
5026 X_Addr, Y_Addr : Node_Id;
d4fd4637
JS
5027
5028 -- The expressions for their integer addresses
2d42e881
ES
5029
5030 X_Size, Y_Size : Node_Id;
d4fd4637
JS
5031
5032 -- The expressions for their sizes
2d42e881
ES
5033
5034 Cond : Node_Id;
5035
5036 begin
5037 -- Attribute expands into:
5038
d4fd4637
JS
5039 -- (if X'Size = 0 or else Y'Size = 0 then
5040 -- False
5041 -- else
5042 -- (if X'Address <= Y'Address then
5043 -- (X'Address + X'Size - 1) >= Y'Address
5044 -- else
5045 -- (Y'Address + Y'Size - 1) >= X'Address))
2d42e881
ES
5046
5047 -- with the proper address operations. We convert addresses to
5048 -- integer addresses to use predefined arithmetic. The size is
90b510e4
AC
5049 -- expressed in storage units. We add copies of X_Addr and Y_Addr
5050 -- to prevent the appearance of the same node in two places in
5051 -- the tree.
2d42e881
ES
5052
5053 X_Addr :=
5054 Unchecked_Convert_To (RTE (RE_Integer_Address),
5055 Make_Attribute_Reference (Loc,
5056 Attribute_Name => Name_Address,
5057 Prefix => New_Copy_Tree (X)));
5058
5059 Y_Addr :=
5060 Unchecked_Convert_To (RTE (RE_Integer_Address),
5061 Make_Attribute_Reference (Loc,
5062 Attribute_Name => Name_Address,
5063 Prefix => New_Copy_Tree (Y)));
5064
5065 X_Size :=
5066 Make_Op_Divide (Loc,
5067 Left_Opnd =>
5068 Make_Attribute_Reference (Loc,
5069 Attribute_Name => Name_Size,
5070 Prefix => New_Copy_Tree (X)),
5071 Right_Opnd =>
5072 Make_Integer_Literal (Loc, System_Storage_Unit));
5073
5074 Y_Size :=
5075 Make_Op_Divide (Loc,
5076 Left_Opnd =>
5077 Make_Attribute_Reference (Loc,
5078 Attribute_Name => Name_Size,
5079 Prefix => New_Copy_Tree (Y)),
5080 Right_Opnd =>
5081 Make_Integer_Literal (Loc, System_Storage_Unit));
5082
5083 Cond :=
5084 Make_Op_Le (Loc,
5085 Left_Opnd => X_Addr,
5086 Right_Opnd => Y_Addr);
5087
d4fd4637
JS
5088 -- Perform the rewriting
5089
2d42e881 5090 Rewrite (N,
9ba9f4c0 5091 Make_If_Expression (Loc, New_List (
d4fd4637 5092
c392a001 5093 -- Generate a check for zero-sized things like a null record with
d4fd4637
JS
5094 -- size zero or an array with zero length since they have no
5095 -- opportunity of overlapping.
5096
c392a001
GD
5097 -- Without this check, a zero-sized object can trigger a false
5098 -- runtime result if it's compared against another object in
5099 -- its declarative region, due to the zero-sized object having
d4fd4637
JS
5100 -- the same address.
5101
5102 Make_Or_Else (Loc,
9ba9f4c0 5103 Left_Opnd =>
d4fd4637
JS
5104 Make_Op_Eq (Loc,
5105 Left_Opnd =>
5106 Make_Attribute_Reference (Loc,
5107 Attribute_Name => Name_Size,
5108 Prefix => New_Copy_Tree (X)),
5109 Right_Opnd => Make_Integer_Literal (Loc, 0)),
5110 Right_Opnd =>
5111 Make_Op_Eq (Loc,
5112 Left_Opnd =>
5113 Make_Attribute_Reference (Loc,
5114 Attribute_Name => Name_Size,
5115 Prefix => New_Copy_Tree (Y)),
5116 Right_Opnd => Make_Integer_Literal (Loc, 0))),
5117
5118 New_Occurrence_Of (Standard_False, Loc),
5119
c392a001 5120 -- Non-zero-size overlap check
d4fd4637
JS
5121
5122 Make_If_Expression (Loc, New_List (
5123 Cond,
5124
5125 Make_Op_Ge (Loc,
5126 Left_Opnd =>
5127 Make_Op_Add (Loc,
5128 Left_Opnd => New_Copy_Tree (X_Addr),
5129 Right_Opnd =>
5130 Make_Op_Subtract (Loc,
5131 Left_Opnd => X_Size,
5132 Right_Opnd => Make_Integer_Literal (Loc, 1))),
5133 Right_Opnd => Y_Addr),
5134
5135 Make_Op_Ge (Loc,
5136 Left_Opnd =>
5137 Make_Op_Add (Loc,
5138 Left_Opnd => New_Copy_Tree (Y_Addr),
5139 Right_Opnd =>
5140 Make_Op_Subtract (Loc,
5141 Left_Opnd => Y_Size,
5142 Right_Opnd => Make_Integer_Literal (Loc, 1))),
5143 Right_Opnd => X_Addr))))));
2d42e881
ES
5144
5145 Analyze_And_Resolve (N, Standard_Boolean);
5146 end Overlaps_Storage;
5147
70482933
RK
5148 ------------
5149 -- Output --
5150 ------------
5151
5152 when Attribute_Output => Output : declare
5153 P_Type : constant Entity_Id := Entity (Pref);
70482933
RK
5154 U_Type : constant Entity_Id := Underlying_Type (P_Type);
5155 Pname : Entity_Id;
5156 Decl : Node_Id;
5157 Prag : Node_Id;
5158 Arg3 : Node_Id;
5159 Wfunc : Node_Id;
5160
5161 begin
5162 -- If no underlying type, we have an error that will be diagnosed
5163 -- elsewhere, so here we just completely ignore the expansion.
5164
5165 if No (U_Type) then
5166 return;
5167 end if;
5168
baa571ab
AC
5169 -- Stream operations can appear in user code even if the restriction
5170 -- No_Streams is active (for example, when instantiating a predefined
5171 -- container). In that case rewrite the attribute as a Raise to
5172 -- prevent any run-time use.
5173
5174 if Restriction_Active (No_Streams) then
5175 Rewrite (N,
5176 Make_Raise_Program_Error (Sloc (N),
b8b2d982 5177 Reason => PE_Stream_Operation_Not_Allowed));
baa571ab
AC
5178 Set_Etype (N, Standard_Void_Type);
5179 return;
5180 end if;
5181
70482933
RK
5182 -- If TSS for Output is present, just call it
5183
fbf5a39b 5184 Pname := Find_Stream_Subprogram (P_Type, TSS_Stream_Output);
70482933
RK
5185
5186 if Present (Pname) then
5187 null;
5188
5189 else
5190 -- If there is a Stream_Convert pragma, use it, we rewrite
5191
5192 -- sourcetyp'Output (stream, Item)
5193
5194 -- as
5195
5196 -- strmtyp'Output (Stream, strmwrite (acttyp (Item)));
5197
758c442c
GD
5198 -- where strmwrite is the given Write function that converts an
5199 -- argument of type sourcetyp or a type acctyp, from which it is
5200 -- derived to type strmtyp. The conversion to acttyp is required
5201 -- for the derived case.
70482933 5202
1d571f3b 5203 Prag := Get_Stream_Convert_Pragma (P_Type);
70482933
RK
5204
5205 if Present (Prag) then
5206 Arg3 :=
5207 Next (Next (First (Pragma_Argument_Associations (Prag))));
5208 Wfunc := Entity (Expression (Arg3));
5209
5210 Rewrite (N,
5211 Make_Attribute_Reference (Loc,
5212 Prefix => New_Occurrence_Of (Etype (Wfunc), Loc),
5213 Attribute_Name => Name_Output,
5214 Expressions => New_List (
5215 Relocate_Node (First (Exprs)),
5216 Make_Function_Call (Loc,
5217 Name => New_Occurrence_Of (Wfunc, Loc),
5218 Parameter_Associations => New_List (
31104818 5219 OK_Convert_To (Etype (First_Formal (Wfunc)),
70482933
RK
5220 Relocate_Node (Next (First (Exprs)))))))));
5221
5222 Analyze (N);
5223 return;
5224
29f2d76c
SB
5225 -- Limited types
5226
5227 elsif Default_Streaming_Unavailable (U_Type) then
5228 -- Do the same thing here as is done above in the
5229 -- case where a No_Streams restriction is active.
5230
5231 Rewrite (N,
5232 Make_Raise_Program_Error (Sloc (N),
5233 Reason => PE_Stream_Operation_Not_Allowed));
5234 Set_Etype (N, Standard_Void_Type);
5235 return;
5236
890f1954
RD
5237 -- For elementary types, we call the W_xxx routine directly. Note
5238 -- that the effect of Write and Output is identical for the case
5239 -- of an elementary type (there are no discriminants or bounds).
70482933
RK
5240
5241 elsif Is_Elementary_Type (U_Type) then
5242
5243 -- A special case arises if we have a defined _Write routine,
5244 -- since in this case we are required to call this routine.
5245
a3fbecee
EB
5246 if Present (Find_Inherited_TSS (P_Type, TSS_Stream_Write)) then
5247 Build_Record_Or_Elementary_Output_Procedure
5248 (Loc, P_Type, Decl, Pname);
5249 Insert_Action (N, Decl);
70482933 5250
a3fbecee 5251 -- For normal cases, we call the W_xxx routine directly
70482933 5252
a3fbecee
EB
5253 else
5254 Rewrite (N, Build_Elementary_Write_Call (N));
5255 Analyze (N);
5256 return;
5257 end if;
70482933
RK
5258
5259 -- Array type case
5260
5261 elsif Is_Array_Type (U_Type) then
5262 Build_Array_Output_Procedure (Loc, U_Type, Decl, Pname);
fb632ef5 5263 Compile_Stream_Body_In_Scope (N, Decl, U_Type);
70482933
RK
5264
5265 -- Class-wide case, first output external tag, then dispatch
5266 -- to the appropriate primitive Output function (RM 13.13.2(31)).
5267
5268 elsif Is_Class_Wide_Type (P_Type) then
0669bebe
GB
5269
5270 -- No need to do anything else compiling under restriction
5271 -- No_Dispatching_Calls. During the semantic analysis we
5272 -- already notified such violation.
5273
5274 if Restriction_Active (No_Dispatching_Calls) then
5275 return;
5276 end if;
5277
70482933
RK
5278 Tag_Write : declare
5279 Strm : constant Node_Id := First (Exprs);
5280 Item : constant Node_Id := Next (Strm);
5281
5282 begin
31104818
HK
5283 -- Ada 2005 (AI-344): Check that the accessibility level
5284 -- of the type of the output object is not deeper than
5285 -- that of the attribute's prefix type.
5286
758c442c
GD
5287 -- if Get_Access_Level (Item'Tag)
5288 -- /= Get_Access_Level (P_Type'Tag)
5289 -- then
5290 -- raise Tag_Error;
5291 -- end if;
31104818 5292
758c442c
GD
5293 -- String'Output (Strm, External_Tag (Item'Tag));
5294
31104818
HK
5295 -- We cannot figure out a practical way to implement this
5296 -- accessibility check on virtual machines, so we omit it.
758c442c 5297
0791fbe9 5298 if Ada_Version >= Ada_2005
1f110335 5299 and then Tagged_Type_Expansion
31104818 5300 then
758c442c
GD
5301 Insert_Action (N,
5302 Make_Implicit_If_Statement (N,
5303 Condition =>
5304 Make_Op_Ne (Loc,
5305 Left_Opnd =>
0669bebe
GB
5306 Build_Get_Access_Level (Loc,
5307 Make_Attribute_Reference (Loc,
5308 Prefix =>
5309 Relocate_Node (
5310 Duplicate_Subexpr (Item,
5311 Name_Req => True)),
5312 Attribute_Name => Name_Tag)),
5313
758c442c 5314 Right_Opnd =>
0669bebe
GB
5315 Make_Integer_Literal (Loc,
5316 Type_Access_Level (P_Type))),
5317
758c442c
GD
5318 Then_Statements =>
5319 New_List (Make_Raise_Statement (Loc,
5320 New_Occurrence_Of (
5321 RTE (RE_Tag_Error), Loc)))));
5322 end if;
70482933
RK
5323
5324 Insert_Action (N,
5325 Make_Attribute_Reference (Loc,
5326 Prefix => New_Occurrence_Of (Standard_String, Loc),
5327 Attribute_Name => Name_Output,
5328 Expressions => New_List (
5329 Relocate_Node (Duplicate_Subexpr (Strm)),
5330 Make_Function_Call (Loc,
5331 Name =>
5332 New_Occurrence_Of (RTE (RE_External_Tag), Loc),
5333 Parameter_Associations => New_List (
5334 Make_Attribute_Reference (Loc,
5335 Prefix =>
5336 Relocate_Node
5337 (Duplicate_Subexpr (Item, Name_Req => True)),
5338 Attribute_Name => Name_Tag))))));
5339 end Tag_Write;
5340
fbf5a39b 5341 Pname := Find_Prim_Op (U_Type, TSS_Stream_Output);
70482933
RK
5342
5343 -- Tagged type case, use the primitive Output function
5344
5345 elsif Is_Tagged_Type (U_Type) then
fbf5a39b 5346 Pname := Find_Prim_Op (U_Type, TSS_Stream_Output);
70482933 5347
0669bebe
GB
5348 -- All other record type cases, including protected records.
5349 -- The latter only arise for expander generated code for
5350 -- handling shared passive partition access.
70482933
RK
5351
5352 else
5353 pragma Assert
5354 (Is_Record_Type (U_Type) or else Is_Protected_Type (U_Type));
5355
5d09245e
AC
5356 -- Ada 2005 (AI-216): Program_Error is raised when executing
5357 -- the default implementation of the Output attribute of an
5358 -- unchecked union type if the type lacks default discriminant
5359 -- values.
5360
5361 if Is_Unchecked_Union (Base_Type (U_Type))
d24ef4e6
PT
5362 and then
5363 No (Discriminant_Default_Value (First_Discriminant (U_Type)))
5d09245e 5364 then
d24ef4e6 5365 Rewrite (N,
5d09245e
AC
5366 Make_Raise_Program_Error (Loc,
5367 Reason => PE_Unchecked_Union_Restriction));
d24ef4e6 5368 Set_Etype (N, Standard_Void_Type);
5d09245e
AC
5369 return;
5370 end if;
5371
70482933
RK
5372 Build_Record_Or_Elementary_Output_Procedure
5373 (Loc, Base_Type (U_Type), Decl, Pname);
5374 Insert_Action (N, Decl);
5375 end if;
5376 end if;
5377
5378 -- If we fall through, Pname is the name of the procedure to call
5379
110d0820 5380 Rewrite_Attribute_Proc_Call (Pname);
70482933
RK
5381 end Output;
5382
5383 ---------
5384 -- Pos --
5385 ---------
5386
47d3b920
AC
5387 -- For enumeration types, with a non-standard representation we generate
5388 -- a call to the _Rep_To_Pos function created when the type was frozen.
10e168cd 5389 -- The call has the form:
70482933 5390
fbf5a39b 5391 -- _rep_to_pos (expr, flag)
70482933 5392
fbf5a39b
AC
5393 -- The parameter flag is True if range checks are enabled, causing
5394 -- Program_Error to be raised if the expression has an invalid
5395 -- representation, and False if range checks are suppressed.
70482933 5396
f193b29e
EB
5397 -- For enumeration types with a standard representation, Pos can be
5398 -- rewritten as a simple conversion with Conversion_OK set.
5399
10e168cd
EB
5400 -- For integer types, Pos is equivalent to a simple integer conversion
5401 -- and we rewrite it as such.
70482933 5402
d8f43ee6 5403 when Attribute_Pos => Pos : declare
f193b29e 5404 Expr : constant Node_Id := First (Exprs);
10e168cd 5405 Etyp : Entity_Id := Base_Type (Ptyp);
70482933
RK
5406
5407 begin
5408 -- Deal with zero/non-zero boolean values
5409
5410 if Is_Boolean_Type (Etyp) then
f193b29e 5411 Adjust_Condition (Expr);
70482933
RK
5412 Etyp := Standard_Boolean;
5413 Set_Prefix (N, New_Occurrence_Of (Standard_Boolean, Loc));
5414 end if;
5415
5416 -- Case of enumeration type
5417
5418 if Is_Enumeration_Type (Etyp) then
5419
5420 -- Non-standard enumeration type (generate call)
5421
5422 if Present (Enum_Pos_To_Rep (Etyp)) then
fbf5a39b 5423 Append_To (Exprs, Rep_To_Pos_Flag (Etyp, Loc));
70482933
RK
5424 Rewrite (N,
5425 Convert_To (Typ,
5426 Make_Function_Call (Loc,
5427 Name =>
e4494292 5428 New_Occurrence_Of (TSS (Etyp, TSS_Rep_To_Pos), Loc),
70482933
RK
5429 Parameter_Associations => Exprs)));
5430
f193b29e 5431 -- Standard enumeration type (replace by conversion)
70482933 5432
f193b29e
EB
5433 -- This is simply a direct conversion from the enumeration type to
5434 -- the target integer type, which is treated by the back end as a
5435 -- normal integer conversion, treating the enumeration type as an
5436 -- integer, which is exactly what we want. We set Conversion_OK to
5437 -- make sure that the analyzer does not complain about what might
5438 -- be an illegal conversion.
5439
5440 -- However the target type is universal integer in most cases,
5441 -- which is a very large type, so we first convert to a small
5442 -- signed integer type in order not to lose the size information.
70482933
RK
5443
5444 else
f193b29e
EB
5445 Rewrite (N, OK_Convert_To (Get_Integer_Type (Ptyp), Expr));
5446 Convert_To_And_Rewrite (Typ, N);
5447
70482933
RK
5448 end if;
5449
5450 -- Deal with integer types (replace by conversion)
5451
bd55fa10 5452 else
f193b29e 5453 Rewrite (N, Convert_To (Typ, Expr));
70482933
RK
5454 end if;
5455
f193b29e 5456 Analyze_And_Resolve (N, Typ);
70482933
RK
5457 end Pos;
5458
5459 --------------
5460 -- Position --
5461 --------------
5462
12be130c
EB
5463 -- We leave the computation up to the back end, since we don't know what
5464 -- layout will be chosen if no component clause was specified.
70482933 5465
12be130c
EB
5466 when Attribute_Position =>
5467 Apply_Universal_Integer_Attribute_Checks (N);
70482933
RK
5468
5469 ----------
5470 -- Pred --
5471 ----------
5472
29049f0b
AC
5473 -- 1. Deal with enumeration types with holes.
5474 -- 2. For floating-point, generate call to attribute function.
5475 -- 3. For other cases, deal with constraint checking.
70482933 5476
d8f43ee6 5477 when Attribute_Pred => Pred : declare
21d27997 5478 Etyp : constant Entity_Id := Base_Type (Ptyp);
70482933
RK
5479
5480 begin
5481 -- For enumeration types with non-standard representations, we
79e267f9 5482 -- expand typ'Pred (x) into:
70482933
RK
5483
5484 -- Pos_To_Rep (Rep_To_Pos (x) - 1)
5485
79e267f9
EB
5486 -- if the representation is non-contiguous, and just x - 1 if it is
5487 -- after having dealt with constraint checking.
fbf5a39b 5488
79e267f9 5489 if Is_Enumeration_Type (Etyp)
21d27997 5490 and then Present (Enum_Pos_To_Rep (Etyp))
70482933 5491 then
21d27997 5492 if Has_Contiguous_Rep (Etyp) then
79e267f9
EB
5493 if not Range_Checks_Suppressed (Ptyp) then
5494 Set_Do_Range_Check (First (Exprs), False);
5495 Expand_Pred_Succ_Attribute (N);
5496 end if;
5497
79e267f9
EB
5498 Rewrite (N,
5499 Unchecked_Convert_To (Etyp,
5500 Make_Op_Subtract (Loc,
5501 Left_Opnd =>
c7c7dd3a
EB
5502 Unchecked_Convert_To (
5503 Integer_Type_For
5504 (Esize (Etyp), Is_Unsigned_Type (Etyp)),
5505 First (Exprs)),
79e267f9
EB
5506 Right_Opnd =>
5507 Make_Integer_Literal (Loc, 1))));
70482933 5508
fbf5a39b 5509 else
16b54914 5510 -- Add Boolean parameter True, to request program error if
fbf5a39b
AC
5511 -- we have a bad representation on our hands. If checks are
5512 -- suppressed, then add False instead
70482933 5513
fbf5a39b
AC
5514 Append_To (Exprs, Rep_To_Pos_Flag (Ptyp, Loc));
5515 Rewrite (N,
5516 Make_Indexed_Component (Loc,
21d27997 5517 Prefix =>
e4494292 5518 New_Occurrence_Of
21d27997 5519 (Enum_Pos_To_Rep (Etyp), Loc),
fbf5a39b
AC
5520 Expressions => New_List (
5521 Make_Op_Subtract (Loc,
70482933
RK
5522 Left_Opnd =>
5523 Make_Function_Call (Loc,
5524 Name =>
e4494292 5525 New_Occurrence_Of
21d27997 5526 (TSS (Etyp, TSS_Rep_To_Pos), Loc),
fbf5a39b 5527 Parameter_Associations => Exprs),
70482933 5528 Right_Opnd => Make_Integer_Literal (Loc, 1)))));
fbf5a39b 5529 end if;
70482933 5530
79e267f9
EB
5531 -- Suppress checks since they have all been done above
5532
5533 Analyze_And_Resolve (N, Typ, Suppress => All_Checks);
70482933
RK
5534
5535 -- For floating-point, we transform 'Pred into a call to the Pred
0083dd66 5536 -- floating-point attribute function in Fat_xxx (xxx is root type).
29049f0b 5537 -- Note that this function takes care of the overflow case.
70482933
RK
5538
5539 elsif Is_Floating_Point_Type (Ptyp) then
5540 Expand_Fpt_Attribute_R (N);
5541 Analyze_And_Resolve (N, Typ);
5542
5543 -- For modular types, nothing to do (no overflow, since wraps)
5544
5545 elsif Is_Modular_Integer_Type (Ptyp) then
5546 null;
5547
d79e621a
GD
5548 -- For other types, if argument is marked as needing a range check or
5549 -- overflow checking is enabled, we must generate a check.
70482933 5550
d79e621a
GD
5551 elsif not Overflow_Checks_Suppressed (Ptyp)
5552 or else Do_Range_Check (First (Exprs))
5553 then
5554 Set_Do_Range_Check (First (Exprs), False);
aa9b151a 5555 Expand_Pred_Succ_Attribute (N);
70482933 5556 end if;
70482933
RK
5557 end Pred;
5558
3450ded1
GD
5559 ----------------------------------
5560 -- Preelaborable_Initialization --
5561 ----------------------------------
5562
5563 when Attribute_Preelaborable_Initialization =>
5564
5565 -- This attribute should already be folded during analysis, but if
5566 -- for some reason it hasn't been, we fold it now.
5567
5568 Fold_Uint
5569 (N,
5570 UI_From_Int
5571 (Boolean'Pos (Has_Preelaborable_Initialization (Ptyp))),
5572 Static => False);
5573
7ce611e2
ES
5574 --------------
5575 -- Priority --
5576 --------------
5577
5578 -- Ada 2005 (AI-327): Dynamic ceiling priorities
5579
5580 -- We rewrite X'Priority as the following run-time call:
5581
5582 -- Get_Ceiling (X._Object)
5583
5584 -- Note that although X'Priority is notionally an object, it is quite
5585 -- deliberately not defined as an aliased object in the RM. This means
5586 -- that it works fine to rewrite it as a call, without having to worry
5587 -- about complications that would other arise from X'Priority'Access,
5588 -- which is illegal, because of the lack of aliasing.
5589
d8f43ee6
HK
5590 when Attribute_Priority => Priority : declare
5591 Call : Node_Id;
5592 Conctyp : Entity_Id;
5593 New_Itype : Entity_Id;
5594 Object_Parm : Node_Id;
5595 Subprg : Entity_Id;
5596 RT_Subprg_Name : Node_Id;
7ce611e2 5597
d8f43ee6
HK
5598 begin
5599 -- Look for the enclosing concurrent type
7ce611e2 5600
d8f43ee6
HK
5601 Conctyp := Current_Scope;
5602 while not Is_Concurrent_Type (Conctyp) loop
5603 Conctyp := Scope (Conctyp);
5604 end loop;
7ce611e2 5605
d8f43ee6 5606 pragma Assert (Is_Protected_Type (Conctyp));
7ce611e2 5607
d8f43ee6 5608 -- Generate the actual of the call
7ce611e2 5609
d8f43ee6
HK
5610 Subprg := Current_Scope;
5611 while not Present (Protected_Body_Subprogram (Subprg)) loop
5612 Subprg := Scope (Subprg);
5613 end loop;
16f67b79 5614
d8f43ee6
HK
5615 -- Use of 'Priority inside protected entries and barriers (in both
5616 -- cases the type of the first formal of their expanded subprogram
5617 -- is Address)
16f67b79 5618
d8f43ee6
HK
5619 if Etype (First_Entity (Protected_Body_Subprogram (Subprg))) =
5620 RTE (RE_Address)
5621 then
5622 -- In the expansion of protected entries the type of the first
5623 -- formal of the Protected_Body_Subprogram is an Address. In order
5624 -- to reference the _object component we generate:
16f67b79 5625
d8f43ee6
HK
5626 -- type T is access p__ptTV;
5627 -- freeze T []
16f67b79 5628
d8f43ee6
HK
5629 New_Itype := Create_Itype (E_Access_Type, N);
5630 Set_Etype (New_Itype, New_Itype);
5631 Set_Directly_Designated_Type (New_Itype,
5632 Corresponding_Record_Type (Conctyp));
5633 Freeze_Itype (New_Itype, N);
16f67b79 5634
d8f43ee6
HK
5635 -- Generate:
5636 -- T!(O)._object'unchecked_access
16f67b79 5637
d8f43ee6
HK
5638 Object_Parm :=
5639 Make_Attribute_Reference (Loc,
5640 Prefix =>
5641 Make_Selected_Component (Loc,
5642 Prefix =>
5643 Unchecked_Convert_To (New_Itype,
5644 New_Occurrence_Of
5645 (First_Entity (Protected_Body_Subprogram (Subprg)),
5646 Loc)),
5647 Selector_Name => Make_Identifier (Loc, Name_uObject)),
5648 Attribute_Name => Name_Unchecked_Access);
16f67b79 5649
d8f43ee6 5650 -- Use of 'Priority inside a protected subprogram
16f67b79 5651
d8f43ee6
HK
5652 else
5653 Object_Parm :=
5654 Make_Attribute_Reference (Loc,
5655 Prefix =>
5656 Make_Selected_Component (Loc,
5657 Prefix =>
5658 New_Occurrence_Of
5659 (First_Entity (Protected_Body_Subprogram (Subprg)),
5660 Loc),
5661 Selector_Name => Make_Identifier (Loc, Name_uObject)),
5662 Attribute_Name => Name_Unchecked_Access);
5663 end if;
7ce611e2 5664
d8f43ee6 5665 -- Select the appropriate run-time subprogram
7ce611e2 5666
d8f43ee6
HK
5667 if Number_Entries (Conctyp) = 0 then
5668 RT_Subprg_Name := New_Occurrence_Of (RTE (RE_Get_Ceiling), Loc);
5669 else
5670 RT_Subprg_Name := New_Occurrence_Of (RTE (RO_PE_Get_Ceiling), Loc);
5671 end if;
7ce611e2 5672
d8f43ee6
HK
5673 Call :=
5674 Make_Function_Call (Loc,
5675 Name => RT_Subprg_Name,
5676 Parameter_Associations => New_List (Object_Parm));
7ce611e2 5677
d8f43ee6 5678 Rewrite (N, Call);
16f67b79 5679
d8f43ee6
HK
5680 -- Avoid the generation of extra checks on the pointer to the
5681 -- protected object.
16f67b79 5682
d8f43ee6
HK
5683 Analyze_And_Resolve (N, Typ, Suppress => Access_Check);
5684 end Priority;
7ce611e2 5685
110d0820
BD
5686 ---------------
5687 -- Put_Image --
5688 ---------------
5689
5690 when Attribute_Put_Image => Put_Image : declare
5691 use Exp_Put_Image;
5692 U_Type : constant Entity_Id := Underlying_Type (Entity (Pref));
5693 Pname : Entity_Id;
5694 Decl : Node_Id;
5695
5696 begin
5697 -- If no underlying type, we have an error that will be diagnosed
5698 -- elsewhere, so here we just completely ignore the expansion.
5699
5700 if No (U_Type) then
5701 return;
5702 end if;
5703
c324c77e
BD
5704 -- If there is a TSS for Put_Image, just call it. This is true for
5705 -- tagged types (if enabled) and if there is a user-specified
5706 -- Put_Image.
110d0820
BD
5707
5708 Pname := TSS (U_Type, TSS_Put_Image);
5709 if No (Pname) then
5710 if Is_Tagged_Type (U_Type) and then Is_Derived_Type (U_Type) then
5711 Pname := Find_Optional_Prim_Op (U_Type, TSS_Put_Image);
110d0820
BD
5712 else
5713 Pname := Find_Inherited_TSS (U_Type, TSS_Put_Image);
5714 end if;
5715 end if;
5716
5717 if No (Pname) then
c324c77e
BD
5718 -- If Put_Image is disabled, call the "unknown" version
5719
5720 if not Enable_Put_Image (U_Type) then
5721 Rewrite (N, Build_Unknown_Put_Image_Call (N));
5722 Analyze (N);
5723 return;
5724
110d0820
BD
5725 -- For elementary types, we call the routine in System.Put_Images
5726 -- directly.
5727
c324c77e 5728 elsif Is_Elementary_Type (U_Type) then
110d0820
BD
5729 Rewrite (N, Build_Elementary_Put_Image_Call (N));
5730 Analyze (N);
5731 return;
5732
eb725219 5733 elsif Is_Standard_String_Type (U_Type) then
110d0820
BD
5734 Rewrite (N, Build_String_Put_Image_Call (N));
5735 Analyze (N);
5736 return;
5737
5738 elsif Is_Array_Type (U_Type) then
5739 Build_Array_Put_Image_Procedure (N, U_Type, Decl, Pname);
5740 Insert_Action (N, Decl);
5741
5742 -- Tagged type case, use the primitive Put_Image function. Note
5743 -- that this will dispatch in the class-wide case which is what we
5744 -- want.
5745
5746 elsif Is_Tagged_Type (U_Type) then
5747 Pname := Find_Optional_Prim_Op (U_Type, TSS_Put_Image);
5748
5749 -- ????Need Find_Optional_Prim_Op instead of Find_Prim_Op,
5750 -- because we might be deriving from a predefined type, which
5751 -- currently has Enable_Put_Image False.
5752
5753 if No (Pname) then
5754 Rewrite (N, Build_Unknown_Put_Image_Call (N));
5755 Analyze (N);
5756 return;
5757 end if;
5758
5759 elsif Is_Protected_Type (U_Type) then
5760 Rewrite (N, Build_Protected_Put_Image_Call (N));
5761 Analyze (N);
5762 return;
5763
5764 elsif Is_Task_Type (U_Type) then
5765 Rewrite (N, Build_Task_Put_Image_Call (N));
5766 Analyze (N);
5767 return;
5768
c324c77e 5769 -- All other record type cases
110d0820
BD
5770
5771 else
5772 pragma Assert (Is_Record_Type (U_Type));
110d0820
BD
5773 Build_Record_Put_Image_Procedure
5774 (Loc, Full_Base (U_Type), Decl, Pname);
5775 Insert_Action (N, Decl);
5776 end if;
5777 end if;
5778
5779 -- If we fall through, Pname is the procedure to be called
5780
5781 Rewrite_Attribute_Proc_Call (Pname);
5782 end Put_Image;
5783
70482933
RK
5784 ------------------
5785 -- Range_Length --
5786 ------------------
5787
d8f43ee6 5788 when Attribute_Range_Length =>
47d3b920 5789
70482933
RK
5790 -- The only special processing required is for the case where
5791 -- Range_Length is applied to an enumeration type with holes.
5792 -- In this case we transform
5793
5794 -- X'Range_Length
5795
5796 -- to
5797
5798 -- X'Pos (X'Last) - X'Pos (X'First) + 1
5799
5800 -- So that the result reflects the proper Pos values instead
5801 -- of the underlying representations.
5802
21d27997
RD
5803 if Is_Enumeration_Type (Ptyp)
5804 and then Has_Non_Standard_Rep (Ptyp)
70482933
RK
5805 then
5806 Rewrite (N,
5807 Make_Op_Add (Loc,
d8f43ee6 5808 Left_Opnd =>
70482933 5809 Make_Op_Subtract (Loc,
d8f43ee6 5810 Left_Opnd =>
70482933
RK
5811 Make_Attribute_Reference (Loc,
5812 Attribute_Name => Name_Pos,
d8f43ee6
HK
5813 Prefix => New_Occurrence_Of (Ptyp, Loc),
5814 Expressions => New_List (
70482933
RK
5815 Make_Attribute_Reference (Loc,
5816 Attribute_Name => Name_Last,
d8f43ee6
HK
5817 Prefix =>
5818 New_Occurrence_Of (Ptyp, Loc)))),
70482933
RK
5819
5820 Right_Opnd =>
5821 Make_Attribute_Reference (Loc,
5822 Attribute_Name => Name_Pos,
d8f43ee6
HK
5823 Prefix => New_Occurrence_Of (Ptyp, Loc),
5824 Expressions => New_List (
70482933
RK
5825 Make_Attribute_Reference (Loc,
5826 Attribute_Name => Name_First,
d8f43ee6
HK
5827 Prefix =>
5828 New_Occurrence_Of (Ptyp, Loc))))),
70482933 5829
49d140bb 5830 Right_Opnd => Make_Integer_Literal (Loc, 1)));
70482933
RK
5831
5832 Analyze_And_Resolve (N, Typ);
5833
21d27997
RD
5834 -- For all other cases, the attribute is handled by the back end, but
5835 -- we need to deal with the case of the range check on a universal
5836 -- integer.
70482933
RK
5837
5838 else
5839 Apply_Universal_Integer_Attribute_Checks (N);
5840 end if;
70482933 5841
3c08de34
ES
5842 ------------
5843 -- Reduce --
5844 ------------
5845
5846 when Attribute_Reduce =>
5847 declare
90cb252f
PT
5848 Loc : constant Source_Ptr := Sloc (N);
5849 E1 : constant Node_Id := First (Expressions (N));
5850 E2 : constant Node_Id := Next (E1);
5851 Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
5852 Typ : constant Entity_Id := Etype (N);
6d0dedfa 5853
3c08de34 5854 New_Loop : Node_Id;
90cb252f 5855 Stat : Node_Id;
6d0dedfa
ES
5856
5857 function Build_Stat (Comp : Node_Id) return Node_Id;
5858 -- The reducer can be a function, a procedure whose first
5859 -- parameter is in-out, or an attribute that is a function,
5860 -- which (for now) can only be Min/Max. This subprogram
5861 -- builds the corresponding computation for the generated loop.
5862
5863 ----------------
5864 -- Build_Stat --
5865 ----------------
5866
5867 function Build_Stat (Comp : Node_Id) return Node_Id is
5868 begin
5869 if Nkind (E1) = N_Attribute_Reference then
90cb252f
PT
5870 Stat := Make_Assignment_Statement (Loc,
5871 Name => New_Occurrence_Of (Bnn, Loc),
5872 Expression => Make_Attribute_Reference (Loc,
5873 Attribute_Name => Attribute_Name (E1),
5874 Prefix => New_Copy (Prefix (E1)),
5875 Expressions => New_List (
5876 New_Occurrence_Of (Bnn, Loc),
5877 Comp)));
6d0dedfa
ES
5878
5879 elsif Ekind (Entity (E1)) = E_Procedure then
5880 Stat := Make_Procedure_Call_Statement (Loc,
5881 Name => New_Occurrence_Of (Entity (E1), Loc),
5882 Parameter_Associations => New_List (
5883 New_Occurrence_Of (Bnn, Loc),
5884 Comp));
5885 else
90cb252f
PT
5886 Stat := Make_Assignment_Statement (Loc,
5887 Name => New_Occurrence_Of (Bnn, Loc),
5888 Expression => Make_Function_Call (Loc,
5889 Name => New_Occurrence_Of (Entity (E1), Loc),
5890 Parameter_Associations => New_List (
5891 New_Occurrence_Of (Bnn, Loc),
5892 Comp)));
6d0dedfa
ES
5893 end if;
5894
5895 return Stat;
5896 end Build_Stat;
3c08de34 5897
dab8e608
GD
5898 -- If the prefix is an aggregate, its unique component is an
5899 -- Iterated_Element, and we create a loop out of its iterator.
90cb252f
PT
5900 -- The iterated_component_association is parsed as a loop parameter
5901 -- specification with "in" or as a container iterator with "of".
3c08de34
ES
5902
5903 begin
5904 if Nkind (Prefix (N)) = N_Aggregate then
5905 declare
5906 Stream : constant Node_Id :=
dab8e608 5907 First (Component_Associations (Prefix (N)));
3c08de34 5908 Expr : constant Node_Id := Expression (Stream);
6d0dedfa
ES
5909 Id : constant Node_Id := Defining_Identifier (Stream);
5910 It_Spec : constant Node_Id :=
5911 Iterator_Specification (Stream);
5912 Ch : Node_Id;
5913 Iter : Node_Id;
5914
3c08de34 5915 begin
6d0dedfa
ES
5916 -- Iteration may be given by an element iterator:
5917
5918 if Nkind (Stream) = N_Iterated_Component_Association
5919 and then Present (It_Spec)
5920 and then Of_Present (It_Spec)
5921 then
5922 Iter :=
5923 Make_Iteration_Scheme (Loc,
5924 Iterator_Specification =>
5925 Relocate_Node (It_Spec),
5926 Loop_Parameter_Specification => Empty);
5927
5928 else
5929 Ch := First (Discrete_Choices (Stream));
5930 Iter :=
3c08de34
ES
5931 Make_Iteration_Scheme (Loc,
5932 Iterator_Specification => Empty,
5933 Loop_Parameter_Specification =>
5934 Make_Loop_Parameter_Specification (Loc,
5935 Defining_Identifier => New_Copy (Id),
5936 Discrete_Subtype_Definition =>
6d0dedfa
ES
5937 Relocate_Node (Ch)));
5938 end if;
5939
5940 New_Loop := Make_Loop_Statement (Loc,
5941 Iteration_Scheme => Iter,
3c08de34 5942 End_Label => Empty,
6d0dedfa
ES
5943 Statements =>
5944 New_List (Build_Stat (Relocate_Node (Expr))));
3c08de34 5945 end;
6d0dedfa 5946
3c08de34 5947 else
dab8e608
GD
5948 -- If the prefix is a name, we construct an element iterator
5949 -- over it. Its expansion will verify that it is an array or
5950 -- a container with the proper aspects.
3c08de34
ES
5951
5952 declare
5953 Iter : Node_Id;
5954 Elem : constant Entity_Id := Make_Temporary (Loc, 'E', N);
5955
5956 begin
5957 Iter :=
5958 Make_Iterator_Specification (Loc,
5959 Defining_Identifier => Elem,
5960 Name => Relocate_Node (Prefix (N)),
5961 Subtype_Indication => Empty);
5962 Set_Of_Present (Iter);
5963
5964 New_Loop := Make_Loop_Statement (Loc,
5965 Iteration_Scheme =>
5966 Make_Iteration_Scheme (Loc,
5967 Iterator_Specification => Iter,
5968 Loop_Parameter_Specification => Empty),
5969 End_Label => Empty,
5970 Statements => New_List (
6d0dedfa 5971 Build_Stat (New_Occurrence_Of (Elem, Loc))));
3c08de34
ES
5972 end;
5973 end if;
5974
5975 Rewrite (N,
5976 Make_Expression_With_Actions (Loc,
5977 Actions => New_List (
5978 Make_Object_Declaration (Loc,
5979 Defining_Identifier => Bnn,
5980 Object_Definition =>
5981 New_Occurrence_Of (Typ, Loc),
5982 Expression => Relocate_Node (E2)), New_Loop),
5983 Expression => New_Occurrence_Of (Bnn, Loc)));
5984 Analyze_And_Resolve (N, Typ);
5985 end;
5986
70482933
RK
5987 ----------
5988 -- Read --
5989 ----------
5990
5991 when Attribute_Read => Read : declare
5992 P_Type : constant Entity_Id := Entity (Pref);
5993 B_Type : constant Entity_Id := Base_Type (P_Type);
5994 U_Type : constant Entity_Id := Underlying_Type (P_Type);
5995 Pname : Entity_Id;
5996 Decl : Node_Id;
5997 Prag : Node_Id;
5998 Arg2 : Node_Id;
5999 Rfunc : Node_Id;
6000 Lhs : Node_Id;
6001 Rhs : Node_Id;
6002
6003 begin
6004 -- If no underlying type, we have an error that will be diagnosed
6005 -- elsewhere, so here we just completely ignore the expansion.
6006
6007 if No (U_Type) then
6008 return;
6009 end if;
6010
baa571ab
AC
6011 -- Stream operations can appear in user code even if the restriction
6012 -- No_Streams is active (for example, when instantiating a predefined
6013 -- container). In that case rewrite the attribute as a Raise to
6014 -- prevent any run-time use.
6015
6016 if Restriction_Active (No_Streams) then
6017 Rewrite (N,
6018 Make_Raise_Program_Error (Sloc (N),
b8b2d982 6019 Reason => PE_Stream_Operation_Not_Allowed));
baa571ab
AC
6020 Set_Etype (N, B_Type);
6021 return;
6022 end if;
6023
70482933
RK
6024 -- The simple case, if there is a TSS for Read, just call it
6025
fbf5a39b 6026 Pname := Find_Stream_Subprogram (P_Type, TSS_Stream_Read);
70482933
RK
6027
6028 if Present (Pname) then
6029 null;
6030
6031 else
6032 -- If there is a Stream_Convert pragma, use it, we rewrite
6033
6034 -- sourcetyp'Read (stream, Item)
6035
6036 -- as
6037
6038 -- Item := sourcetyp (strmread (strmtyp'Input (Stream)));
6039
758c442c
GD
6040 -- where strmread is the given Read function that converts an
6041 -- argument of type strmtyp to type sourcetyp or a type from which
6042 -- it is derived. The conversion to sourcetyp is required in the
6043 -- latter case.
70482933
RK
6044
6045 -- A special case arises if Item is a type conversion in which
6046 -- case, we have to expand to:
6047
6048 -- Itemx := typex (strmread (strmtyp'Input (Stream)));
6049
6050 -- where Itemx is the expression of the type conversion (i.e.
6051 -- the actual object), and typex is the type of Itemx.
6052
1d571f3b 6053 Prag := Get_Stream_Convert_Pragma (P_Type);
70482933
RK
6054
6055 if Present (Prag) then
6056 Arg2 := Next (First (Pragma_Argument_Associations (Prag)));
6057 Rfunc := Entity (Expression (Arg2));
6058 Lhs := Relocate_Node (Next (First (Exprs)));
6059 Rhs :=
31104818 6060 OK_Convert_To (B_Type,
70482933
RK
6061 Make_Function_Call (Loc,
6062 Name => New_Occurrence_Of (Rfunc, Loc),
6063 Parameter_Associations => New_List (
6064 Make_Attribute_Reference (Loc,
6065 Prefix =>
6066 New_Occurrence_Of
6067 (Etype (First_Formal (Rfunc)), Loc),
6068 Attribute_Name => Name_Input,
6069 Expressions => New_List (
6070 Relocate_Node (First (Exprs)))))));
6071
6072 if Nkind (Lhs) = N_Type_Conversion then
6073 Lhs := Expression (Lhs);
6074 Rhs := Convert_To (Etype (Lhs), Rhs);
6075 end if;
6076
6077 Rewrite (N,
6078 Make_Assignment_Statement (Loc,
fbf5a39b 6079 Name => Lhs,
70482933
RK
6080 Expression => Rhs));
6081 Set_Assignment_OK (Lhs);
6082 Analyze (N);
6083 return;
6084
29f2d76c
SB
6085 -- Limited types
6086
6087 elsif Default_Streaming_Unavailable (U_Type) then
6088 -- Do the same thing here as is done above in the
6089 -- case where a No_Streams restriction is active.
6090
6091 Rewrite (N,
6092 Make_Raise_Program_Error (Sloc (N),
6093 Reason => PE_Stream_Operation_Not_Allowed));
6094 Set_Etype (N, B_Type);
6095 return;
6096
70482933
RK
6097 -- For elementary types, we call the I_xxx routine using the first
6098 -- parameter and then assign the result into the second parameter.
6099 -- We set Assignment_OK to deal with the conversion case.
6100
6101 elsif Is_Elementary_Type (U_Type) then
6102 declare
6103 Lhs : Node_Id;
6104 Rhs : Node_Id;
6105
6106 begin
6107 Lhs := Relocate_Node (Next (First (Exprs)));
6108 Rhs := Build_Elementary_Input_Call (N);
6109
6110 if Nkind (Lhs) = N_Type_Conversion then
6111 Lhs := Expression (Lhs);
6112 Rhs := Convert_To (Etype (Lhs), Rhs);
6113 end if;
6114
6115 Set_Assignment_OK (Lhs);
6116
6117 Rewrite (N,
6118 Make_Assignment_Statement (Loc,
49d140bb 6119 Name => Lhs,
70482933
RK
6120 Expression => Rhs));
6121
6122 Analyze (N);
6123 return;
6124 end;
6125
6126 -- Array type case
6127
6128 elsif Is_Array_Type (U_Type) then
6129 Build_Array_Read_Procedure (N, U_Type, Decl, Pname);
fb632ef5 6130 Compile_Stream_Body_In_Scope (N, Decl, U_Type);
70482933
RK
6131
6132 -- Tagged type case, use the primitive Read function. Note that
6133 -- this will dispatch in the class-wide case which is what we want
6134
6135 elsif Is_Tagged_Type (U_Type) then
fbf5a39b 6136 Pname := Find_Prim_Op (U_Type, TSS_Stream_Read);
70482933 6137
758c442c
GD
6138 -- All other record type cases, including protected records. The
6139 -- latter only arise for expander generated code for handling
6140 -- shared passive partition access.
70482933
RK
6141
6142 else
6143 pragma Assert
6144 (Is_Record_Type (U_Type) or else Is_Protected_Type (U_Type));
6145
5d09245e
AC
6146 -- Ada 2005 (AI-216): Program_Error is raised when executing
6147 -- the default implementation of the Read attribute of an
1f70c47f
AC
6148 -- Unchecked_Union type. We replace the attribute with a
6149 -- raise statement (rather than inserting it before) to handle
6150 -- properly the case of an unchecked union that is a record
6151 -- component.
5d09245e
AC
6152
6153 if Is_Unchecked_Union (Base_Type (U_Type)) then
1f70c47f 6154 Rewrite (N,
5d09245e
AC
6155 Make_Raise_Program_Error (Loc,
6156 Reason => PE_Unchecked_Union_Restriction));
1f70c47f
AC
6157 Set_Etype (N, B_Type);
6158 return;
5d09245e
AC
6159 end if;
6160
8adc8d9b 6161 if Has_Defaulted_Discriminants (U_Type) then
70482933 6162 Build_Mutable_Record_Read_Procedure
96d2756f 6163 (Loc, Full_Base (U_Type), Decl, Pname);
70482933
RK
6164 else
6165 Build_Record_Read_Procedure
96d2756f 6166 (Loc, Full_Base (U_Type), Decl, Pname);
70482933
RK
6167 end if;
6168
fb632ef5 6169 Insert_Action (N, Decl);
70482933
RK
6170 end if;
6171 end if;
6172
110d0820 6173 Rewrite_Attribute_Proc_Call (Pname);
70482933
RK
6174 end Read;
6175
1b0b0f18
AC
6176 ---------
6177 -- Ref --
6178 ---------
6179
6180 -- Ref is identical to To_Address, see To_Address for processing
6181
70482933
RK
6182 ---------------
6183 -- Remainder --
6184 ---------------
6185
6186 -- Transforms 'Remainder into a call to the floating-point attribute
6187 -- function Remainder in Fat_xxx (where xxx is the root type)
6188
6189 when Attribute_Remainder =>
6190 Expand_Fpt_Attribute_RR (N);
6191
21d27997
RD
6192 ------------
6193 -- Result --
6194 ------------
6195
6196 -- Transform 'Result into reference to _Result formal. At the point
6197 -- where a legal 'Result attribute is expanded, we know that we are in
6198 -- the context of a _Postcondition function with a _Result parameter.
6199
6200 when Attribute_Result =>
49d140bb 6201 Rewrite (N, Make_Identifier (Loc, Chars => Name_uResult));
21d27997
RD
6202 Analyze_And_Resolve (N, Typ);
6203
70482933
RK
6204 -----------
6205 -- Round --
6206 -----------
6207
32543637
EB
6208 -- The handling of the Round attribute is delicate when the operand is
6209 -- universal fixed. In this case, the processing in Sem_Attr introduced
6210 -- a conversion to universal real, reflecting the semantics of Round,
6211 -- but we do not want anything to do with universal real at run time,
6212 -- since this corresponds to using floating-point arithmetic.
758c442c
GD
6213
6214 -- What we have now is that the Etype of the Round attribute correctly
6215 -- indicates the final result type. The operand of the Round is the
6216 -- conversion to universal real, described above, and the operand of
6217 -- this conversion is the actual operand of Round, which may be the
32543637 6218 -- special case of a fixed point multiplication or division.
758c442c 6219
32543637 6220 -- The expander will expand first the operand of the conversion, then
758c442c
GD
6221 -- the conversion, and finally the round attribute itself, since we
6222 -- always work inside out. But we cannot simply process naively in this
6223 -- order. In the semantic world where universal fixed and real really
6224 -- exist and have infinite precision, there is no problem, but in the
6225 -- implementation world, where universal real is a floating-point type,
6226 -- we would get the wrong result.
6227
32543637
EB
6228 -- So the approach is as follows. When expanding a multiply or divide
6229 -- whose type is universal fixed, Fixup_Universal_Fixed_Operation will
6230 -- look up and skip the conversion to universal real if its parent is
6231 -- a Round attribute, taking information from this attribute node. In
6232 -- the other cases, Expand_N_Type_Conversion does the same by looking
6233 -- at its parent to see if it is a Round attribute, before calling the
6234 -- fixed-point expansion routine.
70482933
RK
6235
6236 -- This means that by the time we get to expanding the Round attribute
6237 -- itself, the Round is nothing more than a type conversion (and will
6238 -- often be a null type conversion), so we just replace it with the
6239 -- appropriate conversion operation.
6240
6241 when Attribute_Round =>
32543637
EB
6242 if Etype (First (Exprs)) = Etype (N) then
6243 Rewrite (N, Relocate_Node (First (Exprs)));
6244 else
6245 Rewrite (N, Convert_To (Etype (N), First (Exprs)));
6246 Set_Rounded_Result (N);
6247 end if;
70482933
RK
6248 Analyze_And_Resolve (N);
6249
6250 --------------
6251 -- Rounding --
6252 --------------
6253
6254 -- Transforms 'Rounding into a call to the floating-point attribute
6255 -- function Rounding in Fat_xxx (where xxx is the root type)
24228312 6256 -- Expansion is avoided for cases the back end can handle directly.
70482933
RK
6257
6258 when Attribute_Rounding =>
24228312
AC
6259 if not Is_Inline_Floating_Point_Attribute (N) then
6260 Expand_Fpt_Attribute_R (N);
6261 end if;
70482933
RK
6262
6263 -------------
6264 -- Scaling --
6265 -------------
6266
6267 -- Transforms 'Scaling into a call to the floating-point attribute
6268 -- function Scaling in Fat_xxx (where xxx is the root type)
6269
6270 when Attribute_Scaling =>
6271 Expand_Fpt_Attribute_RI (N);
6272
e837a621
AC
6273 ----------------------------------------
6274 -- Simple_Storage_Pool & Storage_Pool --
6275 ----------------------------------------
a8551b5f 6276
e837a621 6277 when Attribute_Simple_Storage_Pool | Attribute_Storage_Pool =>
a8551b5f
AC
6278 Rewrite (N,
6279 Make_Type_Conversion (Loc,
e4494292
RD
6280 Subtype_Mark => New_Occurrence_Of (Etype (N), Loc),
6281 Expression => New_Occurrence_Of (Entity (N), Loc)));
a8551b5f
AC
6282 Analyze_And_Resolve (N, Typ);
6283
70482933
RK
6284 ----------
6285 -- Size --
6286 ----------
6287
d8f43ee6
HK
6288 when Attribute_Object_Size
6289 | Attribute_Size
6290 | Attribute_Value_Size
6291 | Attribute_VADS_Size
6292 =>
6293 Size : declare
d8f43ee6 6294 New_Node : Node_Id;
70482933 6295
d8f43ee6
HK
6296 begin
6297 -- Processing for VADS_Size case. Note that this processing
6298 -- removes all traces of VADS_Size from the tree, and completes
6299 -- all required processing for VADS_Size by translating the
6300 -- attribute reference to an appropriate Size or Object_Size
6301 -- reference.
6302
6303 if Id = Attribute_VADS_Size
6304 or else (Use_VADS_Size and then Id = Attribute_Size)
70482933 6305 then
d8f43ee6
HK
6306 -- If the size is specified, then we simply use the specified
6307 -- size. This applies to both types and objects. The size of an
6308 -- object can be specified in the following ways:
6309
36e38022 6310 -- An explicit size clause is given for an object
d8f43ee6
HK
6311 -- A component size is specified for an indexed component
6312 -- A component clause is specified for a selected component
6313 -- The object is a component of a packed composite object
6314
6315 -- If the size is specified, then VADS_Size of an object
6316
6317 if (Is_Entity_Name (Pref)
6318 and then Present (Size_Clause (Entity (Pref))))
6319 or else
6320 (Nkind (Pref) = N_Component_Clause
6321 and then (Present (Component_Clause
6322 (Entity (Selector_Name (Pref))))
6323 or else Is_Packed (Etype (Prefix (Pref)))))
6324 or else
6325 (Nkind (Pref) = N_Indexed_Component
36e38022 6326 and then (Known_Component_Size (Etype (Prefix (Pref)))
d8f43ee6
HK
6327 or else Is_Packed (Etype (Prefix (Pref)))))
6328 then
6329 Set_Attribute_Name (N, Name_Size);
70482933 6330
d8f43ee6
HK
6331 -- Otherwise if we have an object rather than a type, then
6332 -- the VADS_Size attribute applies to the type of the object,
6333 -- rather than the object itself. This is one of the respects
6334 -- in which VADS_Size differs from Size.
70482933 6335
d8f43ee6
HK
6336 else
6337 if (not Is_Entity_Name (Pref)
6338 or else not Is_Type (Entity (Pref)))
6339 and then (Is_Scalar_Type (Ptyp)
6340 or else Is_Constrained (Ptyp))
6341 then
6342 Rewrite (Pref, New_Occurrence_Of (Ptyp, Loc));
6343 end if;
70482933 6344
d8f43ee6
HK
6345 -- For a scalar type for which no size was explicitly given,
6346 -- VADS_Size means Object_Size. This is the other respect in
6347 -- which VADS_Size differs from Size.
70482933 6348
d8f43ee6
HK
6349 if Is_Scalar_Type (Ptyp)
6350 and then No (Size_Clause (Ptyp))
6351 then
6352 Set_Attribute_Name (N, Name_Object_Size);
70482933 6353
cb9d41eb 6354 -- In all other cases, Size and VADS_Size are the same
70482933 6355
d8f43ee6
HK
6356 else
6357 Set_Attribute_Name (N, Name_Size);
6358 end if;
70482933
RK
6359 end if;
6360 end if;
70482933 6361
d8f43ee6
HK
6362 -- If the prefix is X'Class, transform it into a direct reference
6363 -- to the class-wide type, because the back end must not see a
6364 -- 'Class reference.
70482933 6365
d8f43ee6
HK
6366 if Is_Entity_Name (Pref)
6367 and then Is_Class_Wide_Type (Entity (Pref))
6368 then
6369 Rewrite (Prefix (N), New_Occurrence_Of (Entity (Pref), Loc));
6370 return;
fbf5a39b 6371
d8f43ee6
HK
6372 -- For X'Size applied to an object of a class-wide type, transform
6373 -- X'Size into a call to the primitive operation _Size applied to
6374 -- X.
fbf5a39b 6375
d8f43ee6 6376 elsif Is_Class_Wide_Type (Ptyp) then
e23e04db 6377
d8f43ee6
HK
6378 -- No need to do anything else compiling under restriction
6379 -- No_Dispatching_Calls. During the semantic analysis we
6380 -- already noted this restriction violation.
0669bebe 6381
d8f43ee6
HK
6382 if Restriction_Active (No_Dispatching_Calls) then
6383 return;
6384 end if;
0669bebe 6385
d8f43ee6
HK
6386 New_Node :=
6387 Make_Function_Call (Loc,
6388 Name =>
6389 New_Occurrence_Of (Find_Prim_Op (Ptyp, Name_uSize), Loc),
6390 Parameter_Associations => New_List (Pref));
70482933 6391
d8f43ee6 6392 if Typ /= Standard_Long_Long_Integer then
70482933 6393
d8f43ee6
HK
6394 -- The context is a specific integer type with which the
6395 -- original attribute was compatible. The function has a
6396 -- specific type as well, so to preserve the compatibility
6397 -- we must convert explicitly.
70482933 6398
d8f43ee6
HK
6399 New_Node := Convert_To (Typ, New_Node);
6400 end if;
70482933 6401
d8f43ee6
HK
6402 Rewrite (N, New_Node);
6403 Analyze_And_Resolve (N, Typ);
6404 return;
d8f43ee6 6405 end if;
70482933 6406
d39f6b24
YM
6407 -- Call Expand_Size_Attribute to do the final part of the
6408 -- expansion which is shared with GNATprove expansion.
70482933 6409
d39f6b24 6410 Expand_Size_Attribute (N);
d8f43ee6 6411 end Size;
70482933 6412
70482933
RK
6413 ------------------
6414 -- Storage_Size --
6415 ------------------
6416
a8551b5f 6417 when Attribute_Storage_Size => Storage_Size : declare
90cb252f 6418 Alloc_Op : Entity_Id := Empty;
a8551b5f
AC
6419
6420 begin
70482933 6421
70482933
RK
6422 -- Access type case, always go to the root type
6423
6424 -- The case of access types results in a value of zero for the case
6425 -- where no storage size attribute clause has been given. If a
6426 -- storage size has been given, then the attribute is converted
6427 -- to a reference to the variable used to hold this value.
6428
6429 if Is_Access_Type (Ptyp) then
6430 if Present (Storage_Size_Variable (Root_Type (Ptyp))) then
6431 Rewrite (N,
6a987d78
EB
6432 Convert_To (Typ,
6433 Make_Attribute_Reference (Loc,
6434 Prefix => New_Occurrence_Of
6435 (Etype (Storage_Size_Variable (Root_Type (Ptyp))), Loc),
6436 Attribute_Name => Name_Max,
6437 Expressions => New_List (
6438 Make_Integer_Literal (Loc, 0),
e4494292 6439 New_Occurrence_Of
70482933
RK
6440 (Storage_Size_Variable (Root_Type (Ptyp)), Loc)))));
6441
6442 elsif Present (Associated_Storage_Pool (Root_Type (Ptyp))) then
7ce611e2 6443
a8551b5f
AC
6444 -- If the access type is associated with a simple storage pool
6445 -- object, then attempt to locate the optional Storage_Size
6446 -- function of the simple storage pool type. If not found,
6447 -- then the result will default to zero.
6448
6449 if Present (Get_Rep_Pragma (Root_Type (Ptyp),
f6205414 6450 Name_Simple_Storage_Pool_Type))
a8551b5f
AC
6451 then
6452 declare
6453 Pool_Type : constant Entity_Id :=
6454 Base_Type (Etype (Entity (N)));
6455
6456 begin
6457 Alloc_Op := Get_Name_Entity_Id (Name_Storage_Size);
6458 while Present (Alloc_Op) loop
6459 if Scope (Alloc_Op) = Scope (Pool_Type)
6460 and then Present (First_Formal (Alloc_Op))
6461 and then Etype (First_Formal (Alloc_Op)) = Pool_Type
6462 then
6463 exit;
6464 end if;
6465
6466 Alloc_Op := Homonym (Alloc_Op);
6467 end loop;
6468 end;
6469
6470 -- In the normal Storage_Pool case, retrieve the primitive
6471 -- function associated with the pool type.
6472
6473 else
6474 Alloc_Op :=
6475 Find_Prim_Op
6476 (Etype (Associated_Storage_Pool (Root_Type (Ptyp))),
6477 Attribute_Name (N));
6478 end if;
6479
6480 -- If Storage_Size wasn't found (can only occur in the simple
6481 -- storage pool case), then simply use zero for the result.
6482
6483 if not Present (Alloc_Op) then
6484 Rewrite (N, Make_Integer_Literal (Loc, 0));
6485
6486 -- Otherwise, rewrite the allocator as a call to pool type's
6487 -- Storage_Size function.
6488
6489 else
6490 Rewrite (N,
6a987d78 6491 Convert_To (Typ,
a8551b5f
AC
6492 Make_Function_Call (Loc,
6493 Name =>
e4494292 6494 New_Occurrence_Of (Alloc_Op, Loc),
a8551b5f
AC
6495
6496 Parameter_Associations => New_List (
e4494292 6497 New_Occurrence_Of
a8551b5f
AC
6498 (Associated_Storage_Pool
6499 (Root_Type (Ptyp)), Loc)))));
6500 end if;
70482933 6501
70482933
RK
6502 else
6503 Rewrite (N, Make_Integer_Literal (Loc, 0));
6504 end if;
6505
6506 Analyze_And_Resolve (N, Typ);
6507
7ce611e2
ES
6508 -- For tasks, we retrieve the size directly from the TCB. The
6509 -- size may depend on a discriminant of the type, and therefore
6510 -- can be a per-object expression, so type-level information is
6511 -- not sufficient in general. There are four cases to consider:
70482933 6512
7ce611e2
ES
6513 -- a) If the attribute appears within a task body, the designated
6514 -- TCB is obtained by a call to Self.
70482933 6515
7ce611e2
ES
6516 -- b) If the prefix of the attribute is the name of a task object,
6517 -- the designated TCB is the one stored in the corresponding record.
70482933 6518
7ce611e2
ES
6519 -- c) If the prefix is a task type, the size is obtained from the
6520 -- size variable created for each task type
70482933 6521
f145ece7 6522 -- d) If no Storage_Size was specified for the type, there is no
7ce611e2 6523 -- size variable, and the value is a system-specific default.
70482933
RK
6524
6525 else
7ce611e2
ES
6526 if In_Open_Scopes (Ptyp) then
6527
6528 -- Storage_Size (Self)
6529
70482933
RK
6530 Rewrite (N,
6531 Convert_To (Typ,
6532 Make_Function_Call (Loc,
6533 Name =>
7ce611e2
ES
6534 New_Occurrence_Of (RTE (RE_Storage_Size), Loc),
6535 Parameter_Associations =>
6536 New_List (
6537 Make_Function_Call (Loc,
6538 Name =>
e4494292 6539 New_Occurrence_Of (RTE (RE_Self), Loc))))));
70482933 6540
7ce611e2
ES
6541 elsif not Is_Entity_Name (Pref)
6542 or else not Is_Type (Entity (Pref))
6543 then
6544 -- Storage_Size (Rec (Obj).Size)
6545
6546 Rewrite (N,
6547 Convert_To (Typ,
6548 Make_Function_Call (Loc,
6549 Name =>
6550 New_Occurrence_Of (RTE (RE_Storage_Size), Loc),
6551 Parameter_Associations =>
70482933
RK
6552 New_List (
6553 Make_Selected_Component (Loc,
6554 Prefix =>
6555 Unchecked_Convert_To (
6556 Corresponding_Record_Type (Ptyp),
7ce611e2 6557 New_Copy_Tree (Pref)),
70482933 6558 Selector_Name =>
7ce611e2 6559 Make_Identifier (Loc, Name_uTask_Id))))));
70482933 6560
7ce611e2 6561 elsif Present (Storage_Size_Variable (Ptyp)) then
70482933 6562
f145ece7 6563 -- Static Storage_Size pragma given for type: retrieve value
7ce611e2 6564 -- from its allocated storage variable.
70482933 6565
7ce611e2
ES
6566 Rewrite (N,
6567 Convert_To (Typ,
6568 Make_Function_Call (Loc,
6569 Name => New_Occurrence_Of (
6570 RTE (RE_Adjust_Storage_Size), Loc),
6571 Parameter_Associations =>
6572 New_List (
e4494292 6573 New_Occurrence_Of (
7ce611e2
ES
6574 Storage_Size_Variable (Ptyp), Loc)))));
6575 else
6576 -- Get system default
6577
6578 Rewrite (N,
6579 Convert_To (Typ,
6580 Make_Function_Call (Loc,
6581 Name =>
6582 New_Occurrence_Of (
6583 RTE (RE_Default_Stack_Size), Loc))));
70482933 6584 end if;
7ce611e2
ES
6585
6586 Analyze_And_Resolve (N, Typ);
70482933
RK
6587 end if;
6588 end Storage_Size;
6589
82c80734
RD
6590 -----------------
6591 -- Stream_Size --
6592 -----------------
6593
9eea4346
GB
6594 when Attribute_Stream_Size =>
6595 Rewrite (N,
6596 Make_Integer_Literal (Loc, Intval => Get_Stream_Size (Ptyp)));
82c80734 6597 Analyze_And_Resolve (N, Typ);
82c80734 6598
70482933
RK
6599 ----------
6600 -- Succ --
6601 ----------
6602
29049f0b
AC
6603 -- 1. Deal with enumeration types with holes.
6604 -- 2. For floating-point, generate call to attribute function.
6605 -- 3. For other cases, deal with constraint checking.
70482933 6606
47d3b920 6607 when Attribute_Succ => Succ : declare
21d27997 6608 Etyp : constant Entity_Id := Base_Type (Ptyp);
70482933
RK
6609
6610 begin
6611 -- For enumeration types with non-standard representations, we
79e267f9 6612 -- expand typ'Pred (x) into:
70482933
RK
6613
6614 -- Pos_To_Rep (Rep_To_Pos (x) + 1)
6615
79e267f9
EB
6616 -- if the representation is non-contiguous, and just x + 1 if it is
6617 -- after having dealt with constraint checking.
fbf5a39b 6618
79e267f9 6619 if Is_Enumeration_Type (Etyp)
21d27997 6620 and then Present (Enum_Pos_To_Rep (Etyp))
70482933 6621 then
21d27997 6622 if Has_Contiguous_Rep (Etyp) then
79e267f9
EB
6623 if not Range_Checks_Suppressed (Ptyp) then
6624 Set_Do_Range_Check (First (Exprs), False);
6625 Expand_Pred_Succ_Attribute (N);
6626 end if;
6627
fbf5a39b 6628 Rewrite (N,
79e267f9
EB
6629 Unchecked_Convert_To (Etyp,
6630 Make_Op_Add (Loc,
6631 Left_Opnd =>
c7c7dd3a
EB
6632 Unchecked_Convert_To (
6633 Integer_Type_For
6634 (Esize (Etyp), Is_Unsigned_Type (Etyp)),
6635 First (Exprs)),
79e267f9
EB
6636 Right_Opnd =>
6637 Make_Integer_Literal (Loc, 1))));
fbf5a39b 6638
fbf5a39b 6639 else
16b54914 6640 -- Add Boolean parameter True, to request program error if
fbf5a39b
AC
6641 -- we have a bad representation on our hands. Add False if
6642 -- checks are suppressed.
70482933 6643
fbf5a39b
AC
6644 Append_To (Exprs, Rep_To_Pos_Flag (Ptyp, Loc));
6645 Rewrite (N,
6646 Make_Indexed_Component (Loc,
21d27997 6647 Prefix =>
e4494292 6648 New_Occurrence_Of
21d27997 6649 (Enum_Pos_To_Rep (Etyp), Loc),
fbf5a39b
AC
6650 Expressions => New_List (
6651 Make_Op_Add (Loc,
6652 Left_Opnd =>
6653 Make_Function_Call (Loc,
6654 Name =>
e4494292 6655 New_Occurrence_Of
21d27997 6656 (TSS (Etyp, TSS_Rep_To_Pos), Loc),
fbf5a39b
AC
6657 Parameter_Associations => Exprs),
6658 Right_Opnd => Make_Integer_Literal (Loc, 1)))));
6659 end if;
70482933 6660
79e267f9
EB
6661 -- Suppress checks since they have all been done above
6662
6663 Analyze_And_Resolve (N, Typ, Suppress => All_Checks);
70482933
RK
6664
6665 -- For floating-point, we transform 'Succ into a call to the Succ
6666 -- floating-point attribute function in Fat_xxx (xxx is root type)
6667
6668 elsif Is_Floating_Point_Type (Ptyp) then
6669 Expand_Fpt_Attribute_R (N);
6670 Analyze_And_Resolve (N, Typ);
6671
6672 -- For modular types, nothing to do (no overflow, since wraps)
6673
6674 elsif Is_Modular_Integer_Type (Ptyp) then
6675 null;
6676
d79e621a
GD
6677 -- For other types, if argument is marked as needing a range check or
6678 -- overflow checking is enabled, we must generate a check.
70482933 6679
d79e621a
GD
6680 elsif not Overflow_Checks_Suppressed (Ptyp)
6681 or else Do_Range_Check (First (Exprs))
6682 then
6683 Set_Do_Range_Check (First (Exprs), False);
aa9b151a 6684 Expand_Pred_Succ_Attribute (N);
70482933
RK
6685 end if;
6686 end Succ;
6687
6688 ---------
6689 -- Tag --
6690 ---------
6691
6692 -- Transforms X'Tag into a direct reference to the tag of X
6693
47d3b920 6694 when Attribute_Tag => Tag : declare
70482933
RK
6695 Ttyp : Entity_Id;
6696 Prefix_Is_Type : Boolean;
6697
6698 begin
6699 if Is_Entity_Name (Pref) and then Is_Type (Entity (Pref)) then
6700 Ttyp := Entity (Pref);
6701 Prefix_Is_Type := True;
6702 else
21d27997 6703 Ttyp := Ptyp;
70482933
RK
6704 Prefix_Is_Type := False;
6705 end if;
6706
a252a471
JS
6707 -- In the case of a class-wide equivalent type without a parent,
6708 -- the _Tag component has been built in Make_CW_Equivalent_Type
6709 -- manually and must be referenced directly.
6710
6711 if Ekind (Ttyp) = E_Class_Wide_Subtype
6712 and then Present (Equivalent_Type (Ttyp))
6713 and then No (Parent_Subtype (Equivalent_Type (Ttyp)))
6714 then
6715 Ttyp := Equivalent_Type (Ttyp);
6716
6717 -- In all the other cases of class-wide type, including an equivalent
6718 -- type with a parent, the _Tag component ultimately present is that
6719 -- of the root type.
6720
6721 elsif Is_Class_Wide_Type (Ttyp) then
70482933
RK
6722 Ttyp := Root_Type (Ttyp);
6723 end if;
6724
6725 Ttyp := Underlying_Type (Ttyp);
6726
8a78c50d
AC
6727 -- Ada 2005: The type may be a synchronized tagged type, in which
6728 -- case the tag information is stored in the corresponding record.
6729
6730 if Is_Concurrent_Type (Ttyp) then
6731 Ttyp := Corresponding_Record_Type (Ttyp);
6732 end if;
6733
70482933 6734 if Prefix_Is_Type then
3a77b68d 6735
31104818 6736 -- For VMs we leave the type attribute unexpanded because
3a77b68d
GB
6737 -- there's not a dispatching table to reference.
6738
1f110335 6739 if Tagged_Type_Expansion then
3a77b68d
GB
6740 Rewrite (N,
6741 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 6742 New_Occurrence_Of
a9d8907c 6743 (Node (First_Elmt (Access_Disp_Table (Ttyp))), Loc)));
3a77b68d
GB
6744 Analyze_And_Resolve (N, RTE (RE_Tag));
6745 end if;
70482933 6746
934a3a25 6747 -- Ada 2005 (AI-251): The use of 'Tag in the sources always
31104818
HK
6748 -- references the primary tag of the actual object. If 'Tag is
6749 -- applied to class-wide interface objects we generate code that
6750 -- displaces "this" to reference the base of the object.
6751
6752 elsif Comes_From_Source (N)
6753 and then Is_Class_Wide_Type (Etype (Prefix (N)))
63a5b3dc 6754 and then Is_Interface (Underlying_Type (Etype (Prefix (N))))
31104818
HK
6755 then
6756 -- Generate:
6757 -- (To_Tag_Ptr (Prefix'Address)).all
6758
6759 -- Note that Prefix'Address is recursively expanded into a call
6760 -- to Base_Address (Obj.Tag)
6761
470cd9e9
RD
6762 -- Not needed for VM targets, since all handled by the VM
6763
1f110335 6764 if Tagged_Type_Expansion then
470cd9e9
RD
6765 Rewrite (N,
6766 Make_Explicit_Dereference (Loc,
6767 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
6768 Make_Attribute_Reference (Loc,
6769 Prefix => Relocate_Node (Pref),
6770 Attribute_Name => Name_Address))));
6771 Analyze_And_Resolve (N, RTE (RE_Tag));
6772 end if;
31104818 6773
70482933
RK
6774 else
6775 Rewrite (N,
6776 Make_Selected_Component (Loc,
6777 Prefix => Relocate_Node (Pref),
6778 Selector_Name =>
e4494292 6779 New_Occurrence_Of (First_Tag_Component (Ttyp), Loc)));
3a77b68d 6780 Analyze_And_Resolve (N, RTE (RE_Tag));
70482933 6781 end if;
70482933
RK
6782 end Tag;
6783
6784 ----------------
6785 -- Terminated --
6786 ----------------
6787
758c442c 6788 -- Transforms 'Terminated attribute into a call to Terminated function
70482933 6789
d8f43ee6
HK
6790 when Attribute_Terminated => Terminated : begin
6791
65f01153
RD
6792 -- The prefix of Terminated is of a task interface class-wide type.
6793 -- Generate:
31e358e1 6794 -- terminated (Task_Id (_disp_get_task_id (Pref)));
65f01153 6795
0791fbe9 6796 if Ada_Version >= Ada_2005
21d27997
RD
6797 and then Ekind (Ptyp) = E_Class_Wide_Type
6798 and then Is_Interface (Ptyp)
6799 and then Is_Task_Interface (Ptyp)
65f01153 6800 then
99bba92c
AC
6801 Rewrite (N,
6802 Make_Function_Call (Loc,
c0e938d0 6803 Name =>
99bba92c
AC
6804 New_Occurrence_Of (RTE (RE_Terminated), Loc),
6805 Parameter_Associations => New_List (
738a0e8d
BD
6806 Unchecked_Convert_To
6807 (RTE (RO_ST_Task_Id),
6808 Build_Disp_Get_Task_Id_Call (Pref)))));
65f01153
RD
6809
6810 elsif Restricted_Profile then
70482933
RK
6811 Rewrite (N,
6812 Build_Call_With_Task (Pref, RTE (RE_Restricted_Terminated)));
6813
6814 else
6815 Rewrite (N,
6816 Build_Call_With_Task (Pref, RTE (RE_Terminated)));
6817 end if;
6818
6819 Analyze_And_Resolve (N, Standard_Boolean);
6820 end Terminated;
6821
6822 ----------------
6823 -- To_Address --
6824 ----------------
6825
1b0b0f18 6826 -- Transforms System'To_Address (X) and System.Address'Ref (X) into
1e3c434f
BD
6827 -- unchecked conversion from (integral) type of X to type address. If
6828 -- the To_Address is a static expression, the transformed expression
6829 -- also needs to be static, because we do some legality checks (e.g.
6830 -- for Thread_Local_Storage) after this transformation.
70482933 6831
89beb653
HK
6832 when Attribute_Ref
6833 | Attribute_To_Address
6834 =>
6835 To_Address : declare
6836 Is_Static : constant Boolean := Is_Static_Expression (N);
6837
6838 begin
6839 Rewrite (N,
6840 Unchecked_Convert_To (RTE (RE_Address),
6841 Relocate_Node (First (Exprs))));
6842 Set_Is_Static_Expression (N, Is_Static);
6843
6844 Analyze_And_Resolve (N, RTE (RE_Address));
6845 end To_Address;
70482933 6846
54838d1f
AC
6847 ------------
6848 -- To_Any --
6849 ------------
6850
6851 when Attribute_To_Any => To_Any : declare
90cb252f 6852 Decls : constant List_Id := New_List;
54838d1f
AC
6853 begin
6854 Rewrite (N,
6855 Build_To_Any_Call
30ebb114 6856 (Loc,
10e168cd 6857 Convert_To (Ptyp,
54838d1f
AC
6858 Relocate_Node (First (Exprs))), Decls));
6859 Insert_Actions (N, Decls);
6860 Analyze_And_Resolve (N, RTE (RE_Any));
6861 end To_Any;
6862
70482933
RK
6863 ----------------
6864 -- Truncation --
6865 ----------------
6866
6867 -- Transforms 'Truncation into a call to the floating-point attribute
0669bebe
GB
6868 -- function Truncation in Fat_xxx (where xxx is the root type).
6869 -- Expansion is avoided for cases the back end can handle directly.
70482933
RK
6870
6871 when Attribute_Truncation =>
0669bebe
GB
6872 if not Is_Inline_Floating_Point_Attribute (N) then
6873 Expand_Fpt_Attribute_R (N);
6874 end if;
70482933 6875
54838d1f
AC
6876 --------------
6877 -- TypeCode --
6878 --------------
6879
6880 when Attribute_TypeCode => TypeCode : declare
90cb252f 6881 Decls : constant List_Id := New_List;
54838d1f 6882 begin
10e168cd 6883 Rewrite (N, Build_TypeCode_Call (Loc, Ptyp, Decls));
54838d1f
AC
6884 Insert_Actions (N, Decls);
6885 Analyze_And_Resolve (N, RTE (RE_TypeCode));
6886 end TypeCode;
6887
70482933
RK
6888 -----------------------
6889 -- Unbiased_Rounding --
6890 -----------------------
6891
6892 -- Transforms 'Unbiased_Rounding into a call to the floating-point
6893 -- attribute function Unbiased_Rounding in Fat_xxx (where xxx is the
0669bebe
GB
6894 -- root type). Expansion is avoided for cases the back end can handle
6895 -- directly.
70482933
RK
6896
6897 when Attribute_Unbiased_Rounding =>
0669bebe
GB
6898 if not Is_Inline_Floating_Point_Attribute (N) then
6899 Expand_Fpt_Attribute_R (N);
6900 end if;
70482933 6901
18a2ad5d
AC
6902 ------------
6903 -- Update --
6904 ------------
6905
6906 when Attribute_Update =>
6907 Expand_Update_Attribute (N);
6908
70482933
RK
6909 ---------------
6910 -- VADS_Size --
6911 ---------------
6912
6913 -- The processing for VADS_Size is shared with Size
6914
6915 ---------
6916 -- Val --
6917 ---------
6918
10e168cd
EB
6919 -- For enumeration types with a non-standard representation we use the
6920 -- _Pos_To_Rep array that was created when the type was frozen, unless
6921 -- the representation is contiguous in which case we use an addition.
6922
f193b29e
EB
6923 -- For enumeration types with a standard representation, Val can be
6924 -- rewritten as a simple conversion with Conversion_OK set.
6925
10e168cd
EB
6926 -- For integer types, Val is equivalent to a simple integer conversion
6927 -- and we rewrite it as such.
70482933 6928
47d3b920 6929 when Attribute_Val => Val : declare
10e168cd
EB
6930 Etyp : constant Entity_Id := Base_Type (Ptyp);
6931 Expr : constant Node_Id := First (Exprs);
79e267f9 6932 Rtyp : Entity_Id;
70482933
RK
6933
6934 begin
10e168cd 6935 -- Case of enumeration type
fbf5a39b 6936
10e168cd
EB
6937 if Is_Enumeration_Type (Etyp) then
6938
79e267f9 6939 -- Non-contiguous non-standard enumeration type
10e168cd 6940
79e267f9
EB
6941 if Present (Enum_Pos_To_Rep (Etyp))
6942 and then not Has_Contiguous_Rep (Etyp)
6943 then
6944 Rewrite (N,
6945 Make_Indexed_Component (Loc,
6946 Prefix =>
6947 New_Occurrence_Of (Enum_Pos_To_Rep (Etyp), Loc),
6948 Expressions => New_List (
6949 Convert_To (Standard_Integer, Expr))));
10e168cd 6950
79e267f9 6951 Analyze_And_Resolve (N, Typ);
10e168cd 6952
79e267f9 6953 -- Standard or contiguous non-standard enumeration type
fbf5a39b 6954
79e267f9
EB
6955 else
6956 -- If the argument is marked as requiring a range check then
6957 -- generate it here, after looking through a conversion to
6958 -- universal integer, if any.
6959
6960 if Do_Range_Check (Expr) then
6961 if Present (Enum_Pos_To_Rep (Etyp)) then
6962 Rtyp := Enum_Pos_To_Rep (Etyp);
6963 else
6964 Rtyp := Etyp;
6965 end if;
70482933 6966
79e267f9
EB
6967 if Nkind (Expr) = N_Type_Conversion
6968 and then Entity (Subtype_Mark (Expr)) = Universal_Integer
6969 then
6970 Generate_Range_Check
6971 (Expression (Expr), Rtyp, CE_Range_Check_Failed);
10e168cd 6972
79e267f9
EB
6973 else
6974 Generate_Range_Check (Expr, Rtyp, CE_Range_Check_Failed);
6975 end if;
10e168cd 6976
10e168cd 6977 Set_Do_Range_Check (Expr, False);
79e267f9 6978 end if;
d79e621a 6979
79e267f9
EB
6980 -- Contiguous non-standard enumeration type
6981
6982 if Present (Enum_Pos_To_Rep (Etyp)) then
79e267f9
EB
6983 Rewrite (N,
6984 Unchecked_Convert_To (Etyp,
6985 Make_Op_Add (Loc,
6986 Left_Opnd =>
6987 Make_Integer_Literal (Loc,
6988 Enumeration_Rep (First_Literal (Etyp))),
6989 Right_Opnd =>
c7c7dd3a
EB
6990 Unchecked_Convert_To (
6991 Integer_Type_For
6992 (Esize (Etyp), Is_Unsigned_Type (Etyp)),
6993 Expr))));
79e267f9 6994
f193b29e 6995 -- Standard enumeration type
79e267f9 6996
f193b29e
EB
6997 else
6998 Rewrite (N, OK_Convert_To (Typ, Expr));
10e168cd 6999 end if;
f193b29e
EB
7000
7001 -- Suppress checks since the range check was done above
7002 -- and it guarantees that the addition cannot overflow.
7003
7004 Analyze_And_Resolve (N, Typ, Suppress => All_Checks);
10e168cd 7005 end if;
d79e621a 7006
10e168cd
EB
7007 -- Deal with integer types
7008
7009 elsif Is_Integer_Type (Etyp) then
7010 Rewrite (N, Convert_To (Typ, Expr));
7011 Analyze_And_Resolve (N, Typ);
70482933
RK
7012 end if;
7013 end Val;
7014
7015 -----------
7016 -- Valid --
7017 -----------
7018
7019 -- The code for valid is dependent on the particular types involved.
7020 -- See separate sections below for the generated code in each case.
7021
47d3b920 7022 when Attribute_Valid => Valid : declare
382b0e97 7023 PBtyp : Entity_Id := Base_Type (Ptyp);
70482933 7024
fbf5a39b
AC
7025 Save_Validity_Checks_On : constant Boolean := Validity_Checks_On;
7026 -- Save the validity checking mode. We always turn off validity
7027 -- checking during process of 'Valid since this is one place
9e40de1d 7028 -- where we do not want the implicit validity checks to interfere
fbf5a39b
AC
7029 -- with the explicit validity check that the programmer is doing.
7030
70482933
RK
7031 function Make_Range_Test return Node_Id;
7032 -- Build the code for a range test of the form
382b0e97 7033 -- PBtyp!(Pref) in PBtyp!(Ptyp'First) .. PBtyp!(Ptyp'Last)
70482933 7034
fbf5a39b
AC
7035 ---------------------
7036 -- Make_Range_Test --
7037 ---------------------
7038
70482933 7039 function Make_Range_Test return Node_Id is
89b6c83e 7040 Temp : Node_Id;
dbf04430 7041
70482933 7042 begin
89b6c83e
AC
7043 -- The prefix of attribute 'Valid should always denote an object
7044 -- reference. The reference is either coming directly from source
5168a9b3
PMR
7045 -- or is produced by validity check expansion. The object may be
7046 -- wrapped in a conversion in which case the call to Unqual_Conv
7047 -- will yield it.
dbf04430 7048
89b6c83e
AC
7049 -- If the prefix denotes a variable which captures the value of
7050 -- an object for validation purposes, use the variable in the
7051 -- range test. This ensures that no extra copies or extra reads
7052 -- are produced as part of the test. Generate:
7053
7054 -- Temp : ... := Object;
7055 -- if not Temp in ... then
7056
7057 if Is_Validation_Variable_Reference (Pref) then
5168a9b3 7058 Temp := New_Occurrence_Of (Entity (Unqual_Conv (Pref)), Loc);
89b6c83e
AC
7059
7060 -- Otherwise the prefix is either a source object or a constant
7061 -- produced by validity check expansion. Generate:
7062
7063 -- Temp : constant ... := Pref;
7064 -- if not Temp in ... then
7065
7066 else
7067 Temp := Duplicate_Subexpr (Pref);
dbf04430
AC
7068 end if;
7069
70482933 7070 return
ea034236 7071 Make_In (Loc,
382b0e97 7072 Left_Opnd => Unchecked_Convert_To (PBtyp, Temp),
ea034236
AC
7073 Right_Opnd =>
7074 Make_Range (Loc,
89b6c83e 7075 Low_Bound =>
382b0e97 7076 Unchecked_Convert_To (PBtyp,
70482933 7077 Make_Attribute_Reference (Loc,
89b6c83e 7078 Prefix => New_Occurrence_Of (Ptyp, Loc),
ea034236
AC
7079 Attribute_Name => Name_First)),
7080 High_Bound =>
382b0e97 7081 Unchecked_Convert_To (PBtyp,
70482933 7082 Make_Attribute_Reference (Loc,
89b6c83e 7083 Prefix => New_Occurrence_Of (Ptyp, Loc),
70482933
RK
7084 Attribute_Name => Name_Last))));
7085 end Make_Range_Test;
7086
f16cb8df
HK
7087 -- Local variables
7088
7089 Tst : Node_Id;
7090
70482933
RK
7091 -- Start of processing for Attribute_Valid
7092
7093 begin
1d57c04f
AC
7094 -- Do not expand sourced code 'Valid reference in CodePeer mode,
7095 -- will be handled by the back-end directly.
7096
7097 if CodePeer_Mode and then Comes_From_Source (N) then
7098 return;
7099 end if;
7100
fbf5a39b
AC
7101 -- Turn off validity checks. We do not want any implicit validity
7102 -- checks to intefere with the explicit check from the attribute
7103
7104 Validity_Checks_On := False;
7105
d7a44b14
AC
7106 -- Retrieve the base type. Handle the case where the base type is a
7107 -- private enumeration type.
7108
382b0e97
BD
7109 if Is_Private_Type (PBtyp) and then Present (Full_View (PBtyp)) then
7110 PBtyp := Full_View (PBtyp);
d7a44b14
AC
7111 end if;
7112
70482933
RK
7113 -- Floating-point case. This case is handled by the Valid attribute
7114 -- code in the floating-point attribute run-time library.
7115
7116 if Is_Floating_Point_Type (Ptyp) then
dfaff97b 7117 Float_Valid : declare
65f01153
RD
7118 Pkg : RE_Id;
7119 Ftp : Entity_Id;
70482933 7120
8575023c
AC
7121 function Get_Fat_Entity (Nam : Name_Id) return Entity_Id;
7122 -- Return entity for Pkg.Nam
7123
7124 --------------------
7125 -- Get_Fat_Entity --
7126 --------------------
7127
7128 function Get_Fat_Entity (Nam : Name_Id) return Entity_Id is
7129 Exp_Name : constant Node_Id :=
7130 Make_Selected_Component (Loc,
7131 Prefix => New_Occurrence_Of (RTE (Pkg), Loc),
7132 Selector_Name => Make_Identifier (Loc, Nam));
7133 begin
7134 Find_Selected_Component (Exp_Name);
7135 return Entity (Exp_Name);
7136 end Get_Fat_Entity;
7137
dfaff97b
RD
7138 -- Start of processing for Float_Valid
7139
70482933 7140 begin
9324e07d 7141 -- The C back end handles Valid for floating-point types
8575023c 7142
9324e07d 7143 if Modify_Tree_For_C then
88438c0e
AC
7144 Analyze_And_Resolve (Pref, Ptyp);
7145 Set_Etype (N, Standard_Boolean);
7146 Set_Analyzed (N);
8575023c 7147
88438c0e
AC
7148 else
7149 Find_Fat_Info (Ptyp, Ftp, Pkg);
7150
7151 -- If the prefix is a reverse SSO component, or is possibly
7152 -- unaligned, first create a temporary copy that is in
7153 -- native SSO, and properly aligned. Make it Volatile to
7154 -- prevent folding in the back-end. Note that we use an
7155 -- intermediate constrained string type to initialize the
7156 -- temporary, as the value at hand might be invalid, and in
7157 -- that case it cannot be copied using a floating point
7158 -- register.
7159
7160 if In_Reverse_Storage_Order_Object (Pref)
7161 or else Is_Possibly_Unaligned_Object (Pref)
7162 then
7163 declare
7164 Temp : constant Entity_Id :=
7165 Make_Temporary (Loc, 'F');
7166
7167 Fat_S : constant Entity_Id :=
7168 Get_Fat_Entity (Name_S);
7169 -- Constrained string subtype of appropriate size
7170
7171 Fat_P : constant Entity_Id :=
7172 Get_Fat_Entity (Name_P);
7173 -- Access to Fat_S
7174
7175 Decl : constant Node_Id :=
7176 Make_Object_Declaration (Loc,
7177 Defining_Identifier => Temp,
7178 Aliased_Present => True,
7179 Object_Definition =>
7180 New_Occurrence_Of (Ptyp, Loc));
7181
7182 begin
7183 Set_Aspect_Specifications (Decl, New_List (
7184 Make_Aspect_Specification (Loc,
7185 Identifier =>
7186 Make_Identifier (Loc, Name_Volatile))));
7187
7188 Insert_Actions (N,
7189 New_List (
7190 Decl,
7191
7192 Make_Assignment_Statement (Loc,
7193 Name =>
7194 Make_Explicit_Dereference (Loc,
7195 Prefix =>
7196 Unchecked_Convert_To (Fat_P,
7197 Make_Attribute_Reference (Loc,
7198 Prefix =>
7199 New_Occurrence_Of (Temp, Loc),
7200 Attribute_Name =>
7201 Name_Unrestricted_Access))),
7202 Expression =>
7203 Unchecked_Convert_To (Fat_S,
7204 Relocate_Node (Pref)))),
7205
7206 Suppress => All_Checks);
7207
7208 Rewrite (Pref, New_Occurrence_Of (Temp, Loc));
7209 end;
7210 end if;
8575023c 7211
88438c0e
AC
7212 -- We now have an object of the proper endianness and
7213 -- alignment, and can construct a Valid attribute.
74014283 7214
88438c0e
AC
7215 -- We make sure the prefix of this valid attribute is
7216 -- marked as not coming from source, to avoid losing
7217 -- warnings from 'Valid looking like a possible update.
74014283 7218
88438c0e 7219 Set_Comes_From_Source (Pref, False);
8575023c 7220
88438c0e
AC
7221 Expand_Fpt_Attribute
7222 (N, Pkg, Name_Valid,
7223 New_List (
7224 Make_Attribute_Reference (Loc,
7225 Prefix => Unchecked_Convert_To (Ftp, Pref),
7226 Attribute_Name => Name_Unrestricted_Access)));
7227 end if;
70482933
RK
7228
7229 -- One more task, we still need a range check. Required
7230 -- only if we have a constraint, since the Valid routine
7231 -- catches infinities properly (infinities are never valid).
7232
7233 -- The way we do the range check is simply to create the
7234 -- expression: Valid (N) and then Base_Type(Pref) in Typ.
7235
382b0e97 7236 if not Subtypes_Statically_Match (Ptyp, PBtyp) then
70482933
RK
7237 Rewrite (N,
7238 Make_And_Then (Loc,
7239 Left_Opnd => Relocate_Node (N),
7240 Right_Opnd =>
7241 Make_In (Loc,
382b0e97 7242 Left_Opnd => Convert_To (PBtyp, Pref),
70482933
RK
7243 Right_Opnd => New_Occurrence_Of (Ptyp, Loc))));
7244 end if;
dfaff97b 7245 end Float_Valid;
70482933
RK
7246
7247 -- Enumeration type with holes
7248
7249 -- For enumeration types with holes, the Pos value constructed by
7250 -- the Enum_Rep_To_Pos function built in Exp_Ch3 called with a
7251 -- second argument of False returns minus one for an invalid value,
7252 -- and the non-negative pos value for a valid value, so the
7253 -- expansion of X'Valid is simply:
7254
7255 -- type(X)'Pos (X) >= 0
7256
7257 -- We can't quite generate it that way because of the requirement
7324bf49
AC
7258 -- for the non-standard second argument of False in the resulting
7259 -- rep_to_pos call, so we have to explicitly create:
70482933
RK
7260
7261 -- _rep_to_pos (X, False) >= 0
7262
7263 -- If we have an enumeration subtype, we also check that the
7264 -- value is in range:
7265
7266 -- _rep_to_pos (X, False) >= 0
7267 -- and then
7324bf49 7268 -- (X >= type(X)'First and then type(X)'Last <= X)
70482933
RK
7269
7270 elsif Is_Enumeration_Type (Ptyp)
382b0e97 7271 and then Present (Enum_Pos_To_Rep (PBtyp))
70482933
RK
7272 then
7273 Tst :=
7274 Make_Op_Ge (Loc,
7275 Left_Opnd =>
7276 Make_Function_Call (Loc,
7277 Name =>
382b0e97 7278 New_Occurrence_Of (TSS (PBtyp, TSS_Rep_To_Pos), Loc),
70482933
RK
7279 Parameter_Associations => New_List (
7280 Pref,
7281 New_Occurrence_Of (Standard_False, Loc))),
7282 Right_Opnd => Make_Integer_Literal (Loc, 0));
7283
3b3bd801
AO
7284 -- Skip the range test for boolean types, as it buys us
7285 -- nothing. The function called above already fails for
7286 -- values different from both True and False.
7287
7288 if Ptyp /= PBtyp and then not Is_Boolean_Type (PBtyp)
70482933 7289 and then
382b0e97 7290 (Type_Low_Bound (Ptyp) /= Type_Low_Bound (PBtyp)
70482933 7291 or else
382b0e97 7292 Type_High_Bound (Ptyp) /= Type_High_Bound (PBtyp))
70482933
RK
7293 then
7294 -- The call to Make_Range_Test will create declarations
7295 -- that need a proper insertion point, but Pref is now
7296 -- attached to a node with no ancestor. Attach to tree
7297 -- even if it is to be rewritten below.
7298
7299 Set_Parent (Tst, Parent (N));
7300
7301 Tst :=
7302 Make_And_Then (Loc,
7303 Left_Opnd => Make_Range_Test,
7304 Right_Opnd => Tst);
7305 end if;
7306
7307 Rewrite (N, Tst);
7308
7309 -- Fortran convention booleans
7310
7311 -- For the very special case of Fortran convention booleans, the
7312 -- value is always valid, since it is an integer with the semantics
7313 -- that non-zero is true, and any value is permissible.
7314
7315 elsif Is_Boolean_Type (Ptyp)
7316 and then Convention (Ptyp) = Convention_Fortran
7317 then
7318 Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
7319
7320 -- For biased representations, we will be doing an unchecked
758c442c
GD
7321 -- conversion without unbiasing the result. That means that the range
7322 -- test has to take this into account, and the proper form of the
7323 -- test is:
70482933 7324
382b0e97 7325 -- PBtyp!(Pref) < PBtyp!(Ptyp'Range_Length)
70482933
RK
7326
7327 elsif Has_Biased_Representation (Ptyp) then
382b0e97 7328 PBtyp := RTE (RE_Unsigned_32);
70482933
RK
7329 Rewrite (N,
7330 Make_Op_Lt (Loc,
7331 Left_Opnd =>
382b0e97 7332 Unchecked_Convert_To (PBtyp, Duplicate_Subexpr (Pref)),
70482933 7333 Right_Opnd =>
382b0e97 7334 Unchecked_Convert_To (PBtyp,
70482933
RK
7335 Make_Attribute_Reference (Loc,
7336 Prefix => New_Occurrence_Of (Ptyp, Loc),
7337 Attribute_Name => Name_Range_Length))));
7338
7339 -- For all other scalar types, what we want logically is a
7340 -- range test:
7341
7342 -- X in type(X)'First .. type(X)'Last
7343
7344 -- But that's precisely what won't work because of possible
7345 -- unwanted optimization (and indeed the basic motivation for
a90bd866 7346 -- the Valid attribute is exactly that this test does not work).
70482933
RK
7347 -- What will work is:
7348
382b0e97 7349 -- PBtyp!(X) >= PBtyp!(type(X)'First)
70482933 7350 -- and then
382b0e97 7351 -- PBtyp!(X) <= PBtyp!(type(X)'Last)
70482933 7352
382b0e97 7353 -- where PBtyp is an integer type large enough to cover the full
70482933
RK
7354 -- range of possible stored values (i.e. it is chosen on the basis
7355 -- of the size of the type, not the range of the values). We write
7356 -- this as two tests, rather than a range check, so that static
7357 -- evaluation will easily remove either or both of the checks if
ce32ccfc 7358 -- they can be statically determined to be true (this happens
70482933
RK
7359 -- when the type of X is static and the range extends to the full
7360 -- range of stored values).
7361
7362 -- Unsigned types. Note: it is safe to consider only whether the
7363 -- subtype is unsigned, since we will in that case be doing all
758c442c
GD
7364 -- unsigned comparisons based on the subtype range. Since we use the
7365 -- actual subtype object size, this is appropriate.
70482933
RK
7366
7367 -- For example, if we have
7368
7369 -- subtype x is integer range 1 .. 200;
7370 -- for x'Object_Size use 8;
7371
758c442c
GD
7372 -- Now the base type is signed, but objects of this type are bits
7373 -- unsigned, and doing an unsigned test of the range 1 to 200 is
7374 -- correct, even though a value greater than 127 looks signed to a
7375 -- signed comparison.
70482933 7376
70482933 7377 else
c7c7dd3a 7378 declare
ce32ccfc
AC
7379 Uns : constant Boolean :=
7380 Is_Unsigned_Type (Ptyp)
7381 or else (Is_Private_Type (Ptyp)
7382 and then Is_Unsigned_Type (Btyp));
7383 Size : Uint;
7384 P : Node_Id := Pref;
7385
c7c7dd3a 7386 begin
76f9c7f4 7387 -- If the prefix is an object, use the Esize from this object
ce32ccfc
AC
7388 -- to handle in a more user friendly way the case of objects
7389 -- or components with a large Size aspect: if a Size aspect is
7390 -- specified, we want to read a scalar value as large as the
7391 -- Size, unless the Size is larger than
7392 -- System_Max_Integer_Size.
7393
7394 if Nkind (P) = N_Selected_Component then
7395 P := Selector_Name (P);
7396 end if;
7397
7398 if Nkind (P) in N_Has_Entity
7399 and then Present (Entity (P))
76f9c7f4 7400 and then Is_Object (Entity (P))
b23cdc01 7401 and then Known_Esize (Entity (P))
ce32ccfc
AC
7402 then
7403 if Esize (Entity (P)) <= System_Max_Integer_Size then
7404 Size := Esize (Entity (P));
7405 else
7406 Size := UI_From_Int (System_Max_Integer_Size);
7407 end if;
7408 else
7409 Size := Esize (Ptyp);
7410 end if;
7411
7412 PBtyp := Small_Integer_Type_For (Size, Uns);
c7c7dd3a
EB
7413 Rewrite (N, Make_Range_Test);
7414 end;
70482933
RK
7415 end if;
7416
3d6db7f8
GD
7417 -- If a predicate is present, then we do the predicate test, even if
7418 -- within the predicate function (infinite recursion is warned about
97948f41 7419 -- in Sem_Attr in that case).
3d6db7f8
GD
7420
7421 declare
7422 Pred_Func : constant Entity_Id := Predicate_Function (Ptyp);
7423
7424 begin
7425 if Present (Pred_Func) then
7426 Rewrite (N,
7427 Make_And_Then (Loc,
7428 Left_Opnd => Relocate_Node (N),
7429 Right_Opnd => Make_Predicate_Call (Ptyp, Pref)));
3d6db7f8
GD
7430 end if;
7431 end;
7432
70482933 7433 Analyze_And_Resolve (N, Standard_Boolean);
fbf5a39b 7434 Validity_Checks_On := Save_Validity_Checks_On;
70482933
RK
7435 end Valid;
7436
336438b6
BD
7437 -----------------
7438 -- Valid_Value --
7439 -----------------
7440
7441 when Attribute_Valid_Value =>
7442 Exp_Imgv.Expand_Valid_Value_Attribute (N);
7443
2a1f6a1f
AC
7444 -------------------
7445 -- Valid_Scalars --
7446 -------------------
7447
7448 when Attribute_Valid_Scalars => Valid_Scalars : declare
7aaf6620 7449 Val_Typ : constant Entity_Id := Validated_View (Ptyp);
a4dafb8b 7450 Expr : Node_Id;
99fc068e 7451
2a1f6a1f 7452 begin
f16cb8df 7453 -- Assume that the prefix does not need validation
99fc068e 7454
f16cb8df 7455 Expr := Empty;
45ec05e1 7456
d57f8e40
PT
7457 -- Attribute 'Valid_Scalars is not supported on private tagged types;
7458 -- see a detailed explanation where this attribute is analyzed.
99fc068e 7459
f16cb8df
HK
7460 if Is_Private_Type (Ptyp) and then Is_Tagged_Type (Ptyp) then
7461 null;
99fc068e 7462
f16cb8df
HK
7463 -- Attribute 'Valid_Scalars evaluates to True when the type lacks
7464 -- scalars.
99fc068e 7465
f16cb8df
HK
7466 elsif not Scalar_Part_Present (Val_Typ) then
7467 null;
99fc068e 7468
f16cb8df
HK
7469 -- Attribute 'Valid_Scalars is the same as attribute 'Valid when the
7470 -- validated type is a scalar type. Generate:
45ec05e1 7471
f16cb8df 7472 -- Val_Typ (Pref)'Valid
45ec05e1 7473
f16cb8df
HK
7474 elsif Is_Scalar_Type (Val_Typ) then
7475 Expr :=
7476 Make_Attribute_Reference (Loc,
7477 Prefix =>
7478 Unchecked_Convert_To (Val_Typ, New_Copy_Tree (Pref)),
7479 Attribute_Name => Name_Valid);
45ec05e1 7480
efd0843d
EB
7481 -- Required by LLVM although the sizes are the same???
7482
7483 if Nkind (Prefix (Expr)) = N_Unchecked_Type_Conversion then
7484 Set_No_Truncation (Prefix (Expr));
7485 end if;
7486
f16cb8df
HK
7487 -- Validate the scalar components of an array by iterating over all
7488 -- dimensions of the array while checking individual components.
45ec05e1 7489
f16cb8df 7490 elsif Is_Array_Type (Val_Typ) then
a4dafb8b
PT
7491 Expr :=
7492 Make_Function_Call (Loc,
7493 Name =>
7494 New_Occurrence_Of
7495 (Build_Array_VS_Func
7496 (Attr => N,
7497 Formal_Typ => Ptyp,
7498 Array_Typ => Val_Typ),
7499 Loc),
7500 Parameter_Associations => New_List (Pref));
99fc068e 7501
f16cb8df
HK
7502 -- Validate the scalar components, discriminants of a record type by
7503 -- examining the structure of a record type.
99fc068e 7504
f16cb8df
HK
7505 elsif Is_Record_Type (Val_Typ) then
7506 Expr :=
7507 Make_Function_Call (Loc,
7508 Name =>
7509 New_Occurrence_Of
7510 (Build_Record_VS_Func
7511 (Attr => N,
7512 Formal_Typ => Ptyp,
7aaf6620 7513 Rec_Typ => Val_Typ),
f16cb8df
HK
7514 Loc),
7515 Parameter_Associations => New_List (Pref));
7516 end if;
99fc068e 7517
f16cb8df
HK
7518 -- Default the attribute to True when the type of the prefix does not
7519 -- need validation.
99fc068e 7520
f16cb8df
HK
7521 if No (Expr) then
7522 Expr := New_Occurrence_Of (Standard_True, Loc);
99fc068e 7523 end if;
45ec05e1 7524
f16cb8df 7525 Rewrite (N, Expr);
45ec05e1
RD
7526 Analyze_And_Resolve (N, Standard_Boolean);
7527 Set_Is_Static_Expression (N, False);
2a1f6a1f
AC
7528 end Valid_Scalars;
7529
70482933
RK
7530 -----------
7531 -- Value --
7532 -----------
7533
70482933
RK
7534 when Attribute_Value =>
7535 Exp_Imgv.Expand_Value_Attribute (N);
7536
7537 -----------------
7538 -- Value_Size --
7539 -----------------
7540
7541 -- The processing for Value_Size shares the processing for Size
7542
7543 -------------
7544 -- Version --
7545 -------------
7546
7547 -- The processing for Version shares the processing for Body_Version
7548
7549 ----------------
7550 -- Wide_Image --
7551 ----------------
7552
470cd9e9 7553 when Attribute_Wide_Image =>
b63d61f7
AC
7554 -- Leave attribute unexpanded in CodePeer mode: the gnat2scil
7555 -- back-end knows how to handle this attribute directly.
7556
7557 if CodePeer_Mode then
7558 return;
7559 end if;
7560
470cd9e9 7561 Exp_Imgv.Expand_Wide_Image_Attribute (N);
70482933 7562
82c80734
RD
7563 ---------------------
7564 -- Wide_Wide_Image --
7565 ---------------------
7566
470cd9e9 7567 when Attribute_Wide_Wide_Image =>
b63d61f7
AC
7568 -- Leave attribute unexpanded in CodePeer mode: the gnat2scil
7569 -- back-end knows how to handle this attribute directly.
7570
7571 if CodePeer_Mode then
7572 return;
7573 end if;
7574
470cd9e9 7575 Exp_Imgv.Expand_Wide_Wide_Image_Attribute (N);
82c80734 7576
70482933
RK
7577 ----------------
7578 -- Wide_Value --
7579 ----------------
7580
7581 -- We expand typ'Wide_Value (X) into
7582
7583 -- typ'Value
7584 -- (Wide_String_To_String (X, Wide_Character_Encoding_Method))
7585
7586 -- Wide_String_To_String is a runtime function that converts its wide
7587 -- string argument to String, converting any non-translatable characters
7588 -- into appropriate escape sequences. This preserves the required
7589 -- semantics of Wide_Value in all cases, and results in a very simple
7590 -- implementation approach.
7591
7ce611e2
ES
7592 -- Note: for this approach to be fully standard compliant for the cases
7593 -- where typ is Wide_Character and Wide_Wide_Character, the encoding
7594 -- method must cover the entire character range (e.g. UTF-8). But that
7595 -- is a reasonable requirement when dealing with encoded character
7596 -- sequences. Presumably if one of the restrictive encoding mechanisms
7597 -- is in use such as Shift-JIS, then characters that cannot be
7598 -- represented using this encoding will not appear in any case.
70482933 7599
d8f43ee6 7600 when Attribute_Wide_Value =>
70482933
RK
7601 Rewrite (N,
7602 Make_Attribute_Reference (Loc,
7603 Prefix => Pref,
7604 Attribute_Name => Name_Value,
7605
7606 Expressions => New_List (
7607 Make_Function_Call (Loc,
7608 Name =>
e4494292 7609 New_Occurrence_Of (RTE (RE_Wide_String_To_String), Loc),
70482933
RK
7610
7611 Parameter_Associations => New_List (
7612 Relocate_Node (First (Exprs)),
7613 Make_Integer_Literal (Loc,
7614 Intval => Int (Wide_Character_Encoding_Method)))))));
7615
7616 Analyze_And_Resolve (N, Typ);
70482933 7617
82c80734
RD
7618 ---------------------
7619 -- Wide_Wide_Value --
7620 ---------------------
7621
7622 -- We expand typ'Wide_Value_Value (X) into
7623
7624 -- typ'Value
7625 -- (Wide_Wide_String_To_String (X, Wide_Character_Encoding_Method))
7626
336438b6
BD
7627 -- See Wide_Value for more information. This is not quite right where
7628 -- typ = Wide_Wide_Character, because the encoding method may not cover
7629 -- the whole character type.
82c80734 7630
d8f43ee6 7631 when Attribute_Wide_Wide_Value =>
82c80734
RD
7632 Rewrite (N,
7633 Make_Attribute_Reference (Loc,
7634 Prefix => Pref,
7635 Attribute_Name => Name_Value,
7636
7637 Expressions => New_List (
7638 Make_Function_Call (Loc,
d8f43ee6 7639 Name =>
e4494292
RD
7640 New_Occurrence_Of
7641 (RTE (RE_Wide_Wide_String_To_String), Loc),
82c80734
RD
7642
7643 Parameter_Associations => New_List (
7644 Relocate_Node (First (Exprs)),
7645 Make_Integer_Literal (Loc,
7646 Intval => Int (Wide_Character_Encoding_Method)))))));
7647
7648 Analyze_And_Resolve (N, Typ);
82c80734
RD
7649
7650 ---------------------
7651 -- Wide_Wide_Width --
7652 ---------------------
7653
82c80734
RD
7654 when Attribute_Wide_Wide_Width =>
7655 Exp_Imgv.Expand_Width_Attribute (N, Wide_Wide);
7656
70482933
RK
7657 ----------------
7658 -- Wide_Width --
7659 ----------------
7660
70482933 7661 when Attribute_Wide_Width =>
82c80734 7662 Exp_Imgv.Expand_Width_Attribute (N, Wide);
70482933
RK
7663
7664 -----------
7665 -- Width --
7666 -----------
7667
70482933 7668 when Attribute_Width =>
82c80734 7669 Exp_Imgv.Expand_Width_Attribute (N, Normal);
70482933
RK
7670
7671 -----------
7672 -- Write --
7673 -----------
7674
7675 when Attribute_Write => Write : declare
7676 P_Type : constant Entity_Id := Entity (Pref);
7677 U_Type : constant Entity_Id := Underlying_Type (P_Type);
7678 Pname : Entity_Id;
7679 Decl : Node_Id;
7680 Prag : Node_Id;
7681 Arg3 : Node_Id;
7682 Wfunc : Node_Id;
7683
7684 begin
7685 -- If no underlying type, we have an error that will be diagnosed
7686 -- elsewhere, so here we just completely ignore the expansion.
7687
7688 if No (U_Type) then
7689 return;
7690 end if;
7691
baa571ab
AC
7692 -- Stream operations can appear in user code even if the restriction
7693 -- No_Streams is active (for example, when instantiating a predefined
7694 -- container). In that case rewrite the attribute as a Raise to
7695 -- prevent any run-time use.
7696
7697 if Restriction_Active (No_Streams) then
7698 Rewrite (N,
7699 Make_Raise_Program_Error (Sloc (N),
b8b2d982 7700 Reason => PE_Stream_Operation_Not_Allowed));
baa571ab
AC
7701 Set_Etype (N, U_Type);
7702 return;
7703 end if;
7704
70482933
RK
7705 -- The simple case, if there is a TSS for Write, just call it
7706
fbf5a39b 7707 Pname := Find_Stream_Subprogram (P_Type, TSS_Stream_Write);
70482933
RK
7708
7709 if Present (Pname) then
7710 null;
7711
7712 else
7713 -- If there is a Stream_Convert pragma, use it, we rewrite
7714
7715 -- sourcetyp'Output (stream, Item)
7716
7717 -- as
7718
7719 -- strmtyp'Output (Stream, strmwrite (acttyp (Item)));
7720
758c442c
GD
7721 -- where strmwrite is the given Write function that converts an
7722 -- argument of type sourcetyp or a type acctyp, from which it is
7723 -- derived to type strmtyp. The conversion to acttyp is required
7724 -- for the derived case.
70482933 7725
1d571f3b 7726 Prag := Get_Stream_Convert_Pragma (P_Type);
70482933
RK
7727
7728 if Present (Prag) then
7729 Arg3 :=
7730 Next (Next (First (Pragma_Argument_Associations (Prag))));
7731 Wfunc := Entity (Expression (Arg3));
7732
7733 Rewrite (N,
7734 Make_Attribute_Reference (Loc,
7735 Prefix => New_Occurrence_Of (Etype (Wfunc), Loc),
7736 Attribute_Name => Name_Output,
7737 Expressions => New_List (
7738 Relocate_Node (First (Exprs)),
7739 Make_Function_Call (Loc,
7740 Name => New_Occurrence_Of (Wfunc, Loc),
7741 Parameter_Associations => New_List (
31104818 7742 OK_Convert_To (Etype (First_Formal (Wfunc)),
70482933
RK
7743 Relocate_Node (Next (First (Exprs)))))))));
7744
7745 Analyze (N);
7746 return;
7747
29f2d76c
SB
7748 -- Limited types
7749
7750 elsif Default_Streaming_Unavailable (U_Type) then
7751 -- Do the same thing here as is done above in the
7752 -- case where a No_Streams restriction is active.
7753
7754 Rewrite (N,
7755 Make_Raise_Program_Error (Sloc (N),
7756 Reason => PE_Stream_Operation_Not_Allowed));
7757 Set_Etype (N, U_Type);
7758 return;
7759
70482933
RK
7760 -- For elementary types, we call the W_xxx routine directly
7761
7762 elsif Is_Elementary_Type (U_Type) then
7763 Rewrite (N, Build_Elementary_Write_Call (N));
7764 Analyze (N);
7765 return;
7766
7767 -- Array type case
7768
7769 elsif Is_Array_Type (U_Type) then
7770 Build_Array_Write_Procedure (N, U_Type, Decl, Pname);
fb632ef5 7771 Compile_Stream_Body_In_Scope (N, Decl, U_Type);
70482933
RK
7772
7773 -- Tagged type case, use the primitive Write function. Note that
7774 -- this will dispatch in the class-wide case which is what we want
7775
7776 elsif Is_Tagged_Type (U_Type) then
fbf5a39b 7777 Pname := Find_Prim_Op (U_Type, TSS_Stream_Write);
70482933
RK
7778
7779 -- All other record type cases, including protected records.
7780 -- The latter only arise for expander generated code for
7781 -- handling shared passive partition access.
7782
7783 else
7784 pragma Assert
7785 (Is_Record_Type (U_Type) or else Is_Protected_Type (U_Type));
7786
5d09245e
AC
7787 -- Ada 2005 (AI-216): Program_Error is raised when executing
7788 -- the default implementation of the Write attribute of an
0669bebe
GB
7789 -- Unchecked_Union type. However, if the 'Write reference is
7790 -- within the generated Output stream procedure, Write outputs
7791 -- the components, and the default values of the discriminant
1f70c47f
AC
7792 -- are streamed by the Output procedure itself. If there are
7793 -- no default values this is also erroneous.
5d09245e 7794
1f70c47f
AC
7795 if Is_Unchecked_Union (Base_Type (U_Type)) then
7796 if (not Is_TSS (Current_Scope, TSS_Stream_Output)
7797 and not Is_TSS (Current_Scope, TSS_Stream_Write))
7798 or else No (Discriminant_Default_Value
7799 (First_Discriminant (U_Type)))
7800 then
7801 Rewrite (N,
7802 Make_Raise_Program_Error (Loc,
7803 Reason => PE_Unchecked_Union_Restriction));
7804 Set_Etype (N, U_Type);
7805 return;
7806 end if;
5d09245e
AC
7807 end if;
7808
8adc8d9b 7809 if Has_Defaulted_Discriminants (U_Type) then
70482933 7810 Build_Mutable_Record_Write_Procedure
96d2756f 7811 (Loc, Full_Base (U_Type), Decl, Pname);
70482933
RK
7812 else
7813 Build_Record_Write_Procedure
96d2756f 7814 (Loc, Full_Base (U_Type), Decl, Pname);
70482933
RK
7815 end if;
7816
7817 Insert_Action (N, Decl);
7818 end if;
7819 end if;
7820
7821 -- If we fall through, Pname is the procedure to be called
7822
110d0820 7823 Rewrite_Attribute_Proc_Call (Pname);
70482933
RK
7824 end Write;
7825
80d4224f
RD
7826 -- The following attributes are handled by the back end (except that
7827 -- static cases have already been evaluated during semantic processing,
7828 -- but in any case the back end should not count on this).
70482933 7829
3874e79d 7830 when Attribute_Code_Address
d8f43ee6
HK
7831 | Attribute_Deref
7832 | Attribute_Null_Parameter
7833 | Attribute_Passed_By_Reference
7834 | Attribute_Pool_Address
d8f43ee6 7835 =>
70482933
RK
7836 null;
7837
70482933
RK
7838 -- The following attributes should not appear at this stage, since they
7839 -- have already been handled by the analyzer (and properly rewritten
90cb252f 7840 -- with corresponding values or entities to represent the right values).
70482933 7841
d8f43ee6
HK
7842 when Attribute_Abort_Signal
7843 | Attribute_Address_Size
3874e79d 7844 | Attribute_Aft
d8f43ee6
HK
7845 | Attribute_Atomic_Always_Lock_Free
7846 | Attribute_Base
3874e79d 7847 | Attribute_Bit_Order
d8f43ee6
HK
7848 | Attribute_Class
7849 | Attribute_Compiler_Version
7850 | Attribute_Default_Bit_Order
7851 | Attribute_Default_Scalar_Storage_Order
3874e79d 7852 | Attribute_Definite
d8f43ee6
HK
7853 | Attribute_Delta
7854 | Attribute_Denorm
7855 | Attribute_Digits
7856 | Attribute_Emax
7857 | Attribute_Enabled
7858 | Attribute_Epsilon
7859 | Attribute_Fast_Math
7860 | Attribute_First_Valid
7861 | Attribute_Has_Access_Values
7862 | Attribute_Has_Discriminants
7863 | Attribute_Has_Tagged_Values
7864 | Attribute_Large
7865 | Attribute_Last_Valid
7866 | Attribute_Library_Level
7867 | Attribute_Lock_Free
7868 | Attribute_Machine_Emax
7869 | Attribute_Machine_Emin
7870 | Attribute_Machine_Mantissa
7871 | Attribute_Machine_Overflows
7872 | Attribute_Machine_Radix
7873 | Attribute_Machine_Rounds
3874e79d 7874 | Attribute_Max_Alignment_For_Allocation
c7c7dd3a 7875 | Attribute_Max_Integer_Size
d8f43ee6
HK
7876 | Attribute_Maximum_Alignment
7877 | Attribute_Model_Emin
7878 | Attribute_Model_Epsilon
7879 | Attribute_Model_Mantissa
7880 | Attribute_Model_Small
7881 | Attribute_Modulus
7882 | Attribute_Partition_ID
7883 | Attribute_Range
7884 | Attribute_Restriction_Set
7885 | Attribute_Safe_Emax
7886 | Attribute_Safe_First
7887 | Attribute_Safe_Large
7888 | Attribute_Safe_Last
7889 | Attribute_Safe_Small
3874e79d 7890 | Attribute_Scalar_Storage_Order
d8f43ee6
HK
7891 | Attribute_Scale
7892 | Attribute_Signed_Zeros
7893 | Attribute_Small
2bf891fa
EB
7894 | Attribute_Small_Denominator
7895 | Attribute_Small_Numerator
d8f43ee6
HK
7896 | Attribute_Storage_Unit
7897 | Attribute_Stub_Type
7898 | Attribute_System_Allocator_Alignment
7899 | Attribute_Target_Name
7900 | Attribute_Type_Class
7901 | Attribute_Type_Key
7902 | Attribute_Unconstrained_Array
7903 | Attribute_Universal_Literal_String
7904 | Attribute_Wchar_T_Size
7905 | Attribute_Word_Size
7906 =>
70482933 7907 raise Program_Error;
70482933
RK
7908 end case;
7909
2eef7403
AC
7910 -- Note: as mentioned earlier, individual sections of the above case
7911 -- statement assume there is no code after the case statement, and are
7912 -- legitimately allowed to execute return statements if they have nothing
7913 -- more to do, so DO NOT add code at this point.
7914
fbf5a39b
AC
7915 exception
7916 when RE_Not_Available =>
7917 return;
70482933
RK
7918 end Expand_N_Attribute_Reference;
7919
aa9b151a
AC
7920 --------------------------------
7921 -- Expand_Pred_Succ_Attribute --
7922 --------------------------------
70482933
RK
7923
7924 -- For typ'Pred (exp), we generate the check
7925
7926 -- [constraint_error when exp = typ'Base'First]
7927
7928 -- Similarly, for typ'Succ (exp), we generate the check
7929
7930 -- [constraint_error when exp = typ'Base'Last]
7931
7932 -- These checks are not generated for modular types, since the proper
7933 -- semantics for Succ and Pred on modular types is to wrap, not raise CE.
c7532b2d
AC
7934 -- We also suppress these checks if we are the right side of an assignment
7935 -- statement or the expression of an object declaration, where the flag
7936 -- Suppress_Assignment_Checks is set for the assignment/declaration.
70482933 7937
aa9b151a 7938 procedure Expand_Pred_Succ_Attribute (N : Node_Id) is
70482933 7939 Loc : constant Source_Ptr := Sloc (N);
c7532b2d 7940 P : constant Node_Id := Parent (N);
70482933
RK
7941 Cnam : Name_Id;
7942
7943 begin
7944 if Attribute_Name (N) = Name_Pred then
7945 Cnam := Name_First;
7946 else
7947 Cnam := Name_Last;
7948 end if;
7949
4a08c95c 7950 if Nkind (P) not in N_Assignment_Statement | N_Object_Declaration
c7532b2d
AC
7951 or else not Suppress_Assignment_Checks (P)
7952 then
7953 Insert_Action (N,
7954 Make_Raise_Constraint_Error (Loc,
7955 Condition =>
7956 Make_Op_Eq (Loc,
7957 Left_Opnd =>
7958 Duplicate_Subexpr_Move_Checks (First (Expressions (N))),
7959 Right_Opnd =>
7960 Make_Attribute_Reference (Loc,
7961 Prefix =>
e4494292 7962 New_Occurrence_Of (Base_Type (Etype (Prefix (N))), Loc),
c7532b2d
AC
7963 Attribute_Name => Cnam)),
7964 Reason => CE_Overflow_Check_Failed));
7965 end if;
aa9b151a 7966 end Expand_Pred_Succ_Attribute;
70482933 7967
d39f6b24
YM
7968 ---------------------------
7969 -- Expand_Size_Attribute --
7970 ---------------------------
7971
7972 procedure Expand_Size_Attribute (N : Node_Id) is
14a16e30
PT
7973 Loc : constant Source_Ptr := Sloc (N);
7974 Typ : constant Entity_Id := Etype (N);
7975 Pref : constant Node_Id := Prefix (N);
7976 Ptyp : constant Entity_Id := Etype (Pref);
7977 Id : constant Attribute_Id := Get_Attribute_Id (Attribute_Name (N));
7978 Siz : Uint;
d39f6b24
YM
7979
7980 begin
7981 -- Case of known RM_Size of a type
7982
14a16e30 7983 if Id in Attribute_Size | Attribute_Value_Size
d39f6b24
YM
7984 and then Is_Entity_Name (Pref)
7985 and then Is_Type (Entity (Pref))
7986 and then Known_Static_RM_Size (Entity (Pref))
7987 then
7988 Siz := RM_Size (Entity (Pref));
7989
7990 -- Case of known Esize of a type
7991
7992 elsif Id = Attribute_Object_Size
7993 and then Is_Entity_Name (Pref)
7994 and then Is_Type (Entity (Pref))
7995 and then Known_Static_Esize (Entity (Pref))
7996 then
7997 Siz := Esize (Entity (Pref));
7998
7999 -- Case of known size of object
8000
8001 elsif Id = Attribute_Size
8002 and then Is_Entity_Name (Pref)
8003 and then Is_Object (Entity (Pref))
d39f6b24
YM
8004 and then Known_Static_Esize (Entity (Pref))
8005 then
8006 Siz := Esize (Entity (Pref));
8007
8008 -- For an array component, we can do Size in the front end if the
8009 -- component_size of the array is set.
8010
8011 elsif Nkind (Pref) = N_Indexed_Component then
8012 Siz := Component_Size (Etype (Prefix (Pref)));
8013
8014 -- For a record component, we can do Size in the front end if there is a
8015 -- component clause, or if the record is packed and the component's size
8016 -- is known at compile time.
8017
8018 elsif Nkind (Pref) = N_Selected_Component then
8019 declare
8020 Rec : constant Entity_Id := Etype (Prefix (Pref));
8021 Comp : constant Entity_Id := Entity (Selector_Name (Pref));
8022
8023 begin
8024 if Present (Component_Clause (Comp)) then
8025 Siz := Esize (Comp);
8026
8027 elsif Is_Packed (Rec) then
8028 Siz := RM_Size (Ptyp);
8029
8030 else
8031 Apply_Universal_Integer_Attribute_Checks (N);
8032 return;
8033 end if;
8034 end;
8035
8036 -- All other cases are handled by the back end
8037
8038 else
d39f6b24
YM
8039 -- If Size is applied to a formal parameter that is of a packed
8040 -- array subtype, then apply Size to the actual subtype.
8041
8042 if Is_Entity_Name (Pref)
8043 and then Is_Formal (Entity (Pref))
bfe5f951 8044 and then Is_Packed_Array (Ptyp)
d39f6b24
YM
8045 then
8046 Rewrite (N,
8047 Make_Attribute_Reference (Loc,
8048 Prefix =>
8049 New_Occurrence_Of (Get_Actual_Subtype (Pref), Loc),
8050 Attribute_Name => Name_Size));
8051 Analyze_And_Resolve (N, Typ);
d39f6b24 8052
37915d02 8053 -- If Size is applied to a dereference of an access to unconstrained
d39f6b24
YM
8054 -- packed array, the back end needs to see its unconstrained nominal
8055 -- type, but also a hint to the actual constrained type.
8056
37915d02 8057 elsif Nkind (Pref) = N_Explicit_Dereference
bfe5f951 8058 and then Is_Packed_Array (Ptyp)
d39f6b24 8059 and then not Is_Constrained (Ptyp)
d39f6b24
YM
8060 then
8061 Set_Actual_Designated_Subtype (Pref, Get_Actual_Subtype (Pref));
37915d02
EB
8062
8063 -- If Size was applied to a slice of a bit-packed array, we rewrite
8064 -- it into the product of Length and Component_Size. We need to do so
8065 -- because bit-packed arrays are represented internally as arrays of
8066 -- System.Unsigned_Types.Packed_Byte for code generation purposes so
8067 -- the size is always rounded up in the back end.
8068
955379e4 8069 elsif Nkind (Pref) = N_Slice and then Is_Bit_Packed_Array (Ptyp) then
37915d02
EB
8070 Rewrite (N,
8071 Make_Op_Multiply (Loc,
8072 Make_Attribute_Reference (Loc,
8073 Prefix => Duplicate_Subexpr (Pref, True),
8074 Attribute_Name => Name_Length),
8075 Make_Attribute_Reference (Loc,
8076 Prefix => Duplicate_Subexpr (Pref, True),
8077 Attribute_Name => Name_Component_Size)));
8078 Analyze_And_Resolve (N, Typ);
d39f6b24
YM
8079 end if;
8080
955379e4
EB
8081 -- Apply the required checks last, after rewriting has taken place
8082
8083 Apply_Universal_Integer_Attribute_Checks (N);
d39f6b24
YM
8084 return;
8085 end if;
8086
8087 -- Common processing for record and array component case
8088
2175b50b 8089 if Present (Siz) and then Siz /= 0 then
d39f6b24
YM
8090 declare
8091 CS : constant Boolean := Comes_From_Source (N);
8092
8093 begin
8094 Rewrite (N, Make_Integer_Literal (Loc, Siz));
8095
8096 -- This integer literal is not a static expression. We do not
8097 -- call Analyze_And_Resolve here, because this would activate
8098 -- the circuit for deciding that a static value was out of range,
8099 -- and we don't want that.
8100
8101 -- So just manually set the type, mark the expression as
8102 -- nonstatic, and then ensure that the result is checked
8103 -- properly if the attribute comes from source (if it was
8104 -- internally generated, we never need a constraint check).
8105
8106 Set_Etype (N, Typ);
8107 Set_Is_Static_Expression (N, False);
8108
8109 if CS then
8110 Apply_Constraint_Check (N, Typ);
8111 end if;
8112 end;
8113 end if;
8114 end Expand_Size_Attribute;
8115
18a2ad5d
AC
8116 -----------------------------
8117 -- Expand_Update_Attribute --
8118 -----------------------------
8119
8120 procedure Expand_Update_Attribute (N : Node_Id) is
8121 procedure Process_Component_Or_Element_Update
8122 (Temp : Entity_Id;
8123 Comp : Node_Id;
8124 Expr : Node_Id;
8125 Typ : Entity_Id);
8126 -- Generate the statements necessary to update a single component or an
8127 -- element of the prefix. The code is inserted before the attribute N.
8128 -- Temp denotes the entity of the anonymous object created to reflect
8129 -- the changes in values. Comp is the component/index expression to be
8130 -- updated. Expr is an expression yielding the new value of Comp. Typ
8131 -- is the type of the prefix of attribute Update.
8132
8133 procedure Process_Range_Update
8134 (Temp : Entity_Id;
8135 Comp : Node_Id;
d12b19fa
AC
8136 Expr : Node_Id;
8137 Typ : Entity_Id);
18a2ad5d
AC
8138 -- Generate the statements necessary to update a slice of the prefix.
8139 -- The code is inserted before the attribute N. Temp denotes the entity
8140 -- of the anonymous object created to reflect the changes in values.
8141 -- Comp is range of the slice to be updated. Expr is an expression
d12b19fa
AC
8142 -- yielding the new value of Comp. Typ is the type of the prefix of
8143 -- attribute Update.
18a2ad5d
AC
8144
8145 -----------------------------------------
8146 -- Process_Component_Or_Element_Update --
8147 -----------------------------------------
8148
8149 procedure Process_Component_Or_Element_Update
8150 (Temp : Entity_Id;
8151 Comp : Node_Id;
8152 Expr : Node_Id;
8153 Typ : Entity_Id)
8154 is
8155 Loc : constant Source_Ptr := Sloc (Comp);
8156 Exprs : List_Id;
8157 LHS : Node_Id;
8158
8159 begin
8160 -- An array element may be modified by the following relations
8161 -- depending on the number of dimensions:
8162
8163 -- 1 => Expr -- one dimensional update
8164 -- (1, ..., N) => Expr -- multi dimensional update
8165
8166 -- The above forms are converted in assignment statements where the
8167 -- left hand side is an indexed component:
8168
8169 -- Temp (1) := Expr; -- one dimensional update
8170 -- Temp (1, ..., N) := Expr; -- multi dimensional update
8171
8172 if Is_Array_Type (Typ) then
8173
8174 -- The index expressions of a multi dimensional array update
8175 -- appear as an aggregate.
8176
8177 if Nkind (Comp) = N_Aggregate then
8178 Exprs := New_Copy_List_Tree (Expressions (Comp));
8179 else
8180 Exprs := New_List (Relocate_Node (Comp));
8181 end if;
8182
8183 LHS :=
8184 Make_Indexed_Component (Loc,
e4494292 8185 Prefix => New_Occurrence_Of (Temp, Loc),
18a2ad5d
AC
8186 Expressions => Exprs);
8187
8188 -- A record component update appears in the following form:
8189
8190 -- Comp => Expr
8191
8192 -- The above relation is transformed into an assignment statement
8193 -- where the left hand side is a selected component:
8194
8195 -- Temp.Comp := Expr;
8196
8197 else pragma Assert (Is_Record_Type (Typ));
8198 LHS :=
8199 Make_Selected_Component (Loc,
e4494292 8200 Prefix => New_Occurrence_Of (Temp, Loc),
18a2ad5d
AC
8201 Selector_Name => Relocate_Node (Comp));
8202 end if;
8203
8204 Insert_Action (N,
8205 Make_Assignment_Statement (Loc,
8206 Name => LHS,
8207 Expression => Relocate_Node (Expr)));
8208 end Process_Component_Or_Element_Update;
8209
8210 --------------------------
8211 -- Process_Range_Update --
8212 --------------------------
8213
8214 procedure Process_Range_Update
8215 (Temp : Entity_Id;
8216 Comp : Node_Id;
d12b19fa
AC
8217 Expr : Node_Id;
8218 Typ : Entity_Id)
18a2ad5d 8219 is
d12b19fa
AC
8220 Index_Typ : constant Entity_Id := Etype (First_Index (Typ));
8221 Loc : constant Source_Ptr := Sloc (Comp);
8222 Index : Entity_Id;
18a2ad5d
AC
8223
8224 begin
8225 -- A range update appears as
8226
8227 -- (Low .. High => Expr)
8228
8229 -- The above construct is transformed into a loop that iterates over
8230 -- the given range and modifies the corresponding array values to the
8231 -- value of Expr:
8232
8233 -- for Index in Low .. High loop
d12b19fa 8234 -- Temp (<Index_Typ> (Index)) := Expr;
18a2ad5d
AC
8235 -- end loop;
8236
8237 Index := Make_Temporary (Loc, 'I');
8238
8239 Insert_Action (N,
8240 Make_Loop_Statement (Loc,
8241 Iteration_Scheme =>
8242 Make_Iteration_Scheme (Loc,
8243 Loop_Parameter_Specification =>
8244 Make_Loop_Parameter_Specification (Loc,
8245 Defining_Identifier => Index,
8246 Discrete_Subtype_Definition => Relocate_Node (Comp))),
8247
8248 Statements => New_List (
8249 Make_Assignment_Statement (Loc,
8250 Name =>
8251 Make_Indexed_Component (Loc,
e4494292 8252 Prefix => New_Occurrence_Of (Temp, Loc),
d12b19fa 8253 Expressions => New_List (
e4494292
RD
8254 Convert_To (Index_Typ,
8255 New_Occurrence_Of (Index, Loc)))),
18a2ad5d
AC
8256 Expression => Relocate_Node (Expr))),
8257
8258 End_Label => Empty));
8259 end Process_Range_Update;
8260
8261 -- Local variables
8262
6c802906
AC
8263 Aggr : constant Node_Id := First (Expressions (N));
8264 Loc : constant Source_Ptr := Sloc (N);
8265 Pref : constant Node_Id := Prefix (N);
8266 Typ : constant Entity_Id := Etype (Pref);
8267 Assoc : Node_Id;
8268 Comp : Node_Id;
8269 CW_Temp : Entity_Id;
8270 CW_Typ : Entity_Id;
8271 Expr : Node_Id;
8272 Temp : Entity_Id;
18a2ad5d
AC
8273
8274 -- Start of processing for Expand_Update_Attribute
8275
8276 begin
6c802906
AC
8277 -- Create the anonymous object to store the value of the prefix and
8278 -- capture subsequent changes in value.
8279
8280 Temp := Make_Temporary (Loc, 'T', Pref);
18a2ad5d 8281
6c802906
AC
8282 -- Preserve the tag of the prefix by offering a specific view of the
8283 -- class-wide version of the prefix.
18a2ad5d 8284
6c802906 8285 if Is_Tagged_Type (Typ) then
18a2ad5d 8286
6c802906
AC
8287 -- Generate:
8288 -- CW_Temp : Typ'Class := Typ'Class (Pref);
8289
8290 CW_Temp := Make_Temporary (Loc, 'T');
8291 CW_Typ := Class_Wide_Type (Typ);
8292
8293 Insert_Action (N,
8294 Make_Object_Declaration (Loc,
8295 Defining_Identifier => CW_Temp,
8296 Object_Definition => New_Occurrence_Of (CW_Typ, Loc),
8297 Expression =>
8298 Convert_To (CW_Typ, Relocate_Node (Pref))));
8299
8300 -- Generate:
8301 -- Temp : Typ renames Typ (CW_Temp);
8302
8303 Insert_Action (N,
8304 Make_Object_Renaming_Declaration (Loc,
8305 Defining_Identifier => Temp,
8306 Subtype_Mark => New_Occurrence_Of (Typ, Loc),
8307 Name =>
8308 Convert_To (Typ, New_Occurrence_Of (CW_Temp, Loc))));
8309
8310 -- Non-tagged case
8311
8312 else
8313 -- Generate:
8314 -- Temp : Typ := Pref;
8315
8316 Insert_Action (N,
8317 Make_Object_Declaration (Loc,
8318 Defining_Identifier => Temp,
8319 Object_Definition => New_Occurrence_Of (Typ, Loc),
8320 Expression => Relocate_Node (Pref)));
8321 end if;
18a2ad5d
AC
8322
8323 -- Process the update aggregate
8324
8325 Assoc := First (Component_Associations (Aggr));
8326 while Present (Assoc) loop
8327 Comp := First (Choices (Assoc));
8328 Expr := Expression (Assoc);
8329 while Present (Comp) loop
8330 if Nkind (Comp) = N_Range then
d12b19fa 8331 Process_Range_Update (Temp, Comp, Expr, Typ);
3b01ce30
PT
8332 elsif Nkind (Comp) = N_Subtype_Indication then
8333 Process_Range_Update
8334 (Temp, Range_Expression (Constraint (Comp)), Expr, Typ);
18a2ad5d
AC
8335 else
8336 Process_Component_Or_Element_Update (Temp, Comp, Expr, Typ);
8337 end if;
8338
8339 Next (Comp);
8340 end loop;
8341
8342 Next (Assoc);
8343 end loop;
8344
8345 -- The attribute is replaced by a reference to the anonymous object
8346
e4494292 8347 Rewrite (N, New_Occurrence_Of (Temp, Loc));
18a2ad5d
AC
8348 Analyze (N);
8349 end Expand_Update_Attribute;
8350
65f01153
RD
8351 -------------------
8352 -- Find_Fat_Info --
8353 -------------------
8354
8355 procedure Find_Fat_Info
8356 (T : Entity_Id;
8357 Fat_Type : out Entity_Id;
8358 Fat_Pkg : out RE_Id)
8359 is
65f01153 8360 Rtyp : constant Entity_Id := Root_Type (T);
65f01153
RD
8361
8362 begin
80211802
AC
8363 -- All we do is use the root type (historically this dealt with
8364 -- VAX-float .. to be cleaned up further later ???)
65f01153 8365
338e5133
EB
8366 if Rtyp = Standard_Short_Float or else Rtyp = Standard_Float then
8367 Fat_Type := Standard_Float;
8368 Fat_Pkg := RE_Attr_Float;
65f01153 8369
338e5133
EB
8370 elsif Rtyp = Standard_Long_Float then
8371 Fat_Type := Standard_Long_Float;
8372 Fat_Pkg := RE_Attr_Long_Float;
65f01153 8373
338e5133
EB
8374 elsif Rtyp = Standard_Long_Long_Float then
8375 Fat_Type := Standard_Long_Long_Float;
8376 Fat_Pkg := RE_Attr_Long_Long_Float;
7ce611e2
ES
8377
8378 -- Universal real (which is its own root type) is treated as being
8379 -- equivalent to Standard.Long_Long_Float, since it is defined to
8380 -- have the same precision as the longest Float type.
8381
338e5133 8382 elsif Rtyp = Universal_Real then
80211802 8383 Fat_Type := Standard_Long_Long_Float;
338e5133 8384 Fat_Pkg := RE_Attr_Long_Long_Float;
7ce611e2 8385
80211802
AC
8386 else
8387 raise Program_Error;
65f01153
RD
8388 end if;
8389 end Find_Fat_Info;
8390
fbf5a39b
AC
8391 ----------------------------
8392 -- Find_Stream_Subprogram --
8393 ----------------------------
8394
8395 function Find_Stream_Subprogram
8396 (Typ : Entity_Id;
758c442c
GD
8397 Nam : TSS_Name_Type) return Entity_Id
8398 is
b2c6b35f
HK
8399 Base_Typ : constant Entity_Id := Base_Type (Typ);
8400 Ent : constant Entity_Id := TSS (Typ, Nam);
fbf5a39b 8401 begin
758c442c
GD
8402 if Present (Ent) then
8403 return Ent;
8404 end if;
8405
21d27997
RD
8406 -- Stream attributes for strings are expanded into library calls. The
8407 -- following checks are disabled when the run-time is not available or
8408 -- when compiling predefined types due to bootstrap issues. As a result,
8409 -- the compiler will generate in-place stream routines for string types
8410 -- that appear in GNAT's library, but will generate calls via rtsfind
8411 -- to library routines for user code.
f4b049db 8412
a20f4389 8413 -- Note: In the case of using a configurable run time, it is very likely
90878b12
AC
8414 -- that stream routines for string types are not present (they require
8415 -- file system support). In this case, the specific stream routines for
8416 -- strings are not used, relying on the regular stream mechanism
6c9e4a1d 8417 -- instead. That is why we include the test RTE_Available when dealing
a20f4389 8418 -- with these cases.
90878b12 8419
8ab31c0c 8420 if not Is_Predefined_Unit (Current_Sem_Unit) then
161c5cc5
AC
8421 -- Storage_Array as defined in package System.Storage_Elements
8422
8423 if Is_RTE (Base_Typ, RE_Storage_Array) then
8424
8425 -- Case of No_Stream_Optimizations restriction active
8426
8427 if Restriction_Active (No_Stream_Optimizations) then
8428 if Nam = TSS_Stream_Input
6c9e4a1d 8429 and then RTE_Available (RE_Storage_Array_Input)
161c5cc5
AC
8430 then
8431 return RTE (RE_Storage_Array_Input);
8432
8433 elsif Nam = TSS_Stream_Output
6c9e4a1d 8434 and then RTE_Available (RE_Storage_Array_Output)
161c5cc5
AC
8435 then
8436 return RTE (RE_Storage_Array_Output);
8437
8438 elsif Nam = TSS_Stream_Read
6c9e4a1d 8439 and then RTE_Available (RE_Storage_Array_Read)
161c5cc5
AC
8440 then
8441 return RTE (RE_Storage_Array_Read);
8442
8443 elsif Nam = TSS_Stream_Write
6c9e4a1d 8444 and then RTE_Available (RE_Storage_Array_Write)
161c5cc5
AC
8445 then
8446 return RTE (RE_Storage_Array_Write);
8447
8448 elsif Nam /= TSS_Stream_Input and then
8449 Nam /= TSS_Stream_Output and then
8450 Nam /= TSS_Stream_Read and then
8451 Nam /= TSS_Stream_Write
8452 then
8453 raise Program_Error;
8454 end if;
8455
8456 -- Restriction No_Stream_Optimizations is not set, so we can go
8457 -- ahead and optimize using the block IO forms of the routines.
8458
8459 else
8460 if Nam = TSS_Stream_Input
6c9e4a1d 8461 and then RTE_Available (RE_Storage_Array_Input_Blk_IO)
161c5cc5
AC
8462 then
8463 return RTE (RE_Storage_Array_Input_Blk_IO);
8464
8465 elsif Nam = TSS_Stream_Output
6c9e4a1d 8466 and then RTE_Available (RE_Storage_Array_Output_Blk_IO)
161c5cc5
AC
8467 then
8468 return RTE (RE_Storage_Array_Output_Blk_IO);
8469
8470 elsif Nam = TSS_Stream_Read
6c9e4a1d 8471 and then RTE_Available (RE_Storage_Array_Read_Blk_IO)
161c5cc5
AC
8472 then
8473 return RTE (RE_Storage_Array_Read_Blk_IO);
8474
8475 elsif Nam = TSS_Stream_Write
6c9e4a1d 8476 and then RTE_Available (RE_Storage_Array_Write_Blk_IO)
161c5cc5
AC
8477 then
8478 return RTE (RE_Storage_Array_Write_Blk_IO);
8479
8480 elsif Nam /= TSS_Stream_Input and then
8481 Nam /= TSS_Stream_Output and then
8482 Nam /= TSS_Stream_Read and then
8483 Nam /= TSS_Stream_Write
8484 then
8485 raise Program_Error;
8486 end if;
8487 end if;
8488
8489 -- Stream_Element_Array as defined in package Ada.Streams
8490
8491 elsif Is_RTE (Base_Typ, RE_Stream_Element_Array) then
8492
8493 -- Case of No_Stream_Optimizations restriction active
8494
8495 if Restriction_Active (No_Stream_Optimizations) then
8496 if Nam = TSS_Stream_Input
6c9e4a1d 8497 and then RTE_Available (RE_Stream_Element_Array_Input)
161c5cc5
AC
8498 then
8499 return RTE (RE_Stream_Element_Array_Input);
8500
8501 elsif Nam = TSS_Stream_Output
6c9e4a1d 8502 and then RTE_Available (RE_Stream_Element_Array_Output)
161c5cc5
AC
8503 then
8504 return RTE (RE_Stream_Element_Array_Output);
8505
8506 elsif Nam = TSS_Stream_Read
6c9e4a1d 8507 and then RTE_Available (RE_Stream_Element_Array_Read)
161c5cc5
AC
8508 then
8509 return RTE (RE_Stream_Element_Array_Read);
8510
8511 elsif Nam = TSS_Stream_Write
6c9e4a1d 8512 and then RTE_Available (RE_Stream_Element_Array_Write)
161c5cc5
AC
8513 then
8514 return RTE (RE_Stream_Element_Array_Write);
8515
8516 elsif Nam /= TSS_Stream_Input and then
8517 Nam /= TSS_Stream_Output and then
8518 Nam /= TSS_Stream_Read and then
8519 Nam /= TSS_Stream_Write
8520 then
8521 raise Program_Error;
8522 end if;
8523
8524 -- Restriction No_Stream_Optimizations is not set, so we can go
8525 -- ahead and optimize using the block IO forms of the routines.
8526
8527 else
8528 if Nam = TSS_Stream_Input
6c9e4a1d 8529 and then RTE_Available (RE_Stream_Element_Array_Input_Blk_IO)
161c5cc5
AC
8530 then
8531 return RTE (RE_Stream_Element_Array_Input_Blk_IO);
8532
8533 elsif Nam = TSS_Stream_Output
6c9e4a1d 8534 and then RTE_Available (RE_Stream_Element_Array_Output_Blk_IO)
161c5cc5
AC
8535 then
8536 return RTE (RE_Stream_Element_Array_Output_Blk_IO);
8537
8538 elsif Nam = TSS_Stream_Read
6c9e4a1d 8539 and then RTE_Available (RE_Stream_Element_Array_Read_Blk_IO)
161c5cc5
AC
8540 then
8541 return RTE (RE_Stream_Element_Array_Read_Blk_IO);
8542
8543 elsif Nam = TSS_Stream_Write
6c9e4a1d 8544 and then RTE_Available (RE_Stream_Element_Array_Write_Blk_IO)
161c5cc5
AC
8545 then
8546 return RTE (RE_Stream_Element_Array_Write_Blk_IO);
8547
8548 elsif Nam /= TSS_Stream_Input and then
8549 Nam /= TSS_Stream_Output and then
8550 Nam /= TSS_Stream_Read and then
8551 Nam /= TSS_Stream_Write
8552 then
8553 raise Program_Error;
8554 end if;
8555 end if;
8556
21d27997
RD
8557 -- String as defined in package Ada
8558
161c5cc5
AC
8559 elsif Base_Typ = Standard_String then
8560
8561 -- Case of No_Stream_Optimizations restriction active
8562
585df50b 8563 if Restriction_Active (No_Stream_Optimizations) then
90878b12 8564 if Nam = TSS_Stream_Input
6c9e4a1d 8565 and then RTE_Available (RE_String_Input)
90878b12 8566 then
585df50b
AC
8567 return RTE (RE_String_Input);
8568
90878b12 8569 elsif Nam = TSS_Stream_Output
6c9e4a1d 8570 and then RTE_Available (RE_String_Output)
90878b12 8571 then
585df50b
AC
8572 return RTE (RE_String_Output);
8573
90878b12 8574 elsif Nam = TSS_Stream_Read
6c9e4a1d 8575 and then RTE_Available (RE_String_Read)
90878b12 8576 then
585df50b 8577 return RTE (RE_String_Read);
21d27997 8578
90878b12 8579 elsif Nam = TSS_Stream_Write
6c9e4a1d 8580 and then RTE_Available (RE_String_Write)
90878b12 8581 then
585df50b 8582 return RTE (RE_String_Write);
90878b12
AC
8583
8584 elsif Nam /= TSS_Stream_Input and then
8585 Nam /= TSS_Stream_Output and then
8586 Nam /= TSS_Stream_Read and then
8587 Nam /= TSS_Stream_Write
8588 then
8589 raise Program_Error;
585df50b
AC
8590 end if;
8591
161c5cc5
AC
8592 -- Restriction No_Stream_Optimizations is not set, so we can go
8593 -- ahead and optimize using the block IO forms of the routines.
8594
585df50b 8595 else
90878b12 8596 if Nam = TSS_Stream_Input
6c9e4a1d 8597 and then RTE_Available (RE_String_Input_Blk_IO)
90878b12 8598 then
585df50b 8599 return RTE (RE_String_Input_Blk_IO);
21d27997 8600
90878b12 8601 elsif Nam = TSS_Stream_Output
6c9e4a1d 8602 and then RTE_Available (RE_String_Output_Blk_IO)
90878b12 8603 then
585df50b 8604 return RTE (RE_String_Output_Blk_IO);
21d27997 8605
90878b12 8606 elsif Nam = TSS_Stream_Read
6c9e4a1d 8607 and then RTE_Available (RE_String_Read_Blk_IO)
90878b12 8608 then
585df50b
AC
8609 return RTE (RE_String_Read_Blk_IO);
8610
90878b12 8611 elsif Nam = TSS_Stream_Write
6c9e4a1d 8612 and then RTE_Available (RE_String_Write_Blk_IO)
90878b12 8613 then
585df50b 8614 return RTE (RE_String_Write_Blk_IO);
90878b12 8615
161c5cc5 8616 elsif Nam /= TSS_Stream_Input and then
90878b12 8617 Nam /= TSS_Stream_Output and then
161c5cc5 8618 Nam /= TSS_Stream_Read and then
90878b12
AC
8619 Nam /= TSS_Stream_Write
8620 then
8621 raise Program_Error;
585df50b 8622 end if;
21d27997
RD
8623 end if;
8624
8625 -- Wide_String as defined in package Ada
8626
b2c6b35f 8627 elsif Base_Typ = Standard_Wide_String then
161c5cc5
AC
8628
8629 -- Case of No_Stream_Optimizations restriction active
8630
585df50b 8631 if Restriction_Active (No_Stream_Optimizations) then
90878b12 8632 if Nam = TSS_Stream_Input
6c9e4a1d 8633 and then RTE_Available (RE_Wide_String_Input)
90878b12 8634 then
585df50b
AC
8635 return RTE (RE_Wide_String_Input);
8636
90878b12 8637 elsif Nam = TSS_Stream_Output
6c9e4a1d 8638 and then RTE_Available (RE_Wide_String_Output)
90878b12 8639 then
585df50b
AC
8640 return RTE (RE_Wide_String_Output);
8641
90878b12 8642 elsif Nam = TSS_Stream_Read
6c9e4a1d 8643 and then RTE_Available (RE_Wide_String_Read)
90878b12 8644 then
585df50b
AC
8645 return RTE (RE_Wide_String_Read);
8646
90878b12 8647 elsif Nam = TSS_Stream_Write
6c9e4a1d 8648 and then RTE_Available (RE_Wide_String_Write)
90878b12 8649 then
585df50b 8650 return RTE (RE_Wide_String_Write);
90878b12 8651
161c5cc5 8652 elsif Nam /= TSS_Stream_Input and then
90878b12 8653 Nam /= TSS_Stream_Output and then
161c5cc5 8654 Nam /= TSS_Stream_Read and then
90878b12
AC
8655 Nam /= TSS_Stream_Write
8656 then
8657 raise Program_Error;
585df50b
AC
8658 end if;
8659
161c5cc5
AC
8660 -- Restriction No_Stream_Optimizations is not set, so we can go
8661 -- ahead and optimize using the block IO forms of the routines.
8662
585df50b 8663 else
90878b12 8664 if Nam = TSS_Stream_Input
6c9e4a1d 8665 and then RTE_Available (RE_Wide_String_Input_Blk_IO)
90878b12 8666 then
585df50b 8667 return RTE (RE_Wide_String_Input_Blk_IO);
21d27997 8668
90878b12 8669 elsif Nam = TSS_Stream_Output
6c9e4a1d 8670 and then RTE_Available (RE_Wide_String_Output_Blk_IO)
90878b12 8671 then
585df50b 8672 return RTE (RE_Wide_String_Output_Blk_IO);
21d27997 8673
90878b12 8674 elsif Nam = TSS_Stream_Read
6c9e4a1d 8675 and then RTE_Available (RE_Wide_String_Read_Blk_IO)
90878b12 8676 then
585df50b 8677 return RTE (RE_Wide_String_Read_Blk_IO);
21d27997 8678
90878b12 8679 elsif Nam = TSS_Stream_Write
6c9e4a1d 8680 and then RTE_Available (RE_Wide_String_Write_Blk_IO)
90878b12 8681 then
585df50b 8682 return RTE (RE_Wide_String_Write_Blk_IO);
90878b12 8683
161c5cc5 8684 elsif Nam /= TSS_Stream_Input and then
90878b12 8685 Nam /= TSS_Stream_Output and then
161c5cc5 8686 Nam /= TSS_Stream_Read and then
90878b12
AC
8687 Nam /= TSS_Stream_Write
8688 then
8689 raise Program_Error;
585df50b 8690 end if;
21d27997
RD
8691 end if;
8692
8693 -- Wide_Wide_String as defined in package Ada
8694
b2c6b35f 8695 elsif Base_Typ = Standard_Wide_Wide_String then
161c5cc5
AC
8696
8697 -- Case of No_Stream_Optimizations restriction active
8698
585df50b 8699 if Restriction_Active (No_Stream_Optimizations) then
90878b12 8700 if Nam = TSS_Stream_Input
6c9e4a1d 8701 and then RTE_Available (RE_Wide_Wide_String_Input)
90878b12 8702 then
585df50b
AC
8703 return RTE (RE_Wide_Wide_String_Input);
8704
90878b12 8705 elsif Nam = TSS_Stream_Output
6c9e4a1d 8706 and then RTE_Available (RE_Wide_Wide_String_Output)
90878b12 8707 then
585df50b 8708 return RTE (RE_Wide_Wide_String_Output);
21d27997 8709
90878b12 8710 elsif Nam = TSS_Stream_Read
6c9e4a1d 8711 and then RTE_Available (RE_Wide_Wide_String_Read)
90878b12 8712 then
585df50b 8713 return RTE (RE_Wide_Wide_String_Read);
21d27997 8714
90878b12 8715 elsif Nam = TSS_Stream_Write
6c9e4a1d 8716 and then RTE_Available (RE_Wide_Wide_String_Write)
90878b12 8717 then
585df50b 8718 return RTE (RE_Wide_Wide_String_Write);
90878b12 8719
161c5cc5 8720 elsif Nam /= TSS_Stream_Input and then
90878b12 8721 Nam /= TSS_Stream_Output and then
161c5cc5 8722 Nam /= TSS_Stream_Read and then
90878b12
AC
8723 Nam /= TSS_Stream_Write
8724 then
8725 raise Program_Error;
585df50b 8726 end if;
21d27997 8727
161c5cc5
AC
8728 -- Restriction No_Stream_Optimizations is not set, so we can go
8729 -- ahead and optimize using the block IO forms of the routines.
8730
585df50b 8731 else
90878b12 8732 if Nam = TSS_Stream_Input
6c9e4a1d 8733 and then RTE_Available (RE_Wide_Wide_String_Input_Blk_IO)
90878b12 8734 then
585df50b
AC
8735 return RTE (RE_Wide_Wide_String_Input_Blk_IO);
8736
90878b12 8737 elsif Nam = TSS_Stream_Output
6c9e4a1d 8738 and then RTE_Available (RE_Wide_Wide_String_Output_Blk_IO)
90878b12 8739 then
585df50b
AC
8740 return RTE (RE_Wide_Wide_String_Output_Blk_IO);
8741
90878b12 8742 elsif Nam = TSS_Stream_Read
6c9e4a1d 8743 and then RTE_Available (RE_Wide_Wide_String_Read_Blk_IO)
90878b12 8744 then
585df50b
AC
8745 return RTE (RE_Wide_Wide_String_Read_Blk_IO);
8746
90878b12 8747 elsif Nam = TSS_Stream_Write
6c9e4a1d 8748 and then RTE_Available (RE_Wide_Wide_String_Write_Blk_IO)
90878b12 8749 then
585df50b 8750 return RTE (RE_Wide_Wide_String_Write_Blk_IO);
90878b12 8751
161c5cc5 8752 elsif Nam /= TSS_Stream_Input and then
90878b12 8753 Nam /= TSS_Stream_Output and then
161c5cc5 8754 Nam /= TSS_Stream_Read and then
90878b12
AC
8755 Nam /= TSS_Stream_Write
8756 then
8757 raise Program_Error;
585df50b 8758 end if;
21d27997
RD
8759 end if;
8760 end if;
8761 end if;
8762
161c5cc5 8763 if Is_Tagged_Type (Typ) and then Is_Derived_Type (Typ) then
fbf5a39b
AC
8764 return Find_Prim_Op (Typ, Nam);
8765 else
8766 return Find_Inherited_TSS (Typ, Nam);
8767 end if;
8768 end Find_Stream_Subprogram;
8769
96d2756f
AC
8770 ---------------
8771 -- Full_Base --
8772 ---------------
8773
8774 function Full_Base (T : Entity_Id) return Entity_Id is
8775 BT : Entity_Id;
8776
8777 begin
8778 BT := Base_Type (T);
8779
8780 if Is_Private_Type (BT)
8781 and then Present (Full_View (BT))
8782 then
8783 BT := Full_View (BT);
8784 end if;
8785
8786 return BT;
8787 end Full_Base;
8788
1d571f3b
AC
8789 -------------------------------
8790 -- Get_Stream_Convert_Pragma --
8791 -------------------------------
8792
8793 function Get_Stream_Convert_Pragma (T : Entity_Id) return Node_Id is
8794 Typ : Entity_Id;
8795 N : Node_Id;
8796
8797 begin
8798 -- Note: we cannot use Get_Rep_Pragma here because of the peculiarity
8799 -- that a stream convert pragma for a tagged type is not inherited from
8800 -- its parent. Probably what is wrong here is that it is basically
8801 -- incorrect to consider a stream convert pragma to be a representation
8802 -- pragma at all ???
8803
8804 N := First_Rep_Item (Implementation_Base_Type (T));
8805 while Present (N) loop
e10dab7f 8806 if Nkind (N) = N_Pragma
6e759c2a 8807 and then Pragma_Name (N) = Name_Stream_Convert
e10dab7f 8808 then
1d571f3b
AC
8809 -- For tagged types this pragma is not inherited, so we
8810 -- must verify that it is defined for the given type and
8811 -- not an ancestor.
8812
8813 Typ :=
8814 Entity (Expression (First (Pragma_Argument_Associations (N))));
8815
8816 if not Is_Tagged_Type (T)
8817 or else T = Typ
8818 or else (Is_Private_Type (Typ) and then T = Full_View (Typ))
8819 then
8820 return N;
8821 end if;
8822 end if;
8823
8824 Next_Rep_Item (N);
8825 end loop;
8826
8827 return Empty;
8828 end Get_Stream_Convert_Pragma;
8829
70482933
RK
8830 ---------------------------------
8831 -- Is_Constrained_Packed_Array --
8832 ---------------------------------
8833
8834 function Is_Constrained_Packed_Array (Typ : Entity_Id) return Boolean is
8835 Arr : Entity_Id := Typ;
8836
8837 begin
8838 if Is_Access_Type (Arr) then
8839 Arr := Designated_Type (Arr);
8840 end if;
8841
8842 return Is_Array_Type (Arr)
8843 and then Is_Constrained (Arr)
8ca597af 8844 and then Present (Packed_Array_Impl_Type (Arr));
70482933
RK
8845 end Is_Constrained_Packed_Array;
8846
0669bebe
GB
8847 ----------------------------------------
8848 -- Is_Inline_Floating_Point_Attribute --
8849 ----------------------------------------
8850
8851 function Is_Inline_Floating_Point_Attribute (N : Node_Id) return Boolean is
8852 Id : constant Attribute_Id := Get_Attribute_Id (Attribute_Name (N));
8853
d18bbd25
AC
8854 function Is_GCC_Target return Boolean;
8855 -- Return True if we are using a GCC target/back-end
8856 -- ??? Note: the implementation is kludgy/fragile
8857
8858 -------------------
8859 -- Is_GCC_Target --
8860 -------------------
8861
8862 function Is_GCC_Target return Boolean is
8863 begin
9a476d75 8864 return not CodePeer_Mode
c63a2ad6 8865 and then not Modify_Tree_For_C;
d18bbd25
AC
8866 end Is_GCC_Target;
8867
b943a971 8868 -- Start of processing for Is_Inline_Floating_Point_Attribute
d18bbd25 8869
0669bebe 8870 begin
56af8688 8871 -- Machine and Model can be expanded by the GCC back end only
78433fec 8872
24228312 8873 if Id = Attribute_Machine or else Id = Attribute_Model then
f8f50235 8874 return Is_GCC_Target;
78433fec 8875
d18bbd25 8876 -- Remaining cases handled by all back ends are Rounding and Truncation
78433fec 8877 -- when appearing as the operand of a conversion to some integer type.
24228312
AC
8878
8879 elsif Nkind (Parent (N)) /= N_Type_Conversion
0669bebe
GB
8880 or else not Is_Integer_Type (Etype (Parent (N)))
8881 then
8882 return False;
8883 end if;
8884
d8ec2787
EB
8885 -- Here we are in the integer conversion context. We reuse Rounding for
8886 -- Machine_Rounding as System.Fat_Gen, which is a permissible behavior.
78433fec 8887
d8ec2787
EB
8888 return
8889 Id = Attribute_Rounding
8890 or else Id = Attribute_Machine_Rounding
8891 or else Id = Attribute_Truncation;
0669bebe
GB
8892 end Is_Inline_Floating_Point_Attribute;
8893
70482933 8894end Exp_Attr;
This page took 8.313518 seconds and 5 git commands to generate.