"""Code generation for native classes and related wrappers."""

from __future__ import annotations

from collections.abc import Callable, Mapping

from mypy.nodes import ARG_STAR, ARG_STAR2
from mypyc.codegen.cstring import c_string_initializer
from mypyc.codegen.emit import (
    Emitter,
    HeaderDeclaration,
    ReturnHandler,
    native_function_doc_initializer,
)
from mypyc.codegen.emitfunc import native_function_header
from mypyc.codegen.emitwrapper import (
    generate_am_send_wrapper,
    generate_bin_op_wrapper,
    generate_bool_wrapper,
    generate_contains_wrapper,
    generate_dunder_wrapper,
    generate_get_wrapper,
    generate_hash_wrapper,
    generate_ipow_wrapper,
    generate_len_wrapper,
    generate_richcompare_wrapper,
    generate_set_del_item_wrapper,
)
from mypyc.common import (
    BITMAP_BITS,
    BITMAP_TYPE,
    CPYFUNCTION_NAME,
    GENERATOR_HELPER_NAME,
    IS_FREE_THREADED,
    MYPYC_DEFAULTS_SETUP,
    NATIVE_PREFIX,
    PREFIX,
    REG_PREFIX,
    RUNNING_FIELD,
    short_id_from_name,
)
from mypyc.ir.class_ir import ClassIR, VTableEntries
from mypyc.ir.func_ir import (
    FUNC_CLASSMETHOD,
    FUNC_STATICMETHOD,
    FuncDecl,
    FuncIR,
    get_text_signature,
)
from mypyc.ir.rtypes import RTuple, RType, is_simple_refcounted_pointer, object_rprimitive
from mypyc.namegen import NameGenerator
from mypyc.sametype import is_same_type


