Make this code usable elsewhere.
No functional change intended.

gcc/ChangeLog:
        * Makefile.in (OBJS-libcommon):
        Add diagnostics/physical-location-maker.o.
        * diagnostics/physical-location-maker.cc: New file, adapted from
        material in libgdiagnostics.cc.
        * diagnostics/physical-location-maker.h: New file, adapted from
        material in libgdiagnostics.cc.
        * libgdiagnostics.cc: Include
        "diagnostics/physical-location-maker.h".
        (diagnostic_manager::diagnostic_manager): Initialize
        m_phys_loc_maker.
        (diagnostic_manager::new_location_from_file_and_line): Split out
        into physical_location_maker.
        (diagnostic_manager::new_location_from_file_line_column):
        Likewise.
        (diagnostic_manager::ensure_linemap_for_file_and_line): Likewise.
        (diagnostic_manager::m_phys_loc_maker): New field.

Signed-off-by: David Malcolm <[email protected]>
---
 gcc/Makefile.in                            |  1 +
 gcc/diagnostics/physical-location-maker.cc | 75 ++++++++++++++++++++++
 gcc/diagnostics/physical-location-maker.h  | 60 +++++++++++++++++
 gcc/libgdiagnostics.cc                     | 41 ++++--------
 4 files changed, 147 insertions(+), 30 deletions(-)
 create mode 100644 gcc/diagnostics/physical-location-maker.cc
 create mode 100644 gcc/diagnostics/physical-location-maker.h

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 3d3b21abe6ac0..54865765b6ef6 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1895,6 +1895,7 @@ OBJS-libcommon = \
        diagnostics/option-classifier.o \
        diagnostics/paths.o \
        diagnostics/paths-output.o \
+       diagnostics/physical-location-maker.o \
        diagnostics/source-printing.o \
        diagnostics/state-graphs-to-dot.o \
        diagnostics/selftest-context.o \
diff --git a/gcc/diagnostics/physical-location-maker.cc 
b/gcc/diagnostics/physical-location-maker.cc
new file mode 100644
index 0000000000000..975687d739451
--- /dev/null
+++ b/gcc/diagnostics/physical-location-maker.cc
@@ -0,0 +1,75 @@
+/* Convenient but inefficient creation of location_t values.
+   Copyright (C) 2023-2026 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 "cpplib.h"
+#include "diagnostics/physical-location-maker.h"
+#include "diagnostics/dumping.h"
+
+namespace diagnostics {
+
+// class physical_location_maker
+
+location_t
+physical_location_maker::
+new_location_from_file_and_line (const char *filename,
+                                int line_num)
+{
+  ensure_linemap_for_file_and_line (filename, line_num);
+  return linemap_position_for_column (m_line_table, 0);
+}
+
+location_t
+physical_location_maker::
+new_location_from_file_line_column (const char *filename,
+                                   int line_num,
+                                   int column_num)
+{
+  ensure_linemap_for_file_and_line (filename, line_num);
+  return linemap_position_for_column (m_line_table, column_num);
+}
+
+void
+physical_location_maker::
+ensure_linemap_for_file_and_line (const char *filename,
+                                 int line_num)
+{
+  /* Build a simple linemap describing some locations. */
+  if (LINEMAPS_ORDINARY_USED (m_line_table) == 0)
+    linemap_add (m_line_table, LC_ENTER, false, filename, 0);
+  else
+    {
+      line_map_ordinary *last_map
+       = LINEMAPS_LAST_ORDINARY_MAP (m_line_table);
+      if (last_map->to_file != filename
+         || (long)line_num < (long)last_map->to_line)
+       {
+         line_map *map
+           = const_cast<line_map *>
+           (linemap_add (m_line_table, LC_RENAME_VERBATIM, false,
+                         filename, 0));
+         ((line_map_ordinary *)map)->included_from = UNKNOWN_LOCATION;
+       }
+    }
+  linemap_line_start (m_line_table, line_num, 100);
+}
+
+} // namespace diagnostics
diff --git a/gcc/diagnostics/physical-location-maker.h 
b/gcc/diagnostics/physical-location-maker.h
new file mode 100644
index 0000000000000..f5d568c5f82cc
--- /dev/null
+++ b/gcc/diagnostics/physical-location-maker.h
@@ -0,0 +1,60 @@
+/* Convenient but inefficient creation of location_t values.
+   Copyright (C) 2023-2026 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_PHYSICAL_LOCATION_MAKER_H
+#define GCC_DIAGNOSTICS_PHYSICAL_LOCATION_MAKER_H
+
+namespace diagnostics {
+
+/* A class for generating location_t values for arbitrary
+   filename/line/column values.
+   This is less efficient than working with the line_maps
+   directly, but is more convenient and flexible for occasional
+   on-demand location_t values.  */
+
+class physical_location_maker
+{
+public:
+  physical_location_maker (line_maps *line_table_)
+  : m_line_table (line_table_)
+  {
+  }
+
+  location_t
+  new_location_from_file_and_line (const char *filename,
+                                  int line_num);
+
+  /* column_num is 1-based.  */
+  location_t
+  new_location_from_file_line_column (const char *filename,
+                                     int line_num,
+                                     int column_num);
+
+private:
+  void
+  ensure_linemap_for_file_and_line (const char *filename,
+                                   int linenum);
+
+private:
+  line_maps *m_line_table;
+};
+
+} // namespace diagnostics
+
+#endif // #ifndef GCC_DIAGNOSTICS_PHYSICAL_LOCATION_MAKER_H
diff --git a/gcc/libgdiagnostics.cc b/gcc/libgdiagnostics.cc
index eb2d0ac4cac1a..dd5109229b3dc 100644
--- a/gcc/libgdiagnostics.cc
+++ b/gcc/libgdiagnostics.cc
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostics/logical-locations.h"
 #include "diagnostics/dumping.h"
 #include "diagnostics/changes.h"
