* pa64-hpux.h (LIB_SPEC): Fix library specification used with GNU ld.
[official-gcc.git] / gcc / ada / exp_imgv.adb
blob5989cbc3b5c24c56d508dba0013e8c158404d4a3
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-2004 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 Component_Definition =>
144 Make_Component_Definition (Loc,
145 Aliased_Present => False,
146 Subtype_Indication => New_Occurrence_Of (Ityp, Loc))),
148 Expression =>
149 Make_Aggregate (Loc,
150 Expressions => Ind))),
151 Suppress => All_Checks);
153 end Build_Enumeration_Image_Tables;
155 ----------------------------
156 -- Expand_Image_Attribute --
157 ----------------------------
159 -- For all non-enumeration types, and for enumeration types declared
160 -- in packages Standard or System, typ'Image (Val) expands into:
162 -- Image_xx (tp (Expr) [, pm])
164 -- The name xx and type conversion tp (Expr) (called tv below) depend on
165 -- the root type of Expr. The argument pm is an extra type dependent
166 -- parameter only used in some cases as follows:
168 -- For types whose root type is Character
169 -- xx = Character
170 -- tv = Character (Expr)
172 -- For types whose root type is Boolean
173 -- xx = Boolean
174 -- tv = Boolean (Expr)
176 -- For signed integer types with size <= Integer'Size
177 -- xx = Integer
178 -- tv = Integer (Expr)
180 -- For other signed integer types
181 -- xx = Long_Long_Integer
182 -- tv = Long_Long_Integer (Expr)
184 -- For modular types with modulus <= System.Unsigned_Types.Unsigned
185 -- xx = Unsigned
186 -- tv = System.Unsigned_Types.Unsigned (Expr)
188 -- For other modular integer types
189 -- xx = Long_Long_Unsigned
190 -- tv = System.Unsigned_Types.Long_Long_Unsigned (Expr)
192 -- For types whose root type is Wide_Character
193 -- xx = Wide_Character
194 -- tv = Wide_Character (Expr)
195 -- pm = Wide_Character_Encoding_Method
197 -- For floating-point types
198 -- xx = Floating_Point
199 -- tv = Long_Long_Float (Expr)
200 -- pm = typ'Digits
202 -- For ordinary fixed-point types
203 -- xx = Ordinary_Fixed_Point
204 -- tv = Long_Long_Float (Expr)
205 -- pm = typ'Aft
207 -- For decimal fixed-point types with size = Integer'Size
208 -- xx = Decimal
209 -- tv = Integer (Expr)
210 -- pm = typ'Scale
212 -- For decimal fixed-point types with size > Integer'Size
213 -- xx = Long_Long_Decimal
214 -- tv = Long_Long_Integer (Expr)
215 -- pm = typ'Scale
217 -- Note: for the decimal fixed-point type cases, the conversion is
218 -- done literally without scaling (i.e. the actual expression that
219 -- is generated is Image_xx (tp?(Expr) [, pm])
221 -- For enumeration types other than those declared packages Standard
222 -- or System, typ'Image (X) expands into:
224 -- Image_Enumeration_NN (typ'Pos (X), typS, typI'Address)
226 -- where typS and typI are the entities constructed as described in
227 -- the spec for the procedure Build_Enumeration_Image_Tables and NN
228 -- is 32/16/8 depending on the element type of Lit_Indexes.
230 procedure Expand_Image_Attribute (N : Node_Id) is
231 Loc : constant Source_Ptr := Sloc (N);
232 Exprs : constant List_Id := Expressions (N);
233 Pref : constant Node_Id := Prefix (N);
234 Ptyp : constant Entity_Id := Entity (Pref);
235 Rtyp : constant Entity_Id := Root_Type (Ptyp);
236 Expr : constant Node_Id := Relocate_Node (First (Exprs));
237 Imid : RE_Id;
238 Tent : Entity_Id;
239 Arglist : List_Id;
240 Func : RE_Id;
241 Ttyp : Entity_Id;
242 Func_Ent : Entity_Id;
244 begin
245 if Rtyp = Standard_Boolean then
246 Imid := RE_Image_Boolean;
247 Tent := Rtyp;
249 elsif Rtyp = Standard_Character then
250 Imid := RE_Image_Character;
251 Tent := Rtyp;
253 elsif Rtyp = Standard_Wide_Character then
254 Imid := RE_Image_Wide_Character;
255 Tent := Rtyp;
257 elsif Is_Signed_Integer_Type (Rtyp) then
258 if Esize (Rtyp) <= Esize (Standard_Integer) then
259 Imid := RE_Image_Integer;
260 Tent := Standard_Integer;
261 else
262 Imid := RE_Image_Long_Long_Integer;
263 Tent := Standard_Long_Long_Integer;
264 end if;
266 elsif Is_Modular_Integer_Type (Rtyp) then
267 if Modulus (Rtyp) <= Modulus (RTE (RE_Unsigned)) then
268 Imid := RE_Image_Unsigned;
269 Tent := RTE (RE_Unsigned);
270 else
271 Imid := RE_Image_Long_Long_Unsigned;
272 Tent := RTE (RE_Long_Long_Unsigned);
273 end if;
275 elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
276 if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
277 Imid := RE_Image_Decimal;
278 Tent := Standard_Integer;
279 else
280 Imid := RE_Image_Long_Long_Decimal;
281 Tent := Standard_Long_Long_Integer;
282 end if;
284 elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
285 Imid := RE_Image_Ordinary_Fixed_Point;
286 Tent := Standard_Long_Long_Float;
288 elsif Is_Floating_Point_Type (Rtyp) then
289 Imid := RE_Image_Floating_Point;
290 Tent := Standard_Long_Long_Float;
292 -- Only other possibility is user defined enumeration type
294 else
295 if Discard_Names (First_Subtype (Ptyp))
296 or else No (Lit_Strings (Root_Type (Ptyp)))
297 then
298 -- When pragma Discard_Names applies to the first subtype,
299 -- then build (Pref'Pos)'Img.
301 Rewrite (N,
302 Make_Attribute_Reference (Loc,
303 Prefix =>
304 Make_Attribute_Reference (Loc,
305 Prefix => Pref,
306 Attribute_Name => Name_Pos,
307 Expressions => New_List (Expr)),
308 Attribute_Name =>
309 Name_Img));
310 Analyze_And_Resolve (N, Standard_String);
312 else
313 -- Here we get the Image of an enumeration type
315 Ttyp := Component_Type (Etype (Lit_Indexes (Rtyp)));
317 if Ttyp = Standard_Integer_8 then
318 Func := RE_Image_Enumeration_8;
319 elsif Ttyp = Standard_Integer_16 then
320 Func := RE_Image_Enumeration_16;
321 else
322 Func := RE_Image_Enumeration_32;
323 end if;
325 -- Apply a validity check, since it is a bit drastic to
326 -- get a completely junk image value for an invalid value.
328 if not Expr_Known_Valid (Expr) then
329 Insert_Valid_Check (Expr);
330 end if;
332 Rewrite (N,
333 Make_Function_Call (Loc,
334 Name => New_Occurrence_Of (RTE (Func), Loc),
335 Parameter_Associations => New_List (
336 Make_Attribute_Reference (Loc,
337 Attribute_Name => Name_Pos,
338 Prefix => New_Occurrence_Of (Ptyp, Loc),
339 Expressions => New_List (Expr)),
340 New_Occurrence_Of (Lit_Strings (Rtyp), Loc),
341 Make_Attribute_Reference (Loc,
342 Prefix => New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
343 Attribute_Name => Name_Address))));
345 Analyze_And_Resolve (N, Standard_String);
346 end if;
348 return;
349 end if;
351 -- If we fall through, we have one of the cases that is handled by
352 -- calling one of the System.Img_xx routines and Imid is set to the
353 -- RE_Id for the function to be called.
355 Func_Ent := RTE (Imid);
357 -- If the function entity is empty, that means we have a case in
358 -- no run time mode where the operation is not allowed, and an
359 -- appropriate diagnostic has already been issued.
361 if No (Func_Ent) then
362 return;
363 end if;
365 -- Otherwise prepare arguments for run-time call
367 Arglist := New_List (Convert_To (Tent, Relocate_Node (Expr)));
369 -- For floating-point types, append Digits argument
371 if Is_Floating_Point_Type (Rtyp) then
372 Append_To (Arglist,
373 Make_Attribute_Reference (Loc,
374 Prefix => New_Reference_To (Ptyp, Loc),
375 Attribute_Name => Name_Digits));
377 -- For ordinary fixed-point types, append Aft parameter
379 elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
380 Append_To (Arglist,
381 Make_Attribute_Reference (Loc,
382 Prefix => New_Reference_To (Ptyp, Loc),
383 Attribute_Name => Name_Aft));
385 -- For wide character, append encoding method
387 elsif Rtyp = Standard_Wide_Character then
388 Append_To (Arglist,
389 Make_Integer_Literal (Loc,
390 Intval => Int (Wide_Character_Encoding_Method)));
392 -- For decimal, append Scale and also set to do literal conversion
394 elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
395 Append_To (Arglist,
396 Make_Attribute_Reference (Loc,
397 Prefix => New_Reference_To (Ptyp, Loc),
398 Attribute_Name => Name_Scale));
400 Set_Conversion_OK (First (Arglist));
401 Set_Etype (First (Arglist), Tent);
402 end if;
404 Rewrite (N,
405 Make_Function_Call (Loc,
406 Name => New_Reference_To (Func_Ent, Loc),
407 Parameter_Associations => Arglist));
409 Analyze_And_Resolve (N, Standard_String);
410 end Expand_Image_Attribute;
412 ----------------------------
413 -- Expand_Value_Attribute --
414 ----------------------------
416 -- For scalar types derived from Boolean, Character and integer types
417 -- in package Standard, typ'Value (X) expands into:
419 -- btyp (Value_xx (X))
421 -- where btyp is he base type of the prefix, and
423 -- For types whose root type is Character
424 -- xx = Character
426 -- For types whose root type is Boolean
427 -- xx = Boolean
429 -- For signed integer types with size <= Integer'Size
430 -- xx = Integer
432 -- For other signed integer types
433 -- xx = Long_Long_Integer
435 -- For modular types with modulus <= System.Unsigned_Types.Unsigned
436 -- xx = Unsigned
438 -- For other modular integer types
439 -- xx = Long_Long_Unsigned
441 -- For floating-point types and ordinary fixed-point types
442 -- xx = Real
444 -- For types derived from Wide_Character, typ'Value (X) expands into
446 -- Value_Wide_Character (X, Wide_Character_Encoding_Method)
448 -- For decimal types with size <= Integer'Size, typ'Value (X)
449 -- expands into
451 -- btyp?(Value_Decimal (X, typ'Scale));
453 -- For all other decimal types, typ'Value (X) expands into
455 -- btyp?(Value_Long_Long_Decimal (X, typ'Scale))
457 -- For enumeration types other than those derived from types Boolean,
458 -- Character, and Wide_Character in Standard, typ'Value (X) expands to:
460 -- Enum'Val (Value_Enumeration_NN (typS, typI'Address, Num, X))
462 -- where typS and typI and the Lit_Strings and Lit_Indexes entities
463 -- from T's root type entitym and Num is Enum'Pos (Enum'Last). The
464 -- Value_Enumeration_NN function will search the tables looking for
465 -- X and return the position number in the table if found which is
466 -- used to provide the result of 'Value (using Enum'Val). If the
467 -- value is not found Constraint_Error is raised. The suffix _NN
468 -- depends on the element type of typI.
470 procedure Expand_Value_Attribute (N : Node_Id) is
471 Loc : constant Source_Ptr := Sloc (N);
472 Typ : constant Entity_Id := Etype (N);
473 Btyp : constant Entity_Id := Base_Type (Typ);
474 Rtyp : constant Entity_Id := Root_Type (Typ);
475 Exprs : constant List_Id := Expressions (N);
476 Vid : RE_Id;
477 Args : List_Id;
478 Func : RE_Id;
479 Ttyp : Entity_Id;
481 begin
482 Args := Exprs;
484 if Rtyp = Standard_Character then
485 Vid := RE_Value_Character;
487 elsif Rtyp = Standard_Boolean then
488 Vid := RE_Value_Boolean;
490 elsif Rtyp = Standard_Wide_Character then
491 Vid := RE_Value_Wide_Character;
492 Append_To (Args,
493 Make_Integer_Literal (Loc,
494 Intval => Int (Wide_Character_Encoding_Method)));
496 elsif Rtyp = Base_Type (Standard_Short_Short_Integer)
497 or else Rtyp = Base_Type (Standard_Short_Integer)
498 or else Rtyp = Base_Type (Standard_Integer)
499 then
500 Vid := RE_Value_Integer;
502 elsif Is_Signed_Integer_Type (Rtyp) then
503 Vid := RE_Value_Long_Long_Integer;
505 elsif Is_Modular_Integer_Type (Rtyp) then
506 if Modulus (Rtyp) <= Modulus (RTE (RE_Unsigned)) then
507 Vid := RE_Value_Unsigned;
508 else
509 Vid := RE_Value_Long_Long_Unsigned;
510 end if;
512 elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
513 if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
514 Vid := RE_Value_Decimal;
515 else
516 Vid := RE_Value_Long_Long_Decimal;
517 end if;
519 Append_To (Args,
520 Make_Attribute_Reference (Loc,
521 Prefix => New_Reference_To (Typ, Loc),
522 Attribute_Name => Name_Scale));
524 Rewrite (N,
525 OK_Convert_To (Btyp,
526 Make_Function_Call (Loc,
527 Name => New_Reference_To (RTE (Vid), Loc),
528 Parameter_Associations => Args)));
530 Set_Etype (N, Btyp);
531 Analyze_And_Resolve (N, Btyp);
532 return;
534 elsif Is_Real_Type (Rtyp) then
535 Vid := RE_Value_Real;
537 -- Only other possibility is user defined enumeration type
539 else
540 pragma Assert (Is_Enumeration_Type (Rtyp));
542 -- Case of pragma Discard_Names, transform the Value
543 -- attribute to Btyp'Val (Long_Long_Integer'Value (Args))
545 if Discard_Names (First_Subtype (Typ))
546 or else No (Lit_Strings (Rtyp))
547 then
548 Rewrite (N,
549 Make_Attribute_Reference (Loc,
550 Prefix => New_Reference_To (Btyp, Loc),
551 Attribute_Name => Name_Val,
552 Expressions => New_List (
553 Make_Attribute_Reference (Loc,
554 Prefix =>
555 New_Occurrence_Of (Standard_Long_Long_Integer, Loc),
556 Attribute_Name => Name_Value,
557 Expressions => Args))));
559 Analyze_And_Resolve (N, Btyp);
561 -- Here for normal case where we have enumeration tables, this
562 -- is where we build
564 -- T'Val (Value_Enumeration_NN (typS, typI'Address, Num, X))
566 else
567 Ttyp := Component_Type (Etype (Lit_Indexes (Rtyp)));
569 if Ttyp = Standard_Integer_8 then
570 Func := RE_Value_Enumeration_8;
571 elsif Ttyp = Standard_Integer_16 then
572 Func := RE_Value_Enumeration_16;
573 else
574 Func := RE_Value_Enumeration_32;
575 end if;
577 Prepend_To (Args,
578 Make_Attribute_Reference (Loc,
579 Prefix => New_Occurrence_Of (Rtyp, Loc),
580 Attribute_Name => Name_Pos,
581 Expressions => New_List (
582 Make_Attribute_Reference (Loc,
583 Prefix => New_Occurrence_Of (Rtyp, Loc),
584 Attribute_Name => Name_Last))));
586 Prepend_To (Args,
587 Make_Attribute_Reference (Loc,
588 Prefix => New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
589 Attribute_Name => Name_Address));
591 Prepend_To (Args,
592 New_Occurrence_Of (Lit_Strings (Rtyp), Loc));
594 Rewrite (N,
595 Make_Attribute_Reference (Loc,
596 Prefix => New_Reference_To (Typ, Loc),
597 Attribute_Name => Name_Val,
598 Expressions => New_List (
599 Make_Function_Call (Loc,
600 Name =>
601 New_Reference_To (RTE (Func), Loc),
602 Parameter_Associations => Args))));
604 Analyze_And_Resolve (N, Btyp);
605 end if;
607 return;
608 end if;
610 -- Fall through for all cases except user defined enumeration type
611 -- and decimal types, with Vid set to the Id of the entity for the
612 -- Value routine and Args set to the list of parameters for the call.
614 Rewrite (N,
615 Convert_To (Btyp,
616 Make_Function_Call (Loc,
617 Name => New_Reference_To (RTE (Vid), Loc),
618 Parameter_Associations => Args)));
620 Analyze_And_Resolve (N, Btyp);
621 end Expand_Value_Attribute;
623 ----------------------------
624 -- Expand_Width_Attribute --
625 ----------------------------
627 -- The processing here also handles the case of Wide_Width. With the
628 -- exceptions noted, the processing is identical
630 -- For scalar types derived from Boolean, character and integer types
631 -- in package Standard. Note that the Width attribute is computed at
632 -- compile time for all cases except those involving non-static sub-
633 -- types. For such subtypes, typ'Width and typ'Wide_Width expands into:
635 -- Result_Type (xx (yy (Ptyp'First), yy (Ptyp'Last)))
637 -- where
639 -- For types whose root type is Character
640 -- xx = Width_Character (Wide_Width_Character for Wide_Width case)
641 -- yy = Character
643 -- For types whose root type is Boolean
644 -- xx = Width_Boolean
645 -- yy = Boolean
647 -- For signed integer types
648 -- xx = Width_Long_Long_Integer
649 -- yy = Long_Long_Integer
651 -- For modular integer types
652 -- xx = Width_Long_Long_Unsigned
653 -- yy = Long_Long_Unsigned
655 -- For types derived from Wide_Character, typ'Width expands into
657 -- Result_Type (Width_Wide_Character (
658 -- Wide_Character (typ'First),
659 -- Wide_Character (typ'Last),
660 -- Wide_Character_Encoding_Method);
662 -- and typ'Wide_Width expands into:
664 -- Result_Type (Wide_Width_Wide_Character (
665 -- Wide_Character (typ'First),
666 -- Wide_Character (typ'Last));
668 -- For real types, typ'Width and typ'Wide_Width expand into
670 -- if Ptyp'First > Ptyp'Last then 0 else btyp'Width end if
672 -- where btyp is the base type. This looks recursive but it isn't
673 -- because the base type is always static, and hence the expression
674 -- in the else is reduced to an integer literal.
676 -- For user defined enumeration types, typ'Width expands into
678 -- Result_Type (Width_Enumeration_NN
679 -- (typS,
680 -- typI'Address,
681 -- typ'Pos (typ'First),
682 -- typ'Pos (Typ'Last)));
684 -- and typ'Wide_Width expands into:
686 -- Result_Type (Wide_Width_Enumeration_NN
687 -- (typS,
688 -- typI,
689 -- typ'Pos (typ'First),
690 -- typ'Pos (Typ'Last))
691 -- Wide_Character_Encoding_Method);
693 -- where typS and typI are the enumeration image strings and
694 -- indexes table, as described in Build_Enumeration_Image_Tables.
695 -- NN is 8/16/32 for depending on the element type for typI.
697 procedure Expand_Width_Attribute (N : Node_Id; Wide : Boolean) is
698 Loc : constant Source_Ptr := Sloc (N);
699 Typ : constant Entity_Id := Etype (N);
700 Pref : constant Node_Id := Prefix (N);
701 Ptyp : constant Entity_Id := Etype (Pref);
702 Rtyp : constant Entity_Id := Root_Type (Ptyp);
703 XX : RE_Id;
704 YY : Entity_Id;
705 Arglist : List_Id;
706 Ttyp : Entity_Id;
708 begin
709 -- Types derived from Standard.Boolean
711 if Rtyp = Standard_Boolean then
712 XX := RE_Width_Boolean;
713 YY := Rtyp;
715 -- Types derived from Standard.Character
717 elsif Rtyp = Standard_Character then
718 if not Wide then
719 XX := RE_Width_Character;
720 else
721 XX := RE_Wide_Width_Character;
722 end if;
724 YY := Rtyp;
726 -- Types derived from Standard.Wide_Character
728 elsif Rtyp = Standard_Wide_Character then
729 if not Wide then
730 XX := RE_Width_Wide_Character;
731 else
732 XX := RE_Wide_Width_Wide_Character;
733 end if;
735 YY := Rtyp;
737 -- Signed integer types
739 elsif Is_Signed_Integer_Type (Rtyp) then
740 XX := RE_Width_Long_Long_Integer;
741 YY := Standard_Long_Long_Integer;
743 -- Modular integer types
745 elsif Is_Modular_Integer_Type (Rtyp) then
746 XX := RE_Width_Long_Long_Unsigned;
747 YY := RTE (RE_Long_Long_Unsigned);
749 -- Real types
751 elsif Is_Real_Type (Rtyp) then
753 Rewrite (N,
754 Make_Conditional_Expression (Loc,
755 Expressions => New_List (
757 Make_Op_Gt (Loc,
758 Left_Opnd =>
759 Make_Attribute_Reference (Loc,
760 Prefix => New_Reference_To (Ptyp, Loc),
761 Attribute_Name => Name_First),
763 Right_Opnd =>
764 Make_Attribute_Reference (Loc,
765 Prefix => New_Reference_To (Ptyp, Loc),
766 Attribute_Name => Name_Last)),
768 Make_Integer_Literal (Loc, 0),
770 Make_Attribute_Reference (Loc,
771 Prefix => New_Reference_To (Base_Type (Ptyp), Loc),
772 Attribute_Name => Name_Width))));
774 Analyze_And_Resolve (N, Typ);
775 return;
777 -- User defined enumeration types
779 else
780 pragma Assert (Is_Enumeration_Type (Rtyp));
782 Ttyp := Component_Type (Etype (Lit_Indexes (Rtyp)));
784 if not Wide then
785 if Ttyp = Standard_Integer_8 then
786 XX := RE_Width_Enumeration_8;
787 elsif Ttyp = Standard_Integer_16 then
788 XX := RE_Width_Enumeration_16;
789 else
790 XX := RE_Width_Enumeration_32;
791 end if;
793 else
794 if Ttyp = Standard_Integer_8 then
795 XX := RE_Wide_Width_Enumeration_8;
796 elsif Ttyp = Standard_Integer_16 then
797 XX := RE_Wide_Width_Enumeration_16;
798 else
799 XX := RE_Wide_Width_Enumeration_32;
800 end if;
801 end if;
803 Arglist :=
804 New_List (
805 New_Occurrence_Of (Lit_Strings (Rtyp), Loc),
807 Make_Attribute_Reference (Loc,
808 Prefix => New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
809 Attribute_Name => Name_Address),
811 Make_Attribute_Reference (Loc,
812 Prefix => New_Reference_To (Ptyp, Loc),
813 Attribute_Name => Name_Pos,
815 Expressions => New_List (
816 Make_Attribute_Reference (Loc,
817 Prefix => New_Reference_To (Ptyp, Loc),
818 Attribute_Name => Name_First))),
820 Make_Attribute_Reference (Loc,
821 Prefix => New_Reference_To (Ptyp, Loc),
822 Attribute_Name => Name_Pos,
824 Expressions => New_List (
825 Make_Attribute_Reference (Loc,
826 Prefix => New_Reference_To (Ptyp, Loc),
827 Attribute_Name => Name_Last))));
829 -- For enumeration'Wide_Width, add encoding method parameter
831 if Wide then
832 Append_To (Arglist,
833 Make_Integer_Literal (Loc,
834 Intval => Int (Wide_Character_Encoding_Method)));
835 end if;
837 Rewrite (N,
838 Convert_To (Typ,
839 Make_Function_Call (Loc,
840 Name => New_Reference_To (RTE (XX), Loc),
841 Parameter_Associations => Arglist)));
843 Analyze_And_Resolve (N, Typ);
844 return;
845 end if;
847 -- If we fall through XX and YY are set
849 Arglist := New_List (
850 Convert_To (YY,
851 Make_Attribute_Reference (Loc,
852 Prefix => New_Reference_To (Ptyp, Loc),
853 Attribute_Name => Name_First)),
855 Convert_To (YY,
856 Make_Attribute_Reference (Loc,
857 Prefix => New_Reference_To (Ptyp, Loc),
858 Attribute_Name => Name_Last)));
860 -- For Wide_Character'Width, add encoding method parameter
862 if Rtyp = Standard_Wide_Character and then Wide then
863 Append_To (Arglist,
864 Make_Integer_Literal (Loc,
865 Intval => Int (Wide_Character_Encoding_Method)));
866 end if;
868 Rewrite (N,
869 Convert_To (Typ,
870 Make_Function_Call (Loc,
871 Name => New_Reference_To (RTE (XX), Loc),
872 Parameter_Associations => Arglist)));
874 Analyze_And_Resolve (N, Typ);
875 end Expand_Width_Attribute;
877 end Exp_Imgv;