Commit 59650e48 by Zack Weinberg

diagnostic.c: Reorder functions for clarity...

	* diagnostic.c: Reorder functions for clarity, putting all the
	functions in the "error" family next to each other, and
	likewise all the functions in the "error_with_decl" family.
	Some other routines were moved too.  Add comments.
	(vbuild_message_string): Fold into sole caller.

From-SVN: r66676
parent 95e32f85
2003-05-10 Zack Weinberg <zack@codesourcery.com>
* diagnostic.c: Reorder functions for clarity, putting all the
functions in the "error" family next to each other, and
likewise all the functions in the "error_with_decl" family.
Some other routines were moved too. Add comments.
(vbuild_message_string): Fold into sole caller.
2003-05-11 Ulrich Weigand <uweigand@de.ibm.com> 2003-05-11 Ulrich Weigand <uweigand@de.ibm.com>
* except.c (EH_RETURN_STACKADJ_RTX): Do not define. * except.c (EH_RETURN_STACKADJ_RTX): Do not define.
...@@ -57,10 +66,10 @@ ...@@ -57,10 +66,10 @@
2003-05-10 Richard Earnshaw <rearnsha@arm.com> 2003-05-10 Richard Earnshaw <rearnsha@arm.com>
* arm.md (DOM_CC_X_AND_Y, DOM_CC_NX_OR_Y, DOM_CC_X_OR_Y): New * arm.md (DOM_CC_X_AND_Y, DOM_CC_NX_OR_Y, DOM_CC_X_OR_Y): New
constants. constants.
(ior_scc_scc, and_scc_scc): New insn_and_split patterns. (ior_scc_scc, and_scc_scc): New insn_and_split patterns.
* arm.c (arm_select_dominance_cc_mode): Renamed from * arm.c (arm_select_dominance_cc_mode): Renamed from
select_dominance_cc_mode, no-longer static. Use DOM_CC... constants. select_dominance_cc_mode, no-longer static. Use DOM_CC... constants.
Callers updated. Callers updated.
* arm-protos.h (arm_select_dominance_cc_mode): Add prototype. * arm-protos.h (arm_select_dominance_cc_mode): Add prototype.
...@@ -123,7 +132,7 @@ ...@@ -123,7 +132,7 @@
(if_stmt_file): Remove. (if_stmt_file): Remove.
(if_stmt_line): Likewise. (if_stmt_line): Likewise.
* jump.c: include "diagnostic.h" * jump.c: include "diagnostic.h"
(never_reached_warning): Don't use warning_with_file_and_line. (never_reached_warning): Don't use warning_with_file_and_line.
* Makefile.in (jump.o): Add dependce on diagnostic.h * Makefile.in (jump.o): Add dependce on diagnostic.h
2003-05-09 Alan Modra <amodra@bigpond.net.au> 2003-05-09 Alan Modra <amodra@bigpond.net.au>
...@@ -159,8 +168,8 @@ ...@@ -159,8 +168,8 @@
2003-05-08 Aldy Hernandez <aldyh@redhat.com> 2003-05-08 Aldy Hernandez <aldyh@redhat.com>
* mklibgcc.in: Use mkinstalldirs when installing multilib * mklibgcc.in: Use mkinstalldirs when installing multilib
directories. directories.
2003-05-08 J"orn Rennecke <joern.rennecke@superh.com> 2003-05-08 J"orn Rennecke <joern.rennecke@superh.com>
...@@ -170,7 +179,7 @@ ...@@ -170,7 +179,7 @@
2003-05-08 Gabriel Dos Reis <gdr@integrable-solutions.net> 2003-05-08 Gabriel Dos Reis <gdr@integrable-solutions.net>
* objc/objc-act.c (error_with_ivar): Don't use * objc/objc-act.c (error_with_ivar): Don't use
error_with_file_and_line. error_with_file_and_line.
(warn_with_method): Don't use warning_with_file_and_line. (warn_with_method): Don't use warning_with_file_and_line.
2003-05-08 Gabriel Dos Reis <gdr@integrable-solutions.net> 2003-05-08 Gabriel Dos Reis <gdr@integrable-solutions.net>
...@@ -205,7 +214,7 @@ ...@@ -205,7 +214,7 @@
2003-05-07 David Mosberger <davidm@hpl.hp.com> 2003-05-07 David Mosberger <davidm@hpl.hp.com>
* unwind-libunwind.c (_Unwind_FindEnclosingFunction): New. * unwind-libunwind.c (_Unwind_FindEnclosingFunction): New.
2003-05-07 Richard Henderson <rth@redhat.com> 2003-05-07 Richard Henderson <rth@redhat.com>
...@@ -224,38 +233,38 @@ ...@@ -224,38 +233,38 @@
2003-05-07 David Mosberger <davidm@hpl.hp.com> 2003-05-07 David Mosberger <davidm@hpl.hp.com>
* config/ia64/crtbegin.asm (__do_jv_register_classes): Don't * config/ia64/crtbegin.asm (__do_jv_register_classes): Don't
forget to preserve gp. forget to preserve gp.
* config/ia64/crtend.asm (__do_global_ctors_au): Ditto. * config/ia64/crtend.asm (__do_global_ctors_au): Ditto.
* config/ia64/crtbegin.asm (__do_jv_register_classes): Add missing * config/ia64/crtbegin.asm (__do_jv_register_classes): Add missing
.prologue directive. .prologue directive.
Use .skip instead of data8 for .bss section to make Intel Use .skip instead of data8 for .bss section to make Intel
Assembler (ias) happy. Minor whitespace fixups. Make "nop 0" Assembler (ias) happy. Minor whitespace fixups. Make "nop 0"
explicit in the .mib bundles and remove the unnecessary stop explicit in the .mib bundles and remove the unnecessary stop
bits. Replace local labels with normal labels, to make ias bits. Replace local labels with normal labels, to make ias
happy. Don't register __do_global_ctors_aux here, do it in happy. Don't register __do_global_ctors_aux here, do it in
crtend.asm instead. crtend.asm instead.
* config/ia64/crtend.asm [HAVE_INIT_FINI_ARRAY]: Register * config/ia64/crtend.asm [HAVE_INIT_FINI_ARRAY]: Register
__do_global_ctors_aux in .init_array section instead of __do_global_ctors_aux in .init_array section instead of
declaring it as a hidden global. Replace local labels with declaring it as a hidden global. Replace local labels with
ordinary labels to make ias happy. ordinary labels to make ias happy.
2003-05-07 Richard Henderson <rth@redhat.com> 2003-05-07 Richard Henderson <rth@redhat.com>
PR c++/10570 PR c++/10570
* except.c: Revert 04-01 and 04-02 forced-unwind changes. * except.c: Revert 04-01 and 04-02 forced-unwind changes.
* flags.h, toplev.c, doc/invoke.texi: Likewise. * flags.h, toplev.c, doc/invoke.texi: Likewise.
* unwind-dw2.c (_Unwind_GetCFA): Fix ptr->int conversion warning. * unwind-dw2.c (_Unwind_GetCFA): Fix ptr->int conversion warning.
* unwind.inc (_Unwind_DeleteException): Check for null * unwind.inc (_Unwind_DeleteException): Check for null
exception_cleanup. exception_cleanup.
* unwind-sjlj.c (_Unwind_SjLj_Resume_or_Rethrow): New. * unwind-sjlj.c (_Unwind_SjLj_Resume_or_Rethrow): New.
* unwind.inc (_Unwind_Resume_or_Rethrow): New. * unwind.inc (_Unwind_Resume_or_Rethrow): New.
* unwind.h: Declare them. * unwind.h: Declare them.
* libgcc-std.ver (GCC_3.3): Export them. * libgcc-std.ver (GCC_3.3): Export them.
2003-05-07 Richard Henderson <rth@redhat.com> 2003-05-07 Richard Henderson <rth@redhat.com>
......
...@@ -51,8 +51,6 @@ static void output_buffer_to_stream PARAMS ((output_buffer *)); ...@@ -51,8 +51,6 @@ static void output_buffer_to_stream PARAMS ((output_buffer *));
static void output_format PARAMS ((output_buffer *, text_info *)); static void output_format PARAMS ((output_buffer *, text_info *));
static void output_indent PARAMS ((output_buffer *)); static void output_indent PARAMS ((output_buffer *));
static char *vbuild_message_string PARAMS ((const char *, va_list))
ATTRIBUTE_PRINTF (1, 0);
static char *build_message_string PARAMS ((const char *, ...)) static char *build_message_string PARAMS ((const char *, ...))
ATTRIBUTE_PRINTF_1; ATTRIBUTE_PRINTF_1;
static void format_with_decl PARAMS ((output_buffer *, text_info *, tree)); static void format_with_decl PARAMS ((output_buffer *, text_info *, tree));
...@@ -388,6 +386,9 @@ output_append (buffer, start, end) ...@@ -388,6 +386,9 @@ output_append (buffer, start, end)
output_append_r (buffer, start, end - start); output_append_r (buffer, start, end - start);
} }
/* Insert enough spaces into BUFFER to bring the column position to
the current indentation level, assuming that a newline has just
been written to the buffer. */
static void static void
output_indent (buffer) output_indent (buffer)
output_buffer *buffer; output_buffer *buffer;
...@@ -616,19 +617,8 @@ output_format (buffer, text) ...@@ -616,19 +617,8 @@ output_format (buffer, text)
} }
} }
static char * /* Return a malloc'd string containing MSG formatted a la printf. The
vbuild_message_string (msg, ap) caller is responsible for freeing the memory. */
const char *msg;
va_list ap;
{
char *str;
vasprintf (&str, msg, ap);
return str;
}
/* Return a malloc'd string containing MSG formatted a la
printf. The caller is responsible for freeing the memory. */
static char * static char *
build_message_string VPARAMS ((const char *msg, ...)) build_message_string VPARAMS ((const char *msg, ...))
{ {
...@@ -637,7 +627,7 @@ build_message_string VPARAMS ((const char *msg, ...)) ...@@ -637,7 +627,7 @@ build_message_string VPARAMS ((const char *msg, ...))
VA_OPEN (ap, msg); VA_OPEN (ap, msg);
VA_FIXEDARG (ap, const char *, msg); VA_FIXEDARG (ap, const char *, msg);
str = vbuild_message_string (msg, ap); vasprintf (&str, msg, ap);
VA_CLOSE (ap); VA_CLOSE (ap);
...@@ -851,29 +841,6 @@ diagnostic_build_prefix (diagnostic) ...@@ -851,29 +841,6 @@ diagnostic_build_prefix (diagnostic)
_(diagnostic_kind_text[diagnostic->kind])); _(diagnostic_kind_text[diagnostic->kind]));
} }
/* Report a diagnostic MESSAGE at the declaration DECL.
MSG is a format string which uses %s to substitute the declaration
name; subsequent substitutions are a la output_format. */
static void
diagnostic_for_decl (diagnostic, decl)
diagnostic_info *diagnostic;
tree decl;
{
if (global_dc->lock++)
error_recursion (global_dc);
if (diagnostic_count_diagnostic (global_dc, diagnostic->kind))
{
diagnostic_report_current_function (global_dc);
output_set_prefix
(&global_dc->buffer, diagnostic_build_prefix (diagnostic));
format_with_decl (&global_dc->buffer, &diagnostic->message, decl);
output_flush (&global_dc->buffer);
output_destroy_prefix (&global_dc->buffer);
}
global_dc->lock--;
}
void void
diagnostic_flush_buffer (context) diagnostic_flush_buffer (context)
diagnostic_context *context; diagnostic_context *context;
...@@ -923,96 +890,6 @@ diagnostic_count_diagnostic (context, kind) ...@@ -923,96 +890,6 @@ diagnostic_count_diagnostic (context, kind)
return true; return true;
} }
/* Print a diagnostic MSGID on FILE. This is just fprintf, except it
runs its second argument through gettext. */
void
fnotice VPARAMS ((FILE *file, const char *msgid, ...))
{
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, FILE *, file);
VA_FIXEDARG (ap, const char *, msgid);
vfprintf (file, _(msgid), ap);
VA_CLOSE (ap);
}
/* Print a fatal I/O error message. Argument are like printf.
Also include a system error message based on `errno'. */
void
fatal_io_error VPARAMS ((const char *msgid, ...))
{
text_info text;
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, const char *, msgid);
text.format_spec = _(msgid);
text.args_ptr = &ap;
output_printf (&global_dc->buffer, "%s: %s: ", progname, xstrerror (errno));
output_format (&global_dc->buffer, &text);
output_flush (&global_dc->buffer);
VA_CLOSE (ap);
exit (FATAL_EXIT_CODE);
}
/* Issue a pedantic warning MSGID. */
void
pedwarn VPARAMS ((const char *msgid, ...))
{
diagnostic_info diagnostic;
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, const char *, msgid);
diagnostic_set_info (&diagnostic, _(msgid), &ap, input_filename, input_line,
pedantic_error_kind ());
report_diagnostic (&diagnostic);
VA_CLOSE (ap);
}
/* Issue a pedantic warning about DECL. */
void
pedwarn_with_decl VPARAMS ((tree decl, const char *msgid, ...))
{
diagnostic_info diagnostic;
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, tree, decl);
VA_FIXEDARG (ap, const char *, msgid);
diagnostic_set_info (&diagnostic, _(msgid), &ap,
DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
pedantic_error_kind ());
/* We don't want -pedantic-errors to cause the compilation to fail from
"errors" in system header files. Sometimes fixincludes can't fix what's
broken (eg: unsigned char bitfields - fixing it may change the alignment
which will cause programs to mysteriously fail because the C library
or kernel uses the original layout). There's no point in issuing a
warning either, it's just unnecessary noise. */
if (!DECL_IN_SYSTEM_HEADER (decl))
diagnostic_for_decl (&diagnostic, decl);
VA_CLOSE (ap);
}
/* Just apologize with MSGID. */
void
sorry VPARAMS ((const char *msgid, ...))
{
diagnostic_info diagnostic;
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, const char *, msgid);
++sorrycount;
diagnostic_set_info (&diagnostic, _(msgid), &ap,
input_filename, input_line, DK_SORRY);
output_set_prefix
(&global_dc->buffer, diagnostic_build_prefix (&diagnostic));
output_format (&global_dc->buffer, &diagnostic.message);
output_flush (&global_dc->buffer);
VA_CLOSE (ap);
}
/* Called when the start of a function definition is parsed, /* Called when the start of a function definition is parsed,
this function prints on stderr the name of the function. */ this function prints on stderr the name of the function. */
void void
...@@ -1080,107 +957,183 @@ diagnostic_report_current_function (context) ...@@ -1080,107 +957,183 @@ diagnostic_report_current_function (context)
} }
void void
error_with_decl VPARAMS ((tree decl, const char *msgid, ...)) diagnostic_report_current_module (context)
diagnostic_context *context;
{ {
diagnostic_info diagnostic; struct file_stack *p;
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, tree, decl);
VA_FIXEDARG (ap, const char *, msgid);
diagnostic_set_info (&diagnostic, msgid, &ap,
DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
DK_ERROR);
diagnostic_for_decl (&diagnostic, decl);
VA_CLOSE (ap);
}
if (output_needs_newline (&context->buffer))
{
output_add_newline (&context->buffer);
output_needs_newline (&context->buffer) = false;
}
/* Report an error message. The arguments are like that of printf. */ if (input_file_stack && input_file_stack->next != 0
&& diagnostic_last_module_changed (context))
{
for (p = input_file_stack->next; p; p = p->next)
if (p == input_file_stack->next)
output_verbatim (&context->buffer,
"In file included from %s:%d",
p->location.file, p->location.line);
else
output_verbatim (&context->buffer,
",\n from %s:%d",
p->location.file, p->location.line);
output_verbatim (&context->buffer, ":\n");
diagnostic_set_last_module (context);
}
}
void static void
error VPARAMS ((const char *msgid, ...)) default_diagnostic_starter (context, diagnostic)
diagnostic_context *context;
diagnostic_info *diagnostic;
{ {
diagnostic_info diagnostic; diagnostic_report_current_function (context);
output_set_prefix (&context->buffer, diagnostic_build_prefix (diagnostic));
VA_OPEN (ap, msgid); }
VA_FIXEDARG (ap, const char *, msgid);
diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line, static void
DK_ERROR); default_diagnostic_finalizer (context, diagnostic)
report_diagnostic (&diagnostic); diagnostic_context *context;
VA_CLOSE (ap); diagnostic_info *diagnostic __attribute__((unused));
{
output_destroy_prefix (&context->buffer);
} }
/* Likewise, except that the compilation is terminated after printing the /* Report a diagnostic message (an error or a warning) as specified by
error message. */ DC. This function is *the* subroutine in terms of which front-ends
should implement their specific diagnostic handling modules. The
front-end independent format specifiers are exactly those described
in the documentation of output_format. */
void void
fatal_error VPARAMS ((const char *msgid, ...)) diagnostic_report_diagnostic (context, diagnostic)
diagnostic_context *context;
diagnostic_info *diagnostic;
{ {
diagnostic_info diagnostic; if (context->lock++)
error_recursion (context);
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, const char *, msgid);
diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line, if (diagnostic_count_diagnostic (context, diagnostic->kind))
DK_FATAL); {
report_diagnostic (&diagnostic); (*diagnostic_starter (context)) (context, diagnostic);
VA_CLOSE (ap); output_format (&context->buffer, &diagnostic->message);
(*diagnostic_finalizer (context)) (context, diagnostic);
output_flush (&context->buffer);
}
fnotice (stderr, "compilation terminated.\n"); if (context->abort_on_error && diagnostic->kind <= DK_ERROR)
exit (FATAL_EXIT_CODE); real_abort();
--context->lock;
} }
void /* Report a diagnostic MESSAGE at the declaration DECL.
internal_error VPARAMS ((const char *msgid, ...)) MSG is a format string which uses %s to substitute the declaration
name; subsequent substitutions are a la output_format. */
static void
diagnostic_for_decl (diagnostic, decl)
diagnostic_info *diagnostic;
tree decl;
{ {
diagnostic_info diagnostic; if (global_dc->lock++)
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, const char *, msgid);
if (global_dc->lock)
error_recursion (global_dc); error_recursion (global_dc);
#ifndef ENABLE_CHECKING if (diagnostic_count_diagnostic (global_dc, diagnostic->kind))
if (errorcount > 0 || sorrycount > 0)
{ {
fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n", diagnostic_report_current_function (global_dc);
input_filename, input_line); output_set_prefix
exit (FATAL_EXIT_CODE); (&global_dc->buffer, diagnostic_build_prefix (diagnostic));
format_with_decl (&global_dc->buffer, &diagnostic->message, decl);
output_flush (&global_dc->buffer);
output_destroy_prefix (&global_dc->buffer);
} }
#endif global_dc->lock--;
}
if (global_dc->internal_error != 0) /* Given a partial pathname as input, return another pathname that
(*global_dc->internal_error) (_(msgid), &ap); shares no directory elements with the pathname of __FILE__. This
is used by fancy_abort() to print `Internal compiler error in expr.c'
instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */
diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line, const char *
DK_ICE); trim_filename (name)
report_diagnostic (&diagnostic); const char *name;
VA_CLOSE (ap); {
static const char this_file[] = __FILE__;
const char *p = name, *q = this_file;
fnotice (stderr, /* First skip any "../" in each filename. This allows us to give a proper
"Please submit a full bug report,\n\ reference to a file in a subdirectory. */
with preprocessed source if appropriate.\n\ while (p[0] == '.' && p[1] == '.'
See %s for instructions.\n", bug_report_url); && (p[2] == DIR_SEPARATOR
exit (FATAL_EXIT_CODE); #ifdef DIR_SEPARATOR_2
|| p[2] == DIR_SEPARATOR_2
#endif
))
p += 3;
while (q[0] == '.' && q[1] == '.'
&& (q[2] == DIR_SEPARATOR
#ifdef DIR_SEPARATOR_2
|| p[2] == DIR_SEPARATOR_2
#endif
))
q += 3;
/* Now skip any parts the two filenames have in common. */
while (*p == *q && *p != 0 && *q != 0)
p++, q++;
/* Now go backwards until the previous directory separator. */
while (p > name && p[-1] != DIR_SEPARATOR
#ifdef DIR_SEPARATOR_2
&& p[-1] != DIR_SEPARATOR_2
#endif
)
p--;
return p;
} }
/* Standard error reporting routines in increasing order of severity.
All of these take arguments like printf. */
/* Text to be emitted verbatim to the error message stream; this
produces no prefix and disables line-wrapping. Use rarely. */
void void
warning_with_decl VPARAMS ((tree decl, const char *msgid, ...)) verbatim VPARAMS ((const char *msgid, ...))
{
text_info text;
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, const char *, msgid);
text.format_spec = _(msgid);
text.args_ptr = &ap;
output_do_verbatim (&global_dc->buffer, &text);
output_buffer_to_stream (&global_dc->buffer);
VA_CLOSE (ap);
}
/* An informative note. Use this for additional details on an error
message. */
void
inform VPARAMS ((const char *msgid, ...))
{ {
diagnostic_info diagnostic; diagnostic_info diagnostic;
VA_OPEN (ap, msgid); VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, tree, decl);
VA_FIXEDARG (ap, const char *, msgid); VA_FIXEDARG (ap, const char *, msgid);
diagnostic_set_info (&diagnostic, msgid, &ap, diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line,
DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl), DK_NOTE);
DK_WARNING); report_diagnostic (&diagnostic);
diagnostic_for_decl (&diagnostic, decl);
VA_CLOSE (ap); VA_CLOSE (ap);
} }
/* A warning. Use this for code which is correct according to the
relevant language specification but is likely to be buggy anyway. */
void void
warning VPARAMS ((const char *msgid, ...)) warning VPARAMS ((const char *msgid, ...))
{ {
...@@ -1195,188 +1148,198 @@ warning VPARAMS ((const char *msgid, ...)) ...@@ -1195,188 +1148,198 @@ warning VPARAMS ((const char *msgid, ...))
VA_CLOSE (ap); VA_CLOSE (ap);
} }
/* A "pedantic" warning. Use this for code which triggers a
diagnostic which is required by the relevant language
specification, but which is considered unhelpful (i.e. there isn't
anything *really* wrong with the construct in the language as she
is spoke). It is a normal warning unless -pedantic-errors is
applied, which turns it into an error. Note that pedwarn-s still
happen if -pedantic is not given; you must write
"if (pedantic) pedwarn (...)" to get a warning enabled only under
-pedantic. All such warnings should, however, use pedwarn. */
void
pedwarn VPARAMS ((const char *msgid, ...))
{
diagnostic_info diagnostic;
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, const char *, msgid);
/* Same as above but use diagnostic_buffer. */ diagnostic_set_info (&diagnostic, _(msgid), &ap, input_filename, input_line,
pedantic_error_kind ());
report_diagnostic (&diagnostic);
VA_CLOSE (ap);
}
/* A hard error: the code is definitely ill-formed, and an object file
will not be produced. */
void void
verbatim VPARAMS ((const char *msgid, ...)) error VPARAMS ((const char *msgid, ...))
{ {
text_info text; diagnostic_info diagnostic;
VA_OPEN (ap, msgid); VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, const char *, msgid); VA_FIXEDARG (ap, const char *, msgid);
text.format_spec = _(msgid); diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line,
text.args_ptr = &ap; DK_ERROR);
output_do_verbatim (&global_dc->buffer, &text); report_diagnostic (&diagnostic);
output_buffer_to_stream (&global_dc->buffer);
VA_CLOSE (ap); VA_CLOSE (ap);
} }
/* Report a diagnostic message (an error or a warning) as specified by /* "Sorry, not implemented." Use for a language feature which is
DC. This function is *the* subroutine in terms of which front-ends required by the relevant specification but not implemented by GCC.
should implement their specific diagnostic handling modules. The An object file will not be produced. */
front-end independent format specifiers are exactly those described
in the documentation of output_format. */
void void
diagnostic_report_diagnostic (context, diagnostic) sorry VPARAMS ((const char *msgid, ...))
diagnostic_context *context;
diagnostic_info *diagnostic;
{ {
if (context->lock++) diagnostic_info diagnostic;
error_recursion (context);
if (diagnostic_count_diagnostic (context, diagnostic->kind)) VA_OPEN (ap, msgid);
{ VA_FIXEDARG (ap, const char *, msgid);
(*diagnostic_starter (context)) (context, diagnostic);
output_format (&context->buffer, &diagnostic->message);
(*diagnostic_finalizer (context)) (context, diagnostic);
output_flush (&context->buffer);
}
if (context->abort_on_error && diagnostic->kind <= DK_ERROR) ++sorrycount;
real_abort(); diagnostic_set_info (&diagnostic, _(msgid), &ap,
--context->lock; input_filename, input_line, DK_SORRY);
}
/* Inform the user that an error occurred while trying to report some output_set_prefix
other error. This indicates catastrophic internal inconsistencies, (&global_dc->buffer, diagnostic_build_prefix (&diagnostic));
so give up now. But do try to flush out the previous error. output_format (&global_dc->buffer, &diagnostic.message);
This mustn't use internal_error, that will cause infinite recursion. */ output_flush (&global_dc->buffer);
VA_CLOSE (ap);
}
static void /* An error which is severe enough that we make no attempt to
error_recursion (context) continue. Do not use this for internal consistency checks; that's
diagnostic_context *context; internal_error. Use of this function should be rare. */
void
fatal_error VPARAMS ((const char *msgid, ...))
{ {
if (context->lock < 3) diagnostic_info diagnostic;
output_flush (&context->buffer);
fnotice (stderr, VA_OPEN (ap, msgid);
"Internal compiler error: Error reporting routines re-entered.\n"); VA_FIXEDARG (ap, const char *, msgid);
fnotice (stderr,
"Please submit a full bug report,\n\ diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line,
with preprocessed source if appropriate.\n\ DK_FATAL);
See %s for instructions.\n", bug_report_url); report_diagnostic (&diagnostic);
VA_CLOSE (ap);
fnotice (stderr, "compilation terminated.\n");
exit (FATAL_EXIT_CODE); exit (FATAL_EXIT_CODE);
} }
/* Given a partial pathname as input, return another pathname that /* An internal consistency check has failed. We make no attempt to
shares no directory elements with the pathname of __FILE__. This continue. Note that unless there is debugging value to be had from
is used by fancy_abort() to print `Internal compiler error in expr.c' a more specific message, or some other good reason, you should use
instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */ abort () instead of calling this function directly. */
void
const char * internal_error VPARAMS ((const char *msgid, ...))
trim_filename (name)
const char *name;
{ {
static const char this_file[] = __FILE__; diagnostic_info diagnostic;
const char *p = name, *q = this_file;
/* First skip any "../" in each filename. This allows us to give a proper VA_OPEN (ap, msgid);
reference to a file in a subdirectory. */ VA_FIXEDARG (ap, const char *, msgid);
while (p[0] == '.' && p[1] == '.'
&& (p[2] == DIR_SEPARATOR
#ifdef DIR_SEPARATOR_2
|| p[2] == DIR_SEPARATOR_2
#endif
))
p += 3;
while (q[0] == '.' && q[1] == '.' if (global_dc->lock)
&& (q[2] == DIR_SEPARATOR error_recursion (global_dc);
#ifdef DIR_SEPARATOR_2
|| p[2] == DIR_SEPARATOR_2 #ifndef ENABLE_CHECKING
if (errorcount > 0 || sorrycount > 0)
{
fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
input_filename, input_line);
exit (FATAL_EXIT_CODE);
}
#endif #endif
))
q += 3;
/* Now skip any parts the two filenames have in common. */ if (global_dc->internal_error != 0)
while (*p == *q && *p != 0 && *q != 0) (*global_dc->internal_error) (_(msgid), &ap);
p++, q++;
/* Now go backwards until the previous directory separator. */ diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line,
while (p > name && p[-1] != DIR_SEPARATOR DK_ICE);
#ifdef DIR_SEPARATOR_2 report_diagnostic (&diagnostic);
&& p[-1] != DIR_SEPARATOR_2 VA_CLOSE (ap);
#endif
)
p--;
return p; fnotice (stderr,
"Please submit a full bug report,\n\
with preprocessed source if appropriate.\n\
See %s for instructions.\n", bug_report_url);
exit (FATAL_EXIT_CODE);
} }
/* Report an internal compiler error in a friendly manner and without /* Variants of some of the above, which make reference to a particular
dumping core. */ DECL node. These are deprecated. */
void void
fancy_abort (file, line, function) warning_with_decl VPARAMS ((tree decl, const char *msgid, ...))
const char *file;
int line;
const char *function;
{ {
internal_error ("in %s, at %s:%d", function, trim_filename (file), line); diagnostic_info diagnostic;
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, tree, decl);
VA_FIXEDARG (ap, const char *, msgid);
diagnostic_set_info (&diagnostic, msgid, &ap,
DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
DK_WARNING);
diagnostic_for_decl (&diagnostic, decl);
VA_CLOSE (ap);
} }
void void
diagnostic_report_current_module (context) pedwarn_with_decl VPARAMS ((tree decl, const char *msgid, ...))
diagnostic_context *context;
{ {
struct file_stack *p; diagnostic_info diagnostic;
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, tree, decl);
VA_FIXEDARG (ap, const char *, msgid);
if (output_needs_newline (&context->buffer)) diagnostic_set_info (&diagnostic, _(msgid), &ap,
{ DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
output_add_newline (&context->buffer); pedantic_error_kind ());
output_needs_newline (&context->buffer) = false;
}
if (input_file_stack && input_file_stack->next != 0 /* We don't want -pedantic-errors to cause the compilation to fail from
&& diagnostic_last_module_changed (context)) "errors" in system header files. Sometimes fixincludes can't fix what's
{ broken (eg: unsigned char bitfields - fixing it may change the alignment
for (p = input_file_stack->next; p; p = p->next) which will cause programs to mysteriously fail because the C library
if (p == input_file_stack->next) or kernel uses the original layout). There's no point in issuing a
output_verbatim (&context->buffer, warning either, it's just unnecessary noise. */
"In file included from %s:%d", if (!DECL_IN_SYSTEM_HEADER (decl))
p->location.file, p->location.line); diagnostic_for_decl (&diagnostic, decl);
else VA_CLOSE (ap);
output_verbatim (&context->buffer,
",\n from %s:%d",
p->location.file, p->location.line);
output_verbatim (&context->buffer, ":\n");
diagnostic_set_last_module (context);
}
} }
static void void
default_diagnostic_starter (context, diagnostic) error_with_decl VPARAMS ((tree decl, const char *msgid, ...))
diagnostic_context *context;
diagnostic_info *diagnostic;
{ {
diagnostic_report_current_function (context); diagnostic_info diagnostic;
output_set_prefix (&context->buffer, diagnostic_build_prefix (diagnostic)); VA_OPEN (ap, msgid);
} VA_FIXEDARG (ap, tree, decl);
VA_FIXEDARG (ap, const char *, msgid);
static void diagnostic_set_info (&diagnostic, msgid, &ap,
default_diagnostic_finalizer (context, diagnostic) DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
diagnostic_context *context; DK_ERROR);
diagnostic_info *diagnostic __attribute__((unused)); diagnostic_for_decl (&diagnostic, decl);
{ VA_CLOSE (ap);
output_destroy_prefix (&context->buffer);
} }
/* Special case error functions. Most are implemented in terms of the
above, or should be. */
/* Print a diagnostic MSGID on FILE. This is just fprintf, except it
runs its second argument through gettext. */
void void
inform VPARAMS ((const char *msgid, ...)) fnotice VPARAMS ((FILE *file, const char *msgid, ...))
{ {
diagnostic_info diagnostic;
VA_OPEN (ap, msgid); VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, FILE *, file);
VA_FIXEDARG (ap, const char *, msgid); VA_FIXEDARG (ap, const char *, msgid);
diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line, vfprintf (file, _(msgid), ap);
DK_NOTE);
report_diagnostic (&diagnostic);
VA_CLOSE (ap); VA_CLOSE (ap);
} }
/* Warn about a use of an identifier which was marked deprecated. */
void void
warn_deprecated_use (node) warn_deprecated_use (node)
tree node; tree node;
...@@ -1415,6 +1378,58 @@ warn_deprecated_use (node) ...@@ -1415,6 +1378,58 @@ warn_deprecated_use (node)
} }
} }
/* Print a fatal I/O error message. Argument are like printf.
Also include a system error message based on `errno'. */
void
fatal_io_error VPARAMS ((const char *msgid, ...))
{
text_info text;
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, const char *, msgid);
text.format_spec = _(msgid);
text.args_ptr = &ap;
output_printf (&global_dc->buffer, "%s: %s: ", progname, xstrerror (errno));
output_format (&global_dc->buffer, &text);
output_flush (&global_dc->buffer);
VA_CLOSE (ap);
exit (FATAL_EXIT_CODE);
}
/* Inform the user that an error occurred while trying to report some
other error. This indicates catastrophic internal inconsistencies,
so give up now. But do try to flush out the previous error.
This mustn't use internal_error, that will cause infinite recursion. */
static void
error_recursion (context)
diagnostic_context *context;
{
if (context->lock < 3)
output_flush (&context->buffer);
fnotice (stderr,
"Internal compiler error: Error reporting routines re-entered.\n");
fnotice (stderr,
"Please submit a full bug report,\n\
with preprocessed source if appropriate.\n\
See %s for instructions.\n", bug_report_url);
exit (FATAL_EXIT_CODE);
}
/* Report an internal compiler error in a friendly manner. This is
the function that gets called upon use of abort() in the source
code generally, thanks to a special macro. */
void
fancy_abort (file, line, function)
const char *file;
int line;
const char *function;
{
internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
}
/* Really call the system 'abort'. This has to go right at the end of /* Really call the system 'abort'. This has to go right at the end of
this file, so that there are no functions after it that call abort this file, so that there are no functions after it that call abort
and get the system abort instead of our macro. */ and get the system abort instead of our macro. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment