def get_arguments(cursor: cindex.Cursor) -> Iterator[cindex.Cursor]: for child in cursor.get_arguments(): args = [] if child.kind != cindex.CursorKind.UNEXPOSED_EXPR: args.append(child) else: walk_ast(child, _get_arguments_helper, args) yield args[0] if len(args) > 0 else None
def __init__(self, cursor: cindex.Cursor): super().__init__(cursor) self.parent = CursorAdapter.create(cursor.semantic_parent) self.arguments = [(TypeAdapter.create(x.type), x.spelling) for x in cursor.get_arguments()] self.result_type = TypeAdapter.create(cursor.result_type) logger.info(f'FuncType: {self.cursor.kind}, ' f'ResultType: {self.cursor.result_type.kind}')
def find_constructors(node: cindex.Cursor, base: cindex.Cursor) -> Dict: """Find info on all the constructors for the given node. Args: node (cindex.Cursor): The op constructor node base (cindex.Cursor): The base class. Returns: Dict: A dict containing all the required info about the constructor. See function return for what it contains. """ args_ = [] for c in node.get_arguments(): cpp_arg = CppArgument(c) args_.append({ "arg_name": cpp_arg.name, "alt_arg_name": cpp_arg.alt_name, "arg_type": cpp_arg.type_name, "const": cpp_arg.is_const, "ref": cpp_arg.is_ref, "has_default": cpp_arg.has_default, "default": cpp_arg.default }) # Add the full string of args, to avoid having to re-create later. full_args = "" for i, arg in enumerate(args_): full_args += arg["arg_type"] if i + 1 != len(args_): full_args += ", " # Get the relative include path file_ = node.location.file.name file_ = Path(file_).resolve().relative_to( Path(__file__).resolve().parents[1]) return { "name": node.spelling, "constructors": [{ "args": args_, "full_args": full_args, }], "display_name": node.displayname, "hash": node.hash, "file": str(file_), "base_class": base.spelling.replace("class ", "") if hasattr(base, "spelling") else "popart::Op" }
def get_arguments(cursor: clang.Cursor) -> typing.Generator[clang.Cursor, None, None]: """ Retrieves the argument dependencies from the AST node pointed to by the given cursor. :param cursor: The cursor pointing to the node. :return: The cursors of the nodes of the arguments of the node. """ # If the cursor has arguments, yield them yield from cursor.get_arguments() # If the cursor is an enum, yield all children if cursor.kind == clang.CursorKind.ENUM_DECL: for arg_cursor in cursor.walk_preorder(): yield arg_cursor
def generate_macro_definition(self, elem: Cursor, **kwargs): """Transform a macro into a function if possible Examples -------- >>> from tide.generators.clang_utils import parse_clang >>> tu, index = parse_clang('#define PI 3.14') >>> module = BindingGenerator().generate(tu) >>> print(compact(unparse(module))) <BLANKLINE> PI = 3.14 <BLANKLINE> >>> tu, index = parse_clang('' ... '#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE 0x00000001\\n' ... '#define SDL_AUDIO_ALLOW_FORMAT_CHANGE 0x00000002\\n' ... '#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE 0x00000004\\n' ... '#define SDL_AUDIO_ALLOW_ANY_CHANGE (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE)\\n' ... ) >>> module = BindingGenerator().generate(tu) >>> print(compact(unparse(module))) <BLANKLINE> SDL_AUDIO_ALLOW_FREQUENCY_CHANGE = 1 <BLANKLINE> SDL_AUDIO_ALLOW_FORMAT_CHANGE = 2 <BLANKLINE> SDL_AUDIO_ALLOW_CHANNELS_CHANGE = 4 <BLANKLINE> SDL_AUDIO_ALLOW_ANY_CHANGE = (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | (SDL_AUDIO_ALLOW_FORMAT_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE)) <BLANKLINE> """ # builtin macros if elem.location.file is None: return log.debug(f'Macro definition {elem.spelling}') args = list(elem.get_arguments()) children = list(elem.get_children()) tokens = list(elem.get_tokens()) if len(args) != 0: for arg in args: show_elem(arg, print_fun=log.debug) assert False if len(children) != 0: for child in children: show_elem(child, print_fun=log.debug) assert False if len(tokens) == 1: return name, tok_args, tok_body = parse_macro(tokens) if len(tok_body) == 0: return if name.spelling == 'NULL': return T.Assign([T.Name('NULL')], T.Name('None')) try: bods = {t.spelling for t in tok_body} if not bods.isdisjoint(self.unsupported_macros): raise UnsupportedExpression() py_body = parse_macro2(name, tok_args, tok_body, self.definitions, self.type_registry, self.renaming) except UnsupportedExpression: self.unsupported_macros.add(name.spelling) body = [b.spelling for b in tok_body] log.warning( f'Unsupported expression, cannot transform macro {name.spelling} {"".join(body)}' ) return name = name.spelling # if name == 'SDL_TOUCH_MOUSEID': # print(py_body) # assert False if len(tok_args) == 0 and not isinstance(py_body, T.If): return T.Assign([T.Name(name)], py_body) func = T.FunctionDef( name, T.Arguments(args=[T.Arg(arg=a.spelling) for a in tok_args])) if isinstance(py_body, T.Expr): py_body = py_body.value # we use ifs as a makeshift Body expression if isinstance(py_body, T.If) and isinstance(py_body.test, T.Constant) \ and py_body.test.value is True: func.body = py_body.body else: func.body = [T.Return(py_body)] return func