This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[4.5] Make cpplib use compiler's diagnostic.c


This patch, intended for GCC 4.5, makes cpplib use the compiler's
diagnostic.c diagnostic infrastructure.

The general approach is that all diagnostic calls from the
preprocessor go through a single callback, which is passed a location
and may choose to use the compiler's location instead if that is
appropriate.  (That is done for C++ calling back into cpplib after
lexing up front, when the front end's location is accurate and the
preprocessor's isn't.  This is the case for which callbacks were
already used before this patch, in order to get the right diagnostic
locations to fix PR 17964.)

The compiler's diagnostic infrastructure is responsible for everything
to do with choosing whether to emit a diagnostic at all and whether a
particular diagnostic is an error, so several preprocessor options
relating to this are removed from cpplib.  The compiler is also now
solely responsible for counting errors; cpplib no longer maintains a
count, and the code in cpplib that checked for errors before deciding
whether to write dependency output no longer does so (instead, the
compiler has the same check, but this time based on whether there were
any errors at all, whether compiler or preprocessor).

There were four cpplib clients in the tree: common C/C++ code, the
Fortran front end, fix-header.c (part of fixproto, not fixincludes)
and makedepend.c (a program built by cpplib but not used for
anything).  The first two are updated by this patch for the changes to
the cpplib interface.  The third is deliberately not updated: fixproto
is deprecated in 4.4 and scheduled for removal for 4.5 (as are all
targets with it enabled) and I intend to do that removal before
putting this patch in trunk.  The fourth is removed by this patch as
unused experimental code; if someone has an actual use for it, it can
be added back and updated at the point where the use for it is added.

Using the compiler's diagnostic infrastructure of course means
settings such as -fshow-column are consistent with the compiler.  Thus
one testcase needs an explicit -fshow-column.  I believe this is the
right thing to do, and if someone wishes to change the -fshow-column
default for the compiler they can do so independently of this patch.

In order to get #include stacks from diagnostic.c when generating
preprocessed output (-E), the file_change callback used for
preprocessed output needs to set input_location.

The override_column changes to diagnostic.c are explained by the
following text in a comment on the removed function _cpp_begin_message
(I didn't find a good place to move the comment): "The column number
can be specified either using COLUMN or (if COLUMN==0) extracting
SOURCE_COLUMN from SRC_LOC.  (This may seem redundant, but is useful
when pre-scanning (cleaning) a line, when we haven't yet verified
whether the current line_map has a big enough max_column_hint.)".  If
the line map code is changed so that this issue no longer applies, I
expect it should be possible to remove the column argument from
cpp_error_with_line and other associated functions and remove the
override_column support.

Always determining the system-header property based on the location of
the diagnostic runs into an issue with the warning about the previous
definition of a macro being redefined.  If the redefinition was in a
system header (so the warning was suppressed) but the previous
definition was not you could get only the warning about the previous
definition (this affected one libstdc++ test, with the previous
definition reported as on the command line).  (cpplib used its notion
of the current location being in a system header rather than the
location at which the diagnostic is being reported.)  This patch
changes that message to a "note" rather than a pedwarn, as with such
cases in the compiler, and arranges for the callbacks to check whether
diagnostics would be reported at input_location.  This isn't ideal,
but an ideal approach might require further changes to the diagnostic
infrastructure to be able to say "output this note iff the previous
warning was output, without regard to the location assigned to the
note".

One potential use for making cpplib use the compiler's diagnostic
infrastructure would be the ability to control the warnings (with
pragmas, -Werror=option etc.) the same way as with those from the
compiler.  To implement this on top of this patch, cpp_error and
cpp_error_with_line could be changed to take a cpplib-specific
identifier for the diagnostic or group of diagnostics; the callbacks
could then convert those identifiers to ones suitable for
diagnostic.c.

Another potential use, motivating this patch, is allowing for fatal
errors, and in particular making missing #included headers fatal as
discussed in PR 15638.  I plan to implement this as a followup (once
this patch is in trunk).

c_cpp_error is declared in c-tree.h to get ATTRIBUTE_GCC_CDIAG.  I'm
sure this could be fixed so it is declared in c-common code but I'd
rather not try to mix complicated header cleanups with this patch.

linemap_print_containing_files is unused after this patch.  I didn't
remove it since I don't know how likely it is there might be other
uses for it.

Bootstrapped with no regressions on i686-pc-linux-gnu.  Are the C++,
Fortran and diagnostic.[ch] parts OK for trunk after 4.4 has branched
and fixproto has been removed?

gcc:
2009-02-11  Joseph Myers  <joseph@codesourcery.com>

	* Makefile.in (c-opts.o): Depend on c-tree.h.
	* c-common.c: Move down include of diagnostic.h.
	(done_lexing, c_cpp_error): New.
	* c-common.h (done_lexing): Declare.
	* c-decl.c (c_write_global_declarations): Don't check cpp_errors
	(parse_in).
	* c-opts.c: Include c-tree.h.
	(c_common_init_options): Set preprocessor error callback.
	(c_common_handle_option): Do not set preprocessor
	inhibit_warnings, warnings_are_errors, warn_system_headers,
	pedantic_errors or inhibit_warnings flags.
	(c_common_post_options): Do not check cpp_errors (parse_in).
	(c_common_finish): Do not output dependencies if there were
	errors.  Do not check return value of cpp_finish.
	* c-ppoutput.c (pp_file_change): Set input_location.
	* c-tree.h (c_cpp_error): Declare.
	* diagnostic.c (diagnostic_set_info_translated): Also initialize
	override_column.
	(diagnostic_build_prefix): Check override_column.
	* diagnostic.h (diagnostic_info): Add override_column field.
	(diagnostic_override_column): Define.

gcc/cp:
2009-02-11  Joseph Myers  <joseph@codesourcery.com>

	* cp-tree.h (cp_cpp_error): Remove.
	* error.c (cp_cpp_error): Remove.
	* parser.c (cp_lexer_new_main): Set done_lexing instead of
	client_diagnostic and error callback.

gcc/fortran:
2009-02-11  Joseph Myers  <joseph@codesourcery.com>

	* cpp.c (cb_cpp_error): New.
	(gfc_cpp_post_options): Don't set cpp_option->inhibit_warnings.
	Don't check cpp_errors (cpp_in).
	(gfc_cpp_init_0): Set cb->error.

gcc/testsuite:
2009-02-11  Joseph Myers  <joseph@codesourcery.com>

	* gcc.dg/builtin-redefine.c, gcc.dg/cpp/redef2.c,
	gcc.dg/cpp/redef3.c, gcc.dg/cpp/trad/redef2.c: Use dg-message
	instead of dg-warning for "previous definition" messages.
	* gcc.dg/cpp/Wvariadic-1.c, gcc.dg/cpp/Wvariadic-3.c: Expect
	"warnings being treated as errors" message.
	* gcc.dg/fltconst-1.c: Use -fshow-column.

cpplib:
2009-02-11  Joseph Myers  <joseph@codesourcery.com>

	* makedepend.c: Remove.
	* Makefile.in (makedepend_OBJS, makedepend$(EXEEXT)): Remove.
	(all, clean, TAGS_SOURCES, include): Remove makedepend handling.
	* directives.c (cpp_errors): Remove.
	* errors.c (print_location, _cpp_begin_message, v_message):
	Remove.
	(cpp_error, cpp_error_with_line): Always use error callback.
	* include/cpplib.h (cpp_options): Remove pedantic_errors,
	inhibit_warnings, warn_system_headers, inhibit_errors,
	warnings_are_errors, client_diagnostic.
	(cpp_callbacks): Add extra arguments to error callback.
	(cpp_finish): Return void.
	(cpp_destroy): Remove inaccurate comment about return value.
	(cpp_errors, CPP_DL_EXTRACT, CPP_DL_WARNING_P): Remove.
	(CPP_DL_NOTE): Define.
	* init.c (cpp_finish): Do not check for or return number of
	errors.
	* internal.h (cpp_reader): Remove errors field.
	* macro.c (_cpp_create_definition): Use CPP_DL_NOTE for message
	about previous definition.

Index: gcc/diagnostic.c
===================================================================
--- gcc/diagnostic.c	(revision 144036)
+++ gcc/diagnostic.c	(working copy)
@@ -126,6 +126,7 @@ diagnostic_set_info_translated (diagnost
   diagnostic->message.args_ptr = args;
   diagnostic->message.format_spec = msg;
   diagnostic->location = location;
+  diagnostic->override_column = 0;
   diagnostic->kind = kind;
   diagnostic->option_index = 0;
 }
@@ -153,6 +154,8 @@ diagnostic_build_prefix (diagnostic_info
   };
   const char *text = _(diagnostic_kind_text[diagnostic->kind]);
   expanded_location s = expand_location (diagnostic->location);
+  if (diagnostic->override_column)
+    s.column = diagnostic->override_column;
   gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND);
 
   return
