1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- G E N _ I L . U T I L S --
9 -- Copyright (C) 2020-2021, 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 ------------------------------------------------------------------------------
26 package body Gen_IL
.Internals
is
32 procedure Nil
(T
: Node_Or_Entity_Type
) is
41 function Node_Or_Entity
(Root
: Root_Type
) return String is
43 if Root
= Node_Kind
then
50 ------------------------------
51 -- Num_Concrete_Descendants --
52 ------------------------------
54 function Num_Concrete_Descendants
55 (T
: Node_Or_Entity_Type
) return Natural is
57 return Concrete_Type
'Pos (Type_Table
(T
).Last
) -
58 Concrete_Type
'Pos (Type_Table
(T
).First
) + 1;
59 end Num_Concrete_Descendants
;
61 function First_Abstract
(Root
: Root_Type
) return Abstract_Type
is
63 when Node_Kind
=> Abstract_Node
'First,
64 when others => Abstract_Entity
'First); -- Entity_Kind
65 function Last_Abstract
(Root
: Root_Type
) return Abstract_Type
is
67 when Node_Kind
=> Abstract_Node
'Last,
68 when others => Abstract_Entity
'Last); -- Entity_Kind
70 function First_Concrete
(Root
: Root_Type
) return Concrete_Type
is
72 when Node_Kind
=> Concrete_Node
'First,
73 when others => Concrete_Entity
'First); -- Entity_Kind
74 function Last_Concrete
(Root
: Root_Type
) return Concrete_Type
is
76 when Node_Kind
=> Concrete_Node
'Last,
77 when others => Concrete_Entity
'Last); -- Entity_Kind
79 function First_Field
(Root
: Root_Type
) return Field_Enum
is
81 when Node_Kind
=> Node_Field
'First,
82 when others => Entity_Field
'First); -- Entity_Kind
83 function Last_Field
(Root
: Root_Type
) return Field_Enum
is
85 when Node_Kind
=> Node_Field
'Last,
86 when others => Entity_Field
'Last); -- Entity_Kind
88 -----------------------
89 -- Verify_Type_Table --
90 -----------------------
92 procedure Verify_Type_Table
is
94 for T
in Node_Or_Entity_Type
loop
95 if Type_Table
(T
) /= null then
96 if not Type_Table
(T
).Is_Union
then
98 when Concrete_Node | Concrete_Entity
=>
99 pragma Assert
(Type_Table
(T
).First
= T
);
100 pragma Assert
(Type_Table
(T
).Last
= T
);
102 when Abstract_Node | Abstract_Entity
=>
104 (Type_Table
(T
).First
< Type_Table
(T
).Last
);
106 when Type_Boundaries
=>
112 end Verify_Type_Table
;
118 function Id_Image
(T
: Type_Enum
) return String is
127 when Node_Kind_Type
=>
129 when Entity_Kind_Type
=>
130 return "Entity_Kind";
132 return Image
(T
) & "_Id";
136 ----------------------
137 -- Get_Set_Id_Image --
138 ----------------------
140 function Get_Set_Id_Image
(T
: Type_Enum
) return String is
147 when Node_Kind_Type
=>
149 when Entity_Kind_Type
=>
150 return "Entity_Kind";
154 end Get_Set_Id_Image
;
160 function Image
(T
: Opt_Type_Enum
) return String is
163 -- We special case the following; otherwise the compiler will give
164 -- "wrong case" warnings in compiler code.
166 when N_Pop_xxx_Label
=>
167 return "N_Pop_xxx_Label";
169 when N_Push_Pop_xxx_Label
=>
170 return "N_Push_Pop_xxx_Label";
172 when N_Push_xxx_Label
=>
173 return "N_Push_xxx_Label";
175 when N_Raise_xxx_Error
=>
176 return "N_Raise_xxx_Error";
179 return "N_SCIL_Node";
181 when N_SCIL_Dispatch_Table_Tag_Init
=>
182 return "N_SCIL_Dispatch_Table_Tag_Init";
184 when N_SCIL_Dispatching_Call
=>
185 return "N_SCIL_Dispatching_Call";
187 when N_SCIL_Membership_Test
=>
188 return "N_SCIL_Membership_Test";
191 return Capitalize
(T
'Img);
199 function Image_Sans_N
(T
: Opt_Type_Enum
) return String is
200 Im
: constant String := Image
(T
);
201 pragma Assert
(Im
(1 .. 2) = "N_");
203 return Im
(3 .. Im
'Last);
206 -------------------------
207 -- Put_Types_With_Bars --
208 -------------------------
210 procedure Put_Types_With_Bars
(S
: in out Sink
; U
: Type_Vector
) is
211 First_Time
: Boolean := True;
213 Increase_Indent
(S
, 3);
225 Decrease_Indent
(S
, 3);
226 end Put_Types_With_Bars
;
228 ----------------------------
229 -- Put_Type_Ids_With_Bars --
230 ----------------------------
232 procedure Put_Type_Ids_With_Bars
(S
: in out Sink
; U
: Type_Vector
) is
233 First_Time
: Boolean := True;
235 Increase_Indent
(S
, 3);
244 Put
(S
, Id_Image
(T
));
247 Decrease_Indent
(S
, 3);
248 end Put_Type_Ids_With_Bars
;
254 function Image
(F
: Opt_Field_Enum
) return String is
257 -- Special cases for the same reason as in the above Image
258 -- function for Opt_Type_Enum.
260 when Alloc_For_BIP_Return
=>
261 return "Alloc_For_BIP_Return";
262 when Assignment_OK
=>
263 return "Assignment_OK";
265 return "Backwards_OK";
266 when BIP_Initialization_Call
=>
267 return "BIP_Initialization_Call";
268 when Body_Needed_For_SAL
=>
269 return "Body_Needed_For_SAL";
270 when Conversion_OK
=>
271 return "Conversion_OK";
272 when CR_Discriminant
=>
273 return "CR_Discriminant";
276 when DT_Entry_Count
=>
277 return "DT_Entry_Count";
278 when DT_Offset_To_Top_Func
=>
279 return "DT_Offset_To_Top_Func";
281 return "DT_Position";
283 return "Forwards_OK";
284 when Has_Inherited_DIC
=>
285 return "Has_Inherited_DIC";
287 return "Has_Own_DIC";
290 when Has_SP_Choice
=>
291 return "Has_SP_Choice";
292 when Ignore_SPARK_Mode_Pragmas
=>
293 return "Ignore_SPARK_Mode_Pragmas";
294 when Is_Constr_Subt_For_UN_Aliased
=>
295 return "Is_Constr_Subt_For_UN_Aliased";
297 return "Is_CPP_Class";
298 when Is_CUDA_Kernel
=>
299 return "Is_CUDA_Kernel";
300 when Is_DIC_Procedure
=>
301 return "Is_DIC_Procedure";
302 when Is_Discrim_SO_Function
=>
303 return "Is_Discrim_SO_Function";
304 when Is_Elaboration_Checks_OK_Id
=>
305 return "Is_Elaboration_Checks_OK_Id";
306 when Is_Elaboration_Checks_OK_Node
=>
307 return "Is_Elaboration_Checks_OK_Node";
308 when Is_Elaboration_Warnings_OK_Id
=>
309 return "Is_Elaboration_Warnings_OK_Id";
310 when Is_Elaboration_Warnings_OK_Node
=>
311 return "Is_Elaboration_Warnings_OK_Node";
312 when Is_Known_Guaranteed_ABE
=>
313 return "Is_Known_Guaranteed_ABE";
314 when Is_RACW_Stub_Type
=>
315 return "Is_RACW_Stub_Type";
316 when Is_SPARK_Mode_On_Node
=>
317 return "Is_SPARK_Mode_On_Node";
318 when Local_Raise_Not_OK
=>
319 return "Local_Raise_Not_OK";
320 when LSP_Subprogram
=>
321 return "LSP_Subprogram";
323 return "OK_To_Rename";
324 when Referenced_As_LHS
=>
325 return "Referenced_As_LHS";
328 when SCIL_Controlling_Tag
=>
329 return "SCIL_Controlling_Tag";
331 return "SCIL_Entity";
332 when SCIL_Tag_Value
=>
333 return "SCIL_Tag_Value";
334 when SCIL_Target_Prim
=>
335 return "SCIL_Target_Prim";
336 when Shift_Count_OK
=>
337 return "Shift_Count_OK";
338 when SPARK_Aux_Pragma
=>
339 return "SPARK_Aux_Pragma";
340 when SPARK_Aux_Pragma_Inherited
=>
341 return "SPARK_Aux_Pragma_Inherited";
343 return "SPARK_Pragma";
344 when SPARK_Pragma_Inherited
=>
345 return "SPARK_Pragma_Inherited";
348 when SSO_Set_High_By_Default
=>
349 return "SSO_Set_High_By_Default";
350 when SSO_Set_Low_By_Default
=>
351 return "SSO_Set_Low_By_Default";
356 return Capitalize
(F
'Img);
360 function Image
(Default
: Field_Default_Value
) return String is
361 (Capitalize
(Default
'Img));
367 function Value_Image
(Default
: Field_Default_Value
) return String is
369 if Default
= No_Default
then
370 return Image
(Default
);
373 -- Strip off the prefix
376 Im
: constant String := Image
(Default
);
377 Prefix
: constant String := "Default_";
379 pragma Assert
(Im
(1 .. Prefix
'Length) = Prefix
);
380 return Im
(Prefix
'Length + 1 .. Im
'Last);
389 procedure Iterate_Types
390 (Root
: Node_Or_Entity_Type
;
391 Pre
, Post
: not null access procedure (T
: Node_Or_Entity_Type
) :=
394 procedure Recursive
(T
: Node_Or_Entity_Type
);
397 procedure Recursive
(T
: Node_Or_Entity_Type
) is
401 for Child
of Type_Table
(T
).Children
loop
416 function Is_Descendant
(Ancestor
, Descendant
: Node_Or_Entity_Type
)
419 if Ancestor
= Descendant
then
422 elsif Descendant
in Root_Type
then
426 return Is_Descendant
(Ancestor
, Type_Table
(Descendant
).Parent
);
430 ------------------------
431 -- Put_Type_Hierarchy --
432 ------------------------
434 procedure Put_Type_Hierarchy
(S
: in out Sink
; Root
: Root_Type
) is
435 Level
: Natural := 0;
437 function Indentation
return String is ((1 .. 3 * Level
=> ' '));
438 -- Indentation string of space characters. We can't use the Indent
439 -- primitive, because we want this indentation after the "--".
441 procedure Pre
(T
: Node_Or_Entity_Type
);
442 procedure Post
(T
: Node_Or_Entity_Type
);
443 -- Pre and Post actions passed to Iterate_Types
445 procedure Pre
(T
: Node_Or_Entity_Type
) is
447 Put
(S
, "-- " & Indentation
& Image
(T
) & LF
);
451 procedure Post
(T
: Node_Or_Entity_Type
) is
455 -- Put out an "end" line only if there are many descendants, for
456 -- an arbitrary definition of "many".
458 if Num_Concrete_Descendants
(T
) > 10 then
459 Put
(S
, "-- " & Indentation
& "end " & Image
(T
) & LF
);
463 N_Or_E
: constant String :=
465 when Node_Kind
=> "nodes",
466 when others => "entities"); -- Entity_Kind
468 -- Start of processing for Put_Type_Hierarchy
471 Put
(S
, "-- Type hierarchy for " & N_Or_E
& LF
);
474 Iterate_Types
(Root
, Pre
'Access, Post
'Access);
477 Put
(S
, "-- End type hierarchy for " & N_Or_E
& LF
& LF
);
478 end Put_Type_Hierarchy
;
480 end Gen_IL
.Internals
;