|  | # 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/>. | 
|  |  | 
|  | from typing import List, Optional, Tuple, Union | 
|  |  | 
|  |  | 
|  | def join_type_and_name(t: str, n: str): | 
|  | "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: List[Tuple[str, str]]): | 
|  | """Given a sequence of (TYPE, NAME) pairs, generate a comma-separated | 
|  | list of declarations.""" | 
|  | return ", ".join([join_type_and_name(p[0], p[1]) for p in params]) | 
|  |  | 
|  |  | 
|  | class Component: | 
|  | "Base class for all components." | 
|  |  | 
|  | def __init__( | 
|  | self, | 
|  | name: str, | 
|  | type: str, | 
|  | printer: Optional[str] = None, | 
|  | comment: Optional[str] = None, | 
|  | predicate: bool = False, | 
|  | predefault: Optional[str] = None, | 
|  | postdefault: Optional[str] = None, | 
|  | invalid: Union[bool, str] = True, | 
|  | params: Optional[List[Tuple[str, str]]] = None, | 
|  | param_checks: Optional[List[str]] = None, | 
|  | result_checks: Optional[List[str]] = None, | 
|  | implement: bool = 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 or [] | 
|  | 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." | 
|  | 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: str, | 
|  | type: str, | 
|  | comment: Optional[str] = None, | 
|  | predicate: bool = False, | 
|  | predefault: Optional[str] = None, | 
|  | postdefault: Optional[str] = None, | 
|  | invalid: Union[bool, str] = True, | 
|  | printer: Optional[str] = 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: str, | 
|  | type: str, | 
|  | params: List[Tuple[str, str]], | 
|  | comment: Optional[str] = None, | 
|  | predicate: bool = False, | 
|  | predefault: Optional[str] = None, | 
|  | postdefault: Optional[str] = None, | 
|  | invalid: Union[bool, str] = True, | 
|  | printer: Optional[str] = None, | 
|  | param_checks: Optional[List[str]] = None, | 
|  | result_checks: Optional[List[str]] = None, | 
|  | implement: bool = 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] = [] |