+#include "diagnostics/physical-location-maker.h"
 #include "libgdiagnostics.h"
 #include "libgdiagnostics-private.h"
 #include "pretty-print-format-impl.h"
@@ -648,7 +649,8 @@ struct diagnostic_manager
 {
 public:
   diagnostic_manager ()
-  : m_current_diag (nullptr),
+  : m_phys_loc_maker (&m_line_table),
+    m_current_diag (nullptr),
     m_prev_diag_logical_loc (nullptr),
     m_debug_physical_locations (false)
   {
@@ -761,8 +763,9 @@ public:
     if (m_debug_physical_locations)
       fprintf (stderr, "new_location_from_file_and_line (%s, %i)",
               file->get_name (), line_num);
-    ensure_linemap_for_file_and_line (file, line_num);
-    location_t loc = linemap_position_for_column (&m_line_table, 0);
+    location_t loc
+      = m_phys_loc_maker.new_location_from_file_and_line (file->get_name (),
+                                                         line_num);
     return new_location (loc);
   }
 
@@ -774,8 +777,10 @@ public:
     if (m_debug_physical_locations)
       fprintf (stderr, "new_location_from_file_line_column (%s, %i, %i)",
               file->get_name (), line_num, column_num);
-    ensure_linemap_for_file_and_line (file, line_num);
-    location_t loc = linemap_position_for_column (&m_line_table, column_num);
+    location_t loc
+      = m_phys_loc_maker.new_location_from_file_line_column (file->get_name (),
+                                                            line_num,
+                                                            column_num);
     return new_location (loc);
   }
 
@@ -892,31 +897,6 @@ public:
   void
   take_global_graph (std::unique_ptr<diagnostic_graph> graph);
 
-private:
-  void
-  ensure_linemap_for_file_and_line (const diagnostic_file *file,
-                                   diagnostic_line_num_t linenum)
-  {
-    /* Build a simple linemap describing some locations. */
-    if (LINEMAPS_ORDINARY_USED (&m_line_table) == 0)
-      linemap_add (&m_line_table, LC_ENTER, false, file->get_name (), 0);
-    else
-      {
-       line_map_ordinary *last_map
-         = LINEMAPS_LAST_ORDINARY_MAP (&m_line_table);
-       if (last_map->to_file != file->get_name ()
-           || linenum < last_map->to_line)
-         {
-           line_map *map
-             = const_cast<line_map *>
-             (linemap_add (&m_line_table, LC_RENAME_VERBATIM, false,
-                           file->get_name (), 0));
-           ((line_map_ordinary *)map)->included_from = UNKNOWN_LOCATION;
-         }
-      }
-    linemap_line_start (&m_line_table, linenum, 100);
-  }
-
   const diagnostic_physical_location *
   new_location (location_t loc)
   {
@@ -940,6 +920,7 @@ private:
 
   diagnostics::context m_dc;
   line_maps m_line_table;
+  diagnostics::physical_location_maker m_phys_loc_maker;
   impl_client_version_info m_client_version_info;
   std::vector<std::unique_ptr<sink>> m_sinks;
   hash_map<nofree_string_hash, diagnostic_file *> m_str_to_file_map;
-- 
2.26.3

Reply via email to