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