1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
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- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 ------------------------------------------------------------------------------
27 with Atree
; use Atree
;
28 with Checks
; use Checks
;
29 with Einfo
; use Einfo
;
30 with Elists
; use Elists
;
31 with Exp_Atag
; use Exp_Atag
;
32 with Exp_Ch2
; use Exp_Ch2
;
33 with Exp_Ch3
; use Exp_Ch3
;
34 with Exp_Ch6
; use Exp_Ch6
;
35 with Exp_Ch9
; use Exp_Ch9
;
36 with Exp_Imgv
; use Exp_Imgv
;
37 with Exp_Pakd
; use Exp_Pakd
;
38 with Exp_Strm
; use Exp_Strm
;
39 with Exp_Tss
; use Exp_Tss
;
40 with Exp_Util
; use Exp_Util
;
41 with Exp_VFpt
; use Exp_VFpt
;
42 with Fname
; use Fname
;
43 with Freeze
; use Freeze
;
44 with Gnatvsn
; use Gnatvsn
;
45 with Itypes
; use Itypes
;
47 with Namet
; use Namet
;
48 with Nmake
; use Nmake
;
49 with Nlists
; use Nlists
;
51 with Restrict
; use Restrict
;
52 with Rident
; use Rident
;
53 with Rtsfind
; use Rtsfind
;
55 with Sem_Ch6
; use Sem_Ch6
;
56 with Sem_Ch7
; use Sem_Ch7
;
57 with Sem_Ch8
; use Sem_Ch8
;
58 with Sem_Eval
; use Sem_Eval
;
59 with Sem_Res
; use Sem_Res
;
60 with Sem_Util
; use Sem_Util
;
61 with Sinfo
; use Sinfo
;
62 with Snames
; use Snames
;
63 with Stand
; use Stand
;
64 with Stringt
; use Stringt
;
65 with Targparm
; use Targparm
;
66 with Tbuild
; use Tbuild
;
67 with Ttypes
; use Ttypes
;
68 with Uintp
; use Uintp
;
69 with Uname
; use Uname
;
70 with Validsw
; use Validsw
;
72 package body Exp_Attr
is
74 -----------------------
75 -- Local Subprograms --
76 -----------------------
78 procedure Compile_Stream_Body_In_Scope
83 -- The body for a stream subprogram may be generated outside of the scope
84 -- of the type. If the type is fully private, it may depend on the full
85 -- view of other types (e.g. indices) that are currently private as well.
86 -- We install the declarations of the package in which the type is declared
87 -- before compiling the body in what is its proper environment. The Check
88 -- parameter indicates if checks are to be suppressed for the stream body.
89 -- We suppress checks for array/record reads, since the rule is that these
90 -- are like assignments, out of range values due to uninitialized storage,
91 -- or other invalid values do NOT cause a Constraint_Error to be raised.
93 procedure Expand_Access_To_Protected_Op
98 -- An attribute reference to a protected subprogram is transformed into
99 -- a pair of pointers: one to the object, and one to the operations.
100 -- This expansion is performed for 'Access and for 'Unrestricted_Access.
102 procedure Expand_Fpt_Attribute
107 -- This procedure expands a call to a floating-point attribute function.
108 -- N is the attribute reference node, and Args is a list of arguments to
109 -- be passed to the function call. Pkg identifies the package containing
110 -- the appropriate instantiation of System.Fat_Gen. Float arguments in Args
111 -- have already been converted to the floating-point type for which Pkg was
112 -- instantiated. The Nam argument is the relevant attribute processing
113 -- routine to be called. This is the same as the attribute name, except in
114 -- the Unaligned_Valid case.
116 procedure Expand_Fpt_Attribute_R
(N
: Node_Id
);
117 -- This procedure expands a call to a floating-point attribute function
118 -- that takes a single floating-point argument. The function to be called
119 -- is always the same as the attribute name.
121 procedure Expand_Fpt_Attribute_RI
(N
: Node_Id
);
122 -- This procedure expands a call to a floating-point attribute function
123 -- that takes one floating-point argument and one integer argument. The
124 -- function to be called is always the same as the attribute name.
126 procedure Expand_Fpt_Attribute_RR
(N
: Node_Id
);
127 -- This procedure expands a call to a floating-point attribute function
128 -- that takes two floating-point arguments. The function to be called
129 -- is always the same as the attribute name.
131 procedure Expand_Pred_Succ
(N
: Node_Id
);
132 -- Handles expansion of Pred or Succ attributes for case of non-real
133 -- operand with overflow checking required.
135 function Get_Index_Subtype
(N
: Node_Id
) return Entity_Id
;
136 -- Used for Last, Last, and Length, when the prefix is an array type.
137 -- Obtains the corresponding index subtype.
139 procedure Find_Fat_Info
141 Fat_Type
: out Entity_Id
;
142 Fat_Pkg
: out RE_Id
);
143 -- Given a floating-point type T, identifies the package containing the
144 -- attributes for this type (returned in Fat_Pkg), and the corresponding
145 -- type for which this package was instantiated from Fat_Gen. Error if T
146 -- is not a floating-point type.
148 function Find_Stream_Subprogram
150 Nam
: TSS_Name_Type
) return Entity_Id
;
151 -- Returns the stream-oriented subprogram attribute for Typ. For tagged
152 -- types, the corresponding primitive operation is looked up, else the
153 -- appropriate TSS from the type itself, or from its closest ancestor
154 -- defining it, is returned. In both cases, inheritance of representation
155 -- aspects is thus taken into account.
157 function Get_Stream_Convert_Pragma
(T
: Entity_Id
) return Node_Id
;
158 -- Given a type, find a corresponding stream convert pragma that applies to
159 -- the implementation base type of this type (Typ). If found, return the
160 -- pragma node, otherwise return Empty if no pragma is found.
162 function Is_Constrained_Packed_Array
(Typ
: Entity_Id
) return Boolean;
163 -- Utility for array attributes, returns true on packed constrained
164 -- arrays, and on access to same.
166 function Is_Inline_Floating_Point_Attribute
(N
: Node_Id
) return Boolean;
167 -- Returns true iff the given node refers to an attribute call that
168 -- can be expanded directly by the back end and does not need front end
169 -- expansion. Typically used for rounding and truncation attributes that
170 -- appear directly inside a conversion to integer.
172 ----------------------------------
173 -- Compile_Stream_Body_In_Scope --
174 ----------------------------------
176 procedure Compile_Stream_Body_In_Scope
182 Installed
: Boolean := False;
183 Scop
: constant Entity_Id
:= Scope
(Arr
);
184 Curr
: constant Entity_Id
:= Current_Scope
;
188 and then not In_Open_Scopes
(Scop
)
189 and then Ekind
(Scop
) = E_Package
192 Install_Visible_Declarations
(Scop
);
193 Install_Private_Declarations
(Scop
);
196 -- The entities in the package are now visible, but the generated
197 -- stream entity must appear in the current scope (usually an
198 -- enclosing stream function) so that itypes all have their proper
205 Insert_Action
(N
, Decl
);
207 Insert_Action
(N
, Decl
, Suppress
=> All_Checks
);
212 -- Remove extra copy of current scope, and package itself
215 End_Package_Scope
(Scop
);
217 end Compile_Stream_Body_In_Scope
;
219 -----------------------------------
220 -- Expand_Access_To_Protected_Op --
221 -----------------------------------
223 procedure Expand_Access_To_Protected_Op
228 -- The value of the attribute_reference is a record containing two
229 -- fields: an access to the protected object, and an access to the
230 -- subprogram itself. The prefix is a selected component.
232 Loc
: constant Source_Ptr
:= Sloc
(N
);
234 Btyp
: constant Entity_Id
:= Base_Type
(Typ
);
236 E_T
: constant Entity_Id
:= Equivalent_Type
(Btyp
);
237 Acc
: constant Entity_Id
:=
238 Etype
(Next_Component
(First_Component
(E_T
)));
242 function May_Be_External_Call
return Boolean;
243 -- If the 'Access is to a local operation, but appears in a context
244 -- where it may lead to a call from outside the object, we must treat
245 -- this as an external call. Clearly we cannot tell without full
246 -- flow analysis, and a subsequent call that uses this 'Access may
247 -- lead to a bounded error (trying to seize locks twice, e.g.). For
248 -- now we treat 'Access as a potential external call if it is an actual
249 -- in a call to an outside subprogram.
251 --------------------------
252 -- May_Be_External_Call --
253 --------------------------
255 function May_Be_External_Call
return Boolean is
257 Par
: Node_Id
:= Parent
(N
);
260 -- Account for the case where the Access attribute is part of a
261 -- named parameter association.
263 if Nkind
(Par
) = N_Parameter_Association
then
267 if Nkind_In
(Par
, N_Procedure_Call_Statement
, N_Function_Call
)
268 and then Is_Entity_Name
(Name
(Par
))
270 Subp
:= Entity
(Name
(Par
));
271 return not In_Open_Scopes
(Scope
(Subp
));
275 end May_Be_External_Call
;
277 -- Start of processing for Expand_Access_To_Protected_Op
280 -- Within the body of the protected type, the prefix
281 -- designates a local operation, and the object is the first
282 -- parameter of the corresponding protected body of the
283 -- current enclosing operation.
285 if Is_Entity_Name
(Pref
) then
286 if May_Be_External_Call
then
289 (External_Subprogram
(Entity
(Pref
)), Loc
);
293 (Protected_Body_Subprogram
(Entity
(Pref
)), Loc
);
296 -- Don't traverse the scopes when the attribute occurs within an init
297 -- proc, because we directly use the _init formal of the init proc in
300 Curr
:= Current_Scope
;
301 if not Is_Init_Proc
(Curr
) then
302 pragma Assert
(In_Open_Scopes
(Scope
(Entity
(Pref
))));
304 while Scope
(Curr
) /= Scope
(Entity
(Pref
)) loop
305 Curr
:= Scope
(Curr
);
309 -- In case of protected entries the first formal of its Protected_
310 -- Body_Subprogram is the address of the object.
312 if Ekind
(Curr
) = E_Entry
then
316 (Protected_Body_Subprogram
(Curr
)), Loc
);
318 -- If the current scope is an init proc, then use the address of the
319 -- _init formal as the object reference.
321 elsif Is_Init_Proc
(Curr
) then
323 Make_Attribute_Reference
(Loc
,
324 Prefix
=> New_Occurrence_Of
(First_Formal
(Curr
), Loc
),
325 Attribute_Name
=> Name_Address
);
327 -- In case of protected subprograms the first formal of its
328 -- Protected_Body_Subprogram is the object and we get its address.
332 Make_Attribute_Reference
(Loc
,
336 (Protected_Body_Subprogram
(Curr
)), Loc
),
337 Attribute_Name
=> Name_Address
);
340 -- Case where the prefix is not an entity name. Find the
341 -- version of the protected operation to be called from
342 -- outside the protected object.
348 (Entity
(Selector_Name
(Pref
))), Loc
);
351 Make_Attribute_Reference
(Loc
,
352 Prefix
=> Relocate_Node
(Prefix
(Pref
)),
353 Attribute_Name
=> Name_Address
);
361 Unchecked_Convert_To
(Acc
,
362 Make_Attribute_Reference
(Loc
,
364 Attribute_Name
=> Name_Address
))));
368 Analyze_And_Resolve
(N
, E_T
);
370 -- For subsequent analysis, the node must retain its type.
371 -- The backend will replace it with the equivalent type where
375 end Expand_Access_To_Protected_Op
;
377 --------------------------
378 -- Expand_Fpt_Attribute --
379 --------------------------
381 procedure Expand_Fpt_Attribute
387 Loc
: constant Source_Ptr
:= Sloc
(N
);
388 Typ
: constant Entity_Id
:= Etype
(N
);
392 -- The function name is the selected component Attr_xxx.yyy where
393 -- Attr_xxx is the package name, and yyy is the argument Nam.
395 -- Note: it would be more usual to have separate RE entries for each
396 -- of the entities in the Fat packages, but first they have identical
397 -- names (so we would have to have lots of renaming declarations to
398 -- meet the normal RE rule of separate names for all runtime entities),
399 -- and second there would be an awful lot of them!
402 Make_Selected_Component
(Loc
,
403 Prefix
=> New_Reference_To
(RTE
(Pkg
), Loc
),
404 Selector_Name
=> Make_Identifier
(Loc
, Nam
));
406 -- The generated call is given the provided set of parameters, and then
407 -- wrapped in a conversion which converts the result to the target type
408 -- We use the base type as the target because a range check may be
412 Unchecked_Convert_To
(Base_Type
(Etype
(N
)),
413 Make_Function_Call
(Loc
,
415 Parameter_Associations
=> Args
)));
417 Analyze_And_Resolve
(N
, Typ
);
418 end Expand_Fpt_Attribute
;
420 ----------------------------
421 -- Expand_Fpt_Attribute_R --
422 ----------------------------
424 -- The single argument is converted to its root type to call the
425 -- appropriate runtime function, with the actual call being built
426 -- by Expand_Fpt_Attribute
428 procedure Expand_Fpt_Attribute_R
(N
: Node_Id
) is
429 E1
: constant Node_Id
:= First
(Expressions
(N
));
433 Find_Fat_Info
(Etype
(E1
), Ftp
, Pkg
);
435 (N
, Pkg
, Attribute_Name
(N
),
436 New_List
(Unchecked_Convert_To
(Ftp
, Relocate_Node
(E1
))));
437 end Expand_Fpt_Attribute_R
;
439 -----------------------------
440 -- Expand_Fpt_Attribute_RI --
441 -----------------------------
443 -- The first argument is converted to its root type and the second
444 -- argument is converted to standard long long integer to call the
445 -- appropriate runtime function, with the actual call being built
446 -- by Expand_Fpt_Attribute
448 procedure Expand_Fpt_Attribute_RI
(N
: Node_Id
) is
449 E1
: constant Node_Id
:= First
(Expressions
(N
));
452 E2
: constant Node_Id
:= Next
(E1
);
454 Find_Fat_Info
(Etype
(E1
), Ftp
, Pkg
);
456 (N
, Pkg
, Attribute_Name
(N
),
458 Unchecked_Convert_To
(Ftp
, Relocate_Node
(E1
)),
459 Unchecked_Convert_To
(Standard_Integer
, Relocate_Node
(E2
))));
460 end Expand_Fpt_Attribute_RI
;
462 -----------------------------
463 -- Expand_Fpt_Attribute_RR --
464 -----------------------------
466 -- The two arguments are converted to their root types to call the
467 -- appropriate runtime function, with the actual call being built
468 -- by Expand_Fpt_Attribute
470 procedure Expand_Fpt_Attribute_RR
(N
: Node_Id
) is
471 E1
: constant Node_Id
:= First
(Expressions
(N
));
474 E2
: constant Node_Id
:= Next
(E1
);
476 Find_Fat_Info
(Etype
(E1
), Ftp
, Pkg
);
478 (N
, Pkg
, Attribute_Name
(N
),
480 Unchecked_Convert_To
(Ftp
, Relocate_Node
(E1
)),
481 Unchecked_Convert_To
(Ftp
, Relocate_Node
(E2
))));
482 end Expand_Fpt_Attribute_RR
;
484 ----------------------------------
485 -- Expand_N_Attribute_Reference --
486 ----------------------------------
488 procedure Expand_N_Attribute_Reference
(N
: Node_Id
) is
489 Loc
: constant Source_Ptr
:= Sloc
(N
);
490 Typ
: constant Entity_Id
:= Etype
(N
);
491 Btyp
: constant Entity_Id
:= Base_Type
(Typ
);
492 Pref
: constant Node_Id
:= Prefix
(N
);
493 Ptyp
: constant Entity_Id
:= Etype
(Pref
);
494 Exprs
: constant List_Id
:= Expressions
(N
);
495 Id
: constant Attribute_Id
:= Get_Attribute_Id
(Attribute_Name
(N
));
497 procedure Rewrite_Stream_Proc_Call
(Pname
: Entity_Id
);
498 -- Rewrites a stream attribute for Read, Write or Output with the
499 -- procedure call. Pname is the entity for the procedure to call.
501 ------------------------------
502 -- Rewrite_Stream_Proc_Call --
503 ------------------------------
505 procedure Rewrite_Stream_Proc_Call
(Pname
: Entity_Id
) is
506 Item
: constant Node_Id
:= Next
(First
(Exprs
));
507 Formal
: constant Entity_Id
:= Next_Formal
(First_Formal
(Pname
));
508 Formal_Typ
: constant Entity_Id
:= Etype
(Formal
);
509 Is_Written
: constant Boolean := (Ekind
(Formal
) /= E_In_Parameter
);
512 -- The expansion depends on Item, the second actual, which is
513 -- the object being streamed in or out.
515 -- If the item is a component of a packed array type, and
516 -- a conversion is needed on exit, we introduce a temporary to
517 -- hold the value, because otherwise the packed reference will
518 -- not be properly expanded.
520 if Nkind
(Item
) = N_Indexed_Component
521 and then Is_Packed
(Base_Type
(Etype
(Prefix
(Item
))))
522 and then Base_Type
(Etype
(Item
)) /= Base_Type
(Formal_Typ
)
526 Temp
: constant Entity_Id
:=
527 Make_Defining_Identifier
528 (Loc
, New_Internal_Name
('V'));
534 Make_Object_Declaration
(Loc
,
535 Defining_Identifier
=> Temp
,
537 New_Occurrence_Of
(Formal_Typ
, Loc
));
538 Set_Etype
(Temp
, Formal_Typ
);
541 Make_Assignment_Statement
(Loc
,
542 Name
=> New_Copy_Tree
(Item
),
545 (Etype
(Item
), New_Occurrence_Of
(Temp
, Loc
)));
547 Rewrite
(Item
, New_Occurrence_Of
(Temp
, Loc
));
551 Make_Procedure_Call_Statement
(Loc
,
552 Name
=> New_Occurrence_Of
(Pname
, Loc
),
553 Parameter_Associations
=> Exprs
),
556 Rewrite
(N
, Make_Null_Statement
(Loc
));
561 -- For the class-wide dispatching cases, and for cases in which
562 -- the base type of the second argument matches the base type of
563 -- the corresponding formal parameter (that is to say the stream
564 -- operation is not inherited), we are all set, and can use the
565 -- argument unchanged.
567 -- For all other cases we do an unchecked conversion of the second
568 -- parameter to the type of the formal of the procedure we are
569 -- calling. This deals with the private type cases, and with going
570 -- to the root type as required in elementary type case.
572 if not Is_Class_Wide_Type
(Entity
(Pref
))
573 and then not Is_Class_Wide_Type
(Etype
(Item
))
574 and then Base_Type
(Etype
(Item
)) /= Base_Type
(Formal_Typ
)
577 Unchecked_Convert_To
(Formal_Typ
, Relocate_Node
(Item
)));
579 -- For untagged derived types set Assignment_OK, to prevent
580 -- copies from being created when the unchecked conversion
581 -- is expanded (which would happen in Remove_Side_Effects
582 -- if Expand_N_Unchecked_Conversion were allowed to call
583 -- Force_Evaluation). The copy could violate Ada semantics
584 -- in cases such as an actual that is an out parameter.
585 -- Note that this approach is also used in exp_ch7 for calls
586 -- to controlled type operations to prevent problems with
587 -- actuals wrapped in unchecked conversions.
589 if Is_Untagged_Derivation
(Etype
(Expression
(Item
))) then
590 Set_Assignment_OK
(Item
);
594 -- And now rewrite the call
597 Make_Procedure_Call_Statement
(Loc
,
598 Name
=> New_Occurrence_Of
(Pname
, Loc
),
599 Parameter_Associations
=> Exprs
));
602 end Rewrite_Stream_Proc_Call
;
604 -- Start of processing for Expand_N_Attribute_Reference
607 -- Do required validity checking, if enabled. Do not apply check to
608 -- output parameters of an Asm instruction, since the value of this
609 -- is not set till after the attribute has been elaborated.
611 if Validity_Checks_On
and then Validity_Check_Operands
612 and then Id
/= Attribute_Asm_Output
617 Expr
:= First
(Expressions
(N
));
618 while Present
(Expr
) loop
625 -- Ada 2005 (AI-318-02): If attribute prefix is a call to a build-in-
626 -- place function, then a temporary return object needs to be created
627 -- and access to it must be passed to the function. Currently we limit
628 -- such functions to those with inherently limited result subtypes, but
629 -- eventually we plan to expand the functions that are treated as
630 -- build-in-place to include other composite result types.
632 if Ada_Version
>= Ada_05
633 and then Is_Build_In_Place_Function_Call
(Pref
)
635 Make_Build_In_Place_Call_In_Anonymous_Context
(Pref
);
638 -- Remaining processing depends on specific attribute
646 when Attribute_Access |
647 Attribute_Unchecked_Access |
648 Attribute_Unrestricted_Access
=>
650 Access_Cases
: declare
651 Btyp_DDT
: constant Entity_Id
:= Directly_Designated_Type
(Btyp
);
652 Ref_Object
: constant Node_Id
:= Get_Referenced_Object
(Pref
);
655 -- In order to improve the text of error messages, the designated
656 -- type of access-to-subprogram itypes is set by the semantics as
657 -- the associated subprogram entity (see sem_attr). Now we replace
658 -- such node with the proper E_Subprogram_Type itype.
660 if Id
= Attribute_Unrestricted_Access
661 and then Is_Subprogram
(Directly_Designated_Type
(Typ
))
663 -- The following conditions ensure that this special management
664 -- is done only for "Address!(Prim'Unrestricted_Access)" nodes.
665 -- At this stage other cases in which the designated type is
666 -- still a subprogram (instead of an E_Subprogram_Type) are
667 -- wrong because the semantics must have overridden the type of
668 -- the node with the type imposed by the context.
670 if Nkind
(Parent
(N
)) = N_Unchecked_Type_Conversion
671 and then Etype
(Parent
(N
)) = RTE
(RE_Prim_Ptr
)
673 Set_Etype
(N
, RTE
(RE_Prim_Ptr
));
677 Subp
: constant Entity_Id
:=
678 Directly_Designated_Type
(Typ
);
680 Extra
: Entity_Id
:= Empty
;
681 New_Formal
: Entity_Id
;
682 Old_Formal
: Entity_Id
:= First_Formal
(Subp
);
683 Subp_Typ
: Entity_Id
;
686 Subp_Typ
:= Create_Itype
(E_Subprogram_Type
, N
);
687 Set_Etype
(Subp_Typ
, Etype
(Subp
));
688 Set_Returns_By_Ref
(Subp_Typ
, Returns_By_Ref
(Subp
));
690 if Present
(Old_Formal
) then
691 New_Formal
:= New_Copy
(Old_Formal
);
692 Set_First_Entity
(Subp_Typ
, New_Formal
);
695 Set_Scope
(New_Formal
, Subp_Typ
);
696 Etyp
:= Etype
(New_Formal
);
698 -- Handle itypes. There is no need to duplicate
699 -- here the itypes associated with record types
700 -- (i.e the implicit full view of private types).
703 and then Ekind
(Base_Type
(Etyp
)) /= E_Record_Type
705 Extra
:= New_Copy
(Etyp
);
706 Set_Parent
(Extra
, New_Formal
);
707 Set_Etype
(New_Formal
, Extra
);
708 Set_Scope
(Extra
, Subp_Typ
);
712 Next_Formal
(Old_Formal
);
713 exit when No
(Old_Formal
);
715 Set_Next_Entity
(New_Formal
,
716 New_Copy
(Old_Formal
));
717 Next_Entity
(New_Formal
);
720 Set_Next_Entity
(New_Formal
, Empty
);
721 Set_Last_Entity
(Subp_Typ
, Extra
);
724 -- Now that the explicit formals have been duplicated,
725 -- any extra formals needed by the subprogram must be
728 if Present
(Extra
) then
729 Set_Extra_Formal
(Extra
, Empty
);
732 Create_Extra_Formals
(Subp_Typ
);
733 Set_Directly_Designated_Type
(Typ
, Subp_Typ
);
738 if Is_Access_Protected_Subprogram_Type
(Btyp
) then
739 Expand_Access_To_Protected_Op
(N
, Pref
, Typ
);
741 -- If prefix is a type name, this is a reference to the current
742 -- instance of the type, within its initialization procedure.
744 elsif Is_Entity_Name
(Pref
)
745 and then Is_Type
(Entity
(Pref
))
752 -- If the current instance name denotes a task type, then
753 -- the access attribute is rewritten to be the name of the
754 -- "_task" parameter associated with the task type's task
755 -- procedure. An unchecked conversion is applied to ensure
756 -- a type match in cases of expander-generated calls (e.g.
759 if Is_Task_Type
(Entity
(Pref
)) then
761 First_Entity
(Get_Task_Body_Procedure
(Entity
(Pref
)));
762 while Present
(Formal
) loop
763 exit when Chars
(Formal
) = Name_uTask
;
764 Next_Entity
(Formal
);
767 pragma Assert
(Present
(Formal
));
770 Unchecked_Convert_To
(Typ
,
771 New_Occurrence_Of
(Formal
, Loc
)));
774 -- The expression must appear in a default expression,
775 -- (which in the initialization procedure is the
776 -- right-hand side of an assignment), and not in a
777 -- discriminant constraint.
781 while Present
(Par
) loop
782 exit when Nkind
(Par
) = N_Assignment_Statement
;
784 if Nkind
(Par
) = N_Component_Declaration
then
791 if Present
(Par
) then
793 Make_Attribute_Reference
(Loc
,
794 Prefix
=> Make_Identifier
(Loc
, Name_uInit
),
795 Attribute_Name
=> Attribute_Name
(N
)));
797 Analyze_And_Resolve
(N
, Typ
);
802 -- If the prefix of an Access attribute is a dereference of an
803 -- access parameter (or a renaming of such a dereference) and
804 -- the context is a general access type (but not an anonymous
805 -- access type), then rewrite the attribute as a conversion of
806 -- the access parameter to the context access type. This will
807 -- result in an accessibility check being performed, if needed.
809 -- (X.all'Access => Acc_Type (X))
811 -- Note: Limit the expansion of an attribute applied to a
812 -- dereference of an access parameter so that it's only done
813 -- for 'Access. This fixes a problem with 'Unrestricted_Access
814 -- that leads to errors in the case where the attribute type
815 -- is access-to-variable and the access parameter is
816 -- access-to-constant. The conversion is only done to get
817 -- accessibility checks, so it makes sense to limit it to
820 elsif Nkind
(Ref_Object
) = N_Explicit_Dereference
821 and then Is_Entity_Name
(Prefix
(Ref_Object
))
822 and then Ekind
(Btyp
) = E_General_Access_Type
823 and then Ekind
(Entity
(Prefix
(Ref_Object
))) in Formal_Kind
824 and then Ekind
(Etype
(Entity
(Prefix
(Ref_Object
))))
825 = E_Anonymous_Access_Type
826 and then Present
(Extra_Accessibility
827 (Entity
(Prefix
(Ref_Object
))))
830 Convert_To
(Typ
, New_Copy_Tree
(Prefix
(Ref_Object
))));
831 Analyze_And_Resolve
(N
, Typ
);
833 -- Ada 2005 (AI-251): If the designated type is an interface we
834 -- add an implicit conversion to force the displacement of the
835 -- pointer to reference the secondary dispatch table.
837 elsif Is_Interface
(Btyp_DDT
)
838 and then (Comes_From_Source
(N
)
839 or else Comes_From_Source
(Ref_Object
)
840 or else (Nkind
(Ref_Object
) in N_Has_Chars
841 and then Chars
(Ref_Object
) = Name_uInit
))
843 if Nkind
(Ref_Object
) /= N_Explicit_Dereference
then
845 -- No implicit conversion required if types match
847 if Btyp_DDT
/= Etype
(Ref_Object
) then
849 Convert_To
(Directly_Designated_Type
(Typ
),
850 New_Copy_Tree
(Prefix
(N
))));
852 Analyze_And_Resolve
(Prefix
(N
),
853 Directly_Designated_Type
(Typ
));
856 -- When the object is an explicit dereference, convert the
857 -- dereference's prefix.
861 Obj_DDT
: constant Entity_Id
:=
863 (Directly_Designated_Type
864 (Etype
(Prefix
(Ref_Object
))));
866 -- No implicit conversion required if designated types
869 if Obj_DDT
/= Btyp_DDT
870 and then not (Is_Class_Wide_Type
(Obj_DDT
)
871 and then Etype
(Obj_DDT
) = Btyp_DDT
)
875 New_Copy_Tree
(Prefix
(Ref_Object
))));
876 Analyze_And_Resolve
(N
, Typ
);
887 -- Transforms 'Adjacent into a call to the floating-point attribute
888 -- function Adjacent in Fat_xxx (where xxx is the root type)
890 when Attribute_Adjacent
=>
891 Expand_Fpt_Attribute_RR
(N
);
897 when Attribute_Address
=> Address
: declare
898 Task_Proc
: Entity_Id
;
901 -- If the prefix is a task or a task type, the useful address is that
902 -- of the procedure for the task body, i.e. the actual program unit.
903 -- We replace the original entity with that of the procedure.
905 if Is_Entity_Name
(Pref
)
906 and then Is_Task_Type
(Entity
(Pref
))
908 Task_Proc
:= Next_Entity
(Root_Type
(Ptyp
));
910 while Present
(Task_Proc
) loop
911 exit when Ekind
(Task_Proc
) = E_Procedure
912 and then Etype
(First_Formal
(Task_Proc
)) =
913 Corresponding_Record_Type
(Ptyp
);
914 Next_Entity
(Task_Proc
);
917 if Present
(Task_Proc
) then
918 Set_Entity
(Pref
, Task_Proc
);
919 Set_Etype
(Pref
, Etype
(Task_Proc
));
922 -- Similarly, the address of a protected operation is the address
923 -- of the corresponding protected body, regardless of the protected
924 -- object from which it is selected.
926 elsif Nkind
(Pref
) = N_Selected_Component
927 and then Is_Subprogram
(Entity
(Selector_Name
(Pref
)))
928 and then Is_Protected_Type
(Scope
(Entity
(Selector_Name
(Pref
))))
932 External_Subprogram
(Entity
(Selector_Name
(Pref
))), Loc
));
934 elsif Nkind
(Pref
) = N_Explicit_Dereference
935 and then Ekind
(Ptyp
) = E_Subprogram_Type
936 and then Convention
(Ptyp
) = Convention_Protected
938 -- The prefix is be a dereference of an access_to_protected_
939 -- subprogram. The desired address is the second component of
940 -- the record that represents the access.
943 Addr
: constant Entity_Id
:= Etype
(N
);
944 Ptr
: constant Node_Id
:= Prefix
(Pref
);
945 T
: constant Entity_Id
:=
946 Equivalent_Type
(Base_Type
(Etype
(Ptr
)));
950 Unchecked_Convert_To
(Addr
,
951 Make_Selected_Component
(Loc
,
952 Prefix
=> Unchecked_Convert_To
(T
, Ptr
),
953 Selector_Name
=> New_Occurrence_Of
(
954 Next_Entity
(First_Entity
(T
)), Loc
))));
956 Analyze_And_Resolve
(N
, Addr
);
959 -- Ada 2005 (AI-251): Class-wide interface objects are always
960 -- "displaced" to reference the tag associated with the interface
961 -- type. In order to obtain the real address of such objects we
962 -- generate a call to a run-time subprogram that returns the base
963 -- address of the object.
965 -- This processing is not needed in the VM case, where dispatching
966 -- issues are taken care of by the virtual machine.
968 elsif Is_Class_Wide_Type
(Ptyp
)
969 and then Is_Interface
(Ptyp
)
970 and then VM_Target
= No_VM
971 and then not (Nkind
(Pref
) in N_Has_Entity
972 and then Is_Subprogram
(Entity
(Pref
)))
975 Make_Function_Call
(Loc
,
976 Name
=> New_Reference_To
(RTE
(RE_Base_Address
), Loc
),
977 Parameter_Associations
=> New_List
(
978 Relocate_Node
(N
))));
983 -- Deal with packed array reference, other cases are handled by
986 if Involves_Packed_Array_Reference
(Pref
) then
987 Expand_Packed_Address_Reference
(N
);
995 when Attribute_Alignment
=> Alignment
: declare
999 -- For class-wide types, X'Class'Alignment is transformed into a
1000 -- direct reference to the Alignment of the class type, so that the
1001 -- back end does not have to deal with the X'Class'Alignment
1004 if Is_Entity_Name
(Pref
)
1005 and then Is_Class_Wide_Type
(Entity
(Pref
))
1007 Rewrite
(Prefix
(N
), New_Occurrence_Of
(Entity
(Pref
), Loc
));
1010 -- For x'Alignment applied to an object of a class wide type,
1011 -- transform X'Alignment into a call to the predefined primitive
1012 -- operation _Alignment applied to X.
1014 elsif Is_Class_Wide_Type
(Ptyp
) then
1016 -- No need to do anything else compiling under restriction
1017 -- No_Dispatching_Calls. During the semantic analysis we
1018 -- already notified such violation.
1020 if Restriction_Active
(No_Dispatching_Calls
) then
1025 Make_Function_Call
(Loc
,
1026 Name
=> New_Reference_To
1027 (Find_Prim_Op
(Ptyp
, Name_uAlignment
), Loc
),
1028 Parameter_Associations
=> New_List
(Pref
));
1030 if Typ
/= Standard_Integer
then
1032 -- The context is a specific integer type with which the
1033 -- original attribute was compatible. The function has a
1034 -- specific type as well, so to preserve the compatibility
1035 -- we must convert explicitly.
1037 New_Node
:= Convert_To
(Typ
, New_Node
);
1040 Rewrite
(N
, New_Node
);
1041 Analyze_And_Resolve
(N
, Typ
);
1044 -- For all other cases, we just have to deal with the case of
1045 -- the fact that the result can be universal.
1048 Apply_Universal_Integer_Attribute_Checks
(N
);
1056 when Attribute_AST_Entry
=> AST_Entry
: declare
1061 Entry_Ref
: Node_Id
;
1062 -- The reference to the entry or entry family
1065 -- The index expression for an entry family reference, or
1066 -- the Empty if Entry_Ref references a simple entry.
1069 if Nkind
(Pref
) = N_Indexed_Component
then
1070 Entry_Ref
:= Prefix
(Pref
);
1071 Index
:= First
(Expressions
(Pref
));
1077 -- Get expression for Task_Id and the entry entity
1079 if Nkind
(Entry_Ref
) = N_Selected_Component
then
1081 Make_Attribute_Reference
(Loc
,
1082 Attribute_Name
=> Name_Identity
,
1083 Prefix
=> Prefix
(Entry_Ref
));
1085 Ttyp
:= Etype
(Prefix
(Entry_Ref
));
1086 Eent
:= Entity
(Selector_Name
(Entry_Ref
));
1090 Make_Function_Call
(Loc
,
1091 Name
=> New_Occurrence_Of
(RTE
(RE_Current_Task
), Loc
));
1093 Eent
:= Entity
(Entry_Ref
);
1095 -- We have to find the enclosing task to get the task type
1096 -- There must be one, since we already validated this earlier
1098 Ttyp
:= Current_Scope
;
1099 while not Is_Task_Type
(Ttyp
) loop
1100 Ttyp
:= Scope
(Ttyp
);
1104 -- Now rewrite the attribute with a call to Create_AST_Handler
1107 Make_Function_Call
(Loc
,
1108 Name
=> New_Occurrence_Of
(RTE
(RE_Create_AST_Handler
), Loc
),
1109 Parameter_Associations
=> New_List
(
1111 Entry_Index_Expression
(Loc
, Eent
, Index
, Ttyp
))));
1113 Analyze_And_Resolve
(N
, RTE
(RE_AST_Handler
));
1120 -- We compute this if a component clause was present, otherwise we leave
1121 -- the computation up to the back end, since we don't know what layout
1124 -- Note that the attribute can apply to a naked record component
1125 -- in generated code (i.e. the prefix is an identifier that
1126 -- references the component or discriminant entity).
1128 when Attribute_Bit_Position
=> Bit_Position
:
1133 if Nkind
(Pref
) = N_Identifier
then
1134 CE
:= Entity
(Pref
);
1136 CE
:= Entity
(Selector_Name
(Pref
));
1139 if Known_Static_Component_Bit_Offset
(CE
) then
1141 Make_Integer_Literal
(Loc
,
1142 Intval
=> Component_Bit_Offset
(CE
)));
1143 Analyze_And_Resolve
(N
, Typ
);
1146 Apply_Universal_Integer_Attribute_Checks
(N
);
1154 -- A reference to P'Body_Version or P'Version is expanded to
1157 -- pragma Import (C, Vnn, "uuuuT";
1159 -- Get_Version_String (Vnn)
1161 -- where uuuu is the unit name (dots replaced by double underscore)
1162 -- and T is B for the cases of Body_Version, or Version applied to a
1163 -- subprogram acting as its own spec, and S for Version applied to a
1164 -- subprogram spec or package. This sequence of code references the
1165 -- the unsigned constant created in the main program by the binder.
1167 -- A special exception occurs for Standard, where the string
1168 -- returned is a copy of the library string in gnatvsn.ads.
1170 when Attribute_Body_Version | Attribute_Version
=> Version
: declare
1171 E
: constant Entity_Id
:=
1172 Make_Defining_Identifier
(Loc
, New_Internal_Name
('V'));
1177 -- If not library unit, get to containing library unit
1179 Pent
:= Entity
(Pref
);
1180 while Pent
/= Standard_Standard
1181 and then Scope
(Pent
) /= Standard_Standard
1182 and then not Is_Child_Unit
(Pent
)
1184 Pent
:= Scope
(Pent
);
1187 -- Special case Standard and Standard.ASCII
1189 if Pent
= Standard_Standard
or else Pent
= Standard_ASCII
then
1191 Make_String_Literal
(Loc
,
1192 Strval
=> Verbose_Library_Version
));
1197 -- Build required string constant
1199 Get_Name_String
(Get_Unit_Name
(Pent
));
1202 for J
in 1 .. Name_Len
- 2 loop
1203 if Name_Buffer
(J
) = '.' then
1204 Store_String_Chars
("__");
1206 Store_String_Char
(Get_Char_Code
(Name_Buffer
(J
)));
1210 -- Case of subprogram acting as its own spec, always use body
1212 if Nkind
(Declaration_Node
(Pent
)) in N_Subprogram_Specification
1213 and then Nkind
(Parent
(Declaration_Node
(Pent
))) =
1215 and then Acts_As_Spec
(Parent
(Declaration_Node
(Pent
)))
1217 Store_String_Chars
("B");
1219 -- Case of no body present, always use spec
1221 elsif not Unit_Requires_Body
(Pent
) then
1222 Store_String_Chars
("S");
1224 -- Otherwise use B for Body_Version, S for spec
1226 elsif Id
= Attribute_Body_Version
then
1227 Store_String_Chars
("B");
1229 Store_String_Chars
("S");
1233 Lib
.Version_Referenced
(S
);
1235 -- Insert the object declaration
1237 Insert_Actions
(N
, New_List
(
1238 Make_Object_Declaration
(Loc
,
1239 Defining_Identifier
=> E
,
1240 Object_Definition
=>
1241 New_Occurrence_Of
(RTE
(RE_Unsigned
), Loc
))));
1243 -- Set entity as imported with correct external name
1245 Set_Is_Imported
(E
);
1246 Set_Interface_Name
(E
, Make_String_Literal
(Loc
, S
));
1248 -- Set entity as internal to ensure proper Sprint output of its
1249 -- implicit importation.
1251 Set_Is_Internal
(E
);
1253 -- And now rewrite original reference
1256 Make_Function_Call
(Loc
,
1257 Name
=> New_Reference_To
(RTE
(RE_Get_Version_String
), Loc
),
1258 Parameter_Associations
=> New_List
(
1259 New_Occurrence_Of
(E
, Loc
))));
1262 Analyze_And_Resolve
(N
, RTE
(RE_Version_String
));
1269 -- Transforms 'Ceiling into a call to the floating-point attribute
1270 -- function Ceiling in Fat_xxx (where xxx is the root type)
1272 when Attribute_Ceiling
=>
1273 Expand_Fpt_Attribute_R
(N
);
1279 -- Transforms 'Callable attribute into a call to the Callable function
1281 when Attribute_Callable
=> Callable
:
1283 -- We have an object of a task interface class-wide type as a prefix
1284 -- to Callable. Generate:
1286 -- callable (Task_Id (Pref._disp_get_task_id));
1288 if Ada_Version
>= Ada_05
1289 and then Ekind
(Ptyp
) = E_Class_Wide_Type
1290 and then Is_Interface
(Ptyp
)
1291 and then Is_Task_Interface
(Ptyp
)
1294 Make_Function_Call
(Loc
,
1296 New_Reference_To
(RTE
(RE_Callable
), Loc
),
1297 Parameter_Associations
=> New_List
(
1298 Make_Unchecked_Type_Conversion
(Loc
,
1300 New_Reference_To
(RTE
(RO_ST_Task_Id
), Loc
),
1302 Make_Selected_Component
(Loc
,
1304 New_Copy_Tree
(Pref
),
1306 Make_Identifier
(Loc
, Name_uDisp_Get_Task_Id
))))));
1310 Build_Call_With_Task
(Pref
, RTE
(RE_Callable
)));
1313 Analyze_And_Resolve
(N
, Standard_Boolean
);
1320 -- Transforms 'Caller attribute into a call to either the
1321 -- Task_Entry_Caller or the Protected_Entry_Caller function.
1323 when Attribute_Caller
=> Caller
: declare
1324 Id_Kind
: constant Entity_Id
:= RTE
(RO_AT_Task_Id
);
1325 Ent
: constant Entity_Id
:= Entity
(Pref
);
1326 Conctype
: constant Entity_Id
:= Scope
(Ent
);
1327 Nest_Depth
: Integer := 0;
1334 if Is_Protected_Type
(Conctype
) then
1335 case Corresponding_Runtime_Package
(Conctype
) is
1336 when System_Tasking_Protected_Objects_Entries
=>
1339 (RTE
(RE_Protected_Entry_Caller
), Loc
);
1341 when System_Tasking_Protected_Objects_Single_Entry
=>
1344 (RTE
(RE_Protected_Single_Entry_Caller
), Loc
);
1347 raise Program_Error
;
1351 Unchecked_Convert_To
(Id_Kind
,
1352 Make_Function_Call
(Loc
,
1354 Parameter_Associations
=> New_List
(
1356 (Find_Protection_Object
(Current_Scope
), Loc
)))));
1361 -- Determine the nesting depth of the E'Caller attribute, that
1362 -- is, how many accept statements are nested within the accept
1363 -- statement for E at the point of E'Caller. The runtime uses
1364 -- this depth to find the specified entry call.
1366 for J
in reverse 0 .. Scope_Stack
.Last
loop
1367 S
:= Scope_Stack
.Table
(J
).Entity
;
1369 -- We should not reach the scope of the entry, as it should
1370 -- already have been checked in Sem_Attr that this attribute
1371 -- reference is within a matching accept statement.
1373 pragma Assert
(S
/= Conctype
);
1378 elsif Is_Entry
(S
) then
1379 Nest_Depth
:= Nest_Depth
+ 1;
1384 Unchecked_Convert_To
(Id_Kind
,
1385 Make_Function_Call
(Loc
,
1387 New_Reference_To
(RTE
(RE_Task_Entry_Caller
), Loc
),
1388 Parameter_Associations
=> New_List
(
1389 Make_Integer_Literal
(Loc
,
1390 Intval
=> Int
(Nest_Depth
))))));
1393 Analyze_And_Resolve
(N
, Id_Kind
);
1400 -- Transforms 'Compose into a call to the floating-point attribute
1401 -- function Compose in Fat_xxx (where xxx is the root type)
1403 -- Note: we strictly should have special code here to deal with the
1404 -- case of absurdly negative arguments (less than Integer'First)
1405 -- which will return a (signed) zero value, but it hardly seems
1406 -- worth the effort. Absurdly large positive arguments will raise
1407 -- constraint error which is fine.
1409 when Attribute_Compose
=>
1410 Expand_Fpt_Attribute_RI
(N
);
1416 when Attribute_Constrained
=> Constrained
: declare
1417 Formal_Ent
: constant Entity_Id
:= Param_Entity
(Pref
);
1419 function Is_Constrained_Aliased_View
(Obj
: Node_Id
) return Boolean;
1420 -- Ada 2005 (AI-363): Returns True if the object name Obj denotes a
1421 -- view of an aliased object whose subtype is constrained.
1423 ---------------------------------
1424 -- Is_Constrained_Aliased_View --
1425 ---------------------------------
1427 function Is_Constrained_Aliased_View
(Obj
: Node_Id
) return Boolean is
1431 if Is_Entity_Name
(Obj
) then
1434 if Present
(Renamed_Object
(E
)) then
1435 return Is_Constrained_Aliased_View
(Renamed_Object
(E
));
1437 return Is_Aliased
(E
) and then Is_Constrained
(Etype
(E
));
1441 return Is_Aliased_View
(Obj
)
1443 (Is_Constrained
(Etype
(Obj
))
1444 or else (Nkind
(Obj
) = N_Explicit_Dereference
1446 not Has_Constrained_Partial_View
1447 (Base_Type
(Etype
(Obj
)))));
1449 end Is_Constrained_Aliased_View
;
1451 -- Start of processing for Constrained
1454 -- Reference to a parameter where the value is passed as an extra
1455 -- actual, corresponding to the extra formal referenced by the
1456 -- Extra_Constrained field of the corresponding formal. If this
1457 -- is an entry in-parameter, it is replaced by a constant renaming
1458 -- for which Extra_Constrained is never created.
1460 if Present
(Formal_Ent
)
1461 and then Ekind
(Formal_Ent
) /= E_Constant
1462 and then Present
(Extra_Constrained
(Formal_Ent
))
1466 (Extra_Constrained
(Formal_Ent
), Sloc
(N
)));
1468 -- For variables with a Extra_Constrained field, we use the
1469 -- corresponding entity.
1471 elsif Nkind
(Pref
) = N_Identifier
1472 and then Ekind
(Entity
(Pref
)) = E_Variable
1473 and then Present
(Extra_Constrained
(Entity
(Pref
)))
1477 (Extra_Constrained
(Entity
(Pref
)), Sloc
(N
)));
1479 -- For all other entity names, we can tell at compile time
1481 elsif Is_Entity_Name
(Pref
) then
1483 Ent
: constant Entity_Id
:= Entity
(Pref
);
1487 -- (RM J.4) obsolescent cases
1489 if Is_Type
(Ent
) then
1493 if Is_Private_Type
(Ent
) then
1494 Res
:= not Has_Discriminants
(Ent
)
1495 or else Is_Constrained
(Ent
);
1497 -- It not a private type, must be a generic actual type
1498 -- that corresponded to a private type. We know that this
1499 -- correspondence holds, since otherwise the reference
1500 -- within the generic template would have been illegal.
1503 if Is_Composite_Type
(Underlying_Type
(Ent
)) then
1504 Res
:= Is_Constrained
(Ent
);
1510 -- If the prefix is not a variable or is aliased, then
1511 -- definitely true; if it's a formal parameter without an
1512 -- associated extra formal, then treat it as constrained.
1514 -- Ada 2005 (AI-363): An aliased prefix must be known to be
1515 -- constrained in order to set the attribute to True.
1517 elsif not Is_Variable
(Pref
)
1518 or else Present
(Formal_Ent
)
1519 or else (Ada_Version
< Ada_05
1520 and then Is_Aliased_View
(Pref
))
1521 or else (Ada_Version
>= Ada_05
1522 and then Is_Constrained_Aliased_View
(Pref
))
1526 -- Variable case, look at type to see if it is constrained.
1527 -- Note that the one case where this is not accurate (the
1528 -- procedure formal case), has been handled above.
1530 -- We use the Underlying_Type here (and below) in case the
1531 -- type is private without discriminants, but the full type
1532 -- has discriminants. This case is illegal, but we generate it
1533 -- internally for passing to the Extra_Constrained parameter.
1536 Res
:= Is_Constrained
(Underlying_Type
(Etype
(Ent
)));
1540 New_Reference_To
(Boolean_Literals
(Res
), Loc
));
1543 -- Prefix is not an entity name. These are also cases where we can
1544 -- always tell at compile time by looking at the form and type of the
1545 -- prefix. If an explicit dereference of an object with constrained
1546 -- partial view, this is unconstrained (Ada 2005 AI-363).
1552 not Is_Variable
(Pref
)
1554 (Nkind
(Pref
) = N_Explicit_Dereference
1556 not Has_Constrained_Partial_View
(Base_Type
(Ptyp
)))
1557 or else Is_Constrained
(Underlying_Type
(Ptyp
))),
1561 Analyze_And_Resolve
(N
, Standard_Boolean
);
1568 -- Transforms 'Copy_Sign into a call to the floating-point attribute
1569 -- function Copy_Sign in Fat_xxx (where xxx is the root type)
1571 when Attribute_Copy_Sign
=>
1572 Expand_Fpt_Attribute_RR
(N
);
1578 -- Transforms 'Count attribute into a call to the Count function
1580 when Attribute_Count
=> Count
: declare
1582 Conctyp
: Entity_Id
;
1584 Entry_Id
: Entity_Id
;
1589 -- If the prefix is a member of an entry family, retrieve both
1590 -- entry name and index. For a simple entry there is no index.
1592 if Nkind
(Pref
) = N_Indexed_Component
then
1593 Entnam
:= Prefix
(Pref
);
1594 Index
:= First
(Expressions
(Pref
));
1600 Entry_Id
:= Entity
(Entnam
);
1602 -- Find the concurrent type in which this attribute is referenced
1603 -- (there had better be one).
1605 Conctyp
:= Current_Scope
;
1606 while not Is_Concurrent_Type
(Conctyp
) loop
1607 Conctyp
:= Scope
(Conctyp
);
1612 if Is_Protected_Type
(Conctyp
) then
1613 case Corresponding_Runtime_Package
(Conctyp
) is
1614 when System_Tasking_Protected_Objects_Entries
=>
1615 Name
:= New_Reference_To
(RTE
(RE_Protected_Count
), Loc
);
1618 Make_Function_Call
(Loc
,
1620 Parameter_Associations
=> New_List
(
1622 (Find_Protection_Object
(Current_Scope
), Loc
),
1623 Entry_Index_Expression
1624 (Loc
, Entry_Id
, Index
, Scope
(Entry_Id
))));
1626 when System_Tasking_Protected_Objects_Single_Entry
=>
1628 New_Reference_To
(RTE
(RE_Protected_Count_Entry
), Loc
);
1631 Make_Function_Call
(Loc
,
1633 Parameter_Associations
=> New_List
(
1635 (Find_Protection_Object
(Current_Scope
), Loc
)));
1638 raise Program_Error
;
1645 Make_Function_Call
(Loc
,
1646 Name
=> New_Reference_To
(RTE
(RE_Task_Count
), Loc
),
1647 Parameter_Associations
=> New_List
(
1648 Entry_Index_Expression
(Loc
,
1649 Entry_Id
, Index
, Scope
(Entry_Id
))));
1652 -- The call returns type Natural but the context is universal integer
1653 -- so any integer type is allowed. The attribute was already resolved
1654 -- so its Etype is the required result type. If the base type of the
1655 -- context type is other than Standard.Integer we put in a conversion
1656 -- to the required type. This can be a normal typed conversion since
1657 -- both input and output types of the conversion are integer types
1659 if Base_Type
(Typ
) /= Base_Type
(Standard_Integer
) then
1660 Rewrite
(N
, Convert_To
(Typ
, Call
));
1665 Analyze_And_Resolve
(N
, Typ
);
1672 -- This processing is shared by Elab_Spec
1674 -- What we do is to insert the following declarations
1677 -- pragma Import (C, enn, "name___elabb/s");
1679 -- and then the Elab_Body/Spec attribute is replaced by a reference
1680 -- to this defining identifier.
1682 when Attribute_Elab_Body |
1683 Attribute_Elab_Spec
=>
1686 Ent
: constant Entity_Id
:=
1687 Make_Defining_Identifier
(Loc
,
1688 New_Internal_Name
('E'));
1692 procedure Make_Elab_String
(Nod
: Node_Id
);
1693 -- Given Nod, an identifier, or a selected component, put the
1694 -- image into the current string literal, with double underline
1695 -- between components.
1697 ----------------------
1698 -- Make_Elab_String --
1699 ----------------------
1701 procedure Make_Elab_String
(Nod
: Node_Id
) is
1703 if Nkind
(Nod
) = N_Selected_Component
then
1704 Make_Elab_String
(Prefix
(Nod
));
1708 Store_String_Char
('$');
1710 Store_String_Char
('.');
1712 Store_String_Char
('_');
1713 Store_String_Char
('_');
1716 Get_Name_String
(Chars
(Selector_Name
(Nod
)));
1719 pragma Assert
(Nkind
(Nod
) = N_Identifier
);
1720 Get_Name_String
(Chars
(Nod
));
1723 Store_String_Chars
(Name_Buffer
(1 .. Name_Len
));
1724 end Make_Elab_String
;
1726 -- Start of processing for Elab_Body/Elab_Spec
1729 -- First we need to prepare the string literal for the name of
1730 -- the elaboration routine to be referenced.
1733 Make_Elab_String
(Pref
);
1735 if VM_Target
= No_VM
then
1736 Store_String_Chars
("___elab");
1737 Lang
:= Make_Identifier
(Loc
, Name_C
);
1739 Store_String_Chars
("._elab");
1740 Lang
:= Make_Identifier
(Loc
, Name_Ada
);
1743 if Id
= Attribute_Elab_Body
then
1744 Store_String_Char
('b');
1746 Store_String_Char
('s');
1751 Insert_Actions
(N
, New_List
(
1752 Make_Subprogram_Declaration
(Loc
,
1754 Make_Procedure_Specification
(Loc
,
1755 Defining_Unit_Name
=> Ent
)),
1758 Chars
=> Name_Import
,
1759 Pragma_Argument_Associations
=> New_List
(
1760 Make_Pragma_Argument_Association
(Loc
,
1761 Expression
=> Lang
),
1763 Make_Pragma_Argument_Association
(Loc
,
1765 Make_Identifier
(Loc
, Chars
(Ent
))),
1767 Make_Pragma_Argument_Association
(Loc
,
1769 Make_String_Literal
(Loc
, Str
))))));
1771 Set_Entity
(N
, Ent
);
1772 Rewrite
(N
, New_Occurrence_Of
(Ent
, Loc
));
1779 -- Elaborated is always True for preelaborated units, predefined units,
1780 -- pure units and units which have Elaborate_Body pragmas. These units
1781 -- have no elaboration entity.
1783 -- Note: The Elaborated attribute is never passed to the back end
1785 when Attribute_Elaborated
=> Elaborated
: declare
1786 Ent
: constant Entity_Id
:= Entity
(Pref
);
1789 if Present
(Elaboration_Entity
(Ent
)) then
1791 New_Occurrence_Of
(Elaboration_Entity
(Ent
), Loc
));
1793 Rewrite
(N
, New_Occurrence_Of
(Standard_True
, Loc
));
1801 when Attribute_Enum_Rep
=> Enum_Rep
:
1803 -- X'Enum_Rep (Y) expands to
1807 -- This is simply a direct conversion from the enumeration type to
1808 -- the target integer type, which is treated by the back end as a
1809 -- normal integer conversion, treating the enumeration type as an
1810 -- integer, which is exactly what we want! We set Conversion_OK to
1811 -- make sure that the analyzer does not complain about what otherwise
1812 -- might be an illegal conversion.
1814 if Is_Non_Empty_List
(Exprs
) then
1816 OK_Convert_To
(Typ
, Relocate_Node
(First
(Exprs
))));
1818 -- X'Enum_Rep where X is an enumeration literal is replaced by
1819 -- the literal value.
1821 elsif Ekind
(Entity
(Pref
)) = E_Enumeration_Literal
then
1823 Make_Integer_Literal
(Loc
, Enumeration_Rep
(Entity
(Pref
))));
1825 -- If this is a renaming of a literal, recover the representation
1828 elsif Ekind
(Entity
(Pref
)) = E_Constant
1829 and then Present
(Renamed_Object
(Entity
(Pref
)))
1831 Ekind
(Entity
(Renamed_Object
(Entity
(Pref
))))
1832 = E_Enumeration_Literal
1835 Make_Integer_Literal
(Loc
,
1836 Enumeration_Rep
(Entity
(Renamed_Object
(Entity
(Pref
))))));
1838 -- X'Enum_Rep where X is an object does a direct unchecked conversion
1839 -- of the object value, as described for the type case above.
1843 OK_Convert_To
(Typ
, Relocate_Node
(Pref
)));
1847 Analyze_And_Resolve
(N
, Typ
);
1854 when Attribute_Enum_Val
=> Enum_Val
: declare
1856 Btyp
: constant Entity_Id
:= Base_Type
(Ptyp
);
1859 -- X'Enum_Val (Y) expands to
1861 -- [constraint_error when _rep_to_pos (Y, False) = -1, msg]
1864 Expr
:= Unchecked_Convert_To
(Ptyp
, First
(Exprs
));
1867 Make_Raise_Constraint_Error
(Loc
,
1871 Make_Function_Call
(Loc
,
1873 New_Reference_To
(TSS
(Btyp
, TSS_Rep_To_Pos
), Loc
),
1874 Parameter_Associations
=> New_List
(
1875 Relocate_Node
(Duplicate_Subexpr
(Expr
)),
1876 New_Occurrence_Of
(Standard_False
, Loc
))),
1878 Right_Opnd
=> Make_Integer_Literal
(Loc
, -1)),
1879 Reason
=> CE_Range_Check_Failed
));
1882 Analyze_And_Resolve
(N
, Ptyp
);
1889 -- Transforms 'Exponent into a call to the floating-point attribute
1890 -- function Exponent in Fat_xxx (where xxx is the root type)
1892 when Attribute_Exponent
=>
1893 Expand_Fpt_Attribute_R
(N
);
1899 -- transforme X'External_Tag into Ada.Tags.External_Tag (X'tag)
1901 when Attribute_External_Tag
=> External_Tag
:
1904 Make_Function_Call
(Loc
,
1905 Name
=> New_Reference_To
(RTE
(RE_External_Tag
), Loc
),
1906 Parameter_Associations
=> New_List
(
1907 Make_Attribute_Reference
(Loc
,
1908 Attribute_Name
=> Name_Tag
,
1909 Prefix
=> Prefix
(N
)))));
1911 Analyze_And_Resolve
(N
, Standard_String
);
1918 when Attribute_First
=>
1920 -- If the prefix type is a constrained packed array type which
1921 -- already has a Packed_Array_Type representation defined, then
1922 -- replace this attribute with a direct reference to 'First of the
1923 -- appropriate index subtype (since otherwise the back end will try
1924 -- to give us the value of 'First for this implementation type).
1926 if Is_Constrained_Packed_Array
(Ptyp
) then
1928 Make_Attribute_Reference
(Loc
,
1929 Attribute_Name
=> Name_First
,
1930 Prefix
=> New_Reference_To
(Get_Index_Subtype
(N
), Loc
)));
1931 Analyze_And_Resolve
(N
, Typ
);
1933 elsif Is_Access_Type
(Ptyp
) then
1934 Apply_Access_Check
(N
);
1941 -- Compute this if component clause was present, otherwise we leave the
1942 -- computation to be completed in the back-end, since we don't know what
1943 -- layout will be chosen.
1945 when Attribute_First_Bit
=> First_Bit
: declare
1946 CE
: constant Entity_Id
:= Entity
(Selector_Name
(Pref
));
1949 if Known_Static_Component_Bit_Offset
(CE
) then
1951 Make_Integer_Literal
(Loc
,
1952 Component_Bit_Offset
(CE
) mod System_Storage_Unit
));
1954 Analyze_And_Resolve
(N
, Typ
);
1957 Apply_Universal_Integer_Attribute_Checks
(N
);
1967 -- fixtype'Fixed_Value (integer-value)
1971 -- fixtype(integer-value)
1973 -- We do all the required analysis of the conversion here, because we do
1974 -- not want this to go through the fixed-point conversion circuits. Note
1975 -- that the back end always treats fixed-point as equivalent to the
1976 -- corresponding integer type anyway.
1978 when Attribute_Fixed_Value
=> Fixed_Value
:
1981 Make_Type_Conversion
(Loc
,
1982 Subtype_Mark
=> New_Occurrence_Of
(Entity
(Pref
), Loc
),
1983 Expression
=> Relocate_Node
(First
(Exprs
))));
1984 Set_Etype
(N
, Entity
(Pref
));
1987 -- Note: it might appear that a properly analyzed unchecked conversion
1988 -- would be just fine here, but that's not the case, since the full
1989 -- range checks performed by the following call are critical!
1991 Apply_Type_Conversion_Checks
(N
);
1998 -- Transforms 'Floor into a call to the floating-point attribute
1999 -- function Floor in Fat_xxx (where xxx is the root type)
2001 when Attribute_Floor
=>
2002 Expand_Fpt_Attribute_R
(N
);
2008 -- For the fixed-point type Typ:
2014 -- Result_Type (System.Fore (Universal_Real (Type'First)),
2015 -- Universal_Real (Type'Last))
2017 -- Note that we know that the type is a non-static subtype, or Fore
2018 -- would have itself been computed dynamically in Eval_Attribute.
2020 when Attribute_Fore
=> Fore
: begin
2023 Make_Function_Call
(Loc
,
2024 Name
=> New_Reference_To
(RTE
(RE_Fore
), Loc
),
2026 Parameter_Associations
=> New_List
(
2027 Convert_To
(Universal_Real
,
2028 Make_Attribute_Reference
(Loc
,
2029 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
2030 Attribute_Name
=> Name_First
)),
2032 Convert_To
(Universal_Real
,
2033 Make_Attribute_Reference
(Loc
,
2034 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
2035 Attribute_Name
=> Name_Last
))))));
2037 Analyze_And_Resolve
(N
, Typ
);
2044 -- Transforms 'Fraction into a call to the floating-point attribute
2045 -- function Fraction in Fat_xxx (where xxx is the root type)
2047 when Attribute_Fraction
=>
2048 Expand_Fpt_Attribute_R
(N
);
2054 -- For an exception returns a reference to the exception data:
2055 -- Exception_Id!(Prefix'Reference)
2057 -- For a task it returns a reference to the _task_id component of
2058 -- corresponding record:
2060 -- taskV!(Prefix)._Task_Id, converted to the type Task_Id defined
2062 -- in Ada.Task_Identification
2064 when Attribute_Identity
=> Identity
: declare
2065 Id_Kind
: Entity_Id
;
2068 if Ptyp
= Standard_Exception_Type
then
2069 Id_Kind
:= RTE
(RE_Exception_Id
);
2071 if Present
(Renamed_Object
(Entity
(Pref
))) then
2072 Set_Entity
(Pref
, Renamed_Object
(Entity
(Pref
)));
2076 Unchecked_Convert_To
(Id_Kind
, Make_Reference
(Loc
, Pref
)));
2078 Id_Kind
:= RTE
(RO_AT_Task_Id
);
2080 -- If the prefix is a task interface, the Task_Id is obtained
2081 -- dynamically through a dispatching call, as for other task
2082 -- attributes applied to interfaces.
2084 if Ada_Version
>= Ada_05
2085 and then Ekind
(Ptyp
) = E_Class_Wide_Type
2086 and then Is_Interface
(Ptyp
)
2087 and then Is_Task_Interface
(Ptyp
)
2090 Unchecked_Convert_To
(Id_Kind
,
2091 Make_Selected_Component
(Loc
,
2093 New_Copy_Tree
(Pref
),
2095 Make_Identifier
(Loc
, Name_uDisp_Get_Task_Id
))));
2099 Unchecked_Convert_To
(Id_Kind
, Concurrent_Ref
(Pref
)));
2103 Analyze_And_Resolve
(N
, Id_Kind
);
2110 -- Image attribute is handled in separate unit Exp_Imgv
2112 when Attribute_Image
=>
2113 Exp_Imgv
.Expand_Image_Attribute
(N
);
2119 -- X'Img is expanded to typ'Image (X), where typ is the type of X
2121 when Attribute_Img
=> Img
:
2124 Make_Attribute_Reference
(Loc
,
2125 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
2126 Attribute_Name
=> Name_Image
,
2127 Expressions
=> New_List
(Relocate_Node
(Pref
))));
2129 Analyze_And_Resolve
(N
, Standard_String
);
2136 when Attribute_Input
=> Input
: declare
2137 P_Type
: constant Entity_Id
:= Entity
(Pref
);
2138 B_Type
: constant Entity_Id
:= Base_Type
(P_Type
);
2139 U_Type
: constant Entity_Id
:= Underlying_Type
(P_Type
);
2140 Strm
: constant Node_Id
:= First
(Exprs
);
2148 Cntrl
: Node_Id
:= Empty
;
2149 -- Value for controlling argument in call. Always Empty except in
2150 -- the dispatching (class-wide type) case, where it is a reference
2151 -- to the dummy object initialized to the right internal tag.
2153 procedure Freeze_Stream_Subprogram
(F
: Entity_Id
);
2154 -- The expansion of the attribute reference may generate a call to
2155 -- a user-defined stream subprogram that is frozen by the call. This
2156 -- can lead to access-before-elaboration problem if the reference
2157 -- appears in an object declaration and the subprogram body has not
2158 -- been seen. The freezing of the subprogram requires special code
2159 -- because it appears in an expanded context where expressions do
2160 -- not freeze their constituents.
2162 ------------------------------
2163 -- Freeze_Stream_Subprogram --
2164 ------------------------------
2166 procedure Freeze_Stream_Subprogram
(F
: Entity_Id
) is
2167 Decl
: constant Node_Id
:= Unit_Declaration_Node
(F
);
2171 -- If this is user-defined subprogram, the corresponding
2172 -- stream function appears as a renaming-as-body, and the
2173 -- user subprogram must be retrieved by tree traversal.
2176 and then Nkind
(Decl
) = N_Subprogram_Declaration
2177 and then Present
(Corresponding_Body
(Decl
))
2179 Bod
:= Corresponding_Body
(Decl
);
2181 if Nkind
(Unit_Declaration_Node
(Bod
)) =
2182 N_Subprogram_Renaming_Declaration
2184 Set_Is_Frozen
(Entity
(Name
(Unit_Declaration_Node
(Bod
))));
2187 end Freeze_Stream_Subprogram
;
2189 -- Start of processing for Input
2192 -- If no underlying type, we have an error that will be diagnosed
2193 -- elsewhere, so here we just completely ignore the expansion.
2199 -- If there is a TSS for Input, just call it
2201 Fname
:= Find_Stream_Subprogram
(P_Type
, TSS_Stream_Input
);
2203 if Present
(Fname
) then
2207 -- If there is a Stream_Convert pragma, use it, we rewrite
2209 -- sourcetyp'Input (stream)
2213 -- sourcetyp (streamread (strmtyp'Input (stream)));
2215 -- where streamread is the given Read function that converts an
2216 -- argument of type strmtyp to type sourcetyp or a type from which
2217 -- it is derived (extra conversion required for the derived case).
2219 Prag
:= Get_Stream_Convert_Pragma
(P_Type
);
2221 if Present
(Prag
) then
2222 Arg2
:= Next
(First
(Pragma_Argument_Associations
(Prag
)));
2223 Rfunc
:= Entity
(Expression
(Arg2
));
2227 Make_Function_Call
(Loc
,
2228 Name
=> New_Occurrence_Of
(Rfunc
, Loc
),
2229 Parameter_Associations
=> New_List
(
2230 Make_Attribute_Reference
(Loc
,
2233 (Etype
(First_Formal
(Rfunc
)), Loc
),
2234 Attribute_Name
=> Name_Input
,
2235 Expressions
=> Exprs
)))));
2237 Analyze_And_Resolve
(N
, B_Type
);
2242 elsif Is_Elementary_Type
(U_Type
) then
2244 -- A special case arises if we have a defined _Read routine,
2245 -- since in this case we are required to call this routine.
2247 if Present
(TSS
(Base_Type
(U_Type
), TSS_Stream_Read
)) then
2248 Build_Record_Or_Elementary_Input_Function
2249 (Loc
, U_Type
, Decl
, Fname
);
2250 Insert_Action
(N
, Decl
);
2252 -- For normal cases, we call the I_xxx routine directly
2255 Rewrite
(N
, Build_Elementary_Input_Call
(N
));
2256 Analyze_And_Resolve
(N
, P_Type
);
2262 elsif Is_Array_Type
(U_Type
) then
2263 Build_Array_Input_Function
(Loc
, U_Type
, Decl
, Fname
);
2264 Compile_Stream_Body_In_Scope
(N
, Decl
, U_Type
, Check
=> False);
2266 -- Dispatching case with class-wide type
2268 elsif Is_Class_Wide_Type
(P_Type
) then
2270 -- No need to do anything else compiling under restriction
2271 -- No_Dispatching_Calls. During the semantic analysis we
2272 -- already notified such violation.
2274 if Restriction_Active
(No_Dispatching_Calls
) then
2279 Rtyp
: constant Entity_Id
:= Root_Type
(P_Type
);
2284 -- Read the internal tag (RM 13.13.2(34)) and use it to
2285 -- initialize a dummy tag object:
2287 -- Dnn : Ada.Tags.Tag
2288 -- := Descendant_Tag (String'Input (Strm), P_Type);
2290 -- This dummy object is used only to provide a controlling
2291 -- argument for the eventual _Input call. Descendant_Tag is
2292 -- called rather than Internal_Tag to ensure that we have a
2293 -- tag for a type that is descended from the prefix type and
2294 -- declared at the same accessibility level (the exception
2295 -- Tag_Error will be raised otherwise). The level check is
2296 -- required for Ada 2005 because tagged types can be
2297 -- extended in nested scopes (AI-344).
2300 Make_Defining_Identifier
(Loc
,
2301 Chars
=> New_Internal_Name
('D'));
2304 Make_Object_Declaration
(Loc
,
2305 Defining_Identifier
=> Dnn
,
2306 Object_Definition
=>
2307 New_Occurrence_Of
(RTE
(RE_Tag
), Loc
),
2309 Make_Function_Call
(Loc
,
2311 New_Occurrence_Of
(RTE
(RE_Descendant_Tag
), Loc
),
2312 Parameter_Associations
=> New_List
(
2313 Make_Attribute_Reference
(Loc
,
2315 New_Occurrence_Of
(Standard_String
, Loc
),
2316 Attribute_Name
=> Name_Input
,
2317 Expressions
=> New_List
(
2319 (Duplicate_Subexpr
(Strm
)))),
2320 Make_Attribute_Reference
(Loc
,
2321 Prefix
=> New_Reference_To
(P_Type
, Loc
),
2322 Attribute_Name
=> Name_Tag
))));
2324 Insert_Action
(N
, Decl
);
2326 -- Now we need to get the entity for the call, and construct
2327 -- a function call node, where we preset a reference to Dnn
2328 -- as the controlling argument (doing an unchecked convert
2329 -- to the class-wide tagged type to make it look like a real
2332 Fname
:= Find_Prim_Op
(Rtyp
, TSS_Stream_Input
);
2333 Cntrl
:= Unchecked_Convert_To
(P_Type
,
2334 New_Occurrence_Of
(Dnn
, Loc
));
2335 Set_Etype
(Cntrl
, P_Type
);
2336 Set_Parent
(Cntrl
, N
);
2339 -- For tagged types, use the primitive Input function
2341 elsif Is_Tagged_Type
(U_Type
) then
2342 Fname
:= Find_Prim_Op
(U_Type
, TSS_Stream_Input
);
2344 -- All other record type cases, including protected records. The
2345 -- latter only arise for expander generated code for handling
2346 -- shared passive partition access.
2350 (Is_Record_Type
(U_Type
) or else Is_Protected_Type
(U_Type
));
2352 -- Ada 2005 (AI-216): Program_Error is raised executing default
2353 -- implementation of the Input attribute of an unchecked union
2354 -- type if the type lacks default discriminant values.
2356 if Is_Unchecked_Union
(Base_Type
(U_Type
))
2357 and then No
(Discriminant_Constraint
(U_Type
))
2360 Make_Raise_Program_Error
(Loc
,
2361 Reason
=> PE_Unchecked_Union_Restriction
));
2366 Build_Record_Or_Elementary_Input_Function
2367 (Loc
, Base_Type
(U_Type
), Decl
, Fname
);
2368 Insert_Action
(N
, Decl
);
2370 if Nkind
(Parent
(N
)) = N_Object_Declaration
2371 and then Is_Record_Type
(U_Type
)
2373 -- The stream function may contain calls to user-defined
2374 -- Read procedures for individual components.
2381 Comp
:= First_Component
(U_Type
);
2382 while Present
(Comp
) loop
2384 Find_Stream_Subprogram
2385 (Etype
(Comp
), TSS_Stream_Read
);
2387 if Present
(Func
) then
2388 Freeze_Stream_Subprogram
(Func
);
2391 Next_Component
(Comp
);
2398 -- If we fall through, Fname is the function to be called. The result
2399 -- is obtained by calling the appropriate function, then converting
2400 -- the result. The conversion does a subtype check.
2403 Make_Function_Call
(Loc
,
2404 Name
=> New_Occurrence_Of
(Fname
, Loc
),
2405 Parameter_Associations
=> New_List
(
2406 Relocate_Node
(Strm
)));
2408 Set_Controlling_Argument
(Call
, Cntrl
);
2409 Rewrite
(N
, Unchecked_Convert_To
(P_Type
, Call
));
2410 Analyze_And_Resolve
(N
, P_Type
);
2412 if Nkind
(Parent
(N
)) = N_Object_Declaration
then
2413 Freeze_Stream_Subprogram
(Fname
);
2423 -- inttype'Fixed_Value (fixed-value)
2427 -- inttype(integer-value))
2429 -- we do all the required analysis of the conversion here, because we do
2430 -- not want this to go through the fixed-point conversion circuits. Note
2431 -- that the back end always treats fixed-point as equivalent to the
2432 -- corresponding integer type anyway.
2434 when Attribute_Integer_Value
=> Integer_Value
:
2437 Make_Type_Conversion
(Loc
,
2438 Subtype_Mark
=> New_Occurrence_Of
(Entity
(Pref
), Loc
),
2439 Expression
=> Relocate_Node
(First
(Exprs
))));
2440 Set_Etype
(N
, Entity
(Pref
));
2443 -- Note: it might appear that a properly analyzed unchecked conversion
2444 -- would be just fine here, but that's not the case, since the full
2445 -- range checks performed by the following call are critical!
2447 Apply_Type_Conversion_Checks
(N
);
2454 when Attribute_Invalid_Value
=>
2455 Rewrite
(N
, Get_Simple_Init_Val
(Ptyp
, N
));
2461 when Attribute_Last
=>
2463 -- If the prefix type is a constrained packed array type which
2464 -- already has a Packed_Array_Type representation defined, then
2465 -- replace this attribute with a direct reference to 'Last of the
2466 -- appropriate index subtype (since otherwise the back end will try
2467 -- to give us the value of 'Last for this implementation type).
2469 if Is_Constrained_Packed_Array
(Ptyp
) then
2471 Make_Attribute_Reference
(Loc
,
2472 Attribute_Name
=> Name_Last
,
2473 Prefix
=> New_Reference_To
(Get_Index_Subtype
(N
), Loc
)));
2474 Analyze_And_Resolve
(N
, Typ
);
2476 elsif Is_Access_Type
(Ptyp
) then
2477 Apply_Access_Check
(N
);
2484 -- We compute this if a component clause was present, otherwise we leave
2485 -- the computation up to the back end, since we don't know what layout
2488 when Attribute_Last_Bit
=> Last_Bit
: declare
2489 CE
: constant Entity_Id
:= Entity
(Selector_Name
(Pref
));
2492 if Known_Static_Component_Bit_Offset
(CE
)
2493 and then Known_Static_Esize
(CE
)
2496 Make_Integer_Literal
(Loc
,
2497 Intval
=> (Component_Bit_Offset
(CE
) mod System_Storage_Unit
)
2500 Analyze_And_Resolve
(N
, Typ
);
2503 Apply_Universal_Integer_Attribute_Checks
(N
);
2511 -- Transforms 'Leading_Part into a call to the floating-point attribute
2512 -- function Leading_Part in Fat_xxx (where xxx is the root type)
2514 -- Note: strictly, we should generate special case code to deal with
2515 -- absurdly large positive arguments (greater than Integer'Last), which
2516 -- result in returning the first argument unchanged, but it hardly seems
2517 -- worth the effort. We raise constraint error for absurdly negative
2518 -- arguments which is fine.
2520 when Attribute_Leading_Part
=>
2521 Expand_Fpt_Attribute_RI
(N
);
2527 when Attribute_Length
=> declare
2532 -- Processing for packed array types
2534 if Is_Array_Type
(Ptyp
) and then Is_Packed
(Ptyp
) then
2535 Ityp
:= Get_Index_Subtype
(N
);
2537 -- If the index type, Ityp, is an enumeration type with holes,
2538 -- then we calculate X'Length explicitly using
2541 -- (0, Ityp'Pos (X'Last (N)) -
2542 -- Ityp'Pos (X'First (N)) + 1);
2544 -- Since the bounds in the template are the representation values
2545 -- and the back end would get the wrong value.
2547 if Is_Enumeration_Type
(Ityp
)
2548 and then Present
(Enum_Pos_To_Rep
(Base_Type
(Ityp
)))
2553 Xnum
:= Expr_Value
(First
(Expressions
(N
)));
2557 Make_Attribute_Reference
(Loc
,
2558 Prefix
=> New_Occurrence_Of
(Typ
, Loc
),
2559 Attribute_Name
=> Name_Max
,
2560 Expressions
=> New_List
2561 (Make_Integer_Literal
(Loc
, 0),
2565 Make_Op_Subtract
(Loc
,
2567 Make_Attribute_Reference
(Loc
,
2568 Prefix
=> New_Occurrence_Of
(Ityp
, Loc
),
2569 Attribute_Name
=> Name_Pos
,
2571 Expressions
=> New_List
(
2572 Make_Attribute_Reference
(Loc
,
2573 Prefix
=> Duplicate_Subexpr
(Pref
),
2574 Attribute_Name
=> Name_Last
,
2575 Expressions
=> New_List
(
2576 Make_Integer_Literal
(Loc
, Xnum
))))),
2579 Make_Attribute_Reference
(Loc
,
2580 Prefix
=> New_Occurrence_Of
(Ityp
, Loc
),
2581 Attribute_Name
=> Name_Pos
,
2583 Expressions
=> New_List
(
2584 Make_Attribute_Reference
(Loc
,
2586 Duplicate_Subexpr_No_Checks
(Pref
),
2587 Attribute_Name
=> Name_First
,
2588 Expressions
=> New_List
(
2589 Make_Integer_Literal
(Loc
, Xnum
)))))),
2591 Right_Opnd
=> Make_Integer_Literal
(Loc
, 1)))));
2593 Analyze_And_Resolve
(N
, Typ
, Suppress
=> All_Checks
);
2596 -- If the prefix type is a constrained packed array type which
2597 -- already has a Packed_Array_Type representation defined, then
2598 -- replace this attribute with a direct reference to 'Range_Length
2599 -- of the appropriate index subtype (since otherwise the back end
2600 -- will try to give us the value of 'Length for this
2601 -- implementation type).
2603 elsif Is_Constrained
(Ptyp
) then
2605 Make_Attribute_Reference
(Loc
,
2606 Attribute_Name
=> Name_Range_Length
,
2607 Prefix
=> New_Reference_To
(Ityp
, Loc
)));
2608 Analyze_And_Resolve
(N
, Typ
);
2613 elsif Is_Access_Type
(Ptyp
) then
2614 Apply_Access_Check
(N
);
2616 -- If the designated type is a packed array type, then we convert
2617 -- the reference to:
2620 -- xtyp'Pos (Pref'Last (Expr)) -
2621 -- xtyp'Pos (Pref'First (Expr)));
2623 -- This is a bit complex, but it is the easiest thing to do that
2624 -- works in all cases including enum types with holes xtyp here
2625 -- is the appropriate index type.
2628 Dtyp
: constant Entity_Id
:= Designated_Type
(Ptyp
);
2632 if Is_Array_Type
(Dtyp
) and then Is_Packed
(Dtyp
) then
2633 Xtyp
:= Get_Index_Subtype
(N
);
2636 Make_Attribute_Reference
(Loc
,
2637 Prefix
=> New_Occurrence_Of
(Typ
, Loc
),
2638 Attribute_Name
=> Name_Max
,
2639 Expressions
=> New_List
(
2640 Make_Integer_Literal
(Loc
, 0),
2643 Make_Integer_Literal
(Loc
, 1),
2644 Make_Op_Subtract
(Loc
,
2646 Make_Attribute_Reference
(Loc
,
2647 Prefix
=> New_Occurrence_Of
(Xtyp
, Loc
),
2648 Attribute_Name
=> Name_Pos
,
2649 Expressions
=> New_List
(
2650 Make_Attribute_Reference
(Loc
,
2651 Prefix
=> Duplicate_Subexpr
(Pref
),
2652 Attribute_Name
=> Name_Last
,
2654 New_Copy_List
(Exprs
)))),
2657 Make_Attribute_Reference
(Loc
,
2658 Prefix
=> New_Occurrence_Of
(Xtyp
, Loc
),
2659 Attribute_Name
=> Name_Pos
,
2660 Expressions
=> New_List
(
2661 Make_Attribute_Reference
(Loc
,
2663 Duplicate_Subexpr_No_Checks
(Pref
),
2664 Attribute_Name
=> Name_First
,
2666 New_Copy_List
(Exprs
)))))))));
2668 Analyze_And_Resolve
(N
, Typ
);
2672 -- Otherwise leave it to the back end
2675 Apply_Universal_Integer_Attribute_Checks
(N
);
2683 -- Transforms 'Machine into a call to the floating-point attribute
2684 -- function Machine in Fat_xxx (where xxx is the root type)
2686 when Attribute_Machine
=>
2687 Expand_Fpt_Attribute_R
(N
);
2689 ----------------------
2690 -- Machine_Rounding --
2691 ----------------------
2693 -- Transforms 'Machine_Rounding into a call to the floating-point
2694 -- attribute function Machine_Rounding in Fat_xxx (where xxx is the root
2695 -- type). Expansion is avoided for cases the back end can handle
2698 when Attribute_Machine_Rounding
=>
2699 if not Is_Inline_Floating_Point_Attribute
(N
) then
2700 Expand_Fpt_Attribute_R
(N
);
2707 -- Machine_Size is equivalent to Object_Size, so transform it into
2708 -- Object_Size and that way the back end never sees Machine_Size.
2710 when Attribute_Machine_Size
=>
2712 Make_Attribute_Reference
(Loc
,
2713 Prefix
=> Prefix
(N
),
2714 Attribute_Name
=> Name_Object_Size
));
2716 Analyze_And_Resolve
(N
, Typ
);
2722 -- The only case that can get this far is the dynamic case of the old
2723 -- Ada 83 Mantissa attribute for the fixed-point case. For this case,
2730 -- ityp (System.Mantissa.Mantissa_Value
2731 -- (Integer'Integer_Value (typ'First),
2732 -- Integer'Integer_Value (typ'Last)));
2734 when Attribute_Mantissa
=> Mantissa
: begin
2737 Make_Function_Call
(Loc
,
2738 Name
=> New_Occurrence_Of
(RTE
(RE_Mantissa_Value
), Loc
),
2740 Parameter_Associations
=> New_List
(
2742 Make_Attribute_Reference
(Loc
,
2743 Prefix
=> New_Occurrence_Of
(Standard_Integer
, Loc
),
2744 Attribute_Name
=> Name_Integer_Value
,
2745 Expressions
=> New_List
(
2747 Make_Attribute_Reference
(Loc
,
2748 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
2749 Attribute_Name
=> Name_First
))),
2751 Make_Attribute_Reference
(Loc
,
2752 Prefix
=> New_Occurrence_Of
(Standard_Integer
, Loc
),
2753 Attribute_Name
=> Name_Integer_Value
,
2754 Expressions
=> New_List
(
2756 Make_Attribute_Reference
(Loc
,
2757 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
2758 Attribute_Name
=> Name_Last
)))))));
2760 Analyze_And_Resolve
(N
, Typ
);
2763 --------------------
2764 -- Mechanism_Code --
2765 --------------------
2767 when Attribute_Mechanism_Code
=>
2769 -- We must replace the prefix in the renamed case
2771 if Is_Entity_Name
(Pref
)
2772 and then Present
(Alias
(Entity
(Pref
)))
2774 Set_Renamed_Subprogram
(Pref
, Alias
(Entity
(Pref
)));
2781 when Attribute_Mod
=> Mod_Case
: declare
2782 Arg
: constant Node_Id
:= Relocate_Node
(First
(Exprs
));
2783 Hi
: constant Node_Id
:= Type_High_Bound
(Etype
(Arg
));
2784 Modv
: constant Uint
:= Modulus
(Btyp
);
2788 -- This is not so simple. The issue is what type to use for the
2789 -- computation of the modular value.
2791 -- The easy case is when the modulus value is within the bounds
2792 -- of the signed integer type of the argument. In this case we can
2793 -- just do the computation in that signed integer type, and then
2794 -- do an ordinary conversion to the target type.
2796 if Modv
<= Expr_Value
(Hi
) then
2801 Right_Opnd
=> Make_Integer_Literal
(Loc
, Modv
))));
2803 -- Here we know that the modulus is larger than type'Last of the
2804 -- integer type. There are two cases to consider:
2806 -- a) The integer value is non-negative. In this case, it is
2807 -- returned as the result (since it is less than the modulus).
2809 -- b) The integer value is negative. In this case, we know that the
2810 -- result is modulus + value, where the value might be as small as
2811 -- -modulus. The trouble is what type do we use to do the subtract.
2812 -- No type will do, since modulus can be as big as 2**64, and no
2813 -- integer type accommodates this value. Let's do bit of algebra
2816 -- = modulus - (-value)
2817 -- = (modulus - 1) - (-value - 1)
2819 -- Now modulus - 1 is certainly in range of the modular type.
2820 -- -value is in the range 1 .. modulus, so -value -1 is in the
2821 -- range 0 .. modulus-1 which is in range of the modular type.
2822 -- Furthermore, (-value - 1) can be expressed as -(value + 1)
2823 -- which we can compute using the integer base type.
2825 -- Once this is done we analyze the conditional expression without
2826 -- range checks, because we know everything is in range, and we
2827 -- want to prevent spurious warnings on either branch.
2831 Make_Conditional_Expression
(Loc
,
2832 Expressions
=> New_List
(
2834 Left_Opnd
=> Duplicate_Subexpr
(Arg
),
2835 Right_Opnd
=> Make_Integer_Literal
(Loc
, 0)),
2838 Duplicate_Subexpr_No_Checks
(Arg
)),
2840 Make_Op_Subtract
(Loc
,
2842 Make_Integer_Literal
(Loc
,
2843 Intval
=> Modv
- 1),
2849 Left_Opnd
=> Duplicate_Subexpr_No_Checks
(Arg
),
2851 Make_Integer_Literal
(Loc
,
2852 Intval
=> 1))))))));
2856 Analyze_And_Resolve
(N
, Btyp
, Suppress
=> All_Checks
);
2863 -- Transforms 'Model into a call to the floating-point attribute
2864 -- function Model in Fat_xxx (where xxx is the root type)
2866 when Attribute_Model
=>
2867 Expand_Fpt_Attribute_R
(N
);
2873 -- The processing for Object_Size shares the processing for Size
2879 when Attribute_Old
=> Old
: declare
2880 Tnn
: constant Entity_Id
:=
2881 Make_Defining_Identifier
(Loc
,
2882 Chars
=> New_Internal_Name
('T'));
2887 -- Find the nearest subprogram body, ignoring _Preconditions
2891 Subp
:= Parent
(Subp
);
2892 exit when Nkind
(Subp
) = N_Subprogram_Body
2893 and then Chars
(Defining_Entity
(Subp
)) /= Name_uPostconditions
;
2896 -- Insert the assignment at the start of the declarations
2899 Make_Object_Declaration
(Loc
,
2900 Defining_Identifier
=> Tnn
,
2901 Constant_Present
=> True,
2902 Object_Definition
=> New_Occurrence_Of
(Etype
(N
), Loc
),
2903 Expression
=> Pref
);
2905 if Is_Empty_List
(Declarations
(Subp
)) then
2906 Set_Declarations
(Subp
, New_List
(Asn_Stm
));
2909 Insert_Action
(First
(Declarations
(Subp
)), Asn_Stm
);
2912 Rewrite
(N
, New_Occurrence_Of
(Tnn
, Loc
));
2919 when Attribute_Output
=> Output
: declare
2920 P_Type
: constant Entity_Id
:= Entity
(Pref
);
2921 U_Type
: constant Entity_Id
:= Underlying_Type
(P_Type
);
2929 -- If no underlying type, we have an error that will be diagnosed
2930 -- elsewhere, so here we just completely ignore the expansion.
2936 -- If TSS for Output is present, just call it
2938 Pname
:= Find_Stream_Subprogram
(P_Type
, TSS_Stream_Output
);
2940 if Present
(Pname
) then
2944 -- If there is a Stream_Convert pragma, use it, we rewrite
2946 -- sourcetyp'Output (stream, Item)
2950 -- strmtyp'Output (Stream, strmwrite (acttyp (Item)));
2952 -- where strmwrite is the given Write function that converts an
2953 -- argument of type sourcetyp or a type acctyp, from which it is
2954 -- derived to type strmtyp. The conversion to acttyp is required
2955 -- for the derived case.
2957 Prag
:= Get_Stream_Convert_Pragma
(P_Type
);
2959 if Present
(Prag
) then
2961 Next
(Next
(First
(Pragma_Argument_Associations
(Prag
))));
2962 Wfunc
:= Entity
(Expression
(Arg3
));
2965 Make_Attribute_Reference
(Loc
,
2966 Prefix
=> New_Occurrence_Of
(Etype
(Wfunc
), Loc
),
2967 Attribute_Name
=> Name_Output
,
2968 Expressions
=> New_List
(
2969 Relocate_Node
(First
(Exprs
)),
2970 Make_Function_Call
(Loc
,
2971 Name
=> New_Occurrence_Of
(Wfunc
, Loc
),
2972 Parameter_Associations
=> New_List
(
2973 OK_Convert_To
(Etype
(First_Formal
(Wfunc
)),
2974 Relocate_Node
(Next
(First
(Exprs
)))))))));
2979 -- For elementary types, we call the W_xxx routine directly.
2980 -- Note that the effect of Write and Output is identical for
2981 -- the case of an elementary type, since there are no
2982 -- discriminants or bounds.
2984 elsif Is_Elementary_Type
(U_Type
) then
2986 -- A special case arises if we have a defined _Write routine,
2987 -- since in this case we are required to call this routine.
2989 if Present
(TSS
(Base_Type
(U_Type
), TSS_Stream_Write
)) then
2990 Build_Record_Or_Elementary_Output_Procedure
2991 (Loc
, U_Type
, Decl
, Pname
);
2992 Insert_Action
(N
, Decl
);
2994 -- For normal cases, we call the W_xxx routine directly
2997 Rewrite
(N
, Build_Elementary_Write_Call
(N
));
3004 elsif Is_Array_Type
(U_Type
) then
3005 Build_Array_Output_Procedure
(Loc
, U_Type
, Decl
, Pname
);
3006 Compile_Stream_Body_In_Scope
(N
, Decl
, U_Type
, Check
=> False);
3008 -- Class-wide case, first output external tag, then dispatch
3009 -- to the appropriate primitive Output function (RM 13.13.2(31)).
3011 elsif Is_Class_Wide_Type
(P_Type
) then
3013 -- No need to do anything else compiling under restriction
3014 -- No_Dispatching_Calls. During the semantic analysis we
3015 -- already notified such violation.
3017 if Restriction_Active
(No_Dispatching_Calls
) then
3022 Strm
: constant Node_Id
:= First
(Exprs
);
3023 Item
: constant Node_Id
:= Next
(Strm
);
3026 -- Ada 2005 (AI-344): Check that the accessibility level
3027 -- of the type of the output object is not deeper than
3028 -- that of the attribute's prefix type.
3030 -- if Get_Access_Level (Item'Tag)
3031 -- /= Get_Access_Level (P_Type'Tag)
3036 -- String'Output (Strm, External_Tag (Item'Tag));
3038 -- We cannot figure out a practical way to implement this
3039 -- accessibility check on virtual machines, so we omit it.
3041 if Ada_Version
>= Ada_05
3042 and then VM_Target
= No_VM
3045 Make_Implicit_If_Statement
(N
,
3049 Build_Get_Access_Level
(Loc
,
3050 Make_Attribute_Reference
(Loc
,
3053 Duplicate_Subexpr
(Item
,
3055 Attribute_Name
=> Name_Tag
)),
3058 Make_Integer_Literal
(Loc
,
3059 Type_Access_Level
(P_Type
))),
3062 New_List
(Make_Raise_Statement
(Loc
,
3064 RTE
(RE_Tag_Error
), Loc
)))));
3068 Make_Attribute_Reference
(Loc
,
3069 Prefix
=> New_Occurrence_Of
(Standard_String
, Loc
),
3070 Attribute_Name
=> Name_Output
,
3071 Expressions
=> New_List
(
3072 Relocate_Node
(Duplicate_Subexpr
(Strm
)),
3073 Make_Function_Call
(Loc
,
3075 New_Occurrence_Of
(RTE
(RE_External_Tag
), Loc
),
3076 Parameter_Associations
=> New_List
(
3077 Make_Attribute_Reference
(Loc
,
3080 (Duplicate_Subexpr
(Item
, Name_Req
=> True)),
3081 Attribute_Name
=> Name_Tag
))))));
3084 Pname
:= Find_Prim_Op
(U_Type
, TSS_Stream_Output
);
3086 -- Tagged type case, use the primitive Output function
3088 elsif Is_Tagged_Type
(U_Type
) then
3089 Pname
:= Find_Prim_Op
(U_Type
, TSS_Stream_Output
);
3091 -- All other record type cases, including protected records.
3092 -- The latter only arise for expander generated code for
3093 -- handling shared passive partition access.
3097 (Is_Record_Type
(U_Type
) or else Is_Protected_Type
(U_Type
));
3099 -- Ada 2005 (AI-216): Program_Error is raised when executing
3100 -- the default implementation of the Output attribute of an
3101 -- unchecked union type if the type lacks default discriminant
3104 if Is_Unchecked_Union
(Base_Type
(U_Type
))
3105 and then No
(Discriminant_Constraint
(U_Type
))
3108 Make_Raise_Program_Error
(Loc
,
3109 Reason
=> PE_Unchecked_Union_Restriction
));
3114 Build_Record_Or_Elementary_Output_Procedure
3115 (Loc
, Base_Type
(U_Type
), Decl
, Pname
);
3116 Insert_Action
(N
, Decl
);
3120 -- If we fall through, Pname is the name of the procedure to call
3122 Rewrite_Stream_Proc_Call
(Pname
);
3129 -- For enumeration types with a standard representation, Pos is
3130 -- handled by the back end.
3132 -- For enumeration types, with a non-standard representation we
3133 -- generate a call to the _Rep_To_Pos function created when the
3134 -- type was frozen. The call has the form
3136 -- _rep_to_pos (expr, flag)
3138 -- The parameter flag is True if range checks are enabled, causing
3139 -- Program_Error to be raised if the expression has an invalid
3140 -- representation, and False if range checks are suppressed.
3142 -- For integer types, Pos is equivalent to a simple integer
3143 -- conversion and we rewrite it as such
3145 when Attribute_Pos
=> Pos
:
3147 Etyp
: Entity_Id
:= Base_Type
(Entity
(Pref
));
3150 -- Deal with zero/non-zero boolean values
3152 if Is_Boolean_Type
(Etyp
) then
3153 Adjust_Condition
(First
(Exprs
));
3154 Etyp
:= Standard_Boolean
;
3155 Set_Prefix
(N
, New_Occurrence_Of
(Standard_Boolean
, Loc
));
3158 -- Case of enumeration type
3160 if Is_Enumeration_Type
(Etyp
) then
3162 -- Non-standard enumeration type (generate call)
3164 if Present
(Enum_Pos_To_Rep
(Etyp
)) then
3165 Append_To
(Exprs
, Rep_To_Pos_Flag
(Etyp
, Loc
));
3168 Make_Function_Call
(Loc
,
3170 New_Reference_To
(TSS
(Etyp
, TSS_Rep_To_Pos
), Loc
),
3171 Parameter_Associations
=> Exprs
)));
3173 Analyze_And_Resolve
(N
, Typ
);
3175 -- Standard enumeration type (do universal integer check)
3178 Apply_Universal_Integer_Attribute_Checks
(N
);
3181 -- Deal with integer types (replace by conversion)
3183 elsif Is_Integer_Type
(Etyp
) then
3184 Rewrite
(N
, Convert_To
(Typ
, First
(Exprs
)));
3185 Analyze_And_Resolve
(N
, Typ
);
3194 -- We compute this if a component clause was present, otherwise we leave
3195 -- the computation up to the back end, since we don't know what layout
3198 when Attribute_Position
=> Position
:
3200 CE
: constant Entity_Id
:= Entity
(Selector_Name
(Pref
));
3203 if Present
(Component_Clause
(CE
)) then
3205 Make_Integer_Literal
(Loc
,
3206 Intval
=> Component_Bit_Offset
(CE
) / System_Storage_Unit
));
3207 Analyze_And_Resolve
(N
, Typ
);
3210 Apply_Universal_Integer_Attribute_Checks
(N
);
3218 -- 1. Deal with enumeration types with holes
3219 -- 2. For floating-point, generate call to attribute function
3220 -- 3. For other cases, deal with constraint checking
3222 when Attribute_Pred
=> Pred
:
3224 Etyp
: constant Entity_Id
:= Base_Type
(Ptyp
);
3228 -- For enumeration types with non-standard representations, we
3229 -- expand typ'Pred (x) into
3231 -- Pos_To_Rep (Rep_To_Pos (x) - 1)
3233 -- If the representation is contiguous, we compute instead
3234 -- Lit1 + Rep_to_Pos (x -1), to catch invalid representations.
3235 -- The conversion function Enum_Pos_To_Rep is defined on the
3236 -- base type, not the subtype, so we have to use the base type
3237 -- explicitly for this and other enumeration attributes.
3239 if Is_Enumeration_Type
(Ptyp
)
3240 and then Present
(Enum_Pos_To_Rep
(Etyp
))
3242 if Has_Contiguous_Rep
(Etyp
) then
3244 Unchecked_Convert_To
(Ptyp
,
3247 Make_Integer_Literal
(Loc
,
3248 Enumeration_Rep
(First_Literal
(Ptyp
))),
3250 Make_Function_Call
(Loc
,
3253 (TSS
(Etyp
, TSS_Rep_To_Pos
), Loc
),
3255 Parameter_Associations
=>
3257 Unchecked_Convert_To
(Ptyp
,
3258 Make_Op_Subtract
(Loc
,
3260 Unchecked_Convert_To
(Standard_Integer
,
3261 Relocate_Node
(First
(Exprs
))),
3263 Make_Integer_Literal
(Loc
, 1))),
3264 Rep_To_Pos_Flag
(Ptyp
, Loc
))))));
3267 -- Add Boolean parameter True, to request program errror if
3268 -- we have a bad representation on our hands. If checks are
3269 -- suppressed, then add False instead
3271 Append_To
(Exprs
, Rep_To_Pos_Flag
(Ptyp
, Loc
));
3273 Make_Indexed_Component
(Loc
,
3276 (Enum_Pos_To_Rep
(Etyp
), Loc
),
3277 Expressions
=> New_List
(
3278 Make_Op_Subtract
(Loc
,
3280 Make_Function_Call
(Loc
,
3283 (TSS
(Etyp
, TSS_Rep_To_Pos
), Loc
),
3284 Parameter_Associations
=> Exprs
),
3285 Right_Opnd
=> Make_Integer_Literal
(Loc
, 1)))));
3288 Analyze_And_Resolve
(N
, Typ
);
3290 -- For floating-point, we transform 'Pred into a call to the Pred
3291 -- floating-point attribute function in Fat_xxx (xxx is root type)
3293 elsif Is_Floating_Point_Type
(Ptyp
) then
3294 Expand_Fpt_Attribute_R
(N
);
3295 Analyze_And_Resolve
(N
, Typ
);
3297 -- For modular types, nothing to do (no overflow, since wraps)
3299 elsif Is_Modular_Integer_Type
(Ptyp
) then
3302 -- For other types, if range checking is enabled, we must generate
3303 -- a check if overflow checking is enabled.
3305 elsif not Overflow_Checks_Suppressed
(Ptyp
) then
3306 Expand_Pred_Succ
(N
);
3314 -- Ada 2005 (AI-327): Dynamic ceiling priorities
3316 -- We rewrite X'Priority as the following run-time call:
3318 -- Get_Ceiling (X._Object)
3320 -- Note that although X'Priority is notionally an object, it is quite
3321 -- deliberately not defined as an aliased object in the RM. This means
3322 -- that it works fine to rewrite it as a call, without having to worry
3323 -- about complications that would other arise from X'Priority'Access,
3324 -- which is illegal, because of the lack of aliasing.
3326 when Attribute_Priority
=>
3329 Conctyp
: Entity_Id
;
3330 Object_Parm
: Node_Id
;
3332 RT_Subprg_Name
: Node_Id
;
3335 -- Look for the enclosing concurrent type
3337 Conctyp
:= Current_Scope
;
3338 while not Is_Concurrent_Type
(Conctyp
) loop
3339 Conctyp
:= Scope
(Conctyp
);
3342 pragma Assert
(Is_Protected_Type
(Conctyp
));
3344 -- Generate the actual of the call
3346 Subprg
:= Current_Scope
;
3347 while not Present
(Protected_Body_Subprogram
(Subprg
)) loop
3348 Subprg
:= Scope
(Subprg
);
3351 -- Use of 'Priority inside protected entries and barriers (in
3352 -- both cases the type of the first formal of their expanded
3353 -- subprogram is Address)
3355 if Etype
(First_Entity
(Protected_Body_Subprogram
(Subprg
)))
3359 New_Itype
: Entity_Id
;
3362 -- In the expansion of protected entries the type of the
3363 -- first formal of the Protected_Body_Subprogram is an
3364 -- Address. In order to reference the _object component
3367 -- type T is access p__ptTV;
3370 New_Itype
:= Create_Itype
(E_Access_Type
, N
);
3371 Set_Etype
(New_Itype
, New_Itype
);
3372 Set_Directly_Designated_Type
(New_Itype
,
3373 Corresponding_Record_Type
(Conctyp
));
3374 Freeze_Itype
(New_Itype
, N
);
3377 -- T!(O)._object'unchecked_access
3380 Make_Attribute_Reference
(Loc
,
3382 Make_Selected_Component
(Loc
,
3384 Unchecked_Convert_To
(New_Itype
,
3387 (Protected_Body_Subprogram
(Subprg
)),
3390 Make_Identifier
(Loc
, Name_uObject
)),
3391 Attribute_Name
=> Name_Unchecked_Access
);
3394 -- Use of 'Priority inside a protected subprogram
3398 Make_Attribute_Reference
(Loc
,
3400 Make_Selected_Component
(Loc
,
3401 Prefix
=> New_Reference_To
3403 (Protected_Body_Subprogram
(Subprg
)),
3406 Make_Identifier
(Loc
, Name_uObject
)),
3407 Attribute_Name
=> Name_Unchecked_Access
);
3410 -- Select the appropriate run-time subprogram
3412 if Number_Entries
(Conctyp
) = 0 then
3414 New_Reference_To
(RTE
(RE_Get_Ceiling
), Loc
);
3417 New_Reference_To
(RTE
(RO_PE_Get_Ceiling
), Loc
);
3421 Make_Function_Call
(Loc
,
3422 Name
=> RT_Subprg_Name
,
3423 Parameter_Associations
=> New_List
(Object_Parm
));
3427 -- Avoid the generation of extra checks on the pointer to the
3428 -- protected object.
3430 Analyze_And_Resolve
(N
, Typ
, Suppress
=> Access_Check
);
3437 when Attribute_Range_Length
=> Range_Length
: begin
3438 -- The only special processing required is for the case where
3439 -- Range_Length is applied to an enumeration type with holes.
3440 -- In this case we transform
3446 -- X'Pos (X'Last) - X'Pos (X'First) + 1
3448 -- So that the result reflects the proper Pos values instead
3449 -- of the underlying representations.
3451 if Is_Enumeration_Type
(Ptyp
)
3452 and then Has_Non_Standard_Rep
(Ptyp
)
3457 Make_Op_Subtract
(Loc
,
3459 Make_Attribute_Reference
(Loc
,
3460 Attribute_Name
=> Name_Pos
,
3461 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
3462 Expressions
=> New_List
(
3463 Make_Attribute_Reference
(Loc
,
3464 Attribute_Name
=> Name_Last
,
3465 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
)))),
3468 Make_Attribute_Reference
(Loc
,
3469 Attribute_Name
=> Name_Pos
,
3470 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
3471 Expressions
=> New_List
(
3472 Make_Attribute_Reference
(Loc
,
3473 Attribute_Name
=> Name_First
,
3474 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
))))),
3477 Make_Integer_Literal
(Loc
, 1)));
3479 Analyze_And_Resolve
(N
, Typ
);
3481 -- For all other cases, the attribute is handled by the back end, but
3482 -- we need to deal with the case of the range check on a universal
3486 Apply_Universal_Integer_Attribute_Checks
(N
);
3494 when Attribute_Read
=> Read
: declare
3495 P_Type
: constant Entity_Id
:= Entity
(Pref
);
3496 B_Type
: constant Entity_Id
:= Base_Type
(P_Type
);
3497 U_Type
: constant Entity_Id
:= Underlying_Type
(P_Type
);
3507 -- If no underlying type, we have an error that will be diagnosed
3508 -- elsewhere, so here we just completely ignore the expansion.
3514 -- The simple case, if there is a TSS for Read, just call it
3516 Pname
:= Find_Stream_Subprogram
(P_Type
, TSS_Stream_Read
);
3518 if Present
(Pname
) then
3522 -- If there is a Stream_Convert pragma, use it, we rewrite
3524 -- sourcetyp'Read (stream, Item)
3528 -- Item := sourcetyp (strmread (strmtyp'Input (Stream)));
3530 -- where strmread is the given Read function that converts an
3531 -- argument of type strmtyp to type sourcetyp or a type from which
3532 -- it is derived. The conversion to sourcetyp is required in the
3535 -- A special case arises if Item is a type conversion in which
3536 -- case, we have to expand to:
3538 -- Itemx := typex (strmread (strmtyp'Input (Stream)));
3540 -- where Itemx is the expression of the type conversion (i.e.
3541 -- the actual object), and typex is the type of Itemx.
3543 Prag
:= Get_Stream_Convert_Pragma
(P_Type
);
3545 if Present
(Prag
) then
3546 Arg2
:= Next
(First
(Pragma_Argument_Associations
(Prag
)));
3547 Rfunc
:= Entity
(Expression
(Arg2
));
3548 Lhs
:= Relocate_Node
(Next
(First
(Exprs
)));
3550 OK_Convert_To
(B_Type
,
3551 Make_Function_Call
(Loc
,
3552 Name
=> New_Occurrence_Of
(Rfunc
, Loc
),
3553 Parameter_Associations
=> New_List
(
3554 Make_Attribute_Reference
(Loc
,
3557 (Etype
(First_Formal
(Rfunc
)), Loc
),
3558 Attribute_Name
=> Name_Input
,
3559 Expressions
=> New_List
(
3560 Relocate_Node
(First
(Exprs
)))))));
3562 if Nkind
(Lhs
) = N_Type_Conversion
then
3563 Lhs
:= Expression
(Lhs
);
3564 Rhs
:= Convert_To
(Etype
(Lhs
), Rhs
);
3568 Make_Assignment_Statement
(Loc
,
3570 Expression
=> Rhs
));
3571 Set_Assignment_OK
(Lhs
);
3575 -- For elementary types, we call the I_xxx routine using the first
3576 -- parameter and then assign the result into the second parameter.
3577 -- We set Assignment_OK to deal with the conversion case.
3579 elsif Is_Elementary_Type
(U_Type
) then
3585 Lhs
:= Relocate_Node
(Next
(First
(Exprs
)));
3586 Rhs
:= Build_Elementary_Input_Call
(N
);
3588 if Nkind
(Lhs
) = N_Type_Conversion
then
3589 Lhs
:= Expression
(Lhs
);
3590 Rhs
:= Convert_To
(Etype
(Lhs
), Rhs
);
3593 Set_Assignment_OK
(Lhs
);
3596 Make_Assignment_Statement
(Loc
,
3598 Expression
=> Rhs
));
3606 elsif Is_Array_Type
(U_Type
) then
3607 Build_Array_Read_Procedure
(N
, U_Type
, Decl
, Pname
);
3608 Compile_Stream_Body_In_Scope
(N
, Decl
, U_Type
, Check
=> False);
3610 -- Tagged type case, use the primitive Read function. Note that
3611 -- this will dispatch in the class-wide case which is what we want
3613 elsif Is_Tagged_Type
(U_Type
) then
3614 Pname
:= Find_Prim_Op
(U_Type
, TSS_Stream_Read
);
3616 -- All other record type cases, including protected records. The
3617 -- latter only arise for expander generated code for handling
3618 -- shared passive partition access.
3622 (Is_Record_Type
(U_Type
) or else Is_Protected_Type
(U_Type
));
3624 -- Ada 2005 (AI-216): Program_Error is raised when executing
3625 -- the default implementation of the Read attribute of an
3626 -- Unchecked_Union type.
3628 if Is_Unchecked_Union
(Base_Type
(U_Type
)) then
3630 Make_Raise_Program_Error
(Loc
,
3631 Reason
=> PE_Unchecked_Union_Restriction
));
3634 if Has_Discriminants
(U_Type
)
3636 (Discriminant_Default_Value
(First_Discriminant
(U_Type
)))
3638 Build_Mutable_Record_Read_Procedure
3639 (Loc
, Base_Type
(U_Type
), Decl
, Pname
);
3641 Build_Record_Read_Procedure
3642 (Loc
, Base_Type
(U_Type
), Decl
, Pname
);
3645 -- Suppress checks, uninitialized or otherwise invalid
3646 -- data does not cause constraint errors to be raised for
3647 -- a complete record read.
3649 Insert_Action
(N
, Decl
, All_Checks
);
3653 Rewrite_Stream_Proc_Call
(Pname
);
3660 -- Transforms 'Remainder into a call to the floating-point attribute
3661 -- function Remainder in Fat_xxx (where xxx is the root type)
3663 when Attribute_Remainder
=>
3664 Expand_Fpt_Attribute_RR
(N
);
3670 -- Transform 'Result into reference to _Result formal. At the point
3671 -- where a legal 'Result attribute is expanded, we know that we are in
3672 -- the context of a _Postcondition function with a _Result parameter.
3674 when Attribute_Result
=>
3676 Make_Identifier
(Loc
,
3677 Chars
=> Name_uResult
));
3678 Analyze_And_Resolve
(N
, Typ
);
3684 -- The handling of the Round attribute is quite delicate. The processing
3685 -- in Sem_Attr introduced a conversion to universal real, reflecting the
3686 -- semantics of Round, but we do not want anything to do with universal
3687 -- real at runtime, since this corresponds to using floating-point
3690 -- What we have now is that the Etype of the Round attribute correctly
3691 -- indicates the final result type. The operand of the Round is the
3692 -- conversion to universal real, described above, and the operand of
3693 -- this conversion is the actual operand of Round, which may be the
3694 -- special case of a fixed point multiplication or division (Etype =
3697 -- The exapander will expand first the operand of the conversion, then
3698 -- the conversion, and finally the round attribute itself, since we
3699 -- always work inside out. But we cannot simply process naively in this
3700 -- order. In the semantic world where universal fixed and real really
3701 -- exist and have infinite precision, there is no problem, but in the
3702 -- implementation world, where universal real is a floating-point type,
3703 -- we would get the wrong result.
3705 -- So the approach is as follows. First, when expanding a multiply or
3706 -- divide whose type is universal fixed, we do nothing at all, instead
3707 -- deferring the operation till later.
3709 -- The actual processing is done in Expand_N_Type_Conversion which
3710 -- handles the special case of Round by looking at its parent to see if
3711 -- it is a Round attribute, and if it is, handling the conversion (or
3712 -- its fixed multiply/divide child) in an appropriate manner.
3714 -- This means that by the time we get to expanding the Round attribute
3715 -- itself, the Round is nothing more than a type conversion (and will
3716 -- often be a null type conversion), so we just replace it with the
3717 -- appropriate conversion operation.
3719 when Attribute_Round
=>
3721 Convert_To
(Etype
(N
), Relocate_Node
(First
(Exprs
))));
3722 Analyze_And_Resolve
(N
);
3728 -- Transforms 'Rounding into a call to the floating-point attribute
3729 -- function Rounding in Fat_xxx (where xxx is the root type)
3731 when Attribute_Rounding
=>
3732 Expand_Fpt_Attribute_R
(N
);
3738 -- Transforms 'Scaling into a call to the floating-point attribute
3739 -- function Scaling in Fat_xxx (where xxx is the root type)
3741 when Attribute_Scaling
=>
3742 Expand_Fpt_Attribute_RI
(N
);
3748 when Attribute_Size |
3749 Attribute_Object_Size |
3750 Attribute_Value_Size |
3751 Attribute_VADS_Size
=> Size
:
3758 -- Processing for VADS_Size case. Note that this processing removes
3759 -- all traces of VADS_Size from the tree, and completes all required
3760 -- processing for VADS_Size by translating the attribute reference
3761 -- to an appropriate Size or Object_Size reference.
3763 if Id
= Attribute_VADS_Size
3764 or else (Use_VADS_Size
and then Id
= Attribute_Size
)
3766 -- If the size is specified, then we simply use the specified
3767 -- size. This applies to both types and objects. The size of an
3768 -- object can be specified in the following ways:
3770 -- An explicit size object is given for an object
3771 -- A component size is specified for an indexed component
3772 -- A component clause is specified for a selected component
3773 -- The object is a component of a packed composite object
3775 -- If the size is specified, then VADS_Size of an object
3777 if (Is_Entity_Name
(Pref
)
3778 and then Present
(Size_Clause
(Entity
(Pref
))))
3780 (Nkind
(Pref
) = N_Component_Clause
3781 and then (Present
(Component_Clause
3782 (Entity
(Selector_Name
(Pref
))))
3783 or else Is_Packed
(Etype
(Prefix
(Pref
)))))
3785 (Nkind
(Pref
) = N_Indexed_Component
3786 and then (Component_Size
(Etype
(Prefix
(Pref
))) /= 0
3787 or else Is_Packed
(Etype
(Prefix
(Pref
)))))
3789 Set_Attribute_Name
(N
, Name_Size
);
3791 -- Otherwise if we have an object rather than a type, then the
3792 -- VADS_Size attribute applies to the type of the object, rather
3793 -- than the object itself. This is one of the respects in which
3794 -- VADS_Size differs from Size.
3797 if (not Is_Entity_Name
(Pref
)
3798 or else not Is_Type
(Entity
(Pref
)))
3799 and then (Is_Scalar_Type
(Ptyp
) or else Is_Constrained
(Ptyp
))
3801 Rewrite
(Pref
, New_Occurrence_Of
(Ptyp
, Loc
));
3804 -- For a scalar type for which no size was explicitly given,
3805 -- VADS_Size means Object_Size. This is the other respect in
3806 -- which VADS_Size differs from Size.
3808 if Is_Scalar_Type
(Ptyp
) and then No
(Size_Clause
(Ptyp
)) then
3809 Set_Attribute_Name
(N
, Name_Object_Size
);
3811 -- In all other cases, Size and VADS_Size are the sane
3814 Set_Attribute_Name
(N
, Name_Size
);
3819 -- For class-wide types, X'Class'Size is transformed into a direct
3820 -- reference to the Size of the class type, so that the back end does
3821 -- not have to deal with the X'Class'Size reference.
3823 if Is_Entity_Name
(Pref
)
3824 and then Is_Class_Wide_Type
(Entity
(Pref
))
3826 Rewrite
(Prefix
(N
), New_Occurrence_Of
(Entity
(Pref
), Loc
));
3829 -- For X'Size applied to an object of a class-wide type, transform
3830 -- X'Size into a call to the primitive operation _Size applied to X.
3832 elsif Is_Class_Wide_Type
(Ptyp
) then
3834 -- No need to do anything else compiling under restriction
3835 -- No_Dispatching_Calls. During the semantic analysis we
3836 -- already notified such violation.
3838 if Restriction_Active
(No_Dispatching_Calls
) then
3843 Make_Function_Call
(Loc
,
3844 Name
=> New_Reference_To
3845 (Find_Prim_Op
(Ptyp
, Name_uSize
), Loc
),
3846 Parameter_Associations
=> New_List
(Pref
));
3848 if Typ
/= Standard_Long_Long_Integer
then
3850 -- The context is a specific integer type with which the
3851 -- original attribute was compatible. The function has a
3852 -- specific type as well, so to preserve the compatibility
3853 -- we must convert explicitly.
3855 New_Node
:= Convert_To
(Typ
, New_Node
);
3858 Rewrite
(N
, New_Node
);
3859 Analyze_And_Resolve
(N
, Typ
);
3862 -- Case of known RM_Size of a type
3864 elsif (Id
= Attribute_Size
or else Id
= Attribute_Value_Size
)
3865 and then Is_Entity_Name
(Pref
)
3866 and then Is_Type
(Entity
(Pref
))
3867 and then Known_Static_RM_Size
(Entity
(Pref
))
3869 Siz
:= RM_Size
(Entity
(Pref
));
3871 -- Case of known Esize of a type
3873 elsif Id
= Attribute_Object_Size
3874 and then Is_Entity_Name
(Pref
)
3875 and then Is_Type
(Entity
(Pref
))
3876 and then Known_Static_Esize
(Entity
(Pref
))
3878 Siz
:= Esize
(Entity
(Pref
));
3880 -- Case of known size of object
3882 elsif Id
= Attribute_Size
3883 and then Is_Entity_Name
(Pref
)
3884 and then Is_Object
(Entity
(Pref
))
3885 and then Known_Esize
(Entity
(Pref
))
3886 and then Known_Static_Esize
(Entity
(Pref
))
3888 Siz
:= Esize
(Entity
(Pref
));
3890 -- For an array component, we can do Size in the front end
3891 -- if the component_size of the array is set.
3893 elsif Nkind
(Pref
) = N_Indexed_Component
then
3894 Siz
:= Component_Size
(Etype
(Prefix
(Pref
)));
3896 -- For a record component, we can do Size in the front end if there
3897 -- is a component clause, or if the record is packed and the
3898 -- component's size is known at compile time.
3900 elsif Nkind
(Pref
) = N_Selected_Component
then
3902 Rec
: constant Entity_Id
:= Etype
(Prefix
(Pref
));
3903 Comp
: constant Entity_Id
:= Entity
(Selector_Name
(Pref
));
3906 if Present
(Component_Clause
(Comp
)) then
3907 Siz
:= Esize
(Comp
);
3909 elsif Is_Packed
(Rec
) then
3910 Siz
:= RM_Size
(Ptyp
);
3913 Apply_Universal_Integer_Attribute_Checks
(N
);
3918 -- All other cases are handled by the back end
3921 Apply_Universal_Integer_Attribute_Checks
(N
);
3923 -- If Size is applied to a formal parameter that is of a packed
3924 -- array subtype, then apply Size to the actual subtype.
3926 if Is_Entity_Name
(Pref
)
3927 and then Is_Formal
(Entity
(Pref
))
3928 and then Is_Array_Type
(Ptyp
)
3929 and then Is_Packed
(Ptyp
)
3932 Make_Attribute_Reference
(Loc
,
3934 New_Occurrence_Of
(Get_Actual_Subtype
(Pref
), Loc
),
3935 Attribute_Name
=> Name_Size
));
3936 Analyze_And_Resolve
(N
, Typ
);
3939 -- If Size applies to a dereference of an access to unconstrained
3940 -- packed array, the back end needs to see its unconstrained
3941 -- nominal type, but also a hint to the actual constrained type.
3943 if Nkind
(Pref
) = N_Explicit_Dereference
3944 and then Is_Array_Type
(Ptyp
)
3945 and then not Is_Constrained
(Ptyp
)
3946 and then Is_Packed
(Ptyp
)
3948 Set_Actual_Designated_Subtype
(Pref
,
3949 Get_Actual_Subtype
(Pref
));
3955 -- Common processing for record and array component case
3957 if Siz
/= No_Uint
and then Siz
/= 0 then
3959 CS
: constant Boolean := Comes_From_Source
(N
);
3962 Rewrite
(N
, Make_Integer_Literal
(Loc
, Siz
));
3964 -- This integer literal is not a static expression. We do not
3965 -- call Analyze_And_Resolve here, because this would activate
3966 -- the circuit for deciding that a static value was out of
3967 -- range, and we don't want that.
3969 -- So just manually set the type, mark the expression as non-
3970 -- static, and then ensure that the result is checked properly
3971 -- if the attribute comes from source (if it was internally
3972 -- generated, we never need a constraint check).
3975 Set_Is_Static_Expression
(N
, False);
3978 Apply_Constraint_Check
(N
, Typ
);
3988 when Attribute_Storage_Pool
=>
3990 Make_Type_Conversion
(Loc
,
3991 Subtype_Mark
=> New_Reference_To
(Etype
(N
), Loc
),
3992 Expression
=> New_Reference_To
(Entity
(N
), Loc
)));
3993 Analyze_And_Resolve
(N
, Typ
);
3999 when Attribute_Storage_Size
=> Storage_Size
: begin
4001 -- Access type case, always go to the root type
4003 -- The case of access types results in a value of zero for the case
4004 -- where no storage size attribute clause has been given. If a
4005 -- storage size has been given, then the attribute is converted
4006 -- to a reference to the variable used to hold this value.
4008 if Is_Access_Type
(Ptyp
) then
4009 if Present
(Storage_Size_Variable
(Root_Type
(Ptyp
))) then
4011 Make_Attribute_Reference
(Loc
,
4012 Prefix
=> New_Reference_To
(Typ
, Loc
),
4013 Attribute_Name
=> Name_Max
,
4014 Expressions
=> New_List
(
4015 Make_Integer_Literal
(Loc
, 0),
4018 (Storage_Size_Variable
(Root_Type
(Ptyp
)), Loc
)))));
4020 elsif Present
(Associated_Storage_Pool
(Root_Type
(Ptyp
))) then
4023 Make_Function_Call
(Loc
,
4027 (Etype
(Associated_Storage_Pool
(Root_Type
(Ptyp
))),
4028 Attribute_Name
(N
)),
4031 Parameter_Associations
=> New_List
(
4033 (Associated_Storage_Pool
(Root_Type
(Ptyp
)), Loc
)))));
4036 Rewrite
(N
, Make_Integer_Literal
(Loc
, 0));
4039 Analyze_And_Resolve
(N
, Typ
);
4041 -- For tasks, we retrieve the size directly from the TCB. The
4042 -- size may depend on a discriminant of the type, and therefore
4043 -- can be a per-object expression, so type-level information is
4044 -- not sufficient in general. There are four cases to consider:
4046 -- a) If the attribute appears within a task body, the designated
4047 -- TCB is obtained by a call to Self.
4049 -- b) If the prefix of the attribute is the name of a task object,
4050 -- the designated TCB is the one stored in the corresponding record.
4052 -- c) If the prefix is a task type, the size is obtained from the
4053 -- size variable created for each task type
4055 -- d) If no storage_size was specified for the type , there is no
4056 -- size variable, and the value is a system-specific default.
4059 if In_Open_Scopes
(Ptyp
) then
4061 -- Storage_Size (Self)
4065 Make_Function_Call
(Loc
,
4067 New_Occurrence_Of
(RTE
(RE_Storage_Size
), Loc
),
4068 Parameter_Associations
=>
4070 Make_Function_Call
(Loc
,
4072 New_Reference_To
(RTE
(RE_Self
), Loc
))))));
4074 elsif not Is_Entity_Name
(Pref
)
4075 or else not Is_Type
(Entity
(Pref
))
4077 -- Storage_Size (Rec (Obj).Size)
4081 Make_Function_Call
(Loc
,
4083 New_Occurrence_Of
(RTE
(RE_Storage_Size
), Loc
),
4084 Parameter_Associations
=>
4086 Make_Selected_Component
(Loc
,
4088 Unchecked_Convert_To
(
4089 Corresponding_Record_Type
(Ptyp
),
4090 New_Copy_Tree
(Pref
)),
4092 Make_Identifier
(Loc
, Name_uTask_Id
))))));
4094 elsif Present
(Storage_Size_Variable
(Ptyp
)) then
4096 -- Static storage size pragma given for type: retrieve value
4097 -- from its allocated storage variable.
4101 Make_Function_Call
(Loc
,
4102 Name
=> New_Occurrence_Of
(
4103 RTE
(RE_Adjust_Storage_Size
), Loc
),
4104 Parameter_Associations
=>
4107 Storage_Size_Variable
(Ptyp
), Loc
)))));
4109 -- Get system default
4113 Make_Function_Call
(Loc
,
4116 RTE
(RE_Default_Stack_Size
), Loc
))));
4119 Analyze_And_Resolve
(N
, Typ
);
4127 when Attribute_Stream_Size
=> Stream_Size
: declare
4131 -- If we have a Stream_Size clause for this type use it, otherwise
4132 -- the Stream_Size if the size of the type.
4134 if Has_Stream_Size_Clause
(Ptyp
) then
4137 (Static_Integer
(Expression
(Stream_Size_Clause
(Ptyp
))));
4139 Size
:= UI_To_Int
(Esize
(Ptyp
));
4142 Rewrite
(N
, Make_Integer_Literal
(Loc
, Intval
=> Size
));
4143 Analyze_And_Resolve
(N
, Typ
);
4150 -- 1. Deal with enumeration types with holes
4151 -- 2. For floating-point, generate call to attribute function
4152 -- 3. For other cases, deal with constraint checking
4154 when Attribute_Succ
=> Succ
:
4156 Etyp
: constant Entity_Id
:= Base_Type
(Ptyp
);
4160 -- For enumeration types with non-standard representations, we
4161 -- expand typ'Succ (x) into
4163 -- Pos_To_Rep (Rep_To_Pos (x) + 1)
4165 -- If the representation is contiguous, we compute instead
4166 -- Lit1 + Rep_to_Pos (x+1), to catch invalid representations.
4168 if Is_Enumeration_Type
(Ptyp
)
4169 and then Present
(Enum_Pos_To_Rep
(Etyp
))
4171 if Has_Contiguous_Rep
(Etyp
) then
4173 Unchecked_Convert_To
(Ptyp
,
4176 Make_Integer_Literal
(Loc
,
4177 Enumeration_Rep
(First_Literal
(Ptyp
))),
4179 Make_Function_Call
(Loc
,
4182 (TSS
(Etyp
, TSS_Rep_To_Pos
), Loc
),
4184 Parameter_Associations
=>
4186 Unchecked_Convert_To
(Ptyp
,
4189 Unchecked_Convert_To
(Standard_Integer
,
4190 Relocate_Node
(First
(Exprs
))),
4192 Make_Integer_Literal
(Loc
, 1))),
4193 Rep_To_Pos_Flag
(Ptyp
, Loc
))))));
4195 -- Add Boolean parameter True, to request program errror if
4196 -- we have a bad representation on our hands. Add False if
4197 -- checks are suppressed.
4199 Append_To
(Exprs
, Rep_To_Pos_Flag
(Ptyp
, Loc
));
4201 Make_Indexed_Component
(Loc
,
4204 (Enum_Pos_To_Rep
(Etyp
), Loc
),
4205 Expressions
=> New_List
(
4208 Make_Function_Call
(Loc
,
4211 (TSS
(Etyp
, TSS_Rep_To_Pos
), Loc
),
4212 Parameter_Associations
=> Exprs
),
4213 Right_Opnd
=> Make_Integer_Literal
(Loc
, 1)))));
4216 Analyze_And_Resolve
(N
, Typ
);
4218 -- For floating-point, we transform 'Succ into a call to the Succ
4219 -- floating-point attribute function in Fat_xxx (xxx is root type)
4221 elsif Is_Floating_Point_Type
(Ptyp
) then
4222 Expand_Fpt_Attribute_R
(N
);
4223 Analyze_And_Resolve
(N
, Typ
);
4225 -- For modular types, nothing to do (no overflow, since wraps)
4227 elsif Is_Modular_Integer_Type
(Ptyp
) then
4230 -- For other types, if range checking is enabled, we must generate
4231 -- a check if overflow checking is enabled.
4233 elsif not Overflow_Checks_Suppressed
(Ptyp
) then
4234 Expand_Pred_Succ
(N
);
4242 -- Transforms X'Tag into a direct reference to the tag of X
4244 when Attribute_Tag
=> Tag
:
4247 Prefix_Is_Type
: Boolean;
4250 if Is_Entity_Name
(Pref
) and then Is_Type
(Entity
(Pref
)) then
4251 Ttyp
:= Entity
(Pref
);
4252 Prefix_Is_Type
:= True;
4255 Prefix_Is_Type
:= False;
4258 if Is_Class_Wide_Type
(Ttyp
) then
4259 Ttyp
:= Root_Type
(Ttyp
);
4262 Ttyp
:= Underlying_Type
(Ttyp
);
4264 if Prefix_Is_Type
then
4266 -- For VMs we leave the type attribute unexpanded because
4267 -- there's not a dispatching table to reference.
4269 if VM_Target
= No_VM
then
4271 Unchecked_Convert_To
(RTE
(RE_Tag
),
4273 (Node
(First_Elmt
(Access_Disp_Table
(Ttyp
))), Loc
)));
4274 Analyze_And_Resolve
(N
, RTE
(RE_Tag
));
4277 -- (Ada 2005 (AI-251): The use of 'Tag in the sources always
4278 -- references the primary tag of the actual object. If 'Tag is
4279 -- applied to class-wide interface objects we generate code that
4280 -- displaces "this" to reference the base of the object.
4282 elsif Comes_From_Source
(N
)
4283 and then Is_Class_Wide_Type
(Etype
(Prefix
(N
)))
4284 and then Is_Interface
(Etype
(Prefix
(N
)))
4287 -- (To_Tag_Ptr (Prefix'Address)).all
4289 -- Note that Prefix'Address is recursively expanded into a call
4290 -- to Base_Address (Obj.Tag)
4292 -- Not needed for VM targets, since all handled by the VM
4294 if VM_Target
= No_VM
then
4296 Make_Explicit_Dereference
(Loc
,
4297 Unchecked_Convert_To
(RTE
(RE_Tag_Ptr
),
4298 Make_Attribute_Reference
(Loc
,
4299 Prefix
=> Relocate_Node
(Pref
),
4300 Attribute_Name
=> Name_Address
))));
4301 Analyze_And_Resolve
(N
, RTE
(RE_Tag
));
4306 Make_Selected_Component
(Loc
,
4307 Prefix
=> Relocate_Node
(Pref
),
4309 New_Reference_To
(First_Tag_Component
(Ttyp
), Loc
)));
4310 Analyze_And_Resolve
(N
, RTE
(RE_Tag
));
4318 -- Transforms 'Terminated attribute into a call to Terminated function
4320 when Attribute_Terminated
=> Terminated
:
4322 -- The prefix of Terminated is of a task interface class-wide type.
4325 -- terminated (Task_Id (Pref._disp_get_task_id));
4327 if Ada_Version
>= Ada_05
4328 and then Ekind
(Ptyp
) = E_Class_Wide_Type
4329 and then Is_Interface
(Ptyp
)
4330 and then Is_Task_Interface
(Ptyp
)
4333 Make_Function_Call
(Loc
,
4335 New_Reference_To
(RTE
(RE_Terminated
), Loc
),
4336 Parameter_Associations
=> New_List
(
4337 Make_Unchecked_Type_Conversion
(Loc
,
4339 New_Reference_To
(RTE
(RO_ST_Task_Id
), Loc
),
4341 Make_Selected_Component
(Loc
,
4343 New_Copy_Tree
(Pref
),
4345 Make_Identifier
(Loc
, Name_uDisp_Get_Task_Id
))))));
4347 elsif Restricted_Profile
then
4349 Build_Call_With_Task
(Pref
, RTE
(RE_Restricted_Terminated
)));
4353 Build_Call_With_Task
(Pref
, RTE
(RE_Terminated
)));
4356 Analyze_And_Resolve
(N
, Standard_Boolean
);
4363 -- Transforms System'To_Address (X) into unchecked conversion
4364 -- from (integral) type of X to type address.
4366 when Attribute_To_Address
=>
4368 Unchecked_Convert_To
(RTE
(RE_Address
),
4369 Relocate_Node
(First
(Exprs
))));
4370 Analyze_And_Resolve
(N
, RTE
(RE_Address
));
4376 -- Transforms 'Truncation into a call to the floating-point attribute
4377 -- function Truncation in Fat_xxx (where xxx is the root type).
4378 -- Expansion is avoided for cases the back end can handle directly.
4380 when Attribute_Truncation
=>
4381 if not Is_Inline_Floating_Point_Attribute
(N
) then
4382 Expand_Fpt_Attribute_R
(N
);
4385 -----------------------
4386 -- Unbiased_Rounding --
4387 -----------------------
4389 -- Transforms 'Unbiased_Rounding into a call to the floating-point
4390 -- attribute function Unbiased_Rounding in Fat_xxx (where xxx is the
4391 -- root type). Expansion is avoided for cases the back end can handle
4394 when Attribute_Unbiased_Rounding
=>
4395 if not Is_Inline_Floating_Point_Attribute
(N
) then
4396 Expand_Fpt_Attribute_R
(N
);
4403 when Attribute_UET_Address
=> UET_Address
: declare
4404 Ent
: constant Entity_Id
:=
4405 Make_Defining_Identifier
(Loc
, New_Internal_Name
('T'));
4409 Make_Object_Declaration
(Loc
,
4410 Defining_Identifier
=> Ent
,
4411 Aliased_Present
=> True,
4412 Object_Definition
=>
4413 New_Occurrence_Of
(RTE
(RE_Address
), Loc
)));
4415 -- Construct name __gnat_xxx__SDP, where xxx is the unit name
4416 -- in normal external form.
4418 Get_External_Unit_Name_String
(Get_Unit_Name
(Pref
));
4419 Name_Buffer
(1 + 7 .. Name_Len
+ 7) := Name_Buffer
(1 .. Name_Len
);
4420 Name_Len
:= Name_Len
+ 7;
4421 Name_Buffer
(1 .. 7) := "__gnat_";
4422 Name_Buffer
(Name_Len
+ 1 .. Name_Len
+ 5) := "__SDP";
4423 Name_Len
:= Name_Len
+ 5;
4425 Set_Is_Imported
(Ent
);
4426 Set_Interface_Name
(Ent
,
4427 Make_String_Literal
(Loc
,
4428 Strval
=> String_From_Name_Buffer
));
4430 -- Set entity as internal to ensure proper Sprint output of its
4431 -- implicit importation.
4433 Set_Is_Internal
(Ent
);
4436 Make_Attribute_Reference
(Loc
,
4437 Prefix
=> New_Occurrence_Of
(Ent
, Loc
),
4438 Attribute_Name
=> Name_Address
));
4440 Analyze_And_Resolve
(N
, Typ
);
4447 -- The processing for VADS_Size is shared with Size
4453 -- For enumeration types with a standard representation, and for all
4454 -- other types, Val is handled by the back end. For enumeration types
4455 -- with a non-standard representation we use the _Pos_To_Rep array that
4456 -- was created when the type was frozen.
4458 when Attribute_Val
=> Val
:
4460 Etyp
: constant Entity_Id
:= Base_Type
(Entity
(Pref
));
4463 if Is_Enumeration_Type
(Etyp
)
4464 and then Present
(Enum_Pos_To_Rep
(Etyp
))
4466 if Has_Contiguous_Rep
(Etyp
) then
4468 Rep_Node
: constant Node_Id
:=
4469 Unchecked_Convert_To
(Etyp
,
4472 Make_Integer_Literal
(Loc
,
4473 Enumeration_Rep
(First_Literal
(Etyp
))),
4475 (Convert_To
(Standard_Integer
,
4476 Relocate_Node
(First
(Exprs
))))));
4480 Unchecked_Convert_To
(Etyp
,
4483 Make_Integer_Literal
(Loc
,
4484 Enumeration_Rep
(First_Literal
(Etyp
))),
4486 Make_Function_Call
(Loc
,
4489 (TSS
(Etyp
, TSS_Rep_To_Pos
), Loc
),
4490 Parameter_Associations
=> New_List
(
4492 Rep_To_Pos_Flag
(Etyp
, Loc
))))));
4497 Make_Indexed_Component
(Loc
,
4498 Prefix
=> New_Reference_To
(Enum_Pos_To_Rep
(Etyp
), Loc
),
4499 Expressions
=> New_List
(
4500 Convert_To
(Standard_Integer
,
4501 Relocate_Node
(First
(Exprs
))))));
4504 Analyze_And_Resolve
(N
, Typ
);
4512 -- The code for valid is dependent on the particular types involved.
4513 -- See separate sections below for the generated code in each case.
4515 when Attribute_Valid
=> Valid
:
4517 Btyp
: Entity_Id
:= Base_Type
(Ptyp
);
4520 Save_Validity_Checks_On
: constant Boolean := Validity_Checks_On
;
4521 -- Save the validity checking mode. We always turn off validity
4522 -- checking during process of 'Valid since this is one place
4523 -- where we do not want the implicit validity checks to intefere
4524 -- with the explicit validity check that the programmer is doing.
4526 function Make_Range_Test
return Node_Id
;
4527 -- Build the code for a range test of the form
4528 -- Btyp!(Pref) >= Btyp!(Ptyp'First)
4530 -- Btyp!(Pref) <= Btyp!(Ptyp'Last)
4532 ---------------------
4533 -- Make_Range_Test --
4534 ---------------------
4536 function Make_Range_Test
return Node_Id
is
4543 Unchecked_Convert_To
(Btyp
, Duplicate_Subexpr
(Pref
)),
4546 Unchecked_Convert_To
(Btyp
,
4547 Make_Attribute_Reference
(Loc
,
4548 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
4549 Attribute_Name
=> Name_First
))),
4554 Unchecked_Convert_To
(Btyp
,
4555 Duplicate_Subexpr_No_Checks
(Pref
)),
4558 Unchecked_Convert_To
(Btyp
,
4559 Make_Attribute_Reference
(Loc
,
4560 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
4561 Attribute_Name
=> Name_Last
))));
4562 end Make_Range_Test
;
4564 -- Start of processing for Attribute_Valid
4567 -- Turn off validity checks. We do not want any implicit validity
4568 -- checks to intefere with the explicit check from the attribute
4570 Validity_Checks_On
:= False;
4572 -- Floating-point case. This case is handled by the Valid attribute
4573 -- code in the floating-point attribute run-time library.
4575 if Is_Floating_Point_Type
(Ptyp
) then
4581 -- For vax fpt types, call appropriate routine in special vax
4582 -- floating point unit. We do not have to worry about loads in
4583 -- this case, since these types have no signalling NaN's.
4585 if Vax_Float
(Btyp
) then
4586 Expand_Vax_Valid
(N
);
4588 -- The AAMP back end handles Valid for floating-point types
4590 elsif Is_AAMP_Float
(Btyp
) then
4591 Analyze_And_Resolve
(Pref
, Ptyp
);
4592 Set_Etype
(N
, Standard_Boolean
);
4595 -- Non VAX float case
4598 Find_Fat_Info
(Ptyp
, Ftp
, Pkg
);
4600 -- If the floating-point object might be unaligned, we need
4601 -- to call the special routine Unaligned_Valid, which makes
4602 -- the needed copy, being careful not to load the value into
4603 -- any floating-point register. The argument in this case is
4604 -- obj'Address (see Unaligned_Valid routine in Fat_Gen).
4606 if Is_Possibly_Unaligned_Object
(Pref
) then
4607 Expand_Fpt_Attribute
4608 (N
, Pkg
, Name_Unaligned_Valid
,
4610 Make_Attribute_Reference
(Loc
,
4611 Prefix
=> Relocate_Node
(Pref
),
4612 Attribute_Name
=> Name_Address
)));
4614 -- In the normal case where we are sure the object is
4615 -- aligned, we generate a call to Valid, and the argument in
4616 -- this case is obj'Unrestricted_Access (after converting
4617 -- obj to the right floating-point type).
4620 Expand_Fpt_Attribute
4621 (N
, Pkg
, Name_Valid
,
4623 Make_Attribute_Reference
(Loc
,
4624 Prefix
=> Unchecked_Convert_To
(Ftp
, Pref
),
4625 Attribute_Name
=> Name_Unrestricted_Access
)));
4629 -- One more task, we still need a range check. Required
4630 -- only if we have a constraint, since the Valid routine
4631 -- catches infinities properly (infinities are never valid).
4633 -- The way we do the range check is simply to create the
4634 -- expression: Valid (N) and then Base_Type(Pref) in Typ.
4636 if not Subtypes_Statically_Match
(Ptyp
, Btyp
) then
4639 Left_Opnd
=> Relocate_Node
(N
),
4642 Left_Opnd
=> Convert_To
(Btyp
, Pref
),
4643 Right_Opnd
=> New_Occurrence_Of
(Ptyp
, Loc
))));
4647 -- Enumeration type with holes
4649 -- For enumeration types with holes, the Pos value constructed by
4650 -- the Enum_Rep_To_Pos function built in Exp_Ch3 called with a
4651 -- second argument of False returns minus one for an invalid value,
4652 -- and the non-negative pos value for a valid value, so the
4653 -- expansion of X'Valid is simply:
4655 -- type(X)'Pos (X) >= 0
4657 -- We can't quite generate it that way because of the requirement
4658 -- for the non-standard second argument of False in the resulting
4659 -- rep_to_pos call, so we have to explicitly create:
4661 -- _rep_to_pos (X, False) >= 0
4663 -- If we have an enumeration subtype, we also check that the
4664 -- value is in range:
4666 -- _rep_to_pos (X, False) >= 0
4668 -- (X >= type(X)'First and then type(X)'Last <= X)
4670 elsif Is_Enumeration_Type
(Ptyp
)
4671 and then Present
(Enum_Pos_To_Rep
(Base_Type
(Ptyp
)))
4676 Make_Function_Call
(Loc
,
4679 (TSS
(Base_Type
(Ptyp
), TSS_Rep_To_Pos
), Loc
),
4680 Parameter_Associations
=> New_List
(
4682 New_Occurrence_Of
(Standard_False
, Loc
))),
4683 Right_Opnd
=> Make_Integer_Literal
(Loc
, 0));
4687 (Type_Low_Bound
(Ptyp
) /= Type_Low_Bound
(Btyp
)
4689 Type_High_Bound
(Ptyp
) /= Type_High_Bound
(Btyp
))
4691 -- The call to Make_Range_Test will create declarations
4692 -- that need a proper insertion point, but Pref is now
4693 -- attached to a node with no ancestor. Attach to tree
4694 -- even if it is to be rewritten below.
4696 Set_Parent
(Tst
, Parent
(N
));
4700 Left_Opnd
=> Make_Range_Test
,
4706 -- Fortran convention booleans
4708 -- For the very special case of Fortran convention booleans, the
4709 -- value is always valid, since it is an integer with the semantics
4710 -- that non-zero is true, and any value is permissible.
4712 elsif Is_Boolean_Type
(Ptyp
)
4713 and then Convention
(Ptyp
) = Convention_Fortran
4715 Rewrite
(N
, New_Occurrence_Of
(Standard_True
, Loc
));
4717 -- For biased representations, we will be doing an unchecked
4718 -- conversion without unbiasing the result. That means that the range
4719 -- test has to take this into account, and the proper form of the
4722 -- Btyp!(Pref) < Btyp!(Ptyp'Range_Length)
4724 elsif Has_Biased_Representation
(Ptyp
) then
4725 Btyp
:= RTE
(RE_Unsigned_32
);
4729 Unchecked_Convert_To
(Btyp
, Duplicate_Subexpr
(Pref
)),
4731 Unchecked_Convert_To
(Btyp
,
4732 Make_Attribute_Reference
(Loc
,
4733 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
4734 Attribute_Name
=> Name_Range_Length
))));
4736 -- For all other scalar types, what we want logically is a
4739 -- X in type(X)'First .. type(X)'Last
4741 -- But that's precisely what won't work because of possible
4742 -- unwanted optimization (and indeed the basic motivation for
4743 -- the Valid attribute is exactly that this test does not work!)
4744 -- What will work is:
4746 -- Btyp!(X) >= Btyp!(type(X)'First)
4748 -- Btyp!(X) <= Btyp!(type(X)'Last)
4750 -- where Btyp is an integer type large enough to cover the full
4751 -- range of possible stored values (i.e. it is chosen on the basis
4752 -- of the size of the type, not the range of the values). We write
4753 -- this as two tests, rather than a range check, so that static
4754 -- evaluation will easily remove either or both of the checks if
4755 -- they can be -statically determined to be true (this happens
4756 -- when the type of X is static and the range extends to the full
4757 -- range of stored values).
4759 -- Unsigned types. Note: it is safe to consider only whether the
4760 -- subtype is unsigned, since we will in that case be doing all
4761 -- unsigned comparisons based on the subtype range. Since we use the
4762 -- actual subtype object size, this is appropriate.
4764 -- For example, if we have
4766 -- subtype x is integer range 1 .. 200;
4767 -- for x'Object_Size use 8;
4769 -- Now the base type is signed, but objects of this type are bits
4770 -- unsigned, and doing an unsigned test of the range 1 to 200 is
4771 -- correct, even though a value greater than 127 looks signed to a
4772 -- signed comparison.
4774 elsif Is_Unsigned_Type
(Ptyp
) then
4775 if Esize
(Ptyp
) <= 32 then
4776 Btyp
:= RTE
(RE_Unsigned_32
);
4778 Btyp
:= RTE
(RE_Unsigned_64
);
4781 Rewrite
(N
, Make_Range_Test
);
4786 if Esize
(Ptyp
) <= Esize
(Standard_Integer
) then
4787 Btyp
:= Standard_Integer
;
4789 Btyp
:= Universal_Integer
;
4792 Rewrite
(N
, Make_Range_Test
);
4795 Analyze_And_Resolve
(N
, Standard_Boolean
);
4796 Validity_Checks_On
:= Save_Validity_Checks_On
;
4803 -- Value attribute is handled in separate unti Exp_Imgv
4805 when Attribute_Value
=>
4806 Exp_Imgv
.Expand_Value_Attribute
(N
);
4812 -- The processing for Value_Size shares the processing for Size
4818 -- The processing for Version shares the processing for Body_Version
4824 -- Wide_Image attribute is handled in separate unit Exp_Imgv
4826 when Attribute_Wide_Image
=>
4827 Exp_Imgv
.Expand_Wide_Image_Attribute
(N
);
4829 ---------------------
4830 -- Wide_Wide_Image --
4831 ---------------------
4833 -- Wide_Wide_Image attribute is handled in separate unit Exp_Imgv
4835 when Attribute_Wide_Wide_Image
=>
4836 Exp_Imgv
.Expand_Wide_Wide_Image_Attribute
(N
);
4842 -- We expand typ'Wide_Value (X) into
4845 -- (Wide_String_To_String (X, Wide_Character_Encoding_Method))
4847 -- Wide_String_To_String is a runtime function that converts its wide
4848 -- string argument to String, converting any non-translatable characters
4849 -- into appropriate escape sequences. This preserves the required
4850 -- semantics of Wide_Value in all cases, and results in a very simple
4851 -- implementation approach.
4853 -- Note: for this approach to be fully standard compliant for the cases
4854 -- where typ is Wide_Character and Wide_Wide_Character, the encoding
4855 -- method must cover the entire character range (e.g. UTF-8). But that
4856 -- is a reasonable requirement when dealing with encoded character
4857 -- sequences. Presumably if one of the restrictive encoding mechanisms
4858 -- is in use such as Shift-JIS, then characters that cannot be
4859 -- represented using this encoding will not appear in any case.
4861 when Attribute_Wide_Value
=> Wide_Value
:
4864 Make_Attribute_Reference
(Loc
,
4866 Attribute_Name
=> Name_Value
,
4868 Expressions
=> New_List
(
4869 Make_Function_Call
(Loc
,
4871 New_Reference_To
(RTE
(RE_Wide_String_To_String
), Loc
),
4873 Parameter_Associations
=> New_List
(
4874 Relocate_Node
(First
(Exprs
)),
4875 Make_Integer_Literal
(Loc
,
4876 Intval
=> Int
(Wide_Character_Encoding_Method
)))))));
4878 Analyze_And_Resolve
(N
, Typ
);
4881 ---------------------
4882 -- Wide_Wide_Value --
4883 ---------------------
4885 -- We expand typ'Wide_Value_Value (X) into
4888 -- (Wide_Wide_String_To_String (X, Wide_Character_Encoding_Method))
4890 -- Wide_Wide_String_To_String is a runtime function that converts its
4891 -- wide string argument to String, converting any non-translatable
4892 -- characters into appropriate escape sequences. This preserves the
4893 -- required semantics of Wide_Wide_Value in all cases, and results in a
4894 -- very simple implementation approach.
4896 -- It's not quite right where typ = Wide_Wide_Character, because the
4897 -- encoding method may not cover the whole character type ???
4899 when Attribute_Wide_Wide_Value
=> Wide_Wide_Value
:
4902 Make_Attribute_Reference
(Loc
,
4904 Attribute_Name
=> Name_Value
,
4906 Expressions
=> New_List
(
4907 Make_Function_Call
(Loc
,
4909 New_Reference_To
(RTE
(RE_Wide_Wide_String_To_String
), Loc
),
4911 Parameter_Associations
=> New_List
(
4912 Relocate_Node
(First
(Exprs
)),
4913 Make_Integer_Literal
(Loc
,
4914 Intval
=> Int
(Wide_Character_Encoding_Method
)))))));
4916 Analyze_And_Resolve
(N
, Typ
);
4917 end Wide_Wide_Value
;
4919 ---------------------
4920 -- Wide_Wide_Width --
4921 ---------------------
4923 -- Wide_Wide_Width attribute is handled in separate unit Exp_Imgv
4925 when Attribute_Wide_Wide_Width
=>
4926 Exp_Imgv
.Expand_Width_Attribute
(N
, Wide_Wide
);
4932 -- Wide_Width attribute is handled in separate unit Exp_Imgv
4934 when Attribute_Wide_Width
=>
4935 Exp_Imgv
.Expand_Width_Attribute
(N
, Wide
);
4941 -- Width attribute is handled in separate unit Exp_Imgv
4943 when Attribute_Width
=>
4944 Exp_Imgv
.Expand_Width_Attribute
(N
, Normal
);
4950 when Attribute_Write
=> Write
: declare
4951 P_Type
: constant Entity_Id
:= Entity
(Pref
);
4952 U_Type
: constant Entity_Id
:= Underlying_Type
(P_Type
);
4960 -- If no underlying type, we have an error that will be diagnosed
4961 -- elsewhere, so here we just completely ignore the expansion.
4967 -- The simple case, if there is a TSS for Write, just call it
4969 Pname
:= Find_Stream_Subprogram
(P_Type
, TSS_Stream_Write
);
4971 if Present
(Pname
) then
4975 -- If there is a Stream_Convert pragma, use it, we rewrite
4977 -- sourcetyp'Output (stream, Item)
4981 -- strmtyp'Output (Stream, strmwrite (acttyp (Item)));
4983 -- where strmwrite is the given Write function that converts an
4984 -- argument of type sourcetyp or a type acctyp, from which it is
4985 -- derived to type strmtyp. The conversion to acttyp is required
4986 -- for the derived case.
4988 Prag
:= Get_Stream_Convert_Pragma
(P_Type
);
4990 if Present
(Prag
) then
4992 Next
(Next
(First
(Pragma_Argument_Associations
(Prag
))));
4993 Wfunc
:= Entity
(Expression
(Arg3
));
4996 Make_Attribute_Reference
(Loc
,
4997 Prefix
=> New_Occurrence_Of
(Etype
(Wfunc
), Loc
),
4998 Attribute_Name
=> Name_Output
,
4999 Expressions
=> New_List
(
5000 Relocate_Node
(First
(Exprs
)),
5001 Make_Function_Call
(Loc
,
5002 Name
=> New_Occurrence_Of
(Wfunc
, Loc
),
5003 Parameter_Associations
=> New_List
(
5004 OK_Convert_To
(Etype
(First_Formal
(Wfunc
)),
5005 Relocate_Node
(Next
(First
(Exprs
)))))))));
5010 -- For elementary types, we call the W_xxx routine directly
5012 elsif Is_Elementary_Type
(U_Type
) then
5013 Rewrite
(N
, Build_Elementary_Write_Call
(N
));
5019 elsif Is_Array_Type
(U_Type
) then
5020 Build_Array_Write_Procedure
(N
, U_Type
, Decl
, Pname
);
5021 Compile_Stream_Body_In_Scope
(N
, Decl
, U_Type
, Check
=> False);
5023 -- Tagged type case, use the primitive Write function. Note that
5024 -- this will dispatch in the class-wide case which is what we want
5026 elsif Is_Tagged_Type
(U_Type
) then
5027 Pname
:= Find_Prim_Op
(U_Type
, TSS_Stream_Write
);
5029 -- All other record type cases, including protected records.
5030 -- The latter only arise for expander generated code for
5031 -- handling shared passive partition access.
5035 (Is_Record_Type
(U_Type
) or else Is_Protected_Type
(U_Type
));
5037 -- Ada 2005 (AI-216): Program_Error is raised when executing
5038 -- the default implementation of the Write attribute of an
5039 -- Unchecked_Union type. However, if the 'Write reference is
5040 -- within the generated Output stream procedure, Write outputs
5041 -- the components, and the default values of the discriminant
5042 -- are streamed by the Output procedure itself.
5044 if Is_Unchecked_Union
(Base_Type
(U_Type
))
5045 and not Is_TSS
(Current_Scope
, TSS_Stream_Output
)
5048 Make_Raise_Program_Error
(Loc
,
5049 Reason
=> PE_Unchecked_Union_Restriction
));
5052 if Has_Discriminants
(U_Type
)
5054 (Discriminant_Default_Value
(First_Discriminant
(U_Type
)))
5056 Build_Mutable_Record_Write_Procedure
5057 (Loc
, Base_Type
(U_Type
), Decl
, Pname
);
5059 Build_Record_Write_Procedure
5060 (Loc
, Base_Type
(U_Type
), Decl
, Pname
);
5063 Insert_Action
(N
, Decl
);
5067 -- If we fall through, Pname is the procedure to be called
5069 Rewrite_Stream_Proc_Call
(Pname
);
5072 -- Component_Size is handled by the back end, unless the component size
5073 -- is known at compile time, which is always true in the packed array
5074 -- case. It is important that the packed array case is handled in the
5075 -- front end (see Eval_Attribute) since the back end would otherwise get
5076 -- confused by the equivalent packed array type.
5078 when Attribute_Component_Size
=>
5081 -- The following attributes are handled by the back end (except that
5082 -- static cases have already been evaluated during semantic processing,
5083 -- but in any case the back end should not count on this). The one bit
5084 -- of special processing required is that these attributes typically
5085 -- generate conditionals in the code, so we need to check the relevant
5088 when Attribute_Max |
5090 Check_Restriction
(No_Implicit_Conditionals
, N
);
5092 -- The following attributes are handled by the back end (except that
5093 -- static cases have already been evaluated during semantic processing,
5094 -- but in any case the back end should not count on this).
5096 -- The back end also handles the non-class-wide cases of Size
5098 when Attribute_Bit_Order |
5099 Attribute_Code_Address |
5100 Attribute_Definite |
5101 Attribute_Null_Parameter |
5102 Attribute_Passed_By_Reference |
5103 Attribute_Pool_Address
=>
5106 -- The following attributes are also handled by the back end, but return
5107 -- a universal integer result, so may need a conversion for checking
5108 -- that the result is in range.
5110 when Attribute_Aft |
5112 Attribute_Max_Size_In_Storage_Elements
5114 Apply_Universal_Integer_Attribute_Checks
(N
);
5116 -- The following attributes should not appear at this stage, since they
5117 -- have already been handled by the analyzer (and properly rewritten
5118 -- with corresponding values or entities to represent the right values)
5120 when Attribute_Abort_Signal |
5121 Attribute_Address_Size |
5124 Attribute_Default_Bit_Order |
5131 Attribute_Fast_Math |
5132 Attribute_Has_Access_Values |
5133 Attribute_Has_Discriminants |
5134 Attribute_Has_Tagged_Values |
5136 Attribute_Machine_Emax |
5137 Attribute_Machine_Emin |
5138 Attribute_Machine_Mantissa |
5139 Attribute_Machine_Overflows |
5140 Attribute_Machine_Radix |
5141 Attribute_Machine_Rounds |
5142 Attribute_Maximum_Alignment |
5143 Attribute_Model_Emin |
5144 Attribute_Model_Epsilon |
5145 Attribute_Model_Mantissa |
5146 Attribute_Model_Small |
5148 Attribute_Partition_ID |
5150 Attribute_Safe_Emax |
5151 Attribute_Safe_First |
5152 Attribute_Safe_Large |
5153 Attribute_Safe_Last |
5154 Attribute_Safe_Small |
5156 Attribute_Signed_Zeros |
5158 Attribute_Storage_Unit |
5159 Attribute_Stub_Type |
5160 Attribute_Target_Name |
5161 Attribute_Type_Class |
5162 Attribute_Unconstrained_Array |
5163 Attribute_Universal_Literal_String |
5164 Attribute_Wchar_T_Size |
5165 Attribute_Word_Size
=>
5167 raise Program_Error
;
5169 -- The Asm_Input and Asm_Output attributes are not expanded at this
5170 -- stage, but will be eliminated in the expansion of the Asm call, see
5171 -- Exp_Intr for details. So the back end will never see these either.
5173 when Attribute_Asm_Input |
5174 Attribute_Asm_Output
=>
5181 when RE_Not_Available
=>
5183 end Expand_N_Attribute_Reference
;
5185 ----------------------
5186 -- Expand_Pred_Succ --
5187 ----------------------
5189 -- For typ'Pred (exp), we generate the check
5191 -- [constraint_error when exp = typ'Base'First]
5193 -- Similarly, for typ'Succ (exp), we generate the check
5195 -- [constraint_error when exp = typ'Base'Last]
5197 -- These checks are not generated for modular types, since the proper
5198 -- semantics for Succ and Pred on modular types is to wrap, not raise CE.
5200 procedure Expand_Pred_Succ
(N
: Node_Id
) is
5201 Loc
: constant Source_Ptr
:= Sloc
(N
);
5205 if Attribute_Name
(N
) = Name_Pred
then
5212 Make_Raise_Constraint_Error
(Loc
,
5216 Duplicate_Subexpr_Move_Checks
(First
(Expressions
(N
))),
5218 Make_Attribute_Reference
(Loc
,
5220 New_Reference_To
(Base_Type
(Etype
(Prefix
(N
))), Loc
),
5221 Attribute_Name
=> Cnam
)),
5222 Reason
=> CE_Overflow_Check_Failed
));
5223 end Expand_Pred_Succ
;
5229 procedure Find_Fat_Info
5231 Fat_Type
: out Entity_Id
;
5232 Fat_Pkg
: out RE_Id
)
5234 Btyp
: constant Entity_Id
:= Base_Type
(T
);
5235 Rtyp
: constant Entity_Id
:= Root_Type
(T
);
5236 Digs
: constant Nat
:= UI_To_Int
(Digits_Value
(Btyp
));
5239 -- If the base type is VAX float, then get appropriate VAX float type
5241 if Vax_Float
(Btyp
) then
5244 Fat_Type
:= RTE
(RE_Fat_VAX_F
);
5245 Fat_Pkg
:= RE_Attr_VAX_F_Float
;
5248 Fat_Type
:= RTE
(RE_Fat_VAX_D
);
5249 Fat_Pkg
:= RE_Attr_VAX_D_Float
;
5252 Fat_Type
:= RTE
(RE_Fat_VAX_G
);
5253 Fat_Pkg
:= RE_Attr_VAX_G_Float
;
5256 raise Program_Error
;
5259 -- If root type is VAX float, this is the case where the library has
5260 -- been recompiled in VAX float mode, and we have an IEEE float type.
5261 -- This is when we use the special IEEE Fat packages.
5263 elsif Vax_Float
(Rtyp
) then
5266 Fat_Type
:= RTE
(RE_Fat_IEEE_Short
);
5267 Fat_Pkg
:= RE_Attr_IEEE_Short
;
5270 Fat_Type
:= RTE
(RE_Fat_IEEE_Long
);
5271 Fat_Pkg
:= RE_Attr_IEEE_Long
;
5274 raise Program_Error
;
5277 -- If neither the base type nor the root type is VAX_Float then VAX
5278 -- float is out of the picture, and we can just use the root type.
5283 if Fat_Type
= Standard_Short_Float
then
5284 Fat_Pkg
:= RE_Attr_Short_Float
;
5286 elsif Fat_Type
= Standard_Float
then
5287 Fat_Pkg
:= RE_Attr_Float
;
5289 elsif Fat_Type
= Standard_Long_Float
then
5290 Fat_Pkg
:= RE_Attr_Long_Float
;
5292 elsif Fat_Type
= Standard_Long_Long_Float
then
5293 Fat_Pkg
:= RE_Attr_Long_Long_Float
;
5295 -- Universal real (which is its own root type) is treated as being
5296 -- equivalent to Standard.Long_Long_Float, since it is defined to
5297 -- have the same precision as the longest Float type.
5299 elsif Fat_Type
= Universal_Real
then
5300 Fat_Type
:= Standard_Long_Long_Float
;
5301 Fat_Pkg
:= RE_Attr_Long_Long_Float
;
5304 raise Program_Error
;
5309 ----------------------------
5310 -- Find_Stream_Subprogram --
5311 ----------------------------
5313 function Find_Stream_Subprogram
5315 Nam
: TSS_Name_Type
) return Entity_Id
5317 Ent
: constant Entity_Id
:= TSS
(Typ
, Nam
);
5320 if Present
(Ent
) then
5324 -- Stream attributes for strings are expanded into library calls. The
5325 -- following checks are disabled when the run-time is not available or
5326 -- when compiling predefined types due to bootstrap issues. As a result,
5327 -- the compiler will generate in-place stream routines for string types
5328 -- that appear in GNAT's library, but will generate calls via rtsfind
5329 -- to library routines for user code.
5330 -- ??? For now, disable this code for JVM, since this generates a
5331 -- VerifyError exception at run-time on e.g. c330001.
5332 -- This is disabled for AAMP, to avoid making dependences on files not
5333 -- supported in the AAMP library (such as s-fileio.adb).
5335 if VM_Target
/= JVM_Target
5336 and then not AAMP_On_Target
5338 not Is_Predefined_File_Name
(Unit_File_Name
(Current_Sem_Unit
))
5341 -- String as defined in package Ada
5343 if Typ
= Standard_String
then
5344 if Nam
= TSS_Stream_Input
then
5345 return RTE
(RE_String_Input
);
5347 elsif Nam
= TSS_Stream_Output
then
5348 return RTE
(RE_String_Output
);
5350 elsif Nam
= TSS_Stream_Read
then
5351 return RTE
(RE_String_Read
);
5353 else pragma Assert
(Nam
= TSS_Stream_Write
);
5354 return RTE
(RE_String_Write
);
5357 -- Wide_String as defined in package Ada
5359 elsif Typ
= Standard_Wide_String
then
5360 if Nam
= TSS_Stream_Input
then
5361 return RTE
(RE_Wide_String_Input
);
5363 elsif Nam
= TSS_Stream_Output
then
5364 return RTE
(RE_Wide_String_Output
);
5366 elsif Nam
= TSS_Stream_Read
then
5367 return RTE
(RE_Wide_String_Read
);
5369 else pragma Assert
(Nam
= TSS_Stream_Write
);
5370 return RTE
(RE_Wide_String_Write
);
5373 -- Wide_Wide_String as defined in package Ada
5375 elsif Typ
= Standard_Wide_Wide_String
then
5376 if Nam
= TSS_Stream_Input
then
5377 return RTE
(RE_Wide_Wide_String_Input
);
5379 elsif Nam
= TSS_Stream_Output
then
5380 return RTE
(RE_Wide_Wide_String_Output
);
5382 elsif Nam
= TSS_Stream_Read
then
5383 return RTE
(RE_Wide_Wide_String_Read
);
5385 else pragma Assert
(Nam
= TSS_Stream_Write
);
5386 return RTE
(RE_Wide_Wide_String_Write
);
5391 if Is_Tagged_Type
(Typ
)
5392 and then Is_Derived_Type
(Typ
)
5394 return Find_Prim_Op
(Typ
, Nam
);
5396 return Find_Inherited_TSS
(Typ
, Nam
);
5398 end Find_Stream_Subprogram
;
5400 -----------------------
5401 -- Get_Index_Subtype --
5402 -----------------------
5404 function Get_Index_Subtype
(N
: Node_Id
) return Node_Id
is
5405 P_Type
: Entity_Id
:= Etype
(Prefix
(N
));
5410 if Is_Access_Type
(P_Type
) then
5411 P_Type
:= Designated_Type
(P_Type
);
5414 if No
(Expressions
(N
)) then
5417 J
:= UI_To_Int
(Expr_Value
(First
(Expressions
(N
))));
5420 Indx
:= First_Index
(P_Type
);
5426 return Etype
(Indx
);
5427 end Get_Index_Subtype
;
5429 -------------------------------
5430 -- Get_Stream_Convert_Pragma --
5431 -------------------------------
5433 function Get_Stream_Convert_Pragma
(T
: Entity_Id
) return Node_Id
is
5438 -- Note: we cannot use Get_Rep_Pragma here because of the peculiarity
5439 -- that a stream convert pragma for a tagged type is not inherited from
5440 -- its parent. Probably what is wrong here is that it is basically
5441 -- incorrect to consider a stream convert pragma to be a representation
5442 -- pragma at all ???
5444 N
:= First_Rep_Item
(Implementation_Base_Type
(T
));
5445 while Present
(N
) loop
5446 if Nkind
(N
) = N_Pragma
5447 and then Pragma_Name
(N
) = Name_Stream_Convert
5449 -- For tagged types this pragma is not inherited, so we
5450 -- must verify that it is defined for the given type and
5454 Entity
(Expression
(First
(Pragma_Argument_Associations
(N
))));
5456 if not Is_Tagged_Type
(T
)
5458 or else (Is_Private_Type
(Typ
) and then T
= Full_View
(Typ
))
5468 end Get_Stream_Convert_Pragma
;
5470 ---------------------------------
5471 -- Is_Constrained_Packed_Array --
5472 ---------------------------------
5474 function Is_Constrained_Packed_Array
(Typ
: Entity_Id
) return Boolean is
5475 Arr
: Entity_Id
:= Typ
;
5478 if Is_Access_Type
(Arr
) then
5479 Arr
:= Designated_Type
(Arr
);
5482 return Is_Array_Type
(Arr
)
5483 and then Is_Constrained
(Arr
)
5484 and then Present
(Packed_Array_Type
(Arr
));
5485 end Is_Constrained_Packed_Array
;
5487 ----------------------------------------
5488 -- Is_Inline_Floating_Point_Attribute --
5489 ----------------------------------------
5491 function Is_Inline_Floating_Point_Attribute
(N
: Node_Id
) return Boolean is
5492 Id
: constant Attribute_Id
:= Get_Attribute_Id
(Attribute_Name
(N
));
5495 if Nkind
(Parent
(N
)) /= N_Type_Conversion
5496 or else not Is_Integer_Type
(Etype
(Parent
(N
)))
5501 -- Should also support 'Machine_Rounding and 'Unbiased_Rounding, but
5502 -- required back end support has not been implemented yet ???
5504 return Id
= Attribute_Truncation
;
5505 end Is_Inline_Floating_Point_Attribute
;