Index: gcc/diagnostic.h
===================================================================
--- gcc/diagnostic.h	(revision 144036)
+++ gcc/diagnostic.h	(working copy)
@@ -41,6 +41,7 @@ typedef struct diagnostic_info
 {
   text_info message;
   location_t location;
+  unsigned int override_column;
   /* TREE_BLOCK if the diagnostic is to be reported in some inline
      function inlined into other function, otherwise NULL.  */
   tree abstract_origin;
@@ -185,6 +186,10 @@ extern diagnostic_context *global_dc;
 
 #define report_diagnostic(D) diagnostic_report_diagnostic (global_dc, D)
 
+/* Override the column number to be used for reporting a
+   diagnostic.  */
+#define diagnostic_override_column(DI, COL) (DI)->override_column = (COL)
+
 /* Diagnostic related functions.  */
 extern void diagnostic_initialize (diagnostic_context *);
 extern void diagnostic_report_current_module (diagnostic_context *);
Index: gcc/testsuite/gcc.dg/fltconst-1.c
===================================================================
--- gcc/testsuite/gcc.dg/fltconst-1.c	(revision 144036)
+++ gcc/testsuite/gcc.dg/fltconst-1.c	(working copy)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
+/* { dg-options "-std=gnu99 -fshow-column" } */
 
 double a = 1.ld;	/* { dg-error "12:invalid suffix" } */
 double b = 1.fd;	/* { dg-error "12:invalid suffix" } */
Index: gcc/testsuite/gcc.dg/builtin-redefine.c
===================================================================
--- gcc/testsuite/gcc.dg/builtin-redefine.c	(revision 144036)
+++ gcc/testsuite/gcc.dg/builtin-redefine.c	(working copy)
@@ -28,7 +28,7 @@
 #define __TIME__ "X"         /* Re-define while defined.  */
 
 #define __TIME__ "Y"         /* { dg-warning "\"__TIME__\" redefined" } */
-/* { dg-warning "previous definition" "" { target *-*-* } 28 } */
+/* { dg-message "previous definition" "" { target *-*-* } 28 } */
 
 #undef __TIME__              /* Undefine while defined.  */
 
@@ -39,7 +39,7 @@
 #define __DATE__ "X"         /* Re-define while defined.  */
 
 #define __DATE__ "Y"         /* { dg-warning "\"__DATE__\" redefined" } */
-/* { dg-warning "previous definition" "" { target *-*-* } 39 } */
+/* { dg-message "previous definition" "" { target *-*-* } 39 } */
 
 #undef __DATE__              /* Undefine while defined.  */
 
@@ -48,7 +48,7 @@
 #define __TIMESTAMP__ "X"    /* Re-define while defined.  */
 
 #define __TIMESTAMP__ "Y"    /* { dg-warning "\"__TIMESTAMP__\" redefined" } */
-/* { dg-warning "previous definition" "" { target *-*-* } 48 } */
+/* { dg-message "previous definition" "" { target *-*-* } 48 } */
 
 #undef __TIMESTAMP__         /* Undefine while defined.  */
 
Index: gcc/testsuite/gcc.dg/cpp/redef3.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/redef3.c	(revision 144036)
+++ gcc/testsuite/gcc.dg/cpp/redef3.c	(working copy)
@@ -15,7 +15,7 @@
    { dg-warning "redefined" "redef B"      { target *-*-* } 9  }
    { dg-warning "redefined" "redef D"      { target *-*-* } 11 }
    { dg-warning "redefined" "redef E"      { target *-*-* } 12 }
-   { dg-warning "previous"  "prev def A"   { target *-*-* } 6  }
-   { dg-warning "previous"  "prev def B"   { target *-*-* } 8  }
-   { dg-warning "previous"  "prev def D/E" { target *-*-* } 0  }
+   { dg-message "previous"  "prev def A"   { target *-*-* } 6  }
+   { dg-message "previous"  "prev def B"   { target *-*-* } 8  }
+   { dg-message "previous"  "prev def D/E" { target *-*-* } 0  }
 */
Index: gcc/testsuite/gcc.dg/cpp/Wvariadic-3.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/Wvariadic-3.c	(revision 144036)
+++ gcc/testsuite/gcc.dg/cpp/Wvariadic-3.c	(working copy)
@@ -4,3 +4,4 @@
 #define f(x,...)
 #define g(x,y...)	/* { dg-error "variadic" } */
 int not_empty;
+/* { dg-message "warnings being treated as errors" "" { target *-*-* } 0 } */
Index: gcc/testsuite/gcc.dg/cpp/Wvariadic-1.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/Wvariadic-1.c	(revision 144036)
+++ gcc/testsuite/gcc.dg/cpp/Wvariadic-1.c	(working copy)
@@ -4,3 +4,4 @@
 #define f(x,...)	/* { dg-error "variadic" } */
 #define g(x,y...)	/* { dg-error "variadic" } */
 int not_empty;
+/* { dg-message "warnings being treated as errors" "" { target *-*-* } 0 } */
Index: gcc/testsuite/gcc.dg/cpp/redef2.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/redef2.c	(revision 144036)
+++ gcc/testsuite/gcc.dg/cpp/redef2.c	(working copy)
@@ -23,9 +23,9 @@
    { dg-warning "redefined" "redef ro"      { target *-*-* } 12 }
    { dg-warning "redefined" "redef va"      { target *-*-* } 15 }
 
-   { dg-warning "previous"  "prev def mac"  { target *-*-* } 6  }
-   { dg-warning "previous"  "prev def mac"  { target *-*-* } 7  }
-   { dg-warning "previous"  "prev def mac"  { target *-*-* } 8  }
-   { dg-warning "previous"  "prev def ro"   { target *-*-* } 11 }
-   { dg-warning "previous"  "prev def va"   { target *-*-* } 14 }
+   { dg-message "previous"  "prev def mac"  { target *-*-* } 6  }
+   { dg-message "previous"  "prev def mac"  { target *-*-* } 7  }
+   { dg-message "previous"  "prev def mac"  { target *-*-* } 8  }
+   { dg-message "previous"  "prev def ro"   { target *-*-* } 11 }
+   { dg-message "previous"  "prev def va"   { target *-*-* } 14 }
 */
Index: gcc/testsuite/gcc.dg/cpp/trad/redef2.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/trad/redef2.c	(revision 144036)
+++ gcc/testsuite/gcc.dg/cpp/trad/redef2.c	(working copy)
@@ -2,31 +2,31 @@
 
 /* { dg-do preprocess } */
 
-#define foo bar    /* { dg-warning "previous def" "foo prev def" } */
+#define foo bar    /* { dg-message "previous def" "foo prev def" } */
 #define foo barr   /* { dg-warning "redefined" "foo redefined" } */
 
 #undef foo
-#define foo bar    /* { dg-warning "previous def" "foo prev def 2" } */
+#define foo bar    /* { dg-message "previous def" "foo prev def 2" } */
 #define foo() bar    /* { dg-warning "redefined" "foo redefined 2" } */
 
 #undef foo
-#define foo() bar    /* { dg-warning "previous def" "foo prev def" } */
+#define foo() bar    /* { dg-message "previous def" "foo prev def" } */
 #define foo() barr   /* { dg-warning "redefined" "foo redefined" } */
 
-#define quux(thud) a thud b /* { dg-warning "previous def" "quux prev def" } */
+#define quux(thud) a thud b /* { dg-message "previous def" "quux prev def" } */
 #define quux(thu) a thud b   /* { dg-warning "redefined" "quux redefined" } */
 
-#define bar(x, y) x+y /* { dg-warning "previous def" "bar prev def" } */
+#define bar(x, y) x+y /* { dg-message "previous def" "bar prev def" } */
 #define bar(x, y) x+x   /* { dg-warning "redefined" "bar redefined" } */
 
-#define bat(x, y) x+y  /* { dg-warning "previous def" "bat prev def" } */
+#define bat(x, y) x+y  /* { dg-message "previous def" "bat prev def" } */
 #define bat(x, y) x+ y   /* { dg-warning "redefined" "bat redefined" } */
 
-#define baz(x, y) x+y  /* { dg-warning "previous def" "baz prev def" } */
+#define baz(x, y) x+y  /* { dg-message "previous def" "baz prev def" } */
 #define baz(x, y) x +y   /* { dg-warning "redefined" "baz redefined" } */
 
-#define f(x, y) "x y"  /* { dg-warning "previous def" "f prev def" } */
+#define f(x, y) "x y"  /* { dg-message "previous def" "f prev def" } */
 #define f(x, y) "x  y"   /* { dg-warning "redefined" "f redefined" } */
 
-#define g(x, y) 'x'  /* { dg-warning "previous def" "g prev def" } */
+#define g(x, y) 'x'  /* { dg-message "previous def" "g prev def" } */
 #define g(x, y) ' x'   /* { dg-warning "redefined" "g redefined" } */
Index: gcc/cp/error.c
===================================================================
--- gcc/cp/error.c	(revision 144036)
+++ gcc/cp/error.c	(working copy)
@@ -2665,39 +2665,6 @@ cp_printer (pretty_printer *pp, text_inf
 #undef next_int
 }
 
-/* Callback from cpp_error for PFILE to print diagnostics arising from
-   interpreting strings.  The diagnostic is of type LEVEL; MSG is the
-   translated message and AP the arguments.  */
-
-void
-cp_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
-	      const char *msg, va_list *ap)
-{
-  diagnostic_info diagnostic;
-  diagnostic_t dlevel;
-  switch (level)
-    {
-    case CPP_DL_WARNING:
-    case CPP_DL_WARNING_SYSHDR:
-      dlevel = DK_WARNING;
-      break;
-    case CPP_DL_PEDWARN:
-      dlevel = DK_PEDWARN;
-      break;
-    case CPP_DL_ERROR:
-      dlevel = DK_ERROR;
-      break;
-    case CPP_DL_ICE:
-      dlevel = DK_ICE;
-      break;
-    default:
-      gcc_unreachable ();
-    }
-  diagnostic_set_info_translated (&diagnostic, msg, ap,
-				  input_location, dlevel);
-  report_diagnostic (&diagnostic);
-}
-
 /* Warn about the use of C++0x features when appropriate.  */
 void
 maybe_warn_cpp0x (const char* str)
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 144036)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -43,9 +43,6 @@ along with GCC; see the file COPYING3.  
 #else
 #define ATTRIBUTE_GCC_CXXDIAG(m, n) ATTRIBUTE_NONNULL(m)
 #endif
