# -----------------------------------------------------------------
# ** ATTENTION **
# This code was automatically generated from _c_ast.cfg
#
# Do not modify it directly. Modify the configuration file and
# run 'make regen-ast' from the repository root to regenerate and format it.
# ** ** *** ** **
#
# The order of generated __slots__ is significant to Node.__repr__.
# ruff: noqa: RUF023
#
# pycparser: c_ast.py
#
# AST Node classes.
#
# Eli Bendersky [https://eli.thegreenplace.net/]
# License: BSD
# -----------------------------------------------------------------


import sys
from typing import IO, Any, ClassVar


def _repr(obj):
    """
    Get the representation of an object, with dedicated pprint-like format for lists.
    """
    if isinstance(obj, list):
        return "[" + (",\n ".join(_repr(e).replace("\n", "\n ") for e in obj)) + "\n]"
    else:
        return repr(obj)


class Node:
    __slots__ = ()
    """ Abstract base class for AST nodes.
    """
    attr_names: ClassVar[tuple[str, ...]] = ()
    coord: Any | None

    def __repr__(self):
        """Generates a python representation of the current node"""
        result = self.__class__.__name__ + "("

        indent = ""
        separator = ""
        for name in self.__slots__[:-2]:
            result += separator
            result += indent
            result += (
                name
                + "="
                + (
                    _repr(getattr(self, name)).replace(
                        "\n",
                        "\n  " + (" " * (len(name) + len(self.__class__.__name__))),
                    )
                )
            )

            separator = ","
            indent = "\n " + (" " * len(self.__class__.__name__))

        result += indent + ")"

        return result

    def children(self):
        """Return a tuple of (name, child) pairs for immediate child nodes.

        Names identify the field and, for list fields, the index, such as
        "type" or "ext[0]". Optional children that are None are omitted.
        The returned tuple supports len() and indexing. Iterating over the
        node itself yields just the child nodes, without their names.
        """

    def show(
        self,
        buf: IO[str] = sys.stdout,
        offset: int = 0,
        attrnames: bool = False,
        showemptyattrs: bool = True,
        nodenames: bool = False,
        showcoord: bool = False,
        _my_node_name: str | None = None,
    ):
        """Pretty print the Node and all its attributes and
        children (recursively) to a buffer.

        buf:
            Open IO buffer into which the Node is printed.

        offset:
            Initial offset (amount of leading spaces)

        attrnames:
            True if you want to see the attribute names in
            name=value pairs. False to only see the values.

        showemptyattrs:
            False if you want to suppress printing empty attributes.

        nodenames:
            True if you want to see the actual node names
            within their parents.

        showcoord:
            Do you want the coordinates of each Node to be
            displayed.
        """
        lead = " " * offset
        if nodenames and _my_node_name is not None:
            buf.write(lead + self.__class__.__name__ + " <" + _my_node_name + ">: ")
        else:
            buf.write(lead + self.__class__.__name__ + ": ")

        if self.attr_names:

            def is_empty(v):
                return v is None or (hasattr(v, "__len__") and len(v) == 0)

            nvlist = [
                (n, getattr(self, n))
                for n in self.attr_names
                if showemptyattrs or not is_empty(getattr(self, n))
            ]
            if attrnames:
                attrstr = ", ".join(f"{name}={value}" for name, value in nvlist)
            else:
                attrstr = ", ".join(f"{value}" for _, value in nvlist)
            buf.write(attrstr)

        if showcoord:
            buf.write(f" (at {self.coord})")
        buf.write("\n")

        for child_name, child in self.children():
            child.show(
                buf,
                offset=offset + 2,
                attrnames=attrnames,
                showemptyattrs=showemptyattrs,
                nodenames=nodenames,
                showcoord=showcoord,
                _my_node_name=child_name,
            )


