From patchwork Wed Jun 22 22:34:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 55303 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D36823883031 for ; Wed, 22 Jun 2022 22:40:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D36823883031 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1655937650; bh=eFwZVlsl+KI8Uvj2W7la7XxmiVSHiJCWCM9HAQ/GTeg=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=EQ11ygWWVlrBf5VNeERJdzJSq0PG+XA33UbRaS6wNFaYELqRQqgW6T22RjPliDiJm U2Bqb8zJtrp5gzHSLZOWwJUqmwUVPIC6UbksiQ7RS9yKwQpDSQRnnzeA7aUD9bYGoc B29/2pM/AYkh7c7bV5jmJUu43YRElEa9YqP3Hipg= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 64D93383066B for ; Wed, 22 Jun 2022 22:34:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 64D93383066B Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-649-cNnQRQ9mMQmWVS2SsObJcw-1; Wed, 22 Jun 2022 18:34:50 -0400 X-MC-Unique: cNnQRQ9mMQmWVS2SsObJcw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id E703989C7DD for ; Wed, 22 Jun 2022 22:34:49 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.2.17.61]) by smtp.corp.redhat.com (Postfix) with ESMTP id C37DF1121314; Wed, 22 Jun 2022 22:34:49 +0000 (UTC) To: gcc-patches@gcc.gnu.org Subject: [PATCH 07/12] Add deferred-locations.h/cc Date: Wed, 22 Jun 2022 18:34:42 -0400 Message-Id: <20220622223447.2462880-8-dmalcolm@redhat.com> In-Reply-To: <20220622223447.2462880-1-dmalcolm@redhat.com> References: <20220622223447.2462880-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: David Malcolm via Gcc-patches From: David Malcolm Reply-To: David Malcolm Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" 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 --- 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 . + +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 +. */ + +#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 (lhs); + const source_location &location_rhs + = *static_cast (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 (lhs); + const source_line *line_rhs + = *static_cast (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 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 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 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 . + +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 +. */ + +#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 */