[Fortran/Diagnostics] Move Fortran to common diagnostics machinery
diff mbox

Message ID CAESRpQAAg8r10Eqw5G-0zXSp=DRv67Rv1KfxpnuQu6A0oiyNNQ@mail.gmail.com
State New
Headers show

Commit Message

Manuel López-Ibáñez Aug. 6, 2014, 4:50 p.m. UTC
This is the first step for moving Fortran to use the common
diagnostics machinery. This patch makes Fortran use the common
machinery for those warnings that don't have a location or a
controlling option.

Before:

manuel@gcc10:~/test1$ echo end | ./213518/build/gcc/f951
-fdiagnostics-color -Werror -x -
f951: error: command line option '-x -' is valid for the driver but
not for Fortran
Warning: Reading file '<stdin>' as free form

After:

manuel@gcc10:~/test1$ echo end | ./213518M/build/gcc/f951
-fdiagnostics-color -Werror -x -
f951: Error: command line option '-x -' is valid for the driver but
not for Fortran
f951: Error: Reading file '<stdin>' as free form [-Werror]

(Plus the colors that you cannot see in this mail).

Bootstrapped and regression tested on x86_64-linux-gnu.

OK?

2014-08-03  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    PR fortran/44054
c-family/
    * c-format.c: Handle Fortran flags.
    * diagnostic.c (build_message_string): Make it extern.
    * diagnostic.h (build_message_string): Make it extern.
fortran/
    * gfortran.h: Define GCC_DIAG_STYLE.
    (gfc_diagnostics_init,gfc_warning_cmdline): Declare.
    * trans-array.c: Include gfortran.h before diagnostic-core.h.
    * trans-expr.c: Likewise.
    * trans-openmp.c: Likewise.
    * trans-const.c: Likewise.
    * trans.c: Likewise.
    * trans-types.c: Likewise.
    * f95-lang.c: Likewise.
    * trans-decl.c: Likewise.
    * trans-io.c: Likewise.
    * trans-intrinsic.c: Likewise.
    * error.c: Include diagnostic.h and diagnostic-color.h.
    (gfc_diagnostic_build_prefix): New.
    (gfc_diagnostic_starter): New.
    (gfc_diagnostic_finalizer): New.
    (gfc_warning_cmdline): New.
    (gfc_diagnostics_init): New.
    * gfc-diagnostic.def: New.
    * options.c (gfc_init_options): Call gfc_diagnostics_init.
    (gfc_post_options): Use gfc_warning_cmdline.

Comments

Dodji Seketeli Aug. 8, 2014, 10:25 a.m. UTC | #1
Hello Manuel,

Manuel López-Ibáñez <lopezibanez@gmail.com> writes:

> 2014-08-03  Manuel López-Ibáñez  <manu@gcc.gnu.org>
>
>     PR fortran/44054
> c-family/
>     * c-format.c: Handle Fortran flags.
>     * diagnostic.c (build_message_string): Make it extern.
>     * diagnostic.h (build_message_string): Make it extern.

Small nit; the diagnostic.[ch] files are in gcc/, not in c-family.

The language-agnostic diagnostic infrastructure changes otherwise look
OK to me.

Thanks.
Manuel López-Ibáñez Aug. 14, 2014, 8:09 p.m. UTC | #2
Hi Tobias (or any other Fortran maintainer),

Is this patch OK?

https://gcc.gnu.org/ml/gcc-patches/2014-08/msg00488.html

Thanks,

Manuel.
Tobias Burnus Aug. 15, 2014, 1:29 p.m. UTC | #3
Am 06.08.2014 18:50, schrieb Manuel López-Ibáñez:
> This is the first step for moving Fortran to use the common
> diagnostics machinery. This patch makes Fortran use the common
> machinery for those warnings that don't have a location or a
> controlling option.
> Bootstrapped and regression tested on x86_64-linux-gnu.
> OK?

Sorry for replying belated, I was in vacation and seemingly, a few 
others as well.

The patch looks good to me, except for gfc-diagnostic.def which contains 
the file content twice. With that fixed, the patch is OK. Thanks a lot!

Tobias

