1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2010, 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 Sinfo
; use Sinfo
;
40 with Snames
; use Snames
;
41 with Stand
; use Stand
;
42 with Stringt
; use Stringt
;
43 with Tbuild
; use Tbuild
;
44 with Ttypes
; use Ttypes
;
45 with Uintp
; use Uintp
;
46 with Urealp
; use Urealp
;
48 package body Exp_Imgv
is
50 function Has_Decimal_Small
(E
: Entity_Id
) return Boolean;
51 -- Applies to all entities. True for a Decimal_Fixed_Point_Type, or an
52 -- Ordinary_Fixed_Point_Type with a small that is a negative power of ten.
53 -- Shouldn't this be in einfo.adb or sem_aux.adb???
55 ------------------------------------
56 -- Build_Enumeration_Image_Tables --
57 ------------------------------------
59 procedure Build_Enumeration_Image_Tables
(E
: Entity_Id
; N
: Node_Id
) is
60 Loc
: constant Source_Ptr
:= Sloc
(E
);
71 -- Nothing to do for other than a root enumeration type
73 if E
/= Root_Type
(E
) then
76 -- Nothing to do if pragma Discard_Names applies
78 elsif Discard_Names
(E
) then
82 -- Otherwise tables need constructing
86 Lit
:= First_Literal
(E
);
92 Make_Integer_Literal
(Loc
, UI_From_Int
(Len
)));
97 Get_Unqualified_Decoded_Name_String
(Chars
(Lit
));
99 if Name_Buffer
(1) /= ''' then
100 Set_Casing
(All_Upper_Case
);
103 Store_String_Chars
(Name_Buffer
(1 .. Name_Len
));
104 Len
:= Len
+ Int
(Name_Len
);
108 if Len
< Int
(2 ** (8 - 1)) then
109 Ityp
:= Standard_Integer_8
;
110 elsif Len
< Int
(2 ** (16 - 1)) then
111 Ityp
:= Standard_Integer_16
;
113 Ityp
:= Standard_Integer_32
;
119 Make_Defining_Identifier
(Loc
,
120 Chars
=> New_External_Name
(Chars
(E
), 'S'));
123 Make_Defining_Identifier
(Loc
,
124 Chars
=> New_External_Name
(Chars
(E
), 'N'));
126 Set_Lit_Strings
(E
, Estr
);
127 Set_Lit_Indexes
(E
, Eind
);
131 Make_Object_Declaration
(Loc
,
132 Defining_Identifier
=> Estr
,
133 Constant_Present
=> True,
135 New_Occurrence_Of
(Standard_String
, Loc
),
137 Make_String_Literal
(Loc
,
140 Make_Object_Declaration
(Loc
,
141 Defining_Identifier
=> Eind
,
142 Constant_Present
=> True,
145 Make_Constrained_Array_Definition
(Loc
,
146 Discrete_Subtype_Definitions
=> New_List
(
148 Low_Bound
=> Make_Integer_Literal
(Loc
, 0),
149 High_Bound
=> Make_Integer_Literal
(Loc
, Nlit
))),
150 Component_Definition
=>
151 Make_Component_Definition
(Loc
,
152 Aliased_Present
=> False,
153 Subtype_Indication
=> New_Occurrence_Of
(Ityp
, Loc
))),
157 Expressions
=> Ind
))),
158 Suppress
=> All_Checks
);
159 end Build_Enumeration_Image_Tables
;
161 ----------------------------
162 -- Expand_Image_Attribute --
163 ----------------------------
165 -- For all cases other than user defined enumeration types, the scheme
166 -- is as follows. First we insert the following code:
168 -- Snn : String (1 .. rt'Width);
170 -- Image_xx (tv, Snn, Pnn [,pm]);
172 -- and then Expr is replaced by Snn (1 .. Pnn)
174 -- In the above expansion:
176 -- rt is the root type of the expression
177 -- tv is the expression with the value, usually a type conversion
178 -- pm is an extra parameter present in some cases
180 -- The following table shows tv, xx, and (if used) pm for the various
181 -- possible types of the argument:
183 -- For types whose root type is Character
185 -- tv = Character (Expr)
187 -- For types whose root type is Boolean
189 -- tv = Boolean (Expr)
191 -- For signed integer types with size <= Integer'Size
193 -- tv = Integer (Expr)
195 -- For other signed integer types
196 -- xx = Long_Long_Integer
197 -- tv = Long_Long_Integer (Expr)
199 -- For modular types with modulus <= System.Unsigned_Types.Unsigned
201 -- tv = System.Unsigned_Types.Unsigned (Expr)
203 -- For other modular integer types
204 -- xx = Long_Long_Unsigned
205 -- tv = System.Unsigned_Types.Long_Long_Unsigned (Expr)
207 -- For types whose root type is Wide_Character
208 -- xx = Wide_Character
209 -- tv = Wide_Character (Expr)
210 -- pm = Boolean, true if Ada 2005 mode, False otherwise
212 -- For types whose root type is Wide_Wide_Character
213 -- xx = Wide_Wide_Character
214 -- tv = Wide_Wide_Character (Expr)
216 -- For floating-point types
217 -- xx = Floating_Point
218 -- tv = Long_Long_Float (Expr)
219 -- pm = typ'Digits (typ = subtype of expression)
221 -- For ordinary fixed-point types
222 -- xx = Ordinary_Fixed_Point
223 -- tv = Long_Long_Float (Expr)
224 -- pm = typ'Aft (typ = subtype of expression)
226 -- For decimal fixed-point types with size = Integer'Size
228 -- tv = Integer (Expr)
229 -- pm = typ'Scale (typ = subtype of expression)
231 -- For decimal fixed-point types with size > Integer'Size
232 -- xx = Long_Long_Decimal
233 -- tv = Long_Long_Integer?(Expr) [convert with no scaling]
234 -- pm = typ'Scale (typ = subtype of expression)
236 -- For enumeration types other than those declared packages Standard
237 -- or System, Snn, Pnn, are expanded as above, but the call looks like:
239 -- Image_Enumeration_NN (rt'Pos (X), Snn, Pnn, typS, typI'Address)
241 -- where rt is the root type of the expression, and typS and typI are
242 -- the entities constructed as described in the spec for the procedure
243 -- Build_Enumeration_Image_Tables and NN is 32/16/8 depending on the
244 -- element type of Lit_Indexes. The rewriting of the expression to
245 -- Snn (1 .. Pnn) then occurs as in the other cases. A special case is
246 -- when pragma Discard_Names applies, in which case we replace expr by:
250 procedure Expand_Image_Attribute
(N
: Node_Id
) is
251 Loc
: constant Source_Ptr
:= Sloc
(N
);
252 Exprs
: constant List_Id
:= Expressions
(N
);
253 Pref
: constant Node_Id
:= Prefix
(N
);
254 Ptyp
: constant Entity_Id
:= Entity
(Pref
);
255 Rtyp
: constant Entity_Id
:= Root_Type
(Ptyp
);
256 Expr
: constant Node_Id
:= Relocate_Node
(First
(Exprs
));
260 Proc_Ent
: Entity_Id
;
264 -- List of arguments for run-time procedure call
267 -- List of actions to be inserted
269 Snn
: constant Entity_Id
:= Make_Temporary
(Loc
, 'S');
270 Pnn
: constant Entity_Id
:= Make_Temporary
(Loc
, 'P');
273 -- Build declarations of Snn and Pnn to be inserted
275 Ins_List
:= New_List
(
277 -- Snn : String (1 .. typ'Width);
279 Make_Object_Declaration
(Loc
,
280 Defining_Identifier
=> Snn
,
282 Make_Subtype_Indication
(Loc
,
283 Subtype_Mark
=> New_Occurrence_Of
(Standard_String
, Loc
),
285 Make_Index_Or_Discriminant_Constraint
(Loc
,
286 Constraints
=> New_List
(
288 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
290 Make_Attribute_Reference
(Loc
,
291 Prefix
=> New_Occurrence_Of
(Rtyp
, Loc
),
292 Attribute_Name
=> Name_Width
)))))),
296 Make_Object_Declaration
(Loc
,
297 Defining_Identifier
=> Pnn
,
298 Object_Definition
=> New_Occurrence_Of
(Standard_Natural
, Loc
)));
300 -- Set Imid (RE_Id of procedure to call), and Tent, target for the
301 -- type conversion of the first argument for all possibilities.
305 if Rtyp
= Standard_Boolean
then
306 Imid
:= RE_Image_Boolean
;
309 elsif Rtyp
= Standard_Character
then
310 Imid
:= RE_Image_Character
;
313 elsif Rtyp
= Standard_Wide_Character
then
314 Imid
:= RE_Image_Wide_Character
;
317 elsif Rtyp
= Standard_Wide_Wide_Character
then
318 Imid
:= RE_Image_Wide_Wide_Character
;
321 elsif Is_Signed_Integer_Type
(Rtyp
) then
322 if Esize
(Rtyp
) <= Esize
(Standard_Integer
) then
323 Imid
:= RE_Image_Integer
;
324 Tent
:= Standard_Integer
;
326 Imid
:= RE_Image_Long_Long_Integer
;
327 Tent
:= Standard_Long_Long_Integer
;
330 elsif Is_Modular_Integer_Type
(Rtyp
) then
331 if Modulus
(Rtyp
) <= Modulus
(RTE
(RE_Unsigned
)) then
332 Imid
:= RE_Image_Unsigned
;
333 Tent
:= RTE
(RE_Unsigned
);
335 Imid
:= RE_Image_Long_Long_Unsigned
;
336 Tent
:= RTE
(RE_Long_Long_Unsigned
);
339 elsif Is_Fixed_Point_Type
(Rtyp
) and then Has_Decimal_Small
(Rtyp
) then
340 if UI_To_Int
(Esize
(Rtyp
)) <= Standard_Integer_Size
then
341 Imid
:= RE_Image_Decimal
;
342 Tent
:= Standard_Integer
;
344 Imid
:= RE_Image_Long_Long_Decimal
;
345 Tent
:= Standard_Long_Long_Integer
;
348 elsif Is_Ordinary_Fixed_Point_Type
(Rtyp
) then
349 Imid
:= RE_Image_Ordinary_Fixed_Point
;
350 Tent
:= Standard_Long_Long_Float
;
352 elsif Is_Floating_Point_Type
(Rtyp
) then
353 Imid
:= RE_Image_Floating_Point
;
354 Tent
:= Standard_Long_Long_Float
;
356 -- Only other possibility is user defined enumeration type
359 if Discard_Names
(First_Subtype
(Ptyp
))
360 or else No
(Lit_Strings
(Root_Type
(Ptyp
)))
362 -- When pragma Discard_Names applies to the first subtype, build
366 Make_Attribute_Reference
(Loc
,
368 Make_Attribute_Reference
(Loc
,
370 Attribute_Name
=> Name_Pos
,
371 Expressions
=> New_List
(Expr
)),
374 Analyze_And_Resolve
(N
, Standard_String
);
378 -- Here for enumeration type case
380 Ttyp
:= Component_Type
(Etype
(Lit_Indexes
(Rtyp
)));
382 if Ttyp
= Standard_Integer_8
then
383 Imid
:= RE_Image_Enumeration_8
;
385 elsif Ttyp
= Standard_Integer_16
then
386 Imid
:= RE_Image_Enumeration_16
;
389 Imid
:= RE_Image_Enumeration_32
;
392 -- Apply a validity check, since it is a bit drastic to get a
393 -- completely junk image value for an invalid value.
395 if not Expr_Known_Valid
(Expr
) then
396 Insert_Valid_Check
(Expr
);
403 -- Build first argument for call
406 Arg_List
:= New_List
(
407 Make_Attribute_Reference
(Loc
,
408 Attribute_Name
=> Name_Pos
,
409 Prefix
=> New_Occurrence_Of
(Ptyp
, Loc
),
410 Expressions
=> New_List
(Expr
)));
413 Arg_List
:= New_List
(Convert_To
(Tent
, Expr
));
416 -- Append Snn, Pnn arguments
418 Append_To
(Arg_List
, New_Occurrence_Of
(Snn
, Loc
));
419 Append_To
(Arg_List
, New_Occurrence_Of
(Pnn
, Loc
));
421 -- Get entity of procedure to call
423 Proc_Ent
:= RTE
(Imid
);
425 -- If the procedure entity is empty, that means we have a case in
426 -- no run time mode where the operation is not allowed, and an
427 -- appropriate diagnostic has already been issued.
429 if No
(Proc_Ent
) then
433 -- Otherwise complete preparation of arguments for run-time call
435 -- Add extra arguments for Enumeration case
438 Append_To
(Arg_List
, New_Occurrence_Of
(Lit_Strings
(Rtyp
), Loc
));
440 Make_Attribute_Reference
(Loc
,
441 Prefix
=> New_Occurrence_Of
(Lit_Indexes
(Rtyp
), Loc
),
442 Attribute_Name
=> Name_Address
));
444 -- For floating-point types, append Digits argument
446 elsif Is_Floating_Point_Type
(Rtyp
) then
448 Make_Attribute_Reference
(Loc
,
449 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
450 Attribute_Name
=> Name_Digits
));
452 -- For ordinary fixed-point types, append Aft parameter
454 elsif Is_Ordinary_Fixed_Point_Type
(Rtyp
) then
456 Make_Attribute_Reference
(Loc
,
457 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
458 Attribute_Name
=> Name_Aft
));
460 if Has_Decimal_Small
(Rtyp
) then
461 Set_Conversion_OK
(First
(Arg_List
));
462 Set_Etype
(First
(Arg_List
), Tent
);
465 -- For decimal, append Scale and also set to do literal conversion
467 elsif Is_Decimal_Fixed_Point_Type
(Rtyp
) then
469 Make_Attribute_Reference
(Loc
,
470 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
471 Attribute_Name
=> Name_Scale
));
473 Set_Conversion_OK
(First
(Arg_List
));
474 Set_Etype
(First
(Arg_List
), Tent
);
476 -- For Wide_Character, append Ada 2005 indication
478 elsif Rtyp
= Standard_Wide_Character
then
480 New_Reference_To
(Boolean_Literals
(Ada_Version
>= Ada_05
), Loc
));
483 -- Now append the procedure call to the insert list
486 Make_Procedure_Call_Statement
(Loc
,
487 Name
=> New_Reference_To
(Proc_Ent
, Loc
),
488 Parameter_Associations
=> Arg_List
));
490 -- Insert declarations of Snn, Pnn, and the procedure call. We suppress
491 -- checks because we are sure that everything is in range at this stage.
493 Insert_Actions
(N
, Ins_List
, Suppress
=> All_Checks
);
495 -- Final step is to rewrite the expression as a slice and analyze,
496 -- again with no checks, since we are sure that everything is OK.
500 Prefix
=> New_Occurrence_Of
(Snn
, Loc
),
503 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
504 High_Bound
=> New_Occurrence_Of
(Pnn
, Loc
))));
506 Analyze_And_Resolve
(N
, Standard_String
, Suppress
=> All_Checks
);
507 end Expand_Image_Attribute
;
509 ----------------------------
510 -- Expand_Value_Attribute --
511 ----------------------------
513 -- For scalar types derived from Boolean, Character and integer types
514 -- in package Standard, typ'Value (X) expands into:
516 -- btyp (Value_xx (X))
518 -- where btyp is he base type of the prefix
520 -- For types whose root type is Character
523 -- For types whose root type is Wide_Character
524 -- xx = Wide_Character
526 -- For types whose root type is Wide_Wide_Character
527 -- xx = Wide_Wide_Character
529 -- For types whose root type is Boolean
532 -- For signed integer types with size <= Integer'Size
535 -- For other signed integer types
536 -- xx = Long_Long_Integer
538 -- For modular types with modulus <= System.Unsigned_Types.Unsigned
541 -- For other modular integer types
542 -- xx = Long_Long_Unsigned
544 -- For floating-point types and ordinary fixed-point types
547 -- For Wide_[Wide_]Character types, typ'Value (X) expands into:
549 -- btyp (Value_xx (X, EM))
551 -- where btyp is the base type of the prefix, and EM is the encoding method
553 -- For decimal types with size <= Integer'Size, typ'Value (X)
556 -- btyp?(Value_Decimal (X, typ'Scale));
558 -- For all other decimal types, typ'Value (X) expands into
560 -- btyp?(Value_Long_Long_Decimal (X, typ'Scale))
562 -- For enumeration types other than those derived from types Boolean,
563 -- Character, Wide_[Wide_]Character in Standard, typ'Value (X) expands to:
565 -- Enum'Val (Value_Enumeration_NN (typS, typI'Address, Num, X))
567 -- where typS and typI and the Lit_Strings and Lit_Indexes entities
568 -- from T's root type entity, and Num is Enum'Pos (Enum'Last). The
569 -- Value_Enumeration_NN function will search the tables looking for
570 -- X and return the position number in the table if found which is
571 -- used to provide the result of 'Value (using Enum'Val). If the
572 -- value is not found Constraint_Error is raised. The suffix _NN
573 -- depends on the element type of typI.
575 procedure Expand_Value_Attribute
(N
: Node_Id
) is
576 Loc
: constant Source_Ptr
:= Sloc
(N
);
577 Typ
: constant Entity_Id
:= Etype
(N
);
578 Btyp
: constant Entity_Id
:= Base_Type
(Typ
);
579 Rtyp
: constant Entity_Id
:= Root_Type
(Typ
);
580 Exprs
: constant List_Id
:= Expressions
(N
);
589 if Rtyp
= Standard_Character
then
590 Vid
:= RE_Value_Character
;
592 elsif Rtyp
= Standard_Boolean
then
593 Vid
:= RE_Value_Boolean
;
595 elsif Rtyp
= Standard_Wide_Character
then
596 Vid
:= RE_Value_Wide_Character
;
599 Make_Integer_Literal
(Loc
,
600 Intval
=> Int
(Wide_Character_Encoding_Method
)));
602 elsif Rtyp
= Standard_Wide_Wide_Character
then
603 Vid
:= RE_Value_Wide_Wide_Character
;
606 Make_Integer_Literal
(Loc
,
607 Intval
=> Int
(Wide_Character_Encoding_Method
)));
609 elsif Rtyp
= Base_Type
(Standard_Short_Short_Integer
)
610 or else Rtyp
= Base_Type
(Standard_Short_Integer
)
611 or else Rtyp
= Base_Type
(Standard_Integer
)
613 Vid
:= RE_Value_Integer
;
615 elsif Is_Signed_Integer_Type
(Rtyp
) then
616 Vid
:= RE_Value_Long_Long_Integer
;
618 elsif Is_Modular_Integer_Type
(Rtyp
) then
619 if Modulus
(Rtyp
) <= Modulus
(RTE
(RE_Unsigned
)) then
620 Vid
:= RE_Value_Unsigned
;
622 Vid
:= RE_Value_Long_Long_Unsigned
;
625 elsif Is_Decimal_Fixed_Point_Type
(Rtyp
) then
626 if UI_To_Int
(Esize
(Rtyp
)) <= Standard_Integer_Size
then
627 Vid
:= RE_Value_Decimal
;
629 Vid
:= RE_Value_Long_Long_Decimal
;
633 Make_Attribute_Reference
(Loc
,
634 Prefix
=> New_Reference_To
(Typ
, Loc
),
635 Attribute_Name
=> Name_Scale
));
639 Make_Function_Call
(Loc
,
640 Name
=> New_Reference_To
(RTE
(Vid
), Loc
),
641 Parameter_Associations
=> Args
)));
644 Analyze_And_Resolve
(N
, Btyp
);
647 elsif Is_Real_Type
(Rtyp
) then
648 Vid
:= RE_Value_Real
;
650 -- Only other possibility is user defined enumeration type
653 pragma Assert
(Is_Enumeration_Type
(Rtyp
));
655 -- Case of pragma Discard_Names, transform the Value
656 -- attribute to Btyp'Val (Long_Long_Integer'Value (Args))
658 if Discard_Names
(First_Subtype
(Typ
))
659 or else No
(Lit_Strings
(Rtyp
))
662 Make_Attribute_Reference
(Loc
,
663 Prefix
=> New_Reference_To
(Btyp
, Loc
),
664 Attribute_Name
=> Name_Val
,
665 Expressions
=> New_List
(
666 Make_Attribute_Reference
(Loc
,
668 New_Occurrence_Of
(Standard_Long_Long_Integer
, Loc
),
669 Attribute_Name
=> Name_Value
,
670 Expressions
=> Args
))));
672 Analyze_And_Resolve
(N
, Btyp
);
674 -- Here for normal case where we have enumeration tables, this
677 -- T'Val (Value_Enumeration_NN (typS, typI'Address, Num, X))
680 Ttyp
:= Component_Type
(Etype
(Lit_Indexes
(Rtyp
)));
682 if Ttyp
= Standard_Integer_8
then
683 Func
:= RE_Value_Enumeration_8
;
684 elsif Ttyp
= Standard_Integer_16
then
685 Func
:= RE_Value_Enumeration_16
;
687 Func
:= RE_Value_Enumeration_32
;
691 Make_Attribute_Reference
(Loc
,
692 Prefix
=> New_Occurrence_Of
(Rtyp
, Loc
),
693 Attribute_Name
=> Name_Pos
,
694 Expressions
=> New_List
(
695 Make_Attribute_Reference
(Loc
,
696 Prefix
=> New_Occurrence_Of
(Rtyp
, Loc
),
697 Attribute_Name
=> Name_Last
))));
700 Make_Attribute_Reference
(Loc
,
701 Prefix
=> New_Occurrence_Of
(Lit_Indexes
(Rtyp
), Loc
),
702 Attribute_Name
=> Name_Address
));
705 New_Occurrence_Of
(Lit_Strings
(Rtyp
), Loc
));
708 Make_Attribute_Reference
(Loc
,
709 Prefix
=> New_Reference_To
(Typ
, Loc
),
710 Attribute_Name
=> Name_Val
,
711 Expressions
=> New_List
(
712 Make_Function_Call
(Loc
,
714 New_Reference_To
(RTE
(Func
), Loc
),
715 Parameter_Associations
=> Args
))));
717 Analyze_And_Resolve
(N
, Btyp
);
723 -- Fall through for all cases except user defined enumeration type
724 -- and decimal types, with Vid set to the Id of the entity for the
725 -- Value routine and Args set to the list of parameters for the call.
727 -- Compiling package Ada.Tags under No_Run_Time_Mode we disable the
728 -- expansion of the attribute into the function call statement to avoid
729 -- generating spurious errors caused by the use of Integer_Address'Value
730 -- in our implementation of Ada.Tags.Internal_Tag
732 -- Seems like a bit of a kludge, there should be a better way ???
734 -- There is a better way, you should also test RTE_Available ???
737 and then Rtyp
= RTE
(RE_Integer_Address
)
738 and then RTU_Loaded
(Ada_Tags
)
739 and then Cunit_Entity
(Current_Sem_Unit
)
740 = Body_Entity
(RTU_Entity
(Ada_Tags
))
743 Unchecked_Convert_To
(Rtyp
,
744 Make_Integer_Literal
(Loc
, Uint_0
)));
748 Make_Function_Call
(Loc
,
749 Name
=> New_Reference_To
(RTE
(Vid
), Loc
),
750 Parameter_Associations
=> Args
)));
753 Analyze_And_Resolve
(N
, Btyp
);
754 end Expand_Value_Attribute
;
756 ---------------------------------
757 -- Expand_Wide_Image_Attribute --
758 ---------------------------------
760 -- We expand typ'Wide_Image (X) as follows. First we insert this code:
762 -- Rnn : Wide_String (1 .. rt'Wide_Width);
764 -- String_To_Wide_String
765 -- (typ'Image (Expr), Rnn, Lnn, Wide_Character_Encoding_Method);
767 -- where rt is the root type of the prefix type
769 -- Now we replace the Wide_Image reference by
773 -- This works in all cases because String_To_Wide_String converts any
774 -- wide character escape sequences resulting from the Image call to the
775 -- proper Wide_Character equivalent
777 -- not quite right for typ = Wide_Character ???
779 procedure Expand_Wide_Image_Attribute
(N
: Node_Id
) is
780 Loc
: constant Source_Ptr
:= Sloc
(N
);
781 Rtyp
: constant Entity_Id
:= Root_Type
(Entity
(Prefix
(N
)));
782 Rnn
: constant Entity_Id
:= Make_Temporary
(Loc
, 'S');
783 Lnn
: constant Entity_Id
:= Make_Temporary
(Loc
, 'P');
786 Insert_Actions
(N
, New_List
(
788 -- Rnn : Wide_String (1 .. base_typ'Width);
790 Make_Object_Declaration
(Loc
,
791 Defining_Identifier
=> Rnn
,
793 Make_Subtype_Indication
(Loc
,
795 New_Occurrence_Of
(Standard_Wide_String
, Loc
),
797 Make_Index_Or_Discriminant_Constraint
(Loc
,
798 Constraints
=> New_List
(
800 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
802 Make_Attribute_Reference
(Loc
,
803 Prefix
=> New_Occurrence_Of
(Rtyp
, Loc
),
804 Attribute_Name
=> Name_Wide_Width
)))))),
808 Make_Object_Declaration
(Loc
,
809 Defining_Identifier
=> Lnn
,
810 Object_Definition
=> New_Occurrence_Of
(Standard_Natural
, Loc
)),
812 -- String_To_Wide_String
813 -- (typ'Image (X), Rnn, Lnn, Wide_Character_Encoding_Method);
815 Make_Procedure_Call_Statement
(Loc
,
817 New_Reference_To
(RTE
(RE_String_To_Wide_String
), Loc
),
819 Parameter_Associations
=> New_List
(
820 Make_Attribute_Reference
(Loc
,
821 Prefix
=> Prefix
(N
),
822 Attribute_Name
=> Name_Image
,
823 Expressions
=> Expressions
(N
)),
824 New_Reference_To
(Rnn
, Loc
),
825 New_Reference_To
(Lnn
, Loc
),
826 Make_Integer_Literal
(Loc
,
827 Intval
=> Int
(Wide_Character_Encoding_Method
))))),
829 -- Suppress checks because we know everything is properly in range
831 Suppress
=> All_Checks
);
833 -- Final step is to rewrite the expression as a slice and analyze,
834 -- again with no checks, since we are sure that everything is OK.
838 Prefix
=> New_Occurrence_Of
(Rnn
, Loc
),
841 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
842 High_Bound
=> New_Occurrence_Of
(Lnn
, Loc
))));
844 Analyze_And_Resolve
(N
, Standard_Wide_String
, Suppress
=> All_Checks
);
845 end Expand_Wide_Image_Attribute
;
847 --------------------------------------
848 -- Expand_Wide_Wide_Image_Attribute --
849 --------------------------------------
851 -- We expand typ'Wide_Wide_Image (X) as follows. First we insert this code:
853 -- Rnn : Wide_Wide_String (1 .. rt'Wide_Wide_Width);
855 -- String_To_Wide_Wide_String
856 -- (typ'Image (Expr), Rnn, Lnn, Wide_Character_Encoding_Method);
858 -- where rt is the root type of the prefix type
860 -- Now we replace the Wide_Wide_Image reference by
864 -- This works in all cases because String_To_Wide_Wide_String converts any
865 -- wide character escape sequences resulting from the Image call to the
866 -- proper Wide_Wide_Character equivalent
868 -- not quite right for typ = Wide_Wide_Character ???
870 procedure Expand_Wide_Wide_Image_Attribute
(N
: Node_Id
) is
871 Loc
: constant Source_Ptr
:= Sloc
(N
);
872 Rtyp
: constant Entity_Id
:= Root_Type
(Entity
(Prefix
(N
)));
874 Rnn
: constant Entity_Id
:= Make_Temporary
(Loc
, 'S');
875 Lnn
: constant Entity_Id
:= Make_Temporary
(Loc
, 'P');
878 Insert_Actions
(N
, New_List
(
880 -- Rnn : Wide_Wide_String (1 .. rt'Wide_Wide_Width);
882 Make_Object_Declaration
(Loc
,
883 Defining_Identifier
=> Rnn
,
885 Make_Subtype_Indication
(Loc
,
887 New_Occurrence_Of
(Standard_Wide_Wide_String
, Loc
),
889 Make_Index_Or_Discriminant_Constraint
(Loc
,
890 Constraints
=> New_List
(
892 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
894 Make_Attribute_Reference
(Loc
,
895 Prefix
=> New_Occurrence_Of
(Rtyp
, Loc
),
896 Attribute_Name
=> Name_Wide_Wide_Width
)))))),
900 Make_Object_Declaration
(Loc
,
901 Defining_Identifier
=> Lnn
,
902 Object_Definition
=> New_Occurrence_Of
(Standard_Natural
, Loc
)),
904 -- String_To_Wide_Wide_String
905 -- (typ'Image (X), Rnn, Lnn, Wide_Character_Encoding_Method);
907 Make_Procedure_Call_Statement
(Loc
,
909 New_Reference_To
(RTE
(RE_String_To_Wide_Wide_String
), Loc
),
911 Parameter_Associations
=> New_List
(
912 Make_Attribute_Reference
(Loc
,
913 Prefix
=> Prefix
(N
),
914 Attribute_Name
=> Name_Image
,
915 Expressions
=> Expressions
(N
)),
916 New_Reference_To
(Rnn
, Loc
),
917 New_Reference_To
(Lnn
, Loc
),
918 Make_Integer_Literal
(Loc
,
919 Intval
=> Int
(Wide_Character_Encoding_Method
))))),
921 -- Suppress checks because we know everything is properly in range
923 Suppress
=> All_Checks
);
925 -- Final step is to rewrite the expression as a slice and analyze,
926 -- again with no checks, since we are sure that everything is OK.
930 Prefix
=> New_Occurrence_Of
(Rnn
, Loc
),
933 Low_Bound
=> Make_Integer_Literal
(Loc
, 1),
934 High_Bound
=> New_Occurrence_Of
(Lnn
, Loc
))));
937 (N
, Standard_Wide_Wide_String
, Suppress
=> All_Checks
);
938 end Expand_Wide_Wide_Image_Attribute
;
940 ----------------------------
941 -- Expand_Width_Attribute --
942 ----------------------------
944 -- The processing here also handles the case of Wide_[Wide_]Width. With the
945 -- exceptions noted, the processing is identical
947 -- For scalar types derived from Boolean, character and integer types
948 -- in package Standard. Note that the Width attribute is computed at
949 -- compile time for all cases except those involving non-static sub-
950 -- types. For such subtypes, typ'[Wide_[Wide_]]Width expands into:
952 -- Result_Type (xx (yy (Ptyp'First), yy (Ptyp'Last)))
956 -- For types whose root type is Character
957 -- xx = Width_Character
960 -- For types whose root type is Wide_Character
961 -- xx = Wide_Width_Character
964 -- For types whose root type is Wide_Wide_Character
965 -- xx = Wide_Wide_Width_Character
968 -- For types whose root type is Boolean
969 -- xx = Width_Boolean
972 -- For signed integer types
973 -- xx = Width_Long_Long_Integer
974 -- yy = Long_Long_Integer
976 -- For modular integer types
977 -- xx = Width_Long_Long_Unsigned
978 -- yy = Long_Long_Unsigned
980 -- For types derived from Wide_Character, typ'Width expands into
982 -- Result_Type (Width_Wide_Character (
983 -- Wide_Character (typ'First),
984 -- Wide_Character (typ'Last),
986 -- and typ'Wide_Width expands into:
988 -- Result_Type (Wide_Width_Wide_Character (
989 -- Wide_Character (typ'First),
990 -- Wide_Character (typ'Last));
992 -- and typ'Wide_Wide_Width expands into
994 -- Result_Type (Wide_Wide_Width_Wide_Character (
995 -- Wide_Character (typ'First),
996 -- Wide_Character (typ'Last));
998 -- For types derived from Wide_Wide_Character, typ'Width expands into
1000 -- Result_Type (Width_Wide_Wide_Character (
1001 -- Wide_Wide_Character (typ'First),
1002 -- Wide_Wide_Character (typ'Last),
1004 -- and typ'Wide_Width expands into:
1006 -- Result_Type (Wide_Width_Wide_Wide_Character (
1007 -- Wide_Wide_Character (typ'First),
1008 -- Wide_Wide_Character (typ'Last));
1010 -- and typ'Wide_Wide_Width expands into
1012 -- Result_Type (Wide_Wide_Width_Wide_Wide_Char (
1013 -- Wide_Wide_Character (typ'First),
1014 -- Wide_Wide_Character (typ'Last));
1016 -- For real types, typ'Width and typ'Wide_[Wide_]Width expand into
1018 -- if Ptyp'First > Ptyp'Last then 0 else btyp'Width end if
1020 -- where btyp is the base type. This looks recursive but it isn't
1021 -- because the base type is always static, and hence the expression
1022 -- in the else is reduced to an integer literal.
1024 -- For user defined enumeration types, typ'Width expands into
1026 -- Result_Type (Width_Enumeration_NN
1029 -- typ'Pos (typ'First),
1030 -- typ'Pos (Typ'Last)));
1032 -- and typ'Wide_Width expands into:
1034 -- Result_Type (Wide_Width_Enumeration_NN
1037 -- typ'Pos (typ'First),
1038 -- typ'Pos (Typ'Last))
1039 -- Wide_Character_Encoding_Method);
1041 -- and typ'Wide_Wide_Width expands into:
1043 -- Result_Type (Wide_Wide_Width_Enumeration_NN
1046 -- typ'Pos (typ'First),
1047 -- typ'Pos (Typ'Last))
1048 -- Wide_Character_Encoding_Method);
1050 -- where typS and typI are the enumeration image strings and
1051 -- indexes table, as described in Build_Enumeration_Image_Tables.
1052 -- NN is 8/16/32 for depending on the element type for typI.
1054 procedure Expand_Width_Attribute
(N
: Node_Id
; Attr
: Atype
:= Normal
) is
1055 Loc
: constant Source_Ptr
:= Sloc
(N
);
1056 Typ
: constant Entity_Id
:= Etype
(N
);
1057 Pref
: constant Node_Id
:= Prefix
(N
);
1058 Ptyp
: constant Entity_Id
:= Etype
(Pref
);
1059 Rtyp
: constant Entity_Id
:= Root_Type
(Ptyp
);
1066 -- Types derived from Standard.Boolean
1068 if Rtyp
= Standard_Boolean
then
1069 XX
:= RE_Width_Boolean
;
1072 -- Types derived from Standard.Character
1074 elsif Rtyp
= Standard_Character
then
1076 when Normal
=> XX
:= RE_Width_Character
;
1077 when Wide
=> XX
:= RE_Wide_Width_Character
;
1078 when Wide_Wide
=> XX
:= RE_Wide_Wide_Width_Character
;
1083 -- Types derived from Standard.Wide_Character
1085 elsif Rtyp
= Standard_Wide_Character
then
1087 when Normal
=> XX
:= RE_Width_Wide_Character
;
1088 when Wide
=> XX
:= RE_Wide_Width_Wide_Character
;
1089 when Wide_Wide
=> XX
:= RE_Wide_Wide_Width_Wide_Character
;
1094 -- Types derived from Standard.Wide_Wide_Character
1096 elsif Rtyp
= Standard_Wide_Wide_Character
then
1098 when Normal
=> XX
:= RE_Width_Wide_Wide_Character
;
1099 when Wide
=> XX
:= RE_Wide_Width_Wide_Wide_Character
;
1100 when Wide_Wide
=> XX
:= RE_Wide_Wide_Width_Wide_Wide_Char
;
1105 -- Signed integer types
1107 elsif Is_Signed_Integer_Type
(Rtyp
) then
1108 XX
:= RE_Width_Long_Long_Integer
;
1109 YY
:= Standard_Long_Long_Integer
;
1111 -- Modular integer types
1113 elsif Is_Modular_Integer_Type
(Rtyp
) then
1114 XX
:= RE_Width_Long_Long_Unsigned
;
1115 YY
:= RTE
(RE_Long_Long_Unsigned
);
1119 elsif Is_Real_Type
(Rtyp
) then
1122 Make_Conditional_Expression
(Loc
,
1123 Expressions
=> New_List
(
1127 Make_Attribute_Reference
(Loc
,
1128 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
1129 Attribute_Name
=> Name_First
),
1132 Make_Attribute_Reference
(Loc
,
1133 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
1134 Attribute_Name
=> Name_Last
)),
1136 Make_Integer_Literal
(Loc
, 0),
1138 Make_Attribute_Reference
(Loc
,
1139 Prefix
=> New_Reference_To
(Base_Type
(Ptyp
), Loc
),
1140 Attribute_Name
=> Name_Width
))));
1142 Analyze_And_Resolve
(N
, Typ
);
1145 -- User defined enumeration types
1148 pragma Assert
(Is_Enumeration_Type
(Rtyp
));
1150 if Discard_Names
(Rtyp
) then
1152 -- This is a configurable run-time, or else a restriction is in
1153 -- effect. In either case the attribute cannot be supported. Force
1154 -- a load error from Rtsfind to generate an appropriate message,
1155 -- as is done with other ZFP violations.
1158 Discard
: constant Entity_Id
:= RTE
(RE_Null
);
1159 pragma Unreferenced
(Discard
);
1165 Ttyp
:= Component_Type
(Etype
(Lit_Indexes
(Rtyp
)));
1169 if Ttyp
= Standard_Integer_8
then
1170 XX
:= RE_Width_Enumeration_8
;
1171 elsif Ttyp
= Standard_Integer_16
then
1172 XX
:= RE_Width_Enumeration_16
;
1174 XX
:= RE_Width_Enumeration_32
;
1178 if Ttyp
= Standard_Integer_8
then
1179 XX
:= RE_Wide_Width_Enumeration_8
;
1180 elsif Ttyp
= Standard_Integer_16
then
1181 XX
:= RE_Wide_Width_Enumeration_16
;
1183 XX
:= RE_Wide_Width_Enumeration_32
;
1187 if Ttyp
= Standard_Integer_8
then
1188 XX
:= RE_Wide_Wide_Width_Enumeration_8
;
1189 elsif Ttyp
= Standard_Integer_16
then
1190 XX
:= RE_Wide_Wide_Width_Enumeration_16
;
1192 XX
:= RE_Wide_Wide_Width_Enumeration_32
;
1198 New_Occurrence_Of
(Lit_Strings
(Rtyp
), Loc
),
1200 Make_Attribute_Reference
(Loc
,
1201 Prefix
=> New_Occurrence_Of
(Lit_Indexes
(Rtyp
), Loc
),
1202 Attribute_Name
=> Name_Address
),
1204 Make_Attribute_Reference
(Loc
,
1205 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
1206 Attribute_Name
=> Name_Pos
,
1208 Expressions
=> New_List
(
1209 Make_Attribute_Reference
(Loc
,
1210 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
1211 Attribute_Name
=> Name_First
))),
1213 Make_Attribute_Reference
(Loc
,
1214 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
1215 Attribute_Name
=> Name_Pos
,
1217 Expressions
=> New_List
(
1218 Make_Attribute_Reference
(Loc
,
1219 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
1220 Attribute_Name
=> Name_Last
))));
1224 Make_Function_Call
(Loc
,
1225 Name
=> New_Reference_To
(RTE
(XX
), Loc
),
1226 Parameter_Associations
=> Arglist
)));
1228 Analyze_And_Resolve
(N
, Typ
);
1232 -- If we fall through XX and YY are set
1234 Arglist
:= New_List
(
1236 Make_Attribute_Reference
(Loc
,
1237 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
1238 Attribute_Name
=> Name_First
)),
1241 Make_Attribute_Reference
(Loc
,
1242 Prefix
=> New_Reference_To
(Ptyp
, Loc
),
1243 Attribute_Name
=> Name_Last
)));
1247 Make_Function_Call
(Loc
,
1248 Name
=> New_Reference_To
(RTE
(XX
), Loc
),
1249 Parameter_Associations
=> Arglist
)));
1251 Analyze_And_Resolve
(N
, Typ
);
1252 end Expand_Width_Attribute
;
1254 -----------------------
1255 -- Has_Decimal_Small --
1256 -----------------------
1258 function Has_Decimal_Small
(E
: Entity_Id
) return Boolean is
1260 return Is_Decimal_Fixed_Point_Type
(E
)
1262 (Is_Ordinary_Fixed_Point_Type
(E
)
1263 and then Ureal_10
**Aft_Value
(E
) * Small_Value
(E
) = Ureal_1
);
1264 end Has_Decimal_Small
;