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 <tom@tromey.com> Reviewed-By: Andrew Burgess <aburgess@redhat.com>
This commit is contained in:
parent
9f353051de
commit
05e4e89373
3 changed files with 190 additions and 168 deletions
173
gdb/gdbarch.py
173
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."
|
||||
)
|
||||
|
|
|
@ -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",
|
183
gdb/gdbarch_types.py
Executable file
183
gdb/gdbarch_types.py
Executable file
|
@ -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 = []
|
Loading…
Add table
Add a link
Reference in a new issue