From: Simon Marchi <simon.marchi@polymtl.ca>
To: gdb-patches@sourceware.org
Cc: Simon Marchi <simon.marchi@polymtl.ca>, Tom Tromey <tom@tromey.com>
Subject: [PATCH v2 06/10] gdb: split gdbarch component types to gdbarch_types.py
Date: Fri, 24 Feb 2023 22:30:43 -0500 [thread overview]
Message-ID: <20230225033047.373899-7-simon.marchi@polymtl.ca> (raw)
In-Reply-To: <20230225033047.373899-1-simon.marchi@polymtl.ca>
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 <tom@tromey.com>
---
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 <http://www.gnu.org/licenses/>.
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 <http://www.gnu.org/licenses/>.
+
+
+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] = []
--
2.39.2
next prev parent reply other threads:[~2023-02-25 3:37 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-25 3:30 [PATCH v2 00/10] Add typing annotations to gdbarch*.py and make-target-delegates.py Simon Marchi
2023-02-25 3:30 ` [PATCH v2 01/10] gdb: remove invalid / dead code from gdbarch.py Simon Marchi
2023-02-25 3:30 ` [PATCH v2 02/10] gdb: reformat Python files with black 23.1.0 Simon Marchi
2023-02-25 3:30 ` [PATCH v2 03/10] gdb: gdbarch.py: spell out parameters of _Component.__init__ Simon Marchi
2023-02-25 3:30 ` [PATCH v2 04/10] gdb: gdbarch.py: remove Info.__init__ Simon Marchi
2023-02-25 3:30 ` [PATCH v2 05/10] gdb: pyproject.toml: set pyright typeCheckingMode = "strict" Simon Marchi
2023-02-25 3:30 ` Simon Marchi [this message]
2023-02-25 3:30 ` [PATCH v2 07/10] gdb: gdbarch*.py, copyright.py: add type annotations Simon Marchi
2023-02-25 3:30 ` [PATCH v2 08/10] gdb: make-target-delegates.py: make one string raw Simon Marchi
2023-02-25 3:30 ` [PATCH v2 09/10] gdb: make-target-delegates.py: add Entry type Simon Marchi
2023-02-25 3:30 ` [PATCH v2 10/10] gdb: make-target-delegates.py: add type annotations Simon Marchi
2023-02-25 11:05 ` [PATCH v2 00/10] Add typing annotations to gdbarch*.py and make-target-delegates.py Andrew Burgess
2023-02-27 1:11 ` Simon Marchi
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=20230225033047.373899-7-simon.marchi@polymtl.ca \
--to=simon.marchi@polymtl.ca \
--cc=gdb-patches@sourceware.org \
--cc=tom@tromey.com \
/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).