]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ada/repinfo.adb
Add targetm.insn_cost hook
[thirdparty/gcc.git] / gcc / ada / repinfo.adb
CommitLineData
19235870
RK
1------------------------------------------------------------------------------
2-- --
3-- GNAT COMPILER COMPONENTS --
4-- --
5-- R E P I N F O --
6-- --
7-- B o d y --
8-- --
e45f84a5 9-- Copyright (C) 1999-2017, Free Software Foundation, Inc. --
19235870
RK
10-- --
11-- GNAT is free software; you can redistribute it and/or modify it under --
12-- terms of the GNU General Public License as published by the Free Soft- --
748086b7 13-- ware Foundation; either version 3, or (at your option) any later ver- --
19235870
RK
14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
748086b7
JJ
16-- or FITNESS FOR A PARTICULAR PURPOSE. --
17-- --
18-- As a special exception under Section 7 of GPL version 3, you are granted --
19-- additional permissions described in the GCC Runtime Library Exception, --
20-- version 3.1, as published by the Free Software Foundation. --
21-- --
22-- You should have received a copy of the GNU General Public License and --
23-- a copy of the GCC Runtime Library Exception along with this program; --
24-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25-- <http://www.gnu.org/licenses/>. --
26-- --
19235870 27-- GNAT was originally developed by the GNAT team at New York University. --
71ff80dc 28-- Extensive contributions were provided by Ada Core Technologies Inc. --
19235870
RK
29-- --
30------------------------------------------------------------------------------
31
851e9f19 32with Alloc;
d9f8616e
AC
33with Atree; use Atree;
34with Casing; use Casing;
35with Debug; use Debug;
36with Einfo; use Einfo;
37with Lib; use Lib;
38with Namet; use Namet;
19992053 39with Nlists; use Nlists;
d9f8616e
AC
40with Opt; use Opt;
41with Output; use Output;
42with Sem_Aux; use Sem_Aux;
43with Sinfo; use Sinfo;
44with Sinput; use Sinput;
45with Snames; use Snames;
46with Stand; use Stand;
19992053 47with Stringt; use Stringt;
851e9f19 48with Table;
d9f8616e
AC
49with Uname; use Uname;
50with Urealp; use Urealp;
19235870 51
5e61ef09
TQ
52with Ada.Unchecked_Conversion;
53
19235870
RK
54package body Repinfo is
55
56 SSU : constant := 8;
57 -- Value for Storage_Unit, we do not want to get this from TTypes, since
58 -- this introduces problematic dependencies in ASIS, and in any case this
59 -- value is assumed to be 8 for the implementation of the DDA.
fbf5a39b 60
19235870 61 ---------------------------------------
e45f84a5 62 -- Representation of GCC Expressions --
19235870
RK
63 ---------------------------------------
64
5e61ef09
TQ
65 -- A table internal to this unit is used to hold the values of back
66 -- annotated expressions. This table is written out by -gnatt and read
67 -- back in for ASIS processing.
19235870 68
5e61ef09
TQ
69 -- Node values are stored as Uint values using the negative of the node
70 -- index in this table. Constants appear as non-negative Uint values.
19235870
RK
71
72 type Exp_Node is record
73 Expr : TCode;
74 Op1 : Node_Ref_Or_Val;
75 Op2 : Node_Ref_Or_Val;
76 Op3 : Node_Ref_Or_Val;
77 end record;
78
1c28fe3a
RD
79 -- The following representation clause ensures that the above record
80 -- has no holes. We do this so that when instances of this record are
81 -- written by Tree_Gen, we do not write uninitialized values to the file.
82
83 for Exp_Node use record
84 Expr at 0 range 0 .. 31;
85 Op1 at 4 range 0 .. 31;
86 Op2 at 8 range 0 .. 31;
87 Op3 at 12 range 0 .. 31;
88 end record;
89
90 for Exp_Node'Size use 16 * 8;
91 -- This ensures that we did not leave out any fields
92
19235870
RK
93 package Rep_Table is new Table.Table (
94 Table_Component_Type => Exp_Node,
95 Table_Index_Type => Nat,
96 Table_Low_Bound => 1,
97 Table_Initial => Alloc.Rep_Table_Initial,
98 Table_Increment => Alloc.Rep_Table_Increment,
99 Table_Name => "BE_Rep_Table");
100
101 --------------------------------------------------------------
102 -- Representation of Front-End Dynamic Size/Offset Entities --
103 --------------------------------------------------------------
104
105 package Dynamic_SO_Entity_Table is new Table.Table (
106 Table_Component_Type => Entity_Id,
107 Table_Index_Type => Nat,
108 Table_Low_Bound => 1,
109 Table_Initial => Alloc.Rep_Table_Initial,
110 Table_Increment => Alloc.Rep_Table_Increment,
111 Table_Name => "FE_Rep_Table");
112
19235870 113 Unit_Casing : Casing_Type;
d436b30d
AC
114 -- Identifier casing for current unit. This is set by List_Rep_Info for
115 -- each unit, before calling subprograms which may read it.
19235870 116
fbf5a39b 117 Need_Blank_Line : Boolean;
5e61ef09
TQ
118 -- Set True if a blank line is needed before outputting any information for
119 -- the current entity. Set True when a new entity is processed, and false
120 -- when the blank line is output.
fbf5a39b
AC
121
122 -----------------------
123 -- Local Subprograms --
124 -----------------------
19235870
RK
125
126 function Back_End_Layout return Boolean;
5e61ef09
TQ
127 -- Test for layout mode, True = back end, False = front end. This function
128 -- is used rather than checking the configuration parameter because we do
129 -- not want Repinfo to depend on Targparm (for ASIS)
19235870 130
fbf5a39b
AC
131 procedure Blank_Line;
132 -- Called before outputting anything for an entity. Ensures that
133 -- a blank line precedes the output for a particular entity.
134
1e60643a 135 procedure List_Entities
558fbeb0 136 (Ent : Entity_Id;
1e60643a
AC
137 Bytes_Big_Endian : Boolean;
138 In_Subprogram : Boolean := False);
5e61ef09
TQ
139 -- This procedure lists the entities associated with the entity E, starting
140 -- with the First_Entity and using the Next_Entity link. If a nested
141 -- package is found, entities within the package are recursively processed.
1e60643a
AC
142 -- When recursing within a subprogram body, Is_Subprogram suppresses
143 -- duplicate information about signature.
19235870
RK
144
145 procedure List_Name (Ent : Entity_Id);
146 -- List name of entity Ent in appropriate case. The name is listed with
147 -- full qualification up to but not including the compilation unit name.
148
d9f8616e 149 procedure List_Array_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean);
19235870
RK
150 -- List representation info for array type Ent
151
19992053
AC
152 procedure List_Linker_Section (Ent : Entity_Id);
153 -- List linker section for Ent (caller has checked that Ent is an entity
154 -- for which the Linker_Section_Pragma field is defined).
155
fbf5a39b 156 procedure List_Mechanisms (Ent : Entity_Id);
5e61ef09
TQ
157 -- List mechanism information for parameters of Ent, which is subprogram,
158 -- subprogram type, or an entry or entry family.
fbf5a39b 159
19235870
RK
160 procedure List_Object_Info (Ent : Entity_Id);
161 -- List representation info for object Ent
162
d9f8616e 163 procedure List_Record_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean);
19235870
RK
164 -- List representation info for record type Ent
165
d9f8616e
AC
166 procedure List_Scalar_Storage_Order
167 (Ent : Entity_Id;
168 Bytes_Big_Endian : Boolean);
7ed57189
AC
169 -- List scalar storage order information for record or array type Ent.
170 -- Also includes bit order information for record types, if necessary.
d9f8616e 171
19235870
RK
172 procedure List_Type_Info (Ent : Entity_Id);
173 -- List type info for type Ent
174
175 function Rep_Not_Constant (Val : Node_Ref_Or_Val) return Boolean;
176 -- Returns True if Val represents a variable value, and False if it
177 -- represents a value that is fixed at compile time.
178
fbf5a39b
AC
179 procedure Spaces (N : Natural);
180 -- Output given number of spaces
181
07fc65c4 182 procedure Write_Info_Line (S : String);
5e61ef09
TQ
183 -- Routine to write a line to Repinfo output file. This routine is passed
184 -- as a special output procedure to Output.Set_Special_Output. Note that
185 -- Write_Info_Line is called with an EOL character at the end of each line,
186 -- as per the Output spec, but the internal call to the appropriate routine
187 -- in Osint requires that the end of line sequence be stripped off.
07fc65c4 188
fbf5a39b
AC
189 procedure Write_Mechanism (M : Mechanism_Type);
190 -- Writes symbolic string for mechanism represented by M
191
19235870
RK
192 procedure Write_Val (Val : Node_Ref_Or_Val; Paren : Boolean := False);
193 -- Given a representation value, write it out. No_Uint values or values
194 -- dependent on discriminants are written as two question marks. If the
5e61ef09
TQ
195 -- flag Paren is set, then the output is surrounded in parentheses if it is
196 -- other than a simple value.
19235870
RK
197
198 ---------------------
199 -- Back_End_Layout --
200 ---------------------
201
202 function Back_End_Layout return Boolean is
203 begin
5e61ef09
TQ
204 -- We have back end layout if the back end has made any entries in the
205 -- table of GCC expressions, otherwise we have front end layout.
19235870
RK
206
207 return Rep_Table.Last > 0;
208 end Back_End_Layout;
209
fbf5a39b
AC
210 ----------------
211 -- Blank_Line --
212 ----------------
213
214 procedure Blank_Line is
215 begin
216 if Need_Blank_Line then
217 Write_Eol;
218 Need_Blank_Line := False;
219 end if;
220 end Blank_Line;
221
19235870
RK
222 ------------------------
223 -- Create_Discrim_Ref --
224 ------------------------
225
a4c1cd80 226 function Create_Discrim_Ref (Discr : Entity_Id) return Node_Ref is
19235870 227 begin
1d6f10a1
TQ
228 return Create_Node
229 (Expr => Discrim_Val,
230 Op1 => Discriminant_Number (Discr));
19235870
RK
231 end Create_Discrim_Ref;
232
233 ---------------------------
234 -- Create_Dynamic_SO_Ref --
235 ---------------------------
236
a4c1cd80 237 function Create_Dynamic_SO_Ref (E : Entity_Id) return Dynamic_SO_Ref is
19235870 238 begin
1d6f10a1
TQ
239 Dynamic_SO_Entity_Table.Append (E);
240 return UI_From_Int (-Dynamic_SO_Entity_Table.Last);
19235870
RK
241 end Create_Dynamic_SO_Ref;
242
243 -----------------
244 -- Create_Node --
245 -----------------
246
247 function Create_Node
248 (Expr : TCode;
249 Op1 : Node_Ref_Or_Val;
250 Op2 : Node_Ref_Or_Val := No_Uint;
a4c1cd80 251 Op3 : Node_Ref_Or_Val := No_Uint) return Node_Ref
19235870 252 is
19235870 253 begin
1d6f10a1
TQ
254 Rep_Table.Append (
255 (Expr => Expr,
256 Op1 => Op1,
257 Op2 => Op2,
258 Op3 => Op3));
259 return UI_From_Int (-Rep_Table.Last);
19235870
RK
260 end Create_Node;
261
262 ---------------------------
263 -- Get_Dynamic_SO_Entity --
264 ---------------------------
265
a4c1cd80 266 function Get_Dynamic_SO_Entity (U : Dynamic_SO_Ref) return Entity_Id is
19235870
RK
267 begin
268 return Dynamic_SO_Entity_Table.Table (-UI_To_Int (U));
269 end Get_Dynamic_SO_Entity;
270
271 -----------------------
272 -- Is_Dynamic_SO_Ref --
273 -----------------------
274
275 function Is_Dynamic_SO_Ref (U : SO_Ref) return Boolean is
276 begin
277 return U < Uint_0;
278 end Is_Dynamic_SO_Ref;
279
280 ----------------------
281 -- Is_Static_SO_Ref --
282 ----------------------
283
284 function Is_Static_SO_Ref (U : SO_Ref) return Boolean is
285 begin
286 return U >= Uint_0;
287 end Is_Static_SO_Ref;
288
289 ---------
290 -- lgx --
291 ---------
292
293 procedure lgx (U : Node_Ref_Or_Val) is
294 begin
295 List_GCC_Expression (U);
296 Write_Eol;
297 end lgx;
298
299 ----------------------
300 -- List_Array_Info --
301 ----------------------
302
d9f8616e 303 procedure List_Array_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean) is
19235870
RK
304 begin
305 List_Type_Info (Ent);
19235870
RK
306 Write_Str ("for ");
307 List_Name (Ent);
308 Write_Str ("'Component_Size use ");
309 Write_Val (Component_Size (Ent));
310 Write_Line (";");
d9f8616e
AC
311
312 List_Scalar_Storage_Order (Ent, Bytes_Big_Endian);
19235870
RK
313 end List_Array_Info;
314
315 -------------------
316 -- List_Entities --
317 -------------------
318
1e60643a 319 procedure List_Entities
558fbeb0 320 (Ent : Entity_Id;
1e60643a
AC
321 Bytes_Big_Endian : Boolean;
322 In_Subprogram : Boolean := False)
323 is
fbf5a39b
AC
324 Body_E : Entity_Id;
325 E : Entity_Id;
326
327 function Find_Declaration (E : Entity_Id) return Node_Id;
328 -- Utility to retrieve declaration node for entity in the
329 -- case of package bodies and subprograms.
330
331 ----------------------
332 -- Find_Declaration --
333 ----------------------
334
335 function Find_Declaration (E : Entity_Id) return Node_Id is
336 Decl : Node_Id;
a4c1cd80 337
fbf5a39b
AC
338 begin
339 Decl := Parent (E);
fbf5a39b 340 while Present (Decl)
1155ae01 341 and then Nkind (Decl) /= N_Package_Body
fbf5a39b
AC
342 and then Nkind (Decl) /= N_Subprogram_Declaration
343 and then Nkind (Decl) /= N_Subprogram_Body
344 loop
345 Decl := Parent (Decl);
346 end loop;
347
348 return Decl;
349 end Find_Declaration;
350
351 -- Start of processing for List_Entities
19235870
RK
352
353 begin
d3879a5a
RD
354 -- List entity if we have one, and it is not a renaming declaration.
355 -- For renamings, we don't get proper information, and really it makes
356 -- sense to restrict the output to the renamed entity.
fbf5a39b 357
d3879a5a
RD
358 if Present (Ent)
359 and then Nkind (Declaration_Node (Ent)) not in N_Renaming_Declaration
360 then
fbf5a39b 361 -- If entity is a subprogram and we are listing mechanisms,
1e60643a
AC
362 -- then we need to list mechanisms for this entity. We skip this
363 -- if it is a nested subprogram, as the information has already
364 -- been produced when listing the enclosing scope.
fbf5a39b
AC
365
366 if List_Representation_Info_Mechanisms
367 and then (Is_Subprogram (Ent)
19992053
AC
368 or else Ekind (Ent) = E_Entry
369 or else Ekind (Ent) = E_Entry_Family)
1e60643a 370 and then not In_Subprogram
fbf5a39b
AC
371 then
372 Need_Blank_Line := True;
373 List_Mechanisms (Ent);
374 end if;
375
19235870
RK
376 E := First_Entity (Ent);
377 while Present (E) loop
fbf5a39b 378 Need_Blank_Line := True;
19235870 379
5e61ef09
TQ
380 -- We list entities that come from source (excluding private or
381 -- incomplete types or deferred constants, where we will list the
382 -- info for the full view). If debug flag A is set, then all
383 -- entities are listed
fbf5a39b
AC
384
385 if (Comes_From_Source (E)
386 and then not Is_Incomplete_Or_Private_Type (E)
387 and then not (Ekind (E) = E_Constant
388 and then Present (Full_View (E))))
07fc65c4
GB
389 or else Debug_Flag_AA
390 then
19992053
AC
391 if Is_Subprogram (E) then
392 List_Linker_Section (E);
393
394 if List_Representation_Info_Mechanisms then
395 List_Mechanisms (E);
396 end if;
397
1e60643a
AC
398 -- Recurse into entities local to subprogram
399
400 List_Entities (E, Bytes_Big_Endian, True);
401
402 elsif Ekind (E) in Formal_Kind and then In_Subprogram then
403 null;
404
19992053
AC
405 elsif Ekind_In (E, E_Entry,
406 E_Entry_Family,
407 E_Subprogram_Type)
fbf5a39b
AC
408 then
409 if List_Representation_Info_Mechanisms then
410 List_Mechanisms (E);
411 end if;
412
413 elsif Is_Record_Type (E) then
414 if List_Representation_Info >= 1 then
d9f8616e 415 List_Record_Info (E, Bytes_Big_Endian);
fbf5a39b 416 end if;
19235870 417
19992053
AC
418 List_Linker_Section (E);
419
19235870 420 elsif Is_Array_Type (E) then
fbf5a39b 421 if List_Representation_Info >= 1 then
d9f8616e 422 List_Array_Info (E, Bytes_Big_Endian);
fbf5a39b 423 end if;
19235870 424
19992053
AC
425 List_Linker_Section (E);
426
fbf5a39b
AC
427 elsif Is_Type (E) then
428 if List_Representation_Info >= 2 then
19235870 429 List_Type_Info (E);
19992053 430 List_Linker_Section (E);
fbf5a39b 431 end if;
19235870 432
19992053
AC
433 elsif Ekind_In (E, E_Variable, E_Constant) then
434 if List_Representation_Info >= 2 then
435 List_Object_Info (E);
436 List_Linker_Section (E);
437 end if;
438
439 elsif Ekind (E) = E_Loop_Parameter or else Is_Formal (E) then
fbf5a39b 440 if List_Representation_Info >= 2 then
19235870
RK
441 List_Object_Info (E);
442 end if;
443 end if;
444
5e61ef09
TQ
445 -- Recurse into nested package, but not if they are package
446 -- renamings (in particular renamings of the enclosing package,
447 -- as for some Java bindings and for generic instances).
19235870 448
07fc65c4
GB
449 if Ekind (E) = E_Package then
450 if No (Renamed_Object (E)) then
d9f8616e 451 List_Entities (E, Bytes_Big_Endian);
07fc65c4
GB
452 end if;
453
454 -- Recurse into bodies
455
19992053
AC
456 elsif Ekind_In (E, E_Protected_Type,
457 E_Task_Type,
458 E_Subprogram_Body,
459 E_Package_Body,
460 E_Task_Body,
461 E_Protected_Body)
19235870 462 then
d9f8616e 463 List_Entities (E, Bytes_Big_Endian);
07fc65c4
GB
464
465 -- Recurse into blocks
466
467 elsif Ekind (E) = E_Block then
d9f8616e 468 List_Entities (E, Bytes_Big_Endian);
19235870
RK
469 end if;
470 end if;
471
472 E := Next_Entity (E);
473 end loop;
fbf5a39b 474
5e61ef09
TQ
475 -- For a package body, the entities of the visible subprograms are
476 -- declared in the corresponding spec. Iterate over its entities in
477 -- order to handle properly the subprogram bodies. Skip bodies in
478 -- subunits, which are listed independently.
fbf5a39b
AC
479
480 if Ekind (Ent) = E_Package_Body
481 and then Present (Corresponding_Spec (Find_Declaration (Ent)))
482 then
483 E := First_Entity (Corresponding_Spec (Find_Declaration (Ent)));
fbf5a39b
AC
484 while Present (E) loop
485 if Is_Subprogram (E)
486 and then
487 Nkind (Find_Declaration (E)) = N_Subprogram_Declaration
488 then
489 Body_E := Corresponding_Body (Find_Declaration (E));
490
491 if Present (Body_E)
492 and then
493 Nkind (Parent (Find_Declaration (Body_E))) /= N_Subunit
494 then
d9f8616e 495 List_Entities (Body_E, Bytes_Big_Endian);
fbf5a39b
AC
496 end if;
497 end if;
498
499 Next_Entity (E);
500 end loop;
501 end if;
19235870
RK
502 end if;
503 end List_Entities;
504
505 -------------------------
506 -- List_GCC_Expression --
507 -------------------------
508
509 procedure List_GCC_Expression (U : Node_Ref_Or_Val) is
510
fbf5a39b 511 procedure Print_Expr (Val : Node_Ref_Or_Val);
19235870
RK
512 -- Internal recursive procedure to print expression
513
fbf5a39b
AC
514 ----------------
515 -- Print_Expr --
516 ----------------
517
518 procedure Print_Expr (Val : Node_Ref_Or_Val) is
19235870
RK
519 begin
520 if Val >= 0 then
521 UI_Write (Val, Decimal);
522
523 else
524 declare
525 Node : Exp_Node renames Rep_Table.Table (-UI_To_Int (Val));
526
527 procedure Binop (S : String);
528 -- Output text for binary operator with S being operator name
529
fbf5a39b
AC
530 -----------
531 -- Binop --
532 -----------
533
19235870
RK
534 procedure Binop (S : String) is
535 begin
536 Write_Char ('(');
fbf5a39b 537 Print_Expr (Node.Op1);
19235870 538 Write_Str (S);
fbf5a39b 539 Print_Expr (Node.Op2);
19235870
RK
540 Write_Char (')');
541 end Binop;
542
fbf5a39b 543 -- Start of processing for Print_Expr
19235870
RK
544
545 begin
546 case Node.Expr is
547 when Cond_Expr =>
548 Write_Str ("(if ");
fbf5a39b 549 Print_Expr (Node.Op1);
19235870 550 Write_Str (" then ");
fbf5a39b 551 Print_Expr (Node.Op2);
19235870 552 Write_Str (" else ");
fbf5a39b 553 Print_Expr (Node.Op3);
19235870
RK
554 Write_Str (" end)");
555
556 when Plus_Expr =>
557 Binop (" + ");
558
559 when Minus_Expr =>
560 Binop (" - ");
561
562 when Mult_Expr =>
563 Binop (" * ");
564
565 when Trunc_Div_Expr =>
566 Binop (" /t ");
567
568 when Ceil_Div_Expr =>
569 Binop (" /c ");
570
571 when Floor_Div_Expr =>
572 Binop (" /f ");
573
574 when Trunc_Mod_Expr =>
575 Binop (" modt ");
576
577 when Floor_Mod_Expr =>
578 Binop (" modf ");
579
580 when Ceil_Mod_Expr =>
581 Binop (" modc ");
582
583 when Exact_Div_Expr =>
584 Binop (" /e ");
585
586 when Negate_Expr =>
587 Write_Char ('-');
fbf5a39b 588 Print_Expr (Node.Op1);
19235870
RK
589
590 when Min_Expr =>
591 Binop (" min ");
592
593 when Max_Expr =>
594 Binop (" max ");
595
596 when Abs_Expr =>
597 Write_Str ("abs ");
fbf5a39b 598 Print_Expr (Node.Op1);
19235870
RK
599
600 when Truth_Andif_Expr =>
601 Binop (" and if ");
602
603 when Truth_Orif_Expr =>
604 Binop (" or if ");
605
606 when Truth_And_Expr =>
607 Binop (" and ");
608
609 when Truth_Or_Expr =>
610 Binop (" or ");
611
612 when Truth_Xor_Expr =>
613 Binop (" xor ");
614
615 when Truth_Not_Expr =>
616 Write_Str ("not ");
fbf5a39b 617 Print_Expr (Node.Op1);
19235870 618
5e61ef09
TQ
619 when Bit_And_Expr =>
620 Binop (" & ");
621
19235870
RK
622 when Lt_Expr =>
623 Binop (" < ");
624
625 when Le_Expr =>
626 Binop (" <= ");
627
628 when Gt_Expr =>
629 Binop (" > ");
630
631 when Ge_Expr =>
632 Binop (" >= ");
633
634 when Eq_Expr =>
635 Binop (" == ");
636
637 when Ne_Expr =>
638 Binop (" != ");
639
640 when Discrim_Val =>
641 Write_Char ('#');
642 UI_Write (Node.Op1);
e45f84a5
EB
643
644 when Dynamic_Val =>
645 Write_Str ("Var");
646 UI_Write (Node.Op1);
19235870
RK
647 end case;
648 end;
649 end if;
fbf5a39b 650 end Print_Expr;
19235870
RK
651
652 -- Start of processing for List_GCC_Expression
653
654 begin
655 if U = No_Uint then
07fc65c4 656 Write_Str ("??");
19235870 657 else
fbf5a39b 658 Print_Expr (U);
19235870
RK
659 end if;
660 end List_GCC_Expression;
661
19992053
AC
662 -------------------------
663 -- List_Linker_Section --
664 -------------------------
665
666 procedure List_Linker_Section (Ent : Entity_Id) is
667 Arg : Node_Id;
668
669 begin
670 if Present (Linker_Section_Pragma (Ent)) then
671 Write_Str ("pragma Linker_Section (");
672 List_Name (Ent);
673 Write_Str (", """);
674
675 Arg :=
676 Last (Pragma_Argument_Associations (Linker_Section_Pragma (Ent)));
677
678 if Nkind (Arg) = N_Pragma_Argument_Association then
679 Arg := Expression (Arg);
680 end if;
681
682 pragma Assert (Nkind (Arg) = N_String_Literal);
683 String_To_Name_Buffer (Strval (Arg));
684 Write_Str (Name_Buffer (1 .. Name_Len));
685 Write_Str (""");");
686 Write_Eol;
687 end if;
688 end List_Linker_Section;
689
fbf5a39b
AC
690 ---------------------
691 -- List_Mechanisms --
692 ---------------------
693
694 procedure List_Mechanisms (Ent : Entity_Id) is
695 Plen : Natural;
696 Form : Entity_Id;
697
698 begin
699 Blank_Line;
700
701 case Ekind (Ent) is
702 when E_Function =>
703 Write_Str ("function ");
704
705 when E_Operator =>
706 Write_Str ("operator ");
707
708 when E_Procedure =>
709 Write_Str ("procedure ");
710
711 when E_Subprogram_Type =>
712 Write_Str ("type ");
713
d8f43ee6
HK
714 when E_Entry
715 | E_Entry_Family
716 =>
fbf5a39b
AC
717 Write_Str ("entry ");
718
719 when others =>
720 raise Program_Error;
721 end case;
722
723 Get_Unqualified_Decoded_Name_String (Chars (Ent));
724 Write_Str (Name_Buffer (1 .. Name_Len));
725 Write_Str (" declared at ");
726 Write_Location (Sloc (Ent));
727 Write_Eol;
728
729 Write_Str (" convention : ");
730
731 case Convention (Ent) is
d8f43ee6 732 when Convention_Ada =>
e917aec2 733 Write_Line ("Ada");
d8f43ee6
HK
734
735 when Convention_Ada_Pass_By_Copy =>
e917aec2 736 Write_Line ("Ada_Pass_By_Copy");
d8f43ee6 737
e917aec2
RD
738 when Convention_Ada_Pass_By_Reference =>
739 Write_Line ("Ada_Pass_By_Reference");
d8f43ee6
HK
740
741 when Convention_Intrinsic =>
e917aec2 742 Write_Line ("Intrinsic");
d8f43ee6
HK
743
744 when Convention_Entry =>
e917aec2 745 Write_Line ("Entry");
d8f43ee6
HK
746
747 when Convention_Protected =>
e917aec2 748 Write_Line ("Protected");
d8f43ee6
HK
749
750 when Convention_Assembler =>
e917aec2 751 Write_Line ("Assembler");
d8f43ee6
HK
752
753 when Convention_C =>
e917aec2 754 Write_Line ("C");
d8f43ee6
HK
755
756 when Convention_COBOL =>
e917aec2 757 Write_Line ("COBOL");
d8f43ee6
HK
758
759 when Convention_CPP =>
e917aec2 760 Write_Line ("C++");
d8f43ee6
HK
761
762 when Convention_Fortran =>
e917aec2 763 Write_Line ("Fortran");
d8f43ee6
HK
764
765 when Convention_Stdcall =>
e917aec2 766 Write_Line ("Stdcall");
d8f43ee6
HK
767
768 when Convention_Stubbed =>
e917aec2 769 Write_Line ("Stubbed");
fbf5a39b
AC
770 end case;
771
772 -- Find max length of formal name
773
774 Plen := 0;
775 Form := First_Formal (Ent);
776 while Present (Form) loop
777 Get_Unqualified_Decoded_Name_String (Chars (Form));
778
779 if Name_Len > Plen then
780 Plen := Name_Len;
781 end if;
782
783 Next_Formal (Form);
784 end loop;
785
786 -- Output formals and mechanisms
787
788 Form := First_Formal (Ent);
789 while Present (Form) loop
790 Get_Unqualified_Decoded_Name_String (Chars (Form));
fbf5a39b
AC
791 while Name_Len <= Plen loop
792 Name_Len := Name_Len + 1;
793 Name_Buffer (Name_Len) := ' ';
794 end loop;
795
796 Write_Str (" ");
797 Write_Str (Name_Buffer (1 .. Plen + 1));
798 Write_Str (": passed by ");
799
800 Write_Mechanism (Mechanism (Form));
801 Write_Eol;
802 Next_Formal (Form);
803 end loop;
804
805 if Etype (Ent) /= Standard_Void_Type then
806 Write_Str (" returns by ");
807 Write_Mechanism (Mechanism (Ent));
808 Write_Eol;
809 end if;
810 end List_Mechanisms;
811
19235870
RK
812 ---------------
813 -- List_Name --
814 ---------------
815
816 procedure List_Name (Ent : Entity_Id) is
817 begin
818 if not Is_Compilation_Unit (Scope (Ent)) then
819 List_Name (Scope (Ent));
820 Write_Char ('.');
821 end if;
822
823 Get_Unqualified_Decoded_Name_String (Chars (Ent));
824 Set_Casing (Unit_Casing);
825 Write_Str (Name_Buffer (1 .. Name_Len));
826 end List_Name;
827
828 ---------------------
829 -- List_Object_Info --
830 ---------------------
831
832 procedure List_Object_Info (Ent : Entity_Id) is
833 begin
fbf5a39b 834 Blank_Line;
19235870 835
07fc65c4
GB
836 Write_Str ("for ");
837 List_Name (Ent);
838 Write_Str ("'Size use ");
839 Write_Val (Esize (Ent));
840 Write_Line (";");
19235870 841
07fc65c4
GB
842 Write_Str ("for ");
843 List_Name (Ent);
844 Write_Str ("'Alignment use ");
845 Write_Val (Alignment (Ent));
846 Write_Line (";");
19235870
RK
847 end List_Object_Info;
848
849 ----------------------
850 -- List_Record_Info --
851 ----------------------
852
d9f8616e 853 procedure List_Record_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean) is
1c912574
AC
854 procedure Compute_Max_Length
855 (Ent : Entity_Id;
856 Starting_Position : Uint := Uint_0;
857 Starting_First_Bit : Uint := Uint_0;
858 Prefix_Length : Natural := 0);
859 -- Internal recursive procedure to compute the max length
860
861 procedure List_Record_Layout
862 (Ent : Entity_Id;
863 Starting_Position : Uint := Uint_0;
864 Starting_First_Bit : Uint := Uint_0;
865 Prefix : String := "");
866 -- Internal recursive procedure to display the layout
867
868 Max_Name_Length : Natural := 0;
869 Max_Spos_Length : Natural := 0;
870
871 ------------------------
872 -- Compute_Max_Length --
873 ------------------------
874
875 procedure Compute_Max_Length
876 (Ent : Entity_Id;
877 Starting_Position : Uint := Uint_0;
878 Starting_First_Bit : Uint := Uint_0;
879 Prefix_Length : Natural := 0)
880 is
3815f967 881 Comp : Entity_Id;
19235870 882
1c912574
AC
883 begin
884 Comp := First_Component_Or_Discriminant (Ent);
885 while Present (Comp) loop
19235870 886
1c912574 887 -- Skip discriminant in unchecked union (since it is not there!)
19235870 888
1c912574
AC
889 if Ekind (Comp) = E_Discriminant
890 and then Is_Unchecked_Union (Ent)
891 then
892 goto Continue;
893 end if;
19235870 894
1c912574 895 -- All other cases
19235870 896
1c912574
AC
897 declare
898 Ctyp : constant Entity_Id := Underlying_Type (Etype (Comp));
899 Bofs : constant Uint := Component_Bit_Offset (Comp);
900 Npos : Uint;
901 Fbit : Uint;
902 Spos : Uint;
903 Sbit : Uint;
3815f967 904
1c912574 905 Name_Length : Natural;
3815f967 906
1c912574
AC
907 begin
908 Get_Decoded_Name_String (Chars (Comp));
909 Name_Length := Prefix_Length + Name_Len;
19235870 910
1c912574 911 if Rep_Not_Constant (Bofs) then
19235870 912
1c912574
AC
913 -- If the record is not packed, then we know that all fields
914 -- whose position is not specified have starting normalized
915 -- bit position of zero.
3fbbbd1e 916
1c912574
AC
917 if Unknown_Normalized_First_Bit (Comp)
918 and then not Is_Packed (Ent)
919 then
920 Set_Normalized_First_Bit (Comp, Uint_0);
921 end if;
19235870 922
1c912574
AC
923 UI_Image_Length := 2; -- For "??" marker
924 else
925 Npos := Bofs / SSU;
926 Fbit := Bofs mod SSU;
19235870 927
1c912574 928 -- Complete annotation in case not done
19235870 929
1c912574
AC
930 if Unknown_Normalized_First_Bit (Comp) then
931 Set_Normalized_Position (Comp, Npos);
932 Set_Normalized_First_Bit (Comp, Fbit);
933 end if;
cc3a2986 934
1c912574
AC
935 Spos := Starting_Position + Npos;
936 Sbit := Starting_First_Bit + Fbit;
3815f967 937
1c912574
AC
938 if Sbit >= SSU then
939 Spos := Spos + 1;
940 Sbit := Sbit - SSU;
941 end if;
07fc65c4 942
1c912574
AC
943 -- If extended information is requested, recurse fully into
944 -- record components, i.e. skip the outer level.
74a78a4f 945
1c912574
AC
946 if List_Representation_Info_Extended
947 and then Is_Record_Type (Ctyp)
948 then
949 Compute_Max_Length (Ctyp, Spos, Sbit, Name_Length + 1);
950 goto Continue;
951 end if;
19235870 952
1c912574 953 UI_Image (Spos);
74a78a4f 954 end if;
3fbbbd1e 955
1c912574
AC
956 Max_Name_Length := Natural'Max (Max_Name_Length, Name_Length);
957 Max_Spos_Length :=
958 Natural'Max (Max_Spos_Length, UI_Image_Length);
959 end;
19235870 960
1c912574
AC
961 <<Continue>>
962 Next_Component_Or_Discriminant (Comp);
963 end loop;
964 end Compute_Max_Length;
a9a5b8ac 965
1c912574
AC
966 ------------------------
967 -- List_Record_Layout --
968 ------------------------
19235870 969
1c912574
AC
970 procedure List_Record_Layout
971 (Ent : Entity_Id;
972 Starting_Position : Uint := Uint_0;
973 Starting_First_Bit : Uint := Uint_0;
974 Prefix : String := "")
975 is
3815f967 976 Comp : Entity_Id;
19235870 977
1c912574
AC
978 begin
979 Comp := First_Component_Or_Discriminant (Ent);
980 while Present (Comp) loop
3fbbbd1e 981
1c912574 982 -- Skip discriminant in unchecked union (since it is not there!)
3fbbbd1e 983
1c912574
AC
984 if Ekind (Comp) = E_Discriminant
985 and then Is_Unchecked_Union (Ent)
986 then
987 goto Continue;
988 end if;
3fbbbd1e 989
1c912574 990 -- All other cases
3fbbbd1e 991
1c912574
AC
992 declare
993 Ctyp : constant Entity_Id := Underlying_Type (Etype (Comp));
994 Esiz : constant Uint := Esize (Comp);
995 Bofs : constant Uint := Component_Bit_Offset (Comp);
996 Npos : constant Uint := Normalized_Position (Comp);
997 Fbit : constant Uint := Normalized_First_Bit (Comp);
998 Spos : Uint;
999 Sbit : Uint;
1000 Lbit : Uint;
a9a5b8ac 1001
1c912574
AC
1002 begin
1003 Get_Decoded_Name_String (Chars (Comp));
1004 Set_Casing (Unit_Casing);
19235870 1005
1c912574
AC
1006 -- If extended information is requested, recurse fully into
1007 -- record components, i.e. skip the outer level.
19235870 1008
1c912574
AC
1009 if List_Representation_Info_Extended
1010 and then Is_Record_Type (Ctyp)
1011 and then Known_Static_Normalized_Position (Comp)
1012 and then Known_Static_Normalized_First_Bit (Comp)
1013 then
1014 Spos := Starting_Position + Npos;
1015 Sbit := Starting_First_Bit + Fbit;
3815f967 1016
1c912574
AC
1017 if Sbit >= SSU then
1018 Spos := Spos + 1;
1019 Sbit := Sbit - SSU;
1020 end if;
3815f967 1021
1c912574
AC
1022 List_Record_Layout (Ctyp,
1023 Spos, Sbit, Prefix & Name_Buffer (1 .. Name_Len) & ".");
3815f967 1024
1c912574
AC
1025 goto Continue;
1026 end if;
19235870 1027
1c912574
AC
1028 Write_Str (" ");
1029 Write_Str (Prefix);
1030 Write_Str (Name_Buffer (1 .. Name_Len));
19235870 1031
1c912574
AC
1032 for J in 1 .. Max_Name_Length - Prefix'Length - Name_Len loop
1033 Write_Char (' ');
1034 end loop;
a9a5b8ac 1035
1c912574 1036 Write_Str (" at ");
19235870 1037
1c912574
AC
1038 if Known_Static_Normalized_Position (Comp) then
1039 Spos := Starting_Position + Npos;
1040 Sbit := Starting_First_Bit + Fbit;
3815f967 1041
1c912574
AC
1042 if Sbit >= SSU then
1043 Spos := Spos + 1;
1044 end if;
3815f967 1045
1c912574
AC
1046 UI_Image (Spos);
1047 Spaces (Max_Spos_Length - UI_Image_Length);
1048 Write_Str (UI_Image_Buffer (1 .. UI_Image_Length));
a9a5b8ac 1049
1c912574
AC
1050 elsif Known_Component_Bit_Offset (Comp)
1051 and then List_Representation_Info = 3
1052 then
1053 Spaces (Max_Spos_Length - 2);
1054 Write_Str ("bit offset");
3815f967 1055
1c912574
AC
1056 if Starting_Position /= Uint_0
1057 or else Starting_First_Bit /= Uint_0
1058 then
1059 Write_Char (' ');
1060 UI_Write (Starting_Position * SSU + Starting_First_Bit);
1061 Write_Str (" +");
1062 end if;
3815f967 1063
1c912574
AC
1064 Write_Val (Bofs, Paren => True);
1065 Write_Str (" size in bits = ");
1066 Write_Val (Esiz, Paren => True);
1067 Write_Eol;
3815f967 1068
07fc65c4 1069 goto Continue;
19235870 1070
1c912574
AC
1071 elsif Known_Normalized_Position (Comp)
1072 and then List_Representation_Info = 3
1073 then
1074 Spaces (Max_Spos_Length - 2);
3815f967 1075
1c912574
AC
1076 if Starting_Position /= Uint_0 then
1077 Write_Char (' ');
1078 UI_Write (Starting_Position);
1079 Write_Str (" +");
1080 end if;
3815f967 1081
1c912574 1082 Write_Val (Npos);
19235870
RK
1083
1084 else
1c912574
AC
1085 -- For the packed case, we don't know the bit positions if
1086 -- we don't know the starting position.
19235870 1087
1c912574
AC
1088 if Is_Packed (Ent) then
1089 Write_Line ("?? range ? .. ??;");
1090 goto Continue;
19235870 1091
1c912574 1092 -- Otherwise we can continue
07fc65c4 1093
1c912574
AC
1094 else
1095 Write_Str ("??");
1096 end if;
1097 end if;
19235870 1098
1c912574
AC
1099 Write_Str (" range ");
1100 Sbit := Starting_First_Bit + Fbit;
3815f967 1101
1c912574
AC
1102 if Sbit >= SSU then
1103 Sbit := Sbit - SSU;
a9a5b8ac 1104 end if;
3815f967 1105
1c912574
AC
1106 UI_Write (Sbit);
1107 Write_Str (" .. ");
19235870 1108
1c912574
AC
1109 -- Allowing Uint_0 here is an annoying special case. Really
1110 -- this should be a fine Esize value but currently it means
1111 -- unknown, except that we know after gigi has back annotated
1112 -- that a size of zero is real, since otherwise gigi back
1113 -- annotates using No_Uint as the value to indicate unknown).
19235870 1114
1c912574
AC
1115 if (Esize (Comp) = Uint_0 or else Known_Static_Esize (Comp))
1116 and then Known_Static_Normalized_First_Bit (Comp)
1117 then
1118 Lbit := Sbit + Esiz - 1;
07fc65c4 1119
1c912574
AC
1120 if Lbit < 10 then
1121 Write_Char (' ');
1122 end if;
19235870 1123
1c912574 1124 UI_Write (Lbit);
19235870 1125
1c912574
AC
1126 -- The test for Esize (Comp) not Uint_0 here is an annoying
1127 -- special case. Officially a value of zero for Esize means
1128 -- unknown, but here we use the fact that we know that gigi
1129 -- annotates Esize with No_Uint, not Uint_0. Really everyone
1130 -- should use No_Uint???
19235870 1131
1c912574
AC
1132 elsif List_Representation_Info < 3
1133 or else (Esize (Comp) /= Uint_0 and then Unknown_Esize (Comp))
1134 then
1135 Write_Str ("??");
19235870 1136
1c912574 1137 -- List_Representation >= 3 and Known_Esize (Comp)
19235870 1138
1c912574
AC
1139 else
1140 Write_Val (Esiz, Paren => True);
19235870 1141
1c912574
AC
1142 -- If in front end layout mode, then dynamic size is stored
1143 -- in storage units, so renormalize for output
19235870 1144
1c912574
AC
1145 if not Back_End_Layout then
1146 Write_Str (" * ");
1147 Write_Int (SSU);
1148 end if;
19235870 1149
1c912574
AC
1150 -- Add appropriate first bit offset
1151
1152 if Sbit = 0 then
1153 Write_Str (" - 1");
1154
1155 elsif Sbit = 1 then
1156 null;
1157
1158 else
1159 Write_Str (" + ");
1160 Write_Int (UI_To_Int (Sbit) - 1);
1161 end if;
19235870
RK
1162 end if;
1163
1c912574
AC
1164 Write_Line (";");
1165 end;
19235870 1166
1c912574
AC
1167 <<Continue>>
1168 Next_Component_Or_Discriminant (Comp);
1169 end loop;
1170 end List_Record_Layout;
1171
3815f967
AC
1172 -- Start of processing for List_Record_Info
1173
1c912574
AC
1174 begin
1175 Blank_Line;
1176 List_Type_Info (Ent);
1177
1178 Write_Str ("for ");
1179 List_Name (Ent);
1180 Write_Line (" use record");
1181
1182 -- First find out max line length and max starting position
1183 -- length, for the purpose of lining things up nicely.
1184
1185 Compute_Max_Length (Ent);
1186
1187 -- Then do actual output based on those values
1188
1189 List_Record_Layout (Ent);
19235870
RK
1190
1191 Write_Line ("end record;");
d9f8616e
AC
1192
1193 List_Scalar_Storage_Order (Ent, Bytes_Big_Endian);
19235870
RK
1194 end List_Record_Info;
1195
1196 -------------------
1197 -- List_Rep_Info --
1198 -------------------
1199
d9f8616e 1200 procedure List_Rep_Info (Bytes_Big_Endian : Boolean) is
19235870
RK
1201 Col : Nat;
1202
1203 begin
fbf5a39b
AC
1204 if List_Representation_Info /= 0
1205 or else List_Representation_Info_Mechanisms
1206 then
1207 for U in Main_Unit .. Last_Unit loop
1208 if In_Extended_Main_Source_Unit (Cunit_Entity (U)) then
d436b30d 1209 Unit_Casing := Identifier_Casing (Source_Index (U));
07fc65c4 1210
fbf5a39b 1211 -- Normal case, list to standard output
07fc65c4 1212
fbf5a39b 1213 if not List_Representation_Info_To_File then
fbf5a39b
AC
1214 Write_Eol;
1215 Write_Str ("Representation information for unit ");
1216 Write_Unit_Name (Unit_Name (U));
1217 Col := Column;
1218 Write_Eol;
1219
1220 for J in 1 .. Col - 1 loop
1221 Write_Char ('-');
1222 end loop;
07fc65c4 1223
fbf5a39b 1224 Write_Eol;
d9f8616e 1225 List_Entities (Cunit_Entity (U), Bytes_Big_Endian);
07fc65c4 1226
fbf5a39b 1227 -- List representation information to file
07fc65c4 1228
fbf5a39b 1229 else
d3879a5a 1230 Create_Repinfo_File_Access.all
1c28fe3a 1231 (Get_Name_String (File_Name (Source_Index (U))));
fbf5a39b 1232 Set_Special_Output (Write_Info_Line'Access);
d9f8616e 1233 List_Entities (Cunit_Entity (U), Bytes_Big_Endian);
fbf5a39b
AC
1234 Set_Special_Output (null);
1235 Close_Repinfo_File_Access.all;
1236 end if;
07fc65c4 1237 end if;
fbf5a39b
AC
1238 end loop;
1239 end if;
19235870
RK
1240 end List_Rep_Info;
1241
d9f8616e
AC
1242 -------------------------------
1243 -- List_Scalar_Storage_Order --
1244 -------------------------------
1245
1246 procedure List_Scalar_Storage_Order
1247 (Ent : Entity_Id;
1248 Bytes_Big_Endian : Boolean)
1249 is
7ed57189
AC
1250 procedure List_Attr (Attr_Name : String; Is_Reversed : Boolean);
1251 -- Show attribute definition clause for Attr_Name (an endianness
1252 -- attribute), depending on whether or not the endianness is reversed
1253 -- compared to native endianness.
d9f8616e
AC
1254
1255 ---------------
1256 -- List_Attr --
1257 ---------------
1258
7ed57189 1259 procedure List_Attr (Attr_Name : String; Is_Reversed : Boolean) is
d9f8616e
AC
1260 begin
1261 Write_Str ("for ");
1262 List_Name (Ent);
1263 Write_Str ("'" & Attr_Name & " use System.");
489c6e19 1264
7ed57189 1265 if Bytes_Big_Endian xor Is_Reversed then
d9f8616e
AC
1266 Write_Str ("High");
1267 else
1268 Write_Str ("Low");
1269 end if;
489c6e19 1270
d9f8616e
AC
1271 Write_Line ("_Order_First;");
1272 end List_Attr;
1273
7ed57189
AC
1274 List_SSO : constant Boolean :=
1275 Has_Rep_Item (Ent, Name_Scalar_Storage_Order)
1276 or else SSO_Set_Low_By_Default (Ent)
1277 or else SSO_Set_High_By_Default (Ent);
1278 -- Scalar_Storage_Order is displayed if specified explicitly
1279 -- or set by Default_Scalar_Storage_Order.
1280
d9f8616e
AC
1281 -- Start of processing for List_Scalar_Storage_Order
1282
1283 begin
7ed57189 1284 -- For record types, list Bit_Order if not default, or if SSO is shown
d9f8616e 1285
7ed57189
AC
1286 if Is_Record_Type (Ent)
1287 and then (List_SSO or else Reverse_Bit_Order (Ent))
220d1fd9 1288 then
7ed57189
AC
1289 List_Attr ("Bit_Order", Reverse_Bit_Order (Ent));
1290 end if;
d9f8616e 1291
7ed57189
AC
1292 -- List SSO if required. If not, then storage is supposed to be in
1293 -- native order.
489c6e19 1294
7ed57189
AC
1295 if List_SSO then
1296 List_Attr ("Scalar_Storage_Order", Reverse_Storage_Order (Ent));
1297 else
1298 pragma Assert (not Reverse_Storage_Order (Ent));
1299 null;
d9f8616e
AC
1300 end if;
1301 end List_Scalar_Storage_Order;
1302
19235870
RK
1303 --------------------
1304 -- List_Type_Info --
1305 --------------------
1306
1307 procedure List_Type_Info (Ent : Entity_Id) is
1308 begin
fbf5a39b 1309 Blank_Line;
19235870 1310
07fc65c4
GB
1311 -- Do not list size info for unconstrained arrays, not meaningful
1312
1313 if Is_Array_Type (Ent) and then not Is_Constrained (Ent) then
1314 null;
1315
1316 else
1317 -- If Esize and RM_Size are the same and known, list as Size. This
1318 -- is a common case, which we may as well list in simple form.
19235870 1319
07fc65c4 1320 if Esize (Ent) = RM_Size (Ent) then
19235870
RK
1321 Write_Str ("for ");
1322 List_Name (Ent);
1323 Write_Str ("'Size use ");
1324 Write_Val (Esize (Ent));
1325 Write_Line (";");
19235870 1326
07fc65c4 1327 -- For now, temporary case, to be removed when gigi properly back
5e61ef09
TQ
1328 -- annotates RM_Size, if RM_Size is not set, then list Esize as Size.
1329 -- This avoids odd Object_Size output till we fix things???
19235870 1330
07fc65c4 1331 elsif Unknown_RM_Size (Ent) then
19235870
RK
1332 Write_Str ("for ");
1333 List_Name (Ent);
1334 Write_Str ("'Size use ");
1335 Write_Val (Esize (Ent));
1336 Write_Line (";");
19235870 1337
07fc65c4 1338 -- Otherwise list size values separately if they are set
19235870 1339
07fc65c4 1340 else
19235870
RK
1341 Write_Str ("for ");
1342 List_Name (Ent);
1343 Write_Str ("'Object_Size use ");
1344 Write_Val (Esize (Ent));
1345 Write_Line (";");
19235870 1346
07fc65c4
GB
1347 -- Note on following check: The RM_Size of a discrete type can
1348 -- legitimately be set to zero, so a special check is needed.
19235870 1349
19235870
RK
1350 Write_Str ("for ");
1351 List_Name (Ent);
1352 Write_Str ("'Value_Size use ");
1353 Write_Val (RM_Size (Ent));
1354 Write_Line (";");
1355 end if;
1356 end if;
1357
07fc65c4
GB
1358 Write_Str ("for ");
1359 List_Name (Ent);
1360 Write_Str ("'Alignment use ");
1361 Write_Val (Alignment (Ent));
1362 Write_Line (";");
0d57c6f4
RD
1363
1364 -- Special stuff for fixed-point
1365
1366 if Is_Fixed_Point_Type (Ent) then
1367
1368 -- Write small (always a static constant)
1369
1370 Write_Str ("for ");
1371 List_Name (Ent);
1372 Write_Str ("'Small use ");
1373 UR_Write (Small_Value (Ent));
1374 Write_Line (";");
1375
1376 -- Write range if static
1377
1378 declare
1379 R : constant Node_Id := Scalar_Range (Ent);
1380
1381 begin
1382 if Nkind (Low_Bound (R)) = N_Real_Literal
1383 and then
1384 Nkind (High_Bound (R)) = N_Real_Literal
1385 then
1386 Write_Str ("for ");
1387 List_Name (Ent);
1388 Write_Str ("'Range use ");
1389 UR_Write (Realval (Low_Bound (R)));
1390 Write_Str (" .. ");
1391 UR_Write (Realval (High_Bound (R)));
1392 Write_Line (";");
1393 end if;
1394 end;
1395 end if;
19235870
RK
1396 end List_Type_Info;
1397
1398 ----------------------
1399 -- Rep_Not_Constant --
1400 ----------------------
1401
1402 function Rep_Not_Constant (Val : Node_Ref_Or_Val) return Boolean is
1403 begin
1404 if Val = No_Uint or else Val < 0 then
1405 return True;
1406 else
1407 return False;
1408 end if;
1409 end Rep_Not_Constant;
1410
1411 ---------------
1412 -- Rep_Value --
1413 ---------------
1414
1415 function Rep_Value
a4c1cd80
AC
1416 (Val : Node_Ref_Or_Val;
1417 D : Discrim_List) return Uint
19235870
RK
1418 is
1419 function B (Val : Boolean) return Uint;
1420 -- Returns Uint_0 for False, Uint_1 for True
1421
1422 function T (Val : Node_Ref_Or_Val) return Boolean;
1423 -- Returns True for 0, False for any non-zero (i.e. True)
1424
1425 function V (Val : Node_Ref_Or_Val) return Uint;
1426 -- Internal recursive routine to evaluate tree
1427
5e61ef09 1428 function W (Val : Uint) return Word;
0d57c6f4
RD
1429 -- Convert Val to Word, assuming Val is always in the Int range. This
1430 -- is a helper function for the evaluation of bitwise expressions like
5e61ef09
TQ
1431 -- Bit_And_Expr, for which there is no direct support in uintp. Uint
1432 -- values out of the Int range are expected to be seen in such
1433 -- expressions only with overflowing byte sizes around, introducing
276e95ca 1434 -- inherent unreliabilities in computations anyway.
5e61ef09 1435
19235870
RK
1436 -------
1437 -- B --
1438 -------
1439
1440 function B (Val : Boolean) return Uint is
1441 begin
1442 if Val then
1443 return Uint_1;
1444 else
1445 return Uint_0;
1446 end if;
1447 end B;
1448
1449 -------
1450 -- T --
1451 -------
1452
1453 function T (Val : Node_Ref_Or_Val) return Boolean is
1454 begin
1455 if V (Val) = 0 then
1456 return False;
1457 else
1458 return True;
1459 end if;
1460 end T;
1461
1462 -------
1463 -- V --
1464 -------
1465
1466 function V (Val : Node_Ref_Or_Val) return Uint is
1467 L, R, Q : Uint;
1468
1469 begin
1470 if Val >= 0 then
1471 return Val;
1472
1473 else
1474 declare
1475 Node : Exp_Node renames Rep_Table.Table (-UI_To_Int (Val));
1476
1477 begin
1478 case Node.Expr is
1479 when Cond_Expr =>
1480 if T (Node.Op1) then
1481 return V (Node.Op2);
1482 else
1483 return V (Node.Op3);
1484 end if;
1485
1486 when Plus_Expr =>
1487 return V (Node.Op1) + V (Node.Op2);
1488
1489 when Minus_Expr =>
1490 return V (Node.Op1) - V (Node.Op2);
1491
1492 when Mult_Expr =>
1493 return V (Node.Op1) * V (Node.Op2);
1494
1495 when Trunc_Div_Expr =>
1496 return V (Node.Op1) / V (Node.Op2);
1497
1498 when Ceil_Div_Expr =>
1499 return
1500 UR_Ceiling
1501 (V (Node.Op1) / UR_From_Uint (V (Node.Op2)));
1502
1503 when Floor_Div_Expr =>
1504 return
1505 UR_Floor
1506 (V (Node.Op1) / UR_From_Uint (V (Node.Op2)));
1507
1508 when Trunc_Mod_Expr =>
1509 return V (Node.Op1) rem V (Node.Op2);
1510
1511 when Floor_Mod_Expr =>
1512 return V (Node.Op1) mod V (Node.Op2);
1513
1514 when Ceil_Mod_Expr =>
1515 L := V (Node.Op1);
1516 R := V (Node.Op2);
1517 Q := UR_Ceiling (L / UR_From_Uint (R));
1518 return L - R * Q;
1519
1520 when Exact_Div_Expr =>
1521 return V (Node.Op1) / V (Node.Op2);
1522
1523 when Negate_Expr =>
1524 return -V (Node.Op1);
1525
1526 when Min_Expr =>
1527 return UI_Min (V (Node.Op1), V (Node.Op2));
1528
1529 when Max_Expr =>
1530 return UI_Max (V (Node.Op1), V (Node.Op2));
1531
1532 when Abs_Expr =>
1533 return UI_Abs (V (Node.Op1));
1534
1535 when Truth_Andif_Expr =>
1536 return B (T (Node.Op1) and then T (Node.Op2));
1537
1538 when Truth_Orif_Expr =>
1539 return B (T (Node.Op1) or else T (Node.Op2));
1540
1541 when Truth_And_Expr =>
d1ced162 1542 return B (T (Node.Op1) and then T (Node.Op2));
19235870
RK
1543
1544 when Truth_Or_Expr =>
d1ced162 1545 return B (T (Node.Op1) or else T (Node.Op2));
19235870
RK
1546
1547 when Truth_Xor_Expr =>
1548 return B (T (Node.Op1) xor T (Node.Op2));
1549
1550 when Truth_Not_Expr =>
1551 return B (not T (Node.Op1));
1552
5e61ef09
TQ
1553 when Bit_And_Expr =>
1554 L := V (Node.Op1);
1555 R := V (Node.Op2);
1556 return UI_From_Int (Int (W (L) and W (R)));
1557
19235870
RK
1558 when Lt_Expr =>
1559 return B (V (Node.Op1) < V (Node.Op2));
1560
1561 when Le_Expr =>
1562 return B (V (Node.Op1) <= V (Node.Op2));
1563
1564 when Gt_Expr =>
1565 return B (V (Node.Op1) > V (Node.Op2));
1566
1567 when Ge_Expr =>
1568 return B (V (Node.Op1) >= V (Node.Op2));
1569
1570 when Eq_Expr =>
1571 return B (V (Node.Op1) = V (Node.Op2));
1572
1573 when Ne_Expr =>
1574 return B (V (Node.Op1) /= V (Node.Op2));
1575
1576 when Discrim_Val =>
1577 declare
1578 Sub : constant Int := UI_To_Int (Node.Op1);
19235870
RK
1579 begin
1580 pragma Assert (Sub in D'Range);
1581 return D (Sub);
1582 end;
e45f84a5
EB
1583
1584 when Dynamic_Val =>
1585 return No_Uint;
19235870
RK
1586 end case;
1587 end;
1588 end if;
1589 end V;
1590
d3879a5a
RD
1591 -------
1592 -- W --
1593 -------
1594
1595 -- We use an unchecked conversion to map Int values to their Word
1596 -- bitwise equivalent, which we could not achieve with a normal type
1597 -- conversion for negative Ints. We want bitwise equivalents because W
1598 -- is used as a helper for bit operators like Bit_And_Expr, and can be
1599 -- called for negative Ints in the context of aligning expressions like
1600 -- X+Align & -Align.
1601
1602 function W (Val : Uint) return Word is
1603 function To_Word is new Ada.Unchecked_Conversion (Int, Word);
1604 begin
1605 return To_Word (UI_To_Int (Val));
1606 end W;
1607
19235870
RK
1608 -- Start of processing for Rep_Value
1609
1610 begin
1611 if Val = No_Uint then
1612 return No_Uint;
1613
1614 else
1615 return V (Val);
1616 end if;
1617 end Rep_Value;
1618
1619 ------------
1620 -- Spaces --
1621 ------------
1622
1623 procedure Spaces (N : Natural) is
1624 begin
1625 for J in 1 .. N loop
1626 Write_Char (' ');
1627 end loop;
1628 end Spaces;
1629
1630 ---------------
1631 -- Tree_Read --
1632 ---------------
1633
1634 procedure Tree_Read is
1635 begin
1636 Rep_Table.Tree_Read;
1637 end Tree_Read;
1638
1639 ----------------
1640 -- Tree_Write --
1641 ----------------
1642
1643 procedure Tree_Write is
1644 begin
1645 Rep_Table.Tree_Write;
1646 end Tree_Write;
1647
fbf5a39b
AC
1648 ---------------------
1649 -- Write_Info_Line --
1650 ---------------------
1651
1652 procedure Write_Info_Line (S : String) is
1653 begin
1654 Write_Repinfo_Line_Access.all (S (S'First .. S'Last - 1));
1655 end Write_Info_Line;
1656
1657 ---------------------
1658 -- Write_Mechanism --
1659 ---------------------
1660
1661 procedure Write_Mechanism (M : Mechanism_Type) is
1662 begin
1663 case M is
1664 when 0 =>
1665 Write_Str ("default");
1666
1667 when -1 =>
1668 Write_Str ("copy");
1669
1670 when -2 =>
1671 Write_Str ("reference");
1672
fbf5a39b
AC
1673 when others =>
1674 raise Program_Error;
1675 end case;
1676 end Write_Mechanism;
1677
19235870
RK
1678 ---------------
1679 -- Write_Val --
1680 ---------------
1681
1682 procedure Write_Val (Val : Node_Ref_Or_Val; Paren : Boolean := False) is
1683 begin
1684 if Rep_Not_Constant (Val) then
07fc65c4 1685 if List_Representation_Info < 3 or else Val = No_Uint then
19235870 1686 Write_Str ("??");
07fc65c4 1687
19235870
RK
1688 else
1689 if Back_End_Layout then
1690 Write_Char (' ');
07fc65c4
GB
1691
1692 if Paren then
1693 Write_Char ('(');
1694 List_GCC_Expression (Val);
1695 Write_Char (')');
1696 else
1697 List_GCC_Expression (Val);
1698 end if;
1699
19235870 1700 Write_Char (' ');
07fc65c4 1701
19235870 1702 else
07fc65c4
GB
1703 if Paren then
1704 Write_Char ('(');
1705 Write_Name_Decoded (Chars (Get_Dynamic_SO_Entity (Val)));
1706 Write_Char (')');
1707 else
1708 Write_Name_Decoded (Chars (Get_Dynamic_SO_Entity (Val)));
1709 end if;
19235870
RK
1710 end if;
1711 end if;
1712
1713 else
1714 UI_Write (Val);
1715 end if;
1716 end Write_Val;
1717
1718end Repinfo;