from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from lib.core.translator import Translator
    from lib.core.Translator.LlvmGenerator import LlvmGeneratorMixin
import ast
import copy
import llvmlite.ir as ir
from lib.core.Exportable import EnumMember as ExportEnumMember
from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo, FuncMeta
from lib.core.SymbolUtils import IsTModule, FindStructNameInAnnotation
from lib.core.VLogger import get_logger as _vlog
from lib.constants.config import mode as _config_mode
from lib.includes import t
from lib.includes.t import CTypeRegistry


class ClassHandle(BaseHandle):
    def _is_exception_class(self, Node: ast.ClassDef) -> bool:
        if not Node.bases:
            return False
        for base in Node.bases:
            if hasattr(base, 'id'):
                if base.id == 'Exception':
                    return True
                if base.id in self.Trans.exception_registry:
                    return True
            elif hasattr(base, 'attr'):
                if base.attr == 'Exception':
                    return True
                if base.attr in self.Trans.exception_registry:
                    return True
        return False

    def _get_exception_parent(self, Node: ast.ClassDef) -> str | None:
        if not Node.bases:
            return None
        for base in Node.bases:
            if hasattr(base, 'id'):
                if base.id != 'Exception' and base.id in self.Trans.exception_registry:
                    return base.id
            elif hasattr(base, 'attr'):
                if base.attr != 'Exception' and base.attr in self.Trans.exception_registry:
                    return base.attr
        return None

    def _RegisterExceptionClass(self, Node: ast.ClassDef) -> None:
        ClassName: str = Node.name
        if ClassName in self.Trans.exception_registry:
            return
        code: int = self.Trans._next_exception_code
        self.Trans._next_exception_code += 1
        self.Trans.exception_registry[ClassName] = code
        parent: str | None = self._get_exception_parent(Node)
        if parent:
            self.Trans.exception_parents[ClassName] = parent
        ExcTypeInfo: CTypeInfo = CTypeInfo()
        ExcTypeInfo.Name = ClassName
        ExcTypeInfo.IsExceptionClass = True
        ExcTypeInfo.value = code
        self.Trans.SymbolTable.insert(ClassName, ExcTypeInfo)

    def _is_generic_class(self, Node: ast.ClassDef) -> bool:
        if hasattr(Node, 'type_params') and Node.type_params:
            return True
        return False

    def _mangle_generic_class_name(self, class_name: str, type_args: list[str]) -> str:
        mangled_args: list[str] = []
        for ta in type_args:
            llvm_str: str | None = CTypeRegistry.NameToLLVM(ta)
            if llvm_str:
                if llvm_str in ('float', 'double', 'half', 'fp128'):
                    mangled: str = 'f' + str(CTypeRegistry.GetClassByName(ta)().Size)
                else:
                    mangled = llvm_str
            else:
                mangled = ta
            mangled_args.append(mangled)
        return class_name + '[' + ']['.join(mangled_args) + ']'

    def _specialize_generic_class(self, ClassName: str, type_args: list[str], Gen: LlvmGeneratorMixin, type_names: list[str] | None = None, declare_only: bool = False) -> str | None:
        if not hasattr(self, '_generic_class_templates') or ClassName not in self._generic_class_templates:
            return None
        # 防御：共享符号表构建阶段 Gen 可能为 None，此时无法发射特化 IR
        if Gen is None:
            return None
        template: dict = self._generic_class_templates[ClassName]
        Node: ast.ClassDef = template['node']
        type_param_names: list[str] = template['type_params']
        if len(type_args) != len(type_param_names):
            return None
        spec_key: str = ClassName + '<' + ','.join(type_args) + '>'
        # 缓存必须在 Gen 上（每个模块独立），不能在 ClassHandler 上跨模块共享，
        # 否则临时 Gen（如共享符号表构建阶段）的特化会污染正式翻译阶段的缓存
        if not hasattr(Gen, '_generic_class_specializations'):
            Gen._generic_class_specializations = {}
        if spec_key in Gen._generic_class_specializations:
            cached: object = Gen._generic_class_specializations[spec_key]
            # 缓存格式: (spec_name, was_declare_only)
            if isinstance(cached, tuple):
                cached_name: str = cached[0]
                cached_declare_only: bool = cached[1]
                # 完整特化请求但缓存只有 declare_only 版本 → 需要补发方法体
                if not declare_only and cached_declare_only:
                    spec_name = cached_name
                    # 标记为正在完整特化，防止递归
                    Gen._generic_class_specializations[spec_key] = (spec_name, False)
                else:
                    return cached_name
            else:
                # 旧格式（纯字符串）：直接返回
                return cached
        else:
            spec_name: str = self._mangle_generic_class_name(ClassName, type_args)
        # 预注册到缓存，防止特化过程中方法体引用自身类型导致无限递归
        Gen._generic_class_specializations[spec_key] = (spec_name, declare_only)
        type_map: dict[str, str] = {}
        for i, tp_name in enumerate(type_param_names):
            if type_names and i < len(type_names):
                type_map[tp_name] = type_names[i]
            else:
                type_map[tp_name] = type_args[i]
        # 内建类型名集合（必须在 cptr_params 检测之前定义）
        _BUILTIN_TYPE_NAMES: set = {
            'CInt', 'CUInt', 'CInt8T', 'CUInt8T', 'CInt16T', 'CUInt16T',
            'CInt32T', 'CUInt32T', 'CInt64T', 'CUInt64T', 'CChar', 'CShort',
            'CLong', 'CDouble', 'CFloat', 'CFloat32T', 'CFloat64T', 'CBool',
            'CVoid', 'CSizeT', 'CSSizeT', 'CPtr', 'CArray', 'CEnum', 'CUnion',
            'CStruct', 'CDefine',
            'int', 'double', 'float', 'i8', 'i16', 'i32', 'i64', 'void',
            'half', 'fp128', 'char', 'bool',
        }
        # 检测哪些类型参数在原始类型实参中带有 | t.CPtr
        # 当 type_arg 以 'ptr' 结尾（_resolve_type_arg_str 将 t.CPtr 规范化为 'ptr'）
        # 且对应的 type_name 不是内建类型名时，说明调用方写了 list[AST | t.CPtr]
        cptr_params: set[str] = set()
        for i, tp_name in enumerate(type_param_names):
            type_arg: str = type_args[i]
            if type_arg.endswith('ptr'):
                tn: str = type_names[i] if type_names and i < len(type_names) else type_args[i]
                if tn not in _BUILTIN_TYPE_NAMES:
                    cptr_params.add(tp_name)
        # Bug 2 修复：识别特化为 class 类型的类型参数
        # 这类参数在方法签名中是裸 T（无 | t.CPtr），特化后为裸 ClassName（值类型）
        # 需要加 | t.CPtr 使其成为指针类型（class 实例应按指针传递）
        class_type_names: set[str] = set()
        for i, tp_name in enumerate(type_param_names):
            tn: str = type_names[i] if type_names and i < len(type_names) else type_args[i]
            if tn not in _BUILTIN_TYPE_NAMES:
                class_type_names.add(tn)
        # 仅对 t 模块内建类型名注册 _t_c_imported_names（如 CInt -> ('t','CInt')）
        # 类名（如 AST）不应注册为 t.AST，否则会污染名称解析
        if type_names:
            if not hasattr(self.Trans, '_t_c_imported_names'):
                self.Trans._t_c_imported_names = {}
            for tn in type_names:
                if tn in _BUILTIN_TYPE_NAMES and tn not in self.Trans._t_c_imported_names:
                    self.Trans._t_c_imported_names[tn] = ('t', tn)
        SpecNode: ast.ClassDef = copy.deepcopy(Node)
        SpecNode.type_params = []
        SpecNode.name = spec_name
        for item in SpecNode.body:
            if isinstance(item, ast.AnnAssign) and isinstance(item.target, ast.Name):
                if item.annotation:
                    item.annotation = self.Trans.FunctionHandler._replace_type_in_annotation(item.annotation, type_map, cptr_params)
            elif isinstance(item, ast.FunctionDef):
                for arg in item.args.args:
                    if arg.annotation:
                        arg.annotation = self.Trans.FunctionHandler._replace_type_in_annotation(arg.annotation, type_map, cptr_params)
                        # class 类型参数加指针语义：T -> GNode -> GNode | t.CPtr
                        # 去除 SHA1 前缀后检查（如 fc06023a9bcfc93a.AST -> AST）
                        if isinstance(arg.annotation, ast.Name):
                            raw_name: str = arg.annotation.id
                            if '.' in raw_name:
                                raw_name = raw_name.split('.')[-1]
                            if raw_name in class_type_names:
                                arg.annotation = ast.BinOp(
                                    left=ast.Name(id=arg.annotation.id, ctx=ast.Load()),
                                    op=ast.BitOr(),
                                    right=ast.Attribute(value=ast.Name(id='t', ctx=ast.Load()), attr='CPtr', ctx=ast.Load())
                                )
                if item.returns:
                    item.returns = self.Trans.FunctionHandler._replace_type_in_annotation(item.returns, type_map, cptr_params)
                    # 返回类型也加指针语义
                    if isinstance(item.returns, ast.Name):
                        raw_name: str = item.returns.id
                        if '.' in raw_name:
                            raw_name = raw_name.split('.')[-1]
                        if raw_name in class_type_names:
                            item.returns = ast.BinOp(
                                left=ast.Name(id=item.returns.id, ctx=ast.Load()),
                                op=ast.BitOr(),
                                right=ast.Attribute(value=ast.Name(id='t', ctx=ast.Load()), attr='CPtr', ctx=ast.Load())
                            )
                self.Trans.FunctionHandler._apply_type_map_to_body(item.body, type_map, cptr_params)
        saved_builder: ir.IRBuilder = Gen.builder
        saved_func: ir.Function = Gen.func
        saved_variables: dict = dict(Gen.variables) if Gen.variables else {}
        saved_direct_values: dict = dict(Gen._direct_values) if Gen._direct_values else {}
        saved_var_type_info: dict = dict(Gen.var_type_info) if Gen.var_type_info else {}
        saved_var_signedness: dict = dict(Gen.var_signedness) if Gen.var_signedness else {}
        saved_global_vars: set = set(Gen.global_vars) if Gen.global_vars else set()
        saved_var_scopes: list = [dict(s) for s in self.Trans.VarScopes] if self.Trans.VarScopes else []
        saved_block: ir.Block | None = None
        if Gen.builder and Gen.builder.block and not Gen.builder.block.is_terminated:
            saved_block = Gen.builder.block
        try:
            self._EmitClassLlvm(SpecNode, Gen, declare_only=declare_only)
        finally:
            # 确保 Gen 状态恢复，即使 _EmitClassLlvm 抛出异常
            Gen.builder = saved_builder
            if saved_block is not None and Gen.builder is not None:
                Gen.builder.position_at_end(saved_block)
            Gen.func = saved_func
            Gen.variables = saved_variables
            Gen._direct_values = saved_direct_values
            Gen.var_type_info = saved_var_type_info
            Gen.var_signedness = saved_var_signedness
            Gen.global_vars = saved_global_vars
            self.Trans.VarScopes = saved_var_scopes
        Gen._generic_class_specializations[spec_key] = (spec_name, declare_only)
        if not hasattr(self.Trans, '_generic_class_specializations'):
            self.Trans._generic_class_specializations = {}
        self.Trans._generic_class_specializations[spec_key] = spec_name
        if hasattr(self.Trans, '_module_sha1') and self.Trans._module_sha1:
            Gen._struct_sha1_map[spec_name] = self.Trans._module_sha1
        return spec_name

    def _resolve_base_kind(self, base_name: str, Gen: LlvmGeneratorMixin) -> str | None:
        """解析基类名称的类型种类

        查询顺序：
        1. _t_type_symbols（from t import CEnum as en）
        2. t 模块属性（t.CEnum / t.CUnion / t.CStruct / t.REnum）
        3. 返回 None 表示不是已知标记基类

        Returns:
            'enum' | 'union' | 'renum' | 'struct' | None
        """
        # 1) 查 _t_type_symbols（别名导入）
        symtab: object = self.Trans.SymbolTable
        cls: type | None = symtab._t_type_symbols.get(base_name)
        if cls is not None:
            if issubclass(cls, (t.CEnum, t.REnum)):
                return 'renum' if issubclass(cls, t.REnum) else 'enum'
            if issubclass(cls, t.CUnion):
                return 'union'
            if issubclass(cls, t.CStruct):
                return 'struct'

        # 2) 查 t 模块属性（直接引用 t.CEnum 等）
        t_cls: type | None = getattr(t, base_name, None)
        if isinstance(t_cls, type) and issubclass(t_cls, t.CType):
            if issubclass(t_cls, (t.CEnum, t.REnum)):
                return 'renum' if issubclass(t_cls, t.REnum) else 'enum'
            if issubclass(t_cls, t.CUnion):
                return 'union'
            if issubclass(t_cls, t.CStruct):
                return 'struct'

        return None

    def _resolve_decorator_kind(self, Node: ast.ClassDef, Gen: LlvmGeneratorMixin) -> str | None:
        """从装饰器列表中解析结构体类型种类

        支持 @t.CStruct, @t.CUnion, @t.CEnum, @t.REnum
        也支持 from t import CStruct 等别名形式

        Returns:
            'enum' | 'union' | 'renum' | 'struct' | None
        """
        if not hasattr(Node, 'decorator_list') or not Node.decorator_list:
            return None
        symtab: object = self.Trans.SymbolTable
        for decorator in Node.decorator_list:
            attr_name: str | None = None
            # @t.CStruct 形式
            if isinstance(decorator, ast.Attribute) and isinstance(decorator.value, ast.Name):
                if IsTModule(decorator.value.id, symtab):
                    attr_name = decorator.attr
            # @CStruct 形式 (from t import CStruct)
            elif isinstance(decorator, ast.Name):
                cls: type | None = getattr(t, decorator.id, None)
                if cls is None and hasattr(symtab, '_t_type_symbols'):
                    cls = symtab._t_type_symbols.get(decorator.id)
                if cls is not None and isinstance(cls, type) and issubclass(cls, t.CType):
                    attr_name = cls.__name__
            if attr_name:
                # 查 _t_type_symbols 和 t 模块属性以确定种类
                resolved_cls: type | None = None
                if hasattr(symtab, '_t_type_symbols'):
                    resolved_cls = symtab._t_type_symbols.get(attr_name)
                if resolved_cls is None:
                    resolved_cls = getattr(t, attr_name, None)
                if resolved_cls is not None and isinstance(resolved_cls, type):
                    if issubclass(resolved_cls, t.REnum):
                        return 'renum'
                    if issubclass(resolved_cls, t.CEnum):
                        return 'enum'
                    if issubclass(resolved_cls, t.CUnion):
                        return 'union'
                    if issubclass(resolved_cls, t.CStruct):
                        return 'struct'
        return None

    def _resolve_class_flags(self, Node: ast.ClassDef, Gen: LlvmGeneratorMixin) -> tuple[bool, bool, str | None, bool]:
        """解析类的 Object/CVTable 标志和父类信息

        Returns:
            tuple: (IsCpythonObject, IsCVTable, ParentClassName, IsNoVTable)
        """
        ClassName: str = Node.name
        IsCpythonObject: bool = False
        IsCVTable: bool = False
        IsNoVTable: bool = False
        if hasattr(Node, 'decorator_list') and Node.decorator_list:
            for decorator in Node.decorator_list:
                if isinstance(decorator, ast.Attribute):
                    if hasattr(decorator.value, 'id') and IsTModule(decorator.value.id, self.Trans.SymbolTable):
                        if decorator.attr == 'Object':
                            IsCpythonObject = True
                        elif decorator.attr == 'CVTable':
                            IsCVTable = True
                        elif decorator.attr == 'NoVTable':
                            IsNoVTable = True
                elif isinstance(decorator, ast.Name):
                    if decorator.id == 'Object':
                        IsCpythonObject = True
                    elif decorator.id == 'CVTable':
                        IsCVTable = True
                    elif decorator.id == 'NoVTable':
                        IsNoVTable = True
                elif isinstance(decorator, ast.Call):
                    # 检测 @c.Attribute(t.attr.packed)
                    if isinstance(decorator.func, ast.Attribute):
                        if getattr(decorator.func.value, 'id', None) == 'c' and decorator.func.attr == 'Attribute':
                            for arg in decorator.args:
                                if isinstance(arg, ast.Attribute):
                                    if isinstance(arg.value, ast.Attribute):
                                        if IsTModule(getattr(arg.value.value, 'id', ''), self.Trans.SymbolTable) and arg.value.attr == 'attr' and arg.attr == 'packed':
                                            Gen.class_packed.add(ClassName)
        class_graph: dict = Gen._class_graph
        if class_graph.get(ClassName, {}).get('has_methods', False) and not IsNoVTable:
            if not IsCpythonObject:
                IsCpythonObject = True
            # 仅当该类作为其他类的基类时，才启用 CVTable
            # 检查 _class_graph 中是否有任何类将此类作为基类
            is_base_of_any: bool = False
            for other_cls, info in class_graph.items():
                if ClassName in info.get('bases', []):
                    is_base_of_any = True
                    break
            if is_base_of_any:
                IsCVTable = True
        HasParentClass: bool = False
        ParentClassName: str | None = None
        ParentIsNoVTable: bool = False
        if Node.bases:
            for base in Node.bases:
                base_name: str | None = None
                if hasattr(base, 'id'):
                    base_name = base.id
                elif hasattr(base, 'attr'):
                    base_name = base.attr
                if base_name:
                    kind: str | None = self._resolve_base_kind(base_name, Gen)
                    if kind is not None or base_name in t._MARKER_BASES:
                        continue  # 标记基类，跳过
                    if base_name in class_graph or base_name in Gen.class_members or base_name in Gen.structs:
                        HasParentClass = True
                        ParentClassName = base_name
                        # 检测父类是否有 @t.NoVTable 标记（非多态继承）
                        if class_graph.get(base_name, {}).get('has_novtable', False):
                            ParentIsNoVTable = True
                        # 跨模块父类：检查 _cross_module_novtable 集合
                        if base_name in Gen._cross_module_novtable:
                            ParentIsNoVTable = True
                        break
        if HasParentClass and not IsCVTable and not IsNoVTable and not ParentIsNoVTable:
            IsCVTable = True
        if IsCVTable:
            Gen.class_vtable.add(ClassName)
            # 沿继承链向上传播，将所有祖先类加入 vtable
            visited: set[str] = {ClassName}
            ancestor: str | None = ParentClassName
            while ancestor and ancestor not in visited:
                visited.add(ancestor)
                Gen.class_vtable.add(ancestor)
                # 查询祖先类的父类
                ancestor_info: dict | None = class_graph.get(ancestor)
                if ancestor_info:
                    ancestor_bases: list = ancestor_info.get('bases', [])
                    next_ancestor: str | None = None
                    for ab in ancestor_bases:
                        if ab not in t._MARKER_BASES and ab not in visited:
                            next_ancestor = ab
                            break
                    ancestor = next_ancestor
                else:
                    # 类图中没有，尝试从 class_parent 查询
                    ancestor = Gen.class_parent.get(ancestor)
        return IsCpythonObject, IsCVTable, ParentClassName, IsNoVTable

    def _EmitClassLlvm(self, Node: ast.ClassDef, Gen: LlvmGeneratorMixin, declare_only: bool = False) -> None:
        ClassName: str = Node.name
        if self._is_generic_class(Node):
            if not hasattr(self, '_generic_class_templates'):
                self._generic_class_templates = {}
            type_params: list[str] = [tp.name for tp in Node.type_params]
            self._generic_class_templates[ClassName] = {
                'node': Node,
                'type_params': type_params,
            }
            return
        if self._is_exception_class(Node):
            self._RegisterExceptionClass(Node)
            return
        IsCenum: bool = False
        IsCunion: bool = False
        IsRenum: bool = False
        # 先检查装饰器形式（@t.CStruct / @t.CEnum / @t.CUnion / @t.REnum）
        deco_kind: str | None = self._resolve_decorator_kind(Node, Gen)
        if deco_kind == 'enum':
            IsCenum = True
        elif deco_kind == 'union':
            IsCunion = True
        elif deco_kind == 'renum':
            IsRenum = True
        # 再检查基类继承形式（class X(t.CStruct):），与装饰器合并
        if not IsCenum and not IsCunion and not IsRenum and Node.bases:
            for base in Node.bases:
                base_name: str | None = None
                if hasattr(base, 'attr'):
                    base_name = base.attr
                elif hasattr(base, 'id'):
                    base_name = base.id
                if base_name:
                    kind: str | None = self._resolve_base_kind(base_name, Gen)
                    if kind == 'enum':
                        IsCenum = True
                        break
                    elif kind == 'union':
                        IsCunion = True
                    elif kind == 'renum':
                        IsRenum = True
        if IsCenum:
            self._RegisterEnumMembers(Node)
            return
        if IsCunion:
            self._EmitUnionLlvm(Node, Gen)
            return
        if IsRenum:
            self._EmitREnumLlvm(Node, Gen)
            return
        IsCpythonObject: bool
        IsCVTable: bool
        ParentClassName: str | None
        IsNoVTable: bool
        IsCpythonObject, IsCVTable, ParentClassName, IsNoVTable = self._resolve_class_flags(Node, Gen)
        # 跟踪正在发射的类，防止递归特化时 _generate_structs 过早为空成员类设置 body
        Gen._classes_in_progress.add(ClassName)
        # 标记正在收集字段，阻止继承处理（_ResolveGenericSlice → _specialize_generic_class）
        # 和 CollectAnnAssignMember 触发的嵌套 _generate_structs 用不完整 class_members 调用 set_body
        Gen._collecting_members_set.add(ClassName)
        if ClassName not in Gen.class_methods:
            Gen.class_methods[ClassName] = []
        else:
            # 防御性清除：移除导入阶段可能添加的构造函数（__new__/__init__/__before_init__）。
            # 构造函数不参与虚分派，放入 vtable 会导致子类与基类 vtable 大小不一致，
            # 索引偏移破坏多态分派（如 Module 有 __new__/__init__ 使 vtable=7，而 AST 无它们 vtable=5，
            # 调用方按 AST 布局取 append@idx4 实际取到 Module.dump@idx4）。
            Gen.class_methods[ClassName] = [
                m for m in Gen.class_methods[ClassName]
                if m.split('.')[-1] not in ('__new__', '__init__', '__before_init__')
            ]
        # 当前文件定义的类是权威定义，覆盖之前导入阶段可能添加的外部声明。
        # 关键：如果本地类是 @t.NoVTable 但同名导入类有 vtable（名称冲突），
        # 必须清除 vtable 状态，否则 _generate_structs 会错误添加 vtable 指针。
        if IsNoVTable:
            Gen.class_vtable.discard(ClassName)
            Gen._cross_module_vtable_classes.discard(ClassName)
            Gen._cross_module_novtable.add(ClassName)
            # 清除可能从导入 stub 加载的旧 struct body（含错误 vtable 指针），
            # 让 _generate_structs 用本地 class_members 重新生成
            _old_st = Gen.structs.get(ClassName)
            if isinstance(_old_st, ir.IdentifiedStructType) and _old_st.elements is not None:
                _old_st._elements = None
            _ih = getattr(Gen, '_import_handler_ref', None)
            if _ih is not None:
                _ck = (id(Gen), ClassName)
                if _ck in _ih._struct_Load_cache:
                    del _ih._struct_Load_cache[_ck]
        Gen.class_members[ClassName] = []
        Gen.class_member_defaults[ClassName] = {}
        Gen.class_member_signeds[ClassName] = {}
        Gen.class_member_bitfields[ClassName] = {}
        Gen.class_member_byteorders[ClassName] = {}
        Gen.class_member_bitoffsets[ClassName] = {}
        ParentClass: str | None = None
        if Node.bases:
            class_graph: dict = Gen._class_graph
            for base in Node.bases:
                if hasattr(base, 'id'):
                    base_name = base.id
                elif hasattr(base, 'attr'):
                    base_name = base.attr
                elif isinstance(base, ast.Subscript):
                    # 泛型特化基类：GSListNode[GNode]
                    # 特化泛型类，用特化名作为父类名
                    spec_name: str | None = self.Trans.ExprCallHandle._ResolveGenericSlice(base)
                    if spec_name:
                        base_name = spec_name
                    else:
                        continue
                else:
                    continue
                if base_name == ClassName:
                    continue
                if base_name in ('Object', 'CVTable', 'NoVTable', 'CStruct', 'CUnion', 'CEnum', 'REnum', 'Exception', 'Enum'):
                    continue
                # 总是记录父类名，即使父类 class_members 未加载。
                # _get_member_offset 会沿 class_parent 链回退查找继承字段。
                ParentClass = base_name
                Gen.class_parent[ClassName] = ParentClass
                break
        if ParentClass and (ParentClass in class_graph or ParentClass in Gen.class_members):
            parent_members: list = list(Gen.class_members[ParentClass])
            parent_defaults: dict = dict(Gen.class_member_defaults.get(ParentClass, {}))
            existing_names: set = {m[0] for m in Gen.class_members[ClassName]}
            inherited: list[tuple] = []
            for pm_name, pm_type in parent_members:
                if pm_name not in existing_names:
                    inherited.append((pm_name, pm_type))
                    if pm_name in parent_defaults:
                        Gen.class_member_defaults[ClassName][pm_name] = parent_defaults[pm_name]
            Gen.class_members[ClassName] = inherited + Gen.class_members[ClassName]
            if ParentClass in Gen.class_methods:
                parent_methods: list = list(Gen.class_methods[ParentClass])
                # 构建子类已有方法映射（方法短名 -> 方法全名）
                child_method_map: dict[str, str] = {}
                for m in Gen.class_methods[ClassName]:
                    method_name: str = m.split('.')[-1] if '.' in m else m
                    child_method_map[method_name] = m
                # 父类方法在前（保证 vtable 布局一致性，子类多态分派索引正确），
                # 子类新增方法在后。子类覆盖的方法放在父类方法的位置（用子类实现）。
                new_methods: list = []
                covered_names: set[str] = set()
                for pm in parent_methods:
                    method_name: str = pm.split('.')[-1] if '.' in pm else pm
                    if method_name in child_method_map:
                        # 子类覆盖了父类方法 — 用子类的实现，放在父类的位置
                        new_methods.append(child_method_map[method_name])
                        covered_names.add(method_name)
                    else:
                        # 父类独有方法 — 子类未覆盖，注册子类包装器
                        child_method: str = f"{ClassName}.{method_name}"
                        new_methods.append(child_method)
                        Gen.register_method(ClassName, child_method)
                # 添加子类新增方法（不在父类中的）
                for m in Gen.class_methods[ClassName]:
                    method_name: str = m.split('.')[-1] if '.' in m else m
                    if method_name not in covered_names:
                        new_methods.append(m)
                Gen.class_methods[ClassName] = new_methods
        # 提取首个裸字符串字面量作为结构体 __doc__ docstring
        if (Node.body and isinstance(Node.body[0], ast.Expr)
                and isinstance(Node.body[0].value, ast.Constant)
                and isinstance(Node.body[0].value.value, str)):
            Gen._create_doc_global(ClassName, Node.body[0].value.value)
        else:
            Gen._create_doc_global(ClassName, None)
        # 解析 __provides__/__requires__/__require_must__ 编译期元数据
        for item in Node.body:
            if isinstance(item, ast.AnnAssign) and isinstance(item.target, ast.Name):
                field_name: str = item.target.id
                if field_name in ('__provides__', '__requires__', '__require_must__') and item.value:
                    values: list[str] = []
                    if isinstance(item.value, ast.List):
                        for elt in item.value.elts:
                            if isinstance(elt, ast.Constant) and isinstance(elt.value, str):
                                values.append(elt.value)
                    if field_name == '__provides__':
                        Gen.class_provides[ClassName] = values
                    elif field_name == '__requires__':
                        Gen.class_requires[ClassName] = values
                    elif field_name == '__require_must__':
                        Gen.class_require_must[ClassName] = values
        for item in Node.body:
            # 跳过编译期元数据字段（__provides__/__requires__/__require_must__）
            if isinstance(item, ast.AnnAssign) and isinstance(item.target, ast.Name):
                if item.target.id in ('__provides__', '__requires__', '__require_must__'):
                    continue
            parsed = self.CollectAnnAssignMember(item, Gen)
            if parsed:
                VarName, MemberType, TypeInfo = parsed
                Gen.class_members[ClassName].append((VarName, MemberType))
                if TypeInfo:
                    if isinstance(MemberType, ir.PointerType) and isinstance(MemberType.pointee, ir.IntType) and MemberType.pointee.width == 8:
                        if isinstance(item.annotation, ast.BinOp) and isinstance(item.annotation.op, ast.BitOr):
                            element_class: str | None = FindStructNameInAnnotation(item.annotation, Gen.structs)
                            # Fallback: FindStructNameInAnnotation 不处理 Subscript slice 为 BinOp 的情况
                            # (如 list[AST | t.CPtr] | t.CPtr)，使用 TypeInfo.Name 作为回退。
                            # TypeInfo.Name 由 _HandleSubscript 设置为特化名（如 'list[sha1.ASTptr]'），
                            # 经 _MergeCTypeInfoInto 传播后保留。
                            if not element_class and TypeInfo.IsStruct and TypeInfo.Name and TypeInfo.Name in Gen.structs:
                                element_class = TypeInfo.Name
                            if element_class:
                                if ClassName not in Gen.class_member_element_class:
                                    Gen.class_member_element_class[ClassName] = {}
                                Gen.class_member_element_class[ClassName][VarName] = element_class
                    if hasattr(TypeInfo.BaseType, 'IsSigned'):
                        Gen.class_member_signeds[ClassName][VarName] = TypeInfo.BaseType.IsSigned
                    else:
                        Gen.class_member_signeds[ClassName][VarName] = None
                    if TypeInfo.IsBitField:
                        Gen.class_member_bitfields[ClassName][VarName] = TypeInfo.BitWidth
                    else:
                        Gen.class_member_bitfields[ClassName][VarName] = 0
                    if TypeInfo.ByteOrder:
                        Gen.class_member_byteorders[ClassName][VarName] = TypeInfo.ByteOrder
                    else:
                        Gen.class_member_byteorders[ClassName][VarName] = ""
                    if item.value:
                        const: ir.Constant | None = self._BuildScalarConstant(item.value, MemberType, Gen)
                        if const:
                            Gen.class_member_defaults[ClassName][VarName] = const
                else:
                    Gen.class_member_signeds[ClassName][VarName] = None
                    Gen.class_member_bitfields[ClassName][VarName] = 0
        # 字段收集完成，清除标志，允许后续 _generate_structs 正常设置 body
        Gen._collecting_members_set.discard(ClassName)
        existing_members: set[str] = {m[0] for m in Gen.class_members[ClassName]}
        for item in Node.body:
            if isinstance(item, ast.FunctionDef):
                self._current_method_args = {}
                for arg in item.args.args:
                    if arg.arg != 'self' and arg.annotation:
                        self._current_method_args[arg.arg] = arg.annotation
                self._scan_method_body_for_self_members(item.body, ClassName, existing_members, Gen)
        self._current_method_args = {}
        for item in Node.body:
            if isinstance(item, ast.FunctionDef):
                MethodName: str = item.name
                FullMethodName: str = f"{ClassName}.{MethodName}"
                # property setter/deleter 使用不同的函数名后缀
                item_meta: FuncMeta = self.Trans.FunctionHandler._ExtractFuncMeta(item.decorator_list)
                if FuncMeta.PROPERTY_SETTER in item_meta:
                    FullMethodName = FullMethodName + '$set'
                elif FuncMeta.PROPERTY_DELETER in item_meta:
                    FullMethodName = FullMethodName + '$del'
                # 构造函数（__new__/__init__）不放入 vtable，避免子类与基类
                # vtable 大小不一致导致虚分派索引偏移。__before_init__ 由 TPC
                # 自动生成，不会出现在 FunctionDef 中，此处一并防御。
                if MethodName not in ('__new__', '__init__', '__before_init__'):
                    if FullMethodName not in Gen.class_methods[ClassName]:
                        Gen.class_methods[ClassName].append(FullMethodName)
                Gen.register_method(ClassName, FullMethodName)
        if IsCVTable:
            Gen.class_vtable.add(ClassName)
        Gen._generate_structs()
        Gen._create_Vtable_globals()
        # _create_Vtable_globals 会跳过正在发射中的类（方法列表可能不完整），
        # 当前类的方法已全部注册（L559-571），此处显式创建其 vtable
        if IsCVTable:
            Gen._create_vtable_for_class(ClassName)
        if ClassName in Gen.structs:
            self._EmitNewFunctionLlvm(ClassName, Gen, IsCVTable=IsCVTable, IsCpythonObject=IsCpythonObject)
        for item in Node.body:
            if isinstance(item, ast.FunctionDef):
                self.Trans.FunctionHandler._EmitFunctionForwardDeclLlvm(item, Gen, ClassName=ClassName)
        if not declare_only:
            for item in Node.body:
                if isinstance(item, ast.FunctionDef):
                    self.Trans.FunctionHandler._EmitFunctionLlvm(item, Gen, ClassName=ClassName)
        if IsCVTable and ClassName in Gen.Vtables:
            self._fill_vtable_with_methods(ClassName, Gen)
        # Generate wrapper functions for inherited methods that are not overridden
        if ParentClass:
            self._generate_inherited_method_wrappers(ClassName, Gen)
        Gen._classes_in_progress.discard(ClassName)

    def _generate_inherited_method_wrappers(self, ClassName: str, Gen: LlvmGeneratorMixin) -> None:
        """为子类继承但未覆写的方法生成包装函数，使跨模块调用能正确链接。

        例如 Label 继承 Widget.place，生成 Label.place 函数，
        内部将 self 从 Label* bitcast 为 Widget*，然后调用 Widget.place。
        """
        # 收集本类方法 + 沿继承链收集父类方法名
        # 原代码只遍历 class_methods[ClassName]，遗漏父类独有方法（如 __enter__），
        # 导致子类调用继承的方法时链接失败（undefined reference）
        methods: list = list(Gen.class_methods.get(ClassName, []))
        p: str | None = Gen.class_parent.get(ClassName) if hasattr(Gen, 'class_parent') else None
        while p:
            parent_methods: list = Gen.class_methods.get(p, [])
            for pm in parent_methods:
                pm_short: str = pm.split('.')[-1] if '.' in pm else pm
                # 避免重复：如果子类已覆写同名方法，不添加
                if not any(m.split('.')[-1] == pm_short for m in methods):
                    methods.append(pm)
            p = Gen.class_parent.get(p)
        if not methods:
            return
        if ClassName not in Gen.structs:
            return

        for method_name in methods:
            method_short: str = method_name.split('.')[-1] if '.' in method_name else method_name
            child_full: str = f"{ClassName}.{method_short}"

            # 如果子类已经有该方法的实现，跳过
            if Gen._find_function(child_full):
                continue

            # 沿继承链查找父类实现
            parent_func: ir.Function | None = None
            parent_class: str | None = None
            p: str | None = Gen.class_parent.get(ClassName)
            while p:
                parent_full: str = f"{p}.{method_short}"
                parent_func = Gen._find_function(parent_full)
                if parent_func:
                    parent_class = p
                    break
                p = Gen.class_parent.get(p)

            if not parent_func or not parent_class:
                continue

            # 父类和子类都需要有 struct 定义
            if parent_class not in Gen.structs:
                continue

            # 构造子类包装函数签名：与父类函数相同，但 self 参数类型为子类指针
            parent_ftype: ir.FunctionType = parent_func.function_type
            parent_ret_type: ir.Type = parent_ftype.return_type
            parent_param_types: list[ir.Type] = list(parent_ftype.args)
            is_vararg: bool = parent_ftype.var_arg

            # 判断父类方法是否是静态方法：
            # 如果第一个参数类型是父类指针，说明是实例方法；否则是静态方法
            parent_struct_ptr_type: ir.PointerType | None = ir.PointerType(Gen.structs[parent_class]) if parent_class in Gen.structs else None
            is_static: bool = True
            if parent_param_types and parent_struct_ptr_type:
                first_param: ir.Type = parent_param_types[0]
                # 检查第一个参数是否是父类指针（或可以 bitcast 为父类指针的指针类型）
                if isinstance(first_param, ir.PointerType):
                    if isinstance(first_param.pointee, ir.IdentifiedStructType):
                        if first_param.pointee.name == Gen.structs[parent_class].name:
                            is_static = False
                    elif first_param == ir.IntType(8):
                        # i8* 可能是前向声明时的 self 类型，视为实例方法
                        is_static = False

            if is_static:
                # 静态方法：签名与父类完全一致，不需要 self 参数
                child_param_types: list[ir.Type] = list(parent_param_types)
                child_struct_ptr: ir.PointerType | None = None
            else:
                # 实例方法：替换第一个参数（self）的类型为子类指针
                child_struct_ptr = ir.PointerType(Gen.structs[ClassName])
                if parent_param_types:
                    child_param_types = [child_struct_ptr] + parent_param_types[1:]
                else:
                    child_param_types = [child_struct_ptr]

            child_func_type: ir.FunctionType = ir.FunctionType(parent_ret_type, child_param_types, var_arg=is_vararg)
            child_mangled: str = Gen._mangle_func_name(child_full)
            child_func: ir.Function = Gen._get_or_declare_function(child_mangled, child_func_type)
            Gen.functions[child_full] = child_func

            # 生成函数体
            entry_block: ir.Block = child_func.append_basic_block(name="entry")
            saved_builder: ir.IRBuilder = Gen.builder
            saved_func: ir.Function = Gen.func
            Gen.builder = ir.IRBuilder(entry_block)
            Gen.func = child_func

            # 准备参数
            call_args: list[ir.Value] = []
            if is_static:
                # 静态方法：参数直接传递，不做 bitcast
                for arg in child_func.args:
                    call_args.append(arg)
            else:
                # 实例方法：bitcast self，其余参数直接传递
                for i, arg in enumerate(child_func.args):
                    if i == 0 and parent_param_types:
                        actual_self_type: ir.Type = parent_param_types[0]
                        casted_self: ir.Value = Gen.builder.bitcast(arg, actual_self_type, name="self_cast")
                        call_args.append(casted_self)
                    else:
                        call_args.append(arg)

            result: ir.Value = Gen.builder.call(parent_func, call_args, name="inherited_call")

            if isinstance(parent_ret_type, ir.VoidType):
                Gen.builder.ret_void()
            else:
                Gen.builder.ret(result)

            Gen.builder = saved_builder
            Gen.func = saved_func

    def _fill_vtable_with_methods(self, ClassName: str, Gen: LlvmGeneratorMixin) -> None:
        methods: list = Gen.class_methods.get(ClassName, [])
        if not methods or ClassName not in Gen.Vtables:
            return
        Vtable: ir.GlobalVariable = Gen.Vtables[ClassName]
        VtableType: ir.Type = Vtable.type.pointee
        null_i8ptr: ir.Constant = ir.Constant(ir.PointerType(ir.IntType(8)), None)
        initializers: list[ir.Constant] = []
        for mi, method_name in enumerate(methods):
            method_short: str = method_name.split('.')[-1] if '.' in method_name else method_name
            func: ir.Function | None = Gen._find_function(f"{ClassName}.{method_short}")
            if not func:
                func = Gen._find_function(f"{ClassName}.{method_short}__")
            if not func:
                p: str | None = Gen.class_parent.get(ClassName)
                while p:
                    func = Gen._find_function(f"{p}.{method_short}")
                    if not func:
                        func = Gen._find_function(f"{p}.{method_short}__")
                    if func:
                        break
                    p = Gen.class_parent.get(p)
            if func:
                initializers.append(func.bitcast(ir.PointerType(ir.IntType(8))))
            else:
                initializers.append(null_i8ptr)
        if initializers:
            Vtable.initializer = ir.Constant(VtableType, initializers)

    def _scan_method_body_for_self_members(self, body: list[ast.AST], ClassName: str, existing_members: set[str], Gen: LlvmGeneratorMixin) -> None:
        for stmt in body:
            self._scan_node_for_self_assign(stmt, ClassName, existing_members, Gen)

    def _scan_node_for_self_assign(self, node: ast.AST, ClassName: str, existing_members: set[str], Gen: LlvmGeneratorMixin) -> None:
        if isinstance(node, ast.AnnAssign):
            if (isinstance(node.target, ast.Attribute)
                and isinstance(node.target.value, ast.Name)
                and node.target.value.id == 'self'):
                VarName: str = node.target.attr
                if VarName not in existing_members:
                    try:
                        TypeInfo: CTypeInfo | None = CTypeInfo.FromNode(node.annotation, self.Trans.SymbolTable)
                        if TypeInfo is None:
                            TypeInfo = CTypeInfo()
                            TypeInfo.BaseType = t.CInt()
                        MemberType: ir.Type = Gen._ctype_to_llvm(TypeInfo)
                        if isinstance(MemberType, ir.VoidType):
                            MemberType = ir.IntType(32)
                    except Exception as e:  # 回退：成员类型解析失败时使用默认 i32
                        _vlog().warning(f"HandlesClassDef: 忽略异常 {e}", exc_info=e)
                        MemberType = ir.IntType(32)
                    Gen.class_members[ClassName].append((VarName, MemberType))
                    Gen.class_member_signeds[ClassName][VarName] = None
                    Gen.class_member_bitfields[ClassName][VarName] = 0
                    Gen.class_member_byteorders[ClassName][VarName] = ""
                    Gen.class_member_bitoffsets[ClassName][VarName] = 0
                    existing_members.add(VarName)
                    len_name = f'{VarName}__len'
                    if isinstance(MemberType, ir.PointerType) and node.value and isinstance(node.value, ast.List):
                        if len_name not in existing_members:
                            Gen.class_members[ClassName].append((len_name, ir.IntType(64)))
                            Gen.class_member_signeds[ClassName][len_name] = None
                            Gen.class_member_bitfields[ClassName][len_name] = 0
                            Gen.class_member_byteorders[ClassName][len_name] = ""
                            Gen.class_member_bitoffsets[ClassName][len_name] = 0
                            Gen.class_member_defaults[ClassName][len_name] = ir.Constant(ir.IntType(64), len(node.value.elts))
                            existing_members.add(len_name)
        elif isinstance(node, ast.Assign):
            for target in node.targets:
                if (isinstance(target, ast.Attribute)
                    and isinstance(target.value, ast.Name)
                    and target.value.id == 'self'):
                    VarName = target.attr
                    if VarName not in existing_members:
                        MemberType = ir.IntType(32)
                        if node.value:
                            try:
                                if isinstance(node.value, ast.Constant):
                                    if isinstance(node.value.value, int):
                                        MemberType = ir.IntType(32)
                                    elif isinstance(node.value.value, float):
                                        MemberType = ir.DoubleType()
                                    elif isinstance(node.value.value, str):
                                        MemberType = ir.PointerType(ir.IntType(8))
                                elif isinstance(node.value, ast.Name):
                                    if hasattr(self, '_current_method_args'):
                                        arg_info = self._current_method_args.get(node.value.id)
                                        if arg_info:
                                            TypeInfo = CTypeInfo.FromNode(arg_info, self.Trans.SymbolTable)
                                            if TypeInfo:
                                                InferredType = Gen._ctype_to_llvm(TypeInfo)
                                                if not isinstance(InferredType, ir.VoidType):
                                                    MemberType = InferredType
                                elif isinstance(node.value, ast.Call):
                                    if isinstance(node.value.func, ast.Name):
                                        if node.value.func.id in ('float', 'double'):
                                            MemberType = ir.DoubleType()
                                        elif node.value.func.id in ('int', 'long', 'short', 'char'):
                                            MemberType = ir.IntType(32)
                                    elif isinstance(node.value.func, ast.Attribute):
                                        if node.value.func.attr == 'len':
                                            MemberType = ir.IntType(32)
                            except Exception as _e:
                                if _config_mode == "strict":
                                    self.Trans.LogWarning(f"异常被忽略: {_e}")
                        Gen.class_members[ClassName].append((VarName, MemberType))
                        Gen.class_member_signeds[ClassName][VarName] = None
                        Gen.class_member_bitfields[ClassName][VarName] = 0
                        Gen.class_member_byteorders[ClassName][VarName] = ""
                        Gen.class_member_bitoffsets[ClassName][VarName] = 0
                        existing_members.add(VarName)
        for child in ast.iter_child_nodes(node):
            if isinstance(child, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
                continue
            self._scan_node_for_self_assign(child, ClassName, existing_members, Gen)

    def _EmitUnionLlvm(self, Node: ast.ClassDef, Gen: LlvmGeneratorMixin) -> None:
        ClassName: str = Node.name
        union_member_types: list[ir.Type] = []
        for item in Node.body:
            if isinstance(item, ast.ClassDef):
                nested_class_name: str = item.name
                nested_member_types: list[ir.Type] = []
                for nested_item in item.body:
                    parsed = self.CollectAnnAssignMember(nested_item, Gen)
                    if parsed:
                        nested_member_types.append(parsed[1])
                if nested_member_types:
                    nested_struct_type: ir.IdentifiedStructType = ir.IdentifiedStructType(Gen.module, f"{ClassName}_{nested_class_name}")
                    nested_struct_type.set_body(*nested_member_types)
                    Gen.structs[f"{ClassName}_{nested_class_name}"] = nested_struct_type
                    union_member_types.append(nested_struct_type)
                    nested_class_full_name: str = f"{ClassName}_{nested_class_name}"
                    if nested_class_full_name not in Gen.class_members:
                        Gen.class_members[nested_class_full_name] = []
                    if nested_class_full_name not in Gen.class_member_signeds:
                        Gen.class_member_signeds[nested_class_full_name] = {}
                    for nested_item in item.body:
                        parsed = self.CollectAnnAssignMember(nested_item, Gen)
                        if parsed:
                            VarName, MemberType, TypeInfo = parsed
                            Gen.class_members[nested_class_full_name].append((VarName, MemberType))
                            if TypeInfo and hasattr(TypeInfo.BaseType, 'IsSigned'):
                                Gen.class_member_signeds[nested_class_full_name][VarName] = TypeInfo.BaseType.IsSigned
                            else:
                                Gen.class_member_signeds[nested_class_full_name][VarName] = None
        if union_member_types:
            max_size: int = 0
            for member_type in union_member_types:
                try:
                    size: int = member_type.get_abi_size(ir.DataLayout(Gen.module.data_layout))
                except Exception as e:  # 回退：获取类型大小失败时使用默认值 8
                    _vlog().warning(f"HandlesClassDef: 忽略异常 {e}", exc_info=e)
                    size = 8
                max_size = max(max_size, size)
            union_type: ir.IdentifiedStructType = ir.IdentifiedStructType(Gen.module, ClassName)
            union_type.set_body(ir.ArrayType(ir.IntType(8), max_size))
            Gen.structs[ClassName] = union_type
        UnionNode: CTypeInfo = CTypeInfo()
        UnionNode.Name = ClassName
        UnionNode.IsUnion = True
        self.Trans.SymbolTable.insert(ClassName, UnionNode)

    def _EmitREnumLlvm(self, Node: ast.ClassDef, Gen: LlvmGeneratorMixin) -> None:
        ClassName: str = Node.name
        variant_info: list[tuple] = []
        variant_names: list[str] = []

        # 预注册 REnum opaque 结构体到 Gen.structs 和 SymbolTable，
        # 使自引用成员（如 LLVMType | t.CPtr）在收集成员时能正确解析为 %LLVMType*。
        # 若不预注册，GetCTypeInfo 找不到 LLVMType → 回退到 IsEnum → i32 → | t.CPtr → i32*（错误）。
        PreRenumType: ir.IdentifiedStructType = ir.IdentifiedStructType(Gen.module, ClassName)
        Gen.structs[ClassName] = PreRenumType
        PreTypeInfo: CTypeInfo = CTypeInfo()
        PreTypeInfo.Name = ClassName
        PreTypeInfo.BaseType = t.REnum(ClassName)
        PreTypeInfo.IsRenum = True
        PreTypeInfo.IsEnum = True
        # REnum 在内存布局上是 struct（{ i32 __tag, <max_payload> }），
        # 必须设置 IsStruct=True 才能让 HandlesTypeMerge 的 CPtr 吸收逻辑生效：
        # `REnumType | t.CPtr` 应得到 REnumType*（PtrCount=1）而非 REnumType**（PtrCount=2）。
        # 否则 include-imported 函数返回类型会出现双指针，与声明单指针不匹配 → 运行时崩溃。
        PreTypeInfo.IsStruct = True
        PreTypeInfo.RenumVariants = []
        self.Trans.SymbolTable.insert(ClassName, PreTypeInfo)

        # 第一遍：收集显式赋值的 tag 值，确定起始索引
        explicit_values: dict[str, int] = {}
        for item in Node.body:
            if isinstance(item, ast.Assign):
                for target in item.targets:
                    if isinstance(target, ast.Name):
                        if item.value and isinstance(item.value, ast.Constant):
                            explicit_values[target.id] = item.value.value
        # 类变体从 max(explicit_values, default=-1) + 1 开始
        next_class_tag: int = max(explicit_values.values()) + 1 if explicit_values else 0
        variant_index: int = 0

        for item in Node.body:
            if isinstance(item, ast.ClassDef):
                VariantName: str = item.name
                variant_names.append(VariantName)
                member_types: list[ir.Type] = []
                member_names: list[str] = []
                member_annotations: list[ast.AST | None] = []
                for nested_item in item.body:
                    parsed = self.CollectAnnAssignMember(nested_item, Gen)
                    if parsed:
                        VarName, MemberType, TypeInfo = parsed
                        member_types.append(MemberType)
                        member_names.append(VarName)
                        member_annotations.append(nested_item.annotation if TypeInfo else None)
                # 类变体使用专用计数器，避免与显式值冲突
                tag: int = next_class_tag
                next_class_tag += 1
                variant_info.append((VariantName, member_types, member_names, member_annotations, item.lineno, tag))
            elif isinstance(item, ast.Assign):
                for target in item.targets:
                    if isinstance(target, ast.Name):
                        VarName = target.id
                        variant_names.append(VarName)
                        value: int | None = None
                        if item.value and isinstance(item.value, ast.Constant):
                            value = item.value.value
                        else:
                            value = variant_index
                            variant_index += 1
                        variant_info.append((VarName, [], [], [], item.lineno, value))
        # REnum 布局是所有变体的联合体。每个字段位置必须能容纳任何变体在该位置的字段。
        # Bug 修复：原来只选总尺寸最大的变体，但不同变体在同一位置可能有不同尺寸的字段。
        # 例如 MetaType: Concrete 位置3是 i32(4字节)，但 Var 位置3是 MetaType*(8字节)。
        # 用 Concrete 的布局会导致 Var.Instance 指针被截断为4字节 → 运行时崩溃。
        # 修复：按每个位置的 max 字段尺寸构建布局。
        def _ir_type_size(t: ir.Type) -> int:
            if isinstance(t, ir.IntType):
                return max(4, t.width // 8)
            elif isinstance(t, ir.PointerType):
                return 8
            elif isinstance(t, ir.FloatType):
                return 4
            elif isinstance(t, ir.DoubleType):
                return 8
            elif isinstance(t, ir.ArrayType):
                if isinstance(t.element, ir.IntType):
                    return t.element.width // 8 * t.count
                return 8 * t.count
            else:
                return 8

        all_variant_types: list[list[ir.Type]] = []
        max_field_count: int = 0
        for _, member_types, _, _, _, _ in variant_info:
            if member_types:
                full_types: list[ir.Type] = [ir.IntType(32)] + member_types
                all_variant_types.append(full_types)
                if len(full_types) > max_field_count:
                    max_field_count = len(full_types)
        max_variant_struct: list[ir.Type] = []
        for pos in range(max_field_count):
            pos_max_size: int = 0
            for vt in all_variant_types:
                if pos < len(vt):
                    sz: int = _ir_type_size(vt[pos])
                    if sz > pos_max_size:
                        pos_max_size = sz
            # 按最大尺寸选择 LLVM 类型：<=4 用 i32，>4 用 i64（8字节，可容纳指针）
            if pos_max_size <= 4:
                max_variant_struct.append(ir.IntType(32))
            else:
                max_variant_struct.append(ir.IntType(64))
        if not max_variant_struct:
            max_variant_struct = [ir.IntType(32), ir.IntType(32)]
        # 复用预注册的 opaque 结构体，设置 body 使其完整
        PreRenumType.set_body(*max_variant_struct)
        for VariantName, member_types, member_names, member_annotations, lineno, tag_value in variant_info:
            NestedStructName: str = f"{ClassName}_{VariantName}"
            if member_types:
                padded_member_types: list[ir.Type] = list(max_variant_struct)
                nested_struct_type: ir.IdentifiedStructType = ir.IdentifiedStructType(Gen.module, NestedStructName)
                nested_struct_type.set_body(*padded_member_types)
                Gen.structs[NestedStructName] = nested_struct_type
                if NestedStructName not in Gen.class_members:
                    Gen.class_members[NestedStructName] = []
                if NestedStructName not in Gen.class_member_signeds:
                    Gen.class_member_signeds[NestedStructName] = {}
                Gen.class_members[NestedStructName].append(('__tag', ir.IntType(32)))
                Gen.class_member_signeds[NestedStructName]['__tag'] = None
                for i, (mname, mtype) in enumerate(zip(member_names, member_types)):
                    Gen.class_members[NestedStructName].append((mname, mtype))
                    try:
                        ti: CTypeInfo | None = CTypeInfo.FromNode(member_annotations[i], self.Trans.SymbolTable)
                        if ti and hasattr(ti.BaseType, 'IsSigned'):
                            Gen.class_member_signeds[NestedStructName][mname] = ti.BaseType.IsSigned
                        else:
                            Gen.class_member_signeds[NestedStructName][mname] = None
                    except Exception as e:  # 回退：签名信息解析失败时设为 None
                        _vlog().warning(f"HandlesClassDef: 忽略异常 {e}", exc_info=e)
                        Gen.class_member_signeds[NestedStructName][mname] = None
            MemberNode: CTypeInfo = CTypeInfo()
            MemberNode.Name = VariantName
            MemberNode.BaseType = t.CEnum(ClassName)
            MemberNode.value = tag_value
            MemberNode.EnumName = ClassName
            MemberNode.Lineno = lineno
            MemberNode.IsEnumMember = True
            self.Trans.SymbolTable.insert(VariantName, MemberNode)
        # 更新预注册的 REnum 类型信息（填充变体列表）
        PreTypeInfo.RenumVariants = variant_names

    def _RegisterEnumMembers(self, Node: ast.ClassDef) -> None:
        ClassName: str = Node.name
        EnumTypeInfo: CTypeInfo = CTypeInfo()
        EnumTypeInfo.Name = ClassName
        EnumTypeInfo.BaseType = t.CEnum(ClassName)
        EnumTypeInfo.IsEnum = True
        self.Trans.SymbolTable.insert(ClassName, EnumTypeInfo)
        enum_export = self.Trans.Exportable.add_enum(
            name=ClassName,
            lineno=Node.lineno,
            is_public=True
        )
        next_enum_value: int = 0
        for item in Node.body:
            if isinstance(item, ast.Assign):
                for target in item.targets:
                    if isinstance(target, ast.Name):
                        VarName: str = target.id
                        value: int | str | None = None
                        if item.value:
                            if isinstance(item.value, ast.Constant):
                                value = item.value.value
                                next_enum_value = value + 1
                            elif isinstance(item.value, ast.UnaryOp) and isinstance(item.value.op, ast.USub):
                                if isinstance(item.value.operand, ast.Constant):
                                    value = -item.value.operand.value
                                    next_enum_value = value + 1
                            elif isinstance(item.value, ast.Name):
                                value = item.value.id
                                ref_info: CTypeInfo | None = self.Trans.SymbolTable.lookup(value)
                                if ref_info:
                                    if ref_info.value is not None and isinstance(ref_info.value, int):
                                        next_enum_value = ref_info.value + 1
                        else:
                            value = next_enum_value
                            next_enum_value += 1
                        MemberNode: CTypeInfo = CTypeInfo()
                        MemberNode.Name = VarName
                        MemberNode.BaseType = t.CEnum(ClassName)
                        MemberNode.value = value
                        MemberNode.EnumName = ClassName
                        MemberNode.Lineno = item.lineno
                        MemberNode.IsEnumMember = True
                        self.Trans.SymbolTable.insert(VarName, MemberNode)
                        enum_export.members.append(ExportEnumMember(
                            name=VarName,
                            value=value,
                            lineno=item.lineno
                        ))
            elif isinstance(item, ast.AnnAssign):
                if isinstance(item.target, ast.Name):
                    VarName = item.target.id
                    value = None
                    if item.value:
                        if isinstance(item.value, ast.Constant):
                            value = item.value.value
                            next_enum_value = value + 1
                        elif isinstance(item.value, ast.UnaryOp) and isinstance(item.value.op, ast.USub):
                            if isinstance(item.value.operand, ast.Constant):
                                value = -item.value.operand.value
                                next_enum_value = value + 1
                        elif isinstance(item.value, ast.Name):
                            value = item.value.id
                            ref_info: CTypeInfo | None = self.Trans.SymbolTable.lookup(value)
                            if ref_info:
                                if ref_info.value is not None and isinstance(ref_info.value, int):
                                    next_enum_value = ref_info.value + 1
                    else:
                        value = next_enum_value
                        next_enum_value += 1
                    MemberNode: CTypeInfo = CTypeInfo()
                    MemberNode.Name = VarName
                    MemberNode.BaseType = t.CEnum(ClassName)
                    MemberNode.value = value
                    MemberNode.EnumName = ClassName
                    MemberNode.Lineno = item.lineno
                    MemberNode.IsEnumMember = True
                    self.Trans.SymbolTable.insert(VarName, MemberNode)
                    enum_export.members.append(ExportEnumMember(
                        name=VarName,
                        value=value,
                        lineno=item.lineno
                    ))

    def _EmitNewFunctionLlvm(self, ClassName: str, Gen: LlvmGeneratorMixin, IsCVTable: bool = False, IsCpythonObject: bool = False) -> None:
        NewFuncName: str = f'{ClassName}.__before_init__'
        existing_func: ir.Function | None = Gen.functions.get(NewFuncName)
        if existing_func and len(existing_func.blocks) > 0:
            return
        MangledName: str = Gen._mangle_name(NewFuncName)
        StructType: ir.Type = Gen.structs[ClassName]
        if isinstance(StructType, ir.IdentifiedStructType) and (StructType.elements is None or len(StructType.elements) == 0):
            self.Trans.ImportHandler._TryLoadStructFromStub(ClassName, Gen)
            StructType = Gen.structs.get(ClassName, StructType)
        StructPtrType: ir.PointerType = ir.PointerType(StructType)
        FuncType: ir.FunctionType = ir.FunctionType(ir.VoidType(), [StructPtrType])
        if existing_func:
            func: ir.Function = existing_func
        else:
            func = Gen._get_or_declare_function(MangledName, FuncType)
        Gen.functions[NewFuncName] = func
        EntryBlock: ir.Block = func.append_basic_block(name="entry")
        saved_builder: ir.IRBuilder = Gen.builder
        saved_func: ir.Function = Gen.func
        Gen.builder = ir.IRBuilder(EntryBlock)
        Gen.func = func
        StructPtr: ir.Argument = func.args[0]
        base: int = 1 if IsCVTable else 0
        if IsCVTable and ClassName in Gen.Vtables:
            VtablePtr: ir.Value = Gen.builder.gep(StructPtr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)], name="vtable_slot")
            VtableAddr: ir.Value = Gen.builder.bitcast(Gen.Vtables[ClassName], ir.PointerType(ir.IntType(8)), name="vtable_addr")
            Gen.builder.store(VtableAddr, VtablePtr)
        members: list[tuple] = Gen.class_members.get(ClassName, [])
        defaults: dict = Gen.class_member_defaults.get(ClassName, {})
        struct_elems: tuple = StructType.elements if hasattr(StructType, 'elements') and StructType.elements is not None else ()
        for i, (member_name, member_type) in enumerate(members):
            elem_idx: int = base + i
            if len(struct_elems) > 0 and elem_idx >= len(struct_elems):
                break
            ElemPtr: ir.Value = Gen.builder.gep(StructPtr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), elem_idx)], name=f"{ClassName}_{member_name}")
            if member_name in defaults:
                try:
                    val: ir.Constant = defaults[member_name]
                    if not isinstance(val, ir.Constant):
                        val = ir.Constant(ElemPtr.type.pointee, val)
                    Gen.builder.store(val, ElemPtr)
                except Exception as _e:
                    if _config_mode == "strict":
                        self.Trans.LogWarning(f"异常被忽略: {_e}")
            else:
                try:
                    ZeroVal: ir.Constant = ir.Constant(ElemPtr.type.pointee, None)
                    Gen.builder.store(ZeroVal, ElemPtr)
                except Exception:
                    pass
        Gen.builder.ret_void()
        Gen.builder = saved_builder
        Gen.func = saved_func

    def _BuildScalarConstant(self, node: ast.AST, llvm_type: ir.Type, Gen: LlvmGeneratorMixin | None = None) -> ir.Constant | None:
        """构建标量常量，委托给统一的 _BuildScalarConstantUnified 方法。"""
        if Gen is None:
            Gen = self.Trans.LlvmGen
        return self.Trans._BuildScalarConstantUnified(node, llvm_type, Gen)

    def _BuildStructConstant(self, call_node: ast.Call, StructName: str, Gen: LlvmGeneratorMixin) -> ir.Constant | None:
        struct_type: ir.Type = Gen.structs[StructName]
        members: list[tuple] = Gen.class_members.get(StructName, [])
        defaults: dict = Gen.class_member_defaults.get(StructName, {})
        member_values: list[ir.Constant] = []
        for member_name, member_type in members:
            if member_name in defaults:
                val: ir.Constant = defaults[member_name]
                if not isinstance(val, ir.Constant):
                    try:
                        val = ir.Constant(member_type, val)
                    except Exception:  # 回退：常量转换失败时使用零值
                        val = ir.Constant(member_type, 0)
                member_values.append(val)
            else:
                try:
                    if isinstance(member_type, (ir.IdentifiedStructType, ir.LiteralStructType, ir.PointerType, ir.ArrayType)):
                        member_values.append(ir.Constant(member_type, None))
                    else:
                        member_values.append(ir.Constant(member_type, ir.Undefined))
                except Exception:  # 回退：常量创建失败时使用零值
                    member_values.append(ir.Constant(member_type, 0))
        if call_node.args:
            for i, arg in enumerate(call_node.args):
                if i < len(members):
                    _, member_type = members[i]
                    const: ir.Constant | None = self._BuildScalarConstant(arg, member_type, Gen)
                    if const is not None:
                        member_values[i] = const
        try:
            return ir.Constant(struct_type, member_values)
        except Exception:  # 回退：结构体常量创建失败
            return None
