1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1999-2025, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
27 with Atree; use Atree;
28 with Casing; use Casing;
29 with Debug; use Debug;
30 with Einfo; use Einfo;
31 with Einfo.Entities; use Einfo.Entities;
32 with Einfo.Utils; use Einfo.Utils;
33 with GNAT.Heap_Sort_G;
35 with Namet; use Namet;
36 with Nlists; use Nlists;
38 with Output; use Output;
39 with Osint.C; use Osint.C;
40 with Sem_Aux; use Sem_Aux;
41 with Sem_Eval; use Sem_Eval;
43 with Sinfo; use Sinfo;
44 with Sinfo.Nodes; use Sinfo.Nodes;
45 with Sinfo.Utils; use Sinfo.Utils;
46 with Sinput; use Sinput;
47 with Snames; use Snames;
48 with Stand; use Stand;
49 with Stringt; use Stringt;
52 with Uname; use Uname;
53 with Urealp; use Urealp;
55 with Ada.Unchecked_Conversion;
59 package body Repinfo is
61 SSU : Pos renames Ttypes.System_Storage_Unit;
62 -- Value for Storage_Unit
64 ---------------------------------------
65 -- Representation of GCC Expressions --
66 ---------------------------------------
68 -- A table internal to this unit is used to hold the values of back
69 -- annotated expressions.
71 -- Node values are stored as Uint values using the negative of the node
72 -- index in this table. Constants appear as non-negative Uint values.
74 type Exp_Node is record
76 Op1 : Node_Ref_Or_Val;
77 Op2 : Node_Ref_Or_Val;
78 Op3 : Node_Ref_Or_Val;
81 package Rep_Table is new Table.Table (
82 Table_Component_Type => Exp_Node,
83 Table_Index_Type => Nat,
85 Table_Initial => Alloc.Rep_Table_Initial,
86 Table_Increment => Alloc.Rep_Table_Increment,
87 Table_Name => "BE_Rep_Table");
89 --------------------------------------------------------------
90 -- Representation of Front-End Dynamic Size/Offset Entities --
91 --------------------------------------------------------------
93 package Dynamic_SO_Entity_Table is new Table.Table (
94 Table_Component_Type => Entity_Id,
95 Table_Index_Type => Nat,
97 Table_Initial => Alloc.Rep_Table_Initial,
98 Table_Increment => Alloc.Rep_Table_Increment,
99 Table_Name => "FE_Rep_Table");
101 Unit_Casing : Casing_Type;
102 -- Identifier casing for current unit. This is set by List_Rep_Info for
103 -- each unit, before calling subprograms which may read it.
105 Need_Separator : Boolean;
106 -- Set True if a separator is needed before outputting any information for
107 -- the current entity.
109 ------------------------------
110 -- Set of Relevant Entities --
111 ------------------------------
113 Relevant_Entities_Size : constant := 4093;
114 -- Number of headers in hash table
116 subtype Entity_Header_Num is Integer range 0 .. Relevant_Entities_Size - 1;
117 -- Range of headers in hash table
119 function Entity_Hash (Id : Entity_Id) return Entity_Header_Num;
120 -- Simple hash function for Entity_Ids
122 package Relevant_Entities is new GNAT.Htable.Simple_HTable
123 (Header_Num => Entity_Header_Num,
129 -- Hash table to record which compiler-generated entities are relevant
131 -----------------------
132 -- Local Subprograms --
133 -----------------------
135 procedure List_Entities
137 Bytes_Big_Endian : Boolean;
138 In_Subprogram : Boolean := False);
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.
142 -- When recursing within a subprogram body, Is_Subprogram suppresses
143 -- duplicate information about signature.
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.
149 procedure List_Array_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean);
150 -- List representation info for array type Ent
152 procedure List_Common_Type_Info (Ent : Entity_Id);
153 -- List common type info (name, size, alignment) for type Ent
155 procedure List_Linker_Section (Ent : Entity_Id);
156 -- List linker section for Ent (caller has checked that Ent is an entity
157 -- for which the Linker_Section_Pragma field is defined).
159 procedure List_Location (Ent : Entity_Id);
160 -- List location information for Ent
162 procedure List_Object_Info (Ent : Entity_Id);
163 -- List representation info for object Ent
165 procedure List_Record_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean);
166 -- List representation info for record type Ent
168 procedure List_Scalar_Storage_Order
170 Bytes_Big_Endian : Boolean);
171 -- List scalar storage order information for record or array type Ent.
172 -- Also includes bit order information for record types, if necessary.
174 procedure List_Subprogram_Info (Ent : Entity_Id);
175 -- List subprogram info for subprogram Ent
177 procedure List_Type_Info (Ent : Entity_Id);
178 -- List type info for type Ent
180 function Compile_Time_Known_Rep (Val : Node_Ref_Or_Val) return Boolean;
181 -- Returns True if Val represents a representation value that is known at
184 procedure Spaces (N : Natural);
185 -- Output given number of spaces
187 procedure Write_Info_Line (S : String);
188 -- Routine to write a line to Repinfo output file. This routine is passed
189 -- as a special output procedure to Output.Set_Special_Output. Note that
190 -- Write_Info_Line is called with an EOL character at the end of each line,
191 -- as per the Output spec, but the internal call to the appropriate routine
192 -- in Osint requires that the end of line sequence be stripped off.
194 procedure Write_Mechanism (M : Mechanism_Type);
195 -- Writes symbolic string for mechanism represented by M
197 procedure Write_Separator;
198 -- Called before outputting anything for an entity. Ensures that
199 -- a separator precedes the output for a particular entity.
201 procedure Write_Unknown_Val;
202 -- Writes symbolic string for an unknown or non-representable value
204 procedure Write_Val (Val : Node_Ref_Or_Val; Paren : Boolean := False);
205 -- Given a representation value, write it out. No_Uint values or values
206 -- dependent on discriminants are written as two question marks. If the
207 -- flag Paren is set, then the output is surrounded in parentheses if it is
208 -- other than a simple value.
210 ------------------------
211 -- Create_Discrim_Ref --
212 ------------------------
214 function Create_Discrim_Ref (Discr : Entity_Id) return Node_Ref is
217 (Expr => Discrim_Val,
218 Op1 => Discriminant_Number (Discr));
219 end Create_Discrim_Ref;
221 ---------------------------
222 -- Create_Dynamic_SO_Ref --
223 ---------------------------
225 function Create_Dynamic_SO_Ref (E : Entity_Id) return Dynamic_SO_Ref is
227 Dynamic_SO_Entity_Table.Append (E);
228 return UI_From_Int (-Dynamic_SO_Entity_Table.Last);
229 end Create_Dynamic_SO_Ref;
237 Op1 : Node_Ref_Or_Val;
238 Op2 : Node_Ref_Or_Val := No_Uint;
239 Op3 : Node_Ref_Or_Val := No_Uint) return Node_Ref
247 return UI_From_Int (-Rep_Table.Last);
254 function Entity_Hash (Id : Entity_Id) return Entity_Header_Num is
256 return Entity_Header_Num (Id mod Relevant_Entities_Size);
259 ---------------------------
260 -- Get_Dynamic_SO_Entity --
261 ---------------------------
263 function Get_Dynamic_SO_Entity (U : Dynamic_SO_Ref) return Entity_Id is
265 return Dynamic_SO_Entity_Table.Table (-UI_To_Int (U));
266 end Get_Dynamic_SO_Entity;
268 -----------------------
269 -- Is_Dynamic_SO_Ref --
270 -----------------------
272 function Is_Dynamic_SO_Ref (U : SO_Ref) return Boolean is
275 end Is_Dynamic_SO_Ref;
277 ----------------------
278 -- Is_Static_SO_Ref --
279 ----------------------
281 function Is_Static_SO_Ref (U : SO_Ref) return Boolean is
284 end Is_Static_SO_Ref;
290 procedure lgx (U : Node_Ref_Or_Val) is
292 List_GCC_Expression (U);
296 ----------------------
297 -- List_Array_Info --
298 ----------------------
300 procedure List_Array_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean) is
304 if List_Representation_Info_To_JSON then
308 List_Common_Type_Info (Ent);
310 if List_Representation_Info_To_JSON then
312 Write_Str (" ""Component_Size"": ");
313 Write_Val (Component_Size (Ent));
317 Write_Str ("'Component_Size use ");
318 Write_Val (Component_Size (Ent));
322 List_Scalar_Storage_Order (Ent, Bytes_Big_Endian);
324 List_Linker_Section (Ent);
326 if List_Representation_Info_To_JSON then
331 -- The component type is relevant for an array
333 if List_Representation_Info = 4
334 and then Is_Itype (Component_Type (Base_Type (Ent)))
336 Relevant_Entities.Set (Component_Type (Base_Type (Ent)), True);
340 ---------------------------
341 -- List_Common_Type_Info --
342 ---------------------------
344 procedure List_Common_Type_Info (Ent : Entity_Id) is
346 if List_Representation_Info_To_JSON then
347 Write_Str (" ""name"": """);
353 -- Do not list size info for unconstrained arrays, not meaningful
355 if Is_Array_Type (Ent) and then not Is_Constrained (Ent) then
359 if Known_Esize (Ent) and then Known_RM_Size (Ent) then
360 -- If Esize and RM_Size are the same, list as Size. This is a
361 -- common case, which we may as well list in simple form.
363 if Esize (Ent) = RM_Size (Ent) then
364 if List_Representation_Info_To_JSON then
365 Write_Str (" ""Size"": ");
366 Write_Val (Esize (Ent));
371 Write_Str ("'Size use ");
372 Write_Val (Esize (Ent));
376 -- Otherwise list size values separately
379 if List_Representation_Info_To_JSON then
380 Write_Str (" ""Object_Size"": ");
381 Write_Val (Esize (Ent));
384 Write_Str (" ""Value_Size"": ");
385 Write_Val (RM_Size (Ent));
391 Write_Str ("'Object_Size use ");
392 Write_Val (Esize (Ent));
397 Write_Str ("'Value_Size use ");
398 Write_Val (RM_Size (Ent));
405 if Known_Alignment (Ent) then
406 if List_Representation_Info_To_JSON then
407 Write_Str (" ""Alignment"": ");
408 Write_Val (Alignment (Ent));
412 Write_Str ("'Alignment use ");
413 Write_Val (Alignment (Ent));
417 -- Alignment is not always set for concurrent types, class-wide types,
418 -- cloned subtypes, or when doing semantic analysis only. Representation
419 -- aspects are not computed for types declared in a generic unit.
422 -- Add unknown alignment entry in JSON format to ensure the format is
423 -- valid, as a comma is added by the caller before another field.
425 if List_Representation_Info_To_JSON then
426 Write_Str (" ""Alignment"": ");
430 pragma Assert (not Expander_Active
431 or else Is_Concurrent_Type (Ent)
432 or else Is_Class_Wide_Type (Ent)
433 or else (Ekind (Ent) = E_Record_Subtype
434 and then Present (Cloned_Subtype (Ent))
435 and then Has_Delayed_Freeze (Cloned_Subtype (Ent)))
436 or else Sem_Util.In_Generic_Scope (Ent));
438 end List_Common_Type_Info;
444 procedure List_Entities
446 Bytes_Big_Endian : Boolean;
447 In_Subprogram : Boolean := False)
452 -- List entity if we have one, and it is not a renaming declaration.
453 -- For renamings, we don't get proper information, and really it makes
454 -- sense to restrict the output to the renamed entity.
457 and then Nkind (Declaration_Node (Ent)) not in N_Renaming_Declaration
458 and then not Is_Ignored_Ghost_Entity (Ent)
460 -- If entity is a subprogram and we are listing mechanisms,
461 -- then we need to list mechanisms for this entity. We skip this
462 -- if it is a nested subprogram, as the information has already
463 -- been produced when listing the enclosing scope.
465 if List_Representation_Info_Mechanisms
466 and then Is_Subprogram_Or_Entry (Ent)
467 and then not In_Subprogram
469 List_Subprogram_Info (Ent);
472 E := First_Entity (Ent);
473 while Present (E) loop
474 -- We list entities that come from source (excluding private or
475 -- incomplete types or deferred constants, for which we will list
476 -- the information for the full view). If requested, we also list
477 -- relevant entities that have been generated when processing the
478 -- original entities coming from source. But if debug flag A is
479 -- set, then all entities are listed.
481 if ((Comes_From_Source (E)
482 or else (Ekind (E) = E_Block
484 Nkind (Parent (E)) = N_Implicit_Label_Declaration
486 Comes_From_Source (Label_Construct (Parent (E)))))
487 and then not Is_Incomplete_Or_Private_Type (E)
488 and then not (Ekind (E) = E_Constant
489 and then Present (Full_View (E))))
490 or else (List_Representation_Info = 4
491 and then Relevant_Entities.Get (E))
492 or else Debug_Flag_AA
494 if Is_Subprogram (E) then
495 if List_Representation_Info_Mechanisms then
496 List_Subprogram_Info (E);
499 -- Recurse into entities local to subprogram
501 List_Entities (E, Bytes_Big_Endian, True);
503 elsif Ekind (E) in E_Entry
507 if List_Representation_Info_Mechanisms then
508 List_Subprogram_Info (E);
511 elsif Is_Record_Type (E) then
512 if List_Representation_Info >= 1 then
513 if Is_Private_Type (E) then
514 List_Record_Info (Full_View (E), Bytes_Big_Endian);
516 List_Record_Info (E, Bytes_Big_Endian);
519 -- Recurse into entities local to a record type
521 if List_Representation_Info = 4 then
522 List_Entities (E, Bytes_Big_Endian, False);
526 elsif Is_Array_Type (E) then
527 if List_Representation_Info >= 1 then
528 List_Array_Info (E, Bytes_Big_Endian);
531 elsif Is_Type (E) then
532 if List_Representation_Info >= 2 then
536 -- Formals and renamings are not annotated, so we skip them
539 elsif Ekind (E) in E_Constant
542 and then Nkind (Parent (E)) /= N_Object_Renaming_Declaration
544 if List_Representation_Info >= 2 then
545 List_Object_Info (E);
549 -- Recurse into nested package, but not child packages, and not
550 -- nested package renamings (in particular renamings of the
551 -- enclosing package, as for some Java bindings and for generic
554 if Ekind (E) = E_Package then
555 if No (Renamed_Entity (E)) and then not Is_Child_Unit (E)
557 List_Entities (E, Bytes_Big_Endian);
560 -- Recurse into bodies
562 elsif Ekind (E) in E_Package_Body
569 List_Entities (E, Bytes_Big_Endian);
571 -- Recurse into blocks
573 elsif Ekind (E) = E_Block then
574 List_Entities (E, Bytes_Big_Endian);
583 -------------------------
584 -- List_GCC_Expression --
585 -------------------------
587 procedure List_GCC_Expression (U : Node_Ref_Or_Val) is
589 procedure Print_Expr (Val : Node_Ref_Or_Val);
590 -- Internal recursive procedure to print expression
596 procedure Print_Expr (Val : Node_Ref_Or_Val) is
599 UI_Write (Val, Decimal);
603 Node : Exp_Node renames Rep_Table.Table (-UI_To_Int (Val));
605 procedure Unop (S : String);
606 -- Output text for unary operator with S being operator name
608 procedure Binop (S : String);
609 -- Output text for binary operator with S being operator name
615 procedure Unop (S : String) is
617 if List_Representation_Info_To_JSON then
618 Write_Str ("{ ""code"": """);
619 if S (S'Last) = ' ' then
620 Write_Str (S (S'First .. S'Last - 1));
624 Write_Str (""", ""operands"": [ ");
625 Print_Expr (Node.Op1);
629 Print_Expr (Node.Op1);
637 procedure Binop (S : String) is
639 if List_Representation_Info_To_JSON then
640 Write_Str ("{ ""code"": """);
641 Write_Str (S (S'First + 1 .. S'Last - 1));
642 Write_Str (""", ""operands"": [ ");
643 Print_Expr (Node.Op1);
645 Print_Expr (Node.Op2);
649 Print_Expr (Node.Op1);
651 Print_Expr (Node.Op2);
656 -- Start of processing for Print_Expr
661 if List_Representation_Info_To_JSON then
662 Write_Str ("{ ""code"": ""?<>""");
663 Write_Str (", ""operands"": [ ");
664 Print_Expr (Node.Op1);
666 Print_Expr (Node.Op2);
668 Print_Expr (Node.Op3);
672 Print_Expr (Node.Op1);
673 Write_Str (" then ");
674 Print_Expr (Node.Op2);
675 Write_Str (" else ");
676 Print_Expr (Node.Op3);
689 when Trunc_Div_Expr =>
692 when Ceil_Div_Expr =>
695 when Floor_Div_Expr =>
698 when Trunc_Mod_Expr =>
701 when Ceil_Mod_Expr =>
704 when Floor_Mod_Expr =>
707 when Exact_Div_Expr =>
722 when Truth_And_Expr =>
725 when Truth_Or_Expr =>
728 when Truth_Xor_Expr =>
731 when Truth_Not_Expr =>
765 -- Start of processing for List_GCC_Expression
773 end List_GCC_Expression;
775 -------------------------
776 -- List_Linker_Section --
777 -------------------------
779 procedure List_Linker_Section (Ent : Entity_Id) is
784 if Present (Linker_Section_Pragma (Ent)) then
785 Args := Pragma_Argument_Associations (Linker_Section_Pragma (Ent));
786 Sect := Expr_Value_S (Get_Pragma_Arg (Last (Args)));
788 if List_Representation_Info_To_JSON then
790 Write_Str (" ""Linker_Section"": """);
792 Write_Str ("pragma Linker_Section (");
797 pragma Assert (Nkind (Sect) = N_String_Literal);
798 String_To_Name_Buffer (Strval (Sect));
799 Write_Str (Name_Buffer (1 .. Name_Len));
801 if not List_Representation_Info_To_JSON then
805 end List_Linker_Section;
811 procedure List_Location (Ent : Entity_Id) is
813 pragma Assert (List_Representation_Info_To_JSON);
814 Write_Str (" ""location"": """);
815 Write_Location (Sloc (Ent));
823 procedure List_Name (Ent : Entity_Id) is
827 -- In JSON mode, we recurse up to Standard. This is also valid in
828 -- default mode where we recurse up to the first compilation unit and
829 -- should not get to Standard.
831 if Scope (Ent) = Standard_Standard then
833 elsif not Is_Compilation_Unit (Scope (Ent))
834 or else List_Representation_Info_To_JSON
836 List_Name (Scope (Ent));
840 Get_Unqualified_Decoded_Name_String (Chars (Ent));
841 Set_Casing (Unit_Casing);
843 -- The name of operators needs to be properly escaped for JSON
845 for J in 1 .. Name_Len loop
846 C := Name_Buffer (J);
847 if C = '"' and then List_Representation_Info_To_JSON then
854 ---------------------
855 -- List_Object_Info --
856 ---------------------
858 procedure List_Object_Info (Ent : Entity_Id) is
860 -- If size and alignment have not been computed (e.g. if we are in a
861 -- generic unit, or if the back end is not being run), don't try to
864 if not Known_Esize (Ent) or else not Known_Alignment (Ent) then
870 if List_Representation_Info_To_JSON then
873 Write_Str (" ""name"": """);
878 Write_Str (" ""Size"": ");
879 Write_Val (Esize (Ent));
882 Write_Str (" ""Alignment"": ");
883 Write_Val (Alignment (Ent));
885 List_Linker_Section (Ent);
893 Write_Str ("'Size use ");
894 Write_Val (Esize (Ent));
899 Write_Str ("'Alignment use ");
900 Write_Val (Alignment (Ent));
903 List_Linker_Section (Ent);
906 -- The type is relevant for an object
908 if List_Representation_Info = 4 and then Is_Itype (Etype (Ent)) then
909 Relevant_Entities.Set (Etype (Ent), True);
911 end List_Object_Info;
913 ----------------------
914 -- List_Record_Info --
915 ----------------------
917 procedure List_Record_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean) is
918 procedure Compute_Max_Length
920 Starting_Position : Uint := Uint_0;
921 Starting_First_Bit : Uint := Uint_0;
922 Prefix_Length : Natural := 0);
923 -- Internal recursive procedure to compute the max length
925 procedure List_Component_Layout
927 Starting_Position : Uint := Uint_0;
928 Starting_First_Bit : Uint := Uint_0;
929 Prefix : String := "";
930 Indent : Natural := 0);
931 -- Procedure to display the layout of a single component
933 procedure List_Record_Layout
935 Starting_Position : Uint := Uint_0;
936 Starting_First_Bit : Uint := Uint_0;
937 Prefix : String := "");
938 -- Internal recursive procedure to display the layout
940 procedure List_Structural_Record_Layout
943 Ext_Level : Integer := 0;
944 Variant : Node_Id := Empty;
945 Indent : Natural := 0);
946 -- Internal recursive procedure to display the structural layout.
947 -- If Ext_Ent is not equal to Ent, it is an extension of Ent and
948 -- Ext_Level is the number of successive extensions between them,
949 -- with the convention that this number is positive when we are
950 -- called from the fixed part of Ext_Ent and negative when we are
951 -- called from the variant part of Ext_Ent, if any; this is needed
952 -- because the fixed and variant parts of a parent of an extension
953 -- cannot be listed contiguously from this extension's viewpoint.
954 -- If Variant is present, it's for a variant in the variant part
955 -- instead of the common part of Ent. Indent is the indentation.
957 Incomplete_Layout : exception;
958 -- Exception raised if the layout is incomplete in -gnatc mode
960 Not_In_Extended_Main : exception;
961 -- Exception raised when an ancestor is not declared in the main unit
963 Max_Name_Length : Natural := 0;
964 Max_Spos_Length : Natural := 0;
966 ------------------------
967 -- Compute_Max_Length --
968 ------------------------
970 procedure Compute_Max_Length
972 Starting_Position : Uint := Uint_0;
973 Starting_First_Bit : Uint := Uint_0;
974 Prefix_Length : Natural := 0)
979 Comp := First_Component_Or_Discriminant (Ent);
980 while Present (Comp) loop
982 -- Skip a completely hidden discriminant or a discriminant in an
983 -- unchecked union (since it is not there).
985 if Ekind (Comp) = E_Discriminant
986 and then (Is_Completely_Hidden (Comp)
987 or else Is_Unchecked_Union (Ent))
992 -- Skip _Parent component in extension (to avoid overlap)
994 if Chars (Comp) = Name_uParent then
1001 Ctyp : constant Entity_Id := Underlying_Type (Etype (Comp));
1002 Bofs : constant Uint := Component_Bit_Offset (Comp);
1008 Name_Length : Natural;
1011 Get_Decoded_Name_String (Chars (Comp));
1012 Name_Length := Prefix_Length + Name_Len;
1014 if Compile_Time_Known_Rep (Bofs) then
1016 Fbit := Bofs mod SSU;
1018 -- Complete annotation in case not done
1020 if not Known_Normalized_First_Bit (Comp) then
1021 Set_Normalized_Position (Comp, Npos);
1022 Set_Normalized_First_Bit (Comp, Fbit);
1025 Spos := Starting_Position + Npos;
1026 Sbit := Starting_First_Bit + Fbit;
1033 -- If extended information is requested, recurse fully into
1034 -- record components, i.e. skip the outer level.
1036 if List_Representation_Info_Extended
1037 and then Is_Record_Type (Ctyp)
1039 Compute_Max_Length (Ctyp, Spos, Sbit, Name_Length + 1);
1043 UI_Image (Spos, Format => Decimal);
1045 -- If the record is not packed, then we know that all fields
1046 -- whose position is not specified have starting normalized
1047 -- bit position of zero.
1049 if not Known_Normalized_First_Bit (Comp)
1050 and then not Is_Packed (Ent)
1052 Set_Normalized_First_Bit (Comp, Uint_0);
1055 UI_Image_Length := 2; -- For "??" marker
1058 Max_Name_Length := Natural'Max (Max_Name_Length, Name_Length);
1060 Natural'Max (Max_Spos_Length, UI_Image_Length);
1064 Next_Component_Or_Discriminant (Comp);
1066 end Compute_Max_Length;
1068 ---------------------------
1069 -- List_Component_Layout --
1070 ---------------------------
1072 procedure List_Component_Layout
1074 Starting_Position : Uint := Uint_0;
1075 Starting_First_Bit : Uint := Uint_0;
1076 Prefix : String := "";
1077 Indent : Natural := 0)
1079 Esiz : constant Uint := Esize (Ent);
1080 Npos : constant Uint := Normalized_Position (Ent);
1081 Fbit : constant Uint := Normalized_First_Bit (Ent);
1083 Sbit : Uint := No_Uint;
1087 if List_Representation_Info_To_JSON then
1091 Write_Str (" ""name"": """);
1093 Write_Str (Name_Buffer (1 .. Name_Len));
1095 if Ekind (Ent) = E_Discriminant then
1097 Write_Str (" ""discriminant"": ");
1098 UI_Write (Discriminant_Number (Ent), Decimal);
1102 Write_Str (" ""Position"": ");
1106 Write_Str (Name_Buffer (1 .. Name_Len));
1107 Spaces (Max_Name_Length - Prefix'Length - Name_Len);
1111 if Known_Static_Normalized_Position (Ent) then
1112 Spos := Starting_Position + Npos;
1113 Sbit := Starting_First_Bit + Fbit;
1119 UI_Image (Spos, Format => Decimal);
1120 Spaces (Max_Spos_Length - UI_Image_Length);
1121 Write_Str (UI_Image_Buffer (1 .. UI_Image_Length));
1123 elsif Known_Normalized_Position (Ent)
1124 and then List_Representation_Info >= 3
1126 Spaces (Max_Spos_Length - 2);
1128 if Starting_Position /= Uint_0 then
1129 UI_Write (Starting_Position, Decimal);
1139 if List_Representation_Info_To_JSON then
1142 Write_Str (" ""First_Bit"": ");
1144 Write_Str (" range ");
1147 if Known_Static_Normalized_First_Bit (Ent) then
1148 Sbit := Starting_First_Bit + Fbit;
1154 UI_Write (Sbit, Decimal);
1159 if List_Representation_Info_To_JSON then
1162 Write_Str (" ""Size"": ");
1167 if Known_Static_Esize (Ent)
1168 and then Known_Static_Normalized_First_Bit (Ent)
1170 Lbit := Sbit + Esiz - 1;
1172 if List_Representation_Info_To_JSON then
1173 UI_Write (Esiz, Decimal);
1175 if Lbit >= 0 and then Lbit < 10 then
1179 UI_Write (Lbit, Decimal);
1182 elsif List_Representation_Info < 3 or else not Known_Esize (Ent) then
1185 -- List_Representation >= 3 and Known_Esize (Ent)
1188 Write_Val (Esiz, Paren => not List_Representation_Info_To_JSON);
1190 -- Add appropriate first bit offset
1192 if not List_Representation_Info_To_JSON then
1201 Write_Int (UI_To_Int (Sbit) - 1);
1206 if List_Representation_Info_To_JSON then
1214 -- The type is relevant for a component
1216 if List_Representation_Info = 4 and then Is_Itype (Etype (Ent)) then
1217 Relevant_Entities.Set (Etype (Ent), True);
1219 end List_Component_Layout;
1221 ------------------------
1222 -- List_Record_Layout --
1223 ------------------------
1225 procedure List_Record_Layout
1227 Starting_Position : Uint := Uint_0;
1228 Starting_First_Bit : Uint := Uint_0;
1229 Prefix : String := "")
1231 function First_Comp_Or_Discr (Ent : Entity_Id) return Entity_Id;
1232 -- Like First_Component_Or_Discriminant, but reorder the components
1233 -- according to their bit offset if need be.
1235 -------------------------
1236 -- First_Comp_Or_Discr --
1237 -------------------------
1239 function First_Comp_Or_Discr (Ent : Entity_Id) return Entity_Id is
1241 function Is_Placed_Before (C1, C2 : Entity_Id) return Boolean;
1242 -- Return True if components C1 and C2 are in the same component
1243 -- list and component C1 is placed before component C2 in there.
1245 ----------------------
1246 -- Is_Placed_Before --
1247 ----------------------
1249 function Is_Placed_Before (C1, C2 : Entity_Id) return Boolean is
1250 L1 : constant Node_Id := Parent (Parent (C1));
1251 L2 : constant Node_Id := Parent (Parent (C2));
1254 -- Discriminants and top-level components are considered to be
1255 -- in the same list, although this is not syntactically true.
1258 or else (Nkind (Parent (L1)) /= N_Variant
1259 and then Nkind (Parent (L2)) /= N_Variant))
1260 and then Known_Static_Component_Bit_Offset (C1)
1261 and then Known_Static_Component_Bit_Offset (C2)
1263 Component_Bit_Offset (C1) < Component_Bit_Offset (C2);
1264 end Is_Placed_Before;
1269 N_Comp : Natural := 0;
1271 Reorder : Boolean := False;
1273 -- Start of processing for First_Comp_Or_Discr
1276 -- Reordering is needed only for -gnatRh
1278 if not List_Representation_Info_Holes then
1279 return First_Component_Or_Discriminant (Ent);
1282 -- Count the number of components and whether reordering is needed
1284 Comp := First_Component_Or_Discriminant (Ent);
1287 while Present (Comp) loop
1288 N_Comp := N_Comp + 1;
1291 Reorder := Is_Placed_Before (Comp, Prev);
1295 Next_Component_Or_Discriminant (Comp);
1298 -- Reorder the components, if need be, by directly reshuffling the
1299 -- list of entities between First_Entity and Last_Entity, which is
1300 -- safe because we are invoked after compilation is finished.
1304 Comps : array (Natural range 0 .. N_Comp) of Entity_Id;
1305 -- Support array for the heapsort
1307 function Lt (Op1, Op2 : Natural) return Boolean is
1308 (Is_Placed_Before (Comps (Op1), Comps (Op2)));
1309 -- Compare function for the heapsort
1311 procedure Move (From : Natural; To : Natural);
1312 pragma Inline (Move);
1313 -- Move procedure for the heapsort
1319 procedure Move (From : Natural; To : Natural) is
1321 Comps (To) := Comps (From);
1324 package HS is new GNAT.Heap_Sort_G (Lt => Lt, Move => Move);
1325 -- The heapsort for record components
1328 -- Pack the components into the array
1331 Comp := First_Component_Or_Discriminant (Ent);
1333 while Present (Comp) loop
1334 N_Comp := N_Comp + 1;
1335 Comps (N_Comp) := Comp;
1337 Next_Component_Or_Discriminant (Comp);
1344 -- Unpack the component into the list of entities
1346 Set_First_Entity (Ent, Comps (1));
1347 Set_Prev_Entity (Comps (1), Empty);
1348 for J in 1 .. N_Comp - 1 loop
1349 Set_Next_Entity (Comps (J), Comps (J + 1));
1350 Set_Prev_Entity (Comps (J + 1), Comps (J));
1352 Set_Next_Entity (Comps (N_Comp), Empty);
1353 Set_Last_Entity (Ent, Comps (N_Comp));
1357 return First_Component_Or_Discriminant (Ent);
1358 end First_Comp_Or_Discr;
1362 Bit_Offset : Uint := Uint_0;
1364 First : Boolean := True;
1366 -- Start of processing for List_Record_Layout
1369 Comp := First_Comp_Or_Discr (Ent);
1370 while Present (Comp) loop
1372 -- Skip a completely hidden discriminant or a discriminant in an
1373 -- unchecked union (since it is not there).
1375 if Ekind (Comp) = E_Discriminant
1376 and then (Is_Completely_Hidden (Comp)
1377 or else Is_Unchecked_Union (Ent))
1381 -- Skip _Parent component in extension (to avoid overlap)
1383 elsif Chars (Comp) = Name_uParent then
1390 C : constant Entity_Id :=
1391 (if Known_Normalized_Position (Comp)
1393 else Original_Record_Component (Comp));
1394 -- The Parent_Subtype in an extension is not back-annotated
1395 -- but its layout is the same as that of the parent type.
1397 Ctyp : constant Entity_Id := Underlying_Type (Etype (C));
1400 Get_Decoded_Name_String (Chars (C));
1401 Set_Casing (Unit_Casing);
1403 -- If extended information is requested, recurse fully into
1404 -- record components, i.e. skip the outer level.
1406 if List_Representation_Info_Extended
1407 and then Is_Record_Type (Ctyp)
1408 and then Known_Static_Normalized_Position (C)
1409 and then Known_Static_Normalized_First_Bit (C)
1412 Npos : constant Uint := Normalized_Position (C);
1413 Fbit : constant Uint := Normalized_First_Bit (C);
1414 Pref : constant String :=
1415 Prefix & Name_Buffer (1 .. Name_Len) & ".";
1421 Spos := Starting_Position + Npos;
1422 Sbit := Starting_First_Bit + Fbit;
1429 List_Record_Layout (Ctyp, Spos, Sbit, Pref);
1433 if List_Representation_Info_To_JSON then
1442 -- If information about holes is requested, update the
1443 -- current bit offset and report any (static) gap.
1445 if List_Representation_Info_Holes
1446 and then Known_Static_Component_Bit_Offset (C)
1449 Gap : constant Uint :=
1450 Component_Bit_Offset (C) - Bit_Offset;
1452 if Gap > Uint_0 then
1454 UI_Write (Gap, Decimal);
1455 Write_Line (" bits unused --");
1458 if Known_Static_Esize (C) then
1460 Component_Bit_Offset (C) + Esize (C);
1465 List_Component_Layout
1466 (C, Starting_Position, Starting_First_Bit, Prefix);
1471 Next_Component_Or_Discriminant (Comp);
1473 end List_Record_Layout;
1475 -----------------------------------
1476 -- List_Structural_Record_Layout --
1477 -----------------------------------
1479 procedure List_Structural_Record_Layout
1481 Ext_Ent : Entity_Id;
1482 Ext_Level : Integer := 0;
1483 Variant : Node_Id := Empty;
1484 Indent : Natural := 0)
1486 function Derived_Discriminant (Disc : Entity_Id) return Entity_Id;
1487 -- This function assumes that Ext_Ent is an extension of Ent.
1488 -- Disc is a discriminant of Ent that does not itself constrain a
1489 -- discriminant of the parent type of Ent. Return the discriminant
1490 -- of Ext_Ent that ultimately constrains Disc, if any.
1492 ----------------------------
1493 -- Derived_Discriminant --
1494 ----------------------------
1496 function Derived_Discriminant (Disc : Entity_Id) return Entity_Id is
1497 Corr_Disc : Entity_Id;
1498 Derived_Disc : Entity_Id;
1501 -- Deal with an extension of a type with unknown discriminants
1503 if Has_Unknown_Discriminants (Ext_Ent)
1504 and then Present (Underlying_Record_View (Ext_Ent))
1507 First_Discriminant (Underlying_Record_View (Ext_Ent));
1509 Derived_Disc := First_Discriminant (Ext_Ent);
1512 -- Loop over the discriminants of the extension
1514 while Present (Derived_Disc) loop
1516 -- Check if this discriminant constrains another discriminant.
1517 -- If so, find the ultimately constrained discriminant and
1518 -- compare with the original components in the base type.
1520 if Present (Corresponding_Discriminant (Derived_Disc)) then
1521 Corr_Disc := Corresponding_Discriminant (Derived_Disc);
1523 while Present (Corresponding_Discriminant (Corr_Disc)) loop
1524 Corr_Disc := Corresponding_Discriminant (Corr_Disc);
1527 if Original_Record_Component (Corr_Disc) =
1528 Original_Record_Component (Disc)
1530 return Derived_Disc;
1534 Next_Discriminant (Derived_Disc);
1537 -- Disc is not constrained by a discriminant of Ext_Ent
1540 end Derived_Discriminant;
1542 -- Local declarations
1545 Comp_List : Node_Id;
1546 First : Boolean := True;
1547 Parent_Ent : Entity_Id := Empty;
1550 -- Start of processing for List_Structural_Record_Layout
1553 -- If we are dealing with a variant, just process the components
1555 if Present (Variant) then
1556 Comp_List := Component_List (Variant);
1558 -- Otherwise, we are dealing with the full record and need to get
1559 -- to its definition in order to retrieve its structural layout.
1563 Definition : Node_Id :=
1564 Type_Definition (Declaration_Node (Ent));
1566 Is_Extension : constant Boolean :=
1567 Is_Tagged_Type (Ent)
1568 and then Nkind (Definition) =
1569 N_Derived_Type_Definition;
1572 Listed_Disc : Entity_Id;
1573 Parent_Type : Entity_Id;
1576 -- If this is an extension, first list the layout of the parent
1577 -- and then proceed to the extension part, if any.
1579 if Is_Extension then
1580 Parent_Type := Parent_Subtype (Ent);
1581 if No (Parent_Type) then
1582 raise Incomplete_Layout;
1585 if Is_Private_Type (Parent_Type) then
1586 Parent_Type := Full_View (Parent_Type);
1587 pragma Assert (Present (Parent_Type));
1590 -- Do not list variants if one of them has been selected
1592 if Has_Static_Discriminants (Parent_Type) then
1593 List_Record_Layout (Parent_Type);
1596 Parent_Type := Base_Type (Parent_Type);
1598 if Is_Private_Type (Parent_Type) then
1599 Parent_Type := Full_View (Parent_Type);
1600 pragma Assert (Present (Parent_Type));
1603 if not In_Extended_Main_Source_Unit (Parent_Type) then
1604 raise Not_In_Extended_Main;
1607 Parent_Ent := Parent_Type;
1608 if Ext_Level >= 0 then
1609 List_Structural_Record_Layout
1610 (Parent_Ent, Ext_Ent, Ext_Level + 1);
1616 if Present (Record_Extension_Part (Definition)) then
1617 Definition := Record_Extension_Part (Definition);
1621 -- If the record has discriminants and is not an unchecked
1622 -- union, then display them now. Note that, even if this is
1623 -- a structural layout, we list the visible discriminants.
1625 if Has_Discriminants (Ent)
1626 and then not Is_Unchecked_Union (Ent)
1627 and then Ext_Level >= 0
1629 Disc := First_Discriminant (Ent);
1630 while Present (Disc) loop
1632 -- If this is a record extension and the discriminant is
1633 -- the renaming of another discriminant, skip it.
1636 and then Present (Corresponding_Discriminant (Disc))
1641 -- If this is the parent type of an extension, retrieve
1642 -- the derived discriminant from the extension, if any.
1644 if Ent /= Ext_Ent then
1645 Listed_Disc := Derived_Discriminant (Disc);
1647 if No (Listed_Disc) then
1650 elsif not Known_Normalized_Position (Listed_Disc) then
1652 Original_Record_Component (Listed_Disc);
1656 Listed_Disc := Disc;
1659 Get_Decoded_Name_String (Chars (Listed_Disc));
1660 Set_Casing (Unit_Casing);
1669 List_Component_Layout (Listed_Disc, Indent => Indent);
1672 Next_Discriminant (Disc);
1676 Comp_List := Component_List (Definition);
1680 -- Bail out for the null record
1682 if No (Comp_List) then
1686 -- Now deal with the regular components, if any
1688 if Present (Component_Items (Comp_List))
1689 and then (Present (Variant) or else Ext_Level >= 0)
1691 Comp := First_Non_Pragma (Component_Items (Comp_List));
1692 while Present (Comp) loop
1694 -- Skip _Parent component in extension (to avoid overlap)
1696 if Chars (Defining_Identifier (Comp)) = Name_uParent then
1700 Get_Decoded_Name_String (Chars (Defining_Identifier (Comp)));
1701 Set_Casing (Unit_Casing);
1710 List_Component_Layout
1711 (Defining_Identifier (Comp), Indent => Indent);
1714 Next_Non_Pragma (Comp);
1718 -- Stop there if we are called from the fixed part of Ext_Ent,
1719 -- we'll do the variant part when called from its variant part.
1721 if Ext_Level > 0 then
1725 -- List the layout of the variant part of the parent, if any
1727 if Present (Parent_Ent) then
1728 List_Structural_Record_Layout
1729 (Parent_Ent, Ext_Ent, Ext_Level - 1);
1732 -- We are done if there is no variant part
1734 if No (Variant_Part (Comp_List)) then
1743 for J in Ext_Level .. -1 loop
1744 Write_Str ("parent_");
1746 Write_Str ("variant"" : [");
1748 -- Otherwise we recurse on each variant
1750 Var := First_Non_Pragma (Variants (Variant_Part (Comp_List)));
1752 while Present (Var) loop
1763 Write_Str (" ""present"": ");
1764 Write_Val (Present_Expr (Var));
1767 Write_Str (" ""record"": [");
1769 List_Structural_Record_Layout
1770 (Ent, Ext_Ent, Ext_Level, Var, Indent + 4);
1777 Next_Non_Pragma (Var);
1779 end List_Structural_Record_Layout;
1781 -- Use the original record type giving the layout of components
1782 -- to avoid repeated reordering when -gnatRh is specified.
1784 Rec : constant Entity_Id :=
1785 (if Ekind (Ent) = E_Record_Subtype
1786 and then Present (Cloned_Subtype (Ent))
1787 then (if Is_Private_Type (Cloned_Subtype (Ent))
1788 then Full_View (Cloned_Subtype (Ent))
1789 else Cloned_Subtype (Ent))
1792 -- Start of processing for List_Record_Info
1797 if List_Representation_Info_To_JSON then
1801 List_Common_Type_Info (Ent);
1803 -- First find out max line length and max starting position
1804 -- length, for the purpose of lining things up nicely.
1806 Compute_Max_Length (Rec);
1808 -- Then do actual output based on those values
1810 if List_Representation_Info_To_JSON then
1812 Write_Str (" ""record"": [");
1814 -- ??? We can output structural layout only for base types fully
1815 -- declared in the extended main source unit for the time being,
1816 -- because otherwise declarations might not be processed at all.
1818 if Is_Base_Type (Rec) then
1820 List_Structural_Record_Layout (Rec, Rec);
1823 when Incomplete_Layout
1824 | Not_In_Extended_Main
1826 List_Record_Layout (Rec);
1829 raise Program_Error;
1832 List_Record_Layout (Rec);
1840 Write_Line (" use record");
1842 List_Record_Layout (Rec);
1844 Write_Line ("end record;");
1847 List_Scalar_Storage_Order (Ent, Bytes_Big_Endian);
1849 List_Linker_Section (Ent);
1851 if List_Representation_Info_To_JSON then
1856 -- The type is relevant for a record subtype
1858 if List_Representation_Info = 4
1859 and then not Is_Base_Type (Ent)
1860 and then Is_Itype (Etype (Ent))
1862 Relevant_Entities.Set (Etype (Ent), True);
1864 end List_Record_Info;
1870 procedure List_Rep_Info (Bytes_Big_Endian : Boolean) is
1874 if List_Representation_Info /= 0
1875 or else List_Representation_Info_Mechanisms
1877 -- For the normal case, we output a single JSON stream
1879 if not List_Representation_Info_To_File
1880 and then List_Representation_Info_To_JSON
1883 Need_Separator := False;
1886 for U in Main_Unit .. Last_Unit loop
1887 if In_Extended_Main_Source_Unit (Cunit_Entity (U)) then
1888 Unit_Casing := Identifier_Casing (Source_Index (U));
1890 if List_Representation_Info = 4 then
1891 Relevant_Entities.Reset;
1894 -- Normal case, list to standard output
1896 if not List_Representation_Info_To_File then
1897 if not List_Representation_Info_To_JSON then
1899 Write_Str ("Representation information for unit ");
1900 Write_Unit_Name (Unit_Name (U));
1904 for J in 1 .. Col - 1 loop
1909 Need_Separator := True;
1912 List_Entities (Cunit_Entity (U), Bytes_Big_Endian);
1914 -- List representation information to file
1918 (Get_Name_String (File_Name (Source_Index (U))));
1919 Set_Special_Output (Write_Info_Line'Access);
1920 if List_Representation_Info_To_JSON then
1923 Need_Separator := False;
1924 List_Entities (Cunit_Entity (U), Bytes_Big_Endian);
1925 if List_Representation_Info_To_JSON then
1928 Cancel_Special_Output;
1934 if not List_Representation_Info_To_File
1935 and then List_Representation_Info_To_JSON
1942 -------------------------------
1943 -- List_Scalar_Storage_Order --
1944 -------------------------------
1946 procedure List_Scalar_Storage_Order
1948 Bytes_Big_Endian : Boolean)
1950 procedure List_Attr (Attr_Name : String; Is_Reversed : Boolean);
1951 -- Show attribute definition clause for Attr_Name (an endianness
1952 -- attribute), depending on whether or not the endianness is reversed
1953 -- compared to native endianness.
1959 procedure List_Attr (Attr_Name : String; Is_Reversed : Boolean) is
1961 if List_Representation_Info_To_JSON then
1964 Write_Str (Attr_Name);
1965 Write_Str (""": ""System.");
1970 Write_Str (Attr_Name);
1971 Write_Str (" use System.");
1974 if Bytes_Big_Endian xor Is_Reversed then
1980 Write_Str ("_Order_First");
1981 if List_Representation_Info_To_JSON then
1988 List_SSO : constant Boolean :=
1989 Has_Rep_Item (Ent, Name_Scalar_Storage_Order)
1990 or else SSO_Set_Low_By_Default (Ent)
1991 or else SSO_Set_High_By_Default (Ent);
1992 -- Scalar_Storage_Order is displayed if specified explicitly or set by
1993 -- Default_Scalar_Storage_Order.
1995 -- Start of processing for List_Scalar_Storage_Order
1998 -- For record types, list Bit_Order if not default, or if SSO is shown
2000 -- Also, when -gnatR4 is in effect always list bit order and scalar
2001 -- storage order explicitly, so that you don't need to know the native
2002 -- endianness of the target for which the output was produced in order
2005 if Is_Record_Type (Ent)
2007 or else Reverse_Bit_Order (Ent)
2008 or else List_Representation_Info = 4)
2010 List_Attr ("Bit_Order", Reverse_Bit_Order (Ent));
2013 -- List SSO if required. If not, then storage is supposed to be in
2016 if List_SSO or else List_Representation_Info = 4 then
2017 List_Attr ("Scalar_Storage_Order", Reverse_Storage_Order (Ent));
2019 pragma Assert (not Reverse_Storage_Order (Ent));
2022 end List_Scalar_Storage_Order;
2024 --------------------------
2025 -- List_Subprogram_Info --
2026 --------------------------
2028 procedure List_Subprogram_Info (Ent : Entity_Id) is
2029 First : Boolean := True;
2036 if List_Representation_Info_To_JSON then
2038 Write_Str (" ""name"": """);
2041 List_Location (Ent);
2043 Write_Str (" ""Convention"": """);
2047 Write_Str ("function ");
2050 Write_Str ("operator ");
2053 Write_Str ("procedure ");
2055 when E_Subprogram_Type =>
2056 Write_Str ("type ");
2061 Write_Str ("entry ");
2064 raise Program_Error;
2068 Write_Str (" declared at ");
2069 Write_Location (Sloc (Ent));
2072 Write_Str ("convention : ");
2075 case Convention (Ent) is
2076 when Convention_Ada =>
2079 when Convention_Ada_Pass_By_Copy =>
2080 Write_Str ("Ada_Pass_By_Copy");
2082 when Convention_Ada_Pass_By_Reference =>
2083 Write_Str ("Ada_Pass_By_Reference");
2085 when Convention_Intrinsic =>
2086 Write_Str ("Intrinsic");
2088 when Convention_Entry =>
2089 Write_Str ("Entry");
2091 when Convention_Protected =>
2092 Write_Str ("Protected");
2094 when Convention_Assembler =>
2095 Write_Str ("Assembler");
2097 when Convention_C =>
2100 when Convention_C_Variadic =>
2103 Convention_Id'Pos (Convention (Ent)) -
2104 Convention_Id'Pos (Convention_C_Variadic_0);
2106 Write_Str ("C_Variadic_");
2111 pragma Assert (N < 10);
2112 Write_Char (Character'Val (Character'Pos ('0') + N));
2115 when Convention_COBOL =>
2116 Write_Str ("COBOL");
2118 when Convention_CPP =>
2121 when Convention_Fortran =>
2122 Write_Str ("Fortran");
2124 when Convention_Stdcall =>
2125 Write_Str ("Stdcall");
2127 when Convention_Stubbed =>
2128 Write_Str ("Stubbed");
2131 if List_Representation_Info_To_JSON then
2133 Write_Str (" ""formal"": [");
2138 -- Find max length of formal name
2141 Form := First_Formal (Ent);
2142 while Present (Form) loop
2143 Get_Unqualified_Decoded_Name_String (Chars (Form));
2145 if Name_Len > Plen then
2152 -- Output formals and mechanisms
2154 Form := First_Formal (Ent);
2155 while Present (Form) loop
2156 Get_Unqualified_Decoded_Name_String (Chars (Form));
2157 Set_Casing (Unit_Casing);
2159 if List_Representation_Info_To_JSON then
2168 Write_Str (" ""name"": """);
2169 Write_Str (Name_Buffer (1 .. Name_Len));
2172 Write_Str (" ""mechanism"": """);
2173 Write_Mechanism (Mechanism (Form));
2177 while Name_Len <= Plen loop
2178 Name_Len := Name_Len + 1;
2179 Name_Buffer (Name_Len) := ' ';
2183 Write_Str (Name_Buffer (1 .. Plen + 1));
2184 Write_Str (": passed by ");
2186 Write_Mechanism (Mechanism (Form));
2193 if List_Representation_Info_To_JSON then
2198 if Ekind (Ent) = E_Function then
2199 if List_Representation_Info_To_JSON then
2201 Write_Str (" ""mechanism"": """);
2202 Write_Mechanism (Mechanism (Ent));
2205 Write_Str ("returns by ");
2206 Write_Mechanism (Mechanism (Ent));
2211 if not Is_Entry (Ent) then
2212 List_Linker_Section (Ent);
2215 if List_Representation_Info_To_JSON then
2219 end List_Subprogram_Info;
2221 --------------------
2222 -- List_Type_Info --
2223 --------------------
2225 procedure List_Type_Info (Ent : Entity_Id) is
2229 if List_Representation_Info_To_JSON then
2233 List_Common_Type_Info (Ent);
2235 -- Special stuff for fixed-point
2237 if Is_Fixed_Point_Type (Ent) then
2239 -- Write small (always a static constant)
2241 if List_Representation_Info_To_JSON then
2243 Write_Str (" ""Small"": ");
2244 UR_Write_To_JSON (Small_Value (Ent));
2248 Write_Str ("'Small use ");
2249 UR_Write (Small_Value (Ent));
2253 -- Write range if static
2256 R : constant Node_Id := Scalar_Range (Ent);
2259 if Nkind (Low_Bound (R)) = N_Real_Literal
2261 Nkind (High_Bound (R)) = N_Real_Literal
2263 if List_Representation_Info_To_JSON then
2265 Write_Str (" ""Range"": [ ");
2266 UR_Write_To_JSON (Realval (Low_Bound (R)));
2268 UR_Write_To_JSON (Realval (High_Bound (R)));
2273 Write_Str ("'Range use ");
2274 UR_Write (Realval (Low_Bound (R)));
2276 UR_Write (Realval (High_Bound (R)));
2283 List_Linker_Section (Ent);
2285 if List_Representation_Info_To_JSON then
2291 ----------------------------
2292 -- Compile_Time_Known_Rep --
2293 ----------------------------
2295 function Compile_Time_Known_Rep (Val : Node_Ref_Or_Val) return Boolean is
2297 return Present (Val) and then Val >= 0;
2298 end Compile_Time_Known_Rep;
2304 function Rep_Value (Val : Node_Ref_Or_Val; D : Discrim_List) return Uint is
2306 function B (Val : Boolean) return Ubool;
2307 -- Returns Uint_0 for False, Uint_1 for True
2309 function T (Val : Node_Ref_Or_Val) return Boolean;
2310 -- Returns True for 0, False for any non-zero (i.e. True)
2312 function V (Val : Node_Ref_Or_Val) return Uint;
2313 -- Internal recursive routine to evaluate tree
2315 function W (Val : Uint) return Word;
2316 -- Convert Val to Word, assuming Val is always in the Int range. This
2317 -- is a helper function for the evaluation of bitwise expressions like
2318 -- Bit_And_Expr, for which there is no direct support in uintp. Uint
2319 -- values out of the Int range are expected to be seen in such
2320 -- expressions only with overflowing byte sizes around, introducing
2321 -- inherent unreliabilities in computations anyway.
2327 function B (Val : Boolean) return Ubool is
2340 function T (Val : Node_Ref_Or_Val) return Boolean is
2353 function V (Val : Node_Ref_Or_Val) return Uint is
2362 Node : Exp_Node renames Rep_Table.Table (-UI_To_Int (Val));
2367 if T (Node.Op1) then
2368 return V (Node.Op2);
2370 return V (Node.Op3);
2374 return V (Node.Op1) + V (Node.Op2);
2377 return V (Node.Op1) - V (Node.Op2);
2380 return V (Node.Op1) * V (Node.Op2);
2382 when Trunc_Div_Expr =>
2383 return V (Node.Op1) / V (Node.Op2);
2385 when Ceil_Div_Expr =>
2388 (V (Node.Op1) / UR_From_Uint (V (Node.Op2)));
2390 when Floor_Div_Expr =>
2393 (V (Node.Op1) / UR_From_Uint (V (Node.Op2)));
2395 when Trunc_Mod_Expr =>
2396 return V (Node.Op1) rem V (Node.Op2);
2398 when Floor_Mod_Expr =>
2399 return V (Node.Op1) mod V (Node.Op2);
2401 when Ceil_Mod_Expr =>
2404 Q := UR_Ceiling (L / UR_From_Uint (R));
2407 when Exact_Div_Expr =>
2408 return V (Node.Op1) / V (Node.Op2);
2411 return -V (Node.Op1);
2414 return UI_Min (V (Node.Op1), V (Node.Op2));
2417 return UI_Max (V (Node.Op1), V (Node.Op2));
2420 return UI_Abs (V (Node.Op1));
2422 when Truth_And_Expr =>
2423 return B (T (Node.Op1) and then T (Node.Op2));
2425 when Truth_Or_Expr =>
2426 return B (T (Node.Op1) or else T (Node.Op2));
2428 when Truth_Xor_Expr =>
2429 return B (T (Node.Op1) xor T (Node.Op2));
2431 when Truth_Not_Expr =>
2432 return B (not T (Node.Op1));
2434 when Bit_And_Expr =>
2437 return UI_From_Int (Int (W (L) and W (R)));
2440 return B (V (Node.Op1) < V (Node.Op2));
2443 return B (V (Node.Op1) <= V (Node.Op2));
2446 return B (V (Node.Op1) > V (Node.Op2));
2449 return B (V (Node.Op1) >= V (Node.Op2));
2452 return B (V (Node.Op1) = V (Node.Op2));
2455 return B (V (Node.Op1) /= V (Node.Op2));
2459 Sub : constant Int := UI_To_Int (Node.Op1);
2461 pragma Assert (Sub in D'Range);
2476 -- We use an unchecked conversion to map Int values to their Word
2477 -- bitwise equivalent, which we could not achieve with a normal type
2478 -- conversion for negative Ints. We want bitwise equivalents because W
2479 -- is used as a helper for bit operators like Bit_And_Expr, and can be
2480 -- called for negative Ints in the context of aligning expressions like
2481 -- X+Align & -Align.
2483 function W (Val : Uint) return Word is
2484 function To_Word is new Ada.Unchecked_Conversion (Int, Word);
2486 return To_Word (UI_To_Int (Val));
2489 -- Start of processing for Rep_Value
2504 procedure Spaces (N : Natural) is
2506 for J in 1 .. N loop
2511 ---------------------
2512 -- Write_Info_Line --
2513 ---------------------
2515 procedure Write_Info_Line (S : String) is
2517 Write_Repinfo_Line (S (S'First .. S'Last - 1));
2518 end Write_Info_Line;
2520 ---------------------
2521 -- Write_Mechanism --
2522 ---------------------
2524 procedure Write_Mechanism (M : Mechanism_Type) is
2528 Write_Str ("default");
2534 Write_Str ("reference");
2537 raise Program_Error;
2539 end Write_Mechanism;
2541 ---------------------
2542 -- Write_Separator --
2543 ---------------------
2545 procedure Write_Separator is
2547 if Need_Separator then
2548 if List_Representation_Info_To_JSON then
2554 Need_Separator := True;
2556 end Write_Separator;
2558 -----------------------
2559 -- Write_Unknown_Val --
2560 -----------------------
2562 procedure Write_Unknown_Val is
2564 if List_Representation_Info_To_JSON then
2565 Write_Str ("""??""");
2569 end Write_Unknown_Val;
2575 procedure Write_Val (Val : Node_Ref_Or_Val; Paren : Boolean := False) is
2577 if Compile_Time_Known_Rep (Val) then
2578 UI_Write (Val, Decimal);
2579 elsif List_Representation_Info < 3 or else No (Val) then
2586 List_GCC_Expression (Val);