OSDN Git Service

* gcc.dg/attr-weakref-1.c: Add exit (0) to avoid spurious
[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-2005 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,  51  Franklin  Street,  Fifth  Floor, --
20 -- Boston, MA 02110-1301, USA.                                              --
21 --                                                                          --
22 -- GNAT was originally developed  by the GNAT team at  New York University. --
23 -- Extensive contributions were provided by AdaCore.                         --
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 AdaCore.
82
83       procedure End_Line;
84       --  Add blanks up to column 76, and then a final vertical bar
85
86       --------------
87       -- End_Line --
88       --------------
89
90       procedure End_Line is
91       begin
92          Repeat_Char (' ', 76, '|');
93          Write_Eol;
94       end End_Line;
95
96       Is_Public_Version : constant Boolean := Get_Gnat_Build_Type = Public;
97       Is_FSF_Version    : constant Boolean := Get_Gnat_Build_Type = FSF;
98
99    --  Start of processing for Compiler_Abort
100
101    begin
102       --  Prevent recursion through Compiler_Abort, e.g. via SIGSEGV.
103
104       if Abort_In_Progress then
105          Exit_Program (E_Abort);
106       end if;
107
108       Abort_In_Progress := True;
109
110       --  If any errors have already occurred, then we guess that the abort
111       --  may well be caused by previous errors, and we don't make too much
112       --  fuss about it, since we want to let programmer fix the errors first.
113
114       --  Debug flag K disables this behavior (useful for debugging)
115
116       if Serious_Errors_Detected /= 0 and then not Debug_Flag_K then
117          Errout.Finalize;
118
119          Set_Standard_Error;
120          Write_Str ("compilation abandoned due to previous error");
121          Write_Eol;
122
123          Set_Standard_Output;
124          Source_Dump;
125          Tree_Dump;
126          Exit_Program (E_Errors);
127
128       --  Otherwise give message with details of the abort
129
130       else
131          Set_Standard_Error;
132
133          --  Generate header for bug box
134
135          Write_Char ('+');
136          Repeat_Char ('=', 29, 'G');
137          Write_Str ("NAT BUG DETECTED");
138          Repeat_Char ('=', 76, '+');
139          Write_Eol;
140
141          --  Output GNAT version identification
142
143          Write_Str ("| ");
144          Write_Str (Gnat_Version_String);
145          Write_Str (" (");
146
147          --  Output target name, deleting junk final reverse slash
148
149          if Target_Name.all (Target_Name.all'Last) = '\'
150            or else Target_Name.all (Target_Name.all'Last) = '/'
151          then
152             Write_Str (Target_Name.all (1 .. Target_Name.all'Last - 1));
153          else
154             Write_Str (Target_Name.all);
155          end if;
156
157          --  Output identification of error
158
159          Write_Str (") ");
160
161          if X'Length + Column > 76 then
162             if Code < 0 then
163                Write_Str ("GCC error:");
164             end if;
165
166             End_Line;
167
168             Write_Str ("| ");
169          end if;
170
171          if X'Length > 70 then
172             declare
173                Last_Blank : Integer := 70;
174
175             begin
176                for P in 40 .. 69 loop
177                   if X (P) = ' ' then
178                      Last_Blank := P;
179                   end if;
180                end loop;
181
182                Write_Str (X (1 .. Last_Blank));
183                End_Line;
184                Write_Str ("|    ");
185                Write_Str (X (Last_Blank + 1 .. X'Length));
186             end;
187          else
188             Write_Str (X);
189          end if;
190
191          if Code > 0 then
192             Write_Str (", Code=");
193             Write_Int (Int (Code));
194
195          elsif Code = 0 then
196
197             --  For exception case, get exception message from the TSD. Note
198             --  that it would be neater and cleaner to pass the exception
199             --  message (obtained from Exception_Message) as a parameter to
200             --  Compiler_Abort, but we can't do this quite yet since it would
201             --  cause bootstrap path problems for 3.10 to 3.11.
202
203             Write_Char (' ');
204             Write_Str (Exception_Message (Get_Current_Excep.all.all));
205          end if;
206
207          End_Line;
208
209          --  Output source location information
210
211          if Sloc (Current_Error_Node) <= Standard_Location
212            or else Sloc (Current_Error_Node) = No_Location
213          then
214             Write_Str ("| No source file position information available");
215             End_Line;
216          else
217             Write_Str ("| Error detected at ");
218             Write_Location (Sloc (Current_Error_Node));
219             End_Line;
220          end if;
221
222          --  There are two cases now. If the file gnat_bug.box exists,
223          --  we use the contents of this file at this point.
224
225          declare
226             Lo  : Source_Ptr;
227             Hi  : Source_Ptr;
228             Src : Source_Buffer_Ptr;
229
230          begin
231             Namet.Unlock;
232             Name_Buffer (1 .. 12) := "gnat_bug.box";
233             Name_Len := 12;
234             Read_Source_File (Name_Enter, 0, Hi, Src);
235
236             --  If we get a Src file, we use it
237
238             if Src /= null then
239                Lo := 0;
240
241                Outer : while Lo < Hi loop
242                   Write_Str ("| ");
243
244                   Inner : loop
245                      exit Inner when Src (Lo) = ASCII.CR
246                        or else Src (Lo) = ASCII.LF;
247                      Write_Char (Src (Lo));
248                      Lo := Lo + 1;
249                   end loop Inner;
250
251                   End_Line;
252
253                   while Lo <= Hi
254                     and then (Src (Lo) = ASCII.CR
255                                 or else Src (Lo) = ASCII.LF)
256                   loop
257                      Lo := Lo + 1;
258                   end loop;
259                end loop Outer;
260
261             --  Otherwise we use the standard fixed text
262
263             else
264                if Is_FSF_Version then
265                   Write_Str
266                     ("| Please submit a bug report; see" &
267                      " http://gcc.gnu.org/bugs.html.");
268                   End_Line;
269
270                elsif Is_Public_Version then
271                   Write_Str
272                     ("| submit bug report by email " &
273                      "to report@adacore.com.");
274                   End_Line;
275
276                   Write_Str
277                     ("| See gnatinfo.txt for full info on procedure " &
278                      "for submitting bugs.");
279                   End_Line;
280
281                else
282                   Write_Str
283                     ("| Please submit a bug report using GNAT Tracker:");
284                   End_Line;
285
286                   Write_Str
287                     ("| http://www.adacore.com/gnattracker/ " &
288                      "section 'send a report'.");
289                   End_Line;
290
291                   Write_Str
292                     ("| alternatively submit a bug report by email " &
293                      "to report@adacore.com.");
294                   End_Line;
295                end if;
296
297                Write_Str
298                  ("| Use a subject line meaningful to you" &
299                   " and us to track the bug.");
300                End_Line;
301
302                if not (Is_Public_Version or Is_FSF_Version) then
303                   Write_Str
304                     ("| Include your customer number #nnn " &
305                      "in the subject line.");
306                   End_Line;
307                end if;
308
309                Write_Str
310                  ("| Include the entire contents of this bug " &
311                   "box in the report.");
312                End_Line;
313
314                Write_Str
315                  ("| Include the exact gcc or gnatmake command " &
316                   "that you entered.");
317                End_Line;
318
319                Write_Str
320                  ("| Also include sources listed below in gnatchop format");
321                End_Line;
322
323                Write_Str
324                  ("| (concatenated together with no headers between files).");
325                End_Line;
326
327                if not Is_FSF_Version then
328                   Write_Str
329                     ("| Use plain ASCII or MIME attachment.");
330                   End_Line;
331                end if;
332             end if;
333          end;
334
335          --  Complete output of bug box
336
337          Write_Char ('+');
338          Repeat_Char ('=', 76, '+');
339          Write_Eol;
340
341          if Debug_Flag_3 then
342             Write_Eol;
343             Write_Eol;
344             Print_Tree_Node (Current_Error_Node);
345             Write_Eol;
346          end if;
347
348          Write_Eol;
349
350          Write_Line ("Please include these source files with error report");
351          Write_Line ("Note that list may not be accurate in some cases, ");
352          Write_Line ("so please double check that the problem can still ");
353          Write_Line ("be reproduced with the set of files listed.");
354          Write_Eol;
355
356          for U in Main_Unit .. Last_Unit loop
357             begin
358                if not Is_Internal_File_Name
359                         (File_Name (Source_Index (U)))
360                then
361                   Write_Name (Full_File_Name (Source_Index (U)));
362                   Write_Eol;
363                end if;
364
365             --  No point in double bug box if we blow up trying to print
366             --  the list of file names! Output informative msg and quit.
367
368             exception
369                when others =>
370                   Write_Str ("list may be incomplete");
371                   exit;
372             end;
373          end loop;
374
375          Write_Eol;
376          Set_Standard_Output;
377
378          Tree_Dump;
379          Source_Dump;
380          raise Unrecoverable_Error;
381       end if;
382
383    end Compiler_Abort;
384
385    -----------------
386    -- Repeat_Char --
387    -----------------
388
389    procedure Repeat_Char (Char : Character; Col : Nat; After : Character) is
390    begin
391       while Column < Col loop
392          Write_Char (Char);
393       end loop;
394
395       Write_Char (After);
396    end Repeat_Char;
397
398 end Comperr;