1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1999-2004 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 2, 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 COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
32 ------------------------------------------------------------------------------
34 with Alloc
; use Alloc
;
35 with Atree
; use Atree
;
36 with Casing
; use Casing
;
37 with Debug
; use Debug
;
38 with Einfo
; use Einfo
;
40 with Namet
; use Namet
;
42 with Output
; use Output
;
43 with Sinfo
; use Sinfo
;
44 with Sinput
; use Sinput
;
45 with Snames
; use Snames
;
46 with Stand
; use Stand
;
47 with Table
; use Table
;
48 with Uname
; use Uname
;
49 with Urealp
; use Urealp
;
51 package body Repinfo
is
54 -- Value for Storage_Unit, we do not want to get this from TTypes, since
55 -- this introduces problematic dependencies in ASIS, and in any case this
56 -- value is assumed to be 8 for the implementation of the DDA.
58 -- This is wrong for AAMP???
60 ---------------------------------------
61 -- Representation of gcc Expressions --
62 ---------------------------------------
64 -- This table is used only if Frontend_Layout_On_Target is False,
65 -- so that gigi lays out dynamic size/offset fields using encoded
68 -- A table internal to this unit is used to hold the values of
69 -- back annotated expressions. This table is written out by -gnatt
70 -- and read back in for ASIS processing.
72 -- Node values are stored as Uint values which are the negative of
73 -- the node index in this table. Constants appear as non-negative
76 type Exp_Node
is record
78 Op1
: Node_Ref_Or_Val
;
79 Op2
: Node_Ref_Or_Val
;
80 Op3
: Node_Ref_Or_Val
;
83 package Rep_Table
is new Table
.Table
(
84 Table_Component_Type
=> Exp_Node
,
85 Table_Index_Type
=> Nat
,
87 Table_Initial
=> Alloc
.Rep_Table_Initial
,
88 Table_Increment
=> Alloc
.Rep_Table_Increment
,
89 Table_Name
=> "BE_Rep_Table");
91 --------------------------------------------------------------
92 -- Representation of Front-End Dynamic Size/Offset Entities --
93 --------------------------------------------------------------
95 package Dynamic_SO_Entity_Table
is new Table
.Table
(
96 Table_Component_Type
=> Entity_Id
,
97 Table_Index_Type
=> Nat
,
99 Table_Initial
=> Alloc
.Rep_Table_Initial
,
100 Table_Increment
=> Alloc
.Rep_Table_Increment
,
101 Table_Name
=> "FE_Rep_Table");
103 Unit_Casing
: Casing_Type
;
104 -- Identifier casing for current unit
106 Need_Blank_Line
: Boolean;
107 -- Set True if a blank line is needed before outputting any
108 -- information for the current entity. Set True when a new
109 -- entity is processed, and false when the blank line is output.
111 -----------------------
112 -- Local Subprograms --
113 -----------------------
115 function Back_End_Layout
return Boolean;
116 -- Test for layout mode, True = back end, False = front end. This
117 -- function is used rather than checking the configuration parameter
118 -- because we do not want Repinfo to depend on Targparm (for ASIS)
120 procedure Blank_Line
;
121 -- Called before outputting anything for an entity. Ensures that
122 -- a blank line precedes the output for a particular entity.
124 procedure List_Entities
(Ent
: Entity_Id
);
125 -- This procedure lists the entities associated with the entity E,
126 -- starting with the First_Entity and using the Next_Entity link.
127 -- If a nested package is found, entities within the package are
128 -- recursively processed.
130 procedure List_Name
(Ent
: Entity_Id
);
131 -- List name of entity Ent in appropriate case. The name is listed with
132 -- full qualification up to but not including the compilation unit name.
134 procedure List_Array_Info
(Ent
: Entity_Id
);
135 -- List representation info for array type Ent
137 procedure List_Mechanisms
(Ent
: Entity_Id
);
138 -- List mechanism information for parameters of Ent, which is a
139 -- subprogram, subprogram type, or an entry or entry family.
141 procedure List_Object_Info
(Ent
: Entity_Id
);
142 -- List representation info for object Ent
144 procedure List_Record_Info
(Ent
: Entity_Id
);
145 -- List representation info for record type Ent
147 procedure List_Type_Info
(Ent
: Entity_Id
);
148 -- List type info for type Ent
150 function Rep_Not_Constant
(Val
: Node_Ref_Or_Val
) return Boolean;
151 -- Returns True if Val represents a variable value, and False if it
152 -- represents a value that is fixed at compile time.
154 procedure Spaces
(N
: Natural);
155 -- Output given number of spaces
157 procedure Write_Info_Line
(S
: String);
158 -- Routine to write a line to Repinfo output file. This routine is
159 -- passed as a special output procedure to Output.Set_Special_Output.
160 -- Note that Write_Info_Line is called with an EOL character at the
161 -- end of each line, as per the Output spec, but the internal call
162 -- to the appropriate routine in Osint requires that the end of line
163 -- sequence be stripped off.
165 procedure Write_Mechanism
(M
: Mechanism_Type
);
166 -- Writes symbolic string for mechanism represented by M
168 procedure Write_Val
(Val
: Node_Ref_Or_Val
; Paren
: Boolean := False);
169 -- Given a representation value, write it out. No_Uint values or values
170 -- dependent on discriminants are written as two question marks. If the
171 -- flag Paren is set, then the output is surrounded in parentheses if
172 -- it is other than a simple value.
174 ---------------------
175 -- Back_End_Layout --
176 ---------------------
178 function Back_End_Layout
return Boolean is
180 -- We have back end layout if the back end has made any entries in
181 -- the table of GCC expressions, otherwise we have front end layout.
183 return Rep_Table
.Last
> 0;
190 procedure Blank_Line
is
192 if Need_Blank_Line
then
194 Need_Blank_Line
:= False;
198 ------------------------
199 -- Create_Discrim_Ref --
200 ------------------------
202 function Create_Discrim_Ref
(Discr
: Entity_Id
) return Node_Ref
is
203 N
: constant Uint
:= Discriminant_Number
(Discr
);
206 Rep_Table
.Increment_Last
;
208 Rep_Table
.Table
(T
).Expr
:= Discrim_Val
;
209 Rep_Table
.Table
(T
).Op1
:= N
;
210 Rep_Table
.Table
(T
).Op2
:= No_Uint
;
211 Rep_Table
.Table
(T
).Op3
:= No_Uint
;
212 return UI_From_Int
(-T
);
213 end Create_Discrim_Ref
;
215 ---------------------------
216 -- Create_Dynamic_SO_Ref --
217 ---------------------------
219 function Create_Dynamic_SO_Ref
(E
: Entity_Id
) return Dynamic_SO_Ref
is
222 Dynamic_SO_Entity_Table
.Increment_Last
;
223 T
:= Dynamic_SO_Entity_Table
.Last
;
224 Dynamic_SO_Entity_Table
.Table
(T
) := E
;
225 return UI_From_Int
(-T
);
226 end Create_Dynamic_SO_Ref
;
234 Op1
: Node_Ref_Or_Val
;
235 Op2
: Node_Ref_Or_Val
:= No_Uint
;
236 Op3
: Node_Ref_Or_Val
:= No_Uint
) return Node_Ref
240 Rep_Table
.Increment_Last
;
242 Rep_Table
.Table
(T
).Expr
:= Expr
;
243 Rep_Table
.Table
(T
).Op1
:= Op1
;
244 Rep_Table
.Table
(T
).Op2
:= Op2
;
245 Rep_Table
.Table
(T
).Op3
:= Op3
;
246 return UI_From_Int
(-T
);
249 ---------------------------
250 -- Get_Dynamic_SO_Entity --
251 ---------------------------
253 function Get_Dynamic_SO_Entity
(U
: Dynamic_SO_Ref
) return Entity_Id
is
255 return Dynamic_SO_Entity_Table
.Table
(-UI_To_Int
(U
));
256 end Get_Dynamic_SO_Entity
;
258 -----------------------
259 -- Is_Dynamic_SO_Ref --
260 -----------------------
262 function Is_Dynamic_SO_Ref
(U
: SO_Ref
) return Boolean is
265 end Is_Dynamic_SO_Ref
;
267 ----------------------
268 -- Is_Static_SO_Ref --
269 ----------------------
271 function Is_Static_SO_Ref
(U
: SO_Ref
) return Boolean is
274 end Is_Static_SO_Ref
;
280 procedure lgx
(U
: Node_Ref_Or_Val
) is
282 List_GCC_Expression
(U
);
286 ----------------------
287 -- List_Array_Info --
288 ----------------------
290 procedure List_Array_Info
(Ent
: Entity_Id
) is
292 List_Type_Info
(Ent
);
295 Write_Str
("'Component_Size use ");
296 Write_Val
(Component_Size
(Ent
));
304 procedure List_Entities
(Ent
: Entity_Id
) is
308 function Find_Declaration
(E
: Entity_Id
) return Node_Id
;
309 -- Utility to retrieve declaration node for entity in the
310 -- case of package bodies and subprograms.
312 ----------------------
313 -- Find_Declaration --
314 ----------------------
316 function Find_Declaration
(E
: Entity_Id
) return Node_Id
is
322 and then Nkind
(Decl
) /= N_Package_Body
323 and then Nkind
(Decl
) /= N_Subprogram_Declaration
324 and then Nkind
(Decl
) /= N_Subprogram_Body
326 Decl
:= Parent
(Decl
);
330 end Find_Declaration
;
332 -- Start of processing for List_Entities
335 if Present
(Ent
) then
337 -- If entity is a subprogram and we are listing mechanisms,
338 -- then we need to list mechanisms for this entity.
340 if List_Representation_Info_Mechanisms
341 and then (Is_Subprogram
(Ent
)
342 or else Ekind
(Ent
) = E_Entry
343 or else Ekind
(Ent
) = E_Entry_Family
)
345 Need_Blank_Line
:= True;
346 List_Mechanisms
(Ent
);
349 E
:= First_Entity
(Ent
);
350 while Present
(E
) loop
351 Need_Blank_Line
:= True;
353 -- We list entities that come from source (excluding private
354 -- or incomplete types or deferred constants, where we will
355 -- list the info for the full view). If debug flag A is set,
356 -- then all entities are listed
358 if (Comes_From_Source
(E
)
359 and then not Is_Incomplete_Or_Private_Type
(E
)
360 and then not (Ekind
(E
) = E_Constant
361 and then Present
(Full_View
(E
))))
362 or else Debug_Flag_AA
368 Ekind
(E
) = E_Entry_Family
370 Ekind
(E
) = E_Subprogram_Type
372 if List_Representation_Info_Mechanisms
then
376 elsif Is_Record_Type
(E
) then
377 if List_Representation_Info
>= 1 then
378 List_Record_Info
(E
);
381 elsif Is_Array_Type
(E
) then
382 if List_Representation_Info
>= 1 then
386 elsif Is_Type
(E
) then
387 if List_Representation_Info
>= 2 then
391 elsif Ekind
(E
) = E_Variable
393 Ekind
(E
) = E_Constant
395 Ekind
(E
) = E_Loop_Parameter
399 if List_Representation_Info
>= 2 then
400 List_Object_Info
(E
);
405 -- Recurse into nested package, but not if they are
406 -- package renamings (in particular renamings of the
407 -- enclosing package, as for some Java bindings and
408 -- for generic instances).
410 if Ekind
(E
) = E_Package
then
411 if No
(Renamed_Object
(E
)) then
415 -- Recurse into bodies
417 elsif Ekind
(E
) = E_Protected_Type
419 Ekind
(E
) = E_Task_Type
421 Ekind
(E
) = E_Subprogram_Body
423 Ekind
(E
) = E_Package_Body
425 Ekind
(E
) = E_Task_Body
427 Ekind
(E
) = E_Protected_Body
431 -- Recurse into blocks
433 elsif Ekind
(E
) = E_Block
then
438 E
:= Next_Entity
(E
);
441 -- For a package body, the entities of the visible subprograms
442 -- are declared in the corresponding spec. Iterate over its
443 -- entities in order to handle properly the subprogram bodies.
444 -- Skip bodies in subunits, which are listed independently.
446 if Ekind
(Ent
) = E_Package_Body
447 and then Present
(Corresponding_Spec
(Find_Declaration
(Ent
)))
449 E
:= First_Entity
(Corresponding_Spec
(Find_Declaration
(Ent
)));
451 while Present
(E
) loop
454 Nkind
(Find_Declaration
(E
)) = N_Subprogram_Declaration
456 Body_E
:= Corresponding_Body
(Find_Declaration
(E
));
460 Nkind
(Parent
(Find_Declaration
(Body_E
))) /= N_Subunit
462 List_Entities
(Body_E
);
472 -------------------------
473 -- List_GCC_Expression --
474 -------------------------
476 procedure List_GCC_Expression
(U
: Node_Ref_Or_Val
) is
478 procedure Print_Expr
(Val
: Node_Ref_Or_Val
);
479 -- Internal recursive procedure to print expression
485 procedure Print_Expr
(Val
: Node_Ref_Or_Val
) is
488 UI_Write
(Val
, Decimal
);
492 Node
: Exp_Node
renames Rep_Table
.Table
(-UI_To_Int
(Val
));
494 procedure Binop
(S
: String);
495 -- Output text for binary operator with S being operator name
501 procedure Binop
(S
: String) is
504 Print_Expr
(Node
.Op1
);
506 Print_Expr
(Node
.Op2
);
510 -- Start of processing for Print_Expr
516 Print_Expr
(Node
.Op1
);
517 Write_Str
(" then ");
518 Print_Expr
(Node
.Op2
);
519 Write_Str
(" else ");
520 Print_Expr
(Node
.Op3
);
532 when Trunc_Div_Expr
=>
535 when Ceil_Div_Expr
=>
538 when Floor_Div_Expr
=>
541 when Trunc_Mod_Expr
=>
544 when Floor_Mod_Expr
=>
547 when Ceil_Mod_Expr
=>
550 when Exact_Div_Expr
=>
555 Print_Expr
(Node
.Op1
);
565 Print_Expr
(Node
.Op1
);
567 when Truth_Andif_Expr
=>
570 when Truth_Orif_Expr
=>
573 when Truth_And_Expr
=>
576 when Truth_Or_Expr
=>
579 when Truth_Xor_Expr
=>
582 when Truth_Not_Expr
=>
584 Print_Expr
(Node
.Op1
);
613 -- Start of processing for List_GCC_Expression
621 end List_GCC_Expression
;
623 ---------------------
624 -- List_Mechanisms --
625 ---------------------
627 procedure List_Mechanisms
(Ent
: Entity_Id
) is
636 Write_Str
("function ");
639 Write_Str
("operator ");
642 Write_Str
("procedure ");
644 when E_Subprogram_Type
=>
647 when E_Entry | E_Entry_Family
=>
648 Write_Str
("entry ");
654 Get_Unqualified_Decoded_Name_String
(Chars
(Ent
));
655 Write_Str
(Name_Buffer
(1 .. Name_Len
));
656 Write_Str
(" declared at ");
657 Write_Location
(Sloc
(Ent
));
660 Write_Str
(" convention : ");
662 case Convention
(Ent
) is
663 when Convention_Ada
=> Write_Line
("Ada");
664 when Convention_Intrinsic
=> Write_Line
("InLineinsic");
665 when Convention_Entry
=> Write_Line
("Entry");
666 when Convention_Protected
=> Write_Line
("Protected");
667 when Convention_Assembler
=> Write_Line
("Assembler");
668 when Convention_C
=> Write_Line
("C");
669 when Convention_COBOL
=> Write_Line
("COBOL");
670 when Convention_CPP
=> Write_Line
("C++");
671 when Convention_Fortran
=> Write_Line
("Fortran");
672 when Convention_Java
=> Write_Line
("Java");
673 when Convention_Stdcall
=> Write_Line
("Stdcall");
674 when Convention_Stubbed
=> Write_Line
("Stubbed");
677 -- Find max length of formal name
680 Form
:= First_Formal
(Ent
);
681 while Present
(Form
) loop
682 Get_Unqualified_Decoded_Name_String
(Chars
(Form
));
684 if Name_Len
> Plen
then
691 -- Output formals and mechanisms
693 Form
:= First_Formal
(Ent
);
694 while Present
(Form
) loop
695 Get_Unqualified_Decoded_Name_String
(Chars
(Form
));
697 while Name_Len
<= Plen
loop
698 Name_Len
:= Name_Len
+ 1;
699 Name_Buffer
(Name_Len
) := ' ';
703 Write_Str
(Name_Buffer
(1 .. Plen
+ 1));
704 Write_Str
(": passed by ");
706 Write_Mechanism
(Mechanism
(Form
));
711 if Etype
(Ent
) /= Standard_Void_Type
then
712 Write_Str
(" returns by ");
713 Write_Mechanism
(Mechanism
(Ent
));
722 procedure List_Name
(Ent
: Entity_Id
) is
724 if not Is_Compilation_Unit
(Scope
(Ent
)) then
725 List_Name
(Scope
(Ent
));
729 Get_Unqualified_Decoded_Name_String
(Chars
(Ent
));
730 Set_Casing
(Unit_Casing
);
731 Write_Str
(Name_Buffer
(1 .. Name_Len
));
734 ---------------------
735 -- List_Object_Info --
736 ---------------------
738 procedure List_Object_Info
(Ent
: Entity_Id
) is
744 Write_Str
("'Size use ");
745 Write_Val
(Esize
(Ent
));
750 Write_Str
("'Alignment use ");
751 Write_Val
(Alignment
(Ent
));
753 end List_Object_Info
;
755 ----------------------
756 -- List_Record_Info --
757 ----------------------
759 procedure List_Record_Info
(Ent
: Entity_Id
) is
764 Max_Name_Length
: Natural;
765 Max_Suni_Length
: Natural;
769 List_Type_Info
(Ent
);
773 Write_Line
(" use record");
775 -- First loop finds out max line length and max starting position
776 -- length, for the purpose of lining things up nicely.
778 Max_Name_Length
:= 0;
779 Max_Suni_Length
:= 0;
781 Comp
:= First_Entity
(Ent
);
782 while Present
(Comp
) loop
783 if Ekind
(Comp
) = E_Component
784 or else Ekind
(Comp
) = E_Discriminant
786 Get_Decoded_Name_String
(Chars
(Comp
));
787 Max_Name_Length
:= Natural'Max (Max_Name_Length
, Name_Len
);
789 Cfbit
:= Component_Bit_Offset
(Comp
);
791 if Rep_Not_Constant
(Cfbit
) then
792 UI_Image_Length
:= 2;
795 -- Complete annotation in case not done
797 Set_Normalized_Position
(Comp
, Cfbit
/ SSU
);
798 Set_Normalized_First_Bit
(Comp
, Cfbit
mod SSU
);
800 Sunit
:= Cfbit
/ SSU
;
804 -- If the record is not packed, then we know that all
805 -- fields whose position is not specified have a starting
806 -- normalized bit position of zero
808 if Unknown_Normalized_First_Bit
(Comp
)
809 and then not Is_Packed
(Ent
)
811 Set_Normalized_First_Bit
(Comp
, Uint_0
);
815 Natural'Max (Max_Suni_Length
, UI_Image_Length
);
818 Comp
:= Next_Entity
(Comp
);
821 -- Second loop does actual output based on those values
823 Comp
:= First_Entity
(Ent
);
824 while Present
(Comp
) loop
825 if Ekind
(Comp
) = E_Component
826 or else Ekind
(Comp
) = E_Discriminant
829 Esiz
: constant Uint
:= Esize
(Comp
);
830 Bofs
: constant Uint
:= Component_Bit_Offset
(Comp
);
831 Npos
: constant Uint
:= Normalized_Position
(Comp
);
832 Fbit
: constant Uint
:= Normalized_First_Bit
(Comp
);
837 Get_Decoded_Name_String
(Chars
(Comp
));
838 Set_Casing
(Unit_Casing
);
839 Write_Str
(Name_Buffer
(1 .. Name_Len
));
841 for J
in 1 .. Max_Name_Length
- Name_Len
loop
847 if Known_Static_Normalized_Position
(Comp
) then
849 Spaces
(Max_Suni_Length
- UI_Image_Length
);
850 Write_Str
(UI_Image_Buffer
(1 .. UI_Image_Length
));
852 elsif Known_Component_Bit_Offset
(Comp
)
853 and then List_Representation_Info
= 3
855 Spaces
(Max_Suni_Length
- 2);
856 Write_Str
("bit offset");
857 Write_Val
(Bofs
, Paren
=> True);
858 Write_Str
(" size in bits = ");
859 Write_Val
(Esiz
, Paren
=> True);
863 elsif Known_Normalized_Position
(Comp
)
864 and then List_Representation_Info
= 3
866 Spaces
(Max_Suni_Length
- 2);
870 -- For the packed case, we don't know the bit positions
871 -- if we don't know the starting position!
873 if Is_Packed
(Ent
) then
874 Write_Line
("?? range ? .. ??;");
877 -- Otherwise we can continue
884 Write_Str
(" range ");
888 -- Allowing Uint_0 here is a kludge, really this should be
889 -- a fine Esize value but currently it means unknown, except
890 -- that we know after gigi has back annotated that a size of
891 -- zero is real, since otherwise gigi back annotates using
892 -- No_Uint as the value to indicate unknown).
894 if (Esize
(Comp
) = Uint_0
or else Known_Static_Esize
(Comp
))
895 and then Known_Static_Normalized_First_Bit
(Comp
)
897 Lbit
:= Fbit
+ Esiz
- 1;
905 -- The test for Esize (Comp) not being Uint_0 here is a kludge.
906 -- Officially a value of zero for Esize means unknown, but here
907 -- we use the fact that we know that gigi annotates Esize with
908 -- No_Uint, not Uint_0. Really everyone should use No_Uint???
910 elsif List_Representation_Info
< 3
911 or else (Esize
(Comp
) /= Uint_0
and then Unknown_Esize
(Comp
))
915 else -- List_Representation >= 3 and Known_Esize (Comp)
917 Write_Val
(Esiz
, Paren
=> True);
919 -- If in front end layout mode, then dynamic size is
920 -- stored in storage units, so renormalize for output
922 if not Back_End_Layout
then
927 -- Add appropriate first bit offset
937 Write_Int
(UI_To_Int
(Fbit
) - 1);
946 Comp
:= Next_Entity
(Comp
);
949 Write_Line
("end record;");
950 end List_Record_Info
;
956 procedure List_Rep_Info
is
960 if List_Representation_Info
/= 0
961 or else List_Representation_Info_Mechanisms
963 for U
in Main_Unit
.. Last_Unit
loop
964 if In_Extended_Main_Source_Unit
(Cunit_Entity
(U
)) then
966 -- Normal case, list to standard output
968 if not List_Representation_Info_To_File
then
969 Unit_Casing
:= Identifier_Casing
(Source_Index
(U
));
971 Write_Str
("Representation information for unit ");
972 Write_Unit_Name
(Unit_Name
(U
));
976 for J
in 1 .. Col
- 1 loop
981 List_Entities
(Cunit_Entity
(U
));
983 -- List representation information to file
986 Creat_Repinfo_File_Access
.all (File_Name
(Source_Index
(U
)));
987 Set_Special_Output
(Write_Info_Line
'Access);
988 List_Entities
(Cunit_Entity
(U
));
989 Set_Special_Output
(null);
990 Close_Repinfo_File_Access
.all;
1001 procedure List_Type_Info
(Ent
: Entity_Id
) is
1005 -- Do not list size info for unconstrained arrays, not meaningful
1007 if Is_Array_Type
(Ent
) and then not Is_Constrained
(Ent
) then
1011 -- If Esize and RM_Size are the same and known, list as Size. This
1012 -- is a common case, which we may as well list in simple form.
1014 if Esize
(Ent
) = RM_Size
(Ent
) then
1017 Write_Str
("'Size use ");
1018 Write_Val
(Esize
(Ent
));
1021 -- For now, temporary case, to be removed when gigi properly back
1022 -- annotates RM_Size, if RM_Size is not set, then list Esize as
1023 -- Size. This avoids odd Object_Size output till we fix things???
1025 elsif Unknown_RM_Size
(Ent
) then
1028 Write_Str
("'Size use ");
1029 Write_Val
(Esize
(Ent
));
1032 -- Otherwise list size values separately if they are set
1037 Write_Str
("'Object_Size use ");
1038 Write_Val
(Esize
(Ent
));
1041 -- Note on following check: The RM_Size of a discrete type can
1042 -- legitimately be set to zero, so a special check is needed.
1046 Write_Str
("'Value_Size use ");
1047 Write_Val
(RM_Size
(Ent
));
1054 Write_Str
("'Alignment use ");
1055 Write_Val
(Alignment
(Ent
));
1059 ----------------------
1060 -- Rep_Not_Constant --
1061 ----------------------
1063 function Rep_Not_Constant
(Val
: Node_Ref_Or_Val
) return Boolean is
1065 if Val
= No_Uint
or else Val
< 0 then
1070 end Rep_Not_Constant
;
1077 (Val
: Node_Ref_Or_Val
;
1078 D
: Discrim_List
) return Uint
1080 function B
(Val
: Boolean) return Uint
;
1081 -- Returns Uint_0 for False, Uint_1 for True
1083 function T
(Val
: Node_Ref_Or_Val
) return Boolean;
1084 -- Returns True for 0, False for any non-zero (i.e. True)
1086 function V
(Val
: Node_Ref_Or_Val
) return Uint
;
1087 -- Internal recursive routine to evaluate tree
1093 function B
(Val
: Boolean) return Uint
is
1106 function T
(Val
: Node_Ref_Or_Val
) return Boolean is
1119 function V
(Val
: Node_Ref_Or_Val
) return Uint
is
1128 Node
: Exp_Node
renames Rep_Table
.Table
(-UI_To_Int
(Val
));
1133 if T
(Node
.Op1
) then
1134 return V
(Node
.Op2
);
1136 return V
(Node
.Op3
);
1140 return V
(Node
.Op1
) + V
(Node
.Op2
);
1143 return V
(Node
.Op1
) - V
(Node
.Op2
);
1146 return V
(Node
.Op1
) * V
(Node
.Op2
);
1148 when Trunc_Div_Expr
=>
1149 return V
(Node
.Op1
) / V
(Node
.Op2
);
1151 when Ceil_Div_Expr
=>
1154 (V
(Node
.Op1
) / UR_From_Uint
(V
(Node
.Op2
)));
1156 when Floor_Div_Expr
=>
1159 (V
(Node
.Op1
) / UR_From_Uint
(V
(Node
.Op2
)));
1161 when Trunc_Mod_Expr
=>
1162 return V
(Node
.Op1
) rem V
(Node
.Op2
);
1164 when Floor_Mod_Expr
=>
1165 return V
(Node
.Op1
) mod V
(Node
.Op2
);
1167 when Ceil_Mod_Expr
=>
1170 Q
:= UR_Ceiling
(L
/ UR_From_Uint
(R
));
1173 when Exact_Div_Expr
=>
1174 return V
(Node
.Op1
) / V
(Node
.Op2
);
1177 return -V
(Node
.Op1
);
1180 return UI_Min
(V
(Node
.Op1
), V
(Node
.Op2
));
1183 return UI_Max
(V
(Node
.Op1
), V
(Node
.Op2
));
1186 return UI_Abs
(V
(Node
.Op1
));
1188 when Truth_Andif_Expr
=>
1189 return B
(T
(Node
.Op1
) and then T
(Node
.Op2
));
1191 when Truth_Orif_Expr
=>
1192 return B
(T
(Node
.Op1
) or else T
(Node
.Op2
));
1194 when Truth_And_Expr
=>
1195 return B
(T
(Node
.Op1
) and T
(Node
.Op2
));
1197 when Truth_Or_Expr
=>
1198 return B
(T
(Node
.Op1
) or T
(Node
.Op2
));
1200 when Truth_Xor_Expr
=>
1201 return B
(T
(Node
.Op1
) xor T
(Node
.Op2
));
1203 when Truth_Not_Expr
=>
1204 return B
(not T
(Node
.Op1
));
1207 return B
(V
(Node
.Op1
) < V
(Node
.Op2
));
1210 return B
(V
(Node
.Op1
) <= V
(Node
.Op2
));
1213 return B
(V
(Node
.Op1
) > V
(Node
.Op2
));
1216 return B
(V
(Node
.Op1
) >= V
(Node
.Op2
));
1219 return B
(V
(Node
.Op1
) = V
(Node
.Op2
));
1222 return B
(V
(Node
.Op1
) /= V
(Node
.Op2
));
1226 Sub
: constant Int
:= UI_To_Int
(Node
.Op1
);
1229 pragma Assert
(Sub
in D
'Range);
1238 -- Start of processing for Rep_Value
1241 if Val
= No_Uint
then
1253 procedure Spaces
(N
: Natural) is
1255 for J
in 1 .. N
loop
1264 procedure Tree_Read
is
1266 Rep_Table
.Tree_Read
;
1273 procedure Tree_Write
is
1275 Rep_Table
.Tree_Write
;
1278 ---------------------
1279 -- Write_Info_Line --
1280 ---------------------
1282 procedure Write_Info_Line
(S
: String) is
1284 Write_Repinfo_Line_Access
.all (S
(S
'First .. S
'Last - 1));
1285 end Write_Info_Line
;
1287 ---------------------
1288 -- Write_Mechanism --
1289 ---------------------
1291 procedure Write_Mechanism
(M
: Mechanism_Type
) is
1295 Write_Str
("default");
1301 Write_Str
("reference");
1304 Write_Str
("descriptor");
1307 Write_Str
("descriptor (UBS)");
1310 Write_Str
("descriptor (UBSB)");
1313 Write_Str
("descriptor (UBA)");
1316 Write_Str
("descriptor (S)");
1319 Write_Str
("descriptor (SB)");
1322 Write_Str
("descriptor (A)");
1325 Write_Str
("descriptor (NCA)");
1328 raise Program_Error
;
1330 end Write_Mechanism
;
1336 procedure Write_Val
(Val
: Node_Ref_Or_Val
; Paren
: Boolean := False) is
1338 if Rep_Not_Constant
(Val
) then
1339 if List_Representation_Info
< 3 or else Val
= No_Uint
then
1343 if Back_End_Layout
then
1348 List_GCC_Expression
(Val
);
1351 List_GCC_Expression
(Val
);
1359 Write_Name_Decoded
(Chars
(Get_Dynamic_SO_Entity
(Val
)));
1362 Write_Name_Decoded
(Chars
(Get_Dynamic_SO_Entity
(Val
)));