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