-extern void cp_cpp_error			(cpp_reader *, int,
-						 const char *, va_list *)
-     ATTRIBUTE_GCC_CXXDIAG(3,0);
 #ifdef GCC_TOPLEV_H
 #error \
 In order for the format checking to accept the C++ front end diagnostic \
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 144036)
+++ gcc/cp/parser.c	(working copy)
@@ -310,8 +310,7 @@ cp_lexer_new_main (void)
 
   /* Subsequent preprocessor diagnostics should use compiler
      diagnostic functions to get the compiler source location.  */
-  cpp_get_options (parse_in)->client_diagnostic = true;
-  cpp_get_callbacks (parse_in)->error = cp_cpp_error;
+  done_lexing = true;
 
   gcc_assert (lexer->next_token->type != CPP_PURGED);
   return lexer;
Index: gcc/c-tree.h
===================================================================
--- gcc/c-tree.h	(revision 144036)
+++ gcc/c-tree.h	(working copy)
@@ -647,4 +647,8 @@ extern void c_write_global_declarations 
 extern void pedwarn_c90 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_CDIAG(3,4);
 extern void pedwarn_c99 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_CDIAG(3,4);
 
+extern void c_cpp_error (cpp_reader *, int, location_t, unsigned int,
+			 const char *, va_list *)
+     ATTRIBUTE_GCC_CDIAG(5,0);
+
 #endif /* ! GCC_C_TREE_H */
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c	(revision 144036)
+++ gcc/c-decl.c	(working copy)
@@ -8069,7 +8069,7 @@ c_write_global_declarations (void)
 
   /* Don't waste time on further processing if -fsyntax-only or we've
      encountered errors.  */
-  if (flag_syntax_only || errorcount || sorrycount || cpp_errors (parse_in))
+  if (flag_syntax_only || errorcount || sorrycount)
     return;
 
   /* Close the external scope.  */