class NodeVisitor:
    """A base NodeVisitor class for visiting c_ast nodes.
    Subclass it and define your own visit_XXX methods, where
    XXX is the class name you want to visit with these
    methods.

    For example:

    class ConstantVisitor(NodeVisitor):
        def __init__(self):
            self.values = []

        def visit_Constant(self, node):
            self.values.append(node.value)

    Creates a list of values of all the constant nodes
    encountered below the given node. To use it:

    cv = ConstantVisitor()
    cv.visit(node)

    Notes:

    *   generic_visit() will be called for AST nodes for which
        no visit_XXX method was defined.
    *   The children of nodes for which a visit_XXX was
        defined will not be visited - if you need this, call
        generic_visit() on the node.
        You can use:
            NodeVisitor.generic_visit(self, node)
    *   Modeled after Python's own AST visiting facilities
        (the ast module of Python 3.0)
    """

    _method_cache = None

    def visit(self, node: Node):
        """Visit a node."""

        if self._method_cache is None:
            self._method_cache = {}

        visitor = self._method_cache.get(node.__class__.__name__, None)
        if visitor is None:
            method = "visit_" + node.__class__.__name__
            visitor = getattr(self, method, self.generic_visit)
            self._method_cache[node.__class__.__name__] = visitor

        return visitor(node)

    def generic_visit(self, node: Node):
        """Called if no explicit visitor function exists for a
        node. Implements preorder visiting of the node.
        """
        for _, c in node.children():
            self.visit(c)


class ArrayDecl(Node):
    __slots__ = ("type", "dim", "dim_quals", "attributes", "coord", "__weakref__")

    def __init__(self, type, dim, dim_quals, coord=None, *, attributes=None):
        self.type = type
        self.dim = dim
        self.dim_quals = dim_quals
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        if self.type is not None:
            nodelist.append(("type", self.type))
        if self.dim is not None:
            nodelist.append(("dim", self.dim))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.type is not None:
            yield self.type
        if self.dim is not None:
            yield self.dim
        yield from self.attributes or []

    attr_names = ("dim_quals",)


class ArrayDesignator(Node):
    __slots__ = ("expr", "coord", "__weakref__")

    def __init__(self, expr, coord=None):
        self.expr = expr
        self.coord = coord

    def children(self):
        nodelist = []
        if self.expr is not None:
            nodelist.append(("expr", self.expr))
        return tuple(nodelist)

    def __iter__(self):
        if self.expr is not None:
            yield self.expr

    attr_names = ()


class ArrayRef(Node):
    __slots__ = ("name", "subscript", "coord", "__weakref__")

    def __init__(self, name, subscript, coord=None):
        self.name = name
        self.subscript = subscript
        self.coord = coord

    def children(self):
        nodelist = []
        if self.name is not None:
            nodelist.append(("name", self.name))
        if self.subscript is not None:
            nodelist.append(("subscript", self.subscript))
        return tuple(nodelist)

    def __iter__(self):
        if self.name is not None:
            yield self.name
        if self.subscript is not None:
            yield self.subscript

    attr_names = ()


class Assignment(Node):
    __slots__ = ("op", "lvalue", "rvalue", "coord", "__weakref__")

    def __init__(self, op, lvalue, rvalue, coord=None):
        self.op = op
        self.lvalue = lvalue
        self.rvalue = rvalue
        self.coord = coord

    def children(self):
        nodelist = []
        if self.lvalue is not None:
            nodelist.append(("lvalue", self.lvalue))
        if self.rvalue is not None:
            nodelist.append(("rvalue", self.rvalue))
        return tuple(nodelist)

    def __iter__(self):
        if self.lvalue is not None:
            yield self.lvalue
        if self.rvalue is not None:
            yield self.rvalue

    attr_names = ("op",)


class Alignas(Node):
    __slots__ = ("alignment", "coord", "__weakref__")

    def __init__(self, alignment, coord=None):
        self.alignment = alignment
        self.coord = coord

    def children(self):
        nodelist = []
        if self.alignment is not None:
            nodelist.append(("alignment", self.alignment))
        return tuple(nodelist)

    def __iter__(self):
        if self.alignment is not None:
            yield self.alignment

    attr_names = ()


class Attribute(Node):
    __slots__ = ("name", "namespace", "arguments", "coord", "__weakref__")

    def __init__(self, name, namespace, arguments, coord=None):
        self.name = name
        self.namespace = namespace
        self.arguments = arguments
        self.coord = coord

    def children(self):
        nodelist = []
        return tuple(nodelist)

    def __iter__(self):
        return
        yield

    attr_names = (
        "name",
        "namespace",
        "arguments",
    )