> 2014-08-03  Manuel López-Ibáñez  <manu@gcc.gnu.org>
>
>      PR fortran/44054
> c-family/
>      * c-format.c: Handle Fortran flags.
>      * diagnostic.c (build_message_string): Make it extern.
>      * diagnostic.h (build_message_string): Make it extern.
> fortran/
>      * gfortran.h: Define GCC_DIAG_STYLE.
>      (gfc_diagnostics_init,gfc_warning_cmdline): Declare.
>      * trans-array.c: Include gfortran.h before diagnostic-core.h.
>      * trans-expr.c: Likewise.
>      * trans-openmp.c: Likewise.
>      * trans-const.c: Likewise.
>      * trans.c: Likewise.
>      * trans-types.c: Likewise.
>      * f95-lang.c: Likewise.
>      * trans-decl.c: Likewise.
>      * trans-io.c: Likewise.
>      * trans-intrinsic.c: Likewise.
>      * error.c: Include diagnostic.h and diagnostic-color.h.
>      (gfc_diagnostic_build_prefix): New.
>      (gfc_diagnostic_starter): New.
>      (gfc_diagnostic_finalizer): New.
>      (gfc_warning_cmdline): New.
>      (gfc_diagnostics_init): New.
>      * gfc-diagnostic.def: New.
>      * options.c (gfc_init_options): Call gfc_diagnostics_init.
>      (gfc_post_options): Use gfc_warning_cmdline.

Patch
diff mbox

Index: gcc/c-family/c-format.c
===================================================================
--- gcc/c-family/c-format.c	(revision 213518)
+++ gcc/c-family/c-format.c	(working copy)
@@ -508,15 +508,11 @@  static const format_flag_pair gcc_diag_f
 };
 
 #define gcc_tdiag_flag_pairs gcc_diag_flag_pairs
 #define gcc_cdiag_flag_pairs gcc_diag_flag_pairs
 #define gcc_cxxdiag_flag_pairs gcc_diag_flag_pairs
-
-static const format_flag_pair gcc_gfc_flag_pairs[] =
-{
-  { 0, 0, 0, 0 }
-};
+#define gcc_gfc_flag_pairs gcc_diag_flag_pairs
 
 static const format_flag_spec gcc_diag_flag_specs[] =
 {
   { '+',  0, 0, N_("'+' flag"),        N_("the '+' printf flag"),              STD_C89 },
   { '#',  0, 0, N_("'#' flag"),        N_("the '#' printf flag"),              STD_C89 },
@@ -527,10 +523,11 @@  static const format_flag_spec gcc_diag_f
 };
 
 #define gcc_tdiag_flag_specs gcc_diag_flag_specs
 #define gcc_cdiag_flag_specs gcc_diag_flag_specs
 #define gcc_cxxdiag_flag_specs gcc_diag_flag_specs
