1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1999-2018, 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. --
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. --
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/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
33 with Atree
; use Atree
;
34 with Casing
; use Casing
;
35 with Debug
; use Debug
;
36 with Einfo
; use Einfo
;
38 with Namet
; use Namet
;
39 with Nlists
; use Nlists
;
41 with Output
; use Output
;
42 with Sem_Aux
; use Sem_Aux
;
43 with Sinfo
; use Sinfo
;
44 with Sinput
; use Sinput
;
45 with Snames
; use Snames
;
46 with Stand
; use Stand
;
47 with Stringt
; use Stringt
;
49 with Uname
; use Uname
;
50 with Urealp
; use Urealp
;
52 with Ada
.Unchecked_Conversion
;
54 package body Repinfo
is
57 -- Value for Storage_Unit, we do not want to get this from TTypes, since
58 -- this introduces problematic dependencies in ASIS, and in any case this
59 -- value is assumed to be 8 for the implementation of the DDA.
61 ---------------------------------------
62 -- Representation of GCC Expressions --
63 ---------------------------------------
65 -- A table internal to this unit is used to hold the values of back
66 -- annotated expressions. This table is written out by -gnatt and read
67 -- back in for ASIS processing.
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.
72 type Exp_Node
is record
74 Op1
: Node_Ref_Or_Val
;
75 Op2
: Node_Ref_Or_Val
;
76 Op3
: Node_Ref_Or_Val
;
79 -- The following representation clause ensures that the above record
80 -- has no holes. We do this so that when instances of this record are
81 -- written by Tree_Gen, we do not write uninitialized values to the file.
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;
90 for Exp_Node
'Size use 16 * 8;
91 -- This ensures that we did not leave out any fields
93 package Rep_Table
is new Table
.Table
(
94 Table_Component_Type
=> Exp_Node
,
95 Table_Index_Type
=> Nat
,
97 Table_Initial
=> Alloc
.Rep_Table_Initial
,
98 Table_Increment
=> Alloc
.Rep_Table_Increment
,
99 Table_Name
=> "BE_Rep_Table");
101 --------------------------------------------------------------
102 -- Representation of Front-End Dynamic Size/Offset Entities --
103 --------------------------------------------------------------
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");
113 Unit_Casing
: Casing_Type
;
114 -- Identifier casing for current unit. This is set by List_Rep_Info for
115 -- each unit, before calling subprograms which may read it.
117 Need_Blank_Line
: Boolean;
118 -- Set True if a blank line is needed before outputting any information for
119 -- the current entity. Set True when a new entity is processed, and false
120 -- when the blank line is output.
122 -----------------------
123 -- Local Subprograms --
124 -----------------------
126 function Back_End_Layout
return Boolean;
127 -- Test for layout mode, True = back end, False = front end. This function
128 -- is used rather than checking the configuration parameter because we do
129 -- not want Repinfo to depend on Targparm (for ASIS)
131 procedure Blank_Line
;
132 -- Called before outputting anything for an entity. Ensures that
133 -- a blank line precedes the output for a particular entity.
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_Linker_Section
(Ent
: Entity_Id
);
153 -- List linker section for Ent (caller has checked that Ent is an entity
154 -- for which the Linker_Section_Pragma field is defined).
156 procedure List_Location
(Ent
: Entity_Id
);
157 -- List location information for Ent
159 procedure List_Mechanisms
(Ent
: Entity_Id
);
160 -- List mechanism information for parameters of Ent, which is subprogram,
161 -- subprogram type, or an entry or entry family.
163 procedure List_Object_Info
(Ent
: Entity_Id
);
164 -- List representation info for object Ent
166 procedure List_Record_Info
(Ent
: Entity_Id
; Bytes_Big_Endian
: Boolean);
167 -- List representation info for record type Ent
169 procedure List_Scalar_Storage_Order
171 Bytes_Big_Endian
: Boolean);
172 -- List scalar storage order information for record or array type Ent.
173 -- Also includes bit order information for record types, if necessary.
175 procedure List_Type_Info
(Ent
: Entity_Id
);
176 -- List type info for type Ent
178 function Rep_Not_Constant
(Val
: Node_Ref_Or_Val
) return Boolean;
179 -- Returns True if Val represents a variable value, and False if it
180 -- represents a value that is fixed at compile time.
182 procedure Spaces
(N
: Natural);
183 -- Output given number of spaces
185 procedure Write_Info_Line
(S
: String);
186 -- Routine to write a line to Repinfo output file. This routine is passed
187 -- as a special output procedure to Output.Set_Special_Output. Note that
188 -- Write_Info_Line is called with an EOL character at the end of each line,
189 -- as per the Output spec, but the internal call to the appropriate routine
190 -- in Osint requires that the end of line sequence be stripped off.
192 procedure Write_Mechanism
(M
: Mechanism_Type
);
193 -- Writes symbolic string for mechanism represented by M
195 procedure Write_Unknown_Val
;
196 -- Writes symbolic string for an unknown or non-representable value
198 procedure Write_Val
(Val
: Node_Ref_Or_Val
; Paren
: Boolean := False);
199 -- Given a representation value, write it out. No_Uint values or values
200 -- dependent on discriminants are written as two question marks. If the
201 -- flag Paren is set, then the output is surrounded in parentheses if it is
202 -- other than a simple value.
204 ---------------------
205 -- Back_End_Layout --
206 ---------------------
208 function Back_End_Layout
return Boolean is
210 -- We have back-end layout if the back end has made any entries in the
211 -- table of GCC expressions, otherwise we have front-end layout.
213 return Rep_Table
.Last
> 0;
220 procedure Blank_Line
is
222 if Need_Blank_Line
then
224 Need_Blank_Line
:= False;
228 ------------------------
229 -- Create_Discrim_Ref --
230 ------------------------
232 function Create_Discrim_Ref
(Discr
: Entity_Id
) return Node_Ref
is
235 (Expr
=> Discrim_Val
,
236 Op1
=> Discriminant_Number
(Discr
));
237 end Create_Discrim_Ref
;
239 ---------------------------
240 -- Create_Dynamic_SO_Ref --
241 ---------------------------
243 function Create_Dynamic_SO_Ref
(E
: Entity_Id
) return Dynamic_SO_Ref
is
245 Dynamic_SO_Entity_Table
.Append
(E
);
246 return UI_From_Int
(-Dynamic_SO_Entity_Table
.Last
);
247 end Create_Dynamic_SO_Ref
;
255 Op1
: Node_Ref_Or_Val
;
256 Op2
: Node_Ref_Or_Val
:= No_Uint
;
257 Op3
: Node_Ref_Or_Val
:= No_Uint
) return Node_Ref
265 return UI_From_Int
(-Rep_Table
.Last
);
268 ---------------------------
269 -- Get_Dynamic_SO_Entity --
270 ---------------------------
272 function Get_Dynamic_SO_Entity
(U
: Dynamic_SO_Ref
) return Entity_Id
is
274 return Dynamic_SO_Entity_Table
.Table
(-UI_To_Int
(U
));
275 end Get_Dynamic_SO_Entity
;
277 -----------------------
278 -- Is_Dynamic_SO_Ref --
279 -----------------------
281 function Is_Dynamic_SO_Ref
(U
: SO_Ref
) return Boolean is
284 end Is_Dynamic_SO_Ref
;
286 ----------------------
287 -- Is_Static_SO_Ref --
288 ----------------------
290 function Is_Static_SO_Ref
(U
: SO_Ref
) return Boolean is
293 end Is_Static_SO_Ref
;
299 procedure lgx
(U
: Node_Ref_Or_Val
) is
301 List_GCC_Expression
(U
);
305 ----------------------
306 -- List_Array_Info --
307 ----------------------
309 procedure List_Array_Info
(Ent
: Entity_Id
; Bytes_Big_Endian
: Boolean) is
313 if List_Representation_Info_To_JSON
then
317 List_Type_Info
(Ent
);
319 if List_Representation_Info_To_JSON
then
321 Write_Str
(" ""Component_Size"": ");
322 Write_Val
(Component_Size
(Ent
));
326 Write_Str
("'Component_Size use ");
327 Write_Val
(Component_Size
(Ent
));
331 List_Scalar_Storage_Order
(Ent
, Bytes_Big_Endian
);
333 List_Linker_Section
(Ent
);
335 if List_Representation_Info_To_JSON
then
345 procedure List_Entities
347 Bytes_Big_Endian
: Boolean;
348 In_Subprogram
: Boolean := False)
353 function Find_Declaration
(E
: Entity_Id
) return Node_Id
;
354 -- Utility to retrieve declaration node for entity in the
355 -- case of package bodies and subprograms.
357 ----------------------
358 -- Find_Declaration --
359 ----------------------
361 function Find_Declaration
(E
: Entity_Id
) return Node_Id
is
367 and then Nkind
(Decl
) /= N_Package_Body
368 and then Nkind
(Decl
) /= N_Subprogram_Declaration
369 and then Nkind
(Decl
) /= N_Subprogram_Body
371 Decl
:= Parent
(Decl
);
375 end Find_Declaration
;
377 -- Start of processing for List_Entities
380 -- List entity if we have one, and it is not a renaming declaration.
381 -- For renamings, we don't get proper information, and really it makes
382 -- sense to restrict the output to the renamed entity.
385 and then Nkind
(Declaration_Node
(Ent
)) not in N_Renaming_Declaration
387 -- If entity is a subprogram and we are listing mechanisms,
388 -- then we need to list mechanisms for this entity. We skip this
389 -- if it is a nested subprogram, as the information has already
390 -- been produced when listing the enclosing scope.
392 if List_Representation_Info_Mechanisms
393 and then (Is_Subprogram
(Ent
)
394 or else Ekind
(Ent
) = E_Entry
395 or else Ekind
(Ent
) = E_Entry_Family
)
396 and then not In_Subprogram
398 Need_Blank_Line
:= True;
399 List_Mechanisms
(Ent
);
402 E
:= First_Entity
(Ent
);
403 while Present
(E
) loop
404 Need_Blank_Line
:= True;
406 -- We list entities that come from source (excluding private or
407 -- incomplete types or deferred constants, where we will list the
408 -- info for the full view). If debug flag A is set, then all
409 -- entities are listed
411 if ((Comes_From_Source
(E
)
412 or else (Ekind
(E
) = E_Block
414 Nkind
(Parent
(E
)) = N_Implicit_Label_Declaration
416 Comes_From_Source
(Label_Construct
(Parent
(E
)))))
417 and then not Is_Incomplete_Or_Private_Type
(E
)
418 and then not (Ekind
(E
) = E_Constant
419 and then Present
(Full_View
(E
))))
420 or else Debug_Flag_AA
422 if Is_Subprogram
(E
) then
423 if List_Representation_Info_Mechanisms
then
427 -- Recurse into entities local to subprogram
429 List_Entities
(E
, Bytes_Big_Endian
, True);
431 elsif Ekind
(E
) in Formal_Kind
and then In_Subprogram
then
434 elsif Ekind_In
(E
, E_Entry
,
438 if List_Representation_Info_Mechanisms
then
442 elsif Is_Record_Type
(E
) then
443 if List_Representation_Info
>= 1 then
444 List_Record_Info
(E
, Bytes_Big_Endian
);
447 elsif Is_Array_Type
(E
) then
448 if List_Representation_Info
>= 1 then
449 List_Array_Info
(E
, Bytes_Big_Endian
);
452 elsif Is_Type
(E
) then
453 if List_Representation_Info
>= 2 then
455 if List_Representation_Info_To_JSON
then
459 List_Linker_Section
(E
);
460 if List_Representation_Info_To_JSON
then
466 elsif Ekind_In
(E
, E_Variable
, E_Constant
) then
467 if List_Representation_Info
>= 2 then
468 List_Object_Info
(E
);
471 elsif Ekind
(E
) = E_Loop_Parameter
or else Is_Formal
(E
) then
472 if List_Representation_Info
>= 2 then
473 List_Object_Info
(E
);
477 -- Recurse into nested package, but not if they are package
478 -- renamings (in particular renamings of the enclosing package,
479 -- as for some Java bindings and for generic instances).
481 if Ekind
(E
) = E_Package
then
482 if No
(Renamed_Object
(E
)) then
483 List_Entities
(E
, Bytes_Big_Endian
);
486 -- Recurse into bodies
488 elsif Ekind_In
(E
, E_Protected_Type
,
495 List_Entities
(E
, Bytes_Big_Endian
);
497 -- Recurse into blocks
499 elsif Ekind
(E
) = E_Block
then
500 List_Entities
(E
, Bytes_Big_Endian
);
504 E
:= Next_Entity
(E
);
507 -- For a package body, the entities of the visible subprograms are
508 -- declared in the corresponding spec. Iterate over its entities in
509 -- order to handle properly the subprogram bodies. Skip bodies in
510 -- subunits, which are listed independently.
512 if Ekind
(Ent
) = E_Package_Body
513 and then Present
(Corresponding_Spec
(Find_Declaration
(Ent
)))
515 E
:= First_Entity
(Corresponding_Spec
(Find_Declaration
(Ent
)));
516 while Present
(E
) loop
519 Nkind
(Find_Declaration
(E
)) = N_Subprogram_Declaration
521 Body_E
:= Corresponding_Body
(Find_Declaration
(E
));
525 Nkind
(Parent
(Find_Declaration
(Body_E
))) /= N_Subunit
527 List_Entities
(Body_E
, Bytes_Big_Endian
);
537 -------------------------
538 -- List_GCC_Expression --
539 -------------------------
541 procedure List_GCC_Expression
(U
: Node_Ref_Or_Val
) is
543 procedure Print_Expr
(Val
: Node_Ref_Or_Val
);
544 -- Internal recursive procedure to print expression
550 procedure Print_Expr
(Val
: Node_Ref_Or_Val
) is
553 UI_Write
(Val
, Decimal
);
557 Node
: Exp_Node
renames Rep_Table
.Table
(-UI_To_Int
(Val
));
559 procedure Unop
(S
: String);
560 -- Output text for unary operator with S being operator name
562 procedure Binop
(S
: String);
563 -- Output text for binary operator with S being operator name
569 procedure Unop
(S
: String) is
571 if List_Representation_Info_To_JSON
then
572 Write_Str
("{ ""code"": """);
573 if S
(S
'Last) = ' ' then
574 Write_Str
(S
(S
'First .. S
'Last - 1));
578 Write_Str
(""", ""operands"": [ ");
579 Print_Expr
(Node
.Op1
);
583 Print_Expr
(Node
.Op1
);
591 procedure Binop
(S
: String) is
593 if List_Representation_Info_To_JSON
then
594 Write_Str
("{ ""code"": """);
595 Write_Str
(S
(S
'First + 1 .. S
'Last - 1));
596 Write_Str
(""", ""operands"": [ ");
597 Print_Expr
(Node
.Op1
);
599 Print_Expr
(Node
.Op2
);
603 Print_Expr
(Node
.Op1
);
605 Print_Expr
(Node
.Op2
);
610 -- Start of processing for Print_Expr
615 if List_Representation_Info_To_JSON
then
616 Write_Str
("{ ""code"": ""?<>""");
617 Write_Str
(", ""operands"": [ ");
618 Print_Expr
(Node
.Op1
);
620 Print_Expr
(Node
.Op2
);
622 Print_Expr
(Node
.Op3
);
626 Print_Expr
(Node
.Op1
);
627 Write_Str
(" then ");
628 Print_Expr
(Node
.Op2
);
629 Write_Str
(" else ");
630 Print_Expr
(Node
.Op3
);
643 when Trunc_Div_Expr
=>
646 when Ceil_Div_Expr
=>
649 when Floor_Div_Expr
=>
652 when Trunc_Mod_Expr
=>
655 when Ceil_Mod_Expr
=>
658 when Floor_Mod_Expr
=>
661 when Exact_Div_Expr
=>
676 when Truth_And_Expr
=>
679 when Truth_Or_Expr
=>
682 when Truth_Xor_Expr
=>
685 when Truth_Not_Expr
=>
719 -- Start of processing for List_GCC_Expression
727 end List_GCC_Expression
;
729 -------------------------
730 -- List_Linker_Section --
731 -------------------------
733 procedure List_Linker_Section
(Ent
: Entity_Id
) is
734 function Expr_Value_S
(N
: Node_Id
) return Node_Id
;
735 -- Returns the folded value of the expression. This function is called
736 -- in instances where it has already been determined that the expression
737 -- is static or its value is known at compile time. This version is used
738 -- for string types and returns the corresponding N_String_Literal node.
739 -- NOTE: This is an exact copy of Sem_Eval.Expr_Value_S. Licensing stops
740 -- Repinfo from within Sem_Eval. Once ASIS is removed, and the licenses
741 -- are modified, Repinfo should be able to rely on Sem_Eval.
747 function Expr_Value_S
(N
: Node_Id
) return Node_Id
is
749 if Nkind
(N
) = N_String_Literal
then
752 pragma Assert
(Ekind
(Entity
(N
)) = E_Constant
);
753 return Expr_Value_S
(Constant_Value
(Entity
(N
)));
762 -- Start of processing for List_Linker_Section
765 if Present
(Linker_Section_Pragma
(Ent
)) then
766 Args
:= Pragma_Argument_Associations
(Linker_Section_Pragma
(Ent
));
767 Sect
:= Expr_Value_S
(Get_Pragma_Arg
(Last
(Args
)));
769 if List_Representation_Info_To_JSON
then
771 Write_Str
(" ""Linker_Section"": """);
773 Write_Str
("pragma Linker_Section (");
778 pragma Assert
(Nkind
(Sect
) = N_String_Literal
);
779 String_To_Name_Buffer
(Strval
(Sect
));
780 Write_Str
(Name_Buffer
(1 .. Name_Len
));
782 if not List_Representation_Info_To_JSON
then
786 end List_Linker_Section
;
792 procedure List_Location
(Ent
: Entity_Id
) is
794 pragma Assert
(List_Representation_Info_To_JSON
);
795 Write_Str
(" ""location"": """);
796 Write_Location
(Sloc
(Ent
));
800 ---------------------
801 -- List_Mechanisms --
802 ---------------------
804 procedure List_Mechanisms
(Ent
: Entity_Id
) is
805 First
: Boolean := True;
812 if List_Representation_Info_To_JSON
then
814 Write_Str
(" ""name"": """);
819 Write_Str
(" ""Convention"": """);
823 Write_Str
("function ");
826 Write_Str
("operator ");
829 Write_Str
("procedure ");
831 when E_Subprogram_Type
=>
837 Write_Str
("entry ");
844 Write_Str
(" declared at ");
845 Write_Location
(Sloc
(Ent
));
848 Write_Str
("convention : ");
851 case Convention
(Ent
) is
852 when Convention_Ada
=>
855 when Convention_Ada_Pass_By_Copy
=>
856 Write_Str
("Ada_Pass_By_Copy");
858 when Convention_Ada_Pass_By_Reference
=>
859 Write_Str
("Ada_Pass_By_Reference");
861 when Convention_Intrinsic
=>
862 Write_Str
("Intrinsic");
864 when Convention_Entry
=>
867 when Convention_Protected
=>
868 Write_Str
("Protected");
870 when Convention_Assembler
=>
871 Write_Str
("Assembler");
876 when Convention_COBOL
=>
879 when Convention_CPP
=>
882 when Convention_Fortran
=>
883 Write_Str
("Fortran");
885 when Convention_Stdcall
=>
886 Write_Str
("Stdcall");
888 when Convention_Stubbed
=>
889 Write_Str
("Stubbed");
892 if List_Representation_Info_To_JSON
then
894 Write_Str
(" ""formal"": [");
899 -- Find max length of formal name
902 Form
:= First_Formal
(Ent
);
903 while Present
(Form
) loop
904 Get_Unqualified_Decoded_Name_String
(Chars
(Form
));
906 if Name_Len
> Plen
then
913 -- Output formals and mechanisms
915 Form
:= First_Formal
(Ent
);
916 while Present
(Form
) loop
917 Get_Unqualified_Decoded_Name_String
(Chars
(Form
));
918 Set_Casing
(Unit_Casing
);
920 if List_Representation_Info_To_JSON
then
929 Write_Str
(" ""name"": """);
930 Write_Str
(Name_Buffer
(1 .. Name_Len
));
933 Write_Str
(" ""mechanism"": """);
934 Write_Mechanism
(Mechanism
(Form
));
938 while Name_Len
<= Plen
loop
939 Name_Len
:= Name_Len
+ 1;
940 Name_Buffer
(Name_Len
) := ' ';
944 Write_Str
(Name_Buffer
(1 .. Plen
+ 1));
945 Write_Str
(": passed by ");
947 Write_Mechanism
(Mechanism
(Form
));
954 if List_Representation_Info_To_JSON
then
959 if Etype
(Ent
) /= Standard_Void_Type
then
960 if List_Representation_Info_To_JSON
then
962 Write_Str
(" ""mechanism"": """);
963 Write_Mechanism
(Mechanism
(Ent
));
966 Write_Str
("returns by ");
967 Write_Mechanism
(Mechanism
(Ent
));
972 if not Is_Entry
(Ent
) then
973 List_Linker_Section
(Ent
);
976 if List_Representation_Info_To_JSON
then
986 procedure List_Name
(Ent
: Entity_Id
) is
988 -- List the qualified name recursively, except
989 -- at compilation unit level in default mode.
991 if Is_Compilation_Unit
(Ent
) then
993 elsif not Is_Compilation_Unit
(Scope
(Ent
))
994 or else List_Representation_Info_To_JSON
996 List_Name
(Scope
(Ent
));
1000 Get_Unqualified_Decoded_Name_String
(Chars
(Ent
));
1001 Set_Casing
(Unit_Casing
);
1002 Write_Str
(Name_Buffer
(1 .. Name_Len
));
1005 ---------------------
1006 -- List_Object_Info --
1007 ---------------------
1009 procedure List_Object_Info
(Ent
: Entity_Id
) is
1013 if List_Representation_Info_To_JSON
then
1016 Write_Str
(" ""name"": """);
1019 List_Location
(Ent
);
1021 Write_Str
(" ""Size"": ");
1022 Write_Val
(Esize
(Ent
));
1025 Write_Str
(" ""Alignment"": ");
1026 Write_Val
(Alignment
(Ent
));
1028 List_Linker_Section
(Ent
);
1035 Write_Str
("'Size use ");
1036 Write_Val
(Esize
(Ent
));
1041 Write_Str
("'Alignment use ");
1042 Write_Val
(Alignment
(Ent
));
1045 List_Linker_Section
(Ent
);
1047 end List_Object_Info
;
1049 ----------------------
1050 -- List_Record_Info --
1051 ----------------------
1053 procedure List_Record_Info
(Ent
: Entity_Id
; Bytes_Big_Endian
: Boolean) is
1054 procedure Compute_Max_Length
1056 Starting_Position
: Uint
:= Uint_0
;
1057 Starting_First_Bit
: Uint
:= Uint_0
;
1058 Prefix_Length
: Natural := 0);
1059 -- Internal recursive procedure to compute the max length
1061 procedure List_Component_Layout
1063 Starting_Position
: Uint
:= Uint_0
;
1064 Starting_First_Bit
: Uint
:= Uint_0
;
1065 Prefix
: String := "";
1066 Indent
: Natural := 0);
1067 -- Procedure to display the layout of a single component
1069 procedure List_Record_Layout
1071 Starting_Position
: Uint
:= Uint_0
;
1072 Starting_First_Bit
: Uint
:= Uint_0
;
1073 Prefix
: String := "");
1074 -- Internal recursive procedure to display the layout
1076 procedure List_Structural_Record_Layout
1078 Outer_Ent
: Entity_Id
;
1079 Variant
: Node_Id
:= Empty
;
1080 Indent
: Natural := 0);
1081 -- Internal recursive procedure to display the structural layout
1083 Max_Name_Length
: Natural := 0;
1084 Max_Spos_Length
: Natural := 0;
1086 ------------------------
1087 -- Compute_Max_Length --
1088 ------------------------
1090 procedure Compute_Max_Length
1092 Starting_Position
: Uint
:= Uint_0
;
1093 Starting_First_Bit
: Uint
:= Uint_0
;
1094 Prefix_Length
: Natural := 0)
1099 Comp
:= First_Component_Or_Discriminant
(Ent
);
1100 while Present
(Comp
) loop
1102 -- Skip discriminant in unchecked union (since it is not there!)
1104 if Ekind
(Comp
) = E_Discriminant
1105 and then Is_Unchecked_Union
(Ent
)
1110 -- Skip _Parent component in extension (to avoid overlap)
1112 if Chars
(Comp
) = Name_uParent
then
1119 Ctyp
: constant Entity_Id
:= Underlying_Type
(Etype
(Comp
));
1120 Bofs
: constant Uint
:= Component_Bit_Offset
(Comp
);
1126 Name_Length
: Natural;
1129 Get_Decoded_Name_String
(Chars
(Comp
));
1130 Name_Length
:= Prefix_Length
+ Name_Len
;
1132 if Rep_Not_Constant
(Bofs
) then
1134 -- If the record is not packed, then we know that all fields
1135 -- whose position is not specified have starting normalized
1136 -- bit position of zero.
1138 if Unknown_Normalized_First_Bit
(Comp
)
1139 and then not Is_Packed
(Ent
)
1141 Set_Normalized_First_Bit
(Comp
, Uint_0
);
1144 UI_Image_Length
:= 2; -- For "??" marker
1147 Fbit
:= Bofs
mod SSU
;
1149 -- Complete annotation in case not done
1151 if Unknown_Normalized_First_Bit
(Comp
) then
1152 Set_Normalized_Position
(Comp
, Npos
);
1153 Set_Normalized_First_Bit
(Comp
, Fbit
);
1156 Spos
:= Starting_Position
+ Npos
;
1157 Sbit
:= Starting_First_Bit
+ Fbit
;
1164 -- If extended information is requested, recurse fully into
1165 -- record components, i.e. skip the outer level.
1167 if List_Representation_Info_Extended
1168 and then Is_Record_Type
(Ctyp
)
1170 Compute_Max_Length
(Ctyp
, Spos
, Sbit
, Name_Length
+ 1);
1177 Max_Name_Length
:= Natural'Max (Max_Name_Length
, Name_Length
);
1179 Natural'Max (Max_Spos_Length
, UI_Image_Length
);
1183 Next_Component_Or_Discriminant
(Comp
);
1185 end Compute_Max_Length
;
1187 ---------------------------
1188 -- List_Component_Layout --
1189 ---------------------------
1191 procedure List_Component_Layout
1193 Starting_Position
: Uint
:= Uint_0
;
1194 Starting_First_Bit
: Uint
:= Uint_0
;
1195 Prefix
: String := "";
1196 Indent
: Natural := 0)
1198 Esiz
: constant Uint
:= Esize
(Ent
);
1199 Npos
: constant Uint
:= Normalized_Position
(Ent
);
1200 Fbit
: constant Uint
:= Normalized_First_Bit
(Ent
);
1206 if List_Representation_Info_To_JSON
then
1210 Write_Str
(" ""name"": """);
1212 Write_Str
(Name_Buffer
(1 .. Name_Len
));
1214 if Ekind
(Ent
) = E_Discriminant
then
1216 Write_Str
(" ""discriminant"": ");
1217 UI_Write
(Discriminant_Number
(Ent
));
1221 Write_Str
(" ""Position"": ");
1225 Write_Str
(Name_Buffer
(1 .. Name_Len
));
1226 Spaces
(Max_Name_Length
- Prefix
'Length - Name_Len
);
1230 if Known_Static_Normalized_Position
(Ent
) then
1231 Spos
:= Starting_Position
+ Npos
;
1232 Sbit
:= Starting_First_Bit
+ Fbit
;
1239 Spaces
(Max_Spos_Length
- UI_Image_Length
);
1240 Write_Str
(UI_Image_Buffer
(1 .. UI_Image_Length
));
1242 elsif Known_Normalized_Position
(Ent
)
1243 and then List_Representation_Info
= 3
1245 Spaces
(Max_Spos_Length
- 2);
1247 if Starting_Position
/= Uint_0
then
1248 UI_Write
(Starting_Position
);
1258 if List_Representation_Info_To_JSON
then
1261 Write_Str
(" ""First_Bit"": ");
1263 Write_Str
(" range ");
1266 Sbit
:= Starting_First_Bit
+ Fbit
;
1274 if List_Representation_Info_To_JSON
then
1277 Write_Str
(" ""Size"": ");
1282 -- Allowing Uint_0 here is an annoying special case. Really this
1283 -- should be a fine Esize value but currently it means unknown,
1284 -- except that we know after gigi has back annotated that a size
1285 -- of zero is real, since otherwise gigi back annotates using
1286 -- No_Uint as the value to indicate unknown.
1288 if (Esize
(Ent
) = Uint_0
or else Known_Static_Esize
(Ent
))
1289 and then Known_Static_Normalized_First_Bit
(Ent
)
1291 Lbit
:= Sbit
+ Esiz
- 1;
1293 if List_Representation_Info_To_JSON
then
1303 -- The test for Esize (Ent) not Uint_0 here is an annoying special
1304 -- case. Officially a value of zero for Esize means unknown, but
1305 -- here we use the fact that we know that gigi annotates Esize with
1306 -- No_Uint, not Uint_0. Really everyone should use No_Uint???
1308 elsif List_Representation_Info
< 3
1309 or else (Esize
(Ent
) /= Uint_0
and then Unknown_Esize
(Ent
))
1313 -- List_Representation >= 3 and Known_Esize (Ent)
1316 Write_Val
(Esiz
, Paren
=> not List_Representation_Info_To_JSON
);
1318 -- If in front-end layout mode, then dynamic size is stored in
1319 -- storage units, so renormalize for output.
1321 if not Back_End_Layout
then
1326 -- Add appropriate first bit offset
1328 if not List_Representation_Info_To_JSON
then
1337 Write_Int
(UI_To_Int
(Sbit
) - 1);
1342 if List_Representation_Info_To_JSON
then
1349 end List_Component_Layout
;
1351 ------------------------
1352 -- List_Record_Layout --
1353 ------------------------
1355 procedure List_Record_Layout
1357 Starting_Position
: Uint
:= Uint_0
;
1358 Starting_First_Bit
: Uint
:= Uint_0
;
1359 Prefix
: String := "")
1364 Comp
:= First_Component_Or_Discriminant
(Ent
);
1365 while Present
(Comp
) loop
1367 -- Skip discriminant in unchecked union (since it is not there!)
1369 if Ekind
(Comp
) = E_Discriminant
1370 and then Is_Unchecked_Union
(Ent
)
1375 -- Skip _Parent component in extension (to avoid overlap)
1377 if Chars
(Comp
) = Name_uParent
then
1384 Ctyp
: constant Entity_Id
:= Underlying_Type
(Etype
(Comp
));
1385 Npos
: constant Uint
:= Normalized_Position
(Comp
);
1386 Fbit
: constant Uint
:= Normalized_First_Bit
(Comp
);
1391 Get_Decoded_Name_String
(Chars
(Comp
));
1392 Set_Casing
(Unit_Casing
);
1394 -- If extended information is requested, recurse fully into
1395 -- record components, i.e. skip the outer level.
1397 if List_Representation_Info_Extended
1398 and then Is_Record_Type
(Ctyp
)
1399 and then Known_Static_Normalized_Position
(Comp
)
1400 and then Known_Static_Normalized_First_Bit
(Comp
)
1402 Spos
:= Starting_Position
+ Npos
;
1403 Sbit
:= Starting_First_Bit
+ Fbit
;
1410 List_Record_Layout
(Ctyp
,
1411 Spos
, Sbit
, Prefix
& Name_Buffer
(1 .. Name_Len
) & ".");
1416 List_Component_Layout
(Comp
,
1417 Starting_Position
, Starting_First_Bit
, Prefix
);
1421 Next_Component_Or_Discriminant
(Comp
);
1423 end List_Record_Layout
;
1425 -----------------------------------
1426 -- List_Structural_Record_Layout --
1427 -----------------------------------
1429 procedure List_Structural_Record_Layout
1431 Outer_Ent
: Entity_Id
;
1432 Variant
: Node_Id
:= Empty
;
1433 Indent
: Natural := 0)
1435 function Derived_Discriminant
(Disc
: Entity_Id
) return Entity_Id
;
1436 -- This function assumes that Outer_Ent is an extension of Ent.
1437 -- Disc is a discriminant of Ent that does not itself constrain a
1438 -- discriminant of the parent type of Ent. Return the discriminant
1439 -- of Outer_Ent that ultimately constrains Disc, if any.
1441 ----------------------------
1442 -- Derived_Discriminant --
1443 ----------------------------
1445 function Derived_Discriminant
(Disc
: Entity_Id
) return Entity_Id
is
1446 Corr_Disc
: Entity_Id
;
1447 Derived_Disc
: Entity_Id
;
1450 Derived_Disc
:= First_Stored_Discriminant
(Outer_Ent
);
1452 -- Loop over the discriminants of the extension
1454 while Present
(Derived_Disc
) loop
1456 -- Check if this discriminant constrains another discriminant.
1457 -- If so, find the ultimately constrained discriminant and
1458 -- compare with the original components in the base type.
1460 if Present
(Corresponding_Discriminant
(Derived_Disc
)) then
1461 Corr_Disc
:= Corresponding_Discriminant
(Derived_Disc
);
1463 while Present
(Corresponding_Discriminant
(Corr_Disc
)) loop
1464 Corr_Disc
:= Corresponding_Discriminant
(Corr_Disc
);
1467 if Original_Record_Component
(Corr_Disc
) =
1468 Original_Record_Component
(Disc
)
1470 return Derived_Disc
;
1474 Next_Stored_Discriminant
(Derived_Disc
);
1477 -- Disc is not constrained by a discriminant of Outer_Ent
1480 end Derived_Discriminant
;
1482 -- Local declarations
1485 Comp_List
: Node_Id
;
1486 First
: Boolean := True;
1489 -- Start of processing for List_Structural_Record_Layout
1492 -- If we are dealing with a variant, just process the components
1494 if Present
(Variant
) then
1495 Comp_List
:= Component_List
(Variant
);
1497 -- Otherwise, we are dealing with the full record and need to get
1498 -- to its definition in order to retrieve its structural layout.
1502 Definition
: Node_Id
:=
1503 Type_Definition
(Declaration_Node
(Ent
));
1505 Is_Extension
: constant Boolean :=
1506 Is_Tagged_Type
(Ent
)
1507 and then Nkind
(Definition
) =
1508 N_Derived_Type_Definition
;
1511 Listed_Disc
: Entity_Id
;
1514 -- If this is an extension, first list the layout of the parent
1515 -- and then proceed to the extension part, if any.
1517 if Is_Extension
then
1518 List_Structural_Record_Layout
1519 (Base_Type
(Parent_Subtype
(Ent
)), Outer_Ent
);
1522 if Present
(Record_Extension_Part
(Definition
)) then
1523 Definition
:= Record_Extension_Part
(Definition
);
1527 -- If the record has discriminants and is not an unchecked
1528 -- union, then display them now.
1530 if Has_Discriminants
(Ent
)
1531 and then not Is_Unchecked_Union
(Ent
)
1533 Disc
:= First_Stored_Discriminant
(Ent
);
1534 while Present
(Disc
) loop
1536 -- If this is a record extension and the discriminant is
1537 -- the renaming of another discriminant, skip it.
1540 and then Present
(Corresponding_Discriminant
(Disc
))
1545 -- If this is the parent type of an extension, retrieve
1546 -- the derived discriminant from the extension, if any.
1548 if Ent
/= Outer_Ent
then
1549 Listed_Disc
:= Derived_Discriminant
(Disc
);
1551 if No
(Listed_Disc
) then
1555 Listed_Disc
:= Disc
;
1558 Get_Decoded_Name_String
(Chars
(Listed_Disc
));
1559 Set_Casing
(Unit_Casing
);
1568 List_Component_Layout
(Listed_Disc
, Indent
=> Indent
);
1571 Next_Stored_Discriminant
(Disc
);
1575 Comp_List
:= Component_List
(Definition
);
1579 -- Bail out for the null record
1581 if No
(Comp_List
) then
1585 -- Now deal with the regular components, if any
1587 if Present
(Component_Items
(Comp_List
)) then
1588 Comp
:= First_Non_Pragma
(Component_Items
(Comp_List
));
1589 while Present
(Comp
) loop
1591 -- Skip _Parent component in extension (to avoid overlap)
1593 if Chars
(Defining_Identifier
(Comp
)) = Name_uParent
then
1597 Get_Decoded_Name_String
(Chars
(Defining_Identifier
(Comp
)));
1598 Set_Casing
(Unit_Casing
);
1607 List_Component_Layout
1608 (Defining_Identifier
(Comp
), Indent
=> Indent
);
1611 Next_Non_Pragma
(Comp
);
1615 -- We are done if there is no variant part
1617 if No
(Variant_Part
(Comp_List
)) then
1625 Write_Str
(" ""variant"" : [");
1627 -- Otherwise we recurse on each variant
1629 Var
:= First_Non_Pragma
(Variants
(Variant_Part
(Comp_List
)));
1631 while Present
(Var
) loop
1642 Write_Str
(" ""present"": ");
1643 Write_Val
(Present_Expr
(Var
));
1646 Write_Str
(" ""record"": [");
1648 List_Structural_Record_Layout
(Ent
, Outer_Ent
, Var
, Indent
+ 4);
1655 Next_Non_Pragma
(Var
);
1657 end List_Structural_Record_Layout
;
1659 -- Start of processing for List_Record_Info
1664 if List_Representation_Info_To_JSON
then
1668 List_Type_Info
(Ent
);
1670 -- First find out max line length and max starting position
1671 -- length, for the purpose of lining things up nicely.
1673 Compute_Max_Length
(Ent
);
1675 -- Then do actual output based on those values
1677 if List_Representation_Info_To_JSON
then
1679 Write_Str
(" ""record"": [");
1681 List_Structural_Record_Layout
(Ent
, Ent
);
1688 Write_Line
(" use record");
1690 List_Record_Layout
(Ent
);
1692 Write_Line
("end record;");
1695 List_Scalar_Storage_Order
(Ent
, Bytes_Big_Endian
);
1697 List_Linker_Section
(Ent
);
1699 if List_Representation_Info_To_JSON
then
1703 end List_Record_Info
;
1709 procedure List_Rep_Info
(Bytes_Big_Endian
: Boolean) is
1713 if List_Representation_Info
/= 0
1714 or else List_Representation_Info_Mechanisms
1716 for U
in Main_Unit
.. Last_Unit
loop
1717 if In_Extended_Main_Source_Unit
(Cunit_Entity
(U
)) then
1718 Unit_Casing
:= Identifier_Casing
(Source_Index
(U
));
1720 -- Normal case, list to standard output
1722 if not List_Representation_Info_To_File
then
1723 if not List_Representation_Info_To_JSON
then
1725 Write_Str
("Representation information for unit ");
1726 Write_Unit_Name
(Unit_Name
(U
));
1730 for J
in 1 .. Col
- 1 loop
1737 List_Entities
(Cunit_Entity
(U
), Bytes_Big_Endian
);
1739 -- List representation information to file
1742 Create_Repinfo_File_Access
.all
1743 (Get_Name_String
(File_Name
(Source_Index
(U
))));
1744 Set_Special_Output
(Write_Info_Line
'Access);
1745 List_Entities
(Cunit_Entity
(U
), Bytes_Big_Endian
);
1746 Set_Special_Output
(null);
1747 Close_Repinfo_File_Access
.all;
1754 -------------------------------
1755 -- List_Scalar_Storage_Order --
1756 -------------------------------
1758 procedure List_Scalar_Storage_Order
1760 Bytes_Big_Endian
: Boolean)
1762 procedure List_Attr
(Attr_Name
: String; Is_Reversed
: Boolean);
1763 -- Show attribute definition clause for Attr_Name (an endianness
1764 -- attribute), depending on whether or not the endianness is reversed
1765 -- compared to native endianness.
1771 procedure List_Attr
(Attr_Name
: String; Is_Reversed
: Boolean) is
1773 if List_Representation_Info_To_JSON
then
1776 Write_Str
(Attr_Name
);
1777 Write_Str
(""": ""System.");
1782 Write_Str
(Attr_Name
);
1783 Write_Str
(" use System.");
1786 if Bytes_Big_Endian
xor Is_Reversed
then
1792 Write_Str
("_Order_First");
1793 if List_Representation_Info_To_JSON
then
1800 List_SSO
: constant Boolean :=
1801 Has_Rep_Item
(Ent
, Name_Scalar_Storage_Order
)
1802 or else SSO_Set_Low_By_Default
(Ent
)
1803 or else SSO_Set_High_By_Default
(Ent
);
1804 -- Scalar_Storage_Order is displayed if specified explicitly
1805 -- or set by Default_Scalar_Storage_Order.
1807 -- Start of processing for List_Scalar_Storage_Order
1810 -- For record types, list Bit_Order if not default, or if SSO is shown
1812 if Is_Record_Type
(Ent
)
1813 and then (List_SSO
or else Reverse_Bit_Order
(Ent
))
1815 List_Attr
("Bit_Order", Reverse_Bit_Order
(Ent
));
1818 -- List SSO if required. If not, then storage is supposed to be in
1822 List_Attr
("Scalar_Storage_Order", Reverse_Storage_Order
(Ent
));
1824 pragma Assert
(not Reverse_Storage_Order
(Ent
));
1827 end List_Scalar_Storage_Order
;
1829 --------------------
1830 -- List_Type_Info --
1831 --------------------
1833 procedure List_Type_Info
(Ent
: Entity_Id
) is
1835 if List_Representation_Info_To_JSON
then
1836 Write_Str
(" ""name"": """);
1839 List_Location
(Ent
);
1842 -- Do not list size info for unconstrained arrays, not meaningful
1844 if Is_Array_Type
(Ent
) and then not Is_Constrained
(Ent
) then
1848 -- If Esize and RM_Size are the same, list as Size. This is a common
1849 -- case, which we may as well list in simple form.
1851 if Esize
(Ent
) = RM_Size
(Ent
) then
1852 if List_Representation_Info_To_JSON
then
1853 Write_Str
(" ""Size"": ");
1854 Write_Val
(Esize
(Ent
));
1859 Write_Str
("'Size use ");
1860 Write_Val
(Esize
(Ent
));
1864 -- Otherwise list size values separately
1867 if List_Representation_Info_To_JSON
then
1868 Write_Str
(" ""Object_Size"": ");
1869 Write_Val
(Esize
(Ent
));
1872 Write_Str
(" ""Value_Size"": ");
1873 Write_Val
(RM_Size
(Ent
));
1879 Write_Str
("'Object_Size use ");
1880 Write_Val
(Esize
(Ent
));
1885 Write_Str
("'Value_Size use ");
1886 Write_Val
(RM_Size
(Ent
));
1892 if List_Representation_Info_To_JSON
then
1893 Write_Str
(" ""Alignment"": ");
1894 Write_Val
(Alignment
(Ent
));
1898 Write_Str
("'Alignment use ");
1899 Write_Val
(Alignment
(Ent
));
1903 -- Special stuff for fixed-point
1905 if Is_Fixed_Point_Type
(Ent
) then
1907 -- Write small (always a static constant)
1909 if List_Representation_Info_To_JSON
then
1911 Write_Str
(" ""Small"": ");
1912 UR_Write
(Small_Value
(Ent
));
1916 Write_Str
("'Small use ");
1917 UR_Write
(Small_Value
(Ent
));
1921 -- Write range if static
1924 R
: constant Node_Id
:= Scalar_Range
(Ent
);
1927 if Nkind
(Low_Bound
(R
)) = N_Real_Literal
1929 Nkind
(High_Bound
(R
)) = N_Real_Literal
1931 if List_Representation_Info_To_JSON
then
1933 Write_Str
(" ""Range"": [ ");
1934 UR_Write
(Realval
(Low_Bound
(R
)));
1936 UR_Write
(Realval
(High_Bound
(R
)));
1941 Write_Str
("'Range use ");
1942 UR_Write
(Realval
(Low_Bound
(R
)));
1944 UR_Write
(Realval
(High_Bound
(R
)));
1952 ----------------------
1953 -- Rep_Not_Constant --
1954 ----------------------
1956 function Rep_Not_Constant
(Val
: Node_Ref_Or_Val
) return Boolean is
1958 if Val
= No_Uint
or else Val
< 0 then
1963 end Rep_Not_Constant
;
1969 function Rep_Value
(Val
: Node_Ref_Or_Val
; D
: Discrim_List
) return Uint
is
1971 function B
(Val
: Boolean) return Uint
;
1972 -- Returns Uint_0 for False, Uint_1 for True
1974 function T
(Val
: Node_Ref_Or_Val
) return Boolean;
1975 -- Returns True for 0, False for any non-zero (i.e. True)
1977 function V
(Val
: Node_Ref_Or_Val
) return Uint
;
1978 -- Internal recursive routine to evaluate tree
1980 function W
(Val
: Uint
) return Word
;
1981 -- Convert Val to Word, assuming Val is always in the Int range. This
1982 -- is a helper function for the evaluation of bitwise expressions like
1983 -- Bit_And_Expr, for which there is no direct support in uintp. Uint
1984 -- values out of the Int range are expected to be seen in such
1985 -- expressions only with overflowing byte sizes around, introducing
1986 -- inherent unreliabilities in computations anyway.
1992 function B
(Val
: Boolean) return Uint
is
2005 function T
(Val
: Node_Ref_Or_Val
) return Boolean is
2018 function V
(Val
: Node_Ref_Or_Val
) return Uint
is
2027 Node
: Exp_Node
renames Rep_Table
.Table
(-UI_To_Int
(Val
));
2032 if T
(Node
.Op1
) then
2033 return V
(Node
.Op2
);
2035 return V
(Node
.Op3
);
2039 return V
(Node
.Op1
) + V
(Node
.Op2
);
2042 return V
(Node
.Op1
) - V
(Node
.Op2
);
2045 return V
(Node
.Op1
) * V
(Node
.Op2
);
2047 when Trunc_Div_Expr
=>
2048 return V
(Node
.Op1
) / V
(Node
.Op2
);
2050 when Ceil_Div_Expr
=>
2053 (V
(Node
.Op1
) / UR_From_Uint
(V
(Node
.Op2
)));
2055 when Floor_Div_Expr
=>
2058 (V
(Node
.Op1
) / UR_From_Uint
(V
(Node
.Op2
)));
2060 when Trunc_Mod_Expr
=>
2061 return V
(Node
.Op1
) rem V
(Node
.Op2
);
2063 when Floor_Mod_Expr
=>
2064 return V
(Node
.Op1
) mod V
(Node
.Op2
);
2066 when Ceil_Mod_Expr
=>
2069 Q
:= UR_Ceiling
(L
/ UR_From_Uint
(R
));
2072 when Exact_Div_Expr
=>
2073 return V
(Node
.Op1
) / V
(Node
.Op2
);
2076 return -V
(Node
.Op1
);
2079 return UI_Min
(V
(Node
.Op1
), V
(Node
.Op2
));
2082 return UI_Max
(V
(Node
.Op1
), V
(Node
.Op2
));
2085 return UI_Abs
(V
(Node
.Op1
));
2087 when Truth_And_Expr
=>
2088 return B
(T
(Node
.Op1
) and then T
(Node
.Op2
));
2090 when Truth_Or_Expr
=>
2091 return B
(T
(Node
.Op1
) or else T
(Node
.Op2
));
2093 when Truth_Xor_Expr
=>
2094 return B
(T
(Node
.Op1
) xor T
(Node
.Op2
));
2096 when Truth_Not_Expr
=>
2097 return B
(not T
(Node
.Op1
));
2099 when Bit_And_Expr
=>
2102 return UI_From_Int
(Int
(W
(L
) and W
(R
)));
2105 return B
(V
(Node
.Op1
) < V
(Node
.Op2
));
2108 return B
(V
(Node
.Op1
) <= V
(Node
.Op2
));
2111 return B
(V
(Node
.Op1
) > V
(Node
.Op2
));
2114 return B
(V
(Node
.Op1
) >= V
(Node
.Op2
));
2117 return B
(V
(Node
.Op1
) = V
(Node
.Op2
));
2120 return B
(V
(Node
.Op1
) /= V
(Node
.Op2
));
2124 Sub
: constant Int
:= UI_To_Int
(Node
.Op1
);
2126 pragma Assert
(Sub
in D
'Range);
2141 -- We use an unchecked conversion to map Int values to their Word
2142 -- bitwise equivalent, which we could not achieve with a normal type
2143 -- conversion for negative Ints. We want bitwise equivalents because W
2144 -- is used as a helper for bit operators like Bit_And_Expr, and can be
2145 -- called for negative Ints in the context of aligning expressions like
2146 -- X+Align & -Align.
2148 function W
(Val
: Uint
) return Word
is
2149 function To_Word
is new Ada
.Unchecked_Conversion
(Int
, Word
);
2151 return To_Word
(UI_To_Int
(Val
));
2154 -- Start of processing for Rep_Value
2157 if Val
= No_Uint
then
2169 procedure Spaces
(N
: Natural) is
2171 for J
in 1 .. N
loop
2180 procedure Tree_Read
is
2182 Rep_Table
.Tree_Read
;
2189 procedure Tree_Write
is
2191 Rep_Table
.Tree_Write
;
2194 ---------------------
2195 -- Write_Info_Line --
2196 ---------------------
2198 procedure Write_Info_Line
(S
: String) is
2200 Write_Repinfo_Line_Access
.all (S
(S
'First .. S
'Last - 1));
2201 end Write_Info_Line
;
2203 ---------------------
2204 -- Write_Mechanism --
2205 ---------------------
2207 procedure Write_Mechanism
(M
: Mechanism_Type
) is
2211 Write_Str
("default");
2217 Write_Str
("reference");
2220 raise Program_Error
;
2222 end Write_Mechanism
;
2224 -----------------------
2225 -- Write_Unknown_Val --
2226 -----------------------
2228 procedure Write_Unknown_Val
is
2230 if List_Representation_Info_To_JSON
then
2231 Write_Str
("""??""");
2235 end Write_Unknown_Val
;
2241 procedure Write_Val
(Val
: Node_Ref_Or_Val
; Paren
: Boolean := False) is
2243 if Rep_Not_Constant
(Val
) then
2244 if List_Representation_Info
< 3 or else Val
= No_Uint
then
2252 if Back_End_Layout
then
2253 List_GCC_Expression
(Val
);
2255 Write_Name_Decoded
(Chars
(Get_Dynamic_SO_Entity
(Val
)));