class AttributeSpecifier(Node):
    __slots__ = ("attributes", "coord", "__weakref__")

    def __init__(self, attributes, coord=None):
        self.attributes = attributes
        self.coord = coord

    def children(self):
        nodelist = []
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        yield from self.attributes or []

    attr_names = ()


class AttributeDeclaration(Node):
    __slots__ = ("attributes", "coord", "__weakref__")

    def __init__(self, attributes, coord=None):
        self.attributes = attributes
        self.coord = coord

    def children(self):
        nodelist = []
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        yield from self.attributes or []

    attr_names = ()


class AttributedStatement(Node):
    __slots__ = ("attributes", "stmt", "coord", "__weakref__")

    def __init__(self, attributes, stmt, coord=None):
        self.attributes = attributes
        self.stmt = stmt
        self.coord = coord

    def children(self):
        nodelist = []
        if self.stmt is not None:
            nodelist.append(("stmt", self.stmt))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.stmt is not None:
            yield self.stmt
        yield from self.attributes or []

    attr_names = ()


class AttributedType(Node):
    __slots__ = ("type", "attributes", "coord", "__weakref__")

    def __init__(self, type, attributes, coord=None):
        self.type = type
        self.attributes = attributes
        self.coord = coord

    def children(self):
        nodelist = []
        if self.type is not None:
            nodelist.append(("type", self.type))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.type is not None:
            yield self.type
        yield from self.attributes or []

    attr_names = ()


class BinaryOp(Node):
    __slots__ = ("op", "left", "right", "coord", "__weakref__")

    def __init__(self, op, left, right, coord=None):
        self.op = op
        self.left = left
        self.right = right
        self.coord = coord

    def children(self):
        nodelist = []
        if self.left is not None:
            nodelist.append(("left", self.left))
        if self.right is not None:
            nodelist.append(("right", self.right))
        return tuple(nodelist)

    def __iter__(self):
        if self.left is not None:
            yield self.left
        if self.right is not None:
            yield self.right

    attr_names = ("op",)


class BitIntType(Node):
    __slots__ = ("width", "signedness", "coord", "__weakref__")

    def __init__(self, width, signedness, coord=None):
        self.width = width
        self.signedness = signedness
        self.coord = coord

    def children(self):
        nodelist = []
        if self.width is not None:
            nodelist.append(("width", self.width))
        return tuple(nodelist)

    def __iter__(self):
        if self.width is not None:
            yield self.width

    attr_names = ("signedness",)


class Break(Node):
    __slots__ = ("coord", "__weakref__")

    def __init__(self, coord=None):
        self.coord = coord

    def children(self):
        return ()

    def __iter__(self):
        return
        yield

    attr_names = ()


class Case(Node):
    __slots__ = ("expr", "stmts", "attributes", "coord", "__weakref__")

    def __init__(self, expr, stmts, coord=None, *, attributes=None):
        self.expr = expr
        self.stmts = stmts
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        if self.expr is not None:
            nodelist.append(("expr", self.expr))
        for i, child in enumerate(self.stmts or []):
            nodelist.append((f"stmts[{i}]", child))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.expr is not None:
            yield self.expr
        yield from self.stmts or []
        yield from self.attributes or []

    attr_names = ()


class Cast(Node):
    __slots__ = ("to_type", "expr", "coord", "__weakref__")

    def __init__(self, to_type, expr, coord=None):
        self.to_type = to_type
        self.expr = expr
        self.coord = coord

    def children(self):
        nodelist = []
        if self.to_type is not None:
            nodelist.append(("to_type", self.to_type))
        if self.expr is not None:
            nodelist.append(("expr", self.expr))
        return tuple(nodelist)

    def __iter__(self):
        if self.to_type is not None:
            yield self.to_type
        if self.expr is not None:
            yield self.expr

    attr_names = ()


