annotate gcc/ada/exp_imgv.adb @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT COMPILER COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- E X P _ I M G V --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
9 -- Copyright (C) 2001-2018, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
kono
parents:
diff changeset
17 -- for more details. You should have received a copy of the GNU General --
kono
parents:
diff changeset
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
kono
parents:
diff changeset
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
kono
parents:
diff changeset
20 -- --
kono
parents:
diff changeset
21 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
23 -- --
kono
parents:
diff changeset
24 ------------------------------------------------------------------------------
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 with Atree; use Atree;
kono
parents:
diff changeset
27 with Casing; use Casing;
kono
parents:
diff changeset
28 with Checks; use Checks;
kono
parents:
diff changeset
29 with Einfo; use Einfo;
kono
parents:
diff changeset
30 with Exp_Util; use Exp_Util;
kono
parents:
diff changeset
31 with Lib; use Lib;
kono
parents:
diff changeset
32 with Namet; use Namet;
kono
parents:
diff changeset
33 with Nmake; use Nmake;
kono
parents:
diff changeset
34 with Nlists; use Nlists;
kono
parents:
diff changeset
35 with Opt; use Opt;
kono
parents:
diff changeset
36 with Rtsfind; use Rtsfind;
kono
parents:
diff changeset
37 with Sem_Aux; use Sem_Aux;
kono
parents:
diff changeset
38 with Sem_Res; use Sem_Res;
kono
parents:
diff changeset
39 with Sem_Util; use Sem_Util;
kono
parents:
diff changeset
40 with Sinfo; use Sinfo;
kono
parents:
diff changeset
41 with Snames; use Snames;
kono
parents:
diff changeset
42 with Stand; use Stand;
kono
parents:
diff changeset
43 with Stringt; use Stringt;
kono
parents:
diff changeset
44 with Tbuild; use Tbuild;
kono
parents:
diff changeset
45 with Ttypes; use Ttypes;
kono
parents:
diff changeset
46 with Uintp; use Uintp;
kono
parents:
diff changeset
47 with Urealp; use Urealp;
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 package body Exp_Imgv is
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 function Has_Decimal_Small (E : Entity_Id) return Boolean;
kono
parents:
diff changeset
52 -- Applies to all entities. True for a Decimal_Fixed_Point_Type, or an
kono
parents:
diff changeset
53 -- Ordinary_Fixed_Point_Type with a small that is a negative power of ten.
kono
parents:
diff changeset
54 -- Shouldn't this be in einfo.adb or sem_aux.adb???
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 procedure Rewrite_Object_Image
kono
parents:
diff changeset
57 (N : Node_Id;
kono
parents:
diff changeset
58 Pref : Entity_Id;
kono
parents:
diff changeset
59 Attr_Name : Name_Id;
kono
parents:
diff changeset
60 Str_Typ : Entity_Id);
kono
parents:
diff changeset
61 -- AI12-00124: Rewrite attribute 'Image when it is applied to an object
kono
parents:
diff changeset
62 -- reference as an attribute applied to a type. N denotes the node to be
kono
parents:
diff changeset
63 -- rewritten, Pref denotes the prefix of the 'Image attribute, and Name
kono
parents:
diff changeset
64 -- and Str_Typ specify which specific string type and 'Image attribute to
kono
parents:
diff changeset
65 -- apply (e.g. Name_Wide_Image and Standard_Wide_String).
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 ------------------------------------
kono
parents:
diff changeset
68 -- Build_Enumeration_Image_Tables --
kono
parents:
diff changeset
69 ------------------------------------
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 procedure Build_Enumeration_Image_Tables (E : Entity_Id; N : Node_Id) is
kono
parents:
diff changeset
72 Loc : constant Source_Ptr := Sloc (E);
kono
parents:
diff changeset
73 Str : String_Id;
kono
parents:
diff changeset
74 Ind : List_Id;
kono
parents:
diff changeset
75 Lit : Entity_Id;
kono
parents:
diff changeset
76 Nlit : Nat;
kono
parents:
diff changeset
77 Len : Nat;
kono
parents:
diff changeset
78 Estr : Entity_Id;
kono
parents:
diff changeset
79 Eind : Entity_Id;
kono
parents:
diff changeset
80 Ityp : Node_Id;
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 begin
kono
parents:
diff changeset
83 -- Nothing to do for other than a root enumeration type
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 if E /= Root_Type (E) then
kono
parents:
diff changeset
86 return;
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 -- Nothing to do if pragma Discard_Names applies
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 elsif Discard_Names (E) then
kono
parents:
diff changeset
91 return;
kono
parents:
diff changeset
92 end if;
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 -- Otherwise tables need constructing
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 Start_String;
kono
parents:
diff changeset
97 Ind := New_List;
kono
parents:
diff changeset
98 Lit := First_Literal (E);
kono
parents:
diff changeset
99 Len := 1;
kono
parents:
diff changeset
100 Nlit := 0;
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 loop
kono
parents:
diff changeset
103 Append_To (Ind,
kono
parents:
diff changeset
104 Make_Integer_Literal (Loc, UI_From_Int (Len)));
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 exit when No (Lit);
kono
parents:
diff changeset
107 Nlit := Nlit + 1;
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 Get_Unqualified_Decoded_Name_String (Chars (Lit));
kono
parents:
diff changeset
110
kono
parents:
diff changeset
111 if Name_Buffer (1) /= ''' then
kono
parents:
diff changeset
112 Set_Casing (All_Upper_Case);
kono
parents:
diff changeset
113 end if;
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 Store_String_Chars (Name_Buffer (1 .. Name_Len));
kono
parents:
diff changeset
116 Len := Len + Int (Name_Len);
kono
parents:
diff changeset
117 Next_Literal (Lit);
kono
parents:
diff changeset
118 end loop;
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 if Len < Int (2 ** (8 - 1)) then
kono
parents:
diff changeset
121 Ityp := Standard_Integer_8;
kono
parents:
diff changeset
122 elsif Len < Int (2 ** (16 - 1)) then
kono
parents:
diff changeset
123 Ityp := Standard_Integer_16;
kono
parents:
diff changeset
124 else
kono
parents:
diff changeset
125 Ityp := Standard_Integer_32;
kono
parents:
diff changeset
126 end if;
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 Str := End_String;
kono
parents:
diff changeset
129
kono
parents:
diff changeset
130 Estr :=
kono
parents:
diff changeset
131 Make_Defining_Identifier (Loc,
kono
parents:
diff changeset
132 Chars => New_External_Name (Chars (E), 'S'));
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 Eind :=
kono
parents:
diff changeset
135 Make_Defining_Identifier (Loc,
kono
parents:
diff changeset
136 Chars => New_External_Name (Chars (E), 'N'));
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 Set_Lit_Strings (E, Estr);
kono
parents:
diff changeset
139 Set_Lit_Indexes (E, Eind);
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 Insert_Actions (N,
kono
parents:
diff changeset
142 New_List (
kono
parents:
diff changeset
143 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
144 Defining_Identifier => Estr,
kono
parents:
diff changeset
145 Constant_Present => True,
kono
parents:
diff changeset
146 Object_Definition =>
kono
parents:
diff changeset
147 New_Occurrence_Of (Standard_String, Loc),
kono
parents:
diff changeset
148 Expression =>
kono
parents:
diff changeset
149 Make_String_Literal (Loc,
kono
parents:
diff changeset
150 Strval => Str)),
kono
parents:
diff changeset
151
kono
parents:
diff changeset
152 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
153 Defining_Identifier => Eind,
kono
parents:
diff changeset
154 Constant_Present => True,
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 Object_Definition =>
kono
parents:
diff changeset
157 Make_Constrained_Array_Definition (Loc,
kono
parents:
diff changeset
158 Discrete_Subtype_Definitions => New_List (
kono
parents:
diff changeset
159 Make_Range (Loc,
kono
parents:
diff changeset
160 Low_Bound => Make_Integer_Literal (Loc, 0),
kono
parents:
diff changeset
161 High_Bound => Make_Integer_Literal (Loc, Nlit))),
kono
parents:
diff changeset
162 Component_Definition =>
kono
parents:
diff changeset
163 Make_Component_Definition (Loc,
kono
parents:
diff changeset
164 Aliased_Present => False,
kono
parents:
diff changeset
165 Subtype_Indication => New_Occurrence_Of (Ityp, Loc))),
kono
parents:
diff changeset
166
kono
parents:
diff changeset
167 Expression =>
kono
parents:
diff changeset
168 Make_Aggregate (Loc,
kono
parents:
diff changeset
169 Expressions => Ind))),
kono
parents:
diff changeset
170 Suppress => All_Checks);
kono
parents:
diff changeset
171 end Build_Enumeration_Image_Tables;
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 ----------------------------
kono
parents:
diff changeset
174 -- Expand_Image_Attribute --
kono
parents:
diff changeset
175 ----------------------------
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 -- For all cases other than user-defined enumeration types, the scheme
kono
parents:
diff changeset
178 -- is as follows. First we insert the following code:
kono
parents:
diff changeset
179
kono
parents:
diff changeset
180 -- Snn : String (1 .. rt'Width);
kono
parents:
diff changeset
181 -- Pnn : Natural;
kono
parents:
diff changeset
182 -- Image_xx (tv, Snn, Pnn [,pm]);
kono
parents:
diff changeset
183 --
kono
parents:
diff changeset
184 -- and then Expr is replaced by Snn (1 .. Pnn)
kono
parents:
diff changeset
185
kono
parents:
diff changeset
186 -- In the above expansion:
kono
parents:
diff changeset
187
kono
parents:
diff changeset
188 -- rt is the root type of the expression
kono
parents:
diff changeset
189 -- tv is the expression with the value, usually a type conversion
kono
parents:
diff changeset
190 -- pm is an extra parameter present in some cases
kono
parents:
diff changeset
191
kono
parents:
diff changeset
192 -- The following table shows tv, xx, and (if used) pm for the various
kono
parents:
diff changeset
193 -- possible types of the argument:
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 -- For types whose root type is Character
kono
parents:
diff changeset
196 -- xx = Character
kono
parents:
diff changeset
197 -- tv = Character (Expr)
kono
parents:
diff changeset
198
kono
parents:
diff changeset
199 -- For types whose root type is Boolean
kono
parents:
diff changeset
200 -- xx = Boolean
kono
parents:
diff changeset
201 -- tv = Boolean (Expr)
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 -- For signed integer types with size <= Integer'Size
kono
parents:
diff changeset
204 -- xx = Integer
kono
parents:
diff changeset
205 -- tv = Integer (Expr)
kono
parents:
diff changeset
206
kono
parents:
diff changeset
207 -- For other signed integer types
kono
parents:
diff changeset
208 -- xx = Long_Long_Integer
kono
parents:
diff changeset
209 -- tv = Long_Long_Integer (Expr)
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 -- For modular types with modulus <= System.Unsigned_Types.Unsigned
kono
parents:
diff changeset
212 -- xx = Unsigned
kono
parents:
diff changeset
213 -- tv = System.Unsigned_Types.Unsigned (Expr)
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 -- For other modular integer types
kono
parents:
diff changeset
216 -- xx = Long_Long_Unsigned
kono
parents:
diff changeset
217 -- tv = System.Unsigned_Types.Long_Long_Unsigned (Expr)
kono
parents:
diff changeset
218
kono
parents:
diff changeset
219 -- For types whose root type is Wide_Character
kono
parents:
diff changeset
220 -- xx = Wide_Character
kono
parents:
diff changeset
221 -- tv = Wide_Character (Expr)
kono
parents:
diff changeset
222 -- pm = Boolean, true if Ada 2005 mode, False otherwise
kono
parents:
diff changeset
223
kono
parents:
diff changeset
224 -- For types whose root type is Wide_Wide_Character
kono
parents:
diff changeset
225 -- xx = Wide_Wide_Character
kono
parents:
diff changeset
226 -- tv = Wide_Wide_Character (Expr)
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 -- For floating-point types
kono
parents:
diff changeset
229 -- xx = Floating_Point
kono
parents:
diff changeset
230 -- tv = Long_Long_Float (Expr)
kono
parents:
diff changeset
231 -- pm = typ'Digits (typ = subtype of expression)
kono
parents:
diff changeset
232
kono
parents:
diff changeset
233 -- For ordinary fixed-point types
kono
parents:
diff changeset
234 -- xx = Ordinary_Fixed_Point
kono
parents:
diff changeset
235 -- tv = Long_Long_Float (Expr)
kono
parents:
diff changeset
236 -- pm = typ'Aft (typ = subtype of expression)
kono
parents:
diff changeset
237
kono
parents:
diff changeset
238 -- For decimal fixed-point types with size = Integer'Size
kono
parents:
diff changeset
239 -- xx = Decimal
kono
parents:
diff changeset
240 -- tv = Integer (Expr)
kono
parents:
diff changeset
241 -- pm = typ'Scale (typ = subtype of expression)
kono
parents:
diff changeset
242
kono
parents:
diff changeset
243 -- For decimal fixed-point types with size > Integer'Size
kono
parents:
diff changeset
244 -- xx = Long_Long_Decimal
kono
parents:
diff changeset
245 -- tv = Long_Long_Integer?(Expr) [convert with no scaling]
kono
parents:
diff changeset
246 -- pm = typ'Scale (typ = subtype of expression)
kono
parents:
diff changeset
247
kono
parents:
diff changeset
248 -- For enumeration types other than those declared packages Standard
kono
parents:
diff changeset
249 -- or System, Snn, Pnn, are expanded as above, but the call looks like:
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 -- Image_Enumeration_NN (rt'Pos (X), Snn, Pnn, typS, typI'Address)
kono
parents:
diff changeset
252
kono
parents:
diff changeset
253 -- where rt is the root type of the expression, and typS and typI are
kono
parents:
diff changeset
254 -- the entities constructed as described in the spec for the procedure
kono
parents:
diff changeset
255 -- Build_Enumeration_Image_Tables and NN is 32/16/8 depending on the
kono
parents:
diff changeset
256 -- element type of Lit_Indexes. The rewriting of the expression to
kono
parents:
diff changeset
257 -- Snn (1 .. Pnn) then occurs as in the other cases. A special case is
kono
parents:
diff changeset
258 -- when pragma Discard_Names applies, in which case we replace expr by:
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 -- (rt'Pos (expr))'Img
kono
parents:
diff changeset
261
kono
parents:
diff changeset
262 -- So that the result is a space followed by the decimal value for the
kono
parents:
diff changeset
263 -- position of the enumeration value in the enumeration type.
kono
parents:
diff changeset
264
kono
parents:
diff changeset
265 procedure Expand_Image_Attribute (N : Node_Id) is
kono
parents:
diff changeset
266 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
267 Exprs : constant List_Id := Expressions (N);
kono
parents:
diff changeset
268 Expr : constant Node_Id := Relocate_Node (First (Exprs));
kono
parents:
diff changeset
269 Pref : constant Node_Id := Prefix (N);
kono
parents:
diff changeset
270
kono
parents:
diff changeset
271 procedure Expand_User_Defined_Enumeration_Image;
kono
parents:
diff changeset
272 -- Expand attribute 'Image in user-defined enumeration types, avoiding
kono
parents:
diff changeset
273 -- string copy.
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 function Is_User_Defined_Enumeration_Type
kono
parents:
diff changeset
276 (Typ : Entity_Id) return Boolean;
kono
parents:
diff changeset
277 -- Return True if Typ is a user-defined enumeration type
kono
parents:
diff changeset
278
kono
parents:
diff changeset
279 -------------------------------------------
kono
parents:
diff changeset
280 -- Expand_User_Defined_Enumeration_Image --
kono
parents:
diff changeset
281 -------------------------------------------
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 procedure Expand_User_Defined_Enumeration_Image is
kono
parents:
diff changeset
284 Ins_List : constant List_Id := New_List;
kono
parents:
diff changeset
285 P1_Id : constant Entity_Id := Make_Temporary (Loc, 'P');
kono
parents:
diff changeset
286 P2_Id : constant Entity_Id := Make_Temporary (Loc, 'P');
kono
parents:
diff changeset
287 P3_Id : constant Entity_Id := Make_Temporary (Loc, 'P');
kono
parents:
diff changeset
288 P4_Id : constant Entity_Id := Make_Temporary (Loc, 'P');
kono
parents:
diff changeset
289 Ptyp : constant Entity_Id := Entity (Pref);
kono
parents:
diff changeset
290 Rtyp : constant Entity_Id := Root_Type (Ptyp);
kono
parents:
diff changeset
291 S1_Id : constant Entity_Id := Make_Temporary (Loc, 'S');
kono
parents:
diff changeset
292
kono
parents:
diff changeset
293 begin
kono
parents:
diff changeset
294 -- Apply a validity check, since it is a bit drastic to get a
kono
parents:
diff changeset
295 -- completely junk image value for an invalid value.
kono
parents:
diff changeset
296
kono
parents:
diff changeset
297 if not Expr_Known_Valid (Expr) then
kono
parents:
diff changeset
298 Insert_Valid_Check (Expr);
kono
parents:
diff changeset
299 end if;
kono
parents:
diff changeset
300
kono
parents:
diff changeset
301 -- Generate:
kono
parents:
diff changeset
302 -- P1 : constant Natural := Pos;
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 Append_To (Ins_List,
kono
parents:
diff changeset
305 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
306 Defining_Identifier => P1_Id,
kono
parents:
diff changeset
307 Object_Definition =>
kono
parents:
diff changeset
308 New_Occurrence_Of (Standard_Natural, Loc),
kono
parents:
diff changeset
309 Constant_Present => True,
kono
parents:
diff changeset
310 Expression =>
kono
parents:
diff changeset
311 Convert_To (Standard_Natural,
kono
parents:
diff changeset
312 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
313 Attribute_Name => Name_Pos,
kono
parents:
diff changeset
314 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
315 Expressions => New_List (Expr)))));
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 -- Compute the index of the string start, generating:
kono
parents:
diff changeset
318 -- P2 : constant Natural := call_put_enumN (P1);
kono
parents:
diff changeset
319
kono
parents:
diff changeset
320 Append_To (Ins_List,
kono
parents:
diff changeset
321 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
322 Defining_Identifier => P2_Id,
kono
parents:
diff changeset
323 Object_Definition =>
kono
parents:
diff changeset
324 New_Occurrence_Of (Standard_Natural, Loc),
kono
parents:
diff changeset
325 Constant_Present => True,
kono
parents:
diff changeset
326 Expression =>
kono
parents:
diff changeset
327 Convert_To (Standard_Natural,
kono
parents:
diff changeset
328 Make_Indexed_Component (Loc,
kono
parents:
diff changeset
329 Prefix =>
kono
parents:
diff changeset
330 New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
kono
parents:
diff changeset
331 Expressions =>
kono
parents:
diff changeset
332 New_List (New_Occurrence_Of (P1_Id, Loc))))));
kono
parents:
diff changeset
333
kono
parents:
diff changeset
334 -- Compute the index of the next value, generating:
kono
parents:
diff changeset
335 -- P3 : constant Natural := call_put_enumN (P1 + 1);
kono
parents:
diff changeset
336
kono
parents:
diff changeset
337 declare
kono
parents:
diff changeset
338 Add_Node : constant Node_Id := New_Op_Node (N_Op_Add, Loc);
kono
parents:
diff changeset
339
kono
parents:
diff changeset
340 begin
kono
parents:
diff changeset
341 Set_Left_Opnd (Add_Node, New_Occurrence_Of (P1_Id, Loc));
kono
parents:
diff changeset
342 Set_Right_Opnd (Add_Node, Make_Integer_Literal (Loc, 1));
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 Append_To (Ins_List,
kono
parents:
diff changeset
345 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
346 Defining_Identifier => P3_Id,
kono
parents:
diff changeset
347 Object_Definition =>
kono
parents:
diff changeset
348 New_Occurrence_Of (Standard_Natural, Loc),
kono
parents:
diff changeset
349 Constant_Present => True,
kono
parents:
diff changeset
350 Expression =>
kono
parents:
diff changeset
351 Convert_To (Standard_Natural,
kono
parents:
diff changeset
352 Make_Indexed_Component (Loc,
kono
parents:
diff changeset
353 Prefix =>
kono
parents:
diff changeset
354 New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
kono
parents:
diff changeset
355 Expressions =>
kono
parents:
diff changeset
356 New_List (Add_Node)))));
kono
parents:
diff changeset
357 end;
kono
parents:
diff changeset
358
kono
parents:
diff changeset
359 -- Generate:
kono
parents:
diff changeset
360 -- S4 : String renames call_put_enumS (S2 .. S3 - 1);
kono
parents:
diff changeset
361
kono
parents:
diff changeset
362 declare
kono
parents:
diff changeset
363 Sub_Node : constant Node_Id := New_Op_Node (N_Op_Subtract, Loc);
kono
parents:
diff changeset
364
kono
parents:
diff changeset
365 begin
kono
parents:
diff changeset
366 Set_Left_Opnd (Sub_Node, New_Occurrence_Of (P3_Id, Loc));
kono
parents:
diff changeset
367 Set_Right_Opnd (Sub_Node, Make_Integer_Literal (Loc, 1));
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 Append_To (Ins_List,
kono
parents:
diff changeset
370 Make_Object_Renaming_Declaration (Loc,
kono
parents:
diff changeset
371 Defining_Identifier => P4_Id,
kono
parents:
diff changeset
372 Subtype_Mark =>
kono
parents:
diff changeset
373 New_Occurrence_Of (Standard_String, Loc),
kono
parents:
diff changeset
374 Name =>
kono
parents:
diff changeset
375 Make_Slice (Loc,
kono
parents:
diff changeset
376 Prefix =>
kono
parents:
diff changeset
377 New_Occurrence_Of (Lit_Strings (Rtyp), Loc),
kono
parents:
diff changeset
378 Discrete_Range =>
kono
parents:
diff changeset
379 Make_Range (Loc,
kono
parents:
diff changeset
380 Low_Bound => New_Occurrence_Of (P2_Id, Loc),
kono
parents:
diff changeset
381 High_Bound => Sub_Node))));
kono
parents:
diff changeset
382 end;
kono
parents:
diff changeset
383
kono
parents:
diff changeset
384 -- Generate:
kono
parents:
diff changeset
385 -- subtype S1 is string (1 .. P3 - P2);
kono
parents:
diff changeset
386
kono
parents:
diff changeset
387 declare
kono
parents:
diff changeset
388 HB : constant Node_Id := New_Op_Node (N_Op_Subtract, Loc);
kono
parents:
diff changeset
389
kono
parents:
diff changeset
390 begin
kono
parents:
diff changeset
391 Set_Left_Opnd (HB, New_Occurrence_Of (P3_Id, Loc));
kono
parents:
diff changeset
392 Set_Right_Opnd (HB, New_Occurrence_Of (P2_Id, Loc));
kono
parents:
diff changeset
393
kono
parents:
diff changeset
394 Append_To (Ins_List,
kono
parents:
diff changeset
395 Make_Subtype_Declaration (Loc,
kono
parents:
diff changeset
396 Defining_Identifier => S1_Id,
kono
parents:
diff changeset
397 Subtype_Indication =>
kono
parents:
diff changeset
398 Make_Subtype_Indication (Loc,
kono
parents:
diff changeset
399 Subtype_Mark =>
kono
parents:
diff changeset
400 New_Occurrence_Of (Standard_String, Loc),
kono
parents:
diff changeset
401 Constraint =>
kono
parents:
diff changeset
402 Make_Index_Or_Discriminant_Constraint (Loc,
kono
parents:
diff changeset
403 Constraints => New_List (
kono
parents:
diff changeset
404 Make_Range (Loc,
kono
parents:
diff changeset
405 Low_Bound => Make_Integer_Literal (Loc, 1),
kono
parents:
diff changeset
406 High_Bound => HB))))));
kono
parents:
diff changeset
407 end;
kono
parents:
diff changeset
408
kono
parents:
diff changeset
409 -- Insert all the above declarations before N. We suppress checks
kono
parents:
diff changeset
410 -- because everything is in range at this stage.
kono
parents:
diff changeset
411
kono
parents:
diff changeset
412 Insert_Actions (N, Ins_List, Suppress => All_Checks);
kono
parents:
diff changeset
413
kono
parents:
diff changeset
414 Rewrite (N,
kono
parents:
diff changeset
415 Unchecked_Convert_To (S1_Id, New_Occurrence_Of (P4_Id, Loc)));
kono
parents:
diff changeset
416
kono
parents:
diff changeset
417 Analyze_And_Resolve (N, Standard_String);
kono
parents:
diff changeset
418 end Expand_User_Defined_Enumeration_Image;
kono
parents:
diff changeset
419
kono
parents:
diff changeset
420 --------------------------------------
kono
parents:
diff changeset
421 -- Is_User_Defined_Enumeration_Type --
kono
parents:
diff changeset
422 --------------------------------------
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 function Is_User_Defined_Enumeration_Type
kono
parents:
diff changeset
425 (Typ : Entity_Id) return Boolean is
kono
parents:
diff changeset
426 begin
kono
parents:
diff changeset
427 return Ekind (Typ) = E_Enumeration_Type
kono
parents:
diff changeset
428 and then Typ /= Standard_Boolean
kono
parents:
diff changeset
429 and then Typ /= Standard_Character
kono
parents:
diff changeset
430 and then Typ /= Standard_Wide_Character
kono
parents:
diff changeset
431 and then Typ /= Standard_Wide_Wide_Character;
kono
parents:
diff changeset
432 end Is_User_Defined_Enumeration_Type;
kono
parents:
diff changeset
433
kono
parents:
diff changeset
434 -- Local variables
kono
parents:
diff changeset
435
kono
parents:
diff changeset
436 Imid : RE_Id;
kono
parents:
diff changeset
437 Ptyp : Entity_Id;
kono
parents:
diff changeset
438 Rtyp : Entity_Id;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
439 Tent : Entity_Id := Empty;
111
kono
parents:
diff changeset
440 Ttyp : Entity_Id;
kono
parents:
diff changeset
441 Proc_Ent : Entity_Id;
kono
parents:
diff changeset
442 Enum_Case : Boolean;
kono
parents:
diff changeset
443
kono
parents:
diff changeset
444 Arg_List : List_Id;
kono
parents:
diff changeset
445 -- List of arguments for run-time procedure call
kono
parents:
diff changeset
446
kono
parents:
diff changeset
447 Ins_List : List_Id;
kono
parents:
diff changeset
448 -- List of actions to be inserted
kono
parents:
diff changeset
449
kono
parents:
diff changeset
450 Snn : constant Entity_Id := Make_Temporary (Loc, 'S');
kono
parents:
diff changeset
451 Pnn : constant Entity_Id := Make_Temporary (Loc, 'P');
kono
parents:
diff changeset
452
kono
parents:
diff changeset
453 begin
kono
parents:
diff changeset
454 if Is_Object_Image (Pref) then
kono
parents:
diff changeset
455 Rewrite_Object_Image (N, Pref, Name_Image, Standard_String);
kono
parents:
diff changeset
456 return;
kono
parents:
diff changeset
457
kono
parents:
diff changeset
458 -- Enable speed-optimized expansion of user-defined enumeration types
kono
parents:
diff changeset
459 -- if we are compiling with optimizations enabled and enumeration type
kono
parents:
diff changeset
460 -- literals are generated. Otherwise the call will be expanded into a
kono
parents:
diff changeset
461 -- call to the runtime library.
kono
parents:
diff changeset
462
kono
parents:
diff changeset
463 elsif Optimization_Level > 0
kono
parents:
diff changeset
464 and then not Global_Discard_Names
kono
parents:
diff changeset
465 and then Is_User_Defined_Enumeration_Type (Root_Type (Entity (Pref)))
kono
parents:
diff changeset
466 then
kono
parents:
diff changeset
467 Expand_User_Defined_Enumeration_Image;
kono
parents:
diff changeset
468 return;
kono
parents:
diff changeset
469 end if;
kono
parents:
diff changeset
470
kono
parents:
diff changeset
471 Ptyp := Entity (Pref);
kono
parents:
diff changeset
472 Rtyp := Root_Type (Ptyp);
kono
parents:
diff changeset
473
kono
parents:
diff changeset
474 -- Build declarations of Snn and Pnn to be inserted
kono
parents:
diff changeset
475
kono
parents:
diff changeset
476 Ins_List := New_List (
kono
parents:
diff changeset
477
kono
parents:
diff changeset
478 -- Snn : String (1 .. typ'Width);
kono
parents:
diff changeset
479
kono
parents:
diff changeset
480 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
481 Defining_Identifier => Snn,
kono
parents:
diff changeset
482 Object_Definition =>
kono
parents:
diff changeset
483 Make_Subtype_Indication (Loc,
kono
parents:
diff changeset
484 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
kono
parents:
diff changeset
485 Constraint =>
kono
parents:
diff changeset
486 Make_Index_Or_Discriminant_Constraint (Loc,
kono
parents:
diff changeset
487 Constraints => New_List (
kono
parents:
diff changeset
488 Make_Range (Loc,
kono
parents:
diff changeset
489 Low_Bound => Make_Integer_Literal (Loc, 1),
kono
parents:
diff changeset
490 High_Bound =>
kono
parents:
diff changeset
491 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
492 Prefix => New_Occurrence_Of (Rtyp, Loc),
kono
parents:
diff changeset
493 Attribute_Name => Name_Width)))))),
kono
parents:
diff changeset
494
kono
parents:
diff changeset
495 -- Pnn : Natural;
kono
parents:
diff changeset
496
kono
parents:
diff changeset
497 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
498 Defining_Identifier => Pnn,
kono
parents:
diff changeset
499 Object_Definition => New_Occurrence_Of (Standard_Natural, Loc)));
kono
parents:
diff changeset
500
kono
parents:
diff changeset
501 -- Set Imid (RE_Id of procedure to call), and Tent, target for the
kono
parents:
diff changeset
502 -- type conversion of the first argument for all possibilities.
kono
parents:
diff changeset
503
kono
parents:
diff changeset
504 Enum_Case := False;
kono
parents:
diff changeset
505
kono
parents:
diff changeset
506 if Rtyp = Standard_Boolean then
kono
parents:
diff changeset
507 Imid := RE_Image_Boolean;
kono
parents:
diff changeset
508 Tent := Rtyp;
kono
parents:
diff changeset
509
kono
parents:
diff changeset
510 -- For standard character, we have to select the version which handles
kono
parents:
diff changeset
511 -- soft hyphen correctly, based on the version of Ada in use (this is
kono
parents:
diff changeset
512 -- ugly, but we have no choice).
kono
parents:
diff changeset
513
kono
parents:
diff changeset
514 elsif Rtyp = Standard_Character then
kono
parents:
diff changeset
515 if Ada_Version < Ada_2005 then
kono
parents:
diff changeset
516 Imid := RE_Image_Character;
kono
parents:
diff changeset
517 else
kono
parents:
diff changeset
518 Imid := RE_Image_Character_05;
kono
parents:
diff changeset
519 end if;
kono
parents:
diff changeset
520
kono
parents:
diff changeset
521 Tent := Rtyp;
kono
parents:
diff changeset
522
kono
parents:
diff changeset
523 elsif Rtyp = Standard_Wide_Character then
kono
parents:
diff changeset
524 Imid := RE_Image_Wide_Character;
kono
parents:
diff changeset
525 Tent := Rtyp;
kono
parents:
diff changeset
526
kono
parents:
diff changeset
527 elsif Rtyp = Standard_Wide_Wide_Character then
kono
parents:
diff changeset
528 Imid := RE_Image_Wide_Wide_Character;
kono
parents:
diff changeset
529 Tent := Rtyp;
kono
parents:
diff changeset
530
kono
parents:
diff changeset
531 elsif Is_Signed_Integer_Type (Rtyp) then
kono
parents:
diff changeset
532 if Esize (Rtyp) <= Esize (Standard_Integer) then
kono
parents:
diff changeset
533 Imid := RE_Image_Integer;
kono
parents:
diff changeset
534 Tent := Standard_Integer;
kono
parents:
diff changeset
535 else
kono
parents:
diff changeset
536 Imid := RE_Image_Long_Long_Integer;
kono
parents:
diff changeset
537 Tent := Standard_Long_Long_Integer;
kono
parents:
diff changeset
538 end if;
kono
parents:
diff changeset
539
kono
parents:
diff changeset
540 elsif Is_Modular_Integer_Type (Rtyp) then
kono
parents:
diff changeset
541 if Modulus (Rtyp) <= Modulus (RTE (RE_Unsigned)) then
kono
parents:
diff changeset
542 Imid := RE_Image_Unsigned;
kono
parents:
diff changeset
543 Tent := RTE (RE_Unsigned);
kono
parents:
diff changeset
544 else
kono
parents:
diff changeset
545 Imid := RE_Image_Long_Long_Unsigned;
kono
parents:
diff changeset
546 Tent := RTE (RE_Long_Long_Unsigned);
kono
parents:
diff changeset
547 end if;
kono
parents:
diff changeset
548
kono
parents:
diff changeset
549 elsif Is_Fixed_Point_Type (Rtyp) and then Has_Decimal_Small (Rtyp) then
kono
parents:
diff changeset
550 if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
kono
parents:
diff changeset
551 Imid := RE_Image_Decimal;
kono
parents:
diff changeset
552 Tent := Standard_Integer;
kono
parents:
diff changeset
553 else
kono
parents:
diff changeset
554 Imid := RE_Image_Long_Long_Decimal;
kono
parents:
diff changeset
555 Tent := Standard_Long_Long_Integer;
kono
parents:
diff changeset
556 end if;
kono
parents:
diff changeset
557
kono
parents:
diff changeset
558 elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
kono
parents:
diff changeset
559 Imid := RE_Image_Ordinary_Fixed_Point;
kono
parents:
diff changeset
560 Tent := Standard_Long_Long_Float;
kono
parents:
diff changeset
561
kono
parents:
diff changeset
562 elsif Is_Floating_Point_Type (Rtyp) then
kono
parents:
diff changeset
563 Imid := RE_Image_Floating_Point;
kono
parents:
diff changeset
564 Tent := Standard_Long_Long_Float;
kono
parents:
diff changeset
565
kono
parents:
diff changeset
566 -- Only other possibility is user-defined enumeration type
kono
parents:
diff changeset
567
kono
parents:
diff changeset
568 else
kono
parents:
diff changeset
569 if Discard_Names (First_Subtype (Ptyp))
kono
parents:
diff changeset
570 or else No (Lit_Strings (Root_Type (Ptyp)))
kono
parents:
diff changeset
571 then
kono
parents:
diff changeset
572 -- When pragma Discard_Names applies to the first subtype, build
kono
parents:
diff changeset
573 -- (Pref'Pos (Expr))'Img.
kono
parents:
diff changeset
574
kono
parents:
diff changeset
575 Rewrite (N,
kono
parents:
diff changeset
576 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
577 Prefix =>
kono
parents:
diff changeset
578 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
579 Prefix => Pref,
kono
parents:
diff changeset
580 Attribute_Name => Name_Pos,
kono
parents:
diff changeset
581 Expressions => New_List (Expr)),
kono
parents:
diff changeset
582 Attribute_Name =>
kono
parents:
diff changeset
583 Name_Img));
kono
parents:
diff changeset
584 Analyze_And_Resolve (N, Standard_String);
kono
parents:
diff changeset
585 return;
kono
parents:
diff changeset
586
kono
parents:
diff changeset
587 else
kono
parents:
diff changeset
588 -- Here for enumeration type case
kono
parents:
diff changeset
589
kono
parents:
diff changeset
590 Ttyp := Component_Type (Etype (Lit_Indexes (Rtyp)));
kono
parents:
diff changeset
591
kono
parents:
diff changeset
592 if Ttyp = Standard_Integer_8 then
kono
parents:
diff changeset
593 Imid := RE_Image_Enumeration_8;
kono
parents:
diff changeset
594
kono
parents:
diff changeset
595 elsif Ttyp = Standard_Integer_16 then
kono
parents:
diff changeset
596 Imid := RE_Image_Enumeration_16;
kono
parents:
diff changeset
597
kono
parents:
diff changeset
598 else
kono
parents:
diff changeset
599 Imid := RE_Image_Enumeration_32;
kono
parents:
diff changeset
600 end if;
kono
parents:
diff changeset
601
kono
parents:
diff changeset
602 -- Apply a validity check, since it is a bit drastic to get a
kono
parents:
diff changeset
603 -- completely junk image value for an invalid value.
kono
parents:
diff changeset
604
kono
parents:
diff changeset
605 if not Expr_Known_Valid (Expr) then
kono
parents:
diff changeset
606 Insert_Valid_Check (Expr);
kono
parents:
diff changeset
607 end if;
kono
parents:
diff changeset
608
kono
parents:
diff changeset
609 Enum_Case := True;
kono
parents:
diff changeset
610 end if;
kono
parents:
diff changeset
611 end if;
kono
parents:
diff changeset
612
kono
parents:
diff changeset
613 -- Build first argument for call
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 if Enum_Case then
kono
parents:
diff changeset
616 Arg_List := New_List (
kono
parents:
diff changeset
617 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
618 Attribute_Name => Name_Pos,
kono
parents:
diff changeset
619 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
620 Expressions => New_List (Expr)));
kono
parents:
diff changeset
621
kono
parents:
diff changeset
622 else
kono
parents:
diff changeset
623 Arg_List := New_List (Convert_To (Tent, Expr));
kono
parents:
diff changeset
624 end if;
kono
parents:
diff changeset
625
kono
parents:
diff changeset
626 -- Append Snn, Pnn arguments
kono
parents:
diff changeset
627
kono
parents:
diff changeset
628 Append_To (Arg_List, New_Occurrence_Of (Snn, Loc));
kono
parents:
diff changeset
629 Append_To (Arg_List, New_Occurrence_Of (Pnn, Loc));
kono
parents:
diff changeset
630
kono
parents:
diff changeset
631 -- Get entity of procedure to call
kono
parents:
diff changeset
632
kono
parents:
diff changeset
633 Proc_Ent := RTE (Imid);
kono
parents:
diff changeset
634
kono
parents:
diff changeset
635 -- If the procedure entity is empty, that means we have a case in
kono
parents:
diff changeset
636 -- no run time mode where the operation is not allowed, and an
kono
parents:
diff changeset
637 -- appropriate diagnostic has already been issued.
kono
parents:
diff changeset
638
kono
parents:
diff changeset
639 if No (Proc_Ent) then
kono
parents:
diff changeset
640 return;
kono
parents:
diff changeset
641 end if;
kono
parents:
diff changeset
642
kono
parents:
diff changeset
643 -- Otherwise complete preparation of arguments for run-time call
kono
parents:
diff changeset
644
kono
parents:
diff changeset
645 -- Add extra arguments for Enumeration case
kono
parents:
diff changeset
646
kono
parents:
diff changeset
647 if Enum_Case then
kono
parents:
diff changeset
648 Append_To (Arg_List, New_Occurrence_Of (Lit_Strings (Rtyp), Loc));
kono
parents:
diff changeset
649 Append_To (Arg_List,
kono
parents:
diff changeset
650 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
651 Prefix => New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
kono
parents:
diff changeset
652 Attribute_Name => Name_Address));
kono
parents:
diff changeset
653
kono
parents:
diff changeset
654 -- For floating-point types, append Digits argument
kono
parents:
diff changeset
655
kono
parents:
diff changeset
656 elsif Is_Floating_Point_Type (Rtyp) then
kono
parents:
diff changeset
657 Append_To (Arg_List,
kono
parents:
diff changeset
658 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
659 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
660 Attribute_Name => Name_Digits));
kono
parents:
diff changeset
661
kono
parents:
diff changeset
662 -- For ordinary fixed-point types, append Aft parameter
kono
parents:
diff changeset
663
kono
parents:
diff changeset
664 elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
kono
parents:
diff changeset
665 Append_To (Arg_List,
kono
parents:
diff changeset
666 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
667 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
668 Attribute_Name => Name_Aft));
kono
parents:
diff changeset
669
kono
parents:
diff changeset
670 if Has_Decimal_Small (Rtyp) then
kono
parents:
diff changeset
671 Set_Conversion_OK (First (Arg_List));
kono
parents:
diff changeset
672 Set_Etype (First (Arg_List), Tent);
kono
parents:
diff changeset
673 end if;
kono
parents:
diff changeset
674
kono
parents:
diff changeset
675 -- For decimal, append Scale and also set to do literal conversion
kono
parents:
diff changeset
676
kono
parents:
diff changeset
677 elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
kono
parents:
diff changeset
678 Append_To (Arg_List,
kono
parents:
diff changeset
679 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
680 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
681 Attribute_Name => Name_Scale));
kono
parents:
diff changeset
682
kono
parents:
diff changeset
683 Set_Conversion_OK (First (Arg_List));
kono
parents:
diff changeset
684 Set_Etype (First (Arg_List), Tent);
kono
parents:
diff changeset
685
kono
parents:
diff changeset
686 -- For Wide_Character, append Ada 2005 indication
kono
parents:
diff changeset
687
kono
parents:
diff changeset
688 elsif Rtyp = Standard_Wide_Character then
kono
parents:
diff changeset
689 Append_To (Arg_List,
kono
parents:
diff changeset
690 New_Occurrence_Of
kono
parents:
diff changeset
691 (Boolean_Literals (Ada_Version >= Ada_2005), Loc));
kono
parents:
diff changeset
692 end if;
kono
parents:
diff changeset
693
kono
parents:
diff changeset
694 -- Now append the procedure call to the insert list
kono
parents:
diff changeset
695
kono
parents:
diff changeset
696 Append_To (Ins_List,
kono
parents:
diff changeset
697 Make_Procedure_Call_Statement (Loc,
kono
parents:
diff changeset
698 Name => New_Occurrence_Of (Proc_Ent, Loc),
kono
parents:
diff changeset
699 Parameter_Associations => Arg_List));
kono
parents:
diff changeset
700
kono
parents:
diff changeset
701 -- Insert declarations of Snn, Pnn, and the procedure call. We suppress
kono
parents:
diff changeset
702 -- checks because we are sure that everything is in range at this stage.
kono
parents:
diff changeset
703
kono
parents:
diff changeset
704 Insert_Actions (N, Ins_List, Suppress => All_Checks);
kono
parents:
diff changeset
705
kono
parents:
diff changeset
706 -- Final step is to rewrite the expression as a slice and analyze,
kono
parents:
diff changeset
707 -- again with no checks, since we are sure that everything is OK.
kono
parents:
diff changeset
708
kono
parents:
diff changeset
709 Rewrite (N,
kono
parents:
diff changeset
710 Make_Slice (Loc,
kono
parents:
diff changeset
711 Prefix => New_Occurrence_Of (Snn, Loc),
kono
parents:
diff changeset
712 Discrete_Range =>
kono
parents:
diff changeset
713 Make_Range (Loc,
kono
parents:
diff changeset
714 Low_Bound => Make_Integer_Literal (Loc, 1),
kono
parents:
diff changeset
715 High_Bound => New_Occurrence_Of (Pnn, Loc))));
kono
parents:
diff changeset
716
kono
parents:
diff changeset
717 Analyze_And_Resolve (N, Standard_String, Suppress => All_Checks);
kono
parents:
diff changeset
718 end Expand_Image_Attribute;
kono
parents:
diff changeset
719
kono
parents:
diff changeset
720 ----------------------------
kono
parents:
diff changeset
721 -- Expand_Value_Attribute --
kono
parents:
diff changeset
722 ----------------------------
kono
parents:
diff changeset
723
kono
parents:
diff changeset
724 -- For scalar types derived from Boolean, Character and integer types
kono
parents:
diff changeset
725 -- in package Standard, typ'Value (X) expands into:
kono
parents:
diff changeset
726
kono
parents:
diff changeset
727 -- btyp (Value_xx (X))
kono
parents:
diff changeset
728
kono
parents:
diff changeset
729 -- where btyp is he base type of the prefix
kono
parents:
diff changeset
730
kono
parents:
diff changeset
731 -- For types whose root type is Character
kono
parents:
diff changeset
732 -- xx = Character
kono
parents:
diff changeset
733
kono
parents:
diff changeset
734 -- For types whose root type is Wide_Character
kono
parents:
diff changeset
735 -- xx = Wide_Character
kono
parents:
diff changeset
736
kono
parents:
diff changeset
737 -- For types whose root type is Wide_Wide_Character
kono
parents:
diff changeset
738 -- xx = Wide_Wide_Character
kono
parents:
diff changeset
739
kono
parents:
diff changeset
740 -- For types whose root type is Boolean
kono
parents:
diff changeset
741 -- xx = Boolean
kono
parents:
diff changeset
742
kono
parents:
diff changeset
743 -- For signed integer types with size <= Integer'Size
kono
parents:
diff changeset
744 -- xx = Integer
kono
parents:
diff changeset
745
kono
parents:
diff changeset
746 -- For other signed integer types
kono
parents:
diff changeset
747 -- xx = Long_Long_Integer
kono
parents:
diff changeset
748
kono
parents:
diff changeset
749 -- For modular types with modulus <= System.Unsigned_Types.Unsigned
kono
parents:
diff changeset
750 -- xx = Unsigned
kono
parents:
diff changeset
751
kono
parents:
diff changeset
752 -- For other modular integer types
kono
parents:
diff changeset
753 -- xx = Long_Long_Unsigned
kono
parents:
diff changeset
754
kono
parents:
diff changeset
755 -- For floating-point types and ordinary fixed-point types
kono
parents:
diff changeset
756 -- xx = Real
kono
parents:
diff changeset
757
kono
parents:
diff changeset
758 -- For Wide_[Wide_]Character types, typ'Value (X) expands into:
kono
parents:
diff changeset
759
kono
parents:
diff changeset
760 -- btyp (Value_xx (X, EM))
kono
parents:
diff changeset
761
kono
parents:
diff changeset
762 -- where btyp is the base type of the prefix, and EM is the encoding method
kono
parents:
diff changeset
763
kono
parents:
diff changeset
764 -- For decimal types with size <= Integer'Size, typ'Value (X)
kono
parents:
diff changeset
765 -- expands into
kono
parents:
diff changeset
766
kono
parents:
diff changeset
767 -- btyp?(Value_Decimal (X, typ'Scale));
kono
parents:
diff changeset
768
kono
parents:
diff changeset
769 -- For all other decimal types, typ'Value (X) expands into
kono
parents:
diff changeset
770
kono
parents:
diff changeset
771 -- btyp?(Value_Long_Long_Decimal (X, typ'Scale))
kono
parents:
diff changeset
772
kono
parents:
diff changeset
773 -- For enumeration types other than those derived from types Boolean,
kono
parents:
diff changeset
774 -- Character, Wide_[Wide_]Character in Standard, typ'Value (X) expands to:
kono
parents:
diff changeset
775
kono
parents:
diff changeset
776 -- Enum'Val (Value_Enumeration_NN (typS, typI'Address, Num, X))
kono
parents:
diff changeset
777
kono
parents:
diff changeset
778 -- where typS and typI and the Lit_Strings and Lit_Indexes entities
kono
parents:
diff changeset
779 -- from T's root type entity, and Num is Enum'Pos (Enum'Last). The
kono
parents:
diff changeset
780 -- Value_Enumeration_NN function will search the tables looking for
kono
parents:
diff changeset
781 -- X and return the position number in the table if found which is
kono
parents:
diff changeset
782 -- used to provide the result of 'Value (using Enum'Val). If the
kono
parents:
diff changeset
783 -- value is not found Constraint_Error is raised. The suffix _NN
kono
parents:
diff changeset
784 -- depends on the element type of typI.
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 procedure Expand_Value_Attribute (N : Node_Id) is
kono
parents:
diff changeset
787 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
788 Typ : constant Entity_Id := Etype (N);
kono
parents:
diff changeset
789 Btyp : constant Entity_Id := Base_Type (Typ);
kono
parents:
diff changeset
790 Rtyp : constant Entity_Id := Root_Type (Typ);
kono
parents:
diff changeset
791 Exprs : constant List_Id := Expressions (N);
kono
parents:
diff changeset
792 Vid : RE_Id;
kono
parents:
diff changeset
793 Args : List_Id;
kono
parents:
diff changeset
794 Func : RE_Id;
kono
parents:
diff changeset
795 Ttyp : Entity_Id;
kono
parents:
diff changeset
796
kono
parents:
diff changeset
797 begin
kono
parents:
diff changeset
798 Args := Exprs;
kono
parents:
diff changeset
799
kono
parents:
diff changeset
800 if Rtyp = Standard_Character then
kono
parents:
diff changeset
801 Vid := RE_Value_Character;
kono
parents:
diff changeset
802
kono
parents:
diff changeset
803 elsif Rtyp = Standard_Boolean then
kono
parents:
diff changeset
804 Vid := RE_Value_Boolean;
kono
parents:
diff changeset
805
kono
parents:
diff changeset
806 elsif Rtyp = Standard_Wide_Character then
kono
parents:
diff changeset
807 Vid := RE_Value_Wide_Character;
kono
parents:
diff changeset
808
kono
parents:
diff changeset
809 Append_To (Args,
kono
parents:
diff changeset
810 Make_Integer_Literal (Loc,
kono
parents:
diff changeset
811 Intval => Int (Wide_Character_Encoding_Method)));
kono
parents:
diff changeset
812
kono
parents:
diff changeset
813 elsif Rtyp = Standard_Wide_Wide_Character then
kono
parents:
diff changeset
814 Vid := RE_Value_Wide_Wide_Character;
kono
parents:
diff changeset
815
kono
parents:
diff changeset
816 Append_To (Args,
kono
parents:
diff changeset
817 Make_Integer_Literal (Loc,
kono
parents:
diff changeset
818 Intval => Int (Wide_Character_Encoding_Method)));
kono
parents:
diff changeset
819
kono
parents:
diff changeset
820 elsif Rtyp = Base_Type (Standard_Short_Short_Integer)
kono
parents:
diff changeset
821 or else Rtyp = Base_Type (Standard_Short_Integer)
kono
parents:
diff changeset
822 or else Rtyp = Base_Type (Standard_Integer)
kono
parents:
diff changeset
823 then
kono
parents:
diff changeset
824 Vid := RE_Value_Integer;
kono
parents:
diff changeset
825
kono
parents:
diff changeset
826 elsif Is_Signed_Integer_Type (Rtyp) then
kono
parents:
diff changeset
827 Vid := RE_Value_Long_Long_Integer;
kono
parents:
diff changeset
828
kono
parents:
diff changeset
829 elsif Is_Modular_Integer_Type (Rtyp) then
kono
parents:
diff changeset
830 if Modulus (Rtyp) <= Modulus (RTE (RE_Unsigned)) then
kono
parents:
diff changeset
831 Vid := RE_Value_Unsigned;
kono
parents:
diff changeset
832 else
kono
parents:
diff changeset
833 Vid := RE_Value_Long_Long_Unsigned;
kono
parents:
diff changeset
834 end if;
kono
parents:
diff changeset
835
kono
parents:
diff changeset
836 elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
kono
parents:
diff changeset
837 if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
kono
parents:
diff changeset
838 Vid := RE_Value_Decimal;
kono
parents:
diff changeset
839 else
kono
parents:
diff changeset
840 Vid := RE_Value_Long_Long_Decimal;
kono
parents:
diff changeset
841 end if;
kono
parents:
diff changeset
842
kono
parents:
diff changeset
843 Append_To (Args,
kono
parents:
diff changeset
844 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
845 Prefix => New_Occurrence_Of (Typ, Loc),
kono
parents:
diff changeset
846 Attribute_Name => Name_Scale));
kono
parents:
diff changeset
847
kono
parents:
diff changeset
848 Rewrite (N,
kono
parents:
diff changeset
849 OK_Convert_To (Btyp,
kono
parents:
diff changeset
850 Make_Function_Call (Loc,
kono
parents:
diff changeset
851 Name => New_Occurrence_Of (RTE (Vid), Loc),
kono
parents:
diff changeset
852 Parameter_Associations => Args)));
kono
parents:
diff changeset
853
kono
parents:
diff changeset
854 Set_Etype (N, Btyp);
kono
parents:
diff changeset
855 Analyze_And_Resolve (N, Btyp);
kono
parents:
diff changeset
856 return;
kono
parents:
diff changeset
857
kono
parents:
diff changeset
858 elsif Is_Real_Type (Rtyp) then
kono
parents:
diff changeset
859 Vid := RE_Value_Real;
kono
parents:
diff changeset
860
kono
parents:
diff changeset
861 -- Only other possibility is user-defined enumeration type
kono
parents:
diff changeset
862
kono
parents:
diff changeset
863 else
kono
parents:
diff changeset
864 pragma Assert (Is_Enumeration_Type (Rtyp));
kono
parents:
diff changeset
865
kono
parents:
diff changeset
866 -- Case of pragma Discard_Names, transform the Value
kono
parents:
diff changeset
867 -- attribute to Btyp'Val (Long_Long_Integer'Value (Args))
kono
parents:
diff changeset
868
kono
parents:
diff changeset
869 if Discard_Names (First_Subtype (Typ))
kono
parents:
diff changeset
870 or else No (Lit_Strings (Rtyp))
kono
parents:
diff changeset
871 then
kono
parents:
diff changeset
872 Rewrite (N,
kono
parents:
diff changeset
873 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
874 Prefix => New_Occurrence_Of (Btyp, Loc),
kono
parents:
diff changeset
875 Attribute_Name => Name_Val,
kono
parents:
diff changeset
876 Expressions => New_List (
kono
parents:
diff changeset
877 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
878 Prefix =>
kono
parents:
diff changeset
879 New_Occurrence_Of (Standard_Long_Long_Integer, Loc),
kono
parents:
diff changeset
880 Attribute_Name => Name_Value,
kono
parents:
diff changeset
881 Expressions => Args))));
kono
parents:
diff changeset
882
kono
parents:
diff changeset
883 Analyze_And_Resolve (N, Btyp);
kono
parents:
diff changeset
884
kono
parents:
diff changeset
885 -- Here for normal case where we have enumeration tables, this
kono
parents:
diff changeset
886 -- is where we build
kono
parents:
diff changeset
887
kono
parents:
diff changeset
888 -- T'Val (Value_Enumeration_NN (typS, typI'Address, Num, X))
kono
parents:
diff changeset
889
kono
parents:
diff changeset
890 else
kono
parents:
diff changeset
891 Ttyp := Component_Type (Etype (Lit_Indexes (Rtyp)));
kono
parents:
diff changeset
892
kono
parents:
diff changeset
893 if Ttyp = Standard_Integer_8 then
kono
parents:
diff changeset
894 Func := RE_Value_Enumeration_8;
kono
parents:
diff changeset
895 elsif Ttyp = Standard_Integer_16 then
kono
parents:
diff changeset
896 Func := RE_Value_Enumeration_16;
kono
parents:
diff changeset
897 else
kono
parents:
diff changeset
898 Func := RE_Value_Enumeration_32;
kono
parents:
diff changeset
899 end if;
kono
parents:
diff changeset
900
kono
parents:
diff changeset
901 Prepend_To (Args,
kono
parents:
diff changeset
902 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
903 Prefix => New_Occurrence_Of (Rtyp, Loc),
kono
parents:
diff changeset
904 Attribute_Name => Name_Pos,
kono
parents:
diff changeset
905 Expressions => New_List (
kono
parents:
diff changeset
906 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
907 Prefix => New_Occurrence_Of (Rtyp, Loc),
kono
parents:
diff changeset
908 Attribute_Name => Name_Last))));
kono
parents:
diff changeset
909
kono
parents:
diff changeset
910 Prepend_To (Args,
kono
parents:
diff changeset
911 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
912 Prefix => New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
kono
parents:
diff changeset
913 Attribute_Name => Name_Address));
kono
parents:
diff changeset
914
kono
parents:
diff changeset
915 Prepend_To (Args,
kono
parents:
diff changeset
916 New_Occurrence_Of (Lit_Strings (Rtyp), Loc));
kono
parents:
diff changeset
917
kono
parents:
diff changeset
918 Rewrite (N,
kono
parents:
diff changeset
919 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
920 Prefix => New_Occurrence_Of (Typ, Loc),
kono
parents:
diff changeset
921 Attribute_Name => Name_Val,
kono
parents:
diff changeset
922 Expressions => New_List (
kono
parents:
diff changeset
923 Make_Function_Call (Loc,
kono
parents:
diff changeset
924 Name =>
kono
parents:
diff changeset
925 New_Occurrence_Of (RTE (Func), Loc),
kono
parents:
diff changeset
926 Parameter_Associations => Args))));
kono
parents:
diff changeset
927
kono
parents:
diff changeset
928 Analyze_And_Resolve (N, Btyp);
kono
parents:
diff changeset
929 end if;
kono
parents:
diff changeset
930
kono
parents:
diff changeset
931 return;
kono
parents:
diff changeset
932 end if;
kono
parents:
diff changeset
933
kono
parents:
diff changeset
934 -- Fall through for all cases except user-defined enumeration type
kono
parents:
diff changeset
935 -- and decimal types, with Vid set to the Id of the entity for the
kono
parents:
diff changeset
936 -- Value routine and Args set to the list of parameters for the call.
kono
parents:
diff changeset
937
kono
parents:
diff changeset
938 -- Compiling package Ada.Tags under No_Run_Time_Mode we disable the
kono
parents:
diff changeset
939 -- expansion of the attribute into the function call statement to avoid
kono
parents:
diff changeset
940 -- generating spurious errors caused by the use of Integer_Address'Value
kono
parents:
diff changeset
941 -- in our implementation of Ada.Tags.Internal_Tag
kono
parents:
diff changeset
942
kono
parents:
diff changeset
943 -- Seems like a bit of a odd approach, there should be a better way ???
kono
parents:
diff changeset
944
kono
parents:
diff changeset
945 -- There is a better way, test RTE_Available ???
kono
parents:
diff changeset
946
kono
parents:
diff changeset
947 if No_Run_Time_Mode
kono
parents:
diff changeset
948 and then Rtyp = RTE (RE_Integer_Address)
kono
parents:
diff changeset
949 and then RTU_Loaded (Ada_Tags)
kono
parents:
diff changeset
950 and then Cunit_Entity (Current_Sem_Unit)
kono
parents:
diff changeset
951 = Body_Entity (RTU_Entity (Ada_Tags))
kono
parents:
diff changeset
952 then
kono
parents:
diff changeset
953 Rewrite (N,
kono
parents:
diff changeset
954 Unchecked_Convert_To (Rtyp,
kono
parents:
diff changeset
955 Make_Integer_Literal (Loc, Uint_0)));
kono
parents:
diff changeset
956 else
kono
parents:
diff changeset
957 Rewrite (N,
kono
parents:
diff changeset
958 Convert_To (Btyp,
kono
parents:
diff changeset
959 Make_Function_Call (Loc,
kono
parents:
diff changeset
960 Name => New_Occurrence_Of (RTE (Vid), Loc),
kono
parents:
diff changeset
961 Parameter_Associations => Args)));
kono
parents:
diff changeset
962 end if;
kono
parents:
diff changeset
963
kono
parents:
diff changeset
964 Analyze_And_Resolve (N, Btyp);
kono
parents:
diff changeset
965 end Expand_Value_Attribute;
kono
parents:
diff changeset
966
kono
parents:
diff changeset
967 ---------------------------------
kono
parents:
diff changeset
968 -- Expand_Wide_Image_Attribute --
kono
parents:
diff changeset
969 ---------------------------------
kono
parents:
diff changeset
970
kono
parents:
diff changeset
971 -- We expand typ'Wide_Image (X) as follows. First we insert this code:
kono
parents:
diff changeset
972
kono
parents:
diff changeset
973 -- Rnn : Wide_String (1 .. rt'Wide_Width);
kono
parents:
diff changeset
974 -- Lnn : Natural;
kono
parents:
diff changeset
975 -- String_To_Wide_String
kono
parents:
diff changeset
976 -- (typ'Image (Expr), Rnn, Lnn, Wide_Character_Encoding_Method);
kono
parents:
diff changeset
977
kono
parents:
diff changeset
978 -- where rt is the root type of the prefix type
kono
parents:
diff changeset
979
kono
parents:
diff changeset
980 -- Now we replace the Wide_Image reference by
kono
parents:
diff changeset
981
kono
parents:
diff changeset
982 -- Rnn (1 .. Lnn)
kono
parents:
diff changeset
983
kono
parents:
diff changeset
984 -- This works in all cases because String_To_Wide_String converts any
kono
parents:
diff changeset
985 -- wide character escape sequences resulting from the Image call to the
kono
parents:
diff changeset
986 -- proper Wide_Character equivalent
kono
parents:
diff changeset
987
kono
parents:
diff changeset
988 -- not quite right for typ = Wide_Character ???
kono
parents:
diff changeset
989
kono
parents:
diff changeset
990 procedure Expand_Wide_Image_Attribute (N : Node_Id) is
kono
parents:
diff changeset
991 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
992 Pref : constant Entity_Id := Prefix (N);
kono
parents:
diff changeset
993 Rnn : constant Entity_Id := Make_Temporary (Loc, 'S');
kono
parents:
diff changeset
994 Lnn : constant Entity_Id := Make_Temporary (Loc, 'P');
kono
parents:
diff changeset
995 Rtyp : Entity_Id;
kono
parents:
diff changeset
996
kono
parents:
diff changeset
997 begin
kono
parents:
diff changeset
998 if Is_Object_Image (Pref) then
kono
parents:
diff changeset
999 Rewrite_Object_Image (N, Pref, Name_Wide_Image, Standard_Wide_String);
kono
parents:
diff changeset
1000 return;
kono
parents:
diff changeset
1001 end if;
kono
parents:
diff changeset
1002
kono
parents:
diff changeset
1003 Rtyp := Root_Type (Entity (Pref));
kono
parents:
diff changeset
1004
kono
parents:
diff changeset
1005 Insert_Actions (N, New_List (
kono
parents:
diff changeset
1006
kono
parents:
diff changeset
1007 -- Rnn : Wide_String (1 .. base_typ'Width);
kono
parents:
diff changeset
1008
kono
parents:
diff changeset
1009 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
1010 Defining_Identifier => Rnn,
kono
parents:
diff changeset
1011 Object_Definition =>
kono
parents:
diff changeset
1012 Make_Subtype_Indication (Loc,
kono
parents:
diff changeset
1013 Subtype_Mark =>
kono
parents:
diff changeset
1014 New_Occurrence_Of (Standard_Wide_String, Loc),
kono
parents:
diff changeset
1015 Constraint =>
kono
parents:
diff changeset
1016 Make_Index_Or_Discriminant_Constraint (Loc,
kono
parents:
diff changeset
1017 Constraints => New_List (
kono
parents:
diff changeset
1018 Make_Range (Loc,
kono
parents:
diff changeset
1019 Low_Bound => Make_Integer_Literal (Loc, 1),
kono
parents:
diff changeset
1020 High_Bound =>
kono
parents:
diff changeset
1021 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1022 Prefix => New_Occurrence_Of (Rtyp, Loc),
kono
parents:
diff changeset
1023 Attribute_Name => Name_Wide_Width)))))),
kono
parents:
diff changeset
1024
kono
parents:
diff changeset
1025 -- Lnn : Natural;
kono
parents:
diff changeset
1026
kono
parents:
diff changeset
1027 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
1028 Defining_Identifier => Lnn,
kono
parents:
diff changeset
1029 Object_Definition => New_Occurrence_Of (Standard_Natural, Loc)),
kono
parents:
diff changeset
1030
kono
parents:
diff changeset
1031 -- String_To_Wide_String
kono
parents:
diff changeset
1032 -- (typ'Image (X), Rnn, Lnn, Wide_Character_Encoding_Method);
kono
parents:
diff changeset
1033
kono
parents:
diff changeset
1034 Make_Procedure_Call_Statement (Loc,
kono
parents:
diff changeset
1035 Name =>
kono
parents:
diff changeset
1036 New_Occurrence_Of (RTE (RE_String_To_Wide_String), Loc),
kono
parents:
diff changeset
1037
kono
parents:
diff changeset
1038 Parameter_Associations => New_List (
kono
parents:
diff changeset
1039 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1040 Prefix => Prefix (N),
kono
parents:
diff changeset
1041 Attribute_Name => Name_Image,
kono
parents:
diff changeset
1042 Expressions => Expressions (N)),
kono
parents:
diff changeset
1043 New_Occurrence_Of (Rnn, Loc),
kono
parents:
diff changeset
1044 New_Occurrence_Of (Lnn, Loc),
kono
parents:
diff changeset
1045 Make_Integer_Literal (Loc,
kono
parents:
diff changeset
1046 Intval => Int (Wide_Character_Encoding_Method))))),
kono
parents:
diff changeset
1047
kono
parents:
diff changeset
1048 -- Suppress checks because we know everything is properly in range
kono
parents:
diff changeset
1049
kono
parents:
diff changeset
1050 Suppress => All_Checks);
kono
parents:
diff changeset
1051
kono
parents:
diff changeset
1052 -- Final step is to rewrite the expression as a slice and analyze,
kono
parents:
diff changeset
1053 -- again with no checks, since we are sure that everything is OK.
kono
parents:
diff changeset
1054
kono
parents:
diff changeset
1055 Rewrite (N,
kono
parents:
diff changeset
1056 Make_Slice (Loc,
kono
parents:
diff changeset
1057 Prefix => New_Occurrence_Of (Rnn, Loc),
kono
parents:
diff changeset
1058 Discrete_Range =>
kono
parents:
diff changeset
1059 Make_Range (Loc,
kono
parents:
diff changeset
1060 Low_Bound => Make_Integer_Literal (Loc, 1),
kono
parents:
diff changeset
1061 High_Bound => New_Occurrence_Of (Lnn, Loc))));
kono
parents:
diff changeset
1062
kono
parents:
diff changeset
1063 Analyze_And_Resolve (N, Standard_Wide_String, Suppress => All_Checks);
kono
parents:
diff changeset
1064 end Expand_Wide_Image_Attribute;
kono
parents:
diff changeset
1065
kono
parents:
diff changeset
1066 --------------------------------------
kono
parents:
diff changeset
1067 -- Expand_Wide_Wide_Image_Attribute --
kono
parents:
diff changeset
1068 --------------------------------------
kono
parents:
diff changeset
1069
kono
parents:
diff changeset
1070 -- We expand typ'Wide_Wide_Image (X) as follows. First we insert this code:
kono
parents:
diff changeset
1071
kono
parents:
diff changeset
1072 -- Rnn : Wide_Wide_String (1 .. rt'Wide_Wide_Width);
kono
parents:
diff changeset
1073 -- Lnn : Natural;
kono
parents:
diff changeset
1074 -- String_To_Wide_Wide_String
kono
parents:
diff changeset
1075 -- (typ'Image (Expr), Rnn, Lnn, Wide_Character_Encoding_Method);
kono
parents:
diff changeset
1076
kono
parents:
diff changeset
1077 -- where rt is the root type of the prefix type
kono
parents:
diff changeset
1078
kono
parents:
diff changeset
1079 -- Now we replace the Wide_Wide_Image reference by
kono
parents:
diff changeset
1080
kono
parents:
diff changeset
1081 -- Rnn (1 .. Lnn)
kono
parents:
diff changeset
1082
kono
parents:
diff changeset
1083 -- This works in all cases because String_To_Wide_Wide_String converts any
kono
parents:
diff changeset
1084 -- wide character escape sequences resulting from the Image call to the
kono
parents:
diff changeset
1085 -- proper Wide_Wide_Character equivalent
kono
parents:
diff changeset
1086
kono
parents:
diff changeset
1087 -- not quite right for typ = Wide_Wide_Character ???
kono
parents:
diff changeset
1088
kono
parents:
diff changeset
1089 procedure Expand_Wide_Wide_Image_Attribute (N : Node_Id) is
kono
parents:
diff changeset
1090 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
1091 Pref : constant Entity_Id := Prefix (N);
kono
parents:
diff changeset
1092 Rnn : constant Entity_Id := Make_Temporary (Loc, 'S');
kono
parents:
diff changeset
1093 Lnn : constant Entity_Id := Make_Temporary (Loc, 'P');
kono
parents:
diff changeset
1094 Rtyp : Entity_Id;
kono
parents:
diff changeset
1095
kono
parents:
diff changeset
1096 begin
kono
parents:
diff changeset
1097 if Is_Object_Image (Pref) then
kono
parents:
diff changeset
1098 Rewrite_Object_Image
kono
parents:
diff changeset
1099 (N, Pref, Name_Wide_Wide_Image, Standard_Wide_Wide_String);
kono
parents:
diff changeset
1100 return;
kono
parents:
diff changeset
1101 end if;
kono
parents:
diff changeset
1102
kono
parents:
diff changeset
1103 Rtyp := Root_Type (Entity (Pref));
kono
parents:
diff changeset
1104
kono
parents:
diff changeset
1105 Insert_Actions (N, New_List (
kono
parents:
diff changeset
1106
kono
parents:
diff changeset
1107 -- Rnn : Wide_Wide_String (1 .. rt'Wide_Wide_Width);
kono
parents:
diff changeset
1108
kono
parents:
diff changeset
1109 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
1110 Defining_Identifier => Rnn,
kono
parents:
diff changeset
1111 Object_Definition =>
kono
parents:
diff changeset
1112 Make_Subtype_Indication (Loc,
kono
parents:
diff changeset
1113 Subtype_Mark =>
kono
parents:
diff changeset
1114 New_Occurrence_Of (Standard_Wide_Wide_String, Loc),
kono
parents:
diff changeset
1115 Constraint =>
kono
parents:
diff changeset
1116 Make_Index_Or_Discriminant_Constraint (Loc,
kono
parents:
diff changeset
1117 Constraints => New_List (
kono
parents:
diff changeset
1118 Make_Range (Loc,
kono
parents:
diff changeset
1119 Low_Bound => Make_Integer_Literal (Loc, 1),
kono
parents:
diff changeset
1120 High_Bound =>
kono
parents:
diff changeset
1121 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1122 Prefix => New_Occurrence_Of (Rtyp, Loc),
kono
parents:
diff changeset
1123 Attribute_Name => Name_Wide_Wide_Width)))))),
kono
parents:
diff changeset
1124
kono
parents:
diff changeset
1125 -- Lnn : Natural;
kono
parents:
diff changeset
1126
kono
parents:
diff changeset
1127 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
1128 Defining_Identifier => Lnn,
kono
parents:
diff changeset
1129 Object_Definition => New_Occurrence_Of (Standard_Natural, Loc)),
kono
parents:
diff changeset
1130
kono
parents:
diff changeset
1131 -- String_To_Wide_Wide_String
kono
parents:
diff changeset
1132 -- (typ'Image (X), Rnn, Lnn, Wide_Character_Encoding_Method);
kono
parents:
diff changeset
1133
kono
parents:
diff changeset
1134 Make_Procedure_Call_Statement (Loc,
kono
parents:
diff changeset
1135 Name =>
kono
parents:
diff changeset
1136 New_Occurrence_Of (RTE (RE_String_To_Wide_Wide_String), Loc),
kono
parents:
diff changeset
1137
kono
parents:
diff changeset
1138 Parameter_Associations => New_List (
kono
parents:
diff changeset
1139 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1140 Prefix => Prefix (N),
kono
parents:
diff changeset
1141 Attribute_Name => Name_Image,
kono
parents:
diff changeset
1142 Expressions => Expressions (N)),
kono
parents:
diff changeset
1143 New_Occurrence_Of (Rnn, Loc),
kono
parents:
diff changeset
1144 New_Occurrence_Of (Lnn, Loc),
kono
parents:
diff changeset
1145 Make_Integer_Literal (Loc,
kono
parents:
diff changeset
1146 Intval => Int (Wide_Character_Encoding_Method))))),
kono
parents:
diff changeset
1147
kono
parents:
diff changeset
1148 -- Suppress checks because we know everything is properly in range
kono
parents:
diff changeset
1149
kono
parents:
diff changeset
1150 Suppress => All_Checks);
kono
parents:
diff changeset
1151
kono
parents:
diff changeset
1152 -- Final step is to rewrite the expression as a slice and analyze,
kono
parents:
diff changeset
1153 -- again with no checks, since we are sure that everything is OK.
kono
parents:
diff changeset
1154
kono
parents:
diff changeset
1155 Rewrite (N,
kono
parents:
diff changeset
1156 Make_Slice (Loc,
kono
parents:
diff changeset
1157 Prefix => New_Occurrence_Of (Rnn, Loc),
kono
parents:
diff changeset
1158 Discrete_Range =>
kono
parents:
diff changeset
1159 Make_Range (Loc,
kono
parents:
diff changeset
1160 Low_Bound => Make_Integer_Literal (Loc, 1),
kono
parents:
diff changeset
1161 High_Bound => New_Occurrence_Of (Lnn, Loc))));
kono
parents:
diff changeset
1162
kono
parents:
diff changeset
1163 Analyze_And_Resolve
kono
parents:
diff changeset
1164 (N, Standard_Wide_Wide_String, Suppress => All_Checks);
kono
parents:
diff changeset
1165 end Expand_Wide_Wide_Image_Attribute;
kono
parents:
diff changeset
1166
kono
parents:
diff changeset
1167 ----------------------------
kono
parents:
diff changeset
1168 -- Expand_Width_Attribute --
kono
parents:
diff changeset
1169 ----------------------------
kono
parents:
diff changeset
1170
kono
parents:
diff changeset
1171 -- The processing here also handles the case of Wide_[Wide_]Width. With the
kono
parents:
diff changeset
1172 -- exceptions noted, the processing is identical
kono
parents:
diff changeset
1173
kono
parents:
diff changeset
1174 -- For scalar types derived from Boolean, character and integer types
kono
parents:
diff changeset
1175 -- in package Standard. Note that the Width attribute is computed at
kono
parents:
diff changeset
1176 -- compile time for all cases except those involving non-static sub-
kono
parents:
diff changeset
1177 -- types. For such subtypes, typ'[Wide_[Wide_]]Width expands into:
kono
parents:
diff changeset
1178
kono
parents:
diff changeset
1179 -- Result_Type (xx (yy (Ptyp'First), yy (Ptyp'Last)))
kono
parents:
diff changeset
1180
kono
parents:
diff changeset
1181 -- where
kono
parents:
diff changeset
1182
kono
parents:
diff changeset
1183 -- For types whose root type is Character
kono
parents:
diff changeset
1184 -- xx = Width_Character
kono
parents:
diff changeset
1185 -- yy = Character
kono
parents:
diff changeset
1186
kono
parents:
diff changeset
1187 -- For types whose root type is Wide_Character
kono
parents:
diff changeset
1188 -- xx = Wide_Width_Character
kono
parents:
diff changeset
1189 -- yy = Character
kono
parents:
diff changeset
1190
kono
parents:
diff changeset
1191 -- For types whose root type is Wide_Wide_Character
kono
parents:
diff changeset
1192 -- xx = Wide_Wide_Width_Character
kono
parents:
diff changeset
1193 -- yy = Character
kono
parents:
diff changeset
1194
kono
parents:
diff changeset
1195 -- For types whose root type is Boolean
kono
parents:
diff changeset
1196 -- xx = Width_Boolean
kono
parents:
diff changeset
1197 -- yy = Boolean
kono
parents:
diff changeset
1198
kono
parents:
diff changeset
1199 -- For signed integer types
kono
parents:
diff changeset
1200 -- xx = Width_Long_Long_Integer
kono
parents:
diff changeset
1201 -- yy = Long_Long_Integer
kono
parents:
diff changeset
1202
kono
parents:
diff changeset
1203 -- For modular integer types
kono
parents:
diff changeset
1204 -- xx = Width_Long_Long_Unsigned
kono
parents:
diff changeset
1205 -- yy = Long_Long_Unsigned
kono
parents:
diff changeset
1206
kono
parents:
diff changeset
1207 -- For types derived from Wide_Character, typ'Width expands into
kono
parents:
diff changeset
1208
kono
parents:
diff changeset
1209 -- Result_Type (Width_Wide_Character (
kono
parents:
diff changeset
1210 -- Wide_Character (typ'First),
kono
parents:
diff changeset
1211 -- Wide_Character (typ'Last),
kono
parents:
diff changeset
1212
kono
parents:
diff changeset
1213 -- and typ'Wide_Width expands into:
kono
parents:
diff changeset
1214
kono
parents:
diff changeset
1215 -- Result_Type (Wide_Width_Wide_Character (
kono
parents:
diff changeset
1216 -- Wide_Character (typ'First),
kono
parents:
diff changeset
1217 -- Wide_Character (typ'Last));
kono
parents:
diff changeset
1218
kono
parents:
diff changeset
1219 -- and typ'Wide_Wide_Width expands into
kono
parents:
diff changeset
1220
kono
parents:
diff changeset
1221 -- Result_Type (Wide_Wide_Width_Wide_Character (
kono
parents:
diff changeset
1222 -- Wide_Character (typ'First),
kono
parents:
diff changeset
1223 -- Wide_Character (typ'Last));
kono
parents:
diff changeset
1224
kono
parents:
diff changeset
1225 -- For types derived from Wide_Wide_Character, typ'Width expands into
kono
parents:
diff changeset
1226
kono
parents:
diff changeset
1227 -- Result_Type (Width_Wide_Wide_Character (
kono
parents:
diff changeset
1228 -- Wide_Wide_Character (typ'First),
kono
parents:
diff changeset
1229 -- Wide_Wide_Character (typ'Last),
kono
parents:
diff changeset
1230
kono
parents:
diff changeset
1231 -- and typ'Wide_Width expands into:
kono
parents:
diff changeset
1232
kono
parents:
diff changeset
1233 -- Result_Type (Wide_Width_Wide_Wide_Character (
kono
parents:
diff changeset
1234 -- Wide_Wide_Character (typ'First),
kono
parents:
diff changeset
1235 -- Wide_Wide_Character (typ'Last));
kono
parents:
diff changeset
1236
kono
parents:
diff changeset
1237 -- and typ'Wide_Wide_Width expands into
kono
parents:
diff changeset
1238
kono
parents:
diff changeset
1239 -- Result_Type (Wide_Wide_Width_Wide_Wide_Char (
kono
parents:
diff changeset
1240 -- Wide_Wide_Character (typ'First),
kono
parents:
diff changeset
1241 -- Wide_Wide_Character (typ'Last));
kono
parents:
diff changeset
1242
kono
parents:
diff changeset
1243 -- For real types, typ'Width and typ'Wide_[Wide_]Width expand into
kono
parents:
diff changeset
1244
kono
parents:
diff changeset
1245 -- if Ptyp'First > Ptyp'Last then 0 else btyp'Width end if
kono
parents:
diff changeset
1246
kono
parents:
diff changeset
1247 -- where btyp is the base type. This looks recursive but it isn't
kono
parents:
diff changeset
1248 -- because the base type is always static, and hence the expression
kono
parents:
diff changeset
1249 -- in the else is reduced to an integer literal.
kono
parents:
diff changeset
1250
kono
parents:
diff changeset
1251 -- For user-defined enumeration types, typ'Width expands into
kono
parents:
diff changeset
1252
kono
parents:
diff changeset
1253 -- Result_Type (Width_Enumeration_NN
kono
parents:
diff changeset
1254 -- (typS,
kono
parents:
diff changeset
1255 -- typI'Address,
kono
parents:
diff changeset
1256 -- typ'Pos (typ'First),
kono
parents:
diff changeset
1257 -- typ'Pos (Typ'Last)));
kono
parents:
diff changeset
1258
kono
parents:
diff changeset
1259 -- and typ'Wide_Width expands into:
kono
parents:
diff changeset
1260
kono
parents:
diff changeset
1261 -- Result_Type (Wide_Width_Enumeration_NN
kono
parents:
diff changeset
1262 -- (typS,
kono
parents:
diff changeset
1263 -- typI,
kono
parents:
diff changeset
1264 -- typ'Pos (typ'First),
kono
parents:
diff changeset
1265 -- typ'Pos (Typ'Last))
kono
parents:
diff changeset
1266 -- Wide_Character_Encoding_Method);
kono
parents:
diff changeset
1267
kono
parents:
diff changeset
1268 -- and typ'Wide_Wide_Width expands into:
kono
parents:
diff changeset
1269
kono
parents:
diff changeset
1270 -- Result_Type (Wide_Wide_Width_Enumeration_NN
kono
parents:
diff changeset
1271 -- (typS,
kono
parents:
diff changeset
1272 -- typI,
kono
parents:
diff changeset
1273 -- typ'Pos (typ'First),
kono
parents:
diff changeset
1274 -- typ'Pos (Typ'Last))
kono
parents:
diff changeset
1275 -- Wide_Character_Encoding_Method);
kono
parents:
diff changeset
1276
kono
parents:
diff changeset
1277 -- where typS and typI are the enumeration image strings and indexes
kono
parents:
diff changeset
1278 -- table, as described in Build_Enumeration_Image_Tables. NN is 8/16/32
kono
parents:
diff changeset
1279 -- for depending on the element type for typI.
kono
parents:
diff changeset
1280
kono
parents:
diff changeset
1281 -- Finally if Discard_Names is in effect for an enumeration type, then
kono
parents:
diff changeset
1282 -- a special if expression is built that yields the space needed for the
kono
parents:
diff changeset
1283 -- decimal representation of the largest pos value in the subtype. See
kono
parents:
diff changeset
1284 -- code below for details.
kono
parents:
diff changeset
1285
kono
parents:
diff changeset
1286 procedure Expand_Width_Attribute (N : Node_Id; Attr : Atype := Normal) is
kono
parents:
diff changeset
1287 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
1288 Typ : constant Entity_Id := Etype (N);
kono
parents:
diff changeset
1289 Pref : constant Node_Id := Prefix (N);
kono
parents:
diff changeset
1290 Ptyp : constant Entity_Id := Etype (Pref);
kono
parents:
diff changeset
1291 Rtyp : constant Entity_Id := Root_Type (Ptyp);
kono
parents:
diff changeset
1292 Arglist : List_Id;
kono
parents:
diff changeset
1293 Ttyp : Entity_Id;
kono
parents:
diff changeset
1294 XX : RE_Id;
kono
parents:
diff changeset
1295 YY : Entity_Id;
kono
parents:
diff changeset
1296
kono
parents:
diff changeset
1297 begin
kono
parents:
diff changeset
1298 -- Types derived from Standard.Boolean
kono
parents:
diff changeset
1299
kono
parents:
diff changeset
1300 if Rtyp = Standard_Boolean then
kono
parents:
diff changeset
1301 XX := RE_Width_Boolean;
kono
parents:
diff changeset
1302 YY := Rtyp;
kono
parents:
diff changeset
1303
kono
parents:
diff changeset
1304 -- Types derived from Standard.Character
kono
parents:
diff changeset
1305
kono
parents:
diff changeset
1306 elsif Rtyp = Standard_Character then
kono
parents:
diff changeset
1307 case Attr is
kono
parents:
diff changeset
1308 when Normal => XX := RE_Width_Character;
kono
parents:
diff changeset
1309 when Wide => XX := RE_Wide_Width_Character;
kono
parents:
diff changeset
1310 when Wide_Wide => XX := RE_Wide_Wide_Width_Character;
kono
parents:
diff changeset
1311 end case;
kono
parents:
diff changeset
1312
kono
parents:
diff changeset
1313 YY := Rtyp;
kono
parents:
diff changeset
1314
kono
parents:
diff changeset
1315 -- Types derived from Standard.Wide_Character
kono
parents:
diff changeset
1316
kono
parents:
diff changeset
1317 elsif Rtyp = Standard_Wide_Character then
kono
parents:
diff changeset
1318 case Attr is
kono
parents:
diff changeset
1319 when Normal => XX := RE_Width_Wide_Character;
kono
parents:
diff changeset
1320 when Wide => XX := RE_Wide_Width_Wide_Character;
kono
parents:
diff changeset
1321 when Wide_Wide => XX := RE_Wide_Wide_Width_Wide_Character;
kono
parents:
diff changeset
1322 end case;
kono
parents:
diff changeset
1323
kono
parents:
diff changeset
1324 YY := Rtyp;
kono
parents:
diff changeset
1325
kono
parents:
diff changeset
1326 -- Types derived from Standard.Wide_Wide_Character
kono
parents:
diff changeset
1327
kono
parents:
diff changeset
1328 elsif Rtyp = Standard_Wide_Wide_Character then
kono
parents:
diff changeset
1329 case Attr is
kono
parents:
diff changeset
1330 when Normal => XX := RE_Width_Wide_Wide_Character;
kono
parents:
diff changeset
1331 when Wide => XX := RE_Wide_Width_Wide_Wide_Character;
kono
parents:
diff changeset
1332 when Wide_Wide => XX := RE_Wide_Wide_Width_Wide_Wide_Char;
kono
parents:
diff changeset
1333 end case;
kono
parents:
diff changeset
1334
kono
parents:
diff changeset
1335 YY := Rtyp;
kono
parents:
diff changeset
1336
kono
parents:
diff changeset
1337 -- Signed integer types
kono
parents:
diff changeset
1338
kono
parents:
diff changeset
1339 elsif Is_Signed_Integer_Type (Rtyp) then
kono
parents:
diff changeset
1340 XX := RE_Width_Long_Long_Integer;
kono
parents:
diff changeset
1341 YY := Standard_Long_Long_Integer;
kono
parents:
diff changeset
1342
kono
parents:
diff changeset
1343 -- Modular integer types
kono
parents:
diff changeset
1344
kono
parents:
diff changeset
1345 elsif Is_Modular_Integer_Type (Rtyp) then
kono
parents:
diff changeset
1346 XX := RE_Width_Long_Long_Unsigned;
kono
parents:
diff changeset
1347 YY := RTE (RE_Long_Long_Unsigned);
kono
parents:
diff changeset
1348
kono
parents:
diff changeset
1349 -- Real types
kono
parents:
diff changeset
1350
kono
parents:
diff changeset
1351 elsif Is_Real_Type (Rtyp) then
kono
parents:
diff changeset
1352 Rewrite (N,
kono
parents:
diff changeset
1353 Make_If_Expression (Loc,
kono
parents:
diff changeset
1354 Expressions => New_List (
kono
parents:
diff changeset
1355
kono
parents:
diff changeset
1356 Make_Op_Gt (Loc,
kono
parents:
diff changeset
1357 Left_Opnd =>
kono
parents:
diff changeset
1358 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1359 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
1360 Attribute_Name => Name_First),
kono
parents:
diff changeset
1361
kono
parents:
diff changeset
1362 Right_Opnd =>
kono
parents:
diff changeset
1363 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1364 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
1365 Attribute_Name => Name_Last)),
kono
parents:
diff changeset
1366
kono
parents:
diff changeset
1367 Make_Integer_Literal (Loc, 0),
kono
parents:
diff changeset
1368
kono
parents:
diff changeset
1369 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1370 Prefix => New_Occurrence_Of (Base_Type (Ptyp), Loc),
kono
parents:
diff changeset
1371 Attribute_Name => Name_Width))));
kono
parents:
diff changeset
1372
kono
parents:
diff changeset
1373 Analyze_And_Resolve (N, Typ);
kono
parents:
diff changeset
1374 return;
kono
parents:
diff changeset
1375
kono
parents:
diff changeset
1376 -- User-defined enumeration types
kono
parents:
diff changeset
1377
kono
parents:
diff changeset
1378 else
kono
parents:
diff changeset
1379 pragma Assert (Is_Enumeration_Type (Rtyp));
kono
parents:
diff changeset
1380
kono
parents:
diff changeset
1381 -- Whenever pragma Discard_Names is in effect, the value we need
kono
parents:
diff changeset
1382 -- is the value needed to accommodate the largest integer pos value
kono
parents:
diff changeset
1383 -- in the range of the subtype + 1 for the space at the start. We
kono
parents:
diff changeset
1384 -- build:
kono
parents:
diff changeset
1385
kono
parents:
diff changeset
1386 -- Tnn : constant Integer := Rtyp'Pos (Ptyp'Last)
kono
parents:
diff changeset
1387
kono
parents:
diff changeset
1388 -- and replace the expression by
kono
parents:
diff changeset
1389
kono
parents:
diff changeset
1390 -- (if Ptyp'Range_Length = 0 then 0
kono
parents:
diff changeset
1391 -- else (if Tnn < 10 then 2
kono
parents:
diff changeset
1392 -- else (if Tnn < 100 then 3
kono
parents:
diff changeset
1393 -- ...
kono
parents:
diff changeset
1394 -- else n)))...
kono
parents:
diff changeset
1395
kono
parents:
diff changeset
1396 -- where n is equal to Rtyp'Pos (Ptyp'Last) + 1
kono
parents:
diff changeset
1397
kono
parents:
diff changeset
1398 -- Note: The above processing is in accordance with the intent of
kono
parents:
diff changeset
1399 -- the RM, which is that Width should be related to the impl-defined
kono
parents:
diff changeset
1400 -- behavior of Image. It is not clear what this means if Image is
kono
parents:
diff changeset
1401 -- not defined (as in the configurable run-time case for GNAT) and
kono
parents:
diff changeset
1402 -- gives an error at compile time.
kono
parents:
diff changeset
1403
kono
parents:
diff changeset
1404 -- We choose in this case to just go ahead and implement Width the
kono
parents:
diff changeset
1405 -- same way, returning what Image would have returned if it has been
kono
parents:
diff changeset
1406 -- available in the configurable run-time library.
kono
parents:
diff changeset
1407
kono
parents:
diff changeset
1408 if Discard_Names (Rtyp) then
kono
parents:
diff changeset
1409 declare
kono
parents:
diff changeset
1410 Tnn : constant Entity_Id := Make_Temporary (Loc, 'T');
kono
parents:
diff changeset
1411 Cexpr : Node_Id;
kono
parents:
diff changeset
1412 P : Int;
kono
parents:
diff changeset
1413 M : Int;
kono
parents:
diff changeset
1414 K : Int;
kono
parents:
diff changeset
1415
kono
parents:
diff changeset
1416 begin
kono
parents:
diff changeset
1417 Insert_Action (N,
kono
parents:
diff changeset
1418 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
1419 Defining_Identifier => Tnn,
kono
parents:
diff changeset
1420 Constant_Present => True,
kono
parents:
diff changeset
1421 Object_Definition =>
kono
parents:
diff changeset
1422 New_Occurrence_Of (Standard_Integer, Loc),
kono
parents:
diff changeset
1423 Expression =>
kono
parents:
diff changeset
1424 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1425 Prefix => New_Occurrence_Of (Rtyp, Loc),
kono
parents:
diff changeset
1426 Attribute_Name => Name_Pos,
kono
parents:
diff changeset
1427 Expressions => New_List (
kono
parents:
diff changeset
1428 Convert_To (Rtyp,
kono
parents:
diff changeset
1429 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1430 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
1431 Attribute_Name => Name_Last))))));
kono
parents:
diff changeset
1432
kono
parents:
diff changeset
1433 -- OK, now we need to build the if expression. First get the
kono
parents:
diff changeset
1434 -- value of M, the largest possible value needed.
kono
parents:
diff changeset
1435
kono
parents:
diff changeset
1436 P := UI_To_Int
kono
parents:
diff changeset
1437 (Enumeration_Pos (Entity (Type_High_Bound (Rtyp))));
kono
parents:
diff changeset
1438
kono
parents:
diff changeset
1439 K := 1;
kono
parents:
diff changeset
1440 M := 1;
kono
parents:
diff changeset
1441 while M < P loop
kono
parents:
diff changeset
1442 M := M * 10;
kono
parents:
diff changeset
1443 K := K + 1;
kono
parents:
diff changeset
1444 end loop;
kono
parents:
diff changeset
1445
kono
parents:
diff changeset
1446 -- Build inner else
kono
parents:
diff changeset
1447
kono
parents:
diff changeset
1448 Cexpr := Make_Integer_Literal (Loc, K);
kono
parents:
diff changeset
1449
kono
parents:
diff changeset
1450 -- Wrap in inner if's until counted down to 2
kono
parents:
diff changeset
1451
kono
parents:
diff changeset
1452 while K > 2 loop
kono
parents:
diff changeset
1453 M := M / 10;
kono
parents:
diff changeset
1454 K := K - 1;
kono
parents:
diff changeset
1455
kono
parents:
diff changeset
1456 Cexpr :=
kono
parents:
diff changeset
1457 Make_If_Expression (Loc,
kono
parents:
diff changeset
1458 Expressions => New_List (
kono
parents:
diff changeset
1459 Make_Op_Lt (Loc,
kono
parents:
diff changeset
1460 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
kono
parents:
diff changeset
1461 Right_Opnd => Make_Integer_Literal (Loc, M)),
kono
parents:
diff changeset
1462 Make_Integer_Literal (Loc, K),
kono
parents:
diff changeset
1463 Cexpr));
kono
parents:
diff changeset
1464 end loop;
kono
parents:
diff changeset
1465
kono
parents:
diff changeset
1466 -- Add initial comparison for null range and we are done, so
kono
parents:
diff changeset
1467 -- rewrite the attribute occurrence with this expression.
kono
parents:
diff changeset
1468
kono
parents:
diff changeset
1469 Rewrite (N,
kono
parents:
diff changeset
1470 Convert_To (Typ,
kono
parents:
diff changeset
1471 Make_If_Expression (Loc,
kono
parents:
diff changeset
1472 Expressions => New_List (
kono
parents:
diff changeset
1473 Make_Op_Eq (Loc,
kono
parents:
diff changeset
1474 Left_Opnd =>
kono
parents:
diff changeset
1475 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1476 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
1477 Attribute_Name => Name_Range_Length),
kono
parents:
diff changeset
1478 Right_Opnd => Make_Integer_Literal (Loc, 0)),
kono
parents:
diff changeset
1479 Make_Integer_Literal (Loc, 0),
kono
parents:
diff changeset
1480 Cexpr))));
kono
parents:
diff changeset
1481
kono
parents:
diff changeset
1482 Analyze_And_Resolve (N, Typ);
kono
parents:
diff changeset
1483 return;
kono
parents:
diff changeset
1484 end;
kono
parents:
diff changeset
1485 end if;
kono
parents:
diff changeset
1486
kono
parents:
diff changeset
1487 -- Normal case, not Discard_Names
kono
parents:
diff changeset
1488
kono
parents:
diff changeset
1489 Ttyp := Component_Type (Etype (Lit_Indexes (Rtyp)));
kono
parents:
diff changeset
1490
kono
parents:
diff changeset
1491 case Attr is
kono
parents:
diff changeset
1492 when Normal =>
kono
parents:
diff changeset
1493 if Ttyp = Standard_Integer_8 then
kono
parents:
diff changeset
1494 XX := RE_Width_Enumeration_8;
kono
parents:
diff changeset
1495 elsif Ttyp = Standard_Integer_16 then
kono
parents:
diff changeset
1496 XX := RE_Width_Enumeration_16;
kono
parents:
diff changeset
1497 else
kono
parents:
diff changeset
1498 XX := RE_Width_Enumeration_32;
kono
parents:
diff changeset
1499 end if;
kono
parents:
diff changeset
1500
kono
parents:
diff changeset
1501 when Wide =>
kono
parents:
diff changeset
1502 if Ttyp = Standard_Integer_8 then
kono
parents:
diff changeset
1503 XX := RE_Wide_Width_Enumeration_8;
kono
parents:
diff changeset
1504 elsif Ttyp = Standard_Integer_16 then
kono
parents:
diff changeset
1505 XX := RE_Wide_Width_Enumeration_16;
kono
parents:
diff changeset
1506 else
kono
parents:
diff changeset
1507 XX := RE_Wide_Width_Enumeration_32;
kono
parents:
diff changeset
1508 end if;
kono
parents:
diff changeset
1509
kono
parents:
diff changeset
1510 when Wide_Wide =>
kono
parents:
diff changeset
1511 if Ttyp = Standard_Integer_8 then
kono
parents:
diff changeset
1512 XX := RE_Wide_Wide_Width_Enumeration_8;
kono
parents:
diff changeset
1513 elsif Ttyp = Standard_Integer_16 then
kono
parents:
diff changeset
1514 XX := RE_Wide_Wide_Width_Enumeration_16;
kono
parents:
diff changeset
1515 else
kono
parents:
diff changeset
1516 XX := RE_Wide_Wide_Width_Enumeration_32;
kono
parents:
diff changeset
1517 end if;
kono
parents:
diff changeset
1518 end case;
kono
parents:
diff changeset
1519
kono
parents:
diff changeset
1520 Arglist :=
kono
parents:
diff changeset
1521 New_List (
kono
parents:
diff changeset
1522 New_Occurrence_Of (Lit_Strings (Rtyp), Loc),
kono
parents:
diff changeset
1523
kono
parents:
diff changeset
1524 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1525 Prefix => New_Occurrence_Of (Lit_Indexes (Rtyp), Loc),
kono
parents:
diff changeset
1526 Attribute_Name => Name_Address),
kono
parents:
diff changeset
1527
kono
parents:
diff changeset
1528 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1529 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
1530 Attribute_Name => Name_Pos,
kono
parents:
diff changeset
1531
kono
parents:
diff changeset
1532 Expressions => New_List (
kono
parents:
diff changeset
1533 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1534 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
1535 Attribute_Name => Name_First))),
kono
parents:
diff changeset
1536
kono
parents:
diff changeset
1537 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1538 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
1539 Attribute_Name => Name_Pos,
kono
parents:
diff changeset
1540
kono
parents:
diff changeset
1541 Expressions => New_List (
kono
parents:
diff changeset
1542 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1543 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
1544 Attribute_Name => Name_Last))));
kono
parents:
diff changeset
1545
kono
parents:
diff changeset
1546 Rewrite (N,
kono
parents:
diff changeset
1547 Convert_To (Typ,
kono
parents:
diff changeset
1548 Make_Function_Call (Loc,
kono
parents:
diff changeset
1549 Name => New_Occurrence_Of (RTE (XX), Loc),
kono
parents:
diff changeset
1550 Parameter_Associations => Arglist)));
kono
parents:
diff changeset
1551
kono
parents:
diff changeset
1552 Analyze_And_Resolve (N, Typ);
kono
parents:
diff changeset
1553 return;
kono
parents:
diff changeset
1554 end if;
kono
parents:
diff changeset
1555
kono
parents:
diff changeset
1556 -- If we fall through XX and YY are set
kono
parents:
diff changeset
1557
kono
parents:
diff changeset
1558 Arglist := New_List (
kono
parents:
diff changeset
1559 Convert_To (YY,
kono
parents:
diff changeset
1560 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1561 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
1562 Attribute_Name => Name_First)),
kono
parents:
diff changeset
1563
kono
parents:
diff changeset
1564 Convert_To (YY,
kono
parents:
diff changeset
1565 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1566 Prefix => New_Occurrence_Of (Ptyp, Loc),
kono
parents:
diff changeset
1567 Attribute_Name => Name_Last)));
kono
parents:
diff changeset
1568
kono
parents:
diff changeset
1569 Rewrite (N,
kono
parents:
diff changeset
1570 Convert_To (Typ,
kono
parents:
diff changeset
1571 Make_Function_Call (Loc,
kono
parents:
diff changeset
1572 Name => New_Occurrence_Of (RTE (XX), Loc),
kono
parents:
diff changeset
1573 Parameter_Associations => Arglist)));
kono
parents:
diff changeset
1574
kono
parents:
diff changeset
1575 Analyze_And_Resolve (N, Typ);
kono
parents:
diff changeset
1576 end Expand_Width_Attribute;
kono
parents:
diff changeset
1577
kono
parents:
diff changeset
1578 -----------------------
kono
parents:
diff changeset
1579 -- Has_Decimal_Small --
kono
parents:
diff changeset
1580 -----------------------
kono
parents:
diff changeset
1581
kono
parents:
diff changeset
1582 function Has_Decimal_Small (E : Entity_Id) return Boolean is
kono
parents:
diff changeset
1583 begin
kono
parents:
diff changeset
1584 return Is_Decimal_Fixed_Point_Type (E)
kono
parents:
diff changeset
1585 or else
kono
parents:
diff changeset
1586 (Is_Ordinary_Fixed_Point_Type (E)
kono
parents:
diff changeset
1587 and then Ureal_10**Aft_Value (E) * Small_Value (E) = Ureal_1);
kono
parents:
diff changeset
1588 end Has_Decimal_Small;
kono
parents:
diff changeset
1589
kono
parents:
diff changeset
1590 --------------------------
kono
parents:
diff changeset
1591 -- Rewrite_Object_Image --
kono
parents:
diff changeset
1592 --------------------------
kono
parents:
diff changeset
1593
kono
parents:
diff changeset
1594 procedure Rewrite_Object_Image
kono
parents:
diff changeset
1595 (N : Node_Id;
kono
parents:
diff changeset
1596 Pref : Entity_Id;
kono
parents:
diff changeset
1597 Attr_Name : Name_Id;
kono
parents:
diff changeset
1598 Str_Typ : Entity_Id)
kono
parents:
diff changeset
1599 is
kono
parents:
diff changeset
1600 begin
kono
parents:
diff changeset
1601 Rewrite (N,
kono
parents:
diff changeset
1602 Make_Attribute_Reference (Sloc (N),
kono
parents:
diff changeset
1603 Prefix => New_Occurrence_Of (Etype (Pref), Sloc (N)),
kono
parents:
diff changeset
1604 Attribute_Name => Attr_Name,
kono
parents:
diff changeset
1605 Expressions => New_List (Relocate_Node (Pref))));
kono
parents:
diff changeset
1606
kono
parents:
diff changeset
1607 Analyze_And_Resolve (N, Str_Typ);
kono
parents:
diff changeset
1608 end Rewrite_Object_Image;
kono
parents:
diff changeset
1609 end Exp_Imgv;