Merge from the pain train
[official-gcc.git] / gcc / ada / exp_imgv.adb
blob65bcc3d382159b3884ea67d0699020e7a24e028b
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-2005 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 types whose root type is Wide_Wide_Character
198 -- xx = Wide_Wide_haracter
199 -- tv = Wide_Wide_Character (Expr)
200 -- pm = Wide_Character_Encoding_Method
202 -- For floating-point types
203 -- xx = Floating_Point
204 -- tv = Long_Long_Float (Expr)
205 -- pm = typ'Digits
207 -- For ordinary fixed-point types
208 -- xx = Ordinary_Fixed_Point
209 -- tv = Long_Long_Float (Expr)
210 -- pm = typ'Aft
212 -- For decimal fixed-point types with size = Integer'Size
213 -- xx = Decimal
214 -- tv = Integer (Expr)
215 -- pm = typ'Scale
217 -- For decimal fixed-point types with size > Integer'Size
218 -- xx = Long_Long_Decimal
219 -- tv = Long_Long_Integer (Expr)
220 -- pm = typ'Scale
222 -- Note: for the decimal fixed-point type cases, the conversion is
223 -- done literally without scaling (i.e. the actual expression that
224 -- is generated is Image_xx (tp?(Expr) [, pm])
226 -- For enumeration types other than those declared packages Standard
227 -- or System, typ'Image (X) expands into:
229 -- Image_Enumeration_NN (typ'Pos (X), typS, typI'Address)
231 -- where typS and typI are the entities constructed as described in
232 -- the spec for the procedure Build_Enumeration_Image_Tables and NN
233 -- is 32/16/8 depending on the element type of Lit_Indexes.
235 procedure Expand_Image_Attribute (N : Node_Id) is
236 Loc : constant Source_Ptr := Sloc (N);
237 Exprs : constant List_Id := Expressions (N);
238 Pref : constant Node_Id := Prefix (N);
239 Ptyp : constant Entity_Id := Entity (Pref);
240 Rtyp : constant Entity_Id := Root_Type (Ptyp);
241 Expr : constant Node_Id := Relocate_Node (First (Exprs));
242 Imid : RE_Id;
243 Tent : Entity_Id;
244 Arglist : List_Id;
245 Func : RE_Id;
246 Ttyp : Entity_Id;
247 Func_Ent : Entity_Id;
249 begin
250 if Rtyp = Standard_Boolean then
251 Imid := RE_Image_Boolean;
252 Tent := Rtyp;
254 elsif Rtyp = Standard_Character then
255 Imid := RE_Image_Character;
256 Tent := Rtyp;
258 elsif Rtyp = Standard_Wide_Character then
259 Imid := RE_Image_Wide_Character;
260 Tent := Rtyp;
262 elsif Rtyp = Standard_Wide_Wide_Character then
263 Imid := RE_Image_Wide_Wide_Character;
264 Tent := Rtyp;
266 elsif Is_Signed_Integer_Type (Rtyp) then
267 if Esize (Rtyp) <= Esize (Standard_Integer) then
268 Imid := RE_Image_Integer;
269 Tent := Standard_Integer;
270 else
271 Imid := RE_Image_Long_Long_Integer;
272 Tent := Standard_Long_Long_Integer;
273 end if;
275 elsif Is_Modular_Integer_Type (Rtyp) then
276 if Modulus (Rtyp) <= Modulus (RTE (RE_Unsigned)) then
277 Imid := RE_Image_Unsigned;
278 Tent := RTE (RE_Unsigned);
279 else
280 Imid := RE_Image_Long_Long_Unsigned;
281 Tent := RTE (RE_Long_Long_Unsigned);
282 end if;
284 elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
285 if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
286 Imid := RE_Image_Decimal;
287 Tent := Standard_Integer;
288 else
289 Imid := RE_Image_Long_Long_Decimal;
290 Tent := Standard_Long_Long_Integer;
291 end if;
293 elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
294 Imid := RE_Image_Ordinary_Fixed_Point;
295 Tent := Standard_Long_Long_Float;
297 elsif Is_Floating_Point_Type (Rtyp) then
298 Imid := RE_Image_Floating_Point;
299 Tent := Standard_Long_Long_Float;
301 -- Only other possibility is user defined enumeration type
303 else
304 if Discard_Names (First_Subtype (Ptyp))
305 or else No (Lit_Strings (Root_Type (Ptyp)))
306 then
307 -- When pragma Discard_Names applies to the first subtype,
308 -- then build (Pref'Pos)'Img.
310 Rewrite (N,
311 Make_Attribute_Reference (Loc,
312 Prefix =>
313 Make_Attribute_Reference (Loc,
314 Prefix => Pref,
315 Attribute_Name => Name_Pos,
316 Expressions => New_List (Expr)),
317 Attribute_Name =>
318 Name_Img));
319 Analyze_And_Resolve (N, Standard_String);
321 else
322 -- Here we get the Image of an enumeration type
324 Ttyp := Component_Type (Etype (Lit_Indexes (Rtyp)));
326 if Ttyp = Standard_Integer_8 then
327 Func := RE_Image_Enumeration_8;
328 elsif Ttyp = Standard_Integer_16 then
329 Func := RE_Image_Enumeration_16;
330 else
331 Func := RE_Image_Enumeration_32;
332 end if;
334 -- Apply a validity check, since it is a bit drastic to
335 -- get a completely junk image value for an invalid value.
337 if not Expr_Known_Valid (Expr) then
338 Insert_Valid_Check (Expr);
339 end if;
341 Rewrite (N,
342 Make_Function_Call (Loc,
343 Name => New_Occurrence_Of (RTE (Func), Loc),
344 Parameter_Associations => New_List (
345 Make_Attribute_Reference (Loc,
346 Attribute_Name => Name_Pos,
347 Prefix => New_Occurrence_Of (Ptyp, Loc),
348 Expressions => New_List (Expr)),
349 New_Occurrence_Of (Lit_Strings (Rtyp), Loc),
350 Make_Attribute_Reference (Loc,
351 Prefix => New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
352 Attribute_Name => Name_Address))));
354 Analyze_And_Resolve (N, Standard_String);
355 end if;
357 return;
358 end if;
360 -- If we fall through, we have one of the cases that is handled by
361 -- calling one of the System.Img_xx routines and Imid is set to the
362 -- RE_Id for the function to be called.
364 Func_Ent := RTE (Imid);
366 -- If the function entity is empty, that means we have a case in
367 -- no run time mode where the operation is not allowed, and an
368 -- appropriate diagnostic has already been issued.
370 if No (Func_Ent) then
371 return;
372 end if;
374 -- Otherwise prepare arguments for run-time call
376 Arglist := New_List (Convert_To (Tent, Relocate_Node (Expr)));
378 -- For floating-point types, append Digits argument
380 if Is_Floating_Point_Type (Rtyp) then
381 Append_To (Arglist,
382 Make_Attribute_Reference (Loc,
383 Prefix => New_Reference_To (Ptyp, Loc),
384 Attribute_Name => Name_Digits));
386 -- For ordinary fixed-point types, append Aft parameter
388 elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
389 Append_To (Arglist,
390 Make_Attribute_Reference (Loc,
391 Prefix => New_Reference_To (Ptyp, Loc),
392 Attribute_Name => Name_Aft));
394 -- For wide [wide] character, append encoding method
396 elsif Rtyp = Standard_Wide_Character
397 or else Rtyp = Standard_Wide_Wide_Character
398 then
399 Append_To (Arglist,
400 Make_Integer_Literal (Loc,
401 Intval => Int (Wide_Character_Encoding_Method)));
403 -- For decimal, append Scale and also set to do literal conversion
405 elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
406 Append_To (Arglist,
407 Make_Attribute_Reference (Loc,
408 Prefix => New_Reference_To (Ptyp, Loc),
409 Attribute_Name => Name_Scale));
411 Set_Conversion_OK (First (Arglist));
412 Set_Etype (First (Arglist), Tent);
413 end if;
415 Rewrite (N,
416 Make_Function_Call (Loc,
417 Name => New_Reference_To (Func_Ent, Loc),
418 Parameter_Associations => Arglist));
420 Analyze_And_Resolve (N, Standard_String);
421 end Expand_Image_Attribute;
423 ----------------------------
424 -- Expand_Value_Attribute --
425 ----------------------------
427 -- For scalar types derived from Boolean, Character and integer types
428 -- in package Standard, typ'Value (X) expands into:
430 -- btyp (Value_xx (X))
432 -- where btyp is he base type of the prefix, and
434 -- For types whose root type is Character
435 -- xx = Character
437 -- For types whose root type is Boolean
438 -- xx = Boolean
440 -- For signed integer types with size <= Integer'Size
441 -- xx = Integer
443 -- For other signed integer types
444 -- xx = Long_Long_Integer
446 -- For modular types with modulus <= System.Unsigned_Types.Unsigned
447 -- xx = Unsigned
449 -- For other modular integer types
450 -- xx = Long_Long_Unsigned
452 -- For floating-point types and ordinary fixed-point types
453 -- xx = Real
455 -- For types derived from Wide_Character, typ'Value (X) expands into
457 -- Value_Wide_Character (X, Wide_Character_Encoding_Method)
459 -- For types derived from Wide_Wide_Character, typ'Value (X) expands into
461 -- Value_Wide_Wide_Character (X, Wide_Character_Encoding_Method)
463 -- For decimal types with size <= Integer'Size, typ'Value (X)
464 -- expands into
466 -- btyp?(Value_Decimal (X, typ'Scale));
468 -- For all other decimal types, typ'Value (X) expands into
470 -- btyp?(Value_Long_Long_Decimal (X, typ'Scale))
472 -- For enumeration types other than those derived from types Boolean,
473 -- Character, Wide_[Wide_]Character in Standard, typ'Value (X) expands to:
475 -- Enum'Val (Value_Enumeration_NN (typS, typI'Address, Num, X))
477 -- where typS and typI and the Lit_Strings and Lit_Indexes entities
478 -- from T's root type entitym and Num is Enum'Pos (Enum'Last). The
479 -- Value_Enumeration_NN function will search the tables looking for
480 -- X and return the position number in the table if found which is
481 -- used to provide the result of 'Value (using Enum'Val). If the
482 -- value is not found Constraint_Error is raised. The suffix _NN
483 -- depends on the element type of typI.
485 procedure Expand_Value_Attribute (N : Node_Id) is
486 Loc : constant Source_Ptr := Sloc (N);
487 Typ : constant Entity_Id := Etype (N);
488 Btyp : constant Entity_Id := Base_Type (Typ);
489 Rtyp : constant Entity_Id := Root_Type (Typ);
490 Exprs : constant List_Id := Expressions (N);
491 Vid : RE_Id;
492 Args : List_Id;
493 Func : RE_Id;
494 Ttyp : Entity_Id;
496 begin
497 Args := Exprs;
499 if Rtyp = Standard_Character then
500 Vid := RE_Value_Character;
502 elsif Rtyp = Standard_Boolean then
503 Vid := RE_Value_Boolean;
505 elsif Rtyp = Standard_Wide_Character then
506 Vid := RE_Value_Wide_Character;
507 Append_To (Args,
508 Make_Integer_Literal (Loc,
509 Intval => Int (Wide_Character_Encoding_Method)));
511 elsif Rtyp = Standard_Wide_Wide_Character then
512 Vid := RE_Value_Wide_Wide_Character;
513 Append_To (Args,
514 Make_Integer_Literal (Loc,
515 Intval => Int (Wide_Character_Encoding_Method)));
517 elsif Rtyp = Base_Type (Standard_Short_Short_Integer)
518 or else Rtyp = Base_Type (Standard_Short_Integer)
519 or else Rtyp = Base_Type (Standard_Integer)
520 then
521 Vid := RE_Value_Integer;
523 elsif Is_Signed_Integer_Type (Rtyp) then
524 Vid := RE_Value_Long_Long_Integer;
526 elsif Is_Modular_Integer_Type (Rtyp) then
527 if Modulus (Rtyp) <= Modulus (RTE (RE_Unsigned)) then
528 Vid := RE_Value_Unsigned;
529 else
530 Vid := RE_Value_Long_Long_Unsigned;
531 end if;
533 elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
534 if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
535 Vid := RE_Value_Decimal;
536 else
537 Vid := RE_Value_Long_Long_Decimal;
538 end if;
540 Append_To (Args,
541 Make_Attribute_Reference (Loc,
542 Prefix => New_Reference_To (Typ, Loc),
543 Attribute_Name => Name_Scale));
545 Rewrite (N,
546 OK_Convert_To (Btyp,
547 Make_Function_Call (Loc,
548 Name => New_Reference_To (RTE (Vid), Loc),
549 Parameter_Associations => Args)));
551 Set_Etype (N, Btyp);
552 Analyze_And_Resolve (N, Btyp);
553 return;
555 elsif Is_Real_Type (Rtyp) then
556 Vid := RE_Value_Real;
558 -- Only other possibility is user defined enumeration type
560 else
561 pragma Assert (Is_Enumeration_Type (Rtyp));
563 -- Case of pragma Discard_Names, transform the Value
564 -- attribute to Btyp'Val (Long_Long_Integer'Value (Args))
566 if Discard_Names (First_Subtype (Typ))
567 or else No (Lit_Strings (Rtyp))
568 then
569 Rewrite (N,
570 Make_Attribute_Reference (Loc,
571 Prefix => New_Reference_To (Btyp, Loc),
572 Attribute_Name => Name_Val,
573 Expressions => New_List (
574 Make_Attribute_Reference (Loc,
575 Prefix =>
576 New_Occurrence_Of (Standard_Long_Long_Integer, Loc),
577 Attribute_Name => Name_Value,
578 Expressions => Args))));
580 Analyze_And_Resolve (N, Btyp);
582 -- Here for normal case where we have enumeration tables, this
583 -- is where we build
585 -- T'Val (Value_Enumeration_NN (typS, typI'Address, Num, X))
587 else
588 Ttyp := Component_Type (Etype (Lit_Indexes (Rtyp)));
590 if Ttyp = Standard_Integer_8 then
591 Func := RE_Value_Enumeration_8;
592 elsif Ttyp = Standard_Integer_16 then
593 Func := RE_Value_Enumeration_16;
594 else
595 Func := RE_Value_Enumeration_32;
596 end if;
598 Prepend_To (Args,
599 Make_Attribute_Reference (Loc,
600 Prefix => New_Occurrence_Of (Rtyp, Loc),
601 Attribute_Name => Name_Pos,
602 Expressions => New_List (
603 Make_Attribute_Reference (Loc,
604 Prefix => New_Occurrence_Of (Rtyp, Loc),
605 Attribute_Name => Name_Last))));
607 Prepend_To (Args,
608 Make_Attribute_Reference (Loc,
609 Prefix => New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
610 Attribute_Name => Name_Address));
612 Prepend_To (Args,
613 New_Occurrence_Of (Lit_Strings (Rtyp), Loc));
615 Rewrite (N,
616 Make_Attribute_Reference (Loc,
617 Prefix => New_Reference_To (Typ, Loc),
618 Attribute_Name => Name_Val,
619 Expressions => New_List (
620 Make_Function_Call (Loc,
621 Name =>
622 New_Reference_To (RTE (Func), Loc),
623 Parameter_Associations => Args))));
625 Analyze_And_Resolve (N, Btyp);
626 end if;
628 return;
629 end if;
631 -- Fall through for all cases except user defined enumeration type
632 -- and decimal types, with Vid set to the Id of the entity for the
633 -- Value routine and Args set to the list of parameters for the call.
635 Rewrite (N,
636 Convert_To (Btyp,
637 Make_Function_Call (Loc,
638 Name => New_Reference_To (RTE (Vid), Loc),
639 Parameter_Associations => Args)));
641 Analyze_And_Resolve (N, Btyp);
642 end Expand_Value_Attribute;
644 ----------------------------
645 -- Expand_Width_Attribute --
646 ----------------------------
648 -- The processing here also handles the case of Wide_[Wide_]Width. With the
649 -- exceptions noted, the processing is identical
651 -- For scalar types derived from Boolean, character and integer types
652 -- in package Standard. Note that the Width attribute is computed at
653 -- compile time for all cases except those involving non-static sub-
654 -- types. For such subtypes, typ'[Wide_[Wide_]]Width expands into:
656 -- Result_Type (xx (yy (Ptyp'First), yy (Ptyp'Last)))
658 -- where
660 -- For types whose root type is Character
661 -- xx = Width_Character
662 -- yy = Character
664 -- For types whose root type is Wide_Character
665 -- xx = Wide_Width_Character
666 -- yy = Character
668 -- For types whose root type is Wide_Wide_Character
669 -- xx = Wide_Wide_Width_Character
670 -- yy = Character
672 -- For types whose root type is Boolean
673 -- xx = Width_Boolean
674 -- yy = Boolean
676 -- For signed integer types
677 -- xx = Width_Long_Long_Integer
678 -- yy = Long_Long_Integer
680 -- For modular integer types
681 -- xx = Width_Long_Long_Unsigned
682 -- yy = Long_Long_Unsigned
684 -- For types derived from Wide_Character, typ'Width expands into
686 -- Result_Type (Width_Wide_Character (
687 -- Wide_Character (typ'First),
688 -- Wide_Character (typ'Last),
689 -- Wide_Character_Encoding_Method);
691 -- and typ'Wide_Width expands into:
693 -- Result_Type (Wide_Width_Wide_Character (
694 -- Wide_Character (typ'First),
695 -- Wide_Character (typ'Last));
696 -- Wide_Character_Encoding_Method);
698 -- and typ'Wide_Wide_Width expands into
700 -- Result_Type (Wide_Wide_Width_Wide_Character (
701 -- Wide_Character (typ'First),
702 -- Wide_Character (typ'Last));
703 -- Wide_Character_Encoding_Method);
705 -- For types derived from Wide_Wide_Character, typ'Width expands into
707 -- Result_Type (Width_Wide_Wide_Character (
708 -- Wide_Wide_Character (typ'First),
709 -- Wide_Wide_Character (typ'Last),
710 -- Wide_Character_Encoding_Method);
712 -- and typ'Wide_Width expands into:
714 -- Result_Type (Wide_Width_Wide_Wide_Character (
715 -- Wide_Wide_Character (typ'First),
716 -- Wide_Wide_Character (typ'Last));
717 -- Wide_Character_Encoding_Method);
719 -- and typ'Wide_Wide_Width expands into
721 -- Result_Type (Wide_Wide_Width_Wide_Wide_Char (
722 -- Wide_Wide_Character (typ'First),
723 -- Wide_Wide_Character (typ'Last));
724 -- Wide_Character_Encoding_Method);
726 -- For real types, typ'Width and typ'Wide_[Wide_]Width expand into
728 -- if Ptyp'First > Ptyp'Last then 0 else btyp'Width end if
730 -- where btyp is the base type. This looks recursive but it isn't
731 -- because the base type is always static, and hence the expression
732 -- in the else is reduced to an integer literal.
734 -- For user defined enumeration types, typ'Width expands into
736 -- Result_Type (Width_Enumeration_NN
737 -- (typS,
738 -- typI'Address,
739 -- typ'Pos (typ'First),
740 -- typ'Pos (Typ'Last)));
742 -- and typ'Wide_Width expands into:
744 -- Result_Type (Wide_Width_Enumeration_NN
745 -- (typS,
746 -- typI,
747 -- typ'Pos (typ'First),
748 -- typ'Pos (Typ'Last))
749 -- Wide_Character_Encoding_Method);
751 -- and typ'Wide_Wide_Width expands into:
753 -- Result_Type (Wide_Wide_Width_Enumeration_NN
754 -- (typS,
755 -- typI,
756 -- typ'Pos (typ'First),
757 -- typ'Pos (Typ'Last))
758 -- Wide_Character_Encoding_Method);
760 -- where typS and typI are the enumeration image strings and
761 -- indexes table, as described in Build_Enumeration_Image_Tables.
762 -- NN is 8/16/32 for depending on the element type for typI.
764 procedure Expand_Width_Attribute (N : Node_Id; Attr : Atype := Normal) is
765 Loc : constant Source_Ptr := Sloc (N);
766 Typ : constant Entity_Id := Etype (N);
767 Pref : constant Node_Id := Prefix (N);
768 Ptyp : constant Entity_Id := Etype (Pref);
769 Rtyp : constant Entity_Id := Root_Type (Ptyp);
770 XX : RE_Id;
771 YY : Entity_Id;
772 Arglist : List_Id;
773 Ttyp : Entity_Id;
775 begin
776 -- Types derived from Standard.Boolean
778 if Rtyp = Standard_Boolean then
779 XX := RE_Width_Boolean;
780 YY := Rtyp;
782 -- Types derived from Standard.Character
784 elsif Rtyp = Standard_Character then
785 case Attr is
786 when Normal => XX := RE_Width_Character;
787 when Wide => XX := RE_Wide_Width_Character;
788 when Wide_Wide => XX := RE_Wide_Wide_Width_Character;
789 end case;
791 YY := Rtyp;
793 -- Types derived from Standard.Wide_Character
795 elsif Rtyp = Standard_Wide_Character then
796 case Attr is
797 when Normal => XX := RE_Width_Wide_Character;
798 when Wide => XX := RE_Wide_Width_Wide_Character;
799 when Wide_Wide => XX := RE_Wide_Wide_Width_Wide_Character;
800 end case;
802 YY := Rtyp;
804 -- Types derived from Standard.Wide_Wide_Character
806 elsif Rtyp = Standard_Wide_Wide_Character then
807 case Attr is
808 when Normal => XX := RE_Width_Wide_Wide_Character;
809 when Wide => XX := RE_Wide_Width_Wide_Wide_Character;
810 when Wide_Wide => XX := RE_Wide_Wide_Width_Wide_Wide_Char;
811 end case;
813 YY := Rtyp;
815 -- Signed integer types
817 elsif Is_Signed_Integer_Type (Rtyp) then
818 XX := RE_Width_Long_Long_Integer;
819 YY := Standard_Long_Long_Integer;
821 -- Modular integer types
823 elsif Is_Modular_Integer_Type (Rtyp) then
824 XX := RE_Width_Long_Long_Unsigned;
825 YY := RTE (RE_Long_Long_Unsigned);
827 -- Real types
829 elsif Is_Real_Type (Rtyp) then
831 Rewrite (N,
832 Make_Conditional_Expression (Loc,
833 Expressions => New_List (
835 Make_Op_Gt (Loc,
836 Left_Opnd =>
837 Make_Attribute_Reference (Loc,
838 Prefix => New_Reference_To (Ptyp, Loc),
839 Attribute_Name => Name_First),
841 Right_Opnd =>
842 Make_Attribute_Reference (Loc,
843 Prefix => New_Reference_To (Ptyp, Loc),
844 Attribute_Name => Name_Last)),
846 Make_Integer_Literal (Loc, 0),
848 Make_Attribute_Reference (Loc,
849 Prefix => New_Reference_To (Base_Type (Ptyp), Loc),
850 Attribute_Name => Name_Width))));
852 Analyze_And_Resolve (N, Typ);
853 return;
855 -- User defined enumeration types
857 else
858 pragma Assert (Is_Enumeration_Type (Rtyp));
860 Ttyp := Component_Type (Etype (Lit_Indexes (Rtyp)));
862 case Attr is
863 when Normal =>
864 if Ttyp = Standard_Integer_8 then
865 XX := RE_Width_Enumeration_8;
866 elsif Ttyp = Standard_Integer_16 then
867 XX := RE_Width_Enumeration_16;
868 else
869 XX := RE_Width_Enumeration_32;
870 end if;
872 when Wide =>
873 if Ttyp = Standard_Integer_8 then
874 XX := RE_Wide_Width_Enumeration_8;
875 elsif Ttyp = Standard_Integer_16 then
876 XX := RE_Wide_Width_Enumeration_16;
877 else
878 XX := RE_Wide_Width_Enumeration_32;
879 end if;
881 when Wide_Wide =>
882 if Ttyp = Standard_Integer_8 then
883 XX := RE_Wide_Wide_Width_Enumeration_8;
884 elsif Ttyp = Standard_Integer_16 then
885 XX := RE_Wide_Wide_Width_Enumeration_16;
886 else
887 XX := RE_Wide_Wide_Width_Enumeration_32;
888 end if;
889 end case;
891 Arglist :=
892 New_List (
893 New_Occurrence_Of (Lit_Strings (Rtyp), Loc),
895 Make_Attribute_Reference (Loc,
896 Prefix => New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
897 Attribute_Name => Name_Address),
899 Make_Attribute_Reference (Loc,
900 Prefix => New_Reference_To (Ptyp, Loc),
901 Attribute_Name => Name_Pos,
903 Expressions => New_List (
904 Make_Attribute_Reference (Loc,
905 Prefix => New_Reference_To (Ptyp, Loc),
906 Attribute_Name => Name_First))),
908 Make_Attribute_Reference (Loc,
909 Prefix => New_Reference_To (Ptyp, Loc),
910 Attribute_Name => Name_Pos,
912 Expressions => New_List (
913 Make_Attribute_Reference (Loc,
914 Prefix => New_Reference_To (Ptyp, Loc),
915 Attribute_Name => Name_Last))));
917 -- For enumeration'Wide_[Wide_]Width, add encoding method parameter
919 if Attr /= Normal then
920 Append_To (Arglist,
921 Make_Integer_Literal (Loc,
922 Intval => Int (Wide_Character_Encoding_Method)));
923 end if;
925 Rewrite (N,
926 Convert_To (Typ,
927 Make_Function_Call (Loc,
928 Name => New_Reference_To (RTE (XX), Loc),
929 Parameter_Associations => Arglist)));
931 Analyze_And_Resolve (N, Typ);
932 return;
933 end if;
935 -- If we fall through XX and YY are set
937 Arglist := New_List (
938 Convert_To (YY,
939 Make_Attribute_Reference (Loc,
940 Prefix => New_Reference_To (Ptyp, Loc),
941 Attribute_Name => Name_First)),
943 Convert_To (YY,
944 Make_Attribute_Reference (Loc,
945 Prefix => New_Reference_To (Ptyp, Loc),
946 Attribute_Name => Name_Last)));
948 -- For Wide_[Wide_]Character'Width, add encoding method parameter
950 if (Rtyp = Standard_Wide_Character
951 or else
952 Rtyp = Standard_Wide_Wide_Character)
953 and then Attr /= Normal then
954 Append_To (Arglist,
955 Make_Integer_Literal (Loc,
956 Intval => Int (Wide_Character_Encoding_Method)));
957 end if;
959 Rewrite (N,
960 Convert_To (Typ,
961 Make_Function_Call (Loc,
962 Name => New_Reference_To (RTE (XX), Loc),
963 Parameter_Associations => Arglist)));
965 Analyze_And_Resolve (N, Typ);
966 end Expand_Width_Attribute;
968 end Exp_Imgv;