https://gcc.gnu.org/g:0654c543363d935e19f2088dffc655688de35be6

commit r16-2535-g0654c543363d935e19f2088dffc655688de35be6
Author: David Malcolm <dmalc...@redhat.com>
Date:   Fri Jul 25 15:13:39 2025 -0400

    diagnostics: move option_classifier to its own files
    
    No functional change intended.
    
    gcc/ChangeLog:
            * Makefile.in (OBJS-libcommon): Add
            diagnostics/option-classifier.o.
            * diagnostic.cc (diagnostics::option_classifier::init): Move to
            diagnostics/option-classifier.cc.
            (diagnostics::option_classifier::fini): Likewise.
            (diagnostics::option_classifier::pch_save): Likewise.
            (diagnostics::option_classifier::pch_restore): Likewise.
            (diagnostics::option_classifier::push): Likewise.
            (diagnostics::option_classifier::pop): Likewise.
            (diagnostics::option_classifier::classify_diagnostic): Likewise.
            
(diagnostics::option_classifier::update_effective_level_from_pragmas):
            Likewise.
            * diagnostics/context.h: Include
            "diagnostics/option-classifier.h".
            (class option_classifier): Move to
            diagnostics/option-classifier.h.
            * diagnostics/option-classifier.cc: New file, based on material
            from diagnostic.cc.
            * diagnostics/option-classifier.h: New file, based on material
            from diagnostics/context.h.
    
    Signed-off-by: David Malcolm <dmalc...@redhat.com>

Diff:
---
 gcc/Makefile.in                      |   1 +
 gcc/diagnostic.cc                    | 193 ------------------------------
 gcc/diagnostics/context.h            |  82 +------------
 gcc/diagnostics/option-classifier.cc | 222 +++++++++++++++++++++++++++++++++++
 gcc/diagnostics/option-classifier.h  | 110 +++++++++++++++++
 5 files changed, 335 insertions(+), 273 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index a7c184ceae0e..9a867b72ab67 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1861,6 +1861,7 @@ OBJS-libcommon = diagnostic-spec.o diagnostic.o 
diagnostic-color.o \
        diagnostics/sarif-sink.o \
        diagnostics/text-sink.o \
        diagnostics/macro-unwinding.o \
+       diagnostics/option-classifier.o \
        diagnostics/paths.o \
        diagnostics/paths-output.o \
        diagnostics/source-printing.o \
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 847464d1e5f0..9aecd0653cc9 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -126,95 +126,6 @@ diagnostic_set_caret_max_width (diagnostics::context 
*context, int value)
   context->m_source_printing.max_width = value;
 }
 
