OSDN Git Service

2009-11-30 Robert Dewar <dewar@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / sprint.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                               S P R I N T                                --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2009, Free Software Foundation, Inc.         --
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- --
13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license.          --
20 --                                                                          --
21 -- GNAT was originally developed  by the GNAT team at  New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
23 --                                                                          --
24 ------------------------------------------------------------------------------
25
26 with Atree;    use Atree;
27 with Casing;   use Casing;
28 with Csets;    use Csets;
29 with Debug;    use Debug;
30 with Einfo;    use Einfo;
31 with Fname;    use Fname;
32 with Lib;      use Lib;
33 with Namet;    use Namet;
34 with Nlists;   use Nlists;
35 with Opt;      use Opt;
36 with Output;   use Output;
37 with Rtsfind;  use Rtsfind;
38 with Sem_Eval; use Sem_Eval;
39 with Sem_Util; use Sem_Util;
40 with Sinfo;    use Sinfo;
41 with Sinput;   use Sinput;
42 with Sinput.D; use Sinput.D;
43 with Snames;   use Snames;
44 with Stand;    use Stand;
45 with Stringt;  use Stringt;
46 with Uintp;    use Uintp;
47 with Uname;    use Uname;
48 with Urealp;   use Urealp;
49
50 package body Sprint is
51    Current_Source_File : Source_File_Index;
52    --  Index of source file whose generated code is being dumped
53
54    Dump_Node : Node_Id := Empty;
55    --  This is set to the current node, used for printing line numbers. In
56    --  Debug_Generated_Code mode, Dump_Node is set to the current node
57    --  requiring Sloc fixup, until Set_Debug_Sloc is called to set the proper
58    --  value. The call clears it back to Empty.
59
60    Debug_Sloc : Source_Ptr;
61    --  Sloc of first byte of line currently being written if we are
62    --  generating a source debug file.
63
64    Dump_Original_Only : Boolean;
65    --  Set True if the -gnatdo (dump original tree) flag is set
66
67    Dump_Generated_Only : Boolean;
68    --  Set True if the -gnatG (dump generated tree) debug flag is set
69    --  or for Print_Generated_Code (-gnatG) or Dump_Generated_Code (-gnatD).
70
71    Dump_Freeze_Null : Boolean;
72    --  Set True if freeze nodes and non-source null statements output
73
74    Freeze_Indent : Int := 0;
75    --  Keep track of freeze indent level (controls output of blank lines before
76    --  procedures within expression freeze actions). Relevant only if we are
77    --  not in Dump_Source_Text mode, since in Dump_Source_Text mode we don't
78    --  output these blank lines in any case.
79
80    Indent : Int := 0;
81    --  Number of columns for current line output indentation
82
83    Indent_Annull_Flag : Boolean := False;
84    --  Set True if subsequent Write_Indent call to be ignored, gets reset
85    --  by this call, so it is only active to suppress a single indent call.
86
87    Last_Line_Printed : Physical_Line_Number;
88    --  This keeps track of the physical line number of the last source line
89    --  that has been output. The value is only valid in Dump_Source_Text mode.
90
91    -------------------------------
92    -- Operator Precedence Table --
93    -------------------------------
94
95    --  This table is used to decide whether a subexpression needs to be
96    --  parenthesized. The rule is that if an operand of an operator (which
97    --  for this purpose includes AND THEN and OR ELSE) is itself an operator
98    --  with a lower precedence than the operator (or equal precedence if
99    --  appearing as the right operand), then parentheses are required.
100
101    Op_Prec : constant array (N_Subexpr) of Short_Short_Integer :=
102                (N_Op_And          => 1,
103                 N_Op_Or           => 1,
104                 N_Op_Xor          => 1,
105                 N_And_Then        => 1,
106                 N_Or_Else         => 1,
107
108                 N_In              => 2,
109                 N_Not_In          => 2,
110                 N_Op_Eq           => 2,
111                 N_Op_Ge           => 2,
112                 N_Op_Gt           => 2,
113                 N_Op_Le           => 2,
114                 N_Op_Lt           => 2,
115                 N_Op_Ne           => 2,
116
117                 N_Op_Add          => 3,
118                 N_Op_Concat       => 3,
119                 N_Op_Subtract     => 3,
120                 N_Op_Plus         => 3,
121                 N_Op_Minus        => 3,
122
123                 N_Op_Divide       => 4,
124                 N_Op_Mod          => 4,
125                 N_Op_Rem          => 4,
126                 N_Op_Multiply     => 4,
127
128                 N_Op_Expon        => 5,
129                 N_Op_Abs          => 5,
130                 N_Op_Not          => 5,
131
132                 others            => 6);
133
134    procedure Sprint_Left_Opnd (N : Node_Id);
135    --  Print left operand of operator, parenthesizing if necessary
136
137    procedure Sprint_Right_Opnd (N : Node_Id);
138    --  Print right operand of operator, parenthesizing if necessary
139
140    -----------------------
141    -- Local Subprograms --
142    -----------------------
143
144    procedure Col_Check (N : Nat);
145    --  Check that at least N characters remain on current line, and if not,
146    --  then start an extra line with two characters extra indentation for
147    --  continuing text on the next line.
148
149    procedure Extra_Blank_Line;
150    --  In some situations we write extra blank lines to separate the generated
151    --  code to make it more readable. However, these extra blank lines are not
152    --  generated in Dump_Source_Text mode, since there the source text lines
153    --  output with preceding blank lines are quite sufficient as separators.
154    --  This procedure writes a blank line if Dump_Source_Text is False.
155
156    procedure Indent_Annull;
157    --  Causes following call to Write_Indent to be ignored. This is used when
158    --  a higher level node wants to stop a lower level node from starting a
159    --  new line, when it would otherwise be inclined to do so (e.g. the case
160    --  of an accept statement called from an accept alternative with a guard)
161
162    procedure Indent_Begin;
163    --  Increase indentation level
164
165    procedure Indent_End;
166    --  Decrease indentation level
167
168    procedure Print_Debug_Line (S : String);
169    --  Used to print output lines in Debug_Generated_Code mode (this is used
170    --  as the argument for a call to Set_Special_Output in package Output).
171
172    procedure Process_TFAI_RR_Flags (Nod : Node_Id);
173    --  Given a divide, multiplication or division node, check the flags
174    --  Treat_Fixed_As_Integer and Rounded_Flags, and if set, output the
175    --  appropriate special syntax characters (# and @).
176
177    procedure Set_Debug_Sloc;
178    --  If Dump_Node is non-empty, this routine sets the appropriate value
179    --  in its Sloc field, from the current location in the debug source file
180    --  that is currently being written.
181
182    procedure Sprint_And_List (List : List_Id);
183    --  Print the given list with items separated by vertical "and"
184
185    procedure Sprint_Bar_List (List : List_Id);
186    --  Print the given list with items separated by vertical bars
187
188    procedure Sprint_End_Label
189      (Node    : Node_Id;
190       Default : Node_Id);
191    --  Print the end label for a Handled_Sequence_Of_Statements in a body.
192    --  If there is not end label, use the defining identifier of the enclosing
193    --  construct. If the end label is present, treat it as a reference to the
194    --  defining entity of the construct: this guarantees that it carries the
195    --  proper sloc information for debugging purposes.
196
197    procedure Sprint_Node_Actual (Node : Node_Id);
198    --  This routine prints its node argument. It is a lower level routine than
199    --  Sprint_Node, in that it does not bother about rewritten trees.
200
201    procedure Sprint_Node_Sloc (Node : Node_Id);
202    --  Like Sprint_Node, but in addition, in Debug_Generated_Code mode,
203    --  sets the Sloc of the current debug node to be a copy of the Sloc
204    --  of the sprinted node Node. Note that this is done after printing
205    --  Node, so that the Sloc is the proper updated value for the debug file.
206
207    procedure Update_Itype (Node : Node_Id);
208    --  Update the Sloc of an itype that is not attached to the tree, when
209    --  debugging expanded code. This routine is called from nodes whose
210    --  type can be an Itype, such as defining_identifiers that may be of
211    --  an anonymous access type, or ranges in slices.
212
213    procedure Write_Char_Sloc (C : Character);
214    --  Like Write_Char, except that if C is non-blank, Set_Debug_Sloc is
215    --  called to ensure that the current node has a proper Sloc set.
216
217    procedure Write_Condition_And_Reason (Node : Node_Id);
218    --  Write Condition and Reason codes of Raise_xxx_Error node
219
220    procedure Write_Corresponding_Source (S : String);
221    --  If S is a string with a single keyword (possibly followed by a space),
222    --  and if the next non-comment non-blank source line matches this keyword,
223    --  then output all source lines up to this matching line.
224
225    procedure Write_Discr_Specs (N : Node_Id);
226    --  Output discriminant specification for node, which is any of the type
227    --  declarations that can have discriminants.
228
229    procedure Write_Ekind (E : Entity_Id);
230    --  Write the String corresponding to the Ekind without "E_"
231
232    procedure Write_Id (N : Node_Id);
233    --  N is a node with a Chars field. This procedure writes the name that
234    --  will be used in the generated code associated with the name. For a
235    --  node with no associated entity, this is simply the Chars field. For
236    --  the case where there is an entity associated with the node, we print
237    --  the name associated with the entity (since it may have been encoded).
238    --  One other special case is that an entity has an active external name
239    --  (i.e. an external name present with no address clause), then this
240    --  external name is output. This procedure also deals with outputting
241    --  declarations of referenced itypes, if not output earlier.
242
243    function Write_Identifiers (Node : Node_Id) return Boolean;
244    --  Handle node where the grammar has a list of defining identifiers, but
245    --  the tree has a separate declaration for each identifier. Handles the
246    --  printing of the defining identifier, and returns True if the type and
247    --  initialization information is to be printed, False if it is to be
248    --  skipped (the latter case happens when printing defining identifiers
249    --  other than the first in the original tree output case).
250
251    procedure Write_Implicit_Def (E : Entity_Id);
252    pragma Warnings (Off, Write_Implicit_Def);
253    --  Write the definition of the implicit type E according to its Ekind
254    --  For now a debugging procedure, but might be used in the future.
255
256    procedure Write_Indent;
257    --  Start a new line and write indentation spacing
258
259    function Write_Indent_Identifiers (Node : Node_Id) return Boolean;
260    --  Like Write_Identifiers except that each new printed declaration
261    --  is at the start of a new line.
262
263    function Write_Indent_Identifiers_Sloc (Node : Node_Id) return Boolean;
264    --  Like Write_Indent_Identifiers except that in Debug_Generated_Code
265    --  mode, the Sloc of the current debug node is set to point to the
266    --  first output identifier.
267
268    procedure Write_Indent_Str (S : String);
269    --  Start a new line and write indent spacing followed by given string
270
271    procedure Write_Indent_Str_Sloc (S : String);
272    --  Like Write_Indent_Str, but in addition, in Debug_Generated_Code mode,
273    --  the Sloc of the current node is set to the first non-blank character
274    --  in the string S.
275
276    procedure Write_Itype (Typ : Entity_Id);
277    --  If Typ is an Itype that has not been written yet, write it. If Typ is
278    --  any other kind of entity or tree node, the call is ignored.
279
280    procedure Write_Name_With_Col_Check (N : Name_Id);
281    --  Write name (using Write_Name) with initial column check, and possible
282    --  initial Write_Indent (to get new line) if current line is too full.
283
284    procedure Write_Name_With_Col_Check_Sloc (N : Name_Id);
285    --  Like Write_Name_With_Col_Check but in addition, in Debug_Generated_Code
286    --  mode, sets Sloc of current debug node to first character of name.
287
288    procedure Write_Operator (N : Node_Id; S : String);
289    --  Like Write_Str_Sloc, used for operators, encloses the string in
290    --  characters {} if the Do_Overflow flag is set on the node N.
291
292    procedure Write_Param_Specs (N : Node_Id);
293    --  Output parameter specifications for node (which is either a function
294    --  or procedure specification with a Parameter_Specifications field)
295
296    procedure Write_Rewrite_Str (S : String);
297    --  Writes out a string (typically containing <<< or >>>}) for a node
298    --  created by rewriting the tree. Suppressed if we are outputting the
299    --  generated code only, since in this case we don't specially mark nodes
300    --  created by rewriting).
301
302    procedure Write_Source_Line (L : Physical_Line_Number);
303    --  If writing of interspersed source lines is enabled, then write the given
304    --  line from the source file, preceded by Eol, then an extra blank line if
305    --  the line has at least one blank, is not a comment and is not line one,
306    --  then "--" and the line number followed by period followed by text of the
307    --  source line (without terminating Eol). If interspersed source line
308    --  output not enabled, then the call has no effect.
309
310    procedure Write_Source_Lines (L : Physical_Line_Number);
311    --  If writing of interspersed source lines is enabled, then writes source
312    --  lines Last_Line_Printed + 1 .. L, and updates Last_Line_Printed. If
313    --  interspersed source line output not enabled, then call has no effect.
314
315    procedure Write_Str_Sloc (S : String);
316    --  Like Write_Str, but sets debug Sloc of current debug node to first
317    --  non-blank character if a current debug node is active.
318
319    procedure Write_Str_With_Col_Check (S : String);
320    --  Write string (using Write_Str) with initial column check, and possible
321    --  initial Write_Indent (to get new line) if current line is too full.
322
323    procedure Write_Str_With_Col_Check_Sloc (S : String);
324    --  Like Write_Str_With_Col_Check, but sets debug Sloc of current debug
325    --  node to first non-blank character if a current debug node is active.
326
327    procedure Write_Subprogram_Name (N : Node_Id);
328    --  N is the Name field of a function call or procedure statement call.
329    --  The effect of the call is to output the name, preceded by a $ if the
330    --  call is identified as an implicit call to a run time routine.
331
332    procedure Write_Uint_With_Col_Check (U : Uint; Format : UI_Format);
333    --  Write Uint (using UI_Write) with initial column check, and possible
334    --  initial Write_Indent (to get new line) if current line is too full.
335    --  The format parameter determines the output format (see UI_Write).
336
337    procedure Write_Uint_With_Col_Check_Sloc (U : Uint; Format : UI_Format);
338    --  Write Uint (using UI_Write) with initial column check, and possible
339    --  initial Write_Indent (to get new line) if current line is too full.
340    --  The format parameter determines the output format (see UI_Write).
341    --  In addition, in Debug_Generated_Code mode, sets the current node
342    --  Sloc to the first character of the output value.
343
344    procedure Write_Ureal_With_Col_Check_Sloc (U : Ureal);
345    --  Write Ureal (using same output format as UR_Write) with column checks
346    --  and a possible initial Write_Indent (to get new line) if current line
347    --  is too full. In addition, in Debug_Generated_Code mode, sets the
348    --  current node Sloc to the first character of the output value.
349
350    ---------------
351    -- Col_Check --
352    ---------------
353
354    procedure Col_Check (N : Nat) is
355    begin
356       if N + Column > Sprint_Line_Limit then
357          Write_Indent_Str ("  ");
358       end if;
359    end Col_Check;
360
361    ----------------------
362    -- Extra_Blank_Line --
363    ----------------------
364
365    procedure Extra_Blank_Line is
366    begin
367       if not Dump_Source_Text then
368          Write_Indent;
369       end if;
370    end Extra_Blank_Line;
371
372    -------------------
373    -- Indent_Annull --
374    -------------------
375
376    procedure Indent_Annull is
377    begin
378       Indent_Annull_Flag := True;
379    end Indent_Annull;
380
381    ------------------
382    -- Indent_Begin --
383    ------------------
384
385    procedure Indent_Begin is
386    begin
387       Indent := Indent + 3;
388    end Indent_Begin;
389
390    ----------------
391    -- Indent_End --
392    ----------------
393
394    procedure Indent_End is
395    begin
396       Indent := Indent - 3;
397    end Indent_End;
398
399    --------
400    -- pg --
401    --------
402
403    procedure pg (Arg : Union_Id) is
404    begin
405       Dump_Generated_Only := True;
406       Dump_Original_Only := False;
407       Current_Source_File := No_Source_File;
408
409       if Arg in List_Range then
410          Sprint_Node_List (List_Id (Arg));
411
412       elsif Arg in Node_Range then
413          Sprint_Node (Node_Id (Arg));
414
415       else
416          null;
417       end if;
418
419       Write_Eol;
420    end pg;
421
422    --------
423    -- po --
424    --------
425
426    procedure po (Arg : Union_Id) is
427    begin
428       Dump_Generated_Only := False;
429       Dump_Original_Only := True;
430       Current_Source_File := No_Source_File;
431
432       if Arg in List_Range then
433          Sprint_Node_List (List_Id (Arg));
434
435       elsif Arg in Node_Range then
436          Sprint_Node (Node_Id (Arg));
437
438       else
439          null;
440       end if;
441
442       Write_Eol;
443    end po;
444
445    ----------------------
446    -- Print_Debug_Line --
447    ----------------------
448
449    procedure Print_Debug_Line (S : String) is
450    begin
451       Write_Debug_Line (S, Debug_Sloc);
452    end Print_Debug_Line;
453
454    ---------------------------
455    -- Process_TFAI_RR_Flags --
456    ---------------------------
457
458    procedure Process_TFAI_RR_Flags (Nod : Node_Id) is
459    begin
460       if Treat_Fixed_As_Integer (Nod) then
461          Write_Char ('#');
462       end if;
463
464       if Rounded_Result (Nod) then
465          Write_Char ('@');
466       end if;
467    end Process_TFAI_RR_Flags;
468
469    --------
470    -- ps --
471    --------
472
473    procedure ps (Arg : Union_Id) is
474    begin
475       Dump_Generated_Only := False;
476       Dump_Original_Only := False;
477       Current_Source_File := No_Source_File;
478
479       if Arg in List_Range then
480          Sprint_Node_List (List_Id (Arg));
481
482       elsif Arg in Node_Range then
483          Sprint_Node (Node_Id (Arg));
484
485       else
486          null;
487       end if;
488
489       Write_Eol;
490    end ps;
491
492    --------------------
493    -- Set_Debug_Sloc --
494    --------------------
495
496    procedure Set_Debug_Sloc is
497    begin
498       if Debug_Generated_Code and then Present (Dump_Node) then
499          Set_Sloc (Dump_Node, Debug_Sloc + Source_Ptr (Column - 1));
500          Dump_Node := Empty;
501       end if;
502    end Set_Debug_Sloc;
503
504    -----------------
505    -- Source_Dump --
506    -----------------
507
508    procedure Source_Dump is
509
510       procedure Underline;
511       --  Put underline under string we just printed
512
513       ---------------
514       -- Underline --
515       ---------------
516
517       procedure Underline is
518          Col : constant Int := Column;
519
520       begin
521          Write_Eol;
522
523          while Col > Column loop
524             Write_Char ('-');
525          end loop;
526
527          Write_Eol;
528       end Underline;
529
530    --  Start of processing for Source_Dump
531
532    begin
533       Dump_Generated_Only := Debug_Flag_G or
534                              Print_Generated_Code or
535                              Debug_Generated_Code;
536       Dump_Original_Only  := Debug_Flag_O;
537       Dump_Freeze_Null    := Debug_Flag_S or Debug_Flag_G;
538
539       --  Note that we turn off the tree dump flags immediately, before
540       --  starting the dump. This avoids generating two copies of the dump
541       --  if an abort occurs after printing the dump, and more importantly,
542       --  avoids an infinite loop if an abort occurs during the dump.
543
544       if Debug_Flag_Z then
545          Current_Source_File := No_Source_File;
546          Debug_Flag_Z := False;
547          Write_Eol;
548          Write_Eol;
549          Write_Str ("Source recreated from tree of Standard (spec)");
550          Underline;
551          Sprint_Node (Standard_Package_Node);
552          Write_Eol;
553          Write_Eol;
554       end if;
555
556       if Debug_Flag_S or Dump_Generated_Only or Dump_Original_Only then
557          Debug_Flag_G := False;
558          Debug_Flag_O := False;
559          Debug_Flag_S := False;
560
561          --  Dump requested units
562
563          for U in Main_Unit .. Last_Unit loop
564             Current_Source_File := Source_Index (U);
565
566             --  Dump all units if -gnatdf set, otherwise we dump only
567             --  the source files that are in the extended main source.
568
569             if Debug_Flag_F
570               or else In_Extended_Main_Source_Unit (Cunit_Entity (U))
571             then
572                --  If we are generating debug files, setup to write them
573
574                if Debug_Generated_Code then
575                   Set_Special_Output (Print_Debug_Line'Access);
576                   Create_Debug_Source (Source_Index (U), Debug_Sloc);
577                   Write_Source_Line (1);
578                   Last_Line_Printed := 1;
579                   Sprint_Node (Cunit (U));
580                   Write_Source_Lines (Last_Source_Line (Current_Source_File));
581                   Write_Eol;
582                   Close_Debug_Source;
583                   Set_Special_Output (null);
584
585                --  Normal output to standard output file
586
587                else
588                   Write_Str ("Source recreated from tree for ");
589                   Write_Unit_Name (Unit_Name (U));
590                   Underline;
591                   Write_Source_Line (1);
592                   Last_Line_Printed := 1;
593                   Sprint_Node (Cunit (U));
594                   Write_Source_Lines (Last_Source_Line (Current_Source_File));
595                   Write_Eol;
596                   Write_Eol;
597                end if;
598             end if;
599          end loop;
600       end if;
601    end Source_Dump;
602
603    ---------------------
604    -- Sprint_And_List --
605    ---------------------
606
607    procedure Sprint_And_List (List : List_Id) is
608       Node : Node_Id;
609    begin
610       if Is_Non_Empty_List (List) then
611          Node := First (List);
612          loop
613             Sprint_Node (Node);
614             Next (Node);
615             exit when Node = Empty;
616             Write_Str (" and ");
617          end loop;
618       end if;
619    end Sprint_And_List;
620
621    ---------------------
622    -- Sprint_Bar_List --
623    ---------------------
624
625    procedure Sprint_Bar_List (List : List_Id) is
626       Node : Node_Id;
627    begin
628       if Is_Non_Empty_List (List) then
629          Node := First (List);
630          loop
631             Sprint_Node (Node);
632             Next (Node);
633             exit when Node = Empty;
634             Write_Str (" | ");
635          end loop;
636       end if;
637    end Sprint_Bar_List;
638
639    ----------------------
640    -- Sprint_End_Label --
641    ----------------------
642
643    procedure Sprint_End_Label
644      (Node    : Node_Id;
645       Default : Node_Id)
646    is
647    begin
648       if Present (Node)
649         and then Present (End_Label (Node))
650         and then Is_Entity_Name (End_Label (Node))
651       then
652          Set_Entity (End_Label (Node), Default);
653
654          --  For a function whose name is an operator, use the qualified name
655          --  created for the defining entity.
656
657          if Nkind (End_Label (Node)) = N_Operator_Symbol then
658             Set_Chars (End_Label (Node), Chars (Default));
659          end if;
660
661          Sprint_Node (End_Label (Node));
662       else
663          Sprint_Node (Default);
664       end if;
665    end Sprint_End_Label;
666
667    -----------------------
668    -- Sprint_Comma_List --
669    -----------------------
670
671    procedure Sprint_Comma_List (List : List_Id) is
672       Node : Node_Id;
673
674    begin
675       if Is_Non_Empty_List (List) then
676          Node := First (List);
677          loop
678             Sprint_Node (Node);
679             Next (Node);
680             exit when Node = Empty;
681
682             if not Is_Rewrite_Insertion (Node)
683               or else not Dump_Original_Only
684             then
685                Write_Str (", ");
686             end if;
687          end loop;
688       end if;
689    end Sprint_Comma_List;
690
691    --------------------------
692    -- Sprint_Indented_List --
693    --------------------------
694
695    procedure Sprint_Indented_List (List : List_Id) is
696    begin
697       Indent_Begin;
698       Sprint_Node_List (List);
699       Indent_End;
700    end Sprint_Indented_List;
701
702    ---------------------
703    -- Sprint_Left_Opnd --
704    ---------------------
705
706    procedure Sprint_Left_Opnd (N : Node_Id) is
707       Opnd : constant Node_Id := Left_Opnd (N);
708
709    begin
710       if Paren_Count (Opnd) /= 0
711         or else Op_Prec (Nkind (Opnd)) >= Op_Prec (Nkind (N))
712       then
713          Sprint_Node (Opnd);
714
715       else
716          Write_Char ('(');
717          Sprint_Node (Opnd);
718          Write_Char (')');
719       end if;
720    end Sprint_Left_Opnd;
721
722    -----------------
723    -- Sprint_Node --
724    -----------------
725
726    procedure Sprint_Node (Node : Node_Id) is
727    begin
728       if Is_Rewrite_Insertion (Node) then
729          if not Dump_Original_Only then
730
731             --  For special cases of nodes that always output <<< >>>
732             --  do not duplicate the output at this point.
733
734             if Nkind (Node) = N_Freeze_Entity
735               or else Nkind (Node) = N_Implicit_Label_Declaration
736             then
737                Sprint_Node_Actual (Node);
738
739             --  Normal case where <<< >>> may be required
740
741             else
742                Write_Rewrite_Str ("<<<");
743                Sprint_Node_Actual (Node);
744                Write_Rewrite_Str (">>>");
745             end if;
746          end if;
747
748       elsif Is_Rewrite_Substitution (Node) then
749
750          --  Case of dump generated only
751
752          if Dump_Generated_Only then
753             Sprint_Node_Actual (Node);
754
755          --  Case of dump original only
756
757          elsif Dump_Original_Only then
758             Sprint_Node_Actual (Original_Node (Node));
759
760          --  Case of both being dumped
761
762          else
763             Sprint_Node_Actual (Original_Node (Node));
764             Write_Rewrite_Str ("<<<");
765             Sprint_Node_Actual (Node);
766             Write_Rewrite_Str (">>>");
767          end if;
768
769       else
770          Sprint_Node_Actual (Node);
771       end if;
772    end Sprint_Node;
773
774    ------------------------
775    -- Sprint_Node_Actual --
776    ------------------------
777
778    procedure Sprint_Node_Actual (Node : Node_Id) is
779       Save_Dump_Node : constant Node_Id := Dump_Node;
780
781    begin
782       if Node = Empty then
783          return;
784       end if;
785
786       for J in 1 .. Paren_Count (Node) loop
787          Write_Str_With_Col_Check ("(");
788       end loop;
789
790       --  Setup current dump node
791
792       Dump_Node := Node;
793
794       if Nkind (Node) in N_Subexpr
795         and then Do_Range_Check (Node)
796       then
797          Write_Str_With_Col_Check ("{");
798       end if;
799
800       --  Select print circuit based on node kind
801
802       case Nkind (Node) is
803
804          when N_Abort_Statement =>
805             Write_Indent_Str_Sloc ("abort ");
806             Sprint_Comma_List (Names (Node));
807             Write_Char (';');
808
809          when N_Abortable_Part =>
810             Set_Debug_Sloc;
811             Write_Str_Sloc ("abort ");
812             Sprint_Indented_List (Statements (Node));
813
814          when N_Abstract_Subprogram_Declaration =>
815             Write_Indent;
816             Sprint_Node (Specification (Node));
817             Write_Str_With_Col_Check (" is ");
818             Write_Str_Sloc ("abstract;");
819
820          when N_Accept_Alternative =>
821             Sprint_Node_List (Pragmas_Before (Node));
822
823             if Present (Condition (Node)) then
824                Write_Indent_Str ("when ");
825                Sprint_Node (Condition (Node));
826                Write_Str (" => ");
827                Indent_Annull;
828             end if;
829
830             Sprint_Node_Sloc (Accept_Statement (Node));
831             Sprint_Node_List (Statements (Node));
832
833          when N_Accept_Statement =>
834             Write_Indent_Str_Sloc ("accept ");
835             Write_Id (Entry_Direct_Name (Node));
836
837             if Present (Entry_Index (Node)) then
838                Write_Str_With_Col_Check (" (");
839                Sprint_Node (Entry_Index (Node));
840                Write_Char (')');
841             end if;
842
843             Write_Param_Specs (Node);
844
845             if Present (Handled_Statement_Sequence (Node)) then
846                Write_Str_With_Col_Check (" do");
847                Sprint_Node (Handled_Statement_Sequence (Node));
848                Write_Indent_Str ("end ");
849                Write_Id (Entry_Direct_Name (Node));
850             end if;
851
852             Write_Char (';');
853
854          when N_Access_Definition =>
855
856             --  Ada 2005 (AI-254)
857
858             if Present (Access_To_Subprogram_Definition (Node)) then
859                Sprint_Node (Access_To_Subprogram_Definition (Node));
860             else
861                --  Ada 2005 (AI-231)
862
863                if Null_Exclusion_Present (Node) then
864                   Write_Str ("not null ");
865                end if;
866
867                Write_Str_With_Col_Check_Sloc ("access ");
868
869                if All_Present (Node) then
870                   Write_Str ("all ");
871                elsif Constant_Present (Node) then
872                   Write_Str ("constant ");
873                end if;
874
875                Sprint_Node (Subtype_Mark (Node));
876             end if;
877
878          when N_Access_Function_Definition =>
879
880             --  Ada 2005 (AI-231)
881
882             if Null_Exclusion_Present (Node) then
883                Write_Str ("not null ");
884             end if;
885
886             Write_Str_With_Col_Check_Sloc ("access ");
887
888             if Protected_Present (Node) then
889                Write_Str_With_Col_Check ("protected ");
890             end if;
891
892             Write_Str_With_Col_Check ("function");
893             Write_Param_Specs (Node);
894             Write_Str_With_Col_Check (" return ");
895             Sprint_Node (Result_Definition (Node));
896
897          when N_Access_Procedure_Definition =>
898
899             --  Ada 2005 (AI-231)
900
901             if Null_Exclusion_Present (Node) then
902                Write_Str ("not null ");
903             end if;
904
905             Write_Str_With_Col_Check_Sloc ("access ");
906
907             if Protected_Present (Node) then
908                Write_Str_With_Col_Check ("protected ");
909             end if;
910
911             Write_Str_With_Col_Check ("procedure");
912             Write_Param_Specs (Node);
913
914          when N_Access_To_Object_Definition =>
915             Write_Str_With_Col_Check_Sloc ("access ");
916
917             if All_Present (Node) then
918                Write_Str_With_Col_Check ("all ");
919             elsif Constant_Present (Node) then
920                Write_Str_With_Col_Check ("constant ");
921             end if;
922
923             --  Ada 2005 (AI-231)
924
925             if Null_Exclusion_Present (Node) then
926                Write_Str ("not null ");
927             end if;
928
929             Sprint_Node (Subtype_Indication (Node));
930
931          when N_Aggregate =>
932             if Null_Record_Present (Node) then
933                Write_Str_With_Col_Check_Sloc ("(null record)");
934
935             else
936                Write_Str_With_Col_Check_Sloc ("(");
937
938                if Present (Expressions (Node)) then
939                   Sprint_Comma_List (Expressions (Node));
940
941                   if Present (Component_Associations (Node))
942                     and then not Is_Empty_List (Component_Associations (Node))
943                   then
944                      Write_Str (", ");
945                   end if;
946                end if;
947
948                if Present (Component_Associations (Node))
949                  and then not Is_Empty_List (Component_Associations (Node))
950                then
951                   Indent_Begin;
952
953                   declare
954                      Nd : Node_Id;
955
956                   begin
957                      Nd := First (Component_Associations (Node));
958
959                      loop
960                         Write_Indent;
961                         Sprint_Node (Nd);
962                         Next (Nd);
963                         exit when No (Nd);
964
965                         if not Is_Rewrite_Insertion (Nd)
966                           or else not Dump_Original_Only
967                         then
968                            Write_Str (", ");
969                         end if;
970                      end loop;
971                   end;
972
973                   Indent_End;
974                end if;
975
976                Write_Char (')');
977             end if;
978
979          when N_Allocator =>
980             Write_Str_With_Col_Check_Sloc ("new ");
981
982             --  Ada 2005 (AI-231)
983
984             if Null_Exclusion_Present (Node) then
985                Write_Str ("not null ");
986             end if;
987
988             Sprint_Node (Expression (Node));
989
990             if Present (Storage_Pool (Node)) then
991                Write_Str_With_Col_Check ("[storage_pool = ");
992                Sprint_Node (Storage_Pool (Node));
993                Write_Char (']');
994             end if;
995
996          when N_And_Then =>
997             Sprint_Left_Opnd (Node);
998             Write_Str_Sloc (" and then ");
999             Sprint_Right_Opnd (Node);
1000
1001          when N_At_Clause =>
1002             Write_Indent_Str_Sloc ("for ");
1003             Write_Id (Identifier (Node));
1004             Write_Str_With_Col_Check (" use at ");
1005             Sprint_Node (Expression (Node));
1006             Write_Char (';');
1007
1008          when N_Assignment_Statement =>
1009             Write_Indent;
1010             Sprint_Node (Name (Node));
1011             Write_Str_Sloc (" := ");
1012             Sprint_Node (Expression (Node));
1013             Write_Char (';');
1014
1015          when N_Asynchronous_Select =>
1016             Write_Indent_Str_Sloc ("select");
1017             Indent_Begin;
1018             Sprint_Node (Triggering_Alternative (Node));
1019             Indent_End;
1020
1021             --  Note: let the printing of Abortable_Part handle outputting
1022             --  the ABORT keyword, so that the Sloc can be set correctly.
1023
1024             Write_Indent_Str ("then ");
1025             Sprint_Node (Abortable_Part (Node));
1026             Write_Indent_Str ("end select;");
1027
1028          when N_Attribute_Definition_Clause =>
1029             Write_Indent_Str_Sloc ("for ");
1030             Sprint_Node (Name (Node));
1031             Write_Char (''');
1032             Write_Name_With_Col_Check (Chars (Node));
1033             Write_Str_With_Col_Check (" use ");
1034             Sprint_Node (Expression (Node));
1035             Write_Char (';');
1036
1037          when N_Attribute_Reference =>
1038             if Is_Procedure_Attribute_Name (Attribute_Name (Node)) then
1039                Write_Indent;
1040             end if;
1041
1042             Sprint_Node (Prefix (Node));
1043             Write_Char_Sloc (''');
1044             Write_Name_With_Col_Check (Attribute_Name (Node));
1045             Sprint_Paren_Comma_List (Expressions (Node));
1046
1047             if Is_Procedure_Attribute_Name (Attribute_Name (Node)) then
1048                Write_Char (';');
1049             end if;
1050
1051          when N_Block_Statement =>
1052             Write_Indent;
1053
1054             if Present (Identifier (Node))
1055               and then (not Has_Created_Identifier (Node)
1056                           or else not Dump_Original_Only)
1057             then
1058                Write_Rewrite_Str ("<<<");
1059                Write_Id (Identifier (Node));
1060                Write_Str (" : ");
1061                Write_Rewrite_Str (">>>");
1062             end if;
1063
1064             if Present (Declarations (Node)) then
1065                Write_Str_With_Col_Check_Sloc ("declare");
1066                Sprint_Indented_List (Declarations (Node));
1067                Write_Indent;
1068             end if;
1069
1070             Write_Str_With_Col_Check_Sloc ("begin");
1071             Sprint_Node (Handled_Statement_Sequence (Node));
1072             Write_Indent_Str ("end");
1073
1074             if Present (Identifier (Node))
1075               and then (not Has_Created_Identifier (Node)
1076                           or else not Dump_Original_Only)
1077             then
1078                Write_Rewrite_Str ("<<<");
1079                Write_Char (' ');
1080                Write_Id (Identifier (Node));
1081                Write_Rewrite_Str (">>>");
1082             end if;
1083
1084             Write_Char (';');
1085
1086          when N_Case_Statement =>
1087             Write_Indent_Str_Sloc ("case ");
1088             Sprint_Node (Expression (Node));
1089             Write_Str (" is");
1090             Sprint_Indented_List (Alternatives (Node));
1091             Write_Indent_Str ("end case;");
1092
1093          when N_Case_Statement_Alternative =>
1094             Write_Indent_Str_Sloc ("when ");
1095             Sprint_Bar_List (Discrete_Choices (Node));
1096             Write_Str (" => ");
1097             Sprint_Indented_List (Statements (Node));
1098
1099          when N_Character_Literal =>
1100             if Column > Sprint_Line_Limit - 2 then
1101                Write_Indent_Str ("  ");
1102             end if;
1103
1104             Write_Char_Sloc (''');
1105             Write_Char_Code (UI_To_CC (Char_Literal_Value (Node)));
1106             Write_Char (''');
1107
1108          when N_Code_Statement =>
1109             Write_Indent;
1110             Set_Debug_Sloc;
1111             Sprint_Node (Expression (Node));
1112             Write_Char (';');
1113
1114          when N_Compilation_Unit =>
1115             Sprint_Node_List (Context_Items (Node));
1116             Sprint_Opt_Node_List (Declarations (Aux_Decls_Node (Node)));
1117
1118             if Private_Present (Node) then
1119                Write_Indent_Str ("private ");
1120                Indent_Annull;
1121             end if;
1122
1123             Sprint_Node_Sloc (Unit (Node));
1124
1125             if Present (Actions (Aux_Decls_Node (Node)))
1126                  or else
1127                Present (Pragmas_After (Aux_Decls_Node (Node)))
1128             then
1129                Write_Indent;
1130             end if;
1131
1132             Sprint_Opt_Node_List (Actions (Aux_Decls_Node (Node)));
1133             Sprint_Opt_Node_List (Pragmas_After (Aux_Decls_Node (Node)));
1134
1135          when N_Compilation_Unit_Aux =>
1136             null; -- nothing to do, never used, see above
1137
1138          when N_Component_Association =>
1139             Set_Debug_Sloc;
1140             Sprint_Bar_List (Choices (Node));
1141             Write_Str (" => ");
1142
1143             --  Ada 2005 (AI-287): Print the box if present
1144
1145             if Box_Present (Node) then
1146                Write_Str_With_Col_Check ("<>");
1147             else
1148                Sprint_Node (Expression (Node));
1149             end if;
1150
1151          when N_Component_Clause =>
1152             Write_Indent;
1153             Sprint_Node (Component_Name (Node));
1154             Write_Str_Sloc (" at ");
1155             Sprint_Node (Position (Node));
1156             Write_Char (' ');
1157             Write_Str_With_Col_Check ("range ");
1158             Sprint_Node (First_Bit (Node));
1159             Write_Str (" .. ");
1160             Sprint_Node (Last_Bit (Node));
1161             Write_Char (';');
1162
1163          when N_Component_Definition =>
1164             Set_Debug_Sloc;
1165
1166             --  Ada 2005 (AI-230): Access definition components
1167
1168             if Present (Access_Definition (Node)) then
1169                Sprint_Node (Access_Definition (Node));
1170
1171             elsif Present (Subtype_Indication (Node)) then
1172                if Aliased_Present (Node) then
1173                   Write_Str_With_Col_Check ("aliased ");
1174                end if;
1175
1176                --  Ada 2005 (AI-231)
1177
1178                if Null_Exclusion_Present (Node) then
1179                   Write_Str (" not null ");
1180                end if;
1181
1182                Sprint_Node (Subtype_Indication (Node));
1183
1184             else
1185                Write_Str (" ??? ");
1186             end if;
1187
1188          when N_Component_Declaration =>
1189             if Write_Indent_Identifiers_Sloc (Node) then
1190                Write_Str (" : ");
1191                Sprint_Node (Component_Definition (Node));
1192
1193                if Present (Expression (Node)) then
1194                   Write_Str (" := ");
1195                   Sprint_Node (Expression (Node));
1196                end if;
1197
1198                Write_Char (';');
1199             end if;
1200
1201          when N_Component_List =>
1202             if Null_Present (Node) then
1203                Indent_Begin;
1204                Write_Indent_Str_Sloc ("null");
1205                Write_Char (';');
1206                Indent_End;
1207
1208             else
1209                Set_Debug_Sloc;
1210                Sprint_Indented_List (Component_Items (Node));
1211                Sprint_Node (Variant_Part (Node));
1212             end if;
1213
1214          when N_Conditional_Entry_Call =>
1215             Write_Indent_Str_Sloc ("select");
1216             Indent_Begin;
1217             Sprint_Node (Entry_Call_Alternative (Node));
1218             Indent_End;
1219             Write_Indent_Str ("else");
1220             Sprint_Indented_List (Else_Statements (Node));
1221             Write_Indent_Str ("end select;");
1222
1223          when N_Conditional_Expression =>
1224             declare
1225                Condition : constant Node_Id := First (Expressions (Node));
1226                Then_Expr : constant Node_Id := Next (Condition);
1227                Else_Expr : constant Node_Id := Next (Then_Expr);
1228             begin
1229                Write_Str_With_Col_Check_Sloc ("(if ");
1230                Sprint_Node (Condition);
1231                Write_Str_With_Col_Check (" then ");
1232                Sprint_Node (Then_Expr);
1233                Write_Str_With_Col_Check (" else ");
1234                Sprint_Node (Else_Expr);
1235                Write_Char (')');
1236             end;
1237
1238          when N_Constrained_Array_Definition =>
1239             Write_Str_With_Col_Check_Sloc ("array ");
1240             Sprint_Paren_Comma_List (Discrete_Subtype_Definitions (Node));
1241             Write_Str (" of ");
1242
1243             Sprint_Node (Component_Definition (Node));
1244
1245          when N_Decimal_Fixed_Point_Definition =>
1246             Write_Str_With_Col_Check_Sloc (" delta ");
1247             Sprint_Node (Delta_Expression (Node));
1248             Write_Str_With_Col_Check ("digits ");
1249             Sprint_Node (Digits_Expression (Node));
1250             Sprint_Opt_Node (Real_Range_Specification (Node));
1251
1252          when N_Defining_Character_Literal =>
1253             Write_Name_With_Col_Check_Sloc (Chars (Node));
1254
1255          when N_Defining_Identifier =>
1256             Set_Debug_Sloc;
1257             Write_Id (Node);
1258
1259          when N_Defining_Operator_Symbol =>
1260             Write_Name_With_Col_Check_Sloc (Chars (Node));
1261
1262          when N_Defining_Program_Unit_Name =>
1263             Set_Debug_Sloc;
1264             Sprint_Node (Name (Node));
1265             Write_Char ('.');
1266             Write_Id (Defining_Identifier (Node));
1267
1268          when N_Delay_Alternative =>
1269             Sprint_Node_List (Pragmas_Before (Node));
1270
1271             if Present (Condition (Node)) then
1272                Write_Indent;
1273                Write_Str_With_Col_Check ("when ");
1274                Sprint_Node (Condition (Node));
1275                Write_Str (" => ");
1276                Indent_Annull;
1277             end if;
1278
1279             Sprint_Node_Sloc (Delay_Statement (Node));
1280             Sprint_Node_List (Statements (Node));
1281
1282          when N_Delay_Relative_Statement =>
1283             Write_Indent_Str_Sloc ("delay ");
1284             Sprint_Node (Expression (Node));
1285             Write_Char (';');
1286
1287          when N_Delay_Until_Statement =>
1288             Write_Indent_Str_Sloc ("delay until ");
1289             Sprint_Node (Expression (Node));
1290             Write_Char (';');
1291
1292          when N_Delta_Constraint =>
1293             Write_Str_With_Col_Check_Sloc ("delta ");
1294             Sprint_Node (Delta_Expression (Node));
1295             Sprint_Opt_Node (Range_Constraint (Node));
1296
1297          when N_Derived_Type_Definition =>
1298             if Abstract_Present (Node) then
1299                Write_Str_With_Col_Check ("abstract ");
1300             end if;
1301
1302             Write_Str_With_Col_Check_Sloc ("new ");
1303
1304             --  Ada 2005 (AI-231)
1305
1306             if Null_Exclusion_Present (Node) then
1307                Write_Str_With_Col_Check ("not null ");
1308             end if;
1309
1310             Sprint_Node (Subtype_Indication (Node));
1311
1312             if Present (Interface_List (Node)) then
1313                Write_Str_With_Col_Check (" and ");
1314                Sprint_And_List (Interface_List (Node));
1315                Write_Str_With_Col_Check (" with ");
1316             end if;
1317
1318             if Present (Record_Extension_Part (Node)) then
1319                if No (Interface_List (Node)) then
1320                   Write_Str_With_Col_Check (" with ");
1321                end if;
1322
1323                Sprint_Node (Record_Extension_Part (Node));
1324             end if;
1325
1326          when N_Designator =>
1327             Sprint_Node (Name (Node));
1328             Write_Char_Sloc ('.');
1329             Write_Id (Identifier (Node));
1330
1331          when N_Digits_Constraint =>
1332             Write_Str_With_Col_Check_Sloc ("digits ");
1333             Sprint_Node (Digits_Expression (Node));
1334             Sprint_Opt_Node (Range_Constraint (Node));
1335
1336          when N_Discriminant_Association =>
1337             Set_Debug_Sloc;
1338
1339             if Present (Selector_Names (Node)) then
1340                Sprint_Bar_List (Selector_Names (Node));
1341                Write_Str (" => ");
1342             end if;
1343
1344             Set_Debug_Sloc;
1345             Sprint_Node (Expression (Node));
1346
1347          when N_Discriminant_Specification =>
1348             Set_Debug_Sloc;
1349
1350             if Write_Identifiers (Node) then
1351                Write_Str (" : ");
1352
1353                if Null_Exclusion_Present (Node) then
1354                   Write_Str ("not null ");
1355                end if;
1356
1357                Sprint_Node (Discriminant_Type (Node));
1358
1359                if Present (Expression (Node)) then
1360                   Write_Str (" := ");
1361                   Sprint_Node (Expression (Node));
1362                end if;
1363             else
1364                Write_Str (", ");
1365             end if;
1366
1367          when N_Elsif_Part =>
1368             Write_Indent_Str_Sloc ("elsif ");
1369             Sprint_Node (Condition (Node));
1370             Write_Str_With_Col_Check (" then");
1371             Sprint_Indented_List (Then_Statements (Node));
1372
1373          when N_Empty =>
1374             null;
1375
1376          when N_Entry_Body =>
1377             Write_Indent_Str_Sloc ("entry ");
1378             Write_Id (Defining_Identifier (Node));
1379             Sprint_Node (Entry_Body_Formal_Part (Node));
1380             Write_Str_With_Col_Check (" is");
1381             Sprint_Indented_List (Declarations (Node));
1382             Write_Indent_Str ("begin");
1383             Sprint_Node (Handled_Statement_Sequence (Node));
1384             Write_Indent_Str ("end ");
1385             Write_Id (Defining_Identifier (Node));
1386             Write_Char (';');
1387
1388          when N_Entry_Body_Formal_Part =>
1389             if Present (Entry_Index_Specification (Node)) then
1390                Write_Str_With_Col_Check_Sloc (" (");
1391                Sprint_Node (Entry_Index_Specification (Node));
1392                Write_Char (')');
1393             end if;
1394
1395             Write_Param_Specs (Node);
1396             Write_Str_With_Col_Check_Sloc (" when ");
1397             Sprint_Node (Condition (Node));
1398
1399          when N_Entry_Call_Alternative =>
1400             Sprint_Node_List (Pragmas_Before (Node));
1401             Sprint_Node_Sloc (Entry_Call_Statement (Node));
1402             Sprint_Node_List (Statements (Node));
1403
1404          when N_Entry_Call_Statement =>
1405             Write_Indent;
1406             Sprint_Node_Sloc (Name (Node));
1407             Sprint_Opt_Paren_Comma_List (Parameter_Associations (Node));
1408             Write_Char (';');
1409
1410          when N_Entry_Declaration =>
1411             Write_Indent_Str_Sloc ("entry ");
1412             Write_Id (Defining_Identifier (Node));
1413
1414             if Present (Discrete_Subtype_Definition (Node)) then
1415                Write_Str_With_Col_Check (" (");
1416                Sprint_Node (Discrete_Subtype_Definition (Node));
1417                Write_Char (')');
1418             end if;
1419
1420             Write_Param_Specs (Node);
1421             Write_Char (';');
1422
1423          when N_Entry_Index_Specification =>
1424             Write_Str_With_Col_Check_Sloc ("for ");
1425             Write_Id (Defining_Identifier (Node));
1426             Write_Str_With_Col_Check (" in ");
1427             Sprint_Node (Discrete_Subtype_Definition (Node));
1428
1429          when N_Enumeration_Representation_Clause =>
1430             Write_Indent_Str_Sloc ("for ");
1431             Write_Id (Identifier (Node));
1432             Write_Str_With_Col_Check (" use ");
1433             Sprint_Node (Array_Aggregate (Node));
1434             Write_Char (';');
1435
1436          when N_Enumeration_Type_Definition =>
1437             Set_Debug_Sloc;
1438
1439             --  Skip attempt to print Literals field if it's not there and
1440             --  we are in package Standard (case of Character, which is
1441             --  handled specially (without an explicit literals list).
1442
1443             if Sloc (Node) > Standard_Location
1444               or else Present (Literals (Node))
1445             then
1446                Sprint_Paren_Comma_List (Literals (Node));
1447             end if;
1448
1449          when N_Error =>
1450             Write_Str_With_Col_Check_Sloc ("<error>");
1451
1452          when N_Exception_Declaration =>
1453             if Write_Indent_Identifiers (Node) then
1454                Write_Str_With_Col_Check (" : ");
1455
1456                if Is_Statically_Allocated (Defining_Identifier (Node)) then
1457                   Write_Str_With_Col_Check ("static ");
1458                end if;
1459
1460                Write_Str_Sloc ("exception");
1461
1462                if Present (Expression (Node)) then
1463                   Write_Str (" := ");
1464                   Sprint_Node (Expression (Node));
1465                end if;
1466
1467                Write_Char (';');
1468             end if;
1469
1470          when N_Exception_Handler =>
1471             Write_Indent_Str_Sloc ("when ");
1472
1473             if Present (Choice_Parameter (Node)) then
1474                Sprint_Node (Choice_Parameter (Node));
1475                Write_Str (" : ");
1476             end if;
1477
1478             Sprint_Bar_List (Exception_Choices (Node));
1479             Write_Str (" => ");
1480             Sprint_Indented_List (Statements (Node));
1481
1482          when N_Exception_Renaming_Declaration =>
1483             Write_Indent;
1484             Set_Debug_Sloc;
1485             Sprint_Node (Defining_Identifier (Node));
1486             Write_Str_With_Col_Check (" : exception renames ");
1487             Sprint_Node (Name (Node));
1488             Write_Char (';');
1489
1490          when N_Exit_Statement =>
1491             Write_Indent_Str_Sloc ("exit");
1492             Sprint_Opt_Node (Name (Node));
1493
1494             if Present (Condition (Node)) then
1495                Write_Str_With_Col_Check (" when ");
1496                Sprint_Node (Condition (Node));
1497             end if;
1498
1499             Write_Char (';');
1500
1501          when N_Expanded_Name =>
1502             Sprint_Node (Prefix (Node));
1503             Write_Char_Sloc ('.');
1504             Sprint_Node (Selector_Name (Node));
1505
1506          when N_Explicit_Dereference =>
1507             Sprint_Node (Prefix (Node));
1508             Write_Char_Sloc ('.');
1509             Write_Str_Sloc ("all");
1510
1511          when N_Extended_Return_Statement =>
1512             Write_Indent_Str_Sloc ("return ");
1513             Sprint_Node_List (Return_Object_Declarations (Node));
1514
1515             if Present (Handled_Statement_Sequence (Node)) then
1516                Write_Str_With_Col_Check (" do");
1517                Sprint_Node (Handled_Statement_Sequence (Node));
1518                Write_Indent_Str ("end return;");
1519             else
1520                Write_Indent_Str (";");
1521             end if;
1522
1523          when N_Extension_Aggregate =>
1524             Write_Str_With_Col_Check_Sloc ("(");
1525             Sprint_Node (Ancestor_Part (Node));
1526             Write_Str_With_Col_Check (" with ");
1527
1528             if Null_Record_Present (Node) then
1529                Write_Str_With_Col_Check ("null record");
1530             else
1531                if Present (Expressions (Node)) then
1532                   Sprint_Comma_List (Expressions (Node));
1533
1534                   if Present (Component_Associations (Node)) then
1535                      Write_Str (", ");
1536                   end if;
1537                end if;
1538
1539                if Present (Component_Associations (Node)) then
1540                   Sprint_Comma_List (Component_Associations (Node));
1541                end if;
1542             end if;
1543
1544             Write_Char (')');
1545
1546          when N_Floating_Point_Definition =>
1547             Write_Str_With_Col_Check_Sloc ("digits ");
1548             Sprint_Node (Digits_Expression (Node));
1549             Sprint_Opt_Node (Real_Range_Specification (Node));
1550
1551          when N_Formal_Decimal_Fixed_Point_Definition =>
1552             Write_Str_With_Col_Check_Sloc ("delta <> digits <>");
1553
1554          when N_Formal_Derived_Type_Definition =>
1555             Write_Str_With_Col_Check_Sloc ("new ");
1556             Sprint_Node (Subtype_Mark (Node));
1557
1558             if Present (Interface_List (Node)) then
1559                Write_Str_With_Col_Check (" and ");
1560                Sprint_And_List (Interface_List (Node));
1561             end if;
1562
1563             if Private_Present (Node) then
1564                Write_Str_With_Col_Check (" with private");
1565             end if;
1566
1567          when N_Formal_Abstract_Subprogram_Declaration =>
1568             Write_Indent_Str_Sloc ("with ");
1569             Sprint_Node (Specification (Node));
1570
1571             Write_Str_With_Col_Check (" is abstract");
1572
1573             if Box_Present (Node) then
1574                Write_Str_With_Col_Check (" <>");
1575             elsif Present (Default_Name (Node)) then
1576                Write_Str_With_Col_Check (" ");
1577                Sprint_Node (Default_Name (Node));
1578             end if;
1579
1580             Write_Char (';');
1581
1582          when N_Formal_Concrete_Subprogram_Declaration =>
1583             Write_Indent_Str_Sloc ("with ");
1584             Sprint_Node (Specification (Node));
1585
1586             if Box_Present (Node) then
1587                Write_Str_With_Col_Check (" is <>");
1588             elsif Present (Default_Name (Node)) then
1589                Write_Str_With_Col_Check (" is ");
1590                Sprint_Node (Default_Name (Node));
1591             end if;
1592
1593             Write_Char (';');
1594
1595          when N_Formal_Discrete_Type_Definition =>
1596             Write_Str_With_Col_Check_Sloc ("<>");
1597
1598          when N_Formal_Floating_Point_Definition =>
1599             Write_Str_With_Col_Check_Sloc ("digits <>");
1600
1601          when N_Formal_Modular_Type_Definition =>
1602             Write_Str_With_Col_Check_Sloc ("mod <>");
1603
1604          when N_Formal_Object_Declaration =>
1605             Set_Debug_Sloc;
1606
1607             if Write_Indent_Identifiers (Node) then
1608                Write_Str (" : ");
1609
1610                if In_Present (Node) then
1611                   Write_Str_With_Col_Check ("in ");
1612                end if;
1613
1614                if Out_Present (Node) then
1615                   Write_Str_With_Col_Check ("out ");
1616                end if;
1617
1618                if Present (Subtype_Mark (Node)) then
1619
1620                   --  Ada 2005 (AI-423): Formal object with null exclusion
1621
1622                   if Null_Exclusion_Present (Node) then
1623                      Write_Str ("not null ");
1624                   end if;
1625
1626                   Sprint_Node (Subtype_Mark (Node));
1627
1628                --  Ada 2005 (AI-423): Formal object with access definition
1629
1630                else
1631                   pragma Assert (Present (Access_Definition (Node)));
1632
1633                   Sprint_Node (Access_Definition (Node));
1634                end if;
1635
1636                if Present (Default_Expression (Node)) then
1637                   Write_Str (" := ");
1638                   Sprint_Node (Default_Expression (Node));
1639                end if;
1640
1641                Write_Char (';');
1642             end if;
1643
1644          when N_Formal_Ordinary_Fixed_Point_Definition =>
1645             Write_Str_With_Col_Check_Sloc ("delta <>");
1646
1647          when N_Formal_Package_Declaration =>
1648             Write_Indent_Str_Sloc ("with package ");
1649             Write_Id (Defining_Identifier (Node));
1650             Write_Str_With_Col_Check (" is new ");
1651             Sprint_Node (Name (Node));
1652             Write_Str_With_Col_Check (" (<>);");
1653
1654          when N_Formal_Private_Type_Definition =>
1655             if Abstract_Present (Node) then
1656                Write_Str_With_Col_Check ("abstract ");
1657             end if;
1658
1659             if Tagged_Present (Node) then
1660                Write_Str_With_Col_Check ("tagged ");
1661             end if;
1662
1663             if Limited_Present (Node) then
1664                Write_Str_With_Col_Check ("limited ");
1665             end if;
1666
1667             Write_Str_With_Col_Check_Sloc ("private");
1668
1669          when N_Formal_Signed_Integer_Type_Definition =>
1670             Write_Str_With_Col_Check_Sloc ("range <>");
1671
1672          when N_Formal_Type_Declaration =>
1673             Write_Indent_Str_Sloc ("type ");
1674             Write_Id (Defining_Identifier (Node));
1675
1676             if Present (Discriminant_Specifications (Node)) then
1677                Write_Discr_Specs (Node);
1678             elsif Unknown_Discriminants_Present (Node) then
1679                Write_Str_With_Col_Check ("(<>)");
1680             end if;
1681
1682             Write_Str_With_Col_Check (" is ");
1683             Sprint_Node (Formal_Type_Definition (Node));
1684             Write_Char (';');
1685
1686          when N_Free_Statement =>
1687             Write_Indent_Str_Sloc ("free ");
1688             Sprint_Node (Expression (Node));
1689             Write_Char (';');
1690
1691          when N_Freeze_Entity =>
1692             if Dump_Original_Only then
1693                null;
1694
1695             elsif Present (Actions (Node)) or else Dump_Freeze_Null then
1696                Write_Indent;
1697                Write_Rewrite_Str ("<<<");
1698                Write_Str_With_Col_Check_Sloc ("freeze ");
1699                Write_Id (Entity (Node));
1700                Write_Str (" [");
1701
1702                if No (Actions (Node)) then
1703                   Write_Char (']');
1704
1705                else
1706                   --  Output freeze actions. We increment Freeze_Indent during
1707                   --  this output to avoid generating extra blank lines before
1708                   --  any procedures included in the freeze actions.
1709
1710                   Freeze_Indent := Freeze_Indent + 1;
1711                   Sprint_Indented_List (Actions (Node));
1712                   Freeze_Indent := Freeze_Indent - 1;
1713                   Write_Indent_Str ("]");
1714                end if;
1715
1716                Write_Rewrite_Str (">>>");
1717             end if;
1718
1719          when N_Full_Type_Declaration =>
1720             Write_Indent_Str_Sloc ("type ");
1721             Sprint_Node (Defining_Identifier (Node));
1722             Write_Discr_Specs (Node);
1723             Write_Str_With_Col_Check (" is ");
1724             Sprint_Node (Type_Definition (Node));
1725             Write_Char (';');
1726
1727          when N_Function_Call =>
1728             Set_Debug_Sloc;
1729             Write_Subprogram_Name (Name (Node));
1730             Sprint_Opt_Paren_Comma_List (Parameter_Associations (Node));
1731
1732          when N_Function_Instantiation =>
1733             Write_Indent_Str_Sloc ("function ");
1734             Sprint_Node (Defining_Unit_Name (Node));
1735             Write_Str_With_Col_Check (" is new ");
1736             Sprint_Node (Name (Node));
1737             Sprint_Opt_Paren_Comma_List (Generic_Associations (Node));
1738             Write_Char (';');
1739
1740          when N_Function_Specification =>
1741             Write_Str_With_Col_Check_Sloc ("function ");
1742             Sprint_Node (Defining_Unit_Name (Node));
1743             Write_Param_Specs (Node);
1744             Write_Str_With_Col_Check (" return ");
1745
1746             --  Ada 2005 (AI-231)
1747
1748             if Nkind (Result_Definition (Node)) /= N_Access_Definition
1749               and then Null_Exclusion_Present (Node)
1750             then
1751                Write_Str (" not null ");
1752             end if;
1753
1754             Sprint_Node (Result_Definition (Node));
1755
1756          when N_Generic_Association =>
1757             Set_Debug_Sloc;
1758
1759             if Present (Selector_Name (Node)) then
1760                Sprint_Node (Selector_Name (Node));
1761                Write_Str (" => ");
1762             end if;
1763
1764             Sprint_Node (Explicit_Generic_Actual_Parameter (Node));
1765
1766          when N_Generic_Function_Renaming_Declaration =>
1767             Write_Indent_Str_Sloc ("generic function ");
1768             Sprint_Node (Defining_Unit_Name (Node));
1769             Write_Str_With_Col_Check (" renames ");
1770             Sprint_Node (Name (Node));
1771             Write_Char (';');
1772
1773          when N_Generic_Package_Declaration =>
1774             Extra_Blank_Line;
1775             Write_Indent_Str_Sloc ("generic ");
1776             Sprint_Indented_List (Generic_Formal_Declarations (Node));
1777             Write_Indent;
1778             Sprint_Node (Specification (Node));
1779             Write_Char (';');
1780
1781          when N_Generic_Package_Renaming_Declaration =>
1782             Write_Indent_Str_Sloc ("generic package ");
1783             Sprint_Node (Defining_Unit_Name (Node));
1784             Write_Str_With_Col_Check (" renames ");
1785             Sprint_Node (Name (Node));
1786             Write_Char (';');
1787
1788          when N_Generic_Procedure_Renaming_Declaration =>
1789             Write_Indent_Str_Sloc ("generic procedure ");
1790             Sprint_Node (Defining_Unit_Name (Node));
1791             Write_Str_With_Col_Check (" renames ");
1792             Sprint_Node (Name (Node));
1793             Write_Char (';');
1794
1795          when N_Generic_Subprogram_Declaration =>
1796             Extra_Blank_Line;
1797             Write_Indent_Str_Sloc ("generic ");
1798             Sprint_Indented_List (Generic_Formal_Declarations (Node));
1799             Write_Indent;
1800             Sprint_Node (Specification (Node));
1801             Write_Char (';');
1802
1803          when N_Goto_Statement =>
1804             Write_Indent_Str_Sloc ("goto ");
1805             Sprint_Node (Name (Node));
1806             Write_Char (';');
1807
1808             if Nkind (Next (Node)) = N_Label then
1809                Write_Indent;
1810             end if;
1811
1812          when N_Handled_Sequence_Of_Statements =>
1813             Set_Debug_Sloc;
1814             Sprint_Indented_List (Statements (Node));
1815
1816             if Present (Exception_Handlers (Node)) then
1817                Write_Indent_Str ("exception");
1818                Indent_Begin;
1819                Sprint_Node_List (Exception_Handlers (Node));
1820                Indent_End;
1821             end if;
1822
1823             if Present (At_End_Proc (Node)) then
1824                Write_Indent_Str ("at end");
1825                Indent_Begin;
1826                Write_Indent;
1827                Sprint_Node (At_End_Proc (Node));
1828                Write_Char (';');
1829                Indent_End;
1830             end if;
1831
1832          when N_Identifier =>
1833             Set_Debug_Sloc;
1834             Write_Id (Node);
1835
1836          when N_If_Statement =>
1837             Write_Indent_Str_Sloc ("if ");
1838             Sprint_Node (Condition (Node));
1839             Write_Str_With_Col_Check (" then");
1840             Sprint_Indented_List (Then_Statements (Node));
1841             Sprint_Opt_Node_List (Elsif_Parts (Node));
1842
1843             if Present (Else_Statements (Node)) then
1844                Write_Indent_Str ("else");
1845                Sprint_Indented_List (Else_Statements (Node));
1846             end if;
1847
1848             Write_Indent_Str ("end if;");
1849
1850          when N_Implicit_Label_Declaration =>
1851             if not Dump_Original_Only then
1852                Write_Indent;
1853                Write_Rewrite_Str ("<<<");
1854                Set_Debug_Sloc;
1855                Write_Id (Defining_Identifier (Node));
1856                Write_Str (" : ");
1857                Write_Str_With_Col_Check ("label");
1858                Write_Rewrite_Str (">>>");
1859             end if;
1860
1861          when N_In =>
1862             Sprint_Left_Opnd (Node);
1863             Write_Str_Sloc (" in ");
1864
1865             if Present (Right_Opnd (Node)) then
1866                Sprint_Right_Opnd (Node);
1867             else
1868                Sprint_Bar_List (Alternatives (Node));
1869             end if;
1870
1871          when N_Incomplete_Type_Declaration =>
1872             Write_Indent_Str_Sloc ("type ");
1873             Write_Id (Defining_Identifier (Node));
1874
1875             if Present (Discriminant_Specifications (Node)) then
1876                Write_Discr_Specs (Node);
1877             elsif Unknown_Discriminants_Present (Node) then
1878                Write_Str_With_Col_Check ("(<>)");
1879             end if;
1880
1881             Write_Char (';');
1882
1883          when N_Index_Or_Discriminant_Constraint =>
1884             Set_Debug_Sloc;
1885             Sprint_Paren_Comma_List (Constraints (Node));
1886
1887          when N_Indexed_Component =>
1888             Sprint_Node_Sloc (Prefix (Node));
1889             Sprint_Opt_Paren_Comma_List (Expressions (Node));
1890
1891          when N_Integer_Literal =>
1892             if Print_In_Hex (Node) then
1893                Write_Uint_With_Col_Check_Sloc (Intval (Node), Hex);
1894             else
1895                Write_Uint_With_Col_Check_Sloc (Intval (Node), Auto);
1896             end if;
1897
1898          when N_Iteration_Scheme =>
1899             if Present (Condition (Node)) then
1900                Write_Str_With_Col_Check_Sloc ("while ");
1901                Sprint_Node (Condition (Node));
1902             else
1903                Write_Str_With_Col_Check_Sloc ("for ");
1904                Sprint_Node (Loop_Parameter_Specification (Node));
1905             end if;
1906
1907             Write_Char (' ');
1908
1909          when N_Itype_Reference =>
1910             Write_Indent_Str_Sloc ("reference ");
1911             Write_Id (Itype (Node));
1912
1913          when N_Label =>
1914             Write_Indent_Str_Sloc ("<<");
1915             Write_Id (Identifier (Node));
1916             Write_Str (">>");
1917
1918          when N_Loop_Parameter_Specification =>
1919             Set_Debug_Sloc;
1920             Write_Id (Defining_Identifier (Node));
1921             Write_Str_With_Col_Check (" in ");
1922
1923             if Reverse_Present (Node) then
1924                Write_Str_With_Col_Check ("reverse ");
1925             end if;
1926
1927             Sprint_Node (Discrete_Subtype_Definition (Node));
1928
1929          when N_Loop_Statement =>
1930             Write_Indent;
1931
1932             if Present (Identifier (Node))
1933               and then (not Has_Created_Identifier (Node)
1934                           or else not Dump_Original_Only)
1935             then
1936                Write_Rewrite_Str ("<<<");
1937                Write_Id (Identifier (Node));
1938                Write_Str (" : ");
1939                Write_Rewrite_Str (">>>");
1940                Sprint_Node (Iteration_Scheme (Node));
1941                Write_Str_With_Col_Check_Sloc ("loop");
1942                Sprint_Indented_List (Statements (Node));
1943                Write_Indent_Str ("end loop ");
1944                Write_Rewrite_Str ("<<<");
1945                Write_Id (Identifier (Node));
1946                Write_Rewrite_Str (">>>");
1947                Write_Char (';');
1948
1949             else
1950                Sprint_Node (Iteration_Scheme (Node));
1951                Write_Str_With_Col_Check_Sloc ("loop");
1952                Sprint_Indented_List (Statements (Node));
1953                Write_Indent_Str ("end loop;");
1954             end if;
1955
1956          when N_Mod_Clause =>
1957             Sprint_Node_List (Pragmas_Before (Node));
1958             Write_Str_With_Col_Check_Sloc ("at mod ");
1959             Sprint_Node (Expression (Node));
1960
1961          when N_Modular_Type_Definition =>
1962             Write_Str_With_Col_Check_Sloc ("mod ");
1963             Sprint_Node (Expression (Node));
1964
1965          when N_Not_In =>
1966             Sprint_Left_Opnd (Node);
1967             Write_Str_Sloc (" not in ");
1968
1969             if Present (Right_Opnd (Node)) then
1970                Sprint_Right_Opnd (Node);
1971             else
1972                Sprint_Bar_List (Alternatives (Node));
1973             end if;
1974
1975          when N_Null =>
1976             Write_Str_With_Col_Check_Sloc ("null");
1977
1978          when N_Null_Statement =>
1979             if Comes_From_Source (Node)
1980               or else Dump_Freeze_Null
1981               or else not Is_List_Member (Node)
1982               or else (No (Prev (Node)) and then No (Next (Node)))
1983             then
1984                Write_Indent_Str_Sloc ("null;");
1985             end if;
1986
1987          when N_Number_Declaration =>
1988             Set_Debug_Sloc;
1989
1990             if Write_Indent_Identifiers (Node) then
1991                Write_Str_With_Col_Check (" : constant ");
1992                Write_Str (" := ");
1993                Sprint_Node (Expression (Node));
1994                Write_Char (';');
1995             end if;
1996
1997          when N_Object_Declaration =>
1998             Set_Debug_Sloc;
1999
2000             if Write_Indent_Identifiers (Node) then
2001                declare
2002                   Def_Id : constant Entity_Id := Defining_Identifier (Node);
2003
2004                begin
2005                   Write_Str_With_Col_Check (" : ");
2006
2007                   if Is_Statically_Allocated (Def_Id) then
2008                      Write_Str_With_Col_Check ("static ");
2009                   end if;
2010
2011                   if Aliased_Present (Node) then
2012                      Write_Str_With_Col_Check ("aliased ");
2013                   end if;
2014
2015                   if Constant_Present (Node) then
2016                      Write_Str_With_Col_Check ("constant ");
2017                   end if;
2018
2019                   --  Ada 2005 (AI-231)
2020
2021                   if Null_Exclusion_Present (Node) then
2022                      Write_Str_With_Col_Check ("not null ");
2023                   end if;
2024
2025                   Sprint_Node (Object_Definition (Node));
2026
2027                   if Present (Expression (Node)) then
2028                      Write_Str (" := ");
2029                      Sprint_Node (Expression (Node));
2030                   end if;
2031
2032                   Write_Char (';');
2033
2034                   --  Handle implicit importation and implicit exportation of
2035                   --  object declarations:
2036                   --    $pragma import (Convention_Id, Def_Id, "...");
2037                   --    $pragma export (Convention_Id, Def_Id, "...");
2038
2039                   if Is_Internal (Def_Id)
2040                     and then Present (Interface_Name (Def_Id))
2041                   then
2042                      Write_Indent_Str_Sloc ("$pragma ");
2043
2044                      if Is_Imported (Def_Id) then
2045                         Write_Str ("import (");
2046
2047                      else pragma Assert (Is_Exported (Def_Id));
2048                         Write_Str ("export (");
2049                      end if;
2050
2051                      declare
2052                         Prefix : constant String  := "Convention_";
2053                         S      : constant String  := Convention (Def_Id)'Img;
2054
2055                      begin
2056                         Name_Len := S'Last - Prefix'Last;
2057                         Name_Buffer (1 .. Name_Len) :=
2058                           S (Prefix'Last + 1 .. S'Last);
2059                         Set_Casing (All_Lower_Case);
2060                         Write_Str (Name_Buffer (1 .. Name_Len));
2061                      end;
2062
2063                      Write_Str (", ");
2064                      Write_Id  (Def_Id);
2065                      Write_Str (", ");
2066                      Write_String_Table_Entry
2067                        (Strval (Interface_Name (Def_Id)));
2068                      Write_Str (");");
2069                   end if;
2070                end;
2071             end if;
2072
2073          when N_Object_Renaming_Declaration =>
2074             Write_Indent;
2075             Set_Debug_Sloc;
2076             Sprint_Node (Defining_Identifier (Node));
2077             Write_Str (" : ");
2078
2079             --  Ada 2005 (AI-230): Access renamings
2080
2081             if Present (Access_Definition (Node)) then
2082                Sprint_Node (Access_Definition (Node));
2083
2084             elsif Present (Subtype_Mark (Node)) then
2085
2086                --  Ada 2005 (AI-423): Object renaming with a null exclusion
2087
2088                if Null_Exclusion_Present (Node) then
2089                   Write_Str ("not null ");
2090                end if;
2091
2092                Sprint_Node (Subtype_Mark (Node));
2093
2094             else
2095                Write_Str (" ??? ");
2096             end if;
2097
2098             Write_Str_With_Col_Check (" renames ");
2099             Sprint_Node (Name (Node));
2100             Write_Char (';');
2101
2102          when N_Op_Abs =>
2103             Write_Operator (Node, "abs ");
2104             Sprint_Right_Opnd (Node);
2105
2106          when N_Op_Add =>
2107             Sprint_Left_Opnd (Node);
2108             Write_Operator (Node, " + ");
2109             Sprint_Right_Opnd (Node);
2110
2111          when N_Op_And =>
2112             Sprint_Left_Opnd (Node);
2113             Write_Operator (Node, " and ");
2114             Sprint_Right_Opnd (Node);
2115
2116          when N_Op_Concat =>
2117             Sprint_Left_Opnd (Node);
2118             Write_Operator (Node, " & ");
2119             Sprint_Right_Opnd (Node);
2120
2121          when N_Op_Divide =>
2122             Sprint_Left_Opnd (Node);
2123             Write_Char (' ');
2124             Process_TFAI_RR_Flags (Node);
2125             Write_Operator (Node, "/ ");
2126             Sprint_Right_Opnd (Node);
2127
2128          when N_Op_Eq =>
2129             Sprint_Left_Opnd (Node);
2130             Write_Operator (Node, " = ");
2131             Sprint_Right_Opnd (Node);
2132
2133          when N_Op_Expon =>
2134             Sprint_Left_Opnd (Node);
2135             Write_Operator (Node, " ** ");
2136             Sprint_Right_Opnd (Node);
2137
2138          when N_Op_Ge =>
2139             Sprint_Left_Opnd (Node);
2140             Write_Operator (Node, " >= ");
2141             Sprint_Right_Opnd (Node);
2142
2143          when N_Op_Gt =>
2144             Sprint_Left_Opnd (Node);
2145             Write_Operator (Node, " > ");
2146             Sprint_Right_Opnd (Node);
2147
2148          when N_Op_Le =>
2149             Sprint_Left_Opnd (Node);
2150             Write_Operator (Node, " <= ");
2151             Sprint_Right_Opnd (Node);
2152
2153          when N_Op_Lt =>
2154             Sprint_Left_Opnd (Node);
2155             Write_Operator (Node, " < ");
2156             Sprint_Right_Opnd (Node);
2157
2158          when N_Op_Minus =>
2159             Write_Operator (Node, "-");
2160             Sprint_Right_Opnd (Node);
2161
2162          when N_Op_Mod =>
2163             Sprint_Left_Opnd (Node);
2164
2165             if Treat_Fixed_As_Integer (Node) then
2166                Write_Str (" #");
2167             end if;
2168
2169             Write_Operator (Node, " mod ");
2170             Sprint_Right_Opnd (Node);
2171
2172          when N_Op_Multiply =>
2173             Sprint_Left_Opnd (Node);
2174             Write_Char (' ');
2175             Process_TFAI_RR_Flags (Node);
2176             Write_Operator (Node, "* ");
2177             Sprint_Right_Opnd (Node);
2178
2179          when N_Op_Ne =>
2180             Sprint_Left_Opnd (Node);
2181             Write_Operator (Node, " /= ");
2182             Sprint_Right_Opnd (Node);
2183
2184          when N_Op_Not =>
2185             Write_Operator (Node, "not ");
2186             Sprint_Right_Opnd (Node);
2187
2188          when N_Op_Or =>
2189             Sprint_Left_Opnd (Node);
2190             Write_Operator (Node, " or ");
2191             Sprint_Right_Opnd (Node);
2192
2193          when N_Op_Plus =>
2194             Write_Operator (Node, "+");
2195             Sprint_Right_Opnd (Node);
2196
2197          when N_Op_Rem =>
2198             Sprint_Left_Opnd (Node);
2199
2200             if Treat_Fixed_As_Integer (Node) then
2201                Write_Str (" #");
2202             end if;
2203
2204             Write_Operator (Node, " rem ");
2205             Sprint_Right_Opnd (Node);
2206
2207          when N_Op_Shift =>
2208             Set_Debug_Sloc;
2209             Write_Id (Node);
2210             Write_Char ('!');
2211             Write_Str_With_Col_Check ("(");
2212             Sprint_Node (Left_Opnd (Node));
2213             Write_Str (", ");
2214             Sprint_Node (Right_Opnd (Node));
2215             Write_Char (')');
2216
2217          when N_Op_Subtract =>
2218             Sprint_Left_Opnd (Node);
2219             Write_Operator (Node, " - ");
2220             Sprint_Right_Opnd (Node);
2221
2222          when N_Op_Xor =>
2223             Sprint_Left_Opnd (Node);
2224             Write_Operator (Node, " xor ");
2225             Sprint_Right_Opnd (Node);
2226
2227          when N_Operator_Symbol =>
2228             Write_Name_With_Col_Check_Sloc (Chars (Node));
2229
2230          when N_Ordinary_Fixed_Point_Definition =>
2231             Write_Str_With_Col_Check_Sloc ("delta ");
2232             Sprint_Node (Delta_Expression (Node));
2233             Sprint_Opt_Node (Real_Range_Specification (Node));
2234
2235          when N_Or_Else =>
2236             Sprint_Left_Opnd (Node);
2237             Write_Str_Sloc (" or else ");
2238             Sprint_Right_Opnd (Node);
2239
2240          when N_Others_Choice =>
2241             if All_Others (Node) then
2242                Write_Str_With_Col_Check ("all ");
2243             end if;
2244
2245             Write_Str_With_Col_Check_Sloc ("others");
2246
2247          when N_Package_Body =>
2248             Extra_Blank_Line;
2249             Write_Indent_Str_Sloc ("package body ");
2250             Sprint_Node (Defining_Unit_Name (Node));
2251             Write_Str (" is");
2252             Sprint_Indented_List (Declarations (Node));
2253
2254             if Present (Handled_Statement_Sequence (Node)) then
2255                Write_Indent_Str ("begin");
2256                Sprint_Node (Handled_Statement_Sequence (Node));
2257             end if;
2258
2259             Write_Indent_Str ("end ");
2260             Sprint_End_Label
2261               (Handled_Statement_Sequence (Node), Defining_Unit_Name (Node));
2262             Write_Char (';');
2263
2264          when N_Package_Body_Stub =>
2265             Write_Indent_Str_Sloc ("package body ");
2266             Sprint_Node (Defining_Identifier (Node));
2267             Write_Str_With_Col_Check (" is separate;");
2268
2269          when N_Package_Declaration =>
2270             Extra_Blank_Line;
2271             Write_Indent;
2272             Sprint_Node_Sloc (Specification (Node));
2273             Write_Char (';');
2274
2275          when N_Package_Instantiation =>
2276             Extra_Blank_Line;
2277             Write_Indent_Str_Sloc ("package ");
2278             Sprint_Node (Defining_Unit_Name (Node));
2279             Write_Str (" is new ");
2280             Sprint_Node (Name (Node));
2281             Sprint_Opt_Paren_Comma_List (Generic_Associations (Node));
2282             Write_Char (';');
2283
2284          when N_Package_Renaming_Declaration =>
2285             Write_Indent_Str_Sloc ("package ");
2286             Sprint_Node (Defining_Unit_Name (Node));
2287             Write_Str_With_Col_Check (" renames ");
2288             Sprint_Node (Name (Node));
2289             Write_Char (';');
2290
2291          when N_Package_Specification =>
2292             Write_Str_With_Col_Check_Sloc ("package ");
2293             Sprint_Node (Defining_Unit_Name (Node));
2294             Write_Str (" is");
2295             Sprint_Indented_List (Visible_Declarations (Node));
2296
2297             if Present (Private_Declarations (Node)) then
2298                Write_Indent_Str ("private");
2299                Sprint_Indented_List (Private_Declarations (Node));
2300             end if;
2301
2302             Write_Indent_Str ("end ");
2303             Sprint_Node (Defining_Unit_Name (Node));
2304
2305          when N_Parameter_Association =>
2306             Sprint_Node_Sloc (Selector_Name (Node));
2307             Write_Str (" => ");
2308             Sprint_Node (Explicit_Actual_Parameter (Node));
2309
2310          when N_Parameter_Specification =>
2311             Set_Debug_Sloc;
2312
2313             if Write_Identifiers (Node) then
2314                Write_Str (" : ");
2315
2316                if In_Present (Node) then
2317                   Write_Str_With_Col_Check ("in ");
2318                end if;
2319
2320                if Out_Present (Node) then
2321                   Write_Str_With_Col_Check ("out ");
2322                end if;
2323
2324                --  Ada 2005 (AI-231): Parameter specification may carry null
2325                --  exclusion. Do not print it now if this is an access formal,
2326                --  it is emitted when the access definition is displayed.
2327
2328                if Null_Exclusion_Present (Node)
2329                  and then Nkind (Parameter_Type (Node))
2330                    /= N_Access_Definition
2331                then
2332                   Write_Str ("not null ");
2333                end if;
2334
2335                Sprint_Node (Parameter_Type (Node));
2336
2337                if Present (Expression (Node)) then
2338                   Write_Str (" := ");
2339                   Sprint_Node (Expression (Node));
2340                end if;
2341             else
2342                Write_Str (", ");
2343             end if;
2344
2345          when N_Pop_Constraint_Error_Label =>
2346             Write_Indent_Str ("%pop_constraint_error_label");
2347
2348          when N_Pop_Program_Error_Label =>
2349             Write_Indent_Str ("%pop_program_error_label");
2350
2351          when N_Pop_Storage_Error_Label =>
2352             Write_Indent_Str ("%pop_storage_error_label");
2353
2354          when N_Push_Constraint_Error_Label =>
2355             Write_Indent_Str ("%push_constraint_error_label (");
2356
2357             if Present (Exception_Label (Node)) then
2358                Write_Name_With_Col_Check (Chars (Exception_Label (Node)));
2359             end if;
2360
2361             Write_Str (")");
2362
2363          when N_Push_Program_Error_Label =>
2364             Write_Indent_Str ("%push_program_error_label (");
2365
2366             if Present (Exception_Label (Node)) then
2367                Write_Name_With_Col_Check (Chars (Exception_Label (Node)));
2368             end if;
2369
2370             Write_Str (")");
2371
2372          when N_Push_Storage_Error_Label =>
2373             Write_Indent_Str ("%push_storage_error_label (");
2374
2375             if Present (Exception_Label (Node)) then
2376                Write_Name_With_Col_Check (Chars (Exception_Label (Node)));
2377             end if;
2378
2379             Write_Str (")");
2380
2381          when N_Pragma =>
2382             Write_Indent_Str_Sloc ("pragma ");
2383             Write_Name_With_Col_Check (Pragma_Name (Node));
2384
2385             if Present (Pragma_Argument_Associations (Node)) then
2386                Sprint_Opt_Paren_Comma_List
2387                  (Pragma_Argument_Associations (Node));
2388             end if;
2389
2390             Write_Char (';');
2391
2392          when N_Pragma_Argument_Association =>
2393             Set_Debug_Sloc;
2394
2395             if Chars (Node) /= No_Name then
2396                Write_Name_With_Col_Check (Chars (Node));
2397                Write_Str (" => ");
2398             end if;
2399
2400             Sprint_Node (Expression (Node));
2401
2402          when N_Private_Type_Declaration =>
2403             Write_Indent_Str_Sloc ("type ");
2404             Write_Id (Defining_Identifier (Node));
2405
2406             if Present (Discriminant_Specifications (Node)) then
2407                Write_Discr_Specs (Node);
2408             elsif Unknown_Discriminants_Present (Node) then
2409                Write_Str_With_Col_Check ("(<>)");
2410             end if;
2411
2412             Write_Str (" is ");
2413
2414             if Tagged_Present (Node) then
2415                Write_Str_With_Col_Check ("tagged ");
2416             end if;
2417
2418             if Limited_Present (Node) then
2419                Write_Str_With_Col_Check ("limited ");
2420             end if;
2421
2422             Write_Str_With_Col_Check ("private;");
2423
2424          when N_Private_Extension_Declaration =>
2425             Write_Indent_Str_Sloc ("type ");
2426             Write_Id (Defining_Identifier (Node));
2427
2428             if Present (Discriminant_Specifications (Node)) then
2429                Write_Discr_Specs (Node);
2430             elsif Unknown_Discriminants_Present (Node) then
2431                Write_Str_With_Col_Check ("(<>)");
2432             end if;
2433
2434             Write_Str_With_Col_Check (" is new ");
2435             Sprint_Node (Subtype_Indication (Node));
2436
2437             if Present (Interface_List (Node)) then
2438                Write_Str_With_Col_Check (" and ");
2439                Sprint_And_List (Interface_List (Node));
2440             end if;
2441
2442             Write_Str_With_Col_Check (" with private;");
2443
2444          when N_Procedure_Call_Statement =>
2445             Write_Indent;
2446             Set_Debug_Sloc;
2447             Write_Subprogram_Name (Name (Node));
2448             Sprint_Opt_Paren_Comma_List (Parameter_Associations (Node));
2449             Write_Char (';');
2450
2451          when N_Procedure_Instantiation =>
2452             Write_Indent_Str_Sloc ("procedure ");
2453             Sprint_Node (Defining_Unit_Name (Node));
2454             Write_Str_With_Col_Check (" is new ");
2455             Sprint_Node (Name (Node));
2456             Sprint_Opt_Paren_Comma_List (Generic_Associations (Node));
2457             Write_Char (';');
2458
2459          when N_Procedure_Specification =>
2460             Write_Str_With_Col_Check_Sloc ("procedure ");
2461             Sprint_Node (Defining_Unit_Name (Node));
2462             Write_Param_Specs (Node);
2463
2464          when N_Protected_Body =>
2465             Write_Indent_Str_Sloc ("protected body ");
2466             Write_Id (Defining_Identifier (Node));
2467             Write_Str (" is");
2468             Sprint_Indented_List (Declarations (Node));
2469             Write_Indent_Str ("end ");
2470             Write_Id (Defining_Identifier (Node));
2471             Write_Char (';');
2472
2473          when N_Protected_Body_Stub =>
2474             Write_Indent_Str_Sloc ("protected body ");
2475             Write_Id (Defining_Identifier (Node));
2476             Write_Str_With_Col_Check (" is separate;");
2477
2478          when N_Protected_Definition =>
2479             Set_Debug_Sloc;
2480             Sprint_Indented_List (Visible_Declarations (Node));
2481
2482             if Present (Private_Declarations (Node)) then
2483                Write_Indent_Str ("private");
2484                Sprint_Indented_List (Private_Declarations (Node));
2485             end if;
2486
2487             Write_Indent_Str ("end ");
2488
2489          when N_Protected_Type_Declaration =>
2490             Write_Indent_Str_Sloc ("protected type ");
2491             Sprint_Node (Defining_Identifier (Node));
2492             Write_Discr_Specs (Node);
2493
2494             if Present (Interface_List (Node)) then
2495                Write_Str (" is new ");
2496                Sprint_And_List (Interface_List (Node));
2497                Write_Str (" with ");
2498             else
2499                Write_Str (" is");
2500             end if;
2501
2502             Sprint_Node (Protected_Definition (Node));
2503             Write_Id (Defining_Identifier (Node));
2504             Write_Char (';');
2505
2506          when N_Qualified_Expression =>
2507             Sprint_Node (Subtype_Mark (Node));
2508             Write_Char_Sloc (''');
2509
2510             --  Print expression, make sure we have at least one level of
2511             --  parentheses around the expression. For cases of qualified
2512             --  expressions in the source, this is always the case, but
2513             --  for generated qualifications, there may be no explicit
2514             --  parentheses present.
2515
2516             if Paren_Count (Expression (Node)) /= 0 then
2517                Sprint_Node (Expression (Node));
2518             else
2519                Write_Char ('(');
2520                Sprint_Node (Expression (Node));
2521                Write_Char (')');
2522             end if;
2523
2524          when N_Raise_Constraint_Error =>
2525
2526             --  This node can be used either as a subexpression or as a
2527             --  statement form. The following test is a reasonably reliable
2528             --  way to distinguish the two cases.
2529
2530             if Is_List_Member (Node)
2531               and then Nkind (Parent (Node)) not in N_Subexpr
2532             then
2533                Write_Indent;
2534             end if;
2535
2536             Write_Str_With_Col_Check_Sloc ("[constraint_error");
2537             Write_Condition_And_Reason (Node);
2538
2539          when N_Raise_Program_Error =>
2540
2541             --  This node can be used either as a subexpression or as a
2542             --  statement form. The following test is a reasonably reliable
2543             --  way to distinguish the two cases.
2544
2545             if Is_List_Member (Node)
2546               and then Nkind (Parent (Node)) not in N_Subexpr
2547             then
2548                Write_Indent;
2549             end if;
2550
2551             Write_Str_With_Col_Check_Sloc ("[program_error");
2552             Write_Condition_And_Reason (Node);
2553
2554          when N_Raise_Storage_Error =>
2555
2556             --  This node can be used either as a subexpression or as a
2557             --  statement form. The following test is a reasonably reliable
2558             --  way to distinguish the two cases.
2559
2560             if Is_List_Member (Node)
2561               and then Nkind (Parent (Node)) not in N_Subexpr
2562             then
2563                Write_Indent;
2564             end if;
2565
2566             Write_Str_With_Col_Check_Sloc ("[storage_error");
2567             Write_Condition_And_Reason (Node);
2568
2569          when N_Raise_Statement =>
2570             Write_Indent_Str_Sloc ("raise ");
2571             Sprint_Node (Name (Node));
2572             Write_Char (';');
2573
2574          when N_Range =>
2575             Sprint_Node (Low_Bound (Node));
2576             Write_Str_Sloc (" .. ");
2577             Sprint_Node (High_Bound (Node));
2578             Update_Itype (Node);
2579
2580          when N_Range_Constraint =>
2581             Write_Str_With_Col_Check_Sloc ("range ");
2582             Sprint_Node (Range_Expression (Node));
2583
2584          when N_Real_Literal =>
2585             Write_Ureal_With_Col_Check_Sloc (Realval (Node));
2586
2587          when N_Real_Range_Specification =>
2588             Write_Str_With_Col_Check_Sloc ("range ");
2589             Sprint_Node (Low_Bound (Node));
2590             Write_Str (" .. ");
2591             Sprint_Node (High_Bound (Node));
2592
2593          when N_Record_Definition =>
2594             if Abstract_Present (Node) then
2595                Write_Str_With_Col_Check ("abstract ");
2596             end if;
2597
2598             if Tagged_Present (Node) then
2599                Write_Str_With_Col_Check ("tagged ");
2600             end if;
2601
2602             if Limited_Present (Node) then
2603                Write_Str_With_Col_Check ("limited ");
2604             end if;
2605
2606             if Null_Present (Node) then
2607                Write_Str_With_Col_Check_Sloc ("null record");
2608
2609             else
2610                Write_Str_With_Col_Check_Sloc ("record");
2611                Sprint_Node (Component_List (Node));
2612                Write_Indent_Str ("end record");
2613             end if;
2614
2615          when N_Record_Representation_Clause =>
2616             Write_Indent_Str_Sloc ("for ");
2617             Sprint_Node (Identifier (Node));
2618             Write_Str_With_Col_Check (" use record ");
2619
2620             if Present (Mod_Clause (Node)) then
2621                Sprint_Node (Mod_Clause (Node));
2622             end if;
2623
2624             Sprint_Indented_List (Component_Clauses (Node));
2625             Write_Indent_Str ("end record;");
2626
2627          when N_Reference =>
2628             Sprint_Node (Prefix (Node));
2629             Write_Str_With_Col_Check_Sloc ("'reference");
2630
2631          when N_Requeue_Statement =>
2632             Write_Indent_Str_Sloc ("requeue ");
2633             Sprint_Node (Name (Node));
2634
2635             if Abort_Present (Node) then
2636                Write_Str_With_Col_Check (" with abort");
2637             end if;
2638
2639             Write_Char (';');
2640
2641          --  Don't we want to print more detail???
2642
2643          --  Doc of this extended syntax belongs in sinfo.ads and/or
2644          --  sprint.ads ???
2645
2646          when N_SCIL_Dispatch_Table_Object_Init =>
2647             Write_Indent_Str ("[N_SCIL_Dispatch_Table_Object_Init]");
2648
2649          when N_SCIL_Dispatch_Table_Tag_Init =>
2650             Write_Indent_Str ("[N_SCIL_Dispatch_Table_Tag_Init]");
2651
2652          when N_SCIL_Dispatching_Call =>
2653             Write_Indent_Str ("[N_SCIL_Dispatching_Node]");
2654
2655          when N_SCIL_Tag_Init =>
2656             Write_Indent_Str ("[N_SCIL_Dispatch_Table_Tag_Init]");
2657
2658          when N_Simple_Return_Statement =>
2659             if Present (Expression (Node)) then
2660                Write_Indent_Str_Sloc ("return ");
2661                Sprint_Node (Expression (Node));
2662                Write_Char (';');
2663             else
2664                Write_Indent_Str_Sloc ("return;");
2665             end if;
2666
2667          when N_Selective_Accept =>
2668             Write_Indent_Str_Sloc ("select");
2669
2670             declare
2671                Alt_Node : Node_Id;
2672             begin
2673                Alt_Node := First (Select_Alternatives (Node));
2674                loop
2675                   Indent_Begin;
2676                   Sprint_Node (Alt_Node);
2677                   Indent_End;
2678                   Next (Alt_Node);
2679                   exit when No (Alt_Node);
2680                   Write_Indent_Str ("or");
2681                end loop;
2682             end;
2683
2684             if Present (Else_Statements (Node)) then
2685                Write_Indent_Str ("else");
2686                Sprint_Indented_List (Else_Statements (Node));
2687             end if;
2688
2689             Write_Indent_Str ("end select;");
2690
2691          when N_Signed_Integer_Type_Definition =>
2692             Write_Str_With_Col_Check_Sloc ("range ");
2693             Sprint_Node (Low_Bound (Node));
2694             Write_Str (" .. ");
2695             Sprint_Node (High_Bound (Node));
2696
2697          when N_Single_Protected_Declaration =>
2698             Write_Indent_Str_Sloc ("protected ");
2699             Write_Id (Defining_Identifier (Node));
2700             Write_Str (" is");
2701             Sprint_Node (Protected_Definition (Node));
2702             Write_Id (Defining_Identifier (Node));
2703             Write_Char (';');
2704
2705          when N_Single_Task_Declaration =>
2706             Write_Indent_Str_Sloc ("task ");
2707             Sprint_Node (Defining_Identifier (Node));
2708
2709             if Present (Task_Definition (Node)) then
2710                Write_Str (" is");
2711                Sprint_Node (Task_Definition (Node));
2712             end if;
2713
2714             Write_Char (';');
2715
2716          when N_Selected_Component =>
2717             Sprint_Node (Prefix (Node));
2718             Write_Char_Sloc ('.');
2719             Sprint_Node (Selector_Name (Node));
2720
2721          when N_Slice =>
2722             Set_Debug_Sloc;
2723             Sprint_Node (Prefix (Node));
2724             Write_Str_With_Col_Check (" (");
2725             Sprint_Node (Discrete_Range (Node));
2726             Write_Char (')');
2727
2728          when N_String_Literal =>
2729             if String_Length (Strval (Node)) + Column > Sprint_Line_Limit then
2730                Write_Indent_Str ("  ");
2731             end if;
2732
2733             Set_Debug_Sloc;
2734             Write_String_Table_Entry (Strval (Node));
2735
2736          when N_Subprogram_Body =>
2737
2738             --  Output extra blank line unless we are in freeze actions
2739
2740             if Freeze_Indent = 0 then
2741                Extra_Blank_Line;
2742             end if;
2743
2744             Write_Indent;
2745             Sprint_Node_Sloc (Specification (Node));
2746             Write_Str (" is");
2747
2748             Sprint_Indented_List (Declarations (Node));
2749             Write_Indent_Str ("begin");
2750             Sprint_Node (Handled_Statement_Sequence (Node));
2751
2752             Write_Indent_Str ("end ");
2753
2754             Sprint_End_Label
2755               (Handled_Statement_Sequence (Node),
2756                  Defining_Unit_Name (Specification (Node)));
2757             Write_Char (';');
2758
2759             if Is_List_Member (Node)
2760               and then Present (Next (Node))
2761               and then Nkind (Next (Node)) /= N_Subprogram_Body
2762             then
2763                Write_Indent;
2764             end if;
2765
2766          when N_Subprogram_Body_Stub =>
2767             Write_Indent;
2768             Sprint_Node_Sloc (Specification (Node));
2769             Write_Str_With_Col_Check (" is separate;");
2770
2771          when N_Subprogram_Declaration =>
2772             Write_Indent;
2773             Sprint_Node_Sloc (Specification (Node));
2774
2775             if Nkind (Specification (Node)) = N_Procedure_Specification
2776               and then Null_Present (Specification (Node))
2777             then
2778                Write_Str_With_Col_Check (" is null");
2779             end if;
2780
2781             Write_Char (';');
2782
2783          when N_Subprogram_Info =>
2784             Sprint_Node (Identifier (Node));
2785             Write_Str_With_Col_Check_Sloc ("'subprogram_info");
2786
2787          when N_Subprogram_Renaming_Declaration =>
2788             Write_Indent;
2789             Sprint_Node (Specification (Node));
2790             Write_Str_With_Col_Check_Sloc (" renames ");
2791             Sprint_Node (Name (Node));
2792             Write_Char (';');
2793
2794          when N_Subtype_Declaration =>
2795             Write_Indent_Str_Sloc ("subtype ");
2796             Sprint_Node (Defining_Identifier (Node));
2797             Write_Str (" is ");
2798
2799             --  Ada 2005 (AI-231)
2800
2801             if Null_Exclusion_Present (Node) then
2802                Write_Str ("not null ");
2803             end if;
2804
2805             Sprint_Node (Subtype_Indication (Node));
2806             Write_Char (';');
2807
2808          when N_Subtype_Indication =>
2809             Sprint_Node_Sloc (Subtype_Mark (Node));
2810             Write_Char (' ');
2811             Sprint_Node (Constraint (Node));
2812
2813          when N_Subunit =>
2814             Write_Indent_Str_Sloc ("separate (");
2815             Sprint_Node (Name (Node));
2816             Write_Char (')');
2817             Extra_Blank_Line;
2818             Sprint_Node (Proper_Body (Node));
2819
2820          when N_Task_Body =>
2821             Write_Indent_Str_Sloc ("task body ");
2822             Write_Id (Defining_Identifier (Node));
2823             Write_Str (" is");
2824             Sprint_Indented_List (Declarations (Node));
2825             Write_Indent_Str ("begin");
2826             Sprint_Node (Handled_Statement_Sequence (Node));
2827             Write_Indent_Str ("end ");
2828             Sprint_End_Label
2829               (Handled_Statement_Sequence (Node), Defining_Identifier (Node));
2830             Write_Char (';');
2831
2832          when N_Task_Body_Stub =>
2833             Write_Indent_Str_Sloc ("task body ");
2834             Write_Id (Defining_Identifier (Node));
2835             Write_Str_With_Col_Check (" is separate;");
2836
2837          when N_Task_Definition =>
2838             Set_Debug_Sloc;
2839             Sprint_Indented_List (Visible_Declarations (Node));
2840
2841             if Present (Private_Declarations (Node)) then
2842                Write_Indent_Str ("private");
2843                Sprint_Indented_List (Private_Declarations (Node));
2844             end if;
2845
2846             Write_Indent_Str ("end ");
2847             Sprint_End_Label (Node, Defining_Identifier (Parent (Node)));
2848
2849          when N_Task_Type_Declaration =>
2850             Write_Indent_Str_Sloc ("task type ");
2851             Sprint_Node (Defining_Identifier (Node));
2852             Write_Discr_Specs (Node);
2853
2854             if Present (Interface_List (Node)) then
2855                Write_Str (" is new ");
2856                Sprint_And_List (Interface_List (Node));
2857             end if;
2858
2859             if Present (Task_Definition (Node)) then
2860                if No (Interface_List (Node)) then
2861                   Write_Str (" is");
2862                else
2863                   Write_Str (" with ");
2864                end if;
2865
2866                Sprint_Node (Task_Definition (Node));
2867             end if;
2868
2869             Write_Char (';');
2870
2871          when N_Terminate_Alternative =>
2872             Sprint_Node_List (Pragmas_Before (Node));
2873
2874             Write_Indent;
2875
2876             if Present (Condition (Node)) then
2877                Write_Str_With_Col_Check ("when ");
2878                Sprint_Node (Condition (Node));
2879                Write_Str (" => ");
2880             end if;
2881
2882             Write_Str_With_Col_Check_Sloc ("terminate;");
2883             Sprint_Node_List (Pragmas_After (Node));
2884
2885          when N_Timed_Entry_Call =>
2886             Write_Indent_Str_Sloc ("select");
2887             Indent_Begin;
2888             Sprint_Node (Entry_Call_Alternative (Node));
2889             Indent_End;
2890             Write_Indent_Str ("or");
2891             Indent_Begin;
2892             Sprint_Node (Delay_Alternative (Node));
2893             Indent_End;
2894             Write_Indent_Str ("end select;");
2895
2896          when N_Triggering_Alternative =>
2897             Sprint_Node_List (Pragmas_Before (Node));
2898             Sprint_Node_Sloc (Triggering_Statement (Node));
2899             Sprint_Node_List (Statements (Node));
2900
2901          when N_Type_Conversion =>
2902             Set_Debug_Sloc;
2903             Sprint_Node (Subtype_Mark (Node));
2904             Col_Check (4);
2905
2906             if Conversion_OK (Node) then
2907                Write_Char ('?');
2908             end if;
2909
2910             if Float_Truncate (Node) then
2911                Write_Char ('^');
2912             end if;
2913
2914             if Rounded_Result (Node) then
2915                Write_Char ('@');
2916             end if;
2917
2918             Write_Char ('(');
2919             Sprint_Node (Expression (Node));
2920             Write_Char (')');
2921
2922          when N_Unchecked_Expression =>
2923             Col_Check (10);
2924             Write_Str ("`(");
2925             Sprint_Node_Sloc (Expression (Node));
2926             Write_Char (')');
2927
2928          when N_Unchecked_Type_Conversion =>
2929             Sprint_Node (Subtype_Mark (Node));
2930             Write_Char ('!');
2931             Write_Str_With_Col_Check ("(");
2932             Sprint_Node_Sloc (Expression (Node));
2933             Write_Char (')');
2934
2935          when N_Unconstrained_Array_Definition =>
2936             Write_Str_With_Col_Check_Sloc ("array (");
2937
2938             declare
2939                Node1 : Node_Id;
2940             begin
2941                Node1 := First (Subtype_Marks (Node));
2942                loop
2943                   Sprint_Node (Node1);
2944                   Write_Str_With_Col_Check (" range <>");
2945                   Next (Node1);
2946                   exit when Node1 = Empty;
2947                   Write_Str (", ");
2948                end loop;
2949             end;
2950
2951             Write_Str (") of ");
2952             Sprint_Node (Component_Definition (Node));
2953
2954          when N_Unused_At_Start | N_Unused_At_End =>
2955             Write_Indent_Str ("***** Error, unused node encountered *****");
2956             Write_Eol;
2957
2958          when N_Use_Package_Clause =>
2959             Write_Indent_Str_Sloc ("use ");
2960             Sprint_Comma_List (Names (Node));
2961             Write_Char (';');
2962
2963          when N_Use_Type_Clause =>
2964             Write_Indent_Str_Sloc ("use type ");
2965             Sprint_Comma_List (Subtype_Marks (Node));
2966             Write_Char (';');
2967
2968          when N_Validate_Unchecked_Conversion =>
2969             Write_Indent_Str_Sloc ("validate unchecked_conversion (");
2970             Sprint_Node (Source_Type (Node));
2971             Write_Str (", ");
2972             Sprint_Node (Target_Type (Node));
2973             Write_Str (");");
2974
2975          when N_Variant =>
2976             Write_Indent_Str_Sloc ("when ");
2977             Sprint_Bar_List (Discrete_Choices (Node));
2978             Write_Str (" => ");
2979             Sprint_Node (Component_List (Node));
2980
2981          when N_Variant_Part =>
2982             Indent_Begin;
2983             Write_Indent_Str_Sloc ("case ");
2984             Sprint_Node (Name (Node));
2985             Write_Str (" is ");
2986             Sprint_Indented_List (Variants (Node));
2987             Write_Indent_Str ("end case");
2988             Indent_End;
2989
2990          when N_With_Clause =>
2991
2992             --  Special test, if we are dumping the original tree only,
2993             --  then we want to eliminate the bogus with clauses that
2994             --  correspond to the non-existent children of Text_IO.
2995
2996             if Dump_Original_Only
2997               and then Is_Text_IO_Kludge_Unit (Name (Node))
2998             then
2999                null;
3000
3001             --  Normal case, output the with clause
3002
3003             else
3004                if First_Name (Node) or else not Dump_Original_Only then
3005
3006                   --  Ada 2005 (AI-50217): Print limited with_clauses
3007
3008                   if Private_Present (Node) and Limited_Present (Node) then
3009                      Write_Indent_Str ("limited private with ");
3010
3011                   elsif Private_Present (Node) then
3012                      Write_Indent_Str ("private with ");
3013
3014                   elsif Limited_Present (Node) then
3015                      Write_Indent_Str ("limited with ");
3016
3017                   else
3018                      Write_Indent_Str ("with ");
3019                   end if;
3020
3021                else
3022                   Write_Str (", ");
3023                end if;
3024
3025                Sprint_Node_Sloc (Name (Node));
3026
3027                if Last_Name (Node) or else not Dump_Original_Only then
3028                   Write_Char (';');
3029                end if;
3030             end if;
3031
3032       end case;
3033
3034       if Nkind (Node) in N_Subexpr
3035         and then Do_Range_Check (Node)
3036       then
3037          Write_Str ("}");
3038       end if;
3039
3040       for J in 1 .. Paren_Count (Node) loop
3041          Write_Char (')');
3042       end loop;
3043
3044       Dump_Node := Save_Dump_Node;
3045    end Sprint_Node_Actual;
3046
3047    ----------------------
3048    -- Sprint_Node_List --
3049    ----------------------
3050
3051    procedure Sprint_Node_List (List : List_Id) is
3052       Node : Node_Id;
3053
3054    begin
3055       if Is_Non_Empty_List (List) then
3056          Node := First (List);
3057
3058          loop
3059             Sprint_Node (Node);
3060             Next (Node);
3061             exit when Node = Empty;
3062          end loop;
3063       end if;
3064    end Sprint_Node_List;
3065
3066    ----------------------
3067    -- Sprint_Node_Sloc --
3068    ----------------------
3069
3070    procedure Sprint_Node_Sloc (Node : Node_Id) is
3071    begin
3072       Sprint_Node (Node);
3073
3074       if Debug_Generated_Code and then Present (Dump_Node) then
3075          Set_Sloc (Dump_Node, Sloc (Node));
3076          Dump_Node := Empty;
3077       end if;
3078    end Sprint_Node_Sloc;
3079
3080    ---------------------
3081    -- Sprint_Opt_Node --
3082    ---------------------
3083
3084    procedure Sprint_Opt_Node (Node : Node_Id) is
3085    begin
3086       if Present (Node) then
3087          Write_Char (' ');
3088          Sprint_Node (Node);
3089       end if;
3090    end Sprint_Opt_Node;
3091
3092    --------------------------
3093    -- Sprint_Opt_Node_List --
3094    --------------------------
3095
3096    procedure Sprint_Opt_Node_List (List : List_Id) is
3097    begin
3098       if Present (List) then
3099          Sprint_Node_List (List);
3100       end if;
3101    end Sprint_Opt_Node_List;
3102
3103    ---------------------------------
3104    -- Sprint_Opt_Paren_Comma_List --
3105    ---------------------------------
3106
3107    procedure Sprint_Opt_Paren_Comma_List (List : List_Id) is
3108    begin
3109       if Is_Non_Empty_List (List) then
3110          Write_Char (' ');
3111          Sprint_Paren_Comma_List (List);
3112       end if;
3113    end Sprint_Opt_Paren_Comma_List;
3114
3115    -----------------------------
3116    -- Sprint_Paren_Comma_List --
3117    -----------------------------
3118
3119    procedure Sprint_Paren_Comma_List (List : List_Id) is
3120       N           : Node_Id;
3121       Node_Exists : Boolean := False;
3122
3123    begin
3124
3125       if Is_Non_Empty_List (List) then
3126
3127          if Dump_Original_Only then
3128             N := First (List);
3129             while Present (N) loop
3130                if not Is_Rewrite_Insertion (N) then
3131                   Node_Exists := True;
3132                   exit;
3133                end if;
3134
3135                Next (N);
3136             end loop;
3137
3138             if not Node_Exists then
3139                return;
3140             end if;
3141          end if;
3142
3143          Write_Str_With_Col_Check ("(");
3144          Sprint_Comma_List (List);
3145          Write_Char (')');
3146       end if;
3147    end Sprint_Paren_Comma_List;
3148
3149    ----------------------
3150    -- Sprint_Right_Opnd --
3151    ----------------------
3152
3153    procedure Sprint_Right_Opnd (N : Node_Id) is
3154       Opnd : constant Node_Id := Right_Opnd (N);
3155
3156    begin
3157       if Paren_Count (Opnd) /= 0
3158         or else Op_Prec (Nkind (Opnd)) > Op_Prec (Nkind (N))
3159       then
3160          Sprint_Node (Opnd);
3161
3162       else
3163          Write_Char ('(');
3164          Sprint_Node (Opnd);
3165          Write_Char (')');
3166       end if;
3167    end Sprint_Right_Opnd;
3168
3169    ------------------
3170    -- Update_Itype --
3171    ------------------
3172
3173    procedure Update_Itype (Node : Node_Id) is
3174    begin
3175       if Present (Etype (Node))
3176         and then Is_Itype (Etype (Node))
3177         and then Debug_Generated_Code
3178       then
3179          Set_Sloc (Etype (Node), Sloc (Node));
3180       end if;
3181    end Update_Itype;
3182
3183    ---------------------
3184    -- Write_Char_Sloc --
3185    ---------------------
3186
3187    procedure Write_Char_Sloc (C : Character) is
3188    begin
3189       if Debug_Generated_Code and then C /= ' ' then
3190          Set_Debug_Sloc;
3191       end if;
3192
3193       Write_Char (C);
3194    end Write_Char_Sloc;
3195
3196    --------------------------------
3197    -- Write_Condition_And_Reason --
3198    --------------------------------
3199
3200    procedure Write_Condition_And_Reason (Node : Node_Id) is
3201       Cond  : constant Node_Id := Condition (Node);
3202       Image : constant String  := RT_Exception_Code'Image
3203                                     (RT_Exception_Code'Val
3204                                        (UI_To_Int (Reason (Node))));
3205
3206    begin
3207       if Present (Cond) then
3208
3209          --  If condition is a single entity, or NOT with a single entity,
3210          --  output all on one line, since it will likely fit just fine.
3211
3212          if Is_Entity_Name (Cond)
3213            or else (Nkind (Cond) = N_Op_Not
3214                      and then Is_Entity_Name (Right_Opnd (Cond)))
3215          then
3216             Write_Str_With_Col_Check (" when ");
3217             Sprint_Node (Cond);
3218             Write_Char (' ');
3219
3220             --  Otherwise for more complex condition, multiple lines
3221
3222          else
3223             Write_Str_With_Col_Check (" when");
3224             Indent := Indent + 2;
3225             Write_Indent;
3226             Sprint_Node (Cond);
3227             Write_Indent;
3228             Indent := Indent - 2;
3229          end if;
3230
3231       --  If no condition, just need a space (all on one line)
3232
3233       else
3234          Write_Char (' ');
3235       end if;
3236
3237       --  Write the reason
3238
3239       Write_Char ('"');
3240
3241       for J in 4 .. Image'Last loop
3242          if Image (J) = '_' then
3243             Write_Char (' ');
3244          else
3245             Write_Char (Fold_Lower (Image (J)));
3246          end if;
3247       end loop;
3248
3249       Write_Str ("""]");
3250    end Write_Condition_And_Reason;
3251
3252    --------------------------------
3253    -- Write_Corresponding_Source --
3254    --------------------------------
3255
3256    procedure Write_Corresponding_Source (S : String) is
3257       Loc : Source_Ptr;
3258       Src : Source_Buffer_Ptr;
3259
3260    begin
3261       --  Ignore if not in dump source text mode, or if in freeze actions
3262
3263       if Dump_Source_Text and then Freeze_Indent = 0 then
3264
3265          --  Ignore null string
3266
3267          if S = "" then
3268             return;
3269          end if;
3270
3271          --  Ignore space or semicolon at end of given string
3272
3273          if S (S'Last) = ' ' or else S (S'Last) = ';' then
3274             Write_Corresponding_Source (S (S'First .. S'Last - 1));
3275             return;
3276          end if;
3277
3278          --  Loop to look at next lines not yet printed in source file
3279
3280          for L in
3281            Last_Line_Printed + 1 .. Last_Source_Line (Current_Source_File)
3282          loop
3283             Src := Source_Text (Current_Source_File);
3284             Loc := Line_Start (L, Current_Source_File);
3285
3286             --  If comment, keep looking
3287
3288             if Src (Loc .. Loc + 1) = "--" then
3289                null;
3290
3291             --  Search to first non-blank
3292
3293             else
3294                while Src (Loc) not in Line_Terminator loop
3295
3296                   --  Non-blank found
3297
3298                   if Src (Loc) /= ' ' and then Src (Loc) /= ASCII.HT then
3299
3300                      --  Loop through characters in string to see if we match
3301
3302                      for J in S'Range loop
3303
3304                         --  If mismatch, then not the case we are looking for
3305
3306                         if Src (Loc) /= S (J) then
3307                            return;
3308                         end if;
3309
3310                         Loc := Loc + 1;
3311                      end loop;
3312
3313                      --  If we fall through, string matched, if white space or
3314                      --  semicolon after the matched string, this is the case
3315                      --  we are looking for.
3316
3317                      if Src (Loc) in Line_Terminator
3318                        or else Src (Loc) = ' '
3319                        or else Src (Loc) = ASCII.HT
3320                        or else Src (Loc) = ';'
3321                      then
3322                         --  So output source lines up to and including this one
3323
3324                         Write_Source_Lines (L);
3325                         return;
3326                      end if;
3327                   end if;
3328
3329                   Loc := Loc + 1;
3330                end loop;
3331             end if;
3332
3333          --  Line was all blanks, or a comment line, keep looking
3334
3335          end loop;
3336       end if;
3337    end Write_Corresponding_Source;
3338
3339    -----------------------
3340    -- Write_Discr_Specs --
3341    -----------------------
3342
3343    procedure Write_Discr_Specs (N : Node_Id) is
3344       Specs : List_Id;
3345       Spec  : Node_Id;
3346
3347    begin
3348       Specs := Discriminant_Specifications (N);
3349
3350       if Present (Specs) then
3351          Write_Str_With_Col_Check (" (");
3352          Spec := First (Specs);
3353
3354          loop
3355             Sprint_Node (Spec);
3356             Next (Spec);
3357             exit when Spec = Empty;
3358
3359             --  Add semicolon, unless we are printing original tree and the
3360             --  next specification is part of a list (but not the first
3361             --  element of that list)
3362
3363             if not Dump_Original_Only or else not Prev_Ids (Spec) then
3364                Write_Str ("; ");
3365             end if;
3366          end loop;
3367
3368          Write_Char (')');
3369       end if;
3370    end Write_Discr_Specs;
3371
3372    -----------------
3373    -- Write_Ekind --
3374    -----------------
3375
3376    procedure Write_Ekind (E : Entity_Id) is
3377       S : constant String := Entity_Kind'Image (Ekind (E));
3378
3379    begin
3380       Name_Len := S'Length;
3381       Name_Buffer (1 .. Name_Len) := S;
3382       Set_Casing (Mixed_Case);
3383       Write_Str_With_Col_Check (Name_Buffer (1 .. Name_Len));
3384    end Write_Ekind;
3385
3386    --------------
3387    -- Write_Id --
3388    --------------
3389
3390    procedure Write_Id (N : Node_Id) is
3391    begin
3392       --  Deal with outputting Itype
3393
3394       --  Note: if we are printing the full tree with -gnatds, then we may
3395       --  end up picking up the Associated_Node link from a generic template
3396       --  here which overlaps the Entity field, but as documented, Write_Itype
3397       --  is defended against junk calls.
3398
3399       if Nkind (N) in N_Entity then
3400          Write_Itype (N);
3401       elsif Nkind (N) in N_Has_Entity then
3402          Write_Itype (Entity (N));
3403       end if;
3404
3405       --  Case of a defining identifier
3406
3407       if Nkind (N) = N_Defining_Identifier then
3408
3409          --  If defining identifier has an interface name (and no
3410          --  address clause), then we output the interface name.
3411
3412          if (Is_Imported (N) or else Is_Exported (N))
3413            and then Present (Interface_Name (N))
3414            and then No (Address_Clause (N))
3415          then
3416             String_To_Name_Buffer (Strval (Interface_Name (N)));
3417             Write_Str_With_Col_Check (Name_Buffer (1 .. Name_Len));
3418
3419          --  If no interface name (or inactive because there was
3420          --  an address clause), then just output the Chars name.
3421
3422          else
3423             Write_Name_With_Col_Check (Chars (N));
3424          end if;
3425
3426       --  Case of selector of an expanded name where the expanded name
3427       --  has an associated entity, output this entity.
3428
3429       elsif Nkind (Parent (N)) = N_Expanded_Name
3430         and then Selector_Name (Parent (N)) = N
3431         and then Present (Entity (Parent (N)))
3432       then
3433          Write_Id (Entity (Parent (N)));
3434
3435       --  For any other node with an associated entity, output it
3436
3437       elsif Nkind (N) in N_Has_Entity
3438         and then Present (Entity_Or_Associated_Node (N))
3439         and then Nkind (Entity_Or_Associated_Node (N)) in N_Entity
3440       then
3441          Write_Id (Entity (N));
3442
3443       --  All other cases, we just print the Chars field
3444
3445       else
3446          Write_Name_With_Col_Check (Chars (N));
3447       end if;
3448    end Write_Id;
3449
3450    -----------------------
3451    -- Write_Identifiers --
3452    -----------------------
3453
3454    function Write_Identifiers (Node : Node_Id) return Boolean is
3455    begin
3456       Sprint_Node (Defining_Identifier (Node));
3457       Update_Itype (Defining_Identifier (Node));
3458
3459       --  The remainder of the declaration must be printed unless we are
3460       --  printing the original tree and this is not the last identifier
3461
3462       return
3463          not Dump_Original_Only or else not More_Ids (Node);
3464
3465    end Write_Identifiers;
3466
3467    ------------------------
3468    -- Write_Implicit_Def --
3469    ------------------------
3470
3471    procedure Write_Implicit_Def (E : Entity_Id) is
3472       Ind : Node_Id;
3473
3474    begin
3475       case Ekind (E) is
3476          when E_Array_Subtype =>
3477             Write_Str_With_Col_Check ("subtype ");
3478             Write_Id (E);
3479             Write_Str_With_Col_Check (" is ");
3480             Write_Id (Base_Type (E));
3481             Write_Str_With_Col_Check (" (");
3482
3483             Ind := First_Index (E);
3484             while Present (Ind) loop
3485                Sprint_Node (Ind);
3486                Next_Index (Ind);
3487
3488                if Present (Ind) then
3489                   Write_Str (", ");
3490                end if;
3491             end loop;
3492
3493             Write_Str (");");
3494
3495          when E_Signed_Integer_Subtype | E_Enumeration_Subtype =>
3496             Write_Str_With_Col_Check ("subtype ");
3497             Write_Id (E);
3498             Write_Str (" is ");
3499             Write_Id (Etype (E));
3500             Write_Str_With_Col_Check (" range ");
3501             Sprint_Node (Scalar_Range (E));
3502             Write_Str (";");
3503
3504          when others =>
3505             Write_Str_With_Col_Check ("type ");
3506             Write_Id (E);
3507             Write_Str_With_Col_Check (" is <");
3508             Write_Ekind (E);
3509             Write_Str (">;");
3510       end case;
3511
3512    end Write_Implicit_Def;
3513
3514    ------------------
3515    -- Write_Indent --
3516    ------------------
3517
3518    procedure Write_Indent is
3519       Loc : constant Source_Ptr := Sloc (Dump_Node);
3520
3521    begin
3522       if Indent_Annull_Flag then
3523          Indent_Annull_Flag := False;
3524       else
3525          --  Deal with Dump_Source_Text output. Note that we ignore implicit
3526          --  label declarations, since they typically have the sloc of the
3527          --  corresponding label, which really messes up the -gnatL output.
3528
3529          if Dump_Source_Text
3530            and then Loc > No_Location
3531            and then Nkind (Dump_Node) /= N_Implicit_Label_Declaration
3532          then
3533             if Get_Source_File_Index (Loc) = Current_Source_File then
3534                Write_Source_Lines
3535                  (Get_Physical_Line_Number (Sloc (Dump_Node)));
3536             end if;
3537          end if;
3538
3539          Write_Eol;
3540
3541          for J in 1 .. Indent loop
3542             Write_Char (' ');
3543          end loop;
3544       end if;
3545    end Write_Indent;
3546
3547    ------------------------------
3548    -- Write_Indent_Identifiers --
3549    ------------------------------
3550
3551    function Write_Indent_Identifiers (Node : Node_Id) return Boolean is
3552    begin
3553       --  We need to start a new line for every node, except in the case
3554       --  where we are printing the original tree and this is not the first
3555       --  defining identifier in the list.
3556
3557       if not Dump_Original_Only or else not Prev_Ids (Node) then
3558          Write_Indent;
3559
3560       --  If printing original tree and this is not the first defining
3561       --  identifier in the list, then the previous call to this procedure
3562       --  printed only the name, and we add a comma to separate the names.
3563
3564       else
3565          Write_Str (", ");
3566       end if;
3567
3568       Sprint_Node (Defining_Identifier (Node));
3569
3570       --  The remainder of the declaration must be printed unless we are
3571       --  printing the original tree and this is not the last identifier
3572
3573       return
3574          not Dump_Original_Only or else not More_Ids (Node);
3575    end Write_Indent_Identifiers;
3576
3577    -----------------------------------
3578    -- Write_Indent_Identifiers_Sloc --
3579    -----------------------------------
3580
3581    function Write_Indent_Identifiers_Sloc (Node : Node_Id) return Boolean is
3582    begin
3583       --  We need to start a new line for every node, except in the case
3584       --  where we are printing the original tree and this is not the first
3585       --  defining identifier in the list.
3586
3587       if not Dump_Original_Only or else not Prev_Ids (Node) then
3588          Write_Indent;
3589
3590       --  If printing original tree and this is not the first defining
3591       --  identifier in the list, then the previous call to this procedure
3592       --  printed only the name, and we add a comma to separate the names.
3593
3594       else
3595          Write_Str (", ");
3596       end if;
3597
3598       Set_Debug_Sloc;
3599       Sprint_Node (Defining_Identifier (Node));
3600
3601       --  The remainder of the declaration must be printed unless we are
3602       --  printing the original tree and this is not the last identifier
3603
3604       return not Dump_Original_Only or else not More_Ids (Node);
3605    end Write_Indent_Identifiers_Sloc;
3606
3607    ----------------------
3608    -- Write_Indent_Str --
3609    ----------------------
3610
3611    procedure Write_Indent_Str (S : String) is
3612    begin
3613       Write_Corresponding_Source (S);
3614       Write_Indent;
3615       Write_Str (S);
3616    end Write_Indent_Str;
3617
3618    ---------------------------
3619    -- Write_Indent_Str_Sloc --
3620    ---------------------------
3621
3622    procedure Write_Indent_Str_Sloc (S : String) is
3623    begin
3624       Write_Corresponding_Source (S);
3625       Write_Indent;
3626       Write_Str_Sloc (S);
3627    end Write_Indent_Str_Sloc;
3628
3629    -----------------
3630    -- Write_Itype --
3631    -----------------
3632
3633    procedure Write_Itype (Typ : Entity_Id) is
3634
3635       procedure Write_Header (T : Boolean := True);
3636       --  Write type if T is True, subtype if T is false
3637
3638       ------------------
3639       -- Write_Header --
3640       ------------------
3641
3642       procedure Write_Header (T : Boolean := True) is
3643       begin
3644          if T then
3645             Write_Str ("[type ");
3646          else
3647             Write_Str ("[subtype ");
3648          end if;
3649
3650          Write_Name_With_Col_Check (Chars (Typ));
3651          Write_Str (" is ");
3652       end Write_Header;
3653
3654    --  Start of processing for Write_Itype
3655
3656    begin
3657       if Nkind (Typ) in N_Entity
3658         and then Is_Itype (Typ)
3659         and then not Itype_Printed (Typ)
3660       then
3661          --  Itype to be printed
3662
3663          declare
3664             B : constant Node_Id := Etype (Typ);
3665             X : Node_Id;
3666             P : constant Node_Id := Parent (Typ);
3667
3668             S : constant Saved_Output_Buffer := Save_Output_Buffer;
3669             --  Save current output buffer
3670
3671             Old_Sloc : Source_Ptr;
3672             --  Save sloc of related node, so it is not modified when
3673             --  printing with -gnatD.
3674
3675          begin
3676             --  Write indentation at start of line
3677
3678             for J in 1 .. Indent loop
3679                Write_Char (' ');
3680             end loop;
3681
3682             --  If we have a constructed declaration for the itype, print it
3683
3684             if Present (P)
3685               and then Nkind (P) in N_Declaration
3686               and then Defining_Entity (P) = Typ
3687             then
3688                --  We must set Itype_Printed true before the recursive call to
3689                --  print the node, otherwise we get an infinite recursion!
3690
3691                Set_Itype_Printed (Typ, True);
3692
3693                --  Write the declaration enclosed in [], avoiding new line
3694                --  at start of declaration, and semicolon at end.
3695
3696                --  Note: The itype may be imported from another unit, in which
3697                --  case we do not want to modify the Sloc of the declaration.
3698                --  Otherwise the itype may appear to be in the current unit,
3699                --  and the back-end will reject a reference out of scope.
3700
3701                Write_Char ('[');
3702                Indent_Annull_Flag := True;
3703                Old_Sloc := Sloc (P);
3704                Sprint_Node (P);
3705                Set_Sloc (P, Old_Sloc);
3706                Write_Erase_Char (';');
3707
3708             --  If no constructed declaration, then we have to concoct the
3709             --  source corresponding to the type entity that we have at hand.
3710
3711             else
3712                case Ekind (Typ) is
3713
3714                   --  Access types and subtypes
3715
3716                   when Access_Kind =>
3717                      Write_Header (Ekind (Typ) = E_Access_Type);
3718                      Write_Str ("access ");
3719
3720                      if Is_Access_Constant (Typ) then
3721                         Write_Str ("constant ");
3722                      elsif Can_Never_Be_Null (Typ) then
3723                         Write_Str ("not null ");
3724                      end if;
3725
3726                      Write_Id (Directly_Designated_Type (Typ));
3727
3728                   --  Array types and string types
3729
3730                   when E_Array_Type | E_String_Type =>
3731                      Write_Header;
3732                      Write_Str ("array (");
3733
3734                      X := First_Index (Typ);
3735                      loop
3736                         Sprint_Node (X);
3737
3738                         if not Is_Constrained (Typ) then
3739                            Write_Str (" range <>");
3740                         end if;
3741
3742                         Next_Index (X);
3743                         exit when No (X);
3744                         Write_Str (", ");
3745                      end loop;
3746
3747                      Write_Str (") of ");
3748                      X := Component_Type (Typ);
3749
3750                      --  Preserve sloc of component type, which is defined
3751                      --  elsewhere than the itype (see comment above).
3752
3753                      Old_Sloc := Sloc (X);
3754                      Sprint_Node (X);
3755                      Set_Sloc (X, Old_Sloc);
3756
3757                      --  Array subtypes and string subtypes.
3758                      --  Preserve Sloc of index subtypes, as above.
3759
3760                   when E_Array_Subtype | E_String_Subtype =>
3761                      Write_Header (False);
3762                      Write_Id (Etype (Typ));
3763                      Write_Str (" (");
3764
3765                      X := First_Index (Typ);
3766                      loop
3767                         Old_Sloc := Sloc (X);
3768                         Sprint_Node (X);
3769                         Set_Sloc (X, Old_Sloc);
3770                         Next_Index (X);
3771                         exit when No (X);
3772                         Write_Str (", ");
3773                      end loop;
3774
3775                      Write_Char (')');
3776
3777                   --  Signed integer types, and modular integer subtypes,
3778                   --  and also enumeration subtypes.
3779
3780                   when E_Signed_Integer_Type     |
3781                        E_Signed_Integer_Subtype  |
3782                        E_Modular_Integer_Subtype |
3783                        E_Enumeration_Subtype     =>
3784
3785                      Write_Header (Ekind (Typ) = E_Signed_Integer_Type);
3786
3787                      if Ekind (Typ) = E_Signed_Integer_Type then
3788                         Write_Str ("new ");
3789                      end if;
3790
3791                      Write_Id (B);
3792
3793                      --  Print bounds if different from base type
3794
3795                      declare
3796                         L  : constant Node_Id := Type_Low_Bound (Typ);
3797                         H  : constant Node_Id := Type_High_Bound (Typ);
3798                         LE : Node_Id;
3799                         HE : Node_Id;
3800
3801                      begin
3802                         --  B can either be a scalar type, in which case the
3803                         --  declaration of Typ may constrain it with different
3804                         --  bounds, or a private type, in which case we know
3805                         --  that the declaration of Typ cannot have a scalar
3806                         --  constraint.
3807
3808                         if Is_Scalar_Type (B) then
3809                            LE := Type_Low_Bound (B);
3810                            HE := Type_High_Bound (B);
3811                         else
3812                            LE := Empty;
3813                            HE := Empty;
3814                         end if;
3815
3816                         if No (LE)
3817                           or else (True
3818                             and then Nkind (L) = N_Integer_Literal
3819                             and then Nkind (H) = N_Integer_Literal
3820                             and then Nkind (LE) = N_Integer_Literal
3821                             and then Nkind (HE) = N_Integer_Literal
3822                             and then UI_Eq (Intval (L), Intval (LE))
3823                             and then UI_Eq (Intval (H), Intval (HE)))
3824                         then
3825                            null;
3826
3827                         else
3828                            Write_Str (" range ");
3829                            Sprint_Node (Type_Low_Bound (Typ));
3830                            Write_Str (" .. ");
3831                            Sprint_Node (Type_High_Bound (Typ));
3832                         end if;
3833                      end;
3834
3835                   --  Modular integer types
3836
3837                   when E_Modular_Integer_Type =>
3838                      Write_Header;
3839                      Write_Str (" mod ");
3840                      Write_Uint_With_Col_Check (Modulus (Typ), Auto);
3841
3842                   --  Floating point types and subtypes
3843
3844                   when E_Floating_Point_Type    |
3845                        E_Floating_Point_Subtype =>
3846
3847                      Write_Header (Ekind (Typ) = E_Floating_Point_Type);
3848
3849                      if Ekind (Typ) = E_Floating_Point_Type then
3850                         Write_Str ("new ");
3851                      end if;
3852
3853                      Write_Id (Etype (Typ));
3854
3855                      if Digits_Value (Typ) /= Digits_Value (Etype (Typ)) then
3856                         Write_Str (" digits ");
3857                         Write_Uint_With_Col_Check
3858                           (Digits_Value (Typ), Decimal);
3859                      end if;
3860
3861                      --  Print bounds if not different from base type
3862
3863                      declare
3864                         L  : constant Node_Id := Type_Low_Bound (Typ);
3865                         H  : constant Node_Id := Type_High_Bound (Typ);
3866                         LE : constant Node_Id := Type_Low_Bound (B);
3867                         HE : constant Node_Id := Type_High_Bound (B);
3868
3869                      begin
3870                         if Nkind (L) = N_Real_Literal
3871                           and then Nkind (H) = N_Real_Literal
3872                           and then Nkind (LE) = N_Real_Literal
3873                           and then Nkind (HE) = N_Real_Literal
3874                           and then UR_Eq (Realval (L), Realval (LE))
3875                           and then UR_Eq (Realval (H), Realval (HE))
3876                         then
3877                            null;
3878
3879                         else
3880                            Write_Str (" range ");
3881                            Sprint_Node (Type_Low_Bound (Typ));
3882                            Write_Str (" .. ");
3883                            Sprint_Node (Type_High_Bound (Typ));
3884                         end if;
3885                      end;
3886
3887                   --  Record subtypes
3888
3889                   when E_Record_Subtype =>
3890                      Write_Header (False);
3891                      Write_Str ("record");
3892                      Indent_Begin;
3893
3894                      declare
3895                         C : Entity_Id;
3896                      begin
3897                         C := First_Entity (Typ);
3898                         while Present (C) loop
3899                            Write_Indent;
3900                            Write_Id (C);
3901                            Write_Str (" : ");
3902                            Write_Id (Etype (C));
3903                            Next_Entity (C);
3904                         end loop;
3905                      end;
3906
3907                      Indent_End;
3908                      Write_Indent_Str (" end record");
3909
3910                   --  Class-Wide types
3911
3912                   when E_Class_Wide_Type    |
3913                        E_Class_Wide_Subtype =>
3914                      Write_Header;
3915                      Write_Name_With_Col_Check (Chars (Etype (Typ)));
3916                      Write_Str ("'Class");
3917
3918                   --  Subprogram types
3919
3920                   when E_Subprogram_Type =>
3921                      Write_Header;
3922
3923                      if Etype (Typ) = Standard_Void_Type then
3924                         Write_Str ("procedure");
3925                      else
3926                         Write_Str ("function");
3927                      end if;
3928
3929                      if Present (First_Entity (Typ)) then
3930                         Write_Str (" (");
3931
3932                         declare
3933                            Param : Entity_Id;
3934
3935                         begin
3936                            Param := First_Entity (Typ);
3937                            loop
3938                               Write_Id (Param);
3939                               Write_Str (" : ");
3940
3941                               if Ekind (Param) = E_In_Out_Parameter then
3942                                  Write_Str ("in out ");
3943                               elsif Ekind (Param) = E_Out_Parameter then
3944                                  Write_Str ("out ");
3945                               end if;
3946
3947                               Write_Id (Etype (Param));
3948                               Next_Entity (Param);
3949                               exit when No (Param);
3950                               Write_Str (", ");
3951                            end loop;
3952
3953                            Write_Char (')');
3954                         end;
3955                      end if;
3956
3957                      if Etype (Typ) /= Standard_Void_Type then
3958                         Write_Str (" return ");
3959                         Write_Id (Etype (Typ));
3960                      end if;
3961
3962                   when E_String_Literal_Subtype =>
3963                      declare
3964                         LB  : constant Uint :=
3965                                 Expr_Value (String_Literal_Low_Bound (Typ));
3966                         Len : constant Uint :=
3967                                 String_Literal_Length (Typ);
3968                      begin
3969                         Write_Str ("String (");
3970                         Write_Int (UI_To_Int (LB));
3971                         Write_Str (" .. ");
3972                         Write_Int (UI_To_Int (LB + Len) - 1);
3973                         Write_Str (");");
3974                      end;
3975
3976                   --  For all other Itypes, print ??? (fill in later)
3977
3978                   when others =>
3979                      Write_Header (True);
3980                      Write_Str ("???");
3981
3982                end case;
3983             end if;
3984
3985             --  Add terminating bracket and restore output buffer
3986
3987             Write_Char (']');
3988             Write_Eol;
3989             Restore_Output_Buffer (S);
3990          end;
3991
3992          Set_Itype_Printed (Typ);
3993       end if;
3994    end Write_Itype;
3995
3996    -------------------------------
3997    -- Write_Name_With_Col_Check --
3998    -------------------------------
3999
4000    procedure Write_Name_With_Col_Check (N : Name_Id) is
4001       J : Natural;
4002       K : Natural;
4003       L : Natural;
4004
4005    begin
4006       Get_Name_String (N);
4007
4008       --  Deal with -gnatdI which replaces any sequence Cnnnb where C is an
4009       --  upper case letter, nnn is one or more digits and b is a lower case
4010       --  letter by C...b, so that listings do not depend on serial numbers.
4011
4012       if Debug_Flag_II then
4013          J := 1;
4014          while J < Name_Len - 1 loop
4015             if Name_Buffer (J) in 'A' .. 'Z'
4016               and then Name_Buffer (J + 1) in '0' .. '9'
4017             then
4018                K := J + 1;
4019                while K < Name_Len loop
4020                   exit when Name_Buffer (K) not in '0' .. '9';
4021                   K := K + 1;
4022                end loop;
4023
4024                if Name_Buffer (K) in 'a' .. 'z' then
4025                   L := Name_Len - K + 1;
4026
4027                   Name_Buffer (J + 4 .. J + L + 3) :=
4028                     Name_Buffer (K .. Name_Len);
4029                   Name_Buffer (J + 1 .. J + 3) := "...";
4030                   Name_Len := J + L + 3;
4031                   J := J + 5;
4032
4033                else
4034                   J := K;
4035                end if;
4036
4037             else
4038                J := J + 1;
4039             end if;
4040          end loop;
4041       end if;
4042
4043       --  Fall through for normal case
4044
4045       Write_Str_With_Col_Check (Name_Buffer (1 .. Name_Len));
4046    end Write_Name_With_Col_Check;
4047
4048    ------------------------------------
4049    -- Write_Name_With_Col_Check_Sloc --
4050    ------------------------------------
4051
4052    procedure Write_Name_With_Col_Check_Sloc (N : Name_Id) is
4053    begin
4054       Get_Name_String (N);
4055       Write_Str_With_Col_Check_Sloc (Name_Buffer (1 .. Name_Len));
4056    end Write_Name_With_Col_Check_Sloc;
4057
4058    --------------------
4059    -- Write_Operator --
4060    --------------------
4061
4062    procedure Write_Operator (N : Node_Id; S : String) is
4063       F : Natural := S'First;
4064       T : Natural := S'Last;
4065
4066    begin
4067       --  If no overflow check, just write string out, and we are done
4068
4069       if not Do_Overflow_Check (N) then
4070          Write_Str_Sloc (S);
4071
4072       --  If overflow check, we want to surround the operator with curly
4073       --  brackets, but not include spaces within the brackets.
4074
4075       else
4076          if S (F) = ' ' then
4077             Write_Char (' ');
4078             F := F + 1;
4079          end if;
4080
4081          if S (T) = ' ' then
4082             T := T - 1;
4083          end if;
4084
4085          Write_Char ('{');
4086          Write_Str_Sloc (S (F .. T));
4087          Write_Char ('}');
4088
4089          if S (S'Last) = ' ' then
4090             Write_Char (' ');
4091          end if;
4092       end if;
4093    end Write_Operator;
4094
4095    -----------------------
4096    -- Write_Param_Specs --
4097    -----------------------
4098
4099    procedure Write_Param_Specs (N : Node_Id) is
4100       Specs  : List_Id;
4101       Spec   : Node_Id;
4102       Formal : Node_Id;
4103
4104    begin
4105       Specs := Parameter_Specifications (N);
4106
4107       if Is_Non_Empty_List (Specs) then
4108          Write_Str_With_Col_Check (" (");
4109          Spec := First (Specs);
4110
4111          loop
4112             Sprint_Node (Spec);
4113             Formal := Defining_Identifier (Spec);
4114             Next (Spec);
4115             exit when Spec = Empty;
4116
4117             --  Add semicolon, unless we are printing original tree and the
4118             --  next specification is part of a list (but not the first element
4119             --  of that list).
4120
4121             if not Dump_Original_Only or else not Prev_Ids (Spec) then
4122                Write_Str ("; ");
4123             end if;
4124          end loop;
4125
4126          --  Write out any extra formals
4127
4128          while Present (Extra_Formal (Formal)) loop
4129             Formal := Extra_Formal (Formal);
4130             Write_Str ("; ");
4131             Write_Name_With_Col_Check (Chars (Formal));
4132             Write_Str (" : ");
4133             Write_Name_With_Col_Check (Chars (Etype (Formal)));
4134          end loop;
4135
4136          Write_Char (')');
4137       end if;
4138    end Write_Param_Specs;
4139
4140    -----------------------
4141    -- Write_Rewrite_Str --
4142    -----------------------
4143
4144    procedure Write_Rewrite_Str (S : String) is
4145    begin
4146       if not Dump_Generated_Only then
4147          if S'Length = 3 and then S = ">>>" then
4148             Write_Str (">>>");
4149          else
4150             Write_Str_With_Col_Check (S);
4151          end if;
4152       end if;
4153    end Write_Rewrite_Str;
4154
4155    -----------------------
4156    -- Write_Source_Line --
4157    -----------------------
4158
4159    procedure Write_Source_Line (L : Physical_Line_Number) is
4160       Loc : Source_Ptr;
4161       Src : Source_Buffer_Ptr;
4162       Scn : Source_Ptr;
4163
4164    begin
4165       if Dump_Source_Text then
4166          Src := Source_Text (Current_Source_File);
4167          Loc := Line_Start (L, Current_Source_File);
4168          Write_Eol;
4169
4170          --  See if line is a comment line, if not, and if not line one,
4171          --  precede with blank line.
4172
4173          Scn := Loc;
4174          while Src (Scn) = ' ' or else Src (Scn) = ASCII.HT loop
4175             Scn := Scn + 1;
4176          end loop;
4177
4178          if (Src (Scn) in Line_Terminator
4179               or else Src (Scn .. Scn + 1) /= "--")
4180            and then L /= 1
4181          then
4182             Write_Eol;
4183          end if;
4184
4185          --  Now write the source text of the line
4186
4187          Write_Str ("-- ");
4188          Write_Int (Int (L));
4189          Write_Str (": ");
4190
4191          while Src (Loc) not in Line_Terminator loop
4192             Write_Char (Src (Loc));
4193             Loc := Loc + 1;
4194          end loop;
4195       end if;
4196    end Write_Source_Line;
4197
4198    ------------------------
4199    -- Write_Source_Lines --
4200    ------------------------
4201
4202    procedure Write_Source_Lines (L : Physical_Line_Number) is
4203    begin
4204       while Last_Line_Printed < L loop
4205          Last_Line_Printed := Last_Line_Printed + 1;
4206          Write_Source_Line (Last_Line_Printed);
4207       end loop;
4208    end Write_Source_Lines;
4209
4210    --------------------
4211    -- Write_Str_Sloc --
4212    --------------------
4213
4214    procedure Write_Str_Sloc (S : String) is
4215    begin
4216       for J in S'Range loop
4217          Write_Char_Sloc (S (J));
4218       end loop;
4219    end Write_Str_Sloc;
4220
4221    ------------------------------
4222    -- Write_Str_With_Col_Check --
4223    ------------------------------
4224
4225    procedure Write_Str_With_Col_Check (S : String) is
4226    begin
4227       if Int (S'Last) + Column > Sprint_Line_Limit then
4228          Write_Indent_Str ("  ");
4229
4230          if S (S'First) = ' ' then
4231             Write_Str (S (S'First + 1 .. S'Last));
4232          else
4233             Write_Str (S);
4234          end if;
4235
4236       else
4237          Write_Str (S);
4238       end if;
4239    end Write_Str_With_Col_Check;
4240
4241    -----------------------------------
4242    -- Write_Str_With_Col_Check_Sloc --
4243    -----------------------------------
4244
4245    procedure Write_Str_With_Col_Check_Sloc (S : String) is
4246    begin
4247       if Int (S'Last) + Column > Sprint_Line_Limit then
4248          Write_Indent_Str ("  ");
4249
4250          if S (S'First) = ' ' then
4251             Write_Str_Sloc (S (S'First + 1 .. S'Last));
4252          else
4253             Write_Str_Sloc (S);
4254          end if;
4255
4256       else
4257          Write_Str_Sloc (S);
4258       end if;
4259    end Write_Str_With_Col_Check_Sloc;
4260
4261    ---------------------------
4262    -- Write_Subprogram_Name --
4263    ---------------------------
4264
4265    procedure Write_Subprogram_Name (N : Node_Id) is
4266    begin
4267       if not Comes_From_Source (N)
4268         and then Is_Entity_Name (N)
4269       then
4270          declare
4271             Ent : constant Entity_Id := Entity (N);
4272          begin
4273             if not In_Extended_Main_Source_Unit (Ent)
4274               and then
4275                 Is_Predefined_File_Name
4276                   (Unit_File_Name (Get_Source_Unit (Ent)))
4277             then
4278                --  Run-time routine name, output name with a preceding dollar
4279                --  making sure that we do not get a line split between them.
4280
4281                Col_Check (Length_Of_Name (Chars (Ent)) + 1);
4282                Write_Char ('$');
4283                Write_Name (Chars (Ent));
4284                return;
4285             end if;
4286          end;
4287       end if;
4288
4289       --  Normal case, not a run-time routine name
4290
4291       Sprint_Node (N);
4292    end Write_Subprogram_Name;
4293
4294    -------------------------------
4295    -- Write_Uint_With_Col_Check --
4296    -------------------------------
4297
4298    procedure Write_Uint_With_Col_Check (U : Uint; Format : UI_Format) is
4299    begin
4300       Col_Check (UI_Decimal_Digits_Hi (U));
4301       UI_Write (U, Format);
4302    end Write_Uint_With_Col_Check;
4303
4304    ------------------------------------
4305    -- Write_Uint_With_Col_Check_Sloc --
4306    ------------------------------------
4307
4308    procedure Write_Uint_With_Col_Check_Sloc (U : Uint; Format : UI_Format) is
4309    begin
4310       Col_Check (UI_Decimal_Digits_Hi (U));
4311       Set_Debug_Sloc;
4312       UI_Write (U, Format);
4313    end Write_Uint_With_Col_Check_Sloc;
4314
4315    -------------------------------------
4316    -- Write_Ureal_With_Col_Check_Sloc --
4317    -------------------------------------
4318
4319    procedure Write_Ureal_With_Col_Check_Sloc (U : Ureal) is
4320       D : constant Uint := Denominator (U);
4321       N : constant Uint := Numerator (U);
4322
4323    begin
4324       Col_Check
4325         (UI_Decimal_Digits_Hi (D) + UI_Decimal_Digits_Hi (N) + 4);
4326       Set_Debug_Sloc;
4327       UR_Write (U);
4328    end Write_Ureal_With_Col_Check_Sloc;
4329
4330 end Sprint;