1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2017, 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 3, 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 COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with Atree
; use Atree
;
27 with Casing
; use Casing
;
28 with Checks
; use Checks
;
29 with Einfo
; use Einfo
;
30 with Exp_Util
; use Exp_Util
;
32 with Namet
; use Namet
;
33 with Nmake
; use Nmake
;
34 with Nlists
; use Nlists
;
36 with Rtsfind
; use Rtsfind
;
37 with Sem_Aux
; use Sem_Aux
;
38 with Sem_Res
; use Sem_Res
;
39 with Sem_Util
; use Sem_Util
;
40 with Sinfo
; use Sinfo
;
41 with Snames
; use Snames
;
42 with Stand
; use Stand
;
43 with Stringt
; use Stringt
;
44 with Tbuild
; use Tbuild
;
45 with Ttypes
; use Ttypes
;
46 with Uintp
; use Uintp
;
47 with Urealp
; use Urealp
;
49 package body Exp_Imgv
is
51 function Has_Decimal_Small
(E
: Entity_Id
) return Boolean;
52 -- Applies to all entities. True for a Decimal_Fixed_Point_Type, or an
53 -- Ordinary_Fixed_Point_Type with a small that is a negative power of ten.
54 -- Shouldn't this be in einfo.adb or sem_aux.adb???
56 procedure Rewrite_Object_Image
61 -- AI12-00124: Rewrite attribute 'Image when it is applied to an object
62 -- reference as an attribute applied to a type. N denotes the node to be
63 -- rewritten, Pref denotes the prefix of the 'Image attribute, and Name
64 -- and Str_Typ specify which specific string type and 'Image attribute to
65 -- apply (e.g. Name_Wide_Image and Standard_Wide_String).
67 ------------------------------------
68 -- Build_Enumeration_Image_Tables --
69 ------------------------------------
71 procedure Build_Enumeration_Image_Tables
(E
: Entity_Id
; N
: Node_Id
) is
72 Loc
: constant Source_Ptr
:= Sloc
(E
);
83 -- Nothing to do for other than a root enumeration type
85 if E
/= Root_Type
(E
) then
88 -- Nothing to do if pragma Discard_Names applies
90 elsif Discard_Names
(E
) then
94 -- Otherwise tables need constructing
98 Lit
:= First_Literal
(E
);
104 Make_Integer_Literal
(Loc
, UI_From_Int
(Len
)));
109 Get_Unqualified_Decoded_Name_String
(Chars
(Lit
));
111 if Name_Buffer
(1) /= ''' then
112 Set_Casing
(All_Upper_Case
);
115 Store_String_Chars
(Name_Buffer
(1 .. Name_Len
));
116 Len
:= Len
+ Int
(Name_Len
);
120 if Len
< Int
(2 ** (8 - 1)) then
121 Ityp
:= Standard_Integer_8
;
122 elsif Len
< Int
(2 ** (16 - 1)) then
123 Ityp
:= Standard_Integer_16
;
125 Ityp
:= Standard_Integer_32
;
131 Make_Defining_Identifier
(Loc
,
132 Chars
=> New_External_Name
(Chars
(E
), 'S'));
135 Make_Defining_Identifier
(Loc
,
136 Chars
=> New_External_Name
(Chars
(E
), 'N'));
138 Set_Lit_Strings
(E
, Estr
);
139 Set_Lit_Indexes
(E
, Eind
);
143 Make_Object_Declaration
(Loc
,
144 Defining_Identifier
=> Estr
,
145 Constant_Present
=> True,
147 New_Occurrence_Of
(Standard_String
, Loc
),
149 Make_String_Literal
(Loc
,
152 Make_Object_Declaration
(Loc
,
153 Defining_Identifier
=> Eind
,
154 Constant_Present
=> True,
157 Make_Constrained_Array_Definition
(Loc
,
158 Discrete_Subtype_Definitions
=> New_List
(
160 Low_Bound
=> Make_Integer_Literal
(Loc
, 0),
161 High_Bound
=> Make_Integer_Literal
(Loc
, Nlit
))),
162 Component_Definition
=>
163 Make_Component_Definition
(Loc
,
164 Aliased_Present
=> False,
165 Subtype_Indication
=> New_Occurrence_Of
(Ityp
, Loc
))),
169 Expressions
=> Ind
))),
170 Suppress
=> All_Checks
);
171 end Build_Enumeration_Image_Tables
;
173 ----------------------------
174 -- Expand_Image_Attribute --
175 ----------------------------
177 -- For all cases other than user defined enumeration types, the scheme
178 -- is as follows. First we insert the following code:
180 -- Snn : String (1 .. rt'Width);
182 -- Image_xx (tv, Snn, Pnn [,pm]);
184 -- and then Expr is replaced by Snn (1 .. Pnn)
186 -- In the above expansion:
188 -- rt is the root type of the expression
189 -- tv is the expression with the value, usually a type conversion
190 -- pm is an extra parameter present in some cases
192 -- The following table shows tv, xx, and (if used) pm for the various
193 -- possible types of the argument:
195 -- For types whose root type is Character
197 -- tv = Character (Expr)
199 -- For types whose root type is Boolean
201 -- tv = Boolean (Expr)
203 -- For signed integer types with size <= Integer'Size
205 -- tv = Integer (Expr)
207 -- For other signed integer types
208 -- xx = Long_Long_Integer
209 -- tv = Long_Long_Integer (Expr)
211 -- For modular types with modulus <= System.Unsigned_Types.Unsigned
213 -- tv = System.Unsigned_Types.Unsigned (Expr)
215 -- For other modular integer types
216 -- xx = Long_Long_Unsigned
217 -- tv = System.Unsigned_Types.Long_Long_Unsigned (Expr)
219 -- For types whose root type is Wide_Character
220 -- xx = Wide_Character
221 -- tv = Wide_Character (Expr)
222 -- pm = Boolean, true if Ada 2005 mode, False otherwise
224 -- For types whose root type is Wide_Wide_Character
225 -- xx = Wide_Wide_Character
226 -- tv = Wide_Wide_Character (Expr)
228 -- For floating-point types
229 -- xx = Floating_Point
230 -- tv = Long_Long_Float (Expr)
231 -- pm = typ'Digits (typ = subtype of expression)
233 -- For ordinary fixed-point types
234 -- xx = Ordinary_Fixed_Point
235 -- tv = Long_Long_Float (Expr)
236 -- pm = typ'Aft (typ = subtype of expression)
238 -- For decimal fixed-point types with size = Integer'Size
240 -- tv = Integer (Expr)
241 -- pm = typ'Scale (typ = subtype of expression)
243 -- For decimal fixed-point types with size > Integer'Size
244 -- xx = Long_Long_Decimal
245 -- tv = Long_Long_Integer?(Expr) [convert with no scaling]
246 -- pm = typ'Scale (typ = subtype of expression)
248 -- For enumeration types other than those declared packages Standard
249 -- or System, Snn, Pnn, are expanded as above, but the call looks like:
251 -- Image_Enumeration_NN (rt'Pos (X), Snn, Pnn, typS, typI'Address)
253 -- where rt is the root type of the expression, and typS and typI are
254 -- the entities constructed as described in the spec for the procedure
255 -- Build_Enumeration_Image_Tables and NN is 32/16/8 depending on the
256 -- element type of Lit_Indexes. The rewriting of the expression to
257 -- Snn (1 .. Pnn) then occurs as in the other cases. A special case is
258 -- when pragma Discard_Names applies, in which case we replace expr by:
260 -- (rt'Pos (expr))'Img
262 -- So that the result is a space followed by the decimal value for the
263 -- position of the enumeration value in the enumeration type.
265 procedure Expand_Image_Attribute
(N
: Node_Id
) is
266 Loc
: constant Source_Ptr
:= Sloc
(N
);
267 Exprs
: constant List_Id
:= Expressions
(N
);
268 Pref
: constant Node_Id
:= Prefix
(N
);
269 Expr
: constant Node_Id
:= Relocate_Node
(First
(Exprs
));
275 Proc_Ent
: Entity_Id
;
279 -- List of arguments for run-time procedure call
282 -- List of actions to be inserted
284 Snn
: constant Entity_Id
:= Make_Temporary
(Loc
, 'S');
285 Pnn
: constant Entity_Id
:= Make_Temporary
(Loc
, 'P');
288 if Is_Object_Image
(Pref
) then
289 Rewrite_Object_Image
(N
, Pref
, Name_Image
, Standard_String
);
293 Ptyp
:= Entity
(Pref
);
294 Rtyp
:= Root_Type
(Ptyp
);
296 -- Build declarations of Snn and Pnn to be inserted
298 Ins_List
:= New_List
(
300 -- Snn : String (1 .. typ'Width);
302 Make_Object_Declaration
(Loc
,
303 Defining_Identifier
=> Snn
,
305 Make_Subtype_Indication
(Loc
,
306 Subtype_Mark
=> New_Occurrence_Of
(Standard_String
, Loc
),
308 Make_Index_Or_Discriminant_Constraint
(Loc
,
309 Constraints
=> New_List
(
311 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
313 Make_Attribute_Reference
(Loc
,
314 Prefix
=> New_Occurrence_Of
(Rtyp
, Loc
),
315 Attribute_Name
=> Name_Width
)))))),
319 Make_Object_Declaration
(Loc
,
320 Defining_Identifier
=> Pnn
,
321 Object_Definition
=> New_Occurrence_Of
(Standard_Natural
, Loc
)));
323 -- Set Imid (RE_Id of procedure to call), and Tent, target for the
324 -- type conversion of the first argument for all possibilities.
328 if Rtyp
= Standard_Boolean
then
329 Imid
:= RE_Image_Boolean
;
332 -- For standard character, we have to select the version which handles
333 -- soft hyphen correctly, based on the version of Ada in use (this is
334 -- ugly, but we have no choice).
336 elsif Rtyp
= Standard_Character
then
337 if Ada_Version
< Ada_2005
then
338 Imid
:= RE_Image_Character
;
340 Imid
:= RE_Image_Character_05
;
345 elsif Rtyp
= Standard_Wide_Character
then
346 Imid
:= RE_Image_Wide_Character
;
349 elsif Rtyp
= Standard_Wide_Wide_Character
then
350 Imid
:= RE_Image_Wide_Wide_Character
;
353 elsif Is_Signed_Integer_Type
(Rtyp
) then
354 if Esize
(Rtyp
) <= Esize
(Standard_Integer
) then
355 Imid
:= RE_Image_Integer
;
356 Tent
:= Standard_Integer
;
358 Imid
:= RE_Image_Long_Long_Integer
;
359 Tent
:= Standard_Long_Long_Integer
;
362 elsif Is_Modular_Integer_Type
(Rtyp
) then
363 if Modulus
(Rtyp
) <= Modulus
(RTE
(RE_Unsigned
)) then
364 Imid
:= RE_Image_Unsigned
;
365 Tent
:= RTE
(RE_Unsigned
);
367 Imid
:= RE_Image_Long_Long_Unsigned
;
368 Tent
:= RTE
(RE_Long_Long_Unsigned
);
371 elsif Is_Fixed_Point_Type
(Rtyp
) and then Has_Decimal_Small
(Rtyp
) then
372 if UI_To_Int
(Esize
(Rtyp
)) <= Standard_Integer_Size
then
373 Imid
:= RE_Image_Decimal
;
374 Tent
:= Standard_Integer
;
376 Imid
:= RE_Image_Long_Long_Decimal
;
377 Tent
:= Standard_Long_Long_Integer
;
380 elsif Is_Ordinary_Fixed_Point_Type
(Rtyp
) then
381 Imid
:= RE_Image_Ordinary_Fixed_Point
;
382 Tent
:= Standard_Long_Long_Float
;
384 elsif Is_Floating_Point_Type
(Rtyp
) then
385 Imid
:= RE_Image_Floating_Point
;
386 Tent
:= Standard_Long_Long_Float
;
388 -- Only other possibility is user defined enumeration type
391 if Discard_Names
(First_Subtype
(Ptyp
))
392 or else No
(Lit_Strings
(Root_Type
(Ptyp
)))
394 -- When pragma Discard_Names applies to the first subtype, build
395 -- (Pref'Pos (Expr))'Img.
398 Make_Attribute_Reference
(Loc
,
400 Make_Attribute_Reference
(Loc
,
402 Attribute_Name
=> Name_Pos
,
403 Expressions
=> New_List
(Expr
)),
406 Analyze_And_Resolve
(N
, Standard_String
);
410 -- Here for enumeration type case
412 Ttyp
:= Component_Type
(Etype
(Lit_Indexes
(Rtyp
)));
414 if Ttyp
= Standard_Integer_8
then
415 Imid
:= RE_Image_Enumeration_8
;
417 elsif Ttyp
= Standard_Integer_16
then
418 Imid
:= RE_Image_Enumeration_16
;
421 Imid
:= RE_Image_Enumeration_32
;
424 -- Apply a validity check, since it is a bit drastic to get a
425 -- completely junk image value for an invalid value.
427 if not Expr_Known_Valid
(Expr
) then
428 Insert_Valid_Check
(Expr
);
435 -- Build first argument for call
438 Arg_List
:= New_List
(
439 Make_Attribute_Reference
(Loc
,
440 Attribute_Name
=> Name_Pos
,
441 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
442 Expressions
=> New_List
(Expr
)));
445 Arg_List
:= New_List
(Convert_To
(Tent
, Expr
));
448 -- Append Snn, Pnn arguments
450 Append_To
(Arg_List
, New_Occurrence_Of
(Snn
, Loc
));
451 Append_To
(Arg_List
, New_Occurrence_Of
(Pnn
, Loc
));
453 -- Get entity of procedure to call
455 Proc_Ent
:= RTE
(Imid
);
457 -- If the procedure entity is empty, that means we have a case in
458 -- no run time mode where the operation is not allowed, and an
459 -- appropriate diagnostic has already been issued.
461 if No
(Proc_Ent
) then
465 -- Otherwise complete preparation of arguments for run-time call
467 -- Add extra arguments for Enumeration case
470 Append_To
(Arg_List
, New_Occurrence_Of
(Lit_Strings
(Rtyp
), Loc
));
472 Make_Attribute_Reference
(Loc
,
473 Prefix
=> New_Occurrence_Of
(Lit_Indexes
(Rtyp
), Loc
),
474 Attribute_Name
=> Name_Address
));
476 -- For floating-point types, append Digits argument
478 elsif Is_Floating_Point_Type
(Rtyp
) then
480 Make_Attribute_Reference
(Loc
,
481 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
482 Attribute_Name
=> Name_Digits
));
484 -- For ordinary fixed-point types, append Aft parameter
486 elsif Is_Ordinary_Fixed_Point_Type
(Rtyp
) then
488 Make_Attribute_Reference
(Loc
,
489 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
490 Attribute_Name
=> Name_Aft
));
492 if Has_Decimal_Small
(Rtyp
) then
493 Set_Conversion_OK
(First
(Arg_List
));
494 Set_Etype
(First
(Arg_List
), Tent
);
497 -- For decimal, append Scale and also set to do literal conversion
499 elsif Is_Decimal_Fixed_Point_Type
(Rtyp
) then
501 Make_Attribute_Reference
(Loc
,
502 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
503 Attribute_Name
=> Name_Scale
));
505 Set_Conversion_OK
(First
(Arg_List
));
506 Set_Etype
(First
(Arg_List
), Tent
);
508 -- For Wide_Character, append Ada 2005 indication
510 elsif Rtyp
= Standard_Wide_Character
then
513 (Boolean_Literals
(Ada_Version
>= Ada_2005
), Loc
));
516 -- Now append the procedure call to the insert list
519 Make_Procedure_Call_Statement
(Loc
,
520 Name
=> New_Occurrence_Of
(Proc_Ent
, Loc
),
521 Parameter_Associations
=> Arg_List
));
523 -- Insert declarations of Snn, Pnn, and the procedure call. We suppress
524 -- checks because we are sure that everything is in range at this stage.
526 Insert_Actions
(N
, Ins_List
, Suppress
=> All_Checks
);
528 -- Final step is to rewrite the expression as a slice and analyze,
529 -- again with no checks, since we are sure that everything is OK.
533 Prefix
=> New_Occurrence_Of
(Snn
, Loc
),
536 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
537 High_Bound
=> New_Occurrence_Of
(Pnn
, Loc
))));
539 Analyze_And_Resolve
(N
, Standard_String
, Suppress
=> All_Checks
);
540 end Expand_Image_Attribute
;
542 ----------------------------
543 -- Expand_Value_Attribute --
544 ----------------------------
546 -- For scalar types derived from Boolean, Character and integer types
547 -- in package Standard, typ'Value (X) expands into:
549 -- btyp (Value_xx (X))
551 -- where btyp is he base type of the prefix
553 -- For types whose root type is Character
556 -- For types whose root type is Wide_Character
557 -- xx = Wide_Character
559 -- For types whose root type is Wide_Wide_Character
560 -- xx = Wide_Wide_Character
562 -- For types whose root type is Boolean
565 -- For signed integer types with size <= Integer'Size
568 -- For other signed integer types
569 -- xx = Long_Long_Integer
571 -- For modular types with modulus <= System.Unsigned_Types.Unsigned
574 -- For other modular integer types
575 -- xx = Long_Long_Unsigned
577 -- For floating-point types and ordinary fixed-point types
580 -- For Wide_[Wide_]Character types, typ'Value (X) expands into:
582 -- btyp (Value_xx (X, EM))
584 -- where btyp is the base type of the prefix, and EM is the encoding method
586 -- For decimal types with size <= Integer'Size, typ'Value (X)
589 -- btyp?(Value_Decimal (X, typ'Scale));
591 -- For all other decimal types, typ'Value (X) expands into
593 -- btyp?(Value_Long_Long_Decimal (X, typ'Scale))
595 -- For enumeration types other than those derived from types Boolean,
596 -- Character, Wide_[Wide_]Character in Standard, typ'Value (X) expands to:
598 -- Enum'Val (Value_Enumeration_NN (typS, typI'Address, Num, X))
600 -- where typS and typI and the Lit_Strings and Lit_Indexes entities
601 -- from T's root type entity, and Num is Enum'Pos (Enum'Last). The
602 -- Value_Enumeration_NN function will search the tables looking for
603 -- X and return the position number in the table if found which is
604 -- used to provide the result of 'Value (using Enum'Val). If the
605 -- value is not found Constraint_Error is raised. The suffix _NN
606 -- depends on the element type of typI.
608 procedure Expand_Value_Attribute
(N
: Node_Id
) is
609 Loc
: constant Source_Ptr
:= Sloc
(N
);
610 Typ
: constant Entity_Id
:= Etype
(N
);
611 Btyp
: constant Entity_Id
:= Base_Type
(Typ
);
612 Rtyp
: constant Entity_Id
:= Root_Type
(Typ
);
613 Exprs
: constant List_Id
:= Expressions
(N
);
622 if Rtyp
= Standard_Character
then
623 Vid
:= RE_Value_Character
;
625 elsif Rtyp
= Standard_Boolean
then
626 Vid
:= RE_Value_Boolean
;
628 elsif Rtyp
= Standard_Wide_Character
then
629 Vid
:= RE_Value_Wide_Character
;
632 Make_Integer_Literal
(Loc
,
633 Intval
=> Int
(Wide_Character_Encoding_Method
)));
635 elsif Rtyp
= Standard_Wide_Wide_Character
then
636 Vid
:= RE_Value_Wide_Wide_Character
;
639 Make_Integer_Literal
(Loc
,
640 Intval
=> Int
(Wide_Character_Encoding_Method
)));
642 elsif Rtyp
= Base_Type
(Standard_Short_Short_Integer
)
643 or else Rtyp
= Base_Type
(Standard_Short_Integer
)
644 or else Rtyp
= Base_Type
(Standard_Integer
)
646 Vid
:= RE_Value_Integer
;
648 elsif Is_Signed_Integer_Type
(Rtyp
) then
649 Vid
:= RE_Value_Long_Long_Integer
;
651 elsif Is_Modular_Integer_Type
(Rtyp
) then
652 if Modulus
(Rtyp
) <= Modulus
(RTE
(RE_Unsigned
)) then
653 Vid
:= RE_Value_Unsigned
;
655 Vid
:= RE_Value_Long_Long_Unsigned
;
658 elsif Is_Decimal_Fixed_Point_Type
(Rtyp
) then
659 if UI_To_Int
(Esize
(Rtyp
)) <= Standard_Integer_Size
then
660 Vid
:= RE_Value_Decimal
;
662 Vid
:= RE_Value_Long_Long_Decimal
;
666 Make_Attribute_Reference
(Loc
,
667 Prefix
=> New_Occurrence_Of
(Typ
, Loc
),
668 Attribute_Name
=> Name_Scale
));
672 Make_Function_Call
(Loc
,
673 Name
=> New_Occurrence_Of
(RTE
(Vid
), Loc
),
674 Parameter_Associations
=> Args
)));
677 Analyze_And_Resolve
(N
, Btyp
);
680 elsif Is_Real_Type
(Rtyp
) then
681 Vid
:= RE_Value_Real
;
683 -- Only other possibility is user defined enumeration type
686 pragma Assert
(Is_Enumeration_Type
(Rtyp
));
688 -- Case of pragma Discard_Names, transform the Value
689 -- attribute to Btyp'Val (Long_Long_Integer'Value (Args))
691 if Discard_Names
(First_Subtype
(Typ
))
692 or else No
(Lit_Strings
(Rtyp
))
695 Make_Attribute_Reference
(Loc
,
696 Prefix
=> New_Occurrence_Of
(Btyp
, Loc
),
697 Attribute_Name
=> Name_Val
,
698 Expressions
=> New_List
(
699 Make_Attribute_Reference
(Loc
,
701 New_Occurrence_Of
(Standard_Long_Long_Integer
, Loc
),
702 Attribute_Name
=> Name_Value
,
703 Expressions
=> Args
))));
705 Analyze_And_Resolve
(N
, Btyp
);
707 -- Here for normal case where we have enumeration tables, this
710 -- T'Val (Value_Enumeration_NN (typS, typI'Address, Num, X))
713 Ttyp
:= Component_Type
(Etype
(Lit_Indexes
(Rtyp
)));
715 if Ttyp
= Standard_Integer_8
then
716 Func
:= RE_Value_Enumeration_8
;
717 elsif Ttyp
= Standard_Integer_16
then
718 Func
:= RE_Value_Enumeration_16
;
720 Func
:= RE_Value_Enumeration_32
;
724 Make_Attribute_Reference
(Loc
,
725 Prefix
=> New_Occurrence_Of
(Rtyp
, Loc
),
726 Attribute_Name
=> Name_Pos
,
727 Expressions
=> New_List
(
728 Make_Attribute_Reference
(Loc
,
729 Prefix
=> New_Occurrence_Of
(Rtyp
, Loc
),
730 Attribute_Name
=> Name_Last
))));
733 Make_Attribute_Reference
(Loc
,
734 Prefix
=> New_Occurrence_Of
(Lit_Indexes
(Rtyp
), Loc
),
735 Attribute_Name
=> Name_Address
));
738 New_Occurrence_Of
(Lit_Strings
(Rtyp
), Loc
));
741 Make_Attribute_Reference
(Loc
,
742 Prefix
=> New_Occurrence_Of
(Typ
, Loc
),
743 Attribute_Name
=> Name_Val
,
744 Expressions
=> New_List
(
745 Make_Function_Call
(Loc
,
747 New_Occurrence_Of
(RTE
(Func
), Loc
),
748 Parameter_Associations
=> Args
))));
750 Analyze_And_Resolve
(N
, Btyp
);
756 -- Fall through for all cases except user defined enumeration type
757 -- and decimal types, with Vid set to the Id of the entity for the
758 -- Value routine and Args set to the list of parameters for the call.
760 -- Compiling package Ada.Tags under No_Run_Time_Mode we disable the
761 -- expansion of the attribute into the function call statement to avoid
762 -- generating spurious errors caused by the use of Integer_Address'Value
763 -- in our implementation of Ada.Tags.Internal_Tag
765 -- Seems like a bit of a odd approach, there should be a better way ???
767 -- There is a better way, test RTE_Available ???
770 and then Rtyp
= RTE
(RE_Integer_Address
)
771 and then RTU_Loaded
(Ada_Tags
)
772 and then Cunit_Entity
(Current_Sem_Unit
)
773 = Body_Entity
(RTU_Entity
(Ada_Tags
))
776 Unchecked_Convert_To
(Rtyp
,
777 Make_Integer_Literal
(Loc
, Uint_0
)));
781 Make_Function_Call
(Loc
,
782 Name
=> New_Occurrence_Of
(RTE
(Vid
), Loc
),
783 Parameter_Associations
=> Args
)));
786 Analyze_And_Resolve
(N
, Btyp
);
787 end Expand_Value_Attribute
;
789 ---------------------------------
790 -- Expand_Wide_Image_Attribute --
791 ---------------------------------
793 -- We expand typ'Wide_Image (X) as follows. First we insert this code:
795 -- Rnn : Wide_String (1 .. rt'Wide_Width);
797 -- String_To_Wide_String
798 -- (typ'Image (Expr), Rnn, Lnn, Wide_Character_Encoding_Method);
800 -- where rt is the root type of the prefix type
802 -- Now we replace the Wide_Image reference by
806 -- This works in all cases because String_To_Wide_String converts any
807 -- wide character escape sequences resulting from the Image call to the
808 -- proper Wide_Character equivalent
810 -- not quite right for typ = Wide_Character ???
812 procedure Expand_Wide_Image_Attribute
(N
: Node_Id
) is
813 Loc
: constant Source_Ptr
:= Sloc
(N
);
814 Pref
: constant Entity_Id
:= Prefix
(N
);
815 Rnn
: constant Entity_Id
:= Make_Temporary
(Loc
, 'S');
816 Lnn
: constant Entity_Id
:= Make_Temporary
(Loc
, 'P');
820 if Is_Object_Image
(Pref
) then
821 Rewrite_Object_Image
(N
, Pref
, Name_Wide_Image
, Standard_Wide_String
);
825 Rtyp
:= Root_Type
(Entity
(Pref
));
827 Insert_Actions
(N
, New_List
(
829 -- Rnn : Wide_String (1 .. base_typ'Width);
831 Make_Object_Declaration
(Loc
,
832 Defining_Identifier
=> Rnn
,
834 Make_Subtype_Indication
(Loc
,
836 New_Occurrence_Of
(Standard_Wide_String
, Loc
),
838 Make_Index_Or_Discriminant_Constraint
(Loc
,
839 Constraints
=> New_List
(
841 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
843 Make_Attribute_Reference
(Loc
,
844 Prefix
=> New_Occurrence_Of
(Rtyp
, Loc
),
845 Attribute_Name
=> Name_Wide_Width
)))))),
849 Make_Object_Declaration
(Loc
,
850 Defining_Identifier
=> Lnn
,
851 Object_Definition
=> New_Occurrence_Of
(Standard_Natural
, Loc
)),
853 -- String_To_Wide_String
854 -- (typ'Image (X), Rnn, Lnn, Wide_Character_Encoding_Method);
856 Make_Procedure_Call_Statement
(Loc
,
858 New_Occurrence_Of
(RTE
(RE_String_To_Wide_String
), Loc
),
860 Parameter_Associations
=> New_List
(
861 Make_Attribute_Reference
(Loc
,
862 Prefix
=> Prefix
(N
),
863 Attribute_Name
=> Name_Image
,
864 Expressions
=> Expressions
(N
)),
865 New_Occurrence_Of
(Rnn
, Loc
),
866 New_Occurrence_Of
(Lnn
, Loc
),
867 Make_Integer_Literal
(Loc
,
868 Intval
=> Int
(Wide_Character_Encoding_Method
))))),
870 -- Suppress checks because we know everything is properly in range
872 Suppress
=> All_Checks
);
874 -- Final step is to rewrite the expression as a slice and analyze,
875 -- again with no checks, since we are sure that everything is OK.
879 Prefix
=> New_Occurrence_Of
(Rnn
, Loc
),
882 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
883 High_Bound
=> New_Occurrence_Of
(Lnn
, Loc
))));
885 Analyze_And_Resolve
(N
, Standard_Wide_String
, Suppress
=> All_Checks
);
886 end Expand_Wide_Image_Attribute
;
888 --------------------------------------
889 -- Expand_Wide_Wide_Image_Attribute --
890 --------------------------------------
892 -- We expand typ'Wide_Wide_Image (X) as follows. First we insert this code:
894 -- Rnn : Wide_Wide_String (1 .. rt'Wide_Wide_Width);
896 -- String_To_Wide_Wide_String
897 -- (typ'Image (Expr), Rnn, Lnn, Wide_Character_Encoding_Method);
899 -- where rt is the root type of the prefix type
901 -- Now we replace the Wide_Wide_Image reference by
905 -- This works in all cases because String_To_Wide_Wide_String converts any
906 -- wide character escape sequences resulting from the Image call to the
907 -- proper Wide_Wide_Character equivalent
909 -- not quite right for typ = Wide_Wide_Character ???
911 procedure Expand_Wide_Wide_Image_Attribute
(N
: Node_Id
) is
912 Loc
: constant Source_Ptr
:= Sloc
(N
);
913 Pref
: constant Entity_Id
:= Prefix
(N
);
914 Rnn
: constant Entity_Id
:= Make_Temporary
(Loc
, 'S');
915 Lnn
: constant Entity_Id
:= Make_Temporary
(Loc
, 'P');
919 if Is_Object_Image
(Pref
) then
921 (N
, Pref
, Name_Wide_Wide_Image
, Standard_Wide_Wide_String
);
925 Rtyp
:= Root_Type
(Entity
(Pref
));
927 Insert_Actions
(N
, New_List
(
929 -- Rnn : Wide_Wide_String (1 .. rt'Wide_Wide_Width);
931 Make_Object_Declaration
(Loc
,
932 Defining_Identifier
=> Rnn
,
934 Make_Subtype_Indication
(Loc
,
936 New_Occurrence_Of
(Standard_Wide_Wide_String
, Loc
),
938 Make_Index_Or_Discriminant_Constraint
(Loc
,
939 Constraints
=> New_List
(
941 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
943 Make_Attribute_Reference
(Loc
,
944 Prefix
=> New_Occurrence_Of
(Rtyp
, Loc
),
945 Attribute_Name
=> Name_Wide_Wide_Width
)))))),
949 Make_Object_Declaration
(Loc
,
950 Defining_Identifier
=> Lnn
,
951 Object_Definition
=> New_Occurrence_Of
(Standard_Natural
, Loc
)),
953 -- String_To_Wide_Wide_String
954 -- (typ'Image (X), Rnn, Lnn, Wide_Character_Encoding_Method);
956 Make_Procedure_Call_Statement
(Loc
,
958 New_Occurrence_Of
(RTE
(RE_String_To_Wide_Wide_String
), Loc
),
960 Parameter_Associations
=> New_List
(
961 Make_Attribute_Reference
(Loc
,
962 Prefix
=> Prefix
(N
),
963 Attribute_Name
=> Name_Image
,
964 Expressions
=> Expressions
(N
)),
965 New_Occurrence_Of
(Rnn
, Loc
),
966 New_Occurrence_Of
(Lnn
, Loc
),
967 Make_Integer_Literal
(Loc
,
968 Intval
=> Int
(Wide_Character_Encoding_Method
))))),
970 -- Suppress checks because we know everything is properly in range
972 Suppress
=> All_Checks
);
974 -- Final step is to rewrite the expression as a slice and analyze,
975 -- again with no checks, since we are sure that everything is OK.
979 Prefix
=> New_Occurrence_Of
(Rnn
, Loc
),
982 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
983 High_Bound
=> New_Occurrence_Of
(Lnn
, Loc
))));
986 (N
, Standard_Wide_Wide_String
, Suppress
=> All_Checks
);
987 end Expand_Wide_Wide_Image_Attribute
;
989 ----------------------------
990 -- Expand_Width_Attribute --
991 ----------------------------
993 -- The processing here also handles the case of Wide_[Wide_]Width. With the
994 -- exceptions noted, the processing is identical
996 -- For scalar types derived from Boolean, character and integer types
997 -- in package Standard. Note that the Width attribute is computed at
998 -- compile time for all cases except those involving non-static sub-
999 -- types. For such subtypes, typ'[Wide_[Wide_]]Width expands into:
1001 -- Result_Type (xx (yy (Ptyp'First), yy (Ptyp'Last)))
1005 -- For types whose root type is Character
1006 -- xx = Width_Character
1009 -- For types whose root type is Wide_Character
1010 -- xx = Wide_Width_Character
1013 -- For types whose root type is Wide_Wide_Character
1014 -- xx = Wide_Wide_Width_Character
1017 -- For types whose root type is Boolean
1018 -- xx = Width_Boolean
1021 -- For signed integer types
1022 -- xx = Width_Long_Long_Integer
1023 -- yy = Long_Long_Integer
1025 -- For modular integer types
1026 -- xx = Width_Long_Long_Unsigned
1027 -- yy = Long_Long_Unsigned
1029 -- For types derived from Wide_Character, typ'Width expands into
1031 -- Result_Type (Width_Wide_Character (
1032 -- Wide_Character (typ'First),
1033 -- Wide_Character (typ'Last),
1035 -- and typ'Wide_Width expands into:
1037 -- Result_Type (Wide_Width_Wide_Character (
1038 -- Wide_Character (typ'First),
1039 -- Wide_Character (typ'Last));
1041 -- and typ'Wide_Wide_Width expands into
1043 -- Result_Type (Wide_Wide_Width_Wide_Character (
1044 -- Wide_Character (typ'First),
1045 -- Wide_Character (typ'Last));
1047 -- For types derived from Wide_Wide_Character, typ'Width expands into
1049 -- Result_Type (Width_Wide_Wide_Character (
1050 -- Wide_Wide_Character (typ'First),
1051 -- Wide_Wide_Character (typ'Last),
1053 -- and typ'Wide_Width expands into:
1055 -- Result_Type (Wide_Width_Wide_Wide_Character (
1056 -- Wide_Wide_Character (typ'First),
1057 -- Wide_Wide_Character (typ'Last));
1059 -- and typ'Wide_Wide_Width expands into
1061 -- Result_Type (Wide_Wide_Width_Wide_Wide_Char (
1062 -- Wide_Wide_Character (typ'First),
1063 -- Wide_Wide_Character (typ'Last));
1065 -- For real types, typ'Width and typ'Wide_[Wide_]Width expand into
1067 -- if Ptyp'First > Ptyp'Last then 0 else btyp'Width end if
1069 -- where btyp is the base type. This looks recursive but it isn't
1070 -- because the base type is always static, and hence the expression
1071 -- in the else is reduced to an integer literal.
1073 -- For user defined enumeration types, typ'Width expands into
1075 -- Result_Type (Width_Enumeration_NN
1078 -- typ'Pos (typ'First),
1079 -- typ'Pos (Typ'Last)));
1081 -- and typ'Wide_Width expands into:
1083 -- Result_Type (Wide_Width_Enumeration_NN
1086 -- typ'Pos (typ'First),
1087 -- typ'Pos (Typ'Last))
1088 -- Wide_Character_Encoding_Method);
1090 -- and typ'Wide_Wide_Width expands into:
1092 -- Result_Type (Wide_Wide_Width_Enumeration_NN
1095 -- typ'Pos (typ'First),
1096 -- typ'Pos (Typ'Last))
1097 -- Wide_Character_Encoding_Method);
1099 -- where typS and typI are the enumeration image strings and indexes
1100 -- table, as described in Build_Enumeration_Image_Tables. NN is 8/16/32
1101 -- for depending on the element type for typI.
1103 -- Finally if Discard_Names is in effect for an enumeration type, then
1104 -- a special if expression is built that yields the space needed for the
1105 -- decimal representation of the largest pos value in the subtype. See
1106 -- code below for details.
1108 procedure Expand_Width_Attribute
(N
: Node_Id
; Attr
: Atype
:= Normal
) is
1109 Loc
: constant Source_Ptr
:= Sloc
(N
);
1110 Typ
: constant Entity_Id
:= Etype
(N
);
1111 Pref
: constant Node_Id
:= Prefix
(N
);
1112 Ptyp
: constant Entity_Id
:= Etype
(Pref
);
1113 Rtyp
: constant Entity_Id
:= Root_Type
(Ptyp
);
1120 -- Types derived from Standard.Boolean
1122 if Rtyp
= Standard_Boolean
then
1123 XX
:= RE_Width_Boolean
;
1126 -- Types derived from Standard.Character
1128 elsif Rtyp
= Standard_Character
then
1130 when Normal
=> XX
:= RE_Width_Character
;
1131 when Wide
=> XX
:= RE_Wide_Width_Character
;
1132 when Wide_Wide
=> XX
:= RE_Wide_Wide_Width_Character
;
1137 -- Types derived from Standard.Wide_Character
1139 elsif Rtyp
= Standard_Wide_Character
then
1141 when Normal
=> XX
:= RE_Width_Wide_Character
;
1142 when Wide
=> XX
:= RE_Wide_Width_Wide_Character
;
1143 when Wide_Wide
=> XX
:= RE_Wide_Wide_Width_Wide_Character
;
1148 -- Types derived from Standard.Wide_Wide_Character
1150 elsif Rtyp
= Standard_Wide_Wide_Character
then
1152 when Normal
=> XX
:= RE_Width_Wide_Wide_Character
;
1153 when Wide
=> XX
:= RE_Wide_Width_Wide_Wide_Character
;
1154 when Wide_Wide
=> XX
:= RE_Wide_Wide_Width_Wide_Wide_Char
;
1159 -- Signed integer types
1161 elsif Is_Signed_Integer_Type
(Rtyp
) then
1162 XX
:= RE_Width_Long_Long_Integer
;
1163 YY
:= Standard_Long_Long_Integer
;
1165 -- Modular integer types
1167 elsif Is_Modular_Integer_Type
(Rtyp
) then
1168 XX
:= RE_Width_Long_Long_Unsigned
;
1169 YY
:= RTE
(RE_Long_Long_Unsigned
);
1173 elsif Is_Real_Type
(Rtyp
) then
1175 Make_If_Expression
(Loc
,
1176 Expressions
=> New_List
(
1180 Make_Attribute_Reference
(Loc
,
1181 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
1182 Attribute_Name
=> Name_First
),
1185 Make_Attribute_Reference
(Loc
,
1186 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
1187 Attribute_Name
=> Name_Last
)),
1189 Make_Integer_Literal
(Loc
, 0),
1191 Make_Attribute_Reference
(Loc
,
1192 Prefix
=> New_Occurrence_Of
(Base_Type
(Ptyp
), Loc
),
1193 Attribute_Name
=> Name_Width
))));
1195 Analyze_And_Resolve
(N
, Typ
);
1198 -- User defined enumeration types
1201 pragma Assert
(Is_Enumeration_Type
(Rtyp
));
1203 -- Whenever pragma Discard_Names is in effect, the value we need
1204 -- is the value needed to accommodate the largest integer pos value
1205 -- in the range of the subtype + 1 for the space at the start. We
1208 -- Tnn : constant Integer := Rtyp'Pos (Ptyp'Last)
1210 -- and replace the expression by
1212 -- (if Ptyp'Range_Length = 0 then 0
1213 -- else (if Tnn < 10 then 2
1214 -- else (if Tnn < 100 then 3
1218 -- where n is equal to Rtyp'Pos (Ptyp'Last) + 1
1220 -- Note: The above processing is in accordance with the intent of
1221 -- the RM, which is that Width should be related to the impl-defined
1222 -- behavior of Image. It is not clear what this means if Image is
1223 -- not defined (as in the configurable run-time case for GNAT) and
1224 -- gives an error at compile time.
1226 -- We choose in this case to just go ahead and implement Width the
1227 -- same way, returning what Image would have returned if it has been
1228 -- available in the configurable run-time library.
1230 if Discard_Names
(Rtyp
) then
1232 Tnn
: constant Entity_Id
:= Make_Temporary
(Loc
, 'T');
1240 Make_Object_Declaration
(Loc
,
1241 Defining_Identifier
=> Tnn
,
1242 Constant_Present
=> True,
1243 Object_Definition
=>
1244 New_Occurrence_Of
(Standard_Integer
, Loc
),
1246 Make_Attribute_Reference
(Loc
,
1247 Prefix
=> New_Occurrence_Of
(Rtyp
, Loc
),
1248 Attribute_Name
=> Name_Pos
,
1249 Expressions
=> New_List
(
1251 Make_Attribute_Reference
(Loc
,
1252 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
1253 Attribute_Name
=> Name_Last
))))));
1255 -- OK, now we need to build the if expression. First get the
1256 -- value of M, the largest possible value needed.
1259 (Enumeration_Pos
(Entity
(Type_High_Bound
(Rtyp
))));
1270 Cexpr
:= Make_Integer_Literal
(Loc
, K
);
1272 -- Wrap in inner if's until counted down to 2
1279 Make_If_Expression
(Loc
,
1280 Expressions
=> New_List
(
1282 Left_Opnd
=> New_Occurrence_Of
(Tnn
, Loc
),
1283 Right_Opnd
=> Make_Integer_Literal
(Loc
, M
)),
1284 Make_Integer_Literal
(Loc
, K
),
1288 -- Add initial comparison for null range and we are done, so
1289 -- rewrite the attribute occurrence with this expression.
1293 Make_If_Expression
(Loc
,
1294 Expressions
=> New_List
(
1297 Make_Attribute_Reference
(Loc
,
1298 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
1299 Attribute_Name
=> Name_Range_Length
),
1300 Right_Opnd
=> Make_Integer_Literal
(Loc
, 0)),
1301 Make_Integer_Literal
(Loc
, 0),
1304 Analyze_And_Resolve
(N
, Typ
);
1309 -- Normal case, not Discard_Names
1311 Ttyp
:= Component_Type
(Etype
(Lit_Indexes
(Rtyp
)));
1315 if Ttyp
= Standard_Integer_8
then
1316 XX
:= RE_Width_Enumeration_8
;
1317 elsif Ttyp
= Standard_Integer_16
then
1318 XX
:= RE_Width_Enumeration_16
;
1320 XX
:= RE_Width_Enumeration_32
;
1324 if Ttyp
= Standard_Integer_8
then
1325 XX
:= RE_Wide_Width_Enumeration_8
;
1326 elsif Ttyp
= Standard_Integer_16
then
1327 XX
:= RE_Wide_Width_Enumeration_16
;
1329 XX
:= RE_Wide_Width_Enumeration_32
;
1333 if Ttyp
= Standard_Integer_8
then
1334 XX
:= RE_Wide_Wide_Width_Enumeration_8
;
1335 elsif Ttyp
= Standard_Integer_16
then
1336 XX
:= RE_Wide_Wide_Width_Enumeration_16
;
1338 XX
:= RE_Wide_Wide_Width_Enumeration_32
;
1344 New_Occurrence_Of
(Lit_Strings
(Rtyp
), Loc
),
1346 Make_Attribute_Reference
(Loc
,
1347 Prefix
=> New_Occurrence_Of
(Lit_Indexes
(Rtyp
), Loc
),
1348 Attribute_Name
=> Name_Address
),
1350 Make_Attribute_Reference
(Loc
,
1351 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
1352 Attribute_Name
=> Name_Pos
,
1354 Expressions
=> New_List
(
1355 Make_Attribute_Reference
(Loc
,
1356 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
1357 Attribute_Name
=> Name_First
))),
1359 Make_Attribute_Reference
(Loc
,
1360 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
1361 Attribute_Name
=> Name_Pos
,
1363 Expressions
=> New_List
(
1364 Make_Attribute_Reference
(Loc
,
1365 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
1366 Attribute_Name
=> Name_Last
))));
1370 Make_Function_Call
(Loc
,
1371 Name
=> New_Occurrence_Of
(RTE
(XX
), Loc
),
1372 Parameter_Associations
=> Arglist
)));
1374 Analyze_And_Resolve
(N
, Typ
);
1378 -- If we fall through XX and YY are set
1380 Arglist
:= New_List
(
1382 Make_Attribute_Reference
(Loc
,
1383 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
1384 Attribute_Name
=> Name_First
)),
1387 Make_Attribute_Reference
(Loc
,
1388 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
1389 Attribute_Name
=> Name_Last
)));
1393 Make_Function_Call
(Loc
,
1394 Name
=> New_Occurrence_Of
(RTE
(XX
), Loc
),
1395 Parameter_Associations
=> Arglist
)));
1397 Analyze_And_Resolve
(N
, Typ
);
1398 end Expand_Width_Attribute
;
1400 -----------------------
1401 -- Has_Decimal_Small --
1402 -----------------------
1404 function Has_Decimal_Small
(E
: Entity_Id
) return Boolean is
1406 return Is_Decimal_Fixed_Point_Type
(E
)
1408 (Is_Ordinary_Fixed_Point_Type
(E
)
1409 and then Ureal_10
**Aft_Value
(E
) * Small_Value
(E
) = Ureal_1
);
1410 end Has_Decimal_Small
;
1412 --------------------------
1413 -- Rewrite_Object_Image --
1414 --------------------------
1416 procedure Rewrite_Object_Image
1419 Attr_Name
: Name_Id
;
1420 Str_Typ
: Entity_Id
)
1424 Make_Attribute_Reference
(Sloc
(N
),
1425 Prefix
=> New_Occurrence_Of
(Etype
(Pref
), Sloc
(N
)),
1426 Attribute_Name
=> Attr_Name
,
1427 Expressions
=> New_List
(Relocate_Node
(Pref
))));
1429 Analyze_And_Resolve
(N
, Str_Typ
);
1430 end Rewrite_Object_Image
;