-void
-diagnostics::option_classifier::init (int n_opts)
-{
-  m_n_opts = n_opts;
-  m_classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
-  for (int i = 0; i < n_opts; i++)
-    m_classify_diagnostic[i] = DK_UNSPECIFIED;
-  m_push_list = vNULL;
-  m_classification_history = vNULL;
-}
-
-void
-diagnostics::option_classifier::fini ()
-{
-  XDELETEVEC (m_classify_diagnostic);
-  m_classify_diagnostic = nullptr;
-  m_classification_history.release ();
-  m_push_list.release ();
-}
-
-/* Save the diagnostics::option_classifier state to F for PCH
-   output.  Returns 0 on success, -1 on error.  */
-
-int
-diagnostics::option_classifier::pch_save (FILE *f)
-{
-  unsigned int lengths[2] = { m_classification_history.length (),
-                             m_push_list.length () };
-  if (fwrite (lengths, sizeof (lengths), 1, f) != 1
-      || (lengths[0]
-         && fwrite (m_classification_history.address (),
-                    sizeof (classification_change_t),
-                    lengths[0], f) != lengths[0])
-      || (lengths[1]
-         && fwrite (m_push_list.address (), sizeof (int),
-                    lengths[1], f) != lengths[1]))
-    return -1;
-  return 0;
-}
-
-/* Read the diagnostics::option_classifier state from F for PCH
-   read.  Returns 0 on success, -1 on error.  */
-
-int
-diagnostics::option_classifier::pch_restore (FILE *f)
-{
-  unsigned int lengths[2];
-  if (fread (lengths, sizeof (lengths), 1, f) != 1)
-    return -1;
-  gcc_checking_assert (m_classification_history.is_empty ());
-  gcc_checking_assert (m_push_list.is_empty ());
-  m_classification_history.safe_grow (lengths[0]);
-  m_push_list.safe_grow (lengths[1]);
-  if ((lengths[0]
-       && fread (m_classification_history.address (),
-                sizeof (classification_change_t),
-                lengths[0], f) != lengths[0])
-      || (lengths[1]
-         && fread (m_push_list.address (), sizeof (int),
-                   lengths[1], f) != lengths[1]))
-    return -1;
-  return 0;
-}
-
-/* Save all diagnostic classifications in a stack.  */
-
-void
-diagnostics::option_classifier::push ()
-{
-  m_push_list.safe_push (m_classification_history.length ());
-}
-
-/* Restore the topmost classification set off the stack.  If the stack
-   is empty, revert to the state based on command line parameters.  */
-
-void
-diagnostics::option_classifier::pop (location_t where)
-{
-  int jump_to;
-
-  if (!m_push_list.is_empty ())
-    jump_to = m_push_list.pop ();
-  else
-    jump_to = 0;
-
-  classification_change_t v = { where, jump_to, DK_POP };
-  m_classification_history.safe_push (v);
-}
-
 /* Initialize the diagnostic message outputting machinery.  */
 
 void
@@ -1078,58 +989,6 @@ diagnostics::logical_locations::manager::function_p (key 
k) const
     }
 }
 
-/* Interface to specify diagnostic kind overrides.  Returns the
-   previous setting, or DK_UNSPECIFIED if the parameters are out of
-   range.  If OPTION_ID is zero, the new setting is for all the
-   diagnostics.  */
-diagnostic_t
-diagnostics::option_classifier::
-classify_diagnostic (const diagnostics::context *context,
-                    diagnostic_option_id option_id,
-                    diagnostic_t new_kind,
-                    location_t where)
-{
-  diagnostic_t old_kind;
-
-  if (option_id.m_idx < 0
-      || option_id.m_idx >= m_n_opts
-      || new_kind >= DK_LAST_DIAGNOSTIC_KIND)
-    return DK_UNSPECIFIED;
-
-  old_kind = m_classify_diagnostic[option_id.m_idx];
-
-  /* Handle pragmas separately, since we need to keep track of *where*
-     the pragmas were.  */
-  if (where != UNKNOWN_LOCATION)
-    {
-      unsigned i;
-
-      /* Record the command-line status, so we can reset it back on DK_POP. */
-      if (old_kind == DK_UNSPECIFIED)
-       {
-         old_kind = (!context->option_enabled_p (option_id)
-                     ? DK_IGNORED : DK_ANY);
-         m_classify_diagnostic[option_id.m_idx] = old_kind;
-       }
-
-      classification_change_t *p;
-      FOR_EACH_VEC_ELT_REVERSE (m_classification_history, i, p)
-       if (p->option == option_id.m_idx)
-         {
-           old_kind = p->kind;
-           break;
-         }
-
-      classification_change_t v
-       = { where, option_id.m_idx, new_kind };
-      m_classification_history.safe_push (v);
-    }
-  else
-    m_classify_diagnostic[option_id.m_idx] = new_kind;
-
-  return old_kind;
-}
-
 /* Helper function for print_parseable_fixits.  Print TEXT to PP, obeying the
    escaping rules for -fdiagnostics-parseable-fixits.  */
 
