]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ada/repinfo.adb
[Ada] Iterate with procedural versions of Next_... routines where possible
[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-- --
4b490c1e 9-- Copyright (C) 1999-2020, 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;
19992053 46with Stringt; use Stringt;
851e9f19 47with Table;
d9f8616e
AC
48with Uname; use Uname;
49with Urealp; use Urealp;
19235870 50
5e61ef09
TQ
51with Ada.Unchecked_Conversion;
52
b5f581cd
EB
53with GNAT.HTable;
54
19235870
RK
55package body Repinfo is
56
57 SSU : constant := 8;
58 -- Value for Storage_Unit, we do not want to get this from TTypes, since
59 -- this introduces problematic dependencies in ASIS, and in any case this
60 -- value is assumed to be 8 for the implementation of the DDA.
fbf5a39b 61
19235870 62 ---------------------------------------
e45f84a5 63 -- Representation of GCC Expressions --
19235870
RK
64 ---------------------------------------
65
5e61ef09 66 -- A table internal to this unit is used to hold the values of back
ba203461 67 -- annotated expressions.
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
ba203461 81 -- written, we do not write uninitialized values to the file.
1c28fe3a
RD
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
b5d3d113
EB
117 Need_Separator : Boolean;
118 -- Set True if a separator is needed before outputting any information for
119 -- the current entity.
fbf5a39b 120
89beb653
HK
121 ------------------------------
122 -- Set of Relevant Entities --
123 ------------------------------
b5f581cd
EB
124
125 Relevant_Entities_Size : constant := 4093;
126 -- Number of headers in hash table
127
128 subtype Entity_Header_Num is Integer range 0 .. Relevant_Entities_Size - 1;
129 -- Range of headers in hash table
130
131 function Entity_Hash (Id : Entity_Id) return Entity_Header_Num;
132 -- Simple hash function for Entity_Ids
133
134 package Relevant_Entities is new GNAT.Htable.Simple_HTable
135 (Header_Num => Entity_Header_Num,
136 Element => Boolean,
137 No_Element => False,
138 Key => Entity_Id,
139 Hash => Entity_Hash,
140 Equal => "=");
141 -- Hash table to record which compiler-generated entities are relevant
142
fbf5a39b
AC
143 -----------------------
144 -- Local Subprograms --
145 -----------------------
19235870
RK
146
147 function Back_End_Layout return Boolean;
5e61ef09
TQ
148 -- Test for layout mode, True = back end, False = front end. This function
149 -- is used rather than checking the configuration parameter because we do
150 -- not want Repinfo to depend on Targparm (for ASIS)
19235870 151
1e60643a 152 procedure List_Entities
558fbeb0 153 (Ent : Entity_Id;
1e60643a
AC
154 Bytes_Big_Endian : Boolean;
155 In_Subprogram : Boolean := False);
5e61ef09
TQ
156 -- This procedure lists the entities associated with the entity E, starting
157 -- with the First_Entity and using the Next_Entity link. If a nested
158 -- package is found, entities within the package are recursively processed.
1e60643a
AC
159 -- When recursing within a subprogram body, Is_Subprogram suppresses
160 -- duplicate information about signature.
19235870
RK
161
162 procedure List_Name (Ent : Entity_Id);
163 -- List name of entity Ent in appropriate case. The name is listed with
164 -- full qualification up to but not including the compilation unit name.
165
d9f8616e 166 procedure List_Array_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean);
19235870
RK
167 -- List representation info for array type Ent
168
6f65c7ee
EB
169 procedure List_Common_Type_Info (Ent : Entity_Id);
170 -- List common type info (name, size, alignment) for type Ent
171
19992053
AC
172 procedure List_Linker_Section (Ent : Entity_Id);
173 -- List linker section for Ent (caller has checked that Ent is an entity
174 -- for which the Linker_Section_Pragma field is defined).
175
1e7629b8
EB
176 procedure List_Location (Ent : Entity_Id);
177 -- List location information for Ent
178
19235870
RK
179 procedure List_Object_Info (Ent : Entity_Id);
180 -- List representation info for object Ent
181
d9f8616e 182 procedure List_Record_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean);
19235870
RK
183 -- List representation info for record type Ent
184
d9f8616e
AC
185 procedure List_Scalar_Storage_Order
186 (Ent : Entity_Id;
187 Bytes_Big_Endian : Boolean);
7ed57189
AC
188 -- List scalar storage order information for record or array type Ent.
189 -- Also includes bit order information for record types, if necessary.
d9f8616e 190
6f65c7ee
EB
191 procedure List_Subprogram_Info (Ent : Entity_Id);
192 -- List subprogram info for subprogram Ent
193
19235870
RK
194 procedure List_Type_Info (Ent : Entity_Id);
195 -- List type info for type Ent
196
197 function Rep_Not_Constant (Val : Node_Ref_Or_Val) return Boolean;
198 -- Returns True if Val represents a variable value, and False if it
199 -- represents a value that is fixed at compile time.
200
fbf5a39b
AC
201 procedure Spaces (N : Natural);
202 -- Output given number of spaces
203
07fc65c4 204 procedure Write_Info_Line (S : String);
5e61ef09
TQ
205 -- Routine to write a line to Repinfo output file. This routine is passed
206 -- as a special output procedure to Output.Set_Special_Output. Note that
207 -- Write_Info_Line is called with an EOL character at the end of each line,
208 -- as per the Output spec, but the internal call to the appropriate routine
209 -- in Osint requires that the end of line sequence be stripped off.
07fc65c4 210
fbf5a39b
AC
211 procedure Write_Mechanism (M : Mechanism_Type);
212 -- Writes symbolic string for mechanism represented by M
213
b5d3d113
EB
214 procedure Write_Separator;
215 -- Called before outputting anything for an entity. Ensures that
216 -- a separator precedes the output for a particular entity.
217
76b382d9
EB
218 procedure Write_Unknown_Val;
219 -- Writes symbolic string for an unknown or non-representable value
220
19235870
RK
221 procedure Write_Val (Val : Node_Ref_Or_Val; Paren : Boolean := False);
222 -- Given a representation value, write it out. No_Uint values or values
223 -- dependent on discriminants are written as two question marks. If the
5e61ef09
TQ
224 -- flag Paren is set, then the output is surrounded in parentheses if it is
225 -- other than a simple value.
19235870
RK
226
227 ---------------------
228 -- Back_End_Layout --
229 ---------------------
230
231 function Back_End_Layout return Boolean is
232 begin
0f9ca030
EB
233 -- We have back-end layout if the back end has made any entries in the
234 -- table of GCC expressions, otherwise we have front-end layout.
19235870
RK
235
236 return Rep_Table.Last > 0;
237 end Back_End_Layout;
238
239 ------------------------
240 -- Create_Discrim_Ref --
241 ------------------------
242
a4c1cd80 243 function Create_Discrim_Ref (Discr : Entity_Id) return Node_Ref is
19235870 244 begin
1d6f10a1
TQ
245 return Create_Node
246 (Expr => Discrim_Val,
247 Op1 => Discriminant_Number (Discr));
19235870
RK
248 end Create_Discrim_Ref;
249
250 ---------------------------
251 -- Create_Dynamic_SO_Ref --
252 ---------------------------
253
a4c1cd80 254 function Create_Dynamic_SO_Ref (E : Entity_Id) return Dynamic_SO_Ref is
19235870 255 begin
1d6f10a1
TQ
256 Dynamic_SO_Entity_Table.Append (E);
257 return UI_From_Int (-Dynamic_SO_Entity_Table.Last);
19235870
RK
258 end Create_Dynamic_SO_Ref;
259
260 -----------------
261 -- Create_Node --
262 -----------------
263
264 function Create_Node
265 (Expr : TCode;
266 Op1 : Node_Ref_Or_Val;
267 Op2 : Node_Ref_Or_Val := No_Uint;
a4c1cd80 268 Op3 : Node_Ref_Or_Val := No_Uint) return Node_Ref
19235870 269 is
19235870 270 begin
1d6f10a1
TQ
271 Rep_Table.Append (
272 (Expr => Expr,
273 Op1 => Op1,
274 Op2 => Op2,
275 Op3 => Op3));
276 return UI_From_Int (-Rep_Table.Last);
19235870
RK
277 end Create_Node;
278
b5f581cd
EB
279 -----------------
280 -- Entity_Hash --
281 -----------------
282
283 function Entity_Hash (Id : Entity_Id) return Entity_Header_Num is
284 begin
285 return Entity_Header_Num (Id mod Relevant_Entities_Size);
286 end Entity_Hash;
287
19235870
RK
288 ---------------------------
289 -- Get_Dynamic_SO_Entity --
290 ---------------------------
291
a4c1cd80 292 function Get_Dynamic_SO_Entity (U : Dynamic_SO_Ref) return Entity_Id is
19235870
RK
293 begin
294 return Dynamic_SO_Entity_Table.Table (-UI_To_Int (U));
295 end Get_Dynamic_SO_Entity;
296
297 -----------------------
298 -- Is_Dynamic_SO_Ref --
299 -----------------------
300
301 function Is_Dynamic_SO_Ref (U : SO_Ref) return Boolean is
302 begin
303 return U < Uint_0;
304 end Is_Dynamic_SO_Ref;
305
306 ----------------------
307 -- Is_Static_SO_Ref --
308 ----------------------
309
310 function Is_Static_SO_Ref (U : SO_Ref) return Boolean is
311 begin
312 return U >= Uint_0;
313 end Is_Static_SO_Ref;
314
315 ---------
316 -- lgx --
317 ---------
318
319 procedure lgx (U : Node_Ref_Or_Val) is
320 begin
321 List_GCC_Expression (U);
322 Write_Eol;
323 end lgx;
324
325 ----------------------
326 -- List_Array_Info --
327 ----------------------
328
d9f8616e 329 procedure List_Array_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean) is
19235870 330 begin
b5d3d113 331 Write_Separator;
1e7629b8
EB
332
333 if List_Representation_Info_To_JSON then
334 Write_Line ("{");
335 end if;
336
6f65c7ee 337 List_Common_Type_Info (Ent);
7672ab42 338
1e7629b8
EB
339 if List_Representation_Info_To_JSON then
340 Write_Line (",");
341 Write_Str (" ""Component_Size"": ");
342 Write_Val (Component_Size (Ent));
343 else
344 Write_Str ("for ");
345 List_Name (Ent);
346 Write_Str ("'Component_Size use ");
347 Write_Val (Component_Size (Ent));
348 Write_Line (";");
349 end if;
d9f8616e
AC
350
351 List_Scalar_Storage_Order (Ent, Bytes_Big_Endian);
7672ab42
EB
352
353 List_Linker_Section (Ent);
1e7629b8
EB
354
355 if List_Representation_Info_To_JSON then
356 Write_Eol;
357 Write_Line ("}");
358 end if;
3c488e6c
EB
359
360 -- The component type is relevant for an array
361
362 if List_Representation_Info = 4
363 and then Is_Itype (Component_Type (Base_Type (Ent)))
364 then
365 Relevant_Entities.Set (Component_Type (Base_Type (Ent)), True);
366 end if;
19235870
RK
367 end List_Array_Info;
368
6f65c7ee
EB
369 ---------------------------
370 -- List_Common_Type_Info --
371 ---------------------------
372
373 procedure List_Common_Type_Info (Ent : Entity_Id) is
374 begin
375 if List_Representation_Info_To_JSON then
376 Write_Str (" ""name"": """);
377 List_Name (Ent);
378 Write_Line (""",");
379 List_Location (Ent);
380 end if;
381
382 -- Do not list size info for unconstrained arrays, not meaningful
383
384 if Is_Array_Type (Ent) and then not Is_Constrained (Ent) then
385 null;
386
387 else
388 -- If Esize and RM_Size are the same, list as Size. This is a common
389 -- case, which we may as well list in simple form.
390
391 if Esize (Ent) = RM_Size (Ent) then
392 if List_Representation_Info_To_JSON then
393 Write_Str (" ""Size"": ");
394 Write_Val (Esize (Ent));
395 Write_Line (",");
396 else
397 Write_Str ("for ");
398 List_Name (Ent);
399 Write_Str ("'Size use ");
400 Write_Val (Esize (Ent));
401 Write_Line (";");
402 end if;
403
404 -- Otherwise list size values separately
405
406 else
407 if List_Representation_Info_To_JSON then
408 Write_Str (" ""Object_Size"": ");
409 Write_Val (Esize (Ent));
410 Write_Line (",");
411
412 Write_Str (" ""Value_Size"": ");
413 Write_Val (RM_Size (Ent));
414 Write_Line (",");
415
416 else
417 Write_Str ("for ");
418 List_Name (Ent);
419 Write_Str ("'Object_Size use ");
420 Write_Val (Esize (Ent));
421 Write_Line (";");
422
423 Write_Str ("for ");
424 List_Name (Ent);
425 Write_Str ("'Value_Size use ");
426 Write_Val (RM_Size (Ent));
427 Write_Line (";");
428 end if;
429 end if;
430 end if;
431
432 if List_Representation_Info_To_JSON then
433 Write_Str (" ""Alignment"": ");
434 Write_Val (Alignment (Ent));
435 else
436 Write_Str ("for ");
437 List_Name (Ent);
438 Write_Str ("'Alignment use ");
439 Write_Val (Alignment (Ent));
440 Write_Line (";");
441 end if;
442 end List_Common_Type_Info;
443
19235870
RK
444 -------------------
445 -- List_Entities --
446 -------------------
447
1e60643a 448 procedure List_Entities
558fbeb0 449 (Ent : Entity_Id;
1e60643a
AC
450 Bytes_Big_Endian : Boolean;
451 In_Subprogram : Boolean := False)
452 is
fbf5a39b
AC
453 Body_E : Entity_Id;
454 E : Entity_Id;
455
456 function Find_Declaration (E : Entity_Id) return Node_Id;
457 -- Utility to retrieve declaration node for entity in the
458 -- case of package bodies and subprograms.
459
460 ----------------------
461 -- Find_Declaration --
462 ----------------------
463
464 function Find_Declaration (E : Entity_Id) return Node_Id is
465 Decl : Node_Id;
a4c1cd80 466
fbf5a39b
AC
467 begin
468 Decl := Parent (E);
fbf5a39b 469 while Present (Decl)
1155ae01 470 and then Nkind (Decl) /= N_Package_Body
fbf5a39b
AC
471 and then Nkind (Decl) /= N_Subprogram_Declaration
472 and then Nkind (Decl) /= N_Subprogram_Body
473 loop
474 Decl := Parent (Decl);
475 end loop;
476
477 return Decl;
478 end Find_Declaration;
479
480 -- Start of processing for List_Entities
19235870
RK
481
482 begin
d3879a5a
RD
483 -- List entity if we have one, and it is not a renaming declaration.
484 -- For renamings, we don't get proper information, and really it makes
485 -- sense to restrict the output to the renamed entity.
fbf5a39b 486
d3879a5a
RD
487 if Present (Ent)
488 and then Nkind (Declaration_Node (Ent)) not in N_Renaming_Declaration
022c9dfe 489 and then not Is_Ignored_Ghost_Entity (Ent)
d3879a5a 490 then
fbf5a39b 491 -- If entity is a subprogram and we are listing mechanisms,
1e60643a
AC
492 -- then we need to list mechanisms for this entity. We skip this
493 -- if it is a nested subprogram, as the information has already
494 -- been produced when listing the enclosing scope.
fbf5a39b
AC
495
496 if List_Representation_Info_Mechanisms
497 and then (Is_Subprogram (Ent)
19992053
AC
498 or else Ekind (Ent) = E_Entry
499 or else Ekind (Ent) = E_Entry_Family)
1e60643a 500 and then not In_Subprogram
fbf5a39b 501 then
6f65c7ee 502 List_Subprogram_Info (Ent);
fbf5a39b
AC
503 end if;
504
19235870
RK
505 E := First_Entity (Ent);
506 while Present (E) loop
5e61ef09 507 -- We list entities that come from source (excluding private or
b5f581cd
EB
508 -- incomplete types or deferred constants, for which we will list
509 -- the information for the full view). If requested, we also list
510 -- relevant entities that have been generated when processing the
511 -- original entities coming from source. But if debug flag A is
512 -- set, then all entities are listed.
fbf5a39b 513
944e24a3
EB
514 if ((Comes_From_Source (E)
515 or else (Ekind (E) = E_Block
516 and then
517 Nkind (Parent (E)) = N_Implicit_Label_Declaration
518 and then
519 Comes_From_Source (Label_Construct (Parent (E)))))
fbf5a39b
AC
520 and then not Is_Incomplete_Or_Private_Type (E)
521 and then not (Ekind (E) = E_Constant
522 and then Present (Full_View (E))))
b5f581cd
EB
523 or else (List_Representation_Info = 4
524 and then Relevant_Entities.Get (E))
07fc65c4
GB
525 or else Debug_Flag_AA
526 then
19992053 527 if Is_Subprogram (E) then
19992053 528 if List_Representation_Info_Mechanisms then
6f65c7ee 529 List_Subprogram_Info (E);
19992053
AC
530 end if;
531
1e60643a
AC
532 -- Recurse into entities local to subprogram
533
534 List_Entities (E, Bytes_Big_Endian, True);
535
19992053
AC
536 elsif Ekind_In (E, E_Entry,
537 E_Entry_Family,
538 E_Subprogram_Type)
fbf5a39b
AC
539 then
540 if List_Representation_Info_Mechanisms then
6f65c7ee 541 List_Subprogram_Info (E);
fbf5a39b
AC
542 end if;
543
544 elsif Is_Record_Type (E) then
545 if List_Representation_Info >= 1 then
d9f8616e 546 List_Record_Info (E, Bytes_Big_Endian);
fbf5a39b 547 end if;
19235870 548
3c488e6c
EB
549 -- Recurse into entities local to a record type
550
551 if List_Representation_Info = 4 then
552 List_Entities (E, Bytes_Big_Endian, False);
553 end if;
554
19235870 555 elsif Is_Array_Type (E) then
fbf5a39b 556 if List_Representation_Info >= 1 then
d9f8616e 557 List_Array_Info (E, Bytes_Big_Endian);
fbf5a39b 558 end if;
19235870 559
fbf5a39b
AC
560 elsif Is_Type (E) then
561 if List_Representation_Info >= 2 then
19235870 562 List_Type_Info (E);
fbf5a39b 563 end if;
19235870 564
fb95bfcc 565 -- Note that formals are not annotated so we skip them here
19992053 566
134f52b9
HK
567 elsif Ekind_In (E, E_Constant,
568 E_Loop_Parameter,
569 E_Variable)
fb95bfcc 570 then
fbf5a39b 571 if List_Representation_Info >= 2 then
19235870
RK
572 List_Object_Info (E);
573 end if;
574 end if;
575
5e61ef09
TQ
576 -- Recurse into nested package, but not if they are package
577 -- renamings (in particular renamings of the enclosing package,
578 -- as for some Java bindings and for generic instances).
19235870 579
07fc65c4
GB
580 if Ekind (E) = E_Package then
581 if No (Renamed_Object (E)) then
d9f8616e 582 List_Entities (E, Bytes_Big_Endian);
07fc65c4
GB
583 end if;
584
585 -- Recurse into bodies
586
134f52b9
HK
587 elsif Ekind_In (E, E_Package_Body,
588 E_Protected_Body,
589 E_Protected_Type,
19992053 590 E_Subprogram_Body,
19992053 591 E_Task_Body,
134f52b9 592 E_Task_Type)
19235870 593 then
d9f8616e 594 List_Entities (E, Bytes_Big_Endian);
07fc65c4
GB
595
596 -- Recurse into blocks
597
598 elsif Ekind (E) = E_Block then
d9f8616e 599 List_Entities (E, Bytes_Big_Endian);
19235870
RK
600 end if;
601 end if;
602
99859ea7 603 Next_Entity (E);
19235870 604 end loop;
fbf5a39b 605
5e61ef09
TQ
606 -- For a package body, the entities of the visible subprograms are
607 -- declared in the corresponding spec. Iterate over its entities in
608 -- order to handle properly the subprogram bodies. Skip bodies in
609 -- subunits, which are listed independently.
fbf5a39b
AC
610
611 if Ekind (Ent) = E_Package_Body
612 and then Present (Corresponding_Spec (Find_Declaration (Ent)))
613 then
614 E := First_Entity (Corresponding_Spec (Find_Declaration (Ent)));
fbf5a39b
AC
615 while Present (E) loop
616 if Is_Subprogram (E)
617 and then
618 Nkind (Find_Declaration (E)) = N_Subprogram_Declaration
619 then
620 Body_E := Corresponding_Body (Find_Declaration (E));
621
622 if Present (Body_E)
623 and then
624 Nkind (Parent (Find_Declaration (Body_E))) /= N_Subunit
625 then
d9f8616e 626 List_Entities (Body_E, Bytes_Big_Endian);
fbf5a39b
AC
627 end if;
628 end if;
629
630 Next_Entity (E);
631 end loop;
632 end if;
19235870
RK
633 end if;
634 end List_Entities;
635
636 -------------------------
637 -- List_GCC_Expression --
638 -------------------------
639
640 procedure List_GCC_Expression (U : Node_Ref_Or_Val) is
641
fbf5a39b 642 procedure Print_Expr (Val : Node_Ref_Or_Val);
19235870
RK
643 -- Internal recursive procedure to print expression
644
fbf5a39b
AC
645 ----------------
646 -- Print_Expr --
647 ----------------
648
649 procedure Print_Expr (Val : Node_Ref_Or_Val) is
19235870
RK
650 begin
651 if Val >= 0 then
652 UI_Write (Val, Decimal);
653
654 else
655 declare
656 Node : Exp_Node renames Rep_Table.Table (-UI_To_Int (Val));
657
7672ab42
EB
658 procedure Unop (S : String);
659 -- Output text for unary operator with S being operator name
660
19235870
RK
661 procedure Binop (S : String);
662 -- Output text for binary operator with S being operator name
663
7672ab42
EB
664 ----------
665 -- Unop --
666 ----------
667
668 procedure Unop (S : String) is
669 begin
1e7629b8
EB
670 if List_Representation_Info_To_JSON then
671 Write_Str ("{ ""code"": """);
672 if S (S'Last) = ' ' then
673 Write_Str (S (S'First .. S'Last - 1));
674 else
675 Write_Str (S);
676 end if;
677 Write_Str (""", ""operands"": [ ");
678 Print_Expr (Node.Op1);
679 Write_Str (" ] }");
680 else
681 Write_Str (S);
682 Print_Expr (Node.Op1);
683 end if;
7672ab42
EB
684 end Unop;
685
fbf5a39b
AC
686 -----------
687 -- Binop --
688 -----------
689
19235870
RK
690 procedure Binop (S : String) is
691 begin
1e7629b8
EB
692 if List_Representation_Info_To_JSON then
693 Write_Str ("{ ""code"": """);
694 Write_Str (S (S'First + 1 .. S'Last - 1));
695 Write_Str (""", ""operands"": [ ");
696 Print_Expr (Node.Op1);
697 Write_Str (", ");
698 Print_Expr (Node.Op2);
699 Write_Str (" ] }");
700 else
701 Write_Char ('(');
702 Print_Expr (Node.Op1);
703 Write_Str (S);
704 Print_Expr (Node.Op2);
705 Write_Char (')');
706 end if;
19235870
RK
707 end Binop;
708
fbf5a39b 709 -- Start of processing for Print_Expr
19235870
RK
710
711 begin
712 case Node.Expr is
713 when Cond_Expr =>
1e7629b8
EB
714 if List_Representation_Info_To_JSON then
715 Write_Str ("{ ""code"": ""?<>""");
716 Write_Str (", ""operands"": [ ");
717 Print_Expr (Node.Op1);
718 Write_Str (", ");
719 Print_Expr (Node.Op2);
720 Write_Str (", ");
721 Print_Expr (Node.Op3);
722 Write_Str (" ] }");
723 else
724 Write_Str ("(if ");
725 Print_Expr (Node.Op1);
726 Write_Str (" then ");
727 Print_Expr (Node.Op2);
728 Write_Str (" else ");
729 Print_Expr (Node.Op3);
730 Write_Str (" end)");
731 end if;
19235870
RK
732
733 when Plus_Expr =>
734 Binop (" + ");
735
736 when Minus_Expr =>
737 Binop (" - ");
738
739 when Mult_Expr =>
740 Binop (" * ");
741
742 when Trunc_Div_Expr =>
743 Binop (" /t ");
744
745 when Ceil_Div_Expr =>
746 Binop (" /c ");
747
748 when Floor_Div_Expr =>
749 Binop (" /f ");
750
751 when Trunc_Mod_Expr =>
752 Binop (" modt ");
753
19235870
RK
754 when Ceil_Mod_Expr =>
755 Binop (" modc ");
756
7672ab42
EB
757 when Floor_Mod_Expr =>
758 Binop (" modf ");
759
19235870
RK
760 when Exact_Div_Expr =>
761 Binop (" /e ");
762
763 when Negate_Expr =>
7672ab42 764 Unop ("-");
19235870
RK
765
766 when Min_Expr =>
767 Binop (" min ");
768
769 when Max_Expr =>
770 Binop (" max ");
771
772 when Abs_Expr =>
7672ab42 773 Unop ("abs ");
19235870 774
19235870
RK
775 when Truth_And_Expr =>
776 Binop (" and ");
777
778 when Truth_Or_Expr =>
779 Binop (" or ");
780
781 when Truth_Xor_Expr =>
782 Binop (" xor ");
783
784 when Truth_Not_Expr =>
7672ab42 785 Unop ("not ");
5e61ef09 786
19235870
RK
787 when Lt_Expr =>
788 Binop (" < ");
789
790 when Le_Expr =>
791 Binop (" <= ");
792
793 when Gt_Expr =>
794 Binop (" > ");
795
796 when Ge_Expr =>
797 Binop (" >= ");
798
799 when Eq_Expr =>
800 Binop (" == ");
801
802 when Ne_Expr =>
803 Binop (" != ");
804
7672ab42
EB
805 when Bit_And_Expr =>
806 Binop (" & ");
807
19235870 808 when Discrim_Val =>
575e47bf 809 Unop ("#");
e45f84a5
EB
810
811 when Dynamic_Val =>
575e47bf 812 Unop ("var");
19235870
RK
813 end case;
814 end;
815 end if;
fbf5a39b 816 end Print_Expr;
19235870
RK
817
818 -- Start of processing for List_GCC_Expression
819
820 begin
821 if U = No_Uint then
76b382d9 822 Write_Unknown_Val;
19235870 823 else
fbf5a39b 824 Print_Expr (U);
19235870
RK
825 end if;
826 end List_GCC_Expression;
827
19992053
AC
828 -------------------------
829 -- List_Linker_Section --
830 -------------------------
831
832 procedure List_Linker_Section (Ent : Entity_Id) is
24161618
HK
833 function Expr_Value_S (N : Node_Id) return Node_Id;
834 -- Returns the folded value of the expression. This function is called
835 -- in instances where it has already been determined that the expression
836 -- is static or its value is known at compile time. This version is used
837 -- for string types and returns the corresponding N_String_Literal node.
838 -- NOTE: This is an exact copy of Sem_Eval.Expr_Value_S. Licensing stops
839 -- Repinfo from within Sem_Eval. Once ASIS is removed, and the licenses
840 -- are modified, Repinfo should be able to rely on Sem_Eval.
841
842 ------------------
843 -- Expr_Value_S --
844 ------------------
845
846 function Expr_Value_S (N : Node_Id) return Node_Id is
847 begin
848 if Nkind (N) = N_String_Literal then
849 return N;
850 else
851 pragma Assert (Ekind (Entity (N)) = E_Constant);
852 return Expr_Value_S (Constant_Value (Entity (N)));
853 end if;
854 end Expr_Value_S;
855
856 -- Local variables
857
858 Args : List_Id;
859 Sect : Node_Id;
860
861 -- Start of processing for List_Linker_Section
19992053
AC
862
863 begin
864 if Present (Linker_Section_Pragma (Ent)) then
24161618
HK
865 Args := Pragma_Argument_Associations (Linker_Section_Pragma (Ent));
866 Sect := Expr_Value_S (Get_Pragma_Arg (Last (Args)));
867
1e7629b8
EB
868 if List_Representation_Info_To_JSON then
869 Write_Line (",");
870 Write_Str (" ""Linker_Section"": """);
871 else
872 Write_Str ("pragma Linker_Section (");
873 List_Name (Ent);
874 Write_Str (", """);
875 end if;
19992053 876
24161618
HK
877 pragma Assert (Nkind (Sect) = N_String_Literal);
878 String_To_Name_Buffer (Strval (Sect));
19992053 879 Write_Str (Name_Buffer (1 .. Name_Len));
1e7629b8
EB
880 Write_Str ("""");
881 if not List_Representation_Info_To_JSON then
882 Write_Line (");");
883 end if;
19992053
AC
884 end if;
885 end List_Linker_Section;
886
1e7629b8
EB
887 -------------------
888 -- List_Location --
889 -------------------
890
891 procedure List_Location (Ent : Entity_Id) is
892 begin
893 pragma Assert (List_Representation_Info_To_JSON);
894 Write_Str (" ""location"": """);
895 Write_Location (Sloc (Ent));
896 Write_Line (""",");
897 end List_Location;
898
19235870
RK
899 ---------------
900 -- List_Name --
901 ---------------
902
903 procedure List_Name (Ent : Entity_Id) is
fb95bfcc
EB
904 C : Character;
905
19235870 906 begin
1e7629b8
EB
907 -- List the qualified name recursively, except
908 -- at compilation unit level in default mode.
909
910 if Is_Compilation_Unit (Ent) then
911 null;
912 elsif not Is_Compilation_Unit (Scope (Ent))
913 or else List_Representation_Info_To_JSON
914 then
19235870
RK
915 List_Name (Scope (Ent));
916 Write_Char ('.');
917 end if;
918
919 Get_Unqualified_Decoded_Name_String (Chars (Ent));
920 Set_Casing (Unit_Casing);
fb95bfcc
EB
921
922 -- The name of operators needs to be properly escaped for JSON
923
924 for J in 1 .. Name_Len loop
925 C := Name_Buffer (J);
926 if C = '"' and then List_Representation_Info_To_JSON then
927 Write_Char ('\');
928 end if;
929 Write_Char (C);
930 end loop;
19235870
RK
931 end List_Name;
932
933 ---------------------
934 -- List_Object_Info --
935 ---------------------
936
937 procedure List_Object_Info (Ent : Entity_Id) is
938 begin
b5d3d113 939 Write_Separator;
19235870 940
1e7629b8
EB
941 if List_Representation_Info_To_JSON then
942 Write_Line ("{");
943
944 Write_Str (" ""name"": """);
945 List_Name (Ent);
946 Write_Line (""",");
947 List_Location (Ent);
19235870 948
1e7629b8
EB
949 Write_Str (" ""Size"": ");
950 Write_Val (Esize (Ent));
951 Write_Line (",");
7672ab42 952
1e7629b8
EB
953 Write_Str (" ""Alignment"": ");
954 Write_Val (Alignment (Ent));
955
956 List_Linker_Section (Ent);
957
958 Write_Eol;
959 Write_Line ("}");
960 else
961 Write_Str ("for ");
962 List_Name (Ent);
963 Write_Str ("'Size use ");
964 Write_Val (Esize (Ent));
965 Write_Line (";");
966
967 Write_Str ("for ");
968 List_Name (Ent);
969 Write_Str ("'Alignment use ");
970 Write_Val (Alignment (Ent));
971 Write_Line (";");
972
973 List_Linker_Section (Ent);
974 end if;
3c488e6c
EB
975
976 -- The type is relevant for an object
977
978 if List_Representation_Info = 4 and then Is_Itype (Etype (Ent)) then
979 Relevant_Entities.Set (Etype (Ent), True);
980 end if;
19235870
RK
981 end List_Object_Info;
982
983 ----------------------
984 -- List_Record_Info --
985 ----------------------
986
d9f8616e 987 procedure List_Record_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean) is
1c912574
AC
988 procedure Compute_Max_Length
989 (Ent : Entity_Id;
990 Starting_Position : Uint := Uint_0;
991 Starting_First_Bit : Uint := Uint_0;
992 Prefix_Length : Natural := 0);
993 -- Internal recursive procedure to compute the max length
994
7883c42e
EB
995 procedure List_Component_Layout
996 (Ent : Entity_Id;
997 Starting_Position : Uint := Uint_0;
998 Starting_First_Bit : Uint := Uint_0;
1e7629b8
EB
999 Prefix : String := "";
1000 Indent : Natural := 0);
7883c42e
EB
1001 -- Procedure to display the layout of a single component
1002
1c912574
AC
1003 procedure List_Record_Layout
1004 (Ent : Entity_Id;
1005 Starting_Position : Uint := Uint_0;
1006 Starting_First_Bit : Uint := Uint_0;
1007 Prefix : String := "");
1008 -- Internal recursive procedure to display the layout
1009
1e7629b8 1010 procedure List_Structural_Record_Layout
0f9ca030
EB
1011 (Ent : Entity_Id;
1012 Outer_Ent : Entity_Id;
1013 Variant : Node_Id := Empty;
1014 Indent : Natural := 0);
1e7629b8
EB
1015 -- Internal recursive procedure to display the structural layout
1016
abbc4546
EB
1017 Incomplete_Layout : exception;
1018 -- Exception raised if the layout is incomplete in -gnatc mode
1019
1020 Not_In_Extended_Main : exception;
1021 -- Exception raised when an ancestor is not declared in the main unit
1022
1c912574
AC
1023 Max_Name_Length : Natural := 0;
1024 Max_Spos_Length : Natural := 0;
1025
1026 ------------------------
1027 -- Compute_Max_Length --
1028 ------------------------
1029
1030 procedure Compute_Max_Length
1031 (Ent : Entity_Id;
1032 Starting_Position : Uint := Uint_0;
1033 Starting_First_Bit : Uint := Uint_0;
1034 Prefix_Length : Natural := 0)
1035 is
3815f967 1036 Comp : Entity_Id;
19235870 1037
1c912574
AC
1038 begin
1039 Comp := First_Component_Or_Discriminant (Ent);
1040 while Present (Comp) loop
19235870 1041
1c912574 1042 -- Skip discriminant in unchecked union (since it is not there!)
19235870 1043
1c912574
AC
1044 if Ekind (Comp) = E_Discriminant
1045 and then Is_Unchecked_Union (Ent)
1046 then
1047 goto Continue;
1048 end if;
19235870 1049
c8e95568
EB
1050 -- Skip _Parent component in extension (to avoid overlap)
1051
1052 if Chars (Comp) = Name_uParent then
1053 goto Continue;
1054 end if;
1055
1c912574 1056 -- All other cases
19235870 1057
1c912574
AC
1058 declare
1059 Ctyp : constant Entity_Id := Underlying_Type (Etype (Comp));
1060 Bofs : constant Uint := Component_Bit_Offset (Comp);
1061 Npos : Uint;
1062 Fbit : Uint;
1063 Spos : Uint;
1064 Sbit : Uint;
3815f967 1065
1c912574 1066 Name_Length : Natural;
3815f967 1067
1c912574
AC
1068 begin
1069 Get_Decoded_Name_String (Chars (Comp));
1070 Name_Length := Prefix_Length + Name_Len;
19235870 1071
1c912574 1072 if Rep_Not_Constant (Bofs) then
19235870 1073
1c912574
AC
1074 -- If the record is not packed, then we know that all fields
1075 -- whose position is not specified have starting normalized
1076 -- bit position of zero.
3fbbbd1e 1077
1c912574
AC
1078 if Unknown_Normalized_First_Bit (Comp)
1079 and then not Is_Packed (Ent)
1080 then
1081 Set_Normalized_First_Bit (Comp, Uint_0);
1082 end if;
19235870 1083
1c912574
AC
1084 UI_Image_Length := 2; -- For "??" marker
1085 else
1086 Npos := Bofs / SSU;
1087 Fbit := Bofs mod SSU;
19235870 1088
1c912574 1089 -- Complete annotation in case not done
19235870 1090
1c912574
AC
1091 if Unknown_Normalized_First_Bit (Comp) then
1092 Set_Normalized_Position (Comp, Npos);
1093 Set_Normalized_First_Bit (Comp, Fbit);
1094 end if;
cc3a2986 1095
1c912574
AC
1096 Spos := Starting_Position + Npos;
1097 Sbit := Starting_First_Bit + Fbit;
3815f967 1098
1c912574
AC
1099 if Sbit >= SSU then
1100 Spos := Spos + 1;
1101 Sbit := Sbit - SSU;
1102 end if;
07fc65c4 1103
1c912574
AC
1104 -- If extended information is requested, recurse fully into
1105 -- record components, i.e. skip the outer level.
74a78a4f 1106
1c912574
AC
1107 if List_Representation_Info_Extended
1108 and then Is_Record_Type (Ctyp)
1109 then
1110 Compute_Max_Length (Ctyp, Spos, Sbit, Name_Length + 1);
1111 goto Continue;
1112 end if;
19235870 1113
1c912574 1114 UI_Image (Spos);
74a78a4f 1115 end if;
3fbbbd1e 1116
1c912574
AC
1117 Max_Name_Length := Natural'Max (Max_Name_Length, Name_Length);
1118 Max_Spos_Length :=
1119 Natural'Max (Max_Spos_Length, UI_Image_Length);
1120 end;
19235870 1121
1c912574
AC
1122 <<Continue>>
1123 Next_Component_Or_Discriminant (Comp);
1124 end loop;
1125 end Compute_Max_Length;
a9a5b8ac 1126
7883c42e
EB
1127 ---------------------------
1128 -- List_Component_Layout --
1129 ---------------------------
1130
1131 procedure List_Component_Layout
1132 (Ent : Entity_Id;
1133 Starting_Position : Uint := Uint_0;
1134 Starting_First_Bit : Uint := Uint_0;
1e7629b8
EB
1135 Prefix : String := "";
1136 Indent : Natural := 0)
7883c42e
EB
1137 is
1138 Esiz : constant Uint := Esize (Ent);
1139 Npos : constant Uint := Normalized_Position (Ent);
1140 Fbit : constant Uint := Normalized_First_Bit (Ent);
1141 Spos : Uint;
1142 Sbit : Uint;
1143 Lbit : Uint;
1144
1145 begin
1e7629b8
EB
1146 if List_Representation_Info_To_JSON then
1147 Spaces (Indent);
1148 Write_Line (" {");
1149 Spaces (Indent);
1150 Write_Str (" ""name"": """);
1151 Write_Str (Prefix);
1152 Write_Str (Name_Buffer (1 .. Name_Len));
1153 Write_Line (""",");
0f9ca030
EB
1154 if Ekind (Ent) = E_Discriminant then
1155 Spaces (Indent);
1156 Write_Str (" ""discriminant"": ");
f9534f4b 1157 UI_Write (Discriminant_Number (Ent), Decimal);
0f9ca030
EB
1158 Write_Line (",");
1159 end if;
1e7629b8
EB
1160 Spaces (Indent);
1161 Write_Str (" ""Position"": ");
1162 else
1163 Write_Str (" ");
1164 Write_Str (Prefix);
1165 Write_Str (Name_Buffer (1 .. Name_Len));
1166 Spaces (Max_Name_Length - Prefix'Length - Name_Len);
1167 Write_Str (" at ");
1168 end if;
7883c42e
EB
1169
1170 if Known_Static_Normalized_Position (Ent) then
1171 Spos := Starting_Position + Npos;
1172 Sbit := Starting_First_Bit + Fbit;
1173
1174 if Sbit >= SSU then
1175 Spos := Spos + 1;
1176 end if;
1177
1178 UI_Image (Spos);
1179 Spaces (Max_Spos_Length - UI_Image_Length);
1180 Write_Str (UI_Image_Buffer (1 .. UI_Image_Length));
1181
1182 elsif Known_Normalized_Position (Ent)
b5f581cd 1183 and then List_Representation_Info >= 3
7883c42e
EB
1184 then
1185 Spaces (Max_Spos_Length - 2);
1186
1187 if Starting_Position /= Uint_0 then
f9534f4b 1188 UI_Write (Starting_Position, Decimal);
7883c42e
EB
1189 Write_Str (" + ");
1190 end if;
1191
1192 Write_Val (Npos);
1193
1194 else
1195 Write_Unknown_Val;
1196 end if;
1197
1e7629b8
EB
1198 if List_Representation_Info_To_JSON then
1199 Write_Line (",");
1200 Spaces (Indent);
1201 Write_Str (" ""First_Bit"": ");
1202 else
1203 Write_Str (" range ");
1204 end if;
1205
7883c42e
EB
1206 Sbit := Starting_First_Bit + Fbit;
1207
1208 if Sbit >= SSU then
1209 Sbit := Sbit - SSU;
1210 end if;
1211
f9534f4b 1212 UI_Write (Sbit, Decimal);
1e7629b8
EB
1213
1214 if List_Representation_Info_To_JSON then
1215 Write_Line (", ");
1216 Spaces (Indent);
1217 Write_Str (" ""Size"": ");
1218 else
1219 Write_Str (" .. ");
1220 end if;
7883c42e 1221
f537fc00
HK
1222 -- Allowing Uint_0 here is an annoying special case. Really this
1223 -- should be a fine Esize value but currently it means unknown,
1224 -- except that we know after gigi has back annotated that a size
1225 -- of zero is real, since otherwise gigi back annotates using
1226 -- No_Uint as the value to indicate unknown.
7883c42e
EB
1227
1228 if (Esize (Ent) = Uint_0 or else Known_Static_Esize (Ent))
1229 and then Known_Static_Normalized_First_Bit (Ent)
1230 then
1231 Lbit := Sbit + Esiz - 1;
1232
1e7629b8 1233 if List_Representation_Info_To_JSON then
f9534f4b 1234 UI_Write (Esiz, Decimal);
1e7629b8 1235 else
683ccd05 1236 if Lbit >= 0 and then Lbit < 10 then
1e7629b8
EB
1237 Write_Char (' ');
1238 end if;
7883c42e 1239
f9534f4b 1240 UI_Write (Lbit, Decimal);
1e7629b8 1241 end if;
7883c42e 1242
f537fc00
HK
1243 -- The test for Esize (Ent) not Uint_0 here is an annoying special
1244 -- case. Officially a value of zero for Esize means unknown, but
1245 -- here we use the fact that we know that gigi annotates Esize with
1246 -- No_Uint, not Uint_0. Really everyone should use No_Uint???
7883c42e
EB
1247
1248 elsif List_Representation_Info < 3
1249 or else (Esize (Ent) /= Uint_0 and then Unknown_Esize (Ent))
1250 then
1251 Write_Unknown_Val;
1252
1253 -- List_Representation >= 3 and Known_Esize (Ent)
1254
1255 else
1e7629b8 1256 Write_Val (Esiz, Paren => not List_Representation_Info_To_JSON);
7883c42e 1257
f537fc00
HK
1258 -- If in front-end layout mode, then dynamic size is stored in
1259 -- storage units, so renormalize for output.
7883c42e
EB
1260
1261 if not Back_End_Layout then
1262 Write_Str (" * ");
1263 Write_Int (SSU);
1264 end if;
1265
1266 -- Add appropriate first bit offset
1267
1e7629b8
EB
1268 if not List_Representation_Info_To_JSON then
1269 if Sbit = 0 then
1270 Write_Str (" - 1");
7883c42e 1271
1e7629b8
EB
1272 elsif Sbit = 1 then
1273 null;
7883c42e 1274
1e7629b8
EB
1275 else
1276 Write_Str (" + ");
1277 Write_Int (UI_To_Int (Sbit) - 1);
1278 end if;
7883c42e
EB
1279 end if;
1280 end if;
1281
1e7629b8
EB
1282 if List_Representation_Info_To_JSON then
1283 Write_Eol;
1284 Spaces (Indent);
1285 Write_Str (" }");
1286 else
1287 Write_Line (";");
1288 end if;
3c488e6c
EB
1289
1290 -- The type is relevant for a component
1291
1292 if List_Representation_Info = 4 and then Is_Itype (Etype (Ent)) then
1293 Relevant_Entities.Set (Etype (Ent), True);
1294 end if;
7883c42e
EB
1295 end List_Component_Layout;
1296
1c912574
AC
1297 ------------------------
1298 -- List_Record_Layout --
1299 ------------------------
19235870 1300
1c912574
AC
1301 procedure List_Record_Layout
1302 (Ent : Entity_Id;
1303 Starting_Position : Uint := Uint_0;
1304 Starting_First_Bit : Uint := Uint_0;
1305 Prefix : String := "")
1306 is
81d85d4b
EB
1307 Comp : Entity_Id;
1308 First : Boolean := True;
19235870 1309
1c912574
AC
1310 begin
1311 Comp := First_Component_Or_Discriminant (Ent);
1312 while Present (Comp) loop
3fbbbd1e 1313
1c912574 1314 -- Skip discriminant in unchecked union (since it is not there!)
3fbbbd1e 1315
1c912574
AC
1316 if Ekind (Comp) = E_Discriminant
1317 and then Is_Unchecked_Union (Ent)
1318 then
1319 goto Continue;
1320 end if;
3fbbbd1e 1321
c8e95568
EB
1322 -- Skip _Parent component in extension (to avoid overlap)
1323
1324 if Chars (Comp) = Name_uParent then
1325 goto Continue;
1326 end if;
1327
1c912574 1328 -- All other cases
3fbbbd1e 1329
1c912574
AC
1330 declare
1331 Ctyp : constant Entity_Id := Underlying_Type (Etype (Comp));
1c912574
AC
1332 Npos : constant Uint := Normalized_Position (Comp);
1333 Fbit : constant Uint := Normalized_First_Bit (Comp);
1334 Spos : Uint;
1335 Sbit : Uint;
a9a5b8ac 1336
1c912574
AC
1337 begin
1338 Get_Decoded_Name_String (Chars (Comp));
1339 Set_Casing (Unit_Casing);
19235870 1340
1c912574
AC
1341 -- If extended information is requested, recurse fully into
1342 -- record components, i.e. skip the outer level.
19235870 1343
1c912574
AC
1344 if List_Representation_Info_Extended
1345 and then Is_Record_Type (Ctyp)
1346 and then Known_Static_Normalized_Position (Comp)
1347 and then Known_Static_Normalized_First_Bit (Comp)
1348 then
1349 Spos := Starting_Position + Npos;
1350 Sbit := Starting_First_Bit + Fbit;
3815f967 1351
1c912574
AC
1352 if Sbit >= SSU then
1353 Spos := Spos + 1;
1354 Sbit := Sbit - SSU;
1355 end if;
3815f967 1356
1c912574
AC
1357 List_Record_Layout (Ctyp,
1358 Spos, Sbit, Prefix & Name_Buffer (1 .. Name_Len) & ".");
3815f967 1359
1c912574
AC
1360 goto Continue;
1361 end if;
19235870 1362
81d85d4b
EB
1363 if List_Representation_Info_To_JSON then
1364 if First then
1365 Write_Eol;
1366 First := False;
1367 else
1368 Write_Line (",");
1369 end if;
1370 end if;
1371
7883c42e
EB
1372 List_Component_Layout (Comp,
1373 Starting_Position, Starting_First_Bit, Prefix);
1c912574 1374 end;
19235870 1375
1c912574
AC
1376 <<Continue>>
1377 Next_Component_Or_Discriminant (Comp);
1378 end loop;
1379 end List_Record_Layout;
1380
1e7629b8
EB
1381 -----------------------------------
1382 -- List_Structural_Record_Layout --
1383 -----------------------------------
1384
1385 procedure List_Structural_Record_Layout
0f9ca030
EB
1386 (Ent : Entity_Id;
1387 Outer_Ent : Entity_Id;
1388 Variant : Node_Id := Empty;
1389 Indent : Natural := 0)
1e7629b8 1390 is
0f9ca030
EB
1391 function Derived_Discriminant (Disc : Entity_Id) return Entity_Id;
1392 -- This function assumes that Outer_Ent is an extension of Ent.
1393 -- Disc is a discriminant of Ent that does not itself constrain a
1394 -- discriminant of the parent type of Ent. Return the discriminant
1395 -- of Outer_Ent that ultimately constrains Disc, if any.
1396
1397 ----------------------------
1398 -- Derived_Discriminant --
1399 ----------------------------
1400
1401 function Derived_Discriminant (Disc : Entity_Id) return Entity_Id is
f537fc00
HK
1402 Corr_Disc : Entity_Id;
1403 Derived_Disc : Entity_Id;
0f9ca030
EB
1404
1405 begin
1406 Derived_Disc := First_Stored_Discriminant (Outer_Ent);
1407
1408 -- Loop over the discriminants of the extension
1409
1410 while Present (Derived_Disc) loop
1411
1412 -- Check if this discriminant constrains another discriminant.
1413 -- If so, find the ultimately constrained discriminant and
1414 -- compare with the original components in the base type.
1415
1416 if Present (Corresponding_Discriminant (Derived_Disc)) then
1417 Corr_Disc := Corresponding_Discriminant (Derived_Disc);
1418
1419 while Present (Corresponding_Discriminant (Corr_Disc)) loop
1420 Corr_Disc := Corresponding_Discriminant (Corr_Disc);
1421 end loop;
1422
f537fc00
HK
1423 if Original_Record_Component (Corr_Disc) =
1424 Original_Record_Component (Disc)
0f9ca030
EB
1425 then
1426 return Derived_Disc;
1427 end if;
1428 end if;
1429
1430 Next_Stored_Discriminant (Derived_Disc);
1431 end loop;
1432
1433 -- Disc is not constrained by a discriminant of Outer_Ent
1434
1435 return Empty;
1436 end Derived_Discriminant;
1437
1438 -- Local declarations
1439
1e7629b8
EB
1440 Comp : Node_Id;
1441 Comp_List : Node_Id;
1e7629b8 1442 First : Boolean := True;
f537fc00 1443 Var : Node_Id;
1e7629b8 1444
0f9ca030
EB
1445 -- Start of processing for List_Structural_Record_Layout
1446
1e7629b8
EB
1447 begin
1448 -- If we are dealing with a variant, just process the components
1449
1450 if Present (Variant) then
1451 Comp_List := Component_List (Variant);
1452
1453 -- Otherwise, we are dealing with the full record and need to get
1454 -- to its definition in order to retrieve its structural layout.
1455
1456 else
1457 declare
1458 Definition : Node_Id :=
f537fc00
HK
1459 Type_Definition (Declaration_Node (Ent));
1460
1e7629b8 1461 Is_Extension : constant Boolean :=
f537fc00
HK
1462 Is_Tagged_Type (Ent)
1463 and then Nkind (Definition) =
1464 N_Derived_Type_Definition;
1465
1466 Disc : Entity_Id;
1467 Listed_Disc : Entity_Id;
abbc4546 1468 Parent_Type : Entity_Id;
0f9ca030 1469
1e7629b8
EB
1470 begin
1471 -- If this is an extension, first list the layout of the parent
1472 -- and then proceed to the extension part, if any.
1473
1474 if Is_Extension then
abbc4546
EB
1475 Parent_Type := Parent_Subtype (Ent);
1476 if No (Parent_Type) then
1477 raise Incomplete_Layout;
1478 end if;
1479
1480 if Is_Private_Type (Parent_Type) then
1481 Parent_Type := Full_View (Parent_Type);
1482 pragma Assert (Present (Parent_Type));
1483 end if;
1484
1485 Parent_Type := Base_Type (Parent_Type);
1486 if not In_Extended_Main_Source_Unit (Parent_Type) then
1487 raise Not_In_Extended_Main;
1488 end if;
1489
1490 List_Structural_Record_Layout (Parent_Type, Outer_Ent);
9104d201 1491 First := False;
1e7629b8
EB
1492
1493 if Present (Record_Extension_Part (Definition)) then
1494 Definition := Record_Extension_Part (Definition);
1495 end if;
1496 end if;
1497
1498 -- If the record has discriminants and is not an unchecked
1499 -- union, then display them now.
1500
1501 if Has_Discriminants (Ent)
1502 and then not Is_Unchecked_Union (Ent)
1503 then
1504 Disc := First_Stored_Discriminant (Ent);
1505 while Present (Disc) loop
1506
1507 -- If this is a record extension and the discriminant is
1508 -- the renaming of another discriminant, skip it.
1509
1510 if Is_Extension
1511 and then Present (Corresponding_Discriminant (Disc))
1512 then
1513 goto Continue_Disc;
1514 end if;
1515
0f9ca030
EB
1516 -- If this is the parent type of an extension, retrieve
1517 -- the derived discriminant from the extension, if any.
1518
1519 if Ent /= Outer_Ent then
1520 Listed_Disc := Derived_Discriminant (Disc);
1521
1522 if No (Listed_Disc) then
1523 goto Continue_Disc;
1524 end if;
1525 else
1526 Listed_Disc := Disc;
1527 end if;
1528
1529 Get_Decoded_Name_String (Chars (Listed_Disc));
1e7629b8
EB
1530 Set_Casing (Unit_Casing);
1531
1532 if First then
1533 Write_Eol;
1534 First := False;
1535 else
1536 Write_Line (",");
1537 end if;
1538
0f9ca030 1539 List_Component_Layout (Listed_Disc, Indent => Indent);
1e7629b8
EB
1540
1541 <<Continue_Disc>>
1542 Next_Stored_Discriminant (Disc);
1543 end loop;
1544 end if;
1545
1546 Comp_List := Component_List (Definition);
1547 end;
1548 end if;
1549
1550 -- Bail out for the null record
1551
1552 if No (Comp_List) then
1553 return;
1554 end if;
1555
1556 -- Now deal with the regular components, if any
1557
1558 if Present (Component_Items (Comp_List)) then
1559 Comp := First_Non_Pragma (Component_Items (Comp_List));
1560 while Present (Comp) loop
1561
1562 -- Skip _Parent component in extension (to avoid overlap)
1563
1564 if Chars (Defining_Identifier (Comp)) = Name_uParent then
1565 goto Continue_Comp;
1566 end if;
1567
1568 Get_Decoded_Name_String (Chars (Defining_Identifier (Comp)));
1569 Set_Casing (Unit_Casing);
1570
1571 if First then
1572 Write_Eol;
1573 First := False;
1574 else
1575 Write_Line (",");
1576 end if;
1577
1578 List_Component_Layout
1579 (Defining_Identifier (Comp), Indent => Indent);
1580
1581 <<Continue_Comp>>
1582 Next_Non_Pragma (Comp);
1583 end loop;
1584 end if;
1585
1586 -- We are done if there is no variant part
1587
1588 if No (Variant_Part (Comp_List)) then
1589 return;
1590 end if;
1591
1592 Write_Eol;
1593 Spaces (Indent);
1594 Write_Line (" ],");
1595 Spaces (Indent);
1596 Write_Str (" ""variant"" : [");
1597
1598 -- Otherwise we recurse on each variant
1599
1600 Var := First_Non_Pragma (Variants (Variant_Part (Comp_List)));
1601 First := True;
1602 while Present (Var) loop
1603 if First then
1604 Write_Eol;
1605 First := False;
1606 else
1607 Write_Line (",");
1608 end if;
1609
1610 Spaces (Indent);
1611 Write_Line (" {");
1612 Spaces (Indent);
1613 Write_Str (" ""present"": ");
1614 Write_Val (Present_Expr (Var));
1615 Write_Line (",");
1616 Spaces (Indent);
1617 Write_Str (" ""record"": [");
1618
0f9ca030 1619 List_Structural_Record_Layout (Ent, Outer_Ent, Var, Indent + 4);
1e7629b8
EB
1620
1621 Write_Eol;
1622 Spaces (Indent);
1623 Write_Line (" ]");
1624 Spaces (Indent);
1625 Write_Str (" }");
1626 Next_Non_Pragma (Var);
1627 end loop;
1628 end List_Structural_Record_Layout;
1629
3815f967
AC
1630 -- Start of processing for List_Record_Info
1631
1c912574 1632 begin
b5d3d113 1633 Write_Separator;
1c912574 1634
1e7629b8
EB
1635 if List_Representation_Info_To_JSON then
1636 Write_Line ("{");
1637 end if;
1638
6f65c7ee 1639 List_Common_Type_Info (Ent);
1c912574
AC
1640
1641 -- First find out max line length and max starting position
1642 -- length, for the purpose of lining things up nicely.
1643
1644 Compute_Max_Length (Ent);
1645
1646 -- Then do actual output based on those values
1647
1e7629b8
EB
1648 if List_Representation_Info_To_JSON then
1649 Write_Line (",");
1650 Write_Str (" ""record"": [");
1651
abbc4546
EB
1652 -- ??? We can output structural layout only for base types fully
1653 -- declared in the extended main source unit for the time being,
1654 -- because otherwise declarations might not be processed at all.
1655
81d85d4b 1656 if Is_Base_Type (Ent) then
abbc4546
EB
1657 begin
1658 List_Structural_Record_Layout (Ent, Ent);
1659
1660 exception
1661 when Incomplete_Layout
1662 | Not_In_Extended_Main
1663 =>
1664 List_Record_Layout (Ent);
1665
1666 when others =>
1667 raise Program_Error;
1668 end;
81d85d4b
EB
1669 else
1670 List_Record_Layout (Ent);
1671 end if;
1e7629b8
EB
1672
1673 Write_Eol;
1674 Write_Str (" ]");
1675 else
1676 Write_Str ("for ");
1677 List_Name (Ent);
1678 Write_Line (" use record");
1679
1680 List_Record_Layout (Ent);
19235870 1681
1e7629b8
EB
1682 Write_Line ("end record;");
1683 end if;
d9f8616e
AC
1684
1685 List_Scalar_Storage_Order (Ent, Bytes_Big_Endian);
7672ab42
EB
1686
1687 List_Linker_Section (Ent);
1e7629b8
EB
1688
1689 if List_Representation_Info_To_JSON then
1690 Write_Eol;
1691 Write_Line ("}");
1692 end if;
76ccee8f
EB
1693
1694 -- The type is relevant for a record subtype
1695
1696 if List_Representation_Info = 4
1697 and then not Is_Base_Type (Ent)
1698 and then Is_Itype (Etype (Ent))
1699 then
1700 Relevant_Entities.Set (Etype (Ent), True);
1701 end if;
19235870
RK
1702 end List_Record_Info;
1703
1704 -------------------
1705 -- List_Rep_Info --
1706 -------------------
1707
d9f8616e 1708 procedure List_Rep_Info (Bytes_Big_Endian : Boolean) is
19235870
RK
1709 Col : Nat;
1710
1711 begin
fbf5a39b
AC
1712 if List_Representation_Info /= 0
1713 or else List_Representation_Info_Mechanisms
1714 then
b5d3d113
EB
1715 -- For the normal case, we output a single JSON stream
1716
1717 if not List_Representation_Info_To_File
1718 and then List_Representation_Info_To_JSON
1719 then
1720 Write_Line ("[");
1721 Need_Separator := False;
1722 end if;
1723
fbf5a39b
AC
1724 for U in Main_Unit .. Last_Unit loop
1725 if In_Extended_Main_Source_Unit (Cunit_Entity (U)) then
d436b30d 1726 Unit_Casing := Identifier_Casing (Source_Index (U));
07fc65c4 1727
b5f581cd
EB
1728 if List_Representation_Info = 4 then
1729 Relevant_Entities.Reset;
1730 end if;
1731
fbf5a39b 1732 -- Normal case, list to standard output
07fc65c4 1733
de9b2a96
EB
1734 if not List_Representation_Info_To_File then
1735 if not List_Representation_Info_To_JSON then
1736 Write_Eol;
1737 Write_Str ("Representation information for unit ");
1738 Write_Unit_Name (Unit_Name (U));
1739 Col := Column;
1740 Write_Eol;
1741
1742 for J in 1 .. Col - 1 loop
1743 Write_Char ('-');
1744 end loop;
1745
1746 Write_Eol;
b5d3d113 1747 Need_Separator := True;
de9b2a96 1748 end if;
07fc65c4 1749
d9f8616e 1750 List_Entities (Cunit_Entity (U), Bytes_Big_Endian);
07fc65c4 1751
fbf5a39b 1752 -- List representation information to file
07fc65c4 1753
fbf5a39b 1754 else
d3879a5a 1755 Create_Repinfo_File_Access.all
1c28fe3a 1756 (Get_Name_String (File_Name (Source_Index (U))));
fbf5a39b 1757 Set_Special_Output (Write_Info_Line'Access);
b5d3d113
EB
1758 if List_Representation_Info_To_JSON then
1759 Write_Line ("[");
1760 end if;
1761 Need_Separator := False;
d9f8616e 1762 List_Entities (Cunit_Entity (U), Bytes_Big_Endian);
b5d3d113
EB
1763 if List_Representation_Info_To_JSON then
1764 Write_Line ("]");
1765 end if;
e3548b69 1766 Cancel_Special_Output;
fbf5a39b
AC
1767 Close_Repinfo_File_Access.all;
1768 end if;
07fc65c4 1769 end if;
fbf5a39b 1770 end loop;
b5d3d113
EB
1771
1772 if not List_Representation_Info_To_File
1773 and then List_Representation_Info_To_JSON
1774 then
1775 Write_Line ("]");
1776 end if;
fbf5a39b 1777 end if;
19235870
RK
1778 end List_Rep_Info;
1779
d9f8616e
AC
1780 -------------------------------
1781 -- List_Scalar_Storage_Order --
1782 -------------------------------
1783
1784 procedure List_Scalar_Storage_Order
1785 (Ent : Entity_Id;
1786 Bytes_Big_Endian : Boolean)
1787 is
7ed57189
AC
1788 procedure List_Attr (Attr_Name : String; Is_Reversed : Boolean);
1789 -- Show attribute definition clause for Attr_Name (an endianness
1790 -- attribute), depending on whether or not the endianness is reversed
1791 -- compared to native endianness.
d9f8616e
AC
1792
1793 ---------------
1794 -- List_Attr --
1795 ---------------
1796
7ed57189 1797 procedure List_Attr (Attr_Name : String; Is_Reversed : Boolean) is
d9f8616e 1798 begin
1e7629b8
EB
1799 if List_Representation_Info_To_JSON then
1800 Write_Line (",");
972d2984
EB
1801 Write_Str (" """);
1802 Write_Str (Attr_Name);
1803 Write_Str (""": ""System.");
1e7629b8
EB
1804 else
1805 Write_Str ("for ");
1806 List_Name (Ent);
972d2984
EB
1807 Write_Char (''');
1808 Write_Str (Attr_Name);
1809 Write_Str (" use System.");
1e7629b8 1810 end if;
489c6e19 1811
7ed57189 1812 if Bytes_Big_Endian xor Is_Reversed then
d9f8616e
AC
1813 Write_Str ("High");
1814 else
1815 Write_Str ("Low");
1816 end if;
489c6e19 1817
1e7629b8
EB
1818 Write_Str ("_Order_First");
1819 if List_Representation_Info_To_JSON then
1820 Write_Str ("""");
1821 else
1822 Write_Line (";");
1823 end if;
d9f8616e
AC
1824 end List_Attr;
1825
7ed57189
AC
1826 List_SSO : constant Boolean :=
1827 Has_Rep_Item (Ent, Name_Scalar_Storage_Order)
1828 or else SSO_Set_Low_By_Default (Ent)
1829 or else SSO_Set_High_By_Default (Ent);
31fde973
GD
1830 -- Scalar_Storage_Order is displayed if specified explicitly or set by
1831 -- Default_Scalar_Storage_Order.
7ed57189 1832
d9f8616e
AC
1833 -- Start of processing for List_Scalar_Storage_Order
1834
1835 begin
7ed57189 1836 -- For record types, list Bit_Order if not default, or if SSO is shown
d9f8616e 1837
6aaab508
JS
1838 -- Also, when -gnatR4 is in effect always list bit order and scalar
1839 -- storage order explicitly, so that you don't need to know the native
1840 -- endianness of the target for which the output was produced in order
1841 -- to interpret it.
1842
7ed57189 1843 if Is_Record_Type (Ent)
6aaab508
JS
1844 and then (List_SSO
1845 or else Reverse_Bit_Order (Ent)
1846 or else List_Representation_Info = 4)
220d1fd9 1847 then
7ed57189
AC
1848 List_Attr ("Bit_Order", Reverse_Bit_Order (Ent));
1849 end if;
d9f8616e 1850
7ed57189
AC
1851 -- List SSO if required. If not, then storage is supposed to be in
1852 -- native order.
489c6e19 1853
6aaab508 1854 if List_SSO or else List_Representation_Info = 4 then
7ed57189
AC
1855 List_Attr ("Scalar_Storage_Order", Reverse_Storage_Order (Ent));
1856 else
1857 pragma Assert (not Reverse_Storage_Order (Ent));
1858 null;
d9f8616e
AC
1859 end if;
1860 end List_Scalar_Storage_Order;
1861
6f65c7ee
EB
1862 --------------------------
1863 -- List_Subprogram_Info --
1864 --------------------------
1865
1866 procedure List_Subprogram_Info (Ent : Entity_Id) is
1867 First : Boolean := True;
1868 Plen : Natural;
1869 Form : Entity_Id;
19235870 1870
19235870 1871 begin
b5d3d113 1872 Write_Separator;
6f65c7ee 1873
1e7629b8 1874 if List_Representation_Info_To_JSON then
6f65c7ee 1875 Write_Line ("{");
1e7629b8
EB
1876 Write_Str (" ""name"": """);
1877 List_Name (Ent);
1878 Write_Line (""",");
1879 List_Location (Ent);
6f65c7ee
EB
1880
1881 Write_Str (" ""Convention"": """);
1882 else
1883 case Ekind (Ent) is
1884 when E_Function =>
1885 Write_Str ("function ");
1886
1887 when E_Operator =>
1888 Write_Str ("operator ");
1889
1890 when E_Procedure =>
1891 Write_Str ("procedure ");
1892
1893 when E_Subprogram_Type =>
1894 Write_Str ("type ");
1895
1896 when E_Entry
1897 | E_Entry_Family
1898 =>
1899 Write_Str ("entry ");
1900
1901 when others =>
1902 raise Program_Error;
1903 end case;
1904
1905 List_Name (Ent);
1906 Write_Str (" declared at ");
1907 Write_Location (Sloc (Ent));
1908 Write_Eol;
1909
1910 Write_Str ("convention : ");
1e7629b8
EB
1911 end if;
1912
6f65c7ee
EB
1913 case Convention (Ent) is
1914 when Convention_Ada =>
1915 Write_Str ("Ada");
07fc65c4 1916
6f65c7ee
EB
1917 when Convention_Ada_Pass_By_Copy =>
1918 Write_Str ("Ada_Pass_By_Copy");
1919
1920 when Convention_Ada_Pass_By_Reference =>
1921 Write_Str ("Ada_Pass_By_Reference");
1922
1923 when Convention_Intrinsic =>
1924 Write_Str ("Intrinsic");
1925
1926 when Convention_Entry =>
1927 Write_Str ("Entry");
1928
1929 when Convention_Protected =>
1930 Write_Str ("Protected");
07fc65c4 1931
6f65c7ee
EB
1932 when Convention_Assembler =>
1933 Write_Str ("Assembler");
1934
1935 when Convention_C =>
1936 Write_Str ("C");
1937
1938 when Convention_COBOL =>
1939 Write_Str ("COBOL");
1940
1941 when Convention_CPP =>
1942 Write_Str ("C++");
1943
1944 when Convention_Fortran =>
1945 Write_Str ("Fortran");
1946
1947 when Convention_Stdcall =>
1948 Write_Str ("Stdcall");
1949
1950 when Convention_Stubbed =>
1951 Write_Str ("Stubbed");
1952 end case;
1953
1954 if List_Representation_Info_To_JSON then
1955 Write_Line (""",");
1956 Write_Str (" ""formal"": [");
07fc65c4 1957 else
6f65c7ee
EB
1958 Write_Eol;
1959 end if;
19235870 1960
6f65c7ee
EB
1961 -- Find max length of formal name
1962
1963 Plen := 0;
1964 Form := First_Formal (Ent);
1965 while Present (Form) loop
1966 Get_Unqualified_Decoded_Name_String (Chars (Form));
1967
1968 if Name_Len > Plen then
1969 Plen := Name_Len;
1970 end if;
1971
1972 Next_Formal (Form);
1973 end loop;
1974
1975 -- Output formals and mechanisms
1976
1977 Form := First_Formal (Ent);
1978 while Present (Form) loop
1979 Get_Unqualified_Decoded_Name_String (Chars (Form));
1980 Set_Casing (Unit_Casing);
1981
1982 if List_Representation_Info_To_JSON then
1983 if First then
1984 Write_Eol;
1985 First := False;
1e7629b8 1986 else
6f65c7ee 1987 Write_Line (",");
1e7629b8 1988 end if;
19235870 1989
6f65c7ee
EB
1990 Write_Line (" {");
1991 Write_Str (" ""name"": """);
1992 Write_Str (Name_Buffer (1 .. Name_Len));
1993 Write_Line (""",");
19235870 1994
6f65c7ee
EB
1995 Write_Str (" ""mechanism"": """);
1996 Write_Mechanism (Mechanism (Form));
1997 Write_Line ("""");
1998 Write_Str (" }");
07fc65c4 1999 else
6f65c7ee
EB
2000 while Name_Len <= Plen loop
2001 Name_Len := Name_Len + 1;
2002 Name_Buffer (Name_Len) := ' ';
2003 end loop;
19235870 2004
6f65c7ee
EB
2005 Write_Str (" ");
2006 Write_Str (Name_Buffer (1 .. Plen + 1));
2007 Write_Str (": passed by ");
1e7629b8 2008
6f65c7ee
EB
2009 Write_Mechanism (Mechanism (Form));
2010 Write_Eol;
2011 end if;
1e7629b8 2012
6f65c7ee
EB
2013 Next_Formal (Form);
2014 end loop;
2015
2016 if List_Representation_Info_To_JSON then
2017 Write_Eol;
2018 Write_Str (" ]");
2019 end if;
2020
2021 if Ekind (Ent) = E_Function then
2022 if List_Representation_Info_To_JSON then
2023 Write_Line (",");
2024 Write_Str (" ""mechanism"": """);
2025 Write_Mechanism (Mechanism (Ent));
2026 Write_Str ("""");
2027 else
2028 Write_Str ("returns by ");
2029 Write_Mechanism (Mechanism (Ent));
2030 Write_Eol;
19235870
RK
2031 end if;
2032 end if;
2033
6f65c7ee
EB
2034 if not Is_Entry (Ent) then
2035 List_Linker_Section (Ent);
2036 end if;
2037
1e7629b8 2038 if List_Representation_Info_To_JSON then
6f65c7ee
EB
2039 Write_Eol;
2040 Write_Line ("}");
1e7629b8 2041 end if;
6f65c7ee
EB
2042 end List_Subprogram_Info;
2043
2044 --------------------
2045 -- List_Type_Info --
2046 --------------------
2047
2048 procedure List_Type_Info (Ent : Entity_Id) is
2049 begin
b5d3d113 2050 Write_Separator;
6f65c7ee
EB
2051
2052 if List_Representation_Info_To_JSON then
2053 Write_Line ("{");
2054 end if;
2055
2056 List_Common_Type_Info (Ent);
0d57c6f4
RD
2057
2058 -- Special stuff for fixed-point
2059
2060 if Is_Fixed_Point_Type (Ent) then
2061
2062 -- Write small (always a static constant)
2063
1e7629b8
EB
2064 if List_Representation_Info_To_JSON then
2065 Write_Line (",");
2066 Write_Str (" ""Small"": ");
2067 UR_Write (Small_Value (Ent));
2068 else
2069 Write_Str ("for ");
2070 List_Name (Ent);
2071 Write_Str ("'Small use ");
2072 UR_Write (Small_Value (Ent));
2073 Write_Line (";");
2074 end if;
0d57c6f4
RD
2075
2076 -- Write range if static
2077
2078 declare
2079 R : constant Node_Id := Scalar_Range (Ent);
2080
2081 begin
2082 if Nkind (Low_Bound (R)) = N_Real_Literal
2083 and then
2084 Nkind (High_Bound (R)) = N_Real_Literal
2085 then
1e7629b8
EB
2086 if List_Representation_Info_To_JSON then
2087 Write_Line (",");
2088 Write_Str (" ""Range"": [ ");
2089 UR_Write (Realval (Low_Bound (R)));
2090 Write_Str (", ");
2091 UR_Write (Realval (High_Bound (R)));
2092 Write_Str (" ]");
2093 else
2094 Write_Str ("for ");
2095 List_Name (Ent);
2096 Write_Str ("'Range use ");
2097 UR_Write (Realval (Low_Bound (R)));
2098 Write_Str (" .. ");
2099 UR_Write (Realval (High_Bound (R)));
2100 Write_Line (";");
2101 end if;
0d57c6f4
RD
2102 end if;
2103 end;
2104 end if;
6f65c7ee
EB
2105
2106 List_Linker_Section (Ent);
2107
2108 if List_Representation_Info_To_JSON then
2109 Write_Eol;
2110 Write_Line ("}");
2111 end if;
19235870
RK
2112 end List_Type_Info;
2113
2114 ----------------------
2115 -- Rep_Not_Constant --
2116 ----------------------
2117
2118 function Rep_Not_Constant (Val : Node_Ref_Or_Val) return Boolean is
2119 begin
2120 if Val = No_Uint or else Val < 0 then
2121 return True;
2122 else
2123 return False;
2124 end if;
2125 end Rep_Not_Constant;
2126
2127 ---------------
2128 -- Rep_Value --
2129 ---------------
2130
972d2984
EB
2131 function Rep_Value (Val : Node_Ref_Or_Val; D : Discrim_List) return Uint is
2132
19235870
RK
2133 function B (Val : Boolean) return Uint;
2134 -- Returns Uint_0 for False, Uint_1 for True
2135
2136 function T (Val : Node_Ref_Or_Val) return Boolean;
2137 -- Returns True for 0, False for any non-zero (i.e. True)
2138
2139 function V (Val : Node_Ref_Or_Val) return Uint;
2140 -- Internal recursive routine to evaluate tree
2141
5e61ef09 2142 function W (Val : Uint) return Word;
0d57c6f4
RD
2143 -- Convert Val to Word, assuming Val is always in the Int range. This
2144 -- is a helper function for the evaluation of bitwise expressions like
5e61ef09
TQ
2145 -- Bit_And_Expr, for which there is no direct support in uintp. Uint
2146 -- values out of the Int range are expected to be seen in such
2147 -- expressions only with overflowing byte sizes around, introducing
276e95ca 2148 -- inherent unreliabilities in computations anyway.
5e61ef09 2149
19235870
RK
2150 -------
2151 -- B --
2152 -------
2153
2154 function B (Val : Boolean) return Uint is
2155 begin
2156 if Val then
2157 return Uint_1;
2158 else
2159 return Uint_0;
2160 end if;
2161 end B;
2162
2163 -------
2164 -- T --
2165 -------
2166
2167 function T (Val : Node_Ref_Or_Val) return Boolean is
2168 begin
2169 if V (Val) = 0 then
2170 return False;
2171 else
2172 return True;
2173 end if;
2174 end T;
2175
2176 -------
2177 -- V --
2178 -------
2179
2180 function V (Val : Node_Ref_Or_Val) return Uint is
2181 L, R, Q : Uint;
2182
2183 begin
2184 if Val >= 0 then
2185 return Val;
2186
2187 else
2188 declare
2189 Node : Exp_Node renames Rep_Table.Table (-UI_To_Int (Val));
2190
2191 begin
2192 case Node.Expr is
2193 when Cond_Expr =>
2194 if T (Node.Op1) then
2195 return V (Node.Op2);
2196 else
2197 return V (Node.Op3);
2198 end if;
2199
2200 when Plus_Expr =>
2201 return V (Node.Op1) + V (Node.Op2);
2202
2203 when Minus_Expr =>
2204 return V (Node.Op1) - V (Node.Op2);
2205
2206 when Mult_Expr =>
2207 return V (Node.Op1) * V (Node.Op2);
2208
2209 when Trunc_Div_Expr =>
2210 return V (Node.Op1) / V (Node.Op2);
2211
2212 when Ceil_Div_Expr =>
2213 return
2214 UR_Ceiling
2215 (V (Node.Op1) / UR_From_Uint (V (Node.Op2)));
2216
2217 when Floor_Div_Expr =>
2218 return
2219 UR_Floor
2220 (V (Node.Op1) / UR_From_Uint (V (Node.Op2)));
2221
2222 when Trunc_Mod_Expr =>
2223 return V (Node.Op1) rem V (Node.Op2);
2224
2225 when Floor_Mod_Expr =>
2226 return V (Node.Op1) mod V (Node.Op2);
2227
2228 when Ceil_Mod_Expr =>
2229 L := V (Node.Op1);
2230 R := V (Node.Op2);
2231 Q := UR_Ceiling (L / UR_From_Uint (R));
2232 return L - R * Q;
2233
2234 when Exact_Div_Expr =>
2235 return V (Node.Op1) / V (Node.Op2);
2236
2237 when Negate_Expr =>
2238 return -V (Node.Op1);
2239
2240 when Min_Expr =>
2241 return UI_Min (V (Node.Op1), V (Node.Op2));
2242
2243 when Max_Expr =>
2244 return UI_Max (V (Node.Op1), V (Node.Op2));
2245
2246 when Abs_Expr =>
2247 return UI_Abs (V (Node.Op1));
2248
19235870 2249 when Truth_And_Expr =>
d1ced162 2250 return B (T (Node.Op1) and then T (Node.Op2));
19235870
RK
2251
2252 when Truth_Or_Expr =>
d1ced162 2253 return B (T (Node.Op1) or else T (Node.Op2));
19235870
RK
2254
2255 when Truth_Xor_Expr =>
2256 return B (T (Node.Op1) xor T (Node.Op2));
2257
2258 when Truth_Not_Expr =>
2259 return B (not T (Node.Op1));
2260
5e61ef09
TQ
2261 when Bit_And_Expr =>
2262 L := V (Node.Op1);
2263 R := V (Node.Op2);
2264 return UI_From_Int (Int (W (L) and W (R)));
2265
19235870
RK
2266 when Lt_Expr =>
2267 return B (V (Node.Op1) < V (Node.Op2));
2268
2269 when Le_Expr =>
2270 return B (V (Node.Op1) <= V (Node.Op2));
2271
2272 when Gt_Expr =>
2273 return B (V (Node.Op1) > V (Node.Op2));
2274
2275 when Ge_Expr =>
2276 return B (V (Node.Op1) >= V (Node.Op2));
2277
2278 when Eq_Expr =>
2279 return B (V (Node.Op1) = V (Node.Op2));
2280
2281 when Ne_Expr =>
2282 return B (V (Node.Op1) /= V (Node.Op2));
2283
2284 when Discrim_Val =>
2285 declare
2286 Sub : constant Int := UI_To_Int (Node.Op1);
19235870
RK
2287 begin
2288 pragma Assert (Sub in D'Range);
2289 return D (Sub);
2290 end;
e45f84a5
EB
2291
2292 when Dynamic_Val =>
2293 return No_Uint;
19235870
RK
2294 end case;
2295 end;
2296 end if;
2297 end V;
2298
d3879a5a
RD
2299 -------
2300 -- W --
2301 -------
2302
2303 -- We use an unchecked conversion to map Int values to their Word
2304 -- bitwise equivalent, which we could not achieve with a normal type
2305 -- conversion for negative Ints. We want bitwise equivalents because W
2306 -- is used as a helper for bit operators like Bit_And_Expr, and can be
2307 -- called for negative Ints in the context of aligning expressions like
2308 -- X+Align & -Align.
2309
2310 function W (Val : Uint) return Word is
2311 function To_Word is new Ada.Unchecked_Conversion (Int, Word);
2312 begin
2313 return To_Word (UI_To_Int (Val));
2314 end W;
2315
19235870
RK
2316 -- Start of processing for Rep_Value
2317
2318 begin
2319 if Val = No_Uint then
2320 return No_Uint;
2321
2322 else
2323 return V (Val);
2324 end if;
2325 end Rep_Value;
2326
2327 ------------
2328 -- Spaces --
2329 ------------
2330
2331 procedure Spaces (N : Natural) is
2332 begin
2333 for J in 1 .. N loop
2334 Write_Char (' ');
2335 end loop;
2336 end Spaces;
2337
fbf5a39b
AC
2338 ---------------------
2339 -- Write_Info_Line --
2340 ---------------------
2341
2342 procedure Write_Info_Line (S : String) is
2343 begin
2344 Write_Repinfo_Line_Access.all (S (S'First .. S'Last - 1));
2345 end Write_Info_Line;
2346
2347 ---------------------
2348 -- Write_Mechanism --
2349 ---------------------
2350
2351 procedure Write_Mechanism (M : Mechanism_Type) is
2352 begin
2353 case M is
2354 when 0 =>
2355 Write_Str ("default");
2356
2357 when -1 =>
2358 Write_Str ("copy");
2359
2360 when -2 =>
2361 Write_Str ("reference");
2362
fbf5a39b
AC
2363 when others =>
2364 raise Program_Error;
2365 end case;
2366 end Write_Mechanism;
2367
b5d3d113
EB
2368 ---------------------
2369 -- Write_Separator --
2370 ---------------------
2371
2372 procedure Write_Separator is
2373 begin
2374 if Need_Separator then
2375 if List_Representation_Info_To_JSON then
2376 Write_Line (",");
2377 else
2378 Write_Eol;
2379 end if;
2380 else
2381 Need_Separator := True;
2382 end if;
2383 end Write_Separator;
2384
76b382d9
EB
2385 -----------------------
2386 -- Write_Unknown_Val --
2387 -----------------------
2388
2389 procedure Write_Unknown_Val is
2390 begin
1e7629b8
EB
2391 if List_Representation_Info_To_JSON then
2392 Write_Str ("""??""");
2393 else
2394 Write_Str ("??");
2395 end if;
76b382d9
EB
2396 end Write_Unknown_Val;
2397
19235870
RK
2398 ---------------
2399 -- Write_Val --
2400 ---------------
2401
2402 procedure Write_Val (Val : Node_Ref_Or_Val; Paren : Boolean := False) is
2403 begin
2404 if Rep_Not_Constant (Val) then
07fc65c4 2405 if List_Representation_Info < 3 or else Val = No_Uint then
76b382d9 2406 Write_Unknown_Val;
07fc65c4 2407
19235870 2408 else
98b779ae
PMR
2409 if Paren then
2410 Write_Char ('(');
2411 end if;
07fc65c4 2412
98b779ae
PMR
2413 if Back_End_Layout then
2414 List_GCC_Expression (Val);
19235870 2415 else
98b779ae
PMR
2416 Write_Name_Decoded (Chars (Get_Dynamic_SO_Entity (Val)));
2417 end if;
2418
2419 if Paren then
2420 Write_Char (')');
19235870
RK
2421 end if;
2422 end if;
2423
2424 else
f9534f4b 2425 UI_Write (Val, Decimal);
19235870
RK
2426 end if;
2427 end Write_Val;
2428
2429end Repinfo;