Index: gcc/fortran/cpp.c
===================================================================
--- gcc/fortran/cpp.c	(revision 144036)
+++ gcc/fortran/cpp.c	(working copy)
@@ -137,6 +137,9 @@ static void cb_include (cpp_reader *, so
 static void cb_ident (cpp_reader *, source_location, const cpp_string *);
 static void cb_used_define (cpp_reader *, source_location, cpp_hashnode *);
 static void cb_used_undef (cpp_reader *, source_location, cpp_hashnode *);
+static void cb_cpp_error (cpp_reader *, int, location_t, unsigned int,
+			  const char *, va_list *)
+     ATTRIBUTE_GCC_DIAG(5,0);
 void pp_dir_change (cpp_reader *, const char *);
 
 static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
@@ -452,7 +455,6 @@ gfc_cpp_post_options (void)
   cpp_option->cplusplus_comments = 0;
 
   cpp_option->pedantic = pedantic;
-  cpp_option->inhibit_warnings = inhibit_warnings;
 
   cpp_option->dollars_in_ident = gfc_option.flag_dollar_ok;
   cpp_option->discard_comments = gfc_cpp_option.discard_comments;
@@ -465,9 +467,6 @@ gfc_cpp_post_options (void)
 
   cpp_post_options (cpp_in);
 
-  /* If an error has occurred in cpplib, note it so we fail immediately.  */
-  errorcount += cpp_errors (cpp_in);
-
   gfc_cpp_register_include_paths ();
 }
 
@@ -482,6 +481,7 @@ gfc_cpp_init_0 (void)
   cb->line_change = cb_line_change;
   cb->ident = cb_ident;
   cb->def_pragma = cb_def_pragma;
+  cb->error = cb_cpp_error;
 
   if (gfc_cpp_option.dump_includes)
     cb->include = cb_include;
@@ -961,6 +961,57 @@ cb_used_define (cpp_reader *pfile, sourc
   cpp_define_queue = q;
 }
 