@@ -1239,58 +1098,6 @@ diagnostics::context::get_any_inlining_info 
(diagnostic_info *diagnostic)
     }
 }
 
-/* Update the kind of DIAGNOSTIC based on its location(s), including
-   any of those in its inlining stack, relative to any
-     #pragma GCC diagnostic
-   directives recorded within this object.
-
-   Return the new kind of DIAGNOSTIC if it was updated, or DK_UNSPECIFIED
-   otherwise.  */
-
-diagnostic_t
-diagnostics::option_classifier::
-update_effective_level_from_pragmas (diagnostic_info *diagnostic) const
-{
-  if (m_classification_history.is_empty ())
-    return DK_UNSPECIFIED;
-
-  /* Iterate over the locations, checking the diagnostic disposition
-     for the diagnostic at each.  If it's explicitly set as opposed
-     to unspecified, update the disposition for this instance of
-     the diagnostic and return it.  */
-  for (location_t loc: diagnostic->m_iinfo.m_ilocs)
-    {
-      /* FIXME: Stupid search.  Optimize later. */
-      unsigned int i;
-      classification_change_t *p;
-      FOR_EACH_VEC_ELT_REVERSE (m_classification_history, i, p)
-       {
-         location_t pragloc = p->location;
-         if (!linemap_location_before_p (line_table, pragloc, loc))
-           continue;
-
-         if (p->kind == (int) DK_POP)
-           {
-             /* Move on to the next region.  */
-             i = p->option;
-             continue;
-           }
-
-         diagnostic_option_id option = p->option;
-         /* The option 0 is for all the diagnostics.  */
-         if (option == 0 || option == diagnostic->m_option_id)
-           {
-             diagnostic_t kind = p->kind;
-             if (kind != DK_UNSPECIFIED)
-               diagnostic->m_kind = kind;
-             return kind;
-           }
-       }
-    }
-
-  return DK_UNSPECIFIED;
-}
-
 /* Generate a URL string describing CWE.  The caller is responsible for
    freeing the string.  */
 
diff --git a/gcc/diagnostics/context.h b/gcc/diagnostics/context.h
index 21688439aaa5..9dee03342b2a 100644
--- a/gcc/diagnostics/context.h
+++ b/gcc/diagnostics/context.h
@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_DIAGNOSTICS_CONTEXT_H
 #define GCC_DIAGNOSTICS_CONTEXT_H
 
+#include "diagnostics/option-classifier.h"
+
 namespace diagnostics {
 
 /*  Forward declarations.  */
@@ -73,86 +75,6 @@ public:
   virtual char *make_option_url (diagnostic_option_id option_id) const = 0;
 };
 
