From patchwork Sat Feb 25 03:30:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 65643 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 5AB6A3854835 for ; Sat, 25 Feb 2023 03:38:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5AB6A3854835 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677296284; bh=7Fae3UIcpNcOgEworei7RnweK54UPep5MwiXAWvQCHA=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=kyoDXWF/m0kYgfnQOajimgg7OLEEOTROEKGOCLc7OIEsa7IisumJ0He8C8+DkxVVn TgKE4iLfT4bxT3T+saidnyUwOXUt7kKKv++v7zQ8d7t55uasKGInx0w2tvyCKF8vB6 i3TDVvzk4YIPXxlQuxFzqHq+59o1G5OH3conJ6ks= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 49E90385B531 for ; Sat, 25 Feb 2023 03:37:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 49E90385B531 Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 31P3b02k030134 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Feb 2023 22:37:05 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 31P3b02k030134 Received: from simark.localdomain (unknown [217.28.27.60]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id F01021E9EE; Fri, 24 Feb 2023 22:30:50 -0500 (EST) To: gdb-patches@sourceware.org Cc: Simon Marchi , Tom Tromey Subject: [PATCH v2 06/10] gdb: split gdbarch component types to gdbarch_types.py Date: Fri, 24 Feb 2023 22:30:43 -0500 Message-Id: <20230225033047.373899-7-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230225033047.373899-1-simon.marchi@polymtl.ca> References: <20230225033047.373899-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Sat, 25 Feb 2023 03:37:00 +0000 X-Spam-Status: No, score=-3189.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP 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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Editing gdbarch-components.py is not an experience in an editor that is minimally smart about Python. Because gdbarch-components.py is read and exec'd by gdbarch.py, it doesn't import the Info / Method / Function / Value types. And because these types are defined in gdbarch.py, it can't import them, as that would make a cyclic dependency. Solve this by introducing a third file, gdbarch_types.py, to define these types. Make gdbarch.py and gdbarch-components.py import it. Also, replace the read & exec of gdbarch-components.py by a regular import. For this to work though, gdbarch-components.py needs to be renamed to gdbarch_components.py. Change-Id: Ibe994d56ef9efcc0698b3ca9670d4d9bf8bbb853 Reviewed-By: Tom Tromey --- gdb/gdbarch.py | 173 +---------------- ...ch-components.py => gdbarch_components.py} | 2 + gdb/gdbarch_types.py | 183 ++++++++++++++++++ 3 files changed, 190 insertions(+), 168 deletions(-) rename gdb/{gdbarch-components.py => gdbarch_components.py} (99%) create mode 100755 gdb/gdbarch_types.py diff --git a/gdb/gdbarch.py b/gdb/gdbarch.py index f97f39b6db0f..d1ac414d0eb3 100755 --- a/gdb/gdbarch.py +++ b/gdb/gdbarch.py @@ -20,10 +20,12 @@ # along with this program. If not, see . import textwrap -import gdbcopyright -# All the components created in gdbarch-components.py. -components = [] +# gdbarch_components is imported only for its side-effect of filling +# `gdbarch_types.components`. +import gdbarch_components # noqa: F401 # type: ignore +import gdbcopyright +from gdbarch_types import Function, Info, Value, components def indentation(n_columns): @@ -31,171 +33,6 @@ def indentation(n_columns): return "\t" * (n_columns // 8) + " " * (n_columns % 8) -def join_type_and_name(t, n): - "Combine the type T and the name N into a C declaration." - if t.endswith("*") or t.endswith("&"): - return t + n - else: - return t + " " + n - - -def join_params(params): - """Given a sequence of (TYPE, NAME) pairs, generate a comma-separated - list of declarations.""" - params = [join_type_and_name(p[0], p[1]) for p in params] - return ", ".join(params) - - -class _Component: - "Base class for all components." - - def __init__( - self, - name, - type, - printer=None, - comment=None, - predicate=False, - predefault=None, - postdefault=None, - invalid=None, - params=None, - param_checks=None, - result_checks=None, - implement=True, - ): - self.name = name - self.type = type - self.printer = printer - self.comment = comment - self.predicate = predicate - self.predefault = predefault - self.postdefault = postdefault - self.invalid = invalid - self.params = params - self.param_checks = param_checks - self.result_checks = result_checks - self.implement = implement - - components.append(self) - - # It doesn't make sense to have a check of the result value - # for a function or method with void return type. - if self.type == "void" and self.result_checks: - raise Exception("can't have result checks with a void return type") - - def get_predicate(self): - "Return the expression used for validity checking." - assert self.predicate and not isinstance(self.invalid, str) - if self.predefault: - predicate = f"gdbarch->{self.name} != {self.predefault}" - else: - predicate = f"gdbarch->{self.name} != NULL" - return predicate - - -class Info(_Component): - "An Info component is copied from the gdbarch_info." - - -class Value(_Component): - "A Value component is just a data member." - - def __init__( - self, - *, - name, - type, - comment=None, - predicate=False, - predefault=None, - postdefault=None, - invalid=None, - printer=None, - ): - super().__init__( - comment=comment, - name=name, - type=type, - predicate=predicate, - predefault=predefault, - postdefault=postdefault, - invalid=invalid, - printer=printer, - ) - - -class Function(_Component): - "A Function component is a function pointer member." - - def __init__( - self, - *, - name, - type, - params, - comment=None, - predicate=False, - predefault=None, - postdefault=None, - invalid=None, - printer=None, - param_checks=None, - result_checks=None, - implement=True, - ): - super().__init__( - comment=comment, - name=name, - type=type, - predicate=predicate, - predefault=predefault, - postdefault=postdefault, - invalid=invalid, - printer=printer, - params=params, - param_checks=param_checks, - result_checks=result_checks, - implement=implement, - ) - - def ftype(self): - "Return the name of the function typedef to use." - return f"gdbarch_{self.name}_ftype" - - def param_list(self): - "Return the formal parameter list as a string." - return join_params(self.params) - - def set_list(self): - """Return the formal parameter list of the caller function, - as a string. This list includes the gdbarch.""" - arch_arg = ("struct gdbarch *", "gdbarch") - arch_tuple = [arch_arg] - return join_params(arch_tuple + list(self.params)) - - def actuals(self): - "Return the actual parameters to forward, as a string." - return ", ".join([p[1] for p in self.params]) - - -class Method(Function): - "A Method is like a Function but passes the gdbarch through." - - def param_list(self): - "See superclass." - return self.set_list() - - def actuals(self): - "See superclass." - result = ["gdbarch"] + [p[1] for p in self.params] - return ", ".join(result) - - -# Read the components. -with open("gdbarch-components.py") as fd: - exec(fd.read()) - copyright = gdbcopyright.copyright( "gdbarch.py", "Dynamic architecture support for GDB, the GNU debugger." ) diff --git a/gdb/gdbarch-components.py b/gdb/gdbarch_components.py similarity index 99% rename from gdb/gdbarch-components.py rename to gdb/gdbarch_components.py index 76ad2832d8a2..fe5c3b3b4bcd 100644 --- a/gdb/gdbarch-components.py +++ b/gdb/gdbarch_components.py @@ -117,6 +117,8 @@ # * "implement" - optional, a boolean. If True (the default), a # wrapper function for this function will be emitted. +from gdbarch_types import Function, Info, Method, Value + Info( type="const struct bfd_arch_info *", name="bfd_arch_info", diff --git a/gdb/gdbarch_types.py b/gdb/gdbarch_types.py new file mode 100755 index 000000000000..aca23850b911 --- /dev/null +++ b/gdb/gdbarch_types.py @@ -0,0 +1,183 @@ +# Architecture commands for GDB, the GNU debugger. +# +# Copyright (C) 1998-2023 Free Software Foundation, Inc. +# +# This file is part of GDB. +# +# This program 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 of the License, or +# (at your option) any later version. +# +# This program 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 this program. If not, see . + + +def join_type_and_name(t, n): + "Combine the type T and the name N into a C declaration." + if t.endswith("*") or t.endswith("&"): + return t + n + else: + return t + " " + n + + +def join_params(params): + """Given a sequence of (TYPE, NAME) pairs, generate a comma-separated + list of declarations.""" + params = [join_type_and_name(p[0], p[1]) for p in params] + return ", ".join(params) + + +class _Component: + "Base class for all components." + + def __init__( + self, + name, + type, + printer=None, + comment=None, + predicate=False, + predefault=None, + postdefault=None, + invalid=None, + params=None, + param_checks=None, + result_checks=None, + implement=True, + ): + self.name = name + self.type = type + self.printer = printer + self.comment = comment + self.predicate = predicate + self.predefault = predefault + self.postdefault = postdefault + self.invalid = invalid + self.params = params + self.param_checks = param_checks + self.result_checks = result_checks + self.implement = implement + + components.append(self) + + # It doesn't make sense to have a check of the result value + # for a function or method with void return type. + if self.type == "void" and self.result_checks: + raise Exception("can't have result checks with a void return type") + + def get_predicate(self): + "Return the expression used for validity checking." + assert self.predicate and not isinstance(self.invalid, str) + if self.predefault: + predicate = f"gdbarch->{self.name} != {self.predefault}" + else: + predicate = f"gdbarch->{self.name} != NULL" + return predicate + + +class Info(_Component): + "An Info component is copied from the gdbarch_info." + + +class Value(_Component): + "A Value component is just a data member." + + def __init__( + self, + *, + name, + type, + comment=None, + predicate=False, + predefault=None, + postdefault=None, + invalid=None, + printer=None, + ): + super().__init__( + comment=comment, + name=name, + type=type, + predicate=predicate, + predefault=predefault, + postdefault=postdefault, + invalid=invalid, + printer=printer, + ) + + +class Function(_Component): + "A Function component is a function pointer member." + + def __init__( + self, + *, + name, + type, + params, + comment=None, + predicate=False, + predefault=None, + postdefault=None, + invalid=None, + printer=None, + param_checks=None, + result_checks=None, + implement=True, + ): + super().__init__( + comment=comment, + name=name, + type=type, + predicate=predicate, + predefault=predefault, + postdefault=postdefault, + invalid=invalid, + printer=printer, + params=params, + param_checks=param_checks, + result_checks=result_checks, + implement=implement, + ) + + def ftype(self): + "Return the name of the function typedef to use." + return f"gdbarch_{self.name}_ftype" + + def param_list(self): + "Return the formal parameter list as a string." + return join_params(self.params) + + def set_list(self): + """Return the formal parameter list of the caller function, + as a string. This list includes the gdbarch.""" + arch_arg = ("struct gdbarch *", "gdbarch") + arch_tuple = [arch_arg] + return join_params(arch_tuple + list(self.params)) + + def actuals(self): + "Return the actual parameters to forward, as a string." + return ", ".join([p[1] for p in self.params]) + + +class Method(Function): + "A Method is like a Function but passes the gdbarch through." + + def param_list(self): + "See superclass." + return self.set_list() + + def actuals(self): + "See superclass." + result = ["gdbarch"] + [p[1] for p in self.params] + return ", ".join(result) + + +# All the components created in gdbarch-components.py. +components: list[_Component] = []