OSDN Git Service

2003-10-21 Arnaud Charlet <charlet@act-europe.fr>
[pf3gnuchains/gcc-fork.git] / gcc / ada / comperr.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              C O M P E R R                               --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2003 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 2,  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 COPYING.  If not, write --
19 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
20 -- MA 02111-1307, USA.                                                      --
21 --                                                                          --
22 -- GNAT was originally developed  by the GNAT team at  New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
24 --                                                                          --
25 ------------------------------------------------------------------------------
26
27 --  This package contains routines called when a fatal internal compiler
28 --  error is detected. Calls to these routines cause termination of the
29 --  current compilation with appropriate error output.
30
31 with Atree;    use Atree;
32 with Debug;    use Debug;
33 with Errout;   use Errout;
34 with Fname;    use Fname;
35 with Gnatvsn;  use Gnatvsn;
36 with Lib;      use Lib;
37 with Namet;    use Namet;
38 with Osint;    use Osint;
39 with Output;   use Output;
40 with Sinput;   use Sinput;
41 with Sprint;   use Sprint;
42 with Sdefault; use Sdefault;
43 with Treepr;   use Treepr;
44 with Types;    use Types;
45
46 with Ada.Exceptions; use Ada.Exceptions;
47
48 with System.Soft_Links; use System.Soft_Links;
49
50 package body Comperr is
51
52    ----------------
53    -- Local Data --
54    ----------------
55
56    Abort_In_Progress : Boolean := False;
57    --  Used to prevent runaway recursion if something segfaults
58    --  while processing a previous abort.
59
60    -----------------------
61    -- Local Subprograms --
62    -----------------------
63
64    procedure Repeat_Char (Char : Character; Col : Nat; After : Character);
65    --  Output Char until current column is at or past Col, and then output
66    --  the character given by After (if column is already past Col on entry,
67    --  then the effect is simply to output the After character).
68
69    --------------------
70    -- Compiler_Abort --
71    --------------------
72
73    procedure Compiler_Abort
74      (X    : String;
75       Code : Integer := 0)
76    is
77       --  The procedures below output a "bug box" with information about
78       --  the cause of the compiler abort and about the preferred method
79       --  of reporting bugs. The default is a bug box appropriate for
80       --  the FSF version of GNAT, but there are specializations for
81       --  the GNATPRO and Public releases by Ada Core Technologies.
82
83       Public_Version  : constant Boolean := Gnat_Version_Type = "PUBLIC ";
84       --  Set True for the public version of GNAT
85
86       GNATPRO_Version : constant Boolean := Gnat_Version_Type = "GNATPRO";
87       --  Set True for the GNATPRO version of GNAT
88
89       procedure End_Line;
90       --  Add blanks up to column 76, and then a final vertical bar
91
92       --------------
93       -- End_Line --
94       --------------
95
96       procedure End_Line is
97       begin
98          Repeat_Char (' ', 76, '|');
99          Write_Eol;
100       end End_Line;
101
102    --  Start of processing for Compiler_Abort
103
104    begin
105       --  Prevent recursion through Compiler_Abort, e.g. via SIGSEGV.
106
107       if Abort_In_Progress then
108          Exit_Program (E_Abort);
109       end if;
110
111       Abort_In_Progress := True;
112
113       --  If any errors have already occurred, then we guess that the abort
114       --  may well be caused by previous errors, and we don't make too much
115       --  fuss about it, since we want to let programmer fix the errors first.
116
117       --  Debug flag K disables this behavior (useful for debugging)
118
119       if Serious_Errors_Detected /= 0 and then not Debug_Flag_K then
120          Errout.Finalize;
121
122          Set_Standard_Error;
123          Write_Str ("compilation abandoned due to previous error");
124          Write_Eol;
125
126          Set_Standard_Output;
127          Source_Dump;
128          Tree_Dump;
129          Exit_Program (E_Errors);
130
131       --  Otherwise give message with details of the abort
132
133       else
134          Set_Standard_Error;
135
136          --  Generate header for bug box
137
138          Write_Char ('+');
139          Repeat_Char ('=', 29, 'G');
140          Write_Str ("NAT BUG DETECTED");
141          Repeat_Char ('=', 76, '+');
142          Write_Eol;
143
144          --  Output GNAT version identification
145
146          Write_Str ("| ");
147          Write_Str (Gnat_Version_String);
148          Write_Str (" (");
149
150          --  Output target name, deleting junk final reverse slash
151
152          if Target_Name.all (Target_Name.all'Last) = '\'
153            or else Target_Name.all (Target_Name.all'Last) = '/'
154          then
155             Write_Str (Target_Name.all (1 .. Target_Name.all'Last - 1));
156          else
157             Write_Str (Target_Name.all);
158          end if;
159
160          --  Output identification of error
161
162          Write_Str (") ");
163
164          if X'Length + Column > 76 then
165             if Code < 0 then
166                Write_Str ("GCC error:");
167             end if;
168
169             End_Line;
170
171             Write_Str ("| ");
172          end if;
173
174          if X'Length > 70 then
175             declare
176                Last_Blank : Integer := 70;
177
178             begin
179                for P in 40 .. 69 loop
180                   if X (P) = ' ' then
181                      Last_Blank := P;
182                   end if;
183                end loop;
184
185                Write_Str (X (1 .. Last_Blank));
186                End_Line;
187                Write_Str ("|    ");
188                Write_Str (X (Last_Blank + 1 .. X'Length));
189             end;
190          else
191             Write_Str (X);
192          end if;
193
194          if Code > 0 then
195             Write_Str (", Code=");
196             Write_Int (Int (Code));
197
198          elsif Code = 0 then
199
200             --  For exception case, get exception message from the TSD. Note
201             --  that it would be neater and cleaner to pass the exception
202             --  message (obtained from Exception_Message) as a parameter to
203             --  Compiler_Abort, but we can't do this quite yet since it would
204             --  cause bootstrap path problems for 3.10 to 3.11.
205
206             Write_Char (' ');
207             Write_Str (Exception_Message (Get_Current_Excep.all.all));
208          end if;
209
210          End_Line;
211
212          --  Output source location information
213
214          if Sloc (Current_Error_Node) <= Standard_Location
215            or else Sloc (Current_Error_Node) = No_Location
216          then
217             Write_Str ("| No source file position information available");
218             End_Line;
219          else
220             Write_Str ("| Error detected at ");
221             Write_Location (Sloc (Current_Error_Node));
222             End_Line;
223          end if;
224
225          --  There are two cases now. If the file gnat_bug.box exists,
226          --  we use the contents of this file at this point.
227
228          declare
229             Lo  : Source_Ptr;
230             Hi  : Source_Ptr;
231             Src : Source_Buffer_Ptr;
232
233          begin
234             Namet.Unlock;
235             Name_Buffer (1 .. 12) := "gnat_bug.box";
236             Name_Len := 12;
237             Read_Source_File (Name_Enter, 0, Hi, Src);
238
239             --  If we get a Src file, we use it
240
241             if Src /= null then
242                Lo := 0;
243
244                Outer : while Lo < Hi loop
245                   Write_Str ("| ");
246
247                   Inner : loop
248                      exit Inner when Src (Lo) = ASCII.CR
249                        or else Src (Lo) = ASCII.LF;
250                      Write_Char (Src (Lo));
251                      Lo := Lo + 1;
252                   end loop Inner;
253
254                   End_Line;
255
256                   while Lo <= Hi
257                     and then (Src (Lo) = ASCII.CR
258                                 or else Src (Lo) = ASCII.LF)
259                   loop
260                      Lo := Lo + 1;
261                   end loop;
262                end loop Outer;
263
264             --  Otherwise we use the standard fixed text
265
266             else
267                if Public_Version or GNATPRO_Version then
268                   Write_Str
269                     ("| Please submit bug report by email " &
270                      "to report@gnat.com.");
271                   End_Line;
272
273                   Write_Str
274                     ("| Use a subject line meaningful to you" &
275                      " and us to track the bug.");
276                   End_Line;
277
278                else
279                   Write_Str
280                     ("| Please submit a bug report; see" &
281                      " http://gcc.gnu.org/bugs.html.");
282                   End_Line;
283                end if;
284
285                if GNATPRO_Version then
286                   Write_Str
287                     ("| (include your customer number #nnn " &
288                      "in the subject line).");
289                   End_Line;
290                end if;
291
292                Write_Str
293                  ("| Include the entire contents of this bug " &
294                   "box in the report.");
295                End_Line;
296
297                Write_Str
298                  ("| Include the exact gcc or gnatmake command " &
299                   "that you entered.");
300                End_Line;
301
302                Write_Str
303                  ("| Also include sources listed below in gnatchop format");
304                End_Line;
305
306                Write_Str
307                  ("| (concatenated together with no headers between files).");
308                End_Line;
309
310                if Public_Version then
311                   Write_Str
312                     ("| (use plain ASCII or MIME attachment).");
313                   End_Line;
314
315                   Write_Str
316                     ("| See gnatinfo.txt for full info on procedure " &
317                      "for submitting bugs.");
318                   End_Line;
319
320                elsif GNATPRO_Version then
321                   Write_Str
322                     ("| (use plain ASCII or MIME attachment, or FTP "
323                      & "to your customer directory).");
324                   End_Line;
325
326                   Write_Str
327                     ("| See README.GNATPRO for full info on procedure " &
328                      "for submitting bugs.");
329                   End_Line;
330                end if;
331             end if;
332          end;
333
334          --  Complete output of bug box
335
336          Write_Char ('+');
337          Repeat_Char ('=', 76, '+');
338          Write_Eol;
339
340          if Debug_Flag_3 then
341             Write_Eol;
342             Write_Eol;
343             Print_Tree_Node (Current_Error_Node);
344             Write_Eol;
345          end if;
346
347          Write_Eol;
348
349          Write_Line ("Please include these source files with error report");
350          Write_Line ("Note that list may not be accurate in some cases, ");
351          Write_Line ("so please double check that the problem can still ");
352          Write_Line ("be reproduced with the set of files listed.");
353          Write_Eol;
354
355          for U in Main_Unit .. Last_Unit loop
356             begin
357                if not Is_Internal_File_Name
358                         (File_Name (Source_Index (U)))
359                then
360                   Write_Name (Full_File_Name (Source_Index (U)));
361                   Write_Eol;
362                end if;
363
364             --  No point in double bug box if we blow up trying to print
365             --  the list of file names! Output informative msg and quit.
366
367             exception
368                when others =>
369                   Write_Str ("list may be incomplete");
370                   exit;
371             end;
372          end loop;
373
374          Write_Eol;
375          Set_Standard_Output;
376
377          Tree_Dump;
378          Source_Dump;
379          raise Unrecoverable_Error;
380       end if;
381
382    end Compiler_Abort;
383
384    -----------------
385    -- Repeat_Char --
386    -----------------
387
388    procedure Repeat_Char (Char : Character; Col : Nat; After : Character) is
389    begin
390       while Column < Col loop
391          Write_Char (Char);
392       end loop;
393
394       Write_Char (After);
395    end Repeat_Char;
396
397 end Comperr;