-/* A stack of sets of classifications: each entry in the stack is
-   a mapping from option index to diagnostic severity that can be changed
-   via pragmas.  The stack can be pushed and popped.  */
-
-class option_classifier
-{
-public:
-  void init (int n_opts);
-  void fini ();
-
-  /* Save all diagnostic classifications in a stack.  */
-  void push ();
-
-  /* Restore the topmost classification set off the stack.  If the stack
-     is empty, revert to the state based on command line parameters.  */
-  void pop (location_t where);
-
-  bool option_unspecified_p (diagnostic_option_id option_id) const
-  {
-    return get_current_override (option_id) == DK_UNSPECIFIED;
-  }
-
-  diagnostic_t get_current_override (diagnostic_option_id option_id) const
-  {
-    gcc_assert (option_id.m_idx < m_n_opts);
-    return m_classify_diagnostic[option_id.m_idx];
-  }
-
-  diagnostic_t
-  classify_diagnostic (const context *context,
-                      diagnostic_option_id option_id,
-                      diagnostic_t new_kind,
-                      location_t where);
-
-  diagnostic_t
-  update_effective_level_from_pragmas (diagnostic_info *diagnostic) const;
-
-  int pch_save (FILE *);
-  int pch_restore (FILE *);
-
-private:
-  /* Each time a diagnostic's classification is changed with a pragma,
-     we record the change and the location of the change in an array of
-     these structs.  */
-  struct classification_change_t
-  {
-    location_t location;
-
-    /* For DK_POP, this is the index of the corresponding push (as stored
-       in m_push_list).
-       Otherwise, this is an option index.  */
-    int option;
-
-    diagnostic_t kind;
-  };
-
-  int m_n_opts;
-
-  /* For each option index that can be passed to warning() et al
-     (OPT_* from options.h when using this code with the core GCC
-     options), this array may contain a new kind that the diagnostic
-     should be changed to before reporting, or DK_UNSPECIFIED to leave
-     it as the reported kind, or DK_IGNORED to not report it at
-     all.  */
-  diagnostic_t *m_classify_diagnostic;
-
-  /* History of all changes to the classifications above.  This list
-     is stored in location-order, so we can search it, either
-     binary-wise or end-to-front, to find the most recent
-     classification for a given diagnostic, given the location of the
-     diagnostic.  */
-  vec<classification_change_t> m_classification_history;
-
-  /* For context::get_classification_history, declared later.  */
-  friend class context;
-
-  /* For pragma push/pop.  */
-  vec<int> m_push_list;
-};
-
 /* A bundle of options relating to printing the user's source code
    (potentially with a margin, underlining, labels, etc).  */
 
