Mercurial > hg > CbC > CbC_gcc
annotate gcc/diagnostic.c @ 118:fd00160c1b76
ifdef TARGET_64BIT
author | mir3636 |
---|---|
date | Tue, 27 Feb 2018 15:01:35 +0900 |
parents | 04ced10e8804 |
children | 84e7813d76e9 |
rev | line source |
---|---|
0 | 1 /* Language-independent diagnostic subroutines for the GNU Compiler Collection |
111 | 2 Copyright (C) 1999-2017 Free Software Foundation, Inc. |
0 | 3 Contributed by Gabriel Dos Reis <gdr@codesourcery.com> |
4 | |
5 This file is part of GCC. | |
6 | |
7 GCC is free software; you can redistribute it and/or modify it under | |
8 the terms of the GNU General Public License as published by the Free | |
9 Software Foundation; either version 3, or (at your option) any later | |
10 version. | |
11 | |
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GCC; see the file COPYING3. If not see | |
19 <http://www.gnu.org/licenses/>. */ | |
20 | |
21 | |
22 /* This file implements the language independent aspect of diagnostic | |
23 message module. */ | |
24 | |
25 #include "config.h" | |
26 #include "system.h" | |
27 #include "coretypes.h" | |
28 #include "version.h" | |
111 | 29 #include "demangle.h" |
0 | 30 #include "intl.h" |
111 | 31 #include "backtrace.h" |
0 | 32 #include "diagnostic.h" |
111 | 33 #include "diagnostic-color.h" |
34 #include "edit-context.h" | |
35 #include "selftest.h" | |
36 | |
37 #ifdef HAVE_TERMIOS_H | |
38 # include <termios.h> | |
39 #endif | |
40 | |
41 #ifdef GWINSZ_IN_SYS_IOCTL | |
42 # include <sys/ioctl.h> | |
43 #endif | |
0 | 44 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
45 #define pedantic_warning_kind(DC) \ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
46 ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
47 #define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
48 #define permissive_error_option(DC) ((DC)->opt_permissive) |
0 | 49 |
50 /* Prototypes. */ | |
111 | 51 static bool diagnostic_impl (rich_location *, int, const char *, |
52 va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(3,0); | |
53 static bool diagnostic_n_impl (location_t, int, int, const char *, | |
54 const char *, va_list *, | |
55 diagnostic_t) ATTRIBUTE_GCC_DIAG(5,0); | |
56 static bool diagnostic_n_impl_richloc (rich_location *, int, int, const char *, | |
57 const char *, va_list *, | |
58 diagnostic_t) ATTRIBUTE_GCC_DIAG(5,0); | |
0 | 59 |
60 static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN; | |
61 static void real_abort (void) ATTRIBUTE_NORETURN; | |
62 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
63 /* Name of program invoked, sans directories. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
64 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
65 const char *progname; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
66 |
0 | 67 /* A diagnostic_context surrogate for stderr. */ |
68 static diagnostic_context global_diagnostic_context; | |
69 diagnostic_context *global_dc = &global_diagnostic_context; | |
70 | |
71 /* Return a malloc'd string containing MSG formatted a la printf. The | |
72 caller is responsible for freeing the memory. */ | |
111 | 73 char * |
0 | 74 build_message_string (const char *msg, ...) |
75 { | |
76 char *str; | |
77 va_list ap; | |
78 | |
79 va_start (ap, msg); | |
111 | 80 str = xvasprintf (msg, ap); |
0 | 81 va_end (ap); |
82 | |
83 return str; | |
84 } | |
85 | |
86 /* Same as diagnostic_build_prefix, but only the source FILE is given. */ | |
87 char * | |
111 | 88 file_name_as_prefix (diagnostic_context *context, const char *f) |
0 | 89 { |
111 | 90 const char *locus_cs |
91 = colorize_start (pp_show_color (context->printer), "locus"); | |
92 const char *locus_ce = colorize_stop (pp_show_color (context->printer)); | |
93 return build_message_string ("%s%s:%s ", locus_cs, f, locus_ce); | |
0 | 94 } |
95 | |
96 | |
97 | |
111 | 98 /* Return the value of the getenv("COLUMNS") as an integer. If the |
99 value is not set to a positive integer, use ioctl to get the | |
100 terminal width. If it fails, return INT_MAX. */ | |
101 int | |
102 get_terminal_width (void) | |
103 { | |
104 const char * s = getenv ("COLUMNS"); | |
105 if (s != NULL) { | |
106 int n = atoi (s); | |
107 if (n > 0) | |
108 return n; | |
109 } | |
110 | |
111 #ifdef TIOCGWINSZ | |
112 struct winsize w; | |
113 w.ws_col = 0; | |
114 if (ioctl (0, TIOCGWINSZ, &w) == 0 && w.ws_col > 0) | |
115 return w.ws_col; | |
116 #endif | |
117 | |
118 return INT_MAX; | |
119 } | |
120 | |
121 /* Set caret_max_width to value. */ | |
122 void | |
123 diagnostic_set_caret_max_width (diagnostic_context *context, int value) | |
124 { | |
125 /* One minus to account for the leading empty space. */ | |
126 value = value ? value - 1 | |
127 : (isatty (fileno (pp_buffer (context->printer)->stream)) | |
128 ? get_terminal_width () - 1: INT_MAX); | |
129 | |
130 if (value <= 0) | |
131 value = INT_MAX; | |
132 | |
133 context->caret_max_width = value; | |
134 } | |
135 | |
0 | 136 /* Initialize the diagnostic message outputting machinery. */ |
137 void | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
138 diagnostic_initialize (diagnostic_context *context, int n_opts) |
0 | 139 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
140 int i; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
141 |
0 | 142 /* Allocate a basic pretty-printer. Clients will replace this a |
143 much more elaborated pretty-printer if they wish. */ | |
144 context->printer = XNEW (pretty_printer); | |
111 | 145 new (context->printer) pretty_printer (); |
0 | 146 |
147 memset (context->diagnostic_count, 0, sizeof context->diagnostic_count); | |
148 context->warning_as_error_requested = false; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
149 context->n_opts = n_opts; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
150 context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
151 for (i = 0; i < n_opts; i++) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
152 context->classify_diagnostic[i] = DK_UNSPECIFIED; |
111 | 153 context->show_caret = false; |
154 diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer)); | |
155 for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++) | |
156 context->caret_chars[i] = '^'; | |
0 | 157 context->show_option_requested = false; |
158 context->abort_on_error = false; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
159 context->show_column = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
160 context->pedantic_errors = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
161 context->permissive = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
162 context->opt_permissive = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
163 context->fatal_errors = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
164 context->dc_inhibit_warnings = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
165 context->dc_warn_system_headers = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
166 context->max_errors = 0; |
0 | 167 context->internal_error = NULL; |
168 diagnostic_starter (context) = default_diagnostic_starter; | |
111 | 169 context->start_span = default_diagnostic_start_span_fn; |
0 | 170 diagnostic_finalizer (context) = default_diagnostic_finalizer; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
171 context->option_enabled = NULL; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
172 context->option_state = NULL; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
173 context->option_name = NULL; |
111 | 174 context->last_location = UNKNOWN_LOCATION; |
0 | 175 context->last_module = 0; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
176 context->x_data = NULL; |
0 | 177 context->lock = 0; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
178 context->inhibit_notes_p = false; |
111 | 179 context->colorize_source_p = false; |
180 context->show_ruler_p = false; | |
181 context->parseable_fixits_p = false; | |
182 context->edit_context_ptr = NULL; | |
183 } | |
184 | |
185 /* Maybe initialize the color support. We require clients to do this | |
186 explicitly, since most clients don't want color. When called | |
187 without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */ | |
188 | |
189 void | |
190 diagnostic_color_init (diagnostic_context *context, int value /*= -1 */) | |
191 { | |
192 /* value == -1 is the default value. */ | |
193 if (value < 0) | |
194 { | |
195 /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to | |
196 -fdiagnostics-color=auto if GCC_COLORS is in the environment, | |
197 otherwise default to -fdiagnostics-color=never, for other | |
198 values default to that | |
199 -fdiagnostics-color={never,auto,always}. */ | |
200 if (DIAGNOSTICS_COLOR_DEFAULT == -1) | |
201 { | |
202 if (!getenv ("GCC_COLORS")) | |
203 return; | |
204 value = DIAGNOSTICS_COLOR_AUTO; | |
205 } | |
206 else | |
207 value = DIAGNOSTICS_COLOR_DEFAULT; | |
208 } | |
209 pp_show_color (context->printer) | |
210 = colorize_init ((diagnostic_color_rule_t) value); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
211 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
212 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
213 /* Do any cleaning up required after the last diagnostic is emitted. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
214 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
215 void |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
216 diagnostic_finish (diagnostic_context *context) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
217 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
218 /* Some of the errors may actually have been warnings. */ |
111 | 219 if (diagnostic_kind_count (context, DK_WERROR)) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
220 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
221 /* -Werror was given. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
222 if (context->warning_as_error_requested) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
223 pp_verbatim (context->printer, |
111 | 224 _("%s: all warnings being treated as errors"), |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
225 progname); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
226 /* At least one -Werror= was given. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
227 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
228 pp_verbatim (context->printer, |
111 | 229 _("%s: some warnings being treated as errors"), |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
230 progname); |
111 | 231 pp_newline_and_flush (context->printer); |
232 } | |
233 | |
234 diagnostic_file_cache_fini (); | |
235 | |
236 XDELETEVEC (context->classify_diagnostic); | |
237 context->classify_diagnostic = NULL; | |
238 | |
239 /* diagnostic_initialize allocates context->printer using XNEW | |
240 and placement-new. */ | |
241 context->printer->~pretty_printer (); | |
242 XDELETE (context->printer); | |
243 context->printer = NULL; | |
244 | |
245 if (context->edit_context_ptr) | |
246 { | |
247 delete context->edit_context_ptr; | |
248 context->edit_context_ptr = NULL; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
249 } |
0 | 250 } |
251 | |
252 /* Initialize DIAGNOSTIC, where the message MSG has already been | |
253 translated. */ | |
254 void | |
255 diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg, | |
111 | 256 va_list *args, rich_location *richloc, |
0 | 257 diagnostic_t kind) |
258 { | |
111 | 259 gcc_assert (richloc); |
0 | 260 diagnostic->message.err_no = errno; |
261 diagnostic->message.args_ptr = args; | |
262 diagnostic->message.format_spec = msg; | |
111 | 263 diagnostic->message.m_richloc = richloc; |
264 diagnostic->richloc = richloc; | |
0 | 265 diagnostic->kind = kind; |
266 diagnostic->option_index = 0; | |
267 } | |
268 | |
269 /* Initialize DIAGNOSTIC, where the message GMSGID has not yet been | |
270 translated. */ | |
271 void | |
272 diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid, | |
111 | 273 va_list *args, rich_location *richloc, |
0 | 274 diagnostic_t kind) |
275 { | |
111 | 276 gcc_assert (richloc); |
277 diagnostic_set_info_translated (diagnostic, _(gmsgid), args, richloc, kind); | |
278 } | |
279 | |
280 static const char *const diagnostic_kind_color[] = { | |
281 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C), | |
282 #include "diagnostic.def" | |
283 #undef DEFINE_DIAGNOSTIC_KIND | |
284 NULL | |
285 }; | |
286 | |
287 /* Get a color name for diagnostics of type KIND | |
288 Result could be NULL. */ | |
289 | |
290 const char * | |
291 diagnostic_get_color_for_kind (diagnostic_t kind) | |
292 { | |
293 return diagnostic_kind_color[kind]; | |
0 | 294 } |
295 | |
111 | 296 /* Return a malloc'd string describing a location e.g. "foo.c:42:10". |
297 The caller is responsible for freeing the memory. */ | |
298 | |
299 static char * | |
300 diagnostic_get_location_text (diagnostic_context *context, | |
301 expanded_location s) | |
302 { | |
303 pretty_printer *pp = context->printer; | |
304 const char *locus_cs = colorize_start (pp_show_color (pp), "locus"); | |
305 const char *locus_ce = colorize_stop (pp_show_color (pp)); | |
306 | |
307 if (s.file == NULL) | |
308 return build_message_string ("%s%s:%s", locus_cs, progname, locus_ce); | |
309 | |
310 if (!strcmp (s.file, N_("<built-in>"))) | |
311 return build_message_string ("%s%s:%s", locus_cs, s.file, locus_ce); | |
312 | |
313 if (context->show_column) | |
314 return build_message_string ("%s%s:%d:%d:%s", locus_cs, s.file, s.line, | |
315 s.column, locus_ce); | |
316 else | |
317 return build_message_string ("%s%s:%d:%s", locus_cs, s.file, s.line, | |
318 locus_ce); | |
319 } | |
320 | |
321 /* Return a malloc'd string describing a location and the severity of the | |
322 diagnostic, e.g. "foo.c:42:10: error: ". The caller is responsible for | |
323 freeing the memory. */ | |
0 | 324 char * |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
325 diagnostic_build_prefix (diagnostic_context *context, |
111 | 326 const diagnostic_info *diagnostic) |
0 | 327 { |
328 static const char *const diagnostic_kind_text[] = { | |
111 | 329 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T), |
0 | 330 #include "diagnostic.def" |
331 #undef DEFINE_DIAGNOSTIC_KIND | |
332 "must-not-happen" | |
333 }; | |
334 gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND); | |
335 | |
111 | 336 const char *text = _(diagnostic_kind_text[diagnostic->kind]); |
337 const char *text_cs = "", *text_ce = ""; | |
338 pretty_printer *pp = context->printer; | |
339 | |
340 if (diagnostic_kind_color[diagnostic->kind]) | |
341 { | |
342 text_cs = colorize_start (pp_show_color (pp), | |
343 diagnostic_kind_color[diagnostic->kind]); | |
344 text_ce = colorize_stop (pp_show_color (pp)); | |
345 } | |
346 | |
347 expanded_location s = diagnostic_expand_location (diagnostic); | |
348 char *location_text = diagnostic_get_location_text (context, s); | |
349 | |
350 char *result = build_message_string ("%s %s%s%s", location_text, | |
351 text_cs, text, text_ce); | |
352 free (location_text); | |
353 return result; | |
354 } | |
355 | |
356 /* Functions at which to stop the backtrace print. It's not | |
357 particularly helpful to print the callers of these functions. */ | |
358 | |
359 static const char * const bt_stop[] = | |
360 { | |
361 "main", | |
362 "toplev::main", | |
363 "execute_one_pass", | |
364 "compile_file", | |
365 }; | |
366 | |
367 /* A callback function passed to the backtrace_full function. */ | |
368 | |
369 static int | |
370 bt_callback (void *data, uintptr_t pc, const char *filename, int lineno, | |
371 const char *function) | |
372 { | |
373 int *pcount = (int *) data; | |
374 | |
375 /* If we don't have any useful information, don't print | |
376 anything. */ | |
377 if (filename == NULL && function == NULL) | |
378 return 0; | |
379 | |
380 /* Skip functions in diagnostic.c. */ | |
381 if (*pcount == 0 | |
382 && filename != NULL | |
383 && strcmp (lbasename (filename), "diagnostic.c") == 0) | |
384 return 0; | |
385 | |
386 /* Print up to 20 functions. We could make this a --param, but | |
387 since this is only for debugging just use a constant for now. */ | |
388 if (*pcount >= 20) | |
389 { | |
390 /* Returning a non-zero value stops the backtrace. */ | |
391 return 1; | |
392 } | |
393 ++*pcount; | |
394 | |
395 char *alc = NULL; | |
396 if (function != NULL) | |
397 { | |
398 char *str = cplus_demangle_v3 (function, | |
399 (DMGL_VERBOSE | DMGL_ANSI | |
400 | DMGL_GNU_V3 | DMGL_PARAMS)); | |
401 if (str != NULL) | |
402 { | |
403 alc = str; | |
404 function = str; | |
405 } | |
406 | |
407 for (size_t i = 0; i < ARRAY_SIZE (bt_stop); ++i) | |
408 { | |
409 size_t len = strlen (bt_stop[i]); | |
410 if (strncmp (function, bt_stop[i], len) == 0 | |
411 && (function[len] == '\0' || function[len] == '(')) | |
412 { | |
413 if (alc != NULL) | |
414 free (alc); | |
415 /* Returning a non-zero value stops the backtrace. */ | |
416 return 1; | |
417 } | |
418 } | |
419 } | |
420 | |
421 fprintf (stderr, "0x%lx %s\n\t%s:%d\n", | |
422 (unsigned long) pc, | |
423 function == NULL ? "???" : function, | |
424 filename == NULL ? "???" : filename, | |
425 lineno); | |
426 | |
427 if (alc != NULL) | |
428 free (alc); | |
429 | |
430 return 0; | |
431 } | |
432 | |
433 /* A callback function passed to the backtrace_full function. This is | |
434 called if backtrace_full has an error. */ | |
435 | |
436 static void | |
437 bt_err_callback (void *data ATTRIBUTE_UNUSED, const char *msg, int errnum) | |
438 { | |
439 if (errnum < 0) | |
440 { | |
441 /* This means that no debug info was available. Just quietly | |
442 skip printing backtrace info. */ | |
443 return; | |
444 } | |
445 fprintf (stderr, "%s%s%s\n", msg, errnum == 0 ? "" : ": ", | |
446 errnum == 0 ? "" : xstrerror (errnum)); | |
447 } | |
448 | |
449 /* Check if we've met the maximum error limit, and if so fatally exit | |
450 with a message. CONTEXT is the context to check, and FLUSH | |
451 indicates whether a diagnostic_finish call is needed. */ | |
452 | |
453 void | |
454 diagnostic_check_max_errors (diagnostic_context *context, bool flush) | |
455 { | |
456 if (!context->max_errors) | |
457 return; | |
458 | |
459 int count = (diagnostic_kind_count (context, DK_ERROR) | |
460 + diagnostic_kind_count (context, DK_SORRY) | |
461 + diagnostic_kind_count (context, DK_WERROR)); | |
462 | |
463 if (count >= context->max_errors) | |
464 { | |
465 fnotice (stderr, | |
466 "compilation terminated due to -fmax-errors=%u.\n", | |
467 context->max_errors); | |
468 if (flush) | |
469 diagnostic_finish (context); | |
470 exit (FATAL_EXIT_CODE); | |
471 } | |
0 | 472 } |
473 | |
474 /* Take any action which is expected to happen after the diagnostic | |
475 is written out. This function does not always return. */ | |
111 | 476 void |
0 | 477 diagnostic_action_after_output (diagnostic_context *context, |
111 | 478 diagnostic_t diag_kind) |
0 | 479 { |
111 | 480 switch (diag_kind) |
0 | 481 { |
482 case DK_DEBUG: | |
483 case DK_NOTE: | |
484 case DK_ANACHRONISM: | |
485 case DK_WARNING: | |
486 break; | |
487 | |
488 case DK_ERROR: | |
489 case DK_SORRY: | |
490 if (context->abort_on_error) | |
491 real_abort (); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
492 if (context->fatal_errors) |
0 | 493 { |
494 fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n"); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
495 diagnostic_finish (context); |
0 | 496 exit (FATAL_EXIT_CODE); |
497 } | |
498 break; | |
499 | |
500 case DK_ICE: | |
111 | 501 case DK_ICE_NOBT: |
502 { | |
503 struct backtrace_state *state = NULL; | |
504 if (diag_kind == DK_ICE) | |
505 state = backtrace_create_state (NULL, 0, bt_err_callback, NULL); | |
506 int count = 0; | |
507 if (state != NULL) | |
508 backtrace_full (state, 2, bt_callback, bt_err_callback, | |
509 (void *) &count); | |
0 | 510 |
111 | 511 if (context->abort_on_error) |
512 real_abort (); | |
513 | |
514 fnotice (stderr, "Please submit a full bug report,\n" | |
515 "with preprocessed source if appropriate.\n"); | |
516 if (count > 0) | |
517 fnotice (stderr, | |
518 ("Please include the complete backtrace " | |
519 "with any bug report.\n")); | |
520 fnotice (stderr, "See %s for instructions.\n", bug_report_url); | |
521 | |
522 exit (ICE_EXIT_CODE); | |
523 } | |
0 | 524 |
525 case DK_FATAL: | |
526 if (context->abort_on_error) | |
527 real_abort (); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
528 diagnostic_finish (context); |
0 | 529 fnotice (stderr, "compilation terminated.\n"); |
530 exit (FATAL_EXIT_CODE); | |
531 | |
532 default: | |
533 gcc_unreachable (); | |
534 } | |
535 } | |
536 | |
111 | 537 /* True if the last module or file in which a diagnostic was reported is |
538 different from the current one. */ | |
539 | |
540 static bool | |
541 last_module_changed_p (diagnostic_context *context, | |
542 const line_map_ordinary *map) | |
543 { | |
544 return context->last_module != map; | |
545 } | |
546 | |
547 /* Remember the current module or file as being the last one in which we | |
548 report a diagnostic. */ | |
549 | |
550 static void | |
551 set_last_module (diagnostic_context *context, const line_map_ordinary *map) | |
552 { | |
553 context->last_module = map; | |
554 } | |
555 | |
0 | 556 void |
111 | 557 diagnostic_report_current_module (diagnostic_context *context, location_t where) |
0 | 558 { |
111 | 559 const line_map_ordinary *map = NULL; |
0 | 560 |
561 if (pp_needs_newline (context->printer)) | |
562 { | |
563 pp_newline (context->printer); | |
564 pp_needs_newline (context->printer) = false; | |
565 } | |
566 | |
111 | 567 if (where <= BUILTINS_LOCATION) |
0 | 568 return; |
569 | |
111 | 570 linemap_resolve_location (line_table, where, |
571 LRK_MACRO_DEFINITION_LOCATION, | |
572 &map); | |
573 | |
574 if (map && last_module_changed_p (context, map)) | |
0 | 575 { |
111 | 576 set_last_module (context, map); |
0 | 577 if (! MAIN_FILE_P (map)) |
578 { | |
579 map = INCLUDED_FROM (line_table, map); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
580 if (context->show_column) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
581 pp_verbatim (context->printer, |
111 | 582 "In file included from %r%s:%d:%d%R", "locus", |
583 LINEMAP_FILE (map), | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
584 LAST_SOURCE_LINE (map), LAST_SOURCE_COLUMN (map)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
585 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
586 pp_verbatim (context->printer, |
111 | 587 "In file included from %r%s:%d%R", "locus", |
588 LINEMAP_FILE (map), LAST_SOURCE_LINE (map)); | |
0 | 589 while (! MAIN_FILE_P (map)) |
590 { | |
591 map = INCLUDED_FROM (line_table, map); | |
592 pp_verbatim (context->printer, | |
111 | 593 ",\n from %r%s:%d%R", "locus", |
594 LINEMAP_FILE (map), LAST_SOURCE_LINE (map)); | |
0 | 595 } |
596 pp_verbatim (context->printer, ":"); | |
597 pp_newline (context->printer); | |
598 } | |
599 } | |
600 } | |
601 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
602 void |
0 | 603 default_diagnostic_starter (diagnostic_context *context, |
604 diagnostic_info *diagnostic) | |
605 { | |
111 | 606 diagnostic_report_current_module (context, diagnostic_location (diagnostic)); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
607 pp_set_prefix (context->printer, diagnostic_build_prefix (context, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
608 diagnostic)); |
0 | 609 } |
610 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
611 void |
111 | 612 default_diagnostic_start_span_fn (diagnostic_context *context, |
613 expanded_location exploc) | |
614 { | |
615 pp_set_prefix (context->printer, | |
616 diagnostic_get_location_text (context, exploc)); | |
617 pp_string (context->printer, ""); | |
618 pp_newline (context->printer); | |
619 } | |
620 | |
621 void | |
0 | 622 default_diagnostic_finalizer (diagnostic_context *context, |
111 | 623 diagnostic_info *diagnostic) |
0 | 624 { |
111 | 625 diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind); |
0 | 626 pp_destroy_prefix (context->printer); |
111 | 627 pp_flush (context->printer); |
0 | 628 } |
629 | |
630 /* Interface to specify diagnostic kind overrides. Returns the | |
631 previous setting, or DK_UNSPECIFIED if the parameters are out of | |
111 | 632 range. If OPTION_INDEX is zero, the new setting is for all the |
633 diagnostics. */ | |
0 | 634 diagnostic_t |
635 diagnostic_classify_diagnostic (diagnostic_context *context, | |
636 int option_index, | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
637 diagnostic_t new_kind, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
638 location_t where) |
0 | 639 { |
640 diagnostic_t old_kind; | |
641 | |
111 | 642 if (option_index < 0 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
643 || option_index >= context->n_opts |
0 | 644 || new_kind >= DK_LAST_DIAGNOSTIC_KIND) |
645 return DK_UNSPECIFIED; | |
646 | |
647 old_kind = context->classify_diagnostic[option_index]; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
648 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
649 /* Handle pragmas separately, since we need to keep track of *where* |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
650 the pragmas were. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
651 if (where != UNKNOWN_LOCATION) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
652 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
653 int i; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
654 |
111 | 655 /* Record the command-line status, so we can reset it back on DK_POP. */ |
656 if (old_kind == DK_UNSPECIFIED) | |
657 { | |
658 old_kind = !context->option_enabled (option_index, | |
659 context->option_state) | |
660 ? DK_IGNORED : (context->warning_as_error_requested | |
661 ? DK_ERROR : DK_WARNING); | |
662 context->classify_diagnostic[option_index] = old_kind; | |
663 } | |
664 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
665 for (i = context->n_classification_history - 1; i >= 0; i --) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
666 if (context->classification_history[i].option == option_index) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
667 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
668 old_kind = context->classification_history[i].kind; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
669 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
670 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
671 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
672 i = context->n_classification_history; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
673 context->classification_history = |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
674 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
675 * sizeof (diagnostic_classification_change_t)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
676 context->classification_history[i].location = where; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
677 context->classification_history[i].option = option_index; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
678 context->classification_history[i].kind = new_kind; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
679 context->n_classification_history ++; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
680 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
681 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
682 context->classify_diagnostic[option_index] = new_kind; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
683 |
0 | 684 return old_kind; |
685 } | |
686 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
687 /* Save all diagnostic classifications in a stack. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
688 void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
689 diagnostic_push_diagnostics (diagnostic_context *context, location_t where ATTRIBUTE_UNUSED) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
690 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
691 context->push_list = (int *) xrealloc (context->push_list, (context->n_push + 1) * sizeof (int)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
692 context->push_list[context->n_push ++] = context->n_classification_history; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
693 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
694 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
695 /* Restore the topmost classification set off the stack. If the stack |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
696 is empty, revert to the state based on command line parameters. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
697 void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
698 diagnostic_pop_diagnostics (diagnostic_context *context, location_t where) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
699 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
700 int jump_to; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
701 int i; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
702 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
703 if (context->n_push) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
704 jump_to = context->push_list [-- context->n_push]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
705 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
706 jump_to = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
707 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
708 i = context->n_classification_history; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
709 context->classification_history = |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
710 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
711 * sizeof (diagnostic_classification_change_t)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
712 context->classification_history[i].location = where; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
713 context->classification_history[i].option = jump_to; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
714 context->classification_history[i].kind = DK_POP; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
715 context->n_classification_history ++; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
716 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
717 |
111 | 718 /* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the |
719 escaping rules for -fdiagnostics-parseable-fixits. */ | |
720 | |
721 static void | |
722 print_escaped_string (pretty_printer *pp, const char *text) | |
723 { | |
724 gcc_assert (pp); | |
725 gcc_assert (text); | |
726 | |
727 pp_character (pp, '"'); | |
728 for (const char *ch = text; *ch; ch++) | |
729 { | |
730 switch (*ch) | |
731 { | |
732 case '\\': | |
733 /* Escape backslash as two backslashes. */ | |
734 pp_string (pp, "\\\\"); | |
735 break; | |
736 case '\t': | |
737 /* Escape tab as "\t". */ | |
738 pp_string (pp, "\\t"); | |
739 break; | |
740 case '\n': | |
741 /* Escape newline as "\n". */ | |
742 pp_string (pp, "\\n"); | |
743 break; | |
744 case '"': | |
745 /* Escape doublequotes as \". */ | |
746 pp_string (pp, "\\\""); | |
747 break; | |
748 default: | |
749 if (ISPRINT (*ch)) | |
750 pp_character (pp, *ch); | |
751 else | |
752 /* Use octal for non-printable chars. */ | |
753 { | |
754 unsigned char c = (*ch & 0xff); | |
755 pp_printf (pp, "\\%o%o%o", (c / 64), (c / 8) & 007, c & 007); | |
756 } | |
757 break; | |
758 } | |
759 } | |
760 pp_character (pp, '"'); | |
761 } | |
762 | |
763 /* Implementation of -fdiagnostics-parseable-fixits. Print a | |
764 machine-parseable version of all fixits in RICHLOC to PP. */ | |
765 | |
766 static void | |
767 print_parseable_fixits (pretty_printer *pp, rich_location *richloc) | |
768 { | |
769 gcc_assert (pp); | |
770 gcc_assert (richloc); | |
771 | |
772 for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++) | |
773 { | |
774 const fixit_hint *hint = richloc->get_fixit_hint (i); | |
775 source_location start_loc = hint->get_start_loc (); | |
776 expanded_location start_exploc = expand_location (start_loc); | |
777 pp_string (pp, "fix-it:"); | |
778 print_escaped_string (pp, start_exploc.file); | |
779 /* For compatibility with clang, print as a half-open range. */ | |
780 source_location next_loc = hint->get_next_loc (); | |
781 expanded_location next_exploc = expand_location (next_loc); | |
782 pp_printf (pp, ":{%i:%i-%i:%i}:", | |
783 start_exploc.line, start_exploc.column, | |
784 next_exploc.line, next_exploc.column); | |
785 print_escaped_string (pp, hint->get_string ()); | |
786 pp_newline (pp); | |
787 } | |
788 } | |
789 | |
790 /* Update the diag_class of DIAGNOSTIC based on its location | |
791 relative to any | |
792 #pragma GCC diagnostic | |
793 directives recorded within CONTEXT. | |
794 | |
795 Return the new diag_class of DIAGNOSTIC if it was updated, or | |
796 DK_UNSPECIFIED otherwise. */ | |
797 | |
798 static diagnostic_t | |
799 update_effective_level_from_pragmas (diagnostic_context *context, | |
800 diagnostic_info *diagnostic) | |
801 { | |
802 diagnostic_t diag_class = DK_UNSPECIFIED; | |
803 | |
804 if (context->n_classification_history > 0) | |
805 { | |
806 location_t location = diagnostic_location (diagnostic); | |
807 | |
808 /* FIXME: Stupid search. Optimize later. */ | |
809 for (int i = context->n_classification_history - 1; i >= 0; i --) | |
810 { | |
811 if (linemap_location_before_p | |
812 (line_table, | |
813 context->classification_history[i].location, | |
814 location)) | |
815 { | |
816 if (context->classification_history[i].kind == (int) DK_POP) | |
817 { | |
818 i = context->classification_history[i].option; | |
819 continue; | |
820 } | |
821 int option = context->classification_history[i].option; | |
822 /* The option 0 is for all the diagnostics. */ | |
823 if (option == 0 || option == diagnostic->option_index) | |
824 { | |
825 diag_class = context->classification_history[i].kind; | |
826 if (diag_class != DK_UNSPECIFIED) | |
827 diagnostic->kind = diag_class; | |
828 break; | |
829 } | |
830 } | |
831 } | |
832 } | |
833 | |
834 return diag_class; | |
835 } | |
836 | |
837 /* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's | |
838 printer, e.g. " [-Werror=uninitialized]". | |
839 Subroutine of diagnostic_report_diagnostic. */ | |
840 | |
841 static void | |
842 print_option_information (diagnostic_context *context, | |
843 const diagnostic_info *diagnostic, | |
844 diagnostic_t orig_diag_kind) | |
845 { | |
846 char *option_text; | |
847 | |
848 option_text = context->option_name (context, diagnostic->option_index, | |
849 orig_diag_kind, diagnostic->kind); | |
850 | |
851 if (option_text) | |
852 { | |
853 pretty_printer *pp = context->printer; | |
854 pp_string (pp, " ["); | |
855 pp_string (pp, colorize_start (pp_show_color (pp), | |
856 diagnostic_kind_color[diagnostic->kind])); | |
857 pp_string (pp, option_text); | |
858 pp_string (pp, colorize_stop (pp_show_color (pp))); | |
859 pp_character (pp, ']'); | |
860 free (option_text); | |
861 } | |
862 } | |
863 | |
0 | 864 /* Report a diagnostic message (an error or a warning) as specified by |
865 DC. This function is *the* subroutine in terms of which front-ends | |
866 should implement their specific diagnostic handling modules. The | |
867 front-end independent format specifiers are exactly those described | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
868 in the documentation of output_format. |
0 | 869 Return true if a diagnostic was printed, false otherwise. */ |
870 | |
871 bool | |
872 diagnostic_report_diagnostic (diagnostic_context *context, | |
873 diagnostic_info *diagnostic) | |
874 { | |
111 | 875 location_t location = diagnostic_location (diagnostic); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
876 diagnostic_t orig_diag_kind = diagnostic->kind; |
0 | 877 |
878 /* Give preference to being able to inhibit warnings, before they | |
879 get reclassified to something else. */ | |
880 if ((diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
881 && !diagnostic_report_warnings_p (context, location)) |
0 | 882 return false; |
883 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
884 if (diagnostic->kind == DK_PEDWARN) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
885 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
886 diagnostic->kind = pedantic_warning_kind (context); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
887 /* We do this to avoid giving the message for -pedantic-errors. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
888 orig_diag_kind = diagnostic->kind; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
889 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
890 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
891 if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
892 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
893 |
0 | 894 if (context->lock > 0) |
895 { | |
896 /* If we're reporting an ICE in the middle of some other error, | |
897 try to flush out the previous error, then let this one | |
898 through. Don't do this more than once. */ | |
111 | 899 if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) |
900 && context->lock == 1) | |
901 pp_newline_and_flush (context->printer); | |
0 | 902 else |
903 error_recursion (context); | |
904 } | |
905 | |
906 /* If the user requested that warnings be treated as errors, so be | |
907 it. Note that we do this before the next block so that | |
908 individual warnings can be overridden back to warnings with | |
909 -Wno-error=*. */ | |
910 if (context->warning_as_error_requested | |
911 && diagnostic->kind == DK_WARNING) | |
111 | 912 diagnostic->kind = DK_ERROR; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
913 |
111 | 914 if (diagnostic->option_index |
915 && diagnostic->option_index != permissive_error_option (context)) | |
0 | 916 { |
917 /* This tests if the user provided the appropriate -Wfoo or | |
918 -Wno-foo option. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
919 if (! context->option_enabled (diagnostic->option_index, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
920 context->option_state)) |
0 | 921 return false; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
922 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
923 /* This tests for #pragma diagnostic changes. */ |
111 | 924 diagnostic_t diag_class |
925 = update_effective_level_from_pragmas (context, diagnostic); | |
926 | |
0 | 927 /* This tests if the user provided the appropriate -Werror=foo |
928 option. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
929 if (diag_class == DK_UNSPECIFIED |
111 | 930 && (context->classify_diagnostic[diagnostic->option_index] |
931 != DK_UNSPECIFIED)) | |
932 diagnostic->kind | |
933 = context->classify_diagnostic[diagnostic->option_index]; | |
934 | |
0 | 935 /* This allows for future extensions, like temporarily disabling |
936 warnings for ranges of source code. */ | |
937 if (diagnostic->kind == DK_IGNORED) | |
938 return false; | |
939 } | |
940 | |
111 | 941 if (diagnostic->kind != DK_NOTE) |
942 diagnostic_check_max_errors (context); | |
0 | 943 |
944 context->lock++; | |
945 | |
111 | 946 if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) |
0 | 947 { |
948 /* When not checking, ICEs are converted to fatal errors when an | |
949 error has already occurred. This is counteracted by | |
950 abort_on_error. */ | |
111 | 951 if (!CHECKING_P |
952 && (diagnostic_kind_count (context, DK_ERROR) > 0 | |
953 || diagnostic_kind_count (context, DK_SORRY) > 0) | |
0 | 954 && !context->abort_on_error) |
955 { | |
111 | 956 expanded_location s |
957 = expand_location (diagnostic_location (diagnostic)); | |
0 | 958 fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n", |
959 s.file, s.line); | |
960 exit (ICE_EXIT_CODE); | |
961 } | |
962 if (context->internal_error) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
963 (*context->internal_error) (context, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
964 diagnostic->message.format_spec, |
0 | 965 diagnostic->message.args_ptr); |
966 } | |
111 | 967 if (diagnostic->kind == DK_ERROR && orig_diag_kind == DK_WARNING) |
968 ++diagnostic_kind_count (context, DK_WERROR); | |
969 else | |
970 ++diagnostic_kind_count (context, diagnostic->kind); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
971 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
972 diagnostic->message.x_data = &diagnostic->x_data; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
973 diagnostic->x_data = NULL; |
0 | 974 pp_format (context->printer, &diagnostic->message); |
975 (*diagnostic_starter (context)) (context, diagnostic); | |
976 pp_output_formatted_text (context->printer); | |
111 | 977 if (context->show_option_requested) |
978 print_option_information (context, diagnostic, orig_diag_kind); | |
0 | 979 (*diagnostic_finalizer (context)) (context, diagnostic); |
111 | 980 if (context->parseable_fixits_p) |
981 { | |
982 print_parseable_fixits (context->printer, diagnostic->richloc); | |
983 pp_flush (context->printer); | |
984 } | |
985 diagnostic_action_after_output (context, diagnostic->kind); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
986 diagnostic->x_data = NULL; |
0 | 987 |
111 | 988 if (context->edit_context_ptr) |
989 if (diagnostic->richloc->fixits_can_be_auto_applied_p ()) | |
990 context->edit_context_ptr->add_fixits (diagnostic->richloc); | |
991 | |
0 | 992 context->lock--; |
993 | |
994 return true; | |
995 } | |
996 | |
997 /* Given a partial pathname as input, return another pathname that | |
998 shares no directory elements with the pathname of __FILE__. This | |
999 is used by fancy_abort() to print `Internal compiler error in expr.c' | |
1000 instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */ | |
1001 | |
1002 const char * | |
1003 trim_filename (const char *name) | |
1004 { | |
1005 static const char this_file[] = __FILE__; | |
1006 const char *p = name, *q = this_file; | |
1007 | |
1008 /* First skip any "../" in each filename. This allows us to give a proper | |
1009 reference to a file in a subdirectory. */ | |
1010 while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2])) | |
1011 p += 3; | |
1012 | |
1013 while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2])) | |
1014 q += 3; | |
1015 | |
1016 /* Now skip any parts the two filenames have in common. */ | |
1017 while (*p == *q && *p != 0 && *q != 0) | |
1018 p++, q++; | |
1019 | |
1020 /* Now go backwards until the previous directory separator. */ | |
1021 while (p > name && !IS_DIR_SEPARATOR (p[-1])) | |
1022 p--; | |
1023 | |
1024 return p; | |
1025 } | |
1026 | |
1027 /* Standard error reporting routines in increasing order of severity. | |
1028 All of these take arguments like printf. */ | |
1029 | |
1030 /* Text to be emitted verbatim to the error message stream; this | |
1031 produces no prefix and disables line-wrapping. Use rarely. */ | |
1032 void | |
1033 verbatim (const char *gmsgid, ...) | |
1034 { | |
1035 text_info text; | |
1036 va_list ap; | |
1037 | |
1038 va_start (ap, gmsgid); | |
1039 text.err_no = errno; | |
1040 text.args_ptr = ≈ | |
1041 text.format_spec = _(gmsgid); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1042 text.x_data = NULL; |
0 | 1043 pp_format_verbatim (global_dc->printer, &text); |
111 | 1044 pp_newline_and_flush (global_dc->printer); |
1045 va_end (ap); | |
1046 } | |
1047 | |
1048 /* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */ | |
1049 void | |
1050 diagnostic_append_note (diagnostic_context *context, | |
1051 location_t location, | |
1052 const char * gmsgid, ...) | |
1053 { | |
1054 diagnostic_info diagnostic; | |
1055 va_list ap; | |
1056 const char *saved_prefix; | |
1057 rich_location richloc (line_table, location); | |
1058 | |
1059 va_start (ap, gmsgid); | |
1060 diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE); | |
1061 if (context->inhibit_notes_p) | |
1062 { | |
1063 va_end (ap); | |
1064 return; | |
1065 } | |
1066 saved_prefix = pp_get_prefix (context->printer); | |
1067 pp_set_prefix (context->printer, | |
1068 diagnostic_build_prefix (context, &diagnostic)); | |
1069 pp_format (context->printer, &diagnostic.message); | |
1070 pp_output_formatted_text (context->printer); | |
1071 pp_destroy_prefix (context->printer); | |
1072 pp_set_prefix (context->printer, saved_prefix); | |
1073 diagnostic_show_locus (context, &richloc, DK_NOTE); | |
0 | 1074 va_end (ap); |
1075 } | |
1076 | |
111 | 1077 /* Implement emit_diagnostic, inform, inform_at_rich_loc, warning, warning_at, |
1078 warning_at_rich_loc, pedwarn, permerror, permerror_at_rich_loc, error, | |
1079 error_at, error_at_rich_loc, sorry, fatal_error, internal_error, and | |
1080 internal_error_no_backtrace, as documented and defined below. */ | |
1081 static bool | |
1082 diagnostic_impl (rich_location *richloc, int opt, | |
1083 const char *gmsgid, | |
1084 va_list *ap, diagnostic_t kind) | |
1085 { | |
1086 diagnostic_info diagnostic; | |
1087 if (kind == DK_PERMERROR) | |
1088 { | |
1089 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, | |
1090 permissive_error_kind (global_dc)); | |
1091 diagnostic.option_index = permissive_error_option (global_dc); | |
1092 } | |
1093 else | |
1094 { | |
1095 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, kind); | |
1096 if (kind == DK_WARNING || kind == DK_PEDWARN) | |
1097 diagnostic.option_index = opt; | |
1098 } | |
1099 return diagnostic_report_diagnostic (global_dc, &diagnostic); | |
1100 } | |
1101 | |
1102 /* Same as diagonostic_n_impl taking rich_location instead of location_t. */ | |
1103 static bool | |
1104 diagnostic_n_impl_richloc (rich_location *richloc, int opt, int n, | |
1105 const char *singular_gmsgid, | |
1106 const char *plural_gmsgid, | |
1107 va_list *ap, diagnostic_t kind) | |
1108 { | |
1109 diagnostic_info diagnostic; | |
1110 diagnostic_set_info_translated (&diagnostic, | |
1111 ngettext (singular_gmsgid, plural_gmsgid, n), | |
1112 ap, richloc, kind); | |
1113 if (kind == DK_WARNING) | |
1114 diagnostic.option_index = opt; | |
1115 return diagnostic_report_diagnostic (global_dc, &diagnostic); | |
1116 } | |
1117 | |
1118 /* Implement inform_n, warning_n, and error_n, as documented and | |
1119 defined below. */ | |
1120 static bool | |
1121 diagnostic_n_impl (location_t location, int opt, int n, | |
1122 const char *singular_gmsgid, | |
1123 const char *plural_gmsgid, | |
1124 va_list *ap, diagnostic_t kind) | |
1125 { | |
1126 rich_location richloc (line_table, location); | |
1127 return diagnostic_n_impl_richloc (&richloc, opt, n, | |
1128 singular_gmsgid, plural_gmsgid, ap, kind); | |
1129 } | |
1130 | |
1131 /* Wrapper around diagnostic_impl taking a variable argument list. */ | |
1132 | |
0 | 1133 bool |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1134 emit_diagnostic (diagnostic_t kind, location_t location, int opt, |
0 | 1135 const char *gmsgid, ...) |
1136 { | |
1137 va_list ap; | |
1138 va_start (ap, gmsgid); | |
111 | 1139 rich_location richloc (line_table, location); |
1140 bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, kind); | |
0 | 1141 va_end (ap); |
111 | 1142 return ret; |
1143 } | |
0 | 1144 |
111 | 1145 /* Wrapper around diagnostic_impl taking a va_list parameter. */ |
1146 | |
1147 bool | |
1148 emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt, | |
1149 const char *gmsgid, va_list *ap) | |
1150 { | |
1151 rich_location richloc (line_table, location); | |
1152 return diagnostic_impl (&richloc, opt, gmsgid, ap, kind); | |
0 | 1153 } |
1154 | |
1155 /* An informative note at LOCATION. Use this for additional details on an error | |
1156 message. */ | |
1157 void | |
1158 inform (location_t location, const char *gmsgid, ...) | |
1159 { | |
1160 va_list ap; | |
111 | 1161 va_start (ap, gmsgid); |
1162 rich_location richloc (line_table, location); | |
1163 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_NOTE); | |
1164 va_end (ap); | |
1165 } | |
0 | 1166 |
111 | 1167 /* Same as "inform", but at RICHLOC. */ |
1168 void | |
1169 inform_at_rich_loc (rich_location *richloc, const char *gmsgid, ...) | |
1170 { | |
1171 va_list ap; | |
0 | 1172 va_start (ap, gmsgid); |
111 | 1173 diagnostic_impl (richloc, -1, gmsgid, &ap, DK_NOTE); |
0 | 1174 va_end (ap); |
1175 } | |
1176 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1177 /* An informative note at LOCATION. Use this for additional details on an |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1178 error message. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1179 void |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1180 inform_n (location_t location, int n, const char *singular_gmsgid, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1181 const char *plural_gmsgid, ...) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1182 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1183 va_list ap; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1184 va_start (ap, plural_gmsgid); |
111 | 1185 diagnostic_n_impl (location, -1, n, singular_gmsgid, plural_gmsgid, |
1186 &ap, DK_NOTE); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1187 va_end (ap); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1188 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1189 |
0 | 1190 /* A warning at INPUT_LOCATION. Use this for code which is correct according |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1191 to the relevant language specification but is likely to be buggy anyway. |
0 | 1192 Returns true if the warning was printed, false if it was inhibited. */ |
1193 bool | |
1194 warning (int opt, const char *gmsgid, ...) | |
1195 { | |
1196 va_list ap; | |
1197 va_start (ap, gmsgid); | |
111 | 1198 rich_location richloc (line_table, input_location); |
1199 bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, DK_WARNING); | |
0 | 1200 va_end (ap); |
111 | 1201 return ret; |
0 | 1202 } |
1203 | |
1204 /* A warning at LOCATION. Use this for code which is correct according to the | |
1205 relevant language specification but is likely to be buggy anyway. | |
1206 Returns true if the warning was printed, false if it was inhibited. */ | |
1207 | |
1208 bool | |
1209 warning_at (location_t location, int opt, const char *gmsgid, ...) | |
1210 { | |
1211 va_list ap; | |
111 | 1212 va_start (ap, gmsgid); |
1213 rich_location richloc (line_table, location); | |
1214 bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, DK_WARNING); | |
1215 va_end (ap); | |
1216 return ret; | |
1217 } | |
0 | 1218 |
111 | 1219 /* Same as warning at, but using RICHLOC. */ |
1220 | |
1221 bool | |
1222 warning_at_rich_loc (rich_location *richloc, int opt, const char *gmsgid, ...) | |
1223 { | |
1224 va_list ap; | |
0 | 1225 va_start (ap, gmsgid); |
111 | 1226 bool ret = diagnostic_impl (richloc, opt, gmsgid, &ap, DK_WARNING); |
1227 va_end (ap); | |
1228 return ret; | |
1229 } | |
1230 | |
1231 /* Same as warning_at_rich_loc but for plural variant. */ | |
1232 | |
1233 bool | |
1234 warning_at_rich_loc_n (rich_location *richloc, int opt, int n, | |
1235 const char *singular_gmsgid, const char *plural_gmsgid, ...) | |
1236 { | |
1237 va_list ap; | |
1238 va_start (ap, plural_gmsgid); | |
1239 bool ret = diagnostic_n_impl_richloc (richloc, opt, n, | |
1240 singular_gmsgid, plural_gmsgid, | |
1241 &ap, DK_WARNING); | |
0 | 1242 va_end (ap); |
111 | 1243 return ret; |
1244 } | |
1245 | |
1246 /* A warning at LOCATION. Use this for code which is correct according to the | |
1247 relevant language specification but is likely to be buggy anyway. | |
1248 Returns true if the warning was printed, false if it was inhibited. */ | |
1249 | |
1250 bool | |
1251 warning_n (location_t location, int opt, int n, const char *singular_gmsgid, | |
1252 const char *plural_gmsgid, ...) | |
1253 { | |
1254 va_list ap; | |
1255 va_start (ap, plural_gmsgid); | |
1256 bool ret = diagnostic_n_impl (location, opt, n, | |
1257 singular_gmsgid, plural_gmsgid, | |
1258 &ap, DK_WARNING); | |
1259 va_end (ap); | |
1260 return ret; | |
0 | 1261 } |
1262 | |
1263 /* A "pedantic" warning at LOCATION: issues a warning unless | |
1264 -pedantic-errors was given on the command line, in which case it | |
1265 issues an error. Use this for diagnostics required by the relevant | |
1266 language standard, if you have chosen not to make them errors. | |
1267 | |
1268 Note that these diagnostics are issued independent of the setting | |
111 | 1269 of the -Wpedantic command-line switch. To get a warning enabled |
0 | 1270 only with that switch, use either "if (pedantic) pedwarn |
111 | 1271 (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)". To get a |
1272 pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)". | |
0 | 1273 |
1274 Returns true if the warning was printed, false if it was inhibited. */ | |
1275 | |
1276 bool | |
1277 pedwarn (location_t location, int opt, const char *gmsgid, ...) | |
1278 { | |
1279 va_list ap; | |
1280 va_start (ap, gmsgid); | |
111 | 1281 rich_location richloc (line_table, location); |
1282 bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, DK_PEDWARN); | |
0 | 1283 va_end (ap); |
111 | 1284 return ret; |
1285 } | |
1286 | |
1287 /* Same as pedwarn, but using RICHLOC. */ | |
1288 | |
1289 bool | |
1290 pedwarn_at_rich_loc (rich_location *richloc, int opt, const char *gmsgid, ...) | |
1291 { | |
1292 va_list ap; | |
1293 va_start (ap, gmsgid); | |
1294 bool ret = diagnostic_impl (richloc, opt, gmsgid, &ap, DK_PEDWARN); | |
1295 va_end (ap); | |
1296 return ret; | |
0 | 1297 } |
1298 | |
1299 /* A "permissive" error at LOCATION: issues an error unless | |
1300 -fpermissive was given on the command line, in which case it issues | |
1301 a warning. Use this for things that really should be errors but we | |
1302 want to support legacy code. | |
1303 | |
1304 Returns true if the warning was printed, false if it was inhibited. */ | |
1305 | |
1306 bool | |
1307 permerror (location_t location, const char *gmsgid, ...) | |
1308 { | |
1309 va_list ap; | |
1310 va_start (ap, gmsgid); | |
111 | 1311 rich_location richloc (line_table, location); |
1312 bool ret = diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_PERMERROR); | |
0 | 1313 va_end (ap); |
111 | 1314 return ret; |
1315 } | |
1316 | |
1317 /* Same as "permerror", but at RICHLOC. */ | |
1318 | |
1319 bool | |
1320 permerror_at_rich_loc (rich_location *richloc, const char *gmsgid, ...) | |
1321 { | |
1322 va_list ap; | |
1323 va_start (ap, gmsgid); | |
1324 bool ret = diagnostic_impl (richloc, -1, gmsgid, &ap, DK_PERMERROR); | |
1325 va_end (ap); | |
1326 return ret; | |
0 | 1327 } |
1328 | |
1329 /* A hard error: the code is definitely ill-formed, and an object file | |
1330 will not be produced. */ | |
1331 void | |
1332 error (const char *gmsgid, ...) | |
1333 { | |
1334 va_list ap; | |
1335 va_start (ap, gmsgid); | |
111 | 1336 rich_location richloc (line_table, input_location); |
1337 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_ERROR); | |
0 | 1338 va_end (ap); |
1339 } | |
1340 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1341 /* A hard error: the code is definitely ill-formed, and an object file |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1342 will not be produced. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1343 void |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1344 error_n (location_t location, int n, const char *singular_gmsgid, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1345 const char *plural_gmsgid, ...) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1346 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1347 va_list ap; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1348 va_start (ap, plural_gmsgid); |
111 | 1349 diagnostic_n_impl (location, -1, n, singular_gmsgid, plural_gmsgid, |
1350 &ap, DK_ERROR); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1351 va_end (ap); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1352 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1353 |
111 | 1354 /* Same as above, but use location LOC instead of input_location. */ |
0 | 1355 void |
1356 error_at (location_t loc, const char *gmsgid, ...) | |
1357 { | |
1358 va_list ap; | |
111 | 1359 va_start (ap, gmsgid); |
1360 rich_location richloc (line_table, loc); | |
1361 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_ERROR); | |
1362 va_end (ap); | |
1363 } | |
0 | 1364 |
111 | 1365 /* Same as above, but use RICH_LOC. */ |
1366 | |
1367 void | |
1368 error_at_rich_loc (rich_location *richloc, const char *gmsgid, ...) | |
1369 { | |
1370 va_list ap; | |
0 | 1371 va_start (ap, gmsgid); |
111 | 1372 diagnostic_impl (richloc, -1, gmsgid, &ap, DK_ERROR); |
0 | 1373 va_end (ap); |
1374 } | |
1375 | |
1376 /* "Sorry, not implemented." Use for a language feature which is | |
1377 required by the relevant specification but not implemented by GCC. | |
1378 An object file will not be produced. */ | |
1379 void | |
1380 sorry (const char *gmsgid, ...) | |
1381 { | |
1382 va_list ap; | |
1383 va_start (ap, gmsgid); | |
111 | 1384 rich_location richloc (line_table, input_location); |
1385 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_SORRY); | |
0 | 1386 va_end (ap); |
1387 } | |
1388 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1389 /* Return true if an error or a "sorry" has been seen. Various |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1390 processing is disabled after errors. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1391 bool |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1392 seen_error (void) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1393 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1394 return errorcount || sorrycount; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1395 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1396 |
0 | 1397 /* An error which is severe enough that we make no attempt to |
1398 continue. Do not use this for internal consistency checks; that's | |
1399 internal_error. Use of this function should be rare. */ | |
1400 void | |
111 | 1401 fatal_error (location_t loc, const char *gmsgid, ...) |
0 | 1402 { |
1403 va_list ap; | |
1404 va_start (ap, gmsgid); | |
111 | 1405 rich_location richloc (line_table, loc); |
1406 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_FATAL); | |
0 | 1407 va_end (ap); |
1408 | |
1409 gcc_unreachable (); | |
1410 } | |
1411 | |
1412 /* An internal consistency check has failed. We make no attempt to | |
1413 continue. Note that unless there is debugging value to be had from | |
1414 a more specific message, or some other good reason, you should use | |
1415 abort () instead of calling this function directly. */ | |
1416 void | |
1417 internal_error (const char *gmsgid, ...) | |
1418 { | |
1419 va_list ap; | |
111 | 1420 va_start (ap, gmsgid); |
1421 rich_location richloc (line_table, input_location); | |
1422 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_ICE); | |
1423 va_end (ap); | |
1424 | |
1425 gcc_unreachable (); | |
1426 } | |
0 | 1427 |
111 | 1428 /* Like internal_error, but no backtrace will be printed. Used when |
1429 the internal error does not happen at the current location, but happened | |
1430 somewhere else. */ | |
1431 void | |
1432 internal_error_no_backtrace (const char *gmsgid, ...) | |
1433 { | |
1434 va_list ap; | |
0 | 1435 va_start (ap, gmsgid); |
111 | 1436 rich_location richloc (line_table, input_location); |
1437 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_ICE_NOBT); | |
0 | 1438 va_end (ap); |
1439 | |
1440 gcc_unreachable (); | |
1441 } | |
1442 | |
1443 /* Special case error functions. Most are implemented in terms of the | |
1444 above, or should be. */ | |
1445 | |
1446 /* Print a diagnostic MSGID on FILE. This is just fprintf, except it | |
1447 runs its second argument through gettext. */ | |
1448 void | |
1449 fnotice (FILE *file, const char *cmsgid, ...) | |
1450 { | |
1451 va_list ap; | |
1452 | |
1453 va_start (ap, cmsgid); | |
1454 vfprintf (file, _(cmsgid), ap); | |
1455 va_end (ap); | |
1456 } | |
1457 | |
1458 /* Inform the user that an error occurred while trying to report some | |
1459 other error. This indicates catastrophic internal inconsistencies, | |
1460 so give up now. But do try to flush out the previous error. | |
1461 This mustn't use internal_error, that will cause infinite recursion. */ | |
1462 | |
1463 static void | |
1464 error_recursion (diagnostic_context *context) | |
1465 { | |
1466 if (context->lock < 3) | |
111 | 1467 pp_newline_and_flush (context->printer); |
0 | 1468 |
1469 fnotice (stderr, | |
1470 "Internal compiler error: Error reporting routines re-entered.\n"); | |
1471 | |
1472 /* Call diagnostic_action_after_output to get the "please submit a bug | |
111 | 1473 report" message. */ |
1474 diagnostic_action_after_output (context, DK_ICE); | |
0 | 1475 |
1476 /* Do not use gcc_unreachable here; that goes through internal_error | |
1477 and therefore would cause infinite recursion. */ | |
1478 real_abort (); | |
1479 } | |
1480 | |
1481 /* Report an internal compiler error in a friendly manner. This is | |
1482 the function that gets called upon use of abort() in the source | |
1483 code generally, thanks to a special macro. */ | |
1484 | |
1485 void | |
1486 fancy_abort (const char *file, int line, const char *function) | |
1487 { | |
1488 internal_error ("in %s, at %s:%d", function, trim_filename (file), line); | |
1489 } | |
1490 | |
1491 /* Really call the system 'abort'. This has to go right at the end of | |
1492 this file, so that there are no functions after it that call abort | |
1493 and get the system abort instead of our macro. */ | |
1494 #undef abort | |
1495 static void | |
1496 real_abort (void) | |
1497 { | |
1498 abort (); | |
1499 } | |
111 | 1500 |
1501 #if CHECKING_P | |
1502 | |
1503 namespace selftest { | |
1504 | |
1505 /* Helper function for test_print_escaped_string. */ | |
1506 | |
1507 static void | |
1508 assert_print_escaped_string (const location &loc, const char *expected_output, | |
1509 const char *input) | |
1510 { | |
1511 pretty_printer pp; | |
1512 print_escaped_string (&pp, input); | |
1513 ASSERT_STREQ_AT (loc, expected_output, pp_formatted_text (&pp)); | |
1514 } | |
1515 | |
1516 #define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \ | |
1517 assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT) | |
1518 | |
1519 /* Tests of print_escaped_string. */ | |
1520 | |
1521 static void | |
1522 test_print_escaped_string () | |
1523 { | |
1524 /* Empty string. */ | |
1525 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", ""); | |
1526 | |
1527 /* Non-empty string. */ | |
1528 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world"); | |
1529 | |
1530 /* Various things that need to be escaped: */ | |
1531 /* Backslash. */ | |
1532 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"", | |
1533 "before\\after"); | |
1534 /* Tab. */ | |
1535 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"", | |
1536 "before\tafter"); | |
1537 /* Newline. */ | |
1538 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"", | |
1539 "before\nafter"); | |
1540 /* Double quote. */ | |
1541 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"", | |
1542 "before\"after"); | |
1543 | |
1544 /* Non-printable characters: BEL: '\a': 0x07 */ | |
1545 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"", | |
1546 "before\aafter"); | |
1547 /* Non-printable characters: vertical tab: '\v': 0x0b */ | |
1548 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"", | |
1549 "before\vafter"); | |
1550 } | |
1551 | |
1552 /* Tests of print_parseable_fixits. */ | |
1553 | |
1554 /* Verify that print_parseable_fixits emits the empty string if there | |
1555 are no fixits. */ | |
1556 | |
1557 static void | |
1558 test_print_parseable_fixits_none () | |
1559 { | |
1560 pretty_printer pp; | |
1561 rich_location richloc (line_table, UNKNOWN_LOCATION); | |
1562 | |
1563 print_parseable_fixits (&pp, &richloc); | |
1564 ASSERT_STREQ ("", pp_formatted_text (&pp)); | |
1565 } | |
1566 | |
1567 /* Verify that print_parseable_fixits does the right thing if there | |
1568 is an insertion fixit hint. */ | |
1569 | |
1570 static void | |
1571 test_print_parseable_fixits_insert () | |
1572 { | |
1573 pretty_printer pp; | |
1574 rich_location richloc (line_table, UNKNOWN_LOCATION); | |
1575 | |
1576 linemap_add (line_table, LC_ENTER, false, "test.c", 0); | |
1577 linemap_line_start (line_table, 5, 100); | |
1578 linemap_add (line_table, LC_LEAVE, false, NULL, 0); | |
1579 location_t where = linemap_position_for_column (line_table, 10); | |
1580 richloc.add_fixit_insert_before (where, "added content"); | |
1581 | |
1582 print_parseable_fixits (&pp, &richloc); | |
1583 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n", | |
1584 pp_formatted_text (&pp)); | |
1585 } | |
1586 | |
1587 /* Verify that print_parseable_fixits does the right thing if there | |
1588 is an removal fixit hint. */ | |
1589 | |
1590 static void | |
1591 test_print_parseable_fixits_remove () | |
1592 { | |
1593 pretty_printer pp; | |
1594 rich_location richloc (line_table, UNKNOWN_LOCATION); | |
1595 | |
1596 linemap_add (line_table, LC_ENTER, false, "test.c", 0); | |
1597 linemap_line_start (line_table, 5, 100); | |
1598 linemap_add (line_table, LC_LEAVE, false, NULL, 0); | |
1599 source_range where; | |
1600 where.m_start = linemap_position_for_column (line_table, 10); | |
1601 where.m_finish = linemap_position_for_column (line_table, 20); | |
1602 richloc.add_fixit_remove (where); | |
1603 | |
1604 print_parseable_fixits (&pp, &richloc); | |
1605 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n", | |
1606 pp_formatted_text (&pp)); | |
1607 } | |
1608 | |
1609 /* Verify that print_parseable_fixits does the right thing if there | |
1610 is an replacement fixit hint. */ | |
1611 | |
1612 static void | |
1613 test_print_parseable_fixits_replace () | |
1614 { | |
1615 pretty_printer pp; | |
1616 rich_location richloc (line_table, UNKNOWN_LOCATION); | |
1617 | |
1618 linemap_add (line_table, LC_ENTER, false, "test.c", 0); | |
1619 linemap_line_start (line_table, 5, 100); | |
1620 linemap_add (line_table, LC_LEAVE, false, NULL, 0); | |
1621 source_range where; | |
1622 where.m_start = linemap_position_for_column (line_table, 10); | |
1623 where.m_finish = linemap_position_for_column (line_table, 20); | |
1624 richloc.add_fixit_replace (where, "replacement"); | |
1625 | |
1626 print_parseable_fixits (&pp, &richloc); | |
1627 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n", | |
1628 pp_formatted_text (&pp)); | |
1629 } | |
1630 | |
1631 /* Run all of the selftests within this file. */ | |
1632 | |
1633 void | |
1634 diagnostic_c_tests () | |
1635 { | |
1636 test_print_escaped_string (); | |
1637 test_print_parseable_fixits_none (); | |
1638 test_print_parseable_fixits_insert (); | |
1639 test_print_parseable_fixits_remove (); | |
1640 test_print_parseable_fixits_replace (); | |
1641 } | |
1642 | |
1643 } // namespace selftest | |
1644 | |
1645 #endif /* #if CHECKING_P */ |