]> gcc.gnu.org Git - gcc.git/blame - gcc/ada/treepr.adb
[Ada] Find an interpretation for membership test with a singleton value
[gcc.git] / gcc / ada / treepr.adb
CommitLineData
415dddc8
RK
1------------------------------------------------------------------------------
2-- --
3-- GNAT COMPILER COMPONENTS --
4-- --
5-- T R E E P R --
6-- --
7-- B o d y --
8-- --
8d0d46f4 9-- Copyright (C) 1992-2021, Free Software Foundation, Inc. --
415dddc8
RK
10-- --
11-- GNAT is free software; you can redistribute it and/or modify it under --
12-- terms of the GNU General Public License as published by the Free Soft- --
b5c84c3c 13-- ware Foundation; either version 3, or (at your option) any later ver- --
415dddc8
RK
14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
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 --
b5c84c3c
RD
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. --
415dddc8
RK
20-- --
21-- GNAT was originally developed by the GNAT team at New York University. --
71ff80dc 22-- Extensive contributions were provided by Ada Core Technologies Inc. --
415dddc8
RK
23-- --
24------------------------------------------------------------------------------
25
104f58db
BD
26with Aspects; use Aspects;
27with Atree; use Atree;
28with Csets; use Csets;
29with Debug; use Debug;
30with Einfo; use Einfo;
76f9c7f4 31with Einfo.Entities; use Einfo.Entities;
104f58db
BD
32with Einfo.Utils; use Einfo.Utils;
33with Elists; use Elists;
34with Lib; use Lib;
35with Namet; use Namet;
36with Nlists; use Nlists;
37with Output; use Output;
38with Seinfo; use Seinfo;
39with Sinfo; use Sinfo;
40with Sinfo.Nodes; use Sinfo.Nodes;
41with Sinfo.Utils; use Sinfo.Utils;
42with Snames; use Snames;
43with Sinput; use Sinput;
44with Stand; use Stand;
45with Stringt; use Stringt;
46with SCIL_LL; use SCIL_LL;
47with Uintp; use Uintp;
48with Urealp; use Urealp;
49with Uname; use Uname;
76f9c7f4 50with Unchecked_Conversion;
415dddc8
RK
51with Unchecked_Deallocation;
52
53package body Treepr is
54
415dddc8
RK
55 ----------------------------------
56 -- Approach Used for Tree Print --
57 ----------------------------------
58
59 -- When a complete subtree is being printed, a trace phase first marks
60 -- the nodes and lists to be printed. This trace phase allocates logical
61 -- numbers corresponding to the order in which the nodes and lists will
62 -- be printed. The Node_Id, List_Id and Elist_Id values are mapped to
63 -- logical node numbers using a hash table. Output is done using a set
64 -- of Print_xxx routines, which are similar to the Write_xxx routines
65 -- with the same name, except that they do not generate any output in
66 -- the marking phase. This allows identical logic to be used in the
67 -- two phases.
68
69 -- Note that the hash table not only holds the serial numbers, but also
70 -- acts as a record of which nodes have already been visited. In the
71 -- marking phase, a node has been visited if it is already in the hash
72 -- table, and in the printing phase, we can tell whether a node has
73 -- already been printed by looking at the value of the serial number.
74
75 ----------------------
76 -- Global Variables --
77 ----------------------
78
a7cadd18 79 Print_Low_Level_Info : Boolean := False with Warnings => Off;
76f9c7f4
BD
80 -- Set True to print low-level information useful for debugging Atree and
81 -- the like.
82
415dddc8
RK
83 type Hash_Record is record
84 Serial : Nat;
85 -- Serial number for hash table entry. A value of zero means that
86 -- the entry is currently unused.
87
88 Id : Int;
89 -- If serial number field is non-zero, contains corresponding Id value
90 end record;
91
92 type Hash_Table_Type is array (Nat range <>) of Hash_Record;
93 type Access_Hash_Table_Type is access Hash_Table_Type;
94 Hash_Table : Access_Hash_Table_Type;
95 -- The hash table itself, see Serial_Number function for details of use
96
97 Hash_Table_Len : Nat;
98 -- Range of Hash_Table is from 0 .. Hash_Table_Len - 1 so that dividing
99 -- by Hash_Table_Len gives a remainder that is in Hash_Table'Range.
100
101 Next_Serial_Number : Nat;
102 -- Number of last visited node or list. Used during the marking phase to
103 -- set proper node numbers in the hash table, and during the printing
104 -- phase to make sure that a given node is not printed more than once.
105 -- (nodes are printed in order during the printing phase, that's the
a90bd866 106 -- point of numbering them in the first place).
415dddc8
RK
107
108 Printing_Descendants : Boolean;
109 -- True if descendants are being printed, False if not. In the false case,
110 -- only node Id's are printed. In the true case, node numbers as well as
111 -- node Id's are printed, as described above.
112
113 type Phase_Type is (Marking, Printing);
114 -- Type for Phase variable
115
116 Phase : Phase_Type;
117 -- When an entire tree is being printed, the traversal operates in two
118 -- phases. The first phase marks the nodes in use by installing node
119 -- numbers in the node number table. The second phase prints the nodes.
120 -- This variable indicates the current phase.
121
122 ----------------------
123 -- Local Procedures --
124 ----------------------
125
76f9c7f4
BD
126 function From_Union is new Unchecked_Conversion (Union_Id, Uint);
127 function From_Union is new Unchecked_Conversion (Union_Id, Ureal);
128
76f9c7f4
BD
129 function Capitalize (S : String) return String;
130 procedure Capitalize (S : in out String);
131 -- Turns an identifier into Mixed_Case
132
99e30ba8 133 function Image (F : Node_Or_Entity_Field) return String;
415dddc8
RK
134
135 procedure Print_Init;
d9d25d04 136 -- Initialize for printing of tree with descendants
415dddc8 137
a7cadd18
BD
138 procedure Print_End_Span (N : Node_Id);
139 -- Print contents of End_Span field of node N. The format includes the
140 -- implicit source location as well as the value of the field.
141
415dddc8 142 procedure Print_Term;
d9d25d04 143 -- Clean up after printing of tree with descendants
415dddc8
RK
144
145 procedure Print_Char (C : Character);
146 -- Print character C if currently in print phase, noop if in marking phase
147
148 procedure Print_Name (N : Name_Id);
149 -- Print name from names table if currently in print phase, noop if in
150 -- marking phase. Note that the name is output in mixed case mode.
151
ee1a7572
AC
152 procedure Print_Node_Header (N : Node_Id);
153 -- Print header line used by Print_Node and Print_Node_Briefly
154
415dddc8
RK
155 procedure Print_Node_Kind (N : Node_Id);
156 -- Print node kind name in mixed case if in print phase, noop if in
157 -- marking phase.
158
159 procedure Print_Str (S : String);
160 -- Print string S if currently in print phase, noop if in marking phase
161
162 procedure Print_Str_Mixed_Case (S : String);
163 -- Like Print_Str, except that the string is printed in mixed case mode
164
165 procedure Print_Int (I : Int);
166 -- Print integer I if currently in print phase, noop if in marking phase
167
168 procedure Print_Eol;
169 -- Print end of line if currently in print phase, noop if in marking phase
170
171 procedure Print_Node_Ref (N : Node_Id);
172 -- Print "<empty>", "<error>" or "Node #nnn" with additional information
173 -- in the latter case, including the Id and the Nkind of the node.
174
175 procedure Print_List_Ref (L : List_Id);
176 -- Print "<no list>", or "<empty node list>" or "Node list #nnn"
177
178 procedure Print_Elist_Ref (E : Elist_Id);
179 -- Print "<no elist>", or "<empty element list>" or "Element list #nnn"
180
181 procedure Print_Entity_Info (Ent : Entity_Id; Prefix : String);
182 -- Called if the node being printed is an entity. Prints fields from the
183 -- extension, using routines in Einfo to get the field names and flags.
184
185 procedure Print_Field (Val : Union_Id; Format : UI_Format := Auto);
76f9c7f4
BD
186 procedure Print_Field
187 (Prefix : String;
a7cadd18
BD
188 Field : String;
189 N : Node_Or_Entity_Id;
190 FD : Field_Descriptor;
76f9c7f4 191 Format : UI_Format);
415dddc8
RK
192 -- Print representation of Field value (name, tree, string, uint, charcode)
193 -- The format parameter controls the format of printing in the case of an
a7cadd18 194 -- integer value (see UI_Write for details).
76f9c7f4
BD
195
196 procedure Print_Node_Field
197 (Prefix : String;
a7cadd18
BD
198 Field : Node_Field;
199 N : Node_Id;
200 FD : Field_Descriptor;
76f9c7f4
BD
201 Format : UI_Format := Auto);
202
203 procedure Print_Entity_Field
204 (Prefix : String;
a7cadd18
BD
205 Field : Entity_Field;
206 N : Entity_Id;
207 FD : Field_Descriptor;
76f9c7f4 208 Format : UI_Format := Auto);
415dddc8
RK
209
210 procedure Print_Flag (F : Boolean);
211 -- Print True or False
212
213 procedure Print_Node
214 (N : Node_Id;
215 Prefix_Str : String;
216 Prefix_Char : Character);
217 -- This is the internal routine used to print a single node. Each line of
218 -- output is preceded by Prefix_Str (which is used to set the indentation
219 -- level and the bars used to link list elements). In addition, for lines
220 -- other than the first, an additional character Prefix_Char is output.
221
222 function Serial_Number (Id : Int) return Nat;
223 -- Given a Node_Id, List_Id or Elist_Id, returns the previously assigned
224 -- serial number, or zero if no serial number has yet been assigned.
225
226 procedure Set_Serial_Number;
227 -- Can be called only immediately following a call to Serial_Number that
228 -- returned a value of zero. Causes the value of Next_Serial_Number to be
229 -- placed in the hash table (corresponding to the Id argument used in the
230 -- Serial_Number call), and increments Next_Serial_Number.
231
232 procedure Visit_Node
233 (N : Node_Id;
234 Prefix_Str : String;
235 Prefix_Char : Character);
d9d25d04 236 -- Called to process a single node in the case where descendants are to
415dddc8
RK
237 -- be printed before every line, and Prefix_Char added to all lines
238 -- except the header line for the node.
239
240 procedure Visit_List (L : List_Id; Prefix_Str : String);
d9d25d04 241 -- Visit_List is called to process a list in the case where descendants
415dddc8
RK
242 -- are to be printed. Prefix_Str is to be added to all printed lines.
243
244 procedure Visit_Elist (E : Elist_Id; Prefix_Str : String);
245 -- Visit_Elist is called to process an element list in the case where
d9d25d04 246 -- descendants are to be printed. Prefix_Str is to be added to all
415dddc8
RK
247 -- printed lines.
248
76f9c7f4
BD
249 ----------------
250 -- Capitalize --
251 ----------------
252
253 procedure Capitalize (S : in out String) is
254 Cap : Boolean := True;
255 begin
256 for J in S'Range loop
257 declare
258 Old : constant Character := S (J);
259 begin
260 if Cap then
261 S (J) := Fold_Upper (S (J));
262 else
263 S (J) := Fold_Lower (S (J));
264 end if;
265
266 Cap := Old = '_';
267 end;
268 end loop;
269 end Capitalize;
270
271 function Capitalize (S : String) return String is
272 begin
273 return Result : String (S'Range) := S do
274 Capitalize (Result);
275 end return;
276 end Capitalize;
277
278 -----------
279 -- Image --
280 -----------
281
99e30ba8 282 function Image (F : Node_Or_Entity_Field) return String is
76f9c7f4
BD
283 begin
284 case F is
f54fb769 285 when F_Alloc_For_BIP_Return =>
76f9c7f4 286 return "Alloc_For_BIP_Return";
f54fb769 287 when F_Assignment_OK =>
76f9c7f4 288 return "Assignment_OK";
f54fb769 289 when F_Backwards_OK =>
76f9c7f4 290 return "Backwards_OK";
f54fb769 291 when F_Conversion_OK =>
76f9c7f4 292 return "Conversion_OK";
f54fb769 293 when F_Forwards_OK =>
76f9c7f4 294 return "Forwards_OK";
f54fb769 295 when F_Has_SP_Choice =>
76f9c7f4 296 return "Has_SP_Choice";
f54fb769 297 when F_Is_Elaboration_Checks_OK_Node =>
76f9c7f4 298 return "Is_Elaboration_Checks_OK_Node";
f54fb769 299 when F_Is_Elaboration_Warnings_OK_Node =>
76f9c7f4 300 return "Is_Elaboration_Warnings_OK_Node";
f54fb769 301 when F_Is_Known_Guaranteed_ABE =>
76f9c7f4 302 return "Is_Known_Guaranteed_ABE";
f54fb769 303 when F_Is_SPARK_Mode_On_Node =>
76f9c7f4 304 return "Is_SPARK_Mode_On_Node";
f54fb769 305 when F_Local_Raise_Not_OK =>
76f9c7f4 306 return "Local_Raise_Not_OK";
f54fb769 307 when F_SCIL_Controlling_Tag =>
76f9c7f4 308 return "SCIL_Controlling_Tag";
f54fb769 309 when F_SCIL_Entity =>
76f9c7f4 310 return "SCIL_Entity";
f54fb769 311 when F_SCIL_Tag_Value =>
76f9c7f4 312 return "SCIL_Tag_Value";
f54fb769 313 when F_SCIL_Target_Prim =>
76f9c7f4 314 return "SCIL_Target_Prim";
f54fb769 315 when F_Shift_Count_OK =>
76f9c7f4 316 return "Shift_Count_OK";
f54fb769 317 when F_Split_PPC =>
76f9c7f4 318 return "Split_PPC";
f54fb769 319 when F_TSS_Elist =>
76f9c7f4
BD
320 return "TSS_Elist";
321
f54fb769 322 when F_BIP_Initialization_Call =>
76f9c7f4 323 return "BIP_Initialization_Call";
f54fb769 324 when F_Body_Needed_For_SAL =>
76f9c7f4 325 return "Body_Needed_For_SAL";
f54fb769 326 when F_CR_Discriminant =>
76f9c7f4 327 return "CR_Discriminant";
f54fb769 328 when F_DT_Entry_Count =>
76f9c7f4 329 return "DT_Entry_Count";
f54fb769 330 when F_DT_Offset_To_Top_Func =>
76f9c7f4 331 return "DT_Offset_To_Top_Func";
f54fb769 332 when F_DT_Position =>
76f9c7f4 333 return "DT_Position";
f54fb769 334 when F_DTC_Entity =>
76f9c7f4 335 return "DTC_Entity";
f54fb769 336 when F_Has_Inherited_DIC =>
76f9c7f4 337 return "Has_Inherited_DIC";
f54fb769 338 when F_Has_Own_DIC =>
76f9c7f4 339 return "Has_Own_DIC";
f54fb769 340 when F_Has_RACW =>
76f9c7f4 341 return "Has_RACW";
f54fb769 342 when F_Ignore_SPARK_Mode_Pragmas =>
76f9c7f4 343 return "Ignore_SPARK_Mode_Pragmas";
f54fb769 344 when F_Is_Constr_Subt_For_UN_Aliased =>
76f9c7f4 345 return "Is_Constr_Subt_For_UN_Aliased";
f54fb769 346 when F_Is_CPP_Class =>
76f9c7f4 347 return "Is_CPP_Class";
f54fb769 348 when F_Is_CUDA_Kernel =>
76f9c7f4 349 return "Is_CUDA_Kernel";
f54fb769 350 when F_Is_DIC_Procedure =>
76f9c7f4 351 return "Is_DIC_Procedure";
f54fb769 352 when F_Is_Discrim_SO_Function =>
76f9c7f4 353 return "Is_Discrim_SO_Function";
f54fb769 354 when F_Is_Elaboration_Checks_OK_Id =>
76f9c7f4 355 return "Is_Elaboration_Checks_OK_Id";
f54fb769 356 when F_Is_Elaboration_Warnings_OK_Id =>
76f9c7f4 357 return "Is_Elaboration_Warnings_OK_Id";
f54fb769 358 when F_Is_RACW_Stub_Type =>
76f9c7f4 359 return "Is_RACW_Stub_Type";
c37c13e1
JM
360 when F_LSP_Subprogram =>
361 return "LSP_Subprogram";
f54fb769 362 when F_OK_To_Rename =>
76f9c7f4 363 return "OK_To_Rename";
f54fb769 364 when F_Referenced_As_LHS =>
76f9c7f4 365 return "Referenced_As_LHS";
f54fb769 366 when F_RM_Size =>
76f9c7f4 367 return "RM_Size";
f54fb769 368 when F_SPARK_Aux_Pragma =>
76f9c7f4 369 return "SPARK_Aux_Pragma";
f54fb769 370 when F_SPARK_Aux_Pragma_Inherited =>
76f9c7f4 371 return "SPARK_Aux_Pragma_Inherited";
f54fb769 372 when F_SPARK_Pragma =>
76f9c7f4 373 return "SPARK_Pragma";
f54fb769 374 when F_SPARK_Pragma_Inherited =>
76f9c7f4 375 return "SPARK_Pragma_Inherited";
f54fb769 376 when F_SSO_Set_High_By_Default =>
76f9c7f4 377 return "SSO_Set_High_By_Default";
f54fb769 378 when F_SSO_Set_Low_By_Default =>
76f9c7f4
BD
379 return "SSO_Set_Low_By_Default";
380
381 when others =>
f54fb769
BD
382 declare
383 Result : constant String := Capitalize (F'Img);
384 begin
385 return Result (3 .. Result'Last); -- Remove "F_"
386 end;
76f9c7f4
BD
387 end case;
388 end Image;
389
88ff8916
AC
390 -------
391 -- p --
392 -------
393
394 function p (N : Union_Id) return Node_Or_Entity_Id is
395 begin
396 case N is
397 when List_Low_Bound .. List_High_Bound - 1 =>
398 return Nlists.Parent (List_Id (N));
399
400 when Node_Range =>
898edf75 401 return Parent (Node_Or_Entity_Id (N));
88ff8916
AC
402
403 when others =>
404 Write_Int (Int (N));
405 Write_Str (" is not a Node_Id or List_Id value");
406 Write_Eol;
407 return Empty;
408 end case;
409 end p;
410
1399d355
AC
411 ---------
412 -- par --
413 ---------
414
415 function par (N : Union_Id) return Node_Or_Entity_Id renames p;
416
a871b0aa
BD
417 procedure ppar (N : Union_Id) is
418 begin
419 if N /= Empty_List_Or_Node then
420 pp (N);
421 ppar (Union_Id (p (N)));
422 end if;
423 end ppar;
424
1399d355
AC
425 --------
426 -- pe --
427 --------
428
429 procedure pe (N : Union_Id) renames pn;
430
415dddc8 431 --------
07fc65c4 432 -- pl --
415dddc8
RK
433 --------
434
9b998381
RD
435 procedure pl (L : Int) is
436 Lid : Int;
437
415dddc8 438 begin
44b9c671
RK
439 Push_Output;
440 Set_Standard_Output;
441
9b998381
RD
442 if L < 0 then
443 Lid := L;
444
445 -- This is the case where we transform e.g. +36 to -99999936
446
447 else
448 if L <= 9 then
449 Lid := -(99999990 + L);
450 elsif L <= 99 then
451 Lid := -(99999900 + L);
452 elsif L <= 999 then
453 Lid := -(99999000 + L);
454 elsif L <= 9999 then
455 Lid := -(99990000 + L);
456 elsif L <= 99999 then
457 Lid := -(99900000 + L);
458 elsif L <= 999999 then
459 Lid := -(99000000 + L);
460 elsif L <= 9999999 then
461 Lid := -(90000000 + L);
462 else
463 Lid := -L;
464 end if;
465 end if;
466
467 -- Now output the list
468
469 Print_Tree_List (List_Id (Lid));
44b9c671 470 Pop_Output;
07fc65c4 471 end pl;
415dddc8
RK
472
473 --------
07fc65c4 474 -- pn --
415dddc8
RK
475 --------
476
57a8057a 477 procedure pn (N : Union_Id) is
415dddc8 478 begin
44b9c671
RK
479 Push_Output;
480 Set_Standard_Output;
481
57a8057a
AC
482 case N is
483 when List_Low_Bound .. List_High_Bound - 1 =>
484 pl (Int (N));
485 when Node_Range =>
486 Print_Tree_Node (Node_Id (N));
487 when Elist_Range =>
488 Print_Tree_Elist (Elist_Id (N));
489 when Elmt_Range =>
76264f60
AC
490 declare
491 Id : constant Elmt_Id := Elmt_Id (N);
492 begin
493 if No (Id) then
494 Write_Str ("No_Elmt");
495 Write_Eol;
496 else
497 Write_Str ("Elmt_Id --> ");
498 Print_Tree_Node (Node (Id));
499 end if;
500 end;
57a8057a
AC
501 when Names_Range =>
502 Namet.wn (Name_Id (N));
503 when Strings_Range =>
504 Write_String_Table_Entry (String_Id (N));
505 when Uint_Range =>
506 Uintp.pid (From_Union (N));
507 when Ureal_Range =>
508 Urealp.pr (From_Union (N));
509 when others =>
510 Write_Str ("Invalid Union_Id: ");
511 Write_Int (Int (N));
76264f60 512 Write_Eol;
57a8057a 513 end case;
44b9c671
RK
514
515 Pop_Output;
07fc65c4 516 end pn;
415dddc8 517
1399d355
AC
518 --------
519 -- pp --
520 --------
521
522 procedure pp (N : Union_Id) renames pn;
523
524 ---------
525 -- ppp --
526 ---------
527
528 procedure ppp (N : Union_Id) renames pt;
529
415dddc8
RK
530 ----------------
531 -- Print_Char --
532 ----------------
533
534 procedure Print_Char (C : Character) is
535 begin
536 if Phase = Printing then
537 Write_Char (C);
538 end if;
539 end Print_Char;
540
541 ---------------------
542 -- Print_Elist_Ref --
543 ---------------------
544
545 procedure Print_Elist_Ref (E : Elist_Id) is
546 begin
547 if Phase /= Printing then
548 return;
549 end if;
550
551 if E = No_Elist then
552 Write_Str ("<no elist>");
553
554 elsif Is_Empty_Elmt_List (E) then
555 Write_Str ("Empty elist, (Elist_Id=");
556 Write_Int (Int (E));
557 Write_Char (')');
558
559 else
560 Write_Str ("(Elist_Id=");
561 Write_Int (Int (E));
562 Write_Char (')');
563
564 if Printing_Descendants then
565 Write_Str (" #");
566 Write_Int (Serial_Number (Int (E)));
567 end if;
568 end if;
569 end Print_Elist_Ref;
570
571 -------------------------
572 -- Print_Elist_Subtree --
573 -------------------------
574
575 procedure Print_Elist_Subtree (E : Elist_Id) is
576 begin
577 Print_Init;
578
579 Next_Serial_Number := 1;
580 Phase := Marking;
581 Visit_Elist (E, "");
582
583 Next_Serial_Number := 1;
584 Phase := Printing;
585 Visit_Elist (E, "");
586
587 Print_Term;
588 end Print_Elist_Subtree;
589
a7cadd18
BD
590 --------------------
591 -- Print_End_Span --
592 --------------------
593
594 procedure Print_End_Span (N : Node_Id) is
595 Val : constant Uint := End_Span (N);
596
597 begin
598 UI_Write (Val);
599 Write_Str (" (Uint = ");
600 Write_Str (UI_Image (Val));
601 Write_Str (") ");
602
2175b50b 603 if Present (Val) then
a7cadd18
BD
604 Write_Location (End_Location (N));
605 end if;
606 end Print_End_Span;
607
415dddc8
RK
608 -----------------------
609 -- Print_Entity_Info --
610 -----------------------
611
612 procedure Print_Entity_Info (Ent : Entity_Id; Prefix : String) is
415dddc8
RK
613 begin
614 Print_Str (Prefix);
615 Print_Str ("Ekind = ");
616 Print_Str_Mixed_Case (Entity_Kind'Image (Ekind (Ent)));
617 Print_Eol;
618
619 Print_Str (Prefix);
620 Print_Str ("Etype = ");
621 Print_Node_Ref (Etype (Ent));
622 Print_Eol;
623
624 if Convention (Ent) /= Convention_Ada then
625 Print_Str (Prefix);
626 Print_Str ("Convention = ");
627
628 -- Print convention name skipping the Convention_ at the start
629
630 declare
631 S : constant String := Convention_Id'Image (Convention (Ent));
632
633 begin
634 Print_Str_Mixed_Case (S (12 .. S'Last));
635 Print_Eol;
636 end;
637 end if;
638
76f9c7f4 639 declare
a7cadd18
BD
640 Fields : Entity_Field_Array renames
641 Entity_Field_Table (Ekind (Ent)).all;
642 Should_Print : constant Entity_Field_Set :=
643 -- Set of fields that should be printed. False for fields that were
644 -- already printed above.
f54fb769
BD
645 (F_Ekind
646 | F_Basic_Convention => False, -- Convention was printed
a7cadd18 647 others => True);
76f9c7f4
BD
648 begin
649 -- Outer loop makes flags come out last
650
651 for Print_Flags in Boolean loop
a7cadd18 652 for Field_Index in Fields'Range loop
76f9c7f4
BD
653 declare
654 FD : Field_Descriptor renames
99e30ba8 655 Field_Descriptors (Fields (Field_Index));
76f9c7f4 656 begin
a7cadd18
BD
657 if Should_Print (Fields (Field_Index))
658 and then (FD.Kind = Flag_Field) = Print_Flags
659 then
76f9c7f4 660 Print_Entity_Field
a7cadd18 661 (Prefix, Fields (Field_Index), Ent, FD);
76f9c7f4
BD
662 end if;
663 end;
664 end loop;
665 end loop;
666 end;
667 end Print_Entity_Info;
165eab5f 668
76f9c7f4
BD
669 ---------------
670 -- Print_Eol --
671 ---------------
165eab5f 672
76f9c7f4
BD
673 procedure Print_Eol is
674 begin
675 if Phase = Printing then
676 Write_Eol;
165eab5f 677 end if;
76f9c7f4 678 end Print_Eol;
165eab5f 679
76f9c7f4
BD
680 -----------------
681 -- Print_Field --
682 -----------------
e2cc5258 683
76f9c7f4
BD
684 -- Instantiations of low-level getters and setters that take offsets
685 -- in units of the size of the field.
e606088a 686
76f9c7f4 687 use Atree.Atree_Private_Part;
477cfc5b 688
76f9c7f4
BD
689 function Get_Flag is new Get_1_Bit_Field
690 (Boolean) with Inline;
477cfc5b 691
76f9c7f4
BD
692 function Get_Node_Id is new Get_32_Bit_Field
693 (Node_Id) with Inline;
477cfc5b 694
76f9c7f4
BD
695 function Get_List_Id is new Get_32_Bit_Field
696 (List_Id) with Inline;
477cfc5b 697
76f9c7f4
BD
698 function Get_Elist_Id is new Get_32_Bit_Field_With_Default
699 (Elist_Id, No_Elist) with Inline;
477cfc5b 700
76f9c7f4
BD
701 function Get_Name_Id is new Get_32_Bit_Field
702 (Name_Id) with Inline;
477cfc5b 703
76f9c7f4
BD
704 function Get_String_Id is new Get_32_Bit_Field
705 (String_Id) with Inline;
caf07df9 706
76f9c7f4
BD
707 function Get_Uint is new Get_32_Bit_Field_With_Default
708 (Uint, Uint_0) with Inline;
caf07df9 709
0c8ff35e
BD
710 function Get_Valid_Uint is new Get_32_Bit_Field
711 (Uint) with Inline;
712 -- Used for both Valid_Uint and other subtypes of Uint. Note that we don't
713 -- instantiate Get_Valid_32_Bit_Field; we don't want to blow up if the
714 -- value is wrong.
715
76f9c7f4
BD
716 function Get_Ureal is new Get_32_Bit_Field
717 (Ureal) with Inline;
caf07df9 718
a7cadd18 719 function Get_Node_Kind_Type is new Get_8_Bit_Field
76f9c7f4 720 (Node_Kind) with Inline;
caf07df9 721
a7cadd18 722 function Get_Entity_Kind_Type is new Get_8_Bit_Field
76f9c7f4 723 (Entity_Kind) with Inline;
caf07df9 724
76f9c7f4
BD
725 function Get_Source_Ptr is new Get_32_Bit_Field
726 (Source_Ptr) with Inline, Unreferenced;
caf07df9 727
76f9c7f4
BD
728 function Get_Small_Paren_Count_Type is new Get_2_Bit_Field
729 (Small_Paren_Count_Type) with Inline, Unreferenced;
415dddc8 730
76f9c7f4
BD
731 function Get_Union_Id is new Get_32_Bit_Field
732 (Union_Id) with Inline;
415dddc8 733
76f9c7f4
BD
734 function Get_Convention_Id is new Get_8_Bit_Field
735 (Convention_Id) with Inline, Unreferenced;
415dddc8 736
76f9c7f4
BD
737 function Get_Mechanism_Type is new Get_32_Bit_Field
738 (Mechanism_Type) with Inline, Unreferenced;
415dddc8
RK
739
740 procedure Print_Field (Val : Union_Id; Format : UI_Format := Auto) is
741 begin
742 if Phase /= Printing then
743 return;
744 end if;
745
746 if Val in Node_Range then
747 Print_Node_Ref (Node_Id (Val));
748
749 elsif Val in List_Range then
750 Print_List_Ref (List_Id (Val));
751
752 elsif Val in Elist_Range then
753 Print_Elist_Ref (Elist_Id (Val));
754
755 elsif Val in Names_Range then
756 Print_Name (Name_Id (Val));
757 Write_Str (" (Name_Id=");
758 Write_Int (Int (Val));
759 Write_Char (')');
760
761 elsif Val in Strings_Range then
762 Write_String_Table_Entry (String_Id (Val));
763 Write_Str (" (String_Id=");
764 Write_Int (Int (Val));
765 Write_Char (')');
766
767 elsif Val in Uint_Range then
768 UI_Write (From_Union (Val), Format);
769 Write_Str (" (Uint = ");
770 Write_Int (Int (Val));
771 Write_Char (')');
772
773 elsif Val in Ureal_Range then
774 UR_Write (From_Union (Val));
775 Write_Str (" (Ureal = ");
776 Write_Int (Int (Val));
777 Write_Char (')');
778
415dddc8
RK
779 else
780 Print_Str ("****** Incorrect value = ");
781 Print_Int (Int (Val));
782 end if;
783 end Print_Field;
784
76f9c7f4
BD
785 procedure Print_Field
786 (Prefix : String;
a7cadd18
BD
787 Field : String;
788 N : Node_Or_Entity_Id;
789 FD : Field_Descriptor;
790 Format : UI_Format)
791 is
76f9c7f4
BD
792 Printed : Boolean := False;
793
794 procedure Print_Initial;
795 -- Print the initial stuff that goes before the value
796
797 procedure Print_Initial is
798 begin
799 Printed := True;
800 Print_Str (Prefix);
801 Print_Str (Field);
802
a7cadd18 803 if Print_Low_Level_Info then
76f9c7f4
BD
804 Write_Str (" at ");
805 Write_Int (Int (FD.Offset));
806 end if;
807
808 Write_Str (" = ");
809 end Print_Initial;
810
811 begin
812 if Phase /= Printing then
813 return;
814 end if;
815
816 case FD.Kind is
817 when Flag_Field =>
818 declare
819 Val : constant Boolean := Get_Flag (N, FD.Offset);
820 begin
821 if Val then
822 Print_Initial;
823 Print_Flag (Val);
824 end if;
825 end;
826
827 when Node_Id_Field =>
828 declare
829 Val : constant Node_Id := Get_Node_Id (N, FD.Offset);
830 begin
831 if Present (Val) then
832 Print_Initial;
833 Print_Node_Ref (Val);
834 end if;
835 end;
836
837 when List_Id_Field =>
838 declare
839 Val : constant List_Id := Get_List_Id (N, FD.Offset);
840 begin
841 if Present (Val) then
842 Print_Initial;
843 Print_List_Ref (Val);
844 end if;
845 end;
846
847 when Elist_Id_Field =>
848 declare
849 Val : constant Elist_Id := Get_Elist_Id (N, FD.Offset);
850 begin
851 if Present (Val) then
852 Print_Initial;
853 Print_Elist_Ref (Val);
854 end if;
855 end;
856
857 when Name_Id_Field =>
858 declare
859 Val : constant Name_Id := Get_Name_Id (N, FD.Offset);
860 begin
861 if Present (Val) then
862 Print_Initial;
863 Print_Name (Val);
864 Write_Str (" (Name_Id=");
865 Write_Int (Int (Val));
866 Write_Char (')');
867 end if;
868 end;
869
870 when String_Id_Field =>
871 declare
872 Val : constant String_Id := Get_String_Id (N, FD.Offset);
873 begin
874 if Val /= No_String then
875 Print_Initial;
876 Write_String_Table_Entry (Val);
877 Write_Str (" (String_Id=");
878 Write_Int (Int (Val));
879 Write_Char (')');
880 end if;
881 end;
882
883 when Uint_Field =>
884 declare
885 Val : constant Uint := Get_Uint (N, FD.Offset);
886 function Cast is new Unchecked_Conversion (Uint, Int);
887 begin
0c8ff35e
BD
888 -- Do this even if Val = No_Uint, because Uint fields default
889 -- to Uint_0.
890
891 Print_Initial;
892 UI_Write (Val, Format);
893 Write_Str (" (Uint = ");
894 Write_Int (Cast (Val));
895 Write_Char (')');
896 end;
897
898 when Valid_Uint_Field | Unat_Field | Upos_Field
899 | Nonzero_Uint_Field =>
900 declare
901 Val : constant Uint := Get_Valid_Uint (N, FD.Offset);
902 function Cast is new Unchecked_Conversion (Uint, Int);
903 begin
904 Print_Initial;
905 UI_Write (Val, Format);
906
907 case FD.Kind is
908 when Valid_Uint_Field => Write_Str (" v");
909 when Unat_Field => Write_Str (" n");
910 when Upos_Field => Write_Str (" p");
911 when Nonzero_Uint_Field => Write_Str (" nz");
912 when others => raise Program_Error;
913 end case;
914
915 Write_Str (" (Uint = ");
916 Write_Int (Cast (Val));
917 Write_Char (')');
76f9c7f4
BD
918 end;
919
920 when Ureal_Field =>
921 declare
922 Val : constant Ureal := Get_Ureal (N, FD.Offset);
923 function Cast is new Unchecked_Conversion (Ureal, Int);
924 begin
925 if Val /= No_Ureal then
926 Print_Initial;
927 UR_Write (Val);
928 Write_Str (" (Ureal = ");
929 Write_Int (Cast (Val));
930 Write_Char (')');
931 end if;
932 end;
933
a7cadd18 934 when Node_Kind_Type_Field =>
76f9c7f4 935 declare
a7cadd18 936 Val : constant Node_Kind := Get_Node_Kind_Type (N, FD.Offset);
76f9c7f4
BD
937 begin
938 Print_Initial;
939 Print_Str_Mixed_Case (Node_Kind'Image (Val));
940 end;
941
a7cadd18 942 when Entity_Kind_Type_Field =>
76f9c7f4 943 declare
a7cadd18
BD
944 Val : constant Entity_Kind :=
945 Get_Entity_Kind_Type (N, FD.Offset);
76f9c7f4
BD
946 begin
947 Print_Initial;
948 Print_Str_Mixed_Case (Entity_Kind'Image (Val));
949 end;
950
76f9c7f4
BD
951 when Union_Id_Field =>
952 declare
953 Val : constant Union_Id := Get_Union_Id (N, FD.Offset);
954 begin
955 if Val /= Empty_List_Or_Node then
956 Print_Initial;
957
958 if Val in Node_Range then
959 Print_Node_Ref (Node_Id (Val));
960
961 elsif Val in List_Range then
962 Print_List_Ref (List_Id (Val));
963
964 else
a7cadd18 965 Print_Str ("<invalid union id>");
76f9c7f4
BD
966 end if;
967 end if;
968 end;
76f9c7f4
BD
969
970 when others =>
971 Print_Initial;
a7cadd18
BD
972 Print_Str ("<unknown ");
973 Print_Str (Field_Kind'Image (FD.Kind));
974 Print_Str (">");
76f9c7f4
BD
975 end case;
976
977 if Printed then
978 Print_Eol;
979 end if;
980
a7cadd18
BD
981 -- If an exception is raised while printing, we try to print some low-level
982 -- information that is useful for debugging.
983
76f9c7f4
BD
984 exception
985 when others =>
986 declare
a7cadd18 987 function Cast is new Unchecked_Conversion (Field_Size_32_Bit, Int);
76f9c7f4
BD
988 begin
989 Write_Eol;
990 Print_Initial;
991 Write_Str ("exception raised in Print_Field -- int val = ");
992 Write_Eol;
993
994 case Field_Size (FD.Kind) is
995 when 1 => Write_Int (Int (Get_1_Bit_Val (N, FD.Offset)));
996 when 2 => Write_Int (Int (Get_2_Bit_Val (N, FD.Offset)));
997 when 4 => Write_Int (Int (Get_4_Bit_Val (N, FD.Offset)));
998 when 8 => Write_Int (Int (Get_8_Bit_Val (N, FD.Offset)));
999 when others => -- 32
1000 Write_Int (Cast (Get_32_Bit_Val (N, FD.Offset)));
1001 end case;
1002
1003 Write_Str (", ");
1004 Write_Str (FD.Kind'Img);
1005 Write_Str (" ");
1006 Write_Int (Int (Field_Size (FD.Kind)));
1007 Write_Str (" bits");
1008 Write_Eol;
1009 exception
1010 when others =>
1011 Write_Eol;
1012 Write_Str ("double exception raised in Print_Field");
1013 Write_Eol;
1014 end;
1015 end Print_Field;
1016
a7cadd18
BD
1017 ----------------------
1018 -- Print_Node_Field --
1019 ----------------------
1020
76f9c7f4
BD
1021 procedure Print_Node_Field
1022 (Prefix : String;
a7cadd18
BD
1023 Field : Node_Field;
1024 N : Node_Id;
1025 FD : Field_Descriptor;
1026 Format : UI_Format := Auto)
1027 is
76f9c7f4
BD
1028 begin
1029 if not Field_Is_Initial_Zero (N, Field) then
1030 Print_Field (Prefix, Image (Field), N, FD, Format);
1031 end if;
1032 end Print_Node_Field;
1033
a7cadd18
BD
1034 ------------------------
1035 -- Print_Entity_Field --
1036 ------------------------
1037
76f9c7f4
BD
1038 procedure Print_Entity_Field
1039 (Prefix : String;
a7cadd18
BD
1040 Field : Entity_Field;
1041 N : Entity_Id;
1042 FD : Field_Descriptor;
1043 Format : UI_Format := Auto)
1044 is
76f9c7f4
BD
1045 begin
1046 if not Field_Is_Initial_Zero (N, Field) then
1047 Print_Field (Prefix, Image (Field), N, FD, Format);
1048 end if;
1049 end Print_Entity_Field;
1050
415dddc8
RK
1051 ----------------
1052 -- Print_Flag --
1053 ----------------
1054
1055 procedure Print_Flag (F : Boolean) is
1056 begin
1057 if F then
1058 Print_Str ("True");
1059 else
1060 Print_Str ("False");
1061 end if;
1062 end Print_Flag;
1063
1064 ----------------
1065 -- Print_Init --
1066 ----------------
1067
1068 procedure Print_Init is
83dcc2bd
BD
1069 Max_Hash_Entries : constant Nat :=
1070 Approx_Num_Nodes_And_Entities + Num_Lists + Num_Elists;
415dddc8
RK
1071 begin
1072 Printing_Descendants := True;
1073 Write_Eol;
1074
1075 -- Allocate and clear serial number hash table. The size is 150% of
1076 -- the maximum possible number of entries, so that the hash table
1077 -- cannot get significantly overloaded.
1078
83dcc2bd 1079 Hash_Table_Len := (150 * Max_Hash_Entries) / 100;
415dddc8
RK
1080 Hash_Table := new Hash_Table_Type (0 .. Hash_Table_Len - 1);
1081
1082 for J in Hash_Table'Range loop
1083 Hash_Table (J).Serial := 0;
1084 end loop;
1085
1086 end Print_Init;
1087
1088 ---------------
1089 -- Print_Int --
1090 ---------------
1091
1092 procedure Print_Int (I : Int) is
1093 begin
1094 if Phase = Printing then
1095 Write_Int (I);
1096 end if;
1097 end Print_Int;
1098
1099 --------------------
1100 -- Print_List_Ref --
1101 --------------------
1102
1103 procedure Print_List_Ref (L : List_Id) is
1104 begin
1105 if Phase /= Printing then
1106 return;
1107 end if;
1108
1109 if No (L) then
1110 Write_Str ("<no list>");
1111
1112 elsif Is_Empty_List (L) then
1113 Write_Str ("<empty list> (List_Id=");
1114 Write_Int (Int (L));
1115 Write_Char (')');
1116
1117 else
1118 Write_Str ("List");
1119
1120 if Printing_Descendants then
1121 Write_Str (" #");
1122 Write_Int (Serial_Number (Int (L)));
1123 end if;
1124
1125 Write_Str (" (List_Id=");
1126 Write_Int (Int (L));
1127 Write_Char (')');
1128 end if;
1129 end Print_List_Ref;
1130
1131 ------------------------
1132 -- Print_List_Subtree --
1133 ------------------------
1134
1135 procedure Print_List_Subtree (L : List_Id) is
1136 begin
1137 Print_Init;
1138
1139 Next_Serial_Number := 1;
1140 Phase := Marking;
1141 Visit_List (L, "");
1142
1143 Next_Serial_Number := 1;
1144 Phase := Printing;
1145 Visit_List (L, "");
1146
1147 Print_Term;
1148 end Print_List_Subtree;
1149
1150 ----------------
1151 -- Print_Name --
1152 ----------------
1153
1154 procedure Print_Name (N : Name_Id) is
1155 begin
1156 if Phase = Printing then
1157 if N = No_Name then
1158 Print_Str ("<No_Name>");
1159
1160 elsif N = Error_Name then
1161 Print_Str ("<Error_Name>");
1162
87ace727 1163 elsif Is_Valid_Name (N) then
415dddc8
RK
1164 Get_Name_String (N);
1165 Print_Char ('"');
1166 Write_Name (N);
1167 Print_Char ('"');
87ace727
RD
1168
1169 else
a7cadd18 1170 Print_Str ("<invalid name>");
415dddc8
RK
1171 end if;
1172 end if;
1173 end Print_Name;
1174
1175 ----------------
1176 -- Print_Node --
1177 ----------------
1178
1179 procedure Print_Node
1180 (N : Node_Id;
1181 Prefix_Str : String;
1182 Prefix_Char : Character)
1183 is
76f9c7f4 1184 Prefix : constant String := Prefix_Str & Prefix_Char;
415dddc8 1185
e3b3266c 1186 Sfile : Source_File_Index;
415dddc8
RK
1187 Fmt : UI_Format;
1188
1189 begin
1190 if Phase /= Printing then
1191 return;
1192 end if;
1193
ad4ba28b
AC
1194 -- If there is no such node, indicate that. Skip the rest, so we don't
1195 -- crash getting fields of the nonexistent node.
1196
76f9c7f4 1197 if not Is_Valid_Node (Union_Id (N)) then
ad4ba28b
AC
1198 Print_Str ("No such node: ");
1199 Print_Int (Int (N));
1200 Print_Eol;
1201 return;
415dddc8
RK
1202 end if;
1203
415dddc8
RK
1204 -- Print header line
1205
1206 Print_Str (Prefix_Str);
ee1a7572 1207 Print_Node_Header (N);
415dddc8
RK
1208
1209 if Is_Rewrite_Substitution (N) then
1210 Print_Str (Prefix_Str);
1211 Print_Str (" Rewritten: original node = ");
1212 Print_Node_Ref (Original_Node (N));
1213 Print_Eol;
1214 end if;
1215
a7cadd18 1216 if Print_Low_Level_Info then
76f9c7f4
BD
1217 Print_Atree_Info (N);
1218 end if;
1219
415dddc8
RK
1220 if N = Empty then
1221 return;
1222 end if;
1223
1224 if not Is_List_Member (N) then
1225 Print_Str (Prefix_Str);
1226 Print_Str (" Parent = ");
1227 Print_Node_Ref (Parent (N));
1228 Print_Eol;
1229 end if;
1230
1231 -- Print Sloc field if it is set
1232
1233 if Sloc (N) /= No_Location then
76f9c7f4 1234 Print_Str (Prefix);
415dddc8
RK
1235 Print_Str ("Sloc = ");
1236
e3b3266c
AC
1237 if Sloc (N) = Standard_Location then
1238 Print_Str ("Standard_Location");
1239
1240 elsif Sloc (N) = Standard_ASCII_Location then
1241 Print_Str ("Standard_ASCII_Location");
1242
1243 else
1244 Sfile := Get_Source_File_Index (Sloc (N));
1245 Print_Int (Int (Sloc (N)) - Int (Source_Text (Sfile)'First));
1246 Write_Str (" ");
1247 Write_Location (Sloc (N));
1248 end if;
1249
1250 Print_Eol;
415dddc8
RK
1251 end if;
1252
1253 -- Print Chars field if present
1254
99e30ba8
BD
1255 if Nkind (N) in N_Has_Chars then
1256 if Field_Is_Initial_Zero (N, F_Chars) then
1257 Print_Str (Prefix);
1258 Print_Str ("Chars = initial zero");
1259 Print_Eol;
1260
1261 elsif Chars (N) /= No_Name then
1262 Print_Str (Prefix);
1263 Print_Str ("Chars = ");
1264 Print_Name (Chars (N));
1265 Write_Str (" (Name_Id=");
1266 Write_Int (Int (Chars (N)));
1267 Write_Char (')');
1268 Print_Eol;
1269 end if;
415dddc8
RK
1270 end if;
1271
1272 -- Special field print operations for non-entity nodes
1273
1274 if Nkind (N) not in N_Entity then
1275
1276 -- Deal with Left_Opnd and Right_Opnd fields
1277
1278 if Nkind (N) in N_Op
514d0fc5 1279 or else Nkind (N) in N_Short_Circuit
c064e066 1280 or else Nkind (N) in N_Membership_Test
415dddc8
RK
1281 then
1282 -- Print Left_Opnd if present
1283
1284 if Nkind (N) not in N_Unary_Op then
76f9c7f4 1285 Print_Str (Prefix);
415dddc8
RK
1286 Print_Str ("Left_Opnd = ");
1287 Print_Node_Ref (Left_Opnd (N));
1288 Print_Eol;
1289 end if;
1290
1291 -- Print Right_Opnd
1292
76f9c7f4 1293 Print_Str (Prefix);
415dddc8
RK
1294 Print_Str ("Right_Opnd = ");
1295 Print_Node_Ref (Right_Opnd (N));
1296 Print_Eol;
1297 end if;
1298
8863c3aa
BD
1299 -- Deal with Entity_Or_Associated_Node. If N has both, then just
1300 -- print Entity; they are the same thing.
415dddc8 1301
8863c3aa 1302 if N in N_Inclusive_Has_Entity and then Present (Entity (N)) then
76f9c7f4 1303 Print_Str (Prefix);
415dddc8
RK
1304 Print_Str ("Entity = ");
1305 Print_Node_Ref (Entity (N));
1306 Print_Eol;
8863c3aa
BD
1307
1308 elsif N in N_Has_Associated_Node
1309 and then Present (Associated_Node (N))
1310 then
1311 Print_Str (Prefix);
1312 Print_Str ("Associated_Node = ");
1313 Print_Node_Ref (Associated_Node (N));
1314 Print_Eol;
415dddc8
RK
1315 end if;
1316
1317 -- Print special fields if we have a subexpression
1318
1319 if Nkind (N) in N_Subexpr then
1320
1321 if Assignment_OK (N) then
76f9c7f4 1322 Print_Str (Prefix);
415dddc8
RK
1323 Print_Str ("Assignment_OK = True");
1324 Print_Eol;
1325 end if;
1326
1327 if Do_Range_Check (N) then
76f9c7f4 1328 Print_Str (Prefix);
415dddc8
RK
1329 Print_Str ("Do_Range_Check = True");
1330 Print_Eol;
1331 end if;
1332
1333 if Has_Dynamic_Length_Check (N) then
76f9c7f4 1334 Print_Str (Prefix);
415dddc8
RK
1335 Print_Str ("Has_Dynamic_Length_Check = True");
1336 Print_Eol;
1337 end if;
1338
c159409f 1339 if Has_Aspects (N) then
76f9c7f4 1340 Print_Str (Prefix);
c159409f
AC
1341 Print_Str ("Has_Aspects = True");
1342 Print_Eol;
1343 end if;
1344
415dddc8 1345 if Is_Controlling_Actual (N) then
76f9c7f4 1346 Print_Str (Prefix);
415dddc8
RK
1347 Print_Str ("Is_Controlling_Actual = True");
1348 Print_Eol;
1349 end if;
1350
1351 if Is_Overloaded (N) then
76f9c7f4 1352 Print_Str (Prefix);
415dddc8
RK
1353 Print_Str ("Is_Overloaded = True");
1354 Print_Eol;
1355 end if;
1356
1357 if Is_Static_Expression (N) then
76f9c7f4 1358 Print_Str (Prefix);
415dddc8
RK
1359 Print_Str ("Is_Static_Expression = True");
1360 Print_Eol;
1361 end if;
1362
1363 if Must_Not_Freeze (N) then
76f9c7f4 1364 Print_Str (Prefix);
415dddc8
RK
1365 Print_Str ("Must_Not_Freeze = True");
1366 Print_Eol;
1367 end if;
1368
1369 if Paren_Count (N) /= 0 then
76f9c7f4 1370 Print_Str (Prefix);
415dddc8
RK
1371 Print_Str ("Paren_Count = ");
1372 Print_Int (Int (Paren_Count (N)));
1373 Print_Eol;
1374 end if;
1375
1376 if Raises_Constraint_Error (N) then
76f9c7f4 1377 Print_Str (Prefix);
c5a913d3 1378 Print_Str ("Raises_Constraint_Error = True");
415dddc8
RK
1379 Print_Eol;
1380 end if;
1381
1382 end if;
1383
1384 -- Print Do_Overflow_Check field if present
1385
1386 if Nkind (N) in N_Op and then Do_Overflow_Check (N) then
76f9c7f4 1387 Print_Str (Prefix);
415dddc8
RK
1388 Print_Str ("Do_Overflow_Check = True");
1389 Print_Eol;
1390 end if;
1391
1392 -- Print Etype field if present (printing of this field for entities
1393 -- is handled by the Print_Entity_Info procedure).
1394
a99ada67 1395 if Nkind (N) in N_Has_Etype and then Present (Etype (N)) then
76f9c7f4 1396 Print_Str (Prefix);
415dddc8
RK
1397 Print_Str ("Etype = ");
1398 Print_Node_Ref (Etype (N));
1399 Print_Eol;
1400 end if;
1401 end if;
ad4ba28b
AC
1402
1403 if Nkind (N) = N_Integer_Literal and then Print_In_Hex (N) then
1404 Fmt := Hex;
1405 else
1406 Fmt := Auto;
1407 end if;
1408
76f9c7f4 1409 declare
a7cadd18
BD
1410 Fields : Node_Field_Array renames Node_Field_Table (Nkind (N)).all;
1411 Should_Print : constant Node_Field_Set :=
1412 -- Set of fields that should be printed. False for fields that were
1413 -- already printed above, and for In_List, which we don't bother
1414 -- printing.
f54fb769
BD
1415 (F_Nkind
1416 | F_Chars
1417 | F_Comes_From_Source
1418 | F_Analyzed
1419 | F_Error_Posted
1420 | F_Is_Ignored_Ghost_Node
1421 | F_Check_Actuals
1422 | F_Link -- Parent was printed
1423 | F_Sloc
1424 | F_Left_Opnd
1425 | F_Right_Opnd
8863c3aa 1426 | F_Entity_Or_Associated_Node -- one of them was printed
f54fb769
BD
1427 | F_Assignment_OK
1428 | F_Do_Range_Check
1429 | F_Has_Dynamic_Length_Check
1430 | F_Has_Aspects
1431 | F_Is_Controlling_Actual
1432 | F_Is_Overloaded
1433 | F_Is_Static_Expression
1434 | F_Must_Not_Freeze
1435 | F_Small_Paren_Count -- Paren_Count was printed
1436 | F_Raises_Constraint_Error
1437 | F_Do_Overflow_Check
1438 | F_Etype
1439 | F_In_List
a7cadd18 1440 => False,
76f9c7f4 1441
a7cadd18 1442 others => True);
76f9c7f4
BD
1443 begin
1444 -- Outer loop makes flags come out last
1445
1446 for Print_Flags in Boolean loop
a7cadd18 1447 for Field_Index in Fields'Range loop
76f9c7f4
BD
1448 declare
1449 FD : Field_Descriptor renames
99e30ba8 1450 Field_Descriptors (Fields (Field_Index));
76f9c7f4 1451 begin
a7cadd18
BD
1452 if Should_Print (Fields (Field_Index))
1453 and then (FD.Kind = Flag_Field) = Print_Flags
1454 then
1455 -- Special case for End_Span, which also prints the
1456 -- End_Location.
1457
f54fb769 1458 if Fields (Field_Index) = F_End_Span then
a7cadd18
BD
1459 Print_End_Span (N);
1460
1461 else
1462 Print_Node_Field
1463 (Prefix, Fields (Field_Index), N, FD, Fmt);
1464 end if;
415dddc8 1465 end if;
76f9c7f4 1466 end;
415dddc8 1467 end loop;
76f9c7f4
BD
1468 end loop;
1469 end;
415dddc8 1470
c159409f
AC
1471 -- Print aspects if present
1472
1473 if Has_Aspects (N) then
76f9c7f4 1474 Print_Str (Prefix);
c159409f
AC
1475 Print_Str ("Aspect_Specifications = ");
1476 Print_Field (Union_Id (Aspect_Specifications (N)));
1477 Print_Eol;
1478 end if;
1479
415dddc8
RK
1480 -- Print entity information for entities
1481
1482 if Nkind (N) in N_Entity then
76f9c7f4 1483 Print_Entity_Info (N, Prefix);
415dddc8
RK
1484 end if;
1485
7665e4bd
AC
1486 -- Print the SCIL node (if available)
1487
1488 if Present (Get_SCIL_Node (N)) then
76f9c7f4 1489 Print_Str (Prefix);
7665e4bd
AC
1490 Print_Str ("SCIL_Node = ");
1491 Print_Node_Ref (Get_SCIL_Node (N));
1492 Print_Eol;
1493 end if;
415dddc8
RK
1494 end Print_Node;
1495
ee1a7572
AC
1496 ------------------------
1497 -- Print_Node_Briefly --
1498 ------------------------
1499
1500 procedure Print_Node_Briefly (N : Node_Id) is
1501 begin
1502 Printing_Descendants := False;
1503 Phase := Printing;
1504 Print_Node_Header (N);
1505 end Print_Node_Briefly;
1506
1507 -----------------------
1508 -- Print_Node_Header --
1509 -----------------------
1510
1511 procedure Print_Node_Header (N : Node_Id) is
8636f52f
HK
1512 Enumerate : Boolean := False;
1513 -- Flag set when enumerating multiple header flags
1514
1515 procedure Print_Header_Flag (Flag : String);
1516 -- Output one of the flags that appears in a node header. The routine
1517 -- automatically handles enumeration of multiple flags.
1518
1519 -----------------------
1520 -- Print_Header_Flag --
1521 -----------------------
1522
1523 procedure Print_Header_Flag (Flag : String) is
1524 begin
1525 if Enumerate then
1526 Print_Char (',');
1527 else
1528 Enumerate := True;
1529 Print_Char ('(');
1530 end if;
1531
1532 Print_Str (Flag);
1533 end Print_Header_Flag;
1534
1535 -- Start of processing for Print_Node_Header
ee1a7572
AC
1536
1537 begin
1538 Print_Node_Ref (N);
1539
76f9c7f4 1540 if not Is_Valid_Node (Union_Id (N)) then
ee1a7572
AC
1541 Print_Str (" (no such node)");
1542 Print_Eol;
1543 return;
1544 end if;
1545
8636f52f
HK
1546 Print_Char (' ');
1547
ee1a7572 1548 if Comes_From_Source (N) then
8636f52f 1549 Print_Header_Flag ("source");
ee1a7572
AC
1550 end if;
1551
1552 if Analyzed (N) then
8636f52f 1553 Print_Header_Flag ("analyzed");
ee1a7572
AC
1554 end if;
1555
1556 if Error_Posted (N) then
8636f52f
HK
1557 Print_Header_Flag ("posted");
1558 end if;
ee1a7572 1559
8636f52f
HK
1560 if Is_Ignored_Ghost_Node (N) then
1561 Print_Header_Flag ("ignored ghost");
ee1a7572
AC
1562 end if;
1563
b502ba3c
RD
1564 if Check_Actuals (N) then
1565 Print_Header_Flag ("check actuals");
fd957434
AC
1566 end if;
1567
8636f52f 1568 if Enumerate then
ee1a7572
AC
1569 Print_Char (')');
1570 end if;
1571
1572 Print_Eol;
1573 end Print_Node_Header;
1574
415dddc8
RK
1575 ---------------------
1576 -- Print_Node_Kind --
1577 ---------------------
1578
1579 procedure Print_Node_Kind (N : Node_Id) is
415dddc8
RK
1580 begin
1581 if Phase = Printing then
a7cadd18 1582 Print_Str_Mixed_Case (Node_Kind'Image (Nkind (N)));
415dddc8
RK
1583 end if;
1584 end Print_Node_Kind;
1585
1586 --------------------
1587 -- Print_Node_Ref --
1588 --------------------
1589
1590 procedure Print_Node_Ref (N : Node_Id) is
1591 S : Nat;
1592
1593 begin
1594 if Phase /= Printing then
1595 return;
1596 end if;
1597
1598 if N = Empty then
1599 Write_Str ("<empty>");
1600
1601 elsif N = Error then
1602 Write_Str ("<error>");
1603
1604 else
1605 if Printing_Descendants then
1606 S := Serial_Number (Int (N));
1607
1608 if S /= 0 then
1609 Write_Str ("Node");
1610 Write_Str (" #");
1611 Write_Int (S);
1612 Write_Char (' ');
1613 end if;
1614 end if;
1615
1616 Print_Node_Kind (N);
1617
1618 if Nkind (N) in N_Has_Chars then
1619 Write_Char (' ');
99e30ba8
BD
1620
1621 if Field_Is_Initial_Zero (N, F_Chars) then
1622 Print_Str ("Chars = initial zero");
1623 Print_Eol;
1624
1625 else
1626 Print_Name (Chars (N));
1627 end if;
415dddc8
RK
1628 end if;
1629
1630 if Nkind (N) in N_Entity then
1631 Write_Str (" (Entity_Id=");
1632 else
1633 Write_Str (" (Node_Id=");
1634 end if;
1635
1636 Write_Int (Int (N));
1637
1638 if Sloc (N) <= Standard_Location then
1639 Write_Char ('s');
1640 end if;
1641
1642 Write_Char (')');
1643
1644 end if;
1645 end Print_Node_Ref;
1646
1647 ------------------------
1648 -- Print_Node_Subtree --
1649 ------------------------
1650
1651 procedure Print_Node_Subtree (N : Node_Id) is
1652 begin
1653 Print_Init;
1654
1655 Next_Serial_Number := 1;
1656 Phase := Marking;
1657 Visit_Node (N, "", ' ');
1658
1659 Next_Serial_Number := 1;
1660 Phase := Printing;
1661 Visit_Node (N, "", ' ');
1662
1663 Print_Term;
1664 end Print_Node_Subtree;
1665
1666 ---------------
1667 -- Print_Str --
1668 ---------------
1669
1670 procedure Print_Str (S : String) is
1671 begin
1672 if Phase = Printing then
1673 Write_Str (S);
1674 end if;
1675 end Print_Str;
1676
1677 --------------------------
1678 -- Print_Str_Mixed_Case --
1679 --------------------------
1680
1681 procedure Print_Str_Mixed_Case (S : String) is
1682 Ucase : Boolean;
1683
1684 begin
1685 if Phase = Printing then
1686 Ucase := True;
1687
1688 for J in S'Range loop
1689 if Ucase then
1690 Write_Char (S (J));
1691 else
1692 Write_Char (Fold_Lower (S (J)));
1693 end if;
1694
1695 Ucase := (S (J) = '_');
1696 end loop;
1697 end if;
1698 end Print_Str_Mixed_Case;
1699
1700 ----------------
1701 -- Print_Term --
1702 ----------------
1703
1704 procedure Print_Term is
1705 procedure Free is new Unchecked_Deallocation
1706 (Hash_Table_Type, Access_Hash_Table_Type);
1707
1708 begin
1709 Free (Hash_Table);
1710 end Print_Term;
1711
1712 ---------------------
1713 -- Print_Tree_Elist --
1714 ---------------------
1715
1716 procedure Print_Tree_Elist (E : Elist_Id) is
1717 M : Elmt_Id;
1718
1719 begin
1720 Printing_Descendants := False;
1721 Phase := Printing;
1722
1723 Print_Elist_Ref (E);
1724 Print_Eol;
1725
e4bda610
AC
1726 if Present (E) and then not Is_Empty_Elmt_List (E) then
1727 M := First_Elmt (E);
415dddc8 1728
415dddc8
RK
1729 loop
1730 Print_Char ('|');
1731 Print_Eol;
1732 exit when No (Next_Elmt (M));
1733 Print_Node (Node (M), "", '|');
1734 Next_Elmt (M);
1735 end loop;
1736
1737 Print_Node (Node (M), "", ' ');
1738 Print_Eol;
1739 end if;
1740 end Print_Tree_Elist;
1741
1742 ---------------------
1743 -- Print_Tree_List --
1744 ---------------------
1745
1746 procedure Print_Tree_List (L : List_Id) is
1747 N : Node_Id;
1748
1749 begin
1750 Printing_Descendants := False;
1751 Phase := Printing;
1752
1753 Print_List_Ref (L);
1754 Print_Str (" List_Id=");
1755 Print_Int (Int (L));
1756 Print_Eol;
1757
1758 N := First (L);
1759
1760 if N = Empty then
1761 Print_Str ("<empty node list>");
1762 Print_Eol;
1763
1764 else
1765 loop
1766 Print_Char ('|');
1767 Print_Eol;
1768 exit when Next (N) = Empty;
1769 Print_Node (N, "", '|');
1770 Next (N);
1771 end loop;
1772
1773 Print_Node (N, "", ' ');
1774 Print_Eol;
1775 end if;
1776 end Print_Tree_List;
1777
1778 ---------------------
1779 -- Print_Tree_Node --
1780 ---------------------
1781
1782 procedure Print_Tree_Node (N : Node_Id; Label : String := "") is
1783 begin
1784 Printing_Descendants := False;
1785 Phase := Printing;
1786 Print_Node (N, Label, ' ');
1787 end Print_Tree_Node;
1788
1789 --------
07fc65c4 1790 -- pt --
415dddc8
RK
1791 --------
1792
6be44a9a 1793 procedure pt (N : Union_Id) is
415dddc8 1794 begin
6be44a9a
BD
1795 case N is
1796 when List_Low_Bound .. List_High_Bound - 1 =>
1797 Print_List_Subtree (List_Id (N));
d8f43ee6 1798
6be44a9a
BD
1799 when Node_Range =>
1800 Print_Node_Subtree (Node_Id (N));
d8f43ee6 1801
6be44a9a
BD
1802 when Elist_Range =>
1803 Print_Elist_Subtree (Elist_Id (N));
d8f43ee6 1804
6be44a9a
BD
1805 when others =>
1806 pp (N);
1807 end case;
07fc65c4 1808 end pt;
415dddc8
RK
1809
1810 -------------------
1811 -- Serial_Number --
1812 -------------------
1813
1814 -- The hashing algorithm is to use the remainder of the ID value divided
1815 -- by the hash table length as the starting point in the table, and then
1816 -- handle collisions by serial searching wrapping at the end of the table.
1817
1818 Hash_Slot : Nat;
1819 -- Set by an unsuccessful call to Serial_Number (one which returns zero)
1820 -- to save the slot that should be used if Set_Serial_Number is called.
1821
1822 function Serial_Number (Id : Int) return Nat is
1823 H : Int := Id mod Hash_Table_Len;
1824
1825 begin
1826 while Hash_Table (H).Serial /= 0 loop
1827
1828 if Id = Hash_Table (H).Id then
1829 return Hash_Table (H).Serial;
1830 end if;
1831
1832 H := H + 1;
1833
1834 if H > Hash_Table'Last then
1835 H := 0;
1836 end if;
1837 end loop;
1838
1839 -- Entry was not found, save slot number for possible subsequent call
1840 -- to Set_Serial_Number, and unconditionally save the Id in this slot
1841 -- in case of such a call (the Id field is never read if the serial
1842 -- number of the slot is zero, so this is harmless in the case where
1843 -- Set_Serial_Number is not subsequently called).
1844
1845 Hash_Slot := H;
1846 Hash_Table (H).Id := Id;
1847 return 0;
415dddc8
RK
1848 end Serial_Number;
1849
1850 -----------------------
1851 -- Set_Serial_Number --
1852 -----------------------
1853
1854 procedure Set_Serial_Number is
1855 begin
1856 Hash_Table (Hash_Slot).Serial := Next_Serial_Number;
1857 Next_Serial_Number := Next_Serial_Number + 1;
1858 end Set_Serial_Number;
1859
1860 ---------------
1861 -- Tree_Dump --
1862 ---------------
1863
1864 procedure Tree_Dump is
1865 procedure Underline;
1866 -- Put underline under string we just printed
1867
1868 procedure Underline is
1869 Col : constant Int := Column;
1870
1871 begin
1872 Write_Eol;
1873
1874 while Col > Column loop
1875 Write_Char ('-');
1876 end loop;
1877
1878 Write_Eol;
1879 end Underline;
1880
1881 -- Start of processing for Tree_Dump. Note that we turn off the tree dump
1882 -- flags immediately, before starting the dump. This avoids generating two
1883 -- copies of the dump if an abort occurs after printing the dump, and more
1884 -- importantly, avoids an infinite loop if an abort occurs during the dump.
1885
1886 -- Note: unlike in the source print case (in Sprint), we do not output
1887 -- separate trees for each unit. Instead the -df debug switch causes the
1888 -- tree that is output from the main unit to trace references into other
1889 -- units (normally such references are not traced). Since all other units
1890 -- are linked to the main unit by at least one reference, this causes all
1891 -- tree nodes to be included in the output tree.
1892
1893 begin
1894 if Debug_Flag_Y then
1895 Debug_Flag_Y := False;
1896 Write_Eol;
1897 Write_Str ("Tree created for Standard (spec) ");
1898 Underline;
1899 Print_Node_Subtree (Standard_Package_Node);
1900 Write_Eol;
1901 end if;
1902
1903 if Debug_Flag_T then
1904 Debug_Flag_T := False;
1905
1906 Write_Eol;
1907 Write_Str ("Tree created for ");
1908 Write_Unit_Name (Unit_Name (Main_Unit));
1909 Underline;
1910 Print_Node_Subtree (Cunit (Main_Unit));
1911 Write_Eol;
1912 end if;
415dddc8
RK
1913 end Tree_Dump;
1914
1915 -----------------
1916 -- Visit_Elist --
1917 -----------------
1918
1919 procedure Visit_Elist (E : Elist_Id; Prefix_Str : String) is
1920 M : Elmt_Id;
1921 N : Node_Id;
1922 S : constant Nat := Serial_Number (Int (E));
1923
1924 begin
1925 -- In marking phase, return if already marked, otherwise set next
1926 -- serial number in hash table for later reference.
1927
1928 if Phase = Marking then
1929 if S /= 0 then
1930 return; -- already visited
1931 else
1932 Set_Serial_Number;
1933 end if;
1934
1935 -- In printing phase, if already printed, then return, otherwise we
1936 -- are printing the next item, so increment the serial number.
1937
1938 else
1939 if S < Next_Serial_Number then
1940 return; -- already printed
1941 else
1942 Next_Serial_Number := Next_Serial_Number + 1;
1943 end if;
1944 end if;
1945
1946 -- Now process the list (Print calls have no effect in marking phase)
1947
1948 Print_Str (Prefix_Str);
1949 Print_Elist_Ref (E);
1950 Print_Eol;
1951
1952 if Is_Empty_Elmt_List (E) then
1953 Print_Str (Prefix_Str);
1954 Print_Str ("(Empty element list)");
1955 Print_Eol;
1956 Print_Eol;
1957
1958 else
1959 if Phase = Printing then
1960 M := First_Elmt (E);
1961 while Present (M) loop
1962 N := Node (M);
1963 Print_Str (Prefix_Str);
1964 Print_Str (" ");
1965 Print_Node_Ref (N);
1966 Print_Eol;
1967 Next_Elmt (M);
1968 end loop;
1969
1970 Print_Str (Prefix_Str);
1971 Print_Eol;
1972 end if;
1973
1974 M := First_Elmt (E);
1975 while Present (M) loop
1976 Visit_Node (Node (M), Prefix_Str, ' ');
1977 Next_Elmt (M);
1978 end loop;
1979 end if;
1980 end Visit_Elist;
1981
1982 ----------------
1983 -- Visit_List --
1984 ----------------
1985
1986 procedure Visit_List (L : List_Id; Prefix_Str : String) is
1987 N : Node_Id;
1988 S : constant Nat := Serial_Number (Int (L));
1989
1990 begin
1991 -- In marking phase, return if already marked, otherwise set next
1992 -- serial number in hash table for later reference.
1993
1994 if Phase = Marking then
1995 if S /= 0 then
1996 return;
1997 else
1998 Set_Serial_Number;
1999 end if;
2000
2001 -- In printing phase, if already printed, then return, otherwise we
2002 -- are printing the next item, so increment the serial number.
2003
2004 else
2005 if S < Next_Serial_Number then
2006 return; -- already printed
2007 else
2008 Next_Serial_Number := Next_Serial_Number + 1;
2009 end if;
2010 end if;
2011
2012 -- Now process the list (Print calls have no effect in marking phase)
2013
2014 Print_Str (Prefix_Str);
2015 Print_List_Ref (L);
2016 Print_Eol;
2017
2018 Print_Str (Prefix_Str);
2019 Print_Str ("|Parent = ");
2020 Print_Node_Ref (Parent (L));
2021 Print_Eol;
2022
2023 N := First (L);
2024
2025 if N = Empty then
2026 Print_Str (Prefix_Str);
2027 Print_Str ("(Empty list)");
2028 Print_Eol;
2029 Print_Eol;
2030
2031 else
2032 Print_Str (Prefix_Str);
2033 Print_Char ('|');
2034 Print_Eol;
2035
2036 while Next (N) /= Empty loop
2037 Visit_Node (N, Prefix_Str, '|');
2038 Next (N);
2039 end loop;
2040 end if;
2041
2042 Visit_Node (N, Prefix_Str, ' ');
2043 end Visit_List;
2044
2045 ----------------
2046 -- Visit_Node --
2047 ----------------
2048
2049 procedure Visit_Node
2050 (N : Node_Id;
2051 Prefix_Str : String;
2052 Prefix_Char : Character)
2053 is
2054 New_Prefix : String (Prefix_Str'First .. Prefix_Str'Last + 2);
2055 -- Prefix string for printing referenced fields
2056
d9d25d04 2057 procedure Visit_Descendant
415dddc8
RK
2058 (D : Union_Id;
2059 No_Indent : Boolean := False);
2060 -- This procedure tests the given value of one of the Fields referenced
2061 -- by the current node to determine whether to visit it recursively.
3354f96d 2062 -- Normally No_Indent is false, which means that the visited node will
415dddc8
RK
2063 -- be indented using New_Prefix. If No_Indent is set to True, then
2064 -- this indentation is skipped, and Prefix_Str is used for the call
d9d25d04
AC
2065 -- to print the descendant. No_Indent is effective only if the
2066 -- referenced descendant is a node.
415dddc8
RK
2067
2068 ----------------------
d9d25d04 2069 -- Visit_Descendant --
415dddc8
RK
2070 ----------------------
2071
d9d25d04 2072 procedure Visit_Descendant
415dddc8
RK
2073 (D : Union_Id;
2074 No_Indent : Boolean := False)
2075 is
2076 begin
d9d25d04 2077 -- Case of descendant is a node
415dddc8
RK
2078
2079 if D in Node_Range then
2080
d9d25d04 2081 -- Don't bother about Empty or Error descendants
415dddc8
RK
2082
2083 if D <= Union_Id (Empty_Or_Error) then
2084 return;
2085 end if;
2086
2087 declare
2088 Nod : constant Node_Or_Entity_Id := Node_Or_Entity_Id (D);
2089
2090 begin
d9d25d04 2091 -- Descendants in one of the standardly compiled internal
415dddc8
RK
2092 -- packages are normally ignored, unless the parent is also
2093 -- in such a package (happens when Standard itself is output)
2094 -- or if the -df switch is set which causes all links to be
2095 -- followed, even into package standard.
2096
2097 if Sloc (Nod) <= Standard_Location then
2098 if Sloc (N) > Standard_Location
2099 and then not Debug_Flag_F
2100 then
2101 return;
2102 end if;
2103
d9d25d04 2104 -- Don't bother about a descendant in a different unit than
415dddc8
RK
2105 -- the node we came from unless the -df switch is set. Note
2106 -- that we know at this point that Sloc (D) > Standard_Location
2107
2108 -- Note: the tests for No_Location here just make sure that we
2109 -- don't blow up on a node which is missing an Sloc value. This
2110 -- should not normally happen.
2111
2112 else
2113 if (Sloc (N) <= Standard_Location
2114 or else Sloc (N) = No_Location
2115 or else Sloc (Nod) = No_Location
2116 or else not In_Same_Source_Unit (Nod, N))
2117 and then not Debug_Flag_F
2118 then
2119 return;
2120 end if;
2121 end if;
2122
2123 -- Don't bother visiting a source node that has a parent which
2124 -- is not the node we came from. We prefer to trace such nodes
2125 -- from their real parents. This causes the tree to be printed
2126 -- in a more coherent order, e.g. a defining identifier listed
2127 -- next to its corresponding declaration, instead of next to
2128 -- some semantic reference.
2129
2130 -- This test is skipped for nodes in standard packages unless
2131 -- the -dy option is set (which outputs the tree for standard)
2132
2133 -- Also, always follow pointers to Is_Itype entities,
2134 -- since we want to list these when they are first referenced.
2135
2136 if Parent (Nod) /= Empty
2137 and then Comes_From_Source (Nod)
2138 and then Parent (Nod) /= N
2139 and then (Sloc (N) > Standard_Location or else Debug_Flag_Y)
2140 then
2141 return;
2142 end if;
2143
2144 -- If we successfully fall through all the above tests (which
2145 -- execute a return if the node is not to be visited), we can
a90bd866 2146 -- go ahead and visit the node.
415dddc8
RK
2147
2148 if No_Indent then
2149 Visit_Node (Nod, Prefix_Str, Prefix_Char);
2150 else
2151 Visit_Node (Nod, New_Prefix, ' ');
2152 end if;
2153 end;
2154
d9d25d04 2155 -- Case of descendant is a list
415dddc8
RK
2156
2157 elsif D in List_Range then
2158
2159 -- Don't bother with a missing list, empty list or error list
2160
e49de265
BD
2161 pragma Assert (D /= Union_Id (No_List));
2162 -- Because No_List = Empty, which is in Node_Range above
2163
2164 if D = Union_Id (Error_List)
415dddc8
RK
2165 or else Is_Empty_List (List_Id (D))
2166 then
2167 return;
2168
4c51ff88
AC
2169 -- Otherwise we can visit the list. Note that we don't bother to
2170 -- do the parent test that we did for the node case, because it
2171 -- just does not happen that lists are referenced more than one
2172 -- place in the tree. We aren't counting on this being the case
2173 -- to generate valid output, it is just that we don't need in
2174 -- practice to worry about listing the list at a place that is
2175 -- inconvenient.
415dddc8
RK
2176
2177 else
2178 Visit_List (List_Id (D), New_Prefix);
2179 end if;
2180
d9d25d04 2181 -- Case of descendant is an element list
415dddc8
RK
2182
2183 elsif D in Elist_Range then
2184
2185 -- Don't bother with a missing list, or an empty list
2186
2187 if D = Union_Id (No_Elist)
2188 or else Is_Empty_Elmt_List (Elist_Id (D))
2189 then
2190 return;
2191
2192 -- Otherwise, visit the referenced element list
2193
2194 else
2195 Visit_Elist (Elist_Id (D), New_Prefix);
2196 end if;
2197
415dddc8 2198 else
76f9c7f4 2199 raise Program_Error;
415dddc8 2200 end if;
d9d25d04 2201 end Visit_Descendant;
415dddc8
RK
2202
2203 -- Start of processing for Visit_Node
2204
2205 begin
2206 if N = Empty then
2207 return;
2208 end if;
2209
2210 -- Set fatal error node in case we get a blow up during the trace
2211
2212 Current_Error_Node := N;
2213
2214 New_Prefix (Prefix_Str'Range) := Prefix_Str;
2215 New_Prefix (Prefix_Str'Last + 1) := Prefix_Char;
2216 New_Prefix (Prefix_Str'Last + 2) := ' ';
2217
2218 -- In the marking phase, all we do is to set the serial number
2219
2220 if Phase = Marking then
2221 if Serial_Number (Int (N)) /= 0 then
2222 return; -- already visited
2223 else
2224 Set_Serial_Number;
2225 end if;
2226
2227 -- In the printing phase, we print the node
2228
2229 else
2230 if Serial_Number (Int (N)) < Next_Serial_Number then
2231
4c51ff88
AC
2232 -- Here we have already visited the node, but if it is in a list,
2233 -- we still want to print the reference, so that it is clear that
2234 -- it belongs to the list.
415dddc8
RK
2235
2236 if Is_List_Member (N) then
2237 Print_Str (Prefix_Str);
2238 Print_Node_Ref (N);
2239 Print_Eol;
2240 Print_Str (Prefix_Str);
2241 Print_Char (Prefix_Char);
2242 Print_Str ("(already output)");
2243 Print_Eol;
2244 Print_Str (Prefix_Str);
2245 Print_Char (Prefix_Char);
2246 Print_Eol;
2247 end if;
2248
2249 return;
2250
2251 else
2252 Print_Node (N, Prefix_Str, Prefix_Char);
2253 Print_Str (Prefix_Str);
2254 Print_Char (Prefix_Char);
2255 Print_Eol;
2256 Next_Serial_Number := Next_Serial_Number + 1;
2257 end if;
2258 end if;
2259
d9d25d04 2260 -- Visit all descendants of this node
415dddc8 2261
76f9c7f4
BD
2262 declare
2263 A : Node_Field_Array renames Node_Field_Table (Nkind (N)).all;
2264 begin
2265 for Field_Index in A'Range loop
2266 declare
2267 F : constant Node_Field := A (Field_Index);
99e30ba8 2268 FD : Field_Descriptor renames Field_Descriptors (F);
76f9c7f4
BD
2269 begin
2270 if FD.Kind in Node_Id_Field | List_Id_Field | Elist_Id_Field
2271 -- For all other kinds of descendants (strings, names, uints
2272 -- etc), there is nothing to visit (the contents of the
2273 -- field will be printed when we print the containing node,
2274 -- but what concerns us now is looking for descendants in
2275 -- the tree.
2276
f54fb769 2277 and then F /= F_Next_Entity -- See below for why we skip this
76f9c7f4
BD
2278 then
2279 Visit_Descendant (Get_Union_Id (N, FD.Offset));
2280 end if;
2281 end;
2282 end loop;
2283 end;
c159409f 2284
76f9c7f4
BD
2285 if Has_Aspects (N) then
2286 Visit_Descendant (Union_Id (Aspect_Specifications (N)));
2287 end if;
415dddc8 2288
76f9c7f4
BD
2289 if Nkind (N) in N_Entity then
2290 declare
2291 A : Entity_Field_Array renames Entity_Field_Table (Ekind (N)).all;
2292 begin
2293 for Field_Index in A'Range loop
2294 declare
2295 F : constant Entity_Field := A (Field_Index);
99e30ba8 2296 FD : Field_Descriptor renames Field_Descriptors (F);
76f9c7f4
BD
2297 begin
2298 if FD.Kind in Node_Id_Field | List_Id_Field | Elist_Id_Field
2299 then
2300 Visit_Descendant (Get_Union_Id (N, FD.Offset));
2301 end if;
2302 end;
2303 end loop;
2304 end;
415dddc8 2305
e80f0cb0
RD
2306 -- Now an interesting special case. Normally parents are always
2307 -- printed since we traverse the tree in a downwards direction.
2308 -- However, there is an exception to this rule, which is the
2309 -- case where a parent is constructed by the compiler and is not
2310 -- referenced elsewhere in the tree. The following catches this case.
fbf5a39b
AC
2311
2312 if not Comes_From_Source (N) then
d9d25d04 2313 Visit_Descendant (Union_Id (Parent (N)));
fbf5a39b
AC
2314 end if;
2315
76f9c7f4
BD
2316 -- You may be wondering why we omitted Next_Entity above. The answer
2317 -- is that we want to treat it rather specially. Why? Because a
2318 -- Next_Entity link does not correspond to a level deeper in the
2319 -- tree, and we do not want the tree to march off to the right of the
2320 -- page due to bogus indentations coming from this effect.
415dddc8
RK
2321
2322 -- To prevent this, what we do is to control references via
4c51ff88
AC
2323 -- Next_Entity only from the first entity on a given scope chain,
2324 -- and we keep them all at the same level. Of course if an entity
2325 -- has already been referenced it is not printed.
415dddc8
RK
2326
2327 if Present (Next_Entity (N))
2328 and then Present (Scope (N))
2329 and then First_Entity (Scope (N)) = N
2330 then
2331 declare
2332 Nod : Node_Id;
2333
2334 begin
2335 Nod := N;
2336 while Present (Nod) loop
d9d25d04 2337 Visit_Descendant (Union_Id (Next_Entity (Nod)));
99859ea7 2338 Next_Entity (Nod);
415dddc8
RK
2339 end loop;
2340 end;
2341 end if;
2342 end if;
2343 end Visit_Node;
2344
2345end Treepr;
This page took 7.263426 seconds and 5 git commands to generate.