def native_slot(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str:
    return f"{NATIVE_PREFIX}{fn.cname(emitter.names)}"


def dunder_attr_slot(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str:
    wrapper_fn = cl.get_method(fn.name + "__wrapper")
    assert wrapper_fn
    return f"{NATIVE_PREFIX}{wrapper_fn.cname(emitter.names)}"


# We maintain a table from dunder function names to struct slots they
# correspond to and functions that generate a wrapper (if necessary)
# and return the function name to stick in the slot.
# TODO: Add remaining dunder methods
SlotGenerator = Callable[[ClassIR, FuncIR, Emitter], str]
SlotTable = Mapping[str, tuple[str, SlotGenerator]]

SLOT_DEFS: SlotTable = {
    "__init__": ("tp_init", lambda c, t, e: generate_init_for_class(c, t, e)),
    "__call__": ("tp_call", lambda c, t, e: generate_call_wrapper(c, t, e)),
    "__str__": ("tp_str", native_slot),
    "__repr__": ("tp_repr", native_slot),
    "__next__": ("tp_iternext", native_slot),
    "__iter__": ("tp_iter", native_slot),
    "__hash__": ("tp_hash", generate_hash_wrapper),
    "__get__": ("tp_descr_get", generate_get_wrapper),
    "__getattr__": ("tp_getattro", dunder_attr_slot),
    "__setattr__": ("tp_setattro", dunder_attr_slot),
}

AS_MAPPING_SLOT_DEFS: SlotTable = {
    "__getitem__": ("mp_subscript", generate_dunder_wrapper),
    "__setitem__": ("mp_ass_subscript", generate_set_del_item_wrapper),
    "__delitem__": ("mp_ass_subscript", generate_set_del_item_wrapper),
    "__len__": ("mp_length", generate_len_wrapper),
}

AS_SEQUENCE_SLOT_DEFS: SlotTable = {"__contains__": ("sq_contains", generate_contains_wrapper)}

AS_NUMBER_SLOT_DEFS: SlotTable = {
    # Unary operations.
    "__bool__": ("nb_bool", generate_bool_wrapper),
    "__int__": ("nb_int", generate_dunder_wrapper),
    "__float__": ("nb_float", generate_dunder_wrapper),
    "__neg__": ("nb_negative", generate_dunder_wrapper),
    "__pos__": ("nb_positive", generate_dunder_wrapper),
    "__abs__": ("nb_absolute", generate_dunder_wrapper),
    "__invert__": ("nb_invert", generate_dunder_wrapper),
    # Binary operations.
    "__add__": ("nb_add", generate_bin_op_wrapper),
    "__radd__": ("nb_add", generate_bin_op_wrapper),
    "__sub__": ("nb_subtract", generate_bin_op_wrapper),
    "__rsub__": ("nb_subtract", generate_bin_op_wrapper),
    "__mul__": ("nb_multiply", generate_bin_op_wrapper),
    "__rmul__": ("nb_multiply", generate_bin_op_wrapper),
    "__mod__": ("nb_remainder", generate_bin_op_wrapper),
    "__rmod__": ("nb_remainder", generate_bin_op_wrapper),
    "__truediv__": ("nb_true_divide", generate_bin_op_wrapper),
    "__rtruediv__": ("nb_true_divide", generate_bin_op_wrapper),
    "__floordiv__": ("nb_floor_divide", generate_bin_op_wrapper),
    "__rfloordiv__": ("nb_floor_divide", generate_bin_op_wrapper),
    "__divmod__": ("nb_divmod", generate_bin_op_wrapper),
    "__rdivmod__": ("nb_divmod", generate_bin_op_wrapper),
    "__lshift__": ("nb_lshift", generate_bin_op_wrapper),
    "__rlshift__": ("nb_lshift", generate_bin_op_wrapper),
    "__rshift__": ("nb_rshift", generate_bin_op_wrapper),
    "__rrshift__": ("nb_rshift", generate_bin_op_wrapper),
    "__and__": ("nb_and", generate_bin_op_wrapper),
    "__rand__": ("nb_and", generate_bin_op_wrapper),
    "__or__": ("nb_or", generate_bin_op_wrapper),
    "__ror__": ("nb_or", generate_bin_op_wrapper),
    "__xor__": ("nb_xor", generate_bin_op_wrapper),
    "__rxor__": ("nb_xor", generate_bin_op_wrapper),
    "__matmul__": ("nb_matrix_multiply", generate_bin_op_wrapper),
    "__rmatmul__": ("nb_matrix_multiply", generate_bin_op_wrapper),
    # In-place binary operations.
    "__iadd__": ("nb_inplace_add", generate_dunder_wrapper),
    "__isub__": ("nb_inplace_subtract", generate_dunder_wrapper),
    "__imul__": ("nb_inplace_multiply", generate_dunder_wrapper),
    "__imod__": ("nb_inplace_remainder", generate_dunder_wrapper),
    "__itruediv__": ("nb_inplace_true_divide", generate_dunder_wrapper),
    "__ifloordiv__": ("nb_inplace_floor_divide", generate_dunder_wrapper),
    "__ilshift__": ("nb_inplace_lshift", generate_dunder_wrapper),
    "__irshift__": ("nb_inplace_rshift", generate_dunder_wrapper),
    "__iand__": ("nb_inplace_and", generate_dunder_wrapper),
    "__ior__": ("nb_inplace_or", generate_dunder_wrapper),
    "__ixor__": ("nb_inplace_xor", generate_dunder_wrapper),
    "__imatmul__": ("nb_inplace_matrix_multiply", generate_dunder_wrapper),
    # Ternary operations. (yes, really)
    # These are special cased in generate_bin_op_wrapper().
    "__pow__": ("nb_power", generate_bin_op_wrapper),
    "__rpow__": ("nb_power", generate_bin_op_wrapper),
    "__ipow__": ("nb_inplace_power", generate_ipow_wrapper),
}

AS_ASYNC_SLOT_DEFS: SlotTable = {
    "__await__": ("am_await", native_slot),
    "__aiter__": ("am_aiter", native_slot),
    "__anext__": ("am_anext", native_slot),
    # Generator and coroutine classes get an am_send slot based on the generator helper
    # method, so that PyIter_Send can drive them without raising StopIteration.
    GENERATOR_HELPER_NAME: ("am_send", generate_am_send_wrapper),
}

SIDE_TABLES = [
    ("as_mapping", "PyMappingMethods", AS_MAPPING_SLOT_DEFS),
    ("as_sequence", "PySequenceMethods", AS_SEQUENCE_SLOT_DEFS),
    ("as_number", "PyNumberMethods", AS_NUMBER_SLOT_DEFS),
    ("as_async", "PyAsyncMethods", AS_ASYNC_SLOT_DEFS),
]

# Slots that need to always be filled in because they don't get
# inherited right.
ALWAYS_FILL = {"__hash__"}


def generate_call_wrapper(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str:
    return "PyVectorcall_Call"


def slot_key(attr: str) -> str:
    """Map dunder method name to sort key.

    Sort reverse operator methods and __delitem__ after others ('x' > '_').
    """
    if (attr.startswith("__r") and attr != "__rshift__") or attr == "__delitem__":
        return "x" + attr
    return attr


def generate_slots(cl: ClassIR, table: SlotTable, emitter: Emitter) -> dict[str, str]:
    fields: dict[str, str] = {}
    generated: dict[str, str] = {}
    # Sort for determinism on Python 3.5
    for name, (slot, generator) in sorted(table.items(), key=lambda x: slot_key(x[0])):
        method_cls = cl.get_method_and_class(name)
        if method_cls and (method_cls[1] == cl or name in ALWAYS_FILL):
            if slot in generated:
                # Reuse previously generated wrapper.
                fields[slot] = generated[slot]
            else:
                # Generate new wrapper.
                name = generator(cl, method_cls[0], emitter)
                fields[slot] = name
                generated[slot] = name

    return fields


def generate_class_type_decl(
    cl: ClassIR, c_emitter: Emitter, external_emitter: Emitter, emitter: Emitter
) -> None:
    context = c_emitter.context
    name = emitter.type_struct_name(cl)
    context.declarations[name] = HeaderDeclaration(
        f"PyTypeObject *{emitter.type_struct_name(cl)};", needs_export=True
    )

    # If this is a non-extension class, all we want is the type object decl.
    if not cl.is_ext_class:
        return

    generate_object_struct(cl, external_emitter)
    generate_full = not cl.is_trait and not cl.builtin_base
    if generate_full:
        context.declarations[emitter.native_function_name(cl.ctor)] = HeaderDeclaration(
            f"{native_function_header(cl.ctor, emitter)};", needs_export=True
        )


def generate_class_reuse(
    cl: ClassIR, c_emitter: Emitter, external_emitter: Emitter, emitter: Emitter
) -> None:
    """Generate a definition of a single-object per-class free "list".

    This speeds up object allocation and freeing when there are many short-lived
    objects.

    TODO: Generalize to support a free list with up to N objects.
    """
    assert cl.reuse_freed_instance
    context = c_emitter.context
    name = cl.name_prefix(c_emitter.names) + "_free_instance"
    struct_name = cl.struct_name(c_emitter.names)
    # Not exported: the free-instance slot is only read/written by the class's
    # own setup/dealloc code, which lives in the defining group. Exporting it
    # also trips a C diagnostic under `Py_GIL_DISABLED`, where `CPyThreadLocal`
    # expands to `__thread` and can't legally appear inside the exports struct.
    context.declarations[name] = HeaderDeclaration(f"CPyThreadLocal {struct_name} *{name};")


def generate_class(cl: ClassIR, module: str, emitter: Emitter) -> None:
    """Generate C code for a class.

    This is the main entry point to the module.
    """
    name = cl.name
    name_prefix = cl.name_prefix(emitter.names)

    setup_name = emitter.native_function_name(cl.setup)
    new_name = f"{name_prefix}_new"
    finalize_name = f"{name_prefix}_finalize"
    members_name = f"{name_prefix}_members"
    getseters_name = f"{name_prefix}_getseters"
    vtable_name = f"{name_prefix}_vtable"
    traverse_name = f"{name_prefix}_traverse"
    clear_name = emitter.native_function_name(cl.clear)
    clear_subtype_name = f"{clear_name}_subtype"
    clear_on_completion_name = emitter.native_function_name(cl.clear_on_completion)
    clear_on_completion_subtype_name = f"{clear_on_completion_name}_subtype"
    dealloc_name = f"{name_prefix}_dealloc"
    methods_name = f"{name_prefix}_methods"
    vtable_setup_name = f"{name_prefix}_trait_vtable_setup"
    coroutine_setup_name = f"{name_prefix}_coroutine_setup"

    fields: dict[str, str] = {"tp_name": f'"{name}"'}

    generate_full = not cl.is_trait and not cl.builtin_base
    needs_getseters = cl.needs_getseters_table

    if not cl.builtin_base:
        fields["tp_new"] = new_name

    managed_dict = has_managed_dict(cl, emitter)
    # On Python <3.12, subclasses of builtin types (Exception, dict) get an extra __dict__
    # slot that the inherited base dealloc knows nothing about. Emit our own so it gets freed.
    needs_builtin_dict_cleanup = (
        cl.builtin_base is not None
        and cl.has_dict
        and not managed_dict
        and emitter.capi_version < (3, 12)
    )
    generate_dealloc_slots = generate_full or managed_dict or needs_builtin_dict_cleanup
    if generate_dealloc_slots:
        fields["tp_dealloc"] = f"(destructor){name_prefix}_dealloc"
        if not cl.is_acyclic:
            fields["tp_traverse"] = f"(traverseproc){name_prefix}_traverse"
            fields["tp_clear"] = f"(inquiry){clear_name}"
    # Populate .tp_finalize and generate a finalize method only if __del__ is defined for this class.
    del_method = next((e.method for e in cl.vtable_entries if e.name == "__del__"), None)
    if del_method:
        fields["tp_finalize"] = f"(destructor){finalize_name}"
    if needs_getseters:
        fields["tp_getset"] = getseters_name
    fields["tp_methods"] = methods_name

    def emit_line() -> None:
        emitter.emit_line()

    emit_line()

    # If the class has a method to initialize default attribute
    # values, we need to call it during initialization.
    defaults_fn = cl.get_method(MYPYC_DEFAULTS_SETUP)

    # If there is a __init__ method, we'll use it in the native constructor.
    init_fn = cl.get_method("__init__")

    # Fill out slots in the type object from dunder methods.
    fields.update(generate_slots(cl, SLOT_DEFS, emitter))

    # Fill out dunder methods that live in tables hanging off the side.
    for table_name, type, slot_defs in SIDE_TABLES:
        slots = generate_slots(cl, slot_defs, emitter)
        if slots:
            table_struct_name = generate_side_table_for_class(cl, table_name, type, slots, emitter)
            fields[f"tp_{table_name}"] = f"&{table_struct_name}"

    richcompare_name = generate_richcompare_wrapper(cl, emitter)
    if richcompare_name:
        fields["tp_richcompare"] = richcompare_name

    # If the class inherits from python, make space for a __dict__
    struct_name = cl.struct_name(emitter.names)
    if cl.builtin_base:
        base_size = f"sizeof({cl.builtin_base})"
    elif cl.is_trait:
        base_size = "sizeof(PyObject)"
    else:
        base_size = f"sizeof({struct_name})"
    # Since our types aren't allocated using type() we need to
    # populate these fields ourselves if we want them to have correct
    # values. PyType_Ready will inherit the offsets from tp_base but
    # that isn't what we want.

    # XXX: there is no reason for the __weakref__ stuff to be mixed up with __dict__
    if cl.has_dict and not has_managed_dict(cl, emitter):
        # __dict__ lives right after the struct and __weakref__ lives right after that
        # TODO: They should get members in the struct instead of doing this nonsense.
        weak_offset = f"{base_size} + sizeof(PyObject *)"
        emitter.emit_lines(
            f"PyMemberDef {members_name}[] = {{",
            f'{{"__dict__", T_OBJECT_EX, {base_size}, 0, NULL}},',
            f'{{"__weakref__", T_OBJECT_EX, {weak_offset}, 0, NULL}},',
            "{0}",
            "};",
        )

        fields["tp_members"] = members_name
        fields["tp_basicsize"] = f"{base_size} + 2*sizeof(PyObject *)"
        if emitter.capi_version < (3, 12):
            fields["tp_dictoffset"] = base_size
            fields["tp_weaklistoffset"] = weak_offset
    else:
        fields["tp_basicsize"] = base_size

    if generate_dealloc_slots:
        if not cl.is_acyclic:
            generate_traverse_for_class(cl, traverse_name, emitter)
            emit_line()
        subtype_clear_name = None
        if cl.builtin_base:
            # During dealloc, the object has refcount 0, and builtin tp_clear
            # implementations are not generally valid to call in that state. In
            # particular, dict.tp_clear notifies watchers and requires a live
            # object. Split subtype-owned clearing from base-owned clearing so
            # tp_clear can still delegate to the base, while tp_dealloc only
            # clears mypyc-owned state before delegating to the base deallocator.
            generate_subtype_clear_for_class(cl, clear_subtype_name, emitter)
            emit_line()
            subtype_clear_name = clear_subtype_name
        generate_clear_for_class(cl, cl.clear, emitter, subtype_clear_name=subtype_clear_name)
        emit_line()
        if cl.builtin_base:
            generate_subtype_clear_for_class(
                cl,
                clear_on_completion_subtype_name,
                emitter,
                skip_attrs=cl.attrs_to_keep_alive_on_completion,
            )
            emit_line()
            subtype_clear_name = clear_on_completion_subtype_name
        generate_clear_for_class(
            cl,
            cl.clear_on_completion,
            emitter,
            subtype_clear_name=subtype_clear_name,
            skip_attrs=cl.attrs_to_keep_alive_on_completion,
        )
        emit_line()
        dealloc_clear_name = clear_subtype_name if cl.builtin_base else clear_name
        generate_dealloc_for_class(cl, dealloc_name, dealloc_clear_name, bool(del_method), emitter)
        emit_line()
    if generate_full:
        assert cl.setup is not None
        emitter.emit_line(native_function_header(cl.setup, emitter) + ";")
        assert cl.ctor is not None
        emitter.emit_line(native_function_header(cl.ctor, emitter) + ";")

        emit_line()
        init_fn = cl.get_method("__init__")
        generate_new_for_class(cl, new_name, vtable_name, setup_name, init_fn, emitter)
        emit_line()

        if cl.allow_interpreted_subclasses:
            shadow_vtable_name: str | None = generate_vtables(
                cl, vtable_setup_name + "_shadow", vtable_name + "_shadow", emitter, shadow=True
            )
            emit_line()
        else:
            shadow_vtable_name = None
        vtable_name = generate_vtables(cl, vtable_setup_name, vtable_name, emitter, shadow=False)
        emit_line()
        generate_coroutine_setup(cl, coroutine_setup_name, module, emitter)
        emit_line()
    if del_method:
        generate_finalize_for_class(del_method, finalize_name, emitter)
        emit_line()
    if needs_getseters:
        generate_getseter_declarations(cl, emitter)
        emit_line()
        generate_getseters_table(cl, getseters_name, emitter)
        emit_line()

    if cl.is_trait:
        generate_new_for_trait(cl, new_name, emitter)

    generate_methods_table(cl, methods_name, setup_name if generate_full else None, emitter)
    emit_line()

    flags = ["Py_TPFLAGS_DEFAULT", "Py_TPFLAGS_HEAPTYPE", "Py_TPFLAGS_BASETYPE"]
    if generate_dealloc_slots and not cl.is_acyclic:
        # Set explicitly: PyType_Ready won't inherit HAVE_GC once we override tp_dealloc/traverse.
        flags.append("Py_TPFLAGS_HAVE_GC")
    if cl.has_method("__call__"):
        fields["tp_vectorcall_offset"] = "offsetof({}, vectorcall)".format(
            cl.struct_name(emitter.names)
        )
        flags.append("_Py_TPFLAGS_HAVE_VECTORCALL")
        if not fields.get("tp_vectorcall"):
            # This is just a placeholder to please CPython. It will be
            # overridden during setup.
            fields["tp_call"] = "PyVectorcall_Call"
    if managed_dict:
        flags.append("Py_TPFLAGS_MANAGED_DICT")
    fields["tp_flags"] = " | ".join(flags)

    fields["tp_doc"] = f"PyDoc_STR({native_class_doc_initializer(cl)})"

    emitter.emit_line(f"static PyTypeObject {emitter.type_struct_name(cl)}_template_ = {{")
    emitter.emit_line("PyVarObject_HEAD_INIT(NULL, 0)")
    for field, value in fields.items():
        emitter.emit_line(f".{field} = {value},")
    emitter.emit_line("};")
    emitter.emit_line(
        "static PyTypeObject *{t}_template = &{t}_template_;".format(
            t=emitter.type_struct_name(cl)
        )
    )

    if cl.coroutine_name:
        cpyfunction = emitter.static_name(cl.name + "_cpyfunction", module)
        emitter.emit_line(f"static PyObject *{cpyfunction} = NULL;")

    emitter.emit_line()
    if generate_full:
        generate_setup_for_class(cl, defaults_fn, vtable_name, shadow_vtable_name, emitter)
        emitter.emit_line()
        generate_constructor_for_class(cl, cl.ctor, init_fn, setup_name, vtable_name, emitter)
        emitter.emit_line()
    if needs_getseters:
        generate_getseters(cl, emitter)


def getter_name(cl: ClassIR, attribute: str, names: NameGenerator) -> str:
    return names.private_name(cl.module_name, f"{cl.name}_get_{attribute}")


def setter_name(cl: ClassIR, attribute: str, names: NameGenerator) -> str:
    return names.private_name(cl.module_name, f"{cl.name}_set_{attribute}")


def generate_object_struct(cl: ClassIR, emitter: Emitter) -> None:
    seen_attrs: set[str] = set()
    lines: list[str] = []
    lines += ["typedef struct {", "PyObject_HEAD", "CPyVTableItem *vtable;"]
    if cl.has_method("__call__"):
        lines.append("vectorcallfunc vectorcall;")
    # The flag affects attribute offsets, so concrete bases must agree on its presence.
    assert all(
        base.has_running_flag == cl.has_running_flag for base in cl.base_mro
    ), f"{cl.name} disagrees with a base class about the running flag"
    if cl.has_running_flag:
        # This implementation field is intentionally absent from the IR attributes.
        lines.append(f"uint32_t {RUNNING_FIELD};")
    bitmap_attrs = []
    for base in reversed(cl.base_mro):
        if not base.is_trait:
            if base.bitmap_attrs:
                # Do we need another attribute bitmap field?
                if emitter.bitmap_field(len(base.bitmap_attrs) - 1) not in bitmap_attrs:
                    for i in range(0, len(base.bitmap_attrs), BITMAP_BITS):
                        attr = emitter.bitmap_field(i)
                        if attr not in bitmap_attrs:
                            lines.append(f"{BITMAP_TYPE} {attr};")
                            bitmap_attrs.append(attr)
            for attr, rtype in base.attributes.items():
                # Generated class may redefine certain attributes with different
                # types in subclasses (this would be unsafe for user-defined classes).
                if attr not in seen_attrs:
                    lines.append(f"{emitter.ctype_spaced(rtype)}{emitter.attr(attr)};")
                    seen_attrs.add(attr)

                    if isinstance(rtype, RTuple):
                        emitter.declare_tuple_struct(rtype)

    lines.append(f"}} {cl.struct_name(emitter.names)};")
    lines.append("")
    emitter.context.declarations[cl.struct_name(emitter.names)] = HeaderDeclaration(
        lines, is_type=True
    )


def generate_vtables(
    base: ClassIR, vtable_setup_name: str, vtable_name: str, emitter: Emitter, shadow: bool
) -> str:
    """Emit the vtables and vtable setup functions for a class.

    This includes both the primary vtable and any trait implementation vtables.
    The trait vtables go before the main vtable, and have the following layout:
        {
            CPyType_T1,         // pointer to type object
            C_T1_trait_vtable,  // pointer to array of method pointers
            C_T1_offset_table,  // pointer to array of attribute offsets
            CPyType_T2,
            C_T2_trait_vtable,
            C_T2_offset_table,
            ...
        }
    The method implementations are calculated at the end of IR pass, attribute
    offsets are {offsetof(native__C, _x1), offsetof(native__C, _y1), ...}.

    To account for both dynamic loading and dynamic class creation,
    vtables are populated dynamically at class creation time, so we
    emit empty array definitions to store the vtables and a function to
    populate them.

    If shadow is True, generate "shadow vtables" that point to the
    shadow glue methods (which should dispatch via the Python C-API).

    Returns the expression to use to refer to the vtable, which might be
    different than the name, if there are trait vtables.
    """

    def trait_vtable_name(trait: ClassIR) -> str:
        return "{}_{}_trait_vtable{}".format(
            base.name_prefix(emitter.names),
            trait.name_prefix(emitter.names),
            "_shadow" if shadow else "",
        )

    def trait_offset_table_name(trait: ClassIR) -> str:
        return "{}_{}_offset_table".format(
            base.name_prefix(emitter.names), trait.name_prefix(emitter.names)
        )

    # Emit array definitions with enough space for all the entries
    emitter.emit_line(
        "static CPyVTableItem {}[{}];".format(
            vtable_name, max(1, len(base.vtable_entries) + 3 * len(base.trait_vtables))
        )
    )

    for trait, vtable in base.trait_vtables.items():
        # Trait methods entry (vtable index -> method implementation).
        emitter.emit_line(
            f"static CPyVTableItem {trait_vtable_name(trait)}[{max(1, len(vtable))}];"
        )
        # Trait attributes entry (attribute number in trait -> offset in actual struct).
        emitter.emit_line(
            "static size_t {}[{}];".format(
                trait_offset_table_name(trait), max(1, len(trait.attributes))
            )
        )

    # Emit vtable setup function
    emitter.emit_line("static bool")
    emitter.emit_line(f"{NATIVE_PREFIX}{vtable_setup_name}(void)")
    emitter.emit_line("{")

    if base.allow_interpreted_subclasses and not shadow:
        emitter.emit_line(f"{NATIVE_PREFIX}{vtable_setup_name}_shadow();")

    subtables = []
    for trait, vtable in base.trait_vtables.items():
        name = trait_vtable_name(trait)
        offset_name = trait_offset_table_name(trait)
        generate_vtable(vtable, name, emitter, [], shadow)
        generate_offset_table(offset_name, emitter, trait, base)
        subtables.append((trait, name, offset_name))

    generate_vtable(base.vtable_entries, vtable_name, emitter, subtables, shadow)

    emitter.emit_line("return 1;")
    emitter.emit_line("}")

    return vtable_name if not subtables else f"{vtable_name} + {len(subtables) * 3}"


def generate_offset_table(
    trait_offset_table_name: str, emitter: Emitter, trait: ClassIR, cl: ClassIR
) -> None:
    """Generate attribute offset row of a trait vtable."""
    emitter.emit_line(f"size_t {trait_offset_table_name}_scratch[] = {{")
    for attr in trait.attributes:
        emitter.emit_line(f"offsetof({cl.struct_name(emitter.names)}, {emitter.attr(attr)}),")
    if not trait.attributes:
        # This is for msvc.
        emitter.emit_line("0")
    emitter.emit_line("};")
    emitter.emit_line(
        "memcpy({name}, {name}_scratch, sizeof({name}));".format(name=trait_offset_table_name)
    )


def generate_vtable(
    entries: VTableEntries,
    vtable_name: str,
    emitter: Emitter,
    subtables: list[tuple[ClassIR, str, str]],
    shadow: bool,
) -> None:
    emitter.emit_line(f"CPyVTableItem {vtable_name}_scratch[] = {{")
    if subtables:
        emitter.emit_line("/* Array of trait vtables */")
        for trait, table, offset_table in subtables:
            emitter.emit_line(
                "(CPyVTableItem){}, (CPyVTableItem){}, (CPyVTableItem){},".format(
                    emitter.type_struct_name(trait), table, offset_table
                )
            )
        emitter.emit_line("/* Start of real vtable */")

    for entry in entries:
        method = entry.shadow_method if shadow and entry.shadow_method else entry.method
        emitter.emit_line(
            "(CPyVTableItem){}{}{},".format(
                emitter.get_group_prefix(method.decl), NATIVE_PREFIX, method.cname(emitter.names)
            )
        )

    # msvc doesn't allow empty arrays; maybe allowing them at all is an extension?
    if not entries:
        emitter.emit_line("NULL")
    emitter.emit_line("};")
    emitter.emit_line("memcpy({name}, {name}_scratch, sizeof({name}));".format(name=vtable_name))


def generate_setup_for_class(
    cl: ClassIR,
    defaults_fn: FuncIR | None,
    vtable_name: str,
    shadow_vtable_name: str | None,
    emitter: Emitter,
) -> None:
    """Generate a native function that allocates an instance of a class."""
    emitter.emit_line(native_function_header(cl.setup, emitter))
    emitter.emit_line("{")
    type_arg_name = REG_PREFIX + cl.setup.sig.args[0].name
    emitter.emit_line(f"PyTypeObject *type = (PyTypeObject*){type_arg_name};")
    struct_name = cl.struct_name(emitter.names)
    emitter.emit_line(f"{struct_name} *self;")

    prefix = cl.name_prefix(emitter.names)
    if cl.reuse_freed_instance:
        # Attempt to use a per-type free list first (a free "list" with up to one object only).
        emitter.emit_line(f"if ({prefix}_free_instance != NULL) {{")
        emitter.emit_line(f"self = {prefix}_free_instance;")
        emitter.emit_line(f"{prefix}_free_instance = NULL;")
        emitter.emit_line("Py_SET_REFCNT(self, 1);")
        if not cl.is_acyclic:
            emitter.emit_line("PyObject_GC_Track(self);")
        if defaults_fn is not None:
            emit_attr_defaults_func_call(defaults_fn, "self", emitter)
        emitter.emit_line("return (PyObject *)self;")
        emitter.emit_line("}")

    emitter.emit_line(f"self = ({cl.struct_name(emitter.names)} *)type->tp_alloc(type, 0);")
    emitter.emit_line("if (self == NULL)")
    emitter.emit_line("    return NULL;")

    if shadow_vtable_name:
        emitter.emit_line(f"if (type != {emitter.type_struct_name(cl)}) {{")
        emitter.emit_line(f"self->vtable = {shadow_vtable_name};")
        emitter.emit_line("} else {")
        emitter.emit_line(f"self->vtable = {vtable_name};")
        emitter.emit_line("}")
    else:
        emitter.emit_line(f"self->vtable = {vtable_name};")

    emit_clear_bitmaps(cl, emitter)

    if cl.has_method("__call__"):
        name = cl.method_decl("__call__").cname(emitter.names)
        emitter.emit_line(f"self->vectorcall = {PREFIX}{name};")

    for base in reversed(cl.base_mro):
        for attr, rtype in base.attributes.items():
            value = emitter.c_undefined_value(rtype)

            # We don't need to set this field to NULL since tp_alloc() already
            # zero-initializes `self`.
            if value != "NULL":
                emitter.set_undefined_value(f"self->{emitter.attr(attr)}", rtype)

    # Initialize attributes to default values, if necessary
    if defaults_fn is not None:
        emit_attr_defaults_func_call(defaults_fn, "self", emitter)

    emitter.emit_line("return (PyObject *)self;")
    emitter.emit_line("}")


def emit_clear_bitmaps(cl: ClassIR, emitter: Emitter) -> None:
    """Emit C code to clear bitmaps that track if attributes have an assigned value."""
    for i in range(0, len(cl.bitmap_attrs), BITMAP_BITS):
        field = emitter.bitmap_field(i)
        emitter.emit_line(f"self->{field} = 0;")


def emit_attr_defaults_func_call(defaults_fn: FuncIR, self_name: str, emitter: Emitter) -> None:
    """Emit C code to initialize attribute defaults by calling defaults_fn.

    The code returns NULL on a raised exception.
    """
    emitter.emit_lines(
        "if ({}((PyObject *){}) == 0) {{".format(
            emitter.native_function_call(defaults_fn.decl), self_name
        ),
        "Py_DECREF(self);",
        "return NULL;",
        "}",
    )


def emit_setup_or_dunder_new_call(
    cl: ClassIR,
    setup_name: str,
    type_arg: str,
    native_prefix: bool,
    new_args: str,
    emitter: Emitter,
) -> None:
    def emit_null_check() -> None:
        emitter.emit_line("if (self == NULL)")
        emitter.emit_line("    return NULL;")

    new_fn = cl.get_method("__new__")
    if not new_fn:
        emitter.emit_line(f"PyObject *self = {setup_name}({type_arg});")
        emit_null_check()
        return
    call = (
        emitter.native_function_call(new_fn.decl)
        if native_prefix
        else emitter.wrapper_function_call(new_fn.decl)
    )
    all_args = type_arg
    if new_args != "":
        all_args += ", " + new_args
    emitter.emit_line(f"PyObject *self = {call}({all_args});")
    emit_null_check()

    # skip __init__ if __new__ returns some other type
    emitter.emit_line(f"if (Py_TYPE(self) != {emitter.type_struct_name(cl)})")
    emitter.emit_line("    return self;")


def generate_constructor_for_class(
    cl: ClassIR,
    fn: FuncDecl,
    init_fn: FuncIR | None,
    setup_name: str,
    vtable_name: str,
    emitter: Emitter,
) -> None:
    """Generate a native function that allocates and initializes an instance of a class."""
    emitter.emit_line(f"{native_function_header(fn, emitter)}")
    emitter.emit_line("{")

    fn_args = [REG_PREFIX + arg.name for arg in fn.sig.args]
    type_arg = "(PyObject *)" + emitter.type_struct_name(cl)
    new_args = ", ".join(fn_args)

    use_wrapper = (
        cl.has_method("__new__")
        and len(fn.sig.args) == 2
        and fn.sig.args[0].kind == ARG_STAR
        and fn.sig.args[1].kind == ARG_STAR2
    )
    emit_setup_or_dunder_new_call(cl, setup_name, type_arg, not use_wrapper, new_args, emitter)

    args = ", ".join(["self"] + fn_args)
    if init_fn is not None:
        call = (
            emitter.wrapper_function_call(init_fn.decl)
            if use_wrapper
            else emitter.native_function_call(init_fn.decl)
        )
        cast = "!= NULL ? 0 : -1" if use_wrapper else ""
        emitter.emit_line(f"char res = {call}({args}){cast};")
        emitter.emit_line("if (res == 2) {")
        emitter.emit_line("Py_DECREF(self);")
        emitter.emit_line("return NULL;")
        emitter.emit_line("}")

    # If there is a nontrivial ctor that we didn't define, invoke it via tp_init
    elif len(fn.sig.args) > 1:
        emitter.emit_line(f"int res = {emitter.type_struct_name(cl)}->tp_init({args});")

        emitter.emit_line("if (res < 0) {")
        emitter.emit_line("Py_DECREF(self);")
        emitter.emit_line("return NULL;")
        emitter.emit_line("}")

    emitter.emit_line("return self;")
    emitter.emit_line("}")


def generate_init_for_class(cl: ClassIR, init_fn: FuncIR, emitter: Emitter) -> str:
    """Generate an init function suitable for use as tp_init.

    tp_init needs to be a function that returns an int, and our
    __init__ methods return a PyObject. Translate NULL to -1,
    everything else to 0.
    """
    func_name = f"{cl.name_prefix(emitter.names)}_init"

    emitter.emit_line("static int")
    emitter.emit_line(f"{func_name}(PyObject *self, PyObject *args, PyObject *kwds)")
    emitter.emit_line("{")
    if cl.allow_interpreted_subclasses or cl.builtin_base or cl.has_method("__new__"):
        emitter.emit_line(
            f"return {emitter.wrapper_function_call(init_fn.decl)}"
            "(self, args, kwds) != NULL ? 0 : -1;"
        )
    else:
        emitter.emit_line("return 0;")
    emitter.emit_line("}")

    return func_name


def generate_new_for_class(
    cl: ClassIR,
    func_name: str,
    vtable_name: str,
    setup_name: str,
    init_fn: FuncIR | None,
    emitter: Emitter,
) -> None:
    emitter.emit_line("static PyObject *")
    emitter.emit_line(f"{func_name}(PyTypeObject *type, PyObject *args, PyObject *kwds)")
    emitter.emit_line("{")
    # TODO: Check and unbox arguments
    if not cl.allow_interpreted_subclasses:
        emitter.emit_line(f"if (type != {emitter.type_struct_name(cl)}) {{")
        emitter.emit_line(
            'PyErr_SetString(PyExc_TypeError, "interpreted classes cannot inherit from compiled");'
        )
        emitter.emit_line("return NULL;")
        emitter.emit_line("}")

    type_arg = "(PyObject*)type"
    new_args = "args, kwds"
    emit_setup_or_dunder_new_call(cl, setup_name, type_arg, False, new_args, emitter)
    if (
        not init_fn
        or cl.allow_interpreted_subclasses
        or cl.builtin_base
        or cl.is_serializable()
        or cl.has_method("__new__")
    ):
        # Match Python semantics -- __new__ doesn't call __init__.
        emitter.emit_line("return self;")
    else:
        # __new__ of a native class implicitly calls __init__ so that we
        # can enforce that instances are always properly initialized. This
        # is needed to support always defined attributes.
        emitter.emit_line(
            f"PyObject *ret = {emitter.wrapper_function_call(init_fn.decl)}(self, args, kwds);"
        )
        emitter.emit_lines("if (ret == NULL) {", "    Py_DECREF(self);", "    return NULL;", "}")
        emitter.emit_line("Py_DECREF(ret);")
        emitter.emit_line("return self;")
    emitter.emit_line("}")


def generate_new_for_trait(cl: ClassIR, func_name: str, emitter: Emitter) -> None:
    emitter.emit_line("static PyObject *")
    emitter.emit_line(f"{func_name}(PyTypeObject *type, PyObject *args, PyObject *kwds)")
    emitter.emit_line("{")
    emitter.emit_line(f"if (type != {emitter.type_struct_name(cl)}) {{")
    emitter.emit_line(
        "PyErr_SetString(PyExc_TypeError, "
        '"interpreted classes cannot inherit from compiled traits");'
    )
    emitter.emit_line("} else {")
    emitter.emit_line('PyErr_SetString(PyExc_TypeError, "traits may not be directly created");')
    emitter.emit_line("}")
    emitter.emit_line("return NULL;")
    emitter.emit_line("}")


def generate_traverse_for_class(cl: ClassIR, func_name: str, emitter: Emitter) -> None:
    """Emit function that performs cycle GC traversal of an instance."""
    emitter.emit_line("static int")
    emitter.emit_line(
        f"{func_name}({cl.struct_name(emitter.names)} *self, visitproc visit, void *arg)"
    )
    emitter.emit_line("{")
    for base in reversed(cl.base_mro):
        for attr, rtype in base.attributes.items():
            emitter.emit_gc_visit(f"self->{emitter.attr(attr)}", rtype)
    base_args = "(PyObject *)self, visit, arg"
    emitter.emit_line("int rv = 0;")
    if cl.builtin_base:
        emitter.emit_base_tp_function_call(cl, "tp_traverse", base_args, prefix="rv = ")
        emitter.emit_line("if (rv != 0) return rv;")
    if has_managed_dict(cl, emitter):
        emitter.emit_line(f"rv = PyObject_VisitManagedDict({base_args});")
        emitter.emit_line("if (rv != 0) return rv;")
    elif cl.has_dict:
        # __dict__ lives at tp_dictoffset (== base_size), __weakref__ right after it.
        base_size = f"sizeof({cl.builtin_base or cl.struct_name(emitter.names)})"
        emitter.emit_gc_visit(f"*((PyObject **)((char *)self + {base_size}))", object_rprimitive)
        emitter.emit_gc_visit(
            f"*((PyObject **)((char *)self + sizeof(PyObject *) + {base_size}))", object_rprimitive
        )
    emitter.emit_line("return rv;")
    emitter.emit_line("}")


def generate_clear_for_class(
    cl: ClassIR,
    func_decl: FuncDecl,
    emitter: Emitter,
    subtype_clear_name: str | None = None,
    skip_attrs: set[str] | None = None,
) -> None:
    if skip_attrs is None:
        skip_attrs = set()
    emitter.emit_line("static " + native_function_header(func_decl, emitter))
    emitter.emit_line("{")
    if subtype_clear_name is not None:
        emitter.emit_line(f"int32_t res = {subtype_clear_name}(cpy_r_self);")
        emitter.emit_line("if (res != 0) return res;")
        emitter.emit_base_tp_function_call(
            cl, "tp_clear", "(PyObject *)cpy_r_self", prefix="return "
        )
    else:
        generate_subtype_clear_body(cl, emitter, skip_attrs)
        emitter.emit_line("return 0;")
    emitter.emit_line("}")


def generate_subtype_clear_for_class(
    cl: ClassIR, func_name: str, emitter: Emitter, skip_attrs: set[str] | None = None
) -> None:
    if skip_attrs is None:
        skip_attrs = set()
    emitter.emit_line(f"static int32_t {func_name}(PyObject *cpy_r_self)")
    emitter.emit_line("{")
    generate_subtype_clear_body(cl, emitter, skip_attrs)
    emitter.emit_line("return 0;")
    emitter.emit_line("}")


def generate_subtype_clear_body(cl: ClassIR, emitter: Emitter, skip_attrs: set[str]) -> None:
    emitter.emit_line(
        f"{cl.struct_name(emitter.names)} *self = "
        f"({cl.struct_name(emitter.names)} *)cpy_r_self;"
    )
    for base in reversed(cl.base_mro):
        for attr, rtype in base.attributes.items():
            if attr in skip_attrs:
                continue
            emitter.emit_gc_clear(f"self->{emitter.attr(attr)}", rtype)
    base_args = "(PyObject *)self"
    if has_managed_dict(cl, emitter):
        emitter.emit_line(f"PyObject_ClearManagedDict({base_args});")
    elif cl.has_dict:
        # __dict__ lives at tp_dictoffset (== base_size), __weakref__ right after it.
        base_size = f"sizeof({cl.builtin_base or cl.struct_name(emitter.names)})"
        emitter.emit_gc_clear(f"*((PyObject **)((char *)self + {base_size}))", object_rprimitive)
        emitter.emit_gc_clear(
            f"*((PyObject **)((char *)self + sizeof(PyObject *) + {base_size}))", object_rprimitive
        )


def generate_dealloc_for_class(
    cl: ClassIR,
    dealloc_func_name: str,
    clear_func_name: str,
    has_tp_finalize: bool,
    emitter: Emitter,
) -> None:
    emitter.emit_line("static void")
    emitter.emit_line(f"{dealloc_func_name}({cl.struct_name(emitter.names)} *self)")
    emitter.emit_line("{")
    # Always run the finalizer dance for builtin_base subclasses: we're bypassing
    # subtype_dealloc, so an inherited tp_finalize (e.g. from an interpreted base's
    # __del__) would otherwise be skipped. Runtime-gate on tp_finalize so we no-op
    # when nothing in the MRO defines a finalizer.
    if has_tp_finalize or cl.builtin_base:
        if not has_tp_finalize:
            emitter.emit_line("if (Py_TYPE(self)->tp_finalize) {")
        emitter.emit_line("PyObject *type, *value, *traceback;")
        emitter.emit_line("PyErr_Fetch(&type, &value, &traceback);")
        emitter.emit_line("int res = PyObject_CallFinalizerFromDealloc((PyObject *)self);")
        # CPython interpreter uses PyErr_WriteUnraisable: https://docs.python.org/3/c-api/exceptions.html#c.PyErr_WriteUnraisable
        # However, the message is slightly different due to the way mypyc compiles classes.
        # CPython interpreter prints: Exception ignored in: <function F.__del__ at 0x100aed940>
        # mypyc prints: Exception ignored in: <slot wrapper '__del__' of 'F' objects>
        emitter.emit_line("if (PyErr_Occurred() != NULL) {")
        # Don't untrack instance if error occurred
        emitter.emit_line("PyErr_WriteUnraisable((PyObject *)self);")
        emitter.emit_line("res = -1;")
        emitter.emit_line("}")
        emitter.emit_line("PyErr_Restore(type, value, traceback);")
        emitter.emit_line("if (res < 0) {")
        emitter.emit_line("goto done;")
        emitter.emit_line("}")
        if not has_tp_finalize:
            emitter.emit_line("}")
    if not cl.is_acyclic:
        emitter.emit_line("PyObject_GC_UnTrack(self);")
    if cl.builtin_base:
        emitter.emit_line(f"{clear_func_name}((PyObject *)self);")
        # For native subclasses of builtins such as dict, the base deallocator
        # is responsible for tearing down base-owned storage and freeing memory.
        # Re-track self if base is GC-aware to match cpython's subtype_dealloc.
        base = f"{emitter.type_struct_name(cl)}->tp_base"
        base_arg = "(PyObject *)self"
        emitter.emit_line(f"if (PyType_IS_GC({base})) PyObject_GC_Track({base_arg});")
        emitter.emit_base_tp_function_call(cl, "tp_dealloc", base_arg)
        emitter.emit_line("done: ;")
        emitter.emit_line("}")
        return
    if cl.reuse_freed_instance:
        emit_reuse_dealloc(cl, emitter)
    # The trashcan is needed to handle deep recursive deallocations
    emitter.emit_line(f"CPy_TRASHCAN_BEGIN(self, {dealloc_func_name})")
    emitter.emit_line(f"{clear_func_name}((PyObject *)self);")
    emitter.emit_line("Py_TYPE(self)->tp_free((PyObject *)self);")
    emitter.emit_line("CPy_TRASHCAN_END(self)")
    emitter.emit_line("done: ;")
    emitter.emit_line("}")


def emit_reuse_dealloc(cl: ClassIR, emitter: Emitter) -> None:
    """Emit code to deallocate object by putting it to per-type free list.

    The free "list" currently can have up to one object.
    """
    prefix = cl.name_prefix(emitter.names)
    emitter.emit_line(f"if ({prefix}_free_instance == NULL) {{")
    emitter.emit_line(f"{prefix}_free_instance = self;")

    # Clear attributes and free referenced objects.

    emit_clear_bitmaps(cl, emitter)

    for base in reversed(cl.base_mro):
        for attr, rtype in base.attributes.items():
            emitter.emit_reuse_clear(f"self->{emitter.attr(attr)}", rtype)

    emitter.emit_line("return;")
    emitter.emit_line("}")


def generate_finalize_for_class(
    del_method: FuncIR, finalize_func_name: str, emitter: Emitter
) -> None:
    emitter.emit_line("static void")
    emitter.emit_line(f"{finalize_func_name}(PyObject *self)")
    emitter.emit_line("{")
    emitter.emit_line(
        "{}{}{}(self);".format(
            emitter.get_group_prefix(del_method.decl),
            NATIVE_PREFIX,
            del_method.cname(emitter.names),
        )
    )
    emitter.emit_line("}")


def generate_methods_table(
    cl: ClassIR, name: str, setup_name: str | None, emitter: Emitter
) -> None:
    emitter.emit_line(f"static PyMethodDef {name}[] = {{")
    if setup_name:
        # Store pointer to the setup function so it can be resolved dynamically
        # in case of instance creation in __new__.
        # CPy_SetupObject expects this method to be the first one in tp_methods.
        emitter.emit_line(
            f'{{"__internal_mypyc_setup", (PyCFunction){setup_name}, METH_O, NULL}},'
        )
    for fn in cl.methods.values():
        if fn.decl.is_prop_setter or fn.decl.is_prop_getter or fn.internal:
            continue
        emitter.emit_line(f'{{"{fn.name}",')
        emitter.emit_line(f" (PyCFunction){PREFIX}{fn.cname(emitter.names)},")
        flags = ["METH_FASTCALL", "METH_KEYWORDS"]
        if fn.decl.kind == FUNC_STATICMETHOD:
            flags.append("METH_STATIC")
        elif fn.decl.kind == FUNC_CLASSMETHOD:
            flags.append("METH_CLASS")

        doc = native_function_doc_initializer(fn)
        emitter.emit_line(" {}, PyDoc_STR({})}},".format(" | ".join(flags), doc))

    # Provide a default __getstate__ and __setstate__
    if not cl.has_method("__setstate__") and not cl.has_method("__getstate__"):
        emitter.emit_lines(
            '{"__setstate__", (PyCFunction)CPyPickle_SetState, METH_O, NULL},',
            '{"__getstate__", (PyCFunction)CPyPickle_GetState, METH_NOARGS, NULL},',
        )

    emitter.emit_line("{NULL}  /* Sentinel */")
    emitter.emit_line("};")


def generate_side_table_for_class(
    cl: ClassIR, name: str, type: str, slots: dict[str, str], emitter: Emitter
) -> str | None:
    name = f"{cl.name_prefix(emitter.names)}_{name}"
    emitter.emit_line(f"static {type} {name} = {{")
    for field, value in slots.items():
        emitter.emit_line(f".{field} = {value},")
    emitter.emit_line("};")
    return name


def generate_getseter_declarations(cl: ClassIR, emitter: Emitter) -> None:
    if not cl.is_trait:
        for attr in cl.attributes:
            emitter.emit_line("static PyObject *")
            emitter.emit_line(
                "{}({} *self, void *closure);".format(
                    getter_name(cl, attr, emitter.names), cl.struct_name(emitter.names)
                )
            )
            # Final attributes are read-only, so they have no setter.
            if attr not in cl.final_attributes:
                emitter.emit_line("static int")
                emitter.emit_line(
                    "{}({} *self, PyObject *value, void *closure);".format(
                        setter_name(cl, attr, emitter.names), cl.struct_name(emitter.names)
                    )
                )

    for prop, (getter, setter) in cl.properties.items():
        if getter.decl.implicit:
            continue

        # Generate getter declaration
        emitter.emit_line("static PyObject *")
        emitter.emit_line(
            "{}({} *self, void *closure);".format(
                getter_name(cl, prop, emitter.names), cl.struct_name(emitter.names)
            )
        )

        # Generate property setter declaration if a setter exists
        if setter:
            emitter.emit_line("static int")
            emitter.emit_line(
                "{}({} *self, PyObject *value, void *closure);".format(
                    setter_name(cl, prop, emitter.names), cl.struct_name(emitter.names)
                )
            )


def generate_getseters_table(cl: ClassIR, name: str, emitter: Emitter) -> None:
    emitter.emit_line(f"static PyGetSetDef {name}[] = {{")
    if not cl.is_trait:
        for attr in cl.attributes:
            emitter.emit_line(f'{{"{attr}",')
            if attr in cl.final_attributes:
                # Final attributes are read-only, so emit a NULL setter.
                emitter.emit_line(f" (getter){getter_name(cl, attr, emitter.names)}, NULL,")
            else:
                emitter.emit_line(
                    " (getter){}, (setter){},".format(
                        getter_name(cl, attr, emitter.names), setter_name(cl, attr, emitter.names)
                    )
                )
            emitter.emit_line(" NULL, NULL},")
    for prop, (getter, setter) in cl.properties.items():
        if getter.decl.implicit:
            continue

        emitter.emit_line(f'{{"{prop}",')
        emitter.emit_line(f" (getter){getter_name(cl, prop, emitter.names)},")

        if setter:
            emitter.emit_line(f" (setter){setter_name(cl, prop, emitter.names)},")
            emitter.emit_line("NULL, NULL},")
        else:
            emitter.emit_line("NULL, NULL, NULL},")

    if cl.has_dict:
        emitter.emit_line('{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},')

    emitter.emit_line("{NULL}  /* Sentinel */")
    emitter.emit_line("};")


def generate_getseters(cl: ClassIR, emitter: Emitter) -> None:
    if not cl.is_trait:
        for i, (attr, rtype) in enumerate(cl.attributes.items()):
            generate_getter(cl, attr, rtype, emitter)
            # Final attributes are read-only, so they have no setter.
            if attr not in cl.final_attributes:
                emitter.emit_line("")
                generate_setter(cl, attr, rtype, emitter)
            if i < len(cl.attributes) - 1:
                emitter.emit_line("")
    for prop, (getter, setter) in cl.properties.items():
        if getter.decl.implicit:
            continue

        rtype = getter.sig.ret_type
        emitter.emit_line("")
        generate_readonly_getter(cl, prop, rtype, getter, emitter)
        if setter:
            arg_type = setter.sig.args[1].type
            emitter.emit_line("")
            generate_property_setter(cl, prop, arg_type, setter, emitter)


def generate_getter(cl: ClassIR, attr: str, rtype: RType, emitter: Emitter) -> None:
    attr_field = emitter.attr(attr)
    emitter.emit_line("static PyObject *")
    emitter.emit_line(
        "{}({} *self, void *closure)".format(
            getter_name(cl, attr, emitter.names), cl.struct_name(emitter.names)
        )
    )
    emitter.emit_line("{")
    attr_expr = f"self->{attr_field}"

    if IS_FREE_THREADED and is_simple_refcounted_pointer(rtype):
        # In free-threaded builds, load the attribute and take a new reference with
        # an optimistic validated incref to avoid racing with a concurrent setter.
        # CPy_GetAttrRef returns NULL if the attribute is undefined (NULL field),
        # which is exactly the error/undefined value for a 'PyObject *' field.
        #
        # Final attributes are never rebound (no setter), so there is no concurrent
        # writer to race with: a plain load + incref is safe. Use the cheaper
        # CPy_GetAttrRefFinal, which skips the try-incref and the locked
        # _Py_XNewRefWithLock fallback entirely (an unconditional Py_INCREF needs no
        # maybe-weakref).
        # This getter is generated per defining class, so a direct membership test
        # matches the read-only getset table above (no need to walk the MRO).
        if attr in cl.final_attributes:
            getattr_ref = f"CPy_GetAttrRefFinal((PyObject **)&{attr_expr})"
        else:
            getattr_ref = f"CPy_GetAttrRef((PyObject *)self, (PyObject **)&{attr_expr})"
        emitter.emit_line(f"PyObject *retval = {getattr_ref};")
        emitter.emit_line("if (unlikely(retval == NULL)) {")
        emitter.emit_line("PyErr_SetString(PyExc_AttributeError,")
        emitter.emit_line(f'    "attribute {repr(attr)} of {repr(cl.name)} undefined");')
        emitter.emit_line("return NULL;")
        emitter.emit_line("}")
        emitter.emit_line("return retval;")
        emitter.emit_line("}")
        return

    # HACK: Don't consider refcounted values as always defined, since it's possible to
    #       access uninitialized values via 'gc.get_objects()'. Accessing non-refcounted
    #       values is benign.
    always_defined = cl.is_always_defined(attr) and not rtype.is_refcounted

    if not always_defined:
        emitter.emit_undefined_attr_check(rtype, attr_expr, "==", "self", attr, cl, unlikely=True)
        emitter.emit_line("PyErr_SetString(PyExc_AttributeError,")
        emitter.emit_line(f'    "attribute {repr(attr)} of {repr(cl.name)} undefined");')
        emitter.emit_line("return NULL;")
        emitter.emit_line("}")
    emitter.emit_inc_ref(f"self->{attr_field}", rtype)
    emitter.emit_box(f"self->{attr_field}", "retval", rtype, declare_dest=True)
    emitter.emit_line("return retval;")
    emitter.emit_line("}")


def generate_setter(cl: ClassIR, attr: str, rtype: RType, emitter: Emitter) -> None:
    attr_field = emitter.attr(attr)
    emitter.emit_line("static int")
    emitter.emit_line(
        "{}({} *self, PyObject *value, void *closure)".format(
            setter_name(cl, attr, emitter.names), cl.struct_name(emitter.names)
        )
    )
    emitter.emit_line("{")

    deletable = cl.is_deletable(attr)
    if not deletable:
        emitter.emit_line("if (value == NULL) {")
        emitter.emit_line("PyErr_SetString(PyExc_AttributeError,")
        emitter.emit_line(
            f'    "{repr(cl.name)} object attribute {repr(attr)} cannot be deleted");'
        )
        emitter.emit_line("return -1;")
        emitter.emit_line("}")

    if IS_FREE_THREADED and is_simple_refcounted_pointer(rtype):
        # In free-threaded builds, publish the new value via CPy_SetAttrRef, which
        # takes the owner's critical section so a concurrent reader (see
        # CPy_GetAttrRef) can always secure a reference to the value it observes,
        # even though the old value is decrefed right away. CPy_SetAttrRef steals its
        # value and reclaims the old one, so we cast/type-check the incoming value,
        # take a new reference (the setter only borrows 'value'), then hand it over.
        # A NULL value deletes the attribute (reclaims the old value, stores NULL).
        if deletable:
            emitter.emit_line("if (value != NULL) {")
        if is_same_type(rtype, object_rprimitive):
            emitter.emit_line("PyObject *tmp = value;")
        else:
            emitter.emit_cast("value", "tmp", rtype, declare_dest=True)
            emitter.emit_lines("if (!tmp)", "    return -1;")
        emitter.emit_inc_ref("tmp", rtype)
        emitter.emit_line(
            f"CPy_SetAttrRef((PyObject *)self, (PyObject **)&self->{attr_field}, tmp);"
        )
        if deletable:
            emitter.emit_line("} else {")
            emitter.emit_line(
                f"CPy_SetAttrRef((PyObject *)self, (PyObject **)&self->{attr_field}, NULL);"
            )
            emitter.emit_line("}")
        emitter.emit_line("return 0;")
        emitter.emit_line("}")
        return

    # HACK: Don't consider refcounted values as always defined, since it's possible to
    #       access uninitialized values via 'gc.get_objects()'. Accessing non-refcounted
    #       values is benign.
    always_defined = cl.is_always_defined(attr) and not rtype.is_refcounted

    def emit_decref_old_value() -> None:
        if rtype.is_refcounted:
            attr_expr = f"self->{attr_field}"
            if not always_defined:
                emitter.emit_undefined_attr_check(rtype, attr_expr, "!=", "self", attr, cl)
            emitter.emit_dec_ref(attr_expr, rtype)
            if not always_defined:
                emitter.emit_line("}")

    if deletable:
        emitter.emit_line("if (value != NULL) {")

    if rtype.is_unboxed:
        # Borrow the unboxed value: emit_inc_ref below takes the single owned
        # reference, matching the borrowed-then-incref pattern of the other two
        # branches. Without borrow=True, emit_unbox already creates a new
        # reference for refcounted unboxed types (e.g. CPyTagged boxed ints,
        # tuples with refcounted fields), so the emit_inc_ref would double the
        # reference and leak the stored value on every set via this setter.
        emitter.emit_unbox(
            "value", "tmp", rtype, error=ReturnHandler("-1"), declare_dest=True, borrow=True
        )
    elif is_same_type(rtype, object_rprimitive):
        emitter.emit_line("PyObject *tmp = value;")
    else:
        emitter.emit_cast("value", "tmp", rtype, declare_dest=True)
        emitter.emit_lines("if (!tmp)", "    return -1;")
    # Take ownership of the incoming value before releasing the old one. In
    # particular, a failed cast must leave the attribute and its reference intact.
    emitter.emit_inc_ref("tmp", rtype)
    emit_decref_old_value()
    emitter.emit_line(f"self->{attr_field} = tmp;")
    if rtype.error_overlap and not always_defined:
        emitter.emit_attr_bitmap_set("tmp", "self", rtype, cl, attr)

    if deletable:
        emitter.emit_line("} else {")
        emit_decref_old_value()
        emitter.set_undefined_value(f"self->{attr_field}", rtype)
        if rtype.error_overlap:
            emitter.emit_attr_bitmap_clear("self", rtype, cl, attr)
        emitter.emit_line("}")
    emitter.emit_line("return 0;")
    emitter.emit_line("}")


def generate_readonly_getter(
    cl: ClassIR, attr: str, rtype: RType, func_ir: FuncIR, emitter: Emitter
) -> None:
    emitter.emit_line("static PyObject *")
    emitter.emit_line(
        "{}({} *self, void *closure)".format(
            getter_name(cl, attr, emitter.names), cl.struct_name(emitter.names)
        )
    )
    emitter.emit_line("{")
    if rtype.is_unboxed:
        emitter.emit_line(
            "{}retval = {}{}((PyObject *) self);".format(
                emitter.ctype_spaced(rtype), NATIVE_PREFIX, func_ir.cname(emitter.names)
            )
        )
        emitter.emit_error_check("retval", rtype, "return NULL;")
        emitter.emit_box("retval", "retbox", rtype, declare_dest=True)
        emitter.emit_line("return retbox;")
    else:
        emitter.emit_line(
            f"return {NATIVE_PREFIX}{func_ir.cname(emitter.names)}((PyObject *) self);"
        )
    emitter.emit_line("}")


def generate_property_setter(
    cl: ClassIR, attr: str, arg_type: RType, func_ir: FuncIR, emitter: Emitter
) -> None:
    emitter.emit_line("static int")
    emitter.emit_line(
        "{}({} *self, PyObject *value, void *closure)".format(
            setter_name(cl, attr, emitter.names), cl.struct_name(emitter.names)
        )
    )
    emitter.emit_line("{")
    ret_type = func_ir.ret_type
    emitter.emit_line(f"{emitter.ctype(ret_type)} retval = {emitter.c_undefined_value(ret_type)};")
    if arg_type.is_unboxed:
        emitter.emit_unbox("value", "tmp", arg_type, error=ReturnHandler("-1"), declare_dest=True)
        emitter.emit_line(
            f"retval = {NATIVE_PREFIX}{func_ir.cname(emitter.names)}((PyObject *) self, tmp);"
        )
    else:
        emitter.emit_line(
            f"retval = {NATIVE_PREFIX}{func_ir.cname(emitter.names)}((PyObject *) self, value);"
        )
    emitter.emit_error_check("retval", ret_type, "return -1;")
    emitter.emit_line("return 0;")
    emitter.emit_line("}")


def has_managed_dict(cl: ClassIR, emitter: Emitter) -> bool:
    """Should the class get the Py_TPFLAGS_MANAGED_DICT flag?"""
    # On 3.11 and earlier the flag doesn't exist and we use
    # tp_dictoffset instead.  If a class inherits from Exception, the
    # flag conflicts with tp_dictoffset set in the base class.
    return (
        emitter.capi_version >= (3, 12)
        and cl.has_dict
        and cl.builtin_base != "PyBaseExceptionObject"
    )


def native_class_doc_initializer(cl: ClassIR) -> str:
    init_fn = cl.get_method("__init__")
    if init_fn is not None:
        text_sig = get_text_signature(init_fn, bound=True)
        if text_sig is None:
            return "NULL"
        text_sig = text_sig.replace("__init__", cl.name, 1)
    else:
        text_sig = f"{cl.name}()"
    docstring = f"{text_sig}\n--\n\n"
    return c_string_initializer(docstring.encode("ascii", errors="backslashreplace"))


def generate_coroutine_setup(
    cl: ClassIR, coroutine_setup_name: str, module_name: str, emitter: Emitter
) -> None:
    emitter.emit_line("static bool")
    emitter.emit_line(f"{NATIVE_PREFIX}{coroutine_setup_name}(PyObject *type)")
    emitter.emit_line("{")

    error_stmt = "    return 2;"

    def emit_instance(fn: FuncIR, fn_name: str) -> str:
        filepath = emitter.filepath or ""
        return emitter.emit_cpyfunction_instance(fn, fn_name, filepath, error_stmt)

    def success() -> None:
        emitter.emit_line("return 1;")
        emitter.emit_line("}")

    if cl.coroutine_name:
        # Callable class generated for a coroutine. It stores its function wrapper as an attribute.
        wrapper_name = emit_instance(cl.methods["__call__"], cl.coroutine_name)
        struct_name = cl.struct_name(emitter.names)
        attr = emitter.attr(CPYFUNCTION_NAME)
        if IS_FREE_THREADED:
            emitter.emit_line(
                f"CPy_InitAttrRefIfNull(type, (PyObject **)&(({struct_name} *)type)->{attr}, "
                f"{wrapper_name});"
            )
        else:
            # Creating the wrapper may run arbitrary code (e.g. via GC), which could
            # have initialized the attribute already.
            field = f"(({struct_name} *)type)->{attr}"
            emitter.emit_line(f"if ({field} == NULL) {{")
            emitter.emit_line(f"{field} = {wrapper_name};")
            emitter.emit_line("} else {")
            emitter.emit_line(f"Py_DECREF({wrapper_name});")
            emitter.emit_line("}")
        return success()

    if not any(fn.decl.is_coroutine for fn in cl.methods.values()):
        return success()

    emitter.emit_line("PyTypeObject *tp = (PyTypeObject *)type;")

    for fn in cl.methods.values():
        if not fn.decl.is_coroutine:
            continue

        name = short_id_from_name(fn.name, fn.decl.shortname, fn.line)
        wrapper_name = emit_instance(fn, name)
        name_obj = f"name_{wrapper_name}"
        emitter.emit_line(f'PyObject *{name_obj} = PyUnicode_FromString("{fn.name}");')
        emitter.emit_line(f"if (unlikely(!{name_obj}))")
        emitter.emit_line(error_stmt)
        emitter.emit_line(f"if (PyDict_SetItem(tp->tp_dict, {name_obj}, {wrapper_name}) < 0)")
        emitter.emit_line(error_stmt)

    return success()
