00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "config.h"
00035 #undef FLOAT
00036 #undef FFS
00037 #include "system.h"
00038 #ifdef SGI_MONGOOSE
00039
00040 #include "rtl.h"
00041 #endif
00042 #include "tree.h"
00043 #include "tm_p.h"
00044 #include "flags.h"
00045 #include "input.h"
00046 #include "toplev.h"
00047 #include "intl.h"
00048 #include "diagnostic.h"
00049 #include "langhooks.h"
00050 #include "langhooks-def.h"
00051 #ifdef KEY
00052 #include <cmplrs/rcodes.h>
00053 #endif
00054
00055 #define output_text_length(BUFFER) (BUFFER)->line_length
00056 #define is_starting_newline(BUFFER) (output_text_length (BUFFER) == 0)
00057 #define line_wrap_cutoff(BUFFER) (BUFFER)->state.maximum_length
00058 #define prefix_was_emitted_for(BUFFER) (BUFFER)->state.emitted_prefix_p
00059
00060
00061 static void output_flush PARAMS ((output_buffer *));
00062 static void output_do_verbatim PARAMS ((output_buffer *, text_info *));
00063 static void output_buffer_to_stream PARAMS ((output_buffer *));
00064 static void output_format PARAMS ((output_buffer *, text_info *));
00065 static void output_indent PARAMS ((output_buffer *));
00066
00067 static char *vbuild_message_string PARAMS ((const char *, va_list))
00068 ATTRIBUTE_PRINTF (1, 0);
00069 static char *build_message_string PARAMS ((const char *, ...))
00070 ATTRIBUTE_PRINTF_1;
00071 static void format_with_decl PARAMS ((output_buffer *, text_info *, tree));
00072 static void diagnostic_for_decl PARAMS ((diagnostic_info *, tree));
00073 static void set_real_maximum_length PARAMS ((output_buffer *));
00074
00075 static void output_unsigned_decimal PARAMS ((output_buffer *, unsigned int));
00076 static void output_long_decimal PARAMS ((output_buffer *, long int));
00077 static void output_long_unsigned_decimal PARAMS ((output_buffer *,
00078 long unsigned int));
00079 static void output_octal PARAMS ((output_buffer *, unsigned int));
00080 static void output_long_octal PARAMS ((output_buffer *, unsigned long int));
00081 static void output_hexadecimal PARAMS ((output_buffer *, unsigned int));
00082 static void output_long_hexadecimal PARAMS ((output_buffer *,
00083 unsigned long int));
00084 static void output_pointer PARAMS ((output_buffer *, void *));
00085 static void output_append_r PARAMS ((output_buffer *, const char *, int));
00086 static void wrap_text PARAMS ((output_buffer *, const char *, const char *));
00087 static void maybe_wrap_text PARAMS ((output_buffer *, const char *,
00088 const char *));
00089 static void output_clear_data PARAMS ((output_buffer *));
00090
00091 static void default_diagnostic_starter PARAMS ((diagnostic_context *,
00092 diagnostic_info *));
00093 static void default_diagnostic_finalizer PARAMS ((diagnostic_context *,
00094 diagnostic_info *));
00095
00096 static void error_recursion PARAMS ((diagnostic_context *)) ATTRIBUTE_NORETURN;
00097 static bool text_specifies_location PARAMS ((text_info *, location_t *));
00098
00099 extern int rtl_dump_and_exit;
00100 extern int warnings_are_errors;
00101
00102
00103 static diagnostic_context global_diagnostic_context;
00104 diagnostic_context *global_dc = &global_diagnostic_context;
00105
00106
00107
00108
00109 static void
00110 set_real_maximum_length (buffer)
00111 output_buffer *buffer;
00112 {
00113
00114
00115
00116 if (!output_is_line_wrapping (buffer)
00117 || output_prefixing_rule (buffer) == DIAGNOSTICS_SHOW_PREFIX_ONCE
00118 || output_prefixing_rule (buffer) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
00119 line_wrap_cutoff (buffer) = output_line_cutoff (buffer);
00120 else
00121 {
00122 int prefix_length = buffer->state.prefix ?
00123 strlen (buffer->state.prefix) : 0;
00124
00125
00126 if (output_line_cutoff (buffer) - prefix_length < 32)
00127 line_wrap_cutoff (buffer) = output_line_cutoff (buffer) + 32;
00128 else
00129 line_wrap_cutoff (buffer) = output_line_cutoff (buffer);
00130 }
00131 }
00132
00133
00134
00135 void
00136 output_set_maximum_length (buffer, length)
00137 output_buffer *buffer;
00138 int length;
00139 {
00140 output_line_cutoff (buffer) = length;
00141 set_real_maximum_length (buffer);
00142 }
00143
00144
00145 void
00146 output_set_prefix (buffer, prefix)
00147 output_buffer *buffer;
00148 const char *prefix;
00149 {
00150 buffer->state.prefix = prefix;
00151 set_real_maximum_length (buffer);
00152 prefix_was_emitted_for (buffer) = false;
00153 output_indentation (buffer) = 0;
00154 }
00155
00156
00157
00158 const char *
00159 output_last_position (buffer)
00160 const output_buffer *buffer;
00161 {
00162 const char *p = NULL;
00163
00164 if (obstack_base (&buffer->obstack) != obstack_next_free (&buffer->obstack))
00165 p = ((const char *) obstack_next_free (&buffer->obstack)) - 1;
00166 return p;
00167 }
00168
00169
00170 void
00171 output_destroy_prefix (buffer)
00172 output_buffer *buffer;
00173 {
00174 if (buffer->state.prefix != NULL)
00175 {
00176 free ((char *) buffer->state.prefix);
00177 buffer->state.prefix = NULL;
00178 }
00179 }
00180
00181
00182 void
00183 output_clear_message_text (buffer)
00184 output_buffer *buffer;
00185 {
00186 obstack_free (&buffer->obstack, obstack_base (&buffer->obstack));
00187 output_text_length (buffer) = 0;
00188 }
00189
00190
00191 static void
00192 output_clear_data (buffer)
00193 output_buffer *buffer;
00194 {
00195 prefix_was_emitted_for (buffer) = false;
00196 output_indentation (buffer) = 0;
00197 }
00198
00199
00200
00201 void
00202 init_output_buffer (buffer, prefix, maximum_length)
00203 output_buffer *buffer;
00204 const char *prefix;
00205 int maximum_length;
00206 {
00207 memset (buffer, 0, sizeof (output_buffer));
00208 obstack_init (&buffer->obstack);
00209 output_buffer_attached_stream (buffer) = stderr;
00210 output_line_cutoff (buffer) = maximum_length;
00211 output_prefixing_rule (buffer) = diagnostic_prefixing_rule (global_dc);
00212 output_set_prefix (buffer, prefix);
00213 output_text_length (buffer) = 0;
00214 output_clear_data (buffer);
00215 }
00216
00217
00218 void
00219 output_clear (buffer)
00220 output_buffer *buffer;
00221 {
00222 output_clear_message_text (buffer);
00223 output_clear_data (buffer);
00224 }
00225
00226
00227
00228 const char *
00229 output_finalize_message (buffer)
00230 output_buffer *buffer;
00231 {
00232 obstack_1grow (&buffer->obstack, '\0');
00233 return output_message_text (buffer);
00234 }
00235
00236
00237
00238 int
00239 output_space_left (buffer)
00240 const output_buffer *buffer;
00241 {
00242 return line_wrap_cutoff (buffer) - output_text_length (buffer);
00243 }
00244
00245
00246 void
00247 output_emit_prefix (buffer)
00248 output_buffer *buffer;
00249 {
00250 if (buffer->state.prefix != NULL)
00251 {
00252 switch (output_prefixing_rule (buffer))
00253 {
00254 default:
00255 case DIAGNOSTICS_SHOW_PREFIX_NEVER:
00256 break;
00257
00258 case DIAGNOSTICS_SHOW_PREFIX_ONCE:
00259 if (prefix_was_emitted_for (buffer))
00260 {
00261 output_indent (buffer);
00262 break;
00263 }
00264 output_indentation (buffer) += 3;
00265
00266
00267 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
00268 {
00269 int prefix_length = strlen (buffer->state.prefix);
00270 output_append_r (buffer, buffer->state.prefix, prefix_length);
00271 prefix_was_emitted_for (buffer) = true;
00272 }
00273 break;
00274 }
00275 }
00276 }
00277
00278
00279 void
00280 output_add_newline (buffer)
00281 output_buffer *buffer;
00282 {
00283 obstack_1grow (&buffer->obstack, '\n');
00284 output_text_length (buffer) = 0;
00285 }
00286
00287
00288 void
00289 output_add_character (buffer, c)
00290 output_buffer *buffer;
00291 int c;
00292 {
00293 if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
00294 output_add_newline (buffer);
00295 obstack_1grow (&buffer->obstack, c);
00296 ++output_text_length (buffer);
00297 }
00298
00299
00300 void
00301 output_add_space (buffer)
00302 output_buffer *buffer;
00303 {
00304 if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
00305 {
00306 output_add_newline (buffer);
00307 return;
00308 }
00309 obstack_1grow (&buffer->obstack, ' ');
00310 ++output_text_length (buffer);
00311 }
00312
00313
00314
00315 void
00316 output_decimal (buffer, i)
00317 output_buffer *buffer;
00318 int i;
00319 {
00320 output_formatted_scalar (buffer, "%d", i);
00321 }
00322
00323 static void
00324 output_long_decimal (buffer, i)
00325 output_buffer *buffer;
00326 long int i;
00327 {
00328 output_formatted_scalar (buffer, "%ld", i);
00329 }
00330
00331 static void
00332 output_unsigned_decimal (buffer, i)
00333 output_buffer *buffer;
00334 unsigned int i;
00335 {
00336 output_formatted_scalar (buffer, "%u", i);
00337 }
00338
00339 static void
00340 output_long_unsigned_decimal (buffer, i)
00341 output_buffer *buffer;
00342 long unsigned int i;
00343 {
00344 output_formatted_scalar (buffer, "%lu", i);
00345 }
00346
00347 static void
00348 output_octal (buffer, i)
00349 output_buffer *buffer;
00350 unsigned int i;
00351 {
00352 output_formatted_scalar (buffer, "%o", i);
00353 }
00354
00355 static void
00356 output_long_octal (buffer, i)
00357 output_buffer *buffer;
00358 unsigned long int i;
00359 {
00360 output_formatted_scalar (buffer, "%lo", i);
00361 }
00362
00363 static void
00364 output_hexadecimal (buffer, i)
00365 output_buffer *buffer;
00366 unsigned int i;
00367 {
00368 output_formatted_scalar (buffer, "%x", i);
00369 }
00370
00371 static void
00372 output_long_hexadecimal (buffer, i)
00373 output_buffer *buffer;
00374 unsigned long int i;
00375 {
00376 output_formatted_scalar (buffer, "%lx", i);
00377 }
00378
00379 static void
00380 output_pointer (buffer, p)
00381 output_buffer *buffer;
00382 void *p;
00383 {
00384 output_formatted_scalar (buffer, HOST_PTR_PRINTF, p);
00385 }
00386
00387
00388
00389 static void
00390 output_append_r (buffer, start, length)
00391 output_buffer *buffer;
00392 const char *start;
00393 int length;
00394 {
00395 obstack_grow (&buffer->obstack, start, length);
00396 output_text_length (buffer) += length;
00397 }
00398
00399
00400
00401
00402
00403 void
00404 output_append (buffer, start, end)
00405 output_buffer *buffer;
00406 const char *start;
00407 const char *end;
00408 {
00409
00410 if (is_starting_newline (buffer))
00411 {
00412 output_emit_prefix (buffer);
00413 if (output_is_line_wrapping (buffer))
00414 while (start != end && *start == ' ')
00415 ++start;
00416 }
00417 output_append_r (buffer, start, end - start);
00418 }
00419
00420 static void
00421 output_indent (buffer)
00422 output_buffer *buffer;
00423 {
00424 int n = output_indentation (buffer);
00425 int i;
00426
00427 for (i = 0; i < n; ++i)
00428 output_add_character (buffer, ' ');
00429 }
00430
00431
00432 static void
00433 wrap_text (buffer, start, end)
00434 output_buffer *buffer;
00435 const char *start;
00436 const char *end;
00437 {
00438 bool is_wrapping = output_is_line_wrapping (buffer);
00439
00440 while (start != end)
00441 {
00442
00443 {
00444 const char *p = start;
00445 while (p != end && *p != ' ' && *p != '\n')
00446 ++p;
00447 if (is_wrapping && p - start >= output_space_left (buffer))
00448 output_add_newline (buffer);
00449 output_append (buffer, start, p);
00450 start = p;
00451 }
00452
00453 if (start != end && *start == ' ')
00454 {
00455 output_add_space (buffer);
00456 ++start;
00457 }
00458 if (start != end && *start == '\n')
00459 {
00460 output_add_newline (buffer);
00461 ++start;
00462 }
00463 }
00464 }
00465
00466
00467 static void
00468 maybe_wrap_text (buffer, start, end)
00469 output_buffer *buffer;
00470 const char *start;
00471 const char *end;
00472 {
00473 if (output_is_line_wrapping (buffer))
00474 wrap_text (buffer, start, end);
00475 else
00476 output_append (buffer, start, end);
00477 }
00478
00479
00480
00481
00482 void
00483 output_add_string (buffer, str)
00484 output_buffer *buffer;
00485 const char *str;
00486 {
00487 maybe_wrap_text (buffer, str, str + (str ? strlen (str) : 0));
00488 }
00489
00490
00491 void
00492 output_add_identifier (buffer, id)
00493 output_buffer *buffer;
00494 tree id;
00495 {
00496 output_append (buffer, IDENTIFIER_POINTER (id),
00497 IDENTIFIER_POINTER (id) + IDENTIFIER_LENGTH (id));
00498 }
00499
00500
00501
00502
00503 static void
00504 output_buffer_to_stream (buffer)
00505 output_buffer *buffer;
00506 {
00507 const char *text = output_finalize_message (buffer);
00508 fputs (text, output_buffer_attached_stream (buffer));
00509 output_clear_message_text (buffer);
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 static void
00526 output_format (buffer, text)
00527 output_buffer *buffer;
00528 text_info *text;
00529 {
00530 for (; *text->format_spec; ++text->format_spec)
00531 {
00532 bool long_integer = 0;
00533
00534
00535 {
00536 const char *p = text->format_spec;
00537 while (*p && *p != '%')
00538 ++p;
00539 wrap_text (buffer, text->format_spec, p);
00540 text->format_spec = p;
00541 }
00542
00543 if (*text->format_spec == '\0')
00544 break;
00545
00546
00547
00548 if (*++text->format_spec == 'l')
00549 {
00550 long_integer = true;
00551 ++text->format_spec;
00552 }
00553
00554
00555
00556
00557 switch (*text->format_spec)
00558 {
00559 case 'c':
00560 output_add_character (buffer, va_arg (*text->args_ptr, int));
00561 break;
00562
00563 case 'd':
00564 case 'i':
00565 if (long_integer)
00566 output_long_decimal (buffer, va_arg (*text->args_ptr, long int));
00567 else
00568 output_decimal (buffer, va_arg (*text->args_ptr, int));
00569 break;
00570
00571 case 'o':
00572 if (long_integer)
00573 output_long_octal (buffer,
00574 va_arg (*text->args_ptr, unsigned long int));
00575 else
00576 output_octal (buffer, va_arg (*text->args_ptr, unsigned int));
00577 break;
00578
00579 case 's':
00580 output_add_string (buffer, va_arg (*text->args_ptr, const char *));
00581 break;
00582
00583 case 'p':
00584 output_pointer (buffer, va_arg (*text->args_ptr, void *));
00585 break;
00586
00587 case 'u':
00588 if (long_integer)
00589 output_long_unsigned_decimal
00590 (buffer, va_arg (*text->args_ptr, long unsigned int));
00591 else
00592 output_unsigned_decimal
00593 (buffer, va_arg (*text->args_ptr, unsigned int));
00594 break;
00595
00596 case 'x':
00597 if (long_integer)
00598 output_long_hexadecimal
00599 (buffer, va_arg (*text->args_ptr, unsigned long int));
00600 else
00601 output_hexadecimal
00602 (buffer, va_arg (*text->args_ptr, unsigned int));
00603 break;
00604
00605 case '%':
00606 output_add_character (buffer, '%');
00607 break;
00608
00609 case 'H':
00610 {
00611 const location_t *locus = va_arg (*text->args_ptr, location_t *);
00612 output_add_string (buffer, "file '");
00613 output_add_string (buffer, locus->file);
00614 output_add_string (buffer, "', line ");
00615 output_decimal (buffer, locus->line);
00616 }
00617 break;
00618
00619 case '.':
00620 {
00621 int n;
00622 const char *s;
00623
00624 if (*++text->format_spec != '*')
00625 abort ();
00626 else if (*++text->format_spec != 's')
00627 abort ();
00628 n = va_arg (*text->args_ptr, int);
00629 s = va_arg (*text->args_ptr, const char *);
00630 output_append (buffer, s, s + n);
00631 }
00632 break;
00633
00634 default:
00635 if (!buffer->format_decoder
00636 || !(*buffer->format_decoder) (buffer, text))
00637 {
00638
00639
00640 abort ();
00641 }
00642 }
00643 }
00644 }
00645
00646 static char *
00647 vbuild_message_string (msg, ap)
00648 const char *msg;
00649 va_list ap;
00650 {
00651 char *str;
00652
00653 vasprintf (&str, msg, ap);
00654 return str;
00655 }
00656
00657
00658
00659 static char *
00660 build_message_string VPARAMS ((const char *msg, ...))
00661 {
00662 char *str;
00663
00664 VA_OPEN (ap, msg);
00665 VA_FIXEDARG (ap, const char *, msg);
00666
00667 str = vbuild_message_string (msg, ap);
00668
00669 VA_CLOSE (ap);
00670
00671 return str;
00672 }
00673
00674
00675 char *
00676 file_name_as_prefix (f)
00677 const char *f;
00678 {
00679 return build_message_string ("%s: ", f);
00680 }
00681
00682
00683 void
00684 output_printf VPARAMS ((struct output_buffer *buffer, const char *msgid, ...))
00685 {
00686 text_info text;
00687 VA_OPEN (ap, msgid);
00688 VA_FIXEDARG (ap, output_buffer *, buffer);
00689 VA_FIXEDARG (ap, const char *, msgid);
00690
00691 text.args_ptr = ≈
00692 text.format_spec = _(msgid);
00693 output_format (buffer, &text);
00694 VA_CLOSE (ap);
00695 }
00696
00697
00698 static void
00699 format_with_decl (buffer, text, decl)
00700 output_buffer *buffer;
00701 text_info *text;
00702 tree decl;
00703 {
00704 const char *p;
00705
00706
00707
00708
00709 for (p = text->format_spec; *p; ++p)
00710 {
00711 if (*p == '%')
00712 {
00713 if (*(p + 1) == '%')
00714 ++p;
00715 else if (*(p + 1) != 's')
00716 abort ();
00717 else
00718 break;
00719 }
00720 }
00721
00722
00723 maybe_wrap_text (buffer, text->format_spec, p);
00724
00725 if (*p == '%')
00726 {
00727 const char *const n = (DECL_NAME (decl)
00728 ? (*lang_hooks.decl_printable_name) (decl, 2)
00729 : _("((anonymous))"));
00730 output_add_string (buffer, n);
00731 while (*p)
00732 {
00733 ++p;
00734 if (ISALPHA (*(p - 1) & 0xFF))
00735 break;
00736 }
00737 }
00738
00739 if (*p)
00740 {
00741 text->format_spec = p;
00742 output_format (buffer, text);
00743 }
00744 }
00745
00746
00747 static void
00748 output_flush (buffer)
00749 output_buffer *buffer;
00750 {
00751 output_buffer_to_stream (buffer);
00752 output_clear_data (buffer);
00753 fputc ('\n', output_buffer_attached_stream (buffer));
00754 fflush (output_buffer_attached_stream (buffer));
00755 }
00756
00757
00758
00759 static void
00760 output_do_verbatim (buffer, text)
00761 output_buffer *buffer;
00762 text_info *text;
00763 {
00764 diagnostic_prefixing_rule_t rule = output_prefixing_rule (buffer);
00765 int line_cutoff = output_line_cutoff (buffer);
00766
00767
00768 output_prefixing_rule (buffer) = DIAGNOSTICS_SHOW_PREFIX_NEVER;
00769 output_line_cutoff (buffer) = 0;
00770
00771 output_format (buffer, text);
00772
00773 output_prefixing_rule (buffer) = rule;
00774 output_line_cutoff (buffer) = line_cutoff;
00775 }
00776
00777
00778 void
00779 output_verbatim VPARAMS ((output_buffer *buffer, const char *msgid, ...))
00780 {
00781 text_info text;
00782 VA_OPEN (ap, msgid);
00783 VA_FIXEDARG (ap, output_buffer *, buffer);
00784 VA_FIXEDARG (ap, const char *, msgid);
00785
00786 text.format_spec = msgid;
00787 text.args_ptr = ≈
00788 output_do_verbatim (buffer, &text);
00789 VA_CLOSE (ap);
00790 }
00791
00792
00793
00794 void
00795 diagnostic_initialize (context)
00796 diagnostic_context *context;
00797 {
00798 memset (context, 0, sizeof *context);
00799 obstack_init (&context->buffer.obstack);
00800
00801
00802 output_buffer_attached_stream (&context->buffer) = stderr;
00803
00804
00805 diagnostic_prefixing_rule (context) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
00806
00807 diagnostic_starter (context) = default_diagnostic_starter;
00808 diagnostic_finalizer (context) = default_diagnostic_finalizer;
00809 context->warnings_are_errors_message = warnings_are_errors;
00810 }
00811
00812
00813
00814
00815 static bool
00816 text_specifies_location (text, locus)
00817 text_info *text;
00818 location_t *locus;
00819 {
00820 const char *p;
00821
00822 for (p = text->format_spec; *p && *p != '%'; ++p)
00823 ;
00824
00825
00826 if (*p == '%' && *++p == 'H')
00827 {
00828 *locus = *va_arg (*text->args_ptr, location_t *);
00829 text->format_spec = p + 1;
00830 return true;
00831 }
00832
00833 return false;
00834 }
00835
00836 void
00837 diagnostic_set_info (diagnostic, msgid, args, file, line, kind)
00838 diagnostic_info *diagnostic;
00839 const char *msgid;
00840 va_list *args;
00841 const char *file;
00842 int line;
00843 diagnostic_t kind;
00844 {
00845 diagnostic->message.format_spec = msgid;
00846 diagnostic->message.args_ptr = args;
00847
00848
00849 if (!text_specifies_location (&diagnostic->message, &diagnostic->location))
00850 {
00851 diagnostic->location.file = file;
00852 diagnostic->location.line = line;
00853 }
00854 diagnostic->kind = kind;
00855 }
00856
00857
00858
00859 char *
00860 diagnostic_build_prefix (diagnostic)
00861 diagnostic_info *diagnostic;
00862 {
00863 static const char *const diagnostic_kind_text[] = {
00864 #define DEFINE_DIAGNOSTIC_KIND(K, T) (T),
00865 #include "diagnostic.def"
00866 #undef DEFINE_DIAGNOSTIC_KIND
00867 "must-not-happen"
00868 };
00869 if (diagnostic->kind >= DK_LAST_DIAGNOSTIC_KIND)
00870 abort();
00871
00872 return diagnostic->location.file
00873 ? build_message_string ("%s:%d: %s",
00874 diagnostic->location.file,
00875 diagnostic->location.line,
00876 _(diagnostic_kind_text[diagnostic->kind]))
00877 : build_message_string ("%s: %s", progname,
00878 _(diagnostic_kind_text[diagnostic->kind]));
00879 }
00880
00881
00882
00883
00884 static void
00885 diagnostic_for_decl (diagnostic, decl)
00886 diagnostic_info *diagnostic;
00887 tree decl;
00888 {
00889 if (global_dc->lock++)
00890 error_recursion (global_dc);
00891
00892 if (diagnostic_count_diagnostic (global_dc, diagnostic->kind))
00893 {
00894 diagnostic_report_current_function (global_dc);
00895 output_set_prefix
00896 (&global_dc->buffer, diagnostic_build_prefix (diagnostic));
00897 format_with_decl (&global_dc->buffer, &diagnostic->message, decl);
00898 output_flush (&global_dc->buffer);
00899 output_destroy_prefix (&global_dc->buffer);
00900 }
00901 global_dc->lock--;
00902 }
00903
00904 void
00905 diagnostic_flush_buffer (context)
00906 diagnostic_context *context;
00907 {
00908 output_buffer_to_stream (&context->buffer);
00909 fflush (output_buffer_attached_stream (&context->buffer));
00910 }
00911
00912
00913 bool
00914 diagnostic_count_diagnostic (context, kind)
00915 diagnostic_context *context;
00916 diagnostic_t kind;
00917 {
00918 switch (kind)
00919 {
00920 default:
00921 abort();
00922 break;
00923
00924 case DK_FATAL: case DK_ICE: case DK_SORRY:
00925 case DK_ANACHRONISM: case DK_NOTE:
00926 ++diagnostic_kind_count (context, kind);
00927 break;
00928
00929 case DK_WARNING:
00930 if (!diagnostic_report_warnings_p ())
00931 return false;
00932 else if (!warnings_are_errors)
00933 {
00934 ++diagnostic_kind_count (context, DK_WARNING);
00935 break;
00936 }
00937
00938
00939 case DK_ERROR:
00940 if (kind == DK_WARNING && context->warnings_are_errors_message)
00941 {
00942 output_verbatim (&context->buffer,
00943 "%s: warnings being treated as errors\n", progname);
00944 context->warnings_are_errors_message = false;
00945 }
00946 ++diagnostic_kind_count (context, DK_ERROR);
00947 break;
00948 }
00949
00950 return true;
00951 }
00952
00953
00954
00955 void
00956 fnotice VPARAMS ((FILE *file, const char *msgid, ...))
00957 {
00958 VA_OPEN (ap, msgid);
00959 VA_FIXEDARG (ap, FILE *, file);
00960 VA_FIXEDARG (ap, const char *, msgid);
00961
00962 vfprintf (file, _(msgid), ap);
00963 VA_CLOSE (ap);
00964 }
00965
00966
00967
00968
00969 void
00970 fatal_io_error VPARAMS ((const char *msgid, ...))
00971 {
00972 text_info text;
00973 VA_OPEN (ap, msgid);
00974 VA_FIXEDARG (ap, const char *, msgid);
00975
00976 text.format_spec = _(msgid);
00977 text.args_ptr = ≈
00978 output_printf (&global_dc->buffer, "%s: %s: ", progname, xstrerror (errno));
00979 output_format (&global_dc->buffer, &text);
00980 output_flush (&global_dc->buffer);
00981 VA_CLOSE (ap);
00982 exit (FATAL_EXIT_CODE);
00983 }
00984
00985
00986 void
00987 pedwarn VPARAMS ((const char *msgid, ...))
00988 {
00989 diagnostic_info diagnostic;
00990 VA_OPEN (ap, msgid);
00991 VA_FIXEDARG (ap, const char *, msgid);
00992
00993 diagnostic_set_info (&diagnostic, _(msgid), &ap, input_filename, lineno,
00994 pedantic_error_kind ());
00995 report_diagnostic (&diagnostic);
00996 VA_CLOSE (ap);
00997 }
00998
00999
01000 void
01001 pedwarn_with_decl VPARAMS ((tree decl, const char *msgid, ...))
01002 {
01003 diagnostic_info diagnostic;
01004 VA_OPEN (ap, msgid);
01005 VA_FIXEDARG (ap, tree, decl);
01006 VA_FIXEDARG (ap, const char *, msgid);
01007
01008 diagnostic_set_info (&diagnostic, _(msgid), &ap,
01009 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
01010 pedantic_error_kind ());
01011
01012
01013
01014
01015
01016
01017
01018 if (!DECL_IN_SYSTEM_HEADER (decl))
01019 diagnostic_for_decl (&diagnostic, decl);
01020 VA_CLOSE (ap);
01021 }
01022
01023
01024 void
01025 pedwarn_with_file_and_line VPARAMS ((const char *file, int line,
01026 const char *msgid, ...))
01027 {
01028 diagnostic_info diagnostic;
01029 VA_OPEN (ap, msgid);
01030 VA_FIXEDARG (ap, const char *, file);
01031 VA_FIXEDARG (ap, int, line);
01032 VA_FIXEDARG (ap, const char *, msgid);
01033
01034 diagnostic_set_info (&diagnostic, _(msgid), &ap, file, line,
01035 pedantic_error_kind ());
01036 report_diagnostic (&diagnostic);
01037 VA_CLOSE (ap);
01038 }
01039
01040
01041 void
01042 sorry VPARAMS ((const char *msgid, ...))
01043 {
01044 diagnostic_info diagnostic;
01045
01046 VA_OPEN (ap, msgid);
01047 VA_FIXEDARG (ap, const char *, msgid);
01048
01049 ++sorrycount;
01050 diagnostic_set_info (&diagnostic, _(msgid), &ap,
01051 input_filename, lineno, DK_SORRY);
01052
01053 output_set_prefix
01054 (&global_dc->buffer, diagnostic_build_prefix (&diagnostic));
01055 output_format (&global_dc->buffer, &diagnostic.message);
01056 output_flush (&global_dc->buffer);
01057 VA_CLOSE (ap);
01058 }
01059
01060
01061
01062 void
01063 announce_function (decl)
01064 tree decl;
01065 {
01066 if (!quiet_flag)
01067 {
01068 if (rtl_dump_and_exit)
01069 verbatim ("%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
01070 else
01071 verbatim (" %s", (*lang_hooks.decl_printable_name) (decl, 2));
01072 fflush (stderr);
01073 output_needs_newline (&global_dc->buffer) = true;
01074 diagnostic_set_last_function (global_dc);
01075 }
01076 }
01077
01078
01079
01080 void
01081 lhd_print_error_function (context, file)
01082 diagnostic_context *context;
01083 const char *file;
01084 {
01085 if (diagnostic_last_function_changed (context))
01086 {
01087 const char *old_prefix = output_prefix (&context->buffer);
01088 char *new_prefix = file ? build_message_string ("%s: ", file) : NULL;
01089
01090 output_set_prefix (&context->buffer, new_prefix);
01091
01092 if (current_function_decl == NULL)
01093 output_add_string (&context->buffer, _("At top level:"));
01094 else
01095 {
01096 if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
01097 output_printf
01098 (&context->buffer, "In member function `%s':",
01099 (*lang_hooks.decl_printable_name) (current_function_decl, 2));
01100 else
01101 output_printf
01102 (&context->buffer, "In function `%s':",
01103 (*lang_hooks.decl_printable_name) (current_function_decl, 2));
01104 }
01105 output_add_newline (&context->buffer);
01106
01107 diagnostic_set_last_function (context);
01108 output_buffer_to_stream (&context->buffer);
01109 context->buffer.state.prefix = old_prefix;
01110 free ((char*) new_prefix);
01111 }
01112 }
01113
01114
01115
01116
01117
01118 void
01119 diagnostic_report_current_function (context)
01120 diagnostic_context *context;
01121 {
01122 diagnostic_report_current_module (context);
01123 (*lang_hooks.print_error_function) (context, input_filename);
01124 }
01125
01126 void
01127 error_with_file_and_line VPARAMS ((const char *file, int line,
01128 const char *msgid, ...))
01129 {
01130 diagnostic_info diagnostic;
01131
01132 VA_OPEN (ap, msgid);
01133 VA_FIXEDARG (ap, const char *, file);
01134 VA_FIXEDARG (ap, int, line);
01135 VA_FIXEDARG (ap, const char *, msgid);
01136
01137 diagnostic_set_info (&diagnostic, msgid, &ap, file, line, DK_ERROR);
01138 report_diagnostic (&diagnostic);
01139 VA_CLOSE (ap);
01140 }
01141
01142 void
01143 error_with_decl VPARAMS ((tree decl, const char *msgid, ...))
01144 {
01145 diagnostic_info diagnostic;
01146 VA_OPEN (ap, msgid);
01147 VA_FIXEDARG (ap, tree, decl);
01148 VA_FIXEDARG (ap, const char *, msgid);
01149
01150 diagnostic_set_info (&diagnostic, msgid, &ap,
01151 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
01152 DK_ERROR);
01153 diagnostic_for_decl (&diagnostic, decl);
01154 VA_CLOSE (ap);
01155 }
01156
01157
01158
01159
01160 void
01161 error VPARAMS ((const char *msgid, ...))
01162 {
01163 diagnostic_info diagnostic;
01164
01165 VA_OPEN (ap, msgid);
01166 VA_FIXEDARG (ap, const char *, msgid);
01167
01168 diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
01169 DK_ERROR);
01170 report_diagnostic (&diagnostic);
01171 VA_CLOSE (ap);
01172 #ifdef KEY
01173
01174 exit(2);
01175 #endif
01176 }
01177
01178
01179
01180
01181 void
01182 fatal_error VPARAMS ((const char *msgid, ...))
01183 {
01184 diagnostic_info diagnostic;
01185
01186 VA_OPEN (ap, msgid);
01187 VA_FIXEDARG (ap, const char *, msgid);
01188
01189 diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
01190 DK_FATAL);
01191 report_diagnostic (&diagnostic);
01192 VA_CLOSE (ap);
01193
01194 #ifdef KEY
01195 fnotice (stderr, "GNU front-end compilation terminated.\n");
01196 exit (RC_GCC_INTERNAL_ERROR);
01197 #endif
01198
01199 fnotice (stderr, "compilation terminated.\n");
01200 exit (FATAL_EXIT_CODE);
01201 }
01202
01203 void
01204 internal_error VPARAMS ((const char *msgid, ...))
01205 {
01206 diagnostic_info diagnostic;
01207
01208 VA_OPEN (ap, msgid);
01209 VA_FIXEDARG (ap, const char *, msgid);
01210
01211 if (global_dc->lock)
01212 error_recursion (global_dc);
01213
01214 #ifndef ENABLE_CHECKING
01215 if (errorcount > 0 || sorrycount > 0)
01216 {
01217 #ifdef KEY
01218 fnotice (stderr, "%s:%d: confused by earlier errors, GNU front-end bailing out\n",
01219 input_filename, lineno);
01220 exit (RC_GCC_INTERNAL_ERROR);
01221 #endif
01222
01223 fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
01224 input_filename, lineno);
01225 exit (FATAL_EXIT_CODE);
01226 }
01227 #endif
01228
01229 if (global_dc->internal_error != 0)
01230 (*global_dc->internal_error) (_(msgid), &ap);
01231
01232 diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
01233 DK_ICE);
01234 report_diagnostic (&diagnostic);
01235 VA_CLOSE (ap);
01236
01237 #ifdef KEY
01238 fnotice (stderr, "GNU front-end error.\n");
01239 exit (RC_GCC_INTERNAL_ERROR);
01240 #endif
01241
01242 fnotice (stderr,
01243 "Please submit a full bug report,\n\
01244 with preprocessed source if appropriate.\n\
01245 See %s for instructions.\n", bug_report_url);
01246 exit (FATAL_EXIT_CODE);
01247 }
01248
01249 void
01250 warning_with_file_and_line VPARAMS ((const char *file, int line,
01251 const char *msgid, ...))
01252 {
01253 diagnostic_info diagnostic;
01254
01255 VA_OPEN (ap, msgid);
01256 VA_FIXEDARG (ap, const char *, file);
01257 VA_FIXEDARG (ap, int, line);
01258 VA_FIXEDARG (ap, const char *, msgid);
01259
01260 diagnostic_set_info (&diagnostic, msgid, &ap, file, line, DK_WARNING);
01261 report_diagnostic (&diagnostic);
01262 VA_CLOSE (ap);
01263 }
01264
01265 void
01266 warning_with_decl VPARAMS ((tree decl, const char *msgid, ...))
01267 {
01268 diagnostic_info diagnostic;
01269 VA_OPEN (ap, msgid);
01270 VA_FIXEDARG (ap, tree, decl);
01271 VA_FIXEDARG (ap, const char *, msgid);
01272
01273 diagnostic_set_info (&diagnostic, msgid, &ap,
01274 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
01275 DK_WARNING);
01276 diagnostic_for_decl (&diagnostic, decl);
01277 VA_CLOSE (ap);
01278 }
01279
01280 void
01281 warning VPARAMS ((const char *msgid, ...))
01282 {
01283 diagnostic_info diagnostic;
01284
01285 VA_OPEN (ap, msgid);
01286 VA_FIXEDARG (ap, const char *, msgid);
01287
01288 diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
01289 DK_WARNING);
01290 report_diagnostic (&diagnostic);
01291 VA_CLOSE (ap);
01292 }
01293
01294
01295
01296
01297 void
01298 verbatim VPARAMS ((const char *msgid, ...))
01299 {
01300 text_info text;
01301 VA_OPEN (ap, msgid);
01302 VA_FIXEDARG (ap, const char *, msgid);
01303
01304 text.format_spec = _(msgid);
01305 text.args_ptr = ≈
01306 output_do_verbatim (&global_dc->buffer, &text);
01307 output_buffer_to_stream (&global_dc->buffer);
01308 VA_CLOSE (ap);
01309 }
01310
01311
01312
01313
01314
01315
01316
01317 void
01318 diagnostic_report_diagnostic (context, diagnostic)
01319 diagnostic_context *context;
01320 diagnostic_info *diagnostic;
01321 {
01322 if (context->lock++)
01323 error_recursion (context);
01324
01325 if (diagnostic_count_diagnostic (context, diagnostic->kind))
01326 {
01327 (*diagnostic_starter (context)) (context, diagnostic);
01328 output_format (&context->buffer, &diagnostic->message);
01329 (*diagnostic_finalizer (context)) (context, diagnostic);
01330 output_flush (&context->buffer);
01331 }
01332
01333 --context->lock;
01334 }
01335
01336
01337
01338
01339
01340
01341 static void
01342 error_recursion (context)
01343 diagnostic_context *context;
01344 {
01345 if (context->lock < 3)
01346 output_flush (&context->buffer);
01347
01348 #ifdef KEY
01349 fnotice (stderr, "GNU front-end error.\n");
01350 exit (RC_GCC_INTERNAL_ERROR);
01351 #endif
01352
01353 fnotice (stderr,
01354 "Internal compiler error: Error reporting routines re-entered.\n");
01355 fnotice (stderr,
01356 "Please submit a full bug report,\n\
01357 with preprocessed source if appropriate.\n\
01358 See %s for instructions.\n", bug_report_url);
01359 exit (FATAL_EXIT_CODE);
01360 }
01361
01362
01363
01364
01365
01366
01367 const char *
01368 trim_filename (name)
01369 const char *name;
01370 {
01371 static const char this_file[] = __FILE__;
01372 const char *p = name, *q = this_file;
01373
01374
01375
01376 while (p[0] == '.' && p[1] == '.'
01377 && (p[2] == DIR_SEPARATOR
01378 #ifdef DIR_SEPARATOR_2
01379 || p[2] == DIR_SEPARATOR_2
01380 #endif
01381 ))
01382 p += 3;
01383
01384 while (q[0] == '.' && q[1] == '.'
01385 && (q[2] == DIR_SEPARATOR
01386 #ifdef DIR_SEPARATOR_2
01387 || p[2] == DIR_SEPARATOR_2
01388 #endif
01389 ))
01390 q += 3;
01391
01392
01393 while (*p == *q && *p != 0 && *q != 0)
01394 p++, q++;
01395
01396
01397 while (p > name && p[-1] != DIR_SEPARATOR
01398 #ifdef DIR_SEPARATOR_2
01399 && p[-1] != DIR_SEPARATOR_2
01400 #endif
01401 )
01402 p--;
01403
01404 return p;
01405 }
01406
01407
01408
01409
01410 void
01411 fancy_abort (file, line, function)
01412 const char *file;
01413 int line;
01414 const char *function;
01415 {
01416 internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
01417 }
01418
01419 void
01420 diagnostic_report_current_module (context)
01421 diagnostic_context *context;
01422 {
01423 struct file_stack *p;
01424
01425 if (output_needs_newline (&context->buffer))
01426 {
01427 output_add_newline (&context->buffer);
01428 output_needs_newline (&context->buffer) = false;
01429 }
01430
01431 if (input_file_stack && input_file_stack->next != 0
01432 && diagnostic_last_module_changed (context))
01433 {
01434 for (p = input_file_stack->next; p; p = p->next)
01435 if (p == input_file_stack->next)
01436 output_verbatim (&context->buffer,
01437 "In file included from %s:%d", p->name, p->line);
01438 else
01439 output_verbatim (&context->buffer,
01440 ",\n from %s:%d", p->name, p->line);
01441 output_verbatim (&context->buffer, ":\n");
01442 diagnostic_set_last_module (context);
01443 }
01444 }
01445
01446 static void
01447 default_diagnostic_starter (context, diagnostic)
01448 diagnostic_context *context;
01449 diagnostic_info *diagnostic;
01450 {
01451 diagnostic_report_current_function (context);
01452 output_set_prefix (&context->buffer, diagnostic_build_prefix (diagnostic));
01453 }
01454
01455 static void
01456 default_diagnostic_finalizer (context, diagnostic)
01457 diagnostic_context *context;
01458 diagnostic_info *diagnostic __attribute__((unused));
01459 {
01460 output_destroy_prefix (&context->buffer);
01461 }
01462
01463 void
01464 inform VPARAMS ((const char *msgid, ...))
01465 {
01466 diagnostic_info diagnostic;
01467
01468 VA_OPEN (ap, msgid);
01469 VA_FIXEDARG (ap, const char *, msgid);
01470
01471 diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
01472 DK_NOTE);
01473 report_diagnostic (&diagnostic);
01474 VA_CLOSE (ap);
01475 }
01476
01477 void
01478 warn_deprecated_use (node)
01479 tree node;
01480 {
01481 if (node == 0 || !warn_deprecated_decl)
01482 return;
01483
01484 if (DECL_P (node))
01485 warning ("`%s' is deprecated (declared at %s:%d)",
01486 IDENTIFIER_POINTER (DECL_NAME (node)),
01487 DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node));
01488 else if (TYPE_P (node))
01489 {
01490 const char *what = NULL;
01491 tree decl = TYPE_STUB_DECL (node);
01492
01493 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
01494 what = IDENTIFIER_POINTER (TYPE_NAME (node));
01495 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
01496 && DECL_NAME (TYPE_NAME (node)))
01497 what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node)));
01498
01499 if (what)
01500 {
01501 if (decl)
01502 warning ("`%s' is deprecated (declared at %s:%d)", what,
01503 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
01504 else
01505 warning ("`%s' is deprecated", what);
01506 }
01507 else if (decl)
01508 warning ("type is deprecated (declared at %s:%d)",
01509 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
01510 else
01511 warning ("type is deprecated");
01512 }
01513 }