diff --git a/gcc/diagnostics/option-classifier.cc 
b/gcc/diagnostics/option-classifier.cc
new file mode 100644
index 000000000000..77bce36a7302
--- /dev/null
+++ b/gcc/diagnostics/option-classifier.cc
@@ -0,0 +1,222 @@
+/* Stacks of set of classifications of diagnostics.
+   Copyright (C) 1999-2025 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/>.  */
+
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "version.h"
+#include "diagnostic.h"
+
+namespace diagnostics {
+
+void
+option_classifier::init (int n_opts)
+{
+  m_n_opts = n_opts;
+  m_classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
+  for (int i = 0; i < n_opts; i++)
+    m_classify_diagnostic[i] = DK_UNSPECIFIED;
+  m_push_list = vNULL;
+  m_classification_history = vNULL;
+}
+
+void
+option_classifier::fini ()
+{
+  XDELETEVEC (m_classify_diagnostic);
+  m_classify_diagnostic = nullptr;
+  m_classification_history.release ();
+  m_push_list.release ();
+}
+
+/* Save the diagnostics::option_classifier state to F for PCH
+   output.  Returns 0 on success, -1 on error.  */
+
+int
+option_classifier::pch_save (FILE *f)
+{
+  unsigned int lengths[2] = { m_classification_history.length (),
+                             m_push_list.length () };
+  if (fwrite (lengths, sizeof (lengths), 1, f) != 1
+      || (lengths[0]
+         && fwrite (m_classification_history.address (),
+                    sizeof (classification_change_t),
+                    lengths[0], f) != lengths[0])
+      || (lengths[1]
+         && fwrite (m_push_list.address (), sizeof (int),
+                    lengths[1], f) != lengths[1]))
+    return -1;
+  return 0;
+}
+
+/* Read the diagnostics::option_classifier state from F for PCH
+   read.  Returns 0 on success, -1 on error.  */
+
+int
+option_classifier::pch_restore (FILE *f)
+{
+  unsigned int lengths[2];
+  if (fread (lengths, sizeof (lengths), 1, f) != 1)
+    return -1;
+  gcc_checking_assert (m_classification_history.is_empty ());
+  gcc_checking_assert (m_push_list.is_empty ());
+  m_classification_history.safe_grow (lengths[0]);
+  m_push_list.safe_grow (lengths[1]);
+  if ((lengths[0]
+       && fread (m_classification_history.address (),
+                sizeof (classification_change_t),
+                lengths[0], f) != lengths[0])
+      || (lengths[1]
+         && fread (m_push_list.address (), sizeof (int),
+                   lengths[1], f) != lengths[1]))
+    return -1;
+  return 0;
+}
+
+/* Save all diagnostic classifications in a stack.  */
+
+void
+option_classifier::push ()
+{
+  m_push_list.safe_push (m_classification_history.length ());
+}
+
+/* Restore the topmost classification set off the stack.  If the stack
+   is empty, revert to the state based on command line parameters.  */
+
+void
+option_classifier::pop (location_t where)
+{
+  int jump_to;
+
+  if (!m_push_list.is_empty ())
+    jump_to = m_push_list.pop ();
+  else
+    jump_to = 0;
+
+  classification_change_t v = { where, jump_to, DK_POP };
+  m_classification_history.safe_push (v);
+}
+
+/* Interface to specify diagnostic kind overrides.  Returns the
+   previous setting, or DK_UNSPECIFIED if the parameters are out of
+   range.  If OPTION_ID is zero, the new setting is for all the
+   diagnostics.  */
+
+diagnostic_t
+option_classifier::classify_diagnostic (const context *dc,
+                                       diagnostic_option_id option_id,
+                                       diagnostic_t new_kind,
+                                       location_t where)
+{
+  diagnostic_t old_kind;
+
+  if (option_id.m_idx < 0
+      || option_id.m_idx >= m_n_opts
+      || new_kind >= DK_LAST_DIAGNOSTIC_KIND)
+    return DK_UNSPECIFIED;
+
+  old_kind = m_classify_diagnostic[option_id.m_idx];
+
+  /* Handle pragmas separately, since we need to keep track of *where*
+     the pragmas were.  */
+  if (where != UNKNOWN_LOCATION)
+    {
+      unsigned i;
+
+      /* Record the command-line status, so we can reset it back on DK_POP. */
+      if (old_kind == DK_UNSPECIFIED)
+       {
+         old_kind = (!dc->option_enabled_p (option_id)
+                     ? DK_IGNORED : DK_ANY);
+         m_classify_diagnostic[option_id.m_idx] = old_kind;
+       }
+
+      classification_change_t *p;
+      FOR_EACH_VEC_ELT_REVERSE (m_classification_history, i, p)
+       if (p->option == option_id.m_idx)
+         {
+           old_kind = p->kind;
+           break;
+         }
+
+      classification_change_t v
+       = { where, option_id.m_idx, new_kind };
+      m_classification_history.safe_push (v);
+    }
+  else
+    m_classify_diagnostic[option_id.m_idx] = new_kind;
+
+  return old_kind;
+}
+
+/* Update the kind of DIAGNOSTIC based on its location(s), including
+   any of those in its inlining stack, relative to any
+     #pragma GCC diagnostic
+   directives recorded within this object.
+
+   Return the new kind of DIAGNOSTIC if it was updated, or DK_UNSPECIFIED
+   otherwise.  */
+
+diagnostic_t
+option_classifier::
+update_effective_level_from_pragmas (diagnostic_info *diagnostic) const
+{
+  if (m_classification_history.is_empty ())
+    return DK_UNSPECIFIED;
+
+  /* Iterate over the locations, checking the diagnostic disposition
+     for the diagnostic at each.  If it's explicitly set as opposed
+     to unspecified, update the disposition for this instance of
+     the diagnostic and return it.  */
+  for (location_t loc: diagnostic->m_iinfo.m_ilocs)
+    {
+      /* FIXME: Stupid search.  Optimize later. */
+      unsigned int i;
+      classification_change_t *p;
+      FOR_EACH_VEC_ELT_REVERSE (m_classification_history, i, p)
+       {
+         location_t pragloc = p->location;
+         if (!linemap_location_before_p (line_table, pragloc, loc))
+           continue;
+
+         if (p->kind == (int) DK_POP)
+           {
+             /* Move on to the next region.  */
+             i = p->option;
+             continue;
+           }
+
+         diagnostic_option_id option = p->option;
+         /* The option 0 is for all the diagnostics.  */
+         if (option == 0 || option == diagnostic->m_option_id)
+           {
+             diagnostic_t kind = p->kind;
+             if (kind != DK_UNSPECIFIED)
+               diagnostic->m_kind = kind;
+             return kind;
+           }
+       }
+    }
+
+  return DK_UNSPECIFIED;
+}
+
+} // namespace diagnostics
diff --git a/gcc/diagnostics/option-classifier.h 
b/gcc/diagnostics/option-classifier.h
new file mode 100644
index 000000000000..809449ee71c9
--- /dev/null
+++ b/gcc/diagnostics/option-classifier.h
@@ -0,0 +1,110 @@
+/* Stacks of set of classifications of diagnostics.
+   Copyright (C) 2000-2025 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/>.  */
+
+#ifndef GCC_DIAGNOSTICS_OPTION_CLASSIFIER_H
+#define GCC_DIAGNOSTICS_OPTION_CLASSIFIER_H
+
+namespace diagnostics {
+
+/*  Forward declarations.  */
+class context;
+
+/* A stack of sets of classifications: each entry in the stack is
+   a mapping from option index to diagnostic severity that can be changed
+   via pragmas.  The stack can be pushed and popped.  */
+
+class option_classifier
+{
+public:
+  void init (int n_opts);
+  void fini ();
+
+  /* Save all diagnostic classifications in a stack.  */
+  void push ();
+
+  /* Restore the topmost classification set off the stack.  If the stack
+     is empty, revert to the state based on command line parameters.  */
+  void pop (location_t where);
+
+  bool option_unspecified_p (diagnostic_option_id option_id) const
+  {
+    return get_current_override (option_id) == DK_UNSPECIFIED;
+  }
+
+  diagnostic_t get_current_override (diagnostic_option_id option_id) const
+  {
+    gcc_assert (option_id.m_idx < m_n_opts);
+    return m_classify_diagnostic[option_id.m_idx];
+  }
+
+  diagnostic_t
+  classify_diagnostic (const context *context,
+                      diagnostic_option_id option_id,
+                      diagnostic_t new_kind,
+                      location_t where);
+
+  diagnostic_t
+  update_effective_level_from_pragmas (diagnostic_info *diagnostic) const;
+
+  int pch_save (FILE *);
+  int pch_restore (FILE *);
+
+private:
+  /* Each time a diagnostic's classification is changed with a pragma,
+     we record the change and the location of the change in an array of
+     these structs.  */
+  struct classification_change_t
+  {
+    location_t location;
+
+    /* For DK_POP, this is the index of the corresponding push (as stored
+       in m_push_list).
+       Otherwise, this is an option index.  */
+    int option;
+
+    diagnostic_t kind;
+  };
+
+  int m_n_opts;
+
+  /* For each option index that can be passed to warning() et al
+     (OPT_* from options.h when using this code with the core GCC
+     options), this array may contain a new kind that the diagnostic
+     should be changed to before reporting, or DK_UNSPECIFIED to leave
+     it as the reported kind, or DK_IGNORED to not report it at
+     all.  */
+  diagnostic_t *m_classify_diagnostic;
+
+  /* History of all changes to the classifications above.  This list
+     is stored in location-order, so we can search it, either
+     binary-wise or end-to-front, to find the most recent
+     classification for a given diagnostic, given the location of the
+     diagnostic.  */
+  vec<classification_change_t> m_classification_history;
+
+  /* For context::get_classification_history, declared later.  */
+  friend class context;
+
+  /* For pragma push/pop.  */
+  vec<int> m_push_list;
+};
+
+} // namespace diagnostics
+
+#endif /* ! GCC_DIAGNOSTICS_OPTION_CLASSIFIER_H */

Reply via email to