2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / ada / exp_imgv.adb
blob7f3a8f0858d592a1c43f4c8e48e9160f1a79e41b
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ I M G V --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2001-2003 Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
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, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
21 -- --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 -- --
25 ------------------------------------------------------------------------------
27 with Atree; use Atree;
28 with Casing; use Casing;
29 with Checks; use Checks;
30 with Einfo; use Einfo;
31 with Exp_Util; use Exp_Util;
32 with Namet; use Namet;
33 with Nmake; use Nmake;
34 with Nlists; use Nlists;
35 with Opt; use Opt;
36 with Rtsfind; use Rtsfind;
37 with Sem_Res; use Sem_Res;
38 with Sinfo; use Sinfo;
39 with Snames; use Snames;
40 with Stand; use Stand;
41 with Stringt; use Stringt;
42 with Tbuild; use Tbuild;
43 with Ttypes; use Ttypes;
44 with Uintp; use Uintp;
46 package body Exp_Imgv is
48 ------------------------------------
49 -- Build_Enumeration_Image_Tables --
50 ------------------------------------
52 procedure Build_Enumeration_Image_Tables (E : Entity_Id; N : Node_Id) is
53 Loc : constant Source_Ptr := Sloc (E);
54 Str : String_Id;
55 Ind : List_Id;
56 Lit : Entity_Id;
57 Nlit : Nat;
58 Len : Nat;
59 Estr : Entity_Id;
60 Eind : Entity_Id;
61 Ityp : Node_Id;
63 begin
64 -- Nothing to do for other than a root enumeration type
66 if E /= Root_Type (E) then
67 return;
69 -- Nothing to do if pragma Discard_Names applies
71 elsif Discard_Names (E) then
72 return;
73 end if;
75 -- Otherwise tables need constructing
77 Start_String;
78 Ind := New_List;
79 Lit := First_Literal (E);
80 Len := 1;
81 Nlit := 0;
83 loop
84 Append_To (Ind,
85 Make_Integer_Literal (Loc, UI_From_Int (Len)));
87 exit when No (Lit);
88 Nlit := Nlit + 1;
90 Get_Unqualified_Decoded_Name_String (Chars (Lit));
92 if Name_Buffer (1) /= ''' then
93 Set_Casing (All_Upper_Case);
94 end if;
96 Store_String_Chars (Name_Buffer (1 .. Name_Len));
97 Len := Len + Int (Name_Len);
98 Next_Literal (Lit);
99 end loop;
101 if Len < Int (2 ** (8 - 1)) then
102 Ityp := Standard_Integer_8;
103 elsif Len < Int (2 ** (16 - 1)) then
104 Ityp := Standard_Integer_16;
105 else
106 Ityp := Standard_Integer_32;
107 end if;
109 Str := End_String;
111 Estr :=
112 Make_Defining_Identifier (Loc,
113 Chars => New_External_Name (Chars (E), 'S'));
115 Eind :=
116 Make_Defining_Identifier (Loc,
117 Chars => New_External_Name (Chars (E), 'N'));
119 Set_Lit_Strings (E, Estr);
120 Set_Lit_Indexes (E, Eind);
122 Insert_Actions (N,
123 New_List (
124 Make_Object_Declaration (Loc,
125 Defining_Identifier => Estr,
126 Constant_Present => True,
127 Object_Definition =>
128 New_Occurrence_Of (Standard_String, Loc),
129 Expression =>
130 Make_String_Literal (Loc,
131 Strval => Str)),
133 Make_Object_Declaration (Loc,
134 Defining_Identifier => Eind,
135 Constant_Present => True,
137 Object_Definition =>
138 Make_Constrained_Array_Definition (Loc,
139 Discrete_Subtype_Definitions => New_List (
140 Make_Range (Loc,
141 Low_Bound => Make_Integer_Literal (Loc, 0),
142 High_Bound => Make_Integer_Literal (Loc, Nlit))),
143 Subtype_Indication => New_Occurrence_Of (Ityp, Loc)),
145 Expression =>
146 Make_Aggregate (Loc,
147 Expressions => Ind))),
148 Suppress => All_Checks);
150 end Build_Enumeration_Image_Tables;
152 ----------------------------
153 -- Expand_Image_Attribute --
154 ----------------------------
156 -- For all non-enumeration types, and for enumeration types declared
157 -- in packages Standard or System, typ'Image (Val) expands into:
159 -- Image_xx (tp (Expr) [, pm])
161 -- The name xx and type conversion tp (Expr) (called tv below) depend on
162 -- the root type of Expr. The argument pm is an extra type dependent
163 -- parameter only used in some cases as follows:
165 -- For types whose root type is Character
166 -- xx = Character
167 -- tv = Character (Expr)
169 -- For types whose root type is Boolean
170 -- xx = Boolean
171 -- tv = Boolean (Expr)
173 -- For signed integer types with size <= Integer'Size
174 -- xx = Integer
175 -- tv = Integer (Expr)
177 -- For other signed integer types
178 -- xx = Long_Long_Integer
179 -- tv = Long_Long_Integer (Expr)
181 -- For modular types with modulus <= System.Unsigned_Types.Unsigned
182 -- xx = Unsigned
183 -- tv = System.Unsigned_Types.Unsigned (Expr)
185 -- For other modular integer types
186 -- xx = Long_Long_Unsigned
187 -- tv = System.Unsigned_Types.Long_Long_Unsigned (Expr)
189 -- For types whose root type is Wide_Character
190 -- xx = Wide_Character
191 -- tv = Wide_Character (Expr)
192 -- pm = Wide_Character_Encoding_Method
194 -- For floating-point types
195 -- xx = Floating_Point
196 -- tv = Long_Long_Float (Expr)
197 -- pm = typ'Digits
199 -- For ordinary fixed-point types
200 -- xx = Ordinary_Fixed_Point
201 -- tv = Long_Long_Float (Expr)
202 -- pm = typ'Aft
204 -- For decimal fixed-point types with size = Integer'Size
205 -- xx = Decimal
206 -- tv = Integer (Expr)
207 -- pm = typ'Scale
209 -- For decimal fixed-point types with size > Integer'Size
210 -- xx = Long_Long_Decimal
211 -- tv = Long_Long_Integer (Expr)
212 -- pm = typ'Scale
214 -- Note: for the decimal fixed-point type cases, the conversion is
215 -- done literally without scaling (i.e. the actual expression that
216 -- is generated is Image_xx (tp?(Expr) [, pm])
218 -- For enumeration types other than those declared packages Standard
219 -- or System, typ'Image (X) expands into:
221 -- Image_Enumeration_NN (typ'Pos (X), typS, typI'Address)
223 -- where typS and typI are the entities constructed as described in
224 -- the spec for the procedure Build_Enumeration_Image_Tables and NN
225 -- is 32/16/8 depending on the element type of Lit_Indexes.
227 procedure Expand_Image_Attribute (N : Node_Id) is
228 Loc : constant Source_Ptr := Sloc (N);
229 Exprs : constant List_Id := Expressions (N);
230 Pref : constant Node_Id := Prefix (N);
231 Ptyp : constant Entity_Id := Entity (Pref);
232 Rtyp : constant Entity_Id := Root_Type (Ptyp);
233 Expr : constant Node_Id := Relocate_Node (First (Exprs));
234 Imid : RE_Id;
235 Tent : Entity_Id;
236 Arglist : List_Id;
237 Func : RE_Id;
238 Ttyp : Entity_Id;
239 Func_Ent : Entity_Id;
241 begin
242 if Rtyp = Standard_Boolean then
243 Imid := RE_Image_Boolean;
244 Tent := Rtyp;
246 elsif Rtyp = Standard_Character then
247 Imid := RE_Image_Character;
248 Tent := Rtyp;
250 elsif Rtyp = Standard_Wide_Character then
251 Imid := RE_Image_Wide_Character;
252 Tent := Rtyp;
254 elsif Is_Signed_Integer_Type (Rtyp) then
255 if Esize (Rtyp) <= Esize (Standard_Integer) then
256 Imid := RE_Image_Integer;
257 Tent := Standard_Integer;
258 else
259 Imid := RE_Image_Long_Long_Integer;
260 Tent := Standard_Long_Long_Integer;
261 end if;
263 elsif Is_Modular_Integer_Type (Rtyp) then
264 if Modulus (Rtyp) <= Modulus (RTE (RE_Unsigned)) then
265 Imid := RE_Image_Unsigned;
266 Tent := RTE (RE_Unsigned);
267 else
268 Imid := RE_Image_Long_Long_Unsigned;
269 Tent := RTE (RE_Long_Long_Unsigned);
270 end if;
272 elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
273 if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
274 Imid := RE_Image_Decimal;
275 Tent := Standard_Integer;
276 else
277 Imid := RE_Image_Long_Long_Decimal;
278 Tent := Standard_Long_Long_Integer;
279 end if;
281 elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
282 Imid := RE_Image_Ordinary_Fixed_Point;
283 Tent := Standard_Long_Long_Float;
285 elsif Is_Floating_Point_Type (Rtyp) then
286 Imid := RE_Image_Floating_Point;
287 Tent := Standard_Long_Long_Float;
289 -- Only other possibility is user defined enumeration type
291 else
292 if Discard_Names (First_Subtype (Ptyp))
293 or else No (Lit_Strings (Root_Type (Ptyp)))
294 then
295 -- When pragma Discard_Names applies to the first subtype,
296 -- then build (Pref'Pos)'Img.
298 Rewrite (N,
299 Make_Attribute_Reference (Loc,
300 Prefix =>
301 Make_Attribute_Reference (Loc,
302 Prefix => Pref,
303 Attribute_Name => Name_Pos,
304 Expressions => New_List (Expr)),
305 Attribute_Name =>
306 Name_Img));
307 Analyze_And_Resolve (N, Standard_String);
309 else
310 -- Here we get the Image of an enumeration type
312 Ttyp := Component_Type (Etype (Lit_Indexes (Rtyp)));
314 if Ttyp = Standard_Integer_8 then
315 Func := RE_Image_Enumeration_8;
316 elsif Ttyp = Standard_Integer_16 then
317 Func := RE_Image_Enumeration_16;
318 else
319 Func := RE_Image_Enumeration_32;
320 end if;
322 -- Apply a validity check, since it is a bit drastic to
323 -- get a completely junk image value for an invalid value.
325 if not Expr_Known_Valid (Expr) then
326 Insert_Valid_Check (Expr);
327 end if;
329 Rewrite (N,
330 Make_Function_Call (Loc,
331 Name => New_Occurrence_Of (RTE (Func), Loc),
332 Parameter_Associations => New_List (
333 Make_Attribute_Reference (Loc,
334 Attribute_Name => Name_Pos,
335 Prefix => New_Occurrence_Of (Ptyp, Loc),
336 Expressions => New_List (Expr)),
337 New_Occurrence_Of (Lit_Strings (Rtyp), Loc),
338 Make_Attribute_Reference (Loc,
339 Prefix => New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
340 Attribute_Name => Name_Address))));
342 Analyze_And_Resolve (N, Standard_String);
343 end if;
345 return;
346 end if;
348 -- If we fall through, we have one of the cases that is handled by
349 -- calling one of the System.Img_xx routines and Imid is set to the
350 -- RE_Id for the function to be called.
352 Func_Ent := RTE (Imid);
354 -- If the function entity is empty, that means we have a case in
355 -- no run time mode where the operation is not allowed, and an
356 -- appropriate diagnostic has already been issued.
358 if No (Func_Ent) then
359 return;
360 end if;
362 -- Otherwise prepare arguments for run-time call
364 Arglist := New_List (Convert_To (Tent, Relocate_Node (Expr)));
366 -- For floating-point types, append Digits argument
368 if Is_Floating_Point_Type (Rtyp) then
369 Append_To (Arglist,
370 Make_Attribute_Reference (Loc,
371 Prefix => New_Reference_To (Ptyp, Loc),
372 Attribute_Name => Name_Digits));
374 -- For ordinary fixed-point types, append Aft parameter
376 elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
377 Append_To (Arglist,
378 Make_Attribute_Reference (Loc,
379 Prefix => New_Reference_To (Ptyp, Loc),
380 Attribute_Name => Name_Aft));
382 -- For wide character, append encoding method
384 elsif Rtyp = Standard_Wide_Character then
385 Append_To (Arglist,
386 Make_Integer_Literal (Loc,
387 Intval => Int (Wide_Character_Encoding_Method)));
389 -- For decimal, append Scale and also set to do literal conversion
391 elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
392 Append_To (Arglist,
393 Make_Attribute_Reference (Loc,
394 Prefix => New_Reference_To (Ptyp, Loc),
395 Attribute_Name => Name_Scale));
397 Set_Conversion_OK (First (Arglist));
398 Set_Etype (First (Arglist), Tent);
399 end if;
401 Rewrite (N,
402 Make_Function_Call (Loc,
403 Name => New_Reference_To (Func_Ent, Loc),
404 Parameter_Associations => Arglist));
406 Analyze_And_Resolve (N, Standard_String);
407 end Expand_Image_Attribute;
409 ----------------------------
410 -- Expand_Value_Attribute --
411 ----------------------------
413 -- For scalar types derived from Boolean, Character and integer types
414 -- in package Standard, typ'Value (X) expands into:
416 -- btyp (Value_xx (X))
418 -- where btyp is he base type of the prefix, and
420 -- For types whose root type is Character
421 -- xx = Character
423 -- For types whose root type is Boolean
424 -- xx = Boolean
426 -- For signed integer types with size <= Integer'Size
427 -- xx = Integer
429 -- For other signed integer types
430 -- xx = Long_Long_Integer
432 -- For modular types with modulus <= System.Unsigned_Types.Unsigned
433 -- xx = Unsigned
435 -- For other modular integer types
436 -- xx = Long_Long_Unsigned
438 -- For floating-point types and ordinary fixed-point types
439 -- xx = Real
441 -- For types derived from Wide_Character, typ'Value (X) expands into
443 -- Value_Wide_Character (X, Wide_Character_Encoding_Method)
445 -- For decimal types with size <= Integer'Size, typ'Value (X)
446 -- expands into
448 -- btyp?(Value_Decimal (X, typ'Scale));
450 -- For all other decimal types, typ'Value (X) expands into
452 -- btyp?(Value_Long_Long_Decimal (X, typ'Scale))
454 -- For enumeration types other than those derived from types Boolean,
455 -- Character, and Wide_Character in Standard, typ'Value (X) expands to:
457 -- Enum'Val (Value_Enumeration_NN (typS, typI'Address, Num, X))
459 -- where typS and typI and the Lit_Strings and Lit_Indexes entities
460 -- from T's root type entitym and Num is Enum'Pos (Enum'Last). The
461 -- Value_Enumeration_NN function will search the tables looking for
462 -- X and return the position number in the table if found which is
463 -- used to provide the result of 'Value (using Enum'Val). If the
464 -- value is not found Constraint_Error is raised. The suffix _NN
465 -- depends on the element type of typI.
467 procedure Expand_Value_Attribute (N : Node_Id) is
468 Loc : constant Source_Ptr := Sloc (N);
469 Typ : constant Entity_Id := Etype (N);
470 Btyp : constant Entity_Id := Base_Type (Typ);
471 Rtyp : constant Entity_Id := Root_Type (Typ);
472 Exprs : constant List_Id := Expressions (N);
473 Vid : RE_Id;
474 Args : List_Id;
475 Func : RE_Id;
476 Ttyp : Entity_Id;
478 begin
479 Args := Exprs;
481 if Rtyp = Standard_Character then
482 Vid := RE_Value_Character;
484 elsif Rtyp = Standard_Boolean then
485 Vid := RE_Value_Boolean;
487 elsif Rtyp = Standard_Wide_Character then
488 Vid := RE_Value_Wide_Character;
489 Append_To (Args,
490 Make_Integer_Literal (Loc,
491 Intval => Int (Wide_Character_Encoding_Method)));
493 elsif Rtyp = Base_Type (Standard_Short_Short_Integer)
494 or else Rtyp = Base_Type (Standard_Short_Integer)
495 or else Rtyp = Base_Type (Standard_Integer)
496 then
497 Vid := RE_Value_Integer;
499 elsif Is_Signed_Integer_Type (Rtyp) then
500 Vid := RE_Value_Long_Long_Integer;
502 elsif Is_Modular_Integer_Type (Rtyp) then
503 if Modulus (Rtyp) <= Modulus (RTE (RE_Unsigned)) then
504 Vid := RE_Value_Unsigned;
505 else
506 Vid := RE_Value_Long_Long_Unsigned;
507 end if;
509 elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
510 if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
511 Vid := RE_Value_Decimal;
512 else
513 Vid := RE_Value_Long_Long_Decimal;
514 end if;
516 Append_To (Args,
517 Make_Attribute_Reference (Loc,
518 Prefix => New_Reference_To (Typ, Loc),
519 Attribute_Name => Name_Scale));
521 Rewrite (N,
522 OK_Convert_To (Btyp,
523 Make_Function_Call (Loc,
524 Name => New_Reference_To (RTE (Vid), Loc),
525 Parameter_Associations => Args)));
527 Set_Etype (N, Btyp);
528 Analyze_And_Resolve (N, Btyp);
529 return;
531 elsif Is_Real_Type (Rtyp) then
532 Vid := RE_Value_Real;
534 -- Only other possibility is user defined enumeration type
536 else
537 pragma Assert (Is_Enumeration_Type (Rtyp));
539 -- Case of pragma Discard_Names, transform the Value
540 -- attribute to Btyp'Val (Long_Long_Integer'Value (Args))
542 if Discard_Names (First_Subtype (Typ))
543 or else No (Lit_Strings (Rtyp))
544 then
545 Rewrite (N,
546 Make_Attribute_Reference (Loc,
547 Prefix => New_Reference_To (Btyp, Loc),
548 Attribute_Name => Name_Val,
549 Expressions => New_List (
550 Make_Attribute_Reference (Loc,
551 Prefix =>
552 New_Occurrence_Of (Standard_Long_Long_Integer, Loc),
553 Attribute_Name => Name_Value,
554 Expressions => Args))));
556 Analyze_And_Resolve (N, Btyp);
558 -- Here for normal case where we have enumeration tables, this
559 -- is where we build
561 -- T'Val (Value_Enumeration_NN (typS, typI'Address, Num, X))
563 else
564 Ttyp := Component_Type (Etype (Lit_Indexes (Rtyp)));
566 if Ttyp = Standard_Integer_8 then
567 Func := RE_Value_Enumeration_8;
568 elsif Ttyp = Standard_Integer_16 then
569 Func := RE_Value_Enumeration_16;
570 else
571 Func := RE_Value_Enumeration_32;
572 end if;
574 Prepend_To (Args,
575 Make_Attribute_Reference (Loc,
576 Prefix => New_Occurrence_Of (Rtyp, Loc),
577 Attribute_Name => Name_Pos,
578 Expressions => New_List (
579 Make_Attribute_Reference (Loc,
580 Prefix => New_Occurrence_Of (Rtyp, Loc),
581 Attribute_Name => Name_Last))));
583 Prepend_To (Args,
584 Make_Attribute_Reference (Loc,
585 Prefix => New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
586 Attribute_Name => Name_Address));
588 Prepend_To (Args,
589 New_Occurrence_Of (Lit_Strings (Rtyp), Loc));
591 Rewrite (N,
592 Make_Attribute_Reference (Loc,
593 Prefix => New_Reference_To (Typ, Loc),
594 Attribute_Name => Name_Val,
595 Expressions => New_List (
596 Make_Function_Call (Loc,
597 Name =>
598 New_Reference_To (RTE (Func), Loc),
599 Parameter_Associations => Args))));
601 Analyze_And_Resolve (N, Btyp);
602 end if;
604 return;
605 end if;
607 -- Fall through for all cases except user defined enumeration type
608 -- and decimal types, with Vid set to the Id of the entity for the
609 -- Value routine and Args set to the list of parameters for the call.
611 Rewrite (N,
612 Convert_To (Btyp,
613 Make_Function_Call (Loc,
614 Name => New_Reference_To (RTE (Vid), Loc),
615 Parameter_Associations => Args)));
617 Analyze_And_Resolve (N, Btyp);
618 end Expand_Value_Attribute;
620 ----------------------------
621 -- Expand_Width_Attribute --
622 ----------------------------
624 -- The processing here also handles the case of Wide_Width. With the
625 -- exceptions noted, the processing is identical
627 -- For scalar types derived from Boolean, character and integer types
628 -- in package Standard. Note that the Width attribute is computed at
629 -- compile time for all cases except those involving non-static sub-
630 -- types. For such subtypes, typ'Width and typ'Wide_Width expands into:
632 -- Result_Type (xx (yy (Ptyp'First), yy (Ptyp'Last)))
634 -- where
636 -- For types whose root type is Character
637 -- xx = Width_Character (Wide_Width_Character for Wide_Width case)
638 -- yy = Character
640 -- For types whose root type is Boolean
641 -- xx = Width_Boolean
642 -- yy = Boolean
644 -- For signed integer types
645 -- xx = Width_Long_Long_Integer
646 -- yy = Long_Long_Integer
648 -- For modular integer types
649 -- xx = Width_Long_Long_Unsigned
650 -- yy = Long_Long_Unsigned
652 -- For types derived from Wide_Character, typ'Width expands into
654 -- Result_Type (Width_Wide_Character (
655 -- Wide_Character (typ'First),
656 -- Wide_Character (typ'Last),
657 -- Wide_Character_Encoding_Method);
659 -- and typ'Wide_Width expands into:
661 -- Result_Type (Wide_Width_Wide_Character (
662 -- Wide_Character (typ'First),
663 -- Wide_Character (typ'Last));
665 -- For real types, typ'Width and typ'Wide_Width expand into
667 -- if Ptyp'First > Ptyp'Last then 0 else btyp'Width end if
669 -- where btyp is the base type. This looks recursive but it isn't
670 -- because the base type is always static, and hence the expression
671 -- in the else is reduced to an integer literal.
673 -- For user defined enumeration types, typ'Width expands into
675 -- Result_Type (Width_Enumeration_NN
676 -- (typS,
677 -- typI'Address,
678 -- typ'Pos (typ'First),
679 -- typ'Pos (Typ'Last)));
681 -- and typ'Wide_Width expands into:
683 -- Result_Type (Wide_Width_Enumeration_NN
684 -- (typS,
685 -- typI,
686 -- typ'Pos (typ'First),
687 -- typ'Pos (Typ'Last))
688 -- Wide_Character_Encoding_Method);
690 -- where typS and typI are the enumeration image strings and
691 -- indexes table, as described in Build_Enumeration_Image_Tables.
692 -- NN is 8/16/32 for depending on the element type for typI.
694 procedure Expand_Width_Attribute (N : Node_Id; Wide : Boolean) is
695 Loc : constant Source_Ptr := Sloc (N);
696 Typ : constant Entity_Id := Etype (N);
697 Pref : constant Node_Id := Prefix (N);
698 Ptyp : constant Entity_Id := Etype (Pref);
699 Rtyp : constant Entity_Id := Root_Type (Ptyp);
700 XX : RE_Id;
701 YY : Entity_Id;
702 Arglist : List_Id;
703 Ttyp : Entity_Id;
705 begin
706 -- Types derived from Standard.Boolean
708 if Rtyp = Standard_Boolean then
709 XX := RE_Width_Boolean;
710 YY := Rtyp;
712 -- Types derived from Standard.Character
714 elsif Rtyp = Standard_Character then
715 if not Wide then
716 XX := RE_Width_Character;
717 else
718 XX := RE_Wide_Width_Character;
719 end if;
721 YY := Rtyp;
723 -- Types derived from Standard.Wide_Character
725 elsif Rtyp = Standard_Wide_Character then
726 if not Wide then
727 XX := RE_Width_Wide_Character;
728 else
729 XX := RE_Wide_Width_Wide_Character;
730 end if;
732 YY := Rtyp;
734 -- Signed integer types
736 elsif Is_Signed_Integer_Type (Rtyp) then
737 XX := RE_Width_Long_Long_Integer;
738 YY := Standard_Long_Long_Integer;
740 -- Modular integer types
742 elsif Is_Modular_Integer_Type (Rtyp) then
743 XX := RE_Width_Long_Long_Unsigned;
744 YY := RTE (RE_Long_Long_Unsigned);
746 -- Real types
748 elsif Is_Real_Type (Rtyp) then
750 Rewrite (N,
751 Make_Conditional_Expression (Loc,
752 Expressions => New_List (
754 Make_Op_Gt (Loc,
755 Left_Opnd =>
756 Make_Attribute_Reference (Loc,
757 Prefix => New_Reference_To (Ptyp, Loc),
758 Attribute_Name => Name_First),
760 Right_Opnd =>
761 Make_Attribute_Reference (Loc,
762 Prefix => New_Reference_To (Ptyp, Loc),
763 Attribute_Name => Name_Last)),
765 Make_Integer_Literal (Loc, 0),
767 Make_Attribute_Reference (Loc,
768 Prefix => New_Reference_To (Base_Type (Ptyp), Loc),
769 Attribute_Name => Name_Width))));
771 Analyze_And_Resolve (N, Typ);
772 return;
774 -- User defined enumeration types
776 else
777 pragma Assert (Is_Enumeration_Type (Rtyp));
779 Ttyp := Component_Type (Etype (Lit_Indexes (Rtyp)));
781 if not Wide then
782 if Ttyp = Standard_Integer_8 then
783 XX := RE_Width_Enumeration_8;
784 elsif Ttyp = Standard_Integer_16 then
785 XX := RE_Width_Enumeration_16;
786 else
787 XX := RE_Width_Enumeration_32;
788 end if;
790 else
791 if Ttyp = Standard_Integer_8 then
792 XX := RE_Wide_Width_Enumeration_8;
793 elsif Ttyp = Standard_Integer_16 then
794 XX := RE_Wide_Width_Enumeration_16;
795 else
796 XX := RE_Wide_Width_Enumeration_32;
797 end if;
798 end if;
800 Arglist :=
801 New_List (
802 New_Occurrence_Of (Lit_Strings (Rtyp), Loc),
804 Make_Attribute_Reference (Loc,
805 Prefix => New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
806 Attribute_Name => Name_Address),
808 Make_Attribute_Reference (Loc,
809 Prefix => New_Reference_To (Ptyp, Loc),
810 Attribute_Name => Name_Pos,
812 Expressions => New_List (
813 Make_Attribute_Reference (Loc,
814 Prefix => New_Reference_To (Ptyp, Loc),
815 Attribute_Name => Name_First))),
817 Make_Attribute_Reference (Loc,
818 Prefix => New_Reference_To (Ptyp, Loc),
819 Attribute_Name => Name_Pos,
821 Expressions => New_List (
822 Make_Attribute_Reference (Loc,
823 Prefix => New_Reference_To (Ptyp, Loc),
824 Attribute_Name => Name_Last))));
826 -- For enumeration'Wide_Width, add encoding method parameter
828 if Wide then
829 Append_To (Arglist,
830 Make_Integer_Literal (Loc,
831 Intval => Int (Wide_Character_Encoding_Method)));
832 end if;
834 Rewrite (N,
835 Convert_To (Typ,
836 Make_Function_Call (Loc,
837 Name => New_Reference_To (RTE (XX), Loc),
838 Parameter_Associations => Arglist)));
840 Analyze_And_Resolve (N, Typ);
841 return;
842 end if;
844 -- If we fall through XX and YY are set
846 Arglist := New_List (
847 Convert_To (YY,
848 Make_Attribute_Reference (Loc,
849 Prefix => New_Reference_To (Ptyp, Loc),
850 Attribute_Name => Name_First)),
852 Convert_To (YY,
853 Make_Attribute_Reference (Loc,
854 Prefix => New_Reference_To (Ptyp, Loc),
855 Attribute_Name => Name_Last)));
857 -- For Wide_Character'Width, add encoding method parameter
859 if Rtyp = Standard_Wide_Character and then Wide then
860 Append_To (Arglist,
861 Make_Integer_Literal (Loc,
862 Intval => Int (Wide_Character_Encoding_Method)));
863 end if;
865 Rewrite (N,
866 Convert_To (Typ,
867 Make_Function_Call (Loc,
868 Name => New_Reference_To (RTE (XX), Loc),
869 Parameter_Associations => Arglist)));
871 Analyze_And_Resolve (N, Typ);
872 end Expand_Width_Attribute;
874 end Exp_Imgv;