From 05e4e893736c870ad5d2fd4e7ea8d95a94cdff3c Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Sun, 26 Feb 2023 20:13:59 -0500 Subject: [PATCH] gdb: split gdbarch component types to gdbarch_types.py 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 Reviewed-By: Andrew Burgess --- 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 f97f39b6db0..d1ac414d0eb 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 76ad2832d8a..fe5c3b3b4bc 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 00000000000..3a3cbbf8891 --- /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 = [] -- 2.30.2