class Compound(Node):
    __slots__ = ("block_items", "coord", "__weakref__")

    def __init__(self, block_items, coord=None):
        self.block_items = block_items
        self.coord = coord

    def children(self):
        nodelist = []
        for i, child in enumerate(self.block_items or []):
            nodelist.append((f"block_items[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        yield from self.block_items or []

    attr_names = ()


class CompoundLiteral(Node):
    __slots__ = ("type", "init", "storage", "coord", "__weakref__")

    def __init__(self, type, init, storage, coord=None):
        self.type = type
        self.init = init
        self.storage = storage
        self.coord = coord

    def children(self):
        nodelist = []
        if self.type is not None:
            nodelist.append(("type", self.type))
        if self.init is not None:
            nodelist.append(("init", self.init))
        return tuple(nodelist)

    def __iter__(self):
        if self.type is not None:
            yield self.type
        if self.init is not None:
            yield self.init

    attr_names = ("storage",)


class Constant(Node):
    __slots__ = ("type", "value", "coord", "__weakref__")

    def __init__(self, type, value, coord=None):
        self.type = type
        self.value = value
        self.coord = coord

    def children(self):
        nodelist = []
        return tuple(nodelist)

    def __iter__(self):
        return
        yield

    attr_names = (
        "type",
        "value",
    )


class Continue(Node):
    __slots__ = ("coord", "__weakref__")

    def __init__(self, coord=None):
        self.coord = coord

    def children(self):
        return ()

    def __iter__(self):
        return
        yield

    attr_names = ()


class Decl(Node):
    __slots__ = (
        "name",
        "quals",
        "align",
        "storage",
        "funcspec",
        "type",
        "init",
        "bitsize",
        "attributes",
        "coord",
        "__weakref__",
    )

    def __init__(
        self,
        name,
        quals,
        align,
        storage,
        funcspec,
        type,
        init,
        bitsize,
        coord=None,
        *,
        attributes=None,
    ):
        self.name = name
        self.quals = quals
        self.align = align
        self.storage = storage
        self.funcspec = funcspec
        self.type = type
        self.init = init
        self.bitsize = bitsize
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        if self.type is not None:
            nodelist.append(("type", self.type))
        if self.init is not None:
            nodelist.append(("init", self.init))
        if self.bitsize is not None:
            nodelist.append(("bitsize", self.bitsize))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.type is not None:
            yield self.type
        if self.init is not None:
            yield self.init
        if self.bitsize is not None:
            yield self.bitsize
        yield from self.attributes or []

    attr_names = (
        "name",
        "quals",
        "align",
        "storage",
        "funcspec",
    )


class DeclList(Node):
    __slots__ = ("decls", "coord", "__weakref__")

    def __init__(self, decls, coord=None):
        self.decls = decls
        self.coord = coord

    def children(self):
        nodelist = []
        for i, child in enumerate(self.decls or []):
            nodelist.append((f"decls[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        yield from self.decls or []

    attr_names = ()


class Default(Node):
    __slots__ = ("stmts", "attributes", "coord", "__weakref__")

    def __init__(self, stmts, coord=None, *, attributes=None):
        self.stmts = stmts
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        for i, child in enumerate(self.stmts or []):
            nodelist.append((f"stmts[{i}]", child))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        yield from self.stmts or []
        yield from self.attributes or []

    attr_names = ()


class DoWhile(Node):
    __slots__ = ("cond", "stmt", "coord", "__weakref__")

    def __init__(self, cond, stmt, coord=None):
        self.cond = cond
        self.stmt = stmt
        self.coord = coord

    def children(self):
        nodelist = []
        if self.cond is not None:
            nodelist.append(("cond", self.cond))
        if self.stmt is not None:
            nodelist.append(("stmt", self.stmt))
        return tuple(nodelist)

    def __iter__(self):
        if self.cond is not None:
            yield self.cond
        if self.stmt is not None:
            yield self.stmt

    attr_names = ()


class EllipsisParam(Node):
    __slots__ = ("coord", "__weakref__")

    def __init__(self, coord=None):
        self.coord = coord

    def children(self):
        return ()

    def __iter__(self):
        return
        yield

    attr_names = ()


class EmptyStatement(Node):
    __slots__ = ("coord", "__weakref__")

    def __init__(self, coord=None):
        self.coord = coord

    def children(self):
        return ()

    def __iter__(self):
        return
        yield

    attr_names = ()


class Enum(Node):
    __slots__ = (
        "name",
        "values",
        "underlying_type",
        "attributes",
        "coord",
        "__weakref__",
    )

    def __init__(self, name, values, underlying_type, coord=None, *, attributes=None):
        self.name = name
        self.values = values
        self.underlying_type = underlying_type
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        if self.values is not None:
            nodelist.append(("values", self.values))
        if self.underlying_type is not None:
            nodelist.append(("underlying_type", self.underlying_type))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.values is not None:
            yield self.values
        if self.underlying_type is not None:
            yield self.underlying_type
        yield from self.attributes or []

    attr_names = ("name",)


class Enumerator(Node):
    __slots__ = ("name", "value", "attributes", "coord", "__weakref__")

    def __init__(self, name, value, coord=None, *, attributes=None):
        self.name = name
        self.value = value
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        if self.value is not None:
            nodelist.append(("value", self.value))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.value is not None:
            yield self.value
        yield from self.attributes or []

    attr_names = ("name",)


class EnumeratorList(Node):
    __slots__ = ("enumerators", "coord", "__weakref__")

    def __init__(self, enumerators, coord=None):
        self.enumerators = enumerators
        self.coord = coord

    def children(self):
        nodelist = []
        for i, child in enumerate(self.enumerators or []):
            nodelist.append((f"enumerators[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        yield from self.enumerators or []

    attr_names = ()


class ExprList(Node):
    __slots__ = ("exprs", "coord", "__weakref__")

    def __init__(self, exprs, coord=None):
        self.exprs = exprs
        self.coord = coord

    def children(self):
        nodelist = []
        for i, child in enumerate(self.exprs or []):
            nodelist.append((f"exprs[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        yield from self.exprs or []

    attr_names = ()


class FileAST(Node):
    __slots__ = ("ext", "coord", "__weakref__")

    def __init__(self, ext, coord=None):
        self.ext = ext
        self.coord = coord

    def children(self):
        nodelist = []
        for i, child in enumerate(self.ext or []):
            nodelist.append((f"ext[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        yield from self.ext or []

    attr_names = ()


class For(Node):
    __slots__ = ("init", "cond", "next", "stmt", "coord", "__weakref__")

    def __init__(self, init, cond, next, stmt, coord=None):
        self.init = init
        self.cond = cond
        self.next = next
        self.stmt = stmt
        self.coord = coord

    def children(self):
        nodelist = []
        if self.init is not None:
            nodelist.append(("init", self.init))
        if self.cond is not None:
            nodelist.append(("cond", self.cond))
        if self.next is not None:
            nodelist.append(("next", self.next))
        if self.stmt is not None:
            nodelist.append(("stmt", self.stmt))
        return tuple(nodelist)

    def __iter__(self):
        if self.init is not None:
            yield self.init
        if self.cond is not None:
            yield self.cond
        if self.next is not None:
            yield self.next
        if self.stmt is not None:
            yield self.stmt

    attr_names = ()


class FuncCall(Node):
    __slots__ = ("name", "args", "coord", "__weakref__")

    def __init__(self, name, args, coord=None):
        self.name = name
        self.args = args
        self.coord = coord

    def children(self):
        nodelist = []
        if self.name is not None:
            nodelist.append(("name", self.name))
        if self.args is not None:
            nodelist.append(("args", self.args))
        return tuple(nodelist)

    def __iter__(self):
        if self.name is not None:
            yield self.name
        if self.args is not None:
            yield self.args

    attr_names = ()


class FuncDecl(Node):
    __slots__ = ("args", "type", "attributes", "coord", "__weakref__")

    def __init__(self, args, type, coord=None, *, attributes=None):
        self.args = args
        self.type = type
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        if self.args is not None:
            nodelist.append(("args", self.args))
        if self.type is not None:
            nodelist.append(("type", self.type))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.args is not None:
            yield self.args
        if self.type is not None:
            yield self.type
        yield from self.attributes or []

    attr_names = ()


class FuncDef(Node):
    __slots__ = ("decl", "param_decls", "body", "coord", "__weakref__")

    def __init__(self, decl, param_decls, body, coord=None):
        self.decl = decl
        self.param_decls = param_decls
        self.body = body
        self.coord = coord

    def children(self):
        nodelist = []
        if self.decl is not None:
            nodelist.append(("decl", self.decl))
        if self.body is not None:
            nodelist.append(("body", self.body))
        for i, child in enumerate(self.param_decls or []):
            nodelist.append((f"param_decls[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.decl is not None:
            yield self.decl
        if self.body is not None:
            yield self.body
        yield from self.param_decls or []

    attr_names = ()


class GenericAssociation(Node):
    __slots__ = ("type", "expr", "coord", "__weakref__")

    def __init__(self, type, expr, coord=None):
        self.type = type
        self.expr = expr
        self.coord = coord

    def children(self):
        nodelist = []
        if self.type is not None:
            nodelist.append(("type", self.type))
        if self.expr is not None:
            nodelist.append(("expr", self.expr))
        return tuple(nodelist)

    def __iter__(self):
        if self.type is not None:
            yield self.type
        if self.expr is not None:
            yield self.expr

    attr_names = ()


class GenericSelection(Node):
    __slots__ = ("expr", "associations", "coord", "__weakref__")

    def __init__(self, expr, associations, coord=None):
        self.expr = expr
        self.associations = associations
        self.coord = coord

    def children(self):
        nodelist = []
        if self.expr is not None:
            nodelist.append(("expr", self.expr))
        for i, child in enumerate(self.associations or []):
            nodelist.append((f"associations[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.expr is not None:
            yield self.expr
        yield from self.associations or []

    attr_names = ()


class Goto(Node):
    __slots__ = ("name", "coord", "__weakref__")

    def __init__(self, name, coord=None):
        self.name = name
        self.coord = coord

    def children(self):
        nodelist = []
        return tuple(nodelist)

    def __iter__(self):
        return
        yield

    attr_names = ("name",)


class ID(Node):
    __slots__ = ("name", "coord", "__weakref__")

    def __init__(self, name, coord=None):
        self.name = name
        self.coord = coord

    def children(self):
        nodelist = []
        return tuple(nodelist)

    def __iter__(self):
        return
        yield

    attr_names = ("name",)


class IdentifierType(Node):
    __slots__ = ("names", "coord", "__weakref__")

    def __init__(self, names, coord=None):
        self.names = names
        self.coord = coord

    def children(self):
        nodelist = []
        return tuple(nodelist)

    def __iter__(self):
        return
        yield

    attr_names = ("names",)


class If(Node):
    __slots__ = ("cond", "iftrue", "iffalse", "coord", "__weakref__")

    def __init__(self, cond, iftrue, iffalse, coord=None):
        self.cond = cond
        self.iftrue = iftrue
        self.iffalse = iffalse
        self.coord = coord

    def children(self):
        nodelist = []
        if self.cond is not None:
            nodelist.append(("cond", self.cond))
        if self.iftrue is not None:
            nodelist.append(("iftrue", self.iftrue))
        if self.iffalse is not None:
            nodelist.append(("iffalse", self.iffalse))
        return tuple(nodelist)

    def __iter__(self):
        if self.cond is not None:
            yield self.cond
        if self.iftrue is not None:
            yield self.iftrue
        if self.iffalse is not None:
            yield self.iffalse

    attr_names = ()


class InferredType(Node):
    __slots__ = ("coord", "__weakref__")

    def __init__(self, coord=None):
        self.coord = coord

    def children(self):
        return ()

    def __iter__(self):
        return
        yield

    attr_names = ()


class InitList(Node):
    __slots__ = ("exprs", "coord", "__weakref__")

    def __init__(self, exprs, coord=None):
        self.exprs = exprs
        self.coord = coord

    def children(self):
        nodelist = []
        for i, child in enumerate(self.exprs or []):
            nodelist.append((f"exprs[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        yield from self.exprs or []

    attr_names = ()


class Label(Node):
    __slots__ = ("name", "stmt", "attributes", "coord", "__weakref__")

    def __init__(self, name, stmt, coord=None, *, attributes=None):
        self.name = name
        self.stmt = stmt
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        if self.stmt is not None:
            nodelist.append(("stmt", self.stmt))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.stmt is not None:
            yield self.stmt
        yield from self.attributes or []

    attr_names = ("name",)


class NamedInitializer(Node):
    __slots__ = ("name", "expr", "coord", "__weakref__")

    def __init__(self, name, expr, coord=None):
        self.name = name
        self.expr = expr
        self.coord = coord

    def children(self):
        nodelist = []
        if self.expr is not None:
            nodelist.append(("expr", self.expr))
        for i, child in enumerate(self.name or []):
            nodelist.append((f"name[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.expr is not None:
            yield self.expr
        yield from self.name or []

    attr_names = ()


class ParamList(Node):
    __slots__ = ("params", "coord", "__weakref__")

    def __init__(self, params, coord=None):
        self.params = params
        self.coord = coord

    def children(self):
        nodelist = []
        for i, child in enumerate(self.params or []):
            nodelist.append((f"params[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        yield from self.params or []

    attr_names = ()


class PtrDecl(Node):
    __slots__ = ("quals", "type", "attributes", "coord", "__weakref__")

    def __init__(self, quals, type, coord=None, *, attributes=None):
        self.quals = quals
        self.type = type
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        if self.type is not None:
            nodelist.append(("type", self.type))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.type is not None:
            yield self.type
        yield from self.attributes or []

    attr_names = ("quals",)


class Return(Node):
    __slots__ = ("expr", "coord", "__weakref__")

    def __init__(self, expr, coord=None):
        self.expr = expr
        self.coord = coord

    def children(self):
        nodelist = []
        if self.expr is not None:
            nodelist.append(("expr", self.expr))
        return tuple(nodelist)

    def __iter__(self):
        if self.expr is not None:
            yield self.expr

    attr_names = ()


class StaticAssert(Node):
    __slots__ = ("cond", "message", "coord", "__weakref__")

    def __init__(self, cond, message, coord=None):
        self.cond = cond
        self.message = message
        self.coord = coord

    def children(self):
        nodelist = []
        if self.cond is not None:
            nodelist.append(("cond", self.cond))
        if self.message is not None:
            nodelist.append(("message", self.message))
        return tuple(nodelist)

    def __iter__(self):
        if self.cond is not None:
            yield self.cond
        if self.message is not None:
            yield self.message

    attr_names = ()


class Struct(Node):
    __slots__ = ("name", "decls", "attributes", "coord", "__weakref__")

    def __init__(self, name, decls, coord=None, *, attributes=None):
        self.name = name
        self.decls = decls
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        for i, child in enumerate(self.decls or []):
            nodelist.append((f"decls[{i}]", child))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        yield from self.decls or []
        yield from self.attributes or []

    attr_names = ("name",)


class StructRef(Node):
    __slots__ = ("name", "type", "field", "coord", "__weakref__")

    def __init__(self, name, type, field, coord=None):
        self.name = name
        self.type = type
        self.field = field
        self.coord = coord

    def children(self):
        nodelist = []
        if self.name is not None:
            nodelist.append(("name", self.name))
        if self.field is not None:
            nodelist.append(("field", self.field))
        return tuple(nodelist)

    def __iter__(self):
        if self.name is not None:
            yield self.name
        if self.field is not None:
            yield self.field

    attr_names = ("type",)


class Switch(Node):
    __slots__ = ("cond", "stmt", "coord", "__weakref__")

    def __init__(self, cond, stmt, coord=None):
        self.cond = cond
        self.stmt = stmt
        self.coord = coord

    def children(self):
        nodelist = []
        if self.cond is not None:
            nodelist.append(("cond", self.cond))
        if self.stmt is not None:
            nodelist.append(("stmt", self.stmt))
        return tuple(nodelist)

    def __iter__(self):
        if self.cond is not None:
            yield self.cond
        if self.stmt is not None:
            yield self.stmt

    attr_names = ()


class TernaryOp(Node):
    __slots__ = ("cond", "iftrue", "iffalse", "coord", "__weakref__")

    def __init__(self, cond, iftrue, iffalse, coord=None):
        self.cond = cond
        self.iftrue = iftrue
        self.iffalse = iffalse
        self.coord = coord

    def children(self):
        nodelist = []
        if self.cond is not None:
            nodelist.append(("cond", self.cond))
        if self.iftrue is not None:
            nodelist.append(("iftrue", self.iftrue))
        if self.iffalse is not None:
            nodelist.append(("iffalse", self.iffalse))
        return tuple(nodelist)

    def __iter__(self):
        if self.cond is not None:
            yield self.cond
        if self.iftrue is not None:
            yield self.iftrue
        if self.iffalse is not None:
            yield self.iffalse

    attr_names = ()


class TypeDecl(Node):
    __slots__ = (
        "declname",
        "quals",
        "align",
        "type",
        "attributes",
        "coord",
        "__weakref__",
    )

    def __init__(self, declname, quals, align, type, coord=None, *, attributes=None):
        self.declname = declname
        self.quals = quals
        self.align = align
        self.type = type
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        if self.type is not None:
            nodelist.append(("type", self.type))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.type is not None:
            yield self.type
        yield from self.attributes or []

    attr_names = (
        "declname",
        "quals",
        "align",
    )


class Typedef(Node):
    __slots__ = (
        "name",
        "quals",
        "storage",
        "type",
        "attributes",
        "coord",
        "__weakref__",
    )

    def __init__(self, name, quals, storage, type, coord=None, *, attributes=None):
        self.name = name
        self.quals = quals
        self.storage = storage
        self.type = type
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        if self.type is not None:
            nodelist.append(("type", self.type))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.type is not None:
            yield self.type
        yield from self.attributes or []

    attr_names = (
        "name",
        "quals",
        "storage",
    )


class Typename(Node):
    __slots__ = ("name", "quals", "align", "type", "attributes", "coord", "__weakref__")

    def __init__(self, name, quals, align, type, coord=None, *, attributes=None):
        self.name = name
        self.quals = quals
        self.align = align
        self.type = type
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        if self.type is not None:
            nodelist.append(("type", self.type))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        if self.type is not None:
            yield self.type
        yield from self.attributes or []

    attr_names = (
        "name",
        "quals",
        "align",
    )


class TypeOf(Node):
    __slots__ = ("op", "expr", "coord", "__weakref__")

    def __init__(self, op, expr, coord=None):
        self.op = op
        self.expr = expr
        self.coord = coord

    def children(self):
        nodelist = []
        if self.expr is not None:
            nodelist.append(("expr", self.expr))
        return tuple(nodelist)

    def __iter__(self):
        if self.expr is not None:
            yield self.expr

    attr_names = ("op",)


class UnaryOp(Node):
    __slots__ = ("op", "expr", "coord", "__weakref__")

    def __init__(self, op, expr, coord=None):
        self.op = op
        self.expr = expr
        self.coord = coord

    def children(self):
        nodelist = []
        if self.expr is not None:
            nodelist.append(("expr", self.expr))
        return tuple(nodelist)

    def __iter__(self):
        if self.expr is not None:
            yield self.expr

    attr_names = ("op",)


class Union(Node):
    __slots__ = ("name", "decls", "attributes", "coord", "__weakref__")

    def __init__(self, name, decls, coord=None, *, attributes=None):
        self.name = name
        self.decls = decls
        self.attributes = [] if attributes is None else attributes
        self.coord = coord

    def children(self):
        nodelist = []
        for i, child in enumerate(self.decls or []):
            nodelist.append((f"decls[{i}]", child))
        for i, child in enumerate(self.attributes or []):
            nodelist.append((f"attributes[{i}]", child))
        return tuple(nodelist)

    def __iter__(self):
        yield from self.decls or []
        yield from self.attributes or []

    attr_names = ("name",)


class While(Node):
    __slots__ = ("cond", "stmt", "coord", "__weakref__")

    def __init__(self, cond, stmt, coord=None):
        self.cond = cond
        self.stmt = stmt
        self.coord = coord

    def children(self):
        nodelist = []
        if self.cond is not None:
            nodelist.append(("cond", self.cond))
        if self.stmt is not None:
            nodelist.append(("stmt", self.stmt))
        return tuple(nodelist)

    def __iter__(self):
        if self.cond is not None:
            yield self.cond
        if self.stmt is not None:
            yield self.stmt

    attr_names = ()


class Pragma(Node):
    __slots__ = ("string", "coord", "__weakref__")

    def __init__(self, string, coord=None):
        self.string = string
        self.coord = coord

    def children(self):
        nodelist = []
        return tuple(nodelist)

    def __iter__(self):
        return
        yield

    attr_names = ("string",)