+/* Callback from cpp_error for PFILE to print diagnostics from the
+   preprocessor.  The diagnostic is of type LEVEL, at location
+   LOCATION, with column number possibly overridden by COLUMN_OVERRIDE
+   if not zero; MSG is the translated message and AP the
+   arguments.  */
+
+static void
+cb_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
+	      location_t location, unsigned int column_override,
+	      const char *msg, va_list *ap)
+{
+  diagnostic_info diagnostic;
+  diagnostic_t dlevel;
+  int save_warn_system_headers = warn_system_headers;
+
+  switch (level)
+    {
+    case CPP_DL_WARNING_SYSHDR:
+      warn_system_headers = 1;
+      /* Fall through.  */
+    case CPP_DL_WARNING:
+      dlevel = DK_WARNING;
+      break;
+    case CPP_DL_PEDWARN:
+      dlevel = DK_PEDWARN;
+      break;
+    case CPP_DL_ERROR:
+      dlevel = DK_ERROR;
+      break;
+    case CPP_DL_ICE:
+      dlevel = DK_ICE;
+      break;
+    case CPP_DL_NOTE:
+      dlevel = DK_NOTE;
+      /* If the previous warning was not given because it was in a
+	 system header, do not give the "previous definition" note
+	 either.  */
+      if (!diagnostic_report_warnings_p (input_location))
+	return;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+  diagnostic_set_info_translated (&diagnostic, msg, ap,
+				  location, dlevel);
+  if (column_override)
+    diagnostic_override_column (&diagnostic, column_override);
+  report_diagnostic (&diagnostic);
+  if (level == CPP_DL_WARNING_SYSHDR)
+    warn_system_headers = save_warn_system_headers;
+}
 
 /* Callback called when -fworking-director and -E to emit working
    directory in cpp output file.  */
Index: gcc/c-opts.c
===================================================================
--- gcc/c-opts.c	(revision 144036)
+++ gcc/c-opts.c	(working copy)
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.  
 #include "mkdeps.h"
 #include "target.h"
 #include "tm_p.h"
+#include "c-tree.h"		/* For c_cpp_error.  */
 
 #ifndef DOLLARS_IN_IDENTIFIERS
 # define DOLLARS_IN_IDENTIFIERS true
@@ -201,6 +202,7 @@ c_common_init_options (unsigned int argc
 {
   static const unsigned int lang_flags[] = {CL_C, CL_ObjC, CL_CXX, CL_ObjCXX};
   unsigned int i, result;
+  struct cpp_callbacks *cb;
 
   /* This is conditionalized only because that is the way the front
      ends used to do it.  Maybe this should be unconditional?  */
@@ -216,6 +218,8 @@ c_common_init_options (unsigned int argc
 
   parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89,
 				ident_hash, line_table);
+  cb = cpp_get_callbacks (parse_in);
+  cb->error = c_cpp_error;
 
   cpp_opts = cpp_get_options (parse_in);
   cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
@@ -333,7 +337,6 @@ c_common_handle_option (size_t scode, co
 	 or environment var dependency generation is used.  */
       cpp_opts->deps.style = (code == OPT_M ? DEPS_SYSTEM: DEPS_USER);
       flag_no_output = 1;
-      cpp_opts->inhibit_warnings = 1;
       break;
 
     case OPT_MD:
@@ -444,7 +447,6 @@ c_common_handle_option (size_t scode, co
       break;
 
     case OPT_Werror:
-      cpp_opts->warnings_are_errors = value;
       global_dc->warning_as_error_requested = value;
       break;
 
@@ -503,10 +505,6 @@ c_common_handle_option (size_t scode, co
       warn_strict_null_sentinel = value;
       break;
 
-    case OPT_Wsystem_headers:
-      cpp_opts->warn_system_headers = value;
-      break;
-
     case OPT_Wtraditional:
       cpp_opts->warn_traditional = value;
       break;
@@ -895,8 +893,6 @@ c_common_handle_option (size_t scode, co
 	 c_common_post_options, so that a subsequent -Wno-endif-labels
 	 is not overridden.  */
     case OPT_pedantic_errors:
-      cpp_opts->pedantic_errors = 1;
-      /* Fall through.  */
     case OPT_pedantic:
       cpp_opts->pedantic = 1;
       cpp_opts->warn_endif_labels = 1;
@@ -971,10 +967,6 @@ c_common_handle_option (size_t scode, co
       flag_undef = 1;
       break;
 
-    case OPT_w:
-      cpp_opts->inhibit_warnings = 1;
-      break;
-
     case OPT_v:
       verbose = true;
       break;
@@ -1155,10 +1147,6 @@ c_common_post_options (const char **pfil
 
   input_location = UNKNOWN_LOCATION;
 
-  /* If an error has occurred in cpplib, note it so we fail
-     immediately.  */
-  errorcount += cpp_errors (parse_in);
-
   *pfilename = this_input_filename
     = cpp_read_main_file (parse_in, in_fnames[0]);
   /* Don't do any compilation or preprocessing if there is no input file.  */
@@ -1270,7 +1258,8 @@ c_common_finish (void)
 {
   FILE *deps_stream = NULL;
 
-  if (cpp_opts->deps.style != DEPS_NONE)
+  /* Don't write the deps file if there are errors.  */
+  if (cpp_opts->deps.style != DEPS_NONE && errorcount == 0)
     {
       /* If -M or -MM was seen without -MF, default output to the
 	 output stream.  */
@@ -1286,7 +1275,7 @@ c_common_finish (void)
 
   /* For performance, avoid tearing down cpplib's internal structures
      with cpp_destroy ().  */
-  errorcount += cpp_finish (parse_in, deps_stream);
+  cpp_finish (parse_in, deps_stream);
 
   if (deps_stream && deps_stream != out_stream
       && (ferror (deps_stream) || fclose (deps_stream)))
Index: gcc/c-ppoutput.c
===================================================================
--- gcc/c-ppoutput.c	(revision 144036)
+++ gcc/c-ppoutput.c	(working copy)
@@ -521,6 +521,7 @@ pp_file_change (const struct line_map *m
 
   if (map != NULL)
     {
+      input_location = map->start_location;
       if (print.first_time)
 	{
 	  /* Avoid printing foo.i when the main file is foo.c.  */
Index: gcc/c-common.c
===================================================================
--- gcc/c-common.c	(revision 144036)
+++ gcc/c-common.c	(working copy)
@@ -32,7 +32,6 @@ along with GCC; see the file COPYING3.  
 #include "varray.h"
 #include "expr.h"
 #include "c-common.h"
-#include "diagnostic.h"
 #include "tm_p.h"
 #include "obstack.h"
 #include "cpplib.h"
@@ -41,6 +40,7 @@ along with GCC; see the file COPYING3.  
 #include "tree-inline.h"
 #include "c-tree.h"
 #include "toplev.h"
+#include "diagnostic.h"
 #include "tree-iterator.h"
 #include "hashtab.h"
 #include "tree-mudflap.h"
@@ -495,6 +495,10 @@ tree (*make_fname_decl) (tree, int);
    This is a count, since unevaluated expressions can nest.  */
 int skip_evaluation;
 
+/* Whether lexing has been completed, so subsequent preprocessor
+   errors should use the compiler's input_location.  */
+bool done_lexing = false;
+
 /* Information about how a function name is generated.  */
 struct fname_var_t
 {
@@ -7492,6 +7496,67 @@ c_parse_error (const char *gmsgid, enum 
 #undef catenate_messages
 }
 
+/* Callback from cpp_error for PFILE to print diagnostics from the
+   preprocessor.  The diagnostic is of type LEVEL, at location
+   LOCATION unless this is after lexing and the compiler's location
+   should be used instead, with column number possibly overridden by
+   COLUMN_OVERRIDE if not zero; MSG is the translated message and AP
+   the arguments.  */
+
+void
+c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
+	     location_t location, unsigned int column_override,
+	     const char *msg, va_list *ap)
+{
+  diagnostic_info diagnostic;
+  diagnostic_t dlevel;
+  int save_warn_system_headers = warn_system_headers;
+
+  switch (level)
+    {
+    case CPP_DL_WARNING_SYSHDR:
+      if (flag_no_output)
+	return;
+      warn_system_headers = 1;
+      /* Fall through.  */
+    case CPP_DL_WARNING:
+      if (flag_no_output)
+	return;
+      dlevel = DK_WARNING;
+      break;
+    case CPP_DL_PEDWARN:
+      if (flag_no_output && !flag_pedantic_errors)
+	return;
+      dlevel = DK_PEDWARN;
+      break;
+    case CPP_DL_ERROR:
+      dlevel = DK_ERROR;
+      break;
+    case CPP_DL_ICE:
+      dlevel = DK_ICE;
+      break;
+    case CPP_DL_NOTE:
+      dlevel = DK_NOTE;
+      /* If the previous warning was not given because it was in a
+	 system header, do not give the "previous definition" note
+	 either.  */
+      if (!diagnostic_report_warnings_p (input_location))
+	return;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+  if (done_lexing)
+    location = input_location;
+  diagnostic_set_info_translated (&diagnostic, msg, ap,
+				  location, dlevel);
+  if (column_override)
+    diagnostic_override_column (&diagnostic, column_override);
+  report_diagnostic (&diagnostic);
+  if (level == CPP_DL_WARNING_SYSHDR)
+    warn_system_headers = save_warn_system_headers;
+}
+
 /* Walk a gimplified function and warn for functions whose return value is
    ignored and attribute((warn_unused_result)) is set.  This is done before
    inlining, so we don't have to worry about that.  */
Index: gcc/c-common.h
===================================================================
--- gcc/c-common.h	(revision 144036)
+++ gcc/c-common.h	(working copy)
@@ -657,6 +657,11 @@ extern int max_tinst_depth;
 
 extern int skip_evaluation;
 
+/* Whether lexing has been completed, so subsequent preprocessor
+   errors should use the compiler's input_location.  */
+
+extern bool done_lexing;
+
 /* C types are partitioned into three subsets: object, function, and
    incomplete types.  */
 #define C_TYPE_OBJECT_P(type) \
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 144036)
+++ gcc/Makefile.in	(working copy)
@@ -1900,7 +1900,7 @@ c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM
         $(TREE_H) $(C_PRAGMA_H) $(FLAGS_H) $(TOPLEV_H) langhooks.h		\
         $(TREE_INLINE_H) $(DIAGNOSTIC_H) intl.h debug.h $(C_COMMON_H)	\
         opts.h options.h $(MKDEPS_H) incpath.h cppdefault.h $(TARGET_H) \
-	$(TM_P_H) $(VARRAY_H)
+	$(TM_P_H) $(VARRAY_H) $(C_TREE_H)
 	$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
 		$< $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@
 
Index: libcpp/directives.c
===================================================================
--- libcpp/directives.c	(revision 144036)
+++ libcpp/directives.c	(working copy)
@@ -2299,13 +2299,6 @@ handle_assertion (cpp_reader *pfile, con
   run_directive (pfile, type, str, count);
 }
 
-/* The number of errors for a given reader.  */
-unsigned int
-cpp_errors (cpp_reader *pfile)
-{
-  return pfile->errors;
-}
-
 /* The options structure.  */
 cpp_options *
 cpp_get_options (cpp_reader *pfile)
Index: libcpp/Makefile.in
===================================================================
--- libcpp/Makefile.in	(revision 144036)
+++ libcpp/Makefile.in	(working copy)
@@ -73,13 +73,12 @@ ALL_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(
 libcpp_a_OBJS = charset.o directives.o directives-only.o errors.o \
 	expr.o files.o identifiers.o init.o lex.o line-map.o macro.o \
 	mkdeps.o pch.o symtab.o traditional.o
-makedepend_OBJS = makedepend.o
 
 libcpp_a_SOURCES = charset.c directives.c directives-only.c errors.c \
 	expr.c files.c identifiers.c init.c lex.c line-map.c macro.c \
 	mkdeps.c pch.c symtab.c traditional.c
 
-all: libcpp.a makedepend$(EXEEXT) $(USED_CATALOGS)
+all: libcpp.a $(USED_CATALOGS)
 
 .SUFFIXES:
 .SUFFIXES: .c .gmo .o .obj .po .pox
@@ -89,12 +88,6 @@ libcpp.a: $(libcpp_a_OBJS)
 	$(AR) $(ARFLAGS) libcpp.a $(libcpp_a_OBJS)
 	$(RANLIB) libcpp.a
 
-makedepend$(EXEEXT): $(makedepend_OBJS) libcpp.a ../libiberty/libiberty.a
-	@rm -f makedepend$(EXEEXT)
-	$(CC) $(CFLAGS) $(LDFLAGS) -o makedepend$(EXEEXT) \
-	  $(makedepend_OBJS) libcpp.a ../libiberty/libiberty.a \
-	  $(LIBINTL) $(LIBICONV)
-
 # Rules to rebuild the configuration
 
 Makefile: $(srcdir)/Makefile.in config.status
@@ -166,7 +159,7 @@ mostlyclean:
 	-rm -f *.o
 
 clean: mostlyclean
-	-rm -rf makedepend$(EXEEXT) libcpp.a $(srcdir)/autom4te.cache
+	-rm -rf libcpp.a $(srcdir)/autom4te.cache
 
 distclean: clean
 	-rm -f config.h stamp-h1 config.status config.cache config.log \
@@ -248,7 +241,7 @@ po/$(PACKAGE).pot: $(libcpp_a_SOURCES)
 	sed 's:$(srcdir)/::g' <po/$(PACKAGE).pot.tmp >po/$(PACKAGE).pot
 	rm po/$(PACKAGE).pot.tmp
 
-TAGS_SOURCES = $(libcpp_a_SOURCES) makedepend.c internal.h ucnid.h \
+TAGS_SOURCES = $(libcpp_a_SOURCES) internal.h ucnid.h \
     include/line-map.h include/symtab.h include/cpp-id-data.h \
     include/cpplib.h include/mkdeps.h system.h
 
@@ -260,7 +253,7 @@ TAGS: $(TAGS_SOURCES)
 .NOEXPORT:
 
 # Dependencies
--include $(patsubst %.o, $(DEPDIR)/%.Po, $(libcpp_a_OBJS) $(makedepend_OBJS))
+-include $(patsubst %.o, $(DEPDIR)/%.Po, $(libcpp_a_OBJS))
 
 # Dependencies on generated headers have to be explicit.
 init.o: localedir.h
Index: libcpp/macro.c
===================================================================
--- libcpp/macro.c	(revision 144036)
+++ libcpp/macro.c	(working copy)
@@ -1811,7 +1811,7 @@ _cpp_create_definition (cpp_reader *pfil
 			       "\"%s\" redefined", NODE_NAME (node));
 
 	  if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
-	    cpp_error_with_line (pfile, CPP_DL_PEDWARN,
+	    cpp_error_with_line (pfile, CPP_DL_NOTE,
 				 node->value.macro->line, 0,
 			 "this is the location of the previous definition");
 	}
Index: libcpp/include/cpplib.h
===================================================================
--- libcpp/include/cpplib.h	(revision 144036)
+++ libcpp/include/cpplib.h	(working copy)
@@ -302,22 +302,9 @@ struct cpp_options
   /* Nonzero means print names of header files (-H).  */
   unsigned char print_include_names;
 
-  /* Nonzero means cpp_pedwarn causes a hard error.  */
-  unsigned char pedantic_errors;
-
-  /* Nonzero means don't print warning messages.  */
-  unsigned char inhibit_warnings;
-
   /* Nonzero means complain about deprecated features.  */
   unsigned char warn_deprecated;
 
-  /* Nonzero means don't suppress warnings from system headers.  */
-  unsigned char warn_system_headers;
-
-  /* Nonzero means don't print error messages.  Has no option to
-     select it, but can be set by a user of cpplib (e.g. fix-header).  */
-  unsigned char inhibit_errors;
-
   /* Nonzero means warn if slash-star appears in a comment.  */
   unsigned char warn_comments;
 
@@ -353,9 +340,6 @@ struct cpp_options
      explicitly undefined.  */
   unsigned char warn_builtin_macro_redefined;
 
-  /* Nonzero means turn warnings into errors.  */
-  unsigned char warnings_are_errors;
-
   /* Nonzero means we should look for header.gcc files that remap file
      names.  */
   unsigned char remap;
@@ -450,9 +434,6 @@ struct cpp_options
   /* Nonzero means __STDC__ should have the value 0 in system headers.  */
   unsigned char stdc_0_in_system_headers;
 
-  /* True means error callback should be used for diagnostics.  */
-  bool client_diagnostic;
-
   /* True disables tokenization outside of preprocessing directives. */
   bool directives_only;
 };
@@ -492,10 +473,11 @@ struct cpp_callbacks
      be expanded.  */
   cpp_hashnode * (*macro_to_expand) (cpp_reader *, const cpp_token *);
 
-  /* Called to emit a diagnostic if client_diagnostic option is true.
-     This callback receives the translated message.  */
-  void (*error) (cpp_reader *, int, const char *, va_list *)
-       ATTRIBUTE_FPTR_PRINTF(3,0);
+  /* Called to emit a diagnostic.  This callback receives the
+     translated message.  */
+  void (*error) (cpp_reader *, int, source_location, unsigned int,
+		 const char *, va_list *)
+       ATTRIBUTE_FPTR_PRINTF(5,0);
 
   /* Callbacks for when a macro is expanded, or tested (whether
      defined or not at the time) in #ifdef, #ifndef or "defined".  */
@@ -697,19 +679,13 @@ extern void cpp_init_iconv (cpp_reader *
 
 /* Call this to finish preprocessing.  If you requested dependency
    generation, pass an open stream to write the information to,
-   otherwise NULL.  It is your responsibility to close the stream.
-
-   Returns cpp_errors (pfile).  */
-extern int cpp_finish (cpp_reader *, FILE *deps_stream);
+   otherwise NULL.  It is your responsibility to close the stream.  */
+extern void cpp_finish (cpp_reader *, FILE *deps_stream);
 
 /* Call this to release the handle at the end of preprocessing.  Any
-   use of the handle after this function returns is invalid.  Returns
-   cpp_errors (pfile).  */
+   use of the handle after this function returns is invalid.  */
 extern void cpp_destroy (cpp_reader *);
 
-/* Error count.  */
-extern unsigned int cpp_errors (cpp_reader *);
-
 extern unsigned int cpp_token_len (const cpp_token *);
 extern unsigned char *cpp_token_as_text (cpp_reader *, const cpp_token *);
 extern unsigned char *cpp_spell_token (cpp_reader *, const cpp_token *,
@@ -835,11 +811,8 @@ cpp_num cpp_num_sign_extend (cpp_num, si
 /* An internal consistency check failed.  Prints "internal error: ",
    otherwise the same as CPP_DL_ERROR.  */
 #define CPP_DL_ICE		0x04
-/* Extracts a diagnostic level from an int.  */
-#define CPP_DL_EXTRACT(l)	(l & 0xf)
-/* Nonzero if a diagnostic level is one of the warnings.  */
-#define CPP_DL_WARNING_P(l)	(CPP_DL_EXTRACT (l) >= CPP_DL_WARNING \
-				 && CPP_DL_EXTRACT (l) <= CPP_DL_PEDWARN)
+/* An informative note following a warning.  */
+#define CPP_DL_NOTE		0x05
 
 /* Output a diagnostic of some kind.  */
 extern void cpp_error (cpp_reader *, int, const char *msgid, ...)
Index: libcpp/init.c
===================================================================
--- libcpp/init.c	(revision 144036)
+++ libcpp/init.c	(working copy)
@@ -615,12 +615,11 @@ read_original_directory (cpp_reader *pfi
 }
 
 /* This is called at the end of preprocessing.  It pops the last
-   buffer and writes dependency output, and returns the number of
-   errors.
+   buffer and writes dependency output.
 
    Maybe it should also reset state, such that you could call
    cpp_start_read with a new filename to restart processing.  */
-int
+void
 cpp_finish (cpp_reader *pfile, FILE *deps_stream)
 {
   /* Warn about unused macros before popping the final buffer.  */
@@ -635,9 +634,8 @@ cpp_finish (cpp_reader *pfile, FILE *dep
   while (pfile->buffer)
     _cpp_pop_buffer (pfile);
 
-  /* Don't write the deps file if there are errors.  */
   if (CPP_OPTION (pfile, deps.style) != DEPS_NONE
-      && deps_stream && pfile->errors == 0)
+      && deps_stream)
     {
       deps_write (pfile->deps, deps_stream, 72);
 
@@ -648,8 +646,6 @@ cpp_finish (cpp_reader *pfile, FILE *dep
   /* Report on headers that could use multiple include guards.  */
   if (CPP_OPTION (pfile, print_include_names))
     _cpp_report_missing_guards (pfile);
-
-  return pfile->errors;
 }
 
 static void
Index: libcpp/errors.c
===================================================================
--- libcpp/errors.c	(revision 144036)
+++ libcpp/errors.c	(working copy)
@@ -28,146 +28,39 @@ Foundation, 51 Franklin Street, Fifth Fl
 #include "cpplib.h"
 #include "internal.h"
 
-static void print_location (cpp_reader *, source_location, unsigned int);
-
-/* Print the logical file location (LINE, COL) in preparation for a
-   diagnostic.  Outputs the #include chain if it has changed.  A line
-   of zero suppresses the include stack, and outputs the program name
-   instead.  */
-static void
-print_location (cpp_reader *pfile, source_location line, unsigned int col)
-{
-  if (line == 0)
-    fprintf (stderr, "%s: ", progname);
-  else
-    {
-      const struct line_map *map;
-      linenum_type lin;
-
-      map = linemap_lookup (pfile->line_table, line);
-      linemap_print_containing_files (pfile->line_table, map);
-
-      lin = SOURCE_LINE (map, line);
-      if (col == 0)
-	{
-	  col = SOURCE_COLUMN (map, line);
-	  if (col == 0)
-	    col = 1;
-	}
-
-      if (lin == 0)
-	fprintf (stderr, "%s:", map->to_file);
-      else if (CPP_OPTION (pfile, show_column) == 0)
-	fprintf (stderr, "%s:%u:", map->to_file, lin);
-      else
-	fprintf (stderr, "%s:%u:%u:", map->to_file, lin, col);
-
-      fputc (' ', stderr);
-    }
-}
-
-/* Set up for a diagnostic: print the file and line, bump the error
-   counter, etc.  SRC_LOC is the logical line number; zero means to print
-   at the location of the previously lexed token, which tends to be
-   the correct place by default.  The column number can be specified either
-   using COLUMN or (if COLUMN==0) extracting SOURCE_COLUMN from SRC_LOC.
-   (This may seem redundant, but is useful when pre-scanning (cleaning) a line,
-   when we haven't yet verified whether the current line_map has a
-   big enough max_column_hint.)
-
-   Returns 0 if the error has been suppressed.  */
-static int
-_cpp_begin_message (cpp_reader *pfile, int code,
-		    source_location src_loc, unsigned int column)
-{
-  int level = CPP_DL_EXTRACT (code);
-
-  switch (level)
-    {
-    case CPP_DL_WARNING:
-    case CPP_DL_PEDWARN:
-      if (cpp_in_system_header (pfile)
-	  && ! CPP_OPTION (pfile, warn_system_headers))
-	return 0;
-      /* Fall through.  */
-
-    case CPP_DL_WARNING_SYSHDR:
-      if (CPP_OPTION (pfile, warnings_are_errors)
-	  || (level == CPP_DL_PEDWARN && CPP_OPTION (pfile, pedantic_errors)))
-	{
-	  if (CPP_OPTION (pfile, inhibit_errors))
-	    return 0;
-	  level = CPP_DL_ERROR;
-	  pfile->errors++;
-	}
-      else if (CPP_OPTION (pfile, inhibit_warnings))
-	return 0;
-      break;
-
-    case CPP_DL_ERROR:
-      if (CPP_OPTION (pfile, inhibit_errors))
-	return 0;
-      /* ICEs cannot be inhibited.  */
-    case CPP_DL_ICE:
-      pfile->errors++;
-      break;
-    }
-
-  print_location (pfile, src_loc, column);
-  if (CPP_DL_WARNING_P (level))
-    fputs (_("warning: "), stderr);
-  else if (level == CPP_DL_ICE)
-    fputs (_("internal error: "), stderr);
-  else
-    fputs (_("error: "), stderr);
-
-  return 1;
-}
-
-/* Don't remove the blank before do, as otherwise the exgettext
-   script will mistake this as a function definition */
-#define v_message(msgid, ap) \
- do { vfprintf (stderr, _(msgid), ap); putc ('\n', stderr); } while (0)
-
-/* Exported interface.  */
-
 /* Print an error at the location of the previously lexed token.  */
 void
 cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
 {
   source_location src_loc;
   va_list ap;
-  
+
   va_start (ap, msgid);
 
-  if (CPP_OPTION (pfile, client_diagnostic))
-    pfile->cb.error (pfile, level, _(msgid), &ap);
-  else
+  if (CPP_OPTION (pfile, traditional))
     {
-      if (CPP_OPTION (pfile, traditional))
-	{
-	  if (pfile->state.in_directive)
-	    src_loc = pfile->directive_line;
-	  else
-	    src_loc = pfile->line_table->highest_line;
-	}
-      /* We don't want to refer to a token before the beginning of the
-	 current run -- that is invalid.  */
-      else if (pfile->cur_token == pfile->cur_run->base)
-	{
-	  if (pfile->cur_run->prev != NULL)
-	    src_loc = pfile->cur_run->prev->limit->src_loc;
-	  else
-	    src_loc = 0;
-	}
+      if (pfile->state.in_directive)
+	src_loc = pfile->directive_line;
       else
-	{
-	  src_loc = pfile->cur_token[-1].src_loc;
-	}
-
-      if (_cpp_begin_message (pfile, level, src_loc, 0))
-	v_message (msgid, ap);
+	src_loc = pfile->line_table->highest_line;
+    }
+  /* We don't want to refer to a token before the beginning of the
+     current run -- that is invalid.  */
+  else if (pfile->cur_token == pfile->cur_run->base)
+    {
+      if (pfile->cur_run->prev != NULL)
+	src_loc = pfile->cur_run->prev->limit->src_loc;
+      else
+	src_loc = 0;
     }
+  else
+    {
+      src_loc = pfile->cur_token[-1].src_loc;
+    }
+
+  if (!pfile->cb.error)
+    abort ();
+  pfile->cb.error (pfile, level, src_loc, 0, _(msgid), &ap);
 
   va_end (ap);
 }
@@ -182,8 +75,9 @@ cpp_error_with_line (cpp_reader *pfile, 
   
   va_start (ap, msgid);
 
-  if (_cpp_begin_message (pfile, level, src_loc, column))
-    v_message (msgid, ap);
+  if (!pfile->cb.error)
+    abort ();
+  pfile->cb.error (pfile, level, src_loc, column, _(msgid), &ap);
 
   va_end (ap);
 }
Index: libcpp/internal.h
===================================================================
--- libcpp/internal.h	(revision 144036)
+++ libcpp/internal.h	(working copy)
@@ -388,9 +388,6 @@ struct cpp_reader
   /* Nonzero prevents the lexer from re-using the token runs.  */
   unsigned int keep_tokens;
 
-  /* Error counter for exit code.  */
-  unsigned int errors;
-
   /* Buffer to hold macro definition string.  */
   unsigned char *macro_buffer;
   unsigned int macro_buffer_len;
Index: libcpp/makedepend.c
===================================================================
--- libcpp/makedepend.c	(revision 144036)
+++ libcpp/makedepend.c	(working copy)
@@ -1,206 +0,0 @@
-/* Dependency generator utility.
-   Copyright (C) 2004 Free Software Foundation, Inc.
-   Contributed by Zack Weinberg, May 2004
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them.   Help stamp out software-hoarding!  */
-
-#include "config.h"
-#include "system.h"
-#include "line-map.h"
-#include "cpplib.h"
-#include "getopt.h"
-#include "mkdeps.h"
-
-const char *progname;
-const char *vpath;
-
-static const char *output_file;
-static bool had_errors;
-
-/* Option lists, to give to cpplib before each input file.  */
-struct cmd_line_macro
-{
-  struct cmd_line_macro *next;
-  bool is_undef;
-  const char *macro;
-};
-
-static struct cmd_line_macro *cmd_line_macros;
-static cpp_dir *cmd_line_searchpath;
-
-static void
-add_clm (const char *macro, bool is_undef)
-{
-  struct cmd_line_macro *clm = XNEW (struct cmd_line_macro);
-  clm->next = cmd_line_macros;
-  clm->is_undef = is_undef;
-  clm->macro = macro;
-  cmd_line_macros = clm;
-}
-
-static void
-add_dir (char *name, bool sysp)
-{
-  cpp_dir *dir = XNEW (cpp_dir);
-  dir->next = cmd_line_searchpath;
-  dir->name = name;
-  dir->sysp = sysp;
-  dir->construct = 0;
-  dir->user_supplied_p = 1;
-  cmd_line_searchpath = dir;
-}
-
-/* Command line processing.  */
-
-static void ATTRIBUTE_NORETURN
-usage (int errcode)
-{
-  fprintf (stderr,
-"usage: %s [-vh] [-V vpath] [-Dname[=def]...] [-Uname] [-Idir...] [-o file] sources...\n",
-	   progname);
-  exit (errcode);
-}
-
-static int
-parse_options (int argc, char **argv)
-{
-  static const struct option longopts[] = {
-    { "--help", no_argument, 0, 'h' },
-    { 0, 0, 0, 0 }
-  };
-
-  for (;;)
-    switch (getopt_long (argc, argv, "hD:U:I:J:o:V:", longopts, 0))
-      {
-      case 'h': usage (0);
-      case 'D': add_clm (optarg, false); break;
-      case 'U': add_clm (optarg, true);  break;
-      case 'I': add_dir (optarg, false); break;
-      case 'J': add_dir (optarg, true);  break;
-      case 'o':
-	if (output_file)
-	  {
-	    fprintf (stderr, "%s: too many output files\n", progname);
-	    usage (2);
-	  }
-	output_file = optarg;
-	break;
-      case 'V':
-	if (vpath)
-	  {
-	    fprintf (stderr, "%s: too many vpaths\n", progname);
-	    usage (2);
-	  }
-	vpath = optarg;
-	break;
-      case '?':
-	usage (2);  /* getopt has issued the error message.  */
-
-      case -1: /* end of options */
-	if (optind == argc)
-	  {
-	    fprintf (stderr, "%s: no input files\n", progname);
-	    usage (2);
-	  }
-	return optind;
-
-      default:
-	abort ();
-      }
-}
-
-/* Set up cpplib from command line options.  */
-static cpp_reader *
-reader_init (struct line_maps *line_table)
-{
-  cpp_reader *reader;
-  cpp_options *options;
-
-  linemap_init (line_table);
-  reader = cpp_create_reader (CLK_GNUC89, 0, line_table);
-
-  /* Ignore warnings and errors (we don't have access to system
-     headers).  Request dependency output.  */
-  options = cpp_get_options (reader);
-  options->inhibit_warnings = 1;
-  options->inhibit_errors = 1;
-  options->deps.style = DEPS_USER;
-
-  /* Further initialization.  */
-  cpp_post_options (reader);
-  cpp_init_iconv (reader);
-  cpp_set_include_chains (reader, cmd_line_searchpath, cmd_line_searchpath,
-			  false);
-  if (vpath)
-    {
-      struct deps *deps = cpp_get_deps (reader);
-      deps_add_vpath (deps, vpath);
-    }
-
-  return reader;
-}
-
-/* Process one input source file.  */
-static void
-process_file (const char *file)
-{
-  struct line_maps line_table;
-  cpp_reader *reader = reader_init (&line_table);
-
-  if (!cpp_read_main_file (reader, file))
-    had_errors = true;
-  else
-    {
-      struct cmd_line_macro *clm;
-
-      cpp_init_builtins (reader, true);
-      for (clm = cmd_line_macros; clm; clm = clm->next)
-	(clm->is_undef ? cpp_undef : cpp_define) (reader, clm->macro);
-
-      cpp_scan_nooutput (reader);
-      if (cpp_finish (reader, stdout))
-	had_errors = true;
-    }
-  cpp_destroy (reader);
-  linemap_free (&line_table);
-}
-
-/* Master control.  */
-
-int
-main(int argc, char **argv)
-{
-  int first_input, i;
-
-  progname = argv[0];
-  xmalloc_set_program_name (progname);
-
-  first_input = parse_options (argc, argv);
-  if (output_file)
-    if (!freopen (output_file, "w", stdout))
-      {
-	perror (output_file);
-	return 1;
-      }
-
-  for (i = first_input; i < argc; i++)
-    process_file (argv[i]);
-
-  return had_errors;
-}

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]