+#define gcc_gfc_flag_specs gcc_diag_flag_specs
 
 static const format_flag_spec scanf_flag_specs[] =
 {
   { '*',  0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
   { 'a',  0, 0, N_("'a' flag"),               N_("the 'a' scanf flag"),                       STD_EXT },
@@ -739,19 +736,21 @@  static const format_char_info gcc_gfc_ch
 {
   /* C89 conversion specifiers.  */
   { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "", NULL },
   { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "", NULL },
   { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "", NULL },
-  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "cR", NULL },
+  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q", "cR", NULL },
 
   /* gfc conversion specifiers.  */
 
   { "C",   0, STD_C89, NOARGUMENTS, "",      "",   NULL },
 
   /* This will require a "locus" at runtime.  */
   { "L",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "R", NULL },
 
+  /* These will require nothing.  */
+  { "<>",0, STD_C89, NOARGUMENTS, "",      "",   NULL },
   { NULL,  0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
 };
 
 static const format_char_info scan_char_table[] =
 {
@@ -844,12 +843,12 @@  static const format_kind_info format_typ
     gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs,
     FMT_FLAG_ARG_CONVERT,
     0, 0, 'p', 0, 'L', 0,
     NULL, &integer_type_node
   },
-  { "gcc_gfc", gcc_gfc_length_specs, gcc_gfc_char_table, "", NULL,
-    NULL, gcc_gfc_flag_pairs,
+  { "gcc_gfc", gcc_gfc_length_specs, gcc_gfc_char_table, "q+#", NULL,
+    gcc_gfc_flag_specs, gcc_gfc_flag_pairs,
     FMT_FLAG_ARG_CONVERT,
     0, 0, 0, 0, 0, 0,
     NULL, NULL
   },
   { "NSString",   NULL,  NULL, NULL, NULL,
Index: gcc/diagnostic.c
===================================================================
--- gcc/diagnostic.c	(revision 213518)
+++ gcc/diagnostic.c	(working copy)
@@ -39,12 +39,10 @@  along with GCC; see the file COPYING3.
   ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING)
 #define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR)
 #define permissive_error_option(DC) ((DC)->opt_permissive)
 
 /* Prototypes.  */
-static char *build_message_string (const char *, ...) ATTRIBUTE_PRINTF_1;
-
 static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN;
 
 static void diagnostic_action_after_output (diagnostic_context *,
 					    diagnostic_info *);
 static void real_abort (void) ATTRIBUTE_NORETURN;
@@ -57,11 +55,11 @@  const char *progname;
 static diagnostic_context global_diagnostic_context;
 diagnostic_context *global_dc = &global_diagnostic_context;
 
 /* Return a malloc'd string containing MSG formatted a la printf.  The
    caller is responsible for freeing the memory.  */
-static char *
+char *
 build_message_string (const char *msg, ...)
 {
   char *str;
   va_list ap;
 
Index: gcc/diagnostic.h
===================================================================
--- gcc/diagnostic.h	(revision 213518)
+++ gcc/diagnostic.h	(working copy)
@@ -294,6 +294,9 @@  void diagnostic_set_caret_max_width (dia
 void diagnostic_file_cache_fini (void);
 
 /* Pure text formatting support functions.  */
 extern char *file_name_as_prefix (diagnostic_context *, const char *);
 
+extern char *build_message_string (const char *, ...) ATTRIBUTE_PRINTF_1;
+
+
 #endif /* ! GCC_DIAGNOSTIC_H */
Index: gcc/fortran/trans-array.c
===================================================================
--- gcc/fortran/trans-array.c	(revision 213518)
+++ gcc/fortran/trans-array.c	(working copy)
@@ -76,15 +76,15 @@  along with GCC; see the file COPYING3.
    is called to free all the SS allocated by the scalarizer.  */
 
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "gfortran.h"
 #include "tree.h"
 #include "gimple-expr.h"
 #include "diagnostic-core.h"	/* For internal_error/fatal_error.  */
 #include "flags.h"
-#include "gfortran.h"
 #include "constructor.h"
 #include "trans.h"
 #include "trans-stmt.h"
 #include "trans-types.h"
 #include "trans-array.h"
Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c	(revision 213518)
+++ gcc/fortran/trans-expr.c	(working copy)
@@ -22,16 +22,16 @@  along with GCC; see the file COPYING3.
 /* trans-expr.c-- generate GENERIC trees for gfc_expr.  */
 
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "gfortran.h"
 #include "tree.h"
 #include "stringpool.h"
 #include "diagnostic-core.h"	/* For fatal_error.  */
 #include "langhooks.h"
 #include "flags.h"
-#include "gfortran.h"
 #include "arith.h"
 #include "constructor.h"
 #include "trans.h"
 #include "trans-const.h"
 #include "trans-types.h"
Index: gcc/fortran/trans-openmp.c
===================================================================
--- gcc/fortran/trans-openmp.c	(revision 213518)
+++ gcc/fortran/trans-openmp.c	(working copy)
@@ -24,12 +24,12 @@  along with GCC; see the file COPYING3.
 #include "coretypes.h"
 #include "tree.h"
 #include "gimple-expr.h"
 #include "gimplify.h"	/* For create_tmp_var_raw.  */
 #include "stringpool.h"
-#include "diagnostic-core.h"	/* For internal_error.  */
 #include "gfortran.h"
+#include "diagnostic-core.h"	/* For internal_error.  */
 #include "trans.h"
 #include "trans-stmt.h"
 #include "trans-types.h"
 #include "trans-array.h"
 #include "trans-const.h"
Index: gcc/fortran/gfortran.h
===================================================================
--- gcc/fortran/gfortran.h	(revision 213518)
+++ gcc/fortran/gfortran.h	(working copy)
@@ -29,10 +29,23 @@  along with GCC; see the file COPYING3.
 
 #ifndef GCC_CORETYPES_H
 #error "gfortran.h must be included after coretypes.h"
 #endif
 
+/* In order for the format checking to accept the Fortran front end
+   diagnostic framework extensions, you must include this file before
+   diagnostic-core.h, not after.  We override the definition of GCC_DIAG_STYLE
+   in c-common.h.  */
+#undef GCC_DIAG_STYLE
+#define GCC_DIAG_STYLE __gcc_gfc__
+#if defined(GCC_DIAGNOSTIC_CORE_H)
+#error \
+In order for the format checking to accept the Fortran front end diagnostic \
+framework extensions, you must include this file before diagnostic-core.h, \
+not after.
+#endif
+
 /* Declarations common to the front-end and library are put in
    libgfortran/libgfortran_frontend.h  */
 #include "libgfortran.h"
 
 
@@ -2670,16 +2683,19 @@  typedef struct gfc_error_buf
   size_t allocated, index;
   char *message;
 } gfc_error_buf;
 
 void gfc_error_init_1 (void);
+void gfc_diagnostics_init(void);
 void gfc_buffer_error (int);
 
 const char *gfc_print_wide_char (gfc_char_t);
 
 void gfc_warning (const char *, ...) ATTRIBUTE_GCC_GFC(1,2);
 void gfc_warning_now (const char *, ...) ATTRIBUTE_GCC_GFC(1,2);
+void gfc_warning_cmdline (const char *gmsgid, ...) ATTRIBUTE_GCC_GFC(1,2);
+
 void gfc_clear_warning (void);
 void gfc_warning_check (void);
 
 void gfc_error (const char *, ...) ATTRIBUTE_GCC_GFC(1,2);
 void gfc_error_now (const char *, ...) ATTRIBUTE_GCC_GFC(1,2);
Index: gcc/fortran/error.c
===================================================================
--- gcc/fortran/error.c	(revision 213518)
+++ gcc/fortran/error.c	(working copy)
@@ -36,10 +36,12 @@  along with GCC; see the file COPYING3.
 
 #ifdef GWINSZ_IN_SYS_IOCTL
 # include <sys/ioctl.h>
 #endif
 
+#include "diagnostic.h"
+#include "diagnostic-color.h"
 
 static int suppress_errors = 0;
 
 static int warnings_not_errors = 0; 
 
@@ -954,10 +956,87 @@  gfc_warning_now (const char *gmsgid, ...
     gfc_increment_error_count();
 
   buffer_flag = i;
 }
 
+/* Return a malloc'd string describing a location.  The caller is
+   responsible for freeing the memory.  */
+static char *
+gfc_diagnostic_build_prefix (diagnostic_context *context,
+			     const diagnostic_info *diagnostic)
+{
+  static const char *const diagnostic_kind_text[] = {
+#define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
+#include "gfc-diagnostic.def"
+#undef DEFINE_DIAGNOSTIC_KIND
+    "must-not-happen"
+  };
+  static const char *const diagnostic_kind_color[] = {
+#define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
+#include "gfc-diagnostic.def"
+#undef DEFINE_DIAGNOSTIC_KIND
+    NULL
+  };
+  gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND);
+  const char *text = _(diagnostic_kind_text[diagnostic->kind]);
+  const char *text_cs = "", *text_ce = "";
+  pretty_printer *pp = context->printer;
+
+  if (diagnostic_kind_color[diagnostic->kind])
+    {
+      text_cs = colorize_start (pp_show_color (pp),
+				diagnostic_kind_color[diagnostic->kind]);
+      text_ce = colorize_stop (pp_show_color (pp));
+    }
+  const char *locus_cs = colorize_start (pp_show_color (pp), "locus");
+  const char *locus_ce = colorize_stop (pp_show_color (pp));
+
+  expanded_location s = expand_location_to_spelling_point (diagnostic->location);
+  if (diagnostic->override_column)
+    s.column = diagnostic->override_column;
+
+  return (s.file == NULL
+	  ? build_message_string ("%s%s:%s %s%s%s: ", locus_cs, progname, locus_ce,
+				  text_cs, text, text_ce)
+	  : !strcmp (s.file, N_("<built-in>"))
+	  ? build_message_string ("%s%s:%s %s%s%s: ", locus_cs, s.file, locus_ce,
+			     text_cs, text, text_ce)
+	  : context->show_column
+	  ? build_message_string ("%s%s:%d:%d:%s %s%s%s: ", locus_cs, s.file, s.line,
+				  s.column, locus_ce, text_cs, text, text_ce)
+	  : build_message_string ("%s%s:%d:%s %s%s%s: ", locus_cs, s.file, s.line, locus_ce,
+				  text_cs, text, text_ce));
+}
+
+static void
+gfc_diagnostic_starter (diagnostic_context *context,
+			diagnostic_info *diagnostic)
+{
+  pp_set_prefix (context->printer, gfc_diagnostic_build_prefix (context,
+								diagnostic));
+}
+
+static void
+gfc_diagnostic_finalizer (diagnostic_context *context ATTRIBUTE_UNUSED,
+			  diagnostic_info *diagnostic ATTRIBUTE_UNUSED)
+{
+}
+
+/* Give a warning about the command-line.  */
+
+void
+gfc_warning_cmdline (const char *gmsgid, ...)
+{
+  va_list argp;
+  diagnostic_info diagnostic;
+
+  va_start (argp, gmsgid);
+  diagnostic_set_info (&diagnostic, gmsgid, &argp, UNKNOWN_LOCATION,
+		       DK_WARNING);
+  report_diagnostic (&diagnostic);
+  va_end (argp);
+}
 
 /* Clear the warning flag.  */
 
 void
 gfc_clear_warning (void)
@@ -1203,5 +1282,12 @@  gfc_get_errors (int *w, int *e)
 void
 gfc_errors_to_warnings (int f)
 {
   warnings_not_errors = (f == 1) ? 1 : 0;
 }
+
+void
+gfc_diagnostics_init (void)
+{
+  diagnostic_starter (global_dc) = gfc_diagnostic_starter;
+  diagnostic_finalizer (global_dc) = gfc_diagnostic_finalizer;
+}
Index: gcc/fortran/gfc-diagnostic.def
===================================================================
--- gcc/fortran/gfc-diagnostic.def	(revision 0)
+++ gcc/fortran/gfc-diagnostic.def	(revision 0)
@@ -0,0 +1,94 @@ 
+/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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 3, or (at your option) any later
+version.
+
+GCC 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 GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+/* DK_UNSPECIFIED must be first so it has a value of zero.  We never
+   assign this kind to an actual diagnostic, we only use this in
+   variables that can hold a kind, to mean they have yet to have a
+   kind specified.  I.e. they're uninitialized.  Within the diagnostic
+   machinery, this kind also means "don't change the existing kind",
+   meaning "no change is specified".  */
+DEFINE_DIAGNOSTIC_KIND (DK_UNSPECIFIED, "", NULL)
+
+/* If a diagnostic is set to DK_IGNORED, it won't get reported at all.
+   This is used by the diagnostic machinery when it wants to disable a
+   diagnostic without disabling the option which causes it.  */
+DEFINE_DIAGNOSTIC_KIND (DK_IGNORED, "", NULL)
+
+/* The remainder are real diagnostic types.  */
+DEFINE_DIAGNOSTIC_KIND (DK_FATAL, "fatal error", "error")
+DEFINE_DIAGNOSTIC_KIND (DK_ICE, "internal compiler error", "error")
+DEFINE_DIAGNOSTIC_KIND (DK_ERROR, "Error", "error")
+DEFINE_DIAGNOSTIC_KIND (DK_SORRY, "sorry, unimplemented", "error")
+DEFINE_DIAGNOSTIC_KIND (DK_WARNING, "Warning", "warning")
+DEFINE_DIAGNOSTIC_KIND (DK_ANACHRONISM, "anachronism", "warning")
+DEFINE_DIAGNOSTIC_KIND (DK_NOTE, "note", "note")
+DEFINE_DIAGNOSTIC_KIND (DK_DEBUG, "debug", "note")
+/* These two would be re-classified as DK_WARNING or DK_ERROR, so the
+prefix does not matter.  */
+DEFINE_DIAGNOSTIC_KIND (DK_PEDWARN, "pedwarn", NULL)
+DEFINE_DIAGNOSTIC_KIND (DK_PERMERROR, "permerror", NULL)
+/* This one is just for counting DK_WARNING promoted to DK_ERROR
+   due to -Werror and -Werror=warning.  */
+DEFINE_DIAGNOSTIC_KIND (DK_WERROR, "error", NULL)
+/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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 3, or (at your option) any later
+version.
+
+GCC 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 GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+/* DK_UNSPECIFIED must be first so it has a value of zero.  We never
+   assign this kind to an actual diagnostic, we only use this in
+   variables that can hold a kind, to mean they have yet to have a
+   kind specified.  I.e. they're uninitialized.  Within the diagnostic
+   machinery, this kind also means "don't change the existing kind",
+   meaning "no change is specified".  */
+DEFINE_DIAGNOSTIC_KIND (DK_UNSPECIFIED, "", NULL)
+
+/* If a diagnostic is set to DK_IGNORED, it won't get reported at all.
+   This is used by the diagnostic machinery when it wants to disable a
+   diagnostic without disabling the option which causes it.  */
+DEFINE_DIAGNOSTIC_KIND (DK_IGNORED, "", NULL)
+
+/* The remainder are real diagnostic types.  */
+DEFINE_DIAGNOSTIC_KIND (DK_FATAL, "fatal error", "error")
+DEFINE_DIAGNOSTIC_KIND (DK_ICE, "internal compiler error", "error")
+DEFINE_DIAGNOSTIC_KIND (DK_ERROR, "Error", "error")
+DEFINE_DIAGNOSTIC_KIND (DK_SORRY, "sorry, unimplemented", "error")
+DEFINE_DIAGNOSTIC_KIND (DK_WARNING, "Warning", "warning")
+DEFINE_DIAGNOSTIC_KIND (DK_ANACHRONISM, "anachronism", "warning")
+DEFINE_DIAGNOSTIC_KIND (DK_NOTE, "note", "note")
+DEFINE_DIAGNOSTIC_KIND (DK_DEBUG, "debug", "note")
+/* These two would be re-classified as DK_WARNING or DK_ERROR, so the
+prefix does not matter.  */
+DEFINE_DIAGNOSTIC_KIND (DK_PEDWARN, "pedwarn", NULL)
+DEFINE_DIAGNOSTIC_KIND (DK_PERMERROR, "permerror", NULL)
+/* This one is just for counting DK_WARNING promoted to DK_ERROR
+   due to -Werror and -Werror=warning.  */
+DEFINE_DIAGNOSTIC_KIND (DK_WERROR, "error", NULL)
Index: gcc/fortran/trans-const.c
===================================================================
--- gcc/fortran/trans-const.c	(revision 213518)
+++ gcc/fortran/trans-const.c	(working copy)
@@ -21,16 +21,16 @@  along with GCC; see the file COPYING3.
 /* trans-const.c -- convert constant values */
 
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "gfortran.h"
 #include "tree.h"
 #include "stor-layout.h"
 #include "realmpfr.h"
 #include "diagnostic-core.h"	/* For fatal_error.  */
 #include "double-int.h"
-#include "gfortran.h"
 #include "trans.h"
 #include "trans-const.h"
 #include "trans-types.h"
 #include "target-memory.h"
 #include "wide-int.h"
Index: gcc/fortran/trans.c
===================================================================
--- gcc/fortran/trans.c	(revision 213518)
+++ gcc/fortran/trans.c	(working copy)
@@ -19,17 +19,17 @@  along with GCC; see the file COPYING3.
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "gfortran.h"
 #include "tree.h"
 #include "gimple-expr.h"	/* For create_tmp_var_raw.  */
 #include "stringpool.h"
 #include "tree-iterator.h"
 #include "diagnostic-core.h"  /* For internal_error.  */
 #include "flags.h"
-#include "gfortran.h"
 #include "trans.h"
 #include "trans-stmt.h"
 #include "trans-array.h"
 #include "trans-types.h"
 #include "trans-const.h"
Index: gcc/fortran/trans-types.c
===================================================================
--- gcc/fortran/trans-types.c	(revision 213518)
+++ gcc/fortran/trans-types.c	(working copy)
@@ -37,13 +37,13 @@  along with GCC; see the file COPYING3.
 #include "stor-layout.h"
 #include "stringpool.h"
 #include "langhooks.h"	/* For iso-c-bindings.def.  */
 #include "target.h"
 #include "ggc.h"
+#include "gfortran.h"
 #include "diagnostic-core.h"  /* For fatal_error.  */
 #include "toplev.h"	/* For rest_of_decl_compilation.  */
-#include "gfortran.h"
 #include "trans.h"
 #include "trans-types.h"
 #include "trans-const.h"
 #include "flags.h"
 #include "dwarf2out.h"	/* For struct array_descr_info.  */
Index: gcc/fortran/f95-lang.c
===================================================================
--- gcc/fortran/f95-lang.c	(revision 213518)
+++ gcc/fortran/f95-lang.c	(working copy)
@@ -25,10 +25,11 @@  along with GCC; see the file COPYING3.
 #include "config.h"
 #include "system.h"
 #include "ansidecl.h"
 #include "system.h"
 #include "coretypes.h"
+#include "gfortran.h"
 #include "tree.h"
 #include "flags.h"
 #include "langhooks.h"
 #include "langhooks-def.h"
 #include "timevar.h"
@@ -36,14 +37,13 @@  along with GCC; see the file COPYING3.
 #include "function.h"
 #include "ggc.h"
 #include "toplev.h"
 #include "target.h"
 #include "debug.h"
-#include "diagnostic.h"
+#include "diagnostic.h" /* For errorcount/warningcount */
 #include "dumpfile.h"
 #include "cgraph.h"
-#include "gfortran.h"
 #include "cpp.h"
 #include "trans.h"
 #include "trans-types.h"
 #include "trans-const.h"
 
Index: gcc/fortran/trans-decl.c
===================================================================
--- gcc/fortran/trans-decl.c	(revision 213518)
+++ gcc/fortran/trans-decl.c	(working copy)
@@ -22,10 +22,11 @@  along with GCC; see the file COPYING3.
 
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "gfortran.h"
 #include "tree.h"
 #include "stringpool.h"
 #include "stor-layout.h"
 #include "varasm.h"
 #include "attribs.h"
@@ -37,11 +38,10 @@  along with GCC; see the file COPYING3.
 #include "target.h"
 #include "function.h"
 #include "flags.h"
 #include "cgraph.h"
 #include "debug.h"
-#include "gfortran.h"
 #include "hash-set.h"
 #include "constructor.h"
 #include "trans.h"
 #include "trans-types.h"
 #include "trans-array.h"
Index: gcc/fortran/trans-io.c
===================================================================
--- gcc/fortran/trans-io.c	(revision 213518)
+++ gcc/fortran/trans-io.c	(working copy)
@@ -24,12 +24,12 @@  along with GCC; see the file COPYING3.
 #include "coretypes.h"
 #include "tree.h"
 #include "stringpool.h"
 #include "stor-layout.h"
 #include "ggc.h"
-#include "diagnostic-core.h"	/* For internal_error.  */
 #include "gfortran.h"
+#include "diagnostic-core.h"	/* For internal_error.  */
 #include "trans.h"
 #include "trans-stmt.h"
 #include "trans-array.h"
 #include "trans-types.h"
 #include "trans-const.h"
Index: gcc/fortran/trans-intrinsic.c
===================================================================
--- gcc/fortran/trans-intrinsic.c	(revision 213518)
+++ gcc/fortran/trans-intrinsic.c	(working copy)
@@ -28,14 +28,14 @@  along with GCC; see the file COPYING3.
 #include "tree.h"
 #include "stringpool.h"
 #include "tree-nested.h"
 #include "stor-layout.h"
 #include "ggc.h"
+#include "gfortran.h"
 #include "diagnostic-core.h"	/* For internal_error.  */
 #include "toplev.h"	/* For rest_of_decl_compilation.  */
 #include "flags.h"
-#include "gfortran.h"
 #include "arith.h"
 #include "intrinsic.h"
 #include "trans.h"
 #include "trans-const.h"
 #include "trans-types.h"
Index: gcc/fortran/options.c
===================================================================
--- gcc/fortran/options.c	(revision 213518)
+++ gcc/fortran/options.c	(working copy)
@@ -171,10 +171,11 @@  gfc_init_options (unsigned int decoded_o
 
   set_default_std_flags ();
 
   /* Initialize cpp-related options.  */
   gfc_cpp_init_options (decoded_options_count, decoded_options);
+  gfc_diagnostics_init ();
 }
 
 
 /* Determine the source form from the filename extension.  We assume
    case insensitivity.  */
@@ -350,24 +351,24 @@  gfc_post_options (const char **pfilename
       gfc_current_form = form_from_filename (filename);
 
       if (gfc_current_form == FORM_UNKNOWN)
 	{
 	  gfc_current_form = FORM_FREE;
-	  gfc_warning_now ("Reading file '%s' as free form", 
-			   (filename[0] == '\0') ? "<stdin>" : filename);
+	  gfc_warning_cmdline ("Reading file %qs as free form", 
+			       (filename[0] == '\0') ? "<stdin>" : filename);
 	}
     }
 
   /* If the user specified -fd-lines-as-{code|comments} verify that we're
      in fixed form.  */
   if (gfc_current_form == FORM_FREE)
     {
       if (gfc_option.flag_d_lines == 0)
-	gfc_warning_now ("'-fd-lines-as-comments' has no effect "
-			 "in free form");
+	gfc_warning_cmdline ("%<-fd-lines-as-comments%> has no effect "
+			     "in free form");
       else if (gfc_option.flag_d_lines == 1)
-	gfc_warning_now ("'-fd-lines-as-code' has no effect in free form");
+	gfc_warning_cmdline ("%<-fd-lines-as-code%> has no effect in free form");
     }
 
   /* If -pedantic, warn about the use of GNU extensions.  */
   if (pedantic && (gfc_option.allow_std & GFC_STD_GNU) != 0)
     gfc_option.warn_std |= GFC_STD_GNU;
@@ -381,25 +382,25 @@  gfc_post_options (const char **pfilename
   if (gfc_option.flag_second_underscore == -1)
     gfc_option.flag_second_underscore = gfc_option.flag_f2c;
 
   if (!gfc_option.flag_automatic && gfc_option.flag_max_stack_var_size != -2
       && gfc_option.flag_max_stack_var_size != 0)
-    gfc_warning_now ("Flag -fno-automatic overwrites -fmax-stack-var-size=%d",
-		     gfc_option.flag_max_stack_var_size);
+    gfc_warning_cmdline ("Flag %<-fno-automatic%> overwrites %<-fmax-stack-var-size=%d%>",
+			 gfc_option.flag_max_stack_var_size);
   else if (!gfc_option.flag_automatic && gfc_option.flag_recursive)
-    gfc_warning_now ("Flag -fno-automatic overwrites -frecursive");
+    gfc_warning_cmdline ("Flag %<-fno-automatic%> overwrites %<-frecursive%>");
   else if (!gfc_option.flag_automatic && gfc_option.gfc_flag_openmp)
-    gfc_warning_now ("Flag -fno-automatic overwrites -frecursive implied by "
-		     "-fopenmp");
+    gfc_warning_cmdline ("Flag %<-fno-automatic%> overwrites %<-frecursive%> implied by "
+			 "%<-fopenmp%>");
   else if (gfc_option.flag_max_stack_var_size != -2
 	   && gfc_option.flag_recursive)
-    gfc_warning_now ("Flag -frecursive overwrites -fmax-stack-var-size=%d",
-		     gfc_option.flag_max_stack_var_size);
+    gfc_warning_cmdline ("Flag %<-frecursive%> overwrites %<-fmax-stack-var-size=%d%>",
+			 gfc_option.flag_max_stack_var_size);
   else if (gfc_option.flag_max_stack_var_size != -2
 	   && gfc_option.gfc_flag_openmp)
-    gfc_warning_now ("Flag -fmax-stack-var-size=%d overwrites -frecursive "
-		     "implied by -fopenmp", 
+    gfc_warning_cmdline ("Flag %<-fmax-stack-var-size=%d%> overwrites %<-frecursive%> "
+			 "implied by %<-fopenmp%>", 
 		     gfc_option.flag_max_stack_var_size);
 
   /* Implement -frecursive as -fmax-stack-var-size=-1.  */
   if (gfc_option.flag_recursive)
     gfc_option.flag_max_stack_var_size = -1;