public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: David Malcolm <dmalcolm@redhat.com>
To: gcc-patches@gcc.gnu.org
Subject: [PATCH 07/12] Add deferred-locations.h/cc
Date: Wed, 22 Jun 2022 18:34:42 -0400	[thread overview]
Message-ID: <20220622223447.2462880-8-dmalcolm@redhat.com> (raw)
In-Reply-To: <20220622223447.2462880-1-dmalcolm@redhat.com>

libcpp requires locations to be created as if by a tokenizer, creating
them by filename, in ascending order of line/column.

This patch adds support classes that allow the creation of locations
in arbitrary orders, by deferring all location creation,
grouping things up by filename/line, and then creating the linemap
entries in a post-processing phase.

gcc/ChangeLog:
	* deferred-locations.cc: New file, adapted from code in
	jit/jit-playback.cc.
	* deferred-locations.h: New file.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
 gcc/deferred-locations.cc | 231 ++++++++++++++++++++++++++++++++++++++
 gcc/deferred-locations.h  |  52 +++++++++
 2 files changed, 283 insertions(+)
 create mode 100644 gcc/deferred-locations.cc
 create mode 100644 gcc/deferred-locations.h

diff --git a/gcc/deferred-locations.cc b/gcc/deferred-locations.cc
new file mode 100644
index 00000000000..e78b29a4d58
--- /dev/null
+++ b/gcc/deferred-locations.cc
@@ -0,0 +1,231 @@
+/* Support for deferred creation of location_t values.
+   Copyright (C) 2013-2022 Free Software Foundation, Inc.
+   Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+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 "deferred-locations.h"
+
+/* Concrete implementation for use by deferred_locations.  */
+
+class deferred_locations_impl
+{
+public:
+  class source_file;
+  class source_line;
+  class source_location;
+
+  /* A specific location on a source line, with a saved location_t *
+     to write back to.  */
+  class source_location
+  {
+  public:
+    source_location (int column_num, location_t *out_loc)
+    : m_column_num (column_num), m_out_loc (out_loc)
+    {
+    }
+
+    int get_column_num () const { return m_column_num; }
+
+    /* qsort comparator for comparing pairs of source_location *,
+       ordering them by column number.  */
+
+    static int
+    comparator (const void *lhs, const void *rhs)
+    {
+      const source_location &location_lhs
+	= *static_cast<const source_location *> (lhs);
+      const source_location &location_rhs
+	= *static_cast<const source_location *> (rhs);
+      return location_lhs.m_column_num - location_rhs.m_column_num;
+    }
+
+    void generate_location_t_value () const
+    {
+      *m_out_loc = linemap_position_for_column (line_table, m_column_num);
+    }
+
+  private:
+    int m_column_num;
+    location_t *m_out_loc;
+  };
+
+  /* A source line, with one or more locations of interest.  */
+  class source_line
+  {
+  public:
+    source_line (int line_num) : m_line_num (line_num) {}
+
+    source_location *
+    get_location (int column_num, location_t *out_loc);
+
+    int get_line_num () const { return m_line_num; }
+
+    void add_location (const expanded_location &exploc,
+		       location_t *out_loc)
+    {
+      m_locations.safe_push (source_location (exploc.column, out_loc));
+    }
+
+    /* qsort comparator for comparing pairs source_line *,
+       ordering them by line number.  */
+
+    static int
+    comparator (const void *lhs, const void *rhs)
+    {
+      const source_line *line_lhs
+	= *static_cast<const source_line * const*> (lhs);
+      const source_line *line_rhs
+	= *static_cast<const source_line * const*> (rhs);
+      return line_lhs->get_line_num () - line_rhs->get_line_num ();
+    }
+
+    void generate_location_t_values ()
+    {
+      /* Determine maximum column within this line.  */
+      m_locations.qsort (source_location::comparator);
+      gcc_assert (m_locations.length () > 0);
+      source_location *final_column = &m_locations[m_locations.length () - 1];
+      int max_col = final_column->get_column_num ();
+
+      linemap_line_start (line_table, m_line_num, max_col);
+      for (auto loc_iter : m_locations)
+	loc_iter.generate_location_t_value ();
+    }
+
+  private:
+    int m_line_num;
+    auto_vec<source_location> m_locations;
+  };
+
+  /* A set of locations, all sharing a filename */
+  class source_file
+  {
+  public:
+    source_file (const char *filename)
+    : m_filename (xstrdup (filename))
+    {
+    }
+    ~source_file ()
+    {
+      free (m_filename);
+    }
+
+    source_line *
+    get_source_line (int line_num);
+
+    const char*
+    get_filename () const { return m_filename; }
+
+    bool
+    matches (const char *filename)
+    {
+      return ((filename == NULL && m_filename == NULL)
+	      || ((filename && m_filename)
+		  && 0 == strcmp (filename, m_filename)));
+    }
+
+    void add_location (const expanded_location &exploc,
+		       location_t *out_loc)
+    {
+      source_line *line = get_or_create_line (exploc.line);
+      line->add_location (exploc, out_loc);
+    }
+
+    void generate_location_t_values ()
+    {
+      linemap_add (line_table, LC_ENTER, false, xstrdup (m_filename), 0);
+
+      /* Sort lines by ascending line numbers.  */
+      m_source_lines.qsort (source_line::comparator);
+
+      for (auto line_iter : m_source_lines)
+	line_iter->generate_location_t_values ();
+
+      linemap_add (line_table, LC_LEAVE, false, NULL, 0);
+    }
+
+  private:
+    source_line *get_or_create_line (int line_num)
+    {
+      // FIXME: something better than linear search here?
+      for (auto iter : m_source_lines)
+	if (line_num == iter->get_line_num ())
+	  return iter;
+      source_line *line = new source_line (line_num);
+      m_source_lines.safe_push (line);
+      return line;
+    }
+
+    char *m_filename;
+    auto_delete_vec<source_line> m_source_lines;
+  };
+
+  void add_location (const expanded_location &exploc,
+		     location_t *out_loc)
+  {
+    source_file *f = get_or_create_file (exploc.file);
+    f->add_location (exploc, out_loc);
+  }
+
+  void generate_location_t_values ()
+  {
+    for (auto file_iter : m_source_files)
+      file_iter->generate_location_t_values ();
+  }
+
+private:
+  source_file *get_or_create_file (const char *filename)
+  {
+    // FIXME: something better than linear search here?
+    for (auto iter : m_source_files)
+      if (iter->matches (filename))
+	return iter;
+    source_file *f = new source_file (filename);
+    m_source_files.safe_push (f);
+    return f;
+  }
+  auto_delete_vec<source_file> m_source_files;
+};
+
+/* class deferred_locations.  */
+
+deferred_locations::deferred_locations ()
+: m_pimpl (new deferred_locations_impl ())
+{
+}
+
+deferred_locations::~deferred_locations ()
+{
+  delete m_pimpl;
+}
+
+void
+deferred_locations::add_location (const expanded_location &exploc,
+			      location_t *out_loc)
+{
+  m_pimpl->add_location (exploc, out_loc);
+}
+
+void
+deferred_locations::generate_location_t_values ()
+{
+  m_pimpl->generate_location_t_values ();
+}
diff --git a/gcc/deferred-locations.h b/gcc/deferred-locations.h
new file mode 100644
index 00000000000..97d962aa613
--- /dev/null
+++ b/gcc/deferred-locations.h
@@ -0,0 +1,52 @@
+/* Support for deferred creation of location_t values.
+   Copyright (C) 2013-2022 Free Software Foundation, Inc.
+   Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+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 DEFERRED_LOCATIONS_H
+#define DEFERRED_LOCATIONS_H
+
+class deferred_locations_impl;
+
+/* Dealing with the linemap API.
+
+   libcpp requires locations to be created as if by
+   a tokenizer, creating them by filename, in ascending order of
+   line/column.
+
+   This class is for supporting code that allows the creation of locations
+   in arbitrary orders, by deferring all location creation,
+   grouping things up by filename/line, and then creating the linemap
+   entries in a post-processing phase.  */
+
+class deferred_locations
+{
+ public:
+  deferred_locations ();
+  ~deferred_locations ();
+
+  void add_location (const expanded_location &exploc,
+		     location_t *loc);
+
+  void generate_location_t_values ();
+
+ private:
+  deferred_locations_impl *m_pimpl;
+};
+
+#endif /* DEFERRED_LOCATIONS_H */
-- 
2.26.3


  parent reply	other threads:[~2022-06-22 22:34 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-22 22:34 [PATCH 00/12] RFC: Replay of serialized diagnostics David Malcolm
2022-06-22 22:34 ` [PATCH 01/12] diagnostics: add ability to associate diagnostics with rules from coding standards David Malcolm
2022-06-23 19:04   ` David Malcolm
2022-06-22 22:34 ` [PATCH 02/12] diagnostics: associate rules with plugins in SARIF output David Malcolm
2022-06-22 22:34 ` [PATCH 03/12] Add more emit_diagnostic overloads David Malcolm
2022-06-23 16:39   ` Joseph Myers
2022-06-22 22:34 ` [PATCH 04/12] json: add json parsing support David Malcolm
2022-06-22 22:34 ` [PATCH 05/12] Placeholder libcpp fixups David Malcolm
2022-06-22 22:34 ` [PATCH 06/12] prune.exp: move multiline-handling to before other pruning David Malcolm
2022-06-22 22:34 ` David Malcolm [this message]
2022-06-22 22:34 ` [PATCH 08/12] Add json-reader.h/cc David Malcolm
2022-06-22 22:34 ` [PATCH 09/12] Add json frontend David Malcolm
2022-06-22 22:34 ` [PATCH 10/12] Add sarif frontend David Malcolm
2022-06-22 22:34 ` [PATCH 11/12] Fixups to diagnostic-format-sarif.cc David Malcolm
2022-06-22 22:34 ` [PATCH 12/12] Work-in-progress of path remapping David Malcolm
2022-07-08 18:40 ` [PATCH 00/12] RFC: Replay of serialized diagnostics David Malcolm

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220622223447.2462880-8-dmalcolm@redhat.com \
    --to=dmalcolm@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).